@tsed/cli-prompts 7.0.0-beta.11 → 7.0.0-beta.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/lib/esm/PromptRunner.js +5 -1
  2. package/lib/esm/fn/autocomplete.js +10 -54
  3. package/lib/esm/fn/checkbox.js +5 -6
  4. package/lib/esm/fn/confirm.js +5 -7
  5. package/lib/esm/fn/input.js +4 -5
  6. package/lib/esm/fn/list.js +5 -7
  7. package/lib/esm/fn/password.js +2 -6
  8. package/lib/esm/utils/normalizeChoices.js +2 -2
  9. package/lib/esm/utils/normalizeQuestion.js +0 -6
  10. package/lib/tsconfig.esm.tsbuildinfo +1 -1
  11. package/lib/types/fn/checkbox.d.ts +1 -1
  12. package/lib/types/fn/confirm.d.ts +1 -1
  13. package/lib/types/fn/input.d.ts +1 -1
  14. package/lib/types/fn/list.d.ts +1 -1
  15. package/lib/types/fn/password.d.ts +1 -1
  16. package/lib/types/interfaces/NormalizedPromptQuestion.d.ts +2 -3
  17. package/lib/types/interfaces/PromptQuestion.d.ts +17 -31
  18. package/lib/types/utils/normalizeChoices.d.ts +2 -4
  19. package/package.json +3 -3
  20. package/src/PromptRunner.ts +6 -1
  21. package/src/fn/autocomplete.ts +10 -66
  22. package/src/fn/checkbox.ts +11 -14
  23. package/src/fn/confirm.ts +5 -10
  24. package/src/fn/input.ts +5 -8
  25. package/src/fn/list.ts +10 -14
  26. package/src/fn/password.ts +2 -8
  27. package/src/fn/prompts.spec.ts +81 -84
  28. package/src/interfaces/NormalizedPromptQuestion.ts +2 -3
  29. package/src/interfaces/PromptQuestion.ts +21 -32
  30. package/src/utils/normalizeChoices.ts +5 -6
  31. package/src/utils/normalizeQuestion.ts +0 -8
  32. package/src/utils/utils.spec.ts +2 -47
  33. package/lib/esm/utils/getValidationError.js +0 -14
  34. package/lib/esm/utils/processPrompt.js +0 -20
  35. package/lib/types/utils/getValidationError.d.ts +0 -2
  36. package/lib/types/utils/processPrompt.d.ts +0 -5
  37. package/src/utils/getValidationError.ts +0 -21
  38. package/src/utils/processPrompt.ts +0 -29
@@ -1,5 +1,7 @@
1
1
  import { injectable } from "@tsed/di";
2
2
  import * as fn from "./fn/index.js";
3
+ import { applyTransforms } from "./utils/applyTransforms.js";
4
+ import { ensureNotCancelled } from "./utils/ensureNotCancelled.js";
3
5
  import { normalizeQuestion } from "./utils/normalizeQuestion.js";
4
6
  import { shouldAsk } from "./utils/shouldAsk.js";
5
7
  export class PromptRunner {
@@ -23,7 +25,9 @@ export class PromptRunner {
23
25
  if (!fn[type]) {
24
26
  throw new Error(`Unsupported prompt type: ${type}`);
25
27
  }
26
- return fn[type](question, answers);
28
+ const result = await fn[type](question, answers);
29
+ const value = ensureNotCancelled(result);
30
+ return applyTransforms(question, answers, value);
27
31
  }
28
32
  }
29
33
  injectable(PromptRunner);
@@ -1,60 +1,16 @@
1
- import { select, text } from "@clack/prompts";
2
- import { ensureNotCancelled } from "../utils/ensureNotCancelled.js";
1
+ import { autocomplete as a } from "@clack/prompts";
3
2
  import { normalizeChoices } from "../utils/normalizeChoices.js";
4
- import { CONTINUE, processPrompt } from "../utils/processPrompt.js";
5
- import { resolveListDefault } from "../utils/resolveListDefault.js";
6
- const SEARCH_ACTION = "__tsed_cli_search_again__";
7
3
  export async function autocomplete(question, answers) {
8
- if (!question.source) {
4
+ if (!(question.source || question.choices)) {
9
5
  throw new Error(`Question "${question.name}" must provide a source for autocomplete prompts.`);
10
6
  }
11
- let keyword = "";
12
- let choices = await resolveAutocompleteChoices(question.source, answers, keyword);
13
- async function display() {
14
- keyword = await promptKeyword(question.message, keyword, true);
15
- choices = await resolveAutocompleteChoices(question.source, answers, keyword);
16
- }
17
- return processPrompt(question, answers, async () => {
18
- if (!choices.length) {
19
- await display();
20
- return CONTINUE;
21
- }
22
- const selection = await select({
23
- message: buildAutocompleteMessage(question.message, keyword),
24
- options: [
25
- ...choices.map((choice) => ({
26
- label: choice.label,
27
- value: choice.value,
28
- hint: choice.hint
29
- })),
30
- {
31
- label: "🔍 Search again",
32
- value: SEARCH_ACTION,
33
- hint: "Type another keyword"
34
- }
35
- ],
36
- initialValue: resolveListDefault(question, choices),
37
- maxItems: question.pageSize
38
- });
39
- if (selection === SEARCH_ACTION) {
40
- await display();
41
- return CONTINUE;
42
- }
43
- return selection;
7
+ const choices = question.choices ? question.choices : question.source ? normalizeChoices(await question.source(answers)) : [];
8
+ return a({
9
+ ...question,
10
+ options: choices.map((choice) => ({
11
+ label: choice.label,
12
+ value: choice.value,
13
+ hint: choice.hint
14
+ }))
44
15
  });
45
16
  }
46
- async function resolveAutocompleteChoices(source, answers, keyword) {
47
- const items = await source(answers, keyword);
48
- return normalizeChoices(items);
49
- }
50
- async function promptKeyword(message, keyword, emptyState) {
51
- const label = emptyState ? `${message} (no matches, type to search)` : `${message} (type to refine search)`;
52
- const result = await text({
53
- message: label,
54
- initialValue: keyword
55
- });
56
- return ensureNotCancelled(result).trim();
57
- }
58
- function buildAutocompleteMessage(message, keyword) {
59
- return keyword ? `${message} (filter: ${keyword})` : message;
60
- }
@@ -1,20 +1,19 @@
1
1
  import { multiselect } from "@clack/prompts";
2
- import { isArray } from "@tsed/core/utils/isArray";
3
- import { processPrompt } from "../utils/processPrompt.js";
4
- export async function checkbox(question, answers) {
2
+ import { isArray } from "@tsed/core/utils/isArray.js";
3
+ export async function checkbox(question) {
5
4
  if (!question.choices?.length) {
6
5
  throw new Error(`Question "${question.name}" does not provide any choices`);
7
6
  }
8
7
  const initialValues = resolveCheckboxDefaults(question, question.choices);
9
- return processPrompt(question, answers, () => multiselect({
10
- message: question.message,
8
+ return multiselect({
9
+ ...question,
11
10
  options: question.choices.map((choice) => ({
12
11
  label: choice.label,
13
12
  value: choice.value,
14
13
  hint: choice.hint
15
14
  })),
16
15
  initialValues
17
- }));
16
+ });
18
17
  }
19
18
  function resolveCheckboxDefaults(question, choices) {
20
19
  if (isArray(question.default)) {
@@ -1,10 +1,8 @@
1
1
  import { confirm as c } from "@clack/prompts";
2
2
  import { isBoolean } from "@tsed/core/utils/isBoolean.js";
3
- import { processPrompt } from "../utils/processPrompt.js";
4
- export async function confirm(question, answers) {
5
- const initialValue = isBoolean(question.default) ? question.default : undefined;
6
- return processPrompt(question, answers, () => c({
7
- message: question.message,
8
- initialValue
9
- }));
3
+ export async function confirm(question) {
4
+ return c({
5
+ ...question,
6
+ initialValue: isBoolean(question.default) ? question.default : undefined
7
+ });
10
8
  }
@@ -1,8 +1,7 @@
1
1
  import { text } from "@clack/prompts";
2
- import { processPrompt } from "../utils/processPrompt.js";
3
- export async function input(question, answers) {
4
- return processPrompt(question, answers, () => text({
5
- message: question.message,
2
+ export async function input(question) {
3
+ return text({
4
+ ...question,
6
5
  initialValue: String(question.default ?? "")
7
- }));
6
+ });
8
7
  }
@@ -1,18 +1,16 @@
1
1
  import { select } from "@clack/prompts";
2
- import { processPrompt } from "../utils/processPrompt.js";
3
2
  import { resolveListDefault } from "../utils/resolveListDefault.js";
4
- export async function list(question, answers) {
3
+ export async function list(question) {
5
4
  if (!question.choices?.length) {
6
5
  throw new Error(`Question "${question.name}" does not provide any choices`);
7
6
  }
8
- return processPrompt(question, answers, () => select({
9
- message: question.message,
7
+ return select({
8
+ ...question,
10
9
  options: question.choices.map((choice) => ({
11
10
  label: choice.label,
12
11
  value: choice.value,
13
12
  hint: choice.hint
14
13
  })),
15
- initialValue: resolveListDefault(question, question.choices),
16
- maxItems: question.pageSize
17
- }));
14
+ initialValue: resolveListDefault(question, question.choices)
15
+ });
18
16
  }
@@ -1,8 +1,4 @@
1
1
  import { password as clackPassword } from "@clack/prompts";
2
- import { processPrompt } from "../utils/processPrompt.js";
3
- export async function password(question, answers) {
4
- return processPrompt(question, answers, () => clackPassword({
5
- message: question.message,
6
- mask: question.mask === false ? undefined : String(question.mask || "•")
7
- }));
2
+ export async function password(question) {
3
+ return clackPassword(question);
8
4
  }
@@ -1,9 +1,9 @@
1
1
  export function normalizeChoices(inputs = []) {
2
2
  return inputs.map((choice) => {
3
3
  if (typeof choice === "object" && choice !== null && "value" in choice) {
4
- const resolvedValue = choice.value ?? choice.name;
4
+ const resolvedValue = choice.value ?? choice.name ?? choice.label;
5
5
  return {
6
- label: choice.name ?? String(resolvedValue ?? ""),
6
+ label: choice.label ?? choice.name ?? String(resolvedValue ?? ""),
7
7
  value: resolvedValue,
8
8
  hint: choice.short,
9
9
  checked: choice.checked
@@ -13,11 +13,5 @@ export async function normalizeQuestion(question, answers) {
13
13
  if ("choices" in question && question.choices?.length) {
14
14
  normalized.choices = normalizeChoices([...question.choices]);
15
15
  }
16
- if ("source" in question && question.source) {
17
- const source = question.source;
18
- normalized.source = (state, keyword) => {
19
- return source({ ...answers, ...state }, keyword);
20
- };
21
- }
22
16
  return normalized;
23
17
  }