Documentation
Options

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:

TypeParametersValueNormalizationConstraints
helpniladicnever1
versionniladicnever1
functionconfigurableunknown2inline, param count
commandniladic3unknown2
flagniladicboolean
booleanpositional, monadicbooleaninline, truth and falsity
stringpositional, monadicstringtrim, caseinline, enums, regex
numberpositional, monadicnumberconvinline, enums, range
stringspositional, delimited, variadic, append-ablestring[]unique, trim, caseinline, enums, regex, limit
numberspositional, delimited, variadic, append-ablenumber[]unique, convinline, 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 names
  • param - the style of the option parameter
  • descr - 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.

Mutually exclusive with always required.
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 satisfied
  • req.one - an expression that is satisfied when at least one requirement is satisfied
  • req.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, otherwise false
  • 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.

Mutually exclusive with always 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 OR option3 must have a value different than [2]) AND option1 must have the same value as option3.

If they were defined 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 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:

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.

This feature is affected by the inline attribute.

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.

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.

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.

Can only be used on monadic or delimited options.

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.

Mutually exclusive with parameter name.

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.

Mutually exclusive with append values.

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.

Mutually exclusive with enumeration.

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.

Mutually exclusive with enumeration.

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.

Mutually exclusive with parse callback.

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:

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.

Mutually exclusive with resolve callback.

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:

Mutually exclusive with version info.

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

This option has the following sets of attributes:

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
Mutually exclusive with skip 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).

Mutually exclusive with parameter count.

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:

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:

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:
  • 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
  • else, the string is considered false if it evaluates to zero; otherwise true

This option has the following sets of attributes:

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:

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:

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:

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:

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:

Footnotes

  1. help and version options throw a message instead of having a value. 2

  2. the return type of the function or command callback. 2

  3. rather than accepting parameters, it starts a new parsing context with the remaining arguments.

  4. we say that it is delimited, rather than variadic.