Skip to Content
Nextra 4.0 is released 🎉

Options

A command-line interface can be composed of subcommands and options (also known as flags). The options allow a calling application or user to configure the command that will run. tsargp offers a selection of option types that should suit most applications. In the next sections, we present the available types and describe them in detail.

Option types

There are seven types of options, as summarized in the table below:

TypeParametersAttribute classes
helpniladicbasic, message
versionniladicbasic, message
commandniladic1basic, value, template
flagniladicbasic, value, environment
singlepositional, inline, monadicbasic, value, environment, template, parameter, selection
arraypositional, inline, variadic, delimited, appendedbasic, value, environment, template, parameter, selection
functionpositional, inline, configurablebasic, value, environment, template, parameter

Glossary

The next sub-sections cover some concepts that may be used throughout this page.

Option definition

An option is configured through a definition object, whose properties we shall denote as attributes. Also, in a hierarchical set of definitions, a level constitutes the list of options from the same subcommand or main command.

Option type

The type attribute of an option definition indicates the type of the option. It is the only required attribute of any option, and is used as a discriminant for determining the available attributes for a specific option.

Option parameters

Each type of option expects a different number of parameters on the command line:

Option value

The option value (also called parsed value) appears in the resulting object. Its data type depends on the option type. You can check the effective data type of the values for a set of option definitions by inspecting IntelliSense hints. For example, consider the following script:

const = { : { : 'help' }, : { : 'flag' }, : { : 'single', : ['one', 'two'] }, : { : 'array', : ['one', 'two'], : { : 1 }, : true }, : { : 'function', : , : null }, : { : 'command', : { : { : 'version' } } }, } as satisfies ;
Hover over the assigned values
const = await (); const = (); type = <typeof >;

Notice that the properties in the resulting object are readonly. This is intentional: the parsed values should never be modified, because they reflect the command line. Generally, you can do any necessary transformation inside the parsing callback and return arbitrary values, such as class instances, which should be enough for most purposes.

A few additional remarks:

  • the initial value of any valued option is undefined
  • the final value of any valued option can be undefined, unless it is always required or has a default value
  • if an array option declares a default value that is not an array, that value is converted to a single-element tuple
  • help and version options without the save message attribute do not have a value

Option requirements

An option can be configured with requirements, which are specifications of inter-dependencies between options and/or option values in the same definition level.

Option constraints

Non-niladic options can be configured with constraint attributes, which may be of two kinds:

  • parameter constraint — a restriction applied to option parameter(s)
  • value constraint — a restriction applied to the parsed value(s)

Option supply

An option is considered supplied if it either appears on the command line or has data coming from the environment.

When an option is supplied multiple times, its value gets replaced each time. The only exception is an array option configured with append values.

Attribute classes

This section classifies some attributes according to the subset of option types to which they apply. The options themselves will be explained later in this page.

Basic attributes

All options share a set of attributes in addition to their type. They are described below.

Option names

The names attribute lists the option names as they may appear on the command line (e.g., -h or --help). The following rules apply to option names:

  • A name must not contain the equals sign '=', since the latter is used as option-parameter separator.
  • A name should not contain styles, but may contain any other Unicode character (including whitespace) or even be the empty string.
  • A name can be null, in which case the corresponding name slot will be skipped in the help message.
💡

Names can be omitted if the option may be supplied through positional arguments or the environment.

Preferred name

The preferredName attribute is used for informational purposes. It is displayed in messages in cases where a name is not available, e.g., when evaluating option requirements or processing positional arguments. If not specified, the first name from option names will be used.

This attribute is not validated, so it can be any string.

Option synopsis

The synopsis attribute, if present, specifies a brief summary of the option’s purpose. It will be formatted in the help message according to text formatting rules.

Deprecation notice

The deprecated attribute, if present, specifies the reason for the option being deprecated. It will be formatted in the help message according to text formatting rules.

Note that the library does not provide a deprecation mechanism for specific values within attributes, such as option names, parameter choices or data sources. For that effect, you will have to clarify it in the option synopsis.

💡

When a deprecated option is supplied it generates a warning, which you may want to print in the terminal. It can be obtained by destructuring the result of the parseInto function.

Group | hide

The group attribute, if present, specifies the name of a group under which the option should appear in the help message. If absent, the option will belong to the default group, which is also denoted by the empty string. Alternatively, you can use the value null to completely hide it from the help message.

Display styles

The styles attribute, if present, specifies custom styling attributes for each of the option’s help columns. It has the following optional properties:

  • names — the style of option names
  • param — the style of option parameter
  • descr — the style of option description

Layout settings

The layout attribute, if present, specifies option-specific help layout settings for presentation in help messages.

The link attribute, if present, specifies the URL of an external resource or media. It will be included in the option’s description in the help message.

Message attributes

Both the help and version options share the attribute described below.

Save message

By default, the option will throw the generated message, as a convenient way for the application to print it in the terminal. However, this behavior can be changed with the saveMessage attribute. If present, it indicates that the message should be saved as the option value instead of being thrown.

The reason why the library does not itself print the message is to allow client code to choose the output medium. For example, in browser environments, one may want to display the message in a dialog or an embedded terminal instead of printing in the browser console.

Value attributes

All options that may have a value share a set of attributes, which are described below.

Cluster letters

The cluster attribute, if present, specifies letters that can be used to combine options into a single command-line argument. This feature is also known as short-option style, and can be enabled via the cluster prefix parsing flag.

Cluster letters should not be included in the list of option names, although they share the same restrictions.

Here is an example that illustrates how it works. Suppose we have the following options:

  • flag option, with name '--flag' and letters 'fF'
  • single option, with name '--str' and letters 'sS'
  • array option, with name '--num' and letters 'nN'

Given these definitions, the following invocations would be equivalent:

cli -fSN 'my string' 1 2 3 cli -Fsn 'my string' 1 2 3

And would be transformed into their “canonical” form, i.e.:

cli --flag --str 'my string' --num 1 2 3
Cluster parsing rules

The following rules apply to cluster arguments:

  • the order of options in a cluster is preserved when converting to the canonical form
  • variadic options and subcommands are supported, but they must come last in a cluster
  • if word completion is attempted for a cluster, the default completion message is thrown
  • if a nameless positional option appears in a cluster, its argument will be treated as positional
Cluster inline parameters

Cluster arguments may be considered to have inline parameters if they contain at least one unknown letter that is not the first. For example, using the previous definitions, the command line cli -s'my str' -n123 would be parsed as cli --str 'my str' --num 123.

Notice how the parameters appear “glued” to the cluster letter (i.e., with no intervening space), and they contain characters that are not valid cluster letters. However, the first letter must be valid for the argument to be considered a cluster.

This feature is affected by the inline constraint.

Always required

The required attribute, if present, indicates that the option is always required, regardless of other options.

Mutually exclusive with default value and conditional requirements.

💡

When using this attribute, we recommend also setting preferred name to some explanatory name.

Forward requirements

The requires attribute, if present, specifies requirements that must be satisfied if the option is supplied. Its value can be any of the following:

An option key means that the referenced option must also be supplied. In the case of a record, every referenced option must have the corresponding value, which can be any value accepted by that option, or one of the special values:

  • undefined — to signify presence; or
  • null — to signify absence

Options from a subcommand (whether parent or child) cannot be referenced in a requirement. Option keys must always refer to options in the same definition level.

Requirement expression

You can specify requirements as an expression, in which case it is evaluated as follows:

  • allOf — an expression that is satisfied when all requirements are satisfied
  • oneOf — an expression that is satisfied when at least one requirement is satisfied
  • not — an expression that is satisfied when the requirement is not satisfied
Requirement callback

You can specify a custom callback to evaluate requirements. It receives a single parameter containing the parsed values, and should return a boolean (or a promise thereof) indicating whether the requirements were satisfied. It may perform any kind of verification, such as inspect parsed values, check the environment, etc.

It may also be configured with a custom toString method, so it can be displayed in messages. For example:

options.flag.requires.toString = () => 'this and that ...';

Conditional requirements

The requiredIf attribute is reciprocal to the previous one: if present, it specifies requirements that must be satisfied for the affected option to be considered required. It accepts the same kinds of value as the former.

An example might help elucidate the distinction. Suppose we have these requirements:

allOf( 'option1', oneOf({ option2: null }, not({ option3: [2] })), (values) => values['option1'] === values['option3'], );

If they were declared in the requires attribute, they would mean:

If this option is supplied, then the following must hold true: option1 must be present AND (option2 must be absent OR option3 must have a value different than [2]) AND option1 must have the same value as option3.

And if they were declared in the requiredIf attribute, they would mean:

If option1 is present AND (option2 is absent OR option3 has a value different than [2]) AND option1 has the same value as option3, then this option is considered required and must be supplied.

Mutually exclusive with always required.

Default value

The default attribute, if present, specifies a value (or a promise thereof) to be used at the end of the parsing loop, in case the option is not supplied.

Mutually exclusive with always required.

Default value callback

In case the default value is not known beforehand, you can use a callback. It receives a single parameter containing the parsed values, and should return the default value (or a promise thereof).

When rendering a help message, the formatter disregards any value returned by the callback, as it may depend on the values parsed from command-line arguments (which are not available when processing the help option). On the other hand, the callback may be configured with a custom toString method, so it can be displayed in messages, e.g.:

options.flag.default.toString = () => 'this and that ...';

Parsing callback

The parse attribute, if present, specifies a custom callback to parse the option parameter(s). It receives two parameters:

The param will be of a different kind for each option:

  • parsed values — for the command option
  • null value — for the flag option
  • string value — for the single and array options
  • string array — for the function option

The callback should return the parsed value (or a promise thereof). To throw an error from within it, we recommend instantiating the error message class.

💡

You can check whether an option has been supplied before by comparing its value with undefined. This works because default values and values from the environment are only set at the end of the parsing loop.

Environment attributes

Options that may read data from the environment share some attributes, as described below.

Data sources

The sources attribute, if present, lists names of environment data sources from which the option value should be read, in case it is not supplied on the command line. Its elements can be either of:

  • string — an environment variable; or
  • URL — the path of a local file (to be used with import.meta.resolve)

The reason why we did not use a dedicated env attribute for environment variables was a design choice: since the sources are tried in the specified order, you can mix the two types of values in order of priority.

This attribute has precedence over standard input.

Variable names should not be included in the list of option names, although they share the same restrictions.

⚠️

If data is found in a source, the affected option will be considered supplied, which has implications for evaluating option requirements.

Standard input

The stdin attribute, if present, indicates that the option may read data from the standard input. It only has effect if:

  • the option is not supplied; and
  • the option pertains to the command or subcommand being executed (i.e., not a parent one); and
    • the option is always required; or
    • the terminal is non-interactive (i.e., the data comes from a redirected output)

Otherwise, the input stream will remain untouched.

💡

You can omit the option names or hide the option from the help message, if you want its value to be read exclusively from the standard input.

⚠️

In the case of interactive terminals, the parser will block to wait for new input. If you need more sophisticated handling of interactive terminals, do yourself a favor and use a third-party prompting library in conjunction with a default value callback.

Break loop

The break attribute indicates whether the parser should exit the parsing loop after returning from a parsing callback.

⚠️

When setting this attribute, the requirements of all options supplied up to the current argument will be verified. Hence, you should make it clear in the help message that any options required by the affected one must be supplied either before it or through the environment.

Template attributes

Non-niladic options and subcommands share a set of attributes, which are described below.

Example value

The example attribute, if present, specifies a value to display in place of option parameter(s) in help messages. It will appear in the parameter column and, when a parameter name is not present, in the usage statement as well.

Parameter name

The paramName attribute, if present, specifies a name to to display in place of option parameter(s) in help messages. It will appear in the usage statement and, when an example value is not present, in the parameter column as well.

Overrides example value in usage statements.

Usage parameter name

The usageParamName attribute, if present, specifies a name to to display in place of option parameter(s), but only in a usage statement. It does not appear in the parameter column.

Overrides example value and parameter name in usage statements.

Parameter attributes

Non-niladic options share a set of attributes, which are described below.

Positional

The positional attribute, if present, indicates that the option accepts positional arguments. An argument is considered positional if it is not recognized as an option name or is supplied through the positional marker.

If there are multiple positional options, their declaration order determines their relative position in the command line. A variadic option will take all remaining positional arguments. Otherwise, if there are more arguments than options, the last such option will take the excess.

💡

When using this attribute, we recommend also setting preferred name to some explanatory name.

💡

You can assign a unique group to positional options and declare them first in the definitions, so as to highlight them in the help message.

Inline constraint

The inline attribute, if present, indicates the option’s treatment of inline parameters. Its value can be either of:

  • false — to disallow inline parameters;
  • 'always' — to require inline parameters; or
  • object — a record that maps option names to one of the above, indicating the constraint for specific names

By default, parameters are allowed (but not required) to be inlined with any option name.

Completion callback

The complete attribute, if present, specifies a custom callback for word completion, which can be used to make better suggestions than the built-in algorithm would for the option. It receives two parameters:

It should return the list of completion words or suggestions (or a promise thereof). If an error is thrown, it will be ignored and the default completion message will be thrown instead.

Parameter marker

The marker attribute, if present, specifies marker(s) to delimit the option parameters. It has the same semantics as the positional marker, except that it does not appear in help messages and the parameters are not treated as positional.

This attribute is not available for the single option.

Marker(s) should not be included in the list of option names, although they share the same restrictions.

Here is an example that illustrates how it works. Suppose we have the following option:

const = { : { : 'array', : ['-a'], : ['[', ']'], }, } as satisfies ;

Given these definitions, the following invocations would be equivalent:

cli -a abc 1 2 3 cli [ abc 1 2 3 cli [ abc 1 2 3 ]

However, the last two invocations would allow passing option names as parameters (e.g., '-a'), whereas the first would not. Additionally, the last invocation would allow more arguments to come after.

Selection attributes

Both the single and array options can have additional parameter constraints, for which they share the set of attributes described below.

Regular expression

The regex attribute, if present, specifies a regular expression that the option parameter(s) should match. A parameter that does not match the regex (after applying any configured normalization) will cause an error to be raised.

Mutually exclusive with parameter choices.

Parameter choices

The choices attribute, if present, specifies string values that the option accepts as parameter(s). A parameter that does not match any of these values (after applying any configured normalization) will cause an error to be raised. These values are also considered by the completion algorithm when a parameter is being completed.

Mutually exclusive with regular expression.

Parameter mapping

The mapping attribute, if present, specifies a record that maps parameter values to option values. In this case, if a parameter matches one of the given keys (after applying any configured normalization), it will get mapped to the corresponding value; otherwise it will be forwarded to the parsing callback, if one is specified.

Parameter normalization

The normalize attribute, if present, specifies a normalization function to be applied to parameters before they get validated and/or parsed. This includes parsing of option parameters and performing word completion.

Niladic options

Niladic options do not expect any parameter on the command line.

Help option

The help option uses the formatter to generate a help message. Internally, it calls the format function with the provided configuration, obtains the formatted message and throws it. The application is responsible for catching this message and printing it in a terminal.

When word completion is in effect, this option will be skipped.

This option has the following sets of attributes: basic, message and the ones described below.

Help sections

The sections attribute specifies help sections to be rendered in the help message. By default, a single groups section is included.

Enable subcommand

The useCommand attribute, if present, indicates that the option may use the next argument as the name of a subcommand for which the message should be generated. For example, the following invocations would be equivalent:

cli --help cmd cli cmd --help

And would throw the help of the cmd subcommand, if it exists.

If a subcommand with the specified name does not exist or does not have its own help, the argument may still be subject to enable option filter.

Enable option filter

The useFilter attribute, if present, indicates that the option may use the remaining arguments as option filter. If enabled, an invocation like cli --help flag would only include options whose names, synopsis or environment variable names contain the pattern flag (case-insensitive).

This feature can be combined with enable subcommand. For example, the following invocations would be equivalent:

cli --help cmd -f cli cmd --help -f

And would throw the help message of the cmd subcommand, filtered by option -f.

Version option

The version option throws a version message. The application is responsible for catching this message and printing it in a terminal.

When word completion is in effect, this option will be skipped.

This option has the following sets of attributes: basic, message and the one described below.

Version info

The version attribute, if present, specifies the version information. Its value is supposed to be a semantic version, but can be any kind of unstructured text data and is not interpreted or validated.

💡

You can get the version field from a JSON module through the getVersion function.

Command option

The command option, also known as subcommand, can be configured with a set of option definitions for which the remaining arguments should be parsed. It will forward the parsed values to the parsing callback and subsequently break the parsing loop.

The option value will be either the result of the callback, if one is specified, or the parsed values themselves. Values of ancestor commands (i.e. non-immediate parents) cannot be accessed from within the callback. For this purpose, you will need to wait until the parsing procedure returns.

When word completion is in effect, the callback will not be called, since completion will have occurred before it has a chance to execute.

This option has the following sets of attributes: basic, value, template and the ones described below.

Nested options

The options attribute, if present, specifies a set of option definitions for the subcommand. Its value can be either of:

  • object — a record containing the option definitions (or a promise thereof); or
  • a callback that returns the option definitions (or a promise thereof)

A callback is useful for various reasons, but especially because it allows:

In either case, the callback is only evaluated once the affected option is parsed from the command line.

⚠️

Remaining arguments will be parsed according to the definitions from this attribute, not from the parent command. Hence, you should make it clear in the help message that all arguments pertaining to the subcommand must be supplied either after it or through the environment.

Cluster prefix

The clusterPrefix attribute, if present, indicates whether the subcommand accepts cluster arguments. It must be used in conjunction with the cluster letters of the nested options.

This attribute is analogous to the cluster prefix parsing flag, and has precedence over the attribute below.

Option prefix

The optionPrefix attribute, if present, specifies the prefix for option names within the subcommand. If set, then arguments starting with this prefix will be considered an option name, regardless of their position respective to other arguments in the command line.

This attribute is analogous to the option prefix parsing flag.

Flag option

The flag option accepts no parameter, but has a value that will be either the result of the parsing callback, if one is specified, or true. The callback receives the value null as its first parameter.

💡

If you need a boolean-valued option that accepts a single parameter, use the single option instead. To make the parameter optional, use the function option with a parameter count of [0, 1].

This option has the following sets of attributes: basic, value and environment.

Old library versions provided an attribute to indicate alternate option names to turn the option value false (e.g., —no-flag). This can now be achieved by inspecting the name property of the sequence information.

Non-niladic options

Non-niladic options accept one or more parameters on the command line.

Single-valued option

The single option accepts a single parameter. Its value can be either the result of the parsing callback, one of the parameter choices, one of the parameter mapping values or the parameter itself (by default).

The callback receives the option parameter as its first parameter, and should return the parsed value.

This option has the following sets of attributes: basic, value, environment, template, parameter and selection.

Array-valued option

The array option accepts multiple (zero or more) parameters. Its value is an array whose elements can be either the result of the parsing callback, one of the parameter choices, one of the parameter mapping values or the parameters themselves (by default).

The callback receives a single option parameter as its first parameter, and should likewise return the parsed value of a single array element. The resulting array may be subject to value constraints.

This option has the following sets of attributes: basic, value, environment, template, parameter, selection and the ones described below.

Parameter separator

The separator attribute, if present, specifies a delimiter by which to split the option parameters. It can be either a string or a regular expression.

💡

When not using this attribute, we recommend setting the inline constraint to false.

Remove duplicates

The unique attribute, if present, indicates that duplicate elements will be removed from the option value. This normalization is applied before checking the element count limit. The remaining elements are left in the order in which they were parsed.

Append values

The append attribute, if present, indicates that the option allows appending elements to its value when supplied multiple times. Any duplicates are removed after appendage, if enabled.

Element count limit

The limit attribute, if present, indicates the maximum allowed number of elements. Any argument sequence that causes the array length to exceed the given limit (after removing any duplicates) will cause an error to be raised.

Function option

The function option exists for the sole purpose of being configured with an expected parameter count, and is the only option that can accept between zero and one parameter. Its value will be either the result of the parsing callback, if one is specified, or the parameters themselves.

The callback receives the list of option parameters as its first parameter, and should return the parsed value. As a special case, this list may contain all the remaining command-line arguments (see parameter count below).

This option has the following sets of attributes: basic, value, environment, template, parameter and the ones described below.

Parameter count

The paramCount attribute, if present, specifies the number of parameters that the option expects on the command line. Its value can be either of:

  • unspecified or Infinity — the option accepts unlimited parameters;
  • zero — the option accepts unknown number of parameters (see below);
  • positive — the option expects exactly this amount; or
  • range — the option expects between a minimum and a maximum count

In case of a numeric range, the minimum should be strictly less than the maximum, but not less than zero. In the special case of zero, the parsing callback will receive a copy of all remaining command-line arguments. This feature should be used in conjunction with the skip count attribute.

⚠️

If the data comes from the environment, then the callback will receive a single-element tuple as parameter, which may be less than the expected count. To check if this is the case, you should inspect the index property of the sequence information, which should have the value NaN.

Note that this option cannot have a parameter separator, since it would conflict with the parameter count. To see why, consider the case with a minimum count of 2. Then, the second subsequent argument would always be treated as a parameter, regardless of whether it is an option name, even if the previous argument had two or more delimited parameters. This is because the parser does not look for delimiters when forming an argument sequence.

Skip count

The skipCount attribute indicates the number of remaining arguments to skip, after returning from the parsing callback. This value is meant to be changed by the callback, and only works when the parameter count is zero.

It is useful in cases where the number of parameters is not known beforehand, and the callback wants to have control over where an argument sequence ends. Note that this is different from unlimited parameters, where the parser must detect the end of a sequence based on the occurrence of option names in the command line.

Here is an example of how it might be used inside the callback:

{ // other attributes... parse(params) { const index = params.findIndex((val) => !val.startsWith('{')); // find first non-JSON param const count = index >= 0 ? index : params.length; // count how many there are this.skipCount = count; // <<-- tell the parser to skip them return params.slice(0, count).map((val) => JSON.parse(val)); // return the parsed values }, }

When word completion is in effect, the last argument will be the word to complete. If the latter pertains to the current sequence, you can throw a completion message from the callback. (See also the completing property of the sequence information.)

Footnotes

  1. Rather than accepting parameters, it starts a new parsing context with the remaining arguments.

Last updated on