From 00bd92a45172852c9dd20550eb916c101668071c Mon Sep 17 00:00:00 2001 From: Rodry <38259440+ImRodry@users.noreply.github.com> Date: Fri, 3 Sep 2021 12:58:01 +0100 Subject: [PATCH] refactor: ES2021 features (#6540) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Antonio Román Co-authored-by: Voltrex --- src/client/Client.js | 4 +- src/client/websocket/WebSocketManager.js | 15 +++-- src/client/websocket/WebSocketShard.js | 10 ++-- .../ApplicationCommandPermissionsManager.js | 4 +- src/managers/GuildManager.js | 2 +- src/managers/GuildMemberManager.js | 2 +- src/rest/RESTManager.js | 2 +- src/rest/RequestHandler.js | 10 ++-- src/sharding/Shard.js | 4 +- src/sharding/ShardClientUtil.js | 2 +- src/sharding/ShardingManager.js | 4 +- src/structures/Channel.js | 18 +++--- src/structures/ClientPresence.js | 2 +- src/structures/ClientUser.js | 4 +- src/structures/Guild.js | 28 +++++----- src/structures/GuildChannel.js | 2 +- src/structures/GuildTemplate.js | 2 +- src/structures/Integration.js | 4 +- src/structures/Invite.js | 2 +- src/structures/Message.js | 24 ++++---- src/structures/MessageReaction.js | 2 +- src/structures/ThreadChannel.js | 44 ++++++--------- src/structures/Typing.js | 2 +- src/structures/User.js | 4 +- src/structures/VoiceChannel.js | 2 +- src/structures/Webhook.js | 2 +- src/structures/interfaces/TextBasedChannel.js | 10 ++-- src/util/LimitedCollection.js | 4 +- src/util/Options.js | 4 +- src/util/SnowflakeUtil.js | 2 +- src/util/Util.js | 18 +++--- test/random.js | 56 +++++++++---------- test/sendtest.js | 2 +- test/shard.js | 2 +- test/webhooktest.js | 2 +- 35 files changed, 145 insertions(+), 156 deletions(-) diff --git a/src/client/Client.js b/src/client/Client.js index 5550a371e..3d8856fbd 100644 --- a/src/client/Client.js +++ b/src/client/Client.js @@ -181,7 +181,7 @@ class Client extends BaseClient { ); this.sweepMessageInterval = setInterval( this.sweepMessages.bind(this), - this.options.messageSweepInterval * 1000, + this.options.messageSweepInterval * 1_000, ).unref(); } } @@ -401,7 +401,7 @@ class Client extends BaseClient { return -1; } - const lifetimeMs = lifetime * 1000; + const lifetimeMs = lifetime * 1_000; const now = Date.now(); let channels = 0; let messages = 0; diff --git a/src/client/websocket/WebSocketManager.js b/src/client/websocket/WebSocketManager.js index 8f679f6a9..49acd8d62 100644 --- a/src/client/websocket/WebSocketManager.js +++ b/src/client/websocket/WebSocketManager.js @@ -2,6 +2,7 @@ const EventEmitter = require('events'); const { Collection } = require('@discordjs/collection'); +const { RPCErrorCodes } = require('discord-api-types/v9'); const WebSocketShard = require('./WebSocketShard'); const PacketHandlers = require('./handlers'); const { Error } = require('../../errors'); @@ -19,7 +20,11 @@ const BeforeReadyWhitelist = [ ]; const UNRECOVERABLE_CLOSE_CODES = Object.keys(WSCodes).slice(1).map(Number); -const UNRESUMABLE_CLOSE_CODES = [1000, 4006, 4007]; +const UNRESUMABLE_CLOSE_CODES = [ + RPCErrorCodes.UnknownError, + RPCErrorCodes.InvalidPermissions, + RPCErrorCodes.InvalidClientId, +]; /** * The WebSocket manager for this client. @@ -184,7 +189,7 @@ class WebSocketManager extends EventEmitter { }); shard.on(ShardEvents.CLOSE, event => { - if (event.code === 1000 ? this.destroyed : UNRECOVERABLE_CLOSE_CODES.includes(event.code)) { + if (event.code === 1_000 ? this.destroyed : UNRECOVERABLE_CLOSE_CODES.includes(event.code)) { /** * Emitted when a shard's WebSocket disconnects and will no longer reconnect. * @event Client#shardDisconnect @@ -253,7 +258,7 @@ class WebSocketManager extends EventEmitter { // If we have more shards, add a 5s delay if (this.shardQueue.size) { this.debug(`Shard Queue Size: ${this.shardQueue.size}; continuing in 5 seconds...`); - await Util.delayFor(5000); + await Util.delayFor(5_000); return this.createShards(); } @@ -274,7 +279,7 @@ class WebSocketManager extends EventEmitter { this.debug(`Couldn't reconnect or fetch information about the gateway. ${error}`); if (error.httpStatus !== 401) { this.debug(`Possible network error occurred. Retrying in 5s...`); - await Util.delayFor(5000); + await Util.delayFor(5_000); this.reconnecting = false; return this.reconnect(); } @@ -316,7 +321,7 @@ class WebSocketManager extends EventEmitter { this.debug(`Manager was destroyed. Called by:\n${new Error('MANAGER_DESTROYED').stack}`); this.destroyed = true; this.shardQueue.clear(); - for (const shard of this.shards.values()) shard.destroy({ closeCode: 1000, reset: true, emit: false, log: false }); + for (const shard of this.shards.values()) shard.destroy({ closeCode: 1_000, reset: true, emit: false, log: false }); } /** diff --git a/src/client/websocket/WebSocketShard.js b/src/client/websocket/WebSocketShard.js index 25f66bbfc..3ab8d0216 100644 --- a/src/client/websocket/WebSocketShard.js +++ b/src/client/websocket/WebSocketShard.js @@ -415,7 +415,7 @@ class WebSocketShard extends EventEmitter { break; case Opcodes.RECONNECT: this.debug('[RECONNECT] Discord asked us to reconnect'); - this.destroy({ closeCode: 4000 }); + this.destroy({ closeCode: 4_000 }); break; case Opcodes.INVALID_SESSION: this.debug(`[INVALID SESSION] Resumable: ${packet.d}.`); @@ -489,7 +489,7 @@ class WebSocketShard extends EventEmitter { this.emit(ShardEvents.ALL_READY, this.expectedGuilds); }, - hasGuildsIntent ? 15000 : 0, + hasGuildsIntent ? 15_000 : 0, ).unref(); } @@ -511,7 +511,7 @@ class WebSocketShard extends EventEmitter { this.helloTimeout = setTimeout(() => { this.debug('Did not receive HELLO in time. Destroying and connecting again.'); this.destroy({ reset: true, closeCode: 4009 }); - }, 20000).unref(); + }, 20_000).unref(); } /** @@ -656,7 +656,7 @@ class WebSocketShard extends EventEmitter { _send(data) { if (this.connection?.readyState !== WebSocket.OPEN) { this.debug(`Tried to send packet '${JSON.stringify(data)}' but no WebSocket is available!`); - this.destroy({ closeCode: 4000 }); + this.destroy({ closeCode: 4_000 }); return; } @@ -692,7 +692,7 @@ class WebSocketShard extends EventEmitter { * @param {Object} [options={ closeCode: 1000, reset: false, emit: true, log: true }] Options for destroying the shard * @private */ - destroy({ closeCode = 1000, reset = false, emit = true, log = true } = {}) { + destroy({ closeCode = 1_000, reset = false, emit = true, log = true } = {}) { if (log) { this.debug(`[DESTROY] Close Code : ${closeCode} diff --git a/src/managers/ApplicationCommandPermissionsManager.js b/src/managers/ApplicationCommandPermissionsManager.js index 77017f09c..676822a80 100644 --- a/src/managers/ApplicationCommandPermissionsManager.js +++ b/src/managers/ApplicationCommandPermissionsManager.js @@ -380,9 +380,7 @@ class ApplicationCommandPermissionsManager extends BaseManager { if (!commandId && this.guild) { commandId = this.guild.commands.resolveId(command); } - if (!commandId) { - commandId = this.client.application?.commands.resolveId(command); - } + commandId ??= this.client.application?.commands.resolveId(command); if (!commandId) { throw new TypeError('INVALID_TYPE', 'command', 'ApplicationCommandResolvable', true); } diff --git a/src/managers/GuildManager.js b/src/managers/GuildManager.js index 76eacd4e7..b52c15c80 100644 --- a/src/managers/GuildManager.js +++ b/src/managers/GuildManager.js @@ -238,7 +238,7 @@ class GuildManager extends CachedManager { this.client.removeListener(Events.GUILD_CREATE, handleGuild); this.client.decrementMaxListeners(); resolve(this.client.guilds._add(data)); - }, 10000).unref(); + }, 10_000).unref(); }); } diff --git a/src/managers/GuildMemberManager.js b/src/managers/GuildMemberManager.js index 6fb272c32..59cf10c82 100644 --- a/src/managers/GuildMemberManager.js +++ b/src/managers/GuildMemberManager.js @@ -420,7 +420,7 @@ class GuildMemberManager extends CachedManager { for (const member of members.values()) { fetchedMembers.set(member.id, member); } - if (members.size < 1000 || (limit && fetchedMembers.size >= limit) || i === chunk.count) { + if (members.size < 1_000 || (limit && fetchedMembers.size >= limit) || i === chunk.count) { clearTimeout(timeout); this.client.removeListener(Events.GUILD_MEMBERS_CHUNK, handler); this.client.decrementMaxListeners(); diff --git a/src/rest/RESTManager.js b/src/rest/RESTManager.js index 9d5cd2751..7a438aa68 100644 --- a/src/rest/RESTManager.js +++ b/src/rest/RESTManager.js @@ -19,7 +19,7 @@ class RESTManager { if (client.options.restSweepInterval > 0) { this.sweepInterval = setInterval(() => { this.handlers.sweep(handler => handler._inactive); - }, client.options.restSweepInterval * 1000).unref(); + }, client.options.restSweepInterval * 1_000).unref(); } } diff --git a/src/rest/RequestHandler.js b/src/rest/RequestHandler.js index a523087ee..dbf930674 100644 --- a/src/rest/RequestHandler.js +++ b/src/rest/RequestHandler.js @@ -21,9 +21,9 @@ function getAPIOffset(serverDate) { function calculateReset(reset, resetAfter, serverDate) { // Use direct reset time when available, server date becomes irrelevant in this case if (resetAfter) { - return Date.now() + Number(resetAfter) * 1000; + return Date.now() + Number(resetAfter) * 1_000; } - return new Date(Number(reset) * 1000).getTime() - getAPIOffset(serverDate); + return new Date(Number(reset) * 1_000).getTime() - getAPIOffset(serverDate); } /* Invalid request limiting is done on a per-IP basis, not a per-token basis. @@ -157,7 +157,7 @@ class RequestHandler { // As the request goes out, update the global usage information if (!this.manager.globalReset || this.manager.globalReset < Date.now()) { - this.manager.globalReset = Date.now() + 1000; + this.manager.globalReset = Date.now() + 1_000; this.manager.globalRemaining = this.manager.globalLimit; } this.manager.globalRemaining--; @@ -195,7 +195,7 @@ class RequestHandler { // Handle retryAfter, which means we have actually hit a rate limit let retryAfter = res.headers.get('retry-after'); - retryAfter = retryAfter ? Number(retryAfter) * 1000 : -1; + retryAfter = retryAfter ? Number(retryAfter) * 1_000 : -1; if (retryAfter > 0) { // If the global ratelimit header is set, that means we hit the global rate limit if (res.headers.get('x-ratelimit-global')) { @@ -215,7 +215,7 @@ class RequestHandler { // Count the invalid requests if (res.status === 401 || res.status === 403 || res.status === 429) { if (!invalidCountResetTime || invalidCountResetTime < Date.now()) { - invalidCountResetTime = Date.now() + 1000 * 60 * 10; + invalidCountResetTime = Date.now() + 1_000 * 60 * 10; invalidCount = 0; } invalidCount++; diff --git a/src/sharding/Shard.js b/src/sharding/Shard.js index 334331c66..4025a7a42 100644 --- a/src/sharding/Shard.js +++ b/src/sharding/Shard.js @@ -106,7 +106,7 @@ class Shard extends EventEmitter { * before resolving (`-1` or `Infinity` for no wait) * @returns {Promise} */ - spawn(timeout = 30000) { + spawn(timeout = 30_000) { if (this.process) throw new Error('SHARDING_PROCESS_EXISTS', this.id); if (this.worker) throw new Error('SHARDING_WORKER_EXISTS', this.id); @@ -201,7 +201,7 @@ class Shard extends EventEmitter { * @param {ShardRespawnOptions} [options] Options for respawning the shard * @returns {Promise} */ - async respawn({ delay = 500, timeout = 30000 } = {}) { + async respawn({ delay = 500, timeout = 30_000 } = {}) { this.kill(); if (delay > 0) await Util.delayFor(delay); return this.spawn(timeout); diff --git a/src/sharding/ShardClientUtil.js b/src/sharding/ShardClientUtil.js index e7181efcd..eb674c581 100644 --- a/src/sharding/ShardClientUtil.js +++ b/src/sharding/ShardClientUtil.js @@ -167,7 +167,7 @@ class ShardClientUtil { * @returns {Promise} Resolves upon the message being sent * @see {@link ShardingManager#respawnAll} */ - respawnAll({ shardDelay = 5000, respawnDelay = 500, timeout = 30000 } = {}) { + respawnAll({ shardDelay = 5_000, respawnDelay = 500, timeout = 30_000 } = {}) { return this.send({ _sRespawnAll: { shardDelay, respawnDelay, timeout } }); } diff --git a/src/sharding/ShardingManager.js b/src/sharding/ShardingManager.js index 062b8aaa8..7ee74dcb5 100644 --- a/src/sharding/ShardingManager.js +++ b/src/sharding/ShardingManager.js @@ -178,7 +178,7 @@ class ShardingManager extends EventEmitter { * @param {MultipleShardSpawnOptions} [options] Options for spawning shards * @returns {Promise>} */ - async spawn({ amount = this.totalShards, delay = 5500, timeout = 30000 } = {}) { + async spawn({ amount = this.totalShards, delay = 5500, timeout = 30_000 } = {}) { // Obtain/verify the number of shards to spawn if (amount === 'auto') { amount = await Util.fetchRecommendedShards(this.token); @@ -302,7 +302,7 @@ class ShardingManager extends EventEmitter { * @param {MultipleShardRespawnOptions} [options] Options for respawning shards * @returns {Promise>} */ - async respawnAll({ shardDelay = 5000, respawnDelay = 500, timeout = 30000 } = {}) { + async respawnAll({ shardDelay = 5_000, respawnDelay = 500, timeout = 30_000 } = {}) { let s = 0; for (const shard of this.shards.values()) { const promises = [shard.respawn({ respawnDelay, timeout })]; diff --git a/src/structures/Channel.js b/src/structures/Channel.js index 3c0c0ed5a..7e1c6e081 100644 --- a/src/structures/Channel.js +++ b/src/structures/Channel.js @@ -133,14 +133,14 @@ class Channel extends Base { } static create(client, data, guild, { allowUnknownGuild, fromInteraction } = {}) { - if (!CategoryChannel) CategoryChannel = require('./CategoryChannel'); - if (!DMChannel) DMChannel = require('./DMChannel'); - if (!NewsChannel) NewsChannel = require('./NewsChannel'); - if (!StageChannel) StageChannel = require('./StageChannel'); - if (!StoreChannel) StoreChannel = require('./StoreChannel'); - if (!TextChannel) TextChannel = require('./TextChannel'); - if (!ThreadChannel) ThreadChannel = require('./ThreadChannel'); - if (!VoiceChannel) VoiceChannel = require('./VoiceChannel'); + CategoryChannel ??= require('./CategoryChannel'); + DMChannel ??= require('./DMChannel'); + NewsChannel ??= require('./NewsChannel'); + StageChannel ??= require('./StageChannel'); + StoreChannel ??= require('./StoreChannel'); + TextChannel ??= require('./TextChannel'); + ThreadChannel ??= require('./ThreadChannel'); + VoiceChannel ??= require('./VoiceChannel'); let channel; if (!data.guild_id && !guild) { @@ -151,7 +151,7 @@ class Channel extends Base { channel = new PartialGroupDMChannel(client, data); } } else { - if (!guild) guild = client.guilds.cache.get(data.guild_id); + guild ??= client.guilds.cache.get(data.guild_id); if (guild || allowUnknownGuild) { switch (data.type) { diff --git a/src/structures/ClientPresence.js b/src/structures/ClientPresence.js index 9621312dd..7a529336e 100644 --- a/src/structures/ClientPresence.js +++ b/src/structures/ClientPresence.js @@ -53,7 +53,7 @@ class ClientPresence extends Presence { if (activities?.length) { for (const [i, activity] of activities.entries()) { if (typeof activity.name !== 'string') throw new TypeError('INVALID_TYPE', `activities[${i}].name`, 'string'); - if (!activity.type) activity.type = 0; + activity.type ??= 0; data.activities.push({ type: typeof activity.type === 'number' ? activity.type : ActivityTypes[activity.type], diff --git a/src/structures/ClientUser.js b/src/structures/ClientUser.js index c8b0550ef..4d6a63d6c 100644 --- a/src/structures/ClientUser.js +++ b/src/structures/ClientUser.js @@ -25,8 +25,8 @@ class ClientUser extends User { * @type {?boolean} */ this.mfaEnabled = typeof data.mfa_enabled === 'boolean' ? data.mfa_enabled : null; - } else if (typeof this.mfaEnabled === 'undefined') { - this.mfaEnabled = null; + } else { + this.mfaEnabled ??= null; } if (data.token) this.client.token = data.token; diff --git a/src/structures/Guild.js b/src/structures/Guild.js index 5a6d06746..487478307 100644 --- a/src/structures/Guild.js +++ b/src/structures/Guild.js @@ -279,8 +279,8 @@ class Guild extends AnonymousGuild { * @type {?number} */ this.maximumMembers = data.max_members; - } else if (typeof this.maximumMembers === 'undefined') { - this.maximumMembers = null; + } else { + this.maximumMembers ??= null; } if (typeof data.max_presences !== 'undefined') { @@ -289,9 +289,9 @@ class Guild extends AnonymousGuild { * You will need to fetch the guild using {@link Guild#fetch} if you want to receive this parameter * @type {?number} */ - this.maximumPresences = data.max_presences ?? 25000; - } else if (typeof this.maximumPresences === 'undefined') { - this.maximumPresences = null; + this.maximumPresences = data.max_presences ?? 25_000; + } else { + this.maximumPresences ??= null; } if (typeof data.approximate_member_count !== 'undefined') { @@ -301,8 +301,8 @@ class Guild extends AnonymousGuild { * @type {?number} */ this.approximateMemberCount = data.approximate_member_count; - } else if (typeof this.approximateMemberCount === 'undefined') { - this.approximateMemberCount = null; + } else { + this.approximateMemberCount ??= null; } if (typeof data.approximate_presence_count !== 'undefined') { @@ -312,8 +312,8 @@ class Guild extends AnonymousGuild { * @type {?number} */ this.approximatePresenceCount = data.approximate_presence_count; - } else if (typeof this.approximatePresenceCount === 'undefined') { - this.approximatePresenceCount = null; + } else { + this.approximatePresenceCount ??= null; } /** @@ -541,18 +541,18 @@ class Guild extends AnonymousGuild { */ get maximumBitrate() { if (this.features.includes('VIP_REGIONS')) { - return 384000; + return 384_000; } switch (PremiumTiers[this.premiumTier]) { case PremiumTiers.TIER_1: - return 128000; + return 128_000; case PremiumTiers.TIER_2: - return 256000; + return 256_000; case PremiumTiers.TIER_3: - return 384000; + return 384_000; default: - return 96000; + return 96_000; } } diff --git a/src/structures/GuildChannel.js b/src/structures/GuildChannel.js index 14f45b26d..49e24a823 100644 --- a/src/structures/GuildChannel.js +++ b/src/structures/GuildChannel.js @@ -172,7 +172,7 @@ class GuildChannel extends Channel { if (!verified) member = this.guild.members.resolve(member); if (!member) return []; - if (!roles) roles = member.roles.cache; + roles ??= member.roles.cache; const roleOverwrites = []; let memberOverwrites; let everyoneOverwrites; diff --git a/src/structures/GuildTemplate.js b/src/structures/GuildTemplate.js index c09ce6105..953a7cf9d 100644 --- a/src/structures/GuildTemplate.js +++ b/src/structures/GuildTemplate.js @@ -129,7 +129,7 @@ class GuildTemplate extends Base { client.incrementMaxListeners(); client.on(Events.GUILD_CREATE, handleGuild); - const timeout = setTimeout(() => resolveGuild(client.guilds._add(data)), 10000).unref(); + const timeout = setTimeout(() => resolveGuild(client.guilds._add(data)), 10_000).unref(); }); } diff --git a/src/structures/Integration.js b/src/structures/Integration.js index 814846ec0..846e047dd 100644 --- a/src/structures/Integration.js +++ b/src/structures/Integration.js @@ -116,8 +116,8 @@ class Integration extends Base { */ this.application = new IntegrationApplication(this.client, data.application); } - } else if (!this.application) { - this.application = null; + } else { + this.application ??= null; } } diff --git a/src/structures/Invite.js b/src/structures/Invite.js index d89f75de8..6e79da85c 100644 --- a/src/structures/Invite.js +++ b/src/structures/Invite.js @@ -162,7 +162,7 @@ class Invite extends Base { get expiresTimestamp() { return ( this._expiresTimestamp ?? - (this.createdTimestamp && this.maxAge ? this.createdTimestamp + this.maxAge * 1000 : null) + (this.createdTimestamp && this.maxAge ? this.createdTimestamp + this.maxAge * 1_000 : null) ); } diff --git a/src/structures/Message.js b/src/structures/Message.js index 087ceaeff..22a2e8526 100644 --- a/src/structures/Message.js +++ b/src/structures/Message.js @@ -92,8 +92,8 @@ class Message extends Base { * @type {?User} */ this.author = this.client.users._add(data.author, !data.webhook_id); - } else if (!this.author) { - this.author = null; + } else { + this.author ??= null; } if ('pinned' in data) { @@ -102,8 +102,8 @@ class Message extends Base { * @type {?boolean} */ this.pinned = Boolean(data.pinned); - } else if (typeof this.pinned !== 'boolean') { - this.pinned = null; + } else { + this.pinned ??= null; } if ('tts' in data) { @@ -112,8 +112,8 @@ class Message extends Base { * @type {?boolean} */ this.tts = data.tts; - } else if (typeof this.tts !== 'boolean') { - this.tts = null; + } else { + this.tts ??= null; } if (!partial) { @@ -334,8 +334,8 @@ class Message extends Base { commandName: data.interaction.name, user: this.client.users._add(data.interaction.user), }; - } else if (!this.interaction) { - this.interaction = null; + } else { + this.interaction ??= null; } } @@ -447,7 +447,7 @@ class Message extends Base { * @example * // Create a reaction collector * const filter = (reaction, user) => reaction.emoji.name === '👌' && user.id === 'someId'; - * const collector = message.createReactionCollector({ filter, time: 15000 }); + * const collector = message.createReactionCollector({ filter, time: 15_000 }); * collector.on('collect', r => console.log(`Collected ${r.emoji.name}`)); * collector.on('end', collected => console.log(`Collected ${collected.size} items`)); */ @@ -469,7 +469,7 @@ class Message extends Base { * @example * // Create a reaction collector * const filter = (reaction, user) => reaction.emoji.name === '👌' && user.id === 'someId' - * message.awaitReactions({ filter, time: 15000 }) + * message.awaitReactions({ filter, time: 15_000 }) * .then(collected => console.log(`Collected ${collected.size} reactions`)) * .catch(console.error); */ @@ -498,7 +498,7 @@ class Message extends Base { * @example * // Create a message component interaction collector * const filter = (interaction) => interaction.customId === 'button' && interaction.user.id === 'someId'; - * const collector = message.createMessageComponentCollector({ filter, time: 15000 }); + * const collector = message.createMessageComponentCollector({ filter, time: 15_000 }); * collector.on('collect', i => console.log(`Collected ${i.customId}`)); * collector.on('end', collected => console.log(`Collected ${collected.size} items`)); */ @@ -526,7 +526,7 @@ class Message extends Base { * @example * // Collect a message component interaction * const filter = (interaction) => interaction.customId === 'button' && interaction.user.id === 'someId'; - * message.awaitMessageComponent({ filter, time: 15000 }) + * message.awaitMessageComponent({ filter, time: 15_000 }) * .then(interaction => console.log(`${interaction.customId} was clicked!`)) * .catch(console.error); */ diff --git a/src/structures/MessageReaction.js b/src/structures/MessageReaction.js index 8e5f77c30..a2feb37d8 100644 --- a/src/structures/MessageReaction.js +++ b/src/structures/MessageReaction.js @@ -120,7 +120,7 @@ class MessageReaction { if (this.partial) return; this.users.cache.set(user.id, user); if (!this.me || user.id !== this.message.client.user.id || this.count === 0) this.count++; - if (!this.me) this.me = user.id === this.message.client.user.id; + this.me ??= user.id === this.message.client.user.id; } _remove(user) { diff --git a/src/structures/ThreadChannel.js b/src/structures/ThreadChannel.js index 02e82d0fb..1a6ba4e8a 100644 --- a/src/structures/ThreadChannel.js +++ b/src/structures/ThreadChannel.js @@ -67,8 +67,8 @@ class ThreadChannel extends Channel { * @type {?Snowflake} */ this.parentId = data.parent_id; - } else if (!this.parentId) { - this.parentId = null; + } else { + this.parentId ??= null; } if ('thread_metadata' in data) { @@ -105,18 +105,10 @@ class ThreadChannel extends Channel { */ this.archiveTimestamp = new Date(data.thread_metadata.archive_timestamp).getTime(); } else { - if (!this.locked) { - this.locked = null; - } - if (!this.archived) { - this.archived = null; - } - if (!this.autoArchiveDuration) { - this.autoArchiveDuration = null; - } - if (!this.archiveTimestamp) { - this.archiveTimestamp = null; - } + this.locked ??= null; + this.archived ??= null; + this.autoArchiveDuration ??= null; + this.archiveTimestamp ??= null; this.invitable ??= null; } @@ -126,8 +118,8 @@ class ThreadChannel extends Channel { * @type {?Snowflake} */ this.ownerId = data.owner_id; - } else if (!this.ownerId) { - this.ownerId = null; + } else { + this.ownerId ??= null; } if ('last_message_id' in data) { @@ -136,8 +128,8 @@ class ThreadChannel extends Channel { * @type {?Snowflake} */ this.lastMessageId = data.last_message_id; - } else if (!this.lastMessageId) { - this.lastMessageId = null; + } else { + this.lastMessageId ??= null; } if ('last_pin_timestamp' in data) { @@ -146,8 +138,8 @@ class ThreadChannel extends Channel { * @type {?number} */ this.lastPinTimestamp = data.last_pin_timestamp ? new Date(data.last_pin_timestamp).getTime() : null; - } else if (!this.lastPinTimestamp) { - this.lastPinTimestamp = null; + } else { + this.lastPinTimestamp ??= null; } if ('rate_limit_per_user' in data || !partial) { @@ -156,8 +148,8 @@ class ThreadChannel extends Channel { * @type {?number} */ this.rateLimitPerUser = data.rate_limit_per_user ?? 0; - } else if (!this.rateLimitPerUser) { - this.rateLimitPerUser = null; + } else { + this.rateLimitPerUser ??= null; } if ('message_count' in data) { @@ -168,8 +160,8 @@ class ThreadChannel extends Channel { * @type {?number} */ this.messageCount = data.message_count; - } else if (!this.messageCount) { - this.messageCount = null; + } else { + this.messageCount ??= null; } if ('member_count' in data) { @@ -180,8 +172,8 @@ class ThreadChannel extends Channel { * @type {?number} */ this.memberCount = data.member_count; - } else if (!this.memberCount) { - this.memberCount = null; + } else { + this.memberCount ??= null; } if (data.member && this.client.user) this.members._add({ user_id: this.client.user.id, ...data.member }); diff --git a/src/structures/Typing.js b/src/structures/Typing.js index cd38573ac..9b3d89681 100644 --- a/src/structures/Typing.js +++ b/src/structures/Typing.js @@ -35,7 +35,7 @@ class Typing extends Base { * The UNIX timestamp in milliseconds the user started typing at * @type {number} */ - this.startedTimestamp = data.timestamp * 1000; + this.startedTimestamp = data.timestamp * 1_000; } /** diff --git a/src/structures/User.js b/src/structures/User.js index 4af93f5f2..b1dca83f8 100644 --- a/src/structures/User.js +++ b/src/structures/User.js @@ -93,8 +93,8 @@ class User extends Base { * @type {?number} */ this.accentColor = data.accent_color; - } else if (typeof this.accentColor === 'undefined') { - this.accentColor = null; + } else { + this.accentColor ??= null; } if ('system' in data) { diff --git a/src/structures/VoiceChannel.js b/src/structures/VoiceChannel.js index 58122c1b1..6904b7e97 100644 --- a/src/structures/VoiceChannel.js +++ b/src/structures/VoiceChannel.js @@ -53,7 +53,7 @@ class VoiceChannel extends BaseGuildVoiceChannel { * @returns {Promise} * @example * // Set the bitrate of a voice channel - * voiceChannel.setBitrate(48000) + * voiceChannel.setBitrate(48_000) * .then(vc => console.log(`Set bitrate to ${vc.bitrate}bps for ${vc.name}`)) * .catch(console.error); */ diff --git a/src/structures/Webhook.js b/src/structures/Webhook.js index 91b9838c4..244c7fad9 100644 --- a/src/structures/Webhook.js +++ b/src/structures/Webhook.js @@ -189,7 +189,7 @@ class Webhook { * 'color': '#F0F', * 'footer_icon': 'http://snek.s3.amazonaws.com/topSnek.png', * 'footer': 'Powered by sneks', - * 'ts': Date.now() / 1000 + * 'ts': Date.now() / 1_000 * }] * }).catch(console.error); * @see {@link https://api.slack.com/messaging/webhooks} diff --git a/src/structures/interfaces/TextBasedChannel.js b/src/structures/interfaces/TextBasedChannel.js index 99038ecc3..4b37e533d 100644 --- a/src/structures/interfaces/TextBasedChannel.js +++ b/src/structures/interfaces/TextBasedChannel.js @@ -198,7 +198,7 @@ class TextBasedChannel { * @example * // Create a message collector * const filter = m => m.content.includes('discord'); - * const collector = channel.createMessageCollector({ filter, time: 15000 }); + * const collector = channel.createMessageCollector({ filter, time: 15_000 }); * collector.on('collect', m => console.log(`Collected ${m.content}`)); * collector.on('end', collected => console.log(`Collected ${collected.size} items`)); */ @@ -221,7 +221,7 @@ class TextBasedChannel { * // Await !vote messages * const filter = m => m.content.startsWith('!vote'); * // Errors: ['time'] treats ending because of the time limit as an error - * channel.awaitMessages({ filter, max: 4, time: 60000, errors: ['time'] }) + * channel.awaitMessages({ filter, max: 4, time: 60_000, errors: ['time'] }) * .then(collected => console.log(collected.size)) * .catch(collected => console.log(`After a minute, only ${collected.size} out of 4 voted.`)); */ @@ -245,7 +245,7 @@ class TextBasedChannel { * @example * // Create a button interaction collector * const filter = (interaction) => interaction.customId === 'button' && interaction.user.id === 'someId'; - * const collector = channel.createMessageComponentCollector({ filter, time: 15000 }); + * const collector = channel.createMessageComponentCollector({ filter, time: 15_000 }); * collector.on('collect', i => console.log(`Collected ${i.customId}`)); * collector.on('end', collected => console.log(`Collected ${collected.size} items`)); */ @@ -265,7 +265,7 @@ class TextBasedChannel { * @example * // Collect a message component interaction * const filter = (interaction) => interaction.customId === 'button' && interaction.user.id === 'someId'; - * channel.awaitMessageComponent({ filter, time: 15000 }) + * channel.awaitMessageComponent({ filter, time: 15_000 }) * .then(interaction => console.log(`${interaction.customId} was clicked!`)) * .catch(console.error); */ @@ -297,7 +297,7 @@ class TextBasedChannel { if (Array.isArray(messages) || messages instanceof Collection) { let messageIds = messages instanceof Collection ? [...messages.keys()] : messages.map(m => m.id ?? m); if (filterOld) { - messageIds = messageIds.filter(id => Date.now() - SnowflakeUtil.deconstruct(id).timestamp < 1209600000); + messageIds = messageIds.filter(id => Date.now() - SnowflakeUtil.deconstruct(id).timestamp < 1_209_600_000); } if (messageIds.length === 0) return new Collection(); if (messageIds.length === 1) { diff --git a/src/util/LimitedCollection.js b/src/util/LimitedCollection.js index 5f850d89c..b84fd1222 100644 --- a/src/util/LimitedCollection.js +++ b/src/util/LimitedCollection.js @@ -79,7 +79,7 @@ class LimitedCollection extends Collection { if (sweepFn === null) return; if (typeof sweepFn !== 'function') throw new TypeError('SWEEP_FILTER_RETURN'); this.sweep(sweepFn); - }, sweepInterval * 1000).unref() + }, sweepInterval * 1_000).unref() : null; } @@ -129,7 +129,7 @@ class LimitedCollection extends Collection { } return () => { if (lifetime <= 0) return null; - const lifetimeMs = lifetime * 1000; + const lifetimeMs = lifetime * 1_000; const now = Date.now(); return (entry, key, coll) => { if (excludeFromSweep(entry, key, coll)) { diff --git a/src/util/Options.js b/src/util/Options.js index 7f45f9d40..206bc59f5 100644 --- a/src/util/Options.js +++ b/src/util/Options.js @@ -115,8 +115,8 @@ class Options extends null { messageSweepInterval: 0, invalidRequestWarningInterval: 0, partials: [], - restWsBridgeTimeout: 5000, - restRequestTimeout: 15000, + restWsBridgeTimeout: 5_000, + restRequestTimeout: 15_000, restGlobalRateLimit: 0, retryLimit: 1, restTimeOffset: 500, diff --git a/src/util/SnowflakeUtil.js b/src/util/SnowflakeUtil.js index 3321e770b..b66d24982 100644 --- a/src/util/SnowflakeUtil.js +++ b/src/util/SnowflakeUtil.js @@ -3,7 +3,7 @@ const Util = require('./Util'); // Discord epoch (2015-01-01T00:00:00.000Z) -const EPOCH = 1420070400000; +const EPOCH = 1_420_070_400_000; let INCREMENT = 0; /** diff --git a/src/util/Util.js b/src/util/Util.js index 32a858735..1c01f5df7 100644 --- a/src/util/Util.js +++ b/src/util/Util.js @@ -69,7 +69,7 @@ class Util extends null { * @param {SplitOptions} [options] Options controlling the behavior of the split * @returns {string[]} */ - static splitMessage(text, { maxLength = 2000, char = '\n', prepend = '', append = '' } = {}) { + static splitMessage(text, { maxLength = 2_000, char = '\n', prepend = '', append = '' } = {}) { text = Util.verifyString(text); if (text.length <= maxLength) return [text]; let splitText = [text]; @@ -181,7 +181,7 @@ class Util extends null { * @returns {string} */ static escapeCodeBlock(text) { - return text.replace(/```/g, '\\`\\`\\`'); + return text.replaceAll('```', '\\`\\`\\`'); } /** @@ -243,7 +243,7 @@ class Util extends null { * @returns {string} */ static escapeStrikethrough(text) { - return text.replace(/~~/g, '\\~\\~'); + return text.replaceAll('~~', '\\~\\~'); } /** @@ -252,7 +252,7 @@ class Util extends null { * @returns {string} */ static escapeSpoiler(text) { - return text.replace(/\|\|/g, '\\|\\|'); + return text.replaceAll('||', '\\|\\|'); } /** @@ -267,7 +267,7 @@ class Util extends null { * @param {FetchRecommendedShardsOptions} [options] Options for fetching the recommended shard count * @returns {Promise} The recommended number of shards */ - static async fetchRecommendedShards(token, { guildsPerShard = 1000, multipleOf = 1 } = {}) { + static async fetchRecommendedShards(token, { guildsPerShard = 1_000, multipleOf = 1 } = {}) { if (!token) throw new DiscordError('TOKEN_MISSING'); const defaults = Options.createDefault(); const response = await fetch(`${defaults.http.api}/v${defaults.http.version}${Endpoints.botGateway}`, { @@ -279,7 +279,7 @@ class Util extends null { throw response; } const { shards } = await response.json(); - return Math.ceil((shards * (1000 / guildsPerShard)) / multipleOf) * multipleOf; + return Math.ceil((shards * (1_000 / guildsPerShard)) / multipleOf) * multipleOf; } /** @@ -534,7 +534,7 @@ class Util extends null { bin = String(low & 1) + bin; low = Math.floor(low / 2); if (high > 0) { - low += 5000000000 * (high % 2); + low += 5_000_000_000 * (high % 2); high = Math.floor(high / 2); } } @@ -577,7 +577,7 @@ class Util extends null { * @returns {string} */ static removeMentions(str) { - return str.replace(/@/g, '@\u200b'); + return str.replaceAll('@', '@\u200b'); } /** @@ -621,7 +621,7 @@ class Util extends null { * @returns {string} */ static cleanCodeBlockContent(text) { - return text.replace(/```/g, '`\u200b``'); + return text.replaceAll('```', '`\u200b``'); } /** diff --git a/test/random.js b/test/random.js index 04717360e..c24f70043 100644 --- a/test/random.js +++ b/test/random.js @@ -9,7 +9,14 @@ const { Client, Intents } = require('../src'); console.time('magic'); -const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_MESSAGE_REACTIONS, Intents.FLAGS.GUILD_MEMBERS] }); +const client = new Client({ + intents: [ + Intents.FLAGS.GUILDS, + Intents.FLAGS.GUILD_MESSAGES, + Intents.FLAGS.GUILD_MESSAGE_REACTIONS, + Intents.FLAGS.GUILD_MEMBERS, + ], +}); client .login(token) @@ -17,17 +24,21 @@ client .catch(console.error); // Fetch all members in a new guild -client.on('guildCreate', guild => guild.members.fetch() - .catch(err => console.log(`Failed to fetch all members: ${err}\n${err.stack}`))); +client.on('guildCreate', guild => + guild.members.fetch().catch(err => console.log(`Failed to fetch all members: ${err}\n${err.stack}`)), +); // Fetch all members in a newly available guild -client.on('guildUpdate', (oldGuild, newGuild) => !oldGuild.available && newGuild.available ? guild.members.fetch() - .catch(err => console.log(`Failed to fetch all members: ${err}\n${err.stack}`)) : Promise.resolve()); +client.on('guildUpdate', (oldGuild, newGuild) => + !oldGuild.available && newGuild.available + ? guild.members.fetch().catch(err => console.log(`Failed to fetch all members: ${err}\n${err.stack}`)) + : Promise.resolve(), +); client.on('ready', async () => { // Fetch all members for initially available guilds try { - const promises = client.guilds.cache.map(guild => guild.available ? guild.members.fetch() : Promise.resolve()); + const promises = client.guilds.cache.map(guild => (guild.available ? guild.members.fetch() : Promise.resolve())); await Promise.all(promises); } catch (err) { console.log(`Failed to fetch all members before ready! ${err}\n${err.stack}`); @@ -53,7 +64,7 @@ client.on('messageCreate', message => { if (message.content === 'imma queue pls') { let count = 0; let ecount = 0; - for (let x = 0; x < 4000; x++) { + for (let x = 0; x < 4_000; x++) { message.channel .send(`this is message ${x} of 3999`) .then(m => { @@ -131,8 +142,7 @@ client.on('messageCreate', message => { } if (message.content.startsWith('kick')) { - message.guild - .members + message.guild.members .resolve(message.mentions.users.first()) .kick() .then(member => { @@ -156,8 +166,7 @@ client.on('messageCreate', message => { } if (message.content === 'makerole') { - message.guild - .roles + message.guild.roles .create() .then(role => { message.channel.send(`Made role ${role.name}`); @@ -172,10 +181,7 @@ function nameLoop(user) { } function chanLoop(channel) { - channel - .setName(`${channel.name}a`) - .then(chanLoop) - .catch(console.error); + channel.setName(`${channel.name}a`).then(chanLoop).catch(console.error); } client.on('messageCreate', msg => { @@ -185,12 +191,7 @@ client.on('messageCreate', msg => { if (msg.content.startsWith('#eval') && msg.author.id === '66564597481480192') { try { - const com = eval( - msg.content - .split(' ') - .slice(1) - .join(' '), - ); + const com = eval(msg.content.split(' ').slice(1).join(' ')); msg.channel.send(`\`\`\`\n${com}\`\`\``); } catch (e) { msg.channel.send(`\`\`\`\n${e}\`\`\``); @@ -203,21 +204,14 @@ let disp, con; client.on('messageCreate', msg => { if (msg.content.startsWith('/play')) { console.log('I am now going to play', msg.content); - const chan = msg.content - .split(' ') - .slice(1) - .join(' '); + const chan = msg.content.split(' ').slice(1).join(' '); const s = ytdl(chan, { filter: 'audioonly' }, { passes: 3 }); s.on('error', e => console.log(`e w stream 1 ${e}`)); con.play(s); } if (msg.content.startsWith('/join')) { - const chan = msg.content - .split(' ') - .slice(1) - .join(' '); - msg.channel.guild.channels - .cache + const chan = msg.content.split(' ').slice(1).join(' '); + msg.channel.guild.channels.cache .get(chan) .join() .then(conn => { diff --git a/test/sendtest.js b/test/sendtest.js index 3d571fc45..1ca9e22f5 100644 --- a/test/sendtest.js +++ b/test/sendtest.js @@ -97,7 +97,7 @@ client.on('messageCreate', async message => { for (const [i, test] of tests.entries()) { await message.channel.send(`**#${i}**\n\`\`\`js\n${test.toString()}\`\`\``); await test(message).catch(e => message.channel.send(`Error!\n\`\`\`\n${e}\`\`\``)); - await wait(1000); + await wait(1_000); } /* eslint-enable no-await-in-loop */ } else if (match) { diff --git a/test/shard.js b/test/shard.js index 4ea5f5428..c0e8e2725 100644 --- a/test/shard.js +++ b/test/shard.js @@ -28,7 +28,7 @@ client.on('ready', () => { setTimeout(() => { console.log('kek dying'); client.destroy(); - }, 5000); + }, 5_000); } }); diff --git a/test/webhooktest.js b/test/webhooktest.js index e9cc59676..19f208985 100644 --- a/test/webhooktest.js +++ b/test/webhooktest.js @@ -107,7 +107,7 @@ client.on('messageCreate', async message => { for (const [i, test] of tests.entries()) { await message.channel.send(`**#${i}-Hook: ${type}**\n\`\`\`js\n${test.toString()}\`\`\``); await test(message, hook).catch(e => message.channel.send(`Error!\n\`\`\`\n${e}\`\`\``)); - await wait(1000); + await wait(1_000); } } /* eslint-enable no-await-in-loop */