nix-clap
v1.3.13
Published
Simple, lightweight, flexible, and comprehensive Un*x Command Line Argument Parsing for NodeJS
Downloads
45,548
Maintainers
Readme
NixClap
Simple, lightweight, flexible, and comprehensive Un*x Command Line Argument Parsing for NodeJS.
Features
- Lightweight with minimal dependencies.
- Comprehensive and flexible parsing capabilities similar to conventional Un*x parsing.
- Flexible handling of options and commands that can take variadic params.
- A simple and straightforward JSON interface for specifying options and commands.
- Very informative result that tells you where each option came from.
- Webpack friendly - allows bundling your cli into a single JS file with webpack.
Examples
Options only:
const NixClap = require("nix-clap");
const options = {
names: {
desc: "specify names",
alias: ["n", "m"],
type: "string array"
}
};
const parsed = new NixClap()
.version("1.0.0")
.usage("$0 [options]")
.init(options)
.parse();
console.log("names", parsed.opts.names);
With commands:
const NixClap = require("nix-clap");
const options = {
verbose: {
desc: "enable verbose mode",
alias: "v",
type: "boolean",
default: false
}
};
const commands = {
compile: {
desc: "run compile on the files",
args: "<string files...>",
exec: parsed => {
console.log("compile", parsed.args.files, "verbose", parsed.opts.verbose);
}
}
};
const parsed = new NixClap()
.version("1.0.0")
.usage("$0 [options] <command> [options]")
.init(options, commands)
.parse();
version
,help
, andusage
must be called beforeinit
Usage:
$ my-prog compile --verbose file1.jsx file2.jsx file3.jsx
More Examples
See examples folder for more working samples.
Parsing Capabilities
Options
Example: prog -xazvf=hello --foo-option hello bar -. --enable-blah
- Support
-
single char options or--
long form options. - Options can have aliases.
- Both option forms can have argument specified with
=
or space.- ie: long form
--foo-option=bar
or--foo-option bar
- ie: short form
-f=bar
or-f bar
- ie: long form
- Both option forms can have variadic array args.
- ie:
--foo-option hello bar
or-f hello bar
- array args can have an optional type
- ie:
-
options can be compounded, like-xazvf
.- Last char can have args, like
-xazvf=hello
or-xazvf hello
. - Other chars are treated as
boolean
options automatically.
- Last char can have args, like
- Variadic array args are terminated by any other options such as
-x
or--xyz
, or explicitly with-.
or--.
- ie:
cmd1 arg1 arg2 --some-array abc def ghi -. cmd2 arg1 arg2
.
- ie:
- Allow arbitrary unknown options but with arguments specified through
=
only.- Since it's ambiguous whether to take a non-option arg following an unknown option as an argument or a command.
- Counting number of option occurrences.
- Boolean option can be negated with
--no-
prefix. - Allow custom value type coercions with a function or RegExp.
Commands
Example: prog sum 1 2 3 4
- Commands can have optional or required arguments.
- Each argument type defaults to
string
, but can have an optional type
- Each argument type defaults to
- Commands can have aliases.
- Possible to specify multiple commands.
- Commands can have variadic array arguments.
- Variadic array args are terminated by any other options such as
-x
or--xyz
, or explicitly with-.
or--.
- ie:
prog order pizza soda -. pickup
(specifies two commands:order
andpickup
)
- ie:
- Command can have its own options that are binded to it only.
- Top level options can be binded to specific commands only.
- Unbind top level options can be specified before or after commands.
- Allow arbitrary unknown commands that do not have arguments.
- Allow multiple custom value type coercions for each command.
Terminating and Resuming
--
terminates parsing, with remaining args returned inparsed._
.- Parsing can be resumed after it's terminated.
-.
or--.
can terminate variadic params for commands and options.
Install
npm i nix-clap --save
Interface
This module exposes a class with a few methods.
See APIs for more details.
options spec
const options = {
"some-option": {
alias: ["s", "so"],
type: "string",
desc: "description",
default: "foo",
require: true,
requireArg: true,
allowCmd: ["cmd1", "cmd2"]
},
"another-option": {}
};
Where:
| field | description |
| ------------ | --------------------------------------------------------------------------------------------------------------------------------- |
| alias
| Specify aliases for the option, as a single string or an array of strings. |
| type
| Type of argument for the option, one of: string
, number
, float
, boolean
, array
, count
, or coercion |
| | array
can set type of elements as one of string
, number
, float
, boolean
like this: number array
or float array
|
| desc
| Description for the option - a string or a function that returns string. |
| default
| Default value to use for argument |
| require
| true
/false
whether this option must be specified. |
| requireArg
| true
/false
whether argument for the option is required. |
| allowCmd
| list of command names this option is allow to follow only. |
commands spec
const commands = {
cmd1: {
alias: ["c"],
args: "<arg1> [arg2..]",
usage: "$0 $1",
desc: "description",
exec: argv => {},
default: true,
options: {}
},
cmd2: {}
};
Where:
| field | description |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| alias
| Specify aliases for the command, as a single string or an array of strings. |
| args
| Specify arguments for the command. <>
means it's required and []
optional. See rules for more info. |
| usage
| usage message when help for the command is invoked - a string or a function that returns a string. |
| | $0
will be replaced with program name and $1
with command name. |
| desc
| Description for the command - can be a string or a function that returns a string. |
| exec
| The callback handler for the command - see here for more details. |
| default
| If true
, set the command as default, which is invoked when no command was given in command line. |
| | - Only one command can be default. |
| | - Default command cannot have required args and must have the exec
handler |
| options
| List of options arguments private to the command. Follows the same spec as top level options |
Rules for Command args
Rules for when specifying args
for the command:
- all required args must be before optional args
- last one can specify variadic args with
..
, like<names..>
or[names..]
- If you just want to get the list of args without naming it, you can specify with
<..>
or[..]
- named args can have an optional type like
<number value>
or[number values..]
- supported types are
number
,float
,string
,boolean
, or coercion
- supported types are
Value Coercion
If none of the predefined types work for you, you can specify your own as a function or a RegExp, or any value.
You use any valid identifier for the value type, and then you define a field with the same name in your spec that can be:
function
- will be called with the value to convertRegExp
- will be used to match the value.undefined
is returned if it didn't match.- Anything else - will be used as the converted value.
For example:
const options = {
customFn: {
type: "fnval",
fnval: value => {
return value.substr(0, 1);
}
},
customRegex: {
type: "rx",
rx: /^test$/i
},
customAny: {
type: "foo",
foo: "bar"
}
};
const commands = {
foo: {
args: "<type1 value1> <type2 value2>",
type1: value => `test-${value}`,
type2: /^test$/i
}
};
Parse Result
Use the method parse
to parse command line arguments. It will return a parse result object.
{
source: {},
opts: {},
verbatim: {},
commands: [],
index: 5,
error,
_: [],
argv: []
}
Where:
index
- the index inargv
parse stoppederror
- If parse failed and yourparse-fail
event handler throws, then this will contain the parse error. See skip default event behaviors for more details.source
,opts
,verbatim
- objects containing info for the options. See details herecommands
- array of parsed command objects. Seecommands
for more details.argv
- original array of argv_
- remaining args in theargv
array in case parsing was terminated by--
.
If any command with exec
handlers were specified, then parse
will invoke them before returning the parse result object.
Parse Result source
and opts
objects
opts
- contains actual value for each optionsource
- contains info about where the option value came fromcli
- option specified by user in the command linedefault
- default value in your options specuser
- values you applied by calling theapplyConfig
method
verbatim
- contains original unprocessed value as given by the user in the command line- This is an array of values if there was actual values from the user
- If there's no explicit value (ie. boolean or counting options), then this doesn't contain a field for the option.
- If it's a boolean but the user specified with
--no-
prefix, then this contains a field with the value["no-"]
For example, with the following conditions:
- User specified
--foo-bar=test
in the command line - You have an option
fooDefault
with default valuebar
- You called
applyConfig
withapplyConfig({fooConfig: 1, fooBar: "oops"}, parsed)
You would get the following in the parse result object:
{
source: {
fooBar: "cli",
fooDefault: "default",
fooConfig: "user"
},
opts: {
fooBar: "test",
fooDefault: "bar",
fooConfig: 1
},
verbatim: {
fooBar: ["test"]
}
}
Note that the value
oops
forfooBar
passed toapplyConfig
is not used since user's specified value is used.
Parse Result commands
object
The commands
object is an array of parsed commands:
{
commands: [
{
name: "cmdName",
long: "cmdName",
unknown: false,
args: {
foo: "bar",
variadic: ["a", "b"]
},
argList: ["bar", "a", "b"],
opts: {},
source: {},
verbatim: {}
}
];
}
name
is the name of the command used by the user in the command line that could be an aliaslong
is the original form of the command name (not the alias)unknown
-true
if the command is not knownargs
- the processed named argumentsargList
- list of all the arguments in unprocessed string formopts
,source
,verbatim
- info for the options private to the command
Command exec
handler
If the command has an exec
handler, then it will be called with two arguments:
exec(result, parsed);
- First one is the object for the command
- Second one is the overall parsed object
Info about the command object:
{
name: "cmdName",
long: "cmdName",
args: {
foo: "bar",
variadic: [ "a", "b" ]
},
argList: [ "bar", "a", "b" ],
opts: {},
source: {},
verbatim: {}
}
Where opts
and source
contain both the command's private options and top level options.
You can turn this off with the
skipExec
config flag passed toNixClap
constructor
Events
NixClap
emits these events:
help
- when--help
is invoked, emitted with the parse result object.pre-help
- before output for--help
post-help
- after output for--help
help
- when--help
is invoked, emitted with the parse result object.version
- when--version
is invoked, emitted with the parse result object.parsed
- when all parsing is done but before commandexec
are invoked, emitted with{ nixClap, parsed }
wherenixClap
is the NixClap instance.parse-fail
- when parse failed, emitted with parse result object, which haserror
field.unknown-option
- when an unknown option is found, emitted with option nameunknown-command
- when an unknown command is found, emitted with command context, which hasname
field.no-action
- when you have commands withexec
and user specified no command that triggered anexec
call.exit
- When program is expected to terminate, emit with exit code.
Default Event Handlers
NixClap has default handlers for these events:
help
- Output help and emitexit
version
- Ifversion
has been set, then output version and emitexit
.parse-fail
- Output help and error message, and emitexit
.unknown-option
- Throws ErrorUnknown option ${name}
unknown-command
- Throws ErrorUnkown command ${ctx.name}
no-action
- Output help with errorNo command given
and emitexit
exit
- callsprocess.exit(code)
Skip Default Event Behaviors
You can remove the default event handlers with one of these approaches:
- With the
removeDefaultHandlers
method. - By passing in
handlers
object in theconfig
for the constructor.
For example, using removeDefaultHandlers
:
const nc = new NixClap().init(options, commands);
const parsed = nc.removeDefaultHandlers("parse-fail").parse();
if (parsed.error) {
// handle the parse error here
}
Using constructor config.
const parsed = new NixClap({ handlers: { "parse-fail": false } }).parse();
if (parsed.error) {
// handle the parse error here
}
APIs
These are methods NixClap
class supports.
- NixClap
- Features
- Examples
- Parsing Capabilities
- Install
- Interface
- Others
constructor(config)
config
is object with:
name
- set the program name. Will auto detect fromprocess.argv
if not specified.version
- set the program version. Can also set withversion
method.help
- custom help option setting. Can also set withhelp
method.usage
- usage message. Can also set withusage
method.cmdUsage
- generic usage message for commands. Can also set withcmdUsage
method.skipExec
- If true, will not call commandexec
handlers after parse.skipExecDefault
- if true, will not call default commandexec
handler after parse.- In case you need to do something before invoking the
exec
handlers, you can set these flags and call therunExec(parsed, skipDefault)
method yourself.
- In case you need to do something before invoking the
output
- callback for printing to console. Should take string as param. Default to callingprocess.stdout.write
handlers
- custom event handlers.
The handlers
object can specify a function for each of the events or set it to false
to turn off the default handler.
For example, this config will replace handler for parse-fail
and turn off the default unknown-option
handler.
const nc = new NixClap({
handlers: {
"parse-fail": (parsed) => { ... },
"unknown-option": false
}
});
version(v)
Set program version with a string. ie: 1.0.0
Return: The NixClap
instance itself.
Must be called before the
init
method.
help(setting)
Set a custom option setting for invoking help. Default is:
Return: The NixClap
instance itself.
{
alias: "h",
desc: "Show help"
}
Option name is always help
. Call help(false)
to turn off the default --help
option.
Must be called before the
init
method.
usage(msg)
, cmdUsage(msg)
Set usage message for the program or command, which can be override by individual command's own usage.
msg
format is any string. $0
will be replaced with program name and $1
with command name.
Return: The NixClap
instance itself.
Must be called before the
init
method.
init(options, commands)
Initialize your options and commands
Return: The NixClap
instance itself.
parse(argv, start, parsed)
Parse command line. Call without any params to parse process.argv
.
Return: The parse result object.
argv
- array of CLI args. Defaults toprocess.argv
.start
- index for argv from where to start parsingparsed
- previous result fromparse
. If passed, then parsing will add new data to it.
parseAsync(argv, start, parsed)
async version of parse.
- It will use runExecAsync to invoke command
exec
handlers serially. - The command handler can return a Promise, which will be awaited.
Return: A promise the resolve with the parse result object.
showHelp(err, cmdName)
Show help message and then emit exit
.
err
- if valid, thenerr.message
will be printed after help message and exit with code1
.cmdName
- if valid, then will print help for the specific command.
removeDefaultHandlers()
Remove NixClap's default handlers for the list of event names.
If you've replaced the handler through specifying handlers
in config
for the constructor, then this will not remove your handler.
Return: The NixClap
instance itself.
- You can pass in
"*"
to remove all default handlers. - You can pass in the event names you want to remove.
ie:
nc.removeDefaultHandlers("parse-fail", "unknown-option", "unknown-command");
applyConfig(config, parsed, src)
Allow you to apply extra config to the parsed object, overriding any opts
with source
not equal to cli
.
For example, you can allow user to specify options in their package.json
file, and apply those after the command line is parsed.
config
- Config object containing user options configparsed
- The parse result object from NixClap.src
- String, source to set if override. Default touser
Example on applying user config from package.json
:
const pkg = require(path.resolve("package.json"));
const parsed = nc.parse();
nc.applyConfig(pkg.cliConfig, parsed);
runExec(parsed, skipDefault)
Go through the commands in parsed and call their exec
handler.
The
parse
method will call this at the end unlessskipExec
flag is set.
Return: The number of commands with exec
was invoked.
parsed
- The parse result object.skipDefault
-boolean
, iftrue
then do not invoke default command'sexec
handler when no command withexec
handler was given.
runExecAsync(parsed, skipDefault)
async version of runExec
Return: A promise that resolve with the number of commands with exec
invoked.