buddy

node MVC discord bot
Log | Files | Refs | README

Constants.js (19561B)


      1 'use strict';
      2 
      3 const Package = (exports.Package = require('../../package.json'));
      4 const { Error, RangeError } = require('../errors');
      5 const browser = (exports.browser = typeof window !== 'undefined');
      6 
      7 /**
      8  * Options for a client.
      9  * @typedef {Object} ClientOptions
     10  * @property {number|number[]|string} [shards] ID of the shard to run, or an array of shard IDs. If not specified,
     11  * the client will spawn {@link ClientOptions#shardCount} shards. If set to `auto`, it will fetch the
     12  * recommended amount of shards from Discord and spawn that amount
     13  * @property {number} [shardCount=1] The total amount of shards used by all processes of this bot
     14  * (e.g. recommended shard count, shard count of the ShardingManager)
     15  * @property {number} [messageCacheMaxSize=200] Maximum number of messages to cache per channel
     16  * (-1 or Infinity for unlimited - don't do this without message sweeping, otherwise memory usage will climb
     17  * indefinitely)
     18  * @property {number} [messageCacheLifetime=0] How long a message should stay in the cache until it is considered
     19  * sweepable (in seconds, 0 for forever)
     20  * @property {number} [messageSweepInterval=0] How frequently to remove messages from the cache that are older than
     21  * the message cache lifetime (in seconds, 0 for never)
     22  * @property {boolean} [fetchAllMembers=false] Whether to cache all guild members and users upon startup, as well as
     23  * upon joining a guild (should be avoided whenever possible)
     24  * @property {DisableMentionType} [disableMentions='none'] Default value for {@link MessageOptions#disableMentions}
     25  * @property {MessageMentionOptions} [allowedMentions] Default value for {@link MessageOptions#allowedMentions}
     26  * @property {PartialType[]} [partials] Structures allowed to be partial. This means events can be emitted even when
     27  * they're missing all the data for a particular structure. See the "Partials" topic listed in the sidebar for some
     28  * important usage information, as partials require you to put checks in place when handling data.
     29  * @property {number} [restWsBridgeTimeout=5000] Maximum time permitted between REST responses and their
     30  * corresponding websocket events
     31  * @property {number} [restTimeOffset=500] Extra time in millseconds to wait before continuing to make REST
     32  * requests (higher values will reduce rate-limiting errors on bad connections)
     33  * @property {number} [restRequestTimeout=15000] Time to wait before cancelling a REST request, in milliseconds
     34  * @property {number} [restSweepInterval=60] How frequently to delete inactive request buckets, in seconds
     35  * (or 0 for never)
     36  * @property {number} [retryLimit=1] How many times to retry on 5XX errors (Infinity for indefinite amount of retries)
     37  * @property {PresenceData} [presence] Presence data to use upon login
     38  * @property {WebsocketOptions} [ws] Options for the WebSocket
     39  * @property {HTTPOptions} [http] HTTP options
     40  */
     41 exports.DefaultOptions = {
     42   shardCount: 1,
     43   messageCacheMaxSize: 200,
     44   messageCacheLifetime: 0,
     45   messageSweepInterval: 0,
     46   fetchAllMembers: false,
     47   disableMentions: 'none',
     48   partials: [],
     49   restWsBridgeTimeout: 5000,
     50   restRequestTimeout: 15000,
     51   retryLimit: 1,
     52   restTimeOffset: 500,
     53   restSweepInterval: 60,
     54   presence: {},
     55 
     56   /**
     57    * WebSocket options (these are left as snake_case to match the API)
     58    * @typedef {Object} WebsocketOptions
     59    * @property {number} [large_threshold=250] Number of members in a guild to be considered large
     60    * @property {IntentsResolvable} [intents] Intents to enable for this connection
     61    */
     62   ws: {
     63     large_threshold: 250,
     64     compress: false,
     65     properties: {
     66       $os: browser ? 'browser' : process.platform,
     67       $browser: 'discord.js',
     68       $device: 'discord.js',
     69     },
     70     version: 6,
     71   },
     72 
     73   /**
     74    * HTTP options
     75    * @typedef {Object} HTTPOptions
     76    * @property {number} [version=7] API version to use
     77    * @property {string} [api='https://discordapp.com/api'] Base url of the API
     78    * @property {string} [cdn='https://cdn.discordapp.com'] Base url of the CDN
     79    * @property {string} [invite='https://discord.gg'] Base url of invites
     80    */
     81   http: {
     82     version: 7,
     83     api: 'https://discordapp.com/api',
     84     cdn: 'https://cdn.discordapp.com',
     85     invite: 'https://discord.gg',
     86   },
     87 };
     88 
     89 exports.UserAgent = browser
     90   ? null
     91   : `DiscordBot (${Package.homepage.split('#')[0]}, ${Package.version}) Node.js/${process.version}`;
     92 
     93 exports.WSCodes = {
     94   1000: 'WS_CLOSE_REQUESTED',
     95   4004: 'TOKEN_INVALID',
     96   4010: 'SHARDING_INVALID',
     97   4011: 'SHARDING_REQUIRED',
     98   4013: 'INVALID_INTENTS',
     99   4014: 'DISALLOWED_INTENTS',
    100 };
    101 
    102 const AllowedImageFormats = ['webp', 'png', 'jpg', 'jpeg', 'gif'];
    103 
    104 const AllowedImageSizes = Array.from({ length: 9 }, (e, i) => 2 ** (i + 4));
    105 
    106 function makeImageUrl(root, { format = 'webp', size } = {}) {
    107   if (format && !AllowedImageFormats.includes(format)) throw new Error('IMAGE_FORMAT', format);
    108   if (size && !AllowedImageSizes.includes(size)) throw new RangeError('IMAGE_SIZE', size);
    109   return `${root}.${format}${size ? `?size=${size}` : ''}`;
    110 }
    111 /**
    112  * Options for Image URLs.
    113  * @typedef {Object} ImageURLOptions
    114  * @property {string} [format] One of `webp`, `png`, `jpg`, `jpeg`, `gif`. If no format is provided,
    115  * defaults to `webp`.
    116  * @property {boolean} [dynamic] If true, the format will dynamically change to `gif` for
    117  * animated avatars; the default is false.
    118  * @property {number} [size] One of `16`, `32`, `64`, `128`, `256`, `512`, `1024`, `2048`, `4096`
    119  */
    120 
    121 exports.Endpoints = {
    122   CDN(root) {
    123     return {
    124       Emoji: (emojiID, format = 'png') => `${root}/emojis/${emojiID}.${format}`,
    125       Asset: name => `${root}/assets/${name}`,
    126       DefaultAvatar: discriminator => `${root}/embed/avatars/${discriminator}.png`,
    127       Avatar: (userID, hash, format = 'webp', size, dynamic = false) => {
    128         if (dynamic) format = hash.startsWith('a_') ? 'gif' : format;
    129         return makeImageUrl(`${root}/avatars/${userID}/${hash}`, { format, size });
    130       },
    131       Banner: (guildID, hash, format = 'webp', size) =>
    132         makeImageUrl(`${root}/banners/${guildID}/${hash}`, { format, size }),
    133       Icon: (guildID, hash, format = 'webp', size, dynamic = false) => {
    134         if (dynamic) format = hash.startsWith('a_') ? 'gif' : format;
    135         return makeImageUrl(`${root}/icons/${guildID}/${hash}`, { format, size });
    136       },
    137       AppIcon: (clientID, hash, { format = 'webp', size } = {}) =>
    138         makeImageUrl(`${root}/app-icons/${clientID}/${hash}`, { size, format }),
    139       AppAsset: (clientID, hash, { format = 'webp', size } = {}) =>
    140         makeImageUrl(`${root}/app-assets/${clientID}/${hash}`, { size, format }),
    141       GDMIcon: (channelID, hash, format = 'webp', size) =>
    142         makeImageUrl(`${root}/channel-icons/${channelID}/${hash}`, { size, format }),
    143       Splash: (guildID, hash, format = 'webp', size) =>
    144         makeImageUrl(`${root}/splashes/${guildID}/${hash}`, { size, format }),
    145       DiscoverySplash: (guildID, hash, format = 'webp', size) =>
    146         makeImageUrl(`${root}/discovery-splashes/${guildID}/${hash}`, { size, format }),
    147       TeamIcon: (teamID, hash, { format = 'webp', size } = {}) =>
    148         makeImageUrl(`${root}/team-icons/${teamID}/${hash}`, { size, format }),
    149     };
    150   },
    151   invite: (root, code) => `${root}/${code}`,
    152   botGateway: '/gateway/bot',
    153 };
    154 
    155 /**
    156  * The current status of the client. Here are the available statuses:
    157  * * READY: 0
    158  * * CONNECTING: 1
    159  * * RECONNECTING: 2
    160  * * IDLE: 3
    161  * * NEARLY: 4
    162  * * DISCONNECTED: 5
    163  * * WAITING_FOR_GUILDS: 6
    164  * * IDENTIFYING: 7
    165  * * RESUMING: 8
    166  * @typedef {number} Status
    167  */
    168 exports.Status = {
    169   READY: 0,
    170   CONNECTING: 1,
    171   RECONNECTING: 2,
    172   IDLE: 3,
    173   NEARLY: 4,
    174   DISCONNECTED: 5,
    175   WAITING_FOR_GUILDS: 6,
    176   IDENTIFYING: 7,
    177   RESUMING: 8,
    178 };
    179 
    180 /**
    181  * The current status of a voice connection. Here are the available statuses:
    182  * * CONNECTED: 0
    183  * * CONNECTING: 1
    184  * * AUTHENTICATING: 2
    185  * * RECONNECTING: 3
    186  * * DISCONNECTED: 4
    187  * @typedef {number} VoiceStatus
    188  */
    189 exports.VoiceStatus = {
    190   CONNECTED: 0,
    191   CONNECTING: 1,
    192   AUTHENTICATING: 2,
    193   RECONNECTING: 3,
    194   DISCONNECTED: 4,
    195 };
    196 
    197 exports.OPCodes = {
    198   DISPATCH: 0,
    199   HEARTBEAT: 1,
    200   IDENTIFY: 2,
    201   STATUS_UPDATE: 3,
    202   VOICE_STATE_UPDATE: 4,
    203   VOICE_GUILD_PING: 5,
    204   RESUME: 6,
    205   RECONNECT: 7,
    206   REQUEST_GUILD_MEMBERS: 8,
    207   INVALID_SESSION: 9,
    208   HELLO: 10,
    209   HEARTBEAT_ACK: 11,
    210 };
    211 
    212 exports.VoiceOPCodes = {
    213   IDENTIFY: 0,
    214   SELECT_PROTOCOL: 1,
    215   READY: 2,
    216   HEARTBEAT: 3,
    217   SESSION_DESCRIPTION: 4,
    218   SPEAKING: 5,
    219   HELLO: 8,
    220   CLIENT_CONNECT: 12,
    221   CLIENT_DISCONNECT: 13,
    222 };
    223 
    224 exports.Events = {
    225   RATE_LIMIT: 'rateLimit',
    226   CLIENT_READY: 'ready',
    227   GUILD_CREATE: 'guildCreate',
    228   GUILD_DELETE: 'guildDelete',
    229   GUILD_UPDATE: 'guildUpdate',
    230   GUILD_UNAVAILABLE: 'guildUnavailable',
    231   GUILD_AVAILABLE: 'guildAvailable',
    232   GUILD_MEMBER_ADD: 'guildMemberAdd',
    233   GUILD_MEMBER_REMOVE: 'guildMemberRemove',
    234   GUILD_MEMBER_UPDATE: 'guildMemberUpdate',
    235   GUILD_MEMBER_AVAILABLE: 'guildMemberAvailable',
    236   GUILD_MEMBER_SPEAKING: 'guildMemberSpeaking',
    237   GUILD_MEMBERS_CHUNK: 'guildMembersChunk',
    238   GUILD_INTEGRATIONS_UPDATE: 'guildIntegrationsUpdate',
    239   GUILD_ROLE_CREATE: 'roleCreate',
    240   GUILD_ROLE_DELETE: 'roleDelete',
    241   INVITE_CREATE: 'inviteCreate',
    242   INVITE_DELETE: 'inviteDelete',
    243   GUILD_ROLE_UPDATE: 'roleUpdate',
    244   GUILD_EMOJI_CREATE: 'emojiCreate',
    245   GUILD_EMOJI_DELETE: 'emojiDelete',
    246   GUILD_EMOJI_UPDATE: 'emojiUpdate',
    247   GUILD_BAN_ADD: 'guildBanAdd',
    248   GUILD_BAN_REMOVE: 'guildBanRemove',
    249   CHANNEL_CREATE: 'channelCreate',
    250   CHANNEL_DELETE: 'channelDelete',
    251   CHANNEL_UPDATE: 'channelUpdate',
    252   CHANNEL_PINS_UPDATE: 'channelPinsUpdate',
    253   MESSAGE_CREATE: 'message',
    254   MESSAGE_DELETE: 'messageDelete',
    255   MESSAGE_UPDATE: 'messageUpdate',
    256   MESSAGE_BULK_DELETE: 'messageDeleteBulk',
    257   MESSAGE_REACTION_ADD: 'messageReactionAdd',
    258   MESSAGE_REACTION_REMOVE: 'messageReactionRemove',
    259   MESSAGE_REACTION_REMOVE_ALL: 'messageReactionRemoveAll',
    260   MESSAGE_REACTION_REMOVE_EMOJI: 'messageReactionRemoveEmoji',
    261   USER_UPDATE: 'userUpdate',
    262   PRESENCE_UPDATE: 'presenceUpdate',
    263   VOICE_SERVER_UPDATE: 'voiceServerUpdate',
    264   VOICE_STATE_UPDATE: 'voiceStateUpdate',
    265   VOICE_BROADCAST_SUBSCRIBE: 'subscribe',
    266   VOICE_BROADCAST_UNSUBSCRIBE: 'unsubscribe',
    267   TYPING_START: 'typingStart',
    268   TYPING_STOP: 'typingStop',
    269   WEBHOOKS_UPDATE: 'webhookUpdate',
    270   ERROR: 'error',
    271   WARN: 'warn',
    272   DEBUG: 'debug',
    273   SHARD_DISCONNECT: 'shardDisconnect',
    274   SHARD_ERROR: 'shardError',
    275   SHARD_RECONNECTING: 'shardReconnecting',
    276   SHARD_READY: 'shardReady',
    277   SHARD_RESUME: 'shardResume',
    278   INVALIDATED: 'invalidated',
    279   RAW: 'raw',
    280 };
    281 
    282 exports.ShardEvents = {
    283   CLOSE: 'close',
    284   DESTROYED: 'destroyed',
    285   INVALID_SESSION: 'invalidSession',
    286   READY: 'ready',
    287   RESUMED: 'resumed',
    288   ALL_READY: 'allReady',
    289 };
    290 
    291 /**
    292  * The type of Structure allowed to be a partial:
    293  * * USER
    294  * * CHANNEL (only affects DMChannels)
    295  * * GUILD_MEMBER
    296  * * MESSAGE
    297  * * REACTION
    298  * <warn>Partials require you to put checks in place when handling data, read the Partials topic listed in the
    299  * sidebar for more information.</warn>
    300  * @typedef {string} PartialType
    301  */
    302 exports.PartialTypes = keyMirror(['USER', 'CHANNEL', 'GUILD_MEMBER', 'MESSAGE', 'REACTION']);
    303 
    304 /**
    305  * The type of a websocket message event, e.g. `MESSAGE_CREATE`. Here are the available events:
    306  * * READY
    307  * * RESUMED
    308  * * GUILD_CREATE
    309  * * GUILD_DELETE
    310  * * GUILD_UPDATE
    311  * * INVITE_CREATE
    312  * * INVITE_DELETE
    313  * * GUILD_MEMBER_ADD
    314  * * GUILD_MEMBER_REMOVE
    315  * * GUILD_MEMBER_UPDATE
    316  * * GUILD_MEMBERS_CHUNK
    317  * * GUILD_INTEGRATIONS_UPDATE
    318  * * GUILD_ROLE_CREATE
    319  * * GUILD_ROLE_DELETE
    320  * * GUILD_ROLE_UPDATE
    321  * * GUILD_BAN_ADD
    322  * * GUILD_BAN_REMOVE
    323  * * GUILD_EMOJIS_UPDATE
    324  * * CHANNEL_CREATE
    325  * * CHANNEL_DELETE
    326  * * CHANNEL_UPDATE
    327  * * CHANNEL_PINS_UPDATE
    328  * * MESSAGE_CREATE
    329  * * MESSAGE_DELETE
    330  * * MESSAGE_UPDATE
    331  * * MESSAGE_DELETE_BULK
    332  * * MESSAGE_REACTION_ADD
    333  * * MESSAGE_REACTION_REMOVE
    334  * * MESSAGE_REACTION_REMOVE_ALL
    335  * * MESSAGE_REACTION_REMOVE_EMOJI
    336  * * USER_UPDATE
    337  * * PRESENCE_UPDATE
    338  * * TYPING_START
    339  * * VOICE_STATE_UPDATE
    340  * * VOICE_SERVER_UPDATE
    341  * * WEBHOOKS_UPDATE
    342  * @typedef {string} WSEventType
    343  */
    344 exports.WSEvents = keyMirror([
    345   'READY',
    346   'RESUMED',
    347   'GUILD_CREATE',
    348   'GUILD_DELETE',
    349   'GUILD_UPDATE',
    350   'INVITE_CREATE',
    351   'INVITE_DELETE',
    352   'GUILD_MEMBER_ADD',
    353   'GUILD_MEMBER_REMOVE',
    354   'GUILD_MEMBER_UPDATE',
    355   'GUILD_MEMBERS_CHUNK',
    356   'GUILD_INTEGRATIONS_UPDATE',
    357   'GUILD_ROLE_CREATE',
    358   'GUILD_ROLE_DELETE',
    359   'GUILD_ROLE_UPDATE',
    360   'GUILD_BAN_ADD',
    361   'GUILD_BAN_REMOVE',
    362   'GUILD_EMOJIS_UPDATE',
    363   'CHANNEL_CREATE',
    364   'CHANNEL_DELETE',
    365   'CHANNEL_UPDATE',
    366   'CHANNEL_PINS_UPDATE',
    367   'MESSAGE_CREATE',
    368   'MESSAGE_DELETE',
    369   'MESSAGE_UPDATE',
    370   'MESSAGE_DELETE_BULK',
    371   'MESSAGE_REACTION_ADD',
    372   'MESSAGE_REACTION_REMOVE',
    373   'MESSAGE_REACTION_REMOVE_ALL',
    374   'MESSAGE_REACTION_REMOVE_EMOJI',
    375   'USER_UPDATE',
    376   'PRESENCE_UPDATE',
    377   'TYPING_START',
    378   'VOICE_STATE_UPDATE',
    379   'VOICE_SERVER_UPDATE',
    380   'WEBHOOKS_UPDATE',
    381 ]);
    382 
    383 /**
    384  * The type of a message, e.g. `DEFAULT`. Here are the available types:
    385  * * DEFAULT
    386  * * RECIPIENT_ADD
    387  * * RECIPIENT_REMOVE
    388  * * CALL
    389  * * CHANNEL_NAME_CHANGE
    390  * * CHANNEL_ICON_CHANGE
    391  * * PINS_ADD
    392  * * GUILD_MEMBER_JOIN
    393  * * USER_PREMIUM_GUILD_SUBSCRIPTION
    394  * * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1
    395  * * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2
    396  * * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3
    397  * * CHANNEL_FOLLOW_ADD
    398  * * GUILD_DISCOVERY_DISQUALIFIED
    399  * * GUILD_DISCOVERY_REQUALIFIED
    400  * @typedef {string} MessageType
    401  */
    402 exports.MessageTypes = [
    403   'DEFAULT',
    404   'RECIPIENT_ADD',
    405   'RECIPIENT_REMOVE',
    406   'CALL',
    407   'CHANNEL_NAME_CHANGE',
    408   'CHANNEL_ICON_CHANGE',
    409   'PINS_ADD',
    410   'GUILD_MEMBER_JOIN',
    411   'USER_PREMIUM_GUILD_SUBSCRIPTION',
    412   'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1',
    413   'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2',
    414   'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3',
    415   'CHANNEL_FOLLOW_ADD',
    416   // 13 isn't yet documented
    417   null,
    418   'GUILD_DISCOVERY_DISQUALIFIED',
    419   'GUILD_DISCOVERY_REQUALIFIED',
    420 ];
    421 
    422 /**
    423  * <info>Bots cannot set a `CUSTOM_STATUS`, it is only for custom statuses received from users</info>
    424  * The type of an activity of a users presence, e.g. `PLAYING`. Here are the available types:
    425  * * PLAYING
    426  * * STREAMING
    427  * * LISTENING
    428  * * WATCHING
    429  * * CUSTOM_STATUS
    430  * @typedef {string} ActivityType
    431  */
    432 exports.ActivityTypes = ['PLAYING', 'STREAMING', 'LISTENING', 'WATCHING', 'CUSTOM_STATUS'];
    433 
    434 exports.ChannelTypes = {
    435   TEXT: 0,
    436   DM: 1,
    437   VOICE: 2,
    438   GROUP: 3,
    439   CATEGORY: 4,
    440   NEWS: 5,
    441   STORE: 6,
    442 };
    443 
    444 exports.ClientApplicationAssetTypes = {
    445   SMALL: 1,
    446   BIG: 2,
    447 };
    448 
    449 exports.Colors = {
    450   DEFAULT: 0x000000,
    451   WHITE: 0xffffff,
    452   AQUA: 0x1abc9c,
    453   GREEN: 0x2ecc71,
    454   BLUE: 0x3498db,
    455   YELLOW: 0xffff00,
    456   PURPLE: 0x9b59b6,
    457   LUMINOUS_VIVID_PINK: 0xe91e63,
    458   GOLD: 0xf1c40f,
    459   ORANGE: 0xe67e22,
    460   RED: 0xe74c3c,
    461   GREY: 0x95a5a6,
    462   NAVY: 0x34495e,
    463   DARK_AQUA: 0x11806a,
    464   DARK_GREEN: 0x1f8b4c,
    465   DARK_BLUE: 0x206694,
    466   DARK_PURPLE: 0x71368a,
    467   DARK_VIVID_PINK: 0xad1457,
    468   DARK_GOLD: 0xc27c0e,
    469   DARK_ORANGE: 0xa84300,
    470   DARK_RED: 0x992d22,
    471   DARK_GREY: 0x979c9f,
    472   DARKER_GREY: 0x7f8c8d,
    473   LIGHT_GREY: 0xbcc0c0,
    474   DARK_NAVY: 0x2c3e50,
    475   BLURPLE: 0x7289da,
    476   GREYPLE: 0x99aab5,
    477   DARK_BUT_NOT_BLACK: 0x2c2f33,
    478   NOT_QUITE_BLACK: 0x23272a,
    479 };
    480 
    481 /**
    482  * The value set for the explicit content filter levels for a guild:
    483  * * DISABLED
    484  * * MEMBERS_WITHOUT_ROLES
    485  * * ALL_MEMBERS
    486  * @typedef {string} ExplicitContentFilterLevel
    487  */
    488 exports.ExplicitContentFilterLevels = ['DISABLED', 'MEMBERS_WITHOUT_ROLES', 'ALL_MEMBERS'];
    489 
    490 /**
    491  * The value set for the verification levels for a guild:
    492  * * NONE
    493  * * LOW
    494  * * MEDIUM
    495  * * HIGH
    496  * * VERY_HIGH
    497  * @typedef {string} VerificationLevel
    498  */
    499 exports.VerificationLevels = ['NONE', 'LOW', 'MEDIUM', 'HIGH', 'VERY_HIGH'];
    500 
    501 /**
    502  * An error encountered while performing an API request. Here are the potential errors:
    503  * * UNKNOWN_ACCOUNT
    504  * * UNKNOWN_APPLICATION
    505  * * UNKNOWN_CHANNEL
    506  * * UNKNOWN_GUILD
    507  * * UNKNOWN_INTEGRATION
    508  * * UNKNOWN_INVITE
    509  * * UNKNOWN_MEMBER
    510  * * UNKNOWN_MESSAGE
    511  * * UNKNOWN_OVERWRITE
    512  * * UNKNOWN_PROVIDER
    513  * * UNKNOWN_ROLE
    514  * * UNKNOWN_TOKEN
    515  * * UNKNOWN_USER
    516  * * UNKNOWN_EMOJI
    517  * * UNKNOWN_WEBHOOK
    518  * * BOT_PROHIBITED_ENDPOINT
    519  * * BOT_ONLY_ENDPOINT
    520  * * MAXIMUM_GUILDS
    521  * * MAXIMUM_FRIENDS
    522  * * MAXIMUM_PINS
    523  * * MAXIMUM_ROLES
    524  * * MAXIMUM_REACTIONS
    525  * * MAXIMUM_CHANNELS
    526  * * MAXIMUM_INVITES
    527  * * UNAUTHORIZED
    528  * * USER_BANNED
    529  * * MISSING_ACCESS
    530  * * INVALID_ACCOUNT_TYPE
    531  * * CANNOT_EXECUTE_ON_DM
    532  * * EMBED_DISABLED
    533  * * CANNOT_EDIT_MESSAGE_BY_OTHER
    534  * * CANNOT_SEND_EMPTY_MESSAGE
    535  * * CANNOT_MESSAGE_USER
    536  * * CANNOT_SEND_MESSAGES_IN_VOICE_CHANNEL
    537  * * CHANNEL_VERIFICATION_LEVEL_TOO_HIGH
    538  * * OAUTH2_APPLICATION_BOT_ABSENT
    539  * * MAXIMUM_OAUTH2_APPLICATIONS
    540  * * INVALID_OAUTH_STATE
    541  * * MISSING_PERMISSIONS
    542  * * INVALID_AUTHENTICATION_TOKEN
    543  * * NOTE_TOO_LONG
    544  * * INVALID_BULK_DELETE_QUANTITY
    545  * * CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL
    546  * * INVALID_OR_TAKEN_INVITE_CODE
    547  * * CANNOT_EXECUTE_ON_SYSTEM_MESSAGE
    548  * * INVALID_OAUTH_TOKEN
    549  * * BULK_DELETE_MESSAGE_TOO_OLD
    550  * * INVALID_FORM_BODY
    551  * * INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT
    552  * * INVALID_API_VERSION
    553  * * REACTION_BLOCKED
    554  * * RESOURCE_OVERLOADED
    555  * @typedef {string} APIError
    556  */
    557 exports.APIErrors = {
    558   UNKNOWN_ACCOUNT: 10001,
    559   UNKNOWN_APPLICATION: 10002,
    560   UNKNOWN_CHANNEL: 10003,
    561   UNKNOWN_GUILD: 10004,
    562   UNKNOWN_INTEGRATION: 10005,
    563   UNKNOWN_INVITE: 10006,
    564   UNKNOWN_MEMBER: 10007,
    565   UNKNOWN_MESSAGE: 10008,
    566   UNKNOWN_OVERWRITE: 10009,
    567   UNKNOWN_PROVIDER: 10010,
    568   UNKNOWN_ROLE: 10011,
    569   UNKNOWN_TOKEN: 10012,
    570   UNKNOWN_USER: 10013,
    571   UNKNOWN_EMOJI: 10014,
    572   UNKNOWN_WEBHOOK: 10015,
    573   BOT_PROHIBITED_ENDPOINT: 20001,
    574   BOT_ONLY_ENDPOINT: 20002,
    575   MAXIMUM_GUILDS: 30001,
    576   MAXIMUM_FRIENDS: 30002,
    577   MAXIMUM_PINS: 30003,
    578   MAXIMUM_ROLES: 30005,
    579   MAXIMUM_REACTIONS: 30010,
    580   MAXIMUM_CHANNELS: 30013,
    581   MAXIMUM_INVITES: 30016,
    582   UNAUTHORIZED: 40001,
    583   USER_BANNED: 40007,
    584   MISSING_ACCESS: 50001,
    585   INVALID_ACCOUNT_TYPE: 50002,
    586   CANNOT_EXECUTE_ON_DM: 50003,
    587   EMBED_DISABLED: 50004,
    588   CANNOT_EDIT_MESSAGE_BY_OTHER: 50005,
    589   CANNOT_SEND_EMPTY_MESSAGE: 50006,
    590   CANNOT_MESSAGE_USER: 50007,
    591   CANNOT_SEND_MESSAGES_IN_VOICE_CHANNEL: 50008,
    592   CHANNEL_VERIFICATION_LEVEL_TOO_HIGH: 50009,
    593   OAUTH2_APPLICATION_BOT_ABSENT: 50010,
    594   MAXIMUM_OAUTH2_APPLICATIONS: 50011,
    595   INVALID_OAUTH_STATE: 50012,
    596   MISSING_PERMISSIONS: 50013,
    597   INVALID_AUTHENTICATION_TOKEN: 50014,
    598   NOTE_TOO_LONG: 50015,
    599   INVALID_BULK_DELETE_QUANTITY: 50016,
    600   CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL: 50019,
    601   INVALID_OR_TAKEN_INVITE_CODE: 50020,
    602   CANNOT_EXECUTE_ON_SYSTEM_MESSAGE: 50021,
    603   INVALID_OAUTH_TOKEN: 50025,
    604   BULK_DELETE_MESSAGE_TOO_OLD: 50034,
    605   INVALID_FORM_BODY: 50035,
    606   INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT: 50036,
    607   INVALID_API_VERSION: 50041,
    608   REACTION_BLOCKED: 90001,
    609   RESOURCE_OVERLOADED: 130000,
    610 };
    611 
    612 /**
    613  * The value set for a guild's default message notifications, e.g. `ALL`. Here are the available types:
    614  * * ALL
    615  * * MENTIONS
    616  * @typedef {string} DefaultMessageNotifications
    617  */
    618 exports.DefaultMessageNotifications = ['ALL', 'MENTIONS'];
    619 
    620 /**
    621  * The value set for a team members's membership state:
    622  * * INVITED
    623  * * ACCEPTED
    624  * @typedef {string} MembershipStates
    625  */
    626 exports.MembershipStates = [
    627   // They start at 1
    628   null,
    629   'INVITED',
    630   'ACCEPTED',
    631 ];
    632 
    633 /**
    634  * The value set for a webhook's type:
    635  * * Incoming
    636  * * Channel Follower
    637  * @typedef {string} WebhookTypes
    638  */
    639 exports.WebhookTypes = [
    640   // They start at 1
    641   null,
    642   'Incoming',
    643   'Channel Follower',
    644 ];
    645 
    646 function keyMirror(arr) {
    647   let tmp = Object.create(null);
    648   for (const value of arr) tmp[value] = value;
    649   return tmp;
    650 }