@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.
Files changed (113) hide show
  1. package/.idea/compiler.xml +6 -0
  2. package/.idea/git_toolbox_blame.xml +6 -0
  3. package/.idea/git_toolbox_prj.xml +15 -0
  4. package/.idea/misc.xml +6 -0
  5. package/.idea/modules.xml +8 -0
  6. package/.idea/suitecloud-stacker.iml +9 -0
  7. package/.idea/vcs.xml +6 -0
  8. package/CONTRIBUTING.md +72 -0
  9. package/README.md +242 -0
  10. package/bin/updateModule.d.ts +6 -0
  11. package/bin/updateModule.js +12 -0
  12. package/commands/CONTRIBUTING.md +7 -0
  13. package/commands/accountManageauth.d.ts +93 -0
  14. package/commands/accountManageauth.js +228 -0
  15. package/commands/accountSetup.d.ts +56 -0
  16. package/commands/accountSetup.js +218 -0
  17. package/commands/customhook/compiless.d.ts +10 -0
  18. package/commands/customhook/compiless.js +46 -0
  19. package/commands/customhook/watchss.d.ts +14 -0
  20. package/commands/customhook/watchss.js +77 -0
  21. package/commands/fileImport.d.ts +31 -0
  22. package/commands/fileImport.js +503 -0
  23. package/commands/fileList.d.ts +19 -0
  24. package/commands/fileList.js +40 -0
  25. package/commands/fileUpload.d.ts +52 -0
  26. package/commands/fileUpload.js +355 -0
  27. package/commands/generic.d.ts +5 -0
  28. package/commands/generic.js +13 -0
  29. package/commands/objectImport.d.ts +32 -0
  30. package/commands/objectImport.js +287 -0
  31. package/commands/objectList.d.ts +13 -0
  32. package/commands/objectList.js +78 -0
  33. package/commands/projectCreate.d.ts +31 -0
  34. package/commands/projectCreate.js +506 -0
  35. package/commands/projectDeploy.d.ts +25 -0
  36. package/commands/projectDeploy.js +371 -0
  37. package/commands/projectPackage.d.ts +10 -0
  38. package/commands/projectPackage.js +32 -0
  39. package/commands/projectValidate.d.ts +21 -0
  40. package/commands/projectValidate.js +112 -0
  41. package/commands/sdfAcs_authmap.d.ts +15 -0
  42. package/commands/sdfAcs_authmap.js +26 -0
  43. package/commands/sdfAcs_clean.d.ts +20 -0
  44. package/commands/sdfAcs_clean.js +22 -0
  45. package/deleteManifest.cjs +11 -0
  46. package/demo.md +26 -0
  47. package/index.d.ts +284 -0
  48. package/lib/MakeJestTestsFromDeploy.d.ts +13 -0
  49. package/lib/MakeJestTestsFromDeploy.js +60 -0
  50. package/lib/addGitKeep.d.ts +5 -0
  51. package/lib/addGitKeep.js +40 -0
  52. package/lib/addSdfObjectDirs.d.ts +5 -0
  53. package/lib/addSdfObjectDirs.js +16 -0
  54. package/lib/callCli.d.ts +7 -0
  55. package/lib/callCli.js +26 -0
  56. package/lib/compileHelper.d.ts +44 -0
  57. package/lib/compileHelper.js +196 -0
  58. package/lib/deleteProjectJson.d.ts +6 -0
  59. package/lib/deleteProjectJson.js +16 -0
  60. package/lib/deployFileHelper.d.ts +77 -0
  61. package/lib/deployFileHelper.js +249 -0
  62. package/lib/handleRootProjectJson.d.ts +10 -0
  63. package/lib/handleRootProjectJson.js +30 -0
  64. package/lib/isProd.d.ts +9 -0
  65. package/lib/isProd.js +13 -0
  66. package/lib/logHelper.d.ts +5 -0
  67. package/lib/logHelper.js +13 -0
  68. package/lib/logger.d.ts +6 -0
  69. package/lib/logger.js +10 -0
  70. package/lib/makeDeployXml.d.ts +6 -0
  71. package/lib/makeDeployXml.js +30 -0
  72. package/lib/makeJest.d.ts +12 -0
  73. package/lib/makeJest.js +58 -0
  74. package/lib/makeManifestXml.d.ts +6 -0
  75. package/lib/makeManifestXml.js +21 -0
  76. package/lib/makeProjectJson.d.ts +6 -0
  77. package/lib/makeProjectJson.js +16 -0
  78. package/lib/onErrorHelper.d.ts +31 -0
  79. package/lib/onErrorHelper.js +93 -0
  80. package/lib/pathHelpers.d.ts +133 -0
  81. package/lib/pathHelpers.js +428 -0
  82. package/lib/pause.d.ts +6 -0
  83. package/lib/pause.js +10 -0
  84. package/lib/projectJsonHelpers.d.ts +29 -0
  85. package/lib/projectJsonHelpers.js +92 -0
  86. package/lib/promptHelpers.d.ts +77 -0
  87. package/lib/promptHelpers.js +195 -0
  88. package/lib/removeFiles.d.ts +20 -0
  89. package/lib/removeFiles.js +46 -0
  90. package/lib/sdf.d.ts +11 -0
  91. package/lib/sdf.js +158 -0
  92. package/lib/spawnSuitecloudChild.d.ts +30 -0
  93. package/lib/spawnSuitecloudChild.js +88 -0
  94. package/lib/switchAuth.d.ts +17 -0
  95. package/lib/switchAuth.js +23 -0
  96. package/lib/tempFileHelper.d.ts +29 -0
  97. package/lib/tempFileHelper.js +70 -0
  98. package/lib/updateModule.d.ts +10 -0
  99. package/lib/updateModule.js +79 -0
  100. package/lib/validators.d.ts +12 -0
  101. package/lib/validators.js +25 -0
  102. package/package.json +38 -0
  103. package/safeCommands.d.ts +95 -0
  104. package/safeCommands.js +959 -0
  105. package/sdf.config.js +15 -0
  106. package/sdf.exe.js +16 -0
  107. package/templates/customizations.projectroot.d.ts +74 -0
  108. package/templates/makeModuleTypeDef.d.ts +5 -0
  109. package/templates/makeModuleTypeDef.js +29 -0
  110. package/templates/sdfGitIgnore.txt +42 -0
  111. package/templates/suitecloud.config.js +17 -0
  112. package/templates/tsconfig.ss21.projectroot.json +64 -0
  113. package/types/colors.d.ts +43 -0
@@ -0,0 +1,355 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.testFilesPrompt = exports.compileFilesPrompt = exports.fixFileUploadPaths = exports.confirmFileList = exports.getFilesFromDeployXml = exports.promptForPath = void 0;
4
+ const nodePath = require("node:path");
5
+ const errorHelper = require("../lib/onErrorHelper");
6
+ const compileHelper = require("../lib/compileHelper");
7
+ const promptHelpers = require("../lib/promptHelpers");
8
+ const pathHelpers = require("../lib/pathHelpers");
9
+ const deployFileHelper_1 = require("../lib/deployFileHelper");
10
+ const onErrorHelper_1 = require("../lib/onErrorHelper");
11
+ const spawnSuitecloud = require("../lib/spawnSuitecloudChild");
12
+ const promptHelpers_1 = require("../lib/promptHelpers");
13
+ /**
14
+ * @description - only prompt if not paths given
15
+ * @param {string} opts.message
16
+ */
17
+ const promptForPath = (opts) => {
18
+ const origin = 'promptForPath';
19
+ return {
20
+ _origin: origin,
21
+ isStackable: true,
22
+ beforeExecuting: async (options) => {
23
+ if (spawnSuitecloud.isChildProcess())
24
+ return options;
25
+ if (options.arguments.interactive)
26
+ return options;
27
+ if (options.arguments.runhooks == 'quiet')
28
+ return options;
29
+ let arrayKey = options.command === 'object:import' ? 'scriptid' : 'paths';
30
+ // only prompt if currently empty
31
+ if (Array.isArray(Reflect.get(options.arguments, arrayKey)) &&
32
+ Reflect.get(options.arguments, arrayKey)?.length !== 0)
33
+ return options;
34
+ // init
35
+ Reflect.set(options.arguments, arrayKey, []);
36
+ const choices = { 'Y': 'Yes', 'N': 'No' };
37
+ let answer = choices['Y'];
38
+ const whatToDo = async () => {
39
+ let more = await promptHelpers.promptUser({
40
+ message: opts?.message || 'Missing Message',
41
+ });
42
+ more = more.trim().toLowerCase();
43
+ // very basic validation here...
44
+ if (options.command === 'object:import') {
45
+ // note: they can enter a deploy file from the command line
46
+ if (!/^[a-z\*][\w_\*]*:[a-z\*][\w_\*]*$/.test(more)) {
47
+ process.stdout.write((0, promptHelpers_1.goColor)('BAD', '\nBad input...missing wildcards?. input removed: ', more));
48
+ return;
49
+ }
50
+ }
51
+ // add
52
+ Reflect.get(options.arguments, arrayKey).push(more);
53
+ };
54
+ while (answer !== choices['N']) {
55
+ await whatToDo();
56
+ answer = await promptHelpers.promptChoices({
57
+ choices: choices,
58
+ displayChoices: choices,
59
+ question: `Do you want to add more to this list ?`,
60
+ premessage: Reflect.get(options.arguments, arrayKey)
61
+ .map((p) => promptHelpers.goColor('HIGHLIGHT', ' ', p)).join('\n'),
62
+ default: null
63
+ });
64
+ }
65
+ return options;
66
+ },
67
+ onError: async (error) => (0, onErrorHelper_1.detectOriginAndReturn)(origin, error, (error) => {
68
+ return error;
69
+ })
70
+ };
71
+ };
72
+ exports.promptForPath = promptForPath;
73
+ /**
74
+ * @description - deploy.xml files are filtered out of an upload allowed in the upload, buuut...
75
+ * - If you provide one as the only file to upload then it will load the files listed in it
76
+ *
77
+ * - they are allowed in an import BUT that is rare so if an import see this path then it will not import
78
+ * it but treat it like an import instructions
79
+ *
80
+ */
81
+ const getFilesFromDeployXml = () => {
82
+ const origin = 'getFilesFromDeployXml';
83
+ return {
84
+ _origin: origin,
85
+ isStackable: true,
86
+ beforeExecuting: async (options) => {
87
+ if (spawnSuitecloud.isChildProcess())
88
+ return options;
89
+ // ignore this combo
90
+ if (options.command === 'file:import' &&
91
+ // @ts-expect-error it is in file:import
92
+ options.arguments?.calledfromcomparefiles)
93
+ return options;
94
+ const arrayKey = options.command === 'object:import' ? 'scriptid' : 'paths';
95
+ if (!Array.isArray(Reflect.get(options.arguments, arrayKey)))
96
+ return options;
97
+ const [first] = Reflect.get(options.arguments, arrayKey);
98
+ if (!/\bdeploy\b.*\bxml\b$/.test(first))
99
+ return options;
100
+ //zero-out the array
101
+ Reflect.set(options.arguments, arrayKey, []);
102
+ // open the file and get all the paths from it
103
+ // relies upon the xml being in a good structure
104
+ try {
105
+ const fromXml = await (0, deployFileHelper_1.extractFilePathsFromDeployXmlFile)(options.projectPath, first, options.command === 'object:import' ? 'Objects' : 'SuiteScripts');
106
+ if (options.command === 'object:import') {
107
+ Reflect.set(options.arguments, arrayKey,
108
+ // add the type prefix that doesn't exist in the deploy file
109
+ // TODO: guessing the prefix from the record folder
110
+ fromXml.map((x) => [
111
+ '*',
112
+ // e.g. ~/Objects/customrecord/customrecord__gg_allfieldtypes
113
+ x
114
+ ].join(':')));
115
+ }
116
+ else {
117
+ Reflect.set(options.arguments, arrayKey,
118
+ // add the type prefix
119
+ fromXml);
120
+ }
121
+ return options;
122
+ }
123
+ catch (e) {
124
+ throw (0, onErrorHelper_1.makeError)(origin, new Error('DeployXml Could not be found'));
125
+ }
126
+ },
127
+ onError: async (error) => (0, onErrorHelper_1.detectOriginAndReturn)(origin, error, (error) => {
128
+ return error;
129
+ })
130
+ };
131
+ };
132
+ exports.getFilesFromDeployXml = getFilesFromDeployXml;
133
+ /**
134
+ * @description -
135
+ */
136
+ const confirmFileList = () => {
137
+ const origin = 'confirmFileList';
138
+ return {
139
+ _origin: origin,
140
+ isStackable: true,
141
+ beforeExecuting: async (options) => {
142
+ if (spawnSuitecloud.isChildProcess())
143
+ return options;
144
+ const isQuiet = options.arguments.runhooks === 'quiet';
145
+ const arrayKey = options.command === 'object:import' ? 'scriptid' : 'paths';
146
+ const noFiles = Reflect.get(options.arguments, arrayKey)?.length === 0;
147
+ if (noFiles && !isQuiet) {
148
+ let answer = await promptHelpers.promptChoices({
149
+ choices: [],
150
+ displayChoices: [],
151
+ question: `Nothing to do?`,
152
+ default: null
153
+ });
154
+ return options;
155
+ }
156
+ if (noFiles && isQuiet) {
157
+ process.stdout.write(promptHelpers.goColor('INFO', 'Nothing to do'));
158
+ return options;
159
+ }
160
+ const premessage = Reflect.get(options.arguments, arrayKey)
161
+ .map((p) => promptHelpers.goColor('HIGHLIGHT', ' ', p)).join('\n');
162
+ if (isQuiet) {
163
+ process.stdout.write((0, promptHelpers_1.goColor)('SUBTLE', '\n', premessage));
164
+ }
165
+ else {
166
+ const choices = { 'Y': 'Yes', 'N': 'No' };
167
+ let answer = await promptHelpers.promptChoices({
168
+ choices: choices,
169
+ displayChoices: choices,
170
+ question: `Are you good with this list?`,
171
+ premessage,
172
+ default: null
173
+ });
174
+ // force it empty which will quit
175
+ if (answer === choices['N'])
176
+ Reflect.set(options.arguments, arrayKey, []);
177
+ }
178
+ return options;
179
+ }
180
+ };
181
+ };
182
+ exports.confirmFileList = confirmFileList;
183
+ /**
184
+ * @description - fix paths in a way that file:upload needs them fixed.
185
+ * - 0️⃣ paths that begin with SuiteScripts or SuiteBundles or SuiteApps are left as-is.
186
+ * - 1️⃣ relative paths -- these SHOULD begin with `.` or `..` or they will be treated as relative to cwd.
187
+ * - 2️⃣ globbing -- all paths are essentially viewed as a glob. globs that are
188
+ * - 3️⃣ clean and prevent bad files. e.g. typescript should be swapped for js (This should occur AFTER resolving any globs).
189
+ * - 4️⃣ check if the file exists and remove it
190
+ * - 5️⃣ finally trim to valid SDK path such as /SuiteScripts
191
+ *
192
+ * #Globbing:
193
+ * - every path here is SuiteScripts so ...
194
+ *
195
+ * - ignore certain files
196
+ */
197
+ const fixFileUploadPaths = () => {
198
+ const origin = 'fixFileUploadPaths';
199
+ return {
200
+ _origin: origin,
201
+ isStackable: true,
202
+ beforeExecuting: async (options) => {
203
+ if (!Array.isArray(options?.arguments?.paths))
204
+ options.arguments.paths = [];
205
+ // it is expected that paths should be fixed by parent processes that are calling
206
+ // TODO: is spawnSuitecloud.isChildProcess() relevant ever here and what to do
207
+ console.log(origin, { options });
208
+ console.log(options.arguments.paths);
209
+ const { projectPath } = options;
210
+ // deal with relative paths, etc 1️⃣
211
+ const shortenedPathOrGlobs = options.arguments.paths.map((path) => {
212
+ // go to the project root and get ALL the files in it
213
+ // relative paths that do not have SuiteScripts
214
+ if (/^\.+[\\\/]/.test(path) && !/\bSuiteScripts\b/.test(path))
215
+ return nodePath.join(process.cwd(),
216
+ // could be . or a ..
217
+ ...path.split(/[\\\/]/))
218
+ .replace(/^.*(\bSuiteScripts\b.*)/, '/$1');
219
+ // anything longer that might be relative but has SuiteScripts in path
220
+ const fixed = [/^.*(\bSuiteScripts\b.*)$/].reduce((p, rgx) => {
221
+ if (p)
222
+ return p;
223
+ if (!rgx.test(path))
224
+ return p;
225
+ // already good
226
+ return path.replace(rgx, '/$1');
227
+ }, '');
228
+ if (fixed)
229
+ return fixed;
230
+ // TODO: any other patterns?
231
+ }).filter(Boolean);
232
+ // globbing has to be done here before we clean 2️⃣
233
+ const filteredAgainstGlobs = await pathHelpers.getAllFilesRecursively(
234
+ // only care about the SuiteScripts as trunk of the tree
235
+ [projectPath], 'SuiteScripts', shortenedPathOrGlobs
236
+ //
237
+ );
238
+ process.stdout.write(promptHelpers.goColor('SUBTLE', '\npaths:', shortenedPathOrGlobs));
239
+ // 3️⃣
240
+ options.arguments.paths = pathHelpers.removeIllegalFileCabinetFiles(filteredAgainstGlobs);
241
+ return options;
242
+ },
243
+ };
244
+ };
245
+ exports.fixFileUploadPaths = fixFileUploadPaths;
246
+ /**
247
+ * @description - Guesses at what files might be TS and then generates
248
+ * @deprecated - not sure the benefit of this is worth the trouble
249
+ * @todo -
250
+ * @returns {SdfCommand}
251
+ */
252
+ const compileFilesPrompt = () => {
253
+ return {
254
+ _origin: "compileFilesPrompt",
255
+ isStackable: true,
256
+ beforeExecuting: async (options) => {
257
+ const isQuiet = options.arguments.runhooks === 'quiet';
258
+ let { files } = await compileHelper.generateTsConfigFromList(options.arguments.paths, false) || { files: [] };
259
+ if (files.length === 0)
260
+ return options;
261
+ const choices = { 'Y': 'Yes', 'N': 'No' };
262
+ let answer = isQuiet
263
+ ? choices['Y']
264
+ : await promptHelpers.promptChoices({
265
+ choices: choices,
266
+ displayChoices: choices,
267
+ question: `Would you like to compile typescript?`,
268
+ premessage: JSON.stringify(files, null, 2),
269
+ default: choices['Y']
270
+ });
271
+ if (answer === choices['N']) {
272
+ promptHelpers.goColor('INFO', '\nNo Files to compile');
273
+ return options;
274
+ }
275
+ process.stdout.write((0, promptHelpers_1.goColor)('INFO', '\ncompiling'));
276
+ // ({files} = await compileHelper.generateTsConfigFromList(options.arguments.paths, true) || {files: []});
277
+ // compile it
278
+ await compileHelper.compileTsConfig();
279
+ return options;
280
+ }
281
+ };
282
+ };
283
+ exports.compileFilesPrompt = compileFilesPrompt;
284
+ /**
285
+ * @description - calls jest for the files involved
286
+ * ⚠️ - make sure paths are fixed first
287
+ */
288
+ const testFilesPrompt = () => {
289
+ const origin = 'testFilesPrompt';
290
+ let command;
291
+ return {
292
+ _origin: origin,
293
+ isStackable: true,
294
+ beforeExecuting: async (options) => {
295
+ command = options.command || 'unknown';
296
+ const choices = { 'Y': 'Yes', 'N': 'No' };
297
+ // remove the "N" choice for prod
298
+ if (options._isProd)
299
+ delete choices['N'];
300
+ let answer;
301
+ if (spawnSuitecloud.isChildProcess() || options.arguments.runhooks === 'quiet') {
302
+ answer = choices['Y'];
303
+ }
304
+ else {
305
+ answer = await promptHelpers.promptChoices({
306
+ choices: choices,
307
+ displayChoices: choices,
308
+ premessage: options._isProd ? 'This is PROD' : '',
309
+ question: `Would you like to run relatedTests?`,
310
+ default: choices['Y']
311
+ });
312
+ }
313
+ if (answer === choices['N'])
314
+ return options;
315
+ // make sure paths are correct for jest
316
+ const didTheyPass = await compileHelper.runJestTest(options.arguments.paths.map((p) => {
317
+ return nodePath.join(options.projectPath.replace(/^(.*)(.\bFileCabinet\b.\bSuiteScripts\b.*)?$/, '$1/FileCabinet'), p.replace(/^.*FileCabinet/, ''));
318
+ }), Boolean(!options._isProd))
319
+ .then(() => true)
320
+ .catch((e) => {
321
+ // TODO turn this on
322
+ // if (options._isProd) throw errorHelper.makeError(origin,new Error('Tests must exist AND pass for PROD ' + options.command));
323
+ return false;
324
+ });
325
+ if (didTheyPass)
326
+ return options;
327
+ if (!spawnSuitecloud.isChildProcess() && options.arguments.runhooks !== 'quiet') {
328
+ // remove the "N" choice for prod
329
+ const choices2 = { 'Y': 'Yes' };
330
+ const answer2 = await promptHelpers.promptChoices({
331
+ choices: { ...choices2, 'N': 'No' },
332
+ displayChoices: choices2,
333
+ premessage: options._isProd ? 'This is PROD' : '',
334
+ question: `Tests failed. Would you like to upload anyway?`,
335
+ default: null,
336
+ });
337
+ if (answer2 === 'Yes')
338
+ return options;
339
+ throw errorHelper.makeError(origin, new Error('User Chose to Quit'));
340
+ }
341
+ // if( !didTheyPass)
342
+ throw errorHelper.makeError(origin, new Error('Tests failed in child process'));
343
+ },
344
+ onError: async (error) => {
345
+ return errorHelper.detectOriginAndReturn(origin, error, (error) => {
346
+ if (/PROD/m.test(error)) {
347
+ process.stdout.write(promptHelpers.goColor('BAD', '\n ❌ ', error.replace(/.*\bDetails:\n?/, '')));
348
+ }
349
+ return error;
350
+ });
351
+ },
352
+ };
353
+ };
354
+ exports.testFilesPrompt = testFilesPrompt;
355
+ //# sourceMappingURL=fileUpload.js.map
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @file sdf/commands/generic.ts
3
+ * @author Gerald Gillespie <gerald.gillespie@fullscript.com>
4
+ */
5
+ export declare const proxiedBlocker: {};
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ /**
3
+ * @file sdf/commands/generic.ts
4
+ * @author Gerald Gillespie <gerald.gillespie@fullscript.com>
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.proxiedBlocker = void 0;
8
+ exports.proxiedBlocker = new Proxy({}, {
9
+ get(target, property, receiver) {
10
+ throw new Error('nope');
11
+ }
12
+ });
13
+ //# sourceMappingURL=generic.js.map
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @file /Users/geraldgillespie/code/nsaccounts/sdf/commands/objectImport
3
+ * @author Gerald Gillespie <gerald.gillespie@fullscript.com>
4
+ */
5
+ import { SdfCommand } from "index";
6
+ /**
7
+ * @description - the createObjectsDir job can organize them automatically and compliments this well
8
+ * @requires createObjectsDir
9
+ */
10
+ export declare const forceDestination: () => SdfCommand;
11
+ /**
12
+ * @description -
13
+ */
14
+ export declare const forceTypeAll: () => SdfCommand;
15
+ /**
16
+ * @description - similar tothe fixFileUploadPaths. we need to compare against netsuite
17
+ * Also we don't filter out any files
18
+ */
19
+ export declare const fixObjectImportPaths: () => SdfCommand;
20
+ /**
21
+ * @description - if scriptid is a glob then we need a list so that we can filter it
22
+ * @deprecated - replaced by a better stack
23
+ * @requires saveObjectListToTemp - This requires the object:list task to run this handler
24
+ *
25
+ */
26
+ export declare const importGlobOrXml: () => SdfCommand;
27
+ /**
28
+ * @description - Creates an Objects dir. e.g.
29
+ * - check the arguments to import
30
+ * @param {ObjectImportOptions} options
31
+ */
32
+ export declare const createObjectsDir: () => SdfCommand;