discord.js 15.0.0-dev.1763078518-9f18cb212 → 15.0.0-dev.1763164928-7349a6ee3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -9
- package/src/client/Client.js +107 -14
- package/src/client/websocket/handlers/RATE_LIMITED.js +24 -0
- package/src/client/websocket/handlers/index.js +1 -0
- package/src/index.js +0 -1
- package/src/managers/GuildMemberManager.js +44 -23
- package/src/managers/MessageManager.js +2 -2
- package/typings/index.d.mts +8 -13
- package/typings/index.d.ts +8 -13
- package/src/client/BaseClient.js +0 -131
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "discord.js",
|
|
4
|
-
"version": "15.0.0-dev.
|
|
4
|
+
"version": "15.0.0-dev.1763164928-7349a6ee3",
|
|
5
5
|
"description": "A powerful library for interacting with the Discord API",
|
|
6
6
|
"main": "./src/index.js",
|
|
7
7
|
"types": "./typings/index.d.ts",
|
|
@@ -61,12 +61,12 @@
|
|
|
61
61
|
"magic-bytes.js": "^1.12.1",
|
|
62
62
|
"tslib": "^2.8.1",
|
|
63
63
|
"undici": "7.16.0",
|
|
64
|
-
"@discordjs/
|
|
65
|
-
"@discordjs/
|
|
66
|
-
"@discordjs/rest": "3.0.0-dev.
|
|
67
|
-
"@discordjs/
|
|
68
|
-
"@discordjs/ws": "3.0.0-dev.
|
|
69
|
-
"@discordjs/
|
|
64
|
+
"@discordjs/builders": "2.0.0-dev.1763164928-7349a6ee3",
|
|
65
|
+
"@discordjs/collection": "3.0.0-dev.1763164928-7349a6ee3",
|
|
66
|
+
"@discordjs/rest": "3.0.0-dev.1763164928-7349a6ee3",
|
|
67
|
+
"@discordjs/util": "2.0.0-dev.1763164928-7349a6ee3",
|
|
68
|
+
"@discordjs/ws": "3.0.0-dev.1763164928-7349a6ee3",
|
|
69
|
+
"@discordjs/formatters": "1.0.0-dev.1763164928-7349a6ee3"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@favware/cliff-jumper": "^4.1.0",
|
|
@@ -83,8 +83,8 @@
|
|
|
83
83
|
"turbo": "^2.5.8",
|
|
84
84
|
"typescript": "~5.9.3",
|
|
85
85
|
"@discordjs/api-extractor": "7.52.7",
|
|
86
|
-
"@discordjs/
|
|
87
|
-
"@discordjs/
|
|
86
|
+
"@discordjs/docgen": "0.12.1",
|
|
87
|
+
"@discordjs/scripts": "0.1.0"
|
|
88
88
|
},
|
|
89
89
|
"engines": {
|
|
90
90
|
"node": ">=22.12.0"
|
package/src/client/Client.js
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
const process = require('node:process');
|
|
4
4
|
const { clearTimeout, setImmediate, setTimeout } = require('node:timers');
|
|
5
5
|
const { Collection } = require('@discordjs/collection');
|
|
6
|
-
const { makeURLSearchParams } = require('@discordjs/rest');
|
|
6
|
+
const { REST, RESTEvents, makeURLSearchParams } = require('@discordjs/rest');
|
|
7
7
|
const { WebSocketManager, WebSocketShardEvents, WebSocketShardStatus } = require('@discordjs/ws');
|
|
8
|
+
const { AsyncEventEmitter } = require('@vladfrangu/async_event_emitter');
|
|
8
9
|
const { GatewayDispatchEvents, GatewayIntentBits, OAuth2Scopes, Routes } = require('discord-api-types/v10');
|
|
9
10
|
const { DiscordjsError, DiscordjsTypeError, ErrorCodes } = require('../errors/index.js');
|
|
10
11
|
const { ChannelManager } = require('../managers/ChannelManager.js');
|
|
@@ -28,7 +29,7 @@ const { Options } = require('../util/Options.js');
|
|
|
28
29
|
const { PermissionsBitField } = require('../util/PermissionsBitField.js');
|
|
29
30
|
const { Status } = require('../util/Status.js');
|
|
30
31
|
const { Sweepers } = require('../util/Sweepers.js');
|
|
31
|
-
const {
|
|
32
|
+
const { flatten } = require('../util/Util.js');
|
|
32
33
|
const { ActionsManager } = require('./actions/ActionsManager.js');
|
|
33
34
|
const { ClientVoiceManager } = require('./voice/ClientVoiceManager.js');
|
|
34
35
|
const { PacketHandlers } = require('./websocket/handlers/index.js');
|
|
@@ -47,24 +48,66 @@ const BeforeReadyWhitelist = [
|
|
|
47
48
|
/**
|
|
48
49
|
* The main hub for interacting with the Discord API, and the starting point for any bot.
|
|
49
50
|
*
|
|
50
|
-
* @extends {
|
|
51
|
+
* @extends {AsyncEventEmitter}
|
|
51
52
|
*/
|
|
52
|
-
class Client extends
|
|
53
|
+
class Client extends AsyncEventEmitter {
|
|
53
54
|
/**
|
|
54
55
|
* @param {ClientOptions} options Options for the client
|
|
55
56
|
*/
|
|
56
57
|
constructor(options) {
|
|
57
|
-
super(
|
|
58
|
+
super();
|
|
59
|
+
|
|
60
|
+
if (typeof options !== 'object' || options === null) {
|
|
61
|
+
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const defaultOptions = Options.createDefault();
|
|
65
|
+
/**
|
|
66
|
+
* The options the client was instantiated with
|
|
67
|
+
*
|
|
68
|
+
* @type {ClientOptions}
|
|
69
|
+
*/
|
|
70
|
+
this.options = {
|
|
71
|
+
...defaultOptions,
|
|
72
|
+
...options,
|
|
73
|
+
presence: {
|
|
74
|
+
...defaultOptions.presence,
|
|
75
|
+
...options.presence,
|
|
76
|
+
},
|
|
77
|
+
sweepers: {
|
|
78
|
+
...defaultOptions.sweepers,
|
|
79
|
+
...options.sweepers,
|
|
80
|
+
},
|
|
81
|
+
ws: {
|
|
82
|
+
...defaultOptions.ws,
|
|
83
|
+
...options.ws,
|
|
84
|
+
},
|
|
85
|
+
rest: {
|
|
86
|
+
...defaultOptions.rest,
|
|
87
|
+
...options.rest,
|
|
88
|
+
userAgentAppendix: options.rest?.userAgentAppendix
|
|
89
|
+
? `${Options.userAgentAppendix} ${options.rest.userAgentAppendix}`
|
|
90
|
+
: Options.userAgentAppendix,
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* The REST manager of the client
|
|
96
|
+
*
|
|
97
|
+
* @type {REST}
|
|
98
|
+
*/
|
|
99
|
+
this.rest = new REST(this.options.rest);
|
|
100
|
+
|
|
101
|
+
this.rest.on(RESTEvents.Debug, message => this.emit(Events.Debug, message));
|
|
58
102
|
|
|
59
103
|
const data = require('node:worker_threads').workerData ?? process.env;
|
|
60
|
-
const defaults = Options.createDefault();
|
|
61
104
|
|
|
62
|
-
if (this.options.ws.shardIds ===
|
|
105
|
+
if (this.options.ws.shardIds === defaultOptions.ws.shardIds && 'SHARDS' in data) {
|
|
63
106
|
const shards = JSON.parse(data.SHARDS);
|
|
64
107
|
this.options.ws.shardIds = Array.isArray(shards) ? shards : [shards];
|
|
65
108
|
}
|
|
66
109
|
|
|
67
|
-
if (this.options.ws.shardCount ===
|
|
110
|
+
if (this.options.ws.shardCount === defaultOptions.ws.shardCount && 'SHARD_COUNT' in data) {
|
|
68
111
|
this.options.ws.shardCount = Number(data.SHARD_COUNT);
|
|
69
112
|
}
|
|
70
113
|
|
|
@@ -442,12 +485,56 @@ class Client extends BaseClient {
|
|
|
442
485
|
}
|
|
443
486
|
|
|
444
487
|
/**
|
|
445
|
-
*
|
|
488
|
+
* Options used for deleting a webhook.
|
|
489
|
+
*
|
|
490
|
+
* @typedef {Object} WebhookDeleteOptions
|
|
491
|
+
* @property {string} [token] Token of the webhook
|
|
492
|
+
* @property {string} [reason] The reason for deleting the webhook
|
|
493
|
+
*/
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* Deletes a webhook.
|
|
497
|
+
*
|
|
498
|
+
* @param {Snowflake} id The webhook's id
|
|
499
|
+
* @param {WebhookDeleteOptions} [options] Options for deleting the webhook
|
|
500
|
+
* @returns {Promise<void>}
|
|
501
|
+
*/
|
|
502
|
+
async deleteWebhook(id, { token, reason } = {}) {
|
|
503
|
+
await this.rest.delete(Routes.webhook(id, token), { auth: !token, reason });
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* Increments max listeners by one, if they are not zero.
|
|
508
|
+
*
|
|
509
|
+
* @private
|
|
510
|
+
*/
|
|
511
|
+
incrementMaxListeners() {
|
|
512
|
+
const maxListeners = this.getMaxListeners();
|
|
513
|
+
if (maxListeners !== 0) {
|
|
514
|
+
this.setMaxListeners(maxListeners + 1);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Decrements max listeners by one, if they are not zero.
|
|
520
|
+
*
|
|
521
|
+
* @private
|
|
522
|
+
*/
|
|
523
|
+
decrementMaxListeners() {
|
|
524
|
+
const maxListeners = this.getMaxListeners();
|
|
525
|
+
if (maxListeners !== 0) {
|
|
526
|
+
this.setMaxListeners(maxListeners - 1);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* Destroys all assets used by the client.
|
|
446
532
|
*
|
|
447
533
|
* @returns {Promise<void>}
|
|
448
534
|
*/
|
|
449
535
|
async destroy() {
|
|
450
|
-
|
|
536
|
+
this.rest.clearHashSweeper();
|
|
537
|
+
this.rest.clearHandlerSweeper();
|
|
451
538
|
|
|
452
539
|
this.sweepers.destroy();
|
|
453
540
|
await this.ws.destroy();
|
|
@@ -701,10 +788,7 @@ class Client extends BaseClient {
|
|
|
701
788
|
}
|
|
702
789
|
|
|
703
790
|
toJSON() {
|
|
704
|
-
return
|
|
705
|
-
actions: false,
|
|
706
|
-
presence: false,
|
|
707
|
-
});
|
|
791
|
+
return flatten(this, { actions: false, presence: false });
|
|
708
792
|
}
|
|
709
793
|
|
|
710
794
|
/**
|
|
@@ -797,6 +881,10 @@ class Client extends BaseClient {
|
|
|
797
881
|
throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'jsonTransformer', 'a function');
|
|
798
882
|
}
|
|
799
883
|
}
|
|
884
|
+
|
|
885
|
+
async [Symbol.asyncDispose]() {
|
|
886
|
+
await this.destroy();
|
|
887
|
+
}
|
|
800
888
|
}
|
|
801
889
|
|
|
802
890
|
exports.Client = Client;
|
|
@@ -846,6 +934,11 @@ exports.Client = Client;
|
|
|
846
934
|
* @see {@link https://discord.js.org/docs/packages/collection/stable/Collection:Class}
|
|
847
935
|
*/
|
|
848
936
|
|
|
937
|
+
/**
|
|
938
|
+
* @external REST
|
|
939
|
+
* @see {@link https://discord.js.org/docs/packages/rest/stable/REST:Class}
|
|
940
|
+
*/
|
|
941
|
+
|
|
849
942
|
/**
|
|
850
943
|
* @external ImageURLOptions
|
|
851
944
|
* @see {@link https://discord.js.org/docs/packages/rest/stable/ImageURLOptions:Interface}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const process = require('node:process');
|
|
4
|
+
const { GatewayOpcodes } = require('discord-api-types/v10');
|
|
5
|
+
|
|
6
|
+
const emittedFor = new Set();
|
|
7
|
+
|
|
8
|
+
module.exports = (client, { d: data }) => {
|
|
9
|
+
switch (data.opcode) {
|
|
10
|
+
case GatewayOpcodes.RequestGuildMembers: {
|
|
11
|
+
break;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
default: {
|
|
15
|
+
if (!emittedFor.has(data.opcode)) {
|
|
16
|
+
process.emitWarning(
|
|
17
|
+
`Hit a gateway rate limit on opcode ${data.opcode} (${GatewayOpcodes[data.opcode]}). If the discord.js version you're using is up-to-date, please open an issue on GitHub.`,
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
emittedFor.add(data.opcode);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
};
|
|
@@ -52,6 +52,7 @@ const PacketHandlers = Object.fromEntries([
|
|
|
52
52
|
['MESSAGE_REACTION_REMOVE_EMOJI', require('./MESSAGE_REACTION_REMOVE_EMOJI.js')],
|
|
53
53
|
['MESSAGE_UPDATE', require('./MESSAGE_UPDATE.js')],
|
|
54
54
|
['PRESENCE_UPDATE', require('./PRESENCE_UPDATE.js')],
|
|
55
|
+
['RATE_LIMITED', require('./RATE_LIMITED.js')],
|
|
55
56
|
['READY', require('./READY.js')],
|
|
56
57
|
['SOUNDBOARD_SOUNDS', require('./SOUNDBOARD_SOUNDS.js')],
|
|
57
58
|
['STAGE_INSTANCE_CREATE', require('./STAGE_INSTANCE_CREATE.js')],
|
package/src/index.js
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
const { __exportStar } = require('tslib');
|
|
4
4
|
|
|
5
5
|
// "Root" classes (starting points)
|
|
6
|
-
exports.BaseClient = require('./client/BaseClient.js').BaseClient;
|
|
7
6
|
exports.Client = require('./client/Client.js').Client;
|
|
8
7
|
exports.Shard = require('./sharding/Shard.js').Shard;
|
|
9
8
|
exports.ShardClientUtil = require('./sharding/ShardClientUtil.js').ShardClientUtil;
|
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
const { setTimeout, clearTimeout } = require('node:timers');
|
|
4
4
|
const { Collection } = require('@discordjs/collection');
|
|
5
5
|
const { makeURLSearchParams } = require('@discordjs/rest');
|
|
6
|
+
const { GatewayRateLimitError } = require('@discordjs/util');
|
|
7
|
+
const { WebSocketShardEvents } = require('@discordjs/ws');
|
|
6
8
|
const { DiscordSnowflake } = require('@sapphire/snowflake');
|
|
7
|
-
const { Routes, GatewayOpcodes } = require('discord-api-types/v10');
|
|
9
|
+
const { Routes, GatewayOpcodes, GatewayDispatchEvents } = require('discord-api-types/v10');
|
|
8
10
|
const { DiscordjsError, DiscordjsTypeError, DiscordjsRangeError, ErrorCodes } = require('../errors/index.js');
|
|
9
11
|
const { BaseGuildVoiceChannel } = require('../structures/BaseGuildVoiceChannel.js');
|
|
10
12
|
const { GuildMember } = require('../structures/GuildMember.js');
|
|
@@ -246,24 +248,27 @@ class GuildMemberManager extends CachedManager {
|
|
|
246
248
|
const query = initialQuery ?? (users ? undefined : '');
|
|
247
249
|
|
|
248
250
|
return new Promise((resolve, reject) => {
|
|
249
|
-
this.guild.client.ws.send(this.guild.shardId, {
|
|
250
|
-
op: GatewayOpcodes.RequestGuildMembers,
|
|
251
|
-
// eslint-disable-next-line id-length
|
|
252
|
-
d: {
|
|
253
|
-
guild_id: this.guild.id,
|
|
254
|
-
presences,
|
|
255
|
-
user_ids: users,
|
|
256
|
-
query,
|
|
257
|
-
nonce,
|
|
258
|
-
limit,
|
|
259
|
-
},
|
|
260
|
-
});
|
|
261
251
|
const fetchedMembers = new Collection();
|
|
262
252
|
let index = 0;
|
|
253
|
+
|
|
254
|
+
const cleanup = () => {
|
|
255
|
+
/* eslint-disable no-use-before-define */
|
|
256
|
+
clearTimeout(timeout);
|
|
257
|
+
|
|
258
|
+
this.client.ws.removeListener(WebSocketShardEvents.Dispatch, rateLimitHandler);
|
|
259
|
+
this.client.removeListener(Events.GuildMembersChunk, handler);
|
|
260
|
+
this.client.decrementMaxListeners();
|
|
261
|
+
/* eslint-enable no-use-before-define */
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
const timeout = setTimeout(() => {
|
|
265
|
+
cleanup();
|
|
266
|
+
reject(new DiscordjsError(ErrorCodes.GuildMembersTimeout));
|
|
267
|
+
}, time).unref();
|
|
268
|
+
|
|
263
269
|
const handler = (members, _, chunk) => {
|
|
264
270
|
if (chunk.nonce !== nonce) return;
|
|
265
271
|
|
|
266
|
-
// eslint-disable-next-line no-use-before-define
|
|
267
272
|
timeout.refresh();
|
|
268
273
|
index++;
|
|
269
274
|
for (const member of members.values()) {
|
|
@@ -271,21 +276,37 @@ class GuildMemberManager extends CachedManager {
|
|
|
271
276
|
}
|
|
272
277
|
|
|
273
278
|
if (members.size < 1_000 || (limit && fetchedMembers.size >= limit) || index === chunk.count) {
|
|
274
|
-
|
|
275
|
-
clearTimeout(timeout);
|
|
276
|
-
this.client.removeListener(Events.GuildMembersChunk, handler);
|
|
277
|
-
this.client.decrementMaxListeners();
|
|
279
|
+
cleanup();
|
|
278
280
|
resolve(users && !Array.isArray(users) && fetchedMembers.size ? fetchedMembers.first() : fetchedMembers);
|
|
279
281
|
}
|
|
280
282
|
};
|
|
281
283
|
|
|
282
|
-
const
|
|
283
|
-
this.
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
284
|
+
const requestData = {
|
|
285
|
+
guild_id: this.guild.id,
|
|
286
|
+
presences,
|
|
287
|
+
user_ids: users,
|
|
288
|
+
query,
|
|
289
|
+
nonce,
|
|
290
|
+
limit,
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
const rateLimitHandler = payload => {
|
|
294
|
+
if (payload.t === GatewayDispatchEvents.RateLimited && payload.d.meta.nonce === nonce) {
|
|
295
|
+
cleanup();
|
|
296
|
+
reject(new GatewayRateLimitError(payload.d, requestData));
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
this.client.ws.on(WebSocketShardEvents.Dispatch, rateLimitHandler);
|
|
301
|
+
|
|
287
302
|
this.client.incrementMaxListeners();
|
|
288
303
|
this.client.on(Events.GuildMembersChunk, handler);
|
|
304
|
+
|
|
305
|
+
this.guild.client.ws.send(this.guild.shardId, {
|
|
306
|
+
op: GatewayOpcodes.RequestGuildMembers,
|
|
307
|
+
// eslint-disable-next-line id-length
|
|
308
|
+
d: requestData,
|
|
309
|
+
});
|
|
289
310
|
});
|
|
290
311
|
}
|
|
291
312
|
|
|
@@ -150,8 +150,8 @@ class MessageManager extends CachedManager {
|
|
|
150
150
|
*/
|
|
151
151
|
|
|
152
152
|
/**
|
|
153
|
-
* Fetches the pinned messages of this channel
|
|
154
|
-
* <info>The returned
|
|
153
|
+
* Fetches the pinned messages of this channel, returning a paginated result.
|
|
154
|
+
* <info>The returned messages do not contain any reaction data.
|
|
155
155
|
* Those need to be fetched separately.</info>
|
|
156
156
|
*
|
|
157
157
|
* @param {FetchPinnedMessagesOptions} [options={}] Options for fetching pinned messages
|
package/typings/index.d.mts
CHANGED
|
@@ -492,18 +492,6 @@ export abstract class Base {
|
|
|
492
492
|
public valueOf(): string;
|
|
493
493
|
}
|
|
494
494
|
|
|
495
|
-
export class BaseClient<Events extends {}> extends AsyncEventEmitter<Events> implements AsyncDisposable {
|
|
496
|
-
public constructor(options?: ClientOptions);
|
|
497
|
-
private decrementMaxListeners(): void;
|
|
498
|
-
private incrementMaxListeners(): void;
|
|
499
|
-
|
|
500
|
-
public options: ClientOptions;
|
|
501
|
-
public rest: REST;
|
|
502
|
-
public destroy(): void;
|
|
503
|
-
public toJSON(...props: Record<string, boolean | string>[]): unknown;
|
|
504
|
-
public [Symbol.asyncDispose](): Promise<void>;
|
|
505
|
-
}
|
|
506
|
-
|
|
507
495
|
export type GuildCacheMessage<Cached extends CacheType> = CacheTypeReducer<
|
|
508
496
|
Cached,
|
|
509
497
|
Message<true>,
|
|
@@ -913,7 +901,10 @@ export type If<Value extends boolean, TrueResult, FalseResult = null> = Value ex
|
|
|
913
901
|
? FalseResult
|
|
914
902
|
: FalseResult | TrueResult;
|
|
915
903
|
|
|
916
|
-
export class Client<Ready extends boolean = boolean>
|
|
904
|
+
export class Client<Ready extends boolean = boolean>
|
|
905
|
+
extends AsyncEventEmitter<ClientEventTypes>
|
|
906
|
+
implements AsyncDisposable
|
|
907
|
+
{
|
|
917
908
|
public constructor(options: ClientOptions);
|
|
918
909
|
private readonly actions: unknown;
|
|
919
910
|
private readonly expectedGuilds: Set<Snowflake>;
|
|
@@ -928,6 +919,8 @@ export class Client<Ready extends boolean = boolean> extends BaseClient<ClientEv
|
|
|
928
919
|
private _triggerClientReady(): void;
|
|
929
920
|
private _validateOptions(options: ClientOptions): void;
|
|
930
921
|
private get _censoredToken(): string | null;
|
|
922
|
+
private decrementMaxListeners(): void;
|
|
923
|
+
private incrementMaxListeners(): void;
|
|
931
924
|
// This a technique used to brand the ready state. Or else we'll get `never` errors on typeguard checks.
|
|
932
925
|
private readonly _ready: Ready;
|
|
933
926
|
|
|
@@ -939,6 +932,7 @@ export class Client<Ready extends boolean = boolean> extends BaseClient<ClientEv
|
|
|
939
932
|
public get ping(): number | null;
|
|
940
933
|
public get readyAt(): If<Ready, Date>;
|
|
941
934
|
public readyTimestamp: If<Ready, number>;
|
|
935
|
+
public rest: REST;
|
|
942
936
|
public sweepers: Sweepers;
|
|
943
937
|
public shard: ShardClientUtil | null;
|
|
944
938
|
public status: Status;
|
|
@@ -969,6 +963,7 @@ export class Client<Ready extends boolean = boolean> extends BaseClient<ClientEv
|
|
|
969
963
|
public login(token?: string): Promise<string>;
|
|
970
964
|
public isReady(): this is Client<true>;
|
|
971
965
|
public toJSON(): unknown;
|
|
966
|
+
public [Symbol.asyncDispose](): Promise<void>;
|
|
972
967
|
}
|
|
973
968
|
|
|
974
969
|
export interface StickerPackFetchOptions {
|
package/typings/index.d.ts
CHANGED
|
@@ -492,18 +492,6 @@ export abstract class Base {
|
|
|
492
492
|
public valueOf(): string;
|
|
493
493
|
}
|
|
494
494
|
|
|
495
|
-
export class BaseClient<Events extends {}> extends AsyncEventEmitter<Events> implements AsyncDisposable {
|
|
496
|
-
public constructor(options?: ClientOptions);
|
|
497
|
-
private decrementMaxListeners(): void;
|
|
498
|
-
private incrementMaxListeners(): void;
|
|
499
|
-
|
|
500
|
-
public options: ClientOptions;
|
|
501
|
-
public rest: REST;
|
|
502
|
-
public destroy(): void;
|
|
503
|
-
public toJSON(...props: Record<string, boolean | string>[]): unknown;
|
|
504
|
-
public [Symbol.asyncDispose](): Promise<void>;
|
|
505
|
-
}
|
|
506
|
-
|
|
507
495
|
export type GuildCacheMessage<Cached extends CacheType> = CacheTypeReducer<
|
|
508
496
|
Cached,
|
|
509
497
|
Message<true>,
|
|
@@ -913,7 +901,10 @@ export type If<Value extends boolean, TrueResult, FalseResult = null> = Value ex
|
|
|
913
901
|
? FalseResult
|
|
914
902
|
: FalseResult | TrueResult;
|
|
915
903
|
|
|
916
|
-
export class Client<Ready extends boolean = boolean>
|
|
904
|
+
export class Client<Ready extends boolean = boolean>
|
|
905
|
+
extends AsyncEventEmitter<ClientEventTypes>
|
|
906
|
+
implements AsyncDisposable
|
|
907
|
+
{
|
|
917
908
|
public constructor(options: ClientOptions);
|
|
918
909
|
private readonly actions: unknown;
|
|
919
910
|
private readonly expectedGuilds: Set<Snowflake>;
|
|
@@ -928,6 +919,8 @@ export class Client<Ready extends boolean = boolean> extends BaseClient<ClientEv
|
|
|
928
919
|
private _triggerClientReady(): void;
|
|
929
920
|
private _validateOptions(options: ClientOptions): void;
|
|
930
921
|
private get _censoredToken(): string | null;
|
|
922
|
+
private decrementMaxListeners(): void;
|
|
923
|
+
private incrementMaxListeners(): void;
|
|
931
924
|
// This a technique used to brand the ready state. Or else we'll get `never` errors on typeguard checks.
|
|
932
925
|
private readonly _ready: Ready;
|
|
933
926
|
|
|
@@ -939,6 +932,7 @@ export class Client<Ready extends boolean = boolean> extends BaseClient<ClientEv
|
|
|
939
932
|
public get ping(): number | null;
|
|
940
933
|
public get readyAt(): If<Ready, Date>;
|
|
941
934
|
public readyTimestamp: If<Ready, number>;
|
|
935
|
+
public rest: REST;
|
|
942
936
|
public sweepers: Sweepers;
|
|
943
937
|
public shard: ShardClientUtil | null;
|
|
944
938
|
public status: Status;
|
|
@@ -969,6 +963,7 @@ export class Client<Ready extends boolean = boolean> extends BaseClient<ClientEv
|
|
|
969
963
|
public login(token?: string): Promise<string>;
|
|
970
964
|
public isReady(): this is Client<true>;
|
|
971
965
|
public toJSON(): unknown;
|
|
966
|
+
public [Symbol.asyncDispose](): Promise<void>;
|
|
972
967
|
}
|
|
973
968
|
|
|
974
969
|
export interface StickerPackFetchOptions {
|
package/src/client/BaseClient.js
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { REST, RESTEvents } = require('@discordjs/rest');
|
|
4
|
-
const { AsyncEventEmitter } = require('@vladfrangu/async_event_emitter');
|
|
5
|
-
const { Routes } = require('discord-api-types/v10');
|
|
6
|
-
const { DiscordjsTypeError, ErrorCodes } = require('../errors/index.js');
|
|
7
|
-
const { Events } = require('../util/Events.js');
|
|
8
|
-
const { Options } = require('../util/Options.js');
|
|
9
|
-
const { flatten } = require('../util/Util.js');
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* The base class for all clients.
|
|
13
|
-
*
|
|
14
|
-
* @extends {AsyncEventEmitter}
|
|
15
|
-
*/
|
|
16
|
-
class BaseClient extends AsyncEventEmitter {
|
|
17
|
-
constructor(options = {}) {
|
|
18
|
-
super();
|
|
19
|
-
|
|
20
|
-
if (typeof options !== 'object' || options === null) {
|
|
21
|
-
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const defaultOptions = Options.createDefault();
|
|
25
|
-
/**
|
|
26
|
-
* The options the client was instantiated with
|
|
27
|
-
*
|
|
28
|
-
* @type {ClientOptions}
|
|
29
|
-
*/
|
|
30
|
-
this.options = {
|
|
31
|
-
...defaultOptions,
|
|
32
|
-
...options,
|
|
33
|
-
presence: {
|
|
34
|
-
...defaultOptions.presence,
|
|
35
|
-
...options.presence,
|
|
36
|
-
},
|
|
37
|
-
sweepers: {
|
|
38
|
-
...defaultOptions.sweepers,
|
|
39
|
-
...options.sweepers,
|
|
40
|
-
},
|
|
41
|
-
ws: {
|
|
42
|
-
...defaultOptions.ws,
|
|
43
|
-
...options.ws,
|
|
44
|
-
},
|
|
45
|
-
rest: {
|
|
46
|
-
...defaultOptions.rest,
|
|
47
|
-
...options.rest,
|
|
48
|
-
userAgentAppendix: options.rest?.userAgentAppendix
|
|
49
|
-
? `${Options.userAgentAppendix} ${options.rest.userAgentAppendix}`
|
|
50
|
-
: Options.userAgentAppendix,
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* The REST manager of the client
|
|
56
|
-
*
|
|
57
|
-
* @type {REST}
|
|
58
|
-
*/
|
|
59
|
-
this.rest = new REST(this.options.rest);
|
|
60
|
-
|
|
61
|
-
this.rest.on(RESTEvents.Debug, message => this.emit(Events.Debug, message));
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Destroys all assets used by the base client.
|
|
66
|
-
*
|
|
67
|
-
* @returns {void}
|
|
68
|
-
*/
|
|
69
|
-
destroy() {
|
|
70
|
-
this.rest.clearHashSweeper();
|
|
71
|
-
this.rest.clearHandlerSweeper();
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Options used for deleting a webhook.
|
|
76
|
-
*
|
|
77
|
-
* @typedef {Object} WebhookDeleteOptions
|
|
78
|
-
* @property {string} [token] Token of the webhook
|
|
79
|
-
* @property {string} [reason] The reason for deleting the webhook
|
|
80
|
-
*/
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Deletes a webhook.
|
|
84
|
-
*
|
|
85
|
-
* @param {Snowflake} id The webhook's id
|
|
86
|
-
* @param {WebhookDeleteOptions} [options] Options for deleting the webhook
|
|
87
|
-
* @returns {Promise<void>}
|
|
88
|
-
*/
|
|
89
|
-
async deleteWebhook(id, { token, reason } = {}) {
|
|
90
|
-
await this.rest.delete(Routes.webhook(id, token), { auth: !token, reason });
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Increments max listeners by one, if they are not zero.
|
|
95
|
-
*
|
|
96
|
-
* @private
|
|
97
|
-
*/
|
|
98
|
-
incrementMaxListeners() {
|
|
99
|
-
const maxListeners = this.getMaxListeners();
|
|
100
|
-
if (maxListeners !== 0) {
|
|
101
|
-
this.setMaxListeners(maxListeners + 1);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Decrements max listeners by one, if they are not zero.
|
|
107
|
-
*
|
|
108
|
-
* @private
|
|
109
|
-
*/
|
|
110
|
-
decrementMaxListeners() {
|
|
111
|
-
const maxListeners = this.getMaxListeners();
|
|
112
|
-
if (maxListeners !== 0) {
|
|
113
|
-
this.setMaxListeners(maxListeners - 1);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
toJSON(...props) {
|
|
118
|
-
return flatten(this, ...props);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
async [Symbol.asyncDispose]() {
|
|
122
|
-
await this.destroy();
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
exports.BaseClient = BaseClient;
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* @external REST
|
|
130
|
-
* @see {@link https://discord.js.org/docs/packages/rest/stable/REST:Class}
|
|
131
|
-
*/
|