@mikeyt23/node-cli-utils 2.0.0-beta.1 → 2.0.0-beta.2
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/dist/cjs/GitUtility.d.ts +7 -0
- package/dist/cjs/GitUtility.d.ts.map +1 -0
- package/dist/cjs/GitUtility.js +49 -0
- package/dist/cjs/TarballUtility.d.ts +17 -7
- package/dist/cjs/TarballUtility.d.ts.map +1 -1
- package/dist/cjs/TarballUtility.js +18 -24
- package/dist/cjs/certUtils.d.ts +53 -17
- package/dist/cjs/certUtils.d.ts.map +1 -1
- package/dist/cjs/certUtils.js +175 -111
- package/dist/cjs/dbMigrationUtils.js +44 -54
- package/dist/cjs/dotnetUtils.d.ts.map +1 -1
- package/dist/cjs/dotnetUtils.js +4 -2
- package/dist/cjs/esmSpecific.d.mts +5 -0
- package/dist/cjs/esmSpecific.d.mts.map +1 -1
- package/dist/cjs/esmSpecific.mjs +6 -1
- package/dist/cjs/generalUtils.d.ts +268 -26
- package/dist/cjs/generalUtils.d.ts.map +1 -1
- package/dist/cjs/generalUtils.js +522 -106
- package/dist/cjs/generalUtilsInternal.d.ts +9 -3
- package/dist/cjs/generalUtilsInternal.d.ts.map +1 -1
- package/dist/cjs/generalUtilsInternal.js +159 -59
- package/dist/cjs/hostsUtils.d.ts +16 -0
- package/dist/cjs/hostsUtils.d.ts.map +1 -0
- package/dist/cjs/hostsUtils.js +82 -0
- package/dist/cjs/runWhileParentAlive.js +7 -9
- package/dist/esm/GitUtility.d.ts +7 -0
- package/dist/esm/GitUtility.d.ts.map +1 -0
- package/dist/esm/GitUtility.js +43 -0
- package/dist/esm/TarballUtility.d.ts +17 -7
- package/dist/esm/TarballUtility.d.ts.map +1 -1
- package/dist/esm/TarballUtility.js +21 -25
- package/dist/esm/certUtils.d.ts +53 -17
- package/dist/esm/certUtils.d.ts.map +1 -1
- package/dist/esm/certUtils.js +172 -86
- package/dist/esm/dbMigrationUtils.js +45 -55
- package/dist/esm/dotnetUtils.d.ts.map +1 -1
- package/dist/esm/dotnetUtils.js +4 -2
- package/dist/esm/esmSpecific.d.mts +5 -0
- package/dist/esm/esmSpecific.d.mts.map +1 -1
- package/dist/esm/esmSpecific.mjs +6 -1
- package/dist/esm/generalUtils.d.ts +268 -26
- package/dist/esm/generalUtils.d.ts.map +1 -1
- package/dist/esm/generalUtils.js +490 -105
- package/dist/esm/generalUtilsInternal.d.ts +9 -3
- package/dist/esm/generalUtilsInternal.d.ts.map +1 -1
- package/dist/esm/generalUtilsInternal.js +150 -57
- package/dist/esm/hostsUtils.d.ts +16 -0
- package/dist/esm/hostsUtils.d.ts.map +1 -0
- package/dist/esm/hostsUtils.js +69 -0
- package/dist/esm/runWhileParentAlive.js +8 -10
- package/package.json +4 -2
package/dist/cjs/generalUtils.js
CHANGED
|
@@ -26,13 +26,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.escapeStringForRegex = exports.findFilesRecursively = exports.deleteEnvIfExists = exports.sortDictionaryByKeyAsc = exports.filterDictionary = exports.copyModifiedEnv = exports.overwriteEnvFile = exports.copyNewEnvValues = exports.getConfirmationExample = exports.getConfirmation = exports.askQuestion = exports.isDockerRunning = exports.whichSync = exports.isPlatformLinux = exports.isPlatformMac = exports.isPlatformWindows = exports.simpleSpawnSync = exports.simpleCmdSync = exports.stringToNonEmptyLines = exports.spawnDockerCompose = exports.requireValidPath = exports.requireString = exports.copyDirectoryContents = exports.emptyDirectory = exports.mkdirp = exports.ensureDirectory = exports.spawnAsyncLongRunning = exports.spawnAsync = exports.sleep = exports.SimpleSpawnError = exports.SpawnError = exports.trace = exports.log = void 0;
|
|
30
|
-
|
|
29
|
+
exports.isPortAvailable = exports.getPlatformCode = exports.isDirectorySync = exports.isDirectory = exports.getHostname = exports.ExtendedError = exports.humanizeTime = exports.getPowershellHackArgs = exports.powershellHackPrefix = exports.logTable = exports.escapeStringForRegex = exports.findFilesRecursively = exports.deleteEnvIfExists = exports.sortDictionaryByKeyAsc = exports.filterDictionary = exports.copyModifiedEnv = exports.overwriteEnvFile = exports.copyNewEnvValues = exports.getConfirmationExample = exports.getConfirmation = exports.askQuestion = exports.isDockerRunning = exports.whichSync = exports.which = exports.isPlatformLinux = exports.isPlatformMac = exports.isPlatformWindows = exports.simpleSpawnAsync = exports.simpleSpawnSync = exports.simpleCmdAsync = exports.simpleCmdSync = exports.stringToLines = exports.stringToNonEmptyLines = exports.spawnDockerCompose = exports.isDockerComposeProjectNameValid = exports.requireValidPath = exports.requireString = exports.copyDirectoryContents = exports.emptyDirectory = exports.mkdirpSync = exports.mkdirp = exports.ensureDirectory = exports.spawnAsyncLongRunning = exports.spawnAsync = exports.sleep = exports.SimpleSpawnError = exports.SpawnError = exports.trace = exports.logIf = exports.log = void 0;
|
|
30
|
+
exports.Emoji = exports.yellow = exports.purple = exports.gray = exports.cyan = exports.green = exports.red = exports.color = exports.AnsiColor = exports.stripShellMetaCharacters = exports.hasWhitespace = exports.isValidDirName = exports.collapseWhitespace = exports.withRetryAsync = exports.getNormalizedError = exports.getRequiredEnvVar = void 0;
|
|
31
31
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
32
32
|
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
33
33
|
const node_os_1 = require("node:os");
|
|
34
34
|
const node_path_1 = __importStar(require("node:path"));
|
|
35
35
|
const readline = __importStar(require("readline"));
|
|
36
|
+
const net = __importStar(require("net"));
|
|
36
37
|
const NodeCliUtilsConfig_js_1 = require("./NodeCliUtilsConfig.js");
|
|
37
38
|
const generalUtilsInternal_js_1 = require("./generalUtilsInternal.js");
|
|
38
39
|
const dockerComposeCommandsThatSupportDetached = ['exec', 'logs', 'ps', 'restart', 'run', 'start', 'stop', 'up'];
|
|
@@ -45,6 +46,17 @@ function log(data, ...moreData) {
|
|
|
45
46
|
console.log(data, ...moreData);
|
|
46
47
|
}
|
|
47
48
|
exports.log = log;
|
|
49
|
+
/**
|
|
50
|
+
* Log conditionally. Useful for methods that have an option to either suppress output or to show it when it normally isn't.
|
|
51
|
+
* @param data The data to log
|
|
52
|
+
* @param moreData More data to log
|
|
53
|
+
*/
|
|
54
|
+
function logIf(shouldLog, data, ...moreData) {
|
|
55
|
+
if (shouldLog) {
|
|
56
|
+
console.log(data, ...moreData);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.logIf = logIf;
|
|
48
60
|
/**
|
|
49
61
|
* Wrapper for console.log() that is suppressed if NodeCliUtilsConfig.logEnabled is false.
|
|
50
62
|
* @param data The data to log
|
|
@@ -93,30 +105,39 @@ async function sleep(ms) {
|
|
|
93
105
|
}
|
|
94
106
|
exports.sleep = sleep;
|
|
95
107
|
/**
|
|
96
|
-
* This is a wrapper function for NodeJS. Defaults stdio to inherit so that output is visible in the console,
|
|
97
|
-
* but note that this means stdout and stderr will not be available in the returned SpawnResult.
|
|
108
|
+
* This is a wrapper function for NodeJS spawn. Defaults stdio to inherit so that output is visible in the console,
|
|
109
|
+
* but note that this means stdout and stderr will not be available in the returned SpawnResult. To hide the output
|
|
110
|
+
* from the console but collect the stdout and stderr in the SpawnResult, use stdio: 'pipe'.
|
|
98
111
|
*
|
|
99
112
|
* When spawning long-running processes, use {@link spawnAsyncLongRunning} instead so that unexpected
|
|
100
113
|
* termination of the parent process will not orphan the child process tree on windows.
|
|
114
|
+
*
|
|
115
|
+
* **Warning:** Do NOT use this for generating commands dynamically from user input as it could be used to execute arbitrary code.
|
|
116
|
+
* This is meant solely for building up known commands that are not made up of unsanitized user input, and only at compile time.
|
|
117
|
+
* See {@link winInstallCert} and {@link winUninstallCert} for examples of taking user input and inserting it safely into known commands.
|
|
101
118
|
* @param command The command to spawn
|
|
102
119
|
* @param args The arguments to pass to the command
|
|
103
120
|
* @param options The options to pass to the command
|
|
104
121
|
* @returns A Promise that resolves to a {@link SpawnResult}
|
|
105
122
|
*/
|
|
106
123
|
async function spawnAsync(command, args, options) {
|
|
107
|
-
return (0, generalUtilsInternal_js_1.spawnAsyncInternal)(command, args, options);
|
|
124
|
+
return (0, generalUtilsInternal_js_1.spawnAsyncInternal)(command, args !== null && args !== void 0 ? args : [], options);
|
|
108
125
|
}
|
|
109
126
|
exports.spawnAsync = spawnAsync;
|
|
110
127
|
/**
|
|
111
128
|
* Use this alternate spawn wrapper instead of {@link spawnAsync} when spawning long-running processes to
|
|
112
129
|
* avoid orphaned child process trees on Windows.
|
|
130
|
+
*
|
|
131
|
+
* **Warning:** Do NOT use this for generating commands dynamically from user input as it could be used to execute arbitrary code.
|
|
132
|
+
* This is meant solely for building up known commands that are not made up of unsanitized user input, and only at compile time.
|
|
133
|
+
* See {@link winInstallCert} and {@link winUninstallCert} for examples of taking user input and inserting it safely into known commands.
|
|
113
134
|
* @param command The command to spawn
|
|
114
135
|
* @param args The arguments to pass to the command
|
|
115
136
|
* @param cwd The current working directory to run the command from - defaults to process.cwd()
|
|
116
137
|
* @returns A Promise that resolves to a {@link SpawnResult}
|
|
117
138
|
*/
|
|
118
139
|
async function spawnAsyncLongRunning(command, args, cwd) {
|
|
119
|
-
return (0, generalUtilsInternal_js_1.spawnAsyncInternal)(command, args, { cwd: cwd, isLongRunning: true });
|
|
140
|
+
return (0, generalUtilsInternal_js_1.spawnAsyncInternal)(command, args !== null && args !== void 0 ? args : [], { cwd: cwd, isLongRunning: true });
|
|
120
141
|
}
|
|
121
142
|
exports.spawnAsyncLongRunning = spawnAsyncLongRunning;
|
|
122
143
|
/**
|
|
@@ -124,10 +145,7 @@ exports.spawnAsyncLongRunning = spawnAsyncLongRunning;
|
|
|
124
145
|
* @param dir The directory to ensure exists. If it does not exist, it will be created.
|
|
125
146
|
*/
|
|
126
147
|
async function ensureDirectory(dir) {
|
|
127
|
-
|
|
128
|
-
if (!node_fs_1.default.existsSync(dir)) {
|
|
129
|
-
await mkdirp(dir);
|
|
130
|
-
}
|
|
148
|
+
return await mkdirp(dir);
|
|
131
149
|
}
|
|
132
150
|
exports.ensureDirectory = ensureDirectory;
|
|
133
151
|
/**
|
|
@@ -135,9 +153,19 @@ exports.ensureDirectory = ensureDirectory;
|
|
|
135
153
|
* @param dir The directory to create.
|
|
136
154
|
*/
|
|
137
155
|
async function mkdirp(dir) {
|
|
156
|
+
requireString('dir', dir);
|
|
138
157
|
await promises_1.default.mkdir(dir, { recursive: true });
|
|
139
158
|
}
|
|
140
159
|
exports.mkdirp = mkdirp;
|
|
160
|
+
/**
|
|
161
|
+
* Create a directory. Will create parent directory structure if it don't exist. Similar to `mkdir -p`.
|
|
162
|
+
* @param dir The directory to create.
|
|
163
|
+
*/
|
|
164
|
+
async function mkdirpSync(dir) {
|
|
165
|
+
requireString('dir', dir);
|
|
166
|
+
node_fs_1.default.mkdirSync(dir, { recursive: true });
|
|
167
|
+
}
|
|
168
|
+
exports.mkdirpSync = mkdirpSync;
|
|
141
169
|
/**
|
|
142
170
|
* Empties a directory of all files and subdirectories.
|
|
143
171
|
*
|
|
@@ -170,7 +198,7 @@ async function emptyDirectory(directoryToEmpty, fileAndDirectoryNamesToSkip) {
|
|
|
170
198
|
}
|
|
171
199
|
let dirEntry = await dir.read();
|
|
172
200
|
while (dirEntry) {
|
|
173
|
-
if (fileAndDirectoryNamesToSkip
|
|
201
|
+
if (fileAndDirectoryNamesToSkip === null || fileAndDirectoryNamesToSkip === void 0 ? void 0 : fileAndDirectoryNamesToSkip.includes(dirEntry.name)) {
|
|
174
202
|
dirEntry = await dir.read();
|
|
175
203
|
continue;
|
|
176
204
|
}
|
|
@@ -224,19 +252,14 @@ async function copyDirectoryContents(sourceDirectory, destinationDirectory) {
|
|
|
224
252
|
}
|
|
225
253
|
exports.copyDirectoryContents = copyDirectoryContents;
|
|
226
254
|
/**
|
|
227
|
-
* Helper method to validate that a non-falsy value is provided for a parameter that should be a string.
|
|
228
|
-
*
|
|
229
|
-
* **Warning:** this does not validate the type of the parameter, just whether something non-empty was provided.
|
|
230
|
-
* @param paramName The name of the parameter, for logging purposes
|
|
255
|
+
* Helper method to validate that a non-falsy and non-empty value is provided for a parameter that should be a string.
|
|
256
|
+
* @param paramName The name of the parameter to be used in the error message
|
|
231
257
|
* @param paramValue The value of the parameter
|
|
232
258
|
*/
|
|
233
259
|
function requireString(paramName, paramValue) {
|
|
234
|
-
if (paramValue === undefined || paramValue === null || paramValue === '') {
|
|
260
|
+
if (paramValue === undefined || paramValue === null || paramValue === '' || typeof paramValue !== 'string' || paramValue.trim() === '') {
|
|
235
261
|
throw new Error(`Required param '${paramName}' is missing`);
|
|
236
262
|
}
|
|
237
|
-
if (typeof paramValue !== 'string') {
|
|
238
|
-
throw new Error(`Required param '${paramName}' is not a string`);
|
|
239
|
-
}
|
|
240
263
|
}
|
|
241
264
|
exports.requireString = requireString;
|
|
242
265
|
/**
|
|
@@ -252,7 +275,29 @@ function requireValidPath(paramName, paramValue) {
|
|
|
252
275
|
}
|
|
253
276
|
exports.requireValidPath = requireValidPath;
|
|
254
277
|
/**
|
|
255
|
-
*
|
|
278
|
+
* Project names must contain only lowercase letters, decimal digits, dashes, and underscores, and must begin with a lowercase letter or decimal digit.
|
|
279
|
+
*
|
|
280
|
+
* See https://docs.docker.com/compose/environment-variables/envvars/#compose_project_name.
|
|
281
|
+
* @param projectName The string to validate
|
|
282
|
+
* @returns `true` if it's a valid docker compose project name and `false` otherwise
|
|
283
|
+
*/
|
|
284
|
+
function isDockerComposeProjectNameValid(projectName) {
|
|
285
|
+
requireString('projectName', projectName);
|
|
286
|
+
// Ensure first char is a lowercase letter or digit
|
|
287
|
+
if (!/^[a-z0-9]/.test(projectName[0])) {
|
|
288
|
+
return false;
|
|
289
|
+
}
|
|
290
|
+
// Ensure the rest of the chars are only lowercase letters, digits, dashes and underscores
|
|
291
|
+
return /^[a-z0-9-_]+$/.test(projectName);
|
|
292
|
+
}
|
|
293
|
+
exports.isDockerComposeProjectNameValid = isDockerComposeProjectNameValid;
|
|
294
|
+
/**
|
|
295
|
+
* For docker compose commands, see https://docs.docker.com/compose/reference/. For available options for this wrapper function, see {@link DockerComposeOptions}.
|
|
296
|
+
*
|
|
297
|
+
* The current working directory will be the directory of the {@link dockerComposePath} unless specified in the options. This ensures relative paths in the
|
|
298
|
+
* docker compose file will be relative to itself by default.
|
|
299
|
+
*
|
|
300
|
+
* See {@link DockerComposeOptions.projectName} for info on where to locate your docker compose file and how to specify the docker project name.
|
|
256
301
|
* @param dockerComposePath Path to docker-compose.yml
|
|
257
302
|
* @param dockerComposeCommand The docker-compose command to run
|
|
258
303
|
* @param options {@link DockerComposeOptions} to use, including additional arguments to pass to the docker compose command and the project name
|
|
@@ -260,45 +305,55 @@ exports.requireValidPath = requireValidPath;
|
|
|
260
305
|
async function spawnDockerCompose(dockerComposePath, dockerComposeCommand, options) {
|
|
261
306
|
requireValidPath('dockerComposePath', dockerComposePath);
|
|
262
307
|
requireString('dockerComposeCommand', dockerComposeCommand);
|
|
263
|
-
|
|
264
|
-
|
|
308
|
+
if (options === null || options === void 0 ? void 0 : options.cwd) {
|
|
309
|
+
requireValidPath('cwd', options.cwd);
|
|
310
|
+
}
|
|
311
|
+
if ((options === null || options === void 0 ? void 0 : options.projectName) && !isDockerComposeProjectNameValid(options.projectName)) {
|
|
312
|
+
throw new Error('Invalid docker compose project name specified for the projectName param. Project names must contain only lowercase letters, decimal digits, dashes, and underscores, and must begin with a lowercase letter or decimal digit.');
|
|
313
|
+
}
|
|
314
|
+
if ((options === null || options === void 0 ? void 0 : options.profile) && !/[a-zA-Z0-9][a-zA-Z0-9_.-]+/.test(options.profile)) {
|
|
315
|
+
throw new Error('Invalid profile option - must match regex: [a-zA-Z0-9][a-zA-Z0-9_.-]+');
|
|
316
|
+
}
|
|
317
|
+
if (!await isDockerRunning()) {
|
|
265
318
|
throw new Error('Docker is not running');
|
|
266
319
|
}
|
|
267
|
-
const defaultOptions = { attached: false };
|
|
320
|
+
const defaultOptions = { args: [], attached: false, projectName: undefined, cwd: undefined };
|
|
268
321
|
const mergedOptions = { ...defaultOptions, ...options };
|
|
269
322
|
const dockerComposeDir = node_path_1.default.dirname(dockerComposePath);
|
|
270
323
|
const dockerComposeFilename = node_path_1.default.basename(dockerComposePath);
|
|
271
|
-
|
|
272
|
-
|
|
324
|
+
if (!mergedOptions.cwd) {
|
|
325
|
+
mergedOptions.cwd = dockerComposeDir;
|
|
326
|
+
}
|
|
327
|
+
let spawnArgs = ['compose', '-f', mergedOptions.cwd ? node_path_1.default.resolve(dockerComposePath) : dockerComposeFilename];
|
|
273
328
|
if (mergedOptions.projectName) {
|
|
274
329
|
spawnArgs.push('--project-name', mergedOptions.projectName);
|
|
275
330
|
}
|
|
331
|
+
if (mergedOptions.profile) {
|
|
332
|
+
spawnArgs.push('--profile', mergedOptions.profile);
|
|
333
|
+
}
|
|
276
334
|
spawnArgs.push(dockerComposeCommand);
|
|
277
335
|
if (!mergedOptions.attached && dockerComposeCommandsThatSupportDetached.includes(dockerComposeCommand)) {
|
|
278
|
-
spawnArgs.push('
|
|
336
|
+
spawnArgs.push('--detach');
|
|
279
337
|
}
|
|
280
338
|
if (mergedOptions.args) {
|
|
281
339
|
spawnArgs = spawnArgs.concat(mergedOptions.args);
|
|
282
340
|
}
|
|
283
|
-
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
`running command: ${dockerCommandString}`;
|
|
287
|
-
trace(traceMessage);
|
|
288
|
-
const longRunning = dockerComposeCommandsThatSupportDetached.includes(dockerComposeCommand) && options && options.attached;
|
|
341
|
+
trace(`running command in ${mergedOptions.cwd}: docker ${spawnArgs.join(' ')}`);
|
|
342
|
+
const longRunning = dockerComposeCommandsThatSupportDetached.includes(dockerComposeCommand) && (options === null || options === void 0 ? void 0 : options.attached) === true;
|
|
343
|
+
trace(`docker compose command will be configured to use long running options: ${longRunning}`);
|
|
289
344
|
const spawnOptions = {
|
|
290
|
-
cwd:
|
|
291
|
-
shell:
|
|
345
|
+
cwd: mergedOptions.cwd,
|
|
346
|
+
shell: isPlatformWindows(),
|
|
292
347
|
isLongRunning: longRunning
|
|
293
348
|
};
|
|
294
|
-
const spawnResult = await (0, generalUtilsInternal_js_1.spawnAsyncInternal)(
|
|
349
|
+
const spawnResult = await (0, generalUtilsInternal_js_1.spawnAsyncInternal)('docker', spawnArgs, spawnOptions);
|
|
295
350
|
if (spawnResult.code !== 0) {
|
|
296
351
|
throw new Error(`docker compose command failed with code ${spawnResult.code}`);
|
|
297
352
|
}
|
|
298
353
|
}
|
|
299
354
|
exports.spawnDockerCompose = spawnDockerCompose;
|
|
300
355
|
/**
|
|
301
|
-
* Splits a string into lines, removing empty lines
|
|
356
|
+
* Splits a string into lines, removing `\n` and `\r` characters. Does not return empty lines. Also see {@link stringToLines}.
|
|
302
357
|
* @param str String to split into lines
|
|
303
358
|
* @returns An array of lines from the string, with empty lines removed
|
|
304
359
|
*/
|
|
@@ -306,15 +361,31 @@ function stringToNonEmptyLines(str) {
|
|
|
306
361
|
if (!str) {
|
|
307
362
|
return [];
|
|
308
363
|
}
|
|
309
|
-
return str.split('\n').filter(line => line
|
|
364
|
+
return str.split('\n').filter(line => line === null || line === void 0 ? void 0 : line.trim()).map(line => line.replace('\r', ''));
|
|
310
365
|
}
|
|
311
366
|
exports.stringToNonEmptyLines = stringToNonEmptyLines;
|
|
367
|
+
/**
|
|
368
|
+
* Splits a string into lines, removing `\n` and `\r` characters. Returns empty lines. Also see {@link stringToNonEmptyLines}.
|
|
369
|
+
* @param str String to split into lines
|
|
370
|
+
* @returns An array of lines from the string, with empty lines removed
|
|
371
|
+
*/
|
|
372
|
+
function stringToLines(str) {
|
|
373
|
+
if (!str) {
|
|
374
|
+
return [];
|
|
375
|
+
}
|
|
376
|
+
return str.split('\n').map(line => line.replace('\r', ''));
|
|
377
|
+
}
|
|
378
|
+
exports.stringToLines = stringToLines;
|
|
312
379
|
/**
|
|
313
380
|
* Runs the requested command using NodeJS spawnSync wrapped in an outer Windows CMD.exe command and returns the result with stdout split into lines.
|
|
314
381
|
*
|
|
315
382
|
* Use this for simple quick commands that don't require a lot of control.
|
|
316
383
|
*
|
|
317
384
|
* For commands that aren't Windows and CMD specific, use {@link simpleSpawnSync}.
|
|
385
|
+
*
|
|
386
|
+
* **Warning:** Do NOT use this for generating commands dynamically from user input as it could be used to execute arbitrary code.
|
|
387
|
+
* This is meant solely for building up known commands that are not made up of unsanitized user input, and only at compile time.
|
|
388
|
+
* See {@link winInstallCert} and {@link winUninstallCert} for examples of taking user input and inserting it safely into known commands.
|
|
318
389
|
* @param command Command to run
|
|
319
390
|
* @param args Arguments to pass to the command
|
|
320
391
|
* @returns An object with the status code, stdout, stderr, and error (if any)
|
|
@@ -324,38 +395,71 @@ function simpleCmdSync(command, args, throwOnNonZero = true) {
|
|
|
324
395
|
if (!isPlatformWindows()) {
|
|
325
396
|
throw new Error('getCmdResult is only supported on Windows');
|
|
326
397
|
}
|
|
327
|
-
|
|
398
|
+
// Was previously spawning 'cmd' directly with params '/D', '/S', '/C' - but we may as well let NodeJS do the work of escaping args to work correctly with cmd
|
|
399
|
+
return (0, generalUtilsInternal_js_1.simpleSpawnSyncInternal)(command, args, throwOnNonZero, true);
|
|
328
400
|
}
|
|
329
401
|
exports.simpleCmdSync = simpleCmdSync;
|
|
402
|
+
/**
|
|
403
|
+
* Runs the requested command using {@link spawnAsync} wrapped in an outer Windows CMD.exe command and returns the result with stdout split into lines.
|
|
404
|
+
*
|
|
405
|
+
* Use this for simple quick commands that don't require a lot of control.
|
|
406
|
+
*
|
|
407
|
+
* For commands that aren't Windows and CMD specific, use {@link simpleSpawnAsync}.
|
|
408
|
+
*
|
|
409
|
+
* **Warning:** Do NOT use this for generating commands dynamically from user input as it could be used to execute arbitrary code.
|
|
410
|
+
* This is meant solely for building up known commands that are not made up of unsanitized user input, and only at compile time.
|
|
411
|
+
* See {@link winInstallCert} and {@link winUninstallCert} for examples of taking user input and inserting it safely into known commands.
|
|
412
|
+
* @param command Command to run
|
|
413
|
+
* @param args Arguments to pass to the command
|
|
414
|
+
* @returns An object with the status code, stdout, stderr, and error (if any)
|
|
415
|
+
* @throws {@link SimpleSpawnError} if the command fails and throwOnNonZero is true
|
|
416
|
+
*/
|
|
417
|
+
async function simpleCmdAsync(command, args, throwOnNonZero = true) {
|
|
418
|
+
if (!isPlatformWindows()) {
|
|
419
|
+
throw new Error('getCmdResult is only supported on Windows');
|
|
420
|
+
}
|
|
421
|
+
// Was previously spawning 'cmd' directly with params '/D', '/S', '/C' - but we may as well let NodeJS do the work of escaping args to work correctly with cmd
|
|
422
|
+
return await (0, generalUtilsInternal_js_1.simpleSpawnAsyncInternal)(command, args, throwOnNonZero, true);
|
|
423
|
+
}
|
|
424
|
+
exports.simpleCmdAsync = simpleCmdAsync;
|
|
330
425
|
/**
|
|
331
426
|
* Runs the requested command using NodeJS spawnSync and returns the result with stdout split into lines.
|
|
332
427
|
*
|
|
333
428
|
* Use this for simple quick commands that don't require a lot of control.
|
|
334
429
|
*
|
|
335
430
|
* For commands that are Windows and CMD specific, use {@link simpleCmdSync}.
|
|
431
|
+
*
|
|
432
|
+
* **Warning:** Do NOT use this for generating commands dynamically from user input as it could be used to execute arbitrary code.
|
|
433
|
+
* This is meant solely for building up known commands that are not made up of unsanitized user input, and only at compile time.
|
|
434
|
+
* See {@link winInstallCert} and {@link winUninstallCert} for examples of taking user input and inserting it safely into known commands.
|
|
336
435
|
* @param command Command to run
|
|
337
436
|
* @param args Arguments to pass to the command
|
|
338
437
|
* @returns An object with the status code, stdout, stderr, and error (if any)
|
|
339
438
|
* @throws {@link SimpleSpawnError} if the command fails and throwOnNonZero is true
|
|
340
439
|
*/
|
|
341
440
|
function simpleSpawnSync(command, args, throwOnNonZero = true) {
|
|
342
|
-
|
|
343
|
-
requireString('command', command);
|
|
344
|
-
const result = (0, node_child_process_1.spawnSync)(command, args !== null && args !== void 0 ? args : [], { encoding: 'utf-8' });
|
|
345
|
-
const spawnResult = {
|
|
346
|
-
code: (_a = result.status) !== null && _a !== void 0 ? _a : 1,
|
|
347
|
-
stdout: result.stdout.toString(),
|
|
348
|
-
stderr: result.stdout.toString(),
|
|
349
|
-
stdoutLines: stringToNonEmptyLines(result.stdout.toString()),
|
|
350
|
-
error: result.error,
|
|
351
|
-
cwd: process.cwd()
|
|
352
|
-
};
|
|
353
|
-
if (spawnResult.code !== 0 && throwOnNonZero) {
|
|
354
|
-
throw new SimpleSpawnError(`spawned process failed with code ${spawnResult.code}`, spawnResult);
|
|
355
|
-
}
|
|
356
|
-
return spawnResult;
|
|
441
|
+
return (0, generalUtilsInternal_js_1.simpleSpawnSyncInternal)(command, args, throwOnNonZero);
|
|
357
442
|
}
|
|
358
443
|
exports.simpleSpawnSync = simpleSpawnSync;
|
|
444
|
+
/**
|
|
445
|
+
* Runs the requested command using {@link spawnAsync} and returns the result with stdout split into lines.
|
|
446
|
+
*
|
|
447
|
+
* Use this for simple quick commands that don't require a lot of control.
|
|
448
|
+
*
|
|
449
|
+
* For commands that are Windows and CMD specific, use {@link simpleCmdSync}.
|
|
450
|
+
*
|
|
451
|
+
* **Warning:** Do NOT use this for generating commands dynamically from user input as it could be used to execute arbitrary code.
|
|
452
|
+
* This is meant solely for building up known commands that are not made up of unsanitized user input, and only at compile time.
|
|
453
|
+
* See {@link winInstallCert} and {@link winUninstallCert} for examples of taking user input and inserting it safely into known commands.
|
|
454
|
+
* @param command Command to run
|
|
455
|
+
* @param args Arguments to pass to the command
|
|
456
|
+
* @returns An object with the status code, stdout, stderr, and error (if any)
|
|
457
|
+
* @throws {@link SimpleSpawnError} if the command fails and throwOnNonZero is true
|
|
458
|
+
*/
|
|
459
|
+
async function simpleSpawnAsync(command, args, throwOnNonZero = true) {
|
|
460
|
+
return await (0, generalUtilsInternal_js_1.simpleSpawnAsyncInternal)(command, args, throwOnNonZero);
|
|
461
|
+
}
|
|
462
|
+
exports.simpleSpawnAsync = simpleSpawnAsync;
|
|
359
463
|
/**
|
|
360
464
|
* @returns `true` if platform() is 'win32', `false` otherwise
|
|
361
465
|
*/
|
|
@@ -373,7 +477,7 @@ function isPlatformMac() {
|
|
|
373
477
|
exports.isPlatformMac = isPlatformMac;
|
|
374
478
|
/**
|
|
375
479
|
*
|
|
376
|
-
* @returns `true` if {@link isPlatformWindows} and {@link isPlatformMac} are both `false, otherwise returns `
|
|
480
|
+
* @returns `true` if {@link isPlatformWindows} and {@link isPlatformMac} are both `false, otherwise returns `true`
|
|
377
481
|
*/
|
|
378
482
|
function isPlatformLinux() {
|
|
379
483
|
return !isPlatformWindows() && !isPlatformMac();
|
|
@@ -381,33 +485,27 @@ function isPlatformLinux() {
|
|
|
381
485
|
exports.isPlatformLinux = isPlatformLinux;
|
|
382
486
|
/**
|
|
383
487
|
* This is a cross-platform method to get the location of a system command. Useful for checking if software
|
|
384
|
-
* is installed, where it's installed and whether there are multiple locations
|
|
488
|
+
* is installed, where it's installed and whether there are multiple locations.
|
|
489
|
+
* @param commandName The name of the command to find
|
|
490
|
+
* @returns The location of the command, any additional locations, and an error if one occurred
|
|
491
|
+
*/
|
|
492
|
+
async function which(commandName) {
|
|
493
|
+
return (0, generalUtilsInternal_js_1.whichInternal)(commandName, simpleCmdAsync, simpleSpawnAsync);
|
|
494
|
+
}
|
|
495
|
+
exports.which = which;
|
|
496
|
+
/**
|
|
497
|
+
* This is a cross-platform method to get the location of a system command. Useful for checking if software
|
|
498
|
+
* is installed, where it's installed and whether there are multiple locations.
|
|
385
499
|
* @param commandName The name of the command to find
|
|
386
500
|
* @returns The location of the command, any additional locations, and an error if one occurred
|
|
387
501
|
*/
|
|
388
502
|
function whichSync(commandName) {
|
|
389
|
-
|
|
390
|
-
const result = simpleCmdSync('where', [commandName]);
|
|
391
|
-
return {
|
|
392
|
-
location: result.stdoutLines[0],
|
|
393
|
-
additionalLocations: result.stdoutLines.slice(1),
|
|
394
|
-
error: result.error
|
|
395
|
-
};
|
|
396
|
-
}
|
|
397
|
-
else {
|
|
398
|
-
const result = simpleSpawnSync('which', ['-a', commandName]);
|
|
399
|
-
return {
|
|
400
|
-
location: result.stdoutLines[0],
|
|
401
|
-
additionalLocations: result.stdoutLines.slice(1),
|
|
402
|
-
error: result.error
|
|
403
|
-
};
|
|
404
|
-
}
|
|
503
|
+
return (0, generalUtilsInternal_js_1.whichInternal)(commandName, simpleCmdSync, simpleSpawnSync);
|
|
405
504
|
}
|
|
406
505
|
exports.whichSync = whichSync;
|
|
407
506
|
/**
|
|
408
|
-
* First checks if docker is installed and if not immediately returns false.
|
|
409
|
-
*
|
|
410
|
-
* Then runs the `docker info` command and looks for "error during connect" in the output to determine if docker is running.
|
|
507
|
+
* First checks if docker is installed and if not immediately returns false. Then runs the `docker info`
|
|
508
|
+
* command and looks for "error during connect" in the output to determine if docker is running.
|
|
411
509
|
* @returns `true` if docker is installed and running, `false` otherwise
|
|
412
510
|
*/
|
|
413
511
|
async function isDockerRunning() {
|
|
@@ -415,21 +513,13 @@ async function isDockerRunning() {
|
|
|
415
513
|
trace('whichSync will not check if docker is running because docker does not appear to be installed - returning false');
|
|
416
514
|
return false;
|
|
417
515
|
}
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
resolve(false);
|
|
426
|
-
}
|
|
427
|
-
else {
|
|
428
|
-
resolve(true);
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
});
|
|
432
|
-
});
|
|
516
|
+
try {
|
|
517
|
+
const result = await simpleSpawnAsync('docker', ['info']);
|
|
518
|
+
return !result.stdout.includes('error during connect');
|
|
519
|
+
}
|
|
520
|
+
catch (err) {
|
|
521
|
+
return false;
|
|
522
|
+
}
|
|
433
523
|
}
|
|
434
524
|
exports.isDockerRunning = isDockerRunning;
|
|
435
525
|
/**
|
|
@@ -459,10 +549,10 @@ function getConfirmation(question) {
|
|
|
459
549
|
output: process.stdout,
|
|
460
550
|
});
|
|
461
551
|
return new Promise((resolve) => {
|
|
462
|
-
rl.question(`\n
|
|
552
|
+
rl.question(`\n ${Emoji.RedQuestion} ${question}\n ${Emoji.RightArrow} Proceed? (yes/no): `, (answer) => {
|
|
463
553
|
rl.close();
|
|
464
554
|
const confirmed = answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes';
|
|
465
|
-
log(confirmed ?
|
|
555
|
+
log(confirmed ? ` ${Emoji.GreenCheck} Proceeding\n` : ` ${Emoji.RedX} Aborting\n`);
|
|
466
556
|
resolve(confirmed);
|
|
467
557
|
});
|
|
468
558
|
});
|
|
@@ -600,25 +690,15 @@ exports.deleteEnvIfExists = deleteEnvIfExists;
|
|
|
600
690
|
* @returns A Promise that resolves to an array of file paths that match the pattern
|
|
601
691
|
*/
|
|
602
692
|
async function findFilesRecursively(dir, filenamePattern, options) {
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
if (filenamePattern.length > 50) {
|
|
606
|
-
throw new Error(`filenamePattern param must have fewer than 50 characters`);
|
|
607
|
-
}
|
|
608
|
-
const numWildcards = filenamePattern.replace(/\*+/g, '*').split('*').length - 1;
|
|
609
|
-
if (numWildcards > 5) {
|
|
610
|
-
throw new Error(`filenamePattern param must contain 5 or fewer wildcards`);
|
|
611
|
-
}
|
|
612
|
-
if (filenamePattern.includes('/') || filenamePattern.includes('\\')) {
|
|
613
|
-
throw new Error('filenamePattern param must not contain slashes');
|
|
614
|
-
}
|
|
615
|
-
const defaultOptions = { maxDepth: 5 };
|
|
693
|
+
(0, generalUtilsInternal_js_1.validateFindFilesRecursivelyParams)(dir, filenamePattern);
|
|
694
|
+
const defaultOptions = { maxDepth: 5, excludeDirectoryNames: [], returnForwardSlashRelativePaths: false };
|
|
616
695
|
const mergedOptions = { ...defaultOptions, ...options };
|
|
617
696
|
// Convert the pattern to a regex
|
|
618
697
|
const regex = new RegExp('^' + filenamePattern.split(/\*+/).map(escapeStringForRegex).join('.*') + '$');
|
|
619
698
|
const matches = [];
|
|
620
699
|
// Recursive function to search within directories
|
|
621
700
|
async function searchDirectory(directory, depth) {
|
|
701
|
+
var _a;
|
|
622
702
|
if (depth > mergedOptions.maxDepth)
|
|
623
703
|
return;
|
|
624
704
|
const entries = await promises_1.default.readdir(directory, { withFileTypes: true });
|
|
@@ -626,7 +706,7 @@ async function findFilesRecursively(dir, filenamePattern, options) {
|
|
|
626
706
|
const fullPath = (0, node_path_1.resolve)(directory, entry.name);
|
|
627
707
|
if (entry.isDirectory()) {
|
|
628
708
|
// Check if directory is in the exclude list
|
|
629
|
-
if (!mergedOptions.excludeDirectoryNames ||
|
|
709
|
+
if (!((_a = mergedOptions.excludeDirectoryNames) === null || _a === void 0 ? void 0 : _a.includes(entry.name))) {
|
|
630
710
|
await searchDirectory(fullPath, depth + 1);
|
|
631
711
|
}
|
|
632
712
|
}
|
|
@@ -649,4 +729,340 @@ function escapeStringForRegex(str) {
|
|
|
649
729
|
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
650
730
|
}
|
|
651
731
|
exports.escapeStringForRegex = escapeStringForRegex;
|
|
652
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhbFV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2dlbmVyYWxVdGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDJEQUFrRTtBQUNsRSxzREFBd0I7QUFDeEIsZ0VBQWtDO0FBQ2xDLHFDQUFrQztBQUNsQyx1REFBeUM7QUFDekMsbURBQW9DO0FBQ3BDLG1FQUFnRDtBQUNoRCx1RUFBNEk7QUFFNUksTUFBTSx3Q0FBd0MsR0FBRyxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQTtBQUVoSDs7OztHQUlHO0FBQ0gsU0FBZ0IsR0FBRyxDQUFDLElBQWEsRUFBRSxHQUFHLFFBQW1CO0lBQ3ZELE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLEdBQUcsUUFBUSxDQUFDLENBQUE7QUFDaEMsQ0FBQztBQUZELGtCQUVDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQWdCLEtBQUssQ0FBQyxJQUFjLEVBQUUsR0FBRyxRQUFtQjtJQUMxRCxJQUFJLDhCQUFNLENBQUMsWUFBWSxFQUFFO1FBQ3ZCLE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQTtRQUN4QixPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxRQUFRLENBQUMsQ0FBQTtLQUN2QztBQUNILENBQUM7QUFMRCxzQkFLQztBQWlDRDs7OztHQUlHO0FBQ0gsTUFBYSxVQUFXLFNBQVEsS0FBSztJQUduQyxZQUFZLE9BQWUsRUFBRSxNQUFtQjtRQUM5QyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUE7UUFDZCxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQTtJQUN0QixDQUFDO0NBQ0Y7QUFQRCxnQ0FPQztBQVdEOzs7O0dBSUc7QUFDSCxNQUFhLGdCQUFpQixTQUFR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
|
|
732
|
+
/**
|
|
733
|
+
* Logs the provided 2-dimensional string array as a formatted table.
|
|
734
|
+
*
|
|
735
|
+
* @param data 2-dimensional string array where the first row is the column headers
|
|
736
|
+
* @example
|
|
737
|
+
*
|
|
738
|
+
* logTable([
|
|
739
|
+
* ['Name', 'Age', 'Country'],
|
|
740
|
+
* ['Alice', '28', 'USA'],
|
|
741
|
+
* ['Bob', '22', 'Canada']
|
|
742
|
+
* ])
|
|
743
|
+
*/
|
|
744
|
+
function logTable(data) {
|
|
745
|
+
if (data.length === 0 || data[0].length === 0)
|
|
746
|
+
return;
|
|
747
|
+
const numColumns = data[0].length;
|
|
748
|
+
const columnWidths = [];
|
|
749
|
+
for (let i = 0; i < numColumns; i++) {
|
|
750
|
+
columnWidths[i] = Math.max(...data.map(row => { var _a; return ((_a = row[i]) === null || _a === void 0 ? void 0 : _a.length) || 0; }));
|
|
751
|
+
}
|
|
752
|
+
const lineSeparator = columnWidths.map(width => '-'.repeat(width)).join(' + ');
|
|
753
|
+
for (let i = 0; i < data.length; i++) {
|
|
754
|
+
const paddedRowArray = data[i].map((cell, colIdx) => cell.padEnd(columnWidths[colIdx], ' '));
|
|
755
|
+
log(paddedRowArray.join(' | '));
|
|
756
|
+
if (i === 0)
|
|
757
|
+
log(lineSeparator);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
exports.logTable = logTable;
|
|
761
|
+
/**
|
|
762
|
+
* See {@link getPowershellHackArgs}.
|
|
763
|
+
*/
|
|
764
|
+
exports.powershellHackPrefix = `$env:PSModulePath = [Environment]::GetEnvironmentVariable('PSModulePath', 'Machine'); `;
|
|
765
|
+
/**
|
|
766
|
+
* Powershell doesn't load the system PSModulePath when running in a non-interactive shell.
|
|
767
|
+
* This is a workaround to set the PSModulePath environment variable to the system value before running a powershell command.
|
|
768
|
+
*
|
|
769
|
+
* **Warning:** Do NOT use this for generating commands dynamically from user input as it could be used to execute arbitrary code.
|
|
770
|
+
* This is meant solely for building up known commands that are not made up of unsanitized user input, and only at compile time.
|
|
771
|
+
* See {@link winInstallCert} and {@link winUninstallCert} for examples of taking user input and inserting it safely into known commands.
|
|
772
|
+
* @param command The powershell command to run
|
|
773
|
+
* @returns An array of arguments to pass to {@link spawnAsync} with the "powershell" command as the first argument
|
|
774
|
+
*/
|
|
775
|
+
function getPowershellHackArgs(command) {
|
|
776
|
+
return ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', `${exports.powershellHackPrefix}${command}`];
|
|
777
|
+
}
|
|
778
|
+
exports.getPowershellHackArgs = getPowershellHackArgs;
|
|
779
|
+
/**
|
|
780
|
+
* Returns a humanized string representation of the number of milliseconds using ms, seconds, minutes, or hours.
|
|
781
|
+
* @param milliseconds The number of milliseconds to humanize
|
|
782
|
+
* @returns A humanized string representation of the number
|
|
783
|
+
*/
|
|
784
|
+
function humanizeTime(milliseconds) {
|
|
785
|
+
let value;
|
|
786
|
+
let unit;
|
|
787
|
+
if (milliseconds < 1000) {
|
|
788
|
+
return `${milliseconds} ms`;
|
|
789
|
+
}
|
|
790
|
+
if (milliseconds < 60000) {
|
|
791
|
+
value = milliseconds / 1000;
|
|
792
|
+
unit = 'second';
|
|
793
|
+
}
|
|
794
|
+
else if (milliseconds < 3600000) {
|
|
795
|
+
value = milliseconds / 60000;
|
|
796
|
+
unit = 'minute';
|
|
797
|
+
}
|
|
798
|
+
else {
|
|
799
|
+
value = milliseconds / 3600000;
|
|
800
|
+
unit = 'hour';
|
|
801
|
+
}
|
|
802
|
+
let stringValue = value.toFixed(2);
|
|
803
|
+
if (stringValue.endsWith('.00')) {
|
|
804
|
+
stringValue = stringValue.slice(0, -3);
|
|
805
|
+
}
|
|
806
|
+
else if (stringValue.endsWith('0')) {
|
|
807
|
+
stringValue = stringValue.slice(0, -1);
|
|
808
|
+
}
|
|
809
|
+
if (stringValue !== '1') {
|
|
810
|
+
unit += 's';
|
|
811
|
+
}
|
|
812
|
+
return `${stringValue} ${unit}`;
|
|
813
|
+
}
|
|
814
|
+
exports.humanizeTime = humanizeTime;
|
|
815
|
+
class ExtendedError extends Error {
|
|
816
|
+
constructor(message, innerError) {
|
|
817
|
+
super(message);
|
|
818
|
+
this.innerError = innerError !== null && innerError !== void 0 ? innerError : null;
|
|
819
|
+
Object.setPrototypeOf(this, ExtendedError.prototype);
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
exports.ExtendedError = ExtendedError;
|
|
823
|
+
function getHostname(url) {
|
|
824
|
+
requireString('url', url);
|
|
825
|
+
trace(`attempting to convert url to hostname: ${url}`);
|
|
826
|
+
try {
|
|
827
|
+
const encodedUrl = encodeURI(url);
|
|
828
|
+
const parsedUrl = new URL(encodedUrl.startsWith('http') ? encodedUrl : 'https://' + encodedUrl);
|
|
829
|
+
trace(`parsed url: ${parsedUrl}`);
|
|
830
|
+
return parsedUrl.hostname;
|
|
831
|
+
}
|
|
832
|
+
catch (e) {
|
|
833
|
+
throw new ExtendedError("Invalid URL", e);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
exports.getHostname = getHostname;
|
|
837
|
+
async function isDirectory(path) {
|
|
838
|
+
try {
|
|
839
|
+
const stats = await promises_1.default.stat(path);
|
|
840
|
+
return stats.isDirectory();
|
|
841
|
+
}
|
|
842
|
+
catch (err) {
|
|
843
|
+
trace('error checking idDirectory (returning false)', err);
|
|
844
|
+
return false;
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
exports.isDirectory = isDirectory;
|
|
848
|
+
function isDirectorySync(path) {
|
|
849
|
+
try {
|
|
850
|
+
const stats = node_fs_1.default.statSync(path);
|
|
851
|
+
return stats.isDirectory();
|
|
852
|
+
}
|
|
853
|
+
catch (err) {
|
|
854
|
+
trace('error checking idDirectory (returning false)', err);
|
|
855
|
+
return false;
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
exports.isDirectorySync = isDirectorySync;
|
|
859
|
+
/**
|
|
860
|
+
* This is a somewhat naive method but is useful if you rarely or never deal with unusual operating systems.
|
|
861
|
+
* @returns `win`, `mac` or `linux`
|
|
862
|
+
*/
|
|
863
|
+
function getPlatformCode() {
|
|
864
|
+
if (isPlatformWindows()) {
|
|
865
|
+
return 'win';
|
|
866
|
+
}
|
|
867
|
+
if (isPlatformMac()) {
|
|
868
|
+
return 'mac';
|
|
869
|
+
}
|
|
870
|
+
if (isPlatformLinux()) {
|
|
871
|
+
return 'linux';
|
|
872
|
+
}
|
|
873
|
+
throw new Error('unrecognized platform: ' + (0, node_os_1.platform)());
|
|
874
|
+
}
|
|
875
|
+
exports.getPlatformCode = getPlatformCode;
|
|
876
|
+
/**
|
|
877
|
+
* Tries connecting to a port to see if it's being listened on or not. It's likely that this won't work in a lot of scenarios, so use it at your own risk.
|
|
878
|
+
* @param port The port to check
|
|
879
|
+
* @returns `true` if the port is available, `false` otherwise
|
|
880
|
+
*/
|
|
881
|
+
async function isPortAvailable(port) {
|
|
882
|
+
return new Promise((resolve) => {
|
|
883
|
+
const tester = net.connect(port, '127.0.0.1');
|
|
884
|
+
tester.on('connect', () => {
|
|
885
|
+
tester.destroy();
|
|
886
|
+
resolve(false); // port is in use
|
|
887
|
+
});
|
|
888
|
+
tester.on('error', (err) => {
|
|
889
|
+
tester.destroy();
|
|
890
|
+
if (err.code === 'ECONNREFUSED') {
|
|
891
|
+
resolve(true); // port is available
|
|
892
|
+
}
|
|
893
|
+
else {
|
|
894
|
+
resolve(false); // some other error occurred, assume port is in use
|
|
895
|
+
}
|
|
896
|
+
});
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
exports.isPortAvailable = isPortAvailable;
|
|
900
|
+
/**
|
|
901
|
+
* Returns the value for an environment variable or throws if it's undefined or null. Pass optional {@param throwOnEmpty} to throw when the key exists but has an empty value.
|
|
902
|
+
* @param varName The name of the environment variable to get.
|
|
903
|
+
* @param throwOnEmpty Throw an error if key exists (not undefined or null) but is empty.
|
|
904
|
+
* @returns
|
|
905
|
+
*/
|
|
906
|
+
function getRequiredEnvVar(varName, throwOnEmpty = true) {
|
|
907
|
+
requireString('varName', varName);
|
|
908
|
+
const val = process.env[varName];
|
|
909
|
+
if (val === undefined || val === null) {
|
|
910
|
+
throw new Error(`Missing required environment variable: ${varName}`);
|
|
911
|
+
}
|
|
912
|
+
if (throwOnEmpty && val.trim() === '') {
|
|
913
|
+
throw new Error(`Required environment variable is empty: ${varName}`);
|
|
914
|
+
}
|
|
915
|
+
return val;
|
|
916
|
+
}
|
|
917
|
+
exports.getRequiredEnvVar = getRequiredEnvVar;
|
|
918
|
+
function getNormalizedError(err) {
|
|
919
|
+
let lastErrorAsError;
|
|
920
|
+
if (err === undefined || err === null) {
|
|
921
|
+
lastErrorAsError = new Error('lastError was undefined or null');
|
|
922
|
+
}
|
|
923
|
+
else if (err instanceof Error) {
|
|
924
|
+
lastErrorAsError = err;
|
|
925
|
+
}
|
|
926
|
+
else if (typeof err === 'string') {
|
|
927
|
+
lastErrorAsError = new Error(err);
|
|
928
|
+
}
|
|
929
|
+
else if (err instanceof Object) {
|
|
930
|
+
try {
|
|
931
|
+
lastErrorAsError = new Error(JSON.stringify(err));
|
|
932
|
+
}
|
|
933
|
+
catch (jsonError) {
|
|
934
|
+
lastErrorAsError = new Error('Object could not be serialized - could not normalize');
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
else {
|
|
938
|
+
lastErrorAsError = new Error(`Unknown error of type ${typeof err} - could not normalize`);
|
|
939
|
+
}
|
|
940
|
+
return lastErrorAsError;
|
|
941
|
+
}
|
|
942
|
+
exports.getNormalizedError = getNormalizedError;
|
|
943
|
+
/**
|
|
944
|
+
* Call a function until it succeeds. Will stop after the number of calls specified by {@param maxCalls}, or forever if -1 is passed.
|
|
945
|
+
* @param func The function to call
|
|
946
|
+
* @param maxCalls The maximum number of times to call the function before giving up. Pass -1 to retry forever.
|
|
947
|
+
* @param delayMilliseconds The number of milliseconds to wait between calls
|
|
948
|
+
* @param options Options for controlling the behavior of the retry. See {@link WithRetryOptions}.
|
|
949
|
+
*/
|
|
950
|
+
async function withRetryAsync(func, maxCalls, delayMilliseconds, options) {
|
|
951
|
+
var _a, _b;
|
|
952
|
+
let attemptNumber = 0;
|
|
953
|
+
let lastError;
|
|
954
|
+
const forever = maxCalls === -1;
|
|
955
|
+
const defaultOptions = { initialDelayMilliseconds: 0, traceEnabled: false };
|
|
956
|
+
const mergedOptions = { ...defaultOptions, ...options };
|
|
957
|
+
const shouldLog = NodeCliUtilsConfig_js_1.config.traceEnabled || mergedOptions.traceEnabled;
|
|
958
|
+
const retryLog = shouldLog ? log : () => { };
|
|
959
|
+
const funcName = (_b = (_a = mergedOptions.functionLabel) !== null && _a !== void 0 ? _a : func.name) !== null && _b !== void 0 ? _b : 'anonymous';
|
|
960
|
+
if (mergedOptions.initialDelayMilliseconds > 0) {
|
|
961
|
+
retryLog(`initialDelayMilliseconds set to ${mergedOptions.initialDelayMilliseconds} - waiting before first try`);
|
|
962
|
+
await sleep(mergedOptions.initialDelayMilliseconds);
|
|
963
|
+
}
|
|
964
|
+
// eslint-disable-next-line no-constant-condition
|
|
965
|
+
while (true) {
|
|
966
|
+
attemptNumber++;
|
|
967
|
+
retryLog(`calling ${funcName} - attempt number ${attemptNumber}`);
|
|
968
|
+
try {
|
|
969
|
+
await func();
|
|
970
|
+
retryLog(`attempt ${attemptNumber} was successful`);
|
|
971
|
+
break;
|
|
972
|
+
}
|
|
973
|
+
catch (err) {
|
|
974
|
+
if (shouldLog) {
|
|
975
|
+
console.error(err);
|
|
976
|
+
}
|
|
977
|
+
lastError = err;
|
|
978
|
+
}
|
|
979
|
+
if (!forever && attemptNumber === maxCalls) {
|
|
980
|
+
throw new ExtendedError(`Failed to run method with retry after ${maxCalls} attempts`, getNormalizedError(lastError));
|
|
981
|
+
}
|
|
982
|
+
retryLog(`attempt number ${attemptNumber} failed - waiting ${delayMilliseconds} milliseconds before trying again`);
|
|
983
|
+
await sleep(delayMilliseconds);
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
exports.withRetryAsync = withRetryAsync;
|
|
987
|
+
/**
|
|
988
|
+
* Collapses each instance of consecutive whitespace characters into a single space.
|
|
989
|
+
*/
|
|
990
|
+
function collapseWhitespace(str) {
|
|
991
|
+
return str.replace(/\s+/g, ' ');
|
|
992
|
+
}
|
|
993
|
+
exports.collapseWhitespace = collapseWhitespace;
|
|
994
|
+
/**
|
|
995
|
+
* Check if a string is a valid directory name. This is a very simple check that just makes sure the string doesn't contain any invalid characters.
|
|
996
|
+
* @param dirName The directory name to check
|
|
997
|
+
* @returns `true` if the directory name is valid, `false` otherwise
|
|
998
|
+
*/
|
|
999
|
+
function isValidDirName(dirName) {
|
|
1000
|
+
// List of generally invalid characters for directory names in Windows, macOS, and Linux
|
|
1001
|
+
const invalidChars = ['<', '>', ':', '"', '/', '\\', '|', '?', '*'];
|
|
1002
|
+
for (const char of dirName) {
|
|
1003
|
+
if (invalidChars.includes(char) || char.charCodeAt(0) <= 31) {
|
|
1004
|
+
return false;
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
return true;
|
|
1008
|
+
}
|
|
1009
|
+
exports.isValidDirName = isValidDirName;
|
|
1010
|
+
function hasWhitespace(str) {
|
|
1011
|
+
return /\s/.test(str);
|
|
1012
|
+
}
|
|
1013
|
+
exports.hasWhitespace = hasWhitespace;
|
|
1014
|
+
function stripShellMetaCharacters(input) {
|
|
1015
|
+
const metaCharacters = [
|
|
1016
|
+
'\\', '`', '$', '"', "'", '<', '>', '|', ';', ' ',
|
|
1017
|
+
'&', '(', ')', '[', ']', '{', '}', '?', '*', '#', '~', '^'
|
|
1018
|
+
];
|
|
1019
|
+
const escapeRegex = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
1020
|
+
const regex = new RegExp(`[${metaCharacters.map(escapeRegex).join('')}]`, 'g');
|
|
1021
|
+
return input.replace(regex, '');
|
|
1022
|
+
}
|
|
1023
|
+
exports.stripShellMetaCharacters = stripShellMetaCharacters;
|
|
1024
|
+
var AnsiColor;
|
|
1025
|
+
(function (AnsiColor) {
|
|
1026
|
+
AnsiColor["RESET"] = "\u001B[0m";
|
|
1027
|
+
AnsiColor["RED"] = "\u001B[31m";
|
|
1028
|
+
AnsiColor["GREEN"] = "\u001B[32m";
|
|
1029
|
+
AnsiColor["YELLOW"] = "\u001B[33m";
|
|
1030
|
+
AnsiColor["CYAN"] = "\u001B[96m";
|
|
1031
|
+
AnsiColor["GRAY"] = "\u001B[90m";
|
|
1032
|
+
AnsiColor["PURPLE"] = "\u001B[35m";
|
|
1033
|
+
})(AnsiColor || (exports.AnsiColor = AnsiColor = {}));
|
|
1034
|
+
const color = (str, colorAnsiCode) => {
|
|
1035
|
+
return `${colorAnsiCode}${str}${AnsiColor.RESET}`;
|
|
1036
|
+
};
|
|
1037
|
+
exports.color = color;
|
|
1038
|
+
const red = (str) => (0, exports.color)(str, AnsiColor.RED);
|
|
1039
|
+
exports.red = red;
|
|
1040
|
+
const green = (str) => (0, exports.color)(str, AnsiColor.GREEN);
|
|
1041
|
+
exports.green = green;
|
|
1042
|
+
const cyan = (str) => (0, exports.color)(str, AnsiColor.CYAN);
|
|
1043
|
+
exports.cyan = cyan;
|
|
1044
|
+
const gray = (str) => (0, exports.color)(str, AnsiColor.GRAY);
|
|
1045
|
+
exports.gray = gray;
|
|
1046
|
+
const purple = (str) => (0, exports.color)(str, AnsiColor.PURPLE);
|
|
1047
|
+
exports.purple = purple;
|
|
1048
|
+
const yellow = (str) => (0, exports.color)(str, AnsiColor.YELLOW);
|
|
1049
|
+
exports.yellow = yellow;
|
|
1050
|
+
var Emoji;
|
|
1051
|
+
(function (Emoji) {
|
|
1052
|
+
Emoji["RightArrow"] = "\u27A1\uFE0F";
|
|
1053
|
+
Emoji["LeftArrow"] = "\u2B05\uFE0F";
|
|
1054
|
+
Emoji["GreenCheck"] = "\u2705";
|
|
1055
|
+
Emoji["Warning"] = "\u26A0\uFE0F";
|
|
1056
|
+
Emoji["Lightning"] = "\u26A1";
|
|
1057
|
+
Emoji["Exclamation"] = "\u2757";
|
|
1058
|
+
Emoji["RedQuestion"] = "\u2753";
|
|
1059
|
+
Emoji["RedX"] = "\u274C";
|
|
1060
|
+
Emoji["Info"] = "\u2139\uFE0F";
|
|
1061
|
+
Emoji["SadFace"] = "\uD83D\uDE22";
|
|
1062
|
+
Emoji["Tools"] = "\uD83D\uDEE0\uFE0F";
|
|
1063
|
+
Emoji["NoEntry"] = "\u26D4";
|
|
1064
|
+
Emoji["Stop"] = "\uD83D\uDED1";
|
|
1065
|
+
Emoji["Certificate"] = "\uD83D\uDCDC";
|
|
1066
|
+
Emoji["Key"] = "\uD83D\uDD11";
|
|
1067
|
+
})(Emoji || (exports.Emoji = Emoji = {}));
|
|
1068
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhbFV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2dlbmVyYWxVdGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFDQSxzREFBd0I7QUFDeEIsZ0VBQWtDO0FBQ2xDLHFDQUFrQztBQUNsQyx1REFBeUM7QUFDekMsbURBQW9DO0FBQ3BDLHlDQUEwQjtBQUMxQixtRUFBZ0Q7QUFDaEQsdUVBQWtQO0FBTWxQLE1BQU0sd0NBQXdDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUE7QUFFaEg7Ozs7R0FJRztBQUNILFNBQWdCLEdBQUcsQ0FBQyxJQUFhLEVBQUUsR0FBRyxRQUFtQjtJQUN2RCxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxHQUFHLFFBQVEsQ0FBQyxDQUFBO0FBQ2hDLENBQUM7QUFGRCxrQkFFQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFnQixLQUFLLENBQUMsU0FBa0IsRUFBRSxJQUFhLEVBQUUsR0FBRyxRQUFtQjtJQUM3RSxJQUFJLFNBQVMsRUFBRTtRQUNiLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLEdBQUcsUUFBUSxDQUFDLENBQUE7S0FDL0I7QUFDSCxDQUFDO0FBSkQsc0JBSUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBZ0IsS0FBSyxDQUFDLElBQWMsRUFBRSxHQUFHLFFBQW1CO0lBQzFELElBQUksOEJBQU0sQ0FBQyxZQUFZLEVBQUU7UUFDdkIsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFBO1FBQ3hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLFFBQVEsQ0FBQyxDQUFBO0tBQ3ZDO0FBQ0gsQ0FBQztBQUxELHNCQUtDO0FBaUNEOzs7O0dBSUc7QUFDSCxNQUFh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
|