Initial commit of Discord bot

This commit is contained in:
VinceC
2024-09-16 04:22:47 -05:00
commit d50c7c5b15
3950 changed files with 365981 additions and 0 deletions

566
node_modules/discord.js/src/util/APITypes.js generated vendored Normal file
View File

@@ -0,0 +1,566 @@
/* eslint-disable max-len */
/**
* @external ActivityFlags
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ActivityFlags}
*/
/**
* @external ActivityType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ActivityType}
*/
/**
* @external APIActionRowComponent
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIActionRowComponent}
*/
/**
* @external APIApplication
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIApplication}
*/
/**
* @external APIApplicationCommand
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIApplicationCommand}
*/
/**
* @external APIApplicationCommandOption
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10#APIApplicationCommandOption}
*/
/**
* @external ApplicationIntegrationType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ApplicationIntegrationType}
*/
/**
* @external APIAuthorizingIntegrationOwnersMap
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10#APIAuthorizingIntegrationOwnersMap}
*/
/**
* @external APIAutoModerationAction
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIAutoModerationAction}
*/
/**
* @external APIButtonComponent
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10#APIButtonComponent}
*/
/**
* @external APIChannel
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10#APIChannel}
*/
/**
* @external APIChannelSelectComponent
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10#APIChannelSelectComponent}
*/
/**
* @external APIEmbed
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIEmbed}
*/
/**
* @external APIEmbedField
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIEmbedField}
*/
/**
* @external APIEmbedProvider
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIEmbedProvider}
*/
/**
* @external APIEmoji
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIEmoji}
*/
/**
* @external APIGuild
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIGuild}
*/
/**
* @external APIGuildForumDefaultReactionEmoji
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIGuildForumDefaultReactionEmoji}
*/
/**
* @external APIGuildForumTag
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIGuildForumTag}
*/
/**
* @external APIGuildMember
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIGuildMember}
*/
/**
* @external APIInteraction
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10#APIInteraction}
*/
/**
* @external APIInteractionDataResolved
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIInteractionDataResolved}
*/
/**
* @external APIInteractionDataResolvedChannel
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIInteractionDataResolvedChannel}
*/
/**
* @external APIInteractionDataResolvedGuildMember
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIInteractionDataResolvedGuildMember}
*/
/**
* @external APIInteractionGuildMember
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIInteractionGuildMember}
*/
/**
* @external APIMentionableSelectComponent
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10#APIMentionableSelectComponent}
*/
/**
* @external APIMessage
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIMessage}
*/
/**
* @external APIMessageActionRowComponent
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10#APIMessageActionRowComponent}
*/
/**
* @external APIMessageComponent
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10#APIMessageComponent}
*/
/**
* @external APIMessageComponentEmoji
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIMessageComponentEmoji}
*/
/**
* @external APIMessageInteractionMetadata
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIMessageInteractionMetadata}
*/
/**
* @external APIModalInteractionResponse
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIModalInteractionResponse}
*/
/**
* @external APIModalInteractionResponseCallbackData
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIModalInteractionResponseCallbackData}
*/
/**
* @external APIModalComponent
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10#APIModalComponent}
*/
/**
* @external APIModalSubmission
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIModalSubmission}
*/
/**
* @external APIOverwrite
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIOverwrite}
*/
/**
* @external APIPartialEmoji
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIPartialEmoji}
*/
/**
* @external APIRole
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIRole}
*/
/**
* @external APIRoleSelectComponent
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10#APIRoleSelectComponent}
*/
/**
* @external APISelectMenuOption
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APISelectMenuOption}
*/
/**
* @external APISticker
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APISticker}
*/
/**
* @external APIStringSelectComponent
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIStringSelectComponent}
*/
/**
* @external APITextInputComponent
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APITextInputComponent}
*/
/**
* @external APIUser
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIUser}
*/
/**
* @external APIUserSelectComponent
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10#APIUserSelectComponent}
*/
/**
* @external ApplicationCommandType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ApplicationCommandType}
*/
/**
* @external ApplicationCommandOptionType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ApplicationCommandOptionType}
*/
/**
* @external ApplicationCommandPermissionType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ApplicationCommandPermissionType}
*/
/**
* @external ApplicationFlags
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ApplicationFlags}
*/
/**
* @external ApplicationRoleConnectionMetadataType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ApplicationRoleConnectionMetadataType}
*/
/**
* @external AttachmentFlags
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/AttachmentFlags}
*/
/**
* @external AutoModerationActionType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/AutoModerationActionType}
*/
/**
* @external AutoModerationRuleEventType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/AutoModerationRuleEventType}
*/
/**
* @external AutoModerationRuleTriggerType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/AutoModerationRuleTriggerType}
*/
/**
* @external AutoModerationRuleKeywordPresetType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/AutoModerationRuleKeywordPresetType}
*/
/**
* @external AuditLogEvent
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/AuditLogEvent}
*/
/**
* @external ButtonStyle
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ButtonStyle}
*/
/**
* @external ChannelFlags
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ChannelFlags}
*/
/**
* @external ChannelType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ChannelType}
*/
/**
* @external ComponentType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ComponentType}
*/
/**
* @external EntitlementType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/EntitlementType}
*/
/**
* @external ForumLayoutType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ForumLayoutType}
*/
/**
* @external GatewayCloseCodes
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GatewayCloseCodes}
*/
/**
* @external GatewayDispatchEvents
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GatewayDispatchEvents}
*/
/**
* @external GatewayIntentBits
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GatewayIntentBits}
*/
/**
* @external GatewayOpcodes
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GatewayOpcodes}
*/
/**
* @external GatewayPresenceUpdateData
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/GatewayPresenceUpdateData}
*/
/**
* @external GuildDefaultMessageNotifications
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildDefaultMessageNotifications}
*/
/**
* @external GuildExplicitContentFilter
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildExplicitContentFilter}
*/
/**
* @external GuildFeature
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildFeature}
*/
/**
* @external GuildMFALevel
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildMFALevel}
*/
/**
* @external GuildMemberFlags
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildMemberFlags}
*/
/**
* @external GuildNSFWLevel
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildNSFWLevel}
*/
/**
* @external GuildOnboardingMode
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildOnboardingMode}
*/
/**
* @external GuildOnboardingPromptType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildOnboardingPromptType}
*/
/**
* @external GuildPremiumTier
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildPremiumTier}
*/
/**
* @external GuildScheduledEventEntityType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildScheduledEventEntityType}
*/
/**
* @external GuildScheduledEventPrivacyLevel
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildScheduledEventPrivacyLevel}
*/
/**
* @external GuildScheduledEventStatus
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildScheduledEventStatus}
*/
/**
* @external GuildSystemChannelFlags
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildSystemChannelFlags}
*/
/**
* @external GuildVerificationLevel
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildVerificationLevel}
*/
/**
* @external GuildWidgetStyle
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildWidgetStyle}
*/
/**
* @external IntegrationExpireBehavior
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/IntegrationExpireBehavior}
*/
/**
* @external InteractionContextType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/InteractionContextType}
*/
/**
* @external InteractionType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/InteractionType}
*/
/**
* @external InteractionResponseType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/InteractionResponseType}
*/
/**
* @external InviteType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/InviteType}
*/
/**
* @external InviteTargetType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/InviteTargetType}
*/
/**
* @external Locale
* @see {@link https://discord-api-types.dev/api/discord-api-types-rest/common/enum/Locale}
*/
/**
* @external LocaleString
* @see {@link https://discord-api-types.dev/api/discord-api-types-rest/common#LocaleString}
*/
/**
* @external MessageActivityType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/MessageActivityType}
*/
/**
* @external MessageType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/MessageType}
*/
/**
* @external MessageFlags
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/MessageFlags}
*/
/**
* @external OAuth2Scopes
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/OAuth2Scopes}
*/
/**
* @external OverwriteType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/OverwriteType}
*/
/**
* @external PermissionFlagsBits
* @see {@link https://discord-api-types.dev/api/discord-api-types-payloads/common#PermissionFlagsBits}
*/
/**
* @external PollLayoutType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/PollLayoutType}
*/
/**
* @external RoleFlags
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/RoleFlags}
*/
/**
* @external RESTGetAPIGuildThreadsResult
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10#RESTGetAPIGuildThreadsResult}
*/
/**
* @external RESTJSONErrorCodes
* @see {@link https://discord-api-types.dev/api/discord-api-types-rest/common/enum/RESTJSONErrorCodes}
*/
/**
* @external SKUFlags
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/SKUFlags}
*/
/**
* @external SKUType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/SKUType}
*/
/**
* @external SortOrderType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/SortOrderType}
*/
/**
* @external StageInstancePrivacyLevel
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/StageInstancePrivacyLevel}
*/
/**
* @external StickerType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/StickerType}
*/
/**
* @external StickerFormatType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/StickerFormatType}
*/
/**
* @external TeamMemberMembershipState
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/TeamMemberMembershipState}
*/
/**
* @external TeamMemberRole
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/TeamMemberRole}
*/
/**
* @external TextInputStyle
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/TextInputStyle}
*/
/**
* @external ThreadAutoArchiveDuration
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ThreadAutoArchiveDuration}
*/
/**
* @external UserFlags
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/UserFlags}
*/
/**
* @external VideoQualityMode
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/VideoQualityMode}
*/
/**
* @external WebhookType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/WebhookType}
*/

View File

@@ -0,0 +1,26 @@
'use strict';
const { ActivityFlags } = require('discord-api-types/v10');
const BitField = require('./BitField');
/**
* Data structure that makes it easy to interact with an {@link Activity#flags} bitfield.
* @extends {BitField}
*/
class ActivityFlagsBitField extends BitField {
/**
* Numeric activity flags.
* @type {ActivityFlags}
* @memberof ActivityFlagsBitField
*/
static Flags = ActivityFlags;
}
/**
* @name ActivityFlagsBitField
* @kind constructor
* @memberof ActivityFlagsBitField
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
*/
module.exports = ActivityFlagsBitField;

View File

@@ -0,0 +1,41 @@
'use strict';
const { ApplicationFlags } = require('discord-api-types/v10');
const BitField = require('./BitField');
/**
* Data structure that makes it easy to interact with a {@link ClientApplication#flags} bitfield.
* @extends {BitField}
*/
class ApplicationFlagsBitField extends BitField {
/**
* Numeric application flags. All available properties:
* @type {ApplicationFlags}
* @memberof ApplicationFlagsBitField
*/
static Flags = ApplicationFlags;
}
/**
* @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
*/
/**
* Data that can be resolved to give an application flag bit field. This can be:
* * A string (see {@link ApplicationFlagsBitField.Flags})
* * An application flag
* * An instance of ApplicationFlagsBitField
* * An Array of ApplicationFlagsResolvable
* @typedef {string|number|ApplicationFlagsBitField|ApplicationFlagsResolvable[]} ApplicationFlagsResolvable
*/
module.exports = ApplicationFlagsBitField;

View File

@@ -0,0 +1,26 @@
'use strict';
const { AttachmentFlags } = require('discord-api-types/v10');
const BitField = require('./BitField');
/**
* Data structure that makes it easy to interact with an {@link Attachment#flags} bitfield.
* @extends {BitField}
*/
class AttachmentFlagsBitField extends BitField {
/**
* Numeric attachment flags.
* @type {AttachmentFlags}
* @memberof AttachmentFlagsBitField
*/
static Flags = AttachmentFlags;
}
/**
* @name AttachmentFlagsBitField
* @kind constructor
* @memberof AttachmentFlagsBitField
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
*/
module.exports = AttachmentFlagsBitField;

178
node_modules/discord.js/src/util/BitField.js generated vendored Normal file
View File

@@ -0,0 +1,178 @@
'use strict';
const { DiscordjsRangeError, ErrorCodes } = require('../errors');
/**
* Data structure that makes it easy to interact with a bitfield.
*/
class BitField {
/**
* Numeric bitfield flags.
* <info>Defined in extension classes</info>
* @type {Object}
* @memberof BitField
* @abstract
*/
static Flags = {};
/**
* @type {number|bigint}
* @memberof BitField
* @private
*/
static DefaultBit = 0;
/**
* @param {BitFieldResolvable} [bits=this.constructor.DefaultBit] Bit(s) to read from
*/
constructor(bits = this.constructor.DefaultBit) {
/**
* Bitfield of the packed bits
* @type {number|bigint}
*/
this.bitfield = this.constructor.resolve(bits);
}
/**
* Checks whether the bitfield has a bit, or any of multiple bits.
* @param {BitFieldResolvable} bit Bit(s) to check for
* @returns {boolean}
*/
any(bit) {
return (this.bitfield & this.constructor.resolve(bit)) !== this.constructor.DefaultBit;
}
/**
* Checks if this bitfield equals another
* @param {BitFieldResolvable} bit Bit(s) to check for
* @returns {boolean}
*/
equals(bit) {
return this.bitfield === this.constructor.resolve(bit);
}
/**
* Checks whether the bitfield has a bit, or multiple bits.
* @param {BitFieldResolvable} bit Bit(s) to check for
* @returns {boolean}
*/
has(bit) {
bit = this.constructor.resolve(bit);
return (this.bitfield & bit) === bit;
}
/**
* Gets all given bits that are missing from the bitfield.
* @param {BitFieldResolvable} bits Bit(s) to check for
* @param {...*} hasParams Additional parameters for the has method, if any
* @returns {string[]}
*/
missing(bits, ...hasParams) {
return new this.constructor(bits).remove(this).toArray(...hasParams);
}
/**
* Freezes these bits, making them immutable.
* @returns {Readonly<BitField>}
*/
freeze() {
return Object.freeze(this);
}
/**
* Adds bits to these ones.
* @param {...BitFieldResolvable} [bits] Bits to add
* @returns {BitField} These bits or new BitField if the instance is frozen.
*/
add(...bits) {
let total = this.constructor.DefaultBit;
for (const bit of bits) {
total |= this.constructor.resolve(bit);
}
if (Object.isFrozen(this)) return new this.constructor(this.bitfield | total);
this.bitfield |= total;
return this;
}
/**
* Removes bits from these.
* @param {...BitFieldResolvable} [bits] Bits to remove
* @returns {BitField} These bits or new BitField if the instance is frozen.
*/
remove(...bits) {
let total = this.constructor.DefaultBit;
for (const bit of bits) {
total |= this.constructor.resolve(bit);
}
if (Object.isFrozen(this)) return new this.constructor(this.bitfield & ~total);
this.bitfield &= ~total;
return this;
}
/**
* Gets an object mapping field names to a {@link boolean} indicating whether the
* bit is available.
* @param {...*} hasParams Additional parameters for the has method, if any
* @returns {Object}
*/
serialize(...hasParams) {
const serialized = {};
for (const [flag, bit] of Object.entries(this.constructor.Flags)) {
if (isNaN(flag)) serialized[flag] = this.has(bit, ...hasParams);
}
return serialized;
}
/**
* Gets an {@link Array} of bitfield names based on the bits available.
* @param {...*} hasParams Additional parameters for the has method, if any
* @returns {string[]}
*/
toArray(...hasParams) {
return [...this[Symbol.iterator](...hasParams)];
}
toJSON() {
return typeof this.bitfield === 'number' ? this.bitfield : this.bitfield.toString();
}
valueOf() {
return this.bitfield;
}
*[Symbol.iterator](...hasParams) {
for (const bitName of Object.keys(this.constructor.Flags)) {
if (isNaN(bitName) && this.has(bitName, ...hasParams)) yield bitName;
}
}
/**
* 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 string bit number
* * An instance of BitField
* * An Array of BitFieldResolvable
* @typedef {number|string|bigint|BitField|BitFieldResolvable[]} BitFieldResolvable
*/
/**
* Resolves bitfields to their numeric form.
* @param {BitFieldResolvable} [bit] bit(s) to resolve
* @returns {number|bigint}
*/
static resolve(bit) {
const { DefaultBit } = this;
if (typeof DefaultBit === typeof bit && bit >= DefaultBit) return bit;
if (bit instanceof BitField) return bit.bitfield;
if (Array.isArray(bit)) {
return bit.map(bit_ => this.resolve(bit_)).reduce((prev, bit_) => prev | bit_, DefaultBit);
}
if (typeof bit === 'string') {
if (!isNaN(bit)) return typeof DefaultBit === 'bigint' ? BigInt(bit) : Number(bit);
if (this.Flags[bit] !== undefined) return this.Flags[bit];
}
throw new DiscordjsRangeError(ErrorCodes.BitFieldInvalid, bit);
}
}
module.exports = BitField;

View File

@@ -0,0 +1,41 @@
'use strict';
const { ChannelFlags } = require('discord-api-types/v10');
const BitField = require('./BitField');
/**
* Data structure that makes it easy to interact with a {@link BaseChannel#flags} bitfield.
* @extends {BitField}
*/
class ChannelFlagsBitField extends BitField {
/**
* Numeric guild channel flags.
* @type {ChannelFlags}
* @memberof ChannelFlagsBitField
*/
static Flags = ChannelFlags;
}
/**
* @name ChannelFlagsBitField
* @kind constructor
* @memberof ChannelFlagsBitField
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
*/
/**
* Bitfield of the packed bits
* @type {number}
* @name ChannelFlagsBitField#bitfield
*/
/**
* Data that can be resolved to give a channel flag bitfield. This can be:
* * A string (see {@link ChannelFlagsBitField.Flags})
* * A channel flag
* * An instance of ChannelFlagsBitField
* * An Array of ChannelFlagsResolvable
* @typedef {string|number|ChannelFlagsBitField|ChannelFlagsResolvable[]} ChannelFlagsResolvable
*/
module.exports = ChannelFlagsBitField;

161
node_modules/discord.js/src/util/Channels.js generated vendored Normal file
View File

@@ -0,0 +1,161 @@
'use strict';
const { lazy } = require('@discordjs/util');
const { ChannelType } = require('discord-api-types/v10');
const getCategoryChannel = lazy(() => require('../structures/CategoryChannel'));
const getDMChannel = lazy(() => require('../structures/DMChannel'));
const getNewsChannel = lazy(() => require('../structures/NewsChannel'));
const getStageChannel = lazy(() => require('../structures/StageChannel'));
const getTextChannel = lazy(() => require('../structures/TextChannel'));
const getThreadChannel = lazy(() => require('../structures/ThreadChannel'));
const getVoiceChannel = lazy(() => require('../structures/VoiceChannel'));
const getDirectoryChannel = lazy(() => require('../structures/DirectoryChannel'));
const getPartialGroupDMChannel = lazy(() => require('../structures/PartialGroupDMChannel'));
const getForumChannel = lazy(() => require('../structures/ForumChannel'));
const getMediaChannel = lazy(() => require('../structures/MediaChannel'));
/**
* Extra options for creating a channel.
* @typedef {Object} CreateChannelOptions
* @property {boolean} [allowFromUnknownGuild] Whether to allow creating a channel from an unknown guild
* @private
*/
/**
* Creates a discord.js channel from data received from the API.
* @param {Client} client The client
* @param {APIChannel} data The data of the channel to create
* @param {Guild} [guild] The guild where this channel belongs
* @param {CreateChannelOptions} [extras] Extra information to supply for creating this channel
* @returns {BaseChannel} Any kind of channel.
* @ignore
*/
function createChannel(client, data, guild, { allowUnknownGuild } = {}) {
let channel;
if (!data.guild_id && !guild) {
if ((data.recipients && data.type !== ChannelType.GroupDM) || data.type === ChannelType.DM) {
channel = new (getDMChannel())(client, data);
} else if (data.type === ChannelType.GroupDM) {
channel = new (getPartialGroupDMChannel())(client, data);
}
} else {
guild ??= client.guilds.cache.get(data.guild_id);
if (guild || allowUnknownGuild) {
switch (data.type) {
case ChannelType.GuildText: {
channel = new (getTextChannel())(guild, data, client);
break;
}
case ChannelType.GuildVoice: {
channel = new (getVoiceChannel())(guild, data, client);
break;
}
case ChannelType.GuildCategory: {
channel = new (getCategoryChannel())(guild, data, client);
break;
}
case ChannelType.GuildAnnouncement: {
channel = new (getNewsChannel())(guild, data, client);
break;
}
case ChannelType.GuildStageVoice: {
channel = new (getStageChannel())(guild, data, client);
break;
}
case ChannelType.AnnouncementThread:
case ChannelType.PublicThread:
case ChannelType.PrivateThread: {
channel = new (getThreadChannel())(guild, data, client);
if (!allowUnknownGuild) channel.parent?.threads.cache.set(channel.id, channel);
break;
}
case ChannelType.GuildDirectory:
channel = new (getDirectoryChannel())(guild, data, client);
break;
case ChannelType.GuildForum:
channel = new (getForumChannel())(guild, data, client);
break;
case ChannelType.GuildMedia:
channel = new (getMediaChannel())(guild, data, client);
break;
}
if (channel && !allowUnknownGuild) guild.channels?.cache.set(channel.id, channel);
}
}
return channel;
}
/**
* Transforms an API guild forum tag to camel-cased guild forum tag.
* @param {APIGuildForumTag} tag The tag to transform
* @returns {GuildForumTag}
* @ignore
*/
function transformAPIGuildForumTag(tag) {
return {
id: tag.id,
name: tag.name,
moderated: tag.moderated,
emoji:
(tag.emoji_id ?? tag.emoji_name)
? {
id: tag.emoji_id,
name: tag.emoji_name,
}
: null,
};
}
/**
* Transforms a camel-cased guild forum tag to an API guild forum tag.
* @param {GuildForumTag} tag The tag to transform
* @returns {APIGuildForumTag}
* @ignore
*/
function transformGuildForumTag(tag) {
return {
id: tag.id,
name: tag.name,
moderated: tag.moderated,
emoji_id: tag.emoji?.id ?? null,
emoji_name: tag.emoji?.name ?? null,
};
}
/**
* Transforms an API guild forum default reaction object to a
* camel-cased guild forum default reaction object.
* @param {APIGuildForumDefaultReactionEmoji} defaultReaction The default reaction to transform
* @returns {DefaultReactionEmoji}
* @ignore
*/
function transformAPIGuildDefaultReaction(defaultReaction) {
return {
id: defaultReaction.emoji_id,
name: defaultReaction.emoji_name,
};
}
/**
* Transforms a camel-cased guild forum default reaction object to an
* API guild forum default reaction object.
* @param {DefaultReactionEmoji} defaultReaction The default reaction to transform
* @returns {APIGuildForumDefaultReactionEmoji}
* @ignore
*/
function transformGuildDefaultReaction(defaultReaction) {
return {
emoji_id: defaultReaction.id,
emoji_name: defaultReaction.name,
};
}
module.exports = {
createChannel,
transformAPIGuildForumTag,
transformGuildForumTag,
transformAPIGuildDefaultReaction,
transformGuildDefaultReaction,
};

73
node_modules/discord.js/src/util/Colors.js generated vendored Normal file
View File

@@ -0,0 +1,73 @@
'use strict';
/**
* @typedef {Object} Colors
* @property {number} Default 0x000000 | rgb(0,0,0)
* @property {number} White 0xFFFFFF | rgb(255,255,255)
* @property {number} Aqua 0x1ABC9C | rgb(26,188,156)
* @property {number} Green 0x57F287 | rgb(87,242,135)
* @property {number} Blue 0x3498DB | rgb(52,152,219)
* @property {number} Yellow 0xFEE75C | rgb(254,231,92)
* @property {number} Purple 0x9B59B6 | rgb(155,89,182)
* @property {number} LuminousVividPink 0xE91E63 | rgb(233,30,99)
* @property {number} Fuchsia 0xEB459E | rgb(235,69,158)
* @property {number} Gold 0xF1C40F | rgb(241,196,15)
* @property {number} Orange 0xE67E22 | rgb(230,126,34)
* @property {number} Red 0xED4245 | rgb(237,66,69)
* @property {number} Grey 0x95A5A6 | rgb(149,165,166)
* @property {number} Navy 0x34495E | rgb(52,73,94)
* @property {number} DarkAqua 0x11806A | rgb(17,128,106)
* @property {number} DarkGreen 0x1F8B4C | rgb(31,139,76)
* @property {number} DarkBlue 0x206694 | rgb(32,102,148)
* @property {number} DarkPurple 0x71368A | rgb(113,54,138)
* @property {number} DarkVividPink 0xAD1457 | rgb(173,20,87)
* @property {number} DarkGold 0xC27C0E | rgb(194,124,14)
* @property {number} DarkOrange 0xA84300 | rgb(168,67,0)
* @property {number} DarkRed 0x992D22 | rgb(153,45,34)
* @property {number} DarkGrey 0x979C9F | rgb(151,156,159)
* @property {number} DarkerGrey 0x7F8C8D | rgb(127,140,141)
* @property {number} LightGrey 0xBCC0C0 | rgb(188,192,192)
* @property {number} DarkNavy 0x2C3E50 | rgb(44,62,80)
* @property {number} Blurple 0x5865F2 | rgb(88,101,242)
* @property {number} Greyple 0x99AAb5 | rgb(153,170,181)
* @property {number} DarkButNotBlack 0x2C2F33 | rgb(44,47,51)
* @property {number} NotQuiteBlack 0x23272A | rgb(35,39,42)
*/
// JSDoc for IntelliSense purposes
/**
* @type {Colors}
* @ignore
*/
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,
};

152
node_modules/discord.js/src/util/Components.js generated vendored Normal file
View File

@@ -0,0 +1,152 @@
'use strict';
// This file contains the typedefs for camel-cased JSON data
const { ComponentBuilder } = require('@discordjs/builders');
const { ComponentType } = require('discord-api-types/v10');
/**
* @typedef {Object} BaseComponentData
* @property {ComponentType} type The type of component
*/
/**
* @typedef {BaseComponentData} ActionRowData
* @property {ComponentData[]} components The components in this action row
*/
/**
* @typedef {BaseComponentData} ButtonComponentData
* @property {ButtonStyle} style The style of the button
* @property {?boolean} disabled Whether this button is disabled
* @property {string} label The label of this button
* @property {?APIMessageComponentEmoji} emoji The emoji on this button
* @property {?string} customId The custom id of the button
* @property {?string} url The URL of the button
*/
/**
* @typedef {object} SelectMenuComponentOptionData
* @property {string} label The label of the option
* @property {string} value The value of the option
* @property {?string} description The description of the option
* @property {?APIMessageComponentEmoji} emoji The emoji on the option
* @property {?boolean} default Whether this option is selected by default
*/
/**
* @typedef {BaseComponentData} SelectMenuComponentData
* @property {string} customId The custom id of the select menu
* @property {?boolean} disabled Whether the select menu is disabled or not
* @property {?number} maxValues The maximum amount of options that can be selected
* @property {?number} minValues The minimum amount of options that can be selected
* @property {?SelectMenuComponentOptionData[]} options The options in this select menu
* @property {?string} placeholder The placeholder of the select menu
*/
/**
* @typedef {ActionRowData|ButtonComponentData|SelectMenuComponentData} MessageComponentData
*/
/**
* @typedef {BaseComponentData} TextInputComponentData
* @property {string} customId The custom id of the text input
* @property {TextInputStyle} style The style of the text input
* @property {string} label The text that appears on top of the text input field
* @property {?number} minLength The minimum number of characters that can be entered in the text input
* @property {?number} maxLength The maximum number of characters that can be entered in the text input
* @property {?boolean} required Whether or not the text input is required or not
* @property {?string} value The pre-filled text in the text input
* @property {?string} placeholder Placeholder for the text input
*/
/**
* @typedef {ActionRowData|ButtonComponentData|SelectMenuComponentData|TextInputComponentData} ComponentData
*/
/**
* Any emoji data that can be used within a button
* @typedef {APIMessageComponentEmoji|string} ComponentEmojiResolvable
*/
/**
* Transforms API data into a component
* @param {APIMessageComponent|Component} data The data to create the component from
* @returns {Component}
*/
function createComponent(data) {
if (data instanceof Component) {
return data;
}
switch (data.type) {
case ComponentType.ActionRow:
return new ActionRow(data);
case ComponentType.Button:
return new ButtonComponent(data);
case ComponentType.StringSelect:
return new StringSelectMenuComponent(data);
case ComponentType.TextInput:
return new TextInputComponent(data);
case ComponentType.UserSelect:
return new UserSelectMenuComponent(data);
case ComponentType.RoleSelect:
return new RoleSelectMenuComponent(data);
case ComponentType.MentionableSelect:
return new MentionableSelectMenuComponent(data);
case ComponentType.ChannelSelect:
return new ChannelSelectMenuComponent(data);
default:
return new Component(data);
}
}
/**
* Transforms API data into a component builder
* @param {APIMessageComponent|ComponentBuilder} data The data to create the component from
* @returns {ComponentBuilder}
*/
function createComponentBuilder(data) {
if (data instanceof ComponentBuilder) {
return data;
}
switch (data.type) {
case ComponentType.ActionRow:
return new ActionRowBuilder(data);
case ComponentType.Button:
return new ButtonBuilder(data);
case ComponentType.StringSelect:
return new StringSelectMenuBuilder(data);
case ComponentType.TextInput:
return new TextInputBuilder(data);
case ComponentType.UserSelect:
return new UserSelectMenuBuilder(data);
case ComponentType.RoleSelect:
return new RoleSelectMenuBuilder(data);
case ComponentType.MentionableSelect:
return new MentionableSelectMenuBuilder(data);
case ComponentType.ChannelSelect:
return new ChannelSelectMenuBuilder(data);
default:
return new ComponentBuilder(data);
}
}
module.exports = { createComponent, createComponentBuilder };
const ActionRow = require('../structures/ActionRow');
const ActionRowBuilder = require('../structures/ActionRowBuilder');
const ButtonBuilder = require('../structures/ButtonBuilder');
const ButtonComponent = require('../structures/ButtonComponent');
const ChannelSelectMenuBuilder = require('../structures/ChannelSelectMenuBuilder');
const ChannelSelectMenuComponent = require('../structures/ChannelSelectMenuComponent');
const Component = require('../structures/Component');
const MentionableSelectMenuBuilder = require('../structures/MentionableSelectMenuBuilder');
const MentionableSelectMenuComponent = require('../structures/MentionableSelectMenuComponent');
const RoleSelectMenuBuilder = require('../structures/RoleSelectMenuBuilder');
const RoleSelectMenuComponent = require('../structures/RoleSelectMenuComponent');
const StringSelectMenuBuilder = require('../structures/StringSelectMenuBuilder');
const StringSelectMenuComponent = require('../structures/StringSelectMenuComponent');
const TextInputBuilder = require('../structures/TextInputBuilder');
const TextInputComponent = require('../structures/TextInputComponent');
const UserSelectMenuBuilder = require('../structures/UserSelectMenuBuilder');
const UserSelectMenuComponent = require('../structures/UserSelectMenuComponent');

267
node_modules/discord.js/src/util/Constants.js generated vendored Normal file
View File

@@ -0,0 +1,267 @@
'use strict';
const { ChannelType, MessageType, ComponentType, ImageFormat, StickerFormatType } = require('discord-api-types/v10');
/**
* Max bulk deletable message age
* @typedef {number} MaxBulkDeletableMessageAge
*/
exports.MaxBulkDeletableMessageAge = 1_209_600_000;
/**
* The name of an item to be swept in Sweepers
* * `autoModerationRules`
* * `applicationCommands` - both global and guild commands
* * `bans`
* * `emojis`
* * `entitlements`
* * `invites` - accepts the `lifetime` property, using it will sweep based on expires timestamp
* * `guildMembers`
* * `messages` - accepts the `lifetime` property, using it will sweep based on edited or created timestamp
* * `presences`
* * `reactions`
* * `stageInstances`
* * `stickers`
* * `threadMembers`
* * `threads` - accepts the `lifetime` property, using it will sweep archived threads based on archived timestamp
* * `users`
* * `voiceStates`
* @typedef {string} SweeperKey
*/
exports.SweeperKeys = [
'autoModerationRules',
'applicationCommands',
'bans',
'emojis',
'entitlements',
'invites',
'guildMembers',
'messages',
'presences',
'reactions',
'stageInstances',
'stickers',
'threadMembers',
'threads',
'users',
'voiceStates',
];
/**
* The types of messages that are not `System`. The available types are:
* * {@link MessageType.Default}
* * {@link MessageType.Reply}
* * {@link MessageType.ChatInputCommand}
* * {@link MessageType.ContextMenuCommand}
* @typedef {MessageType[]} NonSystemMessageTypes
*/
exports.NonSystemMessageTypes = [
MessageType.Default,
MessageType.Reply,
MessageType.ChatInputCommand,
MessageType.ContextMenuCommand,
];
/**
* The guild channels that are text-based.
* * TextChannel
* * NewsChannel
* * ThreadChannel
* * VoiceChannel
* * StageChannel
* @typedef {TextChannel|NewsChannel|ThreadChannel|VoiceChannel|StageChannel} GuildTextBasedChannel
*/
/**
* The types of guild channels that are text-based. The available types are:
* * {@link ChannelType.GuildText}
* * {@link ChannelType.GuildAnnouncement}
* * {@link ChannelType.AnnouncementThread}
* * {@link ChannelType.PublicThread}
* * {@link ChannelType.PrivateThread}
* * {@link ChannelType.GuildVoice}
* * {@link ChannelType.GuildStageVoice}
* @typedef {ChannelType[]} GuildTextBasedChannelTypes
*/
exports.GuildTextBasedChannelTypes = [
ChannelType.GuildText,
ChannelType.GuildAnnouncement,
ChannelType.AnnouncementThread,
ChannelType.PublicThread,
ChannelType.PrivateThread,
ChannelType.GuildVoice,
ChannelType.GuildStageVoice,
];
/**
* The channels that are text-based.
* * {@link DMChannel}
* * {@link GuildTextBasedChannel}
* @typedef {DMChannel|GuildTextBasedChannel} TextBasedChannels
*/
/**
* Data that resolves to give a text-based channel. This can be:
* * A {@link TextBasedChannel}
* * A {@link Snowflake}
* @typedef {TextBasedChannels|Snowflake} TextBasedChannelsResolvable
*/
/**
* The types of channels that are text-based. The available types are:
* * {@link ChannelType.DM}
* * {@link ChannelType.GuildText}
* * {@link ChannelType.GuildAnnouncement}
* * {@link ChannelType.AnnouncementThread}
* * {@link ChannelType.PublicThread}
* * {@link ChannelType.PrivateThread}
* * {@link ChannelType.GuildVoice}
* * {@link ChannelType.GuildStageVoice}
* * {@link ChannelType.GroupDM}
* @typedef {ChannelType[]} TextBasedChannelTypes
*/
exports.TextBasedChannelTypes = [...exports.GuildTextBasedChannelTypes, ChannelType.DM, ChannelType.GroupDM];
/**
* The types of channels that are text-based and can have messages sent into. The available types are:
* * {@link ChannelType.DM}
* * {@link ChannelType.GuildText}
* * {@link ChannelType.GuildAnnouncement}
* * {@link ChannelType.AnnouncementThread}
* * {@link ChannelType.PublicThread}
* * {@link ChannelType.PrivateThread}
* * {@link ChannelType.GuildVoice}
* * {@link ChannelType.GuildStageVoice}
* @typedef {ChannelType[]} SendableChannels
*/
exports.SendableChannels = [...exports.GuildTextBasedChannelTypes, ChannelType.DM];
/**
* The types of channels that are threads. The available types are:
* * {@link ChannelType.AnnouncementThread}
* * {@link ChannelType.PublicThread}
* * {@link ChannelType.PrivateThread}
* @typedef {ChannelType[]} ThreadChannelTypes
*/
exports.ThreadChannelTypes = [ChannelType.AnnouncementThread, ChannelType.PublicThread, ChannelType.PrivateThread];
/**
* The types of channels that are voice-based. The available types are:
* * {@link ChannelType.GuildVoice}
* * {@link ChannelType.GuildStageVoice}
* @typedef {ChannelType[]} VoiceBasedChannelTypes
*/
exports.VoiceBasedChannelTypes = [ChannelType.GuildVoice, ChannelType.GuildStageVoice];
/**
* The types of select menus. The available types are:
* * {@link ComponentType.StringSelect}
* * {@link ComponentType.UserSelect}
* * {@link ComponentType.RoleSelect}
* * {@link ComponentType.MentionableSelect}
* * {@link ComponentType.ChannelSelect}
* @typedef {ComponentType[]} SelectMenuTypes
*/
exports.SelectMenuTypes = [
ComponentType.StringSelect,
ComponentType.UserSelect,
ComponentType.RoleSelect,
ComponentType.MentionableSelect,
ComponentType.ChannelSelect,
];
/**
* The types of messages that cannot be deleted. The available types are:
* * {@link MessageType.RecipientAdd}
* * {@link MessageType.RecipientRemove}
* * {@link MessageType.Call}
* * {@link MessageType.ChannelNameChange}
* * {@link MessageType.ChannelIconChange}
* * {@link MessageType.ThreadStarterMessage}
* @typedef {MessageType[]} UndeletableMessageTypes
*/
exports.UndeletableMessageTypes = [
MessageType.RecipientAdd,
MessageType.RecipientRemove,
MessageType.Call,
MessageType.ChannelNameChange,
MessageType.ChannelIconChange,
MessageType.ThreadStarterMessage,
];
/**
* The types of messages that can be deleted. The available types are:
* * {@link MessageType.AutoModerationAction}
* * {@link MessageType.ChannelFollowAdd}
* * {@link MessageType.ChannelPinnedMessage}
* * {@link MessageType.ChatInputCommand}
* * {@link MessageType.ContextMenuCommand}
* * {@link MessageType.Default}
* * {@link MessageType.GuildBoost}
* * {@link MessageType.GuildBoostTier1}
* * {@link MessageType.GuildBoostTier2}
* * {@link MessageType.GuildBoostTier3}
* * {@link MessageType.GuildInviteReminder}
* * {@link MessageType.InteractionPremiumUpsell}
* * {@link MessageType.Reply}
* * {@link MessageType.RoleSubscriptionPurchase}
* * {@link MessageType.StageEnd}
* * {@link MessageType.StageRaiseHand}
* * {@link MessageType.StageSpeaker}
* * {@link MessageType.StageStart}
* * {@link MessageType.StageTopic}
* * {@link MessageType.ThreadCreated}
* * {@link MessageType.UserJoin}
* @typedef {MessageType[]} DeletableMessageTypes
* @deprecated This list will no longer be updated. Use {@link UndeletableMessageTypes} instead.
*/
exports.DeletableMessageTypes = [
MessageType.AutoModerationAction,
MessageType.ChannelFollowAdd,
MessageType.ChannelPinnedMessage,
MessageType.ChatInputCommand,
MessageType.ContextMenuCommand,
MessageType.Default,
MessageType.GuildBoost,
MessageType.GuildBoostTier1,
MessageType.GuildBoostTier2,
MessageType.GuildBoostTier3,
MessageType.GuildInviteReminder,
MessageType.InteractionPremiumUpsell,
MessageType.Reply,
MessageType.RoleSubscriptionPurchase,
MessageType.StageEnd,
MessageType.StageRaiseHand,
MessageType.StageSpeaker,
MessageType.StageStart,
MessageType.StageTopic,
MessageType.ThreadCreated,
MessageType.UserJoin,
];
/**
* A mapping between sticker formats and their respective image formats.
* * {@link StickerFormatType.PNG} -> {@link ImageFormat.PNG}
* * {@link StickerFormatType.APNG} -> {@link ImageFormat.PNG}
* * {@link StickerFormatType.Lottie} -> {@link ImageFormat.Lottie}
* * {@link StickerFormatType.GIF} -> {@link ImageFormat.GIF}
* @typedef {Object} StickerFormatExtensionMap
*/
exports.StickerFormatExtensionMap = {
[StickerFormatType.PNG]: ImageFormat.PNG,
[StickerFormatType.APNG]: ImageFormat.PNG,
[StickerFormatType.Lottie]: ImageFormat.Lottie,
[StickerFormatType.GIF]: ImageFormat.GIF,
};
/**
* @typedef {Object} Constants Constants that can be used in an enum or object-like way.
* @property {number} MaxBulkDeletableMessageAge Max bulk deletable message age
* @property {SweeperKey[]} SweeperKeys The possible names of items that can be swept in sweepers
* @property {NonSystemMessageTypes} NonSystemMessageTypes The types of messages that are not deemed a system type
* @property {TextBasedChannelTypes} TextBasedChannelTypes The types of channels that are text-based
* @property {ThreadChannelTypes} ThreadChannelTypes The types of channels that are threads
* @property {VoiceBasedChannelTypes} VoiceBasedChannelTypes The types of channels that are voice-based
* @property {SelectMenuTypes} SelectMenuTypes The types of components that are select menus.
* @property {Object} StickerFormatExtensionMap A mapping between sticker formats and their respective image formats.
*/

141
node_modules/discord.js/src/util/DataResolver.js generated vendored Normal file
View File

@@ -0,0 +1,141 @@
'use strict';
const { Buffer } = require('node:buffer');
const fs = require('node:fs/promises');
const path = require('node:path');
const { fetch } = require('undici');
const { DiscordjsError, DiscordjsTypeError, ErrorCodes } = require('../errors');
const Invite = require('../structures/Invite');
/**
* Data that can be resolved to give an invite code. This can be:
* * An invite code
* * An invite URL
* @typedef {string} InviteResolvable
*/
/**
* Data that can be resolved to give a template code. This can be:
* * A template code
* * A template URL
* @typedef {string} GuildTemplateResolvable
*/
/**
* Resolves the string to a code based on the passed regex.
* @param {string} data The string to resolve
* @param {RegExp} regex The RegExp used to extract the code
* @returns {string}
* @private
*/
function resolveCode(data, regex) {
return regex.exec(data)?.[1] ?? data;
}
/**
* Resolves InviteResolvable to an invite code.
* @param {InviteResolvable} data The invite resolvable to resolve
* @returns {string}
* @private
*/
function resolveInviteCode(data) {
return resolveCode(data, Invite.InvitesPattern);
}
/**
* Resolves GuildTemplateResolvable to a template code.
* @param {GuildTemplateResolvable} data The template resolvable to resolve
* @returns {string}
* @private
*/
function resolveGuildTemplateCode(data) {
const GuildTemplate = require('../structures/GuildTemplate');
return resolveCode(data, GuildTemplate.GuildTemplatesPattern);
}
/**
* Data that can be resolved to give a Buffer. This can be:
* * A Buffer
* * The path to a local file
* * A URL <warn>When provided a URL, discord.js will fetch the URL internally in order to create a Buffer.
* This can pose a security risk when the URL has not been sanitized</warn>
* @typedef {string|Buffer} BufferResolvable
*/
/**
* @external Stream
* @see {@link https://nodejs.org/api/stream.html}
*/
/**
* @typedef {Object} ResolvedFile
* @property {Buffer} data Buffer containing the file data
* @property {string} [contentType] Content-Type of the file
* @private
*/
/**
* Resolves a BufferResolvable to a Buffer.
* @param {BufferResolvable|Stream} resource The buffer or stream resolvable to resolve
* @returns {Promise<ResolvedFile>}
* @private
*/
async function resolveFile(resource) {
if (Buffer.isBuffer(resource)) return { data: resource };
if (typeof resource[Symbol.asyncIterator] === 'function') {
const buffers = [];
for await (const data of resource) buffers.push(Buffer.from(data));
return { data: Buffer.concat(buffers) };
}
if (typeof resource === 'string') {
if (/^https?:\/\//.test(resource)) {
const res = await fetch(resource);
return { data: Buffer.from(await res.arrayBuffer()), contentType: res.headers.get('content-type') };
}
const file = path.resolve(resource);
const stats = await fs.stat(file);
if (!stats.isFile()) throw new DiscordjsError(ErrorCodes.FileNotFound, file);
return { data: await fs.readFile(file) };
}
throw new DiscordjsTypeError(ErrorCodes.ReqResourceType);
}
/**
* Data that resolves to give a Base64 string, typically for image uploading. This can be:
* * A Buffer
* * A base64 string
* @typedef {Buffer|string} Base64Resolvable
*/
/**
* Resolves a Base64Resolvable to a Base 64 image.
* @param {Base64Resolvable} data The base 64 resolvable you want to resolve
* @returns {?string}
* @private
*/
function resolveBase64(data) {
if (Buffer.isBuffer(data)) return `data:image/jpg;base64,${data.toString('base64')}`;
return data;
}
/**
* Resolves a Base64Resolvable, a string, or a BufferResolvable to a Base 64 image.
* @param {BufferResolvable|Base64Resolvable} image The image to be resolved
* @returns {Promise<?string>}
* @private
*/
async function resolveImage(image) {
if (!image) return null;
if (typeof image === 'string' && image.startsWith('data:')) {
return image;
}
const file = await resolveFile(image);
return resolveBase64(file.data);
}
module.exports = { resolveCode, resolveInviteCode, resolveGuildTemplateCode, resolveImage, resolveBase64, resolveFile };

13
node_modules/discord.js/src/util/Enums.js generated vendored Normal file
View File

@@ -0,0 +1,13 @@
'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 };

172
node_modules/discord.js/src/util/Events.js generated vendored Normal file
View File

@@ -0,0 +1,172 @@
'use strict';
/**
* @typedef {Object} Events
* @property {string} ApplicationCommandPermissionsUpdate applicationCommandPermissionsUpdate
* @property {string} AutoModerationActionExecution autoModerationActionExecution
* @property {string} AutoModerationRuleCreate autoModerationRuleCreate
* @property {string} AutoModerationRuleDelete autoModerationRuleDelete
* @property {string} AutoModerationRuleUpdate autoModerationRuleUpdate
* @property {string} CacheSweep cacheSweep
* @property {string} ChannelCreate channelCreate
* @property {string} ChannelDelete channelDelete
* @property {string} ChannelPinsUpdate channelPinsUpdate
* @property {string} ChannelUpdate channelUpdate
* @property {string} ClientReady ready
* @property {string} Debug debug
* @property {string} EntitlementCreate entitlementCreate
* @property {string} EntitlementUpdate entitlementUpdate
* @property {string} EntitlementDelete entitlementDelete
* @property {string} Error error
* @property {string} GuildAuditLogEntryCreate guildAuditLogEntryCreate
* @property {string} GuildAvailable guildAvailable
* @property {string} GuildBanAdd guildBanAdd
* @property {string} GuildBanRemove guildBanRemove
* @property {string} GuildCreate guildCreate
* @property {string} GuildDelete guildDelete
* @property {string} GuildEmojiCreate emojiCreate
* @property {string} GuildEmojiDelete emojiDelete
* @property {string} GuildEmojiUpdate emojiUpdate
* @property {string} GuildIntegrationsUpdate guildIntegrationsUpdate
* @property {string} GuildMemberAdd guildMemberAdd
* @property {string} GuildMemberAvailable guildMemberAvailable
* @property {string} GuildMemberRemove guildMemberRemove
* @property {string} GuildMembersChunk guildMembersChunk
* @property {string} GuildMemberUpdate guildMemberUpdate
* @property {string} GuildRoleCreate roleCreate
* @property {string} GuildRoleDelete roleDelete
* @property {string} GuildRoleUpdate roleUpdate
* @property {string} GuildScheduledEventCreate guildScheduledEventCreate
* @property {string} GuildScheduledEventDelete guildScheduledEventDelete
* @property {string} GuildScheduledEventUpdate guildScheduledEventUpdate
* @property {string} GuildScheduledEventUserAdd guildScheduledEventUserAdd
* @property {string} GuildScheduledEventUserRemove guildScheduledEventUserRemove
* @property {string} GuildStickerCreate stickerCreate
* @property {string} GuildStickerDelete stickerDelete
* @property {string} GuildStickerUpdate stickerUpdate
* @property {string} GuildUnavailable guildUnavailable
* @property {string} GuildUpdate guildUpdate
* @property {string} InteractionCreate interactionCreate
* @property {string} Invalidated invalidated
* @property {string} InviteCreate inviteCreate
* @property {string} InviteDelete inviteDelete
* @property {string} MessageBulkDelete messageDeleteBulk
* @property {string} MessageCreate messageCreate
* @property {string} MessageDelete messageDelete
* @property {string} MessagePollVoteAdd messagePollVoteAdd
* @property {string} MessagePollVoteRemove messagePollVoteRemove
* @property {string} MessageReactionAdd messageReactionAdd
* @property {string} MessageReactionRemove messageReactionRemove
* @property {string} MessageReactionRemoveAll messageReactionRemoveAll
* @property {string} MessageReactionRemoveEmoji messageReactionRemoveEmoji
* @property {string} MessageUpdate messageUpdate
* @property {string} PresenceUpdate presenceUpdate
* @property {string} ShardDisconnect shardDisconnect
* @property {string} ShardError shardError
* @property {string} ShardReady shardReady
* @property {string} ShardReconnecting shardReconnecting
* @property {string} ShardResume shardResume
* @property {string} StageInstanceCreate stageInstanceCreate
* @property {string} StageInstanceDelete stageInstanceDelete
* @property {string} StageInstanceUpdate stageInstanceUpdate
* @property {string} ThreadCreate threadCreate
* @property {string} ThreadDelete threadDelete
* @property {string} ThreadListSync threadListSync
* @property {string} ThreadMembersUpdate threadMembersUpdate
* @property {string} ThreadMemberUpdate threadMemberUpdate
* @property {string} ThreadUpdate threadUpdate
* @property {string} TypingStart typingStart
* @property {string} UserUpdate userUpdate
* @property {string} VoiceServerUpdate voiceServerUpdate
* @property {string} VoiceStateUpdate voiceStateUpdate
* @property {string} Warn warn
* @property {string} WebhooksUpdate webhookUpdate
*/
// JSDoc for IntelliSense purposes
/**
* @type {Events}
* @ignore
*/
module.exports = {
ApplicationCommandPermissionsUpdate: 'applicationCommandPermissionsUpdate',
AutoModerationActionExecution: 'autoModerationActionExecution',
AutoModerationRuleCreate: 'autoModerationRuleCreate',
AutoModerationRuleDelete: 'autoModerationRuleDelete',
AutoModerationRuleUpdate: 'autoModerationRuleUpdate',
CacheSweep: 'cacheSweep',
ChannelCreate: 'channelCreate',
ChannelDelete: 'channelDelete',
ChannelPinsUpdate: 'channelPinsUpdate',
ChannelUpdate: 'channelUpdate',
ClientReady: 'ready',
Debug: 'debug',
EntitlementCreate: 'entitlementCreate',
EntitlementUpdate: 'entitlementUpdate',
EntitlementDelete: 'entitlementDelete',
Error: 'error',
GuildAuditLogEntryCreate: 'guildAuditLogEntryCreate',
GuildAvailable: 'guildAvailable',
GuildBanAdd: 'guildBanAdd',
GuildBanRemove: 'guildBanRemove',
GuildCreate: 'guildCreate',
GuildDelete: 'guildDelete',
GuildEmojiCreate: 'emojiCreate',
GuildEmojiDelete: 'emojiDelete',
GuildEmojiUpdate: 'emojiUpdate',
GuildIntegrationsUpdate: 'guildIntegrationsUpdate',
GuildMemberAdd: 'guildMemberAdd',
GuildMemberAvailable: 'guildMemberAvailable',
GuildMemberRemove: 'guildMemberRemove',
GuildMembersChunk: 'guildMembersChunk',
GuildMemberUpdate: 'guildMemberUpdate',
GuildRoleCreate: 'roleCreate',
GuildRoleDelete: 'roleDelete',
GuildRoleUpdate: 'roleUpdate',
GuildScheduledEventCreate: 'guildScheduledEventCreate',
GuildScheduledEventDelete: 'guildScheduledEventDelete',
GuildScheduledEventUpdate: 'guildScheduledEventUpdate',
GuildScheduledEventUserAdd: 'guildScheduledEventUserAdd',
GuildScheduledEventUserRemove: 'guildScheduledEventUserRemove',
GuildStickerCreate: 'stickerCreate',
GuildStickerDelete: 'stickerDelete',
GuildStickerUpdate: 'stickerUpdate',
GuildUnavailable: 'guildUnavailable',
GuildUpdate: 'guildUpdate',
InteractionCreate: 'interactionCreate',
Invalidated: 'invalidated',
InviteCreate: 'inviteCreate',
InviteDelete: 'inviteDelete',
MessageBulkDelete: 'messageDeleteBulk',
MessageCreate: 'messageCreate',
MessageDelete: 'messageDelete',
MessagePollVoteAdd: 'messagePollVoteAdd',
MessagePollVoteRemove: 'messagePollVoteRemove',
MessageReactionAdd: 'messageReactionAdd',
MessageReactionRemove: 'messageReactionRemove',
MessageReactionRemoveAll: 'messageReactionRemoveAll',
MessageReactionRemoveEmoji: 'messageReactionRemoveEmoji',
MessageUpdate: 'messageUpdate',
PresenceUpdate: 'presenceUpdate',
Raw: 'raw',
ShardDisconnect: 'shardDisconnect',
ShardError: 'shardError',
ShardReady: 'shardReady',
ShardReconnecting: 'shardReconnecting',
ShardResume: 'shardResume',
StageInstanceCreate: 'stageInstanceCreate',
StageInstanceDelete: 'stageInstanceDelete',
StageInstanceUpdate: 'stageInstanceUpdate',
ThreadCreate: 'threadCreate',
ThreadDelete: 'threadDelete',
ThreadListSync: 'threadListSync',
ThreadMembersUpdate: 'threadMembersUpdate',
ThreadMemberUpdate: 'threadMemberUpdate',
ThreadUpdate: 'threadUpdate',
TypingStart: 'typingStart',
UserUpdate: 'userUpdate',
VoiceServerUpdate: 'voiceServerUpdate',
VoiceStateUpdate: 'voiceStateUpdate',
Warn: 'warn',
WebhooksUpdate: 'webhookUpdate',
};

413
node_modules/discord.js/src/util/Formatters.js generated vendored Normal file
View File

@@ -0,0 +1,413 @@
'use strict';
const { deprecate } = require('node:util');
const {
blockQuote,
bold,
channelMention,
codeBlock,
formatEmoji,
hideLinkEmbed,
hyperlink,
inlineCode,
italic,
quote,
roleMention,
spoiler,
strikethrough,
time,
TimestampStyles,
underscore,
userMention,
} = require('@discordjs/formatters');
/**
* Formats an application command name and id into an application command mention.
* @method chatInputApplicationCommandMention
* @param {string} commandName The name of the application command
* @param {string|Snowflake} subcommandGroupOrSubOrId
* The subcommand group name, subcommand name, or application command id
* @param {string|Snowflake} [subcommandNameOrId] The subcommand name or application command id
* @param {string} [commandId] The id of the application command
* @returns {string}
*/
/**
* Wraps the content inside a code block with an optional language.
* @method codeBlock
* @param {string} contentOrLanguage The language to use or content if a second parameter isn't provided
* @param {string} [content] The content to wrap
* @returns {string}
*/
/**
* Wraps the content inside \`backticks\`, which formats it as inline code.
* @method inlineCode
* @param {string} content The content to wrap
* @returns {string}
*/
/**
* Formats the content into italic text.
* @method italic
* @param {string} content The content to wrap
* @returns {string}
*/
/**
* Formats the content into bold text.
* @method bold
* @param {string} content The content to wrap
* @returns {string}
*/
/**
* Formats the content into underscored text.
* @method underscore
* @param {string} content The content to wrap
* @returns {string}
*/
/**
* Formats the content into strike-through text.
* @method strikethrough
* @param {string} content The content to wrap
* @returns {string}
*/
/**
* Formats the content into a quote.
* <info>This needs to be at the start of the line for Discord to format it.</info>
* @method quote
* @param {string} content The content to wrap
* @returns {string}
*/
/**
* Formats the content into a block quote.
* <info>This needs to be at the start of the line for Discord to format it.</info>
* @method blockQuote
* @param {string} content The content to wrap
* @returns {string}
*/
/**
* Wraps the URL into `<>`, which stops it from embedding.
* @method hideLinkEmbed
* @param {string} content The content to wrap
* @returns {string}
*/
/**
* Formats the content and the URL into a masked URL with an optional title.
* @method hyperlink
* @param {string} content The content to display
* @param {string} url The URL the content links to
* @param {string} [title] The title shown when hovering on the masked link
* @returns {string}
*/
/**
* Formats the content into spoiler text.
* @method spoiler
* @param {string} content The content to spoiler
* @returns {string}
*/
/**
* Formats a user id into a user mention.
* @method userMention
* @param {Snowflake} userId The user id to format
* @returns {string}
*/
/**
* Formats a channel id into a channel mention.
* @method channelMention
* @param {Snowflake} channelId The channel id to format
* @returns {string}
*/
/**
* Formats a role id into a role mention.
* @method roleMention
* @param {Snowflake} roleId The role id to format
* @returns {string}
*/
/**
* Formats an emoji id into a fully qualified emoji identifier.
* @method formatEmoji
* @param {Snowflake} emojiId The emoji id to format
* @param {boolean} [animated=false] Whether the emoji is animated
* @returns {string}
*/
/**
* Formats a channel link for a channel.
* @method channelLink
* @param {Snowflake} channelId The id of the channel
* @param {Snowflake} [guildId] The id of the guild
* @returns {string}
*/
/**
* Formats a message link for a channel.
* @method messageLink
* @param {Snowflake} channelId The id of the channel
* @param {Snowflake} messageId The id of the message
* @param {Snowflake} [guildId] The id of the guild
* @returns {string}
*/
/**
* A message formatting timestamp style, as defined in
* [here](https://discord.com/developers/docs/reference#message-formatting-timestamp-styles).
* * `t` Short time format, consisting of hours and minutes, e.g. 16:20.
* * `T` Long time format, consisting of hours, minutes, and seconds, e.g. 16:20:30.
* * `d` Short date format, consisting of day, month, and year, e.g. 20/04/2021.
* * `D` Long date format, consisting of day, month, and year, e.g. 20 April 2021.
* * `f` Short date-time format, consisting of short date and short time formats, e.g. 20 April 2021 16:20.
* * `F` Long date-time format, consisting of long date and short time formats, e.g. Tuesday, 20 April 2021 16:20.
* * `R` Relative time format, consisting of a relative duration format, e.g. 2 months ago.
* @typedef {string} TimestampStylesString
*/
/**
* Formats a date into a short date-time string.
* @method time
* @param {number|Date} [date] The date to format
* @param {TimestampStylesString} [style] The style to use
* @returns {string}
*/
/**
* Contains various Discord-specific functions for formatting messages.
* @deprecated This class is redundant as all methods of the class can be imported from discord.js directly.
*/
class Formatters extends null {
/**
* Formats the content into a block quote.
* <info>This needs to be at the start of the line for Discord to format it.</info>
* @method blockQuote
* @memberof Formatters
* @param {string} content The content to wrap
* @returns {string}
* @deprecated Import this method directly from discord.js instead.
*/
static blockQuote = deprecate(
blockQuote,
'Formatters.blockQuote() is deprecated. Import this method directly from discord.js instead.',
);
/**
* Formats the content into bold text.
* @method bold
* @memberof Formatters
* @param {string} content The content to wrap
* @returns {string}
* @deprecated Import this method directly from discord.js instead.
*/
static bold = deprecate(
bold,
'Formatters.bold() is deprecated. Import this method directly from discord.js instead.',
);
/**
* Formats a channel id into a channel mention.
* @method channelMention
* @memberof Formatters
* @param {Snowflake} channelId The channel id to format
* @returns {string}
* @deprecated Import this method directly from discord.js instead.
*/
static channelMention = deprecate(
channelMention,
'Formatters.channelMention() is deprecated. Import this method directly from discord.js instead.',
);
/**
* Wraps the content inside a code block with an optional language.
* @method codeBlock
* @memberof Formatters
* @param {string} contentOrLanguage The language to use or content if a second parameter isn't provided
* @param {string} [content] The content to wrap
* @returns {string}
* @deprecated Import this method directly from discord.js instead.
*/
static codeBlock = deprecate(
codeBlock,
'Formatters.codeBlock() is deprecated. Import this method directly from discord.js instead.',
);
/**
* Formats an emoji id into a fully qualified emoji identifier.
* @method formatEmoji
* @memberof Formatters
* @param {string} emojiId The emoji id to format
* @param {boolean} [animated=false] Whether the emoji is animated
* @returns {string}
* @deprecated Import this method directly from discord.js instead.
*/
static formatEmoji = deprecate(
formatEmoji,
'Formatters.formatEmoji() is deprecated. Import this method directly from discord.js instead.',
);
/**
* Wraps the URL into `<>`, which stops it from embedding.
* @method hideLinkEmbed
* @memberof Formatters
* @param {string} content The content to wrap
* @returns {string}
* @deprecated Import this method directly from discord.js instead.
*/
static hideLinkEmbed = deprecate(
hideLinkEmbed,
'Formatters.hideLinkEmbed() is deprecated. Import this method directly from discord.js instead.',
);
/**
* Formats the content and the URL into a masked URL with an optional title.
* @method hyperlink
* @memberof Formatters
* @param {string} content The content to display
* @param {string} url The URL the content links to
* @param {string} [title] The title shown when hovering on the masked link
* @returns {string}
* @deprecated Import this method directly from discord.js instead.
*/
static hyperlink = deprecate(
hyperlink,
'Formatters.hyperlink() is deprecated. Import this method directly from discord.js instead.',
);
/**
* Wraps the content inside \`backticks\`, which formats it as inline code.
* @method inlineCode
* @memberof Formatters
* @param {string} content The content to wrap
* @returns {string}
* @deprecated Import this method directly from discord.js instead.
*/
static inlineCode = deprecate(
inlineCode,
'Formatters.inlineCode() is deprecated. Import this method directly from discord.js instead.',
);
/**
* Formats the content into italic text.
* @method italic
* @memberof Formatters
* @param {string} content The content to wrap
* @returns {string}
* @deprecated Import this method directly from discord.js instead.
*/
static italic = deprecate(
italic,
'Formatters.italic() is deprecated. Import this method directly from discord.js instead.',
);
/**
* Formats the content into a quote. This needs to be at the start of the line for Discord to format it.
* @method quote
* @memberof Formatters
* @param {string} content The content to wrap
* @returns {string}
* @deprecated Import this method directly from discord.js instead.
*/
static quote = deprecate(
quote,
'Formatters.quote() is deprecated. Import this method directly from discord.js instead.',
);
/**
* Formats a role id into a role mention.
* @method roleMention
* @memberof Formatters
* @param {Snowflake} roleId The role id to format
* @returns {string}
* @deprecated Import this method directly from discord.js instead.
*/
static roleMention = deprecate(
roleMention,
'Formatters.roleMention() is deprecated. Import this method directly from discord.js instead.',
);
/**
* Formats the content into spoiler text.
* @method spoiler
* @memberof Formatters
* @param {string} content The content to spoiler
* @returns {string}
* @deprecated Import this method directly from discord.js instead.
*/
static spoiler = deprecate(
spoiler,
'Formatters.spoiler() is deprecated. Import this method directly from discord.js instead.',
);
/**
* Formats the content into strike-through text.
* @method strikethrough
* @memberof Formatters
* @param {string} content The content to wrap
* @returns {string}
* @deprecated Import this method directly from discord.js instead.
*/
static strikethrough = deprecate(
strikethrough,
'Formatters.strikethrough() is deprecated. Import this method directly from discord.js instead.',
);
/**
* Formats a date into a short date-time string.
* @method time
* @memberof Formatters
* @param {number|Date} [date] The date to format
* @param {TimestampStylesString} [style] The style to use
* @returns {string}
* @deprecated Import this method directly from discord.js instead.
*/
static time = deprecate(
time,
'Formatters.time() is deprecated. Import this method directly from discord.js instead.',
);
/**
* The message formatting timestamp
* [styles](https://discord.com/developers/docs/reference#message-formatting-timestamp-styles) supported by Discord.
* @type {Object<string, TimestampStylesString>}
* @memberof Formatters
* @deprecated Import this property directly from discord.js instead.
*/
static TimestampStyles = TimestampStyles;
/**
* Formats the content into underscored text.
* @method underscore
* @memberof Formatters
* @param {string} content The content to wrap
* @returns {string}
* @deprecated Import this method directly from discord.js instead.
*/
static underscore = deprecate(
underscore,
'Formatters.underscore() is deprecated. Import this method directly from discord.js instead.',
);
/**
* Formats a user id into a user mention.
* @method userMention
* @memberof Formatters
* @param {Snowflake} userId The user id to format
* @returns {string}
* @deprecated Import this method directly from discord.js instead.
*/
static userMention = deprecate(
userMention,
'Formatters.userMention() is deprecated. Import this method directly from discord.js instead.',
);
}
module.exports = Formatters;

View File

@@ -0,0 +1,41 @@
'use strict';
const { GuildMemberFlags } = require('discord-api-types/v10');
const BitField = require('./BitField');
/**
* Data structure that makes it easy to interact with a {@link GuildMember#flags} bitfield.
* @extends {BitField}
*/
class GuildMemberFlagsBitField extends BitField {
/**
* Numeric guild guild member flags.
* @type {GuildMemberFlags}
* @memberof GuildMemberFlagsBitField
*/
static Flags = GuildMemberFlags;
}
/**
* @name GuildMemberFlagsBitField
* @kind constructor
* @memberof GuildMemberFlagsBitField
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
*/
/**
* Bitfield of the packed bits
* @type {number}
* @name GuildMemberFlagsBitField#bitfield
*/
/**
* Data that can be resolved to give a guild member flag bitfield. This can be:
* * A string (see {@link GuildMemberFlagsBitField.Flags})
* * A guild member flag
* * An instance of GuildMemberFlagsBitField
* * An Array of GuildMemberFlagsResolvable
* @typedef {string|number|GuildMemberFlagsBitField|GuildMemberFlagsResolvable[]} GuildMemberFlagsResolvable
*/
exports.GuildMemberFlagsBitField = GuildMemberFlagsBitField;

34
node_modules/discord.js/src/util/IntentsBitField.js generated vendored Normal file
View File

@@ -0,0 +1,34 @@
'use strict';
const { GatewayIntentBits } = require('discord-api-types/v10');
const BitField = require('./BitField');
/**
* Data structure that makes it easy to calculate intents.
* @extends {BitField}
*/
class IntentsBitField extends BitField {
/**
* Numeric WebSocket intents
* @type {GatewayIntentBits}
* @memberof IntentsBitField
*/
static Flags = GatewayIntentBits;
}
/**
* @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
*/
module.exports = IntentsBitField;

68
node_modules/discord.js/src/util/LimitedCollection.js generated vendored Normal file
View File

@@ -0,0 +1,68 @@
'use strict';
const { Collection } = require('@discordjs/collection');
const { DiscordjsTypeError, ErrorCodes } = require('../errors');
/**
* 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
*/
/**
* A Collection which holds a max amount of entries.
* @extends {Collection}
* @param {LimitedCollectionOptions} [options={}] Options for constructing the Collection.
* @param {Iterable} [iterable=null] Optional entries passed to the Map constructor.
*/
class LimitedCollection extends Collection {
constructor(options = {}, iterable) {
if (typeof options !== 'object' || options === null) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
}
const { maxSize = Infinity, keepOverLimit = null } = options;
if (typeof maxSize !== 'number') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'maxSize', 'number');
}
if (keepOverLimit !== null && typeof keepOverLimit !== 'function') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'keepOverLimit', 'function');
}
super(iterable);
/**
* The max size of the Collection.
* @type {number}
*/
this.maxSize = maxSize;
/**
* A function called to check if an entry should be kept when the Collection is at max size.
* @type {?Function}
*/
this.keepOverLimit = keepOverLimit;
}
set(key, value) {
if (this.maxSize === 0 && !this.keepOverLimit?.(value, key, this)) return this;
if (this.size >= this.maxSize && !this.has(key)) {
for (const [k, v] of this.entries()) {
const keep = this.keepOverLimit?.(v, k, this) ?? false;
if (!keep) {
this.delete(k);
break;
}
}
}
return super.set(key, value);
}
static get [Symbol.species]() {
return Collection;
}
}
module.exports = LimitedCollection;

View File

@@ -0,0 +1,32 @@
'use strict';
const { MessageFlags } = require('discord-api-types/v10');
const BitField = require('./BitField');
/**
* Data structure that makes it easy to interact with a {@link Message#flags} bitfield.
* @extends {BitField}
*/
class MessageFlagsBitField extends BitField {
/**
* Numeric message flags.
* @type {MessageFlags}
* @memberof MessageFlagsBitField
*/
static Flags = MessageFlags;
}
/**
* @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
*/
module.exports = MessageFlagsBitField;

239
node_modules/discord.js/src/util/Options.js generated vendored Normal file
View File

@@ -0,0 +1,239 @@
'use strict';
const { DefaultRestOptions, DefaultUserAgentAppendix } = require('@discordjs/rest');
const { toSnakeCase } = require('./Transformers');
const { version } = require('../../package.json');
// TODO(ckohen): switch order of params so full manager is first and "type" is optional
/**
* @typedef {Function} CacheFactory
* @param {Function} managerType The base manager class the cache is being requested from.
* @param {Function} holds The class that the cache will hold.
* @param {Function} manager The fully extended manager class the cache is being requested from.
* @returns {Collection} A Collection used to store the cache of the manager.
*/
/**
* Options for a client.
* @typedef {Object} ClientOptions
* @property {number|number[]|string} [shards] The shard's id to run, or an array of shard ids. If not specified,
* the client will spawn {@link ClientOptions#shardCount} shards. If set to `auto`, it will fetch the
* recommended amount of shards from Discord and spawn that amount
* @property {number} [closeTimeout=5_000] The amount of time in milliseconds to wait for the close frame to be received
* from the WebSocket. Don't have this too high/low. It's best to have it between 2_000-6_000 ms.
* @property {number} [shardCount=1] The total amount of shards used by all processes of this bot
* (e.g. recommended shard count, shard count of the ShardingManager)
* @property {CacheFactory} [makeCache] Function to create a cache.
* 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 {MessageMentionOptions} [allowedMentions] The default value for {@link BaseMessageOptions#allowedMentions}
* @property {Partials[]} [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 {boolean} [failIfNotExists=true] The default value for {@link MessageReplyOptions#failIfNotExists}
* @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
* {@link GatewayIntentBits.Guilds} gateway intent should wait for missing guilds to be received before being ready.
* @property {SweeperOptions} [sweepers=this.DefaultSweeperSettings] 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 {boolean} [enforceNonce=false] The default value for {@link MessageReplyOptions#enforceNonce}
*/
/**
* Options for {@link Sweepers} defining the behavior of cache sweeping
* @typedef {Object<SweeperKey, SweepOptions>} SweeperOptions
*/
/**
* Options for sweeping a single type of item from cache
* @typedef {Object} SweepOptions
* @property {number} interval The interval (in seconds) at which to perform sweeping of the item
* @property {number} [lifetime] How long an item should stay in cache until it is considered sweepable.
* <warn>This property is only valid for the `invites`, `messages`, and `threads` keys. The `filter` property
* is mutually exclusive to this property and takes priority</warn>
* @property {GlobalSweepFilter} filter The function used to determine the function passed to the sweep method
* <info>This property is optional when the key is `invites`, `messages`, or `threads` and `lifetime` is set</info>
*/
/**
* A function to determine what strategy to use for sharding internally.
* ```js
* (manager) => new WorkerShardingStrategy(manager, { shardsPerWorker: 2 })
* ```
* @typedef {Function} BuildStrategyFunction
* @param {WSWebSocketManager} manager The WebSocketManager that is going to initiate the sharding
* @returns {IShardingStrategy} The strategy to use for sharding
*/
/**
* A function to change the concurrency handling for shard identifies of this manager
* ```js
* async (manager) => {
* const gateway = await manager.fetchGatewayInformation();
* return new SimpleIdentifyThrottler(gateway.session_start_limit.max_concurrency);
* }
* ```
* @typedef {Function} IdentifyThrottlerFunction
* @param {WSWebSocketManager} manager The WebSocketManager that is going to initiate the sharding
* @returns {Awaitable<IIdentifyThrottler>} The identify throttler that this ws manager will use
*/
/**
* WebSocket options (these are left as snake_case to match the API)
* @typedef {Object} WebsocketOptions
* @property {number} [large_threshold=50] Number of members in a guild after which offline users will no longer be
* sent in the initial guild member list, must be between 50 and 250
* @property {number} [version=10] The Discord gateway version to use <warn>Changing this can break the library;
* only set this if you know what you are doing</warn>
* @property {BuildStrategyFunction} [buildStrategy] Builds the strategy to use for sharding
* @property {IdentifyThrottlerFunction} [buildIdentifyThrottler] Builds the identify throttler to use for sharding
*/
/**
* Contains various utilities for client options.
*/
class Options extends null {
/**
* The default user agent appendix.
* @type {string}
* @memberof Options
* @private
*/
static userAgentAppendix = `discord.js/${version} ${DefaultUserAgentAppendix}`.trimEnd();
/**
* The default client options.
* @returns {ClientOptions}
*/
static createDefault() {
return {
closeTimeout: 5_000,
waitGuildTimeout: 15_000,
shardCount: 1,
makeCache: this.cacheWithLimits(this.DefaultMakeCacheSettings),
partials: [],
failIfNotExists: true,
enforceNonce: false,
presence: {},
sweepers: this.DefaultSweeperSettings,
ws: {
large_threshold: 50,
version: 10,
},
rest: {
...DefaultRestOptions,
userAgentAppendix: this.userAgentAppendix,
},
jsonTransformer: toSnakeCase,
};
}
/**
* Create a cache factory using predefined settings to sweep or limit.
* @param {Object<string, LimitedCollectionOptions|number>} [settings={}] Settings passed to the relevant constructor.
* If no setting is provided for a manager, it uses Collection.
* If a number is provided for a manager, it uses that number as the max size for a LimitedCollection.
* 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.
* Options.cacheWithLimits({
* MessageManager: 200,
* GuildMemberManager: {
* maxSize: 200,
* keepOverLimit: (member) => member.id === client.user.id,
* },
* });
*/
static cacheWithLimits(settings = {}) {
const { Collection } = require('@discordjs/collection');
const LimitedCollection = require('./LimitedCollection');
return (managerType, _, manager) => {
const setting = settings[manager.name] ?? settings[managerType.name];
/* eslint-disable-next-line eqeqeq */
if (setting == null) {
return new Collection();
}
if (typeof setting === 'number') {
if (setting === Infinity) {
return new Collection();
}
return new LimitedCollection({ maxSize: setting });
}
/* eslint-disable-next-line eqeqeq */
const noLimit = setting.maxSize == null || setting.maxSize === Infinity;
if (noLimit) {
return new Collection();
}
return new LimitedCollection(setting);
};
}
/**
* Create a cache factory that always caches everything.
* @returns {CacheFactory}
*/
static cacheEverything() {
const { Collection } = require('@discordjs/collection');
return () => new Collection();
}
/**
* The default settings passed to {@link ClientOptions.makeCache}.
* The caches that this changes are:
* * `MessageManager` - Limit to 200 messages
* <info>If you want to keep default behavior and add on top of it you can use this object and add on to it, e.g.
* `makeCache: Options.cacheWithLimits({ ...Options.DefaultMakeCacheSettings, ReactionManager: 0 })`</info>
* @type {Object<string, LimitedCollectionOptions|number>}
*/
static get DefaultMakeCacheSettings() {
return {
MessageManager: 200,
};
}
/**
* The default settings passed to {@link ClientOptions.sweepers}.
* The sweepers that this changes are:
* * `threads` - Sweep archived threads every hour, removing those archived more than 4 hours ago
* <info>If you want to keep default behavior and add on top of it you can use this object and add on to it, e.g.
* `sweepers: { ...Options.DefaultSweeperSettings, messages: { interval: 300, lifetime: 600 } }`</info>
* @type {SweeperOptions}
*/
static get DefaultSweeperSettings() {
return {
threads: {
interval: 3600,
lifetime: 14400,
},
};
}
}
module.exports = Options;
/**
* @external RESTOptions
* @see {@link https://discord.js.org/docs/packages/rest/stable/RESTOptions:Interface}
*/
/**
* @external WSWebSocketManager
* @see {@link https://discord.js.org/docs/packages/ws/stable/WebSocketManager:Class}
*/
/**
* @external IShardingStrategy
* @see {@link https://discord.js.org/docs/packages/ws/stable/IShardingStrategy:Interface}
*/
/**
* @external IIdentifyThrottler
* @see {@link https://discord.js.org/docs/packages/ws/stable/IIdentifyThrottler:Interface}
*/

44
node_modules/discord.js/src/util/Partials.js generated vendored Normal file
View File

@@ -0,0 +1,44 @@
'use strict';
const { createEnum } = require('./Enums');
/**
* The enumeration for partials.
* ```js
* import { Client, Partials } from 'discord.js';
*
* const client = new Client({
* intents: [
* // Intents...
* ],
* partials: [
* Partials.User, // We want to receive uncached users!
* Partials.Message // We want to receive uncached messages!
* ]
* });
* ```
* @typedef {Object} Partials
* @property {number} User The partial to receive uncached users.
* @property {number} Channel The partial to receive uncached channels.
* <info>This is required to receive direct messages!</info>
* @property {number} GuildMember The partial to receive uncached guild members.
* @property {number} Message The partial to receive uncached messages.
* @property {number} Reaction The partial to receive uncached reactions.
* @property {number} GuildScheduledEvent The partial to receive uncached guild scheduled events.
* @property {number} ThreadMember The partial to receive uncached thread members.
*/
// JSDoc for IntelliSense purposes
/**
* @type {Partials}
* @ignore
*/
module.exports = createEnum([
'User',
'Channel',
'GuildMember',
'Message',
'Reaction',
'GuildScheduledEvent',
'ThreadMember',
]);

104
node_modules/discord.js/src/util/PermissionsBitField.js generated vendored Normal file
View File

@@ -0,0 +1,104 @@
'use strict';
const { PermissionFlagsBits } = require('discord-api-types/v10');
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 {
/**
* Numeric permission flags.
* @type {PermissionFlagsBits}
* @memberof PermissionsBitField
* @see {@link https://discord.com/developers/docs/topics/permissions#permissions-bitwise-permission-flags}
*/
static Flags = PermissionFlagsBits;
/**
* Bitfield representing every permission combined
* @type {bigint}
* @memberof PermissionsBitField
*/
static All = Object.values(PermissionFlagsBits).reduce((all, p) => all | p, 0n);
/**
* Bitfield representing the default permissions for users
* @type {bigint}
* @memberof PermissionsBitField
*/
static Default = BigInt(104324673);
/**
* Bitfield representing the permissions required for moderators of stage channels
* @type {bigint}
* @memberof PermissionsBitField
*/
static StageModerator =
PermissionFlagsBits.ManageChannels | PermissionFlagsBits.MuteMembers | PermissionFlagsBits.MoveMembers;
/**
* @type {bigint}
* @memberof PermissionsBitField
* @private
*/
static DefaultBit = BigInt(0);
/**
* Bitfield of the packed bits
* @type {bigint}
* @name PermissionsBitField#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);
}
}
module.exports = PermissionsBitField;

26
node_modules/discord.js/src/util/RoleFlagsBitField.js generated vendored Normal file
View File

@@ -0,0 +1,26 @@
'use strict';
const { RoleFlags } = require('discord-api-types/v10');
const BitField = require('./BitField');
/**
* Data structure that makes it easy to interact with a {@link Role#flags} bitfield.
* @extends {BitField}
*/
class RoleFlagsBitField extends BitField {
/**
* Numeric role flags.
* @type {RoleFlags}
* @memberof RoleFlagsBitField
*/
static Flags = RoleFlags;
}
/**
* @name RoleFlagsBitField
* @kind constructor
* @memberof RoleFlagsBitField
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
*/
module.exports = RoleFlagsBitField;

26
node_modules/discord.js/src/util/SKUFlagsBitField.js generated vendored Normal file
View File

@@ -0,0 +1,26 @@
'use strict';
const { SKUFlags } = require('discord-api-types/v10');
const BitField = require('./BitField');
/**
* Data structure that makes it easy to interact with an {@link SKU#flags} bitfield.
* @extends {BitField}
*/
class SKUFlagsBitField extends BitField {
/**
* Numeric SKU flags.
* @type {SKUFlags}
* @memberof SKUFlagsBitField
*/
static Flags = SKUFlags;
}
/**
* @name SKUFlagsBitField
* @kind constructor
* @memberof SKUFlagsBitField
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
*/
exports.SKUFlagsBitField = SKUFlagsBitField;

29
node_modules/discord.js/src/util/ShardEvents.js generated vendored Normal file
View File

@@ -0,0 +1,29 @@
'use strict';
/**
* @typedef {Object} ShardEvents
* @property {string} Death death
* @property {string} Disconnect disconnect
* @property {string} Error error
* @property {string} Message message
* @property {string} Ready ready
* @property {string} Reconnecting reconnecting
* @property {string} Resume resume
* @property {string} Spawn spawn
*/
// JSDoc for IntelliSense purposes
/**
* @type {ShardEvents}
* @ignore
*/
module.exports = {
Death: 'death',
Disconnect: 'disconnect',
Error: 'error',
Message: 'message',
Ready: 'ready',
Reconnecting: 'reconnecting',
Resume: 'resume',
Spawn: 'spawn',
};

33
node_modules/discord.js/src/util/Status.js generated vendored Normal file
View File

@@ -0,0 +1,33 @@
'use strict';
const { createEnum } = require('./Enums');
/**
* @typedef {Object} Status
* @property {number} Ready
* @property {number} Connecting
* @property {number} Reconnecting
* @property {number} Idle
* @property {number} Nearly
* @property {number} Disconnected
* @property {number} WaitingForGuilds
* @property {number} Identifying
* @property {number} Resuming
*/
// JSDoc for IntelliSense purposes
/**
* @type {Status}
* @ignore
*/
module.exports = createEnum([
'Ready',
'Connecting',
'Reconnecting',
'Idle',
'Nearly',
'Disconnected',
'WaitingForGuilds',
'Identifying',
'Resuming',
]);

487
node_modules/discord.js/src/util/Sweepers.js generated vendored Normal file
View File

@@ -0,0 +1,487 @@
'use strict';
const { setInterval, clearInterval } = require('node:timers');
const { ThreadChannelTypes, SweeperKeys } = require('./Constants');
const Events = require('./Events');
const { DiscordjsTypeError, ErrorCodes } = require('../errors');
/**
* @typedef {Function} GlobalSweepFilter
* @returns {?Function} Return `null` to skip sweeping, otherwise a function passed to `sweep()`,
* See {@link https://discord.js.org/docs/packages/collection/stable/Collection:Class#sweep Collection#sweep}
* for the definition of this function.
*/
/**
* A container for all cache sweeping intervals and their associated sweep methods.
*/
class Sweepers {
constructor(client, options) {
/**
* The client that instantiated this
* @type {Client}
* @readonly
*/
Object.defineProperty(this, 'client', { value: client });
/**
* The options the sweepers were instantiated with
* @type {SweeperOptions}
*/
this.options = options;
/**
* A record of interval timeout that is used to sweep the indicated items, or null if not being swept
* @type {Object<SweeperKey, ?Timeout>}
*/
this.intervals = Object.fromEntries(SweeperKeys.map(key => [key, null]));
for (const key of SweeperKeys) {
if (!(key in options)) continue;
this._validateProperties(key);
const clonedOptions = { ...this.options[key] };
// Handle cases that have a "lifetime"
if (!('filter' in clonedOptions)) {
switch (key) {
case 'invites':
clonedOptions.filter = this.constructor.expiredInviteSweepFilter(clonedOptions.lifetime);
break;
case 'messages':
clonedOptions.filter = this.constructor.outdatedMessageSweepFilter(clonedOptions.lifetime);
break;
case 'threads':
clonedOptions.filter = this.constructor.archivedThreadSweepFilter(clonedOptions.lifetime);
}
}
this._initInterval(key, `sweep${key[0].toUpperCase()}${key.slice(1)}`, clonedOptions);
}
}
/**
* Sweeps all guild and global application commands and removes the ones which are indicated by the filter.
* @param {Function} filter The function used to determine which commands will be removed from the caches.
* @returns {number} Amount of commands that were removed from the caches
*/
sweepApplicationCommands(filter) {
const { guilds, items: guildCommands } = this._sweepGuildDirectProp('commands', filter, { emit: false });
const globalCommands = this.client.application?.commands.cache.sweep(filter) ?? 0;
this.client.emit(
Events.CacheSweep,
`Swept ${globalCommands} global application commands and ${guildCommands} guild commands in ${guilds} guilds.`,
);
return guildCommands + globalCommands;
}
/**
* Sweeps all auto moderation rules and removes the ones which are indicated by the filter.
* @param {Function} filter The function used to determine
* which auto moderation rules will be removed from the caches
* @returns {number} Amount of auto moderation rules that were removed from the caches
*/
sweepAutoModerationRules(filter) {
return this._sweepGuildDirectProp('autoModerationRules', filter).items;
}
/**
* Sweeps all guild bans and removes the ones which are indicated by the filter.
* @param {Function} filter The function used to determine which bans will be removed from the caches.
* @returns {number} Amount of bans that were removed from the caches
*/
sweepBans(filter) {
return this._sweepGuildDirectProp('bans', filter).items;
}
/**
* Sweeps all guild emojis and removes the ones which are indicated by the filter.
* @param {Function} filter The function used to determine which emojis will be removed from the caches.
* @returns {number} Amount of emojis that were removed from the caches
*/
sweepEmojis(filter) {
return this._sweepGuildDirectProp('emojis', filter).items;
}
/**
* Sweeps all client application entitlements and removes the ones which are indicated by the filter.
* @param {Function} filter The function used to determine which entitlements will be removed from the caches.
* @returns {number} Amount of entitlements that were removed from the caches
*/
sweepEntitlements(filter) {
if (typeof filter !== 'function') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'filter', 'function');
}
const entitlements = this.client.application.entitlements.cache.sweep(filter);
this.client.emit(Events.CacheSweep, `Swept ${entitlements} entitlements.`);
return entitlements;
}
/**
* Sweeps all guild invites and removes the ones which are indicated by the filter.
* @param {Function} filter The function used to determine which invites will be removed from the caches.
* @returns {number} Amount of invites that were removed from the caches
*/
sweepInvites(filter) {
return this._sweepGuildDirectProp('invites', filter).items;
}
/**
* Sweeps all guild members and removes the ones which are indicated by the filter.
* <info>It is highly recommended to keep the client guild member cached</info>
* @param {Function} filter The function used to determine which guild members will be removed from the caches.
* @returns {number} Amount of guild members that were removed from the caches
*/
sweepGuildMembers(filter) {
return this._sweepGuildDirectProp('members', filter, { outputName: 'guild members' }).items;
}
/**
* Sweeps all text-based channels' messages and removes the ones which are indicated by the filter.
* @param {Function} filter The function used to determine which messages will be removed from the caches.
* @returns {number} Amount of messages that were removed from the caches
* @example
* // Remove all messages older than 1800 seconds from the messages cache
* const amount = sweepers.sweepMessages(
* Sweepers.filterByLifetime({
* lifetime: 1800,
* getComparisonTimestamp: m => m.editedTimestamp ?? m.createdTimestamp,
* })(),
* );
* console.log(`Successfully removed ${amount} messages from the cache.`);
*/
sweepMessages(filter) {
if (typeof filter !== 'function') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'filter', 'function');
}
let channels = 0;
let messages = 0;
for (const channel of this.client.channels.cache.values()) {
if (!channel.isTextBased()) continue;
channels++;
messages += channel.messages.cache.sweep(filter);
}
this.client.emit(Events.CacheSweep, `Swept ${messages} messages in ${channels} text-based channels.`);
return messages;
}
/**
* Sweeps all presences and removes the ones which are indicated by the filter.
* @param {Function} filter The function used to determine which presences will be removed from the caches.
* @returns {number} Amount of presences that were removed from the caches
*/
sweepPresences(filter) {
return this._sweepGuildDirectProp('presences', filter).items;
}
/**
* Sweeps all message reactions and removes the ones which are indicated by the filter.
* @param {Function} filter The function used to determine which reactions will be removed from the caches.
* @returns {number} Amount of reactions that were removed from the caches
*/
sweepReactions(filter) {
if (typeof filter !== 'function') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'filter', 'function');
}
let channels = 0;
let messages = 0;
let reactions = 0;
for (const channel of this.client.channels.cache.values()) {
if (!channel.isTextBased()) continue;
channels++;
for (const message of channel.messages.cache.values()) {
messages++;
reactions += message.reactions.cache.sweep(filter);
}
}
this.client.emit(
Events.CacheSweep,
`Swept ${reactions} reactions on ${messages} messages in ${channels} text-based channels.`,
);
return reactions;
}
/**
* Sweeps all guild stage instances and removes the ones which are indicated by the filter.
* @param {Function} filter The function used to determine which stage instances will be removed from the caches.
* @returns {number} Amount of stage instances that were removed from the caches
*/
sweepStageInstances(filter) {
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>
* @param {Function} filter The function used to determine which thread members will be removed from the caches.
* @returns {number} Amount of thread members that were removed from the caches
*/
sweepThreadMembers(filter) {
if (typeof filter !== 'function') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'filter', 'function');
}
let threads = 0;
let members = 0;
for (const channel of this.client.channels.cache.values()) {
if (!ThreadChannelTypes.includes(channel.type)) continue;
threads++;
members += channel.members.cache.sweep(filter);
}
this.client.emit(Events.CacheSweep, `Swept ${members} thread members in ${threads} threads.`);
return members;
}
/**
* Sweeps all threads and removes the ones which are indicated by the filter.
* @param {Function} filter The function used to determine which threads will be removed from the caches.
* @returns {number} filter Amount of threads that were removed from the caches
* @example
* // Remove all threads archived greater than 1 day ago from all the channel caches
* const amount = sweepers.sweepThreads(
* Sweepers.filterByLifetime({
* getComparisonTimestamp: t => t.archivedTimestamp,
* excludeFromSweep: t => !t.archived,
* })(),
* );
* console.log(`Successfully removed ${amount} threads from the cache.`);
*/
sweepThreads(filter) {
if (typeof filter !== 'function') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'filter', 'function');
}
let threads = 0;
for (const [key, val] of this.client.channels.cache.entries()) {
if (!ThreadChannelTypes.includes(val.type)) continue;
if (filter(val, key, this.client.channels.cache)) {
threads++;
this.client.channels._remove(key);
}
}
this.client.emit(Events.CacheSweep, `Swept ${threads} threads.`);
return threads;
}
/**
* Sweeps all users and removes the ones which are indicated by the filter.
* @param {Function} filter The function used to determine which users will be removed from the caches.
* @returns {number} Amount of users that were removed from the caches
*/
sweepUsers(filter) {
if (typeof filter !== 'function') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'filter', 'function');
}
const users = this.client.users.cache.sweep(filter);
this.client.emit(Events.CacheSweep, `Swept ${users} users.`);
return users;
}
/**
* Sweeps all guild voice states and removes the ones which are indicated by the filter.
* @param {Function} filter The function used to determine which voice states will be removed from the caches.
* @returns {number} Amount of voice states that were removed from the caches
*/
sweepVoiceStates(filter) {
return this._sweepGuildDirectProp('voiceStates', filter, { outputName: 'voice states' }).items;
}
/**
* Cancels all sweeping intervals
* @returns {void}
*/
destroy() {
for (const key of SweeperKeys) {
if (this.intervals[key]) clearInterval(this.intervals[key]);
}
}
/**
* Options for generating a filter function based on lifetime
* @typedef {Object} LifetimeFilterOptions
* @property {number} [lifetime=14400] How long, in seconds, an entry should stay in the collection
* before it is considered sweepable.
* @property {Function} [getComparisonTimestamp=e => e?.createdTimestamp] A function that takes an entry, key,
* and the collection and returns a timestamp to compare against in order to determine the lifetime of the entry.
* @property {Function} [excludeFromSweep=() => false] A function that takes an entry, key, and the collection
* and returns a boolean, `true` when the entry should not be checked for sweepability.
*/
/**
* Create a sweepFilter function that uses a lifetime to determine sweepability.
* @param {LifetimeFilterOptions} [options={}] The options used to generate the filter function
* @returns {GlobalSweepFilter}
*/
static filterByLifetime({
lifetime = 14400,
getComparisonTimestamp = e => e?.createdTimestamp,
excludeFromSweep = () => false,
} = {}) {
if (typeof lifetime !== 'number') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'lifetime', 'number');
}
if (typeof getComparisonTimestamp !== 'function') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'getComparisonTimestamp', 'function');
}
if (typeof excludeFromSweep !== 'function') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'excludeFromSweep', 'function');
}
return () => {
if (lifetime <= 0) return null;
const lifetimeMs = lifetime * 1_000;
const now = Date.now();
return (entry, key, coll) => {
if (excludeFromSweep(entry, key, coll)) {
return false;
}
const comparisonTimestamp = getComparisonTimestamp(entry, key, coll);
if (!comparisonTimestamp || typeof comparisonTimestamp !== 'number') return false;
return now - comparisonTimestamp > lifetimeMs;
};
};
}
/**
* 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
* @returns {GlobalSweepFilter}
*/
static archivedThreadSweepFilter(lifetime = 14400) {
return this.filterByLifetime({
lifetime,
getComparisonTimestamp: e => e.archiveTimestamp,
excludeFromSweep: e => !e.archived,
});
}
/**
* Creates a sweep filter that sweeps expired invites
* @param {number} [lifetime=14400] How long ago an invite has to have expired to be valid for sweeping
* @returns {GlobalSweepFilter}
*/
static expiredInviteSweepFilter(lifetime = 14400) {
return this.filterByLifetime({
lifetime,
getComparisonTimestamp: i => i.expiresTimestamp,
});
}
/**
* Creates a sweep filter that sweeps outdated messages (edits taken into account)
* @param {number} [lifetime=3600] How long ago a message has to have been sent or edited to be valid for sweeping
* @returns {GlobalSweepFilter}
*/
static outdatedMessageSweepFilter(lifetime = 3600) {
return this.filterByLifetime({
lifetime,
getComparisonTimestamp: m => m.editedTimestamp ?? m.createdTimestamp,
});
}
/**
* Configuration options for emitting the cache sweep client event
* @typedef {Object} SweepEventOptions
* @property {boolean} [emit=true] Whether to emit the client event in this method
* @property {string} [outputName] A name to output in the client event if it should differ from the key
* @private
*/
/**
* Sweep a direct sub property of all guilds
* @param {string} key The name of the property
* @param {Function} filter Filter function passed to sweep
* @param {SweepEventOptions} [eventOptions={}] Options for the Client event emitted here
* @returns {Object} Object containing the number of guilds swept and the number of items swept
* @private
*/
_sweepGuildDirectProp(key, filter, { emit = true, outputName } = {}) {
if (typeof filter !== 'function') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'filter', 'function');
}
let guilds = 0;
let items = 0;
for (const guild of this.client.guilds.cache.values()) {
// We may be unable to sweep the cache if the guild is unavailable and was never patched
if (!guild.available) continue;
const { cache } = guild[key];
guilds++;
items += cache.sweep(filter);
}
if (emit) {
this.client.emit(Events.CacheSweep, `Swept ${items} ${outputName ?? key} in ${guilds} guilds.`);
}
return { guilds, items };
}
/**
* Validates a set of properties
* @param {string} key Key of the options object to check
* @private
*/
_validateProperties(key) {
const props = this.options[key];
if (typeof props !== 'object') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, `sweepers.${key}`, 'object', true);
}
if (typeof props.interval !== 'number') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, `sweepers.${key}.interval`, 'number');
}
// Invites, Messages, and Threads can be provided a lifetime parameter, which we use to generate the filter
if (['invites', 'messages', 'threads'].includes(key) && !('filter' in props)) {
if (typeof props.lifetime !== 'number') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, `sweepers.${key}.lifetime`, 'number');
}
return;
}
if (typeof props.filter !== 'function') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, `sweepers.${key}.filter`, 'function');
}
}
/**
* Initialize an interval for sweeping
* @param {string} intervalKey The name of the property that stores the interval for this sweeper
* @param {string} sweepKey The name of the function that sweeps the desired caches
* @param {Object} opts Validated options for a sweep
* @private
*/
_initInterval(intervalKey, sweepKey, opts) {
if (opts.interval <= 0 || opts.interval === Infinity) return;
this.intervals[intervalKey] = setInterval(() => {
const sweepFn = opts.filter();
if (sweepFn === null) return;
if (typeof sweepFn !== 'function') throw new DiscordjsTypeError(ErrorCodes.SweepFilterReturn);
this[sweepKey](sweepFn);
}, opts.interval * 1_000).unref();
}
}
module.exports = Sweepers;

3
node_modules/discord.js/src/util/Symbols.js generated vendored Normal file
View File

@@ -0,0 +1,3 @@
'use strict';
exports.MakeCacheOverrideSymbol = Symbol('djs.managers.makeCacheOverride');

View File

@@ -0,0 +1,43 @@
'use strict';
const { GuildSystemChannelFlags } = require('discord-api-types/v10');
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 {
/**
* Numeric system channel flags.
* @type {GuildSystemChannelFlags}
* @memberof SystemChannelFlagsBitField
*/
static Flags = GuildSystemChannelFlags;
}
/**
* @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
*/
module.exports = SystemChannelFlagsBitField;

View File

@@ -0,0 +1,31 @@
'use strict';
const BitField = require('./BitField');
/**
* Data structure that makes it easy to interact with a {@link ThreadMember#flags} bitfield.
* @extends {BitField}
*/
class ThreadMemberFlagsBitField extends BitField {
/**
* Numeric thread member flags. There are currently no bitflags relevant to bots for this.
* @type {Object<string, number>}
* @memberof ThreadMemberFlagsBitField
*/
static Flags = {};
}
/**
* @name ThreadMemberFlagsBitField
* @kind constructor
* @memberof ThreadMemberFlagsBitField
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
*/
/**
* Bitfield of the packed bits
* @type {number}
* @name ThreadMemberFlagsBitField#bitfield
*/
module.exports = ThreadMemberFlagsBitField;

57
node_modules/discord.js/src/util/Transformers.js generated vendored Normal file
View File

@@ -0,0 +1,57 @@
'use strict';
const { isJSONEncodable } = require('@discordjs/util');
const snakeCase = require('lodash.snakecase');
/**
* Transforms camel-cased keys into snake cased keys
* @param {*} obj The object to transform
* @returns {*}
*/
function toSnakeCase(obj) {
if (typeof obj !== 'object' || !obj) return obj;
if (obj instanceof Date) return obj;
if (isJSONEncodable(obj)) return toSnakeCase(obj.toJSON());
if (Array.isArray(obj)) return obj.map(toSnakeCase);
return Object.fromEntries(Object.entries(obj).map(([key, value]) => [snakeCase(key), toSnakeCase(value)]));
}
/**
* Transforms an API auto moderation action object to a camel-cased variant.
* @param {APIAutoModerationAction} autoModerationAction The action to transform
* @returns {AutoModerationAction}
* @ignore
*/
function _transformAPIAutoModerationAction(autoModerationAction) {
return {
type: autoModerationAction.type,
metadata: {
durationSeconds: autoModerationAction.metadata.duration_seconds ?? null,
channelId: autoModerationAction.metadata.channel_id ?? null,
customMessage: autoModerationAction.metadata.custom_message ?? null,
},
};
}
/**
* Transforms an API message interaction metadata object to a camel-cased variant.
* @param {Client} client The client
* @param {APIMessageInteractionMetadata} messageInteractionMetadata The metadata to transform
* @returns {MessageInteractionMetadata}
* @ignore
*/
function _transformAPIMessageInteractionMetadata(client, messageInteractionMetadata) {
return {
id: messageInteractionMetadata.id,
type: messageInteractionMetadata.type,
user: client.users._add(messageInteractionMetadata.user),
authorizingIntegrationOwners: messageInteractionMetadata.authorizing_integration_owners,
originalResponseMessageId: messageInteractionMetadata.original_response_message_id ?? null,
interactedMessageId: messageInteractionMetadata.interacted_message_id ?? null,
triggeringInteractionMetadata: messageInteractionMetadata.triggering_interaction_metadata
? _transformAPIMessageInteractionMetadata(client, messageInteractionMetadata.triggering_interaction_metadata)
: null,
};
}
module.exports = { toSnakeCase, _transformAPIAutoModerationAction, _transformAPIMessageInteractionMetadata };

32
node_modules/discord.js/src/util/UserFlagsBitField.js generated vendored Normal file
View File

@@ -0,0 +1,32 @@
'use strict';
const { UserFlags } = require('discord-api-types/v10');
const BitField = require('./BitField');
/**
* Data structure that makes it easy to interact with a {@link User#flags} bitfield.
* @extends {BitField}
*/
class UserFlagsBitField extends BitField {
/**
* Numeric user flags.
* @type {UserFlags}
* @memberof UserFlagsBitField
*/
static Flags = UserFlags;
}
/**
* @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
*/
module.exports = UserFlagsBitField;

526
node_modules/discord.js/src/util/Util.js generated vendored Normal file
View File

@@ -0,0 +1,526 @@
'use strict';
const { parse } = require('node:path');
const { Collection } = require('@discordjs/collection');
const { ChannelType, RouteBases, Routes } = require('discord-api-types/v10');
const { fetch } = require('undici');
const Colors = require('./Colors');
const { DiscordjsError, DiscordjsRangeError, DiscordjsTypeError, ErrorCodes } = require('../errors');
const isObject = d => typeof d === 'object' && d !== null;
/**
* Flatten an object. Any properties that are collections will get converted to an array of keys.
* @param {Object} obj The object to flatten.
* @param {...Object<string, boolean|string>} [props] Specific properties to include/exclude.
* @returns {Object}
*/
function flatten(obj, ...props) {
if (!isObject(obj)) return obj;
const objProps = Object.keys(obj)
.filter(key => !key.startsWith('_'))
.map(key => ({ [key]: true }));
props = objProps.length ? Object.assign(...objProps, ...props) : Object.assign({}, ...props);
const out = {};
for (let [prop, newProp] of Object.entries(props)) {
if (!newProp) continue;
newProp = newProp === true ? prop : newProp;
const element = obj[prop];
const elemIsObj = isObject(element);
const valueOf = elemIsObj && typeof element.valueOf === 'function' ? element.valueOf() : null;
const hasToJSON = elemIsObj && typeof element.toJSON === 'function';
// If it's a Collection, make the array of keys
if (element instanceof Collection) out[newProp] = Array.from(element.keys());
// If the valueOf is a Collection, use its array of keys
else if (valueOf instanceof Collection) out[newProp] = Array.from(valueOf.keys());
// If it's an array, call toJSON function on each element if present, otherwise flatten each element
else if (Array.isArray(element)) out[newProp] = element.map(elm => elm.toJSON?.() ?? flatten(elm));
// If it's an object with a primitive `valueOf`, use that value
else if (typeof valueOf !== 'object') out[newProp] = valueOf;
// If it's an object with a toJSON function, use the return value of it
else if (hasToJSON) out[newProp] = element.toJSON();
// If element is an object, use the flattened version of it
else if (typeof element === 'object') out[newProp] = flatten(element);
// If it's a primitive
else if (!elemIsObj) out[newProp] = element;
}
return out;
}
/**
* @typedef {Object} FetchRecommendedShardCountOptions
* @property {number} [guildsPerShard=1000] Number of guilds assigned per shard
* @property {number} [multipleOf=1] The multiple the shard count should round up to. (16 for large bot sharding)
*/
/**
* Gets the recommended shard count from Discord.
* @param {string} token Discord auth token
* @param {FetchRecommendedShardCountOptions} [options] Options for fetching the recommended shard count
* @returns {Promise<number>} The recommended number of shards
*/
async function fetchRecommendedShardCount(token, { guildsPerShard = 1_000, multipleOf = 1 } = {}) {
if (!token) throw new DiscordjsError(ErrorCodes.TokenMissing);
const response = await fetch(RouteBases.api + Routes.gatewayBot(), {
method: 'GET',
headers: { Authorization: `Bot ${token.replace(/^Bot\s*/i, '')}` },
});
if (!response.ok) {
if (response.status === 401) throw new DiscordjsError(ErrorCodes.TokenInvalid);
throw response;
}
const { shards } = await response.json();
return Math.ceil((shards * (1_000 / guildsPerShard)) / multipleOf) * multipleOf;
}
/**
* A partial emoji object.
* @typedef {Object} PartialEmoji
* @property {boolean} animated Whether the emoji is animated
* @property {Snowflake|undefined} id The id of the emoji
* @property {string} name The name of the emoji
*/
/**
* Parses emoji info out of a string. The string must be one of:
* * A UTF-8 emoji (no id)
* * A URL-encoded UTF-8 emoji (no id)
* * A Discord custom emoji (`<:name:id>` or `<a:name:id>`)
* @param {string} text Emoji string to parse
* @returns {?PartialEmoji}
*/
function parseEmoji(text) {
if (text.includes('%')) text = decodeURIComponent(text);
if (!text.includes(':')) return { animated: false, name: text, id: undefined };
const match = text.match(/<?(?:(a):)?(\w{2,32}):(\d{17,19})?>?/);
return match && { animated: Boolean(match[1]), name: match[2], id: match[3] };
}
/**
* A partial emoji object with only an id.
* @typedef {Object} PartialEmojiOnlyId
* @property {Snowflake} id The id of the emoji
*/
/**
* Resolves a partial emoji object from an {@link EmojiIdentifierResolvable}, without checking a Client.
* @param {Emoji|EmojiIdentifierResolvable} emoji Emoji identifier to resolve
* @returns {?(PartialEmoji|PartialEmojiOnlyId)} Supplying a snowflake yields `PartialEmojiOnlyId`.
* @private
*/
function resolvePartialEmoji(emoji) {
if (!emoji) return null;
if (typeof emoji === 'string') return /^\d{17,19}$/.test(emoji) ? { id: emoji } : parseEmoji(emoji);
const { id, name, animated } = emoji;
if (!id && !name) return null;
return { id, name, animated: Boolean(animated) };
}
/**
* Options used to make an error object.
* @typedef {Object} MakeErrorOptions
* @property {string} name Error type
* @property {string} message Message for the error
* @property {string} stack Stack for the error
* @private
*/
/**
* Makes an Error from a plain info object.
* @param {MakeErrorOptions} obj Error info
* @returns {Error}
* @private
*/
function makeError(obj) {
const err = new Error(obj.message);
err.name = obj.name;
err.stack = obj.stack;
return err;
}
/**
* Makes a plain error info object from an Error.
* @param {Error} err Error to get info from
* @returns {MakeErrorOptions}
* @private
*/
function makePlainError(err) {
return {
name: err.name,
message: err.message,
stack: err.stack,
};
}
const TextSortableGroupTypes = [
ChannelType.GuildText,
ChannelType.GuildAnnouncement,
ChannelType.GuildForum,
ChannelType.GuildMedia,
];
const VoiceSortableGroupTypes = [ChannelType.GuildVoice, ChannelType.GuildStageVoice];
const CategorySortableGroupTypes = [ChannelType.GuildCategory];
/**
* Gets an array of the channel types that can be moved in the channel group. For example, a GuildText channel would
* return an array containing the types that can be ordered within the text channels (always at the top), and a voice
* channel would return an array containing the types that can be ordered within the voice channels (always at the
* bottom).
* @param {ChannelType} type The type of the channel
* @returns {ChannelType[]}
* @private
*/
function getSortableGroupTypes(type) {
switch (type) {
case ChannelType.GuildText:
case ChannelType.GuildAnnouncement:
case ChannelType.GuildForum:
case ChannelType.GuildMedia:
return TextSortableGroupTypes;
case ChannelType.GuildVoice:
case ChannelType.GuildStageVoice:
return VoiceSortableGroupTypes;
case ChannelType.GuildCategory:
return CategorySortableGroupTypes;
default:
return [type];
}
}
/**
* Moves an element in an array *in place*.
* @param {Array<*>} array Array to modify
* @param {*} element Element to move
* @param {number} newIndex Index or offset to move the element to
* @param {boolean} [offset=false] Move the element by an offset amount rather than to a set index
* @returns {number}
* @private
*/
function moveElementInArray(array, element, newIndex, offset = false) {
const index = array.indexOf(element);
newIndex = (offset ? index : 0) + newIndex;
if (newIndex > -1 && newIndex < array.length) {
const removedElement = array.splice(index, 1)[0];
array.splice(newIndex, 0, removedElement);
}
return array.indexOf(element);
}
/**
* Verifies the provided data is a string, otherwise throws provided error.
* @param {string} data The string resolvable to resolve
* @param {Function} [error] The Error constructor to instantiate. Defaults to Error
* @param {string} [errorMessage] The error message to throw with. Defaults to "Expected string, got <data> instead."
* @param {boolean} [allowEmpty=true] Whether an empty string should be allowed
* @returns {string}
*/
function verifyString(
data,
error = Error,
errorMessage = `Expected a string, got ${data} instead.`,
allowEmpty = true,
) {
if (typeof data !== 'string') throw new error(errorMessage);
if (!allowEmpty && data.length === 0) throw new error(errorMessage);
return data;
}
/**
* Can be a number, hex string, an RGB array like:
* ```js
* [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`
* @typedef {string|number|number[]} ColorResolvable
*/
/**
* Resolves a ColorResolvable into a color number.
* @param {ColorResolvable} color Color to resolve
* @returns {number} A color
*/
function resolveColor(color) {
let resolvedColor;
if (typeof color === 'string') {
if (color === 'Random') return Math.floor(Math.random() * (0xffffff + 1));
if (color === 'Default') return 0;
if (/^#?[\da-f]{6}$/i.test(color)) return parseInt(color.replace('#', ''), 16);
resolvedColor = Colors[color];
} else if (Array.isArray(color)) {
resolvedColor = (color[0] << 16) + (color[1] << 8) + color[2];
} else {
resolvedColor = color;
}
if (!Number.isInteger(resolvedColor)) {
throw new DiscordjsTypeError(ErrorCodes.ColorConvert, color);
}
if (resolvedColor < 0 || resolvedColor > 0xffffff) {
throw new DiscordjsRangeError(ErrorCodes.ColorRange);
}
return resolvedColor;
}
/**
* Sorts by Discord's position and id.
* @param {Collection} collection Collection of objects to sort
* @returns {Collection}
*/
function discordSort(collection) {
const isGuildChannel = collection.first() instanceof GuildChannel;
return collection.sorted(
isGuildChannel
? (a, b) => a.rawPosition - b.rawPosition || Number(BigInt(a.id) - BigInt(b.id))
: (a, b) => a.rawPosition - b.rawPosition || Number(BigInt(b.id) - BigInt(a.id)),
);
}
/**
* Sets the position of a Channel or Role.
* @param {BaseChannel|Role} item Object to set the position of
* @param {number} position New position for the object
* @param {boolean} relative Whether `position` is relative to its current position
* @param {Collection<string, BaseChannel|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 {string} [reason] Reason for the change
* @returns {Promise<BaseChannel[]|Role[]>} Updated item list, with `id` and `position` properties
* @private
*/
async function setPosition(item, position, relative, sorted, client, route, reason) {
let updatedItems = [...sorted.values()];
moveElementInArray(updatedItems, item, position, relative);
updatedItems = updatedItems.map((r, i) => ({ id: r.id, position: i }));
await client.rest.patch(route, { body: updatedItems, reason });
return updatedItems;
}
/**
* Alternative to Node's `path.basename`, removing query string after the extension if it exists.
* @param {string} path Path to get the basename of
* @param {string} [ext] File extension to remove
* @returns {string} Basename of the path
* @private
*/
function basename(path, ext) {
const res = parse(path);
return ext && res.ext.startsWith(ext) ? res.name : res.base.split('?')[0];
}
/**
* The content to have all mentions replaced by the equivalent text.
* @param {string} str The string to be converted
* @param {TextBasedChannels} channel The channel the string was sent in
* @returns {string}
*/
function cleanContent(str, channel) {
return str.replaceAll(
/* eslint-disable max-len */
/<(?:(?<type>@[!&]?|#)|(?:\/(?<commandName>[-_\p{L}\p{N}\p{sc=Deva}\p{sc=Thai} ]+):)|(?:a?:(?<emojiName>[\w]+):))(?<id>\d{17,19})>/gu,
(match, type, commandName, emojiName, id) => {
if (commandName) return `/${commandName}`;
if (emojiName) return `:${emojiName}:`;
switch (type) {
case '@':
case '@!': {
const member = channel.guild?.members.cache.get(id);
if (member) {
return `@${member.displayName}`;
}
const user = channel.client.users.cache.get(id);
return user ? `@${user.displayName}` : match;
}
case '@&': {
if (channel.type === ChannelType.DM) return match;
const role = channel.guild.roles.cache.get(id);
return role ? `@${role.name}` : match;
}
case '#': {
const mentionedChannel = channel.client.channels.cache.get(id);
return mentionedChannel ? `#${mentionedChannel.name}` : match;
}
default: {
return match;
}
}
},
);
}
/**
* The content to put in a code block with all code block fences replaced by the equivalent backticks.
* @param {string} text The string to be converted
* @returns {string}
*/
function cleanCodeBlockContent(text) {
return text.replaceAll('```', '`\u200b``');
}
/**
* Parses a webhook URL for the id and token.
* @param {string} url The URL to parse
* @returns {?WebhookClientDataIdWithToken} `null` if the URL is invalid, otherwise the id and the token
*/
function parseWebhookURL(url) {
const matches = url.match(
/https?:\/\/(?:ptb\.|canary\.)?discord\.com\/api(?:\/v\d{1,2})?\/webhooks\/(\d{17,19})\/([\w-]{68})/i,
);
if (!matches || matches.length <= 2) return null;
const [, id, token] = matches;
return {
id,
token,
};
}
/**
* Supportive data for interaction resolved data.
* @typedef {Object} SupportingInteractionResolvedData
* @property {Client} client The client
* @property {Guild} [guild] A guild
* @property {GuildTextBasedChannel} [channel] A channel
* @private
*/
/**
* Transforms the resolved data received from the API.
* @param {SupportingInteractionResolvedData} supportingData Data to support the transformation
* @param {APIInteractionDataResolved} [data] The received resolved objects
* @returns {CommandInteractionResolvedData}
* @private
*/
function transformResolved(
{ client, guild, channel },
{ members, users, channels, roles, messages, attachments } = {},
) {
const result = {};
if (members) {
result.members = new Collection();
for (const [id, member] of Object.entries(members)) {
const user = users[id];
result.members.set(id, guild?.members._add({ user, ...member }) ?? member);
}
}
if (users) {
result.users = new Collection();
for (const user of Object.values(users)) {
result.users.set(user.id, client.users._add(user));
}
}
if (roles) {
result.roles = new Collection();
for (const role of Object.values(roles)) {
result.roles.set(role.id, guild?.roles._add(role) ?? role);
}
}
if (channels) {
result.channels = new Collection();
for (const apiChannel of Object.values(channels)) {
result.channels.set(apiChannel.id, client.channels._add(apiChannel, guild) ?? apiChannel);
}
}
if (messages) {
result.messages = new Collection();
for (const message of Object.values(messages)) {
result.messages.set(message.id, channel?.messages?._add(message) ?? message);
}
}
if (attachments) {
result.attachments = new Collection();
for (const attachment of Object.values(attachments)) {
const patched = new Attachment(attachment);
result.attachments.set(attachment.id, patched);
}
}
return result;
}
/**
* Resolves a SKU id from a SKU resolvable.
* @param {SKUResolvable} resolvable The SKU resolvable to resolve
* @returns {?Snowflake} The resolved SKU id, or `null` if the resolvable was invalid
*/
function resolveSKUId(resolvable) {
if (typeof resolvable === 'string') return resolvable;
if (resolvable instanceof SKU) return resolvable.id;
return null;
}
module.exports = {
flatten,
fetchRecommendedShardCount,
parseEmoji,
resolvePartialEmoji,
makeError,
makePlainError,
getSortableGroupTypes,
moveElementInArray,
verifyString,
resolveColor,
discordSort,
setPosition,
basename,
cleanContent,
cleanCodeBlockContent,
parseWebhookURL,
transformResolved,
resolveSKUId,
};
// Fixes Circular
const Attachment = require('../structures/Attachment');
const GuildChannel = require('../structures/GuildChannel');
const { SKU } = require('../structures/SKU.js');

View File

@@ -0,0 +1,25 @@
'use strict';
/**
* @typedef {Object} WebSocketShardEvents
* @property {string} Close close
* @property {string} Destroyed destroyed
* @property {string} InvalidSession invalidSession
* @property {string} Ready ready
* @property {string} Resumed resumed
* @property {string} AllReady allReady
*/
// JSDoc for IntelliSense purposes
/**
* @type {WebSocketShardEvents}
* @ignore
*/
module.exports = {
Close: 'close',
Destroyed: 'destroyed',
InvalidSession: 'invalidSession',
Ready: 'ready',
Resumed: 'resumed',
AllReady: 'allReady',
};