Validator
The validator
module handles validation of option definitions. It provides functions that accept a set of definitions and perform the validation. They may also produce error and warning 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 assert that your program will work as expected when delivered to end-users.
To validate a set of option 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 compilation of warning messages generated by the validation procedure, if any
The warnings represent non-impeditive issues encountered in the option definitions. You may want to inspect it to see if they are important to your application.
Validation flags
To configure the validation procedure, you can provide a ValidationFlags
object as the first parameter to the validate
function. It contains the following optional properties:
Skip naming issues
The noNamingIssues
property indicates whether the validation procedure should skip detection of naming inconsistencies
Skip recursion
The noRecurse
property indicates whether the validation procedure should skip recursion into nested options.
Resolution callback
The resolve
property specifies a resolution function for JavaScript modules . It is used in places where a module is expected to be dynamically loaded. It is meant for use in non-browser environments and should generally have the following value (see import.meta.resolve ):
import.meta.resolve.bind(import.meta);
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 on 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 or positional marker must not contain the equals sign
'='
, since this character can be used as option-parameter separator on the command-line. Any other Unicode character is allowed (including whitespace). - Duplicate option name - An option should not have duplicate names, and there cannot be two options with the same name.
- Invalid cluster letter - Cluster letters are subject to the same restrictions as option names.
- Duplicate cluster letter - An option should not have duplicate cluster letters, and there cannot be two options with the same letter.
- Duplicate choice value - In an option with parameter choices, the choices must not contain duplicate values.
- Invalid parameter count - In a function option with a range parameter count, the minimum value should be strictly less than the maximum, but not less than zero.
- 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 (
null
orundefined
). - Duplicate positional option - Since positional arguments have no name, they must pertain to exactly one option. Hence, there cannot be two options with the positional attribute in the same set of option definitions.
null
values from the option names are ignored in name validation.
The validator does not validate the satisfiability of option requirements, not only because it cannot evaluate requirement callbacks 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.
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 may be a development mistake, or worse, it can become a source of headaches for end-users. Hence, the validator tries to find names that closely match a given name using the same algorithm employed by the parser in name suggestions, only a little stricter to avoid false positives.
- Mixed naming convention - When a name slot contains names with different naming conventions (e.g., all-uppercase vs all-lowercase, or single-dash vs double-dash), this may be a sign of code review negligence, or worse, it can make it hard for end-users to reason about your application. 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-valued 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. ↩