UNPKG

6.36 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.default = _default;
7
8var _co = _interopRequireDefault(require("co"));
9
10var _promptBypass = _interopRequireDefault(require("./prompt-bypass"));
11
12var buildInActions = _interopRequireWildcard(require("./actions"));
13
14function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
15
16function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; if (obj != null) { var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
17
18function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
20function _default(plopfileApi, flags) {
21 let abort; // triggers inquirer with the correct prompts for this generator
22 // returns a promise that resolves with the user's answers
23
24 const runGeneratorPrompts = _co.default.wrap(function* (genObject, bypassArr = []) {
25 const {
26 prompts
27 } = genObject;
28
29 if (prompts == null) {
30 throw Error(`${genObject.name} has no prompts`);
31 }
32
33 if (typeof prompts === 'function') {
34 return yield prompts(plopfileApi.inquirer);
35 } // handle bypass data when provided
36
37
38 const [promptsAfterBypass, bypassAnswers] = (0, _promptBypass.default)(prompts, bypassArr, plopfileApi);
39 return yield plopfileApi.inquirer.prompt(promptsAfterBypass).then(answers => Object.assign(answers, bypassAnswers));
40 }); // Run the actions for this generator
41
42
43 const runGeneratorActions = _co.default.wrap(function* (genObject, data = {}, hooks = {}) {
44 const noop = () => {};
45
46 const {
47 onSuccess = noop,
48 // runs after each successful action
49 onFailure = noop,
50 // runs after each failed action
51 onComment = noop // runs for each comment line in the actions array
52
53 } = hooks;
54 const changes = []; // array of changed made by the actions
55
56 const failures = []; // array of actions that failed
57
58 let {
59 actions
60 } = genObject; // the list of actions to execute
61
62 const customActionTypes = getCustomActionTypes();
63 const actionTypes = Object.assign({}, customActionTypes, buildInActions);
64 abort = false; // if action is a function, run it to get our array of actions
65
66 if (typeof actions === 'function') {
67 actions = actions(data);
68 } // if actions are not defined... we cannot proceed.
69
70
71 if (actions == null) {
72 throw Error(`${genObject.name} has no actions`);
73 } // if actions are not an array, invalid!
74
75
76 if (!(actions instanceof Array)) {
77 throw Error(`${genObject.name} has invalid actions`);
78 }
79
80 for (let [actionIdx, action] of actions.entries()) {
81 // including strings in the actions array is used for commenting
82 if (typeof action === 'string' && abort) {
83 continue;
84 }
85
86 if (typeof action === 'string') {
87 onComment(action);
88 continue;
89 }
90
91 const actionIsFunction = typeof action === 'function';
92 const actionCfg = actionIsFunction ? {
93 type: 'function'
94 } : action;
95 const actionLogic = actionIsFunction ? action : actionTypes[actionCfg.type]; // bail out if a previous action aborted
96
97 if (abort) {
98 const failure = {
99 type: actionCfg.type || '',
100 path: actionCfg.path || '',
101 error: 'Aborted due to previous action failure'
102 };
103 onFailure(failure);
104 failures.push(failure);
105 continue;
106 }
107
108 actionCfg.force = flags.force === true || actionCfg.force === true;
109
110 if (typeof actionLogic !== 'function') {
111 if (actionCfg.abortOnFail !== false) {
112 abort = true;
113 }
114
115 const failure = {
116 type: actionCfg.type || '',
117 path: actionCfg.path || '',
118 error: `Invalid action (#${actionIdx + 1})`
119 };
120 onFailure(failure);
121 failures.push(failure);
122 continue;
123 }
124
125 try {
126 const actionResult = yield executeActionLogic(actionLogic, actionCfg, data);
127 onSuccess(actionResult);
128 changes.push(actionResult);
129 } catch (failure) {
130 if (actionCfg.abortOnFail !== false) {
131 abort = true;
132 }
133
134 onFailure(failure);
135 failures.push(failure);
136 }
137 }
138
139 return {
140 changes,
141 failures
142 };
143 }); // handle action logic
144
145
146 const executeActionLogic = _co.default.wrap(function* (action, cfg, data) {
147 const type = cfg.type || '';
148 let cfgData = cfg.data || {}; // data can also be a function that returns a data object
149
150 if (typeof cfgData === 'function') {
151 cfgData = yield cfgData();
152 } // track keys that can be applied to the main data scope
153
154
155 const cfgDataKeys = Object.keys(cfgData).filter(k => typeof data[k] === 'undefined'); // copy config data into main data scope so it's available for templates
156
157 cfgDataKeys.forEach(k => {
158 data[k] = cfgData[k];
159 });
160 return yield Promise.resolve(action(data, cfg, plopfileApi)).then( // show the resolved value in the console
161 result => ({
162 type,
163 path: typeof result === 'string' ? result : JSON.stringify(result)
164 }), // a rejected promise is treated as a failure
165 err => {
166 throw {
167 type,
168 path: '',
169 error: err.message || err.toString()
170 };
171 }) // cleanup main data scope so config data doesn't leak
172 .finally(() => cfgDataKeys.forEach(k => {
173 delete data[k];
174 }));
175 }); // request the list of custom actions from the plopfile
176
177
178 function getCustomActionTypes() {
179 return plopfileApi.getActionTypeList().reduce(function (types, name) {
180 types[name] = plopfileApi.getActionType(name);
181 return types;
182 }, {});
183 }
184
185 return {
186 runGeneratorActions,
187 runGeneratorPrompts
188 };
189}
\No newline at end of file