UNPKG

4.76 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const tslib_1 = require("tslib");
4const errors_1 = require("@oclif/errors");
5const chalk_1 = tslib_1.__importDefault(require("chalk"));
6const config_1 = tslib_1.__importDefault(require("./config"));
7const deps_1 = tslib_1.__importDefault(require("./deps"));
8/**
9 * prompt for input
10 */
11function prompt(name, options = {}) {
12 return config_1.default.action.pauseAsync(() => {
13 return _prompt(name, options);
14 }, chalk_1.default.cyan('?'));
15}
16exports.prompt = prompt;
17/**
18 * confirmation prompt (yes/no)
19 */
20function confirm(message) {
21 return config_1.default.action.pauseAsync(async () => {
22 const confirm = async () => {
23 let response = (await _prompt(message)).toLowerCase();
24 if (['n', 'no'].includes(response))
25 return false;
26 if (['y', 'yes'].includes(response))
27 return true;
28 return confirm();
29 };
30 return confirm();
31 }, chalk_1.default.cyan('?'));
32}
33exports.confirm = confirm;
34/**
35 * "press anykey to continue"
36 */
37async function anykey(message) {
38 const tty = !!process.stdin.setRawMode;
39 if (!message) {
40 message = tty
41 ? `Press any key to continue or ${chalk_1.default.yellow('q')} to exit`
42 : `Press enter to continue or ${chalk_1.default.yellow('q')} to exit`;
43 }
44 const char = await prompt(message, { type: 'single', required: false });
45 if (tty)
46 process.stderr.write('\n');
47 if (char === 'q')
48 errors_1.error('quit');
49 if (char === '\u0003')
50 errors_1.error('ctrl-c');
51 return char;
52}
53exports.anykey = anykey;
54function _prompt(name, inputOptions = {}) {
55 const prompt = getPrompt(name, inputOptions.type, inputOptions.default);
56 const options = Object.assign({ isTTY: !!(process.env.TERM !== 'dumb' && process.stdin.isTTY), name,
57 prompt, type: 'normal', required: true, default: '' }, inputOptions);
58 switch (options.type) {
59 case 'normal':
60 return normal(options);
61 case 'single':
62 return single(options);
63 case 'mask':
64 return deps_1.default.passwordPrompt(options.prompt, {
65 method: options.type,
66 required: options.required,
67 default: options.default
68 }).then((value) => {
69 replacePrompt(getPrompt(name, 'hide', inputOptions.default));
70 return value;
71 });
72 case 'hide':
73 return deps_1.default.passwordPrompt(options.prompt, {
74 method: options.type,
75 required: options.required,
76 default: options.default
77 });
78 default:
79 throw new Error(`unexpected type ${options.type}`);
80 }
81}
82async function single(options) {
83 const raw = process.stdin.isRaw;
84 if (process.stdin.setRawMode)
85 process.stdin.setRawMode(true);
86 const response = await normal(Object.assign({ required: false }, options));
87 if (process.stdin.setRawMode)
88 process.stdin.setRawMode(!!raw);
89 return response;
90}
91function normal(options, retries = 100) {
92 if (retries < 0)
93 throw new Error('no input');
94 return new Promise((resolve, reject) => {
95 let timer;
96 if (options.timeout) {
97 timer = setTimeout(() => {
98 process.stdin.pause();
99 reject(new Error('Prompt timeout'));
100 }, options.timeout);
101 timer.unref();
102 }
103 process.stdin.setEncoding('utf8');
104 process.stderr.write(options.prompt);
105 process.stdin.resume();
106 process.stdin.once('data', data => {
107 if (timer)
108 clearTimeout(timer);
109 process.stdin.pause();
110 data = data.trim();
111 if (!options.default && options.required && data === '') {
112 resolve(normal(options, retries - 1));
113 }
114 else {
115 resolve(data || options.default);
116 }
117 });
118 });
119}
120function getPrompt(name, type, defaultValue) {
121 let prompt = '> ';
122 if (defaultValue && type === 'hide') {
123 defaultValue = '*'.repeat(defaultValue.length);
124 }
125 if (name && defaultValue)
126 prompt = name + ' ' + chalk_1.default.yellow('[' + defaultValue + ']') + ': ';
127 else if (name)
128 prompt = `${name}: `;
129 return prompt;
130}
131function replacePrompt(prompt) {
132 process.stderr.write(deps_1.default.ansiEscapes.cursorHide + deps_1.default.ansiEscapes.cursorUp(1) + deps_1.default.ansiEscapes.cursorLeft + prompt
133 + deps_1.default.ansiEscapes.cursorDown(1) + deps_1.default.ansiEscapes.cursorLeft + deps_1.default.ansiEscapes.cursorShow);
134}