commit
This commit is contained in:
parent
68f4b60012
commit
41ae7ff4bd
1010 changed files with 38622 additions and 17071 deletions
2818
node_modules/discord.js/CHANGELOG.md
generated
vendored
2818
node_modules/discord.js/CHANGELOG.md
generated
vendored
File diff suppressed because it is too large
Load diff
35
node_modules/discord.js/README.md
generated
vendored
35
node_modules/discord.js/README.md
generated
vendored
|
@ -13,6 +13,7 @@
|
|||
</p>
|
||||
<p>
|
||||
<a href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"><img src="https://raw.githubusercontent.com/discordjs/discord.js/main/.github/powered-by-vercel.svg" alt="Vercel" /></a>
|
||||
<a href="https://www.cloudflare.com"><img src="https://raw.githubusercontent.com/discordjs/discord.js/main/.github/powered-by-workers.png" alt="Cloudflare Workers" height="44" /></a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
@ -30,7 +31,7 @@ discord.js is a powerful [Node.js](https://nodejs.org) module that allows you to
|
|||
|
||||
**Node.js 16.9.0 or newer is required.**
|
||||
|
||||
```sh-session
|
||||
```sh
|
||||
npm install discord.js
|
||||
yarn add discord.js
|
||||
pnpm add discord.js
|
||||
|
@ -39,7 +40,6 @@ pnpm add discord.js
|
|||
### Optional packages
|
||||
|
||||
- [zlib-sync](https://www.npmjs.com/package/zlib-sync) for WebSocket data compression and inflation (`npm install zlib-sync`)
|
||||
- [erlpack](https://github.com/discord/erlpack) for significantly faster WebSocket data (de)serialisation (`npm install discord/erlpack`)
|
||||
- [bufferutil](https://www.npmjs.com/package/bufferutil) for a much faster WebSocket connection (`npm install bufferutil`)
|
||||
- [utf-8-validate](https://www.npmjs.com/package/utf-8-validate) in combination with `bufferutil` for much faster WebSocket processing (`npm install utf-8-validate`)
|
||||
- [@discordjs/voice](https://www.npmjs.com/package/@discordjs/voice) for interacting with the Discord Voice API (`npm install @discordjs/voice`)
|
||||
|
@ -48,7 +48,7 @@ pnpm add discord.js
|
|||
|
||||
Install discord.js:
|
||||
|
||||
```sh-session
|
||||
```sh
|
||||
npm install discord.js
|
||||
yarn add discord.js
|
||||
pnpm add discord.js
|
||||
|
@ -57,7 +57,7 @@ pnpm add discord.js
|
|||
Register a slash command against the Discord API:
|
||||
|
||||
```js
|
||||
const { REST, Routes } = require('discord.js');
|
||||
import { REST, Routes } from 'discord.js';
|
||||
|
||||
const commands = [
|
||||
{
|
||||
|
@ -68,23 +68,21 @@ const commands = [
|
|||
|
||||
const rest = new REST({ version: '10' }).setToken(TOKEN);
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
console.log('Started refreshing application (/) commands.');
|
||||
try {
|
||||
console.log('Started refreshing application (/) commands.');
|
||||
|
||||
await rest.put(Routes.applicationCommands(CLIENT_ID), { body: commands });
|
||||
await rest.put(Routes.applicationCommands(CLIENT_ID), { body: commands });
|
||||
|
||||
console.log('Successfully reloaded application (/) commands.');
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
})();
|
||||
console.log('Successfully reloaded application (/) commands.');
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
```
|
||||
|
||||
Afterwards we can create a quite simple example bot:
|
||||
|
||||
```js
|
||||
const { Client, GatewayIntentBits } = require('discord.js');
|
||||
import { Client, GatewayIntentBits } from 'discord.js';
|
||||
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
|
||||
|
||||
client.on('ready', () => {
|
||||
|
@ -107,7 +105,7 @@ client.login(TOKEN);
|
|||
- [Website][website] ([source][website-source])
|
||||
- [Documentation][documentation]
|
||||
- [Guide][guide] ([source][guide-source])
|
||||
See also the [Update Guide][guide-update], including updated and removed items in the library.
|
||||
Also see the v13 to v14 [Update Guide][guide-update], which includes updated and removed items from the library.
|
||||
- [discord.js Discord server][discord]
|
||||
- [Discord API Discord server][discord-api]
|
||||
- [GitHub][source]
|
||||
|
@ -126,12 +124,11 @@ See [the contribution guide][contributing] if you'd like to submit a PR.
|
|||
|
||||
## Help
|
||||
|
||||
If you don't understand something in the documentation, you are experiencing problems, or you just need a gentle
|
||||
nudge in the right direction, please don't hesitate to join our official [discord.js Server][discord].
|
||||
If you don't understand something in the documentation, you are experiencing problems, or you just need a gentle nudge in the right direction, please don't hesitate to join our official [discord.js Server][discord].
|
||||
|
||||
[website]: https://discord.js.org/
|
||||
[website]: https://discord.js.org
|
||||
[website-source]: https://github.com/discordjs/discord.js/tree/main/apps/website
|
||||
[documentation]: https://discord.js.org/#/docs
|
||||
[documentation]: https://discord.js.org/docs/packages/discord.js/stable
|
||||
[guide]: https://discordjs.guide/
|
||||
[guide-source]: https://github.com/discordjs/guide
|
||||
[guide-update]: https://discordjs.guide/additional-info/changes-in-v14.html
|
||||
|
|
44
node_modules/discord.js/package.json
generated
vendored
44
node_modules/discord.js/package.json
generated
vendored
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "discord.js",
|
||||
"version": "14.7.1",
|
||||
"version": "14.11.0",
|
||||
"description": "A powerful library for interacting with the Discord API",
|
||||
"scripts": {
|
||||
"test": "yarn docs:test && yarn test:typescript",
|
||||
|
@ -42,38 +42,42 @@
|
|||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/discordjs/discord.js.git"
|
||||
"url": "https://github.com/discordjs/discord.js.git",
|
||||
"directory": "packages/discord.js"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/discordjs/discord.js/issues"
|
||||
},
|
||||
"homepage": "https://discord.js.org",
|
||||
"dependencies": {
|
||||
"@discordjs/builders": "^1.4.0",
|
||||
"@discordjs/collection": "^1.3.0",
|
||||
"@discordjs/rest": "^1.4.0",
|
||||
"@discordjs/util": "^0.1.0",
|
||||
"@sapphire/snowflake": "^3.2.2",
|
||||
"@types/ws": "^8.5.3",
|
||||
"discord-api-types": "^0.37.20",
|
||||
"@discordjs/builders": "^1.6.3",
|
||||
"@discordjs/collection": "^1.5.1",
|
||||
"@discordjs/formatters": "^0.3.1",
|
||||
"@discordjs/rest": "^1.7.1",
|
||||
"@discordjs/util": "^0.3.1",
|
||||
"@discordjs/ws": "^0.8.3",
|
||||
"@sapphire/snowflake": "^3.4.2",
|
||||
"@types/ws": "^8.5.4",
|
||||
"discord-api-types": "^0.37.41",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"lodash.snakecase": "^4.1.1",
|
||||
"tslib": "^2.4.1",
|
||||
"undici": "^5.13.0",
|
||||
"ws": "^8.11.0"
|
||||
"tslib": "^2.5.0",
|
||||
"undici": "^5.22.0",
|
||||
"ws": "^8.13.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@discordjs/docgen": "^0.12.1",
|
||||
"@favware/cliff-jumper": "^1.9.0",
|
||||
"@types/node": "16.18.3",
|
||||
"@favware/cliff-jumper": "^2.0.0",
|
||||
"@types/node": "16.18.25",
|
||||
"dtslint": "^4.2.1",
|
||||
"eslint": "^8.28.0",
|
||||
"eslint-formatter-pretty": "^4.1.0",
|
||||
"jest": "^29.3.1",
|
||||
"prettier": "^2.8.0",
|
||||
"tsd": "^0.24.1",
|
||||
"eslint": "^8.39.0",
|
||||
"eslint-formatter-pretty": "^5.0.0",
|
||||
"jest": "^29.5.0",
|
||||
"prettier": "^2.8.8",
|
||||
"tsd": "^0.28.1",
|
||||
"tslint": "^6.1.3",
|
||||
"typescript": "^4.9.3"
|
||||
"turbo": "^1.9.4-canary.9",
|
||||
"typescript": "^5.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.9.0"
|
||||
|
|
39
node_modules/discord.js/src/WebSocket.js
generated
vendored
39
node_modules/discord.js/src/WebSocket.js
generated
vendored
|
@ -1,39 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
let erlpack;
|
||||
const { Buffer } = require('node:buffer');
|
||||
|
||||
try {
|
||||
erlpack = require('erlpack');
|
||||
if (!erlpack.pack) erlpack = null;
|
||||
} catch {} // eslint-disable-line no-empty
|
||||
|
||||
exports.WebSocket = require('ws');
|
||||
|
||||
const ab = new TextDecoder();
|
||||
|
||||
exports.encoding = erlpack ? 'etf' : 'json';
|
||||
|
||||
exports.pack = erlpack ? erlpack.pack : JSON.stringify;
|
||||
|
||||
exports.unpack = (data, type) => {
|
||||
if (exports.encoding === 'json' || type === 'json') {
|
||||
if (typeof data !== 'string') {
|
||||
data = ab.decode(data);
|
||||
}
|
||||
return JSON.parse(data);
|
||||
}
|
||||
if (!Buffer.isBuffer(data)) data = Buffer.from(new Uint8Array(data));
|
||||
return erlpack.unpack(data);
|
||||
};
|
||||
|
||||
exports.create = (gateway, query = {}, ...args) => {
|
||||
const [g, q] = gateway.split('?');
|
||||
query.encoding = exports.encoding;
|
||||
query = new URLSearchParams(query);
|
||||
if (q) new URLSearchParams(q).forEach((v, k) => query.set(k, v));
|
||||
const ws = new exports.WebSocket(`${g}?${query}`, ...args);
|
||||
return ws;
|
||||
};
|
||||
|
||||
for (const state of ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED']) exports[state] = exports.WebSocket[state];
|
12
node_modules/discord.js/src/client/BaseClient.js
generated
vendored
12
node_modules/discord.js/src/client/BaseClient.js
generated
vendored
|
@ -22,7 +22,15 @@ class BaseClient extends EventEmitter {
|
|||
* The options the client was instantiated with
|
||||
* @type {ClientOptions}
|
||||
*/
|
||||
this.options = mergeDefault(Options.createDefault(), options);
|
||||
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
|
||||
|
@ -71,5 +79,5 @@ module.exports = BaseClient;
|
|||
|
||||
/**
|
||||
* @external REST
|
||||
* @see {@link https://discord.js.org/#/docs/rest/main/class/REST}
|
||||
* @see {@link https://discord.js.org/docs/packages/rest/stable/REST:Class}
|
||||
*/
|
||||
|
|
45
node_modules/discord.js/src/client/Client.js
generated
vendored
45
node_modules/discord.js/src/client/Client.js
generated
vendored
|
@ -307,7 +307,7 @@ class Client extends BaseClient {
|
|||
* .catch(console.error);
|
||||
*/
|
||||
async fetchWebhook(id, token) {
|
||||
const data = await this.rest.get(Routes.webhook(id, token), { auth: typeof token === 'undefined' });
|
||||
const data = await this.rest.get(Routes.webhook(id, token), { auth: token === undefined });
|
||||
return new Webhook(this, { token, ...data });
|
||||
}
|
||||
|
||||
|
@ -411,7 +411,7 @@ class Client extends BaseClient {
|
|||
if (!this.application) throw new DiscordjsError(ErrorCodes.ClientNotReady, 'generate an invite link');
|
||||
|
||||
const { scopes } = options;
|
||||
if (typeof scopes === 'undefined') {
|
||||
if (scopes === undefined) {
|
||||
throw new DiscordjsTypeError(ErrorCodes.InvalidMissingScopes);
|
||||
}
|
||||
if (!Array.isArray(scopes)) {
|
||||
|
@ -420,6 +420,9 @@ class Client extends BaseClient {
|
|||
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) {
|
||||
|
@ -485,7 +488,7 @@ class Client extends BaseClient {
|
|||
* @private
|
||||
*/
|
||||
_validateOptions(options = this.options) {
|
||||
if (typeof options.intents === 'undefined') {
|
||||
if (options.intents === undefined) {
|
||||
throw new DiscordjsTypeError(ErrorCodes.ClientMissingIntents);
|
||||
} else {
|
||||
options.intents = new IntentsBitField(options.intents).freeze();
|
||||
|
@ -512,11 +515,41 @@ class Client extends BaseClient {
|
|||
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.
|
||||
|
@ -544,15 +577,15 @@ module.exports = Client;
|
|||
|
||||
/**
|
||||
* @external Collection
|
||||
* @see {@link https://discord.js.org/#/docs/collection/main/class/Collection}
|
||||
* @see {@link https://discord.js.org/docs/packages/collection/stable/Collection:Class}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external ImageURLOptions
|
||||
* @see {@link https://discord.js.org/#/docs/rest/main/typedef/ImageURLOptions}
|
||||
* @see {@link https://discord.js.org/docs/packages/rest/stable/ImageURLOptions:Interface}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external BaseImageURLOptions
|
||||
* @see {@link https://discord.js.org/#/docs/rest/main/typedef/BaseImageURLOptions}
|
||||
* @see {@link https://discord.js.org/docs/packages/rest/stable/BaseImageURLOptions:Interface}
|
||||
*/
|
||||
|
|
4
node_modules/discord.js/src/client/WebhookClient.js
generated
vendored
4
node_modules/discord.js/src/client/WebhookClient.js
generated
vendored
|
@ -68,7 +68,7 @@ class WebhookClient extends BaseClient {
|
|||
/* eslint-disable no-empty-function, valid-jsdoc */
|
||||
/**
|
||||
* Sends a message with this webhook.
|
||||
* @param {string|MessagePayload|WebhookCreateMessageOptions} options The content for the reply
|
||||
* @param {string|MessagePayload|WebhookMessageCreateOptions} options The content for the reply
|
||||
* @returns {Promise<APIMessage>}
|
||||
*/
|
||||
send() {}
|
||||
|
@ -84,7 +84,7 @@ class WebhookClient extends BaseClient {
|
|||
/**
|
||||
* Edits a message that was sent by this webhook.
|
||||
* @param {MessageResolvable} message The message to edit
|
||||
* @param {string|MessagePayload|WebhookEditMessageOptions} options The options to provide
|
||||
* @param {string|MessagePayload|WebhookMessageEditOptions} options The options to provide
|
||||
* @returns {Promise<APIMessage>} Returns the message edited by this webhook
|
||||
*/
|
||||
editMessage() {}
|
||||
|
|
6
node_modules/discord.js/src/client/actions/Action.js
generated
vendored
6
node_modules/discord.js/src/client/actions/Action.js
generated
vendored
|
@ -34,7 +34,7 @@ class GenericAction {
|
|||
getChannel(data) {
|
||||
const id = data.channel_id ?? data.id;
|
||||
return (
|
||||
data.channel ??
|
||||
data[this.client.actions.injectedChannel] ??
|
||||
this.getPayload(
|
||||
{
|
||||
id,
|
||||
|
@ -51,7 +51,7 @@ class GenericAction {
|
|||
getMessage(data, channel, cache) {
|
||||
const id = data.message_id ?? data.id;
|
||||
return (
|
||||
data.message ??
|
||||
data[this.client.actions.injectedMessage] ??
|
||||
this.getPayload(
|
||||
{
|
||||
id,
|
||||
|
@ -86,7 +86,7 @@ class GenericAction {
|
|||
|
||||
getUser(data) {
|
||||
const id = data.user_id;
|
||||
return data.user ?? this.getPayload({ id }, this.client.users, id, Partials.User);
|
||||
return data[this.client.actions.injectedUser] ?? this.getPayload({ id }, this.client.users, id, Partials.User);
|
||||
}
|
||||
|
||||
getUserFromMember(data) {
|
||||
|
|
8
node_modules/discord.js/src/client/actions/ActionsManager.js
generated
vendored
8
node_modules/discord.js/src/client/actions/ActionsManager.js
generated
vendored
|
@ -1,6 +1,13 @@
|
|||
'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;
|
||||
|
||||
|
@ -12,6 +19,7 @@ class ActionsManager {
|
|||
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'));
|
||||
|
|
29
node_modules/discord.js/src/client/actions/GuildAuditLogEntryCreate.js
generated
vendored
Normal file
29
node_modules/discord.js/src/client/actions/GuildAuditLogEntryCreate.js
generated
vendored
Normal file
|
@ -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;
|
2
node_modules/discord.js/src/client/actions/InteractionCreate.js
generated
vendored
2
node_modules/discord.js/src/client/actions/InteractionCreate.js
generated
vendored
|
@ -20,7 +20,7 @@ class InteractionCreateAction extends Action {
|
|||
const client = this.client;
|
||||
|
||||
// Resolve and cache partial channels for Interaction#channel getter
|
||||
const channel = this.getChannel(data);
|
||||
const channel = data.channel && this.getChannel(data.channel);
|
||||
|
||||
// Do not emit this for interactions that cache messages that are non-text-based.
|
||||
let InteractionClass;
|
||||
|
|
3
node_modules/discord.js/src/client/actions/WebhooksUpdate.js
generated
vendored
3
node_modules/discord.js/src/client/actions/WebhooksUpdate.js
generated
vendored
|
@ -10,7 +10,8 @@ class WebhooksUpdate extends Action {
|
|||
/**
|
||||
* Emitted whenever a channel has its webhooks changed.
|
||||
* @event Client#webhookUpdate
|
||||
* @param {TextChannel|NewsChannel|VoiceChannel|ForumChannel} channel The channel that had a webhook update
|
||||
* @param {TextChannel|NewsChannel|VoiceChannel|StageChannel|ForumChannel} channel
|
||||
* The channel that had a webhook update
|
||||
*/
|
||||
if (channel) client.emit(Events.WebhooksUpdate, channel);
|
||||
}
|
||||
|
|
340
node_modules/discord.js/src/client/websocket/WebSocketManager.js
generated
vendored
340
node_modules/discord.js/src/client/websocket/WebSocketManager.js
generated
vendored
|
@ -1,10 +1,16 @@
|
|||
'use strict';
|
||||
|
||||
const EventEmitter = require('node:events');
|
||||
const process = require('node:process');
|
||||
const { setImmediate } = require('node:timers');
|
||||
const { setTimeout: sleep } = require('node:timers/promises');
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { GatewayCloseCodes, GatewayDispatchEvents, Routes } = require('discord-api-types/v10');
|
||||
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');
|
||||
|
@ -12,6 +18,12 @@ 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,
|
||||
|
@ -22,15 +34,17 @@ const BeforeReadyWhitelist = [
|
|||
GatewayDispatchEvents.GuildMemberRemove,
|
||||
];
|
||||
|
||||
const unrecoverableErrorCodeMap = {
|
||||
[GatewayCloseCodes.AuthenticationFailed]: ErrorCodes.TokenInvalid,
|
||||
[GatewayCloseCodes.InvalidShard]: ErrorCodes.ShardingInvalid,
|
||||
[GatewayCloseCodes.ShardingRequired]: ErrorCodes.ShardingRequired,
|
||||
[GatewayCloseCodes.InvalidIntents]: ErrorCodes.InvalidIntents,
|
||||
[GatewayCloseCodes.DisallowedIntents]: ErrorCodes.DisallowedIntents,
|
||||
};
|
||||
const WaitingForGuildEvents = [GatewayDispatchEvents.GuildCreate, GatewayDispatchEvents.GuildDelete];
|
||||
|
||||
const UNRESUMABLE_CLOSE_CODES = [1000, GatewayCloseCodes.AlreadyAuthenticated, GatewayCloseCodes.InvalidSeq];
|
||||
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.
|
||||
|
@ -56,27 +70,12 @@ class WebSocketManager extends EventEmitter {
|
|||
*/
|
||||
this.gateway = null;
|
||||
|
||||
/**
|
||||
* The amount of shards this manager handles
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.totalShards = this.client.options.shards.length;
|
||||
|
||||
/**
|
||||
* A collection of all shards this manager handles
|
||||
* @type {Collection<number, WebSocketShard>}
|
||||
*/
|
||||
this.shards = new Collection();
|
||||
|
||||
/**
|
||||
* An array of shards to be connected or that need to reconnect
|
||||
* @type {Set<WebSocketShard>}
|
||||
* @private
|
||||
* @name WebSocketManager#shardQueue
|
||||
*/
|
||||
Object.defineProperty(this, 'shardQueue', { value: new Set(), writable: true });
|
||||
|
||||
/**
|
||||
* An array of queued events before this WebSocketManager became ready
|
||||
* @type {Object[]}
|
||||
|
@ -99,11 +98,11 @@ class WebSocketManager extends EventEmitter {
|
|||
this.destroyed = false;
|
||||
|
||||
/**
|
||||
* If this manager is currently reconnecting one or multiple shards
|
||||
* @type {boolean}
|
||||
* The internal WebSocketManager from `@discordjs/ws`.
|
||||
* @type {WSWebSocketManager}
|
||||
* @private
|
||||
*/
|
||||
this.reconnecting = false;
|
||||
this._ws = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -119,11 +118,14 @@ class WebSocketManager extends EventEmitter {
|
|||
/**
|
||||
* Emits a debug message.
|
||||
* @param {string} message The debug message
|
||||
* @param {?WebSocketShard} [shard] The shard that emitted this message, if any
|
||||
* @param {?number} [shardId] The id of the shard that emitted this message, if any
|
||||
* @private
|
||||
*/
|
||||
debug(message, shard) {
|
||||
this.client.emit(Events.Debug, `[WS => ${shard ? `Shard ${shard.id}` : 'Manager'}] ${message}`);
|
||||
debug(message, shardId) {
|
||||
this.client.emit(
|
||||
Events.Debug,
|
||||
`[WS => ${typeof shardId === 'number' ? `Shard ${shardId}` : 'Manager'}] ${message}`,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -132,11 +134,37 @@ class WebSocketManager extends EventEmitter {
|
|||
*/
|
||||
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.buildStrategy) wsOptions.buildStrategy = ws.buildStrategy;
|
||||
this._ws = new WSWebSocketManager(wsOptions);
|
||||
this.attachEvents();
|
||||
}
|
||||
|
||||
const {
|
||||
url: gatewayURL,
|
||||
shards: recommendedShards,
|
||||
session_start_limit: sessionStartLimit,
|
||||
} = await this.client.rest.get(Routes.gatewayBot()).catch(error => {
|
||||
} = await this._ws.fetchGatewayInformation().catch(error => {
|
||||
throw error.status === 401 ? invalidToken : error;
|
||||
});
|
||||
|
||||
|
@ -152,156 +180,131 @@ class WebSocketManager extends EventEmitter {
|
|||
|
||||
this.gateway = `${gatewayURL}/`;
|
||||
|
||||
let { shards } = this.client.options;
|
||||
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);
|
||||
|
||||
if (shards === 'auto') {
|
||||
this.debug(`Using the recommended shard count provided by Discord: ${recommendedShards}`);
|
||||
this.totalShards = this.client.options.shardCount = recommendedShards;
|
||||
shards = this.client.options.shards = Array.from({ length: recommendedShards }, (_, i) => i);
|
||||
}
|
||||
|
||||
this.totalShards = shards.length;
|
||||
this.debug(`Spawning shards: ${shards.join(', ')}`);
|
||||
this.shardQueue = new Set(shards.map(id => new WebSocketShard(this, id)));
|
||||
|
||||
return this.createShards();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the creation of a shard.
|
||||
* @returns {Promise<boolean>}
|
||||
* @private
|
||||
*/
|
||||
async createShards() {
|
||||
// If we don't have any shards to handle, return
|
||||
if (!this.shardQueue.size) return false;
|
||||
|
||||
const [shard] = this.shardQueue;
|
||||
|
||||
this.shardQueue.delete(shard);
|
||||
|
||||
if (!shard.eventsAttached) {
|
||||
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);
|
||||
|
||||
if (!this.shardQueue.size) this.reconnecting = false;
|
||||
this.checkShardsReady();
|
||||
});
|
||||
|
||||
shard.on(WebSocketShardEvents.Close, event => {
|
||||
if (event.code === 1_000 ? this.destroyed : event.code in unrecoverableErrorCodeMap) {
|
||||
shard.on(WebSocketShardEvents.AllReady, unavailableGuilds => {
|
||||
/**
|
||||
* 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
|
||||
* 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.ShardDisconnect, event, shard.id);
|
||||
this.debug(GatewayCloseCodes[event.code], shard);
|
||||
return;
|
||||
}
|
||||
this.client.emit(Events.ShardReady, shard.id, unavailableGuilds);
|
||||
|
||||
if (UNRESUMABLE_CLOSE_CODES.includes(event.code)) {
|
||||
// These event codes cannot be resumed
|
||||
shard.sessionId = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, shard.id);
|
||||
|
||||
this.shardQueue.add(shard);
|
||||
|
||||
if (shard.sessionId) this.debug(`Session id is present, attempting an immediate reconnect...`, shard);
|
||||
this.reconnect();
|
||||
});
|
||||
|
||||
shard.on(WebSocketShardEvents.InvalidSession, () => {
|
||||
this.client.emit(Events.ShardReconnecting, shard.id);
|
||||
});
|
||||
|
||||
shard.on(WebSocketShardEvents.Destroyed, () => {
|
||||
this.debug('Shard was destroyed but no WebSocket connection was present! Reconnecting...', shard);
|
||||
|
||||
this.client.emit(Events.ShardReconnecting, shard.id);
|
||||
|
||||
this.shardQueue.add(shard);
|
||||
this.reconnect();
|
||||
});
|
||||
|
||||
shard.eventsAttached = true;
|
||||
}
|
||||
|
||||
this.shards.set(shard.id, shard);
|
||||
|
||||
try {
|
||||
await shard.connect();
|
||||
} catch (error) {
|
||||
if (error?.code && error.code in unrecoverableErrorCodeMap) {
|
||||
throw new DiscordjsError(unrecoverableErrorCodeMap[error.code]);
|
||||
// Undefined if session is invalid, error event for regular closes
|
||||
} else if (!error || error.code) {
|
||||
this.debug('Failed to connect to the gateway, requeueing...', shard);
|
||||
this.shardQueue.add(shard);
|
||||
} else {
|
||||
throw error;
|
||||
this.checkShardsReady();
|
||||
});
|
||||
shard.status = Status.Connecting;
|
||||
}
|
||||
}
|
||||
// If we have more shards, add a 5s delay
|
||||
if (this.shardQueue.size) {
|
||||
this.debug(`Shard Queue Size: ${this.shardQueue.size}; continuing in 5 seconds...`);
|
||||
await sleep(5_000);
|
||||
return this.createShards();
|
||||
}
|
||||
|
||||
return true;
|
||||
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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles reconnects for this manager.
|
||||
* Attaches event handlers to the internal WebSocketShardManager from `@discordjs/ws`.
|
||||
* @private
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async reconnect() {
|
||||
if (this.reconnecting || this.status !== Status.Ready) return false;
|
||||
this.reconnecting = true;
|
||||
try {
|
||||
await this.createShards();
|
||||
} catch (error) {
|
||||
this.debug(`Couldn't reconnect or fetch information about the gateway. ${error}`);
|
||||
if (error.httpStatus !== 401) {
|
||||
this.debug(`Possible network error occurred. Retrying in 5s...`);
|
||||
await sleep(5_000);
|
||||
this.reconnecting = false;
|
||||
return this.reconnect();
|
||||
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);
|
||||
}
|
||||
// If we get an error at this point, it means we cannot reconnect anymore
|
||||
if (this.client.listenerCount(Events.Invalidated)) {
|
||||
});
|
||||
|
||||
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 the client's session becomes invalidated.
|
||||
* You are expected to handle closing the process gracefully and preventing a boot loop
|
||||
* if you are listening to this event.
|
||||
* @event Client#invalidated
|
||||
* 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.Invalidated);
|
||||
// Destroy just the shards. This means you have to handle the cleanup yourself
|
||||
this.destroy();
|
||||
} else {
|
||||
this.client.destroy();
|
||||
this.client.emit(Events.ShardDisconnect, { code, reason: reasonIsDeprecated, wasClean: true }, shardId);
|
||||
this.debug(GatewayCloseCodes[code], shardId);
|
||||
return;
|
||||
}
|
||||
} finally {
|
||||
this.reconnecting = false;
|
||||
}
|
||||
return true;
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -310,7 +313,7 @@ class WebSocketManager extends EventEmitter {
|
|||
* @private
|
||||
*/
|
||||
broadcast(packet) {
|
||||
for (const shard of this.shards.values()) shard.send(packet);
|
||||
for (const shardId of this.shards.keys()) this._ws.send(shardId, packet);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -322,8 +325,7 @@ class WebSocketManager extends EventEmitter {
|
|||
// TODO: Make a util for getting a stack
|
||||
this.debug(`Manager was destroyed. Called by:\n${new Error().stack}`);
|
||||
this.destroyed = true;
|
||||
this.shardQueue.clear();
|
||||
for (const shard of this.shards.values()) shard.destroy({ closeCode: 1_000, reset: true, emit: false, log: false });
|
||||
this._ws.destroy({ code: CloseCodes.Normal });
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
751
node_modules/discord.js/src/client/websocket/WebSocketShard.js
generated
vendored
751
node_modules/discord.js/src/client/websocket/WebSocketShard.js
generated
vendored
|
@ -1,22 +1,13 @@
|
|||
'use strict';
|
||||
|
||||
const EventEmitter = require('node:events');
|
||||
const { setTimeout, setInterval, clearTimeout, clearInterval } = require('node:timers');
|
||||
const { GatewayDispatchEvents, GatewayIntentBits, GatewayOpcodes } = require('discord-api-types/v10');
|
||||
const WebSocket = require('../../WebSocket');
|
||||
const Events = require('../../util/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');
|
||||
|
||||
const STATUS_KEYS = Object.keys(Status);
|
||||
const CONNECTION_STATE = Object.keys(WebSocket.WebSocket);
|
||||
|
||||
let zlib;
|
||||
|
||||
try {
|
||||
zlib = require('zlib-sync');
|
||||
} catch {} // eslint-disable-line no-empty
|
||||
|
||||
let deprecationEmittedForImportant = false;
|
||||
/**
|
||||
* Represents a Shard's WebSocket connection
|
||||
* @extends {EventEmitter}
|
||||
|
@ -43,13 +34,6 @@ class WebSocketShard extends EventEmitter {
|
|||
*/
|
||||
this.status = Status.Idle;
|
||||
|
||||
/**
|
||||
* The current sequence of the shard
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.sequence = -1;
|
||||
|
||||
/**
|
||||
* The sequence of the shard after close
|
||||
* @type {number}
|
||||
|
@ -57,20 +41,6 @@ class WebSocketShard extends EventEmitter {
|
|||
*/
|
||||
this.closeSequence = 0;
|
||||
|
||||
/**
|
||||
* The current session id of the shard
|
||||
* @type {?string}
|
||||
* @private
|
||||
*/
|
||||
this.sessionId = null;
|
||||
|
||||
/**
|
||||
* The resume url for this shard
|
||||
* @type {?string}
|
||||
* @private
|
||||
*/
|
||||
this.resumeURL = null;
|
||||
|
||||
/**
|
||||
* The previous heartbeat ping of the shard
|
||||
* @type {number}
|
||||
|
@ -83,81 +53,6 @@ class WebSocketShard extends EventEmitter {
|
|||
*/
|
||||
this.lastPingTimestamp = -1;
|
||||
|
||||
/**
|
||||
* If we received a heartbeat ack back. Used to identify zombie connections
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this.lastHeartbeatAcked = true;
|
||||
|
||||
/**
|
||||
* Used to prevent calling {@link WebSocketShard#event:close} twice while closing or terminating the WebSocket.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this.closeEmitted = false;
|
||||
|
||||
/**
|
||||
* Contains the rate limit queue and metadata
|
||||
* @name WebSocketShard#ratelimit
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
Object.defineProperty(this, 'ratelimit', {
|
||||
value: {
|
||||
queue: [],
|
||||
total: 120,
|
||||
remaining: 120,
|
||||
time: 60e3,
|
||||
timer: null,
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* The WebSocket connection for the current shard
|
||||
* @name WebSocketShard#connection
|
||||
* @type {?WebSocket}
|
||||
* @private
|
||||
*/
|
||||
Object.defineProperty(this, 'connection', { value: null, writable: true });
|
||||
|
||||
/**
|
||||
* @external Inflate
|
||||
* @see {@link https://www.npmjs.com/package/zlib-sync}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The compression to use
|
||||
* @name WebSocketShard#inflate
|
||||
* @type {?Inflate}
|
||||
* @private
|
||||
*/
|
||||
Object.defineProperty(this, 'inflate', { value: null, writable: true });
|
||||
|
||||
/**
|
||||
* The HELLO timeout
|
||||
* @name WebSocketShard#helloTimeout
|
||||
* @type {?NodeJS.Timeout}
|
||||
* @private
|
||||
*/
|
||||
Object.defineProperty(this, 'helloTimeout', { value: null, writable: true });
|
||||
|
||||
/**
|
||||
* The WebSocket timeout.
|
||||
* @name WebSocketShard#wsCloseTimeout
|
||||
* @type {?NodeJS.Timeout}
|
||||
* @private
|
||||
*/
|
||||
Object.defineProperty(this, 'wsCloseTimeout', { value: null, writable: true });
|
||||
|
||||
/**
|
||||
* If the manager attached its event handlers on the shard
|
||||
* @name WebSocketShard#eventsAttached
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
Object.defineProperty(this, 'eventsAttached', { value: false, writable: true });
|
||||
|
||||
/**
|
||||
* A set of guild ids this shard expects to receive
|
||||
* @name WebSocketShard#expectedGuilds
|
||||
|
@ -175,12 +70,17 @@ class WebSocketShard extends EventEmitter {
|
|||
Object.defineProperty(this, 'readyTimeout', { value: null, writable: true });
|
||||
|
||||
/**
|
||||
* Time when the WebSocket connection was opened
|
||||
* @name WebSocketShard#connectedAt
|
||||
* @type {number}
|
||||
* @external SessionInfo
|
||||
* @see {@link https://discord.js.org/#/docs/ws/main/typedef/SessionInfo}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The session info used by `@discordjs/ws` package.
|
||||
* @name WebSocketShard#sessionInfo
|
||||
* @type {?SessionInfo}
|
||||
* @private
|
||||
*/
|
||||
Object.defineProperty(this, 'connectedAt', { value: 0, writable: true });
|
||||
Object.defineProperty(this, 'sessionInfo', { value: null, writable: true });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -189,161 +89,7 @@ class WebSocketShard extends EventEmitter {
|
|||
* @private
|
||||
*/
|
||||
debug(message) {
|
||||
this.manager.debug(message, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects the shard to the gateway.
|
||||
* @private
|
||||
* @returns {Promise<void>} A promise that will resolve if the shard turns ready successfully,
|
||||
* or reject if we couldn't connect
|
||||
*/
|
||||
connect() {
|
||||
const { client } = this.manager;
|
||||
|
||||
if (this.connection?.readyState === WebSocket.OPEN && this.status === Status.Ready) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
const gateway = this.resumeURL ?? this.manager.gateway;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const cleanup = () => {
|
||||
this.removeListener(WebSocketShardEvents.Close, onClose);
|
||||
this.removeListener(WebSocketShardEvents.Ready, onReady);
|
||||
this.removeListener(WebSocketShardEvents.Resumed, onResumed);
|
||||
this.removeListener(WebSocketShardEvents.InvalidSession, onInvalidOrDestroyed);
|
||||
this.removeListener(WebSocketShardEvents.Destroyed, onInvalidOrDestroyed);
|
||||
};
|
||||
|
||||
const onReady = () => {
|
||||
cleanup();
|
||||
resolve();
|
||||
};
|
||||
|
||||
const onResumed = () => {
|
||||
cleanup();
|
||||
resolve();
|
||||
};
|
||||
|
||||
const onClose = event => {
|
||||
cleanup();
|
||||
reject(event);
|
||||
};
|
||||
|
||||
const onInvalidOrDestroyed = () => {
|
||||
cleanup();
|
||||
// eslint-disable-next-line prefer-promise-reject-errors
|
||||
reject();
|
||||
};
|
||||
|
||||
this.once(WebSocketShardEvents.Ready, onReady);
|
||||
this.once(WebSocketShardEvents.Resumed, onResumed);
|
||||
this.once(WebSocketShardEvents.Close, onClose);
|
||||
this.once(WebSocketShardEvents.InvalidSession, onInvalidOrDestroyed);
|
||||
this.once(WebSocketShardEvents.Destroyed, onInvalidOrDestroyed);
|
||||
|
||||
if (this.connection?.readyState === WebSocket.OPEN) {
|
||||
this.debug('An open connection was found, attempting an immediate identify.');
|
||||
this.identify();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.connection) {
|
||||
this.debug(`A connection object was found. Cleaning up before continuing.
|
||||
State: ${CONNECTION_STATE[this.connection.readyState]}`);
|
||||
this.destroy({ emit: false });
|
||||
}
|
||||
|
||||
const wsQuery = { v: client.options.ws.version };
|
||||
|
||||
if (zlib) {
|
||||
this.inflate = new zlib.Inflate({
|
||||
chunkSize: 65535,
|
||||
flush: zlib.Z_SYNC_FLUSH,
|
||||
to: WebSocket.encoding === 'json' ? 'string' : '',
|
||||
});
|
||||
wsQuery.compress = 'zlib-stream';
|
||||
}
|
||||
|
||||
this.debug(
|
||||
`[CONNECT]
|
||||
Gateway : ${gateway}
|
||||
Version : ${client.options.ws.version}
|
||||
Encoding : ${WebSocket.encoding}
|
||||
Compression: ${zlib ? 'zlib-stream' : 'none'}`,
|
||||
);
|
||||
|
||||
this.status = this.status === Status.Disconnected ? Status.Reconnecting : Status.Connecting;
|
||||
this.setHelloTimeout();
|
||||
|
||||
this.connectedAt = Date.now();
|
||||
|
||||
// Adding a handshake timeout to just make sure no zombie connection appears.
|
||||
const ws = (this.connection = WebSocket.create(gateway, wsQuery, { handshakeTimeout: 30_000 }));
|
||||
ws.onopen = this.onOpen.bind(this);
|
||||
ws.onmessage = this.onMessage.bind(this);
|
||||
ws.onerror = this.onError.bind(this);
|
||||
ws.onclose = this.onClose.bind(this);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whenever a connection is opened to the gateway.
|
||||
* @private
|
||||
*/
|
||||
onOpen() {
|
||||
this.debug(`[CONNECTED] Took ${Date.now() - this.connectedAt}ms`);
|
||||
this.status = Status.Nearly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whenever a message is received.
|
||||
* @param {MessageEvent} event Event received
|
||||
* @private
|
||||
*/
|
||||
onMessage({ data }) {
|
||||
let raw;
|
||||
if (data instanceof ArrayBuffer) data = new Uint8Array(data);
|
||||
if (zlib) {
|
||||
const l = data.length;
|
||||
const flush =
|
||||
l >= 4 && data[l - 4] === 0x00 && data[l - 3] === 0x00 && data[l - 2] === 0xff && data[l - 1] === 0xff;
|
||||
|
||||
this.inflate.push(data, flush && zlib.Z_SYNC_FLUSH);
|
||||
if (!flush) return;
|
||||
raw = this.inflate.result;
|
||||
} else {
|
||||
raw = data;
|
||||
}
|
||||
let packet;
|
||||
try {
|
||||
packet = WebSocket.unpack(raw);
|
||||
} catch (err) {
|
||||
this.manager.client.emit(Events.ShardError, err, this.id);
|
||||
return;
|
||||
}
|
||||
this.manager.client.emit(Events.Raw, packet, this.id);
|
||||
if (packet.op === GatewayOpcodes.Dispatch) this.manager.emit(packet.t, packet.d, this.id);
|
||||
this.onPacket(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whenever an error occurs with the WebSocket.
|
||||
* @param {ErrorEvent} event The error that occurred
|
||||
* @private
|
||||
*/
|
||||
onError(event) {
|
||||
const error = event?.error ?? event;
|
||||
if (!error) return;
|
||||
|
||||
/**
|
||||
* 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.manager.client.emit(Events.ShardError, error, this.id);
|
||||
this.manager.debug(message, this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -351,39 +97,11 @@ class WebSocketShard extends EventEmitter {
|
|||
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external ErrorEvent
|
||||
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/ErrorEvent}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external MessageEvent
|
||||
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Called whenever a connection to the gateway is closed.
|
||||
* @param {CloseEvent} event Close event that was received
|
||||
* @private
|
||||
*/
|
||||
onClose(event) {
|
||||
this.closeEmitted = true;
|
||||
if (this.sequence !== -1) this.closeSequence = this.sequence;
|
||||
this.sequence = -1;
|
||||
this.setHeartbeatTimer(-1);
|
||||
this.setHelloTimeout(-1);
|
||||
// Clearing the WebSocket close timeout as close was emitted.
|
||||
this.setWsCloseTimeout(-1);
|
||||
// If we still have a connection object, clean up its listeners
|
||||
if (this.connection) this._cleanupConnection();
|
||||
this.status = Status.Disconnected;
|
||||
this.emitClose(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = {
|
||||
|
@ -404,94 +122,37 @@ class WebSocketShard extends EventEmitter {
|
|||
*/
|
||||
this.emit(WebSocketShardEvents.Close, event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whenever a packet is received.
|
||||
* Called when the shard receives the READY payload.
|
||||
* @param {Object} packet The received packet
|
||||
* @private
|
||||
*/
|
||||
onPacket(packet) {
|
||||
onReadyPacket(packet) {
|
||||
if (!packet) {
|
||||
this.debug(`Received broken packet: '${packet}'.`);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (packet.t) {
|
||||
case GatewayDispatchEvents.Ready:
|
||||
/**
|
||||
* Emitted when the shard receives the READY payload and is now waiting for guilds
|
||||
* @event WebSocketShard#ready
|
||||
*/
|
||||
this.emit(WebSocketShardEvents.Ready);
|
||||
/**
|
||||
* Emitted when the shard receives the READY payload and is now waiting for guilds
|
||||
* @event WebSocketShard#ready
|
||||
*/
|
||||
this.emit(WebSocketShardEvents.Ready);
|
||||
|
||||
this.sessionId = packet.d.session_id;
|
||||
this.resumeURL = packet.d.resume_gateway_url;
|
||||
this.expectedGuilds = new Set(packet.d.guilds.map(d => d.id));
|
||||
this.status = Status.WaitingForGuilds;
|
||||
this.debug(`[READY] Session ${this.sessionId} | Resume url ${this.resumeURL}.`);
|
||||
this.lastHeartbeatAcked = true;
|
||||
this.sendHeartbeat('ReadyHeartbeat');
|
||||
break;
|
||||
case GatewayDispatchEvents.Resumed: {
|
||||
/**
|
||||
* Emitted when the shard resumes successfully
|
||||
* @event WebSocketShard#resumed
|
||||
*/
|
||||
this.emit(WebSocketShardEvents.Resumed);
|
||||
this.expectedGuilds = new Set(packet.guilds.map(d => d.id));
|
||||
this.status = Status.WaitingForGuilds;
|
||||
}
|
||||
|
||||
this.status = Status.Ready;
|
||||
const replayed = packet.s - this.closeSequence;
|
||||
this.debug(`[RESUMED] Session ${this.sessionId} | Replayed ${replayed} events.`);
|
||||
this.lastHeartbeatAcked = true;
|
||||
this.sendHeartbeat('ResumeHeartbeat');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (packet.s > this.sequence) this.sequence = packet.s;
|
||||
|
||||
switch (packet.op) {
|
||||
case GatewayOpcodes.Hello:
|
||||
this.setHelloTimeout(-1);
|
||||
this.setHeartbeatTimer(packet.d.heartbeat_interval);
|
||||
this.identify();
|
||||
break;
|
||||
case GatewayOpcodes.Reconnect:
|
||||
this.debug('[RECONNECT] Discord asked us to reconnect');
|
||||
this.destroy({ closeCode: 4_000 });
|
||||
break;
|
||||
case GatewayOpcodes.InvalidSession:
|
||||
this.debug(`[INVALID SESSION] Resumable: ${packet.d}.`);
|
||||
// If we can resume the session, do so immediately
|
||||
if (packet.d) {
|
||||
this.identifyResume();
|
||||
return;
|
||||
}
|
||||
// Reset the sequence
|
||||
this.sequence = -1;
|
||||
// Reset the session id as it's invalid
|
||||
this.sessionId = null;
|
||||
// Set the status to reconnecting
|
||||
this.status = Status.Reconnecting;
|
||||
// Finally, emit the INVALID_SESSION event
|
||||
/**
|
||||
* Emitted when the session has been invalidated.
|
||||
* @event WebSocketShard#invalidSession
|
||||
*/
|
||||
this.emit(WebSocketShardEvents.InvalidSession);
|
||||
break;
|
||||
case GatewayOpcodes.HeartbeatAck:
|
||||
this.ackHeartbeat();
|
||||
break;
|
||||
case GatewayOpcodes.Heartbeat:
|
||||
this.sendHeartbeat('HeartbeatRequest', true);
|
||||
break;
|
||||
default:
|
||||
this.manager.handlePacket(packet, this);
|
||||
if (this.status === Status.WaitingForGuilds && packet.t === GatewayDispatchEvents.GuildCreate) {
|
||||
this.expectedGuilds.delete(packet.d.id);
|
||||
this.checkReady();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -538,7 +199,6 @@ class WebSocketShard extends EventEmitter {
|
|||
);
|
||||
|
||||
this.readyTimeout = null;
|
||||
|
||||
this.status = Status.Ready;
|
||||
|
||||
this.emit(WebSocketShardEvents.AllReady, this.expectedGuilds);
|
||||
|
@ -547,187 +207,6 @@ class WebSocketShard extends EventEmitter {
|
|||
).unref();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the HELLO packet timeout.
|
||||
* @param {number} [time] If set to -1, it will clear the hello timeout
|
||||
* @private
|
||||
*/
|
||||
setHelloTimeout(time) {
|
||||
if (time === -1) {
|
||||
if (this.helloTimeout) {
|
||||
this.debug('Clearing the HELLO timeout.');
|
||||
clearTimeout(this.helloTimeout);
|
||||
this.helloTimeout = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.debug('Setting a HELLO timeout for 20s.');
|
||||
this.helloTimeout = setTimeout(() => {
|
||||
this.debug('Did not receive HELLO in time. Destroying and connecting again.');
|
||||
this.destroy({ reset: true, closeCode: 4009 });
|
||||
}, 20_000).unref();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the WebSocket Close timeout.
|
||||
* This method is responsible for detecting any zombie connections if the WebSocket fails to close properly.
|
||||
* @param {number} [time] If set to -1, it will clear the timeout
|
||||
* @private
|
||||
*/
|
||||
setWsCloseTimeout(time) {
|
||||
if (this.wsCloseTimeout) {
|
||||
this.debug('[WebSocket] Clearing the close timeout.');
|
||||
clearTimeout(this.wsCloseTimeout);
|
||||
}
|
||||
if (time === -1) {
|
||||
this.wsCloseTimeout = null;
|
||||
return;
|
||||
}
|
||||
this.wsCloseTimeout = setTimeout(() => {
|
||||
this.setWsCloseTimeout(-1);
|
||||
this.debug(`[WebSocket] Close Emitted: ${this.closeEmitted}`);
|
||||
// Check if close event was emitted.
|
||||
if (this.closeEmitted) {
|
||||
this.debug(
|
||||
`[WebSocket] was closed. | WS State: ${
|
||||
CONNECTION_STATE[this.connection?.readyState ?? WebSocket.CLOSED]
|
||||
} | Close Emitted: ${this.closeEmitted}`,
|
||||
);
|
||||
// Setting the variable false to check for zombie connections.
|
||||
this.closeEmitted = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this.debug(
|
||||
`[WebSocket] did not close properly, assuming a zombie connection.\nEmitting close and reconnecting again.`,
|
||||
);
|
||||
|
||||
this.emitClose();
|
||||
// Setting the variable false to check for zombie connections.
|
||||
this.closeEmitted = false;
|
||||
}, time).unref();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the heartbeat timer for this shard.
|
||||
* @param {number} time If -1, clears the interval, any other number sets an interval
|
||||
* @private
|
||||
*/
|
||||
setHeartbeatTimer(time) {
|
||||
if (time === -1) {
|
||||
if (this.heartbeatInterval) {
|
||||
this.debug('Clearing the heartbeat interval.');
|
||||
clearInterval(this.heartbeatInterval);
|
||||
this.heartbeatInterval = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.debug(`Setting a heartbeat interval for ${time}ms.`);
|
||||
// Sanity checks
|
||||
if (this.heartbeatInterval) clearInterval(this.heartbeatInterval);
|
||||
this.heartbeatInterval = setInterval(() => this.sendHeartbeat(), time).unref();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a heartbeat to the WebSocket.
|
||||
* If this shard didn't receive a heartbeat last time, it will destroy it and reconnect
|
||||
* @param {string} [tag='HeartbeatTimer'] What caused this heartbeat to be sent
|
||||
* @param {boolean} [ignoreHeartbeatAck] If we should send the heartbeat forcefully.
|
||||
* @private
|
||||
*/
|
||||
sendHeartbeat(
|
||||
tag = 'HeartbeatTimer',
|
||||
ignoreHeartbeatAck = [Status.WaitingForGuilds, Status.Identifying, Status.Resuming].includes(this.status),
|
||||
) {
|
||||
if (ignoreHeartbeatAck && !this.lastHeartbeatAcked) {
|
||||
this.debug(`[${tag}] Didn't process heartbeat ack yet but we are still connected. Sending one now.`);
|
||||
} else if (!this.lastHeartbeatAcked) {
|
||||
this.debug(
|
||||
`[${tag}] Didn't receive a heartbeat ack last time, assuming zombie connection. Destroying and reconnecting.
|
||||
Status : ${STATUS_KEYS[this.status]}
|
||||
Sequence : ${this.sequence}
|
||||
Connection State: ${this.connection ? CONNECTION_STATE[this.connection.readyState] : 'No Connection??'}`,
|
||||
);
|
||||
|
||||
this.destroy({ reset: true, closeCode: 4009 });
|
||||
return;
|
||||
}
|
||||
|
||||
this.debug(`[${tag}] Sending a heartbeat.`);
|
||||
this.lastHeartbeatAcked = false;
|
||||
this.lastPingTimestamp = Date.now();
|
||||
this.send({ op: GatewayOpcodes.Heartbeat, d: this.sequence }, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Acknowledges a heartbeat.
|
||||
* @private
|
||||
*/
|
||||
ackHeartbeat() {
|
||||
this.lastHeartbeatAcked = true;
|
||||
const latency = Date.now() - this.lastPingTimestamp;
|
||||
this.debug(`Heartbeat acknowledged, latency of ${latency}ms.`);
|
||||
this.ping = latency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Identifies the client on the connection.
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
identify() {
|
||||
return this.sessionId ? this.identifyResume() : this.identifyNew();
|
||||
}
|
||||
|
||||
/**
|
||||
* Identifies as a new connection on the gateway.
|
||||
* @private
|
||||
*/
|
||||
identifyNew() {
|
||||
const { client } = this.manager;
|
||||
if (!client.token) {
|
||||
this.debug('[IDENTIFY] No token available to identify a new session.');
|
||||
return;
|
||||
}
|
||||
|
||||
this.status = Status.Identifying;
|
||||
|
||||
// Clone the identify payload and assign the token and shard info
|
||||
const d = {
|
||||
...client.options.ws,
|
||||
intents: client.options.intents.bitfield,
|
||||
token: client.token,
|
||||
shard: [this.id, Number(client.options.shardCount)],
|
||||
};
|
||||
|
||||
this.debug(`[IDENTIFY] Shard ${this.id}/${client.options.shardCount} with intents: ${d.intents}`);
|
||||
this.send({ op: GatewayOpcodes.Identify, d }, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumes a session on the gateway.
|
||||
* @private
|
||||
*/
|
||||
identifyResume() {
|
||||
if (!this.sessionId) {
|
||||
this.debug('[RESUME] No session id was present; identifying as a new session.');
|
||||
this.identifyNew();
|
||||
return;
|
||||
}
|
||||
|
||||
this.status = Status.Resuming;
|
||||
|
||||
this.debug(`[RESUME] Session ${this.sessionId}, sequence ${this.closeSequence}`);
|
||||
|
||||
const d = {
|
||||
token: this.manager.client.token,
|
||||
session_id: this.sessionId,
|
||||
seq: this.closeSequence,
|
||||
};
|
||||
|
||||
this.send({ op: GatewayOpcodes.Resume, d }, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -735,163 +214,17 @@ class WebSocketShard extends EventEmitter {
|
|||
* 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) {
|
||||
this.ratelimit.queue[important ? 'unshift' : 'push'](data);
|
||||
this.processQueue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends data, bypassing the queue.
|
||||
* @param {Object} data Packet to send
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
_send(data) {
|
||||
if (this.connection?.readyState !== WebSocket.OPEN) {
|
||||
this.debug(
|
||||
`Tried to send packet '${JSON.stringify(data).replaceAll(
|
||||
this.manager.client.token,
|
||||
this.manager.client._censoredToken,
|
||||
)}' but no WebSocket is available!`,
|
||||
if (important && !deprecationEmittedForImportant) {
|
||||
process.emitWarning(
|
||||
'Sending important payloads explicitly is deprecated. They are determined by their opcode implicitly now.',
|
||||
'DeprecationWarning',
|
||||
);
|
||||
this.destroy({ closeCode: 4_000 });
|
||||
return;
|
||||
deprecationEmittedForImportant = true;
|
||||
}
|
||||
|
||||
this.connection.send(WebSocket.pack(data), err => {
|
||||
if (err) this.manager.client.emit(Events.ShardError, err, this.id);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the current WebSocket queue.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
processQueue() {
|
||||
if (this.ratelimit.remaining === 0) return;
|
||||
if (this.ratelimit.queue.length === 0) return;
|
||||
if (this.ratelimit.remaining === this.ratelimit.total) {
|
||||
this.ratelimit.timer = setTimeout(() => {
|
||||
this.ratelimit.remaining = this.ratelimit.total;
|
||||
this.processQueue();
|
||||
}, this.ratelimit.time).unref();
|
||||
}
|
||||
while (this.ratelimit.remaining > 0) {
|
||||
const item = this.ratelimit.queue.shift();
|
||||
if (!item) return;
|
||||
this._send(item);
|
||||
this.ratelimit.remaining--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys this shard and closes its WebSocket connection.
|
||||
* @param {Object} [options={ closeCode: 1000, reset: false, emit: true, log: true }] Options for destroying the shard
|
||||
* @private
|
||||
*/
|
||||
destroy({ closeCode = 1_000, reset = false, emit = true, log = true } = {}) {
|
||||
if (log) {
|
||||
this.debug(`[DESTROY]
|
||||
Close Code : ${closeCode}
|
||||
Reset : ${reset}
|
||||
Emit DESTROYED: ${emit}`);
|
||||
}
|
||||
|
||||
// Step 0: Remove all timers
|
||||
this.setHeartbeatTimer(-1);
|
||||
this.setHelloTimeout(-1);
|
||||
|
||||
this.debug(
|
||||
`[WebSocket] Destroy: Attempting to close the WebSocket. | WS State: ${
|
||||
CONNECTION_STATE[this.connection?.readyState ?? WebSocket.CLOSED]
|
||||
}`,
|
||||
);
|
||||
// Step 1: Close the WebSocket connection, if any, otherwise, emit DESTROYED
|
||||
if (this.connection) {
|
||||
// If the connection is currently opened, we will (hopefully) receive close
|
||||
if (this.connection.readyState === WebSocket.OPEN) {
|
||||
this.connection.close(closeCode);
|
||||
this.debug(`[WebSocket] Close: Tried closing. | WS State: ${CONNECTION_STATE[this.connection.readyState]}`);
|
||||
} else {
|
||||
// Connection is not OPEN
|
||||
this.debug(`WS State: ${CONNECTION_STATE[this.connection.readyState]}`);
|
||||
// Remove listeners from the connection
|
||||
this._cleanupConnection();
|
||||
// Attempt to close the connection just in case
|
||||
try {
|
||||
this.connection.close(closeCode);
|
||||
} catch (err) {
|
||||
this.debug(
|
||||
`[WebSocket] Close: Something went wrong while closing the WebSocket: ${
|
||||
err.message || err
|
||||
}. Forcefully terminating the connection | WS State: ${CONNECTION_STATE[this.connection.readyState]}`,
|
||||
);
|
||||
this.connection.terminate();
|
||||
}
|
||||
// Emit the destroyed event if needed
|
||||
if (emit) this._emitDestroyed();
|
||||
}
|
||||
} else if (emit) {
|
||||
// We requested a destroy, but we had no connection. Emit destroyed
|
||||
this._emitDestroyed();
|
||||
}
|
||||
|
||||
if (this.connection?.readyState === WebSocket.CLOSING || this.connection?.readyState === WebSocket.CLOSED) {
|
||||
this.closeEmitted = false;
|
||||
this.debug(
|
||||
`[WebSocket] Adding a WebSocket close timeout to ensure a correct WS reconnect.
|
||||
Timeout: ${this.manager.client.options.closeTimeout}ms`,
|
||||
);
|
||||
this.setWsCloseTimeout(this.manager.client.options.closeTimeout);
|
||||
}
|
||||
|
||||
// Step 2: Null the connection object
|
||||
this.connection = null;
|
||||
|
||||
// Step 3: Set the shard status to disconnected
|
||||
this.status = Status.Disconnected;
|
||||
|
||||
// Step 4: Cache the old sequence (use to attempt a resume)
|
||||
if (this.sequence !== -1) this.closeSequence = this.sequence;
|
||||
|
||||
// Step 5: Reset the sequence, resume url and session id if requested
|
||||
if (reset) {
|
||||
this.sequence = -1;
|
||||
this.sessionId = null;
|
||||
this.resumeURL = null;
|
||||
}
|
||||
|
||||
// Step 6: reset the rate limit data
|
||||
this.ratelimit.remaining = this.ratelimit.total;
|
||||
this.ratelimit.queue.length = 0;
|
||||
if (this.ratelimit.timer) {
|
||||
clearTimeout(this.ratelimit.timer);
|
||||
this.ratelimit.timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up the WebSocket connection listeners.
|
||||
* @private
|
||||
*/
|
||||
_cleanupConnection() {
|
||||
this.connection.onopen = this.connection.onclose = this.connection.onmessage = null;
|
||||
this.connection.onerror = () => null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits the DESTROYED event on the shard
|
||||
* @private
|
||||
*/
|
||||
_emitDestroyed() {
|
||||
/**
|
||||
* Emitted when a shard is destroyed, but no WebSocket connection was present.
|
||||
* @private
|
||||
* @event WebSocketShard#destroyed
|
||||
*/
|
||||
this.emit(WebSocketShardEvents.Destroyed);
|
||||
this.manager._ws.send(this.id, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
5
node_modules/discord.js/src/client/websocket/handlers/GUILD_AUDIT_LOG_ENTRY_CREATE.js
generated
vendored
Normal file
5
node_modules/discord.js/src/client/websocket/handlers/GUILD_AUDIT_LOG_ENTRY_CREATE.js
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = (client, packet) => {
|
||||
client.actions.GuildAuditLogEntryCreate.handle(packet.d);
|
||||
};
|
5
node_modules/discord.js/src/client/websocket/handlers/GUILD_MEMBERS_CHUNK.js
generated
vendored
5
node_modules/discord.js/src/client/websocket/handlers/GUILD_MEMBERS_CHUNK.js
generated
vendored
|
@ -18,6 +18,8 @@ module.exports = (client, { d: data }) => {
|
|||
* @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
|
||||
*/
|
||||
|
||||
|
@ -29,8 +31,9 @@ module.exports = (client, { d: data }) => {
|
|||
* @param {GuildMembersChunk} chunk Properties of the received chunk
|
||||
*/
|
||||
client.emit(Events.GuildMembersChunk, members, guild, {
|
||||
count: data.chunk_count,
|
||||
index: data.chunk_index,
|
||||
count: data.chunk_count,
|
||||
notFound: data.not_found,
|
||||
nonce: data.nonce,
|
||||
});
|
||||
};
|
||||
|
|
2
node_modules/discord.js/src/client/websocket/handlers/RESUMED.js
generated
vendored
2
node_modules/discord.js/src/client/websocket/handlers/RESUMED.js
generated
vendored
|
@ -3,7 +3,7 @@
|
|||
const Events = require('../../../util/Events');
|
||||
|
||||
module.exports = (client, packet, shard) => {
|
||||
const replayed = shard.sequence - shard.closeSequence;
|
||||
const replayed = shard.sessionInfo.sequence - shard.closeSequence;
|
||||
/**
|
||||
* Emitted when a shard resumes successfully.
|
||||
* @event Client#shardResume
|
||||
|
|
1
node_modules/discord.js/src/client/websocket/handlers/index.js
generated
vendored
1
node_modules/discord.js/src/client/websocket/handlers/index.js
generated
vendored
|
@ -10,6 +10,7 @@ const handlers = Object.fromEntries([
|
|||
['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')],
|
||||
|
|
16
node_modules/discord.js/src/errors/ErrorCodes.js
generated
vendored
16
node_modules/discord.js/src/errors/ErrorCodes.js
generated
vendored
|
@ -13,16 +13,23 @@
|
|||
* @property {'ApplicationCommandPermissionsTokenMissing'} ApplicationCommandPermissionsTokenMissing
|
||||
|
||||
* @property {'WSCloseRequested'} WSCloseRequested
|
||||
* <warn>This property is deprecated.</warn>
|
||||
* @property {'WSConnectionExists'} WSConnectionExists
|
||||
* <warn>This property is deprecated.</warn>
|
||||
* @property {'WSNotOpen'} WSNotOpen
|
||||
* <warn>This property is deprecated.</warn>
|
||||
* @property {'ManagerDestroyed'} ManagerDestroyed
|
||||
|
||||
* @property {'BitFieldInvalid'} BitFieldInvalid
|
||||
|
||||
* @property {'ShardingInvalid'} ShardingInvalid
|
||||
* <warn>This property is deprecated.</warn>
|
||||
* @property {'ShardingRequired'} ShardingRequired
|
||||
* <warn>This property is deprecated.</warn>
|
||||
* @property {'InvalidIntents'} InvalidIntents
|
||||
* <warn>This property is deprecated.</warn>
|
||||
* @property {'DisallowedIntents'} DisallowedIntents
|
||||
* <warn>This property is deprecated.</warn>
|
||||
* @property {'ShardingNoShards'} ShardingNoShards
|
||||
* @property {'ShardingInProcess'} ShardingInProcess
|
||||
* @property {'ShardingInvalidEvalBroadcast'} ShardingInvalidEvalBroadcast
|
||||
|
@ -106,7 +113,10 @@
|
|||
|
||||
* @property {'EmojiType'} EmojiType
|
||||
* @property {'EmojiManaged'} EmojiManaged
|
||||
* @property {'MissingManageGuildExpressionsPermission'} MissingManageGuildExpressionsPermission
|
||||
* @property {'MissingManageEmojisAndStickersPermission'} MissingManageEmojisAndStickersPermission
|
||||
* <warn>This property is deprecated. Use `MissingManageGuildExpressionsPermission` instead.</warn>
|
||||
*
|
||||
* @property {'NotGuildSticker'} NotGuildSticker
|
||||
|
||||
* @property {'ReactionResolveUser'} ReactionResolveUser
|
||||
|
@ -135,12 +145,14 @@
|
|||
* @property {'CommandInteractionOptionEmpty'} CommandInteractionOptionEmpty
|
||||
* @property {'CommandInteractionOptionNoSubcommand'} CommandInteractionOptionNoSubcommand
|
||||
* @property {'CommandInteractionOptionNoSubcommandGroup'} CommandInteractionOptionNoSubcommandGroup
|
||||
* @property {'CommandInteractionOptionInvalidChannelType'} CommandInteractionOptionInvalidChannelType
|
||||
* @property {'AutocompleteInteractionOptionNoFocusedOption'} AutocompleteInteractionOptionNoFocusedOption
|
||||
|
||||
* @property {'ModalSubmitInteractionFieldNotFound'} ModalSubmitInteractionFieldNotFound
|
||||
* @property {'ModalSubmitInteractionFieldType'} ModalSubmitInteractionFieldType
|
||||
|
||||
* @property {'InvalidMissingScopes'} InvalidMissingScopes
|
||||
* @property {'InvalidScopesWithPermissions'} InvalidScopesWithPermissions
|
||||
|
||||
* @property {'NotImplemented'} NotImplemented
|
||||
|
||||
|
@ -253,7 +265,9 @@ const keys = [
|
|||
|
||||
'EmojiType',
|
||||
'EmojiManaged',
|
||||
'MissingManageGuildExpressionsPermission',
|
||||
'MissingManageEmojisAndStickersPermission',
|
||||
|
||||
'NotGuildSticker',
|
||||
|
||||
'ReactionResolveUser',
|
||||
|
@ -281,12 +295,14 @@ const keys = [
|
|||
'CommandInteractionOptionEmpty',
|
||||
'CommandInteractionOptionNoSubcommand',
|
||||
'CommandInteractionOptionNoSubcommandGroup',
|
||||
'CommandInteractionOptionInvalidChannelType',
|
||||
'AutocompleteInteractionOptionNoFocusedOption',
|
||||
|
||||
'ModalSubmitInteractionFieldNotFound',
|
||||
'ModalSubmitInteractionFieldType',
|
||||
|
||||
'InvalidMissingScopes',
|
||||
'InvalidScopesWithPermissions',
|
||||
|
||||
'NotImplemented',
|
||||
|
||||
|
|
6
node_modules/discord.js/src/errors/Messages.js
generated
vendored
6
node_modules/discord.js/src/errors/Messages.js
generated
vendored
|
@ -111,8 +111,11 @@ const Messages = {
|
|||
|
||||
[DjsErrorCodes.EmojiType]: 'Emoji must be a string or GuildEmoji/ReactionEmoji',
|
||||
[DjsErrorCodes.EmojiManaged]: 'Emoji is managed and has no Author.',
|
||||
[DjsErrorCodes.MissingManageGuildExpressionsPermission]: guild =>
|
||||
`Client must have Manage Guild Expressions permission in guild ${guild} to see emoji authors.`,
|
||||
[DjsErrorCodes.MissingManageEmojisAndStickersPermission]: guild =>
|
||||
`Client must have Manage Emojis and Stickers permission in guild ${guild} to see emoji authors.`,
|
||||
|
||||
[DjsErrorCodes.NotGuildSticker]: 'Sticker is a standard (non-guild) sticker and has no author.',
|
||||
|
||||
[DjsErrorCodes.ReactionResolveUser]: "Couldn't resolve the user id to remove from the reaction.",
|
||||
|
@ -145,6 +148,8 @@ const Messages = {
|
|||
`Required option "${name}" is of type: ${type}; expected a non-empty value.`,
|
||||
[DjsErrorCodes.CommandInteractionOptionNoSubcommand]: 'No subcommand specified for interaction.',
|
||||
[DjsErrorCodes.CommandInteractionOptionNoSubcommandGroup]: 'No subcommand group specified for interaction.',
|
||||
[DjsErrorCodes.CommandInteractionOptionInvalidChannelType]: (name, type, expected) =>
|
||||
`The type of channel of the option "${name}" is: ${type}; expected ${expected}.`,
|
||||
[DjsErrorCodes.AutocompleteInteractionOptionNoFocusedOption]: 'No focused option for autocomplete interaction.',
|
||||
|
||||
[DjsErrorCodes.ModalSubmitInteractionFieldNotFound]: customId =>
|
||||
|
@ -153,6 +158,7 @@ const Messages = {
|
|||
`Field with custom id "${customId}" is of type: ${type}; expected ${expected}.`,
|
||||
|
||||
[DjsErrorCodes.InvalidMissingScopes]: 'At least one valid scope must be provided for the invite',
|
||||
[DjsErrorCodes.InvalidScopesWithPermissions]: 'Permissions cannot be set without the bot scope.',
|
||||
|
||||
[DjsErrorCodes.NotImplemented]: (what, name) => `Method ${what} not implemented on ${name}.`,
|
||||
|
||||
|
|
7
node_modules/discord.js/src/index.js
generated
vendored
7
node_modules/discord.js/src/index.js
generated
vendored
|
@ -28,6 +28,7 @@ exports.Colors = require('./util/Colors');
|
|||
exports.DataResolver = require('./util/DataResolver');
|
||||
exports.Events = require('./util/Events');
|
||||
exports.Formatters = require('./util/Formatters');
|
||||
exports.GuildMemberFlagsBitField = require('./util/GuildMemberFlagsBitField').GuildMemberFlagsBitField;
|
||||
exports.IntentsBitField = require('./util/IntentsBitField');
|
||||
exports.LimitedCollection = require('./util/LimitedCollection');
|
||||
exports.MessageFlagsBitField = require('./util/MessageFlagsBitField');
|
||||
|
@ -88,6 +89,8 @@ exports.Activity = require('./structures/Presence').Activity;
|
|||
exports.AnonymousGuild = require('./structures/AnonymousGuild');
|
||||
exports.Application = require('./structures/interfaces/Application');
|
||||
exports.ApplicationCommand = require('./structures/ApplicationCommand');
|
||||
exports.ApplicationRoleConnectionMetadata =
|
||||
require('./structures/ApplicationRoleConnectionMetadata').ApplicationRoleConnectionMetadata;
|
||||
exports.AutocompleteInteraction = require('./structures/AutocompleteInteraction');
|
||||
exports.AutoModerationActionExecution = require('./structures/AutoModerationActionExecution');
|
||||
exports.AutoModerationRule = require('./structures/AutoModerationRule');
|
||||
|
@ -201,10 +204,10 @@ exports.WidgetMember = require('./structures/WidgetMember');
|
|||
exports.WelcomeChannel = require('./structures/WelcomeChannel');
|
||||
exports.WelcomeScreen = require('./structures/WelcomeScreen');
|
||||
|
||||
exports.WebSocket = require('./WebSocket');
|
||||
|
||||
// External
|
||||
__exportStar(require('discord-api-types/v10'), exports);
|
||||
__exportStar(require('@discordjs/builders'), exports);
|
||||
__exportStar(require('@discordjs/formatters'), exports);
|
||||
__exportStar(require('@discordjs/rest'), exports);
|
||||
__exportStar(require('@discordjs/util'), exports);
|
||||
__exportStar(require('@discordjs/ws'), exports);
|
||||
|
|
7
node_modules/discord.js/src/managers/ApplicationCommandManager.js
generated
vendored
7
node_modules/discord.js/src/managers/ApplicationCommandManager.js
generated
vendored
|
@ -1,8 +1,8 @@
|
|||
'use strict';
|
||||
|
||||
const { isJSONEncodable } = require('@discordjs/builders');
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { makeURLSearchParams } = require('@discordjs/rest');
|
||||
const { isJSONEncodable } = require('@discordjs/util');
|
||||
const { Routes } = require('discord-api-types/v10');
|
||||
const ApplicationCommandPermissionsManager = require('./ApplicationCommandPermissionsManager');
|
||||
const CachedManager = require('./CachedManager');
|
||||
|
@ -66,12 +66,10 @@ class ApplicationCommandManager extends CachedManager {
|
|||
* @typedef {ApplicationCommand|Snowflake} ApplicationCommandResolvable
|
||||
*/
|
||||
|
||||
/* eslint-disable max-len */
|
||||
/**
|
||||
* Data that resolves to the data of an ApplicationCommand
|
||||
* @typedef {ApplicationCommandData|APIApplicationCommand|JSONEncodable<APIApplicationCommand>} ApplicationCommandDataResolvable
|
||||
* @typedef {ApplicationCommandData|APIApplicationCommand} ApplicationCommandDataResolvable
|
||||
*/
|
||||
/* eslint-enable max-len */
|
||||
|
||||
/**
|
||||
* Options used to fetch data from Discord
|
||||
|
@ -252,6 +250,7 @@ class ApplicationCommandManager extends CachedManager {
|
|||
name: command.name,
|
||||
name_localizations: command.nameLocalizations ?? command.name_localizations,
|
||||
description: command.description,
|
||||
nsfw: command.nsfw,
|
||||
description_localizations: command.descriptionLocalizations ?? command.description_localizations,
|
||||
type: command.type,
|
||||
options: command.options?.map(o => ApplicationCommand.transformOption(o)),
|
||||
|
|
6
node_modules/discord.js/src/managers/ApplicationCommandPermissionsManager.js
generated
vendored
6
node_modules/discord.js/src/managers/ApplicationCommandPermissionsManager.js
generated
vendored
|
@ -112,14 +112,14 @@ class ApplicationCommandPermissionsManager extends BaseManager {
|
|||
* Options used to set permissions for one or more Application Commands in a guild
|
||||
* <warn>Omitting the `command` parameter edits the guild wide permissions
|
||||
* when the manager's `commandId` is `null`</warn>
|
||||
* @typedef {BaseApplicationCommandPermissionsOptions} EditApplicationCommandPermissionsOptions
|
||||
* @typedef {BaseApplicationCommandPermissionsOptions} ApplicationCommandPermissionsEditOptions
|
||||
* @property {ApplicationCommandPermissions[]} permissions The new permissions for the guild or overwrite
|
||||
* @property {string} token The bearer token to use that authorizes the permission edit
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets the permissions for the guild or a command overwrite.
|
||||
* @param {EditApplicationCommandPermissionsOptions} options Options used to set permissions
|
||||
* @param {ApplicationCommandPermissionsEditOptions} options Options used to set permissions
|
||||
* @returns {Promise<ApplicationCommandPermissions[]|Collection<Snowflake, ApplicationCommandPermissions[]>>}
|
||||
* @example
|
||||
* // Set a permission overwrite for a command
|
||||
|
@ -179,7 +179,7 @@ class ApplicationCommandPermissionsManager extends BaseManager {
|
|||
|
||||
/**
|
||||
* Add permissions to a command.
|
||||
* @param {EditApplicationCommandPermissionsOptions} options Options used to add permissions
|
||||
* @param {ApplicationCommandPermissionsEditOptions} options Options used to add permissions
|
||||
* @returns {Promise<ApplicationCommandPermissions[]>}
|
||||
* @example
|
||||
* // Add a rule to block a role from using a command
|
||||
|
|
42
node_modules/discord.js/src/managers/AutoModerationRuleManager.js
generated
vendored
42
node_modules/discord.js/src/managers/AutoModerationRuleManager.js
generated
vendored
|
@ -26,6 +26,24 @@ class AutoModerationRuleManager extends CachedManager {
|
|||
* @name AutoModerationRuleManager#cache
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves an {@link AutoModerationRuleResolvable} to an {@link AutoModerationRule} object.
|
||||
* @method resolve
|
||||
* @memberof AutoModerationRuleManager
|
||||
* @instance
|
||||
* @param {AutoModerationRuleResolvable} autoModerationRule The AutoModerationRule resolvable to resolve
|
||||
* @returns {?AutoModerationRule}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves an {@link AutoModerationRuleResolvable} to a {@link AutoModerationRule} id.
|
||||
* @method resolveId
|
||||
* @memberof AutoModerationRuleManager
|
||||
* @instance
|
||||
* @param {AutoModerationRuleResolvable} autoModerationRule The AutoModerationRule resolvable to resolve
|
||||
* @returns {?Snowflake}
|
||||
*/
|
||||
|
||||
_add(data, cache) {
|
||||
return super._add(data, cache, { extras: [this.guild] });
|
||||
}
|
||||
|
@ -41,6 +59,7 @@ class AutoModerationRuleManager extends CachedManager {
|
|||
* @property {string[]} [allowList] The substrings that will be exempt from triggering
|
||||
* {@link AutoModerationRuleTriggerType.Keyword} and {@link AutoModerationRuleTriggerType.KeywordPreset}
|
||||
* @property {?number} [mentionTotalLimit] The total number of role & user mentions allowed per message
|
||||
* @property {boolean} [mentionRaidProtectionEnabled] Whether to automatically detect mention raids
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -57,6 +76,7 @@ class AutoModerationRuleManager extends CachedManager {
|
|||
* @typedef {Object} AutoModerationActionMetadataOptions
|
||||
* @property {GuildTextChannelResolvable|ThreadChannel} [channel] The channel to which content will be logged
|
||||
* @property {number} [durationSeconds] The timeout duration in seconds
|
||||
* @property {string} [customMessage] The custom message that is shown whenever a message is blocked
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -106,12 +126,14 @@ class AutoModerationRuleManager extends CachedManager {
|
|||
presets: triggerMetadata.presets,
|
||||
allow_list: triggerMetadata.allowList,
|
||||
mention_total_limit: triggerMetadata.mentionTotalLimit,
|
||||
mention_raid_protection_enabled: triggerMetadata.mentionRaidProtectionEnabled,
|
||||
},
|
||||
actions: actions.map(action => ({
|
||||
type: action.type,
|
||||
metadata: {
|
||||
duration_seconds: action.metadata?.durationSeconds,
|
||||
channel_id: action.metadata?.channel && this.guild.channels.resolveId(action.metadata.channel),
|
||||
custom_message: action.metadata?.customMessage,
|
||||
},
|
||||
})),
|
||||
enabled,
|
||||
|
@ -162,12 +184,14 @@ class AutoModerationRuleManager extends CachedManager {
|
|||
presets: triggerMetadata.presets,
|
||||
allow_list: triggerMetadata.allowList,
|
||||
mention_total_limit: triggerMetadata.mentionTotalLimit,
|
||||
mention_raid_protection_enabled: triggerMetadata.mentionRaidProtectionEnabled,
|
||||
},
|
||||
actions: actions?.map(action => ({
|
||||
type: action.type,
|
||||
metadata: {
|
||||
duration_seconds: action.metadata?.durationSeconds,
|
||||
channel_id: action.metadata?.channel && this.guild.channels.resolveId(action.metadata.channel),
|
||||
custom_message: action.metadata?.customMessage,
|
||||
},
|
||||
})),
|
||||
enabled,
|
||||
|
@ -259,24 +283,6 @@ class AutoModerationRuleManager extends CachedManager {
|
|||
const autoModerationRuleId = this.resolveId(autoModerationRule);
|
||||
await this.client.rest.delete(Routes.guildAutoModerationRule(this.guild.id, autoModerationRuleId), { reason });
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves an {@link AutoModerationRuleResolvable} to an {@link AutoModerationRule} object.
|
||||
* @method resolve
|
||||
* @memberof AutoModerationRuleManager
|
||||
* @instance
|
||||
* @param {AutoModerationRuleResolvable} autoModerationRule The AutoModerationRule resolvable to resolve
|
||||
* @returns {?AutoModerationRule}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves an {@link AutoModerationRuleResolvable} to a {@link AutoModerationRule} id.
|
||||
* @method resolveId
|
||||
* @memberof AutoModerationRuleManager
|
||||
* @instance
|
||||
* @param {AutoModerationRuleResolvable} autoModerationRule The AutoModerationRule resolvable to resolve
|
||||
* @returns {?Snowflake}
|
||||
*/
|
||||
}
|
||||
|
||||
module.exports = AutoModerationRuleManager;
|
||||
|
|
4
node_modules/discord.js/src/managers/BaseGuildEmojiManager.js
generated
vendored
4
node_modules/discord.js/src/managers/BaseGuildEmojiManager.js
generated
vendored
|
@ -50,9 +50,9 @@ class BaseGuildEmojiManager extends CachedManager {
|
|||
|
||||
/**
|
||||
* Data that can be resolved to give an emoji identifier. This can be:
|
||||
* * The unicode representation of an emoji
|
||||
* * The `<a:name:id>`, `<:name:id>`, `a:name:id` or `name:id` emoji identifier string of an emoji
|
||||
* * An EmojiResolvable
|
||||
* * The `<a:name:id>`, `<:name:id>`, `a:name:id` or `name:id` emoji identifier string of an emoji
|
||||
* * The Unicode representation of an emoji
|
||||
* @typedef {string|EmojiResolvable} EmojiIdentifierResolvable
|
||||
*/
|
||||
|
||||
|
|
7
node_modules/discord.js/src/managers/CachedManager.js
generated
vendored
7
node_modules/discord.js/src/managers/CachedManager.js
generated
vendored
|
@ -11,6 +11,13 @@ class CachedManager extends DataManager {
|
|||
constructor(client, holds, iterable) {
|
||||
super(client, holds);
|
||||
|
||||
/**
|
||||
* The private cache of items for this manager.
|
||||
* @type {Collection}
|
||||
* @private
|
||||
* @readonly
|
||||
* @name CachedManager#_cache
|
||||
*/
|
||||
Object.defineProperty(this, '_cache', { value: this.client.options.makeCache(this.constructor, this.holds) });
|
||||
|
||||
if (iterable) {
|
||||
|
|
1
node_modules/discord.js/src/managers/CategoryChannelChildManager.js
generated
vendored
1
node_modules/discord.js/src/managers/CategoryChannelChildManager.js
generated
vendored
|
@ -56,6 +56,7 @@ class CategoryChannelChildManager extends DataManager {
|
|||
* @property {ThreadAutoArchiveDuration} [defaultAutoArchiveDuration]
|
||||
* The default auto archive duration for all new threads in this channel
|
||||
* @property {SortOrderType} [defaultSortOrder] The default sort order mode used to order posts (forum only).
|
||||
* @property {ForumLayoutType} [defaultForumLayout] The default layout used to display posts (forum only).
|
||||
* @property {string} [reason] Reason for creating the new channel
|
||||
*/
|
||||
|
||||
|
|
6
node_modules/discord.js/src/managers/ChannelManager.js
generated
vendored
6
node_modules/discord.js/src/managers/ChannelManager.js
generated
vendored
|
@ -36,10 +36,10 @@ class ChannelManager extends CachedManager {
|
|||
* @name ChannelManager#cache
|
||||
*/
|
||||
|
||||
_add(data, guild, { cache = true, allowUnknownGuild = false, fromInteraction = false } = {}) {
|
||||
_add(data, guild, { cache = true, allowUnknownGuild = false } = {}) {
|
||||
const existing = this.cache.get(data.id);
|
||||
if (existing) {
|
||||
if (cache) existing._patch(data, fromInteraction);
|
||||
if (cache) existing._patch(data);
|
||||
guild?.channels?._add(existing);
|
||||
if (ThreadChannelTypes.includes(existing.type)) {
|
||||
existing.parent?.threads?._add(existing);
|
||||
|
@ -47,7 +47,7 @@ class ChannelManager extends CachedManager {
|
|||
return existing;
|
||||
}
|
||||
|
||||
const channel = createChannel(this.client, data, guild, { allowUnknownGuild, fromInteraction });
|
||||
const channel = createChannel(this.client, data, guild, { allowUnknownGuild });
|
||||
|
||||
if (!channel) {
|
||||
this.client.emit(Events.Debug, `Failed to find guild, or unknown type for channel ${data.id} ${data.type}`);
|
||||
|
|
6
node_modules/discord.js/src/managers/GuildBanManager.js
generated
vendored
6
node_modules/discord.js/src/managers/GuildBanManager.js
generated
vendored
|
@ -12,7 +12,7 @@ const { GuildMember } = require('../structures/GuildMember');
|
|||
let deprecationEmittedForDeleteMessageDays = false;
|
||||
|
||||
/**
|
||||
* Manages API methods for GuildBans and stores their cache.
|
||||
* Manages API methods for guild bans and stores their cache.
|
||||
* @extends {CachedManager}
|
||||
*/
|
||||
class GuildBanManager extends CachedManager {
|
||||
|
@ -103,7 +103,7 @@ class GuildBanManager extends CachedManager {
|
|||
const resolvedUser = this.client.users.resolveId(user ?? options);
|
||||
if (resolvedUser) return this._fetchSingle({ user: resolvedUser, cache, force });
|
||||
|
||||
if (!before && !after && !limit && typeof cache === 'undefined') {
|
||||
if (!before && !after && !limit && cache === undefined) {
|
||||
return Promise.reject(new DiscordjsError(ErrorCodes.FetchBanResolveId));
|
||||
}
|
||||
|
||||
|
@ -156,7 +156,7 @@ class GuildBanManager extends CachedManager {
|
|||
const id = this.client.users.resolveId(user);
|
||||
if (!id) throw new DiscordjsError(ErrorCodes.BanResolveId, true);
|
||||
|
||||
if (typeof options.deleteMessageDays !== 'undefined' && !deprecationEmittedForDeleteMessageDays) {
|
||||
if (options.deleteMessageDays !== undefined && !deprecationEmittedForDeleteMessageDays) {
|
||||
process.emitWarning(
|
||||
// eslint-disable-next-line max-len
|
||||
'The deleteMessageDays option for GuildBanManager#create() is deprecated. Use the deleteMessageSeconds option instead.',
|
||||
|
|
66
node_modules/discord.js/src/managers/GuildChannelManager.js
generated
vendored
66
node_modules/discord.js/src/managers/GuildChannelManager.js
generated
vendored
|
@ -161,6 +161,7 @@ class GuildChannelManager extends CachedManager {
|
|||
defaultReactionEmoji,
|
||||
defaultAutoArchiveDuration,
|
||||
defaultSortOrder,
|
||||
defaultForumLayout,
|
||||
reason,
|
||||
}) {
|
||||
parent &&= this.client.channels.resolveId(parent);
|
||||
|
@ -184,6 +185,7 @@ class GuildChannelManager extends CachedManager {
|
|||
default_reaction_emoji: defaultReactionEmoji && transformGuildDefaultReaction(defaultReactionEmoji),
|
||||
default_auto_archive_duration: defaultAutoArchiveDuration,
|
||||
default_sort_order: defaultSortOrder,
|
||||
default_forum_layout: defaultForumLayout,
|
||||
},
|
||||
reason,
|
||||
});
|
||||
|
@ -192,7 +194,7 @@ class GuildChannelManager extends CachedManager {
|
|||
|
||||
/**
|
||||
* @typedef {ChannelWebhookCreateOptions} WebhookCreateOptions
|
||||
* @property {TextChannel|NewsChannel|VoiceChannel|ForumChannel|Snowflake} channel
|
||||
* @property {TextChannel|NewsChannel|VoiceChannel|StageChannel|ForumChannel|Snowflake} channel
|
||||
* The channel to create the webhook for
|
||||
*/
|
||||
|
||||
|
@ -252,13 +254,14 @@ class GuildChannelManager extends CachedManager {
|
|||
* @property {number} [defaultThreadRateLimitPerUser] The rate limit per user (slowmode) to set on forum posts
|
||||
* @property {ChannelFlagsResolvable} [flags] The flags to set on the channel
|
||||
* @property {?SortOrderType} [defaultSortOrder] The default sort order mode to set on the channel
|
||||
* @property {ForumLayoutType} [defaultForumLayout] The default forum layout to set on the channel
|
||||
* @property {string} [reason] Reason for editing this channel
|
||||
*/
|
||||
|
||||
/**
|
||||
* Edits the channel.
|
||||
* @param {GuildChannelResolvable} channel The channel to edit
|
||||
* @param {GuildChannelEditOptions} data Options for editing the channel
|
||||
* @param {GuildChannelEditOptions} options Options for editing the channel
|
||||
* @returns {Promise<GuildChannel>}
|
||||
* @example
|
||||
* // Edit a channel
|
||||
|
@ -266,19 +269,19 @@ class GuildChannelManager extends CachedManager {
|
|||
* .then(console.log)
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async edit(channel, data) {
|
||||
async edit(channel, options) {
|
||||
channel = this.resolve(channel);
|
||||
if (!channel) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
|
||||
|
||||
const parent = data.parent && this.client.channels.resolveId(data.parent);
|
||||
const parent = options.parent && this.client.channels.resolveId(options.parent);
|
||||
|
||||
if (typeof data.position !== 'undefined') {
|
||||
await this.setPosition(channel, data.position, { position: data.position, reason: data.reason });
|
||||
if (options.position !== undefined) {
|
||||
await this.setPosition(channel, options.position, { position: options.position, reason: options.reason });
|
||||
}
|
||||
|
||||
let permission_overwrites = data.permissionOverwrites?.map(o => PermissionOverwrites.resolve(o, this.guild));
|
||||
let permission_overwrites = options.permissionOverwrites?.map(o => PermissionOverwrites.resolve(o, this.guild));
|
||||
|
||||
if (data.lockPermissions) {
|
||||
if (options.lockPermissions) {
|
||||
if (parent) {
|
||||
const newParent = this.guild.channels.resolve(parent);
|
||||
if (newParent?.type === ChannelType.GuildCategory) {
|
||||
|
@ -295,26 +298,28 @@ class GuildChannelManager extends CachedManager {
|
|||
|
||||
const newData = await this.client.rest.patch(Routes.channel(channel.id), {
|
||||
body: {
|
||||
name: (data.name ?? channel.name).trim(),
|
||||
type: data.type,
|
||||
topic: data.topic,
|
||||
nsfw: data.nsfw,
|
||||
bitrate: data.bitrate ?? channel.bitrate,
|
||||
user_limit: data.userLimit ?? channel.userLimit,
|
||||
rtc_region: 'rtcRegion' in data ? data.rtcRegion : channel.rtcRegion,
|
||||
video_quality_mode: data.videoQualityMode,
|
||||
name: (options.name ?? channel.name).trim(),
|
||||
type: options.type,
|
||||
topic: options.topic,
|
||||
nsfw: options.nsfw,
|
||||
bitrate: options.bitrate ?? channel.bitrate,
|
||||
user_limit: options.userLimit ?? channel.userLimit,
|
||||
rtc_region: 'rtcRegion' in options ? options.rtcRegion : channel.rtcRegion,
|
||||
video_quality_mode: options.videoQualityMode,
|
||||
parent_id: parent,
|
||||
lock_permissions: data.lockPermissions,
|
||||
rate_limit_per_user: data.rateLimitPerUser,
|
||||
default_auto_archive_duration: data.defaultAutoArchiveDuration,
|
||||
lock_permissions: options.lockPermissions,
|
||||
rate_limit_per_user: options.rateLimitPerUser,
|
||||
default_auto_archive_duration: options.defaultAutoArchiveDuration,
|
||||
permission_overwrites,
|
||||
available_tags: data.availableTags?.map(availableTag => transformGuildForumTag(availableTag)),
|
||||
default_reaction_emoji: data.defaultReactionEmoji && transformGuildDefaultReaction(data.defaultReactionEmoji),
|
||||
default_thread_rate_limit_per_user: data.defaultThreadRateLimitPerUser,
|
||||
flags: 'flags' in data ? ChannelFlagsBitField.resolve(data.flags) : undefined,
|
||||
default_sort_order: data.defaultSortOrder,
|
||||
available_tags: options.availableTags?.map(availableTag => transformGuildForumTag(availableTag)),
|
||||
default_reaction_emoji:
|
||||
options.defaultReactionEmoji && transformGuildDefaultReaction(options.defaultReactionEmoji),
|
||||
default_thread_rate_limit_per_user: options.defaultThreadRateLimitPerUser,
|
||||
flags: 'flags' in options ? ChannelFlagsBitField.resolve(options.flags) : undefined,
|
||||
default_sort_order: options.defaultSortOrder,
|
||||
default_forum_layout: options.defaultForumLayout,
|
||||
},
|
||||
reason: data.reason,
|
||||
reason: options.reason,
|
||||
});
|
||||
|
||||
return this.client.actions.ChannelUpdate.handle(newData).updated;
|
||||
|
@ -435,7 +440,7 @@ class GuildChannelManager extends CachedManager {
|
|||
id: this.client.channels.resolveId(r.channel),
|
||||
position: r.position,
|
||||
lock_permissions: r.lockPermissions,
|
||||
parent_id: typeof r.parent !== 'undefined' ? this.resolveId(r.parent) : undefined,
|
||||
parent_id: r.parent !== undefined ? this.resolveId(r.parent) : undefined,
|
||||
}));
|
||||
|
||||
await this.client.rest.patch(Routes.guildChannels(this.guild.id), { body: channelPositions });
|
||||
|
@ -446,7 +451,14 @@ class GuildChannelManager extends CachedManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Obtains all active thread channels in the guild from Discord
|
||||
* Data returned from fetching threads.
|
||||
* @typedef {Object} FetchedThreads
|
||||
* @property {Collection<Snowflake, ThreadChannel>} threads The threads that were fetched
|
||||
* @property {Collection<Snowflake, ThreadMember>} members The thread members in the received threads
|
||||
*/
|
||||
|
||||
/**
|
||||
* Obtains all active thread channels in the guild.
|
||||
* @param {boolean} [cache=true] Whether to cache the fetched data
|
||||
* @returns {Promise<FetchedThreads>}
|
||||
* @example
|
||||
|
|
14
node_modules/discord.js/src/managers/GuildEmojiManager.js
generated
vendored
14
node_modules/discord.js/src/managers/GuildEmojiManager.js
generated
vendored
|
@ -124,19 +124,19 @@ class GuildEmojiManager extends BaseGuildEmojiManager {
|
|||
/**
|
||||
* Edits an emoji.
|
||||
* @param {EmojiResolvable} emoji The Emoji resolvable to edit
|
||||
* @param {GuildEmojiEditData} data The new data for the emoji
|
||||
* @param {GuildEmojiEditOptions} options The options to provide
|
||||
* @returns {Promise<GuildEmoji>}
|
||||
*/
|
||||
async edit(emoji, data) {
|
||||
async edit(emoji, options) {
|
||||
const id = this.resolveId(emoji);
|
||||
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true);
|
||||
const roles = data.roles?.map(r => this.guild.roles.resolveId(r));
|
||||
const roles = options.roles?.map(r => this.guild.roles.resolveId(r));
|
||||
const newData = await this.client.rest.patch(Routes.guildEmoji(this.guild.id, id), {
|
||||
body: {
|
||||
name: data.name,
|
||||
name: options.name,
|
||||
roles,
|
||||
},
|
||||
reason: data.reason,
|
||||
reason: options.reason,
|
||||
});
|
||||
const existing = this.cache.get(id);
|
||||
if (existing) {
|
||||
|
@ -161,8 +161,8 @@ class GuildEmojiManager extends BaseGuildEmojiManager {
|
|||
|
||||
const { me } = this.guild.members;
|
||||
if (!me) throw new DiscordjsError(ErrorCodes.GuildUncachedMe);
|
||||
if (!me.permissions.has(PermissionFlagsBits.ManageEmojisAndStickers)) {
|
||||
throw new DiscordjsError(ErrorCodes.MissingManageEmojisAndStickersPermission, this.guild);
|
||||
if (!me.permissions.has(PermissionFlagsBits.ManageGuildExpressions)) {
|
||||
throw new DiscordjsError(ErrorCodes.MissingManageGuildExpressionsPermission, this.guild);
|
||||
}
|
||||
|
||||
const data = await this.client.rest.get(Routes.guildEmoji(this.guild.id, emoji.id));
|
||||
|
|
3
node_modules/discord.js/src/managers/GuildForumThreadManager.js
generated
vendored
3
node_modules/discord.js/src/managers/GuildForumThreadManager.js
generated
vendored
|
@ -18,8 +18,9 @@ class GuildForumThreadManager extends ThreadManager {
|
|||
|
||||
/**
|
||||
* @typedef {BaseMessageOptions} GuildForumThreadMessageCreateOptions
|
||||
* @property {stickers} [stickers] The stickers to send with the message
|
||||
* @property {StickerResolvable} [stickers] The stickers to send with the message
|
||||
* @property {BitFieldResolvable} [flags] The flags to send with the message
|
||||
* <info>Only `MessageFlags.SuppressEmbeds` and `MessageFlags.SuppressNotifications` can be set.</info>
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
2
node_modules/discord.js/src/managers/GuildInviteManager.js
generated
vendored
2
node_modules/discord.js/src/managers/GuildInviteManager.js
generated
vendored
|
@ -167,7 +167,7 @@ class GuildInviteManager extends CachedManager {
|
|||
/**
|
||||
* Create an invite to the guild from the provided channel.
|
||||
* @param {GuildInvitableChannelResolvable} channel The options for creating the invite from a channel.
|
||||
* @param {CreateInviteOptions} [options={}] The options for creating the invite from a channel.
|
||||
* @param {InviteCreateOptions} [options={}] The options for creating the invite from a channel.
|
||||
* @returns {Promise<Invite>}
|
||||
* @example
|
||||
* // Create an invite to a selected channel
|
||||
|
|
129
node_modules/discord.js/src/managers/GuildManager.js
generated
vendored
129
node_modules/discord.js/src/managers/GuildManager.js
generated
vendored
|
@ -57,14 +57,14 @@ class GuildManager extends CachedManager {
|
|||
/**
|
||||
* Partial data for a Role.
|
||||
* @typedef {Object} PartialRoleData
|
||||
* @property {Snowflake|number} [id] The role's id, used to set channel overrides,
|
||||
* this is a placeholder and will be replaced by the API after consumption
|
||||
* @property {Snowflake|number} [id] The role's id, used to set channel overrides.
|
||||
* This is a placeholder and will be replaced by the API after consumption
|
||||
* @property {string} [name] The name of the role
|
||||
* @property {ColorResolvable} [color] The color of the role, either a hex string or a base 10 number
|
||||
* @property {boolean} [hoist] Whether or not the role should be hoisted
|
||||
* @property {boolean} [hoist] Whether the role should be hoisted
|
||||
* @property {number} [position] The position of the role
|
||||
* @property {PermissionResolvable} [permissions] The permissions of the role
|
||||
* @property {boolean} [mentionable] Whether or not the role should be mentionable
|
||||
* @property {boolean} [mentionable] Whether the role should be mentionable
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -79,8 +79,8 @@ class GuildManager extends CachedManager {
|
|||
/**
|
||||
* Partial data for a Channel.
|
||||
* @typedef {Object} PartialChannelData
|
||||
* @property {Snowflake|number} [id] The channel's id, used to set its parent,
|
||||
* this is a placeholder and will be replaced by the API after consumption
|
||||
* @property {Snowflake|number} [id] The channel's id, used to set its parent.
|
||||
* This is a placeholder and will be replaced by the API after consumption
|
||||
* @property {Snowflake|number} [parentId] The parent id for this channel
|
||||
* @property {ChannelType.GuildText|ChannelType.GuildVoice|ChannelType.GuildCategory} [type] The type of the channel
|
||||
* @property {string} name The name of the channel
|
||||
|
@ -141,18 +141,18 @@ class GuildManager extends CachedManager {
|
|||
* Options used to create a guild.
|
||||
* @typedef {Object} GuildCreateOptions
|
||||
* @property {string} name The name of the guild
|
||||
* @property {Snowflake|number} [afkChannelId] The AFK channel's id
|
||||
* @property {number} [afkTimeout] The AFK timeout in seconds
|
||||
* @property {PartialChannelData[]} [channels=[]] The channels for this guild
|
||||
* @property {?(BufferResolvable|Base64Resolvable)} [icon=null] The icon for the guild
|
||||
* @property {GuildVerificationLevel} [verificationLevel] The verification level for the guild
|
||||
* @property {GuildDefaultMessageNotifications} [defaultMessageNotifications] The default message notifications
|
||||
* for the guild
|
||||
* @property {GuildExplicitContentFilter} [explicitContentFilter] The explicit content filter level for the guild
|
||||
* @property {?(BufferResolvable|Base64Resolvable)} [icon=null] The icon for the guild
|
||||
* @property {PartialRoleData[]} [roles=[]] The roles for this guild,
|
||||
* @property {PartialChannelData[]} [channels=[]] The channels for this guild
|
||||
* @property {Snowflake|number} [afkChannelId] The AFK channel's id
|
||||
* @property {number} [afkTimeout] The AFK timeout in seconds
|
||||
* the first element of this array is used to change properties of the guild's everyone role.
|
||||
* @property {Snowflake|number} [systemChannelId] The system channel's id
|
||||
* @property {SystemChannelFlagsResolvable} [systemChannelFlags] The flags of the system channel
|
||||
* @property {GuildVerificationLevel} [verificationLevel] The verification level for the guild
|
||||
*/
|
||||
/* eslint-enable max-len */
|
||||
|
||||
|
@ -164,81 +164,80 @@ class GuildManager extends CachedManager {
|
|||
*/
|
||||
async create({
|
||||
name,
|
||||
afkChannelId,
|
||||
afkTimeout,
|
||||
channels = [],
|
||||
icon = null,
|
||||
verificationLevel,
|
||||
defaultMessageNotifications,
|
||||
explicitContentFilter,
|
||||
icon = null,
|
||||
roles = [],
|
||||
channels = [],
|
||||
afkChannelId,
|
||||
afkTimeout,
|
||||
systemChannelId,
|
||||
systemChannelFlags,
|
||||
verificationLevel,
|
||||
}) {
|
||||
icon = await DataResolver.resolveImage(icon);
|
||||
|
||||
for (const channel of channels) {
|
||||
channel.parent_id = channel.parentId;
|
||||
delete channel.parentId;
|
||||
channel.user_limit = channel.userLimit;
|
||||
delete channel.userLimit;
|
||||
channel.rate_limit_per_user = channel.rateLimitPerUser;
|
||||
delete channel.rateLimitPerUser;
|
||||
channel.rtc_region = channel.rtcRegion;
|
||||
delete channel.rtcRegion;
|
||||
channel.video_quality_mode = channel.videoQualityMode;
|
||||
delete channel.videoQualityMode;
|
||||
|
||||
if (!channel.permissionOverwrites) continue;
|
||||
for (const overwrite of channel.permissionOverwrites) {
|
||||
overwrite.allow &&= PermissionsBitField.resolve(overwrite.allow).toString();
|
||||
overwrite.deny &&= PermissionsBitField.resolve(overwrite.deny).toString();
|
||||
}
|
||||
channel.permission_overwrites = channel.permissionOverwrites;
|
||||
delete channel.permissionOverwrites;
|
||||
}
|
||||
for (const role of roles) {
|
||||
role.color &&= resolveColor(role.color);
|
||||
role.permissions &&= PermissionsBitField.resolve(role.permissions).toString();
|
||||
}
|
||||
systemChannelFlags &&= SystemChannelFlagsBitField.resolve(systemChannelFlags);
|
||||
|
||||
const data = await this.client.rest.post(Routes.guilds(), {
|
||||
body: {
|
||||
name,
|
||||
icon,
|
||||
icon: icon && (await DataResolver.resolveImage(icon)),
|
||||
verification_level: verificationLevel,
|
||||
default_message_notifications: defaultMessageNotifications,
|
||||
explicit_content_filter: explicitContentFilter,
|
||||
roles,
|
||||
channels,
|
||||
roles: roles.map(({ color, permissions, ...options }) => ({
|
||||
...options,
|
||||
color: color && resolveColor(color),
|
||||
permissions: permissions === undefined ? undefined : PermissionsBitField.resolve(permissions).toString(),
|
||||
})),
|
||||
channels: channels.map(
|
||||
({
|
||||
parentId,
|
||||
userLimit,
|
||||
rtcRegion,
|
||||
videoQualityMode,
|
||||
permissionOverwrites,
|
||||
rateLimitPerUser,
|
||||
...options
|
||||
}) => ({
|
||||
...options,
|
||||
parent_id: parentId,
|
||||
user_limit: userLimit,
|
||||
rtc_region: rtcRegion,
|
||||
video_quality_mode: videoQualityMode,
|
||||
permission_overwrites: permissionOverwrites?.map(({ allow, deny, ...permissionOverwriteOptions }) => ({
|
||||
...permissionOverwriteOptions,
|
||||
allow: allow === undefined ? undefined : PermissionsBitField.resolve(allow).toString(),
|
||||
deny: deny === undefined ? undefined : PermissionsBitField.resolve(deny).toString(),
|
||||
})),
|
||||
rate_limit_per_user: rateLimitPerUser,
|
||||
}),
|
||||
),
|
||||
afk_channel_id: afkChannelId,
|
||||
afk_timeout: afkTimeout,
|
||||
system_channel_id: systemChannelId,
|
||||
system_channel_flags: systemChannelFlags,
|
||||
system_channel_flags:
|
||||
systemChannelFlags === undefined ? undefined : SystemChannelFlagsBitField.resolve(systemChannelFlags),
|
||||
},
|
||||
});
|
||||
|
||||
if (this.client.guilds.cache.has(data.id)) return this.client.guilds.cache.get(data.id);
|
||||
return (
|
||||
this.client.guilds.cache.get(data.id) ??
|
||||
new Promise(resolve => {
|
||||
const handleGuild = guild => {
|
||||
if (guild.id === data.id) {
|
||||
clearTimeout(timeout);
|
||||
this.client.decrementMaxListeners();
|
||||
resolve(guild);
|
||||
}
|
||||
};
|
||||
this.client.incrementMaxListeners();
|
||||
this.client.once(Events.GuildCreate, handleGuild);
|
||||
|
||||
return new Promise(resolve => {
|
||||
const handleGuild = guild => {
|
||||
if (guild.id === data.id) {
|
||||
clearTimeout(timeout);
|
||||
const timeout = setTimeout(() => {
|
||||
this.client.removeListener(Events.GuildCreate, handleGuild);
|
||||
this.client.decrementMaxListeners();
|
||||
resolve(guild);
|
||||
}
|
||||
};
|
||||
this.client.incrementMaxListeners();
|
||||
this.client.on(Events.GuildCreate, handleGuild);
|
||||
|
||||
const timeout = setTimeout(() => {
|
||||
this.client.removeListener(Events.GuildCreate, handleGuild);
|
||||
this.client.decrementMaxListeners();
|
||||
resolve(this.client.guilds._add(data));
|
||||
}, 10_000).unref();
|
||||
});
|
||||
resolve(this.client.guilds._add(data));
|
||||
}, 10_000).unref();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
194
node_modules/discord.js/src/managers/GuildMemberManager.js
generated
vendored
194
node_modules/discord.js/src/managers/GuildMemberManager.js
generated
vendored
|
@ -11,6 +11,7 @@ const BaseGuildVoiceChannel = require('../structures/BaseGuildVoiceChannel');
|
|||
const { GuildMember } = require('../structures/GuildMember');
|
||||
const { Role } = require('../structures/Role');
|
||||
const Events = require('../util/Events');
|
||||
const { GuildMemberFlagsBitField } = require('../util/GuildMemberFlagsBitField');
|
||||
const Partials = require('../util/Partials');
|
||||
|
||||
/**
|
||||
|
@ -158,20 +159,18 @@ class GuildMemberManager extends CachedManager {
|
|||
/**
|
||||
* Options used to fetch multiple members from a guild.
|
||||
* @typedef {Object} FetchMembersOptions
|
||||
* @property {UserResolvable|UserResolvable[]} user The user(s) to fetch
|
||||
* @property {?string} query Limit fetch to members with similar usernames
|
||||
* @property {UserResolvable|UserResolvable[]} [user] The user(s) to fetch
|
||||
* @property {?string} [query] Limit fetch to members with similar usernames
|
||||
* @property {number} [limit=0] Maximum number of members to request
|
||||
* @property {boolean} [withPresences=false] Whether or not to include the presences
|
||||
* @property {boolean} [withPresences=false] Whether to include the presences
|
||||
* @property {number} [time=120e3] Timeout for receipt of members
|
||||
* @property {?string} nonce Nonce for this request (32 characters max - default to base 16 now timestamp)
|
||||
* @property {boolean} [force=false] Whether to skip the cache check and request the API
|
||||
* @property {?string} [nonce] Nonce for this request (32 characters max - default to base 16 now timestamp)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fetches member(s) from Discord, even if they're offline.
|
||||
* @param {UserResolvable|FetchMemberOptions|FetchMembersOptions} [options] If a UserResolvable, the user to fetch.
|
||||
* If undefined, fetches all members.
|
||||
* If a query, it limits the results to users with similar usernames.
|
||||
* Fetches member(s) from a guild.
|
||||
* @param {UserResolvable|FetchMemberOptions|FetchMembersOptions} [options] Options for fetching member(s).
|
||||
* Omitting the parameter or providing `undefined` will fetch all members.
|
||||
* @returns {Promise<GuildMember|Collection<Snowflake, GuildMember>>}
|
||||
* @example
|
||||
* // Fetch all members from a guild
|
||||
|
@ -206,18 +205,70 @@ class GuildMemberManager extends CachedManager {
|
|||
*/
|
||||
fetch(options) {
|
||||
if (!options) return this._fetchMany();
|
||||
const user = this.client.users.resolveId(options);
|
||||
if (user) return this._fetchSingle({ user, cache: true });
|
||||
if (options.user) {
|
||||
if (Array.isArray(options.user)) {
|
||||
options.user = options.user.map(u => this.client.users.resolveId(u));
|
||||
return this._fetchMany(options);
|
||||
} else {
|
||||
options.user = this.client.users.resolveId(options.user);
|
||||
}
|
||||
if (!options.limit && !options.withPresences) return this._fetchSingle(options);
|
||||
const { user: users, limit, withPresences, cache, force } = options;
|
||||
const resolvedUser = this.client.users.resolveId(users ?? options);
|
||||
if (resolvedUser && !limit && !withPresences) return this._fetchSingle({ user: resolvedUser, cache, force });
|
||||
const resolvedUsers = users?.map?.(user => this.client.users.resolveId(user)) ?? resolvedUser ?? undefined;
|
||||
return this._fetchMany({ ...options, users: resolvedUsers });
|
||||
}
|
||||
|
||||
async _fetchSingle({ user, cache, force = false }) {
|
||||
if (!force) {
|
||||
const existing = this.cache.get(user);
|
||||
if (existing && !existing.partial) return existing;
|
||||
}
|
||||
return this._fetchMany(options);
|
||||
|
||||
const data = await this.client.rest.get(Routes.guildMember(this.guild.id, user));
|
||||
return this._add(data, cache);
|
||||
}
|
||||
|
||||
_fetchMany({
|
||||
limit = 0,
|
||||
withPresences: presences,
|
||||
users,
|
||||
query,
|
||||
time = 120e3,
|
||||
nonce = DiscordSnowflake.generate().toString(),
|
||||
} = {}) {
|
||||
if (nonce.length > 32) return Promise.reject(new DiscordjsRangeError(ErrorCodes.MemberFetchNonceLength));
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!query && !users) query = '';
|
||||
this.guild.shard.send({
|
||||
op: GatewayOpcodes.RequestGuildMembers,
|
||||
d: {
|
||||
guild_id: this.guild.id,
|
||||
presences,
|
||||
user_ids: users,
|
||||
query,
|
||||
nonce,
|
||||
limit,
|
||||
},
|
||||
});
|
||||
const fetchedMembers = new Collection();
|
||||
let i = 0;
|
||||
const handler = (members, _, chunk) => {
|
||||
if (chunk.nonce !== nonce) return;
|
||||
timeout.refresh();
|
||||
i++;
|
||||
for (const member of members.values()) {
|
||||
fetchedMembers.set(member.id, member);
|
||||
}
|
||||
if (members.size < 1_000 || (limit && fetchedMembers.size >= limit) || i === chunk.count) {
|
||||
clearTimeout(timeout);
|
||||
this.client.removeListener(Events.GuildMembersChunk, handler);
|
||||
this.client.decrementMaxListeners();
|
||||
resolve(users && !Array.isArray(users) && fetchedMembers.size ? fetchedMembers.first() : fetchedMembers);
|
||||
}
|
||||
};
|
||||
const timeout = setTimeout(() => {
|
||||
this.client.removeListener(Events.GuildMembersChunk, handler);
|
||||
this.client.decrementMaxListeners();
|
||||
reject(new DiscordjsError(ErrorCodes.GuildMembersTimeout));
|
||||
}, time).unref();
|
||||
this.client.incrementMaxListeners();
|
||||
this.client.on(Events.GuildMembersChunk, handler);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -270,7 +321,7 @@ class GuildMemberManager extends CachedManager {
|
|||
|
||||
/**
|
||||
* The data for editing a guild member.
|
||||
* @typedef {Object} GuildMemberEditData
|
||||
* @typedef {Object} GuildMemberEditOptions
|
||||
* @property {?string} [nick] The nickname to set for the member
|
||||
* @property {Collection<Snowflake, Role>|RoleResolvable[]} [roles] The roles or role ids to apply
|
||||
* @property {boolean} [mute] Whether or not the member should be muted
|
||||
|
@ -279,6 +330,7 @@ class GuildMemberManager extends CachedManager {
|
|||
* (if they are connected to voice), or `null` if you want to disconnect them from voice
|
||||
* @property {DateResolvable|null} [communicationDisabledUntil] The date or timestamp
|
||||
* for the member's communication to be disabled until. Provide `null` to enable communication again.
|
||||
* @property {GuildMemberFlagsResolvable} [flags] The flags to set for the member
|
||||
* @property {string} [reason] Reason for editing this user
|
||||
*/
|
||||
|
||||
|
@ -286,43 +338,47 @@ class GuildMemberManager extends CachedManager {
|
|||
* Edits a member of the guild.
|
||||
* <info>The user must be a member of the guild</info>
|
||||
* @param {UserResolvable} user The member to edit
|
||||
* @param {GuildMemberEditData} data The data to edit the member with
|
||||
* @param {GuildMemberEditOptions} options The options to provide
|
||||
* @returns {Promise<GuildMember>}
|
||||
*/
|
||||
async edit(user, { reason, ...data }) {
|
||||
async edit(user, { reason, ...options }) {
|
||||
const id = this.client.users.resolveId(user);
|
||||
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'user', 'UserResolvable');
|
||||
|
||||
if (data.channel) {
|
||||
data.channel = this.guild.channels.resolve(data.channel);
|
||||
if (!(data.channel instanceof BaseGuildVoiceChannel)) {
|
||||
if (options.channel) {
|
||||
options.channel = this.guild.channels.resolve(options.channel);
|
||||
if (!(options.channel instanceof BaseGuildVoiceChannel)) {
|
||||
throw new DiscordjsError(ErrorCodes.GuildVoiceChannelResolve);
|
||||
}
|
||||
data.channel_id = data.channel.id;
|
||||
data.channel = undefined;
|
||||
} else if (data.channel === null) {
|
||||
data.channel_id = null;
|
||||
data.channel = undefined;
|
||||
options.channel_id = options.channel.id;
|
||||
options.channel = undefined;
|
||||
} else if (options.channel === null) {
|
||||
options.channel_id = null;
|
||||
options.channel = undefined;
|
||||
}
|
||||
data.roles &&= data.roles.map(role => (role instanceof Role ? role.id : role));
|
||||
options.roles &&= options.roles.map(role => (role instanceof Role ? role.id : role));
|
||||
|
||||
if (typeof data.communicationDisabledUntil !== 'undefined') {
|
||||
data.communication_disabled_until =
|
||||
if (options.communicationDisabledUntil !== undefined) {
|
||||
options.communication_disabled_until =
|
||||
// eslint-disable-next-line eqeqeq
|
||||
data.communicationDisabledUntil != null
|
||||
? new Date(data.communicationDisabledUntil).toISOString()
|
||||
: data.communicationDisabledUntil;
|
||||
options.communicationDisabledUntil != null
|
||||
? new Date(options.communicationDisabledUntil).toISOString()
|
||||
: options.communicationDisabledUntil;
|
||||
}
|
||||
|
||||
if (options.flags !== undefined) {
|
||||
options.flags = GuildMemberFlagsBitField.resolve(options.flags);
|
||||
}
|
||||
|
||||
let endpoint;
|
||||
if (id === this.client.user.id) {
|
||||
const keys = Object.keys(data);
|
||||
const keys = Object.keys(options);
|
||||
if (keys.length === 1 && keys[0] === 'nick') endpoint = Routes.guildMember(this.guild.id);
|
||||
else endpoint = Routes.guildMember(this.guild.id, id);
|
||||
} else {
|
||||
endpoint = Routes.guildMember(this.guild.id, id);
|
||||
}
|
||||
const d = await this.client.rest.patch(endpoint, { body: data, reason });
|
||||
const d = await this.client.rest.patch(endpoint, { body: options, reason });
|
||||
|
||||
const clone = this.cache.get(id)?._clone();
|
||||
clone?._patch(d);
|
||||
|
@ -479,66 +535,6 @@ class GuildMemberManager extends CachedManager {
|
|||
|
||||
return this.resolve(user) ?? this.client.users.resolve(user) ?? userId;
|
||||
}
|
||||
|
||||
async _fetchSingle({ user, cache, force = false }) {
|
||||
if (!force) {
|
||||
const existing = this.cache.get(user);
|
||||
if (existing && !existing.partial) return existing;
|
||||
}
|
||||
|
||||
const data = await this.client.rest.get(Routes.guildMember(this.guild.id, user));
|
||||
return this._add(data, cache);
|
||||
}
|
||||
|
||||
_fetchMany({
|
||||
limit = 0,
|
||||
withPresences: presences = false,
|
||||
user: user_ids,
|
||||
query,
|
||||
time = 120e3,
|
||||
nonce = DiscordSnowflake.generate().toString(),
|
||||
} = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!query && !user_ids) query = '';
|
||||
if (nonce.length > 32) throw new DiscordjsRangeError(ErrorCodes.MemberFetchNonceLength);
|
||||
this.guild.shard.send({
|
||||
op: GatewayOpcodes.RequestGuildMembers,
|
||||
d: {
|
||||
guild_id: this.guild.id,
|
||||
presences,
|
||||
user_ids,
|
||||
query,
|
||||
nonce,
|
||||
limit,
|
||||
},
|
||||
});
|
||||
const fetchedMembers = new Collection();
|
||||
let i = 0;
|
||||
const handler = (members, _, chunk) => {
|
||||
timeout.refresh();
|
||||
if (chunk.nonce !== nonce) return;
|
||||
i++;
|
||||
for (const member of members.values()) {
|
||||
fetchedMembers.set(member.id, member);
|
||||
}
|
||||
if (members.size < 1_000 || (limit && fetchedMembers.size >= limit) || i === chunk.count) {
|
||||
clearTimeout(timeout);
|
||||
this.client.removeListener(Events.GuildMembersChunk, handler);
|
||||
this.client.decrementMaxListeners();
|
||||
let fetched = fetchedMembers;
|
||||
if (user_ids && !Array.isArray(user_ids) && fetched.size) fetched = fetched.first();
|
||||
resolve(fetched);
|
||||
}
|
||||
};
|
||||
const timeout = setTimeout(() => {
|
||||
this.client.removeListener(Events.GuildMembersChunk, handler);
|
||||
this.client.decrementMaxListeners();
|
||||
reject(new DiscordjsError(ErrorCodes.GuildMembersTimeout));
|
||||
}, time).unref();
|
||||
this.client.incrementMaxListeners();
|
||||
this.client.on(Events.GuildMembersChunk, handler);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildMemberManager;
|
||||
|
|
6
node_modules/discord.js/src/managers/GuildScheduledEventManager.js
generated
vendored
6
node_modules/discord.js/src/managers/GuildScheduledEventManager.js
generated
vendored
|
@ -85,12 +85,12 @@ class GuildScheduledEventManager extends CachedManager {
|
|||
|
||||
let entity_metadata, channel_id;
|
||||
if (entityType === GuildScheduledEventEntityType.External) {
|
||||
channel_id = typeof channel === 'undefined' ? channel : null;
|
||||
channel_id = channel === undefined ? channel : null;
|
||||
entity_metadata = { location: entityMetadata?.location };
|
||||
} else {
|
||||
channel_id = this.guild.channels.resolveId(channel);
|
||||
if (!channel_id) throw new DiscordjsError(ErrorCodes.GuildVoiceChannelResolve);
|
||||
entity_metadata = typeof entityMetadata === 'undefined' ? entityMetadata : null;
|
||||
entity_metadata = entityMetadata === undefined ? entityMetadata : null;
|
||||
}
|
||||
|
||||
const data = await this.client.rest.post(Routes.guildScheduledEvents(this.guild.id), {
|
||||
|
@ -214,7 +214,7 @@ class GuildScheduledEventManager extends CachedManager {
|
|||
|
||||
const data = await this.client.rest.patch(Routes.guildScheduledEvent(this.guild.id, guildScheduledEventId), {
|
||||
body: {
|
||||
channel_id: typeof channel === 'undefined' ? channel : this.guild.channels.resolveId(channel),
|
||||
channel_id: channel === undefined ? channel : this.guild.channels.resolveId(channel),
|
||||
name,
|
||||
privacy_level: privacyLevel,
|
||||
scheduled_start_time: scheduledStartTime ? new Date(scheduledStartTime).toISOString() : undefined,
|
||||
|
|
10
node_modules/discord.js/src/managers/GuildStickerManager.js
generated
vendored
10
node_modules/discord.js/src/managers/GuildStickerManager.js
generated
vendored
|
@ -35,7 +35,7 @@ class GuildStickerManager extends CachedManager {
|
|||
/**
|
||||
* Options used to create a guild sticker.
|
||||
* @typedef {Object} GuildStickerCreateOptions
|
||||
* @property {BufferResolvable|Stream|JSONEncodable<AttachmentPayload>} file The file for the sticker
|
||||
* @property {AttachmentPayload|BufferResolvable|Stream} file The file for the sticker
|
||||
* @property {string} name The name for the sticker
|
||||
* @property {string} tags The Discord name of a unicode emoji representing the sticker's expression
|
||||
* @property {?string} [description] The description for the sticker
|
||||
|
@ -101,16 +101,16 @@ class GuildStickerManager extends CachedManager {
|
|||
/**
|
||||
* Edits a sticker.
|
||||
* @param {StickerResolvable} sticker The sticker to edit
|
||||
* @param {GuildStickerEditData} [data={}] The new data for the sticker
|
||||
* @param {GuildStickerEditOptions} [options={}] The new data for the sticker
|
||||
* @returns {Promise<Sticker>}
|
||||
*/
|
||||
async edit(sticker, data = {}) {
|
||||
async edit(sticker, options = {}) {
|
||||
const stickerId = this.resolveId(sticker);
|
||||
if (!stickerId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'sticker', 'StickerResolvable');
|
||||
|
||||
const d = await this.client.rest.patch(Routes.guildSticker(this.guild.id, stickerId), {
|
||||
body: data,
|
||||
reason: data.reason,
|
||||
body: options,
|
||||
reason: options.reason,
|
||||
});
|
||||
|
||||
const existing = this.cache.get(stickerId);
|
||||
|
|
3
node_modules/discord.js/src/managers/MessageManager.js
generated
vendored
3
node_modules/discord.js/src/managers/MessageManager.js
generated
vendored
|
@ -49,6 +49,7 @@ class MessageManager extends CachedManager {
|
|||
|
||||
/**
|
||||
* Options used to fetch multiple messages.
|
||||
* <info>The `before`, `after`, and `around` parameters are mutually exclusive.</info>
|
||||
* @typedef {Object} FetchMessagesOptions
|
||||
* @property {number} [limit] The maximum number of messages to return
|
||||
* @property {Snowflake} [before] Consider only messages before this id
|
||||
|
@ -150,7 +151,7 @@ class MessageManager extends CachedManager {
|
|||
/**
|
||||
* Options that can be passed to edit a message.
|
||||
* @typedef {BaseMessageOptions} MessageEditOptions
|
||||
* @property {Array<JSONEncodable<AttachmentPayload>>} [attachments] An array of attachments to keep,
|
||||
* @property {AttachmentPayload[]} [attachments] An array of attachments to keep,
|
||||
* all attachments will be kept if omitted
|
||||
* @property {MessageFlags} [flags] Which flags to set for the message
|
||||
* <info>Only the {@link MessageFlags.SuppressEmbeds} flag can be modified.</info>
|
||||
|
|
1
node_modules/discord.js/src/managers/ReactionManager.js
generated
vendored
1
node_modules/discord.js/src/managers/ReactionManager.js
generated
vendored
|
@ -33,6 +33,7 @@ class ReactionManager extends CachedManager {
|
|||
* Data that can be resolved to a MessageReaction object. This can be:
|
||||
* * A MessageReaction
|
||||
* * A Snowflake
|
||||
* * The Unicode representation of an emoji
|
||||
* @typedef {MessageReaction|Snowflake} MessageReactionResolvable
|
||||
*/
|
||||
|
||||
|
|
39
node_modules/discord.js/src/managers/RoleManager.js
generated
vendored
39
node_modules/discord.js/src/managers/RoleManager.js
generated
vendored
|
@ -100,7 +100,7 @@ class RoleManager extends CachedManager {
|
|||
|
||||
/**
|
||||
* Options used to create a new role.
|
||||
* @typedef {Object} CreateRoleOptions
|
||||
* @typedef {Object} RoleCreateOptions
|
||||
* @property {string} [name] The name of the new role
|
||||
* @property {ColorResolvable} [color] The data to create the role with
|
||||
* @property {boolean} [hoist] Whether or not the new role should be hoisted
|
||||
|
@ -117,7 +117,7 @@ class RoleManager extends CachedManager {
|
|||
/**
|
||||
* Creates a new role in the guild with given information.
|
||||
* <warn>The position will silently reset to 1 if an invalid one is provided, or none.</warn>
|
||||
* @param {CreateRoleOptions} [options] Options for creating the new role
|
||||
* @param {RoleCreateOptions} [options] Options for creating the new role
|
||||
* @returns {Promise<Role>}
|
||||
* @example
|
||||
* // Create a new role
|
||||
|
@ -137,7 +137,7 @@ class RoleManager extends CachedManager {
|
|||
async create(options = {}) {
|
||||
let { name, color, hoist, permissions, position, mentionable, reason, icon, unicodeEmoji } = options;
|
||||
color &&= resolveColor(color);
|
||||
if (typeof permissions !== 'undefined') permissions = new PermissionsBitField(permissions);
|
||||
if (permissions !== undefined) permissions = new PermissionsBitField(permissions);
|
||||
if (icon) {
|
||||
const guildEmojiURL = this.guild.emojis.resolve(icon)?.url;
|
||||
icon = guildEmojiURL ? await DataResolver.resolveImage(guildEmojiURL) : await DataResolver.resolveImage(icon);
|
||||
|
@ -166,14 +166,14 @@ class RoleManager extends CachedManager {
|
|||
|
||||
/**
|
||||
* Options for editing a role
|
||||
* @typedef {RoleData} EditRoleOptions
|
||||
* @typedef {RoleData} RoleEditOptions
|
||||
* @property {string} [reason] The reason for editing this role
|
||||
*/
|
||||
|
||||
/**
|
||||
* Edits a role of the guild.
|
||||
* @param {RoleResolvable} role The role to edit
|
||||
* @param {EditRoleOptions} data The new data for the role
|
||||
* @param {RoleEditOptions} options The options to provide
|
||||
* @returns {Promise<Role>}
|
||||
* @example
|
||||
* // Edit a role
|
||||
|
@ -181,15 +181,15 @@ class RoleManager extends CachedManager {
|
|||
* .then(updated => console.log(`Edited role name to ${updated.name}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async edit(role, data) {
|
||||
async edit(role, options) {
|
||||
role = this.resolve(role);
|
||||
if (!role) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'role', 'RoleResolvable');
|
||||
|
||||
if (typeof data.position === 'number') {
|
||||
await this.setPosition(role, data.position, { reason: data.reason });
|
||||
if (typeof options.position === 'number') {
|
||||
await this.setPosition(role, options.position, { reason: options.reason });
|
||||
}
|
||||
|
||||
let icon = data.icon;
|
||||
let icon = options.icon;
|
||||
if (icon) {
|
||||
const guildEmojiURL = this.guild.emojis.resolve(icon)?.url;
|
||||
icon = guildEmojiURL ? await DataResolver.resolveImage(guildEmojiURL) : await DataResolver.resolveImage(icon);
|
||||
|
@ -197,16 +197,16 @@ class RoleManager extends CachedManager {
|
|||
}
|
||||
|
||||
const body = {
|
||||
name: data.name,
|
||||
color: typeof data.color === 'undefined' ? undefined : resolveColor(data.color),
|
||||
hoist: data.hoist,
|
||||
permissions: typeof data.permissions === 'undefined' ? undefined : new PermissionsBitField(data.permissions),
|
||||
mentionable: data.mentionable,
|
||||
name: options.name,
|
||||
color: options.color === undefined ? undefined : resolveColor(options.color),
|
||||
hoist: options.hoist,
|
||||
permissions: options.permissions === undefined ? undefined : new PermissionsBitField(options.permissions),
|
||||
mentionable: options.mentionable,
|
||||
icon,
|
||||
unicode_emoji: data.unicodeEmoji,
|
||||
unicode_emoji: options.unicodeEmoji,
|
||||
};
|
||||
|
||||
const d = await this.client.rest.patch(Routes.guildRole(this.guild.id, role.id), { body, reason: data.reason });
|
||||
const d = await this.client.rest.patch(Routes.guildRole(this.guild.id, role.id), { body, reason: options.reason });
|
||||
|
||||
const clone = role._clone();
|
||||
clone._patch(d);
|
||||
|
@ -307,11 +307,14 @@ class RoleManager extends CachedManager {
|
|||
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'role', 'Role nor a Snowflake');
|
||||
}
|
||||
|
||||
if (resolvedRole1.position === resolvedRole2.position) {
|
||||
const role1Position = resolvedRole1.position;
|
||||
const role2Position = resolvedRole2.position;
|
||||
|
||||
if (role1Position === role2Position) {
|
||||
return Number(BigInt(resolvedRole2.id) - BigInt(resolvedRole1.id));
|
||||
}
|
||||
|
||||
return resolvedRole1.position - resolvedRole2.position;
|
||||
return role1Position - role2Position;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
53
node_modules/discord.js/src/managers/ThreadManager.js
generated
vendored
53
node_modules/discord.js/src/managers/ThreadManager.js
generated
vendored
|
@ -75,10 +75,9 @@ class ThreadManager extends CachedManager {
|
|||
*/
|
||||
|
||||
/**
|
||||
* The options for fetching multiple threads, the properties are mutually exclusive
|
||||
* Options for fetching multiple threads.
|
||||
* @typedef {Object} FetchThreadsOptions
|
||||
* @property {FetchArchivedThreadOptions} [archived] The options used to fetch archived threads
|
||||
* @property {boolean} [active] When true, fetches active threads. <warn>If `archived` is set, this is ignored!</warn>
|
||||
* @property {FetchArchivedThreadOptions} [archived] Options used to fetch archived threads
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -87,17 +86,18 @@ class ThreadManager extends CachedManager {
|
|||
* ThreadChannelResolvable then the specified thread will be fetched. Fetches all active threads if `undefined`
|
||||
* @param {BaseFetchOptions} [cacheOptions] Additional options for this fetch. <warn>The `force` field gets ignored
|
||||
* if `options` is not a {@link ThreadChannelResolvable}</warn>
|
||||
* @returns {Promise<?(ThreadChannel|FetchedThreads)>}
|
||||
* @returns {Promise<?(ThreadChannel|FetchedThreads|FetchedThreadsMore)>}
|
||||
* {@link FetchedThreads} if active & {@link FetchedThreadsMore} if archived.
|
||||
* @example
|
||||
* // Fetch a thread by its id
|
||||
* channel.threads.fetch('831955138126104859')
|
||||
* .then(channel => console.log(channel.name))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
fetch(options, { cache = true, force = false } = {}) {
|
||||
fetch(options, { cache, force } = {}) {
|
||||
if (!options) return this.fetchActive(cache);
|
||||
const channel = this.client.channels.resolveId(options);
|
||||
if (channel) return this.client.channels.fetch(channel, cache, force);
|
||||
if (channel) return this.client.channels.fetch(channel, { cache, force });
|
||||
if (options.archived) {
|
||||
return this.fetchArchived(options.archived, cache);
|
||||
}
|
||||
|
@ -118,16 +118,15 @@ class ThreadManager extends CachedManager {
|
|||
* @property {string} [type='public'] The type of threads to fetch (`public` or `private`)
|
||||
* @property {boolean} [fetchAll=false] Whether to fetch **all** archived threads when `type` is `private`
|
||||
* <info>This property requires the {@link PermissionFlagsBits.ManageThreads} permission if `true`.</info>
|
||||
* @property {DateResolvable|ThreadChannelResolvable} [before] Only return threads that were created before this Date
|
||||
* @property {DateResolvable|ThreadChannelResolvable} [before] Only return threads that were archived before this Date
|
||||
* or Snowflake
|
||||
* <warn>Must be a {@link ThreadChannelResolvable} when `type` is `private` and `fetchAll` is `false`.</warn>
|
||||
* @property {number} [limit] Maximum number of threads to return
|
||||
*/
|
||||
|
||||
/**
|
||||
* The data returned from a thread fetch that returns multiple threads.
|
||||
* @typedef {Object} FetchedThreads
|
||||
* @property {Collection<Snowflake, ThreadChannel>} threads The threads that were fetched, with any members returned
|
||||
* Data returned from fetching multiple threads.
|
||||
* @typedef {FetchedThreads} FetchedThreadsMore
|
||||
* @property {?boolean} hasMore Whether there are potentially additional threads that require a subsequent call
|
||||
*/
|
||||
|
||||
|
@ -137,7 +136,7 @@ class ThreadManager extends CachedManager {
|
|||
* in the parent channel.</info>
|
||||
* @param {FetchArchivedThreadOptions} [options] The options to fetch archived threads
|
||||
* @param {boolean} [cache=true] Whether to cache the new thread objects if they aren't already
|
||||
* @returns {Promise<FetchedThreads>}
|
||||
* @returns {Promise<FetchedThreadsMore>}
|
||||
*/
|
||||
async fetchArchived({ type = 'public', fetchAll = false, before, limit } = {}, cache = true) {
|
||||
let path = Routes.channelThreads(this.channel.id, type);
|
||||
|
@ -147,8 +146,8 @@ class ThreadManager extends CachedManager {
|
|||
let timestamp;
|
||||
let id;
|
||||
const query = makeURLSearchParams({ limit });
|
||||
if (typeof before !== 'undefined') {
|
||||
if (before instanceof ThreadChannel || /^\d{16,19}$/.test(String(before))) {
|
||||
if (before !== undefined) {
|
||||
if (before instanceof ThreadChannel || /^\d{17,19}$/.test(String(before))) {
|
||||
id = this.resolveId(before);
|
||||
timestamp = this.resolve(before)?.archivedAt?.toISOString();
|
||||
const toUse = type === 'private' && !fetchAll ? id : timestamp;
|
||||
|
@ -172,15 +171,13 @@ class ThreadManager extends CachedManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Obtains the accessible active threads from Discord.
|
||||
* <info>This method requires the {@link PermissionFlagsBits.ReadMessageHistory} permission
|
||||
* in the parent channel.</info>
|
||||
* @param {boolean} [cache=true] Whether to cache the new thread objects if they aren't already
|
||||
* Obtains all active thread channels in the guild.
|
||||
* This internally calls {@link GuildChannelManager#fetchActiveThreads}.
|
||||
* @param {boolean} [cache=true] Whether to cache the fetched data
|
||||
* @returns {Promise<FetchedThreads>}
|
||||
*/
|
||||
async fetchActive(cache = true) {
|
||||
const raw = await this.client.rest.get(Routes.guildActiveThreads(this.channel.guild.id));
|
||||
return this.constructor._mapThreads(raw, this.client, { parent: this.channel, cache });
|
||||
fetchActive(cache = true) {
|
||||
return this.channel.guild.channels.fetchActiveThreads(cache);
|
||||
}
|
||||
|
||||
static _mapThreads(rawThreads, client, { parent, guild, cache }) {
|
||||
|
@ -189,12 +186,18 @@ class ThreadManager extends CachedManager {
|
|||
if (parent && thread.parentId !== parent.id) return coll;
|
||||
return coll.set(thread.id, thread);
|
||||
}, new Collection());
|
||||
|
||||
// Discord sends the thread id as id in this object
|
||||
for (const rawMember of rawThreads.members) client.channels.cache.get(rawMember.id)?.members._add(rawMember);
|
||||
return {
|
||||
threads,
|
||||
hasMore: rawThreads.has_more ?? false,
|
||||
};
|
||||
const threadMembers = rawThreads.members.reduce(
|
||||
(coll, raw) => coll.set(raw.user_id, threads.get(raw.id).members._add(raw)),
|
||||
new Collection(),
|
||||
);
|
||||
|
||||
const response = { threads, members: threadMembers };
|
||||
|
||||
// The GET `/guilds/{guild.id}/threads/active` route does not return `has_more`.
|
||||
if ('has_more' in rawThreads) response.hasMore = rawThreads.has_more;
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
47
node_modules/discord.js/src/managers/ThreadMemberManager.js
generated
vendored
47
node_modules/discord.js/src/managers/ThreadMemberManager.js
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { makeURLSearchParams } = require('@discordjs/rest');
|
||||
const { Routes } = require('discord-api-types/v10');
|
||||
const CachedManager = require('./CachedManager');
|
||||
const { DiscordjsTypeError, ErrorCodes } = require('../errors');
|
||||
|
@ -29,10 +30,10 @@ class ThreadMemberManager extends CachedManager {
|
|||
|
||||
_add(data, cache = true) {
|
||||
const existing = this.cache.get(data.user_id);
|
||||
if (cache) existing?._patch(data);
|
||||
if (cache) existing?._patch(data, { cache });
|
||||
if (existing) return existing;
|
||||
|
||||
const member = new ThreadMember(this.thread, data);
|
||||
const member = new ThreadMember(this.thread, data, { cache });
|
||||
if (cache) this.cache.set(data.user_id, member);
|
||||
return member;
|
||||
}
|
||||
|
@ -112,15 +113,35 @@ class ThreadMemberManager extends CachedManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Options used to fetch a thread member.
|
||||
* @typedef {BaseFetchOptions} FetchThreadMemberOptions
|
||||
* @property {ThreadMemberResolvable} member The thread member to fetch
|
||||
* @property {boolean} [withMember] Whether to also return the guild member associated with this thread member
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} FetchThreadMembersOptions
|
||||
* Options used to fetch multiple thread members with guild member data.
|
||||
* <info>With `withMember` set to `true`, pagination is enabled.</info>
|
||||
* @typedef {Object} FetchThreadMembersWithGuildMemberDataOptions
|
||||
* @property {true} withMember Whether to also return the guild member data
|
||||
* @property {Snowflake} [after] Consider only thread members after this id
|
||||
* @property {number} [limit] The maximum number of thread members to return
|
||||
* @property {boolean} [cache] Whether to cache the fetched thread members and guild members
|
||||
*/
|
||||
|
||||
/**
|
||||
* Options used to fetch multiple thread members without guild member data.
|
||||
* @typedef {Object} FetchThreadMembersWithoutGuildMemberDataOptions
|
||||
* @property {false} [withMember] Whether to also return the guild member data
|
||||
* @property {boolean} [cache] Whether to cache the fetched thread members
|
||||
*/
|
||||
|
||||
/**
|
||||
* Options used to fetch multiple thread members.
|
||||
* @typedef {FetchThreadMembersWithGuildMemberDataOptions|
|
||||
* FetchThreadMembersWithoutGuildMemberDataOptions} FetchThreadMembersOptions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fetches thread member(s) from Discord.
|
||||
* <info>This method requires the {@link GatewayIntentBits.GuildMembers} privileged gateway intent.</info>
|
||||
|
@ -130,25 +151,31 @@ class ThreadMemberManager extends CachedManager {
|
|||
*/
|
||||
fetch(options) {
|
||||
if (!options) return this._fetchMany();
|
||||
const { member, cache, force } = options;
|
||||
const { member, withMember, cache, force } = options;
|
||||
const resolvedMember = this.resolveId(member ?? options);
|
||||
if (resolvedMember) return this._fetchSingle({ member: resolvedMember, cache, force });
|
||||
if (resolvedMember) return this._fetchSingle({ member: resolvedMember, withMember, cache, force });
|
||||
return this._fetchMany(options);
|
||||
}
|
||||
|
||||
async _fetchSingle({ member, cache, force = false }) {
|
||||
async _fetchSingle({ member, withMember, cache, force = false }) {
|
||||
if (!force) {
|
||||
const existing = this.cache.get(member);
|
||||
if (existing) return existing;
|
||||
}
|
||||
|
||||
const data = await this.client.rest.get(Routes.threadMembers(this.thread.id, member));
|
||||
const data = await this.client.rest.get(Routes.threadMembers(this.thread.id, member), {
|
||||
query: makeURLSearchParams({ with_member: withMember }),
|
||||
});
|
||||
|
||||
return this._add(data, cache);
|
||||
}
|
||||
|
||||
async _fetchMany(options = {}) {
|
||||
const data = await this.client.rest.get(Routes.threadMembers(this.thread.id));
|
||||
return data.reduce((col, member) => col.set(member.user_id, this._add(member, options.cache)), new Collection());
|
||||
async _fetchMany({ withMember, after, limit, cache } = {}) {
|
||||
const data = await this.client.rest.get(Routes.threadMembers(this.thread.id), {
|
||||
query: makeURLSearchParams({ with_member: withMember, after, limit }),
|
||||
});
|
||||
|
||||
return data.reduce((col, member) => col.set(member.user_id, this._add(member, cache)), new Collection());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
37
node_modules/discord.js/src/sharding/Shard.js
generated
vendored
37
node_modules/discord.js/src/sharding/Shard.js
generated
vendored
|
@ -21,8 +21,14 @@ class Shard extends EventEmitter {
|
|||
constructor(manager, id) {
|
||||
super();
|
||||
|
||||
if (manager.mode === 'process') childProcess = require('node:child_process');
|
||||
else if (manager.mode === 'worker') Worker = require('node:worker_threads').Worker;
|
||||
switch (manager.mode) {
|
||||
case 'process':
|
||||
childProcess = require('node:child_process');
|
||||
break;
|
||||
case 'worker':
|
||||
Worker = require('node:worker_threads').Worker;
|
||||
break;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manager that created the shard
|
||||
|
@ -112,18 +118,21 @@ class Shard extends EventEmitter {
|
|||
|
||||
this._exitListener = this._handleExit.bind(this, undefined, timeout);
|
||||
|
||||
if (this.manager.mode === 'process') {
|
||||
this.process = childProcess
|
||||
.fork(path.resolve(this.manager.file), this.args, {
|
||||
env: this.env,
|
||||
execArgv: this.execArgv,
|
||||
})
|
||||
.on('message', this._handleMessage.bind(this))
|
||||
.on('exit', this._exitListener);
|
||||
} else if (this.manager.mode === 'worker') {
|
||||
this.worker = new Worker(path.resolve(this.manager.file), { workerData: this.env })
|
||||
.on('message', this._handleMessage.bind(this))
|
||||
.on('exit', this._exitListener);
|
||||
switch (this.manager.mode) {
|
||||
case 'process':
|
||||
this.process = childProcess
|
||||
.fork(path.resolve(this.manager.file), this.args, {
|
||||
env: this.env,
|
||||
execArgv: this.execArgv,
|
||||
})
|
||||
.on('message', this._handleMessage.bind(this))
|
||||
.on('exit', this._exitListener);
|
||||
break;
|
||||
case 'worker':
|
||||
this.worker = new Worker(path.resolve(this.manager.file), { workerData: this.env })
|
||||
.on('message', this._handleMessage.bind(this))
|
||||
.on('exit', this._exitListener);
|
||||
break;
|
||||
}
|
||||
|
||||
this._evals.clear();
|
||||
|
|
71
node_modules/discord.js/src/sharding/ShardClientUtil.js
generated
vendored
71
node_modules/discord.js/src/sharding/ShardClientUtil.js
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const process = require('node:process');
|
||||
const { calculateShardId } = require('@discordjs/util');
|
||||
const { DiscordjsError, DiscordjsTypeError, ErrorCodes } = require('../errors');
|
||||
const Events = require('../util/Events');
|
||||
const { makeError, makePlainError } = require('../util/Util');
|
||||
|
@ -29,29 +30,32 @@ class ShardClientUtil {
|
|||
*/
|
||||
this.parentPort = null;
|
||||
|
||||
if (mode === 'process') {
|
||||
process.on('message', this._handleMessage.bind(this));
|
||||
client.on('ready', () => {
|
||||
process.send({ _ready: true });
|
||||
});
|
||||
client.on('disconnect', () => {
|
||||
process.send({ _disconnect: true });
|
||||
});
|
||||
client.on('reconnecting', () => {
|
||||
process.send({ _reconnecting: true });
|
||||
});
|
||||
} else if (mode === 'worker') {
|
||||
this.parentPort = require('node:worker_threads').parentPort;
|
||||
this.parentPort.on('message', this._handleMessage.bind(this));
|
||||
client.on('ready', () => {
|
||||
this.parentPort.postMessage({ _ready: true });
|
||||
});
|
||||
client.on('disconnect', () => {
|
||||
this.parentPort.postMessage({ _disconnect: true });
|
||||
});
|
||||
client.on('reconnecting', () => {
|
||||
this.parentPort.postMessage({ _reconnecting: true });
|
||||
});
|
||||
switch (mode) {
|
||||
case 'process':
|
||||
process.on('message', this._handleMessage.bind(this));
|
||||
client.on(Events.ShardReady, () => {
|
||||
process.send({ _ready: true });
|
||||
});
|
||||
client.on(Events.ShardDisconnect, () => {
|
||||
process.send({ _disconnect: true });
|
||||
});
|
||||
client.on(Events.ShardReconnecting, () => {
|
||||
process.send({ _reconnecting: true });
|
||||
});
|
||||
break;
|
||||
case 'worker':
|
||||
this.parentPort = require('node:worker_threads').parentPort;
|
||||
this.parentPort.on('message', this._handleMessage.bind(this));
|
||||
client.on(Events.ShardReady, () => {
|
||||
this.parentPort.postMessage({ _ready: true });
|
||||
});
|
||||
client.on(Events.ShardDisconnect, () => {
|
||||
this.parentPort.postMessage({ _disconnect: true });
|
||||
});
|
||||
client.on(Events.ShardReconnecting, () => {
|
||||
this.parentPort.postMessage({ _reconnecting: true });
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,14 +85,17 @@ class ShardClientUtil {
|
|||
*/
|
||||
send(message) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.mode === 'process') {
|
||||
process.send(message, err => {
|
||||
if (err) reject(err);
|
||||
else resolve();
|
||||
});
|
||||
} else if (this.mode === 'worker') {
|
||||
this.parentPort.postMessage(message);
|
||||
resolve();
|
||||
switch (this.mode) {
|
||||
case 'process':
|
||||
process.send(message, err => {
|
||||
if (err) reject(err);
|
||||
else resolve();
|
||||
});
|
||||
break;
|
||||
case 'worker':
|
||||
this.parentPort.postMessage(message);
|
||||
resolve();
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -245,7 +252,7 @@ class ShardClientUtil {
|
|||
* @returns {number}
|
||||
*/
|
||||
static shardIdForGuildId(guildId, shardCount) {
|
||||
const shard = Number(BigInt(guildId) >> 22n) % shardCount;
|
||||
const shard = calculateShardId(guildId, shardCount);
|
||||
if (shard < 0) throw new DiscordjsError(ErrorCodes.ShardingShardMiscalculation, shard, guildId, shardCount);
|
||||
return shard;
|
||||
}
|
||||
|
|
20
node_modules/discord.js/src/structures/ActionRow.js
generated
vendored
20
node_modules/discord.js/src/structures/ActionRow.js
generated
vendored
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const { deprecate } = require('node:util');
|
||||
const { isJSONEncodable } = require('@discordjs/builders');
|
||||
const { isJSONEncodable } = require('@discordjs/util');
|
||||
const Component = require('./Component');
|
||||
const { createComponent } = require('../util/Components');
|
||||
|
||||
|
@ -23,16 +23,16 @@ class ActionRow extends Component {
|
|||
|
||||
/**
|
||||
* Creates a new action row builder from JSON data
|
||||
* @param {JSONEncodable<APIActionRowComponent>|APIActionRowComponent} other The other data
|
||||
* @method from
|
||||
* @memberof ActionRow
|
||||
* @param {ActionRowBuilder|ActionRow|APIActionRowComponent} other The other data
|
||||
* @returns {ActionRowBuilder}
|
||||
* @deprecated Use {@link ActionRowBuilder.from()} instead.
|
||||
* @deprecated Use {@link ActionRowBuilder.from} instead.
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
}
|
||||
return new this(other);
|
||||
}
|
||||
static from = deprecate(
|
||||
other => new this(isJSONEncodable(other) ? other.toJSON() : other),
|
||||
'ActionRow.from() is deprecated. Use ActionRowBuilder.from() instead.',
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns the API-compatible JSON for this component
|
||||
|
@ -43,6 +43,4 @@ class ActionRow extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
ActionRow.from = deprecate(ActionRow.from, 'ActionRow.from() is deprecated. Use ActionRowBuilder.from() instead.');
|
||||
|
||||
module.exports = ActionRow;
|
||||
|
|
13
node_modules/discord.js/src/structures/ActionRowBuilder.js
generated
vendored
13
node_modules/discord.js/src/structures/ActionRowBuilder.js
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const { ActionRowBuilder: BuildersActionRow, isJSONEncodable } = require('@discordjs/builders');
|
||||
const { ActionRowBuilder: BuildersActionRow } = require('@discordjs/builders');
|
||||
const { isJSONEncodable } = require('@discordjs/util');
|
||||
const { createComponentBuilder } = require('../util/Components');
|
||||
const { toSnakeCase } = require('../util/Transformers');
|
||||
|
||||
|
@ -18,15 +19,11 @@ class ActionRowBuilder extends BuildersActionRow {
|
|||
|
||||
/**
|
||||
* Creates a new action row builder from JSON data
|
||||
* @param {JSONEncodable<APIActionRowComponent<APIActionRowComponentTypes>>
|
||||
* |APIActionRowComponent<APIActionRowComponentTypes>} other The other data
|
||||
* @param {ActionRow|ActionRowBuilder|APIActionRowComponent} other The other data
|
||||
* @returns {ActionRowBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
}
|
||||
return new this(other);
|
||||
return new this(isJSONEncodable(other) ? other.toJSON() : other);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,5 +31,5 @@ module.exports = ActionRowBuilder;
|
|||
|
||||
/**
|
||||
* @external BuildersActionRow
|
||||
* @see {@link https://discord.js.org/#/docs/builders/main/class/ActionRowBuilder}
|
||||
* @see {@link https://discord.js.org/docs/packages/builders/stable/ActionRowBuilder:Class}
|
||||
*/
|
||||
|
|
17
node_modules/discord.js/src/structures/ApplicationCommand.js
generated
vendored
17
node_modules/discord.js/src/structures/ApplicationCommand.js
generated
vendored
|
@ -52,6 +52,12 @@ class ApplicationCommand extends Base {
|
|||
*/
|
||||
this.type = data.type;
|
||||
|
||||
/**
|
||||
* Whether this command is age-restricted (18+)
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.nsfw = data.nsfw ?? false;
|
||||
|
||||
this._patch(data);
|
||||
}
|
||||
|
||||
|
@ -188,6 +194,7 @@ class ApplicationCommand extends Base {
|
|||
* {@link ApplicationCommandType.ChatInput}
|
||||
* @property {Object<Locale, string>} [nameLocalizations] The localizations for the command name
|
||||
* @property {string} description The description of the command, if type is {@link ApplicationCommandType.ChatInput}
|
||||
* @property {boolean} [nsfw] Whether the command is age-restricted
|
||||
* @property {Object<Locale, string>} [descriptionLocalizations] The localizations for the command description,
|
||||
* if type is {@link ApplicationCommandType.ChatInput}
|
||||
* @property {ApplicationCommandType} [type=ApplicationCommandType.ChatInput] The type of the command
|
||||
|
@ -377,11 +384,12 @@ class ApplicationCommand extends Base {
|
|||
('description' in command && command.description !== this.description) ||
|
||||
('version' in command && command.version !== this.version) ||
|
||||
(command.type && command.type !== this.type) ||
|
||||
('nsfw' in command && command.nsfw !== this.nsfw) ||
|
||||
// Future proof for options being nullable
|
||||
// TODO: remove ?? 0 on each when nullable
|
||||
(command.options?.length ?? 0) !== (this.options?.length ?? 0) ||
|
||||
defaultMemberPermissions !== (this.defaultMemberPermissions?.bitfield ?? null) ||
|
||||
(typeof dmPermission !== 'undefined' && dmPermission !== this.dmPermission) ||
|
||||
(dmPermission !== undefined && dmPermission !== this.dmPermission) ||
|
||||
!isEqual(command.nameLocalizations ?? command.name_localizations ?? {}, this.nameLocalizations ?? {}) ||
|
||||
!isEqual(
|
||||
command.descriptionLocalizations ?? command.description_localizations ?? {},
|
||||
|
@ -510,7 +518,7 @@ class ApplicationCommand extends Base {
|
|||
* {@link ApplicationCommandOptionType.Number} option
|
||||
* @property {ApplicationCommandOptionChoice[]} [choices] The choices of the option for the user to pick from
|
||||
* @property {ApplicationCommandOption[]} [options] Additional options if this option is a subcommand (group)
|
||||
* @property {ChannelType[]} [channelTypes] When the option type is channel,
|
||||
* @property {ApplicationCommandOptionAllowedChannelTypes[]} [channelTypes] When the option type is channel,
|
||||
* the allowed types of channels that can be selected
|
||||
* @property {number} [minValue] The minimum value for an {@link ApplicationCommandOptionType.Integer} or
|
||||
* {@link ApplicationCommandOptionType.Number} option
|
||||
|
@ -591,3 +599,8 @@ module.exports = ApplicationCommand;
|
|||
* @external APIApplicationCommandOption
|
||||
* @see {@link https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-option-structure}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external ApplicationCommandOptionAllowedChannelTypes
|
||||
* @see {@link https://discord.js.org/docs/packages/builders/stable/ApplicationCommandOptionAllowedChannelTypes:TypeAlias}
|
||||
*/
|
||||
|
|
46
node_modules/discord.js/src/structures/ApplicationRoleConnectionMetadata.js
generated
vendored
Normal file
46
node_modules/discord.js/src/structures/ApplicationRoleConnectionMetadata.js
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* Role connection metadata object for an application.
|
||||
*/
|
||||
class ApplicationRoleConnectionMetadata {
|
||||
constructor(data) {
|
||||
/**
|
||||
* The name of this metadata field
|
||||
* @type {string}
|
||||
*/
|
||||
this.name = data.name;
|
||||
|
||||
/**
|
||||
* The name localizations for this metadata field
|
||||
* @type {?Object<Locale, string>}
|
||||
*/
|
||||
this.nameLocalizations = data.name_localizations ?? null;
|
||||
|
||||
/**
|
||||
* The description of this metadata field
|
||||
* @type {string}
|
||||
*/
|
||||
this.description = data.description;
|
||||
|
||||
/**
|
||||
* The description localizations for this metadata field
|
||||
* @type {?Object<Locale, string>}
|
||||
*/
|
||||
this.descriptionLocalizations = data.description_localizations ?? null;
|
||||
|
||||
/**
|
||||
* The dictionary key for this metadata field
|
||||
* @type {string}
|
||||
*/
|
||||
this.key = data.key;
|
||||
|
||||
/**
|
||||
* The type of this metadata field
|
||||
* @type {ApplicationRoleConnectionMetadataType}
|
||||
*/
|
||||
this.type = data.type;
|
||||
}
|
||||
}
|
||||
|
||||
exports.ApplicationRoleConnectionMetadata = ApplicationRoleConnectionMetadata;
|
22
node_modules/discord.js/src/structures/Attachment.js
generated
vendored
22
node_modules/discord.js/src/structures/Attachment.js
generated
vendored
|
@ -99,6 +99,28 @@ class Attachment {
|
|||
* @type {boolean}
|
||||
*/
|
||||
this.ephemeral = data.ephemeral ?? false;
|
||||
|
||||
if ('duration_secs' in data) {
|
||||
/**
|
||||
* The duration of this attachment in seconds
|
||||
* <info>This will only be available if the attachment is an audio file.</info>
|
||||
* @type {?number}
|
||||
*/
|
||||
this.duration = data.duration_secs;
|
||||
} else {
|
||||
this.duration ??= null;
|
||||
}
|
||||
|
||||
if ('waveform' in data) {
|
||||
/**
|
||||
* The base64 encoded byte array representing a sampled waveform
|
||||
* <info>This will only be available if the attachment is an audio file.</info>
|
||||
* @type {?string}
|
||||
*/
|
||||
this.waveform = data.waveform;
|
||||
} else {
|
||||
this.waveform ??= null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
2
node_modules/discord.js/src/structures/AttachmentBuilder.js
generated
vendored
2
node_modules/discord.js/src/structures/AttachmentBuilder.js
generated
vendored
|
@ -91,7 +91,7 @@ class AttachmentBuilder {
|
|||
|
||||
/**
|
||||
* Makes a new builder instance from a preexisting attachment structure.
|
||||
* @param {JSONEncodable<AttachmentPayload>} other The builder to construct a new instance from
|
||||
* @param {AttachmentBuilder|Attachment|AttachmentPayload} other The builder to construct a new instance from
|
||||
* @returns {AttachmentBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
|
|
33
node_modules/discord.js/src/structures/AutoModerationActionExecution.js
generated
vendored
33
node_modules/discord.js/src/structures/AutoModerationActionExecution.js
generated
vendored
|
@ -1,5 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const { _transformAPIAutoModerationAction } = require('../util/Transformers');
|
||||
|
||||
/**
|
||||
* Represents the structure of an executed action when an {@link AutoModerationRule} is triggered.
|
||||
*/
|
||||
|
@ -15,7 +17,7 @@ class AutoModerationActionExecution {
|
|||
* The action that was executed.
|
||||
* @type {AutoModerationAction}
|
||||
*/
|
||||
this.action = data.action;
|
||||
this.action = _transformAPIAutoModerationAction(data.action);
|
||||
|
||||
/**
|
||||
* The id of the auto moderation rule this action belongs to.
|
||||
|
@ -43,8 +45,8 @@ class AutoModerationActionExecution {
|
|||
|
||||
/**
|
||||
* The id of the message that triggered this action.
|
||||
* @type {?Snowflake}
|
||||
* <info>This will not be present if the message was blocked or the content was not part of any message.</info>
|
||||
* @type {?Snowflake}
|
||||
*/
|
||||
this.messageId = data.message_id ?? null;
|
||||
|
||||
|
@ -82,6 +84,33 @@ class AutoModerationActionExecution {
|
|||
get autoModerationRule() {
|
||||
return this.guild.autoModerationRules.cache.get(this.ruleId) ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The channel where this action was triggered from.
|
||||
* @type {?TextBasedChannel}
|
||||
* @readonly
|
||||
*/
|
||||
get channel() {
|
||||
return this.guild.channels.cache.get(this.channelId) ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The user that triggered this action.
|
||||
* @type {?User}
|
||||
* @readonly
|
||||
*/
|
||||
get user() {
|
||||
return this.guild.client.users.cache.get(this.userId) ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The guild member that triggered this action.
|
||||
* @type {?GuildMember}
|
||||
* @readonly
|
||||
*/
|
||||
get member() {
|
||||
return this.guild.members.cache.get(this.userId) ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AutoModerationActionExecution;
|
||||
|
|
45
node_modules/discord.js/src/structures/AutoModerationRule.js
generated
vendored
45
node_modules/discord.js/src/structures/AutoModerationRule.js
generated
vendored
|
@ -2,6 +2,7 @@
|
|||
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const Base = require('./Base');
|
||||
const { _transformAPIAutoModerationAction } = require('../util/Transformers');
|
||||
|
||||
/**
|
||||
* Represents an auto moderation rule.
|
||||
|
@ -67,6 +68,7 @@ class AutoModerationRule extends Base {
|
|||
* @property {string[]} allowList The substrings that will be exempt from triggering
|
||||
* {@link AutoModerationRuleTriggerType.Keyword} and {@link AutoModerationRuleTriggerType.KeywordPreset}
|
||||
* @property {?number} mentionTotalLimit The total number of role & user mentions allowed per message
|
||||
* @property {boolean} mentionRaidProtectionEnabled Whether mention raid protection is enabled
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -79,6 +81,7 @@ class AutoModerationRule extends Base {
|
|||
presets: data.trigger_metadata.presets ?? [],
|
||||
allowList: data.trigger_metadata.allow_list ?? [],
|
||||
mentionTotalLimit: data.trigger_metadata.mention_total_limit ?? null,
|
||||
mentionRaidProtectionEnabled: data.trigger_metadata.mention_raid_protection_enabled ?? false,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -95,19 +98,14 @@ class AutoModerationRule extends Base {
|
|||
* @typedef {Object} AutoModerationActionMetadata
|
||||
* @property {?Snowflake} channelId The id of the channel to which content will be logged
|
||||
* @property {?number} durationSeconds The timeout duration in seconds
|
||||
* @property {?string} customMessage The custom message that is shown whenever a message is blocked
|
||||
*/
|
||||
|
||||
/**
|
||||
* The actions of this auto moderation rule.
|
||||
* @type {AutoModerationAction[]}
|
||||
*/
|
||||
this.actions = data.actions.map(action => ({
|
||||
type: action.type,
|
||||
metadata: {
|
||||
durationSeconds: action.metadata.duration_seconds ?? null,
|
||||
channelId: action.metadata.channel_id ?? null,
|
||||
},
|
||||
}));
|
||||
this.actions = data.actions.map(action => _transformAPIAutoModerationAction(action));
|
||||
}
|
||||
|
||||
if ('enabled' in data) {
|
||||
|
@ -184,7 +182,7 @@ class AutoModerationRule extends Base {
|
|||
* @returns {Promise<AutoModerationRule>}
|
||||
*/
|
||||
setKeywordFilter(keywordFilter, reason) {
|
||||
return this.edit({ triggerMetadata: { keywordFilter }, reason });
|
||||
return this.edit({ triggerMetadata: { ...this.triggerMetadata, keywordFilter }, reason });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -195,7 +193,7 @@ class AutoModerationRule extends Base {
|
|||
* @returns {Promise<AutoModerationRule>}
|
||||
*/
|
||||
setRegexPatterns(regexPatterns, reason) {
|
||||
return this.edit({ triggerMetadata: { regexPatterns }, reason });
|
||||
return this.edit({ triggerMetadata: { ...this.triggerMetadata, regexPatterns }, reason });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -205,32 +203,44 @@ class AutoModerationRule extends Base {
|
|||
* @returns {Promise<AutoModerationRule>}
|
||||
*/
|
||||
setPresets(presets, reason) {
|
||||
return this.edit({ triggerMetadata: { presets }, reason });
|
||||
return this.edit({ triggerMetadata: { ...this.triggerMetadata, presets }, reason });
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the allow list for this auto moderation rule.
|
||||
* @param {string[]} allowList The allow list of this auto moderation rule
|
||||
* @param {string[]} allowList The substrings that will be exempt from triggering
|
||||
* {@link AutoModerationRuleTriggerType.Keyword} and {@link AutoModerationRuleTriggerType.KeywordPreset}
|
||||
* @param {string} [reason] The reason for changing the allow list of this auto moderation rule
|
||||
* @returns {Promise<AutoModerationRule>}
|
||||
*/
|
||||
setAllowList(allowList, reason) {
|
||||
return this.edit({ triggerMetadata: { allowList }, reason });
|
||||
return this.edit({ triggerMetadata: { ...this.triggerMetadata, allowList }, reason });
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the mention total limit for this auto moderation rule.
|
||||
* @param {number} mentionTotalLimit The mention total limit of this auto moderation rule
|
||||
* @param {number} mentionTotalLimit The total number of unique role and user mentions allowed per message
|
||||
* @param {string} [reason] The reason for changing the mention total limit of this auto moderation rule
|
||||
* @returns {Promise<AutoModerationRule>}
|
||||
*/
|
||||
setMentionTotalLimit(mentionTotalLimit, reason) {
|
||||
return this.edit({ triggerMetadata: { mentionTotalLimit }, reason });
|
||||
return this.edit({ triggerMetadata: { ...this.triggerMetadata, mentionTotalLimit }, reason });
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether to enable mention raid protection for this auto moderation rule.
|
||||
* @param {boolean} mentionRaidProtectionEnabled
|
||||
* Whether to enable mention raid protection for this auto moderation rule
|
||||
* @param {string} [reason] The reason for changing the mention raid protection of this auto moderation rule
|
||||
* @returns {Promise<AutoModerationRule>}
|
||||
*/
|
||||
setMentionRaidProtectionEnabled(mentionRaidProtectionEnabled, reason) {
|
||||
return this.edit({ triggerMetadata: { ...this.triggerMetadata, mentionRaidProtectionEnabled }, reason });
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the actions for this auto moderation rule.
|
||||
* @param {AutoModerationActionOptions} actions The actions of this auto moderation rule
|
||||
* @param {AutoModerationActionOptions[]} actions The actions of this auto moderation rule
|
||||
* @param {string} [reason] The reason for changing the actions of this auto moderation rule
|
||||
* @returns {Promise<AutoModerationRule>}
|
||||
*/
|
||||
|
@ -250,7 +260,8 @@ class AutoModerationRule extends Base {
|
|||
|
||||
/**
|
||||
* Sets the exempt roles for this auto moderation rule.
|
||||
* @param {Collection<Snowflake, Role>|RoleResolvable[]} [exemptRoles] The exempt roles of this auto moderation rule
|
||||
* @param {Collection<Snowflake, Role>|RoleResolvable[]} [exemptRoles]
|
||||
* The roles that should not be affected by the auto moderation rule
|
||||
* @param {string} [reason] The reason for changing the exempt roles of this auto moderation rule
|
||||
* @returns {Promise<AutoModerationRule>}
|
||||
*/
|
||||
|
@ -261,7 +272,7 @@ class AutoModerationRule extends Base {
|
|||
/**
|
||||
* Sets the exempt channels for this auto moderation rule.
|
||||
* @param {Collection<Snowflake, GuildChannel|ThreadChannel>|GuildChannelResolvable[]} [exemptChannels]
|
||||
* The exempt channels of this auto moderation rule
|
||||
* The channels that should not be affected by the auto moderation rule
|
||||
* @param {string} [reason] The reason for changing the exempt channels of this auto moderation rule
|
||||
* @returns {Promise<AutoModerationRule>}
|
||||
*/
|
||||
|
|
4
node_modules/discord.js/src/structures/AutocompleteInteraction.js
generated
vendored
4
node_modules/discord.js/src/structures/AutocompleteInteraction.js
generated
vendored
|
@ -86,9 +86,7 @@ class AutocompleteInteraction extends BaseInteraction {
|
|||
await this.client.rest.post(Routes.interactionCallback(this.id, this.token), {
|
||||
body: {
|
||||
type: InteractionResponseType.ApplicationCommandAutocompleteResult,
|
||||
data: {
|
||||
choices: options,
|
||||
},
|
||||
data: { choices: this.client.options.jsonTransformer(options) },
|
||||
},
|
||||
auth: false,
|
||||
});
|
||||
|
|
4
node_modules/discord.js/src/structures/BaseGuildTextChannel.js
generated
vendored
4
node_modules/discord.js/src/structures/BaseGuildTextChannel.js
generated
vendored
|
@ -125,7 +125,7 @@ class BaseGuildTextChannel extends GuildChannel {
|
|||
|
||||
/**
|
||||
* Options used to create an invite to a guild channel.
|
||||
* @typedef {Object} CreateInviteOptions
|
||||
* @typedef {Object} InviteCreateOptions
|
||||
* @property {boolean} [temporary] Whether members that joined via the invite should be automatically
|
||||
* kicked after 24 hours if they have not yet received a role
|
||||
* @property {number} [maxAge] How long the invite should last (in seconds, 0 for forever)
|
||||
|
@ -142,7 +142,7 @@ class BaseGuildTextChannel extends GuildChannel {
|
|||
|
||||
/**
|
||||
* Creates an invite to this guild channel.
|
||||
* @param {CreateInviteOptions} [options={}] The options for creating the invite
|
||||
* @param {InviteCreateOptions} [options={}] The options for creating the invite
|
||||
* @returns {Promise<Invite>}
|
||||
* @example
|
||||
* // Create an invite to a channel
|
||||
|
|
138
node_modules/discord.js/src/structures/BaseGuildVoiceChannel.js
generated
vendored
138
node_modules/discord.js/src/structures/BaseGuildVoiceChannel.js
generated
vendored
|
@ -3,12 +3,32 @@
|
|||
const { Collection } = require('@discordjs/collection');
|
||||
const { PermissionFlagsBits } = require('discord-api-types/v10');
|
||||
const GuildChannel = require('./GuildChannel');
|
||||
const TextBasedChannel = require('./interfaces/TextBasedChannel');
|
||||
const MessageManager = require('../managers/MessageManager');
|
||||
|
||||
/**
|
||||
* Represents a voice-based guild channel on Discord.
|
||||
* @extends {GuildChannel}
|
||||
* @implements {TextBasedChannel}
|
||||
*/
|
||||
class BaseGuildVoiceChannel extends GuildChannel {
|
||||
constructor(guild, data, client) {
|
||||
super(guild, data, client, false);
|
||||
/**
|
||||
* A manager of the messages sent to this channel
|
||||
* @type {MessageManager}
|
||||
*/
|
||||
this.messages = new MessageManager(this);
|
||||
|
||||
/**
|
||||
* If the guild considers this channel NSFW
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.nsfw = Boolean(data.nsfw);
|
||||
|
||||
this._patch(data);
|
||||
}
|
||||
|
||||
_patch(data) {
|
||||
super._patch(data);
|
||||
|
||||
|
@ -35,6 +55,40 @@ class BaseGuildVoiceChannel extends GuildChannel {
|
|||
*/
|
||||
this.userLimit = data.user_limit;
|
||||
}
|
||||
|
||||
if ('video_quality_mode' in data) {
|
||||
/**
|
||||
* The camera video quality mode of the channel.
|
||||
* @type {?VideoQualityMode}
|
||||
*/
|
||||
this.videoQualityMode = data.video_quality_mode;
|
||||
} else {
|
||||
this.videoQualityMode ??= null;
|
||||
}
|
||||
|
||||
if ('last_message_id' in data) {
|
||||
/**
|
||||
* The last message id sent in the channel, if one was sent
|
||||
* @type {?Snowflake}
|
||||
*/
|
||||
this.lastMessageId = data.last_message_id;
|
||||
}
|
||||
|
||||
if ('messages' in data) {
|
||||
for (const message of data.messages) this.messages._add(message);
|
||||
}
|
||||
|
||||
if ('rate_limit_per_user' in data) {
|
||||
/**
|
||||
* The rate limit per user (slowmode) for this channel in seconds
|
||||
* @type {number}
|
||||
*/
|
||||
this.rateLimitPerUser = data.rate_limit_per_user;
|
||||
}
|
||||
|
||||
if ('nsfw' in data) {
|
||||
this.nsfw = data.nsfw;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -80,6 +134,44 @@ class BaseGuildVoiceChannel extends GuildChannel {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an invite to this guild channel.
|
||||
* @param {InviteCreateOptions} [options={}] The options for creating the invite
|
||||
* @returns {Promise<Invite>}
|
||||
* @example
|
||||
* // Create an invite to a channel
|
||||
* channel.createInvite()
|
||||
* .then(invite => console.log(`Created an invite with a code of ${invite.code}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
createInvite(options) {
|
||||
return this.guild.invites.create(this.id, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a collection of invites to this guild channel.
|
||||
* @param {boolean} [cache=true] Whether to cache the fetched invites
|
||||
* @returns {Promise<Collection<string, Invite>>}
|
||||
*/
|
||||
fetchInvites(cache = true) {
|
||||
return this.guild.invites.fetch({ channelId: this.id, cache });
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bitrate of the channel.
|
||||
* @param {number} bitrate The new bitrate
|
||||
* @param {string} [reason] Reason for changing the channel's bitrate
|
||||
* @returns {Promise<BaseGuildVoiceChannel>}
|
||||
* @example
|
||||
* // Set the bitrate of a voice channel
|
||||
* channel.setBitrate(48_000)
|
||||
* .then(channel => console.log(`Set bitrate to ${channel.bitrate}bps for ${channel.name}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
setBitrate(bitrate, reason) {
|
||||
return this.edit({ bitrate, reason });
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the RTC region of the channel.
|
||||
* @param {?string} rtcRegion The new region of the channel. Set to `null` to remove a specific region for the channel
|
||||
|
@ -97,28 +189,46 @@ class BaseGuildVoiceChannel extends GuildChannel {
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates an invite to this guild channel.
|
||||
* @param {CreateInviteOptions} [options={}] The options for creating the invite
|
||||
* @returns {Promise<Invite>}
|
||||
* Sets the user limit of the channel.
|
||||
* @param {number} userLimit The new user limit
|
||||
* @param {string} [reason] Reason for changing the user limit
|
||||
* @returns {Promise<BaseGuildVoiceChannel>}
|
||||
* @example
|
||||
* // Create an invite to a channel
|
||||
* channel.createInvite()
|
||||
* .then(invite => console.log(`Created an invite with a code of ${invite.code}`))
|
||||
* // Set the user limit of a voice channel
|
||||
* channel.setUserLimit(42)
|
||||
* .then(channel => console.log(`Set user limit to ${channel.userLimit} for ${channel.name}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
createInvite(options) {
|
||||
return this.guild.invites.create(this.id, options);
|
||||
setUserLimit(userLimit, reason) {
|
||||
return this.edit({ userLimit, reason });
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a collection of invites to this guild channel.
|
||||
* Resolves with a collection mapping invites by their codes.
|
||||
* @param {boolean} [cache=true] Whether or not to cache the fetched invites
|
||||
* @returns {Promise<Collection<string, Invite>>}
|
||||
* Sets the camera video quality mode of the channel.
|
||||
* @param {VideoQualityMode} videoQualityMode The new camera video quality mode.
|
||||
* @param {string} [reason] Reason for changing the camera video quality mode.
|
||||
* @returns {Promise<BaseGuildVoiceChannel>}
|
||||
*/
|
||||
fetchInvites(cache = true) {
|
||||
return this.guild.invites.fetch({ channelId: this.id, cache });
|
||||
setVideoQualityMode(videoQualityMode, reason) {
|
||||
return this.edit({ videoQualityMode, reason });
|
||||
}
|
||||
|
||||
// These are here only for documentation purposes - they are implemented by TextBasedChannel
|
||||
/* eslint-disable no-empty-function */
|
||||
get lastMessage() {}
|
||||
send() {}
|
||||
sendTyping() {}
|
||||
createMessageCollector() {}
|
||||
awaitMessages() {}
|
||||
createMessageComponentCollector() {}
|
||||
awaitMessageComponent() {}
|
||||
bulkDelete() {}
|
||||
fetchWebhooks() {}
|
||||
createWebhook() {}
|
||||
setRateLimitPerUser() {}
|
||||
setNSFW() {}
|
||||
}
|
||||
|
||||
TextBasedChannel.applyToClass(BaseGuildVoiceChannel, true, ['lastPinAt']);
|
||||
|
||||
module.exports = BaseGuildVoiceChannel;
|
||||
|
|
8
node_modules/discord.js/src/structures/BaseInteraction.js
generated
vendored
8
node_modules/discord.js/src/structures/BaseInteraction.js
generated
vendored
|
@ -46,7 +46,7 @@ class BaseInteraction extends Base {
|
|||
* The id of the channel this interaction was sent in
|
||||
* @type {?Snowflake}
|
||||
*/
|
||||
this.channelId = data.channel_id ?? null;
|
||||
this.channelId = data.channel?.id ?? null;
|
||||
|
||||
/**
|
||||
* The id of the guild this interaction was sent in
|
||||
|
@ -270,12 +270,10 @@ class BaseInteraction extends Base {
|
|||
return this.type === InteractionType.MessageComponent && this.componentType === ComponentType.Button;
|
||||
}
|
||||
|
||||
// TODO: Get rid of this in the next major
|
||||
/**
|
||||
* Indicates whether this interaction is a {@link StringSelectMenuInteraction}.
|
||||
* @returns {boolean}
|
||||
*
|
||||
* @deprecated Use {@link Interaction#isStringSelectMenu} instead
|
||||
* @deprecated Use {@link BaseInteraction#isStringSelectMenu} instead.
|
||||
*/
|
||||
isSelectMenu() {
|
||||
return this.isStringSelectMenu();
|
||||
|
@ -322,7 +320,7 @@ class BaseInteraction extends Base {
|
|||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this interaction is a {@link MenionableSelectMenuInteraction}
|
||||
* Indicates whether this interaction is a {@link MentionableSelectMenuInteraction}
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isMentionableSelectMenu() {
|
||||
|
|
4
node_modules/discord.js/src/structures/BaseSelectMenuComponent.js
generated
vendored
4
node_modules/discord.js/src/structures/BaseSelectMenuComponent.js
generated
vendored
|
@ -45,11 +45,11 @@ class BaseSelectMenuComponent extends Component {
|
|||
|
||||
/**
|
||||
* Whether this select menu is disabled
|
||||
* @type {?boolean}
|
||||
* @type {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get disabled() {
|
||||
return this.data.disabled ?? null;
|
||||
return this.data.disabled ?? false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
12
node_modules/discord.js/src/structures/ButtonBuilder.js
generated
vendored
12
node_modules/discord.js/src/structures/ButtonBuilder.js
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const { ButtonBuilder: BuildersButton, isJSONEncodable } = require('@discordjs/builders');
|
||||
const { ButtonBuilder: BuildersButton } = require('@discordjs/builders');
|
||||
const { isJSONEncodable } = require('@discordjs/util');
|
||||
const { toSnakeCase } = require('../util/Transformers');
|
||||
const { resolvePartialEmoji } = require('../util/Util');
|
||||
|
||||
|
@ -27,14 +28,11 @@ class ButtonBuilder extends BuildersButton {
|
|||
|
||||
/**
|
||||
* Creates a new button builder from JSON data
|
||||
* @param {JSONEncodable<APIButtonComponent>|APIButtonComponent} other The other data
|
||||
* @param {ButtonBuilder|ButtonComponent|APIButtonComponent} other The other data
|
||||
* @returns {ButtonBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
}
|
||||
return new this(other);
|
||||
return new this(isJSONEncodable(other) ? other.toJSON() : other);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,5 +40,5 @@ module.exports = ButtonBuilder;
|
|||
|
||||
/**
|
||||
* @external BuildersButton
|
||||
* @see {@link https://discord.js.org/#/docs/builders/main/class/ButtonBuilder}
|
||||
* @see {@link https://discord.js.org/docs/packages/builders/stable/ButtonBuilder:Class}
|
||||
*/
|
||||
|
|
4
node_modules/discord.js/src/structures/ButtonComponent.js
generated
vendored
4
node_modules/discord.js/src/structures/ButtonComponent.js
generated
vendored
|
@ -36,11 +36,11 @@ class ButtonComponent extends Component {
|
|||
|
||||
/**
|
||||
* Whether this button is disabled
|
||||
* @type {?boolean}
|
||||
* @type {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get disabled() {
|
||||
return this.data.disabled ?? null;
|
||||
return this.data.disabled ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
25
node_modules/discord.js/src/structures/CategoryChannel.js
generated
vendored
25
node_modules/discord.js/src/structures/CategoryChannel.js
generated
vendored
|
@ -9,17 +9,21 @@ const CategoryChannelChildManager = require('../managers/CategoryChannelChildMan
|
|||
*/
|
||||
class CategoryChannel extends GuildChannel {
|
||||
/**
|
||||
* A manager of the channels belonging to this category
|
||||
* @type {CategoryChannelChildManager}
|
||||
* The id of the parent of this channel.
|
||||
* @name CategoryChannel#parentId
|
||||
* @type {null}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The parent of this channel.
|
||||
* @name CategoryChannel#parent
|
||||
* @type {null}
|
||||
* @readonly
|
||||
*/
|
||||
get children() {
|
||||
return new CategoryChannelChildManager(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the category parent of this channel.
|
||||
* <warn>It is not currently possible to set the parent of a CategoryChannel.</warn>
|
||||
* <warn>It is not possible to set the parent of a CategoryChannel.</warn>
|
||||
* @method setParent
|
||||
* @memberof CategoryChannel
|
||||
* @instance
|
||||
|
@ -27,6 +31,15 @@ class CategoryChannel extends GuildChannel {
|
|||
* @param {SetParentOptions} [options={}] The options for setting the parent
|
||||
* @returns {Promise<GuildChannel>}
|
||||
*/
|
||||
|
||||
/**
|
||||
* A manager of the channels belonging to this category
|
||||
* @type {CategoryChannelChildManager}
|
||||
* @readonly
|
||||
*/
|
||||
get children() {
|
||||
return new CategoryChannelChildManager(this);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CategoryChannel;
|
||||
|
|
14
node_modules/discord.js/src/structures/ChannelSelectMenuBuilder.js
generated
vendored
14
node_modules/discord.js/src/structures/ChannelSelectMenuBuilder.js
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const { ChannelSelectMenuBuilder: BuildersChannelSelectMenu, isJSONEncodable } = require('@discordjs/builders');
|
||||
const { ChannelSelectMenuBuilder: BuildersChannelSelectMenu } = require('@discordjs/builders');
|
||||
const { isJSONEncodable } = require('@discordjs/util');
|
||||
const { toSnakeCase } = require('../util/Transformers');
|
||||
|
||||
/**
|
||||
|
@ -13,15 +14,12 @@ class ChannelSelectMenuBuilder extends BuildersChannelSelectMenu {
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates a new select menu builder from json data
|
||||
* @param {JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent} other The other data
|
||||
* Creates a new select menu builder from JSON data
|
||||
* @param {ChannelSelectMenuBuilder|ChannelSelectMenuComponent|APIChannelSelectComponent} other The other data
|
||||
* @returns {ChannelSelectMenuBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
}
|
||||
return new this(other);
|
||||
return new this(isJSONEncodable(other) ? other.toJSON() : other);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,5 +27,5 @@ module.exports = ChannelSelectMenuBuilder;
|
|||
|
||||
/**
|
||||
* @external BuildersChannelSelectMenu
|
||||
* @see {@link https://discord.js.org/#/docs/builders/main/class/ChannelSelectMenuBuilder}
|
||||
* @see {@link https://discord.js.org/docs/packages/builders/stable/ChannelSelectMenuBuilder:Class}
|
||||
*/
|
||||
|
|
51
node_modules/discord.js/src/structures/ClientApplication.js
generated
vendored
51
node_modules/discord.js/src/structures/ClientApplication.js
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const { Routes } = require('discord-api-types/v10');
|
||||
const { ApplicationRoleConnectionMetadata } = require('./ApplicationRoleConnectionMetadata');
|
||||
const Team = require('./Team');
|
||||
const Application = require('./interfaces/Application');
|
||||
const ApplicationCommandManager = require('../managers/ApplicationCommandManager');
|
||||
|
@ -108,6 +109,16 @@ class ClientApplication extends Application {
|
|||
this.botPublic ??= null;
|
||||
}
|
||||
|
||||
if ('role_connections_verification_url' in data) {
|
||||
/**
|
||||
* This application's role connection verification entry point URL
|
||||
* @type {?string}
|
||||
*/
|
||||
this.roleConnectionsVerificationURL = data.role_connections_verification_url;
|
||||
} else {
|
||||
this.roleConnectionsVerificationURL ??= null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The owner of this OAuth application
|
||||
* @type {?(User|Team)}
|
||||
|
@ -137,6 +148,46 @@ class ClientApplication extends Application {
|
|||
this._patch(app);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this application's role connection metadata records
|
||||
* @returns {Promise<ApplicationRoleConnectionMetadata[]>}
|
||||
*/
|
||||
async fetchRoleConnectionMetadataRecords() {
|
||||
const metadata = await this.client.rest.get(Routes.applicationRoleConnectionMetadata(this.client.user.id));
|
||||
return metadata.map(data => new ApplicationRoleConnectionMetadata(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data for creating or editing an application role connection metadata.
|
||||
* @typedef {Object} ApplicationRoleConnectionMetadataEditOptions
|
||||
* @property {string} name The name of the metadata field
|
||||
* @property {?Object<Locale, string>} [nameLocalizations] The name localizations for the metadata field
|
||||
* @property {string} description The description of the metadata field
|
||||
* @property {?Object<Locale, string>} [descriptionLocalizations] The description localizations for the metadata field
|
||||
* @property {string} key The dictionary key of the metadata field
|
||||
* @property {ApplicationRoleConnectionMetadataType} type The type of the metadata field
|
||||
*/
|
||||
|
||||
/**
|
||||
* Updates this application's role connection metadata records
|
||||
* @param {ApplicationRoleConnectionMetadataEditOptions[]} records The new role connection metadata records
|
||||
* @returns {Promise<ApplicationRoleConnectionMetadata[]>}
|
||||
*/
|
||||
async editRoleConnectionMetadataRecords(records) {
|
||||
const newRecords = await this.client.rest.put(Routes.applicationRoleConnectionMetadata(this.client.user.id), {
|
||||
body: records.map(record => ({
|
||||
type: record.type,
|
||||
key: record.key,
|
||||
name: record.name,
|
||||
name_localizations: record.nameLocalizations,
|
||||
description: record.description,
|
||||
description_localizations: record.descriptionLocalizations,
|
||||
})),
|
||||
});
|
||||
|
||||
return newRecords.map(data => new ApplicationRoleConnectionMetadata(data));
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ClientApplication;
|
||||
|
|
2
node_modules/discord.js/src/structures/ClientPresence.js
generated
vendored
2
node_modules/discord.js/src/structures/ClientPresence.js
generated
vendored
|
@ -21,7 +21,7 @@ class ClientPresence extends Presence {
|
|||
set(presence) {
|
||||
const packet = this._parse(presence);
|
||||
this._patch(packet);
|
||||
if (typeof presence.shardId === 'undefined') {
|
||||
if (presence.shardId === undefined) {
|
||||
this.client.ws.broadcast({ op: GatewayOpcodes.PresenceUpdate, d: packet });
|
||||
} else if (Array.isArray(presence.shardId)) {
|
||||
for (const shardId of presence.shardId) {
|
||||
|
|
18
node_modules/discord.js/src/structures/ClientUser.js
generated
vendored
18
node_modules/discord.js/src/structures/ClientUser.js
generated
vendored
|
@ -44,22 +44,24 @@ class ClientUser extends User {
|
|||
|
||||
/**
|
||||
* Data used to edit the logged in client
|
||||
* @typedef {Object} ClientUserEditData
|
||||
* @typedef {Object} ClientUserEditOptions
|
||||
* @property {string} [username] The new username
|
||||
* @property {?(BufferResolvable|Base64Resolvable)} [avatar] The new avatar
|
||||
*/
|
||||
|
||||
/**
|
||||
* Edits the logged in client.
|
||||
* @param {ClientUserEditData} data The new data
|
||||
* @param {ClientUserEditOptions} options The options to provide
|
||||
* @returns {Promise<ClientUser>}
|
||||
*/
|
||||
async edit(data) {
|
||||
if (typeof data.avatar !== 'undefined') data.avatar = await DataResolver.resolveImage(data.avatar);
|
||||
const newData = await this.client.rest.patch(Routes.user(), { body: data });
|
||||
this.client.token = newData.token;
|
||||
this.client.rest.setToken(newData.token);
|
||||
const { updated } = this.client.actions.UserUpdate.handle(newData);
|
||||
async edit({ username, avatar }) {
|
||||
const data = await this.client.rest.patch(Routes.user(), {
|
||||
body: { username, avatar: avatar && (await DataResolver.resolveImage(avatar)) },
|
||||
});
|
||||
|
||||
this.client.token = data.token;
|
||||
this.client.rest.setToken(data.token);
|
||||
const { updated } = this.client.actions.UserUpdate.handle(data);
|
||||
return updated ?? this;
|
||||
}
|
||||
|
||||
|
|
63
node_modules/discord.js/src/structures/CommandInteractionOptionResolver.js
generated
vendored
63
node_modules/discord.js/src/structures/CommandInteractionOptionResolver.js
generated
vendored
|
@ -85,19 +85,19 @@ class CommandInteractionOptionResolver {
|
|||
/**
|
||||
* Gets an option by name and property and checks its type.
|
||||
* @param {string} name The name of the option.
|
||||
* @param {ApplicationCommandOptionType} type The type of the option.
|
||||
* @param {ApplicationCommandOptionType[]} allowedTypes The allowed types of the option.
|
||||
* @param {string[]} properties The properties to check for for `required`.
|
||||
* @param {boolean} required Whether to throw an error if the option is not found.
|
||||
* @returns {?CommandInteractionOption} The option, if found.
|
||||
* @private
|
||||
*/
|
||||
_getTypedOption(name, type, properties, required) {
|
||||
_getTypedOption(name, allowedTypes, properties, required) {
|
||||
const option = this.get(name, required);
|
||||
if (!option) {
|
||||
return null;
|
||||
} else if (option.type !== type) {
|
||||
throw new DiscordjsTypeError(ErrorCodes.CommandInteractionOptionType, name, option.type, type);
|
||||
} else if (required && properties.every(prop => option[prop] === null || typeof option[prop] === 'undefined')) {
|
||||
} else if (!allowedTypes.includes(option.type)) {
|
||||
throw new DiscordjsTypeError(ErrorCodes.CommandInteractionOptionType, name, option.type, allowedTypes.join(', '));
|
||||
} else if (required && properties.every(prop => option[prop] === null || option[prop] === undefined)) {
|
||||
throw new DiscordjsTypeError(ErrorCodes.CommandInteractionOptionEmpty, name, option.type);
|
||||
}
|
||||
return option;
|
||||
|
@ -134,7 +134,7 @@ class CommandInteractionOptionResolver {
|
|||
* @returns {?boolean} The value of the option, or null if not set and not required.
|
||||
*/
|
||||
getBoolean(name, required = false) {
|
||||
const option = this._getTypedOption(name, ApplicationCommandOptionType.Boolean, ['value'], required);
|
||||
const option = this._getTypedOption(name, [ApplicationCommandOptionType.Boolean], ['value'], required);
|
||||
return option?.value ?? null;
|
||||
}
|
||||
|
||||
|
@ -142,12 +142,24 @@ class CommandInteractionOptionResolver {
|
|||
* Gets a channel option.
|
||||
* @param {string} name The name of the option.
|
||||
* @param {boolean} [required=false] Whether to throw an error if the option is not found.
|
||||
* @param {ChannelType[]} [channelTypes=[]] The allowed types of channels. If empty, all channel types are allowed.
|
||||
* @returns {?(GuildChannel|ThreadChannel|APIChannel)}
|
||||
* The value of the option, or null if not set and not required.
|
||||
*/
|
||||
getChannel(name, required = false) {
|
||||
const option = this._getTypedOption(name, ApplicationCommandOptionType.Channel, ['channel'], required);
|
||||
return option?.channel ?? null;
|
||||
getChannel(name, required = false, channelTypes = []) {
|
||||
const option = this._getTypedOption(name, [ApplicationCommandOptionType.Channel], ['channel'], required);
|
||||
const channel = option?.channel ?? null;
|
||||
|
||||
if (channel && channelTypes.length > 0 && !channelTypes.includes(channel.type)) {
|
||||
throw new DiscordjsTypeError(
|
||||
ErrorCodes.CommandInteractionOptionInvalidChannelType,
|
||||
name,
|
||||
channel.type,
|
||||
channelTypes.join(', '),
|
||||
);
|
||||
}
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -157,7 +169,7 @@ class CommandInteractionOptionResolver {
|
|||
* @returns {?string} The value of the option, or null if not set and not required.
|
||||
*/
|
||||
getString(name, required = false) {
|
||||
const option = this._getTypedOption(name, ApplicationCommandOptionType.String, ['value'], required);
|
||||
const option = this._getTypedOption(name, [ApplicationCommandOptionType.String], ['value'], required);
|
||||
return option?.value ?? null;
|
||||
}
|
||||
|
||||
|
@ -168,7 +180,7 @@ class CommandInteractionOptionResolver {
|
|||
* @returns {?number} The value of the option, or null if not set and not required.
|
||||
*/
|
||||
getInteger(name, required = false) {
|
||||
const option = this._getTypedOption(name, ApplicationCommandOptionType.Integer, ['value'], required);
|
||||
const option = this._getTypedOption(name, [ApplicationCommandOptionType.Integer], ['value'], required);
|
||||
return option?.value ?? null;
|
||||
}
|
||||
|
||||
|
@ -179,7 +191,7 @@ class CommandInteractionOptionResolver {
|
|||
* @returns {?number} The value of the option, or null if not set and not required.
|
||||
*/
|
||||
getNumber(name, required = false) {
|
||||
const option = this._getTypedOption(name, ApplicationCommandOptionType.Number, ['value'], required);
|
||||
const option = this._getTypedOption(name, [ApplicationCommandOptionType.Number], ['value'], required);
|
||||
return option?.value ?? null;
|
||||
}
|
||||
|
||||
|
@ -190,7 +202,12 @@ class CommandInteractionOptionResolver {
|
|||
* @returns {?User} The value of the option, or null if not set and not required.
|
||||
*/
|
||||
getUser(name, required = false) {
|
||||
const option = this._getTypedOption(name, ApplicationCommandOptionType.User, ['user'], required);
|
||||
const option = this._getTypedOption(
|
||||
name,
|
||||
[ApplicationCommandOptionType.User, ApplicationCommandOptionType.Mentionable],
|
||||
['user'],
|
||||
required,
|
||||
);
|
||||
return option?.user ?? null;
|
||||
}
|
||||
|
||||
|
@ -201,7 +218,12 @@ class CommandInteractionOptionResolver {
|
|||
* The value of the option, or null if the user is not present in the guild or the option is not set.
|
||||
*/
|
||||
getMember(name) {
|
||||
const option = this._getTypedOption(name, ApplicationCommandOptionType.User, ['member'], false);
|
||||
const option = this._getTypedOption(
|
||||
name,
|
||||
[ApplicationCommandOptionType.User, ApplicationCommandOptionType.Mentionable],
|
||||
['member'],
|
||||
false,
|
||||
);
|
||||
return option?.member ?? null;
|
||||
}
|
||||
|
||||
|
@ -212,7 +234,12 @@ class CommandInteractionOptionResolver {
|
|||
* @returns {?(Role|APIRole)} The value of the option, or null if not set and not required.
|
||||
*/
|
||||
getRole(name, required = false) {
|
||||
const option = this._getTypedOption(name, ApplicationCommandOptionType.Role, ['role'], required);
|
||||
const option = this._getTypedOption(
|
||||
name,
|
||||
[ApplicationCommandOptionType.Role, ApplicationCommandOptionType.Mentionable],
|
||||
['role'],
|
||||
required,
|
||||
);
|
||||
return option?.role ?? null;
|
||||
}
|
||||
|
||||
|
@ -223,7 +250,7 @@ class CommandInteractionOptionResolver {
|
|||
* @returns {?Attachment} The value of the option, or null if not set and not required.
|
||||
*/
|
||||
getAttachment(name, required = false) {
|
||||
const option = this._getTypedOption(name, ApplicationCommandOptionType.Attachment, ['attachment'], required);
|
||||
const option = this._getTypedOption(name, [ApplicationCommandOptionType.Attachment], ['attachment'], required);
|
||||
return option?.attachment ?? null;
|
||||
}
|
||||
|
||||
|
@ -237,7 +264,7 @@ class CommandInteractionOptionResolver {
|
|||
getMentionable(name, required = false) {
|
||||
const option = this._getTypedOption(
|
||||
name,
|
||||
ApplicationCommandOptionType.Mentionable,
|
||||
[ApplicationCommandOptionType.Mentionable],
|
||||
['user', 'member', 'role'],
|
||||
required,
|
||||
);
|
||||
|
@ -252,7 +279,7 @@ class CommandInteractionOptionResolver {
|
|||
* The value of the option, or null if not set and not required.
|
||||
*/
|
||||
getMessage(name, required = false) {
|
||||
const option = this._getTypedOption(name, '_MESSAGE', ['message'], required);
|
||||
const option = this._getTypedOption(name, ['_MESSAGE'], ['message'], required);
|
||||
return option?.message ?? null;
|
||||
}
|
||||
|
||||
|
|
2
node_modules/discord.js/src/structures/DMChannel.js
generated
vendored
2
node_modules/discord.js/src/structures/DMChannel.js
generated
vendored
|
@ -68,7 +68,7 @@ class DMChannel extends BaseChannel {
|
|||
* @readonly
|
||||
*/
|
||||
get partial() {
|
||||
return typeof this.lastMessageId === 'undefined';
|
||||
return this.lastMessageId === undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
12
node_modules/discord.js/src/structures/EmbedBuilder.js
generated
vendored
12
node_modules/discord.js/src/structures/EmbedBuilder.js
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const { EmbedBuilder: BuildersEmbed, isJSONEncodable } = require('@discordjs/builders');
|
||||
const { EmbedBuilder: BuildersEmbed } = require('@discordjs/builders');
|
||||
const { isJSONEncodable } = require('@discordjs/util');
|
||||
const { toSnakeCase } = require('../util/Transformers');
|
||||
const { resolveColor } = require('../util/Util');
|
||||
|
||||
|
@ -24,14 +25,11 @@ class EmbedBuilder extends BuildersEmbed {
|
|||
|
||||
/**
|
||||
* Creates a new embed builder from JSON data
|
||||
* @param {JSONEncodable<APIEmbed>|APIEmbed} other The other data
|
||||
* @param {EmbedBuilder|Embed|APIEmbed} other The other data
|
||||
* @returns {EmbedBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
}
|
||||
return new this(other);
|
||||
return new this(isJSONEncodable(other) ? other.toJSON() : other);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,5 +37,5 @@ module.exports = EmbedBuilder;
|
|||
|
||||
/**
|
||||
* @external BuildersEmbed
|
||||
* @see {@link https://discord.js.org/#/docs/builders/main/class/EmbedBuilder}
|
||||
* @see {@link https://discord.js.org/docs/packages/builders/stable/EmbedBuilder:Class}
|
||||
*/
|
||||
|
|
18
node_modules/discord.js/src/structures/ForumChannel.js
generated
vendored
18
node_modules/discord.js/src/structures/ForumChannel.js
generated
vendored
|
@ -134,6 +134,12 @@ class ForumChannel extends GuildChannel {
|
|||
} else {
|
||||
this.defaultSortOrder ??= null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The default layout type used to display posts
|
||||
* @type {ForumLayoutType}
|
||||
*/
|
||||
this.defaultForumLayout = data.default_forum_layout;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -168,7 +174,7 @@ class ForumChannel extends GuildChannel {
|
|||
|
||||
/**
|
||||
* Creates an invite to this guild channel.
|
||||
* @param {CreateInviteOptions} [options={}] The options for creating the invite
|
||||
* @param {InviteCreateOptions} [options={}] The options for creating the invite
|
||||
* @returns {Promise<Invite>}
|
||||
* @example
|
||||
* // Create an invite to a channel
|
||||
|
@ -225,6 +231,16 @@ class ForumChannel extends GuildChannel {
|
|||
return this.edit({ defaultSortOrder, reason });
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default forum layout type used to display posts
|
||||
* @param {ForumLayoutType} defaultForumLayout The default forum layout type to set on this channel
|
||||
* @param {string} [reason] Reason for changing the default forum layout
|
||||
* @returns {Promise<ForumChannel>}
|
||||
*/
|
||||
setDefaultForumLayout(defaultForumLayout, reason) {
|
||||
return this.edit({ defaultForumLayout, reason });
|
||||
}
|
||||
|
||||
// These are here only for documentation purposes - they are implemented by TextBasedChannel
|
||||
/* eslint-disable no-empty-function */
|
||||
createWebhook() {}
|
||||
|
|
209
node_modules/discord.js/src/structures/Guild.js
generated
vendored
209
node_modules/discord.js/src/structures/Guild.js
generated
vendored
|
@ -5,7 +5,6 @@ const { makeURLSearchParams } = require('@discordjs/rest');
|
|||
const { ChannelType, GuildPremiumTier, Routes, GuildFeature } = require('discord-api-types/v10');
|
||||
const AnonymousGuild = require('./AnonymousGuild');
|
||||
const GuildAuditLogs = require('./GuildAuditLogs');
|
||||
const GuildAuditLogsEntry = require('./GuildAuditLogsEntry');
|
||||
const GuildPreview = require('./GuildPreview');
|
||||
const GuildTemplate = require('./GuildTemplate');
|
||||
const Integration = require('./Integration');
|
||||
|
@ -308,6 +307,16 @@ class Guild extends AnonymousGuild {
|
|||
this.maxVideoChannelUsers ??= null;
|
||||
}
|
||||
|
||||
if ('max_stage_video_channel_users' in data) {
|
||||
/**
|
||||
* The maximum amount of users allowed in a stage video channel.
|
||||
* @type {?number}
|
||||
*/
|
||||
this.maxStageVideoChannelUsers = data.max_stage_video_channel_users;
|
||||
} else {
|
||||
this.maxStageVideoChannelUsers ??= null;
|
||||
}
|
||||
|
||||
if ('approximate_member_count' in data) {
|
||||
/**
|
||||
* The approximate amount of members the guild has
|
||||
|
@ -361,6 +370,16 @@ class Guild extends AnonymousGuild {
|
|||
this.preferredLocale = data.preferred_locale;
|
||||
}
|
||||
|
||||
if ('safety_alerts_channel_id' in data) {
|
||||
/**
|
||||
* The safety alerts channel's id for the guild
|
||||
* @type {?Snowflake}
|
||||
*/
|
||||
this.safetyAlertsChannelId = data.safety_alerts_channel_id;
|
||||
} else {
|
||||
this.safetyAlertsChannelId ??= null;
|
||||
}
|
||||
|
||||
if (data.channels) {
|
||||
this.channels.cache.clear();
|
||||
for (const rawChannel of data.channels) {
|
||||
|
@ -525,6 +544,15 @@ class Guild extends AnonymousGuild {
|
|||
return this.client.channels.resolve(this.publicUpdatesChannelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Safety alerts channel for this guild
|
||||
* @type {?TextChannel}
|
||||
* @readonly
|
||||
*/
|
||||
get safetyAlertsChannel() {
|
||||
return this.client.channels.resolve(this.safetyAlertsChannelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum bitrate available for this guild
|
||||
* @type {number}
|
||||
|
@ -624,9 +652,6 @@ class Guild extends AnonymousGuild {
|
|||
* .catch(console.error);
|
||||
*/
|
||||
async fetchVanityData() {
|
||||
if (!this.features.includes(GuildFeature.VanityURL)) {
|
||||
throw new DiscordjsError(ErrorCodes.VanityURL);
|
||||
}
|
||||
const data = await this.client.rest.get(Routes.guildVanityUrl(this.id));
|
||||
this.vanityURLCode = data.code;
|
||||
this.vanityURLUses = data.uses;
|
||||
|
@ -700,7 +725,8 @@ class Guild extends AnonymousGuild {
|
|||
/**
|
||||
* Options used to fetch audit logs.
|
||||
* @typedef {Object} GuildAuditLogsFetchOptions
|
||||
* @property {Snowflake|GuildAuditLogsEntry} [before] Only return entries before this entry
|
||||
* @property {Snowflake|GuildAuditLogsEntry} [before] Consider only entries before this entry
|
||||
* @property {Snowflake|GuildAuditLogsEntry} [after] Consider only entries after this entry
|
||||
* @property {number} [limit] The number of entries to return
|
||||
* @property {UserResolvable} [user] Only return entries for actions made by this user
|
||||
* @property {?AuditLogEvent} [type] Only return entries for this action type
|
||||
|
@ -716,19 +742,18 @@ class Guild extends AnonymousGuild {
|
|||
* .then(audit => console.log(audit.entries.first()))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async fetchAuditLogs(options = {}) {
|
||||
if (options.before && options.before instanceof GuildAuditLogsEntry) options.before = options.before.id;
|
||||
|
||||
async fetchAuditLogs({ before, after, limit, user, type } = {}) {
|
||||
const query = makeURLSearchParams({
|
||||
before: options.before,
|
||||
limit: options.limit,
|
||||
action_type: options.type,
|
||||
before: before?.id ?? before,
|
||||
after: after?.id ?? after,
|
||||
limit,
|
||||
action_type: type,
|
||||
});
|
||||
|
||||
if (options.user) {
|
||||
const id = this.client.users.resolveId(options.user);
|
||||
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'user', 'UserResolvable');
|
||||
query.set('user_id', id);
|
||||
if (user) {
|
||||
const userId = this.client.users.resolveId(user);
|
||||
if (!userId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'user', 'UserResolvable');
|
||||
query.set('user_id', userId);
|
||||
}
|
||||
|
||||
const data = await this.client.rest.get(Routes.guildAuditLog(this.id), { query });
|
||||
|
@ -737,30 +762,30 @@ class Guild extends AnonymousGuild {
|
|||
|
||||
/**
|
||||
* The data for editing a guild.
|
||||
* @typedef {Object} GuildEditData
|
||||
* @typedef {Object} GuildEditOptions
|
||||
* @property {string} [name] The name of the guild
|
||||
* @property {?GuildVerificationLevel} [verificationLevel] The verification level of the guild
|
||||
* @property {?GuildDefaultMessageNotifications} [defaultMessageNotifications] The default message
|
||||
* notification level of the guild
|
||||
* @property {?GuildExplicitContentFilter} [explicitContentFilter] The level of the explicit content filter
|
||||
* @property {?VoiceChannelResolvable} [afkChannel] The AFK channel of the guild
|
||||
* @property {?TextChannelResolvable} [systemChannel] The system channel of the guild
|
||||
* @property {number} [afkTimeout] The AFK timeout of the guild
|
||||
* @property {?(BufferResolvable|Base64Resolvable)} [icon] The icon of the guild
|
||||
* @property {GuildMemberResolvable} [owner] The owner of the guild
|
||||
* @property {?(BufferResolvable|Base64Resolvable)} [splash] The invite splash image of the guild
|
||||
* @property {?(BufferResolvable|Base64Resolvable)} [discoverySplash] The discovery splash image of the guild
|
||||
* @property {?(BufferResolvable|Base64Resolvable)} [banner] The banner of the guild
|
||||
* @property {?GuildDefaultMessageNotifications} [defaultMessageNotifications] The default message
|
||||
* notification level of the guild
|
||||
* @property {?TextChannelResolvable} [systemChannel] The system channel of the guild
|
||||
* @property {SystemChannelFlagsResolvable} [systemChannelFlags] The system channel flags of the guild
|
||||
* @property {?TextChannelResolvable} [rulesChannel] The rules channel of the guild
|
||||
* @property {?TextChannelResolvable} [publicUpdatesChannel] The community updates channel of the guild
|
||||
* @property {?TextChannelResolvable} [safetyAlertsChannel] The safety alerts channel of the guild
|
||||
* @property {?string} [preferredLocale] The preferred locale of the guild
|
||||
* @property {boolean} [premiumProgressBarEnabled] Whether the guild's premium progress bar is enabled
|
||||
* @property {?string} [description] The discovery description of the guild
|
||||
* @property {GuildFeature[]} [features] The features of the guild
|
||||
* @property {?string} [description] The discovery description of the guild
|
||||
* @property {boolean} [premiumProgressBarEnabled] Whether the guild's premium progress bar is enabled
|
||||
* @property {string} [reason] Reason for editing this guild
|
||||
*/
|
||||
/* eslint-enable max-len */
|
||||
|
||||
/**
|
||||
* Data that can be resolved to a Text Channel object. This can be:
|
||||
|
@ -778,7 +803,7 @@ class Guild extends AnonymousGuild {
|
|||
|
||||
/**
|
||||
* Updates the guild with new information - e.g. a new name.
|
||||
* @param {GuildEditData} data The data to update the guild with
|
||||
* @param {GuildEditOptions} options The options to provide
|
||||
* @returns {Promise<Guild>}
|
||||
* @example
|
||||
* // Set the guild name
|
||||
|
@ -788,51 +813,52 @@ class Guild extends AnonymousGuild {
|
|||
* .then(updated => console.log(`New guild name ${updated}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async edit(data) {
|
||||
const _data = {};
|
||||
if (data.name) _data.name = data.name;
|
||||
if (typeof data.verificationLevel !== 'undefined') {
|
||||
_data.verification_level = data.verificationLevel;
|
||||
}
|
||||
if (typeof data.afkChannel !== 'undefined') {
|
||||
_data.afk_channel_id = this.client.channels.resolveId(data.afkChannel);
|
||||
}
|
||||
if (typeof data.systemChannel !== 'undefined') {
|
||||
_data.system_channel_id = this.client.channels.resolveId(data.systemChannel);
|
||||
}
|
||||
if (data.afkTimeout) _data.afk_timeout = Number(data.afkTimeout);
|
||||
if (typeof data.icon !== 'undefined') _data.icon = await DataResolver.resolveImage(data.icon);
|
||||
if (data.owner) _data.owner_id = this.client.users.resolveId(data.owner);
|
||||
if (typeof data.splash !== 'undefined') _data.splash = await DataResolver.resolveImage(data.splash);
|
||||
if (typeof data.discoverySplash !== 'undefined') {
|
||||
_data.discovery_splash = await DataResolver.resolveImage(data.discoverySplash);
|
||||
}
|
||||
if (typeof data.banner !== 'undefined') _data.banner = await DataResolver.resolveImage(data.banner);
|
||||
if (typeof data.explicitContentFilter !== 'undefined') {
|
||||
_data.explicit_content_filter = data.explicitContentFilter;
|
||||
}
|
||||
if (typeof data.defaultMessageNotifications !== 'undefined') {
|
||||
_data.default_message_notifications = data.defaultMessageNotifications;
|
||||
}
|
||||
if (typeof data.systemChannelFlags !== 'undefined') {
|
||||
_data.system_channel_flags = SystemChannelFlagsBitField.resolve(data.systemChannelFlags);
|
||||
}
|
||||
if (typeof data.rulesChannel !== 'undefined') {
|
||||
_data.rules_channel_id = this.client.channels.resolveId(data.rulesChannel);
|
||||
}
|
||||
if (typeof data.publicUpdatesChannel !== 'undefined') {
|
||||
_data.public_updates_channel_id = this.client.channels.resolveId(data.publicUpdatesChannel);
|
||||
}
|
||||
if (typeof data.features !== 'undefined') {
|
||||
_data.features = data.features;
|
||||
}
|
||||
if (typeof data.description !== 'undefined') {
|
||||
_data.description = data.description;
|
||||
}
|
||||
if (typeof data.preferredLocale !== 'undefined') _data.preferred_locale = data.preferredLocale;
|
||||
if ('premiumProgressBarEnabled' in data) _data.premium_progress_bar_enabled = data.premiumProgressBarEnabled;
|
||||
const newData = await this.client.rest.patch(Routes.guild(this.id), { body: _data, reason: data.reason });
|
||||
return this.client.actions.GuildUpdate.handle(newData).updated;
|
||||
async edit({
|
||||
verificationLevel,
|
||||
defaultMessageNotifications,
|
||||
explicitContentFilter,
|
||||
afkChannel,
|
||||
afkTimeout,
|
||||
icon,
|
||||
owner,
|
||||
splash,
|
||||
discoverySplash,
|
||||
banner,
|
||||
systemChannel,
|
||||
systemChannelFlags,
|
||||
rulesChannel,
|
||||
publicUpdatesChannel,
|
||||
preferredLocale,
|
||||
premiumProgressBarEnabled,
|
||||
safetyAlertsChannel,
|
||||
...options
|
||||
}) {
|
||||
const data = await this.client.rest.patch(Routes.guild(this.id), {
|
||||
body: {
|
||||
...options,
|
||||
verification_level: verificationLevel,
|
||||
default_message_notifications: defaultMessageNotifications,
|
||||
explicit_content_filter: explicitContentFilter,
|
||||
afk_channel_id: afkChannel && this.client.channels.resolveId(afkChannel),
|
||||
afk_timeout: afkTimeout,
|
||||
icon: icon && (await DataResolver.resolveImage(icon)),
|
||||
owner_id: owner && this.client.users.resolveId(owner),
|
||||
splash: splash && (await DataResolver.resolveImage(splash)),
|
||||
discovery_splash: discoverySplash && (await DataResolver.resolveImage(discoverySplash)),
|
||||
banner: banner && (await DataResolver.resolveImage(banner)),
|
||||
system_channel_id: systemChannel && this.client.channels.resolveId(systemChannel),
|
||||
system_channel_flags:
|
||||
systemChannelFlags === undefined ? undefined : SystemChannelFlagsBitField.resolve(systemChannelFlags),
|
||||
rules_channel_id: rulesChannel && this.client.channels.resolveId(rulesChannel),
|
||||
public_updates_channel_id: publicUpdatesChannel && this.client.channels.resolveId(publicUpdatesChannel),
|
||||
preferred_locale: preferredLocale,
|
||||
premium_progress_bar_enabled: premiumProgressBarEnabled,
|
||||
safety_alerts_channel_id: safetyAlertsChannel && this.client.channels.resolveId(safetyAlertsChannel),
|
||||
},
|
||||
reason: options.reason,
|
||||
});
|
||||
|
||||
return this.client.actions.GuildUpdate.handle(data).updated;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -845,7 +871,7 @@ class Guild extends AnonymousGuild {
|
|||
|
||||
/**
|
||||
* Welcome screen edit data
|
||||
* @typedef {Object} WelcomeScreenEditData
|
||||
* @typedef {Object} WelcomeScreenEditOptions
|
||||
* @property {boolean} [enabled] Whether the welcome screen is enabled
|
||||
* @property {string} [description] The description for the welcome screen
|
||||
* @property {WelcomeChannelData[]} [welcomeChannels] The welcome channel data for the welcome screen
|
||||
|
@ -869,7 +895,7 @@ class Guild extends AnonymousGuild {
|
|||
|
||||
/**
|
||||
* Updates the guild's welcome screen
|
||||
* @param {WelcomeScreenEditData} data Data to edit the welcome screen with
|
||||
* @param {WelcomeScreenEditOptions} options The options to provide
|
||||
* @returns {Promise<WelcomeScreen>}
|
||||
* @example
|
||||
* guild.editWelcomeScreen({
|
||||
|
@ -883,8 +909,8 @@ class Guild extends AnonymousGuild {
|
|||
* ],
|
||||
* })
|
||||
*/
|
||||
async editWelcomeScreen(data) {
|
||||
const { enabled, description, welcomeChannels } = data;
|
||||
async editWelcomeScreen(options) {
|
||||
const { enabled, description, welcomeChannels } = options;
|
||||
const welcome_channels = welcomeChannels?.map(welcomeChannelData => {
|
||||
const emoji = this.emojis.resolve(welcomeChannelData.emoji);
|
||||
return {
|
||||
|
@ -905,7 +931,6 @@ class Guild extends AnonymousGuild {
|
|||
return new WelcomeScreen(this, patchData);
|
||||
}
|
||||
|
||||
/* eslint-disable max-len */
|
||||
/**
|
||||
* Edits the level of the explicit content filter.
|
||||
* @param {?GuildExplicitContentFilter} explicitContentFilter The new level of the explicit content filter
|
||||
|
@ -918,14 +943,14 @@ class Guild extends AnonymousGuild {
|
|||
|
||||
/**
|
||||
* Edits the setting of the default message notifications of the guild.
|
||||
* @param {?GuildDefaultMessageNotifications} defaultMessageNotifications The new default message notification level of the guild
|
||||
* @param {?GuildDefaultMessageNotifications} defaultMessageNotifications
|
||||
* The new default message notification level of the guild
|
||||
* @param {string} [reason] Reason for changing the setting of the default message notifications
|
||||
* @returns {Promise<Guild>}
|
||||
*/
|
||||
setDefaultMessageNotifications(defaultMessageNotifications, reason) {
|
||||
return this.edit({ defaultMessageNotifications, reason });
|
||||
}
|
||||
/* eslint-enable max-len */
|
||||
|
||||
/**
|
||||
* Edits the flags of the default message notifications of the guild.
|
||||
|
@ -1142,6 +1167,21 @@ class Guild extends AnonymousGuild {
|
|||
return this.edit({ premiumProgressBarEnabled: enabled, reason });
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits the safety alerts channel of the guild.
|
||||
* @param {?TextChannelResolvable} safetyAlertsChannel The new safety alerts channel
|
||||
* @param {string} [reason] Reason for changing the guild's safety alerts channel
|
||||
* @returns {Promise<Guild>}
|
||||
* @example
|
||||
* // Edit the guild safety alerts channel
|
||||
* guild.setSafetyAlertsChannel(channel)
|
||||
* .then(updated => console.log(`Updated guild safety alerts channel to ${updated.safetyAlertsChannel.name}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
setSafetyAlertsChannel(safetyAlertsChannel, reason) {
|
||||
return this.edit({ safetyAlertsChannel, reason });
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits the guild's widget settings.
|
||||
* @param {GuildWidgetSettingsData} settings The widget settings for the guild
|
||||
|
@ -1161,9 +1201,15 @@ class Guild extends AnonymousGuild {
|
|||
|
||||
/**
|
||||
* Sets the guild's MFA level
|
||||
* <info>An elevated MFA level requires guild moderators to have 2FA enabled.</info>
|
||||
* @param {GuildMFALevel} level The MFA level
|
||||
* @param {string} [reason] Reason for changing the guild's MFA level
|
||||
* @returns {Promise<Guild>}
|
||||
* @example
|
||||
* // Set the MFA level of the guild to Elevated
|
||||
* guild.setMFALevel(GuildMFALevel.Elevated)
|
||||
* .then(guild => console.log("Set guild's MFA level to Elevated"))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async setMFALevel(level, reason) {
|
||||
await this.client.rest.post(Routes.guildMFA(this.id), {
|
||||
|
@ -1181,7 +1227,7 @@ class Guild extends AnonymousGuild {
|
|||
* @example
|
||||
* // Leave a guild
|
||||
* guild.leave()
|
||||
* .then(g => console.log(`Left the guild ${g}`))
|
||||
* .then(guild => console.log(`Left the guild: ${guild.name}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async leave() {
|
||||
|
@ -1204,6 +1250,17 @@ class Guild extends AnonymousGuild {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this guild's invites are disabled.
|
||||
* @param {boolean} [disabled=true] Whether the invites are disabled
|
||||
* @returns {Promise<Guild>}
|
||||
*/
|
||||
async disableInvites(disabled = true) {
|
||||
const features = this.features.filter(feature => feature !== GuildFeature.InvitesDisabled);
|
||||
if (disabled) features.push(GuildFeature.InvitesDisabled);
|
||||
return this.edit({ features });
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this guild equals another guild. It compares all properties, so for most operations
|
||||
* it is advisable to just compare `guild.id === guild2.id` as it is much faster and is often
|
||||
|
|
2
node_modules/discord.js/src/structures/GuildAuditLogs.js
generated
vendored
2
node_modules/discord.js/src/structures/GuildAuditLogs.js
generated
vendored
|
@ -78,7 +78,7 @@ class GuildAuditLogs {
|
|||
*/
|
||||
this.entries = new Collection();
|
||||
for (const item of data.audit_log_entries) {
|
||||
const entry = new GuildAuditLogsEntry(this, guild, item);
|
||||
const entry = new GuildAuditLogsEntry(guild, item, this);
|
||||
this.entries.set(entry.id, entry);
|
||||
}
|
||||
}
|
||||
|
|
28
node_modules/discord.js/src/structures/GuildAuditLogsEntry.js
generated
vendored
28
node_modules/discord.js/src/structures/GuildAuditLogsEntry.js
generated
vendored
|
@ -94,7 +94,7 @@ class GuildAuditLogsEntry {
|
|||
*/
|
||||
static Targets = Targets;
|
||||
|
||||
constructor(logs, guild, data) {
|
||||
constructor(guild, data, logs) {
|
||||
/**
|
||||
* The target type of this entry
|
||||
* @type {AuditLogTargetType}
|
||||
|
@ -109,7 +109,7 @@ class GuildAuditLogsEntry {
|
|||
this.actionType = GuildAuditLogsEntry.actionType(data.action_type);
|
||||
|
||||
/**
|
||||
* The type of action that occured.
|
||||
* The type of action that occurred.
|
||||
* @type {AuditLogEvent}
|
||||
*/
|
||||
this.action = data.action_type;
|
||||
|
@ -120,6 +120,12 @@ class GuildAuditLogsEntry {
|
|||
*/
|
||||
this.reason = data.reason ?? null;
|
||||
|
||||
/**
|
||||
* The id of the user that executed this entry
|
||||
* @type {?Snowflake}
|
||||
*/
|
||||
this.executorId = data.user_id;
|
||||
|
||||
/**
|
||||
* The user that executed this entry
|
||||
* @type {?User}
|
||||
|
@ -127,7 +133,7 @@ class GuildAuditLogsEntry {
|
|||
this.executor = data.user_id
|
||||
? guild.client.options.partials.includes(Partials.User)
|
||||
? guild.client.users._add({ id: data.user_id })
|
||||
: guild.client.users.cache.get(data.user_id)
|
||||
: guild.client.users.cache.get(data.user_id) ?? null
|
||||
: null;
|
||||
|
||||
/**
|
||||
|
@ -239,6 +245,12 @@ class GuildAuditLogsEntry {
|
|||
break;
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the target of this entry
|
||||
* @type {?Snowflake}
|
||||
*/
|
||||
this.targetId = data.target_id;
|
||||
|
||||
/**
|
||||
* The target of this entry
|
||||
* @type {?AuditLogEntryTarget}
|
||||
|
@ -254,12 +266,12 @@ class GuildAuditLogsEntry {
|
|||
} else if (targetType === Targets.User && data.target_id) {
|
||||
this.target = guild.client.options.partials.includes(Partials.User)
|
||||
? guild.client.users._add({ id: data.target_id })
|
||||
: guild.client.users.cache.get(data.target_id);
|
||||
: guild.client.users.cache.get(data.target_id) ?? null;
|
||||
} else if (targetType === Targets.Guild) {
|
||||
this.target = guild.client.guilds.cache.get(data.target_id);
|
||||
} else if (targetType === Targets.Webhook) {
|
||||
this.target =
|
||||
logs.webhooks.get(data.target_id) ??
|
||||
logs?.webhooks.get(data.target_id) ??
|
||||
new Webhook(
|
||||
guild.client,
|
||||
this.changes.reduce(
|
||||
|
@ -294,10 +306,10 @@ class GuildAuditLogsEntry {
|
|||
this.target =
|
||||
data.action_type === AuditLogEvent.MessageBulkDelete
|
||||
? guild.channels.cache.get(data.target_id) ?? { id: data.target_id }
|
||||
: guild.client.users.cache.get(data.target_id);
|
||||
: guild.client.users.cache.get(data.target_id) ?? null;
|
||||
} else if (targetType === Targets.Integration) {
|
||||
this.target =
|
||||
logs.integrations.get(data.target_id) ??
|
||||
logs?.integrations.get(data.target_id) ??
|
||||
new Integration(
|
||||
guild.client,
|
||||
this.changes.reduce(
|
||||
|
@ -363,7 +375,7 @@ class GuildAuditLogsEntry {
|
|||
),
|
||||
);
|
||||
} else if (targetType === Targets.ApplicationCommand) {
|
||||
this.target = logs.applicationCommands.get(data.target_id) ?? { id: data.target_id };
|
||||
this.target = logs?.applicationCommands.get(data.target_id) ?? { id: data.target_id };
|
||||
} else if (targetType === Targets.AutoModeration) {
|
||||
this.target =
|
||||
guild.autoModerationRules.cache.get(data.target_id) ??
|
||||
|
|
16
node_modules/discord.js/src/structures/GuildChannel.js
generated
vendored
16
node_modules/discord.js/src/structures/GuildChannel.js
generated
vendored
|
@ -20,7 +20,7 @@ const PermissionsBitField = require('../util/PermissionsBitField');
|
|||
*/
|
||||
class GuildChannel extends BaseChannel {
|
||||
constructor(guild, data, client, immediatePatch = true) {
|
||||
super(guild?.client ?? client, data, false);
|
||||
super(client, data, false);
|
||||
|
||||
/**
|
||||
* The guild the channel is in
|
||||
|
@ -33,8 +33,6 @@ class GuildChannel extends BaseChannel {
|
|||
* @type {Snowflake}
|
||||
*/
|
||||
this.guildId = guild?.id ?? data.guild_id;
|
||||
|
||||
this.parentId = this.parentId ?? null;
|
||||
/**
|
||||
* A manager of permission overwrites that belong to this channel
|
||||
* @type {PermissionOverwriteManager}
|
||||
|
@ -73,6 +71,8 @@ class GuildChannel extends BaseChannel {
|
|||
* @type {?Snowflake}
|
||||
*/
|
||||
this.parentId = data.parent_id;
|
||||
} else {
|
||||
this.parentId ??= null;
|
||||
}
|
||||
|
||||
if ('permission_overwrites' in data) {
|
||||
|
@ -131,8 +131,8 @@ class GuildChannel extends BaseChannel {
|
|||
|
||||
// Compare overwrites
|
||||
return (
|
||||
typeof channelVal !== 'undefined' &&
|
||||
typeof parentVal !== 'undefined' &&
|
||||
channelVal !== undefined &&
|
||||
parentVal !== undefined &&
|
||||
channelVal.deny.bitfield === parentVal.deny.bitfield &&
|
||||
channelVal.allow.bitfield === parentVal.allow.bitfield
|
||||
);
|
||||
|
@ -268,7 +268,7 @@ class GuildChannel extends BaseChannel {
|
|||
|
||||
/**
|
||||
* Edits the channel.
|
||||
* @param {GuildChannelEditOptions} data The new data for the channel
|
||||
* @param {GuildChannelEditOptions} options The options to provide
|
||||
* @returns {Promise<GuildChannel>}
|
||||
* @example
|
||||
* // Edit a channel
|
||||
|
@ -276,8 +276,8 @@ class GuildChannel extends BaseChannel {
|
|||
* .then(console.log)
|
||||
* .catch(console.error);
|
||||
*/
|
||||
edit(data) {
|
||||
return this.guild.channels.edit(this, data);
|
||||
edit(options) {
|
||||
return this.guild.channels.edit(this, options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
10
node_modules/discord.js/src/structures/GuildEmoji.js
generated
vendored
10
node_modules/discord.js/src/structures/GuildEmoji.js
generated
vendored
|
@ -56,7 +56,7 @@ class GuildEmoji extends BaseGuildEmoji {
|
|||
*/
|
||||
get deletable() {
|
||||
if (!this.guild.members.me) throw new DiscordjsError(ErrorCodes.GuildUncachedMe);
|
||||
return !this.managed && this.guild.members.me.permissions.has(PermissionFlagsBits.ManageEmojisAndStickers);
|
||||
return !this.managed && this.guild.members.me.permissions.has(PermissionFlagsBits.ManageGuildExpressions);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,7 +78,7 @@ class GuildEmoji extends BaseGuildEmoji {
|
|||
|
||||
/**
|
||||
* Data for editing an emoji.
|
||||
* @typedef {Object} GuildEmojiEditData
|
||||
* @typedef {Object} GuildEmojiEditOptions
|
||||
* @property {string} [name] The name of the emoji
|
||||
* @property {Collection<Snowflake, Role>|RoleResolvable[]} [roles] Roles to restrict emoji to
|
||||
* @property {string} [reason] Reason for editing this emoji
|
||||
|
@ -86,7 +86,7 @@ class GuildEmoji extends BaseGuildEmoji {
|
|||
|
||||
/**
|
||||
* Edits the emoji.
|
||||
* @param {GuildEmojiEditData} data The new data for the emoji
|
||||
* @param {GuildEmojiEditOptions} options The options to provide
|
||||
* @returns {Promise<GuildEmoji>}
|
||||
* @example
|
||||
* // Edit an emoji
|
||||
|
@ -94,8 +94,8 @@ class GuildEmoji extends BaseGuildEmoji {
|
|||
* .then(e => console.log(`Edited emoji ${e}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
edit(data) {
|
||||
return this.guild.emojis.edit(this.id, data);
|
||||
edit(options) {
|
||||
return this.guild.emojis.edit(this.id, options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
68
node_modules/discord.js/src/structures/GuildMember.js
generated
vendored
68
node_modules/discord.js/src/structures/GuildMember.js
generated
vendored
|
@ -6,6 +6,7 @@ const VoiceState = require('./VoiceState');
|
|||
const TextBasedChannel = require('./interfaces/TextBasedChannel');
|
||||
const { DiscordjsError, ErrorCodes } = require('../errors');
|
||||
const GuildMemberRoleManager = require('../managers/GuildMemberRoleManager');
|
||||
const { GuildMemberFlagsBitField } = require('../util/GuildMemberFlagsBitField');
|
||||
const PermissionsBitField = require('../util/PermissionsBitField');
|
||||
|
||||
/**
|
||||
|
@ -53,6 +54,11 @@ class GuildMember extends Base {
|
|||
*/
|
||||
this.communicationDisabledUntilTimestamp = null;
|
||||
|
||||
/**
|
||||
* The role ids of the member
|
||||
* @type {Snowflake[]}
|
||||
* @private
|
||||
*/
|
||||
this._roles = [];
|
||||
if (data) this._patch(data);
|
||||
}
|
||||
|
@ -93,6 +99,16 @@ class GuildMember extends Base {
|
|||
this.communicationDisabledUntilTimestamp =
|
||||
data.communication_disabled_until && Date.parse(data.communication_disabled_until);
|
||||
}
|
||||
|
||||
if ('flags' in data) {
|
||||
/**
|
||||
* The flags of this member
|
||||
* @type {Readonly<GuildMemberFlagsBitField>}
|
||||
*/
|
||||
this.flags = new GuildMemberFlagsBitField(data.flags).freeze();
|
||||
} else {
|
||||
this.flags ??= new GuildMemberFlagsBitField().freeze();
|
||||
}
|
||||
}
|
||||
|
||||
_clone() {
|
||||
|
@ -307,11 +323,21 @@ class GuildMember extends Base {
|
|||
|
||||
/**
|
||||
* Edits this member.
|
||||
* @param {GuildMemberEditData} data The data to edit the member with
|
||||
* @param {GuildMemberEditOptions} options The options to provide
|
||||
* @returns {Promise<GuildMember>}
|
||||
*/
|
||||
edit(data) {
|
||||
return this.guild.members.edit(this, data);
|
||||
edit(options) {
|
||||
return this.guild.members.edit(this, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the flags for this member.
|
||||
* @param {GuildMemberFlagsResolvable} flags The flags to set
|
||||
* @param {string} [reason] Reason for setting the flags
|
||||
* @returns {Promise<GuildMember>}
|
||||
*/
|
||||
setFlags(flags, reason) {
|
||||
return this.edit({ flags, reason });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -319,6 +345,16 @@ class GuildMember extends Base {
|
|||
* @param {?string} nick The nickname for the guild member, or `null` if you want to reset their nickname
|
||||
* @param {string} [reason] Reason for setting the nickname
|
||||
* @returns {Promise<GuildMember>}
|
||||
* @example
|
||||
* // Set a nickname for a guild member
|
||||
* guildMember.setNickname('cool nickname', 'Needed a new nickname')
|
||||
* .then(member => console.log(`Set nickname of ${member.user.username}`))
|
||||
* .catch(console.error);
|
||||
* @example
|
||||
* // Remove a nickname for a guild member
|
||||
* guildMember.setNickname(null, 'No nicknames allowed!')
|
||||
* .then(member => console.log(`Removed nickname for ${member.user.username}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
setNickname(nick, reason) {
|
||||
return this.edit({ nick, reason });
|
||||
|
@ -361,7 +397,7 @@ class GuildMember extends Base {
|
|||
* .catch(console.error);
|
||||
*/
|
||||
ban(options) {
|
||||
return this.guild.members.ban(this, options);
|
||||
return this.guild.bans.create(this, options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -375,6 +411,11 @@ class GuildMember extends Base {
|
|||
* guildMember.disableCommunicationUntil(Date.now() + (5 * 60 * 1000), 'They deserved it')
|
||||
* .then(console.log)
|
||||
* .catch(console.error);
|
||||
* @example
|
||||
* // Remove the timeout of a guild member
|
||||
* guildMember.disableCommunicationUntil(null)
|
||||
* .then(member => console.log(`Removed timeout for ${member.displayName}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
disableCommunicationUntil(communicationDisabledUntil, reason) {
|
||||
return this.edit({ communicationDisabledUntil, reason });
|
||||
|
@ -423,6 +464,7 @@ class GuildMember extends Base {
|
|||
this.avatar === member.avatar &&
|
||||
this.pending === member.pending &&
|
||||
this.communicationDisabledUntilTimestamp === member.communicationDisabledUntilTimestamp &&
|
||||
this.flags.bitfield === member.flags.bitfield &&
|
||||
(this._roles === member._roles ||
|
||||
(this._roles.length === member._roles.length && this._roles.every((role, i) => role === member._roles[i])))
|
||||
);
|
||||
|
@ -450,12 +492,22 @@ class GuildMember extends Base {
|
|||
json.displayAvatarURL = this.displayAvatarURL();
|
||||
return json;
|
||||
}
|
||||
|
||||
// These are here only for documentation purposes - they are implemented by TextBasedChannel
|
||||
/* eslint-disable no-empty-function */
|
||||
send() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to this user.
|
||||
* @method send
|
||||
* @memberof GuildMember
|
||||
* @instance
|
||||
* @param {string|MessagePayload|MessageCreateOptions} options The options to provide
|
||||
* @returns {Promise<Message>}
|
||||
* @example
|
||||
* // Send a direct message
|
||||
* guildMember.send('Hello!')
|
||||
* .then(message => console.log(`Sent message: ${message.content} to ${guildMember.displayName}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
|
||||
TextBasedChannel.applyToClass(GuildMember);
|
||||
|
||||
exports.GuildMember = GuildMember;
|
||||
|
|
4
node_modules/discord.js/src/structures/GuildScheduledEvent.js
generated
vendored
4
node_modules/discord.js/src/structures/GuildScheduledEvent.js
generated
vendored
|
@ -240,7 +240,7 @@ class GuildScheduledEvent extends Base {
|
|||
|
||||
/**
|
||||
* Options used to create an invite URL to a {@link GuildScheduledEvent}
|
||||
* @typedef {CreateInviteOptions} CreateGuildScheduledEventInviteURLOptions
|
||||
* @typedef {InviteCreateOptions} GuildScheduledEventInviteURLCreateOptions
|
||||
* @property {GuildInvitableChannelResolvable} [channel] The channel to create the invite in.
|
||||
* <warn>This is required when the `entityType` of `GuildScheduledEvent` is
|
||||
* {@link GuildScheduledEventEntityType.External}, gets ignored otherwise</warn>
|
||||
|
@ -248,7 +248,7 @@ class GuildScheduledEvent extends Base {
|
|||
|
||||
/**
|
||||
* Creates an invite URL to this guild scheduled event.
|
||||
* @param {CreateGuildScheduledEventInviteURLOptions} [options] The options to create the invite
|
||||
* @param {GuildScheduledEventInviteURLCreateOptions} [options] The options to create the invite
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
async createInviteURL(options) {
|
||||
|
|
4
node_modules/discord.js/src/structures/GuildTemplate.js
generated
vendored
4
node_modules/discord.js/src/structures/GuildTemplate.js
generated
vendored
|
@ -155,14 +155,14 @@ class GuildTemplate extends Base {
|
|||
|
||||
/**
|
||||
* Options used to edit a guild template.
|
||||
* @typedef {Object} EditGuildTemplateOptions
|
||||
* @typedef {Object} GuildTemplateEditOptions
|
||||
* @property {string} [name] The name of this template
|
||||
* @property {string} [description] The description of this template
|
||||
*/
|
||||
|
||||
/**
|
||||
* Updates the metadata of this template.
|
||||
* @param {EditGuildTemplateOptions} [options] Options for editing the template
|
||||
* @param {GuildTemplateEditOptions} [options] Options for editing the template
|
||||
* @returns {Promise<GuildTemplate>}
|
||||
*/
|
||||
async edit({ name, description } = {}) {
|
||||
|
|
1
node_modules/discord.js/src/structures/Integration.js
generated
vendored
1
node_modules/discord.js/src/structures/Integration.js
generated
vendored
|
@ -16,6 +16,7 @@ const IntegrationApplication = require('./IntegrationApplication');
|
|||
* * `twitch`
|
||||
* * `youtube`
|
||||
* * `discord`
|
||||
* * `guild_subscription`
|
||||
* @typedef {string} IntegrationType
|
||||
*/
|
||||
|
||||
|
|
2
node_modules/discord.js/src/structures/InteractionCollector.js
generated
vendored
2
node_modules/discord.js/src/structures/InteractionCollector.js
generated
vendored
|
@ -14,7 +14,7 @@ const Events = require('../util/Events');
|
|||
* @property {number} [maxComponents] The maximum number of components to collect
|
||||
* @property {number} [maxUsers] The maximum number of users to interact
|
||||
* @property {Message|APIMessage} [message] The message to listen to interactions from
|
||||
* @property {InteractionResponse} interactionResponse The interaction response to listen
|
||||
* @property {InteractionResponse} [interactionResponse] The interaction response to listen
|
||||
* to message component interactions from
|
||||
*/
|
||||
|
||||
|
|
44
node_modules/discord.js/src/structures/InteractionResponse.js
generated
vendored
44
node_modules/discord.js/src/structures/InteractionResponse.js
generated
vendored
|
@ -1,5 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
const { DiscordSnowflake } = require('@sapphire/snowflake');
|
||||
const { InteractionType } = require('discord-api-types/v10');
|
||||
const { DiscordjsError, ErrorCodes } = require('../errors');
|
||||
|
||||
|
@ -21,6 +22,24 @@ class InteractionResponse {
|
|||
this.client = interaction.client;
|
||||
}
|
||||
|
||||
/**
|
||||
* The timestamp the interaction response was created at
|
||||
* @type {number}
|
||||
* @readonly
|
||||
*/
|
||||
get createdTimestamp() {
|
||||
return DiscordSnowflake.timestampFrom(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* The time the interaction response was created at
|
||||
* @type {Date}
|
||||
* @readonly
|
||||
*/
|
||||
get createdAt() {
|
||||
return new Date(this.createdTimestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects a single component interaction that passes the filter.
|
||||
* The Promise will reject if the time expires.
|
||||
|
@ -51,6 +70,31 @@ class InteractionResponse {
|
|||
interactionType: InteractionType.MessageComponent,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the response as a {@link Message} object.
|
||||
* @returns {Promise<Message>}
|
||||
*/
|
||||
fetch() {
|
||||
return this.interaction.fetchReply();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the response.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
delete() {
|
||||
return this.interaction.deleteReply();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits the response.
|
||||
* @param {string|MessagePayload|WebhookMessageEditOptions} options The new options for the response.
|
||||
* @returns {Promise<Message>}
|
||||
*/
|
||||
edit(options) {
|
||||
return this.interaction.editReply(options);
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line import/order
|
||||
|
|
2
node_modules/discord.js/src/structures/InteractionWebhook.js
generated
vendored
2
node_modules/discord.js/src/structures/InteractionWebhook.js
generated
vendored
|
@ -45,7 +45,7 @@ class InteractionWebhook {
|
|||
/**
|
||||
* Edits a message that was sent by this webhook.
|
||||
* @param {MessageResolvable|'@original'} message The message to edit
|
||||
* @param {string|MessagePayload|WebhookEditMessageOptions} options The options to provide
|
||||
* @param {string|MessagePayload|WebhookMessageEditOptions} options The options to provide
|
||||
* @returns {Promise<Message>} Returns the message edited by this webhook
|
||||
*/
|
||||
|
||||
|
|
3
node_modules/discord.js/src/structures/InviteGuild.js
generated
vendored
3
node_modules/discord.js/src/structures/InviteGuild.js
generated
vendored
|
@ -15,8 +15,7 @@ class InviteGuild extends AnonymousGuild {
|
|||
* The welcome screen for this invite guild
|
||||
* @type {?WelcomeScreen}
|
||||
*/
|
||||
this.welcomeScreen =
|
||||
typeof data.welcome_screen !== 'undefined' ? new WelcomeScreen(this, data.welcome_screen) : null;
|
||||
this.welcomeScreen = data.welcome_screen !== undefined ? new WelcomeScreen(this, data.welcome_screen) : null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
15
node_modules/discord.js/src/structures/MentionableSelectMenuBuilder.js
generated
vendored
15
node_modules/discord.js/src/structures/MentionableSelectMenuBuilder.js
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const { MentionableSelectMenuBuilder: BuildersMentionableSelectMenu, isJSONEncodable } = require('@discordjs/builders');
|
||||
const { MentionableSelectMenuBuilder: BuildersMentionableSelectMenu } = require('@discordjs/builders');
|
||||
const { isJSONEncodable } = require('@discordjs/util');
|
||||
const { toSnakeCase } = require('../util/Transformers');
|
||||
|
||||
/**
|
||||
|
@ -13,15 +14,13 @@ class MentionableSelectMenuBuilder extends BuildersMentionableSelectMenu {
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates a new select menu builder from json data
|
||||
* @param {JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent} other The other data
|
||||
* Creates a new select menu builder from JSON data
|
||||
* @param {MentionableSelectMenuBuilder|MentionableSelectMenuComponent|APIMentionableSelectComponent} other
|
||||
* The other data
|
||||
* @returns {MentionableSelectMenuBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
}
|
||||
return new this(other);
|
||||
return new this(isJSONEncodable(other) ? other.toJSON() : other);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,5 +28,5 @@ module.exports = MentionableSelectMenuBuilder;
|
|||
|
||||
/**
|
||||
* @external BuildersMentionableSelectMenu
|
||||
* @see {@link https://discord.js.org/#/docs/builders/main/class/MentionableSelectMenuBuilder}
|
||||
* @see {@link https://discord.js.org/docs/packages/builders/stable/MentionableSelectMenuBuilder:Class}
|
||||
*/
|
||||
|
|
59
node_modules/discord.js/src/structures/Message.js
generated
vendored
59
node_modules/discord.js/src/structures/Message.js
generated
vendored
|
@ -22,7 +22,7 @@ const { Sticker } = require('./Sticker');
|
|||
const { DiscordjsError, ErrorCodes } = require('../errors');
|
||||
const ReactionManager = require('../managers/ReactionManager');
|
||||
const { createComponent } = require('../util/Components');
|
||||
const { NonSystemMessageTypes, MaxBulkDeletableMessageAge } = require('../util/Constants');
|
||||
const { NonSystemMessageTypes, MaxBulkDeletableMessageAge, DeletableMessageTypes } = require('../util/Constants');
|
||||
const MessageFlagsBitField = require('../util/MessageFlagsBitField');
|
||||
const PermissionsBitField = require('../util/PermissionsBitField');
|
||||
const { cleanContent, resolvePartialEmoji } = require('../util/Util');
|
||||
|
@ -198,6 +198,31 @@ class Message extends Base {
|
|||
this.position ??= null;
|
||||
}
|
||||
|
||||
if ('role_subscription_data' in data) {
|
||||
/**
|
||||
* Role subscription data found on {@link MessageType.RoleSubscriptionPurchase} messages.
|
||||
* @typedef {Object} RoleSubscriptionData
|
||||
* @property {Snowflake} roleSubscriptionListingId The id of the SKU and listing the user is subscribed to
|
||||
* @property {string} tierName The name of the tier the user is subscribed to
|
||||
* @property {number} totalMonthsSubscribed The total number of months the user has been subscribed for
|
||||
* @property {boolean} isRenewal Whether this notification is a renewal
|
||||
*/
|
||||
|
||||
/**
|
||||
* The data of the role subscription purchase or renewal.
|
||||
* <info>This is present on {@link MessageType.RoleSubscriptionPurchase} messages.</info>
|
||||
* @type {?RoleSubscriptionData}
|
||||
*/
|
||||
this.roleSubscriptionData = {
|
||||
roleSubscriptionListingId: data.role_subscription_data.role_subscription_listing_id,
|
||||
tierName: data.role_subscription_data.tier_name,
|
||||
totalMonthsSubscribed: data.role_subscription_data.total_months_subscribed,
|
||||
isRenewal: data.role_subscription_data.is_renewal,
|
||||
};
|
||||
} else {
|
||||
this.roleSubscriptionData ??= null;
|
||||
}
|
||||
|
||||
// Discord sends null if the message has not been edited
|
||||
if (data.edited_timestamp) {
|
||||
/**
|
||||
|
@ -543,7 +568,7 @@ class Message extends Base {
|
|||
* @property {ComponentType} [componentType] The type of component interaction to collect
|
||||
* @property {number} [idle] Time to wait without another message component interaction before ending the collector
|
||||
* @property {boolean} [dispose] Whether to remove the message component interaction after collecting
|
||||
* @property {InteractionResponse} [InteractionResponse] The interaction response to collect interactions from
|
||||
* @property {InteractionResponse} [interactionResponse] The interaction response to collect interactions from
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -577,11 +602,17 @@ class Message extends Base {
|
|||
*/
|
||||
get editable() {
|
||||
const precheck = Boolean(this.author.id === this.client.user.id && (!this.guild || this.channel?.viewable));
|
||||
|
||||
// Regardless of permissions thread messages cannot be edited if
|
||||
// the thread is locked.
|
||||
// the thread is archived or the thread is locked and the bot does not have permission to manage threads.
|
||||
if (this.channel?.isThread()) {
|
||||
return precheck && !this.channel.locked;
|
||||
if (this.channel.archived) return false;
|
||||
if (this.channel.locked) {
|
||||
const permissions = this.channel.permissionsFor(this.client.user);
|
||||
if (!permissions?.has(PermissionFlagsBits.ManageThreads, true)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
return precheck;
|
||||
}
|
||||
|
||||
|
@ -591,6 +622,8 @@ class Message extends Base {
|
|||
* @readonly
|
||||
*/
|
||||
get deletable() {
|
||||
if (!DeletableMessageTypes.includes(this.type)) return false;
|
||||
|
||||
if (!this.guild) {
|
||||
return this.author.id === this.client.user.id;
|
||||
}
|
||||
|
@ -604,10 +637,10 @@ class Message extends Base {
|
|||
// This flag allows deleting even if timed out
|
||||
if (permissions.has(PermissionFlagsBits.Administrator, false)) return true;
|
||||
|
||||
return Boolean(
|
||||
this.author.id === this.client.user.id ||
|
||||
(permissions.has(PermissionFlagsBits.ManageMessages, false) &&
|
||||
this.guild.members.me.communicationDisabledUntilTimestamp < Date.now()),
|
||||
// The auto moderation action message author is the reference message author
|
||||
return (
|
||||
(this.type !== MessageType.AutoModerationAction && this.author.id === this.client.user.id) ||
|
||||
(permissions.has(PermissionFlagsBits.ManageMessages, false) && !this.guild.members.me.isCommunicationDisabled())
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -620,12 +653,11 @@ class Message extends Base {
|
|||
* channel.bulkDelete(messages.filter(message => message.bulkDeletable));
|
||||
*/
|
||||
get bulkDeletable() {
|
||||
const permissions = this.channel?.permissionsFor(this.client.user);
|
||||
return (
|
||||
(this.inGuild() &&
|
||||
Date.now() - this.createdTimestamp < MaxBulkDeletableMessageAge &&
|
||||
this.deletable &&
|
||||
permissions?.has(PermissionFlagsBits.ManageMessages, false)) ??
|
||||
this.channel?.permissionsFor(this.client.user).has(PermissionFlagsBits.ManageMessages, false)) ??
|
||||
false
|
||||
);
|
||||
}
|
||||
|
@ -761,9 +793,9 @@ class Message extends Base {
|
|||
|
||||
return this.client.actions.MessageReactionAdd.handle(
|
||||
{
|
||||
user: this.client.user,
|
||||
channel: this.channel,
|
||||
message: this,
|
||||
[this.client.actions.injectedUser]: this.client.user,
|
||||
[this.client.actions.injectedChannel]: this.channel,
|
||||
[this.client.actions.injectedMessage]: this,
|
||||
emoji: resolvePartialEmoji(emoji),
|
||||
},
|
||||
true,
|
||||
|
@ -790,7 +822,6 @@ class Message extends Base {
|
|||
* @typedef {BaseMessageCreateOptions} MessageReplyOptions
|
||||
* @property {boolean} [failIfNotExists=this.client.options.failIfNotExists] Whether to error if the referenced
|
||||
* message does not exist (creates a standard message in this case when false)
|
||||
* @property {StickerResolvable[]} [stickers=[]] Stickers to send in the message
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
25
node_modules/discord.js/src/structures/MessagePayload.js
generated
vendored
25
node_modules/discord.js/src/structures/MessagePayload.js
generated
vendored
|
@ -1,8 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const { Buffer } = require('node:buffer');
|
||||
const { isJSONEncodable } = require('@discordjs/builders');
|
||||
const { lazy } = require('@discordjs/util');
|
||||
const { lazy, isJSONEncodable } = require('@discordjs/util');
|
||||
const { MessageFlags } = require('discord-api-types/v10');
|
||||
const ActionRowBuilder = require('./ActionRowBuilder');
|
||||
const { DiscordjsRangeError, ErrorCodes } = require('../errors');
|
||||
|
@ -107,7 +106,7 @@ class MessagePayload {
|
|||
let content;
|
||||
if (this.options.content === null) {
|
||||
content = '';
|
||||
} else if (typeof this.options.content !== 'undefined') {
|
||||
} else if (this.options.content !== undefined) {
|
||||
content = verifyString(this.options.content, DiscordjsRangeError, ErrorCodes.MessageContentType, true);
|
||||
}
|
||||
|
||||
|
@ -127,7 +126,7 @@ class MessagePayload {
|
|||
const tts = Boolean(this.options.tts);
|
||||
|
||||
let nonce;
|
||||
if (typeof this.options.nonce !== 'undefined') {
|
||||
if (this.options.nonce !== undefined) {
|
||||
nonce = this.options.nonce;
|
||||
if (typeof nonce === 'number' ? !Number.isInteger(nonce) : typeof nonce !== 'string') {
|
||||
throw new DiscordjsRangeError(ErrorCodes.MessageNonceType);
|
||||
|
@ -147,8 +146,8 @@ class MessagePayload {
|
|||
|
||||
let flags;
|
||||
if (
|
||||
typeof this.options.flags !== 'undefined' ||
|
||||
(this.isMessage && typeof this.options.reply === 'undefined') ||
|
||||
this.options.flags !== undefined ||
|
||||
(this.isMessage && this.options.reply === undefined) ||
|
||||
this.isMessageManager
|
||||
) {
|
||||
flags =
|
||||
|
@ -163,11 +162,11 @@ class MessagePayload {
|
|||
}
|
||||
|
||||
let allowedMentions =
|
||||
typeof this.options.allowedMentions === 'undefined'
|
||||
this.options.allowedMentions === undefined
|
||||
? this.target.client.options.allowedMentions
|
||||
: this.options.allowedMentions;
|
||||
|
||||
if (typeof allowedMentions?.repliedUser !== 'undefined') {
|
||||
if (allowedMentions?.repliedUser !== undefined) {
|
||||
allowedMentions = { ...allowedMentions, replied_user: allowedMentions.repliedUser };
|
||||
delete allowedMentions.repliedUser;
|
||||
}
|
||||
|
@ -204,8 +203,7 @@ class MessagePayload {
|
|||
components,
|
||||
username,
|
||||
avatar_url: avatarURL,
|
||||
allowed_mentions:
|
||||
typeof content === 'undefined' && typeof message_reference === 'undefined' ? undefined : allowedMentions,
|
||||
allowed_mentions: content === undefined && message_reference === undefined ? undefined : allowedMentions,
|
||||
flags,
|
||||
message_reference,
|
||||
attachments: this.options.attachments,
|
||||
|
@ -228,8 +226,7 @@ class MessagePayload {
|
|||
|
||||
/**
|
||||
* Resolves a single file into an object sendable to the API.
|
||||
* @param {BufferResolvable|Stream|JSONEncodable<AttachmentPayload>} fileLike Something that could
|
||||
* be resolved to a file
|
||||
* @param {AttachmentPayload|BufferResolvable|Stream} fileLike Something that could be resolved to a file
|
||||
* @returns {Promise<RawFile>}
|
||||
*/
|
||||
static async resolveFile(fileLike) {
|
||||
|
@ -287,7 +284,7 @@ module.exports = MessagePayload;
|
|||
|
||||
/**
|
||||
* A possible payload option.
|
||||
* @typedef {MessageCreateOptions|MessageEditOptions|WebhookCreateMessageOptions|WebhookEditMessageOptions|
|
||||
* @typedef {MessageCreateOptions|MessageEditOptions|WebhookMessageCreateOptions|WebhookMessageEditOptions|
|
||||
* InteractionReplyOptions|InteractionUpdateOptions} MessagePayloadOption
|
||||
*/
|
||||
|
||||
|
@ -298,5 +295,5 @@ module.exports = MessagePayload;
|
|||
|
||||
/**
|
||||
* @external RawFile
|
||||
* @see {@link https://discord.js.org/#/docs/rest/main/typedef/RawFile}
|
||||
* @see {@link https://discord.js.org/docs/packages/rest/stable/RawFile:Interface}
|
||||
*/
|
||||
|
|
4
node_modules/discord.js/src/structures/MessageReaction.js
generated
vendored
4
node_modules/discord.js/src/structures/MessageReaction.js
generated
vendored
|
@ -117,6 +117,10 @@ class MessageReaction {
|
|||
return flatten(this, { emoji: 'emojiId', message: 'messageId' });
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
return this._emoji.id ?? this._emoji.name;
|
||||
}
|
||||
|
||||
_add(user) {
|
||||
if (this.partial) return;
|
||||
this.users.cache.set(user.id, user);
|
||||
|
|
12
node_modules/discord.js/src/structures/ModalBuilder.js
generated
vendored
12
node_modules/discord.js/src/structures/ModalBuilder.js
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const { ModalBuilder: BuildersModal, ComponentBuilder, isJSONEncodable } = require('@discordjs/builders');
|
||||
const { ModalBuilder: BuildersModal, ComponentBuilder } = require('@discordjs/builders');
|
||||
const { isJSONEncodable } = require('@discordjs/util');
|
||||
const { toSnakeCase } = require('../util/Transformers');
|
||||
|
||||
/**
|
||||
|
@ -17,14 +18,11 @@ class ModalBuilder extends BuildersModal {
|
|||
|
||||
/**
|
||||
* Creates a new modal builder from JSON data
|
||||
* @param {JSONEncodable<APIModalComponent>|APIModalComponent} other The other data
|
||||
* @param {ModalBuilder|APIModalComponent} other The other data
|
||||
* @returns {ModalBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
}
|
||||
return new this(other);
|
||||
return new this(isJSONEncodable(other) ? other.toJSON() : other);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,5 +30,5 @@ module.exports = ModalBuilder;
|
|||
|
||||
/**
|
||||
* @external BuildersModal
|
||||
* @see {@link https://discord.js.org/#/docs/builders/main/class/ModalBuilder}
|
||||
* @see {@link https://discord.js.org/docs/packages/builders/stable/ModalBuilder:Class}
|
||||
*/
|
||||
|
|
4
node_modules/discord.js/src/structures/ModalSubmitFields.js
generated
vendored
4
node_modules/discord.js/src/structures/ModalSubmitFields.js
generated
vendored
|
@ -11,13 +11,13 @@ class ModalSubmitFields {
|
|||
constructor(components) {
|
||||
/**
|
||||
* The components within the modal
|
||||
* @type {ActionRowModalData[]} The components in the modal
|
||||
* @type {ActionRowModalData[]}
|
||||
*/
|
||||
this.components = components;
|
||||
|
||||
/**
|
||||
* The extracted fields from the modal
|
||||
* @type {Collection<string, ModalData>} The fields in the modal
|
||||
* @type {Collection<string, ModalData>}
|
||||
*/
|
||||
this.fields = components.reduce((accumulator, next) => {
|
||||
next.components.forEach(c => accumulator.set(c.customId, c));
|
||||
|
|
12
node_modules/discord.js/src/structures/Presence.js
generated
vendored
12
node_modules/discord.js/src/structures/Presence.js
generated
vendored
|
@ -141,6 +141,12 @@ class Presence extends Base {
|
|||
*/
|
||||
class Activity {
|
||||
constructor(presence, data) {
|
||||
/**
|
||||
* The presence of the Activity
|
||||
* @type {Presence}
|
||||
* @readonly
|
||||
* @name Activity#presence
|
||||
*/
|
||||
Object.defineProperty(this, 'presence', { value: presence });
|
||||
|
||||
/**
|
||||
|
@ -287,6 +293,12 @@ class Activity {
|
|||
*/
|
||||
class RichPresenceAssets {
|
||||
constructor(activity, assets) {
|
||||
/**
|
||||
* The activity of the RichPresenceAssets
|
||||
* @type {Activity}
|
||||
* @readonly
|
||||
* @name RichPresenceAssets#activity
|
||||
*/
|
||||
Object.defineProperty(this, 'activity', { value: activity });
|
||||
|
||||
/**
|
||||
|
|
32
node_modules/discord.js/src/structures/Role.js
generated
vendored
32
node_modules/discord.js/src/structures/Role.js
generated
vendored
|
@ -107,6 +107,9 @@ class Role extends Base {
|
|||
* @property {Snowflake} [botId] The id of the bot this role belongs to
|
||||
* @property {Snowflake|string} [integrationId] The id of the integration this role belongs to
|
||||
* @property {true} [premiumSubscriberRole] Whether this is the guild's premium subscription role
|
||||
* @property {Snowflake} [subscriptionListingId] The id of this role's subscription SKU and listing
|
||||
* @property {true} [availableForPurchase] Whether this role is available for purchase
|
||||
* @property {true} [guildConnections] Whether this role is a guild's linked role
|
||||
*/
|
||||
this.tags = data.tags ? {} : null;
|
||||
if (data.tags) {
|
||||
|
@ -119,6 +122,15 @@ class Role extends Base {
|
|||
if ('premium_subscriber' in data.tags) {
|
||||
this.tags.premiumSubscriberRole = true;
|
||||
}
|
||||
if ('subscription_listing_id' in data.tags) {
|
||||
this.tags.subscriptionListingId = data.tags.subscription_listing_id;
|
||||
}
|
||||
if ('available_for_purchase' in data.tags) {
|
||||
this.tags.availableForPurchase = true;
|
||||
}
|
||||
if ('guild_connections' in data.tags) {
|
||||
this.tags.guildConnections = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,8 +188,14 @@ class Role extends Base {
|
|||
* @readonly
|
||||
*/
|
||||
get position() {
|
||||
const sorted = this.guild._sortedRoles();
|
||||
return [...sorted.values()].indexOf(sorted.get(this.id));
|
||||
return this.guild.roles.cache.reduce(
|
||||
(acc, role) =>
|
||||
acc +
|
||||
(this.rawPosition === role.rawPosition
|
||||
? BigInt(this.id) > BigInt(role.id)
|
||||
: this.rawPosition > role.rawPosition),
|
||||
0,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -185,6 +203,10 @@ class Role extends Base {
|
|||
* @param {RoleResolvable} role Role to compare to this one
|
||||
* @returns {number} Negative number if this role's position is lower (other role's is higher),
|
||||
* positive number if this one is higher (other's is lower), 0 if equal
|
||||
* @example
|
||||
* // Compare the position of a role to another
|
||||
* const roleCompare = role.comparePositionTo(otherRole);
|
||||
* if (roleCompare >= 1) console.log(`${role.name} is higher than ${otherRole.name}`);
|
||||
*/
|
||||
comparePositionTo(role) {
|
||||
return this.guild.roles.comparePositions(this, role);
|
||||
|
@ -207,7 +229,7 @@ class Role extends Base {
|
|||
|
||||
/**
|
||||
* Edits the role.
|
||||
* @param {EditRoleOptions} data The new data for the role
|
||||
* @param {RoleEditOptions} options The options to provide
|
||||
* @returns {Promise<Role>}
|
||||
* @example
|
||||
* // Edit a role
|
||||
|
@ -215,8 +237,8 @@ class Role extends Base {
|
|||
* .then(updated => console.log(`Edited role name to ${updated.name}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
edit(data) {
|
||||
return this.guild.roles.edit(this, data);
|
||||
edit(options) {
|
||||
return this.guild.roles.edit(this, options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
14
node_modules/discord.js/src/structures/RoleSelectMenuBuilder.js
generated
vendored
14
node_modules/discord.js/src/structures/RoleSelectMenuBuilder.js
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const { RoleSelectMenuBuilder: BuildersRoleSelectMenu, isJSONEncodable } = require('@discordjs/builders');
|
||||
const { RoleSelectMenuBuilder: BuildersRoleSelectMenu } = require('@discordjs/builders');
|
||||
const { isJSONEncodable } = require('@discordjs/util');
|
||||
const { toSnakeCase } = require('../util/Transformers');
|
||||
|
||||
/**
|
||||
|
@ -13,15 +14,12 @@ class RoleSelectMenuBuilder extends BuildersRoleSelectMenu {
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates a new select menu builder from json data
|
||||
* @param {JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent} other The other data
|
||||
* Creates a new select menu builder from JSON data
|
||||
* @param {RoleSelectMenuBuilder|RoleSelectMenuComponent|APIRoleSelectComponent} other The other data
|
||||
* @returns {RoleSelectMenuBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
}
|
||||
return new this(other);
|
||||
return new this(isJSONEncodable(other) ? other.toJSON() : other);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,5 +27,5 @@ module.exports = RoleSelectMenuBuilder;
|
|||
|
||||
/**
|
||||
* @external BuildersRoleSelectMenu
|
||||
* @see {@link https://discord.js.org/#/docs/builders/main/class/RoleSelectMenuBuilder}
|
||||
* @see {@link https://discord.js.org/docs/packages/builders/stable/RoleSelectMenuBuilder:Class}
|
||||
*/
|
||||
|
|
2
node_modules/discord.js/src/structures/SelectMenuBuilder.js
generated
vendored
2
node_modules/discord.js/src/structures/SelectMenuBuilder.js
generated
vendored
|
@ -15,7 +15,7 @@ class SelectMenuBuilder extends StringSelectMenuBuilder {
|
|||
|
||||
if (!deprecationEmitted) {
|
||||
process.emitWarning(
|
||||
'The SelectMenuBuilder class is deprecated, use StringSelectMenuBuilder instead.',
|
||||
'The SelectMenuBuilder class is deprecated. Use StringSelectMenuBuilder instead.',
|
||||
'DeprecationWarning',
|
||||
);
|
||||
deprecationEmitted = true;
|
||||
|
|
2
node_modules/discord.js/src/structures/SelectMenuComponent.js
generated
vendored
2
node_modules/discord.js/src/structures/SelectMenuComponent.js
generated
vendored
|
@ -15,7 +15,7 @@ class SelectMenuComponent extends StringSelectMenuComponent {
|
|||
|
||||
if (!deprecationEmitted) {
|
||||
process.emitWarning(
|
||||
'The SelectMenuComponent class is deprecated, use StringSelectMenuComponent instead.',
|
||||
'The SelectMenuComponent class is deprecated. Use StringSelectMenuComponent instead.',
|
||||
'DeprecationWarning',
|
||||
);
|
||||
deprecationEmitted = true;
|
||||
|
|
2
node_modules/discord.js/src/structures/SelectMenuInteraction.js
generated
vendored
2
node_modules/discord.js/src/structures/SelectMenuInteraction.js
generated
vendored
|
@ -15,7 +15,7 @@ class SelectMenuInteraction extends StringSelectMenuInteraction {
|
|||
|
||||
if (!deprecationEmitted) {
|
||||
process.emitWarning(
|
||||
'The SelectMenuInteraction class is deprecated, use StringSelectMenuInteraction instead.',
|
||||
'The SelectMenuInteraction class is deprecated. Use StringSelectMenuInteraction instead.',
|
||||
'DeprecationWarning',
|
||||
);
|
||||
deprecationEmitted = true;
|
||||
|
|
2
node_modules/discord.js/src/structures/SelectMenuOptionBuilder.js
generated
vendored
2
node_modules/discord.js/src/structures/SelectMenuOptionBuilder.js
generated
vendored
|
@ -15,7 +15,7 @@ class SelectMenuOptionBuilder extends StringSelectMenuOptionBuilder {
|
|||
|
||||
if (!deprecationEmitted) {
|
||||
process.emitWarning(
|
||||
'The SelectMenuOptionBuilder class is deprecated, use StringSelectMenuOptionBuilder instead.',
|
||||
'The SelectMenuOptionBuilder class is deprecated. Use StringSelectMenuOptionBuilder instead.',
|
||||
'DeprecationWarning',
|
||||
);
|
||||
deprecationEmitted = true;
|
||||
|
|
46
node_modules/discord.js/src/structures/StageChannel.js
generated
vendored
46
node_modules/discord.js/src/structures/StageChannel.js
generated
vendored
|
@ -41,11 +41,11 @@ class StageChannel extends BaseGuildVoiceChannel {
|
|||
* Sets a new topic for the guild channel.
|
||||
* @param {?string} topic The new topic for the guild channel
|
||||
* @param {string} [reason] Reason for changing the guild channel's topic
|
||||
* @returns {Promise<GuildChannel>}
|
||||
* @returns {Promise<StageChannel>}
|
||||
* @example
|
||||
* // Set a new channel topic
|
||||
* channel.setTopic('needs more rate limiting')
|
||||
* .then(newChannel => console.log(`Channel's new topic is ${newChannel.topic}`))
|
||||
* stageChannel.setTopic('needs more rate limiting')
|
||||
* .then(channel => console.log(`Channel's new topic is ${channel.topic}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
setTopic(topic, reason) {
|
||||
|
@ -53,6 +53,21 @@ class StageChannel extends BaseGuildVoiceChannel {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bitrate of the channel.
|
||||
* @method setBitrate
|
||||
* @memberof StageChannel
|
||||
* @instance
|
||||
* @param {number} bitrate The new bitrate
|
||||
* @param {string} [reason] Reason for changing the channel's bitrate
|
||||
* @returns {Promise<StageChannel>}
|
||||
* @example
|
||||
* // Set the bitrate of a voice channel
|
||||
* stageChannel.setBitrate(48_000)
|
||||
* .then(channel => console.log(`Set bitrate to ${channel.bitrate}bps for ${channel.name}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets the RTC region of the channel.
|
||||
* @method setRTCRegion
|
||||
|
@ -69,4 +84,29 @@ class StageChannel extends BaseGuildVoiceChannel {
|
|||
* stageChannel.setRTCRegion(null, 'We want to let Discord decide.');
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets the user limit of the channel.
|
||||
* @method setUserLimit
|
||||
* @memberof StageChannel
|
||||
* @instance
|
||||
* @param {number} userLimit The new user limit
|
||||
* @param {string} [reason] Reason for changing the user limit
|
||||
* @returns {Promise<StageChannel>}
|
||||
* @example
|
||||
* // Set the user limit of a voice channel
|
||||
* stageChannel.setUserLimit(42)
|
||||
* .then(channel => console.log(`Set user limit to ${channel.userLimit} for ${channel.name}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets the camera video quality mode of the channel.
|
||||
* @method setVideoQualityMode
|
||||
* @memberof StageChannel
|
||||
* @instance
|
||||
* @param {VideoQualityMode} videoQualityMode The new camera video quality mode.
|
||||
* @param {string} [reason] Reason for changing the camera video quality mode.
|
||||
* @returns {Promise<StageChannel>}
|
||||
*/
|
||||
|
||||
module.exports = StageChannel;
|
||||
|
|
13
node_modules/discord.js/src/structures/Sticker.js
generated
vendored
13
node_modules/discord.js/src/structures/Sticker.js
generated
vendored
|
@ -1,9 +1,10 @@
|
|||
'use strict';
|
||||
|
||||
const { DiscordSnowflake } = require('@sapphire/snowflake');
|
||||
const { Routes, StickerFormatType } = require('discord-api-types/v10');
|
||||
const { Routes } = require('discord-api-types/v10');
|
||||
const Base = require('./Base');
|
||||
const { DiscordjsError, ErrorCodes } = require('../errors');
|
||||
const { StickerFormatExtensionMap } = require('../util/Constants');
|
||||
|
||||
/**
|
||||
* Represents a Sticker.
|
||||
|
@ -164,7 +165,7 @@ class Sticker extends Base {
|
|||
* @readonly
|
||||
*/
|
||||
get url() {
|
||||
return this.client.rest.cdn.sticker(this.id, this.format === StickerFormatType.Lottie ? 'json' : 'png');
|
||||
return this.client.rest.cdn.sticker(this.id, StickerFormatExtensionMap[this.format]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -197,7 +198,7 @@ class Sticker extends Base {
|
|||
|
||||
/**
|
||||
* Data for editing a sticker.
|
||||
* @typedef {Object} GuildStickerEditData
|
||||
* @typedef {Object} GuildStickerEditOptions
|
||||
* @property {string} [name] The name of the sticker
|
||||
* @property {?string} [description] The description of the sticker
|
||||
* @property {string} [tags] The Discord name of a unicode emoji representing the sticker's expression
|
||||
|
@ -206,7 +207,7 @@ class Sticker extends Base {
|
|||
|
||||
/**
|
||||
* Edits the sticker.
|
||||
* @param {GuildStickerEditData} data The new data for the sticker
|
||||
* @param {GuildStickerEditOptions} options The options to provide
|
||||
* @returns {Promise<Sticker>}
|
||||
* @example
|
||||
* // Update the name of a sticker
|
||||
|
@ -214,8 +215,8 @@ class Sticker extends Base {
|
|||
* .then(s => console.log(`Updated the name of the sticker to ${s.name}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
edit(data) {
|
||||
return this.guild.stickers.edit(this, data);
|
||||
edit(options) {
|
||||
return this.guild.stickers.edit(this, options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
9
node_modules/discord.js/src/structures/StringSelectMenuBuilder.js
generated
vendored
9
node_modules/discord.js/src/structures/StringSelectMenuBuilder.js
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const { SelectMenuBuilder: BuildersSelectMenu, isJSONEncodable, normalizeArray } = require('@discordjs/builders');
|
||||
const { SelectMenuBuilder: BuildersSelectMenu, normalizeArray } = require('@discordjs/builders');
|
||||
const { isJSONEncodable } = require('@discordjs/util');
|
||||
const { toSnakeCase } = require('../util/Transformers');
|
||||
const { resolvePartialEmoji } = require('../util/Util');
|
||||
|
||||
|
@ -23,7 +24,7 @@ class StringSelectMenuBuilder extends BuildersSelectMenu {
|
|||
|
||||
/**
|
||||
* Normalizes a select menu option emoji
|
||||
* @param {SelectMenuOptionData|JSONEncodable<APISelectMenuOption>} selectMenuOption The option to normalize
|
||||
* @param {SelectMenuOptionData|APISelectMenuOption} selectMenuOption The option to normalize
|
||||
* @returns {SelectMenuOptionBuilder|APISelectMenuOption}
|
||||
* @private
|
||||
*/
|
||||
|
@ -59,7 +60,7 @@ class StringSelectMenuBuilder extends BuildersSelectMenu {
|
|||
|
||||
/**
|
||||
* Creates a new select menu builder from json data
|
||||
* @param {JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent} other The other data
|
||||
* @param {StringSelectMenuBuilder|StringSelectMenuComponent|APIStringSelectComponent} other The other data
|
||||
* @returns {StringSelectMenuBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
|
@ -74,5 +75,5 @@ module.exports = StringSelectMenuBuilder;
|
|||
|
||||
/**
|
||||
* @external BuildersSelectMenu
|
||||
* @see {@link https://discord.js.org/#/docs/builders/main/class/SelectMenuBuilder}
|
||||
* @see {@link https://discord.js.org/docs/packages/builders/stable/StringSelectMenuBuilder:Class}
|
||||
*/
|
||||
|
|
12
node_modules/discord.js/src/structures/StringSelectMenuOptionBuilder.js
generated
vendored
12
node_modules/discord.js/src/structures/StringSelectMenuOptionBuilder.js
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const { SelectMenuOptionBuilder: BuildersSelectMenuOption, isJSONEncodable } = require('@discordjs/builders');
|
||||
const { SelectMenuOptionBuilder: BuildersSelectMenuOption } = require('@discordjs/builders');
|
||||
const { isJSONEncodable } = require('@discordjs/util');
|
||||
const { toSnakeCase } = require('../util/Transformers');
|
||||
const { resolvePartialEmoji } = require('../util/Util');
|
||||
|
||||
|
@ -32,14 +33,11 @@ class StringSelectMenuOptionBuilder extends BuildersSelectMenuOption {
|
|||
|
||||
/**
|
||||
* Creates a new select menu option builder from JSON data
|
||||
* @param {JSONEncodable<APISelectMenuOption>|APISelectMenuOption} other The other data
|
||||
* @param {StringSelectMenuOptionBuilder|APISelectMenuOption} other The other data
|
||||
* @returns {StringSelectMenuOptionBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
}
|
||||
return new this(other);
|
||||
return new this(isJSONEncodable(other) ? other.toJSON() : other);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,5 +45,5 @@ module.exports = StringSelectMenuOptionBuilder;
|
|||
|
||||
/**
|
||||
* @external BuildersSelectMenuOption
|
||||
* @see {@link https://discord.js.org/#/docs/builders/main/class/SelectMenuOptionBuilder}
|
||||
* @see {@link https://discord.js.org/docs/packages/builders/stable/SelectMenuOptionBuilder:Class}
|
||||
*/
|
||||
|
|
12
node_modules/discord.js/src/structures/TextInputBuilder.js
generated
vendored
12
node_modules/discord.js/src/structures/TextInputBuilder.js
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const { TextInputBuilder: BuildersTextInput, isJSONEncodable } = require('@discordjs/builders');
|
||||
const { TextInputBuilder: BuildersTextInput } = require('@discordjs/builders');
|
||||
const { isJSONEncodable } = require('@discordjs/util');
|
||||
const { toSnakeCase } = require('../util/Transformers');
|
||||
|
||||
/**
|
||||
|
@ -14,14 +15,11 @@ class TextInputBuilder extends BuildersTextInput {
|
|||
|
||||
/**
|
||||
* Creates a new text input builder from JSON data
|
||||
* @param {JSONEncodable<APITextInputComponent>|APITextInputComponent} other The other data
|
||||
* @param {TextInputBuilder|TextInputComponent|APITextInputComponent} other The other data
|
||||
* @returns {TextInputBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
}
|
||||
return new this(other);
|
||||
return new this(isJSONEncodable(other) ? other.toJSON() : other);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,5 +27,5 @@ module.exports = TextInputBuilder;
|
|||
|
||||
/**
|
||||
* @external BuildersTextInput
|
||||
* @see {@link https://discord.js.org/#/docs/builders/main/class/TextInputBuilder}
|
||||
* @see {@link https://discord.js.org/docs/packages/builders/stable/TextInputBuilder:Class}
|
||||
*/
|
||||
|
|
36
node_modules/discord.js/src/structures/ThreadChannel.js
generated
vendored
36
node_modules/discord.js/src/structures/ThreadChannel.js
generated
vendored
|
@ -14,7 +14,7 @@ const ChannelFlagsBitField = require('../util/ChannelFlagsBitField');
|
|||
* @implements {TextBasedChannel}
|
||||
*/
|
||||
class ThreadChannel extends BaseChannel {
|
||||
constructor(guild, data, client, fromInteraction = false) {
|
||||
constructor(guild, data, client) {
|
||||
super(guild?.client ?? client, data, false);
|
||||
|
||||
/**
|
||||
|
@ -40,12 +40,14 @@ class ThreadChannel extends BaseChannel {
|
|||
* @type {ThreadMemberManager}
|
||||
*/
|
||||
this.members = new ThreadMemberManager(this);
|
||||
if (data) this._patch(data, fromInteraction);
|
||||
if (data) this._patch(data);
|
||||
}
|
||||
|
||||
_patch(data, partial = false) {
|
||||
_patch(data) {
|
||||
super._patch(data);
|
||||
|
||||
if ('message' in data) this.messages._add(data.message);
|
||||
|
||||
if ('name' in data) {
|
||||
/**
|
||||
* The name of the thread
|
||||
|
@ -147,7 +149,7 @@ class ThreadChannel extends BaseChannel {
|
|||
this.lastPinTimestamp ??= null;
|
||||
}
|
||||
|
||||
if ('rate_limit_per_user' in data || !partial) {
|
||||
if ('rate_limit_per_user' in data) {
|
||||
/**
|
||||
* The rate limit per user (slowmode) for this thread in seconds
|
||||
* @type {?number}
|
||||
|
@ -316,7 +318,7 @@ class ThreadChannel extends BaseChannel {
|
|||
|
||||
/**
|
||||
* The options used to edit a thread channel
|
||||
* @typedef {Object} ThreadEditData
|
||||
* @typedef {Object} ThreadEditOptions
|
||||
* @property {string} [name] The new name for the thread
|
||||
* @property {boolean} [archived] Whether the thread is archived
|
||||
* @property {ThreadAutoArchiveDuration} [autoArchiveDuration] The amount of time after which the thread
|
||||
|
@ -324,15 +326,15 @@ class ThreadChannel extends BaseChannel {
|
|||
* @property {number} [rateLimitPerUser] The rate limit per user (slowmode) for the thread in seconds
|
||||
* @property {boolean} [locked] Whether the thread is locked
|
||||
* @property {boolean} [invitable] Whether non-moderators can add other non-moderators to a thread
|
||||
* <info>Can only be edited on {@link ChannelType.PrivateThread}</info>
|
||||
* @property {Snowflake[]} [appliedTags] The tags to apply to the thread
|
||||
* @property {ChannelFlagsResolvable} [flags] The flags to set on the channel
|
||||
* @property {string} [reason] Reason for editing the thread
|
||||
* <info>Can only be edited on {@link ChannelType.PrivateThread}</info>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Edits this thread.
|
||||
* @param {ThreadEditData} data The new data for this thread
|
||||
* @param {ThreadEditOptions} options The options to provide
|
||||
* @returns {Promise<ThreadChannel>}
|
||||
* @example
|
||||
* // Edit a thread
|
||||
|
@ -340,19 +342,19 @@ class ThreadChannel extends BaseChannel {
|
|||
* .then(editedThread => console.log(editedThread))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async edit(data) {
|
||||
async edit(options) {
|
||||
const newData = await this.client.rest.patch(Routes.channel(this.id), {
|
||||
body: {
|
||||
name: (data.name ?? this.name).trim(),
|
||||
archived: data.archived,
|
||||
auto_archive_duration: data.autoArchiveDuration,
|
||||
rate_limit_per_user: data.rateLimitPerUser,
|
||||
locked: data.locked,
|
||||
invitable: this.type === ChannelType.PrivateThread ? data.invitable : undefined,
|
||||
applied_tags: data.appliedTags,
|
||||
flags: 'flags' in data ? ChannelFlagsBitField.resolve(data.flags) : undefined,
|
||||
name: (options.name ?? this.name).trim(),
|
||||
archived: options.archived,
|
||||
auto_archive_duration: options.autoArchiveDuration,
|
||||
rate_limit_per_user: options.rateLimitPerUser,
|
||||
locked: options.locked,
|
||||
invitable: this.type === ChannelType.PrivateThread ? options.invitable : undefined,
|
||||
applied_tags: options.appliedTags,
|
||||
flags: 'flags' in options ? ChannelFlagsBitField.resolve(options.flags) : undefined,
|
||||
},
|
||||
reason: data.reason,
|
||||
reason: options.reason,
|
||||
});
|
||||
|
||||
return this.client.actions.ChannelUpdate.handle(newData).updated;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue