From 33165faf9563971af35bcdea3734d591f946e349 Mon Sep 17 00:00:00 2001 From: MARCROCK22 <57925328+MARCROCK22@users.noreply.github.com> Date: Mon, 8 Apr 2024 22:18:28 -0400 Subject: [PATCH] feat: message commands aliases --- src/client/client.ts | 2 +- src/client/onmessagecreate.ts | 32 ++++++++++++++++++++----------- src/commands/applications/chat.ts | 20 +++++++++++-------- src/commands/decorators.ts | 23 ++++++++++++++++++++++ 4 files changed, 57 insertions(+), 20 deletions(-) diff --git a/src/client/client.ts b/src/client/client.ts index 4345af4..b235629 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -1,4 +1,4 @@ -import { type GatewayDispatchPayload, GatewayIntentBits, type GatewayPresenceUpdateData } from 'discord-api-types/v10'; +import { GatewayIntentBits, type GatewayDispatchPayload, type GatewayPresenceUpdateData } from 'discord-api-types/v10'; import { parentPort, workerData } from 'node:worker_threads'; import type { ClientEvent, Command, CommandContext, EventHandlerLike, Message, SubCommand } from '..'; import type { DeepPartial, If, WatcherPayload, WatcherSendToShard } from '../common'; diff --git a/src/client/onmessagecreate.ts b/src/client/onmessagecreate.ts index f4402de..dda3500 100644 --- a/src/client/onmessagecreate.ts +++ b/src/client/onmessagecreate.ts @@ -32,31 +32,41 @@ function getCommandFromContent( parent?: Command; fullCommandName: string; } { - const parentName = commandRaw[0]; - const groupName = commandRaw.length === 3 ? commandRaw[1] : undefined; - const subcommandName = groupName ? commandRaw[2] : commandRaw[1]; + const rawParentName = commandRaw[0]; + const rawGroupName = commandRaw.length === 3 ? commandRaw[1] : undefined; + const rawSubcommandName = rawGroupName ? commandRaw[2] : commandRaw[1]; const parent = self.commands!.values.find( - x => (!('ignore' in x) || x.ignore !== IgnoreCommand.Message) && x.name === parentName, + x => + (!('ignore' in x) || x.ignore !== IgnoreCommand.Message) && + (x.name === rawParentName || ('aliases' in x ? x.aliases?.includes(rawParentName) : false)), ); - const fullCommandName = `${parentName}${ - groupName ? ` ${groupName} ${subcommandName}` : `${subcommandName ? ` ${subcommandName}` : ''}` + const fullCommandName = `${rawParentName}${ + rawGroupName ? ` ${rawGroupName} ${rawSubcommandName}` : `${rawSubcommandName ? ` ${rawSubcommandName}` : ''}` }`; if (!(parent instanceof Command)) return { fullCommandName }; - if (groupName && !parent.groups?.[groupName!]) return getCommandFromContent([parentName, groupName], self); - if (subcommandName && !parent.options?.some(x => x instanceof SubCommand && x.name === subcommandName)) - return getCommandFromContent([parentName], self); + if (rawGroupName && !parent.groups?.[rawGroupName] && !parent.groupsAliases?.[rawGroupName]) + return getCommandFromContent([rawParentName, rawGroupName], self); + if ( + rawSubcommandName && + !parent.options?.some( + x => x instanceof SubCommand && (x.name === rawSubcommandName || x.aliases?.includes(rawSubcommandName)), + ) + ) + return getCommandFromContent([rawParentName], self); + + const groupName = rawGroupName ? parent.groupsAliases?.[rawGroupName] || rawGroupName : undefined; const command = - groupName || subcommandName + groupName || rawSubcommandName ? (parent.options?.find(opt => { if (opt instanceof SubCommand) { if (groupName) { if (opt.group !== groupName) return false; } if (opt.group && !groupName) return false; - return subcommandName === opt.name; + return rawSubcommandName === opt.name || opt.aliases?.includes(rawSubcommandName); } return false; }) as SubCommand) diff --git a/src/commands/applications/chat.ts b/src/commands/applications/chat.ts index a431035..b6df6cf 100644 --- a/src/commands/applications/chat.ts +++ b/src/commands/applications/chat.ts @@ -109,14 +109,6 @@ class BaseCommand { __filePath?: string; __t?: { name: string | undefined; description: string | undefined }; __autoload?: true; - __tGroups?: Record< - string /* name for group*/, - { - name: string | undefined; - description: string | undefined; - defaultDescription: string; - } - >; guildId?: string[]; name!: string; @@ -134,6 +126,8 @@ class BaseCommand { ignore?: IgnoreCommand; + aliases?: string[]; + /** @internal */ async __runOptions( ctx: CommandContext<{}, never>, @@ -296,6 +290,16 @@ export class Command extends BaseCommand { type = ApplicationCommandType.ChatInput; groups?: Parameters[0]; + groupsAliases?: Record; + __tGroups?: Record< + string /* name for group*/, + { + name: string | undefined; + description: string | undefined; + defaultDescription: string; + } + >; + toJSON() { const options: APIApplicationCommandOption[] = []; diff --git a/src/commands/decorators.ts b/src/commands/decorators.ts index 8dc02a8..ae84d73 100644 --- a/src/commands/decorators.ts +++ b/src/commands/decorators.ts @@ -26,6 +26,7 @@ type DeclareOptions = integrationTypes?: (keyof typeof IntegrationTypes)[]; contexts?: (keyof typeof InteractionContextTypes)[]; ignore?: IgnoreCommand; + aliases?: string[]; } | (Omit< { @@ -71,12 +72,22 @@ export function GroupsT( name?: FlatObjectKeys; description?: FlatObjectKeys; defaultDescription: string; + aliases?: string[]; } >, ) { return (target: T) => class extends target { __tGroups = groups; + groupsAliases: Record = {}; + constructor(...args: any[]) { + super(...args); + for (const i in groups) { + for (const j of groups[i].aliases ?? []) { + this.groupsAliases[j] = i; + } + } + } }; } @@ -87,12 +98,22 @@ export function Groups( name?: [language: LocaleString, value: string][]; description?: [language: LocaleString, value: string][]; defaultDescription: string; + aliases?: string[]; } >, ) { return (target: T) => class extends target { groups = groups; + groupsAliases: Record = {}; + constructor(...args: any[]) { + super(...args); + for (const i in groups) { + for (const j of groups[i].aliases ?? []) { + this.groupsAliases[j] = i; + } + } + } }; } @@ -152,12 +173,14 @@ export function Declare(declare: DeclareOptions) { type: ApplicationCommandType = ApplicationCommandType.ChatInput; guildId?: string[]; ignore?: IgnoreCommand; + aliases?: string[]; constructor(...args: any[]) { super(...args); if ('description' in declare) this.description = declare.description; if ('type' in declare) this.type = declare.type; if ('guildId' in declare) this.guildId = declare.guildId; if ('ignore' in declare) this.ignore = declare.ignore; + if ('aliases' in declare) this.aliases = declare.aliases; // check if all properties are valid } };