spyne-cli 0.3.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.
Files changed (70) hide show
  1. package/README.md +3 -0
  2. package/index-cli.js +56 -0
  3. package/index.js +14 -0
  4. package/lib/ansi.js +116 -0
  5. package/lib/combos.js +75 -0
  6. package/lib/completer.js +52 -0
  7. package/lib/interpolate.js +266 -0
  8. package/lib/keypress.js +243 -0
  9. package/lib/placeholder.js +63 -0
  10. package/lib/prompt.js +485 -0
  11. package/lib/prompts/autocomplete.js +113 -0
  12. package/lib/prompts/basicauth.js +41 -0
  13. package/lib/prompts/confirm.js +13 -0
  14. package/lib/prompts/editable.js +136 -0
  15. package/lib/prompts/form.js +196 -0
  16. package/lib/prompts/index.js +28 -0
  17. package/lib/prompts/input.js +55 -0
  18. package/lib/prompts/invisible.js +11 -0
  19. package/lib/prompts/list.js +36 -0
  20. package/lib/prompts/multiselect.js +11 -0
  21. package/lib/prompts/numeral.js +1 -0
  22. package/lib/prompts/password.js +18 -0
  23. package/lib/prompts/quiz.js +37 -0
  24. package/lib/prompts/scale.js +237 -0
  25. package/lib/prompts/select.js +139 -0
  26. package/lib/prompts/snippet.js +185 -0
  27. package/lib/prompts/sort.js +37 -0
  28. package/lib/prompts/survey.js +163 -0
  29. package/lib/prompts/text.js +1 -0
  30. package/lib/prompts/toggle.js +109 -0
  31. package/lib/render.js +33 -0
  32. package/lib/roles.js +46 -0
  33. package/lib/state.js +69 -0
  34. package/lib/styles.js +144 -0
  35. package/lib/symbols.js +66 -0
  36. package/lib/theme.js +11 -0
  37. package/lib/timer.js +38 -0
  38. package/lib/types/array.js +658 -0
  39. package/lib/types/auth.js +29 -0
  40. package/lib/types/boolean.js +88 -0
  41. package/lib/types/index.js +7 -0
  42. package/lib/types/number.js +86 -0
  43. package/lib/types/string.js +185 -0
  44. package/lib/utils.js +268 -0
  45. package/package.json +45 -0
  46. package/src/app/channels/.gitkeep +0 -0
  47. package/src/app/components/.gitkeep +0 -0
  48. package/src/app/traits/.gitkeep +0 -0
  49. package/src/spyne-file-prompt.js +63 -0
  50. package/src/spyne-template-prompts.js +171 -0
  51. package/src/templates/generate-file-string.js +131 -0
  52. package/src/templates/generate-prompt-input-fields.js +256 -0
  53. package/src/templates/generate-prompt-input-object.js +46 -0
  54. package/src/templates/generate-prompt-output.js +109 -0
  55. package/src/ui.js +16 -0
  56. package/src/utils/color-utils.js +36 -0
  57. package/src/utils/error-logger.js +15 -0
  58. package/src/utils/file-utils.js +69 -0
  59. package/tests/generate-file-prompt.test.js +47 -0
  60. package/tests/generate-file-string.test.js +68 -0
  61. package/tests/generate-prompt-input-fields-methods.test.js +178 -0
  62. package/tests/generate-prompt-input-fields.test.js +181 -0
  63. package/tests/generate-prompt-input-object.test.js +41 -0
  64. package/tests/generate-prompt-output.test.js +60 -0
  65. package/tests/index.test.js +13 -0
  66. package/tests/mocks/answers.js +33 -0
  67. package/tests/mocks/answers.json +33 -0
  68. package/tests/mocks/enquirer-data.js +411 -0
  69. package/tests/mocks/enquirer-data.json +409 -0
  70. package/tests/utils/file-utils.test.js +70 -0
@@ -0,0 +1,658 @@
1
+ 'use strict';
2
+
3
+ const colors = require('ansi-colors');
4
+ const Prompt = require('../prompt');
5
+ const roles = require('../roles');
6
+ const utils = require('../utils');
7
+ const { reorder, scrollUp, scrollDown, isObject, swap } = utils;
8
+
9
+ class ArrayPrompt extends Prompt {
10
+ constructor(options) {
11
+ super(options);
12
+ this.cursorHide();
13
+ this.maxSelected = options.maxSelected || Infinity;
14
+ this.multiple = options.multiple || false;
15
+ this.initial = options.initial || 0;
16
+ this.delay = options.delay || 0;
17
+ this.longest = 0;
18
+ this.num = '';
19
+ }
20
+
21
+ async initialize() {
22
+ if (typeof this.options.initial === 'function') {
23
+ this.initial = await this.options.initial.call(this);
24
+ }
25
+ await this.reset(true);
26
+ await super.initialize();
27
+ }
28
+
29
+ async reset() {
30
+ let { choices, initial, autofocus, suggest } = this.options;
31
+ this.state._choices = [];
32
+ this.state.choices = [];
33
+
34
+ this.choices = await Promise.all(await this.toChoices(choices));
35
+ this.choices.forEach(ch => (ch.enabled = false));
36
+
37
+ if (typeof suggest !== 'function' && this.selectable.length === 0) {
38
+ throw new Error('At least one choice must be selectable');
39
+ }
40
+
41
+ if (isObject(initial)) initial = Object.keys(initial);
42
+ if (Array.isArray(initial)) {
43
+ if (autofocus != null) this.index = this.findIndex(autofocus);
44
+ initial.forEach(v => this.enable(this.find(v)));
45
+ await this.render();
46
+ } else {
47
+ if (autofocus != null) initial = autofocus;
48
+ if (typeof initial === 'string') initial = this.findIndex(initial);
49
+ if (typeof initial === 'number' && initial > -1) {
50
+ this.index = Math.max(0, Math.min(initial, this.choices.length));
51
+ this.enable(this.find(this.index));
52
+ }
53
+ }
54
+
55
+ if (this.isDisabled(this.focused)) {
56
+ await this.down();
57
+ }
58
+ }
59
+
60
+ async toChoices(value, parent) {
61
+ this.state.loadingChoices = true;
62
+ let choices = [];
63
+ let index = 0;
64
+
65
+ let toChoices = async(items, parent) => {
66
+ if (typeof items === 'function') items = await items.call(this);
67
+ if (items instanceof Promise) items = await items;
68
+
69
+ for (let i = 0; i < items.length; i++) {
70
+ let choice = items[i] = await this.toChoice(items[i], index++, parent);
71
+ choices.push(choice);
72
+
73
+ if (choice.choices) {
74
+ await toChoices(choice.choices, choice);
75
+ }
76
+ }
77
+ return choices;
78
+ };
79
+
80
+ return toChoices(value, parent)
81
+ .then(choices => {
82
+ this.state.loadingChoices = false;
83
+ return choices;
84
+ });
85
+ }
86
+
87
+ async toChoice(ele, i, parent) {
88
+ if (typeof ele === 'function') ele = await ele.call(this, this);
89
+ if (ele instanceof Promise) ele = await ele;
90
+ if (typeof ele === 'string') ele = { name: ele };
91
+
92
+ if (ele.normalized) return ele;
93
+ ele.normalized = true;
94
+
95
+ let origVal = ele.value;
96
+ let role = roles(ele.role, this.options);
97
+ ele = role(this, ele);
98
+
99
+ if (typeof ele.disabled === 'string' && !ele.hint) {
100
+ ele.hint = ele.disabled;
101
+ ele.disabled = true;
102
+ }
103
+
104
+ if (ele.disabled === true && ele.hint == null) {
105
+ ele.hint = '(disabled)';
106
+ }
107
+
108
+ // if the choice was already normalized, return it
109
+ if (ele.index != null) return ele;
110
+ ele.name = ele.name || ele.key || ele.title || ele.value || ele.message;
111
+ ele.message = ele.message || ele.name || '';
112
+ ele.value = [ele.value, ele.name].find(this.isValue.bind(this));
113
+
114
+ ele.input = '';
115
+ ele.index = i;
116
+ ele.cursor = 0;
117
+
118
+ utils.define(ele, 'parent', parent);
119
+ ele.level = parent ? parent.level + 1 : 1;
120
+ if (ele.indent == null) {
121
+ ele.indent = parent ? parent.indent + ' ' : (ele.indent || '');
122
+ }
123
+
124
+ ele.path = parent ? parent.path + '.' + ele.name : ele.name;
125
+ ele.enabled = !!(this.multiple && !this.isDisabled(ele) && (ele.enabled || this.isSelected(ele)));
126
+
127
+ if (!this.isDisabled(ele)) {
128
+ this.longest = Math.max(this.longest, colors.unstyle(ele.message).length);
129
+ }
130
+
131
+ // shallow clone the choice first
132
+ let choice = { ...ele };
133
+
134
+ // then allow the choice to be reset using the "original" values
135
+ ele.reset = (input = choice.input, value = choice.value) => {
136
+ for (let key of Object.keys(choice)) ele[key] = choice[key];
137
+ ele.input = input;
138
+ ele.value = value;
139
+ };
140
+
141
+ if (origVal == null && typeof ele.initial === 'function') {
142
+ ele.input = await ele.initial.call(this, this.state, ele, i);
143
+ }
144
+
145
+ return ele;
146
+ }
147
+
148
+ async onChoice(choice, i) {
149
+ this.emit('choice', choice, i, this);
150
+
151
+ if (typeof choice.onChoice === 'function') {
152
+ await choice.onChoice.call(this, this.state, choice, i);
153
+ }
154
+ }
155
+
156
+ async addChoice(ele, i, parent) {
157
+ let choice = await this.toChoice(ele, i, parent);
158
+ this.choices.push(choice);
159
+ this.index = this.choices.length - 1;
160
+ this.limit = this.choices.length;
161
+ return choice;
162
+ }
163
+
164
+ async newItem(item, i, parent) {
165
+ let ele = { name: 'New choice name?', editable: true, newChoice: true, ...item };
166
+ let choice = await this.addChoice(ele, i, parent);
167
+
168
+ choice.updateChoice = () => {
169
+ delete choice.newChoice;
170
+ choice.name = choice.message = choice.input;
171
+ choice.input = '';
172
+ choice.cursor = 0;
173
+ };
174
+
175
+ return this.render();
176
+ }
177
+
178
+ indent(choice) {
179
+ if (choice.indent == null) {
180
+ return choice.level > 1 ? ' '.repeat(choice.level - 1) : '';
181
+ }
182
+ return choice.indent;
183
+ }
184
+
185
+ dispatch(s, key) {
186
+ if (this.multiple && this[key.name]) return this[key.name]();
187
+ this.alert();
188
+ }
189
+
190
+ focus(choice, enabled) {
191
+ if (typeof enabled !== 'boolean') enabled = choice.enabled;
192
+ if (enabled && !choice.enabled && this.selected.length >= this.maxSelected) {
193
+ return this.alert();
194
+ }
195
+ this.index = choice.index;
196
+ choice.enabled = enabled && !this.isDisabled(choice);
197
+ return choice;
198
+ }
199
+
200
+ space() {
201
+ if (!this.multiple) return this.alert();
202
+ this.toggle(this.focused);
203
+ return this.render();
204
+ }
205
+
206
+ a() {
207
+ if (this.maxSelected < this.choices.length) return this.alert();
208
+ let enabled = this.selectable.every(ch => ch.enabled);
209
+ this.choices.forEach(ch => (ch.enabled = !enabled));
210
+ return this.render();
211
+ }
212
+
213
+ i() {
214
+ // don't allow choices to be inverted if it will result in
215
+ // more than the maximum number of allowed selected items.
216
+ if (this.choices.length - this.selected.length > this.maxSelected) {
217
+ return this.alert();
218
+ }
219
+ this.choices.forEach(ch => (ch.enabled = !ch.enabled));
220
+ return this.render();
221
+ }
222
+
223
+ g(choice = this.focused) {
224
+ if (!this.choices.some(ch => !!ch.parent)) return this.a();
225
+ this.toggle((choice.parent && !choice.choices) ? choice.parent : choice);
226
+ return this.render();
227
+ }
228
+
229
+ toggle(choice, enabled) {
230
+ if (!choice.enabled && this.selected.length >= this.maxSelected) {
231
+ return this.alert();
232
+ }
233
+
234
+ if (typeof enabled !== 'boolean') enabled = !choice.enabled;
235
+ choice.enabled = enabled;
236
+
237
+ if (choice.choices) {
238
+ choice.choices.forEach(ch => this.toggle(ch, enabled));
239
+ }
240
+
241
+ let parent = choice.parent;
242
+ while (parent) {
243
+ let choices = parent.choices.filter(ch => this.isDisabled(ch));
244
+ parent.enabled = choices.every(ch => ch.enabled === true);
245
+ parent = parent.parent;
246
+ }
247
+
248
+ reset(this, this.choices);
249
+ this.emit('toggle', choice, this);
250
+ return choice;
251
+ }
252
+
253
+ enable(choice) {
254
+ if (this.selected.length >= this.maxSelected) return this.alert();
255
+ choice.enabled = !this.isDisabled(choice);
256
+ choice.choices && choice.choices.forEach(this.enable.bind(this));
257
+ return choice;
258
+ }
259
+
260
+ disable(choice) {
261
+ choice.enabled = false;
262
+ choice.choices && choice.choices.forEach(this.disable.bind(this));
263
+ return choice;
264
+ }
265
+
266
+ number(n) {
267
+ this.num += n;
268
+
269
+ let number = num => {
270
+ let i = Number(num);
271
+ if (i > this.choices.length - 1) return this.alert();
272
+
273
+ let focused = this.focused;
274
+ let choice = this.choices.find(ch => i === ch.index);
275
+
276
+ if (!choice.enabled && this.selected.length >= this.maxSelected) {
277
+ return this.alert();
278
+ }
279
+
280
+ if (this.visible.indexOf(choice) === -1) {
281
+ let choices = reorder(this.choices);
282
+ let actualIdx = choices.indexOf(choice);
283
+
284
+ if (focused.index > actualIdx) {
285
+ let start = choices.slice(actualIdx, actualIdx + this.limit);
286
+ let end = choices.filter(ch => !start.includes(ch));
287
+ this.choices = start.concat(end);
288
+ } else {
289
+ let pos = actualIdx - this.limit + 1;
290
+ this.choices = choices.slice(pos).concat(choices.slice(0, pos));
291
+ }
292
+ }
293
+
294
+ this.index = this.choices.indexOf(choice);
295
+ this.toggle(this.focused);
296
+ return this.render();
297
+ };
298
+
299
+ clearTimeout(this.numberTimeout);
300
+
301
+ return new Promise(resolve => {
302
+ let len = this.choices.length;
303
+ let num = this.num;
304
+
305
+ let handle = (val = false, res) => {
306
+ clearTimeout(this.numberTimeout);
307
+ if (val) res = number(num);
308
+ this.num = '';
309
+ resolve(res);
310
+ };
311
+
312
+ if (num === '0' || (num.length === 1 && Number(num + '0') > len)) {
313
+ return handle(true);
314
+ }
315
+
316
+ if (Number(num) > len) {
317
+ return handle(false, this.alert());
318
+ }
319
+
320
+ this.numberTimeout = setTimeout(() => handle(true), this.delay);
321
+ });
322
+ }
323
+
324
+ home() {
325
+ this.choices = reorder(this.choices);
326
+ this.index = 0;
327
+ return this.render();
328
+ }
329
+
330
+ end() {
331
+ let pos = this.choices.length - this.limit;
332
+ let choices = reorder(this.choices);
333
+ this.choices = choices.slice(pos).concat(choices.slice(0, pos));
334
+ this.index = this.limit - 1;
335
+ return this.render();
336
+ }
337
+
338
+ first() {
339
+ this.index = 0;
340
+ return this.render();
341
+ }
342
+
343
+ last() {
344
+ this.index = this.visible.length - 1;
345
+ return this.render();
346
+ }
347
+
348
+ prev() {
349
+ if (this.visible.length <= 1) return this.alert();
350
+ return this.up();
351
+ }
352
+
353
+ next() {
354
+ if (this.visible.length <= 1) return this.alert();
355
+ return this.down();
356
+ }
357
+
358
+ right() {
359
+ if (this.cursor >= this.input.length) return this.alert();
360
+ this.cursor++;
361
+ return this.render();
362
+ }
363
+
364
+ left() {
365
+ if (this.cursor <= 0) return this.alert();
366
+ this.cursor--;
367
+ return this.render();
368
+ }
369
+
370
+ up() {
371
+ let len = this.choices.length;
372
+ let vis = this.visible.length;
373
+ let idx = this.index;
374
+ if (this.options.scroll === false && idx === 0) {
375
+ return this.alert();
376
+ }
377
+ if (len > vis && idx === 0) {
378
+ return this.scrollUp();
379
+ }
380
+ this.index = ((idx - 1 % len) + len) % len;
381
+ if (this.isDisabled()) {
382
+ return this.up();
383
+ }
384
+ return this.render();
385
+ }
386
+
387
+ down() {
388
+ let len = this.choices.length;
389
+ let vis = this.visible.length;
390
+ let idx = this.index;
391
+ if (this.options.scroll === false && idx === vis - 1) {
392
+ return this.alert();
393
+ }
394
+ if (len > vis && idx === vis - 1) {
395
+ return this.scrollDown();
396
+ }
397
+ this.index = (idx + 1) % len;
398
+ if (this.isDisabled()) {
399
+ return this.down();
400
+ }
401
+ return this.render();
402
+ }
403
+
404
+ scrollUp(i = 0) {
405
+ this.choices = scrollUp(this.choices);
406
+ this.index = i;
407
+ if (this.isDisabled()) {
408
+ return this.up();
409
+ }
410
+ return this.render();
411
+ }
412
+
413
+ scrollDown(i = this.visible.length - 1) {
414
+ this.choices = scrollDown(this.choices);
415
+ this.index = i;
416
+ if (this.isDisabled()) {
417
+ return this.down();
418
+ }
419
+ return this.render();
420
+ }
421
+
422
+ async shiftUp() {
423
+ if (this.options.sort === true) {
424
+ this.sorting = true;
425
+ this.swap(this.index - 1);
426
+ await this.up();
427
+ this.sorting = false;
428
+ return;
429
+ }
430
+ return this.scrollUp(this.index);
431
+ }
432
+
433
+ async shiftDown() {
434
+ if (this.options.sort === true) {
435
+ this.sorting = true;
436
+ this.swap(this.index + 1);
437
+ await this.down();
438
+ this.sorting = false;
439
+ return;
440
+ }
441
+ return this.scrollDown(this.index);
442
+ }
443
+
444
+ pageUp() {
445
+ if (this.visible.length <= 1) return this.alert();
446
+ this.limit = Math.max(this.limit - 1, 0);
447
+ this.index = Math.min(this.limit - 1, this.index);
448
+ this._limit = this.limit;
449
+ if (this.isDisabled()) {
450
+ return this.up();
451
+ }
452
+ return this.render();
453
+ }
454
+
455
+ pageDown() {
456
+ if (this.visible.length >= this.choices.length) return this.alert();
457
+ this.index = Math.max(0, this.index);
458
+ this.limit = Math.min(this.limit + 1, this.choices.length);
459
+ this._limit = this.limit;
460
+ if (this.isDisabled()) {
461
+ return this.down();
462
+ }
463
+ return this.render();
464
+ }
465
+
466
+ swap(pos) {
467
+ swap(this.choices, this.index, pos);
468
+ }
469
+
470
+ isDisabled(choice = this.focused) {
471
+ let keys = ['disabled', 'collapsed', 'hidden', 'completing', 'readonly'];
472
+ if (choice && keys.some(key => choice[key] === true)) {
473
+ return true;
474
+ }
475
+ return choice && choice.role === 'heading';
476
+ }
477
+
478
+ isEnabled(choice = this.focused) {
479
+ if (Array.isArray(choice)) return choice.every(ch => this.isEnabled(ch));
480
+ if (choice.choices) {
481
+ let choices = choice.choices.filter(ch => !this.isDisabled(ch));
482
+ return choice.enabled && choices.every(ch => this.isEnabled(ch));
483
+ }
484
+ return choice.enabled && !this.isDisabled(choice);
485
+ }
486
+
487
+ isChoice(choice, value) {
488
+ return choice.name === value || choice.index === Number(value);
489
+ }
490
+
491
+ isSelected(choice) {
492
+ if (Array.isArray(this.initial)) {
493
+ return this.initial.some(value => this.isChoice(choice, value));
494
+ }
495
+ return this.isChoice(choice, this.initial);
496
+ }
497
+
498
+ map(names = [], prop = 'value') {
499
+ return [].concat(names || []).reduce((acc, name) => {
500
+ acc[name] = this.find(name, prop);
501
+ return acc;
502
+ }, {});
503
+ }
504
+
505
+ filter(value, prop) {
506
+ let isChoice = (ele, i) => [ele.name, i].includes(value);
507
+ let fn = typeof value === 'function' ? value : isChoice;
508
+ let choices = this.options.multiple ? this.state._choices : this.choices;
509
+ let result = choices.filter(fn);
510
+ if (prop) {
511
+ return result.map(ch => ch[prop]);
512
+ }
513
+ return result;
514
+ }
515
+
516
+ find(value, prop) {
517
+ if (isObject(value)) return prop ? value[prop] : value;
518
+ let isChoice = (ele, i) => [ele.name, i].includes(value);
519
+ let fn = typeof value === 'function' ? value : isChoice;
520
+ let choice = this.choices.find(fn);
521
+ if (choice) {
522
+ return prop ? choice[prop] : choice;
523
+ }
524
+ }
525
+
526
+ findIndex(value) {
527
+ return this.choices.indexOf(this.find(value));
528
+ }
529
+
530
+ async submit() {
531
+ let choice = this.focused;
532
+ if (!choice) return this.alert();
533
+
534
+ if (choice.newChoice) {
535
+ if (!choice.input) return this.alert();
536
+ choice.updateChoice();
537
+ return this.render();
538
+ }
539
+
540
+ if (this.choices.some(ch => ch.newChoice)) {
541
+ return this.alert();
542
+ }
543
+
544
+ let { reorder, sort } = this.options;
545
+ let multi = this.multiple === true;
546
+ let value = this.selected;
547
+ if (value === void 0) {
548
+ return this.alert();
549
+ }
550
+
551
+ // re-sort choices to original order
552
+ if (Array.isArray(value) && reorder !== false && sort !== true) {
553
+ value = utils.reorder(value);
554
+ }
555
+
556
+ this.value = multi ? value.map(ch => ch.name) : value.name;
557
+ return super.submit();
558
+ }
559
+
560
+ set choices(choices = []) {
561
+ this.state._choices = this.state._choices || [];
562
+ this.state.choices = choices;
563
+
564
+ for (let choice of choices) {
565
+ if (!this.state._choices.some(ch => ch.name === choice.name)) {
566
+ this.state._choices.push(choice);
567
+ }
568
+ }
569
+
570
+ if (!this._initial && this.options.initial) {
571
+ this._initial = true;
572
+ let init = this.initial;
573
+ if (typeof init === 'string' || typeof init === 'number') {
574
+ let choice = this.find(init);
575
+ if (choice) {
576
+ this.initial = choice.index;
577
+ this.focus(choice, true);
578
+ }
579
+ }
580
+ }
581
+ }
582
+ get choices() {
583
+ return reset(this, this.state.choices || []);
584
+ }
585
+
586
+ set visible(visible) {
587
+ this.state.visible = visible;
588
+ }
589
+ get visible() {
590
+ return (this.state.visible || this.choices).slice(0, this.limit);
591
+ }
592
+
593
+ set limit(num) {
594
+ this.state.limit = num;
595
+ }
596
+ get limit() {
597
+ let { state, options, choices } = this;
598
+ let limit = state.limit || this._limit || options.limit || choices.length;
599
+ return Math.min(limit, this.height);
600
+ }
601
+
602
+ set value(value) {
603
+ super.value = value;
604
+ }
605
+ get value() {
606
+ if (typeof super.value !== 'string' && super.value === this.initial) {
607
+ return this.input;
608
+ }
609
+ return super.value;
610
+ }
611
+
612
+ set index(i) {
613
+ this.state.index = i;
614
+ }
615
+ get index() {
616
+ return Math.max(0, this.state ? this.state.index : 0);
617
+ }
618
+
619
+ get enabled() {
620
+ return this.filter(this.isEnabled.bind(this));
621
+ }
622
+
623
+ get focused() {
624
+ let choice = this.choices[this.index];
625
+ if (choice && this.state.submitted && this.multiple !== true) {
626
+ choice.enabled = true;
627
+ }
628
+ return choice;
629
+ }
630
+
631
+ get selectable() {
632
+ return this.choices.filter(choice => !this.isDisabled(choice));
633
+ }
634
+
635
+ get selected() {
636
+ return this.multiple ? this.enabled : this.focused;
637
+ }
638
+ }
639
+
640
+ function reset(prompt, choices) {
641
+ if (choices instanceof Promise) return choices;
642
+ if (typeof choices === 'function') {
643
+ if (utils.isAsyncFn(choices)) return choices;
644
+ choices = choices.call(prompt, prompt);
645
+ }
646
+ for (let choice of choices) {
647
+ if (Array.isArray(choice.choices)) {
648
+ let items = choice.choices.filter(ch => !prompt.isDisabled(ch));
649
+ choice.enabled = items.every(ch => ch.enabled === true);
650
+ }
651
+ if (prompt.isDisabled(choice) === true) {
652
+ delete choice.enabled;
653
+ }
654
+ }
655
+ return choices;
656
+ }
657
+
658
+ module.exports = ArrayPrompt;
@@ -0,0 +1,29 @@
1
+ 'use strict';
2
+
3
+ const FormPrompt = require('../prompts/form');
4
+
5
+ const defaultAuthenticate = () => {
6
+ throw new Error('expected prompt to have a custom authenticate method');
7
+ };
8
+
9
+ const factory = (authenticate = defaultAuthenticate) => {
10
+
11
+ class AuthPrompt extends FormPrompt {
12
+ constructor(options) {
13
+ super(options);
14
+ }
15
+
16
+ async submit() {
17
+ this.value = await authenticate.call(this, this.values, this.state);
18
+ super.base.submit.call(this);
19
+ }
20
+
21
+ static create(authenticate) {
22
+ return factory(authenticate);
23
+ }
24
+ }
25
+
26
+ return AuthPrompt;
27
+ };
28
+
29
+ module.exports = factory();