refactor(utils): remove mergeDefault (#9938)

* refactor(utils): remove `mergeDefault`

`BaseClient` and `ShardingManager` not longer mutate options

* refactor(ShardingManager): avoid reassigning method argument
This commit is contained in:
Aura
2023-11-11 10:50:50 +01:00
committed by GitHub
parent d28814d869
commit 5b0aa92c81
4 changed files with 29 additions and 47 deletions

View File

@@ -5,7 +5,7 @@ const { REST } = require('@discordjs/rest');
const { Routes } = require('discord-api-types/v10'); const { Routes } = require('discord-api-types/v10');
const { DiscordjsTypeError, ErrorCodes } = require('../errors'); const { DiscordjsTypeError, ErrorCodes } = require('../errors');
const Options = require('../util/Options'); const Options = require('../util/Options');
const { mergeDefault, flatten } = require('../util/Util'); const { flatten } = require('../util/Util');
/** /**
* The base class for all clients. * The base class for all clients.
@@ -23,15 +23,21 @@ class BaseClient extends EventEmitter {
* The options the client was instantiated with * The options the client was instantiated with
* @type {ClientOptions} * @type {ClientOptions}
*/ */
this.options = mergeDefault(Options.createDefault(), { const defaultOptions = Options.createDefault();
this.options = {
...defaultOptions,
...options, ...options,
ws: {
...defaultOptions.ws,
...options.ws,
},
rest: { rest: {
...options.rest, ...options.rest,
userAgentAppendix: options.rest?.userAgentAppendix userAgentAppendix: options.rest?.userAgentAppendix
? `${Options.userAgentAppendix} ${options.rest.userAgentAppendix}` ? `${Options.userAgentAppendix} ${options.rest.userAgentAppendix}`
: undefined, : undefined,
}, },
}); };
/** /**
* The REST manager of the client * The REST manager of the client

View File

@@ -8,7 +8,7 @@ const { setTimeout: sleep } = require('node:timers/promises');
const { Collection } = require('@discordjs/collection'); const { Collection } = require('@discordjs/collection');
const Shard = require('./Shard'); const Shard = require('./Shard');
const { DiscordjsError, DiscordjsTypeError, DiscordjsRangeError, ErrorCodes } = require('../errors'); const { DiscordjsError, DiscordjsTypeError, DiscordjsRangeError, ErrorCodes } = require('../errors');
const { mergeDefault, fetchRecommendedShardCount } = require('../util/Util'); const { fetchRecommendedShardCount } = require('../util/Util');
/** /**
* This is a utility class that makes multi-process sharding of a bot an easy and painless experience. * This is a utility class that makes multi-process sharding of a bot an easy and painless experience.
@@ -47,20 +47,18 @@ class ShardingManager extends EventEmitter {
* @param {string} file Path to your shard script file * @param {string} file Path to your shard script file
* @param {ShardingManagerOptions} [options] Options for the sharding manager * @param {ShardingManagerOptions} [options] Options for the sharding manager
*/ */
constructor(file, options = {}) { constructor(file, options) {
super(); super();
options = mergeDefault( const _options = {
{ totalShards: 'auto',
totalShards: 'auto', mode: 'process',
mode: 'process', respawn: true,
respawn: true, silent: false,
silent: false, shardArgs: [],
shardArgs: [], execArgv: [],
execArgv: [], token: process.env.DISCORD_TOKEN,
token: process.env.DISCORD_TOKEN, ...options,
}, };
options,
);
/** /**
* Path to the shard script file * Path to the shard script file
@@ -76,7 +74,7 @@ class ShardingManager extends EventEmitter {
* List of shards this sharding manager spawns * List of shards this sharding manager spawns
* @type {string|number[]} * @type {string|number[]}
*/ */
this.shardList = options.shardList ?? 'auto'; this.shardList = _options.shardList ?? 'auto';
if (this.shardList !== 'auto') { if (this.shardList !== 'auto') {
if (!Array.isArray(this.shardList)) { if (!Array.isArray(this.shardList)) {
throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'shardList', 'an array.'); throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'shardList', 'an array.');
@@ -98,7 +96,7 @@ class ShardingManager extends EventEmitter {
* Amount of shards that all sharding managers spawn in total * Amount of shards that all sharding managers spawn in total
* @type {number} * @type {number}
*/ */
this.totalShards = options.totalShards || 'auto'; this.totalShards = _options.totalShards || 'auto';
if (this.totalShards !== 'auto') { if (this.totalShards !== 'auto') {
if (typeof this.totalShards !== 'number' || isNaN(this.totalShards)) { if (typeof this.totalShards !== 'number' || isNaN(this.totalShards)) {
throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'Amount of shards', 'a number.'); throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'Amount of shards', 'a number.');
@@ -115,7 +113,7 @@ class ShardingManager extends EventEmitter {
* Mode for shards to spawn with * Mode for shards to spawn with
* @type {ShardingManagerMode} * @type {ShardingManagerMode}
*/ */
this.mode = options.mode; this.mode = _options.mode;
if (this.mode !== 'process' && this.mode !== 'worker') { if (this.mode !== 'process' && this.mode !== 'worker') {
throw new DiscordjsRangeError(ErrorCodes.ClientInvalidOption, 'Sharding mode', '"process" or "worker"'); throw new DiscordjsRangeError(ErrorCodes.ClientInvalidOption, 'Sharding mode', '"process" or "worker"');
} }
@@ -124,31 +122,31 @@ class ShardingManager extends EventEmitter {
* Whether shards should automatically respawn upon exiting * Whether shards should automatically respawn upon exiting
* @type {boolean} * @type {boolean}
*/ */
this.respawn = options.respawn; this.respawn = _options.respawn;
/** /**
* Whether to pass the silent flag to child process (only when {@link ShardingManager#mode} is `process`) * Whether to pass the silent flag to child process (only when {@link ShardingManager#mode} is `process`)
* @type {boolean} * @type {boolean}
*/ */
this.silent = options.silent; this.silent = _options.silent;
/** /**
* An array of arguments to pass to shards (only when {@link ShardingManager#mode} is `process`) * An array of arguments to pass to shards (only when {@link ShardingManager#mode} is `process`)
* @type {string[]} * @type {string[]}
*/ */
this.shardArgs = options.shardArgs; this.shardArgs = _options.shardArgs;
/** /**
* An array of arguments to pass to the executable (only when {@link ShardingManager#mode} is `process`) * An array of arguments to pass to the executable (only when {@link ShardingManager#mode} is `process`)
* @type {string[]} * @type {string[]}
*/ */
this.execArgv = options.execArgv; this.execArgv = _options.execArgv;
/** /**
* Token to use for obtaining the automatic shard count, and passing to shards * Token to use for obtaining the automatic shard count, and passing to shards
* @type {?string} * @type {?string}
*/ */
this.token = options.token?.replace(/^Bot\s*/i, '') ?? null; this.token = _options.token?.replace(/^Bot\s*/i, '') ?? null;
/** /**
* A collection of shards that this manager has spawned * A collection of shards that this manager has spawned

View File

@@ -122,26 +122,6 @@ function resolvePartialEmoji(emoji) {
return { id, name, animated: Boolean(animated) }; return { id, name, animated: Boolean(animated) };
} }
/**
* Sets default properties on an object that aren't already specified.
* @param {Object} def Default properties
* @param {Object} given Object to assign defaults to
* @returns {Object}
* @private
*/
function mergeDefault(def, given) {
if (!given) return def;
for (const key in def) {
if (!Object.hasOwn(given, key) || given[key] === undefined) {
given[key] = def[key];
} else if (given[key] === Object(given[key])) {
given[key] = mergeDefault(def[key], given[key]);
}
}
return given;
}
/** /**
* Options used to make an error object. * Options used to make an error object.
* @typedef {Object} MakeErrorOptions * @typedef {Object} MakeErrorOptions
@@ -434,7 +414,6 @@ module.exports = {
fetchRecommendedShardCount, fetchRecommendedShardCount,
parseEmoji, parseEmoji,
resolvePartialEmoji, resolvePartialEmoji,
mergeDefault,
makeError, makeError,
makePlainError, makePlainError,
getSortableGroupTypes, getSortableGroupTypes,

View File

@@ -3207,7 +3207,6 @@ export function fetchRecommendedShardCount(token: string, options?: FetchRecomme
export function flatten(obj: unknown, ...props: Record<string, boolean | string>[]): unknown; export function flatten(obj: unknown, ...props: Record<string, boolean | string>[]): unknown;
export function makeError(obj: MakeErrorOptions): Error; export function makeError(obj: MakeErrorOptions): Error;
export function makePlainError(err: Error): MakeErrorOptions; export function makePlainError(err: Error): MakeErrorOptions;
export function mergeDefault(def: unknown, given: unknown): unknown;
export function moveElementInArray(array: unknown[], element: unknown, newIndex: number, offset?: boolean): number; export function moveElementInArray(array: unknown[], element: unknown, newIndex: number, offset?: boolean): number;
export function parseEmoji(text: string): PartialEmoji | null; export function parseEmoji(text: string): PartialEmoji | null;
export function resolveColor(color: ColorResolvable): number; export function resolveColor(color: ColorResolvable): number;