@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,196 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file /Users/geraldgillespie/code/nsaccounts/sdf/lib/compileHelper
|
|
4
|
+
* @author Gerald Gillespie <gerald.gillespie@fullscript.com>
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.runJestTest = exports.getAllTestFiles = exports.makeJestConfig = exports.generateTsConfigFromList = exports.previewFile = exports.compileTsConfig = exports.hasTsConfig = void 0;
|
|
8
|
+
const fs = require("node:fs/promises");
|
|
9
|
+
const nodePath = require("node:path");
|
|
10
|
+
const pathHelpers = require("./pathHelpers");
|
|
11
|
+
const cp = require("node:child_process");
|
|
12
|
+
const promptHelpers = require("./promptHelpers");
|
|
13
|
+
/**
|
|
14
|
+
* @description
|
|
15
|
+
* @returns {string|void}
|
|
16
|
+
*/
|
|
17
|
+
const hasTsConfig = async () => {
|
|
18
|
+
const path = nodePath.join(process.cwd(), 'tsconfig.json');
|
|
19
|
+
return fs.access(path, fs.constants.R_OK)
|
|
20
|
+
.then(() => path)
|
|
21
|
+
.catch(() => { });
|
|
22
|
+
};
|
|
23
|
+
exports.hasTsConfig = hasTsConfig;
|
|
24
|
+
/**
|
|
25
|
+
* @description - Trigger a compile of TypeScript according to the local config file
|
|
26
|
+
* @param configFile
|
|
27
|
+
*/
|
|
28
|
+
const compileTsConfig = async (configFile) => {
|
|
29
|
+
const fileName = configFile || './tsconfig.json';
|
|
30
|
+
// build tsc
|
|
31
|
+
console.log('building tsc');
|
|
32
|
+
return new Promise((ok, no) => {
|
|
33
|
+
process.stdout.write(promptHelpers.goColor('SUBTLE', '\nRunning compile'));
|
|
34
|
+
const tsc = cp.spawn('npx', ['tsc', '-p', `${fileName}`], {
|
|
35
|
+
cwd: process.cwd(),
|
|
36
|
+
// combination of getting all the data without tripping up the parent error state
|
|
37
|
+
stdio: [
|
|
38
|
+
'inherit',
|
|
39
|
+
'inherit',
|
|
40
|
+
'pipe'
|
|
41
|
+
]
|
|
42
|
+
});
|
|
43
|
+
tsc.stderr.on('data', (e) => {
|
|
44
|
+
process.stdout.write(e);
|
|
45
|
+
});
|
|
46
|
+
tsc.on('close', (e) => {
|
|
47
|
+
if (e)
|
|
48
|
+
ok(e);
|
|
49
|
+
ok(0);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
exports.compileTsConfig = compileTsConfig;
|
|
54
|
+
/**
|
|
55
|
+
* @param path
|
|
56
|
+
* @returns {string} - contents
|
|
57
|
+
*/
|
|
58
|
+
const previewFile = async (path) => fs.readFile(path, { encoding: 'utf8' });
|
|
59
|
+
exports.previewFile = previewFile;
|
|
60
|
+
/**
|
|
61
|
+
* @description - takes a list of files and create a TS config. JS files becomes TS only if they exist.
|
|
62
|
+
* - relative paths will be used
|
|
63
|
+
* @param {string[]} jsPaths - could be a list of paths from deploy.xml or not.
|
|
64
|
+
* @param {string} [rootConfigFile='tsconfig.ss21.json'] - defaults to tsconfig.ss21.json
|
|
65
|
+
* @returns {{config:string; files: string[]}} - path of the new tsconfig file
|
|
66
|
+
*/
|
|
67
|
+
const generateTsConfigFromList = async (jsPaths, overwriteConfig, rootConfigFile) => {
|
|
68
|
+
const rootConfig = nodePath.join(pathHelpers.getRootOfAccount(process.cwd()), rootConfigFile || pathHelpers.CONSTANTS.TSCONFIG_SS21);
|
|
69
|
+
// verify the projects root tsconfig exists (or complain)
|
|
70
|
+
try {
|
|
71
|
+
await fs.access(rootConfig, fs.constants.R_OK);
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
throw new Error('Root config ' + rootConfig + ' does not exist');
|
|
75
|
+
}
|
|
76
|
+
const pathToRoot = nodePath.relative(process.cwd(), nodePath.dirname(rootConfig));
|
|
77
|
+
const uniqueList = new Set();
|
|
78
|
+
jsPaths.map(async (path) => {
|
|
79
|
+
// only care about ts or js
|
|
80
|
+
if (!/\.[jt]s$/.test(path))
|
|
81
|
+
return;
|
|
82
|
+
let candidate = /^\.+\//.test(path)
|
|
83
|
+
? nodePath.join(process.cwd(), path).replace(/\.js$/, 'ts')
|
|
84
|
+
: path.replace(/^.*(\bSuiteScripts\b.*)\.[tj]s$/, '$1.js');
|
|
85
|
+
let fileExists = false;
|
|
86
|
+
if (/\.js$/.test(path)) {
|
|
87
|
+
fileExists = await fs.access(candidate).then(() => true).catch(() => false);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
fileExists = true;
|
|
91
|
+
}
|
|
92
|
+
if (fileExists)
|
|
93
|
+
uniqueList.add(candidate.replace(process.cwd(), '.'));
|
|
94
|
+
});
|
|
95
|
+
const uniqueListAsArray = [...uniqueList];
|
|
96
|
+
let newConfigPath = null;
|
|
97
|
+
if (overwriteConfig) {
|
|
98
|
+
newConfigPath = nodePath.join(process.cwd(), 'tsconfig.json');
|
|
99
|
+
// extract existing info
|
|
100
|
+
{
|
|
101
|
+
const tsconfig = (await fs.readFile(newConfigPath, { encoding: 'utf-8' })
|
|
102
|
+
.then((j) => JSON.parse(j))
|
|
103
|
+
.catch(() => ({ extends: undefined, files: undefined })));
|
|
104
|
+
// update the files
|
|
105
|
+
await fs.writeFile(newConfigPath, JSON.stringify({
|
|
106
|
+
...tsconfig,
|
|
107
|
+
extends: tsconfig.extends,
|
|
108
|
+
files: [
|
|
109
|
+
...uniqueListAsArray,
|
|
110
|
+
// write a relative entry to the root types e.g."../../../../../types/*.d.ts",
|
|
111
|
+
nodePath.join(nodePath.relative(process.cwd(), pathHelpers.getRootOfAccount(process.cwd())), 'types', '*.d.ts')
|
|
112
|
+
]
|
|
113
|
+
}, null, 2), { encoding: 'utf-8' });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return { config: newConfigPath, files: uniqueListAsArray };
|
|
117
|
+
};
|
|
118
|
+
exports.generateTsConfigFromList = generateTsConfigFromList;
|
|
119
|
+
/**
|
|
120
|
+
* @description
|
|
121
|
+
*/
|
|
122
|
+
const makeJestConfig = async () => {
|
|
123
|
+
const jestFilePath = nodePath.join(process.cwd(), 'jest.config.js');
|
|
124
|
+
await fs.access(jestFilePath, fs.constants.R_OK).catch(() => {
|
|
125
|
+
process.stdout.write(promptHelpers.goColor('SUBTLE', 'Creating Jest File'));
|
|
126
|
+
return fs.writeFile(jestFilePath, [
|
|
127
|
+
`// this file was created by SDF. You do not need to have this file checked`,
|
|
128
|
+
`const {makeJest} = require('#root/sdf/lib/makeJest.js');`,
|
|
129
|
+
`module.exports = makeJest();`
|
|
130
|
+
].join('\n'), { encoding: 'utf8' });
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
exports.makeJestConfig = makeJestConfig;
|
|
134
|
+
/**
|
|
135
|
+
* @description
|
|
136
|
+
*/
|
|
137
|
+
const getAllTestFiles = async () => fs.readdir(process.cwd(), { recursive: true }).then((list) => {
|
|
138
|
+
return list.filter((f) => /\.test\.js$/.test(f)).map((f) => nodePath.join(process.cwd(), f));
|
|
139
|
+
});
|
|
140
|
+
exports.getAllTestFiles = getAllTestFiles;
|
|
141
|
+
/**
|
|
142
|
+
* @description - we might be running tests OR we might be testing files
|
|
143
|
+
* @param {string[]} jsFilesToTest - Get the list of files from a dryrun
|
|
144
|
+
* @param {boolean} allowMissing - whether to require tests or not
|
|
145
|
+
*/
|
|
146
|
+
const runJestTest = async (jsFilesToTest, allowMissing) => {
|
|
147
|
+
const jsOnly = jsFilesToTest.filter((js) => /\.js$/.test(js));
|
|
148
|
+
if (jsOnly.length === 0)
|
|
149
|
+
return 0;
|
|
150
|
+
// const jsFilesToTest = await getEveryJsTestFromTheDeployXml([deployXmlPath]);
|
|
151
|
+
const jestArgs = ['--clearMocks']; //'--ci']; // '--clearCache'];
|
|
152
|
+
if (!jsFilesToTest.includes('ALL')) {
|
|
153
|
+
// if the list are just files
|
|
154
|
+
jestArgs.push('--findRelatedTests');
|
|
155
|
+
jestArgs.push(...jsOnly);
|
|
156
|
+
if (allowMissing)
|
|
157
|
+
jestArgs.push('--passWithNoTests');
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
if (allowMissing)
|
|
161
|
+
jestArgs.push('--passWithNoTests');
|
|
162
|
+
// jestArgs.push('./**/*.js');
|
|
163
|
+
// the list is test.js files
|
|
164
|
+
}
|
|
165
|
+
process.stdout.write(promptHelpers.goColor('WARN', '\nRunning tests', jestArgs, '\n'));
|
|
166
|
+
const p = process;
|
|
167
|
+
return new Promise((ok, no) => {
|
|
168
|
+
const jest = cp.spawn('npx', ['jest',
|
|
169
|
+
//'--showConfig'
|
|
170
|
+
...jestArgs
|
|
171
|
+
], {
|
|
172
|
+
cwd: process.cwd(),
|
|
173
|
+
// combination of getting all the data without tripping up the parent error state
|
|
174
|
+
stdio: [
|
|
175
|
+
'inherit',
|
|
176
|
+
'inherit',
|
|
177
|
+
'pipe'
|
|
178
|
+
],
|
|
179
|
+
shell: true,
|
|
180
|
+
});
|
|
181
|
+
jest.stderr.on('data', (e) => {
|
|
182
|
+
const dString = e.toString();
|
|
183
|
+
if (/Running all tests instead/m.test(dString)) {
|
|
184
|
+
throw new Error('invalid test pattern');
|
|
185
|
+
}
|
|
186
|
+
p.stdout.write(e);
|
|
187
|
+
});
|
|
188
|
+
jest.on('close', (e) => {
|
|
189
|
+
if (e)
|
|
190
|
+
no(e);
|
|
191
|
+
ok(0);
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
};
|
|
195
|
+
exports.runJestTest = runJestTest;
|
|
196
|
+
//# sourceMappingURL=compileHelper.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file sdf/lib/deleteProjectJson.ts
|
|
4
|
+
* @author Gerald Gillespie <gerald.gillespie@fullscript.com>
|
|
5
|
+
*/
|
|
6
|
+
const nodePath = require("node:path");
|
|
7
|
+
const process = require("node:process");
|
|
8
|
+
const fs = require("node:fs");
|
|
9
|
+
const deleteProjectJson = () => {
|
|
10
|
+
const projectJsonPath = nodePath.join(process.cwd(), 'project.json');
|
|
11
|
+
fs.accessSync(projectJsonPath, fs.constants.W_OK);
|
|
12
|
+
// if we get here we have write access
|
|
13
|
+
fs.rmSync(projectJsonPath, { force: true });
|
|
14
|
+
};
|
|
15
|
+
module.exports = deleteProjectJson;
|
|
16
|
+
//# sourceMappingURL=deleteProjectJson.js.map
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file /Users/geraldgillespie/code/nsaccounts/sdf/lib/deployFileHelper
|
|
3
|
+
* @author Gerald Gillespie <gerald.gillespie@fullscript.com>
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @param {string} path
|
|
7
|
+
* @returns {Promise<string|void>}
|
|
8
|
+
*/
|
|
9
|
+
export declare const hasDeployXml: (path?: string) => Promise<string | void>;
|
|
10
|
+
/**
|
|
11
|
+
* @param path
|
|
12
|
+
* @returns {string} - contents
|
|
13
|
+
*/
|
|
14
|
+
export declare const previewFile: (path: string) => Promise<string>;
|
|
15
|
+
/**
|
|
16
|
+
|
|
17
|
+
*/
|
|
18
|
+
export declare const removeFile: (path: string) => Promise<boolean>;
|
|
19
|
+
/**
|
|
20
|
+
* @description - list of files from this path and deeper
|
|
21
|
+
* @param path
|
|
22
|
+
*/
|
|
23
|
+
export declare const listDeployXmlFiles: (path: string) => Promise<string[]>;
|
|
24
|
+
/**
|
|
25
|
+
* @description - Promotes a deploy.xml as-is
|
|
26
|
+
* @param fromBits
|
|
27
|
+
* @param toBits
|
|
28
|
+
*/
|
|
29
|
+
export declare const promoteDeployXmlFile: (fromBits: string[]) => Promise<boolean>;
|
|
30
|
+
/**
|
|
31
|
+
*
|
|
32
|
+
* @param content
|
|
33
|
+
* @param pathBits
|
|
34
|
+
*/
|
|
35
|
+
export declare const createDeployXmlFile: (content: string, pathBits: string[]) => Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
*
|
|
38
|
+
* @param fromBits
|
|
39
|
+
* @param callback - A function that will provide the unglobbed deploy.xml. If it returns false then deployment will be halted
|
|
40
|
+
* @returns {}
|
|
41
|
+
*/
|
|
42
|
+
export declare const expandAndPromoteDeployXmlFile: (fromBits: string[], callback: ((content: string) => (Promise<boolean> | boolean))) => Promise<boolean>;
|
|
43
|
+
/**
|
|
44
|
+
*
|
|
45
|
+
* @param innerXmlPath e.g. ~/FileCabinet/
|
|
46
|
+
* @param {string} projectPath
|
|
47
|
+
* @returns {Promise<string>}
|
|
48
|
+
*/
|
|
49
|
+
export declare const getRealPathofInnerXmlPath: (innerXmlPath: string, projectPath?: string) => Promise<string>;
|
|
50
|
+
/**
|
|
51
|
+
*
|
|
52
|
+
* @param suiteScripts
|
|
53
|
+
* @param objects
|
|
54
|
+
* @returns {string} - the xml content
|
|
55
|
+
*/
|
|
56
|
+
export declare const makeDeployXmlString: (suiteScripts: string[], objects: string[]) => string;
|
|
57
|
+
/**
|
|
58
|
+
* @descripton
|
|
59
|
+
* ```xml
|
|
60
|
+
* <!-- for case number demo for client td2978513 -->
|
|
61
|
+
* <deploy>
|
|
62
|
+
* <files>
|
|
63
|
+
* <path>~/FileCabinet/SuiteScripts/Apps/demo/utils/utils.js</path>
|
|
64
|
+
* <!--<path>~/FileCabinet/SuiteScripts/Apps/demo/entry/example.js</path> -->
|
|
65
|
+
* <path>~/FileCabinet/SuiteScripts/Apps/demo/docs/*</path>
|
|
66
|
+
* </files>
|
|
67
|
+
* <objects>
|
|
68
|
+
* <path>~/Objects/</path>
|
|
69
|
+
* </objects>
|
|
70
|
+
* </deploy>
|
|
71
|
+
* ```
|
|
72
|
+
* @param {string} projectPath - to the src folder
|
|
73
|
+
* @param {string} relativePath
|
|
74
|
+
* @param {string} type
|
|
75
|
+
* @returns {Promise<string[]>}
|
|
76
|
+
*/
|
|
77
|
+
export declare const extractFilePathsFromDeployXmlFile: (projectPath: string, relativePath: string, type: "SuiteScripts" | "Objects") => Promise<string[]>;
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file /Users/geraldgillespie/code/nsaccounts/sdf/lib/deployFileHelper
|
|
4
|
+
* @author Gerald Gillespie <gerald.gillespie@fullscript.com>
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.extractFilePathsFromDeployXmlFile = exports.makeDeployXmlString = exports.getRealPathofInnerXmlPath = exports.expandAndPromoteDeployXmlFile = exports.createDeployXmlFile = exports.promoteDeployXmlFile = exports.listDeployXmlFiles = exports.removeFile = exports.previewFile = exports.hasDeployXml = void 0;
|
|
8
|
+
const fs = require("node:fs/promises");
|
|
9
|
+
const nodePath = require("node:path");
|
|
10
|
+
const pathHelpers = require("./pathHelpers");
|
|
11
|
+
/**
|
|
12
|
+
* @param {string} path
|
|
13
|
+
* @returns {Promise<string|void>}
|
|
14
|
+
*/
|
|
15
|
+
const hasDeployXml = async (path) => {
|
|
16
|
+
const fcPath = await pathHelpers.getFolderHoldingFileCabinetPlus(path || process.cwd());
|
|
17
|
+
const newPath = nodePath.join(fcPath, 'deploy.xml');
|
|
18
|
+
return fs.access(newPath, fs.constants.R_OK)
|
|
19
|
+
.then(() => newPath)
|
|
20
|
+
.catch(() => {
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
exports.hasDeployXml = hasDeployXml;
|
|
24
|
+
/**
|
|
25
|
+
* @param path
|
|
26
|
+
* @returns {string} - contents
|
|
27
|
+
*/
|
|
28
|
+
const previewFile = async (path) => fs.readFile(path, { encoding: 'utf8' });
|
|
29
|
+
exports.previewFile = previewFile;
|
|
30
|
+
/**
|
|
31
|
+
|
|
32
|
+
*/
|
|
33
|
+
const removeFile = async (path) => fs.rm(path)
|
|
34
|
+
.then(() => true)
|
|
35
|
+
.catch(() => false);
|
|
36
|
+
exports.removeFile = removeFile;
|
|
37
|
+
/**
|
|
38
|
+
* @description - list of files from this path and deeper
|
|
39
|
+
* @param path
|
|
40
|
+
*/
|
|
41
|
+
const listDeployXmlFiles = async (path) => {
|
|
42
|
+
const list = await fs.readdir(path, { recursive: true });
|
|
43
|
+
return list.filter((f) => (nodePath.basename(f).startsWith('deploy') && nodePath.basename(f).endsWith('.xml')));
|
|
44
|
+
};
|
|
45
|
+
exports.listDeployXmlFiles = listDeployXmlFiles;
|
|
46
|
+
/**
|
|
47
|
+
* @description - Promotes a deploy.xml as-is
|
|
48
|
+
* @param fromBits
|
|
49
|
+
* @param toBits
|
|
50
|
+
*/
|
|
51
|
+
const promoteDeployXmlFile = async (fromBits) => {
|
|
52
|
+
const from = nodePath.join(...fromBits);
|
|
53
|
+
if (!from.endsWith('.xml'))
|
|
54
|
+
throw new Error('Even temporary deployXml files must have a .xml extension');
|
|
55
|
+
const fcPath = await pathHelpers.getFolderHoldingFileCabinetPlus(process.cwd());
|
|
56
|
+
const to = nodePath.join(fcPath, 'deploy.xml');
|
|
57
|
+
return fs.cp(from, to)
|
|
58
|
+
.then(() => true)
|
|
59
|
+
.catch(() => false);
|
|
60
|
+
};
|
|
61
|
+
exports.promoteDeployXmlFile = promoteDeployXmlFile;
|
|
62
|
+
/**
|
|
63
|
+
*
|
|
64
|
+
* @param content
|
|
65
|
+
* @param pathBits
|
|
66
|
+
*/
|
|
67
|
+
const createDeployXmlFile = async (content, pathBits) => {
|
|
68
|
+
console.log(nodePath.join(...pathBits));
|
|
69
|
+
return fs.writeFile(nodePath.join(...pathBits), content, { encoding: 'utf-8' });
|
|
70
|
+
};
|
|
71
|
+
exports.createDeployXmlFile = createDeployXmlFile;
|
|
72
|
+
/**
|
|
73
|
+
*
|
|
74
|
+
* @param fromBits
|
|
75
|
+
* @param callback - A function that will provide the unglobbed deploy.xml. If it returns false then deployment will be halted
|
|
76
|
+
* @returns {}
|
|
77
|
+
*/
|
|
78
|
+
const expandAndPromoteDeployXmlFile = async (fromBits, callback) => {
|
|
79
|
+
const from = nodePath.join(...fromBits);
|
|
80
|
+
if (!from.endsWith('.xml'))
|
|
81
|
+
throw new Error('Even temporary deployXml files must have a .xml extension');
|
|
82
|
+
const fcPath = await pathHelpers.getFolderHoldingFileCabinetPlus(process.cwd());
|
|
83
|
+
const to = nodePath.join(fcPath, 'deploy.xml');
|
|
84
|
+
const content = await fs.readFile(from, { encoding: 'utf-8' });
|
|
85
|
+
// transform files
|
|
86
|
+
const transformed = '';
|
|
87
|
+
// transform objects
|
|
88
|
+
const answer = await callback(content);
|
|
89
|
+
if (answer !== true)
|
|
90
|
+
return false;
|
|
91
|
+
//
|
|
92
|
+
return await fs.writeFile(to, transformed, { encoding: 'utf-8' })
|
|
93
|
+
.then(() => true)
|
|
94
|
+
.catch(() => false);
|
|
95
|
+
};
|
|
96
|
+
exports.expandAndPromoteDeployXmlFile = expandAndPromoteDeployXmlFile;
|
|
97
|
+
/**
|
|
98
|
+
*
|
|
99
|
+
* @param innerXmlPath e.g. ~/FileCabinet/
|
|
100
|
+
* @param {string} projectPath
|
|
101
|
+
* @returns {Promise<string>}
|
|
102
|
+
*/
|
|
103
|
+
const getRealPathofInnerXmlPath = async (innerXmlPath, projectPath) => {
|
|
104
|
+
const fcPath = await pathHelpers.getFolderHoldingFileCabinetPlus(projectPath || process.cwd());
|
|
105
|
+
return nodePath.join(fcPath, innerXmlPath.replace(/^.*\b(FileCabinet.*\.js).*$/, '$1'));
|
|
106
|
+
};
|
|
107
|
+
exports.getRealPathofInnerXmlPath = getRealPathofInnerXmlPath;
|
|
108
|
+
/**
|
|
109
|
+
*
|
|
110
|
+
* @param suiteScripts
|
|
111
|
+
* @param objects
|
|
112
|
+
* @returns {string} - the xml content
|
|
113
|
+
*/
|
|
114
|
+
const makeDeployXmlString = (suiteScripts, objects) => {
|
|
115
|
+
const files = [];
|
|
116
|
+
const objectPaths = [];
|
|
117
|
+
const padding = [4, ' '];
|
|
118
|
+
if (suiteScripts.length > 0) {
|
|
119
|
+
files.push('<files>');
|
|
120
|
+
files.push(...suiteScripts.map((f) => `${''.padStart(...padding)}<path>~/FileCabinet/SuiteScripts/${f.replace(/^.*SuiteScripts\b\//, '')}</path>`));
|
|
121
|
+
files.push('</files>');
|
|
122
|
+
}
|
|
123
|
+
if (objects.length > 0) {
|
|
124
|
+
objectPaths.push('<objects>');
|
|
125
|
+
objectPaths.push(...objects.map((f) => `${''.padStart(...padding)}<path>~/Objects/${f.replace(/^.*Objects\b\//, '')}</path>`));
|
|
126
|
+
objectPaths.push('</objects>');
|
|
127
|
+
}
|
|
128
|
+
return [
|
|
129
|
+
'<!-- generated output from globs -->',
|
|
130
|
+
'<deploy>',
|
|
131
|
+
...files.map((f) => `${''.padStart(...padding)}${f}`),
|
|
132
|
+
...objectPaths.map((o) => `${''.padStart(...padding)}${o}`),
|
|
133
|
+
'</deploy>'
|
|
134
|
+
].join('\n');
|
|
135
|
+
};
|
|
136
|
+
exports.makeDeployXmlString = makeDeployXmlString;
|
|
137
|
+
/**
|
|
138
|
+
* @description -
|
|
139
|
+
* {
|
|
140
|
+
* "type": "tag",
|
|
141
|
+
* "tagName": "deploy",
|
|
142
|
+
* "closing": false,
|
|
143
|
+
* "attributes": {},
|
|
144
|
+
* "raw": "<deploy>"
|
|
145
|
+
* },
|
|
146
|
+
* @param xml
|
|
147
|
+
*/
|
|
148
|
+
const tokenizeXML = (xml) => {
|
|
149
|
+
const tokens = [];
|
|
150
|
+
// Regex explanation:
|
|
151
|
+
// 1. <!--([\s\S]*?)--> matches XML comments.
|
|
152
|
+
// 2. <\s*(\/?)([a-zA-Z0-9_:-]+)([^>]*?)> matches tags:
|
|
153
|
+
// - (\/?) captures an optional leading slash (closing tag indicator)
|
|
154
|
+
// - ([a-zA-Z0-9_:-]+) captures the tag name.
|
|
155
|
+
// - ([^>]*?) captures any attributes (not further processed here)
|
|
156
|
+
const regex = /<!--([\s\S]*?)-->|<\s*(\/?)([a-zA-Z0-9_:-]+)([^>]*?)>/g;
|
|
157
|
+
let lastIndex = 0;
|
|
158
|
+
let match;
|
|
159
|
+
while ((match = regex.exec(xml)) !== null) {
|
|
160
|
+
// Capture any text between the previous match and the current match.
|
|
161
|
+
if (match.index > lastIndex) {
|
|
162
|
+
const text = xml.substring(lastIndex, match.index).trim();
|
|
163
|
+
if (text) {
|
|
164
|
+
tokens.push({ type: "text", content: text });
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// If the first capturing group is defined, it's a comment.
|
|
168
|
+
if (match[1] !== undefined) {
|
|
169
|
+
tokens.push({ type: "comment", content: match[1].trim() });
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
// Otherwise it's a tag.
|
|
173
|
+
const closing = match[2] === "/";
|
|
174
|
+
const tagName = match[3];
|
|
175
|
+
// For simplicity, attributes are not parsed in this example.
|
|
176
|
+
const attributes = {};
|
|
177
|
+
tokens.push({
|
|
178
|
+
type: "tag",
|
|
179
|
+
tagName,
|
|
180
|
+
closing,
|
|
181
|
+
attributes,
|
|
182
|
+
// Optionally include the raw tag string
|
|
183
|
+
raw: match[0].trim()
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
// Update lastIndex to capture text after this token.
|
|
187
|
+
lastIndex = regex.lastIndex;
|
|
188
|
+
}
|
|
189
|
+
// If there's any trailing text after the last tag, capture it.
|
|
190
|
+
if (lastIndex < xml.length) {
|
|
191
|
+
const text = xml.substring(lastIndex).trim();
|
|
192
|
+
if (text) {
|
|
193
|
+
tokens.push({ type: "text", content: text });
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// @ts-expect-error
|
|
197
|
+
return tokens;
|
|
198
|
+
};
|
|
199
|
+
// Example usage:
|
|
200
|
+
const xmlString = `<!-- for case number demo for client td2978513 -->
|
|
201
|
+
<deploy>
|
|
202
|
+
<files>
|
|
203
|
+
<path>~/FileCabinet/SuiteScripts/Apps/demo/utils/utils.js</path>
|
|
204
|
+
<!--<path>~/FileCabinet/SuiteScripts/Apps/demo/entry/example.js</path> -->
|
|
205
|
+
<path>~/FileCabinet/SuiteScripts/Apps/demo/docs/*</path>
|
|
206
|
+
</files>
|
|
207
|
+
<!--
|
|
208
|
+
<objects>
|
|
209
|
+
<path>~/Objects/</path>
|
|
210
|
+
</objects>
|
|
211
|
+
-->
|
|
212
|
+
</deploy>`;
|
|
213
|
+
/**
|
|
214
|
+
* @descripton
|
|
215
|
+
* ```xml
|
|
216
|
+
* <!-- for case number demo for client td2978513 -->
|
|
217
|
+
* <deploy>
|
|
218
|
+
* <files>
|
|
219
|
+
* <path>~/FileCabinet/SuiteScripts/Apps/demo/utils/utils.js</path>
|
|
220
|
+
* <!--<path>~/FileCabinet/SuiteScripts/Apps/demo/entry/example.js</path> -->
|
|
221
|
+
* <path>~/FileCabinet/SuiteScripts/Apps/demo/docs/*</path>
|
|
222
|
+
* </files>
|
|
223
|
+
* <objects>
|
|
224
|
+
* <path>~/Objects/</path>
|
|
225
|
+
* </objects>
|
|
226
|
+
* </deploy>
|
|
227
|
+
* ```
|
|
228
|
+
* @param {string} projectPath - to the src folder
|
|
229
|
+
* @param {string} relativePath
|
|
230
|
+
* @param {string} type
|
|
231
|
+
* @returns {Promise<string[]>}
|
|
232
|
+
*/
|
|
233
|
+
const extractFilePathsFromDeployXmlFile = async (projectPath, relativePath, type) => {
|
|
234
|
+
const path = pathHelpers.combineOverLappingPaths(projectPath, relativePath);
|
|
235
|
+
await fs.access(path, fs.constants.R_OK);
|
|
236
|
+
const contents = await fs.readFile(path, { encoding: 'utf-8' });
|
|
237
|
+
const replacer = type === 'Objects'
|
|
238
|
+
? [/^.*(.\bObjects\b.*)$/, '$1']
|
|
239
|
+
: [/^.*(.\bSuiteScripts\b.*)$/, '$1'];
|
|
240
|
+
// remove comments first
|
|
241
|
+
const tokenized = tokenizeXML(contents).flatMap((x) => ((x.type === 'text' && typeof x?.content === 'string' && x?.content.includes(type))
|
|
242
|
+
// content always exists when type === 'text'
|
|
243
|
+
? [x.content.replace(...replacer)]
|
|
244
|
+
: []));
|
|
245
|
+
// console.log(tokenized);
|
|
246
|
+
return tokenized;
|
|
247
|
+
};
|
|
248
|
+
exports.extractFilePathsFromDeployXmlFile = extractFilePathsFromDeployXmlFile;
|
|
249
|
+
//# sourceMappingURL=deployFileHelper.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file /Users/geraldgillespie/code/nsaccounts/sdf/lib/readDefaultsFromRootProjectJson
|
|
3
|
+
* @author Gerald Gillespie <gerald.gillespie@fullscript.com>
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @description -
|
|
7
|
+
* @param {string[]} defaults
|
|
8
|
+
* @returns {Record<string,any>} - any defaults that were stored in the root project.json
|
|
9
|
+
*/
|
|
10
|
+
export declare const readDefaultsFromJson: (defaults: Array<string | "certificateid" | "privatekeypath">) => Record<string, any>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file /Users/geraldgillespie/code/nsaccounts/sdf/lib/readDefaultsFromRootProjectJson
|
|
4
|
+
* @author Gerald Gillespie <gerald.gillespie@fullscript.com>
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.readDefaultsFromJson = void 0;
|
|
8
|
+
const projectJson = {};
|
|
9
|
+
try {
|
|
10
|
+
require('#root/project.json');
|
|
11
|
+
}
|
|
12
|
+
catch (e) {
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* @description -
|
|
16
|
+
* @param {string[]} defaults
|
|
17
|
+
* @returns {Record<string,any>} - any defaults that were stored in the root project.json
|
|
18
|
+
*/
|
|
19
|
+
const readDefaultsFromJson = (defaults) => {
|
|
20
|
+
return defaults.reduce((pj, property) => {
|
|
21
|
+
if (!Reflect.has(projectJson, property))
|
|
22
|
+
return pj;
|
|
23
|
+
return {
|
|
24
|
+
...pj,
|
|
25
|
+
[property]: projectJson[property],
|
|
26
|
+
};
|
|
27
|
+
}, {});
|
|
28
|
+
};
|
|
29
|
+
exports.readDefaultsFromJson = readDefaultsFromJson;
|
|
30
|
+
//# sourceMappingURL=handleRootProjectJson.js.map
|
package/lib/isProd.d.ts
ADDED
package/lib/isProd.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file sdf/lib/isProd.ts
|
|
4
|
+
* @author Gerald Gillespie <gerald.gillespie@fullscript.com>
|
|
5
|
+
*/
|
|
6
|
+
const isProd = /**
|
|
7
|
+
* @description - guess at whether it is prod
|
|
8
|
+
* @param {string} acct
|
|
9
|
+
* @returns {boolean}
|
|
10
|
+
*/ (acct) => /^(td)?\d+$/i.test(acct);
|
|
11
|
+
isProd.default = isProd;
|
|
12
|
+
module.exports = isProd;
|
|
13
|
+
//# sourceMappingURL=isProd.js.map
|
package/lib/logHelper.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file /Users/geraldgillespie/code/nsaccounts/sdf/lib/logHelper
|
|
4
|
+
* @author Gerald Gillespie <gerald.gillespie@fullscript.com>
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.useSdfLog = void 0;
|
|
8
|
+
const useSdfLog = async (command) => {
|
|
9
|
+
const newDate = new Date().toISOString();
|
|
10
|
+
return `./logs/sdflog.${command.replace(':', '_')}${newDate}.txt`; // //`logs/sdflog.${now}.txt`,
|
|
11
|
+
};
|
|
12
|
+
exports.useSdfLog = useSdfLog;
|
|
13
|
+
//# sourceMappingURL=logHelper.js.map
|
package/lib/logger.d.ts
ADDED
package/lib/logger.js
ADDED