@reliverse/relinka 1.1.7 → 1.1.8

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 (121) hide show
  1. package/dist-npm/components/anykey/index.js +57 -77
  2. package/dist-npm/components/block/block.js +48 -61
  3. package/dist-npm/components/checkbox/index.js +178 -211
  4. package/dist-npm/components/confirm/confirm-main.js +85 -122
  5. package/dist-npm/components/confirm/confirm-three.js +24 -27
  6. package/dist-npm/components/confirm/index.js +36 -45
  7. package/dist-npm/components/core/Separator.js +15 -17
  8. package/dist-npm/components/core/create-prompt.js +101 -124
  9. package/dist-npm/components/core/errors.js +19 -15
  10. package/dist-npm/components/core/hook-engine.js +91 -120
  11. package/dist-npm/components/core/index.js +12 -12
  12. package/dist-npm/components/core/key.js +16 -6
  13. package/dist-npm/components/core/lines.js +45 -54
  14. package/dist-npm/components/core/make-theme.js +21 -30
  15. package/dist-npm/components/core/position.js +27 -23
  16. package/dist-npm/components/core/promise-polyfill.js +11 -14
  17. package/dist-npm/components/core/screen-manager.js +59 -74
  18. package/dist-npm/components/core/theme.js +22 -32
  19. package/dist-npm/components/core/use-effect.js +9 -15
  20. package/dist-npm/components/core/use-keypress.js +19 -23
  21. package/dist-npm/components/core/use-memo.js +10 -16
  22. package/dist-npm/components/core/use-pagination.js +33 -32
  23. package/dist-npm/components/core/use-prefix.js +40 -38
  24. package/dist-npm/components/core/use-ref.js +2 -5
  25. package/dist-npm/components/core/use-state.js +15 -23
  26. package/dist-npm/components/core/useKeyPress.js +14 -17
  27. package/dist-npm/components/core/usePromptState.js +8 -14
  28. package/dist-npm/components/core/utils.js +7 -16
  29. package/dist-npm/components/date/date.js +173 -204
  30. package/dist-npm/components/editor/index.js +71 -92
  31. package/dist-npm/components/expand/index.js +96 -124
  32. package/dist-npm/components/figures/index.js +283 -294
  33. package/dist-npm/components/input/index.js +61 -87
  34. package/dist-npm/components/input/text-main.js +97 -124
  35. package/dist-npm/components/input/text.js +24 -28
  36. package/dist-npm/components/instance/basic.js +17 -25
  37. package/dist-npm/components/instance/browser.js +14 -18
  38. package/dist-npm/components/instance/reporter/basic.js +46 -65
  39. package/dist-npm/components/instance/reporter/browser.js +44 -47
  40. package/dist-npm/components/instance/reporter/fancy.js +83 -96
  41. package/dist-npm/components/instance/shared.js +2 -2
  42. package/dist-npm/components/mono/mono.js +52 -62
  43. package/dist-npm/components/mono/monoTwo.js +35 -49
  44. package/dist-npm/components/multiselect/group-multiselect.js +55 -71
  45. package/dist-npm/components/multiselect/multi-select-two.js +97 -130
  46. package/dist-npm/components/multiselect/multi-select.js +43 -49
  47. package/dist-npm/components/multiselect/multiselect-main.d.ts +1 -0
  48. package/dist-npm/components/multiselect/multiselect-main.js +158 -145
  49. package/dist-npm/components/multiselect/num-multi-select.js +97 -130
  50. package/dist-npm/components/multiselect/num-multiselect-main.js +24 -35
  51. package/dist-npm/components/next-steps/next-steps.js +23 -25
  52. package/dist-npm/components/number/index.js +78 -112
  53. package/dist-npm/components/number/number-main.js +95 -2
  54. package/dist-npm/components/password/index.js +54 -73
  55. package/dist-npm/components/password/password-main.js +119 -2
  56. package/dist-npm/components/password/password-three.js +26 -30
  57. package/dist-npm/components/progressbar/ProgressBar.js +45 -64
  58. package/dist-npm/components/progressbar/helper.js +33 -40
  59. package/dist-npm/components/progressbar/index.js +1 -1
  60. package/dist-npm/components/prompts/create.js +29 -44
  61. package/dist-npm/components/prompts/index.d.ts +1 -0
  62. package/dist-npm/components/prompts/index.js +46 -45
  63. package/dist-npm/components/prompts/prompt.js +211 -260
  64. package/dist-npm/components/prompts/promptTwo.js +561 -605
  65. package/dist-npm/components/prompts/relinka.js +237 -295
  66. package/dist-npm/components/range/range.js +247 -294
  67. package/dist-npm/components/rawlist/index.js +87 -107
  68. package/dist-npm/components/results/results.js +31 -37
  69. package/dist-npm/components/search/index.js +148 -193
  70. package/dist-npm/components/select/index.js +148 -186
  71. package/dist-npm/components/select/num-select-main.js +27 -27
  72. package/dist-npm/components/select/num-select.js +124 -5
  73. package/dist-npm/components/select/select-key.js +24 -25
  74. package/dist-npm/components/select/select-main.d.ts +1 -0
  75. package/dist-npm/components/select/select-main.js +143 -133
  76. package/dist-npm/components/select/select-three.js +32 -36
  77. package/dist-npm/components/select/select-two.js +94 -87
  78. package/dist-npm/components/spinner/index.js +107 -136
  79. package/dist-npm/components/st-end/end.js +34 -26
  80. package/dist-npm/components/st-end/start.js +29 -15
  81. package/dist-npm/components/toggle/index.js +113 -137
  82. package/dist-npm/components/visual/animate/animate.js +53 -10
  83. package/dist-npm/components/visual/ascii-art/ascii-art.js +12 -1
  84. package/dist-npm/main.js +1 -0
  85. package/dist-npm/testing/index.js +58 -83
  86. package/dist-npm/types/general.d.ts +1 -1
  87. package/dist-npm/types/general.js +0 -1
  88. package/dist-npm/types/index.js +2 -3
  89. package/dist-npm/types/keypress.js +35 -36
  90. package/dist-npm/types/readline.js +0 -1
  91. package/dist-npm/types/relinka.js +0 -1
  92. package/dist-npm/types/utils.js +0 -1
  93. package/dist-npm/utils/box.js +135 -137
  94. package/dist-npm/utils/color.js +65 -74
  95. package/dist-npm/utils/colorize.js +124 -156
  96. package/dist-npm/utils/component.js +532 -657
  97. package/dist-npm/utils/constants.js +64 -63
  98. package/dist-npm/utils/core.js +2 -3
  99. package/dist-npm/utils/decoder.js +244 -223
  100. package/dist-npm/utils/error.js +4 -9
  101. package/dist-npm/utils/errors.js +14 -4
  102. package/dist-npm/utils/format.js +19 -24
  103. package/dist-npm/utils/keypress.js +316 -414
  104. package/dist-npm/utils/log.js +11 -15
  105. package/dist-npm/utils/mapping.js +45 -52
  106. package/dist-npm/utils/messages.js +196 -183
  107. package/dist-npm/utils/platforms.js +16 -20
  108. package/dist-npm/utils/prompt-tmp.js +235 -286
  109. package/dist-npm/utils/prompt-two.js +235 -286
  110. package/dist-npm/utils/readline.js +5 -7
  111. package/dist-npm/utils/skeleton.js +130 -170
  112. package/dist-npm/utils/stream.js +2 -2
  113. package/dist-npm/utils/string.js +44 -58
  114. package/dist-npm/utils/terminal.js +23 -34
  115. package/dist-npm/utils/tree.js +30 -41
  116. package/dist-npm/utils/types.js +0 -1
  117. package/dist-npm/utils/utils.js +8 -8
  118. package/dist-npm/utils/variants.js +36 -44
  119. package/package.json +14 -14
  120. package/dist-npm/mod.js +0 -2
  121. /package/dist-npm/{mod.d.ts → main.d.ts} +0 -0
@@ -1,214 +1,176 @@
1
- import ansiEscapes from 'ansi-escapes';
2
- import colors from 'picocolors';
1
+ import ansiEscapes from "ansi-escapes";
2
+ import colors from "picocolors";
3
3
  import {
4
- createPrompt,
5
- useState,
6
- useKeypress,
7
- usePrefix,
8
- usePagination,
9
- useRef,
10
- useMemo,
11
- useEffect,
12
- isBackspaceKey,
13
- isEnterKey,
14
- isUpKey,
15
- isDownKey,
16
- isNumberKey,
17
- Separator,
18
- ValidationError,
19
- makeTheme,
20
- } from '../../components/core/index.js';
21
- import figures from '../../components/figures/index.js';
22
-
23
- const isString = (a) => typeof a === 'string';
24
-
4
+ createPrompt,
5
+ useState,
6
+ useKeypress,
7
+ usePrefix,
8
+ usePagination,
9
+ useRef,
10
+ useMemo,
11
+ useEffect,
12
+ isBackspaceKey,
13
+ isEnterKey,
14
+ isUpKey,
15
+ isDownKey,
16
+ isNumberKey,
17
+ Separator,
18
+ ValidationError,
19
+ makeTheme
20
+ } from "../../components/core/index.js";
21
+ import figures from "../../components/figures/index.js";
25
22
  const selectTheme = {
26
- icon: {
27
- cursor: figures.pointer,
28
- },
29
- style: {
30
- disabled: (text) => colors.dim(`- ${text}`),
31
- description: (text) => colors.cyan(text),
32
- },
33
- helpMode: 'auto',
23
+ icon: { cursor: figures.pointer },
24
+ style: {
25
+ disabled: (text) => colors.dim(`- ${text}`),
26
+ description: (text) => colors.cyan(text)
27
+ },
28
+ helpMode: "auto"
34
29
  };
35
-
36
30
  function isSelectable(item) {
37
- return !Separator.isSeparator(item) && !item.disabled;
31
+ return !Separator.isSeparator(item) && !item.disabled;
38
32
  }
39
-
40
33
  function normalizeChoices(choices) {
41
- return choices.map((choice) => {
42
- if (Separator.isSeparator(choice)) {
43
- return choice;
44
- }
45
-
46
- if (isString(choice)) {
47
- return {
48
- value: choice,
49
- name: choice,
50
- short: choice,
51
- disabled: false,
52
- };
53
- }
54
-
55
- const name = choice.name ?? String(choice.value);
56
-
57
- return {
58
- value: choice.value,
59
- name,
60
- description: choice.description,
61
- short: choice.short ?? name,
62
- disabled: choice.disabled ?? false,
63
- };
64
- });
34
+ return choices.map((choice) => {
35
+ if (Separator.isSeparator(choice)) {
36
+ return choice;
37
+ }
38
+ if (typeof choice === "string") {
39
+ return {
40
+ value: choice,
41
+ name: choice,
42
+ short: choice,
43
+ disabled: false
44
+ };
45
+ }
46
+ const name = choice.name ?? String(choice.value);
47
+ return {
48
+ value: choice.value,
49
+ name,
50
+ description: choice.description,
51
+ short: choice.short ?? name,
52
+ disabled: choice.disabled ?? false
53
+ };
54
+ });
65
55
  }
66
-
67
- const select = createPrompt((config, done) => {
68
- const {loop = true, pageSize = 7} = config;
56
+ const select = createPrompt(
57
+ (config, done) => {
58
+ const { loop = true, pageSize = 7 } = config;
69
59
  const firstRender = useRef(true);
70
60
  const theme = makeTheme(selectTheme, config.theme);
71
- const [status, setStatus] = useState('idle');
72
- const prefix = usePrefix({
73
- status,
74
- theme,
75
- });
61
+ const [status, setStatus] = useState("idle");
62
+ const prefix = usePrefix({ status, theme });
76
63
  const searchTimeoutRef = useRef();
77
-
78
- const items = useMemo(() => normalizeChoices(config.choices), [config.choices]);
79
-
64
+ const items = useMemo(
65
+ () => normalizeChoices(config.choices),
66
+ [config.choices]
67
+ );
80
68
  const bounds = useMemo(() => {
81
- const first = items.findIndex(isSelectable);
82
- const last = items.findLastIndex(isSelectable);
83
-
84
- if (first === -1) {
85
- throw new ValidationError('[select prompt] No selectable choices. All choices are disabled.');
86
- }
87
-
88
- return {
89
- first,
90
- last,
91
- };
69
+ const first = items.findIndex(isSelectable);
70
+ const last = items.findLastIndex(isSelectable);
71
+ if (first === -1) {
72
+ throw new ValidationError(
73
+ "[select prompt] No selectable choices. All choices are disabled."
74
+ );
75
+ }
76
+ return { first, last };
92
77
  }, [items]);
93
-
94
78
  const defaultItemIndex = useMemo(() => {
95
- if (!('default' in config)) {
96
- return -1;
97
- }
98
-
99
- return items.findIndex((item) => isSelectable(item) && item.value === config.default);
79
+ if (!("default" in config)) {
80
+ return -1;
81
+ }
82
+ return items.findIndex(
83
+ (item) => isSelectable(item) && item.value === config.default
84
+ );
100
85
  }, [config.default, items]);
101
-
102
- const [active, setActive] = useState(defaultItemIndex === -1 ? bounds.first : defaultItemIndex);
103
-
86
+ const [active, setActive] = useState(
87
+ defaultItemIndex === -1 ? bounds.first : defaultItemIndex
88
+ );
104
89
  const selectedChoice = items[active];
105
-
106
90
  useKeypress((key, rl) => {
107
- clearTimeout(searchTimeoutRef.current);
108
- if (isEnterKey(key)) {
109
- setStatus('done');
110
- done(selectedChoice.value);
111
- } else if (isUpKey(key) || isDownKey(key)) {
112
- rl.clearLine(0);
113
- if (loop || isUpKey(key) && active !== bounds.first || isDownKey(key) && active !== bounds.last) {
114
- const offset = isUpKey(key) ? -1 : 1;
115
- let next = active;
116
-
117
- do {
118
- next = (next + offset + items.length) % items.length;
119
- } while (!isSelectable(items[next]))
120
- setActive(next);
121
- }
122
- } else if (isNumberKey(key)) {
123
- rl.clearLine(0);
124
- const position = Number(key.name) - 1;
125
- const item = items[position];
126
-
127
- if (item != null && isSelectable(item)) {
128
- setActive(position);
129
- }
130
- } else if (isBackspaceKey(key)) {
131
- rl.clearLine(0);
132
- } else {
133
- const searchTerm = rl.line.toLowerCase();
134
- const matchIndex = items.findIndex((item) => {
135
- if (Separator.isSeparator(item) || !isSelectable(item)) {
136
- return false;
137
- }
138
-
139
- return item
140
- .name
141
- .toLowerCase()
142
- .startsWith(searchTerm);
143
- });
144
-
145
- if (matchIndex !== -1) {
146
- setActive(matchIndex);
147
- }
148
-
149
- searchTimeoutRef.current = setTimeout(() => {
150
- rl.clearLine(0);
151
- }, 700);
91
+ clearTimeout(searchTimeoutRef.current);
92
+ if (isEnterKey(key)) {
93
+ setStatus("done");
94
+ done(selectedChoice.value);
95
+ } else if (isUpKey(key) || isDownKey(key)) {
96
+ rl.clearLine(0);
97
+ if (loop || isUpKey(key) && active !== bounds.first || isDownKey(key) && active !== bounds.last) {
98
+ const offset = isUpKey(key) ? -1 : 1;
99
+ let next = active;
100
+ do {
101
+ next = (next + offset + items.length) % items.length;
102
+ } while (!isSelectable(items[next]));
103
+ setActive(next);
104
+ }
105
+ } else if (isNumberKey(key)) {
106
+ rl.clearLine(0);
107
+ const position = Number(key.name) - 1;
108
+ const item = items[position];
109
+ if (item != null && isSelectable(item)) {
110
+ setActive(position);
111
+ }
112
+ } else if (isBackspaceKey(key)) {
113
+ rl.clearLine(0);
114
+ } else {
115
+ const searchTerm = rl.line.toLowerCase();
116
+ const matchIndex = items.findIndex((item) => {
117
+ if (Separator.isSeparator(item) || !isSelectable(item)) {
118
+ return false;
119
+ }
120
+ return item.name.toLowerCase().startsWith(searchTerm);
121
+ });
122
+ if (matchIndex !== -1) {
123
+ setActive(matchIndex);
152
124
  }
153
-
154
-
125
+ searchTimeoutRef.current = setTimeout(() => {
126
+ rl.clearLine(0);
127
+ }, 700);
128
+ }
155
129
  });
156
- useEffect(() => () => {
130
+ useEffect(
131
+ () => () => {
157
132
  clearTimeout(searchTimeoutRef.current);
158
- }, []);
133
+ },
134
+ []
135
+ );
159
136
  const message = theme.style.message(config.message, status);
160
- let helpTipTop = '';
161
- let helpTipBottom = '';
162
-
163
- if (theme.helpMode === 'always' || theme.helpMode === 'auto' && firstRender.current) {
164
- firstRender.current = false;
165
- if (items.length > pageSize) {
166
- helpTipBottom = `
167
- ${theme.style.help('(Use arrow keys to reveal more choices)')}`;
168
- } else {
169
- helpTipTop = theme.style.help('(Use arrow keys)');
170
- }
137
+ let helpTipTop = "";
138
+ let helpTipBottom = "";
139
+ if (theme.helpMode === "always" || theme.helpMode === "auto" && firstRender.current) {
140
+ firstRender.current = false;
141
+ if (items.length > pageSize) {
142
+ helpTipBottom = `
143
+ ${theme.style.help("(Use arrow keys to reveal more choices)")}`;
144
+ } else {
145
+ helpTipTop = theme.style.help("(Use arrow keys)");
146
+ }
171
147
  }
172
-
173
148
  const page = usePagination({
174
- items,
175
- active,
176
- renderItem({item, isActive}) {
177
- if (Separator.isSeparator(item)) {
178
- return ` ${item.separator}`;
179
- }
180
-
181
- if (item.disabled) {
182
- const disabledLabel = isString(item.disabled) ? item.disabled : '(disabled)';
183
- return theme.style.disabled(`${item.name} ${disabledLabel}`);
184
- }
185
-
186
- const color = isActive ? theme.style.highlight : (x) => x;
187
- const cursor = isActive ? theme.icon.cursor : ` `;
188
-
189
- return color(`${cursor} ${item.name}`);
190
- },
191
- pageSize,
192
- loop,
149
+ items,
150
+ active,
151
+ renderItem({ item, isActive }) {
152
+ if (Separator.isSeparator(item)) {
153
+ return ` ${item.separator}`;
154
+ }
155
+ if (item.disabled) {
156
+ const disabledLabel = typeof item.disabled === "string" ? item.disabled : "(disabled)";
157
+ return theme.style.disabled(`${item.name} ${disabledLabel}`);
158
+ }
159
+ const color = isActive ? theme.style.highlight : (x) => x;
160
+ const cursor = isActive ? theme.icon.cursor : ` `;
161
+ return color(`${cursor} ${item.name}`);
162
+ },
163
+ pageSize,
164
+ loop
193
165
  });
194
-
195
- if (status === 'done') {
196
- return `${prefix} ${message} ${theme.style.answer(selectedChoice.short)}`;
166
+ if (status === "done") {
167
+ return `${prefix} ${message} ${theme.style.answer(selectedChoice.short)}`;
197
168
  }
198
-
199
169
  const choiceDescription = selectedChoice.description ? `
200
170
  ${theme.style.description(selectedChoice.description)}` : ``;
201
-
202
- return `${[
203
- prefix,
204
- message,
205
- helpTipTop,
206
- ]
207
- .filter(Boolean)
208
- .join(' ')}
171
+ return `${[prefix, message, helpTipTop].filter(Boolean).join(" ")}
209
172
  ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
210
- });
211
-
173
+ }
174
+ );
212
175
  export default select;
213
-
214
- export {Separator} from '../../components/core/index.js';
176
+ export { Separator } from "../../components/core/index.js";
@@ -1,30 +1,30 @@
1
- import {
2
- stdin as input,
3
- stdout as output,
4
- } from 'node:process';
5
- import readline from 'node:readline/promises';
6
-
7
- export async function selectPrompt({options, initial}) {
8
- const selectedIndex = initial ? options.findIndex((option) => option.value === initial) : 0;
9
- const rl = readline.createInterface({
10
- input,
11
- output,
1
+ import { stdin as input, stdout as output } from "process";
2
+ import readline from "readline/promises";
3
+ export async function selectPrompt(params) {
4
+ const { message, options, initial } = params;
5
+ const selectedIndex = initial ? options.findIndex((option) => option.value === initial) : 0;
6
+ const rl = readline.createInterface({ input, output });
7
+ while (true) {
8
+ console.log(`
9
+ ${message}`);
10
+ options.forEach((option, index2) => {
11
+ const prefix = index2 === selectedIndex ? "->" : " ";
12
+ const isDefault = option.value === initial ? "(default)" : "";
13
+ console.log(`${prefix} [${index2 + 1}] ${option.label} ${isDefault}`);
12
14
  });
13
-
14
- while (true) {
15
- const promptMessage = initial !== void 0 ? `Please select an option by number (default ${selectedIndex + 1}): ` : 'Please select an option by number: ';
16
- const response = await rl.question(promptMessage);
17
- let index;
18
-
19
- if (response.trim() === '' && initial !== void 0) {
20
- index = selectedIndex;
21
- } else {
22
- index = parseInt(response.trim(), 10) - 1;
23
- }
24
-
25
- if (index >= 0 && index < options.length) {
26
- rl.close();
27
- return options[index].value;
28
- }
15
+ const promptMessage = initial !== void 0 ? `Please select an option by number (default ${selectedIndex + 1}): ` : "Please select an option by number: ";
16
+ const response = await rl.question(promptMessage);
17
+ let index;
18
+ if (response.trim() === "" && initial !== void 0) {
19
+ index = selectedIndex;
20
+ } else {
21
+ index = parseInt(response.trim(), 10) - 1;
29
22
  }
23
+ if (index >= 0 && index < options.length) {
24
+ rl.close();
25
+ return options[index].value;
26
+ } else {
27
+ console.log("Invalid selection. Please try again.");
28
+ }
29
+ }
30
30
  }
@@ -1,6 +1,125 @@
1
- export async function numSelectPrompt({choices}) {
2
- if (!choices || !choices.length) {
3
- throw Error('Choices are required for select prompt.');
1
+ import { Value } from "@sinclair/typebox/value";
2
+ import { stdin as input, stdout as output } from "node:process";
3
+ import readline from "node:readline/promises";
4
+ import { colorize } from "../../utils/colorize.js";
5
+ import { fmt, msg, bar } from "../../utils/messages.js";
6
+ import {
7
+ countLines,
8
+ deleteLastLine,
9
+ deleteLastLines
10
+ } from "../../utils/terminal.js";
11
+ export async function numSelectPrompt(options) {
12
+ const {
13
+ title,
14
+ hint,
15
+ validate,
16
+ defaultValue,
17
+ schema,
18
+ titleColor = "cyanBright",
19
+ titleTypography = "bold",
20
+ titleVariant,
21
+ content,
22
+ contentColor,
23
+ contentTypography,
24
+ contentVariant,
25
+ borderColor = "viceGradient",
26
+ variantOptions,
27
+ inline = true,
28
+ choices
29
+ } = options;
30
+ if (!choices || choices.length === 0) {
31
+ throw new Error("Choices are required for select prompt.");
32
+ }
33
+ const rl = readline.createInterface({ input, output });
34
+ const formattedBar = bar({ borderColor });
35
+ let linesToDelete = 0;
36
+ let errorMessage = "";
37
+ while (true) {
38
+ if (linesToDelete > 0) {
39
+ deleteLastLines(linesToDelete);
4
40
  }
5
-
6
- while (true) {}}
41
+ const question = fmt({
42
+ type: errorMessage !== "" ? "M_ERROR" : "M_GENERAL",
43
+ title,
44
+ titleColor,
45
+ titleTypography,
46
+ titleVariant,
47
+ content,
48
+ contentColor,
49
+ contentTypography,
50
+ contentVariant,
51
+ borderColor,
52
+ hint,
53
+ variantOptions,
54
+ errorMessage
55
+ });
56
+ let choicesText = "";
57
+ if (inline) {
58
+ choicesText = choices.map(
59
+ (choice, index) => `${index + 1}) ${choice.title}${choice.description ? ` (${choice.description})` : ""}`
60
+ ).join(" / ");
61
+ } else {
62
+ choicesText = choices.map(
63
+ (choice, index) => `${index + 1}) ${choice.title}${choice.description ? ` - ${choice.description}` : ""}`
64
+ ).join(`
65
+ ${formattedBar} `);
66
+ }
67
+ const formattedPrompt = fmt({
68
+ type: "M_NULL",
69
+ title: `${question}${choicesText}
70
+ ${formattedBar} ${colorize(
71
+ `Enter your choice:`,
72
+ contentColor
73
+ )}
74
+ ${formattedBar} `
75
+ });
76
+ const questionLines = countLines(formattedPrompt);
77
+ linesToDelete = questionLines + 1;
78
+ const prompt = await rl.question(formattedPrompt);
79
+ const answer = prompt.trim() || defaultValue;
80
+ if (!prompt.trim() && defaultValue !== void 0) {
81
+ deleteLastLine();
82
+ msg({
83
+ type: "M_MIDDLE",
84
+ title: ` ${defaultValue}`,
85
+ titleColor: "none"
86
+ });
87
+ }
88
+ const num = Number(answer);
89
+ if (isNaN(num) || num < 1 || num > choices.length) {
90
+ errorMessage = `Please enter a number between 1 and ${choices.length}.`;
91
+ continue;
92
+ }
93
+ const selectedChoice = choices[num - 1];
94
+ const selectedValue = selectedChoice?.id ?? num;
95
+ let isValid = true;
96
+ errorMessage = "";
97
+ if (schema) {
98
+ isValid = Value.Check(schema, selectedValue);
99
+ if (!isValid) {
100
+ const errors = [...Value.Errors(schema, selectedValue)];
101
+ if (errors.length > 0) {
102
+ errorMessage = errors[0]?.message ?? "Invalid input.";
103
+ } else {
104
+ errorMessage = "Invalid input.";
105
+ }
106
+ }
107
+ }
108
+ if (validate && isValid) {
109
+ const validation = await validate(selectedValue);
110
+ if (validation !== true) {
111
+ isValid = false;
112
+ errorMessage = typeof validation === "string" ? validation : "Invalid input.";
113
+ }
114
+ }
115
+ if (isValid) {
116
+ msg({ type: "M_NEWLINE" });
117
+ rl.close();
118
+ if (selectedChoice?.action) {
119
+ await selectedChoice.action();
120
+ }
121
+ return selectedValue;
122
+ } else {
123
+ }
124
+ }
125
+ }
@@ -1,27 +1,26 @@
1
- import Prompt from '../prompts/prompt.js';
2
-
1
+ import Prompt from "../prompts/prompt.js";
3
2
  export default class SelectKeyPrompt extends Prompt {
4
- options;
5
- cursor = 0;
6
- constructor(opts) {
7
- super(opts, false);
8
- this.options = opts.options;
9
-
10
- const keys = this.options.map(({value: [initial]}) => initial?.toLowerCase());
11
-
12
- this.cursor = Math.max(keys.indexOf(opts.initialValue), 0);
13
- this.on('key', (key) => {
14
- if (!keys.includes(key)) {
15
- return;
16
- }
17
-
18
- const value = this.options.find(({value: [initial]}) => key === initial?.toLowerCase());
19
-
20
- if (value) {
21
- this.value = value.value;
22
- this.state = 'submit';
23
- this.emit('submit');
24
- }
25
- });
26
- }
3
+ options;
4
+ cursor = 0;
5
+ constructor(opts) {
6
+ super(opts, false);
7
+ this.options = opts.options;
8
+ const keys = this.options.map(
9
+ ({ value: [initial] }) => initial?.toLowerCase()
10
+ );
11
+ this.cursor = Math.max(keys.indexOf(opts.initialValue), 0);
12
+ this.on("key", (key) => {
13
+ if (!keys.includes(key)) {
14
+ return;
15
+ }
16
+ const value = this.options.find(
17
+ ({ value: [initial] }) => initial?.toLowerCase() === key
18
+ );
19
+ if (value) {
20
+ this.value = value.value;
21
+ this.state = "submit";
22
+ this.emit("submit");
23
+ }
24
+ });
25
+ }
27
26
  }
@@ -15,4 +15,5 @@ export declare function selectPrompt<T extends string>(params: {
15
15
  border?: boolean;
16
16
  endTitle?: string;
17
17
  endTitleColor?: ColorName;
18
+ maxItems?: number;
18
19
  }): Promise<T>;