https://github.com/Yord/shargs
🦈 shargs is a combinator library for building command-line argument parsers.
https://github.com/Yord/shargs
command-line parser shargs
Last synced: about 1 year ago
JSON representation
🦈 shargs is a combinator library for building command-line argument parsers.
- Host: GitHub
- URL: https://github.com/Yord/shargs
- Owner: Yord
- License: mit
- Created: 2020-01-14T07:53:31.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2021-01-31T21:22:22.000Z (over 5 years ago)
- Last Synced: 2025-03-13T09:51:25.330Z (over 1 year ago)
- Topics: command-line, parser, shargs
- Language: JavaScript
- Homepage:
- Size: 3.7 MB
- Stars: 86
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
🦈 shargs (**sh**ell **args**) is a library for building command-line argument parsers.
[![node version][shield-node]][node]
[![npm version][shield-npm]][npm-package]
[![license][shield-license]][license]
[![PRs Welcome][shield-prs]][contribute]
[![linux unit tests status][shield-unit-tests-linux]][actions]
[![macos unit tests status][shield-unit-tests-macos]][actions]
[![windows unit tests status][shield-unit-tests-windows]][actions]
## Features
+ Compose functions to build [highly customizable](#command-line-parsers) command-line argument [parsers](#the-parsersync-function).
+ 35+ opt-in features, e.g. ([multiple](#multiple-subcommands)) [subcommands](#subcommand),
[spelling mistake detection](#suggestOpts), [default values](#setDefaultValues),
and ([best guess](#bestGuessCast)) [casting](#cast).
+ [Synchronous](#the-parsersync-function) and Promise-based [asynchronous](#async-parsers) modes
with async/await support.
+ [Automatic usage documentation generation](#automatic-usage-documentation-generation) with fine-grained control over
[layouts](#automatic-usage-documentation-generation) and [styles](#style).
+ Easily extensible with your own [custom parser stages](#custom-checks-and-stages)
and [custom usage layouts](#custom-usage-functions).
+ [Extensively documented](#documentation) and very well tested (800+ unit and integration tests).
+ [Modular library layout](#installation) with zero runtime dependencies.
## Installation
Install as a bundle (recommended):
npm install --save shargs
Install as modules:
npm install --save shargs-core # core functions like parserSync (in bundle: shargs/core or shargs)
npm install --save shargs-opts # a DSL for command-line options (in bundle: shargs/opts)
npm install --save shargs-parser # collection of parser functions (in bundle: shargs/parser)
npm install --save shargs-usage # collection of usage functions (in bundle: shargs/usage)
npm install --save shargs-repl # build REPLs powered by shargs (not in bundle)
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](#installing-as-bundle-or-modules) for more details.
## Getting Started
Describe your command and its options:
```js
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](#command-line-options) section.
Declare your own command-line parser:
```js
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](#the-parserSync-function)
and [command-line parsers](#command-line-parsers) sections have all the details.
Layout a usage documentation:
```js
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 () [-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](#automatic-usage-documentation-generation)
and [style](#style) sections.
Use the parser and the usage documentation in your program:
```js
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](#building-command-line-parsers-with-shargs) section.
Run your command with node ./deepThought --help:
```bash
deepThought () [-a|--answer] [-h|--help]
Ask a question. [required]
-a, --answer= The answer. [default: 42]
-h, --help Print this help message and exit.
Ask the Ultimate Question.
```
The [automatic usage documentation generation](#automatic-usage-documentation-generation)
and [building command-line parsers with shargs](#building-command-line-parsers-with-shargs) sections have more.
### Tutorials
+ [Beginners: Implementing a `git`-like interface.][shargs-tutorial-git]
### Examples
+ [An asynchronous version of deepThought.][shargs-example-async-deepthought]
+ [A synchronous version of deepThought.][shargs-example-sync-deepthought]
+ [deepThought with three layers of configuration: A config file, environment variables, and command-line arguments.][shargs-example-sync-deepthought-config-env-argv]
+ [A command-line arguments SQL parser.][shargs-example-sync-sql]
+ [A REPL (Real Eval Print Loop) build with `shargs-repl`.][shargs-example-repl]
## Documentation
This documentation encompasses the following shargs modules:
1. [`shargs-opts`][shargs-opts] is documented in [command-line options](#command-line-options).
2. [`shargs-core`][shargs-core] is documented in [the `parserSync` function](#the-parserSync-function).
3. [`shargs-parser`][shargs-parser] is documented in [command-line parsers](#command-line-parsers).
4. [`shargs-usage`][shargs-usage] is documented in [automatic usage documentation generation](#automatic-usage-documentation-generation).
5. [`shargs-repl`][shargs-repl] is documented in [building REPLs with shargs](#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](#command-line-parsers)
and [automatic usage documentation generation](#automatic-usage-documentation-generation).
Shargs defines many different types of command-line options represented by objects with the following interfaces:
Type
Interface
Description
Flag Option
{key, args, types: []}
A present or absent value.
Primitive Option
{key, args, types: [_]}
A unary value given by argument.
Array Option
{key, args, types: [_, _, ...]}
An array of length n given by argument.
Variadic Option
{key, args}
A variable length array given by argument.
Subcommand Option
{key, args, opts}
An option group given by argument.
Primitive Positional Argument
{key, types: [_]}
A unary value given by position.
Array Positional Argument
{key, types: [_, _, ...]}
An array of length n given by position.
Variadic Positional Argument
{key}
A variable length array given by position.
Command Positional Argument
{key, opts}
An option group given by position.
Rest
{values}
An argument value of unknown type.
Since writing objects following these interfaces by hand can be tedious,
[`shargs-opts`][shargs-opts] gives you a simple type-based DSL for defining valid command-line options:
```js
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`](#subcommand), [`number`](#number), [`flag`](#flag),
and [`command`](#command) guarantees the generation of valid objects.
#### Type Functions
The following type functions are available:
Type Function
Description
array(types)(key, args, fields)
arrayPos(types)(key, fields)
array generates an array option,
while arrayPos generates an array positional argument,
representing arrays whose length is known in advance.
The closely related variadic
and variadicPos represent arrays with unknown lengths.
`array` returns the following object:
```js
const array = types => (key, args, fields) => ({
key, args, types, ...fields
})
```
`arrayPos` returns the following object:
```js
const arrayPos = types => (key, fields) => ({
key, types, ...fields
})
```
bool(key, args, fields)
boolPos(key, fields)
bool generates a primitive option,
while boolPos generates a primitive positional argument,
representing the boolean values 'true' and 'false'.
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:
```js
const bool = (key, args, fields) => ({
key, args, types: ['bool'], ...fields
})
```
`boolPos` returns the following object:
```js
const boolPos = (key, fields) => ({
key, types: ['bool'], ...fields
})
```
subcommand(opts)(key, args, fields)
command(key, opts, fields)
subcommand generates a subcommand option,
while command generates a command positional argument.
Combined, they enable commands to do multiple things like git init, git commit, and git push.
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:
```js
const subcommand = opts => (key, args, fields) => ({
key, args, opts, ...fields
})
```
`command` returns the following object:
```js
const command = (key, opts, fields) => ({
key, opts, ...fields
})
```
flag(key, args, fields)
flag generates a flag option,
representing command-line options that take no value.
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:
```js
const flag = (key, args, fields) => ({
key, args, types: [], ...fields
})
```
number(key, args, fields)
numberPos(key, fields)
number generates a primitive option,
while numberPos generates a primitive positional argument,
representing JavaScript numbers.
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:
```js
const number = (key, args, fields) => ({
key, args, types: ['number'], ...fields
})
```
`numberPos` returns the following object:
```js
const numberPos = (key, fields) => ({
key, types: ['number'], ...fields
})
```
string(key, args, fields)
stringPos(key, fields)
string generates a primitive option,
while stringPos generates a primitive positional argument,
representing strings.
`string` returns the following object:
```js
const string = (key, args, fields) => ({
key, args, types: ['string'], ...fields
})
```
`stringPos` returns the following object:
```js
const stringPos = (key, fields) => ({
key, types: ['string'], ...fields
})
```
variadic(key, args, fields)
variadicPos(key, fields)
variadic generates a variadic option,
while variadicPos generates a variadic positional argument.
These types represent arrays whose length is not known in advance.
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:
```js
const variadic = (key, args, fields) => ({
key, args, ...fields
})
```
`variadicPos` returns the following object:
```js
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:
```js
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`](#key), [`args`](#args), [`types`](#types), [`opts`](#opts), and [`values`](#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`](#defaultValues), [`only`](#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-core], [`shargs-parser`][shargs-parser] stages
or [`shargs-usage`][shargs-usage] functions:
Field
Type
Description
args
string[]
args defines argument names for command-line options (e.g. ['-h', '--help']).
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.
contradicts defines what keys an option is incompatible with.
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.
defaultValues defines default values for command-line options.
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.
desc
string
desc defines an option description used by various usage functions.
More specifically, desc is used by
desc, optsList,
optsLists, optsDef,
and optsDefs and their *With versions.
descArg
string
descArg defines a description for an argument value
(e.g. {descArg: 'format'} would print --format=<format>
instead of --format=<string>).
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.
descDefault
string
descDefault overrides the default shield (e.g. [default: 42]) displayed in several usage commands.
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.
implies defines what keys an option must be defined with.
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.
key
string
key defines the name of a command-line option.
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.
only
any[]
only defines valid values of an option.
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.
opts defines the command-line options of commands
and subcommands.
required
boolean
required defines whether a command-line option has to be present or not.
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.
reverse
boolean
reverse defines whether the values of a given option should be reversed by
the reverseBools or reverseFlags
parser stages.
types
string[]
types defines what user input a command-line option takes.
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.
values
any[]
This field should only be set by parser stages and never manually.
values are assigned by the parser.
You may want to use defaultValues.
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`][shargs-opts] provides decorators for them.
You may think of decorators as recurring patterns that are provided as functions.
[`shargs-opts`][shargs-opts] provides the following decorators:
Decorator
Description
complement(prefix)(opt)
complement transforms a bool or flag
option into a complementary option prefixed with a given string
(e.g. --no-html if used on --html).
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:
```js
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:
```js
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`.
posArgToOpt(args)(opt)
posArgToOpt transforms a positional argument into an option
by adding args.
Example:
```js
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:
```js
const {subcommand} = require('shargs/opts')
subcommand(opts)('deepThought', args)
```
#### Verify Commands
Shargs provides a function for verifying that commands have the correct structure:
```js
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`][shargs]' core abstraction.
It generates a command-line parser from a collection of parser stages
and is usually used alongside [`shargs-parser`][shargs-parser]:
```js
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`](#stages) object that takes [parser stages](#command-line-parsers)
and defines what transformations should be applied in which order.
2. An optional [`substages`](#substages) object that defines subcommand-specific `opts` parser stages.
`parserSync` has a twin function called [`parser`](#async-parsers) 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`):
Stage
Field
Type
1
toArgv
any => {errs, argv}
Transforms a value into command-line argument values syntax, e.g.
```js
"-p commit -am 'First commit'"
```
could be transformed to
```js
['-p', 'commit', '-am', 'First commit']
```
2
argv
Array<{errs, argv} => {errs, argv}>
Several stages that modify command-line argument values, e.g.
```js
['-p', 'commit', '-am', 'First commit']
```
could be transformed to
```js
['-p', 'commit', '-a', '-m', 'First commit']
```
3
toOpts
command => {errs, argv} => {errs, opts}
Transforms argument values into command-line options, e.g.
```js
['-p', 'commit', '-a', '-m', 'First commit']
```
could be transformed to
```js
[
{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']},
...
]},
...
]
```
4
opts
Array<{errs, opts} => {errs, opts}>
Several stages that modify command-line options, e.g.
```js
[
{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
```js
[
{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']},
...
]},
...
]
```
5
toArgs
{errs, opts} => {errs, args}
Transforms command-line options into arguments object arrays, e.g.
```js
[
{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
```js
[
{_: [], paginate: {type: 'flag', count: 1}},
{commit: [
{_: [], all: 'true', message: 'First commit'}
]}
]
```
6
args
Array<{errs, args} => {errs, args}>
Several stages that modify arguments object arrays, e.g.
```js
[
{_: [], paginate: {type: 'flag', count: 1}},
{commit: [
{_: [], all: 'true', message: 'First commit'}
]}
]
```
could be transformed to
```js
[
{_: [], paginate: {type: 'flag', count: 1}},
{commit: {
{_: [], all: true, message: 'First commit'}
}}
]
```
7
fromArgs
{errs, args} => any
Transforms argument object arrays into any result value:
```js
[
{_: [], paginate: {type: 'flag', count: 1}},
{commit: [
{_: [], all: true, message: 'First commit'}
]}
]
```
could be transformed to
```js
{
_: [],
paginate: {type: 'flag', count: 1},
commit: {
_: [],
all: true,
message: 'First commit'
}
}
```
The [`argv`](#argv-field), [`opts`](#opts-field), and [`args`](#args-field) stages
are the user-facing API to declare a parser's behavior.
The [`toOps`](#toOpts-field) and [`toArgs`](#toArgs-field) stages
define the core behavior of [`parserSync`](#the-parserSync-function) (and [`parser`](#async-parsers))
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`](#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 [`subcommand`](#subcommand)s of [`subcommand`](#subcommand)s:
E.g. if `ask` had a subcommand with the `question` [`key`](#key), `{ask: {question: [...stages.opts, restrictToOnly]}}` would assign custom `opts` to `question`.
The `_` [`key`](#key) is special in `substages`:
It is a wildcard that is used by any [`subcommand`](#subcommand) that is not given explicitly by [`key`](#key).
E.g. `{ask: {_: [...stages.opts, restrictToOnly]}}` and `{_: {_: [...stages.opts, restrictToOnly]}}` both work for `question`.
#### Async Parsers
The [`parserSync`](#the-parsersync-function) function has an asynchronous alternative called `parser`.
It is used exactly like `parserSync`, but also works with stages returning
[JavaScript Promises](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)
and returns a Promise itself:
```js
// 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`](#stages) and [`substages`](#substages) parameters also take parser stages that return Promises:
Stage
Field
Type
1
toArgv
any => {errs, argv}
any => Promise<{errs, argv}>
Transforms a value into command-line argument values syntax, e.g.
```js
"-p commit -am 'First commit'"
```
could be transformed to
```js
['-p', 'commit', '-am', 'First commit']
```
2
argv
Array<{errs, argv} => {errs, argv}>
Array<{errs, argv} => Promise<{errs, argv}>>
Several stages that modify command-line argument values, e.g.
```js
['-p', 'commit', '-am', 'First commit']
```
could be transformed to
```js
['-p', 'commit', '-a', '-m', 'First commit']
```
3
toOpts
command => {errs, argv} => {errs, opts}
command => {errs, argv} => Promise<{errs, opts}>
Transforms argument values into command-line options, e.g.
```js
['-p', 'commit', '-a', '-m', 'First commit']
```
could be transformed to
```js
[
{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']},
...
]},
...
]
```
4
opts
Array<{errs, opts} => {errs, opts}>
Array<{errs, opts} => Promise<{errs, opts}>>
Several stages that modify command-line options, e.g.
```js
[
{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
```js
[
{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']},
...
]},
...
]
```
5
toArgs
{errs, opts} => {errs, args}
{errs, opts} => Promise<{errs, args}>
Transforms command-line options into arguments object arrays, e.g.
```js
[
{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
```js
[
{_: [], paginate: {type: 'flag', count: 1}},
{commit: [
{_: [], all: 'true', message: 'First commit'}
]}
]
```
6
args
Array<{errs, args} => {errs, args}>
Array<{errs, args} => Promise<{errs, args}>>
Several stages that modify arguments object arrays, e.g.
```js
[
{_: [], paginate: {type: 'flag', count: 1}},
{commit: [
{_: [], all: 'true', message: 'First commit'}
]}
]
```
could be transformed to
```js
[
{_: [], paginate: {type: 'flag', count: 1}},
{commit: {
{_: [], all: true, message: 'First commit'}
}}
]
```
7
fromArgs
{errs, args} => any
{errs, args} => Promise<any>
Transforms argument object arrays into any result value:
```js
[
{_: [], paginate: {type: 'flag', count: 1}},
{commit: [
{_: [], all: true, message: 'First commit'}
]}
]
```
could be transformed to
```js
{
_: [],
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][then] to chain parser stages.
#### Advanced Parsers
+ [Multiple subcommands](#multiple-subcommands)
### Command-line Parsers
You do not have to write all parser stages yourself.
The [`shargs-parser`][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
Description
verifyArgv(rules)
Reports a FalseArgvRules error
if the passed rules predicate returns false for an argument value.
If `rules` is not a function, reports a [`WrongArgvRulesType`](#WrongArgvRulesType) error.
Example:
```js
const {verifyArgv} = require('shargs/parser')
const rules = argv => (
argv.some(_ => _ === '--question') &&
argv.some(_ => _ === '--answer')
)
const argv = ['--answer', '42']
verifyArgv(rules)({argv})
```
Result:
```js
{
errs: [
{
code: 'FalseArgvRules',
msg: 'Your argv rules returned false...',
info: {...}
}
]
}
```
#### `argv` Stages
Description
Allows arguments of the form --answer=42 to be interpreted like --answer 42.
It only removes the first `=`,
so `['--question=1+2=3?']` is transformed into `['--question', '1+2=3?']`.
Example:
```js
const {equalsSignAsSpace} = require('shargs/parser')
const argv = ['--answer=42']
equalsSignAsSpace({argv})
```
Result:
```js
{
argv: ['--answer', '42']
}
```
Allows to omit whitespaces between short arguments and their values.
Passing -a42 would be the same as passing -a 42.
Cannot be used together with splitShortOpts.
Example:
```js
const {shortOptsNoSpace} = require('shargs/parser')
const argv = ['-a42']
shortOptsNoSpace({argv})
```
Result:
```js
{
argv: ['-a', '42']
}
```
Allows using short option groups.
The group -xvzf would be interpreted as -x -v -z -f.
Cannot be used together with shortOptsNoSpace.
Example:
```js
const {splitShortOpts} = require('shargs/parser')
const argv = ['-ha', '42']
splitShortOpts({argv})
```
Result:
```js
{
argv: ['-h', '-a', '42']
}
```
traverseArgv(p)(f)
Transforms arguments by applying a function f to each argument satisfying a predicate p.
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:
```js
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:
```js
{
argv: [
'--answer', '42',
'--help'
]
}
```
#### `opts` Checks
Description
Reports a ContradictionDetected error if options with a contradicts list violate their constraints.
This is the case, if both, the option and an option from its [`contradicts`](#contradicts) list, have [`values`](#values).
If [`contradicts`](#contradicts) is not a list, it reports a [`WrongContradictsType`](#WrongContradictsType) error.
Example:
```js
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:
```js
{
errs: [
{
code: 'ContradictionDetected',
msg: 'Some given keys contradict each other.',
info: {...}
}
]
}
```
Reports a SubcommandRequired
unless at least one subcommand has values.
Example:
```js
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:
```js
{
errs: [
{
code: 'SubcommandRequired',
msg: 'No subcommand found. Please use at least one subcommand!',
info: {...}
}
]
}
```
Reports an ImplicationViolated error
if options with an implies list violate their constraints.
This is the case, if the option has [`values`](#values), but an option from its [`implies`](#implies) list has not.
If [`implies`](#implies) is not a list, it reports a [`WrongImpliesType`](#WrongImpliesType) error.
Example:
```js
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:
```js
{
errs: [
{
code: 'ImplicationViolated',
msg: 'Some given keys that imply...',
info: {...}
}
]
}
```
Reports a RequiredOptionMissing error
if an option whose required field is true is missing.
If [`values`](#values) is not an array,
it reports a [`WrongFormatForRequiredOption`](#WrongFormatForRequiredOption) error.
Example:
```js
const {requireOpts} = require('shargs/parser')
const {string} = require('shargs/opts')
const opts = [
string('question', ['--question'], {required: true})
]
requireOpts({opts})
```
Result:
```js
{
errs: [
{
code: 'RequiredOptionIsMissing',
msg: 'A required option has not been provided.',
info: {...}
}
]
}
```
Corrects spelling mistakes by suggesting existing command-line arguments for all unknown provided arguments.
E.g. if --asnwer was provided, the --answer argument would be suggested.
It checks all [rest](#rest) [`values`](#values),
assuming they are in the [rest](#rest) category because of spelling mistakes.
It collects all command-line options' [`args`](#args)
and computes a distance metric (currently Levenshtein distance) between each arg and each [`rest`](#rest).
It reports the results in a [`DidYouMean`](#DidYouMean) error,
suggesting probable [`args`](#args) replacements for spelling mistakes.
Example:
```js
const {suggestOpts} = require('shargs/parser')
const {number} = require('shargs/opts')
const opts = [
number('answer', ['-a', '--ans']),
{values: ['--asn']}
]
suggestOpts({opts})
```
Result:
```js
{
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:
```js
'Did you mean: ' + (
options
.slice(0, 3)
.reduce((a, b) => a.concat(b))
.flatMap(Object.keys)
.join(', ')
)
```
Results in:
```bash
Did you mean: --age
```
Reports an InvalidRequiredPositionalArgument error
if defined positional arguments (*Pos) violate their rules for the
required field
or the position of variadicPos.
If a positional argument is [`required`](#required),
all previously defined positional arguments must be [`required`](#required), as well,
and no other positional arguments can be defined after a [`variadicPos`](#variadicPos).
In case of a violation of the second rule, `validatePosArgs` reports an
[`InvalidVariadicPositionalArgument`](#InvalidVariadicPositionalArgument) error.
Example:
```js
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})
```
Result:
```js
{
errs: [
{
code: 'InvalidRequiredPositionalArgument',
msg: 'If a positional argument is required, all prev...',
info: {...}
},
{
code: 'InvalidVariadicPositionalArgument',
msg: 'Only the last positional argument may be variadic.',
info: {...}
}
]
}
```
verifyOpts(rules)
Reports a FalseOptsRules error
if the opts array does not adhere to the rules predicate.
rules must have the following function signature: opt => true|false.
If `rules` is not a function, `verifyOpts` reports a [`WrongOptsRulesType`](#WrongOptsRulesType) error.
Example:
```js
const {verifyOpts} = require('shargs/parser')
const {string} = require('shargs/opts')
const implies = (p, q) => !p || q
const rules = opts => implies(
opts.some(_ => _.key === 'question' && _.values),
opts.some(_ => _.key === 'answer' && _.values)
)
const opts = [
string('question', ['--question'], {
values: ['How much is the fish?']
}),
number('answer', ['-a'])
]
verifyOpts(rules)({opts})
```
Result:
```js
{
errs: [
{
code: 'FalseOptsRules',
msg: 'Your opts rules returned false...',
info: {...}
}
]
}
```
Reports an error if an option's
values do not fit its types.
See the [`values`](#values) documentations for the exact rules.
If the lengths of [`values`](#values) and [`types`](#types) do not match,
an [`InvalidArity`](#InvalidArity) error is reported.
If the [`types`](#types) field has an invalid value, an [`InvalidTypes`](#InvalidTypes) error is reported
and `verifyValuesArity` reports an [`InvalidValues`](#InvalidValues) error in case of invalid [`values`](#values).
Example:
```js
const {verifyValuesArity} = require('shargs/parser')
const {number} = require('shargs/opts')
const opts = [
number('answer', ['--answer'], {values: ['42', '23']})
]
verifyValuesArity({opts})
```
Result:
```js
{
errs: [
{
code: 'InvalidArity',
msg: "An option's types arity does not match...",
info: {...}
}
]
}
```
#### `opts` Stages
Description
Collects all repeated keys in an array,
instead of keeping only the first mention of a key.
Example:
```js
const {arrayOnRepeat} = require('shargs/parser')
const {number, string} = require('shargs/opts')
const opts = [
string('answer', ['-a'], {values: ['42']}),
number('answer', ['-a'], {values: [42]})
]
arrayOnRepeat({opts})
```
Result:
```js
{
opts: [
array(['string', 'number'])('answer', ['-a'], {
values: ['42', 42]
})
]
}
```
Takes a best guess approach to transform rest values that did not match a command-line option
into new command-line options.
E.g. {values: ['--version']} becomes {key: 'version', types: [], values: [1]} and
[{values: ['--not']}, {values: ['panic']}]
becomes {key: 'not', types: ['string'], args: ['--not'], values: ['panic']}.
Single [`rest`](#rest) options are interpreted as [`flag`](#flag)s
while two consecutive [`rest`](#rest) options are interpreted as [`string`](#string)s
if the first [`rest`](#rest) is in short option format
(one minus with a single character, e.g. `-n`, `-a`)
or in long option format (two minuses with any more characters, e.g. `--name`, `--answer`).
[`bestGuessArgs`](#bestGuessArgs) is very similar to `bestGuessOpts`,
but also considers non-consecutive rest [`values`](#values).
Example:
```js
const {bestGuessOpts} = require('shargs/parser')
const {flag, string} = require('shargs/opts')
const opts = [
string('age', ['--age'], {values: ['unknown']}),
{values: ['--paranoid']},
{values: ['--name']},
{values: ['Marvin']},
{values: ['foo']}
]
bestGuessOpts({opts})
```
Result:
```js
{
opts: [
string('age', ['--age'], {values: ['unknown']}),
flag('paranoid', [], {values: [1]}),
string('name', [], {values: ['Marvin']}),
{values: ['foo']}
]
}
```
broadenBools(alt)
Transforms bools with
values like 'yes' or 'no' into
bools with 'true' or 'false'
values based on an alt mapping
(e.g. {true: ['yes'], false: ['no']}).
Example:
```js
const {broadenBools} = require('shargs/parser')
const {bool, number} = require('shargs/opts')
const opts = [
number('answer', ['-a', '--answer'], {values: ['42']}),
bool('verbose', ['--verbose'], {values: ['no']})
]
const alt = {
true: ['yes'],
false: ['no', 'f']
}
broadenBools(alt)({opts})
```
Result:
```js
{
opts: [
number('answer', ['-a', '--answer'], {values: ['42']}),
bool('verbose', ['--verbose'], {values: ['false']})
]
}
```
Casts string values
into other JavaScript types (e.g. numbers, booleans)
according to the command-line options' types
(e.g. {key: 'answer', types: ['number'], values: ['42']} is transformed to
{key: 'answer', types: ['number'], values: [42]}).
If [`types`](#types) contains `'number'`, but [`values`](#values)
cannot be cast into a number, an [`ArgumentIsNotANumber`](#ArgumentIsNotANumber) error is reported.
If [`types`](#types) contains `'bool'`, but [`values`](#values)
is not `['true']` or `['false']`, an [`ArgumentIsNotABool`](#ArgumentIsNotABool) error is reported.
Example:
```js
const {cast} = require('shargs/parser')
const {bool, number} = require('shargs/opts')
const opts = [
number('answer', ['-a', '--answer'], {values: ['42']}),
bool('verbose', ['--verbose'], {defaultValues: ['false']})
]
cast({opts})
```
Result:
```js
{
opts: [
number('answer', ['-a', '--answer'], {values: [42]}),
bool('verbose', ['--verbose'], {defaultValues: [false]})
]
}
```
Validates all command-line options with both, only
and values fields,
by making sure that all values in values
are also contained in only.
If values are not found in [`only`](#only),
a [`ValueRestrictionsViolated`](#ValueRestrictionsViolated) error is reported for each value.
Example:
```js
const {restrictToOnly} = require('shargs/parser')
const {number} = require('shargs/opts')
const opts = [
number('answer', ['--answer'], {only: ['42'], values: ['23']})
]
restrictToOnly({opts})
```
Result:
```js
{
errs: [
{
code: 'ValueRestrictionViolated',
msg: 'A value lies outside the allowed values...',
info: {...}
}
],
opts
}
```
Transforms
values of
primitive options and
array options
whose types contain 'bool' and whose
reverse field is true
by replacing 'true'/true with 'false'/false and vice versa.
Example:
```js
const {reverseBools} = require('shargs/parser')
const {bool} = require('shargs/opts')
const opts = [
bool('verbose', ['-v'], {reverse: true, values: [true]}),
bool('verbose', ['-v'], {reverse: true, values: ['true']})
]
reverseBools({opts})
```
Result:
```js
{
opts: [
bool('verbose', ['-v'], {reverse: true, values: [false]}),
bool('verbose', ['-v'], {reverse: true, values: ['false']})
]
}
```
Transforms
values of
flag options whose reverse field is true
by inverting the flag's value (e.g. 1 becomes -1).
Example:
```js
const {reverseFlags} = require('shargs/parser')
const {flag} = require('shargs/opts')
const opts = [
flag('help', ['-h'], {reverse: true, values: [1]})
]
reverseFlags({opts})
```
Result:
```js
{
opts: [
flag('help', ['-h'], {reverse: true, values: [-1]})
]
}
```
Transforms all options that have no
values, but defaultValues,
by setting the values field
to the defaultValues' value.
Example:
```js
const opts = [
flag(['-f'], {defaultValues: [1]}),
bool(['-b'], {defaultValues: ['true']})
]
setDefaultValues({opts})
```
Result:
```js
{
opts: [
flag(['-f'], {values: [1]}),
bool(['-b'], {values: ['true']})
]
}
```
traverseOpts(p)(f)
Transforms opts by applying a function f
to each option satisfying a predicate p.
While `p`'s signature is `opt => true|false`,
`f`'s signature must be `(opt, index, opts) => ({errs = [], opts = []})`.
Many other `opts` checks and stages are defined in terms of `traverseOpts`
and it is of great help for writing custom `opts` stages.
Example:
```js
const {traverseOpts} = require('shargs/parser')
const {flag, number} = require('shargs/opts')
const opts = [
number('answer', ['-a'], {values: ['42']}),
flag('verbose', ['-v'], {values: [1]}),
flag('help', ['-h'], {values: [1]})
]
const isFlag = _ => Array.isArray(_.types) && _.types.length === 0
const reverseFlags = opt => ({
opts: [
{...opt, values: [-opt.values[0]]}
]
})
traverseOpts(isFlag)(reverseFlags)({opts})
```
Result:
```js
{
opts: [
number('answer', ['-a'], {values: ['42']}),
flag('verbose', ['-v'], {values: [-1]}),
flag('help', ['-h'], {values: [-1]})
]
}
```
#### `args` Checks
Description
Reports an UnexpectedArgument error
for each value in the rest field _.
Example:
```js
const {failRest} = require('shargs/parser')
const args = {
_: ['--help']
}
failRest({args})
```
Result:
```js
{
errs: [
{
code: 'UnexpectedArgument',
msg: 'An unexpected argument was used...',
info: {...}
}
]
}
```
verifyArgs(rules)
Reports a FalseArgsRules error for each args object
that does not adhere to the rules predicate (with the signature arg => true|false).
Reports a [`WrongArgsRulesType`](#WrongArgsRulesType) error if `rules` is not a function.
Example:
```js
const {verifyArgs} = require('shargs/parser')
const rules = args => (
typeof args.question !== 'undefined' &&
typeof args.answer !== 'undefined'
)
const args = {
question: 'How much is the fish?'
}
verifyArgs(rules)({args})
```
Result:
```js
{
errs: [
{
code: 'FalseArgsRules',
msg: 'Your args rules returned false...',
info: {...}
}
]
}
```
#### `args` Stages
Description
Introduces new arguments by best guess based on rest field values
(e.g. {_: ['--version']} becomes {version: {type: 'flag', count: 1}}
and {_: ['--not', 'panic']} becomes {not: 'panic'}).
Transforms single rest field values into a flag and two consecutive rest options into a string.
It only assumes rest field values to be strings if the first rest is in short option format
(one minus with a single character, e.g. `-h`, `-v`)
or in long option format (two minuses with any more characters, e.g. `--help`, `--verbose`).
`bestGuessArgs` is very similar to [`bestGuessOpts`](#bestGuessOpts),
but also considers rest fields that originally did not directly follow each other.
E.g. assuming `--help` to be a known argument, `--not --help panic` would produce `{not: 'panic'}`,
although its components were not in tandem.
Example:
```js
const {bestGuessArgs} = require('shargs/parser')
const obj = {
args: {
_: ['--answer', '42', 'foo', '-h'],
command: {
_: ['bar', '-v', '--question', 'What is answer?', '-v']
}
}
}
bestGuessArgs(obj)
```
Result:
```js
{
args: {
_: ['foo'],
answer: '42',
h: {type: 'flag', count: 1},
command: {
_: ['bar'],
v: {type: 'flag', count: 2},
question: 'What is answer?'
}
}
}
```
Casts string args into other JavaScript types
using a best guess approach based on their values (e.g. {answer: '42'} becomes {answer: 42}
and {all: 'true'} becomes {all: true}).
It supports numbers and booleans (e.g. `{help: 'true'}` becomes `{help: true}`).
Example:
```js
const {bestGuessCast} = require('shargs/parser')
const args = {
_: ['--name', 'Marvin'],
str1: 'yay',
num1: '42.3',
num2: '123e-1',
num3: '0x11',
num4: '0b11',
bool1: 'true',
arr1: ['-42', 'true', 'yay'],
obj: {
num5: '0o11',
num6: '-Infinity',
num7: '',
num8: null,
bool2: 'false',
bool3: undefined
}
}
bestGuessCast({args})
```
Result:
```js
{
args: {
_: ['--name', 'Marvin'],
str1: 'yay',
num1: 42.3,
num2: 12.3,
num3: 17,
num4: 3,
bool1: true,
arr1: [-42, true, 'yay'],
obj: {
num5: 9,
num6: -Infinity,
num7: '',
num8: null,
bool2: false,
bool3: undefined
}
}
}
```
boolAsFlag(key)
Transforms bool arguments with key in args to a flag object.
E.g., assuming the all key,
{all: true} is transformed to {all: {type: 'flag', count: 1}} and
{all: false} to {all: {type: 'flag', count: -1}}.
Example:
```js
const args = {
_: [],
version: true
}
boolAsFlag('version')({args})
```
Result:
```js
{
_: [],
version: {type: 'flag', count: 1}
}
```
Transforms all bool arguments in args to flag objects
using boolAsFlag.
Example:
```js
const args = {
_: [],
html: false,
version: true
}
boolsAsFlags({args})
```
Result:
```js
{
_: [],
html: {type: 'flag', count: -1},
version: {type: 'flag', count: 1}
}
```
Sets rest values to an empty array (i.e. {_: []}).
Example:
```js
const {clearRest} = require('shargs/parser')
const args = {_: ['--verbose']}
clearRest({args})
```
Result:
```js
{
args: {_: []}
}
```
flagAsBool(key)
Transforms flags with key in args to a bool value.
E.g., assuming the all key,
{all: {type: 'flag', count: 1}} is transformed to {all: true} and
{all: {type: 'flag', count: -1}} to {all: false}.
If its `count` is greater than `0` it is considered `true`, otherwise it is considered `false`.
Example:
```js
const {flagAsBool} = require('shargs/parser')
const args = {
verbose: {type: 'flag', count: 1}
}
flagAsBool('verbose')({args})
```
Result:
```js
{
args: {
verbose: true
}
}
```
flagAsNumber(key)
Transforms flags with key in args to a number using its count.
E.g., assuming the verbose key,
{verbose: {type: 'flag', count: 3}} becomes {verbose: 3}.
Example:
```js
const {flagAsNumber} = require('shargs/parser')
const args = {
verbose: {type: 'flag', count: 2}
}
flagAsNumber('version')({args})
```
Result:
```js
{
args: {
verbose: 2
}
}
```
Transforms all flag arguments in args to bool values
using flagAsBool.
Example:
```js
const {flagsAsBools} = require('shargs/parser')
const args = {
verbose: {type: 'flag', count: 1}
}
flagsAsBools({args})
```
Result:
```js
{
args: {
verbose: true
}
}
```
Transforms all flag arguments in args to numbers using their count
like flagAsNumber.
Example:
```js
const {flagsAsNumbers} = require('shargs/parser')
const args = {
verbose: {type: 'flag', count: 2}
}
flagsAsNumbers({args})
```
Result:
```js
{
args: {
verbose: 2
}
}
```
mergeArgs(merge)
Transforms args by flattening them
by recursively merging nested objects into their parent object
(e.g. {ask: {question: '42?'}, answer: 42} becomes {question: '42?', answer: 42}).
A custom `merge` function may be passed with the following function signature:
`(obj1 = {}, obj2 = {}) => {}`.
The default `merge` function (if `merge` is `undefined`)
prefers keys from the parent object over keys from nested objects,
but concatenates rest values (`_`) from both objects
(e.g. `{_: ['foo'], answer: 42, ask: {_: ['bar'], answer: 23}}` becomes
`{_: ['foo', 'bar'], answer: 42}`).
Example:
```js
const {mergeArgs} = require('shargs/parser')
const args = {
_: ['--help'],
version: {type: 'flag', count: 2},
name: 'Arthur',
command: {
_: ['-v'],
version: {type: 'flag', count: 1},
name: 'Trillian',
help: true
},
verbose: true
}
const mergeLeft = (outer, inner) => ({
...inner,
...outer,
_: [
...(outer._ || []),
...(inner._ || [])
]
})
mergeArgs(mergeLeft)({args})
```
Result:
```js
{
args: {
_: ['--help', '-v'],
version: {type: 'flag', count: 2},
name: 'Arthur',
help: true,
verbose: true
}
}
```
numberAsFlag(key)
Transforms numbers with key in args to flag objects.
The number becomes the flag's count.
E.g. {answer: 42} becomes {answer: {type: 'flag', count: 42}}.
Example:
```js
const args = {
_: [],
answer: 42
}
numberAsFlag('answer')({args})
```
Result:
```js
{
_: [],
answer: {type: 'flag', count: 42}
}
```
Transforms all numbers in args to flag objects using numberAsFlag.
Example:
```js
const args = {
_: [],
answer: 42
}
numbersAsFlags({args})
```
Result:
```js
{
_: [],
answer: {type: 'flag', count: 42}
}
```
traverseArgs(fs)
Transforms args by applying functions fs to each key/value pair based on the value's type.
`fs` supports the following types:
`array`, `boolean`, `flag`, `function`, `null`, `number`, `object`, `string`, `undefined`, and `otherwise`.
The default behavior for most types is to not change the value, with three notable exceptions:
`function`s and `otherwise`s key/value pairs are removed from args,
while `object`'s default function applies `fs` to nested objects.
`{flag: ({key, val, errs, args}) => ({errs, args})}`
is the signature for `fs` with fields for each type.
Many other `args` checks and stages are defined in terms of `traverseArgs`
and it is of great help for writing custom `args` stages.
Example:
```js
const {traverseArgs} = require('shargs/parser')
const args = {
verbose: {type: 'flag', count: 2},
answer: 23
}
const fs = {
flag: ({key, val, errs, args}) => ({
errs,
args: {...args, [key]: val.count}
}),
number: ({key, val, errs, args}) => ({
errs,
args: {...args, [key]: val + 19}
})
}
traverseArgs(fs)({args})
```
Result:
```js
{
args: {
verbose: 2,
answer: 42
}
}
```
Allowed fs fields:
```js
const fs = {
array: ({key, val, errs, args}) => ({errs, args}),
boolean: ({key, val, errs, args}) => ({errs, args}),
flag: ({key, val, errs, args}) => ({errs, args}),
function: ({key, val, errs, args}) => ({errs, args}),
null: ({key, val, errs, args}) => ({errs, args}),
number: ({key, val, errs, args}) => ({errs, args}),
otherwise: ({key, val, errs, args}) => ({errs, args}),
object: ({key, val, errs, args}) => ({errs, args}),
string: ({key, val, errs, args}) => ({errs, args}),
undefined: ({key, val, errs, args}) => ({errs, args})
}
```
#### Advanced Parser Stages
+ [Custom checks and stages](#custom-checks-and-stages)
### Automatic Usage Documentation Generation
Shargs strictly separates the concerns of parsing command-line arguments and generating usage documentation.
The [`shargs-usage`][shargs-usage] module specializes on
generating terminal-based usage documentation for `--help` flags
from [command-line options](#command-line-options):
```js
const {desc, optsLists, space, synopses, usage} = require('shargs/usage')
const docs = usage([
synopses,
space,
optsLists,
space,
desc
])
```
[`shargs-usage`][shargs-usage] lets you define how your usage documentation should look like in a declarative way.
In the example, we tell our `docs` to start with [`synopses`](#synopses), have [`optsLists`](#optsLists) in the body,
and close with a [`desc`](#usage-desc)ription.
We separate these three parts with [`space`](#space)s and enclose everything in a [`usage`](#usage) function.
Note that we did not mention any command-line options, yet:
```js
const {command, flag, number, stringPos} = require('shargs/opts')
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: 'Deep Thought was created to come up with the Answer to ' +
'The Ultimate Question of Life, the Universe, and Everything.'
})
const optsDocs = docs(deepThought)
```
`optsDocs` now knows what to layout (`deepThought`), and how to layout it (`docs`).
Finally, we `style` the different parts (lines and columns) of the documentation:
```js
const style = {
line: [{width: 60}],
cols: [{width: 25}, {width: 35}]
}
const text = optsDocs(style)
```
Now, if we `console.log(text)`, the following `text` is printed to the console:
```bash
deepThought () [-a|--answer] [-h|--help]
Ask a question. [required]
-a, --answer= The answer. [default: 42]
-h, --help Print this help message and exit.
Deep Thought was created to come up with the Answer to The
Ultimate Question of Life, the Universe, and Everything.
```
`deepThought`, `docs`, and [`style`](#style)
are the moving parts of [automatic usage documentation generation](#automatic-usage-documentation-generation)
and are defined independently.
We have already talked about [command-line options](#command-line-options) before
and will talk about [`style`](#style) in an upcoming section.
#### Usage Functions
[`shargs-usage`][shargs-usage] provides the following usage functions to declare layouts:
Usage Function
Description
desc takes a command-line option's desc field
and formats it according to a style.
If the description is too long to fit one line, it is split and spread over several lines.
`desc` is defined as `descWith({id: 'line'})`.
Example:
```bash
Deep Thought should answer the Ultimate
Question
```
Code:
```js
const {desc, usage} = require('shargs/usage')
const opt = {
opts: [],
desc: 'Deep Thought should answer the Ultimate Question'
}
const style = {
line: [{width: 40}]
}
usage([
desc
])(opt)(style)
```
note(string)
noteWith({id})(string)
note takes a string and formats it according to a style,
ignoring its second parameter.
If the string is too long to fit one line, it is split and spread over several lines.
`note` is defined as `noteWith({id: 'line'})`.
Example:
```bash
Deep Thought was created to come up with
the Answer
```
Code:
```js
const {note, usage} = require('shargs/usage')
const style = {
line: [{width: 40}]
}
usage([
note('Deep Thought was created to come up with the Answer')
])()(style)
```
notes(strings)
notesWith({id})(strings)
notes takes a list of strings and formats it
according to a style,
ignoring its second parameter.
If a string is too long to fit one line, it is split and spread over several lines.
`notes` is defined as `notesWith({id: 'line'})`.
Example:
```bash
Deep Thought was created to come up with
the Answer
to The Ultimate Question.
```
Code:
```js
const {notes, usage} = require('shargs/usage')
const style = {
line: [{width: 40}]
}
usage([
notes([
'Deep Thought was created to come up with the Answer',
'to The Ultimate Question.'
])
])()(style)
```
optsDef
optsDefWith({id, pad})
optsDef layouts its opts as a definition list
and formats it according to its style.
The term part comprises of an opt's [`args`](#args), [`descArg`](#descArg),
[`only`](#only), [`types`](#types), and [`key`](#key) fields, followed by the
[`contradicts`](#contradicts), [`defaultValues`](#defaultValues),
[`implies`](#implies), and [`required`](#required) fields.
The [`desc`](#desc) field is given in the definition part.
`optsDef` is defined as `optsDefWith({id: 'line', pad: 4})`.
Example:
```bash
-a, --answer= [default: 42]
The answer.
-h, --help
Prints help.
--version
The version.
```
Code:
```js
const {optsDef, usage} = require('shargs/usage')
const {flag, number} = require('shargs/opts')
const opt = {
opts: [
number('answer', ['-a', '--answer'], {
desc: 'The answer.', defaultValues: ['42']
}),
flag('help', ['-h', '--help'], {desc: 'Prints help.'}),
flag('version', ['--version'], {desc: 'The version.'})
]
}
const style = {
line: [{width: 40}]
}
usage([
optsDef
])(opt)(style)
```
optsDefs
optsDefsWith({id, pad})
optsDefs first layouts its opts and then the opts
of all its subcommands recursively,
using optsDefs,
indenting each optsDef layer by pad spaces.
`optsDefs` is defined as `optsDefsWith({id: 'line', pad: 4})`.
Example:
```bash
-a, --answer= [default: 42]
The answer.
-h, --help
Show the usage docs.
ask [required]
Ask questions.
-h
Usage docs.
... [required]
Questions.
```
Code:
```js
const {optsDefs, usage} = require('shargs/usage')
const {flag, subcommand} = require('shargs/opts')
const {number, variadicPos} = require('shargs/opts')
const required = true
const askOpts = [
flag('help', ['-h'], {desc: 'Show the usage docs.'}),
variadicPos('questions', {required, desc: 'Questions.'})
]
const ask = subcommand(askOpts)
const opt = {
opts: [
ask('ask', ['ask'], {desc: 'Ask questions.', required}),
number('answer', ['-a', '--answer'], {
desc: 'The answer.', defaultValues: ['42']
}),
flag('help', ['-h', '--help'], {desc: 'Usage docs.'})
]
}
const style = {
line: [{width: 40}]
}
usage([
optsDefs
])(opt)(style)
```
optsList
optsListWith({id})
optsList layouts its opts as a table with two columns
and formats it according to its style.
The first column comprises of an opt's [`args`](#args), [`descArg`](#descArg),
[`only`](#only), [`types`](#types), and [`key`](#key) fields.
The [`desc`](#desc) field is given in the second column, foll