import { Message } from "./message.cjs"; import { HiddenVisibility, OptionName } from "./usage.cjs"; import { DocSection, ShowChoicesOptions, ShowDefaultOptions } from "./doc.cjs"; import { InferMode, InferValue, Mode, ModeValue, Parser } from "./internal/parser.cjs"; import { ShellCompletion } from "./completion.cjs"; import { ParserValuePlaceholder, SourceContext, SourceContextRequest } from "./context.cjs"; import { Program } from "./program.cjs"; //#region src/facade.d.ts /** * Sub-configuration for a meta command's command form. * * @since 1.0.0 */ interface CommandSubConfig { /** * Command names. The first element is the display name shown in help * output; additional elements are hidden aliases that are accepted but * not shown. */ readonly names?: readonly [string, ...string[]]; /** * Group label for the command in help output. When specified, the command * appears under a titled section with this name instead of alongside * user-defined commands. */ readonly group?: string; /** * Granular visibility control. * * - `true`: Hidden from usage, documentation, and suggestions. * - `"usage"`: Hidden from usage lines only. * - `"doc"`: Hidden from documentation only. * - `"help"`: Hidden from usage and documentation only. */ readonly hidden?: HiddenVisibility; } /** * Sub-configuration for a meta command's option form. * * @since 1.0.0 */ interface OptionSubConfig { /** * Option names (all shown in help, e.g., `"-h"`, `"--help"`). */ readonly names?: readonly [OptionName, ...OptionName[]]; /** * Group label for the option in help output. */ readonly group?: string; /** * Granular visibility control. * * - `true`: Hidden from usage, documentation, and suggestions. * - `"usage"`: Hidden from usage lines only. * - `"doc"`: Hidden from documentation only. * - `"help"`: Hidden from usage and documentation only. */ readonly hidden?: HiddenVisibility; } /** * Configuration options for the {@link run} function. * * @template THelp The return type when help is shown. * @template TError The return type when an error occurs. */ interface RunOptions { /** * Enable colored output in help and error messages. * * @default `false` */ readonly colors?: boolean; /** * Maximum width for output formatting. Text will be wrapped to fit within * this width. If not specified, text will not be wrapped. */ readonly maxWidth?: number; /** * Whether and how to display default values for options and arguments. * * - `boolean`: When `true`, displays defaults using format `[value]` * - `ShowDefaultOptions`: Custom formatting with configurable prefix and suffix * * Default values are automatically dimmed when `colors` is enabled. * * @default `false` * @since 0.4.0 */ readonly showDefault?: boolean | ShowDefaultOptions; /** * Whether and how to display valid choices for options and arguments * backed by enumerated value parsers (e.g., `choice()`). * * - `boolean`: When `true`, displays choices using format * `(choices: a, b, c)` * - `ShowChoicesOptions`: Custom formatting with configurable prefix, * suffix, label, and maximum number of items * * Choice values are automatically dimmed when `colors` is enabled. * * @default `false` * @since 0.10.0 */ readonly showChoices?: boolean | ShowChoicesOptions; /** * A custom comparator function to control the order of sections in the * help output. When provided, it is used instead of the default smart * sort (command-only sections first, then mixed, then option/argument-only * sections). Sections that compare equal (return `0`) preserve their * original relative order. * * @param a The first section to compare. * @param b The second section to compare. * @returns A negative number if `a` should appear before `b`, a positive * number if `a` should appear after `b`, or `0` if they are equal. * @since 1.0.0 */ readonly sectionOrder?: (a: DocSection, b: DocSection) => number; /** * Help configuration. When provided, enables help functionality. * At least one of `command` or `option` must be specified. * * @since 1.0.0 */ readonly help?: { /** Callback invoked when help is requested. */ readonly onShow?: (() => THelp) | ((exitCode: number) => THelp); } & ({ readonly command: true | CommandSubConfig; readonly option?: true | OptionSubConfig; } | { readonly option: true | OptionSubConfig; readonly command?: true | CommandSubConfig; }); /** * Version configuration. When provided, enables version functionality. * At least one of `command` or `option` must be specified. * * @since 1.0.0 */ readonly version?: { /** The version string to display when version is requested. */ readonly value: string; /** Callback invoked when version is requested. */ readonly onShow?: (() => THelp) | ((exitCode: number) => THelp); } & ({ readonly command: true | CommandSubConfig; readonly option?: true | OptionSubConfig; } | { readonly option: true | OptionSubConfig; readonly command?: true | CommandSubConfig; }); /** * Completion configuration. When provided, enables shell completion. * At least one of `command` or `option` must be specified. * * @since 1.0.0 */ readonly completion?: { /** * Available shell completions. By default, includes `bash`, `fish`, * `nu`, `pwsh`, and `zsh`. * * @default `{ bash, fish, nu, pwsh, zsh }` */ readonly shells?: Record; /** Callback invoked when completion is requested. */ readonly onShow?: (() => THelp) | ((exitCode: number) => THelp); } & ({ readonly command: true | CommandSubConfig; readonly option?: true | OptionSubConfig; } | { readonly option: true | OptionSubConfig; readonly command?: true | CommandSubConfig; }); /** * What to display above error messages: * - `"usage"`: Show usage information * - `"help"`: Show help text (if available) * - `"none"`: Show nothing above errors * * @default `"usage"` */ readonly aboveError?: "usage" | "help" | "none"; /** * Callback function invoked when parsing fails. The function can * optionally receive an exit code parameter. * * You usually want to pass `process.exit` on Node.js or Bun and `Deno.exit` * on Deno to this option. * @default Throws a {@link RunParserError}. */ readonly onError?: (() => TError) | ((exitCode: number) => TError); /** * Function used to output error messages. Assumes it prints the ending * newline. * * @default `console.error` */ readonly stderr?: (text: string) => void; /** * Function used to output help and usage messages. Assumes it prints * the ending newline. * * @default `console.log` */ readonly stdout?: (text: string) => void; /** * Brief description shown at the top of help text. * * @since 0.4.0 */ readonly brief?: Message; /** * Detailed description shown after the usage line. * * @since 0.4.0 */ readonly description?: Message; /** * Usage examples for the program. * * @since 0.10.0 */ readonly examples?: Message; /** * Author information. * * @since 0.10.0 */ readonly author?: Message; /** * Information about where to report bugs. * * @since 0.10.0 */ readonly bugs?: Message; /** * Footer text shown at the bottom of help text. * * @since 0.4.0 */ readonly footer?: Message; } /** * Runs a parser against command-line arguments with built-in help and error * handling. * * This function provides a complete CLI interface by automatically handling * help commands/options and displaying formatted error messages with usage * information when parsing fails. It augments the provided parser with help * functionality based on the configuration options. * * The function will: * * 1. Add help command/option support (unless disabled) * 2. Parse the provided arguments * 3. Display help if requested * 4. Show formatted error messages with usage/help info on parse failures * 5. Return the parsed result or invoke the appropriate callback * * @template TParser The parser type being run. * @template THelp Return type when help is shown (defaults to `void`). * @template TError Return type when an error occurs (defaults to `never`). * @param parser The parser to run against the command-line arguments. * @param programName Name of the program used in usage and help output. * @param args Command-line arguments to parse (typically from * `process.argv.slice(2)` on Node.js or `Deno.args` on Deno). * @param options Configuration options for output formatting and callbacks. * @returns The parsed result value, or the return value of `onHelp`/`onError` * callbacks. * @throws {TypeError} If `programName` (or `program.metadata.name`) is not * a string, is empty, is whitespace-only, or contains control * characters. Also thrown if `options.version.value` is not a * non-empty string without ASCII control characters, or if any * meta command/option name is empty, whitespace-only, contains * whitespace or control characters, or (for option names) lacks a * valid prefix (`--`, `-`, `/`, or `+`). * @throws {RunParserError} When parsing fails and no `onError` callback is * provided. * @since 0.10.0 Added support for {@link Program} objects. */ declare function runParser(program: Program<"sync", T>, args: readonly string[], options?: RunOptions): T; declare function runParser(program: Program<"async", T>, args: readonly string[], options?: RunOptions): Promise; declare function runParser, THelp = void, TError = never>(parser: TParser, programName: string, args: readonly string[], options?: RunOptions): InferValue; declare function runParser, THelp = void, TError = never>(parser: TParser, programName: string, args: readonly string[], options?: RunOptions): Promise>; declare function runParser, THelp = void, TError = never>(parser: TParser, programName: string, args: readonly string[], options?: RunOptions): ModeValue, InferValue>; /** * Runs a synchronous command-line parser with the given options. * * This is a type-safe version of {@link runParser} that only accepts sync * parsers. Use this when you know your parser is sync-only to get direct * return values without Promise wrappers. * * @template TParser The sync parser type being executed. * @template THelp The return type of the onHelp callback. * @template TError The return type of the onError callback. * @param parser The synchronous command-line parser to execute. * @param programName The name of the program for help messages. * @param args The command-line arguments to parse. * @param options Configuration options for customizing behavior. * @returns The parsed result if successful. * @throws {TypeError} If an async parser is passed at runtime. Use * {@link runParser} or {@link runParserAsync} for async parsers. * @since 0.9.0 */ declare function runParserSync, THelp = void, TError = never>(parser: TParser, programName: string, args: readonly string[], options?: RunOptions): InferValue; /** * Runs any command-line parser asynchronously with the given options. * * This function accepts parsers of any mode (sync or async) and always * returns a Promise. Use this when working with parsers that may contain * async value parsers. * * @template TParser The parser type being executed. * @template THelp The return type of the onHelp callback. * @template TError The return type of the onError callback. * @param parser The command-line parser to execute. * @param programName The name of the program for help messages. * @param args The command-line arguments to parse. * @param options Configuration options for customizing behavior. * @returns A Promise of the parsed result if successful. * @since 0.9.0 */ declare function runParserAsync, THelp = void, TError = never>(parser: TParser, programName: string, args: readonly string[], options?: RunOptions): Promise>; /** * An error class used to indicate that the command line arguments * could not be parsed successfully. */ declare class RunParserError extends Error { constructor(message: string); } /** * Substitutes {@link ParserValuePlaceholder} with the actual parser value type. * * This type recursively traverses `T` and replaces any occurrence of * `ParserValuePlaceholder` with `TValue`. Used by `runWith()` to compute * the required options type based on the parser's result type. * * @template T The type to transform. * @template TValue The parser value type to substitute. * @since 0.10.0 */ type SubstituteParserValue = T extends ParserValuePlaceholder ? TValue : T extends ((...args: infer A) => infer R) ? (...args: { [K in keyof A]: SubstituteParserValue }) => SubstituteParserValue : T extends object ? { [K in keyof T]: SubstituteParserValue } : T; /** * Converts a union type to an intersection type. * @internal */ type UnionToIntersection = (U extends unknown ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never; /** * Extracts and merges required options from an array of source contexts. * * For each context in the array, extracts its `TRequiredOptions` type parameter, * substitutes any `ParserValuePlaceholder` with `TValue`, and intersects all * the resulting option types. * * @template TContexts The tuple/array type of source contexts. * @template TValue The parser value type for placeholder substitution. * @since 0.10.0 */ type ExtractRequiredOptions[], TValue> = [TContexts[number] extends SourceContext ? O extends void ? never : SubstituteParserValue : never] extends [never] ? unknown : UnionToIntersection ? O extends void ? never : SubstituteParserValue : never>; /** * Options for runWith functions. * Extends RunOptions with additional context-related settings. * * @template THelp The return type when help is shown. * @template TError The return type when an error occurs. * @since 0.10.0 */ interface RunWithOptions extends RunOptions { /** * Command-line arguments to parse. If not provided, defaults to * `process.argv.slice(2)` on Node.js/Bun or `Deno.args` on Deno. */ readonly args?: readonly string[]; /** * Options to forward to source contexts. When contexts declare * required options (via `$requiredOptions`), pass them here to * avoid name collisions with runner-level options such as `args`, * `help`, or `colors`. * * @since 1.0.0 */ readonly contextOptions?: Record; } /** * When contexts require options, demands a `contextOptions` property * typed to those requirements. When no context needs options * (`void`, `unknown`, or `{}`), resolves to `unknown` (intersection no-op). * When all context option keys are optional, `contextOptions` itself becomes * optional so callers are not forced to pass an empty wrapper. * * @template TContexts The tuple/array type of source contexts. * @template TValue The parser value type for placeholder substitution. * @since 1.0.0 */ type ContextOptionsParam[], TValue> = keyof ExtractRequiredOptions extends never ? unknown : Record extends ExtractRequiredOptions ? { readonly contextOptions?: ExtractRequiredOptions; } : { readonly contextOptions: ExtractRequiredOptions; }; /** * Runs a parser with multiple source contexts. * * This function automatically handles single-pass and two-pass contexts with * proper priority. Earlier contexts in the array override later ones. * * The function uses a smart two-phase approach: * * 1. *Phase 1*: Collect annotations from all contexts. * 2. *First parse*: Parse with Phase 1 annotations. If that pass finishes * successfully, its value becomes the phase-two input. If the parser * reaches a usable intermediate state but still does not complete * successfully, the runner extracts a best-effort seed from that state * instead. * 3. *Phase 2*: Call `getAnnotations({ phase: "phase2", parsed })` on all * two-pass contexts with the first pass value. Deferred or otherwise * unresolved fields in `parsed` may be `undefined`. Each two-pass * context's phase-two return * value replaces its own phase-one contribution for the final parse, so * returning `{}` clears any annotations that context provided during * phase 1. Single-pass contexts reuse their phase-one snapshot. * 4. *Second parse*: Parse again with the merged phase-two annotations. * * If all contexts are single-pass, the second parse is skipped for * optimization. Phase 2 is also skipped when the first pass does not yield * any usable seed at all. * * @template TParser The parser type. * @template THelp Return type when help is shown. * @template TError Return type when an error occurs. * @param parser The parser to execute. * @param programName Name of the program for help/error output. * @param contexts Source contexts to use (priority: earlier overrides later). * @param options Run options including args, help, version, etc. * @returns Promise that resolves to the parsed result. * @throws {TypeError} If two or more contexts share the same * {@link SourceContext.id}. * @throws {TypeError} If any context omits `phase` or declares an invalid * phase value. * @throws {SuppressedError} If the runner throws and a context's disposal * also throws. The original error is available via `.suppressed` and the * disposal error via `.error`. * @since 0.10.0 * * @example * ```typescript * import { runWith } from "@optique/core/facade"; * import type { SourceContext } from "@optique/core/context"; * * const envContext: SourceContext = { * id: Symbol.for("@myapp/env"), * phase: "single-pass", * getAnnotations() { * return { [Symbol.for("@myapp/env")]: process.env }; * } * }; * * const result = await runWith( * parser, * "myapp", * [envContext], * { args: process.argv.slice(2) } * ); * ``` */ declare function runWith, TContexts extends readonly SourceContext[], THelp = void, TError = never>(parser: TParser, programName: string, contexts: TContexts, options: RunWithOptions & ContextOptionsParam>): Promise>; /** * Runs a synchronous parser with multiple source contexts. * * This is the sync-only variant of {@link runWith}. All contexts must return * annotations synchronously (not Promises). It uses the same two-phase * best-effort seed extraction as {@link runWith} when two-pass contexts are * present. In two-phase runs, each two-pass context's phase-two return value * replaces that context's phase-one contribution for the final parse, so * returning `{}` clears any annotations that context provided during phase 1. * * @template TParser The sync parser type. * @template THelp Return type when help is shown. * @template TError Return type when an error occurs. * @param parser The synchronous parser to execute. * @param programName Name of the program for help/error output. * @param contexts Source contexts to use (priority: earlier overrides later). * @param options Run options including args, help, version, etc. * @returns The parsed result. * @throws {TypeError} If an async parser is passed at runtime. Use * {@link runWith} or {@link runWithAsync} for async parsers. * @throws {TypeError} If two or more contexts share the same * {@link SourceContext.id}. * @throws {TypeError} If any context omits `phase` or declares an invalid * phase value. * @throws {TypeError} If any context returns a Promise or if a context's * `[Symbol.asyncDispose]` returns a Promise. * @throws {SuppressedError} If the runner throws and a context's disposal * also throws. The original error is available via `.suppressed` and the * disposal error via `.error`. * @since 0.10.0 */ declare function runWithSync, TContexts extends readonly SourceContext[], THelp = void, TError = never>(parser: TParser, programName: string, contexts: TContexts, options: RunWithOptions & ContextOptionsParam>): InferValue; /** * Runs any parser asynchronously with multiple source contexts. * * This function accepts parsers of any mode (sync or async) and always * returns a Promise. Use this when working with async contexts or parsers. * * @template TParser The parser type. * @template THelp Return type when help is shown. * @template TError Return type when an error occurs. * @param parser The parser to execute. * @param programName Name of the program for help/error output. * @param contexts Source contexts to use (priority: earlier overrides later). * @param options Run options including args, help, version, etc. * @returns Promise that resolves to the parsed result. * @throws {TypeError} If two or more contexts share the same * {@link SourceContext.id}. * @throws {SuppressedError} If the runner throws and a context's disposal * also throws. The original error is available via `.suppressed` and the * disposal error via `.error`. * @since 0.10.0 */ declare function runWithAsync, TContexts extends readonly SourceContext[], THelp = void, TError = never>(parser: TParser, programName: string, contexts: TContexts, options: RunWithOptions & ContextOptionsParam>): Promise>; //#endregion export { CommandSubConfig, ContextOptionsParam, ExtractRequiredOptions, OptionSubConfig, type ParserValuePlaceholder, RunOptions, RunParserError, RunWithOptions, type SourceContext, type SourceContextRequest, SubstituteParserValue, runParser, runParserAsync, runParserSync, runWith, runWithAsync, runWithSync };