clipanion
- Version 4.0.0-rc.4
- Published
- 235 kB
- 1 dependency
- MIT license
Install
npm i clipanion
yarn add clipanion
pnpm add clipanion
Overview
Type-safe CLI library / framework with no runtime dependencies
Index
Functions
Classes
Interfaces
Type Aliases
Namespaces
Option
- applyValidator()
- Array()
- ArrayFlags
- Boolean()
- BooleanFlags
- cleanValidationError()
- CommandOption
- CommandOptionReturn
- Counter()
- CounterFlags
- formatError()
- GeneralOptionFlags
- isOptionSymbol
- makeCommandOption()
- Proxy()
- ProxyFlags
- rerouteArguments()
- Rest()
- RestFlags
- String()
- StringOption
- StringOptionNoBoolean
- StringOptionTolerateBoolean
- StringPositionalFlags
- Tuple
- TupleOf
- WithArity
Functions
function formatMarkdownish
formatMarkdownish: ( text: string, { format, paragraphs }: { format: ColorFormat; paragraphs: boolean }) => string;
Formats markdown text to be displayed to the console. Not all markdown features are supported.
Parameter text
The markdown text to format.
Parameter
opts.format The format to use.
Parameter
opts.paragraphs Whether to cut the text into paragraphs of 80 characters at most.
function run
run: { <Context extends BaseContext = BaseContext>( commandClasses: RunCommandNoContext<Context> ): Promise<number>; <Context extends BaseContext = BaseContext>( commandClasses: RunCommand<Context>, context: RunContext<Context> ): Promise<number>; <Context extends BaseContext = BaseContext>( options: Partial< Readonly<{ binaryLabel?: string; binaryName: string; binaryVersion?: string; enableCapture: boolean; enableColors?: boolean; }> >, commandClasses: RunCommandNoContext<Context> ): Promise<number>; <Context extends BaseContext = BaseContext>( options: Partial< Readonly<{ binaryLabel?: string; binaryName: string; binaryVersion?: string; enableCapture: boolean; enableColors?: boolean; }> >, commandClasses: RunCommand<Context>, context: RunContext<Context> ): Promise<number>; <Context extends BaseContext = BaseContext>( commandClasses: RunCommandNoContext<Context>, argv: string[] ): Promise<number>; <Context extends BaseContext = BaseContext>( commandClasses: RunCommand<Context>, argv: string[], context: RunContext<Context> ): Promise<number>; <Context extends BaseContext = BaseContext>( options: Partial< Readonly<{ binaryLabel?: string; binaryName: string; binaryVersion?: string; enableCapture: boolean; enableColors?: boolean; }> >, commandClasses: RunCommandNoContext<Context>, argv: string[] ): Promise<number>; <Context extends BaseContext = BaseContext>( options: Partial< Readonly<{ binaryLabel?: string; binaryName: string; binaryVersion?: string; enableCapture: boolean; enableColors?: boolean; }> >, commandClasses: RunCommand<Context>, argv: string[], context: RunContext<Context> ): Promise<number>;};
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 theprocess.exitCode
value before returning.
function runExit
runExit: { <Context extends BaseContext = BaseContext>( commandClasses: RunCommandNoContext<Context> ): Promise<void>; <Context extends BaseContext = BaseContext>( commandClasses: RunCommand<Context>, context: RunContext<Context> ): Promise<void>; <Context extends BaseContext = BaseContext>( options: Partial< Readonly<{ binaryLabel?: string; binaryName: string; binaryVersion?: string; enableCapture: boolean; enableColors?: boolean; }> >, commandClasses: RunCommandNoContext<Context> ): Promise<void>; <Context extends BaseContext = BaseContext>( options: Partial< Readonly<{ binaryLabel?: string; binaryName: string; binaryVersion?: string; enableCapture: boolean; enableColors?: boolean; }> >, commandClasses: RunCommand<Context>, context: RunContext<Context> ): Promise<void>; <Context extends BaseContext = BaseContext>( commandClasses: RunCommandNoContext<Context>, argv: string[] ): Promise<void>; <Context extends BaseContext = BaseContext>( commandClasses: RunCommand<Context>, argv: string[], context: RunContext<Context> ): Promise<void>; <Context extends BaseContext = BaseContext>( options: Partial< Readonly<{ binaryLabel?: string; binaryName: string; binaryVersion?: string; enableCapture: boolean; enableColors?: boolean; }> >, commandClasses: RunCommandNoContext<Context>, argv: string[] ): Promise<void>; <Context extends BaseContext = BaseContext>( options: Partial< Readonly<{ binaryLabel?: string; binaryName: string; binaryVersion?: string; enableCapture: boolean; enableColors?: boolean; }> >, commandClasses: RunCommand<Context>, argv: 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).Just like
Cli#runExit
, this function will set theprocess.exitCode
value before returning.
Classes
class Cli
class Cli<Context extends BaseContext = BaseContext> implements Omit<MiniCli<Context>, `process` | `run`> {}
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 viathis.context
.
constructor
constructor({ binaryLabel, binaryName: binaryNameOpt, binaryVersion, enableCapture, enableColors,}?: Partial< Readonly<{ binaryLabel?: string; binaryName: string; binaryVersion?: string; enableCapture: boolean; enableColors?: boolean; }>>);
property binaryLabel
readonly binaryLabel?: string;
property binaryName
readonly binaryName: string;
property binaryVersion
readonly binaryVersion?: string;
property defaultContext
static defaultContext: { env: NodeJS.ProcessEnv; stdin: NodeJS.ReadStream & { fd: 0 }; stdout: NodeJS.WriteStream & { fd: 1 }; stderr: NodeJS.WriteStream & { fd: 2 }; colorDepth: number;};
The default context of the CLI.
Contains the stdio of the current
process
.
property enableCapture
readonly enableCapture: boolean;
property enableColors
readonly enableColors?: boolean;
property registrations
protected readonly registrations: Map< CommandClass<Context>, { index: number; builder: CommandBuilder<CliContext<Context>>; specs: Map<string, CommandOption<unknown>>; }>;
method definition
definition: ( commandClass: CommandClass<Context>, { colored }?: { colored?: boolean }) => Definition | null;
method definitions
definitions: ({ colored }?: { colored?: boolean }) => Array<Definition>;
method error
error: ( error: Error | any, { colored, command, }?: { colored?: boolean; command?: Command<Context> | null }) => string;
method format
format: (colored?: boolean) => ColorFormat;
method from
static from: <Context extends BaseContext = BaseContext>( commandClasses: RunCommand<Context>, options?: Partial<CliOptions>) => Cli<Context>;
Creates a new Cli and registers all commands passed as parameters.
Parameter commandClasses
The Commands to register
Returns
The created
Cli
instance
method getUsageByIndex
protected getUsageByIndex: ( n: number, opts?: { detailed?: boolean; inlineOptions?: boolean }) => { usage: string; options: { preferredName: string; nameSet: string[]; definition: string; description: string; required: boolean; }[];};
method getUsageByRegistration
protected getUsageByRegistration: ( klass: CommandClass<Context>, opts?: { detailed?: boolean; inlineOptions?: boolean }) => { usage: string; options: { preferredName: string; nameSet: string[]; definition: string; description: string; required: boolean; }[];};
method process
process: { (opts: ProcessOptions<Context>): Command<Context>; ( input: string[], context: VoidIfEmpty<Omit<Context, keyof BaseContext>> ): Command<Context>; ( input: string[], context: MakeOptional<Context, keyof BaseContext> ): Command<Context>;};
method register
register: (commandClass: CommandClass<Context>) => void;
Registers a command inside the CLI.
method run
run: { ( input: Command<Context> | Array<string>, context: VoidIfEmpty<Omit<Context, keyof BaseContext>> ): Promise<number>; ( input: string[] | Command<Context>, context: MakeOptional<Context, keyof BaseContext> ): Promise<number>;};
method runExit
runExit: { ( input: Command<Context> | Array<string>, context: VoidIfEmpty<Omit<Context, keyof BaseContext>> ): Promise<void>; ( input: string[] | Command<Context>, context: MakeOptional<Context, keyof BaseContext> ): Promise<void>;};
Runs a command and exits the current
process
with the exit code returned by the command.Parameter input
An array containing the name of the command and its arguments.
Example 1
cli.runExit(process.argv.slice(2))
method usage
usage: ( command?: CommandClass<Context> | Command<Context> | null, { colored, detailed, prefix, }?: { colored?: boolean; detailed?: boolean; prefix?: string }) => string;
class Command
abstract class Command<Context extends BaseContext = BaseContext> {}
Base abstract class for CLI commands. The main thing to remember is to declare an async
execute
member function that will be called when the command is invoked from the CLI, and optionally apaths
property to declare the set of paths under which the command should be exposed.
property [`constructor`]
[`constructor`]: CommandClass<Context>;
property cli
cli: MiniCli<Context>;
Predefined variable that will be populated with a miniature API that can be used to query Clipanion and forward commands.
property context
context: BaseContext;
Predefined variable that will be populated with the context of the application.
property Default
static Default: never[];
Just an helper to use along with the
paths
fields, to make it clearer that a command is the default one.Example 1
class MyCommand extends Command { static paths = [Command.Default]; }
property help
help: boolean;
Predefined that will be set to true if
-h,--help
has been used, in which caseCommand#execute
won't be called.
property isOption
static isOption: Symbol;
Used to detect option definitions.
property path
static path: never;
Defined to prevent a common typo.
property path
path: string[];
Predefined variable that will be populated with the path that got used to access the command currently being executed.
property paths
static paths?: string[][];
Paths under which the command should be exposed.
property paths
paths?: undefined;
Deprecated
Do not use this; prefer the static
paths
property instead.
property schema
static schema?: LooseTest<{ [key: string]: unknown }>[];
Defines a schema to apply before running the
execute
method. The schema is expected to be generated by Typanion.See Also
https://github.com/arcanis/typanion
property tokens
tokens: Token[];
Predefined variable that will be populated with the tokens found when interpreting the command line.
property usage
static usage?: Usage;
Contains the usage information for the command. If undefined, the command will be hidden from the general listing.
method catch
catch: (error: any) => Promise<void>;
Standard error handler which will simply rethrow the error. Can be used to add custom logic to handle errors from the command or simply return the parent class error handling.
method execute
abstract execute: () => Promise<number | void>;
Standard function that'll get executed by
Cli#run
andCli#runExit
.Expected to return an exit code or nothing (which Clipanion will treat as if 0 had been returned).
method Usage
static Usage: (usage: Usage) => Usage;
Defines the usage information for the given command.
method validateAndExecute
validateAndExecute: () => Promise<number>;
class UsageError
class UsageError extends Error {}
A generic usage error with the name
UsageError
.It should be used over
Error
only when it's the user's fault.
constructor
constructor(message: string);
property clipanion
clipanion: ErrorMeta;
Interfaces
interface ColorFormat
interface ColorFormat {}
interface ErrorWithMeta
interface ErrorWithMeta extends Error {}
An error with metadata telling clipanion how to print it
Errors with this metadata property will have their name and message printed, but not the stacktrace.
This should be used for errors where the message is the part that's important but the stacktrace is useless. Some examples of where this might be useful are:
- Invalid input by the user (see
UsageError
) - A HTTP connection fails, the user is shown "Failed To Fetch Data: Could not connect to server example.com" without stacktrace - A command in which the user enters credentials doesn't want to show a stacktract when the user enters invalid credentials - ...
property clipanion
readonly clipanion: ErrorMeta;
Metadata detailing how clipanion should print this error
Type Aliases
type BaseContext
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;};
The base context of the CLI.
All Contexts have to extend it.
type CliOptions
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;}>;
type CommandClass
type CommandClass<Context extends BaseContext = BaseContext> = { new (): Command<Context>; paths?: Array<Array<string>>; schema?: Array< LooseTest<{ [key: string]: unknown; }> >; usage?: Usage;};
type Definition
type Definition = Usage & { /** * The path of the command, starting with `cli.binaryName`. */ path: string; /** * The detailed usage of the command. */ usage: string; /** * The various options registered on the command. */ options: Array<{ preferredName: string; nameSet: Array<string>; definition: string; description?: string; required: boolean; }>;};
The definition of a Command.
type ErrorMeta
type ErrorMeta = | { type: `none`; } | { type: `usage`; };
type RunContext
type RunContext<Context extends BaseContext = BaseContext> = Partial< Pick<Context, keyof BaseContext>> & UserContext<Context>;
type Token
type Token = PathToken | PositionalToken | OptionToken | AssignToken | ValueToken;
type Usage
type Usage = { /** * The category of the command. * * Included in the detailed usage. */ category?: string; /** * The short description of the command, formatted as Markdown. * * Included in the detailed usage. */ description?: string; /** * The extended details of the command, formatted as Markdown. * * Included in the detailed usage. */ details?: string; /** * Examples of the command represented as an Array of tuples. * * The first element of the tuple represents the description of the example. * * The second element of the tuple represents the command of the example. * If present, the leading `$0` is replaced with `cli.binaryName`. */ examples?: Array<[string, string]>;};
The usage of a Command.
Namespaces
namespace Builtins
module 'lib/advanced/builtins/index.d.ts' {}
class DefinitionsCommand
class DefinitionsCommand extends Command<any> {}
A command that prints the clipanion definitions.
class HelpCommand
class HelpCommand extends Command<any> {}
A command that prints the usage of all commands.
Paths:
-h
,--help
class TokensCommand
class TokensCommand extends Command<any> {}
A command that prints the clipanion tokens.
class VersionCommand
class VersionCommand extends Command<any> {}
A command that prints the version of the binary (
cli.binaryVersion
).Paths:
-v
,--version
namespace Option
module 'lib/advanced/options/index.d.ts' {}
variable isOptionSymbol
const isOptionSymbol: Symbol;
function applyValidator
applyValidator: <U, V>( name: string, value: U, validator?: StrictValidator<unknown, V>) => U;
function Array
Array: { <T extends {} = string, Arity extends number = 1>( descriptor: string, opts: ArrayFlags<T, Arity> & { required: true } ): CommandOptionReturn<Array<WithArity<T, Arity>>>; <T extends {} = string, Arity extends number = 1>( descriptor: string, opts?: ArrayFlags<T, Arity> ): WithArity<T, Arity>[]; <T extends {} = string, Arity extends number = 1>( descriptor: string, initialValue: (Arity extends 0 ? boolean : Arity extends 1 ? string : number extends Arity ? string | boolean | Tuple<string, Arity> : Tuple<string, Arity>)[], opts?: Omit<ArrayFlags<T, Arity>, 'required'> ): WithArity<T, Arity>[];};
Used to annotate array options. Such options will be strings unless they are provided a schema, which will then be used for coercion.
Example 1
--foo hello --foo bar ► {"foo": ["hello", "world"]}
function Boolean
Boolean: { ( descriptor: string, opts: BooleanFlags & { required: true } ): CommandOptionReturn<boolean>; (descriptor: string, opts?: GeneralOptionFlags): boolean; ( descriptor: string, initialValue: boolean, opts?: Omit<GeneralOptionFlags, 'required'> ): boolean;};
Used to annotate boolean options.
Example 1
--foo --no-bar ► {"foo": true, "bar": false}
function cleanValidationError
cleanValidationError: ( message: string, { mergeName }?: { mergeName?: boolean }) => string;
function Counter
Counter: { ( descriptor: string, opts: CounterFlags & { required: true } ): CommandOptionReturn<number>; (descriptor: string, opts?: GeneralOptionFlags): number; ( descriptor: string, initialValue: number, opts?: Omit<GeneralOptionFlags, 'required'> ): number;};
Used to annotate options whose repeated values are aggregated into a single number.
Example 1
-vvvvv ► {"v": 5}
function formatError
formatError: (message: string, errors: Array<string>) => UsageError;
function makeCommandOption
makeCommandOption: <T>(spec: Omit<CommandOption<T>, typeof isOptionSymbol>) => T;
function Proxy
Proxy: (opts?: ProxyFlags) => string[];
Used to annotate that the command wants to retrieve all trailing arguments that cannot be tied to a declared option.
Be careful: this function is order-dependent! Make sure to define it after any positional argument you want to declare.
This function is mutually exclusive with Option.Rest.
Example 1
yarn run foo hello --foo=bar world ► proxy = ["hello", "--foo=bar", "world"]
function rerouteArguments
rerouteArguments: { <A, B>(a: A | B, b: B): [Exclude<A, B>, B]; <A, B>(a: A | B, b: B): [Exclude<A, B>, B];};
function Rest
Rest: (opts?: RestFlags) => string[];
Used to annotate that the command supports any number of positional arguments.
Be careful: this function is order-dependent! Make sure to define it after any positional argument you want to declare.
This function is mutually exclusive with Option.Proxy.
Example 1
yarn add hello world ► rest = ["hello", "world"]
function String
String: { (): CommandOptionReturn<string>; <T = string>(opts: StringPositionalFlags<T> & { required: false }): T; <T = string>(opts: StringPositionalFlags<T>): T; <T extends {} = string, Arity extends number = 1>( descriptor: string, opts: GeneralOptionFlags & { env?: string; validator?: StrictValidator<unknown, T>; tolerateBoolean?: false; arity?: Arity; } & { required: true } ): WithArity<T, Arity>; <T extends {} = string, Arity extends number = 1>( descriptor: string, opts?: StringOptionNoBoolean<T, Arity> ): WithArity<T, Arity>; <T extends {} = string, Arity extends number = 1>( descriptor: string, initialValue: Arity extends 0 ? boolean : Arity extends 1 ? string : number extends Arity ? string | boolean | Tuple<string, Arity> : Tuple<string, Arity>, opts?: Omit<StringOptionNoBoolean<T, Arity>, 'required'> ): WithArity<T, Arity>; <T = string>( descriptor: string, opts: GeneralOptionFlags & { env?: string; validator?: StrictValidator<unknown, T>; tolerateBoolean: boolean; arity?: 0; } & { required: true } ): boolean | T; <T = string>(descriptor: string, opts: StringOptionTolerateBoolean<T>): | boolean | T; <T = string>( descriptor: string, initialValue: string | boolean, opts: Omit<StringOptionTolerateBoolean<T>, 'required'> ): boolean | T;};
Used to annotate positional options. Such options will be strings unless they are provided a schema, which will then be used for coercion.
Be careful: this function is order-dependent! Make sure to define your positional options in the same order you expect to find them on the command line.
Used to annotate string options. Such options will be typed as strings unless they are provided a schema, which will then be used for coercion.
Example 1
--foo=hello --bar world ► {"foo": "hello", "bar": "world"}
type ArrayFlags
type ArrayFlags<T, Arity extends number = 1> = GeneralOptionFlags & { arity?: Arity; validator?: StrictValidator<unknown, Array<T>>;};
type BooleanFlags
type BooleanFlags = GeneralOptionFlags;
type CommandOption
type CommandOption<T> = { [isOptionSymbol]: true; definition: <Context extends BaseContext>( builder: CommandBuilder<CliContext<Context>>, key: string ) => void; transformer: <Context extends BaseContext>( builder: CommandBuilder<CliContext<Context>>, key: string, state: RunState, context: Context ) => T;};
type CommandOptionReturn
type CommandOptionReturn<T> = T;
type CounterFlags
type CounterFlags = GeneralOptionFlags;
type GeneralOptionFlags
type GeneralOptionFlags = { description?: string; hidden?: boolean; required?: boolean;};
type ProxyFlags
type ProxyFlags = { name?: string; required?: number;};
type RestFlags
type RestFlags = { name?: string; required?: number;};
type StringOption
type StringOption<T> = StringOptionNoBoolean<T> | StringOptionTolerateBoolean<T>;
type StringOptionNoBoolean
type StringOptionNoBoolean<T, Arity extends number = 1> = GeneralOptionFlags & { env?: string; validator?: StrictValidator<unknown, T>; tolerateBoolean?: false; arity?: Arity;};
type StringOptionTolerateBoolean
type StringOptionTolerateBoolean<T> = GeneralOptionFlags & { env?: string; validator?: StrictValidator<unknown, T>; tolerateBoolean: boolean; arity?: 0;};
type StringPositionalFlags
type StringPositionalFlags<T> = { validator?: StrictValidator<unknown, T>; name?: string; required?: boolean;};
type Tuple
type Tuple<Type, Arity extends number> = Arity extends Arity ? number extends Arity ? Array<Type> : TupleOf<Type, Arity, []> : never;
type TupleOf
type TupleOf< Type, Arity extends number, Accumulator extends Array<Type>> = Accumulator['length'] extends Arity ? Accumulator : TupleOf<Type, Arity, [Type, ...Accumulator]>;
type WithArity
type WithArity< Type extends { length?: number; }, Arity extends number> = number extends Type['length'] ? Arity extends 0 ? boolean : Arity extends 1 ? Type : number extends Arity ? boolean | Type | Tuple<Type, Arity> : Tuple<Type, Arity> : Type;
Package Files (19)
- lib/advanced/Cli.d.ts
- lib/advanced/Command.d.ts
- lib/advanced/builtins/definitions.d.ts
- lib/advanced/builtins/help.d.ts
- lib/advanced/builtins/index.d.ts
- lib/advanced/builtins/tokens.d.ts
- lib/advanced/builtins/version.d.ts
- lib/advanced/index.d.ts
- lib/advanced/options/Array.d.ts
- lib/advanced/options/Boolean.d.ts
- lib/advanced/options/Counter.d.ts
- lib/advanced/options/Proxy.d.ts
- lib/advanced/options/Rest.d.ts
- lib/advanced/options/String.d.ts
- lib/advanced/options/index.d.ts
- lib/advanced/options/utils.d.ts
- lib/core.d.ts
- lib/errors.d.ts
- lib/format.d.ts
Dependencies (1)
Dev Dependencies (22)
- @rollup/plugin-node-resolve
- @rollup/plugin-typescript
- @types/jest
- @types/lodash
- @types/node
- @types/rollup
- @typescript-eslint/eslint-plugin
- @typescript-eslint/parser
- @yarnpkg/core
- @yarnpkg/eslint-config
- @yarnpkg/fslib
- eslint
- eslint-plugin-arca
- eslint-plugin-react
- get-stream
- jest
- lodash
- rollup
- rollup-plugin-multi-input
- ts-jest
- ts-node
- typescript
Peer Dependencies (1)
Badge
To add a badge like this oneto your package's README, use the codes available below.
You may also use Shields.io to create a custom badge linking to https://www.jsdocs.io/package/clipanion
.
- Markdown[![jsDocs.io](https://img.shields.io/badge/jsDocs.io-reference-blue)](https://www.jsdocs.io/package/clipanion)
- HTML<a href="https://www.jsdocs.io/package/clipanion"><img src="https://img.shields.io/badge/jsDocs.io-reference-blue" alt="jsDocs.io"></a>
- Updated .
Package analyzed in 4899 ms. - Missing or incorrect documentation? Open an issue for this package.