nix-clap v1.3.13
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, andusagemust be called beforeinit
Usage:
$ my-prog compile --verbose file1.jsx file2.jsx file3.jsxMore 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=baror--foo-option bar - ie: short form
-f=baror-f bar
- ie: long form
- Both option forms can have variadic array args.
- ie:
--foo-option hello baror-f hello bar - array args can have an optional type
- ie:
-options can be compounded, like-xazvf.- Last char can have args, like
-xazvf=helloor-xazvf hello. - Other chars are treated as
booleanoptions automatically.
- Last char can have args, like
- Variadic array args are terminated by any other options such as
-xor--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
-xor--xyz, or explicitly with-.or--.- ie:
prog order pizza soda -. pickup(specifies two commands:orderandpickup)
- 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 --saveInterface
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.undefinedis 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 inargvparse stoppederror- If parse failed and yourparse-failevent 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. Seecommandsfor more details.argv- original array of argv_- remaining args in theargvarray 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 theapplyConfigmethod
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=testin the command line - You have an option
fooDefaultwith default valuebar - You called
applyConfigwithapplyConfig({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
oopsforfooBarpassed toapplyConfigis 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: {}
}
];
}nameis the name of the command used by the user in the command line that could be an aliaslongis the original form of the command name (not the alias)unknown-trueif 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
skipExecconfig flag passed toNixClapconstructor
Events
NixClap emits these events:
help- when--helpis invoked, emitted with the parse result object.pre-help- before output for--helppost-help- after output for--helphelp- when--helpis invoked, emitted with the parse result object.version- when--versionis invoked, emitted with the parse result object.parsed- when all parsing is done but before commandexecare invoked, emitted with{ nixClap, parsed }wherenixClapis the NixClap instance.parse-fail- when parse failed, emitted with parse result object, which haserrorfield.unknown-option- when an unknown option is found, emitted with option nameunknown-command- when an unknown command is found, emitted with command context, which hasnamefield.no-action- when you have commands withexecand user specified no command that triggered anexeccall.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 emitexitversion- Ifversionhas 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 givenand emitexitexit- callsprocess.exit(code)
Skip Default Event Behaviors
You can remove the default event handlers with one of these approaches:
- With the
removeDefaultHandlersmethod. - By passing in
handlersobject in theconfigfor 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.argvif not specified.version- set the program version. Can also set withversionmethod.help- custom help option setting. Can also set withhelpmethod.usage- usage message. Can also set withusagemethod.cmdUsage- generic usage message for commands. Can also set withcmdUsagemethod.skipExec- If true, will not call commandexechandlers after parse.skipExecDefault- if true, will not call default commandexechandler after parse.- In case you need to do something before invoking the
exechandlers, 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.writehandlers- 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
initmethod.
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
initmethod.
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
initmethod.
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
exechandlers 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.messagewill 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
parsemethod will call this at the end unlessskipExecflag is set.
Return: The number of commands with exec was invoked.
parsed- The parse result object.skipDefault-boolean, iftruethen do not invoke default command'sexechandler when no command withexechandler was given.
runExecAsync(parsed, skipDefault)
async version of runExec
Return: A promise that resolve with the number of commands with exec invoked.
Others
10 months ago
4 years ago
5 years ago
6 years ago
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
9 years ago