Simple, lightweight, flexible, and comprehensive Un*x Command Line Argument Parsing for NodeJS
APACHE-2.0 License
Simple, lightweight, flexible, and comprehensive Un*x Command Line Argument Parsing for NodeJS.
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
See examples folder for more working samples.
Example: prog -xazvf=hello --foo-option hello bar -. --enable-blah
-
single char options or --
long form options.=
or space.
--foo-option=bar
or --foo-option bar
-f=bar
or -f bar
--foo-option hello bar
or -f hello bar
-
options can be compounded, like -xazvf
.
-xazvf=hello
or -xazvf hello
.boolean
options automatically.-x
or --xyz
, or explicitly with -.
or --.
cmd1 arg1 arg2 --some-array abc def ghi -. cmd2 arg1 arg2
.=
only.
--no-
prefix.Example: prog sum 1 2 3 4
string
, but can have an optional type-x
or --xyz
, or explicitly with -.
or --.
prog order pizza soda -. pickup
(specifies two commands: order
and pickup
)--
terminates parsing, with remaining args returned in parsed._
.-.
or --.
can terminate variadic params for commands and options.npm i nix-clap --save
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 |
args
Rules for when specifying args
for the command:
..
, like <names..>
or [names..]
<..>
or [..]
<number value>
or [number values..]
number
, float
, string
, boolean
, or 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.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
}
};
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 in argv
parse stoppederror
- If parse failed and your parse-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 here
commands
- array of parsed command objects. See commands
for more details.argv
- original array of argv_
- remaining args in the argv
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.
source
and opts
objectsopts
- contains actual value for each option
source
- contains info about where the option value came from
cli
- option specified by user in the command linedefault
- default value in your options spec
user
- values you applied by calling the applyConfig
methodverbatim
- contains original unprocessed value as given by the user in the command line
--no-
prefix, then this contains a field with the value ["no-"]
For example, with the following conditions:
--foo-bar=test
in the command linefooDefault
with default value bar
applyConfig
with applyConfig({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.
commands
objectThe 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 commandexec
handlerIf the command has an exec
handler, then it will be called with two arguments:
exec(result, parsed);
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
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 command exec
are invoked, emitted with { nixClap, parsed }
where nixClap
is the NixClap instance.parse-fail
- when parse failed, emitted with parse result object, which has error
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 has name
field.no-action
- when you have commands with exec
and user specified no command that triggered an exec
call.exit
- When program is expected to terminate, emit with exit code.NixClap has default handlers for these events:
help
- Output help and emit exit
version
- If version
has been set, then output version and emit exit
.parse-fail
- Output help and error message, and emit exit
.unknown-option
- Throws Error Unknown option ${name}
unknown-command
- Throws Error Unkown command ${ctx.name}
no-action
- Output help with error No command given
and emit exit
exit
- calls process.exit(code)
You can remove the default event handlers with one of these approaches:
removeDefaultHandlers
method.handlers
object in the config
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
}
These are methods NixClap
class supports.
constructor(config)
config
is object with:
name
- set the program name. Will auto detect from process.argv
if not specified.version
- set the program version. Can also set with version
method.help
- custom help option setting. Can also set with help
method.usage
- usage message. Can also set with usage
method.cmdUsage
- generic usage message for commands. Can also set with cmdUsage
method.skipExec
- If true, will not call command exec
handlers after parse.skipExecDefault
- if true, will not call default command exec
handler after parse.
exec
handlers, you can set these flags and call the runExec(parsed, skipDefault)
method yourself.output
- callback for printing to console. Should take string as param. Default to calling process.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 to process.argv
.start
- index for argv from where to start parsingparsed
- previous result from parse
. If passed, then parsing will add new data to it.parseAsync(argv, start, parsed)
async version of parse.
exec
handlers serially.Return: A promise the resolve with the parse result object.
showHelp(err, cmdName)
Show help message and then emit exit
.
err
- if valid, then err.message
will be printed after help message and exit with code 1
.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.
"*"
to remove all default handlers.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 to user
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
, if true
then do not invoke default command's exec
handler when no command with exec
handler was given.runExecAsync(parsed, skipDefault)
async version of runExec
Return: A promise that resolve with the number of commands with exec
invoked.