# bellpull/cross-spawn

> Every export of bellpull/cross-spawn, with its signature and doc comment: _enoent, crossSpawn, module.exports, parse, spawn, sync and 2 more, plus 3 types.

Source: https://bellpull.interlace.tools/docs/api/cross-spawn

<!-- Generated by scripts/api-reference.ts from the built dist/*.d.ts. Do not edit; run `npx tsx scripts/api-reference.ts`. -->

`bellpull/cross-spawn` — the drop-in path for `cross-spawn` (design R7, Y3).

Graded by `cross-spawn`'s own 68-case suite in `compat-oracle` (`hosts.ts`,
`target: 'bellpull/cross-spawn'`). The suite runs every case four times — `spawn`,
`spawn-force-shell`, `sync`, `sync-force-shell` — so a divergence in one path cannot hide
behind the other three.

## What a drop-in means here, and the one thing it means most

**On POSIX this is a pass-through, and that is the correct implementation.**
`cross-spawn`'s own `parseNonShell` returns immediately off Windows; its `hookChildProcess`
does too. Everything it is famous for — `npm.cmd`, `PATHEXT`, shebangs, caret escaping —
is Windows-only, because on POSIX the kernel already does all of it. A façade that
"improved" on that by resolving the command itself would change the error a caller sees
(`err.path` would be a resolved path, not the name they wrote), change the process tree,
and break the incumbent's suite in four places. Being identical is the product.

So what this file adds over `node:child_process` is exactly what `cross-spawn` adds:
argument normalisation and cloning, the Windows parse in `spawn-args.ts`, and the ENOENT
reconstruction in `enoent.ts`.

## It reads the ambient process, on purpose

The core (`run.ts`, `which.ts`) takes a `Runtime` argument and reads no global — Y9. A
drop-in cannot: `cross-spawn`'s callers pass a command and some arguments, and the package
reads `process.env` and `process.platform` itself. Requiring a runtime here would mean
every migrating caller edits every call site, which is the definition of not a drop-in.
`ambient.ts` is where that read lives, once.

## Default export

`module.exports = spawn` with `spawn`, `sync`, `_parse` and `_enoent` hung off it, because
that is what `require('cross-spawn')` gives today and a migration must not have to change
how the value is called.

```ts
import crossSpawn from 'bellpull/cross-spawn';
import { _enoent, crossSpawn, module.exports, … } from 'bellpull/cross-spawn';
```

## Functions

### parse

`cross-spawn._parse`: exported because its suite and its ecosystem both reach for it.

```ts
function parse(command: string, args?: ArgsOrOptions, options?: SpawnOptions | null): Parsed;
```

| Parameter | Type |
| :-- | :-- |
| `command` | `string` |
| `args` (optional) | `ArgsOrOptions` |
| `options` (optional) | `SpawnOptions \| null` |

**Returns** `Parsed`

### spawn

`cross-spawn(command, args?, options?)` — a `ChildProcess`, spawned the way the platform
needs.

```ts
function spawn(command: string, args?: ArgsOrOptions, options?: SpawnOptions | null): ChildProcess;
```

| Parameter | Type |
| :-- | :-- |
| `command` | `string` |
| `args` (optional) | `ArgsOrOptions` |
| `options` (optional) | `SpawnOptions \| null` |

**Returns** `ChildProcess`

### sync

`cross-spawn.sync(command, args?, options?)`.

The missing-command case is put back onto `result.error` rather than thrown: `spawnSync`
reports a failure to start that way and a drop-in that threw would turn a value the caller
inspects into control flow they did not write.

```ts
function sync(command: string, args?: ArgsOrOptions, options?: SpawnOptions | null): SpawnSyncReturns<Buffer | string>;
```

| Parameter | Type |
| :-- | :-- |
| `command` | `string` |
| `args` (optional) | `ArgsOrOptions` |
| `options` (optional) | `SpawnOptions \| null` |

**Returns** `SpawnSyncReturns<Buffer \| string>`

## Classes

### ChildProcess

Instances of the `ChildProcess` represent spawned child processes.

Instances of `ChildProcess` are not intended to be created directly. Rather,
use the {@link spawn}, {@link exec},{@link execFile}, or {@link fork} methods to create
instances of `ChildProcess`.

```ts
class ChildProcess implements EventEmitter {
        /**
         * A `Writable Stream` that represents the child process's `stdin`.
         *
         * If a child process waits to read all of its input, the child will not continue
         * until this stream has been closed via `end()`.
         *
         * If the child was spawned with `stdio[0]` set to anything other than `'pipe'`,
         * then this will be `null`.
         *
         * `subprocess.stdin` is an alias for `subprocess.stdio[0]`. Both properties will
         * refer to the same value.
         *
         * The `subprocess.stdin` property can be `null` or `undefined` if the child process could not be successfully spawned.
         * @since v0.1.90
         */
        stdin: Writable | null;
        /**
         * A `Readable Stream` that represents the child process's `stdout`.
         *
         * If the child was spawned with `stdio[1]` set to anything other than `'pipe'`,
         * then this will be `null`.
         *
         * `subprocess.stdout` is an alias for `subprocess.stdio[1]`. Both properties will
         * refer to the same value.
         *
         * ```js
         * import { spawn } from 'node:child_process';
         *
         * const subprocess = spawn('ls');
         *
         * subprocess.stdout.on('data', (data) => {
         *   console.log(`Received chunk ${data}`);
         * });
         * ```
         *
         * The `subprocess.stdout` property can be `null` or `undefined` if the child process could not be successfully spawned.
         * @since v0.1.90
         */
        stdout: Readable | null;
        /**
         * A `Readable Stream` that represents the child process's `stderr`.
         *
         * If the child was spawned with `stdio[2]` set to anything other than `'pipe'`,
         * then this will be `null`.
         *
         * `subprocess.stderr` is an alias for `subprocess.stdio[2]`. Both properties will
         * refer to the same value.
         *
         * The `subprocess.stderr` property can be `null` or `undefined` if the child process could not be successfully spawned.
         * @since v0.1.90
         */
        stderr: Readable | null;
        /**
         * The `subprocess.channel` property is a reference to the child's IPC channel. If
         * no IPC channel exists, this property is `undefined`.
         * @since v7.1.0
         */
        readonly channel?: Control | null;
        /**
         * A sparse array of pipes to the child process, corresponding with positions in
         * the `stdio` option passed to {@link spawn} that have been set
         * to the value `'pipe'`. `subprocess.stdio[0]`, `subprocess.stdio[1]`, and `subprocess.stdio[2]` are also available as `subprocess.stdin`, `subprocess.stdout`, and `subprocess.stderr`,
         * respectively.
         *
         * In the following example, only the child's fd `1` (stdout) is configured as a
         * pipe, so only the parent's `subprocess.stdio[1]` is a stream, all other values
         * in the array are `null`.
         *
         * ```js
         * import assert from 'node:assert';
         * import fs from 'node:fs';
         * import child_process from 'node:child_process';
         *
         * const subprocess = child_process.spawn('ls', {
         *   stdio: [
         *     0, // Use parent's stdin for child.
         *     'pipe', // Pipe child's stdout to parent.
         *     fs.openSync('err.out', 'w'), // Direct child's stderr to a file.
         *   ],
         * });
         *
         * assert.strictEqual(subprocess.stdio[0], null);
         * assert.strictEqual(subprocess.stdio[0], subprocess.stdin);
         *
         * assert(subprocess.stdout);
         * assert.strictEqual(subprocess.stdio[1], subprocess.stdout);
         *
         * assert.strictEqual(subprocess.stdio[2], null);
         * assert.strictEqual(subprocess.stdio[2], subprocess.stderr);
         * ```
         *
         * The `subprocess.stdio` property can be `undefined` if the child process could
         * not be successfully spawned.
         * @since v0.7.10
         */
        readonly stdio: [
            Writable | null,
            // stdin
            Readable | null,
            // stdout
            Readable | null,
            // stderr
            Readable | Writable | null | undefined,
            // extra
            Readable | Writable | null | undefined, // extra
        ];
        /**
         * The `subprocess.killed` property indicates whether the child process
         * successfully received a signal from `subprocess.kill()`. The `killed` property
         * does not indicate that the child process has been terminated.
         * @since v0.5.10
         */
        readonly killed: boolean;
        /**
         * Returns the process identifier (PID) of the child process. If the child process
         * fails to spawn due to errors, then the value is `undefined` and `error` is
         * emitted.
         *
         * ```js
         * import { spawn } from 'node:child_process';
         * const grep = spawn('grep', ['ssh']);
         *
         * console.log(`Spawned child pid: ${grep.pid}`);
         * grep.stdin.end();
         * ```
         * @since v0.1.90
         */
        readonly pid?: number | undefined;
        /**
         * The `subprocess.connected` property indicates whether it is still possible to
         * send and receive messages from a child process. When `subprocess.connected` is `false`, it is no longer possible to send or receive messages.
         * @since v0.7.2
         */
        readonly connected: boolean;
        /**
         * The `subprocess.exitCode` property indicates the exit code of the child process.
         * If the child process is still running, the field will be `null`.
         *
         * When the child process is terminated by a signal, `subprocess.exitCode` will be
         * `null` and `subprocess.signalCode` will be set. To get the corresponding
         * POSIX exit code, use
         * `util.convertProcessSignalToExitCode(subprocess.signalCode)`.
         */
        readonly exitCode: number | null;
        /**
         * The `subprocess.signalCode` property indicates the signal received by
         * the child process if any, else `null`.
         */
        readonly signalCode: NodeJS.Signals | null;
        /**
         * The `subprocess.spawnargs` property represents the full list of command-line
         * arguments the child process was launched with.
         */
        readonly spawnargs: string[];
        /**
         * The `subprocess.spawnfile` property indicates the executable file name of
         * the child process that is launched.
         *
         * For {@link fork}, its value will be equal to `process.execPath`.
         * For {@link spawn}, its value will be the name of
         * the executable file.
         * For {@link exec},  its value will be the name of the shell
         * in which the child process is launched.
         */
        readonly spawnfile: string;
        /**
         * The `subprocess.kill()` method sends a signal to the child process. If no
         * argument is given, the process will be sent the `'SIGTERM'` signal. See [`signal(7)`](http://man7.org/linux/man-pages/man7/signal.7.html) for a list of available signals. This function
         * returns `true` if [`kill(2)`](http://man7.org/linux/man-pages/man2/kill.2.html) succeeds, and `false` otherwise.
         *
         * ```js
         * import { spawn } from 'node:child_process';
         * const grep = spawn('grep', ['ssh']);
         *
         * grep.on('close', (code, signal) => {
         *   console.log(
         *     `child process terminated due to receipt of signal ${signal}`);
         * });
         *
         * // Send SIGHUP to process.
         * grep.kill('SIGHUP');
         * ```
         *
         * The `ChildProcess` object may emit an `'error'` event if the signal
         * cannot be delivered. Sending a signal to a child process that has already exited
         * is not an error but may have unforeseen consequences. Specifically, if the
         * process identifier (PID) has been reassigned to another process, the signal will
         * be delivered to that process instead which can have unexpected results.
         *
         * While the function is called `kill`, the signal delivered to the child process
         * may not actually terminate the process.
         *
         * See [`kill(2)`](http://man7.org/linux/man-pages/man2/kill.2.html) for reference.
         *
         * On Windows, where POSIX signals do not exist, the `signal` argument will be
         * ignored, and the process will be killed forcefully and abruptly (similar to `'SIGKILL'`).
         * See `Signal Events` for more details.
         *
         * On Linux, child processes of child processes will not be terminated
         * when attempting to kill their parent. This is likely to happen when running a
         * new process in a shell or with the use of the `shell` option of `ChildProcess`:
         *
         * ```js
         * import { spawn } from 'node:child_process';
         *
         * const subprocess = spawn(
         *   'sh',
         *   [
         *     '-c',
         *     `node -e "setInterval(() => {
         *       console.log(process.pid, 'is alive')
         *     }, 500);"`,
         *   ], {
         *     stdio: ['inherit', 'inherit', 'inherit'],
         *   },
         * );
         *
         * setTimeout(() => {
         *   subprocess.kill(); // Does not terminate the Node.js process in the shell.
         * }, 2000);
         * ```
         * @since v0.1.90
         */
        kill(signal?: NodeJS.Signals | number): boolean;
        /**
         * Calls {@link ChildProcess.kill} with `'SIGTERM'`.
         * @since v20.5.0
         */
        [Symbol.dispose](): void;
        /**
         * When an IPC channel has been established between the parent and child (
         * i.e. when using {@link fork}), the `subprocess.send()` method can
         * be used to send messages to the child process. When the child process is a
         * Node.js instance, these messages can be received via the `'message'` event.
         *
         * The message goes through serialization and parsing. The resulting
         * message might not be the same as what is originally sent.
         *
         * For example, in the parent script:
         *
         * ```js
         * import cp from 'node:child_process';
         * const n = cp.fork(`${__dirname}/sub.js`);
         *
         * n.on('message', (m) => {
         *   console.log('PARENT got message:', m);
         * });
         *
         * // Causes the child to print: CHILD got message: { hello: 'world' }
         * n.send({ hello: 'world' });
         * ```
         *
         * And then the child script, `'sub.js'` might look like this:
         *
         * ```js
         * process.on('message', (m) => {
         *   console.log('CHILD got message:', m);
         * });
         *
         * // Causes the parent to print: PARENT got message: { foo: 'bar', baz: null }
         * process.send({ foo: 'bar', baz: NaN });
         * ```
         *
         * Child Node.js processes will have a `process.send()` method of their own
         * that allows the child to send messages back to the parent.
         *
         * There is a special case when sending a `{cmd: 'NODE_foo'}` message. Messages
         * containing a `NODE_` prefix in the `cmd` property are reserved for use within
         * Node.js core and will not be emitted in the child's `'message'` event. Rather, such messages are emitted using the `'internalMessage'` event and are consumed internally by Node.js.
         * Applications should avoid using such messages or listening for `'internalMessage'` events as it is subject to change without notice.
         *
         * The optional `sendHandle` argument that may be passed to `subprocess.send()` is
         * for passing a TCP server or socket object to the child process. The child will
         * receive the object as the second argument passed to the callback function
         * registered on the `'message'` event. Any data that is received and buffered in
         * the socket will not be sent to the child. Sending IPC sockets is not supported on Windows.
         *
         * The optional `callback` is a function that is invoked after the message is
         * sent but before the child may have received it. The function is called with a
         * single argument: `null` on success, or an `Error` object on failure.
         *
         * If no `callback` function is provided and the message cannot be sent, an `'error'` event will be emitted by the `ChildProcess` object. This can
         * happen, for instance, when the child process has already exited.
         *
         * `subprocess.send()` will return `false` if the channel has closed or when the
         * backlog of unsent messages exceeds a threshold that makes it unwise to send
         * more. Otherwise, the method returns `true`. The `callback` function can be
         * used to implement flow control.
         *
         * #### Example: sending a server object
         *
         * The `sendHandle` argument can be used, for instance, to pass the handle of
         * a TCP server object to the child process as illustrated in the example below:
         *
         * ```js
         * import { createServer } from 'node:net';
         * import { fork } from 'node:child_process';
         * const subprocess = fork('subprocess.js');
         *
         * // Open up the server object and send the handle.
         * const server = createServer();
         * server.on('connection', (socket) => {
         *   socket.end('handled by parent');
         * });
         * server.listen(1337, () => {
         *   subprocess.send('server', server);
         * });
         * ```
         *
         * The child would then receive the server object as:
         *
         * ```js
         * process.on('message', (m, server) => {
         *   if (m === 'server') {
         *     server.on('connection', (socket) => {
         *       socket.end('handled by child');
         *     });
         *   }
         * });
         * ```
         *
         * Once the server is now shared between the parent and child, some connections
         * can be handled by the parent and some by the child.
         *
         * While the example above uses a server created using the `node:net` module, `node:dgram` module servers use exactly the same workflow with the exceptions of
         * listening on a `'message'` event instead of `'connection'` and using `server.bind()` instead of `server.listen()`. This is, however, only
         * supported on Unix platforms.
         *
         * #### Example: sending a socket object
         *
         * Similarly, the `sendHandler` argument can be used to pass the handle of a
         * socket to the child process. The example below spawns two children that each
         * handle connections with "normal" or "special" priority:
         *
         * ```js
         * import { createServer } from 'node:net';
         * import { fork } from 'node:child_process';
         * const normal = fork('subprocess.js', ['normal']);
         * const special = fork('subprocess.js', ['special']);
         *
         * // Open up the server and send sockets to child. Use pauseOnConnect to prevent
         * // the sockets from being read before they are sent to the child process.
         * const server = createServer({ pauseOnConnect: true });
         * server.on('connection', (socket) => {
         *
         *   // If this is special priority...
         *   if (socket.remoteAddress === '74.125.127.100') {
         *     special.send('socket', socket);
         *     return;
         *   }
         *   // This is normal priority.
         *   normal.send('socket', socket);
         * });
         * server.listen(1337);
         * ```
         *
         * The `subprocess.js` would receive the socket handle as the second argument
         * passed to the event callback function:
         *
         * ```js
         * process.on('message', (m, socket) => {
         *   if (m === 'socket') {
         *     if (socket) {
         *       // Check that the client socket exists.
         *       // It is possible for the socket to be closed between the time it is
         *       // sent and the time it is received in the child process.
         *       socket.end(`Request handled with ${process.argv[2]} priority`);
         *     }
         *   }
         * });
         * ```
         *
         * Do not use `.maxConnections` on a socket that has been passed to a subprocess.
         * The parent cannot track when the socket is destroyed.
         *
         * Any `'message'` handlers in the subprocess should verify that `socket` exists,
         * as the connection may have been closed during the time it takes to send the
         * connection to the child.
         * @since v0.5.9
         * @param sendHandle `undefined`, or a [`net.Socket`](https://nodejs.org/docs/latest-v26.x/api/net.html#class-netsocket), [`net.Server`](https://nodejs.org/docs/latest-v26.x/api/net.html#class-netserver), or [`dgram.Socket`](https://nodejs.org/docs/latest-v26.x/api/dgram.html#class-dgramsocket) object.
         * @param options The `options` argument, if present, is an object used to parameterize the sending of certain types of handles. `options` supports the following properties:
         */
        send(message: Serializable, callback?: (error: Error | null) => void): boolean;
        send(message: Serializable, sendHandle?: SendHandle, callback?: (error: Error | null) => void): boolean;
        send(
            message: Serializable,
            sendHandle?: SendHandle,
            options?: MessageOptions,
            callback?: (error: Error | null) => void,
        ): boolean;
        /**
         * Closes the IPC channel between parent and child, allowing the child to exit
         * gracefully once there are no other connections keeping it alive. After calling
         * this method the `subprocess.connected` and `process.connected` properties in
         * both the parent and child (respectively) will be set to `false`, and it will be
         * no longer possible to pass messages between the processes.
         *
         * The `'disconnect'` event will be emitted when there are no messages in the
         * process of being received. This will most often be triggered immediately after
         * calling `subprocess.disconnect()`.
         *
         * When the child process is a Node.js instance (e.g. spawned using {@link fork}), the `process.disconnect()` method can be invoked
         * within the child process to close the IPC channel as well.
         * @since v0.7.2
         */
        disconnect(): void;
        /**
         * By default, the parent will wait for the detached child to exit. To prevent the
         * parent from waiting for a given `subprocess` to exit, use the `subprocess.unref()` method. Doing so will cause the parent's event loop to not
         * include the child in its reference count, allowing the parent to exit
         * independently of the child, unless there is an established IPC channel between
         * the child and the parent.
         *
         * ```js
         * import { spawn } from 'node:child_process';
         *
         * const subprocess = spawn(process.argv[0], ['child_program.js'], {
         *   detached: true,
         *   stdio: 'ignore',
         * });
         *
         * subprocess.unref();
         * ```
         * @since v0.7.10
         */
        unref(): void;
        /**
         * Calling `subprocess.ref()` after making a call to `subprocess.unref()` will
         * restore the removed reference count for the child process, forcing the parent
         * to wait for the child to exit before exiting itself.
         *
         * ```js
         * import { spawn } from 'node:child_process';
         *
         * const subprocess = spawn(process.argv[0], ['child_program.js'], {
         *   detached: true,
         *   stdio: 'ignore',
         * });
         *
         * subprocess.unref();
         * subprocess.ref();
         * ```
         * @since v0.7.10
         */
        ref(): void;
    }

interface ChildProcess extends InternalEventEmitter<ChildProcessEventMap> {}
```

## Constants

### default

The default export, declared as `crossSpawn`.

The callable default, with the named exports hung off it.

`compat-oracle` re-exports `default` under the name `'module.exports'`, which is what a
CommonJS `require()` of this module returns whole — so the vendored suite's
`const spawn = require('../../shim.mjs')` gets this function and `spawn.sync` finds the
property below, exactly as it does from `cross-spawn` itself.

```ts
const crossSpawn: typeof spawn & {
    spawn: typeof spawn;
    sync: typeof sync;
    parse: typeof parse;
    _parse: typeof parse;
    _enoent: {
        hookChildProcess: typeof hookChildProcess;
        verifyENOENT: typeof verifyENOENT;
        notFoundError: typeof notFoundError;
    };
};
```

### _enoent

`cross-spawn._enoent`, the shape its dependants import.

```ts
const _enoent: {
    hookChildProcess: typeof hookChildProcess;
    verifyENOENT: typeof verifyENOENT;
    notFoundError: typeof notFoundError;
};
```

### crossSpawn

The callable default, with the named exports hung off it.

`compat-oracle` re-exports `default` under the name `'module.exports'`, which is what a
CommonJS `require()` of this module returns whole — so the vendored suite's
`const spawn = require('../../shim.mjs')` gets this function and `spawn.sync` finds the
property below, exactly as it does from `cross-spawn` itself.

```ts
const crossSpawn: typeof spawn & {
    spawn: typeof spawn;
    sync: typeof sync;
    parse: typeof parse;
    _parse: typeof parse;
    _enoent: {
        hookChildProcess: typeof hookChildProcess;
        verifyENOENT: typeof verifyENOENT;
        notFoundError: typeof notFoundError;
    };
};
```

### module.exports

The callable default, with the named exports hung off it.

`compat-oracle` re-exports `default` under the name `'module.exports'`, which is what a
CommonJS `require()` of this module returns whole — so the vendored suite's
`const spawn = require('../../shim.mjs')` gets this function and `spawn.sync` finds the
property below, exactly as it does from `cross-spawn` itself.

```ts
const crossSpawn: typeof spawn & {
    spawn: typeof spawn;
    sync: typeof sync;
    parse: typeof parse;
    _parse: typeof parse;
    _enoent: {
        hookChildProcess: typeof hookChildProcess;
        verifyENOENT: typeof verifyENOENT;
        notFoundError: typeof notFoundError;
    };
};
```

## Interfaces

### Parsed

What was asked for and what will be run. Mirrors `cross-spawn`'s `parsed` exactly.

```ts
interface Parsed {
    command: string;
    args: string[];
    options: SpawnOptions;
    /**
     * The resolved executable, or `undefined` when nothing resolved. Windows-only, and the
     * flag `enoent.ts` reads: `cmd.exe` exits 1 for a command it could not find, which is
     * indistinguishable from a command that ran and failed unless somebody remembered whether
     * the file was there.
     */
    file: string | undefined;
    /** What the caller wrote, kept for the error message: it names their command, not ours. */
    original: {
        command: string;
        args: string[];
    };
}
```

### SpawnOptions

Options a caller may pass through to `child_process`, plus the two this reads.

```ts
interface SpawnOptions {
    cwd?: string | undefined;
    env?: Record<string, string | undefined> | undefined;
    /**
     * Hand the whole thing to a shell. Off by default and **documented as the injection
     * surface it is**: with it on, an argument is text in a command line and a `;` or a `&`
     * in caller-supplied data is another command. Nothing in this package turns it on to
     * solve a Windows problem — that is what `escape.ts` is for.
     */
    shell?: boolean | string | undefined;
    /** `cross-spawn`'s own test hook: take the `cmd.exe` path even for a `.exe`. */
    forceShell?: boolean | undefined;
    windowsVerbatimArguments?: boolean | undefined;
    [key: string]: unknown;
}
```

### SpawnSyncReturns

```ts
interface SpawnSyncReturns<T> {
        pid: number;
        output: Array<T | null>;
        stdout: T;
        stderr: T;
        status: number | null;
        signal: NodeJS.Signals | null;
        error?: Error;
    }
```
