Skip to content

Latest commit

 

History

History
155 lines (132 loc) · 6.52 KB

File metadata and controls

155 lines (132 loc) · 6.52 KB

The definition object describing the Cli.

The general form is:

type Definition<T = Namespace | Command | Option> = {
  [key: string]: T
}

All three types have some properties in common:

type BaseElement = {
  kind?: "namespace" | "command" | "option";
  description?: string;
  hidden?: boolean;
}
  • kind: describes the type of element.
  • description: description of the element, to be used when generating help. The library will search first in CliOptions.messages with an id generated from element's location and name, followed by .description. So for example, for a nested option opt inside a command cmd, the id will be cmd.opt.description.
  • hidden: hide an element when generating help. Default: false

Namespace

An element with kind: "namespace", or since 0.11.0, when its kind is inferred to this one.

type Namespace = BaseElement & {
  kind: "namespace",
  options: Definition<Namespace | Command | Option>;
  default?: string;
}
  • default: default command to execute if none provided

Command

An element with kind: "command", or since 0.11.0, when its kind is inferred to this one.

type Command = BaseElement & {
  kind: "command";
  aliases?: string[];
  options?: Definition<Option>;
  action?: (out: ParsingOutput) => void;
  usage?: string;
}
  • aliases: alternative names for the command. If specified, the will added on top of command key. Default: [key].
  • action: method that will be called when the command is matched, receiving the output of the parsing process.
  • usage: override default Usage content for this command.

Option

An element with kind: "option", or since 0.11.0, when its kind is inferred to this one.

type Option = BaseElement & {
  kind: "option";
  aliases?: string[];
  positional?: boolean | number;
  negatable?: boolean;
  default?: any;
  required?: boolean;
  stdin?: boolean;
  type?: "string" | "boolean" | "list" | "number" | "float";
  enum?: (string | number)[];
  parser?: (input: ValueParserInput) => ValueParserOutput;
  requires?: string[] | ((v: OptionValue) => string[]);
}
  • aliases: alternative names for the options, e.g. ["h", "help"]. They should be specified without dashes, and final alias value will be calculated depending on the provided alias length: prefixed with - for single letters, and -- in other cases. When not specified, the name of the option will be used. Default: [key]
  • positional: enables positional options. Default: false
  • negatable: whether to include negated aliases in boolean options. Default: false
  • default: default value for the option.
  • stdin: whether stdin is allowed. Read below how it behaves.
  • required: specifies an option as required, generating an error if a value is not provided. Default: false
  • type: type of option, to load the appropriate parser. Default: string
  • enum: restrict the possible option-values based on the given list. Available for option-types string, list, number and float.
  • parser: allows defining custom parser for an option, instead of using the supported types.
  • requires: specifies a list of options that need to be set if this option is also set. A function may be provided, receiving the current option value.

Positional options

Positional options allow asigning an option to a determinate position in the arguments.

  • If a number is used, the argument provided in that position will be assigned to the option with that number, as long as the argument does not match with any existing alias. If the argument does match an existing alias, alias takes precedence. To provide a value for the positional option in this case, you can use the alias of the positional argument.
  • If true is provided, all isolated arguments will be assigned to this option, in the form of a list.
new Cli({ projectName: { positional: 0} }, { cliName: "create-project" });
// $ create-project newproject
// => { options: { projectName: "newproject" }}

new Cli({ files: { positional: true} }, { cliName: "format" });
// $ format file1 file2 file3
// => { options: { files: ["file1", "file2", "file3"] }}
  • If -1 is provided in combination with other positional=true, it will match the last argument:
new Cli({ files: { positional: true }, destination: { positional: -1 } }, { cliName: "cp" })
// $ cp file-1.txt file-2.txt dest
// => { options: { files: ["file-1.txt", "file-2.txt"], destination: "dest" }}

Example: jest-cli

Negated aliases

For options with type:boolean, negated aliases can be included specifying negatable:true. These negated aliases are generated from original aliases, prefixing no and no-.

new Cli({ debug: { type: "boolean", negatable: true }}, { cliName: "cli" })
// $ cli --debug
// => { options: { debug : true }}

// $ cli --no-debug
// => { options: { debug : false }}

// $ cli --nodebug
// => { options: { debug : false }}

Example: secondary-cli

Reading from stdin

An option can be configured to read its value from stdin. For this to happen, the following conditions must be met:

  • The option is configured with stdin: true
  • The value provided for the option is - (based on conventions)
  • stdin data is available

This forces a value "-" to be provided in order to read from stdin. If this not desired (many commands like cat or tail read from stdin without requiring this dash value), you could write the logic yourself, as demonstrated in this tail-v2 example.

Example: tail

Custom parser

type ValueParserInput = {
  /** Value to process */
  value: string | undefined;
  /** Current value of the option */
  current: OptionValue;
  /** Option definition */
  option: Option & { key: string };
}

type ValueParserOutput = {
  /** Final value for the parsed option */
  value?: any;
  /** Number of additional arguments that the parser consumed. For example, a boolean option
   * might not consume any additional arguments ("--show-config", next=0) while a string option
   * would ("--path path-value", next=1). The main use-case of `next=0` is when incoming value
   * is `undefined` */
  next?: number;
  /** Error generated during parsing */
  error?: string;
}

Example: custom-option-parser