2023-04-16 16:37:46 +02:00
|
|
|
import { OptionType } from "../interfaces/CommandOption.js";
|
|
|
|
import { ICommand, CommandDefinition } from "../interfaces/Command.js";
|
|
|
|
import SubcommandOption from "./SubcommandOption.js";
|
|
|
|
import SubcommandGroupOption from "./SubcommandGroupOption.js";
|
|
|
|
import CommandOption from "./CommandOption.js";
|
|
|
|
import { ArgsResult } from "../Parser.js";
|
2022-07-28 21:06:11 +02:00
|
|
|
|
2022-07-29 19:37:34 +02:00
|
|
|
abstract class Command implements ICommand {
|
2022-07-28 21:06:11 +02:00
|
|
|
|
|
|
|
name: string;
|
|
|
|
aliases: string[];
|
2022-07-29 13:16:43 +02:00
|
|
|
options: CommandOption[];
|
2022-07-28 21:06:11 +02:00
|
|
|
|
2023-04-13 19:18:40 +02:00
|
|
|
constructor (def: CommandDefinition) {
|
2022-07-28 21:06:11 +02:00
|
|
|
|
2023-04-13 19:18:40 +02:00
|
|
|
if (typeof def !== 'object')
|
|
|
|
throw new Error('Missing command definition');
|
2023-02-12 17:08:52 +01:00
|
|
|
|
2023-04-13 19:18:40 +02:00
|
|
|
if (!def.name)
|
|
|
|
throw new Error('Missing name for command');
|
2022-07-28 21:06:11 +02:00
|
|
|
this.name = def.name;
|
|
|
|
|
|
|
|
this.aliases = def.aliases || [];
|
|
|
|
|
2023-05-05 16:32:29 +02:00
|
|
|
// Add a built-in help flag to any non-subcommand option
|
|
|
|
this.options = [
|
|
|
|
new CommandOption({
|
|
|
|
name: 'help',
|
|
|
|
type: OptionType.BOOLEAN,
|
|
|
|
flag: true,
|
|
|
|
valueOptional: true,
|
|
|
|
defaultValue: true
|
|
|
|
})
|
|
|
|
];
|
|
|
|
|
2022-07-29 17:47:45 +02:00
|
|
|
for (const opt of def.options || []) {
|
2023-04-13 19:18:40 +02:00
|
|
|
if (opt instanceof CommandOption)
|
|
|
|
this.options.push(opt);
|
|
|
|
else
|
|
|
|
this.options.push(new CommandOption(opt));
|
2022-07-29 17:47:45 +02:00
|
|
|
}
|
2023-05-05 16:32:29 +02:00
|
|
|
|
2023-04-13 19:18:40 +02:00
|
|
|
if (this.options.some(opt => [ OptionType.SUB_COMMAND, OptionType.SUB_COMMAND_GROUP ].includes(opt.type))
|
2023-05-05 16:32:29 +02:00
|
|
|
&& this.options.some(opt => ![ OptionType.SUB_COMMAND, OptionType.SUB_COMMAND_GROUP ].includes(opt.type) && opt.name !== 'help'))
|
2023-04-13 19:18:40 +02:00
|
|
|
throw new Error('Cannot have subcommand(group)s on the same level as an option');
|
2022-07-28 21:06:11 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-04-16 15:43:27 +02:00
|
|
|
abstract execute(message: unknown, args?: ArgsResult): Promise<unknown>;
|
2022-07-29 19:37:34 +02:00
|
|
|
|
2023-04-13 19:18:40 +02:00
|
|
|
get subcommands (): SubcommandOption[] {
|
2022-07-28 21:06:11 +02:00
|
|
|
return this._subcommands(this.options);
|
|
|
|
}
|
|
|
|
|
2023-04-13 19:18:40 +02:00
|
|
|
get subcommandGroups (): SubcommandGroupOption[] {
|
2022-07-28 21:06:11 +02:00
|
|
|
return this.options.filter((opt) => opt.type === OptionType.SUB_COMMAND_GROUP);
|
|
|
|
}
|
|
|
|
|
2023-04-13 19:18:40 +02:00
|
|
|
subcommand (name: string): SubcommandOption | null {
|
2022-07-28 21:06:11 +02:00
|
|
|
name = name.toLowerCase();
|
2023-02-12 15:30:54 +01:00
|
|
|
return this.subcommands.find((cmd) => cmd.name === name || cmd.aliases.includes(name)) || null;
|
2022-07-28 21:06:11 +02:00
|
|
|
}
|
|
|
|
|
2023-04-13 19:18:40 +02:00
|
|
|
subcommandGroup (name: string): SubcommandGroupOption | null {
|
2022-07-28 21:06:11 +02:00
|
|
|
name = name.toLowerCase();
|
2023-02-12 15:30:54 +01:00
|
|
|
return this.subcommandGroups.find((grp) => grp.name === name || grp.aliases.includes(name)) || null;
|
2022-07-28 21:06:11 +02:00
|
|
|
}
|
|
|
|
|
2023-04-13 19:18:40 +02:00
|
|
|
private _subcommands (options: CommandOption[]): SubcommandOption[] {
|
2022-07-28 21:06:11 +02:00
|
|
|
const subcommands: SubcommandOption[] = [];
|
|
|
|
for (const opt of options) {
|
2023-04-13 19:18:40 +02:00
|
|
|
if (opt.type === OptionType.SUB_COMMAND)
|
|
|
|
subcommands.push(opt);
|
|
|
|
else if (opt.type === OptionType.SUB_COMMAND_GROUP)
|
|
|
|
subcommands.push(...this._subcommands(opt.options));
|
2022-07-28 21:06:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return subcommands;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export { Command };
|
|
|
|
export default Command;
|