diff options
| author | Adam Mathes <adam@adammathes.com> | 2026-02-13 21:34:48 -0800 |
|---|---|---|
| committer | Adam Mathes <adam@adammathes.com> | 2026-02-13 21:34:48 -0800 |
| commit | 76cb9c2a39d477a64824a985ade40507e3bbade1 (patch) | |
| tree | 41e997aa9c6f538d3a136af61dae9424db2005a9 /vanilla/node_modules/tinyexec | |
| parent | 819a39a21ac992b1393244a4c283bbb125208c69 (diff) | |
| download | neko-76cb9c2a39d477a64824a985ade40507e3bbade1.tar.gz neko-76cb9c2a39d477a64824a985ade40507e3bbade1.tar.bz2 neko-76cb9c2a39d477a64824a985ade40507e3bbade1.zip | |
feat(vanilla): add testing infrastructure and tests (NK-wjnczv)
Diffstat (limited to 'vanilla/node_modules/tinyexec')
| -rw-r--r-- | vanilla/node_modules/tinyexec/LICENSE | 21 | ||||
| -rw-r--r-- | vanilla/node_modules/tinyexec/README.md | 269 | ||||
| -rw-r--r-- | vanilla/node_modules/tinyexec/dist/main.d.ts | 74 | ||||
| -rw-r--r-- | vanilla/node_modules/tinyexec/dist/main.js | 633 | ||||
| -rw-r--r-- | vanilla/node_modules/tinyexec/package.json | 61 |
5 files changed, 1058 insertions, 0 deletions
diff --git a/vanilla/node_modules/tinyexec/LICENSE b/vanilla/node_modules/tinyexec/LICENSE new file mode 100644 index 0000000..558eb6a --- /dev/null +++ b/vanilla/node_modules/tinyexec/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Tinylibs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vanilla/node_modules/tinyexec/README.md b/vanilla/node_modules/tinyexec/README.md new file mode 100644 index 0000000..0bdace7 --- /dev/null +++ b/vanilla/node_modules/tinyexec/README.md @@ -0,0 +1,269 @@ +# tinyexec 📟 + +> A minimal package for executing commands + +This package was created to provide a minimal way of interacting with child +processes without having to manually deal with streams, piping, etc. + +## Installing + +```sh +$ npm i -S tinyexec +``` + +## Usage + +A process can be spawned and awaited like so: + +```ts +import {x} from 'tinyexec'; + +const result = await x('ls', ['-l']); + +// result.stdout - the stdout as a string +// result.stderr - the stderr as a string +// result.exitCode - the process exit code as a number +``` + +By default, tinyexec does not throw on non‑zero exit codes. Check `result.exitCode` or pass `{throwOnError: true}`. + +Output is returned exactly as produced; trailing newlines are not trimmed. If you need trimming, do it explicitly: + +```ts +const clean = result.stdout.replace(/\r?\n$/, ''); +``` + +You may also iterate over the lines of output via an async loop: + +```ts +import {x} from 'tinyexec'; + +const proc = x('ls', ['-l']); + +for await (const line of proc) { + // line will be from stderr/stdout in the order you'd see it in a term +} +``` + +### Options + +Options can be passed to have finer control over spawning of the process: + +```ts +await x('ls', [], { + timeout: 1000 +}); +``` + +The options object can have the following properties: + +- `signal` - an `AbortSignal` to allow aborting of the execution +- `timeout` - time in milliseconds at which the process will be forceably killed +- `persist` - if `true`, the process will continue after the host exits +- `stdin` - another `Result` can be used as the input to this process +- `nodeOptions` - any valid options to node's underlying `spawn` function +- `throwOnError` - if true, non-zero exit codes will throw an error + +### Piping to another process + +You can pipe a process to another via the `pipe` method: + +```ts +const proc1 = x('ls', ['-l']); +const proc2 = proc1.pipe('grep', ['.js']); +const result = await proc2; + +console.log(result.stdout); +``` + +`pipe` takes the same options as a regular execution. For example, you can +pass a timeout to the pipe call: + +```ts +proc1.pipe('grep', ['.js'], { + timeout: 2000 +}); +``` + +### Killing a process + +You can kill the process via the `kill` method: + +```ts +const proc = x('ls'); + +proc.kill(); + +// or with a signal +proc.kill('SIGHUP'); +``` + +### Node modules/binaries + +By default, node's available binaries from `node_modules` will be accessible +in your command. + +For example, in a repo which has `eslint` installed: + +```ts +await x('eslint', ['.']); +``` + +In this example, `eslint` will come from the locally installed `node_modules`. + +### Using an abort signal + +An abort signal can be passed to a process in order to abort it at a later +time. This will result in the process being killed and `aborted` being set +to `true`. + +```ts +const aborter = new AbortController(); +const proc = x('node', ['./foo.mjs'], { + signal: aborter.signal +}); + +// elsewhere... +aborter.abort(); + +await proc; + +proc.aborted; // true +proc.killed; // true +``` + +### Using with command strings + +If you need to continue supporting commands as strings (e.g. "command arg0 arg1"), +you can use [args-tokenizer](https://github.com/TrySound/args-tokenizer), +a lightweight library for parsing shell command strings into an array. + +```ts +import {x} from 'tinyexec'; +import {tokenizeArgs} from 'args-tokenizer'; + +const commandString = 'echo "Hello, World!"'; +const [command, ...args] = tokenizeArgs(commandString); +const result = await x(command, args); + +result.stdout; // Hello, World! +``` + +## API + +Calling `x(command[, args])` returns an awaitable `Result` which has the +following API methods and properties available: + +### `pipe(command[, args[, options]])` + +Pipes the current command to another. For example: + +```ts +x('ls', ['-l']) + .pipe('grep', ['js']); +``` + +The parameters are as follows: + +- `command` - the command to execute (_without any arguments_) +- `args` - an array of arguments +- `options` - options object + +### `process` + +The underlying Node.js `ChildProcess`. tinyexec keeps the surface minimal and does not re‑expose every child_process method/event. Use `proc.process` for advanced access (streams, events, etc.). + +```ts +const proc = x('node', ['./foo.mjs']); + +proc.process?.stdout?.on('data', (chunk) => { + // ... +}); +proc.process?.once('close', (code) => { + // ... +}); +``` + +### `kill([signal])` + +Kills the current process with the specified signal. By default, this will +use the `SIGTERM` signal. + +For example: + +```ts +const proc = x('ls'); + +proc.kill(); +``` + +### `pid` + +The current process ID. For example: + +```ts +const proc = x('ls'); + +proc.pid; // number +``` + +### `aborted` + +Whether the process has been aborted or not (via the `signal` originally +passed in the options object). + +For example: + +```ts +const proc = x('ls'); + +proc.aborted; // bool +``` + +### `killed` + +Whether the process has been killed or not (e.g. via `kill()` or an abort +signal). + +For example: + +```ts +const proc = x('ls'); + +proc.killed; // bool +``` + +### `exitCode` + +The exit code received when the process completed execution. + +For example: + +```ts +const proc = x('ls'); + +proc.exitCode; // number (e.g. 1) +``` + +## Comparison with other libraries + +`tinyexec` aims to provide a lightweight layer on top of Node's own +`child_process` API. + +Some clear benefits compared to other libraries are that `tinyexec` will be much lighter, have a much +smaller footprint and will have a less abstract interface (less "magic"). It +will also have equal security and cross-platform support to popular +alternatives. + +There are various features other libraries include which we are unlikely +to ever implement, as they would prevent us from providing a lightweight layer. + +For example, if you'd like write scripts rather than individual commands, and +prefer to use templating, we'd definitely recommend +[zx](https://github.com/google/zx). zx is a much higher level library which +does some of the same work `tinyexec` does but behind a template string +interface. + +Similarly, libraries like `execa` will provide helpers for various things +like passing files as input to processes. We opt not to support features like +this since many of them are easy to do yourself (using Node's own APIs). diff --git a/vanilla/node_modules/tinyexec/dist/main.d.ts b/vanilla/node_modules/tinyexec/dist/main.d.ts new file mode 100644 index 0000000..acf34b9 --- /dev/null +++ b/vanilla/node_modules/tinyexec/dist/main.d.ts @@ -0,0 +1,74 @@ +/// <reference types="node" resolution-mode="require"/> +import { ChildProcess, SpawnOptions } from "node:child_process"; +import { Readable } from "node:stream"; + +//#region src/non-zero-exit-error.d.ts +declare class NonZeroExitError extends Error { + readonly result: Result; + readonly output?: Output; + get exitCode(): number | undefined; + constructor(result: Result, output?: Output); +} + +//#endregion +//#region src/main.d.ts +interface Output { + stderr: string; + stdout: string; + exitCode: number | undefined; +} +interface PipeOptions extends Options {} +type KillSignal = Parameters<ChildProcess['kill']>[0]; +interface OutputApi extends AsyncIterable<string> { + pipe(command: string, args?: string[], options?: Partial<PipeOptions>): Result; + process: ChildProcess | undefined; + kill(signal?: KillSignal): boolean; + get pid(): number | undefined; + get aborted(): boolean; + get killed(): boolean; + get exitCode(): number | undefined; +} +type Result = PromiseLike<Output> & OutputApi; +interface Options { + signal: AbortSignal; + nodeOptions: SpawnOptions; + timeout: number; + persist: boolean; + stdin: ExecProcess; + throwOnError: boolean; +} +interface TinyExec { + (command: string, args?: string[], options?: Partial<Options>): Result; +} +declare class ExecProcess implements Result { + protected _process?: ChildProcess; + protected _aborted: boolean; + protected _options: Partial<Options>; + protected _command: string; + protected _args: string[]; + protected _resolveClose?: () => void; + protected _processClosed: Promise<void>; + protected _thrownError?: Error; + get process(): ChildProcess | undefined; + get pid(): number | undefined; + get exitCode(): number | undefined; + constructor(command: string, args?: string[], options?: Partial<Options>); + kill(signal?: KillSignal): boolean; + get aborted(): boolean; + get killed(): boolean; + pipe(command: string, args?: string[], options?: Partial<PipeOptions>): Result; + [Symbol.asyncIterator](): AsyncIterator<string>; + protected _waitForOutput(): Promise<Output>; + then<TResult1 = Output, TResult2 = never>(onfulfilled?: ((value: Output) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>; + protected _streamOut?: Readable; + protected _streamErr?: Readable; + spawn(): void; + protected _resetState(): void; + protected _onError: (err: Error) => void; + protected _onClose: () => void; +} +declare const x: TinyExec; +declare const exec: TinyExec; + +//#endregion +export { ExecProcess, KillSignal, NonZeroExitError, Options, Output, OutputApi, PipeOptions, Result, TinyExec, exec, x };
\ No newline at end of file diff --git a/vanilla/node_modules/tinyexec/dist/main.js b/vanilla/node_modules/tinyexec/dist/main.js new file mode 100644 index 0000000..59f1931 --- /dev/null +++ b/vanilla/node_modules/tinyexec/dist/main.js @@ -0,0 +1,633 @@ +import { createRequire as e } from "module"; +import { spawn as t } from "node:child_process"; +import { delimiter as n, dirname as r, normalize as i, resolve as a } from "node:path"; +import { cwd as o } from "node:process"; +import { PassThrough as s } from "node:stream"; +import c from "node:readline"; +var l = Object.create; +var u = Object.defineProperty; +var d = Object.getOwnPropertyDescriptor; +var f = Object.getOwnPropertyNames; +var p = Object.getPrototypeOf; +var m = Object.prototype.hasOwnProperty; +var h = (e, t) => () => (t || e((t = { exports: {} }).exports, t), t.exports); +var g = (e, t, n, r) => { + if (t && typeof t === "object" || typeof t === "function") for (var i = f(t), a = 0, o = i.length, s; a < o; a++) { + s = i[a]; + if (!m.call(e, s) && s !== n) u(e, s, { + get: ((e) => t[e]).bind(null, s), + enumerable: !(r = d(t, s)) || r.enumerable + }); + } + return e; +}; +var _ = (e, t, n) => (n = e != null ? l(p(e)) : {}, g(t || !e || !e.__esModule ? u(n, "default", { + value: e, + enumerable: true +}) : n, e)); +var v = /* @__PURE__ */ e(import.meta.url); +const y = /^path$/i; +const b = { + key: "PATH", + value: "" +}; +function x(e) { + for (const t in e) { + if (!Object.prototype.hasOwnProperty.call(e, t) || !y.test(t)) continue; + const n = e[t]; + if (!n) return b; + return { + key: t, + value: n + }; + } + return b; +} +function S(e, t) { + const i = t.value.split(n); + let o = e; + let s; + do { + i.push(a(o, "node_modules", ".bin")); + s = o; + o = r(o); + } while (o !== s); + return { + key: t.key, + value: i.join(n) + }; +} +function C(e, t) { + const n = { + ...process.env, + ...t + }; + const r = S(e, x(n)); + n[r.key] = r.value; + return n; +} +const w = (e) => { + let t = e.length; + const n = new s(); + const r = () => { + if (--t === 0) n.emit("end"); + }; + for (const t of e) { + t.pipe(n, { end: false }); + t.on("end", r); + } + return n; +}; +var T = h((exports, t) => { + t.exports = a; + a.sync = o; + var n = v("fs"); + function r(e, t) { + var n = t.pathExt !== void 0 ? t.pathExt : process.env.PATHEXT; + if (!n) return true; + n = n.split(";"); + if (n.indexOf("") !== -1) return true; + for (var r = 0; r < n.length; r++) { + var i = n[r].toLowerCase(); + if (i && e.substr(-i.length).toLowerCase() === i) return true; + } + return false; + } + function i(e, t, n) { + if (!e.isSymbolicLink() && !e.isFile()) return false; + return r(t, n); + } + function a(e, t, r) { + n.stat(e, function(n, a) { + r(n, n ? false : i(a, e, t)); + }); + } + function o(e, t) { + return i(n.statSync(e), e, t); + } +}); +var E = h((exports, t) => { + t.exports = r; + r.sync = i; + var n = v("fs"); + function r(e, t, r) { + n.stat(e, function(e, n) { + r(e, e ? false : a(n, t)); + }); + } + function i(e, t) { + return a(n.statSync(e), t); + } + function a(e, t) { + return e.isFile() && o(e, t); + } + function o(e, t) { + var n = e.mode; + var r = e.uid; + var i = e.gid; + var a = t.uid !== void 0 ? t.uid : process.getuid && process.getuid(); + var o = t.gid !== void 0 ? t.gid : process.getgid && process.getgid(); + var s = parseInt("100", 8); + var c = parseInt("010", 8); + var l = parseInt("001", 8); + var u = s | c; + var d = n & l || n & c && i === o || n & s && r === a || n & u && a === 0; + return d; + } +}); +var D = h((exports, t) => { + var n = v("fs"); + var r; + if (process.platform === "win32" || global.TESTING_WINDOWS) r = T(); + else r = E(); + t.exports = i; + i.sync = a; + function i(e, t, n) { + if (typeof t === "function") { + n = t; + t = {}; + } + if (!n) { + if (typeof Promise !== "function") throw new TypeError("callback not provided"); + return new Promise(function(n, r) { + i(e, t || {}, function(e, t) { + if (e) r(e); + else n(t); + }); + }); + } + r(e, t || {}, function(e, r) { + if (e) { + if (e.code === "EACCES" || t && t.ignoreErrors) { + e = null; + r = false; + } + } + n(e, r); + }); + } + function a(e, t) { + try { + return r.sync(e, t || {}); + } catch (e) { + if (t && t.ignoreErrors || e.code === "EACCES") return false; + else throw e; + } + } +}); +var O = h((exports, t) => { + const n = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys"; + const r = v("path"); + const i = n ? ";" : ":"; + const a = D(); + const o = (e) => Object.assign(new Error(`not found: ${e}`), { code: "ENOENT" }); + const s = (e, t) => { + const r = t.colon || i; + const a = e.match(/\//) || n && e.match(/\\/) ? [""] : [...n ? [process.cwd()] : [], ...(t.path || process.env.PATH || "").split(r)]; + const o = n ? t.pathExt || process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM" : ""; + const s = n ? o.split(r) : [""]; + if (n) { + if (e.indexOf(".") !== -1 && s[0] !== "") s.unshift(""); + } + return { + pathEnv: a, + pathExt: s, + pathExtExe: o + }; + }; + const c = (e, t, n) => { + if (typeof t === "function") { + n = t; + t = {}; + } + if (!t) t = {}; + const { pathEnv: i, pathExt: c, pathExtExe: l } = s(e, t); + const u = []; + const d = (n) => new Promise((a, s) => { + if (n === i.length) return t.all && u.length ? a(u) : s(o(e)); + const c = i[n]; + const l = /^".*"$/.test(c) ? c.slice(1, -1) : c; + const d = r.join(l, e); + const p = !l && /^\.[\\\/]/.test(e) ? e.slice(0, 2) + d : d; + a(f(p, n, 0)); + }); + const f = (e, n, r) => new Promise((i, o) => { + if (r === c.length) return i(d(n + 1)); + const s = c[r]; + a(e + s, { pathExt: l }, (a, o) => { + if (!a && o) if (t.all) u.push(e + s); + else return i(e + s); + return i(f(e, n, r + 1)); + }); + }); + return n ? d(0).then((e) => n(null, e), n) : d(0); + }; + const l = (e, t) => { + t = t || {}; + const { pathEnv: n, pathExt: i, pathExtExe: c } = s(e, t); + const l = []; + for (let o = 0; o < n.length; o++) { + const s = n[o]; + const u = /^".*"$/.test(s) ? s.slice(1, -1) : s; + const d = r.join(u, e); + const f = !u && /^\.[\\\/]/.test(e) ? e.slice(0, 2) + d : d; + for (let e = 0; e < i.length; e++) { + const n = f + i[e]; + try { + const e = a.sync(n, { pathExt: c }); + if (e) if (t.all) l.push(n); + else return n; + } catch (e) {} + } + } + if (t.all && l.length) return l; + if (t.nothrow) return null; + throw o(e); + }; + t.exports = c; + c.sync = l; +}); +var k = h((exports, t) => { + const n = (e = {}) => { + const t = e.env || process.env; + const n = e.platform || process.platform; + if (n !== "win32") return "PATH"; + return Object.keys(t).reverse().find((e) => e.toUpperCase() === "PATH") || "Path"; + }; + t.exports = n; + t.exports.default = n; +}); +var A = h((exports, t) => { + const n = v("path"); + const r = O(); + const i = k(); + function a(e, t) { + const a = e.options.env || process.env; + const o = process.cwd(); + const s = e.options.cwd != null; + const c = s && process.chdir !== void 0 && !process.chdir.disabled; + if (c) try { + process.chdir(e.options.cwd); + } catch (e) {} + let l; + try { + l = r.sync(e.command, { + path: a[i({ env: a })], + pathExt: t ? n.delimiter : void 0 + }); + } catch (e) {} finally { + if (c) process.chdir(o); + } + if (l) l = n.resolve(s ? e.options.cwd : "", l); + return l; + } + function o(e) { + return a(e) || a(e, true); + } + t.exports = o; +}); +var j = h((exports, t) => { + const n = /([()\][%!^"`<>&|;, *?])/g; + function r(e) { + e = e.replace(n, "^$1"); + return e; + } + function i(e, t) { + e = `${e}`; + e = e.replace(/(\\*)"/g, "$1$1\\\""); + e = e.replace(/(\\*)$/, "$1$1"); + e = `"${e}"`; + e = e.replace(n, "^$1"); + if (t) e = e.replace(n, "^$1"); + return e; + } + t.exports.command = r; + t.exports.argument = i; +}); +var M = h((exports, t) => { + t.exports = /^#!(.*)/; +}); +var N = h((exports, t) => { + const n = M(); + t.exports = (e = "") => { + const t = e.match(n); + if (!t) return null; + const [r, i] = t[0].replace(/#! ?/, "").split(" "); + const a = r.split("/").pop(); + if (a === "env") return i; + return i ? `${a} ${i}` : a; + }; +}); +var P = h((exports, t) => { + const n = v("fs"); + const r = N(); + function i(e) { + const t = 150; + const i = Buffer.alloc(t); + let a; + try { + a = n.openSync(e, "r"); + n.readSync(a, i, 0, t, 0); + n.closeSync(a); + } catch (e) {} + return r(i.toString()); + } + t.exports = i; +}); +var F = h((exports, t) => { + const n = v("path"); + const r = A(); + const i = j(); + const a = P(); + const o = process.platform === "win32"; + const s = /\.(?:com|exe)$/i; + const c = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i; + function l(e) { + e.file = r(e); + const t = e.file && a(e.file); + if (t) { + e.args.unshift(e.file); + e.command = t; + return r(e); + } + return e.file; + } + function u(e) { + if (!o) return e; + const t = l(e); + const r = !s.test(t); + if (e.options.forceShell || r) { + const r = c.test(t); + e.command = n.normalize(e.command); + e.command = i.command(e.command); + e.args = e.args.map((e) => i.argument(e, r)); + const a = [e.command].concat(e.args).join(" "); + e.args = [ + "/d", + "/s", + "/c", + `"${a}"` + ]; + e.command = process.env.comspec || "cmd.exe"; + e.options.windowsVerbatimArguments = true; + } + return e; + } + function d(e, t, n) { + if (t && !Array.isArray(t)) { + n = t; + t = null; + } + t = t ? t.slice(0) : []; + n = Object.assign({}, n); + const r = { + command: e, + args: t, + options: n, + file: void 0, + original: { + command: e, + args: t + } + }; + return n.shell ? r : u(r); + } + t.exports = d; +}); +var I = h((exports, t) => { + const n = process.platform === "win32"; + function r(e, t) { + return Object.assign(new Error(`${t} ${e.command} ENOENT`), { + code: "ENOENT", + errno: "ENOENT", + syscall: `${t} ${e.command}`, + path: e.command, + spawnargs: e.args + }); + } + function i(e, t) { + if (!n) return; + const r = e.emit; + e.emit = function(n, i) { + if (n === "exit") { + const n = a(i, t, "spawn"); + if (n) return r.call(e, "error", n); + } + return r.apply(e, arguments); + }; + } + function a(e, t) { + if (n && e === 1 && !t.file) return r(t.original, "spawn"); + return null; + } + function o(e, t) { + if (n && e === 1 && !t.file) return r(t.original, "spawnSync"); + return null; + } + t.exports = { + hookChildProcess: i, + verifyENOENT: a, + verifyENOENTSync: o, + notFoundError: r + }; +}); +var L = h((exports, t) => { + const n = v("child_process"); + const r = F(); + const i = I(); + function a(e, t, a) { + const o = r(e, t, a); + const s = n.spawn(o.command, o.args, o.options); + i.hookChildProcess(s, o); + return s; + } + function o(e, t, a) { + const o = r(e, t, a); + const s = n.spawnSync(o.command, o.args, o.options); + s.error = s.error || i.verifyENOENTSync(s.status, o); + return s; + } + t.exports = a; + t.exports.spawn = a; + t.exports.sync = o; + t.exports._parse = r; + t.exports._enoent = i; +}); +var R = _(L(), 1); +var z = class extends Error { + result; + output; + get exitCode() { + if (this.result.exitCode !== null) return this.result.exitCode; + return void 0; + } + constructor(e, t) { + super(`Process exited with non-zero status (${e.exitCode})`); + this.result = e; + this.output = t; + } +}; +const B = { + timeout: void 0, + persist: false +}; +const V = { windowsHide: true }; +function H(e, t) { + const n = i(e); + const r = t ?? []; + return { + command: n, + args: r + }; +} +function U(e) { + const t = new AbortController(); + for (const n of e) { + if (n.aborted) { + t.abort(); + return n; + } + const e = () => { + t.abort(n.reason); + }; + n.addEventListener("abort", e, { signal: t.signal }); + } + return t.signal; +} +async function W(e) { + let t = ""; + for await (const n of e) t += n.toString(); + return t; +} +var G = class { + _process; + _aborted = false; + _options; + _command; + _args; + _resolveClose; + _processClosed; + _thrownError; + get process() { + return this._process; + } + get pid() { + return this._process?.pid; + } + get exitCode() { + if (this._process && this._process.exitCode !== null) return this._process.exitCode; + return void 0; + } + constructor(e, t, n) { + this._options = { + ...B, + ...n + }; + this._command = e; + this._args = t ?? []; + this._processClosed = new Promise((e) => { + this._resolveClose = e; + }); + } + kill(e) { + return this._process?.kill(e) === true; + } + get aborted() { + return this._aborted; + } + get killed() { + return this._process?.killed === true; + } + pipe(e, t, n) { + return q(e, t, { + ...n, + stdin: this + }); + } + async *[Symbol.asyncIterator]() { + const e = this._process; + if (!e) return; + const t = []; + if (this._streamErr) t.push(this._streamErr); + if (this._streamOut) t.push(this._streamOut); + const n = w(t); + const r = c.createInterface({ input: n }); + for await (const e of r) yield e.toString(); + await this._processClosed; + e.removeAllListeners(); + if (this._thrownError) throw this._thrownError; + if (this._options?.throwOnError && this.exitCode !== 0 && this.exitCode !== void 0) throw new z(this); + } + async _waitForOutput() { + const e = this._process; + if (!e) throw new Error("No process was started"); + const [t, n] = await Promise.all([this._streamOut ? W(this._streamOut) : "", this._streamErr ? W(this._streamErr) : ""]); + await this._processClosed; + if (this._options?.stdin) await this._options.stdin; + e.removeAllListeners(); + if (this._thrownError) throw this._thrownError; + const r = { + stderr: n, + stdout: t, + exitCode: this.exitCode + }; + if (this._options.throwOnError && this.exitCode !== 0 && this.exitCode !== void 0) throw new z(this, r); + return r; + } + then(e, t) { + return this._waitForOutput().then(e, t); + } + _streamOut; + _streamErr; + spawn() { + const e = o(); + const n = this._options; + const r = { + ...V, + ...n.nodeOptions + }; + const i = []; + this._resetState(); + if (n.timeout !== void 0) i.push(AbortSignal.timeout(n.timeout)); + if (n.signal !== void 0) i.push(n.signal); + if (n.persist === true) r.detached = true; + if (i.length > 0) r.signal = U(i); + r.env = C(e, r.env); + const { command: a, args: s } = H(this._command, this._args); + const c = (0, R._parse)(a, s, r); + const l = t(c.command, c.args, c.options); + if (l.stderr) this._streamErr = l.stderr; + if (l.stdout) this._streamOut = l.stdout; + this._process = l; + l.once("error", this._onError); + l.once("close", this._onClose); + if (n.stdin !== void 0 && l.stdin && n.stdin.process) { + const { stdout: e } = n.stdin.process; + if (e) e.pipe(l.stdin); + } + } + _resetState() { + this._aborted = false; + this._processClosed = new Promise((e) => { + this._resolveClose = e; + }); + this._thrownError = void 0; + } + _onError = (e) => { + if (e.name === "AbortError" && (!(e.cause instanceof Error) || e.cause.name !== "TimeoutError")) { + this._aborted = true; + return; + } + this._thrownError = e; + }; + _onClose = () => { + if (this._resolveClose) this._resolveClose(); + }; +}; +const K = (e, t, n) => { + const r = new G(e, t, n); + r.spawn(); + return r; +}; +const q = K; +export { G as ExecProcess, z as NonZeroExitError, q as exec, K as x }; diff --git a/vanilla/node_modules/tinyexec/package.json b/vanilla/node_modules/tinyexec/package.json new file mode 100644 index 0000000..7c1d3bf --- /dev/null +++ b/vanilla/node_modules/tinyexec/package.json @@ -0,0 +1,61 @@ +{ + "name": "tinyexec", + "version": "1.0.2", + "type": "module", + "description": "A minimal library for executing processes in Node", + "main": "./dist/main.js", + "engines": { + "node": ">=18" + }, + "files": [ + "dist" + ], + "scripts": { + "build": "tsdown", + "build:types": "tsc", + "dev": "tsdown --watch", + "format": "prettier --write src", + "format:check": "prettier --check src", + "lint": "eslint src", + "prepare": "npm run build", + "test": "npm run build && vitest run" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/tinylibs/tinyexec.git" + }, + "keywords": [ + "execa", + "exec", + "tiny", + "child_process", + "spawn" + ], + "author": "James Garbutt (https://github.com/43081j)", + "license": "MIT", + "bugs": { + "url": "https://github.com/tinylibs/tinyexec/issues" + }, + "homepage": "https://github.com/tinylibs/tinyexec#readme", + "devDependencies": { + "@eslint/js": "^9.0.0", + "@types/cross-spawn": "^6.0.6", + "@types/node": "^20.12.7", + "@vitest/coverage-v8": "^4.0.7", + "cross-spawn": "^7.0.3", + "eslint-config-google": "^0.14.0", + "prettier": "^3.2.5", + "tsdown": "^0.9.9", + "typescript": "^5.4.5", + "typescript-eslint": "^7.7.0", + "vitest": "^4.0.7" + }, + "exports": { + ".": { + "types": "./dist/main.d.ts", + "default": "./dist/main.js" + }, + "./package.json": "./package.json" + }, + "types": "./dist/main.d.ts" +} |
