@ovencord/discord.js 14.16.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +191 -0
- package/README.md +148 -0
- package/package.json +73 -0
- package/src/client/Client.ts +967 -0
- package/src/client/actions/Action.ts +141 -0
- package/src/client/actions/ActionsManager.ts +138 -0
- package/src/client/actions/ChannelCreate.ts +21 -0
- package/src/client/actions/ChannelDelete.ts +20 -0
- package/src/client/actions/ChannelUpdate.ts +38 -0
- package/src/client/actions/GuildChannelsPositionUpdate.ts +17 -0
- package/src/client/actions/GuildEmojiCreate.ts +17 -0
- package/src/client/actions/GuildEmojiDelete.ts +16 -0
- package/src/client/actions/GuildEmojiUpdate.ts +17 -0
- package/src/client/actions/GuildEmojisUpdate.ts +30 -0
- package/src/client/actions/GuildMemberRemove.ts +29 -0
- package/src/client/actions/GuildMemberUpdate.ts +41 -0
- package/src/client/actions/GuildRoleCreate.ts +23 -0
- package/src/client/actions/GuildRoleDelete.ts +26 -0
- package/src/client/actions/GuildRolesPositionUpdate.ts +17 -0
- package/src/client/actions/GuildScheduledEventDelete.ts +28 -0
- package/src/client/actions/GuildScheduledEventUserAdd.ts +29 -0
- package/src/client/actions/GuildScheduledEventUserRemove.ts +29 -0
- package/src/client/actions/GuildSoundboardSoundDelete.ts +26 -0
- package/src/client/actions/GuildStickerCreate.ts +17 -0
- package/src/client/actions/GuildStickerDelete.ts +16 -0
- package/src/client/actions/GuildStickerUpdate.ts +17 -0
- package/src/client/actions/GuildStickersUpdate.ts +30 -0
- package/src/client/actions/GuildUpdate.ts +30 -0
- package/src/client/actions/InteractionCreate.ts +104 -0
- package/src/client/actions/MessageCreate.ts +38 -0
- package/src/client/actions/MessageDelete.ts +29 -0
- package/src/client/actions/MessageDeleteBulk.ts +45 -0
- package/src/client/actions/MessagePollVoteAdd.ts +37 -0
- package/src/client/actions/MessagePollVoteRemove.ts +35 -0
- package/src/client/actions/MessageReactionAdd.ts +68 -0
- package/src/client/actions/MessageReactionRemove.ts +47 -0
- package/src/client/actions/MessageReactionRemoveAll.ts +30 -0
- package/src/client/actions/MessageReactionRemoveEmoji.ts +25 -0
- package/src/client/actions/MessageUpdate.ts +22 -0
- package/src/client/actions/StageInstanceCreate.ts +25 -0
- package/src/client/actions/StageInstanceDelete.ts +28 -0
- package/src/client/actions/StageInstanceUpdate.ts +27 -0
- package/src/client/actions/ThreadCreate.ts +22 -0
- package/src/client/actions/ThreadMembersUpdate.ts +45 -0
- package/src/client/actions/TypingStart.ts +26 -0
- package/src/client/actions/UserUpdate.ts +33 -0
- package/src/client/voice/ClientVoiceManager.ts +46 -0
- package/src/client/websocket/handlers/APPLICATION_COMMAND_PERMISSIONS_UPDATE.ts +19 -0
- package/src/client/websocket/handlers/AUTO_MODERATION_ACTION_EXECUTION.ts +17 -0
- package/src/client/websocket/handlers/AUTO_MODERATION_RULE_CREATE.ts +18 -0
- package/src/client/websocket/handlers/AUTO_MODERATION_RULE_DELETE.ts +21 -0
- package/src/client/websocket/handlers/AUTO_MODERATION_RULE_UPDATE.ts +20 -0
- package/src/client/websocket/handlers/CHANNEL_CREATE.ts +4 -0
- package/src/client/websocket/handlers/CHANNEL_DELETE.ts +4 -0
- package/src/client/websocket/handlers/CHANNEL_PINS_UPDATE.ts +22 -0
- package/src/client/websocket/handlers/CHANNEL_UPDATE.ts +16 -0
- package/src/client/websocket/handlers/ENTITLEMENT_CREATE.ts +14 -0
- package/src/client/websocket/handlers/ENTITLEMENT_DELETE.ts +18 -0
- package/src/client/websocket/handlers/ENTITLEMENT_UPDATE.ts +16 -0
- package/src/client/websocket/handlers/GUILD_AUDIT_LOG_ENTRY_CREATE.ts +19 -0
- package/src/client/websocket/handlers/GUILD_BAN_ADD.ts +15 -0
- package/src/client/websocket/handlers/GUILD_BAN_REMOVE.ts +20 -0
- package/src/client/websocket/handlers/GUILD_CREATE.ts +34 -0
- package/src/client/websocket/handlers/GUILD_DELETE.ts +36 -0
- package/src/client/websocket/handlers/GUILD_EMOJIS_UPDATE.ts +4 -0
- package/src/client/websocket/handlers/GUILD_INTEGRATIONS_UPDATE.ts +15 -0
- package/src/client/websocket/handlers/GUILD_MEMBERS_CHUNK.ts +40 -0
- package/src/client/websocket/handlers/GUILD_MEMBER_ADD.ts +17 -0
- package/src/client/websocket/handlers/GUILD_MEMBER_REMOVE.ts +4 -0
- package/src/client/websocket/handlers/GUILD_MEMBER_UPDATE.ts +4 -0
- package/src/client/websocket/handlers/GUILD_ROLE_CREATE.ts +4 -0
- package/src/client/websocket/handlers/GUILD_ROLE_DELETE.ts +4 -0
- package/src/client/websocket/handlers/GUILD_ROLE_UPDATE.ts +21 -0
- package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_CREATE.ts +17 -0
- package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_DELETE.ts +4 -0
- package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_UPDATE.ts +19 -0
- package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_ADD.ts +4 -0
- package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_REMOVE.ts +4 -0
- package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUNDS_UPDATE.ts +24 -0
- package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_CREATE.ts +18 -0
- package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_DELETE.ts +4 -0
- package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_UPDATE.ts +20 -0
- package/src/client/websocket/handlers/GUILD_STICKERS_UPDATE.ts +4 -0
- package/src/client/websocket/handlers/GUILD_UPDATE.ts +4 -0
- package/src/client/websocket/handlers/INTERACTION_CREATE.ts +4 -0
- package/src/client/websocket/handlers/INVITE_CREATE.ts +20 -0
- package/src/client/websocket/handlers/INVITE_DELETE.ts +23 -0
- package/src/client/websocket/handlers/MESSAGE_CREATE.ts +4 -0
- package/src/client/websocket/handlers/MESSAGE_DELETE.ts +4 -0
- package/src/client/websocket/handlers/MESSAGE_DELETE_BULK.ts +4 -0
- package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_ADD.ts +4 -0
- package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_REMOVE.ts +4 -0
- package/src/client/websocket/handlers/MESSAGE_REACTION_ADD.ts +4 -0
- package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE.ts +4 -0
- package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_ALL.ts +4 -0
- package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_EMOJI.ts +4 -0
- package/src/client/websocket/handlers/MESSAGE_UPDATE.ts +16 -0
- package/src/client/websocket/handlers/PRESENCE_UPDATE.ts +42 -0
- package/src/client/websocket/handlers/RATE_LIMITED.ts +23 -0
- package/src/client/websocket/handlers/READY.ts +29 -0
- package/src/client/websocket/handlers/SOUNDBOARD_SOUNDS.ts +24 -0
- package/src/client/websocket/handlers/STAGE_INSTANCE_CREATE.ts +4 -0
- package/src/client/websocket/handlers/STAGE_INSTANCE_DELETE.ts +4 -0
- package/src/client/websocket/handlers/STAGE_INSTANCE_UPDATE.ts +4 -0
- package/src/client/websocket/handlers/SUBSCRIPTION_CREATE.ts +14 -0
- package/src/client/websocket/handlers/SUBSCRIPTION_DELETE.ts +16 -0
- package/src/client/websocket/handlers/SUBSCRIPTION_UPDATE.ts +16 -0
- package/src/client/websocket/handlers/THREAD_CREATE.ts +4 -0
- package/src/client/websocket/handlers/THREAD_DELETE.ts +17 -0
- package/src/client/websocket/handlers/THREAD_LIST_SYNC.ts +50 -0
- package/src/client/websocket/handlers/THREAD_MEMBERS_UPDATE.ts +4 -0
- package/src/client/websocket/handlers/THREAD_MEMBER_UPDATE.ts +25 -0
- package/src/client/websocket/handlers/THREAD_UPDATE.ts +16 -0
- package/src/client/websocket/handlers/TYPING_START.ts +4 -0
- package/src/client/websocket/handlers/USER_UPDATE.ts +4 -0
- package/src/client/websocket/handlers/VOICE_CHANNEL_EFFECT_SEND.ts +16 -0
- package/src/client/websocket/handlers/VOICE_SERVER_UPDATE.ts +5 -0
- package/src/client/websocket/handlers/VOICE_STATE_UPDATE.ts +37 -0
- package/src/client/websocket/handlers/WEBHOOKS_UPDATE.ts +16 -0
- package/src/client/websocket/handlers/index.ts +74 -0
- package/src/errors/DJSError.ts +50 -0
- package/src/errors/ErrorCodes.ts +277 -0
- package/src/errors/Messages.ts +155 -0
- package/src/errors/index.ts +6 -0
- package/src/index.ts +241 -0
- package/src/managers/ApplicationCommandManager.ts +303 -0
- package/src/managers/ApplicationCommandPermissionsManager.ts +453 -0
- package/src/managers/ApplicationEmojiManager.ts +149 -0
- package/src/managers/AutoModerationRuleManager.ts +307 -0
- package/src/managers/BaseManager.ts +13 -0
- package/src/managers/CachedManager.ts +56 -0
- package/src/managers/CategoryChannelChildManager.ts +81 -0
- package/src/managers/ChannelManager.ts +194 -0
- package/src/managers/DMMessageManager.ts +15 -0
- package/src/managers/DataManager.ts +38 -0
- package/src/managers/EntitlementManager.ts +182 -0
- package/src/managers/GuildApplicationCommandManager.ts +29 -0
- package/src/managers/GuildBanManager.ts +221 -0
- package/src/managers/GuildChannelManager.ts +552 -0
- package/src/managers/GuildEmojiManager.ts +262 -0
- package/src/managers/GuildEmojiRoleManager.ts +134 -0
- package/src/managers/GuildForumThreadManager.ts +84 -0
- package/src/managers/GuildInviteManager.ts +236 -0
- package/src/managers/GuildManager.ts +265 -0
- package/src/managers/GuildMemberManager.ts +619 -0
- package/src/managers/GuildMemberRoleManager.ts +230 -0
- package/src/managers/GuildMessageManager.ts +31 -0
- package/src/managers/GuildScheduledEventManager.ts +330 -0
- package/src/managers/GuildSoundboardSoundManager.ts +157 -0
- package/src/managers/GuildStickerManager.ts +192 -0
- package/src/managers/GuildTextThreadManager.ts +91 -0
- package/src/managers/MessageManager.ts +352 -0
- package/src/managers/PartialGroupDMMessageManager.ts +15 -0
- package/src/managers/PermissionOverwriteManager.ts +174 -0
- package/src/managers/PollAnswerVoterManager.ts +59 -0
- package/src/managers/PresenceManager.ts +60 -0
- package/src/managers/ReactionManager.ts +72 -0
- package/src/managers/ReactionUserManager.ts +82 -0
- package/src/managers/RoleManager.ts +432 -0
- package/src/managers/StageInstanceManager.ts +166 -0
- package/src/managers/SubscriptionManager.ts +83 -0
- package/src/managers/ThreadManager.ts +210 -0
- package/src/managers/ThreadMemberManager.ts +194 -0
- package/src/managers/UserManager.ts +139 -0
- package/src/managers/VoiceStateManager.ts +61 -0
- package/src/sharding/Shard.ts +513 -0
- package/src/sharding/ShardClientUtil.ts +293 -0
- package/src/sharding/ShardingManager.ts +374 -0
- package/src/structures/ActionRow.ts +31 -0
- package/src/structures/AnnouncementChannel.ts +25 -0
- package/src/structures/AnonymousGuild.ts +110 -0
- package/src/structures/ApplicationCommand.ts +675 -0
- package/src/structures/ApplicationEmoji.ts +189 -0
- package/src/structures/ApplicationRoleConnectionMetadata.ts +54 -0
- package/src/structures/Attachment.ts +189 -0
- package/src/structures/AuthorizingIntegrationOwners.ts +63 -0
- package/src/structures/AutoModerationActionExecution.ts +138 -0
- package/src/structures/AutoModerationRule.ts +325 -0
- package/src/structures/AutocompleteInteraction.ts +115 -0
- package/src/structures/Base.ts +37 -0
- package/src/structures/BaseChannel.ts +188 -0
- package/src/structures/BaseGuild.ts +134 -0
- package/src/structures/BaseGuildEmoji.ts +113 -0
- package/src/structures/BaseGuildTextChannel.ts +230 -0
- package/src/structures/BaseGuildVoiceChannel.ts +270 -0
- package/src/structures/BaseInteraction.ts +393 -0
- package/src/structures/BaseInvite.ts +192 -0
- package/src/structures/BaseSelectMenuComponent.ts +58 -0
- package/src/structures/ButtonComponent.ts +68 -0
- package/src/structures/ButtonInteraction.ts +8 -0
- package/src/structures/CategoryChannel.ts +46 -0
- package/src/structures/ChannelSelectMenuComponent.ts +18 -0
- package/src/structures/ChannelSelectMenuInteraction.ts +34 -0
- package/src/structures/ChatInputCommandInteraction.ts +43 -0
- package/src/structures/ClientApplication.ts +470 -0
- package/src/structures/ClientPresence.ts +87 -0
- package/src/structures/ClientUser.ts +219 -0
- package/src/structures/CommandInteraction.ts +193 -0
- package/src/structures/CommandInteractionOptionResolver.ts +336 -0
- package/src/structures/Component.ts +59 -0
- package/src/structures/ContainerComponent.ts +63 -0
- package/src/structures/ContextMenuCommandInteraction.ts +68 -0
- package/src/structures/DMChannel.ts +148 -0
- package/src/structures/DirectoryChannel.ts +40 -0
- package/src/structures/Embed.ts +251 -0
- package/src/structures/Emoji.ts +61 -0
- package/src/structures/Entitlement.ts +206 -0
- package/src/structures/FileComponent.ts +41 -0
- package/src/structures/ForumChannel.ts +31 -0
- package/src/structures/GroupDMInvite.ts +34 -0
- package/src/structures/Guild.ts +1605 -0
- package/src/structures/GuildAuditLogs.ts +99 -0
- package/src/structures/GuildAuditLogsEntry.ts +557 -0
- package/src/structures/GuildBan.ts +65 -0
- package/src/structures/GuildChannel.ts +515 -0
- package/src/structures/GuildEmoji.ts +159 -0
- package/src/structures/GuildInvite.ts +233 -0
- package/src/structures/GuildMember.ts +643 -0
- package/src/structures/GuildOnboarding.ts +73 -0
- package/src/structures/GuildOnboardingPrompt.ts +93 -0
- package/src/structures/GuildOnboardingPromptOption.ts +100 -0
- package/src/structures/GuildPreview.ts +218 -0
- package/src/structures/GuildPreviewEmoji.ts +28 -0
- package/src/structures/GuildScheduledEvent.ts +593 -0
- package/src/structures/GuildTemplate.ts +229 -0
- package/src/structures/Integration.ts +257 -0
- package/src/structures/IntegrationApplication.ts +84 -0
- package/src/structures/InteractionCallback.ts +86 -0
- package/src/structures/InteractionCallbackResource.ts +57 -0
- package/src/structures/InteractionCallbackResponse.ts +35 -0
- package/src/structures/InteractionCollector.ts +260 -0
- package/src/structures/InteractionWebhook.ts +65 -0
- package/src/structures/InviteGuild.ts +22 -0
- package/src/structures/LabelComponent.ts +51 -0
- package/src/structures/MediaChannel.ts +8 -0
- package/src/structures/MediaGalleryComponent.ts +31 -0
- package/src/structures/MediaGalleryItem.ts +54 -0
- package/src/structures/MentionableSelectMenuComponent.ts +8 -0
- package/src/structures/MentionableSelectMenuInteraction.ts +76 -0
- package/src/structures/Message.ts +1202 -0
- package/src/structures/MessageCollector.ts +155 -0
- package/src/structures/MessageComponentInteraction.ts +132 -0
- package/src/structures/MessageContextMenuCommandInteraction.ts +18 -0
- package/src/structures/MessageMentions.ts +327 -0
- package/src/structures/MessagePayload.ts +325 -0
- package/src/structures/MessageReaction.ts +219 -0
- package/src/structures/ModalComponentResolver.ts +237 -0
- package/src/structures/ModalSubmitInteraction.ts +260 -0
- package/src/structures/OAuth2Guild.ts +30 -0
- package/src/structures/PartialGroupDMChannel.ts +151 -0
- package/src/structures/PermissionOverwrites.ts +222 -0
- package/src/structures/Poll.ts +195 -0
- package/src/structures/PollAnswer.ts +100 -0
- package/src/structures/Presence.ts +448 -0
- package/src/structures/PrimaryEntryPointCommandInteraction.ts +8 -0
- package/src/structures/ReactionCollector.ts +245 -0
- package/src/structures/ReactionEmoji.ts +30 -0
- package/src/structures/Role.ts +543 -0
- package/src/structures/RoleSelectMenuComponent.ts +8 -0
- package/src/structures/RoleSelectMenuInteraction.ts +34 -0
- package/src/structures/SKU.ts +62 -0
- package/src/structures/SectionComponent.ts +44 -0
- package/src/structures/SeparatorComponent.ts +29 -0
- package/src/structures/SoundboardSound.ts +176 -0
- package/src/structures/StageChannel.ts +118 -0
- package/src/structures/StageInstance.ts +173 -0
- package/src/structures/Sticker.ts +300 -0
- package/src/structures/StickerPack.ts +111 -0
- package/src/structures/StringSelectMenuComponent.ts +18 -0
- package/src/structures/StringSelectMenuInteraction.ts +21 -0
- package/src/structures/Subscription.ts +138 -0
- package/src/structures/Team.ts +131 -0
- package/src/structures/TeamMember.ts +77 -0
- package/src/structures/TextChannel.ts +33 -0
- package/src/structures/TextDisplayComponent.ts +18 -0
- package/src/structures/TextInputComponent.ts +28 -0
- package/src/structures/ThreadChannel.ts +680 -0
- package/src/structures/ThreadMember.ts +125 -0
- package/src/structures/ThreadOnlyChannel.ts +276 -0
- package/src/structures/ThumbnailComponent.ts +51 -0
- package/src/structures/Typing.ts +81 -0
- package/src/structures/UnfurledMediaItem.ts +33 -0
- package/src/structures/User.ts +511 -0
- package/src/structures/UserContextMenuCommandInteraction.ts +28 -0
- package/src/structures/UserSelectMenuComponent.ts +8 -0
- package/src/structures/UserSelectMenuInteraction.ts +54 -0
- package/src/structures/VoiceChannel.ts +119 -0
- package/src/structures/VoiceChannelEffect.ts +92 -0
- package/src/structures/VoiceRegion.ts +52 -0
- package/src/structures/VoiceState.ts +346 -0
- package/src/structures/Webhook.ts +526 -0
- package/src/structures/WelcomeChannel.ts +67 -0
- package/src/structures/WelcomeScreen.ts +53 -0
- package/src/structures/Widget.ts +110 -0
- package/src/structures/WidgetMember.ts +124 -0
- package/src/structures/interfaces/Application.ts +179 -0
- package/src/structures/interfaces/Collector.ts +372 -0
- package/src/structures/interfaces/InteractionResponses.ts +384 -0
- package/src/structures/interfaces/TextBasedChannel.ts +430 -0
- package/src/util/APITypes.ts +690 -0
- package/src/util/ActivityFlagsBitField.ts +26 -0
- package/src/util/ApplicationFlagsBitField.ts +43 -0
- package/src/util/AttachmentFlagsBitField.ts +26 -0
- package/src/util/BitField.ts +178 -0
- package/src/util/ChannelFlagsBitField.ts +43 -0
- package/src/util/Channels.ts +165 -0
- package/src/util/Colors.ts +72 -0
- package/src/util/Components.ts +285 -0
- package/src/util/Constants.ts +251 -0
- package/src/util/DataResolver.ts +146 -0
- package/src/util/Enums.ts +10 -0
- package/src/util/Events.ts +178 -0
- package/src/util/GuildMemberFlagsBitField.ts +43 -0
- package/src/util/IntentsBitField.ts +35 -0
- package/src/util/InviteFlagsBitField.ts +26 -0
- package/src/util/Invites.ts +27 -0
- package/src/util/LimitedCollection.ts +73 -0
- package/src/util/MessageFlagsBitField.ts +43 -0
- package/src/util/Options.ts +215 -0
- package/src/util/Partials.ts +50 -0
- package/src/util/PermissionsBitField.ts +113 -0
- package/src/util/RoleFlagsBitField.ts +26 -0
- package/src/util/SKUFlagsBitField.ts +26 -0
- package/src/util/ShardEvents.ts +26 -0
- package/src/util/Status.ts +16 -0
- package/src/util/Sweepers.ts +532 -0
- package/src/util/Symbols.ts +1 -0
- package/src/util/SystemChannelFlagsBitField.ts +45 -0
- package/src/util/ThreadMemberFlagsBitField.ts +33 -0
- package/src/util/Transformers.ts +123 -0
- package/src/util/UserFlagsBitField.ts +33 -0
- package/src/util/Util.ts +519 -0
|
@@ -0,0 +1,967 @@
|
|
|
1
|
+
import process from 'node:process';
|
|
2
|
+
import { workerData } from 'node:worker_threads';
|
|
3
|
+
import { clearTimeout, setImmediate, setTimeout } from 'node:timers';
|
|
4
|
+
import { Collection } from '@ovencord/collection';
|
|
5
|
+
import { REST, RESTEvents, makeURLSearchParams } from '@ovencord/rest';
|
|
6
|
+
import { WebSocketManager, WebSocketShardEvents, WebSocketShardStatus } from '@ovencord/ws';
|
|
7
|
+
import { AsyncEventEmitter } from '@vladfrangu/async_event_emitter';
|
|
8
|
+
import { GatewayDispatchEvents, GatewayIntentBits, OAuth2Scopes, Routes } from 'discord-api-types/v10';
|
|
9
|
+
import { DiscordjsError, DiscordjsTypeError, ErrorCodes } from '../errors/index.js';
|
|
10
|
+
import { ChannelManager } from '../managers/ChannelManager.js';
|
|
11
|
+
import { GuildManager } from '../managers/GuildManager.js';
|
|
12
|
+
import { UserManager } from '../managers/UserManager.js';
|
|
13
|
+
import { ShardClientUtil } from '../sharding/ShardClientUtil.js';
|
|
14
|
+
import { ClientPresence } from '../structures/ClientPresence.js';
|
|
15
|
+
import { GuildPreview } from '../structures/GuildPreview.js';
|
|
16
|
+
import { GuildTemplate } from '../structures/GuildTemplate.js';
|
|
17
|
+
import { SoundboardSound } from '../structures/SoundboardSound.js';
|
|
18
|
+
import { Sticker } from '../structures/Sticker.js';
|
|
19
|
+
import { StickerPack } from '../structures/StickerPack.js';
|
|
20
|
+
import { VoiceRegion } from '../structures/VoiceRegion.js';
|
|
21
|
+
import { Webhook } from '../structures/Webhook.js';
|
|
22
|
+
import { Widget } from '../structures/Widget.js';
|
|
23
|
+
import { resolveInviteCode, resolveGuildTemplateCode } from '../util/DataResolver.js';
|
|
24
|
+
import { Events } from '../util/Events.js';
|
|
25
|
+
import { IntentsBitField } from '../util/IntentsBitField.js';
|
|
26
|
+
import { createInvite } from '../util/Invites.js';
|
|
27
|
+
import { Options } from '../util/Options.js';
|
|
28
|
+
import { PermissionsBitField } from '../util/PermissionsBitField.js';
|
|
29
|
+
import { Status } from '../util/Status.js';
|
|
30
|
+
import { Sweepers } from '../util/Sweepers.js';
|
|
31
|
+
import { flatten } from '../util/Util.js';
|
|
32
|
+
import { ActionsManager } from './actions/ActionsManager.js';
|
|
33
|
+
import { ClientVoiceManager } from './voice/ClientVoiceManager.js';
|
|
34
|
+
import { PacketHandlers } from './websocket/handlers/index.js';
|
|
35
|
+
|
|
36
|
+
const WaitingForGuildEvents = [GatewayDispatchEvents.GuildCreate, GatewayDispatchEvents.GuildDelete];
|
|
37
|
+
const BeforeReadyWhitelist = [
|
|
38
|
+
GatewayDispatchEvents.Ready,
|
|
39
|
+
GatewayDispatchEvents.Resumed,
|
|
40
|
+
GatewayDispatchEvents.GuildCreate,
|
|
41
|
+
GatewayDispatchEvents.GuildDelete,
|
|
42
|
+
GatewayDispatchEvents.GuildMembersChunk,
|
|
43
|
+
GatewayDispatchEvents.GuildMemberAdd,
|
|
44
|
+
GatewayDispatchEvents.GuildMemberRemove,
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The main hub for interacting with the Discord API, and the starting point for any bot.
|
|
49
|
+
*
|
|
50
|
+
* @extends {AsyncEventEmitter}
|
|
51
|
+
*/
|
|
52
|
+
export class Client extends AsyncEventEmitter {
|
|
53
|
+
public status: any;
|
|
54
|
+
public readyTimeout: any;
|
|
55
|
+
public options: any;
|
|
56
|
+
public rest: REST;
|
|
57
|
+
public presence: ClientPresence;
|
|
58
|
+
public actions: ActionsManager;
|
|
59
|
+
public users: UserManager;
|
|
60
|
+
public guilds: GuildManager;
|
|
61
|
+
public channels: ChannelManager;
|
|
62
|
+
public sweepers: Sweepers;
|
|
63
|
+
public ws: WebSocketManager;
|
|
64
|
+
public shard: ShardClientUtil | null;
|
|
65
|
+
public voice: ClientVoiceManager;
|
|
66
|
+
public user: ClientUser | null;
|
|
67
|
+
public application: ClientApplication | null;
|
|
68
|
+
public pings: Collection<number, number>;
|
|
69
|
+
public lastPingTimestamps: Collection<number, number>;
|
|
70
|
+
public readyTimestamp: number | null;
|
|
71
|
+
public token: string | null;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @param {any} options Options for the client
|
|
75
|
+
*/
|
|
76
|
+
constructor(options: any) {
|
|
77
|
+
super();
|
|
78
|
+
|
|
79
|
+
if (typeof options !== 'object' || options === null) {
|
|
80
|
+
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const defaultOptions = Options.createDefault();
|
|
84
|
+
/**
|
|
85
|
+
* The options the client was instantiated with
|
|
86
|
+
*
|
|
87
|
+
* @type {ClientOptions}
|
|
88
|
+
*/
|
|
89
|
+
this.options = {
|
|
90
|
+
...defaultOptions,
|
|
91
|
+
...options,
|
|
92
|
+
presence: {
|
|
93
|
+
...defaultOptions.presence,
|
|
94
|
+
...options.presence,
|
|
95
|
+
},
|
|
96
|
+
sweepers: {
|
|
97
|
+
...defaultOptions.sweepers,
|
|
98
|
+
...options.sweepers,
|
|
99
|
+
},
|
|
100
|
+
ws: {
|
|
101
|
+
...defaultOptions.ws,
|
|
102
|
+
...options.ws,
|
|
103
|
+
},
|
|
104
|
+
rest: {
|
|
105
|
+
...defaultOptions.rest,
|
|
106
|
+
...options.rest,
|
|
107
|
+
userAgentAppendix: options.rest?.userAgentAppendix
|
|
108
|
+
? `${Options.userAgentAppendix} ${options.rest.userAgentAppendix}`
|
|
109
|
+
: Options.userAgentAppendix,
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* The REST manager of the client
|
|
115
|
+
*
|
|
116
|
+
* @type {REST}
|
|
117
|
+
*/
|
|
118
|
+
this.rest = new REST(this.options.rest);
|
|
119
|
+
|
|
120
|
+
this.rest.on(RESTEvents.Debug, message => this.emit(Events.Debug, message));
|
|
121
|
+
|
|
122
|
+
const data = workerData ?? process.env;
|
|
123
|
+
|
|
124
|
+
if (this.options.ws.shardIds === defaultOptions.ws.shardIds && 'SHARDS' in data) {
|
|
125
|
+
const shards = JSON.parse(data.SHARDS);
|
|
126
|
+
this.options.ws.shardIds = Array.isArray(shards) ? shards : [shards];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (this.options.ws.shardCount === defaultOptions.ws.shardCount && 'SHARD_COUNT' in data) {
|
|
130
|
+
this.options.ws.shardCount = Number(data.SHARD_COUNT);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* The presence of the Client
|
|
135
|
+
*
|
|
136
|
+
* @private
|
|
137
|
+
* @type {ClientPresence}
|
|
138
|
+
*/
|
|
139
|
+
this.presence = new ClientPresence(this, this.options.ws.initialPresence ?? this.options.presence);
|
|
140
|
+
|
|
141
|
+
this._validateOptions();
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* The current status of this Client
|
|
145
|
+
*
|
|
146
|
+
* @type {Status}
|
|
147
|
+
* @private
|
|
148
|
+
*/
|
|
149
|
+
this.status = Status.Idle;
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* A set of guild ids this Client expects to receive
|
|
153
|
+
*
|
|
154
|
+
* @name Client#expectedGuilds
|
|
155
|
+
* @type {Set<string>}
|
|
156
|
+
* @private
|
|
157
|
+
*/
|
|
158
|
+
Object.defineProperty(this, 'expectedGuilds', { value: new Set(), writable: true });
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* The ready timeout
|
|
162
|
+
*
|
|
163
|
+
* @name Client#readyTimeout
|
|
164
|
+
* @type {?NodeJS.Timeout}
|
|
165
|
+
* @private
|
|
166
|
+
*/
|
|
167
|
+
Object.defineProperty(this, 'readyTimeout', { value: null, writable: true });
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* The action manager of the client
|
|
171
|
+
*
|
|
172
|
+
* @type {ActionsManager}
|
|
173
|
+
* @private
|
|
174
|
+
*/
|
|
175
|
+
this.actions = new ActionsManager(this);
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* The user manager of this client
|
|
179
|
+
*
|
|
180
|
+
* @type {UserManager}
|
|
181
|
+
*/
|
|
182
|
+
this.users = new UserManager(this);
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* A manager of all the guilds the client is currently handling -
|
|
186
|
+
* as long as sharding isn't being used, this will be *every* guild the bot is a member of
|
|
187
|
+
*
|
|
188
|
+
* @type {GuildManager}
|
|
189
|
+
*/
|
|
190
|
+
this.guilds = new GuildManager(this);
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* All of the {@link BaseChannel}s that the client is currently handling -
|
|
194
|
+
* as long as sharding isn't being used, this will be *every* channel in *every* guild the bot
|
|
195
|
+
* is a member of. Note that DM channels will not be initially cached, and thus not be present
|
|
196
|
+
* in the Manager without their explicit fetching or use.
|
|
197
|
+
*
|
|
198
|
+
* @type {ChannelManager}
|
|
199
|
+
*/
|
|
200
|
+
this.channels = new ChannelManager(this);
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* The sweeping functions and their intervals used to periodically sweep caches
|
|
204
|
+
*
|
|
205
|
+
* @type {Sweepers}
|
|
206
|
+
*/
|
|
207
|
+
this.sweepers = new Sweepers(this, this.options.sweepers);
|
|
208
|
+
|
|
209
|
+
Object.defineProperty(this, 'token', { writable: true });
|
|
210
|
+
if (!this.token && 'DISCORD_TOKEN' in process.env) {
|
|
211
|
+
/**
|
|
212
|
+
* Authorization token for the logged in bot.
|
|
213
|
+
* If present, this defaults to `process.env.DISCORD_TOKEN` when instantiating the client
|
|
214
|
+
* <warn>This should be kept private at all times.</warn>
|
|
215
|
+
*
|
|
216
|
+
* @type {?string}
|
|
217
|
+
*/
|
|
218
|
+
this.token = process.env.DISCORD_TOKEN;
|
|
219
|
+
} else if (this.options.ws.token) {
|
|
220
|
+
this.token = this.options.ws.token;
|
|
221
|
+
} else {
|
|
222
|
+
this.token = null;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const wsOptions = {
|
|
226
|
+
...this.options.ws,
|
|
227
|
+
intents: this.options.intents.bitfield,
|
|
228
|
+
fetchGatewayInformation: () => this.rest.get(Routes.gatewayBot()),
|
|
229
|
+
// Explicitly nulled to always be set using `setToken` in `login`
|
|
230
|
+
token: null,
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* The WebSocket manager of the client
|
|
235
|
+
*
|
|
236
|
+
* @type {WebSocketManager}
|
|
237
|
+
*/
|
|
238
|
+
this.ws = new WebSocketManager(wsOptions);
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Shard helpers for the client (only if the process was spawned from a {@link ShardingManager})
|
|
242
|
+
*
|
|
243
|
+
* @type {?ShardClientUtil}
|
|
244
|
+
*/
|
|
245
|
+
this.shard = process.env.SHARDING_MANAGER
|
|
246
|
+
? ShardClientUtil.singleton(this, process.env.SHARDING_MANAGER_MODE)
|
|
247
|
+
: null;
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* The voice manager of the client
|
|
251
|
+
*
|
|
252
|
+
* @type {ClientVoiceManager}
|
|
253
|
+
*/
|
|
254
|
+
this.voice = new ClientVoiceManager(this);
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* User that the client is logged in as
|
|
258
|
+
*
|
|
259
|
+
* @type {?ClientUser}
|
|
260
|
+
*/
|
|
261
|
+
this.user = null;
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* The application of this bot
|
|
265
|
+
*
|
|
266
|
+
* @type {?ClientApplication}
|
|
267
|
+
*/
|
|
268
|
+
this.application = null;
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* The latencies of the WebSocketShard connections
|
|
272
|
+
*
|
|
273
|
+
* @type {Collection<number, number>}
|
|
274
|
+
*/
|
|
275
|
+
this.pings = new Collection();
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* The last time a ping was sent (a timestamp) for each WebSocketShard connection
|
|
279
|
+
*
|
|
280
|
+
* @type {Collection<number, number>}
|
|
281
|
+
*/
|
|
282
|
+
this.lastPingTimestamps = new Collection();
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Timestamp of the time the client was last {@link Status.Ready} at
|
|
286
|
+
*
|
|
287
|
+
* @type {?number}
|
|
288
|
+
*/
|
|
289
|
+
this.readyTimestamp = null;
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* An array of queued events before this Client became ready
|
|
293
|
+
*
|
|
294
|
+
* @type {Object[]}
|
|
295
|
+
* @private
|
|
296
|
+
* @name Client#incomingPacketQueue
|
|
297
|
+
*/
|
|
298
|
+
Object.defineProperty(this, 'incomingPacketQueue', { value: [] });
|
|
299
|
+
|
|
300
|
+
this._attachEvents();
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Time at which the client was last regarded as being in the {@link Status.Ready} state
|
|
305
|
+
* (each time the client disconnects and successfully reconnects, this will be overwritten)
|
|
306
|
+
*
|
|
307
|
+
* @type {?Date}
|
|
308
|
+
* @readonly
|
|
309
|
+
*/
|
|
310
|
+
get readyAt() {
|
|
311
|
+
return this.readyTimestamp && new Date(this.readyTimestamp);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* How long it has been since the client last entered the {@link Status.Ready} state in milliseconds
|
|
316
|
+
*
|
|
317
|
+
* @type {?number}
|
|
318
|
+
* @readonly
|
|
319
|
+
*/
|
|
320
|
+
get uptime() {
|
|
321
|
+
return this.readyTimestamp && Date.now() - this.readyTimestamp;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Logs the client in, establishing a WebSocket connection to Discord.
|
|
326
|
+
*
|
|
327
|
+
* @param {string} [token=this.token] Token of the account to log in with
|
|
328
|
+
* @returns {Promise<string>} Token of the account used
|
|
329
|
+
* @example
|
|
330
|
+
* client.login('my token');
|
|
331
|
+
*/
|
|
332
|
+
public async login(token: string | null = this.token): Promise<string> {
|
|
333
|
+
if (!token || typeof token !== 'string') throw new DiscordjsError(ErrorCodes.TokenInvalid);
|
|
334
|
+
this.token = token.replace(/^bot\s*/i, '');
|
|
335
|
+
|
|
336
|
+
this.rest.setToken(this.token);
|
|
337
|
+
|
|
338
|
+
this.emit(Events.Debug, `Provided token: ${this._censoredToken}`);
|
|
339
|
+
this.emit(Events.Debug, 'Preparing to connect to the gateway...');
|
|
340
|
+
|
|
341
|
+
this.ws.setToken(this.token);
|
|
342
|
+
|
|
343
|
+
try {
|
|
344
|
+
await this.ws.connect();
|
|
345
|
+
return this.token;
|
|
346
|
+
} catch (error) {
|
|
347
|
+
await this.destroy();
|
|
348
|
+
throw error;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Checks if the client can be marked as ready
|
|
354
|
+
*
|
|
355
|
+
* @private
|
|
356
|
+
*/
|
|
357
|
+
async _checkReady() {
|
|
358
|
+
// Step 0. Clear the ready timeout, if it exists
|
|
359
|
+
if (this.readyTimeout) {
|
|
360
|
+
clearTimeout(this.readyTimeout);
|
|
361
|
+
this.readyTimeout = null;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Step 1. If we don't have any other guilds pending, we are ready
|
|
365
|
+
if (
|
|
366
|
+
!this.expectedGuilds.size &&
|
|
367
|
+
(await this.ws.fetchStatus()).every(status => status === WebSocketShardStatus.Ready)
|
|
368
|
+
) {
|
|
369
|
+
this.emit(Events.Debug, 'Client received all its guilds. Marking as fully ready.');
|
|
370
|
+
|
|
371
|
+
this._triggerClientReady();
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
const hasGuildsIntent = this.options.intents.has(GatewayIntentBits.Guilds);
|
|
376
|
+
// Step 2. Create a timeout that will mark the client as ready if there are still unavailable guilds
|
|
377
|
+
// * The timeout is 15 seconds by default
|
|
378
|
+
// * This can be optionally changed in the client options via the `waitGuildTimeout` option
|
|
379
|
+
// * a timeout time of zero will skip this timeout, which potentially could cause the Client to miss guilds.
|
|
380
|
+
|
|
381
|
+
this.readyTimeout = setTimeout(
|
|
382
|
+
() => {
|
|
383
|
+
this.emit(
|
|
384
|
+
Events.Debug,
|
|
385
|
+
`${
|
|
386
|
+
hasGuildsIntent
|
|
387
|
+
? `Client did not receive any guild packets in ${this.options.waitGuildTimeout} ms.`
|
|
388
|
+
: 'Client will not receive anymore guild packets.'
|
|
389
|
+
}\nUnavailable guild count: ${this.expectedGuilds.size}`,
|
|
390
|
+
);
|
|
391
|
+
|
|
392
|
+
this.readyTimeout = null;
|
|
393
|
+
|
|
394
|
+
this._triggerClientReady();
|
|
395
|
+
},
|
|
396
|
+
hasGuildsIntent ? this.options.waitGuildTimeout : 0,
|
|
397
|
+
).unref();
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Attaches event handlers to the WebSocketShardManager from `@ovencord/ws`.
|
|
402
|
+
*
|
|
403
|
+
* @private
|
|
404
|
+
*/
|
|
405
|
+
_attachEvents() {
|
|
406
|
+
this.ws.on(WebSocketShardEvents.Debug, (message, shardId) =>
|
|
407
|
+
this.emit(Events.Debug, `[WS => ${typeof shardId === 'number' ? `Shard ${shardId}` : 'Manager'}] ${message}`),
|
|
408
|
+
);
|
|
409
|
+
this.ws.on(WebSocketShardEvents.Dispatch, this._handlePacket.bind(this));
|
|
410
|
+
|
|
411
|
+
this.ws.on(WebSocketShardEvents.HeartbeatComplete, ({ heartbeatAt, latency }, shardId) => {
|
|
412
|
+
this.emit(Events.Debug, `[WS => Shard ${shardId}] Heartbeat acknowledged, latency of ${latency}ms.`);
|
|
413
|
+
this.lastPingTimestamps.set(shardId, heartbeatAt);
|
|
414
|
+
this.pings.set(shardId, latency);
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Processes a packet and queues it if this WebSocketManager is not ready.
|
|
420
|
+
*
|
|
421
|
+
* @param {GatewayDispatchPayload} packet The packet to be handled
|
|
422
|
+
* @param {number} shardId The shardId that received this packet
|
|
423
|
+
* @private
|
|
424
|
+
*/
|
|
425
|
+
async _handlePacket(packet, shardId) {
|
|
426
|
+
if (this.status !== Status.Ready && !BeforeReadyWhitelist.includes(packet.t)) {
|
|
427
|
+
this.incomingPacketQueue.push({ packet, shardId });
|
|
428
|
+
} else {
|
|
429
|
+
if (this.incomingPacketQueue.length) {
|
|
430
|
+
const item = this.incomingPacketQueue.shift();
|
|
431
|
+
setImmediate(async () => {
|
|
432
|
+
await this._handlePacket(item.packet, item.shardId);
|
|
433
|
+
}).unref();
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if (PacketHandlers[packet.t]) {
|
|
437
|
+
PacketHandlers[packet.t](this, packet, shardId);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
if (packet.t === GatewayDispatchEvents.Ready) {
|
|
441
|
+
await this._checkReady();
|
|
442
|
+
} else if (this.status === Status.WaitingForGuilds && WaitingForGuildEvents.includes(packet.t)) {
|
|
443
|
+
this.expectedGuilds.delete(packet.d.id);
|
|
444
|
+
await this._checkReady();
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Broadcasts a packet to every shard of this client handles.
|
|
451
|
+
*
|
|
452
|
+
* @param {Object} packet The packet to send
|
|
453
|
+
* @private
|
|
454
|
+
*/
|
|
455
|
+
async _broadcast(packet) {
|
|
456
|
+
const shardIds = await this.ws.getShardIds();
|
|
457
|
+
return Promise.all(shardIds.map(shardId => this.ws.send(shardId, packet)));
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Causes the client to be marked as ready and emits the ready event.
|
|
462
|
+
*
|
|
463
|
+
* @private
|
|
464
|
+
*/
|
|
465
|
+
_triggerClientReady() {
|
|
466
|
+
this.status = Status.Ready;
|
|
467
|
+
|
|
468
|
+
this.readyTimestamp = Date.now();
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Emitted when the client becomes ready to start working.
|
|
472
|
+
*
|
|
473
|
+
* @event Client#clientReady
|
|
474
|
+
* @param {Client} client The client
|
|
475
|
+
*/
|
|
476
|
+
this.emit(Events.ClientReady, this);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Returns whether the client has logged in, indicative of being able to access
|
|
481
|
+
* properties such as `user` and `application`.
|
|
482
|
+
*
|
|
483
|
+
* @returns {boolean}
|
|
484
|
+
*/
|
|
485
|
+
isReady() {
|
|
486
|
+
return this.status === Status.Ready;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* The average ping of all WebSocketShards
|
|
491
|
+
*
|
|
492
|
+
* @type {?number}
|
|
493
|
+
* @readonly
|
|
494
|
+
*/
|
|
495
|
+
get ping() {
|
|
496
|
+
return this.pings.size ? this.pings.reduce((a, b) => a + b, 0) / this.pings.size : null;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Options used for deleting a webhook.
|
|
501
|
+
*
|
|
502
|
+
* @typedef {Object} WebhookDeleteOptions
|
|
503
|
+
* @property {string} [token] Token of the webhook
|
|
504
|
+
* @property {string} [reason] The reason for deleting the webhook
|
|
505
|
+
*/
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Deletes a webhook.
|
|
509
|
+
*
|
|
510
|
+
* @param {Snowflake} id The webhook's id
|
|
511
|
+
* @param {WebhookDeleteOptions} [options] Options for deleting the webhook
|
|
512
|
+
* @returns {Promise<void>}
|
|
513
|
+
*/
|
|
514
|
+
async deleteWebhook(id, { token, reason } = {}) {
|
|
515
|
+
await this.rest.delete(Routes.webhook(id, token), { auth: !token, reason });
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Increments max listeners by one, if they are not zero.
|
|
520
|
+
*
|
|
521
|
+
* @private
|
|
522
|
+
*/
|
|
523
|
+
incrementMaxListeners() {
|
|
524
|
+
const maxListeners = this.getMaxListeners();
|
|
525
|
+
if (maxListeners !== 0) {
|
|
526
|
+
this.setMaxListeners(maxListeners + 1);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* Decrements max listeners by one, if they are not zero.
|
|
532
|
+
*
|
|
533
|
+
* @private
|
|
534
|
+
*/
|
|
535
|
+
decrementMaxListeners() {
|
|
536
|
+
const maxListeners = this.getMaxListeners();
|
|
537
|
+
if (maxListeners !== 0) {
|
|
538
|
+
this.setMaxListeners(maxListeners - 1);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* Destroys all assets used by the client.
|
|
544
|
+
*
|
|
545
|
+
* @returns {Promise<void>}
|
|
546
|
+
*/
|
|
547
|
+
async destroy() {
|
|
548
|
+
this.rest.clearHashSweeper();
|
|
549
|
+
this.rest.clearHandlerSweeper();
|
|
550
|
+
|
|
551
|
+
this.sweepers.destroy();
|
|
552
|
+
await this.ws.destroy();
|
|
553
|
+
this.token = null;
|
|
554
|
+
this.rest.setToken(null);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Options used when fetching an invite from Discord.
|
|
559
|
+
*
|
|
560
|
+
* @typedef {Object} ClientFetchInviteOptions
|
|
561
|
+
* @property {boolean} [withCounts] Whether to include approximate member counts
|
|
562
|
+
* @property {Snowflake} [guildScheduledEventId] The id of the guild scheduled event to include with
|
|
563
|
+
* the invite
|
|
564
|
+
*/
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* Obtains an invite from Discord.
|
|
568
|
+
*
|
|
569
|
+
* @param {InviteResolvable} invite Invite code or URL
|
|
570
|
+
* @param {ClientFetchInviteOptions} [options] Options for fetching the invite
|
|
571
|
+
* @returns {Promise<Invite>}
|
|
572
|
+
* @example
|
|
573
|
+
* client.fetchInvite('https://discord.gg/djs')
|
|
574
|
+
* .then(invite => console.log(`Obtained invite with code: ${invite.code}`))
|
|
575
|
+
* .catch(console.error);
|
|
576
|
+
*/
|
|
577
|
+
async fetchInvite(invite, { withCounts, guildScheduledEventId } = {}) {
|
|
578
|
+
const code = resolveInviteCode(invite);
|
|
579
|
+
|
|
580
|
+
const query = makeURLSearchParams({
|
|
581
|
+
with_counts: withCounts,
|
|
582
|
+
guild_scheduled_event_id: guildScheduledEventId,
|
|
583
|
+
});
|
|
584
|
+
|
|
585
|
+
const data = await this.rest.get(Routes.invite(code), { query });
|
|
586
|
+
return createInvite(this, data);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* Obtains a template from Discord.
|
|
591
|
+
*
|
|
592
|
+
* @param {GuildTemplateResolvable} template Template code or URL
|
|
593
|
+
* @returns {Promise<GuildTemplate>}
|
|
594
|
+
* @example
|
|
595
|
+
* client.fetchGuildTemplate('https://discord.new/FKvmczH2HyUf')
|
|
596
|
+
* .then(template => console.log(`Obtained template with code: ${template.code}`))
|
|
597
|
+
* .catch(console.error);
|
|
598
|
+
*/
|
|
599
|
+
async fetchGuildTemplate(template) {
|
|
600
|
+
const code = resolveGuildTemplateCode(template);
|
|
601
|
+
const data = await this.rest.get(Routes.template(code));
|
|
602
|
+
return new GuildTemplate(this, data);
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Obtains a webhook from Discord.
|
|
607
|
+
*
|
|
608
|
+
* @param {Snowflake} id The webhook's id
|
|
609
|
+
* @param {string} [token] Token for the webhook
|
|
610
|
+
* @returns {Promise<Webhook>}
|
|
611
|
+
* @example
|
|
612
|
+
* client.fetchWebhook('id', 'token')
|
|
613
|
+
* .then(webhook => console.log(`Obtained webhook with name: ${webhook.name}`))
|
|
614
|
+
* .catch(console.error);
|
|
615
|
+
*/
|
|
616
|
+
async fetchWebhook(id, token) {
|
|
617
|
+
const data = await this.rest.get(Routes.webhook(id, token), { auth: token === undefined });
|
|
618
|
+
return new Webhook(this, { token, ...data });
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* Obtains the available voice regions from Discord.
|
|
623
|
+
*
|
|
624
|
+
* @returns {Promise<Collection<string, VoiceRegion>>}
|
|
625
|
+
* @example
|
|
626
|
+
* client.fetchVoiceRegions()
|
|
627
|
+
* .then(regions => console.log(`Available regions are: ${regions.map(region => region.name).join(', ')}`))
|
|
628
|
+
* .catch(console.error);
|
|
629
|
+
*/
|
|
630
|
+
async fetchVoiceRegions() {
|
|
631
|
+
const apiRegions = await this.rest.get(Routes.voiceRegions());
|
|
632
|
+
const regions = new Collection();
|
|
633
|
+
for (const region of apiRegions) regions.set(region.id, new VoiceRegion(region));
|
|
634
|
+
return regions;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
/**
|
|
638
|
+
* Obtains a sticker from Discord.
|
|
639
|
+
*
|
|
640
|
+
* @param {Snowflake} id The sticker's id
|
|
641
|
+
* @returns {Promise<Sticker>}
|
|
642
|
+
* @example
|
|
643
|
+
* client.fetchSticker('id')
|
|
644
|
+
* .then(sticker => console.log(`Obtained sticker with name: ${sticker.name}`))
|
|
645
|
+
* .catch(console.error);
|
|
646
|
+
*/
|
|
647
|
+
async fetchSticker(id) {
|
|
648
|
+
const data = await this.rest.get(Routes.sticker(id));
|
|
649
|
+
return new Sticker(this, data);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
/**
|
|
653
|
+
* Options for fetching sticker packs.
|
|
654
|
+
*
|
|
655
|
+
* @typedef {Object} StickerPackFetchOptions
|
|
656
|
+
* @property {Snowflake} [packId] The id of the sticker pack to fetch
|
|
657
|
+
*/
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* Obtains the list of available sticker packs.
|
|
661
|
+
*
|
|
662
|
+
* @param {StickerPackFetchOptions} [options={}] Options for fetching sticker packs
|
|
663
|
+
* @returns {Promise<Collection<Snowflake, StickerPack>|StickerPack>}
|
|
664
|
+
* A collection of sticker packs, or a single sticker pack if a packId was provided
|
|
665
|
+
* @example
|
|
666
|
+
* client.fetchStickerPacks()
|
|
667
|
+
* .then(packs => console.log(`Available sticker packs are: ${packs.map(pack => pack.name).join(', ')}`))
|
|
668
|
+
* .catch(console.error);
|
|
669
|
+
* @example
|
|
670
|
+
* client.fetchStickerPacks({ packId: '751604115435421716' })
|
|
671
|
+
* .then(pack => console.log(`Sticker pack name: ${pack.name}`))
|
|
672
|
+
* .catch(console.error);
|
|
673
|
+
*/
|
|
674
|
+
async fetchStickerPacks({ packId } = {}) {
|
|
675
|
+
if (packId) {
|
|
676
|
+
const innerData = await this.rest.get(Routes.stickerPack(packId));
|
|
677
|
+
return new StickerPack(this, innerData);
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
const data = await this.rest.get(Routes.stickerPacks());
|
|
681
|
+
return new Collection(data.sticker_packs.map(stickerPack => [stickerPack.id, new StickerPack(this, stickerPack)]));
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Obtains the list of default soundboard sounds.
|
|
686
|
+
*
|
|
687
|
+
* @returns {Promise<Collection<string, SoundboardSound>>}
|
|
688
|
+
* @example
|
|
689
|
+
* client.fetchDefaultSoundboardSounds()
|
|
690
|
+
* .then(sounds => console.log(`Available soundboard sounds are: ${sounds.map(sound => sound.name).join(', ')}`))
|
|
691
|
+
* .catch(console.error);
|
|
692
|
+
*/
|
|
693
|
+
async fetchDefaultSoundboardSounds() {
|
|
694
|
+
const data = await this.rest.get(Routes.soundboardDefaultSounds());
|
|
695
|
+
return new Collection(data.map(sound => [sound.sound_id, new SoundboardSound(this, sound)]));
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
/**
|
|
699
|
+
* Obtains a guild preview from Discord, available for all guilds the bot is in and all Discoverable guilds.
|
|
700
|
+
*
|
|
701
|
+
* @param {GuildResolvable} guild The guild to fetch the preview for
|
|
702
|
+
* @returns {Promise<GuildPreview>}
|
|
703
|
+
*/
|
|
704
|
+
async fetchGuildPreview(guild) {
|
|
705
|
+
const id = this.guilds.resolveId(guild);
|
|
706
|
+
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'guild', 'GuildResolvable');
|
|
707
|
+
const data = await this.rest.get(Routes.guildPreview(id));
|
|
708
|
+
return new GuildPreview(this, data);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
/**
|
|
712
|
+
* Obtains the widget data of a guild from Discord, available for guilds with the widget enabled.
|
|
713
|
+
*
|
|
714
|
+
* @param {GuildResolvable} guild The guild to fetch the widget data for
|
|
715
|
+
* @returns {Promise<Widget>}
|
|
716
|
+
*/
|
|
717
|
+
async fetchGuildWidget(guild) {
|
|
718
|
+
const id = this.guilds.resolveId(guild);
|
|
719
|
+
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'guild', 'GuildResolvable');
|
|
720
|
+
const data = await this.rest.get(Routes.guildWidgetJSON(id));
|
|
721
|
+
return new Widget(this, data);
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
/**
|
|
725
|
+
* Options for {@link Client#generateInvite}.
|
|
726
|
+
*
|
|
727
|
+
* @typedef {Object} InviteGenerationOptions
|
|
728
|
+
* @property {OAuth2Scopes[]} scopes Scopes that should be requested
|
|
729
|
+
* @property {PermissionResolvable} [permissions] Permissions to request
|
|
730
|
+
* @property {GuildResolvable} [guild] Guild to preselect
|
|
731
|
+
* @property {boolean} [disableGuildSelect] Whether to disable the guild selection
|
|
732
|
+
*/
|
|
733
|
+
|
|
734
|
+
/**
|
|
735
|
+
* Generates a link that can be used to invite the bot to a guild.
|
|
736
|
+
*
|
|
737
|
+
* @param {InviteGenerationOptions} [options={}] Options for the invite
|
|
738
|
+
* @returns {string}
|
|
739
|
+
* @example
|
|
740
|
+
* const link = client.generateInvite({
|
|
741
|
+
* scopes: [OAuth2Scopes.ApplicationsCommands],
|
|
742
|
+
* });
|
|
743
|
+
* console.log(`Generated application invite link: ${link}`);
|
|
744
|
+
* @example
|
|
745
|
+
* const link = client.generateInvite({
|
|
746
|
+
* permissions: [
|
|
747
|
+
* PermissionFlagsBits.SendMessages,
|
|
748
|
+
* PermissionFlagsBits.ManageGuild,
|
|
749
|
+
* PermissionFlagsBits.MentionEveryone,
|
|
750
|
+
* ],
|
|
751
|
+
* scopes: [OAuth2Scopes.Bot],
|
|
752
|
+
* });
|
|
753
|
+
* console.log(`Generated bot invite link: ${link}`);
|
|
754
|
+
*/
|
|
755
|
+
generateInvite(options = {}) {
|
|
756
|
+
if (typeof options !== 'object') throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
|
|
757
|
+
if (!this.application) throw new DiscordjsError(ErrorCodes.ClientNotReady, 'generate an invite link');
|
|
758
|
+
|
|
759
|
+
const { scopes } = options;
|
|
760
|
+
if (scopes === undefined) {
|
|
761
|
+
throw new DiscordjsTypeError(ErrorCodes.InvalidMissingScopes);
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
if (!Array.isArray(scopes)) {
|
|
765
|
+
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'scopes', 'Array of Invite Scopes', true);
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
if (!scopes.some(scope => [OAuth2Scopes.Bot, OAuth2Scopes.ApplicationsCommands].includes(scope))) {
|
|
769
|
+
throw new DiscordjsTypeError(ErrorCodes.InvalidMissingScopes);
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
if (!scopes.includes(OAuth2Scopes.Bot) && options.permissions) {
|
|
773
|
+
throw new DiscordjsTypeError(ErrorCodes.InvalidScopesWithPermissions);
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
const validScopes = Object.values(OAuth2Scopes);
|
|
777
|
+
const invalidScope = scopes.find(scope => !validScopes.includes(scope));
|
|
778
|
+
if (invalidScope) {
|
|
779
|
+
throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array', 'scopes', invalidScope);
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
const query = makeURLSearchParams({
|
|
783
|
+
client_id: this.application.id,
|
|
784
|
+
scope: scopes.join(' '),
|
|
785
|
+
disable_guild_select: options.disableGuildSelect,
|
|
786
|
+
});
|
|
787
|
+
|
|
788
|
+
if (options.permissions) {
|
|
789
|
+
const permissions = PermissionsBitField.resolve(options.permissions);
|
|
790
|
+
if (permissions) query.set('permissions', permissions.toString());
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
if (options.guild) {
|
|
794
|
+
const guildId = this.guilds.resolveId(options.guild);
|
|
795
|
+
if (!guildId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options.guild', 'GuildResolvable');
|
|
796
|
+
query.set('guild_id', guildId);
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
return `${this.options.rest.api}${Routes.oauth2Authorization()}?${query}`;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
toJSON() {
|
|
803
|
+
return flatten(this, { actions: false, presence: false });
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
/**
|
|
807
|
+
* Partially censored client token for debug logging purposes.
|
|
808
|
+
*
|
|
809
|
+
* @type {?string}
|
|
810
|
+
* @readonly
|
|
811
|
+
* @private
|
|
812
|
+
*/
|
|
813
|
+
get _censoredToken() {
|
|
814
|
+
if (!this.token) return null;
|
|
815
|
+
|
|
816
|
+
return this.token
|
|
817
|
+
.split('.')
|
|
818
|
+
.map((val, index) => (index > 1 ? val.replaceAll(/./g, '*') : val))
|
|
819
|
+
.join('.');
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* Calls {@link https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/eval} on a script
|
|
824
|
+
* with the client as `this`.
|
|
825
|
+
*
|
|
826
|
+
* @param {string} script Script to eval
|
|
827
|
+
* @returns {*}
|
|
828
|
+
* @private
|
|
829
|
+
*/
|
|
830
|
+
_eval(script) {
|
|
831
|
+
// eslint-disable-next-line no-eval
|
|
832
|
+
return eval(script);
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
/**
|
|
836
|
+
* Validates the client options.
|
|
837
|
+
*
|
|
838
|
+
* @param {ClientOptions} [options=this.options] Options to validate
|
|
839
|
+
* @private
|
|
840
|
+
*/
|
|
841
|
+
_validateOptions(options = this.options) {
|
|
842
|
+
if (options.intents === undefined && options.ws?.intents === undefined) {
|
|
843
|
+
throw new DiscordjsTypeError(ErrorCodes.ClientMissingIntents);
|
|
844
|
+
} else {
|
|
845
|
+
options.intents = new IntentsBitField(options.intents ?? options.ws.intents).freeze();
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
if (typeof options.sweepers !== 'object' || options.sweepers === null) {
|
|
849
|
+
throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'sweepers', 'an object');
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
if (!Array.isArray(options.partials)) {
|
|
853
|
+
throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'partials', 'an Array');
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
if (typeof options.waitGuildTimeout !== 'number' || Number.isNaN(options.waitGuildTimeout)) {
|
|
857
|
+
throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'waitGuildTimeout', 'a number');
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
if (typeof options.failIfNotExists !== 'boolean') {
|
|
861
|
+
throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'failIfNotExists', 'a boolean');
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
if (typeof options.enforceNonce !== 'boolean') {
|
|
865
|
+
throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'enforceNonce', 'a boolean');
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
if (
|
|
869
|
+
(typeof options.allowedMentions !== 'object' && options.allowedMentions !== undefined) ||
|
|
870
|
+
options.allowedMentions === null
|
|
871
|
+
) {
|
|
872
|
+
throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'allowedMentions', 'an object');
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
if (typeof options.ws !== 'object' || options.ws === null) {
|
|
876
|
+
throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'ws', 'an object');
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
if (
|
|
880
|
+
(typeof options.presence !== 'object' || options.presence === null) &&
|
|
881
|
+
options.ws.initialPresence === undefined
|
|
882
|
+
) {
|
|
883
|
+
throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'presence', 'an object');
|
|
884
|
+
} else {
|
|
885
|
+
options.ws.initialPresence = options.ws.initialPresence ?? this.presence._parse(this.options.presence);
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
if (typeof options.rest !== 'object' || options.rest === null) {
|
|
889
|
+
throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'rest', 'an object');
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
if (typeof options.jsonTransformer !== 'function') {
|
|
893
|
+
throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'jsonTransformer', 'a function');
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
async [Symbol.asyncDispose]() {
|
|
898
|
+
await this.destroy();
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
|
|
903
|
+
|
|
904
|
+
/**
|
|
905
|
+
* @class SnowflakeUtil
|
|
906
|
+
* @classdesc This class is an alias for {@link https://www.npmjs.com/package/@sapphire/snowflake @sapphire/snowflake}'s
|
|
907
|
+
* `DiscordSnowflake` class.
|
|
908
|
+
*
|
|
909
|
+
* Check their documentation
|
|
910
|
+
* {@link https://www.sapphirejs.dev/docs/Documentation/api-utilities/classes/sapphire_snowflake.Snowflake here}
|
|
911
|
+
* ({@link https://www.sapphirejs.dev/docs/Guide/utilities/snowflake guide})
|
|
912
|
+
* to see what you can do.
|
|
913
|
+
* @hideconstructor
|
|
914
|
+
*/
|
|
915
|
+
|
|
916
|
+
/**
|
|
917
|
+
* A {@link https://docs.x.com/resources/fundamentals/x-ids Twitter snowflake},
|
|
918
|
+
* except the epoch is 2015-01-01T00:00:00.000Z.
|
|
919
|
+
*
|
|
920
|
+
* If we have a snowflake '266241948824764416' we can represent it as binary:
|
|
921
|
+
* ```
|
|
922
|
+
* 64 22 17 12 0
|
|
923
|
+
* 000000111011000111100001101001000101000000 00001 00000 000000000000
|
|
924
|
+
* number of milliseconds since Discord epoch worker pid increment
|
|
925
|
+
* ```
|
|
926
|
+
*
|
|
927
|
+
* @typedef {string} Snowflake
|
|
928
|
+
*/
|
|
929
|
+
|
|
930
|
+
/**
|
|
931
|
+
* Emitted for general debugging information.
|
|
932
|
+
*
|
|
933
|
+
* @event Client#debug
|
|
934
|
+
* @param {string} info The debug information
|
|
935
|
+
*/
|
|
936
|
+
|
|
937
|
+
/**
|
|
938
|
+
* Emitted for general warnings.
|
|
939
|
+
*
|
|
940
|
+
* @event Client#warn
|
|
941
|
+
* @param {string} info The warning
|
|
942
|
+
*/
|
|
943
|
+
|
|
944
|
+
/**
|
|
945
|
+
* @external Collection
|
|
946
|
+
* @see {@link https://discord.js.org/docs/packages/collection/stable/Collection:Class}
|
|
947
|
+
*/
|
|
948
|
+
|
|
949
|
+
/**
|
|
950
|
+
* @external REST
|
|
951
|
+
* @see {@link https://discord.js.org/docs/packages/rest/stable/REST:Class}
|
|
952
|
+
*/
|
|
953
|
+
|
|
954
|
+
/**
|
|
955
|
+
* @external ImageURLOptions
|
|
956
|
+
* @see {@link https://discord.js.org/docs/packages/rest/stable/ImageURLOptions:Interface}
|
|
957
|
+
*/
|
|
958
|
+
|
|
959
|
+
/**
|
|
960
|
+
* @external EmojiURLOptions
|
|
961
|
+
* @see {@link https://discord.js.org/docs/packages/rest/stable/EmojiURLOptions:TypeAlias}
|
|
962
|
+
*/
|
|
963
|
+
|
|
964
|
+
/**
|
|
965
|
+
* @external BaseImageURLOptions
|
|
966
|
+
* @see {@link https://discord.js.org/docs/packages/rest/stable/BaseImageURLOptions:Interface}
|
|
967
|
+
*/
|