Validator
The validator
module handles validation of option definitions. It provides a function that accepts a set of definitions and performs the validation. It may also produce error messages, which can be customized via message configuration.
Option validation
We use the term validation to refer to the “sanity check” of option definitions. It is meant for use during development, whereas in production it would impose an unnecessary performance penalty on your application. In this sense, validations behave like assertions: they ensure that your program will work as expected when delivered to end-users.
Validating the options
To validate a set of definitions, you must call the validate
function. It accepts the following parameters:
options
— the option definitions (required)flags
— an object containing the validation flags (optional)
It returns a promise that resolves to a ValidationResult
object containing the following property:
warning
— a list of warnings encountered in the validation procedure, if any
Validation flags
The validation procedure can be configured via a ValidationFlags
object that has some optional properties, as described below.
Skip warnings
The noWarn
property indicates whether the validator should skip generation of warnings.
Skip recursion
The noRecurse
property indicates whether the validator should skip recursion into nested options.
Similarity threshold
The similarity
property indicates the similarity threshold for similar option name validation. Values are given in percentage (e.g., 0.8
). Zero or NaN
means disabled.
Validation rules
There are two kinds of validation rules, depending on whether they generate an error or a warning. They are listed below.
Validation errors
The following restrictions will raise an error for any option definition that fails to satisfy it, with an explanatory message that may include the option’s key.
- Invalid option name — An option name, cluster letter, parameter marker, environment variable name must not contain the equals sign
'='
, since this character can be used as option-parameter separator. Any other Unicode character is allowed (including whitespace). - Duplicate option name — An option should not have duplicate names (including all of the above), and there cannot be two options with the same name.
- Duplicate parameter choice — In an option with parameter choices, the choices must not contain duplicate values.
- Invalid parameter count — A function option should have a valid parameter count.
- Option requiring itself — An option must not declare a requirement that references itself.
- Unknown required option — An option must not declare a requirement that references an unknown option.
- Invalid required option — An option must not declare a requirement that references a non-valued option (help or version) in a requirement.
- Invalid required value — An option must not declare a requirement that references another option that is either always required or has a default value, if the required value is nullish (i.e.,
null
orundefined
). - Invalid inline constraint — An inline constraint should not be declared if the option has no name, or if it applies to all names and the option is polyadic, or if it applies to specific names and references an unknown name.
- Option not suppliable — It must be possible for an option to be supplied, i.e., the latter must either have an option name, cluster letter, data source, parameter marker, or accept positional arguments.
null
values from the option names are ignored in name validation.
The satisfiability of option requirements is not verified, not only because requirement callbacks cannot be evaluated at validation time, but also because requirement expressions can be arbitrarily complex. For example, a simple expression like allOf({ opt: 1 }, { opt: 2 })
cannot be satisfied, but is hard to verify in general1. You should ensure that this does not happen.
Validation warnings
The following restrictions will produce a warning that is returned by the validation procedure.
- Too similar names — When two option names are very similar (e.g., if they differ by a single character in a five-character name), this could be a development mistake or, worse, it can become a source of headaches for end-users. Hence, when the similarity threshold flag is enabled, the validator tries to find names that closely match a given name using the Gestalt  algorithm.
- Mixed naming convention — When a name slot contains names with different naming conventions (e.g., all uppercase vs all lowercase), this could be a sign of code review neglect or, worse, it can make reasoning about your application difficult. Thus, the validator tries to find names within a slot that contain mixed naming patterns.
- Variadic option with cluster letter — A variadic option that declares cluster letters must always be the last option in a cluster argument. This includes subcommands, array options and function options with a variable parameter count. This might not be the intended behavior and, if so, you should consider alternatives.
Footnotes
-
This problem is known as B-SAT , which is known to be NP-complete  in the general case. ↩