Options
A command-line interface is composed of commands and options (also known as flags). Options allow the 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 is a total of ten option types, as summarized in the table below:
Type | Parameters | Value | Normalization | Constraints |
---|---|---|---|---|
help | niladic | never 1 | ||
version | niladic | never 1 | ||
function | configurable | unknown 2 | inline, param count | |
command | niladic3 | unknown 2 | ||
flag | niladic | boolean | ||
boolean | positional, monadic | boolean | inline, truth and falsity | |
string | positional, monadic | string | trim, case | inline, enums, regex |
number | positional, monadic | number | conv | inline, enums, range |
strings | positional, delimited, variadic, append-able | string[] | unique, trim, case | inline, enums, regex, limit |
numbers | positional, delimited, variadic, append-able | number[] | unique, conv | inline, enums, range, limit |
The meaning of each column is explained below.
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 (opens in a new tab) for determining the available
attributes of each specific option.
Option parameters
The parameters column indicates how many parameters an option expects on the command-line:
- niladic - no parameter
- monadic - single parameter
- variadic - variable number of parameters
- delimited - single parameter in which values are delimited by a separator
- append-able - can be specified multiple times, with values getting appended
- configurable - niladic by default, but can be configured with a certain parameter count
In the case of non-niladic options, parameters can be made optional by setting a fallback value.
If a single-valued option is specified multiple times on the command line, its value is replaced by the new value. This is also the default behavior of array-valued options, unless the append attribute is set.
Option value
The data type column indicates the base type of the option value in the resulting object. Except
for the help and version options, which do not have values, the initial value of any option is
undefined
.
Normalization & constraints
Non-niladic options can be configured with normalization and constraint attributes. There are three kinds of attributes for this purpose:
- parameter constraint - restriction applied to option parameters (i.e., before they get parsed)
- value normalization - indicate how the option value should be transformed after being parsed
- value constraint - restriction applied to the parsed and normalized value
Common attributes
This section describes attributes that are common to a subset of option types. 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.
Names & preferred name
The names
attribute lists the option names as they may appear on the command-line (e.g., -h
or
--help
). Names must not contain whitespace or the equals sign '='
, since this character can
be used as option-parameter separator. If the option is not positional (i.e., does not accept
positional arguments), then it must contain at least one valid name.
The preferredName
attribute, if present, is displayed in error and help messages in cases where a
name is not available (e.g., when evaluating option requirements or processing positional arguments).
It is not validated, so it can be any string. If not specified, the first name in the names
array
will be used.
Synopsis & deprecated
The desc
attribute is the option's synopsis. The deprecated
attribute specifies the option's
deprecation notice. Both attributes are 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 parser's
parseInto
method.
Group & hide
The group
attribute is the name of a group under which the option should appear in the help
message. The hide
attribute indicates to the formatter that the option should not be displayed
in 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 can be used to customize the styling of the help message entry for the
option. 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
External reference
The link
attribute is a URL of an external resource or media, that is included in the help message
if specified.
Value attributes
All options that may have a value share a set of attributes, which are described below.
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.
Default value
The default
attribute, if present, specifies a value to be used in case the option is specified
neither on the command-line nor as an environment variable. It is only evaluated at the end of
the parsing loop.
String representation
Unknown-valued options may have any kind of value as the default. In the case of object values, it's
useful to specify a custom toString
method in order to render it in the help message, e.g.:
toString() {
return JSON.stringify(this);
}
Default callback
If the default value is not known beforehand (e.g., if it depends on the values of other options), you may want to use a callback to inspect parsed values and determine the default based on those values. It receives one parameter:
values
- the parsed values
Notes about this callback:
- it can be asynchronous
- it may be configured with a custom
toString
method to render it in the help message
Note that the help message does not use the value returned by the callback, as it may depend on the values of options passed in the command-line, which are generally not available when throwing the help.
Forward requirements
The requires
attribute, if present, specifies requirements that must be satisfied if the option
is specified on the command-line. It can be either:
- an option key;
- an object that maps option keys to required values;
- a requirement expression; or
- a requirement callback
In the case of an option key, the referenced option must also be present on the command-line. In the
case of an object, every referenced option must have the corresponding value, which can be any value
accepted by that option, undefined
to signify presence or null
to signify absence.
You cannot reference options from a nested command (parent or child) in a requirement. Option keys must always refer to options in the same set of option definitions.
Requirement expression
You can also specify an expression, in which case it is evaluated as follows:
req.all
- an expression that is satisfied when all requirements are satisfiedreq.one
- an expression that is satisfied when at least one requirement is satisfiedreq.not
- 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:
values
- the parsed values
Notes about this callback:
- it can be asynchronous
- it should return
true
if the requirements were satisfied, otherwisefalse
- it may be configured with a custom
toString
method to render it in error and help messages
The callback may perform any kind of verification, not only inspect parsed values. For example, it may check whether the environment is setup correctly for the use of an option.
Conditional requirements
The requiredIf
attribute, if present, specifies conditional requirements. They behave like the
reverse of the previous attribute: they indicate requirements that must be satisfied for the
affected option to be considered required.
An example might help elucidate this distinction. Suppose we have these requirements:
req.all(
'option1',
req.one({ option2: null }, req.not({ option3: [2] })),
(values) => values['option1'] === values['option3'],
);
If they were defined in the requires
attribute, they would mean:
If this option is specified (either on the command-line or as an environment variable), 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
.
If they were defined 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 (either on the command-line or as an environment variable).
During requirement evaluation, values are compared after being normalized.
Cluster letters
The clusterLetters
attribute, if present, specifies letters (or any Unicode characters except
whitespace) that can be used to cluster options in a single command-line argument. This feature is
also known as short-option (opens in a new tab) style, and can be enabled via the parser's clusterPrefix
configuration flag.
Here is an example that illustrates how it works. Suppose we have the following options:
- flag option, with name
'--flag'
and letters'fF'
- string option, with name
'--str'
and letters'sS'
- number option, with name
'--num'
and letters'nN'
Given these options, the following invocations would all be equivalent:
cli -fSN 'my string' 123
cli -Fsn 'my string' 123
They would be transformed to their "canonical" form, i.e.:
cli --flag --str 'my string' --num 123
Notes about this feature:
- the order of options in a cluster is preserved when converting to the canonical form
- variadic options and command options are supported, but they must be the 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
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 first letter, with no intervening space, and they contain characters that are not valid cluster letters. The first one must be valid, otherwise the argument will not be considered a cluster.
Parameter attributes
All non-niladic options share a set of attributes, which are described below.
Parameter name
The paramName
attribute, if present, specifies a name that replaces the option type in the help
message.
Positional | marker
The positional
attribute, if present, indicates that the option accepts positional arguments.
There may be at most one option with this setting.
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 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.
Complete callback
The complete
attribute, if present, specifies a custom callback for word completion. It
receives a single parameter that contains the current argument sequence information, in which
comp
is the word being completed and param
holds the option parameters preceding comp
, if any.
Notes about this callback:
- it can be asynchronous
- it should return the list of completion words
- if an error is thrown, it is ignored, and the default completion message is thrown instead
This can be used to make better suggestions than the built-in completion algorithm would do for the option.
Disable | require inline
The inline
attribute, if present, indicates the option's treatment of inline parameters. Can be
either false
to disallow or 'always'
to always require. By default, parameters are
allowed (but not required) to be inlined with option names.
Known value attributes
All non-niladic options that have known values share a set of attributes, which are described below.
Example value
The example
attribute, if present, specifies a value that replaces the option type in the help
message.
Parse callback
The parse
attribute, if present, specifies a custom callback to parse the value of the option
parameter(s). It receives a single parameter that contains the current argument sequence
information, in which param
holds the option parameter(s) and comp
indicates whether word
completion is in effect.
Notes about this callback:
- it can be asynchronous
- it should return the new option value
Enumeration
The enums
attribute, if present, specifies enumerated values that the option accepts as the result
of parsing a single option parameter. Any parameter whose parsed and normalized value does not equal
one of these values will cause an error to be thrown. They are also considered by the completion
algorithm when a word is being completed.
Mutually exclusive with regular expression and numeric range. Explicitly not available for the boolean option.
Fallback value
The fallback
attribute, if present, specifies a value to be used when the option is specified in
the command-line without any parameter. This makes the option parameter(s) optional, for both
single- and array-valued options. If not specified, the option parameter(s) will be required.
You may also specify a callback that returns the fallback value, with same semantics as the default callback.
This attribute is inherently different from the default value (i.e., they are not mutually exclusive).
String attributes
String-valued options share a set of attributes, as described below.
Regular expression
The regex
attribute, if present, specifies a regular expression that string values should match.
Any parameter whose normalized value that does not match the regular expression will cause an
error to be thrown.
Trim whitespace
The trim
attribute, if present, indicates that string values will be trimmed (i.e., have leading
and trailing whitespace removed). This normalization is applied before checking value constraints.
Case conversion
The case
attribute, if present, specifies the kind of case conversion to apply to string values.
Can be one of 'lower'
(convert to lowercase) or 'upper'
(convert to uppercase). This
normalization is applied before checking value constraints.
Number attributes
Number-valued options share a set of attributes, as described below.
Numeric range
The range
attribute, if present, specifies a (closed) numeric range within which number values
should fall. Any parameter whose parsed and normalized value is not within the given range will
cause an error to be thrown. You may want to use [-Infinity, Infinity]
to disallow NaN
.
Math conversion
The conv
attribute, if present, specifies the kind of math conversion to apply to number values.
Can be any of JavaScript's Math (opens in a new tab) functions that accept a single number parameter. This
normalization is applied before checking value constraints.
Array attributes
Array-valued options share a set of attributes, as described below.
Separator
The separator
attribute, if present, specifies a delimiter by which to split the option parameter.
If specified, the option will accept a single parameter4 on the command-line, not multiple
parameters (as is the default). It can be either a string or a regular expression.
When using this attribute, inline parameters will be allowed for an array-valued option, unless explicitly disabled by the inline attribute.
Remove duplicates
The unique
attribute, if present, indicates that duplicate elements will be removed from the
option value. This normalization is applied after other normalizations and before checking the
count limit constraint.
Due to the nature of JavaScript's Set (opens in a new tab) type, the order of elements is preserved (i.e., it reflects the order in which they were parsed).
Append values
The append
attribute, if present, indicates that the option allows appending elements to its value
if specified multiple times on the command-line. Both the remove duplicates normalization and the
count limit constraint, if enabled, are applied after appendage.
Count limit
The limit
attribute, if present, indicates the maximum allowed number of elements. Any parameter
sequence that causes the option value to exceed the given limit (after normalization) will cause
an error to be thrown.
Miscellaneous attributes
Some attributes are shared by all valued options except unknown-valued ones. They are described below.
Environment variable
The envVar
attribute, if present, specifies the name of an environment variable from which the
option value should be extracted, in case the option is not specified on the command-line.
If the environment variable for an option is found, the option is counted as if it were specified on the command-line, which has implications for the evaluation of option requirements.
Niladic options
Niladic options do not expect any parameter on the command-line. With the notable exception of the flag option, these options may have side-effects.
When word completion is in effect, help and version options are not processed.
Help option
The help option is a convenient specialization of the function option that handles the formatting of help messages. Internally, it instantiates a formatter class with the provided configuration, obtains a formatted message and throws it. The application is responsible for catching this message and printing it in a terminal.
In addition to the set of basic attributes, this option has the attributes described below.
Formatter config
The config
attribute specifies a custom formatter configuration.
Help sections
The sections
attribute specifies help sections to be rendered in the help message. By default,
two sections are included:
- usage section - with
'Usage:'
as heading, indented by 2 spaces - groups section - with
'Options:'
as the default group heading
Enable nested
The useNested
attribute is an opt-in feature that allows the next argument to be used as the name
of a nested command for which the help message should be assembled. For example, the invocation
cli --help cmd
would throw the help of the cmd
command, if it exists.
If a nested command with the specified name does not exist or does not have a help option, the argument may still be used as either a help format (if enable format is set) or an option filter (if enable filter is set).
The nested command may also set enable format and enable filter in its help option definition.
For example, the invocation cli --help cmd json -f
would throw the help of the cmd
command in
JSON format, filtered by -f
.
Enable format
The useFormat
attribute is an opt-in feature that allows the next argument to be used as the name
of a help format with which the help message should be assembled. For example, the invocation
cli --help json
would produce the help message in JSON format. The available formats are
'ansi'
(the default), 'json'
, 'csv'
and 'md'
.
Enable 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 variable name match the regex
/flag/i
.
Save message
By default, the help option will throw the help message, as a convenient way 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.
Version option
The version option is another specialization of the function option that throws a version message. In addition to the set of basic attributes, it has the attributes described below.
Version info
The version
attribute specifies a semantic version or version information.
Resolve callback
The resolve
attribute specifies a resolution function scoped to the module where a package.json
file will be searched for and read to extract its version
field.
Notes about this callback:
- it is meant for use in non-browser environments
- you should use
import.meta.resolve
(opens in a new tab) as value
Save message
By default, the version option will throw the message, as a convenient way 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.
Function option
The function option executes a generic callback function and saves its result as the option value. You can use it to perform many kinds of actions, such as:
- reading configuration from a file
- parsing key-value pairs into an object
- altering the values of previous options
- altering the option definitions in response to an option value
- e.g., if
--verbose
is set, add more help items to the help option's format
- e.g., if
This option has the following sets of attributes:
- basic attributes
- value attributes
- parameter attributes
- the attributes described below
Function callback
The exec
attribute specifies the custom callback that should be executed. It receives a single
parameter that contains the current argument sequence information, in which param
holds either
the remaining arguments or the option parameters (if parameter count is set), and comp
indicates
whether word completion is in effect.
Notes about this callback:
- it can be asynchronous
- the returned value, if any, will be saved as the option value
- altering the
param
property will have no effect on the original command-line arguments
Inside this callback, you may check whether an option has been specified before it by comparing
its value with undefined
. This works because default values are only set at the end of the
parsing loop.
Break loop
The break
attribute indicates whether the parser should exit the parsing loop after returning from
the callback.
When setting this attribute, the requirements of all options specified up to the current sequence (including the function option) will be verified. Hence, you should make it clear in the help message that any option required by the affected one must be specified before it.
Parameter count
By default, a function option is niladic. However, this behavior can be changed with the
paramCount
attribute. If present, it specifies how many parameters the option expects. It can
have either of the following values:
- a zero value: same as the niladic case
- a negative number: the option accepts unlimited parameters
- a positive number: the option expects exactly this number of parameters
- a numeric range: the option expects between a minimum and maximum count
Notice that a function option cannot have a parameter separator. The latter is only intended for
array-valued options, as they lack the flexibility of specifying a parameter count. On the other
hand, setting this attribute to 1
or [0, 1]
makes the option monadic, which enables
the use of inline parameters and/or the inline attribute.
Skip count
The skipCount
attribute indicates the number of remaining arguments to skip, after the callback
returns. Its value is meant to be changed by the callback (the parser does not alter it).
It is useful in cases where the number of parameters is unknown, 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...
exec({param}) {
const index = param.findIndex((val) => !val.startsWith('{')); // find first non-JSON param
const count = index >= 0 ? index : param.length; // count how many there are
this.skipCount = count; // <<-- tell the parser to skip them
return param.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 inside the callback.
Command option
The command option is yet another specialization of the function option that handles the execution of a "nested" command. It lets you specify the command's options in one of its attributes. The parser will process the remaining arguments and supply the parsed values to the command's callback, subsequently exiting the parsing loop.
As you might have guessed, this option allows the definition of hierarchical commands, including recursive ones. This is explained in detail in the commands guide.
This option has the following sets of attributes:
- basic attributes
- value attributes
- the attributes described below
Command callback
The exec
attribute specifies the custom callback that should be executed. It receives a single
parameter that contains the current argument sequence information, in which param
holds the
values parsed for the command.
Notes about this callback:
- it can be asynchronous
- the returned value, if any, will be saved as the option value
- when word completion is in effect, this callback will not be called, since the completion will have taken place before it gets a chance to execute
The simplest implementation would just return param
. This way, the values can be handled after
the parser returns from the parsing loop.
Please note that a command cannot access the parsed values of ancestor commands (except its immediate parent) during parsing. However, this can be achieved by handling the values after parsing.
Command options | callback
The options
attribute specifies the set of option definitions for the command. A callback may be
used to provide these definitions, which allows the implementation of recursive commands. An
asynchronous callback may be used to dynamically load option definitions from a module, in which
case you can return the result of the import
directive.
All incoming arguments will be parsed using the option definitions from this attribute, not those from the parent command. Hence, you should make it clear in the help message that all arguments pertaining to the command must be specified after it.
Cluster letters
The clusterLetters
property indicates whether the command accepts cluster arguments. This must be
used in conjunction with the cluster letters of the command's options.
Flag option
The flag option is unique in the sense that it is both niladic and has a boolean value. It differs from the boolean option in that it does not expect a parameter. While the latter can be configured to have a fallback value (thus making its parameter optional), that potentially introduces ambiguity of whether arguments are positional or not.
For example, consider the command line cli -b 1
, where -b
is a boolean option with a fallback
value and there is a positional option. In this case, would 1
be a parameter to -b
or a
positional argument? The parser is implemented to consider it a parameter to -b
. However, the flag
option completely solves this ambiguity.
If a flag option specifies an environment variable, and the variable exists in the system, the
parser considers the option value as true
, regardless of the value in the variable. This is
to be consistent with the behavior of the command-line, where the option cannot be specified with
a parameter.
This option has the following sets of attributes:
- basic attributes
- value attributes
- miscellaneous attributes
- the attribute described below
Negation names
The negationNames
attribute specifies alternate option names that can be used to turn the option
value false
(e.g., --no-flag). This is particularly useful in scripting scenarios where a
flag that has been previously specified must be reset by a supplementary list of arguments.
Non-niladic options
Non-niladic options accept one or more parameters on the command-line.
Boolean option
The boolean option accepts a single parameter that is converted to boolean according to the following rules:
- if:
- it matches one of the truth names, it is considered
true
- it matches one of the falsity names, it is considered
false
- it matches one of the truth names, it is considered
- else if:
- there are truth names, but no falsity name, the result is
false
- there are falsity names, but no truth name, the result is
true
- there are both truth and falsity names, an error is thrown
- there are truth names, but no falsity name, the result is
- else, the string is considered
false
if it evaluates to zero; otherwisetrue
This option has the following sets of attributes:
- basic attributes
- value attributes
- parameter attributes
- known value attributes for a
boolean
data type - miscellaneous attributes
- the attributes described below
Truth & falsity names
The truthNames
attribute, if present, specifies the names of the boolean truth value (e.g. true
,
yes
, on
). The falsityNames
attribute, if present, specifies the names of the boolean falsity
value. (e.g. false
, no
, off
).
These names are equivalent to the enumeration, but for a boolean value. As such, they share some of the same behaviors:
- they are considered by the completion algorithm
- they are included in the constraints validation
- they appear under the same help item
Case sensitive
The caseSensitive
attribute, if present, indicates whether the truth and falsity names should be
considered case-sensitive.
String option
The string option accepts a single parameter that is normalized according to the constraints specified in its definition. It has the following sets of attributes:
- basic attributes
- value attributes
- parameter attributes
- known value attributes for a
string
data type - string attributes
- miscellaneous attributes
Number option
The number option accepts a single parameter that is converted to number
and normalized
according to the constraints specified in its definition. It has the following sets of attributes:
- basic attributes
- value attributes
- parameter attributes
- known value attributes for a
number
data type - number attributes
- miscellaneous attributes
Strings option
The strings option accepts multiple parameters that are normalized according to the constraints specified in its definition. It has the following sets of attributes:
- basic attributes
- value attributes
- parameter attributes
- known value attributes for a
string[]
data type - string attributes
- array attributes
- miscellaneous attributes
Numbers option
The numbers option accepts multiple parameters that are converted to number
and
normalized according to the constraints specified in its definition. It has the following sets of
attributes:
- basic attributes
- value attributes
- parameter attributes
- known value attributes for a
number[]
data type - number attributes
- array attributes
- miscellaneous attributes