- Argument
A single positional argument. These are intended to be nested within Command objects, but can also be used standalone.
By default, an
Argument
represents a single, required argument with no validation or preprocessing applied. All of these defaults can be modified.- Preprocessors can validate and modify the argument.
- An
Argument
can be optional, preventing CommandErrors from being thrown for missing values. - Variable arguments (varargs) can be enabled to take in multiple values.
- Command
A text-based command with positional arguments.
A
Command
can be given a set of Arguments (or multiple sets of Arguments), parse strings into an object of values (see Args), and pass those values to a function that runs on command execution.- CommandError ⇐
Error
Error thrown during execution of Argument, Command, and CommandRegistry objects.
Anything thrown in user-provided code (command handlers and argument preprocessors) is wrapped with a
CommandError
. TheCommandError
instance also contains additional context, such as extended error messages and a reference to the Command that threw (if any). This allows callers to do command-specific error handling, if necessary.- SetupError ⇐
Error
Error thrown when setting up Argument, Command, and CommandRegistry objects. These are typically thrown for invalid values, such as passing non-Function values for handler functions.
- CommandRegistry
A registry containing commands. Can take in command strings and delegate them to the appropriate commands.
- Args
An Object of parsed arguments for a command. Matches the format from other argument parsing libraries, such as Yargs.
- Handler ⇒
any
|Promise.<?any>
A function a Command calls when it is executed.
- DefaultHandler ⇒
any
|Promise.<?any>
A function a CommandRegistry can optionally call when it gets an unrecognized command.
NOTE the arguments passed to a
DefaultHandler
function are slightly different than a normal Handler. It gets the string array of command parts instead of a parsed Object of arguments.- ErrorHandler ⇒
any
|Promise.<?any>
A function a Command can optionally use to handle values thrown during execution.
NOTE the arguments passed to an
ErrorHandler
function are slightly different than a normal Handler. It gets the value thrown during execution.- HelpHandler ⇒
any
|Promise.<?any>
A function a CommandRegistry can optionally use for its help command.
NOTE the arguments passed to a
HelpHandler
function are slightly different than a normal Handler. It gets the command map of a CommandRegistry as the second parameter.- Preprocessor ⇒
any
A function a Argument can optionally use to validate and apply preprocessing to an argument.
A single positional argument. These are intended to be nested within Command objects, but can also be used standalone.
By default, an Argument
represents a single, required argument with no
validation or preprocessing applied. All of these defaults can be modified.
- Preprocessors can validate and modify the argument.
- An
Argument
can be optional, preventing CommandErrors from being thrown for missing values. - Variable arguments (varargs) can be enabled to take in multiple values.
Kind: global class
- Argument
- new Argument(name)
- accessor
- builder
- execution
- .parse(args) ⇒
any
|Array.<any>
|Promise.<any>
|Promise.<Array.<any>>
- .usage() ⇒
String
- .parse(args) ⇒
Creates a new Argument
with the given name. This name is used in the
usage text (see usage).
Throws:
SetupError
for non-String or empty String names.
Param | Type | Description |
---|---|---|
name | String |
The name for this Argument . |
Example
function coerceToNumber(val) {
if (!Number.isInteger(val)) throw new Error('not a number!');
return Number.parseInt(val);
}
const arg = new Argument('thing')
.optional(true)
.varargs(true)
.preprocessor(coerceToNumber);
const vals1 = arg.parse('123'); // vals1 = [123]
const vals2 = arg.parse(['1', '9', '5']); // vals2 = [1, 9, 5]
const vals3 = arg.parse(); // vals3 = []
const vals4 = arg.parse(['1', 'hello']); // CommandError thrown, not a number!
const use = arg.usage(); // use = "[thing_1] [thing_2] ... [thing_n]"
Directly get and set async mode for this Argument
. Setting this has the
same effect as calling asynchronous.
Kind: instance property of Argument
Default: false
Category: accessor
See: asynchronous
Directly get and set whether or not this Argument
is optional. Setting
this has the same effect as calling optional.
Kind: instance property of Argument
Default: false
Category: accessor
See: optional
Directly get and set whether or not this Argument
is a varargs argument.
Setting this has the same effect as calling varargs.
Kind: instance property of Argument
Default: false
Category: accessor
See: varargs
Directly get and set the name for this Argument
. Setting this has the
same effect as calling new Argument().
Kind: instance property of Argument
Category: accessor
See: new Argument()
Directly get and set the Preprocessor function for this
Argument
. Setting this has the same effect as calling
preprocess.
Kind: instance property of Argument
Default: null
Category: accessor
See: preprocess
argument.asynchronous(enabled) ⇒ Argument
Enables or disables async mode. In async mode, parse
returns a Promise that fulfills based on parse
execution, instead of returning or throwing. This setting only applies
to this Argument
.
An async Argument
will have its async setting disabled if it is added
to a non-async Command. This is intentional to discourage mixing
sync and async elements.
Kind: instance method of Argument
Returns: Argument
- instance so we can chain calls.
Category: builder
Throws:
SetupError
for non-Boolean values.
Param | Type | Description |
---|---|---|
enabled | Boolean |
true to enable async, false to disable. |
argument.optional(enabled) ⇒ Argument
Sets this Argument
as optional. When an Argument
is optional,
parse will not throw an error when a value is not
provided. NOTE Only the last argument in an argument list may be
optional.
Kind: instance method of Argument
Returns: Argument
- instance so we can chain calls.
Category: builder
Throws:
SetupError
for non-Boolean values.
Param | Type | Description |
---|---|---|
enabled | Boolean |
true for optional, false for required. |
argument.preprocess(func) ⇒ Argument
Sets up a preprocessor function that will be applied to any value that
passes through parse for this Argument
. When called in
the context of a Command, the return value of this preprocessor
will be added to the parsed Args Object. If the preprocessor does
not return anything (return value is undefined
), the value will be
added to Args as-is. Values thrown from this preprocessor will
bubble up with additional context.
Kind: instance method of Argument
Returns: Argument
- instance so we can chain calls.
Category: builder
Throws:
SetupError
for non-Function values.
Param | Type | Description |
---|---|---|
func | Preprocessor |
The preprocessor function. |
argument.varargs(enabled) ⇒ Argument
Enables or disables variable arguments (varargs) for this Argument
.
A varargs Argument
can accept multiple values, and each individual
value will be separately subject to the preprocessor (if one is given).
The first value of a varargs Argument
is required (unless optional is
enabled), but all subsequent values are always optional.
NOTE A varargs Argument
must be the last argument in a set for a
Command.
Kind: instance method of Argument
Returns: Argument
- instance so we can chain calls.
Category: builder
Throws:
SetupError
for non-Boolean values.
Param | Type | Description |
---|---|---|
enabled | Boolean |
true for enabled, false for disabled. |
Parses the given argument(s) using the preprocessor function (if set). If no preprocessor function has been set, this function will still perform basic validation on the argument(s), but will return it(them) as-is.
In async mode, this function returns a Promise that
fulfills with the processed arguments. Any intermediate Promise
is
internally resolved, so the final returned Promise
will resolve to
a processed value. This is particularly useful for varargs.
In varargs mode, the returned (or resolved) value will always be an Array, even if the given argument was a single, non-Array value.
Kind: instance method of Argument
Returns: any
| Array.<any>
- The processed value (or array of values, in varargs
mode).Promise.<any>
| Promise.<Array.<any>>
- in async mode.
Category: execution
Throws:
CommandError
for non-String and non-Array-of-String data.CommandError
for incorrect number of arguments.CommandError
wrapping anything thrown from the preprocessor. Additional context is added where possible, indicating which argument caused the problem and why.
Param | Type | Description |
---|---|---|
args | String | ?Array.<String> |
Argument strings to parse. |
argument.usage() ⇒ String
Generates a human-readable string describing this Argument
. Useful for
building command usage strings from multiple arguments.
- Required
<example>
- Optional
[example]
- Varargs
<example_1> [example_2] ... [example_n]
Kind: instance method of Argument
Returns: String
- A human-readable description of this Argument
.
Category: execution
A text-based command with positional arguments.
A Command
can be given a set of Arguments (or multiple sets of
Arguments), parse strings into an object of values (see Args),
and pass those values to a function that runs on command execution.
Kind: global class
- Command
- new Command()
- instance
- accessor
- builder
- execution
- .execute(parts) ⇒
any
|Promise.<?any>
- .parse(parts) ⇒
Args
|Promise.<Args>
- .usage() ⇒
String
- .execute(parts) ⇒
- static
Creates a new Command
with the given name.
Throws:
SetupError
Missing, empty, or non-String names.
Example
function coerceToNumber(val) {
if (!Number.isInteger(val)) throw new Error('not a number!');
return Number.parseInt(val);
}
const command = new Command('example')
.description('My cool command that adds numbers')
.addArgSet([
new Argument('arg1').preprocess(coerceToNumber),
new Argument('arg2').preprocess(coerceToNumber),
])
.handler((args, arbitrary) => {
const value = args.arg1 + args.arg2;
console.log('Value is', value);
console.log('Also got this from caller:', arbitrary);
return value;
});
const use = command.usage(); // "example <arg1> <arg2>"
const val1 = command.execute('12 34'); // val1 = 46
const val2 = command.execute(['55', '45']); // val2 = 100
const val3 = command.execute('12'); // throws CommandError, missing second argument!
const val4 = command.execute('12 hello'); // throws CommandError, second argument not a number!
Directly access the argument sets for this Command
. This is a read-only
property.
Kind: instance property of Command
Category: accessor
Directly get and set the description for this Command
. Setting this has
the same effect as calling description.
Kind: instance property of Command
Category: accessor
See: description
Directly get and set asynchronous mode for this Command
. Setting this
has the same effect as calling asynchronous.
Kind: instance property of Command
Default: false
Category: accessor
See: asynchronous
Directly get and set the name for this Command
. Subject to the same
validation as new Command().
Kind: instance property of Command
Category: accessor
See: new Command()
command.addArgSet(argset) ⇒ Command
Adds a set of Arguments this Command
can accept.
Arguments are all positional, so this function enforces several rules to
avoid ambiguous command definitions:
- A
Command
cannot have multiple argument sets with the same length. - A
Command
cannot have multiple argument sets with varargs arguments. - Optional arguments must be the last arguments in an argument set.
- A varargs argument must be the last argument in an argument set.
- The argument set containing a varargs argument must be the largest set.
Kind: instance method of Command
Returns: Command
- instance so we can chain calls.
Category: builder
Throws:
SetupError
for non-Array values.SetupError
for Arrays containing non-Argument values.SetupError
if any argument set rule is violated.
Param | Type | Description |
---|---|---|
argset | Array.<Argument> |
Array of Argument objects. |
command.asynchronous(enabled) ⇒ Command
Enables or disables async mode. In async mode, execute
and parse will both return a Promise
that fulfills based on the parse and/or command execution, instead of
returning or throwing. Promises returned from Arguments will also
be automatically resolved before adding them to the Args.
This setting is applied recursively to all Arguments in this
Command
.
Kind: instance method of Command
Returns: Command
- instance so we can chain calls.
Category: builder
Throws:
SetupError
for non-Boolean values.
Param | Type | Description |
---|---|---|
enabled | Boolean |
true to enable async, false to disable. |
command.description(desc) ⇒ Command
Sets the description text for this Command
.
Kind: instance method of Command
Returns: Command
- instance so we can chain calls.
Category: builder
Throws:
SetupError
for non-String values.
Param | Type | Description |
---|---|---|
desc | String |
The description text. |
command.error(func) ⇒ Command
Sets up a handler function for values thrown during command execution.
When this is set, values will not be thrown (or passed to .catch()
in
async mode). Instead, they will be passed to this handler function, along
with all of the arbitrary arguments originally forwarded from
execute. Additionally, values returned from this handler
will be returned to the caller (via .then()
in async mode). Values
thrown within this handler will be re-thrown to the caller as a
CommandError (bubbled up via .catch()
in async mode).
Kind: instance method of Command
Returns: Command
- instance so we can chain calls.
Category: builder
Throws:
SetupError
for non-Function values.
Param | Type | Description |
---|---|---|
func | ErrorHandler |
The error handler function. |
command.handler(func) ⇒ Command
Sets up a handler function when this Command
is executed.
Kind: instance method of Command
Returns: Command
- instance so we can chain calls.
Category: builder
Throws:
SetupError
for non-Function values.
Param | Type | Description |
---|---|---|
func | Handler |
The handler function. |
Executes an argument string (or array) using the handler for this
Command
. Additional arbitrary arguments can be forwarded to the command
handler. Values returned from the handler will be returned from this
function (or bubble up via .then()
in async mode). Values thrown from
the handler will be rethrown from this function (or bubble up via
.catch()
in async mode).
If an ErrorHandler has been set via error, values
thrown from the handler function will be passed to that handler instead
of being rethrown from this function. The error handler is subject to all
of the same conditions as the command handler, so values returned/thrown
from the error handler will be returned/thrown from this function
(or bubble up via .then()
and .catch()
, respectively in async mode).
If this Command
has no handler, the given arguments will still be
processed and validated.
Kind: instance method of Command
Returns: any
- Whatever the handler function returns.Promise.<?any>
- in async mode.
Category: execution
Throws:
CommandError
for all reasons as parse.CommandError
for anything thrown within the handler.
Param | Type | Description |
---|---|---|
parts | String | Array.<String> |
Arguments for this command. Should not include the command's name. |
...forward | Array.<any> |
Arbitrary additional values passed to handler. |
command.parse(parts) ⇒ Args
| Promise.<Args>
Parses the given positional argument array into an Object of values.
This function does its best to match the given values to an appropriate
argument set. Since all arguments are positional, error diagnostics are
limited if this Command
has multiple argument sets defined.
Kind: instance method of Command
Returns: Args
- the parsed Object of arguments.Promise.<Args>
- in async mode.
Category: execution
Throws:
CommandError
if no argument set matches the given parts.CommandError
if any argument preprocessor function throws.
Param | Type | Description |
---|---|---|
parts | Array.<String> |
Array of command parts from split. |
command.usage() ⇒ String
Generates a string describing the usage of this Command
.
If this command has multiple argument sets, each version of the command
is in the string, separated by a newline. If the command has no argument
sets, this just returns the command name.
Kind: instance method of Command
Returns: String
- description of command usage.
Category: execution
Command.split(string) ⇒ Array.<String>
Splits a command string into an array of tokens. This essentially just splits on whitespace.
Kind: static method of Command
Returns: Array.<String>
- Array of command tokens.
Param | Type | Description |
---|---|---|
string | String |
Command string to split. |
CommandError ⇐ Error
Error thrown during execution of Argument, Command, and CommandRegistry objects.
Anything thrown in user-provided code (command handlers and argument
preprocessors) is wrapped with a CommandError
. The CommandError
instance
also contains additional context, such as extended error messages and a
reference to the Command that threw (if any). This allows callers
to do command-specific error handling, if necessary.
Kind: global class
Extends: Error
The Command this CommandError
originated in, if any.
Kind: instance property of CommandError
Default: undefined
A simple flag callers can check to see if an Error
is a CommandError
.
This field is always true
, and is provided only as an alternative to
error instanceof CommandError
.
Kind: instance property of CommandError
The value that was actually thrown in the user code. This could be anything.
Kind: instance property of CommandError
Default: null
Gets this CommandError
's message
combined with nested.message
, if
nested
is an Error. Otherwise, this value is identical
to CommandError#message.
Kind: instance property of CommandError
SetupError ⇐ Error
Error thrown when setting up Argument, Command, and CommandRegistry objects. These are typically thrown for invalid values, such as passing non-Function values for handler functions.
Kind: global class
Extends: Error
A registry containing commands. Can take in command strings and delegate them to the appropriate commands.
Kind: global class
- CommandRegistry
- new CommandRegistry()
- instance
- accessor
- builder
- execution
- .execute(parts) ⇒
any
|Promise.<?any>
- .help(cmd_name) ⇒
any
|Promise.<?any>
- .execute(parts) ⇒
- static
Creates a new CommandRegistry
.
The Map of Command objects. Useful for iterating.
Kind: instance property of CommandRegistry
Category: accessor
Directly get and set asynchronous mode for this CommandRegistry
.
Setting this has the same effect as calling
asynchronous.
Kind: instance property of CommandRegistry
Default: false
Category: accessor
See: asynchronous
Directly get and set the default handler for unrecognized commands for
this CommandRegistry
. Setting this has the same effect as calling
defaultHandler.
Kind: instance property of CommandRegistry
Category: accessor
See: defaultHandler
registry.add(command) ⇒ CommandRegistry
Adds a Command to this CommandRegistry
. All commands must have
unique names. If this CommandRegistry
is in async mode, the
Command
will be switched to async mode too.
Kind: instance method of CommandRegistry
Returns: CommandRegistry
- instance so we can chain calls.
Category: builder
Throws:
SetupError
For non-Command values.SetupError
If theCommandRegistry
already has aCommand
with the given name.
Param | Type | Description |
---|---|---|
command | Command |
The command to add. |
registry.asynchronous(enabled) ⇒ CommandRegistry
Enables or disables async mode for this CommandRegistry
. In async mode,
help and execute will
both return a Promise that fulfills based on the command
execution. This setting is applied recursively to all Commands
and Arguments in this CommandRegistry
.
Kind: instance method of CommandRegistry
Returns: CommandRegistry
- instance so we can chain calls.
Category: builder
Throws:
SetupError
for non-Boolean values.
Param | Type | Description |
---|---|---|
enabled | Boolean |
true to enable async, false to disable. |
registry.defaultHandler(func) ⇒ CommandRegistry
Sets up a handler function for unrecognized commands. If this is not set, unknown commands are a no-op.
NOTE the default handler function signature is slightly different from other handlers (see DefaultHandler).
Kind: instance method of CommandRegistry
Returns: CommandRegistry
- instance so we can chain calls.
Category: builder
Throws:
SetupError
for non-Function values.
Param | Type | Description |
---|---|---|
func | DefaultHandler |
The handler function. If omitted, uses defaultDefaultHandler. |
registry.helpHandler(func) ⇒ CommandRegistry
Sets up a help command using the given HelpHandler function. If this is not set, help commands are treated like unknown commands.
NOTE the help handler function signature is slightly different from other handlers (see HelpHandler).
Kind: instance method of CommandRegistry
Returns: CommandRegistry
- instance so we can chain calls.
Category: builder
Throws:
SetupError
for non-Function values.
Param | Type | Description |
---|---|---|
func | HelpHandler |
The handler function. If omitted, uses defaultHelpHandler. |
Executes a string (or array) as a command. Additional arbitrary arguments
can be forwarded to the command handler, and the value returned from the
command handler will bubble up and return from this function. If this
CommandRegistry
does not have a command matching the given string, this
is either a no-op, or the default command handler is called (if set). If
the given command's name is help
, this call is equivalent to calling
help.
Kind: instance method of CommandRegistry
Returns: any
- Return value forwarded back to caller.Promise.<?any>
- In async mode.
Category: execution
Throws:
CommandError
Wraps anything thrown in handler.
See: Command.execute
Param | Type | Description |
---|---|---|
parts | String | Array.<String> |
A string containing a command, or a pre-split Array of command parts. |
...forward | Array.<any> |
Arbitrary additional values passed to handler. |
Example
// Call a command that adds two numbers
let x = registry.execute('add 12 14'); // x is 26
let x = registry.execute(['add', '10', '20']); // x is 30
// Call a command from a Discord.js message.
// Remember to sanitize your inputs! https://xkcd.com/327/
registry.execute(msg.content, msg);
Executes the help command for this CommandRegistry
. In order for this
function to do anything, helpHandler needs to
be called first to set up a help command. Like
execute, this function can forward additional
arbitrary arguments to the help handler function, and the value returned
from the help handler will bubble up to this function.
Kind: instance method of CommandRegistry
Returns: any
- Return value forwarded back to caller.Promise.<?any>
- In async mode.
Category: execution
Throws:
CommandError
Wraps anything thrown in handler.
Param | Type | Description |
---|---|---|
cmd_name | String |
The name of a command to request help for. In order to omit this value while providing forwarded arguments, pass in a falsy value, like null . |
...forward | Array.<any> |
Arbitrary additional values passed to handler. |
Example
registry.help();
registry.help('say');
registry.help('say', msg);
registry.help(null, msg);
An optional default handler for unrecognized commands. Simply throws an error.
Kind: static method of CommandRegistry
Throws:
Error
Always
See: DefaultHandler
Param | Type | Description |
---|---|---|
cmd_parts | Array.<String> |
Array of command parts from split. |
CommandRegistry.defaultHelpHandler(args, commands) ⇒ String
An optional default handler for the help command. Returns the usage for the given command, according to its usage function. If no command name is given, returns the usage for all known commands, separated by newlines.
Kind: static method of CommandRegistry
Returns: String
- Description of the given command, or all known
commands.
See: HelpHandler
Param | Type | Description |
---|---|---|
args | Args |
Argument Object containing at least command . |
commands | Map.<Command> |
The Map of Commands in the registry. |
An Object of parsed arguments for a command. Matches the format from other argument parsing libraries, such as Yargs.
Kind: global typedef
Example
{
_: ['my', 'cool', 'args'],
arg1: 'my',
arg2: 'cool',
arg3: 'args',
vararg1: ['thing1', 'thing2'],
}
A function a Command calls when it is executed.
Kind: global typedef
Returns: any
- Return value forwarded back to caller.Promise.<?any>
- In async mode.
Throws:
any
Anything the user code wants to throw. This value will be captured and re-thrown as a CommandError.
Param | Type | Description |
---|---|---|
args | Args |
The Object of parsed arguments. |
...forward | Array.<any> |
Arbitrary additional values. |
Example
// Adds two numbers together and replies to a Discord.js message
function myHandler(args, message) {
const val = args.val1 + args.val2;
return message.reply('Result is ' + val);
}
A function a CommandRegistry can optionally call when it gets an unrecognized command.
NOTE the arguments passed to a DefaultHandler
function are slightly
different than a normal Handler. It gets the string array of command
parts instead of a parsed Object of arguments.
Kind: global typedef
Returns: any
- Return value forwarded back to caller.Promise.<?any>
- In async mode.
Throws:
any
Anything the user code wants to throw. This value will be captured and re-thrown as a CommandError.
Param | Type | Description |
---|---|---|
cmd_parts | Array.<String> |
Array of command parts from split. |
...forward | Array.<any> |
Arbitrary additional values passed into CommandRegistry.execute. |
Example
// Replying to a Discord.js message
function myDefaultHandler(cmd_parts, message) {
return message.reply('Unrecognized command ' + cmd_parts.shift());
}
A function a Command can optionally use to handle values thrown during execution.
NOTE the arguments passed to an ErrorHandler
function are slightly
different than a normal Handler. It gets the value thrown during
execution.
Kind: global typedef
Returns: any
- Return value forwarded back to caller.Promise.<?any>
- In async mode.
Throws:
any
Anything the user code wants to throw. This value will be captured and re-thrown as a CommandError.
Param | Type | Description |
---|---|---|
value | any |
Value thrown during command execution. |
...forward | Array.<any> |
Arbitrary additional values passed into Command.execute. |
Example
// Replying to a Discord.js message with the error
function myErrorHandler(err, message) {
return message.reply('Command failed: ' + err.message);
}
A function a CommandRegistry can optionally use for its help command.
NOTE the arguments passed to a HelpHandler
function are slightly
different than a normal Handler. It gets the command map of a
CommandRegistry as the second parameter.
Kind: global typedef
Returns: any
- Return value forwarded back to caller.Promise.<?any>
- In async mode.
Throws:
any
Anything the user code wants to throw. This value will be captured and re-thrown as a CommandError.
Param | Type | Description |
---|---|---|
args | Args |
Argument Object containing the following: - command - The command name. |
commands | Map.<Command> |
The CommandRegistry 's Map of commands. |
...forward | Array.<any> |
Arbitrary additional values passed into CommandRegistry.execute. |
Example
// Replying to a Discord.js message
function myHelpHandler(args, commands, message) {
return message.reply(commands.get(args.command).usage());
}
A function a Argument can optionally use to validate and apply preprocessing to an argument.
Kind: global typedef
Returns: any
- The final value returned from Argument.parse.
Throws:
any
Anything the user code wants to throw. This value will be captured and re-thrown as a CommandError.
Param | Type | Description |
---|---|---|
value | String |
The string representation of an argument. |
Example
function coerceToNumber(value) {
if (!Number.isInteger(val)) throw new Error('not a number!');
return Number.parseInt(val);
}