From 0b10b3d2e419841be65fd7e1c2473e665c3d4e80 Mon Sep 17 00:00:00 2001 From: TTtie Date: Thu, 9 Mar 2023 10:22:13 +0000 Subject: [PATCH 01/16] bump the minimum node version --- README.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b4bce93f..726111f7 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ A fork of [Eris](https://github.com/abalabahaha/eris), a Node.js wrapper for int Installing ---------- -You will need NodeJS 10.4+. Voice support requires [additional software](https://github.com/nodejs/node-gyp#installation). +You will need NodeJS 18+. Voice support requires [additional software](https://github.com/nodejs/node-gyp#installation). ``` npm install --omit=optional @projectdysnomia/dysnomia diff --git a/package.json b/package.json index 8f2e4f4c..1d180f82 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ }, "typings": "./index.d.ts", "engines": { - "node": ">=10.4.0" + "node": ">=18.0.0" }, "scripts": { "lint:js": "eslint -c .eslintrc.yml lib examples *.js", From 855b6badeda9de1149af6c3fdab593e539114175 Mon Sep 17 00:00:00 2001 From: TTtie Date: Thu, 9 Mar 2023 18:47:15 +0000 Subject: [PATCH 02/16] modernization round 1 --- .eslintrc.yml | 5 +- lib/Client.js | 20 ++-- lib/gateway/Shard.js | 143 ++++++++++---------------- lib/rest/RequestHandler.js | 8 +- lib/structures/Guild.js | 2 +- lib/structures/GuildAuditLogEntry.js | 24 ++--- lib/structures/GuildScheduledEvent.js | 6 +- lib/structures/Member.js | 12 +-- lib/structures/Message.js | 24 ++--- lib/structures/StageInstance.js | 2 +- 10 files changed, 97 insertions(+), 149 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index 4db6bea8..52aa802f 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -1,15 +1,12 @@ --- env: - es6: true + es2022: true node: true plugins: - "sort-class-members" extends: "eslint:recommended" globals: - BigInt: true window: true -parserOptions: - ecmaVersion: 2020 rules: array-bracket-spacing: - 2 diff --git a/lib/Client.js b/lib/Client.js index 816416c0..3a2991dc 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -134,8 +134,8 @@ class Client extends EventEmitter { throw new TypeError(`Invalid default image size: ${defaultImageSize}`); } // Set HTTP Agent on Websockets if not already set - if(this.options.rest.agent && !(this.options.ws && this.options.ws.agent)) { - this.options.ws = this.options.ws || {}; + if(this.options.rest.agent && !this.options.ws?.agent) { + this.options.ws ??= {}; this.options.ws.agent = this.options.rest.agent; } @@ -343,12 +343,10 @@ class Client extends EventEmitter { throw new Error("Failed to autoshard due to lack of data from Discord."); } this.shards.options.maxShards = data.shards; - if(this.shards.options.lastShardID === undefined) { - this.shards.options.lastShardID = data.shards - 1; - } + this.shards.options.lastShardID ??= data.shards - 1; } - if(this.shards.options.shardConcurrency === "auto" && data.session_start_limit && typeof data.session_start_limit.max_concurrency === "number") { + if(this.shards.options.shardConcurrency === "auto" && typeof data.session_start_limit?.max_concurrency === "number") { this.shards.options.maxConcurrency = data.session_start_limit.max_concurrency; } @@ -423,7 +421,7 @@ class Client extends EventEmitter { return this.requestHandler.request("POST", Endpoints.GUILD_CHANNELS(guildID), true, { name: name, type: type, - available_tags: options.availableTags && options.availableTags.map((tag) => ({ + available_tags: options.availableTags?.map((tag) => ({ id: tag.id, name: tag.name, moderated: tag.moderated, @@ -1211,7 +1209,7 @@ class Client extends EventEmitter { return this.requestHandler.request("PATCH", Endpoints.CHANNEL(channelID), true, { archived: options.archived, auto_archive_duration: options.autoArchiveDuration, - available_tags: options.availableTags && options.availableTags.map((tag) => ({ + available_tags: options.availableTags?.map((tag) => ({ id: tag.id, name: tag.name, moderated: tag.moderated, @@ -1477,7 +1475,7 @@ class Client extends EventEmitter { */ editGuildMember(guildID, memberID, options, reason) { return this.requestHandler.request("PATCH", Endpoints.GUILD_MEMBER(guildID, memberID), true, { - roles: options.roles && options.roles.filter((roleID, index) => options.roles.indexOf(roleID) === index), + roles: options.roles?.filter((roleID, index) => options.roles.indexOf(roleID) === index), nick: options.nick, mute: options.mute, deaf: options.deaf, @@ -2806,9 +2804,7 @@ class Client extends EventEmitter { self_mute: options.selfMute || false, self_deaf: options.selfDeaf || false }); - if(options.opusOnly === undefined) { - options.opusOnly = this.options.opusOnly; - } + options.opusOnly ??= this.options.opusOnly; return this.voiceConnections.join(this.channelGuildMap[channelID], channelID, options); } diff --git a/lib/gateway/Shard.js b/lib/gateway/Shard.js index 1ec76ab9..92b995e3 100644 --- a/lib/gateway/Shard.js +++ b/lib/gateway/Shard.js @@ -88,7 +88,7 @@ class Shard extends EventEmitter { * Tells the shard to connect */ connect() { - if(this.ws && this.ws.readyState != WebSocket.CLOSED) { + if(this.ws?.readyState != WebSocket.CLOSED) { this.emit("error", new Error("Existing connection detected"), this.id); return; } @@ -442,11 +442,11 @@ class Shard extends EventEmitter { requestGuildMembers(guildID, options) { const opts = { guild_id: guildID, - limit: (options && options.limit) || 0, - user_ids: options && options.userIDs, - query: options && options.query, + limit: options?.limit || 0, + user_ids: options?.userIDs, + query: options?.query, nonce: Date.now().toString() + Math.random().toString(36), - presences: options && options.presences + presences: options?.presences }; if(!opts.user_ids && !opts.query) { opts.query = ""; @@ -457,7 +457,7 @@ class Shard extends EventEmitter { if(opts.presences && (this.client.shards.options.intents && !(this.client.shards.options.intents & Constants.Intents.guildPresences))) { throw new Error("Cannot request members presences without guildPresences intent"); } - if(opts.user_ids && opts.user_ids.length > 100) { + if(opts.user_ids?.length > 100) { throw new Error("Cannot request more than 100 users by their ID"); } this.sendWS(GatewayOPCodes.REQUEST_GUILD_MEMBERS, opts); @@ -532,11 +532,11 @@ class Shard extends EventEmitter { } sendWS(op, _data, priority = false) { - if(this.ws && this.ws.readyState === WebSocket.OPEN) { + if(this.ws?.readyState === WebSocket.OPEN) { let i = 0; let waitFor = 1; const func = () => { - if(++i >= waitFor && this.ws && this.ws.readyState === WebSocket.OPEN) { + if(++i >= waitFor && this.ws?.readyState === WebSocket.OPEN) { const data = Erlpack ? Erlpack.pack({op: op, d: _data}) : JSON.stringify({op: op, d: _data}); this.ws.send(data); if(_data.token) { @@ -900,7 +900,7 @@ class Shard extends EventEmitter { * @event Client#messageDelete * @prop {Message | Object} message The message object. If the message is not cached, this will be an object with `id` and `channel` keys. If the channel is not cached, channel will be an object with an `id` key. If the uncached message is from a guild, the message will also contain a `guildID` key, and the channel will contain a `guild` with an `id` key. No other property is guaranteed. */ - this.emit("messageDelete", (channel && channel.messages.remove(packet.d)) || { + this.emit("messageDelete", channel?.messages.remove(packet.d) || { id: packet.d.id, channel: channel || { id: packet.d.channel_id, @@ -921,7 +921,7 @@ class Shard extends EventEmitter { * @event Client#messageDeleteBulk * @prop {Array | Array} messages An array of (potentially partial) message objects. If a message is not cached, it will be an object with `id` and `channel` keys If the uncached messages are from a guild, the messages will also contain a `guildID` key, and the channel will contain a `guild` with an `id` key. No other property is guaranteed */ - this.emit("messageDeleteBulk", packet.d.ids.map((id) => (channel && channel.messages.remove({ + this.emit("messageDeleteBulk", packet.d.ids.map((id) => (channel?.messages.remove({ id }) || { id: id, @@ -932,18 +932,16 @@ class Shard extends EventEmitter { } case "MESSAGE_REACTION_ADD": { const channel = this.client.getChannel(packet.d.channel_id); - let message; + let message = channel?.messages.get(packet.d.message_id); let member; - if(channel) { - message = channel.messages.get(packet.d.message_id); - if(channel.guild) { - if(packet.d.member) { - // Updates the member cache with this member for future events. - packet.d.member.id = packet.d.user_id; - member = channel.guild.members.update(packet.d.member, channel.guild); - } + if(channel?.guild) { + if(packet.d.member) { + // Updates the member cache with this member for future events. + packet.d.member.id = packet.d.user_id; + member = channel.guild.members.update(packet.d.member, channel.guild); } } + if(message) { const reaction = packet.d.emoji.id ? `${packet.d.emoji.name}:${packet.d.emoji.id}` : packet.d.emoji.name; if(message.reactions[reaction]) { @@ -965,9 +963,7 @@ class Shard extends EventEmitter { if(packet.d.guild_id) { message.guildID = packet.d.guild_id; - if(!message.channel.guild) { - message.channel.guild = {id: packet.d.guild_id}; - } + message.channel.guild ??= {id: packet.d.guild_id}; } } /** @@ -985,10 +981,7 @@ class Shard extends EventEmitter { } case "MESSAGE_REACTION_REMOVE": { const channel = this.client.getChannel(packet.d.channel_id); - let message; - if(channel) { - message = channel.messages.get(packet.d.message_id); - } + let message = channel?.messages.get(packet.d.message_id); if(message) { const reaction = packet.d.emoji.id ? `${packet.d.emoji.name}:${packet.d.emoji.id}` : packet.d.emoji.name; const reactionObj = message.reactions[reaction]; @@ -1008,9 +1001,7 @@ class Shard extends EventEmitter { if(packet.d.guild_id) { message.guildID = packet.d.guild_id; - if(!message.channel.guild) { - message.channel.guild = {id: packet.d.guild_id}; - } + message.channel.guild ??= {id: packet.d.guild_id}; } } /** @@ -1028,12 +1019,9 @@ class Shard extends EventEmitter { } case "MESSAGE_REACTION_REMOVE_ALL": { const channel = this.client.getChannel(packet.d.channel_id); - let message; - if(channel) { - message = channel.messages.get(packet.d.message_id); - if(message) { - message.reactions = {}; - } + let message = channel?.messages.get(packet.d.message_id); + if(message) { + message.reactions = {}; } if(!message) { message = { @@ -1042,9 +1030,7 @@ class Shard extends EventEmitter { }; if(packet.d.guild_id) { message.guildID = packet.d.guild_id; - if(!message.channel.guild) { - message.channel.guild = {id: packet.d.guild_id}; - } + message.channel.guild ??= {id: packet.d.guild_id}; } } /** @@ -1057,13 +1043,10 @@ class Shard extends EventEmitter { } case "MESSAGE_REACTION_REMOVE_EMOJI": { const channel = this.client.getChannel(packet.d.channel_id); - let message; - if(channel) { - message = channel.messages.get(packet.d.message_id); - if(message) { - const reaction = packet.d.emoji.id ? `${packet.d.emoji.name}:${packet.d.emoji.id}` : packet.d.emoji.name; - delete message.reactions[reaction]; - } + let message = channel?.messages.get(packet.d.message_id); + if(message) { + const reaction = packet.d.emoji.id ? `${packet.d.emoji.name}:${packet.d.emoji.id}` : packet.d.emoji.name; + delete message.reactions[reaction]; } if(!message) { message = { @@ -1072,9 +1055,7 @@ class Shard extends EventEmitter { }; if(packet.d.guild_id) { message.guildID = packet.d.guild_id; - if(!message.channel.guild) { - message.channel.guild = {id: packet.d.guild_id}; - } + message.channel.guild ??= {id: packet.d.guild_id}; } } /** @@ -1304,11 +1285,9 @@ class Shard extends EventEmitter { delete this.client.guildShardMap[packet.d.id]; const guild = this.client.guilds.remove(packet.d); - if(guild) { // Discord sends GUILD_DELETE for guilds that were previously unavailable in READY - guild.channels.forEach((channel) => { - delete this.client.channelGuildMap[channel.id]; - }); - } + guild?.channels.forEach((channel) => { // Discord sends GUILD_DELETE for guilds that were previously unavailable in READY + delete this.client.channelGuildMap[channel.id]; + }); if(packet.d.unavailable) { /** * Fired when a guild becomes unavailable @@ -1483,12 +1462,10 @@ class Shard extends EventEmitter { case "CHANNEL_CREATE": { const channel = Channel.from(packet.d, this.client); if(packet.d.guild_id) { + channel.guild ??= this.client.guilds.get(packet.d.guild_id); if(!channel.guild) { - channel.guild = this.client.guilds.get(packet.d.guild_id); - if(!channel.guild) { - this.emit("debug", `Received CHANNEL_CREATE for channel in missing guild ${packet.d.guild_id}`); - break; - } + this.emit("debug", `Received CHANNEL_CREATE for channel in missing guild ${packet.d.guild_id}`); + break; } channel.guild.channels.add(channel, this.client); this.client.channelGuildMap[packet.d.id] = packet.d.guild_id; @@ -1838,15 +1815,13 @@ class Shard extends EventEmitter { } case "THREAD_CREATE": { const channel = Channel.from(packet.d, this.client); + channel.guild ??= this.client.guilds.get(packet.d.guild_id); if(!channel.guild) { - channel.guild = this.client.guilds.get(packet.d.guild_id); - if(!channel.guild) { - this.emit("debug", `Received THREAD_CREATE for channel in missing guild ${packet.d.guild_id}`); - break; - } + this.emit("debug", `Received THREAD_CREATE for channel in missing guild ${packet.d.guild_id}`); + break; } const parent = this.client.getChannel(packet.d.parent_id); - if(parent && parent.type === ChannelTypes.GUILD_FORUM) { + if(parent?.type === ChannelTypes.GUILD_FORUM) { parent.lastThreadID = packet.d.id; } @@ -1973,31 +1948,25 @@ class Shard extends EventEmitter { break; } channel.update(packet.d); - let addedMembers; - let removedMembers; - if(packet.d.added_members) { - addedMembers = packet.d.added_members.map((m) => { - if(m.presence) { - m.presence.id = m.presence.user.id; - this.client.users.update(m.presence.user, this.client); - } + const addedMembers = packet.d.added_members?.map((m) => { + if(m.presence) { + m.presence.id = m.presence.user.id; + this.client.users.update(m.presence.user, this.client); + } - m.thread_id = m.id; - m.id = m.user_id; - m.member.id = m.member.user.id; - const guild = this.client.guilds.get(packet.d.guild_id); - if(guild) { - if(m.presence) { - guild.members.update(m.presence, guild); - } - guild.members.update(m.member, guild); + m.thread_id = m.id; + m.id = m.user_id; + m.member.id = m.member.user.id; + const guild = this.client.guilds.get(packet.d.guild_id); + if(guild) { + if(m.presence) { + guild.members.update(m.presence, guild); } - return channel.members.update(m, this.client); - }); - } - if(packet.d.removed_member_ids) { - removedMembers = packet.d.removed_member_ids.map((id) => channel.members.remove({id}) || {id}); - } + guild.members.update(m.member, guild); + } + return channel.members.update(m, this.client); + }); + const removedMembers = packet.d.removed_member_ids?.map((id) => channel.members.remove({id}) || {id}); /** * Fired when anyone is added or removed from a thread. If the `guildMembers` intent is not specified, this will only apply for the current user * @event Client#threadMembersUpdate diff --git a/lib/rest/RequestHandler.js b/lib/rest/RequestHandler.js index 4d118f8b..02f15a48 100644 --- a/lib/rest/RequestHandler.js +++ b/lib/rest/RequestHandler.js @@ -371,15 +371,11 @@ class RequestHandler { if(this.globalBlock && auth) { this.readyQueue.push(() => { - if(!this.ratelimits[route]) { - this.ratelimits[route] = new SequentialBucket(1, this.latencyRef); - } + this.ratelimits[route] ??= new SequentialBucket(1, this.latencyRef); this.ratelimits[route].queue(actualCall, short); }); } else { - if(!this.ratelimits[route]) { - this.ratelimits[route] = new SequentialBucket(1, this.latencyRef); - } + this.ratelimits[route] ??= new SequentialBucket(1, this.latencyRef); this.ratelimits[route].queue(actualCall, short); } }); diff --git a/lib/structures/Guild.js b/lib/structures/Guild.js index b8b8a7fd..96c95198 100644 --- a/lib/structures/Guild.js +++ b/lib/structures/Guild.js @@ -278,7 +278,7 @@ class Guild extends Base { if(data.welcome_screen !== undefined) { this.welcomeScreen = { description: data.welcome_screen.description, - welcomeChannels: data.welcome_screen.welcome_channels && data.welcome_screen.welcome_channels.map((c) => { + welcomeChannels: data.welcome_screen.welcome_channels?.map((c) => { return { channelID: c.channel, description: c.description, diff --git a/lib/structures/GuildAuditLogEntry.js b/lib/structures/GuildAuditLogEntry.js index 495d28fe..8632f4c9 100644 --- a/lib/structures/GuildAuditLogEntry.js +++ b/lib/structures/GuildAuditLogEntry.js @@ -89,7 +89,7 @@ class GuildAuditLogEntry extends Base { this.channel = guild.threads.get(data.options.channel_id) || guild.channels.get(data.options.channel_id); if(data.options.message_id) { - this.message = this.channel && this.channel.messages.get(data.options.message_id) || {id: data.options.message_id}; + this.message = this.channel?.messages.get(data.options.message_id) || {id: data.options.message_id}; } } if(data.options.delete_member_days) { @@ -115,14 +115,14 @@ class GuildAuditLogEntry extends Base { if(this.actionType < 10) { // Guild return this.guild; } else if(this.actionType < 20) { // Channel - return this.guild && this.guild.channels.get(this.targetID); + return this.guild?.channels.get(this.targetID); } else if(this.actionType < 30) { // Member if(this.actionType === AuditLogActions.MEMBER_MOVE || this.actionType === AuditLogActions.MEMBER_DISCONNECT) { // MEMBER_MOVE / MEMBER_DISCONNECT return null; } - return this.guild && this.guild.members.get(this.targetID); + return this.guild?.members.get(this.targetID); } else if(this.actionType < 40) { // Role - return this.guild && this.guild.roles.get(this.targetID); + return this.guild?.roles.get(this.targetID); } else if(this.actionType < 50) { // Invite const changes = this.actionType === 42 ? this.before : this.after; // Apparently the meaning of life is a deleted invite return new Invite({ @@ -135,29 +135,29 @@ class GuildAuditLogEntry extends Base { max_uses: changes.max_uses, max_age: changes.max_age, temporary: changes.temporary - }, this.guild && this.guild.shard.client); + }, this.guild?.shard.client); } else if(this.actionType < 60) { // Webhook return null; // Go get the webhook yourself } else if(this.actionType < 70) { // Emoji - return this.guild && this.guild.emojis.find((emoji) => emoji.id === this.targetID); + return this.guild?.emojis.find((emoji) => emoji.id === this.targetID); } else if(this.actionType < 80) { // Message - return this.guild && this.guild.shard.client.users.get(this.targetID); + return this.guild?.shard.client.users.get(this.targetID); } else if(this.actionType < 83) { // Integrations return null; } else if(this.actionType < 90) { // Stage Instances - return this.guild && this.guild.stageInstances.get(this.targetID); + return this.guild?.stageInstances.get(this.targetID); } else if(this.actionType < 100) { // Sticker - return this.guild && this.guild.stickers.find((sticker) => sticker.id === this.targetID); + return this.guild?.stickers.find((sticker) => sticker.id === this.targetID); } else if(this.actionType < 110) { // Guild Scheduled Events - return this.guild && this.guild.events.get(this.targetID); + return this.guild?.events.get(this.targetID); } else if(this.actionType < 120) { // Thread - return this.guild && this.guild.threads.get(this.targetID); + return this.guild?.threads.get(this.targetID); } else if(this.actionType < 140) { // Application Command return null; } else if(this.actionType < 143) { // Auto Moderation Rule Updates return null; } else if(this.actionType < 146) { // Auto Moderation Actions - return this.guild && this.guild.shard.client.users.get(this.targetID); + return this.guild?.shard.client.users.get(this.targetID); } else { throw new Error("Unrecognized action type: " + this.actionType); } diff --git a/lib/structures/GuildScheduledEvent.js b/lib/structures/GuildScheduledEvent.js index 19c244e9..332d0470 100644 --- a/lib/structures/GuildScheduledEvent.js +++ b/lib/structures/GuildScheduledEvent.js @@ -43,11 +43,7 @@ class GuildScheduledEvent extends Base { update(data) { if(data.channel_id !== undefined) { if(data.channel_id !== null) { - if(this._client.guilds.get(data.guild_id)) { - this.channel = this._client.guilds.get(data.guild_id).channels.get(data.channel_id) || {id: data.channel_id}; - } else { - this.channel = {id: data.channel_id}; - } + this.channel = this._client.guilds.get(data.guild_id)?.channels.get(data.channel_id) || {id: data.channel_id}; } else { this.channel = null; } diff --git a/lib/structures/Member.js b/lib/structures/Member.js index 21cfa53e..cd2787f6 100644 --- a/lib/structures/Member.js +++ b/lib/structures/Member.js @@ -176,17 +176,13 @@ class Member extends Base { } get voiceState() { - if(this.guild && this.guild.voiceStates.has(this.id)) { - return this.guild.voiceStates.get(this.id); - } else { - return new VoiceState({ - id: this.id - }); - } + return this.guild?.voiceStates.get(this.id) || new VoiceState({ + id: this.id + }); } get game() { - return this.activities && this.activities.length > 0 ? this.activities[0] : null; + return this.activities?.length > 0 ? this.activities[0] : null; } /** diff --git a/lib/structures/Message.js b/lib/structures/Message.js index bf8b81ff..b03d2e52 100644 --- a/lib/structures/Message.js +++ b/lib/structures/Message.js @@ -379,35 +379,33 @@ class Message extends Base { let authorName = this.author.username; if(this.channel.guild) { const member = this.channel.guild.members.get(this.author.id); - if(member && member.nick) { + if(member?.nick) { authorName = member.nick; } } cleanContent = cleanContent.replace(new RegExp(`<@!?${this.author.id}>`, "g"), "@\u200b" + authorName); - if(this.mentions) { - this.mentions.forEach((mention) => { - if(this.channel.guild) { - const member = this.channel.guild.members.get(mention.id); - if(member && member.nick) { - cleanContent = cleanContent.replace(new RegExp(`<@!?${mention.id}>`, "g"), "@\u200b" + member.nick); - } + this.mentions?.forEach((mention) => { + if(this.channel.guild) { + const member = this.channel.guild.members.get(mention.id); + if(member?.nick) { + cleanContent = cleanContent.replace(new RegExp(`<@!?${mention.id}>`, "g"), "@\u200b" + member.nick); } - cleanContent = cleanContent.replace(new RegExp(`<@!?${mention.id}>`, "g"), "@\u200b" + mention.username); - }); - } + } + cleanContent = cleanContent.replace(new RegExp(`<@!?${mention.id}>`, "g"), "@\u200b" + mention.username); + }); if(this.channel.guild && this.roleMentions) { for(const roleID of this.roleMentions) { const role = this.channel.guild.roles.get(roleID); - const roleName = role ? role.name : "deleted-role"; + const roleName = role?.name ?? "deleted-role"; cleanContent = cleanContent.replace(new RegExp(`<@&${roleID}>`, "g"), "@\u200b" + roleName); } } this.channelMentions.forEach((id) => { const channel = this._client.getChannel(id); - if(channel && channel.name && channel.mention) { + if(channel?.name && channel?.mention) { cleanContent = cleanContent.replace(channel.mention, "#" + channel.name); } }); diff --git a/lib/structures/StageInstance.js b/lib/structures/StageInstance.js index b8ee76fc..1de8f024 100644 --- a/lib/structures/StageInstance.js +++ b/lib/structures/StageInstance.js @@ -18,7 +18,7 @@ class StageInstance extends Base { this._client = client; this.channel = client.getChannel(data.channel_id) || {id: data.channel_id}; this.guild = client.guilds.get(data.guild_id) || {id: data.guild_id}; - this.guildScheduledEvent = (this.guild.events && this.guild.events.get(data.guild_scheduled_event_id)) || {id: data.guild_scheduled_event_id}; + this.guildScheduledEvent = (this.guild.events?.get(data.guild_scheduled_event_id)) || {id: data.guild_scheduled_event_id}; this.update(data); } From 41993b976c55832502e71a26f5e73b5c89c87550 Mon Sep 17 00:00:00 2001 From: TTtie Date: Fri, 10 Mar 2023 16:30:47 +0000 Subject: [PATCH 03/16] more modernization, round 2 --- lib/structures/CategoryChannel.js | 2 +- lib/structures/Guild.js | 2 +- lib/structures/GuildChannel.js | 6 ++--- lib/structures/Message.js | 26 ++++++++------------ lib/structures/StageInstance.js | 2 +- lib/voice/Piper.js | 16 +++++------- lib/voice/SharedStream.js | 2 +- lib/voice/VoiceConnection.js | 30 +++++++++-------------- lib/voice/VoiceConnectionManager.js | 4 +-- lib/voice/streams/FFmpegDuplex.js | 4 +-- lib/voice/streams/FFmpegOggTransformer.js | 4 +-- lib/voice/streams/FFmpegPCMTransformer.js | 4 +-- lib/voice/streams/PCMOpusTransformer.js | 4 +-- 13 files changed, 41 insertions(+), 65 deletions(-) diff --git a/lib/structures/CategoryChannel.js b/lib/structures/CategoryChannel.js index 928974fb..e73e0b5e 100644 --- a/lib/structures/CategoryChannel.js +++ b/lib/structures/CategoryChannel.js @@ -32,7 +32,7 @@ class CategoryChannel extends GuildChannel { get channels() { const channels = new Collection(GuildChannel); - if(this.guild && this.guild.channels) { + if(this.guild?.channels) { for(const channel of this.guild.channels.values()) { if(channel.parentID === this.id) { channels.add(channel); diff --git a/lib/structures/Guild.js b/lib/structures/Guild.js index 96c95198..61df3694 100644 --- a/lib/structures/Guild.js +++ b/lib/structures/Guild.js @@ -166,7 +166,7 @@ class Guild extends Base { try { const channel = this.channels.get(voiceState.channel_id); const member = this.members.update(voiceState); - if(channel && channel.voiceMembers) { + if(channel?.voiceMembers) { channel.voiceMembers.add(member); } } catch(err) { diff --git a/lib/structures/GuildChannel.js b/lib/structures/GuildChannel.js index f02570eb..05b0ce14 100644 --- a/lib/structures/GuildChannel.js +++ b/lib/structures/GuildChannel.js @@ -130,20 +130,20 @@ class GuildChannel extends Channel { return new Permission(Permissions.all); } const channel = this instanceof ThreadChannel ? this.guild.channels.get(this.parentID) : this; - let overwrite = channel && channel.permissionOverwrites.get(this.guild.id); + let overwrite = channel?.permissionOverwrites.get(this.guild.id); if(overwrite) { permission = (permission & ~overwrite.deny) | overwrite.allow; } let deny = 0n; let allow = 0n; for(const roleID of member.roles) { - if((overwrite = channel && channel.permissionOverwrites.get(roleID))) { + if((overwrite = channel?.permissionOverwrites.get(roleID))) { deny |= overwrite.deny; allow |= overwrite.allow; } } permission = (permission & ~deny) | allow; - overwrite = channel && channel.permissionOverwrites.get(member.id); + overwrite = channel?.permissionOverwrites.get(member.id); if(overwrite) { permission = (permission & ~overwrite.deny) | overwrite.allow; } diff --git a/lib/structures/Message.js b/lib/structures/Message.js index b03d2e52..11277d4a 100644 --- a/lib/structures/Message.js +++ b/lib/structures/Message.js @@ -111,7 +111,7 @@ class Message extends Base { } else { interactionMember = data.interaction.member; } - } else if(this.channel.guild && this.channel.guild.members.has(data.interaction.user.id)) { + } else if(this.channel.guild?.members.has(data.interaction.user.id)) { interactionMember = this.channel.guild.members.get(data.interaction.user.id); } else { interactionMember = null; @@ -135,9 +135,7 @@ class Message extends Base { this.member = null; } - if(!this.guildID) { - this.guildID = this.channel.guild.id; - } + this.guildID ??= this.channel.guild.id; if(data.thread) { this.thread = this.channel.guild.threads.update(data.thread, client); @@ -370,27 +368,23 @@ class Message extends Base { return this._channelMentions; } - return (this._channelMentions = (this.content && this.content.match(/<#[0-9]+>/g) || []).map((mention) => mention.substring(2, mention.length - 1))); + return (this._channelMentions = (this.content?.match(/<#[0-9]+>/g) || []).map((mention) => mention.substring(2, mention.length - 1))); } get cleanContent() { - let cleanContent = this.content && this.content.replace(//g, "$1") || ""; + let cleanContent = this.content?.replace(//g, "$1") || ""; let authorName = this.author.username; - if(this.channel.guild) { - const member = this.channel.guild.members.get(this.author.id); - if(member?.nick) { - authorName = member.nick; - } + const member = this.channel.guild?.members.get(this.author.id); + if(member?.nick) { + authorName = member.nick; } cleanContent = cleanContent.replace(new RegExp(`<@!?${this.author.id}>`, "g"), "@\u200b" + authorName); this.mentions?.forEach((mention) => { - if(this.channel.guild) { - const member = this.channel.guild.members.get(mention.id); - if(member?.nick) { - cleanContent = cleanContent.replace(new RegExp(`<@!?${mention.id}>`, "g"), "@\u200b" + member.nick); - } + const member = this.channel.guild?.members.get(mention.id); + if(member?.nick) { + cleanContent = cleanContent.replace(new RegExp(`<@!?${mention.id}>`, "g"), "@\u200b" + member.nick); } cleanContent = cleanContent.replace(new RegExp(`<@!?${mention.id}>`, "g"), "@\u200b" + mention.username); }); diff --git a/lib/structures/StageInstance.js b/lib/structures/StageInstance.js index 1de8f024..1df1ce1a 100644 --- a/lib/structures/StageInstance.js +++ b/lib/structures/StageInstance.js @@ -18,7 +18,7 @@ class StageInstance extends Base { this._client = client; this.channel = client.getChannel(data.channel_id) || {id: data.channel_id}; this.guild = client.guilds.get(data.guild_id) || {id: data.guild_id}; - this.guildScheduledEvent = (this.guild.events?.get(data.guild_scheduled_event_id)) || {id: data.guild_scheduled_event_id}; + this.guildScheduledEvent = this.guild.events?.get(data.guild_scheduled_event_id) || {id: data.guild_scheduled_event_id}; this.update(data); } diff --git a/lib/voice/Piper.js b/lib/voice/Piper.js index f4f7f7b4..63645908 100644 --- a/lib/voice/Piper.js +++ b/lib/voice/Piper.js @@ -75,9 +75,9 @@ class Piper extends EventEmitter { if(!this.encoding) { return; } - if(this._dataPackets.push(packet) < this._dataPacketMax && this._endStream && this._endStream.manualCB) { + if(this._dataPackets.push(packet) < this._dataPacketMax && this._endStream?.manualCB) { process.nextTick(() => { - if(this._endStream && this._endStream.manualCB) { + if(this._endStream?.manualCB) { this._endStream.transformCB(); } }); @@ -225,16 +225,14 @@ class Piper extends EventEmitter { } getDataPacket() { - if(this._dataPackets.length < this._dataPacketMin && this._endStream && this._endStream.manualCB) { + if(this._dataPackets.length < this._dataPacketMin && this._endStream?.manualCB) { this._endStream.transformCB(); } if(this._retransformer.length === 0) { return this._dataPackets.shift(); } else { // If we don't have an opus instance yet, create one. - if(!this.opus) { - this.opus = this.opusFactory(); - } + this.opus ??= this.opusFactory(); const packet = this.opus.decode(this._dataPackets.shift()); for(let i = 0, num; i < packet.length - 1; i += 2) { @@ -264,7 +262,7 @@ class Piper extends EventEmitter { resetPackets() { // We no longer need this to convert inline volume, so... let it go. if(this.opus) { - this.opus.delete && this.opus.delete(); + this.opus.delete?.(); this.opus = null; } this._dataPackets = []; @@ -296,9 +294,7 @@ class Piper extends EventEmitter { return; } - if(this._endStream) { - this._endStream.removeAllListeners("data"); - } + this._endStream?.removeAllListeners("data"); this.reset(); if(this.encoding) { diff --git a/lib/voice/SharedStream.js b/lib/voice/SharedStream.js index d4dc133b..b9e91857 100644 --- a/lib/voice/SharedStream.js +++ b/lib/voice/SharedStream.js @@ -162,7 +162,7 @@ class SharedStream extends EventEmitter { return; } this.ended = true; - if(this.current && this.current.timeout) { + if(this.current?.timeout) { clearTimeout(this.current.timeout); this.current.timeout = null; } diff --git a/lib/voice/VoiceConnection.js b/lib/voice/VoiceConnection.js index 3c545343..0ca3d8a3 100644 --- a/lib/voice/VoiceConnection.js +++ b/lib/voice/VoiceConnection.js @@ -153,7 +153,7 @@ class VoiceConnection extends EventEmitter { connect(data) { this.connecting = true; - if(this.ws && this.ws.readyState !== WebSocket.CLOSED) { + if(this.ws?.readyState !== WebSocket.CLOSED) { this.disconnect(undefined, true); setTimeout(() => { if(!this.connecting && !this.ready) { @@ -326,9 +326,7 @@ class VoiceConnection extends EventEmitter { case VoiceOPCodes.CLIENT_DISCONNECT: { if(this.opus) { // opusscript requires manual cleanup - if(this.opus[packet.d.user_id] && this.opus[packet.d.user_id].delete) { - this.opus[packet.d.user_id].delete(); - } + this.opus[packet.d.user_id]?.delete?.(); delete this.opus[packet.d.user_id]; } @@ -608,9 +606,7 @@ class VoiceConnection extends EventEmitter { } if(this.receiveStreamPCM) { const userID = this.ssrcUserMap[nonce.readUIntBE(8, 4)]; - if(!this.opus[userID]) { - this.opus[userID] = createOpus(this.samplingRate, this.channels, this.bitrate); - } + this.opus[userID] ??= createOpus(this.samplingRate, this.channels, this.bitrate); data = this.opus[userID].decode(data, this.frameSize); if(!data) { @@ -665,7 +661,7 @@ class VoiceConnection extends EventEmitter { } sendWS(op, data) { - if(this.ws && this.ws.readyState === WebSocket.OPEN) { + if(this.ws?.readyState === WebSocket.OPEN) { data = JSON.stringify({op: op, d: data}); this.ws.send(data); this.emit("debug", data); @@ -697,7 +693,7 @@ class VoiceConnection extends EventEmitter { return; } this.ended = true; - if(this.current && this.current.timeout) { + if(this.current?.timeout) { clearTimeout(this.current.timeout); this.current.timeout = null; } @@ -747,20 +743,18 @@ class VoiceConnection extends EventEmitter { * @arg {Boolean} selfDeaf Whether the bot deafened itself or not (audio sending is unaffected) */ updateVoiceState(selfMute, selfDeaf) { - if(this.shard.sendWS) { - this.shard.sendWS(GatewayOPCodes.VOICE_STATE_UPDATE, { - guild_id: this.id, - channel_id: this.channelID || null, - self_mute: !!selfMute, - self_deaf: !!selfDeaf - }); - } + this.shard.sendWS?.(GatewayOPCodes.VOICE_STATE_UPDATE, { + guild_id: this.id, + channel_id: this.channelID || null, + self_mute: !!selfMute, + self_deaf: !!selfDeaf + }); } _destroy() { if(this.opus) { for(const key in this.opus) { - this.opus[key].delete && this.opus[key].delete(); + this.opus[key].delete?.(); delete this.opus[key]; } } diff --git a/lib/voice/VoiceConnectionManager.js b/lib/voice/VoiceConnectionManager.js index 49143026..2df1e321 100644 --- a/lib/voice/VoiceConnectionManager.js +++ b/lib/voice/VoiceConnectionManager.js @@ -11,7 +11,7 @@ class VoiceConnectionManager extends Collection { join(guildID, channelID, options) { const connection = this.get(guildID); - if(connection && connection.ws) { + if(connection?.ws) { connection.switchChannel(channelID); if(connection.ready) { return Promise.resolve(connection); @@ -70,7 +70,7 @@ class VoiceConnectionManager extends Collection { } voiceServerUpdate(data) { - if(this.pendingGuilds[data.guild_id] && this.pendingGuilds[data.guild_id].timeout) { + if(this.pendingGuilds[data.guild_id]?.timeout) { clearTimeout(this.pendingGuilds[data.guild_id].timeout); this.pendingGuilds[data.guild_id].timeout = null; } diff --git a/lib/voice/streams/FFmpegDuplex.js b/lib/voice/streams/FFmpegDuplex.js index 91a491a3..99e5f150 100644 --- a/lib/voice/streams/FFmpegDuplex.js +++ b/lib/voice/streams/FFmpegDuplex.js @@ -15,9 +15,7 @@ const delegateEvents = { class FFmpegDuplex extends DuplexStream { constructor(command, options = {}) { - if(options.highWaterMark === undefined) { - options.highWaterMark = 0; - } + options.highWaterMark ??= 0; super(options); this.command = command; diff --git a/lib/voice/streams/FFmpegOggTransformer.js b/lib/voice/streams/FFmpegOggTransformer.js index e42a8130..cb3f2c51 100644 --- a/lib/voice/streams/FFmpegOggTransformer.js +++ b/lib/voice/streams/FFmpegOggTransformer.js @@ -6,9 +6,7 @@ module.exports = function(options = {}) { if(!options.command) { throw new Error("Invalid converter command"); } - if(options.frameDuration === undefined) { - options.frameDuration = 60; - } + options.frameDuration ??= 60; let inputArgs = [ "-analyzeduration", "0", "-loglevel", "24" diff --git a/lib/voice/streams/FFmpegPCMTransformer.js b/lib/voice/streams/FFmpegPCMTransformer.js index 3ee0362a..139fb332 100644 --- a/lib/voice/streams/FFmpegPCMTransformer.js +++ b/lib/voice/streams/FFmpegPCMTransformer.js @@ -6,9 +6,7 @@ module.exports = function(options = {}) { if(!options.command) { throw new Error("Invalid converter command"); } - if(options.samplingRate === undefined) { - options.samplingRate = 48000; - } + options.samplingRate ??= 48000; const inputArgs = [ "-analyzeduration", "0", "-loglevel", "24" diff --git a/lib/voice/streams/PCMOpusTransformer.js b/lib/voice/streams/PCMOpusTransformer.js index ba7cd38e..ceaf301d 100644 --- a/lib/voice/streams/PCMOpusTransformer.js +++ b/lib/voice/streams/PCMOpusTransformer.js @@ -14,9 +14,7 @@ class PCMOpusTransformer extends BaseTransformer { } _destroy(...args) { - if(this.opus.delete) { - this.opus.delete(); - } + this.opus.delete?.(); return super._destroy(...args); } From 986100778d6d1089b5fa95e30ce1c08cf1ab47d5 Mon Sep 17 00:00:00 2001 From: TTtie Date: Sat, 11 Mar 2023 16:43:45 +0000 Subject: [PATCH 04/16] compact this a bit better --- lib/structures/Guild.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/structures/Guild.js b/lib/structures/Guild.js index 61df3694..4eacbed9 100644 --- a/lib/structures/Guild.js +++ b/lib/structures/Guild.js @@ -166,9 +166,7 @@ class Guild extends Base { try { const channel = this.channels.get(voiceState.channel_id); const member = this.members.update(voiceState); - if(channel?.voiceMembers) { - channel.voiceMembers.add(member); - } + channel?.voiceMembers?.add(member); } catch(err) { client.emit("error", err, this.shard.id); continue; From a76104cba7a80f9c16b5508c0ebd1619ed11691b Mon Sep 17 00:00:00 2001 From: TTtie Date: Sat, 11 Mar 2023 17:08:10 +0000 Subject: [PATCH 05/16] move leftovers to optional chaining --- lib/Client.js | 2 +- lib/gateway/Shard.js | 4 ++-- lib/rest/RequestHandler.js | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 3a2991dc..0db98ee0 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -2795,7 +2795,7 @@ class Client extends EventEmitter { if(!channel) { return Promise.reject(new Error("Channel not found")); } - if(channel.guild && channel.guild.members.has(this.user.id) && !(channel.permissionsOf(this.user.id).allow & Constants.Permissions.voiceConnect)) { + if(channel.guild?.members.has(this.user.id) && !(channel.permissionsOf(this.user.id).allow & Constants.Permissions.voiceConnect)) { return Promise.reject(new Error("Insufficient permission to connect to voice channel")); } this.shards.get(this.guildShardMap[this.channelGuildMap[channelID]] || 0).sendWS(Constants.GatewayOPCodes.VOICE_STATE_UPDATE, { diff --git a/lib/gateway/Shard.js b/lib/gateway/Shard.js index 92b995e3..e96a091e 100644 --- a/lib/gateway/Shard.js +++ b/lib/gateway/Shard.js @@ -468,7 +468,7 @@ class Shard extends EventEmitter { timeout: setTimeout(() => { res(this.requestMembersPromise[opts.nonce].members); delete this.requestMembersPromise[opts.nonce]; - }, (options && options.timeout) || this.client.shards.options.requestTimeout) + }, options?.timeout || this.client.shards.options.requestTimeout) }); } @@ -748,7 +748,7 @@ class Shard extends EventEmitter { let oldChannel, newChannel; if(oldChannelID) { oldChannel = guild.channels.get(oldChannelID); - if(oldChannel && oldChannel.type !== ChannelTypes.GUILD_VOICE && oldChannel.type !== ChannelTypes.GUILD_STAGE_VOICE) { + if(oldChannel?.type !== ChannelTypes.GUILD_VOICE && oldChannel?.type !== ChannelTypes.GUILD_STAGE_VOICE) { this.emit("warn", "Old channel not a recognized voice channel: " + oldChannelID, this.id); oldChannel = null; } diff --git a/lib/rest/RequestHandler.js b/lib/rest/RequestHandler.js index 02f15a48..ea5c71ce 100644 --- a/lib/rest/RequestHandler.js +++ b/lib/rest/RequestHandler.js @@ -85,10 +85,9 @@ class RequestHandler { if(auth) { headers.Authorization = this._client._token; } - if(body && body.reason) { // Audit log reason sniping + if(body?.reason) { // Audit log reason sniping headers["X-Audit-Log-Reason"] = encodeURIComponent(body.reason); delete body.reason; - } if(file) { if(Array.isArray(file)) { From 1955420daf45a53c0c7815c7b15693177f2951de Mon Sep 17 00:00:00 2001 From: TTtie Date: Sat, 11 Mar 2023 17:29:52 +0000 Subject: [PATCH 06/16] more optional chaining/null coalescing --- lib/Client.js | 12 +++--------- lib/gateway/Shard.js | 12 ++++-------- lib/voice/VoiceConnectionManager.js | 5 +---- lib/voice/streams/BaseTransformer.js | 8 ++------ 4 files changed, 10 insertions(+), 27 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 0db98ee0..42ce9e07 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -2097,9 +2097,7 @@ class Client extends EventEmitter { * @returns {Promise<{autoModerationRules: Array, commands: Array, entries: Array, events: Array, integrations: Array, threads: Array, users: Array, webhooks: Array}>} */ getGuildAuditLog(guildID, options = {}) { - if(options.limit === undefined) { // Legacy behavior - options.limit = 50; - } + options.limit ??= 50; // Legacy behavior if(options.actionType !== undefined) { options.action_type = options.actionType; } @@ -2403,9 +2401,7 @@ class Client extends EventEmitter { if(reaction === decodeURI(reaction)) { reaction = encodeURIComponent(reaction); } - if(options.limit === undefined) { // Legacy behavior - options.limit = 100; - } + options.limit ??= 100; // Legacy behavior return this.requestHandler.request("GET", Endpoints.CHANNEL_MESSAGE_REACTION(channelID, messageID, reaction), true, options).then((users) => users.map((user) => new User(user, this))); } @@ -2420,9 +2416,7 @@ class Client extends EventEmitter { * @returns {Promise>} */ async getMessages(channelID, options = {}) { - if(options.limit === undefined) { // Legacy behavior - options.limit = 50; - } + options.limit ??= 50; // Legacy behavior let limit = options.limit; if(limit && limit > 100) { let logs = []; diff --git a/lib/gateway/Shard.js b/lib/gateway/Shard.js index e96a091e..a46d6f49 100644 --- a/lib/gateway/Shard.js +++ b/lib/gateway/Shard.js @@ -1612,14 +1612,10 @@ class Shard extends EventEmitter { return guild.members.add(member, guild); }); - if(packet.d.presences) { - packet.d.presences.forEach((presence) => { - const member = guild.members.get(presence.user.id); - if(member) { - member.update(presence); - } - }); - } + packet.d.presences?.forEach((presence) => { + const member = guild.members.get(presence.user.id); + member?.update(presence); + }); if(this.requestMembersPromise.hasOwnProperty(packet.d.nonce)) { this.requestMembersPromise[packet.d.nonce].members.push(...members); diff --git a/lib/voice/VoiceConnectionManager.js b/lib/voice/VoiceConnectionManager.js index 2df1e321..46754644 100644 --- a/lib/voice/VoiceConnectionManager.js +++ b/lib/voice/VoiceConnectionManager.js @@ -63,10 +63,7 @@ class VoiceConnectionManager extends Collection { switch(guildID, channelID) { const connection = this.get(guildID); - if(!connection) { - return; - } - connection.switch(channelID); + connection?.switch(channelID); } voiceServerUpdate(data) { diff --git a/lib/voice/streams/BaseTransformer.js b/lib/voice/streams/BaseTransformer.js index 7160c6ce..d4dfa766 100644 --- a/lib/voice/streams/BaseTransformer.js +++ b/lib/voice/streams/BaseTransformer.js @@ -6,12 +6,8 @@ const TransformStream = require("stream").Transform; class BaseTransformer extends TransformStream { constructor(options = {}) { - if(options.allowHalfOpen === undefined) { - options.allowHalfOpen = true; - } - if(options.highWaterMark === undefined) { - options.highWaterMark = 0; - } + options.allowHalfOpen ??= true; + options.highWaterMark ??= 0; super(options); this.manualCB = false; } From 20fcef2568bb63e975e09312d18632cb60b0f981 Mon Sep 17 00:00:00 2001 From: TTtie Date: Sun, 12 Mar 2023 13:55:08 +0000 Subject: [PATCH 07/16] revert a few changes breaking old logic --- lib/gateway/Shard.js | 4 ++-- lib/voice/VoiceConnection.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/gateway/Shard.js b/lib/gateway/Shard.js index a46d6f49..4da7ed1a 100644 --- a/lib/gateway/Shard.js +++ b/lib/gateway/Shard.js @@ -88,7 +88,7 @@ class Shard extends EventEmitter { * Tells the shard to connect */ connect() { - if(this.ws?.readyState != WebSocket.CLOSED) { + if(this.ws && this.ws.readyState != WebSocket.CLOSED) { this.emit("error", new Error("Existing connection detected"), this.id); return; } @@ -748,7 +748,7 @@ class Shard extends EventEmitter { let oldChannel, newChannel; if(oldChannelID) { oldChannel = guild.channels.get(oldChannelID); - if(oldChannel?.type !== ChannelTypes.GUILD_VOICE && oldChannel?.type !== ChannelTypes.GUILD_STAGE_VOICE) { + if(oldChannel && oldChannel.type !== ChannelTypes.GUILD_VOICE && oldChannel.type !== ChannelTypes.GUILD_STAGE_VOICE) { this.emit("warn", "Old channel not a recognized voice channel: " + oldChannelID, this.id); oldChannel = null; } diff --git a/lib/voice/VoiceConnection.js b/lib/voice/VoiceConnection.js index 0ca3d8a3..3522d6da 100644 --- a/lib/voice/VoiceConnection.js +++ b/lib/voice/VoiceConnection.js @@ -153,7 +153,7 @@ class VoiceConnection extends EventEmitter { connect(data) { this.connecting = true; - if(this.ws?.readyState !== WebSocket.CLOSED) { + if(this.ws && this.ws.readyState !== WebSocket.CLOSED) { this.disconnect(undefined, true); setTimeout(() => { if(!this.connecting && !this.ready) { From b006fc83b72054e646ba21182659115f4bb584eb Mon Sep 17 00:00:00 2001 From: TTtie Date: Thu, 16 Mar 2023 22:07:40 +0000 Subject: [PATCH 08/16] (hopefully not breaking) use class fields where possible --- .eslintrc.yml | 4 +++ lib/Client.js | 41 +++++++++++----------- lib/gateway/ShardManager.js | 8 ++--- lib/rest/RequestHandler.js | 8 ++--- lib/util/Bucket.js | 6 ++-- lib/util/MultipartData.js | 6 ++-- lib/util/SequentialBucket.js | 6 ++-- lib/voice/Piper.js | 20 +++++------ lib/voice/SharedStream.js | 20 +++++------ lib/voice/VoiceConnection.js | 43 +++++++++++++----------- lib/voice/VoiceConnectionManager.js | 2 +- lib/voice/streams/BaseTransformer.js | 2 +- lib/voice/streams/DCAOpusTransformer.js | 6 +--- lib/voice/streams/OggOpusTransformer.js | 8 ++--- lib/voice/streams/PCMOpusTransformer.js | 3 +- lib/voice/streams/VolumeTransformer.js | 2 +- lib/voice/streams/WebmOpusTransformer.js | 10 ++---- 17 files changed, 94 insertions(+), 101 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index 52aa802f..b379faef 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -62,6 +62,7 @@ rules: sort-class-members/sort-class-members: - 2 - order: + - "[alphabetical-properties]" - constructor - update - "[alphabetical-getters]" @@ -78,6 +79,9 @@ rules: alphabetical-methods: - type: method sort: alphabetical + alphabetical-properties: + - type: property + sort: alphabetical alphabetical-conventional-private-methods: - name: "/_.+/" type: method diff --git a/lib/Client.js b/lib/Client.js index 42ce9e07..e6b7fe78 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -65,6 +65,27 @@ const sleep = (ms) => new Promise((res) => setTimeout(res, ms)); * @prop {Collection} voiceConnections Extended collection of active VoiceConnections the bot has */ class Client extends EventEmitter { + channelGuildMap = {}; + guilds = new Collection(Guild); + guildShardMap = {}; + lastConnect = 0; + lastReconnectDelay = 0; + presence = { + activities: null, + afk: false, + since: null, + status: "offline" + }; + privateChannelMap = {}; + privateChannels = new Collection(PrivateChannel); + ready = false; + reconnectAttempts = 0; + startTime = 0; + threadGuildMap = {}; + unavailableGuilds = new Collection(UnavailableGuild); + users = new Collection(User); + voiceConnections = new VoiceConnectionManager(); + /** * Create a Client * @arg {String} token The auth token to use. Bot tokens should be prefixed with `Bot` (e.g. `Bot MTExIHlvdSAgdHJpZWQgMTEx.O5rKAA.dQw4w9WgXcQ_wpV-gGA4PSk_bm8`). @@ -152,29 +173,9 @@ class Client extends EventEmitter { this.shards = new ShardManager(this, this.options.gateway); delete this.options.gateway; - this.ready = false; this.bot = this._token.startsWith("Bot "); - this.startTime = 0; - this.lastConnect = 0; - this.channelGuildMap = {}; - this.threadGuildMap = {}; - this.guilds = new Collection(Guild); - this.privateChannelMap = {}; - this.privateChannels = new Collection(PrivateChannel); - this.guildShardMap = {}; - this.unavailableGuilds = new Collection(UnavailableGuild); - this.users = new Collection(User); - this.presence = { - activities: null, - afk: false, - since: null, - status: "offline" - }; - this.voiceConnections = new VoiceConnectionManager(); this.connect = this.connect.bind(this); - this.lastReconnectDelay = 0; - this.reconnectAttempts = 0; } get uptime() { diff --git a/lib/gateway/ShardManager.js b/lib/gateway/ShardManager.js index 5f273dce..e8f43ef4 100644 --- a/lib/gateway/ShardManager.js +++ b/lib/gateway/ShardManager.js @@ -14,6 +14,10 @@ try { } } class ShardManager extends Collection { + buckets = new Map(); + connectQueue = []; + connectTimeout = null; + constructor(client, options = {}) { super(Shard); this._client = client; @@ -65,10 +69,6 @@ class ShardManager extends Collection { if(typeof window !== "undefined" || !ZlibSync) { this.options.compress = false; // zlib does not like Blobs, Pako is not here } - - this.buckets = new Map(); - this.connectQueue = []; - this.connectTimeout = null; } connect(shard) { diff --git a/lib/rest/RequestHandler.js b/lib/rest/RequestHandler.js index ea5c71ce..1804a644 100644 --- a/lib/rest/RequestHandler.js +++ b/lib/rest/RequestHandler.js @@ -15,6 +15,10 @@ const Zlib = require("zlib"); * Handles API requests */ class RequestHandler { + globalBlock = false; + ratelimits = {}; + readyQueue = []; + userAgent = `DiscordBot (https://github.com/projectdysnomia/dysnomia, ${require("../../package.json").version})`; constructor(client, options) { this.options = options = Object.assign({ agent: null, @@ -28,8 +32,6 @@ class RequestHandler { }, options); this._client = client; - this.userAgent = `DiscordBot (https://github.com/projectdysnomia/dysnomia, ${require("../../package.json").version})`; - this.ratelimits = {}; this.latencyRef = { latency: this.options.ratelimiterOffset, raw: new Array(10).fill(this.options.ratelimiterOffset), @@ -37,8 +39,6 @@ class RequestHandler { timeOffsets: new Array(10).fill(0), lastTimeOffsetCheck: 0 }; - this.globalBlock = false; - this.readyQueue = []; if(this.options.forceQueueing) { this.globalBlock = true; this._client.once("shardPreReady", () => this.globalUnblock()); diff --git a/lib/util/Bucket.js b/lib/util/Bucket.js index cca9e38c..525bf10c 100644 --- a/lib/util/Bucket.js +++ b/lib/util/Bucket.js @@ -12,6 +12,10 @@ const Base = require("../structures/Base"); * @prop {Number} tokens How many tokens the bucket has consumed in this interval */ class Bucket { + _queue = []; + lastReset = 0; + lastSend = 0; + tokens = 0; /** * Construct a Bucket * @arg {Number} tokenLimit The max number of tokens the bucket can consume per interval @@ -25,9 +29,7 @@ class Bucket { this.tokenLimit = tokenLimit; this.interval = interval; this.latencyRef = options.latencyRef || {latency: 0}; - this.lastReset = this.tokens = this.lastSend = 0; this.reservedTokens = options.reservedTokens || 0; - this._queue = []; } check() { diff --git a/lib/util/MultipartData.js b/lib/util/MultipartData.js index e9870cb4..e60f6016 100644 --- a/lib/util/MultipartData.js +++ b/lib/util/MultipartData.js @@ -1,10 +1,8 @@ "use strict"; class MultipartData { - constructor() { - this.boundary = "----------------Dysnomia"; - this.bufs = []; - } + boundary = "----------------Dysnomia"; + bufs = []; attach(fieldName, data, filename) { if(data === undefined) { diff --git a/lib/util/SequentialBucket.js b/lib/util/SequentialBucket.js index 4806f5d4..e96e669b 100644 --- a/lib/util/SequentialBucket.js +++ b/lib/util/SequentialBucket.js @@ -12,6 +12,9 @@ const Base = require("../structures/Base"); * @prop {Number} reset Timestamp of next reset */ class SequentialBucket { + _queue = []; + processing = false; + reset = 0; /** * Construct a SequentialBucket * @arg {Number} limit The max number of tokens the bucket can consume per interval @@ -20,10 +23,7 @@ class SequentialBucket { */ constructor(limit, latencyRef = {latency: 0}) { this.limit = this.remaining = limit; - this.reset = 0; - this.processing = false; this.latencyRef = latencyRef; - this._queue = []; } check(override) { diff --git a/lib/voice/Piper.js b/lib/voice/Piper.js index 63645908..083456dc 100644 --- a/lib/voice/Piper.js +++ b/lib/voice/Piper.js @@ -45,24 +45,22 @@ function webGetter(link, depth = 8) { } class Piper extends EventEmitter { + _dataPacketMax = 30; + _dataPacketMin = 15; + _dataPackets = []; + _retransformer = []; + encoding = false; + libopus = true; + opus = null; + volumeLevel = 1; + constructor(converterCommand, opusFactory) { super(); this.reset(); this.converterCommand = converterCommand; - this._dataPackets = []; - this._dataPacketMax = 30; - this._dataPacketMin = 15; - this.encoding = false; - this.libopus = true; - this.opusFactory = opusFactory; - this.opus = null; - - this.volumeLevel = 1; - - this._retransformer = []; this.addDataPacket = this.addDataPacket.bind(this); } diff --git a/lib/voice/SharedStream.js b/lib/voice/SharedStream.js index b9e91857..cef64578 100644 --- a/lib/voice/SharedStream.js +++ b/lib/voice/SharedStream.js @@ -24,16 +24,18 @@ try { * @prop {Number} volume The current volume level of the connection */ class SharedStream extends EventEmitter { + bitrate = 64_000; + channels = 2; + ended = true; + frameDuration = 20; + playing = false; + samplingRate = 48_000; + speaking = false; + voiceConnections = new Collection(VoiceConnection); + constructor() { super(); - this.samplingRate = 48000; - this.frameDuration = 20; - this.channels = 2; - this.bitrate = 64000; - - this.voiceConnections = new Collection(VoiceConnection); - if(!VoiceConnection._converterCommand.cmd) { VoiceConnection._converterCommand.pickCommand(); } @@ -49,10 +51,6 @@ class SharedStream extends EventEmitter { this.piper.libopus = false; } - this.ended = true; - this.playing = false; - this.speaking = false; - this._send = this._send.bind(this); } diff --git a/lib/voice/VoiceConnection.js b/lib/voice/VoiceConnection.js index 3522d6da..c57feb6f 100644 --- a/lib/voice/VoiceConnection.js +++ b/lib/voice/VoiceConnection.js @@ -77,6 +77,30 @@ converterCommand.pickCommand = function pickCommand() { * @prop {Number} volume The current volume level of the connection */ class VoiceConnection extends EventEmitter { + bitrate = 64_000; + channelID = null; + channels = 2; + connecting = false; + connectionTimeout = null; + frameDuration = 20; + paused = true; + ready = false; + reconnecting = false; + samplingRate = 48_000; + sendBuffer = Buffer.allocUnsafe(16 + 32 + MAX_FRAME_SIZE); + sendNonce = Buffer.alloc(24); + + sequence = 0; + speaking = false; + ssrcUserMap = {}; + timestamp = 0; + + // frameSize and pcmSize must come after the properties they reference to get initialized correctly + /* eslint-disable sort-class-members/sort-class-members */ + frameSize = this.samplingRate * this.frameDuration / 1_000; + pcmSize = this.frameSize * this.channels * 2; + /* eslint-enable sort-class-members/sort-class-members */ + constructor(id, options = {}) { super(); @@ -97,12 +121,6 @@ class VoiceConnection extends EventEmitter { } this.id = id; - this.samplingRate = 48000; - this.channels = 2; - this.frameDuration = 20; - this.frameSize = this.samplingRate * this.frameDuration / 1000; - this.pcmSize = this.frameSize * this.channels * 2; - this.bitrate = 64000; this.shared = !!options.shared; this.shard = options.shard || {}; this.opusOnly = !!options.opusOnly; @@ -111,19 +129,6 @@ class VoiceConnection extends EventEmitter { this.opus = {}; } - this.channelID = null; - this.paused = true; - this.speaking = false; - this.sequence = 0; - this.timestamp = 0; - this.ssrcUserMap = {}; - this.connectionTimeout = null; - this.connecting = false; - this.reconnecting = false; - this.ready = false; - - this.sendBuffer = Buffer.allocUnsafe(16 + 32 + MAX_FRAME_SIZE); - this.sendNonce = Buffer.alloc(24); this.sendNonce[0] = 0x80; this.sendNonce[1] = 0x78; diff --git a/lib/voice/VoiceConnectionManager.js b/lib/voice/VoiceConnectionManager.js index 46754644..90555489 100644 --- a/lib/voice/VoiceConnectionManager.js +++ b/lib/voice/VoiceConnectionManager.js @@ -4,9 +4,9 @@ const Base = require("../structures/Base"); const Collection = require("../util/Collection"); class VoiceConnectionManager extends Collection { + pendingGuilds = {}; constructor(vcObject) { super(vcObject || require("./VoiceConnection")); - this.pendingGuilds = {}; } join(guildID, channelID, options) { diff --git a/lib/voice/streams/BaseTransformer.js b/lib/voice/streams/BaseTransformer.js index d4dfa766..832fc8cb 100644 --- a/lib/voice/streams/BaseTransformer.js +++ b/lib/voice/streams/BaseTransformer.js @@ -5,11 +5,11 @@ const Base = require("../../structures/Base"); const TransformStream = require("stream").Transform; class BaseTransformer extends TransformStream { + manualCB = false; constructor(options = {}) { options.allowHalfOpen ??= true; options.highWaterMark ??= 0; super(options); - this.manualCB = false; } setTransformCB(cb) { diff --git a/lib/voice/streams/DCAOpusTransformer.js b/lib/voice/streams/DCAOpusTransformer.js index 6c44afb9..5ea2aef5 100644 --- a/lib/voice/streams/DCAOpusTransformer.js +++ b/lib/voice/streams/DCAOpusTransformer.js @@ -3,11 +3,7 @@ const BaseTransformer = require("./BaseTransformer"); class DCAOpusTransformer extends BaseTransformer { - constructor(options = {}) { - super(options); - - this._remainder = null; - } + _remainder = null; process(buffer) { if(buffer.length - buffer._index < 2) { diff --git a/lib/voice/streams/OggOpusTransformer.js b/lib/voice/streams/OggOpusTransformer.js index 6c4baed3..25560150 100644 --- a/lib/voice/streams/OggOpusTransformer.js +++ b/lib/voice/streams/OggOpusTransformer.js @@ -3,12 +3,8 @@ const BaseTransformer = require("./BaseTransformer"); class OggOpusTransformer extends BaseTransformer { - constructor(options = {}) { - super(options); - - this._remainder = null; - this._bitstream = null; - } + _bitstream = null; + _remainder = null; process(buffer) { if(buffer.length - buffer._index <= 26) { diff --git a/lib/voice/streams/PCMOpusTransformer.js b/lib/voice/streams/PCMOpusTransformer.js index ceaf301d..924fb00e 100644 --- a/lib/voice/streams/PCMOpusTransformer.js +++ b/lib/voice/streams/PCMOpusTransformer.js @@ -3,14 +3,13 @@ const BaseTransformer = require("./BaseTransformer"); class PCMOpusTransformer extends BaseTransformer { + _remainder = null; constructor(options = {}) { super(options); this.opus = options.opusFactory(); this.frameSize = options.frameSize || 2880; this.pcmSize = options.pcmSize || 11520; - - this._remainder = null; } _destroy(...args) { diff --git a/lib/voice/streams/VolumeTransformer.js b/lib/voice/streams/VolumeTransformer.js index f5a1a7f1..3b2fd01a 100644 --- a/lib/voice/streams/VolumeTransformer.js +++ b/lib/voice/streams/VolumeTransformer.js @@ -3,10 +3,10 @@ const BaseTransformer = require("./BaseTransformer"); class VolumeTransformer extends BaseTransformer { + _remainder = null; constructor(options = {}) { super(options); - this._remainder = null; this.setVolume(1.0); } diff --git a/lib/voice/streams/WebmOpusTransformer.js b/lib/voice/streams/WebmOpusTransformer.js index 9af7eb3c..449e5dd0 100644 --- a/lib/voice/streams/WebmOpusTransformer.js +++ b/lib/voice/streams/WebmOpusTransformer.js @@ -16,13 +16,9 @@ const TAG_TYPE_TAG = 2; const TRACKTYPE_AUDIO = 2; // EBML spec: https://www.matroska.org/technical/specs/index.html#TrackType class WebmOpusTransformer extends BaseTransformer { - constructor(options = {}) { - super(options); - - this._tag_stack = []; - this._state = STATE_TAG; - this._total = 0; - } + _state = STATE_TAG; + _tag_stack = []; + _total = 0; getVIntLength(buffer, index) { let length = 1; From 53b6938e863d8991b9bb0eac9366f7245d85a60f Mon Sep 17 00:00:00 2001 From: TTtie Date: Sat, 18 Mar 2023 21:25:07 +0000 Subject: [PATCH 09/16] prefix Node.js built-in imports with `node:` --- lib/Client.js | 2 +- lib/gateway/Shard.js | 4 ++-- lib/rest/RequestHandler.js | 8 ++++---- lib/structures/Base.js | 2 +- lib/util/BrowserWebSocket.js | 4 ++-- lib/util/Bucket.js | 2 +- lib/util/SequentialBucket.js | 2 +- lib/voice/Piper.js | 14 +++++++------- lib/voice/SharedStream.js | 4 ++-- lib/voice/VoiceConnection.js | 10 +++++----- lib/voice/VoiceDataStream.js | 2 +- lib/voice/streams/BaseTransformer.js | 4 ++-- lib/voice/streams/FFmpegDuplex.js | 8 ++++---- 13 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index e6b7fe78..7b62e8a9 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -32,7 +32,7 @@ let EventEmitter; try { EventEmitter = require("eventemitter3"); } catch(err) { - EventEmitter = require("events"); + EventEmitter = require("node:events"); } let Erlpack; try { diff --git a/lib/gateway/Shard.js b/lib/gateway/Shard.js index 4da7ed1a..9bf77920 100644 --- a/lib/gateway/Shard.js +++ b/lib/gateway/Shard.js @@ -1,6 +1,6 @@ "use strict"; -const util = require("util"); +const util = require("node:util"); const Base = require("../structures/Base"); const Bucket = require("../util/Bucket"); const Channel = require("../structures/Channel"); @@ -26,7 +26,7 @@ let EventEmitter; try { EventEmitter = require("eventemitter3"); } catch(err) { - EventEmitter = require("events").EventEmitter; + EventEmitter = require("node:events").EventEmitter; } let Erlpack; try { diff --git a/lib/rest/RequestHandler.js b/lib/rest/RequestHandler.js index 1804a644..8c6036d8 100644 --- a/lib/rest/RequestHandler.js +++ b/lib/rest/RequestHandler.js @@ -1,15 +1,15 @@ "use strict"; -const util = require("util"); +const util = require("node:util"); const Base = require("../structures/Base"); const DiscordHTTPError = require("../errors/DiscordHTTPError"); const DiscordRESTError = require("../errors/DiscordRESTError"); const Endpoints = require("./Endpoints"); -const HTTPS = require("https"); -const HTTP = require("http"); +const HTTPS = require("node:https"); +const HTTP = require("node:http"); const MultipartData = require("../util/MultipartData"); const SequentialBucket = require("../util/SequentialBucket"); -const Zlib = require("zlib"); +const Zlib = require("node:zlib"); /** * Handles API requests diff --git a/lib/structures/Base.js b/lib/structures/Base.js index a6271148..07c9541b 100644 --- a/lib/structures/Base.js +++ b/lib/structures/Base.js @@ -1,6 +1,6 @@ "use strict"; -const util = require("util"); +const util = require("node:util"); /** * Provides utilities for working with many Discord structures diff --git a/lib/util/BrowserWebSocket.js b/lib/util/BrowserWebSocket.js index b585a690..76d0d9c9 100644 --- a/lib/util/BrowserWebSocket.js +++ b/lib/util/BrowserWebSocket.js @@ -1,11 +1,11 @@ -const util = require("util"); +const util = require("node:util"); const Base = require("../structures/Base"); let EventEmitter; try { EventEmitter = require("eventemitter3"); } catch(err) { - EventEmitter = require("events").EventEmitter; + EventEmitter = require("node:events").EventEmitter; } class BrowserWebSocketError extends Error { diff --git a/lib/util/Bucket.js b/lib/util/Bucket.js index 525bf10c..ad2c8433 100644 --- a/lib/util/Bucket.js +++ b/lib/util/Bucket.js @@ -1,6 +1,6 @@ "use strict"; -const util = require("util"); +const util = require("node:util"); const Base = require("../structures/Base"); /** diff --git a/lib/util/SequentialBucket.js b/lib/util/SequentialBucket.js index e96e669b..6de05458 100644 --- a/lib/util/SequentialBucket.js +++ b/lib/util/SequentialBucket.js @@ -1,6 +1,6 @@ "use strict"; -const util = require("util"); +const util = require("node:util"); const Base = require("../structures/Base"); /** diff --git a/lib/voice/Piper.js b/lib/voice/Piper.js index 083456dc..916e40b0 100644 --- a/lib/voice/Piper.js +++ b/lib/voice/Piper.js @@ -1,17 +1,17 @@ "use strict"; -const util = require("util"); +const util = require("node:util"); const Base = require("../structures/Base"); const DCAOpusTransformer = require("./streams/DCAOpusTransformer"); const FFmpegOggTransformer = require("./streams/FFmpegOggTransformer"); const FFmpegPCMTransformer = require("./streams/FFmpegPCMTransformer"); -const FS = require("fs"); -const HTTP = require("http"); -const HTTPS = require("https"); +const FS = require("node:fs"); +const HTTP = require("node:http"); +const HTTPS = require("node:https"); const OggOpusTransformer = require("./streams/OggOpusTransformer"); -const PassThroughStream = require("stream").PassThrough; +const PassThroughStream = require("node:stream").PassThrough; const PCMOpusTransformer = require("./streams/PCMOpusTransformer"); -const Stream = require("stream").Stream; +const Stream = require("node:stream").Stream; const VolumeTransformer = require("./streams/VolumeTransformer"); const WebmOpusTransformer = require("./streams/WebmOpusTransformer"); @@ -19,7 +19,7 @@ let EventEmitter; try { EventEmitter = require("eventemitter3"); } catch(err) { - EventEmitter = require("events").EventEmitter; + EventEmitter = require("node:events").EventEmitter; } function resolveHTTPType(link) { diff --git a/lib/voice/SharedStream.js b/lib/voice/SharedStream.js index cef64578..40fca4e9 100644 --- a/lib/voice/SharedStream.js +++ b/lib/voice/SharedStream.js @@ -1,6 +1,6 @@ "use strict"; -const util = require("util"); +const util = require("node:util"); const Base = require("../structures/Base"); const Piper = require("./Piper"); const VoiceConnection = require("./VoiceConnection"); @@ -11,7 +11,7 @@ let EventEmitter; try { EventEmitter = require("eventemitter3"); } catch(err) { - EventEmitter = require("events").EventEmitter; + EventEmitter = require("node:events").EventEmitter; } /** diff --git a/lib/voice/VoiceConnection.js b/lib/voice/VoiceConnection.js index c57feb6f..77fb3af3 100644 --- a/lib/voice/VoiceConnection.js +++ b/lib/voice/VoiceConnection.js @@ -1,11 +1,11 @@ "use strict"; -const util = require("util"); +const util = require("node:util"); const Base = require("../structures/Base"); -const ChildProcess = require("child_process"); +const ChildProcess = require("node:child_process"); const {VoiceOPCodes, GatewayOPCodes} = require("../Constants"); -const Dgram = require("dgram"); -const Net = require("net"); +const Dgram = require("node:dgram"); +const Net = require("node:net"); const Piper = require("./Piper"); const VoiceDataStream = require("./VoiceDataStream"); const {createOpus} = require("../util/Opus"); @@ -16,7 +16,7 @@ let EventEmitter; try { EventEmitter = require("eventemitter3"); } catch(err) { - EventEmitter = require("events").EventEmitter; + EventEmitter = require("node:events").EventEmitter; } let Sodium = null; diff --git a/lib/voice/VoiceDataStream.js b/lib/voice/VoiceDataStream.js index e7743d6d..13f3f4e9 100644 --- a/lib/voice/VoiceDataStream.js +++ b/lib/voice/VoiceDataStream.js @@ -4,7 +4,7 @@ let EventEmitter; try { EventEmitter = require("eventemitter3"); } catch(err) { - EventEmitter = require("events").EventEmitter; + EventEmitter = require("node:events").EventEmitter; } /** diff --git a/lib/voice/streams/BaseTransformer.js b/lib/voice/streams/BaseTransformer.js index 832fc8cb..548434a4 100644 --- a/lib/voice/streams/BaseTransformer.js +++ b/lib/voice/streams/BaseTransformer.js @@ -1,8 +1,8 @@ "use strict"; -const util = require("util"); +const util = require("node:util"); const Base = require("../../structures/Base"); -const TransformStream = require("stream").Transform; +const TransformStream = require("node:stream").Transform; class BaseTransformer extends TransformStream { manualCB = false; diff --git a/lib/voice/streams/FFmpegDuplex.js b/lib/voice/streams/FFmpegDuplex.js index 99e5f150..067c3d3f 100644 --- a/lib/voice/streams/FFmpegDuplex.js +++ b/lib/voice/streams/FFmpegDuplex.js @@ -1,9 +1,9 @@ "use strict"; -const util = require("util"); +const util = require("node:util"); const Base = require("../../structures/Base"); -const ChildProcess = require("child_process"); -const DuplexStream = require("stream").Duplex; -const PassThroughStream = require("stream").PassThrough; +const ChildProcess = require("node:child_process"); +const DuplexStream = require("node:stream").Duplex; +const PassThroughStream = require("node:stream").PassThrough; const delegateEvents = { readable: "_reader", From e6ad5139c3c9c088e0b9f02e90d7069697b1e3ec Mon Sep 17 00:00:00 2001 From: TTtie Date: Mon, 20 Mar 2023 22:53:13 +0000 Subject: [PATCH 10/16] use optional catch binding TODO: find a way to enforce no space after catch with binding, but also not force having no space after catch without binding --- lib/Client.js | 4 ++-- lib/gateway/Shard.js | 8 ++++---- lib/gateway/ShardManager.js | 4 ++-- lib/util/BrowserWebSocket.js | 2 +- lib/util/Opus.js | 4 ++-- lib/voice/Piper.js | 2 +- lib/voice/SharedStream.js | 2 +- lib/voice/VoiceConnection.js | 6 +++--- lib/voice/VoiceDataStream.js | 2 +- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/Client.js b/lib/Client.js index 7b62e8a9..670cce42 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -31,13 +31,13 @@ const AutoModerationRule = require("./structures/AutoModerationRule"); let EventEmitter; try { EventEmitter = require("eventemitter3"); -} catch(err) { +} catch{ EventEmitter = require("node:events"); } let Erlpack; try { Erlpack = require("erlpack"); -} catch(err) { // eslint-disable no-empty +} catch{ // eslint-disable no-empty } const sleep = (ms) => new Promise((res) => setTimeout(res, ms)); diff --git a/lib/gateway/Shard.js b/lib/gateway/Shard.js index 9bf77920..c5acd022 100644 --- a/lib/gateway/Shard.js +++ b/lib/gateway/Shard.js @@ -25,21 +25,21 @@ const WebSocket = typeof window !== "undefined" ? require("../util/BrowserWebSoc let EventEmitter; try { EventEmitter = require("eventemitter3"); -} catch(err) { +} catch{ EventEmitter = require("node:events").EventEmitter; } let Erlpack; try { Erlpack = require("erlpack"); -} catch(err) { // eslint-disable no-empty +} catch{ // eslint-disable no-empty } let ZlibSync; try { ZlibSync = require("zlib-sync"); -} catch(err) { +} catch{ try { ZlibSync = require("pako"); - } catch(err) { // eslint-disable no-empty + } catch{ // eslint-disable no-empty } } diff --git a/lib/gateway/ShardManager.js b/lib/gateway/ShardManager.js index e8f43ef4..f276daf7 100644 --- a/lib/gateway/ShardManager.js +++ b/lib/gateway/ShardManager.js @@ -7,10 +7,10 @@ const Constants = require("../Constants"); let ZlibSync; try { ZlibSync = require("zlib-sync"); -} catch(err) { +} catch{ try { ZlibSync = require("pako"); - } catch(err) { // eslint-disable no-empty + } catch{ // eslint-disable no-empty } } class ShardManager extends Collection { diff --git a/lib/util/BrowserWebSocket.js b/lib/util/BrowserWebSocket.js index 76d0d9c9..d8e94e27 100644 --- a/lib/util/BrowserWebSocket.js +++ b/lib/util/BrowserWebSocket.js @@ -4,7 +4,7 @@ const Base = require("../structures/Base"); let EventEmitter; try { EventEmitter = require("eventemitter3"); -} catch(err) { +} catch{ EventEmitter = require("node:events").EventEmitter; } diff --git a/lib/util/Opus.js b/lib/util/Opus.js index 3a94a75e..f9b40431 100644 --- a/lib/util/Opus.js +++ b/lib/util/Opus.js @@ -7,10 +7,10 @@ module.exports.createOpus = function createOpus(samplingRate, channels, bitrate) if(!NativeOpus && !OpusScript) { try { NativeOpus = require("@discordjs/opus"); - } catch(err) { + } catch{ try { OpusScript = require("opusscript"); - } catch(err) { // eslint-disable no-empty + } catch{ // eslint-disable no-empty } } } diff --git a/lib/voice/Piper.js b/lib/voice/Piper.js index 916e40b0..50efa14a 100644 --- a/lib/voice/Piper.js +++ b/lib/voice/Piper.js @@ -18,7 +18,7 @@ const WebmOpusTransformer = require("./streams/WebmOpusTransformer"); let EventEmitter; try { EventEmitter = require("eventemitter3"); -} catch(err) { +} catch{ EventEmitter = require("node:events").EventEmitter; } diff --git a/lib/voice/SharedStream.js b/lib/voice/SharedStream.js index 40fca4e9..43afcf3d 100644 --- a/lib/voice/SharedStream.js +++ b/lib/voice/SharedStream.js @@ -10,7 +10,7 @@ const {createOpus} = require("../util/Opus"); let EventEmitter; try { EventEmitter = require("eventemitter3"); -} catch(err) { +} catch{ EventEmitter = require("node:events").EventEmitter; } diff --git a/lib/voice/VoiceConnection.js b/lib/voice/VoiceConnection.js index 77fb3af3..87de658f 100644 --- a/lib/voice/VoiceConnection.js +++ b/lib/voice/VoiceConnection.js @@ -15,7 +15,7 @@ const WebSocket = typeof window !== "undefined" ? require("../util/BrowserWebSoc let EventEmitter; try { EventEmitter = require("eventemitter3"); -} catch(err) { +} catch{ EventEmitter = require("node:events").EventEmitter; } @@ -111,10 +111,10 @@ class VoiceConnection extends EventEmitter { if(!Sodium && !NaCl) { try { Sodium = require("sodium-native"); - } catch(err) { + } catch{ try { NaCl = require("tweetnacl"); - } catch(err) { // eslint-disable no-empty + } catch{ // eslint-disable no-empty throw new Error("Error loading tweetnacl/libsodium, voice not available"); } } diff --git a/lib/voice/VoiceDataStream.js b/lib/voice/VoiceDataStream.js index 13f3f4e9..18597f51 100644 --- a/lib/voice/VoiceDataStream.js +++ b/lib/voice/VoiceDataStream.js @@ -3,7 +3,7 @@ let EventEmitter; try { EventEmitter = require("eventemitter3"); -} catch(err) { +} catch{ EventEmitter = require("node:events").EventEmitter; } From 63ad82469578c782c3dc61f77015cb47b22a05d4 Mon Sep 17 00:00:00 2001 From: TTtie Date: Wed, 22 Mar 2023 19:15:19 +0000 Subject: [PATCH 11/16] convert _properties to ES private properties where possible --- .eslintrc.yml | 4 + lib/gateway/Shard.js | 61 ++++---- lib/gateway/ShardManager.js | 35 ++--- lib/rest/RequestHandler.js | 21 +-- lib/structures/ApplicationCommand.js | 7 +- lib/structures/AutoModerationRule.js | 7 +- lib/structures/AutocompleteInteraction.js | 10 +- lib/structures/CommandInteraction.js | 38 ++--- lib/structures/ComponentInteraction.js | 46 +++--- lib/structures/Guild.js | 173 +++++++++++----------- lib/structures/GuildChannel.js | 12 +- lib/structures/GuildPreview.js | 15 +- lib/structures/GuildScheduledEvent.js | 13 +- lib/structures/GuildTemplate.js | 11 +- lib/structures/Interaction.js | 11 +- lib/structures/Invite.js | 12 +- lib/structures/Message.js | 58 ++++---- lib/structures/ModalSubmitInteraction.js | 36 ++--- lib/structures/Permission.js | 11 +- lib/structures/PingInteraction.js | 7 +- lib/structures/StageInstance.js | 7 +- lib/structures/ThreadMember.js | 7 +- lib/structures/User.js | 38 ++--- lib/util/BrowserWebSocket.js | 21 +-- lib/util/Bucket.js | 14 +- lib/util/SequentialBucket.js | 12 +- lib/voice/Piper.js | 53 +++---- lib/voice/SharedStream.js | 21 +-- lib/voice/VoiceConnection.js | 17 ++- lib/voice/streams/BaseTransformer.js | 9 +- lib/voice/streams/DCAOpusTransformer.js | 16 +- lib/voice/streams/FFmpegDuplex.js | 57 +++---- lib/voice/streams/OggOpusTransformer.js | 18 +-- lib/voice/streams/PCMOpusTransformer.js | 20 +-- lib/voice/streams/VolumeTransformer.js | 10 +- lib/voice/streams/WebmOpusTransformer.js | 43 +++--- 36 files changed, 500 insertions(+), 451 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index b379faef..d6960da3 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -69,6 +69,7 @@ rules: - "[alphabetical-methods]" - "[alphabetical-conventional-private-methods]" - "[everything-else]" + - "[alphabetical-private-methods]" - "[custom-inspect-method]" - toString - toJSON @@ -86,6 +87,9 @@ rules: - name: "/_.+/" type: method sort: alphabetical + alphabetical-private-methods: + - type: method + sort: alphabetical custom-inspect-method: - name: "[util.inspect.custom]" type: method diff --git a/lib/gateway/Shard.js b/lib/gateway/Shard.js index c5acd022..3d7500e6 100644 --- a/lib/gateway/Shard.js +++ b/lib/gateway/Shard.js @@ -56,6 +56,12 @@ try { * @prop {String} status The status of the shard. "disconnected"/"connecting"/"handshaking"/"ready"/"identifying"/"resuming" */ class Shard extends EventEmitter { + #onWSClose; + #onWSError; + #onWSMessage; + #onWSOpen; + #token; + #zlibSync; constructor(id, client) { super(); @@ -63,10 +69,10 @@ class Shard extends EventEmitter { this.client = client; this.onPacket = this.onPacket.bind(this); - this._onWSOpen = this._onWSOpen.bind(this); - this._onWSMessage = this._onWSMessage.bind(this); - this._onWSError = this._onWSError.bind(this); - this._onWSClose = this._onWSClose.bind(this); + this.#onWSOpen = this.#onWSOpenUnbound.bind(this); + this.#onWSMessage = this.#onWSMessageUnbound.bind(this); + this.#onWSError = this.#onWSErrorUnbound.bind(this); + this.#onWSClose = this.#onWSCloseUnbound.bind(this); this.hardReset(); } @@ -126,8 +132,8 @@ class Shard extends EventEmitter { } if(this.ws.readyState !== WebSocket.CLOSED) { - this.ws.removeListener("message", this._onWSMessage); - this.ws.removeListener("close", this._onWSClose); + this.ws.removeListener("message", this.#onWSMessage); + this.ws.removeListener("close", this.#onWSClose); try { if(options.reconnect && this.sessionID) { if(this.ws.readyState === WebSocket.OPEN) { @@ -246,12 +252,7 @@ class Shard extends EventEmitter { this.globalBucket = new Bucket(120, 60000, {reservedTokens: 5}); this.presenceUpdateBucket = new Bucket(5, 20000); this.presence = JSON.parse(JSON.stringify(this.client.presence)); // Fast copy - Object.defineProperty(this, "_token", { - configurable: true, - enumerable: false, - writable: true, - value: this.client._token - }); + this.#token = this.client._token; } heartbeat(normal) { @@ -291,7 +292,7 @@ class Shard extends EventEmitter { } this.status = "identifying"; const identify = { - token: this._token, + token: this.#token, v: GATEWAY_VERSION, compress: !!this.client.shards.options.compress, large_threshold: this.client.shards.options.largeThreshold, @@ -312,14 +313,14 @@ class Shard extends EventEmitter { } initializeWS() { - if(!this._token) { + if(!this.#token) { return this.disconnect(null, new Error("Token not specified")); } this.status = "connecting"; if(this.client.shards.options.compress) { this.emit("debug", "Initializing zlib-sync-based compression"); - this._zlibSync = new ZlibSync.Inflate({ + this.#zlibSync = new ZlibSync.Inflate({ chunkSize: 128 * 1024 }); } @@ -331,10 +332,10 @@ class Shard extends EventEmitter { } else { this.ws = new WebSocket(this.client.gatewayURL, this.client.options.ws); } - this.ws.on("open", this._onWSOpen); - this.ws.on("message", this._onWSMessage); - this.ws.on("error", this._onWSError); - this.ws.on("close", this._onWSClose); + this.ws.on("open", this.#onWSOpen); + this.ws.on("message", this.#onWSMessage); + this.ws.on("error", this.#onWSError); + this.ws.on("close", this.#onWSClose); this.connectTimeout = setTimeout(() => { if(this.connecting) { @@ -516,7 +517,7 @@ class Shard extends EventEmitter { resume() { this.status = "resuming"; this.sendWS(GatewayOPCodes.RESUME, { - token: this._token, + token: this.#token, session_id: this.sessionID, seq: this.seq }); @@ -2258,7 +2259,7 @@ class Shard extends EventEmitter { } /* eslint-enable no-redeclare */ } - _onWSClose(code, reason) { + #onWSCloseUnbound(code, reason) { reason = reason.toString(); this.emit("debug", "WS disconnected: " + JSON.stringify({ code: code, @@ -2282,7 +2283,7 @@ class Shard extends EventEmitter { this.sessionID = null; this.resumeURL = null; reconnect = false; - this.emit("error", new Error(`Invalid token: ${this._token}`)); + this.emit("error", new Error(`Invalid token: ${this.#token}`)); } else if(code === 4005) { err = new Error("Already authenticated"); } else if(code === 4006 || code === 4009) { @@ -2330,11 +2331,11 @@ class Shard extends EventEmitter { }, err); } - _onWSError(err) { + #onWSErrorUnbound(err) { this.emit("error", err, this.id); } - _onWSMessage(data) { + #onWSMessageUnbound(data) { try { if(data instanceof ArrayBuffer) { if(this.client.shards.options.compress || Erlpack) { @@ -2345,13 +2346,13 @@ class Shard extends EventEmitter { } if(this.client.shards.options.compress) { if(data.length >= 4 && data.readUInt32BE(data.length - 4) === 0xFFFF) { - this._zlibSync.push(data, ZlibSync.Z_SYNC_FLUSH); - if(this._zlibSync.err) { - this.emit("error", new Error(`zlib error ${this._zlibSync.err}: ${this._zlibSync.msg}`)); + this.#zlibSync.push(data, ZlibSync.Z_SYNC_FLUSH); + if(this.#zlibSync.err) { + this.emit("error", new Error(`zlib error ${this.#zlibSync.err}: ${this.#zlibSync.msg}`)); return; } - data = Buffer.from(this._zlibSync.result); + data = Buffer.from(this.#zlibSync.result); try { if(Erlpack) { @@ -2366,7 +2367,7 @@ class Shard extends EventEmitter { return this.onPacket(data); } else { - this._zlibSync.push(data, false); + this.#zlibSync.push(data, false); } } else if(Erlpack) { return this.onPacket(Erlpack.unpack(data)); @@ -2378,7 +2379,7 @@ class Shard extends EventEmitter { } } - _onWSOpen() { + #onWSOpenUnbound() { this.status = "handshaking"; /** * Fired when the shard establishes a connection diff --git a/lib/gateway/ShardManager.js b/lib/gateway/ShardManager.js index f276daf7..c7b28dca 100644 --- a/lib/gateway/ShardManager.js +++ b/lib/gateway/ShardManager.js @@ -14,13 +14,14 @@ try { } } class ShardManager extends Collection { + #client; buckets = new Map(); connectQueue = []; connectTimeout = null; constructor(client, options = {}) { super(Shard); - this._client = client; + this.#client = client; this.options = Object.assign({ autoreconnect: true, compress: false, @@ -50,7 +51,7 @@ class ShardManager extends Collection { } else if(typeof intent === "number") { bitmask |= intent; } else { - this._client.emit("warn", `Unknown intent: ${intent}`); + this.#client.emit("warn", `Unknown intent: ${intent}`); } } this.options.intents = bitmask; @@ -79,15 +80,15 @@ class ShardManager extends Collection { spawn(id) { let shard = this.get(id); if(!shard) { - shard = this.add(new Shard(id, this._client)); + shard = this.add(new Shard(id, this.#client)); shard.on("ready", () => { /** * Fired when a shard turns ready * @event Client#shardReady * @prop {Number} id The ID of the shard */ - this._client.emit("shardReady", shard.id); - if(this._client.ready) { + this.#client.emit("shardReady", shard.id); + if(this.#client.ready) { return; } for(const other of this.values()) { @@ -95,21 +96,21 @@ class ShardManager extends Collection { return; } } - this._client.ready = true; - this._client.startTime = Date.now(); + this.#client.ready = true; + this.#client.startTime = Date.now(); /** * Fired when all shards turn ready * @event Client#ready */ - this._client.emit("ready"); + this.#client.emit("ready"); }).on("resume", () => { /** * Fired when a shard resumes * @event Client#shardResume * @prop {Number} id The ID of the shard */ - this._client.emit("shardResume", shard.id); - if(this._client.ready) { + this.#client.emit("shardResume", shard.id); + if(this.#client.ready) { return; } for(const other of this.values()) { @@ -117,9 +118,9 @@ class ShardManager extends Collection { return; } } - this._client.ready = true; - this._client.startTime = Date.now(); - this._client.emit("ready"); + this.#client.ready = true; + this.#client.startTime = Date.now(); + this.#client.emit("ready"); }).on("disconnect", (error) => { /** * Fired when a shard disconnects @@ -127,19 +128,19 @@ class ShardManager extends Collection { * @prop {Error?} error The error, if any * @prop {Number} id The ID of the shard */ - this._client.emit("shardDisconnect", error, shard.id); + this.#client.emit("shardDisconnect", error, shard.id); for(const other of this.values()) { if(other.ready) { return; } } - this._client.ready = false; - this._client.startTime = 0; + this.#client.ready = false; + this.#client.startTime = 0; /** * Fired when all shards disconnect * @event Client#disconnect */ - this._client.emit("disconnect"); + this.#client.emit("disconnect"); }); } if(shard.status === "disconnected") { diff --git a/lib/rest/RequestHandler.js b/lib/rest/RequestHandler.js index 8c6036d8..ae549b8e 100644 --- a/lib/rest/RequestHandler.js +++ b/lib/rest/RequestHandler.js @@ -15,6 +15,7 @@ const Zlib = require("node:zlib"); * Handles API requests */ class RequestHandler { + #client; globalBlock = false; ratelimits = {}; readyQueue = []; @@ -31,7 +32,7 @@ class RequestHandler { requestTimeout: 15000 }, options); - this._client = client; + this.#client = client; this.latencyRef = { latency: this.options.ratelimiterOffset, raw: new Array(10).fill(this.options.ratelimiterOffset), @@ -41,7 +42,7 @@ class RequestHandler { }; if(this.options.forceQueueing) { this.globalBlock = true; - this._client.once("shardPreReady", () => this.globalUnblock()); + this.#client.once("shardPreReady", () => this.globalUnblock()); } } @@ -83,7 +84,7 @@ class RequestHandler { try { if(auth) { - headers.Authorization = this._client._token; + headers.Authorization = this.#client._token; } if(body?.reason) { // Audit log reason sniping headers["X-Audit-Log-Reason"] = encodeURIComponent(body.reason); @@ -183,7 +184,7 @@ class RequestHandler { this.latencyRef.latency = this.latencyRef.latency - ~~(this.latencyRef.raw.shift() / 10) + ~~(latency / 10); } - if(this._client.listeners("rawREST").length) { + if(this.#client.listeners("rawREST").length) { /** * Fired when the Client's RequestHandler receives a response * @event Client#rawREST @@ -200,14 +201,14 @@ class RequestHandler { * @prop {Boolean} request.short Whether or not the request was prioritized in its ratelimiting queue * @prop {String} request.url URL of the endpoint */ - this._client.emit("rawREST", {method, url, auth, body, file, route, short, resp, latency}); + this.#client.emit("rawREST", {method, url, auth, body, file, route, short, resp, latency}); } const headerNow = Date.parse(resp.headers["date"]); if(this.latencyRef.lastTimeOffsetCheck < Date.now() - 5000) { const timeOffset = headerNow + 500 - (this.latencyRef.lastTimeOffsetCheck = Date.now()); if(this.latencyRef.timeOffset - this.latencyRef.latency >= this.options.latencyThreshold && timeOffset - this.latencyRef.latency >= this.options.latencyThreshold) { - this._client.emit("warn", new Error(`Your clock is ${this.latencyRef.timeOffset}ms behind Discord's server clock. Please check your connection and system time.`)); + this.#client.emit("warn", new Error(`Your clock is ${this.latencyRef.timeOffset}ms behind Discord's server clock. Please check your connection and system time.`)); } this.latencyRef.timeOffset = this.latencyRef.timeOffset - ~~(this.latencyRef.timeOffsets.shift() / 10) + ~~(timeOffset / 10); this.latencyRef.timeOffsets.push(timeOffset); @@ -244,7 +245,7 @@ class RequestHandler { } if(method !== "GET" && (resp.headers["x-ratelimit-remaining"] == undefined || resp.headers["x-ratelimit-limit"] == undefined) && this.ratelimits[route].limit !== 1) { - this._client.emit("debug", `Missing ratelimit headers for SequentialBucket(${this.ratelimits[route].remaining}/${this.ratelimits[route].limit}) with non-default limit\n` + this.#client.emit("debug", `Missing ratelimit headers for SequentialBucket(${this.ratelimits[route].remaining}/${this.ratelimits[route].limit}) with non-default limit\n` + `${resp.statusCode} ${resp.headers["content-type"]}: ${method} ${route} | ${resp.headers["cf-ray"]}\n` + "content-type = " + + "\n" + "x-ratelimit-remaining = " + resp.headers["x-ratelimit-remaining"] + "\n" @@ -275,7 +276,7 @@ class RequestHandler { if(resp.statusCode !== 429) { const content = typeof body === "object" ? `${body.content} ` : ""; - this._client.emit("debug", `${content}${now} ${route} ${resp.statusCode}: ${latency}ms (${this.latencyRef.latency}ms avg) | ${this.ratelimits[route].remaining}/${this.ratelimits[route].limit} left | Reset ${this.ratelimits[route].reset} (${this.ratelimits[route].reset - now}ms left)`); + this.#client.emit("debug", `${content}${now} ${route} ${resp.statusCode}: ${latency}ms (${this.latencyRef.latency}ms avg) | ${this.ratelimits[route].remaining}/${this.ratelimits[route].limit} left | Reset ${this.ratelimits[route].reset} (${this.ratelimits[route].reset - now}ms left)`); } if(resp.statusCode >= 300) { @@ -290,7 +291,7 @@ class RequestHandler { return; } } - this._client.emit("debug", `${resp.headers["x-ratelimit-global"] ? "Global" : "Unexpected"} 429 (╯°□°)╯︵ ┻━┻: ${response}\n${content} ${now} ${route} ${resp.statusCode}: ${latency}ms (${this.latencyRef.latency}ms avg) | ${this.ratelimits[route].remaining}/${this.ratelimits[route].limit} left | Reset ${delay} (${this.ratelimits[route].reset - now}ms left) | Scope ${resp.headers["x-ratelimit-scope"]}`); + this.#client.emit("debug", `${resp.headers["x-ratelimit-global"] ? "Global" : "Unexpected"} 429 (╯°□°)╯︵ ┻━┻: ${response}\n${content} ${now} ${route} ${resp.statusCode}: ${latency}ms (${this.latencyRef.latency}ms avg) | ${this.ratelimits[route].remaining}/${this.ratelimits[route].limit} left | Reset ${delay} (${this.ratelimits[route].reset - now}ms left) | Scope ${resp.headers["x-ratelimit-scope"]}`); if(delay) { setTimeout(() => { cb(); @@ -303,7 +304,7 @@ class RequestHandler { return; } } else if(resp.statusCode === 502 && ++attempts < 4) { - this._client.emit("debug", "A wild 502 appeared! Thanks CloudFlare!"); + this.#client.emit("debug", "A wild 502 appeared! Thanks CloudFlare!"); setTimeout(() => { this.request(method, url, auth, body, file, route, true).then(resolve).catch(reject); }, Math.floor(Math.random() * 1900 + 100)); diff --git a/lib/structures/ApplicationCommand.js b/lib/structures/ApplicationCommand.js index 20ef540e..ac601482 100644 --- a/lib/structures/ApplicationCommand.js +++ b/lib/structures/ApplicationCommand.js @@ -17,9 +17,10 @@ const Base = require("./Base"); * @prop {String} version The id of the version of this command */ class ApplicationCommand extends Base { + #client; constructor(data, client) { super(data.id); - this._client = client; + this.#client = client; this.applicationID = data.application_id; this.name = data.name; this.description = data.description; @@ -60,7 +61,7 @@ class ApplicationCommand extends Base { * @returns {Promise} */ delete() { - return this.guildID === undefined ? this._client.deleteCommand.call(this._client, this.id) : this._client.deleteGuildCommand.call(this._client, this.guildID, this.id); + return this.guildID === undefined ? this.#client.deleteCommand.call(this.#client, this.id) : this.#client.deleteGuildCommand.call(this.#client, this.guildID, this.id); } /** @@ -76,7 +77,7 @@ class ApplicationCommand extends Base { * @returns {Promise} */ edit(options) { - return this.guildID === undefined ? this._client.editCommand.call(this._client, this.id, options) : this._client.editGuildCommand.call(this._client, this.id, this.guildID, options); + return this.guildID === undefined ? this.#client.editCommand.call(this.#client, this.id, options) : this.#client.editGuildCommand.call(this.#client, this.id, this.guildID, options); } toJSON(props = []) { diff --git a/lib/structures/AutoModerationRule.js b/lib/structures/AutoModerationRule.js index c15496bd..a616e055 100644 --- a/lib/structures/AutoModerationRule.js +++ b/lib/structures/AutoModerationRule.js @@ -17,9 +17,10 @@ const Base = require("./Base"); * @prop {Number} triggerType The rule [trigger type](https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-rule-object-trigger-types) */ class AutoModerationRule extends Base { + #client; constructor(data, client) { super(data.id); - this._client = client; + this.#client = client; this.actions = data.actions.map((action) => ({ type: action.type, @@ -42,7 +43,7 @@ class AutoModerationRule extends Base { * @returns {Promise} */ delete() { - return this._client.deleteAutoModerationRule.call(this._client, this.guildID, this.id); + return this.#client.deleteAutoModerationRule.call(this.#client, this.guildID, this.id); } /** @@ -59,7 +60,7 @@ class AutoModerationRule extends Base { * @returns {Promise} */ edit(options) { - return this._client.editAutoModerationRule.call(this._client, this.guildID, this.id, options); + return this.#client.editAutoModerationRule.call(this.#client, this.guildID, this.id, options); } } diff --git a/lib/structures/AutocompleteInteraction.js b/lib/structures/AutocompleteInteraction.js index 40f2ed8e..19319176 100644 --- a/lib/structures/AutocompleteInteraction.js +++ b/lib/structures/AutocompleteInteraction.js @@ -22,10 +22,12 @@ const {InteractionResponseTypes} = require("../Constants"); * @prop {Array?} data.options[].options Sub-options (Mutually exclusive with value, subcommand/subcommandgroup) */ class AutocompleteInteraction extends Interaction { + #client; constructor(data, client) { super(data, client); + this.#client = client; - this.channel = this._client.getChannel(data.channel_id) || { + this.channel = this.#client.getChannel(data.channel_id) || { id: data.channel_id }; @@ -40,13 +42,13 @@ class AutocompleteInteraction extends Interaction { data.member.id = data.member.user.id; this.member = this.channel.guild.members.update(data.member, this.channel.guild); } else { - const guild = this._client.guilds.get(data.guild_id); + const guild = this.#client.guilds.get(data.guild_id); this.member = guild.members.update(data.member, guild); } } if(data.user !== undefined) { - this.user = this._client.users.update(data.user, client); + this.user = this.#client.users.update(data.user, client); } if(data.app_permissions !== undefined) { @@ -78,7 +80,7 @@ class AutocompleteInteraction extends Interaction { if(this.acknowledged === true) { throw new Error("You have already acknowledged this interaction."); } - return this._client.createInteractionResponse.call(this._client, this.id, this.token, { + return this.#client.createInteractionResponse.call(this.#client, this.id, this.token, { type: InteractionResponseTypes.APPLICATION_COMMAND_AUTOCOMPLETE_RESULT, data: {choices} }).then(() => this.update()); diff --git a/lib/structures/CommandInteraction.js b/lib/structures/CommandInteraction.js index c6f7cb3d..58df5d68 100644 --- a/lib/structures/CommandInteraction.js +++ b/lib/structures/CommandInteraction.js @@ -35,10 +35,12 @@ const {InteractionResponseTypes} = require("../Constants"); * @prop {Collection?} data.resolved.users resolved users */ class CommandInteraction extends Interaction { + #client; constructor(data, client) { super(data, client); + this.#client = client; - this.channel = this._client.getChannel(data.channel_id) || { + this.channel = this.#client.getChannel(data.channel_id) || { id: data.channel_id }; @@ -49,7 +51,7 @@ class CommandInteraction extends Interaction { if(data.data.resolved.users !== undefined) { const usermap = new Collection(User); Object.entries(data.data.resolved.users).forEach(([id, user]) => { - usermap.set(id, this._client.users.update(user, client)); + usermap.set(id, this.#client.users.update(user, client)); }); this.data.resolved.users = usermap; } @@ -62,7 +64,7 @@ class CommandInteraction extends Interaction { if(this.channel.guild) { membermap.set(id, this.channel.guild.members.update(member, this.channel.guild)); } else { - const guild = this._client.guilds.get(data.guild_id); + const guild = this.#client.guilds.get(data.guild_id); membermap.set(id, guild.members.update(member, guild)); } }); @@ -80,7 +82,7 @@ class CommandInteraction extends Interaction { if(data.data.resolved.channels !== undefined) { const channelmap = new Collection(Channel); Object.entries(data.data.resolved.channels).forEach(([id, channel]) => { - channelmap.set(id, Channel.from(channel, this._client) || new Channel(channel, this._client)); + channelmap.set(id, Channel.from(channel, this.#client) || new Channel(channel, this.#client)); }); this.data.resolved.channels = channelmap; } @@ -88,7 +90,7 @@ class CommandInteraction extends Interaction { if(data.data.resolved.messages !== undefined) { const messagemap = new Collection(Message); Object.entries(data.data.resolved.messages).forEach(([id, message]) => { - messagemap.set(id, new Message(message, this._client)); + messagemap.set(id, new Message(message, this.#client)); }); this.data.resolved.messages = messagemap; } @@ -111,13 +113,13 @@ class CommandInteraction extends Interaction { data.member.id = data.member.user.id; this.member = this.channel.guild.members.update(data.member, this.channel.guild); } else { - const guild = this._client.guilds.get(data.guild_id); + const guild = this.#client.guilds.get(data.guild_id); this.member = guild.members.update(data.member, guild); } } if(data.user !== undefined) { - this.user = this._client.users.update(data.user, client); + this.user = this.#client.users.update(data.user, client); } if(data.app_permissions !== undefined) { @@ -166,7 +168,7 @@ class CommandInteraction extends Interaction { content.content = "" + content.content; } } - return this._client.executeWebhook.call(this._client, this.applicationID, this.token, Object.assign({wait: true}, content)); + return this.#client.executeWebhook.call(this.#client, this.applicationID, this.token, Object.assign({wait: true}, content)); } /** @@ -200,14 +202,14 @@ class CommandInteraction extends Interaction { content.content = "" + content.content; } if(content.content !== undefined || content.embeds || content.allowedMentions) { - content.allowed_mentions = this._client._formatAllowedMentions(content.allowedMentions); + content.allowed_mentions = this.#client._formatAllowedMentions(content.allowedMentions); } } - const {files, attachments} = this._client._processAttachments(content.attachments); + const {files, attachments} = this.#client._processAttachments(content.attachments); content.attachments = attachments; - return this._client.createInteractionResponse.call(this._client, this.id, this.token, { + return this.#client.createInteractionResponse.call(this.#client, this.id, this.token, { type: InteractionResponseTypes.CHANNEL_MESSAGE_WITH_SOURCE, data: content }, files).then(() => this.update()); @@ -222,7 +224,7 @@ class CommandInteraction extends Interaction { * @returns {Promise} */ async createModal(content) { - return this._client.createInteractionResponse.call(this._client, this.id, this.token, { + return this.#client.createInteractionResponse.call(this.#client, this.id, this.token, { type: InteractionResponseTypes.MODAL, data: content }).then(() => this.update()); @@ -238,7 +240,7 @@ class CommandInteraction extends Interaction { if(this.acknowledged === true) { throw new Error("You have already acknowledged this interaction."); } - return this._client.createInteractionResponse.call(this._client, this.id, this.token, { + return this.#client.createInteractionResponse.call(this.#client, this.id, this.token, { type: InteractionResponseTypes.DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE, data: { flags: flags || 0 @@ -255,7 +257,7 @@ class CommandInteraction extends Interaction { if(this.acknowledged === false) { throw new Error("deleteMessage cannot be used to acknowledge an interaction, please use acknowledge, createMessage, or defer first."); } - return this._client.deleteWebhookMessage.call(this._client, this.applicationID, this.token, messageID); + return this.#client.deleteWebhookMessage.call(this.#client, this.applicationID, this.token, messageID); } /** @@ -267,7 +269,7 @@ class CommandInteraction extends Interaction { if(this.acknowledged === false) { throw new Error("deleteOriginalMessage cannot be used to acknowledge an interaction, please use acknowledge, createMessage, or defer first."); } - return this._client.deleteWebhookMessage.call(this._client, this.applicationID, this.token, "@original"); + return this.#client.deleteWebhookMessage.call(this.#client, this.applicationID, this.token, "@original"); } /** @@ -302,7 +304,7 @@ class CommandInteraction extends Interaction { content.content = "" + content.content; } } - return this._client.editWebhookMessage.call(this._client, this.applicationID, this.token, messageID, content); + return this.#client.editWebhookMessage.call(this.#client, this.applicationID, this.token, messageID, content); } /** @@ -336,7 +338,7 @@ class CommandInteraction extends Interaction { content.content = "" + content.content; } } - return this._client.editWebhookMessage.call(this._client, this.applicationID, this.token, "@original", content); + return this.#client.editWebhookMessage.call(this.#client, this.applicationID, this.token, "@original", content); } /** @@ -348,7 +350,7 @@ class CommandInteraction extends Interaction { if(this.acknowledged === false) { throw new Error("getOriginalMessage cannot be used to acknowledge an interaction, please use acknowledge, createMessage, or defer first."); } - return this._client.getWebhookMessage.call(this._client, this.applicationID, this.token, "@original"); + return this.#client.getWebhookMessage.call(this.#client, this.applicationID, this.token, "@original"); } } diff --git a/lib/structures/ComponentInteraction.js b/lib/structures/ComponentInteraction.js index 3ff4b33f..bc6c2101 100644 --- a/lib/structures/ComponentInteraction.js +++ b/lib/structures/ComponentInteraction.js @@ -31,10 +31,12 @@ const {InteractionResponseTypes} = require("../Constants"); * @prop {User?} user The user who triggered the interaction (This is only sent when the interaction is invoked within a dm) */ class ComponentInteraction extends Interaction { + #client; constructor(data, client) { super(data, client); + this.#client = client; - this.channel = this._client.getChannel(data.channel_id) || { + this.channel = this.#client.getChannel(data.channel_id) || { id: data.channel_id }; @@ -45,7 +47,7 @@ class ComponentInteraction extends Interaction { if(data.data.resolved.users !== undefined) { const usermap = new Collection(User); Object.entries(data.data.resolved.users).forEach(([id, user]) => { - usermap.set(id, this._client.users.update(user, client)); + usermap.set(id, this.#client.users.update(user, client)); }); this.data.resolved.users = usermap; } @@ -58,7 +60,7 @@ class ComponentInteraction extends Interaction { if(this.channel.guild) { membermap.set(id, this.channel.guild.members.update(member, this.channel.guild)); } else { - const guild = this._client.guilds.get(data.guild_id); + const guild = this.#client.guilds.get(data.guild_id); membermap.set(id, guild.members.update(member, guild)); } }); @@ -76,7 +78,7 @@ class ComponentInteraction extends Interaction { if(data.data.resolved.channels !== undefined) { const channelmap = new Collection(Channel); Object.entries(data.data.resolved.channels).forEach(([id, channel]) => { - channelmap.set(id, Channel.from(channel, this._client) || new Channel(channel, this._client)); + channelmap.set(id, Channel.from(channel, this.#client) || new Channel(channel, this.#client)); }); this.data.resolved.channels = channelmap; } @@ -91,17 +93,17 @@ class ComponentInteraction extends Interaction { data.member.id = data.member.user.id; this.member = this.channel.guild.members.update(data.member, this.channel.guild); } else { - const guild = this._client.guilds.get(data.guild_id); + const guild = this.#client.guilds.get(data.guild_id); this.member = guild.members.update(data.member, guild); } } if(data.message !== undefined) { - this.message = new Message(data.message, this._client); + this.message = new Message(data.message, this.#client); } if(data.user !== undefined) { - this.user = this._client.users.update(data.user, client); + this.user = this.#client.users.update(data.user, client); } if(data.app_permissions !== undefined) { @@ -148,7 +150,7 @@ class ComponentInteraction extends Interaction { content.content = "" + content.content; } } - return this._client.executeWebhook.call(this._client, this.applicationID, this.token, Object.assign({wait: true}, content)); + return this.#client.executeWebhook.call(this.#client, this.applicationID, this.token, Object.assign({wait: true}, content)); } /** @@ -182,14 +184,14 @@ class ComponentInteraction extends Interaction { content.content = "" + content.content; } if(content.content !== undefined || content.embeds || content.allowedMentions) { - content.allowed_mentions = this._client._formatAllowedMentions(content.allowedMentions); + content.allowed_mentions = this.#client._formatAllowedMentions(content.allowedMentions); } } - const {files, attachments} = this._client._processAttachments(content.attachments); + const {files, attachments} = this.#client._processAttachments(content.attachments); content.attachments = attachments; - return this._client.createInteractionResponse.call(this._client, this.id, this.token, { + return this.#client.createInteractionResponse.call(this.#client, this.id, this.token, { type: InteractionResponseTypes.CHANNEL_MESSAGE_WITH_SOURCE, data: content }, files).then(() => this.update()); @@ -204,7 +206,7 @@ class ComponentInteraction extends Interaction { * @returns {Promise} */ async createModal(content) { - return this._client.createInteractionResponse.call(this._client, this.id, this.token, { + return this.#client.createInteractionResponse.call(this.#client, this.id, this.token, { type: InteractionResponseTypes.MODAL, data: content }).then(() => this.update()); @@ -220,7 +222,7 @@ class ComponentInteraction extends Interaction { if(this.acknowledged === true) { throw new Error("You have already acknowledged this interaction."); } - return this._client.createInteractionResponse.call(this._client, this.id, this.token, { + return this.#client.createInteractionResponse.call(this.#client, this.id, this.token, { type: InteractionResponseTypes.DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE, data: { flags: flags || 0 @@ -237,7 +239,7 @@ class ComponentInteraction extends Interaction { if(this.acknowledged === true) { throw new Error("You have already acknowledged this interaction."); } - return this._client.createInteractionResponse.call(this._client, this.id, this.token, { + return this.#client.createInteractionResponse.call(this.#client, this.id, this.token, { type: InteractionResponseTypes.DEFERRED_UPDATE_MESSAGE }).then(() => this.update()); } @@ -251,7 +253,7 @@ class ComponentInteraction extends Interaction { if(this.acknowledged === false) { throw new Error("deleteMessage cannot be used to acknowledge an interaction, please use acknowledge, createMessage, defer, deferUpdate, or editParent first."); } - return this._client.deleteWebhookMessage.call(this._client, this.applicationID, this.token, messageID); + return this.#client.deleteWebhookMessage.call(this.#client, this.applicationID, this.token, messageID); } /** @@ -263,7 +265,7 @@ class ComponentInteraction extends Interaction { if(this.acknowledged === false) { throw new Error("deleteOriginalMessage cannot be used to acknowledge an interaction, please use acknowledge, createMessage, defer, deferUpdate, or editParent first."); } - return this._client.deleteWebhookMessage.call(this._client, this.applicationID, this.token, "@original"); + return this.#client.deleteWebhookMessage.call(this.#client, this.applicationID, this.token, "@original"); } /** @@ -298,7 +300,7 @@ class ComponentInteraction extends Interaction { content.content = "" + content.content; } } - return this._client.editWebhookMessage.call(this._client, this.applicationID, this.token, messageID, content); + return this.#client.editWebhookMessage.call(this.#client, this.applicationID, this.token, messageID, content); } /** @@ -332,7 +334,7 @@ class ComponentInteraction extends Interaction { content.content = "" + content.content; } } - return this._client.editWebhookMessage.call(this._client, this.applicationID, this.token, "@original", content); + return this.#client.editWebhookMessage.call(this.#client, this.applicationID, this.token, "@original", content); } /** @@ -370,14 +372,14 @@ class ComponentInteraction extends Interaction { content.content = "" + content.content; } if(content.content !== undefined || content.embeds || content.allowedMentions) { - content.allowed_mentions = this._client._formatAllowedMentions(content.allowedMentions); + content.allowed_mentions = this.#client._formatAllowedMentions(content.allowedMentions); } } - const {files, attachments} = this._client._processAttachments(content.attachments); + const {files, attachments} = this.#client._processAttachments(content.attachments); content.attachments = attachments; - return this._client.createInteractionResponse.call(this._client, this.id, this.token, { + return this.#client.createInteractionResponse.call(this.#client, this.id, this.token, { type: InteractionResponseTypes.UPDATE_MESSAGE, data: content }, files).then(() => this.update()); @@ -392,7 +394,7 @@ class ComponentInteraction extends Interaction { if(this.acknowledged === false) { throw new Error("getOriginalMessage cannot be used to acknowledge an interaction, please use acknowledge, createMessage, defer, deferUpdate, or editParent first."); } - return this._client.getWebhookMessage.call(this._client, this.applicationID, this.token, "@original"); + return this.#client.getWebhookMessage.call(this.#client, this.applicationID, this.token, "@original"); } } diff --git a/lib/structures/Guild.js b/lib/structures/Guild.js index 4eacbed9..5782a8ce 100644 --- a/lib/structures/Guild.js +++ b/lib/structures/Guild.js @@ -72,9 +72,10 @@ const ThreadChannel = require("./ThreadChannel"); * @prop {Boolean?} widgetEnabled Whether the guild widget is enabled. REST only. */ class Guild extends Base { + #client; constructor(data, client) { super(data.id); - this._client = client; + this.#client = client; this.shard = client.shards.get(client.guildShardMap[this.id] || (Base.getDiscordEpoch(data.id) % client.shards.options.maxShards) || 0); this.unavailable = !!data.unavailable; this.joinedAt = Date.parse(data.joined_at); @@ -172,7 +173,7 @@ class Guild extends Base { continue; } if(client.options.seedVoiceConnections && voiceState.id === client.user.id && !client.voiceConnections.get(this.id)) { - process.nextTick(() => this._client.joinVoiceChannel(voiceState.channel_id)); + process.nextTick(() => this.#client.joinVoiceChannel(voiceState.channel_id)); } } } @@ -292,19 +293,19 @@ class Guild extends Base { } get bannerURL() { - return this.banner ? this._client._formatImage(Endpoints.BANNER(this.id, this.banner)) : null; + return this.banner ? this.#client._formatImage(Endpoints.BANNER(this.id, this.banner)) : null; } get iconURL() { - return this.icon ? this._client._formatImage(Endpoints.GUILD_ICON(this.id, this.icon)) : null; + return this.icon ? this.#client._formatImage(Endpoints.GUILD_ICON(this.id, this.icon)) : null; } get splashURL() { - return this.splash ? this._client._formatImage(Endpoints.GUILD_SPLASH(this.id, this.splash)) : null; + return this.splash ? this.#client._formatImage(Endpoints.GUILD_SPLASH(this.id, this.splash)) : null; } get discoverySplashURL() { - return this.discoverySplash ? this._client._formatImage(Endpoints.GUILD_DISCOVERY_SPLASH(this.id, this.discoverySplash)) : null; + return this.discoverySplash ? this.#client._formatImage(Endpoints.GUILD_DISCOVERY_SPLASH(this.id, this.discoverySplash)) : null; } /** @@ -318,7 +319,7 @@ class Guild extends Base { * @arg {Boolean} [options.deaf] Whether the user should be deafened */ addMember(userID, accessToken, options = {}) { - return this._client.addGuildMember.call(this._client, this.id, userID, accessToken, options); + return this.#client.addGuildMember.call(this.#client, this.id, userID, accessToken, options); } /** @@ -329,7 +330,7 @@ class Guild extends Base { * @returns {Promise} */ addMemberRole(memberID, roleID, reason) { - return this._client.addGuildMemberRole.call(this._client, this.id, memberID, roleID, reason); + return this.#client.addGuildMemberRole.call(this.#client, this.id, memberID, roleID, reason); } /** @@ -340,7 +341,7 @@ class Guild extends Base { * @returns {Promise} */ banMember(userID, options) { - return this._client.banGuildMember.call(this._client, this.id, userID, options); + return this.#client.banGuildMember.call(this.#client, this.id, userID, options); } /** @@ -350,7 +351,7 @@ class Guild extends Base { * @returns {Promise>} Returns an array of [GuildApplicationCommandPermissions](https://discord.com/developers/docs/interactions/application-commands#application-command-permissions-object-guild-application-command-permissions-structure) objects. */ bulkEditCommandPermissions(permissions) { - return this._client.bulkEditCommandPermissions.call(this._client, this.id, permissions); + return this.#client.bulkEditCommandPermissions.call(this.#client, this.id, permissions); } /** @@ -359,7 +360,7 @@ class Guild extends Base { * @returns {Promise} Resolves with a commands object */ bulkEditCommands(commands) { - return this._client.bulkEditGuildCommands.call(this._client, this.id, commands); + return this.#client.bulkEditGuildCommands.call(this.#client, this.id, commands); } /** @@ -377,7 +378,7 @@ class Guild extends Base { * @returns {Promise} */ createAutoModerationRule(options) { - return this._client.createAutoModerationRule.call(this._client, this.id, options); + return this.#client.createAutoModerationRule.call(this.#client, this.id, options); } /** @@ -403,7 +404,7 @@ class Guild extends Base { * @returns {Promise} */ createChannel(name, type, options) { - return this._client.createChannel.call(this._client, this.id, name, type, options); + return this.#client.createChannel.call(this.#client, this.id, name, type, options); } /** @@ -419,7 +420,7 @@ class Guild extends Base { * @returns {Promise} */ createCommand(command) { - return this._client.createGuildCommand.call(this._client, this.id, command); + return this.#client.createGuildCommand.call(this.#client, this.id, command); } /** @@ -432,7 +433,7 @@ class Guild extends Base { * @returns {Promise} A guild emoji object */ createEmoji(options, reason) { - return this._client.createGuildEmoji.call(this._client, this.id, options, reason); + return this.#client.createGuildEmoji.call(this.#client, this.id, options, reason); } /** @@ -449,7 +450,7 @@ class Guild extends Base { * @returns {Promise} */ createRole(options, reason) { - return this._client.createRole.call(this._client, this.id, options, reason); + return this.#client.createRole.call(this.#client, this.id, options, reason); } /** @@ -469,7 +470,7 @@ class Guild extends Base { * @returns {Promise} */ createScheduledEvent(event, reason) { - return this._client.createGuildScheduledEvent.call(this._client, this.id, event, reason); + return this.#client.createGuildScheduledEvent.call(this.#client, this.id, event, reason); } /** @@ -485,7 +486,7 @@ class Guild extends Base { * @returns {Promise} A sticker object */ createSticker(options, reason) { - return this._client.createGuildSticker.call(this._client, this.id, options, reason); + return this.#client.createGuildSticker.call(this.#client, this.id, options, reason); } /** @@ -495,7 +496,7 @@ class Guild extends Base { * @returns {Promise} */ createTemplate(name, description) { - return this._client.createGuildTemplate.call(this._client, this.id, name, description); + return this.#client.createGuildTemplate.call(this.#client, this.id, name, description); } /** @@ -503,7 +504,7 @@ class Guild extends Base { * @returns {Promise} */ delete() { - return this._client.deleteGuild.call(this._client, this.id); + return this.#client.deleteGuild.call(this.#client, this.id); } /** @@ -513,7 +514,7 @@ class Guild extends Base { * @returns {Promise} */ deleteAutoModerationRule(ruleID, reason) { - return this._client.deleteAutoModerationRule.call(this._client, this.id, ruleID, reason); + return this.#client.deleteAutoModerationRule.call(this.#client, this.id, ruleID, reason); } /** @@ -522,7 +523,7 @@ class Guild extends Base { * @returns {Promise} */ deleteCommand(commandID) { - return this._client.deleteGuildCommand.call(this._client, this.id, commandID); + return this.#client.deleteGuildCommand.call(this.#client, this.id, commandID); } /** @@ -532,7 +533,7 @@ class Guild extends Base { * @returns {Promise} */ deleteEmoji(emojiID, reason) { - return this._client.deleteGuildEmoji.call(this._client, this.id, emojiID, reason); + return this.#client.deleteGuildEmoji.call(this.#client, this.id, emojiID, reason); } /** @@ -541,7 +542,7 @@ class Guild extends Base { * @returns {Promise} */ deleteIntegration(integrationID) { - return this._client.deleteGuildIntegration.call(this._client, this.id, integrationID); + return this.#client.deleteGuildIntegration.call(this.#client, this.id, integrationID); } /** @@ -551,7 +552,7 @@ class Guild extends Base { * @returns {Promise} */ deleteRole(roleID, reason) { - return this._client.deleteRole.call(this._client, this.id, roleID, reason); + return this.#client.deleteRole.call(this.#client, this.id, roleID, reason); } /** @@ -560,7 +561,7 @@ class Guild extends Base { * @returns {Promise} */ deleteScheduledEvent(eventID) { - return this._client.deleteGuildScheduledEvent.call(this._client, this.id, eventID); + return this.#client.deleteGuildScheduledEvent.call(this.#client, this.id, eventID); } /** @@ -570,7 +571,7 @@ class Guild extends Base { * @returns {Promise} */ deleteSticker(stickerID, reason) { - return this._client.deleteGuildSticker.call(this._client, this.id, stickerID, reason); + return this.#client.deleteGuildSticker.call(this.#client, this.id, stickerID, reason); } /** @@ -579,7 +580,7 @@ class Guild extends Base { * @returns {Promise} */ deleteTemplate(code) { - return this._client.deleteGuildTemplate.call(this._client, this.id, code); + return this.#client.deleteGuildTemplate.call(this.#client, this.id, code); } /** @@ -589,7 +590,7 @@ class Guild extends Base { * @returns {String?} */ dynamicBannerURL(format, size) { - return this.banner ? this._client._formatImage(Endpoints.BANNER(this.id, this.banner), format, size) : null; + return this.banner ? this.#client._formatImage(Endpoints.BANNER(this.id, this.banner), format, size) : null; } /** @@ -599,7 +600,7 @@ class Guild extends Base { * @returns {String?} */ dynamicDiscoverySplashURL(format, size) { - return this.discoverySplash ? this._client._formatImage(Endpoints.GUILD_DISCOVERY_SPLASH(this.id, this.discoverySplash), format, size) : null; + return this.discoverySplash ? this.#client._formatImage(Endpoints.GUILD_DISCOVERY_SPLASH(this.id, this.discoverySplash), format, size) : null; } /** @@ -609,7 +610,7 @@ class Guild extends Base { * @returns {String?} */ dynamicIconURL(format, size) { - return this.icon ? this._client._formatImage(Endpoints.GUILD_ICON(this.id, this.icon), format, size) : null; + return this.icon ? this.#client._formatImage(Endpoints.GUILD_ICON(this.id, this.icon), format, size) : null; } /** @@ -619,7 +620,7 @@ class Guild extends Base { * @returns {String?} */ dynamicSplashURL(format, size) { - return this.splash ? this._client._formatImage(Endpoints.GUILD_SPLASH(this.id, this.splash), format, size) : null; + return this.splash ? this.#client._formatImage(Endpoints.GUILD_SPLASH(this.id, this.splash), format, size) : null; } /** @@ -648,7 +649,7 @@ class Guild extends Base { * @returns {Promise} */ edit(options, reason) { - return this._client.editGuild.call(this._client, this.id, options, reason); + return this.#client.editGuild.call(this.#client, this.id, options, reason); } /** @@ -666,7 +667,7 @@ class Guild extends Base { * @returns {Promise} */ editAutoModerationRule(ruleID, options) { - return this._client.editAutoModerationRule.call(this._client, this.id, ruleID, options); + return this.#client.editAutoModerationRule.call(this.#client, this.id, ruleID, options); } /** @@ -679,7 +680,7 @@ class Guild extends Base { * @returns {Promise} */ editChannelPositions(channelPositions) { - return this._client.editChannelPositions.call(this._client, this.id, channelPositions); + return this.#client.editChannelPositions.call(this.#client, this.id, channelPositions); } /** @@ -695,7 +696,7 @@ class Guild extends Base { * @returns {Promise} */ editCommand(commandID, command) { - return this._client.editGuildCommand.call(this._client, this.id, commandID, command); + return this.#client.editGuildCommand.call(this.#client, this.id, commandID, command); } /** @@ -706,7 +707,7 @@ class Guild extends Base { * @returns {Promise} Resolves with a [GuildApplicationCommandPermissions](https://discord.com/developers/docs/interactions/application-commands#application-command-permissions-object-guild-application-command-permissions-structure) object. */ editCommandPermissions(commandID, permissions) { - return this._client.editCommandPermissions.call(this._client, this.id, commandID, permissions); + return this.#client.editCommandPermissions.call(this.#client, this.id, commandID, permissions); } /** @@ -719,7 +720,7 @@ class Guild extends Base { * @returns {Promise} A guild emoji object */ editEmoji(emojiID, options, reason) { - return this._client.editGuildEmoji.call(this._client, this.id, emojiID, options, reason); + return this.#client.editGuildEmoji.call(this.#client, this.id, emojiID, options, reason); } /** @@ -737,7 +738,7 @@ class Guild extends Base { * @returns {Promise} */ editMember(memberID, options, reason) { - return this._client.editGuildMember.call(this._client, this.id, memberID, options, reason); + return this.#client.editGuildMember.call(this.#client, this.id, memberID, options, reason); } /** @@ -748,7 +749,7 @@ class Guild extends Base { * @returns {Promise} Returns the new MFA level */ editMFALevel(options) { - return this._client.editGuildMFALevel.call(this._client, this.id, options); + return this.#client.editGuildMFALevel.call(this.#client, this.id, options); } /** @@ -766,7 +767,7 @@ class Guild extends Base { * @returns {Promise} */ editRole(roleID, options, reason) { - return this._client.editRole.call(this._client, this.id, roleID, options, reason); + return this.#client.editRole.call(this.#client, this.id, roleID, options, reason); } /** @@ -788,7 +789,7 @@ class Guild extends Base { * @returns {Promise} */ editScheduledEvent(eventID, event, reason) { - return this._client.editGuildScheduledEvent.call(this._client, this.id, eventID, event, reason); + return this.#client.editGuildScheduledEvent.call(this.#client, this.id, eventID, event, reason); } /** @@ -802,7 +803,7 @@ class Guild extends Base { * @returns {Promise} A sticker object */ editSticker(stickerID, options, reason) { - return this._client.editGuildSticker.call(this._client, this.id, stickerID, options, reason); + return this.#client.editGuildSticker.call(this.#client, this.id, stickerID, options, reason); } /** @@ -814,7 +815,7 @@ class Guild extends Base { * @returns {Promise} */ editTemplate(code, options) { - return this._client.editGuildTemplate.call(this._client, this.id, code, options); + return this.#client.editGuildTemplate.call(this.#client, this.id, code, options); } /** @@ -827,7 +828,7 @@ class Guild extends Base { * @returns {Promise} */ editVoiceState(options, userID) { - return this._client.editGuildVoiceState.call(this._client, this.id, options, userID); + return this.#client.editGuildVoiceState.call(this.#client, this.id, options, userID); } /** @@ -843,7 +844,7 @@ class Guild extends Base { * @returns {Promise} */ editWelcomeScreen(options) { - return this._client.editGuildWelcomeScreen.call(this._client, this.id, options); + return this.#client.editGuildWelcomeScreen.call(this.#client, this.id, options); } /** @@ -852,7 +853,7 @@ class Guild extends Base { * @returns {Promise} A guild widget object */ editWidget(options) { - return this._client.editGuildWidget.call(this._client, this.id, options); + return this.#client.editGuildWidget.call(this.#client, this.id, options); } /** @@ -874,7 +875,7 @@ class Guild extends Base { * @returns {Promise} An object containing an array of `threads` and an array of `members` */ getActiveThreads() { - return this._client.getActiveGuildThreads.call(this._client, this.id); + return this.#client.getActiveGuildThreads.call(this.#client, this.id); } /** @@ -888,7 +889,7 @@ class Guild extends Base { * @returns {Promise<{entries: Array, integrations: Array, threads: Array, users: Array, webhooks: Array}>} */ getAuditLog(options) { - return this._client.getGuildAuditLog.call(this._client, this.id, options); + return this.#client.getGuildAuditLog.call(this.#client, this.id, options); } /** @@ -898,7 +899,7 @@ class Guild extends Base { * @returns {Promise} */ getAutoModerationRule(ruleID) { - return this._client.getAutoModerationRule.call(this._client, this.id, ruleID); + return this.#client.getAutoModerationRule.call(this.#client, this.id, ruleID); } /** @@ -907,7 +908,7 @@ class Guild extends Base { * @returns {Promise} */ getAutoModerationRules() { - return this._client.getAutoModerationRules.call(this._client, this.id); + return this.#client.getAutoModerationRules.call(this.#client, this.id); } /** @@ -916,7 +917,7 @@ class Guild extends Base { * @returns {Promise} Resolves with {reason: String, user: User} */ getBan(userID) { - return this._client.getGuildBan.call(this._client, this.id, userID); + return this.#client.getGuildBan.call(this.#client, this.id, userID); } /** @@ -928,7 +929,7 @@ class Guild extends Base { * @returns {Promise>} Resolves with an array of { reason: String, user: User } */ getBans(options) { - return this._client.getGuildBans.call(this._client, this.id, options); + return this.#client.getGuildBans.call(this.#client, this.id, options); } /** @@ -938,7 +939,7 @@ class Guild extends Base { * @returns {Promise} Resolves with a command object */ getCommand(commandID, withLocalizations) { - return this._client.getGuildCommand.call(this._client, this.id, commandID, withLocalizations); + return this.#client.getGuildCommand.call(this.#client, this.id, commandID, withLocalizations); } /** @@ -947,7 +948,7 @@ class Guild extends Base { * @returns {Promise} Resolves with a guild application command permissions object. */ getCommandPermissions(commandID) { - return this._client.getCommandPermissions.call(this._client, this.id, commandID); + return this.#client.getCommandPermissions.call(this.#client, this.id, commandID); } /** @@ -956,7 +957,7 @@ class Guild extends Base { * @returns {Promise>} Resolves with an array of command objects */ getCommands(withLocalizations) { - return this._client.getGuildCommands.call(this._client, this.id, withLocalizations); + return this.#client.getGuildCommands.call(this.#client, this.id, withLocalizations); } /** @@ -964,7 +965,7 @@ class Guild extends Base { * @returns {Promise>} Resolves with an array of guild application command permissions objects. */ getGuildCommandPermissions() { - return this._client.getGuildCommandPermissions.call(this._client, this.id); + return this.#client.getGuildCommandPermissions.call(this.#client, this.id); } /** @@ -972,7 +973,7 @@ class Guild extends Base { * @returns {Promise>} */ getIntegrations() { - return this._client.getGuildIntegrations.call(this._client, this.id); + return this.#client.getGuildIntegrations.call(this.#client, this.id); } /** @@ -980,7 +981,7 @@ class Guild extends Base { * @returns {Promise>} */ getInvites() { - return this._client.getGuildInvites.call(this._client, this.id); + return this.#client.getGuildInvites.call(this.#client, this.id); } /** @@ -991,7 +992,7 @@ class Guild extends Base { * @returns {Promise} Resolves with the number of members that would be pruned */ getPruneCount(options) { - return this._client.getPruneCount.call(this._client, this.id, options); + return this.#client.getPruneCount.call(this.#client, this.id, options); } /** @@ -999,7 +1000,7 @@ class Guild extends Base { * @returns {Promise>} */ getRESTChannels() { - return this._client.getRESTGuildChannels.call(this._client, this.id); + return this.#client.getRESTGuildChannels.call(this.#client, this.id); } /** @@ -1008,7 +1009,7 @@ class Guild extends Base { * @returns {Promise} An emoji object */ getRESTEmoji(emojiID) { - return this._client.getRESTGuildEmoji.call(this._client, this.id, emojiID); + return this.#client.getRESTGuildEmoji.call(this.#client, this.id, emojiID); } /** @@ -1016,7 +1017,7 @@ class Guild extends Base { * @returns {Promise>} An array of guild emoji objects */ getRESTEmojis() { - return this._client.getRESTGuildEmojis.call(this._client, this.id); + return this.#client.getRESTGuildEmojis.call(this.#client, this.id); } /** @@ -1025,7 +1026,7 @@ class Guild extends Base { * @returns {Promise} */ getRESTMember(memberID) { - return this._client.getRESTGuildMember.call(this._client, this.id, memberID); + return this.#client.getRESTGuildMember.call(this.#client, this.id, memberID); } /** @@ -1036,7 +1037,7 @@ class Guild extends Base { * @returns {Promise>} */ getRESTMembers(options) { - return this._client.getRESTGuildMembers.call(this._client, this.id, options); + return this.#client.getRESTGuildMembers.call(this.#client, this.id, options); } /** @@ -1044,7 +1045,7 @@ class Guild extends Base { * @returns {Promise>} */ getRESTRoles() { - return this._client.getRESTGuildRoles.call(this._client, this.id); + return this.#client.getRESTGuildRoles.call(this.#client, this.id); } /** @@ -1055,7 +1056,7 @@ class Guild extends Base { * @returns {Promise} */ getRESTScheduledEvent(eventID, options) { - return this._client.getRESTGuildScheduledEvent.call(this._client, this.id, eventID, options); + return this.#client.getRESTGuildScheduledEvent.call(this.#client, this.id, eventID, options); } /** @@ -1064,7 +1065,7 @@ class Guild extends Base { * @returns {Promise} A sticker object */ getRESTSticker(stickerID) { - return this._client.getRESTGuildSticker.call(this._client, this.id, stickerID); + return this.#client.getRESTGuildSticker.call(this.#client, this.id, stickerID); } /** @@ -1072,7 +1073,7 @@ class Guild extends Base { * @returns {Promise>} An array of guild sticker objects */ getRESTStickers() { - return this._client.getRESTGuildStickers.call(this._client, this.id); + return this.#client.getRESTGuildStickers.call(this.#client, this.id); } /** @@ -1082,7 +1083,7 @@ class Guild extends Base { * @returns {Promise>} */ getScheduledEvents(options) { - return this._client.getGuildScheduledEvents.call(this._client, this.id, options); + return this.#client.getGuildScheduledEvents.call(this.#client, this.id, options); } /** @@ -1096,7 +1097,7 @@ class Guild extends Base { * @returns {Promise>} */ getScheduledEventUsers(eventID, options) { - return this._client.getGuildScheduledEventUsers.call(this._client, this.id, eventID, options); + return this.#client.getGuildScheduledEventUsers.call(this.#client, this.id, eventID, options); } /** @@ -1104,7 +1105,7 @@ class Guild extends Base { * @returns {Promise>} */ getTemplates() { - return this._client.getGuildTemplates.call(this._client, this.id); + return this.#client.getGuildTemplates.call(this.#client, this.id); } /** @@ -1112,7 +1113,7 @@ class Guild extends Base { * @returns {Promise} */ getVanity() { - return this._client.getGuildVanity.call(this._client, this.id); + return this.#client.getGuildVanity.call(this.#client, this.id); } /** @@ -1120,7 +1121,7 @@ class Guild extends Base { * @returns {Promise>} Resolves with an array of voice region objects */ getVoiceRegions() { - return this._client.getVoiceRegions.call(this._client, this.id); + return this.#client.getVoiceRegions.call(this.#client, this.id); } /** @@ -1128,7 +1129,7 @@ class Guild extends Base { * @returns {Promise>} Resolves with an array of webhook objects */ getWebhooks() { - return this._client.getGuildWebhooks.call(this._client, this.id); + return this.#client.getGuildWebhooks.call(this.#client, this.id); } /** @@ -1136,7 +1137,7 @@ class Guild extends Base { * @returns {Promise} */ getWelcomeScreen() { - return this._client.getGuildWelcomeScreen.call(this._client, this.id); + return this.#client.getGuildWelcomeScreen.call(this.#client, this.id); } /** @@ -1144,7 +1145,7 @@ class Guild extends Base { * @returns {Promise} A guild widget object */ getWidget() { - return this._client.getGuildWidget.call(this._client, this.id); + return this.#client.getGuildWidget.call(this.#client, this.id); } /** @@ -1152,7 +1153,7 @@ class Guild extends Base { * @returns {Promise} A guild widget settings object */ getWidgetSettings() { - return this._client.getGuildWidgetSettings.call(this._client, this.id); + return this.#client.getGuildWidgetSettings.call(this.#client, this.id); } /** @@ -1162,7 +1163,7 @@ class Guild extends Base { * @returns {Promise} */ kickMember(userID, reason) { - return this._client.kickGuildMember.call(this._client, this.id, userID, reason); + return this.#client.kickGuildMember.call(this.#client, this.id, userID, reason); } /** @@ -1170,14 +1171,14 @@ class Guild extends Base { * @returns {Promise} */ leave() { - return this._client.leaveGuild.call(this._client, this.id); + return this.#client.leaveGuild.call(this.#client, this.id); } /** * Leaves the voice channel in this guild */ leaveVoiceChannel() { - this._client.closeVoiceConnection.call(this._client, this.id); + this.#client.closeVoiceConnection.call(this.#client, this.id); } /** @@ -1222,7 +1223,7 @@ class Guild extends Base { * @returns {Promise} Resolves with the number of pruned members */ pruneMembers(options) { - return this._client.pruneMembers.call(this._client, this.id, options); + return this.#client.pruneMembers.call(this.#client, this.id, options); } /** @@ -1233,7 +1234,7 @@ class Guild extends Base { * @returns {Promise} */ removeMemberRole(memberID, roleID, reason) { - return this._client.removeGuildMemberRole.call(this._client, this.id, memberID, roleID, reason); + return this.#client.removeGuildMemberRole.call(this.#client, this.id, memberID, roleID, reason); } /** @@ -1243,7 +1244,7 @@ class Guild extends Base { * @returns {Promise>} */ searchMembers(query, limit) { - return this._client.searchGuildMembers.call(this._client, this.id, query, limit); + return this.#client.searchGuildMembers.call(this.#client, this.id, query, limit); } /** @@ -1252,7 +1253,7 @@ class Guild extends Base { * @returns {Promise} */ syncTemplate(code) { - return this._client.syncGuildTemplate.call(this._client, this.id, code); + return this.#client.syncGuildTemplate.call(this.#client, this.id, code); } /** @@ -1262,7 +1263,7 @@ class Guild extends Base { * @returns {Promise} */ unbanMember(userID, reason) { - return this._client.unbanGuildMember.call(this._client, this.id, userID, reason); + return this.#client.unbanGuildMember.call(this.#client, this.id, userID, reason); } toJSON(props = []) { diff --git a/lib/structures/GuildChannel.js b/lib/structures/GuildChannel.js index 05b0ce14..f6da5a2d 100644 --- a/lib/structures/GuildChannel.js +++ b/lib/structures/GuildChannel.js @@ -15,8 +15,10 @@ const {Permissions} = require("../Constants"); * @prop {Permission?} permissions The permissions of the bot user in this channel (available only for channels resolved via interactions) */ class GuildChannel extends Channel { + #client; constructor(data, client) { super(data, client); + this.#client = client; this.guild = client.guilds.get(data.guild_id) || { id: data.guild_id }; @@ -49,7 +51,7 @@ class GuildChannel extends Channel { * @returns {Promise} */ delete(reason) { - return this.client.deleteChannel.call(this.client, this.id, reason); + return this.#client.deleteChannel.call(this.#client, this.id, reason); } /** @@ -59,7 +61,7 @@ class GuildChannel extends Channel { * @returns {Promise} */ deletePermission(overwriteID, reason) { - return this.client.deleteChannelPermission.call(this.client, this.id, overwriteID, reason); + return this.#client.deleteChannelPermission.call(this.#client, this.id, overwriteID, reason); } /** @@ -90,7 +92,7 @@ class GuildChannel extends Channel { * @returns {Promise} */ edit(options, reason) { - return this.client.editChannel.call(this.client, this.id, options, reason); + return this.#client.editChannel.call(this.#client, this.id, options, reason); } /** @@ -103,7 +105,7 @@ class GuildChannel extends Channel { * @returns {Promise} */ editPermission(overwriteID, allow, deny, type, reason) { - return this.client.editChannelPermission.call(this.client, this.id, overwriteID, allow, deny, type, reason); + return this.#client.editChannelPermission.call(this.#client, this.id, overwriteID, allow, deny, type, reason); } /** @@ -115,7 +117,7 @@ class GuildChannel extends Channel { * @returns {Promise} */ editPosition(position, options) { - return this.client.editChannelPosition.call(this.client, this.id, position, options); + return this.#client.editChannelPosition.call(this.#client, this.id, position, options); } /** diff --git a/lib/structures/GuildPreview.js b/lib/structures/GuildPreview.js index b3b54f0b..cdccd9f7 100644 --- a/lib/structures/GuildPreview.js +++ b/lib/structures/GuildPreview.js @@ -22,9 +22,10 @@ const Endpoints = require("../rest/Endpoints.js"); * @prop {Array} stickers An array of guild sticker objects */ class GuildPreview extends Base { + #client; constructor(data, client) { super(data.id); - this._client = client; + this.#client = client; this.name = data.name; this.icon = data.icon; @@ -39,15 +40,15 @@ class GuildPreview extends Base { } get iconURL() { - return this.icon ? this._client._formatImage(Endpoints.GUILD_ICON(this.id, this.icon)) : null; + return this.icon ? this.#client._formatImage(Endpoints.GUILD_ICON(this.id, this.icon)) : null; } get splashURL() { - return this.splash ? this._client._formatImage(Endpoints.GUILD_SPLASH(this.id, this.splash)) : null; + return this.splash ? this.#client._formatImage(Endpoints.GUILD_SPLASH(this.id, this.splash)) : null; } get discoverySplashURL() { - return this.discoverySplash ? this._client._formatImage(Endpoints.GUILD_DISCOVERY_SPLASH(this.id, this.discoverySplash)) : null; + return this.discoverySplash ? this.#client._formatImage(Endpoints.GUILD_DISCOVERY_SPLASH(this.id, this.discoverySplash)) : null; } /** @@ -57,7 +58,7 @@ class GuildPreview extends Base { * @returns {String?} */ dynamicDiscoverySplashURL(format, size) { - return this.discoverySplash ? this._client._formatImage(Endpoints.GUILD_DISCOVERY_SPLASH(this.id, this.discoverySplash), format, size) : null; + return this.discoverySplash ? this.#client._formatImage(Endpoints.GUILD_DISCOVERY_SPLASH(this.id, this.discoverySplash), format, size) : null; } /** @@ -67,7 +68,7 @@ class GuildPreview extends Base { * @returns {String?} */ dynamicIconURL(format, size) { - return this.icon ? this._client._formatImage(Endpoints.GUILD_ICON(this.id, this.icon), format, size) : null; + return this.icon ? this.#client._formatImage(Endpoints.GUILD_ICON(this.id, this.icon), format, size) : null; } /** @@ -77,7 +78,7 @@ class GuildPreview extends Base { * @returns {String?} */ dynamicSplashURL(format, size) { - return this.splash ? this._client._formatImage(Endpoints.GUILD_SPLASH(this.id, this.splash), format, size) : null; + return this.splash ? this.#client._formatImage(Endpoints.GUILD_SPLASH(this.id, this.splash), format, size) : null; } toJSON(props = []) { diff --git a/lib/structures/GuildScheduledEvent.js b/lib/structures/GuildScheduledEvent.js index 332d0470..f83004f8 100644 --- a/lib/structures/GuildScheduledEvent.js +++ b/lib/structures/GuildScheduledEvent.js @@ -24,10 +24,11 @@ const Endpoints = require("../rest/Endpoints"); * @prop {Number?} userCount The number of users subscribed to the event */ class GuildScheduledEvent extends Base { + #client; constructor(data, client) { super(data.id); - this._client = client; + this.#client = client; if(data.creator !== undefined) { this.creator = client.users.update(data.creator, this.client); } else { @@ -43,7 +44,7 @@ class GuildScheduledEvent extends Base { update(data) { if(data.channel_id !== undefined) { if(data.channel_id !== null) { - this.channel = this._client.guilds.get(data.guild_id)?.channels.get(data.channel_id) || {id: data.channel_id}; + this.channel = this.#client.guilds.get(data.guild_id)?.channels.get(data.channel_id) || {id: data.channel_id}; } else { this.channel = null; } @@ -84,7 +85,7 @@ class GuildScheduledEvent extends Base { } get imageURL() { - return this.image ? this._client._formatImage(Endpoints.GUILD_SCHEDULED_EVENT_COVER(this.id, this.image)) : null; + return this.image ? this.#client._formatImage(Endpoints.GUILD_SCHEDULED_EVENT_COVER(this.id, this.image)) : null; } /** @@ -92,7 +93,7 @@ class GuildScheduledEvent extends Base { * @returns {Promise} */ delete() { - return this._client.deleteGuildScheduledEvent.call(this._client, this.guildID, this.id); + return this.#client.deleteGuildScheduledEvent.call(this.#client, this.guildID, this.id); } /** @@ -113,7 +114,7 @@ class GuildScheduledEvent extends Base { * @returns {Promise} */ edit(event, reason) { - return this._client.editGuildScheduledEvent.call(this._client, this.guildID, this.id, event, reason); + return this.#client.editGuildScheduledEvent.call(this.#client, this.guildID, this.id, event, reason); } /** @@ -126,7 +127,7 @@ class GuildScheduledEvent extends Base { * @returns {Promise>} */ getUsers(options) { - return this._client.getGuildScheduledEventUsers.call(this._client, this.guild.id, this.id, options); + return this.#client.getGuildScheduledEventUsers.call(this.#client, this.guild.id, this.id, options); } toJSON(props = []) { diff --git a/lib/structures/GuildTemplate.js b/lib/structures/GuildTemplate.js index 97b0125c..ce6e9911 100644 --- a/lib/structures/GuildTemplate.js +++ b/lib/structures/GuildTemplate.js @@ -15,8 +15,9 @@ const Guild = require("./Guild"); * @prop {Number} usageCount Number of times this template has been used */ class GuildTemplate { + #client; constructor(data, client) { - this._client = client; + this.#client = client; this.code = data.code; this.createdAt = Date.parse(data.created_at); this.creator = client.users.update(data.creator, client); @@ -36,7 +37,7 @@ class GuildTemplate { * @returns {Promise} */ createGuild(name, icon) { - return this._client.createGuildFromTemplate.call(this._client, this.code, name, icon); + return this.#client.createGuildFromTemplate.call(this.#client, this.code, name, icon); } /** @@ -44,7 +45,7 @@ class GuildTemplate { * @returns {Promise} */ delete() { - return this._client.deleteGuildTemplate.call(this._client, this.sourceGuild.id, this.code); + return this.#client.deleteGuildTemplate.call(this.#client, this.sourceGuild.id, this.code); } /** @@ -55,7 +56,7 @@ class GuildTemplate { * @returns {Promise} */ edit(options) { - return this._client.editGuildTemplate.call(this._client, this.sourceGuild.id, this.code, options); + return this.#client.editGuildTemplate.call(this.#client, this.sourceGuild.id, this.code, options); } /** @@ -63,7 +64,7 @@ class GuildTemplate { * @returns {Promise} */ sync() { - return this._client.syncGuildTemplate.call(this._client, this.sourceGuild.id, this.code); + return this.#client.syncGuildTemplate.call(this.#client, this.sourceGuild.id, this.code); } toJSON(props = []) { diff --git a/lib/structures/Interaction.js b/lib/structures/Interaction.js index 9776edfa..15acf534 100644 --- a/lib/structures/Interaction.js +++ b/lib/structures/Interaction.js @@ -23,9 +23,10 @@ const Permission = require("./Permission"); * @prop {Number} version The interaction version */ class Interaction extends Base { + #client; constructor(data, client) { super(data.id); - this._client = client; + this.#client = client; this.applicationID = data.application_id; this.token = data.token; @@ -34,7 +35,7 @@ class Interaction extends Base { this.acknowledged = false; if(data.channel_id !== undefined) { - this.channel = this._client.getChannel(data.channel_id) || { + this.channel = this.#client.getChannel(data.channel_id) || { id: data.channel_id }; } @@ -52,14 +53,14 @@ class Interaction extends Base { data.member.id = data.member.user.id; this.member = this.channel.guild.members.update(data.member, this.channel.guild); } else { - const guild = this._client.guilds.get(data.guild_id); - this.member = new Member(data.member, guild, this._client); + const guild = this.#client.guilds.get(data.guild_id); + this.member = new Member(data.member, guild, this.#client); } this.user = this.member.user; } if(data.user !== undefined) { - this.user = this._client.users.update(data.user, client); + this.user = this.#client.users.update(data.user, client); } if(data.locale !== undefined) { diff --git a/lib/structures/Invite.js b/lib/structures/Invite.js index 9f444623..5440e2a9 100644 --- a/lib/structures/Invite.js +++ b/lib/structures/Invite.js @@ -33,9 +33,11 @@ const GuildScheduledEvent = require("./GuildScheduledEvent"); * @prop {Number?} uses The number of invite uses */ class Invite extends Base { + #client; + #createdAt; constructor(data, client) { super(); - this._client = client; + this.#client = client; this.code = data.code; if(data.guild && client.guilds.has(data.guild.id)) { this.channel = client.guilds.get(data.guild.id).channels.update(data.channel, client); @@ -56,7 +58,7 @@ class Invite extends Base { this.maxUses = data.max_uses !== undefined ? data.max_uses : null; this.maxAge = data.max_age !== undefined ? data.max_age : null; this.temporary = data.temporary !== undefined ? data.temporary : null; - this._createdAt = data.created_at !== undefined ? data.created_at : null; + this.#createdAt = data.created_at !== undefined ? data.created_at : null; this.presenceCount = data.approximate_presence_count !== undefined ? data.approximate_presence_count : null; this.memberCount = data.approximate_member_count !== undefined ? data.approximate_member_count : null; if(data.stage_instance !== undefined) { @@ -80,7 +82,7 @@ class Invite extends Base { this.targetType = data.target_type; } if(data.target_user !== undefined) { - this.targetUser = client.users.update(data.target_user, this._client); + this.targetUser = client.users.update(data.target_user, this.#client); } if(data.expires_at !== undefined) { this.expiresAt = Date.parse(data.expires_at); @@ -91,7 +93,7 @@ class Invite extends Base { } get createdAt() { - return Date.parse(this._createdAt); + return Date.parse(this.#createdAt); } /** @@ -100,7 +102,7 @@ class Invite extends Base { * @returns {Promise} */ delete(reason) { - return this._client.deleteInvite.call(this._client, this.code, reason); + return this.#client.deleteInvite.call(this.#client, this.code, reason); } toString() { diff --git a/lib/structures/Message.js b/lib/structures/Message.js index 11277d4a..da969dc3 100644 --- a/lib/structures/Message.js +++ b/lib/structures/Message.js @@ -54,13 +54,15 @@ const Collection = require("../util/Collection"); * @prop {String?} webhookID ID of the webhook that sent the message */ class Message extends Base { + #channelMentions; + #client; constructor(data, client) { super(data.id); - this._client = client; + this.#client = client; this.type = data.type || 0; this.attachments = new Collection(Attachment); this.timestamp = Date.parse(data.timestamp); - this.channel = this._client.getChannel(data.channel_id) || { + this.channel = this.#client.getChannel(data.channel_id) || { id: data.channel_id }; this.content = ""; @@ -82,19 +84,19 @@ class Message extends Base { if(data.author) { if(data.author.discriminator !== "0000") { - this.author = this._client.users.update(data.author, client); + this.author = this.#client.users.update(data.author, client); } else { this.author = new User(data.author, client); } } else { - this._client.emit("error", new Error("MESSAGE_CREATE but no message author:\n" + JSON.stringify(data, null, 2))); + this.#client.emit("error", new Error("MESSAGE_CREATE but no message author:\n" + JSON.stringify(data, null, 2))); } if(data.referenced_message) { - const channel = this._client.getChannel(data.referenced_message.channel_id); + const channel = this.#client.getChannel(data.referenced_message.channel_id); if(channel) { - this.referencedMessage = channel.messages.update(data.referenced_message, this._client); + this.referencedMessage = channel.messages.update(data.referenced_message, this.#client); } else { - this.referencedMessage = new Message(data.referenced_message, this._client); + this.referencedMessage = new Message(data.referenced_message, this.#client); } } else { this.referencedMessage = data.referenced_message; @@ -103,7 +105,7 @@ class Message extends Base { if(data.interaction) { this.interaction = data.interaction; let interactionMember; - const interactionUser = this._client.users.update(data.interaction.user, client); + const interactionUser = this.#client.users.update(data.interaction.user, client); if(data.interaction.member) { data.interaction.member.id = data.interaction.user.id; if(this.channel.guild) { @@ -266,7 +268,7 @@ class Message extends Base { break; } default: { - this._client.emit("warn", `Unhandled MESSAGE_CREATE type: ${JSON.stringify(data, null, 2)}`); + this.#client.emit("warn", `Unhandled MESSAGE_CREATE type: ${JSON.stringify(data, null, 2)}`); break; } } @@ -280,7 +282,7 @@ class Message extends Base { this.mentionEveryone = !!data.mention_everyone; this.mentions = data.mentions.map((mention) => { - const user = this._client.users.add(mention, client); + const user = this.#client.users.add(mention, client); if(mention.member && this.channel.guild) { mention.member.id = mention.id; this.channel.guild.members.update(mention.member, this.channel.guild); @@ -338,7 +340,7 @@ class Message extends Base { if(data.sticker_items !== undefined) { this.stickerItems = data.sticker_items.map((sticker) => { if(sticker.user) { - sticker.user = this._client.users.update(sticker.user, client); + sticker.user = this.#client.users.update(sticker.user, client); } return sticker; @@ -364,11 +366,11 @@ class Message extends Base { } get channelMentions() { - if(this._channelMentions) { - return this._channelMentions; + if(this.#channelMentions) { + return this.#channelMentions; } - return (this._channelMentions = (this.content?.match(/<#[0-9]+>/g) || []).map((mention) => mention.substring(2, mention.length - 1))); + return (this.#channelMentions = (this.content?.match(/<#[0-9]+>/g) || []).map((mention) => mention.substring(2, mention.length - 1))); } get cleanContent() { @@ -398,7 +400,7 @@ class Message extends Base { } this.channelMentions.forEach((id) => { - const channel = this._client.getChannel(id); + const channel = this.#client.getChannel(id); if(channel?.name && channel?.mention) { cleanContent = cleanContent.replace(channel.mention, "#" + channel.name); } @@ -420,7 +422,7 @@ class Message extends Base { if(this.flags & MessageFlags.EPHEMERAL) { throw new Error("Ephemeral messages cannot have reactions"); } - return this._client.addMessageReaction.call(this._client, this.channel.id, this.id, reaction); + return this.#client.addMessageReaction.call(this.#client, this.channel.id, this.id, reaction); } /** @@ -431,7 +433,7 @@ class Message extends Base { * @returns {Promise} */ createThreadWithMessage(options) { - return this._client.createThreadWithMessage.call(this._client, this.channel.id, this.id, options); + return this.#client.createThreadWithMessage.call(this.#client, this.channel.id, this.id, options); } /** @@ -442,7 +444,7 @@ class Message extends Base { if(this.flags & MessageFlags.EPHEMERAL) { throw new Error("Ephemeral messages cannot be crossposted"); } - return this._client.crosspostMessage.call(this._client, this.channel.id, this.id); + return this.#client.crosspostMessage.call(this.#client, this.channel.id, this.id); } /** @@ -454,7 +456,7 @@ class Message extends Base { if(this.flags & MessageFlags.EPHEMERAL) { throw new Error("Ephemeral messages cannot be deleted"); } - return this._client.deleteMessage.call(this._client, this.channel.id, this.id, reason); + return this.#client.deleteMessage.call(this.#client, this.channel.id, this.id, reason); } /** @@ -469,7 +471,7 @@ class Message extends Base { if(this.flags & MessageFlags.EPHEMERAL) { throw new Error("Ephemeral messages cannot be deleted"); } - return this._client.deleteWebhookMessage.call(this._client, this.webhookID, token, this.id); + return this.#client.deleteWebhookMessage.call(this.#client, this.webhookID, token, this.id); } /** @@ -494,7 +496,7 @@ class Message extends Base { if(this.flags & MessageFlags.EPHEMERAL) { throw new Error("Ephemeral messages cannot be edited via this method"); } - return this._client.editMessage.call(this._client, this.channel.id, this.id, content); + return this.#client.editMessage.call(this.#client, this.channel.id, this.id, content); } /** @@ -520,7 +522,7 @@ class Message extends Base { if(!this.webhookID) { throw new Error("Message is not a webhook"); } - return this._client.editWebhookMessage.call(this._client, this.webhookID, token, this.id, options); + return this.#client.editWebhookMessage.call(this.#client, this.webhookID, token, this.id, options); } /** @@ -535,7 +537,7 @@ class Message extends Base { if(this.flags & MessageFlags.EPHEMERAL) { throw new Error("Ephemeral messages cannot have reactions"); } - return this._client.getMessageReaction.call(this._client, this.channel.id, this.id, reaction, options); + return this.#client.getMessageReaction.call(this.#client, this.channel.id, this.id, reaction, options); } /** @@ -546,7 +548,7 @@ class Message extends Base { if(this.flags & MessageFlags.EPHEMERAL) { throw new Error("Ephemeral messages cannot be pinned"); } - return this._client.pinMessage.call(this._client, this.channel.id, this.id); + return this.#client.pinMessage.call(this.#client, this.channel.id, this.id); } /** @@ -559,7 +561,7 @@ class Message extends Base { if(this.flags & MessageFlags.EPHEMERAL) { throw new Error("Ephemeral messages cannot have reactions"); } - return this._client.removeMessageReaction.call(this._client, this.channel.id, this.id, reaction, userID); + return this.#client.removeMessageReaction.call(this.#client, this.channel.id, this.id, reaction, userID); } /** @@ -571,7 +573,7 @@ class Message extends Base { if(this.flags & MessageFlags.EPHEMERAL) { throw new Error("Ephemeral messages cannot have reactions"); } - return this._client.removeMessageReactionEmoji.call(this._client, this.channel.id, this.id, reaction); + return this.#client.removeMessageReactionEmoji.call(this.#client, this.channel.id, this.id, reaction); } /** @@ -582,7 +584,7 @@ class Message extends Base { if(this.flags & MessageFlags.EPHEMERAL) { throw new Error("Ephemeral messages cannot have reactions"); } - return this._client.removeMessageReactions.call(this._client, this.channel.id, this.id); + return this.#client.removeMessageReactions.call(this.#client, this.channel.id, this.id); } /** @@ -593,7 +595,7 @@ class Message extends Base { if(this.flags & MessageFlags.EPHEMERAL) { throw new Error("Ephemeral messages cannot be pinned"); } - return this._client.unpinMessage.call(this._client, this.channel.id, this.id); + return this.#client.unpinMessage.call(this.#client, this.channel.id, this.id); } toJSON(props = []) { diff --git a/lib/structures/ModalSubmitInteraction.js b/lib/structures/ModalSubmitInteraction.js index 8198c81d..ed0accf9 100644 --- a/lib/structures/ModalSubmitInteraction.js +++ b/lib/structures/ModalSubmitInteraction.js @@ -16,10 +16,12 @@ const {InteractionResponseTypes} = require("../Constants"); * @prop {User?} user The user who triggered the interaction (This is only sent when the interaction is invoked within a dm) */ class ModalSubmitInteraction extends Interaction { + #client; constructor(data, client) { super(data, client); + this.#client = client; - this.channel = this._client.getChannel(data.channel_id) || { + this.channel = this.#client.getChannel(data.channel_id) || { id: data.channel_id }; @@ -34,13 +36,13 @@ class ModalSubmitInteraction extends Interaction { data.member.id = data.member.user.id; this.member = this.channel.guild.members.update(data.member, this.channel.guild); } else { - const guild = this._client.guilds.get(data.guild_id); + const guild = this.#client.guilds.get(data.guild_id); this.member = guild.members.update(data.member, guild); } } if(data.user !== undefined) { - this.user = this._client.users.update(data.user, client); + this.user = this.#client.users.update(data.user, client); } } @@ -84,7 +86,7 @@ class ModalSubmitInteraction extends Interaction { content.content = "" + content.content; } } - return this._client.executeWebhook.call(this._client, this.applicationID, this.token, Object.assign({wait: true}, content)); + return this.#client.executeWebhook.call(this.#client, this.applicationID, this.token, Object.assign({wait: true}, content)); } /** @@ -118,14 +120,14 @@ class ModalSubmitInteraction extends Interaction { content.content = "" + content.content; } if(content.content !== undefined || content.embeds || content.allowedMentions) { - content.allowed_mentions = this._client._formatAllowedMentions(content.allowedMentions); + content.allowed_mentions = this.#client._formatAllowedMentions(content.allowedMentions); } } - const {files, attachments} = this._client._processAttachments(content.attachments); + const {files, attachments} = this.#client._processAttachments(content.attachments); content.attachments = attachments; - return this._client.createInteractionResponse.call(this._client, this.id, this.token, { + return this.#client.createInteractionResponse.call(this.#client, this.id, this.token, { type: InteractionResponseTypes.CHANNEL_MESSAGE_WITH_SOURCE, data: content }, files).then(() => this.update()); @@ -141,7 +143,7 @@ class ModalSubmitInteraction extends Interaction { if(this.acknowledged === true) { throw new Error("You have already acknowledged this interaction."); } - return this._client.createInteractionResponse.call(this._client, this.id, this.token, { + return this.#client.createInteractionResponse.call(this.#client, this.id, this.token, { type: InteractionResponseTypes.DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE, data: { flags: flags || 0 @@ -158,7 +160,7 @@ class ModalSubmitInteraction extends Interaction { if(this.acknowledged === true) { throw new Error("You have already acknowledged this interaction."); } - return this._client.createInteractionResponse.call(this._client, this.id, this.token, { + return this.#client.createInteractionResponse.call(this.#client, this.id, this.token, { type: InteractionResponseTypes.DEFERRED_UPDATE_MESSAGE }).then(() => this.update()); } @@ -172,7 +174,7 @@ class ModalSubmitInteraction extends Interaction { if(this.acknowledged === false) { throw new Error("deleteMessage cannot be used to acknowledge an interaction, please use acknowledge, createMessage, defer, deferUpdate, or editParent first."); } - return this._client.deleteWebhookMessage.call(this._client, this.applicationID, this.token, messageID); + return this.#client.deleteWebhookMessage.call(this.#client, this.applicationID, this.token, messageID); } /** @@ -184,7 +186,7 @@ class ModalSubmitInteraction extends Interaction { if(this.acknowledged === false) { throw new Error("deleteOriginalMessage cannot be used to acknowledge an interaction, please use acknowledge, createMessage, defer, deferUpdate, or editParent first."); } - return this._client.deleteWebhookMessage.call(this._client, this.applicationID, this.token, "@original"); + return this.#client.deleteWebhookMessage.call(this.#client, this.applicationID, this.token, "@original"); } /** @@ -219,7 +221,7 @@ class ModalSubmitInteraction extends Interaction { content.content = "" + content.content; } } - return this._client.editWebhookMessage.call(this._client, this.applicationID, this.token, messageID, content); + return this.#client.editWebhookMessage.call(this.#client, this.applicationID, this.token, messageID, content); } /** @@ -253,7 +255,7 @@ class ModalSubmitInteraction extends Interaction { content.content = "" + content.content; } } - return this._client.editWebhookMessage.call(this._client, this.applicationID, this.token, "@original", content); + return this.#client.editWebhookMessage.call(this.#client, this.applicationID, this.token, "@original", content); } /** @@ -290,14 +292,14 @@ class ModalSubmitInteraction extends Interaction { content.content = "" + content.content; } if(content.content !== undefined || content.embeds || content.allowedMentions) { - content.allowed_mentions = this._client._formatAllowedMentions(content.allowedMentions); + content.allowed_mentions = this.#client._formatAllowedMentions(content.allowedMentions); } } - const {files, attachments} = this._client._processAttachments(content.attachments); + const {files, attachments} = this.#client._processAttachments(content.attachments); content.attachments = attachments; - return this._client.createInteractionResponse.call(this._client, this.id, this.token, { + return this.#client.createInteractionResponse.call(this.#client, this.id, this.token, { type: InteractionResponseTypes.UPDATE_MESSAGE, data: content }, files).then(() => this.update()); @@ -312,7 +314,7 @@ class ModalSubmitInteraction extends Interaction { if(this.acknowledged === false) { throw new Error("getOriginalMessage cannot be used to acknowledge an interaction, please use acknowledge, createMessage, defer, deferUpdate, or editParent first."); } - return this._client.getWebhookMessage.call(this._client, this.applicationID, this.token, "@original"); + return this.#client.getWebhookMessage.call(this.#client, this.applicationID, this.token, "@original"); } } diff --git a/lib/structures/Permission.js b/lib/structures/Permission.js index 79b2b475..ee0be342 100644 --- a/lib/structures/Permission.js +++ b/lib/structures/Permission.js @@ -21,6 +21,7 @@ const {Permissions} = require("../Constants"); * [A full list of permission nodes can be found in Constants](https://github.com/projectdysnomia/dysnomia/blob/dev/lib/Constants.js#L442) */ class Permission extends Base { + #json; constructor(allow, deny = 0) { super(); this.allow = BigInt(allow); @@ -28,19 +29,19 @@ class Permission extends Base { } get json() { - if(!this._json) { - this._json = {}; + if(!this.#json) { + this.#json = {}; for(const perm of Object.keys(Permissions)) { if(!perm.startsWith("all")) { if(this.allow & Permissions[perm]) { - this._json[perm] = true; + this.#json[perm] = true; } else if(this.deny & Permissions[perm]) { - this._json[perm] = false; + this.#json[perm] = false; } } } } - return this._json; + return this.#json; } /** diff --git a/lib/structures/PingInteraction.js b/lib/structures/PingInteraction.js index 3a4ea9ca..dc3277eb 100644 --- a/lib/structures/PingInteraction.js +++ b/lib/structures/PingInteraction.js @@ -8,6 +8,11 @@ const {InteractionResponseTypes} = require("../Constants"); * @extends Interaction */ class PingInteraction extends Interaction { + #client; + constructor(data, client) { + super(data, client); + this.#client = client; + } /** * Acknowledges the ping interaction with a pong response. @@ -27,7 +32,7 @@ class PingInteraction extends Interaction { if(this.acknowledged === true) { throw new Error("You have already acknowledged this interaction."); } - return this._client.createInteractionResponse.call(this._client, this.id, this.token, { + return this.#client.createInteractionResponse.call(this.#client, this.id, this.token, { type: InteractionResponseTypes.PONG }).then(() => this.update()); } diff --git a/lib/structures/StageInstance.js b/lib/structures/StageInstance.js index 1df1ce1a..f9e7580e 100644 --- a/lib/structures/StageInstance.js +++ b/lib/structures/StageInstance.js @@ -13,9 +13,10 @@ const Base = require("./Base"); * @prop {String} topic The stage instance topic */ class StageInstance extends Base { + #client; constructor(data, client) { super(data.id); - this._client = client; + this.#client = client; this.channel = client.getChannel(data.channel_id) || {id: data.channel_id}; this.guild = client.guilds.get(data.guild_id) || {id: data.guild_id}; this.guildScheduledEvent = this.guild.events?.get(data.guild_scheduled_event_id) || {id: data.guild_scheduled_event_id}; @@ -39,7 +40,7 @@ class StageInstance extends Base { * @returns {Promise} */ delete() { - return this._client.deleteStageInstance.call(this._client, this.channel.id); + return this.#client.deleteStageInstance.call(this.#client, this.channel.id); } /** @@ -50,7 +51,7 @@ class StageInstance extends Base { * @returns {Promise} */ edit(options) { - return this._client.editStageInstance.call(this._client, this.channel.id, options); + return this.#client.editStageInstance.call(this.#client, this.channel.id, options); } } diff --git a/lib/structures/ThreadMember.js b/lib/structures/ThreadMember.js index c765456f..7b78e53d 100644 --- a/lib/structures/ThreadMember.js +++ b/lib/structures/ThreadMember.js @@ -12,9 +12,10 @@ const Member = require("./Member"); * @prop {String} threadID The ID of the thread this member is a part of */ class ThreadMember extends Base { + #client; constructor(data, client) { super(data.user_id); - this._client = client; + this.#client = client; this.flags = data.flags; this.threadID = data.thread_id || data.id; // Thanks Discord this.joinTimestamp = Date.parse(data.join_timestamp); @@ -24,7 +25,7 @@ class ThreadMember extends Base { data.member.id = this.id; } - const guild = this._client.guilds.get(this._client.threadGuildMap[this.threadID]); + const guild = this.#client.guilds.get(this.#client.threadGuildMap[this.threadID]); this.guildMember = guild ? guild.members.update(data.member, guild) : new Member(data.member, guild, client); if(data.presence !== undefined) { this.guildMember.update(data.presence); @@ -45,7 +46,7 @@ class ThreadMember extends Base { * @returns {Promise} */ leave() { - return this._client.leaveThread.call(this._client, this.threadID, this.id); + return this.#client.leaveThread.call(this.#client, this.threadID, this.id); } toJSON(props = []) { diff --git a/lib/structures/User.js b/lib/structures/User.js index 3fee5570..ac7db902 100644 --- a/lib/structures/User.js +++ b/lib/structures/User.js @@ -23,12 +23,14 @@ const Endpoints = require("../rest/Endpoints"); * @prop {String} username The username of the user */ class User extends Base { + #client; + #missingClientError; constructor(data, client) { super(data.id); if(!client) { - this._missingClientError = new Error("Missing client in constructor"); // Preserve constructor callstack + this.#missingClientError = new Error("Missing client in constructor"); // Preserve constructor callstack } - this._client = client; + this.#client = client; this.bot = !!data.bot; this.system = !!data.system; this.update(data); @@ -56,20 +58,20 @@ class User extends Base { } get avatarURL() { - if(this._missingClientError) { - throw this._missingClientError; + if(this.#missingClientError) { + throw this.#missingClientError; } - return this.avatar ? this._client._formatImage(Endpoints.USER_AVATAR(this.id, this.avatar)) : this.defaultAvatarURL; + return this.avatar ? this.#client._formatImage(Endpoints.USER_AVATAR(this.id, this.avatar)) : this.defaultAvatarURL; } get bannerURL() { if(!this.banner) { return null; } - if(this._missingClientError) { - throw this._missingClientError; + if(this.#missingClientError) { + throw this.#missingClientError; } - return this._client._formatImage(Endpoints.BANNER(this.id, this.banner)); + return this.#client._formatImage(Endpoints.BANNER(this.id, this.banner)); } get defaultAvatar() { @@ -85,10 +87,10 @@ class User extends Base { } get staticAvatarURL() { - if(this._missingClientError) { - throw this._missingClientError; + if(this.#missingClientError) { + throw this.#missingClientError; } - return this.avatar ? this._client._formatImage(Endpoints.USER_AVATAR(this.id, this.avatar), "jpg") : this.defaultAvatarURL; + return this.avatar ? this.#client._formatImage(Endpoints.USER_AVATAR(this.id, this.avatar), "jpg") : this.defaultAvatarURL; } /** @@ -101,10 +103,10 @@ class User extends Base { if(!this.avatar) { return this.defaultAvatarURL; } - if(this._missingClientError) { - throw this._missingClientError; + if(this.#missingClientError) { + throw this.#missingClientError; } - return this._client._formatImage(Endpoints.USER_AVATAR(this.id, this.avatar), format, size); + return this.#client._formatImage(Endpoints.USER_AVATAR(this.id, this.avatar), format, size); } /** @@ -117,10 +119,10 @@ class User extends Base { if(!this.banner) { return null; } - if(this._missingClientError) { - throw this._missingClientError; + if(this.#missingClientError) { + throw this.#missingClientError; } - return this._client._formatImage(Endpoints.BANNER(this.id, this.banner), format, size); + return this.#client._formatImage(Endpoints.BANNER(this.id, this.banner), format, size); } /** @@ -128,7 +130,7 @@ class User extends Base { * @returns {Promise} */ getDMChannel() { - return this._client.getDMChannel.call(this._client, this.id); + return this.#client.getDMChannel.call(this.#client, this.id); } toJSON(props = []) { diff --git a/lib/util/BrowserWebSocket.js b/lib/util/BrowserWebSocket.js index d8e94e27..7078e35b 100644 --- a/lib/util/BrowserWebSocket.js +++ b/lib/util/BrowserWebSocket.js @@ -21,6 +21,7 @@ class BrowserWebSocketError extends Error { * @prop {String} url The URL to connect to */ class BrowserWebSocket extends EventEmitter { + #ws; constructor(url) { super(); @@ -28,19 +29,19 @@ class BrowserWebSocket extends EventEmitter { throw new Error("BrowserWebSocket cannot be used outside of a browser environment"); } - this._ws = new window.WebSocket(url); - this._ws.onopen = () => this.emit("open"); - this._ws.onmessage = this._onMessage.bind(this); - this._ws.onerror = (event) => this.emit("error", new BrowserWebSocketError("Unknown error", event)); - this._ws.onclose = (event) => this.emit("close", event.code, event.reason); + this.#ws = new window.WebSocket(url); + this.#ws.onopen = () => this.emit("open"); + this.#ws.onmessage = this.#onMessage.bind(this); + this.#ws.onerror = (event) => this.emit("error", new BrowserWebSocketError("Unknown error", event)); + this.#ws.onclose = (event) => this.emit("close", event.code, event.reason); } get readyState() { - return this._ws.readyState; + return this.#ws.readyState; } close(code, reason) { - return this._ws.close(code, reason); + return this.#ws.close(code, reason); } removeEventListener(type, listener) { @@ -48,14 +49,14 @@ class BrowserWebSocket extends EventEmitter { } send(data) { - return this._ws.send(data); + return this.#ws.send(data); } terminate() { - return this._ws.close(); + return this.#ws.close(); } - async _onMessage(event) { + async #onMessage(event) { if(event.data instanceof window.Blob) { this.emit("message", await event.data.arrayBuffer()); } else { diff --git a/lib/util/Bucket.js b/lib/util/Bucket.js index ad2c8433..8be046fd 100644 --- a/lib/util/Bucket.js +++ b/lib/util/Bucket.js @@ -12,7 +12,7 @@ const Base = require("../structures/Base"); * @prop {Number} tokens How many tokens the bucket has consumed in this interval */ class Bucket { - _queue = []; + #queue = []; lastReset = 0; lastSend = 0; tokens = 0; @@ -33,7 +33,7 @@ class Bucket { } check() { - if(this.timeout || this._queue.length === 0) { + if(this.timeout || this.#queue.length === 0) { return; } if(this.lastReset + this.interval + this.tokenLimit * this.latencyRef.latency < Date.now()) { @@ -44,11 +44,11 @@ class Bucket { let val; let tokensAvailable = this.tokens < this.tokenLimit; let unreservedTokensAvailable = this.tokens < (this.tokenLimit - this.reservedTokens); - while(this._queue.length > 0 && (unreservedTokensAvailable || (tokensAvailable && this._queue[0].priority))) { + while(this.#queue.length > 0 && (unreservedTokensAvailable || (tokensAvailable && this.#queue[0].priority))) { this.tokens++; tokensAvailable = this.tokens < this.tokenLimit; unreservedTokensAvailable = this.tokens < (this.tokenLimit - this.reservedTokens); - const item = this._queue.shift(); + const item = this.#queue.shift(); val = this.latencyRef.latency - Date.now() + this.lastSend; if(this.latencyRef.latency === 0 || val <= 0) { item.func(); @@ -61,7 +61,7 @@ class Bucket { } } - if(this._queue.length > 0 && !this.timeout) { + if(this.#queue.length > 0 && !this.timeout) { this.timeout = setTimeout(() => { this.timeout = null; this.check(); @@ -76,9 +76,9 @@ class Bucket { */ queue(func, priority=false) { if(priority) { - this._queue.unshift({func, priority}); + this.#queue.unshift({func, priority}); } else { - this._queue.push({func, priority}); + this.#queue.push({func, priority}); } this.check(); } diff --git a/lib/util/SequentialBucket.js b/lib/util/SequentialBucket.js index 6de05458..1bd4dcff 100644 --- a/lib/util/SequentialBucket.js +++ b/lib/util/SequentialBucket.js @@ -12,7 +12,7 @@ const Base = require("../structures/Base"); * @prop {Number} reset Timestamp of next reset */ class SequentialBucket { - _queue = []; + #queue = []; processing = false; reset = 0; /** @@ -27,7 +27,7 @@ class SequentialBucket { } check(override) { - if(this._queue.length === 0) { + if(this.#queue.length === 0) { if(this.processing) { clearTimeout(this.processing); this.processing = false; @@ -53,8 +53,8 @@ class SequentialBucket { } --this.remaining; this.processing = true; - this._queue.shift()(() => { - if(this._queue.length > 0) { + this.#queue.shift()(() => { + if(this.#queue.length > 0) { this.check(true); } else { this.processing = false; @@ -68,9 +68,9 @@ class SequentialBucket { */ queue(func, short) { if(short) { - this._queue.unshift(func); + this.#queue.unshift(func); } else { - this._queue.push(func); + this.#queue.push(func); } this.check(); } diff --git a/lib/voice/Piper.js b/lib/voice/Piper.js index 50efa14a..3bddd371 100644 --- a/lib/voice/Piper.js +++ b/lib/voice/Piper.js @@ -45,10 +45,11 @@ function webGetter(link, depth = 8) { } class Piper extends EventEmitter { - _dataPacketMax = 30; - _dataPacketMin = 15; - _dataPackets = []; - _retransformer = []; + #dataPacketMax = 30; + #dataPacketMin = 15; + #dataPackets = []; + #endStream; + #retransformer = []; encoding = false; libopus = true; opus = null; @@ -66,17 +67,17 @@ class Piper extends EventEmitter { } get dataPacketCount() { - return this._dataPackets.length; + return this.#dataPackets.length; } addDataPacket(packet) { if(!this.encoding) { return; } - if(this._dataPackets.push(packet) < this._dataPacketMax && this._endStream?.manualCB) { + if(this.#dataPackets.push(packet) < this.#dataPacketMax && this.#endStream?.manualCB) { process.nextTick(() => { - if(this._endStream?.manualCB) { - this._endStream.transformCB(); + if(this.#endStream?.manualCB) { + this.#endStream.transformCB(); } }); } @@ -114,8 +115,8 @@ class Piper extends EventEmitter { return false; } - this._dataPacketMax = 30; - this._dataPacketMin = 15; + this.#dataPacketMax = 30; + this.#dataPacketMin = 15; if(typeof source !== "string") { this.streams.push(source.once("error", (e) => this.stop(e))); @@ -158,8 +159,8 @@ class Piper extends EventEmitter { frameSize: options.frameSize, pcmSize: options.pcmSize })).once("error", (e) => this.stop(e))); - this._dataPacketMax = 1; // Live volume updating - this._dataPacketMin = 4; + this.#dataPacketMax = 1; // Live volume updating + this.#dataPacketMin = 4; } else { if(this.libopus) { if(typeof source === "string") { @@ -209,13 +210,13 @@ class Piper extends EventEmitter { return false; } - this._endStream = this.streams[this.streams.length - 1]; - if(this._endStream.hasOwnProperty("manualCB")) { - this._endStream.manualCB = true; + this.#endStream = this.streams[this.streams.length - 1]; + if(this.#endStream.hasOwnProperty("manualCB")) { + this.#endStream.manualCB = true; } - this._endStream.on("data", this.addDataPacket); - this._endStream.once("end", () => this.stop(null, source)); + this.#endStream.on("data", this.addDataPacket); + this.#endStream.once("end", () => this.stop(null, source)); this.emit("start"); @@ -223,18 +224,18 @@ class Piper extends EventEmitter { } getDataPacket() { - if(this._dataPackets.length < this._dataPacketMin && this._endStream?.manualCB) { - this._endStream.transformCB(); + if(this.#dataPackets.length < this.#dataPacketMin && this.#endStream?.manualCB) { + this.#endStream.transformCB(); } - if(this._retransformer.length === 0) { - return this._dataPackets.shift(); + if(this.#retransformer.length === 0) { + return this.#dataPackets.shift(); } else { // If we don't have an opus instance yet, create one. this.opus ??= this.opusFactory(); - const packet = this.opus.decode(this._dataPackets.shift()); + const packet = this.opus.decode(this.#dataPackets.shift()); for(let i = 0, num; i < packet.length - 1; i += 2) { - num = ~~(this._retransformer.shift() * packet.readInt16LE(i)); + num = ~~(this.#retransformer.shift() * packet.readInt16LE(i)); packet.writeInt16LE(num >= 32767 ? 32767 : num <= -32767 ? -32767 : num, i); } return this.opus.encode(packet, 3840 / 2 / 2); @@ -253,7 +254,7 @@ class Piper extends EventEmitter { } this.streams = []; - this._endStream = null; + this.#endStream = null; this.volume = null; } @@ -263,7 +264,7 @@ class Piper extends EventEmitter { this.opus.delete?.(); this.opus = null; } - this._dataPackets = []; + this.#dataPackets = []; } setVolume(volume) { @@ -292,7 +293,7 @@ class Piper extends EventEmitter { return; } - this._endStream?.removeAllListeners("data"); + this.#endStream?.removeAllListeners("data"); this.reset(); if(this.encoding) { diff --git a/lib/voice/SharedStream.js b/lib/voice/SharedStream.js index 43afcf3d..0e23d529 100644 --- a/lib/voice/SharedStream.js +++ b/lib/voice/SharedStream.js @@ -24,6 +24,7 @@ try { * @prop {Number} volume The current volume level of the connection */ class SharedStream extends EventEmitter { + #send; bitrate = 64_000; channels = 2; ended = true; @@ -51,7 +52,7 @@ class SharedStream extends EventEmitter { this.piper.libopus = false; } - this._send = this._send.bind(this); + this.#send = this.#sendUnbound.bind(this); } get volume() { @@ -124,7 +125,7 @@ class SharedStream extends EventEmitter { */ this.emit("start"); - this._send(); + this.#send(); } /** @@ -177,26 +178,26 @@ class SharedStream extends EventEmitter { this.emit("end"); } - _incrementSequences() { + #incrementSequences() { for(const vc of this.voiceConnections.values()) { vc.sequence = (vc.sequence + 1) & 0xFFFF; } } - _incrementTimestamps(val) { + #incrementTimestamps(val) { for(const vc of this.voiceConnections.values()) { vc.timestamp = (vc.timestamp + val) >>> 0; } } - _send() { + #sendUnbound() { if(!this.piper.encoding && this.piper.dataPacketCount === 0) { return this.stopPlaying(); } - this._incrementTimestamps(this.current.options.frameSize); + this.#incrementTimestamps(this.current.options.frameSize); - this._incrementSequences(); + this.#incrementSequences(); if((this.current.buffer = this.piper.getDataPacket())) { if(this.current.startTime === 0) { @@ -211,8 +212,8 @@ class SharedStream extends EventEmitter { this.setSpeaking(false); } else { this.current.pausedTime += 4 * this.current.options.frameDuration; - this._incrementTimestamps(3 * this.current.options.frameSize); - this.current.timeout = setTimeout(this._send, 4 * this.current.options.frameDuration); + this.#incrementTimestamps(3 * this.current.options.frameSize); + this.current.timeout = setTimeout(this.#send, 4 * this.current.options.frameDuration); return; } } else { @@ -225,7 +226,7 @@ class SharedStream extends EventEmitter { } }); this.current.playTime += this.current.options.frameDuration; - this.current.timeout = setTimeout(this._send, this.current.startTime + this.current.pausedTime + this.current.playTime - Date.now()); + this.current.timeout = setTimeout(this.#send, this.current.startTime + this.current.pausedTime + this.current.playTime - Date.now()); } [util.inspect.custom]() { diff --git a/lib/voice/VoiceConnection.js b/lib/voice/VoiceConnection.js index 87de658f..d643600b 100644 --- a/lib/voice/VoiceConnection.js +++ b/lib/voice/VoiceConnection.js @@ -77,6 +77,7 @@ converterCommand.pickCommand = function pickCommand() { * @prop {Number} volume The current volume level of the connection */ class VoiceConnection extends EventEmitter { + #send; bitrate = 64_000; channelID = null; channels = 2; @@ -149,7 +150,7 @@ class VoiceConnection extends EventEmitter { } } - this._send = this._send.bind(this); + this.#send = this.#sendUnbound.bind(this); } get volume() { @@ -536,7 +537,7 @@ class VoiceConnection extends EventEmitter { */ this.emit("start"); - this._send(); + this.#send(); } /** @@ -633,7 +634,7 @@ class VoiceConnection extends EventEmitter { this.current.pausedTime += Date.now() - this.current.pausedTimestamp; this.current.pausedTimestamp = 0; } - this._send(); + this.#send(); } else { this.setSpeaking(0); } @@ -648,7 +649,7 @@ class VoiceConnection extends EventEmitter { this.timestamp = (this.timestamp + frameSize) >>> 0; this.sequence = (this.sequence + 1) & 0xFFFF; - return this._sendAudioFrame(frame); + return this.#sendAudioFrame(frame); } /** @@ -774,7 +775,7 @@ class VoiceConnection extends EventEmitter { } } - _send() { + #sendUnbound() { if(!this.piper.encoding && this.piper.dataPacketCount === 0) { return this.stopPlaying(); } @@ -793,7 +794,7 @@ class VoiceConnection extends EventEmitter { } this.current.pausedTime += 4 * this.current.options.frameDuration; this.timestamp = (this.timestamp + 3 * this.current.options.frameSize) >>> 0; - this.current.timeout = setTimeout(this._send, 4 * this.current.options.frameDuration); + this.current.timeout = setTimeout(this.#send, 4 * this.current.options.frameDuration); return; } else { return this.stopPlaying(); @@ -801,10 +802,10 @@ class VoiceConnection extends EventEmitter { this.sendAudioFrame(this.current.buffer, this.current.options.frameSize); this.current.playTime += this.current.options.frameDuration; - this.current.timeout = setTimeout(this._send, this.current.startTime + this.current.pausedTime + this.current.playTime - Date.now()); + this.current.timeout = setTimeout(this.#send, this.current.startTime + this.current.pausedTime + this.current.playTime - Date.now()); } - _sendAudioFrame(frame) { + #sendAudioFrame(frame) { this.sendNonce.writeUInt16BE(this.sequence, 2); this.sendNonce.writeUInt32BE(this.timestamp, 4); diff --git a/lib/voice/streams/BaseTransformer.js b/lib/voice/streams/BaseTransformer.js index 548434a4..a1b342f1 100644 --- a/lib/voice/streams/BaseTransformer.js +++ b/lib/voice/streams/BaseTransformer.js @@ -5,6 +5,7 @@ const Base = require("../../structures/Base"); const TransformStream = require("node:stream").Transform; class BaseTransformer extends TransformStream { + #transformCB; manualCB = false; constructor(options = {}) { options.allowHalfOpen ??= true; @@ -15,16 +16,16 @@ class BaseTransformer extends TransformStream { setTransformCB(cb) { if(this.manualCB) { this.transformCB(); - this._transformCB = cb; + this.#transformCB = cb; } else { cb(); } } transformCB() { - if(this._transformCB) { - this._transformCB(); - this._transformCB = null; + if(this.#transformCB) { + this.#transformCB(); + this.#transformCB = null; } } diff --git a/lib/voice/streams/DCAOpusTransformer.js b/lib/voice/streams/DCAOpusTransformer.js index 5ea2aef5..29ec084a 100644 --- a/lib/voice/streams/DCAOpusTransformer.js +++ b/lib/voice/streams/DCAOpusTransformer.js @@ -3,7 +3,7 @@ const BaseTransformer = require("./BaseTransformer"); class DCAOpusTransformer extends BaseTransformer { - _remainder = null; + #remainder = null; process(buffer) { if(buffer.length - buffer._index < 2) { @@ -22,14 +22,14 @@ class DCAOpusTransformer extends BaseTransformer { } _transform(chunk, enc, cb) { - if(this._remainder) { - chunk = Buffer.concat([this._remainder, chunk]); - this._remainder = null; + if(this.#remainder) { + chunk = Buffer.concat([this.#remainder, chunk]); + this.#remainder = null; } if(!this.head) { if(chunk.length < 4) { - this._remainder = chunk; + this.#remainder = chunk; return cb(); } else { const dcaVersion = chunk.subarray(0, 4); @@ -37,12 +37,12 @@ class DCAOpusTransformer extends BaseTransformer { this.head = true; // Attempt to play as if it were a DCA0 file } else if(dcaVersion[3] === 49) { // DCA1 if(chunk.length < 8) { - this._remainder = chunk; + this.#remainder = chunk; return cb(); } const jsonLength = chunk.subarray(4, 8).readInt32LE(0); if(chunk.length < 8 + jsonLength) { - this._remainder = chunk; + this.#remainder = chunk; return cb(); } const jsonMetadata = chunk.subarray(8, 8 + jsonLength); @@ -61,7 +61,7 @@ class DCAOpusTransformer extends BaseTransformer { const offset = chunk._index; const ret = this.process(chunk); if(ret) { - this._remainder = chunk.subarray(offset); + this.#remainder = chunk.subarray(offset); cb(); return; } diff --git a/lib/voice/streams/FFmpegDuplex.js b/lib/voice/streams/FFmpegDuplex.js index 067c3d3f..42d6f5d6 100644 --- a/lib/voice/streams/FFmpegDuplex.js +++ b/lib/voice/streams/FFmpegDuplex.js @@ -14,6 +14,11 @@ const delegateEvents = { }; class FFmpegDuplex extends DuplexStream { + #onError; + #process; + #stderr; + #stdin; + #stdout; constructor(command, options = {}) { options.highWaterMark ??= 0; super(options); @@ -22,10 +27,10 @@ class FFmpegDuplex extends DuplexStream { this._reader = new PassThroughStream(options); this._writer = new PassThroughStream(options); - this._onError = this.emit.bind(this, "error"); + this.#onError = this.emit.bind(this, "error"); - this._reader.on("error", this._onError); - this._writer.on("error", this._onError); + this._reader.on("error", this.#onError); + this._writer.on("error", this.#onError); this._readableState = this._reader._readableState; this._writableState = this._writer._writableState; @@ -86,10 +91,10 @@ class FFmpegDuplex extends DuplexStream { }; const cleanup = () => { - this._process = - this._stderr = - this._stdout = - this._stdin = + this.#process = + this.#stderr = + this.#stdout = + this.#stdin = stderr = ex = killed = null; @@ -115,7 +120,7 @@ class FFmpegDuplex extends DuplexStream { } else { // Everything else ex = new Error("Command failed: " + Buffer.concat(stderr).toString("utf8")); - ex.killed = this._process.killed || killed; + ex.killed = this.#process.killed || killed; ex.code = code; ex.signal = signal; this.emit("error", ex); @@ -127,8 +132,8 @@ class FFmpegDuplex extends DuplexStream { const onError = (err) => { ex = err; - this._stdout.destroy(); - this._stderr.destroy(); + this.#stdout.destroy(); + this.#stderr.destroy(); onExit(); }; @@ -136,41 +141,41 @@ class FFmpegDuplex extends DuplexStream { if(killed) { return; } - this._stdout.destroy(); - this._stderr.destroy(); + this.#stdout.destroy(); + this.#stderr.destroy(); killed = true; try { - this._process.kill(options.killSignal || "SIGTERM"); - setTimeout(() => this._process && this._process.kill("SIGKILL"), 2000); + this.#process.kill(options.killSignal || "SIGTERM"); + setTimeout(() => this.#process && this.#process.kill("SIGKILL"), 2000); } catch(e) { ex = e; onExit(); } }; - this._process = ChildProcess.spawn(this.command, args, options); - this._stdin = this._process.stdin; - this._stdout = this._process.stdout; - this._stderr = this._process.stderr; - this._writer.pipe(this._stdin); - this._stdout.pipe(this._reader, { + this.#process = ChildProcess.spawn(this.command, args, options); + this.#stdin = this.#process.stdin; + this.#stdout = this.#process.stdout; + this.#stderr = this.#process.stderr; + this._writer.pipe(this.#stdin); + this.#stdout.pipe(this._reader, { end: false }); this.kill = this.destroy = kill; - this._stderr.on("data", onStderrData); + this.#stderr.on("data", onStderrData); // In some cases ECONNRESET can be emitted by stdin because the process is not interested in any // more data but the _writer is still piping. Forget about errors emitted on stdin and stdout - this._stdin.on("error", this.noop); - this._stdout.on("error", this.noop); + this.#stdin.on("error", this.noop); + this.#stdout.on("error", this.noop); - this._stdout.on("end", onStdoutEnd); + this.#stdout.on("end", onStdoutEnd); - this._process.once("close", onExit); - this._process.once("error", onError); + this.#process.once("close", onExit); + this.#process.once("error", onError); return this; } diff --git a/lib/voice/streams/OggOpusTransformer.js b/lib/voice/streams/OggOpusTransformer.js index 25560150..e4c7eb0f 100644 --- a/lib/voice/streams/OggOpusTransformer.js +++ b/lib/voice/streams/OggOpusTransformer.js @@ -3,8 +3,8 @@ const BaseTransformer = require("./BaseTransformer"); class OggOpusTransformer extends BaseTransformer { - _bitstream = null; - _remainder = null; + #bitstream = null; + #remainder = null; process(buffer) { if(buffer.length - buffer._index <= 26) { @@ -57,11 +57,11 @@ class OggOpusTransformer extends BaseTransformer { if(this.head) { if(byte === "OpusTags") { this.emit("debug", segment.toString()); - } else if(bitstream === this._bitstream) { + } else if(bitstream === this.#bitstream) { this.push(segment); } } else if(byte === "OpusHead") { - this._bitstream = bitstream; + this.#bitstream = bitstream; this.emit("debug", (this.head = segment.toString())); } else { this.emit("debug", "Invalid codec: " + byte); @@ -70,15 +70,15 @@ class OggOpusTransformer extends BaseTransformer { } _final() { - if(!this._bitstream) { + if(!this.#bitstream) { this.emit("error", new Error("No Opus stream was found")); } } _transform(chunk, enc, cb) { - if(this._remainder) { - chunk = Buffer.concat([this._remainder, chunk]); - this._remainder = null; + if(this.#remainder) { + chunk = Buffer.concat([this.#remainder, chunk]); + this.#remainder = null; } chunk._index = 0; @@ -87,7 +87,7 @@ class OggOpusTransformer extends BaseTransformer { const offset = chunk._index; const ret = this.process(chunk); if(ret) { - this._remainder = chunk.subarray(offset); + this.#remainder = chunk.subarray(offset); if(ret instanceof Error) { this.emit("error", ret); } diff --git a/lib/voice/streams/PCMOpusTransformer.js b/lib/voice/streams/PCMOpusTransformer.js index 924fb00e..4a1512d5 100644 --- a/lib/voice/streams/PCMOpusTransformer.js +++ b/lib/voice/streams/PCMOpusTransformer.js @@ -3,7 +3,7 @@ const BaseTransformer = require("./BaseTransformer"); class PCMOpusTransformer extends BaseTransformer { - _remainder = null; + #remainder = null; constructor(options = {}) { super(options); @@ -19,24 +19,24 @@ class PCMOpusTransformer extends BaseTransformer { } _flush(cb) { - if(this._remainder) { + if(this.#remainder) { const buf = Buffer.allocUnsafe(this.pcmSize); - this._remainder.copy(buf); - buf.fill(0, this._remainder.length); + this.#remainder.copy(buf); + buf.fill(0, this.#remainder.length); this.push(this.opus.encode(buf, this.frameSize)); - this._remainder = null; + this.#remainder = null; } cb(); } _transform(chunk, enc, cb) { - if(this._remainder) { - chunk = Buffer.concat([this._remainder, chunk]); - this._remainder = null; + if(this.#remainder) { + chunk = Buffer.concat([this.#remainder, chunk]); + this.#remainder = null; } if(chunk.length < this.pcmSize) { - this._remainder = chunk; + this.#remainder = chunk; return cb(); } @@ -48,7 +48,7 @@ class PCMOpusTransformer extends BaseTransformer { } if(chunk._index < chunk.length) { - this._remainder = chunk.subarray(chunk._index); + this.#remainder = chunk.subarray(chunk._index); } this.setTransformCB(cb); diff --git a/lib/voice/streams/VolumeTransformer.js b/lib/voice/streams/VolumeTransformer.js index 3b2fd01a..7245987a 100644 --- a/lib/voice/streams/VolumeTransformer.js +++ b/lib/voice/streams/VolumeTransformer.js @@ -3,7 +3,7 @@ const BaseTransformer = require("./BaseTransformer"); class VolumeTransformer extends BaseTransformer { - _remainder = null; + #remainder = null; constructor(options = {}) { super(options); @@ -19,9 +19,9 @@ class VolumeTransformer extends BaseTransformer { } _transform(chunk, enc, cb) { - if(this._remainder) { - chunk = Buffer.concat([this._remainder, chunk]); - this._remainder = null; + if(this.#remainder) { + chunk = Buffer.concat([this.#remainder, chunk]); + this.#remainder = null; } if(chunk.length < 2) { @@ -30,7 +30,7 @@ class VolumeTransformer extends BaseTransformer { let buf; if(chunk.length & 1) { - this._remainder = chunk.subarray(chunk.length - 1); + this.#remainder = chunk.subarray(chunk.length - 1); buf = Buffer.allocUnsafe(chunk.length - 1); } else { buf = Buffer.allocUnsafe(chunk.length); diff --git a/lib/voice/streams/WebmOpusTransformer.js b/lib/voice/streams/WebmOpusTransformer.js index 449e5dd0..a5812f26 100644 --- a/lib/voice/streams/WebmOpusTransformer.js +++ b/lib/voice/streams/WebmOpusTransformer.js @@ -16,9 +16,10 @@ const TAG_TYPE_TAG = 2; const TRACKTYPE_AUDIO = 2; // EBML spec: https://www.matroska.org/technical/specs/index.html#TrackType class WebmOpusTransformer extends BaseTransformer { - _state = STATE_TAG; - _tag_stack = []; - _total = 0; + #remainder; + #state = STATE_TAG; + #tag_stack = []; + #total = 0; getVIntLength(buffer, index) { let length = 1; @@ -93,11 +94,11 @@ class WebmOpusTransformer extends BaseTransformer { } readContent(buffer) { - const tagObj = this._tag_stack[this._tag_stack.length - 1]; + const tagObj = this.#tag_stack[this.#tag_stack.length - 1]; if(tagObj.type === "m") { this.process(TAG_TYPE_START, tagObj); - this._state = STATE_TAG; + this.#state = STATE_TAG; return true; } @@ -107,18 +108,18 @@ class WebmOpusTransformer extends BaseTransformer { tagObj.data = buffer.subarray(buffer._index, buffer._index + tagObj.size); buffer._index += tagObj.size; - this._total += tagObj.size; - this._state = STATE_TAG; + this.#total += tagObj.size; + this.#state = STATE_TAG; - this._tag_stack.pop(); + this.#tag_stack.pop(); this.process(TAG_TYPE_TAG, tagObj); - while(this._tag_stack.length > 0) { - if(this._total < this._tag_stack[this._tag_stack.length - 1].end) { + while(this.#tag_stack.length > 0) { + if(this.#total < this.#tag_stack[this.#tag_stack.length - 1].end) { break; } - this.process(TAG_TYPE_END, this._tag_stack.pop()); + this.process(TAG_TYPE_END, this.#tag_stack.pop()); } return true; @@ -140,7 +141,7 @@ class WebmOpusTransformer extends BaseTransformer { const tagObj = { type: "unknown", name: "unknown", - end: this._total + tagSize + end: this.#total + tagSize }; if(schema[tagStr]) { tagObj.type = schema[tagStr].type; @@ -163,33 +164,33 @@ class WebmOpusTransformer extends BaseTransformer { tagObj.size = value; buffer._index += size; - this._total += tagSize + size; - this._state = STATE_CONTENT; + this.#total += tagSize + size; + this.#state = STATE_CONTENT; - this._tag_stack.push(tagObj); + this.#tag_stack.push(tagObj); return true; } _transform(chunk, enc, cb) { - if(this._remainder) { - chunk = Buffer.concat([this._remainder, chunk]); - this._remainder = null; + if(this.#remainder) { + chunk = Buffer.concat([this.#remainder, chunk]); + this.#remainder = null; } chunk._index = 0; while(chunk._index < chunk.length) { - if(this._state === STATE_TAG && !this.readTag(chunk)) { + if(this.#state === STATE_TAG && !this.readTag(chunk)) { break; } - if(this._state === STATE_CONTENT && !this.readContent(chunk)) { + if(this.#state === STATE_CONTENT && !this.readContent(chunk)) { break; } } if(chunk._index < chunk.length) { - this._remainder = chunk.subarray(chunk._index); + this.#remainder = chunk.subarray(chunk._index); } this.setTransformCB(cb); From dddf5ba33309a59a1905cd13b34caf7a40983e09 Mon Sep 17 00:00:00 2001 From: TTtie Date: Sat, 1 Apr 2023 11:42:41 +0000 Subject: [PATCH 12/16] NodeJS -> Node.js while we're at it --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 726111f7..da9131fe 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ A fork of [Eris](https://github.com/abalabahaha/eris), a Node.js wrapper for int Installing ---------- -You will need NodeJS 18+. Voice support requires [additional software](https://github.com/nodejs/node-gyp#installation). +You will need Node.js 18+. Voice support requires [additional software](https://github.com/nodejs/node-gyp#installation). ``` npm install --omit=optional @projectdysnomia/dysnomia From c886c9a24fffa6986866fb46fedc601e3dd28dd0 Mon Sep 17 00:00:00 2001 From: TTtie Date: Sat, 1 Apr 2023 12:05:28 +0000 Subject: [PATCH 13/16] remove extra newline (clean diffs) --- lib/gateway/Shard.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/gateway/Shard.js b/lib/gateway/Shard.js index 3d7500e6..16f53d6a 100644 --- a/lib/gateway/Shard.js +++ b/lib/gateway/Shard.js @@ -942,7 +942,6 @@ class Shard extends EventEmitter { member = channel.guild.members.update(packet.d.member, channel.guild); } } - if(message) { const reaction = packet.d.emoji.id ? `${packet.d.emoji.name}:${packet.d.emoji.id}` : packet.d.emoji.name; if(message.reactions[reaction]) { From e0f998048f6361607933093bab11742c65ada97c Mon Sep 17 00:00:00 2001 From: TTtie Date: Sat, 1 Apr 2023 12:06:38 +0000 Subject: [PATCH 14/16] compress Message#channelMentions even further --- lib/structures/Message.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/structures/Message.js b/lib/structures/Message.js index da969dc3..dfec2ea8 100644 --- a/lib/structures/Message.js +++ b/lib/structures/Message.js @@ -366,11 +366,7 @@ class Message extends Base { } get channelMentions() { - if(this.#channelMentions) { - return this.#channelMentions; - } - - return (this.#channelMentions = (this.content?.match(/<#[0-9]+>/g) || []).map((mention) => mention.substring(2, mention.length - 1))); + return this.#channelMentions ?? (this.#channelMentions = (this.content?.match(/<#[0-9]+>/g) || []).map((mention) => mention.substring(2, mention.length - 1))); } get cleanContent() { From f284eddef601e542270da913c614d252ff6d948a Mon Sep 17 00:00:00 2001 From: TTtie Date: Sat, 1 Apr 2023 12:07:28 +0000 Subject: [PATCH 15/16] aesthetics: 48000 > 48_000 --- lib/voice/streams/FFmpegPCMTransformer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/voice/streams/FFmpegPCMTransformer.js b/lib/voice/streams/FFmpegPCMTransformer.js index 139fb332..4b887202 100644 --- a/lib/voice/streams/FFmpegPCMTransformer.js +++ b/lib/voice/streams/FFmpegPCMTransformer.js @@ -6,7 +6,7 @@ module.exports = function(options = {}) { if(!options.command) { throw new Error("Invalid converter command"); } - options.samplingRate ??= 48000; + options.samplingRate ??= 48_000; const inputArgs = [ "-analyzeduration", "0", "-loglevel", "24" From a8175866c09b6f48f919b98e7cc9d95b77b28f38 Mon Sep 17 00:00:00 2001 From: TTtie Date: Sat, 1 Apr 2023 12:20:05 +0000 Subject: [PATCH 16/16] GuildChannel##client -> Channel#client Not yet... --- lib/structures/GuildChannel.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/structures/GuildChannel.js b/lib/structures/GuildChannel.js index f6da5a2d..05b0ce14 100644 --- a/lib/structures/GuildChannel.js +++ b/lib/structures/GuildChannel.js @@ -15,10 +15,8 @@ const {Permissions} = require("../Constants"); * @prop {Permission?} permissions The permissions of the bot user in this channel (available only for channels resolved via interactions) */ class GuildChannel extends Channel { - #client; constructor(data, client) { super(data, client); - this.#client = client; this.guild = client.guilds.get(data.guild_id) || { id: data.guild_id }; @@ -51,7 +49,7 @@ class GuildChannel extends Channel { * @returns {Promise} */ delete(reason) { - return this.#client.deleteChannel.call(this.#client, this.id, reason); + return this.client.deleteChannel.call(this.client, this.id, reason); } /** @@ -61,7 +59,7 @@ class GuildChannel extends Channel { * @returns {Promise} */ deletePermission(overwriteID, reason) { - return this.#client.deleteChannelPermission.call(this.#client, this.id, overwriteID, reason); + return this.client.deleteChannelPermission.call(this.client, this.id, overwriteID, reason); } /** @@ -92,7 +90,7 @@ class GuildChannel extends Channel { * @returns {Promise} */ edit(options, reason) { - return this.#client.editChannel.call(this.#client, this.id, options, reason); + return this.client.editChannel.call(this.client, this.id, options, reason); } /** @@ -105,7 +103,7 @@ class GuildChannel extends Channel { * @returns {Promise} */ editPermission(overwriteID, allow, deny, type, reason) { - return this.#client.editChannelPermission.call(this.#client, this.id, overwriteID, allow, deny, type, reason); + return this.client.editChannelPermission.call(this.client, this.id, overwriteID, allow, deny, type, reason); } /** @@ -117,7 +115,7 @@ class GuildChannel extends Channel { * @returns {Promise} */ editPosition(position, options) { - return this.#client.editChannelPosition.call(this.#client, this.id, position, options); + return this.client.editChannelPosition.call(this.client, this.id, position, options); } /**