UNPKG

7.44 kBJavaScriptView Raw
1"use strict";
2
3var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
4
5var _Object$defineProperty = require("@babel/runtime-corejs3/core-js-stable/object/define-property");
6
7_Object$defineProperty(exports, "__esModule", {
8 value: true
9});
10
11exports.default = _default;
12
13var _assign = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/object/assign"));
14
15var _isArray = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/array/is-array"));
16
17var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/map"));
18
19var _some = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/some"));
20
21var _filter = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/filter"));
22
23var _find = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/find"));
24
25var _includes = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/includes"));
26
27/* ========================================================================
28 * PROMPT BYPASSING
29 * -----------------
30 * this allows a user to bypass a prompt by supplying input before
31 * the prompts are run. we handle input differently depending on the
32 * type of prompt that's in play (ie "y" means "true" for a confirm prompt)
33 * ======================================================================== */
34/////
35// HELPER FUNCTIONS
36//
37// pull the "value" out of a choice option
38const getChoiceValue = choice => {
39 const isObject = typeof choice === 'object';
40
41 if (isObject && choice.value != null) {
42 return choice.value;
43 }
44
45 if (isObject && choice.name != null) {
46 return choice.name;
47 }
48
49 if (isObject && choice.key != null) {
50 return choice.key;
51 }
52
53 return choice;
54}; // check if a bypass value matches some aspect of
55// a particular choice option (index, value, key, etc)
56
57
58const choiceMatchesValue = (choice, choiceIdx, value) => {
59 const choiceValue = getChoiceValue(choice);
60 const valueMatchesChoice = choiceValue && choiceValue.toLowerCase() === value.toLowerCase();
61 const valueMatchesChoiceKey = typeof choice.key === 'string' && choice.key.toLowerCase() === value.toLowerCase();
62 const valueMatchesChoiceName = typeof choice.name === 'string' && choice.name.toLowerCase() === value.toLowerCase();
63 const valueMatchesChoiceIndex = choiceIdx.toString() === value;
64 return valueMatchesChoice || valueMatchesChoiceKey || valueMatchesChoiceName || valueMatchesChoiceIndex;
65}; // check if a value matches a particular set of flagged input options
66
67
68const isFlag = (list, v) => (0, _includes.default)(list).call(list, v.toLowerCase()); // input values that represent different types of responses
69
70
71const flag = {
72 isTrue: v => isFlag(['yes', 'y', 'true', 't'], v),
73 isFalse: v => isFlag(['no', 'n', 'false', 'f'], v),
74 isPrompt: v => /^_+$/.test(v)
75}; // generic list bypass function. used for all types of lists.
76// accepts value, index, or key as matching criteria
77
78const listTypeBypass = (v, prompt) => {
79 var _context;
80
81 const choice = (0, _find.default)(_context = prompt.choices).call(_context, (c, idx) => choiceMatchesValue(c, idx, v));
82
83 if (choice != null) {
84 return getChoiceValue(choice);
85 }
86
87 throw Error('invalid choice');
88}; /////
89// BYPASS FUNCTIONS
90//
91// list of prompt bypass functions by prompt type
92
93
94const typeBypass = {
95 confirm(v) {
96 if (flag.isTrue(v)) {
97 return true;
98 }
99
100 if (flag.isFalse(v)) {
101 return false;
102 }
103
104 throw Error('invalid input');
105 },
106
107 checkbox(v, prompt) {
108 const valList = v.split(',');
109 const valuesNoMatch = (0, _filter.default)(valList).call(valList, val => {
110 var _context2;
111
112 return !(0, _some.default)(_context2 = prompt.choices).call(_context2, (c, idx) => choiceMatchesValue(c, idx, val));
113 });
114
115 if (valuesNoMatch.length) {
116 throw Error(`no match for "${valuesNoMatch.join('", "')}"`);
117 }
118
119 return (0, _map.default)(valList).call(valList, val => {
120 var _context3;
121
122 return getChoiceValue((0, _find.default)(_context3 = prompt.choices).call(_context3, (c, idx) => choiceMatchesValue(c, idx, val)));
123 });
124 },
125
126 list: listTypeBypass,
127 rawlist: listTypeBypass,
128 expand: listTypeBypass
129}; /////
130// MAIN LOGIC
131//
132// returns new prompts, initial answers object, and any failures
133
134function _default(prompts, bypassArr, plop) {
135 const noop = [prompts, {}, []]; // bail out if we don't have prompts or bypass data
136
137 if (!(0, _isArray.default)(prompts)) {
138 return noop;
139 }
140
141 if (bypassArr.length === 0) {
142 return noop;
143 } // pull registered prompts out of inquirer
144
145
146 const {
147 prompts: inqPrompts
148 } = plop.inquirer.prompt;
149 const answers = {};
150 const bypassFailures = []; // generate a list of pompts that the user is bypassing
151
152 const bypassedPrompts = (0, _filter.default)(prompts).call(prompts, function (p, idx) {
153 // if the user didn't provide value for this prompt, skip it
154 if (idx >= bypassArr.length) {
155 return false;
156 }
157
158 const val = bypassArr[idx].toString(); // if the user asked to be given this prompt, skip it
159
160 if (flag.isPrompt(val)) {
161 return false;
162 } // if this prompt is dynamic, throw error because we can't know if
163 // the pompt bypass values given line up with the path this user
164 // has taken through the prompt tree.
165
166
167 if (typeof p.when === 'function') {
168 bypassFailures.push(`You can not bypass conditional prompts: ${p.name}`);
169 return false;
170 }
171
172 try {
173 const inqPrompt = inqPrompts[p.type] || {}; // try to find a bypass function to run
174
175 const bypass = p.bypass || inqPrompt.bypass || typeBypass[p.type] || null; // get the real answer data out of the bypass function and attach it
176 // to the answer data object
177
178 const bypassIsFunc = typeof bypass === 'function';
179 const value = bypassIsFunc ? bypass.call(null, val, p) : val; // if inquirer prompt has a filter function - call it
180
181 const answer = (0, _filter.default)(p) ? (0, _filter.default)(p).call(p, value) : value; // if inquirer prompt has a validate function - call it
182
183 if (p.validate) {
184 const validation = p.validate(value);
185
186 if (validation !== true) {
187 // if validation failed return validation error
188 bypassFailures.push(validation);
189 return false;
190 }
191 }
192
193 answers[p.name] = answer;
194 } catch (err) {
195 // if we encounter an error above... assume the bypass value was invalid
196 bypassFailures.push(`The "${p.name}" prompt did not recognize "${val}" as a valid ${p.type} value (ERROR: ${err.message})`);
197 return false;
198 } // if we got this far, we successfully bypassed this prompt
199
200
201 return true;
202 }); // rip out any prompts that have been bypassed
203
204 const promptsAfterBypass = [// first prompt will copy the bypass answer data so it's available
205 // for prompts and actions to use
206 {
207 when: data => ((0, _assign.default)(data, answers), false)
208 }, // inlcude any prompts that were NOT bypassed
209 ...(0, _filter.default)(prompts).call(prompts, p => !(0, _includes.default)(bypassedPrompts).call(bypassedPrompts, p))]; // if we have failures, throw the first one
210
211 if (bypassFailures.length) {
212 throw Error(bypassFailures[0]);
213 } else {
214 // return the prompts that still need to be run
215 return [promptsAfterBypass, answers];
216 } // BOOM!
217
218}
\No newline at end of file