@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.
@@ -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
- // use the first file
63
- const [file] = options.arguments.paths;
64
- // normalize to file system
65
- // e.g. /User/geraldgillespie/project/src/FileCabinet/SuiteScripts/blah.js
66
- let fixed = (0, pathHelpers_1.getAbsolutePath)({
67
- projectPath: options.projectPath,
68
- executionPath: options.executionPath,
69
- filePath: file,
70
- });
71
- // await promptUser({message: 'pause'});
72
- // check if you have it locally
73
- if (!await (0, pathHelpers_1.hasFile)(fixed) && !/\btemp\b.FileCabinet/.test(fixed)) {
74
- throw onErrorHelper.makeError(origin, new Error('You do not have this file locally ' + fixed));
75
- }
76
- // finish the fix for SDF
77
- // e.g. /SuiteScripts/blah.js
78
- fixed = fixed.replace(/^.*(.\bSuiteScripts.*)$/, '$1');
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
- const currentFile = (0, pathHelpers_1.joinPaths)(options.projectPath, 'FileCabinet', fixed);
129
- // const thirdFile =
130
- // launch diff tool
131
- // Spawn a new process (e.g., launching another Node script)
132
- console.log([diffTool, ['diff', currentFile, newFile, secondFile]]);
133
- const fileArgs = [newFile, currentFile, secondFile].filter(Boolean).map((f) => `"${f}"`);
134
- const diffChildProc = cp.spawn(diffTool, ['diff', ...fileArgs], {
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
- // do not prompt when in quiet mode
154
- const choices = { 'Y': 'Yes', 'N': 'No' };
155
- let answer = choices['N'];
156
- options.arguments.paths = [];
157
- if (!isQuiet) {
158
- answer = await (0, promptHelpers_1.promptChoices)({
159
- choices,
160
- displayChoices: choices,
161
- // premessage:,
162
- question: 'Would you like to continue with the import?',
163
- default: choices['N'],
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 = [fixed];
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']);
@@ -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 in the same account root
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: (projectPath: string) => Promise<string>;
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
@@ -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 in the same account root
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 (projectPath) => {
244
- const newPath = nodePath.join(projectPath, '..', exports.CONSTANTS.SDF_TEMP_ROOT);
245
- // clean up old files first
246
- await (0, exports.removeTempDirForSdf)(projectPath);
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');
@@ -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 consumed (DISBALED)', path));
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@suitegeezus/suitecloud-stacker",
3
- "version": "25.2.127",
3
+ "version": "25.2.128",
4
4
  "description": "SuiteCloud Stacker",
5
5
  "main": "safeCommands.js",
6
6
  "scripts": {
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'}))