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.
- package/LICENSE +674 -0
- package/README.md +119 -5
- package/package.json +101 -6
- package/src/WebSocket.js +39 -0
- package/src/client/BaseClient.js +87 -0
- package/src/client/Client.js +1154 -0
- package/src/client/WebhookClient.js +61 -0
- package/src/client/actions/Action.js +115 -0
- package/src/client/actions/ActionsManager.js +72 -0
- package/src/client/actions/ApplicationCommandPermissionsUpdate.js +34 -0
- package/src/client/actions/AutoModerationActionExecution.js +26 -0
- package/src/client/actions/AutoModerationRuleCreate.js +27 -0
- package/src/client/actions/AutoModerationRuleDelete.js +31 -0
- package/src/client/actions/AutoModerationRuleUpdate.js +29 -0
- package/src/client/actions/ChannelCreate.js +23 -0
- package/src/client/actions/ChannelDelete.js +39 -0
- package/src/client/actions/ChannelUpdate.js +34 -0
- package/src/client/actions/GuildAuditLogEntryCreate.js +29 -0
- package/src/client/actions/GuildBanAdd.js +20 -0
- package/src/client/actions/GuildBanRemove.js +25 -0
- package/src/client/actions/GuildChannelsPositionUpdate.js +21 -0
- package/src/client/actions/GuildDelete.js +65 -0
- package/src/client/actions/GuildEmojiCreate.js +20 -0
- package/src/client/actions/GuildEmojiDelete.js +21 -0
- package/src/client/actions/GuildEmojiUpdate.js +20 -0
- package/src/client/actions/GuildEmojisUpdate.js +34 -0
- package/src/client/actions/GuildIntegrationsUpdate.js +19 -0
- package/src/client/actions/GuildMemberRemove.js +33 -0
- package/src/client/actions/GuildMemberUpdate.js +44 -0
- package/src/client/actions/GuildRoleCreate.js +25 -0
- package/src/client/actions/GuildRoleDelete.js +31 -0
- package/src/client/actions/GuildRoleUpdate.js +39 -0
- package/src/client/actions/GuildRolesPositionUpdate.js +21 -0
- package/src/client/actions/GuildScheduledEventCreate.js +27 -0
- package/src/client/actions/GuildScheduledEventDelete.js +31 -0
- package/src/client/actions/GuildScheduledEventUpdate.js +30 -0
- package/src/client/actions/GuildScheduledEventUserAdd.js +32 -0
- package/src/client/actions/GuildScheduledEventUserRemove.js +32 -0
- package/src/client/actions/GuildStickerCreate.js +20 -0
- package/src/client/actions/GuildStickerDelete.js +21 -0
- package/src/client/actions/GuildStickerUpdate.js +20 -0
- package/src/client/actions/GuildStickersUpdate.js +34 -0
- package/src/client/actions/GuildUpdate.js +33 -0
- package/src/client/actions/InteractionCreate.js +115 -0
- package/src/client/actions/InviteCreate.js +28 -0
- package/src/client/actions/InviteDelete.js +30 -0
- package/src/client/actions/MessageCreate.js +50 -0
- package/src/client/actions/MessageDelete.js +32 -0
- package/src/client/actions/MessageDeleteBulk.js +46 -0
- package/src/client/actions/MessageReactionAdd.js +56 -0
- package/src/client/actions/MessageReactionRemove.js +45 -0
- package/src/client/actions/MessageReactionRemoveAll.js +33 -0
- package/src/client/actions/MessageReactionRemoveEmoji.js +28 -0
- package/src/client/actions/MessageUpdate.js +26 -0
- package/src/client/actions/PresenceUpdate.js +45 -0
- package/src/client/actions/StageInstanceCreate.js +28 -0
- package/src/client/actions/StageInstanceDelete.js +33 -0
- package/src/client/actions/StageInstanceUpdate.js +30 -0
- package/src/client/actions/ThreadCreate.js +24 -0
- package/src/client/actions/ThreadDelete.js +32 -0
- package/src/client/actions/ThreadListSync.js +59 -0
- package/src/client/actions/ThreadMemberUpdate.js +30 -0
- package/src/client/actions/ThreadMembersUpdate.js +34 -0
- package/src/client/actions/TypingStart.js +29 -0
- package/src/client/actions/UserUpdate.js +35 -0
- package/src/client/actions/VoiceStateUpdate.js +57 -0
- package/src/client/actions/WebhooksUpdate.js +20 -0
- package/src/client/voice/ClientVoiceManager.js +51 -0
- package/src/client/websocket/WebSocketManager.js +412 -0
- package/src/client/websocket/WebSocketShard.js +908 -0
- package/src/client/websocket/handlers/APPLICATION_COMMAND_AUTOCOMPLETE_RESPONSE.js +23 -0
- package/src/client/websocket/handlers/APPLICATION_COMMAND_CREATE.js +18 -0
- package/src/client/websocket/handlers/APPLICATION_COMMAND_DELETE.js +20 -0
- package/src/client/websocket/handlers/APPLICATION_COMMAND_PERMISSIONS_UPDATE.js +5 -0
- package/src/client/websocket/handlers/APPLICATION_COMMAND_UPDATE.js +20 -0
- package/src/client/websocket/handlers/AUTO_MODERATION_ACTION_EXECUTION.js +5 -0
- package/src/client/websocket/handlers/AUTO_MODERATION_RULE_CREATE.js +5 -0
- package/src/client/websocket/handlers/AUTO_MODERATION_RULE_DELETE.js +5 -0
- package/src/client/websocket/handlers/AUTO_MODERATION_RULE_UPDATE.js +5 -0
- package/src/client/websocket/handlers/CALL_CREATE.js +14 -0
- package/src/client/websocket/handlers/CALL_DELETE.js +11 -0
- package/src/client/websocket/handlers/CALL_UPDATE.js +11 -0
- package/src/client/websocket/handlers/CHANNEL_CREATE.js +5 -0
- package/src/client/websocket/handlers/CHANNEL_DELETE.js +5 -0
- package/src/client/websocket/handlers/CHANNEL_PINS_UPDATE.js +22 -0
- package/src/client/websocket/handlers/CHANNEL_RECIPIENT_ADD.js +16 -0
- package/src/client/websocket/handlers/CHANNEL_RECIPIENT_REMOVE.js +16 -0
- package/src/client/websocket/handlers/CHANNEL_UPDATE.js +16 -0
- package/src/client/websocket/handlers/GUILD_APPLICATION_COMMANDS_UPDATE.js +11 -0
- package/src/client/websocket/handlers/GUILD_AUDIT_LOG_ENTRY_CREATE.js +5 -0
- package/src/client/websocket/handlers/GUILD_BAN_ADD.js +5 -0
- package/src/client/websocket/handlers/GUILD_BAN_REMOVE.js +5 -0
- package/src/client/websocket/handlers/GUILD_CREATE.js +46 -0
- package/src/client/websocket/handlers/GUILD_DELETE.js +5 -0
- package/src/client/websocket/handlers/GUILD_EMOJIS_UPDATE.js +5 -0
- package/src/client/websocket/handlers/GUILD_INTEGRATIONS_UPDATE.js +5 -0
- package/src/client/websocket/handlers/GUILD_MEMBERS_CHUNK.js +39 -0
- package/src/client/websocket/handlers/GUILD_MEMBER_ADD.js +20 -0
- package/src/client/websocket/handlers/GUILD_MEMBER_LIST_UPDATE.js +55 -0
- package/src/client/websocket/handlers/GUILD_MEMBER_REMOVE.js +5 -0
- package/src/client/websocket/handlers/GUILD_MEMBER_UPDATE.js +5 -0
- package/src/client/websocket/handlers/GUILD_ROLE_CREATE.js +5 -0
- package/src/client/websocket/handlers/GUILD_ROLE_DELETE.js +5 -0
- package/src/client/websocket/handlers/GUILD_ROLE_UPDATE.js +5 -0
- package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_CREATE.js +5 -0
- package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_DELETE.js +5 -0
- package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_UPDATE.js +5 -0
- package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_ADD.js +5 -0
- package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_REMOVE.js +5 -0
- package/src/client/websocket/handlers/GUILD_STICKERS_UPDATE.js +5 -0
- package/src/client/websocket/handlers/GUILD_UPDATE.js +5 -0
- package/src/client/websocket/handlers/INTERACTION_CREATE.js +16 -0
- package/src/client/websocket/handlers/INTERACTION_FAILURE.js +18 -0
- package/src/client/websocket/handlers/INTERACTION_MODAL_CREATE.js +11 -0
- package/src/client/websocket/handlers/INTERACTION_SUCCESS.js +30 -0
- package/src/client/websocket/handlers/INVITE_CREATE.js +5 -0
- package/src/client/websocket/handlers/INVITE_DELETE.js +5 -0
- package/src/client/websocket/handlers/MESSAGE_ACK.js +16 -0
- package/src/client/websocket/handlers/MESSAGE_CREATE.js +5 -0
- package/src/client/websocket/handlers/MESSAGE_DELETE.js +5 -0
- package/src/client/websocket/handlers/MESSAGE_DELETE_BULK.js +5 -0
- package/src/client/websocket/handlers/MESSAGE_REACTION_ADD.js +5 -0
- package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE.js +5 -0
- package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_ALL.js +5 -0
- package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_EMOJI.js +5 -0
- package/src/client/websocket/handlers/MESSAGE_UPDATE.js +16 -0
- package/src/client/websocket/handlers/PRESENCE_UPDATE.js +5 -0
- package/src/client/websocket/handlers/READY.js +172 -0
- package/src/client/websocket/handlers/RELATIONSHIP_ADD.js +17 -0
- package/src/client/websocket/handlers/RELATIONSHIP_REMOVE.js +15 -0
- package/src/client/websocket/handlers/RELATIONSHIP_UPDATE.js +18 -0
- package/src/client/websocket/handlers/RESUMED.js +14 -0
- package/src/client/websocket/handlers/STAGE_INSTANCE_CREATE.js +5 -0
- package/src/client/websocket/handlers/STAGE_INSTANCE_DELETE.js +5 -0
- package/src/client/websocket/handlers/STAGE_INSTANCE_UPDATE.js +5 -0
- package/src/client/websocket/handlers/THREAD_CREATE.js +5 -0
- package/src/client/websocket/handlers/THREAD_DELETE.js +5 -0
- package/src/client/websocket/handlers/THREAD_LIST_SYNC.js +5 -0
- package/src/client/websocket/handlers/THREAD_MEMBERS_UPDATE.js +5 -0
- package/src/client/websocket/handlers/THREAD_MEMBER_UPDATE.js +5 -0
- package/src/client/websocket/handlers/THREAD_UPDATE.js +16 -0
- package/src/client/websocket/handlers/TYPING_START.js +5 -0
- package/src/client/websocket/handlers/USER_GUILD_SETTINGS_UPDATE.js +12 -0
- package/src/client/websocket/handlers/USER_NOTE_UPDATE.js +5 -0
- package/src/client/websocket/handlers/USER_SETTINGS_UPDATE.js +9 -0
- package/src/client/websocket/handlers/USER_UPDATE.js +5 -0
- package/src/client/websocket/handlers/VOICE_SERVER_UPDATE.js +6 -0
- package/src/client/websocket/handlers/VOICE_STATE_UPDATE.js +5 -0
- package/src/client/websocket/handlers/WEBHOOKS_UPDATE.js +5 -0
- package/src/client/websocket/handlers/index.js +86 -0
- package/src/errors/DJSError.js +61 -0
- package/src/errors/Messages.js +227 -0
- package/src/errors/index.js +4 -0
- package/src/index.js +190 -0
- package/src/main.js +42 -0
- package/src/managers/ApplicationCommandManager.js +267 -0
- package/src/managers/ApplicationCommandPermissionsManager.js +425 -0
- package/src/managers/AutoModerationRuleManager.js +296 -0
- package/src/managers/BaseGuildEmojiManager.js +80 -0
- package/src/managers/BaseManager.js +19 -0
- package/src/managers/BillingManager.js +66 -0
- package/src/managers/CachedManager.js +71 -0
- package/src/managers/ChannelManager.js +139 -0
- package/src/managers/ClientUserSettingManager.js +490 -0
- package/src/managers/DataManager.js +61 -0
- package/src/managers/DeveloperPortalManager.js +104 -0
- package/src/managers/GuildApplicationCommandManager.js +28 -0
- package/src/managers/GuildBanManager.js +204 -0
- package/src/managers/GuildChannelManager.js +502 -0
- package/src/managers/GuildEmojiManager.js +171 -0
- package/src/managers/GuildEmojiRoleManager.js +118 -0
- package/src/managers/GuildFolderManager.js +24 -0
- package/src/managers/GuildForumThreadManager.js +114 -0
- package/src/managers/GuildInviteManager.js +213 -0
- package/src/managers/GuildManager.js +304 -0
- package/src/managers/GuildMemberManager.js +724 -0
- package/src/managers/GuildMemberRoleManager.js +191 -0
- package/src/managers/GuildScheduledEventManager.js +296 -0
- package/src/managers/GuildSettingManager.js +148 -0
- package/src/managers/GuildStickerManager.js +179 -0
- package/src/managers/GuildTextThreadManager.js +98 -0
- package/src/managers/InteractionManager.js +39 -0
- package/src/managers/MessageManager.js +393 -0
- package/src/managers/PermissionOverwriteManager.js +166 -0
- package/src/managers/PresenceManager.js +58 -0
- package/src/managers/ReactionManager.js +67 -0
- package/src/managers/ReactionUserManager.js +71 -0
- package/src/managers/RelationshipManager.js +258 -0
- package/src/managers/RoleManager.js +352 -0
- package/src/managers/SessionManager.js +57 -0
- package/src/managers/StageInstanceManager.js +162 -0
- package/src/managers/ThreadManager.js +207 -0
- package/src/managers/ThreadMemberManager.js +186 -0
- package/src/managers/UserManager.js +150 -0
- package/src/managers/VoiceStateManager.js +37 -0
- package/src/rest/APIRequest.js +136 -0
- package/src/rest/APIRouter.js +53 -0
- package/src/rest/CaptchaSolver.js +78 -0
- package/src/rest/DiscordAPIError.js +103 -0
- package/src/rest/HTTPError.js +62 -0
- package/src/rest/RESTManager.js +81 -0
- package/src/rest/RateLimitError.js +55 -0
- package/src/rest/RequestHandler.js +446 -0
- package/src/sharding/Shard.js +443 -0
- package/src/sharding/ShardClientUtil.js +275 -0
- package/src/sharding/ShardingManager.js +318 -0
- package/src/structures/AnonymousGuild.js +98 -0
- package/src/structures/ApplicationCommand.js +1028 -0
- package/src/structures/ApplicationRoleConnectionMetadata.js +45 -0
- package/src/structures/AutoModerationActionExecution.js +89 -0
- package/src/structures/AutoModerationRule.js +294 -0
- package/src/structures/AutocompleteInteraction.js +106 -0
- package/src/structures/Base.js +43 -0
- package/src/structures/BaseCommandInteraction.js +211 -0
- package/src/structures/BaseGuild.js +116 -0
- package/src/structures/BaseGuildEmoji.js +56 -0
- package/src/structures/BaseGuildTextChannel.js +193 -0
- package/src/structures/BaseGuildVoiceChannel.js +243 -0
- package/src/structures/BaseMessageComponent.js +114 -0
- package/src/structures/ButtonInteraction.js +11 -0
- package/src/structures/Call.js +58 -0
- package/src/structures/CategoryChannel.js +83 -0
- package/src/structures/Channel.js +271 -0
- package/src/structures/ClientApplication.js +204 -0
- package/src/structures/ClientPresence.js +84 -0
- package/src/structures/ClientUser.js +624 -0
- package/src/structures/CommandInteraction.js +41 -0
- package/src/structures/CommandInteractionOptionResolver.js +276 -0
- package/src/structures/ContextMenuInteraction.js +65 -0
- package/src/structures/DMChannel.js +280 -0
- package/src/structures/DeveloperPortalApplication.js +520 -0
- package/src/structures/DirectoryChannel.js +20 -0
- package/src/structures/Emoji.js +148 -0
- package/src/structures/ForumChannel.js +271 -0
- package/src/structures/Guild.js +1744 -0
- package/src/structures/GuildAuditLogs.js +734 -0
- package/src/structures/GuildBan.js +59 -0
- package/src/structures/GuildBoost.js +108 -0
- package/src/structures/GuildChannel.js +454 -0
- package/src/structures/GuildEmoji.js +161 -0
- package/src/structures/GuildFolder.js +75 -0
- package/src/structures/GuildMember.js +686 -0
- package/src/structures/GuildPreview.js +191 -0
- package/src/structures/GuildPreviewEmoji.js +27 -0
- package/src/structures/GuildScheduledEvent.js +441 -0
- package/src/structures/GuildTemplate.js +236 -0
- package/src/structures/Integration.js +188 -0
- package/src/structures/IntegrationApplication.js +96 -0
- package/src/structures/Interaction.js +351 -0
- package/src/structures/InteractionCollector.js +248 -0
- package/src/structures/InteractionResponse.js +114 -0
- package/src/structures/InteractionWebhook.js +43 -0
- package/src/structures/Invite.js +375 -0
- package/src/structures/InviteGuild.js +23 -0
- package/src/structures/InviteStageInstance.js +86 -0
- package/src/structures/Message.js +1188 -0
- package/src/structures/MessageActionRow.js +103 -0
- package/src/structures/MessageAttachment.js +193 -0
- package/src/structures/MessageButton.js +231 -0
- package/src/structures/MessageCollector.js +146 -0
- package/src/structures/MessageComponentInteraction.js +120 -0
- package/src/structures/MessageContextMenuInteraction.js +20 -0
- package/src/structures/MessageEmbed.js +586 -0
- package/src/structures/MessageMentions.js +272 -0
- package/src/structures/MessagePayload.js +358 -0
- package/src/structures/MessageReaction.js +171 -0
- package/src/structures/MessageSelectMenu.js +391 -0
- package/src/structures/Modal.js +279 -0
- package/src/structures/ModalSubmitFieldsResolver.js +53 -0
- package/src/structures/ModalSubmitInteraction.js +119 -0
- package/src/structures/NewsChannel.js +32 -0
- package/src/structures/OAuth2Guild.js +28 -0
- package/src/structures/PartialGroupDMChannel.js +430 -0
- package/src/structures/PermissionOverwrites.js +196 -0
- package/src/structures/Presence.js +441 -0
- package/src/structures/ReactionCollector.js +229 -0
- package/src/structures/ReactionEmoji.js +31 -0
- package/src/structures/RichPresence.js +722 -0
- package/src/structures/Role.js +515 -0
- package/src/structures/SelectMenuInteraction.js +170 -0
- package/src/structures/Session.js +81 -0
- package/src/structures/StageChannel.js +104 -0
- package/src/structures/StageInstance.js +208 -0
- package/src/structures/Sticker.js +310 -0
- package/src/structures/StickerPack.js +95 -0
- package/src/structures/StoreChannel.js +56 -0
- package/src/structures/Team.js +167 -0
- package/src/structures/TeamMember.js +71 -0
- package/src/structures/TextChannel.js +33 -0
- package/src/structures/TextInputComponent.js +201 -0
- package/src/structures/ThreadChannel.js +626 -0
- package/src/structures/ThreadMember.js +105 -0
- package/src/structures/Typing.js +74 -0
- package/src/structures/User.js +697 -0
- package/src/structures/UserContextMenuInteraction.js +29 -0
- package/src/structures/VoiceChannel.js +110 -0
- package/src/structures/VoiceRegion.js +53 -0
- package/src/structures/VoiceState.js +306 -0
- package/src/structures/WebEmbed.js +401 -0
- package/src/structures/Webhook.js +461 -0
- package/src/structures/WelcomeChannel.js +60 -0
- package/src/structures/WelcomeScreen.js +48 -0
- package/src/structures/Widget.js +87 -0
- package/src/structures/WidgetMember.js +99 -0
- package/src/structures/interfaces/Application.js +190 -0
- package/src/structures/interfaces/Collector.js +300 -0
- package/src/structures/interfaces/InteractionResponses.js +313 -0
- package/src/structures/interfaces/TextBasedChannel.js +566 -0
- package/src/util/ActivityFlags.js +44 -0
- package/src/util/ApplicationFlags.js +74 -0
- package/src/util/BitField.js +170 -0
- package/src/util/ChannelFlags.js +45 -0
- package/src/util/Constants.js +1917 -0
- package/src/util/DataResolver.js +145 -0
- package/src/util/Formatters.js +214 -0
- package/src/util/GuildMemberFlags.js +43 -0
- package/src/util/Intents.js +74 -0
- package/src/util/LimitedCollection.js +131 -0
- package/src/util/MessageFlags.js +54 -0
- package/src/util/Options.js +360 -0
- package/src/util/Permissions.js +187 -0
- package/src/util/PremiumUsageFlags.js +31 -0
- package/src/util/PurchasedFlags.js +31 -0
- package/src/util/RemoteAuth.js +522 -0
- package/src/util/SnowflakeUtil.js +92 -0
- package/src/util/Sweepers.js +466 -0
- package/src/util/SystemChannelFlags.js +55 -0
- package/src/util/ThreadMemberFlags.js +30 -0
- package/src/util/UserFlags.js +104 -0
- package/src/util/Util.js +741 -0
- package/src/util/Voice.js +1456 -0
- package/src/util/arRPC/index.js +229 -0
- package/src/util/arRPC/process/detectable.json +1 -0
- package/src/util/arRPC/process/index.js +102 -0
- package/src/util/arRPC/process/native/index.js +5 -0
- package/src/util/arRPC/process/native/linux.js +37 -0
- package/src/util/arRPC/process/native/win32.js +25 -0
- package/src/util/arRPC/transports/ipc.js +281 -0
- package/src/util/arRPC/transports/websocket.js +128 -0
- package/typings/enums.d.ts +346 -0
- package/typings/index.d.ts +7725 -0
- package/typings/index.test-d.ts +0 -0
- 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
|
+
*/
|