From 4724f18fdca2059fc6c7f283092dd77453f39e5c Mon Sep 17 00:00:00 2001 From: GRZ4NA Date: Wed, 8 Sep 2021 22:21:19 +0200 Subject: [PATCH] removed InputParameter + fixed all related errors --- index.ts | 7 +- src/commands/BaseCommand.ts | 17 ++--- src/commands/ChatCommand.ts | 6 +- src/commands/CommandManager.ts | 2 +- src/commands/types/BaseCommand.ts | 7 +- src/commands/types/ChatCommand.ts | 11 +-- src/commands/types/commands.ts | 2 +- src/errors.ts | 2 +- src/structures/Bot.ts | 108 ++++++++++++++---------------- src/structures/Parameter.ts | 85 +---------------------- src/structures/types/Parameter.ts | 2 +- 11 files changed, 70 insertions(+), 179 deletions(-) diff --git a/index.ts b/index.ts index 9cabefc..ab0141f 100644 --- a/index.ts +++ b/index.ts @@ -7,7 +7,7 @@ import { ChatCommandInit } from "./src/commands/types/ChatCommand.js"; import { HelpMessageParams } from "./src/commands/types/HelpMessage.js"; import { ParameterResolvable, ParameterType, ParameterSchema } from "./src/structures/types/Parameter.js"; import { SystemMessageAppearance, SystemMessageData } from "./src/structures/types/SystemMessage.js"; -import { ObjectID, InputParameter, StringParameter, BooleanParameter, NumberParameter, ObjectParameter, Parameter } from "./src/structures/Parameter.js"; +import { ObjectID, Parameter } from "./src/structures/parameter.js"; import { PermissionsError, ParameterTypeError, MissingParameterError, OperationSuccess } from "./src/errors.js"; import { CommandInteractionData } from "./src/commands/types/commands.js"; @@ -28,11 +28,6 @@ export { SystemMessageData, ParameterSchema, Parameter, - InputParameter, - StringParameter, - BooleanParameter, - NumberParameter, - ObjectParameter, PermissionsError, ParameterTypeError, MissingParameterError, diff --git a/src/commands/BaseCommand.ts b/src/commands/BaseCommand.ts index e67b34c..d4165b4 100644 --- a/src/commands/BaseCommand.ts +++ b/src/commands/BaseCommand.ts @@ -1,11 +1,12 @@ import { Interaction, Message, Permissions, ReplyMessageOptions, MessageEmbed, GuildMember } from "discord.js"; import { PermissionCheckTypes } from "./types/permissions.js"; import { CommandType, BaseCommandInit, CommandFunction } from "./types/BaseCommand.js"; -import { InputParameter } from "../structures/Parameter.js"; import { OperationSuccess, PermissionsError } from "../errors.js"; import { BaseCommandObject } from "../structures/types/api.js"; import { ChatCommand } from "./ChatCommand.js"; import { MessageCommand } from "./MessageCommand.js"; +import { ParameterResolvable } from "../structures/types/Parameter.js"; +import { TargetID } from "../structures/parameter.js"; export class BaseCommand { /** @@ -96,13 +97,13 @@ export class BaseCommand { * @param {InputParameter[]} [cmdParams] - list of processed parameters passed in a Discord interaction * @returns {Promise} */ - public async start(interaction: Message | Interaction, args?: InputParameter[]): Promise { - if (interaction instanceof Interaction && !interaction.isCommand() && !interaction.isContextMenu()) return; + public async start(args: ReadonlyMap | TargetID, interaction: Message | Interaction): Promise { + if (interaction instanceof Interaction && !interaction.isCommand() && !interaction.isContextMenu()) throw new TypeError(`Interaction not recognized`); if (this.permissionChecker(interaction)) { if (interaction instanceof Interaction) { await interaction.deferReply(); } - await this.handleReply(interaction, await this.function.call(this, interaction, this.createAccessor(args || []))); + await this.handleReply(interaction, await this.function(args, interaction)); } else { throw new PermissionsError(this, interaction.member as GuildMember); } @@ -121,14 +122,8 @@ export class BaseCommand { return obj; } - private createAccessor(args: InputParameter[]) { - return function (query: string, returnType?: "value" | "object") { - return returnType === "object" ? args.find((p) => p.name === query) || null : args.find((p) => p.name === query)?.value || null; - }; - } - private async handleReply(interaction: Message | Interaction, result: void | string | MessageEmbed | ReplyMessageOptions) { - if (interaction instanceof Interaction && !interaction.isCommand() && !interaction.isContextMenu()) return null; + if (interaction instanceof Interaction && !interaction.isCommand() && !interaction.isContextMenu()) throw new TypeError(`Interaction not recognized`); if ( result instanceof Object && ("content" in (result as any) || "embeds" in (result as any) || "files" in (result as any) || "components" in (result as any) || "sticker" in (result as any)) diff --git a/src/commands/ChatCommand.ts b/src/commands/ChatCommand.ts index c7c2be7..4d6eb37 100644 --- a/src/commands/ChatCommand.ts +++ b/src/commands/ChatCommand.ts @@ -1,7 +1,7 @@ import { Message, Interaction } from "discord.js"; import { BaseCommand } from "./BaseCommand.js"; import { ChatCommandInit } from "./types/ChatCommand.js"; -import { DefaultParameter, InputParameter, ObjectID, Parameter } from "../structures/Parameter.js"; +import { DefaultParameter, ObjectID, Parameter, TargetID } from "../structures/parameter.js"; import { TextCommandObject, TextCommandOptionChoiceObject, TextCommandOptionObject } from "../structures/types/api.js"; import { ParameterResolvable } from "../structures/types/Parameter.js"; import { MissingParameterError, ParameterTypeError } from "errors.js"; @@ -88,11 +88,11 @@ export class ChatCommand extends BaseCommand { * @param {InputParameter[]} [cmdParams] - list of processed parameters passed in a Discord interaction * @returns {Promise} */ - public async start(interaction: Message | Interaction, cmdParams?: InputParameter[]): Promise { + public async start(args: ReadonlyMap | TargetID, interaction: Message | Interaction): Promise { if (!this.slash && interaction instanceof Interaction) { throw new Error("This command is not available as a slash command"); } - super.start(interaction, cmdParams); + super.start(args, interaction); } /** diff --git a/src/commands/CommandManager.ts b/src/commands/CommandManager.ts index 6f18454..5745133 100644 --- a/src/commands/CommandManager.ts +++ b/src/commands/CommandManager.ts @@ -1,5 +1,5 @@ import { Interaction, Message } from "discord.js"; -import { TargetID } from "structures/Parameter.js"; +import { TargetID } from "structures/parameter.js"; import { CommandNotFound } from "../errors.js"; import { applicationState } from "../state.js"; import { BaseCommand } from "./BaseCommand.js"; diff --git a/src/commands/types/BaseCommand.ts b/src/commands/types/BaseCommand.ts index 0c3ac65..84a9c95 100644 --- a/src/commands/types/BaseCommand.ts +++ b/src/commands/types/BaseCommand.ts @@ -1,8 +1,8 @@ import { MessageEmbed, ReplyMessageOptions, Message, CommandInteraction } from "discord.js"; -import { InputParameter } from "../../structures/Parameter.js"; import { ParameterResolvable } from "../../structures/types/Parameter.js"; import { PermissionCheckTypes, PermissionTypes } from "./permissions.js"; import { BaseCommand } from "../BaseCommand.js"; +import { TargetID } from "structures/parameter.js"; export interface BaseCommandInit { name: string; @@ -17,10 +17,7 @@ export type CommandType = "CHAT" | "MESSAGE" | "USER"; export type CommandFunctionReturnTypes = void | string | MessageEmbed | ReplyMessageOptions | Promise; -export type CommandFunction = ( - interaction: Message | CommandInteraction, - argumentAccessor?: (query: string, returnType?: "value" | "object") => ParameterResolvable | InputParameter | null -) => CommandFunctionReturnTypes; +export type CommandFunction = (argumentAccessor: ReadonlyMap | TargetID, interaction?: Message | CommandInteraction) => CommandFunctionReturnTypes; export interface PhraseOccurrenceData { command: BaseCommand; diff --git a/src/commands/types/ChatCommand.ts b/src/commands/types/ChatCommand.ts index 6b75797..6e7de93 100644 --- a/src/commands/types/ChatCommand.ts +++ b/src/commands/types/ChatCommand.ts @@ -1,8 +1,6 @@ -import { CommandInteraction, Message } from "discord.js"; -import { ParameterSchema, ParameterResolvable } from "../../structures/types/Parameter.js"; -import { InputParameter } from "../../structures/Parameter.js"; +import { ParameterSchema } from "../../structures/types/Parameter.js"; import { PermissionCheckTypes, PermissionTypes } from "./permissions.js"; -import { CommandFunctionReturnTypes } from "./BaseCommand.js"; +import { CommandFunction } from "./BaseCommand.js"; /** * @interface @@ -82,10 +80,7 @@ export interface ChatCommandInit { * @param {Function} p - function to fetch input parameters' values * @param {Message | CommandInteraction} i - interaction object */ - function: ( - interaction: Message | CommandInteraction, - params?: (query: string, returnType?: "value" | "object") => ParameterResolvable | InputParameter | null - ) => CommandFunctionReturnTypes; + function: CommandFunction; } export type GetMode = "ALL" | "PREFIX" | "NO_PREFIX"; diff --git a/src/commands/types/commands.ts b/src/commands/types/commands.ts index 0915503..6f351b5 100644 --- a/src/commands/types/commands.ts +++ b/src/commands/types/commands.ts @@ -4,7 +4,7 @@ import { MessageCommand } from "../MessageCommand.js"; import { UserCommand } from "../UserCommand.js"; import { Interaction, Message } from "discord.js"; import { ParameterResolvable } from "structures/types/Parameter.js"; -import { TargetID } from "structures/Parameter.js"; +import { TargetID } from "structures/parameter.js"; export type CommandResolvable = BaseCommand | ChatCommand | MessageCommand | UserCommand; diff --git a/src/errors.ts b/src/errors.ts index 8c6d7b6..1d082ff 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -1,6 +1,6 @@ import { BaseCommand } from "./commands/BaseCommand.js"; import { GuildMember } from "discord.js"; -import { Parameter } from "./structures/Parameter.js"; +import { Parameter } from "./structures/parameter.js"; import { ParameterType } from "./structures/types/Parameter.js"; /** diff --git a/src/structures/Bot.ts b/src/structures/Bot.ts index 5340710..a07a240 100644 --- a/src/structures/Bot.ts +++ b/src/structures/Bot.ts @@ -2,7 +2,7 @@ import { Client, CommandInteraction, GuildMember, Intents, Message } from "disco import { EventEmitter } from "events"; import * as http from "http"; import { ChatCommand } from "../commands/ChatCommand.js"; -import { ChatCommandManager } from "../managers/ChatCommandManager.js"; +import { CommandManager } from "../commands/CommandManager"; import { CommandNotFound, OperationSuccess, PermissionsError } from "../errors.js"; import { HelpMessage } from "../commands/Help.js"; import { SystemMessageManager } from "./SystemMessage.js"; @@ -10,7 +10,6 @@ import { CommandInteractionData } from "../commands/types/commands.js"; import { InitOptions } from "./types/Bot.js"; import { HelpMessageParams } from "../commands/types/HelpMessage.js"; import { applicationState } from "../state.js"; -import { MessageCommandManager } from "../managers/MessageCommandManager.js"; export declare interface Bot { on(event: "READY", listener: Function): this; @@ -37,16 +36,10 @@ export class Bot extends EventEmitter { public readonly client: Client; /** - * Instance command manager for chat commands + * Instance command manager * @type {ChatCommandManager} */ - public readonly chatCommands: ChatCommandManager; - - /** - * Instance command manager for message context menu commands - * @type {MessageCommandManager} - */ - public readonly messageCommands: MessageCommandManager; + public readonly commands: CommandManager; /** * Discord bot token @@ -105,8 +98,7 @@ export class Bot extends EventEmitter { ], } ); - this.chatCommands = new ChatCommandManager(options.prefix, options.parameterSeparator); - this.messageCommands = new MessageCommandManager(); + this.commands = new CommandManager(options.prefix, options.parameterSeparator); this.token = options.token; this.applicationId = options.applicationId; this.messages = { @@ -136,7 +128,7 @@ export class Bot extends EventEmitter { throw new Error("This bot is already running"); } console.log(`\nBot name: ${this.name}`); - console.log(`Prefix: ${this.chatCommands.prefix || "/ (only slash commands)"} \n`); + console.log(`Prefix: ${this.commands.prefix || "/ (only slash commands)"} \n`); if (this.token === "") { throw new ReferenceError('No token specified. Please pass your Discord application token as an argument to the "start" method or in the constructor'); } @@ -146,8 +138,8 @@ export class Bot extends EventEmitter { console.log("✔"); } if (this.messages.help.enabled === true) { - const helpMsg: ChatCommand = new HelpMessage(this.chatCommands, this.messages.help, this.name); - this.chatCommands.add(helpMsg); + const helpMsg: ChatCommand = new HelpMessage(this.commands, this.messages.help, this.name); + this.commands.add(helpMsg); } applicationState.running = true; process.stdout.write("Connecting to Discord... "); @@ -167,7 +159,7 @@ export class Bot extends EventEmitter { this.client.on("messageCreate", async (m) => { let cmdMsg: CommandInteractionData | null = null; try { - cmdMsg = this.chatCommands.fetch(m); + cmdMsg = this.commands.fetch(m); if (cmdMsg) { this.emit("COMMAND", m, cmdMsg); await cmdMsg.command.start(m, cmdMsg.parameters); @@ -207,49 +199,49 @@ export class Bot extends EventEmitter { this.client.on("interactionCreate", async (i) => { let cmd: CommandInteractionData | null = null; try { - if (i.isContextMenu()) { - switch (i.targetType) { - case "MESSAGE": - cmd = this.messageCommands.fetch(i); - break; - case "USER": - break; - } - } else if (i.isCommand()) { - cmd = this.chatCommands.fetch(i); - } - if (cmd) { - this.emit("COMMAND", i, cmd); - await cmd.command.start(i, cmd.parameters); - } + // if (i.isContextMenu()) { + // switch (i.targetType) { + // case "MESSAGE": + // cmd = this.messageCommands.fetch(i); + // break; + // case "USER": + // break; + // } + // } else if (i.isCommand()) { + // cmd = this.commands.fetch(i); + // } + // if (cmd) { + // this.emit("COMMAND", i, cmd); + // await cmd.command.start(i, cmd.parameters); + // } } catch (e) { - if (e instanceof PermissionsError) { - await this.messages.system.send( - "PERMISSION", - { - user: (i.member as GuildMember) || undefined, - command: cmd?.command, - }, - i as CommandInteraction - ); - this.emit("ERROR", e); - } else if (e instanceof OperationSuccess) { - await this.messages.system.send("SUCCESS", undefined, i as CommandInteraction); - } else if (e instanceof CommandNotFound) { - await this.messages.system.send("NOT_FOUND", { user: i.user, phrase: e.query }, i); - } else { - await this.messages.system.send( - "ERROR", - { - command: cmd?.command, - user: (i.member as GuildMember) || undefined, - error: e as Error, - }, - i as CommandInteraction - ); - this.emit("ERROR", e); - } - return; + // if (e instanceof PermissionsError) { + // await this.messages.system.send( + // "PERMISSION", + // { + // user: (i.member as GuildMember) || undefined, + // command: cmd?.command, + // }, + // i as CommandInteraction + // ); + // this.emit("ERROR", e); + // } else if (e instanceof OperationSuccess) { + // await this.messages.system.send("SUCCESS", undefined, i as CommandInteraction); + // } else if (e instanceof CommandNotFound) { + // await this.messages.system.send("NOT_FOUND", { user: i.user, phrase: e.query }, i); + // } else { + // await this.messages.system.send( + // "ERROR", + // { + // command: cmd?.command, + // user: (i.member as GuildMember) || undefined, + // error: e as Error, + // }, + // i as CommandInteraction + // ); + // this.emit("ERROR", e); + // } + // return; } }); return true; diff --git a/src/structures/Parameter.ts b/src/structures/Parameter.ts index 058309b..5b5c194 100644 --- a/src/structures/Parameter.ts +++ b/src/structures/Parameter.ts @@ -1,5 +1,5 @@ import { CategoryChannel, DMChannel, Guild, GuildMember, Message, NewsChannel, Role, StageChannel, StoreChannel, TextChannel, VoiceChannel } from "discord.js"; -import { ParameterType, ParameterResolvable, ParameterSchema } from "./types/Parameter.js"; +import { ParameterType, ParameterSchema } from "./types/Parameter.js"; /** * @class Representation of command parameter @@ -64,74 +64,6 @@ export class DefaultParameter extends Parameter { } } -/** - * @class Representation of input parameter (argument) coming from a message or an interaction - * @extends Parameter - */ -export class InputParameter extends Parameter { - /** - * Input value - * @type {ParameterResolvable} - */ - public readonly value: ParameterResolvable; - - constructor(parameter: Parameter, value: ParameterResolvable) { - super(parameter); - this.value = value; - } -} - -export class StringParameter extends InputParameter { - constructor(parameter: Parameter, value: ParameterResolvable) { - if (parameter.type != "string") { - throw new Error(`Parameter type mismatch`); - } - if (parameter.choices) { - const match = parameter.choices.filter((c) => c.toLowerCase() === value?.toString().toLowerCase()); - if (match.length === 0) { - throw new Error(`Parameter "${parameter.name}" has incorrect value. Please enter one of the following values: ${parameter.choices.join(", ")}`); - } else { - super(parameter, match[0]); - return; - } - } - super(parameter, value?.toString() || ""); - } -} - -export class BooleanParameter extends InputParameter { - constructor(parameter: Parameter, value: ParameterResolvable) { - if (parameter.type != "boolean") { - throw new Error(`Parameter type mismatch`); - } - if (value?.toString().toLowerCase() === "true") { - super(parameter, true); - } else if (value?.toString().toLowerCase() === "false") { - super(parameter, false); - } else { - throw new Error(`Cannot convert "${parameter.name}" parameter to boolean. Please enter either "true" or "false".`); - } - } -} - -export class NumberParameter extends InputParameter { - constructor(parameter: Parameter, value: ParameterResolvable) { - if (parameter.type != "number") { - throw new Error(`Parameter type mismatch`); - } - super(parameter, parseFloat(value ? value.toString() : "")); - } -} - -export class ObjectParameter extends InputParameter { - constructor(parameter: Parameter, value: ParameterResolvable) { - if (parameter.type != "channel" && parameter.type != "mentionable" && parameter.type != "user" && parameter.type != "role") { - throw new Error(`Parameter type mismatch`); - } - super(parameter, new ObjectID(value?.toString() || "")); - } -} - export class ObjectID { public readonly id: string; @@ -154,21 +86,6 @@ export class ObjectID { } } -export class NullParameter extends InputParameter { - constructor(parameter: Parameter) { - if (parameter.optional === false) { - throw new Error(`Parameter "${parameter.name}" cannot be null`); - } - super(parameter, null); - } -} - -// export class TargetParameter extends InputParameter { -// constructor(parameter: Parameter, targetId: TargetID) { -// super(parameter, targetId); -// } -// } - export class TargetID { public readonly id: string; private readonly type: "MESSAGE" | "USER"; diff --git a/src/structures/types/Parameter.ts b/src/structures/types/Parameter.ts index 7d0b55e..e4fc680 100644 --- a/src/structures/types/Parameter.ts +++ b/src/structures/types/Parameter.ts @@ -1,4 +1,4 @@ -import { ObjectID, TargetID } from "../Parameter.js"; +import { ObjectID, TargetID } from "../parameter.js"; export type ParameterType = "string" | "boolean" | "number" | "user" | "role" | "channel" | "mentionable" | "target";