33const process = require ( 'node:process' ) ;
44const { clearTimeout, setImmediate, setTimeout } = require ( 'node:timers' ) ;
55const { Collection } = require ( '@discordjs/collection' ) ;
6- const { makeURLSearchParams } = require ( '@discordjs/rest' ) ;
6+ const { REST , RESTEvents , makeURLSearchParams } = require ( '@discordjs/rest' ) ;
77const { WebSocketManager, WebSocketShardEvents, WebSocketShardStatus } = require ( '@discordjs/ws' ) ;
8+ const { AsyncEventEmitter } = require ( '@vladfrangu/async_event_emitter' ) ;
89const { GatewayDispatchEvents, GatewayIntentBits, OAuth2Scopes, Routes } = require ( 'discord-api-types/v10' ) ;
910const { DiscordjsError, DiscordjsTypeError, ErrorCodes } = require ( '../errors/index.js' ) ;
1011const { ChannelManager } = require ( '../managers/ChannelManager.js' ) ;
@@ -28,7 +29,7 @@ const { Options } = require('../util/Options.js');
2829const { PermissionsBitField } = require ( '../util/PermissionsBitField.js' ) ;
2930const { Status } = require ( '../util/Status.js' ) ;
3031const { Sweepers } = require ( '../util/Sweepers.js' ) ;
31- const { BaseClient } = require ( './BaseClient .js' ) ;
32+ const { flatten } = require ( '../util/Util .js' ) ;
3233const { ActionsManager } = require ( './actions/ActionsManager.js' ) ;
3334const { ClientVoiceManager } = require ( './voice/ClientVoiceManager.js' ) ;
3435const { PacketHandlers } = require ( './websocket/handlers/index.js' ) ;
@@ -47,24 +48,66 @@ const BeforeReadyWhitelist = [
4748/**
4849 * The main hub for interacting with the Discord API, and the starting point for any bot.
4950 *
50- * @extends {BaseClient }
51+ * @extends {AsyncEventEmitter }
5152 */
52- class Client extends BaseClient {
53+ class Client extends AsyncEventEmitter {
5354 /**
5455 * @param {ClientOptions } options Options for the client
5556 */
5657 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 ) ) ;
58102
59103 const data = require ( 'node:worker_threads' ) . workerData ?? process . env ;
60- const defaults = Options . createDefault ( ) ;
61104
62- if ( this . options . ws . shardIds === defaults . ws . shardIds && 'SHARDS' in data ) {
105+ if ( this . options . ws . shardIds === defaultOptions . ws . shardIds && 'SHARDS' in data ) {
63106 const shards = JSON . parse ( data . SHARDS ) ;
64107 this . options . ws . shardIds = Array . isArray ( shards ) ? shards : [ shards ] ;
65108 }
66109
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 ) {
68111 this . options . ws . shardCount = Number ( data . SHARD_COUNT ) ;
69112 }
70113
@@ -442,12 +485,56 @@ class Client extends BaseClient {
442485 }
443486
444487 /**
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.
446532 *
447533 * @returns {Promise<void> }
448534 */
449535 async destroy ( ) {
450- super . destroy ( ) ;
536+ this . rest . clearHashSweeper ( ) ;
537+ this . rest . clearHandlerSweeper ( ) ;
451538
452539 this . sweepers . destroy ( ) ;
453540 await this . ws . destroy ( ) ;
@@ -701,10 +788,7 @@ class Client extends BaseClient {
701788 }
702789
703790 toJSON ( ) {
704- return super . toJSON ( {
705- actions : false ,
706- presence : false ,
707- } ) ;
791+ return flatten ( this , { actions : false , presence : false } ) ;
708792 }
709793
710794 /**
@@ -797,6 +881,10 @@ class Client extends BaseClient {
797881 throw new DiscordjsTypeError ( ErrorCodes . ClientInvalidOption , 'jsonTransformer' , 'a function' ) ;
798882 }
799883 }
884+
885+ async [ Symbol . asyncDispose ] ( ) {
886+ await this . destroy ( ) ;
887+ }
800888}
801889
802890exports . Client = Client ;
@@ -846,6 +934,11 @@ exports.Client = Client;
846934 * @see {@link https://discord.js.org/docs/packages/collection/stable/Collection:Class }
847935 */
848936
937+ /**
938+ * @external REST
939+ * @see {@link https://discord.js.org/docs/packages/rest/stable/REST:Class }
940+ */
941+
849942/**
850943 * @external ImageURLOptions
851944 * @see {@link https://discord.js.org/docs/packages/rest/stable/ImageURLOptions:Interface }
0 commit comments