From a709198f157d2f83cfa535f963a84bb2e2135999 Mon Sep 17 00:00:00 2001 From: MARCROCK22 <57925328+MARCROCK22@users.noreply.github.com> Date: Sun, 14 Apr 2024 16:49:23 -0400 Subject: [PATCH] feat: default commands methods --- src/client/base.ts | 44 ++++++++++++++++++++++++++++--- src/client/client.ts | 4 +-- src/client/oninteractioncreate.ts | 4 +-- src/client/onmessagecreate.ts | 4 +-- src/commands/applications/chat.ts | 36 ++++++------------------- src/commands/handler.ts | 37 +++++++++++++++++++++----- 6 files changed, 85 insertions(+), 44 deletions(-) diff --git a/src/client/base.ts b/src/client/base.ts index d1a7b11..3c8814a 100644 --- a/src/client/base.ts +++ b/src/client/base.ts @@ -2,7 +2,7 @@ import { join } from 'node:path'; import { ApiHandler, Router } from '../api'; import type { Adapter } from '../cache'; import { Cache, MemoryAdapter } from '../cache'; -import type { RegisteredMiddlewares } from '../commands'; +import type { Command, CommandContext, OnOptionsReturnObject, RegisteredMiddlewares } from '../commands'; import { IgnoreCommand, type InferWithPrefix, type MiddlewareContext } from '../commands/applications/shared'; import { CommandHandler } from '../commands/handler'; import { @@ -12,6 +12,7 @@ import { LogLevels, Logger, MemberShorter, + MergeOptions, MessageShorter, ReactionShorter, RoleShorter, @@ -24,7 +25,7 @@ import { } from '../common'; import type { LocaleString } from 'discord-api-types/rest/v10'; -import type { DeepPartial, IntentStrings, OmitInsert, When } from '../common/types/util'; +import type { DeepPartial, IntentStrings, OmitInsert, PermissionStrings, When } from '../common/types/util'; import { ComponentHandler } from '../components/handler'; import { LangsHandler } from '../langs/handler'; import type { @@ -77,7 +78,33 @@ export class BaseClient { options: BaseClientOptions | undefined; constructor(options?: BaseClientOptions) { - this.options = options; + this.options = MergeOptions( + { + commands: { + defaults: { + onRunError(context: CommandContext, error: unknown): any { + context.client.logger.fatal(`${context.command.name}.`, context.author.id, error); + }, + onOptionsError(context: CommandContext<{}, never>, metadata: OnOptionsReturnObject): any { + context.client.logger.fatal(`${context.command}.`, context.author.id, metadata); + }, + onMiddlewaresError(context: CommandContext<{}, never>, error: string): any { + context.client.logger.fatal(`${context.command}.`, context.author.id, error); + }, + onBotPermissionsFail(context: CommandContext<{}, never>, permissions: PermissionStrings): any { + context.client.logger.fatal(`${context.command}.`, context.author.id, permissions); + }, + onPermissionsFail(context: CommandContext<{}, never>, permissions: PermissionStrings): any { + context.client.logger.fatal(`${context.command}.`, context.author.id, permissions); + }, + onInternalError(context: CommandContext, error?: unknown): any { + context.client.logger.fatal(`${context.command}.`, error); + }, + }, + }, + } satisfies BaseClientOptions, + options, + ); } set botId(id: string) { @@ -290,6 +317,17 @@ export interface BaseClientOptions { | When, ) => {}; globalMiddlewares?: readonly (keyof RegisteredMiddlewares)[]; + commands?: { + defaults?: { + onRunError?: Command['onRunError']; + onPermissionsFail?: Command['onPermissionsFail']; + onBotPermissionsFail?: Command['onBotPermissionsFail']; + onInternalError?: Command['onInternalError']; + onMiddlewaresError?: Command['onMiddlewaresError']; + onOptionsError?: Command['onOptionsError']; + onAfterRun?: Command['onAfterRun']; + }; + }; } export interface StartOptions { diff --git a/src/client/client.ts b/src/client/client.ts index 48b25f0..662baa6 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -197,8 +197,8 @@ export interface ClientOptions extends BaseClientOptions { properties?: Partial; compress?: ShardManagerOptions['compress']; }; - commands?: { - prefix: (message: Message) => Promise | string[]; + commands?: BaseClientOptions['commands'] & { + prefix?: (message: Message) => Promise | string[]; deferReplyResponse?: (ctx: CommandContext) => Parameters[0]; reply?: (ctx: CommandContext) => boolean; argsParser?: (content: string, command: SubCommand | Command) => Record; diff --git a/src/client/oninteractioncreate.ts b/src/client/oninteractioncreate.ts index b8eca26..1963057 100644 --- a/src/client/oninteractioncreate.ts +++ b/src/client/oninteractioncreate.ts @@ -63,7 +63,7 @@ export async function onInteractionCreate( } } catch (error) { try { - await optionsResolver.getCommand()?.onInternalError?.(self, error); + await optionsResolver.getCommand()?.onInternalError?.(interaction, error); } catch { // supress error } @@ -191,7 +191,7 @@ export async function onInteractionCreate( } } catch (error) { try { - await command.onInternalError?.(self, error); + await command.onInternalError?.(context, error); } catch { // supress error } diff --git a/src/client/onmessagecreate.ts b/src/client/onmessagecreate.ts index dda3500..61b4327 100644 --- a/src/client/onmessagecreate.ts +++ b/src/client/onmessagecreate.ts @@ -84,7 +84,7 @@ export async function onMessageCreate( rawMessage: GatewayMessageCreateDispatchData, shardId: number, ) { - if (!self.options?.commands) return; + if (!self.options?.commands?.prefix) return; const message = new Message(self, rawMessage); const prefixes = (await self.options.commands.prefix(message)).sort((a, b) => b.length - a.length); const prefix = prefixes.find(x => message.content.startsWith(x)); @@ -185,7 +185,7 @@ export async function onMessageCreate( } } catch (error) { try { - await command.onInternalError?.(self, error); + await command.onInternalError?.(context, error); } catch { // supress error } diff --git a/src/commands/applications/chat.ts b/src/commands/applications/chat.ts index ba6cd81..a9172cc 100644 --- a/src/commands/applications/chat.ts +++ b/src/commands/applications/chat.ts @@ -20,7 +20,6 @@ import type { OnOptionsReturnObject, PassFunction, StopFunction, - UsingClient, } from './shared'; export interface ReturnOptionsTypes { @@ -277,14 +276,14 @@ class BaseCommand { Object.setPrototypeOf(this, __tempCommand.prototype); } - run?(context: CommandContext): any; - onAfterRun?(context: CommandContext, error: unknown | undefined): any; - onRunError?(context: CommandContext, error: unknown): any; - onOptionsError?(context: CommandContext<{}, never>, metadata: OnOptionsReturnObject): any; - onMiddlewaresError?(context: CommandContext<{}, never>, error: string): any; - onBotPermissionsFail?(context: CommandContext<{}, never>, permissions: PermissionStrings): any; - onPermissionsFail?(context: CommandContext<{}, never>, permissions: PermissionStrings): any; - onInternalError?(client: UsingClient, error?: unknown): any; + run?(context: CommandContext): any; + onAfterRun?(context: CommandContext, error: unknown | undefined): any; + onRunError?(context: CommandContext, error: unknown): any; + onOptionsError?(context: CommandContext, metadata: OnOptionsReturnObject): any; + onMiddlewaresError?(context: CommandContext, error: string): any; + onBotPermissionsFail?(context: CommandContext, permissions: PermissionStrings): any; + onPermissionsFail?(context: CommandContext, permissions: PermissionStrings): any; + onInternalError?(client: CommandContext | AutocompleteInteraction, error?: unknown): any; } export class Command extends BaseCommand { @@ -332,25 +331,6 @@ export class Command extends BaseCommand { options, }; } - - onRunError(context: CommandContext, error: unknown): any { - context.client.logger.fatal(`${this.name}.`, context.author.id, error); - } - onOptionsError(context: CommandContext<{}, never>, metadata: OnOptionsReturnObject): any { - context.client.logger.fatal(`${this.name}.`, context.author.id, metadata); - } - onMiddlewaresError(context: CommandContext<{}, never>, error: string): any { - context.client.logger.fatal(`${this.name}.`, context.author.id, error); - } - onBotPermissionsFail(context: CommandContext<{}, never>, permissions: PermissionStrings): any { - context.client.logger.fatal(`${this.name}.`, context.author.id, permissions); - } - onPermissionsFail(context: CommandContext<{}, never>, permissions: PermissionStrings): any { - context.client.logger.fatal(`${this.name}.`, context.author.id, permissions); - } - onInternalError(client: UsingClient, error?: unknown): any { - client.logger.fatal(`${this.name}.`, error); - } } export abstract class SubCommand extends BaseCommand { diff --git a/src/commands/handler.ts b/src/commands/handler.ts index 744c45b..29a2a1d 100644 --- a/src/commands/handler.ts +++ b/src/commands/handler.ts @@ -66,6 +66,13 @@ export class CommandHandler extends BaseHandler { if (!(commandInstance instanceof Command)) { continue; } + commandInstance.onAfterRun ??= client.options?.commands?.defaults?.onAfterRun; + commandInstance.onBotPermissionsFail ??= client.options?.commands?.defaults?.onBotPermissionsFail; + commandInstance.onInternalError ??= client.options?.commands?.defaults?.onInternalError; + commandInstance.onMiddlewaresError ??= client.options?.commands?.defaults?.onMiddlewaresError; + commandInstance.onOptionsError ??= client.options?.commands?.defaults?.onOptionsError; + commandInstance.onPermissionsFail ??= client.options?.commands?.defaults?.onPermissionsFail; + commandInstance.onRunError ??= client.options?.commands?.defaults?.onRunError; commandInstance.__filePath = command.path; commandInstance.options ??= [] as NonNullable; if (commandInstance.__autoload) { @@ -91,17 +98,33 @@ export class CommandHandler extends BaseHandler { if (option instanceof SubCommand) { option.middlewares = (commandInstance.middlewares ?? []).concat(option.middlewares ?? []); option.onMiddlewaresError = - option.onMiddlewaresError?.bind(option) ?? commandInstance.onMiddlewaresError?.bind(commandInstance); - option.onRunError = option.onRunError?.bind(option) ?? commandInstance.onRunError?.bind(commandInstance); + option.onMiddlewaresError?.bind(option) ?? + commandInstance.onMiddlewaresError?.bind(commandInstance) ?? + this.client.options?.commands?.defaults?.onMiddlewaresError; + option.onRunError = + option.onRunError?.bind(option) ?? + commandInstance.onRunError?.bind(commandInstance) ?? + this.client.options?.commands?.defaults?.onRunError; option.onOptionsError = - option.onOptionsError?.bind(option) ?? commandInstance.onOptionsError?.bind(commandInstance); + option.onOptionsError?.bind(option) ?? + commandInstance.onOptionsError?.bind(commandInstance) ?? + this.client.options?.commands?.defaults?.onOptionsError; option.onInternalError = - option.onInternalError?.bind(option) ?? commandInstance.onInternalError?.bind(commandInstance); - option.onAfterRun = option.onAfterRun?.bind(option) ?? commandInstance.onAfterRun?.bind(commandInstance); + option.onInternalError?.bind(option) ?? + commandInstance.onInternalError?.bind(commandInstance) ?? + this.client.options?.commands?.defaults?.onInternalError; + option.onAfterRun = + option.onAfterRun?.bind(option) ?? + commandInstance.onAfterRun?.bind(commandInstance) ?? + this.client.options?.commands?.defaults?.onAfterRun; option.onBotPermissionsFail = - option.onBotPermissionsFail?.bind(option) ?? commandInstance.onBotPermissionsFail?.bind(commandInstance); + option.onBotPermissionsFail?.bind(option) ?? + commandInstance.onBotPermissionsFail?.bind(commandInstance) ?? + this.client.options?.commands?.defaults?.onBotPermissionsFail; option.onPermissionsFail = - option.onPermissionsFail?.bind(option) ?? commandInstance.onPermissionsFail?.bind(commandInstance); + option.onPermissionsFail?.bind(option) ?? + commandInstance.onPermissionsFail?.bind(commandInstance) ?? + this.client.options?.commands?.defaults?.onPermissionsFail; } }