diff options
Diffstat (limited to 'node_modules/discord.js/src/client')
125 files changed, 4051 insertions, 0 deletions
diff --git a/node_modules/discord.js/src/client/BaseClient.js b/node_modules/discord.js/src/client/BaseClient.js new file mode 100644 index 0000000..631748c --- /dev/null +++ b/node_modules/discord.js/src/client/BaseClient.js @@ -0,0 +1,83 @@ +'use strict'; + +const EventEmitter = require('node:events'); +const { REST } = require('@discordjs/rest'); +const { DiscordjsTypeError, ErrorCodes } = require('../errors'); +const Options = require('../util/Options'); +const { mergeDefault, flatten } = require('../util/Util'); + +/** + * The base class for all clients. + * @extends {EventEmitter} + */ +class BaseClient extends EventEmitter { + constructor(options = {}) { + super({ captureRejections: true }); + + if (typeof options !== 'object' || options === null) { + throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true); + } + + /** + * The options the client was instantiated with + * @type {ClientOptions} + */ + this.options = mergeDefault(Options.createDefault(), { + ...options, + rest: { + ...options.rest, + userAgentAppendix: options.rest?.userAgentAppendix + ? `${Options.userAgentAppendix} ${options.rest.userAgentAppendix}` + : undefined, + }, + }); + + /** + * The REST manager of the client + * @type {REST} + */ + this.rest = new REST(this.options.rest); + } + + /** + * Destroys all assets used by the base client. + * @returns {void} + */ + destroy() { + this.rest.clearHashSweeper(); + this.rest.clearHandlerSweeper(); + } + + /** + * Increments max listeners by one, if they are not zero. + * @private + */ + incrementMaxListeners() { + const maxListeners = this.getMaxListeners(); + if (maxListeners !== 0) { + this.setMaxListeners(maxListeners + 1); + } + } + + /** + * Decrements max listeners by one, if they are not zero. + * @private + */ + decrementMaxListeners() { + const maxListeners = this.getMaxListeners(); + if (maxListeners !== 0) { + this.setMaxListeners(maxListeners - 1); + } + } + + toJSON(...props) { + return flatten(this, ...props); + } +} + +module.exports = BaseClient; + +/** + * @external REST + * @see {@link https://discord.js.org/docs/packages/rest/stable/REST:Class} + */ diff --git a/node_modules/discord.js/src/client/Client.js b/node_modules/discord.js/src/client/Client.js new file mode 100644 index 0000000..80719e8 --- /dev/null +++ b/node_modules/discord.js/src/client/Client.js @@ -0,0 +1,608 @@ +'use strict'; + +const process = require('node:process'); +const { Collection } = require('@discordjs/collection'); +const { makeURLSearchParams } = require('@discordjs/rest'); +const { OAuth2Scopes, Routes } = require('discord-api-types/v10'); +const BaseClient = require('./BaseClient'); +const ActionsManager = require('./actions/ActionsManager'); +const ClientVoiceManager = require('./voice/ClientVoiceManager'); +const WebSocketManager = require('./websocket/WebSocketManager'); +const { DiscordjsError, DiscordjsTypeError, DiscordjsRangeError, ErrorCodes } = require('../errors'); +const BaseGuildEmojiManager = require('../managers/BaseGuildEmojiManager'); +const ChannelManager = require('../managers/ChannelManager'); +const GuildManager = require('../managers/GuildManager'); +const UserManager = require('../managers/UserManager'); +const ShardClientUtil = require('../sharding/ShardClientUtil'); +const ClientPresence = require('../structures/ClientPresence'); +const GuildPreview = require('../structures/GuildPreview'); +const GuildTemplate = require('../structures/GuildTemplate'); +const Invite = require('../structures/Invite'); +const { Sticker } = require('../structures/Sticker'); +const StickerPack = require('../structures/StickerPack'); +const VoiceRegion = require('../structures/VoiceRegion'); +const Webhook = require('../structures/Webhook'); +const Widget = require('../structures/Widget'); +const DataResolver = require('../util/DataResolver'); +const Events = require('../util/Events'); +const IntentsBitField = require('../util/IntentsBitField'); +const Options = require('../util/Options'); +const PermissionsBitField = require('../util/PermissionsBitField'); +const Status = require('../util/Status'); +const Sweepers = require('../util/Sweepers'); + +/** + * The main hub for interacting with the Discord API, and the starting point for any bot. + * @extends {BaseClient} + */ +class Client extends BaseClient { + /** + * @param {ClientOptions} options Options for the client + */ + constructor(options) { + super(options); + + const data = require('node:worker_threads').workerData ?? process.env; + const defaults = Options.createDefault(); + + if (this.options.shards === defaults.shards) { + if ('SHARDS' in data) { + this.options.shards = JSON.parse(data.SHARDS); + } + } + + if (this.options.shardCount === defaults.shardCount) { + if ('SHARD_COUNT' in data) { + this.options.shardCount = Number(data.SHARD_COUNT); + } else if (Array.isArray(this.options.shards)) { + this.options.shardCount = this.options.shards.length; + } + } + + const typeofShards = typeof this.options.shards; + + if (typeofShards === 'undefined' && typeof this.options.shardCount === 'number') { + this.options.shards = Array.from({ length: this.options.shardCount }, (_, i) => i); + } + + if (typeofShards === 'number') this.options.shards = [this.options.shards]; + + if (Array.isArray(this.options.shards)) { + this.options.shards = [ + ...new Set( + this.options.shards.filter(item => !isNaN(item) && item >= 0 && item < Infinity && item === (item | 0)), + ), + ]; + } + + this._validateOptions(); + + /** + * The WebSocket manager of the client + * @type {WebSocketManager} + */ + this.ws = new WebSocketManager(this); + + /** + * The action manager of the client + * @type {ActionsManager} + * @private + */ + this.actions = new ActionsManager(this); + + /** + * The voice manager of the client + * @type {ClientVoiceManager} + */ + this.voice = new ClientVoiceManager(this); + + /** + * Shard helpers for the client (only if the process was spawned from a {@link ShardingManager}) + * @type {?ShardClientUtil} + */ + this.shard = process.env.SHARDING_MANAGER + ? ShardClientUtil.singleton(this, process.env.SHARDING_MANAGER_MODE) + : null; + + /** + * All of the {@link User} objects that have been cached at any point, mapped by their ids + * @type {UserManager} + */ + this.users = new UserManager(this); + + /** + * All of the guilds the client is currently handling, mapped by their ids - + * as long as sharding isn't being used, this will be *every* guild the bot is a member of + * @type {GuildManager} + */ + this.guilds = new GuildManager(this); + + /** + * All of the {@link BaseChannel}s that the client is currently handling, mapped by their ids - + * as long as sharding isn't being used, this will be *every* channel in *every* guild the bot + * is a member of. Note that DM channels will not be initially cached, and thus not be present + * in the Manager without their explicit fetching or use. + * @type {ChannelManager} + */ + this.channels = new ChannelManager(this); + + /** + * The sweeping functions and their intervals used to periodically sweep caches + * @type {Sweepers} + */ + this.sweepers = new Sweepers(this, this.options.sweepers); + + /** + * The presence of the Client + * @private + * @type {ClientPresence} + */ + this.presence = new ClientPresence(this, this.options.presence); + + Object.defineProperty(this, 'token', { writable: true }); + if (!this.token && 'DISCORD_TOKEN' in process.env) { + /** + * Authorization token for the logged in bot. + * If present, this defaults to `process.env.DISCORD_TOKEN` when instantiating the client + * <warn>This should be kept private at all times.</warn> + * @type {?string} + */ + this.token = process.env.DISCORD_TOKEN; + } else { + this.token = null; + } + + /** + * User that the client is logged in as + * @type {?ClientUser} + */ + this.user = null; + + /** + * The application of this bot + * @type {?ClientApplication} + */ + this.application = null; + + /** + * Timestamp of the time the client was last {@link Status.Ready} at + * @type {?number} + */ + this.readyTimestamp = null; + } + + /** + * All custom emojis that the client has access to, mapped by their ids + * @type {BaseGuildEmojiManager} + * @readonly + */ + get emojis() { + const emojis = new BaseGuildEmojiManager(this); + for (const guild of this.guilds.cache.values()) { + if (guild.available) for (const emoji of guild.emojis.cache.values()) emojis.cache.set(emoji.id, emoji); + } + return emojis; + } + + /** + * Time at which the client was last regarded as being in the {@link Status.Ready} state + * (each time the client disconnects and successfully reconnects, this will be overwritten) + * @type {?Date} + * @readonly + */ + get readyAt() { + return this.readyTimestamp && new Date(this.readyTimestamp); + } + + /** + * How long it has been since the client last entered the {@link Status.Ready} state in milliseconds + * @type {?number} + * @readonly + */ + get uptime() { + return this.readyTimestamp && Date.now() - this.readyTimestamp; + } + + /** + * Logs the client in, establishing a WebSocket connection to Discord. + * @param {string} [token=this.token] Token of the account to log in with + * @returns {Promise<string>} Token of the account used + * @example + * client.login('my token'); + */ + async login(token = this.token) { + if (!token || typeof token !== 'string') throw new DiscordjsError(ErrorCodes.TokenInvalid); + this.token = token = token.replace(/^(Bot|Bearer)\s*/i, ''); + this.rest.setToken(token); + this.emit(Events.Debug, `Provided token: ${this._censoredToken}`); + + if (this.options.presence) { + this.options.ws.presence = this.presence._parse(this.options.presence); + } + + this.emit(Events.Debug, 'Preparing to connect to the gateway...'); + + try { + await this.ws.connect(); + return this.token; + } catch (error) { + await this.destroy(); + throw error; + } + } + + /** + * Returns whether the client has logged in, indicative of being able to access + * properties such as `user` and `application`. + * @returns {boolean} + */ + isReady() { + return this.ws.status === Status.Ready; + } + + /** + * Logs out, terminates the connection to Discord, and destroys the client. + * @returns {Promise<void>} + */ + async destroy() { + super.destroy(); + + this.sweepers.destroy(); + await this.ws.destroy(); + this.token = null; + this.rest.setToken(null); + } + + /** + * Options used for deleting a webhook. + * @typedef {Object} WebhookDeleteOptions + * @property {string} [token] Token of the webhook + * @property {string} [reason] The reason for deleting the webhook + */ + + /** + * Deletes a webhook. + * @param {Snowflake} id The webhook's id + * @param {WebhookDeleteOptions} [options] Options for deleting the webhook + * @returns {Promise<void>} + */ + async deleteWebhook(id, { token, reason } = {}) { + await this.rest.delete(Routes.webhook(id, token), { auth: !token, reason }); + } + + /** + * Options used when fetching an invite from Discord. + * @typedef {Object} ClientFetchInviteOptions + * @property {Snowflake} [guildScheduledEventId] The id of the guild scheduled event to include with + * the invite + */ + + /** + * Obtains an invite from Discord. + * @param {InviteResolvable} invite Invite code or URL + * @param {ClientFetchInviteOptions} [options] Options for fetching the invite + * @returns {Promise<Invite>} + * @example + * client.fetchInvite('https://discord.gg/djs') + * .then(invite => console.log(`Obtained invite with code: ${invite.code}`)) + * .catch(console.error); + */ + async fetchInvite(invite, options) { + const code = DataResolver.resolveInviteCode(invite); + const query = makeURLSearchParams({ + with_counts: true, + with_expiration: true, + guild_scheduled_event_id: options?.guildScheduledEventId, + }); + const data = await this.rest.get(Routes.invite(code), { query }); + return new Invite(this, data); + } + + /** + * Obtains a template from Discord. + * @param {GuildTemplateResolvable} template Template code or URL + * @returns {Promise<GuildTemplate>} + * @example + * client.fetchGuildTemplate('https://discord.new/FKvmczH2HyUf') + * .then(template => console.log(`Obtained template with code: ${template.code}`)) + * .catch(console.error); + */ + async fetchGuildTemplate(template) { + const code = DataResolver.resolveGuildTemplateCode(template); + const data = await this.rest.get(Routes.template(code)); + return new GuildTemplate(this, data); + } + + /** + * Obtains a webhook from Discord. + * @param {Snowflake} id The webhook's id + * @param {string} [token] Token for the webhook + * @returns {Promise<Webhook>} + * @example + * client.fetchWebhook('id', 'token') + * .then(webhook => console.log(`Obtained webhook with name: ${webhook.name}`)) + * .catch(console.error); + */ + async fetchWebhook(id, token) { + const data = await this.rest.get(Routes.webhook(id, token), { auth: token === undefined }); + return new Webhook(this, { token, ...data }); + } + + /** + * Obtains the available voice regions from Discord. + * @returns {Promise<Collection<string, VoiceRegion>>} + * @example + * client.fetchVoiceRegions() + * .then(regions => console.log(`Available regions are: ${regions.map(region => region.name).join(', ')}`)) + * .catch(console.error); + */ + async fetchVoiceRegions() { + const apiRegions = await this.rest.get(Routes.voiceRegions()); + const regions = new Collection(); + for (const region of apiRegions) regions.set(region.id, new VoiceRegion(region)); + return regions; + } + + /** + * Obtains a sticker from Discord. + * @param {Snowflake} id The sticker's id + * @returns {Promise<Sticker>} + * @example + * client.fetchSticker('id') + * .then(sticker => console.log(`Obtained sticker with name: ${sticker.name}`)) + * .catch(console.error); + */ + async fetchSticker(id) { + const data = await this.rest.get(Routes.sticker(id)); + return new Sticker(this, data); + } + + /** + * Obtains the list of sticker packs available to Nitro subscribers from Discord. + * @returns {Promise<Collection<Snowflake, StickerPack>>} + * @example + * client.fetchPremiumStickerPacks() + * .then(packs => console.log(`Available sticker packs are: ${packs.map(pack => pack.name).join(', ')}`)) + * .catch(console.error); + */ + async fetchPremiumStickerPacks() { + const data = await this.rest.get(Routes.nitroStickerPacks()); + return new Collection(data.sticker_packs.map(p => [p.id, new StickerPack(this, p)])); + } + + /** + * Obtains a guild preview from Discord, available for all guilds the bot is in and all Discoverable guilds. + * @param {GuildResolvable} guild The guild to fetch the preview for + * @returns {Promise<GuildPreview>} + */ + async fetchGuildPreview(guild) { + const id = this.guilds.resolveId(guild); + if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'guild', 'GuildResolvable'); + const data = await this.rest.get(Routes.guildPreview(id)); + return new GuildPreview(this, data); + } + + /** + * Obtains the widget data of a guild from Discord, available for guilds with the widget enabled. + * @param {GuildResolvable} guild The guild to fetch the widget data for + * @returns {Promise<Widget>} + */ + async fetchGuildWidget(guild) { + const id = this.guilds.resolveId(guild); + if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'guild', 'GuildResolvable'); + const data = await this.rest.get(Routes.guildWidgetJSON(id)); + return new Widget(this, data); + } + + /** + * Options for {@link Client#generateInvite}. + * @typedef {Object} InviteGenerationOptions + * @property {OAuth2Scopes[]} scopes Scopes that should be requested + * @property {PermissionResolvable} [permissions] Permissions to request + * @property {GuildResolvable} [guild] Guild to preselect + * @property {boolean} [disableGuildSelect] Whether to disable the guild selection + */ + + /** + * Generates a link that can be used to invite the bot to a guild. + * @param {InviteGenerationOptions} [options={}] Options for the invite + * @returns {string} + * @example + * const link = client.generateInvite({ + * scopes: [OAuth2Scopes.ApplicationsCommands], + * }); + * console.log(`Generated application invite link: ${link}`); + * @example + * const link = client.generateInvite({ + * permissions: [ + * PermissionFlagsBits.SendMessages, + * PermissionFlagsBits.ManageGuild, + * PermissionFlagsBits.MentionEveryone, + * ], + * scopes: [OAuth2Scopes.Bot], + * }); + * console.log(`Generated bot invite link: ${link}`); + */ + generateInvite(options = {}) { + if (typeof options !== 'object') throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true); + if (!this.application) throw new DiscordjsError(ErrorCodes.ClientNotReady, 'generate an invite link'); + + const { scopes } = options; + if (scopes === undefined) { + throw new DiscordjsTypeError(ErrorCodes.InvalidMissingScopes); + } + if (!Array.isArray(scopes)) { + throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'scopes', 'Array of Invite Scopes', true); + } + if (!scopes.some(scope => [OAuth2Scopes.Bot, OAuth2Scopes.ApplicationsCommands].includes(scope))) { + throw new DiscordjsTypeError(ErrorCodes.InvalidMissingScopes); + } + if (!scopes.includes(OAuth2Scopes.Bot) && options.permissions) { + throw new DiscordjsTypeError(ErrorCodes.InvalidScopesWithPermissions); + } + const validScopes = Object.values(OAuth2Scopes); + const invalidScope = scopes.find(scope => !validScopes.includes(scope)); + if (invalidScope) { + throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array', 'scopes', invalidScope); + } + + const query = makeURLSearchParams({ + client_id: this.application.id, + scope: scopes.join(' '), + disable_guild_select: options.disableGuildSelect, + }); + + if (options.permissions) { + const permissions = PermissionsBitField.resolve(options.permissions); + if (permissions) query.set('permissions', permissions.toString()); + } + + if (options.guild) { + const guildId = this.guilds.resolveId(options.guild); + if (!guildId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options.guild', 'GuildResolvable'); + query.set('guild_id', guildId); + } + + return `${this.options.rest.api}${Routes.oauth2Authorization()}?${query}`; + } + + toJSON() { + return super.toJSON({ + actions: false, + presence: false, + }); + } + + /** + * Partially censored client token for debug logging purposes. + * @type {?string} + * @readonly + * @private + */ + get _censoredToken() { + if (!this.token) return null; + + return this.token + .split('.') + .map((val, i) => (i > 1 ? val.replace(/./g, '*') : val)) + .join('.'); + } + + /** + * Calls {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval} on a script + * with the client as `this`. + * @param {string} script Script to eval + * @returns {*} + * @private + */ + _eval(script) { + return eval(script); + } + + /** + * Validates the client options. + * @param {ClientOptions} [options=this.options] Options to validate + * @private + */ + _validateOptions(options = this.options) { + if (options.intents === undefined) { + throw new DiscordjsTypeError(ErrorCodes.ClientMissingIntents); + } else { + options.intents = new IntentsBitField(options.intents).freeze(); + } + if (typeof options.shardCount !== 'number' || isNaN(options.shardCount) || options.shardCount < 1) { + throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'shardCount', 'a number greater than or equal to 1'); + } + if (options.shards && !(options.shards === 'auto' || Array.isArray(options.shards))) { + throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'shards', "'auto', a number or array of numbers"); + } + if (options.shards && !options.shards.length) throw new DiscordjsRangeError(ErrorCodes.ClientInvalidProvidedShards); + if (typeof options.makeCache !== 'function') { + throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'makeCache', 'a function'); + } + if (typeof options.sweepers !== 'object' || options.sweepers === null) { + throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'sweepers', 'an object'); + } + if (!Array.isArray(options.partials)) { + throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'partials', 'an Array'); + } + if (typeof options.waitGuildTimeout !== 'number' || isNaN(options.waitGuildTimeout)) { + throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'waitGuildTimeout', 'a number'); + } + if (typeof options.failIfNotExists !== 'boolean') { + throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'failIfNotExists', 'a boolean'); + } + if ( + (typeof options.allowedMentions !== 'object' && options.allowedMentions !== undefined) || + options.allowedMentions === null + ) { + throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'allowedMentions', 'an object'); + } + if (typeof options.presence !== 'object' || options.presence === null) { + throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'presence', 'an object'); + } + if (typeof options.ws !== 'object' || options.ws === null) { + throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'ws', 'an object'); + } + if (typeof options.rest !== 'object' || options.rest === null) { + throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'rest', 'an object'); + } + if (typeof options.jsonTransformer !== 'function') { + throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'jsonTransformer', 'a function'); + } + } +} + +module.exports = Client; + +/** + * @class SnowflakeUtil + * @classdesc This class is an alias for {@link https://www.npmjs.com/package/@sapphire/snowflake @sapphire/snowflake}'s + * `DiscordSnowflake` class. + * + * Check their documentation + * {@link https://www.sapphirejs.dev/docs/Documentation/api-utilities/classes/sapphire_snowflake.Snowflake here} + * ({@link https://www.sapphirejs.dev/docs/Guide/utilities/snowflake guide}) + * to see what you can do. + * @hideconstructor + */ + +/** + * A {@link https://developer.twitter.com/en/docs/twitter-ids Twitter snowflake}, + * except the epoch is 2015-01-01T00:00:00.000Z. + * + * If we have a snowflake '266241948824764416' we can represent it as binary: + * ``` + * 64 22 17 12 0 + * 000000111011000111100001101001000101000000 00001 00000 000000000000 + * number of milliseconds since Discord epoch worker pid increment + * ``` + * @typedef {string} Snowflake + */ + +/** + * Emitted for general debugging information. + * @event Client#debug + * @param {string} info The debug information + */ + +/** + * Emitted for general warnings. + * @event Client#warn + * @param {string} info The warning + */ + +/** + * @external Collection + * @see {@link https://discord.js.org/docs/packages/collection/stable/Collection:Class} + */ + +/** + * @external ImageURLOptions + * @see {@link https://discord.js.org/docs/packages/rest/stable/ImageURLOptions:Interface} + */ + +/** + * @external BaseImageURLOptions + * @see {@link https://discord.js.org/docs/packages/rest/stable/BaseImageURLOptions:Interface} + */ diff --git a/node_modules/discord.js/src/client/WebhookClient.js b/node_modules/discord.js/src/client/WebhookClient.js new file mode 100644 index 0000000..5bb6412 --- /dev/null +++ b/node_modules/discord.js/src/client/WebhookClient.js @@ -0,0 +1,103 @@ +'use strict'; + +const BaseClient = require('./BaseClient'); +const { DiscordjsError, ErrorCodes } = require('../errors'); +const Webhook = require('../structures/Webhook'); +const { parseWebhookURL } = require('../util/Util'); + +/** + * The webhook client. + * @implements {Webhook} + * @extends {BaseClient} + */ +class WebhookClient extends BaseClient { + /** + * Represents the credentials used for a webhook in the form of its id and token. + * @typedef {Object} WebhookClientDataIdWithToken + * @property {Snowflake} id The webhook's id + * @property {string} token The webhook's token + */ + + /** + * Represents the credentials used for a webhook in the form of a URL. + * @typedef {Object} WebhookClientDataURL + * @property {string} url The full URL for the webhook + */ + + /** + * Represents the credentials used for a webhook. + * @typedef {WebhookClientDataIdWithToken|WebhookClientDataURL} WebhookClientData + */ + + /** + * Options for a webhook client. + * @typedef {Object} WebhookClientOptions + * @property {MessageMentionOptions} [allowedMentions] Default value for {@link BaseMessageOptions#allowedMentions} + * @property {RESTOptions} [rest] Options for the REST manager + */ + + /** + * @param {WebhookClientData} data The data of the webhook + * @param {WebhookClientOptions} [options] Options for the webhook client + */ + constructor(data, options) { + super(options); + Object.defineProperty(this, 'client', { value: this }); + let { id, token } = data; + + if ('url' in data) { + const parsed = parseWebhookURL(data.url); + if (!parsed) { + throw new DiscordjsError(ErrorCodes.WebhookURLInvalid); + } + + ({ id, token } = parsed); + } + + this.id = id; + Object.defineProperty(this, 'token', { value: token, writable: true, configurable: true }); + } + + /** + * The options the webhook client was instantiated with. + * @type {WebhookClientOptions} + * @name WebhookClient#options + */ + + // These are here only for documentation purposes - they are implemented by Webhook + /* eslint-disable no-empty-function, valid-jsdoc */ + /** + * Sends a message with this webhook. + * @param {string|MessagePayload|WebhookMessageCreateOptions} options The content for the reply + * @returns {Promise<APIMessage>} + */ + send() {} + + /** + * Gets a message that was sent by this webhook. + * @param {Snowflake} message The id of the message to fetch + * @param {WebhookFetchMessageOptions} [options={}] The options to provide to fetch the message. + * @returns {Promise<APIMessage>} Returns the message sent by this webhook + */ + fetchMessage() {} + + /** + * Edits a message that was sent by this webhook. + * @param {MessageResolvable} message The message to edit + * @param {string|MessagePayload|WebhookMessageEditOptions} options The options to provide + * @returns {Promise<APIMessage>} Returns the message edited by this webhook + */ + editMessage() {} + + sendSlackMessage() {} + edit() {} + delete() {} + deleteMessage() {} + get createdTimestamp() {} + get createdAt() {} + get url() {} +} + +Webhook.applyToClass(WebhookClient); + +module.exports = WebhookClient; diff --git a/node_modules/discord.js/src/client/actions/Action.js b/node_modules/discord.js/src/client/actions/Action.js new file mode 100644 index 0000000..6c04a64 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/Action.js @@ -0,0 +1,120 @@ +'use strict'; + +const Partials = require('../../util/Partials'); + +/* + +ABOUT ACTIONS + +Actions are similar to WebSocket Packet Handlers, but since introducing +the REST API methods, in order to prevent rewriting code to handle data, +"actions" have been introduced. They're basically what Packet Handlers +used to be but they're strictly for manipulating data and making sure +that WebSocket events don't clash with REST methods. + +*/ + +class GenericAction { + constructor(client) { + this.client = client; + } + + handle(data) { + return data; + } + + getPayload(data, manager, id, partialType, cache) { + return this.client.options.partials.includes(partialType) ? manager._add(data, cache) : manager.cache.get(id); + } + + getChannel(data) { + const payloadData = {}; + const id = data.channel_id ?? data.id; + + if ('recipients' in data) { + payloadData.recipients = data.recipients; + } else { + // Try to resolve the recipient, but do not add the client user. + const recipient = data.author ?? data.user ?? { id: data.user_id }; + if (recipient.id !== this.client.user.id) payloadData.recipients = [recipient]; + } + + if (id !== undefined) payloadData.id = id; + if ('guild_id' in data) payloadData.guild_id = data.guild_id; + if ('last_message_id' in data) payloadData.last_message_id = data.last_message_id; + + return ( + data[this.client.actions.injectedChannel] ?? + this.getPayload(payloadData, this.client.channels, id, Partials.Channel) + ); + } + + getMessage(data, channel, cache) { + const id = data.message_id ?? data.id; + return ( + data[this.client.actions.injectedMessage] ?? + this.getPayload( + { + id, + channel_id: channel.id, + guild_id: data.guild_id ?? channel.guild?.id, + }, + channel.messages, + id, + Partials.Message, + cache, + ) + ); + } + + getReaction(data, message, user) { + const id = data.emoji.id ?? decodeURIComponent(data.emoji.name); + return this.getPayload( + { + emoji: data.emoji, + count: message.partial ? null : 0, + me: user?.id === this.client.user.id, + }, + message.reactions, + id, + Partials.Reaction, + ); + } + + getMember(data, guild) { + return this.getPayload(data, guild.members, data.user.id, Partials.GuildMember); + } + + getUser(data) { + const id = data.user_id; + return data[this.client.actions.injectedUser] ?? this.getPayload({ id }, this.client.users, id, Partials.User); + } + + getUserFromMember(data) { + if (data.guild_id && data.member?.user) { + const guild = this.client.guilds.cache.get(data.guild_id); + if (guild) { + return guild.members._add(data.member).user; + } else { + return this.client.users._add(data.member.user); + } + } + return this.getUser(data); + } + + getScheduledEvent(data, guild) { + const id = data.guild_scheduled_event_id ?? data.id; + return this.getPayload( + { id, guild_id: data.guild_id ?? guild.id }, + guild.scheduledEvents, + id, + Partials.GuildScheduledEvent, + ); + } + + getThreadMember(id, manager) { + return this.getPayload({ user_id: id }, manager, id, Partials.ThreadMember, false); + } +} + +module.exports = GenericAction; diff --git a/node_modules/discord.js/src/client/actions/ActionsManager.js b/node_modules/discord.js/src/client/actions/ActionsManager.js new file mode 100644 index 0000000..301a6a9 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/ActionsManager.js @@ -0,0 +1,79 @@ +'use strict'; + +class ActionsManager { + // These symbols represent fully built data that we inject at times when calling actions manually. + // Action#getUser, for example, will return the injected data (which is assumed to be a built structure) + // instead of trying to make it from provided data + injectedUser = Symbol('djs.actions.injectedUser'); + injectedChannel = Symbol('djs.actions.injectedChannel'); + injectedMessage = Symbol('djs.actions.injectedMessage'); + + constructor(client) { + this.client = client; + + this.register(require('./ApplicationCommandPermissionsUpdate')); + this.register(require('./AutoModerationActionExecution')); + this.register(require('./AutoModerationRuleCreate')); + this.register(require('./AutoModerationRuleDelete')); + this.register(require('./AutoModerationRuleUpdate')); + this.register(require('./ChannelCreate')); + this.register(require('./ChannelDelete')); + this.register(require('./ChannelUpdate')); + this.register(require('./GuildAuditLogEntryCreate')); + this.register(require('./GuildBanAdd')); + this.register(require('./GuildBanRemove')); + this.register(require('./GuildChannelsPositionUpdate')); + this.register(require('./GuildDelete')); + this.register(require('./GuildEmojiCreate')); + this.register(require('./GuildEmojiDelete')); + this.register(require('./GuildEmojiUpdate')); + this.register(require('./GuildEmojisUpdate')); + this.register(require('./GuildIntegrationsUpdate')); + this.register(require('./GuildMemberRemove')); + this.register(require('./GuildMemberUpdate')); + this.register(require('./GuildRoleCreate')); + this.register(require('./GuildRoleDelete')); + this.register(require('./GuildRoleUpdate')); + this.register(require('./GuildRolesPositionUpdate')); + this.register(require('./GuildScheduledEventCreate')); + this.register(require('./GuildScheduledEventDelete')); + this.register(require('./GuildScheduledEventUpdate')); + this.register(require('./GuildScheduledEventUserAdd')); + this.register(require('./GuildScheduledEventUserRemove')); + this.register(require('./GuildStickerCreate')); + this.register(require('./GuildStickerDelete')); + this.register(require('./GuildStickerUpdate')); + this.register(require('./GuildStickersUpdate')); + this.register(require('./GuildUpdate')); + this.register(require('./InteractionCreate')); + this.register(require('./InviteCreate')); + this.register(require('./InviteDelete')); + this.register(require('./MessageCreate')); + this.register(require('./MessageDelete')); + this.register(require('./MessageDeleteBulk')); + this.register(require('./MessageReactionAdd')); + this.register(require('./MessageReactionRemove')); + this.register(require('./MessageReactionRemoveAll')); + this.register(require('./MessageReactionRemoveEmoji')); + this.register(require('./MessageUpdate')); + this.register(require('./PresenceUpdate')); + this.register(require('./StageInstanceCreate')); + this.register(require('./StageInstanceDelete')); + this.register(require('./StageInstanceUpdate')); + this.register(require('./ThreadCreate')); + this.register(require('./ThreadDelete')); + this.register(require('./ThreadListSync')); + this.register(require('./ThreadMemberUpdate')); + this.register(require('./ThreadMembersUpdate')); + this.register(require('./TypingStart')); + this.register(require('./UserUpdate')); + this.register(require('./VoiceStateUpdate')); + this.register(require('./WebhooksUpdate')); + } + + register(Action) { + this[Action.name.replace(/Action$/, '')] = new Action(this.client); + } +} + +module.exports = ActionsManager; diff --git a/node_modules/discord.js/src/client/actions/ApplicationCommandPermissionsUpdate.js b/node_modules/discord.js/src/client/actions/ApplicationCommandPermissionsUpdate.js new file mode 100644 index 0000000..f2bc214 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/ApplicationCommandPermissionsUpdate.js @@ -0,0 +1,34 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +/** + * The data received in the {@link Client#event:applicationCommandPermissionsUpdate} event + * @typedef {Object} ApplicationCommandPermissionsUpdateData + * @property {Snowflake} id The id of the command or global entity that was updated + * @property {Snowflake} guildId The id of the guild in which permissions were updated + * @property {Snowflake} applicationId The id of the application that owns the command or entity being updated + * @property {ApplicationCommandPermissions[]} permissions The updated permissions + */ + +class ApplicationCommandPermissionsUpdateAction extends Action { + handle(data) { + const client = this.client; + /** + * Emitted whenever permissions for an application command in a guild were updated. + * <warn>This includes permission updates for other applications in addition to the logged in client, + * check `data.applicationId` to verify which application the update is for</warn> + * @event Client#applicationCommandPermissionsUpdate + * @param {ApplicationCommandPermissionsUpdateData} data The updated permissions + */ + client.emit(Events.ApplicationCommandPermissionsUpdate, { + permissions: data.permissions, + id: data.id, + guildId: data.guild_id, + applicationId: data.application_id, + }); + } +} + +module.exports = ApplicationCommandPermissionsUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/AutoModerationActionExecution.js b/node_modules/discord.js/src/client/actions/AutoModerationActionExecution.js new file mode 100644 index 0000000..ad60116 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/AutoModerationActionExecution.js @@ -0,0 +1,26 @@ +'use strict'; + +const Action = require('./Action'); +const AutoModerationActionExecution = require('../../structures/AutoModerationActionExecution'); +const Events = require('../../util/Events'); + +class AutoModerationActionExecutionAction extends Action { + handle(data) { + const { client } = this; + const guild = client.guilds.cache.get(data.guild_id); + + if (guild) { + /** + * Emitted whenever an auto moderation rule is triggered. + * <info>This event requires the {@link PermissionFlagsBits.ManageGuild} permission.</info> + * @event Client#autoModerationActionExecution + * @param {AutoModerationActionExecution} autoModerationActionExecution The data of the execution + */ + client.emit(Events.AutoModerationActionExecution, new AutoModerationActionExecution(data, guild)); + } + + return {}; + } +} + +module.exports = AutoModerationActionExecutionAction; diff --git a/node_modules/discord.js/src/client/actions/AutoModerationRuleCreate.js b/node_modules/discord.js/src/client/actions/AutoModerationRuleCreate.js new file mode 100644 index 0000000..775b1d3 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/AutoModerationRuleCreate.js @@ -0,0 +1,27 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class AutoModerationRuleCreateAction extends Action { + handle(data) { + const { client } = this; + const guild = client.guilds.cache.get(data.guild_id); + + if (guild) { + const autoModerationRule = guild.autoModerationRules._add(data); + + /** + * Emitted whenever an auto moderation rule is created. + * <info>This event requires the {@link PermissionFlagsBits.ManageGuild} permission.</info> + * @event Client#autoModerationRuleCreate + * @param {AutoModerationRule} autoModerationRule The created auto moderation rule + */ + client.emit(Events.AutoModerationRuleCreate, autoModerationRule); + } + + return {}; + } +} + +module.exports = AutoModerationRuleCreateAction; diff --git a/node_modules/discord.js/src/client/actions/AutoModerationRuleDelete.js b/node_modules/discord.js/src/client/actions/AutoModerationRuleDelete.js new file mode 100644 index 0000000..641822c --- /dev/null +++ b/node_modules/discord.js/src/client/actions/AutoModerationRuleDelete.js @@ -0,0 +1,31 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class AutoModerationRuleDeleteAction extends Action { + handle(data) { + const { client } = this; + const guild = client.guilds.cache.get(data.guild_id); + + if (guild) { + const autoModerationRule = guild.autoModerationRules.cache.get(data.id); + + if (autoModerationRule) { + guild.autoModerationRules.cache.delete(autoModerationRule.id); + + /** + * Emitted whenever an auto moderation rule is deleted. + * <info>This event requires the {@link PermissionFlagsBits.ManageGuild} permission.</info> + * @event Client#autoModerationRuleDelete + * @param {AutoModerationRule} autoModerationRule The deleted auto moderation rule + */ + client.emit(Events.AutoModerationRuleDelete, autoModerationRule); + } + } + + return {}; + } +} + +module.exports = AutoModerationRuleDeleteAction; diff --git a/node_modules/discord.js/src/client/actions/AutoModerationRuleUpdate.js b/node_modules/discord.js/src/client/actions/AutoModerationRuleUpdate.js new file mode 100644 index 0000000..56e3956 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/AutoModerationRuleUpdate.js @@ -0,0 +1,29 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class AutoModerationRuleUpdateAction extends Action { + handle(data) { + const { client } = this; + const guild = client.guilds.cache.get(data.guild_id); + + if (guild) { + const oldAutoModerationRule = guild.autoModerationRules.cache.get(data.id)?._clone() ?? null; + const newAutoModerationRule = guild.autoModerationRules._add(data); + + /** + * Emitted whenever an auto moderation rule gets updated. + * <info>This event requires the {@link PermissionFlagsBits.ManageGuild} permission.</info> + * @event Client#autoModerationRuleUpdate + * @param {?AutoModerationRule} oldAutoModerationRule The auto moderation rule before the update + * @param {AutoModerationRule} newAutoModerationRule The auto moderation rule after the update + */ + client.emit(Events.AutoModerationRuleUpdate, oldAutoModerationRule, newAutoModerationRule); + } + + return {}; + } +} + +module.exports = AutoModerationRuleUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/ChannelCreate.js b/node_modules/discord.js/src/client/actions/ChannelCreate.js new file mode 100644 index 0000000..fdf8ddd --- /dev/null +++ b/node_modules/discord.js/src/client/actions/ChannelCreate.js @@ -0,0 +1,23 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class ChannelCreateAction extends Action { + handle(data) { + const client = this.client; + const existing = client.channels.cache.has(data.id); + const channel = client.channels._add(data); + if (!existing && channel) { + /** + * Emitted whenever a guild channel is created. + * @event Client#channelCreate + * @param {GuildChannel} channel The channel that was created + */ + client.emit(Events.ChannelCreate, channel); + } + return { channel }; + } +} + +module.exports = ChannelCreateAction; diff --git a/node_modules/discord.js/src/client/actions/ChannelDelete.js b/node_modules/discord.js/src/client/actions/ChannelDelete.js new file mode 100644 index 0000000..acf03d9 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/ChannelDelete.js @@ -0,0 +1,23 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class ChannelDeleteAction extends Action { + handle(data) { + const client = this.client; + const channel = client.channels.cache.get(data.id); + + if (channel) { + client.channels._remove(channel.id); + /** + * Emitted whenever a channel is deleted. + * @event Client#channelDelete + * @param {DMChannel|GuildChannel} channel The channel that was deleted + */ + client.emit(Events.ChannelDelete, channel); + } + } +} + +module.exports = ChannelDeleteAction; diff --git a/node_modules/discord.js/src/client/actions/ChannelUpdate.js b/node_modules/discord.js/src/client/actions/ChannelUpdate.js new file mode 100644 index 0000000..7ca331a --- /dev/null +++ b/node_modules/discord.js/src/client/actions/ChannelUpdate.js @@ -0,0 +1,42 @@ +'use strict'; + +const Action = require('./Action'); +const { createChannel } = require('../../util/Channels'); + +class ChannelUpdateAction extends Action { + handle(data) { + const client = this.client; + let channel = client.channels.cache.get(data.id); + + if (channel) { + const old = channel._update(data); + + if (channel.type !== data.type) { + const newChannel = createChannel(this.client, data, channel.guild); + + if (!newChannel) { + this.client.channels.cache.delete(channel.id); + return {}; + } + + if (channel.isTextBased() && newChannel.isTextBased()) { + for (const [id, message] of channel.messages.cache) newChannel.messages.cache.set(id, message); + } + + channel = newChannel; + this.client.channels.cache.set(channel.id, channel); + } + + return { + old, + updated: channel, + }; + } else { + client.channels._add(data); + } + + return {}; + } +} + +module.exports = ChannelUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/GuildAuditLogEntryCreate.js b/node_modules/discord.js/src/client/actions/GuildAuditLogEntryCreate.js new file mode 100644 index 0000000..fa16de6 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildAuditLogEntryCreate.js @@ -0,0 +1,29 @@ +'use strict'; + +const Action = require('./Action'); +const GuildAuditLogsEntry = require('../../structures/GuildAuditLogsEntry'); +const Events = require('../../util/Events'); + +class GuildAuditLogEntryCreateAction extends Action { + handle(data) { + const client = this.client; + const guild = client.guilds.cache.get(data.guild_id); + let auditLogEntry; + + if (guild) { + auditLogEntry = new GuildAuditLogsEntry(guild, data); + + /** + * Emitted whenever a guild audit log entry is created. + * @event Client#guildAuditLogEntryCreate + * @param {GuildAuditLogsEntry} auditLogEntry The entry that was created + * @param {Guild} guild The guild where the entry was created + */ + client.emit(Events.GuildAuditLogEntryCreate, auditLogEntry, guild); + } + + return { auditLogEntry }; + } +} + +module.exports = GuildAuditLogEntryCreateAction; diff --git a/node_modules/discord.js/src/client/actions/GuildBanAdd.js b/node_modules/discord.js/src/client/actions/GuildBanAdd.js new file mode 100644 index 0000000..2ef4b11 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildBanAdd.js @@ -0,0 +1,20 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class GuildBanAdd extends Action { + handle(data) { + const client = this.client; + const guild = client.guilds.cache.get(data.guild_id); + + /** + * Emitted whenever a member is banned from a guild. + * @event Client#guildBanAdd + * @param {GuildBan} ban The ban that occurred + */ + if (guild) client.emit(Events.GuildBanAdd, guild.bans._add(data)); + } +} + +module.exports = GuildBanAdd; diff --git a/node_modules/discord.js/src/client/actions/GuildBanRemove.js b/node_modules/discord.js/src/client/actions/GuildBanRemove.js new file mode 100644 index 0000000..8048efd --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildBanRemove.js @@ -0,0 +1,25 @@ +'use strict'; + +const Action = require('./Action'); +const GuildBan = require('../../structures/GuildBan'); +const Events = require('../../util/Events'); + +class GuildBanRemove extends Action { + handle(data) { + const client = this.client; + const guild = client.guilds.cache.get(data.guild_id); + + /** + * Emitted whenever a member is unbanned from a guild. + * @event Client#guildBanRemove + * @param {GuildBan} ban The ban that was removed + */ + if (guild) { + const ban = guild.bans.cache.get(data.user.id) ?? new GuildBan(client, data, guild); + guild.bans.cache.delete(ban.user.id); + client.emit(Events.GuildBanRemove, ban); + } + } +} + +module.exports = GuildBanRemove; diff --git a/node_modules/discord.js/src/client/actions/GuildChannelsPositionUpdate.js b/node_modules/discord.js/src/client/actions/GuildChannelsPositionUpdate.js new file mode 100644 index 0000000..a393167 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildChannelsPositionUpdate.js @@ -0,0 +1,21 @@ +'use strict'; + +const Action = require('./Action'); + +class GuildChannelsPositionUpdate extends Action { + handle(data) { + const client = this.client; + + const guild = client.guilds.cache.get(data.guild_id); + if (guild) { + for (const partialChannel of data.channels) { + const channel = guild.channels.cache.get(partialChannel.id); + if (channel) channel.rawPosition = partialChannel.position; + } + } + + return { guild }; + } +} + +module.exports = GuildChannelsPositionUpdate; diff --git a/node_modules/discord.js/src/client/actions/GuildDelete.js b/node_modules/discord.js/src/client/actions/GuildDelete.js new file mode 100644 index 0000000..eb0a44d --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildDelete.js @@ -0,0 +1,44 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class GuildDeleteAction extends Action { + handle(data) { + const client = this.client; + + let guild = client.guilds.cache.get(data.id); + if (guild) { + if (data.unavailable) { + // Guild is unavailable + guild.available = false; + + /** + * Emitted whenever a guild becomes unavailable, likely due to a server outage. + * @event Client#guildUnavailable + * @param {Guild} guild The guild that has become unavailable + */ + client.emit(Events.GuildUnavailable, guild); + + // Stops the GuildDelete packet thinking a guild was actually deleted, + // handles emitting of event itself + return; + } + + for (const channel of guild.channels.cache.values()) this.client.channels._remove(channel.id); + client.voice.adapters.get(data.id)?.destroy(); + + // Delete guild + client.guilds.cache.delete(guild.id); + + /** + * Emitted whenever a guild kicks the client or the guild is deleted/left. + * @event Client#guildDelete + * @param {Guild} guild The guild that was deleted + */ + client.emit(Events.GuildDelete, guild); + } + } +} + +module.exports = GuildDeleteAction; diff --git a/node_modules/discord.js/src/client/actions/GuildEmojiCreate.js b/node_modules/discord.js/src/client/actions/GuildEmojiCreate.js new file mode 100644 index 0000000..61858cf --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildEmojiCreate.js @@ -0,0 +1,20 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class GuildEmojiCreateAction extends Action { + handle(guild, createdEmoji) { + const already = guild.emojis.cache.has(createdEmoji.id); + const emoji = guild.emojis._add(createdEmoji); + /** + * Emitted whenever a custom emoji is created in a guild. + * @event Client#emojiCreate + * @param {GuildEmoji} emoji The emoji that was created + */ + if (!already) this.client.emit(Events.GuildEmojiCreate, emoji); + return { emoji }; + } +} + +module.exports = GuildEmojiCreateAction; diff --git a/node_modules/discord.js/src/client/actions/GuildEmojiDelete.js b/node_modules/discord.js/src/client/actions/GuildEmojiDelete.js new file mode 100644 index 0000000..e3373c2 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildEmojiDelete.js @@ -0,0 +1,19 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class GuildEmojiDeleteAction extends Action { + handle(emoji) { + emoji.guild.emojis.cache.delete(emoji.id); + /** + * Emitted whenever a custom emoji is deleted in a guild. + * @event Client#emojiDelete + * @param {GuildEmoji} emoji The emoji that was deleted + */ + this.client.emit(Events.GuildEmojiDelete, emoji); + return { emoji }; + } +} + +module.exports = GuildEmojiDeleteAction; diff --git a/node_modules/discord.js/src/client/actions/GuildEmojiUpdate.js b/node_modules/discord.js/src/client/actions/GuildEmojiUpdate.js new file mode 100644 index 0000000..6bf9657 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildEmojiUpdate.js @@ -0,0 +1,20 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class GuildEmojiUpdateAction extends Action { + handle(current, data) { + const old = current._update(data); + /** + * Emitted whenever a custom emoji is updated in a guild. + * @event Client#emojiUpdate + * @param {GuildEmoji} oldEmoji The old emoji + * @param {GuildEmoji} newEmoji The new emoji + */ + this.client.emit(Events.GuildEmojiUpdate, old, current); + return { emoji: current }; + } +} + +module.exports = GuildEmojiUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/GuildEmojisUpdate.js b/node_modules/discord.js/src/client/actions/GuildEmojisUpdate.js new file mode 100644 index 0000000..7829db1 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildEmojisUpdate.js @@ -0,0 +1,34 @@ +'use strict'; + +const Action = require('./Action'); + +class GuildEmojisUpdateAction extends Action { + handle(data) { + const guild = this.client.guilds.cache.get(data.guild_id); + if (!guild?.emojis) return; + + const deletions = new Map(guild.emojis.cache); + + for (const emoji of data.emojis) { + // Determine type of emoji event + const cachedEmoji = guild.emojis.cache.get(emoji.id); + if (cachedEmoji) { + deletions.delete(emoji.id); + if (!cachedEmoji.equals(emoji)) { + // Emoji updated + this.client.actions.GuildEmojiUpdate.handle(cachedEmoji, emoji); + } + } else { + // Emoji added + this.client.actions.GuildEmojiCreate.handle(guild, emoji); + } + } + + for (const emoji of deletions.values()) { + // Emoji deleted + this.client.actions.GuildEmojiDelete.handle(emoji); + } + } +} + +module.exports = GuildEmojisUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/GuildIntegrationsUpdate.js b/node_modules/discord.js/src/client/actions/GuildIntegrationsUpdate.js new file mode 100644 index 0000000..28b9bbb --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildIntegrationsUpdate.js @@ -0,0 +1,19 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class GuildIntegrationsUpdate extends Action { + handle(data) { + const client = this.client; + const guild = client.guilds.cache.get(data.guild_id); + /** + * Emitted whenever a guild integration is updated + * @event Client#guildIntegrationsUpdate + * @param {Guild} guild The guild whose integrations were updated + */ + if (guild) client.emit(Events.GuildIntegrationsUpdate, guild); + } +} + +module.exports = GuildIntegrationsUpdate; diff --git a/node_modules/discord.js/src/client/actions/GuildMemberRemove.js b/node_modules/discord.js/src/client/actions/GuildMemberRemove.js new file mode 100644 index 0000000..45eb6c4 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildMemberRemove.js @@ -0,0 +1,31 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); +const Status = require('../../util/Status'); + +class GuildMemberRemoveAction extends Action { + handle(data, shard) { + const client = this.client; + const guild = client.guilds.cache.get(data.guild_id); + let member = null; + if (guild) { + member = this.getMember({ user: data.user }, guild); + guild.memberCount--; + if (member) { + guild.members.cache.delete(member.id); + /** + * Emitted whenever a member leaves a guild, or is kicked. + * @event Client#guildMemberRemove + * @param {GuildMember} member The member that has left/been kicked from the guild + */ + if (shard.status === Status.Ready) client.emit(Events.GuildMemberRemove, member); + } + guild.presences.cache.delete(data.user.id); + guild.voiceStates.cache.delete(data.user.id); + } + return { guild, member }; + } +} + +module.exports = GuildMemberRemoveAction; diff --git a/node_modules/discord.js/src/client/actions/GuildMemberUpdate.js b/node_modules/discord.js/src/client/actions/GuildMemberUpdate.js new file mode 100644 index 0000000..491b361 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildMemberUpdate.js @@ -0,0 +1,44 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); +const Status = require('../../util/Status'); + +class GuildMemberUpdateAction extends Action { + handle(data, shard) { + const { client } = this; + if (data.user.username) { + const user = client.users.cache.get(data.user.id); + if (!user) { + client.users._add(data.user); + } else if (!user._equals(data.user)) { + client.actions.UserUpdate.handle(data.user); + } + } + + const guild = client.guilds.cache.get(data.guild_id); + if (guild) { + const member = this.getMember({ user: data.user }, guild); + if (member) { + const old = member._update(data); + /** + * Emitted whenever a guild member changes - i.e. new role, removed role, nickname. + * @event Client#guildMemberUpdate + * @param {GuildMember} oldMember The member before the update + * @param {GuildMember} newMember The member after the update + */ + if (shard.status === Status.Ready && !member.equals(old)) client.emit(Events.GuildMemberUpdate, old, member); + } else { + const newMember = guild.members._add(data); + /** + * Emitted whenever a member becomes available. + * @event Client#guildMemberAvailable + * @param {GuildMember} member The member that became available + */ + this.client.emit(Events.GuildMemberAvailable, newMember); + } + } + } +} + +module.exports = GuildMemberUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/GuildRoleCreate.js b/node_modules/discord.js/src/client/actions/GuildRoleCreate.js new file mode 100644 index 0000000..461443b --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildRoleCreate.js @@ -0,0 +1,25 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class GuildRoleCreate extends Action { + handle(data) { + const client = this.client; + const guild = client.guilds.cache.get(data.guild_id); + let role; + if (guild) { + const already = guild.roles.cache.has(data.role.id); + role = guild.roles._add(data.role); + /** + * Emitted whenever a role is created. + * @event Client#roleCreate + * @param {Role} role The role that was created + */ + if (!already) client.emit(Events.GuildRoleCreate, role); + } + return { role }; + } +} + +module.exports = GuildRoleCreate; diff --git a/node_modules/discord.js/src/client/actions/GuildRoleDelete.js b/node_modules/discord.js/src/client/actions/GuildRoleDelete.js new file mode 100644 index 0000000..e043a1a --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildRoleDelete.js @@ -0,0 +1,29 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class GuildRoleDeleteAction extends Action { + handle(data) { + const client = this.client; + const guild = client.guilds.cache.get(data.guild_id); + let role; + + if (guild) { + role = guild.roles.cache.get(data.role_id); + if (role) { + guild.roles.cache.delete(data.role_id); + /** + * Emitted whenever a guild role is deleted. + * @event Client#roleDelete + * @param {Role} role The role that was deleted + */ + client.emit(Events.GuildRoleDelete, role); + } + } + + return { role }; + } +} + +module.exports = GuildRoleDeleteAction; diff --git a/node_modules/discord.js/src/client/actions/GuildRoleUpdate.js b/node_modules/discord.js/src/client/actions/GuildRoleUpdate.js new file mode 100644 index 0000000..b0632c5 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildRoleUpdate.js @@ -0,0 +1,39 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class GuildRoleUpdateAction extends Action { + handle(data) { + const client = this.client; + const guild = client.guilds.cache.get(data.guild_id); + + if (guild) { + let old = null; + + const role = guild.roles.cache.get(data.role.id); + if (role) { + old = role._update(data.role); + /** + * Emitted whenever a guild role is updated. + * @event Client#roleUpdate + * @param {Role} oldRole The role before the update + * @param {Role} newRole The role after the update + */ + client.emit(Events.GuildRoleUpdate, old, role); + } + + return { + old, + updated: role, + }; + } + + return { + old: null, + updated: null, + }; + } +} + +module.exports = GuildRoleUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/GuildRolesPositionUpdate.js b/node_modules/discord.js/src/client/actions/GuildRolesPositionUpdate.js new file mode 100644 index 0000000..d7abca9 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildRolesPositionUpdate.js @@ -0,0 +1,21 @@ +'use strict'; + +const Action = require('./Action'); + +class GuildRolesPositionUpdate extends Action { + handle(data) { + const client = this.client; + + const guild = client.guilds.cache.get(data.guild_id); + if (guild) { + for (const partialRole of data.roles) { + const role = guild.roles.cache.get(partialRole.id); + if (role) role.rawPosition = partialRole.position; + } + } + + return { guild }; + } +} + +module.exports = GuildRolesPositionUpdate; diff --git a/node_modules/discord.js/src/client/actions/GuildScheduledEventCreate.js b/node_modules/discord.js/src/client/actions/GuildScheduledEventCreate.js new file mode 100644 index 0000000..0a2fb9b --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildScheduledEventCreate.js @@ -0,0 +1,27 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class GuildScheduledEventCreateAction extends Action { + handle(data) { + const client = this.client; + const guild = client.guilds.cache.get(data.guild_id); + if (guild) { + const guildScheduledEvent = guild.scheduledEvents._add(data); + + /** + * Emitted whenever a guild scheduled event is created. + * @event Client#guildScheduledEventCreate + * @param {GuildScheduledEvent} guildScheduledEvent The created guild scheduled event + */ + client.emit(Events.GuildScheduledEventCreate, guildScheduledEvent); + + return { guildScheduledEvent }; + } + + return {}; + } +} + +module.exports = GuildScheduledEventCreateAction; diff --git a/node_modules/discord.js/src/client/actions/GuildScheduledEventDelete.js b/node_modules/discord.js/src/client/actions/GuildScheduledEventDelete.js new file mode 100644 index 0000000..636bfc5 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildScheduledEventDelete.js @@ -0,0 +1,31 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class GuildScheduledEventDeleteAction extends Action { + handle(data) { + const client = this.client; + const guild = client.guilds.cache.get(data.guild_id); + + if (guild) { + const guildScheduledEvent = this.getScheduledEvent(data, guild); + if (guildScheduledEvent) { + guild.scheduledEvents.cache.delete(guildScheduledEvent.id); + + /** + * Emitted whenever a guild scheduled event is deleted. + * @event Client#guildScheduledEventDelete + * @param {GuildScheduledEvent} guildScheduledEvent The deleted guild scheduled event + */ + client.emit(Events.GuildScheduledEventDelete, guildScheduledEvent); + + return { guildScheduledEvent }; + } + } + + return {}; + } +} + +module.exports = GuildScheduledEventDeleteAction; diff --git a/node_modules/discord.js/src/client/actions/GuildScheduledEventUpdate.js b/node_modules/discord.js/src/client/actions/GuildScheduledEventUpdate.js new file mode 100644 index 0000000..7cabd85 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildScheduledEventUpdate.js @@ -0,0 +1,30 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class GuildScheduledEventUpdateAction extends Action { + handle(data) { + const client = this.client; + const guild = client.guilds.cache.get(data.guild_id); + + if (guild) { + const oldGuildScheduledEvent = guild.scheduledEvents.cache.get(data.id)?._clone() ?? null; + const newGuildScheduledEvent = guild.scheduledEvents._add(data); + + /** + * Emitted whenever a guild scheduled event gets updated. + * @event Client#guildScheduledEventUpdate + * @param {?GuildScheduledEvent} oldGuildScheduledEvent The guild scheduled event object before the update + * @param {GuildScheduledEvent} newGuildScheduledEvent The guild scheduled event object after the update + */ + client.emit(Events.GuildScheduledEventUpdate, oldGuildScheduledEvent, newGuildScheduledEvent); + + return { oldGuildScheduledEvent, newGuildScheduledEvent }; + } + + return {}; + } +} + +module.exports = GuildScheduledEventUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/GuildScheduledEventUserAdd.js b/node_modules/discord.js/src/client/actions/GuildScheduledEventUserAdd.js new file mode 100644 index 0000000..03520db --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildScheduledEventUserAdd.js @@ -0,0 +1,32 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class GuildScheduledEventUserAddAction extends Action { + handle(data) { + const client = this.client; + const guild = client.guilds.cache.get(data.guild_id); + + if (guild) { + const guildScheduledEvent = this.getScheduledEvent(data, guild); + const user = this.getUser(data); + + if (guildScheduledEvent && user) { + /** + * Emitted whenever a user subscribes to a guild scheduled event + * @event Client#guildScheduledEventUserAdd + * @param {GuildScheduledEvent} guildScheduledEvent The guild scheduled event + * @param {User} user The user who subscribed + */ + client.emit(Events.GuildScheduledEventUserAdd, guildScheduledEvent, user); + + return { guildScheduledEvent, user }; + } + } + + return {}; + } +} + +module.exports = GuildScheduledEventUserAddAction; diff --git a/node_modules/discord.js/src/client/actions/GuildScheduledEventUserRemove.js b/node_modules/discord.js/src/client/actions/GuildScheduledEventUserRemove.js new file mode 100644 index 0000000..2a04849 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildScheduledEventUserRemove.js @@ -0,0 +1,32 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class GuildScheduledEventUserRemoveAction extends Action { + handle(data) { + const client = this.client; + const guild = client.guilds.cache.get(data.guild_id); + + if (guild) { + const guildScheduledEvent = this.getScheduledEvent(data, guild); + const user = this.getUser(data); + + if (guildScheduledEvent && user) { + /** + * Emitted whenever a user unsubscribes from a guild scheduled event + * @event Client#guildScheduledEventUserRemove + * @param {GuildScheduledEvent} guildScheduledEvent The guild scheduled event + * @param {User} user The user who unsubscribed + */ + client.emit(Events.GuildScheduledEventUserRemove, guildScheduledEvent, user); + + return { guildScheduledEvent, user }; + } + } + + return {}; + } +} + +module.exports = GuildScheduledEventUserRemoveAction; diff --git a/node_modules/discord.js/src/client/actions/GuildStickerCreate.js b/node_modules/discord.js/src/client/actions/GuildStickerCreate.js new file mode 100644 index 0000000..7d81de9 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildStickerCreate.js @@ -0,0 +1,20 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class GuildStickerCreateAction extends Action { + handle(guild, createdSticker) { + const already = guild.stickers.cache.has(createdSticker.id); + const sticker = guild.stickers._add(createdSticker); + /** + * Emitted whenever a custom sticker is created in a guild. + * @event Client#stickerCreate + * @param {Sticker} sticker The sticker that was created + */ + if (!already) this.client.emit(Events.GuildStickerCreate, sticker); + return { sticker }; + } +} + +module.exports = GuildStickerCreateAction; diff --git a/node_modules/discord.js/src/client/actions/GuildStickerDelete.js b/node_modules/discord.js/src/client/actions/GuildStickerDelete.js new file mode 100644 index 0000000..7fd6b57 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildStickerDelete.js @@ -0,0 +1,19 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class GuildStickerDeleteAction extends Action { + handle(sticker) { + sticker.guild.stickers.cache.delete(sticker.id); + /** + * Emitted whenever a custom sticker is deleted in a guild. + * @event Client#stickerDelete + * @param {Sticker} sticker The sticker that was deleted + */ + this.client.emit(Events.GuildStickerDelete, sticker); + return { sticker }; + } +} + +module.exports = GuildStickerDeleteAction; diff --git a/node_modules/discord.js/src/client/actions/GuildStickerUpdate.js b/node_modules/discord.js/src/client/actions/GuildStickerUpdate.js new file mode 100644 index 0000000..5561c7e --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildStickerUpdate.js @@ -0,0 +1,20 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class GuildStickerUpdateAction extends Action { + handle(current, data) { + const old = current._update(data); + /** + * Emitted whenever a custom sticker is updated in a guild. + * @event Client#stickerUpdate + * @param {Sticker} oldSticker The old sticker + * @param {Sticker} newSticker The new sticker + */ + this.client.emit(Events.GuildStickerUpdate, old, current); + return { sticker: current }; + } +} + +module.exports = GuildStickerUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/GuildStickersUpdate.js b/node_modules/discord.js/src/client/actions/GuildStickersUpdate.js new file mode 100644 index 0000000..ccf1d63 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildStickersUpdate.js @@ -0,0 +1,34 @@ +'use strict'; + +const Action = require('./Action'); + +class GuildStickersUpdateAction extends Action { + handle(data) { + const guild = this.client.guilds.cache.get(data.guild_id); + if (!guild?.stickers) return; + + const deletions = new Map(guild.stickers.cache); + + for (const sticker of data.stickers) { + // Determine type of sticker event + const cachedSticker = guild.stickers.cache.get(sticker.id); + if (cachedSticker) { + deletions.delete(sticker.id); + if (!cachedSticker.equals(sticker)) { + // Sticker updated + this.client.actions.GuildStickerUpdate.handle(cachedSticker, sticker); + } + } else { + // Sticker added + this.client.actions.GuildStickerCreate.handle(guild, sticker); + } + } + + for (const sticker of deletions.values()) { + // Sticker deleted + this.client.actions.GuildStickerDelete.handle(sticker); + } + } +} + +module.exports = GuildStickersUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/GuildUpdate.js b/node_modules/discord.js/src/client/actions/GuildUpdate.js new file mode 100644 index 0000000..ef1f51b --- /dev/null +++ b/node_modules/discord.js/src/client/actions/GuildUpdate.js @@ -0,0 +1,33 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class GuildUpdateAction extends Action { + handle(data) { + const client = this.client; + + const guild = client.guilds.cache.get(data.id); + if (guild) { + const old = guild._update(data); + /** + * Emitted whenever a guild is updated - e.g. name change. + * @event Client#guildUpdate + * @param {Guild} oldGuild The guild before the update + * @param {Guild} newGuild The guild after the update + */ + client.emit(Events.GuildUpdate, old, guild); + return { + old, + updated: guild, + }; + } + + return { + old: null, + updated: null, + }; + } +} + +module.exports = GuildUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/InteractionCreate.js b/node_modules/discord.js/src/client/actions/InteractionCreate.js new file mode 100644 index 0000000..434fb0c --- /dev/null +++ b/node_modules/discord.js/src/client/actions/InteractionCreate.js @@ -0,0 +1,101 @@ +'use strict'; + +const { InteractionType, ComponentType, ApplicationCommandType } = require('discord-api-types/v10'); +const Action = require('./Action'); +const AutocompleteInteraction = require('../../structures/AutocompleteInteraction'); +const ButtonInteraction = require('../../structures/ButtonInteraction'); +const ChannelSelectMenuInteraction = require('../../structures/ChannelSelectMenuInteraction'); +const ChatInputCommandInteraction = require('../../structures/ChatInputCommandInteraction'); +const MentionableSelectMenuInteraction = require('../../structures/MentionableSelectMenuInteraction'); +const MessageContextMenuCommandInteraction = require('../../structures/MessageContextMenuCommandInteraction'); +const ModalSubmitInteraction = require('../../structures/ModalSubmitInteraction'); +const RoleSelectMenuInteraction = require('../../structures/RoleSelectMenuInteraction'); +const StringSelectMenuInteraction = require('../../structures/StringSelectMenuInteraction'); +const UserContextMenuCommandInteraction = require('../../structures/UserContextMenuCommandInteraction'); +const UserSelectMenuInteraction = require('../../structures/UserSelectMenuInteraction'); +const Events = require('../../util/Events'); + +class InteractionCreateAction extends Action { + handle(data) { + const client = this.client; + + // Resolve and cache partial channels for Interaction#channel getter + const channel = data.channel && this.getChannel(data.channel); + + // Do not emit this for interactions that cache messages that are non-text-based. + let InteractionClass; + + switch (data.type) { + case InteractionType.ApplicationCommand: + switch (data.data.type) { + case ApplicationCommandType.ChatInput: + InteractionClass = ChatInputCommandInteraction; + break; + case ApplicationCommandType.User: + InteractionClass = UserContextMenuCommandInteraction; + break; + case ApplicationCommandType.Message: + if (channel && !channel.isTextBased()) return; + InteractionClass = MessageContextMenuCommandInteraction; + break; + default: + client.emit( + Events.Debug, + `[INTERACTION] Received application command interaction with unknown type: ${data.data.type}`, + ); + return; + } + break; + case InteractionType.MessageComponent: + if (channel && !channel.isTextBased()) return; + + switch (data.data.component_type) { + case ComponentType.Button: + InteractionClass = ButtonInteraction; + break; + case ComponentType.StringSelect: + InteractionClass = StringSelectMenuInteraction; + break; + case ComponentType.UserSelect: + InteractionClass = UserSelectMenuInteraction; + break; + case ComponentType.RoleSelect: + InteractionClass = RoleSelectMenuInteraction; + break; + case ComponentType.MentionableSelect: + InteractionClass = MentionableSelectMenuInteraction; + break; + case ComponentType.ChannelSelect: + InteractionClass = ChannelSelectMenuInteraction; + break; + default: + client.emit( + Events.Debug, + `[INTERACTION] Received component interaction with unknown type: ${data.data.component_type}`, + ); + return; + } + break; + case InteractionType.ApplicationCommandAutocomplete: + InteractionClass = AutocompleteInteraction; + break; + case InteractionType.ModalSubmit: + InteractionClass = ModalSubmitInteraction; + break; + default: + client.emit(Events.Debug, `[INTERACTION] Received interaction with unknown type: ${data.type}`); + return; + } + + const interaction = new InteractionClass(client, data); + + /** + * Emitted when an interaction is created. + * @event Client#interactionCreate + * @param {BaseInteraction} interaction The interaction which was created + */ + client.emit(Events.InteractionCreate, interaction); + } +} + +module.exports = InteractionCreateAction; diff --git a/node_modules/discord.js/src/client/actions/InviteCreate.js b/node_modules/discord.js/src/client/actions/InviteCreate.js new file mode 100644 index 0000000..dc03f07 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/InviteCreate.js @@ -0,0 +1,27 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class InviteCreateAction extends Action { + handle(data) { + const client = this.client; + const channel = client.channels.cache.get(data.channel_id); + const guild = client.guilds.cache.get(data.guild_id); + if (!channel) return false; + + const inviteData = Object.assign(data, { channel, guild }); + const invite = guild.invites._add(inviteData); + + /** + * Emitted when an invite is created. + * <info>This event requires the {@link PermissionFlagsBits.ManageChannels} permission for the channel.</info> + * @event Client#inviteCreate + * @param {Invite} invite The invite that was created + */ + client.emit(Events.InviteCreate, invite); + return { invite }; + } +} + +module.exports = InviteCreateAction; diff --git a/node_modules/discord.js/src/client/actions/InviteDelete.js b/node_modules/discord.js/src/client/actions/InviteDelete.js new file mode 100644 index 0000000..58be00c --- /dev/null +++ b/node_modules/discord.js/src/client/actions/InviteDelete.js @@ -0,0 +1,29 @@ +'use strict'; + +const Action = require('./Action'); +const Invite = require('../../structures/Invite'); +const Events = require('../../util/Events'); + +class InviteDeleteAction extends Action { + handle(data) { + const client = this.client; + const channel = client.channels.cache.get(data.channel_id); + const guild = client.guilds.cache.get(data.guild_id); + if (!channel) return false; + + const inviteData = Object.assign(data, { channel, guild }); + const invite = new Invite(client, inviteData); + guild.invites.cache.delete(invite.code); + + /** + * Emitted when an invite is deleted. + * <info>This event requires the {@link PermissionFlagsBits.ManageChannels} permission for the channel.</info> + * @event Client#inviteDelete + * @param {Invite} invite The invite that was deleted + */ + client.emit(Events.InviteDelete, invite); + return { invite }; + } +} + +module.exports = InviteDeleteAction; diff --git a/node_modules/discord.js/src/client/actions/MessageCreate.js b/node_modules/discord.js/src/client/actions/MessageCreate.js new file mode 100644 index 0000000..8e011fc --- /dev/null +++ b/node_modules/discord.js/src/client/actions/MessageCreate.js @@ -0,0 +1,37 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class MessageCreateAction extends Action { + handle(data) { + const client = this.client; + const channel = this.getChannel(data); + if (channel) { + if (!channel.isTextBased()) return {}; + + if (channel.isThread()) { + channel.messageCount++; + channel.totalMessageSent++; + } + + const existing = channel.messages.cache.get(data.id); + if (existing) return { message: existing }; + const message = channel.messages._add(data); + channel.lastMessageId = data.id; + + /** + * Emitted whenever a message is created. + * @event Client#messageCreate + * @param {Message} message The created message + */ + client.emit(Events.MessageCreate, message); + + return { message }; + } + + return {}; + } +} + +module.exports = MessageCreateAction; diff --git a/node_modules/discord.js/src/client/actions/MessageDelete.js b/node_modules/discord.js/src/client/actions/MessageDelete.js new file mode 100644 index 0000000..f0c74d7 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/MessageDelete.js @@ -0,0 +1,32 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class MessageDeleteAction extends Action { + handle(data) { + const client = this.client; + const channel = this.getChannel(data); + let message; + if (channel) { + if (!channel.isTextBased()) return {}; + + if (channel.isThread()) channel.messageCount--; + + message = this.getMessage(data, channel); + if (message) { + channel.messages.cache.delete(message.id); + /** + * Emitted whenever a message is deleted. + * @event Client#messageDelete + * @param {Message} message The deleted message + */ + client.emit(Events.MessageDelete, message); + } + } + + return { message }; + } +} + +module.exports = MessageDeleteAction; diff --git a/node_modules/discord.js/src/client/actions/MessageDeleteBulk.js b/node_modules/discord.js/src/client/actions/MessageDeleteBulk.js new file mode 100644 index 0000000..5f61d19 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/MessageDeleteBulk.js @@ -0,0 +1,47 @@ +'use strict'; + +const { Collection } = require('@discordjs/collection'); +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class MessageDeleteBulkAction extends Action { + handle(data) { + const client = this.client; + const channel = client.channels.cache.get(data.channel_id); + + if (channel) { + if (!channel.isTextBased()) return {}; + + if (channel.isThread()) channel.messageCount -= data.ids.length; + + const ids = data.ids; + const messages = new Collection(); + for (const id of ids) { + const message = this.getMessage( + { + id, + guild_id: data.guild_id, + }, + channel, + false, + ); + if (message) { + messages.set(message.id, message); + channel.messages.cache.delete(id); + } + } + + /** + * Emitted whenever messages are deleted in bulk. + * @event Client#messageDeleteBulk + * @param {Collection<Snowflake, Message>} messages The deleted messages, mapped by their id + * @param {GuildTextBasedChannel} channel The channel that the messages were deleted in + */ + if (messages.size > 0) client.emit(Events.MessageBulkDelete, messages, channel); + return { messages }; + } + return {}; + } +} + +module.exports = MessageDeleteBulkAction; diff --git a/node_modules/discord.js/src/client/actions/MessageReactionAdd.js b/node_modules/discord.js/src/client/actions/MessageReactionAdd.js new file mode 100644 index 0000000..ea97bd6 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/MessageReactionAdd.js @@ -0,0 +1,55 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); +const Partials = require('../../util/Partials'); + +/* +{ user_id: 'id', + message_id: 'id', + emoji: { name: '�', id: null }, + channel_id: 'id', + // If originating from a guild + guild_id: 'id', + member: { ..., user: { ... } } } +*/ + +class MessageReactionAdd extends Action { + handle(data, fromStructure = false) { + if (!data.emoji) return false; + + const user = this.getUserFromMember(data); + if (!user) return false; + + // Verify channel + const channel = this.getChannel(data); + if (!channel?.isTextBased()) return false; + + // Verify message + const message = this.getMessage(data, channel); + if (!message) return false; + + // Verify reaction + const includePartial = this.client.options.partials.includes(Partials.Reaction); + if (message.partial && !includePartial) return false; + const reaction = message.reactions._add({ + emoji: data.emoji, + count: message.partial ? null : 0, + me: user.id === this.client.user.id, + }); + if (!reaction) return false; + reaction._add(user); + if (fromStructure) return { message, reaction, user }; + /** + * Emitted whenever a reaction is added to a cached message. + * @event Client#messageReactionAdd + * @param {MessageReaction} messageReaction The reaction object + * @param {User} user The user that applied the guild or reaction emoji + */ + this.client.emit(Events.MessageReactionAdd, reaction, user); + + return { message, reaction, user }; + } +} + +module.exports = MessageReactionAdd; diff --git a/node_modules/discord.js/src/client/actions/MessageReactionRemove.js b/node_modules/discord.js/src/client/actions/MessageReactionRemove.js new file mode 100644 index 0000000..9ca3a8e --- /dev/null +++ b/node_modules/discord.js/src/client/actions/MessageReactionRemove.js @@ -0,0 +1,45 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +/* +{ user_id: 'id', + message_id: 'id', + emoji: { name: '�', id: null }, + channel_id: 'id', + guild_id: 'id' } +*/ + +class MessageReactionRemove extends Action { + handle(data) { + if (!data.emoji) return false; + + const user = this.getUser(data); + if (!user) return false; + + // Verify channel + const channel = this.getChannel(data); + if (!channel?.isTextBased()) return false; + + // Verify message + const message = this.getMessage(data, channel); + if (!message) return false; + + // Verify reaction + const reaction = this.getReaction(data, message, user); + if (!reaction) return false; + reaction._remove(user); + /** + * Emitted whenever a reaction is removed from a cached message. + * @event Client#messageReactionRemove + * @param {MessageReaction} messageReaction The reaction object + * @param {User} user The user whose emoji or reaction emoji was removed + */ + this.client.emit(Events.MessageReactionRemove, reaction, user); + + return { message, reaction, user }; + } +} + +module.exports = MessageReactionRemove; diff --git a/node_modules/discord.js/src/client/actions/MessageReactionRemoveAll.js b/node_modules/discord.js/src/client/actions/MessageReactionRemoveAll.js new file mode 100644 index 0000000..b1c023f --- /dev/null +++ b/node_modules/discord.js/src/client/actions/MessageReactionRemoveAll.js @@ -0,0 +1,33 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class MessageReactionRemoveAll extends Action { + handle(data) { + // Verify channel + const channel = this.getChannel(data); + if (!channel?.isTextBased()) return false; + + // Verify message + const message = this.getMessage(data, channel); + if (!message) return false; + + // Copy removed reactions to emit for the event. + const removed = message.reactions.cache.clone(); + + message.reactions.cache.clear(); + this.client.emit(Events.MessageReactionRemoveAll, message, removed); + + return { message }; + } +} + +/** + * Emitted whenever all reactions are removed from a cached message. + * @event Client#messageReactionRemoveAll + * @param {Message} message The message the reactions were removed from + * @param {Collection<string|Snowflake, MessageReaction>} reactions The cached message reactions that were removed. + */ + +module.exports = MessageReactionRemoveAll; diff --git a/node_modules/discord.js/src/client/actions/MessageReactionRemoveEmoji.js b/node_modules/discord.js/src/client/actions/MessageReactionRemoveEmoji.js new file mode 100644 index 0000000..3290214 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/MessageReactionRemoveEmoji.js @@ -0,0 +1,28 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class MessageReactionRemoveEmoji extends Action { + handle(data) { + const channel = this.getChannel(data); + if (!channel?.isTextBased()) return false; + + const message = this.getMessage(data, channel); + if (!message) return false; + + const reaction = this.getReaction(data, message); + if (!reaction) return false; + if (!message.partial) message.reactions.cache.delete(reaction.emoji.id ?? reaction.emoji.name); + + /** + * Emitted when a bot removes an emoji reaction from a cached message. + * @event Client#messageReactionRemoveEmoji + * @param {MessageReaction} reaction The reaction that was removed + */ + this.client.emit(Events.MessageReactionRemoveEmoji, reaction); + return { reaction }; + } +} + +module.exports = MessageReactionRemoveEmoji; diff --git a/node_modules/discord.js/src/client/actions/MessageUpdate.js b/node_modules/discord.js/src/client/actions/MessageUpdate.js new file mode 100644 index 0000000..fe757c0 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/MessageUpdate.js @@ -0,0 +1,26 @@ +'use strict'; + +const Action = require('./Action'); + +class MessageUpdateAction extends Action { + handle(data) { + const channel = this.getChannel(data); + if (channel) { + if (!channel.isTextBased()) return {}; + + const { id, channel_id, guild_id, author, timestamp, type } = data; + const message = this.getMessage({ id, channel_id, guild_id, author, timestamp, type }, channel); + if (message) { + const old = message._update(data); + return { + old, + updated: message, + }; + } + } + + return {}; + } +} + +module.exports = MessageUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/PresenceUpdate.js b/node_modules/discord.js/src/client/actions/PresenceUpdate.js new file mode 100644 index 0000000..0b4aaab --- /dev/null +++ b/node_modules/discord.js/src/client/actions/PresenceUpdate.js @@ -0,0 +1,42 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class PresenceUpdateAction extends Action { + handle(data) { + let user = this.client.users.cache.get(data.user.id); + if (!user && data.user.username) user = this.client.users._add(data.user); + if (!user) return; + + if (data.user.username) { + if (!user._equals(data.user)) this.client.actions.UserUpdate.handle(data.user); + } + + const guild = this.client.guilds.cache.get(data.guild_id); + if (!guild) return; + + const oldPresence = guild.presences.cache.get(user.id)?._clone() ?? null; + let member = guild.members.cache.get(user.id); + if (!member && data.status !== 'offline') { + member = guild.members._add({ + user, + deaf: false, + mute: false, + }); + this.client.emit(Events.GuildMemberAvailable, member); + } + const newPresence = guild.presences._add(Object.assign(data, { guild })); + if (this.client.listenerCount(Events.PresenceUpdate) && !newPresence.equals(oldPresence)) { + /** + * Emitted whenever a guild member's presence (e.g. status, activity) is changed. + * @event Client#presenceUpdate + * @param {?Presence} oldPresence The presence before the update, if one at all + * @param {Presence} newPresence The presence after the update + */ + this.client.emit(Events.PresenceUpdate, oldPresence, newPresence); + } + } +} + +module.exports = PresenceUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/StageInstanceCreate.js b/node_modules/discord.js/src/client/actions/StageInstanceCreate.js new file mode 100644 index 0000000..4edd530 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/StageInstanceCreate.js @@ -0,0 +1,28 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class StageInstanceCreateAction extends Action { + handle(data) { + const client = this.client; + const channel = this.getChannel(data); + + if (channel) { + const stageInstance = channel.guild.stageInstances._add(data); + + /** + * Emitted whenever a stage instance is created. + * @event Client#stageInstanceCreate + * @param {StageInstance} stageInstance The created stage instance + */ + client.emit(Events.StageInstanceCreate, stageInstance); + + return { stageInstance }; + } + + return {}; + } +} + +module.exports = StageInstanceCreateAction; diff --git a/node_modules/discord.js/src/client/actions/StageInstanceDelete.js b/node_modules/discord.js/src/client/actions/StageInstanceDelete.js new file mode 100644 index 0000000..0d5da38 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/StageInstanceDelete.js @@ -0,0 +1,31 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class StageInstanceDeleteAction extends Action { + handle(data) { + const client = this.client; + const channel = this.getChannel(data); + + if (channel) { + const stageInstance = channel.guild.stageInstances._add(data); + if (stageInstance) { + channel.guild.stageInstances.cache.delete(stageInstance.id); + + /** + * Emitted whenever a stage instance is deleted. + * @event Client#stageInstanceDelete + * @param {StageInstance} stageInstance The deleted stage instance + */ + client.emit(Events.StageInstanceDelete, stageInstance); + + return { stageInstance }; + } + } + + return {}; + } +} + +module.exports = StageInstanceDeleteAction; diff --git a/node_modules/discord.js/src/client/actions/StageInstanceUpdate.js b/node_modules/discord.js/src/client/actions/StageInstanceUpdate.js new file mode 100644 index 0000000..008a53c --- /dev/null +++ b/node_modules/discord.js/src/client/actions/StageInstanceUpdate.js @@ -0,0 +1,30 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class StageInstanceUpdateAction extends Action { + handle(data) { + const client = this.client; + const channel = this.getChannel(data); + + if (channel) { + const oldStageInstance = channel.guild.stageInstances.cache.get(data.id)?._clone() ?? null; + const newStageInstance = channel.guild.stageInstances._add(data); + + /** + * Emitted whenever a stage instance gets updated - e.g. change in topic or privacy level + * @event Client#stageInstanceUpdate + * @param {?StageInstance} oldStageInstance The stage instance before the update + * @param {StageInstance} newStageInstance The stage instance after the update + */ + client.emit(Events.StageInstanceUpdate, oldStageInstance, newStageInstance); + + return { oldStageInstance, newStageInstance }; + } + + return {}; + } +} + +module.exports = StageInstanceUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/ThreadCreate.js b/node_modules/discord.js/src/client/actions/ThreadCreate.js new file mode 100644 index 0000000..a8ff6c6 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/ThreadCreate.js @@ -0,0 +1,24 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class ThreadCreateAction extends Action { + handle(data) { + const client = this.client; + const existing = client.channels.cache.has(data.id); + const thread = client.channels._add(data); + if (!existing && thread) { + /** + * Emitted whenever a thread is created or when the client user is added to a thread. + * @event Client#threadCreate + * @param {ThreadChannel} thread The thread that was created + * @param {boolean} newlyCreated Whether the thread was newly created + */ + client.emit(Events.ThreadCreate, thread, data.newly_created ?? false); + } + return { thread }; + } +} + +module.exports = ThreadCreateAction; diff --git a/node_modules/discord.js/src/client/actions/ThreadDelete.js b/node_modules/discord.js/src/client/actions/ThreadDelete.js new file mode 100644 index 0000000..3ec81a4 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/ThreadDelete.js @@ -0,0 +1,26 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class ThreadDeleteAction extends Action { + handle(data) { + const client = this.client; + const thread = client.channels.cache.get(data.id); + + if (thread) { + client.channels._remove(thread.id); + + /** + * Emitted whenever a thread is deleted. + * @event Client#threadDelete + * @param {ThreadChannel} thread The thread that was deleted + */ + client.emit(Events.ThreadDelete, thread); + } + + return { thread }; + } +} + +module.exports = ThreadDeleteAction; diff --git a/node_modules/discord.js/src/client/actions/ThreadListSync.js b/node_modules/discord.js/src/client/actions/ThreadListSync.js new file mode 100644 index 0000000..b16fb85 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/ThreadListSync.js @@ -0,0 +1,60 @@ +'use strict'; + +const { Collection } = require('@discordjs/collection'); +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class ThreadListSyncAction extends Action { + handle(data) { + const client = this.client; + + const guild = client.guilds.cache.get(data.guild_id); + if (!guild) return {}; + + if (data.channel_ids) { + for (const id of data.channel_ids) { + const channel = client.channels.resolve(id); + if (channel) this.removeStale(channel); + } + } else { + for (const channel of guild.channels.cache.values()) { + this.removeStale(channel); + } + } + + const syncedThreads = data.threads.reduce((coll, rawThread) => { + const thread = client.channels._add(rawThread); + return coll.set(thread.id, thread); + }, new Collection()); + + for (const rawMember of Object.values(data.members)) { + // Discord sends the thread id as id in this object + const thread = client.channels.cache.get(rawMember.id); + if (thread) { + thread.members._add(rawMember); + } + } + + /** + * Emitted whenever the client user gains access to a text or news channel that contains threads + * @event Client#threadListSync + * @param {Collection<Snowflake, ThreadChannel>} threads The threads that were synced + * @param {Guild} guild The guild that the threads were synced in + */ + client.emit(Events.ThreadListSync, syncedThreads, guild); + + return { + syncedThreads, + }; + } + + removeStale(channel) { + channel.threads?.cache.forEach(thread => { + if (!thread.archived) { + this.client.channels._remove(thread.id); + } + }); + } +} + +module.exports = ThreadListSyncAction; diff --git a/node_modules/discord.js/src/client/actions/ThreadMemberUpdate.js b/node_modules/discord.js/src/client/actions/ThreadMemberUpdate.js new file mode 100644 index 0000000..0b17f70 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/ThreadMemberUpdate.js @@ -0,0 +1,30 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class ThreadMemberUpdateAction extends Action { + handle(data) { + const client = this.client; + // Discord sends the thread id as id in this object + const thread = client.channels.cache.get(data.id); + if (thread) { + const member = thread.members.cache.get(data.user_id); + if (!member) { + const newMember = thread.members._add(data); + return { newMember }; + } + const old = member._update(data); + /** + * Emitted whenever the client user's thread member is updated. + * @event Client#threadMemberUpdate + * @param {ThreadMember} oldMember The member before the update + * @param {ThreadMember} newMember The member after the update + */ + client.emit(Events.ThreadMemberUpdate, old, member); + } + return {}; + } +} + +module.exports = ThreadMemberUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/ThreadMembersUpdate.js b/node_modules/discord.js/src/client/actions/ThreadMembersUpdate.js new file mode 100644 index 0000000..c1781b9 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/ThreadMembersUpdate.js @@ -0,0 +1,47 @@ +'use strict'; + +const { Collection } = require('@discordjs/collection'); +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class ThreadMembersUpdateAction extends Action { + handle(data) { + const client = this.client; + const thread = client.channels.cache.get(data.id); + if (thread) { + thread.memberCount = data.member_count; + const addedMembers = new Collection(); + const removedMembers = new Collection(); + + data.added_members?.reduce( + (_addedMembers, addedMember) => _addedMembers.set(addedMember.user_id, thread.members._add(addedMember)), + addedMembers, + ); + + data.removed_member_ids?.reduce((removedMembersIds, removedMembersId) => { + const threadMember = this.getThreadMember(removedMembersId, thread.members); + if (threadMember) removedMembersIds.set(threadMember.id, threadMember); + thread.members.cache.delete(removedMembersId); + return removedMembersIds; + }, removedMembers); + + if (addedMembers.size === 0 && removedMembers.size === 0) { + // Uncached thread member(s) left. + return {}; + } + + /** + * Emitted whenever members are added or removed from a thread. + * <info>This event requires the {@link GatewayIntentBits.GuildMembers} privileged gateway intent.</info> + * @event Client#threadMembersUpdate + * @param {Collection<Snowflake, ThreadMember>} addedMembers The members that were added + * @param {Collection<Snowflake, ThreadMember>} removedMembers The members that were removed + * @param {ThreadChannel} thread The thread where members got updated + */ + client.emit(Events.ThreadMembersUpdate, addedMembers, removedMembers, thread); + } + return {}; + } +} + +module.exports = ThreadMembersUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/TypingStart.js b/node_modules/discord.js/src/client/actions/TypingStart.js new file mode 100644 index 0000000..4e79920 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/TypingStart.js @@ -0,0 +1,29 @@ +'use strict'; + +const Action = require('./Action'); +const Typing = require('../../structures/Typing'); +const Events = require('../../util/Events'); + +class TypingStart extends Action { + handle(data) { + const channel = this.getChannel(data); + if (!channel) return; + + if (!channel.isTextBased()) { + this.client.emit(Events.Warn, `Discord sent a typing packet to a ${channel.type} channel ${channel.id}`); + return; + } + + const user = this.getUserFromMember(data); + if (user) { + /** + * Emitted whenever a user starts typing in a channel. + * @event Client#typingStart + * @param {Typing} typing The typing state + */ + this.client.emit(Events.TypingStart, new Typing(channel, user, data)); + } + } +} + +module.exports = TypingStart; diff --git a/node_modules/discord.js/src/client/actions/UserUpdate.js b/node_modules/discord.js/src/client/actions/UserUpdate.js new file mode 100644 index 0000000..923ddf5 --- /dev/null +++ b/node_modules/discord.js/src/client/actions/UserUpdate.js @@ -0,0 +1,36 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class UserUpdateAction extends Action { + handle(data) { + const client = this.client; + + const newUser = data.id === client.user.id ? client.user : client.users.cache.get(data.id); + const oldUser = newUser._update(data); + + if (!oldUser.equals(newUser)) { + /** + * Emitted whenever a user's details (e.g. username) are changed. + * Triggered by the Discord gateway events {@link Events.UserUpdate}, + * {@link Events.GuildMemberUpdate}, and {@link Events.PresenceUpdate}. + * @event Client#userUpdate + * @param {User} oldUser The user before the update + * @param {User} newUser The user after the update + */ + client.emit(Events.UserUpdate, oldUser, newUser); + return { + old: oldUser, + updated: newUser, + }; + } + + return { + old: null, + updated: null, + }; + } +} + +module.exports = UserUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/VoiceStateUpdate.js b/node_modules/discord.js/src/client/actions/VoiceStateUpdate.js new file mode 100644 index 0000000..fc7400f --- /dev/null +++ b/node_modules/discord.js/src/client/actions/VoiceStateUpdate.js @@ -0,0 +1,43 @@ +'use strict'; + +const Action = require('./Action'); +const VoiceState = require('../../structures/VoiceState'); +const Events = require('../../util/Events'); + +class VoiceStateUpdate extends Action { + handle(data) { + const client = this.client; + const guild = client.guilds.cache.get(data.guild_id); + if (guild) { + // Update the state + const oldState = + guild.voiceStates.cache.get(data.user_id)?._clone() ?? new VoiceState(guild, { user_id: data.user_id }); + + const newState = guild.voiceStates._add(data); + + // Get the member + let member = guild.members.cache.get(data.user_id); + if (member && data.member) { + member._patch(data.member); + } else if (data.member?.user && data.member.joined_at) { + member = guild.members._add(data.member); + } + + // Emit event + if (member?.user.id === client.user.id) { + client.emit('debug', `[VOICE] received voice state update: ${JSON.stringify(data)}`); + client.voice.onVoiceStateUpdate(data); + } + + /** + * Emitted whenever a member changes voice state - e.g. joins/leaves a channel, mutes/unmutes. + * @event Client#voiceStateUpdate + * @param {VoiceState} oldState The voice state before the update + * @param {VoiceState} newState The voice state after the update + */ + client.emit(Events.VoiceStateUpdate, oldState, newState); + } + } +} + +module.exports = VoiceStateUpdate; diff --git a/node_modules/discord.js/src/client/actions/WebhooksUpdate.js b/node_modules/discord.js/src/client/actions/WebhooksUpdate.js new file mode 100644 index 0000000..2bf41ba --- /dev/null +++ b/node_modules/discord.js/src/client/actions/WebhooksUpdate.js @@ -0,0 +1,37 @@ +'use strict'; + +const process = require('node:process'); +const Action = require('./Action'); + +let deprecationEmitted = false; + +class WebhooksUpdate extends Action { + handle(data) { + const client = this.client; + const channel = client.channels.cache.get(data.channel_id); + if (!channel) return; + + // TODO: change to Events.WebhooksUpdate in the next major version + /** + * Emitted whenever a channel has its webhooks changed. + * @event Client#webhooksUpdate + * @param {TextChannel|NewsChannel|VoiceChannel|StageChannel|ForumChannel} channel + * The channel that had a webhook update + */ + client.emit('webhooksUpdate', channel); + + /** + * Emitted whenever a channel has its webhooks changed. + * @event Client#webhookUpdate + * @param {TextChannel|NewsChannel|VoiceChannel|StageChannel|ForumChannel} channel + * The channel that had a webhook update + * @deprecated Use {@link Client#event:webhooksUpdate} instead. + */ + if (client.emit('webhookUpdate', channel) && !deprecationEmitted) { + deprecationEmitted = true; + process.emitWarning('The webhookUpdate event is deprecated. Use webhooksUpdate instead.', 'DeprecationWarning'); + } + } +} + +module.exports = WebhooksUpdate; diff --git a/node_modules/discord.js/src/client/voice/ClientVoiceManager.js b/node_modules/discord.js/src/client/voice/ClientVoiceManager.js new file mode 100644 index 0000000..192e700 --- /dev/null +++ b/node_modules/discord.js/src/client/voice/ClientVoiceManager.js @@ -0,0 +1,44 @@ +'use strict'; + +const Events = require('../../util/Events'); + +/** + * Manages voice connections for the client + */ +class ClientVoiceManager { + constructor(client) { + /** + * The client that instantiated this voice manager + * @type {Client} + * @readonly + * @name ClientVoiceManager#client + */ + Object.defineProperty(this, 'client', { value: client }); + + /** + * Maps guild ids to voice adapters created for use with @discordjs/voice. + * @type {Map<Snowflake, Object>} + */ + this.adapters = new Map(); + + client.on(Events.ShardDisconnect, (_, shardId) => { + for (const [guildId, adapter] of this.adapters.entries()) { + if (client.guilds.cache.get(guildId)?.shardId === shardId) { + adapter.destroy(); + } + } + }); + } + + onVoiceServer(payload) { + this.adapters.get(payload.guild_id)?.onVoiceServerUpdate(payload); + } + + onVoiceStateUpdate(payload) { + if (payload.guild_id && payload.session_id && payload.user_id === this.client.user?.id) { + this.adapters.get(payload.guild_id)?.onVoiceStateUpdate(payload); + } + } +} + +module.exports = ClientVoiceManager; diff --git a/node_modules/discord.js/src/client/websocket/WebSocketManager.js b/node_modules/discord.js/src/client/websocket/WebSocketManager.js new file mode 100644 index 0000000..f62610b --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/WebSocketManager.js @@ -0,0 +1,394 @@ +'use strict'; + +const EventEmitter = require('node:events'); +const process = require('node:process'); +const { setImmediate } = require('node:timers'); +const { Collection } = require('@discordjs/collection'); +const { + WebSocketManager: WSWebSocketManager, + WebSocketShardEvents: WSWebSocketShardEvents, + CompressionMethod, + CloseCodes, +} = require('@discordjs/ws'); +const { GatewayCloseCodes, GatewayDispatchEvents } = require('discord-api-types/v10'); +const WebSocketShard = require('./WebSocketShard'); +const PacketHandlers = require('./handlers'); +const { DiscordjsError, ErrorCodes } = require('../../errors'); +const Events = require('../../util/Events'); +const Status = require('../../util/Status'); +const WebSocketShardEvents = require('../../util/WebSocketShardEvents'); + +let zlib; + +try { + zlib = require('zlib-sync'); +} catch {} // eslint-disable-line no-empty + +const BeforeReadyWhitelist = [ + GatewayDispatchEvents.Ready, + GatewayDispatchEvents.Resumed, + GatewayDispatchEvents.GuildCreate, + GatewayDispatchEvents.GuildDelete, + GatewayDispatchEvents.GuildMembersChunk, + GatewayDispatchEvents.GuildMemberAdd, + GatewayDispatchEvents.GuildMemberRemove, +]; + +const WaitingForGuildEvents = [GatewayDispatchEvents.GuildCreate, GatewayDispatchEvents.GuildDelete]; + +const UNRESUMABLE_CLOSE_CODES = [ + CloseCodes.Normal, + GatewayCloseCodes.AlreadyAuthenticated, + GatewayCloseCodes.InvalidSeq, +]; + +const reasonIsDeprecated = 'the reason property is deprecated, use the code property to determine the reason'; +let deprecationEmittedForInvalidSessionEvent = false; +let deprecationEmittedForDestroyedEvent = false; + +/** + * The WebSocket manager for this client. + * <info>This class forwards raw dispatch events, + * read more about it here {@link https://discord.com/developers/docs/topics/gateway}</info> + * @extends {EventEmitter} + */ +class WebSocketManager extends EventEmitter { + constructor(client) { + super(); + + /** + * The client that instantiated this WebSocketManager + * @type {Client} + * @readonly + * @name WebSocketManager#client + */ + Object.defineProperty(this, 'client', { value: client }); + + /** + * The gateway this manager uses + * @type {?string} + */ + this.gateway = null; + + /** + * A collection of all shards this manager handles + * @type {Collection<number, WebSocketShard>} + */ + this.shards = new Collection(); + + /** + * An array of queued events before this WebSocketManager became ready + * @type {Object[]} + * @private + * @name WebSocketManager#packetQueue + */ + Object.defineProperty(this, 'packetQueue', { value: [] }); + + /** + * The current status of this WebSocketManager + * @type {Status} + */ + this.status = Status.Idle; + + /** + * If this manager was destroyed. It will prevent shards from reconnecting + * @type {boolean} + * @private + */ + this.destroyed = false; + + /** + * The internal WebSocketManager from `@discordjs/ws`. + * @type {WSWebSocketManager} + * @private + */ + this._ws = null; + } + + /** + * The average ping of all WebSocketShards + * @type {number} + * @readonly + */ + get ping() { + const sum = this.shards.reduce((a, b) => a + b.ping, 0); + return sum / this.shards.size; + } + + /** + * Emits a debug message. + * @param {string} message The debug message + * @param {?number} [shardId] The id of the shard that emitted this message, if any + * @private + */ + debug(message, shardId) { + this.client.emit( + Events.Debug, + `[WS => ${typeof shardId === 'number' ? `Shard ${shardId}` : 'Manager'}] ${message}`, + ); + } + + /** + * Connects this manager to the gateway. + * @private + */ + async connect() { + const invalidToken = new DiscordjsError(ErrorCodes.TokenInvalid); + const { shards, shardCount, intents, ws } = this.client.options; + if (this._ws && this._ws.options.token !== this.client.token) { + await this._ws.destroy({ code: CloseCodes.Normal, reason: 'Login with differing token requested' }); + this._ws = null; + } + if (!this._ws) { + const wsOptions = { + intents: intents.bitfield, + rest: this.client.rest, + token: this.client.token, + largeThreshold: ws.large_threshold, + version: ws.version, + shardIds: shards === 'auto' ? null : shards, + shardCount: shards === 'auto' ? null : shardCount, + initialPresence: ws.presence, + retrieveSessionInfo: shardId => this.shards.get(shardId).sessionInfo, + updateSessionInfo: (shardId, sessionInfo) => { + this.shards.get(shardId).sessionInfo = sessionInfo; + }, + compression: zlib ? CompressionMethod.ZlibStream : null, + }; + if (ws.buildIdentifyThrottler) wsOptions.buildIdentifyThrottler = ws.buildIdentifyThrottler; + if (ws.buildStrategy) wsOptions.buildStrategy = ws.buildStrategy; + this._ws = new WSWebSocketManager(wsOptions); + this.attachEvents(); + } + + const { + url: gatewayURL, + shards: recommendedShards, + session_start_limit: sessionStartLimit, + } = await this._ws.fetchGatewayInformation().catch(error => { + throw error.status === 401 ? invalidToken : error; + }); + + const { total, remaining } = sessionStartLimit; + + this.debug(`Fetched Gateway Information + URL: ${gatewayURL} + Recommended Shards: ${recommendedShards}`); + + this.debug(`Session Limit Information + Total: ${total} + Remaining: ${remaining}`); + + this.gateway = `${gatewayURL}/`; + + this.client.options.shardCount = await this._ws.getShardCount(); + this.client.options.shards = await this._ws.getShardIds(); + this.totalShards = this.client.options.shards.length; + for (const id of this.client.options.shards) { + if (!this.shards.has(id)) { + const shard = new WebSocketShard(this, id); + this.shards.set(id, shard); + + shard.on(WebSocketShardEvents.AllReady, unavailableGuilds => { + /** + * Emitted when a shard turns ready. + * @event Client#shardReady + * @param {number} id The shard id that turned ready + * @param {?Set<Snowflake>} unavailableGuilds Set of unavailable guild ids, if any + */ + this.client.emit(Events.ShardReady, shard.id, unavailableGuilds); + + this.checkShardsReady(); + }); + shard.status = Status.Connecting; + } + } + + await this._ws.connect(); + + this.shards.forEach(shard => { + if (shard.listenerCount(WebSocketShardEvents.InvalidSession) > 0 && !deprecationEmittedForInvalidSessionEvent) { + process.emitWarning( + 'The WebSocketShard#invalidSession event is deprecated and will never emit.', + 'DeprecationWarning', + ); + + deprecationEmittedForInvalidSessionEvent = true; + } + if (shard.listenerCount(WebSocketShardEvents.Destroyed) > 0 && !deprecationEmittedForDestroyedEvent) { + process.emitWarning( + 'The WebSocketShard#destroyed event is deprecated and will never emit.', + 'DeprecationWarning', + ); + + deprecationEmittedForDestroyedEvent = true; + } + }); + } + + /** + * Attaches event handlers to the internal WebSocketShardManager from `@discordjs/ws`. + * @private + */ + attachEvents() { + this._ws.on(WSWebSocketShardEvents.Debug, ({ message, shardId }) => this.debug(message, shardId)); + this._ws.on(WSWebSocketShardEvents.Dispatch, ({ data, shardId }) => { + this.client.emit(Events.Raw, data, shardId); + this.emit(data.t, data.d, shardId); + const shard = this.shards.get(shardId); + this.handlePacket(data, shard); + if (shard.status === Status.WaitingForGuilds && WaitingForGuildEvents.includes(data.t)) { + shard.gotGuild(data.d.id); + } + }); + + this._ws.on(WSWebSocketShardEvents.Ready, ({ data, shardId }) => { + this.shards.get(shardId).onReadyPacket(data); + }); + + this._ws.on(WSWebSocketShardEvents.Closed, ({ code, shardId }) => { + const shard = this.shards.get(shardId); + shard.emit(WebSocketShardEvents.Close, { code, reason: reasonIsDeprecated, wasClean: true }); + if (UNRESUMABLE_CLOSE_CODES.includes(code) && this.destroyed) { + shard.status = Status.Disconnected; + /** + * Emitted when a shard's WebSocket disconnects and will no longer reconnect. + * @event Client#shardDisconnect + * @param {CloseEvent} event The WebSocket close event + * @param {number} id The shard id that disconnected + */ + this.client.emit(Events.ShardDisconnect, { code, reason: reasonIsDeprecated, wasClean: true }, shardId); + this.debug(GatewayCloseCodes[code], shardId); + return; + } + + this.shards.get(shardId).status = Status.Connecting; + /** + * Emitted when a shard is attempting to reconnect or re-identify. + * @event Client#shardReconnecting + * @param {number} id The shard id that is attempting to reconnect + */ + this.client.emit(Events.ShardReconnecting, shardId); + }); + this._ws.on(WSWebSocketShardEvents.Hello, ({ shardId }) => { + const shard = this.shards.get(shardId); + if (shard.sessionInfo) { + shard.closeSequence = shard.sessionInfo.sequence; + shard.status = Status.Resuming; + } else { + shard.status = Status.Identifying; + } + }); + + this._ws.on(WSWebSocketShardEvents.Resumed, ({ shardId }) => { + const shard = this.shards.get(shardId); + shard.status = Status.Ready; + /** + * Emitted when the shard resumes successfully + * @event WebSocketShard#resumed + */ + shard.emit(WebSocketShardEvents.Resumed); + }); + + this._ws.on(WSWebSocketShardEvents.HeartbeatComplete, ({ heartbeatAt, latency, shardId }) => { + this.debug(`Heartbeat acknowledged, latency of ${latency}ms.`, shardId); + const shard = this.shards.get(shardId); + shard.lastPingTimestamp = heartbeatAt; + shard.ping = latency; + }); + + this._ws.on(WSWebSocketShardEvents.Error, ({ error, shardId }) => { + /** + * Emitted whenever a shard's WebSocket encounters a connection error. + * @event Client#shardError + * @param {Error} error The encountered error + * @param {number} shardId The shard that encountered this error + */ + this.client.emit(Events.ShardError, error, shardId); + }); + } + + /** + * Broadcasts a packet to every shard this manager handles. + * @param {Object} packet The packet to send + * @private + */ + broadcast(packet) { + for (const shardId of this.shards.keys()) this._ws.send(shardId, packet); + } + + /** + * Destroys this manager and all its shards. + * @private + */ + async destroy() { + if (this.destroyed) return; + // TODO: Make a util for getting a stack + this.debug(`Manager was destroyed. Called by:\n${new Error().stack}`); + this.destroyed = true; + await this._ws?.destroy({ code: CloseCodes.Normal }); + } + + /** + * Processes a packet and queues it if this WebSocketManager is not ready. + * @param {Object} [packet] The packet to be handled + * @param {WebSocketShard} [shard] The shard that will handle this packet + * @returns {boolean} + * @private + */ + handlePacket(packet, shard) { + if (packet && this.status !== Status.Ready) { + if (!BeforeReadyWhitelist.includes(packet.t)) { + this.packetQueue.push({ packet, shard }); + return false; + } + } + + if (this.packetQueue.length) { + const item = this.packetQueue.shift(); + setImmediate(() => { + this.handlePacket(item.packet, item.shard); + }).unref(); + } + + if (packet && PacketHandlers[packet.t]) { + PacketHandlers[packet.t](this.client, packet, shard); + } + + return true; + } + + /** + * Checks whether the client is ready to be marked as ready. + * @private + */ + checkShardsReady() { + if (this.status === Status.Ready) return; + if (this.shards.size !== this.totalShards || this.shards.some(s => s.status !== Status.Ready)) { + return; + } + + this.triggerClientReady(); + } + + /** + * Causes the client to be marked as ready and emits the ready event. + * @private + */ + triggerClientReady() { + this.status = Status.Ready; + + this.client.readyTimestamp = Date.now(); + + /** + * Emitted when the client becomes ready to start working. + * @event Client#ready + * @param {Client} client The client + */ + this.client.emit(Events.ClientReady, this.client); + + this.handlePacket(); + } +} + +module.exports = WebSocketManager; diff --git a/node_modules/discord.js/src/client/websocket/WebSocketShard.js b/node_modules/discord.js/src/client/websocket/WebSocketShard.js new file mode 100644 index 0000000..05bc225 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/WebSocketShard.js @@ -0,0 +1,231 @@ +'use strict'; + +const EventEmitter = require('node:events'); +const process = require('node:process'); +const { setTimeout, clearTimeout } = require('node:timers'); +const { GatewayIntentBits } = require('discord-api-types/v10'); +const Status = require('../../util/Status'); +const WebSocketShardEvents = require('../../util/WebSocketShardEvents'); + +let deprecationEmittedForImportant = false; +/** + * Represents a Shard's WebSocket connection + * @extends {EventEmitter} + */ +class WebSocketShard extends EventEmitter { + constructor(manager, id) { + super(); + + /** + * The WebSocketManager of the shard + * @type {WebSocketManager} + */ + this.manager = manager; + + /** + * The shard's id + * @type {number} + */ + this.id = id; + + /** + * The current status of the shard + * @type {Status} + */ + this.status = Status.Idle; + + /** + * The sequence of the shard after close + * @type {number} + * @private + */ + this.closeSequence = 0; + + /** + * The previous heartbeat ping of the shard + * @type {number} + */ + this.ping = -1; + + /** + * The last time a ping was sent (a timestamp) + * @type {number} + */ + this.lastPingTimestamp = -1; + + /** + * A set of guild ids this shard expects to receive + * @name WebSocketShard#expectedGuilds + * @type {?Set<string>} + * @private + */ + Object.defineProperty(this, 'expectedGuilds', { value: null, writable: true }); + + /** + * The ready timeout + * @name WebSocketShard#readyTimeout + * @type {?NodeJS.Timeout} + * @private + */ + Object.defineProperty(this, 'readyTimeout', { value: null, writable: true }); + + /** + * @external SessionInfo + * @see {@link https://discord.js.org/docs/packages/ws/stable/SessionInfo:Interface} + */ + + /** + * The session info used by `@discordjs/ws` package. + * @name WebSocketShard#sessionInfo + * @type {?SessionInfo} + * @private + */ + Object.defineProperty(this, 'sessionInfo', { value: null, writable: true }); + } + + /** + * Emits a debug event. + * @param {string} message The debug message + * @private + */ + debug(message) { + this.manager.debug(message, this.id); + } + + /** + * @external CloseEvent + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent} + */ + + /** + * This method is responsible to emit close event for this shard. + * This method helps the shard reconnect. + * @param {CloseEvent} [event] Close event that was received + * @deprecated + */ + emitClose( + event = { + code: 1011, + reason: 'INTERNAL_ERROR', + wasClean: false, + }, + ) { + this.debug(`[CLOSE] + Event Code: ${event.code} + Clean : ${event.wasClean} + Reason : ${event.reason ?? 'No reason received'}`); + /** + * Emitted when a shard's WebSocket closes. + * @private + * @event WebSocketShard#close + * @param {CloseEvent} event The received event + */ + this.emit(WebSocketShardEvents.Close, event); + } + + /** + * Called when the shard receives the READY payload. + * @param {Object} packet The received packet + * @private + */ + onReadyPacket(packet) { + if (!packet) { + this.debug(`Received broken packet: '${packet}'.`); + return; + } + + /** + * Emitted when the shard receives the READY payload and is now waiting for guilds + * @event WebSocketShard#ready + */ + this.emit(WebSocketShardEvents.Ready); + + this.expectedGuilds = new Set(packet.guilds.map(d => d.id)); + this.status = Status.WaitingForGuilds; + } + + /** + * Called when a GuildCreate or GuildDelete for this shard was sent after READY payload was received, + * but before we emitted the READY event. + * @param {Snowflake} guildId the id of the Guild sent in the payload + * @private + */ + gotGuild(guildId) { + this.expectedGuilds.delete(guildId); + this.checkReady(); + } + + /** + * Checks if the shard can be marked as ready + * @private + */ + checkReady() { + // Step 0. Clear the ready timeout, if it exists + if (this.readyTimeout) { + clearTimeout(this.readyTimeout); + this.readyTimeout = null; + } + // Step 1. If we don't have any other guilds pending, we are ready + if (!this.expectedGuilds.size) { + this.debug('Shard received all its guilds. Marking as fully ready.'); + this.status = Status.Ready; + + /** + * Emitted when the shard is fully ready. + * This event is emitted if: + * * all guilds were received by this shard + * * the ready timeout expired, and some guilds are unavailable + * @event WebSocketShard#allReady + * @param {?Set<string>} unavailableGuilds Set of unavailable guilds, if any + */ + this.emit(WebSocketShardEvents.AllReady); + return; + } + const hasGuildsIntent = this.manager.client.options.intents.has(GatewayIntentBits.Guilds); + // Step 2. Create a timeout that will mark the shard as ready if there are still unavailable guilds + // * The timeout is 15 seconds by default + // * This can be optionally changed in the client options via the `waitGuildTimeout` option + // * a timeout time of zero will skip this timeout, which potentially could cause the Client to miss guilds. + + const { waitGuildTimeout } = this.manager.client.options; + + this.readyTimeout = setTimeout( + () => { + this.debug( + `Shard ${hasGuildsIntent ? 'did' : 'will'} not receive any more guild packets` + + `${hasGuildsIntent ? ` in ${waitGuildTimeout} ms` : ''}.\nUnavailable guild count: ${ + this.expectedGuilds.size + }`, + ); + + this.readyTimeout = null; + this.status = Status.Ready; + + this.emit(WebSocketShardEvents.AllReady, this.expectedGuilds); + }, + hasGuildsIntent ? waitGuildTimeout : 0, + ).unref(); + } + + /** + * Adds a packet to the queue to be sent to the gateway. + * <warn>If you use this method, make sure you understand that you need to provide + * a full [Payload](https://discord.com/developers/docs/topics/gateway#commands-and-events-gateway-commands). + * Do not use this method if you don't know what you're doing.</warn> + * @param {Object} data The full packet to send + * @param {boolean} [important=false] If this packet should be added first in queue + * <warn>This parameter is **deprecated**. Important payloads are determined by their opcode instead.</warn> + */ + send(data, important = false) { + if (important && !deprecationEmittedForImportant) { + process.emitWarning( + 'Sending important payloads explicitly is deprecated. They are determined by their opcode implicitly now.', + 'DeprecationWarning', + ); + deprecationEmittedForImportant = true; + } + this.manager._ws.send(this.id, data); + } +} + +module.exports = WebSocketShard; diff --git a/node_modules/discord.js/src/client/websocket/handlers/APPLICATION_COMMAND_PERMISSIONS_UPDATE.js b/node_modules/discord.js/src/client/websocket/handlers/APPLICATION_COMMAND_PERMISSIONS_UPDATE.js new file mode 100644 index 0000000..73d4ec4 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/APPLICATION_COMMAND_PERMISSIONS_UPDATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.ApplicationCommandPermissionsUpdate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/AUTO_MODERATION_ACTION_EXECUTION.js b/node_modules/discord.js/src/client/websocket/handlers/AUTO_MODERATION_ACTION_EXECUTION.js new file mode 100644 index 0000000..22463b6 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/AUTO_MODERATION_ACTION_EXECUTION.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.AutoModerationActionExecution.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/AUTO_MODERATION_RULE_CREATE.js b/node_modules/discord.js/src/client/websocket/handlers/AUTO_MODERATION_RULE_CREATE.js new file mode 100644 index 0000000..af64b9c --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/AUTO_MODERATION_RULE_CREATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.AutoModerationRuleCreate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/AUTO_MODERATION_RULE_DELETE.js b/node_modules/discord.js/src/client/websocket/handlers/AUTO_MODERATION_RULE_DELETE.js new file mode 100644 index 0000000..56ec504 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/AUTO_MODERATION_RULE_DELETE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.AutoModerationRuleDelete.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/AUTO_MODERATION_RULE_UPDATE.js b/node_modules/discord.js/src/client/websocket/handlers/AUTO_MODERATION_RULE_UPDATE.js new file mode 100644 index 0000000..3caf6ba --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/AUTO_MODERATION_RULE_UPDATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.AutoModerationRuleUpdate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/CHANNEL_CREATE.js b/node_modules/discord.js/src/client/websocket/handlers/CHANNEL_CREATE.js new file mode 100644 index 0000000..d6d560d --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/CHANNEL_CREATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.ChannelCreate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/CHANNEL_DELETE.js b/node_modules/discord.js/src/client/websocket/handlers/CHANNEL_DELETE.js new file mode 100644 index 0000000..cb9f3d8 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/CHANNEL_DELETE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.ChannelDelete.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/CHANNEL_PINS_UPDATE.js b/node_modules/discord.js/src/client/websocket/handlers/CHANNEL_PINS_UPDATE.js new file mode 100644 index 0000000..c46e527 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/CHANNEL_PINS_UPDATE.js @@ -0,0 +1,22 @@ +'use strict'; + +const Events = require('../../../util/Events'); + +module.exports = (client, { d: data }) => { + const channel = client.channels.cache.get(data.channel_id); + const time = data.last_pin_timestamp ? Date.parse(data.last_pin_timestamp) : null; + + if (channel) { + // Discord sends null for last_pin_timestamp if the last pinned message was removed + channel.lastPinTimestamp = time; + + /** + * Emitted whenever the pins of a channel are updated. Due to the nature of the WebSocket event, + * not much information can be provided easily here - you need to manually check the pins yourself. + * @event Client#channelPinsUpdate + * @param {TextBasedChannels} channel The channel that the pins update occurred in + * @param {Date} time The time of the pins update + */ + client.emit(Events.ChannelPinsUpdate, channel, time); + } +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/CHANNEL_UPDATE.js b/node_modules/discord.js/src/client/websocket/handlers/CHANNEL_UPDATE.js new file mode 100644 index 0000000..8f35121 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/CHANNEL_UPDATE.js @@ -0,0 +1,16 @@ +'use strict'; + +const Events = require('../../../util/Events'); + +module.exports = (client, packet) => { + const { old, updated } = client.actions.ChannelUpdate.handle(packet.d); + if (old && updated) { + /** + * Emitted whenever a channel is updated - e.g. name change, topic change, channel type change. + * @event Client#channelUpdate + * @param {DMChannel|GuildChannel} oldChannel The channel before the update + * @param {DMChannel|GuildChannel} newChannel The channel after the update + */ + client.emit(Events.ChannelUpdate, old, updated); + } +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/GUILD_AUDIT_LOG_ENTRY_CREATE.js b/node_modules/discord.js/src/client/websocket/handlers/GUILD_AUDIT_LOG_ENTRY_CREATE.js new file mode 100644 index 0000000..8623141 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/GUILD_AUDIT_LOG_ENTRY_CREATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.GuildAuditLogEntryCreate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/GUILD_BAN_ADD.js b/node_modules/discord.js/src/client/websocket/handlers/GUILD_BAN_ADD.js new file mode 100644 index 0000000..d8dc0f9 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/GUILD_BAN_ADD.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.GuildBanAdd.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/GUILD_BAN_REMOVE.js b/node_modules/discord.js/src/client/websocket/handlers/GUILD_BAN_REMOVE.js new file mode 100644 index 0000000..8389e46 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/GUILD_BAN_REMOVE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.GuildBanRemove.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/GUILD_CREATE.js b/node_modules/discord.js/src/client/websocket/handlers/GUILD_CREATE.js new file mode 100644 index 0000000..141f0ab --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/GUILD_CREATE.js @@ -0,0 +1,33 @@ +'use strict'; + +const Events = require('../../../util/Events'); +const Status = require('../../../util/Status'); + +module.exports = (client, { d: data }, shard) => { + let guild = client.guilds.cache.get(data.id); + if (guild) { + if (!guild.available && !data.unavailable) { + // A newly available guild + guild._patch(data); + + /** + * Emitted whenever a guild becomes available. + * @event Client#guildAvailable + * @param {Guild} guild The guild that became available + */ + client.emit(Events.GuildAvailable, guild); + } + } else { + // A new guild + data.shardId = shard.id; + guild = client.guilds._add(data); + if (client.ws.status === Status.Ready) { + /** + * Emitted whenever the client joins a guild. + * @event Client#guildCreate + * @param {Guild} guild The created guild + */ + client.emit(Events.GuildCreate, guild); + } + } +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/GUILD_DELETE.js b/node_modules/discord.js/src/client/websocket/handlers/GUILD_DELETE.js new file mode 100644 index 0000000..27a3256 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/GUILD_DELETE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.GuildDelete.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/GUILD_EMOJIS_UPDATE.js b/node_modules/discord.js/src/client/websocket/handlers/GUILD_EMOJIS_UPDATE.js new file mode 100644 index 0000000..e23b671 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/GUILD_EMOJIS_UPDATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.GuildEmojisUpdate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/GUILD_INTEGRATIONS_UPDATE.js b/node_modules/discord.js/src/client/websocket/handlers/GUILD_INTEGRATIONS_UPDATE.js new file mode 100644 index 0000000..e90a72c --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/GUILD_INTEGRATIONS_UPDATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.GuildIntegrationsUpdate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/GUILD_MEMBERS_CHUNK.js b/node_modules/discord.js/src/client/websocket/handlers/GUILD_MEMBERS_CHUNK.js new file mode 100644 index 0000000..2f61a1e --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/GUILD_MEMBERS_CHUNK.js @@ -0,0 +1,39 @@ +'use strict'; + +const { Collection } = require('@discordjs/collection'); +const Events = require('../../../util/Events'); + +module.exports = (client, { d: data }) => { + const guild = client.guilds.cache.get(data.guild_id); + if (!guild) return; + const members = new Collection(); + + for (const member of data.members) members.set(member.user.id, guild.members._add(member)); + if (data.presences) { + for (const presence of data.presences) guild.presences._add(Object.assign(presence, { guild })); + } + + /** + * Represents the properties of a guild members chunk + * @typedef {Object} GuildMembersChunk + * @property {number} index Index of the received chunk + * @property {number} count Number of chunks the client should receive + * @property {Array<*>} notFound An array of whatever could not be found + * when using {@link GatewayOpcodes.RequestGuildMembers} + * @property {?string} nonce Nonce for this chunk + */ + + /** + * Emitted whenever a chunk of guild members is received (all members come from the same guild). + * @event Client#guildMembersChunk + * @param {Collection<Snowflake, GuildMember>} members The members in the chunk + * @param {Guild} guild The guild related to the member chunk + * @param {GuildMembersChunk} chunk Properties of the received chunk + */ + client.emit(Events.GuildMembersChunk, members, guild, { + index: data.chunk_index, + count: data.chunk_count, + notFound: data.not_found, + nonce: data.nonce, + }); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/GUILD_MEMBER_ADD.js b/node_modules/discord.js/src/client/websocket/handlers/GUILD_MEMBER_ADD.js new file mode 100644 index 0000000..fece5d7 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/GUILD_MEMBER_ADD.js @@ -0,0 +1,20 @@ +'use strict'; + +const Events = require('../../../util/Events'); +const Status = require('../../../util/Status'); + +module.exports = (client, { d: data }, shard) => { + const guild = client.guilds.cache.get(data.guild_id); + if (guild) { + guild.memberCount++; + const member = guild.members._add(data); + if (shard.status === Status.Ready) { + /** + * Emitted whenever a user joins a guild. + * @event Client#guildMemberAdd + * @param {GuildMember} member The member that has joined a guild + */ + client.emit(Events.GuildMemberAdd, member); + } + } +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/GUILD_MEMBER_REMOVE.js b/node_modules/discord.js/src/client/websocket/handlers/GUILD_MEMBER_REMOVE.js new file mode 100644 index 0000000..72432af --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/GUILD_MEMBER_REMOVE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet, shard) => { + client.actions.GuildMemberRemove.handle(packet.d, shard); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/GUILD_MEMBER_UPDATE.js b/node_modules/discord.js/src/client/websocket/handlers/GUILD_MEMBER_UPDATE.js new file mode 100644 index 0000000..cafc6bd --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/GUILD_MEMBER_UPDATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet, shard) => { + client.actions.GuildMemberUpdate.handle(packet.d, shard); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/GUILD_ROLE_CREATE.js b/node_modules/discord.js/src/client/websocket/handlers/GUILD_ROLE_CREATE.js new file mode 100644 index 0000000..da9e7bc --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/GUILD_ROLE_CREATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.GuildRoleCreate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/GUILD_ROLE_DELETE.js b/node_modules/discord.js/src/client/websocket/handlers/GUILD_ROLE_DELETE.js new file mode 100644 index 0000000..cdc6353 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/GUILD_ROLE_DELETE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.GuildRoleDelete.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/GUILD_ROLE_UPDATE.js b/node_modules/discord.js/src/client/websocket/handlers/GUILD_ROLE_UPDATE.js new file mode 100644 index 0000000..3a9b62e --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/GUILD_ROLE_UPDATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.GuildRoleUpdate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_CREATE.js b/node_modules/discord.js/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_CREATE.js new file mode 100644 index 0000000..04ff2df --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_CREATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.GuildScheduledEventCreate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_DELETE.js b/node_modules/discord.js/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_DELETE.js new file mode 100644 index 0000000..b660c09 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_DELETE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.GuildScheduledEventDelete.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_UPDATE.js b/node_modules/discord.js/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_UPDATE.js new file mode 100644 index 0000000..0064708 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_UPDATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.GuildScheduledEventUpdate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_ADD.js b/node_modules/discord.js/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_ADD.js new file mode 100644 index 0000000..d5adca2 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_ADD.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.GuildScheduledEventUserAdd.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_REMOVE.js b/node_modules/discord.js/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_REMOVE.js new file mode 100644 index 0000000..114df68 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_REMOVE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.GuildScheduledEventUserRemove.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/GUILD_STICKERS_UPDATE.js b/node_modules/discord.js/src/client/websocket/handlers/GUILD_STICKERS_UPDATE.js new file mode 100644 index 0000000..e3aba61 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/GUILD_STICKERS_UPDATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.GuildStickersUpdate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/GUILD_UPDATE.js b/node_modules/discord.js/src/client/websocket/handlers/GUILD_UPDATE.js new file mode 100644 index 0000000..fd0012a --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/GUILD_UPDATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.GuildUpdate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/INTERACTION_CREATE.js b/node_modules/discord.js/src/client/websocket/handlers/INTERACTION_CREATE.js new file mode 100644 index 0000000..5bf30fc --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/INTERACTION_CREATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.InteractionCreate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/INVITE_CREATE.js b/node_modules/discord.js/src/client/websocket/handlers/INVITE_CREATE.js new file mode 100644 index 0000000..50a2e72 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/INVITE_CREATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.InviteCreate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/INVITE_DELETE.js b/node_modules/discord.js/src/client/websocket/handlers/INVITE_DELETE.js new file mode 100644 index 0000000..5971852 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/INVITE_DELETE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.InviteDelete.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_CREATE.js b/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_CREATE.js new file mode 100644 index 0000000..c9b79a8 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_CREATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.MessageCreate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_DELETE.js b/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_DELETE.js new file mode 100644 index 0000000..85ae2bc --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_DELETE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.MessageDelete.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_DELETE_BULK.js b/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_DELETE_BULK.js new file mode 100644 index 0000000..fbcf80f --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_DELETE_BULK.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.MessageDeleteBulk.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_REACTION_ADD.js b/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_REACTION_ADD.js new file mode 100644 index 0000000..e219b4a --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_REACTION_ADD.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.MessageReactionAdd.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE.js b/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE.js new file mode 100644 index 0000000..2980e69 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.MessageReactionRemove.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_ALL.js b/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_ALL.js new file mode 100644 index 0000000..ead80f7 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_ALL.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.MessageReactionRemoveAll.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_EMOJI.js b/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_EMOJI.js new file mode 100644 index 0000000..579444c --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_EMOJI.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.MessageReactionRemoveEmoji.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_UPDATE.js b/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_UPDATE.js new file mode 100644 index 0000000..c2a470b --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/MESSAGE_UPDATE.js @@ -0,0 +1,16 @@ +'use strict'; + +const Events = require('../../../util/Events'); + +module.exports = (client, packet) => { + const { old, updated } = client.actions.MessageUpdate.handle(packet.d); + if (old && updated) { + /** + * Emitted whenever a message is updated - e.g. embed or content change. + * @event Client#messageUpdate + * @param {Message} oldMessage The message before the update + * @param {Message} newMessage The message after the update + */ + client.emit(Events.MessageUpdate, old, updated); + } +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/PRESENCE_UPDATE.js b/node_modules/discord.js/src/client/websocket/handlers/PRESENCE_UPDATE.js new file mode 100644 index 0000000..bde3629 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/PRESENCE_UPDATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.PresenceUpdate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/READY.js b/node_modules/discord.js/src/client/websocket/handlers/READY.js new file mode 100644 index 0000000..82da01c --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/READY.js @@ -0,0 +1,27 @@ +'use strict'; + +const ClientApplication = require('../../../structures/ClientApplication'); +let ClientUser; + +module.exports = (client, { d: data }, shard) => { + if (client.user) { + client.user._patch(data.user); + } else { + ClientUser ??= require('../../../structures/ClientUser'); + client.user = new ClientUser(client, data.user); + client.users.cache.set(client.user.id, client.user); + } + + for (const guild of data.guilds) { + guild.shardId = shard.id; + client.guilds._add(guild); + } + + if (client.application) { + client.application._patch(data.application); + } else { + client.application = new ClientApplication(client, data.application); + } + + shard.checkReady(); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/RESUMED.js b/node_modules/discord.js/src/client/websocket/handlers/RESUMED.js new file mode 100644 index 0000000..27ed7dd --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/RESUMED.js @@ -0,0 +1,14 @@ +'use strict'; + +const Events = require('../../../util/Events'); + +module.exports = (client, packet, shard) => { + const replayed = shard.sessionInfo.sequence - shard.closeSequence; + /** + * Emitted when a shard resumes successfully. + * @event Client#shardResume + * @param {number} id The shard id that resumed + * @param {number} replayedEvents The amount of replayed events + */ + client.emit(Events.ShardResume, shard.id, replayed); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/STAGE_INSTANCE_CREATE.js b/node_modules/discord.js/src/client/websocket/handlers/STAGE_INSTANCE_CREATE.js new file mode 100644 index 0000000..77ae2ff --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/STAGE_INSTANCE_CREATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.StageInstanceCreate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/STAGE_INSTANCE_DELETE.js b/node_modules/discord.js/src/client/websocket/handlers/STAGE_INSTANCE_DELETE.js new file mode 100644 index 0000000..e2bb627 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/STAGE_INSTANCE_DELETE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.StageInstanceDelete.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/STAGE_INSTANCE_UPDATE.js b/node_modules/discord.js/src/client/websocket/handlers/STAGE_INSTANCE_UPDATE.js new file mode 100644 index 0000000..fabc84a --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/STAGE_INSTANCE_UPDATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.StageInstanceUpdate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/THREAD_CREATE.js b/node_modules/discord.js/src/client/websocket/handlers/THREAD_CREATE.js new file mode 100644 index 0000000..d92cab0 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/THREAD_CREATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.ThreadCreate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/THREAD_DELETE.js b/node_modules/discord.js/src/client/websocket/handlers/THREAD_DELETE.js new file mode 100644 index 0000000..1140a08 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/THREAD_DELETE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.ThreadDelete.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/THREAD_LIST_SYNC.js b/node_modules/discord.js/src/client/websocket/handlers/THREAD_LIST_SYNC.js new file mode 100644 index 0000000..17b173a --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/THREAD_LIST_SYNC.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.ThreadListSync.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/THREAD_MEMBERS_UPDATE.js b/node_modules/discord.js/src/client/websocket/handlers/THREAD_MEMBERS_UPDATE.js new file mode 100644 index 0000000..f3c7a73 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/THREAD_MEMBERS_UPDATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.ThreadMembersUpdate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/THREAD_MEMBER_UPDATE.js b/node_modules/discord.js/src/client/websocket/handlers/THREAD_MEMBER_UPDATE.js new file mode 100644 index 0000000..a111b0a --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/THREAD_MEMBER_UPDATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.ThreadMemberUpdate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/THREAD_UPDATE.js b/node_modules/discord.js/src/client/websocket/handlers/THREAD_UPDATE.js new file mode 100644 index 0000000..481dcd4 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/THREAD_UPDATE.js @@ -0,0 +1,16 @@ +'use strict'; + +const Events = require('../../../util/Events'); + +module.exports = (client, packet) => { + const { old, updated } = client.actions.ChannelUpdate.handle(packet.d); + if (old && updated) { + /** + * Emitted whenever a thread is updated - e.g. name change, archive state change, locked state change. + * @event Client#threadUpdate + * @param {ThreadChannel} oldThread The thread before the update + * @param {ThreadChannel} newThread The thread after the update + */ + client.emit(Events.ThreadUpdate, old, updated); + } +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/TYPING_START.js b/node_modules/discord.js/src/client/websocket/handlers/TYPING_START.js new file mode 100644 index 0000000..9a56a54 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/TYPING_START.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.TypingStart.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/USER_UPDATE.js b/node_modules/discord.js/src/client/websocket/handlers/USER_UPDATE.js new file mode 100644 index 0000000..a02bf58 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/USER_UPDATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.UserUpdate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/VOICE_SERVER_UPDATE.js b/node_modules/discord.js/src/client/websocket/handlers/VOICE_SERVER_UPDATE.js new file mode 100644 index 0000000..f9cf534 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/VOICE_SERVER_UPDATE.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = (client, packet) => { + client.emit('debug', `[VOICE] received voice server: ${JSON.stringify(packet)}`); + client.voice.onVoiceServer(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/VOICE_STATE_UPDATE.js b/node_modules/discord.js/src/client/websocket/handlers/VOICE_STATE_UPDATE.js new file mode 100644 index 0000000..dbff6ea --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/VOICE_STATE_UPDATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.VoiceStateUpdate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/WEBHOOKS_UPDATE.js b/node_modules/discord.js/src/client/websocket/handlers/WEBHOOKS_UPDATE.js new file mode 100644 index 0000000..46cacee --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/WEBHOOKS_UPDATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, packet) => { + client.actions.WebhooksUpdate.handle(packet.d); +}; diff --git a/node_modules/discord.js/src/client/websocket/handlers/index.js b/node_modules/discord.js/src/client/websocket/handlers/index.js new file mode 100644 index 0000000..f175dbe --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/handlers/index.js @@ -0,0 +1,64 @@ +'use strict'; + +const handlers = Object.fromEntries([ + ['APPLICATION_COMMAND_PERMISSIONS_UPDATE', require('./APPLICATION_COMMAND_PERMISSIONS_UPDATE')], + ['AUTO_MODERATION_ACTION_EXECUTION', require('./AUTO_MODERATION_ACTION_EXECUTION')], + ['AUTO_MODERATION_RULE_CREATE', require('./AUTO_MODERATION_RULE_CREATE')], + ['AUTO_MODERATION_RULE_DELETE', require('./AUTO_MODERATION_RULE_DELETE')], + ['AUTO_MODERATION_RULE_UPDATE', require('./AUTO_MODERATION_RULE_UPDATE')], + ['CHANNEL_CREATE', require('./CHANNEL_CREATE')], + ['CHANNEL_DELETE', require('./CHANNEL_DELETE')], + ['CHANNEL_PINS_UPDATE', require('./CHANNEL_PINS_UPDATE')], + ['CHANNEL_UPDATE', require('./CHANNEL_UPDATE')], + ['GUILD_AUDIT_LOG_ENTRY_CREATE', require('./GUILD_AUDIT_LOG_ENTRY_CREATE')], + ['GUILD_BAN_ADD', require('./GUILD_BAN_ADD')], + ['GUILD_BAN_REMOVE', require('./GUILD_BAN_REMOVE')], + ['GUILD_CREATE', require('./GUILD_CREATE')], + ['GUILD_DELETE', require('./GUILD_DELETE')], + ['GUILD_EMOJIS_UPDATE', require('./GUILD_EMOJIS_UPDATE')], + ['GUILD_INTEGRATIONS_UPDATE', require('./GUILD_INTEGRATIONS_UPDATE')], + ['GUILD_MEMBERS_CHUNK', require('./GUILD_MEMBERS_CHUNK')], + ['GUILD_MEMBER_ADD', require('./GUILD_MEMBER_ADD')], + ['GUILD_MEMBER_REMOVE', require('./GUILD_MEMBER_REMOVE')], + ['GUILD_MEMBER_UPDATE', require('./GUILD_MEMBER_UPDATE')], + ['GUILD_ROLE_CREATE', require('./GUILD_ROLE_CREATE')], + ['GUILD_ROLE_DELETE', require('./GUILD_ROLE_DELETE')], + ['GUILD_ROLE_UPDATE', require('./GUILD_ROLE_UPDATE')], + ['GUILD_SCHEDULED_EVENT_CREATE', require('./GUILD_SCHEDULED_EVENT_CREATE')], + ['GUILD_SCHEDULED_EVENT_DELETE', require('./GUILD_SCHEDULED_EVENT_DELETE')], + ['GUILD_SCHEDULED_EVENT_UPDATE', require('./GUILD_SCHEDULED_EVENT_UPDATE')], + ['GUILD_SCHEDULED_EVENT_USER_ADD', require('./GUILD_SCHEDULED_EVENT_USER_ADD')], + ['GUILD_SCHEDULED_EVENT_USER_REMOVE', require('./GUILD_SCHEDULED_EVENT_USER_REMOVE')], + ['GUILD_STICKERS_UPDATE', require('./GUILD_STICKERS_UPDATE')], + ['GUILD_UPDATE', require('./GUILD_UPDATE')], + ['INTERACTION_CREATE', require('./INTERACTION_CREATE')], + ['INVITE_CREATE', require('./INVITE_CREATE')], + ['INVITE_DELETE', require('./INVITE_DELETE')], + ['MESSAGE_CREATE', require('./MESSAGE_CREATE')], + ['MESSAGE_DELETE', require('./MESSAGE_DELETE')], + ['MESSAGE_DELETE_BULK', require('./MESSAGE_DELETE_BULK')], + ['MESSAGE_REACTION_ADD', require('./MESSAGE_REACTION_ADD')], + ['MESSAGE_REACTION_REMOVE', require('./MESSAGE_REACTION_REMOVE')], + ['MESSAGE_REACTION_REMOVE_ALL', require('./MESSAGE_REACTION_REMOVE_ALL')], + ['MESSAGE_REACTION_REMOVE_EMOJI', require('./MESSAGE_REACTION_REMOVE_EMOJI')], + ['MESSAGE_UPDATE', require('./MESSAGE_UPDATE')], + ['PRESENCE_UPDATE', require('./PRESENCE_UPDATE')], + ['READY', require('./READY')], + ['RESUMED', require('./RESUMED')], + ['STAGE_INSTANCE_CREATE', require('./STAGE_INSTANCE_CREATE')], + ['STAGE_INSTANCE_DELETE', require('./STAGE_INSTANCE_DELETE')], + ['STAGE_INSTANCE_UPDATE', require('./STAGE_INSTANCE_UPDATE')], + ['THREAD_CREATE', require('./THREAD_CREATE')], + ['THREAD_DELETE', require('./THREAD_DELETE')], + ['THREAD_LIST_SYNC', require('./THREAD_LIST_SYNC')], + ['THREAD_MEMBERS_UPDATE', require('./THREAD_MEMBERS_UPDATE')], + ['THREAD_MEMBER_UPDATE', require('./THREAD_MEMBER_UPDATE')], + ['THREAD_UPDATE', require('./THREAD_UPDATE')], + ['TYPING_START', require('./TYPING_START')], + ['USER_UPDATE', require('./USER_UPDATE')], + ['VOICE_SERVER_UPDATE', require('./VOICE_SERVER_UPDATE')], + ['VOICE_STATE_UPDATE', require('./VOICE_STATE_UPDATE')], + ['WEBHOOKS_UPDATE', require('./WEBHOOKS_UPDATE')], +]); + +module.exports = handlers; |