diff --git a/flow-typed/environment/node.js b/flow-typed/environment/node.js index c2f5626e3be4..47c30518aa42 100644 --- a/flow-typed/environment/node.js +++ b/flow-typed/environment/node.js @@ -221,10 +221,10 @@ declare module 'buffer' { declare var File: typeof globalThis.File; } -type child_process$execOpts = { +type child_process$execOpts = Readonly<{ cwd?: string, - env?: Object, - encoding?: string, + env?: Readonly<{[key: string]: string | number | void}>, + encoding?: buffer$NonBufferEncoding | 'buffer' | string, shell?: string, timeout?: number, maxBuffer?: number, @@ -232,8 +232,8 @@ type child_process$execOpts = { uid?: number, gid?: number, windowsHide?: boolean, - ... -}; + signal?: AbortSignal, +}>; declare class child_process$Error extends Error { code: number | string | null; @@ -246,32 +246,31 @@ declare class child_process$Error extends Error { cmd: string; } -type child_process$execCallback = ( +type child_process$execCallback = ( error: ?child_process$Error, - stdout: string | Buffer, - stderr: string | Buffer, + stdout: T, + stderr: T, ) => void; -type child_process$execSyncOpts = { +type child_process$execSyncOpts = Readonly<{ cwd?: string, input?: string | Buffer | $TypedArray | DataView, stdio?: string | Array, - env?: Object, + env?: Readonly<{[key: string]: string | number | void}>, shell?: string, uid?: number, gid?: number, timeout?: number, killSignal?: string | number, maxBuffer?: number, - encoding?: string, + encoding?: buffer$NonBufferEncoding | 'buffer' | string, windowsHide?: boolean, - ... -}; +}>; -type child_process$execFileOpts = { +type child_process$execFileOpts = Readonly<{ cwd?: string, - env?: Object, - encoding?: string, + env?: Readonly<{[key: string]: string | number | void}>, + encoding?: buffer$NonBufferEncoding | 'buffer' | string, timeout?: number, maxBuffer?: number, killSignal?: string | number, @@ -280,168 +279,414 @@ type child_process$execFileOpts = { windowsHide?: boolean, windowsVerbatimArguments?: boolean, shell?: boolean | string, - ... -}; + signal?: AbortSignal, +}>; -type child_process$execFileCallback = ( - error: ?child_process$Error, - stdout: string | Buffer, - stderr: string | Buffer, -) => void; +type child_process$execFileCallback = + child_process$execCallback; -type child_process$execFileSyncOpts = { +type child_process$execFileSyncOpts = Readonly<{ cwd?: string, input?: string | Buffer | $TypedArray | DataView, stdio?: string | Array, - env?: Object, + env?: {[key: string]: string | number | void}, uid?: number, gid?: number, timeout?: number, killSignal?: string | number, maxBuffer?: number, - encoding?: string, + encoding?: buffer$NonBufferEncoding | 'buffer' | string, windowsHide?: boolean, shell?: boolean | string, - ... -}; +}>; -type child_process$forkOpts = { +type child_process$forkOpts = Readonly<{ cwd?: string, - env?: Object, + env?: Readonly<{[key: string]: string | number | void}>, execPath?: string, - execArgv?: Array, + execArgv?: ReadonlyArray, silent?: boolean, - stdio?: Array | string, + stdio?: + | child_process$StdioPipe + | string + | Readonly< + [ + child_process$StdioPipe, + child_process$StdioPipe, + child_process$StdioPipe, + ... + ], + > + | Readonly< + [ + child_process$StdioPipe, + child_process$StdioPipe, + string | number, + ... + ], + > + | Readonly< + [ + child_process$StdioPipe, + string | number, + child_process$StdioPipe, + ... + ], + > + | Readonly< + [ + string | number, + child_process$StdioPipe, + child_process$StdioPipe, + ... + ], + > + | Readonly<[child_process$StdioPipe, string | number, string | number, ...]> + | Readonly<[string | number, child_process$StdioPipe, string | number, ...]> + | Readonly<[string | number, string | number, child_process$StdioPipe, ...]> + | Readonly<[string | number, string | number, string | number, ...]>, windowsVerbatimArguments?: boolean, uid?: number, gid?: number, - ... -}; + serialization?: 'json' | 'advanced', + killSignal?: string | number, + timeout?: number, + signal?: AbortSignal, +}>; type child_process$Handle = any; // TODO -type child_process$spawnOpts = { +type child_process$StdioPipe = 'pipe' | 'overlapped'; + +type child_process$spawnOpts = Readonly<{ cwd?: string, - env?: Object, + env?: Readonly<{[key: string]: string | number | void}>, + encoding?: buffer$NonBufferEncoding | 'buffer' | string, argv0?: string, - stdio?: string | Array, + stdio?: + | child_process$StdioPipe + | string + | Readonly< + [ + child_process$StdioPipe, + child_process$StdioPipe, + child_process$StdioPipe, + ... + ], + > + | Readonly< + [ + child_process$StdioPipe, + child_process$StdioPipe, + string | number, + ... + ], + > + | Readonly< + [ + child_process$StdioPipe, + string | number, + child_process$StdioPipe, + ... + ], + > + | Readonly< + [ + string | number, + child_process$StdioPipe, + child_process$StdioPipe, + ... + ], + > + | Readonly<[child_process$StdioPipe, string | number, string | number, ...]> + | Readonly<[string | number, child_process$StdioPipe, string | number, ...]> + | Readonly<[string | number, string | number, child_process$StdioPipe, ...]> + | Readonly<[string | number, string | number, string | number, ...]>, detached?: boolean, uid?: number, gid?: number, shell?: boolean | string, windowsVerbatimArguments?: boolean, windowsHide?: boolean, - ... -}; + signal?: AbortSignal, + killSignal?: string | number, + timeout?: number, + serialization?: 'json' | 'advanced', +}>; -type child_process$spawnRet = { +type child_process$spawnSyncRet = Readonly<{ pid: number, output: Array, - stdout: Buffer | string, - stderr: Buffer | string, + // TODO: subprocess.stdout may be null in case of error + stdout: T, + // TODO: subprocess.stderr may be null in case of error + stderr: T, + // TODO: subprocess.status may be null in case of error or signal status: number, - signal: string, - error: Error, - ... -}; + signal: string | null, + error: Error | void, +}>; -type child_process$spawnSyncOpts = { +type child_process$spawnSyncOpts = Readonly<{ cwd?: string, input?: string | Buffer, - stdio?: string | Array, - env?: Object, + stdio?: string | ReadonlyArray, + env?: Readonly<{[key: string]: string | number | void}>, uid?: number, gid?: number, timeout?: number, - killSignal?: string, + killSignal?: string | number, maxBuffer?: number, - encoding?: string, + encoding?: buffer$NonBufferEncoding | 'buffer' | string, shell?: boolean | string, - ... -}; - -type child_process$spawnSyncRet = child_process$spawnRet; - -declare class child_process$ChildProcess extends events$EventEmitter { - channel: Object; - connected: boolean; - killed: boolean; - pid: number; - exitCode: number | null; - stderr: stream$Readable; - stdin: stream$Writable; - stdio: Array; - stdout: stream$Readable; + windowsHide?: boolean, + windowsVerbatimArguments?: boolean, +}>; +type child_process$Serializable = + | string + | number + | boolean + | bigint + | {[key: string]: child_process$Serializable} + | Array; + +type child_process$SendHandle = net$Server | net$Socket; + +declare class child_process$ChildProcessTyped< + TStdin: stream$Writable | null, + TStdout: stream$Readable | null, + TStderr: stream$Readable | null, +> extends events$EventEmitter +{ + +stdin: TStdin; + +stdout: TStdout; + +stderr: TStderr; + +channel: unknown; + +stdio: [TStdin, TStdout, TStderr, ...]; + +killed: boolean; + +pid: number; + +connected: boolean; + +exitCode: number | null; + +signalCode: string | null; + +spawnargs: Array; + +spawnfile: string; disconnect(): void; - kill(signal?: string): void; + kill(signal?: string | number): boolean; send( - message: Object, - sendHandleOrCallback?: child_process$Handle, - optionsOrCallback?: Object | Function, - callback?: Function, + message: child_process$Serializable, + callback?: (error: Error | null) => void, + ): boolean; + send( + message: child_process$Serializable, + sendHandle: child_process$SendHandle, + callback?: (error: Error | null) => void, + ): boolean; + send( + message: child_process$Serializable, + sendHandle: child_process$SendHandle, + options: Readonly<{keepOpen?: boolean}>, + callback?: (error: Error | null) => void, ): boolean; unref(): void; ref(): void; } +/** + * @deprecated - Unsafely assumes stdio is piped + */ +declare type child_process$ChildProcess = child_process$ChildProcessTyped< + stream$Writable, + stream$Readable, + stream$Readable, +>; + declare module 'child_process' { - declare var ChildProcess: typeof child_process$ChildProcess; + declare type ExecOptions = child_process$execOpts; + declare type ExecFileOptions = child_process$execFileOpts; + declare type ExecSyncOptions = child_process$execSyncOpts; + declare type ForkOptions = child_process$forkOpts; + declare type SpawnOptions = child_process$spawnOpts; + declare type SpawnSyncOptions = child_process$spawnSyncOpts; + + declare var ChildProcess: typeof child_process$ChildProcessTyped< + stream$Writable, + stream$Readable, + stream$Readable, + >; + + type StringOrBuffer = + Opts extends Readonly<{encoding: infer E, ...}> + ? E extends buffer$NonBufferEncoding + ? string + : E extends 'buffer' + ? Buffer + : string | Buffer + : Default; + + type StreamForChannel = Channel extends 0 + ? stream$Writable + : stream$Readable; + + type MaybeStream = + Opts extends Readonly<{stdio: infer E, ...}> + ? E extends child_process$StdioPipe + ? StreamForChannel + : E extends string + ? null + : E[FD] extends child_process$StdioPipe + ? StreamForChannel + : E[FD] extends string | number + ? null + : null | StreamForChannel + : PipeByDefault extends true + ? StreamForChannel + : null; declare function exec( command: string, - optionsOrCallback?: child_process$execOpts | child_process$execCallback, - callback?: child_process$execCallback, - ): child_process$ChildProcess; - - declare function execSync( + callback?: child_process$execCallback, + ): child_process$ChildProcessTyped< + stream$Writable, + stream$Readable, + stream$Readable, + >; + + declare function exec( command: string, - options: { - encoding: buffer$NonBufferEncoding, - ... - } & child_process$execSyncOpts, - ): string; - - declare function execSync( + options: Opts, + callback?: child_process$execCallback>, + ): child_process$ChildProcessTyped< + stream$Writable, + stream$Readable, + stream$Readable, + >; + + declare function execSync( command: string, - options?: child_process$execSyncOpts, ): Buffer; + declare function execSync( + command: string, + options: Opts, + ): StringOrBuffer; + declare function execFile( file: string, - argsOrOptionsOrCallback?: - | Array - | child_process$execFileOpts - | child_process$execFileCallback, - optionsOrCallback?: - | child_process$execFileOpts - | child_process$execFileCallback, - callback?: child_process$execFileCallback, - ): child_process$ChildProcess; + argsOrCallback?: + | ReadonlyArray + | child_process$execFileCallback, + callback?: child_process$execFileCallback, + ): child_process$ChildProcessTyped< + stream$Writable, + stream$Readable, + stream$Readable, + >; + + declare function execFile( + file: string, + args: ReadonlyArray, + options: Opts, + callback?: child_process$execFileCallback>, + ): child_process$ChildProcessTyped< + stream$Writable, + stream$Readable, + stream$Readable, + >; + + declare function execFile( + file: string, + options: Opts, + callback?: child_process$execFileCallback>, + ): child_process$ChildProcessTyped< + stream$Writable, + stream$Readable, + stream$Readable, + >; declare function execFileSync( command: string, - argsOrOptions?: Array | child_process$execFileSyncOpts, - options?: child_process$execFileSyncOpts, - ): Buffer | string; + args?: ReadonlyArray, + ): Buffer; + + declare function execFileSync( + command: string, + args: ReadonlyArray, + options: Opts, + ): StringOrBuffer; + + declare function execFileSync( + command: string, + options: Opts, + ): StringOrBuffer; declare function fork( modulePath: string, - argsOrOptions?: Array | child_process$forkOpts, - options?: child_process$forkOpts, - ): child_process$ChildProcess; + args?: ReadonlyArray, + ): child_process$ChildProcessTyped; + + declare function fork( + modulePath: string, + args: ReadonlyArray, + options: Opts, + ): child_process$ChildProcessTyped< + MaybeStream, + MaybeStream, + MaybeStream, + >; + + declare function fork( + modulePath: string, + options: Opts, + ): child_process$ChildProcessTyped< + MaybeStream, + MaybeStream, + MaybeStream, + >; declare function spawn( command: string, - argsOrOptions?: Array | child_process$spawnOpts, - options?: child_process$spawnOpts, - ): child_process$ChildProcess; + args?: ReadonlyArray, + ): child_process$ChildProcessTyped< + stream$Writable, + stream$Readable, + stream$Readable, + >; + + declare function spawn( + command: string, + args: ReadonlyArray, + options: Opts, + ): child_process$ChildProcessTyped< + MaybeStream, + MaybeStream, + MaybeStream, + >; + + declare function spawn( + command: string, + options: Opts, + ): child_process$ChildProcessTyped< + MaybeStream, + MaybeStream, + MaybeStream, + >; declare function spawnSync( command: string, - argsOrOptions?: Array | child_process$spawnSyncOpts, - options?: child_process$spawnSyncOpts, - ): child_process$spawnSyncRet; + args?: ReadonlyArray, + ): child_process$spawnSyncRet; + + declare function spawnSync( + command: string, + args: ReadonlyArray, + options: Opts, + ): child_process$spawnSyncRet>; + + declare function spawnSync( + command: string, + options: Opts, + ): child_process$spawnSyncRet>; } declare module 'cluster' { @@ -2280,6 +2525,10 @@ declare module 'fs' { declare var promises: FSPromise; } +declare module 'fs/promises' { + declare module.exports: $Exports<'fs'>['promises']; +} + type http$agentOptions = { keepAlive?: boolean, keepAliveMsecs?: number, @@ -3061,6 +3310,10 @@ declare module 'perf_hooks' { ): RecordableHistogram; } +declare module 'process' { + declare module.exports: Process; +} + declare module 'punycode' { declare function decode(string: string): string; declare function encode(string: string): string; @@ -4718,6 +4971,10 @@ declare module 'assert' { }; } +declare module 'assert/strict' { + declare module.exports: $Exports<'assert'>['strict']; +} + type HeapCodeStatistics = { code_and_metadata_size: number, bytecode_and_metadata_size: number, @@ -5082,68 +5339,6 @@ declare function setImmediate( ): Object; declare function clearImmediate(immediateObject: any): Object; -// https://nodejs.org/api/esm.html#node-imports - -declare module 'node:assert' { - declare module.exports: $Exports<'assert'>; -} - -declare module 'node:assert/strict' { - declare module.exports: $Exports<'assert'>['strict']; -} - -declare module 'node:events' { - declare module.exports: $Exports<'events'>; -} - -declare module 'node:fs' { - declare module.exports: $Exports<'fs'>; -} - -declare module 'node:os' { - declare module.exports: $Exports<'os'>; -} - -declare module 'fs/promises' { - declare module.exports: $Exports<'fs'>['promises']; -} - -declare module 'node:fs/promises' { - declare module.exports: $Exports<'fs'>['promises']; -} - -declare module 'node:path' { - declare module.exports: $Exports<'path'>; -} - -declare module 'node:perf_hooks' { - declare module.exports: $Exports<'perf_hooks'>; -} - -declare module 'process' { - declare module.exports: Process; -} - -declare module 'node:process' { - declare module.exports: $Exports<'process'>; -} - -declare module 'node:timers' { - declare module.exports: $Exports<'timers'>; -} - -declare module 'node:timers/promises' { - declare module.exports: $Exports<'timers/promises'>; -} - -declare module 'node:util' { - declare module.exports: $Exports<'util'>; -} - -declare module 'node:url' { - declare module.exports: $Exports<'url'>; -} - declare module 'worker_threads' { declare var isMainThread: boolean; declare var parentPort: null | MessagePort; @@ -5319,6 +5514,93 @@ declare module 'worker_threads' { } } +// https://nodejs.org/api/esm.html#node-imports + +declare module 'node:assert' { + export type * from 'assert'; + declare module.exports: $Exports<'assert'>; +} + +declare module 'node:assert/strict' { + export type * from 'assert/strict'; + declare module.exports: $Exports<'assert'>['strict']; +} + +declare module 'node:child_process' { + export type * from 'child_process'; + declare module.exports: $Exports<'child_process'>; +} + +declare module 'node:cluster' { + export type * from 'cluster'; + declare module.exports: $Exports<'cluster'>; +} + +declare module 'node:crypto' { + export type * from 'crypto'; + declare module.exports: $Exports<'crypto'>; +} + +declare module 'node:dns' { + export type * from 'dns'; + declare module.exports: $Exports<'dns'>; +} + +declare module 'node:events' { + export type * from 'events'; + declare module.exports: $Exports<'events'>; +} + +declare module 'node:fs' { + export type * from 'fs'; + declare module.exports: $Exports<'fs'>; +} + +declare module 'node:fs/promises' { + export type * from 'fs/promises'; + declare module.exports: $Exports<'fs'>['promises']; +} + +declare module 'node:os' { + export type * from 'os'; + declare module.exports: $Exports<'os'>; +} + +declare module 'node:path' { + export type * from 'path'; + declare module.exports: $Exports<'path'>; +} + +declare module 'node:perf_hooks' { + export type * from 'perf_hooks'; + declare module.exports: $Exports<'perf_hooks'>; +} + +declare module 'node:process' { + export type * from 'process'; + declare module.exports: $Exports<'process'>; +} + +declare module 'node:timers' { + export type * from 'timers'; + declare module.exports: $Exports<'timers'>; +} + +declare module 'node:timers/promises' { + export type * from 'timers/promises'; + declare module.exports: $Exports<'timers/promises'>; +} + +declare module 'node:url' { + declare module.exports: $Exports<'url'>; +} + +declare module 'node:util' { + export type * from 'util'; + declare module.exports: $Exports<'util'>; +} + declare module 'node:worker_threads' { + export type * from 'worker_threads'; declare module.exports: $Exports<'worker_threads'>; } diff --git a/flow-typed/npm/shelljs_v0.x.x.js b/flow-typed/npm/shelljs_v0.x.x.js index 9e1ca8fe8055..51567de3d7dc 100644 --- a/flow-typed/npm/shelljs_v0.x.x.js +++ b/flow-typed/npm/shelljs_v0.x.x.js @@ -34,7 +34,8 @@ declare type $npm$shelljs$OptionsPoly = { declare interface $npm$shelljs$ExecThen { (code: number, stdout: string, stderr: string): void; } -declare type $npm$shelljs$ExecOptionsPoly = T & { +declare type $npm$shelljs$ExecOptionsPoly = { + ...T, async?: boolean, silent?: boolean, ... diff --git a/packages/debugger-shell/src/node/index.flow.js b/packages/debugger-shell/src/node/index.flow.js index a742c8f015ae..a3918962f918 100644 --- a/packages/debugger-shell/src/node/index.flow.js +++ b/packages/debugger-shell/src/node/index.flow.js @@ -101,7 +101,7 @@ async function unstable_spawnDebuggerShellWithArgs( } else if (mode === 'syncThenExit') { child.on('close', function (code, signal) { debug('Debugger exited with code %s and signal %s', code, signal); - if (code === null && !silent) { + if (code == null && !silent) { console.error( 'Debugger exited with code %s and signal %s', code, diff --git a/scripts/release-testing/utils/testing-utils.js b/scripts/release-testing/utils/testing-utils.js index 629fe271a5c7..96319b9d22f5 100644 --- a/scripts/release-testing/utils/testing-utils.js +++ b/scripts/release-testing/utils/testing-utils.js @@ -48,16 +48,10 @@ const launchEmulator = (emulatorName /*: string */) => { // from docs: "When using the detached option to start a long-running process, the process will not stay running in the background after the parent exits unless it is provided with a stdio configuration that is not connected to the parent. If the parent's stdio is inherited, the child will remain attached to the controlling terminal." // here: https://nodejs.org/api/child_process.html#optionsdetached - const child_process /*: child_process$ChildProcess */ = spawn( - emulatorCommand, - [`@${emulatorName}`], - { - detached: true, - stdio: 'ignore', - }, - ); - - child_process.unref(); + spawn(emulatorCommand, [`@${emulatorName}`], { + detached: true, + stdio: 'ignore', + }).unref(); }; function tryLaunchEmulator() {