UNPKG

just-scripts

Version:
107 lines 4.48 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.spawn = exports.logNodeCommand = exports.encodeArgs = void 0; const cross_spawn_1 = require("cross-spawn"); const just_task_1 = require("just-task"); // `exec` and `execSync` were removed due to security issues (keeping filename for history) /** * @deprecated This prevents issues from spaces in args, but does NOT escape shell metacharacters. * For full escaping, consider a library such as `shell-quote` instead. (Note that `spawn` and tasks * from this package now use `cross-spawn` which escapes spaces internally.) */ function encodeArgs(cmdArgs) { return quoteSpaces(cmdArgs); } exports.encodeArgs = encodeArgs; /** * Quote arguments containing spaces. Note that this does NOT do any other escaping! * For more complete escaping, consider a library such as `shell-quote`, or use safer APIs which * don't require escaping. (Note that `spawn` from this package now uses `cross-spawn` which * escapes spaces internally.) */ function quoteSpaces(cmdArgs) { // Taken from https://github.com/xxorax/node-shell-escape/blob/master/shell-escape.js // However, we needed to use double quotes because that's the norm in more platforms if (!cmdArgs) { return cmdArgs; } return cmdArgs.map(arg => { if (/[^\w/:=-]/.test(arg)) { arg = `"${arg.replace(/"/g, '"\\"')}"`; arg = arg.replace(/^(?:"")+/g, '').replace(/\\"""/g, '\\"'); } return arg; }); } /** * Log `Running: <process.execPath> <...args>` */ function logNodeCommand(...args) { just_task_1.logger.info(`Running: ${process.execPath} ${quoteSpaces(args.flat()).join(' ')}`); } exports.logNodeCommand = logNodeCommand; /** * Execute a command in a new process. Uses `cross-spawn` to avoid issues with spaces in arguments, * but does not do any additional escaping. (For further enhancements, consider using the `execa` * library instead.) * * **WARNING: If the `shell` option is enabled, do not pass unsanitized user input to this function. * Any input containing shell metacharacters may be used to trigger arbitrary command execution.** * * @param cmd Command to execute * @param args Args for the command. Quoting spaces is handled internally by `cross-spawn`. * @param opts Normal spawn options plus stdout/stderr for piping output. (To inherit stdio from the * parent process, just use `stdio: 'inherit'` instead.) * * @returns Promise which will settle when the command completes. If the promise is rejected, the error will * include the child process's exit code (`error.code`) or signal (`error.signal`) if relevant. * The returned promise also has a `child` property with the spawned `ChildProcess` instance. * * @deprecated This function is not recommended for use outside the `just-scripts` package. * Instead, consider a more mature, purpose-specific library such as `execa` or `nano-spawn`. */ function spawn(cmd, args = [], opts = {}) { return new Promise((resolve, reject) => { var _a, _b; let child; try { child = (0, cross_spawn_1.spawn)(cmd, args, opts); } catch (error) { reject(error); return; } const onExit = (code, signal) => { child.off('error', onError); if (code) { const error = new Error('Command failed: ' + [cmd, ...args].join(' ')); error.code = code; reject(error); } else if (signal) { const error = new Error(`Command terminated by signal ${signal}: ` + [cmd, ...args].join(' ')); error.signal = signal; reject(error); } else { resolve(); } }; // Some error circumstances may fire 'error' rather than 'exit' // https://nodejs.org/docs/latest/api/child_process.html#event-error const onError = (error) => { reject(error); child.off('exit', onExit); }; child.on('exit', onExit); child.on('error', onError); if (opts.stdout) { (_a = child.stdout) === null || _a === void 0 ? void 0 : _a.pipe(opts.stdout); } if (opts.stderr) { (_b = child.stderr) === null || _b === void 0 ? void 0 : _b.pipe(opts.stderr); } }); } exports.spawn = spawn; //# sourceMappingURL=exec.js.map