diff --git a/index.d.ts b/index.d.ts index 359541e9d3..68ec6fa746 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,6 +1,6 @@ -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} from 'node:stream'; export type StdioOption = | 'pipe' @@ -12,7 +12,7 @@ export type StdioOption = | number | undefined; -export interface CommonOptions { +export type CommonOptions = { /** Kill the spawned process when the parent process exits unless either: - the spawned process is [`detached`](https://nodejs.org/api/child_process.html#child_process_options_detached) @@ -244,23 +244,23 @@ export interface CommonOptions { @default true */ readonly windowsHide?: boolean; -} +}; -export interface Options extends CommonOptions { +export type Options = { /** Write some input to the `stdin` of your binary. */ readonly input?: string | Buffer | ReadableStream; -} +} & CommonOptions; -export interface SyncOptions extends CommonOptions { +export type SyncOptions = { /** Write some input to the `stdin` of your binary. */ readonly input?: string | Buffer; -} +} & CommonOptions; -export interface NodeOptions extends Options { +export type NodeOptions = { /** The Node.js executable to use. @@ -274,9 +274,9 @@ export interface NodeOptions extends Options; -export interface ExecaReturnBase { +export type ExecaReturnBase = { /** The file and arguments that were run, for logging purposes. @@ -335,11 +335,10 @@ export interface ExecaReturnBase { 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. */ signalDescription?: string; -} +}; -export interface ExecaSyncReturnValue - extends ExecaReturnBase { -} +export type ExecaSyncReturnValue = { +} & ExecaReturnBase; /** Result of a child process execution. On success this is a plain object. On failure this is also an `Error` instance. @@ -351,8 +350,7 @@ The child process fails when: - being canceled - there's not enough memory or there are already too many child processes */ -export interface ExecaReturnValue - extends ExecaSyncReturnValue { +export type ExecaReturnValue = { /** The output of the process with `stdout` and `stderr` interleaved. @@ -368,11 +366,9 @@ export interface ExecaReturnValue You can cancel the spawned process using the [`signal`](https://github.com/sindresorhus/execa#signal-1) option. */ isCanceled: boolean; -} +} & ExecaSyncReturnValue; -export interface ExecaSyncError - extends Error, - ExecaReturnBase { +export type ExecaSyncError = { /** 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. @@ -391,10 +387,9 @@ export interface ExecaSyncError This is `undefined` unless the child process exited due to an `error` event or a timeout. */ originalMessage?: string; -} +} & Error & ExecaReturnBase; -export interface ExecaError - extends ExecaSyncError { +export type ExecaError = { /** The output of the process with `stdout` and `stderr` interleaved. @@ -408,9 +403,9 @@ export interface ExecaError Whether the process was canceled. */ isCanceled: boolean; -} +} & ExecaSyncError; -export interface KillOptions { +export type KillOptions = { /** Milliseconds to wait for the child process to terminate before sending `SIGKILL`. @@ -419,9 +414,9 @@ export interface KillOptions { @default 5000 */ forceKillAfterTimeout?: number | false; -} +}; -export interface ExecaChildPromise { +export type ExecaChildPromise = { /** 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). @@ -444,7 +439,7 @@ export interface ExecaChildPromise { 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 = ChildProcess & ExecaChildPromise & diff --git a/index.test-d.ts b/index.test-d.ts index 24cc93caa3..a805354706 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -3,7 +3,7 @@ import {Buffer} from 'node:buffer'; // `process.stdin`, `process.stderr`, and `process.stdout` // to get treated as `any` by `@typescript-eslint/no-unsafe-assignment`. import * as process from 'node:process'; -import {Readable as ReadableStream} from 'node:stream'; +import {type Readable as ReadableStream} from 'node:stream'; import {expectType, expectError} from 'tsd'; import { execa, @@ -11,11 +11,11 @@ import { execaCommand, execaCommandSync, execaNode, - ExecaReturnValue, - ExecaChildProcess, - ExecaError, - ExecaSyncReturnValue, - ExecaSyncError, + type ExecaReturnValue, + type ExecaChildProcess, + type ExecaError, + type ExecaSyncReturnValue, + type ExecaSyncError, } from './index.js'; try { diff --git a/lib/promise.js b/lib/promise.js index c655c0e4a5..975aee0cd6 100644 --- a/lib/promise.js +++ b/lib/promise.js @@ -1,4 +1,6 @@ +// eslint-disable-next-line unicorn/prefer-top-level-await const nativePromisePrototype = (async () => {})().constructor.prototype; + const descriptors = ['then', 'catch', 'finally'].map(property => [ property, Reflect.getOwnPropertyDescriptor(nativePromisePrototype, property), diff --git a/package.json b/package.json index c6711b2187..4d3c7b7602 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.1", - "human-signals": "^4.1.0", + "human-signals": "^4.3.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", @@ -52,16 +52,16 @@ "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": "^18.13.0", + "ava": "^5.2.0", + "c8": "^7.12.0", + "get-node": "^13.5.0", "is-running": "^2.1.0", "p-event": "^5.0.1", "path-key": "^4.0.0", "tempfile": "^4.0.0", - "tsd": "^0.19.1", - "xo": "^0.48.0" + "tsd": "^0.25.0", + "xo": "^0.53.1" }, "c8": { "reporter": [ @@ -74,6 +74,9 @@ "**/test/**" ] }, + "ava": { + "workerThreads": false + }, "xo": { "rules": { "unicorn/no-empty-file": "off", diff --git a/test/fixtures/sub-process-exit.js b/test/fixtures/sub-process-exit.js index ae21147ef1..79890abd66 100755 --- a/test/fixtures/sub-process-exit.js +++ b/test/fixtures/sub-process-exit.js @@ -5,13 +5,9 @@ import {execa} from '../../index.js'; const cleanup = process.argv[2] === 'true'; const detached = process.argv[3] === 'true'; -const runChild = async () => { - try { - await execa('node', ['./test/fixtures/noop.js'], {cleanup, detached}); - } catch (error) { - console.error(error); - process.exit(1); - } -}; - -runChild(); +try { + await execa('node', ['./test/fixtures/noop.js'], {cleanup, detached}); +} catch (error) { + console.error(error); + process.exit(1); +} diff --git a/test/test.js b/test/test.js index da0cb67aed..47192fb5ce 100644 --- a/test/test.js +++ b/test/test.js @@ -104,9 +104,9 @@ test('localDir option', async t => { }); test('execPath option', async t => { - const {path: execPath} = await getNode('6.0.0'); + const {path: execPath} = await getNode('16.0.0'); const {stdout} = await execa('node', ['-p', 'process.env.Path || process.env.PATH'], {preferLocal: true, execPath}); - t.true(stdout.includes('6.0.0')); + t.true(stdout.includes('16.0.0')); }); test('stdin errors are handled', async t => {