From cfdf77027a172fe4362793b4dda9b4e4bbe12153 Mon Sep 17 00:00:00 2001 From: Fleny Date: Sat, 9 Nov 2024 17:27:55 +0100 Subject: [PATCH] refactor(types,utils,rest,bot)!: Cleanup types & files (#3951) * Cleanup some un-used & sort types, split files * Remove commented code from reverse/component.ts * Fix type error on the bot E2E test * Add comment, remove DiscordInteractionResponse * Remove camel.ts * Error on unusedImport, refactor type imports * Run biome check * fix: typo * Update comments for skuId and defaultValues --------- Co-authored-by: Awesome Stickz --- biome.jsonc | 4 +- examples/bigbot/src/rest/index.ts | 2 +- packages/bot/src/bot.ts | 160 +-- packages/bot/src/desiredProperties.ts | 1014 ++++++++++++++++ packages/bot/src/events.ts | 138 +++ packages/bot/src/handlers.ts | 8 +- packages/bot/src/helpers.ts | 94 +- packages/bot/src/index.ts | 4 +- packages/bot/src/optionalize.ts | 73 -- packages/bot/src/transformers.ts | 1033 +---------------- .../bot/src/transformers/auditLogEntry.ts | 2 +- packages/bot/src/transformers/component.ts | 89 +- packages/bot/src/transformers/index.ts | 1 + packages/bot/src/transformers/interaction.ts | 27 +- packages/bot/src/transformers/member.ts | 2 +- packages/bot/src/transformers/onboarding.ts | 2 +- .../src/transformers/reverse/auditLogEntry.ts | 2 +- .../bot/src/transformers/reverse/component.ts | 80 +- .../reverse/createApplicationCommand.ts | 3 +- .../bot/src/transformers/reverse/index.ts | 1 - .../reverse/interactionResponse.ts | 26 - packages/bot/src/transformers/threadMember.ts | 3 +- packages/bot/src/transformers/types.ts | 12 +- packages/bot/src/typings.ts | 220 ---- packages/bot/tests/e2e/resetguilds.spec.ts | 2 +- .../discordeno/src/bin/generate/typescript.ts | 2 +- packages/discordeno/tests/generate.spec.ts | 2 +- packages/gateway/src/Shard.ts | 2 +- packages/rest/src/types.ts | 695 +++++------ packages/types/src/camel.ts | 350 ------ packages/types/src/discord.ts | 135 ++- packages/types/src/discordeno.ts | 8 +- packages/types/src/index.ts | 1 - packages/types/src/shared.ts | 2 +- packages/utils/src/typeguards.ts | 23 +- website/sidebars.ts | 2 +- .../src/components/architecture/FlowChart.tsx | 2 +- .../src/components/home/features/feature.tsx | 2 +- .../src/components/home/features/index.tsx | 2 +- website/src/styling/index.css | 6 +- 40 files changed, 1819 insertions(+), 2417 deletions(-) create mode 100644 packages/bot/src/desiredProperties.ts create mode 100644 packages/bot/src/events.ts delete mode 100644 packages/bot/src/optionalize.ts delete mode 100644 packages/bot/src/transformers/reverse/interactionResponse.ts delete mode 100644 packages/bot/src/typings.ts delete mode 100644 packages/types/src/camel.ts diff --git a/biome.jsonc b/biome.jsonc index 097c65506..56e7545c8 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -16,11 +16,13 @@ "rules": { "recommended": false, "correctness": { - "noUnusedVariables": "error" + "noUnusedVariables": "error", + "noUnusedImports": "error" }, "style": { "noNamespace": "error", "noNonNullAssertion": "off", + "useImportType": "error", "useConsistentArrayType": { "level": "error", "options": { "syntax": "shorthand" } diff --git a/examples/bigbot/src/rest/index.ts b/examples/bigbot/src/rest/index.ts index 2aa3503ff..50696f958 100644 --- a/examples/bigbot/src/rest/index.ts +++ b/examples/bigbot/src/rest/index.ts @@ -1,4 +1,4 @@ -import { type RequestMethods } from '@discordeno/bot' +import type { RequestMethods } from '@discordeno/bot' import { REST_HOST, REST_PORT } from '../config.js' import { buildFastifyApp, parseMultiformBody } from './fastify.js' import restManager, { logger } from './restManager.js' diff --git a/packages/bot/src/bot.ts b/packages/bot/src/bot.ts index 5b375d6a1..84de53584 100644 --- a/packages/bot/src/bot.ts +++ b/packages/bot/src/bot.ts @@ -2,43 +2,13 @@ import type { CreateGatewayManagerOptions, GatewayManager } from '@discordeno/ga import { ShardSocketCloseCodes, createGatewayManager } from '@discordeno/gateway' import type { CreateRestManagerOptions, RestManager } from '@discordeno/rest' import { createRestManager } from '@discordeno/rest' -import type { - BigString, - DiscordGatewayPayload, - DiscordReady, - DiscordVoiceChannelEffectAnimationType, - GatewayIntents, - RecursivePartial, -} from '@discordeno/types' -import { type Collection, createLogger, getBotIdFromToken, type logger } from '@discordeno/utils' -import { createBotGatewayHandlers } from './handlers.js' +import type { BigString, GatewayDispatchEventNames, GatewayIntents, RecursivePartial } from '@discordeno/types' +import { createLogger, getBotIdFromToken, type logger } from '@discordeno/utils' +import type { TransformersDesiredProperties } from './desiredProperties.js' +import type { EventHandlers } from './events.js' +import { type GatewayHandlers, createBotGatewayHandlers } from './handlers.js' import { type BotHelpers, createBotHelpers } from './helpers.js' -import { type Transformers, type TransformersDesiredProperties, createTransformers } from './transformers.js' -import type { - AuditLogEntry, - AutoModerationActionExecution, - AutoModerationRule, - Channel, - Emoji, - Entitlement, - Guild, - GuildApplicationCommandPermissions, - Integration, - Interaction, - Invite, - Member, - Message, - PresenceUpdate, - Role, - ScheduledEvent, - SoundboardSound, - Sticker, - Subscription, - ThreadMember, - User, - VoiceState, -} from './transformers/index.js' -import type { BotGatewayHandlerOptions } from './typings.js' +import { type Transformers, createTransformers } from './transformers.js' /** * Create a bot object that will maintain the rest and gateway connection. @@ -65,7 +35,7 @@ export function createBot(options: CreateBotOptions): Bot { // RUN DISPATCH CHECK await bot.events.dispatchRequirements?.(data, shard.id) - bot.handlers[data.t as keyof ReturnType]?.(bot, data, shard.id) + bot.handlers[data.t as GatewayDispatchEventNames]?.(bot, data, shard.id) } } @@ -133,7 +103,7 @@ export interface CreateBotOptions { /** The functions that should transform discord objects to discordeno shaped objects. */ transformers?: RecursivePartial /** The handler functions that should handle incoming discord payloads from gateway and call an event. */ - handlers?: Partial + handlers?: Partial /** * @deprecated Use with caution * @@ -176,122 +146,10 @@ export interface Bot { /** The functions that should transform discord objects to discordeno shaped objects. */ transformers: Transformers /** The handler functions that should handle incoming discord payloads from gateway and call an event. */ - handlers: ReturnType + handlers: GatewayHandlers helpers: BotHelpers /** Start the bot connection to the gateway. */ start: () => Promise /** Shuts down all the bot connections to the gateway. */ shutdown: () => Promise } - -export interface EventHandlers { - debug: (text: string, ...args: any[]) => unknown - applicationCommandPermissionsUpdate: (command: GuildApplicationCommandPermissions) => unknown - guildAuditLogEntryCreate: (log: AuditLogEntry, guildId: bigint) => unknown - automodRuleCreate: (rule: AutoModerationRule) => unknown - automodRuleUpdate: (rule: AutoModerationRule) => unknown - automodRuleDelete: (rule: AutoModerationRule) => unknown - automodActionExecution: (payload: AutoModerationActionExecution) => unknown - threadCreate: (thread: Channel) => unknown - threadDelete: (thread: Channel) => unknown - threadListSync: (payload: { guildId: bigint; channelIds?: bigint[]; threads: Channel[]; members: ThreadMember[] }) => unknown - threadMemberUpdate: (payload: { id: bigint; guildId: bigint; joinedAt: number; flags: number }) => unknown - threadMembersUpdate: (payload: { id: bigint; guildId: bigint; addedMembers?: ThreadMember[]; removedMemberIds?: bigint[] }) => unknown - threadUpdate: (thread: Channel) => unknown - scheduledEventCreate: (event: ScheduledEvent) => unknown - scheduledEventUpdate: (event: ScheduledEvent) => unknown - scheduledEventDelete: (event: ScheduledEvent) => unknown - /** Sent when a user has subscribed to a guild scheduled event. EXPERIMENTAL! */ - scheduledEventUserAdd: (payload: { guildScheduledEventId: bigint; guildId: bigint; userId: bigint }) => unknown - /** Sent when a user has unsubscribed to a guild scheduled event. EXPERIMENTAL! */ - scheduledEventUserRemove: (payload: { guildScheduledEventId: bigint; guildId: bigint; userId: bigint }) => unknown - ready: ( - payload: { - shardId: number - v: number - user: User - guilds: bigint[] - sessionId: string - shard?: number[] - applicationId: bigint - }, - rawPayload: DiscordReady, - ) => unknown - interactionCreate: (interaction: Interaction) => unknown - integrationCreate: (integration: Integration) => unknown - integrationDelete: (payload: { id: bigint; guildId: bigint; applicationId?: bigint }) => unknown - integrationUpdate: (payload: { guildId: bigint }) => unknown - inviteCreate: (invite: Invite) => unknown - inviteDelete: (payload: { channelId: bigint; guildId?: bigint; code: string }) => unknown - guildMemberAdd: (member: Member, user: User) => unknown - guildMemberRemove: (user: User, guildId: bigint) => unknown - guildMemberUpdate: (member: Member, user: User) => unknown - guildStickersUpdate: (payload: { guildId: bigint; stickers: Sticker[] }) => unknown - messageCreate: (message: Message) => unknown - messageDelete: (payload: { id: bigint; channelId: bigint; guildId?: bigint }, message?: Message) => unknown - messageDeleteBulk: (payload: { ids: bigint[]; channelId: bigint; guildId?: bigint }) => unknown - messageUpdate: (message: Message) => unknown - reactionAdd: (payload: { - userId: bigint - channelId: bigint - messageId: bigint - guildId?: bigint - member?: Member - user?: User - emoji: Emoji - messageAuthorId?: bigint - burst: boolean - burstColors?: string[] - }) => unknown - reactionRemove: (payload: { userId: bigint; channelId: bigint; messageId: bigint; guildId?: bigint; emoji: Emoji; burst: boolean }) => unknown - reactionRemoveEmoji: (payload: { channelId: bigint; messageId: bigint; guildId?: bigint; emoji: Emoji }) => unknown - reactionRemoveAll: (payload: { channelId: bigint; messageId: bigint; guildId?: bigint }) => unknown - presenceUpdate: (presence: PresenceUpdate) => unknown - voiceChannelEffectSend: (payload: { - channelId: bigint - guildId: bigint - userId: bigint - emoji?: Emoji - animationType?: DiscordVoiceChannelEffectAnimationType - animationId?: number - soundId?: bigint | number - soundVolume?: number - }) => unknown - voiceServerUpdate: (payload: { token: string; endpoint?: string; guildId: bigint }) => unknown - voiceStateUpdate: (voiceState: VoiceState) => unknown - channelCreate: (channel: Channel) => unknown - dispatchRequirements: (data: DiscordGatewayPayload, shardId: number) => unknown - channelDelete: (channel: Channel) => unknown - channelPinsUpdate: (data: { guildId?: bigint; channelId: bigint; lastPinTimestamp?: number }) => unknown - channelUpdate: (channel: Channel) => unknown - stageInstanceCreate: (data: { id: bigint; guildId: bigint; channelId: bigint; topic: string }) => unknown - stageInstanceDelete: (data: { id: bigint; guildId: bigint; channelId: bigint; topic: string }) => unknown - stageInstanceUpdate: (data: { id: bigint; guildId: bigint; channelId: bigint; topic: string }) => unknown - guildEmojisUpdate: (payload: { guildId: bigint; emojis: Collection }) => unknown - guildBanAdd: (user: User, guildId: bigint) => unknown - guildBanRemove: (user: User, guildId: bigint) => unknown - guildCreate: (guild: Guild) => unknown - guildDelete: (id: bigint, shardId: number) => unknown - guildUnavailable: (id: bigint, shardId: number) => unknown - guildUpdate: (guild: Guild) => unknown - raw: (data: DiscordGatewayPayload, shardId: number) => unknown - roleCreate: (role: Role) => unknown - roleDelete: (payload: { guildId: bigint; roleId: bigint }) => unknown - roleUpdate: (role: Role) => unknown - webhooksUpdate: (payload: { channelId: bigint; guildId: bigint }) => unknown - botUpdate: (user: User) => unknown - typingStart: (payload: { guildId: bigint | undefined; channelId: bigint; userId: bigint; timestamp: number; member: Member | undefined }) => unknown - entitlementCreate: (entitlement: Entitlement) => unknown - entitlementUpdate: (entitlement: Entitlement) => unknown - entitlementDelete: (entitlement: Entitlement) => unknown - subscriptionCreate: (subscription: Subscription) => unknown - subscriptionUpdate: (subscription: Subscription) => unknown - subscriptionDelete: (subscription: Subscription) => unknown - messagePollVoteAdd: (payload: { userId: bigint; channelId: bigint; messageId: bigint; guildId?: bigint; answerId: number }) => unknown - messagePollVoteRemove: (payload: { userId: bigint; channelId: bigint; messageId: bigint; guildId?: bigint; answerId: number }) => unknown - soundboardSoundCreate: (payload: SoundboardSound) => unknown - soundboardSoundUpdate: (payload: SoundboardSound) => unknown - soundboardSoundDelete: (payload: { soundId: bigint; guildId: bigint }) => unknown - soundboardSoundsUpdate: (payload: { soundboardSounds: SoundboardSound[]; guildId: bigint }) => unknown - soundboardSounds: (payload: { soundboardSounds: SoundboardSound[]; guildId: bigint }) => unknown -} diff --git a/packages/bot/src/desiredProperties.ts b/packages/bot/src/desiredProperties.ts new file mode 100644 index 000000000..1421b0916 --- /dev/null +++ b/packages/bot/src/desiredProperties.ts @@ -0,0 +1,1014 @@ +import type { RecursivePartial } from '@discordeno/types' + +export interface TransformersDesiredProperties { + activityInstance: { + applicationId: boolean + instanceId: boolean + launchId: boolean + location: boolean + users: boolean + } + activityLocation: { + id: boolean + kind: boolean + channelId: boolean + guildId: boolean + } + attachment: { + id: boolean + filename: boolean + title: boolean + contentType: boolean + size: boolean + url: boolean + proxyUrl: boolean + height: boolean + width: boolean + ephemeral: boolean + description: boolean + duration_secs: boolean + waveform: boolean + flags: boolean + } + channel: { + type: boolean + position: boolean + name: boolean + topic: boolean + nsfw: boolean + bitrate: boolean + userLimit: boolean + rateLimitPerUser: boolean + rtcRegion: boolean + videoQualityMode: boolean + guildId: boolean + lastPinTimestamp: boolean + permissionOverwrites: boolean + id: boolean + permissions: boolean + lastMessageId: boolean + ownerId: boolean + applicationId: boolean + managed: boolean + parentId: boolean + memberCount: boolean + messageCount: boolean + archiveTimestamp: boolean + defaultAutoArchiveDuration: boolean + autoArchiveDuration: boolean + botIsMember: boolean + archived: boolean + locked: boolean + invitable: boolean + createTimestamp: boolean + newlyCreated: boolean + flags: boolean + recipients: boolean + icon: boolean + member: boolean + totalMessageSent: boolean + availableTags: boolean + appliedTags: boolean + defaultReactionEmoji: boolean + defaultThreadRateLimitPerUser: boolean + defaultSortOrder: boolean + defaultForumLayout: boolean + } + forumTag: { + id: boolean + name: boolean + moderated: boolean + emojiId: boolean + emojiName: boolean + } + emoji: { + id: boolean + name: boolean + roles: boolean + user: boolean + } + defaultReactionEmoji: { + emojiId: boolean + emojiName: boolean + } + guild: { + afkTimeout: boolean + approximateMemberCount: boolean + approximatePresenceCount: boolean + defaultMessageNotifications: boolean + description: boolean + explicitContentFilter: boolean + maxMembers: boolean + maxPresences: boolean + maxVideoChannelUsers: boolean + mfaLevel: boolean + name: boolean + nsfwLevel: boolean + preferredLocale: boolean + premiumSubscriptionCount: boolean + premiumTier: boolean + toggles: boolean + stageInstances: boolean + channels: boolean + members: boolean + roles: boolean + emojis: boolean + stickers: boolean + threads: boolean + voiceStates: boolean + large: boolean + owner: boolean + widgetEnabled: boolean + unavailable: boolean + iconHash: boolean + presences: boolean + systemChannelFlags: boolean + vanityUrlCode: boolean + verificationLevel: boolean + welcomeScreen: boolean + discoverySplash: boolean + joinedAt: boolean + memberCount: boolean + shardId: boolean + icon: boolean + banner: boolean + splash: boolean + id: boolean + ownerId: boolean + permissions: boolean + afkChannelId: boolean + widgetChannelId: boolean + applicationId: boolean + systemChannelId: boolean + rulesChannelId: boolean + publicUpdatesChannelId: boolean + premiumProgressBarEnabled: boolean + safetyAlertsChannelId: boolean + } + interaction: { + id: boolean + applicationId: boolean + type: boolean + guild: boolean + guildId: boolean + channel: boolean + channelId: boolean + member: boolean + user: boolean + token: boolean + version: boolean + message: boolean + data: boolean + locale: boolean + guildLocale: boolean + appPermissions: boolean + authorizingIntegrationOwners: boolean + context: boolean + } + interactionCallback: { + id: boolean + type: boolean + activityInstanceId: boolean + responseMessageId: boolean + responseMessageLoading: boolean + responseMessageEphemeral: boolean + } + interactionCallbackResponse: { + interaction: boolean + resource: boolean + } + interactionResource: { + type: boolean + activityInstance: boolean + message: boolean + } + invite: { + type: boolean + channelId: boolean + code: boolean + createdAt: boolean + guildId: boolean + inviter: boolean + maxAge: boolean + maxUses: boolean + targetType: boolean + targetUser: boolean + targetApplication: boolean + temporary: boolean + uses: boolean + approximateMemberCount: boolean + approximatePresenceCount: boolean + guildScheduledEvent: boolean + stageInstance: boolean + expiresAt: boolean + } + member: { + id: boolean + guildId: boolean + user: boolean + nick: boolean + roles: boolean + joinedAt: boolean + premiumSince: boolean + avatar: boolean + banner: boolean + permissions: boolean + communicationDisabledUntil: boolean + flags: boolean + toggles: boolean + avatarDecorationData: boolean + } + message: { + activity: boolean + application: boolean + applicationId: boolean + attachments: boolean + author: boolean + channelId: boolean + components: boolean + content: boolean + editedTimestamp: boolean + embeds: boolean + guildId: boolean + id: boolean + interactionMetadata: boolean + interaction: boolean + member: boolean + mentionedChannelIds: boolean + mentionedRoleIds: boolean + mentions: boolean + messageReference: boolean + referencedMessage: boolean + messageSnapshots: boolean + nonce: boolean + reactions: boolean + stickerItems: boolean + thread: boolean + type: boolean + webhookId: boolean + poll: boolean + call: boolean + } + messageSnapshot: { + message: boolean + } + messageInteractionMetadata: { + id: boolean + type: boolean + user: boolean + authorizingIntegrationOwners: boolean + originalResponseMessageId: boolean + interactedMessageId: boolean + triggeringInteractionMetadata: boolean + targetUser: boolean + targetMessageId: boolean + } + messageInteraction: { + id: boolean + member: boolean + name: boolean + user: boolean + type: boolean + } + messageReference: { + messageId: boolean + channelId: boolean + guildId: boolean + } + messageCall: { + participants: boolean + endedTimestamp: boolean + } + role: { + name: boolean + guildId: boolean + position: boolean + color: boolean + id: boolean + permissions: boolean + icon: boolean + unicodeEmoji: boolean + flags: boolean + tags: boolean + toggles: boolean + } + scheduledEvent: { + id: boolean + guildId: boolean + channelId: boolean + creatorId: boolean + scheduledStartTime: boolean + scheduledEndTime: boolean + entityId: boolean + creator: boolean + name: boolean + description: boolean + privacyLevel: boolean + status: boolean + entityType: boolean + userCount: boolean + location: boolean + image: boolean + recurrenceRule: boolean + } + scheduledEventRecurrenceRule: { + start: boolean + end: boolean + frequency: boolean + interval: boolean + byWeekday: boolean + byNWeekday: boolean + byMonth: boolean + byMonthDay: boolean + byYearDay: boolean + count: boolean + } + stageInstance: { + id: boolean + guildId: boolean + channelId: boolean + topic: boolean + guildScheduledEventId: boolean + } + inviteStageInstance: { + members: boolean + participantCount: boolean + speakerCount: boolean + topic: boolean + } + sticker: { + id: boolean + packId: boolean + name: boolean + description: boolean + tags: boolean + type: boolean + formatType: boolean + available: boolean + guildId: boolean + user: boolean + sortValue: boolean + } + subscription: { + id: boolean + userId: boolean + skuIds: boolean + entitlementIds: boolean + currentPeriodStart: boolean + currentPeriodEnd: boolean + status: boolean + canceledAt: boolean + country: boolean + } + user: { + username: boolean + globalName: boolean + locale: boolean + flags: boolean + premiumType: boolean + publicFlags: boolean + accentColor: boolean + id: boolean + discriminator: boolean + avatar: boolean + email: boolean + banner: boolean + avatarDecorationData: boolean + toggles: boolean + } + avatarDecorationData: { + asset: boolean + skuId: boolean + } + webhook: { + id: boolean + type: boolean + guildId: boolean + channelId: boolean + user: boolean + name: boolean + avatar: boolean + token: boolean + applicationId: boolean + sourceGuild: boolean + sourceChannel: boolean + url: boolean + } + guildOnboarding: { + guildId: boolean + prompts: boolean + defaultChannelIds: boolean + enabled: boolean + mode: boolean + } + guildOnboardingPrompt: { + id: boolean + type: boolean + options: boolean + title: boolean + singleSelect: boolean + required: boolean + inOnboarding: boolean + } + guildOnboardingPromptOption: { + id: boolean + channelIds: boolean + roleIds: boolean + emoji: boolean + title: boolean + description: boolean + } + entitlement: { + id: boolean + skuId: boolean + userId: boolean + guildId: boolean + applicationId: boolean + type: boolean + deleted: boolean + startsAt: boolean + endsAt: boolean + consumed: boolean + } + sku: { + id: boolean + type: boolean + applicationId: boolean + name: boolean + slug: boolean + flags: boolean + } + voiceState: { + requestToSpeakTimestamp: boolean + channelId: boolean + guildId: boolean + toggles: boolean + sessionId: boolean + userId: boolean + } + poll: { + question: boolean + answers: boolean + expiry: boolean + allowMultiselect: boolean + layoutType: boolean + results: boolean + } + pollAnswer: { + answerId: boolean + pollMedia: boolean + } + pollResult: { + isFinalized: boolean + answerCounts: boolean + } + pollAnswerCount: { + id: boolean + count: boolean + meVoted: boolean + } + pollMedia: { + text: boolean + emoji: boolean + } + soundboardSound: { + name: boolean + soundId: boolean + volume: boolean + emojiId: boolean + emojiName: boolean + guildId: boolean + available: boolean + user: boolean + } +} + +export function createDesiredPropertiesObject( + desiredProperties: RecursivePartial, + defaultValue = false, +): TransformersDesiredProperties { + return { + activityInstance: { + applicationId: defaultValue, + instanceId: defaultValue, + launchId: defaultValue, + location: defaultValue, + users: defaultValue, + ...desiredProperties.activityInstance, + }, + activityLocation: { + channelId: defaultValue, + guildId: defaultValue, + id: defaultValue, + kind: defaultValue, + ...desiredProperties.activityLocation, + }, + attachment: { + id: defaultValue, + filename: defaultValue, + title: defaultValue, + contentType: defaultValue, + size: defaultValue, + url: defaultValue, + proxyUrl: defaultValue, + height: defaultValue, + width: defaultValue, + ephemeral: defaultValue, + description: defaultValue, + duration_secs: defaultValue, + waveform: defaultValue, + flags: defaultValue, + ...desiredProperties.attachment, + }, + channel: { + type: defaultValue, + position: defaultValue, + name: defaultValue, + topic: defaultValue, + nsfw: defaultValue, + bitrate: defaultValue, + userLimit: defaultValue, + rateLimitPerUser: defaultValue, + rtcRegion: defaultValue, + videoQualityMode: defaultValue, + guildId: defaultValue, + lastPinTimestamp: defaultValue, + permissionOverwrites: defaultValue, + id: defaultValue, + permissions: defaultValue, + lastMessageId: defaultValue, + ownerId: defaultValue, + applicationId: defaultValue, + managed: defaultValue, + parentId: defaultValue, + memberCount: defaultValue, + messageCount: defaultValue, + archiveTimestamp: defaultValue, + defaultAutoArchiveDuration: defaultValue, + autoArchiveDuration: defaultValue, + botIsMember: defaultValue, + archived: defaultValue, + locked: defaultValue, + invitable: defaultValue, + createTimestamp: defaultValue, + newlyCreated: defaultValue, + flags: defaultValue, + appliedTags: defaultValue, + availableTags: defaultValue, + defaultForumLayout: defaultValue, + defaultReactionEmoji: defaultValue, + defaultSortOrder: defaultValue, + defaultThreadRateLimitPerUser: defaultValue, + icon: defaultValue, + member: defaultValue, + recipients: defaultValue, + totalMessageSent: defaultValue, + ...desiredProperties.channel, + }, + forumTag: { + emojiId: defaultValue, + emojiName: defaultValue, + id: defaultValue, + moderated: defaultValue, + name: defaultValue, + ...desiredProperties.forumTag, + }, + emoji: { + id: defaultValue, + name: defaultValue, + roles: defaultValue, + user: defaultValue, + ...desiredProperties.emoji, + }, + defaultReactionEmoji: { + emojiId: defaultValue, + emojiName: defaultValue, + ...desiredProperties.defaultReactionEmoji, + }, + guild: { + afkTimeout: defaultValue, + approximateMemberCount: defaultValue, + approximatePresenceCount: defaultValue, + defaultMessageNotifications: defaultValue, + description: defaultValue, + explicitContentFilter: defaultValue, + maxMembers: defaultValue, + maxPresences: defaultValue, + maxVideoChannelUsers: defaultValue, + mfaLevel: defaultValue, + name: defaultValue, + channels: defaultValue, + emojis: defaultValue, + iconHash: defaultValue, + large: defaultValue, + members: defaultValue, + owner: defaultValue, + presences: defaultValue, + roles: defaultValue, + stickers: defaultValue, + threads: defaultValue, + toggles: defaultValue, + unavailable: defaultValue, + voiceStates: defaultValue, + widgetEnabled: defaultValue, + nsfwLevel: defaultValue, + preferredLocale: defaultValue, + premiumSubscriptionCount: defaultValue, + premiumTier: defaultValue, + stageInstances: defaultValue, + systemChannelFlags: defaultValue, + vanityUrlCode: defaultValue, + verificationLevel: defaultValue, + welcomeScreen: defaultValue, + discoverySplash: defaultValue, + joinedAt: defaultValue, + memberCount: defaultValue, + shardId: defaultValue, + icon: defaultValue, + banner: defaultValue, + splash: defaultValue, + id: defaultValue, + ownerId: defaultValue, + permissions: defaultValue, + afkChannelId: defaultValue, + widgetChannelId: defaultValue, + applicationId: defaultValue, + systemChannelId: defaultValue, + rulesChannelId: defaultValue, + publicUpdatesChannelId: defaultValue, + premiumProgressBarEnabled: defaultValue, + safetyAlertsChannelId: defaultValue, + ...desiredProperties.guild, + }, + interaction: { + id: defaultValue, + applicationId: defaultValue, + type: defaultValue, + guild: defaultValue, + guildId: defaultValue, + channel: defaultValue, + channelId: defaultValue, + member: defaultValue, + user: defaultValue, + token: defaultValue, + version: defaultValue, + message: defaultValue, + data: defaultValue, + locale: defaultValue, + guildLocale: defaultValue, + appPermissions: defaultValue, + authorizingIntegrationOwners: defaultValue, + context: defaultValue, + ...desiredProperties.interaction, + }, + interactionCallback: { + type: defaultValue, + id: defaultValue, + activityInstanceId: defaultValue, + responseMessageEphemeral: defaultValue, + responseMessageId: defaultValue, + responseMessageLoading: defaultValue, + ...desiredProperties.interactionCallback, + }, + interactionCallbackResponse: { + interaction: defaultValue, + resource: defaultValue, + ...desiredProperties.interactionCallbackResponse, + }, + interactionResource: { + type: defaultValue, + activityInstance: defaultValue, + message: defaultValue, + ...desiredProperties.interactionResource, + }, + invite: { + type: defaultValue, + channelId: defaultValue, + code: defaultValue, + createdAt: defaultValue, + guildId: defaultValue, + inviter: defaultValue, + maxAge: defaultValue, + maxUses: defaultValue, + targetType: defaultValue, + targetUser: defaultValue, + targetApplication: defaultValue, + temporary: defaultValue, + uses: defaultValue, + approximateMemberCount: defaultValue, + approximatePresenceCount: defaultValue, + guildScheduledEvent: defaultValue, + stageInstance: defaultValue, + expiresAt: defaultValue, + ...desiredProperties.invite, + }, + member: { + id: defaultValue, + guildId: defaultValue, + user: defaultValue, + nick: defaultValue, + roles: defaultValue, + joinedAt: defaultValue, + premiumSince: defaultValue, + avatar: defaultValue, + banner: defaultValue, + permissions: defaultValue, + communicationDisabledUntil: defaultValue, + flags: defaultValue, + toggles: defaultValue, + avatarDecorationData: defaultValue, + ...desiredProperties.member, + }, + message: { + activity: defaultValue, + application: defaultValue, + applicationId: defaultValue, + attachments: defaultValue, + author: defaultValue, + channelId: defaultValue, + components: defaultValue, + content: defaultValue, + editedTimestamp: defaultValue, + embeds: defaultValue, + guildId: defaultValue, + id: defaultValue, + interactionMetadata: defaultValue, + interaction: defaultValue, + member: defaultValue, + mentionedChannelIds: defaultValue, + mentionedRoleIds: defaultValue, + mentions: defaultValue, + messageReference: defaultValue, + messageSnapshots: defaultValue, + referencedMessage: defaultValue, + nonce: defaultValue, + reactions: defaultValue, + stickerItems: defaultValue, + thread: defaultValue, + type: defaultValue, + webhookId: defaultValue, + poll: defaultValue, + call: defaultValue, + ...desiredProperties.message, + }, + messageSnapshot: { + message: defaultValue, + ...desiredProperties.messageSnapshot, + }, + messageInteractionMetadata: { + id: defaultValue, + type: defaultValue, + user: defaultValue, + authorizingIntegrationOwners: defaultValue, + originalResponseMessageId: defaultValue, + interactedMessageId: defaultValue, + triggeringInteractionMetadata: defaultValue, + targetUser: defaultValue, + targetMessageId: defaultValue, + ...desiredProperties.messageInteractionMetadata, + }, + messageInteraction: { + id: defaultValue, + member: defaultValue, + name: defaultValue, + type: defaultValue, + user: defaultValue, + ...desiredProperties.messageInteraction, + }, + messageReference: { + messageId: defaultValue, + channelId: defaultValue, + guildId: defaultValue, + ...desiredProperties.messageReference, + }, + messageCall: { + participants: defaultValue, + endedTimestamp: defaultValue, + ...desiredProperties.messageCall, + }, + role: { + name: defaultValue, + guildId: defaultValue, + position: defaultValue, + color: defaultValue, + id: defaultValue, + permissions: defaultValue, + icon: defaultValue, + unicodeEmoji: defaultValue, + flags: defaultValue, + tags: defaultValue, + toggles: defaultValue, + ...desiredProperties.role, + }, + scheduledEvent: { + id: defaultValue, + guildId: defaultValue, + channelId: defaultValue, + creatorId: defaultValue, + scheduledStartTime: defaultValue, + scheduledEndTime: defaultValue, + entityId: defaultValue, + creator: defaultValue, + name: defaultValue, + description: defaultValue, + privacyLevel: defaultValue, + status: defaultValue, + entityType: defaultValue, + userCount: defaultValue, + location: defaultValue, + image: defaultValue, + recurrenceRule: defaultValue, + ...desiredProperties.scheduledEvent, + }, + scheduledEventRecurrenceRule: { + start: defaultValue, + end: defaultValue, + frequency: defaultValue, + interval: defaultValue, + byWeekday: defaultValue, + byNWeekday: defaultValue, + byMonth: defaultValue, + byMonthDay: defaultValue, + byYearDay: defaultValue, + count: defaultValue, + ...desiredProperties.scheduledEventRecurrenceRule, + }, + stageInstance: { + id: defaultValue, + guildId: defaultValue, + channelId: defaultValue, + topic: defaultValue, + guildScheduledEventId: defaultValue, + ...desiredProperties.stageInstance, + }, + inviteStageInstance: { + members: defaultValue, + participantCount: defaultValue, + speakerCount: defaultValue, + topic: defaultValue, + ...desiredProperties.inviteStageInstance, + }, + sticker: { + id: defaultValue, + packId: defaultValue, + name: defaultValue, + description: defaultValue, + tags: defaultValue, + type: defaultValue, + formatType: defaultValue, + available: defaultValue, + guildId: defaultValue, + user: defaultValue, + sortValue: defaultValue, + ...desiredProperties.sticker, + }, + subscription: { + id: defaultValue, + userId: defaultValue, + skuIds: defaultValue, + entitlementIds: defaultValue, + currentPeriodStart: defaultValue, + currentPeriodEnd: defaultValue, + status: defaultValue, + canceledAt: defaultValue, + country: defaultValue, + ...desiredProperties.subscription, + }, + user: { + username: defaultValue, + globalName: defaultValue, + locale: defaultValue, + flags: defaultValue, + premiumType: defaultValue, + publicFlags: defaultValue, + accentColor: defaultValue, + id: defaultValue, + discriminator: defaultValue, + avatar: defaultValue, + email: defaultValue, + banner: defaultValue, + avatarDecorationData: defaultValue, + toggles: defaultValue, + ...desiredProperties.user, + }, + avatarDecorationData: { + asset: defaultValue, + skuId: defaultValue, + ...desiredProperties.avatarDecorationData, + }, + webhook: { + id: defaultValue, + type: defaultValue, + guildId: defaultValue, + channelId: defaultValue, + user: defaultValue, + name: defaultValue, + avatar: defaultValue, + token: defaultValue, + applicationId: defaultValue, + sourceGuild: defaultValue, + sourceChannel: defaultValue, + url: defaultValue, + ...desiredProperties.webhook, + }, + guildOnboarding: { + defaultChannelIds: defaultValue, + enabled: defaultValue, + guildId: defaultValue, + mode: defaultValue, + prompts: defaultValue, + ...desiredProperties.guildOnboarding, + }, + guildOnboardingPrompt: { + id: defaultValue, + inOnboarding: defaultValue, + options: defaultValue, + required: defaultValue, + singleSelect: defaultValue, + title: defaultValue, + type: defaultValue, + ...desiredProperties.guildOnboardingPrompt, + }, + guildOnboardingPromptOption: { + channelIds: defaultValue, + description: defaultValue, + emoji: defaultValue, + id: defaultValue, + roleIds: defaultValue, + title: defaultValue, + ...desiredProperties.guildOnboardingPromptOption, + }, + entitlement: { + id: defaultValue, + skuId: defaultValue, + userId: defaultValue, + guildId: defaultValue, + applicationId: defaultValue, + type: defaultValue, + deleted: defaultValue, + startsAt: defaultValue, + endsAt: defaultValue, + consumed: defaultValue, + ...desiredProperties.entitlement, + }, + sku: { + id: defaultValue, + type: defaultValue, + applicationId: defaultValue, + name: defaultValue, + slug: defaultValue, + flags: defaultValue, + ...desiredProperties.sku, + }, + voiceState: { + requestToSpeakTimestamp: defaultValue, + channelId: defaultValue, + guildId: defaultValue, + toggles: defaultValue, + sessionId: defaultValue, + userId: defaultValue, + ...desiredProperties.voiceState, + }, + poll: { + question: defaultValue, + answers: defaultValue, + expiry: defaultValue, + layoutType: defaultValue, + allowMultiselect: defaultValue, + results: defaultValue, + ...desiredProperties.poll, + }, + pollAnswer: { + answerId: defaultValue, + pollMedia: defaultValue, + ...desiredProperties.pollAnswer, + }, + pollResult: { + isFinalized: defaultValue, + answerCounts: defaultValue, + ...desiredProperties.pollResult, + }, + pollAnswerCount: { + id: defaultValue, + count: defaultValue, + meVoted: defaultValue, + ...desiredProperties.pollAnswerCount, + }, + pollMedia: { + text: defaultValue, + emoji: defaultValue, + ...desiredProperties.pollMedia, + }, + soundboardSound: { + name: defaultValue, + soundId: defaultValue, + volume: defaultValue, + emojiId: defaultValue, + emojiName: defaultValue, + guildId: defaultValue, + available: defaultValue, + user: defaultValue, + ...desiredProperties.soundboardSound, + }, + } +} diff --git a/packages/bot/src/events.ts b/packages/bot/src/events.ts new file mode 100644 index 000000000..513153191 --- /dev/null +++ b/packages/bot/src/events.ts @@ -0,0 +1,138 @@ +import type { DiscordGatewayPayload, DiscordReady, DiscordVoiceChannelEffectAnimationType } from '@discordeno/types' +import type { Collection } from '@discordeno/utils' +import type { + AuditLogEntry, + AutoModerationActionExecution, + AutoModerationRule, + Channel, + Emoji, + Entitlement, + Guild, + GuildApplicationCommandPermissions, + Integration, + Interaction, + Invite, + Member, + Message, + PresenceUpdate, + Role, + ScheduledEvent, + SoundboardSound, + Sticker, + Subscription, + ThreadMember, + User, + VoiceState, +} from './transformers/types.js' + +export interface EventHandlers { + debug: (text: string, ...args: any[]) => unknown + applicationCommandPermissionsUpdate: (command: GuildApplicationCommandPermissions) => unknown + guildAuditLogEntryCreate: (log: AuditLogEntry, guildId: bigint) => unknown + automodRuleCreate: (rule: AutoModerationRule) => unknown + automodRuleUpdate: (rule: AutoModerationRule) => unknown + automodRuleDelete: (rule: AutoModerationRule) => unknown + automodActionExecution: (payload: AutoModerationActionExecution) => unknown + threadCreate: (thread: Channel) => unknown + threadDelete: (thread: Channel) => unknown + threadListSync: (payload: { guildId: bigint; channelIds?: bigint[]; threads: Channel[]; members: ThreadMember[] }) => unknown + threadMemberUpdate: (payload: { id: bigint; guildId: bigint; joinedAt: number; flags: number }) => unknown + threadMembersUpdate: (payload: { id: bigint; guildId: bigint; addedMembers?: ThreadMember[]; removedMemberIds?: bigint[] }) => unknown + threadUpdate: (thread: Channel) => unknown + scheduledEventCreate: (event: ScheduledEvent) => unknown + scheduledEventUpdate: (event: ScheduledEvent) => unknown + scheduledEventDelete: (event: ScheduledEvent) => unknown + /** Sent when a user has subscribed to a guild scheduled event. EXPERIMENTAL! */ + scheduledEventUserAdd: (payload: { guildScheduledEventId: bigint; guildId: bigint; userId: bigint }) => unknown + /** Sent when a user has unsubscribed to a guild scheduled event. EXPERIMENTAL! */ + scheduledEventUserRemove: (payload: { guildScheduledEventId: bigint; guildId: bigint; userId: bigint }) => unknown + ready: ( + payload: { + shardId: number + v: number + user: User + guilds: bigint[] + sessionId: string + shard?: number[] + applicationId: bigint + }, + rawPayload: DiscordReady, + ) => unknown + interactionCreate: (interaction: Interaction) => unknown + integrationCreate: (integration: Integration) => unknown + integrationDelete: (payload: { id: bigint; guildId: bigint; applicationId?: bigint }) => unknown + integrationUpdate: (payload: { guildId: bigint }) => unknown + inviteCreate: (invite: Invite) => unknown + inviteDelete: (payload: { channelId: bigint; guildId?: bigint; code: string }) => unknown + guildMemberAdd: (member: Member, user: User) => unknown + guildMemberRemove: (user: User, guildId: bigint) => unknown + guildMemberUpdate: (member: Member, user: User) => unknown + guildStickersUpdate: (payload: { guildId: bigint; stickers: Sticker[] }) => unknown + messageCreate: (message: Message) => unknown + messageDelete: (payload: { id: bigint; channelId: bigint; guildId?: bigint }, message?: Message) => unknown + messageDeleteBulk: (payload: { ids: bigint[]; channelId: bigint; guildId?: bigint }) => unknown + messageUpdate: (message: Message) => unknown + reactionAdd: (payload: { + userId: bigint + channelId: bigint + messageId: bigint + guildId?: bigint + member?: Member + user?: User + emoji: Emoji + messageAuthorId?: bigint + burst: boolean + burstColors?: string[] + }) => unknown + reactionRemove: (payload: { userId: bigint; channelId: bigint; messageId: bigint; guildId?: bigint; emoji: Emoji; burst: boolean }) => unknown + reactionRemoveEmoji: (payload: { channelId: bigint; messageId: bigint; guildId?: bigint; emoji: Emoji }) => unknown + reactionRemoveAll: (payload: { channelId: bigint; messageId: bigint; guildId?: bigint }) => unknown + presenceUpdate: (presence: PresenceUpdate) => unknown + voiceChannelEffectSend: (payload: { + channelId: bigint + guildId: bigint + userId: bigint + emoji?: Emoji + animationType?: DiscordVoiceChannelEffectAnimationType + animationId?: number + soundId?: bigint | number + soundVolume?: number + }) => unknown + voiceServerUpdate: (payload: { token: string; endpoint?: string; guildId: bigint }) => unknown + voiceStateUpdate: (voiceState: VoiceState) => unknown + channelCreate: (channel: Channel) => unknown + dispatchRequirements: (data: DiscordGatewayPayload, shardId: number) => unknown + channelDelete: (channel: Channel) => unknown + channelPinsUpdate: (data: { guildId?: bigint; channelId: bigint; lastPinTimestamp?: number }) => unknown + channelUpdate: (channel: Channel) => unknown + stageInstanceCreate: (data: { id: bigint; guildId: bigint; channelId: bigint; topic: string }) => unknown + stageInstanceDelete: (data: { id: bigint; guildId: bigint; channelId: bigint; topic: string }) => unknown + stageInstanceUpdate: (data: { id: bigint; guildId: bigint; channelId: bigint; topic: string }) => unknown + guildEmojisUpdate: (payload: { guildId: bigint; emojis: Collection }) => unknown + guildBanAdd: (user: User, guildId: bigint) => unknown + guildBanRemove: (user: User, guildId: bigint) => unknown + guildCreate: (guild: Guild) => unknown + guildDelete: (id: bigint, shardId: number) => unknown + guildUnavailable: (id: bigint, shardId: number) => unknown + guildUpdate: (guild: Guild) => unknown + raw: (data: DiscordGatewayPayload, shardId: number) => unknown + roleCreate: (role: Role) => unknown + roleDelete: (payload: { guildId: bigint; roleId: bigint }) => unknown + roleUpdate: (role: Role) => unknown + webhooksUpdate: (payload: { channelId: bigint; guildId: bigint }) => unknown + botUpdate: (user: User) => unknown + typingStart: (payload: { guildId: bigint | undefined; channelId: bigint; userId: bigint; timestamp: number; member: Member | undefined }) => unknown + entitlementCreate: (entitlement: Entitlement) => unknown + entitlementUpdate: (entitlement: Entitlement) => unknown + entitlementDelete: (entitlement: Entitlement) => unknown + subscriptionCreate: (subscription: Subscription) => unknown + subscriptionUpdate: (subscription: Subscription) => unknown + subscriptionDelete: (subscription: Subscription) => unknown + messagePollVoteAdd: (payload: { userId: bigint; channelId: bigint; messageId: bigint; guildId?: bigint; answerId: number }) => unknown + messagePollVoteRemove: (payload: { userId: bigint; channelId: bigint; messageId: bigint; guildId?: bigint; answerId: number }) => unknown + soundboardSoundCreate: (payload: SoundboardSound) => unknown + soundboardSoundUpdate: (payload: SoundboardSound) => unknown + soundboardSoundDelete: (payload: { soundId: bigint; guildId: bigint }) => unknown + soundboardSoundsUpdate: (payload: { soundboardSounds: SoundboardSound[]; guildId: bigint }) => unknown + soundboardSounds: (payload: { soundboardSounds: SoundboardSound[]; guildId: bigint }) => unknown +} diff --git a/packages/bot/src/handlers.ts b/packages/bot/src/handlers.ts index 27b980861..6713c784b 100644 --- a/packages/bot/src/handlers.ts +++ b/packages/bot/src/handlers.ts @@ -1,10 +1,7 @@ import * as handlers from './handlers/index.js' import type { Bot, DiscordGatewayPayload, GatewayDispatchEventNames } from './index.js' -import type { BotGatewayHandlerOptions } from './typings.js' -export function createBotGatewayHandlers( - options: Partial, -): Record any> { +export function createBotGatewayHandlers(options: Partial): GatewayHandlers { return { APPLICATION_COMMAND_PERMISSIONS_UPDATE: options.APPLICATION_COMMAND_PERMISSIONS_UPDATE ?? handlers.handleApplicationCommandPermissionsUpdate, AUTO_MODERATION_ACTION_EXECUTION: options.AUTO_MODERATION_ACTION_EXECUTION ?? handlers.handleAutoModerationActionExecution, @@ -83,4 +80,5 @@ export function createBotGatewayHandlers( } } -export interface GatewayHandlers extends ReturnType {} +export type GatewayHandlers = Record +export type BotGatewayHandler = (bot: Bot, data: DiscordGatewayPayload, shardId: number) => unknown diff --git a/packages/bot/src/helpers.ts b/packages/bot/src/helpers.ts index 6cd496649..5f4bb5f6a 100644 --- a/packages/bot/src/helpers.ts +++ b/packages/bot/src/helpers.ts @@ -1,4 +1,3 @@ -import type { CreateWebhook } from '@discordeno/rest' import type { AddDmRecipientOptions, AddGuildMemberOptions, @@ -6,26 +5,6 @@ import type { BeginGuildPrune, BigString, Camelize, - CamelizedDiscordAccessTokenResponse, - CamelizedDiscordApplicationCommandPermissions, - CamelizedDiscordApplicationRoleConnection, - CamelizedDiscordArchivedThreads, - CamelizedDiscordAuditLog, - CamelizedDiscordBan, - CamelizedDiscordConnection, - CamelizedDiscordCurrentAuthorization, - CamelizedDiscordFollowedChannel, - CamelizedDiscordGetGatewayBot, - CamelizedDiscordGuildPreview, - CamelizedDiscordGuildWidgetSettings, - CamelizedDiscordInvite, - CamelizedDiscordInviteMetadata, - CamelizedDiscordModifyGuildWelcomeScreen, - CamelizedDiscordPrunedCount, - CamelizedDiscordTokenExchange, - CamelizedDiscordTokenRevocation, - CamelizedDiscordVanityUrl, - CamelizedDiscordVoiceRegion, CreateApplicationCommand, CreateApplicationEmoji, CreateAutoModerationRuleOptions, @@ -47,11 +26,32 @@ import type { CreateScheduledEvent, CreateStageInstance, CreateTemplate, + CreateWebhook, DeleteWebhookMessageOptions, + DiscordAccessTokenResponse, DiscordActivityInstance, + DiscordApplicationCommandPermissions, + DiscordApplicationRoleConnection, + DiscordArchivedThreads, + DiscordAuditLog, + DiscordBan, + DiscordConnection, + DiscordCurrentAuthorization, DiscordEntitlement, + DiscordFollowedChannel, + DiscordGetGatewayBot, + DiscordGuildPreview, + DiscordGuildWidgetSettings, + DiscordInvite, + DiscordInviteMetadata, DiscordMessage, + DiscordModifyGuildWelcomeScreen, + DiscordPrunedCount, DiscordSubscription, + DiscordTokenExchange, + DiscordTokenRevocation, + DiscordVanityUrl, + DiscordVoiceRegion, EditApplication, EditAutoModerationRuleOptions, EditBotMemberOptions, @@ -818,7 +818,7 @@ export interface BotHelpers { createGuildFromTemplate: (templateCode: string, options: CreateGuildFromTemplate) => Promise createGuildSticker: (guildId: BigString, options: CreateGuildStickerOptions, reason?: string) => Promise createGuildTemplate: (guildId: BigString, options: CreateTemplate) => Promise