@suitegeezus/suitecloud-stacker 25.2.127 → 25.2.128
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/commands/fileImport.js +88 -78
- package/lib/pathHelpers.d.ts +7 -3
- package/lib/pathHelpers.js +15 -6
- package/lib/tempFileHelper.js +1 -1
- package/package.json +1 -1
- package/safeCommands.js +1 -1
package/commands/fileImport.js
CHANGED
|
@@ -10,6 +10,7 @@ const cp = require("node:child_process");
|
|
|
10
10
|
const nodePath = require("node:path");
|
|
11
11
|
const promptHelpers_1 = require("../lib/promptHelpers");
|
|
12
12
|
const tempFileHelper = require("../lib/tempFileHelper");
|
|
13
|
+
const os = require("node:os");
|
|
13
14
|
const pathHelpers_1 = require("../lib/pathHelpers");
|
|
14
15
|
const onErrorHelper = require("../lib/onErrorHelper");
|
|
15
16
|
const minimatch_1 = require("minimatch");
|
|
@@ -59,63 +60,63 @@ const downloadForDiff = () => {
|
|
|
59
60
|
// single length array
|
|
60
61
|
if (options.arguments.paths.length === 0)
|
|
61
62
|
throw onErrorHelper.makeError(origin, new Error('Diff compare supports exactly 1 file at a time currently.'));
|
|
62
|
-
//
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
63
|
+
// fixed lists
|
|
64
|
+
const candidates = await Promise.all([...options.arguments.paths].map(async (candidate) => {
|
|
65
|
+
// normalize to file system
|
|
66
|
+
// e.g. /User/geraldgillespie/project/src/FileCabinet/SuiteScripts/blah.js
|
|
67
|
+
let fixed = (0, pathHelpers_1.getAbsolutePath)({
|
|
68
|
+
projectPath: options.projectPath,
|
|
69
|
+
executionPath: options.executionPath,
|
|
70
|
+
filePath: candidate,
|
|
71
|
+
});
|
|
72
|
+
// await promptUser({message: 'pause'});
|
|
73
|
+
// check if you have it locally
|
|
74
|
+
if (!await (0, pathHelpers_1.hasFile)(fixed)) {
|
|
75
|
+
throw onErrorHelper.makeError(origin, new Error('You do not have this file locally ' + fixed));
|
|
76
|
+
}
|
|
77
|
+
// finish the fix for SDF
|
|
78
|
+
// e.g. /SuiteScripts/blah.js
|
|
79
|
+
return fixed.replace(/^.*(.\bSuiteScripts.*)$/, '$1');
|
|
80
|
+
}));
|
|
81
|
+
options.arguments.paths = [];
|
|
82
|
+
const tempLocations = [];
|
|
83
|
+
const auths = [options.authId, secondAuth].filter(Boolean);
|
|
84
|
+
// the temp import can happen all at once
|
|
85
|
+
await auths.reduce(async (linkedPromises, auth) => {
|
|
86
|
+
await linkedPromises;
|
|
87
|
+
const rootFolder = auth;
|
|
88
|
+
tempLocations.push(await (0, pathHelpers_1.makeTempDirForSdf)({ root: rootFolder }));
|
|
89
|
+
const childArgs = [
|
|
90
|
+
'--paths', ...candidates,
|
|
91
|
+
'--calledfromcomparefiles',
|
|
92
|
+
'--runhooks none',
|
|
93
|
+
'--excludeproperties',
|
|
94
|
+
'--project', rootFolder,
|
|
95
|
+
// run with noconfig to disconnect from existing project
|
|
96
|
+
'--noconfig',
|
|
97
|
+
];
|
|
98
|
+
if (auth)
|
|
99
|
+
childArgs.push('--authid', auth);
|
|
100
|
+
// arguments to keep?
|
|
101
|
+
[].forEach((keep) => {
|
|
102
|
+
if (Reflect.has(options.arguments, keep))
|
|
103
|
+
childArgs.push(`--${keep}`, Reflect.get(options.arguments, keep));
|
|
104
|
+
});
|
|
105
|
+
// trigger the import for it in the temp folder
|
|
106
|
+
const errorCode = await spawnSuitecloud.createAsync({
|
|
107
|
+
command: 'file:import',
|
|
108
|
+
args: childArgs,
|
|
109
|
+
interact: true,
|
|
110
|
+
cwd: os.tmpdir()
|
|
111
|
+
// spawns in a separate location but is still a child process
|
|
112
|
+
});
|
|
113
|
+
if (errorCode !== 0)
|
|
114
|
+
process.exit(errorCode);
|
|
115
|
+
// the file location is the
|
|
116
|
+
return linkedPromises;
|
|
117
|
+
}, Promise.resolve(true));
|
|
118
|
+
let diffTool = process.env.SUITECLOUD_DIFF_TOOL;
|
|
79
119
|
{
|
|
80
|
-
// child process will save to temp
|
|
81
|
-
// mktemp for the file
|
|
82
|
-
// reset this array
|
|
83
|
-
options.arguments.paths = [];
|
|
84
|
-
// copy suitecloud there
|
|
85
|
-
const tempLocation = await (0, pathHelpers_1.makeTempDirForSdf)(options.projectPath);
|
|
86
|
-
const tempProjectFolder = (0, pathHelpers_1.getRelativeOf)(process.cwd(), tempLocation);
|
|
87
|
-
const [newFile, secondFile] = await Promise.all([
|
|
88
|
-
options.authId, secondAuth
|
|
89
|
-
]
|
|
90
|
-
.filter(Boolean)
|
|
91
|
-
.map(async (auth) => {
|
|
92
|
-
const childArgs = [
|
|
93
|
-
'--paths', fixed,
|
|
94
|
-
'--calledfromcomparefiles',
|
|
95
|
-
'--excludeproperties',
|
|
96
|
-
'--project', tempProjectFolder,
|
|
97
|
-
'--noconfig',
|
|
98
|
-
];
|
|
99
|
-
if (auth)
|
|
100
|
-
childArgs.push('--authid', auth);
|
|
101
|
-
['config'].forEach((keep) => {
|
|
102
|
-
if (Reflect.has(options.arguments, keep))
|
|
103
|
-
childArgs.push(`--${keep}`, Reflect.get(options.arguments, keep));
|
|
104
|
-
});
|
|
105
|
-
// trigger the import for it in the temp folder
|
|
106
|
-
const errorCode = await spawnSuitecloud.createAsync({
|
|
107
|
-
command: 'file:import',
|
|
108
|
-
args: childArgs,
|
|
109
|
-
interact: true,
|
|
110
|
-
// spawns in a separate location but is still a child process
|
|
111
|
-
});
|
|
112
|
-
if (errorCode !== 0)
|
|
113
|
-
process.exit(errorCode);
|
|
114
|
-
const dataJson = await (0, tempFileHelper_1.consumeTempFile)(tempFile);
|
|
115
|
-
const parsedData = JSON.parse(dataJson);
|
|
116
|
-
return parsedData.fullPath;
|
|
117
|
-
}));
|
|
118
|
-
let diffTool = process.env.SUITECLOUD_DIFF_TOOL;
|
|
119
120
|
// console.log(process.env);
|
|
120
121
|
const nag = async () => {
|
|
121
122
|
process.stdout.write((0, promptHelpers_1.goColor)('INFO', `\nSet your environment variable ${(0, promptHelpers_1.goColor)('HIGHLIGHT', 'SUITECLOUD_DIFF_TOOL')}${(0, promptHelpers_1.goColor)('INFO', ' to avoid this prompt in the future')}`));
|
|
@@ -125,13 +126,16 @@ const downloadForDiff = () => {
|
|
|
125
126
|
while (!diffTool && !isQuiet) {
|
|
126
127
|
await nag();
|
|
127
128
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
129
|
+
}
|
|
130
|
+
// iterate over ALL the files to create diff commands
|
|
131
|
+
const diffCombos = candidates.map((file) => {
|
|
132
|
+
return [...tempLocations, options.projectPath].map((location) => {
|
|
133
|
+
return (0, pathHelpers_1.joinPaths)(location, 'FileCabinet', file);
|
|
134
|
+
}).filter(Boolean).map((f) => `"${f}"`);
|
|
135
|
+
});
|
|
136
|
+
await diffCombos.reduce(async (linked, combo) => {
|
|
137
|
+
await linked;
|
|
138
|
+
const diffChildProc = cp.spawn(diffTool, ['diff', ...combo], {
|
|
135
139
|
detached: true, // Allows the child to run independently
|
|
136
140
|
stdio: 'inherit',
|
|
137
141
|
shell: true // Optional: ignore parent's stdio (or use 'inherit' to share)
|
|
@@ -150,22 +154,27 @@ const downloadForDiff = () => {
|
|
|
150
154
|
// Exit the current process
|
|
151
155
|
await diffPromise;
|
|
152
156
|
diffChildProc.unref();
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
answer =
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
157
|
+
const toGet = combo.pop();
|
|
158
|
+
if (toGet) {
|
|
159
|
+
const fixedToGet = toGet.replace(/^.*(.\bSuiteScripts.*)$/, '$1');
|
|
160
|
+
// do not prompt when in quiet mode
|
|
161
|
+
const choices = { 'Y': 'Yes', 'N': 'No' };
|
|
162
|
+
let answer = choices['N'];
|
|
163
|
+
options.arguments.paths = [];
|
|
164
|
+
if (!isQuiet) {
|
|
165
|
+
answer = await (0, promptHelpers_1.promptChoices)({
|
|
166
|
+
choices,
|
|
167
|
+
displayChoices: choices,
|
|
168
|
+
premessage: fixedToGet,
|
|
169
|
+
question: 'Would you like to continue with the import?',
|
|
170
|
+
default: choices['N'],
|
|
171
|
+
});
|
|
172
|
+
}
|
|
165
173
|
if (answer === choices['Y'])
|
|
166
|
-
options.arguments.paths
|
|
174
|
+
options.arguments.paths.push(fixedToGet);
|
|
167
175
|
}
|
|
168
|
-
|
|
176
|
+
return linked;
|
|
177
|
+
}, Promise.resolve(true));
|
|
169
178
|
}
|
|
170
179
|
catch (e) {
|
|
171
180
|
console.error(e);
|
|
@@ -474,7 +483,8 @@ const detectManifest = () => {
|
|
|
474
483
|
if (deleteManifest && options?._commandParameters?.project) {
|
|
475
484
|
const unquotedProject = await Promise.resolve(options?._commandParameters?.project)
|
|
476
485
|
.then((p) => JSON.parse(p))
|
|
477
|
-
.catch(() => {
|
|
486
|
+
.catch(() => {
|
|
487
|
+
});
|
|
478
488
|
if (unquotedProject) {
|
|
479
489
|
process.stdout.write((0, promptHelpers_1.goColor)('INFO', '\n', 'Deleting temporary manifest in ', unquotedProject));
|
|
480
490
|
await (0, pathHelpers_1.removeFile)([unquotedProject, 'manifest.xml']);
|
package/lib/pathHelpers.d.ts
CHANGED
|
@@ -77,12 +77,16 @@ export declare const removeTempDirForSdf: (projectPath: string) => Promise<strin
|
|
|
77
77
|
*/
|
|
78
78
|
export declare const removeFile: (pathBits: string[]) => Promise<string>;
|
|
79
79
|
/**
|
|
80
|
-
* @description - makes a `temp` directory
|
|
80
|
+
* @description - makes a `temp` directory that behaves like a project file
|
|
81
81
|
* - no need to copy anything over
|
|
82
|
-
* @param {string} projectPath
|
|
82
|
+
* @param {string} [options.projectPath] - Default to OS tmpdir
|
|
83
|
+
* @param {string} [options.root] - Defaults to sdf-like dir
|
|
83
84
|
* @returns {Promise<string>}
|
|
84
85
|
*/
|
|
85
|
-
export declare const makeTempDirForSdf: (
|
|
86
|
+
export declare const makeTempDirForSdf: (options: {
|
|
87
|
+
projectPath?: string;
|
|
88
|
+
root?: string;
|
|
89
|
+
}) => Promise<string>;
|
|
86
90
|
/**
|
|
87
91
|
* @description - Figures out the path
|
|
88
92
|
* - if you have a relative path then compare it against cwd
|
package/lib/pathHelpers.js
CHANGED
|
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
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
8
|
const nodePath = require("node:path");
|
|
9
9
|
const fs = require("node:fs/promises");
|
|
10
|
+
const nodeOs = require("node:os");
|
|
10
11
|
const validators_1 = require("./validators");
|
|
11
12
|
const minimatch_1 = require("minimatch");
|
|
12
13
|
const makeManifest = require("./makeManifestXml");
|
|
@@ -235,15 +236,23 @@ const removeFile = async (pathBits) => {
|
|
|
235
236
|
};
|
|
236
237
|
exports.removeFile = removeFile;
|
|
237
238
|
/**
|
|
238
|
-
* @description - makes a `temp` directory
|
|
239
|
+
* @description - makes a `temp` directory that behaves like a project file
|
|
239
240
|
* - no need to copy anything over
|
|
240
|
-
* @param {string} projectPath
|
|
241
|
+
* @param {string} [options.projectPath] - Default to OS tmpdir
|
|
242
|
+
* @param {string} [options.root] - Defaults to sdf-like dir
|
|
241
243
|
* @returns {Promise<string>}
|
|
242
244
|
*/
|
|
243
|
-
const makeTempDirForSdf = async (
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
245
|
+
const makeTempDirForSdf = async (options) => {
|
|
246
|
+
let newPath;
|
|
247
|
+
const { projectPath, root } = options;
|
|
248
|
+
if (!projectPath) {
|
|
249
|
+
newPath = nodePath.join(nodeOs.tmpdir(), root || exports.CONSTANTS.SDF_DEFAULT_ROOT);
|
|
250
|
+
await (0, exports.removeTempDirForSdf)(nodeOs.tmpdir());
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
newPath = nodePath.join(projectPath, '..', root || exports.CONSTANTS.SDF_TEMP_ROOT);
|
|
254
|
+
// clean up old files first
|
|
255
|
+
}
|
|
247
256
|
await fs.mkdir(newPath, { recursive: true });
|
|
248
257
|
// make manifest file
|
|
249
258
|
await makeManifest(newPath, 'temp');
|
package/lib/tempFileHelper.js
CHANGED
|
@@ -45,7 +45,7 @@ const consumeTempFile = async (fileName) => {
|
|
|
45
45
|
const path = nodePath.join(process.cwd(), [prefix, fileName].join('_'));
|
|
46
46
|
const contents = await fs.readFile(path, { encoding: 'utf-8' });
|
|
47
47
|
// await fs.rm(path).catch(e => console.error(e));
|
|
48
|
-
process.stdout.write(promptHelpers.goColor('SUBTLE', '\nTemp file
|
|
48
|
+
process.stdout.write(promptHelpers.goColor('SUBTLE', '\nTemp file read', path));
|
|
49
49
|
return contents;
|
|
50
50
|
};
|
|
51
51
|
exports.consumeTempFile = consumeTempFile;
|
package/package.json
CHANGED
package/safeCommands.js
CHANGED
|
@@ -768,11 +768,11 @@ exports.caseCommands = {
|
|
|
768
768
|
message: 'Enter a file or Glob to import (e.g. ./**/*.js)'
|
|
769
769
|
}))
|
|
770
770
|
.stack(printOptions({ messageType: 'INFO', confirm: true }))
|
|
771
|
-
.stack(fileImports.downloadForDiff())
|
|
772
771
|
// could be an xml
|
|
773
772
|
.stack(fileUpload.getFilesFromDeployXml())
|
|
774
773
|
// or could be a glob or partial
|
|
775
774
|
.stack(fileImports.fixFileImportPaths())
|
|
775
|
+
.stack(fileImports.downloadForDiff())
|
|
776
776
|
.stack(fileUpload.confirmFileList())
|
|
777
777
|
.stack(fileImports.detectManifest())
|
|
778
778
|
// .stack(printOptions({messageType: 'SUBTLE'}))
|