diff --git a/src/client/base.ts b/src/client/base.ts index 09a1271..00d2b65 100644 --- a/src/client/base.ts +++ b/src/client/base.ts @@ -4,7 +4,7 @@ import type { Adapter } from '../cache'; import { Cache, MemoryAdapter } from '../cache'; import type { RegisteredMiddlewares } from '../commands'; import type { InferWithPrefix, MiddlewareContext } from '../commands/applications/shared'; -import { CommandHandler } from '../commands/handler'; +import { CommandHandler, type CommandHandlerLike } from '../commands/handler'; import { ChannelShorter, EmojiShorter, @@ -25,8 +25,8 @@ import { } from '../common'; import type { DeepPartial, IntentStrings, OmitInsert, When } from '../common/types/util'; -import { ComponentHandler } from '../components/handler'; -import { LangsHandler } from '../langs/handler'; +import { ComponentHandler, type ComponentHandlerLike } from '../components/handler'; +import { LangsHandler, type LangsHandlerLike } from '../langs/handler'; import type { ChatInputCommandInteraction, Message, @@ -55,9 +55,9 @@ export class BaseClient { name: '[Seyfert]', }); - langs = new LangsHandler(this.logger); - commands = new CommandHandler(this.logger, this); - components = new ComponentHandler(this.logger, this); + langs?: LangsHandlerLike = new LangsHandler(this.logger); + commands?: CommandHandlerLike = new CommandHandler(this.logger, this); + components?: ComponentHandlerLike = new ComponentHandler(this.logger, this); private _applicationId?: string; private _botId?: string; @@ -99,7 +99,7 @@ export class BaseClient { return new Router(this.rest).createProxy(); } - setServices({ rest, cache, langs, middlewares }: ServicesOptions) { + setServices({ rest, cache, langs, middlewares, handlers }: ServicesOptions) { if (rest) { this.rest = rest; } @@ -111,13 +111,24 @@ export class BaseClient { this, ); } - if (langs) { - if (langs.default) this.langs.defaultLang = langs.default; - if (langs.aliases) this.langs.aliases = Object.entries(langs.aliases); - } if (middlewares) { this.middlewares = middlewares; } + if (handlers) { + if ('components' in handlers) { + this.components = handlers.components; + } + if ('commands' in handlers) { + this.commands = handlers.commands; + } + if ('langs' in handlers) { + this.langs = handlers.langs; + } + } + if (langs) { + if (langs.default) this.langs!.defaultLang = langs.default; + if (langs.aliases) this.langs!.aliases = Object.entries(langs.aliases); + } } protected async execute(..._options: unknown[]) { @@ -170,7 +181,7 @@ export class BaseClient { applicationId ??= await this.getRC().then(x => x.applicationId ?? this.applicationId); BaseClient.assertString(applicationId, 'applicationId is not a string'); - const commands = this.commands.values.map(x => x.toJSON()); + const commands = this.commands!.values.map(x => x.toJSON()); const filter = filterSplit(commands, command => !command.guild_id); await this.proxy.applications(applicationId).commands.put({ @@ -197,7 +208,7 @@ export class BaseClient { async loadCommands(dir?: string) { dir ??= await this.getRC().then(x => x.commands); - if (dir) { + if (dir && this.commands) { await this.commands.load(dir, this); this.logger.info('CommandHandler loaded'); } @@ -205,7 +216,7 @@ export class BaseClient { async loadComponents(dir?: string) { dir ??= await this.getRC().then(x => x.components); - if (dir) { + if (dir && this.components) { await this.components.load(dir); this.logger.info('ComponentHandler loaded'); } @@ -213,14 +224,14 @@ export class BaseClient { async loadLangs(dir?: string) { dir ??= await this.getRC().then(x => x.langs); - if (dir) { + if (dir && this.langs) { await this.langs.load(dir); this.logger.info('LangsHandler loaded'); } } t(locale: string) { - return this.langs.get(locale); + return this.langs!.get(locale); } async getRC< @@ -310,4 +321,9 @@ export interface ServicesOptions { aliases?: Record; }; middlewares?: Record; + handlers?: { + components?: ComponentHandlerLike; + commands?: CommandHandlerLike; + langs?: LangsHandlerLike; + }; } diff --git a/src/client/client.ts b/src/client/client.ts index 8b50a5f..1903cb9 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -1,5 +1,5 @@ import { parentPort, workerData } from 'node:worker_threads'; -import type { Command, CommandContext, Message, SubCommand } from '..'; +import type { Command, CommandContext, EventHandlerLike, Message, SubCommand } from '..'; import { GatewayIntentBits, type DeepPartial, @@ -22,7 +22,7 @@ import { onMessageCreate } from './onmessagecreate'; export class Client extends BaseClient { private __handleGuilds?: Set = new Set(); gateway!: ShardManager; - events = new EventHandler(this.logger); + events?: EventHandlerLike = new EventHandler(this.logger); me!: If; declare options: ClientOptions | undefined; memberUpdateHandler = new MemberUpdateHandler(); @@ -37,6 +37,9 @@ export class Client extends BaseClient { ...rest }: ServicesOptions & { gateway?: ShardManager; + handlers?: ServicesOptions['handlers'] & { + events?: EventHandlerLike; + }; }) { super.setServices(rest); if (gateway) { @@ -48,11 +51,14 @@ export class Client extends BaseClient { }; this.gateway = gateway; } + if (rest.handlers && 'events' in rest.handlers) { + this.events = rest.handlers.events; + } } async loadEvents(dir?: string) { dir ??= await this.getRC().then(x => x.events); - if (dir) { + if (dir && this.events) { await this.events.load(dir); this.logger.info('EventHandler loaded'); } @@ -114,21 +120,21 @@ export class Client extends BaseClient { } protected async onPacket(shardId: number, packet: GatewayDispatchPayload) { - await this.events.runEvent('RAW', this, packet, shardId); + await this.events?.runEvent('RAW', this, packet, shardId); switch (packet.t) { //// Cases where we must obtain the old data before updating case 'GUILD_MEMBER_UPDATE': if (!this.memberUpdateHandler.check(packet.d)) { return; } - await this.events.execute(packet.t, packet, this as Client, shardId); + await this.events?.execute(packet.t, packet, this as Client, shardId); await this.cache.onPacket(packet); break; case 'PRESENCE_UPDATE': if (!this.presenceUpdateHandler.check(packet.d as any)) { return; } - await this.events.execute(packet.t, packet, this as Client, shardId); + await this.events?.execute(packet.t, packet, this as Client, shardId); await this.cache.onPacket(packet); break; //rest of the events @@ -153,7 +159,7 @@ export class Client extends BaseClient { !((this.gateway.options.intents & GatewayIntentBits.Guilds) === GatewayIntentBits.Guilds) ) { if ([...this.gateway.values()].every(shard => shard.data.session_id)) { - await this.events.runEvent('BOT_READY', this, this.me, -1); + await this.events?.runEvent('BOT_READY', this, this.me, -1); } delete this.__handleGuilds; } @@ -163,7 +169,7 @@ export class Client extends BaseClient { if (this.__handleGuilds?.has(packet.d.id)) { this.__handleGuilds.delete(packet.d.id); if (!this.__handleGuilds.size && [...this.gateway.values()].every(shard => shard.data.session_id)) { - await this.events.runEvent('BOT_READY', this, this.me, -1); + await this.events?.runEvent('BOT_READY', this, this.me, -1); } if (!this.__handleGuilds.size) delete this.__handleGuilds; return; @@ -171,7 +177,7 @@ export class Client extends BaseClient { break; } } - await this.events.execute(packet.t, packet, this as Client, shardId); + await this.events?.execute(packet.t, packet, this as Client, shardId); break; } } diff --git a/src/client/oninteractioncreate.ts b/src/client/oninteractioncreate.ts index e2ef1a0..1027ff4 100644 --- a/src/client/oninteractioncreate.ts +++ b/src/client/oninteractioncreate.ts @@ -1,11 +1,11 @@ import { ApplicationCommandType, InteractionType, type APIInteraction } from 'discord-api-types/v10'; import { CommandContext, - type ContextOptionsResolved, MenuCommandContext, OptionResolver, type Command, type ContextMenuCommand, + type ContextOptionsResolved, } from '../commands'; import type { ChatInputCommandInteraction, @@ -28,7 +28,7 @@ export async function onInteractionCreate( switch (body.type) { case InteractionType.ApplicationCommandAutocomplete: { - const parentCommand = self.commands.values.find(x => { + const parentCommand = self.commands?.values.find(x => { if (x.guild_id && !x.guild_id.includes(body.data.guild_id ?? '')) { return false; } @@ -76,7 +76,7 @@ export async function onInteractionCreate( case ApplicationCommandType.Message: case ApplicationCommandType.User: { - const command = self.commands.values.find(x => { + const command = self.commands?.values.find(x => { if (x.guild_id && !x.guild_id.includes(body.data.guild_id ?? '')) { return false; } @@ -135,7 +135,7 @@ export async function onInteractionCreate( case ApplicationCommandType.ChatInput: { const packetData = body.data; - const parentCommand = self.commands.values.find(x => { + const parentCommand = self.commands?.values.find(x => { if (x.guild_id && !x.guild_id.includes(packetData.guild_id ?? '')) { return false; } @@ -206,20 +206,20 @@ export async function onInteractionCreate( case InteractionType.ModalSubmit: { const interaction = BaseInteraction.from(self, body, __reply) as ModalSubmitInteraction; - if (self.components.hasModal(interaction)) { + if (self.components?.hasModal(interaction)) { await self.components.onModalSubmit(interaction); } else { - await self.components.executeModal(interaction); + await self.components?.executeModal(interaction); } } break; case InteractionType.MessageComponent: { const interaction = BaseInteraction.from(self, body, __reply) as ComponentInteraction; - if (self.components.hasComponent(body.message.id, interaction.customId)) { + if (self.components?.hasComponent(body.message.id, interaction.customId)) { await self.components.onComponent(body.message.id, interaction); } else { - await self.components.executeComponent(interaction); + await self.components?.executeComponent(interaction); } } break; diff --git a/src/client/onmessagecreate.ts b/src/client/onmessagecreate.ts index 0012f88..2167b2a 100644 --- a/src/client/onmessagecreate.ts +++ b/src/client/onmessagecreate.ts @@ -34,7 +34,7 @@ function getCommandFromContent( const parentName = commandRaw[0]; const groupName = commandRaw.length === 3 ? commandRaw[1] : undefined; const subcommandName = groupName ? commandRaw[2] : commandRaw[1]; - const parent = self.commands.values.find(x => x.name === parentName); + const parent = self.commands!.values.find(x => x.name === parentName); const fullCommandName = `${parentName}${ groupName ? ` ${groupName} ${subcommandName}` : `${subcommandName ? ` ${subcommandName}` : ''}` }`; @@ -48,15 +48,15 @@ function getCommandFromContent( const command = groupName || subcommandName ? (parent.options?.find(opt => { - if (opt instanceof SubCommand) { - if (groupName) { - if (opt.group !== groupName) return false; + if (opt instanceof SubCommand) { + if (groupName) { + if (opt.group !== groupName) return false; + } + if (opt.group && !groupName) return false; + return subcommandName === opt.name; } - if (opt.group && !groupName) return false; - return subcommandName === opt.name; - } - return false; - }) as SubCommand) + return false; + }) as SubCommand) : parent; return { @@ -80,7 +80,10 @@ export async function onMessageCreate( const content = message.content.slice(prefix.length).trimStart(); const { fullCommandName, command, parent } = getCommandFromContent( - content.split(' ').filter(x => x).slice(0, 3), + content + .split(' ') + .filter(x => x) + .slice(0, 3), self, ); diff --git a/src/client/workerclient.ts b/src/client/workerclient.ts index 828f7d0..93d4ef1 100644 --- a/src/client/workerclient.ts +++ b/src/client/workerclient.ts @@ -5,7 +5,7 @@ import type { Cache } from '../cache'; import { WorkerAdapter } from '../cache'; import type { GatewayDispatchPayload, GatewaySendPayload, When } from '../common'; import { GatewayIntentBits, LogLevels, Logger, type DeepPartial } from '../common'; -import { EventHandler } from '../events'; +import { EventHandler, type EventHandlerLike } from '../events'; import { ClientUser } from '../structures'; import { Shard, type ShardManagerOptions, type WorkerData } from '../websocket'; import type { @@ -21,7 +21,7 @@ import type { WorkerStart, } from '../websocket/discord/worker'; import type { ManagerMessages } from '../websocket/discord/workermanager'; -import type { BaseClientOptions, StartOptions } from './base'; +import type { BaseClientOptions, ServicesOptions, StartOptions } from './base'; import { BaseClient } from './base'; import type { Client } from './client'; import { onInteractionCreate } from './oninteractioncreate'; @@ -46,7 +46,7 @@ export class WorkerClient extends BaseClient { name: `[Worker #${workerData.workerId}]`, }); - events = new EventHandler(this.logger); + events?: EventHandlerLike = new EventHandler(this.logger); me!: When; promises = new Map void; timeout: NodeJS.Timeout }>(); @@ -98,6 +98,19 @@ export class WorkerClient extends BaseClient { return acc / this.shards.size; } + setServices({ + ...rest + }: ServicesOptions & { + handlers?: ServicesOptions['handlers'] & { + events?: EventHandlerLike; + }; + }) { + super.setServices(rest); + if (rest.handlers && 'events' in rest.handlers) { + this.events = rest.handlers.events; + } + } + async start(options: Omit, 'httpConnection' | 'token' | 'connection'> = {}) { await super.start(options); await this.loadEvents(options.eventsDir); @@ -106,7 +119,7 @@ export class WorkerClient extends BaseClient { async loadEvents(dir?: string) { dir ??= await this.getRC().then(x => x.events); - if (dir) { + if (dir && this.events) { await this.events.load(dir); this.logger.info('EventHandler loaded'); } @@ -221,7 +234,7 @@ export class WorkerClient extends BaseClient { } break; case 'BOT_READY': - await this.events.runEvent('BOT_READY', this, this.me, -1); + await this.events?.runEvent('BOT_READY', this, this.me, -1); break; case 'API_RESPONSE': { @@ -302,14 +315,14 @@ export class WorkerClient extends BaseClient { } protected async onPacket(packet: GatewayDispatchPayload, shardId: number) { - await this.events.execute('RAW', packet, this as WorkerClient, shardId); + await this.events?.execute('RAW', packet, this as WorkerClient, shardId); switch (packet.t) { case 'GUILD_MEMBER_UPDATE': - await this.events.execute(packet.t, packet, this as WorkerClient, shardId); + await this.events?.execute(packet.t, packet, this as WorkerClient, shardId); await this.cache.onPacket(packet); break; case 'PRESENCE_UPDATE': - await this.events.execute(packet.t, packet, this as WorkerClient, shardId); + await this.events?.execute(packet.t, packet, this as WorkerClient, shardId); await this.cache.onPacket(packet); break; //rest of the events @@ -332,7 +345,7 @@ export class WorkerClient extends BaseClient { type: 'WORKER_READY', workerId: this.workerId, } as WorkerReady); - await this.events.runEvent('WORKER_READY', this, this.me, -1); + await this.events?.runEvent('WORKER_READY', this, this.me, -1); } delete this.__handleGuilds; } @@ -352,14 +365,14 @@ export class WorkerClient extends BaseClient { type: 'WORKER_READY', workerId: this.workerId, } as WorkerReady); - await this.events.runEvent('WORKER_READY', this, this.me, -1); + await this.events?.runEvent('WORKER_READY', this, this.me, -1); } if (!this.__handleGuilds.size) delete this.__handleGuilds; return; } } } - await this.events.execute(packet.t, packet, this, shardId); + await this.events?.execute(packet.t, packet, this, shardId); } break; } diff --git a/src/commands/applications/chatcontext.ts b/src/commands/applications/chatcontext.ts index 70923eb..4d28d19 100644 --- a/src/commands/applications/chatcontext.ts +++ b/src/commands/applications/chatcontext.ts @@ -54,7 +54,7 @@ export class CommandContext path.endsWith('.js') || (!path.endsWith('.d.ts') && path.endsWith('.ts')); @@ -122,20 +127,20 @@ export class CommandHandler extends BaseHandler { if (command.__t) { command.name_localizations = {}; command.description_localizations = {}; - for (const locale of Object.keys(client.langs.values)) { - const locales = this.client.langs.aliases.find(x => x[0] === locale)?.[1] ?? []; + for (const locale of Object.keys(client.langs!.values)) { + const locales = this.client.langs!.aliases.find(x => x[0] === locale)?.[1] ?? []; if (Object.values(Locale).includes(locale)) locales.push(locale as LocaleString); if (command.__t.name) { for (const i of locales) { - const valueName = client.langs.getKey(locale, command.__t.name!); + const valueName = client.langs!.getKey(locale, command.__t.name!); if (valueName) command.name_localizations[i] = valueName; } } if (command.__t.description) { for (const i of locales) { - const valueKey = client.langs.getKey(locale, command.__t.description!); + const valueKey = client.langs!.getKey(locale, command.__t.description!); if (valueKey) command.description_localizations[i] = valueKey; } } @@ -146,20 +151,20 @@ export class CommandHandler extends BaseHandler { if (options instanceof SubCommand || !options.locales) continue; options.name_localizations = {}; options.description_localizations = {}; - for (const locale of Object.keys(client.langs.values)) { - const locales = this.client.langs.aliases.find(x => x[0] === locale)?.[1] ?? []; + for (const locale of Object.keys(client.langs!.values)) { + const locales = this.client.langs!.aliases.find(x => x[0] === locale)?.[1] ?? []; if (Object.values(Locale).includes(locale)) locales.push(locale as LocaleString); if (options.locales.name) { for (const i of locales) { - const valueName = client.langs.getKey(locale, options.locales.name!); + const valueName = client.langs!.getKey(locale, options.locales.name!); if (valueName) options.name_localizations[i] = valueName; } } if (options.locales.description) { for (const i of locales) { - const valueKey = client.langs.getKey(locale, options.locales.description!); + const valueKey = client.langs!.getKey(locale, options.locales.description!); if (valueKey) options.description_localizations[i] = valueKey; } } @@ -168,8 +173,8 @@ export class CommandHandler extends BaseHandler { if (command instanceof Command && command.__tGroups) { command.groups = {}; - for (const locale of Object.keys(client.langs.values)) { - const locales = this.client.langs.aliases.find(x => x[0] === locale)?.[1] ?? []; + for (const locale of Object.keys(client.langs!.values)) { + const locales = this.client.langs!.aliases.find(x => x[0] === locale)?.[1] ?? []; if (Object.values(Locale).includes(locale)) locales.push(locale as LocaleString); for (const group in command.__tGroups) { command.groups[group] ??= { @@ -180,7 +185,7 @@ export class CommandHandler extends BaseHandler { if (command.__tGroups[group].name) { for (const i of locales) { - const valueName = client.langs.getKey(locale, command.__tGroups[group].name!); + const valueName = client.langs!.getKey(locale, command.__tGroups[group].name!); if (valueName) { command.groups[group].name!.push([i, valueName]); } @@ -189,7 +194,7 @@ export class CommandHandler extends BaseHandler { if (command.__tGroups[group].description) { for (const i of locales) { - const valueKey = client.langs.getKey(locale, command.__tGroups[group].description!); + const valueKey = client.langs!.getKey(locale, command.__tGroups[group].description!); if (valueKey) { command.groups[group].description!.push([i, valueKey]); } diff --git a/src/common/shorters/messages.ts b/src/common/shorters/messages.ts index 7ffe2bf..af20a65 100644 --- a/src/common/shorters/messages.ts +++ b/src/common/shorters/messages.ts @@ -50,7 +50,7 @@ export class MessageShorter extends BaseShorter { .messages(messageId) .delete({ reason }) .then(() => { - return this.client.components.onMessageDelete(messageId); + return this.client.components?.onMessageDelete(messageId); }); } fetch(messageId: string, channelId: string) { diff --git a/src/components/handler.ts b/src/components/handler.ts index 3fffbdd..e853d9e 100644 --- a/src/components/handler.ts +++ b/src/components/handler.ts @@ -14,8 +14,28 @@ type COMPONENTS = { __run: (customId: string | string[] | RegExp, callback: ComponentCallback) => any; }; +export interface ComponentHandlerLike { + readonly values: Map; + readonly commands: (ComponentCommand | ModalCommand)[]; + readonly modals: Map | LimitedCollection; + + createComponentCollector: ComponentHandler['createComponentCollector']; + + hasModal: ComponentHandler['hasModal']; + onModalSubmit: ComponentHandler['onModalSubmit']; + executeModal: ComponentHandler['executeModal']; + + hasComponent: ComponentHandler['hasComponent']; + executeComponent: ComponentHandler['executeComponent']; + onComponent: ComponentHandler['onComponent']; + + load: ComponentHandler['load']; + + onMessageDelete: ComponentHandler['onMessageDelete']; +} + export class ComponentHandler extends BaseHandler { - protected onFail?: OnFailCallback; + onFail?: OnFailCallback; readonly values = new Map(); // 10 minutes timeout, because discord dont send an event when the user cancel the modal readonly modals = new LimitedCollection({ expire: 60e3 * 10 }); @@ -99,11 +119,13 @@ export class ComponentHandler extends BaseHandler { } hasComponent(id: string, customId: string) { - return this.values.get(id)?.components?.some(x => { - if (typeof x.match === 'string') return x.match === customId; - if (Array.isArray(x.match)) return x.match.includes(customId); - return customId.match(x.match); - }); + return ( + this.values.get(id)?.components?.some(x => { + if (typeof x.match === 'string') return x.match === customId; + if (Array.isArray(x.match)) return x.match.includes(customId); + return customId.match(x.match); + }) ?? false + ); } resetTimeouts(id: string) { @@ -164,6 +186,7 @@ export class ComponentHandler extends BaseHandler { } async reload(path: string) { + if (!this.client.components) return; const component = this.client.components.commands.find( x => x.__filePath?.endsWith(`${path}.js`) || @@ -184,6 +207,7 @@ export class ComponentHandler extends BaseHandler { } async reloadAll() { + if (!this.client.components) return; for (const i of this.client.components.commands) { if (!i.__filePath) return this.logger.warn('Unknown command dont have __filePath property', i); await this.reload(i.__filePath); diff --git a/src/events/handler.ts b/src/events/handler.ts index f974a89..d303d24 100644 --- a/src/events/handler.ts +++ b/src/events/handler.ts @@ -19,6 +19,13 @@ type EventValue = MakeRequired & { fired?: boolean }; type GatewayEvents = Uppercase>; +export interface EventHandlerLike { + runEvent: EventHandler['runEvent']; + execute: EventHandler['execute']; + load: EventHandler['load']; + values: EventHandler['values']; +} + export class EventHandler extends BaseHandler { protected onFail: OnFailCallback = err => this.logger.warn('.events.OnFail', err); protected filter = (path: string) => path.endsWith('.js') || (!path.endsWith('.d.ts') && path.endsWith('.ts')); @@ -54,7 +61,7 @@ export class EventHandler extends BaseHandler { case 'MESSAGE_CREATE': { const { d: data } = args[0] as GatewayMessageCreateDispatch; - if (args[1].components.values.has(data.interaction?.id ?? data.id)) { + if (args[1].components?.values.has(data.interaction?.id ?? data.id)) { args[1].components.values.get(data.interaction?.id ?? data.id)!.messageId = data.id; } } @@ -62,20 +69,20 @@ export class EventHandler extends BaseHandler { case 'MESSAGE_DELETE': { const { d: data } = args[0] as GatewayMessageDeleteDispatch; - const value = [...args[1].components.values].find(x => x[1].messageId === data.id); + const value = [...(args[1].components?.values ?? [])].find(x => x[1].messageId === data.id); if (value) { - args[1].components.onMessageDelete(value[0]); + args[1].components!.onMessageDelete(value[0]); } } break; case 'MESSAGE_DELETE_BULK': { const { d: data } = args[0] as GatewayMessageDeleteBulkDispatch; - const values = [...args[1].components.values]; + const values = [...(args[1].components?.values ?? [])]; data.ids.forEach(id => { const value = values.find(x => x[1].messageId === id); if (value) { - args[1].components.onMessageDelete(value[0]); + args[1].components!.onMessageDelete(value[0]); } }); } diff --git a/src/langs/handler.ts b/src/langs/handler.ts index a60c04a..2621f69 100644 --- a/src/langs/handler.ts +++ b/src/langs/handler.ts @@ -1,6 +1,15 @@ import { BaseHandler, type Locale, type LocaleString } from '../common'; import { LangRouter } from './router'; +export interface LangsHandlerLike { + getKey: LangsHandler['getKey']; + load: LangsHandler['load']; + values: LangsHandler['values']; + aliases: LangsHandler['aliases']; + get: LangsHandler['get']; + defaultLang?: LangsHandler['defaultLang']; +} + export class LangsHandler extends BaseHandler { values: Partial> = {}; protected filter = (path: string) => diff --git a/src/structures/Interaction.ts b/src/structures/Interaction.ts index b3c0d2c..3b84c06 100644 --- a/src/structures/Interaction.ts +++ b/src/structures/Interaction.ts @@ -388,7 +388,7 @@ export class Interaction< .webhooks(this.applicationId)(this.token) .messages(messageId) .delete() - .then(() => this.client.components.onMessageDelete(messageId === '@original' ? this.id : messageId)); + .then(() => this.client.components?.onMessageDelete(messageId === '@original' ? this.id : messageId)); } async createResponse({ files, ...body }: MessageWebhookCreateBodyRequest) { diff --git a/src/structures/Message.ts b/src/structures/Message.ts index 51929e4..675c8c4 100644 --- a/src/structures/Message.ts +++ b/src/structures/Message.ts @@ -51,7 +51,7 @@ export class BaseMessage extends DiscordBase { } createComponentCollector(options?: ListenerOptions) { - return this.client.components.createComponentCollector(this.id, options); + return this.client.components!.createComponentCollector(this.id, options); } get url() {