UNPKG

@donmccurdy/caporal

Version:

A full-featured framework for building command line applications (cli) with node.js

346 lines (345 loc) 10.8 kB
/// <reference types="node" /> /** * @packageDocumentation * @module caporal/program */ import { EventEmitter } from "events"; import { Command } from "../command/index.js"; import { CustomizedHelpOpts } from "../help/types.js"; import { Action, Logger, ParserTypes, ProgramConfig, CreateArgumentOpts, CreateOptionProgramOpts, CommandConfig } from "../types.js"; import { CaporalValidator } from "../types.js"; /** * Program class * * @noInheritDoc */ export declare class Program extends EventEmitter { private commands; private _config; private _version?; private _name?; private _description?; private _programmaticMode; /** * @internal */ defaultCommand?: Command; private _progCommand?; private _bin; private _discoveryPath?; private _discoveredCommands?; /** * Number validator. Check that the value looks like a numeric one * and cast the provided value to a javascript `Number`. */ readonly NUMBER = CaporalValidator.NUMBER; /** * String validator. Mainly used to make sure the value is a string, * and prevent Caporal auto-casting of numerical values and boolean * strings like `true` or `false`. */ readonly STRING = CaporalValidator.STRING; /** * Array validator. Convert any provided value to an array. If a string is provided, * this validator will try to split it by commas. */ readonly ARRAY = CaporalValidator.ARRAY; /** * Boolean validator. Check that the value looks like a boolean. * It accepts values like `true`, `false`, `yes`, `no`, `0`, and `1` * and will auto-cast those values to `true` or `false`. */ readonly BOOLEAN = CaporalValidator.BOOLEAN; /** * Program constructor. * - Detects the "bin" name from process argv * - Detects the version from package.json * - Set up the help command * @ignore */ constructor(); /** * @internal */ private setupErrorHandlers; /** * The program-command is the command attached directly to the program, * meaning there is no command-keyword used to trigger it. * Mainly used for programs executing only one possible action. * * @internal */ get progCommand(): Command; /** * Setup the help command */ private setupHelpCommand; /** * Customize program help. Can be called multiple times to add more paragraphs and/or sections. * * @param text Help contents * @param options Display options */ help(text: string, options?: Partial<CustomizedHelpOpts>): Program; /** * Toggle strict mode. * Shortcut to calling: `.configure({ strictArgsCount: strict, strictOptions: strict })`. * By default, the program is strict, so if you want to disable strict checking, * just call `.strict(false)`. This setting can be overridden at the command level. * * @param strict boolean enabled flag */ strict(strict?: boolean): Program; /** * Configure some behavioral properties. * * @param props properties to set/update */ configure(props: Partial<ProgramConfig>): Program; /** * Get a configuration property value. {@link ProgramConfig Possible keys}. * * @param key Property * @internal */ getConfigProperty<K extends keyof ProgramConfig>(key: K): ProgramConfig[K]; /** * Return a reformatted synopsis string * * @internal */ getSynopsis(): Promise<string>; /** * Return the discovery path, if set * * @internal */ get discoveryPath(): string | undefined; /** * Return the program version * * @internal */ getVersion(): string | undefined; /** * Set the version fo your program. * You won't likely use this method as Caporal tries to guess it from your package.json */ version(ver: string): Program; /** * Set the program name. If not set, the filename minus the extension will be used. */ name(name: string): Program; /** * Return the program name. * * @internal */ getName(): string | undefined; /** * Return the program description. * * @internal */ getDescription(): string | undefined; /** * Set the program description displayed in help. */ description(desc: string): Program; /** * Get the bin name (the name of your executable). * * @internal */ getBin(): string; /** * Sets the executable name. By default, it's auto-detected from the filename of your program. * * @param name Executable name * @example * ```ts * program.bin('myprog') * ``` */ bin(name: string): Program; /** * Set a custom logger for your program. * Your logger should implement the {@link Logger} interface. */ logger(logger: Logger): Program; /** * Disable a global option. Will warn if the global option * does not exist of has already been disabled. * * @param name Name, short, or long notation of the option to disable. */ disableGlobalOption(name: string): Program; /** * Returns the list of all commands registered * - By default, Caporal creates one: the "help" command * - When calling argument() or action() on the program instance, * Caporal also create what is called the "program command", which * is a command directly attach to the program, usually used * in mono-command programs. * @internal */ getCommands(): Command[]; /** * Add a command to the program. * * @param name Command name * @param description Command description * @example * ```ts * program.command('order', 'Order some food') * ``` */ command(name: string, description: string, config?: Partial<CommandConfig>): Command; /** * Check if the program has user-defined commands. * * @internal * @private */ hasCommands(): Promise<boolean>; /** * @internal */ getAllCommands(): Promise<Command[]>; /** * Return the log level override, if any is provided using * the right environment variable. * * @internal * @private */ getLogLevelOverride(): string | undefined; /** * Enable or disable auto casting of arguments & options at the program level. * * @param enabled */ cast(enabled: boolean): Program; /** * Sets a *unique* action for the *entire* program. * * @param {Function} action - Action to run */ action(action: Action): Program; /** * Add an argument to the *unique* command of the program. */ argument(synopsis: string, description: string, options?: CreateArgumentOpts): Command; /** * Add an option to the *unique* command of the program, * or add a global option to the program when `options.global` * is set to `true`. * * @param synopsis Option synopsis like '-f, --force', or '-f, --file \<file\>', or '--with-openssl [path]' * @param description Option description * @param options Additional parameters */ option(synopsis: string, description: string, options?: CreateOptionProgramOpts): Program; /** * Discover commands from a specified path. * * Commands must be organized into files (one command per file) in a file tree like: * * ```sh * └── commands * ├── config * │ ├── set.ts * │ └── unset.ts * ├── create * │ ├── job.ts * │ └── service.ts * ├── create.ts * ├── describe.ts * └── get.ts * ``` * * The code above shows a short example of `kubectl` commands and subcommands. * In this case, Caporal will generate the following commands: * * - kubectl get [args...] [options...] * - kubectl config set [args...] [options...] * - kubectl config unset [args...] [options...] * - kubectl create [args...] [options...] * - kubectl create job [args...] [options...] * - kubectl create service [args...] [options...] * - kubectl describe [args...] [options...] * - kubectl get [args...] [options...] * * Notice how the `config` command has a mandatory subcommand associated, * hence cannot be called without a subcommand, contrary to the `create` command. * This is why there is no `config.ts` in the tree. * * @param path */ discover(dirPath: string): Program; /** * Do a full scan of the discovery path to get all existing commands * This should only be used to generate the full list of command, * as for help rendering * * @private */ private scanCommands; /** * Reset all commands * * @internal */ reset(): Program; /** * Run the program by parsing command line arguments. * Caporal will automatically detect command line arguments from `process.argv` values, * but it can be overridden by providing the `argv` parameter. It returns a Promise * of the value returned by the *Action* triggered. * * ::: warning Be careful * This method returns a `Promise`. You'll usually ignore the returned promise and call run() like this: * * ```ts * [...] * program.action(...) * program.run() * ``` * * If you do add some `.catch()` handler to it, Caporal won't display any potential errors * that the promise could reject, and will let you the responsibility to do it. * ::: * * @param argv Command line arguments to parse, default to `process.argv.slice(2)`. */ run(argv?: string[]): Promise<unknown>; /** * Try to find the executed command from argv * If command cannot be found from argv, return the default command if any, * then the program-command if any, or finally `undefined`. * If argv is empty, and there is no defaultCommand or progCommand * use the help command * * @param argv */ private findCommand; /** * Run a command, providing parsed data * * @param result * @param cmd * @internal */ private _run; /** * Programmatic usage. Execute input command with given arguments & options * * Not ideal regarding type casting etc. * * @param args argv array * @param options options object * @param ddash double dash array * @public */ exec(args: string[], options?: Record<string, ParserTypes>, ddash?: string[]): Promise<unknown>; }