Compare commits
3 Commits
57313488b4
...
fb46e09d70
Author | SHA1 | Date | |
---|---|---|---|
fb46e09d70 | |||
3a4eb4be6f | |||
1d8aa751b9 |
41
README.md
41
README.md
@ -1,3 +1,40 @@
|
|||||||
A command parser for Discord bots. Should work with any JS library.
|
A command parser initially made for quickly making discord bots, but works as a standalone parser too.
|
||||||
|
|
||||||
You're expected to implement a string -> abstraction resolver yourself and pass it to the parser.
|
Your commands are expected to inherit from the Command class
|
||||||
|
|
||||||
|
**Example usage**
|
||||||
|
```js
|
||||||
|
|
||||||
|
const commands: Command[] = [
|
||||||
|
new Command({
|
||||||
|
name: 'ping',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'respond', //
|
||||||
|
type: OptionType.BOOLEAN, // Boolean type expects the parser to have some kind of string -> boolean resolver, see the resolver interface for which methods are expected
|
||||||
|
required: true, // Will throw error if not provided
|
||||||
|
defaultValue: true, // The value that will be given back if no value is given, or if option is required but not provided
|
||||||
|
flag: true // The parser will look for the option in the "--respond value" form
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
]; // Command definitions
|
||||||
|
|
||||||
|
const parser = new Parser({commands, prefix: ''}); // Empty prefix
|
||||||
|
const parsed = await parser.parseMessage('ping --respond');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parsed will be an object cotaining properties args, command, subcommand, and subcommandgroup
|
||||||
|
* the args property is an object of the given options mapped by their names, e.g.
|
||||||
|
* {
|
||||||
|
* respond: {
|
||||||
|
* ... properties,
|
||||||
|
* value: true
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Some of the option types have built-in parsers (e.g. numbers, strings), but others will require the resolver implementation, and in some cases CommandOption extensions.
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@navy.gif/commandparser",
|
"name": "@navy.gif/commandparser",
|
||||||
"version": "1.5.0",
|
"version": "1.5.1",
|
||||||
"description": "Parser meant to parse commands and their options for discord bots",
|
"description": "Parser meant to parse commands and their options for discord bots",
|
||||||
"author": "Navy.gif",
|
"author": "Navy.gif",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
@ -23,7 +23,8 @@ type ParserOptions = {
|
|||||||
commands: Iterable<Command>,
|
commands: Iterable<Command>,
|
||||||
prefix?: string,
|
prefix?: string,
|
||||||
debug?: boolean,
|
debug?: boolean,
|
||||||
resolver?: IResolver<unknown, unknown, unknown, unknown, unknown>
|
resolver?: IResolver<unknown, unknown, unknown, unknown, unknown>,
|
||||||
|
allowDefaultOnRequired?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
type ParseOptions = {
|
type ParseOptions = {
|
||||||
@ -39,14 +40,12 @@ const flagReg = /(?:^| )(?<flag>(?:--[a-z0-9]{3,})|(?:-[a-z]{1,2}))(?:$| )/iu;
|
|||||||
class Parser extends EventEmitter {
|
class Parser extends EventEmitter {
|
||||||
|
|
||||||
private commands: ExtendedMap<string, Command>;
|
private commands: ExtendedMap<string, Command>;
|
||||||
|
|
||||||
private _debug = false;
|
private _debug = false;
|
||||||
|
|
||||||
prefix: string;
|
prefix: string;
|
||||||
|
|
||||||
resolver?: IResolver<unknown, unknown, unknown, unknown, unknown>;
|
resolver?: IResolver<unknown, unknown, unknown, unknown, unknown>;
|
||||||
|
allowDefaultOnRequired: boolean;
|
||||||
|
|
||||||
constructor ({ commands, prefix, debug = false, resolver }: ParserOptions) {
|
constructor ({ commands, prefix, debug = false, resolver, allowDefaultOnRequired }: ParserOptions) {
|
||||||
|
|
||||||
super();
|
super();
|
||||||
|
|
||||||
@ -57,6 +56,7 @@ class Parser extends EventEmitter {
|
|||||||
this.resolver = resolver;
|
this.resolver = resolver;
|
||||||
|
|
||||||
this.prefix = prefix || '';
|
this.prefix = prefix || '';
|
||||||
|
this.allowDefaultOnRequired = allowDefaultOnRequired ?? true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,10 +311,17 @@ class Parser extends EventEmitter {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
this.debug(`Making sure required options were given.`);
|
this.debug(`Making sure required options were given.`);
|
||||||
for (const req of options.filter((opt) => opt.required))
|
for (const req of options.filter((opt) => opt.required)) {
|
||||||
if (!args[req.name])
|
if (!args[req.name]) {
|
||||||
|
if (req.defaultValue === null || !this.allowDefaultOnRequired)
|
||||||
throw new ParseError(`${req.name} is a required option`);
|
throw new ParseError(`${req.name} is a required option`);
|
||||||
|
|
||||||
|
const opt = req.clone();
|
||||||
|
opt.value = req.defaultValue;
|
||||||
|
args[req.name] = opt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (strings.length)
|
if (strings.length)
|
||||||
throw new ParseError(`Unrecognised option(s): "${strings.join('", "')}"`);
|
throw new ParseError(`Unrecognised option(s): "${strings.join('", "')}"`);
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ class CommandOption implements ICommandOption {
|
|||||||
value?: unknown;
|
value?: unknown;
|
||||||
aliased = false;
|
aliased = false;
|
||||||
strict: boolean;
|
strict: boolean;
|
||||||
private resolver?: IResolver<unknown, unknown, unknown, unknown, unknown>|undefined;
|
private resolver?: IResolver | undefined;
|
||||||
|
|
||||||
constructor (def: CommandOptionDefinition|CommandOption|ICommandOption) {
|
constructor (def: CommandOptionDefinition|CommandOption|ICommandOption) {
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ class CommandOption implements ICommandOption {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clone (rawValue?: string[], resolver?: IResolver<unknown, unknown, unknown, unknown, unknown>): CommandOption {
|
clone (rawValue?: string[], resolver?: IResolver): CommandOption {
|
||||||
const opt = new CommandOption(this);
|
const opt = new CommandOption(this);
|
||||||
opt.rawValue = rawValue;
|
opt.rawValue = rawValue;
|
||||||
opt.resolver = resolver;
|
opt.resolver = resolver;
|
||||||
|
@ -130,7 +130,7 @@ interface ICommandOption {
|
|||||||
|
|
||||||
// private _options?: CommandOptionDefinition
|
// private _options?: CommandOptionDefinition
|
||||||
|
|
||||||
clone(rawValue?: string[], resolver?: IResolver<unknown, unknown, unknown, unknown, unknown>): CommandOption
|
clone(rawValue?: string[], resolver?: IResolver): CommandOption
|
||||||
|
|
||||||
parse(guild: unknown): Promise<ParseResult>
|
parse(guild: unknown): Promise<ParseResult>
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
interface IResolver <User, Member, Channel, Role, Guild> {
|
interface IResolver {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should resolve to a user abstraction
|
* Should resolve to a user abstraction
|
||||||
@ -8,7 +8,7 @@ interface IResolver <User, Member, Channel, Role, Guild> {
|
|||||||
* @return {User} {User}
|
* @return {User} {User}
|
||||||
* @memberof IResolver
|
* @memberof IResolver
|
||||||
*/
|
*/
|
||||||
resolveUser(resolveable: string, strict?: boolean): Promise<User | null>
|
resolveUser<User>(resolveable: string, strict?: boolean): Promise<User | null>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should resolve to a member abstraction
|
* Should resolve to a member abstraction
|
||||||
@ -19,7 +19,7 @@ interface IResolver <User, Member, Channel, Role, Guild> {
|
|||||||
* @return {Member} {Member}
|
* @return {Member} {Member}
|
||||||
* @memberof IResolver
|
* @memberof IResolver
|
||||||
*/
|
*/
|
||||||
resolveMember(resolveable: string, strict: boolean, guild: Guild): Promise<Member | null>
|
resolveMember<Guild, Member>(resolveable: string, strict: boolean, guild: Guild): Promise<Member | null>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should resolve to a role abstraction
|
* Should resolve to a role abstraction
|
||||||
@ -30,7 +30,7 @@ interface IResolver <User, Member, Channel, Role, Guild> {
|
|||||||
* @return {Channel} {Channel}
|
* @return {Channel} {Channel}
|
||||||
* @memberof IResolver
|
* @memberof IResolver
|
||||||
*/
|
*/
|
||||||
resolveChannel(resolveable: string, strict: boolean, guild: Guild): Promise<Channel | null>
|
resolveChannel<Guild, Channel>(resolveable: string, strict: boolean, guild: Guild): Promise<Channel | null>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should resolve to a role abstraction
|
* Should resolve to a role abstraction
|
||||||
@ -41,7 +41,7 @@ interface IResolver <User, Member, Channel, Role, Guild> {
|
|||||||
* @return {Role} {Role}
|
* @return {Role} {Role}
|
||||||
* @memberof IResolver
|
* @memberof IResolver
|
||||||
*/
|
*/
|
||||||
resolveRole(resolveable: string, strict: boolean, guild: Guild): Promise<Role | null>
|
resolveRole<Guild, Role>(resolveable: string, strict: boolean, guild: Guild): Promise<Role | null>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should resolve to true when a truthy resolveable is passed, i.e. yes, true, on etc
|
* Should resolve to true when a truthy resolveable is passed, i.e. yes, true, on etc
|
||||||
|
Loading…
Reference in New Issue
Block a user