Socket
Socket
Sign inDemoInstall

execa

Package Overview
Dependencies
Maintainers
2
Versions
57
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

execa - npm Package Compare versions

Comparing version 6.1.0 to 8.0.1

lib/pipe.js

549

index.d.ts

@@ -1,7 +0,8 @@

import {Buffer} from 'node:buffer';
import {ChildProcess} from 'node:child_process';
import {Stream, Readable as ReadableStream} from 'node:stream';
import {type Buffer} from 'node:buffer';
import {type ChildProcess} from 'node:child_process';
import {type Stream, type Readable as ReadableStream, type Writable as WritableStream} from 'node:stream';
export type StdioOption =
| 'pipe'
| 'overlapped'
| 'ipc'

@@ -14,3 +15,23 @@ | 'ignore'

export interface CommonOptions<EncodingType> {
type EncodingOption =
| 'utf8'
// eslint-disable-next-line unicorn/text-encoding-identifier-case
| 'utf-8'
| 'utf16le'
| 'utf-16le'
| 'ucs2'
| 'ucs-2'
| 'latin1'
| 'binary'
| 'ascii'
| 'hex'
| 'base64'
| 'base64url'
| 'buffer'
| null
| undefined;
type DefaultEncodingOption = 'utf8';
type BufferEncodingOption = 'buffer' | null;
export type CommonOptions<EncodingType extends EncodingOption = DefaultEncodingOption> = {
/**

@@ -30,3 +51,3 @@ Kill the spawned process when the parent process exits unless either:

@default false
@default `true` with `$`, `false` otherwise
*/

@@ -38,4 +59,2 @@ readonly preferLocal?: boolean;

Using a `URL` is only supported in Node.js `14.18.0`, `16.14.0` or above.
@default process.cwd()

@@ -70,3 +89,3 @@ */

@default 'pipe'
@default `inherit` with `$`, `pipe` otherwise
*/

@@ -120,4 +139,2 @@ readonly stdin?: StdioOption;

Using a `URL` is only supported in Node.js `14.18.0`, `16.14.0` or above.
@default process.cwd()

@@ -144,3 +161,3 @@ */

*/
readonly stdio?: 'pipe' | 'ignore' | 'inherit' | readonly StdioOption[];
readonly stdio?: 'pipe' | 'overlapped' | 'ignore' | 'inherit' | readonly StdioOption[];

@@ -152,4 +169,2 @@ /**

Requires Node.js `13.2.0` or later.
[More info.](https://nodejs.org/api/child_process.html#child_process_advanced_serialization)

@@ -191,3 +206,3 @@

/**
Specify the character encoding used to decode the `stdout` and `stderr` output. If set to `null`, then `stdout` and `stderr` will be a `Buffer` instead of a string.
Specify the character encoding used to decode the `stdout` and `stderr` output. If set to `'buffer'` or `null`, then `stdout` and `stderr` will be a `Buffer` instead of a string.

@@ -222,8 +237,6 @@ @default 'utf8'

When `AbortController.abort()` is called, [`.isCanceled`](https://github.com/sindresorhus/execa#iscanceled) becomes `false`.
When `AbortController.abort()` is called, [`.isCanceled`](https://github.com/sindresorhus/execa#iscanceled) becomes `true`.
*Requires Node.js 16 or later.*
@example
```js
```
import {execa} from 'execa';

@@ -261,20 +274,47 @@

readonly windowsHide?: boolean;
}
export interface Options<EncodingType = string> extends CommonOptions<EncodingType> {
/**
Print each command on `stderr` before executing it.
This can also be enabled by setting the `NODE_DEBUG=execa` environment variable in the current process.
@default false
*/
readonly verbose?: boolean;
};
export type Options<EncodingType extends EncodingOption = DefaultEncodingOption> = {
/**
Write some input to the `stdin` of your binary.
If the input is a file, use the `inputFile` option instead.
*/
readonly input?: string | Buffer | ReadableStream;
}
export interface SyncOptions<EncodingType = string> extends CommonOptions<EncodingType> {
/**
Use a file as input to the the `stdin` of your binary.
If the input is not a file, use the `input` option instead.
*/
readonly inputFile?: string;
} & CommonOptions<EncodingType>;
export type SyncOptions<EncodingType extends EncodingOption = DefaultEncodingOption> = {
/**
Write some input to the `stdin` of your binary.
If the input is a file, use the `inputFile` option instead.
*/
readonly input?: string | Buffer;
}
export interface NodeOptions<EncodingType = string> extends Options<EncodingType> {
/**
Use a file as input to the the `stdin` of your binary.
If the input is not a file, use the `input` option instead.
*/
readonly inputFile?: string;
} & CommonOptions<EncodingType>;
export type NodeOptions<EncodingType extends EncodingOption = DefaultEncodingOption> = {
/**
The Node.js executable to use.

@@ -292,5 +332,7 @@

readonly nodeOptions?: string[];
}
} & Options<EncodingType>;
export interface ExecaReturnBase<StdoutStderrType> {
type StdoutStderrAll = string | Buffer | undefined;
export type ExecaReturnBase<StdoutStderrType extends StdoutStderrAll> = {
/**

@@ -354,8 +396,12 @@ The file and arguments that were run, for logging purposes.

signalDescription?: string;
}
export interface ExecaSyncReturnValue<StdoutErrorType = string>
extends ExecaReturnBase<StdoutErrorType> {
}
/**
The `cwd` of the command if provided in the command options. Otherwise it is `process.cwd()`.
*/
cwd: string;
};
export type ExecaSyncReturnValue<StdoutStderrType extends StdoutStderrAll = string> = {
} & ExecaReturnBase<StdoutStderrType>;
/**

@@ -371,4 +417,3 @@ Result of a child process execution. On success this is a plain object. On failure this is also an `Error` instance.

*/
export interface ExecaReturnValue<StdoutErrorType = string>
extends ExecaSyncReturnValue<StdoutErrorType> {
export type ExecaReturnValue<StdoutStderrType extends StdoutStderrAll = string> = {
/**

@@ -381,3 +426,3 @@ The output of the process with `stdout` and `stderr` interleaved.

*/
all?: StdoutErrorType;
all?: StdoutStderrType;

@@ -390,7 +435,5 @@ /**

isCanceled: boolean;
}
} & ExecaSyncReturnValue<StdoutStderrType>;
export interface ExecaSyncError<StdoutErrorType = string>
extends Error,
ExecaReturnBase<StdoutErrorType> {
export type ExecaSyncError<StdoutStderrType extends StdoutStderrAll = string> = {
/**

@@ -414,6 +457,5 @@ Error message when the child process failed to run. In addition to the underlying error message, it also contains some information related to why the child process errored.

originalMessage?: string;
}
} & Error & ExecaReturnBase<StdoutStderrType>;
export interface ExecaError<StdoutErrorType = string>
extends ExecaSyncError<StdoutErrorType> {
export type ExecaError<StdoutStderrType extends StdoutStderrAll = string> = {
/**

@@ -426,3 +468,3 @@ The output of the process with `stdout` and `stderr` interleaved.

*/
all?: StdoutErrorType;
all?: StdoutStderrType;

@@ -433,5 +475,5 @@ /**

isCanceled: boolean;
}
} & ExecaSyncError<StdoutStderrType>;
export interface KillOptions {
export type KillOptions = {
/**

@@ -445,5 +487,5 @@ Milliseconds to wait for the child process to terminate before sending `SIGKILL`.

forceKillAfterTimeout?: number | false;
}
};
export interface ExecaChildPromise<StdoutErrorType> {
export type ExecaChildPromise<StdoutStderrType extends StdoutStderrAll> = {
/**

@@ -459,7 +501,7 @@ Stream combining/interleaving [`stdout`](https://nodejs.org/api/child_process.html#child_process_subprocess_stdout) and [`stderr`](https://nodejs.org/api/child_process.html#child_process_subprocess_stderr).

catch<ResultType = never>(
onRejected?: (reason: ExecaError<StdoutErrorType>) => ResultType | PromiseLike<ResultType>
): Promise<ExecaReturnValue<StdoutErrorType> | ResultType>;
onRejected?: (reason: ExecaError<StdoutStderrType>) => ResultType | PromiseLike<ResultType>
): Promise<ExecaReturnValue<StdoutStderrType> | ResultType>;
/**
Same as the original [`child_process#kill()`](https://nodejs.org/api/child_process.html#child_process_subprocess_kill_signal), except if `signal` is `SIGTERM` (the default value) and the child process is not terminated after 5 seconds, force it by sending `SIGKILL`.
Same as the original [`child_process#kill()`](https://nodejs.org/api/child_process.html#child_process_subprocess_kill_signal), except if `signal` is `SIGTERM` (the default value) and the child process is not terminated after 5 seconds, force it by sending `SIGKILL`. Note that this graceful termination does not work on Windows, because Windows [doesn't support signals](https://nodejs.org/api/process.html#process_signal_events) (`SIGKILL` and `SIGTERM` has the same effect of force-killing the process immediately.) If you want to achieve graceful termination on Windows, you have to use other means, such as [`taskkill`](https://github.com/sindresorhus/taskkill).
*/

@@ -469,21 +511,55 @@ kill(signal?: string, options?: KillOptions): void;

/**
Similar to [`childProcess.kill()`](https://nodejs.org/api/child_process.html#child_process_subprocess_kill_signal). This is preferred when cancelling the child process execution as the error is more descriptive and [`childProcessResult.isCanceled`](#iscanceled) is set to `true`.
Similar to [`childProcess.kill()`](https://nodejs.org/api/child_process.html#child_process_subprocess_kill_signal). This used to be preferred when cancelling the child process execution as the error is more descriptive and [`childProcessResult.isCanceled`](#iscanceled) is set to `true`. But now this is deprecated and you should either use `.kill()` or the `signal` option when creating the child process.
*/
cancel(): void;
}
export type ExecaChildProcess<StdoutErrorType = string> = ChildProcess &
ExecaChildPromise<StdoutErrorType> &
Promise<ExecaReturnValue<StdoutErrorType>>;
/**
[Pipe](https://nodejs.org/api/stream.html#readablepipedestination-options) the child process's `stdout` to `target`, which can be:
- Another `execa()` return value
- A writable stream
- A file path string
If the `target` is another `execa()` return value, it is returned. Otherwise, the original `execa()` return value is returned. This allows chaining `pipeStdout()` then `await`ing the final result.
The `stdout` option] must be kept as `pipe`, its default value.
*/
pipeStdout?<Target extends ExecaChildPromise<StdoutStderrAll>>(target: Target): Target;
pipeStdout?(target: WritableStream | string): ExecaChildProcess<StdoutStderrType>;
/**
Like `pipeStdout()` but piping the child process's `stderr` instead.
The `stderr` option must be kept as `pipe`, its default value.
*/
pipeStderr?<Target extends ExecaChildPromise<StdoutStderrAll>>(target: Target): Target;
pipeStderr?(target: WritableStream | string): ExecaChildProcess<StdoutStderrType>;
/**
Combines both `pipeStdout()` and `pipeStderr()`.
Either the `stdout` option or the `stderr` option must be kept as `pipe`, their default value. Also, the `all` option must be set to `true`.
*/
pipeAll?<Target extends ExecaChildPromise<StdoutStderrAll>>(target: Target): Target;
pipeAll?(target: WritableStream | string): ExecaChildProcess<StdoutStderrType>;
};
export type ExecaChildProcess<StdoutStderrType extends StdoutStderrAll = string> = ChildProcess &
ExecaChildPromise<StdoutStderrType> &
Promise<ExecaReturnValue<StdoutStderrType>>;
/**
Execute a file.
Executes a command using `file ...arguments`. `arguments` are specified as an array of strings. Returns a `childProcess`.
Think of this as a mix of `child_process.execFile` and `child_process.spawn`.
Arguments are automatically escaped. They can contain any character, including spaces.
This is the preferred method when executing single commands.
@param file - The program/script to execute.
@param arguments - Arguments to pass to `file` on execution.
@returns A [`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess), which is enhanced to also be a `Promise` for a result `Object` with `stdout` and `stderr` properties.
@returns An `ExecaChildProcess` that is both:
- a `Promise` resolving or rejecting with a `childProcessResult`.
- a [`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess) with some additional methods and properties.
@throws A `childProcessResult` error
@example
@example <caption>Promise interface</caption>
```

@@ -495,21 +571,91 @@ import {execa} from 'execa';

//=> 'unicorns'
```
// Cancelling a spawned process
@example <caption>Redirect output to a file</caption>
```
import {execa} from 'execa';
const subprocess = execa('node');
// Similar to `echo unicorns > stdout.txt` in Bash
await execa('echo', ['unicorns']).pipeStdout('stdout.txt');
setTimeout(() => {
subprocess.cancel()
}, 1000);
// Similar to `echo unicorns 2> stdout.txt` in Bash
await execa('echo', ['unicorns']).pipeStderr('stderr.txt');
// Similar to `echo unicorns &> stdout.txt` in Bash
await execa('echo', ['unicorns'], {all: true}).pipeAll('all.txt');
```
@example <caption>Redirect input from a file</caption>
```
import {execa} from 'execa';
// Similar to `cat < stdin.txt` in Bash
const {stdout} = await execa('cat', {inputFile: 'stdin.txt'});
console.log(stdout);
//=> 'unicorns'
```
@example <caption>Save and pipe output from a child process</caption>
```
import {execa} from 'execa';
const {stdout} = await execa('echo', ['unicorns']).pipeStdout(process.stdout);
// Prints `unicorns`
console.log(stdout);
// Also returns 'unicorns'
```
@example <caption>Pipe multiple processes</caption>
```
import {execa} from 'execa';
// Similar to `echo unicorns | cat` in Bash
const {stdout} = await execa('echo', ['unicorns']).pipeStdout(execa('cat'));
console.log(stdout);
//=> 'unicorns'
```
@example <caption>Handling errors</caption>
```
import {execa} from 'execa';
// Catching an error
try {
await subprocess;
await execa('unknown', ['command']);
} catch (error) {
console.log(subprocess.killed); // true
console.log(error.isCanceled); // true
console.log(error);
/*
{
message: 'Command failed with ENOENT: unknown command spawn unknown ENOENT',
errno: -2,
code: 'ENOENT',
syscall: 'spawn unknown',
path: 'unknown',
spawnargs: ['command'],
originalMessage: 'spawn unknown ENOENT',
shortMessage: 'Command failed with ENOENT: unknown command spawn unknown ENOENT',
command: 'unknown command',
escapedCommand: 'unknown command',
stdout: '',
stderr: '',
failed: true,
timedOut: false,
isCanceled: false,
killed: false,
cwd: '/path/to/cwd'
}
\*\/
}
```
// Pipe the child process stdout to the current stdout
execa('echo', ['unicorns']).stdout.pipe(process.stdout);
@example <caption>Graceful termination</caption>
```
const subprocess = execa('node');
setTimeout(() => {
subprocess.kill('SIGTERM', {
forceKillAfterTimeout: 2000
});
}, 1000);
```
*/

@@ -524,15 +670,66 @@ export function execa(

arguments?: readonly string[],
options?: Options<null>
options?: Options<BufferEncodingOption>
): ExecaChildProcess<Buffer>;
export function execa(file: string, options?: Options): ExecaChildProcess;
export function execa(file: string, options?: Options<null>): ExecaChildProcess<Buffer>;
export function execa(file: string, options?: Options<BufferEncodingOption>): ExecaChildProcess<Buffer>;
/**
Execute a file synchronously.
Same as `execa()` but synchronous.
This method throws an `Error` if the command fails.
@param file - The program/script to execute.
@param arguments - Arguments to pass to `file` on execution.
@returns A result `Object` with `stdout` and `stderr` properties.
@returns A `childProcessResult` object
@throws A `childProcessResult` error
@example <caption>Promise interface</caption>
```
import {execa} from 'execa';
const {stdout} = execaSync('echo', ['unicorns']);
console.log(stdout);
//=> 'unicorns'
```
@example <caption>Redirect input from a file</caption>
```
import {execa} from 'execa';
// Similar to `cat < stdin.txt` in Bash
const {stdout} = execaSync('cat', {inputFile: 'stdin.txt'});
console.log(stdout);
//=> 'unicorns'
```
@example <caption>Handling errors</caption>
```
import {execa} from 'execa';
// Catching an error
try {
execaSync('unknown', ['command']);
} catch (error) {
console.log(error);
/*
{
message: 'Command failed with ENOENT: unknown command spawnSync unknown ENOENT',
errno: -2,
code: 'ENOENT',
syscall: 'spawnSync unknown',
path: 'unknown',
spawnargs: ['command'],
originalMessage: 'spawnSync unknown ENOENT',
shortMessage: 'Command failed with ENOENT: unknown command spawnSync unknown ENOENT',
command: 'unknown command',
escapedCommand: 'unknown command',
stdout: '',
stderr: '',
failed: true,
timedOut: false,
isCanceled: false,
killed: false,
cwd: '/path/to/cwd'
}
\*\/
}
```
*/

@@ -547,3 +744,3 @@ export function execaSync(

arguments?: readonly string[],
options?: SyncOptions<null>
options?: SyncOptions<BufferEncodingOption>
): ExecaSyncReturnValue<Buffer>;

@@ -553,14 +750,17 @@ export function execaSync(file: string, options?: SyncOptions): ExecaSyncReturnValue;

file: string,
options?: SyncOptions<null>
options?: SyncOptions<BufferEncodingOption>
): ExecaSyncReturnValue<Buffer>;
/**
Same as `execa()` except both file and arguments are specified in a single `command` string. For example, `execa('echo', ['unicorns'])` is the same as `execaCommand('echo unicorns')`.
Executes a command. The `command` string includes both the `file` and its `arguments`. Returns a `childProcess`.
If the file or an argument contains spaces, they must be escaped with backslashes. This matters especially if `command` is not a constant but a variable, for example with `__dirname` or `process.cwd()`. Except for spaces, no escaping/quoting is needed.
Arguments are automatically escaped. They can contain any character, but spaces must be escaped with a backslash like `execaCommand('echo has\\ space')`.
The `shell` option must be used if the `command` uses shell-specific features (for example, `&&` or `||`), as opposed to being a simple `file` followed by its `arguments`.
This is the preferred method when executing a user-supplied `command` string, such as in a REPL.
@param command - The program/script to execute and its arguments.
@returns A [`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess), which is enhanced to also be a `Promise` for a result `Object` with `stdout` and `stderr` properties.
@returns An `ExecaChildProcess` that is both:
- a `Promise` resolving or rejecting with a `childProcessResult`.
- a [`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess) with some additional methods and properties.
@throws A `childProcessResult` error

@@ -577,3 +777,3 @@ @example

export function execaCommand(command: string, options?: Options): ExecaChildProcess;
export function execaCommand(command: string, options?: Options<null>): ExecaChildProcess<Buffer>;
export function execaCommand(command: string, options?: Options<BufferEncodingOption>): ExecaChildProcess<Buffer>;

@@ -584,18 +784,187 @@ /**

@param command - The program/script to execute and its arguments.
@returns A result `Object` with `stdout` and `stderr` properties.
@returns A `childProcessResult` object
@throws A `childProcessResult` error
@example
```
import {execaCommandSync} from 'execa';
const {stdout} = execaCommandSync('echo unicorns');
console.log(stdout);
//=> 'unicorns'
```
*/
export function execaCommandSync(command: string, options?: SyncOptions): ExecaSyncReturnValue;
export function execaCommandSync(command: string, options?: SyncOptions<null>): ExecaSyncReturnValue<Buffer>;
export function execaCommandSync(command: string, options?: SyncOptions<BufferEncodingOption>): ExecaSyncReturnValue<Buffer>;
type TemplateExpression =
| string
| number
| ExecaReturnValue<string | Buffer>
| ExecaSyncReturnValue<string | Buffer>
| Array<string | number | ExecaReturnValue<string | Buffer> | ExecaSyncReturnValue<string | Buffer>>;
type Execa$<StdoutStderrType extends StdoutStderrAll = string> = {
/**
Returns a new instance of `$` but with different default `options`. Consecutive calls are merged to previous ones.
This can be used to either:
- Set options for a specific command: `` $(options)`command` ``
- Share options for multiple commands: `` const $$ = $(options); $$`command`; $$`otherCommand` ``
@param options - Options to set
@returns A new instance of `$` with those `options` set
@example
```
import {$} from 'execa';
const $$ = $({stdio: 'inherit'});
await $$`echo unicorns`;
//=> 'unicorns'
await $$`echo rainbows`;
//=> 'rainbows'
```
*/
(options: Options<undefined>): Execa$<StdoutStderrType>;
(options: Options): Execa$;
(options: Options<BufferEncodingOption>): Execa$<Buffer>;
(
templates: TemplateStringsArray,
...expressions: TemplateExpression[]
): ExecaChildProcess<StdoutStderrType>;
/**
Same as $\`command\` but synchronous.
@returns A `childProcessResult` object
@throws A `childProcessResult` error
@example <caption>Basic</caption>
```
import {$} from 'execa';
const branch = $.sync`git branch --show-current`;
$.sync`dep deploy --branch=${branch}`;
```
@example <caption>Multiple arguments</caption>
```
import {$} from 'execa';
const args = ['unicorns', '&', 'rainbows!'];
const {stdout} = $.sync`echo ${args}`;
console.log(stdout);
//=> 'unicorns & rainbows!'
```
@example <caption>With options</caption>
```
import {$} from 'execa';
$.sync({stdio: 'inherit'})`echo unicorns`;
//=> 'unicorns'
```
@example <caption>Shared options</caption>
```
import {$} from 'execa';
const $$ = $({stdio: 'inherit'});
$$.sync`echo unicorns`;
//=> 'unicorns'
$$.sync`echo rainbows`;
//=> 'rainbows'
```
*/
sync(
templates: TemplateStringsArray,
...expressions: TemplateExpression[]
): ExecaSyncReturnValue<StdoutStderrType>;
};
/**
Executes a command. The `command` string includes both the `file` and its `arguments`. Returns a `childProcess`.
Arguments are automatically escaped. They can contain any character, but spaces must use `${}` like `` $`echo ${'has space'}` ``.
This is the preferred method when executing multiple commands in a script file.
The `command` string can inject any `${value}` with the following types: string, number, `childProcess` or an array of those types. For example: `` $`echo one ${'two'} ${3} ${['four', 'five']}` ``. For `${childProcess}`, the process's `stdout` is used.
@returns An `ExecaChildProcess` that is both:
- a `Promise` resolving or rejecting with a `childProcessResult`.
- a [`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess) with some additional methods and properties.
@throws A `childProcessResult` error
@example <caption>Basic</caption>
```
import {$} from 'execa';
const branch = await $`git branch --show-current`;
await $`dep deploy --branch=${branch}`;
```
@example <caption>Multiple arguments</caption>
```
import {$} from 'execa';
const args = ['unicorns', '&', 'rainbows!'];
const {stdout} = await $`echo ${args}`;
console.log(stdout);
//=> 'unicorns & rainbows!'
```
@example <caption>With options</caption>
```
import {$} from 'execa';
await $({stdio: 'inherit'})`echo unicorns`;
//=> 'unicorns'
```
@example <caption>Shared options</caption>
```
import {$} from 'execa';
const $$ = $({stdio: 'inherit'});
await $$`echo unicorns`;
//=> 'unicorns'
await $$`echo rainbows`;
//=> 'rainbows'
```
*/
export const $: Execa$;
/**
Execute a Node.js script as a child process.
Same as `execa('node', [scriptPath, ...arguments], options)` except (like [`child_process#fork()`](https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options)):
- the current Node version and options are used. This can be overridden using the `nodePath` and `nodeArguments` options.
- the `shell` option cannot be used
- an extra channel [`ipc`](https://nodejs.org/api/child_process.html#child_process_options_stdio) is passed to [`stdio`](#stdio)
Arguments are automatically escaped. They can contain any character, including spaces.
This is the preferred method when executing Node.js files.
Like [`child_process#fork()`](https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options):
- the current Node version and options are used. This can be overridden using the `nodePath` and `nodeOptions` options.
- the `shell` option cannot be used
- an extra channel [`ipc`](https://nodejs.org/api/child_process.html#child_process_options_stdio) is passed to `stdio`
@param scriptPath - Node.js script to execute.
@param arguments - Arguments to pass to `scriptPath` on execution.
@returns A [`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess), which is enhanced to also be a `Promise` for a result `Object` with `stdout` and `stderr` properties.
@returns An `ExecaChildProcess` that is both:
- a `Promise` resolving or rejecting with a `childProcessResult`.
- a [`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess) with some additional methods and properties.
@throws A `childProcessResult` error
@example
```
import {execa} from 'execa';
await execaNode('scriptPath', ['argument']);
```
*/

@@ -610,5 +979,5 @@ export function execaNode(

arguments?: readonly string[],
options?: Options<null>
options?: NodeOptions<BufferEncodingOption>
): ExecaChildProcess<Buffer>;
export function execaNode(scriptPath: string, options?: Options): ExecaChildProcess;
export function execaNode(scriptPath: string, options?: Options<null>): ExecaChildProcess<Buffer>;
export function execaNode(scriptPath: string, options?: NodeOptions): ExecaChildProcess;
export function execaNode(scriptPath: string, options?: NodeOptions<BufferEncodingOption>): ExecaChildProcess<Buffer>;

@@ -12,5 +12,7 @@ import {Buffer} from 'node:buffer';

import {spawnedKill, spawnedCancel, setupTimeout, validateTimeout, setExitHandler} from './lib/kill.js';
import {handleInput, getSpawnedResult, makeAllStream, validateInputSync} from './lib/stream.js';
import {addPipeMethods} from './lib/pipe.js';
import {handleInput, getSpawnedResult, makeAllStream, handleInputSync} from './lib/stream.js';
import {mergePromise, getSpawnedPromise} from './lib/promise.js';
import {joinCommand, parseCommand, getEscapedCommand} from './lib/command.js';
import {joinCommand, parseCommand, parseTemplates, getEscapedCommand} from './lib/command.js';
import {logCommand, verboseDefault} from './lib/verbose.js';

@@ -48,2 +50,3 @@ const DEFAULT_MAX_BUFFER = 1000 * 1000 * 100;

windowsHide: true,
verbose: verboseDefault,
...options,

@@ -81,2 +84,3 @@ };

const escapedCommand = getEscapedCommand(file, args);
logCommand(escapedCommand, parsed.options);

@@ -103,3 +107,4 @@ validateTimeout(parsed.options);

}));
return mergePromise(dummySpawned, errorPromise);
mergePromise(dummySpawned, errorPromise);
return dummySpawned;
}

@@ -161,7 +166,9 @@

handleInput(spawned, parsed.options.input);
handleInput(spawned, parsed.options);
spawned.all = makeAllStream(spawned, parsed.options);
return mergePromise(spawned, handlePromiseOnce);
addPipeMethods(spawned);
mergePromise(spawned, handlePromiseOnce);
return spawned;
}

@@ -173,8 +180,9 @@

const escapedCommand = getEscapedCommand(file, args);
logCommand(escapedCommand, parsed.options);
validateInputSync(parsed.options);
const input = handleInputSync(parsed.options);
let result;
try {
result = childProcess.spawnSync(parsed.file, parsed.args, parsed.options);
result = childProcess.spawnSync(parsed.file, parsed.args, {...parsed.options, input});
} catch (error) {

@@ -233,2 +241,36 @@ throw makeError({

const normalizeScriptStdin = ({input, inputFile, stdio}) => input === undefined && inputFile === undefined && stdio === undefined
? {stdin: 'inherit'}
: {};
const normalizeScriptOptions = (options = {}) => ({
preferLocal: true,
...normalizeScriptStdin(options),
...options,
});
function create$(options) {
function $(templatesOrOptions, ...expressions) {
if (!Array.isArray(templatesOrOptions)) {
return create$({...options, ...templatesOrOptions});
}
const [file, ...args] = parseTemplates(templatesOrOptions, expressions);
return execa(file, args, normalizeScriptOptions(options));
}
$.sync = (templates, ...expressions) => {
if (!Array.isArray(templates)) {
throw new TypeError('Please use $(options).sync`command` instead of $.sync(options)`command`.');
}
const [file, ...args] = parseTemplates(templates, expressions);
return execaSync(file, args, normalizeScriptOptions(options));
};
return $;
}
export const $ = create$();
export function execaCommand(command, options) {

@@ -235,0 +277,0 @@ const [file, ...args] = parseCommand(command);

@@ -0,1 +1,4 @@

import {Buffer} from 'node:buffer';
import {ChildProcess} from 'node:child_process';
const normalizeArgs = (file, args = []) => {

@@ -10,3 +13,2 @@ if (!Array.isArray(args)) {

const NO_ESCAPE_REGEXP = /^[\w.-]+$/;
const DOUBLE_QUOTES_REGEXP = /"/g;

@@ -18,3 +20,3 @@ const escapeArg = arg => {

return `"${arg.replace(DOUBLE_QUOTES_REGEXP, '\\"')}"`;
return `"${arg.replaceAll('"', '\\"')}"`;
};

@@ -33,3 +35,3 @@

// Allow spaces to be escaped by a backslash if not meant as a delimiter
const previousToken = tokens[tokens.length - 1];
const previousToken = tokens.at(-1);
if (previousToken && previousToken.endsWith('\\')) {

@@ -45,1 +47,77 @@ // Merge previous token with current one

};
const parseExpression = expression => {
const typeOfExpression = typeof expression;
if (typeOfExpression === 'string') {
return expression;
}
if (typeOfExpression === 'number') {
return String(expression);
}
if (
typeOfExpression === 'object'
&& expression !== null
&& !(expression instanceof ChildProcess)
&& 'stdout' in expression
) {
const typeOfStdout = typeof expression.stdout;
if (typeOfStdout === 'string') {
return expression.stdout;
}
if (Buffer.isBuffer(expression.stdout)) {
return expression.stdout.toString();
}
throw new TypeError(`Unexpected "${typeOfStdout}" stdout in template expression`);
}
throw new TypeError(`Unexpected "${typeOfExpression}" in template expression`);
};
const concatTokens = (tokens, nextTokens, isNew) => isNew || tokens.length === 0 || nextTokens.length === 0
? [...tokens, ...nextTokens]
: [
...tokens.slice(0, -1),
`${tokens.at(-1)}${nextTokens[0]}`,
...nextTokens.slice(1),
];
const parseTemplate = ({templates, expressions, tokens, index, template}) => {
const templateString = template ?? templates.raw[index];
const templateTokens = templateString.split(SPACES_REGEXP).filter(Boolean);
const newTokens = concatTokens(
tokens,
templateTokens,
templateString.startsWith(' '),
);
if (index === expressions.length) {
return newTokens;
}
const expression = expressions[index];
const expressionTokens = Array.isArray(expression)
? expression.map(expression => parseExpression(expression))
: [parseExpression(expression)];
return concatTokens(
newTokens,
expressionTokens,
templateString.endsWith(' '),
);
};
export const parseTemplates = (templates, expressions) => {
let tokens = [];
for (const [index, template] of templates.entries()) {
tokens = parseTemplate({templates, expressions, tokens, index, template});
}
return tokens;
};

4

lib/error.js

@@ -0,1 +1,2 @@

import process from 'node:process';
import {signalsByName} from 'human-signals';

@@ -39,3 +40,3 @@

killed,
parsed: {options: {timeout}},
parsed: {options: {timeout, cwd = process.cwd()}},
}) => {

@@ -71,2 +72,3 @@ // `signal` and `exitCode` emitted on `spawned.on('exit')` event can be `null`.

error.stderr = stderr;
error.cwd = cwd;

@@ -73,0 +75,0 @@ if (all !== undefined) {

import os from 'node:os';
import onExit from 'signal-exit';
import {onExit} from 'signal-exit';

@@ -4,0 +4,0 @@ const DEFAULT_FORCE_KILL_TIMEOUT = 1000 * 5;

@@ -0,2 +1,4 @@

// eslint-disable-next-line unicorn/prefer-top-level-await
const nativePromisePrototype = (async () => {})().constructor.prototype;
const descriptors = ['then', 'catch', 'finally'].map(property => [

@@ -17,4 +19,2 @@ property,

}
return spawned;
};

@@ -21,0 +21,0 @@

@@ -0,10 +1,47 @@

import {createReadStream, readFileSync} from 'node:fs';
import {setTimeout} from 'node:timers/promises';
import {isStream} from 'is-stream';
import getStream from 'get-stream';
import getStream, {getStreamAsBuffer} from 'get-stream';
import mergeStream from 'merge-stream';
// `input` option
export const handleInput = (spawned, input) => {
// Checking for stdin is workaround for https://github.com/nodejs/node/issues/26852
// @todo remove `|| spawned.stdin === undefined` once we drop support for Node.js <=12.2.0
if (input === undefined || spawned.stdin === undefined) {
const validateInputOptions = input => {
if (input !== undefined) {
throw new TypeError('The `input` and `inputFile` options cannot be both set.');
}
};
const getInputSync = ({input, inputFile}) => {
if (typeof inputFile !== 'string') {
return input;
}
validateInputOptions(input);
return readFileSync(inputFile);
};
// `input` and `inputFile` option in sync mode
export const handleInputSync = options => {
const input = getInputSync(options);
if (isStream(input)) {
throw new TypeError('The `input` option cannot be a stream in sync mode');
}
return input;
};
const getInput = ({input, inputFile}) => {
if (typeof inputFile !== 'string') {
return input;
}
validateInputOptions(input);
return createReadStream(inputFile);
};
// `input` and `inputFile` option in async mode
export const handleInput = (spawned, options) => {
const input = getInput(options);
if (input === undefined) {
return;

@@ -41,6 +78,10 @@ }

const getBufferedData = async (stream, streamPromise) => {
if (!stream) {
// When `buffer` is `false`, `streamPromise` is `undefined` and there is no buffered data to retrieve
if (!stream || streamPromise === undefined) {
return;
}
// Wait for the `all` stream to receive the last chunk before destroying the stream
await setTimeout(0);
stream.destroy();

@@ -60,9 +101,19 @@

if (encoding) {
return getStream(stream, {encoding, maxBuffer});
// eslint-disable-next-line unicorn/text-encoding-identifier-case
if (encoding === 'utf8' || encoding === 'utf-8') {
return getStream(stream, {maxBuffer});
}
return getStream.buffer(stream, {maxBuffer});
if (encoding === null || encoding === 'buffer') {
return getStreamAsBuffer(stream, {maxBuffer});
}
return applyEncoding(stream, maxBuffer, encoding);
};
const applyEncoding = async (stream, maxBuffer, encoding) => {
const buffer = await getStreamAsBuffer(stream, {maxBuffer});
return buffer.toString(encoding);
};
// Retrieve result of child process: exit code, signal, error, streams (stdout/stderr/all)

@@ -85,7 +136,1 @@ export const getSpawnedResult = async ({stdout, stderr, all}, {encoding, buffer, maxBuffer}, processDone) => {

};
export const validateInputSync = ({input}) => {
if (isStream(input)) {
throw new TypeError('The `input` option cannot be a stream in sync mode');
}
};
{
"name": "execa",
"version": "6.1.0",
"version": "8.0.1",
"description": "Process execution for humans",

@@ -14,5 +14,8 @@ "license": "MIT",

"type": "module",
"exports": "./index.js",
"exports": {
"types": "./index.d.ts",
"default": "./index.js"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
"node": ">=16.17"
},

@@ -42,8 +45,9 @@ "scripts": {

"path",
"local"
"local",
"zx"
],
"dependencies": {
"cross-spawn": "^7.0.3",
"get-stream": "^6.0.1",
"human-signals": "^3.0.1",
"get-stream": "^8.0.1",
"human-signals": "^5.0.0",
"is-stream": "^3.0.0",

@@ -53,16 +57,16 @@ "merge-stream": "^2.0.0",

"onetime": "^6.0.0",
"signal-exit": "^3.0.7",
"signal-exit": "^4.1.0",
"strip-final-newline": "^3.0.0"
},
"devDependencies": {
"@types/node": "^17.0.17",
"ava": "^4.0.1",
"c8": "^7.11.0",
"get-node": "^12.0.0",
"@types/node": "^20.4.0",
"ava": "^5.2.0",
"c8": "^8.0.1",
"get-node": "^14.2.0",
"is-running": "^2.1.0",
"p-event": "^5.0.1",
"semver": "^7.3.5",
"tempfile": "^4.0.0",
"tsd": "^0.19.1",
"xo": "^0.48.0"
"p-event": "^6.0.0",
"path-key": "^4.0.0",
"tempfile": "^5.0.0",
"tsd": "^0.28.1",
"xo": "^0.55.0"
},

@@ -80,2 +84,5 @@ "c8": {

},
"ava": {
"workerThreads": false
},
"xo": {

@@ -82,0 +89,0 @@ "rules": {

@@ -1,2 +0,5 @@

<img src="media/logo.svg" width="400">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="media/logo_dark.svg">
<img alt="execa logo" src="media/logo.svg" width="400">
</picture>
<br>

@@ -8,2 +11,32 @@

<br>
---
<div align="center">
<p>
<p>
<sup>
<a href="https://github.com/sponsors/sindresorhus">Sindre's open source work is supported by the community</a>
</sup>
</p>
<sup>Special thanks to:</sup>
<br>
<br>
<a href="https://transloadit.com?utm_source=sindresorhus&utm_medium=referral&utm_campaign=sponsorship&utm_content=execa">
<picture>
<source width="360" media="(prefers-color-scheme: dark)" srcset="https://sindresorhus.com/assets/thanks/transloadit-logo-dark.svg">
<source width="360" media="(prefers-color-scheme: light)" srcset="https://sindresorhus.com/assets/thanks/transloadit-logo.svg">
<img width="360" src="https://sindresorhus.com/assets/thanks/transloadit-logo.svg" alt="Transloadit logo">
</picture>
</a>
<br>
<br>
</p>
</div>
---
<br>
## Why

@@ -13,12 +46,15 @@

- Promise interface.
- [Promise interface](#execacommandcommand-options).
- [Scripts interface](#scripts-interface), like `zx`.
- Improved [Windows support](https://github.com/IndigoUnited/node-cross-spawn#why), including [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) binaries.
- Executes [locally installed binaries](#preferlocal) without `npx`.
- [Cleans up](#cleanup) child processes when the parent process ends.
- [Graceful termination](#optionsforcekillaftertimeout).
- Get [interleaved output](#all) from `stdout` and `stderr` similar to what is printed on the terminal.
- [Strips the final newline](#stripfinalnewline) from the output so you don't have to do `stdout.trim()`.
- Supports [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) binaries cross-platform.
- [Improved Windows support.](https://github.com/IndigoUnited/node-cross-spawn#why)
- Higher max buffer. 100 MB instead of 200 KB.
- [Executes locally installed binaries by name.](#preferlocal)
- [Cleans up spawned processes when the parent process dies.](#cleanup)
- [Get interleaved output](#all) from `stdout` and `stderr` similar to what is printed on the terminal. [*(Async only)*](#execasyncfile-arguments-options)
- [Can specify file and arguments as a single string without a shell](#execacommandcommand-options)
- Convenience methods to pipe processes' [input](#input) and [output](#redirect-output-to-a-file).
- Can specify file and arguments [as a single string](#execacommandcommand-options) without a shell.
- [Verbose mode](#verbose-mode) for debugging.
- More descriptive errors.
- Higher max buffer: 100 MB instead of 1 MB.

@@ -33,2 +69,4 @@ ## Install

### Promise interface
```js

@@ -42,11 +80,81 @@ import {execa} from 'execa';

### Pipe the child process stdout to the parent
### Scripts interface
For more information about Execa scripts, please see [this page](docs/scripts.md).
#### Basic
```js
import {$} from 'execa';
const branch = await $`git branch --show-current`;
await $`dep deploy --branch=${branch}`;
```
#### Multiple arguments
```js
import {$} from 'execa';
const args = ['unicorns', '&', 'rainbows!'];
const {stdout} = await $`echo ${args}`;
console.log(stdout);
//=> 'unicorns & rainbows!'
```
#### With options
```js
import {$} from 'execa';
await $({stdio: 'inherit'})`echo unicorns`;
//=> 'unicorns'
```
#### Shared options
```js
import {$} from 'execa';
const $$ = $({stdio: 'inherit'});
await $$`echo unicorns`;
//=> 'unicorns'
await $$`echo rainbows`;
//=> 'rainbows'
```
#### Verbose mode
```sh
> node file.js
unicorns
rainbows
> NODE_DEBUG=execa node file.js
[16:50:03.305] echo unicorns
unicorns
[16:50:03.308] echo rainbows
rainbows
```
### Input/output
#### Redirect output to a file
```js
import {execa} from 'execa';
execa('echo', ['unicorns']).stdout.pipe(process.stdout);
// Similar to `echo unicorns > stdout.txt` in Bash
await execa('echo', ['unicorns']).pipeStdout('stdout.txt');
// Similar to `echo unicorns 2> stdout.txt` in Bash
await execa('echo', ['unicorns']).pipeStderr('stderr.txt');
// Similar to `echo unicorns &> stdout.txt` in Bash
await execa('echo', ['unicorns'], {all: true}).pipeAll('all.txt');
```
### Handling Errors
#### Redirect input from a file

@@ -56,32 +164,9 @@ ```js

// Catching an error
try {
await execa('unknown', ['command']);
} catch (error) {
console.log(error);
/*
{
message: 'Command failed with ENOENT: unknown command spawn unknown ENOENT',
errno: -2,
code: 'ENOENT',
syscall: 'spawn unknown',
path: 'unknown',
spawnargs: ['command'],
originalMessage: 'spawn unknown ENOENT',
shortMessage: 'Command failed with ENOENT: unknown command spawn unknown ENOENT',
command: 'unknown command',
escapedCommand: 'unknown command',
stdout: '',
stderr: '',
all: '',
failed: true,
timedOut: false,
isCanceled: false,
killed: false
}
*/
}
// Similar to `cat < stdin.txt` in Bash
const {stdout} = await execa('cat', {inputFile: 'stdin.txt'});
console.log(stdout);
//=> 'unicorns'
```
### Cancelling a spawned process
#### Save and pipe output from a child process

@@ -91,24 +176,27 @@ ```js

const abortController = new AbortController();
const subprocess = execa('node', [], {signal: abortController.signal});
const {stdout} = await execa('echo', ['unicorns']).pipeStdout(process.stdout);
// Prints `unicorns`
console.log(stdout);
// Also returns 'unicorns'
```
setTimeout(() => {
abortController.abort();
}, 1000);
#### Pipe multiple processes
try {
await subprocess;
} catch (error) {
console.log(subprocess.killed); // true
console.log(error.isCanceled); // true
}
```js
import {execa} from 'execa';
// Similar to `echo unicorns | cat` in Bash
const {stdout} = await execa('echo', ['unicorns']).pipeStdout(execa('cat'));
console.log(stdout);
//=> 'unicorns'
```
### Catching an error with the sync method
### Handling Errors
```js
import {execaSync} from 'execa';
import {execa} from 'execa';
// Catching an error
try {
execaSync('unknown', ['command']);
await execa('unknown', ['command']);
} catch (error) {

@@ -118,10 +206,10 @@ console.log(error);

{
message: 'Command failed with ENOENT: unknown command spawnSync unknown ENOENT',
message: 'Command failed with ENOENT: unknown command spawn unknown ENOENT',
errno: -2,
code: 'ENOENT',
syscall: 'spawnSync unknown',
syscall: 'spawn unknown',
path: 'unknown',
spawnargs: ['command'],
originalMessage: 'spawnSync unknown ENOENT',
shortMessage: 'Command failed with ENOENT: unknown command spawnSync unknown ENOENT',
originalMessage: 'spawn unknown ENOENT',
shortMessage: 'Command failed with ENOENT: unknown command spawn unknown ENOENT',
command: 'unknown command',

@@ -131,3 +219,2 @@ escapedCommand: 'unknown command',

stderr: '',
all: '',
failed: true,

@@ -142,3 +229,3 @@ timedOut: false,

### Kill a process
### Graceful termination

@@ -159,14 +246,81 @@ Using SIGTERM, and after 2 seconds, kill it with SIGKILL.

### execa(file, arguments, options?)
### Methods
Execute a file. Think of this as a mix of [`child_process.execFile()`](https://nodejs.org/api/child_process.html#child_process_child_process_execfile_file_args_options_callback) and [`child_process.spawn()`](https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options).
#### execa(file, arguments?, options?)
No escaping/quoting is needed.
Executes a command using `file ...arguments`. `arguments` are specified as an array of strings. Returns a [`childProcess`](#childprocess).
Unless the [`shell`](#shell) option is used, no shell interpreter (Bash, `cmd.exe`, etc.) is used, so shell features such as variables substitution (`echo $PATH`) are not allowed.
Arguments are [automatically escaped](#shell-syntax). They can contain any character, including spaces.
Returns a [`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess) which:
- is also a `Promise` resolving or rejecting with a [`childProcessResult`](#childProcessResult).
- exposes the following additional methods and properties.
This is the preferred method when executing single commands.
#### execaNode(scriptPath, arguments?, options?)
Executes a Node.js file using `node scriptPath ...arguments`. `arguments` are specified as an array of strings. Returns a [`childProcess`](#childprocess).
Arguments are [automatically escaped](#shell-syntax). They can contain any character, including spaces.
This is the preferred method when executing Node.js files.
Like [`child_process#fork()`](https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options):
- the current Node version and options are used. This can be overridden using the [`nodePath`](#nodepath-for-node-only) and [`nodeOptions`](#nodeoptions-for-node-only) options.
- the [`shell`](#shell) option cannot be used
- an extra channel [`ipc`](https://nodejs.org/api/child_process.html#child_process_options_stdio) is passed to [`stdio`](#stdio)
#### $\`command\`
Executes a command. The `command` string includes both the `file` and its `arguments`. Returns a [`childProcess`](#childprocess).
Arguments are [automatically escaped](#shell-syntax). They can contain any character, but spaces must use `${}` like `` $`echo ${'has space'}` ``.
This is the preferred method when executing multiple commands in a script file.
The `command` string can inject any `${value}` with the following types: string, number, [`childProcess`](#childprocess) or an array of those types. For example: `` $`echo one ${'two'} ${3} ${['four', 'five']}` ``. For `${childProcess}`, the process's `stdout` is used.
For more information, please see [this section](#scripts-interface) and [this page](docs/scripts.md).
#### $(options)
Returns a new instance of [`$`](#command) but with different default `options`. Consecutive calls are merged to previous ones.
This can be used to either:
- Set options for a specific command: `` $(options)`command` ``
- Share options for multiple commands: `` const $$ = $(options); $$`command`; $$`otherCommand`; ``
#### execaCommand(command, options?)
Executes a command. The `command` string includes both the `file` and its `arguments`. Returns a [`childProcess`](#childprocess).
Arguments are [automatically escaped](#shell-syntax). They can contain any character, but spaces must be escaped with a backslash like `execaCommand('echo has\\ space')`.
This is the preferred method when executing a user-supplied `command` string, such as in a REPL.
### execaSync(file, arguments?, options?)
Same as [`execa()`](#execacommandcommand-options) but synchronous.
Returns or throws a [`childProcessResult`](#childProcessResult).
### $.sync\`command\`
Same as [$\`command\`](#command) but synchronous.
Returns or throws a [`childProcessResult`](#childProcessResult).
### execaCommandSync(command, options?)
Same as [`execaCommand()`](#execacommand-command-options) but synchronous.
Returns or throws a [`childProcessResult`](#childProcessResult).
### Shell syntax
For all the [methods above](#methods), no shell interpreter (Bash, cmd.exe, etc.) is used unless the [`shell` option](#shell) is set. This means shell-specific characters and expressions (`$variable`, `&&`, `||`, `;`, `|`, etc.) have no special meaning and do not need to be escaped.
### childProcess
The return value of all [asynchronous methods](#methods) is both:
- a `Promise` resolving or rejecting with a [`childProcessResult`](#childProcessResult).
- a [`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess) with the following additional methods and properties.
#### kill(signal?, options?)

@@ -176,2 +330,4 @@

Note that this graceful termination does not work on Windows, because Windows [doesn't support signals](https://nodejs.org/api/process.html#process_signal_events) (`SIGKILL` and `SIGTERM` has the same effect of force-killing the process immediately.) If you want to achieve graceful termination on Windows, you have to use other means, such as [`taskkill`](https://github.com/sindresorhus/taskkill).
##### options.forceKillAfterTimeout

@@ -196,31 +352,25 @@

### execaSync(file, arguments?, options?)
#### pipeStdout(target)
Execute a file synchronously.
[Pipe](https://nodejs.org/api/stream.html#readablepipedestination-options) the child process's `stdout` to `target`, which can be:
- Another [`execa()` return value](#pipe-multiple-processes)
- A [writable stream](#save-and-pipe-output-from-a-child-process)
- A [file path string](#redirect-output-to-a-file)
Returns or throws a [`childProcessResult`](#childProcessResult).
If the `target` is another [`execa()` return value](#execacommandcommand-options), it is returned. Otherwise, the original `execa()` return value is returned. This allows chaining `pipeStdout()` then `await`ing the [final result](#childprocessresult).
### execaCommand(command, options?)
The [`stdout` option](#stdout-1) must be kept as `pipe`, its default value.
Same as [`execa()`](#execafile-arguments-options) except both file and arguments are specified in a single `command` string. For example, `execa('echo', ['unicorns'])` is the same as `execaCommand('echo unicorns')`.
#### pipeStderr(target)
If the file or an argument contains spaces, they must be escaped with backslashes. This matters especially if `command` is not a constant but a variable, for example with `__dirname` or `process.cwd()`. Except for spaces, no escaping/quoting is needed.
Like [`pipeStdout()`](#pipestdouttarget) but piping the child process's `stderr` instead.
The [`shell` option](#shell) must be used if the `command` uses shell-specific features (for example, `&&` or `||`), as opposed to being a simple `file` followed by its `arguments`.
The [`stderr` option](#stderr-1) must be kept as `pipe`, its default value.
### execaCommandSync(command, options?)
#### pipeAll(target)
Same as [`execaCommand()`](#execacommand-command-options) but synchronous.
Combines both [`pipeStdout()`](#pipestdouttarget) and [`pipeStderr()`](#pipestderrtarget).
Returns or throws a [`childProcessResult`](#childProcessResult).
Either the [`stdout` option](#stdout-1) or the [`stderr` option](#stderr-1) must be kept as `pipe`, their default value. Also, the [`all` option](#all-2) must be set to `true`.
### execaNode(scriptPath, arguments?, options?)
Execute a Node.js script as a child process.
Same as `execa('node', [scriptPath, ...arguments], options)` except (like [`child_process#fork()`](https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options)):
- the current Node version and options are used. This can be overridden using the [`nodePath`](#nodepath-for-node-only) and [`nodeOptions`](#nodeoptions-for-node-only) options.
- the [`shell`](#shell) option cannot be used
- an extra channel [`ipc`](https://nodejs.org/api/child_process.html#child_process_options_stdio) is passed to [`stdio`](#stdio)
### childProcessResult

@@ -251,3 +401,3 @@

Same as [`command`](#command) but escaped.
Same as [`command`](#command-1) but escaped.

@@ -327,2 +477,8 @@ This is meant to be copy and pasted into a shell, for debugging purposes.

#### cwd
Type: `string`
The `cwd` of the command if provided in the [command options](#cwd-1). Otherwise it is `process.cwd()`.
#### message

@@ -366,3 +522,3 @@

Type: `boolean`\
Default: `false`
Default: `true` with [`$`](#command), `false` otherwise

@@ -379,4 +535,2 @@ Prefer locally installed binaries when looking for a binary to execute.\

Using a `URL` is only supported in Node.js `14.18.0`, `16.14.0` or above.
#### execPath

@@ -411,6 +565,16 @@

If the input is a file, use the [`inputFile` option](#inputfile) instead.
#### inputFile
Type: `string`
Use a file as input to the the `stdin` of your binary.
If the input is not a file, use the [`input` option](#input) instead.
#### stdin
Type: `string | number | Stream | undefined`\
Default: `pipe`
Default: `inherit` with [`$`](#command), `pipe` otherwise

@@ -472,4 +636,2 @@ Same options as [`stdio`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio).

Using a `URL` is only supported in Node.js `14.18.0`, `16.14.0` or above.
#### env

@@ -504,4 +666,2 @@

Requires Node.js `13.2.0` or later.
[More info.](https://nodejs.org/api/child_process.html#child_process_advanced_serialization)

@@ -544,3 +704,3 @@

Specify the character encoding used to decode the `stdout` and `stderr` output. If set to `null`, then `stdout` and `stderr` will be a `Buffer` instead of a string.
Specify the character encoding used to decode the `stdout` and `stderr` output. If set to `'buffer'` or `null`, then `stdout` and `stderr` will be a `Buffer` instead of a string.

@@ -574,6 +734,4 @@ #### timeout

When `AbortController.abort()` is called, [`.isCanceled`](#iscanceled) becomes `false`.
When `AbortController.abort()` is called, [`.isCanceled`](#iscanceled) becomes `true`.
*Requires Node.js 16 or later.*
#### windowsVerbatimArguments

@@ -593,2 +751,11 @@

#### verbose
Type: `boolean`\
Default: `false`
[Print each command](#verbose-mode) on `stderr` before executing it.
This can also be enabled by setting the `NODE_DEBUG=execa` environment variable in the current process.
#### nodePath *(For `.node()` only)*

@@ -625,41 +792,29 @@

### Save and pipe output from a child process
### Cancelling a spawned process
Let's say you want to show the output of a child process in real-time while also saving it to a variable.
```js
import {execa} from 'execa';
const subprocess = execa('echo', ['foo']);
subprocess.stdout.pipe(process.stdout);
const abortController = new AbortController();
const subprocess = execa('node', [], {signal: abortController.signal});
const {stdout} = await subprocess;
console.log('child output:', stdout);
```
setTimeout(() => {
abortController.abort();
}, 1000);
### Redirect output to a file
```js
import {execa} from 'execa';
const subprocess = execa('echo', ['foo'])
subprocess.stdout.pipe(fs.createWriteStream('stdout.txt'))
try {
await subprocess;
} catch (error) {
console.log(subprocess.killed); // true
console.log(error.isCanceled); // true
}
```
### Redirect input from a file
```js
import {execa} from 'execa';
const subprocess = execa('cat')
fs.createReadStream('stdin.txt').pipe(subprocess.stdin)
```
### Execute the current package's binary
```js
import {getBinPathSync} from 'get-bin-path';
import {getBinPath} from 'get-bin-path';
const binPath = getBinPathSync();
const subprocess = execa(binPath);
const binPath = await getBinPath();
await execa(binPath);
```

@@ -666,0 +821,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc