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:
Type | Parameters | Attribute classes |
---|---|---|
help | niladic | basic, message |
version | niladic | basic, message |
command | niladic1 | basic, value, |
flag | niladic | basic, value, environment |
single | positional, inline, monadic | basic, value, environment, parameter, selection |
array | positional, inline, variadic, delimited, appended | basic, value, environment, parameter, selection |
function | positional, inline, configurable | basic, value, environment, parameter |
The next sub-sections cover some concepts that may be used throughout this page.
Option type
The type
attribute of an option’s 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 of a specific option.
Option parameters
Each type of option expects different number of parameters on the command line:
- niladic - no parameter
- monadic - single parameter
- variadic - variable number of parameters
- delimited - values can be delimited with a parameter separator
- appended - can be specified multiple times and append values
- configurable - can be configured with a parameter count
- inline - allows parameters to be inlined with an option name
When an option is specified multiple times on the command line, its value gets replaced each time. The only exception is the case of an array-valued option with append values set.
Option value
The data type of an option value in the resulting object depends on the option type. You can check the effective data type of the option values for a set of option definitions by inspecting the IntelliSense output of:
- the result of the
parse
function - the result of the
valuesFor
function - a type alias for
OptionValues<typeof your_options>
The initial value of any option is undefined
, except for help and version options without the save message attribute.
Constraints
Non-niladic options can be configured with constraint attributes, which may be of two kinds:
- parameter constraint - a restriction applied to option parameters
- value constraint - a restriction applied to the parsed value(s)
Attribute classes
This section classifies 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 this character can be used as option-parameter separator. - A name can contain whitespace or even be the empty string. (However, this may look strange in help messages.)
- A name can be
null
, in which case the corresponding name slot will be skipped in the help message.
This attribute can be safely omitted if the option may be specified through positional arguments or through 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 in the names
array 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.
Deprecated options specified on the command line generate a warning message, 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, then the option belongs 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.
You can assign a unique group to the positional option (if there is one) and place it first in the option definitions, in order to highlight it in 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 the option namesparam
- the style of the option parameterdescr
- the style of the option description
Hyperlink
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.
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 the 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 are subject to 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 options, the following invocations would be equivalent:
cli -fSN 'my string' 1 2 3
cli -Fsn 'my string' 1 2 3
They 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 an inline parameter if they contain at least one unknown letter that is not the first. For example, using the same option definitions as above, 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, 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 argument.
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 specified, either on the command line or through the environment. Its value can be either:
- an option key;
- an object that maps option keys to required values;
- a requirement expression; or
- a requirement callback
An option key means that the referenced option must also be specified (either on the command line or through the environment). In the case of an object, 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 presencenull
to signify absence
You cannot reference options from a subcommand (parent or child) in a requirement. Option keys must always refer to options in the same level of definitions.
Requirement expression
You can also specify an expression, in which case it is evaluated as follows:
allOf
- an expression that is satisfied when all requirements are satisfiedoneOf
- an expression that is satisfied when at least one requirement is satisfiednotOf
- an expression that is satisfied when the requirement is not satisfied.
Requirement callback
You can also specify a custom callback to evaluate requirements. It receives a single parameter which contains 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 be configured with a custom toString
method to render it in error and help messages, e.g.:
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.
Mutually exclusive with always required.
An example might help elucidate this distinction. Suppose we have these requirements:
allOf(
'option1',
oneOf({ option2: null }, notOf({ option3: [2] })),
(values) => values['option1'] === values['option3'],
);
If they were declared in the requires
attribute, they would mean:
If this option is specified, then the following must hold true:
option1
must be present AND (option2
must be absent ORoption3
must have a value different than[2]
) ANDoption1
must have the same value asoption3
.
And if they were declared in the requiredIf
attribute, they would mean:
If
option1
is present AND (option2
is absent ORoption3
has a value different than[2]
) ANDoption1
has the same value asoption3
, then this option is considered required and must be specified.
An option is considered specified if it either appears on the command line or has data coming from the environment.
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 specified neither on the command line nor in the environment.
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 option 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 can be configured with a custom toString
method, e.g.:
options.flag.default.toString = () => 'this and that ...';
Parsing callback
The parse
attribute, if present, specifies a custom callback to parse the option’s parameter(s). It should return the option value (or a promise thereof).
Depending on the option type, the callback receives a different kind of data in its first parameter. But its second parameter always contains the current argument information, which includes the option’s name, argument index and any previously parsed values.
If you need to throw an error from the callback, we recommend using the error message’s createCustom
static method. It receives a custom phrase that is formatted similarly to error phrases.
Within the callback, you can check whether an option has been specified before by comparing its value with undefined
. This works because default values 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.
Accept input
The stdin
attribute, if present, indicates that the option accepts data from the standard input. It will only have effect if the option is not specified on the command line, otherwise the input stream will remain untouched.
The parser only reads readily available data, without waiting for new input. This means that it can only extract data from redirected command outputs, not from interactive terminals. For the latter effect, you should use a default value callback in conjunction with third-party prompting libraries.
This attribute has precedence over data sources.
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.
Data sources
The sources
attribute, if present, specifies names of environment data sources from which the option value should be read, in case it is specified neither on the command line nor in the standard input.
Sources are tried in the specified order. A string
means an environment variable, while a URL
indicates the path of a local file.
If data is found in a source, the affected option will be considered as if specified on the command line, which has implications for evaluating the option’s requirements.
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 specified 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 specified before it.
Parameter attributes
All non-niladic options share a set of attributes, which are described below.
Example value
The example
attribute, if present, specifies a value to appear in the help message parameter column.
Mutually exclusive with parameter name.
Parameter name
The paramName
attribute, if present, specifies a name to appear in the help message parameter column.
Mutually exclusive with example value.
Positional | marker
The positional
attribute, if present, indicates that the option accepts positional arguments. There may be at most one option with this setting in the same level of definitions.
If set to true
, then any argument not recognized as an option name will be considered positional. If set to a string, then it acts as a positional marker, in which case all arguments that appear beyond the marker will be considered positional.
When using this attribute, we recommend also setting preferred name to some explanatory name.
The positional marker should not be included in the list of option names, although it is subject to the same restrictions.
Inline constraint
The inline
attribute, if present, indicates the option’s treatment of inline parameters. It can be either false
to disallow, or 'always'
to always require inline parameters. By default, parameters are allowed (but not required) to be inlined with option names.
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:
param
- the word being completedinfo
- the current argument information
It should return the list of completion words (or a promise thereof). If an error is thrown, it will be ignored and the default completion message will be thrown instead.
Selection attributes
Both single- and array-valued 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’s parameter(s) should match. Any parameter that does not match the regex (after applying any 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). Any parameter that does not match one of these values (after applying any normalization) will cause an error to be raised. They 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 keys (after applying any normalization), it will get mapped to the corresponding value; otherwise it will be forwarded to the parsing callback, if specified.
Parameter normalization
The normalize
attribute, if present, specifies a normalization function 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 handles the formatting of help messages. 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.
In addition to the sets of basic and message attributes, this option has the attributes 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 is an opt-in feature that allows the next argument to be used as the name of a subcommand for which the help message should be generated. For example, the invocation cli --help cmd
would throw the help of the cmd
command, 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 considered as an option filter when enable option filter is set.
Enable option filter
The useFilter
attribute is an opt-in feature that allows the remaining arguments to be used as option filter. For example, the invocation cli --help flag
would only include in the help message those options whose names, synopsis or environment data sources match the regex /flag/i
.
The two features above may be used together. For example, the invocation cli --help cmd -f
would throw the help message of the cmd
subcommand, filtered by option -f
.
Version option
The version option throws a version message. In addition to the sets of basic and message attributes, it has a single attribute described below.
When word completion is in effect, this option will be skipped.
Version info
The version
attribute specifies the version information. It accepts either of the following values:
- unstructured text data (e.g., a semantic version)
- the path of a JSON file whence a
version
field will be extracted
In the latter case, the path should generally be './package.json'
and should be used in conjunction with the resolution callback parsing flag.
Command option
The command option — a.k.a. subcommand — lets you specify a set of option definitions for which the parser should process the remaining arguments.
It will supply the parsing callback of the subcommand with the parsed values and subsequently exit the parsing loop. The option value will be either the result of the callback, if 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 parsing callback will not be called, since completion will have occurred before it has a chance to execute.
In addition to the sets of basic and value attributes, it has the attributes described below.
Nested options
The options
attribute, if present, specifies a set of option definitions for the subcommand. Its value can be either of:
- an object containing the option definitions (or a promise thereof)
- a callback that returns the option definitions (or a promise thereof)
- the path of a JavaScript module exporting the option definitions
A callback allows the implementation of recursive commands, whereas a module path allows a dynamic import . The latter case should be used in conjunction with the resolution callback parsing flag. In either case, it is only evaluated once the affected option is parsed from the command line.
All incoming arguments will be parsed using the option 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 specified after it.
Cluster prefix
The clusterPrefix
attribute, if present, indicates whether the command accepts cluster arguments. It has the same semantics as the cluster prefix parsing flag, and must be used in conjunction with the cluster letters of the nested options.
This attribute has precedence over option prefix.
Option prefix
The optionPrefix
attribute, if present, specifies the prefix for option names within the command. 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.
Flag option
The flag option accepts no parameter, but has a value that will be either the result of the parsing callback, if specified, or true
. The callback receives the empty string 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 attributes
- value attributes
- environment attributes
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 argument 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 parsing callback receives a string
as first parameter, which is the option parameter, and should return the option value.
This option has the following sets of attributes:
- basic attributes
- value attributes
- environment attributes
- parameter attributes
- selection attributes
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 parsing callback receives a string
as first parameter, which is a single option parameter, and should likewise return the value of a single array element. The resulting array may be normalized according to value constraints.
This option has the following sets of attributes:
- basic attributes
- value attributes
- environment attributes
- parameter attributes
- selection attributes
- the attributes 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.
Due to the nature of JavaScript’s Set , the order of elements is preserved (i.e., it reflects the order in which the arguments were parsed).
Append values
The append
attribute, if present, indicates that the option allows appending elements to its value when specified multiple times on the command line. 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 option value 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 specified, or the parsed values themselves.
The callback receives a string[]
as first parameter, which contains the option parameters, and should return the option value. As a special case, this array may contain all the remaining command-line arguments (see parameter count for details).
This option has the following sets of attributes:
- basic attributes
- value attributes
- environment attributes
- parameter attributes
- the attributes described below
Parameter count
The paramCount
attribute, if present, specifies the number of parameters that the option expects. It can have either of the following values:
- unspecified or negative: the option accepts unlimited parameters
- zero: the option accepts unknown number of parameters (see below)
- positive: the option expects exactly this amount
- range: the option expects between a minimum and a maximum count
In the special case of zero, the parsing callback will receive all remaining command-line arguments. It should be used in conjunction with the skip count attribute. Note that altering the string array inside the callback would have no effect on the original arguments, as it is just a copy.
Note that this option cannot have a parameter separator, since it would conflict with the parameter count. To see why, consider the case where the minimum count is 2. Then, the second argument following the option would always be treated as a parameter, regardless of whether it is the name of another option, even if the previous argument had two delimited parameters. This is because the parser does not look for delimiters when forming an argument sequence.
If the data comes from the environment, then the parsing callback will receive an array with a single element as parameter, which may be less than the expected count. You should inspect the index
property of the argument information, which should be NaN
in this case.
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. 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 (you can check if this is the case by inspecting the comp
property of the argument information). If it pertains to the current argument sequence, you can throw completion words from the callback as an instance of the text message.
Footnotes
-
Rather than accepting parameters, it starts a new parsing context with the remaining arguments. ↩