1 | ;
|
2 |
|
3 | const $ = exports;
|
4 |
|
5 | const el = require('./elements');
|
6 |
|
7 | const noop = v => v;
|
8 |
|
9 | function toPrompt(type, args, opts = {}) {
|
10 | return new Promise((res, rej) => {
|
11 | const p = new el[type](args);
|
12 | const onAbort = opts.onAbort || noop;
|
13 | const onSubmit = opts.onSubmit || noop;
|
14 | const onExit = opts.onExit || noop;
|
15 | p.on('state', args.onState || noop);
|
16 | p.on('submit', x => res(onSubmit(x)));
|
17 | p.on('exit', x => res(onExit(x)));
|
18 | p.on('abort', x => rej(onAbort(x)));
|
19 | });
|
20 | }
|
21 | /**
|
22 | * Text prompt
|
23 | * @param {string} args.message Prompt message to display
|
24 | * @param {string} [args.initial] Default string value
|
25 | * @param {string} [args.style="default"] Render style ('default', 'password', 'invisible')
|
26 | * @param {function} [args.onState] On state change callback
|
27 | * @param {function} [args.validate] Function to validate user input
|
28 | * @param {Stream} [args.stdin] The Readable stream to listen to
|
29 | * @param {Stream} [args.stdout] The Writable stream to write readline data to
|
30 | * @returns {Promise} Promise with user input
|
31 | */
|
32 |
|
33 |
|
34 | $.text = args => toPrompt('TextPrompt', args);
|
35 | /**
|
36 | * Password prompt with masked input
|
37 | * @param {string} args.message Prompt message to display
|
38 | * @param {string} [args.initial] Default string value
|
39 | * @param {function} [args.onState] On state change callback
|
40 | * @param {function} [args.validate] Function to validate user input
|
41 | * @param {Stream} [args.stdin] The Readable stream to listen to
|
42 | * @param {Stream} [args.stdout] The Writable stream to write readline data to
|
43 | * @returns {Promise} Promise with user input
|
44 | */
|
45 |
|
46 |
|
47 | $.password = args => {
|
48 | args.style = 'password';
|
49 | return $.text(args);
|
50 | };
|
51 | /**
|
52 | * Prompt where input is invisible, like sudo
|
53 | * @param {string} args.message Prompt message to display
|
54 | * @param {string} [args.initial] Default string value
|
55 | * @param {function} [args.onState] On state change callback
|
56 | * @param {function} [args.validate] Function to validate user input
|
57 | * @param {Stream} [args.stdin] The Readable stream to listen to
|
58 | * @param {Stream} [args.stdout] The Writable stream to write readline data to
|
59 | * @returns {Promise} Promise with user input
|
60 | */
|
61 |
|
62 |
|
63 | $.invisible = args => {
|
64 | args.style = 'invisible';
|
65 | return $.text(args);
|
66 | };
|
67 | /**
|
68 | * Number prompt
|
69 | * @param {string} args.message Prompt message to display
|
70 | * @param {number} args.initial Default number value
|
71 | * @param {function} [args.onState] On state change callback
|
72 | * @param {number} [args.max] Max value
|
73 | * @param {number} [args.min] Min value
|
74 | * @param {string} [args.style="default"] Render style ('default', 'password', 'invisible')
|
75 | * @param {Boolean} [opts.float=false] Parse input as floats
|
76 | * @param {Number} [opts.round=2] Round floats to x decimals
|
77 | * @param {Number} [opts.increment=1] Number to increment by when using arrow-keys
|
78 | * @param {function} [args.validate] Function to validate user input
|
79 | * @param {Stream} [args.stdin] The Readable stream to listen to
|
80 | * @param {Stream} [args.stdout] The Writable stream to write readline data to
|
81 | * @returns {Promise} Promise with user input
|
82 | */
|
83 |
|
84 |
|
85 | $.number = args => toPrompt('NumberPrompt', args);
|
86 | /**
|
87 | * Date prompt
|
88 | * @param {string} args.message Prompt message to display
|
89 | * @param {number} args.initial Default number value
|
90 | * @param {function} [args.onState] On state change callback
|
91 | * @param {number} [args.max] Max value
|
92 | * @param {number} [args.min] Min value
|
93 | * @param {string} [args.style="default"] Render style ('default', 'password', 'invisible')
|
94 | * @param {Boolean} [opts.float=false] Parse input as floats
|
95 | * @param {Number} [opts.round=2] Round floats to x decimals
|
96 | * @param {Number} [opts.increment=1] Number to increment by when using arrow-keys
|
97 | * @param {function} [args.validate] Function to validate user input
|
98 | * @param {Stream} [args.stdin] The Readable stream to listen to
|
99 | * @param {Stream} [args.stdout] The Writable stream to write readline data to
|
100 | * @returns {Promise} Promise with user input
|
101 | */
|
102 |
|
103 |
|
104 | $.date = args => toPrompt('DatePrompt', args);
|
105 | /**
|
106 | * Classic yes/no prompt
|
107 | * @param {string} args.message Prompt message to display
|
108 | * @param {boolean} [args.initial=false] Default value
|
109 | * @param {function} [args.onState] On state change callback
|
110 | * @param {Stream} [args.stdin] The Readable stream to listen to
|
111 | * @param {Stream} [args.stdout] The Writable stream to write readline data to
|
112 | * @returns {Promise} Promise with user input
|
113 | */
|
114 |
|
115 |
|
116 | $.confirm = args => toPrompt('ConfirmPrompt', args);
|
117 | /**
|
118 | * List prompt, split intput string by `seperator`
|
119 | * @param {string} args.message Prompt message to display
|
120 | * @param {string} [args.initial] Default string value
|
121 | * @param {string} [args.style="default"] Render style ('default', 'password', 'invisible')
|
122 | * @param {string} [args.separator] String separator
|
123 | * @param {function} [args.onState] On state change callback
|
124 | * @param {Stream} [args.stdin] The Readable stream to listen to
|
125 | * @param {Stream} [args.stdout] The Writable stream to write readline data to
|
126 | * @returns {Promise} Promise with user input, in form of an `Array`
|
127 | */
|
128 |
|
129 |
|
130 | $.list = args => {
|
131 | const sep = args.separator || ',';
|
132 | return toPrompt('TextPrompt', args, {
|
133 | onSubmit: str => str.split(sep).map(s => s.trim())
|
134 | });
|
135 | };
|
136 | /**
|
137 | * Toggle/switch prompt
|
138 | * @param {string} args.message Prompt message to display
|
139 | * @param {boolean} [args.initial=false] Default value
|
140 | * @param {string} [args.active="on"] Text for `active` state
|
141 | * @param {string} [args.inactive="off"] Text for `inactive` state
|
142 | * @param {function} [args.onState] On state change callback
|
143 | * @param {Stream} [args.stdin] The Readable stream to listen to
|
144 | * @param {Stream} [args.stdout] The Writable stream to write readline data to
|
145 | * @returns {Promise} Promise with user input
|
146 | */
|
147 |
|
148 |
|
149 | $.toggle = args => toPrompt('TogglePrompt', args);
|
150 | /**
|
151 | * Interactive select prompt
|
152 | * @param {string} args.message Prompt message to display
|
153 | * @param {Array} args.choices Array of choices objects `[{ title, value }, ...]`
|
154 | * @param {number} [args.initial] Index of default value
|
155 | * @param {String} [args.hint] Hint to display
|
156 | * @param {function} [args.onState] On state change callback
|
157 | * @param {Stream} [args.stdin] The Readable stream to listen to
|
158 | * @param {Stream} [args.stdout] The Writable stream to write readline data to
|
159 | * @returns {Promise} Promise with user input
|
160 | */
|
161 |
|
162 |
|
163 | $.select = args => toPrompt('SelectPrompt', args);
|
164 | /**
|
165 | * Interactive multi-select / autocompleteMultiselect prompt
|
166 | * @param {string} args.message Prompt message to display
|
167 | * @param {Array} args.choices Array of choices objects `[{ title, value, [selected] }, ...]`
|
168 | * @param {number} [args.max] Max select
|
169 | * @param {string} [args.hint] Hint to display user
|
170 | * @param {Number} [args.cursor=0] Cursor start position
|
171 | * @param {function} [args.onState] On state change callback
|
172 | * @param {Stream} [args.stdin] The Readable stream to listen to
|
173 | * @param {Stream} [args.stdout] The Writable stream to write readline data to
|
174 | * @returns {Promise} Promise with user input
|
175 | */
|
176 |
|
177 |
|
178 | $.multiselect = args => {
|
179 | args.choices = [].concat(args.choices || []);
|
180 |
|
181 | const toSelected = items => items.filter(item => item.selected).map(item => item.value);
|
182 |
|
183 | return toPrompt('MultiselectPrompt', args, {
|
184 | onAbort: toSelected,
|
185 | onSubmit: toSelected
|
186 | });
|
187 | };
|
188 |
|
189 | $.autocompleteMultiselect = args => {
|
190 | args.choices = [].concat(args.choices || []);
|
191 |
|
192 | const toSelected = items => items.filter(item => item.selected).map(item => item.value);
|
193 |
|
194 | return toPrompt('AutocompleteMultiselectPrompt', args, {
|
195 | onAbort: toSelected,
|
196 | onSubmit: toSelected
|
197 | });
|
198 | };
|
199 |
|
200 | const byTitle = (input, choices) => Promise.resolve(choices.filter(item => item.title.slice(0, input.length).toLowerCase() === input.toLowerCase()));
|
201 | /**
|
202 | * Interactive auto-complete prompt
|
203 | * @param {string} args.message Prompt message to display
|
204 | * @param {Array} args.choices Array of auto-complete choices objects `[{ title, value }, ...]`
|
205 | * @param {Function} [args.suggest] Function to filter results based on user input. Defaults to sort by `title`
|
206 | * @param {number} [args.limit=10] Max number of results to show
|
207 | * @param {string} [args.style="default"] Render style ('default', 'password', 'invisible')
|
208 | * @param {String} [args.initial] Index of the default value
|
209 | * @param {boolean} [opts.clearFirst] The first ESCAPE keypress will clear the input
|
210 | * @param {String} [args.fallback] Fallback message - defaults to initial value
|
211 | * @param {function} [args.onState] On state change callback
|
212 | * @param {Stream} [args.stdin] The Readable stream to listen to
|
213 | * @param {Stream} [args.stdout] The Writable stream to write readline data to
|
214 | * @returns {Promise} Promise with user input
|
215 | */
|
216 |
|
217 |
|
218 | $.autocomplete = args => {
|
219 | args.suggest = args.suggest || byTitle;
|
220 | args.choices = [].concat(args.choices || []);
|
221 | return toPrompt('AutocompletePrompt', args);
|
222 | }; |
\ | No newline at end of file |