diff --git a/src/cache/resources/default/base.ts b/src/cache/resources/default/base.ts index 9500a95..a28a42a 100644 --- a/src/cache/resources/default/base.ts +++ b/src/cache/resources/default/base.ts @@ -1,11 +1,10 @@ import type { GatewayIntentBits } from 'discord-api-types/v10'; -import type { BaseClient } from '../../../client/base'; import type { UsingClient } from '../../../commands'; import { fakePromise } from '../../../common'; import type { Cache, ReturnCache } from '../../index'; export class BaseResource { - client!: BaseClient; + client!: UsingClient; namespace = 'base'; constructor( diff --git a/src/cache/resources/default/guild-based.ts b/src/cache/resources/default/guild-based.ts index 8f43027..90125d9 100644 --- a/src/cache/resources/default/guild-based.ts +++ b/src/cache/resources/default/guild-based.ts @@ -1,11 +1,10 @@ import type { GatewayIntentBits } from 'discord-api-types/v10'; -import type { BaseClient } from '../../../client/base'; import type { UsingClient } from '../../../commands'; import { fakePromise } from '../../../common'; import type { Cache, ReturnCache } from '../../index'; export class GuildBasedResource { - client!: BaseClient; + client!: UsingClient; namespace = 'base'; constructor( diff --git a/src/client/base.ts b/src/client/base.ts index d01fcbd..67c27a5 100644 --- a/src/client/base.ts +++ b/src/client/base.ts @@ -39,6 +39,7 @@ import type { UserCommandInteraction, } from '../structures'; import type { ComponentCommand, ComponentContext, ModalCommand, ModalContext } from '../components'; +import { promises } from 'node:fs'; export class BaseClient { rest!: ApiHandler; @@ -269,6 +270,13 @@ export class BaseClient { throw new Error('Function not implemented'); } + shouldUploadCommands(cachePath: string) { + return this.commands!.shouldUpload(cachePath).then(async should => { + if (should) await promises.writeFile(cachePath, JSON.stringify(this.commands!.values.map(x => x.toJSON()))); + return should; + }); + } + async uploadCommands(applicationId?: string) { applicationId ??= await this.getRC().then(x => x.applicationId ?? this.applicationId); BaseClient.assertString(applicationId, 'applicationId is not a string'); diff --git a/src/client/oninteractioncreate.ts b/src/client/oninteractioncreate.ts index 9210b88..3be4878 100644 --- a/src/client/oninteractioncreate.ts +++ b/src/client/oninteractioncreate.ts @@ -8,6 +8,7 @@ import { type Command, type ContextMenuCommand, type ContextOptionsResolved, + type UsingClient, } from '../commands'; import type { ChatInputCommandInteraction, @@ -18,11 +19,10 @@ import type { __InternalReplyFunction, } from '../structures'; import { AutocompleteInteraction, BaseInteraction } from '../structures'; -import type { BaseClient } from './base'; import { ComponentContext, ModalContext } from '../components'; export async function onInteractionCreate( - self: BaseClient, + self: UsingClient, body: APIInteraction, shardId: number, __reply?: __InternalReplyFunction, diff --git a/src/client/onmessagecreate.ts b/src/client/onmessagecreate.ts index 54b9ab0..d686f44 100644 --- a/src/client/onmessagecreate.ts +++ b/src/client/onmessagecreate.ts @@ -328,6 +328,7 @@ async function parseOptions( value = args[i.name]; const option = i as SeyfertStringOption; if (!value) break; + console.log({ option, value }, value.length); if (option.min_length) { if (value.length < option.min_length) { value = undefined; @@ -428,10 +429,11 @@ async function parseOptions( value, } as APIApplicationCommandInteractionDataOption); } else if (i.required) - errors.push({ - error: 'Option is required but returned undefined', - name: i.name, - }); + if (!errors.some(x => x.name === i.name)) + errors.push({ + error: 'Option is required but returned undefined', + name: i.name, + }); } catch (e) { errors.push({ error: e && typeof e === 'object' && 'message' in e ? (e.message as string) : `${e}`, diff --git a/src/commands/handler.ts b/src/commands/handler.ts index 9cb4b21..84f9f55 100644 --- a/src/commands/handler.ts +++ b/src/commands/handler.ts @@ -1,10 +1,21 @@ -import { Locale, type LocaleString } from 'discord-api-types/v10'; +import { + type APIApplicationCommandOption, + Locale, + type LocaleString, + ApplicationCommandOptionType, + type APIApplicationCommandIntegerOption, + type APIApplicationCommandStringOption, + type APIApplicationCommandSubcommandOption, + type APIApplicationCommandSubcommandGroupOption, + type APIApplicationCommandChannelOption, +} from 'discord-api-types/v10'; import { basename, dirname } from 'node:path'; import type { Logger } from '../common'; import { BaseHandler } from '../common'; import { Command, SubCommand } from './applications/chat'; import { ContextMenuCommand } from './applications/menu'; import type { UsingClient } from './applications/shared'; +import { promises } from 'node:fs'; export class CommandHandler extends BaseHandler { values: (Command | ContextMenuCommand)[] = []; @@ -37,6 +48,127 @@ export class CommandHandler extends BaseHandler { } } + protected shouldUploadOption(option: APIApplicationCommandOption, cached: APIApplicationCommandOption) { + if (option.description !== cached.description) return true; + if (option.type !== cached.type) return true; + if (option.required !== cached.required) return true; + if (option.name !== cached.name) return true; + //TODO: locales + + switch (option.type) { + case ApplicationCommandOptionType.String: + return ( + option.min_length !== (cached as APIApplicationCommandStringOption).min_length || + option.max_length !== (cached as APIApplicationCommandStringOption).max_length + ); + case ApplicationCommandOptionType.Channel: + { + if (option.channel_types?.length !== (cached as APIApplicationCommandChannelOption).channel_types?.length) + return true; + if ('channel_types' in option && 'channel_types' in cached) { + if (!option.channel_types || !cached.channel_types) return true; + return option.channel_types.some(ct => !cached.channel_types!.includes(ct)); + } + } + return; + case ApplicationCommandOptionType.Subcommand: + case ApplicationCommandOptionType.SubcommandGroup: + if ( + option.options?.length !== + (cached as APIApplicationCommandSubcommandOption | APIApplicationCommandSubcommandGroupOption).options?.length + ) { + return true; + } + if ( + option.options && + (cached as APIApplicationCommandSubcommandOption | APIApplicationCommandSubcommandGroupOption).options + ) + for (const i of option.options) { + const cachedOption = ( + cached as APIApplicationCommandSubcommandOption | APIApplicationCommandSubcommandGroupOption + ).options!.find(x => x.name === i.name); + if (!cachedOption) return true; + if (this.shouldUploadOption(i, cachedOption)) return true; + } + break; + case ApplicationCommandOptionType.Integer: + case ApplicationCommandOptionType.Number: + return ( + option.min_value !== (cached as APIApplicationCommandIntegerOption).min_value || + option.max_value !== (cached as APIApplicationCommandIntegerOption).max_value + ); + case ApplicationCommandOptionType.Attachment: + case ApplicationCommandOptionType.Boolean: + case ApplicationCommandOptionType.Mentionable: + case ApplicationCommandOptionType.Role: + case ApplicationCommandOptionType.User: + break; + } + + return false; + } + + async shouldUpload(file: string) { + if ( + !(await promises.access(file).then( + () => true, + () => false, + )) + ) { + await promises.writeFile(file, JSON.stringify(this.values.map(x => x.toJSON()))); + return true; + } + + const cachedCommands: (ReturnType | ReturnType)[] = JSON.parse( + (await promises.readFile(file)).toString(), + ); + + if (cachedCommands.length !== this.values.length) return true; + + for (const command of this.values.map(x => x.toJSON())) { + const cached = cachedCommands.find(x => { + if (x.name !== command.name) return false; + if (command.guild_id) return command.guild_id.every(id => x.guild_id?.includes(id)); + return true; + }); + if (!cached) return true; + if (cached.description !== command.description) return true; + if (cached.default_member_permissions !== command.default_member_permissions) return true; + if (cached.type !== command.type) return true; + if (cached.nsfw !== command.nsfw) return true; + + if (!!('options' in cached) !== !!('options' in command)) return true; + if (!!cached.contexts !== !!command.contexts) return true; + if (!!cached.integration_types !== !!command.integration_types) return true; + //TODO: locales + + if ('contexts' in command && 'contexts' in cached) { + if (command.contexts?.length !== cached.contexts?.length) return true; + if (command.contexts && cached.contexts) { + if (command.contexts.some(ctx => !cached.contexts!.includes(ctx))) return true; + } + } + + if ('integration_types' in command && 'integration_types' in cached) { + if (command.integration_types?.length !== cached.integration_types?.length) return true; + if (command.integration_types && cached.integration_types) { + if (command.integration_types.some(ctx => !cached.integration_types!.includes(ctx))) return true; + } + } + + if ('options' in command && 'options' in cached) { + if (command.options.length !== cached.options.length) return true; + for (const option of command.options) { + const cachedOption = cached.options.find(x => x.name === option.name); + if (!cachedOption) return true; + if (this.shouldUploadOption(option, cachedOption)) return true; + } + } + } + + return false; + } + async load(commandsDir: string, client: UsingClient, instances?: { new (): Command | ContextMenuCommand }[]) { const result = instances?.map(x => { diff --git a/src/events/hooks/application_command.ts b/src/events/hooks/application_command.ts index 814cbad..d3b8421 100644 --- a/src/events/hooks/application_command.ts +++ b/src/events/hooks/application_command.ts @@ -1,9 +1,9 @@ import type { GatewayApplicationCommandPermissionsUpdateDispatchData } from 'discord-api-types/v10'; -import type { BaseClient } from '../../client/base'; import { toCamelCase } from '../../common'; +import type { UsingClient } from '../../commands'; export const APPLICATION_COMMAND_PERMISSIONS_UPDATE = ( - _self: BaseClient, + _self: UsingClient, data: GatewayApplicationCommandPermissionsUpdateDispatchData, ) => { return toCamelCase(data); diff --git a/src/events/hooks/auto_moderation.ts b/src/events/hooks/auto_moderation.ts index fba7fe3..d3a9ba0 100644 --- a/src/events/hooks/auto_moderation.ts +++ b/src/events/hooks/auto_moderation.ts @@ -4,25 +4,25 @@ import type { GatewayAutoModerationRuleDeleteDispatchData, GatewayAutoModerationRuleUpdateDispatchData, } from 'discord-api-types/v10'; -import type { BaseClient } from '../../client/base'; import { toCamelCase } from '../../common'; import { AutoModerationRule } from '../../structures'; +import type { UsingClient } from '../../commands'; export const AUTO_MODERATION_ACTION_EXECUTION = ( - _self: BaseClient, + _self: UsingClient, data: GatewayAutoModerationActionExecutionDispatchData, ) => { return toCamelCase(data); }; -export const AUTO_MODERATION_RULE_CREATE = (self: BaseClient, data: GatewayAutoModerationRuleCreateDispatchData) => { +export const AUTO_MODERATION_RULE_CREATE = (self: UsingClient, data: GatewayAutoModerationRuleCreateDispatchData) => { return new AutoModerationRule(self, data); }; -export const AUTO_MODERATION_RULE_DELETE = (self: BaseClient, data: GatewayAutoModerationRuleDeleteDispatchData) => { +export const AUTO_MODERATION_RULE_DELETE = (self: UsingClient, data: GatewayAutoModerationRuleDeleteDispatchData) => { return new AutoModerationRule(self, data); }; -export const AUTO_MODERATION_RULE_UPDATE = (self: BaseClient, data: GatewayAutoModerationRuleUpdateDispatchData) => { +export const AUTO_MODERATION_RULE_UPDATE = (self: UsingClient, data: GatewayAutoModerationRuleUpdateDispatchData) => { return new AutoModerationRule(self, data); }; diff --git a/src/events/hooks/channel.ts b/src/events/hooks/channel.ts index 8771c2b..357cc53 100644 --- a/src/events/hooks/channel.ts +++ b/src/events/hooks/channel.ts @@ -5,25 +5,25 @@ import type { GatewayChannelUpdateDispatchData, } from 'discord-api-types/v10'; -import type { BaseClient } from '../../client/base'; import { toCamelCase } from '../../common'; import type { AllChannels } from '../../structures'; import channelFrom from '../../structures/channels'; +import type { UsingClient } from '../../commands'; -export const CHANNEL_CREATE = (self: BaseClient, data: GatewayChannelCreateDispatchData) => { +export const CHANNEL_CREATE = (self: UsingClient, data: GatewayChannelCreateDispatchData) => { return channelFrom(data, self); }; -export const CHANNEL_DELETE = (self: BaseClient, data: GatewayChannelDeleteDispatchData) => { +export const CHANNEL_DELETE = (self: UsingClient, data: GatewayChannelDeleteDispatchData) => { return channelFrom(data, self); }; -export const CHANNEL_PINS_UPDATE = (_self: BaseClient, data: GatewayChannelPinsUpdateDispatchData) => { +export const CHANNEL_PINS_UPDATE = (_self: UsingClient, data: GatewayChannelPinsUpdateDispatchData) => { return toCamelCase(data); }; export const CHANNEL_UPDATE = async ( - self: BaseClient, + self: UsingClient, data: GatewayChannelUpdateDispatchData, ): Promise<[channel: AllChannels, old?: AllChannels]> => { return [channelFrom(data, self), await self.cache.channels?.get(data.id)]; diff --git a/src/events/hooks/custom.ts b/src/events/hooks/custom.ts index 389a228..67b87a7 100644 --- a/src/events/hooks/custom.ts +++ b/src/events/hooks/custom.ts @@ -1,10 +1,10 @@ -import type { BaseClient } from '../../client/base'; +import type { UsingClient } from '../../commands'; import type { ClientUser } from '../../structures'; -export const BOT_READY = (_self: BaseClient, me: ClientUser) => { +export const BOT_READY = (_self: UsingClient, me: ClientUser) => { return me; }; -export const WORKER_READY = (_self: BaseClient, me: ClientUser) => { +export const WORKER_READY = (_self: UsingClient, me: ClientUser) => { return me; }; diff --git a/src/events/hooks/dispatch.ts b/src/events/hooks/dispatch.ts index d58fb89..697c79e 100644 --- a/src/events/hooks/dispatch.ts +++ b/src/events/hooks/dispatch.ts @@ -1,15 +1,15 @@ import type { GatewayDispatchPayload, GatewayReadyDispatchData, GatewayResumedDispatch } from 'discord-api-types/v10'; -import type { BaseClient } from '../../client/base'; import { ClientUser } from '../../structures'; +import type { UsingClient } from '../../commands'; -export const READY = (self: BaseClient, data: GatewayReadyDispatchData) => { +export const READY = (self: UsingClient, data: GatewayReadyDispatchData) => { return new ClientUser(self, data.user, data.application); }; -export const RESUMED = (_self: BaseClient, _data: GatewayResumedDispatch['d']) => { +export const RESUMED = (_self: UsingClient, _data: GatewayResumedDispatch['d']) => { return; }; -export const RAW = (_self: BaseClient, data: GatewayDispatchPayload) => { +export const RAW = (_self: UsingClient, data: GatewayDispatchPayload) => { return data; }; diff --git a/src/events/hooks/entitlement.ts b/src/events/hooks/entitlement.ts index d5176ce..1ec8683 100644 --- a/src/events/hooks/entitlement.ts +++ b/src/events/hooks/entitlement.ts @@ -1,15 +1,15 @@ import type { APIEntitlement } from 'discord-api-types/v10'; -import type { BaseClient } from '../../client/base'; import { toCamelCase } from '../../common'; +import type { UsingClient } from '../../commands'; -export const ENTITLEMENT_CREATE = (_: BaseClient, data: APIEntitlement) => { +export const ENTITLEMENT_CREATE = (_: UsingClient, data: APIEntitlement) => { return toCamelCase(data); }; -export const ENTITLEMENT_UPDATE = (_: BaseClient, data: APIEntitlement) => { +export const ENTITLEMENT_UPDATE = (_: UsingClient, data: APIEntitlement) => { return toCamelCase(data); }; -export const ENTITLEMENT_DELETE = (_: BaseClient, data: APIEntitlement) => { +export const ENTITLEMENT_DELETE = (_: UsingClient, data: APIEntitlement) => { return toCamelCase(data); }; diff --git a/src/events/hooks/guild.ts b/src/events/hooks/guild.ts index e996591..1041965 100644 --- a/src/events/hooks/guild.ts +++ b/src/events/hooks/guild.ts @@ -20,7 +20,6 @@ import type { GatewayGuildStickersUpdateDispatchData, GatewayGuildUpdateDispatchData, } from 'discord-api-types/v10'; -import type { BaseClient } from '../../client/base'; import { toCamelCase } from '../../common'; import { Guild, @@ -32,48 +31,49 @@ import { User, type GatewayGuildMemberAddDispatchDataFixed, } from '../../structures'; +import type { UsingClient } from '../../commands'; -export const GUILD_AUDIT_LOG_ENTRY_CREATE = (_self: BaseClient, data: GatewayGuildAuditLogEntryCreateDispatchData) => { +export const GUILD_AUDIT_LOG_ENTRY_CREATE = (_self: UsingClient, data: GatewayGuildAuditLogEntryCreateDispatchData) => { return toCamelCase(data); }; -export const GUILD_BAN_ADD = (self: BaseClient, data: GatewayGuildBanAddDispatchData) => { +export const GUILD_BAN_ADD = (self: UsingClient, data: GatewayGuildBanAddDispatchData) => { return { ...toCamelCase(data), user: new User(self, data.user) }; }; -export const GUILD_BAN_REMOVE = (self: BaseClient, data: GatewayGuildBanRemoveDispatchData) => { +export const GUILD_BAN_REMOVE = (self: UsingClient, data: GatewayGuildBanRemoveDispatchData) => { return { ...toCamelCase(data), user: new User(self, data.user) }; }; -export const GUILD_CREATE = (self: BaseClient, data: GatewayGuildCreateDispatchData) => { +export const GUILD_CREATE = (self: UsingClient, data: GatewayGuildCreateDispatchData) => { return new Guild<'create'>(self, data); }; -export const GUILD_DELETE = async (self: BaseClient, data: GatewayGuildDeleteDispatchData) => { +export const GUILD_DELETE = async (self: UsingClient, data: GatewayGuildDeleteDispatchData) => { return (await self.cache.guilds?.get(data.id)) ?? data; }; -export const GUILD_EMOJIS_UPDATE = (self: BaseClient, data: GatewayGuildEmojisUpdateDispatchData) => { +export const GUILD_EMOJIS_UPDATE = (self: UsingClient, data: GatewayGuildEmojisUpdateDispatchData) => { return { ...toCamelCase(data), emojis: data.emojis.map(x => new GuildEmoji(self, x, data.guild_id)), }; }; -export const GUILD_INTEGRATIONS_UPDATE = (_self: BaseClient, data: GatewayGuildIntegrationsUpdateDispatchData) => { +export const GUILD_INTEGRATIONS_UPDATE = (_self: UsingClient, data: GatewayGuildIntegrationsUpdateDispatchData) => { return toCamelCase(data); }; -export const GUILD_MEMBER_ADD = (self: BaseClient, data: GatewayGuildMemberAddDispatchDataFixed) => { +export const GUILD_MEMBER_ADD = (self: UsingClient, data: GatewayGuildMemberAddDispatchDataFixed) => { if (!('user' in data)) return new UnavailableMember(self, data, data.id, data.guild_id); return new GuildMember(self, data, data.user, data.guild_id); }; -export const GUILD_MEMBER_REMOVE = (self: BaseClient, data: GatewayGuildMemberRemoveDispatchData) => { +export const GUILD_MEMBER_REMOVE = (self: UsingClient, data: GatewayGuildMemberRemoveDispatchData) => { return { ...toCamelCase(data), user: new User(self, data.user) }; }; -export const GUILD_MEMBERS_CHUNK = (self: BaseClient, data: GatewayGuildMembersChunkDispatchData) => { +export const GUILD_MEMBERS_CHUNK = (self: UsingClient, data: GatewayGuildMembersChunkDispatchData) => { return { ...toCamelCase(data), members: data.members.map(x => new GuildMember(self, x, x.user!, data.guild_id)), @@ -81,55 +81,64 @@ export const GUILD_MEMBERS_CHUNK = (self: BaseClient, data: GatewayGuildMembersC }; export const GUILD_MEMBER_UPDATE = async ( - self: BaseClient, + self: UsingClient, data: GatewayGuildMemberUpdateDispatchData, ): Promise<[member: GuildMember, old?: GuildMember]> => { const oldData = await self.cache.members?.get(data.user.id, data.guild_id); return [new GuildMember(self, data, data.user, data.guild_id), oldData]; }; -export const GUILD_SCHEDULED_EVENT_CREATE = (_self: BaseClient, data: GatewayGuildScheduledEventCreateDispatchData) => { +export const GUILD_SCHEDULED_EVENT_CREATE = ( + _self: UsingClient, + data: GatewayGuildScheduledEventCreateDispatchData, +) => { return toCamelCase(data); }; -export const GUILD_SCHEDULED_EVENT_UPDATE = (_self: BaseClient, data: GatewayGuildScheduledEventUpdateDispatchData) => { +export const GUILD_SCHEDULED_EVENT_UPDATE = ( + _self: UsingClient, + data: GatewayGuildScheduledEventUpdateDispatchData, +) => { return toCamelCase(data); }; -export const GUILD_SCHEDULED_EVENT_DELETE = (_self: BaseClient, data: GatewayGuildScheduledEventDeleteDispatchData) => { +export const GUILD_SCHEDULED_EVENT_DELETE = ( + _self: UsingClient, + data: GatewayGuildScheduledEventDeleteDispatchData, +) => { return toCamelCase(data); }; export const GUILD_SCHEDULED_EVENT_USER_ADD = ( - _self: BaseClient, + _self: UsingClient, data: GatewayGuildScheduledEventUserAddDispatchData, ) => { return toCamelCase(data); }; export const GUILD_SCHEDULED_EVENT_USER_REMOVE = ( - _self: BaseClient, + _self: UsingClient, data: GatewayGuildScheduledEventUserRemoveDispatchData, ) => { return toCamelCase(data); }; -export const GUILD_ROLE_CREATE = (self: BaseClient, data: GatewayGuildRoleCreateDispatchData) => { +export const GUILD_ROLE_CREATE = (self: UsingClient, data: GatewayGuildRoleCreateDispatchData) => { return new GuildRole(self, data.role, data.guild_id); }; -export const GUILD_ROLE_DELETE = async (self: BaseClient, data: GatewayGuildRoleDeleteDispatchData) => { +export const GUILD_ROLE_DELETE = async (self: UsingClient, data: GatewayGuildRoleDeleteDispatchData) => { return (await self.cache.roles?.get(data.role_id)) || toCamelCase(data); }; export const GUILD_ROLE_UPDATE = async ( - self: BaseClient, + self: UsingClient, data: GatewayGuildRoleUpdateDispatchData, ): Promise<[role: GuildRole, old?: GuildRole]> => { return [new GuildRole(self, data.role, data.guild_id), await self.cache.roles?.get(data.role.id)]; }; -export const GUILD_STICKERS_UPDATE = (self: BaseClient, data: GatewayGuildStickersUpdateDispatchData) => { +export const GUILD_STICKERS_UPDATE = (self: UsingClient, data: GatewayGuildStickersUpdateDispatchData) => { return { ...toCamelCase(data), stickers: data.stickers.map(x => new Sticker(self, x)), @@ -137,7 +146,7 @@ export const GUILD_STICKERS_UPDATE = (self: BaseClient, data: GatewayGuildSticke }; export const GUILD_UPDATE = async ( - self: BaseClient, + self: UsingClient, data: GatewayGuildUpdateDispatchData, ): Promise<[guild: Guild, old?: Guild<'cached'>]> => { return [new Guild(self, data), await self.cache.guilds?.get(data.id)]; diff --git a/src/events/hooks/integration.ts b/src/events/hooks/integration.ts index e273dea..206f685 100644 --- a/src/events/hooks/integration.ts +++ b/src/events/hooks/integration.ts @@ -3,11 +3,11 @@ import type { GatewayIntegrationDeleteDispatchData, GatewayIntegrationUpdateDispatchData, } from 'discord-api-types/v10'; -import type { BaseClient } from '../../client/base'; import { toCamelCase } from '../../common'; import { User } from '../../structures'; +import type { UsingClient } from '../../commands'; -export const INTEGRATION_CREATE = (self: BaseClient, data: GatewayIntegrationCreateDispatchData) => { +export const INTEGRATION_CREATE = (self: UsingClient, data: GatewayIntegrationCreateDispatchData) => { return data.user ? { ...toCamelCase(data), @@ -16,7 +16,7 @@ export const INTEGRATION_CREATE = (self: BaseClient, data: GatewayIntegrationCre : toCamelCase(data); }; -export const INTEGRATION_UPDATE = (self: BaseClient, data: GatewayIntegrationUpdateDispatchData) => { +export const INTEGRATION_UPDATE = (self: UsingClient, data: GatewayIntegrationUpdateDispatchData) => { return data.user ? { ...toCamelCase(data), @@ -26,7 +26,7 @@ export const INTEGRATION_UPDATE = (self: BaseClient, data: GatewayIntegrationUpd }; export const INTEGRATION_DELETE = ( - _self: BaseClient, + _self: UsingClient, data: GatewayIntegrationDeleteDispatchData, ) => { diff --git a/src/events/hooks/interactions.ts b/src/events/hooks/interactions.ts index 75b1212..a336fab 100644 --- a/src/events/hooks/interactions.ts +++ b/src/events/hooks/interactions.ts @@ -1,7 +1,7 @@ import type { GatewayInteractionCreateDispatchData } from 'discord-api-types/v10'; -import type { BaseClient } from '../../client/base'; import { BaseInteraction } from '../../structures'; +import type { UsingClient } from '../../commands'; -export const INTERACTION_CREATE = (self: BaseClient, data: GatewayInteractionCreateDispatchData) => { +export const INTERACTION_CREATE = (self: UsingClient, data: GatewayInteractionCreateDispatchData) => { return BaseInteraction.from(self, data); }; diff --git a/src/events/hooks/invite.ts b/src/events/hooks/invite.ts index f6c4209..a6b1171 100644 --- a/src/events/hooks/invite.ts +++ b/src/events/hooks/invite.ts @@ -1,12 +1,11 @@ import type { GatewayInviteCreateDispatchData, GatewayInviteDeleteDispatchData } from 'discord-api-types/v10'; - -import type { BaseClient } from '../../client/base'; +import type { UsingClient } from '../../commands'; import { toCamelCase } from '../../common'; -export const INVITE_CREATE = (_self: BaseClient, data: GatewayInviteCreateDispatchData) => { +export const INVITE_CREATE = (_self: UsingClient, data: GatewayInviteCreateDispatchData) => { return toCamelCase(data); }; -export const INVITE_DELETE = (_self: BaseClient, data: GatewayInviteDeleteDispatchData) => { +export const INVITE_DELETE = (_self: UsingClient, data: GatewayInviteDeleteDispatchData) => { return toCamelCase(data); }; diff --git a/src/events/hooks/message.ts b/src/events/hooks/message.ts index 8831a40..d2314bd 100644 --- a/src/events/hooks/message.ts +++ b/src/events/hooks/message.ts @@ -10,46 +10,46 @@ import type { GatewayMessageReactionRemoveEmojiDispatchData, GatewayMessageUpdateDispatchData, } from 'discord-api-types/v10'; -import type { BaseClient } from '../../client/base'; import { type MakeRequired, type PartialClass, toCamelCase } from '../../common'; import { Message } from '../../structures'; +import type { UsingClient } from '../../commands'; -export const MESSAGE_CREATE = (self: BaseClient, data: GatewayMessageCreateDispatchData) => { +export const MESSAGE_CREATE = (self: UsingClient, data: GatewayMessageCreateDispatchData) => { return new Message(self, data); }; -export const MESSAGE_DELETE = async (self: BaseClient, data: GatewayMessageDeleteDispatchData) => { +export const MESSAGE_DELETE = async (self: UsingClient, data: GatewayMessageDeleteDispatchData) => { return (await self.cache.messages?.get(data.id)) ?? toCamelCase(data); }; -export const MESSAGE_DELETE_BULK = async (self: BaseClient, data: GatewayMessageDeleteBulkDispatchData) => { +export const MESSAGE_DELETE_BULK = async (self: UsingClient, data: GatewayMessageDeleteBulkDispatchData) => { return { ...data, messages: await Promise.all(data.ids.map(id => self.cache.messages?.get(id))), }; }; -export const MESSAGE_REACTION_ADD = (_self: BaseClient, data: GatewayMessageReactionAddDispatchData) => { +export const MESSAGE_REACTION_ADD = (_self: UsingClient, data: GatewayMessageReactionAddDispatchData) => { return toCamelCase(data); }; -export const MESSAGE_REACTION_REMOVE = (_self: BaseClient, data: GatewayMessageReactionRemoveDispatchData) => { +export const MESSAGE_REACTION_REMOVE = (_self: UsingClient, data: GatewayMessageReactionRemoveDispatchData) => { return toCamelCase(data); }; -export const MESSAGE_REACTION_REMOVE_ALL = (_self: BaseClient, data: GatewayMessageReactionRemoveAllDispatchData) => { +export const MESSAGE_REACTION_REMOVE_ALL = (_self: UsingClient, data: GatewayMessageReactionRemoveAllDispatchData) => { return toCamelCase(data); }; export const MESSAGE_REACTION_REMOVE_EMOJI = ( - _self: BaseClient, + _self: UsingClient, data: GatewayMessageReactionRemoveEmojiDispatchData, ) => { return toCamelCase(data); }; export const MESSAGE_UPDATE = async ( - self: BaseClient, + self: UsingClient, data: GatewayMessageUpdateDispatchData, ): Promise< [ @@ -74,10 +74,10 @@ export const MESSAGE_UPDATE = async ( return [new Message(self, data as APIMessage), await self.cache.messages?.get(data.id)]; }; -export const MESSAGE_POLL_VOTE_ADD = (_: BaseClient, data: GatewayMessagePollVoteDispatchData) => { +export const MESSAGE_POLL_VOTE_ADD = (_: UsingClient, data: GatewayMessagePollVoteDispatchData) => { return toCamelCase(data); }; -export const MESSAGE_POLL_VOTE_REMOVE = (_: BaseClient, data: GatewayMessagePollVoteDispatchData) => { +export const MESSAGE_POLL_VOTE_REMOVE = (_: UsingClient, data: GatewayMessagePollVoteDispatchData) => { return toCamelCase(data); }; diff --git a/src/events/hooks/presence.ts b/src/events/hooks/presence.ts index 60a9505..a70f2f2 100644 --- a/src/events/hooks/presence.ts +++ b/src/events/hooks/presence.ts @@ -1,8 +1,7 @@ import type { GatewayPresenceUpdateDispatchData } from 'discord-api-types/v10'; - -import type { BaseClient } from '../../client/base'; +import type { UsingClient } from '../../commands'; import { toCamelCase } from '../../common'; -export const PRESENCE_UPDATE = async (self: BaseClient, data: GatewayPresenceUpdateDispatchData) => { +export const PRESENCE_UPDATE = async (self: UsingClient, data: GatewayPresenceUpdateDispatchData) => { return [toCamelCase(data), await self.cache.presences?.get(data.user.id)]; }; diff --git a/src/events/hooks/stage.ts b/src/events/hooks/stage.ts index 92d3ef8..6f59da3 100644 --- a/src/events/hooks/stage.ts +++ b/src/events/hooks/stage.ts @@ -3,21 +3,20 @@ import type { GatewayStageInstanceDeleteDispatchData, GatewayStageInstanceUpdateDispatchData, } from 'discord-api-types/v10'; - -import type { BaseClient } from '../../client/base'; +import type { UsingClient } from '../../commands'; import { type ObjectToLower, toCamelCase } from '../../common'; import type { StageInstances } from '../../cache/resources/stage-instances'; -export const STAGE_INSTANCE_CREATE = (_self: BaseClient, data: GatewayStageInstanceCreateDispatchData) => { +export const STAGE_INSTANCE_CREATE = (_self: UsingClient, data: GatewayStageInstanceCreateDispatchData) => { return toCamelCase(data); }; -export const STAGE_INSTANCE_DELETE = (_self: BaseClient, data: GatewayStageInstanceDeleteDispatchData) => { +export const STAGE_INSTANCE_DELETE = (_self: UsingClient, data: GatewayStageInstanceDeleteDispatchData) => { return toCamelCase(data); }; export const STAGE_INSTANCE_UPDATE = async ( - self: BaseClient, + self: UsingClient, data: GatewayStageInstanceUpdateDispatchData, ): Promise<[stage: ObjectToLower, old?: ReturnType]> => { return [toCamelCase(data), await self.cache.stageInstances?.get(data.id)]; diff --git a/src/events/hooks/thread.ts b/src/events/hooks/thread.ts index 820e654..28ee4fb 100644 --- a/src/events/hooks/thread.ts +++ b/src/events/hooks/thread.ts @@ -6,32 +6,32 @@ import type { GatewayThreadMembersUpdateDispatchData, GatewayThreadUpdateDispatchData, } from 'discord-api-types/v10'; -import type { BaseClient } from '../../client/base'; import { toCamelCase } from '../../common'; import { ThreadChannel } from '../../structures'; +import type { UsingClient } from '../../commands'; -export const THREAD_CREATE = (self: BaseClient, data: GatewayThreadCreateDispatchData) => { +export const THREAD_CREATE = (self: UsingClient, data: GatewayThreadCreateDispatchData) => { return new ThreadChannel(self, data); }; -export const THREAD_DELETE = (self: BaseClient, data: GatewayThreadDeleteDispatchData) => { +export const THREAD_DELETE = (self: UsingClient, data: GatewayThreadDeleteDispatchData) => { return new ThreadChannel(self, data); }; -export const THREAD_LIST_SYNC = (_self: BaseClient, data: GatewayThreadListSyncDispatchData) => { +export const THREAD_LIST_SYNC = (_self: UsingClient, data: GatewayThreadListSyncDispatchData) => { return toCamelCase(data); }; -export const THREAD_MEMBER_UPDATE = (_self: BaseClient, data: GatewayThreadMemberUpdateDispatchData) => { +export const THREAD_MEMBER_UPDATE = (_self: UsingClient, data: GatewayThreadMemberUpdateDispatchData) => { return toCamelCase(data); }; -export const THREAD_MEMBERS_UPDATE = (_self: BaseClient, data: GatewayThreadMembersUpdateDispatchData) => { +export const THREAD_MEMBERS_UPDATE = (_self: UsingClient, data: GatewayThreadMembersUpdateDispatchData) => { return toCamelCase(data); }; export const THREAD_UPDATE = async ( - self: BaseClient, + self: UsingClient, data: GatewayThreadUpdateDispatchData, ): Promise<[thread: ThreadChannel, old?: ThreadChannel]> => { return [new ThreadChannel(self, data), await self.cache.threads?.get(data.id)]; diff --git a/src/events/hooks/typing.ts b/src/events/hooks/typing.ts index af33789..effa657 100644 --- a/src/events/hooks/typing.ts +++ b/src/events/hooks/typing.ts @@ -1,10 +1,9 @@ import type { GatewayTypingStartDispatchData } from 'discord-api-types/v10'; - -import type { BaseClient } from '../../client/base'; import { toCamelCase } from '../../common'; import { GuildMember } from '../../structures'; +import type { UsingClient } from '../../commands'; -export const TYPING_START = (self: BaseClient, data: GatewayTypingStartDispatchData) => { +export const TYPING_START = (self: UsingClient, data: GatewayTypingStartDispatchData) => { return data.member ? { ...toCamelCase(data), diff --git a/src/events/hooks/user.ts b/src/events/hooks/user.ts index 1a24493..dd23fc5 100644 --- a/src/events/hooks/user.ts +++ b/src/events/hooks/user.ts @@ -1,9 +1,9 @@ import type { GatewayUserUpdateDispatchData } from 'discord-api-types/v10'; -import type { BaseClient } from '../../client/base'; import { User } from '../../structures'; +import type { UsingClient } from '../../commands'; export const USER_UPDATE = async ( - self: BaseClient, + self: UsingClient, data: GatewayUserUpdateDispatchData, ): Promise<[user: User, old?: User]> => { return [new User(self, data), await self.cache.users?.get(data.id)]; diff --git a/src/events/hooks/voice.ts b/src/events/hooks/voice.ts index e704f83..5267930 100644 --- a/src/events/hooks/voice.ts +++ b/src/events/hooks/voice.ts @@ -1,14 +1,14 @@ import type { GatewayVoiceServerUpdateDispatchData, GatewayVoiceStateUpdateDispatchData } from '../../types'; -import type { BaseClient } from '../../client/base'; import { toCamelCase } from '../../common'; import { VoiceState } from '../../structures'; +import type { UsingClient } from '../../commands'; -export const VOICE_SERVER_UPDATE = (_self: BaseClient, data: GatewayVoiceServerUpdateDispatchData) => { +export const VOICE_SERVER_UPDATE = (_self: UsingClient, data: GatewayVoiceServerUpdateDispatchData) => { return toCamelCase(data); }; export const VOICE_STATE_UPDATE = async ( - self: BaseClient, + self: UsingClient, data: GatewayVoiceStateUpdateDispatchData, ): Promise<[VoiceState] | [state: VoiceState, old?: VoiceState]> => { if (!data.guild_id) return [new VoiceState(self, data)]; diff --git a/src/events/hooks/webhook.ts b/src/events/hooks/webhook.ts index c475d3b..cf7d0ce 100644 --- a/src/events/hooks/webhook.ts +++ b/src/events/hooks/webhook.ts @@ -1,7 +1,7 @@ import type { GatewayWebhooksUpdateDispatchData } from 'discord-api-types/v10'; -import type { BaseClient } from '../../client/base'; import { toCamelCase } from '../../common'; +import type { UsingClient } from '../../commands'; -export const WEBHOOKS_UPDATE = (_self: BaseClient, data: GatewayWebhooksUpdateDispatchData) => { +export const WEBHOOKS_UPDATE = (_self: UsingClient, data: GatewayWebhooksUpdateDispatchData) => { return toCamelCase(data); }; diff --git a/src/structures/Interaction.ts b/src/structures/Interaction.ts index 5655041..c0d38a3 100644 --- a/src/structures/Interaction.ts +++ b/src/structures/Interaction.ts @@ -57,7 +57,6 @@ import { User } from './User'; import channelFrom from './channels'; import { DiscordBase } from './extra/DiscordBase'; import { PermissionsBitField } from './extra/Permissions'; -import type { BaseClient } from '../client/base'; export type ReplyInteractionBody = | { type: InteractionResponseType.Modal; data: ModalCreateBodyRequest } @@ -115,7 +114,7 @@ export class BaseInteraction< this.user = this.member?.user ?? new User(client, interaction.user!); } - static transformBodyRequest(body: ReplyInteractionBody, self: BaseClient): APIInteractionResponse { + static transformBodyRequest(body: ReplyInteractionBody, self: UsingClient): APIInteractionResponse { switch (body.type) { case InteractionResponseType.ApplicationCommandAutocompleteResult: case InteractionResponseType.DeferredMessageUpdate: