feat: default commands methods

This commit is contained in:
MARCROCK22 2024-04-14 16:49:23 -04:00
parent 96003b75dd
commit a709198f15
6 changed files with 85 additions and 44 deletions

View File

@ -2,7 +2,7 @@ import { join } from 'node:path';
import { ApiHandler, Router } from '../api'; import { ApiHandler, Router } from '../api';
import type { Adapter } from '../cache'; import type { Adapter } from '../cache';
import { Cache, MemoryAdapter } 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 { IgnoreCommand, type InferWithPrefix, type MiddlewareContext } from '../commands/applications/shared';
import { CommandHandler } from '../commands/handler'; import { CommandHandler } from '../commands/handler';
import { import {
@ -12,6 +12,7 @@ import {
LogLevels, LogLevels,
Logger, Logger,
MemberShorter, MemberShorter,
MergeOptions,
MessageShorter, MessageShorter,
ReactionShorter, ReactionShorter,
RoleShorter, RoleShorter,
@ -24,7 +25,7 @@ import {
} from '../common'; } from '../common';
import type { LocaleString } from 'discord-api-types/rest/v10'; 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 { ComponentHandler } from '../components/handler';
import { LangsHandler } from '../langs/handler'; import { LangsHandler } from '../langs/handler';
import type { import type {
@ -77,7 +78,33 @@ export class BaseClient {
options: BaseClientOptions | undefined; options: BaseClientOptions | undefined;
constructor(options?: BaseClientOptions) { constructor(options?: BaseClientOptions) {
this.options = options; this.options = MergeOptions(
{
commands: {
defaults: {
onRunError(context: CommandContext<any>, error: unknown): any {
context.client.logger.fatal(`${context.command.name}.<onRunError>`, context.author.id, error);
},
onOptionsError(context: CommandContext<{}, never>, metadata: OnOptionsReturnObject): any {
context.client.logger.fatal(`${context.command}.<onOptionsError>`, context.author.id, metadata);
},
onMiddlewaresError(context: CommandContext<{}, never>, error: string): any {
context.client.logger.fatal(`${context.command}.<onMiddlewaresError>`, context.author.id, error);
},
onBotPermissionsFail(context: CommandContext<{}, never>, permissions: PermissionStrings): any {
context.client.logger.fatal(`${context.command}.<onBotPermissionsFail>`, context.author.id, permissions);
},
onPermissionsFail(context: CommandContext<{}, never>, permissions: PermissionStrings): any {
context.client.logger.fatal(`${context.command}.<onPermissionsFail>`, context.author.id, permissions);
},
onInternalError(context: CommandContext, error?: unknown): any {
context.client.logger.fatal(`${context.command}.<onInternalError>`, error);
},
},
},
} satisfies BaseClientOptions,
options,
);
} }
set botId(id: string) { set botId(id: string) {
@ -290,6 +317,17 @@ export interface BaseClientOptions {
| When<InferWithPrefix, Message, never>, | When<InferWithPrefix, Message, never>,
) => {}; ) => {};
globalMiddlewares?: readonly (keyof RegisteredMiddlewares)[]; 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 { export interface StartOptions {

View File

@ -197,8 +197,8 @@ export interface ClientOptions extends BaseClientOptions {
properties?: Partial<ShardManagerOptions['properties']>; properties?: Partial<ShardManagerOptions['properties']>;
compress?: ShardManagerOptions['compress']; compress?: ShardManagerOptions['compress'];
}; };
commands?: { commands?: BaseClientOptions['commands'] & {
prefix: (message: Message) => Promise<string[]> | string[]; prefix?: (message: Message) => Promise<string[]> | string[];
deferReplyResponse?: (ctx: CommandContext) => Parameters<Message['write']>[0]; deferReplyResponse?: (ctx: CommandContext) => Parameters<Message['write']>[0];
reply?: (ctx: CommandContext) => boolean; reply?: (ctx: CommandContext) => boolean;
argsParser?: (content: string, command: SubCommand | Command) => Record<string, string>; argsParser?: (content: string, command: SubCommand | Command) => Record<string, string>;

View File

@ -63,7 +63,7 @@ export async function onInteractionCreate(
} }
} catch (error) { } catch (error) {
try { try {
await optionsResolver.getCommand()?.onInternalError?.(self, error); await optionsResolver.getCommand()?.onInternalError?.(interaction, error);
} catch { } catch {
// supress error // supress error
} }
@ -191,7 +191,7 @@ export async function onInteractionCreate(
} }
} catch (error) { } catch (error) {
try { try {
await command.onInternalError?.(self, error); await command.onInternalError?.(context, error);
} catch { } catch {
// supress error // supress error
} }

View File

@ -84,7 +84,7 @@ export async function onMessageCreate(
rawMessage: GatewayMessageCreateDispatchData, rawMessage: GatewayMessageCreateDispatchData,
shardId: number, shardId: number,
) { ) {
if (!self.options?.commands) return; if (!self.options?.commands?.prefix) return;
const message = new Message(self, rawMessage); const message = new Message(self, rawMessage);
const prefixes = (await self.options.commands.prefix(message)).sort((a, b) => b.length - a.length); const prefixes = (await self.options.commands.prefix(message)).sort((a, b) => b.length - a.length);
const prefix = prefixes.find(x => message.content.startsWith(x)); const prefix = prefixes.find(x => message.content.startsWith(x));
@ -185,7 +185,7 @@ export async function onMessageCreate(
} }
} catch (error) { } catch (error) {
try { try {
await command.onInternalError?.(self, error); await command.onInternalError?.(context, error);
} catch { } catch {
// supress error // supress error
} }

View File

@ -20,7 +20,6 @@ import type {
OnOptionsReturnObject, OnOptionsReturnObject,
PassFunction, PassFunction,
StopFunction, StopFunction,
UsingClient,
} from './shared'; } from './shared';
export interface ReturnOptionsTypes { export interface ReturnOptionsTypes {
@ -277,14 +276,14 @@ class BaseCommand {
Object.setPrototypeOf(this, __tempCommand.prototype); Object.setPrototypeOf(this, __tempCommand.prototype);
} }
run?(context: CommandContext<any>): any; run?(context: CommandContext): any;
onAfterRun?(context: CommandContext<any>, error: unknown | undefined): any; onAfterRun?(context: CommandContext, error: unknown | undefined): any;
onRunError?(context: CommandContext<any>, error: unknown): any; onRunError?(context: CommandContext, error: unknown): any;
onOptionsError?(context: CommandContext<{}, never>, metadata: OnOptionsReturnObject): any; onOptionsError?(context: CommandContext, metadata: OnOptionsReturnObject): any;
onMiddlewaresError?(context: CommandContext<{}, never>, error: string): any; onMiddlewaresError?(context: CommandContext, error: string): any;
onBotPermissionsFail?(context: CommandContext<{}, never>, permissions: PermissionStrings): any; onBotPermissionsFail?(context: CommandContext, permissions: PermissionStrings): any;
onPermissionsFail?(context: CommandContext<{}, never>, permissions: PermissionStrings): any; onPermissionsFail?(context: CommandContext, permissions: PermissionStrings): any;
onInternalError?(client: UsingClient, error?: unknown): any; onInternalError?(client: CommandContext | AutocompleteInteraction, error?: unknown): any;
} }
export class Command extends BaseCommand { export class Command extends BaseCommand {
@ -332,25 +331,6 @@ export class Command extends BaseCommand {
options, options,
}; };
} }
onRunError(context: CommandContext<any>, error: unknown): any {
context.client.logger.fatal(`${this.name}.<onRunError>`, context.author.id, error);
}
onOptionsError(context: CommandContext<{}, never>, metadata: OnOptionsReturnObject): any {
context.client.logger.fatal(`${this.name}.<onOptionsError>`, context.author.id, metadata);
}
onMiddlewaresError(context: CommandContext<{}, never>, error: string): any {
context.client.logger.fatal(`${this.name}.<onMiddlewaresError>`, context.author.id, error);
}
onBotPermissionsFail(context: CommandContext<{}, never>, permissions: PermissionStrings): any {
context.client.logger.fatal(`${this.name}.<onBotPermissionsFail>`, context.author.id, permissions);
}
onPermissionsFail(context: CommandContext<{}, never>, permissions: PermissionStrings): any {
context.client.logger.fatal(`${this.name}.<onPermissionsFail>`, context.author.id, permissions);
}
onInternalError(client: UsingClient, error?: unknown): any {
client.logger.fatal(`${this.name}.<onInternalError>`, error);
}
} }
export abstract class SubCommand extends BaseCommand { export abstract class SubCommand extends BaseCommand {

View File

@ -66,6 +66,13 @@ export class CommandHandler extends BaseHandler {
if (!(commandInstance instanceof Command)) { if (!(commandInstance instanceof Command)) {
continue; 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.__filePath = command.path;
commandInstance.options ??= [] as NonNullable<Command['options']>; commandInstance.options ??= [] as NonNullable<Command['options']>;
if (commandInstance.__autoload) { if (commandInstance.__autoload) {
@ -91,17 +98,33 @@ export class CommandHandler extends BaseHandler {
if (option instanceof SubCommand) { if (option instanceof SubCommand) {
option.middlewares = (commandInstance.middlewares ?? []).concat(option.middlewares ?? []); option.middlewares = (commandInstance.middlewares ?? []).concat(option.middlewares ?? []);
option.onMiddlewaresError = option.onMiddlewaresError =
option.onMiddlewaresError?.bind(option) ?? commandInstance.onMiddlewaresError?.bind(commandInstance); option.onMiddlewaresError?.bind(option) ??
option.onRunError = option.onRunError?.bind(option) ?? commandInstance.onRunError?.bind(commandInstance); 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 =
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 =
option.onInternalError?.bind(option) ?? commandInstance.onInternalError?.bind(commandInstance); option.onInternalError?.bind(option) ??
option.onAfterRun = option.onAfterRun?.bind(option) ?? commandInstance.onAfterRun?.bind(commandInstance); 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 =
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 =
option.onPermissionsFail?.bind(option) ?? commandInstance.onPermissionsFail?.bind(commandInstance); option.onPermissionsFail?.bind(option) ??
commandInstance.onPermissionsFail?.bind(commandInstance) ??
this.client.options?.commands?.defaults?.onPermissionsFail;
} }
} }