@rzl-zone/build-tools 0.0.10 → 0.0.12-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/dist/.references/index.d.cts +1 -1
  2. package/dist/.references/index.d.ts +1 -1
  3. package/dist/bundler/rolldown.cjs +4 -4
  4. package/dist/bundler/rolldown.cjs.map +1 -1
  5. package/dist/bundler/rolldown.d.cts +2 -2
  6. package/dist/bundler/rolldown.d.ts +2 -2
  7. package/dist/bundler/rolldown.js +1 -1
  8. package/dist/bundler/rolldown.js.map +1 -1
  9. package/dist/bundler/tsdown.cjs +9 -9
  10. package/dist/bundler/tsdown.cjs.map +1 -1
  11. package/dist/bundler/tsdown.d.cts +2 -2
  12. package/dist/bundler/tsdown.d.ts +2 -2
  13. package/dist/bundler/tsdown.js +3 -3
  14. package/dist/bundler/tsdown.js.map +1 -1
  15. package/dist/bundler/utils.cjs +2 -2
  16. package/dist/bundler/utils.cjs.map +1 -1
  17. package/dist/bundler/utils.d.cts +2 -2
  18. package/dist/bundler/utils.d.ts +2 -2
  19. package/dist/bundler/utils.js +2 -2
  20. package/dist/bundler/utils.js.map +1 -1
  21. package/dist/client-E8kISMNO.cjs +81 -0
  22. package/dist/client-E8kISMNO.cjs.map +1 -0
  23. package/dist/client-MFOxk6MV.js +75 -0
  24. package/dist/client-MFOxk6MV.js.map +1 -0
  25. package/dist/commander-kit/index.cjs +84 -65
  26. package/dist/commander-kit/index.cjs.map +1 -1
  27. package/dist/commander-kit/index.d.cts +3 -3
  28. package/dist/commander-kit/index.d.ts +3 -3
  29. package/dist/commander-kit/index.js +24 -5
  30. package/dist/commander-kit/index.js.map +1 -1
  31. package/dist/{extra-CYpD3D9p.d.ts → extra-B1CzOGop.d.ts} +2 -2
  32. package/dist/{extra-Dc_eIyiW.d.cts → extra-DJwL1pB2.d.cts} +2 -2
  33. package/dist/{fast-globe-options-CZ-9wIKV.d.ts → fast-globe-options-DDloBj5e.d.ts} +3 -3
  34. package/dist/{fast-globe-options-BtIrCNb6.d.cts → fast-globe-options-Rz3TI5hc.d.cts} +3 -3
  35. package/dist/{helper-CWU8QYq3.js → formatter-BS3omf7k.js} +88 -3
  36. package/dist/formatter-BS3omf7k.js.map +1 -0
  37. package/dist/{helper-DvCvgDxy.cjs → formatter-Cbz6g0Mi.cjs} +142 -14
  38. package/dist/formatter-Cbz6g0Mi.cjs.map +1 -0
  39. package/dist/{identity-xuDCNgfm.js → identity-Cznri5bj.js} +5 -6
  40. package/dist/{identity-xuDCNgfm.js.map → identity-Cznri5bj.js.map} +1 -1
  41. package/dist/{identity-D192lL-_.cjs → identity-D2BhaOq4.cjs} +14 -15
  42. package/dist/{identity-D192lL-_.cjs.map → identity-D2BhaOq4.cjs.map} +1 -1
  43. package/dist/{index-1FKLQ7ah.d.cts → index-BW05_5Zw.d.ts} +2 -2
  44. package/dist/{index-qft-a5kh.d.ts → index-C5uH9Zib.d.cts} +2 -2
  45. package/dist/{index-CEsO_rxz.d.ts → index-D5tuL_Tf.d.cts} +2 -2
  46. package/dist/{index-DW1JFluR.d.cts → index-DMYmm0in.d.ts} +2 -2
  47. package/dist/index.cjs +378 -359
  48. package/dist/index.cjs.map +1 -1
  49. package/dist/index.d.cts +81 -48
  50. package/dist/index.d.ts +81 -48
  51. package/dist/index.js +175 -156
  52. package/dist/index.js.map +1 -1
  53. package/dist/package-banner-Com8U-Xm.cjs +59 -0
  54. package/dist/{package-banner-BHyF8RdG.cjs.map → package-banner-Com8U-Xm.cjs.map} +1 -1
  55. package/dist/{package-banner-BmLNyezO.js → package-banner-Jw1DuF8v.js} +4 -5
  56. package/dist/{package-banner-BmLNyezO.js.map → package-banner-Jw1DuF8v.js.map} +1 -1
  57. package/dist/server-Bewzn3sy.cjs +255 -0
  58. package/dist/server-Bewzn3sy.cjs.map +1 -0
  59. package/dist/server-Owi9-DW1.js +198 -0
  60. package/dist/server-Owi9-DW1.js.map +1 -0
  61. package/dist/utils/client.cjs +12 -11
  62. package/dist/utils/client.d.cts +1 -1
  63. package/dist/utils/client.d.ts +1 -1
  64. package/dist/utils/client.js +3 -2
  65. package/dist/utils/server.cjs +5 -2
  66. package/dist/utils/server.d.cts +433 -3
  67. package/dist/utils/server.d.ts +433 -3
  68. package/dist/utils/server.js +3 -3
  69. package/package.json +10 -6
  70. package/dist/client-BmfdVI22.js +0 -160
  71. package/dist/client-BmfdVI22.js.map +0 -1
  72. package/dist/client-DnTjQyyo.cjs +0 -221
  73. package/dist/client-DnTjQyyo.cjs.map +0 -1
  74. package/dist/helper-CWU8QYq3.js.map +0 -1
  75. package/dist/helper-DvCvgDxy.cjs.map +0 -1
  76. package/dist/package-banner-BHyF8RdG.cjs +0 -60
  77. package/dist/server-BA7ruG1h.js +0 -142
  78. package/dist/server-BA7ruG1h.js.map +0 -1
  79. package/dist/server-DZvrqlyy.cjs +0 -181
  80. package/dist/server-DZvrqlyy.cjs.map +0 -1
package/dist/index.js CHANGED
@@ -2,22 +2,22 @@
2
2
  * ========================================================================
3
3
  * @rzl-zone/build-tools
4
4
  * ------------------------------------------------------------------------
5
- * Version: `0.0.10`
5
+ * Version: `0.0.12-beta.0`
6
6
  * Author: `Rizalvin Dwiky <rizalvindwiky1998@gmail.com>`
7
7
  * Repository: `https://github.com/rzl-zone/rzl-zone/tree/main/packages/build-tools`
8
8
  * ========================================================================
9
9
  */
10
10
 
11
- import { S as toStringSet, _ as isUndefined, a as isError, d as isNumber, g as isString, h as isSet, i as isBoolean, l as isNonEmptyString, m as isRegExp, n as flattenStrings, p as isPlainObject, r as isArray, v as normalizeSpaces, x as toObjectSet, y as safeStableStringify } from "./helper-CWU8QYq3.js";
12
- import { a as resolvePatternOptions, i as defaultPatternOptions, n as fsExtra, o as sourceOfPatternOptions, r as ICONS, t as fastGlob } from "./server-BA7ruG1h.js";
13
- import { t as CommandIdentity } from "./identity-xuDCNgfm.js";
14
- import { a as joinInline, i as formatOptionValue, l as picocolors, n as EOL, o as joinLines, s as joinLinesLoose, u as plural } from "./client-BmfdVI22.js";
15
- import { n as getPackageJson, t as generatePackageBanner } from "./package-banner-BmLNyezO.js";
11
+ import { C as isString, E as safeStableStringify, O as toObjectSet, S as isSet, _ as isNonEmptyString, b as isPlainObject, c as picocolors, d as flattenStrings, f as isArray, i as joinInline, k as toStringSet, l as plural, o as joinLinesLoose, p as isBoolean, r as formatOptionValue, t as EOL, w as isUndefined, x as isRegExp, y as isNumber } from "./formatter-BS3omf7k.js";
12
+ import { c as resolvePatternOptions, i as sourceOf, l as sourceOfPatternOptions, n as fsExtra, r as BUILD_LOGGER, s as defaultPatternOptions, t as fastGlob } from "./server-Owi9-DW1.js";
13
+ import { t as CommandIdentity } from "./identity-Cznri5bj.js";
14
+ import { n as getPackageJson, t as generatePackageBanner } from "./package-banner-Jw1DuF8v.js";
16
15
  import "@rzl-zone/node-only";
17
16
  import * as t from "@babel/types";
18
17
  import { parse } from "@babel/parser";
19
18
  import traverseImport from "@babel/traverse";
20
19
  import path from "node:path";
20
+ import { parse as parse$2 } from "shell-quote";
21
21
  import { ChildProcess, spawn } from "node:child_process";
22
22
  import * as acorn from "acorn";
23
23
  function isLogLevel(value) {
@@ -186,58 +186,6 @@ function stripUseStrict(content, { trimStart = true, trimEnd = false } = {}) {
186
186
  if (trimEnd) result.trimEnd();
187
187
  return result;
188
188
  }
189
- const sourceOf = (value, defaultValue) => {
190
- return Object.is(value, defaultValue) ? "default" : "overridden";
191
- };
192
- const BUILD_LOGGER = {
193
- SOURCE_OF: sourceOf,
194
- OPTIONS(label, value, source, isRequired) {
195
- const sourceLabel = !isRequired && source ? source === "default" ? picocolors.blueBright(` (${source})`) : picocolors.yellowBright(` (${source})`) : "";
196
- console.log(picocolors.dim(" - ") + normalizeSpaces(picocolors.bold(label || "`⚠️ Label Unset!!!`") + picocolors.dim(": ") + formatOptionValue(value) + picocolors.italic(sourceLabel)));
197
- },
198
- SECTION(title, options = {}) {
199
- const { icon = ICONS.config, indent = "" } = options;
200
- console.log(picocolors.bold(`${indent}${picocolors.whiteBright(icon)} ${picocolors.underline(picocolors.cyanBright(title || "`⚠️ Unset Title!!!`"))}:`));
201
- },
202
- NEW_LINE(value = "") {
203
- return console.log(value);
204
- },
205
- ON_STARTING: (options) => {
206
- const { actionName, textDirectAction = "to" } = options;
207
- console.log(picocolors.bold(`${picocolors.whiteBright(ICONS.start)} ${picocolors.cyanBright("Starting")} ${normalizeSpaces(`${textDirectAction} ${picocolors.underline(picocolors.blueBright(actionName))}`)}.`));
208
- },
209
- ON_FINISH: (options) => {
210
- const { actionName, count, typeCount = "file", progress, textSuccess = "Success" } = options;
211
- console.log(picocolors.bold(`${picocolors.greenBright(ICONS.success)} ${picocolors.greenBright(textSuccess)} ${normalizeSpaces(`${picocolors.underline(picocolors.blueBright(actionName))} (${picocolors.yellowBright(`${isNonEmptyString(progress) ? progress : count} ${typeCount}${count > 1 ? "(s)" : ""}`)}`)}).`));
212
- },
213
- ON_SKIPPING: (options) => {
214
- const { actionName, reasonEndText, reasonSkipAction = "nothing left", reasonTitle = "because", reasonType = "files", textDirectAction = "to" } = options;
215
- console.log(picocolors.bold(`${picocolors.yellowBright(ICONS.warn)} ${picocolors.yellowBright("Skipping")} ${normalizeSpaces(`${picocolors.underline(picocolors.blueBright(actionName))} ${picocolors.white(reasonTitle)} ${picocolors.redBright(reasonSkipAction)} ${reasonType} ${textDirectAction} ${picocolors.redBright(reasonEndText)}`)}.`));
216
- },
217
- ON_ERROR: (options) => {
218
- const { actionName, textDirectAction = "to", error } = options;
219
- const errorMsg = isError(error) ? error.message : "Something went wrong";
220
- console.error(picocolors.bold(`${picocolors.redBright(ICONS.error)} ${picocolors.redBright("Error")} ${normalizeSpaces(`${textDirectAction} ${picocolors.underline(picocolors.blueBright(actionName))},`)} ${joinLines("because: ", "", ` ${picocolors.bold(picocolors.red(ICONS.arrowRight))} ${picocolors.inverse(picocolors.red(normalizeSpaces(errorMsg)))}`)}`));
221
- },
222
- ON_PROCESS: (options) => {
223
- const { actionName, count, nameDirect, textDirectFolder = "in" } = options;
224
- console.log(`${picocolors.bold(" " + picocolors.whiteBright(ICONS.bullet))} ${picocolors.italic(`${picocolors.white(count + ".")} ${normalizeSpaces(`${picocolors.white(actionName)} ${picocolors.magentaBright(textDirectFolder)} ${picocolors.bold(picocolors.underline(picocolors.blue(nameDirect)))}.`)}`)}`);
225
- },
226
- ON_PROCESS_COPY: (options) => {
227
- const { actionName, count, copyTo, copyFrom, textFrom = "from", textArrow = "➔" } = options;
228
- console.log(`${picocolors.bold(" " + picocolors.whiteBright(ICONS.bullet))} ${picocolors.italic(`${picocolors.white(count + ".")} ${normalizeSpaces(`${picocolors.white(actionName)} ${picocolors.yellow(textFrom)} '${picocolors.bold(picocolors.underline(picocolors.cyanBright(copyFrom)))}' ${picocolors.bold(picocolors.gray(textArrow))} '${picocolors.bold(picocolors.underline(picocolors.cyanBright(copyTo)))}'.`)}`)}`);
229
- },
230
- ON_PROCESS_COPY_ERROR: (options) => {
231
- const { actionName, count, errorReason, copyFrom, index, indexKey, textFrom = "from", textReason = "because" } = options;
232
- const errorReasonText = isError(errorReason) ? errorReason.message : String(errorReason);
233
- const atIndexText = isNumber(index) ? picocolors.blueBright(` (at${isNonEmptyString(indexKey) ? ` '${indexKey}' ` : " "}index: ${picocolors.magentaBright(index)}) `) : " ";
234
- console.log(`${picocolors.bold(" " + picocolors.whiteBright(ICONS.bullet))} ${picocolors.italic(`${picocolors.white(count + ".")} ${normalizeSpaces(`${picocolors.redBright(actionName)} ${picocolors.yellow(textFrom)} '${picocolors.bold(picocolors.underline(picocolors.cyanBright(copyFrom)))}'${atIndexText}${picocolors.bold(picocolors.gray(textReason))} ${picocolors.redBright(errorReasonText)}.`)}`)}`);
235
- },
236
- ON_PROCESS_REFERENCING: (options) => {
237
- const { actionName, count, referenceTo, referenceFrom, textFrom = "from", textArrow = "➔" } = options;
238
- console.log(`${picocolors.bold(" " + picocolors.whiteBright(ICONS.bullet))} ${picocolors.italic(`${picocolors.white(count + ".")} ${normalizeSpaces(`${picocolors.white(actionName)} ${picocolors.magentaBright(textFrom)} ${picocolors.bold(picocolors.underline(picocolors.cyanBright(referenceFrom)))} ${picocolors.bold(picocolors.gray(textArrow))} ${picocolors.bold(picocolors.underline(picocolors.blueBright(referenceTo)))}.`)}`)}`);
239
- }
240
- };
241
189
  function stripLineArtifacts(line, options) {
242
190
  let out = line.replace(/^[ \t]*\/\/\s*(?:\.\.\/|\.\/)*[^ \n]*?(?:src|node_modules)\/[^\n]*\n?/gm, "").replace(/\/\/\s*eslint[^\n]*/g, "");
243
191
  if (options.removeSourceMap) out = out.replace(/^[ \t]*\/\/[#@]\s*sourceMappingURL\s*=\s*\S+/gm, "");
@@ -1155,31 +1103,44 @@ const normalizeJsBuildNewlines = async (pattern, options = {}) => {
1155
1103
  }
1156
1104
  };
1157
1105
  function runCommand(command, argsOrOptions = [], maybeOptions = {}) {
1158
- assertValidCommand(command);
1159
- let args;
1160
- let options;
1161
- if (Array.isArray(argsOrOptions)) {
1162
- args = argsOrOptions;
1163
- options = maybeOptions;
1164
- } else {
1165
- args = [];
1166
- options = argsOrOptions;
1167
- }
1168
1106
  return new Promise((resolve, reject) => {
1169
- const { shell = true, stdio = "inherit", argv0: _argv0, useColors = true, ...restOption } = options;
1170
- const { child, setupLifecycle, cmdStringPlain } = spawnWithLifecycle(command, args, {
1171
- ...restOption,
1172
- stdio,
1173
- useColors,
1174
- shell
1175
- }, { rejectOnNonZero: true });
1176
- setupLifecycle({
1177
- onSuccess: (code) => {
1178
- if (code === 0) resolve(child);
1179
- else reject(/* @__PURE__ */ new Error(`${cmdStringPlain} exited with code ${code}`));
1180
- },
1181
- onError: reject
1182
- });
1107
+ try {
1108
+ let args;
1109
+ let options;
1110
+ const isArgsArray = isArray(argsOrOptions);
1111
+ if (isArgsArray) {
1112
+ args = argsOrOptions;
1113
+ options = maybeOptions;
1114
+ } else {
1115
+ args = [];
1116
+ options = argsOrOptions;
1117
+ }
1118
+ assertValidCommand(command, {
1119
+ apiType: "runCommand",
1120
+ useColors: options.useColors,
1121
+ allowInline: !isArgsArray
1122
+ });
1123
+ const { shell = true, stdio = "inherit", argv0: _argv0, useColors = true, ...restOption } = options;
1124
+ const { child, setupLifecycle, cmdStringPlain } = spawnWithLifecycle(command, args, {
1125
+ ...restOption,
1126
+ stdio,
1127
+ useColors,
1128
+ shell
1129
+ }, { rejectOnNonZero: true });
1130
+ setupLifecycle({
1131
+ onSuccess: (code) => {
1132
+ if (code === 0) resolve(child);
1133
+ else reject(/* @__PURE__ */ new Error(`${cmdStringPlain} exited with code ${code}`));
1134
+ },
1135
+ onError: reject
1136
+ });
1137
+ } catch (err) {
1138
+ const e = err instanceof Error ? err : new Error(String(err));
1139
+ const cleanedBase = stripInternalStack(((/* @__PURE__ */ new Error()).stack?.split(EOL).slice(1) ?? []).filter((line) => !line.includes("runCommand")));
1140
+ e.stack = [e.message, ...cleanedBase].join(EOL);
1141
+ reject(e);
1142
+ return;
1143
+ }
1183
1144
  });
1184
1145
  }
1185
1146
  function normalizeChunk(chunk) {
@@ -1188,74 +1149,89 @@ function normalizeChunk(chunk) {
1188
1149
  return String(chunk);
1189
1150
  }
1190
1151
  function runCommandCapture(command, argsOrOptions = [], maybeOptions = {}) {
1191
- assertValidCommand(command);
1192
- let args;
1193
- let options;
1194
- if (Array.isArray(argsOrOptions)) {
1195
- args = argsOrOptions;
1196
- options = maybeOptions;
1197
- } else {
1198
- args = [];
1199
- options = argsOrOptions;
1200
- }
1201
- const { shell = true, signal, timeout, forceKill, useColors = true, argv0: _argv0, ...restOption } = options;
1202
1152
  return new Promise((resolve, reject) => {
1203
- const { child, setupLifecycle } = spawnWithLifecycle(command, args, {
1204
- ...restOption,
1205
- stdio: "pipe",
1206
- shell,
1207
- signal,
1208
- timeout,
1209
- forceKill,
1210
- useColors
1211
- }, { rejectOnNonZero: false });
1212
- let stdout = "";
1213
- let stderr = "";
1214
- child.stdout?.on("data", (chunk) => {
1215
- stdout += normalizeChunk(chunk);
1216
- });
1217
- child.stderr?.on("data", (chunk) => {
1218
- stderr += normalizeChunk(chunk);
1219
- });
1220
- setupLifecycle({
1221
- onSuccess: (code) => {
1222
- resolve({
1223
- stdout: stdout.trimEnd(),
1224
- stderr: stderr.trimEnd(),
1225
- exitCode: code,
1226
- ok: code === 0
1227
- });
1228
- },
1229
- onError: reject
1230
- });
1153
+ try {
1154
+ let args;
1155
+ let options;
1156
+ const isArgsArray = isArray(argsOrOptions);
1157
+ if (isArgsArray) {
1158
+ args = argsOrOptions;
1159
+ options = maybeOptions;
1160
+ } else {
1161
+ args = [];
1162
+ options = argsOrOptions;
1163
+ }
1164
+ assertValidCommand(command, {
1165
+ apiType: "runCommandCapture",
1166
+ useColors: options.useColors,
1167
+ allowInline: !isArgsArray
1168
+ });
1169
+ const { shell = true, signal, timeout, forceKill, useColors = true, argv0: _argv0, ...restOption } = options;
1170
+ const { child, setupLifecycle } = spawnWithLifecycle(command, args, {
1171
+ ...restOption,
1172
+ stdio: "pipe",
1173
+ shell,
1174
+ signal,
1175
+ timeout,
1176
+ forceKill,
1177
+ useColors
1178
+ }, { rejectOnNonZero: false });
1179
+ let stdout = "";
1180
+ let stderr = "";
1181
+ child.stdout?.on("data", (chunk) => {
1182
+ stdout += normalizeChunk(chunk);
1183
+ });
1184
+ child.stderr?.on("data", (chunk) => {
1185
+ stderr += normalizeChunk(chunk);
1186
+ });
1187
+ setupLifecycle({
1188
+ onSuccess: (code) => {
1189
+ resolve({
1190
+ stdout: stdout.trimEnd(),
1191
+ stderr: formatMessageColor(stderr.trimEnd(), useColors),
1192
+ exitCode: code,
1193
+ ok: code === 0
1194
+ });
1195
+ },
1196
+ onError: reject
1197
+ });
1198
+ } catch (err) {
1199
+ const e = err instanceof Error ? err : new Error(String(err));
1200
+ const cleanedBase = stripInternalStack(((/* @__PURE__ */ new Error()).stack?.split(EOL).slice(1) ?? []).filter((line) => !line.includes("runCommandCapture")));
1201
+ e.stack = [e.message, ...cleanedBase].join(EOL);
1202
+ reject(e);
1203
+ return;
1204
+ }
1231
1205
  });
1232
1206
  }
1207
+ const formatMessageColor = (message, useColors = true) => {
1208
+ return useColors ? picocolors.redBright(message) : message;
1209
+ };
1233
1210
  function formatCommand(command, args, { useColors = true } = {}) {
1234
1211
  const hasArgs = args.length > 0;
1235
1212
  const argsString = hasArgs ? args.map((a) => safeStableStringify(a)).join(" ") : "";
1236
- if (useColors) {
1237
- const cmd = picocolors.cyanBright(command);
1238
- return hasArgs ? `${cmd} ${picocolors.gray(argsString)}` : cmd;
1239
- }
1240
- return hasArgs ? `${command} ${argsString}` : command;
1213
+ if (!hasArgs) return formatMessageColor(command, useColors);
1214
+ if (useColors) return `${picocolors.cyanBright(command)} ${picocolors.gray(argsString)}`;
1215
+ return `${command} ${argsString}`;
1241
1216
  }
1242
- function assertValidCommand(command, { useColors = true } = {}) {
1243
- if (typeof command !== "string") {
1217
+ function assertValidCommand(command, options) {
1218
+ const { useColors = true, allowInline = false, apiType } = options || {};
1219
+ if (!isString(command)) {
1244
1220
  const errorMsg = `Invalid command: expected a string, received ${safeStableStringify(command)}`;
1245
- throw new TypeError(useColors ? picocolors.redBright(errorMsg) : errorMsg);
1221
+ throw new TypeError(formatMessageColor(errorMsg, useColors));
1246
1222
  }
1247
1223
  const trimmed = command.trim();
1248
- if (trimmed.length === 0) {
1249
- const errorMsg = "Invalid command: command cannot be empty";
1250
- throw new Error(useColors ? picocolors.redBright(errorMsg) : errorMsg);
1224
+ if (trimmed.length === 0) throw new Error(formatMessageColor("Invalid command: command cannot be empty", useColors));
1225
+ const hasSpace = /\s/.test(trimmed);
1226
+ if (hasShellSyntax(trimmed)) {
1227
+ const errorMsg = joinLinesLoose(`Invalid command: "${trimmed}"`, "Shell operators are not supported in this context (e.g. &&, ||, |, >).", "This utility only supports a single command with arguments.");
1228
+ throw new Error(formatMessageColor(errorMsg, useColors));
1251
1229
  }
1252
- const hasSpace = trimmed.includes(" ");
1253
- const hasQuotes = /['"`]/.test(trimmed);
1254
- const hasShellOps = /[|&;<>(){}$]/.test(trimmed);
1255
- if (hasSpace || hasQuotes || hasShellOps) {
1230
+ if (!allowInline && hasSpace) {
1256
1231
  const [cmd, ...rest] = trimmed.split(/\s+/);
1257
- const errorMsg = joinLinesLoose(`Invalid command: "${trimmed}"`, "Do not pass a full shell command.", `Use arguments instead: runCommand("${cmd}", ${safeStableStringify(rest)})`);
1258
- throw new Error(useColors ? picocolors.redBright(errorMsg) : errorMsg);
1232
+ if (!cmd) throw new Error("Invalid command: unable to resolve executable.");
1233
+ const errorMsg = joinLinesLoose(`Invalid command: "${trimmed}"`, "Do not include arguments in the command when passing them separately.", `Use: ${apiType}("${cmd}", ${safeStableStringify(rest)})`);
1234
+ throw new Error(formatMessageColor(errorMsg, useColors));
1259
1235
  }
1260
1236
  }
1261
1237
  function stripInternalStack(lines) {
@@ -1267,8 +1243,10 @@ function stripInternalStack(lines) {
1267
1243
  "createProcessError",
1268
1244
  "formatError",
1269
1245
  "spawnWithLifecycle",
1246
+ "assertValidCommand",
1270
1247
  "setupLifecycle",
1271
- "node:internal"
1248
+ "node:internal",
1249
+ "node:internal/process/promises"
1272
1250
  ];
1273
1251
  return lines.filter((line) => {
1274
1252
  if (blacklist.some((key) => line.includes(key))) return false;
@@ -1335,29 +1313,70 @@ var CommandProcessError = class extends Error {
1335
1313
  function isCommandProcessError(err) {
1336
1314
  return err instanceof CommandProcessError;
1337
1315
  }
1316
+ function hasShellSyntax(str) {
1317
+ return /(\|\||&&|[|&;<>\n])/.test(str);
1318
+ }
1319
+ function resolveCommand(input, useColors = true) {
1320
+ const tokens = parse$2(input);
1321
+ const normalized = [];
1322
+ for (const t of tokens) {
1323
+ if (typeof t === "string") {
1324
+ normalized.push(t);
1325
+ continue;
1326
+ }
1327
+ if ("comment" in t) continue;
1328
+ if ("pattern" in t) {
1329
+ normalized.push(t.pattern);
1330
+ continue;
1331
+ }
1332
+ if ("op" in t) throw new Error(formatMessageColor("Unsupported shell operator detected.", useColors));
1333
+ throw new Error(formatMessageColor("Unknown token in command.", useColors));
1334
+ }
1335
+ if (normalized.length === 0) throw new Error(formatMessageColor("Invalid command: empty after parsing.", useColors));
1336
+ const [cmd, ...args] = normalized;
1337
+ if (!cmd) throw new Error(formatMessageColor("Invalid command: empty after parsing.", useColors));
1338
+ return {
1339
+ command: cmd,
1340
+ args
1341
+ };
1342
+ }
1338
1343
  function spawnWithLifecycle(command, args, options, config) {
1339
- const { useColors = true, timeout, forceKill, signal: abortSignal, ...restOption } = options;
1344
+ const { useColors = true, timeout, forceKill, signal: abortSignal, shell = false, ...restOption } = options;
1345
+ let cmd = command;
1346
+ let finalArgs = [...args];
1347
+ const isInline = finalArgs.length === 0 && /\s/.test(cmd);
1340
1348
  const baseStack = (/* @__PURE__ */ new Error()).stack;
1341
- const cmdString = formatCommand(command, args, { useColors });
1342
- const cmdStringPlain = formatCommand(command, args, { useColors: false });
1343
1349
  const formatError = config?.formatError ?? ((msg, meta) => {
1344
1350
  const metaCommand = meta.command.trim();
1345
- const argsString = meta.args.length > 0 ? meta.args.map((a) => safeStableStringify(a).trim()).join(" ") : "";
1351
+ const hasArgs = meta.args.length > 0;
1352
+ const argsString = hasArgs ? meta.args.map((a) => safeStableStringify(a).trim()).join(" ") : "";
1353
+ const commandString = hasArgs ? `${metaCommand} ${argsString}` : metaCommand;
1346
1354
  if (meta.useColors) {
1347
1355
  const cmd = picocolors.magentaBright(metaCommand);
1348
- const args = argsString ? picocolors.yellowBright(argsString) : "";
1356
+ const args = hasArgs ? picocolors.yellowBright(argsString) : "";
1349
1357
  return createProcessError(`${cmd}${args ? " " + args : ""} ${picocolors.redBright(msg)}`, {
1350
1358
  ...meta,
1351
- command: `${metaCommand} ${argsString}`
1359
+ command: commandString
1352
1360
  }, baseStack);
1353
1361
  }
1354
- return createProcessError(`${metaCommand}${isNonEmptyString(argsString) ? " " + argsString : ""} ${msg}`, {
1362
+ return createProcessError(`${commandString} ${msg}`, {
1355
1363
  ...meta,
1356
- command: `${metaCommand} ${argsString}`
1364
+ command: commandString
1357
1365
  }, baseStack);
1358
1366
  });
1359
1367
  const rejectOnNonZero = config?.rejectOnNonZero ?? false;
1360
- const child = spawn(command, [...args], restOption);
1368
+ if (isInline) {
1369
+ const resolved = resolveCommand(cmd, useColors);
1370
+ cmd = resolved.command;
1371
+ finalArgs = resolved.args;
1372
+ }
1373
+ for (const arg of finalArgs) if (hasShellSyntax(arg)) throw new Error(formatMessageColor(`Invalid argument: "${arg}" contains unsupported shell syntax`, useColors));
1374
+ const cmdString = formatCommand(cmd, finalArgs, { useColors });
1375
+ const cmdStringPlain = formatCommand(cmd, finalArgs, { useColors: false });
1376
+ const child = spawn(cmd, finalArgs, {
1377
+ shell,
1378
+ ...restOption
1379
+ });
1361
1380
  let finished = false;
1362
1381
  const kill = () => {
1363
1382
  try {
@@ -1382,8 +1401,8 @@ function spawnWithLifecycle(command, args, options, config) {
1382
1401
  kill();
1383
1402
  fail(formatError(`timed out after ${timeout}ms`, {
1384
1403
  reason: "timeout",
1385
- command,
1386
- args,
1404
+ command: cmd,
1405
+ args: finalArgs,
1387
1406
  useColors
1388
1407
  }));
1389
1408
  }, timeout) : null;
@@ -1407,8 +1426,8 @@ function spawnWithLifecycle(command, args, options, config) {
1407
1426
  kill();
1408
1427
  fail(formatError("aborted by signal", {
1409
1428
  reason: "abort",
1410
- command,
1411
- args,
1429
+ command: cmd,
1430
+ args: finalArgs,
1412
1431
  useColors
1413
1432
  }));
1414
1433
  };
@@ -1426,8 +1445,8 @@ function spawnWithLifecycle(command, args, options, config) {
1426
1445
  reason: "signal",
1427
1446
  signal,
1428
1447
  exitCode: code ?? void 0,
1429
- command,
1430
- args,
1448
+ command: cmd,
1449
+ args: finalArgs,
1431
1450
  useColors
1432
1451
  }));
1433
1452
  return;
@@ -1437,8 +1456,8 @@ function spawnWithLifecycle(command, args, options, config) {
1437
1456
  fail(formatError(`exited with code ${exitCode}`, {
1438
1457
  reason: "non-zero exit code",
1439
1458
  exitCode,
1440
- command,
1441
- args,
1459
+ command: cmd,
1460
+ args: finalArgs,
1442
1461
  useColors
1443
1462
  }));
1444
1463
  return;