spyne-cli 0.6.8 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +80 -30
- package/index.js +131 -21
- package/package.json +31 -6
- package/src/cli/args.js +197 -0
- package/src/cli/render.js +198 -0
- package/src/core/create-app.js +256 -0
- package/src/core/generate-app.js +155 -0
- package/src/core/generate-module.js +146 -0
- package/src/registry.js +180 -0
- package/src/spyne-file-prompt.js +77 -30
- package/src/templates/generate-prompt-input-fields.js +1 -1
- package/src/ui.js +5 -1
- package/lib/ansi.js +0 -116
- package/lib/combos.js +0 -75
- package/lib/completer.js +0 -52
- package/lib/interpolate.js +0 -266
- package/lib/keypress.js +0 -243
- package/lib/placeholder.js +0 -63
- package/lib/prompt.js +0 -485
- package/lib/prompts/autocomplete.js +0 -113
- package/lib/prompts/basicauth.js +0 -41
- package/lib/prompts/confirm.js +0 -13
- package/lib/prompts/editable.js +0 -136
- package/lib/prompts/form.js +0 -196
- package/lib/prompts/index.js +0 -28
- package/lib/prompts/input.js +0 -55
- package/lib/prompts/invisible.js +0 -11
- package/lib/prompts/list.js +0 -36
- package/lib/prompts/multiselect.js +0 -11
- package/lib/prompts/numeral.js +0 -1
- package/lib/prompts/password.js +0 -18
- package/lib/prompts/quiz.js +0 -37
- package/lib/prompts/scale.js +0 -237
- package/lib/prompts/select.js +0 -139
- package/lib/prompts/snippet.js +0 -185
- package/lib/prompts/sort.js +0 -37
- package/lib/prompts/survey.js +0 -163
- package/lib/prompts/text.js +0 -1
- package/lib/prompts/toggle.js +0 -109
- package/lib/render.js +0 -33
- package/lib/roles.js +0 -46
- package/lib/state.js +0 -69
- package/lib/styles.js +0 -144
- package/lib/symbols.js +0 -66
- package/lib/theme.js +0 -11
- package/lib/timer.js +0 -38
- package/lib/types/array.js +0 -658
- package/lib/types/auth.js +0 -29
- package/lib/types/boolean.js +0 -88
- package/lib/types/index.js +0 -7
- package/lib/types/number.js +0 -86
- package/lib/types/string.js +0 -185
- package/lib/utils.js +0 -268
- package/mocha.conf.cjs +0 -16
- package/src/app/channels/.gitkeep +0 -0
- package/src/app/channels/channel-custom.js +0 -1
- package/src/app/components/.gitkeep +0 -0
- package/src/app/traits/.gitkeep +0 -0
- package/src/hello-world-app-source/README.md +0 -15
- package/src/hello-world-app-source/apache-htaccess +0 -20
- package/src/hello-world-app-source/karma.conf.js +0 -75
- package/src/hello-world-app-source/package.json +0 -50
- package/src/hello-world-app-source/src/app/app-view.js +0 -38
- package/src/hello-world-app-source/src/app/channels/.gitkeep +0 -0
- package/src/hello-world-app-source/src/app/components/.gitkeep +0 -0
- package/src/hello-world-app-source/src/app/traits/.gitkeep +0 -0
- package/src/hello-world-app-source/src/index.js +0 -16
- package/src/hello-world-app-source/src/index.tmpl.html +0 -12
- package/src/hello-world-app-source/src/scss/01-vendors/normalize.css +0 -349
- package/src/hello-world-app-source/src/scss/02-variables/mixins.scss +0 -0
- package/src/hello-world-app-source/src/scss/03-components/.gitkeep +0 -0
- package/src/hello-world-app-source/src/scss/main.scss +0 -15
- package/src/hello-world-app-source/src/static/data/.gitkeep +0 -0
- package/src/hello-world-app-source/src/static/fonts/.gitkeep +0 -0
- package/src/hello-world-app-source/src/static/imgs/.gitkeep +0 -0
- package/src/hello-world-app-source/src/tests/unit-tests/index.test.js +0 -10
- package/src/hello-world-app-source/webpack.config.js +0 -178
- package/src/spyne-app-create.js +0 -209
- package/src/spyne-app-creator.js +0 -119
- package/src/spyne-starter-app-create.js +0 -147
- package/tests/create-spyne-app.test.js +0 -63
- package/tests/generate-file-prompt.test.js +0 -45
- package/tests/generate-file-string.test.js +0 -66
- package/tests/generate-prompt-input-fields-methods.test.js +0 -177
- package/tests/generate-prompt-input-fields.test.js +0 -179
- package/tests/generate-prompt-input-object.test.js +0 -39
- package/tests/generate-prompt-output.test.js +0 -58
- package/tests/index.test.js +0 -11
- package/tests/mocks/answers.js +0 -33
- package/tests/mocks/answers.json +0 -33
- package/tests/mocks/enquirer-data.js +0 -411
- package/tests/mocks/enquirer-data.json +0 -409
- package/tests/utils/file-utils.test.js +0 -84
package/lib/prompt.js
DELETED
|
@@ -1,485 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const Events = require('events');
|
|
4
|
-
const colors = require('ansi-colors');
|
|
5
|
-
const keypress = require('./keypress');
|
|
6
|
-
const timer = require('./timer');
|
|
7
|
-
const State = require('./state');
|
|
8
|
-
const theme = require('./theme');
|
|
9
|
-
const utils = require('./utils');
|
|
10
|
-
const ansi = require('./ansi');
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Base class for creating a new Prompt.
|
|
14
|
-
* @param {Object} `options` Question object.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
class Prompt extends Events {
|
|
18
|
-
constructor(options = {}) {
|
|
19
|
-
super();
|
|
20
|
-
this.name = options.name;
|
|
21
|
-
this.type = options.type;
|
|
22
|
-
this.options = options;
|
|
23
|
-
theme(this);
|
|
24
|
-
timer(this);
|
|
25
|
-
this.state = new State(this);
|
|
26
|
-
this.initial = [options.initial, options.default].find(v => v != null);
|
|
27
|
-
this.stdout = options.stdout || process.stdout;
|
|
28
|
-
this.stdin = options.stdin || process.stdin;
|
|
29
|
-
this.scale = options.scale || 1;
|
|
30
|
-
this.term = this.options.term || process.env.TERM_PROGRAM;
|
|
31
|
-
this.margin = margin(this.options.margin);
|
|
32
|
-
this.setMaxListeners(0);
|
|
33
|
-
setOptions(this);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async keypress(input, event = {}) {
|
|
37
|
-
this.keypressed = true;
|
|
38
|
-
let key = keypress.action(input, keypress(input, event), this.options.actions);
|
|
39
|
-
this.state.keypress = key;
|
|
40
|
-
this.emit('keypress', input, key);
|
|
41
|
-
this.emit('state', this.state.clone());
|
|
42
|
-
let fn = this.options[key.action] || this[key.action] || this.dispatch;
|
|
43
|
-
if (typeof fn === 'function') {
|
|
44
|
-
return await fn.call(this, input, key);
|
|
45
|
-
}
|
|
46
|
-
this.alert();
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
alert() {
|
|
50
|
-
delete this.state.alert;
|
|
51
|
-
if (this.options.show === false) {
|
|
52
|
-
this.emit('alert');
|
|
53
|
-
} else {
|
|
54
|
-
this.stdout.write(ansi.code.beep);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
cursorHide() {
|
|
59
|
-
this.stdout.write(ansi.cursor.hide());
|
|
60
|
-
utils.onExit(() => this.cursorShow());
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
cursorShow() {
|
|
64
|
-
this.stdout.write(ansi.cursor.show());
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
write(str) {
|
|
68
|
-
if (!str) return;
|
|
69
|
-
if (this.stdout && this.state.show !== false) {
|
|
70
|
-
this.stdout.write(str);
|
|
71
|
-
}
|
|
72
|
-
this.state.buffer += str;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
clear(lines = 0) {
|
|
76
|
-
let buffer = this.state.buffer;
|
|
77
|
-
this.state.buffer = '';
|
|
78
|
-
if ((!buffer && !lines) || this.options.show === false) return;
|
|
79
|
-
this.stdout.write(ansi.cursor.down(lines) + ansi.clear(buffer, this.width));
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
restore() {
|
|
83
|
-
if (this.state.closed || this.options.show === false) return;
|
|
84
|
-
|
|
85
|
-
let { prompt, after, rest } = this.sections();
|
|
86
|
-
let { cursor, initial = '', input = '', value = '' } = this;
|
|
87
|
-
|
|
88
|
-
let size = this.state.size = rest.length;
|
|
89
|
-
let state = { after, cursor, initial, input, prompt, size, value };
|
|
90
|
-
let codes = ansi.cursor.restore(state);
|
|
91
|
-
if (codes) {
|
|
92
|
-
this.stdout.write(codes);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
sections() {
|
|
97
|
-
let { buffer, input, prompt } = this.state;
|
|
98
|
-
prompt = colors.unstyle(prompt);
|
|
99
|
-
let buf = colors.unstyle(buffer);
|
|
100
|
-
let idx = buf.indexOf(prompt);
|
|
101
|
-
let header = buf.slice(0, idx);
|
|
102
|
-
let rest = buf.slice(idx);
|
|
103
|
-
let lines = rest.split('\n');
|
|
104
|
-
let first = lines[0];
|
|
105
|
-
let last = lines[lines.length - 1];
|
|
106
|
-
let promptLine = prompt + (input ? ' ' + input : '');
|
|
107
|
-
let len = promptLine.length;
|
|
108
|
-
let after = len < first.length ? first.slice(len + 1) : '';
|
|
109
|
-
return { header, prompt: first, after, rest: lines.slice(1), last };
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
async submit() {
|
|
113
|
-
this.state.submitted = true;
|
|
114
|
-
this.state.validating = true;
|
|
115
|
-
|
|
116
|
-
// this will only be called when the prompt is directly submitted
|
|
117
|
-
// without initializing, i.e. when the prompt is skipped, etc. Otherwize,
|
|
118
|
-
// "options.onSubmit" is will be handled by the "initialize()" method.
|
|
119
|
-
if (this.options.onSubmit) {
|
|
120
|
-
await this.options.onSubmit.call(this, this.name, this.value, this);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
let result = this.state.error || await this.validate(this.value, this.state);
|
|
124
|
-
if (result !== true) {
|
|
125
|
-
let error = '\n' + this.symbols.pointer + ' ';
|
|
126
|
-
|
|
127
|
-
if (typeof result === 'string') {
|
|
128
|
-
error += result.trim();
|
|
129
|
-
} else {
|
|
130
|
-
error += 'Invalid input';
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
this.state.error = '\n' + this.styles.danger(error);
|
|
134
|
-
this.state.submitted = false;
|
|
135
|
-
await this.render();
|
|
136
|
-
await this.alert();
|
|
137
|
-
this.state.validating = false;
|
|
138
|
-
this.state.error = void 0;
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
this.state.validating = false;
|
|
143
|
-
await this.render();
|
|
144
|
-
await this.close();
|
|
145
|
-
|
|
146
|
-
this.value = await this.result(this.value);
|
|
147
|
-
this.emit('submit', this.value);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
async cancel(err) {
|
|
151
|
-
this.state.cancelled = this.state.submitted = true;
|
|
152
|
-
|
|
153
|
-
await this.render();
|
|
154
|
-
await this.close();
|
|
155
|
-
|
|
156
|
-
if (typeof this.options.onCancel === 'function') {
|
|
157
|
-
await this.options.onCancel.call(this, this.name, this.value, this);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
this.emit('cancel', await this.error(err));
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
async close() {
|
|
164
|
-
this.state.closed = true;
|
|
165
|
-
|
|
166
|
-
try {
|
|
167
|
-
let sections = this.sections();
|
|
168
|
-
let lines = Math.ceil(sections.prompt.length / this.width);
|
|
169
|
-
if (sections.rest) {
|
|
170
|
-
this.write(ansi.cursor.down(sections.rest.length));
|
|
171
|
-
}
|
|
172
|
-
this.write('\n'.repeat(lines));
|
|
173
|
-
} catch (err) { /* do nothing */ }
|
|
174
|
-
|
|
175
|
-
this.emit('close');
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
start() {
|
|
179
|
-
if (!this.stop && this.options.show !== false) {
|
|
180
|
-
this.stop = keypress.listen(this, this.keypress.bind(this));
|
|
181
|
-
this.once('close', this.stop);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
async skip() {
|
|
186
|
-
this.skipped = this.options.skip === true;
|
|
187
|
-
if (typeof this.options.skip === 'function') {
|
|
188
|
-
this.skipped = await this.options.skip.call(this, this.name, this.value);
|
|
189
|
-
}
|
|
190
|
-
return this.skipped;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
async initialize() {
|
|
194
|
-
let { format, options, result } = this;
|
|
195
|
-
|
|
196
|
-
this.format = () => format.call(this, this.value);
|
|
197
|
-
this.result = () => result.call(this, this.value);
|
|
198
|
-
|
|
199
|
-
if (typeof options.initial === 'function') {
|
|
200
|
-
this.initial = await options.initial.call(this, this);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
if (typeof options.onRun === 'function') {
|
|
204
|
-
await options.onRun.call(this, this);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// if "options.onSubmit" is defined, we wrap the "submit" method to guarantee
|
|
208
|
-
// that "onSubmit" will always called first thing inside the submit
|
|
209
|
-
// method, regardless of how it's handled in inheriting prompts.
|
|
210
|
-
if (typeof options.onSubmit === 'function') {
|
|
211
|
-
let onSubmit = options.onSubmit.bind(this);
|
|
212
|
-
let submit = this.submit.bind(this);
|
|
213
|
-
delete this.options.onSubmit;
|
|
214
|
-
this.submit = async() => {
|
|
215
|
-
await onSubmit(this.name, this.value, this);
|
|
216
|
-
return submit();
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
await this.start();
|
|
221
|
-
await this.render();
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
render() {
|
|
225
|
-
throw new Error('expected prompt to have a custom render method');
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
run() {
|
|
229
|
-
return new Promise(async(resolve, reject) => {
|
|
230
|
-
this.once('submit', resolve);
|
|
231
|
-
this.once('cancel', reject);
|
|
232
|
-
if (await this.skip()) {
|
|
233
|
-
this.render = () => {};
|
|
234
|
-
return this.submit();
|
|
235
|
-
}
|
|
236
|
-
await this.initialize();
|
|
237
|
-
this.emit('run');
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
async element(name, choice, i) {
|
|
242
|
-
let { options, state, symbols, timers } = this;
|
|
243
|
-
let timer = timers && timers[name];
|
|
244
|
-
state.timer = timer;
|
|
245
|
-
let value = options[name] || state[name] || symbols[name];
|
|
246
|
-
let val = choice && choice[name] != null ? choice[name] : await value;
|
|
247
|
-
if (val === '') return val;
|
|
248
|
-
|
|
249
|
-
let res = await this.resolve(val, state, choice, i);
|
|
250
|
-
if (!res && choice && choice[name]) {
|
|
251
|
-
return this.resolve(value, state, choice, i);
|
|
252
|
-
}
|
|
253
|
-
return res;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
async prefix() {
|
|
257
|
-
let element = await this.element('prefix') || this.symbols;
|
|
258
|
-
let timer = this.timers && this.timers.prefix;
|
|
259
|
-
let state = this.state;
|
|
260
|
-
state.timer = timer;
|
|
261
|
-
if (utils.isObject(element)) element = element[state.status] || element.pending;
|
|
262
|
-
if (!utils.hasColor(element)) {
|
|
263
|
-
let style = this.styles[state.status] || this.styles.pending;
|
|
264
|
-
return style(element);
|
|
265
|
-
}
|
|
266
|
-
return element;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
async message() {
|
|
270
|
-
let message = await this.element('message');
|
|
271
|
-
if (!utils.hasColor(message)) {
|
|
272
|
-
return this.styles.strong(message);
|
|
273
|
-
}
|
|
274
|
-
return message;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
async separator() {
|
|
278
|
-
let element = await this.element('separator') || this.symbols;
|
|
279
|
-
let timer = this.timers && this.timers.separator;
|
|
280
|
-
let state = this.state;
|
|
281
|
-
state.timer = timer;
|
|
282
|
-
let value = element[state.status] || element.pending || state.separator;
|
|
283
|
-
let ele = await this.resolve(value, state);
|
|
284
|
-
if (utils.isObject(ele)) ele = ele[state.status] || ele.pending;
|
|
285
|
-
if (!utils.hasColor(ele)) {
|
|
286
|
-
return this.styles.muted(ele);
|
|
287
|
-
}
|
|
288
|
-
return ele;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
async pointer(choice, i) {
|
|
292
|
-
let val = await this.element('pointer', choice, i);
|
|
293
|
-
|
|
294
|
-
if (typeof val === 'string' && utils.hasColor(val)) {
|
|
295
|
-
return val;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
if (val) {
|
|
299
|
-
let styles = this.styles;
|
|
300
|
-
let focused = this.index === i;
|
|
301
|
-
let style = focused ? styles.primary : val => val;
|
|
302
|
-
let ele = await this.resolve(val[focused ? 'on' : 'off'] || val, this.state);
|
|
303
|
-
let styled = !utils.hasColor(ele) ? style(ele) : ele;
|
|
304
|
-
return focused ? styled : ' '.repeat(ele.length);
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
async indicator(choice, i) {
|
|
309
|
-
let val = await this.element('indicator', choice, i);
|
|
310
|
-
if (typeof val === 'string' && utils.hasColor(val)) {
|
|
311
|
-
return val;
|
|
312
|
-
}
|
|
313
|
-
if (val) {
|
|
314
|
-
let styles = this.styles;
|
|
315
|
-
let enabled = choice.enabled === true;
|
|
316
|
-
let style = enabled ? styles.success : styles.dark;
|
|
317
|
-
let ele = val[enabled ? 'on' : 'off'] || val;
|
|
318
|
-
return !utils.hasColor(ele) ? style(ele) : ele;
|
|
319
|
-
}
|
|
320
|
-
return '';
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
body() {
|
|
324
|
-
return null;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
footer() {
|
|
328
|
-
if (this.state.status === 'pending') {
|
|
329
|
-
return this.element('footer');
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
header() {
|
|
334
|
-
if (this.state.status === 'pending') {
|
|
335
|
-
return this.element('header');
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
async hint() {
|
|
340
|
-
if (this.state.status === 'pending' && !this.isValue(this.state.input)) {
|
|
341
|
-
let hint = await this.element('hint');
|
|
342
|
-
if (!utils.hasColor(hint)) {
|
|
343
|
-
return this.styles.muted(hint);
|
|
344
|
-
}
|
|
345
|
-
return hint;
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
error(err) {
|
|
350
|
-
return !this.state.submitted ? (err || this.state.error) : '';
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
format(value) {
|
|
354
|
-
return value;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
result(value) {
|
|
358
|
-
return value;
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
validate(value) {
|
|
362
|
-
if (this.options.required === true) {
|
|
363
|
-
return this.isValue(value);
|
|
364
|
-
}
|
|
365
|
-
return true;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
isValue(value) {
|
|
369
|
-
return value != null && value !== '';
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
resolve(value, ...args) {
|
|
373
|
-
return utils.resolve(this, value, ...args);
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
get base() {
|
|
377
|
-
return Prompt.prototype;
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
get style() {
|
|
381
|
-
return this.styles[this.state.status];
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
get height() {
|
|
385
|
-
return this.options.rows || utils.height(this.stdout, 25);
|
|
386
|
-
}
|
|
387
|
-
get width() {
|
|
388
|
-
return this.options.columns || utils.width(this.stdout, 80);
|
|
389
|
-
}
|
|
390
|
-
get size() {
|
|
391
|
-
return { width: this.width, height: this.height };
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
set cursor(value) {
|
|
395
|
-
this.state.cursor = value;
|
|
396
|
-
}
|
|
397
|
-
get cursor() {
|
|
398
|
-
return this.state.cursor;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
set input(value) {
|
|
402
|
-
this.state.input = value;
|
|
403
|
-
}
|
|
404
|
-
get input() {
|
|
405
|
-
return this.state.input;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
set value(value) {
|
|
409
|
-
this.state.value = value;
|
|
410
|
-
}
|
|
411
|
-
get value() {
|
|
412
|
-
let { input, value } = this.state;
|
|
413
|
-
let result = [value, input].find(this.isValue.bind(this));
|
|
414
|
-
return this.isValue(result) ? result : this.initial;
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
static get prompt() {
|
|
418
|
-
return options => new this(options).run();
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
function setOptions(prompt) {
|
|
423
|
-
let isValidKey = key => {
|
|
424
|
-
return prompt[key] === void 0 || typeof prompt[key] === 'function';
|
|
425
|
-
};
|
|
426
|
-
|
|
427
|
-
let ignore = [
|
|
428
|
-
'actions',
|
|
429
|
-
'choices',
|
|
430
|
-
'initial',
|
|
431
|
-
'margin',
|
|
432
|
-
'roles',
|
|
433
|
-
'styles',
|
|
434
|
-
'symbols',
|
|
435
|
-
'theme',
|
|
436
|
-
'timers',
|
|
437
|
-
'value'
|
|
438
|
-
];
|
|
439
|
-
|
|
440
|
-
let ignoreFn = [
|
|
441
|
-
'body',
|
|
442
|
-
'footer',
|
|
443
|
-
'error',
|
|
444
|
-
'header',
|
|
445
|
-
'hint',
|
|
446
|
-
'indicator',
|
|
447
|
-
'message',
|
|
448
|
-
'prefix',
|
|
449
|
-
'separator',
|
|
450
|
-
'skip'
|
|
451
|
-
];
|
|
452
|
-
|
|
453
|
-
for (let key of Object.keys(prompt.options)) {
|
|
454
|
-
if (ignore.includes(key)) continue;
|
|
455
|
-
if (/^on[A-Z]/.test(key)) continue;
|
|
456
|
-
let option = prompt.options[key];
|
|
457
|
-
if (typeof option === 'function' && isValidKey(key)) {
|
|
458
|
-
if (!ignoreFn.includes(key)) {
|
|
459
|
-
prompt[key] = option.bind(prompt);
|
|
460
|
-
}
|
|
461
|
-
} else if (typeof prompt[key] !== 'function') {
|
|
462
|
-
prompt[key] = option;
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
function margin(value) {
|
|
468
|
-
if (typeof value === 'number') {
|
|
469
|
-
value = [value, value, value, value];
|
|
470
|
-
}
|
|
471
|
-
let arr = [].concat(value || []);
|
|
472
|
-
let pad = i => i % 2 === 0 ? '\n' : ' ';
|
|
473
|
-
let res = [];
|
|
474
|
-
for (let i = 0; i < 4; i++) {
|
|
475
|
-
let char = pad(i);
|
|
476
|
-
if (arr[i]) {
|
|
477
|
-
res.push(char.repeat(arr[i]));
|
|
478
|
-
} else {
|
|
479
|
-
res.push('');
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
return res;
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
module.exports = Prompt;
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const Select = require('./select');
|
|
4
|
-
|
|
5
|
-
const highlight = (input, color) => {
|
|
6
|
-
let val = input.toLowerCase();
|
|
7
|
-
return str => {
|
|
8
|
-
let s = str.toLowerCase();
|
|
9
|
-
let i = s.indexOf(val);
|
|
10
|
-
let colored = color(str.slice(i, i + val.length));
|
|
11
|
-
return i >= 0 ? str.slice(0, i) + colored + str.slice(i + val.length) : str;
|
|
12
|
-
};
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
class AutoComplete extends Select {
|
|
16
|
-
constructor(options) {
|
|
17
|
-
super(options);
|
|
18
|
-
this.cursorShow();
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
moveCursor(n) {
|
|
22
|
-
this.state.cursor += n;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
dispatch(ch) {
|
|
26
|
-
return this.append(ch);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
space(ch) {
|
|
30
|
-
return this.options.multiple ? super.space(ch) : this.append(ch);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
append(ch) {
|
|
34
|
-
let { cursor, input } = this.state;
|
|
35
|
-
this.input = input.slice(0, cursor) + ch + input.slice(cursor);
|
|
36
|
-
this.moveCursor(1);
|
|
37
|
-
return this.complete();
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
delete() {
|
|
41
|
-
let { cursor, input } = this.state;
|
|
42
|
-
if (!input) return this.alert();
|
|
43
|
-
this.input = input.slice(0, cursor - 1) + input.slice(cursor);
|
|
44
|
-
this.moveCursor(-1);
|
|
45
|
-
return this.complete();
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
deleteForward() {
|
|
49
|
-
let { cursor, input } = this.state;
|
|
50
|
-
if (input[cursor] === void 0) return this.alert();
|
|
51
|
-
this.input = `${input}`.slice(0, cursor) + `${input}`.slice(cursor + 1);
|
|
52
|
-
return this.complete();
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
number(ch) {
|
|
56
|
-
return this.append(ch);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async complete() {
|
|
60
|
-
this.completing = true;
|
|
61
|
-
this.choices = await this.suggest(this.input, this.state._choices);
|
|
62
|
-
this.state.limit = void 0; // allow getter/setter to reset limit
|
|
63
|
-
this.index = Math.min(Math.max(this.visible.length - 1, 0), this.index);
|
|
64
|
-
await this.render();
|
|
65
|
-
this.completing = false;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
suggest(input = this.input, choices = this.state._choices) {
|
|
69
|
-
if (typeof this.options.suggest === 'function') {
|
|
70
|
-
return this.options.suggest.call(this, input, choices);
|
|
71
|
-
}
|
|
72
|
-
let str = input.toLowerCase();
|
|
73
|
-
return choices.filter(ch => ch.message.toLowerCase().includes(str));
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
pointer() {
|
|
77
|
-
return '';
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
format() {
|
|
81
|
-
if (!this.focused) return this.input;
|
|
82
|
-
if (this.options.multiple && this.state.submitted) {
|
|
83
|
-
return this.selected.map(ch => this.styles.primary(ch.message)).join(', ');
|
|
84
|
-
}
|
|
85
|
-
if (this.state.submitted) {
|
|
86
|
-
let value = this.value = this.input = this.focused.value;
|
|
87
|
-
return this.styles.primary(value);
|
|
88
|
-
}
|
|
89
|
-
return this.input;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
async render() {
|
|
93
|
-
if (this.state.status !== 'pending') return super.render();
|
|
94
|
-
let style = this.options.highlight
|
|
95
|
-
? this.options.highlight.bind(this)
|
|
96
|
-
: this.styles.placeholder;
|
|
97
|
-
|
|
98
|
-
let color = highlight(this.input, style);
|
|
99
|
-
let choices = this.choices;
|
|
100
|
-
this.choices = choices.map(ch => ({ ...ch, message: color(ch.message) }));
|
|
101
|
-
await super.render();
|
|
102
|
-
this.choices = choices;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
submit() {
|
|
106
|
-
if (this.options.multiple) {
|
|
107
|
-
this.value = this.selected.map(ch => ch.name);
|
|
108
|
-
}
|
|
109
|
-
return super.submit();
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
module.exports = AutoComplete;
|
package/lib/prompts/basicauth.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const AuthPrompt = require('../types/auth');
|
|
4
|
-
|
|
5
|
-
function defaultAuthenticate(value, state) {
|
|
6
|
-
if (value.username === this.options.username && value.password === this.options.password) {
|
|
7
|
-
return true;
|
|
8
|
-
}
|
|
9
|
-
return false;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const factory = (authenticate = defaultAuthenticate) => {
|
|
13
|
-
const choices = [
|
|
14
|
-
{ name: 'username', message: 'username' },
|
|
15
|
-
{
|
|
16
|
-
name: 'password',
|
|
17
|
-
message: 'password',
|
|
18
|
-
format(input) {
|
|
19
|
-
if (this.options.showPassword) {
|
|
20
|
-
return input;
|
|
21
|
-
}
|
|
22
|
-
let color = this.state.submitted ? this.styles.primary : this.styles.muted;
|
|
23
|
-
return color(this.symbols.asterisk.repeat(input.length));
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
];
|
|
27
|
-
|
|
28
|
-
class BasicAuthPrompt extends AuthPrompt.create(authenticate) {
|
|
29
|
-
constructor(options) {
|
|
30
|
-
super({ ...options, choices });
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
static create(authenticate) {
|
|
34
|
-
return factory(authenticate);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return BasicAuthPrompt;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
module.exports = factory();
|
package/lib/prompts/confirm.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const BooleanPrompt = require('../types/boolean');
|
|
4
|
-
|
|
5
|
-
class ConfirmPrompt extends BooleanPrompt {
|
|
6
|
-
constructor(options) {
|
|
7
|
-
super(options);
|
|
8
|
-
this.default = this.options.default || (this.initial ? '(Y/n)' : '(y/N)');
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
module.exports = ConfirmPrompt;
|
|
13
|
-
|