import type {Readable, Writable} from 'node:stream'; import type {ReadableStream, WritableStream, TransformStream} from 'node:stream/web'; import type { Not, And, Unless, AndUnless, } from '../utils.js'; import type { GeneratorTransform, GeneratorTransformFull, DuplexTransform, WebTransform, } from '../transform/normalize.js'; type IsStandardStream = FdNumber extends keyof StandardStreams ? true : false; export type StandardStreams = readonly ['stdin', 'stdout', 'stderr']; // When `options.stdin|stdout|stderr|stdio` is set to one of those values, no stream is created export type NoStreamStdioOption = | 'ignore' | 'inherit' | number | Readable | Writable | Unless, undefined> | readonly [NoStreamStdioOption] | {readonly value: 'inherit' | number; readonly input?: boolean}; // `options.stdio` when it is not an array type SimpleStdioOption< IsSync extends boolean, IsExtra extends boolean, IsArray extends boolean, > = | undefined | 'pipe' | Unless, IsArray>, IsExtra>, 'inherit'> | Unless | Unless; // The `{value, input}` object form wraps a direction-ambiguous value and sets its direction explicitly. export type AmbiguousStdioOption< IsSync extends boolean, IsExtra extends boolean, IsArray extends boolean, ObjectModeChunk = unknown, TransformChunk = string, > = { readonly value: AmbiguousStdioValue; readonly input?: Unless, boolean> | false; }; // Values whose direction is ambiguous on additional file descriptors, so they default to output unless `input` is set. // This excludes values with a fixed direction (readable/writable streams, iterables, standard file descriptors). type AmbiguousStdioValue< IsSync extends boolean, IsArray extends boolean, ObjectModeChunk, TransformChunk, > = | 'pipe' | 'inherit' | Unless | URL | GeneratorTransform | GeneratorTransformFull | Unless, IsArray>, 3 | 4 | 5 | 6 | 7 | 8 | 9> | Unless | {readonly file: string; readonly append?: boolean}; // Values available in both `options.stdin|stdio` and `options.stdout|stderr|stdio` type CommonStdioOption< IsSync extends boolean, IsExtra extends boolean, IsArray extends boolean, ObjectModeChunk = unknown, TransformChunk = string, > = // TypeScript cannot contextually type inline full generator transform objects through this broad stdio union because the union also includes `{transform: Duplex | TransformStream}` wrapper objects. Users should annotate `chunk` when assigning an inline object directly to `StdinOption`, `StdoutStderrOption`, `Options['stdout']`, etc. Keep `GeneratorTransformFull` mode branches narrow, but do not add a broad full-object fallback here to try to recover contextual typing. SimpleStdioOption | URL | GeneratorTransform | GeneratorTransformFull | Unless, IsArray>, 3 | 4 | 5 | 6 | 7 | 8 | 9> | Unless | AmbiguousStdioOption | {readonly file: string; readonly append?: boolean}; // Synchronous iterables excluding strings, Uint8Arrays and Arrays type IterableObject = Iterable & object & AndUnless & {readonly BYTES_PER_ELEMENT?: never}; // `process.stdin|stdout|stderr` are `Duplex` with a `fd` property. // This ensures they can only be passed to `stdin`/`stdout`/`stderr`, based on their direction. type ProcessStdinFd = {readonly fd?: 0}; type ProcessStdoutStderrFd = {readonly fd?: 1 | 2}; // Values available only in `options.stdin|stdio` export type InputStdioOption< IsSync extends boolean = boolean, IsExtra extends boolean = boolean, IsArray extends boolean = boolean, > = | 0 | Unless, Uint8Array | IterableObject> | Unless, Readable & ProcessStdinFd> | Unless & ProcessStdinFd) | ReadableStream>; // Values available only in `options.stdout|stderr|stdio` type OutputStdioOption< IsSync extends boolean, IsArray extends boolean, > = | 1 | 2 | Unless, Writable & ProcessStdoutStderrFd> | Unless; // `options.stdin` array items type StdinSingleOption< IsSync extends boolean, IsExtra extends boolean, IsArray extends boolean, TransformChunk = string, > = | CommonStdioOption | InputStdioOption; // `options.stdin` export type StdinOptionCommon< IsSync extends boolean = boolean, IsExtra extends boolean = boolean, TransformChunk = string, > = TransformChunk extends unknown ? | StdinSingleOption | ReadonlyArray> : never; // `options.stdin`, async export type StdinOption = StdinOptionCommon; // `options.stdin`, sync export type StdinSyncOption = StdinOptionCommon; // `options.stdout|stderr` array items type StdoutStderrSingleOption< IsSync extends boolean, IsExtra extends boolean, IsArray extends boolean, TransformChunk = string, > = | CommonStdioOption | OutputStdioOption; // `options.stdout|stderr` // In `objectMode`, the `chunk` argument of every array item is typed as `string`, even though only the first transform in the pipeline receives subprocess lines. The array index cannot be used to infer the pipeline position, since non-transform items are filtered out and transforms are reordered at runtime. export type StdoutStderrOptionCommon< IsSync extends boolean = boolean, IsExtra extends boolean = boolean, TransformChunk = string, > = TransformChunk extends unknown ? | StdoutStderrSingleOption | ReadonlyArray> : never; // `options.stdout|stderr`, async export type StdoutStderrOption = StdoutStderrOptionCommon; // `options.stdout|stderr`, sync export type StdoutStderrSyncOption = StdoutStderrOptionCommon; // `options.stdio[3+]` type StdioExtraOptionCommon = | StdinOptionCommon | StdoutStderrOptionCommon; // `options.stdin|stdout|stderr|stdio` array items type StdioSingleOption< IsSync extends boolean = boolean, IsExtra extends boolean = boolean, IsArray extends boolean = boolean, TransformChunk = string, > = | StdinSingleOption | StdoutStderrSingleOption; // Get `options.stdin|stdout|stderr|stdio` items if it is an array, else keep as is export type StdioSingleOptionItems = StdioOptionType extends readonly StdioSingleOption[] ? StdioOptionType[number] : StdioOptionType; // `options.stdin|stdout|stderr|stdio` export type StdioOptionCommon = | StdinOptionCommon | StdoutStderrOptionCommon; // `options.stdio` when it is an array export type StdioOptionsArray = readonly [ StdinOptionCommon, StdoutStderrOptionCommon, StdoutStderrOptionCommon, ...ReadonlyArray>, ]; // `options.stdio` export type StdioOptionsProperty = TransformChunk extends unknown ? | SimpleStdioOption | StdioOptionsArray : never; export {};