storybook
Version:
Storybook: Develop, document, and test UI components in isolation
1,456 lines (1,250 loc) • 97.5 kB
TypeScript
import * as storybook_internal_types from 'storybook/internal/types';
import { CLIOptions, LoadOptions, BuilderOptions, StorybookConfigRaw, PresetConfig, CoreCommon_ResolvedAddonPreset, CoreCommon_ResolvedAddonVirtual, LoadedPreset, Presets, CoreCommon_AddonInfo, SupportedFramework, SupportedRenderer, SupportedBuilder, Options as Options$2, CoreWebpackCompiler, CoreCommon_StorybookInfo, Ref, StorybookConfig, StoriesEntry, NormalizedStoriesSpecifier, PackageJson } from 'storybook/internal/types';
export { PackageJson } from 'storybook/internal/types';
import { WriteStream } from 'node:fs';
import { ChildProcess } from 'node:child_process';
import { SignalConstants } from 'node:os';
import { Duplex, Readable, Writable } from 'node:stream';
import { TransformStream, ReadableStream, WritableStream } from 'node:stream/web';
import { ConfigFile } from 'storybook/internal/csf-tools';
import { types } from 'storybook/internal/babel';
export { isWebContainer } from '@webcontainer/env';
declare const _default: {
'@storybook/addon-a11y': string;
'@storybook/addon-docs': string;
'@storybook/addon-links': string;
'@storybook/addon-onboarding': string;
'storybook-addon-pseudo-states': string;
'@storybook/addon-themes': string;
'@storybook/addon-vitest': string;
'@storybook/builder-vite': string;
'@storybook/builder-webpack5': string;
storybook: string;
'@storybook/angular': string;
'@storybook/ember': string;
'@storybook/html-vite': string;
'@storybook/nextjs': string;
'@storybook/nextjs-vite': string;
'@storybook/preact-vite': string;
'@storybook/react-native-web-vite': string;
'@storybook/react-vite': string;
'@storybook/react-webpack5': string;
'@storybook/server-webpack5': string;
'@storybook/svelte-vite': string;
'@storybook/sveltekit': string;
'@storybook/vue3-vite': string;
'@storybook/web-components-vite': string;
sb: string;
'@storybook/cli': string;
'@storybook/codemod': string;
'@storybook/core-webpack': string;
'create-storybook': string;
'@storybook/csf-plugin': string;
'eslint-plugin-storybook': string;
'@storybook/react-dom-shim': string;
'@storybook/preset-create-react-app': string;
'@storybook/preset-react-webpack': string;
'@storybook/preset-server-webpack': string;
'@storybook/html': string;
'@storybook/preact': string;
'@storybook/react': string;
'@storybook/server': string;
'@storybook/svelte': string;
'@storybook/vue3': string;
'@storybook/web-components': string;
};
interface Listener {
(...args: any[]): void;
}
/**
* Structural interface for Channel, used in type declarations to avoid nominal incompatibility
* between source and dist Channel class declarations.
*/
interface ChannelLike {
readonly isAsync: boolean;
readonly hasTransport: boolean;
addListener(eventName: string, listener: Listener): void;
emit(eventName: string, ...args: any): void;
last(eventName: string): any;
eventNames(): string[];
listenerCount(eventName: string): number;
listeners(eventName: string): Listener[] | undefined;
once(eventName: string, listener: Listener): void;
removeAllListeners(eventName?: string): void;
removeListener(eventName: string, listener: Listener): void;
on(eventName: string, listener: Listener): void;
off(eventName: string, listener: Listener): void;
}
type InterPresetOptions = Omit<CLIOptions & LoadOptions & BuilderOptions & {
isCritical?: boolean;
build?: StorybookConfigRaw['build'];
}, 'frameworkPresets'>;
declare function filterPresetsConfig(presetsConfig: PresetConfig[]): PresetConfig[];
/**
* Parse an addon into either a managerEntries or a preset. Throw on invalid input.
*
* Valid inputs:
*
* - `'@storybook/addon-docs/preset' => { type: 'presets', item }`
* - `'@storybook/addon-docs' => { type: 'presets', item: '@storybook/addon-docs/preset' }`
* - `{ name: '@storybook/addon-docs(/preset)?', options: { } } => { type: 'presets', item: { name:
* '@storybook/addon-docs/preset', options } }`
*/
declare const resolveAddonName: (configDir: string, name: string, options: any) => CoreCommon_ResolvedAddonPreset | CoreCommon_ResolvedAddonVirtual | undefined;
declare function loadPreset(input: PresetConfig, level: number, storybookOptions: InterPresetOptions): Promise<LoadedPreset[]>;
declare function getPresets(presets: PresetConfig[], storybookOptions: InterPresetOptions): Promise<Presets>;
declare function loadAllPresets(options: CLIOptions & LoadOptions & BuilderOptions & {
corePresets: PresetConfig[];
overridePresets: PresetConfig[];
/** Whether preset failures should be critical or not */
isCritical?: boolean;
build?: StorybookConfigRaw['build'];
channel: ChannelLike;
}): Promise<Presets>;
interface FileSystemCacheOptions {
ns?: string;
prefix?: string;
hash_alg?: string;
basePath?: string;
ttl?: number;
}
interface CacheItem {
key: string;
content?: any;
value?: any;
}
interface CacheSetOptions {
ttl?: number;
encoding?: BufferEncoding;
}
declare class FileSystemCache {
private prefix;
private hash_alg;
private cache_dir;
private ttl;
constructor(options?: FileSystemCacheOptions);
private generateHash;
private isExpired;
private parseCacheData;
private parseSetData;
get<T = any>(name: string, fallback?: T): Promise<T>;
getSync<T>(name: string, fallback?: T): T;
set<T>(name: string, data: T, orgOpts?: CacheSetOptions | number): Promise<void>;
setSync<T>(name: string, data: T, orgOpts?: CacheSetOptions | number): void;
setMany(items: CacheItem[], options?: CacheSetOptions): Promise<void>;
setManySync(items: CacheItem[], options?: CacheSetOptions): void;
remove(name: string): Promise<void>;
removeSync(name: string): void;
clear(): Promise<void>;
clearSync(): void;
getAll(): Promise<CacheItem[]>;
load(): Promise<{
files: CacheItem[];
}>;
}
declare function createFileSystemCache(options: FileSystemCacheOptions): FileSystemCache;
declare const cache: FileSystemCache;
declare global {
interface SymbolConstructor {
readonly observable: symbol;
}
}
// Helper type. Not useful on its own.
type Without<FirstType, SecondType> = {[KeyType in Exclude<keyof FirstType, keyof SecondType>]?: never};
/**
Create a type that has mutually exclusive keys.
This type was inspired by [this comment](https://github.com/Microsoft/TypeScript/issues/14094#issuecomment-373782604).
This type works with a helper type, called `Without`. `Without<FirstType, SecondType>` produces a type that has only keys from `FirstType` which are not present on `SecondType` and sets the value type for these keys to `never`. This helper type is then used in `MergeExclusive` to remove keys from either `FirstType` or `SecondType`.
@example
```
import type {MergeExclusive} from 'type-fest';
interface ExclusiveVariation1 {
exclusive1: boolean;
}
interface ExclusiveVariation2 {
exclusive2: string;
}
type ExclusiveOptions = MergeExclusive<ExclusiveVariation1, ExclusiveVariation2>;
let exclusiveOptions: ExclusiveOptions;
exclusiveOptions = {exclusive1: true};
//=> Works
exclusiveOptions = {exclusive2: 'hi'};
//=> Works
exclusiveOptions = {exclusive1: true, exclusive2: 'hi'};
//=> Error
```
@category Object
*/
type MergeExclusive<FirstType, SecondType> =
(FirstType | SecondType) extends object ?
(Without<FirstType, SecondType> & SecondType) | (Without<SecondType, FirstType> & FirstType) :
FirstType | SecondType;
declare function temporaryDirectory({ prefix }?: {
prefix?: string | undefined;
}): Promise<string>;
type FileOptions = MergeExclusive<{
/**
* File extension.
*
* Mutually exclusive with the `name` option.
*
* _You usually won't need this option. Specify it only when actually needed._
*/
readonly extension?: string;
}, {
/**
* Filename.
*
* Mutually exclusive with the `extension` option.
*
* _You usually won't need this option. Specify it only when actually needed._
*/
readonly name?: string;
}>;
declare function temporaryFile({ name, extension }?: FileOptions): Promise<string>;
declare function parseList(str: string): string[];
declare function getEnvConfig(program: Record<string, any>, configEnv: Record<string, any>): void;
/**
* Given a file name, creates an object with utilities to manage a log file. It creates a temporary
* log file which you can manage with the returned functions. You can then decide whether to move
* the log file to the users project, or remove it.
*
* @example
*
* ```ts
* const { logStream, moveLogFile, removeLogFile, clearLogFile, readLogFile } =
* await createLogStream('my-log-file.log');
*
* // SCENARIO 1:
* // you can write custom messages to generate a log file
* logStream.write('my log message');
* await moveLogFile();
*
* // SCENARIO 2:
* // or you can pass it to stdio and capture the output of that command
* try {
* await executeCommand({
* command: 'pnpm',
* args: ['info', packageName, ...args],
* // do not output to the user, and send stdio and stderr to log file
* stdio: ['ignore', logStream, logStream],
* });
* } catch (err) {
* // do something with the log file content
* const output = await readLogFile();
* // move the log file to the users project
* await moveLogFile();
* }
* // success, no need to keep the log file
* await removeLogFile();
* ```
*/
declare const createLogStream: (logFileName?: string) => Promise<{
moveLogFile: () => Promise<void>;
removeLogFile: () => Promise<void>;
clearLogFile: () => Promise<void>;
readLogFile: () => Promise<string>;
logStream: WriteStream;
}>;
declare const isCorePackage: (pkg: string) => boolean;
declare const isSatelliteAddon: (pkg: string) => boolean;
interface Options$1 {
before: CoreCommon_AddonInfo;
after: CoreCommon_AddonInfo;
configFile: string;
getConfig: (path: string) => any;
}
declare const checkAddonOrder: ({ before, after, configFile, getConfig }: Options$1) => Promise<void>;
declare function loadEnvs(options?: {
production?: boolean;
}): Promise<{
stringified: Record<string, string>;
raw: Record<string, string>;
}>;
declare const stringifyEnvs: (raw: Record<string, string>) => Record<string, string>;
declare const stringifyProcessEnvs: (raw: Record<string, string>) => Record<string, string>;
declare const optionalEnvToBoolean: (input: string | undefined) => boolean | undefined;
/**
* Consistently determine if we are in a CI environment
*
* Doing Boolean(process.env.CI) or !process.env.CI is not enough, because users might set CI=false
* or CI=0, which would be truthy, and thus return true in those cases.
*/
declare function isCI(): boolean | undefined;
declare const commonGlobOptions: (glob: string) => {
ignore?: undefined;
} | {
ignore: string[];
};
declare const frameworkToRenderer: Record<SupportedFramework | SupportedRenderer, SupportedRenderer>;
declare const frameworkToBuilder: Record<SupportedFramework, SupportedBuilder>;
/**
* Builder options can be specified in `core.builder.options` or `framework.options.builder`.
* Preference is given here to `framework.options.builder` if both are specified.
*/
declare function getBuilderOptions<T extends Record<string, any>>(options: Options$2): Promise<T | Record<string, never>>;
/** Framework can be a string or an object. This utility always returns the string name. */
declare function getFrameworkName(options: Options$2): Promise<string>;
/**
* Extracts the proper framework name from the given framework field. The framework field can be the
* framework package name or a path to the framework package.
*
* @example
*
* ```ts
* extractFrameworkPackageName('/path/to/@storybook/angular'); // => '@storybook/angular'
* extractFrameworkPackageName('@third-party/framework'); // => '@third-party/framework'
* ```
*/
declare const extractFrameworkPackageName: (framework: string) => string;
/**
* Render is set as a string on core. It must be set by the framework It falls back to the framework
* name if not set
*/
declare function getRendererName(options: Options$2): Promise<string>;
/**
* Extracts the proper renderer name from the given framework name.
*
* @example
*
* ```ts
* extractRenderer('@storybook/react'); // => 'react'
* extractRenderer('@storybook/angular'); // => 'angular'
* extractRenderer('@third-party/framework'); // => null
* ```
*
* @param frameworkName The name of the framework.
* @returns The name of the renderer.
*/
declare function extractRenderer(frameworkName: string): Promise<storybook_internal_types.SupportedRenderer | null>;
declare function getStorybookConfiguration(storybookScript: string, shortName: string, longName: string): string | null;
declare const rendererPackages: Record<string, SupportedRenderer>;
declare const frameworkPackages: Record<string, SupportedFramework>;
declare const builderPackages: Record<string, SupportedBuilder>;
declare const compilerPackages: Record<string, CoreWebpackCompiler>;
declare const findConfigFile: (prefix: string, configDir: string) => string | null;
declare const getConfigInfo: (configDir?: string) => {
configDir: string;
mainConfigPath: string | null;
previewConfigPath: string | null;
managerConfigPath: string | null;
};
declare const getStorybookInfo: (configDir?: string, cwd?: string) => Promise<CoreCommon_StorybookInfo>;
declare const getAutoRefs: (options: Options$2) => Promise<Record<string, Ref>>;
declare const checkRef: (url: string) => Promise<boolean>;
declare function getRefs(options: Options$2): Promise<Record<string, Ref>>;
declare function globToRegexp(glob: string): RegExp;
declare class HandledError extends Error {
handled: boolean;
constructor(error: unknown);
}
/**
* Return a string corresponding to template filled with bindings using following pattern: For each
* (key, value) of `bindings` replace, in template, `{{key}}` by escaped version of `value`
*
* @param template {String} Template with `{{binding}}`
* @param bindings {Object} key-value object use to fill the template, `{{key}}` will be replaced by
* `escaped(value)`
* @returns {String} Filled template
*/
declare const interpolate: (template: string, bindings: Record<string, string>) => string;
interface PackageMeta {
name: string;
version: string;
[key: string]: any;
}
interface ToString {
toString(): string;
}
type StringOrToString = string | ToString;
/**
* Callback invoked when resolving asynchronously
*
* @param error
* @param resolved Absolute path to resolved identifier
*/
type resolveCallback = (err: Error | null, resolved?: string, pkg?: PackageMeta) => void;
/**
* Callback invoked when checking if a file or directory exists
*
* @param error
* @param exists If the given file or directory exists
*/
type existsCallback = (err: Error | null, isFile?: boolean) => void;
/**
* Callback invoked when reading a file
*
* @param error
* @param isFile If the given file exists
*/
type readFileCallback = (err: Error | null, file?: StringOrToString) => void;
/**
* Callback invoked when resolving a potential symlink
*
* @param error
* @param resolved Absolute path to the resolved file
*/
type realpathCallback = (err: Error | null, resolved?: string) => void;
/**
* Callback invoked when reading and parsing a package.json file
*
* @param error
* @param resolved Absolute path to the resolved file
*/
type readPackageCallback = (err: Error | null, package?: Record<string, unknown>) => void;
/**
* Synchronously resolve the module path string id, returning the result and throwing an error when id can't be resolved.
*
* @param id Identifier to resolve
* @param options Options to use for resolving, optional.
*/
declare function resolveSync(id: string, opts?: resolve.SyncOpts): string;
/**
* Return whether a package is in core
*/
declare function resolveIsCore(id: string): boolean | undefined;
// https://github.com/Microsoft/TypeScript/issues/3496#issuecomment-128553540
type JSONValue = string | number | boolean | JSONObject | JSONArray;
interface JSONObject {
[x: string]: JSONValue;
}
interface JSONArray extends Array<JSONValue> {}
/**
* Asynchronously resolve the module path string id into cb(err, res [, pkg]), where pkg (if defined) is the data from package.json
*
* @param id Identifier to resolve
* @param callback
*/
declare function resolve(id: string, cb: resolveCallback): void;
/**
* Asynchronously resolve the module path string id into cb(err, res [, pkg]), where pkg (if defined) is the data from package.json
*
* @param id Identifier to resolve
* @param options Options to use for resolving, optional.
* @param callback
*/
declare function resolve(id: string, opts: resolve.AsyncOpts, cb: resolveCallback): void;
declare namespace resolve {
export type PackageJSON = JSONObject;
interface Opts {
/** directory to begin resolving from (defaults to __dirname) */
basedir?: string | undefined;
/** package.json data applicable to the module being loaded */
package?: any;
/** set to false to exclude node core modules (e.g. fs) from the search */
includeCoreModules?: boolean | undefined;
/** array of file extensions to search in order (defaults to ['.js']) */
extensions?: string | readonly string[] | undefined;
/** transform the parsed package.json contents before looking at the "main" field */
packageFilter?: ((pkg: PackageJSON, pkgFile: string, dir: string) => PackageJSON) | undefined;
/** transform a path within a package */
pathFilter?: ((pkg: PackageJSON, path: string, relativePath: string) => string) | undefined;
/** require.paths array to use if nothing is found on the normal node_modules recursive walk (probably don't use this) */
paths?: string | readonly string[] | undefined;
/** return the list of candidate paths where the packages sources may be found (probably don't use this) */
packageIterator?:
| ((request: string, start: string, getPackageCandidates: () => string[], opts: Opts) => string[])
| undefined;
/** directory (or directories) in which to recursively look for modules. (default to 'node_modules') */
moduleDirectory?: string | readonly string[] | undefined;
/**
* if true, doesn't resolve `basedir` to real path before resolving.
* This is the way Node resolves dependencies when executed with the --preserve-symlinks flag.
*
* Note: this property is currently true by default but it will be changed to false in the next major version because Node's resolution
* algorithm does not preserve symlinks by default.
*/
preserveSymlinks?: boolean | undefined;
}
interface BaseAsyncOpts extends Opts {
/** function to asynchronously test whether a file exists */
isFile?: ((file: string, cb: existsCallback) => void) | undefined;
/** function to asynchronously test whether a directory exists */
isDirectory?: ((directory: string, cb: existsCallback) => void) | undefined;
/** function to asynchronously resolve a potential symlink to its real path */
realpath?: ((file: string, cb: realpathCallback) => void) | undefined;
}
export type AsyncOpts =
& BaseAsyncOpts
& ({
/** how to read files asynchronously (defaults to fs.readFile) */
readFile?: ((file: string, cb: readFileCallback) => void) | undefined;
/** function to asynchronously read and parse a package.json file */
readPackage?: never | undefined;
} | {
/** how to read files asynchronously (defaults to fs.readFile) */
readFile?: never | undefined;
/** function to asynchronously read and parse a package.json file */
readPackage?:
| ((
readFile: (file: string, cb: readFileCallback) => void,
pkgfile: string,
cb: readPackageCallback,
) => void)
| undefined;
});
interface BaseSyncOpts extends Opts {
/** function to synchronously test whether a file exists */
isFile?: ((file: string) => boolean) | undefined;
/** function to synchronously test whether a directory exists */
isDirectory?: ((directory: string) => boolean) | undefined;
/** function to synchronously resolve a potential symlink to its real path */
realpathSync?: ((file: string) => string) | undefined;
}
export type SyncOpts =
& BaseSyncOpts
& ({
/** how to read files synchronously (defaults to fs.readFileSync) */
readFileSync?: ((file: string) => StringOrToString) | undefined;
/** function to synchronously read and parse a package.json file */
readPackageSync?: never | undefined;
} | {
/** how to read files synchronously (defaults to fs.readFileSync) */
readFileSync?: never | undefined;
/** function to synchronously read and parse a package.json file */
readPackageSync?:
| ((
readFileSync: (file: string) => StringOrToString,
pkgfile: string,
) => Record<string, unknown> | undefined)
| undefined;
});
export var sync: typeof resolveSync;
export var isCore: typeof resolveIsCore;
}
declare const supportedExtensions: readonly [".js", ".ts", ".jsx", ".tsx", ".mjs", ".mts", ".mtsx", ".cjs", ".cts", ".ctsx"];
declare function getInterpretedFile(pathToFile: string): string | undefined;
declare function resolveImport(id: string, options: resolve.SyncOpts): string;
declare function serverRequire(filePath: string | string[]): Promise<any> | null;
declare function loadMainConfig({ configDir, cwd, skipCache, }: {
configDir: string;
cwd?: string;
skipCache?: boolean;
}): Promise<StorybookConfig>;
declare function loadManagerOrAddonsFile({ configDir }: {
configDir: string;
}): string | undefined;
declare function loadPreviewOrConfigFile({ configDir }: {
configDir: string;
}): string | undefined;
declare function logConfig(caption: unknown, config: unknown): void;
declare const DEFAULT_FILES_PATTERN = "**/*.@(mdx|stories.@(js|jsx|mjs|ts|tsx))";
declare const getDirectoryFromWorkingDir: ({ configDir, workingDir, directory, }: NormalizeOptions & {
directory: string;
}) => string;
declare const normalizeStoriesEntry: (entry: StoriesEntry, { configDir, workingDir, defaultFilesPattern }: NormalizeOptions) => NormalizedStoriesSpecifier;
interface NormalizeOptions {
configDir: string;
workingDir: string;
defaultFilesPattern?: string;
}
declare const normalizeStories: (entries: StoriesEntry[], options: NormalizeOptions) => NormalizedStoriesSpecifier[];
declare const getProjectRoot: () => string;
declare const invalidateProjectRootCache: () => void;
/** Finds files in the directory tree up to the project root */
declare const findFilesUp: (matchers: string[], baseDir?: string) => string[];
declare const nodePathsToArray: (nodePath: string) => string[];
/** Ensures that a path starts with `./` or `../`, or is entirely `.` or `..` */
declare function normalizeStoryPath(filename: string): string;
declare function readTemplate(filename: string): Promise<string>;
type Not<Value extends boolean> = Value extends true ? false : true;
type And<First extends boolean, Second extends boolean> = First extends true ? Second : false;
type Or<First extends boolean, Second extends boolean> = First extends true ? true : Second;
type Unless<Condition extends boolean, ThenValue, ElseValue = never> = Condition extends true ? ElseValue : ThenValue;
type AndUnless<Condition extends boolean, ThenValue, ElseValue = unknown> = Condition extends true ? ElseValue : ThenValue;
// Whether any of T's union element is the same as one of U's union element.
// `&` does not work here.
type Intersects<T, U> = true extends (T extends U ? true : false) ? true : false;
// `options.std*: Generator`
// @todo Use `string`, `Uint8Array` or `unknown` for both the argument and the return type, based on whether `encoding: 'buffer'` and `objectMode: true` are used.
// See https://github.com/sindresorhus/execa/issues/694
type GeneratorTransform<IsSync extends boolean> = (chunk: unknown) =>
| Unless<IsSync, AsyncGenerator<unknown, void, void>>
| Generator<unknown, void, void>;
type GeneratorFinal<IsSync extends boolean> = () =>
| Unless<IsSync, AsyncGenerator<unknown, void, void>>
| Generator<unknown, void, void>;
type TransformCommon = {
/**
If `true`, allow `transformOptions.transform` and `transformOptions.final` to return any type, not just `string` or `Uint8Array`.
*/
readonly objectMode?: boolean;
};
/**
A transform or an array of transforms can be passed to the `stdin`, `stdout`, `stderr` or `stdio` option.
A transform is either a generator function or a plain object with the following members.
*/
type GeneratorTransformFull<IsSync extends boolean> = {
/**
Map or filter the input or output of the subprocess.
*/
readonly transform: GeneratorTransform<IsSync>;
/**
Create additional lines after the last one.
*/
readonly final?: GeneratorFinal<IsSync>;
/**
If `true`, iterate over arbitrary chunks of `Uint8Array`s instead of line `string`s.
*/
readonly binary?: boolean;
/**
If `true`, keep newlines in each `line` argument. Also, this allows multiple `yield`s to produces a single line.
*/
readonly preserveNewlines?: boolean;
} & TransformCommon;
// `options.std*: Duplex`
type DuplexTransform = {
readonly transform: Duplex;
} & TransformCommon;
// `options.std*: TransformStream`
type WebTransform = {
readonly transform: TransformStream;
} & TransformCommon;
type IsStandardStream<FdNumber extends string> = FdNumber extends keyof StandardStreams ? true : false;
type StandardStreams = readonly ['stdin', 'stdout', 'stderr'];
// When `options.stdin|stdout|stderr|stdio` is set to one of those values, no stream is created
type NoStreamStdioOption<FdNumber extends string> =
| 'ignore'
| 'inherit'
| 'ipc'
| number
| Readable
| Writable
| Unless<IsStandardStream<FdNumber>, undefined>
| readonly [NoStreamStdioOption<FdNumber>];
// `options.stdio` when it is not an array
type SimpleStdioOption<
IsSync extends boolean,
IsExtra extends boolean,
IsArray extends boolean,
> =
| undefined
| 'pipe'
| Unless<And<And<Not<IsSync>, IsArray>, IsExtra>, 'inherit'>
| Unless<IsArray, 'ignore'>
| Unless<IsSync, 'overlapped'>;
// Values available in both `options.stdin|stdio` and `options.stdout|stderr|stdio`
type CommonStdioOption<
IsSync extends boolean,
IsExtra extends boolean,
IsArray extends boolean,
> =
| SimpleStdioOption<IsSync, IsExtra, IsArray>
| URL
| {readonly file: string; readonly append?: boolean}
| GeneratorTransform<IsSync>
| GeneratorTransformFull<IsSync>
| Unless<And<Not<IsSync>, IsArray>, 3 | 4 | 5 | 6 | 7 | 8 | 9>
| Unless<Or<IsSync, IsArray>, 'ipc'>
| Unless<IsSync, DuplexTransform | WebTransform | TransformStream>;
// Synchronous iterables excluding strings, Uint8Arrays and Arrays
type IterableObject<IsArray extends boolean> = Iterable<unknown>
& object
& {readonly BYTES_PER_ELEMENT?: never}
& AndUnless<IsArray, {readonly lastIndexOf?: 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`
type InputStdioOption<
IsSync extends boolean = boolean,
IsExtra extends boolean = boolean,
IsArray extends boolean = boolean,
> =
| 0
| Unless<And<IsSync, IsExtra>, Uint8Array | IterableObject<IsArray>>
| Unless<And<IsSync, IsArray>, Readable & ProcessStdinFd>
| Unless<IsSync, (AsyncIterable<unknown> & ProcessStdinFd) | ReadableStream>;
// Values available only in `options.stdout|stderr|stdio`
type OutputStdioOption<
IsSync extends boolean,
IsArray extends boolean,
> =
| 1
| 2
| Unless<And<IsSync, IsArray>, Writable & ProcessStdoutStderrFd>
| Unless<IsSync, WritableStream>;
// `options.stdin` array items
type StdinSingleOption<
IsSync extends boolean,
IsExtra extends boolean,
IsArray extends boolean,
> =
| CommonStdioOption<IsSync, IsExtra, IsArray>
| InputStdioOption<IsSync, IsExtra, IsArray>;
// `options.stdin`
type StdinOptionCommon<
IsSync extends boolean = boolean,
IsExtra extends boolean = boolean,
> =
| StdinSingleOption<IsSync, IsExtra, false>
| ReadonlyArray<StdinSingleOption<IsSync, IsExtra, true>>;
// `options.stdout|stderr` array items
type StdoutStderrSingleOption<
IsSync extends boolean,
IsExtra extends boolean,
IsArray extends boolean,
> =
| CommonStdioOption<IsSync, IsExtra, IsArray>
| OutputStdioOption<IsSync, IsArray>;
// `options.stdout|stderr`
type StdoutStderrOptionCommon<
IsSync extends boolean = boolean,
IsExtra extends boolean = boolean,
> =
| StdoutStderrSingleOption<IsSync, IsExtra, false>
| ReadonlyArray<StdoutStderrSingleOption<IsSync, IsExtra, true>>;
// `options.stdio[3+]`
type StdioExtraOptionCommon<IsSync extends boolean> =
| StdinOptionCommon<IsSync, true>
| StdoutStderrOptionCommon<IsSync, true>;
// `options.stdin|stdout|stderr|stdio` array items
type StdioSingleOption<
IsSync extends boolean = boolean,
IsExtra extends boolean = boolean,
IsArray extends boolean = boolean,
> =
| StdinSingleOption<IsSync, IsExtra, IsArray>
| StdoutStderrSingleOption<IsSync, IsExtra, IsArray>;
// Get `options.stdin|stdout|stderr|stdio` items if it is an array, else keep as is
type StdioSingleOptionItems<StdioOptionType> = StdioOptionType extends readonly StdioSingleOption[]
? StdioOptionType[number]
: StdioOptionType;
// `options.stdin|stdout|stderr|stdio`
type StdioOptionCommon<IsSync extends boolean = boolean> =
| StdinOptionCommon<IsSync>
| StdoutStderrOptionCommon<IsSync>;
// `options.stdio` when it is an array
type StdioOptionsArray<IsSync extends boolean = boolean> = readonly [
StdinOptionCommon<IsSync, false>,
StdoutStderrOptionCommon<IsSync, false>,
StdoutStderrOptionCommon<IsSync, false>,
...ReadonlyArray<StdioExtraOptionCommon<IsSync>>,
];
// `options.stdio`
type StdioOptionsProperty<IsSync extends boolean = boolean> =
| SimpleStdioOption<IsSync, false, false>
| StdioOptionsArray<IsSync>;
// Message when the `serialization` option is `'advanced'`
type AdvancedMessage =
| string
| number
| boolean
| null
| object;
// Message when the `serialization` option is `'json'`
type JsonMessage =
| string
| number
| boolean
| null
| readonly JsonMessage[]
| {readonly [key: string | number]: JsonMessage};
/**
Type of messages exchanged between a process and its subprocess using `sendMessage()`, `getOneMessage()` and `getEachMessage()`.
This requires the `ipc` option to be `true`. The type of `message` depends on the `serialization` option.
*/
type Message<
Serialization extends Options['serialization'] = Options['serialization'],
> = Serialization extends 'json' ? JsonMessage : AdvancedMessage;
/**
Options to `sendMessage()` and `subprocess.sendMessage()`
*/
type SendMessageOptions = {
/**
Throw when the other process is not receiving or listening to messages.
@default false
*/
readonly strict?: boolean;
};
/**
Options to `getOneMessage()` and `subprocess.getOneMessage()`
*/
type GetOneMessageOptions<
Serialization extends Options['serialization'],
> = {
/**
Ignore any `message` that returns `false`.
*/
readonly filter?: (message: Message<Serialization>) => boolean;
/**
Keep the subprocess alive while `getOneMessage()` is waiting.
@default true
*/
readonly reference?: boolean;
};
/**
Options to `getEachMessage()` and `subprocess.getEachMessage()`
*/
type GetEachMessageOptions = {
/**
Keep the subprocess alive while `getEachMessage()` is waiting.
@default true
*/
readonly reference?: boolean;
};
// IPC methods in the subprocess
type IpcMethods<
IpcEnabled extends boolean,
Serialization extends Options['serialization'],
> = IpcEnabled extends true
? {
/**
Send a `message` to the subprocess.
This requires the `ipc` option to be `true`. The type of `message` depends on the `serialization` option.
*/
sendMessage(message: Message<Serialization>, sendMessageOptions?: SendMessageOptions): Promise<void>;
/**
Receive a single `message` from the subprocess.
This requires the `ipc` option to be `true`. The type of `message` depends on the `serialization` option.
*/
getOneMessage(getOneMessageOptions?: GetOneMessageOptions<Serialization>): Promise<Message<Serialization>>;
/**
Iterate over each `message` from the subprocess.
This requires the `ipc` option to be `true`. The type of `message` depends on the `serialization` option.
*/
getEachMessage(getEachMessageOptions?: GetEachMessageOptions): AsyncIterableIterator<Message<Serialization>>;
}
// Those methods only work if the `ipc` option is `true`.
// At runtime, they are actually defined, in order to provide with a nice error message.
// At type check time, they are typed as `undefined` to prevent calling them.
: {
sendMessage: undefined;
getOneMessage: undefined;
getEachMessage: undefined;
};
// Whether IPC is enabled, based on the `ipc`, `ipcInput` and `gracefulCancel` options
type HasIpc<OptionsType extends Options> = HasIpcOption<
OptionsType['ipc'],
'ipcInput' extends keyof OptionsType ? OptionsType['ipcInput'] : undefined,
'gracefulCancel' extends keyof OptionsType ? OptionsType['gracefulCancel'] : undefined
>;
type HasIpcOption<
IpcOption extends Options['ipc'],
IpcInputOption extends Options['ipcInput'],
GracefulCancelOption extends Options['gracefulCancel'],
> = IpcOption extends true
? true
: IpcOption extends false
? false
: IpcInputOption extends undefined
? GracefulCancelOption extends true
? true
: false
: true;
type FileDescriptorOption = `fd${number}`;
// `from` option of `subprocess.readable|duplex|iterable|pipe()`
// Also used by fd-specific options
type FromOption = 'stdout' | 'stderr' | 'all' | FileDescriptorOption;
// `to` option of `subprocess.writable|duplex|pipe()`
type ToOption = 'stdin' | FileDescriptorOption;
// Options which can be fd-specific like `{verbose: {stdout: 'none', stderr: 'full'}}`
type FdGenericOption<OptionType> = OptionType | GenericOptionObject<OptionType>;
type GenericOptionObject<OptionType> = {
readonly [FdName in GenericFromOption]?: OptionType
};
type GenericFromOption = FromOption | 'ipc';
// Retrieve fd-specific option's value
type FdSpecificOption<
GenericOption extends FdGenericOption<unknown>,
FdNumber extends string,
> = GenericOption extends GenericOptionObject<unknown>
? FdSpecificObjectOption<GenericOption, FdNumber>
: GenericOption;
type FdSpecificObjectOption<
GenericOption extends GenericOptionObject<unknown>,
FdNumber extends string,
> = keyof GenericOption extends GenericFromOption
? FdNumberToFromOption<FdNumber, keyof GenericOption> extends never
? undefined
: GenericOption[FdNumberToFromOption<FdNumber, keyof GenericOption>]
: GenericOption;
type FdNumberToFromOption<
FdNumber extends string,
GenericOptionKeys extends GenericFromOption,
> = FdNumber extends '1'
? 'stdout' extends GenericOptionKeys
? 'stdout'
: 'fd1' extends GenericOptionKeys
? 'fd1'
: 'all' extends GenericOptionKeys
? 'all'
: never
: FdNumber extends '2'
? 'stderr' extends GenericOptionKeys
? 'stderr'
: 'fd2' extends GenericOptionKeys
? 'fd2'
: 'all' extends GenericOptionKeys
? 'all'
: never
: `fd${FdNumber}` extends GenericOptionKeys
? `fd${FdNumber}`
: 'ipc' extends GenericOptionKeys
? 'ipc'
: never;
// `result.*` defined only on failure, i.e. on `error.*`
type ErrorProperties =
| 'name'
| 'message'
| 'stack'
| 'cause'
| 'shortMessage'
| 'originalMessage'
| 'code';
// `options.stdio`, normalized as an array
type StdioOptionNormalizedArray<OptionsType extends CommonOptions> = StdioOptionNormalized<OptionsType['stdio']>;
type StdioOptionNormalized<StdioOption extends CommonOptions['stdio']> = StdioOption extends StdioOptionsArray
? StdioOption
: StdioOption extends StdinOptionCommon
? StdioOption extends StdoutStderrOptionCommon
? readonly [StdioOption, StdioOption, StdioOption]
: DefaultStdioOption
: DefaultStdioOption;
// `options.stdio` default value
type DefaultStdioOption = readonly ['pipe', 'pipe', 'pipe'];
// `options.stdin|stdout|stderr|stdio` for a given file descriptor
type FdStdioOption<
FdNumber extends string,
OptionsType extends CommonOptions,
> = FdStdioOptionProperty<FdNumber, OptionsType>;
type FdStdioOptionProperty<
FdNumber extends string,
OptionsType extends CommonOptions,
> = string extends FdNumber ? StdioOptionCommon
: FdNumber extends keyof StandardStreams
? StandardStreams[FdNumber] extends keyof OptionsType
? OptionsType[StandardStreams[FdNumber]] extends undefined
? FdStdioArrayOption<FdNumber, OptionsType>
: OptionsType[StandardStreams[FdNumber]]
: FdStdioArrayOption<FdNumber, OptionsType>
: FdStdioArrayOption<FdNumber, OptionsType>;
// `options.stdio[FdNumber]`, excluding `options.stdin|stdout|stderr`
type FdStdioArrayOption<
FdNumber extends string,
OptionsType extends CommonOptions,
> = FdStdioArrayOptionProperty<FdNumber, StdioOptionNormalizedArray<OptionsType>>;
type FdStdioArrayOptionProperty<
FdNumber extends string,
StdioOptionsType,
> = string extends FdNumber
? StdioOptionCommon | undefined
: StdioOptionsType extends StdioOptionsArray
? FdNumber extends keyof StdioOptionsType
? StdioOptionsType[FdNumber]
: StdioOptionNormalizedArray<CommonOptions> extends StdioOptionsType
? StdioOptionsType[number]
: undefined
: undefined;
// Whether a file descriptor is in object mode
// I.e. whether `result.stdout|stderr|stdio|all` is an array of `unknown` due to `objectMode: true`
type IsObjectFd<
FdNumber extends string,
OptionsType extends CommonOptions,
> = IsObjectStdioOption<FdStdioOption<FdNumber, OptionsType>>;
type IsObjectStdioOption<StdioOptionType> = IsObjectStdioSingleOption<StdioSingleOptionItems<StdioOptionType>>;
type IsObjectStdioSingleOption<StdioSingleOptionType> = StdioSingleOptionType extends TransformCommon
? BooleanObjectMode<StdioSingleOptionType['objectMode']>
: StdioSingleOptionType extends DuplexTransform
? StdioSingleOptionType['transform']['readableObjectMode']
: false;
type BooleanObjectMode<ObjectModeOption extends boolean | undefined> = ObjectModeOption extends true ? true : false;
// Whether `result.stdio[FdNumber]` is an input stream
type IsInputFd<
FdNumber extends string,
OptionsType extends CommonOptions,
> = FdNumber extends '0'
? true
: Intersects<StdioSingleOptionItems<FdStdioArrayOption<FdNumber, OptionsType>>, InputStdioOption>;
// Whether `result.stdin|stdout|stderr|all|stdio[*]` is `undefined`
type IgnoresResultOutput<
FdNumber extends string,
OptionsType extends CommonOptions,
> = FdSpecificOption<OptionsType['buffer'], FdNumber> extends false
? true
: IsInputFd<FdNumber, OptionsType> extends true
? true
: IgnoresSubprocessOutput<FdNumber, OptionsType>;
// Whether `subprocess.stdout|stderr|all` is `undefined|null`
type IgnoresSubprocessOutput<
FdNumber extends string,
OptionsType extends CommonOptions,
> = IgnoresOutput<FdNumber, FdStdioOption<FdNumber, OptionsType>>;
type IgnoresOutput<
FdNumber extends string,
StdioOptionType,
> = StdioOptionType extends NoStreamStdioOption<FdNumber> ? true : false;
type DefaultEncodingOption = 'utf8';
type TextEncodingOption =
| DefaultEncodingOption
| 'utf16le';
type BufferEncodingOption = 'buffer';
type BinaryEncodingOption =
| BufferEncodingOption
| 'hex'
| 'base64'
| 'base64url'
| 'latin1'
| 'ascii';
// `options.encoding`
type EncodingOption =
| TextEncodingOption
| BinaryEncodingOption
| undefined;
// `result.stdout|stderr|stdio`
type ResultStdioNotAll<
FdNumber extends string,
OptionsType extends CommonOptions,
> = ResultStdio<FdNumber, FdNumber, FdNumber, OptionsType>;
// `result.stdout|stderr|stdio|all`
type ResultStdio<
MainFdNumber extends string,
ObjectFdNumber extends string,
LinesFdNumber extends string,
OptionsType extends CommonOptions,
> = ResultStdioProperty<
ObjectFdNumber,
LinesFdNumber,
IgnoresResultOutput<MainFdNumber, OptionsType>,
OptionsType
>;
type ResultStdioProperty<
ObjectFdNumber extends string,
LinesFdNumber extends string,
StreamOutputIgnored,
OptionsType extends CommonOptions,
> = StreamOutputIgnored extends true
? undefined
: ResultStdioItem<
IsObjectFd<ObjectFdNumber, OptionsType>,
FdSpecificOption<OptionsType['lines'], LinesFdNumber>,
OptionsType['encoding']
>;
type ResultStdioItem<
IsObjectResult,
LinesOption extends boolean | undefined,
Encoding extends CommonOptions['encoding'],
> = IsObjectResult extends true ? unknown[]
: Encoding extends BufferEncodingOption
? Uint8Array
: LinesOption extends true
? Encoding extends BinaryEncodingOption
? string
: string[]
: string;
// `result.all`
type ResultAll<OptionsType extends CommonOptions> =
ResultAllProperty<OptionsType['all'], OptionsType>;
type ResultAllProperty<
AllOption extends CommonOptions['all'],
OptionsType extends CommonOptions,
> = AllOption extends true
? ResultStdio<
AllMainFd<OptionsType>,
AllObjectFd<OptionsType>,
AllLinesFd<OptionsType>,
OptionsType
>
: undefined;
type AllMainFd<OptionsType extends CommonOptions> =
IgnoresResultOutput<'1', OptionsType> extends true ? '2' : '1';
type AllObjectFd<OptionsType extends CommonOptions> =
IsObjectFd<'1', OptionsType> extends true ? '1' : '2';
type AllLinesFd<OptionsType extends CommonOptions> =
FdSpecificOption<OptionsType['lines'], '1'> extends true ? '1' : '2';
// `result.stdio`
type ResultStdioArray<OptionsType extends CommonOptions> =
MapResultStdio<StdioOptionNormalizedArray<OptionsType>, OptionsType>;
type MapResultStdio<
StdioOptionsArrayType,
OptionsType extends CommonOptions,
> = {
-readonly [FdNumber in keyof StdioOptionsArrayType]: ResultStdioNotAll<
FdNumber extends string ? FdNumber : string,
OptionsType
>
};
// `result.ipcOutput`
// This is empty unless the `ipc` option is `true`.
// Also, this is empty if the `buffer` option is `false`.
type ResultIpcOutput<
IsSync,
OptionsType extends CommonOptions,
> = IsSync extends true
? []
: ResultIpcAsync<
FdSpecificOption<OptionsType['buffer'], 'ipc'>,
HasIpc<StricterOptions<OptionsType, Options>>,
OptionsType['serialization']
>;
type ResultIpcAsync<
BufferOption extends boolean | undefined,
IpcEnabled extends boolean,
SerializationOption extends CommonOptions['serialization'],
> = BufferOption extends false
? []
: IpcEnabled extends true
? Array<Message<SerializationOption>>
: [];
declare abstract class CommonResult<
IsSync extends boolean,
OptionsType extends CommonOptions,
> {
/**
The output of the subprocess on [`stdout`](https://en.wikipedia.org/wiki/Standard_streams#Standard_output_(stdout)).
This is `undefined` if the `stdout` option is set to only `'inherit'`, `'ignore'`, `Writable` or `integer`, or if the `buffer` option is `false`.
This is an array if the `lines` option is `true`, or if the `stdout` option is a transform in object mode.
*/
stdout: ResultStdioNotAll<'1', OptionsType>;
/**
The output of the subprocess on [`stderr`](https://en.wikipedia.org/wiki/Standard_streams#Standard_error_(stderr)).
This is `undefined` if the `stderr` option is set to only `'inherit'`, `'ignore'`, `Writable` or `integer`, or if the `buffer` option is `false`.
This is an array if the `lines` option is `true`, or if the `stderr` option is a transform in object mode.
*/
stderr: ResultStdioNotAll<'2', OptionsType>;
/**
The output of the subprocess with `result.stdout` and `result.stderr` interleaved.
This requires the `all` option to be `true`.
This is `undefined` if both `stdout` and `stderr` options are set to only `'inherit'`, `'ignore'`, `Writable` or `integer`, or if the `buffer` option is `false`.
This is an array if the `lines` option is `true`, or if either the `stdout` or `stderr` option is a transform in object mode.
*/
all: ResultAll<OptionsType>;
/**
The output of the subprocess on `stdin`, `stdout`, `stderr` and other file descriptors.
Items are `undefined` when their corresponding `stdio` option is set to only `'inherit'`, `'ignore'`, `Writable` or `integer`, or if the `buffer` option is `false`.
Items are arrays when their corresponding `stdio` option is a transform in object mode.
*/
stdio: ResultStdioArray<OptionsType>;
/**
All the messages sent by the subprocess to the current process.
This is empty unless the `ipc` option is `true`. Also, this is empty if the `buffer` option is `false`.
*/
ipcOutput: ResultIpcOutput<IsSync, OptionsType>;
/**
Results of the other subprocesses that were piped into this subprocess.
This array is initially empty and is populated each time the `subprocess.pipe()` method resolves.
*/
pipedFrom: Unless<IsSync, Result[], []>;
/**
The file and arguments that were run.
*/
command: string;
/**
Same as `command` but escaped.
*/
escapedCommand: string;
/**
The current directory in which the command was run.
*/
cwd: string;
/**
Duration of the subprocess, in milliseconds.
*/
durationMs: number;
/**
Whether the subprocess failed to run.
When this is `true`, the result is an `ExecaError` instance with additional error-related properties.
*/
failed: boolean;
/**
Whether the subprocess timed out due to the `timeout` option.
*/
timedOut: boolean;
/**
Whether the subprocess was canceled using the `cancelSignal` option.
*/
isCanceled: boolean;
/**
Whether the subprocess was canceled using both the `cancelSignal` and the `gracefulCancel` options.
*/
isGracefullyCanceled: boolean;
/**
Whether the subprocess failed because its output was larger than the `maxBuffer` option.
*/
isMaxBuffer: boolean;
/**
Whether the subprocess was terminated by a signal (like `SIGTERM`) sent by either:
- The current process.
- Another process. This case is [not supported on Windows](https://nodejs.org/api/process.html#signal-events).
*/
isTerminated: boolean;
/**
Whether the subprocess was terminated by the `SIGKILL` signal sent by the `forceKillAfterDelay` option.
*/
isForcefullyTerminated: boolean;
/**
The numeric [exit code](https://en.wikipedia.org/wiki/Exit_status) of the subprocess that was run.
This is `undefined` when the subprocess could not be spawned or was terminated by a signal.
*/
exitCode?: number;
/**
The name of the signal (like `SIGTERM`) that terminated the subprocess, sent by either:
- The current process.
- Another process. This case is [not supported on Windows](https://nodejs.org/api/process.html#signal-events).
If a signal terminated the subprocess, this property is defined and included in the error message. Otherwise it is `undefined`.
*/
signal?: keyof SignalConstants;
/**
A human-friendly description of the signal that was used to terminate the subprocess.
If a signal terminated the subprocess, 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;
/**
Error message when the subprocess failed to run.
*/
message?: string;
/**
This is the same as `error.message` except it does not include the subprocess output.
*/
shortMessage?: string;
/**
Original error message. This is the same as `error.message` excluding the subprocess output and some additional information added by Execa.
This exists only in specific instances, such as during a timeout.
*/
originalMessage?: string;
/**
Underlying error, if there is one. For example, this is set by `subprocess.kill(error)`.
This is usually an `Error` instance.
*/
cause?: unknown;
/**
Node.js-specific [error code](https://nodejs.org/api/errors.html#errorcode), when available.
*/
code?: string;
// We cannot `extend Error` because `message` must be optional. So we copy its types here.
readonly name?: Error['name'];
stack?: Error['stack'];
}
type SuccessResult<
IsSync extends boolean = boolean,
OptionsType extends CommonOptions = CommonOptions,
> = InstanceType<typeof CommonResult<IsSync, OptionsType>> & OmitErrorIfReject<OptionsType['reject']>;
type OmitErrorIfReject<RejectOption extends CommonOptions['reject']> = {
[ErrorProperty in ErrorProperties]: RejectOption extends false ? unknown : never
};
/**
Result of a subprocess successful execution.
When the subprocess fails, it is rejected with an `ExecaError` instead.
*/
type Result<OptionsType extends Options = Options> = SuccessResult<false, OptionsType>;
/**
Result of a subprocess successful execution.
When the subprocess fails, it is rejected with an `ExecaError` instead.
*/
type SyncResult<OptionsType extends SyncOptions = SyncOptions> = SuccessResult<true, OptionsType>;
type VerboseOption = FdGenericOption<
| 'none'
| 'short'
| 'full'
| VerboseFunction
>;
type VerboseFunction = (verboseLine: string, verboseObject: MinimalVerboseObject) => string | void;
type GenericVerboseObject = {
/**
Event type. This can be:
- `'command'`: subprocess start
- `'output'`: `stdout`/`stderr` output
- `'ipc'`: IPC output
- `'error'`: subprocess failure
- `