mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 16:13:31 +01:00
refactor(client)!: remove BaseClient (#11274)
BREAKING CHANGE: `BaseClient` has been removed and its functionality has been merged into `Client`.
This commit is contained in:
@@ -1,131 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
const { REST, RESTEvents } = require('@discordjs/rest');
|
|
||||||
const { AsyncEventEmitter } = require('@vladfrangu/async_event_emitter');
|
|
||||||
const { Routes } = require('discord-api-types/v10');
|
|
||||||
const { DiscordjsTypeError, ErrorCodes } = require('../errors/index.js');
|
|
||||||
const { Events } = require('../util/Events.js');
|
|
||||||
const { Options } = require('../util/Options.js');
|
|
||||||
const { flatten } = require('../util/Util.js');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The base class for all clients.
|
|
||||||
*
|
|
||||||
* @extends {AsyncEventEmitter}
|
|
||||||
*/
|
|
||||||
class BaseClient extends AsyncEventEmitter {
|
|
||||||
constructor(options = {}) {
|
|
||||||
super();
|
|
||||||
|
|
||||||
if (typeof options !== 'object' || options === null) {
|
|
||||||
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
const defaultOptions = Options.createDefault();
|
|
||||||
/**
|
|
||||||
* The options the client was instantiated with
|
|
||||||
*
|
|
||||||
* @type {ClientOptions}
|
|
||||||
*/
|
|
||||||
this.options = {
|
|
||||||
...defaultOptions,
|
|
||||||
...options,
|
|
||||||
presence: {
|
|
||||||
...defaultOptions.presence,
|
|
||||||
...options.presence,
|
|
||||||
},
|
|
||||||
sweepers: {
|
|
||||||
...defaultOptions.sweepers,
|
|
||||||
...options.sweepers,
|
|
||||||
},
|
|
||||||
ws: {
|
|
||||||
...defaultOptions.ws,
|
|
||||||
...options.ws,
|
|
||||||
},
|
|
||||||
rest: {
|
|
||||||
...defaultOptions.rest,
|
|
||||||
...options.rest,
|
|
||||||
userAgentAppendix: options.rest?.userAgentAppendix
|
|
||||||
? `${Options.userAgentAppendix} ${options.rest.userAgentAppendix}`
|
|
||||||
: Options.userAgentAppendix,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The REST manager of the client
|
|
||||||
*
|
|
||||||
* @type {REST}
|
|
||||||
*/
|
|
||||||
this.rest = new REST(this.options.rest);
|
|
||||||
|
|
||||||
this.rest.on(RESTEvents.Debug, message => this.emit(Events.Debug, message));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroys all assets used by the base client.
|
|
||||||
*
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
destroy() {
|
|
||||||
this.rest.clearHashSweeper();
|
|
||||||
this.rest.clearHandlerSweeper();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Options used for deleting a webhook.
|
|
||||||
*
|
|
||||||
* @typedef {Object} WebhookDeleteOptions
|
|
||||||
* @property {string} [token] Token of the webhook
|
|
||||||
* @property {string} [reason] The reason for deleting the webhook
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes a webhook.
|
|
||||||
*
|
|
||||||
* @param {Snowflake} id The webhook's id
|
|
||||||
* @param {WebhookDeleteOptions} [options] Options for deleting the webhook
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
|
||||||
async deleteWebhook(id, { token, reason } = {}) {
|
|
||||||
await this.rest.delete(Routes.webhook(id, token), { auth: !token, reason });
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Increments max listeners by one, if they are not zero.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
incrementMaxListeners() {
|
|
||||||
const maxListeners = this.getMaxListeners();
|
|
||||||
if (maxListeners !== 0) {
|
|
||||||
this.setMaxListeners(maxListeners + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decrements max listeners by one, if they are not zero.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
decrementMaxListeners() {
|
|
||||||
const maxListeners = this.getMaxListeners();
|
|
||||||
if (maxListeners !== 0) {
|
|
||||||
this.setMaxListeners(maxListeners - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
toJSON(...props) {
|
|
||||||
return flatten(this, ...props);
|
|
||||||
}
|
|
||||||
|
|
||||||
async [Symbol.asyncDispose]() {
|
|
||||||
await this.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.BaseClient = BaseClient;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @external REST
|
|
||||||
* @see {@link https://discord.js.org/docs/packages/rest/stable/REST:Class}
|
|
||||||
*/
|
|
||||||
@@ -3,8 +3,9 @@
|
|||||||
const process = require('node:process');
|
const process = require('node:process');
|
||||||
const { clearTimeout, setImmediate, setTimeout } = require('node:timers');
|
const { clearTimeout, setImmediate, setTimeout } = require('node:timers');
|
||||||
const { Collection } = require('@discordjs/collection');
|
const { Collection } = require('@discordjs/collection');
|
||||||
const { makeURLSearchParams } = require('@discordjs/rest');
|
const { REST, RESTEvents, makeURLSearchParams } = require('@discordjs/rest');
|
||||||
const { WebSocketManager, WebSocketShardEvents, WebSocketShardStatus } = require('@discordjs/ws');
|
const { WebSocketManager, WebSocketShardEvents, WebSocketShardStatus } = require('@discordjs/ws');
|
||||||
|
const { AsyncEventEmitter } = require('@vladfrangu/async_event_emitter');
|
||||||
const { GatewayDispatchEvents, GatewayIntentBits, OAuth2Scopes, Routes } = require('discord-api-types/v10');
|
const { GatewayDispatchEvents, GatewayIntentBits, OAuth2Scopes, Routes } = require('discord-api-types/v10');
|
||||||
const { DiscordjsError, DiscordjsTypeError, ErrorCodes } = require('../errors/index.js');
|
const { DiscordjsError, DiscordjsTypeError, ErrorCodes } = require('../errors/index.js');
|
||||||
const { ChannelManager } = require('../managers/ChannelManager.js');
|
const { ChannelManager } = require('../managers/ChannelManager.js');
|
||||||
@@ -28,7 +29,7 @@ const { Options } = require('../util/Options.js');
|
|||||||
const { PermissionsBitField } = require('../util/PermissionsBitField.js');
|
const { PermissionsBitField } = require('../util/PermissionsBitField.js');
|
||||||
const { Status } = require('../util/Status.js');
|
const { Status } = require('../util/Status.js');
|
||||||
const { Sweepers } = require('../util/Sweepers.js');
|
const { Sweepers } = require('../util/Sweepers.js');
|
||||||
const { BaseClient } = require('./BaseClient.js');
|
const { flatten } = require('../util/Util.js');
|
||||||
const { ActionsManager } = require('./actions/ActionsManager.js');
|
const { ActionsManager } = require('./actions/ActionsManager.js');
|
||||||
const { ClientVoiceManager } = require('./voice/ClientVoiceManager.js');
|
const { ClientVoiceManager } = require('./voice/ClientVoiceManager.js');
|
||||||
const { PacketHandlers } = require('./websocket/handlers/index.js');
|
const { PacketHandlers } = require('./websocket/handlers/index.js');
|
||||||
@@ -47,24 +48,66 @@ const BeforeReadyWhitelist = [
|
|||||||
/**
|
/**
|
||||||
* The main hub for interacting with the Discord API, and the starting point for any bot.
|
* The main hub for interacting with the Discord API, and the starting point for any bot.
|
||||||
*
|
*
|
||||||
* @extends {BaseClient}
|
* @extends {AsyncEventEmitter}
|
||||||
*/
|
*/
|
||||||
class Client extends BaseClient {
|
class Client extends AsyncEventEmitter {
|
||||||
/**
|
/**
|
||||||
* @param {ClientOptions} options Options for the client
|
* @param {ClientOptions} options Options for the client
|
||||||
*/
|
*/
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
super(options);
|
super();
|
||||||
|
|
||||||
|
if (typeof options !== 'object' || options === null) {
|
||||||
|
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultOptions = Options.createDefault();
|
||||||
|
/**
|
||||||
|
* The options the client was instantiated with
|
||||||
|
*
|
||||||
|
* @type {ClientOptions}
|
||||||
|
*/
|
||||||
|
this.options = {
|
||||||
|
...defaultOptions,
|
||||||
|
...options,
|
||||||
|
presence: {
|
||||||
|
...defaultOptions.presence,
|
||||||
|
...options.presence,
|
||||||
|
},
|
||||||
|
sweepers: {
|
||||||
|
...defaultOptions.sweepers,
|
||||||
|
...options.sweepers,
|
||||||
|
},
|
||||||
|
ws: {
|
||||||
|
...defaultOptions.ws,
|
||||||
|
...options.ws,
|
||||||
|
},
|
||||||
|
rest: {
|
||||||
|
...defaultOptions.rest,
|
||||||
|
...options.rest,
|
||||||
|
userAgentAppendix: options.rest?.userAgentAppendix
|
||||||
|
? `${Options.userAgentAppendix} ${options.rest.userAgentAppendix}`
|
||||||
|
: Options.userAgentAppendix,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The REST manager of the client
|
||||||
|
*
|
||||||
|
* @type {REST}
|
||||||
|
*/
|
||||||
|
this.rest = new REST(this.options.rest);
|
||||||
|
|
||||||
|
this.rest.on(RESTEvents.Debug, message => this.emit(Events.Debug, message));
|
||||||
|
|
||||||
const data = require('node:worker_threads').workerData ?? process.env;
|
const data = require('node:worker_threads').workerData ?? process.env;
|
||||||
const defaults = Options.createDefault();
|
|
||||||
|
|
||||||
if (this.options.ws.shardIds === defaults.ws.shardIds && 'SHARDS' in data) {
|
if (this.options.ws.shardIds === defaultOptions.ws.shardIds && 'SHARDS' in data) {
|
||||||
const shards = JSON.parse(data.SHARDS);
|
const shards = JSON.parse(data.SHARDS);
|
||||||
this.options.ws.shardIds = Array.isArray(shards) ? shards : [shards];
|
this.options.ws.shardIds = Array.isArray(shards) ? shards : [shards];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.options.ws.shardCount === defaults.ws.shardCount && 'SHARD_COUNT' in data) {
|
if (this.options.ws.shardCount === defaultOptions.ws.shardCount && 'SHARD_COUNT' in data) {
|
||||||
this.options.ws.shardCount = Number(data.SHARD_COUNT);
|
this.options.ws.shardCount = Number(data.SHARD_COUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,12 +485,56 @@ class Client extends BaseClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs out, terminates the connection to Discord, and destroys the client.
|
* Options used for deleting a webhook.
|
||||||
|
*
|
||||||
|
* @typedef {Object} WebhookDeleteOptions
|
||||||
|
* @property {string} [token] Token of the webhook
|
||||||
|
* @property {string} [reason] The reason for deleting the webhook
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a webhook.
|
||||||
|
*
|
||||||
|
* @param {Snowflake} id The webhook's id
|
||||||
|
* @param {WebhookDeleteOptions} [options] Options for deleting the webhook
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async deleteWebhook(id, { token, reason } = {}) {
|
||||||
|
await this.rest.delete(Routes.webhook(id, token), { auth: !token, reason });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increments max listeners by one, if they are not zero.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
incrementMaxListeners() {
|
||||||
|
const maxListeners = this.getMaxListeners();
|
||||||
|
if (maxListeners !== 0) {
|
||||||
|
this.setMaxListeners(maxListeners + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrements max listeners by one, if they are not zero.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
decrementMaxListeners() {
|
||||||
|
const maxListeners = this.getMaxListeners();
|
||||||
|
if (maxListeners !== 0) {
|
||||||
|
this.setMaxListeners(maxListeners - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys all assets used by the client.
|
||||||
*
|
*
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async destroy() {
|
async destroy() {
|
||||||
super.destroy();
|
this.rest.clearHashSweeper();
|
||||||
|
this.rest.clearHandlerSweeper();
|
||||||
|
|
||||||
this.sweepers.destroy();
|
this.sweepers.destroy();
|
||||||
await this.ws.destroy();
|
await this.ws.destroy();
|
||||||
@@ -701,10 +788,7 @@ class Client extends BaseClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toJSON() {
|
toJSON() {
|
||||||
return super.toJSON({
|
return flatten(this, { actions: false, presence: false });
|
||||||
actions: false,
|
|
||||||
presence: false,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -797,6 +881,10 @@ class Client extends BaseClient {
|
|||||||
throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'jsonTransformer', 'a function');
|
throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'jsonTransformer', 'a function');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async [Symbol.asyncDispose]() {
|
||||||
|
await this.destroy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.Client = Client;
|
exports.Client = Client;
|
||||||
@@ -846,6 +934,11 @@ exports.Client = Client;
|
|||||||
* @see {@link https://discord.js.org/docs/packages/collection/stable/Collection:Class}
|
* @see {@link https://discord.js.org/docs/packages/collection/stable/Collection:Class}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @external REST
|
||||||
|
* @see {@link https://discord.js.org/docs/packages/rest/stable/REST:Class}
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @external ImageURLOptions
|
* @external ImageURLOptions
|
||||||
* @see {@link https://discord.js.org/docs/packages/rest/stable/ImageURLOptions:Interface}
|
* @see {@link https://discord.js.org/docs/packages/rest/stable/ImageURLOptions:Interface}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
const { __exportStar } = require('tslib');
|
const { __exportStar } = require('tslib');
|
||||||
|
|
||||||
// "Root" classes (starting points)
|
// "Root" classes (starting points)
|
||||||
exports.BaseClient = require('./client/BaseClient.js').BaseClient;
|
|
||||||
exports.Client = require('./client/Client.js').Client;
|
exports.Client = require('./client/Client.js').Client;
|
||||||
exports.Shard = require('./sharding/Shard.js').Shard;
|
exports.Shard = require('./sharding/Shard.js').Shard;
|
||||||
exports.ShardClientUtil = require('./sharding/ShardClientUtil.js').ShardClientUtil;
|
exports.ShardClientUtil = require('./sharding/ShardClientUtil.js').ShardClientUtil;
|
||||||
|
|||||||
21
packages/discord.js/typings/index.d.ts
vendored
21
packages/discord.js/typings/index.d.ts
vendored
@@ -492,18 +492,6 @@ export abstract class Base {
|
|||||||
public valueOf(): string;
|
public valueOf(): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BaseClient<Events extends {}> extends AsyncEventEmitter<Events> implements AsyncDisposable {
|
|
||||||
public constructor(options?: ClientOptions);
|
|
||||||
private decrementMaxListeners(): void;
|
|
||||||
private incrementMaxListeners(): void;
|
|
||||||
|
|
||||||
public options: ClientOptions;
|
|
||||||
public rest: REST;
|
|
||||||
public destroy(): void;
|
|
||||||
public toJSON(...props: Record<string, boolean | string>[]): unknown;
|
|
||||||
public [Symbol.asyncDispose](): Promise<void>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type GuildCacheMessage<Cached extends CacheType> = CacheTypeReducer<
|
export type GuildCacheMessage<Cached extends CacheType> = CacheTypeReducer<
|
||||||
Cached,
|
Cached,
|
||||||
Message<true>,
|
Message<true>,
|
||||||
@@ -913,7 +901,10 @@ export type If<Value extends boolean, TrueResult, FalseResult = null> = Value ex
|
|||||||
? FalseResult
|
? FalseResult
|
||||||
: FalseResult | TrueResult;
|
: FalseResult | TrueResult;
|
||||||
|
|
||||||
export class Client<Ready extends boolean = boolean> extends BaseClient<ClientEventTypes> {
|
export class Client<Ready extends boolean = boolean>
|
||||||
|
extends AsyncEventEmitter<ClientEventTypes>
|
||||||
|
implements AsyncDisposable
|
||||||
|
{
|
||||||
public constructor(options: ClientOptions);
|
public constructor(options: ClientOptions);
|
||||||
private readonly actions: unknown;
|
private readonly actions: unknown;
|
||||||
private readonly expectedGuilds: Set<Snowflake>;
|
private readonly expectedGuilds: Set<Snowflake>;
|
||||||
@@ -928,6 +919,8 @@ export class Client<Ready extends boolean = boolean> extends BaseClient<ClientEv
|
|||||||
private _triggerClientReady(): void;
|
private _triggerClientReady(): void;
|
||||||
private _validateOptions(options: ClientOptions): void;
|
private _validateOptions(options: ClientOptions): void;
|
||||||
private get _censoredToken(): string | null;
|
private get _censoredToken(): string | null;
|
||||||
|
private decrementMaxListeners(): void;
|
||||||
|
private incrementMaxListeners(): void;
|
||||||
// This a technique used to brand the ready state. Or else we'll get `never` errors on typeguard checks.
|
// This a technique used to brand the ready state. Or else we'll get `never` errors on typeguard checks.
|
||||||
private readonly _ready: Ready;
|
private readonly _ready: Ready;
|
||||||
|
|
||||||
@@ -939,6 +932,7 @@ export class Client<Ready extends boolean = boolean> extends BaseClient<ClientEv
|
|||||||
public get ping(): number | null;
|
public get ping(): number | null;
|
||||||
public get readyAt(): If<Ready, Date>;
|
public get readyAt(): If<Ready, Date>;
|
||||||
public readyTimestamp: If<Ready, number>;
|
public readyTimestamp: If<Ready, number>;
|
||||||
|
public rest: REST;
|
||||||
public sweepers: Sweepers;
|
public sweepers: Sweepers;
|
||||||
public shard: ShardClientUtil | null;
|
public shard: ShardClientUtil | null;
|
||||||
public status: Status;
|
public status: Status;
|
||||||
@@ -969,6 +963,7 @@ export class Client<Ready extends boolean = boolean> extends BaseClient<ClientEv
|
|||||||
public login(token?: string): Promise<string>;
|
public login(token?: string): Promise<string>;
|
||||||
public isReady(): this is Client<true>;
|
public isReady(): this is Client<true>;
|
||||||
public toJSON(): unknown;
|
public toJSON(): unknown;
|
||||||
|
public [Symbol.asyncDispose](): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StickerPackFetchOptions {
|
export interface StickerPackFetchOptions {
|
||||||
|
|||||||
Reference in New Issue
Block a user