0
# Prompt
1
2
Prompt is a comprehensive command-line prompting library for Node.js applications that enables developers to interactively collect user input with built-in validation, default values, and password hiding capabilities. It offers a simple yet powerful API with methods like `prompt.get()` and `prompt.addProperties()` for gathering user input, supports complex property validation through revalidator integration, provides extensive customization options including colors and formatting, and includes robust error handling and async/await support for modern JavaScript development patterns.
3
4
## Package Information
5
6
- **Package Name**: prompt
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install prompt`
10
11
## Core Imports
12
13
```javascript
14
const prompt = require('prompt');
15
```
16
17
ESM import:
18
19
```javascript
20
import prompt from 'prompt';
21
```
22
23
## Basic Usage
24
25
```javascript
26
const prompt = require('prompt');
27
28
// Start the prompt system
29
prompt.start();
30
31
// Get simple input
32
prompt.get(['username', 'email'], function (err, result) {
33
if (err) return console.error(err);
34
console.log('Username:', result.username);
35
console.log('Email:', result.email);
36
});
37
38
// Using Promises (modern approach)
39
async function getUserInfo() {
40
prompt.start();
41
try {
42
const result = await prompt.get(['username', 'email']);
43
console.log('Username:', result.username);
44
console.log('Email:', result.email);
45
} catch (err) {
46
console.error('Error:', err);
47
}
48
}
49
```
50
51
## Callback vs Promise Usage
52
53
Prompt supports both callback-based and Promise-based APIs for modern JavaScript development:
54
55
**Callback Style (Traditional):**
56
```javascript
57
prompt.get(['username', 'email'], function(err, result) {
58
if (err) return console.error(err);
59
console.log('Result:', result);
60
});
61
```
62
63
**Promise Style (Modern/Async-Await):**
64
```javascript
65
// Using Promises
66
prompt.get(['username', 'email'])
67
.then(result => console.log('Result:', result))
68
.catch(err => console.error(err));
69
70
// Using async/await
71
async function getUserInfo() {
72
try {
73
const result = await prompt.get(['username', 'email']);
74
console.log('Result:', result);
75
} catch (err) {
76
console.error(err);
77
}
78
}
79
```
80
81
**Important Notes:**
82
- When no callback is provided, methods return a Promise
83
- When a callback is provided, methods return the prompt object for chaining
84
- All main methods (`get`, `addProperties`) support both patterns
85
- `confirm` always requires a callback and does not return a Promise
86
87
## Architecture
88
89
Prompt is built around several key components:
90
91
- **Core Prompt System**: Main prompt object providing all user interaction methods
92
- **Schema Validation**: Integration with revalidator for complex input validation
93
- **Event System**: EventEmitter-based architecture for handling prompt lifecycle events
94
- **Stream Management**: Flexible input/output stream handling with default process.stdin/stdout
95
- **History System**: Built-in memory of previous prompt/answer pairs for reference
96
- **Cross-Platform Support**: Handles platform-specific differences (Windows vs Unix)
97
98
## Capabilities
99
100
### Prompt Initialization
101
102
Initialize the prompt system with configuration options.
103
104
```javascript { .api }
105
/**
106
* Starts the prompt by listening to the appropriate events on stdin/stdout
107
* @param {Object} options - Optional configuration options
108
* @param {ReadableStream} options.stdin - Input stream (default: process.stdin)
109
* @param {WritableStream} options.stdout - Output stream (default: process.stdout)
110
* @param {number} options.memory - Number of previous prompts to remember (default: 10)
111
* @param {boolean} options.allowEmpty - Allow empty responses globally (default: false)
112
* @param {string} options.message - Default message prefix (default: 'prompt')
113
* @param {string} options.delimiter - Default delimiter (default: ': ')
114
* @param {boolean} options.colors - Enable colors (default: true)
115
* @param {boolean} options.noHandleSIGINT - Disable SIGINT handling (default: false)
116
* @returns {Object} prompt object for chaining
117
*/
118
function start(options);
119
```
120
121
**Usage Example:**
122
123
```javascript
124
const prompt = require('prompt');
125
126
// Basic initialization
127
prompt.start();
128
129
// Custom configuration
130
prompt.start({
131
message: 'myapp',
132
delimiter: ' > ',
133
colors: false,
134
allowEmpty: true
135
});
136
```
137
138
### Input Collection
139
140
Get user input using simple property names or complex validation schemas.
141
142
```javascript { .api }
143
/**
144
* Gets input from the user via stdin for specified message(s)
145
* @param {string|string[]|PropertySchema|FullSchema} schema - Set of variables to get input for
146
* @param {(err: Error|null, result?: Object) => void} callback - Optional callback function
147
* @returns {Promise<Object>|typeof prompt} Promise when no callback provided, otherwise prompt object
148
*/
149
function get(schema, callback);
150
151
/** Complete schema object with properties */
152
interface FullSchema {
153
properties: {
154
[propertyName: string]: PropertySchema;
155
};
156
}
157
```
158
159
**Schema Types:**
160
161
- **String**: Simple property name
162
- **Array**: List of property names
163
- **Object**: Complex validation schema with properties
164
165
**Usage Examples:**
166
167
```javascript
168
// Simple property names
169
const result = await prompt.get(['name', 'age']);
170
171
// Array of properties
172
const result = await prompt.get(['username', 'password', 'email']);
173
174
// Complex validation schema
175
const schema = {
176
properties: {
177
name: {
178
pattern: /^[a-zA-Z\s\-]+$/,
179
message: 'Name must be only letters, spaces, or dashes',
180
required: true
181
},
182
password: {
183
hidden: true,
184
replace: '*'
185
},
186
age: {
187
type: 'integer',
188
minimum: 0,
189
maximum: 120,
190
message: 'Age must be between 0 and 120'
191
}
192
}
193
};
194
195
const result = await prompt.get(schema);
196
```
197
198
### Property Addition
199
200
Add missing properties to existing objects by prompting the user.
201
202
```javascript { .api }
203
/**
204
* Prompts user for values of properties if obj doesn't already have them
205
* @param {Object} obj - Object to add properties to
206
* @param {Array} properties - List of properties to get values for
207
* @param {Function} callback - Callback function (err, updatedObj)
208
* @returns {Object} prompt object for chaining
209
*/
210
function addProperties(obj, properties, callback);
211
```
212
213
**Usage Example:**
214
215
```javascript
216
const config = {
217
host: 'localhost',
218
port: 3000
219
};
220
221
// Only prompt for missing properties
222
prompt.addProperties(config, ['host', 'port', 'username', 'password'], function(err, result) {
223
// Only prompts for 'username' and 'password' since host/port already exist
224
console.log('Complete config:', result);
225
});
226
```
227
228
### Confirmation Prompts
229
230
Prompt for yes/no confirmation with customizable validation.
231
232
```javascript { .api }
233
/**
234
* Confirms a single or series of messages by prompting for Y/N response
235
* @param {string|ConfirmSchema|Array<string|ConfirmSchema>} msg - Set of messages to confirm
236
* @param {Object} options - Optional additional options to merge with each confirm schema
237
* @param {(err: Error|null, isConfirmed: boolean) => void} callback - Callback function
238
* @returns {void} Calls callback with true if ALL messages confirmed, otherwise false
239
*/
240
function confirm(msg, options, callback);
241
242
/** Confirmation schema with customizable validation */
243
interface ConfirmSchema {
244
/** Message to display for confirmation */
245
description: string;
246
/** Pattern for valid responses (default: /^[yntf]{1}/i) */
247
pattern?: RegExp;
248
/** Pattern for "yes" responses (default: /^[yt]{1}/i) */
249
yes?: RegExp;
250
/** Error message for invalid responses */
251
message?: string;
252
}
253
```
254
255
**Usage Examples:**
256
257
```javascript
258
// Simple confirmation
259
prompt.confirm('Are you sure?', function(err, result) {
260
console.log('User confirmed:', result);
261
});
262
263
// Custom validation
264
const confirmOptions = {
265
description: 'Delete all files?',
266
pattern: /^[yntf]{1}/i,
267
yes: /^[yt]{1}/i,
268
message: 'Please enter yes, y, no, n, true, t, false, or f'
269
};
270
271
prompt.confirm(confirmOptions, function(err, result) {
272
if (result) {
273
console.log('Proceeding with deletion...');
274
}
275
});
276
```
277
278
### Low-Level Input
279
280
Get single input with validation (used internally by get()).
281
282
```javascript { .api }
283
/**
284
* Gets input from user via stdin for specified message with validation
285
* @param {Object|string} prop - Property schema or name
286
* @param {Function} callback - Callback function (err, input)
287
*/
288
function getInput(prop, callback);
289
```
290
291
### State Management
292
293
Control the prompt system lifecycle and state.
294
295
```javascript { .api }
296
/**
297
* Pauses input coming in from stdin
298
* @returns {Object} prompt object for chaining
299
*/
300
function pause();
301
302
/**
303
* Resumes input coming in from stdin
304
* @returns {Object} prompt object for chaining
305
*/
306
function resume();
307
308
/**
309
* Stops input coming in from stdin and destroys it
310
* @returns {Object} prompt object for chaining
311
*/
312
function stop();
313
```
314
315
**Usage Example:**
316
317
```javascript
318
prompt.start();
319
320
// Pause during async operation
321
prompt.pause();
322
await someAsyncOperation();
323
prompt.resume();
324
325
// Later, stop completely
326
prompt.stop();
327
```
328
329
### History Access
330
331
Access previous prompt/answer pairs from memory.
332
333
```javascript { .api }
334
/**
335
* Returns property:value pair from within the prompts history array
336
* @param {number|string} search - Index or property name to find
337
* @returns {Object|null} History entry object or null if not found
338
*/
339
function history(search);
340
```
341
342
**Usage Example:**
343
344
```javascript
345
// Get by index
346
const lastPrompt = prompt.history(0);
347
348
// Get by property name
349
const usernameEntry = prompt.history('username');
350
console.log('Previous username:', usernameEntry?.value);
351
```
352
353
## Configuration Properties
354
355
### State Properties
356
357
```javascript { .api }
358
/** Indicates if prompt has been started */
359
boolean started;
360
361
/** Indicates if prompt is currently paused */
362
boolean paused;
363
364
/** Indicates if prompt has been stopped */
365
boolean stopped;
366
```
367
368
### Behavior Properties
369
370
```javascript { .api }
371
/** Global setting to allow empty responses */
372
boolean allowEmpty;
373
374
/** Default message prefix for prompts */
375
string message;
376
377
/** Default delimiter between message and input */
378
string delimiter;
379
380
/** Enable/disable colored output */
381
boolean colors;
382
383
/** Number of previous prompt/answer pairs to remember */
384
number memory;
385
```
386
387
### Storage Properties
388
389
```javascript { .api }
390
/** Stored property schemas for reuse */
391
Object properties;
392
393
/** Property values to override during prompting */
394
Object override;
395
```
396
397
### Utility Properties
398
399
```javascript { .api }
400
/** Package version from package.json */
401
string version;
402
403
/** Winston logger instance for prompt output */
404
Object logger;
405
```
406
407
## Schema Validation
408
409
Prompt uses JSON Schema-compatible validation with additional properties:
410
411
```javascript { .api }
412
interface PropertySchema {
413
// Display Properties
414
/** Prompt text displayed to user */
415
description?: string;
416
/** Error message displayed on validation failure */
417
message?: string;
418
419
// Data Type Properties
420
/** Data type: 'string', 'boolean', 'number', 'integer', 'array' */
421
type?: 'string' | 'boolean' | 'number' | 'integer' | 'array';
422
/** Default value if no input provided */
423
default?: any;
424
/** Whether input is required (non-empty) */
425
required?: boolean;
426
427
// Validation Properties
428
/** Regular expression for validation */
429
pattern?: RegExp;
430
/** Custom validation function */
431
conform?: (value: any) => boolean;
432
/** Format validation (from revalidator) - 'email', 'url', 'date-time', etc. */
433
format?: string;
434
435
// Input Control Properties
436
/** Hide input characters (for passwords) */
437
hidden?: boolean;
438
/** Replacement character for hidden input (default: '*') */
439
replace?: string;
440
/** Transform input before validation */
441
before?: (value: any) => any;
442
/** Dynamic condition to show/skip prompt */
443
ask?: () => boolean;
444
445
// Array Type Properties
446
/** For array type - maximum number of items */
447
maxItems?: number;
448
/** For array type - minimum number of items */
449
minItems?: number;
450
451
// Numeric Type Properties (inherited from revalidator)
452
/** For number/integer types - minimum value */
453
minimum?: number;
454
/** For number/integer types - maximum value */
455
maximum?: number;
456
457
// String Type Properties (inherited from revalidator)
458
/** For string type - minimum length */
459
minLength?: number;
460
/** For string type - maximum length */
461
maxLength?: number;
462
}
463
```
464
465
**Type-Specific Behavior:**
466
467
- **boolean**: Accepts case-insensitive 'true', 't', 'false', 'f'
468
- **number/integer**: Automatically converts string input to Number
469
- **array**: Requires users to press Ctrl+C to end input, supports maxItems/minItems
470
- **string**: Default type, no automatic conversion
471
472
## Event System
473
474
Prompt inherits from EventEmitter and emits the following events:
475
476
```javascript { .api }
477
/**
478
* Emitted when prompt.start() is called successfully
479
* Fired after streams are configured and SIGINT handlers are set up
480
*/
481
event 'start'
482
483
/**
484
* Emitted when prompt.pause() is called
485
* Fired after stdin.pause() is executed and prompt is in paused state
486
*/
487
event 'pause'
488
489
/**
490
* Emitted when prompt.resume() is called
491
* Fired after stdin.resume() is executed and prompt is active again
492
*/
493
event 'resume'
494
495
/**
496
* Emitted when prompt.stop() is called
497
* Fired after stdin is destroyed and prompt is fully stopped
498
*/
499
event 'stop'
500
501
/**
502
* Emitted when getInput begins prompting for a specific property
503
* Fired before the actual input prompt is displayed to the user
504
* @param {Object} prop - Property object being prompted for
505
* @param {Array} prop.path - Property path array (e.g., ['username'])
506
* @param {Object} prop.schema - Validation schema for this property
507
*/
508
event 'prompt'
509
510
/**
511
* Emitted when user input fails validation
512
* Fired after validation fails but before re-prompting the user
513
* @param {Object} prop - Property object that failed validation
514
* @param {Array} prop.path - Property path array
515
* @param {Object} prop.schema - Validation schema that failed
516
* @param {any} input - The input value that failed validation
517
*/
518
event 'invalid'
519
```
520
521
**Usage Example:**
522
523
```javascript
524
prompt.on('prompt', function(prop) {
525
console.log('Prompting for:', prop.path);
526
});
527
528
prompt.on('invalid', function(prop, input) {
529
console.log('Invalid input:', input, 'for property:', prop.path);
530
});
531
```
532
533
## Error Handling
534
535
### Validation Errors
536
537
Validation is handled through the revalidator package:
538
539
```javascript
540
// Validation errors cause re-prompting
541
const schema = {
542
properties: {
543
email: {
544
format: 'email',
545
message: 'Please enter a valid email address'
546
}
547
}
548
};
549
550
try {
551
const result = await prompt.get(schema);
552
} catch (err) {
553
// Handle system errors (not validation errors)
554
console.error('System error:', err);
555
}
556
```
557
558
### Exception Handling
559
560
```javascript
561
// Handle SIGINT (Ctrl+C)
562
process.on('SIGINT', function() {
563
console.log('Received SIGINT, exiting...');
564
process.exit(1);
565
});
566
567
// Handle stream errors
568
prompt.start({
569
stdin: customInputStream,
570
stdout: customOutputStream
571
});
572
```
573
574
## Advanced Usage
575
576
### Custom Validation
577
578
```javascript
579
const schema = {
580
properties: {
581
username: {
582
conform: function(value) {
583
return value.length >= 3 && /^[a-zA-Z0-9_]+$/.test(value);
584
},
585
message: 'Username must be at least 3 characters and contain only letters, numbers, and underscores'
586
}
587
}
588
};
589
```
590
591
### Dynamic Prompts
592
593
```javascript
594
const schema = {
595
properties: {
596
hasEmail: {
597
type: 'boolean',
598
description: 'Do you have an email?'
599
},
600
email: {
601
ask: function() {
602
return prompt.history('hasEmail')?.value === true;
603
},
604
format: 'email',
605
description: 'Enter your email'
606
}
607
}
608
};
609
```
610
611
### Password Input
612
613
```javascript
614
const schema = {
615
properties: {
616
password: {
617
hidden: true,
618
replace: '*',
619
description: 'Enter password'
620
},
621
confirmPassword: {
622
hidden: true,
623
replace: '*',
624
description: 'Confirm password',
625
conform: function(value) {
626
return value === prompt.history('password')?.value;
627
},
628
message: 'Passwords do not match'
629
}
630
}
631
};
632
```