1 | 'use strict';
|
2 |
|
3 | const prompts = require('./prompts');
|
4 |
|
5 | const passOn = ['suggest', 'format', 'onState', 'validate', 'onRender', 'type'];
|
6 | const noop = () => {};
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 | async function prompt(questions=[], { onSubmit=noop, onCancel=noop }={}) {
|
16 | const answers = {};
|
17 | const override = prompt._override || {};
|
18 | questions = [].concat(questions);
|
19 | let answer, question, quit, name, type, lastPrompt;
|
20 |
|
21 | const getFormattedAnswer = async (question, answer, skipValidation = false) => {
|
22 | if (!skipValidation && question.validate && question.validate(answer) !== true) {
|
23 | return;
|
24 | }
|
25 | return question.format ? await question.format(answer, answers) : answer
|
26 | };
|
27 |
|
28 | for (question of questions) {
|
29 | ({ name, type } = question);
|
30 |
|
31 |
|
32 | if (typeof type === 'function') {
|
33 | type = await type(answer, { ...answers }, question)
|
34 | question['type'] = type
|
35 | }
|
36 | if (!type) continue;
|
37 |
|
38 |
|
39 | for (let key in question) {
|
40 | if (passOn.includes(key)) continue;
|
41 | let value = question[key];
|
42 | question[key] = typeof value === 'function' ? await value(answer, { ...answers }, lastPrompt) : value;
|
43 | }
|
44 |
|
45 | lastPrompt = question;
|
46 |
|
47 | if (typeof question.message !== 'string') {
|
48 | throw new Error('prompt message is required');
|
49 | }
|
50 |
|
51 |
|
52 | ({ name, type } = question);
|
53 |
|
54 | if (prompts[type] === void 0) {
|
55 | throw new Error(`prompt type (${type}) is not defined`);
|
56 | }
|
57 |
|
58 | if (override[question.name] !== undefined) {
|
59 | answer = await getFormattedAnswer(question, override[question.name]);
|
60 | if (answer !== undefined) {
|
61 | answers[name] = answer;
|
62 | continue;
|
63 | }
|
64 | }
|
65 |
|
66 | try {
|
67 |
|
68 | answer = prompt._injected ? getInjectedAnswer(prompt._injected, question.initial) : await prompts[type](question);
|
69 | answers[name] = answer = await getFormattedAnswer(question, answer, true);
|
70 | quit = await onSubmit(question, answer, answers);
|
71 | } catch (err) {
|
72 | quit = !(await onCancel(question, answers));
|
73 | }
|
74 |
|
75 | if (quit) return answers;
|
76 | }
|
77 |
|
78 | return answers;
|
79 | }
|
80 |
|
81 | function getInjectedAnswer(injected, deafultValue) {
|
82 | const answer = injected.shift();
|
83 | if (answer instanceof Error) {
|
84 | throw answer;
|
85 | }
|
86 |
|
87 | return (answer === undefined) ? deafultValue : answer;
|
88 | }
|
89 |
|
90 | function inject(answers) {
|
91 | prompt._injected = (prompt._injected || []).concat(answers);
|
92 | }
|
93 |
|
94 | function override(answers) {
|
95 | prompt._override = Object.assign({}, answers);
|
96 | }
|
97 |
|
98 | module.exports = Object.assign(prompt, { prompt, prompts, inject, override });
|