1 | 'use strict';
|
2 |
|
3 | var fs = require('fs');
|
4 | var path = require('path');
|
5 | var index = require('./index-688c5d50.js');
|
6 | var os = require('os');
|
7 | var assert = require('assert');
|
8 | var Events = require('events');
|
9 | var readline = require('readline');
|
10 | require('stream');
|
11 | require('string_decoder');
|
12 | require('buffer');
|
13 | require('zlib');
|
14 | require('util');
|
15 | require('crypto');
|
16 | require('tty');
|
17 | require('constants');
|
18 | require('https');
|
19 | require('child_process');
|
20 | require('url');
|
21 | require('net');
|
22 | require('tls');
|
23 |
|
24 | function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
25 |
|
26 | var fs__default = _interopDefaultLegacy(fs);
|
27 | var path__default = _interopDefaultLegacy(path);
|
28 | var os__default = _interopDefaultLegacy(os);
|
29 | var assert__default = _interopDefaultLegacy(assert);
|
30 | var Events__default = _interopDefaultLegacy(Events);
|
31 | var readline__default = _interopDefaultLegacy(readline);
|
32 |
|
33 | function toArr(any) {
|
34 | return any == null ? [] : Array.isArray(any) ? any : [any];
|
35 | }
|
36 |
|
37 | function toVal(out, key, val, opts) {
|
38 | var x, old=out[key], nxt=(
|
39 | !!~opts.string.indexOf(key) ? (val == null || val === true ? '' : String(val))
|
40 | : typeof val === 'boolean' ? val
|
41 | : !!~opts.boolean.indexOf(key) ? (val === 'false' ? false : val === 'true' || (out._.push((x = +val,x * 0 === 0) ? x : val),!!val))
|
42 | : (x = +val,x * 0 === 0) ? x : val
|
43 | );
|
44 | out[key] = old == null ? nxt : (Array.isArray(old) ? old.concat(nxt) : [old, nxt]);
|
45 | }
|
46 |
|
47 | function mri (args, opts) {
|
48 | args = args || [];
|
49 | opts = opts || {};
|
50 |
|
51 | var k, arr, arg, name, val, out={ _:[] };
|
52 | var i=0, j=0, idx=0, len=args.length;
|
53 |
|
54 | const alibi = opts.alias !== void 0;
|
55 | const strict = opts.unknown !== void 0;
|
56 | const defaults = opts.default !== void 0;
|
57 |
|
58 | opts.alias = opts.alias || {};
|
59 | opts.string = toArr(opts.string);
|
60 | opts.boolean = toArr(opts.boolean);
|
61 |
|
62 | if (alibi) {
|
63 | for (k in opts.alias) {
|
64 | arr = opts.alias[k] = toArr(opts.alias[k]);
|
65 | for (i=0; i < arr.length; i++) {
|
66 | (opts.alias[arr[i]] = arr.concat(k)).splice(i, 1);
|
67 | }
|
68 | }
|
69 | }
|
70 |
|
71 | for (i=opts.boolean.length; i-- > 0;) {
|
72 | arr = opts.alias[opts.boolean[i]] || [];
|
73 | for (j=arr.length; j-- > 0;) opts.boolean.push(arr[j]);
|
74 | }
|
75 |
|
76 | for (i=opts.string.length; i-- > 0;) {
|
77 | arr = opts.alias[opts.string[i]] || [];
|
78 | for (j=arr.length; j-- > 0;) opts.string.push(arr[j]);
|
79 | }
|
80 |
|
81 | if (defaults) {
|
82 | for (k in opts.default) {
|
83 | name = typeof opts.default[k];
|
84 | arr = opts.alias[k] = opts.alias[k] || [];
|
85 | if (opts[name] !== void 0) {
|
86 | opts[name].push(k);
|
87 | for (i=0; i < arr.length; i++) {
|
88 | opts[name].push(arr[i]);
|
89 | }
|
90 | }
|
91 | }
|
92 | }
|
93 |
|
94 | const keys = strict ? Object.keys(opts.alias) : [];
|
95 |
|
96 | for (i=0; i < len; i++) {
|
97 | arg = args[i];
|
98 |
|
99 | if (arg === '--') {
|
100 | out._ = out._.concat(args.slice(++i));
|
101 | break;
|
102 | }
|
103 |
|
104 | for (j=0; j < arg.length; j++) {
|
105 | if (arg.charCodeAt(j) !== 45) break;
|
106 | }
|
107 |
|
108 | if (j === 0) {
|
109 | out._.push(arg);
|
110 | } else if (arg.substring(j, j + 3) === 'no-') {
|
111 | name = arg.substring(j + 3);
|
112 | if (strict && !~keys.indexOf(name)) {
|
113 | return opts.unknown(arg);
|
114 | }
|
115 | out[name] = false;
|
116 | } else {
|
117 | for (idx=j+1; idx < arg.length; idx++) {
|
118 | if (arg.charCodeAt(idx) === 61) break;
|
119 | }
|
120 |
|
121 | name = arg.substring(j, idx);
|
122 | val = arg.substring(++idx) || (i+1 === len || (''+args[i+1]).charCodeAt(0) === 45 || args[++i]);
|
123 | arr = (j === 2 ? [name] : name);
|
124 |
|
125 | for (idx=0; idx < arr.length; idx++) {
|
126 | name = arr[idx];
|
127 | if (strict && !~keys.indexOf(name)) return opts.unknown('-'.repeat(j) + name);
|
128 | toVal(out, name, (idx + 1 < arr.length) || val, opts);
|
129 | }
|
130 | }
|
131 | }
|
132 |
|
133 | if (defaults) {
|
134 | for (k in opts.default) {
|
135 | if (out[k] === void 0) {
|
136 | out[k] = opts.default[k];
|
137 | }
|
138 | }
|
139 | }
|
140 |
|
141 | if (alibi) {
|
142 | for (k in out) {
|
143 | arr = opts.alias[k] || [];
|
144 | while (arr.length > 0) {
|
145 | out[arr.shift()] = out[k];
|
146 | }
|
147 | }
|
148 | }
|
149 |
|
150 | return out;
|
151 | }
|
152 |
|
153 | const isWin$1 = process.platform === 'win32';
|
154 | const SEP = isWin$1 ? `\\\\+` : `\\/`;
|
155 | const SEP_ESC = isWin$1 ? `\\\\` : `/`;
|
156 | const GLOBSTAR = `((?:[^/]*(?:/|$))*)`;
|
157 | const WILDCARD = `([^/]*)`;
|
158 | const GLOBSTAR_SEGMENT = `((?:[^${SEP_ESC}]*(?:${SEP_ESC}|$))*)`;
|
159 | const WILDCARD_SEGMENT = `([^${SEP_ESC}]*)`;
|
160 |
|
161 |
|
162 |
|
163 |
|
164 |
|
165 |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 |
|
171 |
|
172 | function globrex(glob, {extended = false, globstar = false, strict = false, filepath = false, flags = ''} = {}) {
|
173 | let regex = '';
|
174 | let segment = '';
|
175 | let path = { regex: '', segments: [] };
|
176 |
|
177 |
|
178 |
|
179 | let inGroup = false;
|
180 | let inRange = false;
|
181 |
|
182 |
|
183 | const ext = [];
|
184 |
|
185 |
|
186 | function add(str, {split, last, only}={}) {
|
187 | if (only !== 'path') regex += str;
|
188 | if (filepath && only !== 'regex') {
|
189 | path.regex += (str === '\\/' ? SEP : str);
|
190 | if (split) {
|
191 | if (last) segment += str;
|
192 | if (segment !== '') {
|
193 | if (!flags.includes('g')) segment = `^${segment}$`;
|
194 | path.segments.push(new RegExp(segment, flags));
|
195 | }
|
196 | segment = '';
|
197 | } else {
|
198 | segment += str;
|
199 | }
|
200 | }
|
201 | }
|
202 |
|
203 | let c, n;
|
204 | for (let i = 0; i < glob.length; i++) {
|
205 | c = glob[i];
|
206 | n = glob[i + 1];
|
207 |
|
208 | if (['\\', '$', '^', '.', '='].includes(c)) {
|
209 | add(`\\${c}`);
|
210 | continue;
|
211 | }
|
212 |
|
213 | if (c === '/') {
|
214 | add(`\\${c}`, {split: true});
|
215 | if (n === '/' && !strict) regex += '?';
|
216 | continue;
|
217 | }
|
218 |
|
219 | if (c === '(') {
|
220 | if (ext.length) {
|
221 | add(c);
|
222 | continue;
|
223 | }
|
224 | add(`\\${c}`);
|
225 | continue;
|
226 | }
|
227 |
|
228 | if (c === ')') {
|
229 | if (ext.length) {
|
230 | add(c);
|
231 | let type = ext.pop();
|
232 | if (type === '@') {
|
233 | add('{1}');
|
234 | } else if (type === '!') {
|
235 | add('([^\/]*)');
|
236 | } else {
|
237 | add(type);
|
238 | }
|
239 | continue;
|
240 | }
|
241 | add(`\\${c}`);
|
242 | continue;
|
243 | }
|
244 |
|
245 | if (c === '|') {
|
246 | if (ext.length) {
|
247 | add(c);
|
248 | continue;
|
249 | }
|
250 | add(`\\${c}`);
|
251 | continue;
|
252 | }
|
253 |
|
254 | if (c === '+') {
|
255 | if (n === '(' && extended) {
|
256 | ext.push(c);
|
257 | continue;
|
258 | }
|
259 | add(`\\${c}`);
|
260 | continue;
|
261 | }
|
262 |
|
263 | if (c === '@' && extended) {
|
264 | if (n === '(') {
|
265 | ext.push(c);
|
266 | continue;
|
267 | }
|
268 | }
|
269 |
|
270 | if (c === '!') {
|
271 | if (extended) {
|
272 | if (inRange) {
|
273 | add('^');
|
274 | continue
|
275 | }
|
276 | if (n === '(') {
|
277 | ext.push(c);
|
278 | add('(?!');
|
279 | i++;
|
280 | continue;
|
281 | }
|
282 | add(`\\${c}`);
|
283 | continue;
|
284 | }
|
285 | add(`\\${c}`);
|
286 | continue;
|
287 | }
|
288 |
|
289 | if (c === '?') {
|
290 | if (extended) {
|
291 | if (n === '(') {
|
292 | ext.push(c);
|
293 | } else {
|
294 | add('.');
|
295 | }
|
296 | continue;
|
297 | }
|
298 | add(`\\${c}`);
|
299 | continue;
|
300 | }
|
301 |
|
302 | if (c === '[') {
|
303 | if (inRange && n === ':') {
|
304 | i++;
|
305 | let value = '';
|
306 | while(glob[++i] !== ':') value += glob[i];
|
307 | if (value === 'alnum') add('(\\w|\\d)');
|
308 | else if (value === 'space') add('\\s');
|
309 | else if (value === 'digit') add('\\d');
|
310 | i++;
|
311 | continue;
|
312 | }
|
313 | if (extended) {
|
314 | inRange = true;
|
315 | add(c);
|
316 | continue;
|
317 | }
|
318 | add(`\\${c}`);
|
319 | continue;
|
320 | }
|
321 |
|
322 | if (c === ']') {
|
323 | if (extended) {
|
324 | inRange = false;
|
325 | add(c);
|
326 | continue;
|
327 | }
|
328 | add(`\\${c}`);
|
329 | continue;
|
330 | }
|
331 |
|
332 | if (c === '{') {
|
333 | if (extended) {
|
334 | inGroup = true;
|
335 | add('(');
|
336 | continue;
|
337 | }
|
338 | add(`\\${c}`);
|
339 | continue;
|
340 | }
|
341 |
|
342 | if (c === '}') {
|
343 | if (extended) {
|
344 | inGroup = false;
|
345 | add(')');
|
346 | continue;
|
347 | }
|
348 | add(`\\${c}`);
|
349 | continue;
|
350 | }
|
351 |
|
352 | if (c === ',') {
|
353 | if (inGroup) {
|
354 | add('|');
|
355 | continue;
|
356 | }
|
357 | add(`\\${c}`);
|
358 | continue;
|
359 | }
|
360 |
|
361 | if (c === '*') {
|
362 | if (n === '(' && extended) {
|
363 | ext.push(c);
|
364 | continue;
|
365 | }
|
366 |
|
367 |
|
368 | let prevChar = glob[i - 1];
|
369 | let starCount = 1;
|
370 | while (glob[i + 1] === '*') {
|
371 | starCount++;
|
372 | i++;
|
373 | }
|
374 | let nextChar = glob[i + 1];
|
375 | if (!globstar) {
|
376 |
|
377 | add('.*');
|
378 | } else {
|
379 |
|
380 | let isGlobstar =
|
381 | starCount > 1 &&
|
382 | (prevChar === '/' || prevChar === undefined) &&
|
383 | (nextChar === '/' || nextChar === undefined);
|
384 | if (isGlobstar) {
|
385 |
|
386 | add(GLOBSTAR, {only:'regex'});
|
387 | add(GLOBSTAR_SEGMENT, {only:'path', last:true, split:true});
|
388 | i++;
|
389 | } else {
|
390 |
|
391 | add(WILDCARD, {only:'regex'});
|
392 | add(WILDCARD_SEGMENT, {only:'path'});
|
393 | }
|
394 | }
|
395 | continue;
|
396 | }
|
397 |
|
398 | add(c);
|
399 | }
|
400 |
|
401 |
|
402 |
|
403 |
|
404 | if (!flags.includes('g')) {
|
405 | regex = `^${regex}$`;
|
406 | segment = `^${segment}$`;
|
407 | if (filepath) path.regex = `^${path.regex}$`;
|
408 | }
|
409 |
|
410 | const result = {regex: new RegExp(regex, flags)};
|
411 |
|
412 |
|
413 | if (filepath) {
|
414 | path.segments.push(new RegExp(segment, flags));
|
415 | path.regex = new RegExp(path.regex, flags);
|
416 | path.globstar = new RegExp(!flags.includes('g') ? `^${GLOBSTAR_SEGMENT}$` : GLOBSTAR_SEGMENT, flags);
|
417 | result.path = path;
|
418 | }
|
419 |
|
420 | return result;
|
421 | }
|
422 |
|
423 | var globrex_1 = globrex;
|
424 |
|
425 | const isWin = os__default['default'].platform() === 'win32';
|
426 |
|
427 | const CHARS = { '{': '}', '(': ')', '[': ']'};
|
428 | const STRICT = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\)|(\\).|([@?!+*]\(.*\)))/;
|
429 | const RELAXED = /\\(.)|(^!|[*?{}()[\]]|\(\?)/;
|
430 |
|
431 |
|
432 |
|
433 |
|
434 |
|
435 |
|
436 |
|
437 |
|
438 | function isglob(str, { strict = true } = {}) {
|
439 | if (str === '') return false;
|
440 | let match, rgx = strict ? STRICT : RELAXED;
|
441 |
|
442 | while ((match = rgx.exec(str))) {
|
443 | if (match[2]) return true;
|
444 | let idx = match.index + match[0].length;
|
445 |
|
446 |
|
447 |
|
448 | let open = match[1];
|
449 | let close = open ? CHARS[open] : null;
|
450 | if (open && close) {
|
451 | let n = str.indexOf(close, idx);
|
452 | if (n !== -1) idx = n + 1;
|
453 | }
|
454 |
|
455 | str = str.slice(idx);
|
456 | }
|
457 | return false;
|
458 | }
|
459 |
|
460 |
|
461 |
|
462 |
|
463 |
|
464 |
|
465 |
|
466 |
|
467 | function parent(str, { strict = false } = {}) {
|
468 | if (isWin && str.includes('/'))
|
469 | str = str.split('\\').join('/');
|
470 |
|
471 |
|
472 | if (/[\{\[].*[\/]*.*[\}\]]$/.test(str)) str += '/';
|
473 |
|
474 |
|
475 | str += 'a';
|
476 |
|
477 | do {str = path__default['default'].dirname(str);}
|
478 | while (isglob(str, {strict}) || /(^|[^\\])([\{\[]|\([^\)]+$)/.test(str));
|
479 |
|
480 |
|
481 | return str.replace(/\\([\*\?\|\[\]\(\)\{\}])/g, '$1');
|
482 | }
|
483 |
|
484 |
|
485 |
|
486 |
|
487 |
|
488 |
|
489 |
|
490 |
|
491 | function globalyzer(pattern, opts = {}) {
|
492 | let base = parent(pattern, opts);
|
493 | let isGlob = isglob(pattern, opts);
|
494 | let glob;
|
495 |
|
496 | if (base != '.') {
|
497 | glob = pattern.substr(base.length);
|
498 | if (glob.startsWith('/')) glob = glob.substr(1);
|
499 | } else {
|
500 | glob = pattern;
|
501 | }
|
502 |
|
503 | if (!isGlob) {
|
504 | base = path__default['default'].dirname(pattern);
|
505 | glob = base !== '.' ? pattern.substr(base.length) : pattern;
|
506 | }
|
507 |
|
508 | if (glob.startsWith('./')) glob = glob.substr(2);
|
509 | if (glob.startsWith('/')) glob = glob.substr(1);
|
510 |
|
511 | return { base, glob, isGlob };
|
512 | }
|
513 |
|
514 |
|
515 | var src$1 = globalyzer;
|
516 |
|
517 | const { join, resolve, relative } = path__default['default'];
|
518 | const isHidden = /(^|[\\\/])\.[^\\\/\.]/g;
|
519 |
|
520 | let CACHE = {};
|
521 |
|
522 | function walk(output, prefix, lexer, opts, dirname='', level=0) {
|
523 | const rgx = lexer.segments[level];
|
524 | const dir = resolve(opts.cwd, prefix, dirname);
|
525 | const files = fs__default['default'].readdirSync(dir);
|
526 | const { dot, filesOnly } = opts;
|
527 |
|
528 | let i=0, len=files.length, file;
|
529 | let fullpath, relpath, stats, isMatch;
|
530 |
|
531 | for (; i < len; i++) {
|
532 | fullpath = join(dir, file=files[i]);
|
533 | relpath = dirname ? join(dirname, file) : file;
|
534 | if (!dot && isHidden.test(relpath)) continue;
|
535 | isMatch = lexer.regex.test(relpath);
|
536 |
|
537 | if ((stats=CACHE[relpath]) === void 0) {
|
538 | CACHE[relpath] = stats = fs__default['default'].lstatSync(fullpath);
|
539 | }
|
540 |
|
541 | if (!stats.isDirectory()) {
|
542 | isMatch && output.push(relative(opts.cwd, fullpath));
|
543 | continue;
|
544 | }
|
545 |
|
546 | if (rgx && !rgx.test(file)) continue;
|
547 | !filesOnly && isMatch && output.push(join(prefix, relpath));
|
548 |
|
549 | walk(output, prefix, lexer, opts, relpath, rgx && rgx.toString() !== lexer.globstar && level + 1);
|
550 | }
|
551 | }
|
552 |
|
553 |
|
554 |
|
555 |
|
556 |
|
557 |
|
558 |
|
559 |
|
560 |
|
561 |
|
562 |
|
563 |
|
564 | var sync = function (str, opts={}) {
|
565 | if (!str) return [];
|
566 |
|
567 | let glob = src$1(str);
|
568 |
|
569 | opts.cwd = opts.cwd || '.';
|
570 |
|
571 | if (!glob.isGlob) {
|
572 | try {
|
573 | let resolved = resolve(opts.cwd, str);
|
574 | let dirent = fs__default['default'].statSync(resolved);
|
575 | if (opts.filesOnly && !dirent.isFile()) return [];
|
576 |
|
577 | return opts.absolute ? [resolved] : [str];
|
578 | } catch (err) {
|
579 | if (err.code != 'ENOENT') throw err;
|
580 |
|
581 | return [];
|
582 | }
|
583 | }
|
584 |
|
585 | if (opts.flush) CACHE = {};
|
586 |
|
587 | let matches = [];
|
588 | const { path } = globrex_1(glob.glob, { filepath:true, globstar:true, extended:true });
|
589 |
|
590 | path.globstar = path.globstar.toString();
|
591 | walk(matches, glob.base, path, opts, '.', 0);
|
592 |
|
593 | return opts.absolute ? matches.map(x => resolve(opts.cwd, x)) : matches;
|
594 | };
|
595 |
|
596 | function fuzzysearch (needle, haystack) {
|
597 | var tlen = haystack.length;
|
598 | var qlen = needle.length;
|
599 | if (qlen > tlen) {
|
600 | return false;
|
601 | }
|
602 | if (qlen === tlen) {
|
603 | return needle === haystack;
|
604 | }
|
605 | outer: for (var i = 0, j = 0; i < qlen; i++) {
|
606 | var nch = needle.charCodeAt(i);
|
607 | while (j < tlen) {
|
608 | if (haystack.charCodeAt(j++) === nch) {
|
609 | continue outer;
|
610 | }
|
611 | }
|
612 | return false;
|
613 | }
|
614 | return true;
|
615 | }
|
616 |
|
617 | var fuzzysearch_1 = fuzzysearch;
|
618 |
|
619 | var symbols$1 = index.createCommonjsModule(function (module) {
|
620 |
|
621 | const isHyper = process.env.TERM_PROGRAM === 'Hyper';
|
622 | const isWindows = process.platform === 'win32';
|
623 | const isLinux = process.platform === 'linux';
|
624 |
|
625 | const common = {
|
626 | ballotDisabled: '☒',
|
627 | ballotOff: '☐',
|
628 | ballotOn: '☑',
|
629 | bullet: '•',
|
630 | bulletWhite: '◦',
|
631 | fullBlock: '█',
|
632 | heart: '❤',
|
633 | identicalTo: '≡',
|
634 | line: '─',
|
635 | mark: '※',
|
636 | middot: '·',
|
637 | minus: '-',
|
638 | multiplication: '×',
|
639 | obelus: '÷',
|
640 | pencilDownRight: '✎',
|
641 | pencilRight: '✏',
|
642 | pencilUpRight: '✐',
|
643 | percent: '%',
|
644 | pilcrow2: '❡',
|
645 | pilcrow: '¶',
|
646 | plusMinus: '±',
|
647 | section: '§',
|
648 | starsOff: '☆',
|
649 | starsOn: '★',
|
650 | upDownArrow: '↕'
|
651 | };
|
652 |
|
653 | const windows = Object.assign({}, common, {
|
654 | check: '√',
|
655 | cross: '×',
|
656 | ellipsisLarge: '...',
|
657 | ellipsis: '...',
|
658 | info: 'i',
|
659 | question: '?',
|
660 | questionSmall: '?',
|
661 | pointer: '>',
|
662 | pointerSmall: '»',
|
663 | radioOff: '( )',
|
664 | radioOn: '(*)',
|
665 | warning: '‼'
|
666 | });
|
667 |
|
668 | const other = Object.assign({}, common, {
|
669 | ballotCross: '✘',
|
670 | check: '✔',
|
671 | cross: '✖',
|
672 | ellipsisLarge: '⋯',
|
673 | ellipsis: '…',
|
674 | info: 'ℹ',
|
675 | question: '?',
|
676 | questionFull: '?',
|
677 | questionSmall: '﹖',
|
678 | pointer: isLinux ? '▸' : '❯',
|
679 | pointerSmall: isLinux ? '‣' : '›',
|
680 | radioOff: '◯',
|
681 | radioOn: '◉',
|
682 | warning: '⚠'
|
683 | });
|
684 |
|
685 | module.exports = (isWindows && !isHyper) ? windows : other;
|
686 | Reflect.defineProperty(module.exports, 'common', { enumerable: false, value: common });
|
687 | Reflect.defineProperty(module.exports, 'windows', { enumerable: false, value: windows });
|
688 | Reflect.defineProperty(module.exports, 'other', { enumerable: false, value: other });
|
689 | });
|
690 |
|
691 | const isObject$1 = val => val !== null && typeof val === 'object' && !Array.isArray(val);
|
692 |
|
693 |
|
694 |
|
695 | const ANSI_REGEX = /[\u001b\u009b][[\]#;?()]*(?:(?:(?:[^\W_]*;?[^\W_]*)\u0007)|(?:(?:[0-9]{1,4}(;[0-9]{0,4})*)?[~0-9=<>cf-nqrtyA-PRZ]))/g;
|
696 |
|
697 | const create$1 = () => {
|
698 | const colors = { enabled: true, visible: true, styles: {}, keys: {} };
|
699 |
|
700 | if ('FORCE_COLOR' in process.env) {
|
701 | colors.enabled = process.env.FORCE_COLOR !== '0';
|
702 | }
|
703 |
|
704 | const ansi = style => {
|
705 | let open = style.open = `\u001b[${style.codes[0]}m`;
|
706 | let close = style.close = `\u001b[${style.codes[1]}m`;
|
707 | let regex = style.regex = new RegExp(`\\u001b\\[${style.codes[1]}m`, 'g');
|
708 | style.wrap = (input, newline) => {
|
709 | if (input.includes(close)) input = input.replace(regex, close + open);
|
710 | let output = open + input + close;
|
711 |
|
712 |
|
713 |
|
714 | return newline ? output.replace(/\r*\n/g, `${close}$&${open}`) : output;
|
715 | };
|
716 | return style;
|
717 | };
|
718 |
|
719 | const wrap = (style, input, newline) => {
|
720 | return typeof style === 'function' ? style(input) : style.wrap(input, newline);
|
721 | };
|
722 |
|
723 | const style = (input, stack) => {
|
724 | if (input === '' || input == null) return '';
|
725 | if (colors.enabled === false) return input;
|
726 | if (colors.visible === false) return '';
|
727 | let str = '' + input;
|
728 | let nl = str.includes('\n');
|
729 | let n = stack.length;
|
730 | if (n > 0 && stack.includes('unstyle')) {
|
731 | stack = [...new Set(['unstyle', ...stack])].reverse();
|
732 | }
|
733 | while (n-- > 0) str = wrap(colors.styles[stack[n]], str, nl);
|
734 | return str;
|
735 | };
|
736 |
|
737 | const define = (name, codes, type) => {
|
738 | colors.styles[name] = ansi({ name, codes });
|
739 | let keys = colors.keys[type] || (colors.keys[type] = []);
|
740 | keys.push(name);
|
741 |
|
742 | Reflect.defineProperty(colors, name, {
|
743 | configurable: true,
|
744 | enumerable: true,
|
745 | set(value) {
|
746 | colors.alias(name, value);
|
747 | },
|
748 | get() {
|
749 | let color = input => style(input, color.stack);
|
750 | Reflect.setPrototypeOf(color, colors);
|
751 | color.stack = this.stack ? this.stack.concat(name) : [name];
|
752 | return color;
|
753 | }
|
754 | });
|
755 | };
|
756 |
|
757 | define('reset', [0, 0], 'modifier');
|
758 | define('bold', [1, 22], 'modifier');
|
759 | define('dim', [2, 22], 'modifier');
|
760 | define('italic', [3, 23], 'modifier');
|
761 | define('underline', [4, 24], 'modifier');
|
762 | define('inverse', [7, 27], 'modifier');
|
763 | define('hidden', [8, 28], 'modifier');
|
764 | define('strikethrough', [9, 29], 'modifier');
|
765 |
|
766 | define('black', [30, 39], 'color');
|
767 | define('red', [31, 39], 'color');
|
768 | define('green', [32, 39], 'color');
|
769 | define('yellow', [33, 39], 'color');
|
770 | define('blue', [34, 39], 'color');
|
771 | define('magenta', [35, 39], 'color');
|
772 | define('cyan', [36, 39], 'color');
|
773 | define('white', [37, 39], 'color');
|
774 | define('gray', [90, 39], 'color');
|
775 | define('grey', [90, 39], 'color');
|
776 |
|
777 | define('bgBlack', [40, 49], 'bg');
|
778 | define('bgRed', [41, 49], 'bg');
|
779 | define('bgGreen', [42, 49], 'bg');
|
780 | define('bgYellow', [43, 49], 'bg');
|
781 | define('bgBlue', [44, 49], 'bg');
|
782 | define('bgMagenta', [45, 49], 'bg');
|
783 | define('bgCyan', [46, 49], 'bg');
|
784 | define('bgWhite', [47, 49], 'bg');
|
785 |
|
786 | define('blackBright', [90, 39], 'bright');
|
787 | define('redBright', [91, 39], 'bright');
|
788 | define('greenBright', [92, 39], 'bright');
|
789 | define('yellowBright', [93, 39], 'bright');
|
790 | define('blueBright', [94, 39], 'bright');
|
791 | define('magentaBright', [95, 39], 'bright');
|
792 | define('cyanBright', [96, 39], 'bright');
|
793 | define('whiteBright', [97, 39], 'bright');
|
794 |
|
795 | define('bgBlackBright', [100, 49], 'bgBright');
|
796 | define('bgRedBright', [101, 49], 'bgBright');
|
797 | define('bgGreenBright', [102, 49], 'bgBright');
|
798 | define('bgYellowBright', [103, 49], 'bgBright');
|
799 | define('bgBlueBright', [104, 49], 'bgBright');
|
800 | define('bgMagentaBright', [105, 49], 'bgBright');
|
801 | define('bgCyanBright', [106, 49], 'bgBright');
|
802 | define('bgWhiteBright', [107, 49], 'bgBright');
|
803 |
|
804 | colors.ansiRegex = ANSI_REGEX;
|
805 | colors.hasColor = colors.hasAnsi = str => {
|
806 | colors.ansiRegex.lastIndex = 0;
|
807 | return typeof str === 'string' && str !== '' && colors.ansiRegex.test(str);
|
808 | };
|
809 |
|
810 | colors.alias = (name, color) => {
|
811 | let fn = typeof color === 'string' ? colors[color] : color;
|
812 |
|
813 | if (typeof fn !== 'function') {
|
814 | throw new TypeError('Expected alias to be the name of an existing color (string) or a function');
|
815 | }
|
816 |
|
817 | if (!fn.stack) {
|
818 | Reflect.defineProperty(fn, 'name', { value: name });
|
819 | colors.styles[name] = fn;
|
820 | fn.stack = [name];
|
821 | }
|
822 |
|
823 | Reflect.defineProperty(colors, name, {
|
824 | configurable: true,
|
825 | enumerable: true,
|
826 | set(value) {
|
827 | colors.alias(name, value);
|
828 | },
|
829 | get() {
|
830 | let color = input => style(input, color.stack);
|
831 | Reflect.setPrototypeOf(color, colors);
|
832 | color.stack = this.stack ? this.stack.concat(fn.stack) : fn.stack;
|
833 | return color;
|
834 | }
|
835 | });
|
836 | };
|
837 |
|
838 | colors.theme = custom => {
|
839 | if (!isObject$1(custom)) throw new TypeError('Expected theme to be an object');
|
840 | for (let name of Object.keys(custom)) {
|
841 | colors.alias(name, custom[name]);
|
842 | }
|
843 | return colors;
|
844 | };
|
845 |
|
846 | colors.alias('unstyle', str => {
|
847 | if (typeof str === 'string' && str !== '') {
|
848 | colors.ansiRegex.lastIndex = 0;
|
849 | return str.replace(colors.ansiRegex, '');
|
850 | }
|
851 | return '';
|
852 | });
|
853 |
|
854 | colors.alias('noop', str => str);
|
855 | colors.none = colors.clear = colors.noop;
|
856 |
|
857 | colors.stripColor = colors.unstyle;
|
858 | colors.symbols = symbols$1;
|
859 | colors.define = define;
|
860 | return colors;
|
861 | };
|
862 |
|
863 | var ansiColors = create$1();
|
864 | var create_1 = create$1;
|
865 | ansiColors.create = create_1;
|
866 |
|
867 | var utils = index.createCommonjsModule(function (module, exports) {
|
868 |
|
869 | const toString = Object.prototype.toString;
|
870 |
|
871 | let called = false;
|
872 | let fns = [];
|
873 |
|
874 | const complements = {
|
875 | 'yellow': 'blue',
|
876 | 'cyan': 'red',
|
877 | 'green': 'magenta',
|
878 | 'black': 'white',
|
879 | 'blue': 'yellow',
|
880 | 'red': 'cyan',
|
881 | 'magenta': 'green',
|
882 | 'white': 'black'
|
883 | };
|
884 |
|
885 | exports.longest = (arr, prop) => {
|
886 | return arr.reduce((a, v) => Math.max(a, prop ? v[prop].length : v.length), 0);
|
887 | };
|
888 |
|
889 | exports.hasColor = str => !!str && ansiColors.hasColor(str);
|
890 |
|
891 | const isObject = exports.isObject = val => {
|
892 | return val !== null && typeof val === 'object' && !Array.isArray(val);
|
893 | };
|
894 |
|
895 | exports.nativeType = val => {
|
896 | return toString.call(val).slice(8, -1).toLowerCase().replace(/\s/g, '');
|
897 | };
|
898 |
|
899 | exports.isAsyncFn = val => {
|
900 | return exports.nativeType(val) === 'asyncfunction';
|
901 | };
|
902 |
|
903 | exports.isPrimitive = val => {
|
904 | return val != null && typeof val !== 'object' && typeof val !== 'function';
|
905 | };
|
906 |
|
907 | exports.resolve = (context, value, ...rest) => {
|
908 | if (typeof value === 'function') {
|
909 | return value.call(context, ...rest);
|
910 | }
|
911 | return value;
|
912 | };
|
913 |
|
914 | exports.scrollDown = (choices = []) => [...choices.slice(1), choices[0]];
|
915 | exports.scrollUp = (choices = []) => [choices.pop(), ...choices];
|
916 |
|
917 | exports.reorder = (arr = []) => {
|
918 | let res = arr.slice();
|
919 | res.sort((a, b) => {
|
920 | if (a.index > b.index) return 1;
|
921 | if (a.index < b.index) return -1;
|
922 | return 0;
|
923 | });
|
924 | return res;
|
925 | };
|
926 |
|
927 | exports.swap = (arr, index, pos) => {
|
928 | let len = arr.length;
|
929 | let idx = pos === len ? 0 : pos < 0 ? len - 1 : pos;
|
930 | let choice = arr[index];
|
931 | arr[index] = arr[idx];
|
932 | arr[idx] = choice;
|
933 | };
|
934 |
|
935 | exports.width = (stream, fallback = 80) => {
|
936 | let columns = (stream && stream.columns) ? stream.columns : fallback;
|
937 | if (stream && typeof stream.getWindowSize === 'function') {
|
938 | columns = stream.getWindowSize()[0];
|
939 | }
|
940 | if (process.platform === 'win32') {
|
941 | return columns - 1;
|
942 | }
|
943 | return columns;
|
944 | };
|
945 |
|
946 | exports.height = (stream, fallback = 20) => {
|
947 | let rows = (stream && stream.rows) ? stream.rows : fallback;
|
948 | if (stream && typeof stream.getWindowSize === 'function') {
|
949 | rows = stream.getWindowSize()[1];
|
950 | }
|
951 | return rows;
|
952 | };
|
953 |
|
954 | exports.wordWrap = (str, options = {}) => {
|
955 | if (!str) return str;
|
956 |
|
957 | if (typeof options === 'number') {
|
958 | options = { width: options };
|
959 | }
|
960 |
|
961 | let { indent = '', newline = ('\n' + indent), width = 80 } = options;
|
962 | let spaces = (newline + indent).match(/[^\S\n]/g) || [];
|
963 | width -= spaces.length;
|
964 | let source = `.{1,${width}}([\\s\\u200B]+|$)|[^\\s\\u200B]+?([\\s\\u200B]+|$)`;
|
965 | let output = str.trim();
|
966 | let regex = new RegExp(source, 'g');
|
967 | let lines = output.match(regex) || [];
|
968 | lines = lines.map(line => line.replace(/\n$/, ''));
|
969 | if (options.padEnd) lines = lines.map(line => line.padEnd(width, ' '));
|
970 | if (options.padStart) lines = lines.map(line => line.padStart(width, ' '));
|
971 | return indent + lines.join(newline);
|
972 | };
|
973 |
|
974 | exports.unmute = color => {
|
975 | let name = color.stack.find(n => ansiColors.keys.color.includes(n));
|
976 | if (name) {
|
977 | return ansiColors[name];
|
978 | }
|
979 | let bg = color.stack.find(n => n.slice(2) === 'bg');
|
980 | if (bg) {
|
981 | return ansiColors[name.slice(2)];
|
982 | }
|
983 | return str => str;
|
984 | };
|
985 |
|
986 | exports.pascal = str => str ? str[0].toUpperCase() + str.slice(1) : '';
|
987 |
|
988 | exports.inverse = color => {
|
989 | if (!color || !color.stack) return color;
|
990 | let name = color.stack.find(n => ansiColors.keys.color.includes(n));
|
991 | if (name) {
|
992 | let col = ansiColors['bg' + exports.pascal(name)];
|
993 | return col ? col.black : color;
|
994 | }
|
995 | let bg = color.stack.find(n => n.slice(0, 2) === 'bg');
|
996 | if (bg) {
|
997 | return ansiColors[bg.slice(2).toLowerCase()] || color;
|
998 | }
|
999 | return ansiColors.none;
|
1000 | };
|
1001 |
|
1002 | exports.complement = color => {
|
1003 | if (!color || !color.stack) return color;
|
1004 | let name = color.stack.find(n => ansiColors.keys.color.includes(n));
|
1005 | let bg = color.stack.find(n => n.slice(0, 2) === 'bg');
|
1006 | if (name && !bg) {
|
1007 | return ansiColors[complements[name] || name];
|
1008 | }
|
1009 | if (bg) {
|
1010 | let lower = bg.slice(2).toLowerCase();
|
1011 | let comp = complements[lower];
|
1012 | if (!comp) return color;
|
1013 | return ansiColors['bg' + exports.pascal(comp)] || color;
|
1014 | }
|
1015 | return ansiColors.none;
|
1016 | };
|
1017 |
|
1018 | exports.meridiem = date => {
|
1019 | let hours = date.getHours();
|
1020 | let minutes = date.getMinutes();
|
1021 | let ampm = hours >= 12 ? 'pm' : 'am';
|
1022 | hours = hours % 12;
|
1023 | let hrs = hours === 0 ? 12 : hours;
|
1024 | let min = minutes < 10 ? '0' + minutes : minutes;
|
1025 | return hrs + ':' + min + ' ' + ampm;
|
1026 | };
|
1027 |
|
1028 |
|
1029 |
|
1030 |
|
1031 |
|
1032 |
|
1033 |
|
1034 |
|
1035 | exports.set = (obj = {}, prop = '', val) => {
|
1036 | return prop.split('.').reduce((acc, k, i, arr) => {
|
1037 | let value = arr.length - 1 > i ? (acc[k] || {}) : val;
|
1038 | if (!exports.isObject(value) && i < arr.length - 1) value = {};
|
1039 | return (acc[k] = value);
|
1040 | }, obj);
|
1041 | };
|
1042 |
|
1043 |
|
1044 |
|
1045 |
|
1046 |
|
1047 |
|
1048 |
|
1049 | exports.get = (obj = {}, prop = '', fallback) => {
|
1050 | let value = obj[prop] == null
|
1051 | ? prop.split('.').reduce((acc, k) => acc && acc[k], obj)
|
1052 | : obj[prop];
|
1053 | return value == null ? fallback : value;
|
1054 | };
|
1055 |
|
1056 | exports.mixin = (target, b) => {
|
1057 | if (!isObject(target)) return b;
|
1058 | if (!isObject(b)) return target;
|
1059 | for (let key of Object.keys(b)) {
|
1060 | let desc = Object.getOwnPropertyDescriptor(b, key);
|
1061 | if (desc.hasOwnProperty('value')) {
|
1062 | if (target.hasOwnProperty(key) && isObject(desc.value)) {
|
1063 | let existing = Object.getOwnPropertyDescriptor(target, key);
|
1064 | if (isObject(existing.value)) {
|
1065 | target[key] = exports.merge({}, target[key], b[key]);
|
1066 | } else {
|
1067 | Reflect.defineProperty(target, key, desc);
|
1068 | }
|
1069 | } else {
|
1070 | Reflect.defineProperty(target, key, desc);
|
1071 | }
|
1072 | } else {
|
1073 | Reflect.defineProperty(target, key, desc);
|
1074 | }
|
1075 | }
|
1076 | return target;
|
1077 | };
|
1078 |
|
1079 | exports.merge = (...args) => {
|
1080 | let target = {};
|
1081 | for (let ele of args) exports.mixin(target, ele);
|
1082 | return target;
|
1083 | };
|
1084 |
|
1085 | exports.mixinEmitter = (obj, emitter) => {
|
1086 | let proto = emitter.constructor.prototype;
|
1087 | for (let key of Object.keys(proto)) {
|
1088 | let val = proto[key];
|
1089 | if (typeof val === 'function') {
|
1090 | exports.define(obj, key, val.bind(emitter));
|
1091 | } else {
|
1092 | exports.define(obj, key, val);
|
1093 | }
|
1094 | }
|
1095 | };
|
1096 |
|
1097 | exports.onExit = callback => {
|
1098 | const onExit = (quit, code) => {
|
1099 | if (called) return;
|
1100 |
|
1101 | called = true;
|
1102 | fns.forEach(fn => fn());
|
1103 |
|
1104 | if (quit === true) {
|
1105 | process.exit(128 + code);
|
1106 | }
|
1107 | };
|
1108 |
|
1109 | if (fns.length === 0) {
|
1110 | process.once('SIGTERM', onExit.bind(null, true, 15));
|
1111 | process.once('SIGINT', onExit.bind(null, true, 2));
|
1112 | process.once('exit', onExit);
|
1113 | }
|
1114 |
|
1115 | fns.push(callback);
|
1116 | };
|
1117 |
|
1118 | exports.define = (obj, key, value) => {
|
1119 | Reflect.defineProperty(obj, key, { value });
|
1120 | };
|
1121 |
|
1122 | exports.defineExport = (obj, key, fn) => {
|
1123 | let custom;
|
1124 | Reflect.defineProperty(obj, key, {
|
1125 | enumerable: true,
|
1126 | configurable: true,
|
1127 | set(val) {
|
1128 | custom = val;
|
1129 | },
|
1130 | get() {
|
1131 | return custom ? custom() : fn();
|
1132 | }
|
1133 | });
|
1134 | };
|
1135 | });
|
1136 |
|
1137 |
|
1138 |
|
1139 |
|
1140 |
|
1141 |
|
1142 | var ctrl = {
|
1143 | a: 'first',
|
1144 | b: 'backward',
|
1145 | c: 'cancel',
|
1146 | d: 'deleteForward',
|
1147 | e: 'last',
|
1148 | f: 'forward',
|
1149 | g: 'reset',
|
1150 | i: 'tab',
|
1151 | k: 'cutForward',
|
1152 | l: 'reset',
|
1153 | n: 'newItem',
|
1154 | m: 'cancel',
|
1155 | j: 'submit',
|
1156 | p: 'search',
|
1157 | r: 'remove',
|
1158 | s: 'save',
|
1159 | u: 'undo',
|
1160 | w: 'cutLeft',
|
1161 | x: 'toggleCursor',
|
1162 | v: 'paste'
|
1163 | };
|
1164 |
|
1165 | var shift = {
|
1166 | up: 'shiftUp',
|
1167 | down: 'shiftDown',
|
1168 | left: 'shiftLeft',
|
1169 | right: 'shiftRight',
|
1170 | tab: 'prev'
|
1171 | };
|
1172 |
|
1173 | var fn = {
|
1174 | up: 'pageUp',
|
1175 | down: 'pageDown',
|
1176 | left: 'pageLeft',
|
1177 | right: 'pageRight',
|
1178 | delete: 'deleteForward'
|
1179 | };
|
1180 |
|
1181 |
|
1182 | var option = {
|
1183 | b: 'backward',
|
1184 | f: 'forward',
|
1185 | d: 'cutRight',
|
1186 | left: 'cutLeft',
|
1187 | up: 'altUp',
|
1188 | down: 'altDown'
|
1189 | };
|
1190 |
|
1191 | var keys = {
|
1192 | pageup: 'pageUp',
|
1193 | pagedown: 'pageDown',
|
1194 | home: 'home',
|
1195 | end: 'end',
|
1196 | cancel: 'cancel',
|
1197 | delete: 'deleteForward',
|
1198 | backspace: 'delete',
|
1199 | down: 'down',
|
1200 | enter: 'submit',
|
1201 | escape: 'cancel',
|
1202 | left: 'left',
|
1203 | space: 'space',
|
1204 | number: 'number',
|
1205 | return: 'submit',
|
1206 | right: 'right',
|
1207 | tab: 'next',
|
1208 | up: 'up'
|
1209 | };
|
1210 |
|
1211 | var combos = {
|
1212 | ctrl: ctrl,
|
1213 | shift: shift,
|
1214 | fn: fn,
|
1215 | option: option,
|
1216 | keys: keys
|
1217 | };
|
1218 |
|
1219 |
|
1220 | const metaKeyCodeRe = /^(?:\x1b)([a-zA-Z0-9])$/;
|
1221 | const fnKeyRe = /^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/;
|
1222 | const keyName = {
|
1223 |
|
1224 | 'OP': 'f1',
|
1225 | 'OQ': 'f2',
|
1226 | 'OR': 'f3',
|
1227 | 'OS': 'f4',
|
1228 |
|
1229 | '[11~': 'f1',
|
1230 | '[12~': 'f2',
|
1231 | '[13~': 'f3',
|
1232 | '[14~': 'f4',
|
1233 |
|
1234 | '[[A': 'f1',
|
1235 | '[[B': 'f2',
|
1236 | '[[C': 'f3',
|
1237 | '[[D': 'f4',
|
1238 | '[[E': 'f5',
|
1239 |
|
1240 | '[15~': 'f5',
|
1241 | '[17~': 'f6',
|
1242 | '[18~': 'f7',
|
1243 | '[19~': 'f8',
|
1244 | '[20~': 'f9',
|
1245 | '[21~': 'f10',
|
1246 | '[23~': 'f11',
|
1247 | '[24~': 'f12',
|
1248 |
|
1249 | '[A': 'up',
|
1250 | '[B': 'down',
|
1251 | '[C': 'right',
|
1252 | '[D': 'left',
|
1253 | '[E': 'clear',
|
1254 | '[F': 'end',
|
1255 | '[H': 'home',
|
1256 |
|
1257 | 'OA': 'up',
|
1258 | 'OB': 'down',
|
1259 | 'OC': 'right',
|
1260 | 'OD': 'left',
|
1261 | 'OE': 'clear',
|
1262 | 'OF': 'end',
|
1263 | 'OH': 'home',
|
1264 |
|
1265 | '[1~': 'home',
|
1266 | '[2~': 'insert',
|
1267 | '[3~': 'delete',
|
1268 | '[4~': 'end',
|
1269 | '[5~': 'pageup',
|
1270 | '[6~': 'pagedown',
|
1271 |
|
1272 | '[[5~': 'pageup',
|
1273 | '[[6~': 'pagedown',
|
1274 |
|
1275 | '[7~': 'home',
|
1276 | '[8~': 'end',
|
1277 |
|
1278 | '[a': 'up',
|
1279 | '[b': 'down',
|
1280 | '[c': 'right',
|
1281 | '[d': 'left',
|
1282 | '[e': 'clear',
|
1283 |
|
1284 | '[2$': 'insert',
|
1285 | '[3$': 'delete',
|
1286 | '[5$': 'pageup',
|
1287 | '[6$': 'pagedown',
|
1288 | '[7$': 'home',
|
1289 | '[8$': 'end',
|
1290 |
|
1291 | 'Oa': 'up',
|
1292 | 'Ob': 'down',
|
1293 | 'Oc': 'right',
|
1294 | 'Od': 'left',
|
1295 | 'Oe': 'clear',
|
1296 |
|
1297 | '[2^': 'insert',
|
1298 | '[3^': 'delete',
|
1299 | '[5^': 'pageup',
|
1300 | '[6^': 'pagedown',
|
1301 | '[7^': 'home',
|
1302 | '[8^': 'end',
|
1303 |
|
1304 | '[Z': 'tab',
|
1305 | };
|
1306 |
|
1307 | function isShiftKey(code) {
|
1308 | return ['[a', '[b', '[c', '[d', '[e', '[2$', '[3$', '[5$', '[6$', '[7$', '[8$', '[Z'].includes(code)
|
1309 | }
|
1310 |
|
1311 | function isCtrlKey(code) {
|
1312 | return [ 'Oa', 'Ob', 'Oc', 'Od', 'Oe', '[2^', '[3^', '[5^', '[6^', '[7^', '[8^'].includes(code)
|
1313 | }
|
1314 |
|
1315 | const keypress = (s = '', event = {}) => {
|
1316 | let parts;
|
1317 | let key = {
|
1318 | name: event.name,
|
1319 | ctrl: false,
|
1320 | meta: false,
|
1321 | shift: false,
|
1322 | option: false,
|
1323 | sequence: s,
|
1324 | raw: s,
|
1325 | ...event
|
1326 | };
|
1327 |
|
1328 | if (Buffer.isBuffer(s)) {
|
1329 | if (s[0] > 127 && s[1] === void 0) {
|
1330 | s[0] -= 128;
|
1331 | s = '\x1b' + String(s);
|
1332 | } else {
|
1333 | s = String(s);
|
1334 | }
|
1335 | } else if (s !== void 0 && typeof s !== 'string') {
|
1336 | s = String(s);
|
1337 | } else if (!s) {
|
1338 | s = key.sequence || '';
|
1339 | }
|
1340 |
|
1341 | key.sequence = key.sequence || s || key.name;
|
1342 |
|
1343 | if (s === '\r') {
|
1344 |
|
1345 | key.raw = void 0;
|
1346 | key.name = 'return';
|
1347 | } else if (s === '\n') {
|
1348 |
|
1349 | key.name = 'enter';
|
1350 | } else if (s === '\t') {
|
1351 |
|
1352 | key.name = 'tab';
|
1353 | } else if (s === '\b' || s === '\x7f' || s === '\x1b\x7f' || s === '\x1b\b') {
|
1354 |
|
1355 | key.name = 'backspace';
|
1356 | key.meta = s.charAt(0) === '\x1b';
|
1357 | } else if (s === '\x1b' || s === '\x1b\x1b') {
|
1358 |
|
1359 | key.name = 'escape';
|
1360 | key.meta = s.length === 2;
|
1361 | } else if (s === ' ' || s === '\x1b ') {
|
1362 | key.name = 'space';
|
1363 | key.meta = s.length === 2;
|
1364 | } else if (s <= '\x1a') {
|
1365 |
|
1366 | key.name = String.fromCharCode(s.charCodeAt(0) + 'a'.charCodeAt(0) - 1);
|
1367 | key.ctrl = true;
|
1368 | } else if (s.length === 1 && s >= '0' && s <= '9') {
|
1369 |
|
1370 | key.name = 'number';
|
1371 | } else if (s.length === 1 && s >= 'a' && s <= 'z') {
|
1372 |
|
1373 | key.name = s;
|
1374 | } else if (s.length === 1 && s >= 'A' && s <= 'Z') {
|
1375 |
|
1376 | key.name = s.toLowerCase();
|
1377 | key.shift = true;
|
1378 | } else if ((parts = metaKeyCodeRe.exec(s))) {
|
1379 |
|
1380 | key.meta = true;
|
1381 | key.shift = /^[A-Z]$/.test(parts[1]);
|
1382 | } else if ((parts = fnKeyRe.exec(s))) {
|
1383 | let segs = [...s];
|
1384 |
|
1385 | if (segs[0] === '\u001b' && segs[1] === '\u001b') {
|
1386 | key.option = true;
|
1387 | }
|
1388 |
|
1389 |
|
1390 |
|
1391 |
|
1392 | let code = [parts[1], parts[2], parts[4], parts[6]].filter(Boolean).join('');
|
1393 | let modifier = (parts[3] || parts[5] || 1) - 1;
|
1394 |
|
1395 |
|
1396 | key.ctrl = !!(modifier & 4);
|
1397 | key.meta = !!(modifier & 10);
|
1398 | key.shift = !!(modifier & 1);
|
1399 | key.code = code;
|
1400 |
|
1401 | key.name = keyName[code];
|
1402 | key.shift = isShiftKey(code) || key.shift;
|
1403 | key.ctrl = isCtrlKey(code) || key.ctrl;
|
1404 | }
|
1405 | return key;
|
1406 | };
|
1407 |
|
1408 | keypress.listen = (options = {}, onKeypress) => {
|
1409 | let { stdin } = options;
|
1410 |
|
1411 | if (!stdin || (stdin !== process.stdin && !stdin.isTTY)) {
|
1412 | throw new Error('Invalid stream passed');
|
1413 | }
|
1414 |
|
1415 | let rl = readline__default['default'].createInterface({ terminal: true, input: stdin });
|
1416 | readline__default['default'].emitKeypressEvents(stdin, rl);
|
1417 |
|
1418 | let on = (buf, key) => onKeypress(buf, keypress(buf, key), rl);
|
1419 | let isRaw = stdin.isRaw;
|
1420 |
|
1421 | if (stdin.isTTY) stdin.setRawMode(true);
|
1422 | stdin.on('keypress', on);
|
1423 | rl.resume();
|
1424 |
|
1425 | let off = () => {
|
1426 | if (stdin.isTTY) stdin.setRawMode(isRaw);
|
1427 | stdin.removeListener('keypress', on);
|
1428 | rl.pause();
|
1429 | rl.close();
|
1430 | };
|
1431 |
|
1432 | return off;
|
1433 | };
|
1434 |
|
1435 | keypress.action = (buf, key, customActions) => {
|
1436 | let obj = { ...combos, ...customActions };
|
1437 | if (key.ctrl) {
|
1438 | key.action = obj.ctrl[key.name];
|
1439 | return key;
|
1440 | }
|
1441 |
|
1442 | if (key.option && obj.option) {
|
1443 | key.action = obj.option[key.name];
|
1444 | return key;
|
1445 | }
|
1446 |
|
1447 | if (key.shift) {
|
1448 | key.action = obj.shift[key.name];
|
1449 | return key;
|
1450 | }
|
1451 |
|
1452 | key.action = obj.keys[key.name];
|
1453 | return key;
|
1454 | };
|
1455 |
|
1456 | var keypress_1 = keypress;
|
1457 |
|
1458 | var timer = prompt => {
|
1459 | prompt.timers = prompt.timers || {};
|
1460 |
|
1461 | let timers = prompt.options.timers;
|
1462 | if (!timers) return;
|
1463 |
|
1464 | for (let key of Object.keys(timers)) {
|
1465 | let opts = timers[key];
|
1466 | if (typeof opts === 'number') {
|
1467 | opts = { interval: opts };
|
1468 | }
|
1469 | create(prompt, key, opts);
|
1470 | }
|
1471 | };
|
1472 |
|
1473 | function create(prompt, name, options = {}) {
|
1474 | let timer = prompt.timers[name] = { name, start: Date.now(), ms: 0, tick: 0 };
|
1475 | let ms = options.interval || 120;
|
1476 | timer.frames = options.frames || [];
|
1477 | timer.loading = true;
|
1478 |
|
1479 | let interval = setInterval(() => {
|
1480 | timer.ms = Date.now() - timer.start;
|
1481 | timer.tick++;
|
1482 | prompt.render();
|
1483 | }, ms);
|
1484 |
|
1485 | timer.stop = () => {
|
1486 | timer.loading = false;
|
1487 | clearInterval(interval);
|
1488 | };
|
1489 |
|
1490 | Reflect.defineProperty(timer, 'interval', { value: interval });
|
1491 | prompt.once('close', () => timer.stop());
|
1492 | return timer.stop;
|
1493 | }
|
1494 |
|
1495 | const { define, width } = utils;
|
1496 |
|
1497 | class State {
|
1498 | constructor(prompt) {
|
1499 | let options = prompt.options;
|
1500 | define(this, '_prompt', prompt);
|
1501 | this.type = prompt.type;
|
1502 | this.name = prompt.name;
|
1503 | this.message = '';
|
1504 | this.header = '';
|
1505 | this.footer = '';
|
1506 | this.error = '';
|
1507 | this.hint = '';
|
1508 | this.input = '';
|
1509 | this.cursor = 0;
|
1510 | this.index = 0;
|
1511 | this.lines = 0;
|
1512 | this.tick = 0;
|
1513 | this.prompt = '';
|
1514 | this.buffer = '';
|
1515 | this.width = width(options.stdout || process.stdout);
|
1516 | Object.assign(this, options);
|
1517 | this.name = this.name || this.message;
|
1518 | this.message = this.message || this.name;
|
1519 | this.symbols = prompt.symbols;
|
1520 | this.styles = prompt.styles;
|
1521 | this.required = new Set();
|
1522 | this.cancelled = false;
|
1523 | this.submitted = false;
|
1524 | }
|
1525 |
|
1526 | clone() {
|
1527 | let state = { ...this };
|
1528 | state.status = this.status;
|
1529 | state.buffer = Buffer.from(state.buffer);
|
1530 | delete state.clone;
|
1531 | return state;
|
1532 | }
|
1533 |
|
1534 | set color(val) {
|
1535 | this._color = val;
|
1536 | }
|
1537 | get color() {
|
1538 | let styles = this.prompt.styles;
|
1539 | if (this.cancelled) return styles.cancelled;
|
1540 | if (this.submitted) return styles.submitted;
|
1541 | let color = this._color || styles[this.status];
|
1542 | return typeof color === 'function' ? color : styles.pending;
|
1543 | }
|
1544 |
|
1545 | set loading(value) {
|
1546 | this._loading = value;
|
1547 | }
|
1548 | get loading() {
|
1549 | if (typeof this._loading === 'boolean') return this._loading;
|
1550 | if (this.loadingChoices) return 'choices';
|
1551 | return false;
|
1552 | }
|
1553 |
|
1554 | get status() {
|
1555 | if (this.cancelled) return 'cancelled';
|
1556 | if (this.submitted) return 'submitted';
|
1557 | return 'pending';
|
1558 | }
|
1559 | }
|
1560 |
|
1561 | var state = State;
|
1562 |
|
1563 | const styles = {
|
1564 | default: ansiColors.noop,
|
1565 | noop: ansiColors.noop,
|
1566 |
|
1567 | |
1568 |
|
1569 |
|
1570 |
|
1571 | set inverse(custom) {
|
1572 | this._inverse = custom;
|
1573 | },
|
1574 | get inverse() {
|
1575 | return this._inverse || utils.inverse(this.primary);
|
1576 | },
|
1577 |
|
1578 | set complement(custom) {
|
1579 | this._complement = custom;
|
1580 | },
|
1581 | get complement() {
|
1582 | return this._complement || utils.complement(this.primary);
|
1583 | },
|
1584 |
|
1585 | |
1586 |
|
1587 |
|
1588 |
|
1589 | primary: ansiColors.cyan,
|
1590 |
|
1591 | |
1592 |
|
1593 |
|
1594 |
|
1595 | success: ansiColors.green,
|
1596 | danger: ansiColors.magenta,
|
1597 | strong: ansiColors.bold,
|
1598 | warning: ansiColors.yellow,
|
1599 | muted: ansiColors.dim,
|
1600 | disabled: ansiColors.gray,
|
1601 | dark: ansiColors.dim.gray,
|
1602 | underline: ansiColors.underline,
|
1603 |
|
1604 | set info(custom) {
|
1605 | this._info = custom;
|
1606 | },
|
1607 | get info() {
|
1608 | return this._info || this.primary;
|
1609 | },
|
1610 |
|
1611 | set em(custom) {
|
1612 | this._em = custom;
|
1613 | },
|
1614 | get em() {
|
1615 | return this._em || this.primary.underline;
|
1616 | },
|
1617 |
|
1618 | set heading(custom) {
|
1619 | this._heading = custom;
|
1620 | },
|
1621 | get heading() {
|
1622 | return this._heading || this.muted.underline;
|
1623 | },
|
1624 |
|
1625 | |
1626 |
|
1627 |
|
1628 |
|
1629 | set pending(custom) {
|
1630 | this._pending = custom;
|
1631 | },
|
1632 | get pending() {
|
1633 | return this._pending || this.primary;
|
1634 | },
|
1635 |
|
1636 | set submitted(custom) {
|
1637 | this._submitted = custom;
|
1638 | },
|
1639 | get submitted() {
|
1640 | return this._submitted || this.success;
|
1641 | },
|
1642 |
|
1643 | set cancelled(custom) {
|
1644 | this._cancelled = custom;
|
1645 | },
|
1646 | get cancelled() {
|
1647 | return this._cancelled || this.danger;
|
1648 | },
|
1649 |
|
1650 | |
1651 |
|
1652 |
|
1653 |
|
1654 | set typing(custom) {
|
1655 | this._typing = custom;
|
1656 | },
|
1657 | get typing() {
|
1658 | return this._typing || this.dim;
|
1659 | },
|
1660 |
|
1661 | set placeholder(custom) {
|
1662 | this._placeholder = custom;
|
1663 | },
|
1664 | get placeholder() {
|
1665 | return this._placeholder || this.primary.dim;
|
1666 | },
|
1667 |
|
1668 | set highlight(custom) {
|
1669 | this._highlight = custom;
|
1670 | },
|
1671 | get highlight() {
|
1672 | return this._highlight || this.inverse;
|
1673 | }
|
1674 | };
|
1675 |
|
1676 | styles.merge = (options = {}) => {
|
1677 | if (options.styles && typeof options.styles.enabled === 'boolean') {
|
1678 | ansiColors.enabled = options.styles.enabled;
|
1679 | }
|
1680 | if (options.styles && typeof options.styles.visible === 'boolean') {
|
1681 | ansiColors.visible = options.styles.visible;
|
1682 | }
|
1683 |
|
1684 | let result = utils.merge({}, styles, options.styles);
|
1685 | delete result.merge;
|
1686 |
|
1687 | for (let key of Object.keys(ansiColors)) {
|
1688 | if (!result.hasOwnProperty(key)) {
|
1689 | Reflect.defineProperty(result, key, { get: () => ansiColors[key] });
|
1690 | }
|
1691 | }
|
1692 |
|
1693 | for (let key of Object.keys(ansiColors.styles)) {
|
1694 | if (!result.hasOwnProperty(key)) {
|
1695 | Reflect.defineProperty(result, key, { get: () => ansiColors[key] });
|
1696 | }
|
1697 | }
|
1698 | return result;
|
1699 | };
|
1700 |
|
1701 | var styles_1 = styles;
|
1702 |
|
1703 | const isWindows = process.platform === 'win32';
|
1704 |
|
1705 |
|
1706 |
|
1707 | const symbols = {
|
1708 | ...ansiColors.symbols,
|
1709 | upDownDoubleArrow: '⇕',
|
1710 | upDownDoubleArrow2: '⬍',
|
1711 | upDownArrow: '↕',
|
1712 | asterisk: '*',
|
1713 | asterism: '⁂',
|
1714 | bulletWhite: '◦',
|
1715 | electricArrow: '⌁',
|
1716 | ellipsisLarge: '⋯',
|
1717 | ellipsisSmall: '…',
|
1718 | fullBlock: '█',
|
1719 | identicalTo: '≡',
|
1720 | indicator: ansiColors.symbols.check,
|
1721 | leftAngle: '‹',
|
1722 | mark: '※',
|
1723 | minus: '−',
|
1724 | multiplication: '×',
|
1725 | obelus: '÷',
|
1726 | percent: '%',
|
1727 | pilcrow: '¶',
|
1728 | pilcrow2: '❡',
|
1729 | pencilUpRight: '✐',
|
1730 | pencilDownRight: '✎',
|
1731 | pencilRight: '✏',
|
1732 | plus: '+',
|
1733 | plusMinus: '±',
|
1734 | pointRight: '☞',
|
1735 | rightAngle: '›',
|
1736 | section: '§',
|
1737 | hexagon: { off: '⬡', on: '⬢', disabled: '⬢' },
|
1738 | ballot: { on: '☑', off: '☐', disabled: '☒' },
|
1739 | stars: { on: '★', off: '☆', disabled: '☆' },
|
1740 | folder: { on: '▼', off: '▶', disabled: '▶' },
|
1741 | prefix: {
|
1742 | pending: ansiColors.symbols.question,
|
1743 | submitted: ansiColors.symbols.check,
|
1744 | cancelled: ansiColors.symbols.cross
|
1745 | },
|
1746 | separator: {
|
1747 | pending: ansiColors.symbols.pointerSmall,
|
1748 | submitted: ansiColors.symbols.middot,
|
1749 | cancelled: ansiColors.symbols.middot
|
1750 | },
|
1751 | radio: {
|
1752 | off: isWindows ? '( )' : '◯',
|
1753 | on: isWindows ? '(*)' : '◉',
|
1754 | disabled: isWindows ? '(|)' : 'Ⓘ'
|
1755 | },
|
1756 | numbers: ['⓪', '①', '②', '③', '④', '⑤', '⑥', '⑦', '⑧', '⑨', '⑩', '⑪', '⑫', '⑬', '⑭', '⑮', '⑯', '⑰', '⑱', '⑲', '⑳', '㉑', '㉒', '㉓', '㉔', '㉕', '㉖', '㉗', '㉘', '㉙', '㉚', '㉛', '㉜', '㉝', '㉞', '㉟', '㊱', '㊲', '㊳', '㊴', '㊵', '㊶', '㊷', '㊸', '㊹', '㊺', '㊻', '㊼', '㊽', '㊾', '㊿']
|
1757 | };
|
1758 |
|
1759 | symbols.merge = options => {
|
1760 | let result = utils.merge({}, ansiColors.symbols, symbols, options.symbols);
|
1761 | delete result.merge;
|
1762 | return result;
|
1763 | };
|
1764 |
|
1765 | var symbols_1 = symbols;
|
1766 |
|
1767 | var theme = prompt => {
|
1768 | prompt.options = utils.merge({}, prompt.options.theme, prompt.options);
|
1769 | prompt.symbols = symbols_1.merge(prompt.options);
|
1770 | prompt.styles = styles_1.merge(prompt.options);
|
1771 | };
|
1772 |
|
1773 | var ansi_1 = index.createCommonjsModule(function (module, exports) {
|
1774 |
|
1775 | const isTerm = process.env.TERM_PROGRAM === 'Apple_Terminal';
|
1776 |
|
1777 |
|
1778 | const ansi = module.exports = exports;
|
1779 | const ESC = '\u001b[';
|
1780 | const BEL = '\u0007';
|
1781 | let hidden = false;
|
1782 |
|
1783 | const code = ansi.code = {
|
1784 | bell: BEL,
|
1785 | beep: BEL,
|
1786 | beginning: `${ESC}G`,
|
1787 | down: `${ESC}J`,
|
1788 | esc: ESC,
|
1789 | getPosition: `${ESC}6n`,
|
1790 | hide: `${ESC}?25l`,
|
1791 | line: `${ESC}2K`,
|
1792 | lineEnd: `${ESC}K`,
|
1793 | lineStart: `${ESC}1K`,
|
1794 | restorePosition: ESC + (isTerm ? '8' : 'u'),
|
1795 | savePosition: ESC + (isTerm ? '7' : 's'),
|
1796 | screen: `${ESC}2J`,
|
1797 | show: `${ESC}?25h`,
|
1798 | up: `${ESC}1J`
|
1799 | };
|
1800 |
|
1801 | const cursor = ansi.cursor = {
|
1802 | get hidden() {
|
1803 | return hidden;
|
1804 | },
|
1805 |
|
1806 | hide() {
|
1807 | hidden = true;
|
1808 | return code.hide;
|
1809 | },
|
1810 | show() {
|
1811 | hidden = false;
|
1812 | return code.show;
|
1813 | },
|
1814 |
|
1815 | forward: (count = 1) => `${ESC}${count}C`,
|
1816 | backward: (count = 1) => `${ESC}${count}D`,
|
1817 | nextLine: (count = 1) => `${ESC}E`.repeat(count),
|
1818 | prevLine: (count = 1) => `${ESC}F`.repeat(count),
|
1819 |
|
1820 | up: (count = 1) => count ? `${ESC}${count}A` : '',
|
1821 | down: (count = 1) => count ? `${ESC}${count}B` : '',
|
1822 | right: (count = 1) => count ? `${ESC}${count}C` : '',
|
1823 | left: (count = 1) => count ? `${ESC}${count}D` : '',
|
1824 |
|
1825 | to(x, y) {
|
1826 | return y ? `${ESC}${y + 1};${x + 1}H` : `${ESC}${x + 1}G`;
|
1827 | },
|
1828 |
|
1829 | move(x = 0, y = 0) {
|
1830 | let res = '';
|
1831 | res += (x < 0) ? cursor.left(-x) : (x > 0) ? cursor.right(x) : '';
|
1832 | res += (y < 0) ? cursor.up(-y) : (y > 0) ? cursor.down(y) : '';
|
1833 | return res;
|
1834 | },
|
1835 |
|
1836 | restore(state = {}) {
|
1837 | let { after, cursor, initial, input, prompt, size, value } = state;
|
1838 | initial = utils.isPrimitive(initial) ? String(initial) : '';
|
1839 | input = utils.isPrimitive(input) ? String(input) : '';
|
1840 | value = utils.isPrimitive(value) ? String(value) : '';
|
1841 |
|
1842 | if (size) {
|
1843 | let codes = ansi.cursor.up(size) + ansi.cursor.to(prompt.length);
|
1844 | let diff = input.length - cursor;
|
1845 | if (diff > 0) {
|
1846 | codes += ansi.cursor.left(diff);
|
1847 | }
|
1848 | return codes;
|
1849 | }
|
1850 |
|
1851 | if (value || after) {
|
1852 | let pos = (!input && !!initial) ? -initial.length : -input.length + cursor;
|
1853 | if (after) pos -= after.length;
|
1854 | if (input === '' && initial && !prompt.includes(initial)) {
|
1855 | pos += initial.length;
|
1856 | }
|
1857 | return ansi.cursor.move(pos);
|
1858 | }
|
1859 | }
|
1860 | };
|
1861 |
|
1862 | const erase = ansi.erase = {
|
1863 | screen: code.screen,
|
1864 | up: code.up,
|
1865 | down: code.down,
|
1866 | line: code.line,
|
1867 | lineEnd: code.lineEnd,
|
1868 | lineStart: code.lineStart,
|
1869 | lines(n) {
|
1870 | let str = '';
|
1871 | for (let i = 0; i < n; i++) {
|
1872 | str += ansi.erase.line + (i < n - 1 ? ansi.cursor.up(1) : '');
|
1873 | }
|
1874 | if (n) str += ansi.code.beginning;
|
1875 | return str;
|
1876 | }
|
1877 | };
|
1878 |
|
1879 | ansi.clear = (input = '', columns = process.stdout.columns) => {
|
1880 | if (!columns) return erase.line + cursor.to(0);
|
1881 | let width = str => [...ansiColors.unstyle(str)].length;
|
1882 | let lines = input.split(/\r?\n/);
|
1883 | let rows = 0;
|
1884 | for (let line of lines) {
|
1885 | rows += 1 + Math.floor(Math.max(width(line) - 1, 0) / columns);
|
1886 | }
|
1887 | return (erase.line + cursor.prevLine()).repeat(rows - 1) + erase.line + cursor.to(0);
|
1888 | };
|
1889 | });
|
1890 |
|
1891 |
|
1892 |
|
1893 |
|
1894 |
|
1895 |
|
1896 | class Prompt extends Events__default['default'] {
|
1897 | constructor(options = {}) {
|
1898 | super();
|
1899 | this.name = options.name;
|
1900 | this.type = options.type;
|
1901 | this.options = options;
|
1902 | theme(this);
|
1903 | timer(this);
|
1904 | this.state = new state(this);
|
1905 | this.initial = [options.initial, options.default].find(v => v != null);
|
1906 | this.stdout = options.stdout || process.stdout;
|
1907 | this.stdin = options.stdin || process.stdin;
|
1908 | this.scale = options.scale || 1;
|
1909 | this.term = this.options.term || process.env.TERM_PROGRAM;
|
1910 | this.margin = margin(this.options.margin);
|
1911 | this.setMaxListeners(0);
|
1912 | setOptions(this);
|
1913 | }
|
1914 |
|
1915 | async keypress(input, event = {}) {
|
1916 | this.keypressed = true;
|
1917 | let key = keypress_1.action(input, keypress_1(input, event), this.options.actions);
|
1918 | this.state.keypress = key;
|
1919 | this.emit('keypress', input, key);
|
1920 | this.emit('state', this.state.clone());
|
1921 | let fn = this.options[key.action] || this[key.action] || this.dispatch;
|
1922 | if (typeof fn === 'function') {
|
1923 | return await fn.call(this, input, key);
|
1924 | }
|
1925 | this.alert();
|
1926 | }
|
1927 |
|
1928 | alert() {
|
1929 | delete this.state.alert;
|
1930 | if (this.options.show === false) {
|
1931 | this.emit('alert');
|
1932 | } else {
|
1933 | this.stdout.write(ansi_1.code.beep);
|
1934 | }
|
1935 | }
|
1936 |
|
1937 | cursorHide() {
|
1938 | this.stdout.write(ansi_1.cursor.hide());
|
1939 | utils.onExit(() => this.cursorShow());
|
1940 | }
|
1941 |
|
1942 | cursorShow() {
|
1943 | this.stdout.write(ansi_1.cursor.show());
|
1944 | }
|
1945 |
|
1946 | write(str) {
|
1947 | if (!str) return;
|
1948 | if (this.stdout && this.state.show !== false) {
|
1949 | this.stdout.write(str);
|
1950 | }
|
1951 | this.state.buffer += str;
|
1952 | }
|
1953 |
|
1954 | clear(lines = 0) {
|
1955 | let buffer = this.state.buffer;
|
1956 | this.state.buffer = '';
|
1957 | if ((!buffer && !lines) || this.options.show === false) return;
|
1958 | this.stdout.write(ansi_1.cursor.down(lines) + ansi_1.clear(buffer, this.width));
|
1959 | }
|
1960 |
|
1961 | restore() {
|
1962 | if (this.state.closed || this.options.show === false) return;
|
1963 |
|
1964 | let { prompt, after, rest } = this.sections();
|
1965 | let { cursor, initial = '', input = '', value = '' } = this;
|
1966 |
|
1967 | let size = this.state.size = rest.length;
|
1968 | let state = { after, cursor, initial, input, prompt, size, value };
|
1969 | let codes = ansi_1.cursor.restore(state);
|
1970 | if (codes) {
|
1971 | this.stdout.write(codes);
|
1972 | }
|
1973 | }
|
1974 |
|
1975 | sections() {
|
1976 | let { buffer, input, prompt } = this.state;
|
1977 | prompt = ansiColors.unstyle(prompt);
|
1978 | let buf = ansiColors.unstyle(buffer);
|
1979 | let idx = buf.indexOf(prompt);
|
1980 | let header = buf.slice(0, idx);
|
1981 | let rest = buf.slice(idx);
|
1982 | let lines = rest.split('\n');
|
1983 | let first = lines[0];
|
1984 | let last = lines[lines.length - 1];
|
1985 | let promptLine = prompt + (input ? ' ' + input : '');
|
1986 | let len = promptLine.length;
|
1987 | let after = len < first.length ? first.slice(len + 1) : '';
|
1988 | return { header, prompt: first, after, rest: lines.slice(1), last };
|
1989 | }
|
1990 |
|
1991 | async submit() {
|
1992 | this.state.submitted = true;
|
1993 | this.state.validating = true;
|
1994 |
|
1995 |
|
1996 |
|
1997 |
|
1998 | if (this.options.onSubmit) {
|
1999 | await this.options.onSubmit.call(this, this.name, this.value, this);
|
2000 | }
|
2001 |
|
2002 | let result = this.state.error || await this.validate(this.value, this.state);
|
2003 | if (result !== true) {
|
2004 | let error = '\n' + this.symbols.pointer + ' ';
|
2005 |
|
2006 | if (typeof result === 'string') {
|
2007 | error += result.trim();
|
2008 | } else {
|
2009 | error += 'Invalid input';
|
2010 | }
|
2011 |
|
2012 | this.state.error = '\n' + this.styles.danger(error);
|
2013 | this.state.submitted = false;
|
2014 | await this.render();
|
2015 | await this.alert();
|
2016 | this.state.validating = false;
|
2017 | this.state.error = void 0;
|
2018 | return;
|
2019 | }
|
2020 |
|
2021 | this.state.validating = false;
|
2022 | await this.render();
|
2023 | await this.close();
|
2024 |
|
2025 | this.value = await this.result(this.value);
|
2026 | this.emit('submit', this.value);
|
2027 | }
|
2028 |
|
2029 | async cancel(err) {
|
2030 | this.state.cancelled = this.state.submitted = true;
|
2031 |
|
2032 | await this.render();
|
2033 | await this.close();
|
2034 |
|
2035 | if (typeof this.options.onCancel === 'function') {
|
2036 | await this.options.onCancel.call(this, this.name, this.value, this);
|
2037 | }
|
2038 |
|
2039 | this.emit('cancel', await this.error(err));
|
2040 | }
|
2041 |
|
2042 | async close() {
|
2043 | this.state.closed = true;
|
2044 |
|
2045 | try {
|
2046 | let sections = this.sections();
|
2047 | let lines = Math.ceil(sections.prompt.length / this.width);
|
2048 | if (sections.rest) {
|
2049 | this.write(ansi_1.cursor.down(sections.rest.length));
|
2050 | }
|
2051 | this.write('\n'.repeat(lines));
|
2052 | } catch (err) { }
|
2053 |
|
2054 | this.emit('close');
|
2055 | }
|
2056 |
|
2057 | start() {
|
2058 | if (!this.stop && this.options.show !== false) {
|
2059 | this.stop = keypress_1.listen(this, this.keypress.bind(this));
|
2060 | this.once('close', this.stop);
|
2061 | }
|
2062 | }
|
2063 |
|
2064 | async skip() {
|
2065 | this.skipped = this.options.skip === true;
|
2066 | if (typeof this.options.skip === 'function') {
|
2067 | this.skipped = await this.options.skip.call(this, this.name, this.value);
|
2068 | }
|
2069 | return this.skipped;
|
2070 | }
|
2071 |
|
2072 | async initialize() {
|
2073 | let { format, options, result } = this;
|
2074 |
|
2075 | this.format = () => format.call(this, this.value);
|
2076 | this.result = () => result.call(this, this.value);
|
2077 |
|
2078 | if (typeof options.initial === 'function') {
|
2079 | this.initial = await options.initial.call(this, this);
|
2080 | }
|
2081 |
|
2082 | if (typeof options.onRun === 'function') {
|
2083 | await options.onRun.call(this, this);
|
2084 | }
|
2085 |
|
2086 |
|
2087 |
|
2088 |
|
2089 | if (typeof options.onSubmit === 'function') {
|
2090 | let onSubmit = options.onSubmit.bind(this);
|
2091 | let submit = this.submit.bind(this);
|
2092 | delete this.options.onSubmit;
|
2093 | this.submit = async() => {
|
2094 | await onSubmit(this.name, this.value, this);
|
2095 | return submit();
|
2096 | };
|
2097 | }
|
2098 |
|
2099 | await this.start();
|
2100 | await this.render();
|
2101 | }
|
2102 |
|
2103 | render() {
|
2104 | throw new Error('expected prompt to have a custom render method');
|
2105 | }
|
2106 |
|
2107 | run() {
|
2108 | return new Promise(async(resolve, reject) => {
|
2109 | this.once('submit', resolve);
|
2110 | this.once('cancel', reject);
|
2111 | if (await this.skip()) {
|
2112 | this.render = () => {};
|
2113 | return this.submit();
|
2114 | }
|
2115 | await this.initialize();
|
2116 | this.emit('run');
|
2117 | });
|
2118 | }
|
2119 |
|
2120 | async element(name, choice, i) {
|
2121 | let { options, state, symbols, timers } = this;
|
2122 | let timer = timers && timers[name];
|
2123 | state.timer = timer;
|
2124 | let value = options[name] || state[name] || symbols[name];
|
2125 | let val = choice && choice[name] != null ? choice[name] : await value;
|
2126 | if (val === '') return val;
|
2127 |
|
2128 | let res = await this.resolve(val, state, choice, i);
|
2129 | if (!res && choice && choice[name]) {
|
2130 | return this.resolve(value, state, choice, i);
|
2131 | }
|
2132 | return res;
|
2133 | }
|
2134 |
|
2135 | async prefix() {
|
2136 | let element = await this.element('prefix') || this.symbols;
|
2137 | let timer = this.timers && this.timers.prefix;
|
2138 | let state = this.state;
|
2139 | state.timer = timer;
|
2140 | if (utils.isObject(element)) element = element[state.status] || element.pending;
|
2141 | if (!utils.hasColor(element)) {
|
2142 | let style = this.styles[state.status] || this.styles.pending;
|
2143 | return style(element);
|
2144 | }
|
2145 | return element;
|
2146 | }
|
2147 |
|
2148 | async message() {
|
2149 | let message = await this.element('message');
|
2150 | if (!utils.hasColor(message)) {
|
2151 | return this.styles.strong(message);
|
2152 | }
|
2153 | return message;
|
2154 | }
|
2155 |
|
2156 | async separator() {
|
2157 | let element = await this.element('separator') || this.symbols;
|
2158 | let timer = this.timers && this.timers.separator;
|
2159 | let state = this.state;
|
2160 | state.timer = timer;
|
2161 | let value = element[state.status] || element.pending || state.separator;
|
2162 | let ele = await this.resolve(value, state);
|
2163 | if (utils.isObject(ele)) ele = ele[state.status] || ele.pending;
|
2164 | if (!utils.hasColor(ele)) {
|
2165 | return this.styles.muted(ele);
|
2166 | }
|
2167 | return ele;
|
2168 | }
|
2169 |
|
2170 | async pointer(choice, i) {
|
2171 | let val = await this.element('pointer', choice, i);
|
2172 |
|
2173 | if (typeof val === 'string' && utils.hasColor(val)) {
|
2174 | return val;
|
2175 | }
|
2176 |
|
2177 | if (val) {
|
2178 | let styles = this.styles;
|
2179 | let focused = this.index === i;
|
2180 | let style = focused ? styles.primary : val => val;
|
2181 | let ele = await this.resolve(val[focused ? 'on' : 'off'] || val, this.state);
|
2182 | let styled = !utils.hasColor(ele) ? style(ele) : ele;
|
2183 | return focused ? styled : ' '.repeat(ele.length);
|
2184 | }
|
2185 | }
|
2186 |
|
2187 | async indicator(choice, i) {
|
2188 | let val = await this.element('indicator', choice, i);
|
2189 | if (typeof val === 'string' && utils.hasColor(val)) {
|
2190 | return val;
|
2191 | }
|
2192 | if (val) {
|
2193 | let styles = this.styles;
|
2194 | let enabled = choice.enabled === true;
|
2195 | let style = enabled ? styles.success : styles.dark;
|
2196 | let ele = val[enabled ? 'on' : 'off'] || val;
|
2197 | return !utils.hasColor(ele) ? style(ele) : ele;
|
2198 | }
|
2199 | return '';
|
2200 | }
|
2201 |
|
2202 | body() {
|
2203 | return null;
|
2204 | }
|
2205 |
|
2206 | footer() {
|
2207 | if (this.state.status === 'pending') {
|
2208 | return this.element('footer');
|
2209 | }
|
2210 | }
|
2211 |
|
2212 | header() {
|
2213 | if (this.state.status === 'pending') {
|
2214 | return this.element('header');
|
2215 | }
|
2216 | }
|
2217 |
|
2218 | async hint() {
|
2219 | if (this.state.status === 'pending' && !this.isValue(this.state.input)) {
|
2220 | let hint = await this.element('hint');
|
2221 | if (!utils.hasColor(hint)) {
|
2222 | return this.styles.muted(hint);
|
2223 | }
|
2224 | return hint;
|
2225 | }
|
2226 | }
|
2227 |
|
2228 | error(err) {
|
2229 | return !this.state.submitted ? (err || this.state.error) : '';
|
2230 | }
|
2231 |
|
2232 | format(value) {
|
2233 | return value;
|
2234 | }
|
2235 |
|
2236 | result(value) {
|
2237 | return value;
|
2238 | }
|
2239 |
|
2240 | validate(value) {
|
2241 | if (this.options.required === true) {
|
2242 | return this.isValue(value);
|
2243 | }
|
2244 | return true;
|
2245 | }
|
2246 |
|
2247 | isValue(value) {
|
2248 | return value != null && value !== '';
|
2249 | }
|
2250 |
|
2251 | resolve(value, ...args) {
|
2252 | return utils.resolve(this, value, ...args);
|
2253 | }
|
2254 |
|
2255 | get base() {
|
2256 | return Prompt.prototype;
|
2257 | }
|
2258 |
|
2259 | get style() {
|
2260 | return this.styles[this.state.status];
|
2261 | }
|
2262 |
|
2263 | get height() {
|
2264 | return this.options.rows || utils.height(this.stdout, 25);
|
2265 | }
|
2266 | get width() {
|
2267 | return this.options.columns || utils.width(this.stdout, 80);
|
2268 | }
|
2269 | get size() {
|
2270 | return { width: this.width, height: this.height };
|
2271 | }
|
2272 |
|
2273 | set cursor(value) {
|
2274 | this.state.cursor = value;
|
2275 | }
|
2276 | get cursor() {
|
2277 | return this.state.cursor;
|
2278 | }
|
2279 |
|
2280 | set input(value) {
|
2281 | this.state.input = value;
|
2282 | }
|
2283 | get input() {
|
2284 | return this.state.input;
|
2285 | }
|
2286 |
|
2287 | set value(value) {
|
2288 | this.state.value = value;
|
2289 | }
|
2290 | get value() {
|
2291 | let { input, value } = this.state;
|
2292 | let result = [value, input].find(this.isValue.bind(this));
|
2293 | return this.isValue(result) ? result : this.initial;
|
2294 | }
|
2295 |
|
2296 | static get prompt() {
|
2297 | return options => new this(options).run();
|
2298 | }
|
2299 | }
|
2300 |
|
2301 | function setOptions(prompt) {
|
2302 | let isValidKey = key => {
|
2303 | return prompt[key] === void 0 || typeof prompt[key] === 'function';
|
2304 | };
|
2305 |
|
2306 | let ignore = [
|
2307 | 'actions',
|
2308 | 'choices',
|
2309 | 'initial',
|
2310 | 'margin',
|
2311 | 'roles',
|
2312 | 'styles',
|
2313 | 'symbols',
|
2314 | 'theme',
|
2315 | 'timers',
|
2316 | 'value'
|
2317 | ];
|
2318 |
|
2319 | let ignoreFn = [
|
2320 | 'body',
|
2321 | 'footer',
|
2322 | 'error',
|
2323 | 'header',
|
2324 | 'hint',
|
2325 | 'indicator',
|
2326 | 'message',
|
2327 | 'prefix',
|
2328 | 'separator',
|
2329 | 'skip'
|
2330 | ];
|
2331 |
|
2332 | for (let key of Object.keys(prompt.options)) {
|
2333 | if (ignore.includes(key)) continue;
|
2334 | if (/^on[A-Z]/.test(key)) continue;
|
2335 | let option = prompt.options[key];
|
2336 | if (typeof option === 'function' && isValidKey(key)) {
|
2337 | if (!ignoreFn.includes(key)) {
|
2338 | prompt[key] = option.bind(prompt);
|
2339 | }
|
2340 | } else if (typeof prompt[key] !== 'function') {
|
2341 | prompt[key] = option;
|
2342 | }
|
2343 | }
|
2344 | }
|
2345 |
|
2346 | function margin(value) {
|
2347 | if (typeof value === 'number') {
|
2348 | value = [value, value, value, value];
|
2349 | }
|
2350 | let arr = [].concat(value || []);
|
2351 | let pad = i => i % 2 === 0 ? '\n' : ' ';
|
2352 | let res = [];
|
2353 | for (let i = 0; i < 4; i++) {
|
2354 | let char = pad(i);
|
2355 | if (arr[i]) {
|
2356 | res.push(char.repeat(arr[i]));
|
2357 | } else {
|
2358 | res.push('');
|
2359 | }
|
2360 | }
|
2361 | return res;
|
2362 | }
|
2363 |
|
2364 | var prompt = Prompt;
|
2365 |
|
2366 | const roles = {
|
2367 | default(prompt, choice) {
|
2368 | return choice;
|
2369 | },
|
2370 | checkbox(prompt, choice) {
|
2371 | throw new Error('checkbox role is not implemented yet');
|
2372 | },
|
2373 | editable(prompt, choice) {
|
2374 | throw new Error('editable role is not implemented yet');
|
2375 | },
|
2376 | expandable(prompt, choice) {
|
2377 | throw new Error('expandable role is not implemented yet');
|
2378 | },
|
2379 | heading(prompt, choice) {
|
2380 | choice.disabled = '';
|
2381 | choice.indicator = [choice.indicator, ' '].find(v => v != null);
|
2382 | choice.message = choice.message || '';
|
2383 | return choice;
|
2384 | },
|
2385 | input(prompt, choice) {
|
2386 | throw new Error('input role is not implemented yet');
|
2387 | },
|
2388 | option(prompt, choice) {
|
2389 | return roles.default(prompt, choice);
|
2390 | },
|
2391 | radio(prompt, choice) {
|
2392 | throw new Error('radio role is not implemented yet');
|
2393 | },
|
2394 | separator(prompt, choice) {
|
2395 | choice.disabled = '';
|
2396 | choice.indicator = [choice.indicator, ' '].find(v => v != null);
|
2397 | choice.message = choice.message || prompt.symbols.line.repeat(5);
|
2398 | return choice;
|
2399 | },
|
2400 | spacer(prompt, choice) {
|
2401 | return choice;
|
2402 | }
|
2403 | };
|
2404 |
|
2405 | var roles_1 = (name, options = {}) => {
|
2406 | let role = utils.merge({}, roles, options.roles);
|
2407 | return role[name] || role.default;
|
2408 | };
|
2409 |
|
2410 | const { reorder, scrollUp, scrollDown, isObject, swap } = utils;
|
2411 |
|
2412 | class ArrayPrompt extends prompt {
|
2413 | constructor(options) {
|
2414 | super(options);
|
2415 | this.cursorHide();
|
2416 | this.maxSelected = options.maxSelected || Infinity;
|
2417 | this.multiple = options.multiple || false;
|
2418 | this.initial = options.initial || 0;
|
2419 | this.delay = options.delay || 0;
|
2420 | this.longest = 0;
|
2421 | this.num = '';
|
2422 | }
|
2423 |
|
2424 | async initialize() {
|
2425 | if (typeof this.options.initial === 'function') {
|
2426 | this.initial = await this.options.initial.call(this);
|
2427 | }
|
2428 | await this.reset(true);
|
2429 | await super.initialize();
|
2430 | }
|
2431 |
|
2432 | async reset() {
|
2433 | let { choices, initial, autofocus, suggest } = this.options;
|
2434 | this.state._choices = [];
|
2435 | this.state.choices = [];
|
2436 |
|
2437 | this.choices = await Promise.all(await this.toChoices(choices));
|
2438 | this.choices.forEach(ch => (ch.enabled = false));
|
2439 |
|
2440 | if (typeof suggest !== 'function' && this.selectable.length === 0) {
|
2441 | throw new Error('At least one choice must be selectable');
|
2442 | }
|
2443 |
|
2444 | if (isObject(initial)) initial = Object.keys(initial);
|
2445 | if (Array.isArray(initial)) {
|
2446 | if (autofocus != null) this.index = this.findIndex(autofocus);
|
2447 | initial.forEach(v => this.enable(this.find(v)));
|
2448 | await this.render();
|
2449 | } else {
|
2450 | if (autofocus != null) initial = autofocus;
|
2451 | if (typeof initial === 'string') initial = this.findIndex(initial);
|
2452 | if (typeof initial === 'number' && initial > -1) {
|
2453 | this.index = Math.max(0, Math.min(initial, this.choices.length));
|
2454 | this.enable(this.find(this.index));
|
2455 | }
|
2456 | }
|
2457 |
|
2458 | if (this.isDisabled(this.focused)) {
|
2459 | await this.down();
|
2460 | }
|
2461 | }
|
2462 |
|
2463 | async toChoices(value, parent) {
|
2464 | this.state.loadingChoices = true;
|
2465 | let choices = [];
|
2466 | let index = 0;
|
2467 |
|
2468 | let toChoices = async(items, parent) => {
|
2469 | if (typeof items === 'function') items = await items.call(this);
|
2470 | if (items instanceof Promise) items = await items;
|
2471 |
|
2472 | for (let i = 0; i < items.length; i++) {
|
2473 | let choice = items[i] = await this.toChoice(items[i], index++, parent);
|
2474 | choices.push(choice);
|
2475 |
|
2476 | if (choice.choices) {
|
2477 | await toChoices(choice.choices, choice);
|
2478 | }
|
2479 | }
|
2480 | return choices;
|
2481 | };
|
2482 |
|
2483 | return toChoices(value, parent)
|
2484 | .then(choices => {
|
2485 | this.state.loadingChoices = false;
|
2486 | return choices;
|
2487 | });
|
2488 | }
|
2489 |
|
2490 | async toChoice(ele, i, parent) {
|
2491 | if (typeof ele === 'function') ele = await ele.call(this, this);
|
2492 | if (ele instanceof Promise) ele = await ele;
|
2493 | if (typeof ele === 'string') ele = { name: ele };
|
2494 |
|
2495 | if (ele.normalized) return ele;
|
2496 | ele.normalized = true;
|
2497 |
|
2498 | let origVal = ele.value;
|
2499 | let role = roles_1(ele.role, this.options);
|
2500 | ele = role(this, ele);
|
2501 |
|
2502 | if (typeof ele.disabled === 'string' && !ele.hint) {
|
2503 | ele.hint = ele.disabled;
|
2504 | ele.disabled = true;
|
2505 | }
|
2506 |
|
2507 | if (ele.disabled === true && ele.hint == null) {
|
2508 | ele.hint = '(disabled)';
|
2509 | }
|
2510 |
|
2511 |
|
2512 | if (ele.index != null) return ele;
|
2513 | ele.name = ele.name || ele.key || ele.title || ele.value || ele.message;
|
2514 | ele.message = ele.message || ele.name || '';
|
2515 | ele.value = [ele.value, ele.name].find(this.isValue.bind(this));
|
2516 |
|
2517 | ele.input = '';
|
2518 | ele.index = i;
|
2519 | ele.cursor = 0;
|
2520 |
|
2521 | utils.define(ele, 'parent', parent);
|
2522 | ele.level = parent ? parent.level + 1 : 1;
|
2523 | if (ele.indent == null) {
|
2524 | ele.indent = parent ? parent.indent + ' ' : (ele.indent || '');
|
2525 | }
|
2526 |
|
2527 | ele.path = parent ? parent.path + '.' + ele.name : ele.name;
|
2528 | ele.enabled = !!(this.multiple && !this.isDisabled(ele) && (ele.enabled || this.isSelected(ele)));
|
2529 |
|
2530 | if (!this.isDisabled(ele)) {
|
2531 | this.longest = Math.max(this.longest, ansiColors.unstyle(ele.message).length);
|
2532 | }
|
2533 |
|
2534 |
|
2535 | let choice = { ...ele };
|
2536 |
|
2537 |
|
2538 | ele.reset = (input = choice.input, value = choice.value) => {
|
2539 | for (let key of Object.keys(choice)) ele[key] = choice[key];
|
2540 | ele.input = input;
|
2541 | ele.value = value;
|
2542 | };
|
2543 |
|
2544 | if (origVal == null && typeof ele.initial === 'function') {
|
2545 | ele.input = await ele.initial.call(this, this.state, ele, i);
|
2546 | }
|
2547 |
|
2548 | return ele;
|
2549 | }
|
2550 |
|
2551 | async onChoice(choice, i) {
|
2552 | this.emit('choice', choice, i, this);
|
2553 |
|
2554 | if (typeof choice.onChoice === 'function') {
|
2555 | await choice.onChoice.call(this, this.state, choice, i);
|
2556 | }
|
2557 | }
|
2558 |
|
2559 | async addChoice(ele, i, parent) {
|
2560 | let choice = await this.toChoice(ele, i, parent);
|
2561 | this.choices.push(choice);
|
2562 | this.index = this.choices.length - 1;
|
2563 | this.limit = this.choices.length;
|
2564 | return choice;
|
2565 | }
|
2566 |
|
2567 | async newItem(item, i, parent) {
|
2568 | let ele = { name: 'New choice name?', editable: true, newChoice: true, ...item };
|
2569 | let choice = await this.addChoice(ele, i, parent);
|
2570 |
|
2571 | choice.updateChoice = () => {
|
2572 | delete choice.newChoice;
|
2573 | choice.name = choice.message = choice.input;
|
2574 | choice.input = '';
|
2575 | choice.cursor = 0;
|
2576 | };
|
2577 |
|
2578 | return this.render();
|
2579 | }
|
2580 |
|
2581 | indent(choice) {
|
2582 | if (choice.indent == null) {
|
2583 | return choice.level > 1 ? ' '.repeat(choice.level - 1) : '';
|
2584 | }
|
2585 | return choice.indent;
|
2586 | }
|
2587 |
|
2588 | dispatch(s, key) {
|
2589 | if (this.multiple && this[key.name]) return this[key.name]();
|
2590 | this.alert();
|
2591 | }
|
2592 |
|
2593 | focus(choice, enabled) {
|
2594 | if (typeof enabled !== 'boolean') enabled = choice.enabled;
|
2595 | if (enabled && !choice.enabled && this.selected.length >= this.maxSelected) {
|
2596 | return this.alert();
|
2597 | }
|
2598 | this.index = choice.index;
|
2599 | choice.enabled = enabled && !this.isDisabled(choice);
|
2600 | return choice;
|
2601 | }
|
2602 |
|
2603 | space() {
|
2604 | if (!this.multiple) return this.alert();
|
2605 | this.toggle(this.focused);
|
2606 | return this.render();
|
2607 | }
|
2608 |
|
2609 | a() {
|
2610 | if (this.maxSelected < this.choices.length) return this.alert();
|
2611 | let enabled = this.selectable.every(ch => ch.enabled);
|
2612 | this.choices.forEach(ch => (ch.enabled = !enabled));
|
2613 | return this.render();
|
2614 | }
|
2615 |
|
2616 | i() {
|
2617 |
|
2618 |
|
2619 | if (this.choices.length - this.selected.length > this.maxSelected) {
|
2620 | return this.alert();
|
2621 | }
|
2622 | this.choices.forEach(ch => (ch.enabled = !ch.enabled));
|
2623 | return this.render();
|
2624 | }
|
2625 |
|
2626 | g(choice = this.focused) {
|
2627 | if (!this.choices.some(ch => !!ch.parent)) return this.a();
|
2628 | this.toggle((choice.parent && !choice.choices) ? choice.parent : choice);
|
2629 | return this.render();
|
2630 | }
|
2631 |
|
2632 | toggle(choice, enabled) {
|
2633 | if (!choice.enabled && this.selected.length >= this.maxSelected) {
|
2634 | return this.alert();
|
2635 | }
|
2636 |
|
2637 | if (typeof enabled !== 'boolean') enabled = !choice.enabled;
|
2638 | choice.enabled = enabled;
|
2639 |
|
2640 | if (choice.choices) {
|
2641 | choice.choices.forEach(ch => this.toggle(ch, enabled));
|
2642 | }
|
2643 |
|
2644 | let parent = choice.parent;
|
2645 | while (parent) {
|
2646 | let choices = parent.choices.filter(ch => this.isDisabled(ch));
|
2647 | parent.enabled = choices.every(ch => ch.enabled === true);
|
2648 | parent = parent.parent;
|
2649 | }
|
2650 |
|
2651 | reset(this, this.choices);
|
2652 | this.emit('toggle', choice, this);
|
2653 | return choice;
|
2654 | }
|
2655 |
|
2656 | enable(choice) {
|
2657 | if (this.selected.length >= this.maxSelected) return this.alert();
|
2658 | choice.enabled = !this.isDisabled(choice);
|
2659 | choice.choices && choice.choices.forEach(this.enable.bind(this));
|
2660 | return choice;
|
2661 | }
|
2662 |
|
2663 | disable(choice) {
|
2664 | choice.enabled = false;
|
2665 | choice.choices && choice.choices.forEach(this.disable.bind(this));
|
2666 | return choice;
|
2667 | }
|
2668 |
|
2669 | number(n) {
|
2670 | this.num += n;
|
2671 |
|
2672 | let number = num => {
|
2673 | let i = Number(num);
|
2674 | if (i > this.choices.length - 1) return this.alert();
|
2675 |
|
2676 | let focused = this.focused;
|
2677 | let choice = this.choices.find(ch => i === ch.index);
|
2678 |
|
2679 | if (!choice.enabled && this.selected.length >= this.maxSelected) {
|
2680 | return this.alert();
|
2681 | }
|
2682 |
|
2683 | if (this.visible.indexOf(choice) === -1) {
|
2684 | let choices = reorder(this.choices);
|
2685 | let actualIdx = choices.indexOf(choice);
|
2686 |
|
2687 | if (focused.index > actualIdx) {
|
2688 | let start = choices.slice(actualIdx, actualIdx + this.limit);
|
2689 | let end = choices.filter(ch => !start.includes(ch));
|
2690 | this.choices = start.concat(end);
|
2691 | } else {
|
2692 | let pos = actualIdx - this.limit + 1;
|
2693 | this.choices = choices.slice(pos).concat(choices.slice(0, pos));
|
2694 | }
|
2695 | }
|
2696 |
|
2697 | this.index = this.choices.indexOf(choice);
|
2698 | this.toggle(this.focused);
|
2699 | return this.render();
|
2700 | };
|
2701 |
|
2702 | clearTimeout(this.numberTimeout);
|
2703 |
|
2704 | return new Promise(resolve => {
|
2705 | let len = this.choices.length;
|
2706 | let num = this.num;
|
2707 |
|
2708 | let handle = (val = false, res) => {
|
2709 | clearTimeout(this.numberTimeout);
|
2710 | if (val) res = number(num);
|
2711 | this.num = '';
|
2712 | resolve(res);
|
2713 | };
|
2714 |
|
2715 | if (num === '0' || (num.length === 1 && Number(num + '0') > len)) {
|
2716 | return handle(true);
|
2717 | }
|
2718 |
|
2719 | if (Number(num) > len) {
|
2720 | return handle(false, this.alert());
|
2721 | }
|
2722 |
|
2723 | this.numberTimeout = setTimeout(() => handle(true), this.delay);
|
2724 | });
|
2725 | }
|
2726 |
|
2727 | home() {
|
2728 | this.choices = reorder(this.choices);
|
2729 | this.index = 0;
|
2730 | return this.render();
|
2731 | }
|
2732 |
|
2733 | end() {
|
2734 | let pos = this.choices.length - this.limit;
|
2735 | let choices = reorder(this.choices);
|
2736 | this.choices = choices.slice(pos).concat(choices.slice(0, pos));
|
2737 | this.index = this.limit - 1;
|
2738 | return this.render();
|
2739 | }
|
2740 |
|
2741 | first() {
|
2742 | this.index = 0;
|
2743 | return this.render();
|
2744 | }
|
2745 |
|
2746 | last() {
|
2747 | this.index = this.visible.length - 1;
|
2748 | return this.render();
|
2749 | }
|
2750 |
|
2751 | prev() {
|
2752 | if (this.visible.length <= 1) return this.alert();
|
2753 | return this.up();
|
2754 | }
|
2755 |
|
2756 | next() {
|
2757 | if (this.visible.length <= 1) return this.alert();
|
2758 | return this.down();
|
2759 | }
|
2760 |
|
2761 | right() {
|
2762 | if (this.cursor >= this.input.length) return this.alert();
|
2763 | this.cursor++;
|
2764 | return this.render();
|
2765 | }
|
2766 |
|
2767 | left() {
|
2768 | if (this.cursor <= 0) return this.alert();
|
2769 | this.cursor--;
|
2770 | return this.render();
|
2771 | }
|
2772 |
|
2773 | up() {
|
2774 | let len = this.choices.length;
|
2775 | let vis = this.visible.length;
|
2776 | let idx = this.index;
|
2777 | if (this.options.scroll === false && idx === 0) {
|
2778 | return this.alert();
|
2779 | }
|
2780 | if (len > vis && idx === 0) {
|
2781 | return this.scrollUp();
|
2782 | }
|
2783 | this.index = ((idx - 1 % len) + len) % len;
|
2784 | if (this.isDisabled()) {
|
2785 | return this.up();
|
2786 | }
|
2787 | return this.render();
|
2788 | }
|
2789 |
|
2790 | down() {
|
2791 | let len = this.choices.length;
|
2792 | let vis = this.visible.length;
|
2793 | let idx = this.index;
|
2794 | if (this.options.scroll === false && idx === vis - 1) {
|
2795 | return this.alert();
|
2796 | }
|
2797 | if (len > vis && idx === vis - 1) {
|
2798 | return this.scrollDown();
|
2799 | }
|
2800 | this.index = (idx + 1) % len;
|
2801 | if (this.isDisabled()) {
|
2802 | return this.down();
|
2803 | }
|
2804 | return this.render();
|
2805 | }
|
2806 |
|
2807 | scrollUp(i = 0) {
|
2808 | this.choices = scrollUp(this.choices);
|
2809 | this.index = i;
|
2810 | if (this.isDisabled()) {
|
2811 | return this.up();
|
2812 | }
|
2813 | return this.render();
|
2814 | }
|
2815 |
|
2816 | scrollDown(i = this.visible.length - 1) {
|
2817 | this.choices = scrollDown(this.choices);
|
2818 | this.index = i;
|
2819 | if (this.isDisabled()) {
|
2820 | return this.down();
|
2821 | }
|
2822 | return this.render();
|
2823 | }
|
2824 |
|
2825 | async shiftUp() {
|
2826 | if (this.options.sort === true) {
|
2827 | this.sorting = true;
|
2828 | this.swap(this.index - 1);
|
2829 | await this.up();
|
2830 | this.sorting = false;
|
2831 | return;
|
2832 | }
|
2833 | return this.scrollUp(this.index);
|
2834 | }
|
2835 |
|
2836 | async shiftDown() {
|
2837 | if (this.options.sort === true) {
|
2838 | this.sorting = true;
|
2839 | this.swap(this.index + 1);
|
2840 | await this.down();
|
2841 | this.sorting = false;
|
2842 | return;
|
2843 | }
|
2844 | return this.scrollDown(this.index);
|
2845 | }
|
2846 |
|
2847 | pageUp() {
|
2848 | if (this.visible.length <= 1) return this.alert();
|
2849 | this.limit = Math.max(this.limit - 1, 0);
|
2850 | this.index = Math.min(this.limit - 1, this.index);
|
2851 | this._limit = this.limit;
|
2852 | if (this.isDisabled()) {
|
2853 | return this.up();
|
2854 | }
|
2855 | return this.render();
|
2856 | }
|
2857 |
|
2858 | pageDown() {
|
2859 | if (this.visible.length >= this.choices.length) return this.alert();
|
2860 | this.index = Math.max(0, this.index);
|
2861 | this.limit = Math.min(this.limit + 1, this.choices.length);
|
2862 | this._limit = this.limit;
|
2863 | if (this.isDisabled()) {
|
2864 | return this.down();
|
2865 | }
|
2866 | return this.render();
|
2867 | }
|
2868 |
|
2869 | swap(pos) {
|
2870 | swap(this.choices, this.index, pos);
|
2871 | }
|
2872 |
|
2873 | isDisabled(choice = this.focused) {
|
2874 | let keys = ['disabled', 'collapsed', 'hidden', 'completing', 'readonly'];
|
2875 | if (choice && keys.some(key => choice[key] === true)) {
|
2876 | return true;
|
2877 | }
|
2878 | return choice && choice.role === 'heading';
|
2879 | }
|
2880 |
|
2881 | isEnabled(choice = this.focused) {
|
2882 | if (Array.isArray(choice)) return choice.every(ch => this.isEnabled(ch));
|
2883 | if (choice.choices) {
|
2884 | let choices = choice.choices.filter(ch => !this.isDisabled(ch));
|
2885 | return choice.enabled && choices.every(ch => this.isEnabled(ch));
|
2886 | }
|
2887 | return choice.enabled && !this.isDisabled(choice);
|
2888 | }
|
2889 |
|
2890 | isChoice(choice, value) {
|
2891 | return choice.name === value || choice.index === Number(value);
|
2892 | }
|
2893 |
|
2894 | isSelected(choice) {
|
2895 | if (Array.isArray(this.initial)) {
|
2896 | return this.initial.some(value => this.isChoice(choice, value));
|
2897 | }
|
2898 | return this.isChoice(choice, this.initial);
|
2899 | }
|
2900 |
|
2901 | map(names = [], prop = 'value') {
|
2902 | return [].concat(names || []).reduce((acc, name) => {
|
2903 | acc[name] = this.find(name, prop);
|
2904 | return acc;
|
2905 | }, {});
|
2906 | }
|
2907 |
|
2908 | filter(value, prop) {
|
2909 | let isChoice = (ele, i) => [ele.name, i].includes(value);
|
2910 | let fn = typeof value === 'function' ? value : isChoice;
|
2911 | let choices = this.options.multiple ? this.state._choices : this.choices;
|
2912 | let result = choices.filter(fn);
|
2913 | if (prop) {
|
2914 | return result.map(ch => ch[prop]);
|
2915 | }
|
2916 | return result;
|
2917 | }
|
2918 |
|
2919 | find(value, prop) {
|
2920 | if (isObject(value)) return prop ? value[prop] : value;
|
2921 | let isChoice = (ele, i) => [ele.name, i].includes(value);
|
2922 | let fn = typeof value === 'function' ? value : isChoice;
|
2923 | let choice = this.choices.find(fn);
|
2924 | if (choice) {
|
2925 | return prop ? choice[prop] : choice;
|
2926 | }
|
2927 | }
|
2928 |
|
2929 | findIndex(value) {
|
2930 | return this.choices.indexOf(this.find(value));
|
2931 | }
|
2932 |
|
2933 | async submit() {
|
2934 | let choice = this.focused;
|
2935 | if (!choice) return this.alert();
|
2936 |
|
2937 | if (choice.newChoice) {
|
2938 | if (!choice.input) return this.alert();
|
2939 | choice.updateChoice();
|
2940 | return this.render();
|
2941 | }
|
2942 |
|
2943 | if (this.choices.some(ch => ch.newChoice)) {
|
2944 | return this.alert();
|
2945 | }
|
2946 |
|
2947 | let { reorder, sort } = this.options;
|
2948 | let multi = this.multiple === true;
|
2949 | let value = this.selected;
|
2950 | if (value === void 0) {
|
2951 | return this.alert();
|
2952 | }
|
2953 |
|
2954 |
|
2955 | if (Array.isArray(value) && reorder !== false && sort !== true) {
|
2956 | value = utils.reorder(value);
|
2957 | }
|
2958 |
|
2959 | this.value = multi ? value.map(ch => ch.name) : value.name;
|
2960 | return super.submit();
|
2961 | }
|
2962 |
|
2963 | set choices(choices = []) {
|
2964 | this.state._choices = this.state._choices || [];
|
2965 | this.state.choices = choices;
|
2966 |
|
2967 | for (let choice of choices) {
|
2968 | if (!this.state._choices.some(ch => ch.name === choice.name)) {
|
2969 | this.state._choices.push(choice);
|
2970 | }
|
2971 | }
|
2972 |
|
2973 | if (!this._initial && this.options.initial) {
|
2974 | this._initial = true;
|
2975 | let init = this.initial;
|
2976 | if (typeof init === 'string' || typeof init === 'number') {
|
2977 | let choice = this.find(init);
|
2978 | if (choice) {
|
2979 | this.initial = choice.index;
|
2980 | this.focus(choice, true);
|
2981 | }
|
2982 | }
|
2983 | }
|
2984 | }
|
2985 | get choices() {
|
2986 | return reset(this, this.state.choices || []);
|
2987 | }
|
2988 |
|
2989 | set visible(visible) {
|
2990 | this.state.visible = visible;
|
2991 | }
|
2992 | get visible() {
|
2993 | return (this.state.visible || this.choices).slice(0, this.limit);
|
2994 | }
|
2995 |
|
2996 | set limit(num) {
|
2997 | this.state.limit = num;
|
2998 | }
|
2999 | get limit() {
|
3000 | let { state, options, choices } = this;
|
3001 | let limit = state.limit || this._limit || options.limit || choices.length;
|
3002 | return Math.min(limit, this.height);
|
3003 | }
|
3004 |
|
3005 | set value(value) {
|
3006 | super.value = value;
|
3007 | }
|
3008 | get value() {
|
3009 | if (typeof super.value !== 'string' && super.value === this.initial) {
|
3010 | return this.input;
|
3011 | }
|
3012 | return super.value;
|
3013 | }
|
3014 |
|
3015 | set index(i) {
|
3016 | this.state.index = i;
|
3017 | }
|
3018 | get index() {
|
3019 | return Math.max(0, this.state ? this.state.index : 0);
|
3020 | }
|
3021 |
|
3022 | get enabled() {
|
3023 | return this.filter(this.isEnabled.bind(this));
|
3024 | }
|
3025 |
|
3026 | get focused() {
|
3027 | let choice = this.choices[this.index];
|
3028 | if (choice && this.state.submitted && this.multiple !== true) {
|
3029 | choice.enabled = true;
|
3030 | }
|
3031 | return choice;
|
3032 | }
|
3033 |
|
3034 | get selectable() {
|
3035 | return this.choices.filter(choice => !this.isDisabled(choice));
|
3036 | }
|
3037 |
|
3038 | get selected() {
|
3039 | return this.multiple ? this.enabled : this.focused;
|
3040 | }
|
3041 | }
|
3042 |
|
3043 | function reset(prompt, choices) {
|
3044 | if (choices instanceof Promise) return choices;
|
3045 | if (typeof choices === 'function') {
|
3046 | if (utils.isAsyncFn(choices)) return choices;
|
3047 | choices = choices.call(prompt, prompt);
|
3048 | }
|
3049 | for (let choice of choices) {
|
3050 | if (Array.isArray(choice.choices)) {
|
3051 | let items = choice.choices.filter(ch => !prompt.isDisabled(ch));
|
3052 | choice.enabled = items.every(ch => ch.enabled === true);
|
3053 | }
|
3054 | if (prompt.isDisabled(choice) === true) {
|
3055 | delete choice.enabled;
|
3056 | }
|
3057 | }
|
3058 | return choices;
|
3059 | }
|
3060 |
|
3061 | var array = ArrayPrompt;
|
3062 |
|
3063 | class SelectPrompt extends array {
|
3064 | constructor(options) {
|
3065 | super(options);
|
3066 | this.emptyError = this.options.emptyError || 'No items were selected';
|
3067 | }
|
3068 |
|
3069 | async dispatch(s, key) {
|
3070 | if (this.multiple) {
|
3071 | return this[key.name] ? await this[key.name](s, key) : await super.dispatch(s, key);
|
3072 | }
|
3073 | this.alert();
|
3074 | }
|
3075 |
|
3076 | separator() {
|
3077 | if (this.options.separator) return super.separator();
|
3078 | let sep = this.styles.muted(this.symbols.ellipsis);
|
3079 | return this.state.submitted ? super.separator() : sep;
|
3080 | }
|
3081 |
|
3082 | pointer(choice, i) {
|
3083 | return (!this.multiple || this.options.pointer) ? super.pointer(choice, i) : '';
|
3084 | }
|
3085 |
|
3086 | indicator(choice, i) {
|
3087 | return this.multiple ? super.indicator(choice, i) : '';
|
3088 | }
|
3089 |
|
3090 | choiceMessage(choice, i) {
|
3091 | let message = this.resolve(choice.message, this.state, choice, i);
|
3092 | if (choice.role === 'heading' && !utils.hasColor(message)) {
|
3093 | message = this.styles.strong(message);
|
3094 | }
|
3095 | return this.resolve(message, this.state, choice, i);
|
3096 | }
|
3097 |
|
3098 | choiceSeparator() {
|
3099 | return ':';
|
3100 | }
|
3101 |
|
3102 | async renderChoice(choice, i) {
|
3103 | await this.onChoice(choice, i);
|
3104 |
|
3105 | let focused = this.index === i;
|
3106 | let pointer = await this.pointer(choice, i);
|
3107 | let check = await this.indicator(choice, i) + (choice.pad || '');
|
3108 | let hint = await this.resolve(choice.hint, this.state, choice, i);
|
3109 |
|
3110 | if (hint && !utils.hasColor(hint)) {
|
3111 | hint = this.styles.muted(hint);
|
3112 | }
|
3113 |
|
3114 | let ind = this.indent(choice);
|
3115 | let msg = await this.choiceMessage(choice, i);
|
3116 | let line = () => [this.margin[3], ind + pointer + check, msg, this.margin[1], hint].filter(Boolean).join(' ');
|
3117 |
|
3118 | if (choice.role === 'heading') {
|
3119 | return line();
|
3120 | }
|
3121 |
|
3122 | if (choice.disabled) {
|
3123 | if (!utils.hasColor(msg)) {
|
3124 | msg = this.styles.disabled(msg);
|
3125 | }
|
3126 | return line();
|
3127 | }
|
3128 |
|
3129 | if (focused) {
|
3130 | msg = this.styles.em(msg);
|
3131 | }
|
3132 |
|
3133 | return line();
|
3134 | }
|
3135 |
|
3136 | async renderChoices() {
|
3137 | if (this.state.loading === 'choices') {
|
3138 | return this.styles.warning('Loading choices');
|
3139 | }
|
3140 |
|
3141 | if (this.state.submitted) return '';
|
3142 | let choices = this.visible.map(async(ch, i) => await this.renderChoice(ch, i));
|
3143 | let visible = await Promise.all(choices);
|
3144 | if (!visible.length) visible.push(this.styles.danger('No matching choices'));
|
3145 | let result = this.margin[0] + visible.join('\n');
|
3146 | let header;
|
3147 |
|
3148 | if (this.options.choicesHeader) {
|
3149 | header = await this.resolve(this.options.choicesHeader, this.state);
|
3150 | }
|
3151 |
|
3152 | return [header, result].filter(Boolean).join('\n');
|
3153 | }
|
3154 |
|
3155 | format() {
|
3156 | if (!this.state.submitted || this.state.cancelled) return '';
|
3157 | if (Array.isArray(this.selected)) {
|
3158 | return this.selected.map(choice => this.styles.primary(choice.name)).join(', ');
|
3159 | }
|
3160 | return this.styles.primary(this.selected.name);
|
3161 | }
|
3162 |
|
3163 | async render() {
|
3164 | let { submitted, size } = this.state;
|
3165 |
|
3166 | let prompt = '';
|
3167 | let header = await this.header();
|
3168 | let prefix = await this.prefix();
|
3169 | let separator = await this.separator();
|
3170 | let message = await this.message();
|
3171 |
|
3172 | if (this.options.promptLine !== false) {
|
3173 | prompt = [prefix, message, separator, ''].join(' ');
|
3174 | this.state.prompt = prompt;
|
3175 | }
|
3176 |
|
3177 | let output = await this.format();
|
3178 | let help = (await this.error()) || (await this.hint());
|
3179 | let body = await this.renderChoices();
|
3180 | let footer = await this.footer();
|
3181 |
|
3182 | if (output) prompt += output;
|
3183 | if (help && !prompt.includes(help)) prompt += ' ' + help;
|
3184 |
|
3185 | if (submitted && !output && !body.trim() && this.multiple && this.emptyError != null) {
|
3186 | prompt += this.styles.danger(this.emptyError);
|
3187 | }
|
3188 |
|
3189 | this.clear(size);
|
3190 | this.write([header, prompt, body, footer].filter(Boolean).join('\n'));
|
3191 | this.write(this.margin[2]);
|
3192 | this.restore();
|
3193 | }
|
3194 | }
|
3195 |
|
3196 | var select = SelectPrompt;
|
3197 |
|
3198 | const highlight = (input, color) => {
|
3199 | let val = input.toLowerCase();
|
3200 | return str => {
|
3201 | let s = str.toLowerCase();
|
3202 | let i = s.indexOf(val);
|
3203 | let colored = color(str.slice(i, i + val.length));
|
3204 | return i >= 0 ? str.slice(0, i) + colored + str.slice(i + val.length) : str;
|
3205 | };
|
3206 | };
|
3207 |
|
3208 | class AutoComplete extends select {
|
3209 | constructor(options) {
|
3210 | super(options);
|
3211 | this.cursorShow();
|
3212 | }
|
3213 |
|
3214 | moveCursor(n) {
|
3215 | this.state.cursor += n;
|
3216 | }
|
3217 |
|
3218 | dispatch(ch) {
|
3219 | return this.append(ch);
|
3220 | }
|
3221 |
|
3222 | space(ch) {
|
3223 | return this.options.multiple ? super.space(ch) : this.append(ch);
|
3224 | }
|
3225 |
|
3226 | append(ch) {
|
3227 | let { cursor, input } = this.state;
|
3228 | this.input = input.slice(0, cursor) + ch + input.slice(cursor);
|
3229 | this.moveCursor(1);
|
3230 | return this.complete();
|
3231 | }
|
3232 |
|
3233 | delete() {
|
3234 | let { cursor, input } = this.state;
|
3235 | if (!input) return this.alert();
|
3236 | this.input = input.slice(0, cursor - 1) + input.slice(cursor);
|
3237 | this.moveCursor(-1);
|
3238 | return this.complete();
|
3239 | }
|
3240 |
|
3241 | deleteForward() {
|
3242 | let { cursor, input } = this.state;
|
3243 | if (input[cursor] === void 0) return this.alert();
|
3244 | this.input = `${input}`.slice(0, cursor) + `${input}`.slice(cursor + 1);
|
3245 | return this.complete();
|
3246 | }
|
3247 |
|
3248 | number(ch) {
|
3249 | return this.append(ch);
|
3250 | }
|
3251 |
|
3252 | async complete() {
|
3253 | this.completing = true;
|
3254 | this.choices = await this.suggest(this.input, this.state._choices);
|
3255 | this.state.limit = void 0;
|
3256 | this.index = Math.min(Math.max(this.visible.length - 1, 0), this.index);
|
3257 | await this.render();
|
3258 | this.completing = false;
|
3259 | }
|
3260 |
|
3261 | suggest(input = this.input, choices = this.state._choices) {
|
3262 | if (typeof this.options.suggest === 'function') {
|
3263 | return this.options.suggest.call(this, input, choices);
|
3264 | }
|
3265 | let str = input.toLowerCase();
|
3266 | return choices.filter(ch => ch.message.toLowerCase().includes(str));
|
3267 | }
|
3268 |
|
3269 | pointer() {
|
3270 | return '';
|
3271 | }
|
3272 |
|
3273 | format() {
|
3274 | if (!this.focused) return this.input;
|
3275 | if (this.options.multiple && this.state.submitted) {
|
3276 | return this.selected.map(ch => this.styles.primary(ch.message)).join(', ');
|
3277 | }
|
3278 | if (this.state.submitted) {
|
3279 | let value = this.value = this.input = this.focused.value;
|
3280 | return this.styles.primary(value);
|
3281 | }
|
3282 | return this.input;
|
3283 | }
|
3284 |
|
3285 | async render() {
|
3286 | if (this.state.status !== 'pending') return super.render();
|
3287 | let style = this.options.highlight
|
3288 | ? this.options.highlight.bind(this)
|
3289 | : this.styles.placeholder;
|
3290 |
|
3291 | let color = highlight(this.input, style);
|
3292 | let choices = this.choices;
|
3293 | this.choices = choices.map(ch => ({ ...ch, message: color(ch.message) }));
|
3294 | await super.render();
|
3295 | this.choices = choices;
|
3296 | }
|
3297 |
|
3298 | submit() {
|
3299 | if (this.options.multiple) {
|
3300 | this.value = this.selected.map(ch => ch.name);
|
3301 | }
|
3302 | return super.submit();
|
3303 | }
|
3304 | }
|
3305 |
|
3306 | var autocomplete = AutoComplete;
|
3307 |
|
3308 |
|
3309 |
|
3310 |
|
3311 |
|
3312 |
|
3313 |
|
3314 |
|
3315 |
|
3316 |
|
3317 |
|
3318 |
|
3319 |
|
3320 |
|
3321 | var placeholder = (prompt, options = {}) => {
|
3322 | prompt.cursorHide();
|
3323 |
|
3324 | let { input = '', initial = '', pos, showCursor = true, color } = options;
|
3325 | let style = color || prompt.styles.placeholder;
|
3326 | let inverse = utils.inverse(prompt.styles.primary);
|
3327 | let blinker = str => inverse(prompt.styles.black(str));
|
3328 | let output = input;
|
3329 | let char = ' ';
|
3330 | let reverse = blinker(char);
|
3331 |
|
3332 | if (prompt.blink && prompt.blink.off === true) {
|
3333 | blinker = str => str;
|
3334 | reverse = '';
|
3335 | }
|
3336 |
|
3337 | if (showCursor && pos === 0 && initial === '' && input === '') {
|
3338 | return blinker(char);
|
3339 | }
|
3340 |
|
3341 | if (showCursor && pos === 0 && (input === initial || input === '')) {
|
3342 | return blinker(initial[0]) + style(initial.slice(1));
|
3343 | }
|
3344 |
|
3345 | initial = utils.isPrimitive(initial) ? `${initial}` : '';
|
3346 | input = utils.isPrimitive(input) ? `${input}` : '';
|
3347 |
|
3348 | let placeholder = initial && initial.startsWith(input) && initial !== input;
|
3349 | let cursor = placeholder ? blinker(initial[input.length]) : reverse;
|
3350 |
|
3351 | if (pos !== input.length && showCursor === true) {
|
3352 | output = input.slice(0, pos) + blinker(input[pos]) + input.slice(pos + 1);
|
3353 | cursor = '';
|
3354 | }
|
3355 |
|
3356 | if (showCursor === false) {
|
3357 | cursor = '';
|
3358 | }
|
3359 |
|
3360 | if (placeholder) {
|
3361 | let raw = prompt.styles.unstyle(output + cursor);
|
3362 | return output + cursor + style(initial.slice(raw.length));
|
3363 | }
|
3364 |
|
3365 | return output + cursor;
|
3366 | };
|
3367 |
|
3368 | class FormPrompt extends select {
|
3369 | constructor(options) {
|
3370 | super({ ...options, multiple: true });
|
3371 | this.type = 'form';
|
3372 | this.initial = this.options.initial;
|
3373 | this.align = [this.options.align, 'right'].find(v => v != null);
|
3374 | this.emptyError = '';
|
3375 | this.values = {};
|
3376 | }
|
3377 |
|
3378 | async reset(first) {
|
3379 | await super.reset();
|
3380 | if (first === true) this._index = this.index;
|
3381 | this.index = this._index;
|
3382 | this.values = {};
|
3383 | this.choices.forEach(choice => choice.reset && choice.reset());
|
3384 | return this.render();
|
3385 | }
|
3386 |
|
3387 | dispatch(char) {
|
3388 | return !!char && this.append(char);
|
3389 | }
|
3390 |
|
3391 | append(char) {
|
3392 | let choice = this.focused;
|
3393 | if (!choice) return this.alert();
|
3394 | let { cursor, input } = choice;
|
3395 | choice.value = choice.input = input.slice(0, cursor) + char + input.slice(cursor);
|
3396 | choice.cursor++;
|
3397 | return this.render();
|
3398 | }
|
3399 |
|
3400 | delete() {
|
3401 | let choice = this.focused;
|
3402 | if (!choice || choice.cursor <= 0) return this.alert();
|
3403 | let { cursor, input } = choice;
|
3404 | choice.value = choice.input = input.slice(0, cursor - 1) + input.slice(cursor);
|
3405 | choice.cursor--;
|
3406 | return this.render();
|
3407 | }
|
3408 |
|
3409 | deleteForward() {
|
3410 | let choice = this.focused;
|
3411 | if (!choice) return this.alert();
|
3412 | let { cursor, input } = choice;
|
3413 | if (input[cursor] === void 0) return this.alert();
|
3414 | let str = `${input}`.slice(0, cursor) + `${input}`.slice(cursor + 1);
|
3415 | choice.value = choice.input = str;
|
3416 | return this.render();
|
3417 | }
|
3418 |
|
3419 | right() {
|
3420 | let choice = this.focused;
|
3421 | if (!choice) return this.alert();
|
3422 | if (choice.cursor >= choice.input.length) return this.alert();
|
3423 | choice.cursor++;
|
3424 | return this.render();
|
3425 | }
|
3426 |
|
3427 | left() {
|
3428 | let choice = this.focused;
|
3429 | if (!choice) return this.alert();
|
3430 | if (choice.cursor <= 0) return this.alert();
|
3431 | choice.cursor--;
|
3432 | return this.render();
|
3433 | }
|
3434 |
|
3435 | space(ch, key) {
|
3436 | return this.dispatch(ch, key);
|
3437 | }
|
3438 |
|
3439 | number(ch, key) {
|
3440 | return this.dispatch(ch, key);
|
3441 | }
|
3442 |
|
3443 | next() {
|
3444 | let ch = this.focused;
|
3445 | if (!ch) return this.alert();
|
3446 | let { initial, input } = ch;
|
3447 | if (initial && initial.startsWith(input) && input !== initial) {
|
3448 | ch.value = ch.input = initial;
|
3449 | ch.cursor = ch.value.length;
|
3450 | return this.render();
|
3451 | }
|
3452 | return super.next();
|
3453 | }
|
3454 |
|
3455 | prev() {
|
3456 | let ch = this.focused;
|
3457 | if (!ch) return this.alert();
|
3458 | if (ch.cursor === 0) return super.prev();
|
3459 | ch.value = ch.input = '';
|
3460 | ch.cursor = 0;
|
3461 | return this.render();
|
3462 | }
|
3463 |
|
3464 | separator() {
|
3465 | return '';
|
3466 | }
|
3467 |
|
3468 | format(value) {
|
3469 | return !this.state.submitted ? super.format(value) : '';
|
3470 | }
|
3471 |
|
3472 | pointer() {
|
3473 | return '';
|
3474 | }
|
3475 |
|
3476 | indicator(choice) {
|
3477 | return choice.input ? '⦿' : '⊙';
|
3478 | }
|
3479 |
|
3480 | async choiceSeparator(choice, i) {
|
3481 | let sep = await this.resolve(choice.separator, this.state, choice, i) || ':';
|
3482 | return sep ? ' ' + this.styles.disabled(sep) : '';
|
3483 | }
|
3484 |
|
3485 | async renderChoice(choice, i) {
|
3486 | await this.onChoice(choice, i);
|
3487 |
|
3488 | let { state, styles } = this;
|
3489 | let { cursor, initial = '', name, hint, input = '' } = choice;
|
3490 | let { muted, submitted, primary, danger } = styles;
|
3491 |
|
3492 | let help = hint;
|
3493 | let focused = this.index === i;
|
3494 | let validate = choice.validate || (() => true);
|
3495 | let sep = await this.choiceSeparator(choice, i);
|
3496 | let msg = choice.message;
|
3497 |
|
3498 | if (this.align === 'right') msg = msg.padStart(this.longest + 1, ' ');
|
3499 | if (this.align === 'left') msg = msg.padEnd(this.longest + 1, ' ');
|
3500 |
|
3501 |
|
3502 | let value = this.values[name] = (input || initial);
|
3503 | let color = input ? 'success' : 'dark';
|
3504 |
|
3505 | if ((await validate.call(choice, value, this.state)) !== true) {
|
3506 | color = 'danger';
|
3507 | }
|
3508 |
|
3509 | let style = styles[color];
|
3510 | let indicator = style(await this.indicator(choice, i)) + (choice.pad || '');
|
3511 |
|
3512 | let indent = this.indent(choice);
|
3513 | let line = () => [indent, indicator, msg + sep, input, help].filter(Boolean).join(' ');
|
3514 |
|
3515 | if (state.submitted) {
|
3516 | msg = ansiColors.unstyle(msg);
|
3517 | input = submitted(input);
|
3518 | help = '';
|
3519 | return line();
|
3520 | }
|
3521 |
|
3522 | if (choice.format) {
|
3523 | input = await choice.format.call(this, input, choice, i);
|
3524 | } else {
|
3525 | let color = this.styles.muted;
|
3526 | let options = { input, initial, pos: cursor, showCursor: focused, color };
|
3527 | input = placeholder(this, options);
|
3528 | }
|
3529 |
|
3530 | if (!this.isValue(input)) {
|
3531 | input = this.styles.muted(this.symbols.ellipsis);
|
3532 | }
|
3533 |
|
3534 | if (choice.result) {
|
3535 | this.values[name] = await choice.result.call(this, value, choice, i);
|
3536 | }
|
3537 |
|
3538 | if (focused) {
|
3539 | msg = primary(msg);
|
3540 | }
|
3541 |
|
3542 | if (choice.error) {
|
3543 | input += (input ? ' ' : '') + danger(choice.error.trim());
|
3544 | } else if (choice.hint) {
|
3545 | input += (input ? ' ' : '') + muted(choice.hint.trim());
|
3546 | }
|
3547 |
|
3548 | return line();
|
3549 | }
|
3550 |
|
3551 | async submit() {
|
3552 | this.value = this.values;
|
3553 | return super.base.submit.call(this);
|
3554 | }
|
3555 | }
|
3556 |
|
3557 | var form$1 = FormPrompt;
|
3558 |
|
3559 | const defaultAuthenticate$1 = () => {
|
3560 | throw new Error('expected prompt to have a custom authenticate method');
|
3561 | };
|
3562 |
|
3563 | const factory$1 = (authenticate = defaultAuthenticate$1) => {
|
3564 |
|
3565 | class AuthPrompt extends form$1 {
|
3566 | constructor(options) {
|
3567 | super(options);
|
3568 | }
|
3569 |
|
3570 | async submit() {
|
3571 | this.value = await authenticate.call(this, this.values, this.state);
|
3572 | super.base.submit.call(this);
|
3573 | }
|
3574 |
|
3575 | static create(authenticate) {
|
3576 | return factory$1(authenticate);
|
3577 | }
|
3578 | }
|
3579 |
|
3580 | return AuthPrompt;
|
3581 | };
|
3582 |
|
3583 | var auth = factory$1();
|
3584 |
|
3585 | function defaultAuthenticate(value, state) {
|
3586 | if (value.username === this.options.username && value.password === this.options.password) {
|
3587 | return true;
|
3588 | }
|
3589 | return false;
|
3590 | }
|
3591 |
|
3592 | const factory = (authenticate = defaultAuthenticate) => {
|
3593 | const choices = [
|
3594 | { name: 'username', message: 'username' },
|
3595 | {
|
3596 | name: 'password',
|
3597 | message: 'password',
|
3598 | format(input) {
|
3599 | if (this.options.showPassword) {
|
3600 | return input;
|
3601 | }
|
3602 | let color = this.state.submitted ? this.styles.primary : this.styles.muted;
|
3603 | return color(this.symbols.asterisk.repeat(input.length));
|
3604 | }
|
3605 | }
|
3606 | ];
|
3607 |
|
3608 | class BasicAuthPrompt extends auth.create(authenticate) {
|
3609 | constructor(options) {
|
3610 | super({ ...options, choices });
|
3611 | }
|
3612 |
|
3613 | static create(authenticate) {
|
3614 | return factory(authenticate);
|
3615 | }
|
3616 | }
|
3617 |
|
3618 | return BasicAuthPrompt;
|
3619 | };
|
3620 |
|
3621 | var basicauth = factory();
|
3622 |
|
3623 | const { isPrimitive: isPrimitive$1, hasColor } = utils;
|
3624 |
|
3625 | class BooleanPrompt extends prompt {
|
3626 | constructor(options) {
|
3627 | super(options);
|
3628 | this.cursorHide();
|
3629 | }
|
3630 |
|
3631 | async initialize() {
|
3632 | let initial = await this.resolve(this.initial, this.state);
|
3633 | this.input = await this.cast(initial);
|
3634 | await super.initialize();
|
3635 | }
|
3636 |
|
3637 | dispatch(ch) {
|
3638 | if (!this.isValue(ch)) return this.alert();
|
3639 | this.input = ch;
|
3640 | return this.submit();
|
3641 | }
|
3642 |
|
3643 | format(value) {
|
3644 | let { styles, state } = this;
|
3645 | return !state.submitted ? styles.primary(value) : styles.success(value);
|
3646 | }
|
3647 |
|
3648 | cast(input) {
|
3649 | return this.isTrue(input);
|
3650 | }
|
3651 |
|
3652 | isTrue(input) {
|
3653 | return /^[ty1]/i.test(input);
|
3654 | }
|
3655 |
|
3656 | isFalse(input) {
|
3657 | return /^[fn0]/i.test(input);
|
3658 | }
|
3659 |
|
3660 | isValue(value) {
|
3661 | return isPrimitive$1(value) && (this.isTrue(value) || this.isFalse(value));
|
3662 | }
|
3663 |
|
3664 | async hint() {
|
3665 | if (this.state.status === 'pending') {
|
3666 | let hint = await this.element('hint');
|
3667 | if (!hasColor(hint)) {
|
3668 | return this.styles.muted(hint);
|
3669 | }
|
3670 | return hint;
|
3671 | }
|
3672 | }
|
3673 |
|
3674 | async render() {
|
3675 | let { input, size } = this.state;
|
3676 |
|
3677 | let prefix = await this.prefix();
|
3678 | let sep = await this.separator();
|
3679 | let msg = await this.message();
|
3680 | let hint = this.styles.muted(this.default);
|
3681 |
|
3682 | let promptLine = [prefix, msg, hint, sep].filter(Boolean).join(' ');
|
3683 | this.state.prompt = promptLine;
|
3684 |
|
3685 | let header = await this.header();
|
3686 | let value = this.value = this.cast(input);
|
3687 | let output = await this.format(value);
|
3688 | let help = (await this.error()) || (await this.hint());
|
3689 | let footer = await this.footer();
|
3690 |
|
3691 | if (help && !promptLine.includes(help)) output += ' ' + help;
|
3692 | promptLine += ' ' + output;
|
3693 |
|
3694 | this.clear(size);
|
3695 | this.write([header, promptLine, footer].filter(Boolean).join('\n'));
|
3696 | this.restore();
|
3697 | }
|
3698 |
|
3699 | set value(value) {
|
3700 | super.value = value;
|
3701 | }
|
3702 | get value() {
|
3703 | return this.cast(super.value);
|
3704 | }
|
3705 | }
|
3706 |
|
3707 | var boolean = BooleanPrompt;
|
3708 |
|
3709 | class ConfirmPrompt extends boolean {
|
3710 | constructor(options) {
|
3711 | super(options);
|
3712 | this.default = this.options.default || (this.initial ? '(Y/n)' : '(y/N)');
|
3713 | }
|
3714 | }
|
3715 |
|
3716 | var confirm = ConfirmPrompt;
|
3717 |
|
3718 | const form = form$1.prototype;
|
3719 |
|
3720 | class Editable extends select {
|
3721 | constructor(options) {
|
3722 | super({ ...options, multiple: true });
|
3723 | this.align = [this.options.align, 'left'].find(v => v != null);
|
3724 | this.emptyError = '';
|
3725 | this.values = {};
|
3726 | }
|
3727 |
|
3728 | dispatch(char, key) {
|
3729 | let choice = this.focused;
|
3730 | let parent = choice.parent || {};
|
3731 | if (!choice.editable && !parent.editable) {
|
3732 | if (char === 'a' || char === 'i') return super[char]();
|
3733 | }
|
3734 | return form.dispatch.call(this, char, key);
|
3735 | }
|
3736 |
|
3737 | append(char, key) {
|
3738 | return form.append.call(this, char, key);
|
3739 | }
|
3740 |
|
3741 | delete(char, key) {
|
3742 | return form.delete.call(this, char, key);
|
3743 | }
|
3744 |
|
3745 | space(char) {
|
3746 | return this.focused.editable ? this.append(char) : super.space();
|
3747 | }
|
3748 |
|
3749 | number(char) {
|
3750 | return this.focused.editable ? this.append(char) : super.number(char);
|
3751 | }
|
3752 |
|
3753 | next() {
|
3754 | return this.focused.editable ? form.next.call(this) : super.next();
|
3755 | }
|
3756 |
|
3757 | prev() {
|
3758 | return this.focused.editable ? form.prev.call(this) : super.prev();
|
3759 | }
|
3760 |
|
3761 | async indicator(choice, i) {
|
3762 | let symbol = choice.indicator || '';
|
3763 | let value = choice.editable ? symbol : super.indicator(choice, i);
|
3764 | return await this.resolve(value, this.state, choice, i) || '';
|
3765 | }
|
3766 |
|
3767 | indent(choice) {
|
3768 | return choice.role === 'heading' ? '' : (choice.editable ? ' ' : ' ');
|
3769 | }
|
3770 |
|
3771 | async renderChoice(choice, i) {
|
3772 | choice.indent = '';
|
3773 | if (choice.editable) return form.renderChoice.call(this, choice, i);
|
3774 | return super.renderChoice(choice, i);
|
3775 | }
|
3776 |
|
3777 | error() {
|
3778 | return '';
|
3779 | }
|
3780 |
|
3781 | footer() {
|
3782 | return this.state.error;
|
3783 | }
|
3784 |
|
3785 | async validate() {
|
3786 | let result = true;
|
3787 |
|
3788 | for (let choice of this.choices) {
|
3789 | if (typeof choice.validate !== 'function') {
|
3790 | continue;
|
3791 | }
|
3792 |
|
3793 | if (choice.role === 'heading') {
|
3794 | continue;
|
3795 | }
|
3796 |
|
3797 | let val = choice.parent ? this.value[choice.parent.name] : this.value;
|
3798 |
|
3799 | if (choice.editable) {
|
3800 | val = choice.value === choice.name ? choice.initial || '' : choice.value;
|
3801 | } else if (!this.isDisabled(choice)) {
|
3802 | val = choice.enabled === true;
|
3803 | }
|
3804 |
|
3805 | result = await choice.validate(val, this.state);
|
3806 |
|
3807 | if (result !== true) {
|
3808 | break;
|
3809 | }
|
3810 | }
|
3811 |
|
3812 | if (result !== true) {
|
3813 | this.state.error = typeof result === 'string' ? result : 'Invalid Input';
|
3814 | }
|
3815 |
|
3816 | return result;
|
3817 | }
|
3818 |
|
3819 | submit() {
|
3820 | if (this.focused.newChoice === true) return super.submit();
|
3821 | if (this.choices.some(ch => ch.newChoice)) {
|
3822 | return this.alert();
|
3823 | }
|
3824 |
|
3825 | this.value = {};
|
3826 |
|
3827 | for (let choice of this.choices) {
|
3828 | let val = choice.parent ? this.value[choice.parent.name] : this.value;
|
3829 |
|
3830 | if (choice.role === 'heading') {
|
3831 | this.value[choice.name] = {};
|
3832 | continue;
|
3833 | }
|
3834 |
|
3835 | if (choice.editable) {
|
3836 | val[choice.name] = choice.value === choice.name
|
3837 | ? (choice.initial || '')
|
3838 | : choice.value;
|
3839 |
|
3840 | } else if (!this.isDisabled(choice)) {
|
3841 | val[choice.name] = choice.enabled === true;
|
3842 | }
|
3843 | }
|
3844 |
|
3845 | return this.base.submit.call(this);
|
3846 | }
|
3847 | }
|
3848 |
|
3849 | var editable = Editable;
|
3850 |
|
3851 | const { isPrimitive } = utils;
|
3852 |
|
3853 | class StringPrompt extends prompt {
|
3854 | constructor(options) {
|
3855 | super(options);
|
3856 | this.initial = isPrimitive(this.initial) ? String(this.initial) : '';
|
3857 | if (this.initial) this.cursorHide();
|
3858 | this.state.prevCursor = 0;
|
3859 | this.state.clipboard = [];
|
3860 | }
|
3861 |
|
3862 | async keypress(input, key = {}) {
|
3863 | let prev = this.state.prevKeypress;
|
3864 | this.state.prevKeypress = key;
|
3865 | if (this.options.multiline === true && key.name === 'return') {
|
3866 | if (!prev || prev.name !== 'return') {
|
3867 | return this.append('\n', key);
|
3868 | }
|
3869 | }
|
3870 | return super.keypress(input, key);
|
3871 | }
|
3872 |
|
3873 | moveCursor(n) {
|
3874 | this.cursor += n;
|
3875 | }
|
3876 |
|
3877 | reset() {
|
3878 | this.input = this.value = '';
|
3879 | this.cursor = 0;
|
3880 | return this.render();
|
3881 | }
|
3882 |
|
3883 | dispatch(ch, key) {
|
3884 | if (!ch || key.ctrl || key.code) return this.alert();
|
3885 | this.append(ch);
|
3886 | }
|
3887 |
|
3888 | append(ch) {
|
3889 | let { cursor, input } = this.state;
|
3890 | this.input = `${input}`.slice(0, cursor) + ch + `${input}`.slice(cursor);
|
3891 | this.moveCursor(String(ch).length);
|
3892 | this.render();
|
3893 | }
|
3894 |
|
3895 | insert(str) {
|
3896 | this.append(str);
|
3897 | }
|
3898 |
|
3899 | delete() {
|
3900 | let { cursor, input } = this.state;
|
3901 | if (cursor <= 0) return this.alert();
|
3902 | this.input = `${input}`.slice(0, cursor - 1) + `${input}`.slice(cursor);
|
3903 | this.moveCursor(-1);
|
3904 | this.render();
|
3905 | }
|
3906 |
|
3907 | deleteForward() {
|
3908 | let { cursor, input } = this.state;
|
3909 | if (input[cursor] === void 0) return this.alert();
|
3910 | this.input = `${input}`.slice(0, cursor) + `${input}`.slice(cursor + 1);
|
3911 | this.render();
|
3912 | }
|
3913 |
|
3914 | cutForward() {
|
3915 | let pos = this.cursor;
|
3916 | if (this.input.length <= pos) return this.alert();
|
3917 | this.state.clipboard.push(this.input.slice(pos));
|
3918 | this.input = this.input.slice(0, pos);
|
3919 | this.render();
|
3920 | }
|
3921 |
|
3922 | cutLeft() {
|
3923 | let pos = this.cursor;
|
3924 | if (pos === 0) return this.alert();
|
3925 | let before = this.input.slice(0, pos);
|
3926 | let after = this.input.slice(pos);
|
3927 | let words = before.split(' ');
|
3928 | this.state.clipboard.push(words.pop());
|
3929 | this.input = words.join(' ');
|
3930 | this.cursor = this.input.length;
|
3931 | this.input += after;
|
3932 | this.render();
|
3933 | }
|
3934 |
|
3935 | paste() {
|
3936 | if (!this.state.clipboard.length) return this.alert();
|
3937 | this.insert(this.state.clipboard.pop());
|
3938 | this.render();
|
3939 | }
|
3940 |
|
3941 | toggleCursor() {
|
3942 | if (this.state.prevCursor) {
|
3943 | this.cursor = this.state.prevCursor;
|
3944 | this.state.prevCursor = 0;
|
3945 | } else {
|
3946 | this.state.prevCursor = this.cursor;
|
3947 | this.cursor = 0;
|
3948 | }
|
3949 | this.render();
|
3950 | }
|
3951 |
|
3952 | first() {
|
3953 | this.cursor = 0;
|
3954 | this.render();
|
3955 | }
|
3956 |
|
3957 | last() {
|
3958 | this.cursor = this.input.length - 1;
|
3959 | this.render();
|
3960 | }
|
3961 |
|
3962 | next() {
|
3963 | let init = this.initial != null ? String(this.initial) : '';
|
3964 | if (!init || !init.startsWith(this.input)) return this.alert();
|
3965 | this.input = this.initial;
|
3966 | this.cursor = this.initial.length;
|
3967 | this.render();
|
3968 | }
|
3969 |
|
3970 | prev() {
|
3971 | if (!this.input) return this.alert();
|
3972 | this.reset();
|
3973 | }
|
3974 |
|
3975 | backward() {
|
3976 | return this.left();
|
3977 | }
|
3978 |
|
3979 | forward() {
|
3980 | return this.right();
|
3981 | }
|
3982 |
|
3983 | right() {
|
3984 | if (this.cursor >= this.input.length) return this.alert();
|
3985 | this.moveCursor(1);
|
3986 | return this.render();
|
3987 | }
|
3988 |
|
3989 | left() {
|
3990 | if (this.cursor <= 0) return this.alert();
|
3991 | this.moveCursor(-1);
|
3992 | return this.render();
|
3993 | }
|
3994 |
|
3995 | isValue(value) {
|
3996 | return !!value;
|
3997 | }
|
3998 |
|
3999 | async format(input = this.value) {
|
4000 | let initial = await this.resolve(this.initial, this.state);
|
4001 | if (!this.state.submitted) {
|
4002 | return placeholder(this, { input, initial, pos: this.cursor });
|
4003 | }
|
4004 | return this.styles.submitted(input || initial);
|
4005 | }
|
4006 |
|
4007 | async render() {
|
4008 | let size = this.state.size;
|
4009 |
|
4010 | let prefix = await this.prefix();
|
4011 | let separator = await this.separator();
|
4012 | let message = await this.message();
|
4013 |
|
4014 | let prompt = [prefix, message, separator].filter(Boolean).join(' ');
|
4015 | this.state.prompt = prompt;
|
4016 |
|
4017 | let header = await this.header();
|
4018 | let output = await this.format();
|
4019 | let help = (await this.error()) || (await this.hint());
|
4020 | let footer = await this.footer();
|
4021 |
|
4022 | if (help && !output.includes(help)) output += ' ' + help;
|
4023 | prompt += ' ' + output;
|
4024 |
|
4025 | this.clear(size);
|
4026 | this.write([header, prompt, footer].filter(Boolean).join('\n'));
|
4027 | this.restore();
|
4028 | }
|
4029 | }
|
4030 |
|
4031 | var string = StringPrompt;
|
4032 |
|
4033 | const unique = arr => arr.filter((v, i) => arr.lastIndexOf(v) === i);
|
4034 | const compact = arr => unique(arr).filter(Boolean);
|
4035 |
|
4036 | var completer = (action, data = {}, value = '') => {
|
4037 | let { past = [], present = '' } = data;
|
4038 | let rest, prev;
|
4039 |
|
4040 | switch (action) {
|
4041 | case 'prev':
|
4042 | case 'undo':
|
4043 | rest = past.slice(0, past.length - 1);
|
4044 | prev = past[past.length - 1] || '';
|
4045 | return {
|
4046 | past: compact([value, ...rest]),
|
4047 | present: prev
|
4048 | };
|
4049 |
|
4050 | case 'next':
|
4051 | case 'redo':
|
4052 | rest = past.slice(1);
|
4053 | prev = past[0] || '';
|
4054 | return {
|
4055 | past: compact([...rest, value]),
|
4056 | present: prev
|
4057 | };
|
4058 |
|
4059 | case 'save':
|
4060 | return {
|
4061 | past: compact([...past, value]),
|
4062 | present: ''
|
4063 | };
|
4064 |
|
4065 | case 'remove':
|
4066 | prev = compact(past.filter(v => v !== value));
|
4067 | present = '';
|
4068 |
|
4069 | if (prev.length) {
|
4070 | present = prev.pop();
|
4071 | }
|
4072 |
|
4073 | return {
|
4074 | past: prev,
|
4075 | present
|
4076 | };
|
4077 |
|
4078 | default: {
|
4079 | throw new Error(`Invalid action: "${action}"`);
|
4080 | }
|
4081 | }
|
4082 | };
|
4083 |
|
4084 | class Input extends string {
|
4085 | constructor(options) {
|
4086 | super(options);
|
4087 | let history = this.options.history;
|
4088 | if (history && history.store) {
|
4089 | let initial = history.values || this.initial;
|
4090 | this.autosave = !!history.autosave;
|
4091 | this.store = history.store;
|
4092 | this.data = this.store.get('values') || { past: [], present: initial };
|
4093 | this.initial = this.data.present || this.data.past[this.data.past.length - 1];
|
4094 | }
|
4095 | }
|
4096 |
|
4097 | completion(action) {
|
4098 | if (!this.store) return this.alert();
|
4099 | this.data = completer(action, this.data, this.input);
|
4100 | if (!this.data.present) return this.alert();
|
4101 | this.input = this.data.present;
|
4102 | this.cursor = this.input.length;
|
4103 | return this.render();
|
4104 | }
|
4105 |
|
4106 | altUp() {
|
4107 | return this.completion('prev');
|
4108 | }
|
4109 |
|
4110 | altDown() {
|
4111 | return this.completion('next');
|
4112 | }
|
4113 |
|
4114 | prev() {
|
4115 | this.save();
|
4116 | return super.prev();
|
4117 | }
|
4118 |
|
4119 | save() {
|
4120 | if (!this.store) return;
|
4121 | this.data = completer('save', this.data, this.input);
|
4122 | this.store.set('values', this.data);
|
4123 | }
|
4124 |
|
4125 | submit() {
|
4126 | if (this.store && this.autosave === true) {
|
4127 | this.save();
|
4128 | }
|
4129 | return super.submit();
|
4130 | }
|
4131 | }
|
4132 |
|
4133 | var input = Input;
|
4134 |
|
4135 | class InvisiblePrompt extends string {
|
4136 | format() {
|
4137 | return '';
|
4138 | }
|
4139 | }
|
4140 |
|
4141 | var invisible = InvisiblePrompt;
|
4142 |
|
4143 | class ListPrompt extends string {
|
4144 | constructor(options = {}) {
|
4145 | super(options);
|
4146 | this.sep = this.options.separator || /, */;
|
4147 | this.initial = options.initial || '';
|
4148 | }
|
4149 |
|
4150 | split(input = this.value) {
|
4151 | return input ? String(input).split(this.sep) : [];
|
4152 | }
|
4153 |
|
4154 | format() {
|
4155 | let style = this.state.submitted ? this.styles.primary : val => val;
|
4156 | return this.list.map(style).join(', ');
|
4157 | }
|
4158 |
|
4159 | async submit(value) {
|
4160 | let result = this.state.error || await this.validate(this.list, this.state);
|
4161 | if (result !== true) {
|
4162 | this.state.error = result;
|
4163 | return super.submit();
|
4164 | }
|
4165 | this.value = this.list;
|
4166 | return super.submit();
|
4167 | }
|
4168 |
|
4169 | get list() {
|
4170 | return this.split();
|
4171 | }
|
4172 | }
|
4173 |
|
4174 | var list = ListPrompt;
|
4175 |
|
4176 | class MultiSelect extends select {
|
4177 | constructor(options) {
|
4178 | super({ ...options, multiple: true });
|
4179 | }
|
4180 | }
|
4181 |
|
4182 | var multiselect = MultiSelect;
|
4183 |
|
4184 | class NumberPrompt extends string {
|
4185 | constructor(options = {}) {
|
4186 | super({ style: 'number', ...options });
|
4187 | this.min = this.isValue(options.min) ? this.toNumber(options.min) : -Infinity;
|
4188 | this.max = this.isValue(options.max) ? this.toNumber(options.max) : Infinity;
|
4189 | this.delay = options.delay != null ? options.delay : 1000;
|
4190 | this.float = options.float !== false;
|
4191 | this.round = options.round === true || options.float === false;
|
4192 | this.major = options.major || 10;
|
4193 | this.minor = options.minor || 1;
|
4194 | this.initial = options.initial != null ? options.initial : '';
|
4195 | this.input = String(this.initial);
|
4196 | this.cursor = this.input.length;
|
4197 | this.cursorShow();
|
4198 | }
|
4199 |
|
4200 | append(ch) {
|
4201 | if (!/[-+.]/.test(ch) || (ch === '.' && this.input.includes('.'))) {
|
4202 | return this.alert('invalid number');
|
4203 | }
|
4204 | return super.append(ch);
|
4205 | }
|
4206 |
|
4207 | number(ch) {
|
4208 | return super.append(ch);
|
4209 | }
|
4210 |
|
4211 | next() {
|
4212 | if (this.input && this.input !== this.initial) return this.alert();
|
4213 | if (!this.isValue(this.initial)) return this.alert();
|
4214 | this.input = this.initial;
|
4215 | this.cursor = String(this.initial).length;
|
4216 | return this.render();
|
4217 | }
|
4218 |
|
4219 | up(number) {
|
4220 | let step = number || this.minor;
|
4221 | let num = this.toNumber(this.input);
|
4222 | if (num > this.max + step) return this.alert();
|
4223 | this.input = `${num + step}`;
|
4224 | return this.render();
|
4225 | }
|
4226 |
|
4227 | down(number) {
|
4228 | let step = number || this.minor;
|
4229 | let num = this.toNumber(this.input);
|
4230 | if (num < this.min - step) return this.alert();
|
4231 | this.input = `${num - step}`;
|
4232 | return this.render();
|
4233 | }
|
4234 |
|
4235 | shiftDown() {
|
4236 | return this.down(this.major);
|
4237 | }
|
4238 |
|
4239 | shiftUp() {
|
4240 | return this.up(this.major);
|
4241 | }
|
4242 |
|
4243 | format(input = this.input) {
|
4244 | if (typeof this.options.format === 'function') {
|
4245 | return this.options.format.call(this, input);
|
4246 | }
|
4247 | return this.styles.info(input);
|
4248 | }
|
4249 |
|
4250 | toNumber(value = '') {
|
4251 | return this.float ? +value : Math.round(+value);
|
4252 | }
|
4253 |
|
4254 | isValue(value) {
|
4255 | return /^[-+]?[0-9]+((\.)|(\.[0-9]+))?$/.test(value);
|
4256 | }
|
4257 |
|
4258 | submit() {
|
4259 | let value = [this.input, this.initial].find(v => this.isValue(v));
|
4260 | this.value = this.toNumber(value || 0);
|
4261 | return super.submit();
|
4262 | }
|
4263 | }
|
4264 |
|
4265 | var number = NumberPrompt;
|
4266 |
|
4267 | var numeral = number;
|
4268 |
|
4269 | class PasswordPrompt extends string {
|
4270 | constructor(options) {
|
4271 | super(options);
|
4272 | this.cursorShow();
|
4273 | }
|
4274 |
|
4275 | format(input = this.input) {
|
4276 | if (!this.keypressed) return '';
|
4277 | let color = this.state.submitted ? this.styles.primary : this.styles.muted;
|
4278 | return color(this.symbols.asterisk.repeat(input.length));
|
4279 | }
|
4280 | }
|
4281 |
|
4282 | var password = PasswordPrompt;
|
4283 |
|
4284 | class LikertScale extends array {
|
4285 | constructor(options = {}) {
|
4286 | super(options);
|
4287 | this.widths = [].concat(options.messageWidth || 50);
|
4288 | this.align = [].concat(options.align || 'left');
|
4289 | this.linebreak = options.linebreak || false;
|
4290 | this.edgeLength = options.edgeLength || 3;
|
4291 | this.newline = options.newline || '\n ';
|
4292 | let start = options.startNumber || 1;
|
4293 | if (typeof this.scale === 'number') {
|
4294 | this.scaleKey = false;
|
4295 | this.scale = Array(this.scale).fill(0).map((v, i) => ({ name: i + start }));
|
4296 | }
|
4297 | }
|
4298 |
|
4299 | async reset() {
|
4300 | this.tableized = false;
|
4301 | await super.reset();
|
4302 | return this.render();
|
4303 | }
|
4304 |
|
4305 | tableize() {
|
4306 | if (this.tableized === true) return;
|
4307 | this.tableized = true;
|
4308 | let longest = 0;
|
4309 |
|
4310 | for (let ch of this.choices) {
|
4311 | longest = Math.max(longest, ch.message.length);
|
4312 | ch.scaleIndex = ch.initial || 2;
|
4313 | ch.scale = [];
|
4314 |
|
4315 | for (let i = 0; i < this.scale.length; i++) {
|
4316 | ch.scale.push({ index: i });
|
4317 | }
|
4318 | }
|
4319 | this.widths[0] = Math.min(this.widths[0], longest + 3);
|
4320 | }
|
4321 |
|
4322 | async dispatch(s, key) {
|
4323 | if (this.multiple) {
|
4324 | return this[key.name] ? await this[key.name](s, key) : await super.dispatch(s, key);
|
4325 | }
|
4326 | this.alert();
|
4327 | }
|
4328 |
|
4329 | heading(msg, item, i) {
|
4330 | return this.styles.strong(msg);
|
4331 | }
|
4332 |
|
4333 | separator() {
|
4334 | return this.styles.muted(this.symbols.ellipsis);
|
4335 | }
|
4336 |
|
4337 | right() {
|
4338 | let choice = this.focused;
|
4339 | if (choice.scaleIndex >= this.scale.length - 1) return this.alert();
|
4340 | choice.scaleIndex++;
|
4341 | return this.render();
|
4342 | }
|
4343 |
|
4344 | left() {
|
4345 | let choice = this.focused;
|
4346 | if (choice.scaleIndex <= 0) return this.alert();
|
4347 | choice.scaleIndex--;
|
4348 | return this.render();
|
4349 | }
|
4350 |
|
4351 | indent() {
|
4352 | return '';
|
4353 | }
|
4354 |
|
4355 | format() {
|
4356 | if (this.state.submitted) {
|
4357 | let values = this.choices.map(ch => this.styles.info(ch.index));
|
4358 | return values.join(', ');
|
4359 | }
|
4360 | return '';
|
4361 | }
|
4362 |
|
4363 | pointer() {
|
4364 | return '';
|
4365 | }
|
4366 |
|
4367 | |
4368 |
|
4369 |
|
4370 |
|
4371 |
|
4372 | renderScaleKey() {
|
4373 | if (this.scaleKey === false) return '';
|
4374 | if (this.state.submitted) return '';
|
4375 | let scale = this.scale.map(item => ` ${item.name} - ${item.message}`);
|
4376 | let key = ['', ...scale].map(item => this.styles.muted(item));
|
4377 | return key.join('\n');
|
4378 | }
|
4379 |
|
4380 | |
4381 |
|
4382 |
|
4383 |
|
4384 |
|
4385 | renderScaleHeading(max) {
|
4386 | let keys = this.scale.map(ele => ele.name);
|
4387 | if (typeof this.options.renderScaleHeading === 'function') {
|
4388 | keys = this.options.renderScaleHeading.call(this, max);
|
4389 | }
|
4390 | let diff = this.scaleLength - keys.join('').length;
|
4391 | let spacing = Math.round(diff / (keys.length - 1));
|
4392 | let names = keys.map(key => this.styles.strong(key));
|
4393 | let headings = names.join(' '.repeat(spacing));
|
4394 | let padding = ' '.repeat(this.widths[0]);
|
4395 | return this.margin[3] + padding + this.margin[1] + headings;
|
4396 | }
|
4397 |
|
4398 | |
4399 |
|
4400 |
|
4401 |
|
4402 | scaleIndicator(choice, item, i) {
|
4403 | if (typeof this.options.scaleIndicator === 'function') {
|
4404 | return this.options.scaleIndicator.call(this, choice, item, i);
|
4405 | }
|
4406 | let enabled = choice.scaleIndex === item.index;
|
4407 | if (item.disabled) return this.styles.hint(this.symbols.radio.disabled);
|
4408 | if (enabled) return this.styles.success(this.symbols.radio.on);
|
4409 | return this.symbols.radio.off;
|
4410 | }
|
4411 |
|
4412 | |
4413 |
|
4414 |
|
4415 |
|
4416 | renderScale(choice, i) {
|
4417 | let scale = choice.scale.map(item => this.scaleIndicator(choice, item, i));
|
4418 | let padding = this.term === 'Hyper' ? '' : ' ';
|
4419 | return scale.join(padding + this.symbols.line.repeat(this.edgeLength));
|
4420 | }
|
4421 |
|
4422 | |
4423 |
|
4424 |
|
4425 |
|
4426 |
|
4427 | async renderChoice(choice, i) {
|
4428 | await this.onChoice(choice, i);
|
4429 |
|
4430 | let focused = this.index === i;
|
4431 | let pointer = await this.pointer(choice, i);
|
4432 | let hint = await choice.hint;
|
4433 |
|
4434 | if (hint && !utils.hasColor(hint)) {
|
4435 | hint = this.styles.muted(hint);
|
4436 | }
|
4437 |
|
4438 | let pad = str => this.margin[3] + str.replace(/\s+$/, '').padEnd(this.widths[0], ' ');
|
4439 | let newline = this.newline;
|
4440 | let ind = this.indent(choice);
|
4441 | let message = await this.resolve(choice.message, this.state, choice, i);
|
4442 | let scale = await this.renderScale(choice, i);
|
4443 | let margin = this.margin[1] + this.margin[3];
|
4444 | this.scaleLength = ansiColors.unstyle(scale).length;
|
4445 | this.widths[0] = Math.min(this.widths[0], this.width - this.scaleLength - margin.length);
|
4446 | let msg = utils.wordWrap(message, { width: this.widths[0], newline });
|
4447 | let lines = msg.split('\n').map(line => pad(line) + this.margin[1]);
|
4448 |
|
4449 | if (focused) {
|
4450 | scale = this.styles.info(scale);
|
4451 | lines = lines.map(line => this.styles.info(line));
|
4452 | }
|
4453 |
|
4454 | lines[0] += scale;
|
4455 |
|
4456 | if (this.linebreak) lines.push('');
|
4457 | return [ind + pointer, lines.join('\n')].filter(Boolean);
|
4458 | }
|
4459 |
|
4460 | async renderChoices() {
|
4461 | if (this.state.submitted) return '';
|
4462 | this.tableize();
|
4463 | let choices = this.visible.map(async(ch, i) => await this.renderChoice(ch, i));
|
4464 | let visible = await Promise.all(choices);
|
4465 | let heading = await this.renderScaleHeading();
|
4466 | return this.margin[0] + [heading, ...visible.map(v => v.join(' '))].join('\n');
|
4467 | }
|
4468 |
|
4469 | async render() {
|
4470 | let { submitted, size } = this.state;
|
4471 |
|
4472 | let prefix = await this.prefix();
|
4473 | let separator = await this.separator();
|
4474 | let message = await this.message();
|
4475 |
|
4476 | let prompt = '';
|
4477 | if (this.options.promptLine !== false) {
|
4478 | prompt = [prefix, message, separator, ''].join(' ');
|
4479 | this.state.prompt = prompt;
|
4480 | }
|
4481 |
|
4482 | let header = await this.header();
|
4483 | let output = await this.format();
|
4484 | let key = await this.renderScaleKey();
|
4485 | let help = await this.error() || await this.hint();
|
4486 | let body = await this.renderChoices();
|
4487 | let footer = await this.footer();
|
4488 | let err = this.emptyError;
|
4489 |
|
4490 | if (output) prompt += output;
|
4491 | if (help && !prompt.includes(help)) prompt += ' ' + help;
|
4492 |
|
4493 | if (submitted && !output && !body.trim() && this.multiple && err != null) {
|
4494 | prompt += this.styles.danger(err);
|
4495 | }
|
4496 |
|
4497 | this.clear(size);
|
4498 | this.write([header, prompt, key, body, footer].filter(Boolean).join('\n'));
|
4499 | if (!this.state.submitted) {
|
4500 | this.write(this.margin[2]);
|
4501 | }
|
4502 | this.restore();
|
4503 | }
|
4504 |
|
4505 | submit() {
|
4506 | this.value = {};
|
4507 | for (let choice of this.choices) {
|
4508 | this.value[choice.name] = choice.scaleIndex;
|
4509 | }
|
4510 | return this.base.submit.call(this);
|
4511 | }
|
4512 | }
|
4513 |
|
4514 | var scale = LikertScale;
|
4515 |
|
4516 | const clean = (str = '') => {
|
4517 | return typeof str === 'string' ? str.replace(/^['"]|['"]$/g, '') : '';
|
4518 | };
|
4519 |
|
4520 |
|
4521 |
|
4522 |
|
4523 |
|
4524 |
|
4525 | class Item {
|
4526 | constructor(token) {
|
4527 | this.name = token.key;
|
4528 | this.field = token.field || {};
|
4529 | this.value = clean(token.initial || this.field.initial || '');
|
4530 | this.message = token.message || this.name;
|
4531 | this.cursor = 0;
|
4532 | this.input = '';
|
4533 | this.lines = [];
|
4534 | }
|
4535 | }
|
4536 |
|
4537 | const tokenize = async(options = {}, defaults = {}, fn = token => token) => {
|
4538 | let unique = new Set();
|
4539 | let fields = options.fields || [];
|
4540 | let input = options.template;
|
4541 | let tabstops = [];
|
4542 | let items = [];
|
4543 | let keys = [];
|
4544 | let line = 1;
|
4545 |
|
4546 | if (typeof input === 'function') {
|
4547 | input = await input();
|
4548 | }
|
4549 |
|
4550 | let i = -1;
|
4551 | let next = () => input[++i];
|
4552 | let peek = () => input[i + 1];
|
4553 | let push = token => {
|
4554 | token.line = line;
|
4555 | tabstops.push(token);
|
4556 | };
|
4557 |
|
4558 | push({ type: 'bos', value: '' });
|
4559 |
|
4560 | while (i < input.length - 1) {
|
4561 | let value = next();
|
4562 |
|
4563 | if (/^[^\S\n ]$/.test(value)) {
|
4564 | push({ type: 'text', value });
|
4565 | continue;
|
4566 | }
|
4567 |
|
4568 | if (value === '\n') {
|
4569 | push({ type: 'newline', value });
|
4570 | line++;
|
4571 | continue;
|
4572 | }
|
4573 |
|
4574 | if (value === '\\') {
|
4575 | value += next();
|
4576 | push({ type: 'text', value });
|
4577 | continue;
|
4578 | }
|
4579 |
|
4580 | if ((value === '$' || value === '#' || value === '{') && peek() === '{') {
|
4581 | let n = next();
|
4582 | value += n;
|
4583 |
|
4584 | let token = { type: 'template', open: value, inner: '', close: '', value };
|
4585 | let ch;
|
4586 |
|
4587 | while ((ch = next())) {
|
4588 | if (ch === '}') {
|
4589 | if (peek() === '}') ch += next();
|
4590 | token.value += ch;
|
4591 | token.close = ch;
|
4592 | break;
|
4593 | }
|
4594 |
|
4595 | if (ch === ':') {
|
4596 | token.initial = '';
|
4597 | token.key = token.inner;
|
4598 | } else if (token.initial !== void 0) {
|
4599 | token.initial += ch;
|
4600 | }
|
4601 |
|
4602 | token.value += ch;
|
4603 | token.inner += ch;
|
4604 | }
|
4605 |
|
4606 | token.template = token.open + (token.initial || token.inner) + token.close;
|
4607 | token.key = token.key || token.inner;
|
4608 |
|
4609 | if (defaults.hasOwnProperty(token.key)) {
|
4610 | token.initial = defaults[token.key];
|
4611 | }
|
4612 |
|
4613 | token = fn(token);
|
4614 | push(token);
|
4615 |
|
4616 | keys.push(token.key);
|
4617 | unique.add(token.key);
|
4618 |
|
4619 | let item = items.find(item => item.name === token.key);
|
4620 | token.field = fields.find(ch => ch.name === token.key);
|
4621 |
|
4622 | if (!item) {
|
4623 | item = new Item(token);
|
4624 | items.push(item);
|
4625 | }
|
4626 |
|
4627 | item.lines.push(token.line - 1);
|
4628 | continue;
|
4629 | }
|
4630 |
|
4631 | let last = tabstops[tabstops.length - 1];
|
4632 | if (last.type === 'text' && last.line === line) {
|
4633 | last.value += value;
|
4634 | } else {
|
4635 | push({ type: 'text', value });
|
4636 | }
|
4637 | }
|
4638 |
|
4639 | push({ type: 'eos', value: '' });
|
4640 | return { input, tabstops, unique, keys, items };
|
4641 | };
|
4642 |
|
4643 | var interpolate = async prompt => {
|
4644 | let options = prompt.options;
|
4645 | let required = new Set(options.required === true ? [] : (options.required || []));
|
4646 | let defaults = { ...options.values, ...options.initial };
|
4647 | let { tabstops, items, keys } = await tokenize(options, defaults);
|
4648 |
|
4649 | let result = createFn('result', prompt);
|
4650 | let format = createFn('format', prompt);
|
4651 | let isValid = createFn('validate', prompt, options, true);
|
4652 | let isVal = prompt.isValue.bind(prompt);
|
4653 |
|
4654 | return async(state = {}, submitted = false) => {
|
4655 | let index = 0;
|
4656 |
|
4657 | state.required = required;
|
4658 | state.items = items;
|
4659 | state.keys = keys;
|
4660 | state.output = '';
|
4661 |
|
4662 | let validate = async(value, state, item, index) => {
|
4663 | let error = await isValid(value, state, item, index);
|
4664 | if (error === false) {
|
4665 | return 'Invalid field ' + item.name;
|
4666 | }
|
4667 | return error;
|
4668 | };
|
4669 |
|
4670 | for (let token of tabstops) {
|
4671 | let value = token.value;
|
4672 | let key = token.key;
|
4673 |
|
4674 | if (token.type !== 'template') {
|
4675 | if (value) state.output += value;
|
4676 | continue;
|
4677 | }
|
4678 |
|
4679 | if (token.type === 'template') {
|
4680 | let item = items.find(ch => ch.name === key);
|
4681 |
|
4682 | if (options.required === true) {
|
4683 | state.required.add(item.name);
|
4684 | }
|
4685 |
|
4686 | let val = [item.input, state.values[item.value], item.value, value].find(isVal);
|
4687 | let field = item.field || {};
|
4688 | let message = field.message || token.inner;
|
4689 |
|
4690 | if (submitted) {
|
4691 | let error = await validate(state.values[key], state, item, index);
|
4692 | if ((error && typeof error === 'string') || error === false) {
|
4693 | state.invalid.set(key, error);
|
4694 | continue;
|
4695 | }
|
4696 |
|
4697 | state.invalid.delete(key);
|
4698 | let res = await result(state.values[key], state, item, index);
|
4699 | state.output += ansiColors.unstyle(res);
|
4700 | continue;
|
4701 | }
|
4702 |
|
4703 | item.placeholder = false;
|
4704 |
|
4705 | let before = value;
|
4706 | value = await format(value, state, item, index);
|
4707 |
|
4708 | if (val !== value) {
|
4709 | state.values[key] = val;
|
4710 | value = prompt.styles.typing(val);
|
4711 | state.missing.delete(message);
|
4712 |
|
4713 | } else {
|
4714 | state.values[key] = void 0;
|
4715 | val = `<${message}>`;
|
4716 | value = prompt.styles.primary(val);
|
4717 | item.placeholder = true;
|
4718 |
|
4719 | if (state.required.has(key)) {
|
4720 | state.missing.add(message);
|
4721 | }
|
4722 | }
|
4723 |
|
4724 | if (state.missing.has(message) && state.validating) {
|
4725 | value = prompt.styles.warning(val);
|
4726 | }
|
4727 |
|
4728 | if (state.invalid.has(key) && state.validating) {
|
4729 | value = prompt.styles.danger(val);
|
4730 | }
|
4731 |
|
4732 | if (index === state.index) {
|
4733 | if (before !== value) {
|
4734 | value = prompt.styles.underline(value);
|
4735 | } else {
|
4736 | value = prompt.styles.heading(ansiColors.unstyle(value));
|
4737 | }
|
4738 | }
|
4739 |
|
4740 | index++;
|
4741 | }
|
4742 |
|
4743 | if (value) {
|
4744 | state.output += value;
|
4745 | }
|
4746 | }
|
4747 |
|
4748 | let lines = state.output.split('\n').map(l => ' ' + l);
|
4749 | let len = items.length;
|
4750 | let done = 0;
|
4751 |
|
4752 | for (let item of items) {
|
4753 | if (state.invalid.has(item.name)) {
|
4754 | item.lines.forEach(i => {
|
4755 | if (lines[i][0] !== ' ') return;
|
4756 | lines[i] = state.styles.danger(state.symbols.bullet) + lines[i].slice(1);
|
4757 | });
|
4758 | }
|
4759 |
|
4760 | if (prompt.isValue(state.values[item.name])) {
|
4761 | done++;
|
4762 | }
|
4763 | }
|
4764 |
|
4765 | state.completed = ((done / len) * 100).toFixed(0);
|
4766 | state.output = lines.join('\n');
|
4767 | return state.output;
|
4768 | };
|
4769 | };
|
4770 |
|
4771 | function createFn(prop, prompt, options, fallback) {
|
4772 | return (value, state, item, index) => {
|
4773 | if (typeof item.field[prop] === 'function') {
|
4774 | return item.field[prop].call(prompt, value, state, item, index);
|
4775 | }
|
4776 | return [fallback, value].find(v => prompt.isValue(v));
|
4777 | };
|
4778 | }
|
4779 |
|
4780 | class SnippetPrompt extends prompt {
|
4781 | constructor(options) {
|
4782 | super(options);
|
4783 | this.cursorHide();
|
4784 | this.reset(true);
|
4785 | }
|
4786 |
|
4787 | async initialize() {
|
4788 | this.interpolate = await interpolate(this);
|
4789 | await super.initialize();
|
4790 | }
|
4791 |
|
4792 | async reset(first) {
|
4793 | this.state.keys = [];
|
4794 | this.state.invalid = new Map();
|
4795 | this.state.missing = new Set();
|
4796 | this.state.completed = 0;
|
4797 | this.state.values = {};
|
4798 |
|
4799 | if (first !== true) {
|
4800 | await this.initialize();
|
4801 | await this.render();
|
4802 | }
|
4803 | }
|
4804 |
|
4805 | moveCursor(n) {
|
4806 | let item = this.getItem();
|
4807 | this.cursor += n;
|
4808 | item.cursor += n;
|
4809 | }
|
4810 |
|
4811 | dispatch(ch, key) {
|
4812 | if (!key.code && !key.ctrl && ch != null && this.getItem()) {
|
4813 | this.append(ch, key);
|
4814 | return;
|
4815 | }
|
4816 | this.alert();
|
4817 | }
|
4818 |
|
4819 | append(ch, key) {
|
4820 | let item = this.getItem();
|
4821 | let prefix = item.input.slice(0, this.cursor);
|
4822 | let suffix = item.input.slice(this.cursor);
|
4823 | this.input = item.input = `${prefix}${ch}${suffix}`;
|
4824 | this.moveCursor(1);
|
4825 | this.render();
|
4826 | }
|
4827 |
|
4828 | delete() {
|
4829 | let item = this.getItem();
|
4830 | if (this.cursor <= 0 || !item.input) return this.alert();
|
4831 | let suffix = item.input.slice(this.cursor);
|
4832 | let prefix = item.input.slice(0, this.cursor - 1);
|
4833 | this.input = item.input = `${prefix}${suffix}`;
|
4834 | this.moveCursor(-1);
|
4835 | this.render();
|
4836 | }
|
4837 |
|
4838 | increment(i) {
|
4839 | return i >= this.state.keys.length - 1 ? 0 : i + 1;
|
4840 | }
|
4841 |
|
4842 | decrement(i) {
|
4843 | return i <= 0 ? this.state.keys.length - 1 : i - 1;
|
4844 | }
|
4845 |
|
4846 | first() {
|
4847 | this.state.index = 0;
|
4848 | this.render();
|
4849 | }
|
4850 |
|
4851 | last() {
|
4852 | this.state.index = this.state.keys.length - 1;
|
4853 | this.render();
|
4854 | }
|
4855 |
|
4856 | right() {
|
4857 | if (this.cursor >= this.input.length) return this.alert();
|
4858 | this.moveCursor(1);
|
4859 | this.render();
|
4860 | }
|
4861 |
|
4862 | left() {
|
4863 | if (this.cursor <= 0) return this.alert();
|
4864 | this.moveCursor(-1);
|
4865 | this.render();
|
4866 | }
|
4867 |
|
4868 | prev() {
|
4869 | this.state.index = this.decrement(this.state.index);
|
4870 | this.getItem();
|
4871 | this.render();
|
4872 | }
|
4873 |
|
4874 | next() {
|
4875 | this.state.index = this.increment(this.state.index);
|
4876 | this.getItem();
|
4877 | this.render();
|
4878 | }
|
4879 |
|
4880 | up() {
|
4881 | this.prev();
|
4882 | }
|
4883 |
|
4884 | down() {
|
4885 | this.next();
|
4886 | }
|
4887 |
|
4888 | format(value) {
|
4889 | let color = this.state.completed < 100 ? this.styles.warning : this.styles.success;
|
4890 | if (this.state.submitted === true && this.state.completed !== 100) {
|
4891 | color = this.styles.danger;
|
4892 | }
|
4893 | return color(`${this.state.completed}% completed`);
|
4894 | }
|
4895 |
|
4896 | async render() {
|
4897 | let { index, keys = [], submitted, size } = this.state;
|
4898 |
|
4899 | let newline = [this.options.newline, '\n'].find(v => v != null);
|
4900 | let prefix = await this.prefix();
|
4901 | let separator = await this.separator();
|
4902 | let message = await this.message();
|
4903 |
|
4904 | let prompt = [prefix, message, separator].filter(Boolean).join(' ');
|
4905 | this.state.prompt = prompt;
|
4906 |
|
4907 | let header = await this.header();
|
4908 | let error = (await this.error()) || '';
|
4909 | let hint = (await this.hint()) || '';
|
4910 | let body = submitted ? '' : await this.interpolate(this.state);
|
4911 |
|
4912 | let key = this.state.key = keys[index] || '';
|
4913 | let input = await this.format(key);
|
4914 | let footer = await this.footer();
|
4915 | if (input) prompt += ' ' + input;
|
4916 | if (hint && !input && this.state.completed === 0) prompt += ' ' + hint;
|
4917 |
|
4918 | this.clear(size);
|
4919 | let lines = [header, prompt, body, footer, error.trim()];
|
4920 | this.write(lines.filter(Boolean).join(newline));
|
4921 | this.restore();
|
4922 | }
|
4923 |
|
4924 | getItem(name) {
|
4925 | let { items, keys, index } = this.state;
|
4926 | let item = items.find(ch => ch.name === keys[index]);
|
4927 | if (item && item.input != null) {
|
4928 | this.input = item.input;
|
4929 | this.cursor = item.cursor;
|
4930 | }
|
4931 | return item;
|
4932 | }
|
4933 |
|
4934 | async submit() {
|
4935 | if (typeof this.interpolate !== 'function') await this.initialize();
|
4936 | await this.interpolate(this.state, true);
|
4937 |
|
4938 | let { invalid, missing, output, values } = this.state;
|
4939 | if (invalid.size) {
|
4940 | let err = '';
|
4941 | for (let [key, value] of invalid) err += `Invalid ${key}: ${value}\n`;
|
4942 | this.state.error = err;
|
4943 | return super.submit();
|
4944 | }
|
4945 |
|
4946 | if (missing.size) {
|
4947 | this.state.error = 'Required: ' + [...missing.keys()].join(', ');
|
4948 | return super.submit();
|
4949 | }
|
4950 |
|
4951 | let lines = ansiColors.unstyle(output).split('\n');
|
4952 | let result = lines.map(v => v.slice(1)).join('\n');
|
4953 | this.value = { values, result };
|
4954 | return super.submit();
|
4955 | }
|
4956 | }
|
4957 |
|
4958 | var snippet = SnippetPrompt;
|
4959 |
|
4960 | const hint = '(Use <shift>+<up/down> to sort)';
|
4961 |
|
4962 |
|
4963 | class Sort extends select {
|
4964 | constructor(options) {
|
4965 | super({ ...options, reorder: false, sort: true, multiple: true });
|
4966 | this.state.hint = [this.options.hint, hint].find(this.isValue.bind(this));
|
4967 | }
|
4968 |
|
4969 | indicator() {
|
4970 | return '';
|
4971 | }
|
4972 |
|
4973 | async renderChoice(choice, i) {
|
4974 | let str = await super.renderChoice(choice, i);
|
4975 | let sym = this.symbols.identicalTo + ' ';
|
4976 | let pre = (this.index === i && this.sorting) ? this.styles.muted(sym) : ' ';
|
4977 | if (this.options.drag === false) pre = '';
|
4978 | if (this.options.numbered === true) {
|
4979 | return pre + `${i + 1} - ` + str;
|
4980 | }
|
4981 | return pre + str;
|
4982 | }
|
4983 |
|
4984 | get selected() {
|
4985 | return this.choices;
|
4986 | }
|
4987 |
|
4988 | submit() {
|
4989 | this.value = this.choices.map(choice => choice.value);
|
4990 | return super.submit();
|
4991 | }
|
4992 | }
|
4993 |
|
4994 | var sort = Sort;
|
4995 |
|
4996 | class Survey extends array {
|
4997 | constructor(options = {}) {
|
4998 | super(options);
|
4999 | this.emptyError = options.emptyError || 'No items were selected';
|
5000 | this.term = process.env.TERM_PROGRAM;
|
5001 |
|
5002 | if (!this.options.header) {
|
5003 | let header = ['', '4 - Strongly Agree', '3 - Agree', '2 - Neutral', '1 - Disagree', '0 - Strongly Disagree', ''];
|
5004 | header = header.map(ele => this.styles.muted(ele));
|
5005 | this.state.header = header.join('\n ');
|
5006 | }
|
5007 | }
|
5008 |
|
5009 | async toChoices(...args) {
|
5010 | if (this.createdScales) return false;
|
5011 | this.createdScales = true;
|
5012 | let choices = await super.toChoices(...args);
|
5013 | for (let choice of choices) {
|
5014 | choice.scale = createScale(5, this.options);
|
5015 | choice.scaleIdx = 2;
|
5016 | }
|
5017 | return choices;
|
5018 | }
|
5019 |
|
5020 | dispatch() {
|
5021 | this.alert();
|
5022 | }
|
5023 |
|
5024 | space() {
|
5025 | let choice = this.focused;
|
5026 | let ele = choice.scale[choice.scaleIdx];
|
5027 | let selected = ele.selected;
|
5028 | choice.scale.forEach(e => (e.selected = false));
|
5029 | ele.selected = !selected;
|
5030 | return this.render();
|
5031 | }
|
5032 |
|
5033 | indicator() {
|
5034 | return '';
|
5035 | }
|
5036 |
|
5037 | pointer() {
|
5038 | return '';
|
5039 | }
|
5040 |
|
5041 | separator() {
|
5042 | return this.styles.muted(this.symbols.ellipsis);
|
5043 | }
|
5044 |
|
5045 | right() {
|
5046 | let choice = this.focused;
|
5047 | if (choice.scaleIdx >= choice.scale.length - 1) return this.alert();
|
5048 | choice.scaleIdx++;
|
5049 | return this.render();
|
5050 | }
|
5051 |
|
5052 | left() {
|
5053 | let choice = this.focused;
|
5054 | if (choice.scaleIdx <= 0) return this.alert();
|
5055 | choice.scaleIdx--;
|
5056 | return this.render();
|
5057 | }
|
5058 |
|
5059 | indent() {
|
5060 | return ' ';
|
5061 | }
|
5062 |
|
5063 | async renderChoice(item, i) {
|
5064 | await this.onChoice(item, i);
|
5065 | let focused = this.index === i;
|
5066 | let isHyper = this.term === 'Hyper';
|
5067 | let n = !isHyper ? 8 : 9;
|
5068 | let s = !isHyper ? ' ' : '';
|
5069 | let ln = this.symbols.line.repeat(n);
|
5070 | let sp = ' '.repeat(n + (isHyper ? 0 : 1));
|
5071 | let dot = enabled => (enabled ? this.styles.success('◉') : '◯') + s;
|
5072 |
|
5073 | let num = i + 1 + '.';
|
5074 | let color = focused ? this.styles.heading : this.styles.noop;
|
5075 | let msg = await this.resolve(item.message, this.state, item, i);
|
5076 | let indent = this.indent(item);
|
5077 | let scale = indent + item.scale.map((e, i) => dot(i === item.scaleIdx)).join(ln);
|
5078 | let val = i => i === item.scaleIdx ? color(i) : i;
|
5079 | let next = indent + item.scale.map((e, i) => val(i)).join(sp);
|
5080 |
|
5081 | let line = () => [num, msg].filter(Boolean).join(' ');
|
5082 | let lines = () => [line(), scale, next, ' '].filter(Boolean).join('\n');
|
5083 |
|
5084 | if (focused) {
|
5085 | scale = this.styles.cyan(scale);
|
5086 | next = this.styles.cyan(next);
|
5087 | }
|
5088 |
|
5089 | return lines();
|
5090 | }
|
5091 |
|
5092 | async renderChoices() {
|
5093 | if (this.state.submitted) return '';
|
5094 | let choices = this.visible.map(async(ch, i) => await this.renderChoice(ch, i));
|
5095 | let visible = await Promise.all(choices);
|
5096 | if (!visible.length) visible.push(this.styles.danger('No matching choices'));
|
5097 | return visible.join('\n');
|
5098 | }
|
5099 |
|
5100 | format() {
|
5101 | if (this.state.submitted) {
|
5102 | let values = this.choices.map(ch => this.styles.info(ch.scaleIdx));
|
5103 | return values.join(', ');
|
5104 | }
|
5105 | return '';
|
5106 | }
|
5107 |
|
5108 | async render() {
|
5109 | let { submitted, size } = this.state;
|
5110 |
|
5111 | let prefix = await this.prefix();
|
5112 | let separator = await this.separator();
|
5113 | let message = await this.message();
|
5114 |
|
5115 | let prompt = [prefix, message, separator].filter(Boolean).join(' ');
|
5116 | this.state.prompt = prompt;
|
5117 |
|
5118 | let header = await this.header();
|
5119 | let output = await this.format();
|
5120 | let help = await this.error() || await this.hint();
|
5121 | let body = await this.renderChoices();
|
5122 | let footer = await this.footer();
|
5123 |
|
5124 | if (output || !help) prompt += ' ' + output;
|
5125 | if (help && !prompt.includes(help)) prompt += ' ' + help;
|
5126 |
|
5127 | if (submitted && !output && !body && this.multiple && this.type !== 'form') {
|
5128 | prompt += this.styles.danger(this.emptyError);
|
5129 | }
|
5130 |
|
5131 | this.clear(size);
|
5132 | this.write([prompt, header, body, footer].filter(Boolean).join('\n'));
|
5133 | this.restore();
|
5134 | }
|
5135 |
|
5136 | submit() {
|
5137 | this.value = {};
|
5138 | for (let choice of this.choices) {
|
5139 | this.value[choice.name] = choice.scaleIdx;
|
5140 | }
|
5141 | return this.base.submit.call(this);
|
5142 | }
|
5143 | }
|
5144 |
|
5145 | function createScale(n, options = {}) {
|
5146 | if (Array.isArray(options.scale)) {
|
5147 | return options.scale.map(ele => ({ ...ele }));
|
5148 | }
|
5149 | let scale = [];
|
5150 | for (let i = 1; i < n + 1; i++) scale.push({ i, selected: false });
|
5151 | return scale;
|
5152 | }
|
5153 |
|
5154 | var survey = Survey;
|
5155 |
|
5156 | var text = input;
|
5157 |
|
5158 | class TogglePrompt extends boolean {
|
5159 | async initialize() {
|
5160 | await super.initialize();
|
5161 | this.value = this.initial = !!this.options.initial;
|
5162 | this.disabled = this.options.disabled || 'no';
|
5163 | this.enabled = this.options.enabled || 'yes';
|
5164 | await this.render();
|
5165 | }
|
5166 |
|
5167 | reset() {
|
5168 | this.value = this.initial;
|
5169 | this.render();
|
5170 | }
|
5171 |
|
5172 | delete() {
|
5173 | this.alert();
|
5174 | }
|
5175 |
|
5176 | toggle() {
|
5177 | this.value = !this.value;
|
5178 | this.render();
|
5179 | }
|
5180 |
|
5181 | enable() {
|
5182 | if (this.value === true) return this.alert();
|
5183 | this.value = true;
|
5184 | this.render();
|
5185 | }
|
5186 | disable() {
|
5187 | if (this.value === false) return this.alert();
|
5188 | this.value = false;
|
5189 | this.render();
|
5190 | }
|
5191 |
|
5192 | up() {
|
5193 | this.toggle();
|
5194 | }
|
5195 | down() {
|
5196 | this.toggle();
|
5197 | }
|
5198 | right() {
|
5199 | this.toggle();
|
5200 | }
|
5201 | left() {
|
5202 | this.toggle();
|
5203 | }
|
5204 | next() {
|
5205 | this.toggle();
|
5206 | }
|
5207 | prev() {
|
5208 | this.toggle();
|
5209 | }
|
5210 |
|
5211 | dispatch(ch = '', key) {
|
5212 | switch (ch.toLowerCase()) {
|
5213 | case ' ':
|
5214 | return this.toggle();
|
5215 | case '1':
|
5216 | case 'y':
|
5217 | case 't':
|
5218 | return this.enable();
|
5219 | case '0':
|
5220 | case 'n':
|
5221 | case 'f':
|
5222 | return this.disable();
|
5223 | default: {
|
5224 | return this.alert();
|
5225 | }
|
5226 | }
|
5227 | }
|
5228 |
|
5229 | format() {
|
5230 | let active = str => this.styles.primary.underline(str);
|
5231 | let value = [
|
5232 | this.value ? this.disabled : active(this.disabled),
|
5233 | this.value ? active(this.enabled) : this.enabled
|
5234 | ];
|
5235 | return value.join(this.styles.muted(' / '));
|
5236 | }
|
5237 |
|
5238 | async render() {
|
5239 | let { size } = this.state;
|
5240 |
|
5241 | let header = await this.header();
|
5242 | let prefix = await this.prefix();
|
5243 | let separator = await this.separator();
|
5244 | let message = await this.message();
|
5245 |
|
5246 | let output = await this.format();
|
5247 | let help = (await this.error()) || (await this.hint());
|
5248 | let footer = await this.footer();
|
5249 |
|
5250 | let prompt = [prefix, message, separator, output].join(' ');
|
5251 | this.state.prompt = prompt;
|
5252 |
|
5253 | if (help && !prompt.includes(help)) prompt += ' ' + help;
|
5254 |
|
5255 | this.clear(size);
|
5256 | this.write([header, prompt, footer].filter(Boolean).join('\n'));
|
5257 | this.write(this.margin[2]);
|
5258 | this.restore();
|
5259 | }
|
5260 | }
|
5261 |
|
5262 | var toggle = TogglePrompt;
|
5263 |
|
5264 | class Quiz extends select {
|
5265 | constructor(options) {
|
5266 | super(options);
|
5267 | if (typeof this.options.correctChoice !== 'number' || this.options.correctChoice < 0) {
|
5268 | throw new Error('Please specify the index of the correct answer from the list of choices');
|
5269 | }
|
5270 | }
|
5271 |
|
5272 | async toChoices(value, parent) {
|
5273 | let choices = await super.toChoices(value, parent);
|
5274 | if (choices.length < 2) {
|
5275 | throw new Error('Please give at least two choices to the user');
|
5276 | }
|
5277 | if (this.options.correctChoice > choices.length) {
|
5278 | throw new Error('Please specify the index of the correct answer from the list of choices');
|
5279 | }
|
5280 | return choices;
|
5281 | }
|
5282 |
|
5283 | check(state) {
|
5284 | return state.index === this.options.correctChoice;
|
5285 | }
|
5286 |
|
5287 | async result(selected) {
|
5288 | return {
|
5289 | selectedAnswer: selected,
|
5290 | correctAnswer: this.options.choices[this.options.correctChoice].value,
|
5291 | correct: await this.check(this.state)
|
5292 | };
|
5293 | }
|
5294 | }
|
5295 |
|
5296 | var quiz = Quiz;
|
5297 |
|
5298 | var prompts$1 = index.createCommonjsModule(function (module, exports) {
|
5299 |
|
5300 |
|
5301 |
|
5302 | const define = (key, fn) => {
|
5303 | utils.defineExport(exports, key, fn);
|
5304 | utils.defineExport(exports, key.toLowerCase(), fn);
|
5305 | };
|
5306 |
|
5307 | define('AutoComplete', () => autocomplete);
|
5308 | define('BasicAuth', () => basicauth);
|
5309 | define('Confirm', () => confirm);
|
5310 | define('Editable', () => editable);
|
5311 | define('Form', () => form$1);
|
5312 | define('Input', () => input);
|
5313 | define('Invisible', () => invisible);
|
5314 | define('List', () => list);
|
5315 | define('MultiSelect', () => multiselect);
|
5316 | define('Numeral', () => numeral);
|
5317 | define('Password', () => password);
|
5318 | define('Scale', () => scale);
|
5319 | define('Select', () => select);
|
5320 | define('Snippet', () => snippet);
|
5321 | define('Sort', () => sort);
|
5322 | define('Survey', () => survey);
|
5323 | define('Text', () => text);
|
5324 | define('Toggle', () => toggle);
|
5325 | define('Quiz', () => quiz);
|
5326 | });
|
5327 |
|
5328 | var types = {
|
5329 | ArrayPrompt: array,
|
5330 | AuthPrompt: auth,
|
5331 | BooleanPrompt: boolean,
|
5332 | NumberPrompt: number,
|
5333 | StringPrompt: string
|
5334 | };
|
5335 |
|
5336 |
|
5337 |
|
5338 |
|
5339 |
|
5340 |
|
5341 |
|
5342 |
|
5343 |
|
5344 |
|
5345 |
|
5346 |
|
5347 |
|
5348 |
|
5349 | class Enquirer extends Events__default['default'] {
|
5350 | constructor(options, answers) {
|
5351 | super();
|
5352 | this.options = utils.merge({}, options);
|
5353 | this.answers = { ...answers };
|
5354 | }
|
5355 |
|
5356 | |
5357 |
|
5358 |
|
5359 |
|
5360 |
|
5361 |
|
5362 |
|
5363 |
|
5364 |
|
5365 |
|
5366 |
|
5367 |
|
5368 |
|
5369 |
|
5370 |
|
5371 | register(type, fn) {
|
5372 | if (utils.isObject(type)) {
|
5373 | for (let key of Object.keys(type)) this.register(key, type[key]);
|
5374 | return this;
|
5375 | }
|
5376 | assert__default['default'].equal(typeof fn, 'function', 'expected a function');
|
5377 | let name = type.toLowerCase();
|
5378 | if (fn.prototype instanceof this.Prompt) {
|
5379 | this.prompts[name] = fn;
|
5380 | } else {
|
5381 | this.prompts[name] = fn(this.Prompt, this);
|
5382 | }
|
5383 | return this;
|
5384 | }
|
5385 |
|
5386 | |
5387 |
|
5388 |
|
5389 |
|
5390 |
|
5391 |
|
5392 |
|
5393 |
|
5394 |
|
5395 |
|
5396 |
|
5397 |
|
5398 |
|
5399 |
|
5400 |
|
5401 |
|
5402 |
|
5403 |
|
5404 |
|
5405 |
|
5406 |
|
5407 | async prompt(questions = []) {
|
5408 | for (let question of [].concat(questions)) {
|
5409 | try {
|
5410 | if (typeof question === 'function') question = await question.call(this);
|
5411 | await this.ask(utils.merge({}, this.options, question));
|
5412 | } catch (err) {
|
5413 | return Promise.reject(err);
|
5414 | }
|
5415 | }
|
5416 | return this.answers;
|
5417 | }
|
5418 |
|
5419 | async ask(question) {
|
5420 | if (typeof question === 'function') {
|
5421 | question = await question.call(this);
|
5422 | }
|
5423 |
|
5424 | let opts = utils.merge({}, this.options, question);
|
5425 | let { type, name } = question;
|
5426 | let { set, get } = utils;
|
5427 |
|
5428 | if (typeof type === 'function') {
|
5429 | type = await type.call(this, question, this.answers);
|
5430 | }
|
5431 |
|
5432 | if (!type) return this.answers[name];
|
5433 |
|
5434 | assert__default['default'](this.prompts[type], `Prompt "${type}" is not registered`);
|
5435 |
|
5436 | let prompt = new this.prompts[type](opts);
|
5437 | let value = get(this.answers, name);
|
5438 |
|
5439 | prompt.state.answers = this.answers;
|
5440 | prompt.enquirer = this;
|
5441 |
|
5442 | if (name) {
|
5443 | prompt.on('submit', value => {
|
5444 | this.emit('answer', name, value, prompt);
|
5445 | set(this.answers, name, value);
|
5446 | });
|
5447 | }
|
5448 |
|
5449 | // bubble events
|
5450 | let emit = prompt.emit.bind(prompt);
|
5451 | prompt.emit = (...args) => {
|
5452 | this.emit.call(this, ...args);
|
5453 | return emit(...args);
|
5454 | };
|
5455 |
|
5456 | this.emit('prompt', prompt, this);
|
5457 |
|
5458 | if (opts.autofill && value != null) {
|
5459 | prompt.value = prompt.input = value;
|
5460 |
|
5461 |
|
5462 | if (opts.autofill === 'show') {
|
5463 | await prompt.submit();
|
5464 | }
|
5465 | } else {
|
5466 | value = prompt.value = await prompt.run();
|
5467 | }
|
5468 |
|
5469 | return value;
|
5470 | }
|
5471 |
|
5472 | |
5473 |
|
5474 |
|
5475 |
|
5476 |
|
5477 |
|
5478 |
|
5479 |
|
5480 |
|
5481 |
|
5482 |
|
5483 |
|
5484 |
|
5485 |
|
5486 |
|
5487 |
|
5488 |
|
5489 | use(plugin) {
|
5490 | plugin.call(this, this);
|
5491 | return this;
|
5492 | }
|
5493 |
|
5494 | set Prompt(value) {
|
5495 | this._Prompt = value;
|
5496 | }
|
5497 | get Prompt() {
|
5498 | return this._Prompt || this.constructor.Prompt;
|
5499 | }
|
5500 |
|
5501 | get prompts() {
|
5502 | return this.constructor.prompts;
|
5503 | }
|
5504 |
|
5505 | static set Prompt(value) {
|
5506 | this._Prompt = value;
|
5507 | }
|
5508 | static get Prompt() {
|
5509 | return this._Prompt || prompt;
|
5510 | }
|
5511 |
|
5512 | static get prompts() {
|
5513 | return prompts$1;
|
5514 | }
|
5515 |
|
5516 | static get types() {
|
5517 | return types;
|
5518 | }
|
5519 |
|
5520 | |
5521 |
|
5522 |
|
5523 |
|
5524 |
|
5525 |
|
5526 |
|
5527 |
|
5528 |
|
5529 |
|
5530 |
|
5531 |
|
5532 |
|
5533 |
|
5534 |
|
5535 |
|
5536 |
|
5537 |
|
5538 |
|
5539 | static get prompt() {
|
5540 | const fn = (questions, ...rest) => {
|
5541 | let enquirer = new this(...rest);
|
5542 | let emit = enquirer.emit.bind(enquirer);
|
5543 | enquirer.emit = (...args) => {
|
5544 | fn.emit(...args);
|
5545 | return emit(...args);
|
5546 | };
|
5547 | return enquirer.prompt(questions);
|
5548 | };
|
5549 | utils.mixinEmitter(fn, new Events__default['default']());
|
5550 | return fn;
|
5551 | }
|
5552 | }
|
5553 |
|
5554 | utils.mixinEmitter(Enquirer, new Events__default['default']());
|
5555 | const prompts = Enquirer.prompts;
|
5556 |
|
5557 | for (let name of Object.keys(prompts)) {
|
5558 | let key = name.toLowerCase();
|
5559 |
|
5560 | let run = options => new prompts[name](options).run();
|
5561 | Enquirer.prompt[key] = run;
|
5562 | Enquirer[key] = run;
|
5563 |
|
5564 | if (!Enquirer[name]) {
|
5565 | Reflect.defineProperty(Enquirer, name, { get: () => prompts[name] });
|
5566 | }
|
5567 | }
|
5568 |
|
5569 | const exp = name => {
|
5570 | utils.defineExport(Enquirer, name, () => Enquirer.types[name]);
|
5571 | };
|
5572 |
|
5573 | exp('ArrayPrompt');
|
5574 | exp('AuthPrompt');
|
5575 | exp('BooleanPrompt');
|
5576 | exp('NumberPrompt');
|
5577 | exp('StringPrompt');
|
5578 |
|
5579 | var enquirer = Enquirer;
|
5580 |
|
5581 | const args = mri(process.argv.slice(2), {
|
5582 | alias: {
|
5583 | f: 'force',
|
5584 | c: 'cache',
|
5585 | v: 'verbose',
|
5586 | m: 'mode'
|
5587 | },
|
5588 | boolean: ['force', 'cache', 'verbose']
|
5589 | });
|
5590 |
|
5591 | const [src, dest = '.'] = args._;
|
5592 |
|
5593 | async function main() {
|
5594 | if (args.help) {
|
5595 | const help = fs__default['default']
|
5596 | .readFileSync(path__default['default'].join(__dirname, 'help.md'), 'utf-8')
|
5597 | .replace(/^(\s*)#+ (.+)/gm, (m, s, _) => s + index.source.bold(_))
|
5598 | .replace(/_([^_]+)_/g, (m, _) => index.source.underline(_))
|
5599 | .replace(/`([^`]+)`/g, (m, _) => index.source.cyan(_));
|
5600 |
|
5601 | process.stdout.write(`\n${help}\n`);
|
5602 | } else if (!src) {
|
5603 |
|
5604 |
|
5605 | const accessLookup = new Map();
|
5606 |
|
5607 | sync(`**/access.json`, { cwd: index.base }).forEach(file => {
|
5608 | const [host, user, repo] = file.split(path__default['default'].sep);
|
5609 |
|
5610 | const json = fs__default['default'].readFileSync(`${index.base}/${file}`, 'utf-8');
|
5611 | const logs = JSON.parse(json);
|
5612 |
|
5613 | Object.entries(logs).forEach(([ref, timestamp]) => {
|
5614 | const id = `${host}:${user}/${repo}#${ref}`;
|
5615 | accessLookup.set(id, new Date(timestamp).getTime());
|
5616 | });
|
5617 | });
|
5618 |
|
5619 | const getChoice = file => {
|
5620 | const [host, user, repo] = file.split(path__default['default'].sep);
|
5621 |
|
5622 | return Object.entries(index.tryRequire(`${index.base}/${file}`)).map(
|
5623 | ([ref, hash]) => ({
|
5624 | name: hash,
|
5625 | message: `${host}:${user}/${repo}#${ref}`,
|
5626 | value: `${host}:${user}/${repo}#${ref}`
|
5627 | })
|
5628 | );
|
5629 | };
|
5630 |
|
5631 | const choices = sync(`**/map.json`, { cwd: index.base })
|
5632 | .map(getChoice)
|
5633 | .reduce(
|
5634 | (accumulator, currentValue) => accumulator.concat(currentValue),
|
5635 | []
|
5636 | )
|
5637 | .sort((a, b) => {
|
5638 | const aTime = accessLookup.get(a.value) || 0;
|
5639 | const bTime = accessLookup.get(b.value) || 0;
|
5640 |
|
5641 | return bTime - aTime;
|
5642 | });
|
5643 |
|
5644 | const options = await enquirer.prompt([
|
5645 | {
|
5646 | type: 'autocomplete',
|
5647 | name: 'src',
|
5648 | message: 'Repo to clone?',
|
5649 | suggest: (input, choices) =>
|
5650 | choices.filter(({ value }) => fuzzysearch_1(input, value)),
|
5651 | choices
|
5652 | },
|
5653 | {
|
5654 | type: 'input',
|
5655 | name: 'dest',
|
5656 | message: 'Destination directory?',
|
5657 | initial: '.'
|
5658 | },
|
5659 | {
|
5660 | type: 'toggle',
|
5661 | name: 'cache',
|
5662 | message: 'Use cached version?'
|
5663 | }
|
5664 | ]);
|
5665 |
|
5666 | const empty =
|
5667 | !fs__default['default'].existsSync(options.dest) || fs__default['default'].readdirSync(options.dest).length === 0;
|
5668 |
|
5669 | if (!empty) {
|
5670 | const { force } = await enquirer.prompt([
|
5671 | {
|
5672 | type: 'toggle',
|
5673 | name: 'force',
|
5674 | message: 'Overwrite existing files?'
|
5675 | }
|
5676 | ]);
|
5677 |
|
5678 | if (!force) {
|
5679 | console.error(index.source.magenta(`! Directory not empty — aborting`));
|
5680 | return;
|
5681 | }
|
5682 | }
|
5683 |
|
5684 | run(options.src, options.dest, {
|
5685 | force: true,
|
5686 | cache: options.cache
|
5687 | });
|
5688 | } else {
|
5689 | run(src, dest, args);
|
5690 | }
|
5691 | }
|
5692 |
|
5693 | function run(src, dest, args) {
|
5694 | const d = index.degit(src, args);
|
5695 |
|
5696 | d.on('info', event => {
|
5697 | console.error(index.source.cyan(`> ${event.message.replace('options.', '--')}`));
|
5698 | });
|
5699 |
|
5700 | d.on('warn', event => {
|
5701 | console.error(
|
5702 | index.source.magenta(`! ${event.message.replace('options.', '--')}`)
|
5703 | );
|
5704 | });
|
5705 |
|
5706 | d.clone(dest).catch(err => {
|
5707 | console.error(index.source.red(`! ${err.message.replace('options.', '--')}`));
|
5708 | process.exit(1);
|
5709 | });
|
5710 | }
|
5711 |
|
5712 | main();
|
5713 |
|