@topcli/prompts 3.0.0 → 4.0.0
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.
- package/README.md +62 -4
- package/dist/index.d.mts +140 -0
- package/dist/index.mjs +1171 -0
- package/package.json +10 -10
- package/dist/index.cjs +0 -1312
- package/dist/index.d.cts +0 -121
- package/dist/index.d.ts +0 -121
- package/dist/index.js +0 -1271
package/README.md
CHANGED
|
@@ -55,6 +55,8 @@ Simple prompt, similar to `rl.question()` with an improved UI.
|
|
|
55
55
|
|
|
56
56
|
Use `options.defaultValue` to set a default value.
|
|
57
57
|
|
|
58
|
+
Use `options.hint` to display a hint alongside the question.
|
|
59
|
+
|
|
58
60
|
Use `options.secure` if you need to hide both input and answer. You can provide either a **boolean** or an **object** which allows to configure a `placeholder` such as `*`.
|
|
59
61
|
|
|
60
62
|
Use `options.signal` to set an `AbortSignal` (throws a [AbortError](#aborterror)).
|
|
@@ -170,7 +172,36 @@ Use `options.caseSensitive` to make autocomplete filters case sensitive. Default
|
|
|
170
172
|
|
|
171
173
|
Use `options.signal` to set an `AbortSignal` (throws a [AbortError](#aborterror)).
|
|
172
174
|
|
|
173
|
-
Use `options.skip` to skip prompt. It will return the first choice.
|
|
175
|
+
Use `options.skip` to skip prompt. It will return the first non-separator choice.
|
|
176
|
+
|
|
177
|
+
Use `Separator` items in `choices` to visually group options. Separators are not selectable and are skipped during keyboard navigation. When `autocomplete` is active and the user has typed a filter, separators are hidden.
|
|
178
|
+
|
|
179
|
+
```js
|
|
180
|
+
import { select } from "@topcli/prompts";
|
|
181
|
+
|
|
182
|
+
const framework = await select("Choose a framework", {
|
|
183
|
+
choices: [
|
|
184
|
+
{ type: "separator", label: "Frontend" },
|
|
185
|
+
{ value: "react", label: "React" },
|
|
186
|
+
{ value: "vue", label: "Vue" },
|
|
187
|
+
{ type: "separator", label: "Backend" },
|
|
188
|
+
{ value: "express", label: "Express" },
|
|
189
|
+
{ value: "fastify", label: "Fastify" },
|
|
190
|
+
]
|
|
191
|
+
});
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Use `choice.disabled` to mark a choice as non-selectable.
|
|
195
|
+
|
|
196
|
+
```js
|
|
197
|
+
const runner = await select("Choose a runner", {
|
|
198
|
+
choices: [
|
|
199
|
+
{ value: "node", label: "Node.js" },
|
|
200
|
+
{ value: "bun", label: "Bun", disabled: "not available" },
|
|
201
|
+
{ value: "deno", label: "Deno", disabled: true }
|
|
202
|
+
]
|
|
203
|
+
});
|
|
204
|
+
```
|
|
174
205
|
|
|
175
206
|
### `multiselect()`
|
|
176
207
|
|
|
@@ -193,6 +224,10 @@ Use `options.signal` to set an `AbortSignal` (throws a [AbortError](#aborterror)
|
|
|
193
224
|
|
|
194
225
|
Use `options.skip` to skip prompt. It will return `options.preSelectedChoices` if given, `[]` otherwise.
|
|
195
226
|
|
|
227
|
+
Use `Separator` items in `choices` to visually group options. Separators are not selectable and are skipped during keyboard navigation. When `autocomplete` is active and the user has typed a filter, separators are hidden.
|
|
228
|
+
|
|
229
|
+
Use `choice.disabled` to mark a choice as non-selectable.
|
|
230
|
+
|
|
196
231
|
### `confirm()`
|
|
197
232
|
|
|
198
233
|
```ts
|
|
@@ -212,14 +247,30 @@ Use `options.skip` to skip prompt. It will return `options.initial` (`false` by
|
|
|
212
247
|
|
|
213
248
|
The `PromptAgent` class allows to programmatically set the next answers for any prompt function, this can be useful for testing.
|
|
214
249
|
|
|
250
|
+
#### Shared instance
|
|
251
|
+
|
|
252
|
+
`PromptAgent.shared()` returns a singleton shared across all prompt calls that do not receive an explicit `agent` option. Suitable for simple test setups, but beware of state leaking between tests.
|
|
253
|
+
|
|
215
254
|
```ts
|
|
216
|
-
const agent = PromptAgent.
|
|
255
|
+
const agent = PromptAgent.shared();
|
|
217
256
|
agent.nextAnswer("John");
|
|
218
257
|
|
|
219
258
|
const input = await question("What's your name?");
|
|
220
259
|
assert.equal(input, "John");
|
|
221
260
|
```
|
|
222
261
|
|
|
262
|
+
#### Individual instance
|
|
263
|
+
|
|
264
|
+
For better isolation (e.g. in unit tests), create a dedicated `PromptAgent` and pass it via the `agent` option. This avoids any state leaking from the shared instance.
|
|
265
|
+
|
|
266
|
+
```ts
|
|
267
|
+
const agent = new PromptAgent();
|
|
268
|
+
agent.nextAnswer("John");
|
|
269
|
+
|
|
270
|
+
const input = await question("What's your name?", { agent });
|
|
271
|
+
assert.equal(input, "John");
|
|
272
|
+
```
|
|
273
|
+
|
|
223
274
|
> [!WARNING]
|
|
224
275
|
> Answers set with `PromptAgent` will **bypass** any logical & validation rules.
|
|
225
276
|
> Examples:
|
|
@@ -278,6 +329,7 @@ export type TransformationResponse<T> = InvalidResponse | ValidTransformationRes
|
|
|
278
329
|
|
|
279
330
|
export interface QuestionOptions<T = string> extends AbstractPromptOptions {
|
|
280
331
|
defaultValue?: string;
|
|
332
|
+
hint?: string;
|
|
281
333
|
validators?: PromptValidator<string>[];
|
|
282
334
|
transformer?: PromptTransformer<T>;
|
|
283
335
|
secure?: boolean | { placeholder: string };
|
|
@@ -287,10 +339,16 @@ export interface Choice<T = any> {
|
|
|
287
339
|
value: T;
|
|
288
340
|
label: string;
|
|
289
341
|
description?: string;
|
|
342
|
+
disabled?: boolean | string;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
export interface Separator {
|
|
346
|
+
type: "separator";
|
|
347
|
+
label?: string;
|
|
290
348
|
}
|
|
291
349
|
|
|
292
350
|
export interface SelectOptions<T extends string> extends AbstractPromptOptions {
|
|
293
|
-
choices: (Choice<T> | T)[];
|
|
351
|
+
choices: (Choice<T> | T | Separator)[];
|
|
294
352
|
maxVisible?: number;
|
|
295
353
|
ignoreValues?: (T | number | boolean)[];
|
|
296
354
|
validators?: PromptValidator<string>[];
|
|
@@ -299,7 +357,7 @@ export interface SelectOptions<T extends string> extends AbstractPromptOptions {
|
|
|
299
357
|
}
|
|
300
358
|
|
|
301
359
|
export interface MultiselectOptions<T extends string> extends AbstractPromptOptions {
|
|
302
|
-
choices: (Choice<T> | T)[];
|
|
360
|
+
choices: (Choice<T> | T | Separator)[];
|
|
303
361
|
maxVisible?: number;
|
|
304
362
|
preSelectedChoices?: (Choice<T> | T)[];
|
|
305
363
|
validators?: PromptValidator<string[]>[];
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import EventEmitter from "node:events";
|
|
2
|
+
import readline from "node:readline";
|
|
3
|
+
|
|
4
|
+
//#region src/validators.d.ts
|
|
5
|
+
type ValidResponseObject = {
|
|
6
|
+
isValid?: true;
|
|
7
|
+
};
|
|
8
|
+
type InvalidResponseObject = {
|
|
9
|
+
isValid: false;
|
|
10
|
+
error: string;
|
|
11
|
+
};
|
|
12
|
+
type ValidationResponseObject = ValidResponseObject | InvalidResponseObject;
|
|
13
|
+
type ValidationResponse = InvalidResponse | ValidResponse;
|
|
14
|
+
type InvalidResponse = string | InvalidResponseObject;
|
|
15
|
+
type ValidResponse = null | undefined | true | ValidResponseObject;
|
|
16
|
+
type ValidTransformationResponse<T> = {
|
|
17
|
+
isValid: true;
|
|
18
|
+
transformed: T;
|
|
19
|
+
};
|
|
20
|
+
type TransformationResponse<T> = InvalidResponse | ValidTransformationResponse<T>;
|
|
21
|
+
interface PromptValidator<T extends string | string[]> {
|
|
22
|
+
validate: (input: T) => ValidationResponse | Promise<ValidationResponse>;
|
|
23
|
+
}
|
|
24
|
+
interface PromptTransformer<T> {
|
|
25
|
+
transform: (input: string) => TransformationResponse<T> | Promise<TransformationResponse<T>>;
|
|
26
|
+
}
|
|
27
|
+
declare function required(): PromptValidator<any>;
|
|
28
|
+
//#endregion
|
|
29
|
+
//#region src/prompt-agent.d.ts
|
|
30
|
+
declare class PromptAgent<T = string> {
|
|
31
|
+
#private;
|
|
32
|
+
/**
|
|
33
|
+
* The prompts answers queue.
|
|
34
|
+
* When not empty, any prompt will be answered by the first answer in this list.
|
|
35
|
+
*/
|
|
36
|
+
nextAnswers: T[];
|
|
37
|
+
static shared<T>(): PromptAgent<any>;
|
|
38
|
+
/**
|
|
39
|
+
* Programmatically set the next answer for any prompt (`question()`, `confirm()`, `select()`)
|
|
40
|
+
*
|
|
41
|
+
* This is useful for testing.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```js
|
|
45
|
+
* const promptAgent = PromptAgent.shared();
|
|
46
|
+
* promptAgent.nextAnswer("toto");
|
|
47
|
+
*
|
|
48
|
+
* const input = await question("what is your name?");
|
|
49
|
+
* assert.equal(input, "toto");
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
nextAnswer(value: T | T[]): void;
|
|
53
|
+
clear(): void;
|
|
54
|
+
}
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/transformers.d.ts
|
|
57
|
+
declare function number(): PromptTransformer<number>;
|
|
58
|
+
declare function integer(): PromptTransformer<number>;
|
|
59
|
+
declare function url(): PromptTransformer<URL>;
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/types.d.ts
|
|
62
|
+
interface Choice<T extends string> {
|
|
63
|
+
value: T;
|
|
64
|
+
label: string;
|
|
65
|
+
description?: string;
|
|
66
|
+
disabled?: boolean | string;
|
|
67
|
+
}
|
|
68
|
+
interface Separator {
|
|
69
|
+
type: "separator";
|
|
70
|
+
label?: string;
|
|
71
|
+
}
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region src/prompts/abstract.d.ts
|
|
74
|
+
type Stdin = NodeJS.ReadStream & {
|
|
75
|
+
fd: 0;
|
|
76
|
+
};
|
|
77
|
+
type Stdout = NodeJS.WriteStream & {
|
|
78
|
+
fd: 1;
|
|
79
|
+
};
|
|
80
|
+
interface AbstractPromptOptions {
|
|
81
|
+
stdin?: Stdin;
|
|
82
|
+
stdout?: Stdout;
|
|
83
|
+
message: string;
|
|
84
|
+
skip?: boolean;
|
|
85
|
+
signal?: AbortSignal;
|
|
86
|
+
agent?: PromptAgent<string | boolean>;
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/prompts/question.d.ts
|
|
90
|
+
interface QuestionOptions<T = string> extends AbstractPromptOptions {
|
|
91
|
+
defaultValue?: string;
|
|
92
|
+
hint?: string;
|
|
93
|
+
validators?: PromptValidator<string>[];
|
|
94
|
+
transformer?: PromptTransformer<T>;
|
|
95
|
+
secure?: boolean | {
|
|
96
|
+
placeholder: string;
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region src/prompts/confirm.d.ts
|
|
101
|
+
interface ConfirmOptions extends AbstractPromptOptions {
|
|
102
|
+
initial?: boolean;
|
|
103
|
+
}
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region src/prompts/select.d.ts
|
|
106
|
+
interface SelectOptions<T extends string> extends AbstractPromptOptions {
|
|
107
|
+
choices: (Choice<T> | T | Separator)[];
|
|
108
|
+
maxVisible?: number;
|
|
109
|
+
ignoreValues?: (T | number | boolean)[];
|
|
110
|
+
validators?: PromptValidator<string>[];
|
|
111
|
+
autocomplete?: boolean;
|
|
112
|
+
caseSensitive?: boolean;
|
|
113
|
+
}
|
|
114
|
+
//#endregion
|
|
115
|
+
//#region src/prompts/multiselect.d.ts
|
|
116
|
+
interface MultiselectOptions<T extends string> extends AbstractPromptOptions {
|
|
117
|
+
choices: (Choice<T> | T | Separator)[];
|
|
118
|
+
maxVisible?: number;
|
|
119
|
+
preSelectedChoices?: (Choice<T> | T)[];
|
|
120
|
+
validators?: PromptValidator<string[]>[];
|
|
121
|
+
autocomplete?: boolean;
|
|
122
|
+
caseSensitive?: boolean;
|
|
123
|
+
showHint?: boolean;
|
|
124
|
+
}
|
|
125
|
+
//#endregion
|
|
126
|
+
//#region src/index.d.ts
|
|
127
|
+
declare function question<T = string>(message: string, options?: Omit<QuestionOptions<T>, "message">): Promise<T>;
|
|
128
|
+
declare function select<T extends string>(message: string, options: Omit<SelectOptions<T>, "message">): Promise<T>;
|
|
129
|
+
declare function confirm(message: string, options?: Omit<ConfirmOptions, "message">): Promise<boolean>;
|
|
130
|
+
declare function multiselect<T extends string>(message: string, options: Omit<MultiselectOptions<T>, "message">): Promise<T[]>;
|
|
131
|
+
declare const validators: {
|
|
132
|
+
required: typeof required;
|
|
133
|
+
};
|
|
134
|
+
declare const transformers: {
|
|
135
|
+
number: typeof number;
|
|
136
|
+
integer: typeof integer;
|
|
137
|
+
url: typeof url;
|
|
138
|
+
};
|
|
139
|
+
//#endregion
|
|
140
|
+
export { type AbstractPromptOptions, type Choice, type ConfirmOptions, type InvalidResponse, type InvalidResponseObject, type MultiselectOptions, PromptAgent, type PromptTransformer, type PromptValidator, type QuestionOptions, type SelectOptions, type Separator, type TransformationResponse, type ValidResponse, type ValidResponseObject, type ValidTransformationResponse, type ValidationResponse, type ValidationResponseObject, confirm, multiselect, question, select, transformers, validators };
|