UNPKG

clipanion

Version:

Type-safe CLI library / framework with no runtime dependencies

272 lines (271 loc) 12.6 kB
/// <reference types="node" /> /// <reference types="node" /> import { Readable, Writable } from 'stream'; import { CommandBuilder } from '../core'; import { ColorFormat } from '../format'; import { CommandClass, Command, Definition } from './Command'; import { CommandOption } from './options/utils'; declare type MakeOptional<T, Keys extends keyof T> = Omit<T, Keys> & Partial<Pick<T, Keys>>; declare type VoidIfEmpty<T> = keyof T extends never ? void : never; /** * The base context of the CLI. * * All Contexts have to extend it. */ export declare type BaseContext = { /** * Environment variables. * * @default * process.env */ env: Record<string, string | undefined>; /** * The input stream of the CLI. * * @default * process.stdin */ stdin: Readable; /** * The output stream of the CLI. * * @default * process.stdout */ stdout: Writable; /** * The error stream of the CLI. * * @default * process.stderr */ stderr: Writable; /** * Whether colors should be enabled. */ colorDepth: number; }; export declare type CliContext<Context extends BaseContext> = { commandClass: CommandClass<Context>; }; export declare type UserContextKeys<Context extends BaseContext> = Exclude<keyof Context, keyof BaseContext>; export declare type UserContext<Context extends BaseContext> = Pick<Context, UserContextKeys<Context>>; export declare type PartialContext<Context extends BaseContext> = UserContextKeys<Context> extends never ? Partial<Pick<Context, keyof BaseContext>> | undefined | void : Partial<Pick<Context, keyof BaseContext>> & UserContext<Context>; export declare type RunContext<Context extends BaseContext = BaseContext> = Partial<Pick<Context, keyof BaseContext>> & UserContext<Context>; export declare type RunCommand<Context extends BaseContext = BaseContext> = Array<CommandClass<Context>> | CommandClass<Context>; export declare type RunCommandNoContext<Context extends BaseContext = BaseContext> = UserContextKeys<Context> extends never ? RunCommand<Context> : never; export declare type CliOptions = Readonly<{ /** * The label of the binary. * * Shown at the top of the usage information. */ binaryLabel?: string; /** * The name of the binary. * * Included in the path and the examples of the definitions. */ binaryName: string; /** * The version of the binary. * * Shown at the top of the usage information. */ binaryVersion?: string; /** * If `true`, the Cli will hook into the process standard streams to catch * the output produced by console.log and redirect them into the context * streams. Note: stdin isn't captured at the moment. * * @default * false */ enableCapture: boolean; /** * If `true`, the Cli will use colors in the output. If `false`, it won't. * If `undefined`, Clipanion will infer the correct value from the env. */ enableColors?: boolean; }>; export declare type MiniCli<Context extends BaseContext> = CliOptions & { /** * Returns an Array representing the definitions of all registered commands. */ definitions(): Array<Definition>; /** * Formats errors using colors. * * @param error The error to format. If `error.name` is `'Error'`, it is replaced with `'Internal Error'`. * @param opts.command The command whose usage will be included in the formatted error. */ error(error: Error, opts?: { command?: Command<Context> | null; }): string; /** * Returns a rich color format if colors are enabled, or a plain text format otherwise. * * @param colored Forcefully enable or disable colors. */ format(colored?: boolean): ColorFormat; /** * Compiles a command and its arguments using the `CommandBuilder`. * * @param input An array containing the name of the command and its arguments * * @returns The compiled `Command`, with its properties populated with the arguments. */ process(input: Array<string>, context?: Partial<Context>): Command<Context>; /** * Runs a command. * * @param input An array containing the name of the command and its arguments * @param context Overrides the Context of the main `Cli` instance * * @returns The exit code of the command */ run(input: Array<string>, context?: Partial<Context>): Promise<number>; /** * Returns the usage of a command. * * @param command The `Command` whose usage will be returned or `null` to return the usage of all commands. * @param opts.detailed If `true`, the usage of a command will also include its description, details, and examples. Doesn't have any effect if `command` is `null` or doesn't have a `usage` property. * @param opts.prefix The prefix displayed before each command. Defaults to `$`. */ usage(command?: CommandClass<Context> | Command<Context> | null, opts?: { detailed?: boolean; prefix?: string; }): string; }; /** * An all-in-one helper that simultaneously instantiate a CLI and immediately * executes it. All parameters are optional except the command classes and * will be filled by sensible values for the current environment (for example * the argv argument will default to `process.argv`, etc). * * Just like `Cli#runExit`, this function will set the `process.exitCode` value * before returning. */ export declare function runExit<Context extends BaseContext = BaseContext>(commandClasses: RunCommandNoContext<Context>): Promise<void>; export declare function runExit<Context extends BaseContext = BaseContext>(commandClasses: RunCommand<Context>, context: RunContext<Context>): Promise<void>; export declare function runExit<Context extends BaseContext = BaseContext>(options: Partial<CliOptions>, commandClasses: RunCommandNoContext<Context>): Promise<void>; export declare function runExit<Context extends BaseContext = BaseContext>(options: Partial<CliOptions>, commandClasses: RunCommand<Context>, context: RunContext<Context>): Promise<void>; export declare function runExit<Context extends BaseContext = BaseContext>(commandClasses: RunCommandNoContext<Context>, argv: Array<string>): Promise<void>; export declare function runExit<Context extends BaseContext = BaseContext>(commandClasses: RunCommand<Context>, argv: Array<string>, context: RunContext<Context>): Promise<void>; export declare function runExit<Context extends BaseContext = BaseContext>(options: Partial<CliOptions>, commandClasses: RunCommandNoContext<Context>, argv: Array<string>): Promise<void>; export declare function runExit<Context extends BaseContext = BaseContext>(options: Partial<CliOptions>, commandClasses: RunCommand<Context>, argv: Array<string>, context: RunContext<Context>): Promise<void>; /** * An all-in-one helper that simultaneously instantiate a CLI and immediately * executes it. All parameters are optional except the command classes and * will be filled by sensible values for the current environment (for example * the argv argument will default to `process.argv`, etc). * * Unlike `runExit`, this function won't set the `process.exitCode` value * before returning. */ export declare function run<Context extends BaseContext = BaseContext>(commandClasses: RunCommandNoContext<Context>): Promise<number>; export declare function run<Context extends BaseContext = BaseContext>(commandClasses: RunCommand<Context>, context: RunContext<Context>): Promise<number>; export declare function run<Context extends BaseContext = BaseContext>(options: Partial<CliOptions>, commandClasses: RunCommandNoContext<Context>): Promise<number>; export declare function run<Context extends BaseContext = BaseContext>(options: Partial<CliOptions>, commandClasses: RunCommand<Context>, context: RunContext<Context>): Promise<number>; export declare function run<Context extends BaseContext = BaseContext>(commandClasses: RunCommandNoContext<Context>, argv: Array<string>): Promise<number>; export declare function run<Context extends BaseContext = BaseContext>(commandClasses: RunCommand<Context>, argv: Array<string>, context: RunContext<Context>): Promise<number>; export declare function run<Context extends BaseContext = BaseContext>(options: Partial<CliOptions>, commandClasses: RunCommandNoContext<Context>, argv: Array<string>): Promise<number>; export declare function run<Context extends BaseContext = BaseContext>(options: Partial<CliOptions>, commandClasses: RunCommand<Context>, argv: Array<string>, context: RunContext<Context>): Promise<number>; /** * @template Context The context shared by all commands. Contexts are a set of values, defined when calling the `run`/`runExit` functions from the CLI instance, that will be made available to the commands via `this.context`. */ export declare class Cli<Context extends BaseContext = BaseContext> implements Omit<MiniCli<Context>, `process` | `run`> { /** * The default context of the CLI. * * Contains the stdio of the current `process`. */ static defaultContext: { env: NodeJS.ProcessEnv; stdin: NodeJS.ReadStream & { fd: 0; }; stdout: NodeJS.WriteStream & { fd: 1; }; stderr: NodeJS.WriteStream & { fd: 2; }; colorDepth: number; }; private readonly builder; protected readonly registrations: Map<CommandClass<Context>, { index: number; builder: CommandBuilder<CliContext<Context>>; specs: Map<string, CommandOption<unknown>>; }>; readonly binaryLabel?: string; readonly binaryName: string; readonly binaryVersion?: string; readonly enableCapture: boolean; readonly enableColors?: boolean; /** * Creates a new Cli and registers all commands passed as parameters. * * @param commandClasses The Commands to register * @returns The created `Cli` instance */ static from<Context extends BaseContext = BaseContext>(commandClasses: RunCommand<Context>, options?: Partial<CliOptions>): Cli<Context>; constructor({ binaryLabel, binaryName: binaryNameOpt, binaryVersion, enableCapture, enableColors }?: Partial<CliOptions>); /** * Registers a command inside the CLI. */ register(commandClass: CommandClass<Context>): void; process(input: Array<string>, context: VoidIfEmpty<Omit<Context, keyof BaseContext>>): Command<Context>; process(input: Array<string>, context: MakeOptional<Context, keyof BaseContext>): Command<Context>; run(input: Command<Context> | Array<string>, context: VoidIfEmpty<Omit<Context, keyof BaseContext>>): Promise<number>; run(input: Command<Context> | Array<string>, context: MakeOptional<Context, keyof BaseContext>): Promise<number>; /** * Runs a command and exits the current `process` with the exit code returned by the command. * * @param input An array containing the name of the command and its arguments. * * @example * cli.runExit(process.argv.slice(2)) */ runExit(input: Command<Context> | Array<string>, context: VoidIfEmpty<Omit<Context, keyof BaseContext>>): Promise<void>; runExit(input: Command<Context> | Array<string>, context: MakeOptional<Context, keyof BaseContext>): Promise<void>; suggest(input: Array<string>, partial: boolean): string[][]; definitions({ colored }?: { colored?: boolean; }): Array<Definition>; usage(command?: CommandClass<Context> | Command<Context> | null, { colored, detailed, prefix }?: { colored?: boolean; detailed?: boolean; prefix?: string; }): string; error(error: Error | any, { colored, command }?: { colored?: boolean; command?: Command<Context> | null; }): string; format(colored?: boolean): ColorFormat; protected getUsageByRegistration(klass: CommandClass<Context>, opts?: { detailed?: boolean; inlineOptions?: boolean; }): { usage: string; options: { definition: string; description: string; required: boolean; }[]; }; protected getUsageByIndex(n: number, opts?: { detailed?: boolean; inlineOptions?: boolean; }): { usage: string; options: { definition: string; description: string; required: boolean; }[]; }; } export {};