argument parsers from json schemas, using subarg syntax and the ajv validator
jargon-parser
is designed to be a drop in cli
builder that you don't have to manage or configure beyond the natural data schema for your application. This means you can easily use the same logic for your .json
configurator, REST
api, and cli
, without losing power.
With the example/parser.js (rough equivalent in es6
):
import newParser from 'jargon-parser'
const cli = newParser({ schema: __dirname + '/schema.json' })
console.log(JSON.stringify(cli()))
The invocation
node example/parser.js \
--billing_address [ \
--street_address "1234 fake st" ] \
--shipping_address [ \
--street_address "2222 muddle drive" \
--city houston --type business ] \
--items [ \
[ --name foo ] \
[ --price 0.99 --name bar ] ] \
| python -mjson.tool # for pretty printing
yields
{
"billing_address": {
"city": "Austin",
"state": "TX",
"street_address": "1234 fake st"
},
"shipping_address": {
"city": "houston",
"state": "TX",
"street_address": "2222 muddle drive",
"type": "business"
},
"items": [
{
"name": "foo"
},
{
"name": "bar",
"price": 0.99
}
]
}
given the sample schema in examples/schema.json
(notice that default
s are applied).
Note: Currently might not work with more complicated schemas
jargon-parser
uses cliui for help formatting:
node example/parser.js --help
Usage: example/parser.js
A delivery order
Arguments:
--billing_address [ # address affiliated with credit card
--street_address <string> [required] # street number and name
--city <string> [default: "Austin"]
--state <string> [default: "TX"]
]
--items [ # array of items to purchase
[
--name <string> [required]
--price <number> [optional]
],
...items
]
--shipping_address [ # address to which we will ship the package
--street_address <string> [optional] # street number and name
--city <string> [default: "Austin"]
--state <string> [default: "TX"]
--type <string> [optional]
]
By default help is displayed with the flag --help
or on error,
both of which can be customized via helpOptions
passed to newParser
: { flag: 'help', catchErrors: true }
Caveat/technical details:
Currently, the only "schema intelligence" --help
currently has is the ability to resolve references and merge allOf
statments in object
s. It is also as verbose as possible by default.
The default
export newParser({schema, schemaCaster, name, description, helpOptions})
returns a parser
that takes an optional array of argv
arguments,
defaulting to process.argv.slice(2)
, and returns the validated/cast result.
schema
and schemaCaster
are mutually exclusive, and schemaCaster
takes precedence.
If schema
is provided, either as as a relative path or object,
it will be passed to newCaster with the default ajv compiler,
which will construct Avj
with the arguments { coerceTypes: true, useDefaults: true, v5: true }
.
The result of newParser
Aside from avj
type coercion and default filling, jargon-parser
s function mostly the same as subarg's, except that arrays and dictionaries are mutually exclusive in json. This means that cli command --sub [ args args -f ]
is invalid, because the subarg
result is
{
"_": [ "command" ],
"sub": {
"_": [ "args" , "args" ],
"f": true
}
}
So [ "command" ]
and { "sub": ... }
would be in conflict,
as would [ "args" , "args" ]
and { "f": true }
.
A valid alternative would be cli command [ --sub [ --list [ args args ] -f ] ]
, resulting in
{
"command": {
"sub": {
"list": [ "args" , "args" ],
"f": true
}
}
}