@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.
Files changed (332) hide show
  1. package/LICENSE +191 -0
  2. package/README.md +148 -0
  3. package/package.json +73 -0
  4. package/src/client/Client.ts +967 -0
  5. package/src/client/actions/Action.ts +141 -0
  6. package/src/client/actions/ActionsManager.ts +138 -0
  7. package/src/client/actions/ChannelCreate.ts +21 -0
  8. package/src/client/actions/ChannelDelete.ts +20 -0
  9. package/src/client/actions/ChannelUpdate.ts +38 -0
  10. package/src/client/actions/GuildChannelsPositionUpdate.ts +17 -0
  11. package/src/client/actions/GuildEmojiCreate.ts +17 -0
  12. package/src/client/actions/GuildEmojiDelete.ts +16 -0
  13. package/src/client/actions/GuildEmojiUpdate.ts +17 -0
  14. package/src/client/actions/GuildEmojisUpdate.ts +30 -0
  15. package/src/client/actions/GuildMemberRemove.ts +29 -0
  16. package/src/client/actions/GuildMemberUpdate.ts +41 -0
  17. package/src/client/actions/GuildRoleCreate.ts +23 -0
  18. package/src/client/actions/GuildRoleDelete.ts +26 -0
  19. package/src/client/actions/GuildRolesPositionUpdate.ts +17 -0
  20. package/src/client/actions/GuildScheduledEventDelete.ts +28 -0
  21. package/src/client/actions/GuildScheduledEventUserAdd.ts +29 -0
  22. package/src/client/actions/GuildScheduledEventUserRemove.ts +29 -0
  23. package/src/client/actions/GuildSoundboardSoundDelete.ts +26 -0
  24. package/src/client/actions/GuildStickerCreate.ts +17 -0
  25. package/src/client/actions/GuildStickerDelete.ts +16 -0
  26. package/src/client/actions/GuildStickerUpdate.ts +17 -0
  27. package/src/client/actions/GuildStickersUpdate.ts +30 -0
  28. package/src/client/actions/GuildUpdate.ts +30 -0
  29. package/src/client/actions/InteractionCreate.ts +104 -0
  30. package/src/client/actions/MessageCreate.ts +38 -0
  31. package/src/client/actions/MessageDelete.ts +29 -0
  32. package/src/client/actions/MessageDeleteBulk.ts +45 -0
  33. package/src/client/actions/MessagePollVoteAdd.ts +37 -0
  34. package/src/client/actions/MessagePollVoteRemove.ts +35 -0
  35. package/src/client/actions/MessageReactionAdd.ts +68 -0
  36. package/src/client/actions/MessageReactionRemove.ts +47 -0
  37. package/src/client/actions/MessageReactionRemoveAll.ts +30 -0
  38. package/src/client/actions/MessageReactionRemoveEmoji.ts +25 -0
  39. package/src/client/actions/MessageUpdate.ts +22 -0
  40. package/src/client/actions/StageInstanceCreate.ts +25 -0
  41. package/src/client/actions/StageInstanceDelete.ts +28 -0
  42. package/src/client/actions/StageInstanceUpdate.ts +27 -0
  43. package/src/client/actions/ThreadCreate.ts +22 -0
  44. package/src/client/actions/ThreadMembersUpdate.ts +45 -0
  45. package/src/client/actions/TypingStart.ts +26 -0
  46. package/src/client/actions/UserUpdate.ts +33 -0
  47. package/src/client/voice/ClientVoiceManager.ts +46 -0
  48. package/src/client/websocket/handlers/APPLICATION_COMMAND_PERMISSIONS_UPDATE.ts +19 -0
  49. package/src/client/websocket/handlers/AUTO_MODERATION_ACTION_EXECUTION.ts +17 -0
  50. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_CREATE.ts +18 -0
  51. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_DELETE.ts +21 -0
  52. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_UPDATE.ts +20 -0
  53. package/src/client/websocket/handlers/CHANNEL_CREATE.ts +4 -0
  54. package/src/client/websocket/handlers/CHANNEL_DELETE.ts +4 -0
  55. package/src/client/websocket/handlers/CHANNEL_PINS_UPDATE.ts +22 -0
  56. package/src/client/websocket/handlers/CHANNEL_UPDATE.ts +16 -0
  57. package/src/client/websocket/handlers/ENTITLEMENT_CREATE.ts +14 -0
  58. package/src/client/websocket/handlers/ENTITLEMENT_DELETE.ts +18 -0
  59. package/src/client/websocket/handlers/ENTITLEMENT_UPDATE.ts +16 -0
  60. package/src/client/websocket/handlers/GUILD_AUDIT_LOG_ENTRY_CREATE.ts +19 -0
  61. package/src/client/websocket/handlers/GUILD_BAN_ADD.ts +15 -0
  62. package/src/client/websocket/handlers/GUILD_BAN_REMOVE.ts +20 -0
  63. package/src/client/websocket/handlers/GUILD_CREATE.ts +34 -0
  64. package/src/client/websocket/handlers/GUILD_DELETE.ts +36 -0
  65. package/src/client/websocket/handlers/GUILD_EMOJIS_UPDATE.ts +4 -0
  66. package/src/client/websocket/handlers/GUILD_INTEGRATIONS_UPDATE.ts +15 -0
  67. package/src/client/websocket/handlers/GUILD_MEMBERS_CHUNK.ts +40 -0
  68. package/src/client/websocket/handlers/GUILD_MEMBER_ADD.ts +17 -0
  69. package/src/client/websocket/handlers/GUILD_MEMBER_REMOVE.ts +4 -0
  70. package/src/client/websocket/handlers/GUILD_MEMBER_UPDATE.ts +4 -0
  71. package/src/client/websocket/handlers/GUILD_ROLE_CREATE.ts +4 -0
  72. package/src/client/websocket/handlers/GUILD_ROLE_DELETE.ts +4 -0
  73. package/src/client/websocket/handlers/GUILD_ROLE_UPDATE.ts +21 -0
  74. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_CREATE.ts +17 -0
  75. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_DELETE.ts +4 -0
  76. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_UPDATE.ts +19 -0
  77. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_ADD.ts +4 -0
  78. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_REMOVE.ts +4 -0
  79. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUNDS_UPDATE.ts +24 -0
  80. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_CREATE.ts +18 -0
  81. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_DELETE.ts +4 -0
  82. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_UPDATE.ts +20 -0
  83. package/src/client/websocket/handlers/GUILD_STICKERS_UPDATE.ts +4 -0
  84. package/src/client/websocket/handlers/GUILD_UPDATE.ts +4 -0
  85. package/src/client/websocket/handlers/INTERACTION_CREATE.ts +4 -0
  86. package/src/client/websocket/handlers/INVITE_CREATE.ts +20 -0
  87. package/src/client/websocket/handlers/INVITE_DELETE.ts +23 -0
  88. package/src/client/websocket/handlers/MESSAGE_CREATE.ts +4 -0
  89. package/src/client/websocket/handlers/MESSAGE_DELETE.ts +4 -0
  90. package/src/client/websocket/handlers/MESSAGE_DELETE_BULK.ts +4 -0
  91. package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_ADD.ts +4 -0
  92. package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_REMOVE.ts +4 -0
  93. package/src/client/websocket/handlers/MESSAGE_REACTION_ADD.ts +4 -0
  94. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE.ts +4 -0
  95. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_ALL.ts +4 -0
  96. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_EMOJI.ts +4 -0
  97. package/src/client/websocket/handlers/MESSAGE_UPDATE.ts +16 -0
  98. package/src/client/websocket/handlers/PRESENCE_UPDATE.ts +42 -0
  99. package/src/client/websocket/handlers/RATE_LIMITED.ts +23 -0
  100. package/src/client/websocket/handlers/READY.ts +29 -0
  101. package/src/client/websocket/handlers/SOUNDBOARD_SOUNDS.ts +24 -0
  102. package/src/client/websocket/handlers/STAGE_INSTANCE_CREATE.ts +4 -0
  103. package/src/client/websocket/handlers/STAGE_INSTANCE_DELETE.ts +4 -0
  104. package/src/client/websocket/handlers/STAGE_INSTANCE_UPDATE.ts +4 -0
  105. package/src/client/websocket/handlers/SUBSCRIPTION_CREATE.ts +14 -0
  106. package/src/client/websocket/handlers/SUBSCRIPTION_DELETE.ts +16 -0
  107. package/src/client/websocket/handlers/SUBSCRIPTION_UPDATE.ts +16 -0
  108. package/src/client/websocket/handlers/THREAD_CREATE.ts +4 -0
  109. package/src/client/websocket/handlers/THREAD_DELETE.ts +17 -0
  110. package/src/client/websocket/handlers/THREAD_LIST_SYNC.ts +50 -0
  111. package/src/client/websocket/handlers/THREAD_MEMBERS_UPDATE.ts +4 -0
  112. package/src/client/websocket/handlers/THREAD_MEMBER_UPDATE.ts +25 -0
  113. package/src/client/websocket/handlers/THREAD_UPDATE.ts +16 -0
  114. package/src/client/websocket/handlers/TYPING_START.ts +4 -0
  115. package/src/client/websocket/handlers/USER_UPDATE.ts +4 -0
  116. package/src/client/websocket/handlers/VOICE_CHANNEL_EFFECT_SEND.ts +16 -0
  117. package/src/client/websocket/handlers/VOICE_SERVER_UPDATE.ts +5 -0
  118. package/src/client/websocket/handlers/VOICE_STATE_UPDATE.ts +37 -0
  119. package/src/client/websocket/handlers/WEBHOOKS_UPDATE.ts +16 -0
  120. package/src/client/websocket/handlers/index.ts +74 -0
  121. package/src/errors/DJSError.ts +50 -0
  122. package/src/errors/ErrorCodes.ts +277 -0
  123. package/src/errors/Messages.ts +155 -0
  124. package/src/errors/index.ts +6 -0
  125. package/src/index.ts +241 -0
  126. package/src/managers/ApplicationCommandManager.ts +303 -0
  127. package/src/managers/ApplicationCommandPermissionsManager.ts +453 -0
  128. package/src/managers/ApplicationEmojiManager.ts +149 -0
  129. package/src/managers/AutoModerationRuleManager.ts +307 -0
  130. package/src/managers/BaseManager.ts +13 -0
  131. package/src/managers/CachedManager.ts +56 -0
  132. package/src/managers/CategoryChannelChildManager.ts +81 -0
  133. package/src/managers/ChannelManager.ts +194 -0
  134. package/src/managers/DMMessageManager.ts +15 -0
  135. package/src/managers/DataManager.ts +38 -0
  136. package/src/managers/EntitlementManager.ts +182 -0
  137. package/src/managers/GuildApplicationCommandManager.ts +29 -0
  138. package/src/managers/GuildBanManager.ts +221 -0
  139. package/src/managers/GuildChannelManager.ts +552 -0
  140. package/src/managers/GuildEmojiManager.ts +262 -0
  141. package/src/managers/GuildEmojiRoleManager.ts +134 -0
  142. package/src/managers/GuildForumThreadManager.ts +84 -0
  143. package/src/managers/GuildInviteManager.ts +236 -0
  144. package/src/managers/GuildManager.ts +265 -0
  145. package/src/managers/GuildMemberManager.ts +619 -0
  146. package/src/managers/GuildMemberRoleManager.ts +230 -0
  147. package/src/managers/GuildMessageManager.ts +31 -0
  148. package/src/managers/GuildScheduledEventManager.ts +330 -0
  149. package/src/managers/GuildSoundboardSoundManager.ts +157 -0
  150. package/src/managers/GuildStickerManager.ts +192 -0
  151. package/src/managers/GuildTextThreadManager.ts +91 -0
  152. package/src/managers/MessageManager.ts +352 -0
  153. package/src/managers/PartialGroupDMMessageManager.ts +15 -0
  154. package/src/managers/PermissionOverwriteManager.ts +174 -0
  155. package/src/managers/PollAnswerVoterManager.ts +59 -0
  156. package/src/managers/PresenceManager.ts +60 -0
  157. package/src/managers/ReactionManager.ts +72 -0
  158. package/src/managers/ReactionUserManager.ts +82 -0
  159. package/src/managers/RoleManager.ts +432 -0
  160. package/src/managers/StageInstanceManager.ts +166 -0
  161. package/src/managers/SubscriptionManager.ts +83 -0
  162. package/src/managers/ThreadManager.ts +210 -0
  163. package/src/managers/ThreadMemberManager.ts +194 -0
  164. package/src/managers/UserManager.ts +139 -0
  165. package/src/managers/VoiceStateManager.ts +61 -0
  166. package/src/sharding/Shard.ts +513 -0
  167. package/src/sharding/ShardClientUtil.ts +293 -0
  168. package/src/sharding/ShardingManager.ts +374 -0
  169. package/src/structures/ActionRow.ts +31 -0
  170. package/src/structures/AnnouncementChannel.ts +25 -0
  171. package/src/structures/AnonymousGuild.ts +110 -0
  172. package/src/structures/ApplicationCommand.ts +675 -0
  173. package/src/structures/ApplicationEmoji.ts +189 -0
  174. package/src/structures/ApplicationRoleConnectionMetadata.ts +54 -0
  175. package/src/structures/Attachment.ts +189 -0
  176. package/src/structures/AuthorizingIntegrationOwners.ts +63 -0
  177. package/src/structures/AutoModerationActionExecution.ts +138 -0
  178. package/src/structures/AutoModerationRule.ts +325 -0
  179. package/src/structures/AutocompleteInteraction.ts +115 -0
  180. package/src/structures/Base.ts +37 -0
  181. package/src/structures/BaseChannel.ts +188 -0
  182. package/src/structures/BaseGuild.ts +134 -0
  183. package/src/structures/BaseGuildEmoji.ts +113 -0
  184. package/src/structures/BaseGuildTextChannel.ts +230 -0
  185. package/src/structures/BaseGuildVoiceChannel.ts +270 -0
  186. package/src/structures/BaseInteraction.ts +393 -0
  187. package/src/structures/BaseInvite.ts +192 -0
  188. package/src/structures/BaseSelectMenuComponent.ts +58 -0
  189. package/src/structures/ButtonComponent.ts +68 -0
  190. package/src/structures/ButtonInteraction.ts +8 -0
  191. package/src/structures/CategoryChannel.ts +46 -0
  192. package/src/structures/ChannelSelectMenuComponent.ts +18 -0
  193. package/src/structures/ChannelSelectMenuInteraction.ts +34 -0
  194. package/src/structures/ChatInputCommandInteraction.ts +43 -0
  195. package/src/structures/ClientApplication.ts +470 -0
  196. package/src/structures/ClientPresence.ts +87 -0
  197. package/src/structures/ClientUser.ts +219 -0
  198. package/src/structures/CommandInteraction.ts +193 -0
  199. package/src/structures/CommandInteractionOptionResolver.ts +336 -0
  200. package/src/structures/Component.ts +59 -0
  201. package/src/structures/ContainerComponent.ts +63 -0
  202. package/src/structures/ContextMenuCommandInteraction.ts +68 -0
  203. package/src/structures/DMChannel.ts +148 -0
  204. package/src/structures/DirectoryChannel.ts +40 -0
  205. package/src/structures/Embed.ts +251 -0
  206. package/src/structures/Emoji.ts +61 -0
  207. package/src/structures/Entitlement.ts +206 -0
  208. package/src/structures/FileComponent.ts +41 -0
  209. package/src/structures/ForumChannel.ts +31 -0
  210. package/src/structures/GroupDMInvite.ts +34 -0
  211. package/src/structures/Guild.ts +1605 -0
  212. package/src/structures/GuildAuditLogs.ts +99 -0
  213. package/src/structures/GuildAuditLogsEntry.ts +557 -0
  214. package/src/structures/GuildBan.ts +65 -0
  215. package/src/structures/GuildChannel.ts +515 -0
  216. package/src/structures/GuildEmoji.ts +159 -0
  217. package/src/structures/GuildInvite.ts +233 -0
  218. package/src/structures/GuildMember.ts +643 -0
  219. package/src/structures/GuildOnboarding.ts +73 -0
  220. package/src/structures/GuildOnboardingPrompt.ts +93 -0
  221. package/src/structures/GuildOnboardingPromptOption.ts +100 -0
  222. package/src/structures/GuildPreview.ts +218 -0
  223. package/src/structures/GuildPreviewEmoji.ts +28 -0
  224. package/src/structures/GuildScheduledEvent.ts +593 -0
  225. package/src/structures/GuildTemplate.ts +229 -0
  226. package/src/structures/Integration.ts +257 -0
  227. package/src/structures/IntegrationApplication.ts +84 -0
  228. package/src/structures/InteractionCallback.ts +86 -0
  229. package/src/structures/InteractionCallbackResource.ts +57 -0
  230. package/src/structures/InteractionCallbackResponse.ts +35 -0
  231. package/src/structures/InteractionCollector.ts +260 -0
  232. package/src/structures/InteractionWebhook.ts +65 -0
  233. package/src/structures/InviteGuild.ts +22 -0
  234. package/src/structures/LabelComponent.ts +51 -0
  235. package/src/structures/MediaChannel.ts +8 -0
  236. package/src/structures/MediaGalleryComponent.ts +31 -0
  237. package/src/structures/MediaGalleryItem.ts +54 -0
  238. package/src/structures/MentionableSelectMenuComponent.ts +8 -0
  239. package/src/structures/MentionableSelectMenuInteraction.ts +76 -0
  240. package/src/structures/Message.ts +1202 -0
  241. package/src/structures/MessageCollector.ts +155 -0
  242. package/src/structures/MessageComponentInteraction.ts +132 -0
  243. package/src/structures/MessageContextMenuCommandInteraction.ts +18 -0
  244. package/src/structures/MessageMentions.ts +327 -0
  245. package/src/structures/MessagePayload.ts +325 -0
  246. package/src/structures/MessageReaction.ts +219 -0
  247. package/src/structures/ModalComponentResolver.ts +237 -0
  248. package/src/structures/ModalSubmitInteraction.ts +260 -0
  249. package/src/structures/OAuth2Guild.ts +30 -0
  250. package/src/structures/PartialGroupDMChannel.ts +151 -0
  251. package/src/structures/PermissionOverwrites.ts +222 -0
  252. package/src/structures/Poll.ts +195 -0
  253. package/src/structures/PollAnswer.ts +100 -0
  254. package/src/structures/Presence.ts +448 -0
  255. package/src/structures/PrimaryEntryPointCommandInteraction.ts +8 -0
  256. package/src/structures/ReactionCollector.ts +245 -0
  257. package/src/structures/ReactionEmoji.ts +30 -0
  258. package/src/structures/Role.ts +543 -0
  259. package/src/structures/RoleSelectMenuComponent.ts +8 -0
  260. package/src/structures/RoleSelectMenuInteraction.ts +34 -0
  261. package/src/structures/SKU.ts +62 -0
  262. package/src/structures/SectionComponent.ts +44 -0
  263. package/src/structures/SeparatorComponent.ts +29 -0
  264. package/src/structures/SoundboardSound.ts +176 -0
  265. package/src/structures/StageChannel.ts +118 -0
  266. package/src/structures/StageInstance.ts +173 -0
  267. package/src/structures/Sticker.ts +300 -0
  268. package/src/structures/StickerPack.ts +111 -0
  269. package/src/structures/StringSelectMenuComponent.ts +18 -0
  270. package/src/structures/StringSelectMenuInteraction.ts +21 -0
  271. package/src/structures/Subscription.ts +138 -0
  272. package/src/structures/Team.ts +131 -0
  273. package/src/structures/TeamMember.ts +77 -0
  274. package/src/structures/TextChannel.ts +33 -0
  275. package/src/structures/TextDisplayComponent.ts +18 -0
  276. package/src/structures/TextInputComponent.ts +28 -0
  277. package/src/structures/ThreadChannel.ts +680 -0
  278. package/src/structures/ThreadMember.ts +125 -0
  279. package/src/structures/ThreadOnlyChannel.ts +276 -0
  280. package/src/structures/ThumbnailComponent.ts +51 -0
  281. package/src/structures/Typing.ts +81 -0
  282. package/src/structures/UnfurledMediaItem.ts +33 -0
  283. package/src/structures/User.ts +511 -0
  284. package/src/structures/UserContextMenuCommandInteraction.ts +28 -0
  285. package/src/structures/UserSelectMenuComponent.ts +8 -0
  286. package/src/structures/UserSelectMenuInteraction.ts +54 -0
  287. package/src/structures/VoiceChannel.ts +119 -0
  288. package/src/structures/VoiceChannelEffect.ts +92 -0
  289. package/src/structures/VoiceRegion.ts +52 -0
  290. package/src/structures/VoiceState.ts +346 -0
  291. package/src/structures/Webhook.ts +526 -0
  292. package/src/structures/WelcomeChannel.ts +67 -0
  293. package/src/structures/WelcomeScreen.ts +53 -0
  294. package/src/structures/Widget.ts +110 -0
  295. package/src/structures/WidgetMember.ts +124 -0
  296. package/src/structures/interfaces/Application.ts +179 -0
  297. package/src/structures/interfaces/Collector.ts +372 -0
  298. package/src/structures/interfaces/InteractionResponses.ts +384 -0
  299. package/src/structures/interfaces/TextBasedChannel.ts +430 -0
  300. package/src/util/APITypes.ts +690 -0
  301. package/src/util/ActivityFlagsBitField.ts +26 -0
  302. package/src/util/ApplicationFlagsBitField.ts +43 -0
  303. package/src/util/AttachmentFlagsBitField.ts +26 -0
  304. package/src/util/BitField.ts +178 -0
  305. package/src/util/ChannelFlagsBitField.ts +43 -0
  306. package/src/util/Channels.ts +165 -0
  307. package/src/util/Colors.ts +72 -0
  308. package/src/util/Components.ts +285 -0
  309. package/src/util/Constants.ts +251 -0
  310. package/src/util/DataResolver.ts +146 -0
  311. package/src/util/Enums.ts +10 -0
  312. package/src/util/Events.ts +178 -0
  313. package/src/util/GuildMemberFlagsBitField.ts +43 -0
  314. package/src/util/IntentsBitField.ts +35 -0
  315. package/src/util/InviteFlagsBitField.ts +26 -0
  316. package/src/util/Invites.ts +27 -0
  317. package/src/util/LimitedCollection.ts +73 -0
  318. package/src/util/MessageFlagsBitField.ts +43 -0
  319. package/src/util/Options.ts +215 -0
  320. package/src/util/Partials.ts +50 -0
  321. package/src/util/PermissionsBitField.ts +113 -0
  322. package/src/util/RoleFlagsBitField.ts +26 -0
  323. package/src/util/SKUFlagsBitField.ts +26 -0
  324. package/src/util/ShardEvents.ts +26 -0
  325. package/src/util/Status.ts +16 -0
  326. package/src/util/Sweepers.ts +532 -0
  327. package/src/util/Symbols.ts +1 -0
  328. package/src/util/SystemChannelFlagsBitField.ts +45 -0
  329. package/src/util/ThreadMemberFlagsBitField.ts +33 -0
  330. package/src/util/Transformers.ts +123 -0
  331. package/src/util/UserFlagsBitField.ts +33 -0
  332. 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
+ */