minargs
v2.0.3
Published
minimum viable argument parser
Downloads
23
Maintainers
Readme
minargs
minargs
is an argument parser with minimal configuration & assumptions. Argument parsing can take many shapes but the explicit goals of this library are as follows:
Goals
- no usage
- no validation
- no types or type cohersion
- no regular expressions
- no strictness
- no dependencies
- no information loss
- minimal assumptions
- minimal configuration
- consistant results/format
- 100% test coverage
Mantras
- Bring Your Own Usage™️
- Bring Your Own Validation™️
Installation
npm install minargs
miargs([argv][, options])
argv
(Array
)- Default:
process.argv
- The argument strings to parse
- Default:
Options
alias
(Object
)- Default: none
- Define shorts & aliases to map to a canonical argument
- Note: only single character aliases can be parsed as "shorts" (read more in the F.A.Q. below)
positionalValues
(Boolean
)- Default:
false
- Define whether or not to use positionals that follow bare flag definitions as values
- Default:
recursive
(Boolean
)- Default:
false
- Define whether or not to end parsing when a bare
--
marker is found
- Default:
Returned Values
{
args: {},
positionals: [],
remainder: [],
argv: []
}
args
- An
Object
of canonical argument keys with correspondingArray
of parsedString
values - Examples:
--foo
will return[""]
(note the empty string by default)--foo=bar
will return["bar"]
--foo bar
will return["bar"]
whenpositionalValues
istrue
- Notably,
bar
is treated as a positional & returned inpositionals
ifpositionalValues
isfalse
- Notably,
positionals
- An
Array
of parsed positionalString
values
remainder
- An
Array
ofString
values the follow the first bare--
whenrecursive
isfalse
- Notably, this is useful for recursively parsing arguments or passing along args to other processes (read more in the F.A.Q. below)
argv
- An
Array
ofObject
s with correspondingindex
s mapping back to the originalprocess.argv
or providedArray
Object
s also contain thevalue
parsed &type
(ie."argument"
,"short"
,"positional"
or"value"
)- The
type
"value"
will only ever be defined -- in place of"positional"
-- whenpositionalValues=true
- Notably, this is useful for recreating the original
String
values or extending the capabilities of this information (ref. https://github.com/pkgjs/parseargs/issues/84)
Example Usage
Basic
$ basic.js - --foo=bar -- --baz
#!/usr/bin/env node
// basic.js
const { minargs } = require('minargs')
const { args, positionals, remainder, argv } = minargs()
args // { "foo": ["bar"] }
positionals // ["-"]
remainder // ["--baz"]
argv // [ { index: 0, type: 'argument', value: { name: "foo", value: "bar" } } ... ]
Handling existence
$ exists.js --foo
#!/usr/bin/env node
// exists.js
const { minargs } = require('minargs')
const { args } = minargs()
if (args.foo) {
// ...
}
Handling last value define
$ last-definition-.js --foo
#!/usr/bin/env node
// exists.js
const { minargs } = require('minargs')
const { args } = minargs()
if (args.foo) {
// ...
}
Handling unknown args
$ unknown.js --baz
Handling extension
#!/usr/bin/env node
// unknown.js
const { minargs } = require('minargs')
const { args } = minargs()
const known = ['foo', 'bar']
const unknown = Object.keys(args).filter(arg => !known.includes(arg))
if (unknown.length > 0) {
console.error('unknown flags passed:', unknown)
// stop the process & set an `exitCode` appropriately
process.exit(1)
}
// ...
Handling validation
$ validate.js --num=1337
#!/usr/bin/env node
// validate.js
const { minargs } = require('minargs')
const { args } = minargs()
const usage = {
num: {
validate: (value) => {
if (!isNaN(value)) {
return Number(value)
}
throw Error('Validation error!')
}
},
force: {
validate: (value) => {
if (~['true','false'].indexOf(value.toLowerCase())) {
return Boolean(value)
}
throw Error('Validation error!')
}
}
}
Object.keys(args).filter(name => args[name]).map(name => {
usage[name].validate(args[name].pop())
})
// ...
Handling recursive parsing
$ recursive-parse.js
#!/usr/bin/env node
// recursive-parse.js
const { minargs } = require('minargs')
console.log(minargs({ recursive: true }))
// ...
Handling sub process
$ mkdir.js ./path/to/new/dir/ --force --verbose --parents
#!/usr/bin/env node
// mkdir.js
const known = ['force']
const { args, positionals } = minargs()
const cmd = (args.force) ? 'sudo mkdir' : 'mkdir'
const _args = Object.keys(flags).filter(f => known[f])
process('child_process').spawnSync(cmd, [..._args, ...positionals])
Handling robust options & usage
$ usage.js -h
#!/usr/bin/env node
// usage.js
const { minargs } = require('minargs')
const usage = {
help: {
short: 'h',
usage: 'cli --help',
description: 'Print usage information'
}
force: {
short: 'f',
usage: 'cli --force',
description: 'Run this cli tool with no restrictions'
}
}
const opts = {
alias: Object.keys(usage).filter(arg => usage[arg].short).reduce((o, k) => {
o[usage[k].short] = k
return o
}, {})
}
const { args } = minargs(opts)
if (args.help) {
Object.keys(usage).map(name => {
let short = usage[name].short ? `-${usage[name].short}, ` : ''
let row = [` ${short}--${name}`, usage[name].usage, usage[name].description]
console.log.apply(this, fill(columns, row))
})
}
/// ...
F.A.Q.
Why isn't strictness supported?
- Strictness is a function of usage. By default,
minargs
does not assume anything about "known" or "unknown" arguments or their intended values (ex. defaults/types). Usage examples above show how you can quickly & easily utilizeminargs
as the backbone for an application which does enforce strictness/validation & more.
Are shorts supported?
- Yes.
- Individual (ex.
-a
) & combined (ex.-aCdeFg
) shorts are supported -a=b
will capture & return"b"
as a value-a b
will capture & return"b"
as a value ifpositionalValues
istrue
Are multiples supported?
- Yes.
- By default multiple definitions of the same argument will get consolidated into a single
arg
entry with a correspondingArray
ofString
values - Getting the last defined value of an argument is as simple as running
.pop()
on theArray
(ex.args.foo.pop()
)
What is an alias
?
- An alias can be any other string that maps to a canonical option; this includes single characters which will map shorts to a long-form (ex.
alias: { f: foo }
will parse-f
as{ args: { "foo": [""] } }
)
Is cmd --foo=bar baz
the same as cmd baz --foo=bar
?
- Sort of.
- The returned
argv
Array
will change to reflect the differing positions of the arguments & positionals BUTargs
&positionals
will remain consistent
Is value validation or type cohersion supported?
- No.
Are usage errors supported?
- No.
Does --no-foo
coerce to --foo=false
?
- No.
--no-foo
will parse to{ args: { "no-foo": [""] } }
&--foo-false
to{ args: { "no-foo": ["false"] } }
respectively
Is --foo
the same as --foo=true
?
- No.
--foo
will parse to{ args: { "foo": [""] } }
&--foo=true
to{ args: { "foo": ["true"] } }
respectively
Are environment variables supported?
- No.
Does --
signal the end of flags/options?
- Yes.
- Any arguments following a bare
--
definition will be returned inremainder
.
Is a value stored to represent the existence of --
?
- No.
- The only way to determine if
--
was present & there were arguments passed afterward is to check the value ofremainder
Is -
a positional?
- Yes.
- A bare
-
is treated as & returned inpositionals
Is -bar
the same as --bar
?
- No.
-bar
will be parsed as short options, expanding to-b
,-a
,-r
(ref. Utility Syntax Guidelines in POSIX.1-2017)
Is ---foo
the same as --foo
?
- No.
---foo
returns{ args: "-foo": [""] }
--foo
returns{ args: { "foo": [""] }
Is foo=bar
a positional?
- Yes.
Are negative numbers supported as positional values?
- No.
minargs
aligns with the POSIX Argument Syntax here (ie. "Arguments are options if they begin with a hyphen delimiter")--number -2
will be parsed as{ args: { "number": [""], "2": [""] } }
- You will have to use explicit value setting to make this association (ex.
--number=-2
) & may further require validation/type coercion to determine if the value is aNumber
(as is shown in the usage examples above)
CLI
minargs
has a companion CLI library: @minargs/cli
Installation
# install package globally & call bin...
npm install @minargs/cli -g && minargs
# or, use `npx` to install & call bin...
npx -- @minargs/cli "<args>" [<options>]
Usage
minargs "<args>" [<options>]
Options & more....
To learn more, check out the @minargs/cli
GitHub repository or package page