From 3622fb6f7f6453043073929ca02b628abf48997a Mon Sep 17 00:00:00 2001 From: MAKS11060 <31521952+MAKS11060@users.noreply.github.com> Date: Thu, 5 Jun 2025 08:53:47 +0200 Subject: [PATCH 1/3] feat(cli/unstable): make the output predictable if the input data is known --- cli/unstable_prompt_multiple_select.ts | 8 +++--- cli/unstable_prompt_multiple_select_test.ts | 27 +++++++++++++++++++ cli/unstable_prompt_select.ts | 6 ++--- cli/unstable_prompt_select_test.ts | 30 +++++++++++++++++++++ 4 files changed, 64 insertions(+), 7 deletions(-) diff --git a/cli/unstable_prompt_multiple_select.ts b/cli/unstable_prompt_multiple_select.ts index 76dc3607d898..3c0dc8128690 100644 --- a/cli/unstable_prompt_multiple_select.ts +++ b/cli/unstable_prompt_multiple_select.ts @@ -40,11 +40,11 @@ const SHOW_CURSOR = encoder.encode("\x1b[?25h"); * const browsers = promptMultipleSelect("Please select browsers:", ["safari", "chrome", "firefox"], { clear: true }); * ``` */ -export function promptMultipleSelect( +export function promptMultipleSelect( message: string, - values: string[], + values: readonly T[], options: PromptMultipleSelectOptions = {}, -): string[] | null { +): T[] | null { if (!input.isTerminal()) return null; const { clear } = options; @@ -103,5 +103,5 @@ export function promptMultipleSelect( output.writeSync(SHOW_CURSOR); input.setRaw(false); - return [...selectedIndexes].map((it) => values[it] as string); + return [...selectedIndexes].map((it) => values[it] as string) as T[]; } diff --git a/cli/unstable_prompt_multiple_select_test.ts b/cli/unstable_prompt_multiple_select_test.ts index 1e0320aefac3..087bd8b7dccf 100644 --- a/cli/unstable_prompt_multiple_select_test.ts +++ b/cli/unstable_prompt_multiple_select_test.ts @@ -644,3 +644,30 @@ Deno.test("promptMultipleSelect() returns null if Deno.stdin.isTerminal() is fal assertEquals(expectedOutput, actualOutput); restore(); }); + +Deno.test("promptMultipleSelect() check return types", () => { + stub(Deno.stdin, "setRaw"); + stub(Deno.stdin, "isTerminal", () => false); + + promptMultipleSelect("Please select a browser:", [ + "safari", + "chrome", + "firefox", + ]) satisfies ("safari" | "chrome" | "firefox")[] | null; + + const browsers = ["safari", "chrome", "firefox"] as const; + promptMultipleSelect("Please select a browsers:", browsers) satisfies + | ("safari" | "chrome" | "firefox")[] + | null; + + promptMultipleSelect("Please select a browsers:", [...browsers, 'edge']) satisfies + | ("safari" | "chrome" | "firefox"| 'edge')[] + | null; + + const selectItems = ["safari", "chrome", "firefox"]; + promptMultipleSelect("Please select a browsers:", selectItems) satisfies + | string[] + | null; + + restore(); +}); diff --git a/cli/unstable_prompt_select.ts b/cli/unstable_prompt_select.ts index 7644c171c88f..6130f16dde16 100644 --- a/cli/unstable_prompt_select.ts +++ b/cli/unstable_prompt_select.ts @@ -48,11 +48,11 @@ const SHOW_CURSOR = encoder.encode("\x1b[?25h"); * ], { clear: true, visibleLines: 3, indicator: "*" }); * ``` */ -export function promptSelect( +export function promptSelect( message: string, - values: string[], + values: readonly T[], options: PromptSelectOptions = {}, -): string | null { +): T | null { if (!input.isTerminal()) return null; const SAFE_PADDING = 3; diff --git a/cli/unstable_prompt_select_test.ts b/cli/unstable_prompt_select_test.ts index eab084f7dd3e..fba2e49e2fe5 100644 --- a/cli/unstable_prompt_select_test.ts +++ b/cli/unstable_prompt_select_test.ts @@ -816,3 +816,33 @@ Deno.test("promptSelect() handles ETX", () => { assertEquals(expectedOutput, actualOutput); restore(); }); + +Deno.test("promptSelect() check return types", () => { + stub(Deno.stdin, "setRaw"); + stub(Deno.stdin, "isTerminal", () => false); + + promptSelect("Please select a browser:", [ + "safari", + "chrome", + "firefox", + ]) satisfies "safari" | "chrome" | "firefox" | null; + + const browsers = ["safari", "chrome", "firefox"] as const; + promptSelect("Please select a browser:", browsers) satisfies + | "safari" + | "chrome" + | "firefox" + | null; + + promptSelect("Please select a browser:", [...browsers, 'edge']) satisfies + | "safari" + | "chrome" + | "firefox" + | 'edge' + | null; + + const selectItems = ["safari", "chrome", "firefox"]; + promptSelect("Please select a browser:", selectItems) satisfies string | null; + + restore(); +}); From a0bd98f67199a0b21fce9b91da832a524a0b5ff1 Mon Sep 17 00:00:00 2001 From: MAKS11060 <31521952+MAKS11060@users.noreply.github.com> Date: Thu, 5 Jun 2025 09:48:24 +0200 Subject: [PATCH 2/3] upd: add description for generic --- cli/unstable_prompt_multiple_select.ts | 2 ++ cli/unstable_prompt_select.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/cli/unstable_prompt_multiple_select.ts b/cli/unstable_prompt_multiple_select.ts index 3c0dc8128690..1587045b88c1 100644 --- a/cli/unstable_prompt_multiple_select.ts +++ b/cli/unstable_prompt_multiple_select.ts @@ -28,6 +28,8 @@ const SHOW_CURSOR = encoder.encode("\x1b[?25h"); /** * Shows the given message and waits for the user's input. Returns the user's selected value as string. * + * @typeParam T The type of the array elements. + * * @param message The prompt message to show to the user. * @param values The values for the prompt. * @param options The options for the prompt. diff --git a/cli/unstable_prompt_select.ts b/cli/unstable_prompt_select.ts index 6130f16dde16..e375defded86 100644 --- a/cli/unstable_prompt_select.ts +++ b/cli/unstable_prompt_select.ts @@ -29,6 +29,8 @@ const SHOW_CURSOR = encoder.encode("\x1b[?25h"); /** * Shows the given message and waits for the user's input. Returns the user's selected value as string. * + * @typeParam T The type of the array elements. + * * @param message The prompt message to show to the user. * @param values The values for the prompt. * @param options The options for the prompt. From 5683fc7a6f4d8f35e4b203310e28d701d01c561d Mon Sep 17 00:00:00 2001 From: MAKS11060 <31521952+MAKS11060@users.noreply.github.com> Date: Thu, 5 Jun 2025 10:24:05 +0200 Subject: [PATCH 3/3] upd: fmt --- cli/unstable_prompt_multiple_select_test.ts | 7 +++++-- cli/unstable_prompt_select_test.ts | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/cli/unstable_prompt_multiple_select_test.ts b/cli/unstable_prompt_multiple_select_test.ts index 087bd8b7dccf..f7585f986955 100644 --- a/cli/unstable_prompt_multiple_select_test.ts +++ b/cli/unstable_prompt_multiple_select_test.ts @@ -660,8 +660,11 @@ Deno.test("promptMultipleSelect() check return types", () => { | ("safari" | "chrome" | "firefox")[] | null; - promptMultipleSelect("Please select a browsers:", [...browsers, 'edge']) satisfies - | ("safari" | "chrome" | "firefox"| 'edge')[] + promptMultipleSelect("Please select a browsers:", [ + ...browsers, + "edge", + ]) satisfies + | ("safari" | "chrome" | "firefox" | "edge")[] | null; const selectItems = ["safari", "chrome", "firefox"]; diff --git a/cli/unstable_prompt_select_test.ts b/cli/unstable_prompt_select_test.ts index fba2e49e2fe5..471ec81e29f4 100644 --- a/cli/unstable_prompt_select_test.ts +++ b/cli/unstable_prompt_select_test.ts @@ -834,11 +834,11 @@ Deno.test("promptSelect() check return types", () => { | "firefox" | null; - promptSelect("Please select a browser:", [...browsers, 'edge']) satisfies + promptSelect("Please select a browser:", [...browsers, "edge"]) satisfies | "safari" | "chrome" | "firefox" - | 'edge' + | "edge" | null; const selectItems = ["safari", "chrome", "firefox"];