Downgrade to v13
[vi] cảm giác đau khổ
This commit is contained in:
44
src/util/ActivityFlags.js
Normal file
44
src/util/ActivityFlags.js
Normal file
@@ -0,0 +1,44 @@
|
||||
'use strict';
|
||||
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with an {@link Activity#flags} bitfield.
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class ActivityFlags extends BitField {}
|
||||
|
||||
/**
|
||||
* @name ActivityFlags
|
||||
* @kind constructor
|
||||
* @memberof ActivityFlags
|
||||
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
|
||||
*/
|
||||
|
||||
/**
|
||||
* Numeric activity flags. All available properties:
|
||||
* * `INSTANCE`
|
||||
* * `JOIN`
|
||||
* * `SPECTATE`
|
||||
* * `JOIN_REQUEST`
|
||||
* * `SYNC`
|
||||
* * `PLAY`
|
||||
* * `PARTY_PRIVACY_FRIENDS`
|
||||
* * `PARTY_PRIVACY_VOICE_CHANNEL`
|
||||
* * `EMBEDDED`
|
||||
* @type {Object}
|
||||
* @see {@link https://discord.com/developers/docs/topics/gateway#activity-object-activity-flags}
|
||||
*/
|
||||
ActivityFlags.FLAGS = {
|
||||
INSTANCE: 1 << 0,
|
||||
JOIN: 1 << 1,
|
||||
SPECTATE: 1 << 2,
|
||||
JOIN_REQUEST: 1 << 3,
|
||||
SYNC: 1 << 4,
|
||||
PLAY: 1 << 5,
|
||||
PARTY_PRIVACY_FRIENDS: 1 << 6,
|
||||
PARTY_PRIVACY_VOICE_CHANNEL: 1 << 7,
|
||||
EMBEDDED: 1 << 8,
|
||||
};
|
||||
|
||||
module.exports = ActivityFlags;
|
||||
@@ -1,25 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const { ActivityFlags } = require('discord-api-types/v9');
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with an {@link Activity#flags} bitfield.
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class ActivityFlagsBitField extends BitField {}
|
||||
|
||||
/**
|
||||
* @name ActivityFlagsBitField
|
||||
* @kind constructor
|
||||
* @memberof ActivityFlagsBitField
|
||||
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
|
||||
*/
|
||||
|
||||
/**
|
||||
* Numeric activity flags.
|
||||
* @type {ActivityFlags}
|
||||
*/
|
||||
ActivityFlagsBitField.Flags = ActivityFlags;
|
||||
|
||||
module.exports = ActivityFlagsBitField;
|
||||
48
src/util/ApplicationFlags.js
Normal file
48
src/util/ApplicationFlags.js
Normal file
@@ -0,0 +1,48 @@
|
||||
'use strict';
|
||||
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with a {@link ClientApplication#flags} bitfield.
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class ApplicationFlags extends BitField {}
|
||||
|
||||
/**
|
||||
* @name ApplicationFlags
|
||||
* @kind constructor
|
||||
* @memberof ApplicationFlags
|
||||
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bitfield of the packed bits
|
||||
* @type {number}
|
||||
* @name ApplicationFlags#bitfield
|
||||
*/
|
||||
|
||||
/**
|
||||
* Numeric application flags. All available properties:
|
||||
* * `GATEWAY_PRESENCE`
|
||||
* * `GATEWAY_PRESENCE_LIMITED`
|
||||
* * `GATEWAY_GUILD_MEMBERS`
|
||||
* * `GATEWAY_GUILD_MEMBERS_LIMITED`
|
||||
* * `VERIFICATION_PENDING_GUILD_LIMIT`
|
||||
* * `EMBEDDED`
|
||||
* * `GATEWAY_MESSAGE_CONTENT`
|
||||
* * `GATEWAY_MESSAGE_CONTENT_LIMITED`
|
||||
* @type {Object}
|
||||
* @see {@link https://discord.com/developers/docs/resources/application#application-object-application-flags}
|
||||
*/
|
||||
ApplicationFlags.FLAGS = {
|
||||
GATEWAY_PRESENCE: 1 << 12,
|
||||
GATEWAY_PRESENCE_LIMITED: 1 << 13,
|
||||
GATEWAY_GUILD_MEMBERS: 1 << 14,
|
||||
GATEWAY_GUILD_MEMBERS_LIMITED: 1 << 15,
|
||||
VERIFICATION_PENDING_GUILD_LIMIT: 1 << 16,
|
||||
EMBEDDED: 1 << 17,
|
||||
GATEWAY_MESSAGE_CONTENT: 1 << 18,
|
||||
GATEWAY_MESSAGE_CONTENT_LIMITED: 1 << 19,
|
||||
};
|
||||
|
||||
module.exports = ApplicationFlags;
|
||||
@@ -1,31 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const { ApplicationFlags } = require('discord-api-types/v9');
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with a {@link ClientApplication#flags} bitfield.
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class ApplicationFlagsBitField extends BitField {}
|
||||
|
||||
/**
|
||||
* @name ApplicationFlagsBitField
|
||||
* @kind constructor
|
||||
* @memberof ApplicationFlagsBitField
|
||||
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bitfield of the packed bits
|
||||
* @type {number}
|
||||
* @name ApplicationFlagsBitField#bitfield
|
||||
*/
|
||||
|
||||
/**
|
||||
* Numeric application flags. All available properties:
|
||||
* @type {ApplicationFlags}
|
||||
*/
|
||||
ApplicationFlagsBitField.Flags = ApplicationFlags;
|
||||
|
||||
module.exports = ApplicationFlagsBitField;
|
||||
@@ -101,7 +101,7 @@ class BitField {
|
||||
*/
|
||||
serialize(...hasParams) {
|
||||
const serialized = {};
|
||||
for (const [flag, bit] of Object.entries(this.constructor.Flags)) serialized[flag] = this.has(bit, ...hasParams);
|
||||
for (const [flag, bit] of Object.entries(this.constructor.FLAGS)) serialized[flag] = this.has(bit, ...hasParams);
|
||||
return serialized;
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ class BitField {
|
||||
* @returns {string[]}
|
||||
*/
|
||||
toArray(...hasParams) {
|
||||
return Object.keys(this.constructor.Flags).filter(bit => this.has(bit, ...hasParams));
|
||||
return Object.keys(this.constructor.FLAGS).filter(bit => this.has(bit, ...hasParams));
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
@@ -128,7 +128,7 @@ class BitField {
|
||||
|
||||
/**
|
||||
* Data that can be resolved to give a bitfield. This can be:
|
||||
* * A bit number (this can be a number literal or a value taken from {@link BitField.Flags})
|
||||
* * A bit number (this can be a number literal or a value taken from {@link BitField.FLAGS})
|
||||
* * A string bit number
|
||||
* * An instance of BitField
|
||||
* * An Array of BitFieldResolvable
|
||||
@@ -146,7 +146,7 @@ class BitField {
|
||||
if (bit instanceof BitField) return bit.bitfield;
|
||||
if (Array.isArray(bit)) return bit.map(p => this.resolve(p)).reduce((prev, p) => prev | p, defaultBit);
|
||||
if (typeof bit === 'string') {
|
||||
if (typeof this.Flags[bit] !== 'undefined') return this.Flags[bit];
|
||||
if (typeof this.FLAGS[bit] !== 'undefined') return this.FLAGS[bit];
|
||||
if (!isNaN(bit)) return typeof defaultBit === 'bigint' ? BigInt(bit) : Number(bit);
|
||||
}
|
||||
throw new RangeError('BITFIELD_INVALID', bit);
|
||||
@@ -159,7 +159,7 @@ class BitField {
|
||||
* @type {Object}
|
||||
* @abstract
|
||||
*/
|
||||
BitField.Flags = {};
|
||||
BitField.FLAGS = {};
|
||||
|
||||
/**
|
||||
* @type {number|bigint}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
Default: 0x000000,
|
||||
White: 0xffffff,
|
||||
Aqua: 0x1abc9c,
|
||||
Green: 0x57f287,
|
||||
Blue: 0x3498db,
|
||||
Yellow: 0xfee75c,
|
||||
Purple: 0x9b59b6,
|
||||
LuminousVividPink: 0xe91e63,
|
||||
Fuchsia: 0xeb459e,
|
||||
Gold: 0xf1c40f,
|
||||
Orange: 0xe67e22,
|
||||
Red: 0xed4245,
|
||||
Grey: 0x95a5a6,
|
||||
Navy: 0x34495e,
|
||||
DarkAqua: 0x11806a,
|
||||
DarkGreen: 0x1f8b4c,
|
||||
DarkBlue: 0x206694,
|
||||
DarkPurple: 0x71368a,
|
||||
DarkVividPink: 0xad1457,
|
||||
DarkGold: 0xc27c0e,
|
||||
DarkOrange: 0xa84300,
|
||||
DarkRed: 0x992d22,
|
||||
DarkGrey: 0x979c9f,
|
||||
DarkerGrey: 0x7f8c8d,
|
||||
LightGrey: 0xbcc0c0,
|
||||
DarkNavy: 0x2c3e50,
|
||||
Blurple: 0x5865f2,
|
||||
Greyple: 0x99aab5,
|
||||
DarkButNotBlack: 0x2c2f33,
|
||||
NotQuiteBlack: 0x23272a,
|
||||
};
|
||||
@@ -1,44 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @typedef {Object} BaseComponentData
|
||||
* @property {ComponentType} type
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseComponentData} ActionRowData
|
||||
* @property {ComponentData[]} components
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseComponentData} ButtonComponentData
|
||||
* @property {ButtonStyle} style
|
||||
* @property {?boolean} disabled
|
||||
* @property {string} label
|
||||
* @property {?APIComponentEmoji} emoji
|
||||
* @property {?string} customId
|
||||
* @property {?string} url
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {object} SelectMenuComponentOptionData
|
||||
* @property {string} label
|
||||
* @property {string} value
|
||||
* @property {?string} description
|
||||
* @property {?APIComponentEmoji} emoji
|
||||
* @property {?boolean} default
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseComponentData} SelectMenuComponentData
|
||||
* @property {string} customId
|
||||
* @property {?boolean} disabled
|
||||
* @property {?number} maxValues
|
||||
* @property {?number} minValues
|
||||
* @property {?SelectMenuComponentOptionData[]} options
|
||||
* @property {?string} placeholder
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {ActionRowData|ButtonComponentData|SelectMenuComponentData} ComponentData
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
const { Buffer } = require('node:buffer');
|
||||
const fs = require('node:fs/promises');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const stream = require('node:stream');
|
||||
const { fetch } = require('undici');
|
||||
const fetch = require('node-fetch');
|
||||
const { Error: DiscordError, TypeError } = require('../errors');
|
||||
const Invite = require('../structures/Invite');
|
||||
|
||||
@@ -66,8 +66,8 @@ class DataResolver extends null {
|
||||
if (typeof image === 'string' && image.startsWith('data:')) {
|
||||
return image;
|
||||
}
|
||||
const file = await this.resolveFile(image);
|
||||
return this.resolveBase64(file);
|
||||
const file = await this.resolveFileAsBuffer(image);
|
||||
return DataResolver.resolveBase64(file);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,34 +102,44 @@ class DataResolver extends null {
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves a BufferResolvable to a Buffer.
|
||||
* Resolves a BufferResolvable to a Buffer or a Stream.
|
||||
* @param {BufferResolvable|Stream} resource The buffer or stream resolvable to resolve
|
||||
* @returns {Promise<Buffer>}
|
||||
* @returns {Promise<Buffer|Stream>}
|
||||
*/
|
||||
static async resolveFile(resource) {
|
||||
if (Buffer.isBuffer(resource)) return resource;
|
||||
|
||||
if (resource instanceof stream.Readable) {
|
||||
const buffers = [];
|
||||
for await (const data of resource) buffers.push(data);
|
||||
return Buffer.concat(buffers);
|
||||
}
|
||||
|
||||
if (Buffer.isBuffer(resource) || resource instanceof stream.Readable) return resource;
|
||||
if (typeof resource === 'string') {
|
||||
if (/^https?:\/\//.test(resource)) {
|
||||
const res = await fetch(resource);
|
||||
return Buffer.from(await res.arrayBuffer());
|
||||
return res.body;
|
||||
}
|
||||
|
||||
const file = path.resolve(resource);
|
||||
|
||||
const stats = await fs.stat(file);
|
||||
if (!stats.isFile()) throw new DiscordError('FILE_NOT_FOUND', file);
|
||||
return fs.readFile(file);
|
||||
return new Promise((resolve, reject) => {
|
||||
const file = path.resolve(resource);
|
||||
fs.stat(file, (err, stats) => {
|
||||
if (err) return reject(err);
|
||||
if (!stats.isFile()) return reject(new DiscordError('FILE_NOT_FOUND', file));
|
||||
return resolve(fs.createReadStream(file));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
throw new TypeError('REQ_RESOURCE_TYPE');
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a BufferResolvable to a Buffer.
|
||||
* @param {BufferResolvable|Stream} resource The buffer or stream resolvable to resolve
|
||||
* @returns {Promise<Buffer>}
|
||||
*/
|
||||
static async resolveFileAsBuffer(resource) {
|
||||
const file = await this.resolveFile(resource);
|
||||
if (Buffer.isBuffer(file)) return file;
|
||||
|
||||
const buffers = [];
|
||||
for await (const data of file) buffers.push(data);
|
||||
return Buffer.concat(buffers);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = DataResolver;
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @typedef {Object} EmbedData
|
||||
* @property {?string} title
|
||||
* @property {?EmbedType} type
|
||||
* @property {?string} description
|
||||
* @property {?string} url
|
||||
* @property {?string} timestamp
|
||||
* @property {?number} color
|
||||
* @property {?EmbedFooterData} footer
|
||||
* @property {?EmbedImageData} image
|
||||
* @property {?EmbedImageData} thumbnail
|
||||
* @property {?EmbedProviderData} provider
|
||||
* @property {?EmbedAuthorData} author
|
||||
* @property {?EmbedFieldData[]} fields
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} EmbedFooterData
|
||||
* @property {string} text
|
||||
* @property {?string} iconURL
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} EmbedImageData
|
||||
* @property {?string} url
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} EmbedProviderData
|
||||
* @property {?string} name
|
||||
* @property {?string} url
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} EmbedAuthorData
|
||||
* @property {string} name
|
||||
* @property {?string} url
|
||||
* @property {?string} iconURL
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} EmbedFieldData
|
||||
* @property {string} name
|
||||
* @property {string} value
|
||||
* @property {?boolean} inline
|
||||
*/
|
||||
@@ -1,819 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const {
|
||||
ApplicationCommandType,
|
||||
InteractionType,
|
||||
ComponentType,
|
||||
ButtonStyle,
|
||||
ApplicationCommandOptionType,
|
||||
ChannelType,
|
||||
ApplicationCommandPermissionType,
|
||||
MessageType,
|
||||
GuildNSFWLevel,
|
||||
GuildVerificationLevel,
|
||||
GuildDefaultMessageNotifications,
|
||||
GuildExplicitContentFilter,
|
||||
GuildPremiumTier,
|
||||
GuildScheduledEventStatus,
|
||||
StageInstancePrivacyLevel,
|
||||
GuildMFALevel,
|
||||
TeamMemberMembershipState,
|
||||
GuildScheduledEventEntityType,
|
||||
IntegrationExpireBehavior,
|
||||
AuditLogEvent,
|
||||
} = require('discord-api-types/v9');
|
||||
|
||||
function unknownKeyStrategy(val) {
|
||||
throw new Error(`Could not resolve enum value for ${val}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds a bunch of methods to resolve enum values to readable strings.
|
||||
*/
|
||||
class EnumResolvers extends null {
|
||||
/**
|
||||
* A string that can be resolved to a {@link ChannelType} enum value. Here are the available types:
|
||||
* * GUILD_TEXT
|
||||
* * DM
|
||||
* * GUILD_VOICE
|
||||
* * GROUP_DM
|
||||
* * GUILD_CATEGORY
|
||||
* * GUILD_NEWS
|
||||
* * GUILD_NEWS_THREAD
|
||||
* * GUILD_PUBLIC_THREAD
|
||||
* * GUILD_PRIVATE_THREAD
|
||||
* * GUILD_STAGE_VOICE
|
||||
* @typedef {string} ChannelTypeEnumResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves enum key to {@link ChannelType} enum value
|
||||
* @param {ChannelTypeEnumResolvable|ChannelType} key The key to resolve
|
||||
* @returns {ChannelType}
|
||||
*/
|
||||
static resolveChannelType(key) {
|
||||
switch (key) {
|
||||
case 'GUILD_TEXT':
|
||||
return ChannelType.GuildText;
|
||||
case 'DM':
|
||||
return ChannelType.DM;
|
||||
case 'GUILD_VOICE':
|
||||
return ChannelType.GuildVoice;
|
||||
case 'GROUP_DM':
|
||||
return ChannelType.GroupDM;
|
||||
case 'GUILD_CATEGORY':
|
||||
return ChannelType.GuildCategory;
|
||||
case 'GUILD_NEWS':
|
||||
return ChannelType.GuildNews;
|
||||
case 'GUILD_NEWS_THREAD':
|
||||
return ChannelType.GuildNewsThread;
|
||||
case 'GUILD_PUBLIC_THREAD':
|
||||
return ChannelType.GuildPublicThread;
|
||||
case 'GUILD_PRIVATE_THREAD':
|
||||
return ChannelType.GuildPrivateThread;
|
||||
case 'GUILD_STAGE_VOICE':
|
||||
return ChannelType.GuildStageVoice;
|
||||
default:
|
||||
return unknownKeyStrategy(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that can be resolved to an {@link InteractionType} enum value. Here are the available types:
|
||||
* * PING
|
||||
* * APPLICATION_COMMAND
|
||||
* * MESSAGE_COMPONENT
|
||||
* * APPLICATION_COMMAND_AUTOCOMPLETE
|
||||
* @typedef {string} InteractionTypeEnumResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves enum key to {@link InteractionType} enum value
|
||||
* @param {InteractionTypeEnumResolvable|InteractionType} key The key to resolve
|
||||
* @returns {InteractionType}
|
||||
*/
|
||||
static resolveInteractionType(key) {
|
||||
switch (key) {
|
||||
case 'PING':
|
||||
return InteractionType.Ping;
|
||||
case 'APPLICATION_COMMAND':
|
||||
return InteractionType.ApplicationCommand;
|
||||
case 'MESSAGE_COMPONENT':
|
||||
return InteractionType.MessageComponent;
|
||||
case 'APPLICATION_COMMAND_AUTOCOMPLETE':
|
||||
return InteractionType.ApplicationCommandAutocomplete;
|
||||
default:
|
||||
return unknownKeyStrategy(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that can be resolved to an {@link ApplicationCommandType} enum value. Here are the available types:
|
||||
* * CHAT_INPUT
|
||||
* * USER
|
||||
* * MESSAGE
|
||||
* @typedef {string} ApplicationCommandTypeEnumResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves enum key to {@link ApplicationCommandType} enum value
|
||||
* @param {ApplicationCommandTypeEnumResolvable|ApplicationCommandType} key The key to resolve
|
||||
* @returns {ApplicationCommandType}
|
||||
*/
|
||||
static resolveApplicationCommandType(key) {
|
||||
switch (key) {
|
||||
case 'CHAT_INPUT':
|
||||
return ApplicationCommandType.ChatInput;
|
||||
case 'USER':
|
||||
return ApplicationCommandType.User;
|
||||
case 'MESSAGE':
|
||||
return ApplicationCommandType.Message;
|
||||
default:
|
||||
return unknownKeyStrategy(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that can be resolved to an {@link ApplicationCommandOptionType} enum value. Here are the available types:
|
||||
* * SUB_COMMAND
|
||||
* * SUB_COMMAND_GROUP
|
||||
* * STRING
|
||||
* * INTEGER
|
||||
* * BOOLEAN
|
||||
* * USER
|
||||
* * CHANNEL
|
||||
* * ROLE
|
||||
* * NUMBER
|
||||
* * MENTIONABLE
|
||||
* @typedef {string} ApplicationCommandOptionTypeEnumResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves enum key to {@link ApplicationCommandOptionType} enum value
|
||||
* @param {ApplicationCommandOptionTypeEnumResolvable|ApplicationCommandOptionType} key The key to resolve
|
||||
* @returns {ApplicationCommandOptionType}
|
||||
*/
|
||||
static resolveApplicationCommandOptionType(key) {
|
||||
switch (key) {
|
||||
case 'SUB_COMMAND':
|
||||
return ApplicationCommandOptionType.Subcommand;
|
||||
case 'SUB_COMMAND_GROUP':
|
||||
return ApplicationCommandOptionType.SubcommandGroup;
|
||||
case 'STRING':
|
||||
return ApplicationCommandOptionType.String;
|
||||
case 'INTEGER':
|
||||
return ApplicationCommandOptionType.Integer;
|
||||
case 'BOOLEAN':
|
||||
return ApplicationCommandOptionType.Boolean;
|
||||
case 'USER':
|
||||
return ApplicationCommandOptionType.User;
|
||||
case 'CHANNEL':
|
||||
return ApplicationCommandOptionType.Channel;
|
||||
case 'ROLE':
|
||||
return ApplicationCommandOptionType.Role;
|
||||
case 'NUMBER':
|
||||
return ApplicationCommandOptionType.Number;
|
||||
case 'MENTIONABLE':
|
||||
return ApplicationCommandOptionType.Mentionable;
|
||||
default:
|
||||
return unknownKeyStrategy(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that can be resolved to an {@link ApplicationCommandPermissionType} enum value.
|
||||
* Here are the available types:
|
||||
* * ROLE
|
||||
* * USER
|
||||
* @typedef {string} ApplicationCommandPermissionTypeEnumResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves enum key to {@link ApplicationCommandPermissionType} enum value
|
||||
* @param {ApplicationCommandPermissionTypeEnumResolvable|ApplicationCommandPermissionType} key The key to resolve
|
||||
* @returns {ApplicationCommandPermissionType}
|
||||
*/
|
||||
static resolveApplicationCommandPermissionType(key) {
|
||||
switch (key) {
|
||||
case 'ROLE':
|
||||
return ApplicationCommandPermissionType.Role;
|
||||
case 'USER':
|
||||
return ApplicationCommandPermissionType.User;
|
||||
default:
|
||||
return unknownKeyStrategy(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that can be resolved to a {@link ComponentType} enum value. Here are the available types:
|
||||
* * ACTION_ROW
|
||||
* * BUTTON
|
||||
* * SELECT_MENU
|
||||
* @typedef {string} ComponentTypeEnumResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves enum key to {@link ComponentType} enum value
|
||||
* @param {ComponentTypeEnumResolvable|ComponentType} key The key to resolve
|
||||
* @returns {ComponentType}
|
||||
*/
|
||||
static resolveComponentType(key) {
|
||||
switch (key) {
|
||||
case 'ACTION_ROW':
|
||||
return ComponentType.ActionRow;
|
||||
case 'BUTTON':
|
||||
return ComponentType.Button;
|
||||
case 'SELECT_MENU':
|
||||
return ComponentType.SelectMenu;
|
||||
default:
|
||||
return unknownKeyStrategy(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that can be resolved to a {@link ButtonStyle} enum value. Here are the available types:
|
||||
* * PRIMARY
|
||||
* * SECONDARY
|
||||
* * SUCCESS
|
||||
* * DANGER
|
||||
* * LINK
|
||||
* @typedef {string} ButtonStyleEnumResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves enum key to {@link ButtonStyle} enum value
|
||||
* @param {ButtonStyleEnumResolvable|ButtonStyle} key The key to resolve
|
||||
* @returns {ButtonStyle}
|
||||
*/
|
||||
static resolveButtonStyle(key) {
|
||||
switch (key) {
|
||||
case 'PRIMARY':
|
||||
return ButtonStyle.Primary;
|
||||
case 'SECONDARY':
|
||||
return ButtonStyle.Secondary;
|
||||
case 'SUCCESS':
|
||||
return ButtonStyle.Success;
|
||||
case 'DANGER':
|
||||
return ButtonStyle.Danger;
|
||||
case 'LINK':
|
||||
return ButtonStyle.Link;
|
||||
default:
|
||||
return unknownKeyStrategy(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that can be resolved to a {@link MessageType} enum value. Here are the available types:
|
||||
* * DEFAULT
|
||||
* * RECIPIENT_ADD
|
||||
* * RECIPIENT_REMOVE
|
||||
* * CALL
|
||||
* * CHANNEL_NAME_CHANGE
|
||||
* * CHANNEL_ICON_CHANGE
|
||||
* * CHANNEL_PINNED_MESSAGE
|
||||
* * 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
|
||||
* * THREAD_CREATED
|
||||
* * REPLY
|
||||
* * CHAT_INPUT_COMMAND
|
||||
* * THREAD_STARTER_MESSAGE
|
||||
* * GUILD_INVITE_REMINDER
|
||||
* * CONTEXT_MENU_COMMAND
|
||||
* @typedef {string} MessageTypeEnumResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves enum key to {@link MessageType} enum value
|
||||
* @param {MessageTypeEnumResolvable|MessageType} key The key to lookup
|
||||
* @returns {MessageType}
|
||||
*/
|
||||
static resolveMessageType(key) {
|
||||
switch (key) {
|
||||
case 'DEFAULT':
|
||||
return MessageType.Default;
|
||||
case 'RECIPIENT_ADD':
|
||||
return MessageType.RecipientAdd;
|
||||
case 'RECIPIENT_REMOVE':
|
||||
return MessageType.RecipientRemove;
|
||||
case 'CALL':
|
||||
return MessageType.Call;
|
||||
case 'CHANNEL_NAME_CHANGE':
|
||||
return MessageType.ChannelNameChange;
|
||||
case 'CHANNEL_ICON_CHANGE':
|
||||
return MessageType.ChannelIconChange;
|
||||
case 'CHANNEL_PINNED_MESSAGE':
|
||||
return MessageType.ChannelPinnedMessage;
|
||||
case 'GUILD_MEMBER_JOIN':
|
||||
return MessageType.GuildMemberJoin;
|
||||
case 'USER_PREMIUM_GUILD_SUBSCRIPTION':
|
||||
return MessageType.UserPremiumGuildSubscription;
|
||||
case 'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1':
|
||||
return MessageType.UserPremiumGuildSubscriptionTier1;
|
||||
case 'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2':
|
||||
return MessageType.UserPremiumGuildSubscriptionTier2;
|
||||
case 'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3':
|
||||
return MessageType.UserPremiumGuildSubscriptionTier3;
|
||||
case 'CHANNEL_FOLLOW_ADD':
|
||||
return MessageType.ChannelFollowAdd;
|
||||
case 'GUILD_DISCOVERY_DISQUALIFIED':
|
||||
return MessageType.GuildDiscoveryDisqualified;
|
||||
case 'GUILD_DISCOVERY_REQUALIFIED':
|
||||
return MessageType.GuildDiscoveryRequalified;
|
||||
case 'GUILD_DISCOVERY_GRACE_PERIOD_INITIAL_WARNING':
|
||||
return MessageType.GuildDiscoveryGracePeriodInitialWarning;
|
||||
case 'GUILD_DISCOVERY_GRACE_PERIOD_FINAL_WARNING':
|
||||
return MessageType.GuildDiscoveryGracePeriodFinalWarning;
|
||||
case 'THREAD_CREATED':
|
||||
return MessageType.ThreadCreated;
|
||||
case 'REPLY':
|
||||
return MessageType.Reply;
|
||||
case 'CHAT_INPUT_COMMAND':
|
||||
return MessageType.ChatInputCommand;
|
||||
case 'THREAD_STARTER_MESSAGE':
|
||||
return MessageType.ThreadStarterMessage;
|
||||
case 'GUILD_INVITE_REMINDER':
|
||||
return MessageType.GuildInviteReminder;
|
||||
case 'CONTEXT_MENU_COMMAND':
|
||||
return MessageType.ContextMenuCommand;
|
||||
default:
|
||||
return unknownKeyStrategy(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that can be resolved to a {@link GuildNSFWLevel} enum value. Here are the available types:
|
||||
* * DEFAULT
|
||||
* * EXPLICIT
|
||||
* * SAFE
|
||||
* * AGE_RESTRICTED
|
||||
* @typedef {string} GuildNSFWLevelEnumResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves enum key to {@link GuildNSFWLevel} enum value
|
||||
* @param {GuildNSFWLevelEnumResolvable|GuildNSFWLevel} key The key to lookup
|
||||
* @returns {GuildNSFWLevel}
|
||||
*/
|
||||
static resolveGuildNSFWLevel(key) {
|
||||
switch (key) {
|
||||
case 'DEFAULT':
|
||||
return GuildNSFWLevel.Default;
|
||||
case 'EXPLICIT':
|
||||
return GuildNSFWLevel.Explicit;
|
||||
case 'SAFE':
|
||||
return GuildNSFWLevel.Safe;
|
||||
case 'AGE_RESTRICTED':
|
||||
return GuildNSFWLevel.AgeRestricted;
|
||||
default:
|
||||
return unknownKeyStrategy(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that can be resolved to a {@link GuildVerificationLevel} enum value. Here are the available types:
|
||||
* * NONE
|
||||
* * LOW
|
||||
* * MEDIUM
|
||||
* * HIGH
|
||||
* * VERY_HIGH
|
||||
* @typedef {string} GuildVerificationLevelEnumResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves enum key to {@link GuildVerificationLevel} enum value
|
||||
* @param {GuildVerificationLevelEnumResolvable|GuildVerificationLevel} key The key to lookup
|
||||
* @returns {GuildVerificationLevel}
|
||||
*/
|
||||
static resolveGuildVerificationLevel(key) {
|
||||
switch (key) {
|
||||
case 'NONE':
|
||||
return GuildVerificationLevel.None;
|
||||
case 'LOW':
|
||||
return GuildVerificationLevel.Low;
|
||||
case 'MEDIUM':
|
||||
return GuildVerificationLevel.Medium;
|
||||
case 'HIGH':
|
||||
return GuildVerificationLevel.High;
|
||||
case 'VERY_HIGH':
|
||||
return GuildVerificationLevel.VeryHigh;
|
||||
default:
|
||||
return unknownKeyStrategy(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that can be resolved to a {@link GuildDefaultMessageNotifications} enum value.
|
||||
* Here are the available types:
|
||||
* * ALL_MESSAGES
|
||||
* * ONLY_MENTIONS
|
||||
* @typedef {string} GuildDefaultMessageNotificationsEnumResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves enum key to {@link GuildDefaultMessageNotifications} enum value
|
||||
* @param {GuildDefaultMessageNotificationsEnumResolvable|GuildDefaultMessageNotifications} key The key to lookup
|
||||
* @returns {GuildDefaultMessageNotifications}
|
||||
*/
|
||||
static resolveGuildDefaultMessageNotifications(key) {
|
||||
switch (key) {
|
||||
case 'ALL_MESSAGES':
|
||||
return GuildDefaultMessageNotifications.AllMessages;
|
||||
case 'ONLY_MENTIONS':
|
||||
return GuildDefaultMessageNotifications.OnlyMentions;
|
||||
default:
|
||||
return unknownKeyStrategy(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that can be resolved to a {@link GuildExplicitContentFilter} enum value. Here are the available types:
|
||||
* * DISABLED
|
||||
* * MEMBERS_WITHOUT_ROLES
|
||||
* * ALL_MEMBERS
|
||||
* @typedef {string} GuildExplicitContentFilterEnumResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves enum key to {@link GuildExplicitContentFilter} enum value
|
||||
* @param {GuildExplicitContentFilterEnumResolvable|GuildExplicitContentFilter} key The key to lookup
|
||||
* @returns {GuildExplicitContentFilter}
|
||||
*/
|
||||
static resolveGuildExplicitContentFilter(key) {
|
||||
switch (key) {
|
||||
case 'DISABLED':
|
||||
return GuildExplicitContentFilter.Disabled;
|
||||
case 'MEMBERS_WITHOUT_ROLES':
|
||||
return GuildExplicitContentFilter.MembersWithoutRoles;
|
||||
case 'ALL_MEMBERS':
|
||||
return GuildExplicitContentFilter.AllMembers;
|
||||
default:
|
||||
return unknownKeyStrategy(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that can be resolved to a {@link GuildPremiumTier} enum value. Here are the available types:
|
||||
* * NONE
|
||||
* * TIER_1
|
||||
* * TIER_2
|
||||
* * TIER_3
|
||||
* @typedef {string} GuildPremiumTierEnumResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves enum key to {@link GuildPremiumTier} enum value
|
||||
* @param {GuildPremiumTierEnumResolvable|GuildPremiumTier} key The key to lookup
|
||||
* @returns {GuildPremiumTier}
|
||||
*/
|
||||
static resolveGuildPremiumTier(key) {
|
||||
switch (key) {
|
||||
case 'NONE':
|
||||
return GuildPremiumTier.None;
|
||||
case 'TIER_1':
|
||||
return GuildPremiumTier.Tier1;
|
||||
case 'TIER_2':
|
||||
return GuildPremiumTier.Tier2;
|
||||
case 'TIER_3':
|
||||
return GuildPremiumTier.Tier3;
|
||||
default:
|
||||
return unknownKeyStrategy(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that can be resolved to a {@link GuildScheduledEventStatus} enum value. Here are the available types:
|
||||
* * SCHEDULED
|
||||
* * ACTIVE
|
||||
* * COMPLETED
|
||||
* * CANCELED
|
||||
* @typedef {string} GuildScheduledEventStatusEnumResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves enum key to {@link GuildScheduledEventStatus} enum value
|
||||
* @param {GuildScheduledEventStatusEnumResolvable|GuildScheduledEventStatus} key The key to lookup
|
||||
* @returns {GuildScheduledEventStatus}
|
||||
*/
|
||||
static resolveGuildScheduledEventStatus(key) {
|
||||
switch (key) {
|
||||
case 'SCHEDULED':
|
||||
return GuildScheduledEventStatus.Scheduled;
|
||||
case 'ACTIVE':
|
||||
return GuildScheduledEventStatus.Active;
|
||||
case 'COMPLETED':
|
||||
return GuildScheduledEventStatus.Completed;
|
||||
case 'CANCELED':
|
||||
return GuildScheduledEventStatus.Canceled;
|
||||
default:
|
||||
return unknownKeyStrategy(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that can be resolved to a {@link StageInstancePrivacyLevel} enum value. Here are the available types:
|
||||
* * PUBLIC
|
||||
* * GUILD_ONLY
|
||||
* @typedef {string} StageInstancePrivacyLevelEnumResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves enum key to {@link StageInstancePrivacyLevel} enum value
|
||||
* @param {StageInstancePrivacyLevelEnumResolvable|StageInstancePrivacyLevel} key The key to lookup
|
||||
* @returns {StageInstancePrivacyLevel}
|
||||
*/
|
||||
static resolveStageInstancePrivacyLevel(key) {
|
||||
switch (key) {
|
||||
case 'PUBLIC':
|
||||
return StageInstancePrivacyLevel.Public;
|
||||
case 'GUILD_ONLY':
|
||||
return StageInstancePrivacyLevel.GuildOnly;
|
||||
default:
|
||||
return unknownKeyStrategy(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that can be resolved to a {@link GuildMFALevel} enum value. Here are the available types:
|
||||
* * NONE
|
||||
* * ELEVATED
|
||||
* @typedef {string} GuildMFALevelEnumResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves enum key to {@link GuildMFALevel} enum value
|
||||
* @param {GuildMFALevelEnumResolvable|GuildMFALevel} key The key to lookup
|
||||
* @returns {GuildMFALevel}
|
||||
*/
|
||||
static resolveGuildMFALevel(key) {
|
||||
switch (key) {
|
||||
case 'NONE':
|
||||
return GuildMFALevel.None;
|
||||
case 'ELEVATED':
|
||||
return GuildMFALevel.Elevated;
|
||||
default:
|
||||
return unknownKeyStrategy(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that can be resolved to a {@link TeamMemberMembershipState} enum value. Here are the available types:
|
||||
* * INVITED
|
||||
* * ACCEPTED
|
||||
* @typedef {string} TeamMemberMembershipStateEnumResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves enum key to {@link TeamMemberMembershipState} enum value
|
||||
* @param {TeamMemberMembershipStateEnumResolvable|TeamMemberMembershipState} key The key to lookup
|
||||
* @returns {TeamMemberMembershipState}
|
||||
*/
|
||||
static resolveTeamMemberMembershipState(key) {
|
||||
switch (key) {
|
||||
case 'INVITED':
|
||||
return TeamMemberMembershipState.Invited;
|
||||
case 'ACCEPTED':
|
||||
return TeamMemberMembershipState.Accepted;
|
||||
default:
|
||||
return unknownKeyStrategy(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that can be resolved to a {@link GuildScheduledEventEntityType} enum value. Here are the available types:
|
||||
* * STAGE_INSTANCE
|
||||
* * VOICE
|
||||
* * EXTERNAL
|
||||
* @typedef {string} GuildScheduledEventEntityTypeEnumResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves enum key to {@link GuildScheduledEventEntityType} enum value
|
||||
* @param {GuildScheduledEventEntityTypeEnumResolvable|GuildScheduledEventEntityType} key The key to lookup
|
||||
* @returns {GuildScheduledEventEntityType}
|
||||
*/
|
||||
static resolveGuildScheduledEventEntityType(key) {
|
||||
switch (key) {
|
||||
case 'STAGE_INSTANCE':
|
||||
return GuildScheduledEventEntityType.StageInstance;
|
||||
case 'VOICE':
|
||||
return GuildScheduledEventEntityType.Voice;
|
||||
case 'EXTERNAL':
|
||||
return GuildScheduledEventEntityType.External;
|
||||
default:
|
||||
return unknownKeyStrategy(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that can be resolved to a {@link IntegrationExpireBehavior} enum value. Here are the available types:
|
||||
* * REMOVE_ROLE
|
||||
* * KICK
|
||||
* @typedef {string} IntegrationExpireBehaviorEnumResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves enum key to {@link IntegrationExpireBehavior} enum value
|
||||
* @param {IntegrationExpireBehaviorEnumResolvable|IntegrationExpireBehavior} key The key to lookup
|
||||
* @returns {IntegrationExpireBehavior}
|
||||
*/
|
||||
static resolveIntegrationExpireBehavior(key) {
|
||||
switch (key) {
|
||||
case 'REMOVE_ROLE':
|
||||
return IntegrationExpireBehavior.RemoveRole;
|
||||
case 'KICK':
|
||||
return IntegrationExpireBehavior.Kick;
|
||||
default:
|
||||
return unknownKeyStrategy(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A string that can be resolved to a {@link AuditLogEvent} enum value. Here are the available types:
|
||||
* * GUILD_UPDATE
|
||||
* * CHANNEL_CREATE
|
||||
* * CHANNEL_UPDATE
|
||||
* * CHANNEL_DELETE
|
||||
* * CHANNEL_OVERWRITE_CREATE
|
||||
* * CHANNEL_OVERWRITE_UPDATE
|
||||
* * CHANNEL_OVERWRITE_DELETE
|
||||
* * MEMBER_KICK
|
||||
* * MEMBER_PRUNE
|
||||
* * MEMBER_BAN_ADD
|
||||
* * MEMBER_BAN_REMOVE
|
||||
* * MEMBER_UPDATE
|
||||
* * MEMBER_ROLE_UPDATE
|
||||
* * MEMBER_MOVE
|
||||
* * MEMBER_DISCONNECT
|
||||
* * BOT_ADD
|
||||
* * ROLE_CREATE
|
||||
* * ROLE_UPDATE
|
||||
* * ROLE_DELETE
|
||||
* * INVITE_CREATE
|
||||
* * INVITE_UPDATE
|
||||
* * INVITE_DELETE
|
||||
* * WEBHOOK_CREATE
|
||||
* * WEBHOOK_UPDATE
|
||||
* * WEBHOOK_DELETE
|
||||
* * INTEGRATION_CREATE
|
||||
* * INTEGRATION_UPDATE
|
||||
* * INTEGRATION_DELETE
|
||||
* * STAGE_INSTANCE_CREATE
|
||||
* * STAGE_INSTANCE_UPDATE
|
||||
* * STAGE_INSTANCE_DELETE
|
||||
* * STICKER_CREATE
|
||||
* * STICKER_UPDATE
|
||||
* * STICKER_DELETE
|
||||
* * GUILD_SCHEDULED_EVENT_CREATE
|
||||
* * GUILD_SCHEDULED_EVENT_UPDATE
|
||||
* * GUILD_SCHEDULED_EVENT_DELETE
|
||||
* * THREAD_CREATE
|
||||
* * THREAD_UPDATE
|
||||
* * THREAD_DELETE
|
||||
* @typedef {string} AuditLogEventEnumResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves enum key to {@link AuditLogEvent} enum value
|
||||
* @param {AuditLogEventEnumResolvable|AuditLogEvent} key The key to lookup
|
||||
* @returns {AuditLogEvent}
|
||||
*/
|
||||
static resolveAuditLogEvent(key) {
|
||||
switch (key) {
|
||||
case 'GUILD_UPDATE':
|
||||
return AuditLogEvent.GuildUpdate;
|
||||
case 'CHANNEL_CREATE':
|
||||
return AuditLogEvent.ChannelCreate;
|
||||
case 'CHANNEL_UPDATE':
|
||||
return AuditLogEvent.ChannelUpdate;
|
||||
case 'CHANNEL_DELETE':
|
||||
return AuditLogEvent.ChannelDelete;
|
||||
case 'CHANNEL_OVERWRITE_CREATE':
|
||||
return AuditLogEvent.ChannelOverwriteCreate;
|
||||
case 'CHANNEL_OVERWRITE_UPDATE':
|
||||
return AuditLogEvent.ChannelOverwriteUpdate;
|
||||
case 'CHANNEL_OVERWRITE_DELETE':
|
||||
return AuditLogEvent.ChannelOverwriteDelete;
|
||||
case 'MEMBER_KICK':
|
||||
return AuditLogEvent.MemberKick;
|
||||
case 'MEMBER_PRUNE':
|
||||
return AuditLogEvent.MemberPrune;
|
||||
case 'MEMBER_BAN_ADD':
|
||||
return AuditLogEvent.MemberBanAdd;
|
||||
case 'MEMBER_BAN_REMOVE':
|
||||
return AuditLogEvent.MemberBanRemove;
|
||||
case 'MEMBER_UPDATE':
|
||||
return AuditLogEvent.MemberUpdate;
|
||||
case 'MEMBER_ROLE_UPDATE':
|
||||
return AuditLogEvent.MemberRoleUpdate;
|
||||
case 'MEMBER_MOVE':
|
||||
return AuditLogEvent.MemberMove;
|
||||
case 'MEMBER_DISCONNECT':
|
||||
return AuditLogEvent.MemberDisconnect;
|
||||
case 'BOT_ADD':
|
||||
return AuditLogEvent.BotAdd;
|
||||
case 'ROLE_CREATE':
|
||||
return AuditLogEvent.RoleCreate;
|
||||
case 'ROLE_UPDATE':
|
||||
return AuditLogEvent.RoleUpdate;
|
||||
case 'ROLE_DELETE':
|
||||
return AuditLogEvent.RoleDelete;
|
||||
case 'INVITE_CREATE':
|
||||
return AuditLogEvent.InviteCreate;
|
||||
case 'INVITE_UPDATE':
|
||||
return AuditLogEvent.InviteUpdate;
|
||||
case 'INVITE_DELETE':
|
||||
return AuditLogEvent.InviteDelete;
|
||||
case 'WEBHOOK_CREATE':
|
||||
return AuditLogEvent.WebhookCreate;
|
||||
case 'WEBHOOK_UPDATE':
|
||||
return AuditLogEvent.WebhookUpdate;
|
||||
case 'WEBHOOK_DELETE':
|
||||
return AuditLogEvent.WebhookDelete;
|
||||
case 'EMOJI_CREATE':
|
||||
return AuditLogEvent.EmojiCreate;
|
||||
case 'EMOJI_UPDATE':
|
||||
return AuditLogEvent.EmojiUpdate;
|
||||
case 'EMOJI_DELETE':
|
||||
return AuditLogEvent.EmojiDelete;
|
||||
case 'MESSAGE_DELETE':
|
||||
return AuditLogEvent.MessageDelete;
|
||||
case 'MESSAGE_BULK_DELETE':
|
||||
return AuditLogEvent.MessageBulkDelete;
|
||||
case 'MESSAGE_PIN':
|
||||
return AuditLogEvent.MessagePin;
|
||||
case 'MESSAGE_UNPIN':
|
||||
return AuditLogEvent.MessageUnpin;
|
||||
case 'INTEGRATION_CREATE':
|
||||
return AuditLogEvent.IntegrationCreate;
|
||||
case 'INTEGRATION_UPDATE':
|
||||
return AuditLogEvent.IntegrationUpdate;
|
||||
case 'INTEGRATION_DELETE':
|
||||
return AuditLogEvent.IntegrationDelete;
|
||||
case 'STAGE_INSTANCE_CREATE':
|
||||
return AuditLogEvent.StageInstanceCreate;
|
||||
case 'STAGE_INSTANCE_UPDATE':
|
||||
return AuditLogEvent.StageInstanceUpdate;
|
||||
case 'STAGE_INSTANCE_DELETE':
|
||||
return AuditLogEvent.StageInstanceDelete;
|
||||
case 'STICKER_CREATE':
|
||||
return AuditLogEvent.StickerCreate;
|
||||
case 'STICKER_UPDATE':
|
||||
return AuditLogEvent.StickerUpdate;
|
||||
case 'STICKER_DELETE':
|
||||
return AuditLogEvent.StickerDelete;
|
||||
case 'GUILD_SCHEDULED_EVENT_CREATE':
|
||||
return AuditLogEvent.GuildScheduledEventCreate;
|
||||
case 'GUILD_SCHEDULED_EVENT_UPDATE':
|
||||
return AuditLogEvent.GuildScheduledEventUpdate;
|
||||
case 'GUILD_SCHEDULED_EVENT_DELETE':
|
||||
return AuditLogEvent.GuildScheduledEventDelete;
|
||||
case 'THREAD_CREATE':
|
||||
return AuditLogEvent.ThreadCreate;
|
||||
case 'THREAD_UPDATE':
|
||||
return AuditLogEvent.ThreadUpdate;
|
||||
case 'THREAD_DELETE':
|
||||
return AuditLogEvent.ThreadDelete;
|
||||
default:
|
||||
return unknownKeyStrategy(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Precondition logic wrapper
|
||||
function preconditioner(func) {
|
||||
return key => {
|
||||
if (typeof key !== 'string' && typeof key !== 'number') {
|
||||
throw new Error('Enum value must be string or number');
|
||||
}
|
||||
|
||||
if (typeof key === 'number') {
|
||||
return key;
|
||||
}
|
||||
|
||||
return func(key);
|
||||
};
|
||||
}
|
||||
|
||||
// Injects wrapper into class static methods.
|
||||
function applyPreconditioner(obj) {
|
||||
for (const name in Object.getOwnPropertyNames(obj)) {
|
||||
if (typeof obj[name] !== 'function') {
|
||||
return;
|
||||
}
|
||||
|
||||
obj[name] = preconditioner(obj[name]);
|
||||
}
|
||||
}
|
||||
|
||||
// Apply precondition logic
|
||||
applyPreconditioner(EnumResolvers);
|
||||
|
||||
module.exports = EnumResolvers;
|
||||
@@ -1,13 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
function createEnum(keys) {
|
||||
const obj = {};
|
||||
for (const [index, key] of keys.entries()) {
|
||||
if (key === null) continue;
|
||||
obj[key] = index;
|
||||
obj[index] = key;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
module.exports = { createEnum };
|
||||
@@ -1,72 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
ClientReady: 'ready',
|
||||
GuildCreate: 'guildCreate',
|
||||
GuildDelete: 'guildDelete',
|
||||
GuildUpdate: 'guildUpdate',
|
||||
GuildUnavailable: 'guildUnavailable',
|
||||
GuildMemberAdd: 'guildMemberAdd',
|
||||
GuildMemberRemove: 'guildMemberRemove',
|
||||
GuildMemberUpdate: 'guildMemberUpdate',
|
||||
GuildMemberAvailable: 'guildMemberAvailable',
|
||||
GuildMembersChunk: 'guildMembersChunk',
|
||||
GuildIntegrationsUpdate: 'guildIntegrationsUpdate',
|
||||
GuildRoleCreate: 'roleCreate',
|
||||
GuildRoleDelete: 'roleDelete',
|
||||
InviteCreate: 'inviteCreate',
|
||||
InviteDelete: 'inviteDelete',
|
||||
GuildRoleUpdate: 'roleUpdate',
|
||||
GuildEmojiCreate: 'emojiCreate',
|
||||
GuildEmojiDelete: 'emojiDelete',
|
||||
GuildEmojiUpdate: 'emojiUpdate',
|
||||
GuildBanAdd: 'guildBanAdd',
|
||||
GuildBanRemove: 'guildBanRemove',
|
||||
ChannelCreate: 'channelCreate',
|
||||
ChannelDelete: 'channelDelete',
|
||||
ChannelUpdate: 'channelUpdate',
|
||||
ChannelPinsUpdate: 'channelPinsUpdate',
|
||||
MessageCreate: 'messageCreate',
|
||||
MessageDelete: 'messageDelete',
|
||||
MessageUpdate: 'messageUpdate',
|
||||
MessageBulkDelete: 'messageDeleteBulk',
|
||||
MessageReactionAdd: 'messageReactionAdd',
|
||||
MessageReactionRemove: 'messageReactionRemove',
|
||||
MessageReactionRemoveAll: 'messageReactionRemoveAll',
|
||||
MessageReactionRemoveEmoji: 'messageReactionRemoveEmoji',
|
||||
ThreadCreate: 'threadCreate',
|
||||
ThreadDelete: 'threadDelete',
|
||||
ThreadUpdate: 'threadUpdate',
|
||||
ThreadListSync: 'threadListSync',
|
||||
ThreadMemberUpdate: 'threadMemberUpdate',
|
||||
ThreadMembersUpdate: 'threadMembersUpdate',
|
||||
UserUpdate: 'userUpdate',
|
||||
PresenceUpdate: 'presenceUpdate',
|
||||
VoiceServerUpdate: 'voiceServerUpdate',
|
||||
VoiceStateUpdate: 'voiceStateUpdate',
|
||||
TypingStart: 'typingStart',
|
||||
WebhooksUpdate: 'webhookUpdate',
|
||||
InteractionCreate: 'interactionCreate',
|
||||
Error: 'error',
|
||||
Warn: 'warn',
|
||||
Debug: 'debug',
|
||||
CacheSweep: 'cacheSweep',
|
||||
ShardDisconnect: 'shardDisconnect',
|
||||
ShardError: 'shardError',
|
||||
ShardReconnecting: 'shardReconnecting',
|
||||
ShardReady: 'shardReady',
|
||||
ShardResume: 'shardResume',
|
||||
Invalidated: 'invalidated',
|
||||
Raw: 'raw',
|
||||
StageInstanceCreate: 'stageInstanceCreate',
|
||||
StageInstanceUpdate: 'stageInstanceUpdate',
|
||||
StageInstanceDelete: 'stageInstanceDelete',
|
||||
GuildStickerCreate: 'stickerCreate',
|
||||
GuildStickerDelete: 'stickerDelete',
|
||||
GuildStickerUpdate: 'stickerUpdate',
|
||||
GuildScheduledEventCreate: 'guildScheduledEventCreate',
|
||||
GuildScheduledEventUpdate: 'guildScheduledEventUpdate',
|
||||
GuildScheduledEventDelete: 'guildScheduledEventDelete',
|
||||
GuildScheduledEventUserAdd: 'guildScheduledEventUserAdd',
|
||||
GuildScheduledEventUserRemove: 'guildScheduledEventUserRemove',
|
||||
};
|
||||
66
src/util/Intents.js
Normal file
66
src/util/Intents.js
Normal file
@@ -0,0 +1,66 @@
|
||||
'use strict';
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to calculate intents.
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class Intents extends BitField {}
|
||||
|
||||
/**
|
||||
* @name Intents
|
||||
* @kind constructor
|
||||
* @memberof Intents
|
||||
* @param {IntentsResolvable} [bits=0] Bit(s) to read from
|
||||
*/
|
||||
|
||||
/**
|
||||
* Data that can be resolved to give a permission number. This can be:
|
||||
* * A string (see {@link Intents.FLAGS})
|
||||
* * An intents flag
|
||||
* * An instance of Intents
|
||||
* * An array of IntentsResolvable
|
||||
* @typedef {string|number|Intents|IntentsResolvable[]} IntentsResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Numeric WebSocket intents. All available properties:
|
||||
* * `GUILDS`
|
||||
* * `GUILD_MEMBERS`
|
||||
* * `GUILD_BANS`
|
||||
* * `GUILD_EMOJIS_AND_STICKERS`
|
||||
* * `GUILD_INTEGRATIONS`
|
||||
* * `GUILD_WEBHOOKS`
|
||||
* * `GUILD_INVITES`
|
||||
* * `GUILD_VOICE_STATES`
|
||||
* * `GUILD_PRESENCES`
|
||||
* * `GUILD_MESSAGES`
|
||||
* * `GUILD_MESSAGE_REACTIONS`
|
||||
* * `GUILD_MESSAGE_TYPING`
|
||||
* * `DIRECT_MESSAGES`
|
||||
* * `DIRECT_MESSAGE_REACTIONS`
|
||||
* * `DIRECT_MESSAGE_TYPING`
|
||||
* * `GUILD_SCHEDULED_EVENTS`
|
||||
* @type {Object}
|
||||
* @see {@link https://discord.com/developers/docs/topics/gateway#list-of-intents}
|
||||
*/
|
||||
Intents.FLAGS = {
|
||||
GUILDS: 1 << 0,
|
||||
GUILD_MEMBERS: 1 << 1,
|
||||
GUILD_BANS: 1 << 2,
|
||||
GUILD_EMOJIS_AND_STICKERS: 1 << 3,
|
||||
GUILD_INTEGRATIONS: 1 << 4,
|
||||
GUILD_WEBHOOKS: 1 << 5,
|
||||
GUILD_INVITES: 1 << 6,
|
||||
GUILD_VOICE_STATES: 1 << 7,
|
||||
GUILD_PRESENCES: 1 << 8,
|
||||
GUILD_MESSAGES: 1 << 9,
|
||||
GUILD_MESSAGE_REACTIONS: 1 << 10,
|
||||
GUILD_MESSAGE_TYPING: 1 << 11,
|
||||
DIRECT_MESSAGES: 1 << 12,
|
||||
DIRECT_MESSAGE_REACTIONS: 1 << 13,
|
||||
DIRECT_MESSAGE_TYPING: 1 << 14,
|
||||
GUILD_SCHEDULED_EVENTS: 1 << 16,
|
||||
};
|
||||
|
||||
module.exports = Intents;
|
||||
@@ -1,33 +0,0 @@
|
||||
'use strict';
|
||||
const { GatewayIntentBits } = require('discord-api-types/v9');
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to calculate intents.
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class IntentsBitField extends BitField {}
|
||||
|
||||
/**
|
||||
* @name IntentsBitField
|
||||
* @kind constructor
|
||||
* @memberof IntentsBitField
|
||||
* @param {IntentsResolvable} [bits=0] Bit(s) to read from
|
||||
*/
|
||||
|
||||
/**
|
||||
* Data that can be resolved to give a permission number. This can be:
|
||||
* * A string (see {@link IntentsBitField.Flags})
|
||||
* * An intents flag
|
||||
* * An instance of {@link IntentsBitField}
|
||||
* * An array of IntentsResolvable
|
||||
* @typedef {string|number|IntentsBitField|IntentsResolvable[]} IntentsResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Numeric WebSocket intents
|
||||
* @type {GatewayIntentBits}
|
||||
*/
|
||||
IntentsBitField.Flags = GatewayIntentBits;
|
||||
|
||||
module.exports = IntentsBitField;
|
||||
@@ -1,18 +1,35 @@
|
||||
'use strict';
|
||||
|
||||
const { setInterval } = require('node:timers');
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { _cleanupSymbol } = require('./Constants.js');
|
||||
const Sweepers = require('./Sweepers.js');
|
||||
const { TypeError } = require('../errors/DJSError.js');
|
||||
|
||||
/**
|
||||
* @typedef {Function} SweepFilter
|
||||
* @param {LimitedCollection} collection The collection being swept
|
||||
* @returns {Function|null} Return `null` to skip sweeping, otherwise a function passed to `sweep()`,
|
||||
* See {@link [Collection#sweep](https://discord.js.org/#/docs/collection/main/class/Collection?scrollTo=sweep)}
|
||||
* for the definition of this function.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Options for defining the behavior of a LimitedCollection
|
||||
* @typedef {Object} LimitedCollectionOptions
|
||||
* @property {?number} [maxSize=Infinity] The maximum size of the Collection
|
||||
* @property {?Function} [keepOverLimit=null] A function, which is passed the value and key of an entry, ran to decide
|
||||
* to keep an entry past the maximum size
|
||||
* @property {?SweepFilter} [sweepFilter=null] DEPRECATED: There is no direct alternative to this,
|
||||
* however most of its purpose is fulfilled by {@link Client#sweepers}
|
||||
* A function ran every `sweepInterval` to determine how to sweep
|
||||
* @property {?number} [sweepInterval=0] DEPRECATED: There is no direct alternative to this,
|
||||
* however most of its purpose is fulfilled by {@link Client#sweepers}
|
||||
* How frequently, in seconds, to sweep the collection.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A Collection which holds a max amount of entries.
|
||||
* A Collection which holds a max amount of entries and sweeps periodically.
|
||||
* @extends {Collection}
|
||||
* @param {LimitedCollectionOptions} [options={}] Options for constructing the Collection.
|
||||
* @param {Iterable} [iterable=null] Optional entries passed to the Map constructor.
|
||||
@@ -22,7 +39,7 @@ class LimitedCollection extends Collection {
|
||||
if (typeof options !== 'object' || options === null) {
|
||||
throw new TypeError('INVALID_TYPE', 'options', 'object', true);
|
||||
}
|
||||
const { maxSize = Infinity, keepOverLimit = null } = options;
|
||||
const { maxSize = Infinity, keepOverLimit = null, sweepInterval = 0, sweepFilter = null } = options;
|
||||
|
||||
if (typeof maxSize !== 'number') {
|
||||
throw new TypeError('INVALID_TYPE', 'maxSize', 'number');
|
||||
@@ -30,6 +47,12 @@ class LimitedCollection extends Collection {
|
||||
if (keepOverLimit !== null && typeof keepOverLimit !== 'function') {
|
||||
throw new TypeError('INVALID_TYPE', 'keepOverLimit', 'function');
|
||||
}
|
||||
if (typeof sweepInterval !== 'number') {
|
||||
throw new TypeError('INVALID_TYPE', 'sweepInterval', 'number');
|
||||
}
|
||||
if (sweepFilter !== null && typeof sweepFilter !== 'function') {
|
||||
throw new TypeError('INVALID_TYPE', 'sweepFilter', 'function');
|
||||
}
|
||||
|
||||
super(iterable);
|
||||
|
||||
@@ -44,6 +67,28 @@ class LimitedCollection extends Collection {
|
||||
* @type {?Function}
|
||||
*/
|
||||
this.keepOverLimit = keepOverLimit;
|
||||
|
||||
/**
|
||||
* A function called every sweep interval that returns a function passed to `sweep`.
|
||||
* @deprecated in favor of {@link Client#sweepers}
|
||||
* @type {?SweepFilter}
|
||||
*/
|
||||
this.sweepFilter = sweepFilter;
|
||||
|
||||
/**
|
||||
* The id of the interval being used to sweep.
|
||||
* @deprecated in favor of {@link Client#sweepers}
|
||||
* @type {?Timeout}
|
||||
*/
|
||||
this.interval =
|
||||
sweepInterval > 0 && sweepInterval !== Infinity && sweepFilter
|
||||
? setInterval(() => {
|
||||
const sweepFn = this.sweepFilter(this);
|
||||
if (sweepFn === null) return;
|
||||
if (typeof sweepFn !== 'function') throw new TypeError('SWEEP_FILTER_RETURN');
|
||||
this.sweep(sweepFn);
|
||||
}, sweepInterval * 1_000).unref()
|
||||
: null;
|
||||
}
|
||||
|
||||
set(key, value) {
|
||||
@@ -60,6 +105,24 @@ class LimitedCollection extends Collection {
|
||||
return super.set(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a sweepFilter function that uses a lifetime to determine sweepability.
|
||||
* @param {LifetimeFilterOptions} [options={}] The options used to generate the filter function
|
||||
* @deprecated Use {@link Sweepers.filterByLifetime} instead
|
||||
* @returns {SweepFilter}
|
||||
*/
|
||||
static filterByLifetime({
|
||||
lifetime = 14400,
|
||||
getComparisonTimestamp = e => e?.createdTimestamp,
|
||||
excludeFromSweep = () => false,
|
||||
} = {}) {
|
||||
return Sweepers.filterByLifetime({ lifetime, getComparisonTimestamp, excludeFromSweep });
|
||||
}
|
||||
|
||||
[_cleanupSymbol]() {
|
||||
return this.interval ? () => clearInterval(this.interval) : null;
|
||||
}
|
||||
|
||||
static get [Symbol.species]() {
|
||||
return Collection;
|
||||
}
|
||||
|
||||
48
src/util/MessageFlags.js
Normal file
48
src/util/MessageFlags.js
Normal file
@@ -0,0 +1,48 @@
|
||||
'use strict';
|
||||
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with a {@link Message#flags} bitfield.
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class MessageFlags extends BitField {}
|
||||
|
||||
/**
|
||||
* @name MessageFlags
|
||||
* @kind constructor
|
||||
* @memberof MessageFlags
|
||||
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bitfield of the packed bits
|
||||
* @type {number}
|
||||
* @name MessageFlags#bitfield
|
||||
*/
|
||||
|
||||
/**
|
||||
* Numeric message flags. All available properties:
|
||||
* * `CROSSPOSTED`
|
||||
* * `IS_CROSSPOST`
|
||||
* * `SUPPRESS_EMBEDS`
|
||||
* * `SOURCE_MESSAGE_DELETED`
|
||||
* * `URGENT`
|
||||
* * `HAS_THREAD`
|
||||
* * `EPHEMERAL`
|
||||
* * `LOADING`
|
||||
* @type {Object}
|
||||
* @see {@link https://discord.com/developers/docs/resources/channel#message-object-message-flags}
|
||||
*/
|
||||
MessageFlags.FLAGS = {
|
||||
CROSSPOSTED: 1 << 0,
|
||||
IS_CROSSPOST: 1 << 1,
|
||||
SUPPRESS_EMBEDS: 1 << 2,
|
||||
SOURCE_MESSAGE_DELETED: 1 << 3,
|
||||
URGENT: 1 << 4,
|
||||
HAS_THREAD: 1 << 5,
|
||||
EPHEMERAL: 1 << 6,
|
||||
LOADING: 1 << 7,
|
||||
};
|
||||
|
||||
module.exports = MessageFlags;
|
||||
@@ -1,31 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const { MessageFlags } = require('discord-api-types/v9');
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with a {@link Message#flags} bitfield.
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class MessageFlagsBitField extends BitField {}
|
||||
|
||||
/**
|
||||
* @name MessageFlagsBitField
|
||||
* @kind constructor
|
||||
* @memberof MessageFlagsBitField
|
||||
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bitfield of the packed bits
|
||||
* @type {number}
|
||||
* @name MessageFlagsBitField#bitfield
|
||||
*/
|
||||
|
||||
/**
|
||||
* Numeric message flags.
|
||||
* @type {MessageFlags}
|
||||
*/
|
||||
MessageFlagsBitField.Flags = MessageFlags;
|
||||
|
||||
module.exports = MessageFlagsBitField;
|
||||
@@ -1,8 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
const process = require('node:process');
|
||||
const Transformers = require('./Transformers');
|
||||
const JSONBig = require('json-bigint');
|
||||
/**
|
||||
* 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<boolean>}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Function} CacheFactory
|
||||
@@ -23,20 +39,44 @@ const JSONBig = require('json-bigint');
|
||||
* You can use your own function, or the {@link Options} class to customize the Collection used for the cache.
|
||||
* <warn>Overriding the cache used in `GuildManager`, `ChannelManager`, `GuildChannelManager`, `RoleManager`,
|
||||
* and `PermissionOverwriteManager` is unsupported and **will** break functionality</warn>
|
||||
* @property {number} [messageCacheLifetime=0] DEPRECATED: Pass `lifetime` to `sweepers.messages` instead.
|
||||
* How long a message should stay in the cache until it is considered sweepable (in seconds, 0 for forever)
|
||||
* @property {number} [messageSweepInterval=0] DEPRECATED: Pass `interval` to `sweepers.messages` instead.
|
||||
* 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 {Partials[]} [partials] Structures allowed to be partial. This means events can be emitted even when
|
||||
* @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 "Partial Structures" topic on the
|
||||
* [guide](https://discordjs.guide/popular-topics/partials.html) 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 an indefinite amount of retries)
|
||||
* @property {boolean} [failIfNotExists=true] Default value for {@link ReplyMessageOptions#failIfNotExists}
|
||||
* @property {string[]} [userAgentSuffix] An array of additional bot info to be appended to the end of the required
|
||||
* [User Agent](https://discord.com/developers/docs/reference#user-agent) header
|
||||
* @property {PresenceData} [presence={}] Presence data to use upon login
|
||||
* @property {IntentsResolvable} intents Intents to enable for this connection
|
||||
* @property {number} [waitGuildTimeout=15_000] Time in milliseconds that Clients with the GUILDS intent should wait for
|
||||
* missing guilds to be received before starting the bot. If not specified, the default is 15 seconds.
|
||||
* missing guilds to be recieved before starting the bot. If not specified, the default is 15 seconds.
|
||||
* @property {SweeperOptions} [sweepers={}] Options for cache sweeping
|
||||
* @property {WebsocketOptions} [ws] Options for the WebSocket
|
||||
* @property {RESTOptions} [rest] Options for the REST manager
|
||||
* @property {Function} [jsonTransformer] A function used to transform outgoing json data
|
||||
* @property {HTTPOptions} [http] HTTP options
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -62,6 +102,26 @@ const JSONBig = require('json-bigint');
|
||||
* sent in the initial guild member list, must be between 50 and 250
|
||||
*/
|
||||
|
||||
/**
|
||||
* HTTPS Agent options.
|
||||
* @typedef {Object} AgentOptions
|
||||
* @see {@link https://nodejs.org/api/https.html#https_class_https_agent}
|
||||
* @see {@link https://nodejs.org/api/http.html#http_new_agent_options}
|
||||
*/
|
||||
|
||||
/**
|
||||
* HTTP options
|
||||
* @typedef {Object} HTTPOptions
|
||||
* @property {number} [version=9] API version to use
|
||||
* @property {AgentOptions} [agent={}] HTTPS Agent options
|
||||
* @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
|
||||
* @property {string} [scheduledEvent='https://discord.com/events'] Base URL of guild scheduled events
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains various utilities for client options.
|
||||
*/
|
||||
@@ -72,25 +132,28 @@ class Options extends null {
|
||||
*/
|
||||
static createDefault() {
|
||||
return {
|
||||
waitGuildTimeout: 15_000,
|
||||
shardCount: 1,
|
||||
makeCache: this.cacheWithLimits(this.defaultMakeCacheSettings),
|
||||
messageCacheLifetime: 0,
|
||||
messageSweepInterval: 0,
|
||||
invalidRequestWarningInterval: 0,
|
||||
intents: 32767,
|
||||
partials: [],
|
||||
restWsBridgeTimeout: 5_000,
|
||||
restRequestTimeout: 15_000,
|
||||
restGlobalRateLimit: 0,
|
||||
retryLimit: 1,
|
||||
restTimeOffset: 500,
|
||||
restSweepInterval: 60,
|
||||
failIfNotExists: true,
|
||||
userAgentSuffix: [],
|
||||
presence: {},
|
||||
sweepers: {},
|
||||
ws: {
|
||||
jsonTransformer: (object) => JSONBig.stringify(object),
|
||||
checkUpdate: true,
|
||||
readyStatus: false,
|
||||
waitGuildTimeout: 15_000,
|
||||
shardCount: 1,
|
||||
makeCache: this.cacheWithLimits(this.defaultMakeCacheSettings),
|
||||
messageCacheLifetime: 0,
|
||||
messageSweepInterval: 0,
|
||||
invalidRequestWarningInterval: 0,
|
||||
intents: 65535,
|
||||
partials: [],
|
||||
restWsBridgeTimeout: 5_000,
|
||||
restRequestTimeout: 15_000,
|
||||
restGlobalRateLimit: 0,
|
||||
retryLimit: 1,
|
||||
restTimeOffset: 500,
|
||||
restSweepInterval: 60,
|
||||
failIfNotExists: true,
|
||||
userAgentSuffix: [],
|
||||
presence: {},
|
||||
sweepers: {},
|
||||
ws: {
|
||||
large_threshold: 50,
|
||||
compress: false,
|
||||
properties: {
|
||||
@@ -121,6 +184,7 @@ class Options extends null {
|
||||
'X-Debug-Options': 'bugReporterEnabled',
|
||||
'X-Discord-Locale': 'en-US',
|
||||
Origin: 'https://discord.com',
|
||||
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36',
|
||||
},
|
||||
agent: {},
|
||||
version: 10,
|
||||
@@ -130,10 +194,7 @@ class Options extends null {
|
||||
template: 'https://discord.new',
|
||||
scheduledEvent: 'https://discord.com/events',
|
||||
},
|
||||
jsonTransformer: (object) => JSONBig.stringify(object),
|
||||
checkUpdate: true,
|
||||
readyStatus: false,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,14 +205,32 @@ class Options extends null {
|
||||
* If LimitedCollectionOptions are provided for a manager, it uses those settings to form a LimitedCollection.
|
||||
* @returns {CacheFactory}
|
||||
* @example
|
||||
* // Store up to 200 messages per channel and 200 members per guild, always keeping the client member.
|
||||
* // Store up to 200 messages per channel and discard archived threads if they were archived more than 4 hours ago.
|
||||
* // Note archived threads will remain in the guild and client caches with these settings
|
||||
* Options.cacheWithLimits({
|
||||
* MessageManager: 200,
|
||||
* GuildMemberManager: {
|
||||
* maxSize: 200,
|
||||
* keepOverLimit: (member) => member.id === client.user.id,
|
||||
* ThreadManager: {
|
||||
* sweepInterval: 3600,
|
||||
* sweepFilter: LimitedCollection.filterByLifetime({
|
||||
* getComparisonTimestamp: e => e.archiveTimestamp,
|
||||
* excludeFromSweep: e => !e.archived,
|
||||
* }),
|
||||
* },
|
||||
* });
|
||||
* @example
|
||||
* // Sweep messages every 5 minutes, removing messages that have not been edited or created in the last 30 minutes
|
||||
* Options.cacheWithLimits({
|
||||
* // Keep default thread sweeping behavior
|
||||
* ...Options.defaultMakeCacheSettings,
|
||||
* // Override MessageManager
|
||||
* MessageManager: {
|
||||
* sweepInterval: 300,
|
||||
* sweepFilter: LimitedCollection.filterByLifetime({
|
||||
* lifetime: 1800,
|
||||
* getComparisonTimestamp: e => e.editedTimestamp ?? e.createdTimestamp,
|
||||
* })
|
||||
* }
|
||||
* });
|
||||
*/
|
||||
static cacheWithLimits(settings = {}) {
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
@@ -169,9 +248,15 @@ class Options extends null {
|
||||
}
|
||||
return new LimitedCollection({ maxSize: setting });
|
||||
}
|
||||
/* eslint-disable-next-line eqeqeq */
|
||||
/* eslint-disable eqeqeq */
|
||||
const noSweeping =
|
||||
setting.sweepFilter == null ||
|
||||
setting.sweepInterval == null ||
|
||||
setting.sweepInterval <= 0 ||
|
||||
setting.sweepInterval === Infinity;
|
||||
const noLimit = setting.maxSize == null || setting.maxSize === Infinity;
|
||||
if (noLimit) {
|
||||
/* eslint-enable eqeqeq */
|
||||
if (noSweeping && noLimit) {
|
||||
return new Collection();
|
||||
}
|
||||
return new LimitedCollection(setting);
|
||||
@@ -201,6 +286,20 @@ class Options extends null {
|
||||
static get defaultMakeCacheSettings() {
|
||||
return {
|
||||
MessageManager: 200,
|
||||
/*
|
||||
ChannelManager: {
|
||||
sweepInterval: 3600,
|
||||
sweepFilter: require('./Util').archivedThreadSweepFilter(),
|
||||
},
|
||||
GuildChannelManager: {
|
||||
sweepInterval: 3600,
|
||||
sweepFilter: require('./Util').archivedThreadSweepFilter(),
|
||||
},
|
||||
ThreadManager: {
|
||||
sweepInterval: 3600,
|
||||
sweepFilter: require('./Util').archivedThreadSweepFilter(),
|
||||
},
|
||||
*/
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -221,8 +320,3 @@ Options.defaultSweeperSettings = {
|
||||
};
|
||||
|
||||
module.exports = Options;
|
||||
|
||||
/**
|
||||
* @external RESTOptions
|
||||
* @see {@link https://discord.js.org/#/docs/rest/main/typedef/RESTOptions}
|
||||
*/
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const { createEnum } = require('./Enums');
|
||||
|
||||
module.exports = createEnum(['User', 'Channel', 'GuildMember', 'Message', 'Reaction', 'GuildScheduledEvent']);
|
||||
182
src/util/Permissions.js
Normal file
182
src/util/Permissions.js
Normal file
@@ -0,0 +1,182 @@
|
||||
'use strict';
|
||||
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with a permission bitfield. All {@link GuildMember}s have a set of
|
||||
* permissions in their guild, and each channel in the guild may also have {@link PermissionOverwrites} for the member
|
||||
* that override their default permissions.
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class Permissions extends BitField {
|
||||
/**
|
||||
* Bitfield of the packed bits
|
||||
* @type {bigint}
|
||||
* @name Permissions#bitfield
|
||||
*/
|
||||
|
||||
/**
|
||||
* Data that can be resolved to give a permission number. This can be:
|
||||
* * A string (see {@link Permissions.FLAGS})
|
||||
* * A permission number
|
||||
* * An instance of Permissions
|
||||
* * An Array of PermissionResolvable
|
||||
* @typedef {string|bigint|Permissions|PermissionResolvable[]} PermissionResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets all given bits that are missing from the bitfield.
|
||||
* @param {BitFieldResolvable} bits Bit(s) to check for
|
||||
* @param {boolean} [checkAdmin=true] Whether to allow the administrator permission to override
|
||||
* @returns {string[]}
|
||||
*/
|
||||
missing(bits, checkAdmin = true) {
|
||||
return checkAdmin && this.has(this.constructor.FLAGS.ADMINISTRATOR) ? [] : super.missing(bits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the bitfield has a permission, or any of multiple permissions.
|
||||
* @param {PermissionResolvable} permission Permission(s) to check for
|
||||
* @param {boolean} [checkAdmin=true] Whether to allow the administrator permission to override
|
||||
* @returns {boolean}
|
||||
*/
|
||||
any(permission, checkAdmin = true) {
|
||||
return (checkAdmin && super.has(this.constructor.FLAGS.ADMINISTRATOR)) || super.any(permission);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the bitfield has a permission, or multiple permissions.
|
||||
* @param {PermissionResolvable} permission Permission(s) to check for
|
||||
* @param {boolean} [checkAdmin=true] Whether to allow the administrator permission to override
|
||||
* @returns {boolean}
|
||||
*/
|
||||
has(permission, checkAdmin = true) {
|
||||
return (checkAdmin && super.has(this.constructor.FLAGS.ADMINISTRATOR)) || super.has(permission);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an {@link Array} of bitfield names based on the permissions available.
|
||||
* @returns {string[]}
|
||||
*/
|
||||
toArray() {
|
||||
return super.toArray(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Numeric permission flags. All available properties:
|
||||
* * `CREATE_INSTANT_INVITE` (create invitations to the guild)
|
||||
* * `KICK_MEMBERS`
|
||||
* * `BAN_MEMBERS`
|
||||
* * `ADMINISTRATOR` (implicitly has *all* permissions, and bypasses all channel overwrites)
|
||||
* * `MANAGE_CHANNELS` (edit and reorder channels)
|
||||
* * `MANAGE_GUILD` (edit the guild information, region, etc.)
|
||||
* * `ADD_REACTIONS` (add new reactions to messages)
|
||||
* * `VIEW_AUDIT_LOG`
|
||||
* * `PRIORITY_SPEAKER`
|
||||
* * `STREAM`
|
||||
* * `VIEW_CHANNEL`
|
||||
* * `SEND_MESSAGES`
|
||||
* * `SEND_TTS_MESSAGES`
|
||||
* * `MANAGE_MESSAGES` (delete messages and reactions)
|
||||
* * `EMBED_LINKS` (links posted will have a preview embedded)
|
||||
* * `ATTACH_FILES`
|
||||
* * `READ_MESSAGE_HISTORY` (view messages that were posted prior to opening Discord)
|
||||
* * `MENTION_EVERYONE`
|
||||
* * `USE_EXTERNAL_EMOJIS` (use emojis from different guilds)
|
||||
* * `VIEW_GUILD_INSIGHTS`
|
||||
* * `CONNECT` (connect to a voice channel)
|
||||
* * `SPEAK` (speak in a voice channel)
|
||||
* * `MUTE_MEMBERS` (mute members across all voice channels)
|
||||
* * `DEAFEN_MEMBERS` (deafen members across all voice channels)
|
||||
* * `MOVE_MEMBERS` (move members between voice channels)
|
||||
* * `USE_VAD` (use voice activity detection)
|
||||
* * `CHANGE_NICKNAME`
|
||||
* * `MANAGE_NICKNAMES` (change other members' nicknames)
|
||||
* * `MANAGE_ROLES`
|
||||
* * `MANAGE_WEBHOOKS`
|
||||
* * `MANAGE_EMOJIS_AND_STICKERS`
|
||||
* * `USE_APPLICATION_COMMANDS`
|
||||
* * `REQUEST_TO_SPEAK`
|
||||
* * `MANAGE_EVENTS`
|
||||
* * `MANAGE_THREADS`
|
||||
* * `USE_PUBLIC_THREADS` (deprecated)
|
||||
* * `CREATE_PUBLIC_THREADS`
|
||||
* * `USE_PRIVATE_THREADS` (deprecated)
|
||||
* * `CREATE_PRIVATE_THREADS`
|
||||
* * `USE_EXTERNAL_STICKERS` (use stickers from different guilds)
|
||||
* * `SEND_MESSAGES_IN_THREADS`
|
||||
* * `START_EMBEDDED_ACTIVITIES`
|
||||
* * `MODERATE_MEMBERS`
|
||||
* @type {Object<string, bigint>}
|
||||
* @see {@link https://discord.com/developers/docs/topics/permissions#permissions-bitwise-permission-flags}
|
||||
*/
|
||||
Permissions.FLAGS = {
|
||||
CREATE_INSTANT_INVITE: 1n << 0n,
|
||||
KICK_MEMBERS: 1n << 1n,
|
||||
BAN_MEMBERS: 1n << 2n,
|
||||
ADMINISTRATOR: 1n << 3n,
|
||||
MANAGE_CHANNELS: 1n << 4n,
|
||||
MANAGE_GUILD: 1n << 5n,
|
||||
ADD_REACTIONS: 1n << 6n,
|
||||
VIEW_AUDIT_LOG: 1n << 7n,
|
||||
PRIORITY_SPEAKER: 1n << 8n,
|
||||
STREAM: 1n << 9n,
|
||||
VIEW_CHANNEL: 1n << 10n,
|
||||
SEND_MESSAGES: 1n << 11n,
|
||||
SEND_TTS_MESSAGES: 1n << 12n,
|
||||
MANAGE_MESSAGES: 1n << 13n,
|
||||
EMBED_LINKS: 1n << 14n,
|
||||
ATTACH_FILES: 1n << 15n,
|
||||
READ_MESSAGE_HISTORY: 1n << 16n,
|
||||
MENTION_EVERYONE: 1n << 17n,
|
||||
USE_EXTERNAL_EMOJIS: 1n << 18n,
|
||||
VIEW_GUILD_INSIGHTS: 1n << 19n,
|
||||
CONNECT: 1n << 20n,
|
||||
SPEAK: 1n << 21n,
|
||||
MUTE_MEMBERS: 1n << 22n,
|
||||
DEAFEN_MEMBERS: 1n << 23n,
|
||||
MOVE_MEMBERS: 1n << 24n,
|
||||
USE_VAD: 1n << 25n,
|
||||
CHANGE_NICKNAME: 1n << 26n,
|
||||
MANAGE_NICKNAMES: 1n << 27n,
|
||||
MANAGE_ROLES: 1n << 28n,
|
||||
MANAGE_WEBHOOKS: 1n << 29n,
|
||||
MANAGE_EMOJIS_AND_STICKERS: 1n << 30n,
|
||||
USE_APPLICATION_COMMANDS: 1n << 31n,
|
||||
REQUEST_TO_SPEAK: 1n << 32n,
|
||||
MANAGE_EVENTS: 1n << 33n,
|
||||
MANAGE_THREADS: 1n << 34n,
|
||||
// TODO: Remove deprecated USE_*_THREADS flags in v14
|
||||
USE_PUBLIC_THREADS: 1n << 35n,
|
||||
CREATE_PUBLIC_THREADS: 1n << 35n,
|
||||
USE_PRIVATE_THREADS: 1n << 36n,
|
||||
CREATE_PRIVATE_THREADS: 1n << 36n,
|
||||
USE_EXTERNAL_STICKERS: 1n << 37n,
|
||||
SEND_MESSAGES_IN_THREADS: 1n << 38n,
|
||||
START_EMBEDDED_ACTIVITIES: 1n << 39n,
|
||||
MODERATE_MEMBERS: 1n << 40n,
|
||||
};
|
||||
|
||||
/**
|
||||
* Bitfield representing every permission combined
|
||||
* @type {bigint}
|
||||
*/
|
||||
Permissions.ALL = Object.values(Permissions.FLAGS).reduce((all, p) => all | p, 0n);
|
||||
|
||||
/**
|
||||
* Bitfield representing the default permissions for users
|
||||
* @type {bigint}
|
||||
*/
|
||||
Permissions.DEFAULT = BigInt(104324673);
|
||||
|
||||
/**
|
||||
* Bitfield representing the permissions required for moderators of stage channels
|
||||
* @type {bigint}
|
||||
*/
|
||||
Permissions.STAGE_MODERATOR =
|
||||
Permissions.FLAGS.MANAGE_CHANNELS | Permissions.FLAGS.MUTE_MEMBERS | Permissions.FLAGS.MOVE_MEMBERS;
|
||||
|
||||
Permissions.defaultBit = BigInt(0);
|
||||
|
||||
module.exports = Permissions;
|
||||
@@ -1,95 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const { PermissionFlagsBits } = require('discord-api-types/v9');
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with a permission bitfield. All {@link GuildMember}s have a set of
|
||||
* permissions in their guild, and each channel in the guild may also have {@link PermissionOverwrites} for the member
|
||||
* that override their default permissions.
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class PermissionsBitField extends BitField {
|
||||
/**
|
||||
* Bitfield of the packed bits
|
||||
* @type {bigint}
|
||||
* @name Permissions#bitfield
|
||||
*/
|
||||
|
||||
/**
|
||||
* Data that can be resolved to give a permission number. This can be:
|
||||
* * A string (see {@link PermissionsBitField.Flags})
|
||||
* * A permission number
|
||||
* * An instance of {@link PermissionsBitField}
|
||||
* * An Array of PermissionResolvable
|
||||
* @typedef {string|bigint|PermissionsBitField|PermissionResolvable[]} PermissionResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets all given bits that are missing from the bitfield.
|
||||
* @param {BitFieldResolvable} bits Bit(s) to check for
|
||||
* @param {boolean} [checkAdmin=true] Whether to allow the administrator permission to override
|
||||
* @returns {string[]}
|
||||
*/
|
||||
missing(bits, checkAdmin = true) {
|
||||
return checkAdmin && this.has(PermissionFlagsBits.Administrator) ? [] : super.missing(bits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the bitfield has a permission, or any of multiple permissions.
|
||||
* @param {PermissionResolvable} permission Permission(s) to check for
|
||||
* @param {boolean} [checkAdmin=true] Whether to allow the administrator permission to override
|
||||
* @returns {boolean}
|
||||
*/
|
||||
any(permission, checkAdmin = true) {
|
||||
return (checkAdmin && super.has(PermissionFlagsBits.Administrator)) || super.any(permission);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the bitfield has a permission, or multiple permissions.
|
||||
* @param {PermissionResolvable} permission Permission(s) to check for
|
||||
* @param {boolean} [checkAdmin=true] Whether to allow the administrator permission to override
|
||||
* @returns {boolean}
|
||||
*/
|
||||
has(permission, checkAdmin = true) {
|
||||
return (checkAdmin && super.has(PermissionFlagsBits.Administrator)) || super.has(permission);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an {@link Array} of bitfield names based on the permissions available.
|
||||
* @returns {string[]}
|
||||
*/
|
||||
toArray() {
|
||||
return super.toArray(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Numeric permission flags.
|
||||
* @type {PermissionFlagsBits}
|
||||
* @see {@link https://discord.com/developers/docs/topics/permissions#permissions-bitwise-permission-flags}
|
||||
*/
|
||||
PermissionsBitField.Flags = PermissionFlagsBits;
|
||||
|
||||
/**
|
||||
* Bitfield representing every permission combined
|
||||
* @type {bigint}
|
||||
*/
|
||||
PermissionsBitField.All = Object.values(PermissionFlagsBits).reduce((all, p) => all | p, 0n);
|
||||
|
||||
/**
|
||||
* Bitfield representing the default permissions for users
|
||||
* @type {bigint}
|
||||
*/
|
||||
PermissionsBitField.Default = BigInt(104324673);
|
||||
|
||||
/**
|
||||
* Bitfield representing the permissions required for moderators of stage channels
|
||||
* @type {bigint}
|
||||
*/
|
||||
PermissionsBitField.StageModerator =
|
||||
PermissionFlagsBits.ManageChannels | PermissionFlagsBits.MuteMembers | PermissionFlagsBits.MoveMembers;
|
||||
|
||||
PermissionsBitField.defaultBit = BigInt(0);
|
||||
|
||||
module.exports = PermissionsBitField;
|
||||
@@ -1,10 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
Close: 'close',
|
||||
Destroyed: 'destroyed',
|
||||
InvalidSession: 'invalidSession',
|
||||
Ready: 'ready',
|
||||
Resumed: 'resumed',
|
||||
AllReady: 'allReady',
|
||||
};
|
||||
92
src/util/SnowflakeUtil.js
Normal file
92
src/util/SnowflakeUtil.js
Normal file
@@ -0,0 +1,92 @@
|
||||
'use strict';
|
||||
|
||||
// Discord epoch (2015-01-01T00:00:00.000Z)
|
||||
const EPOCH = 1_420_070_400_000;
|
||||
let INCREMENT = BigInt(0);
|
||||
|
||||
/**
|
||||
* A container for useful snowflake-related methods.
|
||||
*/
|
||||
class SnowflakeUtil extends null {
|
||||
/**
|
||||
* A {@link https://developer.twitter.com/en/docs/twitter-ids Twitter snowflake},
|
||||
* except the epoch is 2015-01-01T00:00:00.000Z.
|
||||
*
|
||||
* If we have a snowflake '266241948824764416' we can represent it as binary:
|
||||
* ```
|
||||
* 64 22 17 12 0
|
||||
* 000000111011000111100001101001000101000000 00001 00000 000000000000
|
||||
* number of ms since Discord epoch worker pid increment
|
||||
* ```
|
||||
* @typedef {string} Snowflake
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generates a Discord snowflake.
|
||||
* <info>This hardcodes the worker's id as 1 and the process's id as 0.</info>
|
||||
* @param {number|Date} [timestamp=Date.now()] Timestamp or date of the snowflake to generate
|
||||
* @returns {Snowflake} The generated snowflake
|
||||
*/
|
||||
static generate(timestamp = Date.now()) {
|
||||
if (timestamp instanceof Date) timestamp = timestamp.getTime();
|
||||
if (typeof timestamp !== 'number' || isNaN(timestamp)) {
|
||||
throw new TypeError(
|
||||
`"timestamp" argument must be a number (received ${isNaN(timestamp) ? 'NaN' : typeof timestamp})`,
|
||||
);
|
||||
}
|
||||
if (INCREMENT >= 4095n) INCREMENT = BigInt(0);
|
||||
|
||||
// Assign WorkerId as 1 and ProcessId as 0:
|
||||
return ((BigInt(timestamp - EPOCH) << 22n) | (1n << 17n) | INCREMENT++).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* A deconstructed snowflake.
|
||||
* @typedef {Object} DeconstructedSnowflake
|
||||
* @property {number} timestamp Timestamp the snowflake was created
|
||||
* @property {Date} date Date the snowflake was created
|
||||
* @property {number} workerId The worker's id in the snowflake
|
||||
* @property {number} processId The process's id in the snowflake
|
||||
* @property {number} increment Increment in the snowflake
|
||||
* @property {string} binary Binary representation of the snowflake
|
||||
*/
|
||||
|
||||
/**
|
||||
* Deconstructs a Discord snowflake.
|
||||
* @param {Snowflake} snowflake Snowflake to deconstruct
|
||||
* @returns {DeconstructedSnowflake}
|
||||
*/
|
||||
static deconstruct(snowflake) {
|
||||
const bigIntSnowflake = BigInt(snowflake);
|
||||
return {
|
||||
timestamp: Number(bigIntSnowflake >> 22n) + EPOCH,
|
||||
get date() {
|
||||
return new Date(this.timestamp);
|
||||
},
|
||||
workerId: Number((bigIntSnowflake >> 17n) & 0b11111n),
|
||||
processId: Number((bigIntSnowflake >> 12n) & 0b11111n),
|
||||
increment: Number(bigIntSnowflake & 0b111111111111n),
|
||||
binary: bigIntSnowflake.toString(2).padStart(64, '0'),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the timestamp field's value from a Discord snowflake.
|
||||
* @param {Snowflake} snowflake Snowflake to get the timestamp value from
|
||||
* @returns {number}
|
||||
*/
|
||||
static timestampFrom(snowflake) {
|
||||
return Number(BigInt(snowflake) >> 22n) + EPOCH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Discord's epoch value (2015-01-01T00:00:00.000Z).
|
||||
* @type {number}
|
||||
* @readonly
|
||||
*/
|
||||
static get EPOCH() {
|
||||
return EPOCH;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SnowflakeUtil;
|
||||
@@ -1,15 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const { createEnum } = require('./Enums');
|
||||
|
||||
module.exports = createEnum([
|
||||
'Ready',
|
||||
'Connecting',
|
||||
'Reconnecting',
|
||||
'Idle',
|
||||
'Nearly',
|
||||
'Disconnected',
|
||||
'WaitingForGuilds',
|
||||
'Identifying',
|
||||
'Resuming',
|
||||
]);
|
||||
@@ -1,8 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const { setInterval, clearInterval } = require('node:timers');
|
||||
const { ThreadChannelTypes, SweeperKeys } = require('./Constants');
|
||||
const Events = require('./Events');
|
||||
const { setInterval } = require('node:timers');
|
||||
const { Events, ThreadChannelTypes, SweeperKeys } = require('./Constants');
|
||||
const { TypeError } = require('../errors/DJSError.js');
|
||||
|
||||
/**
|
||||
@@ -72,7 +71,7 @@ class Sweepers {
|
||||
const globalCommands = this.client.application?.commands.cache.sweep(filter) ?? 0;
|
||||
|
||||
this.client.emit(
|
||||
Events.CacheSweep,
|
||||
Events.CACHE_SWEEP,
|
||||
`Swept ${globalCommands} global application commands and ${guildCommands} guild commands in ${guilds} guilds.`,
|
||||
);
|
||||
return guildCommands + globalCommands;
|
||||
@@ -137,12 +136,12 @@ class Sweepers {
|
||||
let messages = 0;
|
||||
|
||||
for (const channel of this.client.channels.cache.values()) {
|
||||
if (!channel.isTextBased()) continue;
|
||||
if (!channel.isText()) continue;
|
||||
|
||||
channels++;
|
||||
messages += channel.messages.cache.sweep(filter);
|
||||
}
|
||||
this.client.emit(Events.CacheSweep, `Swept ${messages} messages in ${channels} text-based channels.`);
|
||||
this.client.emit(Events.CACHE_SWEEP, `Swept ${messages} messages in ${channels} text-based channels.`);
|
||||
return messages;
|
||||
}
|
||||
|
||||
@@ -169,7 +168,7 @@ class Sweepers {
|
||||
let reactions = 0;
|
||||
|
||||
for (const channel of this.client.channels.cache.values()) {
|
||||
if (!channel.isTextBased()) continue;
|
||||
if (!channel.isText()) continue;
|
||||
channels++;
|
||||
|
||||
for (const message of channel.messages.cache.values()) {
|
||||
@@ -178,7 +177,7 @@ class Sweepers {
|
||||
}
|
||||
}
|
||||
this.client.emit(
|
||||
Events.CacheSweep,
|
||||
Events.CACHE_SWEEP,
|
||||
`Swept ${reactions} reactions on ${messages} messages in ${channels} text-based channels.`,
|
||||
);
|
||||
return reactions;
|
||||
@@ -193,15 +192,6 @@ class Sweepers {
|
||||
return this._sweepGuildDirectProp('stageInstances', filter, { outputName: 'stage instances' }).items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sweeps all guild stickers and removes the ones which are indicated by the filter.
|
||||
* @param {Function} filter The function used to determine which stickers will be removed from the caches.
|
||||
* @returns {number} Amount of stickers that were removed from the caches
|
||||
*/
|
||||
sweepStickers(filter) {
|
||||
return this._sweepGuildDirectProp('stickers', filter).items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sweeps all thread members and removes the ones which are indicated by the filter.
|
||||
* <info>It is highly recommended to keep the client thread member cached</info>
|
||||
@@ -220,7 +210,7 @@ class Sweepers {
|
||||
threads++;
|
||||
members += channel.members.cache.sweep(filter);
|
||||
}
|
||||
this.client.emit(Events.CacheSweep, `Swept ${members} thread members in ${threads} threads.`);
|
||||
this.client.emit(Events.CACHE_SWEEP, `Swept ${members} thread members in ${threads} threads.`);
|
||||
return members;
|
||||
}
|
||||
|
||||
@@ -251,7 +241,7 @@ class Sweepers {
|
||||
this.client.channels._remove(key);
|
||||
}
|
||||
}
|
||||
this.client.emit(Events.CacheSweep, `Swept ${threads} threads.`);
|
||||
this.client.emit(Events.CACHE_SWEEP, `Swept ${threads} threads.`);
|
||||
return threads;
|
||||
}
|
||||
|
||||
@@ -267,7 +257,7 @@ class Sweepers {
|
||||
|
||||
const users = this.client.users.cache.sweep(filter);
|
||||
|
||||
this.client.emit(Events.CacheSweep, `Swept ${users} users.`);
|
||||
this.client.emit(Events.CACHE_SWEEP, `Swept ${users} users.`);
|
||||
|
||||
return users;
|
||||
}
|
||||
@@ -405,7 +395,7 @@ class Sweepers {
|
||||
}
|
||||
|
||||
if (emit) {
|
||||
this.client.emit(Events.CacheSweep, `Swept ${items} ${outputName ?? key} in ${guilds} guilds.`);
|
||||
this.client.emit(Events.CACHE_SWEEP, `Swept ${items} ${outputName ?? key} in ${guilds} guilds.`);
|
||||
}
|
||||
|
||||
return { guilds, items };
|
||||
|
||||
51
src/util/SystemChannelFlags.js
Normal file
51
src/util/SystemChannelFlags.js
Normal file
@@ -0,0 +1,51 @@
|
||||
'use strict';
|
||||
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with a {@link Guild#systemChannelFlags} bitfield.
|
||||
* <info>Note that all event message types are enabled by default,
|
||||
* and by setting their corresponding flags you are disabling them</info>
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class SystemChannelFlags extends BitField {}
|
||||
|
||||
/**
|
||||
* @name SystemChannelFlags
|
||||
* @kind constructor
|
||||
* @memberof SystemChannelFlags
|
||||
* @param {SystemChannelFlagsResolvable} [bits=0] Bit(s) to read from
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bitfield of the packed bits
|
||||
* @type {number}
|
||||
* @name SystemChannelFlags#bitfield
|
||||
*/
|
||||
|
||||
/**
|
||||
* Data that can be resolved to give a system channel flag bitfield. This can be:
|
||||
* * A string (see {@link SystemChannelFlags.FLAGS})
|
||||
* * A system channel flag
|
||||
* * An instance of SystemChannelFlags
|
||||
* * An Array of SystemChannelFlagsResolvable
|
||||
* @typedef {string|number|SystemChannelFlags|SystemChannelFlagsResolvable[]} SystemChannelFlagsResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Numeric system channel flags. All available properties:
|
||||
* * `SUPPRESS_JOIN_NOTIFICATIONS` (Suppress member join notifications)
|
||||
* * `SUPPRESS_PREMIUM_SUBSCRIPTIONS` (Suppress server boost notifications)
|
||||
* * `SUPPRESS_GUILD_REMINDER_NOTIFICATIONS` (Suppress server setup tips)
|
||||
* * `SUPPRESS_JOIN_NOTIFICATION_REPLIES` (Hide member join sticker reply buttons)
|
||||
* @type {Object}
|
||||
* @see {@link https://discord.com/developers/docs/resources/guild#guild-object-system-channel-flags}
|
||||
*/
|
||||
SystemChannelFlags.FLAGS = {
|
||||
SUPPRESS_JOIN_NOTIFICATIONS: 1 << 0,
|
||||
SUPPRESS_PREMIUM_SUBSCRIPTIONS: 1 << 1,
|
||||
SUPPRESS_GUILD_REMINDER_NOTIFICATIONS: 1 << 2,
|
||||
SUPPRESS_JOIN_NOTIFICATION_REPLIES: 1 << 3,
|
||||
};
|
||||
|
||||
module.exports = SystemChannelFlags;
|
||||
@@ -1,42 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const { GuildSystemChannelFlags } = require('discord-api-types/v9');
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with a {@link Guild#systemChannelFlags} bitfield.
|
||||
* <info>Note that all event message types are enabled by default,
|
||||
* and by setting their corresponding flags you are disabling them</info>
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class SystemChannelFlagsBitField extends BitField {}
|
||||
|
||||
/**
|
||||
* @name SystemChannelFlagsBitField
|
||||
* @kind constructor
|
||||
* @memberof SystemChannelFlagsBitField
|
||||
* @param {SystemChannelFlagsResolvable} [bits=0] Bit(s) to read from
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bitfield of the packed bits
|
||||
* @type {number}
|
||||
* @name SystemChannelFlagsBitField#bitfield
|
||||
*/
|
||||
|
||||
/**
|
||||
* Data that can be resolved to give a system channel flag bitfield. This can be:
|
||||
* * A string (see {@link SystemChannelFlagsBitField.Flags})
|
||||
* * A system channel flag
|
||||
* * An instance of SystemChannelFlagsBitField
|
||||
* * An Array of SystemChannelFlagsResolvable
|
||||
* @typedef {string|number|SystemChannelFlagsBitField|SystemChannelFlagsResolvable[]} SystemChannelFlagsResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Numeric system channel flags.
|
||||
* @type {GuildSystemChannelFlags}
|
||||
*/
|
||||
SystemChannelFlagsBitField.Flags = GuildSystemChannelFlags;
|
||||
|
||||
module.exports = SystemChannelFlagsBitField;
|
||||
@@ -6,25 +6,25 @@ const BitField = require('./BitField');
|
||||
* Data structure that makes it easy to interact with a {@link ThreadMember#flags} bitfield.
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class ThreadMemberFlagsBitField extends BitField {}
|
||||
class ThreadMemberFlags extends BitField {}
|
||||
|
||||
/**
|
||||
* @name ThreadMemberFlagsBitField
|
||||
* @name ThreadMemberFlags
|
||||
* @kind constructor
|
||||
* @memberof ThreadMemberFlagsBitField
|
||||
* @memberof ThreadMemberFlags
|
||||
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bitfield of the packed bits
|
||||
* @type {number}
|
||||
* @name ThreadMemberFlagsBitField#bitfield
|
||||
* @name ThreadMemberFlags#bitfield
|
||||
*/
|
||||
|
||||
/**
|
||||
* Numeric thread member flags. There are currently no bitflags relevant to bots for this.
|
||||
* @type {Object<string, number>}
|
||||
*/
|
||||
ThreadMemberFlagsBitField.Flags = {};
|
||||
ThreadMemberFlags.FLAGS = {};
|
||||
|
||||
module.exports = ThreadMemberFlagsBitField;
|
||||
module.exports = ThreadMemberFlags;
|
||||
@@ -1,20 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const snakeCase = require('lodash.snakecase');
|
||||
|
||||
class Transformers extends null {
|
||||
/**
|
||||
* Transforms camel-cased keys into snake cased keys
|
||||
* @param {*} obj The object to transform
|
||||
* @returns {*}
|
||||
*/
|
||||
static toSnakeCase(obj) {
|
||||
if (typeof obj !== 'object' || !obj) return obj;
|
||||
if (Array.isArray(obj)) return obj.map(Transformers.toSnakeCase);
|
||||
return Object.fromEntries(
|
||||
Object.entries(obj).map(([key, value]) => [snakeCase(key), Transformers.toSnakeCase(value)]),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Transformers;
|
||||
59
src/util/UserFlags.js
Normal file
59
src/util/UserFlags.js
Normal file
@@ -0,0 +1,59 @@
|
||||
'use strict';
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with a {@link User#flags} bitfield.
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class UserFlags extends BitField {}
|
||||
|
||||
/**
|
||||
* @name UserFlags
|
||||
* @kind constructor
|
||||
* @memberof UserFlags
|
||||
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bitfield of the packed bits
|
||||
* @type {number}
|
||||
* @name UserFlags#bitfield
|
||||
*/
|
||||
|
||||
/**
|
||||
* Numeric user flags. All available properties:
|
||||
* * `DISCORD_EMPLOYEE`
|
||||
* * `PARTNERED_SERVER_OWNER`
|
||||
* * `HYPESQUAD_EVENTS`
|
||||
* * `BUGHUNTER_LEVEL_1`
|
||||
* * `HOUSE_BRAVERY`
|
||||
* * `HOUSE_BRILLIANCE`
|
||||
* * `HOUSE_BALANCE`
|
||||
* * `EARLY_SUPPORTER`
|
||||
* * `TEAM_USER`
|
||||
* * `BUGHUNTER_LEVEL_2`
|
||||
* * `VERIFIED_BOT`
|
||||
* * `EARLY_VERIFIED_BOT_DEVELOPER`
|
||||
* * `DISCORD_CERTIFIED_MODERATOR`
|
||||
* * `BOT_HTTP_INTERACTIONS`
|
||||
* @type {Object}
|
||||
* @see {@link https://discord.com/developers/docs/resources/user#user-object-user-flags}
|
||||
*/
|
||||
UserFlags.FLAGS = {
|
||||
DISCORD_EMPLOYEE: 1 << 0,
|
||||
PARTNERED_SERVER_OWNER: 1 << 1,
|
||||
HYPESQUAD_EVENTS: 1 << 2,
|
||||
BUGHUNTER_LEVEL_1: 1 << 3,
|
||||
HOUSE_BRAVERY: 1 << 6,
|
||||
HOUSE_BRILLIANCE: 1 << 7,
|
||||
HOUSE_BALANCE: 1 << 8,
|
||||
EARLY_SUPPORTER: 1 << 9,
|
||||
TEAM_USER: 1 << 10,
|
||||
BUGHUNTER_LEVEL_2: 1 << 14,
|
||||
VERIFIED_BOT: 1 << 16,
|
||||
EARLY_VERIFIED_BOT_DEVELOPER: 1 << 17,
|
||||
DISCORD_CERTIFIED_MODERATOR: 1 << 18,
|
||||
BOT_HTTP_INTERACTIONS: 1 << 19,
|
||||
};
|
||||
|
||||
module.exports = UserFlags;
|
||||
@@ -1,31 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const { UserFlags } = require('discord-api-types/v9');
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with a {@link User#flags} bitfield.
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class UserFlagsBitField extends BitField {}
|
||||
|
||||
/**
|
||||
* @name UserFlagsBitField
|
||||
* @kind constructor
|
||||
* @memberof UserFlagsBitField
|
||||
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bitfield of the packed bits
|
||||
* @type {number}
|
||||
* @name UserFlagsBitField#bitfield
|
||||
*/
|
||||
|
||||
/**
|
||||
* Numeric user flags.
|
||||
* @type {UserFlags}
|
||||
*/
|
||||
UserFlagsBitField.Flags = UserFlags;
|
||||
|
||||
module.exports = UserFlagsBitField;
|
||||
136
src/util/Util.js
136
src/util/Util.js
@@ -1,13 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
const { parse } = require('node:path');
|
||||
const process = require('node:process');
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { ChannelType, RouteBases, Routes } = require('discord-api-types/v9');
|
||||
const { fetch } = require('undici');
|
||||
const Colors = require('./Colors');
|
||||
const fetch = require('node-fetch');
|
||||
const { Colors, Endpoints } = require('./Constants');
|
||||
const Options = require('./Options');
|
||||
const { Error: DiscordError, RangeError, TypeError } = require('../errors');
|
||||
const has = (o, k) => Object.prototype.hasOwnProperty.call(o, k);
|
||||
const isObject = d => typeof d === 'object' && d !== null;
|
||||
|
||||
let deprecationEmittedForRemoveMentions = false;
|
||||
|
||||
/**
|
||||
* Contains various general-purpose utility methods.
|
||||
*/
|
||||
@@ -268,7 +272,8 @@ class Util extends null {
|
||||
*/
|
||||
static async fetchRecommendedShards(token, { guildsPerShard = 1_000, multipleOf = 1 } = {}) {
|
||||
if (!token) throw new DiscordError('TOKEN_MISSING');
|
||||
const response = await fetch(RouteBases.api + Routes.gatewayBot(), {
|
||||
const defaults = Options.createDefault();
|
||||
const response = await fetch(`${defaults.http.api}/v${defaults.http.version}${Endpoints.botGateway}`, {
|
||||
method: 'GET',
|
||||
headers: { Authorization: `Bot ${token.replace(/^Bot\s*/i, '')}` },
|
||||
});
|
||||
@@ -330,7 +335,7 @@ class Util extends null {
|
||||
static mergeDefault(def, given) {
|
||||
if (!given) return def;
|
||||
for (const key in def) {
|
||||
if (!Object.hasOwn(given, key) || given[key] === undefined) {
|
||||
if (!has(given, key) || given[key] === undefined) {
|
||||
given[key] = def[key];
|
||||
} else if (given[key] === Object(given[key])) {
|
||||
given[key] = Util.mergeDefault(def[key], given[key]);
|
||||
@@ -419,37 +424,37 @@ class Util extends null {
|
||||
* [255, 0, 255] // purple
|
||||
* ```
|
||||
* or one of the following strings:
|
||||
* - `Default`
|
||||
* - `White`
|
||||
* - `Aqua`
|
||||
* - `Green`
|
||||
* - `Blue`
|
||||
* - `Yellow`
|
||||
* - `Purple`
|
||||
* - `LuminousVividPink`
|
||||
* - `Fuchsia`
|
||||
* - `Gold`
|
||||
* - `Orange`
|
||||
* - `Red`
|
||||
* - `Grey`
|
||||
* - `Navy`
|
||||
* - `DarkAqua`
|
||||
* - `DarkGreen`
|
||||
* - `DarkBlue`
|
||||
* - `DarkPurple`
|
||||
* - `DarkVividPink`
|
||||
* - `DarkGold`
|
||||
* - `DarkOrange`
|
||||
* - `DarkRed`
|
||||
* - `DarkGrey`
|
||||
* - `DarkerGrey`
|
||||
* - `LightGrey`
|
||||
* - `DarkNavy`
|
||||
* - `Blurple`
|
||||
* - `Greyple`
|
||||
* - `DarkButNotBlack`
|
||||
* - `NotQuiteBlack`
|
||||
* - `Random`
|
||||
* - `DEFAULT`
|
||||
* - `WHITE`
|
||||
* - `AQUA`
|
||||
* - `GREEN`
|
||||
* - `BLUE`
|
||||
* - `YELLOW`
|
||||
* - `PURPLE`
|
||||
* - `LUMINOUS_VIVID_PINK`
|
||||
* - `FUCHSIA`
|
||||
* - `GOLD`
|
||||
* - `ORANGE`
|
||||
* - `RED`
|
||||
* - `GREY`
|
||||
* - `NAVY`
|
||||
* - `DARK_AQUA`
|
||||
* - `DARK_GREEN`
|
||||
* - `DARK_BLUE`
|
||||
* - `DARK_PURPLE`
|
||||
* - `DARK_VIVID_PINK`
|
||||
* - `DARK_GOLD`
|
||||
* - `DARK_ORANGE`
|
||||
* - `DARK_RED`
|
||||
* - `DARK_GREY`
|
||||
* - `DARKER_GREY`
|
||||
* - `LIGHT_GREY`
|
||||
* - `DARK_NAVY`
|
||||
* - `BLURPLE`
|
||||
* - `GREYPLE`
|
||||
* - `DARK_BUT_NOT_BLACK`
|
||||
* - `NOT_QUITE_BLACK`
|
||||
* - `RANDOM`
|
||||
* @typedef {string|number|number[]} ColorResolvable
|
||||
*/
|
||||
|
||||
@@ -460,8 +465,8 @@ class Util extends null {
|
||||
*/
|
||||
static resolveColor(color) {
|
||||
if (typeof color === 'string') {
|
||||
if (color === 'Random') return Math.floor(Math.random() * (0xffffff + 1));
|
||||
if (color === 'Default') return 0;
|
||||
if (color === 'RANDOM') return Math.floor(Math.random() * (0xffffff + 1));
|
||||
if (color === 'DEFAULT') return 0;
|
||||
color = Colors[color] ?? parseInt(color.replace('#', ''), 16);
|
||||
} else if (Array.isArray(color)) {
|
||||
color = (color[0] << 16) + (color[1] << 8) + color[2];
|
||||
@@ -493,17 +498,16 @@ class Util extends null {
|
||||
* @param {number} position New position for the object
|
||||
* @param {boolean} relative Whether `position` is relative to its current position
|
||||
* @param {Collection<string, Channel|Role>} sorted A collection of the objects sorted properly
|
||||
* @param {Client} client The client to use to patch the data
|
||||
* @param {string} route Route to call PATCH on
|
||||
* @param {APIRouter} route Route to call PATCH on
|
||||
* @param {string} [reason] Reason for the change
|
||||
* @returns {Promise<Channel[]|Role[]>} Updated item list, with `id` and `position` properties
|
||||
* @private
|
||||
*/
|
||||
static async setPosition(item, position, relative, sorted, client, route, reason) {
|
||||
static async setPosition(item, position, relative, sorted, route, reason) {
|
||||
let updatedItems = [...sorted.values()];
|
||||
Util.moveElementInArray(updatedItems, item, position, relative);
|
||||
updatedItems = updatedItems.map((r, i) => ({ id: r.id, position: i }));
|
||||
await client.rest.patch(route, { body: updatedItems, reason });
|
||||
await route.patch({ data: updatedItems, reason });
|
||||
return updatedItems;
|
||||
}
|
||||
|
||||
@@ -518,8 +522,34 @@ class Util extends null {
|
||||
const res = parse(path);
|
||||
return ext && res.ext.startsWith(ext) ? res.name : res.base.split('?')[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Breaks user, role and everyone/here mentions by adding a zero width space after every @ character
|
||||
* @param {string} str The string to sanitize
|
||||
* @returns {string}
|
||||
* @deprecated Use {@link BaseMessageOptions#allowedMentions} instead.
|
||||
*/
|
||||
static removeMentions(str) {
|
||||
if (!deprecationEmittedForRemoveMentions) {
|
||||
process.emitWarning(
|
||||
'The Util.removeMentions method is deprecated. Use MessageOptions#allowedMentions instead.',
|
||||
'DeprecationWarning',
|
||||
);
|
||||
|
||||
deprecationEmittedForRemoveMentions = true;
|
||||
}
|
||||
|
||||
return Util._removeMentions(str);
|
||||
}
|
||||
|
||||
static _removeMentions(str) {
|
||||
return str.replaceAll('@', '@\u200b');
|
||||
}
|
||||
|
||||
/**
|
||||
* The content to have all mentions replaced by the equivalent text.
|
||||
* <warn>When {@link Util.removeMentions} is removed, this method will no longer sanitize mentions.
|
||||
* Use {@link BaseMessageOptions#allowedMentions} instead to prevent mentions when sending a message.</warn>
|
||||
* @param {string} str The string to be converted
|
||||
* @param {TextBasedChannels} channel The channel the string was sent in
|
||||
* @returns {string}
|
||||
@@ -528,17 +558,17 @@ class Util extends null {
|
||||
str = str
|
||||
.replace(/<@!?[0-9]+>/g, input => {
|
||||
const id = input.replace(/<|!|>|@/g, '');
|
||||
if (channel.type === ChannelType.DM) {
|
||||
if (channel.type === 'DM') {
|
||||
const user = channel.client.users.cache.get(id);
|
||||
return user ? `@${user.username}` : input;
|
||||
return user ? Util._removeMentions(`@${user.username}`) : input;
|
||||
}
|
||||
|
||||
const member = channel.guild.members.cache.get(id);
|
||||
if (member) {
|
||||
return `@${member.displayName}`;
|
||||
return Util._removeMentions(`@${member.displayName}`);
|
||||
} else {
|
||||
const user = channel.client.users.cache.get(id);
|
||||
return user ? `@${user.username}` : input;
|
||||
return user ? Util._removeMentions(`@${user.username}`) : input;
|
||||
}
|
||||
})
|
||||
.replace(/<#[0-9]+>/g, input => {
|
||||
@@ -546,7 +576,7 @@ class Util extends null {
|
||||
return mentionedChannel ? `#${mentionedChannel.name}` : input;
|
||||
})
|
||||
.replace(/<@&[0-9]+>/g, input => {
|
||||
if (channel.type === ChannelType.DM) return input;
|
||||
if (channel.type === 'DM') return input;
|
||||
const role = channel.guild.roles.cache.get(input.replace(/<|@|>|&/g, ''));
|
||||
return role ? `@${role.name}` : input;
|
||||
});
|
||||
@@ -561,6 +591,18 @@ class Util extends null {
|
||||
static cleanCodeBlockContent(text) {
|
||||
return text.replaceAll('```', '`\u200b``');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a sweep filter that sweeps archived threads
|
||||
* @param {number} [lifetime=14400] How long a thread has to be archived to be valid for sweeping
|
||||
* @deprecated When not using with `makeCache` use `Sweepers.archivedThreadSweepFilter` instead
|
||||
* @returns {SweepFilter}
|
||||
*/
|
||||
static archivedThreadSweepFilter(lifetime = 14400) {
|
||||
const filter = require('./Sweepers').archivedThreadSweepFilter(lifetime);
|
||||
filter.isDefault = true;
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Util;
|
||||
|
||||
Reference in New Issue
Block a user