1.1.1 • Published 3 years ago

shargs v1.1.1

Weekly downloads
235
License
MIT
Repository
github
Last release
3 years ago

🦈 shargs (shell args) is a library for building command-line argument parsers.

node version npm version license PRs Welcome linux unit tests status macos unit tests status windows unit tests status

Features

Installation

Install as a bundle (recommended):

Install as modules:

The documentation assumes the bundle is installed, but the only difference between the bundle and modules installation is how functions are imported: The bundle uses require('shargs/opts'), while require('shargs-opts') is used by modules (note the use of / vs. -). Read installing as bundle or modules for more details.

Getting Started

const opts = [
  stringPos('question', {desc: 'Ask a question.', required: true}),
  number('answer', ['-a', '--answer'], {desc: 'The answer.', defaultValues: [42]}),
  flag('help', ['-h', '--help'], {desc: 'Print this help message and exit.'})
]

const deepThought = command('deepThought', opts, {desc: 'Ask the Ultimate Question.'})

The deepThought command has three command-line options:

  1. A required string positional argument named question.
  2. An answer number option specified with -a or --answer that should default to 42 if not given.
  3. A help command-line flag given by -h or --help.

You may use the shargs-opts module to get a nice DSL for describing our options. However, you could have also written them out as objects yourself or could have used a different DSL.

Read up on the details in the command-line options section.

const parser = parserSync({
  argv: [splitShortOpts],
  opts: [setDefaultValues, requireOpts, cast],
  args: [flagsAsBools]
})

Shargs gives you fine-grained control over how the options are parsed. By using the shargs-core and shargs-parser modules, we have build the following parser:

  1. splitShortOpts: Short option groups like -cvzf are transformed to -c -v -z -f.
  2. setDefaultValues: Options with default values that were not provided are set.
  3. requireOpts: It is verified that all required options have been given.
  4. cast: Strings are cast to other types, like numbers or booleans.
  5. flagsAsBools: Command-line flags are transformed to booleans.

Note that you did not tell parser how exactly to do those things. Everything is nice and declarative, and the details are hidden away in the parser stages.

The parserSync function and command-line parsers sections have all the details.

const docs = usage([synopsis, space, optsList, space, desc])

const style = {
  line: [{width: 80}],
  cols: [{width: 25}, {width: 55}]
}

You may use shargs-usage to automatically generate a usage documentation based on a command definition (e.g. deepThought from before). The module provides all components generally found in usage documentations, like:

  1. A synopsis, summarizing available options: e.g. deepThought (<question>) [-a|--answer] [-h|--help].
  2. An options list (optsList), describing option details in a tabular format.

Note that shargs-usage is declarative: You only specify what components our usage documentation should have. The details on how exactly those components transform command-line options into text is hidden away.

See the automatic usage documentation generation and style sections.

const argv = process.argv.slice(2)
const {errs, args} = parser(deepThought)(argv)

errs.forEach(err => console.log(err.msg))

const help = docs(deepThought)(style)
if (args.help) console.log(help)

The command-line option DSL, the parser DSL, and the usage documentation DSL combined give you a very flexible way to write command-line programs.

Find out more in the building command-line parsers with shargs section.

deepThought (<question>) [-a|--answer] [-h|--help]                              
                                                                                
<question>               Ask a question. [required]                             
-a, --answer=<number>    The answer. [default: 42]                              
-h, --help               Print this help message and exit.                      
                                                                                
Ask the Ultimate Question.                                                      

The automatic usage documentation generation and building command-line parsers with shargs sections have more.

Tutorials

Examples

Documentation

This documentation encompasses the following shargs modules:

  1. shargs-opts is documented in command-line options.
  2. shargs-core is documented in the parserSync function.
  3. shargs-parser is documented in command-line parsers.
  4. shargs-usage is documented in automatic usage documentation generation.
  5. shargs-repl is documented in building REPLs with shargs.

Command-line Options

Command-line options are the most important concept in shargs. They are the basis for its two main features: Command-line parsers and automatic usage documentation generation.

Shargs defines many different types of command-line options represented by objects with the following interfaces:

Since writing objects following these interfaces by hand can be tedious, shargs-opts gives you a simple type-based DSL for defining valid command-line options:

const {command, flag, number, subcommand} = require('shargs/opts')

const opts = [
  subcommand(askOpts)('ask', ['ask'], {required: true, desc: 'Ask a question.'}),
  number('answer', ['-a', '--answer'], {defaultValues: [42], desc: 'The answer.'}),
  flag('help', ['-h', '--help'], {desc: 'Print this help message and exit.'})
]

const deepThought = command('deepThought', opts, {
  desc: 'Deep Thought was created to come up with the Answer to ' +
        'The Ultimate Question of Life, the Universe, and Everything.'
})

In the example, using the type functions subcommand, number, flag, and command guarantees the generation of valid objects.

Type Functions

The following type functions are available:

The closely related variadic and variadicPos represent arrays with unknown lengths.

array returns the following object:

const array = types => (key, args, fields) => ({
  key, args, types, ...fields
})

arrayPos returns the following object:

const arrayPos = types => (key, fields) => ({
  key, types, ...fields
})

Note that the values are represented as strings and you may want to cast them. If you need more values representing 'true' (e.g. 't', 'yes') or 'false' (e.g. 'F', 'no'), have a look at broadenBools. If you want to treat a value as its reverse, see reverseBools. If you need flags instead of bools, have a look at the boolAsFlag and boolsAsFlags parser stages.

bool returns the following object:

const bool = (key, args, fields) => ({
  key, args, types: ['bool'], ...fields
})

boolPos returns the following object:

const boolPos = (key, fields) => ({
  key, types: ['bool'], ...fields
})

subcommand's and command's opts fields are arrays of command-line options used to parse their values. Subcommands may have their own command-specific parsers or are parsed by command's parser. command or subcommand values are either terminated by the end of the input or by --.

subcommand returns the following object:

const subcommand = opts => (key, args, fields) => ({
  key, args, opts, ...fields
})

command returns the following object:

const command = (key, opts, fields) => ({
  key, opts, ...fields
})

Shargs counts the number of times a flag occurs, so a flag may be amplified by repeating it. If you don't need counts and prefer numbers or boolean values, have a look at the flagAsBool, flagAsNumber, flagsAsBools and flagsAsNumbers parser stages. If you need the presence of a flag to imply negativity (e.g. --no-fun), see complement, reverse and reverseFlags.

flag returns the following object:

const flag = (key, args, fields) => ({
  key, args, types: [], ...fields
})

Numbers are represented as strings and you may want to cast them. If you need flags instead of numbers, have a look at the numberAsFlag and numbersAsFlags parser stages.

number returns the following object:

const number = (key, args, fields) => ({
  key, args, types: ['number'], ...fields
})

numberPos returns the following object:

const numberPos = (key, fields) => ({
  key, types: ['number'], ...fields
})

string returns the following object:

const string = (key, args, fields) => ({
  key, args, types: ['string'], ...fields
})

stringPos returns the following object:

const stringPos = (key, fields) => ({
  key, types: ['string'], ...fields
})

An opts array can have at most one variadic positional argument and no other positional arguments (*Pos) may be defined after it. The closely related array and arrayPos represent arrays with known lengths, while command and subcommand are variadicPos and variadic with opts fields. A variadic's or variadicPos' values are either terminated by the end of the input or by --.

variadic returns the following object:

const variadic = (key, args, fields) => ({
  key, args, ...fields
})

variadicPos returns the following object:

const variadicPos = (key, fields) => ({
  key, ...fields
})

You may write out command-line options by hand, or write your own DSLs for creating them, they are just JavaScript objects:

const askOpts = [
  {key: 'format', args: ['--format'], types: ['string'], only: ['json', 'xml'], defaultValues: ['json'],
   desc: 'Respond either with json or xml.'},
  {key: 'html', args: ['--no-html'], types: [], reverse: true, desc: 'Remove HTML tags.'},
  {key: 'help', args: ['-h', '--help'], types: [], desc: 'Print this help message and exit.'},
  {key: 'question', types: ['string'], required: true, desc: 'State your question.'}
]

Apart from key, args, types, opts, and values that we have already seen and that determine an option's type, command-line option objects may be given any other fields, that may be used to provide information to parser stages (e.g. defaultValues, only), or to provide descriptions for usage documentation generation (e.g. desc, descArg). If you write your own parser stages, you may also define your own fields.

Option Fields

The following fields are used by shargs-core, shargs-parser stages or shargs-usage functions:

Argument names have no restrictions and can be any string. E.g. '-h', '--help' could be used for a help flag or 'ask' could be used for a command. Positional arguments must not have an args field, as they are not given by argument, but by their position.

This information is used by the contradictOpts parser stage to report errors if incompatible options are used together. Note that contradicts is unidirectional and not transitive (e.g. if a contradicts b and b contradicts c, a does not contradict c, and thus a and c are compatible). Only two keys that each contradict the other key are mutually exclusive.

They are used by the setDefaultValues parser stage that sets the values field if no values are supplied. The defaultValues' type depends on the command-line option type: Subcommands takes the same array of options as opts. Flag options' values have to be a number. All other options take an array of values, that must have the same length as their types field.

More specifically, desc is used by desc, optsList, optsLists, optsDef, and optsDefs and their *With versions.

It is used by the optsList, optsLists, optsDef, and optsDefs usage functions and their *With versions. only, types, and key are other fields that change the argument value description. These fields are applied in the following order (highest priority first): descArg, only, types, and key. If descArg is an empty string, no argument value description is displayed.

It is used by the optsList, optsLists, optsDef, and optsDefs usage functions and their *With versions. If descDefault is an empty string, the default shield is hidden.

This information is used by the implyOpts parser stage to report errors if mandatory options are missing. Note that implies is unidirectional (e.g. if a implies b and a is present, b must be present as well, but if b is present, a does not have to be present) and transitive (e.g. if a implies b and b implies c, a also implies c, and thus if a is present, c must also be present). Only two keys that each imply the other key are mutually inclusive.

It is used by the parser function as a field name for the parsed values in the resulting args object. Most command-line options should have a unique key to avoid collisions with other options. However, if two different options describe the same result field, it may make sense to give them a shared key. See complement for an example. A key must not be named _. It is also used by the optsList, optsLists, optsDef, optsDefs, synopses, and synopsis usage functions and their *With versions to describe argument values (e.g. --format=<format>). descArg, only, and types are other fields that change the argument value description. These fields are applied in the following order (highest priority first): descArg, only, types, and key.

It is used by the restrictToOnly parser stage to validate user input. only may be used to implement enumerations. It is also used by the optsList, optsLists, optsDef, and optsDefs usage functions and their *With versions to describe argument values (e.g. --format=<json|xml>). descArg, types, and key are other fields that change the argument value description. These fields are applied in the following order (highest priority first): descArg, only, types, and key.

It is used by the requireOpts stage that reports an error if a required option does not have values. A positional argument (Pos) can only be required, if all previously defined positional arguments are required as well. The synopsis, synopses, optsList, optsLists, optsDef, and optsDefs usage functions and their With versions mark required options.

Flag options' types must be []. Primitive options' and primitive positional arguments' types must be _, and array options' and array positional arguments' types must be _, _, ..., where _ is the name of a type given as a string. Variadic options, variadic positional arguments, subcommand options, and command positional arguments must not have a types field. types is also used by the optsList, optsLists, optsDef, and optsDefs usage functions and their *With versions to describe argument values (e.g. --format=<bool> for a bool option). descArg, only, and key are other fields that change the argument value description. These fields are applied in the following order (highest priority first): descArg, only, types, and key.

The length of a values' array depends on the command-line option type: Flag options, primitive options, primitive positional arguments, and rest must each have values of length 1. Array options' and array positional arguments' values field must match their types in length. subcommand option's, command positional argument's, variadic option's, and variadic positional argument's values may have any number of entries.

Option Decorators

Certain changes to options are so frequent, that shargs-opts provides decorators for them. You may think of decorators as recurring patterns that are provided as functions.

shargs-opts provides the following decorators:

The complementary option has the same key as the original option, but reverses its value. If complement is used, you most probably want to also use the reverseBools or reverseFlags parser stage.

Example:

const {flag, complement} = require('shargs/opts')

const no = complement('--no-')

const html = flag('html', ['-H', '--html'], {defaultValues: ['false']})
const noHtml = no(html)

Is the same as:

const {flag} = require('shargs/opts')

const html = flag('html', ['-H', '--html'], {defaultValues: ['false']})
const noHtml = flag('html', ['--no-H', '--no-html'], {reverse: true})

Note the differences in defaultValues and reverse.

Example:

const {command, stringPos} = require('shargs/opts')

const opts = [stringPos('question')]
const deepThought = command('deepThought', opts)

const args = ['deepThought', 'D']
posArgToOpt(args)(deepThought)

Is the same as:

const {subcommand} = require('shargs/opts')

subcommand(opts)('deepThought', args)

Verify Commands

Shargs provides a function for verifying that commands have the correct structure:

const {verifyCommand} = require('shargs')

const {errs, opt} = verifyCommand(deepThought)

In the example, it would return a list of errs if deepThought was invalid. If the command is valid, the errs list is empty. verifyCommand is used internally by parserSync and parser, but may be used independently.

The parserSync Function

The parserSync function is shargs' core abstraction. It generates a command-line parser from a collection of parser stages and is usually used alongside shargs-parser:

const {parserSync} = require('shargs')
const {cast, flagsAsBools, requireOpts, restrictToOnly} = require('shargs/parser')
const {reverseFlags, setDefaultValues, splitShortOpts} = require('shargs/parser')

const stages = {
  argv: [splitShortOpts],
  opts: [setDefaultValues, requireOpts, reverseFlags, cast],
  args: [flagsAsBools]
}

const substages = {
  ask: [...stages.opts, restrictToOnly]
}

const parser = parserSync(stages, substages)

parserSync takes two parameters:

  1. A stages object that takes parser stages and defines what transformations should be applied in which order.
  2. An optional substages object that defines subcommand-specific opts parser stages.

parserSync has a twin function called parser that does the same, but works asynchronously.

stages

Shargs has seven different processing steps called stages that are applied in a predefined order and transform argument values (process.argv) via command-line options (opts) to arguments (args):

Transforms a value into command-line argument values syntax, e.g.

"-p commit -am 'First commit'"

could be transformed to

['-p', 'commit', '-am', 'First commit']

Several stages that modify command-line argument values, e.g.

['-p', 'commit', '-am', 'First commit']

could be transformed to

['-p', 'commit', '-a', '-m', 'First commit']

Transforms argument values into command-line options, e.g.

['-p', 'commit', '-a', '-m', 'First commit']

could be transformed to

[
  {key: 'paginate', args: ['-p'], types: [], values: [1]},
  {key: 'commit', args: ['commit'], opts: [...], values: [
    {key: 'all', args: ['-a'], types: [], values: [1]},
    {key: 'message', args: ['-m'], types: ['string'], values: ['First commit']},
    ...
  ]},
  ...
]

Several stages that modify command-line options, e.g.

[
  {key: 'paginate', args: ['-p'], types: [], values: [1]},
  {key: 'commit', args: ['commit'], opts: [...], values: [
    {key: 'all', args: ['-a'], types: [], values: [1]},
    {key: 'message', args: ['-m'], types: ['string'], values: ['First commit']},
    ...
  ]},
  ...
]

could be transformed to

[
  {key: 'paginate', args: ['-p'], types: [], values: [1]},
  {key: 'commit', args: ['commit'], opts: [...], values: [
    {key: 'all', args: ['-a'], types: ['bool'], values: ['true']},
    {key: 'message', args: ['-m'], types: ['string'], values: ['First commit']},
    ...
  ]},
  ...
]

Transforms command-line options into arguments object arrays, e.g.

[
  {key: 'paginate', args: ['-p'], types: [], values: [1]},
  {key: 'commit', args: ['commit'], opts: [...], values: [
    {key: 'all', args: ['-a'], types: ['bool'], values: ['true']},
    {key: 'message', args: ['-m'], types: ['string'], values: ['First commit']},
    ...
  ]},
  ...
]

could be transformed to

[
  {_: [], paginate: {type: 'flag', count: 1}},
  {commit: [
    {_: [], all: 'true', message: 'First commit'}
  ]}
]

Several stages that modify arguments object arrays, e.g.

[
  {_: [], paginate: {type: 'flag', count: 1}},
  {commit: [
    {_: [], all: 'true', message: 'First commit'}
  ]}
]

could be transformed to

[
  {_: [], paginate: {type: 'flag', count: 1}},
  {commit: {
    {_: [], all: true, message: 'First commit'}
  }}
]

Transforms argument object arrays into any result value:

[
  {_: [], paginate: {type: 'flag', count: 1}},
  {commit: [
    {_: [], all: true, message: 'First commit'}
  ]}
]

could be transformed to

{
  _: [],
  paginate: {type: 'flag', count: 1},
  commit: {
    _: [],
    all: true,
    message: 'First commit'
  }
}

The argv, opts, and args stages are the user-facing API to declare a parser's behavior.

The toOps and toArgs stages define the core behavior of parserSync (and parser) and shargs defines sensible defaults that should not have to be changed in most use cases. However, if you do have a use case that needs adjustments to those stages, you may carefully swap them out.

If you read the types from top to bottom, you get a good impression of how parserSync works.

substages

substages define custom opts stages for subcommands. That means, while most subcommands are parsed using the opts defined in stages, those whose key matches a key in the substages object are parsed using the opts defined under that key.

Keys may be deeply nested to account for subcommands of subcommands: E.g. if ask had a subcommand with the question key, {ask: {question: [...stages.opts, restrictToOnly]}} would assign custom opts to question.

The _ key is special in substages: It is a wildcard that is used by any subcommand that is not given explicitly by key. E.g. {ask: {_: [...stages.opts, restrictToOnly]}} and {_: {_: [...stages.opts, restrictToOnly]}} both work for question.

Async Parsers

The parserSync function has an asynchronous alternative called parser. It is used exactly like parserSync, but also works with stages returning JavaScript Promises and returns a Promise itself:

// stages, substages, deepThought, argv are taken from the Getting Started section

const {parser} = require('shargs')

const asyncParser = parser(stages, substages)
const parse = asyncParser(deepThought)
const {errs, args} = await parse(argv)

In addition to parserSync's parameters, parser's stages and substages parameters also take parser stages that return Promises:

Transforms a value into command-line argument values syntax, e.g.

"-p commit -am 'First commit'"

could be transformed to

['-p', 'commit', '-am', 'First commit']

Several stages that modify command-line argument values, e.g.

['-p', 'commit', '-am', 'First commit']

could be transformed to

['-p', 'commit', '-a', '-m', 'First commit']

Transforms argument values into command-line options, e.g.

['-p', 'commit', '-a', '-m', 'First commit']

could be transformed to

[
  {key: 'paginate', args: ['-p'], types: [], values: [1]},
  {key: 'commit', args: ['commit'], opts: [...], values: [
    {key: 'all', args: ['-a'], types: [], values: [1]},
    {key: 'message', args: ['-m'], types: ['string'], values: ['First commit']},
    ...
  ]},
  ...
]

Several stages that modify command-line options, e.g.

[
  {key: 'paginate', args: ['-p'], types: [], values: [1]},
  {key: 'commit', args: ['commit'], opts: [...], values: [
    {key: 'all', args: ['-a'], types: [], values: [1]},
    {key: 'message', args: ['-m'], types: ['string'], values: ['First commit']},
    ...
  ]},
  ...
]

could be transformed to

[
  {key: 'paginate', args: ['-p'], types: [], values: [1]},
  {key: 'commit', args: ['commit'], opts: [...], values: [
    {key: 'all', args: ['-a'], types: ['bool'], values: ['true']},
    {key: 'message', args: ['-m'], types: ['string'], values: ['First commit']},
    ...
  ]},
  ...
]

Transforms command-line options into arguments object arrays, e.g.

[
  {key: 'paginate', args: ['-p'], types: [], values: [1]},
  {key: 'commit', args: ['commit'], opts: [...], values: [
    {key: 'all', args: ['-a'], types: ['bool'], values: ['true']},
    {key: 'message', args: ['-m'], types: ['string'], values: ['First commit']},
    ...
  ]},
  ...
]

could be transformed to

[
  {_: [], paginate: {type: 'flag', count: 1}},
  {commit: [
    {_: [], all: 'true', message: 'First commit'}
  ]}
]

Several stages that modify arguments object arrays, e.g.

[
  {_: [], paginate: {type: 'flag', count: 1}},
  {commit: [
    {_: [], all: 'true', message: 'First commit'}
  ]}
]

could be transformed to

[
  {_: [], paginate: {type: 'flag', count: 1}},
  {commit: {
    {_: [], all: true, message: 'First commit'}
  }}
]

Transforms argument object arrays into any result value:

[
  {_: [], paginate: {type: 'flag', count: 1}},
  {commit: [
    {_: [], all: true, message: 'First commit'}
  ]}
]

could be transformed to

{
  _: [],
  paginate: {type: 'flag', count: 1},
  commit: {
    _: [],
    all: true,
    message: 'First commit'
  }
}

If you read the stages' field types from top to bottom, you get a good impression of what an asynchronous parser does. Internally, an asynchronous shargs parser really differs only in one major way from a synchronous parser: Instead of using function composition, it uses Promise.prototype.then to chain parser stages.

Advanced Parsers

Command-line Parsers

You do not have to write all parser stages yourself. The shargs-parser library offers a large collection of common parser stages, you can use.

The parser stages presented here are split into checks and stages. While checks only report errors, stages also transform their argv, opts, or args. Usually, it makes sense to declare checks before stages.

argv Checks

If rules is not a function, reports a WrongArgvRulesType error.

Example:

const {verifyArgv} = require('shargs/parser')

const rules = argv => (
  argv.some(_ => _ === '--question') &&
  argv.some(_ => _ === '--answer')
)

const argv = ['--answer', '42']

verifyArgv(rules)({argv})

Result:

{
  errs: [
    {
      code: 'FalseArgvRules',
      msg:  'Your argv rules returned false...',
      info: {...}
    }
  ]
}

argv Stages

It only removes the first =, so ['--question=1+2=3?'] is transformed into ['--question', '1+2=3?'].

Example:

const {equalsSignAsSpace} = require('shargs/parser')

const argv = ['--answer=42']

equalsSignAsSpace({argv})

Result:

{
  argv: ['--answer', '42']
}

Example:

const {shortOptsNoSpace} = require('shargs/parser')

const argv = ['-a42']

shortOptsNoSpace({argv})

Result:

{
  argv: ['-a', '42']
}

Example:

const {splitShortOpts} = require('shargs/parser')

const argv = ['-ha', '42']

splitShortOpts({argv})

Result:

{
  argv: ['-h', '-a', '42']
}

While p's signature is arg => true|false, f's signature must be (arg, index, argv) => ({errs = [], argv = []}). Many other argv checks and stages are defined in terms of traverseArgv and it is of great help for writing custom argv stages.

Example:

const {traverseArgv} = require('shargs/parser')

const argv = [
  '--answer=42',
  '--help'
]

const hasEqualsSign = arg => arg.indexOf('=') > -1

const replaceFirstEqualsSign = arg => ({
  argv: [
    arg.slice(0, arg.indexOf('=')),
    arg.slice(arg.indexOf('=') + 1)
  ]
})

traverseArgv(hasEqualsSign)(replaceFirstEqualsSign)({argv})

Result:

{
  argv: [
    '--answer', '42',
    '--help'
  ]
}

opts Checks

This is the case, if both, the option and an option from its contradicts list, have values. If contradicts is not a list, it reports a WrongContradictsType error.

Example:

const {contradictOpts} = require('shargs/parser')
const {number, string} = require('shargs/opts')

const opts = [
  number('age', ['-a'], {
    values: ['27']
  }),
  string('birthday', ['-b'], {
    contradicts: ['age'],
    values: ['27.7.1927']
  })
]

contradictOpts({opts})

Result:

{
  errs: [
    {
      code: 'ContradictionDetected',
      msg:  'Some given keys contradict each other.',
      info: {...}
    }
  ]
}

Example:

const {demandASubcommand} = require('shargs/parser')
const {flag, number, subcommand} = require('shargs/opts')

const opts = [
  subcommand([])('ask', ['ask'], {desc: 'Ask a question.'}),
  number('answer', ['-a', '--answer'], {
    values: ['42'],
    desc: 'The answer.'
  }),
  flag('help', ['-h', '--help'], {
    desc: 'Print this help message and exit.'
  })
]

demandASubcommand({opts})

Result:

{
  errs: [
    {
      code: 'SubcommandRequired',
      msg:  'No subcommand found. Please use at least one subcommand!',
      info: {...}
    }
  ]
}

This is the case, if the option has values, but an option from its implies list has not. If implies is not a list, it reports a WrongImpliesType error.

Example:

const {implyOpts} = require('shargs/parser')
const {number, string} = require('shargs/opts')

const opts = [
  number('answer', ['-a']),
  string('question', ['-q'], {
    implies: ['answer'],
    values: ['How much is the fish?']
  })
]

implyOpts({opts})

Result:

{
  errs: [
    {
      code: 'ImplicationViolated',
      msg:  'Some given keys that imply...',
      info: {...}
    }
  ]
}

If values is not an array, it reports a WrongFormatForRequiredOption error.

Example:

const {requireOpts} = require('shargs/parser')
const {string} = require('shargs/opts')

const opts = [
  string('question', ['--question'], {required: true})
]

requireOpts({opts})

Result:

{
  errs: [
    {
      code: 'RequiredOptionIsMissing',
      msg:  'A required option has not been provided.',
      info: {...}
    }
  ]
}

It checks all rest values, assuming they are in the rest category because of spelling mistakes. It collects all command-line options' args and computes a distance metric (currently Levenshtein distance) between each arg and each rest. It reports the results in a DidYouMean error, suggesting probable args replacements for spelling mistakes.

Example:

const {suggestOpts} = require('shargs/parser')
const {number} = require('shargs/opts')

const opts = [
  number('answer', ['-a', '--ans']),
  {values: ['--asn']}
]

suggestOpts({opts})

Result:

{
  errs: [
    {
      code: 'DidYouMean',
      msg:  'An unknown command-line argument...',
      info: {
        argv: '--asn',
        options: [
          [],
          [],
          [{'--ans': number('answer', ['-a', '--ans'])}],
          [{'-a': number('answer', ['-a', '--ans'])}]
        ]
      }
    }
  ]
}

The options array looks a little bit strange, so an explanation is in order. The array's index is the cost necessary to transform the unknown option in the arguments, represented as keys. Because of this, you can conveniently work with the results, e.g. by only using the most probable ones:

'Did you mean: ' + (
  options
  .slice(0, 3)
  .reduce((a, b) => a.concat(b))
  .flatMap(Object.keys)
  .join(', ')
)

Results in:

Did you mean: --age

If a positional argument is required, all previously defined positional arguments must be required, as well, and no other positional arguments can be defined after a variadicPos. In case of a violation of the second rule, validatePosArgs reports an InvalidVariadicPositionalArgument error.

Example:

const {validatePosArgs} = require('shargs/parser')
const {stringPos, variadicPos} = require('shargs/opts')

const opts = [
  stringPos('name1', {required: true, values: ['Arthur']}),
  stringPos('name2', {required: false, values: ['Ford']}),
  stringPos('name3', {required: true, values: ['Trillian']}),
  variadicPos('names', {values: ['Zaphod', 'Marvin']}),
  stringPos('name4', {values: ['Douglas']})
]

validatePosArgs({opts})

Resul

1.1.1

3 years ago

1.1.0

3 years ago

1.0.2

3 years ago

1.0.1

3 years ago

1.0.0

3 years ago

0.26.2

3 years ago

0.26.1

3 years ago

0.26.0

3 years ago

0.25.0

3 years ago

0.24.9

4 years ago

0.24.8

4 years ago

0.24.7

4 years ago

0.24.6

4 years ago

0.24.5

4 years ago

0.24.4

4 years ago

0.24.3

4 years ago

0.24.2

4 years ago

0.24.1

4 years ago

0.24.0

4 years ago

0.23.4

4 years ago

0.23.3

4 years ago

0.23.2

4 years ago

0.23.1

4 years ago

0.23.0

4 years ago

0.22.4

4 years ago

0.22.3

4 years ago

0.22.2

4 years ago

0.22.1

4 years ago

0.22.0

4 years ago

0.21.0

4 years ago

0.20.5

4 years ago

0.20.4

4 years ago

0.20.3

4 years ago

0.20.2

4 years ago

0.20.1

4 years ago

0.20.0

4 years ago

0.19.1

4 years ago

0.19.2

4 years ago

0.19.0

4 years ago

0.18.0

4 years ago

0.17.12

4 years ago

0.17.11

4 years ago

0.17.8

4 years ago

0.17.9

4 years ago

0.17.10

4 years ago

0.17.2

4 years ago

0.17.3

4 years ago

0.17.4

4 years ago

0.17.5

4 years ago

0.17.6

4 years ago

0.17.7

4 years ago

0.17.1

4 years ago

0.16.8

4 years ago

0.16.7

4 years ago

0.16.5

4 years ago

0.16.6

4 years ago

0.16.3

4 years ago

0.16.4

4 years ago

0.16.2

4 years ago

0.16.1

4 years ago

0.16.0

4 years ago

0.15.6

4 years ago

0.15.5

4 years ago

0.15.4

4 years ago

0.15.3

4 years ago

0.15.2

4 years ago

0.15.1

4 years ago

0.15.0

4 years ago

0.14.31

4 years ago

0.14.30

4 years ago

0.14.28

4 years ago

0.14.29

4 years ago

0.14.27

4 years ago

0.14.26

4 years ago

0.14.24

4 years ago

0.14.23

4 years ago

0.14.22

4 years ago

0.14.21

4 years ago

0.14.20

4 years ago

0.14.19

4 years ago

0.14.18

4 years ago

0.14.17

4 years ago

0.14.16

4 years ago

0.14.15

4 years ago

0.14.13

4 years ago

0.14.12

4 years ago

0.14.11

4 years ago

0.14.10

4 years ago

0.14.9

4 years ago

0.14.5

4 years ago

0.14.6

4 years ago

0.14.7

4 years ago

0.14.8

4 years ago

0.14.4

4 years ago

0.14.1

4 years ago

0.14.2

4 years ago

0.14.3

4 years ago

0.14.0

4 years ago

0.13.15

4 years ago

0.13.14

4 years ago

0.13.13

4 years ago

0.13.12

4 years ago

0.13.7

4 years ago

0.13.8

4 years ago

0.13.9

4 years ago

0.13.10

4 years ago

0.13.6

4 years ago

0.13.5

4 years ago

0.13.4

4 years ago

0.13.3

4 years ago

0.13.0

4 years ago

0.13.1

4 years ago

0.13.2

4 years ago

0.12.16

4 years ago

0.12.25

4 years ago

0.12.26

4 years ago

0.12.24

4 years ago

0.12.23

4 years ago

0.12.22

4 years ago

0.12.21

4 years ago

0.12.20

4 years ago

0.12.19

4 years ago

0.12.17

4 years ago

0.12.18

4 years ago

0.12.15

4 years ago

0.12.14

4 years ago

0.12.13

4 years ago

0.12.12

4 years ago

0.12.10

4 years ago

0.12.11

4 years ago

0.12.7

4 years ago

0.12.8

4 years ago

0.12.9

4 years ago

0.12.5

4 years ago

0.12.6

4 years ago

0.12.4

4 years ago

0.12.3

4 years ago

0.12.1

4 years ago

0.12.2

4 years ago

0.12.0

4 years ago

0.11.5

4 years ago

0.11.4

4 years ago

0.11.3

4 years ago

0.11.2

4 years ago

0.11.1

4 years ago

0.11.0

4 years ago

0.10.12

4 years ago

0.10.11

4 years ago

0.10.10

4 years ago

0.10.9

4 years ago

0.10.8

4 years ago

0.10.5

4 years ago

0.10.6

4 years ago

0.10.7

4 years ago

0.10.4

4 years ago

0.10.3

4 years ago

0.10.2

4 years ago

0.10.1

4 years ago

0.10.0

4 years ago

0.9.2

4 years ago

0.9.1

4 years ago

0.8.0

4 years ago

0.7.0

4 years ago

0.6.0

4 years ago