UNPKG

commandbot

Version:

A framework that helps you create your own Discord bot easier.

301 lines (300 loc) 13.9 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ChatCommand = void 0; const discord_js_1 = require("discord.js"); const Parameter_js_1 = require("../structures/Parameter.js"); const commandsTypes_js_1 = require("./commandsTypes.js"); const PermissionGuildCommand_js_1 = require("./base/PermissionGuildCommand.js"); const generateUsageFromArguments_js_1 = require("../utils/generateUsageFromArguments.js"); const SubCommand_js_1 = require("./SubCommand.js"); const SubCommandGroup_js_1 = require("./SubCommandGroup.js"); const state_js_1 = require("../state.js"); const InputManager_js_1 = require("../structures/InputManager.js"); /** * A representation of CHAT_INPUT command (also known as a slash command) * @class * @extends {PermissionGuildCommand} */ class ChatCommand extends PermissionGuildCommand_js_1.PermissionGuildCommand { /** * ChatCommand constructor * @constructor * @param {CommandManager} manager - a manager that this command belongs to * @param {ChatCommandInit} options - {@link ChatCommandInit} object containing all options needed to create a {@link ChatCommand} */ constructor(manager, options) { var _a, _b; super(manager, "CHAT", { name: options.name, function: options.function, announceSuccess: options.announceSuccess, guilds: options.guilds, permissions: options.permissions, dm: options.dm, ephemeral: options.ephemeral, }); /** * Subcommands and groups of this command * @type {Array<ChildCommandResolvable>} * @private * @readonly */ this._children = []; if (options.parameters == "no_input" || !options.parameters) { this.parameters = []; } else if (options.parameters == "simple") { this.parameters = [new Parameter_js_1.DefaultParameter(this)]; } else { this.parameters = options.parameters.map((ps) => new Parameter_js_1.Parameter(this, ps)); } this.aliases = options.aliases ? (Array.isArray(options.aliases) ? options.aliases : [options.aliases]) : undefined; this.description = (_a = options.description) !== null && _a !== void 0 ? _a : "No description"; this.usage = (_b = options.usage) !== null && _b !== void 0 ? _b : (0, generateUsageFromArguments_js_1.generateUsageFromArguments)(this); this.visible = options.visible !== undefined ? options.visible : true; this.slash = options.slash !== undefined ? options.slash : true; if (!commandsTypes_js_1.CommandRegExps.chatName.test(this.name)) { throw new Error(`"${this.name}" is not a valid command name (regexp: ${commandsTypes_js_1.CommandRegExps.chatName})`); } if (this.description && !commandsTypes_js_1.CommandRegExps.chatDescription.test(this.description)) { throw new Error(`The description of "${this.name}" doesn't match the regular expression ${commandsTypes_js_1.CommandRegExps.chatDescription}`); } if (this.aliases) { if (Array.isArray(this.aliases)) { this.aliases.map((a) => { if (!commandsTypes_js_1.CommandRegExps.chatName.test(a)) { throw new Error(`"${a}" is not a valid alias name (regexp: ${commandsTypes_js_1.CommandRegExps.chatName})`); } }); } else { if (!commandsTypes_js_1.CommandRegExps.chatName.test(this.aliases)) { throw new Error(`"${this.aliases}" is not a valid alias name (regexp: ${commandsTypes_js_1.CommandRegExps.chatName})`); } } } if (this.aliases && this.aliases.length > 0 && this.aliases.find((a) => this.manager.get(a, this.type))) { throw new Error(`One of aliases from "${this.name}" command is already a registered name in the manager and cannot be reused.`); } } /** * Returns *true* if the command has subcommands attached * @type {boolean} */ get hasSubCommands() { return this._children.length > 0; } /** * Returns list of attached subcommands * @type {Array<ChildCommandResolvable>} * @readonly */ get children() { return Object.freeze([...this._children]); } /** * Invoke the command * @param {InputManager} input - input data manager * @returns {Promise<void>} * @public * @async */ start(input) { const _super = Object.create(null, { start: { get: () => super.start } }); return __awaiter(this, void 0, void 0, function* () { if (!this.slash && input.interaction instanceof discord_js_1.Interaction) { throw new Error("This command is not available as a slash command"); } yield _super.start.call(this, input); }); } /** * Attaches subcommand or subcommand group to this ChatCommand * @param {T} type - subcommand type * @param {ChildCommandInit<T>} options - initialization options * @returns {ChildCommands<T>} A computed subcommand object * @public * @remarks After appending a subcommand or a subcommand group the main command can only be invoked using prefix interactions */ append(type, options) { const command = type === "COMMAND" ? new SubCommand_js_1.SubCommand(this, options) : type === "GROUP" ? new SubCommandGroup_js_1.SubCommandGroup(this, options) : null; if (!command) { throw new Error("Incorrect command type"); } if (state_js_1.applicationState.running) { console.warn(`[❌ ERROR] Cannot add command "${command.name}" while the application is running.`); return command; } this._children.push(command); return command; } /** * * @param {Array<CommandInteractionOption>} options - parameter options * @param {Interaction | Message} interaction - Discord interaction * @returns {?InputManager} an {@link InputManager} containing all interaction-related data or *null* * @public */ fetchSubcommand(options, interaction) { if (!this.hasSubCommands) return null; if (options[0]) { if (options[0].type === "SUB_COMMAND_GROUP") { const grName = options[0].name; const group = this._children.filter((c) => c instanceof SubCommandGroup_js_1.SubCommandGroup).find((c) => c.name === grName); const scOpt = options[0].options; if (group && scOpt) { const scName = scOpt[0].name; const cmd = group.children.filter((c) => c instanceof SubCommand_js_1.SubCommand).find((c) => c.name === scName); if (cmd && scOpt[0].options) { return new InputManager_js_1.InputManager(cmd, interaction, cmd.parameters.map((p, index) => { var _a, _b, _c, _d, _e, _f; if (p.type === "user" || p.type === "role" || p.type === "channel" || p.type === "mentionable") { return new Parameter_js_1.InputParameter(p, new Parameter_js_1.ObjectID((_c = (_b = (_a = scOpt[0].options) === null || _a === void 0 ? void 0 : _a[index].value) === null || _b === void 0 ? void 0 : _b.toString()) !== null && _c !== void 0 ? _c : "", p.type, (_d = interaction.guild) !== null && _d !== void 0 ? _d : undefined)); } else { return new Parameter_js_1.InputParameter(p, (_f = (_e = scOpt[0].options) === null || _e === void 0 ? void 0 : _e[index].value) !== null && _f !== void 0 ? _f : null); } })); } else { return null; } } else { return null; } } else if (options[0].type === "SUB_COMMAND") { const cmd = this._children.filter((c) => c instanceof SubCommand_js_1.SubCommand).find((c) => c.name === options[0].name); if (cmd) { return new InputManager_js_1.InputManager(cmd, interaction, cmd.parameters.map((p, index) => { var _a, _b, _c, _d, _e, _f; if (p.type === "user" || p.type === "role" || p.type === "channel" || p.type === "mentionable") { return new Parameter_js_1.InputParameter(p, new Parameter_js_1.ObjectID((_c = (_b = (_a = options[0].options) === null || _a === void 0 ? void 0 : _a[index].value) === null || _b === void 0 ? void 0 : _b.toString()) !== null && _c !== void 0 ? _c : "", p.type, (_d = interaction.guild) !== null && _d !== void 0 ? _d : undefined)); } else { return new Parameter_js_1.InputParameter(p, (_f = (_e = options[0].options) === null || _e === void 0 ? void 0 : _e[index].value) !== null && _f !== void 0 ? _f : null); } })); } else { return null; } } else { return null; } } else { return null; } } /** * * @param {string} name - subcommand name * @param {?string} [group] - name of the group (if any) * @returns {?SubCommand} a {@link SubCommand} object or *null* */ getSubcommand(name, group) { if (!this.hasSubCommands) return null; if (group) { const gr = this._children.filter((c) => c instanceof SubCommandGroup_js_1.SubCommandGroup).find((g) => g.name === group); if (gr) { return gr.children.find((c) => c.name === name) || null; } else { return null; } } else { return this._children.filter((c) => c instanceof SubCommand_js_1.SubCommand).find((c) => c.name === name) || null; } } /** * Converts {@link ChatCommand} instance to object that is recognized by the Discord API * @returns {ChatCommandObject} Discord API object * @public */ toObject() { const obj = Object.assign(Object.assign({}, super.toObject()), { type: 1, description: this.description }); let options = []; if (this.parameters) { options = this.parameters .map((p) => { let type = 3; switch (p.type) { case "boolean": type = 5; break; case "user": type = 6; break; case "channel": type = 7; break; case "role": type = 8; break; case "mentionable": type = 9; break; case "number": type = 10; break; case "target": throw new Error(`"target" parameter cannot be used in chat commands`); default: type = 3; break; } const choices = []; if (p.choices) { p.choices.map((c) => { choices.push({ name: c, value: c }); }); } const optionObj = { name: p.name, description: p.description, required: !p.optional, type: p.choices ? 3 : type, choices: choices.length > 0 ? choices : undefined, }; return optionObj; }) .sort((a, b) => { if (a.required && !b.required) { return -1; } else if (a.required && b.required) { return 0; } else if (!a.required && b.required) { return 1; } return 0; }); obj.options = this.hasSubCommands ? this._children.map((sc) => sc.toObject()) : options; } return obj; } } exports.ChatCommand = ChatCommand;