@suitegeezus/suitecloud-stacker 25.2.127
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/.idea/compiler.xml +6 -0
- package/.idea/git_toolbox_blame.xml +6 -0
- package/.idea/git_toolbox_prj.xml +15 -0
- package/.idea/misc.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/suitecloud-stacker.iml +9 -0
- package/.idea/vcs.xml +6 -0
- package/CONTRIBUTING.md +72 -0
- package/README.md +242 -0
- package/bin/updateModule.d.ts +6 -0
- package/bin/updateModule.js +12 -0
- package/commands/CONTRIBUTING.md +7 -0
- package/commands/accountManageauth.d.ts +93 -0
- package/commands/accountManageauth.js +228 -0
- package/commands/accountSetup.d.ts +56 -0
- package/commands/accountSetup.js +218 -0
- package/commands/customhook/compiless.d.ts +10 -0
- package/commands/customhook/compiless.js +46 -0
- package/commands/customhook/watchss.d.ts +14 -0
- package/commands/customhook/watchss.js +77 -0
- package/commands/fileImport.d.ts +31 -0
- package/commands/fileImport.js +503 -0
- package/commands/fileList.d.ts +19 -0
- package/commands/fileList.js +40 -0
- package/commands/fileUpload.d.ts +52 -0
- package/commands/fileUpload.js +355 -0
- package/commands/generic.d.ts +5 -0
- package/commands/generic.js +13 -0
- package/commands/objectImport.d.ts +32 -0
- package/commands/objectImport.js +287 -0
- package/commands/objectList.d.ts +13 -0
- package/commands/objectList.js +78 -0
- package/commands/projectCreate.d.ts +31 -0
- package/commands/projectCreate.js +506 -0
- package/commands/projectDeploy.d.ts +25 -0
- package/commands/projectDeploy.js +371 -0
- package/commands/projectPackage.d.ts +10 -0
- package/commands/projectPackage.js +32 -0
- package/commands/projectValidate.d.ts +21 -0
- package/commands/projectValidate.js +112 -0
- package/commands/sdfAcs_authmap.d.ts +15 -0
- package/commands/sdfAcs_authmap.js +26 -0
- package/commands/sdfAcs_clean.d.ts +20 -0
- package/commands/sdfAcs_clean.js +22 -0
- package/deleteManifest.cjs +11 -0
- package/demo.md +26 -0
- package/index.d.ts +284 -0
- package/lib/MakeJestTestsFromDeploy.d.ts +13 -0
- package/lib/MakeJestTestsFromDeploy.js +60 -0
- package/lib/addGitKeep.d.ts +5 -0
- package/lib/addGitKeep.js +40 -0
- package/lib/addSdfObjectDirs.d.ts +5 -0
- package/lib/addSdfObjectDirs.js +16 -0
- package/lib/callCli.d.ts +7 -0
- package/lib/callCli.js +26 -0
- package/lib/compileHelper.d.ts +44 -0
- package/lib/compileHelper.js +196 -0
- package/lib/deleteProjectJson.d.ts +6 -0
- package/lib/deleteProjectJson.js +16 -0
- package/lib/deployFileHelper.d.ts +77 -0
- package/lib/deployFileHelper.js +249 -0
- package/lib/handleRootProjectJson.d.ts +10 -0
- package/lib/handleRootProjectJson.js +30 -0
- package/lib/isProd.d.ts +9 -0
- package/lib/isProd.js +13 -0
- package/lib/logHelper.d.ts +5 -0
- package/lib/logHelper.js +13 -0
- package/lib/logger.d.ts +6 -0
- package/lib/logger.js +10 -0
- package/lib/makeDeployXml.d.ts +6 -0
- package/lib/makeDeployXml.js +30 -0
- package/lib/makeJest.d.ts +12 -0
- package/lib/makeJest.js +58 -0
- package/lib/makeManifestXml.d.ts +6 -0
- package/lib/makeManifestXml.js +21 -0
- package/lib/makeProjectJson.d.ts +6 -0
- package/lib/makeProjectJson.js +16 -0
- package/lib/onErrorHelper.d.ts +31 -0
- package/lib/onErrorHelper.js +93 -0
- package/lib/pathHelpers.d.ts +133 -0
- package/lib/pathHelpers.js +428 -0
- package/lib/pause.d.ts +6 -0
- package/lib/pause.js +10 -0
- package/lib/projectJsonHelpers.d.ts +29 -0
- package/lib/projectJsonHelpers.js +92 -0
- package/lib/promptHelpers.d.ts +77 -0
- package/lib/promptHelpers.js +195 -0
- package/lib/removeFiles.d.ts +20 -0
- package/lib/removeFiles.js +46 -0
- package/lib/sdf.d.ts +11 -0
- package/lib/sdf.js +158 -0
- package/lib/spawnSuitecloudChild.d.ts +30 -0
- package/lib/spawnSuitecloudChild.js +88 -0
- package/lib/switchAuth.d.ts +17 -0
- package/lib/switchAuth.js +23 -0
- package/lib/tempFileHelper.d.ts +29 -0
- package/lib/tempFileHelper.js +70 -0
- package/lib/updateModule.d.ts +10 -0
- package/lib/updateModule.js +79 -0
- package/lib/validators.d.ts +12 -0
- package/lib/validators.js +25 -0
- package/package.json +38 -0
- package/safeCommands.d.ts +95 -0
- package/safeCommands.js +959 -0
- package/sdf.config.js +15 -0
- package/sdf.exe.js +16 -0
- package/templates/customizations.projectroot.d.ts +74 -0
- package/templates/makeModuleTypeDef.d.ts +5 -0
- package/templates/makeModuleTypeDef.js +29 -0
- package/templates/sdfGitIgnore.txt +42 -0
- package/templates/suitecloud.config.js +17 -0
- package/templates/tsconfig.ss21.projectroot.json +64 -0
- package/types/colors.d.ts +43 -0
package/safeCommands.js
ADDED
|
@@ -0,0 +1,959 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file sdf/safeCommands.ts
|
|
4
|
+
* @author Gerald Gillespie <gerald.gillespie@fullscript.com>
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.makeSafeExports = exports.caseCommands = exports.defaultCommands = exports.stack = exports.makeSuiteCloudConfig = exports.genericCommandProxy = exports.makeFunctionProxy = exports.accountManageAuthCommand = exports.accountSetupCommand = exports.fileUploadCommand = exports.objectImportCommand = exports.objectListCommand = exports.projectValidateCommand = exports.projectDeployCommand = exports.projectCreateCommand = exports.fileImportCommand = exports.promptHelpers = void 0;
|
|
8
|
+
const makeManifest = require("./lib/makeManifestXml");
|
|
9
|
+
const makeDeploy = require("./lib/makeDeployXml");
|
|
10
|
+
const removeFiles = require("./lib/removeFiles");
|
|
11
|
+
const process = require("node:process");
|
|
12
|
+
const fs = require("node:fs");
|
|
13
|
+
const nodePath = require("node:path");
|
|
14
|
+
const promptHelper = require("./lib/promptHelpers");
|
|
15
|
+
const pathHelpers = require("./lib/pathHelpers");
|
|
16
|
+
const projectJsonHelpers = require("./lib/projectJsonHelpers");
|
|
17
|
+
const accountManageAuth = require("./commands/accountManageauth");
|
|
18
|
+
const accountSetup = require("./commands/accountSetup");
|
|
19
|
+
const onErrorHelper = require("./lib/onErrorHelper");
|
|
20
|
+
const spawnSuitecloudChild = require("./lib/spawnSuitecloudChild");
|
|
21
|
+
const tempFileHelper = require("./lib/tempFileHelper");
|
|
22
|
+
const fileList = require("./commands/fileList");
|
|
23
|
+
const fileImports = require("./commands/fileImport");
|
|
24
|
+
const projectCreates = require("./commands/projectCreate");
|
|
25
|
+
const projectDeploys = require("./commands/projectDeploy");
|
|
26
|
+
const fileUpload = require("./commands/fileUpload");
|
|
27
|
+
const projectValidates = require("./commands/projectValidate");
|
|
28
|
+
const objectLists = require("./commands/objectList");
|
|
29
|
+
const objectImports = require("./commands/objectImport");
|
|
30
|
+
const projectPackages = require("./commands/projectPackage");
|
|
31
|
+
const onErrorHelper_1 = require("./lib/onErrorHelper");
|
|
32
|
+
const watchss_1 = require("./commands/customhook/watchss");
|
|
33
|
+
const compiless_1 = require("./commands/customhook/compiless");
|
|
34
|
+
const promptHelpers_1 = require("./lib/promptHelpers");
|
|
35
|
+
exports.promptHelpers = promptHelper;
|
|
36
|
+
exports.fileImportCommand = fileImports;
|
|
37
|
+
exports.projectCreateCommand = projectCreates;
|
|
38
|
+
exports.projectDeployCommand = projectDeploys;
|
|
39
|
+
exports.projectValidateCommand = projectValidates;
|
|
40
|
+
exports.objectListCommand = objectLists;
|
|
41
|
+
exports.objectImportCommand = objectImports;
|
|
42
|
+
exports.fileUploadCommand = fileUpload;
|
|
43
|
+
exports.accountSetupCommand = accountSetup;
|
|
44
|
+
exports.accountManageAuthCommand = accountManageAuth;
|
|
45
|
+
const SHARED = {
|
|
46
|
+
DEBUG: false,
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* @internal
|
|
50
|
+
* @description - clean up some files
|
|
51
|
+
* @param fileNames
|
|
52
|
+
* @param root
|
|
53
|
+
*/
|
|
54
|
+
const cleanup = (fileNames, root) => {
|
|
55
|
+
removeFiles({
|
|
56
|
+
fileNames,
|
|
57
|
+
doBackup: false,
|
|
58
|
+
root
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* @description - if blocked then an error is thrown (useful for temporarily neutering a capability)
|
|
63
|
+
* - the original candidate can satisfy the handler then it will
|
|
64
|
+
* - otherwise the replacement will
|
|
65
|
+
* @param {function} candidate - the root object
|
|
66
|
+
* @param {boolean} doBlock - whether to block access to the true candidate or not -- useful in debugging
|
|
67
|
+
* @param {boolean} debug - Whether to print useful values such as the property, value, arguments
|
|
68
|
+
*/
|
|
69
|
+
const makeFunctionProxy = (candidate, doBlock, debug) => {
|
|
70
|
+
if (candidate === null || (!['function', 'object'].includes(typeof candidate))) {
|
|
71
|
+
if (debug)
|
|
72
|
+
console.log(exports.promptHelpers.goColor('SUBTLE', 'skipping proxy for', typeof candidate, JSON.stringify({
|
|
73
|
+
doBlock,
|
|
74
|
+
debug
|
|
75
|
+
}, null, 2), false));
|
|
76
|
+
if (doBlock)
|
|
77
|
+
throw Error('blocked');
|
|
78
|
+
return candidate;
|
|
79
|
+
}
|
|
80
|
+
// console.log(promptHelpers.goColor('SUBTLE', 'making proxy', false));
|
|
81
|
+
if (debug)
|
|
82
|
+
console.log(exports.promptHelpers.goColor('SUBTLE', 'for', typeof candidate, JSON.stringify({
|
|
83
|
+
doBlock,
|
|
84
|
+
debug
|
|
85
|
+
}, null, 2), false));
|
|
86
|
+
return new Proxy(candidate, {
|
|
87
|
+
get(target, key, receiver) {
|
|
88
|
+
if (debug)
|
|
89
|
+
console.log(exports.promptHelpers.goColor('SUBTLE', 'accessing proxied object', JSON.stringify({
|
|
90
|
+
key,
|
|
91
|
+
doBlock,
|
|
92
|
+
debug
|
|
93
|
+
}, null, 2), false));
|
|
94
|
+
if (doBlock === true)
|
|
95
|
+
throw Error('blocked');
|
|
96
|
+
if (Array.isArray(doBlock) && doBlock.includes(key))
|
|
97
|
+
throw Error('blocked');
|
|
98
|
+
const toReturn = Reflect.get(target, key, receiver);
|
|
99
|
+
return (0, exports.makeFunctionProxy)(toReturn, doBlock, debug);
|
|
100
|
+
},
|
|
101
|
+
set(target, key, value, receiver) {
|
|
102
|
+
if (debug)
|
|
103
|
+
console.log(exports.promptHelpers.goColor('SUBTLE', 'accessing proxied object', JSON.stringify({
|
|
104
|
+
key,
|
|
105
|
+
value,
|
|
106
|
+
doBlock,
|
|
107
|
+
debug
|
|
108
|
+
}, null, 2), false));
|
|
109
|
+
if (doBlock === true)
|
|
110
|
+
throw Error('blocked');
|
|
111
|
+
if (Array.isArray(doBlock) && doBlock.includes(key))
|
|
112
|
+
throw Error('blocked');
|
|
113
|
+
return Reflect.set(target, key, value, receiver);
|
|
114
|
+
},
|
|
115
|
+
apply(target, thisArg, argArray) {
|
|
116
|
+
if (debug)
|
|
117
|
+
console.log(exports.promptHelpers.goColor('SUBTLE', 'running function', JSON.stringify({ argArray }, null, 2), false));
|
|
118
|
+
if (doBlock === true)
|
|
119
|
+
throw Error('blocked');
|
|
120
|
+
if (typeof target === 'function')
|
|
121
|
+
return Reflect.apply(target, thisArg, argArray);
|
|
122
|
+
throw new Error('not a function');
|
|
123
|
+
},
|
|
124
|
+
has(target, key) {
|
|
125
|
+
if (debug)
|
|
126
|
+
console.log(exports.promptHelpers.goColor('SUBTLE', 'accessing proxied function', JSON.stringify({ key }), false));
|
|
127
|
+
if (doBlock === true)
|
|
128
|
+
throw Error('blocked');
|
|
129
|
+
return Reflect.has(target, key);
|
|
130
|
+
},
|
|
131
|
+
isExtensible( /* target */) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
};
|
|
136
|
+
exports.makeFunctionProxy = makeFunctionProxy;
|
|
137
|
+
/**
|
|
138
|
+
* @description - converts an "existing" command object into a proxy for both the existing and missing pieces so you can track the inputs and outputs
|
|
139
|
+
* @param {object} existing
|
|
140
|
+
* @param {boolean} doBlock
|
|
141
|
+
* @param {boolean} debug
|
|
142
|
+
*/
|
|
143
|
+
const genericCommandProxy = (existing, doBlock, debug) => {
|
|
144
|
+
try {
|
|
145
|
+
const noop = (options) => options;
|
|
146
|
+
return new Proxy(existing, {
|
|
147
|
+
get(target, key, receiver) {
|
|
148
|
+
try {
|
|
149
|
+
if (Reflect.has(target, key)) {
|
|
150
|
+
return (0, exports.makeFunctionProxy)(Reflect.get(target, key, receiver), doBlock, debug);
|
|
151
|
+
}
|
|
152
|
+
if (typeof key === 'string' && /:/.test(key)) {
|
|
153
|
+
return (0, exports.makeFunctionProxy)({
|
|
154
|
+
projectFolder: null,
|
|
155
|
+
beforeExecuting: noop,
|
|
156
|
+
onCompleted: noop,
|
|
157
|
+
onError: noop,
|
|
158
|
+
}, doBlock, debug);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
console.error(err);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
console.error(err);
|
|
169
|
+
throw err;
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
exports.genericCommandProxy = genericCommandProxy;
|
|
173
|
+
/**
|
|
174
|
+
* @deprecated
|
|
175
|
+
* @description - Take commands and export safe commands.
|
|
176
|
+
* - Proxies the function of each command
|
|
177
|
+
* - Anytime the `authid` option is seen it will strip it out as this is coming from native.
|
|
178
|
+
* - Will replace the `authid` option with a value that is taken from a transient .project.json file. Note that the
|
|
179
|
+
* transient file will only exist if it was called properly.
|
|
180
|
+
* @param options
|
|
181
|
+
*/
|
|
182
|
+
const makeSuiteCloudConfig = (options, authFolderMap, extras) => {
|
|
183
|
+
cleanup(['manifest.xml', 'deploy.xml'], process.cwd());
|
|
184
|
+
let authid = null;
|
|
185
|
+
let projectFolder = null;
|
|
186
|
+
let debugInJson = null;
|
|
187
|
+
let { debug } = { debug: false, ...extras };
|
|
188
|
+
try {
|
|
189
|
+
// make manifest
|
|
190
|
+
// temp
|
|
191
|
+
const projectJson = fs.readFileSync(nodePath.join(process.cwd(), '.project.json'), { encoding: 'utf8' });
|
|
192
|
+
({ defaultAuthId: authid, defaultProjectFolder: projectFolder, debug: debugInJson } = {
|
|
193
|
+
defaultAuthId: null,
|
|
194
|
+
defaultProjectFolder: null,
|
|
195
|
+
debug: null,
|
|
196
|
+
...JSON.parse(projectJson || "null")
|
|
197
|
+
});
|
|
198
|
+
if (projectFolder === null && authid !== null)
|
|
199
|
+
projectFolder = authid;
|
|
200
|
+
// debug in .project.json means it was requested on the command line so it is an override
|
|
201
|
+
if (debugInJson === true)
|
|
202
|
+
debug = true;
|
|
203
|
+
if (debugInJson === false)
|
|
204
|
+
debug = false;
|
|
205
|
+
if (authFolderMap && typeof authFolderMap === 'object') {
|
|
206
|
+
for (const [authMapKey, folders] of Object.entries(authFolderMap)) {
|
|
207
|
+
if (authMapKey !== authid)
|
|
208
|
+
continue;
|
|
209
|
+
if (!folders.includes(projectFolder))
|
|
210
|
+
throw new Error(`${authMapKey} is not allowed to work with folder ${projectFolder}. Check your suitecloud.config.js`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
const deferredJobs = [];
|
|
214
|
+
// delete the project.json files
|
|
215
|
+
if (projectFolder !== null) {
|
|
216
|
+
deferredJobs.push(() => cleanup(['manifest.xml', 'deploy.xml'], nodePath.join(process.cwd(), projectFolder)), () => makeManifest(nodePath.join(process.cwd(), projectFolder, 'manifest.xml'), projectFolder), () => makeDeploy(nodePath.join(process.cwd(), projectFolder, 'deploy.xml')));
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
deferredJobs.push(() => makeManifest(nodePath.join(process.cwd(), 'manifest.xml'), 'unknown'), () => makeDeploy(nodePath.join(process.cwd(), 'deploy.xml')));
|
|
220
|
+
console.log('No project folder found ***************');
|
|
221
|
+
}
|
|
222
|
+
// for now execute them here as everything is synchronous so far
|
|
223
|
+
deferredJobs.forEach((job) => job());
|
|
224
|
+
if (debug)
|
|
225
|
+
console.log({ cwd: process.cwd() });
|
|
226
|
+
return new Proxy(options, {
|
|
227
|
+
get(outer, key, receiver) {
|
|
228
|
+
if (debug)
|
|
229
|
+
console.log('accessing outer', { key });
|
|
230
|
+
// in case this file is imported by another in order to read the commands
|
|
231
|
+
if (['then', 'catch', 'finally'].includes(key))
|
|
232
|
+
return Reflect.get(outer, key, receiver);
|
|
233
|
+
if (key === 'default')
|
|
234
|
+
return { ...options, authFolderMap, };
|
|
235
|
+
if (['projectFolder', 'defaultProjectFolder'].includes(key)) {
|
|
236
|
+
// temporary
|
|
237
|
+
return projectFolder;
|
|
238
|
+
}
|
|
239
|
+
if (key === 'commands')
|
|
240
|
+
return new Proxy(options?.commands || {}, {
|
|
241
|
+
get(target, command, receiver) {
|
|
242
|
+
if (debug)
|
|
243
|
+
console.log('accessing inner', { command });
|
|
244
|
+
let commandSpecificObject = Reflect.has(target, command)
|
|
245
|
+
? Reflect.get(target, command, receiver)
|
|
246
|
+
: {};
|
|
247
|
+
return new Proxy(commandSpecificObject, {
|
|
248
|
+
get(target, property, receiver) {
|
|
249
|
+
if (debug)
|
|
250
|
+
console.log('accessing command', { property });
|
|
251
|
+
if (['projectFolder', 'defaultProjectFolder'].includes(command)) {
|
|
252
|
+
// temporary
|
|
253
|
+
return projectFolder + '2';
|
|
254
|
+
}
|
|
255
|
+
const value = Reflect.get(target, property, receiver);
|
|
256
|
+
if (typeof value === 'function')
|
|
257
|
+
return (0, exports.makeFunctionProxy)(value, false, debug);
|
|
258
|
+
// assume any other property is a function until we know more
|
|
259
|
+
return (0, exports.makeFunctionProxy)((options) => options, false, debug);
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
const value = Reflect.get(outer, key, receiver);
|
|
265
|
+
if (debug)
|
|
266
|
+
console.log({ key, value });
|
|
267
|
+
return value;
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
if (debug)
|
|
273
|
+
console.error(error);
|
|
274
|
+
cleanup(['manifest.xml', 'deploy.xml', 'project.json', '.project.json'], nodePath.join(process.cwd()));
|
|
275
|
+
if (projectFolder !== null)
|
|
276
|
+
cleanup(['manifest.xml', 'deploy.xml', 'project.json', '.project.json'], nodePath.join(process.cwd(), projectFolder));
|
|
277
|
+
throw error;
|
|
278
|
+
}
|
|
279
|
+
cleanup(['manifest.xml', 'deploy.xml', 'project.json', '.project.json'], nodePath.join(process.cwd()));
|
|
280
|
+
if (projectFolder !== null)
|
|
281
|
+
cleanup(['manifest.xml', 'deploy.xml', 'project.json', '.project.json'], nodePath.join(process.cwd(), projectFolder));
|
|
282
|
+
};
|
|
283
|
+
exports.makeSuiteCloudConfig = makeSuiteCloudConfig;
|
|
284
|
+
/** @internal
|
|
285
|
+
* @example
|
|
286
|
+
* stacks['file:import'].beforeExecuting = []
|
|
287
|
+
* */
|
|
288
|
+
const stacks = {};
|
|
289
|
+
/**
|
|
290
|
+
* @description - curried
|
|
291
|
+
* @param {string} command - e.g. 'file:import'
|
|
292
|
+
* @param {string} [origin] - e.g. a property of the handling library that was used
|
|
293
|
+
* @param {string} [projectFolder]
|
|
294
|
+
*/
|
|
295
|
+
const done = (command, origin, projectFolder) => {
|
|
296
|
+
/** @ internal
|
|
297
|
+
* @description - async because any one of the internal stacks might contain async methods
|
|
298
|
+
*/
|
|
299
|
+
return (options) => {
|
|
300
|
+
if (stacks[command].onError.length === 0)
|
|
301
|
+
stacks[command].onError.push(
|
|
302
|
+
// add a default error handler that will help error forensics
|
|
303
|
+
(error) => onErrorHelper.detectOriginAndReturn(command, error));
|
|
304
|
+
if (stacks[command].onCompleted.length === 0)
|
|
305
|
+
stacks[command].onCompleted.push(
|
|
306
|
+
// add a default error handler that will help error forensics
|
|
307
|
+
(options) => options);
|
|
308
|
+
const starter = { stacked: true };
|
|
309
|
+
if (projectFolder)
|
|
310
|
+
starter[projectFolder] = projectFolder;
|
|
311
|
+
//
|
|
312
|
+
return Object.entries(stacks[command]).reduce((accumulator, [methodName, methods], i) => {
|
|
313
|
+
// iterate over them calling each method
|
|
314
|
+
accumulator[methodName] = async (originalOptions) => {
|
|
315
|
+
if (SHARED.DEBUG)
|
|
316
|
+
await exports.promptHelpers.promptUser({
|
|
317
|
+
message: `pause from \`done\` prior to calling ${methodName}[${i}]`,
|
|
318
|
+
});
|
|
319
|
+
// validation
|
|
320
|
+
if (['beforeExecuting'].includes(methodName) && !originalOptions?.command) {
|
|
321
|
+
process.stdout.write(exports.promptHelpers.goColor('SUBTLE', '\n', 'options passed in ', originalOptions));
|
|
322
|
+
throw new Error(`This must be called from a valid command`);
|
|
323
|
+
}
|
|
324
|
+
const { command } = originalOptions;
|
|
325
|
+
// validation
|
|
326
|
+
if (methods.length === 0)
|
|
327
|
+
throw new Error(`The stack for ${origin}:${command}:${methodName} cannot be empty`);
|
|
328
|
+
// DRY validation
|
|
329
|
+
const optionsTest = (opts, index, method) => {
|
|
330
|
+
if (typeof opts === null || !['object', 'string'].includes(typeof opts))
|
|
331
|
+
throw new Error(`handler[${index}] for ${origin}:${command}:${methodName} must return the options to be stackable`);
|
|
332
|
+
process.stdout.write(exports.promptHelpers.goColor('SUBTLE', '\n', 'pop off ', [method?.origin ?? origin, methodName].join(':')));
|
|
333
|
+
// call with', JSON.stringify(opts, null, 2), '\n'));
|
|
334
|
+
};
|
|
335
|
+
// console.log({methods}, methods.map((m) => [Reflect.get(m, 'origin'), Reflect.get(m, 'command')]));
|
|
336
|
+
const newOptions = await methods.reduce(async (toPass, method, i) => {
|
|
337
|
+
// // @ts-expect-error is optional
|
|
338
|
+
// process.stdout.write(promptHelpers.goColor('SUBTLE', '\n', method?.origin, '[',i,']'));
|
|
339
|
+
const awaitedOptions = await toPass;
|
|
340
|
+
// validate
|
|
341
|
+
optionsTest(awaitedOptions, i, method);
|
|
342
|
+
// only some methods technically need to return the options but we return them always
|
|
343
|
+
return method(awaitedOptions);
|
|
344
|
+
}, Promise.resolve(originalOptions))
|
|
345
|
+
.catch((err) => {
|
|
346
|
+
process.stdout.write(exports.promptHelpers.goColor('INFO', '\n', 'error from ', origin, ': '));
|
|
347
|
+
// // @ts-expect-error yes it does
|
|
348
|
+
process.stdout.write(exports.promptHelpers.goColor('WARN', err?.message, '\n'));
|
|
349
|
+
// console.error(err);
|
|
350
|
+
throw err;
|
|
351
|
+
});
|
|
352
|
+
// validate
|
|
353
|
+
optionsTest(newOptions, methods.length - 1);
|
|
354
|
+
// always force this cleaning of projectJson
|
|
355
|
+
if (['onCompleted', 'onError'].includes(methodName)) {
|
|
356
|
+
// projectJsonHelpers.updateProjectJson(process.cwd(), Boolean(options?.allowLoops), 0);
|
|
357
|
+
}
|
|
358
|
+
return newOptions;
|
|
359
|
+
};
|
|
360
|
+
return accumulator;
|
|
361
|
+
}, starter);
|
|
362
|
+
};
|
|
363
|
+
};
|
|
364
|
+
/**
|
|
365
|
+
* @description -
|
|
366
|
+
* - Be careful about what you return. Each function in the stack should return options BUT some of the properties in a function are effectively `readonly` --
|
|
367
|
+
* i.e. they are not frozen and do not behave readonly until the very last handler.
|
|
368
|
+
* e.g. if you modify the property `options.arguments.authid` in `beforeExecuting` then you will be able to
|
|
369
|
+
* but the final SDF internal handler will not read the updated value.
|
|
370
|
+
* - Further some functions do not need to export options, BUT this process will pass them on to the next. This is an
|
|
371
|
+
* opportunity to modify those options, but it is a rare cases so be careful
|
|
372
|
+
* @param {string} command - e.g. 'file:import'
|
|
373
|
+
* @returns {Function}
|
|
374
|
+
*/
|
|
375
|
+
const stack = (command) => {
|
|
376
|
+
// if (!Reflect.has(stacks, command))
|
|
377
|
+
// process.stdout.write(promptHelpers.goColor('SUBTLE', 'overwriting stack for ', command, '|'));
|
|
378
|
+
// else
|
|
379
|
+
// process.stdout.write(promptHelpers.goColor('SUBTLE', 'creating stack for ', command, '|'));
|
|
380
|
+
// // process.stdout.write(goColor('SUBTLE', '\n', 'creating stack for ', methodName));
|
|
381
|
+
//
|
|
382
|
+
let origin = '';
|
|
383
|
+
// always re-initiate for a command
|
|
384
|
+
Reflect.set(stacks, command, {
|
|
385
|
+
beforeExecuting: [],
|
|
386
|
+
onCompleted: [],
|
|
387
|
+
onError: [],
|
|
388
|
+
});
|
|
389
|
+
/**
|
|
390
|
+
* @description
|
|
391
|
+
* @param {*} firstToStack
|
|
392
|
+
* @param {*[]} restToStack
|
|
393
|
+
* @returns {{stack: typeof stack; done: typeof done}}
|
|
394
|
+
*/
|
|
395
|
+
const innerStack = (firstToStack, ...restToStack) => {
|
|
396
|
+
// for easier troubleshooting
|
|
397
|
+
const noop = () => {
|
|
398
|
+
throw new Error(`You forgot to call \`done\` for ${command} stack`);
|
|
399
|
+
};
|
|
400
|
+
noop.stack = innerStack;
|
|
401
|
+
noop.add = innerStack;
|
|
402
|
+
try {
|
|
403
|
+
if (Array.isArray(restToStack) && restToStack.length > 0) {
|
|
404
|
+
console.log(restToStack);
|
|
405
|
+
[firstToStack, ...restToStack].map((to) => innerStack(to));
|
|
406
|
+
}
|
|
407
|
+
else if (typeof firstToStack === 'function')
|
|
408
|
+
return innerStack(firstToStack());
|
|
409
|
+
//
|
|
410
|
+
else if (typeof firstToStack !== 'object')
|
|
411
|
+
throw new Error('You must provide a stackable object');
|
|
412
|
+
//
|
|
413
|
+
else {
|
|
414
|
+
origin = firstToStack._origin || origin;
|
|
415
|
+
if (!Reflect.has(firstToStack, 'onError')) {
|
|
416
|
+
// a default error handler that stamps the command
|
|
417
|
+
Reflect.set(firstToStack, 'onError', (error) => onErrorHelper.detectOriginAndReturn(command, error));
|
|
418
|
+
}
|
|
419
|
+
if (!Reflect.get(firstToStack, 'isStackable'))
|
|
420
|
+
throw new Error(`The handler ${Reflect.get(firstToStack, 'name') || 'unnamed'} must have property \`isStackable\``);
|
|
421
|
+
Object.entries(firstToStack).forEach(
|
|
422
|
+
/**
|
|
423
|
+
*
|
|
424
|
+
* @param methodName e.g. 'beforeExecuting'
|
|
425
|
+
* @param method
|
|
426
|
+
* @param i
|
|
427
|
+
*/
|
|
428
|
+
([methodName, method], i) => {
|
|
429
|
+
if (typeof method !== 'function')
|
|
430
|
+
return;
|
|
431
|
+
// safety for unknown methods
|
|
432
|
+
if (!Reflect.get(stacks[command], methodName))
|
|
433
|
+
Reflect.set(stacks[command], methodName, []);
|
|
434
|
+
// if (i === 0) process.stdout.write(goColor('SUBTLE', '\n', 'adding to stack for ', methodName));
|
|
435
|
+
// else process.stdout.write(goColor('SUBTLE', '.'));
|
|
436
|
+
if (Reflect.get(stacks, command)[methodName].includes(method)) {
|
|
437
|
+
console.log({ methodName, command });
|
|
438
|
+
throw new Error('thi sis already int he stack');
|
|
439
|
+
}
|
|
440
|
+
method.origin = origin;
|
|
441
|
+
method.command = command;
|
|
442
|
+
// process.stdout.write(promptHelpers.goColor('SUBTLE', '\nadding ', i, ':', command, ':', origin, '|', typeof method));
|
|
443
|
+
Reflect.get(stacks, command)[methodName].push(method);
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
// finish
|
|
447
|
+
noop.done = done(command, origin);
|
|
448
|
+
return noop;
|
|
449
|
+
}
|
|
450
|
+
catch (e) {
|
|
451
|
+
console.error(e);
|
|
452
|
+
throw e;
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
const noop = () => {
|
|
456
|
+
throw new Error(`You forgot to "add" to the \`stack\` for the ${command} stack`);
|
|
457
|
+
};
|
|
458
|
+
noop.stack = innerStack;
|
|
459
|
+
noop.add = innerStack;
|
|
460
|
+
noop.done = () => {
|
|
461
|
+
throw new Error(`You must add a handler to the ${command} stack before calling done`);
|
|
462
|
+
};
|
|
463
|
+
return noop;
|
|
464
|
+
};
|
|
465
|
+
exports.stack = stack;
|
|
466
|
+
const defaultStackable = () => ({
|
|
467
|
+
_origin: 'defaultStackable',
|
|
468
|
+
beforeExecuting: (options) => options,
|
|
469
|
+
onCompleted: (options) => options,
|
|
470
|
+
onError: (error) => onErrorHelper.detectOriginAndReturn('defaultStackable', error),
|
|
471
|
+
isStackable: true,
|
|
472
|
+
});
|
|
473
|
+
/** @internal */
|
|
474
|
+
const printOptions = (opts) => {
|
|
475
|
+
const origin = 'printOptions';
|
|
476
|
+
return {
|
|
477
|
+
_origin: origin,
|
|
478
|
+
isStackable: true,
|
|
479
|
+
beforeExecuting: async (options) => {
|
|
480
|
+
try {
|
|
481
|
+
process.stdout.write(exports.promptHelpers.goColor(opts.messageType, '\nargs:', process.argv));
|
|
482
|
+
process.stdout.write(exports.promptHelpers.goColor(opts.messageType, '\noptions:', JSON.stringify(options, null, 2)));
|
|
483
|
+
const SDFENV = Object.fromEntries(Object.entries(process.env).filter(([key]) => key.startsWith('SUITECLOUD')));
|
|
484
|
+
process.stdout.write(exports.promptHelpers.goColor(opts.messageType, '\nsdf:', JSON.stringify(SDFENV, null, 2)));
|
|
485
|
+
if (options.arguments.runhooks !== 'quiet' && opts.confirm === true && !spawnSuitecloudChild.isChildProcess()) {
|
|
486
|
+
const choices = { 'Y': 'Yes' };
|
|
487
|
+
await promptHelper.promptChoices({
|
|
488
|
+
choices,
|
|
489
|
+
displayChoices: choices,
|
|
490
|
+
question: 'Continue? (Y)',
|
|
491
|
+
default: choices['Y'],
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
catch (e) {
|
|
496
|
+
console.error(e);
|
|
497
|
+
throw e;
|
|
498
|
+
}
|
|
499
|
+
return options;
|
|
500
|
+
},
|
|
501
|
+
onCompleted: async (options) => {
|
|
502
|
+
process.stdout.write(exports.promptHelpers.goColor(opts.messageType, '\n', JSON.stringify(options, null, 2)));
|
|
503
|
+
return options;
|
|
504
|
+
},
|
|
505
|
+
onError: async (error) => {
|
|
506
|
+
process.stdout.write(exports.promptHelpers.goColor(opts.messageType, '\n', error));
|
|
507
|
+
return error;
|
|
508
|
+
}
|
|
509
|
+
};
|
|
510
|
+
};
|
|
511
|
+
/** @internal */
|
|
512
|
+
const fakeManifest = (features) => {
|
|
513
|
+
const origin = 'fakeManifest';
|
|
514
|
+
return {
|
|
515
|
+
_origin: origin,
|
|
516
|
+
isStackable: true,
|
|
517
|
+
/**
|
|
518
|
+
* @description - the only reliable way to get the manifest location is to know the project folder
|
|
519
|
+
* which does not come through options. You must get it from the project.JSON
|
|
520
|
+
* @param options
|
|
521
|
+
*/
|
|
522
|
+
beforeExecuting: async (options) => {
|
|
523
|
+
const { defaultProjectFolder } = {
|
|
524
|
+
defaultProjectFolder: '',
|
|
525
|
+
...await projectJsonHelpers.updateProjectJson({}, [options.projectPath])
|
|
526
|
+
};
|
|
527
|
+
if (!defaultProjectFolder)
|
|
528
|
+
throw (0, onErrorHelper_1.makeError)(origin, new Error('Failed to read project json at ' + options.projectPath));
|
|
529
|
+
const manifestPath = nodePath.join(options.projectPath, defaultProjectFolder, 'manifest.xml');
|
|
530
|
+
console.log({ manifestPath });
|
|
531
|
+
if (!fs.existsSync(manifestPath))
|
|
532
|
+
fs.writeFileSync(manifestPath, '');
|
|
533
|
+
return options;
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
};
|
|
537
|
+
/**
|
|
538
|
+
* @description - forces interactive mode
|
|
539
|
+
* @param options
|
|
540
|
+
*/
|
|
541
|
+
const onlyInteractive = () => {
|
|
542
|
+
const origin = 'onlyInteractive';
|
|
543
|
+
return {
|
|
544
|
+
_origin: origin,
|
|
545
|
+
isStackable: true,
|
|
546
|
+
beforeExecuting: async (options) => {
|
|
547
|
+
if (options.interactive)
|
|
548
|
+
return options;
|
|
549
|
+
// only allow interactive mode
|
|
550
|
+
if (process.argv.includes('-i'))
|
|
551
|
+
return options;
|
|
552
|
+
throw onErrorHelper.makeError(origin, new Error(`${options?.command} is currently only allowing interactive mode (-i))`));
|
|
553
|
+
}
|
|
554
|
+
};
|
|
555
|
+
};
|
|
556
|
+
/**
|
|
557
|
+
* @internal
|
|
558
|
+
*/
|
|
559
|
+
const notSupported = () => {
|
|
560
|
+
const origin = 'notSupported';
|
|
561
|
+
return {
|
|
562
|
+
_origin: origin,
|
|
563
|
+
isStackable: true,
|
|
564
|
+
beforeExecuting: async (options) => {
|
|
565
|
+
if (!/\bFileCabinet\b/.test(process.cwd()))
|
|
566
|
+
throw onErrorHelper.makeError(origin, new Error(`\n ${options.command} not supported from ${process.cwd()} yet`));
|
|
567
|
+
return options;
|
|
568
|
+
},
|
|
569
|
+
};
|
|
570
|
+
};
|
|
571
|
+
/**
|
|
572
|
+
* @internal
|
|
573
|
+
* @description - Prompt for which folder to use -- only useful at the root level
|
|
574
|
+
*/
|
|
575
|
+
const verifyFolderFromRoot = () => {
|
|
576
|
+
const origin = 'verifyFolderFromRoot';
|
|
577
|
+
return {
|
|
578
|
+
_origin: origin,
|
|
579
|
+
isStackable: true,
|
|
580
|
+
beforeExecuting: async (options) => {
|
|
581
|
+
// verify the current root from the project JSON
|
|
582
|
+
const { defaultProjectFolder } = await projectJsonHelpers.readProjectJson([]);
|
|
583
|
+
console.log(options);
|
|
584
|
+
if (process.cwd() === pathHelpers.getRootOfProject()) {
|
|
585
|
+
const potentials = await pathHelpers.findMatchingDirectories(process.cwd(),
|
|
586
|
+
// length/depth of 3. first test must be to match account number (folder)
|
|
587
|
+
[/^(td)?\d+/, /^\w+$/, /^\w+$/, /^\w+$/]);
|
|
588
|
+
const filtered = potentials.filter((p) => /\bFileCabinet$/.test(p));
|
|
589
|
+
const displayChoices = filtered
|
|
590
|
+
.map((f) => f.replace(/^.*nsaccounts\b.((td)?\d+.*)$/, '$1'))
|
|
591
|
+
.map((x) => {
|
|
592
|
+
const [...rest] = x.split(/[\\\/]/);
|
|
593
|
+
const last = rest.pop();
|
|
594
|
+
if (last === 'FileCabinet')
|
|
595
|
+
return `${rest.join('/')}${(0, promptHelpers_1.goColor)('SUBTLE', '/', last)}`;
|
|
596
|
+
return x;
|
|
597
|
+
});
|
|
598
|
+
const choices = filtered
|
|
599
|
+
.map((f) => f.replace(/^.*nsaccounts\b.((td)?\d+.*?)(\W?\bFileCabinet.*)?$/, '$1'));
|
|
600
|
+
console.log({ choices });
|
|
601
|
+
const folderChoice = await promptHelper.promptChoices({
|
|
602
|
+
choices,
|
|
603
|
+
displayChoices,
|
|
604
|
+
question: `Which folder to use? ${(0, promptHelpers_1.goColor)('SUBTLE', 'current: ', [options.projectPath, defaultProjectFolder].join('/'))}`,
|
|
605
|
+
default: null
|
|
606
|
+
});
|
|
607
|
+
console.log({ folderChoice }, folderChoice !== defaultProjectFolder);
|
|
608
|
+
if (folderChoice !== defaultProjectFolder) {
|
|
609
|
+
// force a restart
|
|
610
|
+
await projectJsonHelpers.updateProjectJson({ defaultProjectFolder: folderChoice }, []);
|
|
611
|
+
throw onErrorHelper.makeError(origin, new Error('Must restart due to folder change'));
|
|
612
|
+
}
|
|
613
|
+
return options;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
};
|
|
617
|
+
};
|
|
618
|
+
// default
|
|
619
|
+
/**
|
|
620
|
+
* @description - getters so that stack is not invoked until called and they are readonly
|
|
621
|
+
*/
|
|
622
|
+
exports.defaultCommands = {
|
|
623
|
+
get 'account:manageauth'() {
|
|
624
|
+
return (0, exports.stack)('account:manageauth')
|
|
625
|
+
.stack(defaultStackable)
|
|
626
|
+
// .stack(printOptions({messageType: 'SUBTLE'}))
|
|
627
|
+
.stack(accountManageAuth.saveList())
|
|
628
|
+
.stack(accountManageAuth.betterList())
|
|
629
|
+
.done();
|
|
630
|
+
},
|
|
631
|
+
get 'account:setup:ci'() {
|
|
632
|
+
return (0, exports.stack)('account:setup:ci')
|
|
633
|
+
.stack(defaultStackable)
|
|
634
|
+
.stack(printOptions({ messageType: 'SUBTLE' }))
|
|
635
|
+
.stack(fakeManifest({}))
|
|
636
|
+
.stack(accountSetup.chooseExistingCertificate())
|
|
637
|
+
.stack(accountSetup.promptForAccount())
|
|
638
|
+
.stack(accountSetup.promptForAuthId())
|
|
639
|
+
.stack(accountSetup.askToReplace())
|
|
640
|
+
.stack(printOptions({ messageType: 'INFO', confirm: true }))
|
|
641
|
+
// .stack(forceAccountInName()) // does not make sense for default
|
|
642
|
+
.done();
|
|
643
|
+
},
|
|
644
|
+
get 'account:setup'() {
|
|
645
|
+
return (0, exports.stack)('account:setup')
|
|
646
|
+
.stack(defaultStackable).done();
|
|
647
|
+
},
|
|
648
|
+
get 'object:import'() {
|
|
649
|
+
return (0, exports.stack)('object:import')
|
|
650
|
+
.stack(notSupported())
|
|
651
|
+
.stack(accountManageAuth.promptForAccountChoice())
|
|
652
|
+
.done();
|
|
653
|
+
},
|
|
654
|
+
get 'object:list'() {
|
|
655
|
+
return (0, exports.stack)('object:list')
|
|
656
|
+
.stack(notSupported())
|
|
657
|
+
.stack(accountManageAuth.promptForAccountChoice())
|
|
658
|
+
.done();
|
|
659
|
+
},
|
|
660
|
+
get 'file:create'() {
|
|
661
|
+
return (0, exports.stack)('file:create')
|
|
662
|
+
.stack(notSupported())
|
|
663
|
+
.stack(accountManageAuth.promptForAccountChoice())
|
|
664
|
+
.done();
|
|
665
|
+
},
|
|
666
|
+
get 'file:import'() {
|
|
667
|
+
return (0, exports.stack)('file:import')
|
|
668
|
+
.stack(notSupported())
|
|
669
|
+
/*.stack(
|
|
670
|
+
accountManageAuth.promptForAccountChoice()
|
|
671
|
+
)*/ .done();
|
|
672
|
+
},
|
|
673
|
+
get 'file:list'() {
|
|
674
|
+
return (0, exports.stack)('file:list')
|
|
675
|
+
.stack(notSupported())
|
|
676
|
+
.stack(accountManageAuth.promptForAccountChoice())
|
|
677
|
+
.done();
|
|
678
|
+
},
|
|
679
|
+
get 'file:upload'() {
|
|
680
|
+
return (0, exports.stack)('file:upload')
|
|
681
|
+
.stack(notSupported())
|
|
682
|
+
.stack(accountManageAuth.promptForAccountChoice()).done();
|
|
683
|
+
},
|
|
684
|
+
get 'object:update'() {
|
|
685
|
+
return (0, exports.stack)('object:update')
|
|
686
|
+
.stack(notSupported())
|
|
687
|
+
.stack(accountManageAuth.promptForAccountChoice()).done();
|
|
688
|
+
},
|
|
689
|
+
get 'project:adddependencies'() {
|
|
690
|
+
return (0, exports.stack)('project:adddependencies')
|
|
691
|
+
.stack(notSupported())
|
|
692
|
+
.done();
|
|
693
|
+
},
|
|
694
|
+
get 'project:create'() {
|
|
695
|
+
return (0, exports.stack)('project:create')
|
|
696
|
+
.stack(projectCreates.rootProjectChoices())
|
|
697
|
+
.done();
|
|
698
|
+
},
|
|
699
|
+
get 'project:deploy'() {
|
|
700
|
+
return (0, exports.stack)('project:deploy')
|
|
701
|
+
.stack(notSupported())
|
|
702
|
+
.stack(accountManageAuth.promptForAccountChoice())
|
|
703
|
+
.done();
|
|
704
|
+
},
|
|
705
|
+
get 'project:package'() {
|
|
706
|
+
return (0, exports.stack)('project:package')
|
|
707
|
+
.stack(notSupported())
|
|
708
|
+
.stack(accountManageAuth.promptForAccountChoice())
|
|
709
|
+
.done();
|
|
710
|
+
},
|
|
711
|
+
get 'project:validate'() {
|
|
712
|
+
return (0, exports.stack)('project:validate')
|
|
713
|
+
.stack(notSupported())
|
|
714
|
+
.stack(accountManageAuth.promptForAccountChoice())
|
|
715
|
+
.done();
|
|
716
|
+
},
|
|
717
|
+
get help() {
|
|
718
|
+
return (0, exports.stack)('help')
|
|
719
|
+
.stack(defaultStackable).done();
|
|
720
|
+
},
|
|
721
|
+
};
|
|
722
|
+
/**
|
|
723
|
+
* @description - getters
|
|
724
|
+
*/
|
|
725
|
+
exports.caseCommands = {
|
|
726
|
+
get 'custom:hook'() {
|
|
727
|
+
return (0, exports.stack)('custom:hook')
|
|
728
|
+
.stack((0, compiless_1.compileSuiteScript)([]))
|
|
729
|
+
.stack((0, watchss_1.watchSuiteScript)('sdf.config.js', ['module.d.ts']))
|
|
730
|
+
.done();
|
|
731
|
+
},
|
|
732
|
+
get 'account:manageauth'() {
|
|
733
|
+
return (0, exports.stack)('account:manageauth')
|
|
734
|
+
.stack(defaultStackable)
|
|
735
|
+
//.stack(printOptions({messageType: 'SUBTLE'})) // this is very noisy here on success
|
|
736
|
+
.stack(accountManageAuth.saveList())
|
|
737
|
+
.stack(accountManageAuth.betterList())
|
|
738
|
+
.done();
|
|
739
|
+
},
|
|
740
|
+
get 'account:setup:ci'() {
|
|
741
|
+
return (0, exports.stack)('account:setup:ci')
|
|
742
|
+
.stack(defaultStackable)
|
|
743
|
+
.stack(printOptions({ messageType: 'SUBTLE' }))
|
|
744
|
+
.stack(accountSetup.chooseExistingCertificate())
|
|
745
|
+
.stack(accountSetup.promptForAccount())
|
|
746
|
+
.stack(accountSetup.promptForAuthId())
|
|
747
|
+
.stack(accountSetup.forceAccountInName())
|
|
748
|
+
.stack(fileImports.detectManifest())
|
|
749
|
+
.stack(printOptions({ messageType: 'INFO' }))
|
|
750
|
+
.done();
|
|
751
|
+
},
|
|
752
|
+
get 'account:setup'() {
|
|
753
|
+
return (0, exports.stack)('account:setup')
|
|
754
|
+
.stack(defaultStackable)
|
|
755
|
+
.done();
|
|
756
|
+
},
|
|
757
|
+
get 'file:create'() {
|
|
758
|
+
return (0, exports.stack)('file:create')
|
|
759
|
+
.stack(notSupported())
|
|
760
|
+
.stack(accountManageAuth.promptForAccountChoice())
|
|
761
|
+
.done();
|
|
762
|
+
},
|
|
763
|
+
get 'file:import'() {
|
|
764
|
+
return (0, exports.stack)('file:import')
|
|
765
|
+
.stack(accountManageAuth.promptForAccountChoice())
|
|
766
|
+
// prompt if they didn't give us one
|
|
767
|
+
.stack(fileUpload.promptForPath({
|
|
768
|
+
message: 'Enter a file or Glob to import (e.g. ./**/*.js)'
|
|
769
|
+
}))
|
|
770
|
+
.stack(printOptions({ messageType: 'INFO', confirm: true }))
|
|
771
|
+
.stack(fileImports.downloadForDiff())
|
|
772
|
+
// could be an xml
|
|
773
|
+
.stack(fileUpload.getFilesFromDeployXml())
|
|
774
|
+
// or could be a glob or partial
|
|
775
|
+
.stack(fileImports.fixFileImportPaths())
|
|
776
|
+
.stack(fileUpload.confirmFileList())
|
|
777
|
+
.stack(fileImports.detectManifest())
|
|
778
|
+
// .stack(printOptions({messageType: 'SUBTLE'}))
|
|
779
|
+
.done();
|
|
780
|
+
},
|
|
781
|
+
get 'file:list'() {
|
|
782
|
+
return (0, exports.stack)('file:list')
|
|
783
|
+
.stack(printOptions({ messageType: 'INFO', confirm: true }))
|
|
784
|
+
.stack(accountManageAuth.promptForAccountChoice())
|
|
785
|
+
.stack(printOptions({ messageType: 'INFO', confirm: true }))
|
|
786
|
+
.stack(fileList.saveFileListToTemp())
|
|
787
|
+
.done();
|
|
788
|
+
},
|
|
789
|
+
get 'file:upload'() {
|
|
790
|
+
return (0, exports.stack)('file:upload')
|
|
791
|
+
.stack(printOptions({ messageType: 'INFO', confirm: true }))
|
|
792
|
+
.stack(accountManageAuth.promptForAccountChoice())
|
|
793
|
+
// prompt if they didn't give us one
|
|
794
|
+
.stack(fileUpload.promptForPath({
|
|
795
|
+
message: 'Enter a file or Glob to upload (e.g. ./**/*.js)'
|
|
796
|
+
}))
|
|
797
|
+
// could be an xml
|
|
798
|
+
.stack(fileUpload.getFilesFromDeployXml())
|
|
799
|
+
// or could be a glob or partial
|
|
800
|
+
.stack(fileUpload.fixFileUploadPaths())
|
|
801
|
+
.stack(fileUpload.confirmFileList())
|
|
802
|
+
// .stack(fileUpload.compileFilesPrompt()) // use nodemon instead
|
|
803
|
+
.stack(fileUpload.testFilesPrompt())
|
|
804
|
+
.done();
|
|
805
|
+
},
|
|
806
|
+
get 'object:import'() {
|
|
807
|
+
return (0, exports.stack)('object:import')
|
|
808
|
+
// .stack(notSupported())
|
|
809
|
+
.stack(printOptions({ messageType: 'INFO', confirm: true }))
|
|
810
|
+
.stack(accountManageAuth.promptForAccountChoice())
|
|
811
|
+
.stack(objectImports.forceDestination())
|
|
812
|
+
.stack(printOptions({ messageType: 'INFO', confirm: true }))
|
|
813
|
+
.stack(objectImports.forceTypeAll())
|
|
814
|
+
.stack(fileUpload.promptForPath({
|
|
815
|
+
message: `Enter an object to upload. ${exports.promptHelpers.goColor('SUBTLE', '\n Wildcard is * \n \`type\` prefix is required but can be a wildcard (e.g. customrecord:custrecord_acs*)')}`
|
|
816
|
+
}))
|
|
817
|
+
.stack(fileUpload.getFilesFromDeployXml())
|
|
818
|
+
// .stack(printOptions({messageType: 'INFO', confirm: true}))
|
|
819
|
+
// or could be a glob or partial
|
|
820
|
+
.stack(objectImports.fixObjectImportPaths())
|
|
821
|
+
.stack(fileUpload.confirmFileList())
|
|
822
|
+
// .stack(objectImports.importGlobOrXml())
|
|
823
|
+
// organize into folders
|
|
824
|
+
.stack(objectImports.createObjectsDir())
|
|
825
|
+
.done();
|
|
826
|
+
},
|
|
827
|
+
get 'object:list'() {
|
|
828
|
+
return (0, exports.stack)('object:list')
|
|
829
|
+
.stack(printOptions({ messageType: 'INFO', confirm: true }))
|
|
830
|
+
.stack(accountManageAuth.promptForAccountChoice())
|
|
831
|
+
.stack(objectLists.saveObjectListToTemp())
|
|
832
|
+
.stack(objectLists.createFoldersForAllTypes())
|
|
833
|
+
.done();
|
|
834
|
+
},
|
|
835
|
+
get 'object:update'() {
|
|
836
|
+
return (0, exports.stack)('object:update')
|
|
837
|
+
.stack(notSupported())
|
|
838
|
+
.stack(accountManageAuth.promptForAccountChoice()).done();
|
|
839
|
+
},
|
|
840
|
+
get 'project:adddependencies'() {
|
|
841
|
+
return (0, exports.stack)('project:adddependencies')
|
|
842
|
+
.stack(notSupported())
|
|
843
|
+
.done();
|
|
844
|
+
},
|
|
845
|
+
get 'project:create'() {
|
|
846
|
+
return (0, exports.stack)('project:create')
|
|
847
|
+
.stack(notSupported())
|
|
848
|
+
.stack(accountManageAuth.promptForAccountChoice()).stack(projectCreates.projectJsonPromptAndEscape()).done();
|
|
849
|
+
},
|
|
850
|
+
get 'project:deploy'() {
|
|
851
|
+
return (0, exports.stack)('project:deploy')
|
|
852
|
+
.stack(projectDeploys.logErrors())
|
|
853
|
+
.stack(accountManageAuth.promptForAccountChoice()).stack(projectDeploys.forceLog())
|
|
854
|
+
.stack(projectDeploys.offerValidate())
|
|
855
|
+
.stack(projectDeploys.promptForDeployFile())
|
|
856
|
+
.stack(projectDeploys.askForDryrun())
|
|
857
|
+
.stack(projectDeploys.compileBeforeDeploy())
|
|
858
|
+
.stack(projectDeploys.runTestBeforeDeploy()
|
|
859
|
+
// projectDeploy.makeProjectDeployV1()
|
|
860
|
+
)
|
|
861
|
+
.done();
|
|
862
|
+
},
|
|
863
|
+
get 'project:package'() {
|
|
864
|
+
return (0, exports.stack)('project:package')
|
|
865
|
+
.stack(notSupported())
|
|
866
|
+
.stack(projectPackages.watchAndCompile())
|
|
867
|
+
.stack(printOptions({ messageType: "SUBTLE" }))
|
|
868
|
+
.stack(onlyInteractive())
|
|
869
|
+
.done();
|
|
870
|
+
},
|
|
871
|
+
get 'project:validate'() {
|
|
872
|
+
return (0, exports.stack)('project:validate')
|
|
873
|
+
.stack(notSupported())
|
|
874
|
+
.stack(projectValidates.forceLog())
|
|
875
|
+
.stack(projectValidates.promptServer())
|
|
876
|
+
// .stack(printOptions({messageType: 'SUBTLE'}))
|
|
877
|
+
.stack(projectValidates.runTests())
|
|
878
|
+
.stack(projectValidates.validateJest())
|
|
879
|
+
.stack(accountManageAuth.promptForAccountChoice()).done();
|
|
880
|
+
},
|
|
881
|
+
get help() {
|
|
882
|
+
return (0, exports.stack)('help')
|
|
883
|
+
.stack(defaultStackable).done();
|
|
884
|
+
}
|
|
885
|
+
};
|
|
886
|
+
/**
|
|
887
|
+
* @description - THIS MUST BE SYNCHRONOUS - you will get errors if the account is not setup.
|
|
888
|
+
* The way around that is to prompt the user and then they can try again
|
|
889
|
+
* @param options
|
|
890
|
+
* @param {object} extra
|
|
891
|
+
* @param {string[]} [extra.clean] - Files to remove after running. Default is `deploy.xml` and `.project.json`. `sdftemp.*` files are always removed
|
|
892
|
+
* @param {function} [extra.onExit] - callback that run on Exit of the process. Whatever string[] are returned will be printed as lines to the console
|
|
893
|
+
* @param {module} module
|
|
894
|
+
*/
|
|
895
|
+
const makeSafeExports = (options, extra, module) => {
|
|
896
|
+
try {
|
|
897
|
+
// if launched by something like:
|
|
898
|
+
// nodemon ./suitecloud.config.js watch -e ts --ignore module.d.ts
|
|
899
|
+
if (process.pid !== process.ppid && /^\d+$/.test(`${process.ppid}`) && process.argv.includes('watch')) {
|
|
900
|
+
// compile
|
|
901
|
+
return;
|
|
902
|
+
}
|
|
903
|
+
//Todo: if no local jest.config file exists then create one
|
|
904
|
+
// jobs when the process was spawned "normally from command line"
|
|
905
|
+
if (!spawnSuitecloudChild.isChildProcess()) {
|
|
906
|
+
// clean these up on start-up
|
|
907
|
+
tempFileHelper.removeTempFiles('sdftemp.');
|
|
908
|
+
// parent processes subscribe to clean-up
|
|
909
|
+
process.once('exit', async (e) => {
|
|
910
|
+
// console.log('close');
|
|
911
|
+
// do not delete 'tsconfig.json'
|
|
912
|
+
const toClean = Array.isArray(extra.clean) ? extra.clean : ['deploy.xml', '.project.json'];
|
|
913
|
+
process.stdout.write(exports.promptHelpers.goColor('SUBTLE', '\ncleaning up '));
|
|
914
|
+
cleanup(toClean, process.cwd());
|
|
915
|
+
if (!e)
|
|
916
|
+
process.stdout.write('\n✅');
|
|
917
|
+
process.stdout.write('\n');
|
|
918
|
+
if (e > 0)
|
|
919
|
+
tempFileHelper.removeTempFiles('sdftemp.');
|
|
920
|
+
if (typeof extra.onExit === 'function') {
|
|
921
|
+
const result = await extra.onExit(process);
|
|
922
|
+
if (Array.isArray(result))
|
|
923
|
+
result
|
|
924
|
+
.filter((r) => (typeof r === 'string'))
|
|
925
|
+
.forEach((msg) => process.stdout.write(` ${msg}\n`));
|
|
926
|
+
}
|
|
927
|
+
});
|
|
928
|
+
}
|
|
929
|
+
Object.assign(options, projectJsonHelpers.readProjectJsonSync([]));
|
|
930
|
+
// projectJson defaults
|
|
931
|
+
if (extra.autoCreateProjectJson && !spawnSuitecloudChild.isChildProcess()) {
|
|
932
|
+
// note: do not need project json anymore
|
|
933
|
+
projectJsonHelpers.updateProjectJsonSync({
|
|
934
|
+
defaultAuthId: options.defaultAuthId || 'root',
|
|
935
|
+
defaultProjectFolder: options.defaultProjectFolder || 'demo'
|
|
936
|
+
}, [], 'project.json', false);
|
|
937
|
+
}
|
|
938
|
+
// look for loops
|
|
939
|
+
// SHARED.DEBUG = true; // Boolean(extra?.debug);
|
|
940
|
+
//if (doConfig) {
|
|
941
|
+
Object.keys(exports.defaultCommands).forEach((command) => {
|
|
942
|
+
if (!Reflect.get(options.commands, command)) {
|
|
943
|
+
// use default
|
|
944
|
+
Reflect.set(options.commands, command, exports.defaultCommands[command]);
|
|
945
|
+
}
|
|
946
|
+
const fromOptions = options.commands[command];
|
|
947
|
+
});
|
|
948
|
+
// @ts-expect-error yes it does
|
|
949
|
+
options.commands = (0, exports.genericCommandProxy)(options.commands, Boolean(extra.block), Boolean(extra.debug));
|
|
950
|
+
module.exports = options;
|
|
951
|
+
return module.exports;
|
|
952
|
+
}
|
|
953
|
+
catch (e) {
|
|
954
|
+
console.error(e);
|
|
955
|
+
throw e;
|
|
956
|
+
}
|
|
957
|
+
};
|
|
958
|
+
exports.makeSafeExports = makeSafeExports;
|
|
959
|
+
//# sourceMappingURL=safeCommands.js.map
|