@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
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.askForDryrun = exports.logErrors = exports.promptForDeployFile = exports.forceLog = exports.runTestBeforeDeploy = exports.compileBeforeDeploy = exports.forceValidate = exports.offerValidate = exports.doDryRunAsChild = void 0;
|
|
4
|
+
const promptHelper = require("../lib/promptHelpers");
|
|
5
|
+
const fs = require("node:fs/promises");
|
|
6
|
+
const path = require("node:path");
|
|
7
|
+
const onErrorHelper = require("../lib/onErrorHelper");
|
|
8
|
+
const spawnSuitecloud = require("../lib/spawnSuitecloudChild");
|
|
9
|
+
const deployFileHelper = require("../lib/deployFileHelper");
|
|
10
|
+
const tempFileHelper = require("../lib/tempFileHelper");
|
|
11
|
+
const compileHelper = require("../lib/compileHelper");
|
|
12
|
+
const logHelper = require("../lib/logHelper");
|
|
13
|
+
const pathHelper = require("../lib/pathHelpers");
|
|
14
|
+
// CONSTANTS.PROJECT_JSON_PATH
|
|
15
|
+
const doDryRunAsChild = async (authid) => {
|
|
16
|
+
process.stdout.write(promptHelper.goColor('INFO', '\nPerforming dryrun'));
|
|
17
|
+
const errorCode = await spawnSuitecloud.createAsync({
|
|
18
|
+
command: 'project:deploy',
|
|
19
|
+
args: ['--dryrun', '--authid', authid || 'foo'],
|
|
20
|
+
interact: true,
|
|
21
|
+
});
|
|
22
|
+
if (errorCode)
|
|
23
|
+
throw new Error('Dry Run failed. Check log');
|
|
24
|
+
return errorCode;
|
|
25
|
+
};
|
|
26
|
+
exports.doDryRunAsChild = doDryRunAsChild;
|
|
27
|
+
const offerValidate = () => {
|
|
28
|
+
return {
|
|
29
|
+
_origin: 'offerValidate',
|
|
30
|
+
isStackable: true,
|
|
31
|
+
beforeExecuting: async (options) => {
|
|
32
|
+
if (options?.arguments?.runhooks === 'quiet')
|
|
33
|
+
return options;
|
|
34
|
+
const choices = { 'Y': 'Yes', 'N': 'No' };
|
|
35
|
+
let answer = await promptHelper.promptChoices({
|
|
36
|
+
choices,
|
|
37
|
+
displayChoices: choices,
|
|
38
|
+
default: choices['Y'],
|
|
39
|
+
question: `Validate Deployment?`
|
|
40
|
+
});
|
|
41
|
+
options.arguments.validate = (answer === choices['Y']);
|
|
42
|
+
return options;
|
|
43
|
+
},
|
|
44
|
+
onCompleted: async (options) => {
|
|
45
|
+
return options;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
exports.offerValidate = offerValidate;
|
|
50
|
+
const forceValidate = () => {
|
|
51
|
+
return {
|
|
52
|
+
_origin: 'forceValidate',
|
|
53
|
+
isStackable: true,
|
|
54
|
+
beforeExecuting: async (options) => {
|
|
55
|
+
options.arguments.validate = true;
|
|
56
|
+
return options;
|
|
57
|
+
},
|
|
58
|
+
onCompleted: async (options) => {
|
|
59
|
+
return options;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
exports.forceValidate = forceValidate;
|
|
64
|
+
const compileBeforeDeploy = () => {
|
|
65
|
+
const origin = 'compileBeforeDeploy';
|
|
66
|
+
return {
|
|
67
|
+
_origin: origin,
|
|
68
|
+
isStackable: true,
|
|
69
|
+
beforeExecuting: async (options) => {
|
|
70
|
+
try {
|
|
71
|
+
if (spawnSuitecloud.isChildProcess())
|
|
72
|
+
return options;
|
|
73
|
+
if (options?.arguments?.runhooks === 'quiet')
|
|
74
|
+
return options;
|
|
75
|
+
const hasTsc = await compileHelper.hasTsConfig();
|
|
76
|
+
if (!hasTsc)
|
|
77
|
+
return options;
|
|
78
|
+
const contents = compileHelper.previewFile(hasTsc);
|
|
79
|
+
process.stdout.write(promptHelper.goColor('SUBTLE', '\ntsConfig', contents));
|
|
80
|
+
const choices = { 'Y': 'Yes', 'N': 'No' };
|
|
81
|
+
let answer = await promptHelper.promptChoices({
|
|
82
|
+
choices,
|
|
83
|
+
displayChoices: choices,
|
|
84
|
+
default: choices['Y'],
|
|
85
|
+
question: `Compile Typescript?`
|
|
86
|
+
});
|
|
87
|
+
if (answer === choices['N'])
|
|
88
|
+
return options;
|
|
89
|
+
const errorCode = await compileHelper.compileTsConfig();
|
|
90
|
+
if (errorCode === 0)
|
|
91
|
+
return options;
|
|
92
|
+
answer = await promptHelper.promptChoices({
|
|
93
|
+
choices,
|
|
94
|
+
displayChoices: choices,
|
|
95
|
+
default: choices['Y'],
|
|
96
|
+
question: `Continue with errors?`
|
|
97
|
+
});
|
|
98
|
+
if (answer === choices['Y'])
|
|
99
|
+
return options;
|
|
100
|
+
throw new Error(origin + ':Errors compiling');
|
|
101
|
+
}
|
|
102
|
+
catch (e) {
|
|
103
|
+
throw new Error(origin + ':Unexpected Error');
|
|
104
|
+
}
|
|
105
|
+
return options;
|
|
106
|
+
},
|
|
107
|
+
onError: async (error) => onErrorHelper.detectOriginAndReturn(origin, error),
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
exports.compileBeforeDeploy = compileBeforeDeploy;
|
|
111
|
+
/**
|
|
112
|
+
* @deprecated
|
|
113
|
+
*/
|
|
114
|
+
const runTestBeforeDeploy = () => {
|
|
115
|
+
const origin = 'runTestBeforeDeploy';
|
|
116
|
+
return {
|
|
117
|
+
_origin: origin,
|
|
118
|
+
isStackable: true,
|
|
119
|
+
beforeExecuting: async (options) => {
|
|
120
|
+
// passthrough child processes
|
|
121
|
+
try {
|
|
122
|
+
if (spawnSuitecloud.isChildProcess())
|
|
123
|
+
return options;
|
|
124
|
+
if (options?.arguments?.runhooks === 'quiet')
|
|
125
|
+
return options;
|
|
126
|
+
const choices = { 'Y': 'Yes (not supported yet)', 'N': 'No' };
|
|
127
|
+
let answer = await promptHelper.promptChoices({
|
|
128
|
+
choices,
|
|
129
|
+
displayChoices: choices,
|
|
130
|
+
default: choices['Y'],
|
|
131
|
+
question: `Run tests on deploying JS files? \n(This will perform a dryrun to obtain which files need testing)`,
|
|
132
|
+
});
|
|
133
|
+
if (answer === choices['N'])
|
|
134
|
+
return options;
|
|
135
|
+
// wait for a dryun run
|
|
136
|
+
throw onErrorHelper.makeError(origin, new Error('Not supported yet'));
|
|
137
|
+
// get the files from the dryrun file
|
|
138
|
+
const results = await tempFileHelper.consumeTempFile('dryrun.json');
|
|
139
|
+
// console.log({results}, 'dryrun results');
|
|
140
|
+
const data = JSON.parse(results)?._data;
|
|
141
|
+
const testFiles = await data.reduce(async (flatAcc, l) => {
|
|
142
|
+
const acc = await flatAcc;
|
|
143
|
+
if (l.startsWith('Upload file') && l.endsWith('.js')) {
|
|
144
|
+
const realPath = await deployFileHelper.getRealPathofInnerXmlPath(l);
|
|
145
|
+
acc.push(realPath);
|
|
146
|
+
}
|
|
147
|
+
return acc;
|
|
148
|
+
}, Promise.resolve([]));
|
|
149
|
+
const errorCode = await compileHelper.runJestTest(testFiles).catch((e) => {
|
|
150
|
+
if (spawnSuitecloud.isChildProcess())
|
|
151
|
+
throw e;
|
|
152
|
+
return 1;
|
|
153
|
+
});
|
|
154
|
+
if (errorCode !== 0) {
|
|
155
|
+
const choices = { 'Y': 'Yes', 'N': 'No' };
|
|
156
|
+
let answer = await promptHelper.promptChoices({
|
|
157
|
+
choices,
|
|
158
|
+
displayChoices: choices,
|
|
159
|
+
default: choices['Y'],
|
|
160
|
+
question: `Tests failed. Would you like to deploy Anyway?`
|
|
161
|
+
});
|
|
162
|
+
if (answer === choices['Y'])
|
|
163
|
+
return options;
|
|
164
|
+
throw onErrorHelper.makeError(origin, new Error('Jest Tests failed'));
|
|
165
|
+
}
|
|
166
|
+
return options;
|
|
167
|
+
}
|
|
168
|
+
catch (e) {
|
|
169
|
+
throw onErrorHelper.makeError(origin, e);
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
onCompleted: async (options) => {
|
|
173
|
+
return options;
|
|
174
|
+
},
|
|
175
|
+
onError: async (error) => onErrorHelper.detectOriginAndReturn(origin, error)
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
exports.runTestBeforeDeploy = runTestBeforeDeploy;
|
|
179
|
+
const forceLog = () => {
|
|
180
|
+
return {
|
|
181
|
+
_origin: 'forceLog',
|
|
182
|
+
isStackable: true,
|
|
183
|
+
beforeExecuting: async (options) => {
|
|
184
|
+
const now = new Date().toISOString();
|
|
185
|
+
const { log } = {
|
|
186
|
+
log: (await logHelper.useSdfLog(options.command || 'unknown')),
|
|
187
|
+
...options?.arguments
|
|
188
|
+
};
|
|
189
|
+
options.arguments.log = log;
|
|
190
|
+
// make log dir
|
|
191
|
+
await fs.access(path.join(process.cwd(), path.dirname(options.arguments.log)))
|
|
192
|
+
.catch(() => fs.mkdir(path.join(process.cwd(), path.dirname(options.arguments.log))));
|
|
193
|
+
return options;
|
|
194
|
+
},
|
|
195
|
+
onCompleted: async (options) => {
|
|
196
|
+
return options;
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
};
|
|
200
|
+
exports.forceLog = forceLog;
|
|
201
|
+
/**
|
|
202
|
+
* @description - prompt deployXml choices and confirm
|
|
203
|
+
* @see {SdfCommand}
|
|
204
|
+
*/
|
|
205
|
+
const promptForDeployFile = () => {
|
|
206
|
+
const toReturn = {
|
|
207
|
+
_origin: 'promptForDeployFile',
|
|
208
|
+
isStackable: true,
|
|
209
|
+
beforeExecuting: async (options) => {
|
|
210
|
+
if (options?.arguments?.runhooks === 'quiet')
|
|
211
|
+
return options;
|
|
212
|
+
try {
|
|
213
|
+
process.stdout.write(promptHelper.goColor('SUBTLE', '\npromptForDeployFile', options));
|
|
214
|
+
const { projectPath } = options;
|
|
215
|
+
// check if there is a current deploy file at the root
|
|
216
|
+
let deployFilePath = await deployFileHelper.hasDeployXml(projectPath);
|
|
217
|
+
const choices = { 'Y': 'Yes', 'N': 'No' };
|
|
218
|
+
let answer = choices['N'];
|
|
219
|
+
if (deployFilePath && !spawnSuitecloud.isChildProcess()) {
|
|
220
|
+
const contentDeployXml = await deployFileHelper.previewFile(deployFilePath);
|
|
221
|
+
// display the chosen contents and confirm
|
|
222
|
+
answer = await promptHelper.promptChoices({
|
|
223
|
+
choices,
|
|
224
|
+
displayChoices: choices,
|
|
225
|
+
default: choices['Y'],
|
|
226
|
+
question: 'Use this file? (Y/N)',
|
|
227
|
+
premessage: contentDeployXml
|
|
228
|
+
});
|
|
229
|
+
//
|
|
230
|
+
if (answer === choices['N'])
|
|
231
|
+
await deployFileHelper.removeFile(deployFilePath);
|
|
232
|
+
if (answer === choices['Y'])
|
|
233
|
+
return options;
|
|
234
|
+
}
|
|
235
|
+
if ((!deployFilePath || answer === choices['N']) && !spawnSuitecloud.isChildProcess()) {
|
|
236
|
+
// look for deploy files that we can use below the current working directory
|
|
237
|
+
const deployXmlList = await deployFileHelper.listDeployXmlFiles(projectPath);
|
|
238
|
+
deployFilePath = await promptHelper.promptChoices({
|
|
239
|
+
choices: deployXmlList,
|
|
240
|
+
displayChoices: deployXmlList.map((l) => [l, promptHelper.goColor('SUBTLE', `${options.projectPath}/${l}`.replace(/^.*(\bSuiteScripts\b.*)$/, '($1)'))].join(' ')),
|
|
241
|
+
default: deployXmlList[0],
|
|
242
|
+
question: 'Use which deploy file?',
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
const filesFromXml = await deployFileHelper.extractFilePathsFromDeployXmlFile(options.projectPath, deployFilePath, 'SuiteScripts');
|
|
246
|
+
const objectsFromXml = await deployFileHelper.extractFilePathsFromDeployXmlFile(options.projectPath, deployFilePath, 'Objects');
|
|
247
|
+
const filecabinetHolder = await pathHelper.getFolderHoldingFileCabinetPlus(options.projectPath);
|
|
248
|
+
const filteredFilesAgainstGlobs = await pathHelper.getAllFilesRecursively(
|
|
249
|
+
// need to examine ALL files in the project
|
|
250
|
+
[filecabinetHolder, 'FileCabinet', 'SuiteScripts'], 'SuiteScripts',
|
|
251
|
+
//
|
|
252
|
+
filesFromXml.map((fx) => fx.replace(/^.*(.\bSuiteScripts\b.*)$/, '$1')));
|
|
253
|
+
const filteredObjectsAgainstGlobs = await pathHelper.getAllFilesRecursively(
|
|
254
|
+
// need to examine ALL files in the project
|
|
255
|
+
[filecabinetHolder, 'Objects'], 'Objects',
|
|
256
|
+
//
|
|
257
|
+
objectsFromXml
|
|
258
|
+
.map((ox) => ox.replace(/^.*(.\bObjects\b.*)$/, '$1'))
|
|
259
|
+
.map((ox) => {
|
|
260
|
+
const [typeOrPath, pathOrUndefined] = ox.split(':');
|
|
261
|
+
return pathOrUndefined || typeOrPath;
|
|
262
|
+
}));
|
|
263
|
+
const filteredLegalFiles = pathHelper.removeIllegalFileCabinetFiles(filteredFilesAgainstGlobs);
|
|
264
|
+
const deployXmlContent = deployFileHelper.makeDeployXmlString(filteredLegalFiles, filteredObjectsAgainstGlobs);
|
|
265
|
+
// make the candidate deployXml file inthe projectPath
|
|
266
|
+
await deployFileHelper.createDeployXmlFile(deployXmlContent, [filecabinetHolder, 'deploy.xml']);
|
|
267
|
+
await promptHelper.promptUser({
|
|
268
|
+
message: 'kill me now',
|
|
269
|
+
});
|
|
270
|
+
// loop only for re-prompting
|
|
271
|
+
if (!spawnSuitecloud.isChildProcess())
|
|
272
|
+
return await toReturn.beforeExecuting(options);
|
|
273
|
+
//
|
|
274
|
+
return options;
|
|
275
|
+
}
|
|
276
|
+
catch (e) {
|
|
277
|
+
console.log({ e });
|
|
278
|
+
throw e;
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
onCompleted: async (options) => {
|
|
282
|
+
// remove the temporary deploy.xml file?
|
|
283
|
+
return options;
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
return toReturn;
|
|
287
|
+
};
|
|
288
|
+
exports.promptForDeployFile = promptForDeployFile;
|
|
289
|
+
const logErrors = () => {
|
|
290
|
+
return {
|
|
291
|
+
_origin: 'logError',
|
|
292
|
+
isStackable: true,
|
|
293
|
+
onError: async (error) => onErrorHelper.detectOriginAndReturn('logError', error, (error) => {
|
|
294
|
+
return error;
|
|
295
|
+
})
|
|
296
|
+
};
|
|
297
|
+
};
|
|
298
|
+
exports.logErrors = logErrors;
|
|
299
|
+
/**
|
|
300
|
+
* @description -
|
|
301
|
+
* @
|
|
302
|
+
*/
|
|
303
|
+
const askForDryrun = () => {
|
|
304
|
+
const origin = 'askForDryrun';
|
|
305
|
+
return {
|
|
306
|
+
_origin: origin,
|
|
307
|
+
isStackable: true,
|
|
308
|
+
beforeExecuting: async (options) => {
|
|
309
|
+
process.stdout.write(promptHelper.goColor('SUBTLE', options));
|
|
310
|
+
if (options?.arguments?.runhooks === 'quiet')
|
|
311
|
+
return options;
|
|
312
|
+
try {
|
|
313
|
+
const choices = { 'Y': 'Yes', 'N': 'No' };
|
|
314
|
+
let answer = choices['N'];
|
|
315
|
+
let innerDryRunError = false;
|
|
316
|
+
if (!options.arguments.dryrun && !spawnSuitecloud.isChildProcess()) {
|
|
317
|
+
answer = await promptHelper.promptChoices({
|
|
318
|
+
choices,
|
|
319
|
+
displayChoices: choices,
|
|
320
|
+
default: choices['Y'],
|
|
321
|
+
question: 'Would ou like to do a dryrun first?',
|
|
322
|
+
});
|
|
323
|
+
if (answer === choices['Y']) {
|
|
324
|
+
// mini internal dryrun
|
|
325
|
+
// spawn child
|
|
326
|
+
const errorCode = await (0, exports.doDryRunAsChild)(options.authId).catch((e) => {
|
|
327
|
+
throw new Error(origin + ':Dryrun failed');
|
|
328
|
+
});
|
|
329
|
+
if (errorCode)
|
|
330
|
+
innerDryRunError = true;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if (!options.arguments.dryrun && !spawnSuitecloud.isChildProcess()) {
|
|
334
|
+
if (answer === choices['N']) {
|
|
335
|
+
// ask if this should be a dryrun
|
|
336
|
+
const answer = await promptHelper.promptChoices({
|
|
337
|
+
choices,
|
|
338
|
+
displayChoices: choices,
|
|
339
|
+
default: choices['Y'],
|
|
340
|
+
question: 'Would you like to make this run a dryrun?',
|
|
341
|
+
});
|
|
342
|
+
if (answer === choices['Y'])
|
|
343
|
+
options.arguments.dryrun = true;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
// these are exclusive options to each other
|
|
347
|
+
if (options.arguments.dryrun)
|
|
348
|
+
options.arguments.validate = false;
|
|
349
|
+
return options;
|
|
350
|
+
}
|
|
351
|
+
catch (e) {
|
|
352
|
+
throw new Error(origin + ':Unexpected Error');
|
|
353
|
+
}
|
|
354
|
+
},
|
|
355
|
+
onCompleted: async (options) => {
|
|
356
|
+
// store results
|
|
357
|
+
process.stdout.write(promptHelper.goColor('SUBTLE', options));
|
|
358
|
+
if (/preview process/.test(options._resultMessage)) {
|
|
359
|
+
await tempFileHelper.makeTempFile('dryrun.json', JSON.stringify(options, null, 2));
|
|
360
|
+
}
|
|
361
|
+
return options;
|
|
362
|
+
},
|
|
363
|
+
onError: async (error) => onErrorHelper.detectOriginAndReturn(origin, error, (error) => {
|
|
364
|
+
// check log
|
|
365
|
+
console.error(error);
|
|
366
|
+
return error;
|
|
367
|
+
}),
|
|
368
|
+
};
|
|
369
|
+
};
|
|
370
|
+
exports.askForDryrun = askForDryrun;
|
|
371
|
+
//# sourceMappingURL=projectDeploy.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file /Users/geraldgillespie/code/nsaccounts/sdf/commands/projectPackage
|
|
3
|
+
* @author Gerald Gillespie <gerald.gillespie@fullscript.com>
|
|
4
|
+
*/
|
|
5
|
+
import { SdfCommand } from "#root/index";
|
|
6
|
+
/**
|
|
7
|
+
* @description - watches for a non-standard argument
|
|
8
|
+
* - meant for you to use nodemon to keep it runninga
|
|
9
|
+
*/
|
|
10
|
+
export declare const watchAndCompile: () => SdfCommand;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file /Users/geraldgillespie/code/nsaccounts/sdf/commands/projectPackage
|
|
4
|
+
* @author Gerald Gillespie <gerald.gillespie@fullscript.com>
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.watchAndCompile = void 0;
|
|
8
|
+
const safeCommands = require("../safeCommands");
|
|
9
|
+
/**
|
|
10
|
+
* @description - watches for a non-standard argument
|
|
11
|
+
* - meant for you to use nodemon to keep it runninga
|
|
12
|
+
*/
|
|
13
|
+
const watchAndCompile = () => {
|
|
14
|
+
const origin = 'watchAndCompile';
|
|
15
|
+
return {
|
|
16
|
+
_origin: origin,
|
|
17
|
+
isStackable: true,
|
|
18
|
+
beforeExecuting: async (options) => {
|
|
19
|
+
if (process.argv.includes('watch')) {
|
|
20
|
+
// compile tsc
|
|
21
|
+
//TODO
|
|
22
|
+
// update module.d.ts
|
|
23
|
+
// exit cleanly and pre-maturely on purpose
|
|
24
|
+
process.stdout.write(safeCommands.promptHelpers.goColor('SUBTLE', '\nWatch does nothing yet✅'));
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
return options;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
exports.watchAndCompile = watchAndCompile;
|
|
32
|
+
//# sourceMappingURL=projectPackage.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file /Users/geraldgillespie/code/nsaccounts/sdf/commands/projectValidate
|
|
3
|
+
* @author Gerald Gillespie <gerald.gillespie@fullscript.com>
|
|
4
|
+
*/
|
|
5
|
+
import { SdfCommand } from "#root/index";
|
|
6
|
+
export declare const validateJest: () => SdfCommand;
|
|
7
|
+
export declare const forceLog: () => SdfCommand;
|
|
8
|
+
/**
|
|
9
|
+
* @description -
|
|
10
|
+
* @todo - make it a prompt?
|
|
11
|
+
*/
|
|
12
|
+
export declare const promptServer: () => SdfCommand;
|
|
13
|
+
/**
|
|
14
|
+
* @description - runs all tests. Creates the jest config if needed
|
|
15
|
+
*/
|
|
16
|
+
export declare const runTests: () => {
|
|
17
|
+
_origin: string;
|
|
18
|
+
isStackable: boolean;
|
|
19
|
+
beforeExecuting: (options: any) => Promise<any>;
|
|
20
|
+
onError: (error: string) => Promise<string>;
|
|
21
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file /Users/geraldgillespie/code/nsaccounts/sdf/commands/projectValidate
|
|
4
|
+
* @author Gerald Gillespie <gerald.gillespie@fullscript.com>
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.runTests = exports.promptServer = exports.forceLog = exports.validateJest = void 0;
|
|
8
|
+
const fs = require("node:fs/promises");
|
|
9
|
+
const onErrorHelper = require("../lib/onErrorHelper");
|
|
10
|
+
const promptHelper = require("../lib/promptHelpers");
|
|
11
|
+
const compileHelper = require("../lib/compileHelper");
|
|
12
|
+
const logHelper = require("../lib/logHelper");
|
|
13
|
+
const validateJest = () => {
|
|
14
|
+
const origin = 'validateJest';
|
|
15
|
+
const badTestFiles = [];
|
|
16
|
+
return {
|
|
17
|
+
_origin: origin,
|
|
18
|
+
isStackable: true,
|
|
19
|
+
beforeExecuting: async (options) => {
|
|
20
|
+
// make sure that all test files are in the right place
|
|
21
|
+
const invalidTestFiles = await fs.readdir(process.cwd(), { recursive: true }).then((list) => {
|
|
22
|
+
return Promise.all(list.map(async (f) => {
|
|
23
|
+
// test if it is a dir
|
|
24
|
+
const stats = await fs.stat(f);
|
|
25
|
+
if (stats.isDirectory()) {
|
|
26
|
+
if (!f.includes('test'))
|
|
27
|
+
return;
|
|
28
|
+
// tests directories need to have a certain name
|
|
29
|
+
if (!/\W__tests__\W?$/.test(f))
|
|
30
|
+
return f;
|
|
31
|
+
}
|
|
32
|
+
else if (stats.isFile()) {
|
|
33
|
+
if (!f.endsWith('.js'))
|
|
34
|
+
return;
|
|
35
|
+
if (!f.includes('test'))
|
|
36
|
+
return;
|
|
37
|
+
if (f.endsWith('.test.js') && !f.includes('__tests'))
|
|
38
|
+
return f;
|
|
39
|
+
if (!f.endsWith('.test.js'))
|
|
40
|
+
return f;
|
|
41
|
+
}
|
|
42
|
+
return;
|
|
43
|
+
})).then((l) => l.filter(Boolean));
|
|
44
|
+
}).catch(() => []);
|
|
45
|
+
if (invalidTestFiles.length > 0) {
|
|
46
|
+
badTestFiles.push(...invalidTestFiles);
|
|
47
|
+
throw onErrorHelper.makeError(origin, new Error('Tests are not organized properly'));
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
process.stdout.write(promptHelper.goColor('INFO', '\nNo test file problems detected'));
|
|
51
|
+
}
|
|
52
|
+
return options;
|
|
53
|
+
},
|
|
54
|
+
onError: async (error) => onErrorHelper.detectOriginAndReturn(origin, error, (error) => {
|
|
55
|
+
if (badTestFiles.length > 0) {
|
|
56
|
+
process.stdout.write(promptHelper.goColor('BAD', '\nThese files are not organized correctly', badTestFiles));
|
|
57
|
+
}
|
|
58
|
+
return error;
|
|
59
|
+
}),
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
exports.validateJest = validateJest;
|
|
63
|
+
const forceLog = () => {
|
|
64
|
+
const origin = 'forceLog';
|
|
65
|
+
return {
|
|
66
|
+
_origin: origin,
|
|
67
|
+
isStackable: true,
|
|
68
|
+
beforeExecuting: async (options) => {
|
|
69
|
+
options.arguments.log = await logHelper.useSdfLog(options.command || 'unknown');
|
|
70
|
+
return options;
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
exports.forceLog = forceLog;
|
|
75
|
+
/**
|
|
76
|
+
* @description -
|
|
77
|
+
* @todo - make it a prompt?
|
|
78
|
+
*/
|
|
79
|
+
const promptServer = () => {
|
|
80
|
+
const origin = 'promptServer';
|
|
81
|
+
return {
|
|
82
|
+
_origin: origin,
|
|
83
|
+
isStackable: true,
|
|
84
|
+
beforeExecuting: async (options) => {
|
|
85
|
+
options.arguments.server = true;
|
|
86
|
+
return options;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
exports.promptServer = promptServer;
|
|
91
|
+
/**
|
|
92
|
+
* @description - runs all tests. Creates the jest config if needed
|
|
93
|
+
*/
|
|
94
|
+
const runTests = () => {
|
|
95
|
+
const origin = 'runTests';
|
|
96
|
+
return {
|
|
97
|
+
_origin: origin,
|
|
98
|
+
isStackable: true,
|
|
99
|
+
beforeExecuting: async (options) => {
|
|
100
|
+
// make sure there is a jest.config file
|
|
101
|
+
await compileHelper.makeJestConfig();
|
|
102
|
+
// run tests
|
|
103
|
+
await compileHelper.runJestTest(['ALL'], false);
|
|
104
|
+
return options;
|
|
105
|
+
},
|
|
106
|
+
onError: async (error) => onErrorHelper.detectOriginAndReturn(origin, error, (error) => {
|
|
107
|
+
return error;
|
|
108
|
+
})
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
exports.runTests = runTests;
|
|
112
|
+
//# sourceMappingURL=projectValidate.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file sdf/commands/sdfAcs_authmap.ts
|
|
3
|
+
* @author Gerald Gillespie <gerald.gillespie@fullscript.com>
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @description - Display the authid map for the provided authid / folder combo.
|
|
7
|
+
* - if no combo is given then display the entire map
|
|
8
|
+
* - the process of doing the import is asynchronous but this should be the final operation.
|
|
9
|
+
* @returns {boolean}
|
|
10
|
+
*/
|
|
11
|
+
declare const checkAuthMap: (options: {
|
|
12
|
+
authid?: string;
|
|
13
|
+
folder?: string;
|
|
14
|
+
}) => Promise<string | boolean>;
|
|
15
|
+
export = checkAuthMap;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file sdf/commands/sdfAcs_authmap.ts
|
|
4
|
+
* @author Gerald Gillespie <gerald.gillespie@fullscript.com>
|
|
5
|
+
*/
|
|
6
|
+
const nodePath = require("node:path");
|
|
7
|
+
/**
|
|
8
|
+
* @description - Display the authid map for the provided authid / folder combo.
|
|
9
|
+
* - if no combo is given then display the entire map
|
|
10
|
+
* - the process of doing the import is asynchronous but this should be the final operation.
|
|
11
|
+
* @returns {boolean}
|
|
12
|
+
*/
|
|
13
|
+
const checkAuthMap = async (options) => {
|
|
14
|
+
const { authid, folder } = options;
|
|
15
|
+
return Promise.resolve(`${nodePath.join(process.cwd(), 'suitecloud.config.js')}`).then(s => require(s)).then((x) => {
|
|
16
|
+
const stringifiedMap = JSON.stringify(x.default.authFolderMap, null, 2);
|
|
17
|
+
// yconsole.log(`${
|
|
18
|
+
if (!authid)
|
|
19
|
+
return stringifiedMap;
|
|
20
|
+
// boolean on whether the folder relationship with the authid exists
|
|
21
|
+
const folders = x?.default?.authFolderMap?.[authid];
|
|
22
|
+
return Array.isArray(folders) && folders.includes(folder);
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
module.exports = checkAuthMap;
|
|
26
|
+
//# sourceMappingURL=sdfAcs_authmap.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file sdf/commands/sdfAcs_clean.ts
|
|
3
|
+
* @author Gerald Gillespie <gerald.gillespie@fullscript.com>
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @description - Can be used to wip a directory or setup a new project
|
|
7
|
+
* - the root directory needs to exist first
|
|
8
|
+
* - because you have everything under source control you do not need to worry
|
|
9
|
+
* - you should do the auth setup at the same time
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* sdfAcs:clean --authid 3905005_bl
|
|
13
|
+
* ```
|
|
14
|
+
* @param {string} options.authid
|
|
15
|
+
* @returns {boolean}
|
|
16
|
+
*/
|
|
17
|
+
declare const cleanProject: (options: {
|
|
18
|
+
authid: string;
|
|
19
|
+
}) => boolean;
|
|
20
|
+
export = cleanProject;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file sdf/commands/sdfAcs_clean.ts
|
|
4
|
+
* @author Gerald Gillespie <gerald.gillespie@fullscript.com>
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* @description - Can be used to wip a directory or setup a new project
|
|
8
|
+
* - the root directory needs to exist first
|
|
9
|
+
* - because you have everything under source control you do not need to worry
|
|
10
|
+
* - you should do the auth setup at the same time
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* sdfAcs:clean --authid 3905005_bl
|
|
14
|
+
* ```
|
|
15
|
+
* @param {string} options.authid
|
|
16
|
+
* @returns {boolean}
|
|
17
|
+
*/
|
|
18
|
+
const cleanProject = (options) => {
|
|
19
|
+
return true;
|
|
20
|
+
};
|
|
21
|
+
module.exports = cleanProject;
|
|
22
|
+
//# sourceMappingURL=sdfAcs_clean.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file deleteManifest.cjs
|
|
3
|
+
* - delete the manifest.xml file in the suitecloud working directory
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('node:fs');
|
|
7
|
+
const nodePath = require('node:path');
|
|
8
|
+
const pathOfRoot = nodePath.basename(require.resolve('#root'));
|
|
9
|
+
|
|
10
|
+
// delete the current manifest.xml
|
|
11
|
+
fs.rmSync(nodePath.join(pathOfRoot, 'manifest.xml'));
|
package/demo.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Overview / Features
|
|
2
|
+
|
|
3
|
+
* build a UserEvent that will help with adhoc debugging
|
|
4
|
+
* 3 different UEs
|
|
5
|
+
* separation of beforeLoad, beforeSubmit, afterSubmit
|
|
6
|
+
* deployable to any record
|
|
7
|
+
* easier ordering of rank
|
|
8
|
+
* each can launch other UEs
|
|
9
|
+
|
|
10
|
+
# Requirements
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# Objects & Scripts
|
|
14
|
+
|
|
15
|
+
## Objects
|
|
16
|
+
1. UserEvent record for each entry point method
|
|
17
|
+
2. script parameter that will accept a scriptid / filepath (string)
|
|
18
|
+
|
|
19
|
+
## Scripts
|
|
20
|
+
1. Script for beforeLoad
|
|
21
|
+
2. Script for beforeSubmit
|
|
22
|
+
3. Script for afterSubmit
|
|
23
|
+
4. A generic function to proxy an unknown script
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|