Skip to content

Latest commit

 

History

History
1082 lines (842 loc) · 47.8 KB

API.md

File metadata and controls

1082 lines (842 loc) · 47.8 KB

Classes

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.

CommandErrorError

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.

SetupErrorError

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.

Typedefs

Args

An Object of parsed arguments for a command. Matches the format from other argument parsing libraries, such as Yargs.

Handlerany | Promise.<?any>

A function a Command calls when it is executed.

DefaultHandlerany | 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.

ErrorHandlerany | 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.

HelpHandlerany | 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.

Preprocessorany

A function a Argument can optionally use to validate and apply preprocessing to an argument.

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

new Argument(name)

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]"

argument.is_async

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

argument.is_optional

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

argument.is_varargs

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

argument.name

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()

argument.preprocessor

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:

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:

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:

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:

Param Type Description
enabled Boolean true for enabled, false for disabled.

argument.parse(args) ⇒ any | Array.<any> | Promise.<any> | Promise.<Array.<any>>

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

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.

Kind: global class

new Command()

Creates a new Command with the given name.

Throws:

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!

command.argsets

Directly access the argument sets for this Command. This is a read-only property.

Kind: instance property of Command
Category: accessor

command.desc

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

command.is_async

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

command.name

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:

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:

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:

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:

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:

Param Type Description
func Handler The handler function.

command.execute(parts) ⇒ any | Promise.<?any>

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:

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:

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

err.command

The Command this CommandError originated in, if any.

Kind: instance property of CommandError
Default: undefined

err.is_command_error

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

err.nested

The value that was actually thrown in the user code. This could be anything.

Kind: instance property of CommandError
Default: null

err.full_message

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

CommandRegistry

A registry containing commands. Can take in command strings and delegate them to the appropriate commands.

Kind: global class

new CommandRegistry()

Creates a new CommandRegistry.

registry.commands

The Map of Command objects. Useful for iterating.

Kind: instance property of CommandRegistry
Category: accessor

registry.is_async

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

registry.default_handler

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 the CommandRegistry already has a Command 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:

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:

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:

Param Type Description
func HelpHandler The handler function. If omitted, uses defaultHelpHandler.

registry.execute(parts) ⇒ any | Promise.<?any>

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:

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);

registry.help(cmd_name) ⇒ any | Promise.<?any>

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:

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);

CommandRegistry.defaultDefaultHandler(cmd_parts)

An optional default handler for unrecognized commands. Simply throws an error.

Kind: static method of CommandRegistry
Throws:

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.

Args

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'],
}

Handler ⇒ any | Promise.<?any>

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);
}

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.

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());
}

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.

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);
}

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.

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());
}

Preprocessor ⇒ any

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);
}