extra-child-process
Version:
Useful additions to inbuilt child_process module.
352 lines (346 loc) • 12.2 kB
JavaScript
;
var os = require('os');
var C = require('child_process');
var F = require('fs');
var P = require('path');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var C__namespace = /*#__PURE__*/_interopNamespaceDefault(C);
var F__namespace = /*#__PURE__*/_interopNamespaceDefault(F);
var P__namespace = /*#__PURE__*/_interopNamespaceDefault(P);
class ExecAsyncHandler {
constructor() {
this.resolve = null;
this.reject = null;
this.callback = (err, stdout, stderr) => {
if (err != null)
this.reject(Object.assign(err, { stdout, stderr }));
else
this.resolve({ stdout, stderr });
};
this.promise = new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
}
}
function execAsync(command, options) {
var e = new ExecAsyncHandler();
var child = C__namespace.exec(command, options, e.callback);
return Object.assign(e.promise, { child });
}
function exec(...args) {
if (typeof args[args.length - 1] === "function")
C__namespace.exec.apply(null, args);
else
return execAsync.apply(null, args);
}
function execFileAsync(file, args, options) {
var e = new ExecAsyncHandler();
var _args = args instanceof Array ? args : null;
var _options = args instanceof Array ? options : args;
var child = C__namespace.execFile(file, _args, _options, e.callback);
return Object.assign(e.promise, { child });
}
function execFile(...args) {
if (typeof args[args.length - 1] === "function")
C__namespace.execFile.apply(null, args);
else
return execFileAsync.apply(null, args);
}
const MAX_BUFFER = 1024 * 1024;
class StreamBuffer {
constructor(stream, encoding = "buffer", maxBuffer = MAX_BUFFER) {
this.size = 0;
this.data = [];
this.encoding = encoding;
if (encoding && encoding !== "buffer")
stream.setEncoding(encoding);
stream.on("data", chunk => {
if (this.size + chunk.length > maxBuffer)
return;
this.data.push(chunk);
this.size += chunk.length;
});
}
value() {
if (!this.encoding || this.encoding === "buffer")
return Buffer.concat(this.data);
return this.data.join("");
}
}
function spawnAsync(command, args, options) {
var _args = args instanceof Array ? args : null;
var _options = args instanceof Array ? options : args;
var encoding = (_options === null || _options === void 0 ? void 0 : _options.encoding) || "buffer";
var maxBuffer = (_options === null || _options === void 0 ? void 0 : _options.maxBuffer) || MAX_BUFFER;
var child = C__namespace.spawn(command, _args, _options);
var outbuf = new StreamBuffer(child.stdout, encoding, maxBuffer);
var errbuf = new StreamBuffer(child.stderr, encoding, maxBuffer);
var promise = new Promise((resolve, reject) => {
child.on("error", err => {
var { pid, exitCode, signalCode } = child;
var stdout = outbuf.value();
var stderr = errbuf.value();
var output = [null, stdout, stderr];
reject(Object.assign(err, { pid, output, stdout, stderr, status: exitCode, signal: signalCode }));
});
child.on("close", (code, signal) => {
var { pid } = child;
var stdout = outbuf.value();
var stderr = errbuf.value();
var output = [null, stdout, stderr];
resolve({ pid, output, stdout, stderr, status: code, signal });
});
});
return Object.assign(promise, { child });
}
function whichWin32(dir, entries, exts, ft) {
var apath = null, afile = null;
var aprio = Number.MAX_SAFE_INTEGER;
for (var e of entries) {
if (!e.isFile())
continue;
var ext = P__namespace.extname(e.name);
var file = P__namespace.basename(e.name, ext);
if (afile != null && file !== afile)
break;
if (!ft(file))
continue;
var prio = exts.indexOf((ext || ".?").toLowerCase());
if (prio < 0 || prio >= aprio)
continue;
apath = P__namespace.join(dir, e.name);
afile = file;
aprio = prio;
}
return apath;
}
function whichAllWin32(dir, entries, exts, ft) {
var a = [];
for (var e of entries) {
if (!e.isFile())
continue;
var ext = P__namespace.extname(e.name);
var file = P__namespace.basename(e.name, ext);
if (!ft(file))
continue;
var prio = exts.indexOf((ext || ".?").toLowerCase());
if (prio >= 0)
a.push({ file, prio, path: P__namespace.join(dir, e.name) });
}
a.sort((a, b) => a.file.localeCompare(b.file) || a.prio - b.prio);
return a.map(x => x.path);
}
function whichLinuxSync(dir, entries, ft) {
for (var e of entries) {
if (!e.isFile())
continue;
if (!ft(e.name))
continue;
var path = P__namespace.join(dir, e.name);
try {
F__namespace.accessSync(path, F__namespace.constants.X_OK);
}
catch (_a) {
continue;
}
return path;
}
return null;
}
function whichAllLinuxSync(dir, entries, ft) {
var a = [];
for (var e of entries) {
if (!e.isFile())
continue;
if (!ft(e.name))
continue;
var path = P__namespace.join(dir, e.name);
try {
F__namespace.accessSync(path, F__namespace.constants.X_OK);
a.push(path);
}
catch (_a) { }
}
return a.sort();
}
function whichLinuxAsync(dir, entries, ft) {
return new Promise(resolve => {
var n = 0, paths = [];
var best = Number.MAX_SAFE_INTEGER;
for (var e of entries) {
if (!e.isFile())
continue;
if (!ft(e.name))
continue;
let i = paths.push(null) - 1;
let path = P__namespace.join(dir, e.name);
F__namespace.access(path, F__namespace.constants.X_OK, err => {
paths[i] = err ? "" : path;
--n;
if (!err)
best = Math.min(best, i);
if (best === Number.MAX_SAFE_INTEGER) {
if (n === 0)
resolve(null);
}
else if (!paths.slice(0, best).includes(null))
resolve(paths[best]);
});
++n;
}
});
}
function whichAllLinuxAsync(dir, entries, ft) {
return new Promise(resolve => {
var a = [], n = 0;
for (var e of entries) {
if (!e.isFile())
continue;
if (!ft(e.name))
continue;
let path = P__namespace.join(dir, e.name);
F__namespace.access(path, F__namespace.constants.X_OK, err => {
if (!err)
a.push(path);
if (--n === 0)
resolve(a.sort());
});
++n;
}
});
}
function whichFnSync(dirs, exts, ft) {
for (var dir of dirs) {
var entries = F__namespace.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
var path = os.EOL === "\n" ? whichLinuxSync(dir, entries, ft) : whichWin32(dir, entries, exts, ft);
if (path)
return path;
}
return null;
}
function whichAllFnSync(dirs, exts, ft) {
var a = [];
for (var dir of dirs) {
var entries = F__namespace.readdirSync(dir, { withFileTypes: true });
var paths = os.EOL === "\n" ? whichAllLinuxSync(dir, entries, ft) : whichAllWin32(dir, entries, exts, ft);
a.push(...paths);
}
return a;
}
async function whichFnAsync(dirs, exts, ft) {
var pathps = [];
for (let dir of dirs) {
var p = F__namespace.promises.readdir(dir, { withFileTypes: true }).then(entries => entries.sort((a, b) => a.name.localeCompare(b.name)));
pathps.push(p.then(entries => os.EOL === "\n" ? whichLinuxAsync(dir, entries, ft) : whichWin32(dir, entries, exts, ft)));
}
for (var pathp of pathps) {
var path = await pathp;
if (path)
return path;
}
return null;
}
async function whichAllFnAsync(dirs, exts, ft) {
var pathps = [], a = [];
for (let dir of dirs) {
var p = F__namespace.promises.readdir(dir, { withFileTypes: true });
pathps.push(p.then(entries => os.EOL === "\n" ? whichAllLinuxAsync(dir, entries, ft) : whichAllWin32(dir, entries, exts, ft)));
}
for (var pathp of pathps)
a.push(...(await pathp));
return a;
}
function whichDirs(options) {
var sep = os.EOL === "\n" ? ":" : ";";
var dirs = (options === null || options === void 0 ? void 0 : options.paths) || process.env.PATH.split(sep);
return os.EOL !== "\n" && (options === null || options === void 0 ? void 0 : options.cwd) ? new Set([options.cwd, ...dirs]) : new Set(dirs);
}
function whichExts(options) {
return (options === null || options === void 0 ? void 0 : options.extnames) || (process.env.PATHEXT || "").toLowerCase().split(";");
}
function whichTestFunction(cmd) {
if (typeof cmd === "function")
return cmd;
if (typeof cmd === "string")
return file => file === cmd;
return file => cmd.test(file);
}
function whichSync(cmd, options) {
return whichFnSync(whichDirs(options), whichExts(options), whichTestFunction(cmd));
}
function whichAllSync(cmd, options) {
return whichAllFnSync(whichDirs(options), whichExts(options), whichTestFunction(cmd));
}
function whichAsync(cmd, options) {
return whichFnAsync(whichDirs(options), whichExts(options), whichTestFunction(cmd));
}
function whichAllAsync(cmd, options) {
return whichAllFnAsync(whichDirs(options), whichExts(options), whichTestFunction(cmd));
}
function which(cmd, options, callback) {
if (typeof callback === "function")
whichAsync(cmd, options).then(bin => callback(null, bin), callback);
else if (typeof options === "function")
whichAsync(cmd).then(bin => options(null, bin), options);
else
return whichAsync(cmd, options);
}
function whichAll(cmd, options, callback) {
if (typeof callback === "function")
whichAllAsync(cmd, options).then(bin => callback(null, bin), callback);
else if (typeof options === "function")
whichAllAsync(cmd).then(bin => options(null, bin), options);
else
return whichAllAsync(cmd, options);
}
Object.defineProperty(exports, 'ChildProcess', {
enumerable: true,
get: function () { return C.ChildProcess; }
});
Object.defineProperty(exports, 'execFileSync', {
enumerable: true,
get: function () { return C.execFileSync; }
});
Object.defineProperty(exports, 'execSync', {
enumerable: true,
get: function () { return C.execSync; }
});
Object.defineProperty(exports, 'fork', {
enumerable: true,
get: function () { return C.fork; }
});
Object.defineProperty(exports, 'spawn', {
enumerable: true,
get: function () { return C.spawn; }
});
Object.defineProperty(exports, 'spawnSync', {
enumerable: true,
get: function () { return C.spawnSync; }
});
exports.exec = exec;
exports.execAsync = execAsync;
exports.execFile = execFile;
exports.execFileAsync = execFileAsync;
exports.spawnAsync = spawnAsync;
exports.which = which;
exports.whichAll = whichAll;
exports.whichAllAsync = whichAllAsync;
exports.whichAllSync = whichAllSync;
exports.whichAsync = whichAsync;
exports.whichSync = whichSync;