UNPKG

kaven-utils

Version:

Utils for Node.js.

127 lines (126 loc) 5.5 kB
/******************************************************************** * @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); } }); }