kaven-utils
Version:
Utils for Node.js.
127 lines (126 loc) • 5.5 kB
JavaScript
/********************************************************************
* @author: Kaven
* @email: kaven@wuwenkai.com
* @website: http://blog.kaven.xyz
* @file: [Kaven-Utils] /src/KavenUtility.ChildProcess.ts
* @create: 2023-11-25 22:29:30.048
* @modify: 2024-11-01 17:02:27.206
* @version: 5.4.5
* @times: 30
* @lines: 153
* @copyright: Copyright © 2023-2024 Kaven. All Rights Reserved.
* @description: [description]
* @license: [license]
********************************************************************/
import pkgIconvLite from "iconv-lite";
import { exec, spawn } from "node:child_process";
import { InternalLogger } from "./KavenUtility.Internal.js";
export async function Execute(p1, p2) {
const decodeStream = pkgIconvLite.decodeStream;
return new Promise((resolve, reject) => {
try {
let command = typeof p1 === "string" ? p1 : p1.command;
const options = typeof p1 === "string" ? (p2 ?? {}) : (p1.options ?? {});
if (options.trace) {
options.stdout ??= process.stdout;
options.stderr ??= process.stderr;
InternalLogger()?.Info(`Execute: ${command}`);
}
if (options.spawn) {
if (options.spawnArgs === undefined) {
// command = command.trim();
// if (command.startsWith(Strings_DoubleQuotes)) {
// const index = command.indexOf(Strings_DoubleQuotes, 1);
// if (index > 0) {
// command = command.substring(0, index);
// options.spawnArgs = command.substring(index + 1).trim().split(Strings_WhiteSpace);
// }
// } else if (command.startsWith("'")) {
// const index = command.indexOf("'", 1);
// if (index > 0) {
// command = command.substring(0, index);
// options.spawnArgs = command.substring(index + 1).trim().split(Strings_WhiteSpace);
// }
// } else {
// [command, ...options.spawnArgs] = command.trim().split(Strings_WhiteSpace);
// }
command = command.trim();
// Regular expression to match quoted or unquoted parts
const regex = /(?:[^\s'"]+|"[^"]*"|'[^']*')+/g;
// Extract the matched parts
const parts = command.match(regex) || [];
// The first part is the command
command = parts.shift() ?? command;
// The remaining parts are the arguments
options.spawnArgs = parts.map(arg => arg.replace(/^(['"])(.*)\1$/, "$2"));
}
const p = spawn(command, options.spawnArgs, options.spawnOptions);
p.on("close", code => {
if (code !== 0) {
if (!options.resolveNonZeroExitCodes) {
reject(code);
return;
}
}
resolve(code);
});
p.on("error", data => {
InternalLogger()?.Error(data);
});
if (options.decoderEncoding) {
if (options.stdout) {
p.stdout.pipe(decodeStream(options.decoderEncoding)).pipe(options.stdout);
}
if (options.stderr) {
p.stderr.pipe(decodeStream(options.decoderEncoding)).pipe(options.stderr);
}
}
else {
if (options.stdout) {
p.stdout.pipe(options.stdout);
}
if (options.stderr) {
p.stderr.pipe(options.stderr);
}
}
}
else {
const p = exec(command, {
encoding: "buffer",
...options.execOptions,
});
p.once("close", code => {
if (code !== 0) {
if (!options.resolveNonZeroExitCodes) {
reject(code);
return;
}
}
resolve(code);
});
p.on("error", data => {
InternalLogger()?.Error(data);
});
if (options.stdout && p.stdout) {
if (options.decoderEncoding) {
p.stdout.pipe(decodeStream(options.decoderEncoding)).pipe(options.stdout);
}
else {
p.stdout.pipe(options.stdout);
}
}
if (options.stderr && p.stderr) {
if (options.decoderEncoding) {
p.stderr.pipe(decodeStream(options.decoderEncoding)).pipe(options.stderr);
}
else {
p.stderr.pipe(options.stderr);
}
}
}
}
catch (ex) {
reject(ex);
}
});
}