@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,428 @@
1
+ "use strict";
2
+ /**
3
+ * @file /Users/geraldgillespie/code/nsaccounts/sdf/lib/pathHelpers
4
+ * @author Gerald Gillespie <gerald.gillespie@fullscript.com>
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.convertFileExtensions = exports.removeIllegalObjectFiles = exports.removeIllegalFileCabinetFiles = exports.getAllFilesRecursively = exports.findMatchingDirectories = exports.getAccountFolders = exports.getAbsolutePath = exports.makeTempDirForSdf = exports.removeFile = exports.removeTempDirForSdf = exports.getAccountDir = exports.getRelativeOf = exports.getDifferenceFromProjectRootToFileCabinet = exports.getFolderHoldingFileCabinetPlus = exports.getRootOfAccount = exports.getSuiteCloudConfigPath = exports.joinPaths = exports.combineOverLappingPaths = exports.getRootOfProject = exports.hasFile = exports.CONSTANTS = void 0;
8
+ const nodePath = require("node:path");
9
+ const fs = require("node:fs/promises");
10
+ const validators_1 = require("./validators");
11
+ const minimatch_1 = require("minimatch");
12
+ const makeManifest = require("./makeManifestXml");
13
+ const packageJsonLocation = nodePath.dirname(require.resolve('#root/package.json'));
14
+ const AccountRoots = [
15
+ 'SuiteScripts',
16
+ 'FileCabinet',
17
+ 'Objects',
18
+ ];
19
+ exports.CONSTANTS = {
20
+ TSCONFIG_SS21: 'tsconfig.ss21.json',
21
+ SDF_DEFAULT_ROOT: 'src',
22
+ SDF_TEMP_ROOT: '.src',
23
+ SDF_FILE_CABINET: 'FileCabinet',
24
+ SDF_TEMP_ROOT_RGX: new RegExp('(?:^|\W)[.]src\b')
25
+ };
26
+ /**
27
+ * @description - have it or not
28
+ * @param filePath
29
+ * @returns {false|string}
30
+ */
31
+ const hasFile = async (filePath) => {
32
+ const path = nodePath.join(...[filePath].flat());
33
+ return fs.access(path, fs.constants.R_OK)
34
+ .then(() => path)
35
+ .catch(() => false);
36
+ };
37
+ exports.hasFile = hasFile;
38
+ /**
39
+ * ⚠️⚠️⚠️⚠️⚠️ WARNING: this gets the root of this project and not the project using this as a dependency!
40
+ * @returns {string} e.g. /Users/jdoe/code/nsaccounts
41
+ */
42
+ const getRootOfProject = () => {
43
+ return packageJsonLocation;
44
+ };
45
+ exports.getRootOfProject = getRootOfProject;
46
+ /**
47
+ * @description - for example:
48
+ * - a relative path and the current directory
49
+ * - the entire path and a SuiteScripts path that both have SuiteScripts in it
50
+ * @param path1 -- must be an absolute path
51
+ * @param path2 - can be a partial path, relative path or special SDK path e.g. /SuiteScripts
52
+ */
53
+ const combineOverLappingPaths = (path1, path2) => {
54
+ // remove any separators or dots
55
+ const normalizedPath1 = nodePath.normalize(path1);
56
+ const normalizedPath2 = nodePath.normalize(path2);
57
+ // first resolve any relative paths
58
+ const projectPath = process.env.SUITECLOUD_PROJECT_PATH || normalizedPath1;
59
+ const newPath2 = (0, exports.getAbsolutePath)({
60
+ projectPath,
61
+ filePath: path2
62
+ });
63
+ // address any obvious overlap
64
+ if (normalizedPath1.includes(normalizedPath2))
65
+ return normalizedPath1;
66
+ if (normalizedPath2.includes(normalizedPath1))
67
+ return normalizedPath2;
68
+ // Split paths into segments (ignoring any empty segments)
69
+ const parts1 = normalizedPath1.split(/[\/\\]/).filter(Boolean);
70
+ const parts2 = normalizedPath2.split(/[\/\\]/).filter(Boolean);
71
+ // Determine the maximum overlap length between the end of parts1 and start of parts2.
72
+ let overlapLength = 0;
73
+ const maxOverlap = Math.min(parts1.length, parts2.length);
74
+ for (let i = maxOverlap; i > 0; i--) {
75
+ // Compare the last i segments of parts1 with the first i segments of parts2.
76
+ if (parts1.slice(-i).join(nodePath.sep) === parts2.slice(0, i).join(nodePath.sep)) {
77
+ overlapLength = i;
78
+ break;
79
+ }
80
+ }
81
+ // Create the combined segments: all of parts1 plus the non-overlapping part of parts2.
82
+ const combinedParts = parts1.concat(parts2.slice(overlapLength));
83
+ // Reconstruct the path. Preserve absolute paths from the first argument.
84
+ // If path1 is absolute, ensure the result starts with the path separator.
85
+ let combinedPath = combinedParts.join(nodePath.sep);
86
+ if (nodePath.isAbsolute(normalizedPath1)) {
87
+ combinedPath = nodePath.sep + combinedPath;
88
+ }
89
+ return combinedPath;
90
+ };
91
+ exports.combineOverLappingPaths = combineOverLappingPaths;
92
+ const joinPaths = (...paths) => {
93
+ return nodePath.join(...paths);
94
+ };
95
+ exports.joinPaths = joinPaths;
96
+ /**
97
+ *
98
+ * @param {string} [path]
99
+ * @returns {Promise<string>}
100
+ */
101
+ const getSuiteCloudConfigPath = async (path) => {
102
+ const pathToUse = path || process.env['SUITECLOUD_PROJECT_ROOT'] || process.cwd();
103
+ await fs.access(pathToUse, fs.constants.R_OK);
104
+ return pathToUse;
105
+ };
106
+ exports.getSuiteCloudConfigPath = getSuiteCloudConfigPath;
107
+ /**
108
+ *
109
+ * @param {string} folder - the current place that you are. e.g process.cwd() or __dirname or whatever
110
+ * @param {boolean} [folderNameOnly] - where to strip off the folders e.g. 12345323
111
+ * @returns {string} e.g. /path/to/12346357
112
+ */
113
+ const getRootOfAccount = (folder, folderNameOnly) => {
114
+ // get the root and subtract that
115
+ const projectRoot = (0, exports.getRootOfProject)();
116
+ const projectFolder = folder.replace(projectRoot, '')
117
+ // slit on dir separators
118
+ .split(/[\\\/]/)
119
+ // filter out leading slash artifacts
120
+ .filter(Boolean)
121
+ // return the first
122
+ .shift();
123
+ console.log({ projectFolder, projectRoot });
124
+ return folderNameOnly === true ? projectFolder : nodePath.join(projectRoot, projectFolder);
125
+ };
126
+ exports.getRootOfAccount = getRootOfAccount;
127
+ /**
128
+ * @description - aka. "projectPath" in SDF SDK - the combination of where the config resolves and the projectFolder
129
+ * @param {string} anyCabinetPathInAccount
130
+ * @returns {string} e.g. /Users/jdoe/code/nsaccounts/24365476/src
131
+ */
132
+ const getFolderHoldingFileCabinet = (anyCabinetPathInAccount) => {
133
+ if (/\bFileCabinet\b/.test(anyCabinetPathInAccount))
134
+ // get the filecabinet and subtract that
135
+ return anyCabinetPathInAccount.replace(/^(.*?).\bFileCabinet\b.*$/, '$1');
136
+ if (process.env['SUITECLOUD_PROJECT_PATH'])
137
+ return process.env['SUITECLOUD_PROJECT_PATH'];
138
+ throw new Error('Cannot find FileCabinet. You must provide a `defaultProjectFolder` argument or be in an account');
139
+ };
140
+ /**
141
+ * @description - If the provided path does not contain the reference then this will scan the descendants for the first one
142
+ * @param path
143
+ * @returns {Promise<string>}
144
+ */
145
+ const getFolderHoldingFileCabinetPlus = async (path) => {
146
+ if (/\bFileCabinet\b/.test(path))
147
+ return getFolderHoldingFileCabinet(path);
148
+ // go hunting for it.
149
+ const list = await fs.readdir(path, { recursive: true });
150
+ const candidate = list.find((c) => /\bFileCabinet\b/.test(c) && !exports.CONSTANTS.SDF_TEMP_ROOT_RGX.test(c));
151
+ return getFolderHoldingFileCabinet(nodePath.join(path, candidate));
152
+ };
153
+ exports.getFolderHoldingFileCabinetPlus = getFolderHoldingFileCabinetPlus;
154
+ /**
155
+ *
156
+ * @param {string} anyCabinetPathInAccount
157
+ * @param {string} [projectRoot]
158
+ * @returns {string} * @returns {string} e.g. 24365476/src
159
+ */
160
+ const getDifferenceFromProjectRootToFileCabinet = (anyCabinetPathInAccount, projectRoot) => {
161
+ const root = projectRoot || (0, exports.getRootOfProject)();
162
+ let tempFolder = anyCabinetPathInAccount.replace(root, '').replace(/^[\\\/]?/, '');
163
+ // get the filecabinet and subtract that
164
+ return tempFolder.replace(/(.*?).\bFileCabinet\b.*$/, '$1');
165
+ };
166
+ exports.getDifferenceFromProjectRootToFileCabinet = getDifferenceFromProjectRootToFileCabinet;
167
+ /**
168
+ * @description - same as path.relative
169
+ * @param projectJsonLocation
170
+ * @param projectRoot
171
+ */
172
+ const getRelativeOf = (projectJsonLocation, projectRoot) => {
173
+ return nodePath.relative(projectJsonLocation, projectRoot);
174
+ };
175
+ exports.getRelativeOf = getRelativeOf;
176
+ /**
177
+ * @description - for common folders
178
+ * @param {string} type
179
+ * @param {string[]} extras
180
+ * @param {string} [target] - defaults to cwd
181
+ * @returns {string} - The full path
182
+ *
183
+ */
184
+ const getAccountDir = async (type, extras, target) => {
185
+ let dirs = [];
186
+ switch (type) {
187
+ case 'FileCabinet':
188
+ dirs.push('FileCabinet');
189
+ break;
190
+ case 'Objects':
191
+ dirs.push('Objects');
192
+ break;
193
+ case 'Translations':
194
+ dirs.push('Translations');
195
+ break;
196
+ case 'AccountConfiguration':
197
+ dirs.push('AccountConfiguration');
198
+ break;
199
+ case 'SuiteScripts':
200
+ dirs.push('FileCabinet', 'SuiteScripts');
201
+ break;
202
+ case 'Templates':
203
+ dirs.push('FileCabinet', 'Templates');
204
+ break;
205
+ case 'Web Site Hosting Files':
206
+ dirs.push('FileCabinet', 'Web Site Hosting Files');
207
+ default:
208
+ break;
209
+ }
210
+ console.log({ target, dirs, type });
211
+ const fcPath = await (0, exports.getFolderHoldingFileCabinetPlus)(target || process.env['SUITECLOUD_PROJECT_PATH'] || process.cwd());
212
+ if (dirs.length > 0)
213
+ return nodePath.join(fcPath, ...dirs, ...extras.flatMap((x) => x.split(/\\\//)));
214
+ throw new Error('Unknown type');
215
+ };
216
+ exports.getAccountDir = getAccountDir;
217
+ const removeTempDirForSdf = async (projectPath) => {
218
+ const newPath = nodePath.join(projectPath, '..', exports.CONSTANTS.SDF_TEMP_ROOT);
219
+ await fs.rm(newPath, { recursive: true, force: true }).catch((e) => {
220
+ console.error(e);
221
+ });
222
+ return newPath;
223
+ };
224
+ exports.removeTempDirForSdf = removeTempDirForSdf;
225
+ /**
226
+ * @description
227
+ * @param {string[]} pathBits
228
+ */
229
+ const removeFile = async (pathBits) => {
230
+ const newPath = nodePath.join(...pathBits);
231
+ await fs.rm(newPath, { force: true }).catch((e) => {
232
+ console.error(e);
233
+ });
234
+ return newPath;
235
+ };
236
+ exports.removeFile = removeFile;
237
+ /**
238
+ * @description - makes a `temp` directory in the same account root
239
+ * - no need to copy anything over
240
+ * @param {string} projectPath
241
+ * @returns {Promise<string>}
242
+ */
243
+ const makeTempDirForSdf = async (projectPath) => {
244
+ const newPath = nodePath.join(projectPath, '..', exports.CONSTANTS.SDF_TEMP_ROOT);
245
+ // clean up old files first
246
+ await (0, exports.removeTempDirForSdf)(projectPath);
247
+ await fs.mkdir(newPath, { recursive: true });
248
+ // make manifest file
249
+ await makeManifest(newPath, 'temp');
250
+ return newPath;
251
+ };
252
+ exports.makeTempDirForSdf = makeTempDirForSdf;
253
+ /**
254
+ * @description - Figures out the path
255
+ * - if you have a relative path then compare it against cwd
256
+ * - if you have an absolute path then check if it is actually a NetSuite project path
257
+ * -
258
+ */
259
+ const getAbsolutePath = (options) => {
260
+ if (!nodePath.isAbsolute(options.filePath))
261
+ return nodePath.resolve(nodePath.join(options.executionPath || process.cwd(), options.filePath));
262
+ if (/^[\\\/]\b(SuiteScripts|SuiteBundles|Suite\w+)\b/.test(options.filePath)) {
263
+ return nodePath.resolve(nodePath.join(options.projectPath, 'FileCabinet', options.filePath));
264
+ }
265
+ if (/^[\\\/]\b(Objects)\b/.test(options.filePath)) {
266
+ return nodePath.resolve(nodePath.join(options.projectPath, options.filePath));
267
+ }
268
+ // e.g. /Users/geraldgillespie/project/src/FileCabinet/SuiteScripts
269
+ return nodePath.resolve(options.filePath);
270
+ };
271
+ exports.getAbsolutePath = getAbsolutePath;
272
+ /**
273
+ * @description -
274
+ */
275
+ const getAccountFolders = async (path) => {
276
+ const tier1List = await fs.readdir(path, { withFileTypes: true });
277
+ return tier1List.flatMap((p) => {
278
+ if (!p.isDirectory())
279
+ return [];
280
+ return (0, validators_1.isValidAccountFolderName)(p.name) ? [p.name] : [];
281
+ });
282
+ };
283
+ exports.getAccountFolders = getAccountFolders;
284
+ /**
285
+ * Recursively find directories whose names match a series of tests at each depth.
286
+ * @param {string} dir - The directory to start searching from.
287
+ * @param {*[]} tests - Current recursion depth (default is 0).
288
+ * @returns {Promise<string[]>} - An array of matching directory paths.
289
+ */
290
+ const findMatchingDirectories = async (dir, tests) => {
291
+ // remove it and make the test list shorter
292
+ const [rgx, ...rest] = tests;
293
+ let matchingDirs = [];
294
+ // Stop recursion if we exceed the maximum depth
295
+ if (typeof rgx === 'undefined')
296
+ return matchingDirs;
297
+ let entries;
298
+ try {
299
+ entries = await fs.readdir(dir, { withFileTypes: true });
300
+ }
301
+ catch (error) {
302
+ console.error(`Error reading directory ${dir}:`, error);
303
+ return matchingDirs;
304
+ }
305
+ for (const entry of entries) {
306
+ if (entry.isDirectory()) {
307
+ const fullPath = nodePath.join(dir, entry.name);
308
+ // If the directory name passes the test, add its full path to the results
309
+ if (rgx.test(entry.name)) {
310
+ matchingDirs.push(fullPath);
311
+ // Recursively search within the directory
312
+ const subDirs = await (0, exports.findMatchingDirectories)(fullPath, rest);
313
+ matchingDirs = matchingDirs.concat(subDirs);
314
+ }
315
+ }
316
+ }
317
+ return matchingDirs;
318
+ };
319
+ exports.findMatchingDirectories = findMatchingDirectories;
320
+ /**
321
+ * @description - Get the remaining path
322
+ * @param {string[]} paths
323
+ * @param {'SuiteScripts'} type -
324
+ * @param {Array<function|string|RegExp>} [tests] - functions or globs or regex to apply. Only `some` has to pass.
325
+ * @returns {Promise<string[]>}
326
+ */
327
+ const getAllFilesRecursively = async (paths, type, tests) => {
328
+ // console.log({paths, tests});
329
+ const unique = new Set();
330
+ const replacer = [new RegExp(`^.*(\\b${type}\\b.*)$`), '/$1'];
331
+ const testers = tests.flatMap((test) => {
332
+ if (typeof test === 'function')
333
+ return [test];
334
+ if (typeof test === 'string')
335
+ return [(x) => (0, minimatch_1.minimatch)(x, test)];
336
+ if (typeof test === 'object' && test instanceof RegExp)
337
+ return [(x) => test.test(x)];
338
+ return [];
339
+ });
340
+ await Promise.allSettled(paths.map(async (path) => {
341
+ const branch = await fs.readdir(path, { recursive: true, withFileTypes: true });
342
+ branch.forEach((p) => {
343
+ if (!p.isFile())
344
+ return;
345
+ if (!p.parentPath.includes(type))
346
+ return;
347
+ let modifiedP = nodePath.join(p.parentPath, p.name);
348
+ if (Array.isArray(replacer))
349
+ modifiedP = modifiedP.replace(...replacer);
350
+ if (testers.some((test) => test(modifiedP)))
351
+ unique.add(modifiedP);
352
+ });
353
+ }));
354
+ return [...unique];
355
+ };
356
+ exports.getAllFilesRecursively = getAllFilesRecursively;
357
+ /**
358
+ * @description -- you should convert first
359
+ * @param paths
360
+ */
361
+ const removeIllegalFileCabinetFiles = (paths) => {
362
+ return paths.filter((p) => {
363
+ if (/\.tsx?$/.test(p))
364
+ return false;
365
+ if (/\.csv$/.test(p))
366
+ return false;
367
+ if (/\.test\.js$/.test(p))
368
+ return false;
369
+ if (/\.map$/.test(p))
370
+ return false;
371
+ // anything in these subfolders
372
+ if (/__(tests?|mocks?)__/.test(p))
373
+ return false;
374
+ if (/\.attributes\b/.test(p))
375
+ return false;
376
+ if (/\.attr\.xml\b/.test(p))
377
+ return false;
378
+ if (/\.[mc]js$/.test(p))
379
+ return false;
380
+ // suitecloud
381
+ if (/\bsuitecloud\.config\b/.test(p))
382
+ return false;
383
+ if (/\bproject\b.*\bjson\b/.test(p))
384
+ return false;
385
+ // any deploy files
386
+ if (/\bdeploy\b.*\bxml\b/.test(p))
387
+ return false;
388
+ // jest config
389
+ if (/\bjest\b/.test(p))
390
+ return false;
391
+ // tscnofig
392
+ if (/\btsconfig\b/.test(p))
393
+ return false;
394
+ // hidden files e.g. .gitKeep
395
+ if (/[\\\/]\./.test(p))
396
+ return false;
397
+ if (/\beslint\b/.test(p))
398
+ return false;
399
+ return true;
400
+ });
401
+ };
402
+ exports.removeIllegalFileCabinetFiles = removeIllegalFileCabinetFiles;
403
+ /**
404
+ * @description - A legal object file has only one extension '.xml'
405
+ * And the scriptid inside matches its file name. We cannot open files here
406
+ * @param paths
407
+ */
408
+ const removeIllegalObjectFiles = (paths) => {
409
+ return paths.filter((p) => {
410
+ if (!/^(.*\/)?[a-z_\d\*]+\.xml$/.test(p))
411
+ return false;
412
+ });
413
+ // open the file
414
+ };
415
+ exports.removeIllegalObjectFiles = removeIllegalObjectFiles;
416
+ /**
417
+ * @description - e.g. ts to js
418
+ * @param paths
419
+ */
420
+ const convertFileExtensions = (paths) => {
421
+ return paths.map((p) => {
422
+ if (/\.ts$/.test(p))
423
+ return p.replace(/(\.d)?\.ts$/, '.js');
424
+ return p;
425
+ });
426
+ };
427
+ exports.convertFileExtensions = convertFileExtensions;
428
+ //# sourceMappingURL=pathHelpers.js.map
package/lib/pause.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @file sdf/lib/pause.ts
3
+ * @author Gerald Gillespie <gerald.gillespie@fullscript.com>
4
+ */
5
+ declare const pause: () => never;
6
+ export = pause;
package/lib/pause.js ADDED
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ /**
3
+ * @file sdf/lib/pause.ts
4
+ * @author Gerald Gillespie <gerald.gillespie@fullscript.com>
5
+ */
6
+ const pause = () => {
7
+ throw new Error('this should be a pause detection');
8
+ };
9
+ module.exports = pause;
10
+ //# sourceMappingURL=pause.js.map
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @file /Users/geraldgillespie/code/nsaccounts/sdf/lib/projectJsonHelpers
3
+ * @author Gerald Gillespie <gerald.gillespie@fullscript.com>
4
+ */
5
+ import { ProjectJsonContents } from '../index';
6
+ /**
7
+ *
8
+ * @param location
9
+ * @param altName
10
+ */
11
+ export declare const readProjectJson: (location: string[], altName?: string) => Promise<any>;
12
+ /**
13
+ * @description - re-usable ProjectJson updated
14
+ * @param {ProjectJsonContents} options
15
+ * @param {string[]} location
16
+ * @param {string} [altName] e.g. project.x.json
17
+ * @returns {ProjectJsonContents}
18
+ */
19
+ export declare const updateProjectJson: <T extends ProjectJsonContents>(options: T, location: string[], altName?: "project.json" | string) => Promise<T>;
20
+ export declare const readProjectJsonSync: (location: string[], altName?: string) => any;
21
+ /**
22
+ * @description - re-usable ProjectJson updated
23
+ * @param {ProjectJsonContents} options
24
+ * @param {string[]} location
25
+ * @param {string} [altName] e.g. project.x.json
26
+ * @param {boolean} [keepExisting]
27
+ * @returns {ProjectJsonContents}
28
+ */
29
+ export declare const updateProjectJsonSync: <T extends ProjectJsonContents>(options: T, location: string[], altName?: "project.json" | string, keepExisting?: boolean) => T;
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ /**
3
+ * @file /Users/geraldgillespie/code/nsaccounts/sdf/lib/projectJsonHelpers
4
+ * @author Gerald Gillespie <gerald.gillespie@fullscript.com>
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.updateProjectJsonSync = exports.readProjectJsonSync = exports.updateProjectJson = exports.readProjectJson = void 0;
8
+ const fs = require("node:fs/promises");
9
+ const fsSync = require("node:fs");
10
+ const nodePath = require("node:path");
11
+ const promptHelpers_1 = require("./promptHelpers");
12
+ /**
13
+ *
14
+ * @param location
15
+ * @param altName
16
+ */
17
+ const readProjectJson = async (location, altName) => {
18
+ if (location.length === 0)
19
+ location.push(process.cwd());
20
+ const filePath = nodePath.join(...location, altName || 'project.json');
21
+ const serializedContents = await fs.readFile(filePath, { encoding: 'utf8' }).catch(() => ('{}'));
22
+ return JSON.parse(serializedContents);
23
+ };
24
+ exports.readProjectJson = readProjectJson;
25
+ /**
26
+ * @description - re-usable ProjectJson updated
27
+ * @param {ProjectJsonContents} options
28
+ * @param {string[]} location
29
+ * @param {string} [altName] e.g. project.x.json
30
+ * @returns {ProjectJsonContents}
31
+ */
32
+ const updateProjectJson = async (options, location, altName) => {
33
+ if (location.length === 0)
34
+ location.push(process.cwd());
35
+ const filePath = nodePath.join(...location, altName || 'project.json');
36
+ const data = await (0, exports.readProjectJson)(location, altName || 'project.json');
37
+ if (Object.keys(options).length > 0) {
38
+ process.stdout.write((0, promptHelpers_1.goColor)('SUBTLE', '\nUpdating project json', JSON.stringify(data, null, 2)));
39
+ Object.entries(options).forEach(([key, value]) => {
40
+ data[key] = value;
41
+ });
42
+ await fs.writeFile(filePath, JSON.stringify(data, null, 2), { encoding: 'utf8' });
43
+ }
44
+ // if( !data.defaultAuthId )
45
+ return data;
46
+ };
47
+ exports.updateProjectJson = updateProjectJson;
48
+ const readProjectJsonSync = (location, altName) => {
49
+ if (location.length === 0)
50
+ location.push(process.cwd());
51
+ const filePath = nodePath.join(...location, altName || 'project.json');
52
+ try {
53
+ const serializedContents = fsSync.readFileSync(filePath, { encoding: 'utf8' });
54
+ return JSON.parse(serializedContents);
55
+ }
56
+ catch (err) {
57
+ return {};
58
+ }
59
+ };
60
+ exports.readProjectJsonSync = readProjectJsonSync;
61
+ /**
62
+ * @description - re-usable ProjectJson updated
63
+ * @param {ProjectJsonContents} options
64
+ * @param {string[]} location
65
+ * @param {string} [altName] e.g. project.x.json
66
+ * @param {boolean} [keepExisting]
67
+ * @returns {ProjectJsonContents}
68
+ */
69
+ const updateProjectJsonSync = (options, location, altName, keepExisting) => {
70
+ if (location.length === 0)
71
+ location.push(process.cwd());
72
+ const filePath = nodePath.join(...location, altName || 'project.json');
73
+ let serializedContents = '{}';
74
+ try {
75
+ serializedContents = fsSync.readFileSync(filePath, { encoding: 'utf8' });
76
+ }
77
+ catch (e) {
78
+ serializedContents = '{}';
79
+ }
80
+ const data = JSON.parse(serializedContents);
81
+ if (Object.keys(options).length > 0) {
82
+ Object.entries(options).forEach(([key, value]) => {
83
+ if (keepExisting && Reflect.has(data, key))
84
+ return;
85
+ data[key] = value;
86
+ });
87
+ fsSync.writeFileSync(filePath, JSON.stringify(data, null, 2), { encoding: 'utf8' });
88
+ }
89
+ return data;
90
+ };
91
+ exports.updateProjectJsonSync = updateProjectJsonSync;
92
+ //# sourceMappingURL=projectJsonHelpers.js.map
@@ -0,0 +1,77 @@
1
+ /**
2
+ * @file sdf/lib/promptHelpers.ts
3
+ * @author Gerald Gillespie <gerald.gillespie@fullscript.com>
4
+ */
5
+ import { COLORS } from '../types/colors';
6
+ declare const Colors: {
7
+ readonly WARN: COLORS.ORANGE;
8
+ readonly BAD: COLORS.RED;
9
+ readonly INFO: COLORS.CYAN;
10
+ readonly HIGHLIGHT: COLORS.YELLOW;
11
+ readonly GOOD: COLORS.GREEN;
12
+ readonly NONE: COLORS.RESET_ALL;
13
+ readonly BOLD: COLORS.BOLD;
14
+ readonly SUBTLE: COLORS.BRIGHT_BLACK;
15
+ };
16
+ interface GoColor {
17
+ /**
18
+ * @des
19
+ * @param {colors: string|(keyof typeof Colors)| Array<string|keyof typeof Colors>} colors
20
+ * @param {string[]} messages
21
+ * @param {boolean} [skipReset=false]
22
+ * @returns {string}
23
+ */
24
+ (colors: string | (keyof typeof Colors) | Array<string | keyof typeof Colors>, messages: any[], skipReset?: boolean): string;
25
+ (colors: string | (keyof typeof Colors) | Array<string | keyof typeof Colors>, ...messages: Array<any | boolean>): string;
26
+ }
27
+ /**
28
+ * @description
29
+ * @param {Array<string|keyof typeof Colors>} colors
30
+ * @param {string[]} messages
31
+ * @param {boolean} skipReset
32
+ * @returns {string}
33
+ */
34
+ export declare const goColor: GoColor;
35
+ /**
36
+ * @description
37
+ * @param {string} previousMessage
38
+ * @param {string} toAppend
39
+ * @returns {string}
40
+ */
41
+ export declare const appendToPrevious: (previousMessage: string, toAppend: string) => void;
42
+ /**
43
+ * @description -
44
+ * @param line
45
+ * @returns {boolean}
46
+ */
47
+ export declare const detectPrompt: (line: string) => boolean;
48
+ /**
49
+ * @param {{message: string; timeout?: number;}} options
50
+ * @param {(string)=>any} [callback]
51
+ * @returns {Promise<string|null>}
52
+ */
53
+ export declare const promptUser: ({ message, timeout }: {
54
+ message: string;
55
+ timeout?: number | null;
56
+ }, callback?: (answer: any) => any) => Promise<any>;
57
+ export declare const promptUserSync: ({ message, timeout }: {
58
+ message: string;
59
+ timeout?: number | null;
60
+ }, callback?: (answer: any) => any) => void;
61
+ /**
62
+ * @description - pass in a array of strings to be presented with a numbered choice list
63
+ * 0 is always "QUIT" (even if not presented) and the program will exit with code 0 (coincidence on the number)
64
+ * "-1" is always the default -- this helps with automation
65
+ *
66
+ * @param {{choices: string[]}} options
67
+ * @returns {Promise<string>}
68
+ */
69
+ export declare const promptChoices: <C>(options: {
70
+ choices: Record<string, C> | C[];
71
+ displayChoices: string[] | Record<string, string>;
72
+ default: C | null;
73
+ premessage?: string;
74
+ question: string;
75
+ childDefault?: C;
76
+ }) => Promise<C & string>;
77
+ export {};