discord-sb-v13 0.0.1-security → 2.0.0

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.

Potentially problematic release.


This version of discord-sb-v13 might be problematic. Click here for more details.

Files changed (343) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +119 -5
  3. package/package.json +101 -6
  4. package/src/WebSocket.js +39 -0
  5. package/src/client/BaseClient.js +87 -0
  6. package/src/client/Client.js +1154 -0
  7. package/src/client/WebhookClient.js +61 -0
  8. package/src/client/actions/Action.js +115 -0
  9. package/src/client/actions/ActionsManager.js +72 -0
  10. package/src/client/actions/ApplicationCommandPermissionsUpdate.js +34 -0
  11. package/src/client/actions/AutoModerationActionExecution.js +26 -0
  12. package/src/client/actions/AutoModerationRuleCreate.js +27 -0
  13. package/src/client/actions/AutoModerationRuleDelete.js +31 -0
  14. package/src/client/actions/AutoModerationRuleUpdate.js +29 -0
  15. package/src/client/actions/ChannelCreate.js +23 -0
  16. package/src/client/actions/ChannelDelete.js +39 -0
  17. package/src/client/actions/ChannelUpdate.js +34 -0
  18. package/src/client/actions/GuildAuditLogEntryCreate.js +29 -0
  19. package/src/client/actions/GuildBanAdd.js +20 -0
  20. package/src/client/actions/GuildBanRemove.js +25 -0
  21. package/src/client/actions/GuildChannelsPositionUpdate.js +21 -0
  22. package/src/client/actions/GuildDelete.js +65 -0
  23. package/src/client/actions/GuildEmojiCreate.js +20 -0
  24. package/src/client/actions/GuildEmojiDelete.js +21 -0
  25. package/src/client/actions/GuildEmojiUpdate.js +20 -0
  26. package/src/client/actions/GuildEmojisUpdate.js +34 -0
  27. package/src/client/actions/GuildIntegrationsUpdate.js +19 -0
  28. package/src/client/actions/GuildMemberRemove.js +33 -0
  29. package/src/client/actions/GuildMemberUpdate.js +44 -0
  30. package/src/client/actions/GuildRoleCreate.js +25 -0
  31. package/src/client/actions/GuildRoleDelete.js +31 -0
  32. package/src/client/actions/GuildRoleUpdate.js +39 -0
  33. package/src/client/actions/GuildRolesPositionUpdate.js +21 -0
  34. package/src/client/actions/GuildScheduledEventCreate.js +27 -0
  35. package/src/client/actions/GuildScheduledEventDelete.js +31 -0
  36. package/src/client/actions/GuildScheduledEventUpdate.js +30 -0
  37. package/src/client/actions/GuildScheduledEventUserAdd.js +32 -0
  38. package/src/client/actions/GuildScheduledEventUserRemove.js +32 -0
  39. package/src/client/actions/GuildStickerCreate.js +20 -0
  40. package/src/client/actions/GuildStickerDelete.js +21 -0
  41. package/src/client/actions/GuildStickerUpdate.js +20 -0
  42. package/src/client/actions/GuildStickersUpdate.js +34 -0
  43. package/src/client/actions/GuildUpdate.js +33 -0
  44. package/src/client/actions/InteractionCreate.js +115 -0
  45. package/src/client/actions/InviteCreate.js +28 -0
  46. package/src/client/actions/InviteDelete.js +30 -0
  47. package/src/client/actions/MessageCreate.js +50 -0
  48. package/src/client/actions/MessageDelete.js +32 -0
  49. package/src/client/actions/MessageDeleteBulk.js +46 -0
  50. package/src/client/actions/MessageReactionAdd.js +56 -0
  51. package/src/client/actions/MessageReactionRemove.js +45 -0
  52. package/src/client/actions/MessageReactionRemoveAll.js +33 -0
  53. package/src/client/actions/MessageReactionRemoveEmoji.js +28 -0
  54. package/src/client/actions/MessageUpdate.js +26 -0
  55. package/src/client/actions/PresenceUpdate.js +45 -0
  56. package/src/client/actions/StageInstanceCreate.js +28 -0
  57. package/src/client/actions/StageInstanceDelete.js +33 -0
  58. package/src/client/actions/StageInstanceUpdate.js +30 -0
  59. package/src/client/actions/ThreadCreate.js +24 -0
  60. package/src/client/actions/ThreadDelete.js +32 -0
  61. package/src/client/actions/ThreadListSync.js +59 -0
  62. package/src/client/actions/ThreadMemberUpdate.js +30 -0
  63. package/src/client/actions/ThreadMembersUpdate.js +34 -0
  64. package/src/client/actions/TypingStart.js +29 -0
  65. package/src/client/actions/UserUpdate.js +35 -0
  66. package/src/client/actions/VoiceStateUpdate.js +57 -0
  67. package/src/client/actions/WebhooksUpdate.js +20 -0
  68. package/src/client/voice/ClientVoiceManager.js +51 -0
  69. package/src/client/websocket/WebSocketManager.js +412 -0
  70. package/src/client/websocket/WebSocketShard.js +908 -0
  71. package/src/client/websocket/handlers/APPLICATION_COMMAND_AUTOCOMPLETE_RESPONSE.js +23 -0
  72. package/src/client/websocket/handlers/APPLICATION_COMMAND_CREATE.js +18 -0
  73. package/src/client/websocket/handlers/APPLICATION_COMMAND_DELETE.js +20 -0
  74. package/src/client/websocket/handlers/APPLICATION_COMMAND_PERMISSIONS_UPDATE.js +5 -0
  75. package/src/client/websocket/handlers/APPLICATION_COMMAND_UPDATE.js +20 -0
  76. package/src/client/websocket/handlers/AUTO_MODERATION_ACTION_EXECUTION.js +5 -0
  77. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_CREATE.js +5 -0
  78. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_DELETE.js +5 -0
  79. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_UPDATE.js +5 -0
  80. package/src/client/websocket/handlers/CALL_CREATE.js +14 -0
  81. package/src/client/websocket/handlers/CALL_DELETE.js +11 -0
  82. package/src/client/websocket/handlers/CALL_UPDATE.js +11 -0
  83. package/src/client/websocket/handlers/CHANNEL_CREATE.js +5 -0
  84. package/src/client/websocket/handlers/CHANNEL_DELETE.js +5 -0
  85. package/src/client/websocket/handlers/CHANNEL_PINS_UPDATE.js +22 -0
  86. package/src/client/websocket/handlers/CHANNEL_RECIPIENT_ADD.js +16 -0
  87. package/src/client/websocket/handlers/CHANNEL_RECIPIENT_REMOVE.js +16 -0
  88. package/src/client/websocket/handlers/CHANNEL_UPDATE.js +16 -0
  89. package/src/client/websocket/handlers/GUILD_APPLICATION_COMMANDS_UPDATE.js +11 -0
  90. package/src/client/websocket/handlers/GUILD_AUDIT_LOG_ENTRY_CREATE.js +5 -0
  91. package/src/client/websocket/handlers/GUILD_BAN_ADD.js +5 -0
  92. package/src/client/websocket/handlers/GUILD_BAN_REMOVE.js +5 -0
  93. package/src/client/websocket/handlers/GUILD_CREATE.js +46 -0
  94. package/src/client/websocket/handlers/GUILD_DELETE.js +5 -0
  95. package/src/client/websocket/handlers/GUILD_EMOJIS_UPDATE.js +5 -0
  96. package/src/client/websocket/handlers/GUILD_INTEGRATIONS_UPDATE.js +5 -0
  97. package/src/client/websocket/handlers/GUILD_MEMBERS_CHUNK.js +39 -0
  98. package/src/client/websocket/handlers/GUILD_MEMBER_ADD.js +20 -0
  99. package/src/client/websocket/handlers/GUILD_MEMBER_LIST_UPDATE.js +55 -0
  100. package/src/client/websocket/handlers/GUILD_MEMBER_REMOVE.js +5 -0
  101. package/src/client/websocket/handlers/GUILD_MEMBER_UPDATE.js +5 -0
  102. package/src/client/websocket/handlers/GUILD_ROLE_CREATE.js +5 -0
  103. package/src/client/websocket/handlers/GUILD_ROLE_DELETE.js +5 -0
  104. package/src/client/websocket/handlers/GUILD_ROLE_UPDATE.js +5 -0
  105. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_CREATE.js +5 -0
  106. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_DELETE.js +5 -0
  107. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_UPDATE.js +5 -0
  108. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_ADD.js +5 -0
  109. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_REMOVE.js +5 -0
  110. package/src/client/websocket/handlers/GUILD_STICKERS_UPDATE.js +5 -0
  111. package/src/client/websocket/handlers/GUILD_UPDATE.js +5 -0
  112. package/src/client/websocket/handlers/INTERACTION_CREATE.js +16 -0
  113. package/src/client/websocket/handlers/INTERACTION_FAILURE.js +18 -0
  114. package/src/client/websocket/handlers/INTERACTION_MODAL_CREATE.js +11 -0
  115. package/src/client/websocket/handlers/INTERACTION_SUCCESS.js +30 -0
  116. package/src/client/websocket/handlers/INVITE_CREATE.js +5 -0
  117. package/src/client/websocket/handlers/INVITE_DELETE.js +5 -0
  118. package/src/client/websocket/handlers/MESSAGE_ACK.js +16 -0
  119. package/src/client/websocket/handlers/MESSAGE_CREATE.js +5 -0
  120. package/src/client/websocket/handlers/MESSAGE_DELETE.js +5 -0
  121. package/src/client/websocket/handlers/MESSAGE_DELETE_BULK.js +5 -0
  122. package/src/client/websocket/handlers/MESSAGE_REACTION_ADD.js +5 -0
  123. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE.js +5 -0
  124. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_ALL.js +5 -0
  125. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_EMOJI.js +5 -0
  126. package/src/client/websocket/handlers/MESSAGE_UPDATE.js +16 -0
  127. package/src/client/websocket/handlers/PRESENCE_UPDATE.js +5 -0
  128. package/src/client/websocket/handlers/READY.js +172 -0
  129. package/src/client/websocket/handlers/RELATIONSHIP_ADD.js +17 -0
  130. package/src/client/websocket/handlers/RELATIONSHIP_REMOVE.js +15 -0
  131. package/src/client/websocket/handlers/RELATIONSHIP_UPDATE.js +18 -0
  132. package/src/client/websocket/handlers/RESUMED.js +14 -0
  133. package/src/client/websocket/handlers/STAGE_INSTANCE_CREATE.js +5 -0
  134. package/src/client/websocket/handlers/STAGE_INSTANCE_DELETE.js +5 -0
  135. package/src/client/websocket/handlers/STAGE_INSTANCE_UPDATE.js +5 -0
  136. package/src/client/websocket/handlers/THREAD_CREATE.js +5 -0
  137. package/src/client/websocket/handlers/THREAD_DELETE.js +5 -0
  138. package/src/client/websocket/handlers/THREAD_LIST_SYNC.js +5 -0
  139. package/src/client/websocket/handlers/THREAD_MEMBERS_UPDATE.js +5 -0
  140. package/src/client/websocket/handlers/THREAD_MEMBER_UPDATE.js +5 -0
  141. package/src/client/websocket/handlers/THREAD_UPDATE.js +16 -0
  142. package/src/client/websocket/handlers/TYPING_START.js +5 -0
  143. package/src/client/websocket/handlers/USER_GUILD_SETTINGS_UPDATE.js +12 -0
  144. package/src/client/websocket/handlers/USER_NOTE_UPDATE.js +5 -0
  145. package/src/client/websocket/handlers/USER_SETTINGS_UPDATE.js +9 -0
  146. package/src/client/websocket/handlers/USER_UPDATE.js +5 -0
  147. package/src/client/websocket/handlers/VOICE_SERVER_UPDATE.js +6 -0
  148. package/src/client/websocket/handlers/VOICE_STATE_UPDATE.js +5 -0
  149. package/src/client/websocket/handlers/WEBHOOKS_UPDATE.js +5 -0
  150. package/src/client/websocket/handlers/index.js +86 -0
  151. package/src/errors/DJSError.js +61 -0
  152. package/src/errors/Messages.js +227 -0
  153. package/src/errors/index.js +4 -0
  154. package/src/index.js +190 -0
  155. package/src/main.js +42 -0
  156. package/src/managers/ApplicationCommandManager.js +267 -0
  157. package/src/managers/ApplicationCommandPermissionsManager.js +425 -0
  158. package/src/managers/AutoModerationRuleManager.js +296 -0
  159. package/src/managers/BaseGuildEmojiManager.js +80 -0
  160. package/src/managers/BaseManager.js +19 -0
  161. package/src/managers/BillingManager.js +66 -0
  162. package/src/managers/CachedManager.js +71 -0
  163. package/src/managers/ChannelManager.js +139 -0
  164. package/src/managers/ClientUserSettingManager.js +490 -0
  165. package/src/managers/DataManager.js +61 -0
  166. package/src/managers/DeveloperPortalManager.js +104 -0
  167. package/src/managers/GuildApplicationCommandManager.js +28 -0
  168. package/src/managers/GuildBanManager.js +204 -0
  169. package/src/managers/GuildChannelManager.js +502 -0
  170. package/src/managers/GuildEmojiManager.js +171 -0
  171. package/src/managers/GuildEmojiRoleManager.js +118 -0
  172. package/src/managers/GuildFolderManager.js +24 -0
  173. package/src/managers/GuildForumThreadManager.js +114 -0
  174. package/src/managers/GuildInviteManager.js +213 -0
  175. package/src/managers/GuildManager.js +304 -0
  176. package/src/managers/GuildMemberManager.js +724 -0
  177. package/src/managers/GuildMemberRoleManager.js +191 -0
  178. package/src/managers/GuildScheduledEventManager.js +296 -0
  179. package/src/managers/GuildSettingManager.js +148 -0
  180. package/src/managers/GuildStickerManager.js +179 -0
  181. package/src/managers/GuildTextThreadManager.js +98 -0
  182. package/src/managers/InteractionManager.js +39 -0
  183. package/src/managers/MessageManager.js +393 -0
  184. package/src/managers/PermissionOverwriteManager.js +166 -0
  185. package/src/managers/PresenceManager.js +58 -0
  186. package/src/managers/ReactionManager.js +67 -0
  187. package/src/managers/ReactionUserManager.js +71 -0
  188. package/src/managers/RelationshipManager.js +258 -0
  189. package/src/managers/RoleManager.js +352 -0
  190. package/src/managers/SessionManager.js +57 -0
  191. package/src/managers/StageInstanceManager.js +162 -0
  192. package/src/managers/ThreadManager.js +207 -0
  193. package/src/managers/ThreadMemberManager.js +186 -0
  194. package/src/managers/UserManager.js +150 -0
  195. package/src/managers/VoiceStateManager.js +37 -0
  196. package/src/rest/APIRequest.js +136 -0
  197. package/src/rest/APIRouter.js +53 -0
  198. package/src/rest/CaptchaSolver.js +78 -0
  199. package/src/rest/DiscordAPIError.js +103 -0
  200. package/src/rest/HTTPError.js +62 -0
  201. package/src/rest/RESTManager.js +81 -0
  202. package/src/rest/RateLimitError.js +55 -0
  203. package/src/rest/RequestHandler.js +446 -0
  204. package/src/sharding/Shard.js +443 -0
  205. package/src/sharding/ShardClientUtil.js +275 -0
  206. package/src/sharding/ShardingManager.js +318 -0
  207. package/src/structures/AnonymousGuild.js +98 -0
  208. package/src/structures/ApplicationCommand.js +1028 -0
  209. package/src/structures/ApplicationRoleConnectionMetadata.js +45 -0
  210. package/src/structures/AutoModerationActionExecution.js +89 -0
  211. package/src/structures/AutoModerationRule.js +294 -0
  212. package/src/structures/AutocompleteInteraction.js +106 -0
  213. package/src/structures/Base.js +43 -0
  214. package/src/structures/BaseCommandInteraction.js +211 -0
  215. package/src/structures/BaseGuild.js +116 -0
  216. package/src/structures/BaseGuildEmoji.js +56 -0
  217. package/src/structures/BaseGuildTextChannel.js +193 -0
  218. package/src/structures/BaseGuildVoiceChannel.js +243 -0
  219. package/src/structures/BaseMessageComponent.js +114 -0
  220. package/src/structures/ButtonInteraction.js +11 -0
  221. package/src/structures/Call.js +58 -0
  222. package/src/structures/CategoryChannel.js +83 -0
  223. package/src/structures/Channel.js +271 -0
  224. package/src/structures/ClientApplication.js +204 -0
  225. package/src/structures/ClientPresence.js +84 -0
  226. package/src/structures/ClientUser.js +624 -0
  227. package/src/structures/CommandInteraction.js +41 -0
  228. package/src/structures/CommandInteractionOptionResolver.js +276 -0
  229. package/src/structures/ContextMenuInteraction.js +65 -0
  230. package/src/structures/DMChannel.js +280 -0
  231. package/src/structures/DeveloperPortalApplication.js +520 -0
  232. package/src/structures/DirectoryChannel.js +20 -0
  233. package/src/structures/Emoji.js +148 -0
  234. package/src/structures/ForumChannel.js +271 -0
  235. package/src/structures/Guild.js +1744 -0
  236. package/src/structures/GuildAuditLogs.js +734 -0
  237. package/src/structures/GuildBan.js +59 -0
  238. package/src/structures/GuildBoost.js +108 -0
  239. package/src/structures/GuildChannel.js +454 -0
  240. package/src/structures/GuildEmoji.js +161 -0
  241. package/src/structures/GuildFolder.js +75 -0
  242. package/src/structures/GuildMember.js +686 -0
  243. package/src/structures/GuildPreview.js +191 -0
  244. package/src/structures/GuildPreviewEmoji.js +27 -0
  245. package/src/structures/GuildScheduledEvent.js +441 -0
  246. package/src/structures/GuildTemplate.js +236 -0
  247. package/src/structures/Integration.js +188 -0
  248. package/src/structures/IntegrationApplication.js +96 -0
  249. package/src/structures/Interaction.js +351 -0
  250. package/src/structures/InteractionCollector.js +248 -0
  251. package/src/structures/InteractionResponse.js +114 -0
  252. package/src/structures/InteractionWebhook.js +43 -0
  253. package/src/structures/Invite.js +375 -0
  254. package/src/structures/InviteGuild.js +23 -0
  255. package/src/structures/InviteStageInstance.js +86 -0
  256. package/src/structures/Message.js +1188 -0
  257. package/src/structures/MessageActionRow.js +103 -0
  258. package/src/structures/MessageAttachment.js +193 -0
  259. package/src/structures/MessageButton.js +231 -0
  260. package/src/structures/MessageCollector.js +146 -0
  261. package/src/structures/MessageComponentInteraction.js +120 -0
  262. package/src/structures/MessageContextMenuInteraction.js +20 -0
  263. package/src/structures/MessageEmbed.js +586 -0
  264. package/src/structures/MessageMentions.js +272 -0
  265. package/src/structures/MessagePayload.js +358 -0
  266. package/src/structures/MessageReaction.js +171 -0
  267. package/src/structures/MessageSelectMenu.js +391 -0
  268. package/src/structures/Modal.js +279 -0
  269. package/src/structures/ModalSubmitFieldsResolver.js +53 -0
  270. package/src/structures/ModalSubmitInteraction.js +119 -0
  271. package/src/structures/NewsChannel.js +32 -0
  272. package/src/structures/OAuth2Guild.js +28 -0
  273. package/src/structures/PartialGroupDMChannel.js +430 -0
  274. package/src/structures/PermissionOverwrites.js +196 -0
  275. package/src/structures/Presence.js +441 -0
  276. package/src/structures/ReactionCollector.js +229 -0
  277. package/src/structures/ReactionEmoji.js +31 -0
  278. package/src/structures/RichPresence.js +722 -0
  279. package/src/structures/Role.js +515 -0
  280. package/src/structures/SelectMenuInteraction.js +170 -0
  281. package/src/structures/Session.js +81 -0
  282. package/src/structures/StageChannel.js +104 -0
  283. package/src/structures/StageInstance.js +208 -0
  284. package/src/structures/Sticker.js +310 -0
  285. package/src/structures/StickerPack.js +95 -0
  286. package/src/structures/StoreChannel.js +56 -0
  287. package/src/structures/Team.js +167 -0
  288. package/src/structures/TeamMember.js +71 -0
  289. package/src/structures/TextChannel.js +33 -0
  290. package/src/structures/TextInputComponent.js +201 -0
  291. package/src/structures/ThreadChannel.js +626 -0
  292. package/src/structures/ThreadMember.js +105 -0
  293. package/src/structures/Typing.js +74 -0
  294. package/src/structures/User.js +697 -0
  295. package/src/structures/UserContextMenuInteraction.js +29 -0
  296. package/src/structures/VoiceChannel.js +110 -0
  297. package/src/structures/VoiceRegion.js +53 -0
  298. package/src/structures/VoiceState.js +306 -0
  299. package/src/structures/WebEmbed.js +401 -0
  300. package/src/structures/Webhook.js +461 -0
  301. package/src/structures/WelcomeChannel.js +60 -0
  302. package/src/structures/WelcomeScreen.js +48 -0
  303. package/src/structures/Widget.js +87 -0
  304. package/src/structures/WidgetMember.js +99 -0
  305. package/src/structures/interfaces/Application.js +190 -0
  306. package/src/structures/interfaces/Collector.js +300 -0
  307. package/src/structures/interfaces/InteractionResponses.js +313 -0
  308. package/src/structures/interfaces/TextBasedChannel.js +566 -0
  309. package/src/util/ActivityFlags.js +44 -0
  310. package/src/util/ApplicationFlags.js +74 -0
  311. package/src/util/BitField.js +170 -0
  312. package/src/util/ChannelFlags.js +45 -0
  313. package/src/util/Constants.js +1917 -0
  314. package/src/util/DataResolver.js +145 -0
  315. package/src/util/Formatters.js +214 -0
  316. package/src/util/GuildMemberFlags.js +43 -0
  317. package/src/util/Intents.js +74 -0
  318. package/src/util/LimitedCollection.js +131 -0
  319. package/src/util/MessageFlags.js +54 -0
  320. package/src/util/Options.js +360 -0
  321. package/src/util/Permissions.js +187 -0
  322. package/src/util/PremiumUsageFlags.js +31 -0
  323. package/src/util/PurchasedFlags.js +31 -0
  324. package/src/util/RemoteAuth.js +522 -0
  325. package/src/util/SnowflakeUtil.js +92 -0
  326. package/src/util/Sweepers.js +466 -0
  327. package/src/util/SystemChannelFlags.js +55 -0
  328. package/src/util/ThreadMemberFlags.js +30 -0
  329. package/src/util/UserFlags.js +104 -0
  330. package/src/util/Util.js +741 -0
  331. package/src/util/Voice.js +1456 -0
  332. package/src/util/arRPC/index.js +229 -0
  333. package/src/util/arRPC/process/detectable.json +1 -0
  334. package/src/util/arRPC/process/index.js +102 -0
  335. package/src/util/arRPC/process/native/index.js +5 -0
  336. package/src/util/arRPC/process/native/linux.js +37 -0
  337. package/src/util/arRPC/process/native/win32.js +25 -0
  338. package/src/util/arRPC/transports/ipc.js +281 -0
  339. package/src/util/arRPC/transports/websocket.js +128 -0
  340. package/typings/enums.d.ts +346 -0
  341. package/typings/index.d.ts +7725 -0
  342. package/typings/index.test-d.ts +0 -0
  343. package/typings/rawDataTypes.d.ts +283 -0
@@ -0,0 +1,1028 @@
1
+ 'use strict';
2
+
3
+ const { setTimeout } = require('node:timers');
4
+ const { findBestMatch } = require('string-similarity');
5
+ const Base = require('./Base');
6
+ const MessagePayload = require('./MessagePayload');
7
+ const ApplicationCommandPermissionsManager = require('../managers/ApplicationCommandPermissionsManager');
8
+ const {
9
+ ApplicationCommandOptionTypes,
10
+ ApplicationCommandTypes,
11
+ ChannelTypes,
12
+ Events,
13
+ InteractionTypes,
14
+ } = require('../util/Constants');
15
+ const Permissions = require('../util/Permissions');
16
+ const SnowflakeUtil = require('../util/SnowflakeUtil');
17
+ const { lazy, getAttachments, uploadFile } = require('../util/Util');
18
+ const Message = lazy(() => require('../structures/Message').Message);
19
+
20
+ /**
21
+ * Represents an application command.
22
+ * @extends {Base}
23
+ */
24
+ class ApplicationCommand extends Base {
25
+ constructor(client, data) {
26
+ super(client);
27
+
28
+ /**
29
+ * The command's id
30
+ * @type {Snowflake}
31
+ */
32
+ this.id = data.id;
33
+
34
+ /**
35
+ * The parent application's id
36
+ * @type {Snowflake}
37
+ */
38
+ this.applicationId = data.application_id;
39
+
40
+ /**
41
+ * The manager for permissions of this command on its guild or arbitrary guilds when the command is global
42
+ * @type {ApplicationCommandPermissionsManager}
43
+ */
44
+ this.permissions = new ApplicationCommandPermissionsManager(this, this.applicationId);
45
+
46
+ /**
47
+ * The type of this application command
48
+ * @type {ApplicationCommandType}
49
+ */
50
+ this.type = ApplicationCommandTypes[data.type];
51
+
52
+ this.user = client.users.cache.get(this.applicationId);
53
+
54
+ this._patch(data);
55
+ }
56
+
57
+ /**
58
+ * The guild this command is part of
59
+ * @type {?Guild}
60
+ * @readonly
61
+ */
62
+ get guild() {
63
+ return this.client.guilds.resolve(this.guildId);
64
+ }
65
+
66
+ _patch(data) {
67
+ if ('guild_id' in data) {
68
+ /**
69
+ * The guild's id this command is part of, this may be non-null when `guild` is `null` if the command
70
+ * was fetched from the `ApplicationCommandManager`
71
+ * @type {?Snowflake}
72
+ */
73
+ this.guildId = data.guild_id ?? null;
74
+ }
75
+
76
+ if ('name' in data) {
77
+ /**
78
+ * The name of this command
79
+ * @type {string}
80
+ */
81
+ this.name = data.name;
82
+ }
83
+
84
+ if ('name_localizations' in data) {
85
+ /**
86
+ * The name localizations for this command
87
+ * @type {?Object<Locale, string>}
88
+ */
89
+ this.nameLocalizations = data.name_localizations;
90
+ } else {
91
+ this.nameLocalizations ??= null;
92
+ }
93
+
94
+ if ('name_localized' in data) {
95
+ /**
96
+ * The localized name for this command
97
+ * @type {?string}
98
+ */
99
+ this.nameLocalized = data.name_localized;
100
+ } else {
101
+ this.nameLocalized ??= null;
102
+ }
103
+
104
+ if ('description' in data) {
105
+ /**
106
+ * The description of this command
107
+ * @type {string}
108
+ */
109
+ this.description = data.description;
110
+ }
111
+
112
+ if ('description_localizations' in data) {
113
+ /**
114
+ * The description localizations for this command
115
+ * @type {?Object<Locale, string>}
116
+ */
117
+ this.descriptionLocalizations = data.description_localizations;
118
+ } else {
119
+ this.descriptionLocalizations ??= null;
120
+ }
121
+
122
+ if ('description_localized' in data) {
123
+ /**
124
+ * The localized description for this command
125
+ * @type {?string}
126
+ */
127
+ this.descriptionLocalized = data.description_localized;
128
+ } else {
129
+ this.descriptionLocalized ??= null;
130
+ }
131
+
132
+ if ('options' in data) {
133
+ /**
134
+ * The options of this command
135
+ * @type {ApplicationCommandOption[]}
136
+ */
137
+ this.options = data.options.map(o => this.constructor.transformOption(o, true));
138
+ } else {
139
+ this.options ??= [];
140
+ }
141
+
142
+ /* eslint-disable max-len */
143
+ if ('default_permission' in data) {
144
+ /**
145
+ * Whether the command is enabled by default when the app is added to a guild
146
+ * @type {boolean}
147
+ * @deprecated Use {@link ApplicationCommand.defaultMemberPermissions} and {@link ApplicationCommand.dmPermission} instead.
148
+ */
149
+ this.defaultPermission = data.default_permission;
150
+ }
151
+
152
+ /* eslint-disable max-len */
153
+
154
+ if ('default_member_permissions' in data) {
155
+ /**
156
+ * The default bitfield used to determine whether this command be used in a guild
157
+ * @type {?Readonly<Permissions>}
158
+ */
159
+ this.defaultMemberPermissions = data.default_member_permissions
160
+ ? new Permissions(BigInt(data.default_member_permissions)).freeze()
161
+ : null;
162
+ } else {
163
+ this.defaultMemberPermissions ??= null;
164
+ }
165
+
166
+ if ('dm_permission' in data) {
167
+ /**
168
+ * Whether the command can be used in DMs
169
+ * <info>This property is always `null` on guild commands</info>
170
+ * @type {?boolean}
171
+ */
172
+ this.dmPermission = data.dm_permission;
173
+ } else {
174
+ this.dmPermission ??= null;
175
+ }
176
+
177
+ if ('version' in data) {
178
+ /**
179
+ * Autoincrementing version identifier updated during substantial record changes
180
+ * @type {Snowflake}
181
+ */
182
+ this.version = data.version;
183
+ }
184
+ }
185
+
186
+ /**
187
+ * The timestamp the command was created at
188
+ * @type {number}
189
+ * @readonly
190
+ */
191
+ get createdTimestamp() {
192
+ return SnowflakeUtil.timestampFrom(this.id);
193
+ }
194
+
195
+ /**
196
+ * The time the command was created at
197
+ * @type {Date}
198
+ * @readonly
199
+ */
200
+ get createdAt() {
201
+ return new Date(this.createdTimestamp);
202
+ }
203
+
204
+ /**
205
+ * The manager that this command belongs to
206
+ * @type {ApplicationCommandManager}
207
+ * @readonly
208
+ */
209
+ get manager() {
210
+ return (this.guild ?? this.client.application).commands;
211
+ }
212
+
213
+ /**
214
+ * Data for creating or editing an application command.
215
+ * @typedef {Object} ApplicationCommandData
216
+ * @property {string} name The name of the command
217
+ * @property {Object<Locale, string>} [nameLocalizations] The localizations for the command name
218
+ * @property {string} description The description of the command
219
+ * @property {Object<Locale, string>} [descriptionLocalizations] The localizations for the command description
220
+ * @property {ApplicationCommandType} [type] The type of the command
221
+ * @property {ApplicationCommandOptionData[]} [options] Options for the command
222
+ * @property {boolean} [defaultPermission] Whether the command is enabled by default when the app is added to a guild
223
+ * @property {?PermissionResolvable} [defaultMemberPermissions] The bitfield used to determine the default permissions
224
+ * a member needs in order to run the command
225
+ * @property {boolean} [dmPermission] Whether the command is enabled in DMs
226
+ */
227
+
228
+ /**
229
+ * An option for an application command or subcommand.
230
+ * <info>In addition to the listed properties, when used as a parameter,
231
+ * API style `snake_case` properties can be used for compatibility with generators like `@discordjs/builders`.</info>
232
+ * <warn>Note that providing a value for the `camelCase` counterpart for any `snake_case` property
233
+ * will discard the provided `snake_case` property.</warn>
234
+ * @typedef {Object} ApplicationCommandOptionData
235
+ * @property {ApplicationCommandOptionType|number} type The type of the option
236
+ * @property {string} name The name of the option
237
+ * @property {Object<Locale, string>} [nameLocalizations] The name localizations for the option
238
+ * @property {string} description The description of the option
239
+ * @property {Object<Locale, string>} [descriptionLocalizations] The description localizations for the option
240
+ * @property {boolean} [autocomplete] Whether the option is an autocomplete option
241
+ * @property {boolean} [required] Whether the option is required
242
+ * @property {ApplicationCommandOptionChoiceData[]} [choices] The choices of the option for the user to pick from
243
+ * @property {ApplicationCommandOptionData[]} [options] Additional options if this option is a subcommand (group)
244
+ * @property {ChannelType[]|number[]} [channelTypes] When the option type is channel,
245
+ * the allowed types of channels that can be selected
246
+ * @property {number} [minValue] The minimum value for an `INTEGER` or `NUMBER` option
247
+ * @property {number} [maxValue] The maximum value for an `INTEGER` or `NUMBER` option
248
+ * @property {number} [minLength] The minimum length for a `STRING` option
249
+ * (maximum of `6000`)
250
+ * @property {number} [maxLength] The maximum length for a `STRING` option
251
+ * (maximum of `6000`)
252
+ */
253
+
254
+ /**
255
+ * @typedef {Object} ApplicationCommandOptionChoiceData
256
+ * @property {string} name The name of the choice
257
+ * @property {Object<Locale, string>} [nameLocalizations] The localized names for this choice
258
+ * @property {string|number} value The value of the choice
259
+ */
260
+
261
+ /**
262
+ * Edits this application command.
263
+ * @param {Partial<ApplicationCommandData>} data The data to update the command with
264
+ * @returns {Promise<ApplicationCommand>}
265
+ * @example
266
+ * // Edit the description of this command
267
+ * command.edit({
268
+ * description: 'New description',
269
+ * })
270
+ * .then(console.log)
271
+ * .catch(console.error);
272
+ */
273
+ edit(data) {
274
+ return this.manager.edit(this, data, this.guildId);
275
+ }
276
+
277
+ /**
278
+ * Edits the name of this ApplicationCommand
279
+ * @param {string} name The new name of the command
280
+ * @returns {Promise<ApplicationCommand>}
281
+ */
282
+ setName(name) {
283
+ return this.edit({ name });
284
+ }
285
+
286
+ /**
287
+ * Edits the localized names of this ApplicationCommand
288
+ * @param {Object<Locale, string>} nameLocalizations The new localized names for the command
289
+ * @returns {Promise<ApplicationCommand>}
290
+ * @example
291
+ * // Edit the name localizations of this command
292
+ * command.setLocalizedNames({
293
+ * 'en-GB': 'test',
294
+ * 'pt-BR': 'teste',
295
+ * })
296
+ * .then(console.log)
297
+ * .catch(console.error)
298
+ */
299
+ setNameLocalizations(nameLocalizations) {
300
+ return this.edit({ nameLocalizations });
301
+ }
302
+
303
+ /**
304
+ * Edits the description of this ApplicationCommand
305
+ * @param {string} description The new description of the command
306
+ * @returns {Promise<ApplicationCommand>}
307
+ */
308
+ setDescription(description) {
309
+ return this.edit({ description });
310
+ }
311
+
312
+ /**
313
+ * Edits the localized descriptions of this ApplicationCommand
314
+ * @param {Object<Locale, string>} descriptionLocalizations The new localized descriptions for the command
315
+ * @returns {Promise<ApplicationCommand>}
316
+ * @example
317
+ * // Edit the description localizations of this command
318
+ * command.setLocalizedDescriptions({
319
+ * 'en-GB': 'A test command',
320
+ * 'pt-BR': 'Um comando de teste',
321
+ * })
322
+ * .then(console.log)
323
+ * .catch(console.error)
324
+ */
325
+ setDescriptionLocalizations(descriptionLocalizations) {
326
+ return this.edit({ descriptionLocalizations });
327
+ }
328
+
329
+ /* eslint-disable max-len */
330
+ /**
331
+ * Edits the default permission of this ApplicationCommand
332
+ * @param {boolean} [defaultPermission=true] The default permission for this command
333
+ * @returns {Promise<ApplicationCommand>}
334
+ * @deprecated Use {@link ApplicationCommand#setDefaultMemberPermissions} and {@link ApplicationCommand#setDMPermission} instead.
335
+ */
336
+ setDefaultPermission(defaultPermission = true) {
337
+ return this.edit({ defaultPermission });
338
+ }
339
+
340
+ /* eslint-enable max-len */
341
+
342
+ /**
343
+ * Edits the default member permissions of this ApplicationCommand
344
+ * @param {?PermissionResolvable} defaultMemberPermissions The default member permissions required to run this command
345
+ * @returns {Promise<ApplicationCommand>}
346
+ */
347
+ setDefaultMemberPermissions(defaultMemberPermissions) {
348
+ return this.edit({ defaultMemberPermissions });
349
+ }
350
+
351
+ /**
352
+ * Edits the DM permission of this ApplicationCommand
353
+ * @param {boolean} [dmPermission=true] Whether the command can be used in DMs
354
+ * @returns {Promise<ApplicationCommand>}
355
+ */
356
+ setDMPermission(dmPermission = true) {
357
+ return this.edit({ dmPermission });
358
+ }
359
+
360
+ /**
361
+ * Edits the options of this ApplicationCommand
362
+ * @param {ApplicationCommandOptionData[]} options The options to set for this command
363
+ * @returns {Promise<ApplicationCommand>}
364
+ */
365
+ setOptions(options) {
366
+ return this.edit({ options });
367
+ }
368
+
369
+ /**
370
+ * Deletes this command.
371
+ * @returns {Promise<ApplicationCommand>}
372
+ * @example
373
+ * // Delete this command
374
+ * command.delete()
375
+ * .then(console.log)
376
+ * .catch(console.error);
377
+ */
378
+ delete() {
379
+ return this.manager.delete(this, this.guildId);
380
+ }
381
+
382
+ /**
383
+ * Whether this command equals another command. It compares all properties, so for most operations
384
+ * it is advisable to just compare `command.id === command2.id` as it is much faster and is often
385
+ * what most users need.
386
+ * @param {ApplicationCommand|ApplicationCommandData|APIApplicationCommand} command The command to compare with
387
+ * @param {boolean} [enforceOptionOrder=false] Whether to strictly check that options and choices are in the same
388
+ * order in the array <info>The client may not always respect this ordering!</info>
389
+ * @returns {boolean}
390
+ */
391
+ equals(command, enforceOptionOrder = false) {
392
+ // If given an id, check if the id matches
393
+ if (command.id && this.id !== command.id) return false;
394
+ let defaultMemberPermissions = null;
395
+ let dmPermission = command.dmPermission ?? command.dm_permission;
396
+
397
+ if ('default_member_permissions' in command) {
398
+ defaultMemberPermissions = command.default_member_permissions
399
+ ? new Permissions(BigInt(command.default_member_permissions)).bitfield
400
+ : null;
401
+ }
402
+
403
+ if ('defaultMemberPermissions' in command) {
404
+ defaultMemberPermissions =
405
+ command.defaultMemberPermissions !== null ? new Permissions(command.defaultMemberPermissions).bitfield : null;
406
+ }
407
+ // Check top level parameters
408
+ const commandType = typeof command.type === 'string' ? command.type : ApplicationCommandTypes[command.type];
409
+ if (
410
+ command.name !== this.name ||
411
+ ('description' in command && command.description !== this.description) ||
412
+ ('version' in command && command.version !== this.version) ||
413
+ ('autocomplete' in command && command.autocomplete !== this.autocomplete) ||
414
+ (commandType && commandType !== this.type) ||
415
+ defaultMemberPermissions !== (this.defaultMemberPermissions?.bitfield ?? null) ||
416
+ (typeof dmPermission !== 'undefined' && dmPermission !== this.dmPermission) ||
417
+ // Future proof for options being nullable
418
+ // TODO: remove ?? 0 on each when nullable
419
+ (command.options?.length ?? 0) !== (this.options?.length ?? 0) ||
420
+ (command.defaultPermission ?? command.default_permission ?? true) !== this.defaultPermission
421
+ ) {
422
+ return false;
423
+ }
424
+
425
+ if (command.options) {
426
+ return this.constructor.optionsEqual(this.options, command.options, enforceOptionOrder);
427
+ }
428
+ return true;
429
+ }
430
+
431
+ /**
432
+ * Recursively checks that all options for an {@link ApplicationCommand} are equal to the provided options.
433
+ * In most cases it is better to compare using {@link ApplicationCommand#equals}
434
+ * @param {ApplicationCommandOptionData[]} existing The options on the existing command,
435
+ * should be {@link ApplicationCommand#options}
436
+ * @param {ApplicationCommandOptionData[]|APIApplicationCommandOption[]} options The options to compare against
437
+ * @param {boolean} [enforceOptionOrder=false] Whether to strictly check that options and choices are in the same
438
+ * order in the array <info>The client may not always respect this ordering!</info>
439
+ * @returns {boolean}
440
+ */
441
+ static optionsEqual(existing, options, enforceOptionOrder = false) {
442
+ if (existing.length !== options.length) return false;
443
+ if (enforceOptionOrder) {
444
+ return existing.every((option, index) => this._optionEquals(option, options[index], enforceOptionOrder));
445
+ }
446
+ const newOptions = new Map(options.map(option => [option.name, option]));
447
+ for (const option of existing) {
448
+ const foundOption = newOptions.get(option.name);
449
+ if (!foundOption || !this._optionEquals(option, foundOption)) {
450
+ return false;
451
+ }
452
+ }
453
+ return true;
454
+ }
455
+
456
+ /**
457
+ * Checks that an option for an {@link ApplicationCommand} is equal to the provided option
458
+ * In most cases it is better to compare using {@link ApplicationCommand#equals}
459
+ * @param {ApplicationCommandOptionData} existing The option on the existing command,
460
+ * should be from {@link ApplicationCommand#options}
461
+ * @param {ApplicationCommandOptionData|APIApplicationCommandOption} option The option to compare against
462
+ * @param {boolean} [enforceOptionOrder=false] Whether to strictly check that options or choices are in the same
463
+ * order in their array <info>The client may not always respect this ordering!</info>
464
+ * @returns {boolean}
465
+ * @private
466
+ */
467
+ static _optionEquals(existing, option, enforceOptionOrder = false) {
468
+ const optionType = typeof option.type === 'string' ? option.type : ApplicationCommandOptionTypes[option.type];
469
+ if (
470
+ option.name !== existing.name ||
471
+ optionType !== existing.type ||
472
+ option.description !== existing.description ||
473
+ option.autocomplete !== existing.autocomplete ||
474
+ (option.required ?? (['SUB_COMMAND', 'SUB_COMMAND_GROUP'].includes(optionType) ? undefined : false)) !==
475
+ existing.required ||
476
+ option.choices?.length !== existing.choices?.length ||
477
+ option.options?.length !== existing.options?.length ||
478
+ (option.channelTypes ?? option.channel_types)?.length !== existing.channelTypes?.length ||
479
+ (option.minValue ?? option.min_value) !== existing.minValue ||
480
+ (option.maxValue ?? option.max_value) !== existing.maxValue ||
481
+ (option.minLength ?? option.min_length) !== existing.minLength ||
482
+ (option.maxLength ?? option.max_length) !== existing.maxLength
483
+ ) {
484
+ return false;
485
+ }
486
+
487
+ if (existing.choices) {
488
+ if (
489
+ enforceOptionOrder &&
490
+ !existing.choices.every(
491
+ (choice, index) => choice.name === option.choices[index].name && choice.value === option.choices[index].value,
492
+ )
493
+ ) {
494
+ return false;
495
+ }
496
+ if (!enforceOptionOrder) {
497
+ const newChoices = new Map(option.choices.map(choice => [choice.name, choice]));
498
+ for (const choice of existing.choices) {
499
+ const foundChoice = newChoices.get(choice.name);
500
+ if (!foundChoice || foundChoice.value !== choice.value) return false;
501
+ }
502
+ }
503
+ }
504
+
505
+ if (existing.channelTypes) {
506
+ const newTypes = (option.channelTypes ?? option.channel_types).map(type =>
507
+ typeof type === 'number' ? ChannelTypes[type] : type,
508
+ );
509
+ for (const type of existing.channelTypes) {
510
+ if (!newTypes.includes(type)) return false;
511
+ }
512
+ }
513
+
514
+ if (existing.options) {
515
+ return this.optionsEqual(existing.options, option.options, enforceOptionOrder);
516
+ }
517
+ return true;
518
+ }
519
+
520
+ /**
521
+ * An option for an application command or subcommand.
522
+ * @typedef {Object} ApplicationCommandOption
523
+ * @property {ApplicationCommandOptionType} type The type of the option
524
+ * @property {string} name The name of the option
525
+ * @property {Object<string, string>} [nameLocalizations] The localizations for the option name
526
+ * @property {string} [nameLocalized] The localized name for this option
527
+ * @property {string} description The description of the option
528
+ * @property {Object<string, string>} [descriptionLocalizations] The localizations for the option description
529
+ * @property {string} [descriptionLocalized] The localized description for this option
530
+ * @property {boolean} [required] Whether the option is required
531
+ * @property {boolean} [autocomplete] Whether the option is an autocomplete option
532
+ * @property {ApplicationCommandOptionChoice[]} [choices] The choices of the option for the user to pick from
533
+ * @property {ApplicationCommandOption[]} [options] Additional options if this option is a subcommand (group)
534
+ * @property {ChannelType[]} [channelTypes] When the option type is channel,
535
+ * the allowed types of channels that can be selected
536
+ * @property {number} [minValue] The minimum value for an `INTEGER` or `NUMBER` option
537
+ * @property {number} [maxValue] The maximum value for an `INTEGER` or `NUMBER` option
538
+ * @property {number} [minLength] The minimum length for a `STRING` option
539
+ * (maximum of `6000`)
540
+ * @property {number} [maxLength] The maximum length for a `STRING` option
541
+ * (maximum of `6000`)
542
+ */
543
+
544
+ /**
545
+ * A choice for an application command option.
546
+ * @typedef {Object} ApplicationCommandOptionChoice
547
+ * @property {string} name The name of the choice
548
+ * @property {?string} nameLocalized The localized name of the choice in the provided locale, if any
549
+ * @property {?Object<string, string>} [nameLocalizations] The localized names for this choice
550
+ * @property {string|number} value The value of the choice
551
+ */
552
+
553
+ /**
554
+ * Transforms an {@link ApplicationCommandOptionData} object into something that can be used with the API.
555
+ * @param {ApplicationCommandOptionData|ApplicationCommandOption} option The option to transform
556
+ * @param {boolean} [received] Whether this option has been received from Discord
557
+ * @returns {APIApplicationCommandOption}
558
+ * @private
559
+ */
560
+ static transformOption(option, received) {
561
+ const stringType = typeof option.type === 'string' ? option.type : ApplicationCommandOptionTypes[option.type];
562
+ const channelTypesKey = received ? 'channelTypes' : 'channel_types';
563
+ const minValueKey = received ? 'minValue' : 'min_value';
564
+ const maxValueKey = received ? 'maxValue' : 'max_value';
565
+ const minLengthKey = received ? 'minLength' : 'min_length';
566
+ const maxLengthKey = received ? 'maxLength' : 'max_length';
567
+ const nameLocalizationsKey = received ? 'nameLocalizations' : 'name_localizations';
568
+ const nameLocalizedKey = received ? 'nameLocalized' : 'name_localized';
569
+ const descriptionLocalizationsKey = received ? 'descriptionLocalizations' : 'description_localizations';
570
+ const descriptionLocalizedKey = received ? 'descriptionLocalized' : 'description_localized';
571
+ return {
572
+ type: typeof option.type === 'number' && !received ? option.type : ApplicationCommandOptionTypes[option.type],
573
+ name: option.name,
574
+ [nameLocalizationsKey]: option.nameLocalizations ?? option.name_localizations,
575
+ [nameLocalizedKey]: option.nameLocalized ?? option.name_localized,
576
+ description: option.description,
577
+ [descriptionLocalizationsKey]: option.descriptionLocalizations ?? option.description_localizations,
578
+ [descriptionLocalizedKey]: option.descriptionLocalized ?? option.description_localized,
579
+ required:
580
+ option.required ?? (stringType === 'SUB_COMMAND' || stringType === 'SUB_COMMAND_GROUP' ? undefined : false),
581
+ autocomplete: option.autocomplete,
582
+ choices: option.choices?.map(choice => ({
583
+ name: choice.name,
584
+ [nameLocalizedKey]: choice.nameLocalized ?? choice.name_localized,
585
+ [nameLocalizationsKey]: choice.nameLocalizations ?? choice.name_localizations,
586
+ value: choice.value,
587
+ })),
588
+ options: option.options?.map(o => this.transformOption(o, received)),
589
+ [channelTypesKey]: received
590
+ ? option.channel_types?.map(type => ChannelTypes[type])
591
+ : option.channelTypes?.map(type => (typeof type === 'string' ? ChannelTypes[type] : type)) ??
592
+ // When transforming to API data, accept API data
593
+ option.channel_types,
594
+ [minValueKey]: option.minValue ?? option.min_value,
595
+ [maxValueKey]: option.maxValue ?? option.max_value,
596
+ [minLengthKey]: option.minLength ?? option.min_length,
597
+ [maxLengthKey]: option.maxLength ?? option.max_length,
598
+ };
599
+ }
600
+ /**
601
+ * Send Slash command to channel
602
+ * @param {Message} message Discord Message
603
+ * @param {Array<string>} subCommandArray SubCommand Array
604
+ * @param {Array<any>} options The options to Slash Command
605
+ * @returns {Promise<InteractionResponse>}
606
+ */
607
+ // eslint-disable-next-line consistent-return
608
+ async sendSlashCommand(message, subCommandArray = [], options = []) {
609
+ // Todo: Refactor [Done]
610
+ const buildError = (type, value, array, msg) =>
611
+ new Error(`Invalid ${type}: ${value} ${msg}\nList of ${type}:\n${array}`);
612
+ // Check Options
613
+ if (!(message instanceof Message())) {
614
+ throw new TypeError('The message must be a Discord.Message');
615
+ }
616
+ if (!Array.isArray(options)) {
617
+ throw new TypeError('The options must be an array of strings');
618
+ }
619
+ if (this.type !== 'CHAT_INPUT') throw new Error('This command is not a chat input [/]');
620
+ const optionFormat = [];
621
+ const attachments = [];
622
+ const attachmentsBuffer = [];
623
+ const parseChoices = (list_choices, value) => {
624
+ if (value !== undefined) {
625
+ if (Array.isArray(list_choices) && list_choices.length) {
626
+ const choice = list_choices.find(c => c.name === value) || list_choices.find(c => c.value === value);
627
+ if (choice) {
628
+ return choice.value;
629
+ }
630
+ throw buildError(
631
+ 'choice',
632
+ value,
633
+ list_choices.map((c, i) => ` #${i + 1} Name: ${c.name} Value: ${c.value}`).join('\n'),
634
+ 'is not a valid choice for this option',
635
+ );
636
+ } else {
637
+ return value;
638
+ }
639
+ } else {
640
+ return undefined;
641
+ }
642
+ };
643
+ const parseOption = async (optionCommand, value) => {
644
+ const data = {
645
+ type: ApplicationCommandOptionTypes[optionCommand.type],
646
+ name: optionCommand.name,
647
+ };
648
+ if (value !== undefined) {
649
+ value = parseChoices(optionCommand.choices, value);
650
+ switch (optionCommand.type) {
651
+ case 'BOOLEAN': {
652
+ data.value = Boolean(value);
653
+ break;
654
+ }
655
+ case 'INTEGER': {
656
+ data.value = Number(value);
657
+ break;
658
+ }
659
+ case 'ATTACHMENT': {
660
+ data.value = await addDataFromAttachment(value, this.client);
661
+ break;
662
+ }
663
+ case 'SUB_COMMAND_GROUP': {
664
+ break;
665
+ }
666
+ default: {
667
+ if (optionCommand.autocomplete) {
668
+ let optionsBuild;
669
+ switch (subCommandArray.length) {
670
+ case 0: {
671
+ optionsBuild = [
672
+ ...optionFormat,
673
+ {
674
+ type: ApplicationCommandOptionTypes[optionCommand.type],
675
+ name: optionCommand.name,
676
+ value,
677
+ focused: true,
678
+ },
679
+ ];
680
+ break;
681
+ }
682
+ case 1: {
683
+ const subCommand = this.options.find(o => o.name == subCommandArray[0] && o.type == 'SUB_COMMAND');
684
+ optionsBuild = [
685
+ {
686
+ type: ApplicationCommandOptionTypes[subCommand.type],
687
+ name: subCommand.name,
688
+ options: [
689
+ ...optionFormat,
690
+ {
691
+ type: ApplicationCommandOptionTypes[optionCommand.type],
692
+ name: optionCommand.name,
693
+ value,
694
+ focused: true,
695
+ },
696
+ ],
697
+ },
698
+ ];
699
+ break;
700
+ }
701
+ case 2: {
702
+ const subGroup = this.options.find(
703
+ o => o.name == subCommandArray[0] && o.type == 'SUB_COMMAND_GROUP',
704
+ );
705
+ const subCommand = subGroup.options.find(
706
+ o => o.name == subCommandArray[1] && o.type == 'SUB_COMMAND',
707
+ );
708
+ optionsBuild = [
709
+ {
710
+ type: ApplicationCommandOptionTypes[subGroup.type],
711
+ name: subGroup.name,
712
+ options: [
713
+ {
714
+ type: ApplicationCommandOptionTypes[subCommand.type],
715
+ name: subCommand.name,
716
+ options: [
717
+ ...optionFormat,
718
+ {
719
+ type: ApplicationCommandOptionTypes[optionCommand.type],
720
+ name: optionCommand.name,
721
+ value,
722
+ focused: true,
723
+ },
724
+ ],
725
+ },
726
+ ],
727
+ },
728
+ ];
729
+ break;
730
+ }
731
+ }
732
+ const autoValue = await getAutoResponse(optionsBuild, value);
733
+ data.value = autoValue;
734
+ } else {
735
+ data.value = value;
736
+ }
737
+ }
738
+ }
739
+ optionFormat.push(data);
740
+ }
741
+ return optionFormat;
742
+ };
743
+ const parseSubCommand = async (subCommandName, options, subGroup) => {
744
+ const options_sub = subGroup ? subGroup.options : this.options;
745
+ const subCommand = options_sub.find(
746
+ o => (o.name == subCommandName || o.nameLocalized == subCommandName) && o.type == 'SUB_COMMAND',
747
+ );
748
+ if (!subCommand) {
749
+ throw buildError(
750
+ 'SubCommand',
751
+ subCommandName,
752
+ options_sub.map((o, i) => ` #${i + 1} Name: ${o.name}`).join('\n'),
753
+ 'is not a valid sub command',
754
+ );
755
+ }
756
+ const valueRequired = subCommand.options?.filter(o => o.required).length || 0;
757
+ for (let i = 0; i < options.length; i++) {
758
+ const optionInput = subCommand.options[i];
759
+ const value = options[i];
760
+ await parseOption(optionInput, value);
761
+ }
762
+ if (valueRequired > options.length) {
763
+ throw new Error(`Value required missing\nDebug:
764
+ Required: ${valueRequired} - Options: ${optionFormat.length}`);
765
+ }
766
+ return {
767
+ type: ApplicationCommandOptionTypes[subCommand.type],
768
+ name: subCommand.name,
769
+ options: optionFormat,
770
+ };
771
+ };
772
+ const parseSubGroupCommand = async (subGroupName, subName) => {
773
+ const subGroup = this.options.find(
774
+ o => (o.name == subGroupName || o.nameLocalized == subGroupName) && o.type == 'SUB_COMMAND_GROUP',
775
+ );
776
+ if (!subGroup) {
777
+ throw buildError(
778
+ 'SubGroupCommand',
779
+ subGroupName,
780
+ this.options.map((o, i) => ` #${i + 1} Name: ${o.name}`).join('\n'),
781
+ 'is not a valid sub group command',
782
+ );
783
+ }
784
+ const data = await parseSubCommand(subName, options, subGroup);
785
+ return {
786
+ type: ApplicationCommandOptionTypes[subGroup.type],
787
+ name: subGroup.name,
788
+ options: [data],
789
+ };
790
+ };
791
+ async function addDataFromAttachment(data, client) {
792
+ const data_ = await MessagePayload.resolveFile(data);
793
+ if (!data_.file) {
794
+ throw new TypeError(
795
+ 'The attachment data must be a BufferResolvable or Stream or FileOptions of MessageAttachment',
796
+ );
797
+ }
798
+ if (client.options.usingNewAttachmentAPI === true) {
799
+ const attachments_ = await getAttachments(client, message.channelId, data_);
800
+ await uploadFile(data_.file, attachments_[0].upload_url);
801
+ const id = attachments.length;
802
+ attachments.push({
803
+ id: id,
804
+ filename: data_.name,
805
+ uploaded_filename: attachments_[0].upload_filename,
806
+ });
807
+ return id;
808
+ } else {
809
+ const id = attachments.length;
810
+ attachments.push({
811
+ id: id,
812
+ filename: data_.name,
813
+ });
814
+ attachmentsBuffer.push(data_);
815
+ return id;
816
+ }
817
+ }
818
+ const getDataPost = (dataAdd = [], nonce, autocomplete = false) => {
819
+ if (!Array.isArray(dataAdd) && typeof dataAdd == 'object') {
820
+ dataAdd = [dataAdd];
821
+ }
822
+ const data = {
823
+ type: autocomplete ? InteractionTypes.APPLICATION_COMMAND_AUTOCOMPLETE : InteractionTypes.APPLICATION_COMMAND,
824
+ application_id: this.applicationId,
825
+ guild_id: message.guildId,
826
+ channel_id: message.channelId,
827
+ session_id: this.client.session_id,
828
+ data: {
829
+ version: this.version,
830
+ id: this.id,
831
+ name: this.name,
832
+ type: ApplicationCommandTypes[this.type],
833
+ options: dataAdd,
834
+ attachments: attachments,
835
+ },
836
+ nonce,
837
+ };
838
+ if (this.guildId) {
839
+ data.data.guild_id = message.guildId;
840
+ }
841
+ return data;
842
+ };
843
+ const getAutoResponse = async (sendData, value) => {
844
+ let nonce = SnowflakeUtil.generate();
845
+ const data = getDataPost(sendData, nonce, true);
846
+ await this.client.api.interactions.post({
847
+ data,
848
+ files: attachmentsBuffer,
849
+ });
850
+ return new Promise(resolve => {
851
+ const handler = data => {
852
+ timeout.refresh();
853
+ if (data.nonce !== nonce) return;
854
+ clearTimeout(timeout);
855
+ this.client.removeListener(Events.APPLICATION_COMMAND_AUTOCOMPLETE_RESPONSE, handler);
856
+ this.client.decrementMaxListeners();
857
+ if (data.choices.length > 1) {
858
+ // Find best match name
859
+ const bestMatch = findBestMatch(
860
+ value,
861
+ data.choices.map(c => c.name),
862
+ );
863
+ const result = data.choices.find(c => c.name == bestMatch.bestMatch.target);
864
+ resolve(result.value);
865
+ } else {
866
+ resolve(value);
867
+ }
868
+ };
869
+ const timeout = setTimeout(() => {
870
+ this.client.removeListener(Events.APPLICATION_COMMAND_AUTOCOMPLETE_RESPONSE, handler);
871
+ this.client.decrementMaxListeners();
872
+ resolve(value);
873
+ }, this.client.options.interactionTimeout).unref();
874
+ this.client.incrementMaxListeners();
875
+ this.client.on(Events.APPLICATION_COMMAND_AUTOCOMPLETE_RESPONSE, handler);
876
+ });
877
+ };
878
+ const sendData = async (optionsData = []) => {
879
+ let nonce = SnowflakeUtil.generate();
880
+ const data = getDataPost(optionsData, nonce);
881
+ await this.client.api.interactions.post({
882
+ body: data,
883
+ files: attachmentsBuffer,
884
+ });
885
+ this.client._interactionCache.set(nonce, {
886
+ channelId: message.channelId,
887
+ guildId: message.guildId,
888
+ metadata: data,
889
+ });
890
+ return new Promise((resolve, reject) => {
891
+ const handler = data => {
892
+ timeout.refresh();
893
+ if (data.metadata.nonce !== nonce) return;
894
+ clearTimeout(timeout);
895
+ this.client.removeListener('interactionResponse', handler);
896
+ this.client.decrementMaxListeners();
897
+ if (data.status) {
898
+ resolve(data.metadata);
899
+ } else {
900
+ reject(
901
+ new Error('INTERACTION_ERROR', {
902
+ cause: data,
903
+ }),
904
+ );
905
+ }
906
+ };
907
+ const timeout = setTimeout(() => {
908
+ this.client.removeListener('interactionResponse', handler);
909
+ this.client.decrementMaxListeners();
910
+ reject(
911
+ new Error('INTERACTION_TIMEOUT', {
912
+ cause: data,
913
+ }),
914
+ );
915
+ }, this.client.options.interactionTimeout).unref();
916
+ this.client.incrementMaxListeners();
917
+ this.client.on('interactionResponse', handler);
918
+ });
919
+ };
920
+ // SubCommandArray length max 2
921
+ // length = 0 => no sub command
922
+ // length = 1 => sub command
923
+ // length = 2 => sub command group + sub command
924
+ switch (subCommandArray.length) {
925
+ case 0: {
926
+ const valueRequired = this.options?.filter(o => o.required).length || 0;
927
+ for (let i = 0; i < options.length; i++) {
928
+ const optionInput = this.options[i];
929
+ const value = options[i];
930
+ await parseOption(optionInput, value);
931
+ }
932
+ if (valueRequired > options.length) {
933
+ throw new Error(`Value required missing\nDebug:
934
+ Required: ${valueRequired} - Options: ${optionFormat.length}`);
935
+ }
936
+ return sendData(optionFormat);
937
+ }
938
+ case 1: {
939
+ const optionsData = await parseSubCommand(subCommandArray[0], options);
940
+ return sendData(optionsData);
941
+ }
942
+ case 2: {
943
+ const optionsData = await parseSubGroupCommand(subCommandArray[0], subCommandArray[1], options);
944
+ return sendData(optionsData);
945
+ }
946
+ }
947
+ }
948
+ /**
949
+ * Message Context Menu
950
+ * @param {Message} message Discord Message
951
+ * @returns {Promise<InteractionResponse>}
952
+ */
953
+ async sendContextMenu(message) {
954
+ if (!(message instanceof Message())) {
955
+ throw new TypeError('The message must be a Discord.Message');
956
+ }
957
+ if (this.type == 'CHAT_INPUT') return false;
958
+ const nonce = SnowflakeUtil.generate();
959
+ const data = {
960
+ type: InteractionTypes.APPLICATION_COMMAND,
961
+ application_id: this.applicationId,
962
+ guild_id: message.guildId,
963
+ channel_id: message.channelId,
964
+ session_id: this.client.session_id,
965
+ data: {
966
+ version: this.version,
967
+ id: this.id,
968
+ name: this.name,
969
+ type: ApplicationCommandTypes[this.type],
970
+ target_id: ApplicationCommandTypes[this.type] == 1 ? message.author.id : message.id,
971
+ },
972
+ nonce,
973
+ };
974
+ if (this.guildId) {
975
+ data.data.guild_id = message.guildId;
976
+ }
977
+ await this.client.api.interactions.post({
978
+ body: data,
979
+ });
980
+ this.client._interactionCache.set(nonce, {
981
+ channelId: message.channelId,
982
+ guildId: message.guildId,
983
+ metadata: data,
984
+ });
985
+ return new Promise((resolve, reject) => {
986
+ const handler = data => {
987
+ timeout.refresh();
988
+ if (data.metadata.nonce !== nonce) return;
989
+ clearTimeout(timeout);
990
+ this.client.removeListener('interactionResponse', handler);
991
+ this.client.decrementMaxListeners();
992
+ if (data.status) {
993
+ resolve(data.metadata);
994
+ } else {
995
+ reject(
996
+ new Error('INTERACTION_ERROR', {
997
+ cause: data,
998
+ }),
999
+ );
1000
+ }
1001
+ };
1002
+ const timeout = setTimeout(() => {
1003
+ this.client.removeListener('interactionResponse', handler);
1004
+ this.client.decrementMaxListeners();
1005
+ reject(
1006
+ new Error('INTERACTION_TIMEOUT', {
1007
+ cause: data,
1008
+ }),
1009
+ );
1010
+ }, this.client.options.interactionTimeout).unref();
1011
+ this.client.incrementMaxListeners();
1012
+ this.client.on('interactionResponse', handler);
1013
+ });
1014
+ }
1015
+ }
1016
+
1017
+ module.exports = ApplicationCommand;
1018
+
1019
+ /* eslint-disable max-len */
1020
+ /**
1021
+ * @external APIApplicationCommand
1022
+ * @see {@link https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-structure}
1023
+ */
1024
+
1025
+ /**
1026
+ * @external APIApplicationCommandOption
1027
+ * @see {@link https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-option-structure}
1028
+ */