@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,195 @@
1
+ "use strict";
2
+ /**
3
+ * @file sdf/lib/promptHelpers.ts
4
+ * @author Gerald Gillespie <gerald.gillespie@fullscript.com>
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.promptChoices = exports.promptUserSync = exports.promptUser = exports.detectPrompt = exports.appendToPrevious = exports.goColor = void 0;
8
+ const readline = require('node:readline');
9
+ const SpawnSuitecloud = require("./spawnSuitecloudChild");
10
+ const Colors = {
11
+ WARN: "\u001B[38;5;214m" /* COLORS.ORANGE */,
12
+ BAD: "\u001B[31m" /* COLORS.RED */,
13
+ INFO: "\u001B[36m" /* COLORS.CYAN */,
14
+ HIGHLIGHT: "\u001B[33m" /* COLORS.YELLOW */,
15
+ GOOD: "\u001B[32m" /* COLORS.GREEN */, // '\x1b[32m', // green
16
+ NONE: "\u001B[0m" /* COLORS.RESET_ALL */, // '\x1b[0m', // reset
17
+ BOLD: "\u001B[1m" /* COLORS.BOLD */, // '\x1b[1m',
18
+ SUBTLE: "\u001B[90m" /* COLORS.BRIGHT_BLACK */, // `\x1b[90m` // grey
19
+ };
20
+ /**
21
+ * @description
22
+ * @param {Array<string|keyof typeof Colors>} colors
23
+ * @param {string[]} messages
24
+ * @param {boolean} skipReset
25
+ * @returns {string}
26
+ */
27
+ exports.goColor = ((colors, ...messages) => {
28
+ let skip = typeof messages[messages.length - 1] === 'boolean' ? messages.pop() : false;
29
+ const msgStrings = messages.map((m) => {
30
+ switch (true) {
31
+ case m === null:
32
+ return null;
33
+ case typeof m === 'object':
34
+ return JSON.stringify(m);
35
+ default:
36
+ return String(m);
37
+ }
38
+ });
39
+ // @ts-expect-error is good
40
+ return `${skip ? '' : Colors.NONE}${[colors].flat().map((c) => Colors?.[c]).join('')}${msgStrings.join('')}${skip ? '' : Colors.NONE}`;
41
+ });
42
+ const QuestionPrompt = (0, exports.goColor)('SUBTLE', 'ANSWER: ');
43
+ /**
44
+ * @description
45
+ * @param {string} previousMessage
46
+ * @param {string} toAppend
47
+ * @returns {string}
48
+ */
49
+ const appendToPrevious = (previousMessage, toAppend) => {
50
+ readline.moveCursor(process.stdout, 0, -1);
51
+ // Position the cursor at the end of the previous line by using its length
52
+ readline.cursorTo(process.stdout, previousMessage.length);
53
+ process.stdout.write(toAppend);
54
+ };
55
+ exports.appendToPrevious = appendToPrevious;
56
+ /**
57
+ * @description -
58
+ * @param line
59
+ * @returns {boolean}
60
+ */
61
+ const detectPrompt = (line) => {
62
+ // console.log(line === QuestionPrompt? 'ischild': '');
63
+ return line === (0, exports.goColor)('SUBTLE', 'ANSWER: ');
64
+ };
65
+ exports.detectPrompt = detectPrompt;
66
+ /**
67
+ * @param {{message: string; timeout?: number;}} options
68
+ * @param {(string)=>any} [callback]
69
+ * @returns {Promise<string|null>}
70
+ */
71
+ const promptUser = async ({ message, timeout }, callback) => {
72
+ const rl = readline.createInterface({
73
+ input: process.stdin,
74
+ output: process.stdout,
75
+ prompt: QuestionPrompt
76
+ });
77
+ console.log(`\n${(0, exports.goColor)('BOLD', message || 'Hit Enter to continue')}`);
78
+ // Display the prompt
79
+ rl.prompt();
80
+ return new Promise((resolve, reject) => {
81
+ rl.once('line', (line) => {
82
+ console.log((0, exports.goColor)('SUBTLE', 'You pressed:', line, false));
83
+ resolve(line);
84
+ });
85
+ if (typeof timeout === 'number') {
86
+ setTimeout(() => {
87
+ resolve(null);
88
+ }, timeout);
89
+ }
90
+ rl.once('close', (e) => {
91
+ console.log((0, exports.goColor)('SUBTLE', 'Exiting'));
92
+ if (e)
93
+ reject(e);
94
+ });
95
+ }).then((answer) => {
96
+ rl.close();
97
+ return (typeof callback === 'function' ? callback(answer) : answer);
98
+ }).catch((err) => {
99
+ if (typeof callback === 'function')
100
+ return callback(err);
101
+ else
102
+ throw (err);
103
+ });
104
+ };
105
+ exports.promptUser = promptUser;
106
+ const promptUserSync = ({ message, timeout }, callback) => {
107
+ const rl = readline.createInterface({
108
+ input: process.stdin,
109
+ output: process.stdout,
110
+ prompt: (0, exports.goColor)('SUBTLE', '> ')
111
+ });
112
+ console.log(`\n${(0, exports.goColor)('BOLD', message || 'Hit Enter to continue')}`);
113
+ // Display the prompt
114
+ rl.prompt();
115
+ rl.once('line', (line) => {
116
+ console.log((0, exports.goColor)('SUBTLE', 'You pressed:', line, false));
117
+ rl.close();
118
+ });
119
+ if (typeof timeout === 'number') {
120
+ setTimeout(() => {
121
+ rl.close();
122
+ }, timeout);
123
+ }
124
+ rl.once('close', (e) => {
125
+ console.log((0, exports.goColor)('SUBTLE', 'Exiting'));
126
+ if (e)
127
+ throw e;
128
+ });
129
+ };
130
+ exports.promptUserSync = promptUserSync;
131
+ /**
132
+ * @description - pass in a array of strings to be presented with a numbered choice list
133
+ * 0 is always "QUIT" (even if not presented) and the program will exit with code 0 (coincidence on the number)
134
+ * "-1" is always the default -- this helps with automation
135
+ *
136
+ * @param {{choices: string[]}} options
137
+ * @returns {Promise<string>}
138
+ */
139
+ const promptChoices = async (options) => {
140
+ const { choices, question, displayChoices, childDefault } = options;
141
+ if (typeof childDefault !== 'undefined' && SpawnSuitecloud.isChildProcess())
142
+ return options.childDefault;
143
+ if (displayChoices.length !== choices.length)
144
+ throw new Error(`displayChoices must match choices`);
145
+ let answer;
146
+ if ((Array.isArray(choices) !== Array.isArray(displayChoices))
147
+ || choices?.length !== displayChoices?.length) {
148
+ throw new Error(`displayChoices must be of same structure and length as choices`);
149
+ }
150
+ // const choices: Array<typeof nature> = ['path','regex'];
151
+ if (Reflect.get(choices, 'Q'))
152
+ throw new Error('choices cannot contain index of "Q"');
153
+ let maxKeyLength = 0;
154
+ const reIndexChoices = Array.isArray(choices) ? [undefined, ...choices] : choices;
155
+ const printChoices = (Array.isArray(displayChoices)
156
+ ? ['QUIT', ...displayChoices].map((c, i) => [(i === 0 ? 'Q' : String(i)), c])
157
+ : Object.entries({ ...{ 'Q': 'FORCE QUIT' + (0, exports.goColor)('SUBTLE', ' skips cleanup -- not recommend') }, ...displayChoices }))
158
+ .sort(([a, y], [b, z]) => {
159
+ maxKeyLength = Math.max(maxKeyLength, a.length);
160
+ return (a === 'Q' ? -1 : 0);
161
+ })
162
+ .map(([i, c]) => `${(0, exports.goColor)('HIGHLIGHT', i.padEnd(maxKeyLength, ' '))}: ${(0, exports.goColor)('INFO', c)}`);
163
+ const nag = async (msg) => {
164
+ if (typeof msg === 'string')
165
+ process.stdout.write((0, exports.goColor)('SUBTLE', '\nYou entered:', msg));
166
+ if (options.premessage)
167
+ process.stdout.write((0, exports.goColor)('SUBTLE', '\n', options.premessage));
168
+ answer = await (0, exports.promptUser)({
169
+ message: `${question} \n${printChoices.join('\n')}`,
170
+ });
171
+ };
172
+ while (
173
+ // @ts-expect-error that's ok
174
+ !reIndexChoices[answer] &&
175
+ !['Q', '-1', '0'].includes(String(answer))) {
176
+ // console.log({reIndexChoices, answer});
177
+ await nag(String(answer));
178
+ }
179
+ if (
180
+ // intentional quit
181
+ ['Q', '0'].includes(String(answer))
182
+ // implied quit
183
+ || (String(answer) === '-1' && ['Q', 'QUIT'].includes(String(options?.default || 0)))) {
184
+ process.stdout.write((0, exports.goColor)('WARN', '\nYou chose to Quit ✅\n'));
185
+ process.exit(1);
186
+ }
187
+ return (String(answer) === '-1' && options.default
188
+ ? options.default
189
+ : Array.isArray(choices)
190
+ ? reIndexChoices[Number.parseInt(String(answer), 10)]
191
+ : choices[answer]);
192
+ throw new Error('misconfigured question');
193
+ };
194
+ exports.promptChoices = promptChoices;
195
+ //# sourceMappingURL=promptHelpers.js.map
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @file sdf/lib/removeFiles.ts
3
+ * @author Gerald Gillespie <gerald.gillespie@fullscript.com>
4
+ */
5
+ type FilesList = 'manifest.xml' | 'deploy.xml' | 'project.json' | 'tsconfig.json' | 'jest.config.js' | '.project.json';
6
+ /**
7
+ * @description - Deletes files from the list
8
+ * - optional backup with .bak extension
9
+ * @param options
10
+ * @param {boolean|string} [options.doBackup] - A non-empty short string can be used as the extension. Default is .bak
11
+ * @param {string} options.root
12
+ * @param {string[]} options.fileNames
13
+ * @returns {string[]} - State of the deletes
14
+ */
15
+ declare const removeFiles: (options: {
16
+ fileNames: (FilesList | string)[];
17
+ root: string;
18
+ doBackup?: boolean | string;
19
+ }) => (string | null)[];
20
+ export = removeFiles;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ /**
3
+ * @file sdf/lib/removeFiles.ts
4
+ * @author Gerald Gillespie <gerald.gillespie@fullscript.com>
5
+ */
6
+ const fs = require("node:fs");
7
+ const nodePath = require("node:path");
8
+ const promptHelpers = require("./promptHelpers");
9
+ const promptHelpers_1 = require("./promptHelpers");
10
+ const filesList = ['manifest.xml', 'deploy.xml', 'project.json', '.project.json', 'tsconfig.json', 'jest.config.js'];
11
+ /**
12
+ * @description - Deletes files from the list
13
+ * - optional backup with .bak extension
14
+ * @param options
15
+ * @param {boolean|string} [options.doBackup] - A non-empty short string can be used as the extension. Default is .bak
16
+ * @param {string} options.root
17
+ * @param {string[]} options.fileNames
18
+ * @returns {string[]} - State of the deletes
19
+ */
20
+ const removeFiles = (options) => {
21
+ const { fileNames, root, doBackup } = options;
22
+ return fileNames.map((name) => {
23
+ const path = nodePath.join(root, name);
24
+ if (![...filesList].includes(name))
25
+ return null;
26
+ const extension = typeof doBackup === 'string' && /^\w{2,4}$/.test(doBackup)
27
+ ? `.${doBackup}`
28
+ : doBackup ? '.bak' : '';
29
+ try {
30
+ if (doBackup)
31
+ fs.cpSync(path, path + extension);
32
+ process.stdout.write(promptHelpers.goColor('INFO', '\nremoving ', (0, promptHelpers_1.goColor)('SUBTLE', ' ', path, ' ')));
33
+ fs.rmSync(path);
34
+ return path;
35
+ }
36
+ catch (error) {
37
+ const { message } = error;
38
+ if (/no such file/.test(message))
39
+ return path;
40
+ process.stdout.write(promptHelpers.goColor('INFO', '\nfailed to remove ', path, '\n', promptHelpers.goColor('BAD', message)));
41
+ return null;
42
+ }
43
+ });
44
+ };
45
+ module.exports = removeFiles;
46
+ //# sourceMappingURL=removeFiles.js.map
package/lib/sdf.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @file sdf/lib/sdf.ts
3
+ * @author Gerald Gillespie <gerald.gillespie@fullscript.com>
4
+ */
5
+ /**
6
+ * @description - Extract arguments and create a native command and execute it.
7
+ * - Note that native SDF supports having a colon and that is not recommended here.
8
+ * @param {string[]} commandLineArguments
9
+ * @returns {void}
10
+ */
11
+ export declare const executeCommand: (commandLineArguments: string[]) => void;
package/lib/sdf.js ADDED
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ /**
3
+ * @file sdf/lib/sdf.ts
4
+ * @author Gerald Gillespie <gerald.gillespie@fullscript.com>
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.executeCommand = void 0;
8
+ const makeProjectJson = require("./makeProjectJson");
9
+ const spawnNativeSdf = require("./callCli");
10
+ const removeFiles = require("./removeFiles");
11
+ const sdfAcsAuthMap = require("../commands/sdfAcs_authmap");
12
+ const nodePath = require("node:path");
13
+ const commandsThatNativelyNeedAuthId = ['account:setup', 'account:setup:ci'];
14
+ const commandsThatWithGrace = ['account:manageauth', '-h', '--help', '--version'];
15
+ const passThroughCommands = ['--version', '-h', '--help', '-i'];
16
+ const printSdfAcsHelp = () => {
17
+ console.log('\n');
18
+ [
19
+ ['sdfAcs:clean', 'removes native manifest, deploy and project.json files'],
20
+ ].forEach(([a, b]) => console.log([a.padEnd(30), b].join('')));
21
+ console.log('\n');
22
+ };
23
+ /**
24
+ * @description - Extract the command arguments that are not-native to suitecloud-cli
25
+ * - Passthrough the rest.
26
+ * @param {string[]} commandLineArguments - From the original call
27
+ * @returns {Record<string,string|true>}
28
+ */
29
+ const handleCommandLine = (commandLineArguments) => {
30
+ return commandLineArguments.reduce((accumulator, argument, index, original) => {
31
+ // commands
32
+ if (/:/.test(argument) && index === 0)
33
+ return {
34
+ ...accumulator,
35
+ [argument]: null,
36
+ };
37
+ // skip values
38
+ if (!argument.startsWith("-"))
39
+ return accumulator;
40
+ let property = argument;
41
+ // arguments with no value means the next argument is a property and the implied value is true
42
+ let [nextArgument] = [original[index + 1]].filter((n) => !n || !n.startsWith('-'));
43
+ // after filtering if we have a nextArgument the value must be true
44
+ let value = typeof nextArgument === 'undefined' ? true : nextArgument;
45
+ return {
46
+ ...accumulator,
47
+ [property]: value,
48
+ };
49
+ }, {});
50
+ };
51
+ /**
52
+ * @description - Extract arguments and create a native command and execute it.
53
+ * - Note that native SDF supports having a colon and that is not recommended here.
54
+ * @param {string[]} commandLineArguments
55
+ * @returns {void}
56
+ */
57
+ const executeCommand = (commandLineArguments) => {
58
+ // quick backup straight up
59
+ const filesToRemove = ['manifest.xml', 'deploy.xml', 'project.json'];
60
+ const removed = removeFiles({
61
+ fileNames: ['manifest.xml', 'deploy.xml', 'project.json'],
62
+ root: process.cwd(),
63
+ doBackup: true
64
+ });
65
+ const { '--authid': authidFolder, '--debug': debug, ...remaining } = handleCommandLine(commandLineArguments);
66
+ if (debug)
67
+ console.log({ commandLineArguments });
68
+ // handle a ':' being used in the real authid
69
+ const splitAuthIdFolder = typeof authidFolder === 'string' ? authidFolder.split(':') : [];
70
+ const folder = splitAuthIdFolder.pop();
71
+ const authid = splitAuthIdFolder.join(':') || folder;
72
+ if (debug)
73
+ console.log({ remaining, authid, folder });
74
+ const [command, ...nativeArguments] = Object.entries(remaining).flat().filter((a) => (typeof a === 'string'));
75
+ switch (true) {
76
+ case command === '-h':
77
+ case command === '--help':
78
+ printSdfAcsHelp();
79
+ break;
80
+ case command === 'sdfAcs:authmap':
81
+ // use 'dist' here because it does not matter and that should always exist
82
+ makeProjectJson(nodePath.join(process.cwd(), '.project.json'), 'foo', 'dist', Boolean(debug));
83
+ makeProjectJson(nodePath.join(process.cwd(), 'project.json'), 'foo', 'dist', Boolean(debug));
84
+ sdfAcsAuthMap({ authid, folder }).then((result) => {
85
+ const message = typeof result === 'boolean' ? `That Mapping Is${result ? '' : ' NOT'} Supported!!` : `${result}`;
86
+ console.log(message);
87
+ removeFiles({
88
+ fileNames: ['project.json', '.project.json', 'deploy.xml', 'manifest.xml'],
89
+ root: nodePath.join(process.cwd(), 'dist'),
90
+ doBackup: false
91
+ });
92
+ });
93
+ return;
94
+ case command === 'sdfAcs:clean':
95
+ if (folder)
96
+ removed.push(...removeFiles({
97
+ fileNames: ['manifest.xml', 'deploy.xml', 'project.json'],
98
+ root: nodePath.join(process.cwd(), folder),
99
+ doBackup: true
100
+ }));
101
+ console.log('Removed', removed.filter(Boolean));
102
+ return;
103
+ }
104
+ const hasHelpOrVersion = !passThroughCommands.includes(command) &&
105
+ nativeArguments.some((n) => passThroughCommands.includes(n));
106
+ const filteredArguments = nativeArguments.filter((n) => passThroughCommands.includes(n));
107
+ let sdfProcess;
108
+ if (hasHelpOrVersion && !authid && !folder) {
109
+ if (debug)
110
+ console.log('skipping project json', 'passing', { filteredArguments });
111
+ spawnNativeSdf([command, ...filteredArguments]);
112
+ return;
113
+ }
114
+ // most commands need an authid and a folder
115
+ if (!commandsThatWithGrace.includes(command) && (!authid || !folder))
116
+ throw new Error('Missing required argument');
117
+ // restore this property for authid
118
+ if (commandsThatNativelyNeedAuthId.includes(command))
119
+ nativeArguments.push('--authid', authid);
120
+ // before calling native, store the authid and the folder in a temporary project.json
121
+ if (debug)
122
+ console.log('making project jsons', folder);
123
+ makeProjectJson(nodePath.join(process.cwd(), '.project.json'), authid, folder, Boolean(debug));
124
+ makeProjectJson(nodePath.join(process.cwd(), 'project.json'), authid, folder, Boolean(debug));
125
+ sdfProcess = hasHelpOrVersion
126
+ ? spawnNativeSdf([command, ...nativeArguments])
127
+ : spawnNativeSdf([command, ...nativeArguments]);
128
+ sdfProcess.on('close', (err) => {
129
+ console.log('\nSDFENDSDFENDSDFENDSDFENDSDFENDSDFENDSDFENDSDFENDSDFENDSDFENDSDFENDSDFEND');
130
+ if (debug)
131
+ console.log(err);
132
+ const removed = [];
133
+ // can do deletes here
134
+ if (folder)
135
+ removed.push(...removeFiles({
136
+ fileNames: ['manifest.xml', 'deploy.xml', 'project.json', '.project.json'],
137
+ root: nodePath.join(process.cwd(), folder),
138
+ doBackup: false
139
+ }));
140
+ else
141
+ removed.push(...removeFiles({
142
+ fileNames: ['manifest.xml', 'deploy.xml'],
143
+ root: nodePath.join(process.cwd()),
144
+ doBackup: false
145
+ }));
146
+ removed.push(...removeFiles({
147
+ fileNames: ['project.json', '.project.json'],
148
+ root: nodePath.join(process.cwd()),
149
+ doBackup: false
150
+ }));
151
+ if (debug)
152
+ console.log('removing files', removed);
153
+ else
154
+ console.log('cleaning up', removed.length);
155
+ });
156
+ };
157
+ exports.executeCommand = executeCommand;
158
+ //# sourceMappingURL=sdf.js.map
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @file /Users/geraldgillespie/code/nsaccounts/sdf/lib/spawnSuitecloudChild
3
+ * @author Gerald Gillespie <gerald.gillespie@fullscript.com>
4
+ */
5
+ export declare const getChildEnv: () => string;
6
+ /**
7
+ * @description - whether the process is a child process or not
8
+ * @returns {boolean}
9
+ */
10
+ export declare const isChildProcess: () => boolean;
11
+ /**
12
+ * @description - a suitecloud child process run in the current-working directory
13
+ * will re-evaluate the same suitecloud.config.js that the outer process evaluated.
14
+ * You must design for this. Such as being re-prompted for the same questions, etc.
15
+ * - if you are piping stdout then you will need to interact with these choices programmatically.
16
+ * - if you inherit stdout then the user will be prompted (but it may be repetitive)
17
+ *
18
+ * @param {{onPrompt: Function}} options - a handler where you will get a handle to stdin to interact with the prompt.
19
+ * @returns {Promise<number>}
20
+ */
21
+ export declare const createAsync: (options: {
22
+ command: string;
23
+ args: string[];
24
+ interact: boolean;
25
+ ultraQuiet?: boolean;
26
+ cwd?: string;
27
+ onData?: (lines: string[]) => void;
28
+ onPrompt?: (lines: string[], stdin: any) => void;
29
+ onMessage?: (lines: string) => void;
30
+ }) => Promise<number>;
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ /**
3
+ * @file /Users/geraldgillespie/code/nsaccounts/sdf/lib/spawnSuitecloudChild
4
+ * @author Gerald Gillespie <gerald.gillespie@fullscript.com>
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.createAsync = exports.isChildProcess = exports.getChildEnv = void 0;
8
+ const cp = require("node:child_process");
9
+ const promptHelpers = require("./promptHelpers");
10
+ const sdfExec = process.env['SUITECLOUD_EXE'] || 'sdf';
11
+ const CONSTANTS = {
12
+ get ENV_IS_CHILD_TO_SDF() {
13
+ return 'IS_CHILD_TO_SDF';
14
+ },
15
+ };
16
+ const getChildEnv = () => CONSTANTS.ENV_IS_CHILD_TO_SDF;
17
+ exports.getChildEnv = getChildEnv;
18
+ /**
19
+ * @description - whether the process is a child process or not
20
+ * @returns {boolean}
21
+ */
22
+ const isChildProcess = () => Boolean(process.env[(0, exports.getChildEnv)()]);
23
+ exports.isChildProcess = isChildProcess;
24
+ /**
25
+ * @description - a suitecloud child process run in the current-working directory
26
+ * will re-evaluate the same suitecloud.config.js that the outer process evaluated.
27
+ * You must design for this. Such as being re-prompted for the same questions, etc.
28
+ * - if you are piping stdout then you will need to interact with these choices programmatically.
29
+ * - if you inherit stdout then the user will be prompted (but it may be repetitive)
30
+ *
31
+ * @param {{onPrompt: Function}} options - a handler where you will get a handle to stdin to interact with the prompt.
32
+ * @returns {Promise<number>}
33
+ */
34
+ const createAsync = async (options) => new Promise((ok, no) => {
35
+ process.stdout.write(promptHelpers.goColor('WARN', `\ninvoking suitecloud w/ \`${options.command}\``));
36
+ const innerProcess = cp.spawn(sdfExec, [
37
+ options.command, // 'file:list',
38
+ // authId, etc should already be in the args list
39
+ ...options.args // ['--folder',options.folder]
40
+ ], {
41
+ stdio: [
42
+ 'inherit',
43
+ options.interact ? 'inherit' : 'pipe',
44
+ 'inherit',
45
+ ],
46
+ cwd: options.cwd || process.cwd(),
47
+ env: { ...process.env, [(0, exports.getChildEnv)()]: String(process.pid) }
48
+ });
49
+ // process.stdout.write(['\n','processes', process.pid, process.ppid, innerProcess.pid].join(' '));
50
+ let lines = 0;
51
+ if (!options.interact) {
52
+ innerProcess.stdout.on('data', data => {
53
+ const dStrings = data.toString().split(/\r?\n/);
54
+ lines += dStrings.length;
55
+ if (!options.ultraQuiet) {
56
+ process.stdout.write(promptHelpers.goColor('INFO', '...', lines || ''));
57
+ }
58
+ if (typeof options.onMessage === 'function') {
59
+ options.onMessage(promptHelpers.goColor('INFO', '...', lines || ''));
60
+ }
61
+ //console.log({dStrings});
62
+ // detect prompt
63
+ const isPrompt = dStrings.find((l) => promptHelpers.detectPrompt(l));
64
+ if (typeof options.onPrompt === 'function')
65
+ options.onPrompt(dStrings, innerProcess.stdin);
66
+ if (typeof options.onData === 'function')
67
+ options.onData(dStrings);
68
+ });
69
+ }
70
+ innerProcess.on('error', (e) => {
71
+ if (!options.ultraQuiet)
72
+ process.stdout.write(promptHelpers.goColor('BAD', '\n', e));
73
+ if (typeof options.onMessage === 'function') {
74
+ options.onMessage(promptHelpers.goColor('BAD', '\n', e));
75
+ }
76
+ no(e);
77
+ });
78
+ innerProcess.on('close', (e) => {
79
+ if (e)
80
+ no(e);
81
+ ok(0);
82
+ });
83
+ }).catch(err => {
84
+ process.stdout.write(promptHelpers.goColor('BAD', 'error', err));
85
+ throw err;
86
+ });
87
+ exports.createAsync = createAsync;
88
+ //# sourceMappingURL=spawnSuitecloudChild.js.map
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @file sdf/lib/switchAuth.ts
3
+ * - detect an authid property and extract it.
4
+ * ## authid implies:
5
+ * - a switch to a different directory based on the account tied to that auth
6
+ * - a switch to that auth
7
+ * @author Gerald Gillespie <gerald.gillespie@fullscript.com>
8
+ */
9
+ /**
10
+ * @description - Extracts and acts on an authid property
11
+ * @param options
12
+ * @returns {typeof options} - Similar object but without the authid
13
+ */
14
+ declare const processAuthId: (options: object & {
15
+ authid: string;
16
+ }) => {};
17
+ export = processAuthId;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ /**
3
+ * @file sdf/lib/switchAuth.ts
4
+ * - detect an authid property and extract it.
5
+ * ## authid implies:
6
+ * - a switch to a different directory based on the account tied to that auth
7
+ * - a switch to that auth
8
+ * @author Gerald Gillespie <gerald.gillespie@fullscript.com>
9
+ */
10
+ const switchAuth = (options) => {
11
+ // handle project.json file
12
+ };
13
+ /**
14
+ * @description - Extracts and acts on an authid property
15
+ * @param options
16
+ * @returns {typeof options} - Similar object but without the authid
17
+ */
18
+ const processAuthId = (options) => {
19
+ const { authid, ...remaining } = options;
20
+ return remaining;
21
+ };
22
+ module.exports = processAuthId;
23
+ //# sourceMappingURL=switchAuth.js.map
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @file /Users/geraldgillespie/code/nsaccounts/sdf/lib/tempFileHelper
3
+ * @author Gerald Gillespie <gerald.gillespie@fullscript.com>
4
+ */
5
+ export declare const FileNames: {
6
+ accountManagementList: string;
7
+ objectList: string;
8
+ fileList: string;
9
+ };
10
+ /**
11
+ * @description - usually a temp file is:
12
+ * - created by an 'onCompleted' handler on a child process
13
+ * - consumed by a 'beforeExecuting' handler of a parent process
14
+ * - therefore watch out for file cleanup activities
15
+ * @param {string} fileName
16
+ * @param {string} data - serialized data
17
+ * @returns {Promise<string>} - the new file and path
18
+ */
19
+ export declare const makeTempFile: (fileName: string, data: string) => Promise<string>;
20
+ /**
21
+ * @description - read and delete the temp file
22
+ * @param {string} fileName
23
+ * @returns {Promise<string>}
24
+ */
25
+ export declare const consumeTempFile: (fileName: string) => Promise<string>;
26
+ /**
27
+ * @description - removes temp files
28
+ */
29
+ export declare const removeTempFiles: (prefix?: string) => Promise<void>;