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 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.1763078518-9f18cb212",
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/collection": "3.0.0-dev.1763078518-9f18cb212",
65
- "@discordjs/builders": "2.0.0-dev.1763078518-9f18cb212",
66
- "@discordjs/rest": "3.0.0-dev.1763078518-9f18cb212",
67
- "@discordjs/formatters": "1.0.0-dev.1763078518-9f18cb212",
68
- "@discordjs/ws": "3.0.0-dev.1763078518-9f18cb212",
69
- "@discordjs/util": "2.0.0-dev.1763078518-9f18cb212"
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/scripts": "0.1.0",
87
- "@discordjs/docgen": "0.12.1"
86
+ "@discordjs/docgen": "0.12.1",
87
+ "@discordjs/scripts": "0.1.0"
88
88
  },
89
89
  "engines": {
90
90
  "node": ">=22.12.0"
@@ -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 { BaseClient } = require('./BaseClient.js');
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 {BaseClient}
51
+ * @extends {AsyncEventEmitter}
51
52
  */
52
- class Client extends BaseClient {
53
+ class Client extends AsyncEventEmitter {
53
54
  /**
54
55
  * @param {ClientOptions} options Options for the client
55
56
  */
56
57
  constructor(options) {
57
- super(options);
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 === defaults.ws.shardIds && 'SHARDS' in data) {
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 === defaults.ws.shardCount && 'SHARD_COUNT' in data) {
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
- * Logs out, terminates the connection to Discord, and destroys the client.
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
- super.destroy();
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 super.toJSON({
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
- // eslint-disable-next-line no-use-before-define
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 timeout = setTimeout(() => {
283
- this.client.removeListener(Events.GuildMembersChunk, handler);
284
- this.client.decrementMaxListeners();
285
- reject(new DiscordjsError(ErrorCodes.GuildMembersTimeout));
286
- }, time).unref();
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 and returns a collection of them.
154
- * <info>The returned Collection does not contain any reaction data of the messages.
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
@@ -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> extends BaseClient<ClientEventTypes> {
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 {
@@ -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> extends BaseClient<ClientEventTypes> {
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 {
@@ -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
- */