UNPKG

@beenotung/tslib

Version:
99 lines (98 loc) 2.88 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SpawnError = exports.exec = void 0; exports.spawn = spawn; exports.spawnAndWait = spawnAndWait; const tslib_1 = require("tslib"); const child_process_1 = require("child_process"); const util = tslib_1.__importStar(require("util")); exports.exec = util.promisify(child_process_1.exec); class SpawnError extends Error { stdout; stderr; processError; code; constructor(stdout, stderr) { super(); this.stdout = stdout; this.stderr = stderr; } } exports.SpawnError = SpawnError; /** * Won't throw error, the error handling should be done in callback and if-throw style. * Use spawnAndWait if you want error handling in try-catch style. */ async function spawn(options) { let { cmd, args } = options; if (!args) { args = cmd.split(' '); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion cmd = args.shift(); } const code = await new Promise(resolve => { const child = (0, child_process_1.spawn)(cmd, args, options.options); child.stdout.setEncoding('utf8'); child.stdout.on('data', data => { if (options.on_stdout) { options.on_stdout(data); } else { process.stdout.write(data.toString()); } }); child.stderr.setEncoding('utf8'); child.stderr.on('data', data => { if (options.on_stderr) { options.on_stderr(data); } else { process.stderr.write(data.toString()); } }); child.on('error', err => { if (options.on_error) { options.on_error(err); } else { console.error(err); } resolve(null); }); child.on('close', code => { resolve(code); }); }); return code; } /** * spawn a child process and return the stdout and stderr in promise * * the console is not used to output the stdout and stderr * * the error stack is preserved (avoided lost in native event loop) */ async function spawnAndWait(options) { let stdout = ''; let stderr = ''; let error = null; const code = await spawn({ cmd: options.cmd, args: options.args, options: options.options, on_stdout: chunk => (stdout += chunk), on_stderr: chunk => (stderr += chunk), on_error: err => (error = err), }); if (error || code) { const spawnError = new SpawnError(stdout, stderr); if (error) { spawnError.processError = error; } if (code) { spawnError.code = code; } throw spawnError; } return { code, stdout, stderr }; }