Lines 1-53javascript
1import { t as PATHS } from "./paths-Cn5OzmYL.js";
2import { randomUUID } from "node:crypto";
3import fs from "node:fs/promises";
4import nodePath from "node:path";
5import process from "node:process";
6import { spawn, spawnSync } from "node:child_process";
7import { existsSync } from "node:fs";
HighChild Process
Package source references child process execution.
dist/lifecycle-Cqe8OQVX.jsView on unpkg · L5 9//#region src/lib/exec.ts
11* Parse a boolean-ish env value. Returns `undefined` when unset or
12* unrecognized so callers can apply their own default. Accepts
13* `1|true|yes|on` (true) and `0|false|no|off|<empty>` (false),
14* case-insensitive. The single shared parser for all new `GH_ROUTER_*`
15* flags so on/off semantics don't drift per call site.
17function parseBoolEnv(value) {
18 if (value === void 0) return void 0;
19 const v = value.trim().toLowerCase();
20 if (v === "1" || v === "true" || v === "yes" || v === "on") return true;
21 if (v === "0" || v === "false" || v === "no" || v === "off" || v === "") return false;
23/** Read the PATH value from an env object, case-insensitively. */
24function pathValueOf(env) {
25 for (const key of Object.keys(env)) if (key.toLowerCase() === "path") return env[key] ?? "";
29* Resolve an executable name to an absolute path against PATH, honoring
30* `PATHEXT` on Windows and **excluding the current working directory**.
32* Returns `null` when unresolved — callers treat that as "tool absent"
33* and skip (best-effort). Spawning the returned absolute path means
34* `cmd.exe`'s implicit cwd-first lookup never applies, closing the
35* planted-`npm.cmd` vector.
37function resolveExecutable(name, opts = {}) {
38 const platform = opts.platform ?? process.platform;
39 const env = opts.env ?? process.env;
40 const cwdRaw = opts.cwd ?? (typeof process.cwd === "function" ? process.cwd() : void 0);
41 const resolvedCwd = cwdRaw ? nodePath.resolve(cwdRaw) : null;
42 const dirs = pathValueOf(env).split(nodePath.delimiter).filter((d) => d.length > 0 && d !== ".");
43 const isWin = platform === "win32";
44 if (!isWin && name.includes("/")) return existsSync(name) ? nodePath.resolve(name) : null;
45 if (isWin && (name.includes("\\") || name.includes("/"))) return existsSync(name) ? nodePath.resolve(name) : null;
46 const exts = isWin && nodePath.extname(name) === "" ? (env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").map((e) => e.trim()).filter(Boolean) : [""];
47 for (const dir of dirs) {
48 if (resolvedCwd && nodePath.resolve(dir) === resolvedCwd) continue;
49 for (const ext of exts) {
50 const candidate = nodePath.join(dir, name + ext);
51 if (existsSync(candidate)) return candidate;