1 | import {Buffer} from 'node:buffer';
|
2 | import {ChildProcess} from 'node:child_process';
|
3 | import {Stream, Readable as ReadableStream} from 'node:stream';
|
4 |
|
5 | export type StdioOption =
|
6 | | 'pipe'
|
7 | | 'ipc'
|
8 | | 'ignore'
|
9 | | 'inherit'
|
10 | | Stream
|
11 | | number
|
12 | | undefined;
|
13 |
|
14 | export interface CommonOptions<EncodingType> {
|
15 | /**
|
16 | Kill the spawned process when the parent process exits unless either:
|
17 | - the spawned process is [`detached`](https://nodejs.org/api/child_process.html#child_process_options_detached)
|
18 | - the parent process is terminated abruptly, for example, with `SIGKILL` as opposed to `SIGTERM` or a normal exit
|
19 |
|
20 | @default true
|
21 | */
|
22 | readonly cleanup?: boolean;
|
23 |
|
24 | /**
|
25 | Prefer locally installed binaries when looking for a binary to execute.
|
26 |
|
27 | If you `$ npm install foo`, you can then `execa('foo')`.
|
28 |
|
29 | @default false
|
30 | */
|
31 | readonly preferLocal?: boolean;
|
32 |
|
33 | /**
|
34 | Preferred path to find locally installed binaries in (use with `preferLocal`).
|
35 |
|
36 | @default process.cwd()
|
37 | */
|
38 | readonly localDir?: string;
|
39 |
|
40 | /**
|
41 | Path to the Node.js executable to use in child processes.
|
42 |
|
43 | This can be either an absolute path or a path relative to the `cwd` option.
|
44 |
|
45 | Requires `preferLocal` to be `true`.
|
46 |
|
47 | For example, this can be used together with [`get-node`](https://github.com/ehmicky/get-node) to run a specific Node.js version in a child process.
|
48 |
|
49 | @default process.execPath
|
50 | */
|
51 | readonly execPath?: string;
|
52 |
|
53 | /**
|
54 | Buffer the output from the spawned process. When set to `false`, you must read the output of `stdout` and `stderr` (or `all` if the `all` option is `true`). Otherwise the returned promise will not be resolved/rejected.
|
55 |
|
56 | If the spawned process fails, `error.stdout`, `error.stderr`, and `error.all` will contain the buffered data.
|
57 |
|
58 | @default true
|
59 | */
|
60 | readonly buffer?: boolean;
|
61 |
|
62 | /**
|
63 | Same options as [`stdio`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio).
|
64 |
|
65 | @default 'pipe'
|
66 | */
|
67 | readonly stdin?: StdioOption;
|
68 |
|
69 | /**
|
70 | Same options as [`stdio`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio).
|
71 |
|
72 | @default 'pipe'
|
73 | */
|
74 | readonly stdout?: StdioOption;
|
75 |
|
76 | /**
|
77 | Same options as [`stdio`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio).
|
78 |
|
79 | @default 'pipe'
|
80 | */
|
81 | readonly stderr?: StdioOption;
|
82 |
|
83 | /**
|
84 | Setting this to `false` resolves the promise with the error instead of rejecting it.
|
85 |
|
86 | @default true
|
87 | */
|
88 | readonly reject?: boolean;
|
89 |
|
90 | /**
|
91 | Add an `.all` property on the promise and the resolved value. The property contains the output of the process with `stdout` and `stderr` interleaved.
|
92 |
|
93 | @default false
|
94 | */
|
95 | readonly all?: boolean;
|
96 |
|
97 | /**
|
98 | Strip the final [newline character](https://en.wikipedia.org/wiki/Newline) from the output.
|
99 |
|
100 | @default true
|
101 | */
|
102 | readonly stripFinalNewline?: boolean;
|
103 |
|
104 | /**
|
105 | Set to `false` if you don't want to extend the environment variables when providing the `env` property.
|
106 |
|
107 | @default true
|
108 | */
|
109 | readonly extendEnv?: boolean;
|
110 |
|
111 | /**
|
112 | Current working directory of the child process.
|
113 |
|
114 | @default process.cwd()
|
115 | */
|
116 | readonly cwd?: string;
|
117 |
|
118 | /**
|
119 | Environment key-value pairs. Extends automatically from `process.env`. Set `extendEnv` to `false` if you don't want this.
|
120 |
|
121 | @default process.env
|
122 | */
|
123 | readonly env?: NodeJS.ProcessEnv;
|
124 |
|
125 | /**
|
126 | Explicitly set the value of `argv[0]` sent to the child process. This will be set to `command` or `file` if not specified.
|
127 | */
|
128 | readonly argv0?: string;
|
129 |
|
130 | /**
|
131 | Child's [stdio](https://nodejs.org/api/child_process.html#child_process_options_stdio) configuration.
|
132 |
|
133 | @default 'pipe'
|
134 | */
|
135 | readonly stdio?: 'pipe' | 'ignore' | 'inherit' | readonly StdioOption[];
|
136 |
|
137 | /**
|
138 | Specify the kind of serialization used for sending messages between processes when using the `stdio: 'ipc'` option or `execaNode()`:
|
139 | - `json`: Uses `JSON.stringify()` and `JSON.parse()`.
|
140 | - `advanced`: Uses [`v8.serialize()`](https://nodejs.org/api/v8.html#v8_v8_serialize_value)
|
141 |
|
142 | Requires Node.js `13.2.0` or later.
|
143 |
|
144 | [More info.](https://nodejs.org/api/child_process.html#child_process_advanced_serialization)
|
145 |
|
146 | @default 'json'
|
147 | */
|
148 | readonly serialization?: 'json' | 'advanced';
|
149 |
|
150 | /**
|
151 | Prepare child to run independently of its parent process. Specific behavior [depends on the platform](https://nodejs.org/api/child_process.html#child_process_options_detached).
|
152 |
|
153 | @default false
|
154 | */
|
155 | readonly detached?: boolean;
|
156 |
|
157 | /**
|
158 | Sets the user identity of the process.
|
159 | */
|
160 | readonly uid?: number;
|
161 |
|
162 | /**
|
163 | Sets the group identity of the process.
|
164 | */
|
165 | readonly gid?: number;
|
166 |
|
167 | /**
|
168 | If `true`, runs `command` inside of a shell. Uses `/bin/sh` on UNIX and `cmd.exe` on Windows. A different shell can be specified as a string. The shell should understand the `-c` switch on UNIX or `/d /s /c` on Windows.
|
169 |
|
170 | We recommend against using this option since it is:
|
171 | - not cross-platform, encouraging shell-specific syntax.
|
172 | - slower, because of the additional shell interpretation.
|
173 | - unsafe, potentially allowing command injection.
|
174 |
|
175 | @default false
|
176 | */
|
177 | readonly shell?: boolean | string;
|
178 |
|
179 | /**
|
180 | 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.
|
181 |
|
182 | @default 'utf8'
|
183 | */
|
184 | readonly encoding?: EncodingType;
|
185 |
|
186 | /**
|
187 | If `timeout` is greater than `0`, the parent will send the signal identified by the `killSignal` property (the default is `SIGTERM`) if the child runs longer than `timeout` milliseconds.
|
188 |
|
189 | @default 0
|
190 | */
|
191 | readonly timeout?: number;
|
192 |
|
193 | /**
|
194 | Largest amount of data in bytes allowed on `stdout` or `stderr`. Default: 100 MB.
|
195 |
|
196 | @default 100_000_000
|
197 | */
|
198 | readonly maxBuffer?: number;
|
199 |
|
200 | /**
|
201 | Signal value to be used when the spawned process will be killed.
|
202 |
|
203 | @default 'SIGTERM'
|
204 | */
|
205 | readonly killSignal?: string | number;
|
206 |
|
207 | /**
|
208 | If `true`, no quoting or escaping of arguments is done on Windows. Ignored on other platforms. This is set to `true` automatically when the `shell` option is `true`.
|
209 |
|
210 | @default false
|
211 | */
|
212 | readonly windowsVerbatimArguments?: boolean;
|
213 |
|
214 | /**
|
215 | On Windows, do not create a new console window. Please note this also prevents `CTRL-C` [from working](https://github.com/nodejs/node/issues/29837) on Windows.
|
216 |
|
217 | @default true
|
218 | */
|
219 | readonly windowsHide?: boolean;
|
220 | }
|
221 |
|
222 | export interface Options<EncodingType = string> extends CommonOptions<EncodingType> {
|
223 | /**
|
224 | Write some input to the `stdin` of your binary.
|
225 | */
|
226 | readonly input?: string | Buffer | ReadableStream;
|
227 | }
|
228 |
|
229 | export interface SyncOptions<EncodingType = string> extends CommonOptions<EncodingType> {
|
230 | /**
|
231 | Write some input to the `stdin` of your binary.
|
232 | */
|
233 | readonly input?: string | Buffer;
|
234 | }
|
235 |
|
236 | export interface NodeOptions<EncodingType = string> extends Options<EncodingType> {
|
237 | /**
|
238 | The Node.js executable to use.
|
239 |
|
240 | @default process.execPath
|
241 | */
|
242 | readonly nodePath?: string;
|
243 |
|
244 | /**
|
245 | List of [CLI options](https://nodejs.org/api/cli.html#cli_options) passed to the Node.js executable.
|
246 |
|
247 | @default process.execArgv
|
248 | */
|
249 | readonly nodeOptions?: string[];
|
250 | }
|
251 |
|
252 | export interface ExecaReturnBase<StdoutStderrType> {
|
253 | /**
|
254 | The file and arguments that were run, for logging purposes.
|
255 |
|
256 | This is not escaped and should not be executed directly as a process, including using `execa()` or `execaCommand()`.
|
257 | */
|
258 | command: string;
|
259 |
|
260 | /**
|
261 | Same as `command` but escaped.
|
262 |
|
263 | This is meant to be copy and pasted into a shell, for debugging purposes.
|
264 | Since the escaping is fairly basic, this should not be executed directly as a process, including using `execa()` or `execaCommand()`.
|
265 | */
|
266 | escapedCommand: string;
|
267 |
|
268 | /**
|
269 | The numeric exit code of the process that was run.
|
270 | */
|
271 | exitCode: number;
|
272 |
|
273 | /**
|
274 | The output of the process on stdout.
|
275 | */
|
276 | stdout: StdoutStderrType;
|
277 |
|
278 | /**
|
279 | The output of the process on stderr.
|
280 | */
|
281 | stderr: StdoutStderrType;
|
282 |
|
283 | /**
|
284 | Whether the process failed to run.
|
285 | */
|
286 | failed: boolean;
|
287 |
|
288 | /**
|
289 | Whether the process timed out.
|
290 | */
|
291 | timedOut: boolean;
|
292 |
|
293 | /**
|
294 | Whether the process was killed.
|
295 | */
|
296 | killed: boolean;
|
297 |
|
298 | /**
|
299 | The name of the signal that was used to terminate the process. For example, `SIGFPE`.
|
300 |
|
301 | If a signal terminated the process, this property is defined and included in the error message. Otherwise it is `undefined`.
|
302 | */
|
303 | signal?: string;
|
304 |
|
305 | /**
|
306 | A human-friendly description of the signal that was used to terminate the process. For example, `Floating point arithmetic error`.
|
307 |
|
308 | If a signal terminated the process, this property is defined and included in the error message. Otherwise it is `undefined`. It is also `undefined` when the signal is very uncommon which should seldomly happen.
|
309 | */
|
310 | signalDescription?: string;
|
311 | }
|
312 |
|
313 | export interface ExecaSyncReturnValue<StdoutErrorType = string>
|
314 | extends ExecaReturnBase<StdoutErrorType> {
|
315 | }
|
316 |
|
317 | /**
|
318 | Result of a child process execution. On success this is a plain object. On failure this is also an `Error` instance.
|
319 |
|
320 | The child process fails when:
|
321 | - its exit code is not `0`
|
322 | - it was killed with a signal
|
323 | - timing out
|
324 | - being canceled
|
325 | - there's not enough memory or there are already too many child processes
|
326 | */
|
327 | export interface ExecaReturnValue<StdoutErrorType = string>
|
328 | extends ExecaSyncReturnValue<StdoutErrorType> {
|
329 | /**
|
330 | The output of the process with `stdout` and `stderr` interleaved.
|
331 |
|
332 | This is `undefined` if either:
|
333 | - the `all` option is `false` (default value)
|
334 | - `execaSync()` was used
|
335 | */
|
336 | all?: StdoutErrorType;
|
337 |
|
338 | /**
|
339 | Whether the process was canceled.
|
340 | */
|
341 | isCanceled: boolean;
|
342 | }
|
343 |
|
344 | export interface ExecaSyncError<StdoutErrorType = string>
|
345 | extends Error,
|
346 | ExecaReturnBase<StdoutErrorType> {
|
347 | /**
|
348 | 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.
|
349 |
|
350 | The child process stderr then stdout are appended to the end, separated with newlines and not interleaved.
|
351 | */
|
352 | message: string;
|
353 |
|
354 | /**
|
355 | This is the same as the `message` property except it does not include the child process stdout/stderr.
|
356 | */
|
357 | shortMessage: string;
|
358 |
|
359 | /**
|
360 | Original error message. This is the same as the `message` property except it includes neither the child process stdout/stderr nor some additional information added by Execa.
|
361 |
|
362 | This is `undefined` unless the child process exited due to an `error` event or a timeout.
|
363 | */
|
364 | originalMessage?: string;
|
365 | }
|
366 |
|
367 | export interface ExecaError<StdoutErrorType = string>
|
368 | extends ExecaSyncError<StdoutErrorType> {
|
369 | /**
|
370 | The output of the process with `stdout` and `stderr` interleaved.
|
371 |
|
372 | This is `undefined` if either:
|
373 | - the `all` option is `false` (default value)
|
374 | - `execaSync()` was used
|
375 | */
|
376 | all?: StdoutErrorType;
|
377 |
|
378 | /**
|
379 | Whether the process was canceled.
|
380 | */
|
381 | isCanceled: boolean;
|
382 | }
|
383 |
|
384 | export interface KillOptions {
|
385 | /**
|
386 | Milliseconds to wait for the child process to terminate before sending `SIGKILL`.
|
387 |
|
388 | Can be disabled with `false`.
|
389 |
|
390 | @default 5000
|
391 | */
|
392 | forceKillAfterTimeout?: number | false;
|
393 | }
|
394 |
|
395 | export interface ExecaChildPromise<StdoutErrorType> {
|
396 | /**
|
397 | 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).
|
398 |
|
399 | This is `undefined` if either:
|
400 | - the `all` option is `false` (the default value)
|
401 | - both `stdout` and `stderr` options are set to [`'inherit'`, `'ipc'`, `Stream` or `integer`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio)
|
402 | */
|
403 | all?: ReadableStream;
|
404 |
|
405 | catch<ResultType = never>(
|
406 | onRejected?: (reason: ExecaError<StdoutErrorType>) => ResultType | PromiseLike<ResultType>
|
407 | ): Promise<ExecaReturnValue<StdoutErrorType> | ResultType>;
|
408 |
|
409 | /**
|
410 | 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`.
|
411 | */
|
412 | kill(signal?: string, options?: KillOptions): void;
|
413 |
|
414 | /**
|
415 | 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`.
|
416 | */
|
417 | cancel(): void;
|
418 | }
|
419 |
|
420 | export type ExecaChildProcess<StdoutErrorType = string> = ChildProcess &
|
421 | ExecaChildPromise<StdoutErrorType> &
|
422 | Promise<ExecaReturnValue<StdoutErrorType>>;
|
423 |
|
424 | /**
|
425 | Execute a file.
|
426 |
|
427 | Think of this as a mix of `child_process.execFile` and `child_process.spawn`.
|
428 |
|
429 | @param file - The program/script to execute.
|
430 | @param arguments - Arguments to pass to `file` on execution.
|
431 | @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.
|
432 |
|
433 | @example
|
434 | ```
|
435 | import {execa} from 'execa';
|
436 |
|
437 | const {stdout} = await execa('echo', ['unicorns']);
|
438 | console.log(stdout);
|
439 | //=> 'unicorns'
|
440 |
|
441 | // Cancelling a spawned process
|
442 |
|
443 | const subprocess = execa('node');
|
444 |
|
445 | setTimeout(() => {
|
446 | subprocess.cancel()
|
447 | }, 1000);
|
448 |
|
449 | try {
|
450 | await subprocess;
|
451 | } catch (error) {
|
452 | console.log(subprocess.killed); // true
|
453 | console.log(error.isCanceled); // true
|
454 | }
|
455 |
|
456 | // Pipe the child process stdout to the current stdout
|
457 | execa('echo', ['unicorns']).stdout.pipe(process.stdout);
|
458 | ```
|
459 | */
|
460 | export function execa(
|
461 | file: string,
|
462 | arguments?: readonly string[],
|
463 | options?: Options
|
464 | ): ExecaChildProcess;
|
465 | export function execa(
|
466 | file: string,
|
467 | arguments?: readonly string[],
|
468 | options?: Options<null>
|
469 | ): ExecaChildProcess<Buffer>;
|
470 | export function execa(file: string, options?: Options): ExecaChildProcess;
|
471 | export function execa(file: string, options?: Options<null>): ExecaChildProcess<Buffer>;
|
472 |
|
473 | /**
|
474 | Execute a file synchronously.
|
475 |
|
476 | This method throws an `Error` if the command fails.
|
477 |
|
478 | @param file - The program/script to execute.
|
479 | @param arguments - Arguments to pass to `file` on execution.
|
480 | @returns A result `Object` with `stdout` and `stderr` properties.
|
481 | */
|
482 | export function execaSync(
|
483 | file: string,
|
484 | arguments?: readonly string[],
|
485 | options?: SyncOptions
|
486 | ): ExecaSyncReturnValue;
|
487 | export function execaSync(
|
488 | file: string,
|
489 | arguments?: readonly string[],
|
490 | options?: SyncOptions<null>
|
491 | ): ExecaSyncReturnValue<Buffer>;
|
492 | export function execaSync(file: string, options?: SyncOptions): ExecaSyncReturnValue;
|
493 | export function execaSync(
|
494 | file: string,
|
495 | options?: SyncOptions<null>
|
496 | ): ExecaSyncReturnValue<Buffer>;
|
497 |
|
498 | /**
|
499 | 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')`.
|
500 |
|
501 | 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.
|
502 |
|
503 | 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`.
|
504 |
|
505 | @param command - The program/script to execute and its arguments.
|
506 | @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.
|
507 |
|
508 | @example
|
509 | ```
|
510 | import {execaCommand} from 'execa';
|
511 |
|
512 | const {stdout} = await execaCommand('echo unicorns');
|
513 | console.log(stdout);
|
514 | //=> 'unicorns'
|
515 | ```
|
516 | */
|
517 | export function execaCommand(command: string, options?: Options): ExecaChildProcess;
|
518 | export function execaCommand(command: string, options?: Options<null>): ExecaChildProcess<Buffer>;
|
519 |
|
520 | /**
|
521 | Same as `execaCommand()` but synchronous.
|
522 |
|
523 | @param command - The program/script to execute and its arguments.
|
524 | @returns A result `Object` with `stdout` and `stderr` properties.
|
525 | */
|
526 | export function execaCommandSync(command: string, options?: SyncOptions): ExecaSyncReturnValue;
|
527 | export function execaCommandSync(command: string, options?: SyncOptions<null>): ExecaSyncReturnValue<Buffer>;
|
528 |
|
529 | /**
|
530 | Execute a Node.js script as a child process.
|
531 |
|
532 | 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)):
|
533 | - the current Node version and options are used. This can be overridden using the `nodePath` and `nodeArguments` options.
|
534 | - the `shell` option cannot be used
|
535 | - an extra channel [`ipc`](https://nodejs.org/api/child_process.html#child_process_options_stdio) is passed to [`stdio`](#stdio)
|
536 |
|
537 | @param scriptPath - Node.js script to execute.
|
538 | @param arguments - Arguments to pass to `scriptPath` on execution.
|
539 | @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.
|
540 | */
|
541 | export function execaNode(
|
542 | scriptPath: string,
|
543 | arguments?: readonly string[],
|
544 | options?: NodeOptions
|
545 | ): ExecaChildProcess;
|
546 | export function execaNode(
|
547 | scriptPath: string,
|
548 | arguments?: readonly string[],
|
549 | options?: Options<null>
|
550 | ): ExecaChildProcess<Buffer>;
|
551 | export function execaNode(scriptPath: string, options?: Options): ExecaChildProcess;
|
552 | export function execaNode(scriptPath: string, options?: Options<null>): ExecaChildProcess<Buffer>;
|