'use strict'; const Package = (exports.Package = require('../../package.json')); const { Error, RangeError } = require('../errors'); /** * Rate limit data * @typedef {Object} RateLimitData * @property {number} timeout Time until this rate limit ends, in ms * @property {number} limit The maximum amount of requests of this endpoint * @property {string} method The http method of this request * @property {string} path The path of the request relative to the HTTP endpoint * @property {string} route The route of the request relative to the HTTP endpoint * @property {boolean} global Whether this is a global rate limit */ /** * Whether this rate limit should throw an Error * @typedef {Function} RateLimitQueueFilter * @param {RateLimitData} rateLimitData The data of this rate limit * @returns {boolean|Promise} */ /** * Options for a client. * @typedef {Object} ClientOptions * @property {number|number[]|string} [shards] ID of the shard to run, or an array of shard IDs. If not specified, * the client will spawn {@link ClientOptions#shardCount} shards. If set to `auto`, it will fetch the * recommended amount of shards from Discord and spawn that amount * @property {number} [shardCount=1] The total amount of shards used by all processes of this bot * (e.g. recommended shard count, shard count of the ShardingManager) * @property {number} [messageCacheMaxSize=200] Maximum number of messages to cache per channel * (-1 or Infinity for unlimited - don't do this without message sweeping, otherwise memory usage will climb * indefinitely) * @property {number} [messageCacheLifetime=0] How long a message should stay in the cache until it is considered * sweepable (in seconds, 0 for forever) * @property {number} [messageSweepInterval=0] How frequently to remove messages from the cache that are older than * the message cache lifetime (in seconds, 0 for never) * @property {MessageMentionOptions} [allowedMentions] Default value for {@link MessageOptions#allowedMentions} * @property {number} [invalidRequestWarningInterval=0] The number of invalid REST requests (those that return * 401, 403, or 429) in a 10 minute window between emitted warnings (0 for no warnings). That is, if set to 500, * warnings will be emitted at invalid request number 500, 1000, 1500, and so on. * @property {PartialType[]} [partials] Structures allowed to be partial. This means events can be emitted even when * they're missing all the data for a particular structure. See the "Partials" topic listed in the sidebar for some * important usage information, as partials require you to put checks in place when handling data. * @property {number} [restWsBridgeTimeout=5000] Maximum time permitted between REST responses and their * corresponding websocket events * @property {number} [restTimeOffset=500] Extra time in milliseconds to wait before continuing to make REST * requests (higher values will reduce rate-limiting errors on bad connections) * @property {number} [restRequestTimeout=15000] Time to wait before cancelling a REST request, in milliseconds * @property {number} [restSweepInterval=60] How frequently to delete inactive request buckets, in seconds * (or 0 for never) * @property {number} [restGlobalRateLimit=0] How many requests to allow sending per second (0 for unlimited, 50 for * the standard global limit used by Discord) * @property {string[]|RateLimitQueueFilter} [rejectOnRateLimit] Decides how rate limits and pre-emptive throttles * should be handled. If this option is an array containing the prefix of the request route (e.g. /channels to match any * route starting with /channels, such as /channels/222197033908436994/messages) or a function returning true, a * {@link RateLimitError} will be thrown. Otherwise the request will be queued for later * @property {number} [retryLimit=1] How many times to retry on 5XX errors (Infinity for indefinite amount of retries) * @property {PresenceData} [presence={}] Presence data to use upon login * @property {IntentsResolvable} intents Intents to enable for this connection * @property {WebsocketOptions} [ws] Options for the WebSocket * @property {HTTPOptions} [http] HTTP options */ exports.DefaultOptions = { shardCount: 1, messageCacheMaxSize: 200, messageCacheLifetime: 0, messageSweepInterval: 0, invalidRequestWarningInterval: 0, partials: [], restWsBridgeTimeout: 5000, restRequestTimeout: 15000, restGlobalRateLimit: 0, retryLimit: 1, restTimeOffset: 500, restSweepInterval: 60, presence: {}, /** * WebSocket options (these are left as snake_case to match the API) * @typedef {Object} WebsocketOptions * @property {number} [large_threshold=50] Number of members in a guild after which offline users will no longer be * sent in the initial guild member list, must be between 50 and 250 */ ws: { large_threshold: 50, compress: false, properties: { $os: process.platform, $browser: 'discord.js', $device: 'discord.js', }, version: 8, }, /** * HTTP options * @typedef {Object} HTTPOptions * @property {number} [version=8] API version to use * @property {string} [api='https://discord.com/api'] Base url of the API * @property {string} [cdn='https://cdn.discordapp.com'] Base url of the CDN * @property {string} [invite='https://discord.gg'] Base url of invites * @property {string} [template='https://discord.new'] Base url of templates * @property {Object} [headers] Additional headers to send for all API requests */ http: { version: 8, api: 'https://discord.com/api', cdn: 'https://cdn.discordapp.com', invite: 'https://discord.gg', template: 'https://discord.new', }, }; exports.UserAgent = `DiscordBot (${Package.homepage.split('#')[0]}, ${Package.version}) Node.js/${process.version}`; exports.WSCodes = { 1000: 'WS_CLOSE_REQUESTED', 4004: 'TOKEN_INVALID', 4010: 'SHARDING_INVALID', 4011: 'SHARDING_REQUIRED', 4013: 'INVALID_INTENTS', 4014: 'DISALLOWED_INTENTS', }; const AllowedImageFormats = ['webp', 'png', 'jpg', 'jpeg', 'gif']; const AllowedImageSizes = Array.from({ length: 9 }, (e, i) => 2 ** (i + 4)); function makeImageUrl(root, { format = 'webp', size } = {}) { if (format && !AllowedImageFormats.includes(format)) throw new Error('IMAGE_FORMAT', format); if (size && !AllowedImageSizes.includes(size)) throw new RangeError('IMAGE_SIZE', size); return `${root}.${format}${size ? `?size=${size}` : ''}`; } /** * Options for Image URLs. * @typedef {StaticImageURLOptions} ImageURLOptions * @property {boolean} [dynamic] If true, the format will dynamically change to `gif` for * animated avatars; the default is false */ /** * Options for static Image URLs. * @typedef {Object} StaticImageURLOptions * @property {string} [format] One of `webp`, `png`, `jpg`, `jpeg`, `gif`. If no format is provided, * defaults to `webp` * @property {number} [size] One of `16`, `32`, `64`, `128`, `256`, `512`, `1024`, `2048`, `4096` */ exports.Endpoints = { CDN(root) { return { Emoji: (emojiID, format = 'png') => `${root}/emojis/${emojiID}.${format}`, Asset: name => `${root}/assets/${name}`, DefaultAvatar: discriminator => `${root}/embed/avatars/${discriminator}.png`, Avatar: (userID, hash, format = 'webp', size, dynamic = false) => { if (dynamic) format = hash.startsWith('a_') ? 'gif' : format; return makeImageUrl(`${root}/avatars/${userID}/${hash}`, { format, size }); }, Banner: (guildID, hash, format = 'webp', size) => makeImageUrl(`${root}/banners/${guildID}/${hash}`, { format, size }), Icon: (guildID, hash, format = 'webp', size, dynamic = false) => { if (dynamic) format = hash.startsWith('a_') ? 'gif' : format; return makeImageUrl(`${root}/icons/${guildID}/${hash}`, { format, size }); }, AppIcon: (clientID, hash, { format = 'webp', size } = {}) => makeImageUrl(`${root}/app-icons/${clientID}/${hash}`, { size, format }), AppAsset: (clientID, hash, { format = 'webp', size } = {}) => makeImageUrl(`${root}/app-assets/${clientID}/${hash}`, { size, format }), GDMIcon: (channelID, hash, format = 'webp', size) => makeImageUrl(`${root}/channel-icons/${channelID}/${hash}`, { size, format }), Splash: (guildID, hash, format = 'webp', size) => makeImageUrl(`${root}/splashes/${guildID}/${hash}`, { size, format }), DiscoverySplash: (guildID, hash, format = 'webp', size) => makeImageUrl(`${root}/discovery-splashes/${guildID}/${hash}`, { size, format }), TeamIcon: (teamID, hash, { format = 'webp', size } = {}) => makeImageUrl(`${root}/team-icons/${teamID}/${hash}`, { size, format }), }; }, invite: (root, code) => `${root}/${code}`, botGateway: '/gateway/bot', }; /** * The current status of the client. Here are the available statuses: * * READY: 0 * * CONNECTING: 1 * * RECONNECTING: 2 * * IDLE: 3 * * NEARLY: 4 * * DISCONNECTED: 5 * * WAITING_FOR_GUILDS: 6 * * IDENTIFYING: 7 * * RESUMING: 8 * @typedef {number} Status */ exports.Status = { READY: 0, CONNECTING: 1, RECONNECTING: 2, IDLE: 3, NEARLY: 4, DISCONNECTED: 5, WAITING_FOR_GUILDS: 6, IDENTIFYING: 7, RESUMING: 8, }; exports.OPCodes = { DISPATCH: 0, HEARTBEAT: 1, IDENTIFY: 2, STATUS_UPDATE: 3, VOICE_STATE_UPDATE: 4, VOICE_GUILD_PING: 5, RESUME: 6, RECONNECT: 7, REQUEST_GUILD_MEMBERS: 8, INVALID_SESSION: 9, HELLO: 10, HEARTBEAT_ACK: 11, }; exports.Events = { RATE_LIMIT: 'rateLimit', INVALID_REQUEST_WARNING: 'invalidRequestWarning', CLIENT_READY: 'ready', APPLICATION_COMMAND_CREATE: 'applicationCommandCreate', APPLICATION_COMMAND_DELETE: 'applicationCommandDelete', APPLICATION_COMMAND_UPDATE: 'applicationCommandUpdate', GUILD_CREATE: 'guildCreate', GUILD_DELETE: 'guildDelete', GUILD_UPDATE: 'guildUpdate', GUILD_UNAVAILABLE: 'guildUnavailable', GUILD_MEMBER_ADD: 'guildMemberAdd', GUILD_MEMBER_REMOVE: 'guildMemberRemove', GUILD_MEMBER_UPDATE: 'guildMemberUpdate', GUILD_MEMBER_AVAILABLE: 'guildMemberAvailable', GUILD_MEMBERS_CHUNK: 'guildMembersChunk', GUILD_INTEGRATIONS_UPDATE: 'guildIntegrationsUpdate', GUILD_ROLE_CREATE: 'roleCreate', GUILD_ROLE_DELETE: 'roleDelete', INVITE_CREATE: 'inviteCreate', INVITE_DELETE: 'inviteDelete', GUILD_ROLE_UPDATE: 'roleUpdate', GUILD_EMOJI_CREATE: 'emojiCreate', GUILD_EMOJI_DELETE: 'emojiDelete', GUILD_EMOJI_UPDATE: 'emojiUpdate', GUILD_BAN_ADD: 'guildBanAdd', GUILD_BAN_REMOVE: 'guildBanRemove', CHANNEL_CREATE: 'channelCreate', CHANNEL_DELETE: 'channelDelete', CHANNEL_UPDATE: 'channelUpdate', CHANNEL_PINS_UPDATE: 'channelPinsUpdate', MESSAGE_CREATE: 'message', MESSAGE_DELETE: 'messageDelete', MESSAGE_UPDATE: 'messageUpdate', MESSAGE_BULK_DELETE: 'messageDeleteBulk', MESSAGE_REACTION_ADD: 'messageReactionAdd', MESSAGE_REACTION_REMOVE: 'messageReactionRemove', MESSAGE_REACTION_REMOVE_ALL: 'messageReactionRemoveAll', MESSAGE_REACTION_REMOVE_EMOJI: 'messageReactionRemoveEmoji', USER_UPDATE: 'userUpdate', PRESENCE_UPDATE: 'presenceUpdate', VOICE_SERVER_UPDATE: 'voiceServerUpdate', VOICE_STATE_UPDATE: 'voiceStateUpdate', TYPING_START: 'typingStart', WEBHOOKS_UPDATE: 'webhookUpdate', INTERACTION_CREATE: 'interaction', ERROR: 'error', WARN: 'warn', DEBUG: 'debug', SHARD_DISCONNECT: 'shardDisconnect', SHARD_ERROR: 'shardError', SHARD_RECONNECTING: 'shardReconnecting', SHARD_READY: 'shardReady', SHARD_RESUME: 'shardResume', INVALIDATED: 'invalidated', RAW: 'raw', }; exports.ShardEvents = { CLOSE: 'close', DESTROYED: 'destroyed', INVALID_SESSION: 'invalidSession', READY: 'ready', RESUMED: 'resumed', ALL_READY: 'allReady', }; /** * The type of Structure allowed to be a partial: * * USER * * CHANNEL (only affects DMChannels) * * GUILD_MEMBER * * MESSAGE * * REACTION * Partials require you to put checks in place when handling data, read the Partials topic listed in the * sidebar for more information. * @typedef {string} PartialType */ exports.PartialTypes = keyMirror(['USER', 'CHANNEL', 'GUILD_MEMBER', 'MESSAGE', 'REACTION']); /** * The type of a websocket message event, e.g. `MESSAGE_CREATE`. Here are the available events: * * READY * * RESUMED * * APPLICATION_COMMAND_CREATE * * APPLICATION_COMMAND_DELETE * * APPLICATION_COMMAND_UPDATE * * GUILD_CREATE * * GUILD_DELETE * * GUILD_UPDATE * * INVITE_CREATE * * INVITE_DELETE * * GUILD_MEMBER_ADD * * GUILD_MEMBER_REMOVE * * GUILD_MEMBER_UPDATE * * GUILD_MEMBERS_CHUNK * * GUILD_INTEGRATIONS_UPDATE * * GUILD_ROLE_CREATE * * GUILD_ROLE_DELETE * * GUILD_ROLE_UPDATE * * GUILD_BAN_ADD * * GUILD_BAN_REMOVE * * GUILD_EMOJIS_UPDATE * * CHANNEL_CREATE * * CHANNEL_DELETE * * CHANNEL_UPDATE * * CHANNEL_PINS_UPDATE * * MESSAGE_CREATE * * MESSAGE_DELETE * * MESSAGE_UPDATE * * MESSAGE_DELETE_BULK * * MESSAGE_REACTION_ADD * * MESSAGE_REACTION_REMOVE * * MESSAGE_REACTION_REMOVE_ALL * * MESSAGE_REACTION_REMOVE_EMOJI * * USER_UPDATE * * PRESENCE_UPDATE * * TYPING_START * * VOICE_STATE_UPDATE * * VOICE_SERVER_UPDATE * * WEBHOOKS_UPDATE * * INTERACTION_CREATE * @typedef {string} WSEventType */ exports.WSEvents = keyMirror([ 'READY', 'RESUMED', 'APPLICATION_COMMAND_CREATE', 'APPLICATION_COMMAND_DELETE', 'APPLICATION_COMMAND_UPDATE', 'GUILD_CREATE', 'GUILD_DELETE', 'GUILD_UPDATE', 'INVITE_CREATE', 'INVITE_DELETE', 'GUILD_MEMBER_ADD', 'GUILD_MEMBER_REMOVE', 'GUILD_MEMBER_UPDATE', 'GUILD_MEMBERS_CHUNK', 'GUILD_INTEGRATIONS_UPDATE', 'GUILD_ROLE_CREATE', 'GUILD_ROLE_DELETE', 'GUILD_ROLE_UPDATE', 'GUILD_BAN_ADD', 'GUILD_BAN_REMOVE', 'GUILD_EMOJIS_UPDATE', 'CHANNEL_CREATE', 'CHANNEL_DELETE', 'CHANNEL_UPDATE', 'CHANNEL_PINS_UPDATE', 'MESSAGE_CREATE', 'MESSAGE_DELETE', 'MESSAGE_UPDATE', 'MESSAGE_DELETE_BULK', 'MESSAGE_REACTION_ADD', 'MESSAGE_REACTION_REMOVE', 'MESSAGE_REACTION_REMOVE_ALL', 'MESSAGE_REACTION_REMOVE_EMOJI', 'USER_UPDATE', 'PRESENCE_UPDATE', 'TYPING_START', 'VOICE_STATE_UPDATE', 'VOICE_SERVER_UPDATE', 'WEBHOOKS_UPDATE', 'INTERACTION_CREATE', ]); /** * A valid scope to request when generating an invite link. * Scopes that require whitelist are not considered valid for this generator * * `applications.builds.read`: allows reading build data for a users applications * * `applications.commands`: allows this bot to create commands in the server * * `applications.entitlements`: allows reading entitlements for a users applications * * `applications.store.update`: allows reading and updating of store data for a users applications * * `connections`: makes the endpoint for getting a users connections available * * `email`: allows the `/users/@me` endpoint return with an email * * `identify`: allows the `/users/@me` endpoint without an email * * `guilds`: makes the `/users/@me/guilds` endpoint available for a user * * `guilds.join`: allows the bot to join the user to any guild it is in using Guild#addMember * * `gdm.join`: allows joining the user to a group dm * * `webhook.incoming`: generates a webhook to a channel * @typedef {string} InviteScope */ exports.InviteScopes = [ 'applications.builds.read', 'applications.commands', 'applications.entitlements', 'applications.store.update', 'connections', 'email', 'identity', 'guilds', 'guilds.join', 'gdm.join', 'webhook.incoming', ]; /** * The type of a message, e.g. `DEFAULT`. Here are the available types: * * DEFAULT * * RECIPIENT_ADD * * RECIPIENT_REMOVE * * CALL * * CHANNEL_NAME_CHANGE * * CHANNEL_ICON_CHANGE * * PINS_ADD * * GUILD_MEMBER_JOIN * * USER_PREMIUM_GUILD_SUBSCRIPTION * * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1 * * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2 * * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3 * * CHANNEL_FOLLOW_ADD * * GUILD_DISCOVERY_DISQUALIFIED * * GUILD_DISCOVERY_REQUALIFIED * * GUILD_DISCOVERY_GRACE_PERIOD_INITIAL_WARNING * * GUILD_DISCOVERY_GRACE_PERIOD_FINAL_WARNING * * REPLY * * APPLICATION_COMMAND * @typedef {string} MessageType */ exports.MessageTypes = [ 'DEFAULT', 'RECIPIENT_ADD', 'RECIPIENT_REMOVE', 'CALL', 'CHANNEL_NAME_CHANGE', 'CHANNEL_ICON_CHANGE', 'PINS_ADD', 'GUILD_MEMBER_JOIN', 'USER_PREMIUM_GUILD_SUBSCRIPTION', 'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1', 'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2', 'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3', 'CHANNEL_FOLLOW_ADD', null, 'GUILD_DISCOVERY_DISQUALIFIED', 'GUILD_DISCOVERY_REQUALIFIED', 'GUILD_DISCOVERY_GRACE_PERIOD_INITIAL_WARNING', 'GUILD_DISCOVERY_GRACE_PERIOD_FINAL_WARNING', null, 'REPLY', 'APPLICATION_COMMAND', ]; /** * The types of messages that are `System`. The available types are `MessageTypes` excluding: * * DEFAULT * * REPLY * * APPLICATION_COMMAND * @typedef {string} SystemMessageType */ exports.SystemMessageTypes = exports.MessageTypes.filter( type => type && !['DEFAULT', 'REPLY', 'APPLICATION_COMMAND'].includes(type), ); /** * Bots cannot set a `CUSTOM_STATUS`, it is only for custom statuses received from users * The type of an activity of a users presence, e.g. `PLAYING`. Here are the available types: * * PLAYING * * STREAMING * * LISTENING * * WATCHING * * CUSTOM_STATUS * * COMPETING * @typedef {string} ActivityType */ exports.ActivityTypes = ['PLAYING', 'STREAMING', 'LISTENING', 'WATCHING', 'CUSTOM_STATUS', 'COMPETING']; exports.ChannelTypes = createEnum([ 'TEXT', 'DM', 'VOICE', 'GROUP', 'CATEGORY', 'NEWS', // 6 'STORE', ...Array(6).fill(null), // 13 'STAGE', ]); exports.ClientApplicationAssetTypes = { SMALL: 1, BIG: 2, }; exports.Colors = { DEFAULT: 0x000000, WHITE: 0xffffff, AQUA: 0x1abc9c, GREEN: 0x57f287, BLUE: 0x3498db, YELLOW: 0xfee75c, PURPLE: 0x9b59b6, LUMINOUS_VIVID_PINK: 0xe91e63, FUCHSIA: 0xeb459e, GOLD: 0xf1c40f, ORANGE: 0xe67e22, RED: 0xed4245, GREY: 0x95a5a6, NAVY: 0x34495e, DARK_AQUA: 0x11806a, DARK_GREEN: 0x1f8b4c, DARK_BLUE: 0x206694, DARK_PURPLE: 0x71368a, DARK_VIVID_PINK: 0xad1457, DARK_GOLD: 0xc27c0e, DARK_ORANGE: 0xa84300, DARK_RED: 0x992d22, DARK_GREY: 0x979c9f, DARKER_GREY: 0x7f8c8d, LIGHT_GREY: 0xbcc0c0, DARK_NAVY: 0x2c3e50, BLURPLE: 0x5865f2, GREYPLE: 0x99aab5, DARK_BUT_NOT_BLACK: 0x2c2f33, NOT_QUITE_BLACK: 0x23272a, }; /** * The value set for the explicit content filter levels for a guild: * * DISABLED * * MEMBERS_WITHOUT_ROLES * * ALL_MEMBERS * @typedef {string} ExplicitContentFilterLevel */ exports.ExplicitContentFilterLevels = ['DISABLED', 'MEMBERS_WITHOUT_ROLES', 'ALL_MEMBERS']; /** * The value set for the verification levels for a guild: * * NONE * * LOW * * MEDIUM * * HIGH * * VERY_HIGH * @typedef {string} VerificationLevel */ exports.VerificationLevels = ['NONE', 'LOW', 'MEDIUM', 'HIGH', 'VERY_HIGH']; /** * An error encountered while performing an API request. Here are the potential errors: * * UNKNOWN_ACCOUNT * * UNKNOWN_APPLICATION * * UNKNOWN_CHANNEL * * UNKNOWN_GUILD * * UNKNOWN_INTEGRATION * * UNKNOWN_INVITE * * UNKNOWN_MEMBER * * UNKNOWN_MESSAGE * * UNKNOWN_OVERWRITE * * UNKNOWN_PROVIDER * * UNKNOWN_ROLE * * UNKNOWN_TOKEN * * UNKNOWN_USER * * UNKNOWN_EMOJI * * UNKNOWN_WEBHOOK * * UNKNOWN_BAN * * UNKNOWN_GUILD_TEMPLATE * * BOT_PROHIBITED_ENDPOINT * * BOT_ONLY_ENDPOINT * * ANNOUNCEMENT_EDIT_LIMIT_EXCEEDED * * CHANNEL_HIT_WRITE_RATELIMIT * * MAXIMUM_GUILDS * * MAXIMUM_FRIENDS * * MAXIMUM_PINS * * MAXIMUM_ROLES * * MAXIMUM_WEBHOOKS * * MAXIMUM_REACTIONS * * MAXIMUM_CHANNELS * * MAXIMUM_ATTACHMENTS * * MAXIMUM_INVITES * * MAXIMUM_ANIMATED_EMOJIS * * MAXIMUM_SERVER_MEMBERS * * GUILD_ALREADY_HAS_TEMPLATE * * UNAUTHORIZED * * ACCOUNT_VERIFICATION_REQUIRED * * REQUEST_ENTITY_TOO_LARGE * * FEATURE_TEMPORARILY_DISABLED * * USER_BANNED * * ALREADY_CROSSPOSTED * * MISSING_ACCESS * * INVALID_ACCOUNT_TYPE * * CANNOT_EXECUTE_ON_DM * * EMBED_DISABLED * * CANNOT_EDIT_MESSAGE_BY_OTHER * * CANNOT_SEND_EMPTY_MESSAGE * * CANNOT_MESSAGE_USER * * CANNOT_SEND_MESSAGES_IN_VOICE_CHANNEL * * CHANNEL_VERIFICATION_LEVEL_TOO_HIGH * * OAUTH2_APPLICATION_BOT_ABSENT * * MAXIMUM_OAUTH2_APPLICATIONS * * INVALID_OAUTH_STATE * * MISSING_PERMISSIONS * * INVALID_AUTHENTICATION_TOKEN * * NOTE_TOO_LONG * * INVALID_BULK_DELETE_QUANTITY * * CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL * * INVALID_OR_TAKEN_INVITE_CODE * * CANNOT_EXECUTE_ON_SYSTEM_MESSAGE * * CANNOT_EXECUTE_ON_CHANNEL_TYPE * * INVALID_OAUTH_TOKEN * * INVALID_RECIPIENTS * * BULK_DELETE_MESSAGE_TOO_OLD * * INVALID_FORM_BODY * * INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT * * INVALID_API_VERSION * * CANNOT_DELETE_COMMUNITY_REQUIRED_CHANNEL * * REACTION_BLOCKED * * RESOURCE_OVERLOADED * @typedef {string} APIError */ exports.APIErrors = { UNKNOWN_ACCOUNT: 10001, UNKNOWN_APPLICATION: 10002, UNKNOWN_CHANNEL: 10003, UNKNOWN_GUILD: 10004, UNKNOWN_INTEGRATION: 10005, UNKNOWN_INVITE: 10006, UNKNOWN_MEMBER: 10007, UNKNOWN_MESSAGE: 10008, UNKNOWN_OVERWRITE: 10009, UNKNOWN_PROVIDER: 10010, UNKNOWN_ROLE: 10011, UNKNOWN_TOKEN: 10012, UNKNOWN_USER: 10013, UNKNOWN_EMOJI: 10014, UNKNOWN_WEBHOOK: 10015, UNKNOWN_BAN: 10026, UNKNOWN_GUILD_TEMPLATE: 10057, BOT_PROHIBITED_ENDPOINT: 20001, BOT_ONLY_ENDPOINT: 20002, ANNOUNCEMENT_EDIT_LIMIT_EXCEEDED: 20022, CHANNEL_HIT_WRITE_RATELIMIT: 20028, MAXIMUM_GUILDS: 30001, MAXIMUM_FRIENDS: 30002, MAXIMUM_PINS: 30003, MAXIMUM_ROLES: 30005, MAXIMUM_WEBHOOKS: 30007, MAXIMUM_REACTIONS: 30010, MAXIMUM_CHANNELS: 30013, MAXIMUM_ATTACHMENTS: 30015, MAXIMUM_INVITES: 30016, MAXIMUM_ANIMATED_EMOJIS: 30018, MAXIMUM_SERVER_MEMBERS: 30019, GUILD_ALREADY_HAS_TEMPLATE: 30031, UNAUTHORIZED: 40001, ACCOUNT_VERIFICATION_REQUIRED: 40002, REQUEST_ENTITY_TOO_LARGE: 40005, FEATURE_TEMPORARILY_DISABLED: 40006, USER_BANNED: 40007, ALREADY_CROSSPOSTED: 40033, MISSING_ACCESS: 50001, INVALID_ACCOUNT_TYPE: 50002, CANNOT_EXECUTE_ON_DM: 50003, EMBED_DISABLED: 50004, CANNOT_EDIT_MESSAGE_BY_OTHER: 50005, CANNOT_SEND_EMPTY_MESSAGE: 50006, CANNOT_MESSAGE_USER: 50007, CANNOT_SEND_MESSAGES_IN_VOICE_CHANNEL: 50008, CHANNEL_VERIFICATION_LEVEL_TOO_HIGH: 50009, OAUTH2_APPLICATION_BOT_ABSENT: 50010, MAXIMUM_OAUTH2_APPLICATIONS: 50011, INVALID_OAUTH_STATE: 50012, MISSING_PERMISSIONS: 50013, INVALID_AUTHENTICATION_TOKEN: 50014, NOTE_TOO_LONG: 50015, INVALID_BULK_DELETE_QUANTITY: 50016, CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL: 50019, INVALID_OR_TAKEN_INVITE_CODE: 50020, CANNOT_EXECUTE_ON_SYSTEM_MESSAGE: 50021, CANNOT_EXECUTE_ON_CHANNEL_TYPE: 50024, INVALID_OAUTH_TOKEN: 50025, INVALID_RECIPIENTS: 50033, BULK_DELETE_MESSAGE_TOO_OLD: 50034, INVALID_FORM_BODY: 50035, INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT: 50036, INVALID_API_VERSION: 50041, CANNOT_DELETE_COMMUNITY_REQUIRED_CHANNEL: 50074, INVALID_STICKER_SENT: 50081, REACTION_BLOCKED: 90001, RESOURCE_OVERLOADED: 130000, }; /** * The value set for a guild's default message notifications, e.g. `ALL`. Here are the available types: * * ALL * * MENTIONS * @typedef {string} DefaultMessageNotifications */ exports.DefaultMessageNotifications = ['ALL', 'MENTIONS']; /** * The value set for a team members's membership state: * * INVITED * * ACCEPTED * @typedef {string} MembershipStates */ exports.MembershipStates = [ // They start at 1 null, 'INVITED', 'ACCEPTED', ]; /** * The value set for a webhook's type: * * Incoming * * Channel Follower * @typedef {string} WebhookTypes */ exports.WebhookTypes = [ // They start at 1 null, 'Incoming', 'Channel Follower', ]; /** * The value set for a sticker's type: * * PNG * * APNG * * LOTTIE * @typedef {string} StickerFormatTypes */ exports.StickerFormatTypes = createEnum([null, 'PNG', 'APNG', 'LOTTIE']); /** * An overwrite type: * * role * * member * @typedef {string} OverwriteType */ exports.OverwriteTypes = createEnum(['role', 'member']); /** * The type of an {@link ApplicationCommandOption} object: * * SUB_COMMAND * * SUB_COMMAND_GROUP * * STRING * * INTEGER * * BOOLEAN * * USER * * CHANNEL * * ROLE * * MENTIONABLE * @typedef {string} ApplicationCommandOptionType */ exports.ApplicationCommandOptionTypes = createEnum([ null, 'SUB_COMMAND', 'SUB_COMMAND_GROUP', 'STRING', 'INTEGER', 'BOOLEAN', 'USER', 'CHANNEL', 'ROLE', 'MENTIONABLE', ]); /** * The type of an {@link ApplicationCommandPermissions} object: * * ROLE * * USER * @typedef {string} ApplicationCommandPermissionType */ exports.ApplicationCommandPermissionTypes = createEnum([null, 'ROLE', 'USER']); /** * The type of an {@link Interaction} object: * * PING * * APPLICATION_COMMAND * * MESSAGE_COMPONENT * @typedef {string} InteractionType */ exports.InteractionTypes = createEnum([null, 'PING', 'APPLICATION_COMMAND', 'MESSAGE_COMPONENT']); /** * The type of an interaction response: * * PONG * * CHANNEL_MESSAGE_WITH_SOURCE * * DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE * * DEFERRED_MESSAGE_UPDATE * * UPDATE_MESSAGE * @typedef {string} InteractionResponseType */ exports.InteractionResponseTypes = createEnum([ null, 'PONG', null, null, 'CHANNEL_MESSAGE_WITH_SOURCE', 'DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE', 'DEFERRED_MESSAGE_UPDATE', 'UPDATE_MESSAGE', ]); /** * The type of a message component * * ACTION_ROW * * BUTTON * @typedef {string} MessageComponentType */ exports.MessageComponentTypes = createEnum([null, 'ACTION_ROW', 'BUTTON']); /** * The style of a message button * * PRIMARY * * SECONDARY * * SUCCESS * * DANGER * * LINK * @typedef {string} MessageButtonStyle */ exports.MessageButtonStyles = createEnum([null, 'PRIMARY', 'SECONDARY', 'SUCCESS', 'DANGER', 'LINK']); /** * The required MFA level for a guild * * NONE * * ELEVATED * @typedef {string} MFALevel */ exports.MFALevels = createEnum(['NONE', 'ELEVATED']); /** * NSFW level of a Guild * * DEFAULT * * EXPLICIT * * SAFE * * AGE_RESTRICTED * @typedef {string} NSFWLevel */ exports.NSFWLevels = createEnum(['DEFAULT', 'EXPLICIT', 'SAFE', 'AGE_RESTRICTED']); function keyMirror(arr) { let tmp = Object.create(null); for (const value of arr) tmp[value] = value; return tmp; } function createEnum(keys) { const obj = {}; for (const [index, key] of keys.entries()) { if (key === null) continue; obj[key] = index; obj[index] = key; } return obj; }