import { OptionType } from "../interfaces/CommandOption"; import { ICommand, CommandDefinition } from "../interfaces/Command"; import SubcommandOption from "./SubcommandOption"; import SubcommandGroupOption from "./SubcommandGroupOption"; import CommandOption from "./CommandOption"; import { ArgsResult } from "../Parser"; abstract class Command implements ICommand { name: string; aliases: string[]; options: CommandOption[]; constructor (def: CommandDefinition) { if (typeof def !== 'object') throw new Error('Missing command definition'); if (!def.name) throw new Error('Missing name for command'); this.name = def.name; this.aliases = def.aliases || []; this.options = []; for (const opt of def.options || []) { if (opt instanceof CommandOption) this.options.push(opt); else this.options.push(new CommandOption(opt)); } if (this.options.some(opt => [ OptionType.SUB_COMMAND, OptionType.SUB_COMMAND_GROUP ].includes(opt.type)) && this.options.some(opt => ![ OptionType.SUB_COMMAND, OptionType.SUB_COMMAND_GROUP ].includes(opt.type))) throw new Error('Cannot have subcommand(group)s on the same level as an option'); } abstract execute(message: unknown, args: ArgsResult): Promise; get subcommands (): SubcommandOption[] { return this._subcommands(this.options); } get subcommandGroups (): SubcommandGroupOption[] { return this.options.filter((opt) => opt.type === OptionType.SUB_COMMAND_GROUP); } subcommand (name: string): SubcommandOption | null { name = name.toLowerCase(); return this.subcommands.find((cmd) => cmd.name === name || cmd.aliases.includes(name)) || null; } subcommandGroup (name: string): SubcommandGroupOption | null { name = name.toLowerCase(); return this.subcommandGroups.find((grp) => grp.name === name || grp.aliases.includes(name)) || null; } private _subcommands (options: CommandOption[]): SubcommandOption[] { const subcommands: SubcommandOption[] = []; for (const opt of options) { if (opt.type === OptionType.SUB_COMMAND) subcommands.push(opt); else if (opt.type === OptionType.SUB_COMMAND_GROUP) subcommands.push(...this._subcommands(opt.options)); } return subcommands; } } export { Command }; export default Command;