mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 16:13:31 +01:00
refactor: new node features (#5132)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
This commit is contained in:
@@ -34,14 +34,7 @@ class Client extends BaseClient {
|
||||
constructor(options) {
|
||||
super(Object.assign({ _tokenType: 'Bot' }, options));
|
||||
|
||||
// Obtain shard details from environment or if present, worker threads
|
||||
let data = process.env;
|
||||
try {
|
||||
// Test if worker threads module is present and used
|
||||
data = require('worker_threads').workerData || data;
|
||||
} catch {
|
||||
// Do nothing
|
||||
}
|
||||
const data = require('worker_threads').workerData ?? process.env;
|
||||
|
||||
if (this.options.shards === DefaultOptions.shards) {
|
||||
if ('SHARDS' in data) {
|
||||
@@ -188,7 +181,7 @@ class Client extends BaseClient {
|
||||
* @readonly
|
||||
*/
|
||||
get readyTimestamp() {
|
||||
return this.readyAt ? this.readyAt.getTime() : null;
|
||||
return this.readyAt?.getTime() ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -341,7 +334,7 @@ class Client extends BaseClient {
|
||||
channels++;
|
||||
|
||||
messages += channel.messages.cache.sweep(
|
||||
message => now - (message.editedTimestamp || message.createdTimestamp) > lifetimeMs,
|
||||
message => now - (message.editedTimestamp ?? message.createdTimestamp) > lifetimeMs,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,14 +32,14 @@ class GenericAction {
|
||||
}
|
||||
|
||||
getChannel(data) {
|
||||
const id = data.channel_id || data.id;
|
||||
const id = data.channel_id ?? data.id;
|
||||
return (
|
||||
data.channel ||
|
||||
data.channel ??
|
||||
this.getPayload(
|
||||
{
|
||||
id,
|
||||
guild_id: data.guild_id,
|
||||
recipients: [data.author || { id: data.user_id }],
|
||||
recipients: [data.author ?? { id: data.user_id }],
|
||||
},
|
||||
this.client.channels,
|
||||
id,
|
||||
@@ -49,14 +49,14 @@ class GenericAction {
|
||||
}
|
||||
|
||||
getMessage(data, channel, cache) {
|
||||
const id = data.message_id || data.id;
|
||||
const id = data.message_id ?? data.id;
|
||||
return (
|
||||
data.message ||
|
||||
data.message ??
|
||||
this.getPayload(
|
||||
{
|
||||
id,
|
||||
channel_id: channel.id,
|
||||
guild_id: data.guild_id || (channel.guild ? channel.guild.id : null),
|
||||
guild_id: data.guild_id ?? channel.guild?.id,
|
||||
},
|
||||
channel.messages,
|
||||
id,
|
||||
@@ -67,12 +67,12 @@ class GenericAction {
|
||||
}
|
||||
|
||||
getReaction(data, message, user) {
|
||||
const id = data.emoji.id || decodeURIComponent(data.emoji.name);
|
||||
const id = data.emoji.id ?? decodeURIComponent(data.emoji.name);
|
||||
return this.getPayload(
|
||||
{
|
||||
emoji: data.emoji,
|
||||
count: message.partial ? null : 0,
|
||||
me: user ? user.id === this.client.user.id : false,
|
||||
me: user?.id === this.client.user.id,
|
||||
},
|
||||
message.reactions,
|
||||
id,
|
||||
@@ -86,11 +86,11 @@ class GenericAction {
|
||||
|
||||
getUser(data) {
|
||||
const id = data.user_id;
|
||||
return data.user || this.getPayload({ id }, this.client.users, id, PartialTypes.USER);
|
||||
return data.user ?? this.getPayload({ id }, this.client.users, id, PartialTypes.USER);
|
||||
}
|
||||
|
||||
getUserFromMember(data) {
|
||||
if (data.guild_id && data.member && data.member.user) {
|
||||
if (data.guild_id && data.member?.user) {
|
||||
const guild = this.client.guilds.cache.get(data.guild_id);
|
||||
if (guild) {
|
||||
return guild.members.add(data.member).user;
|
||||
|
||||
@@ -12,7 +12,7 @@ class ChannelDeleteAction extends Action {
|
||||
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
let channel = client.channels.cache.get(data.id);
|
||||
const channel = client.channels.cache.get(data.id);
|
||||
|
||||
if (channel) {
|
||||
client.channels.remove(channel.id);
|
||||
|
||||
@@ -53,7 +53,7 @@ class GuildDeleteAction extends Action {
|
||||
this.deleted.set(guild.id, guild);
|
||||
this.scheduleForDeletion(guild.id);
|
||||
} else {
|
||||
guild = this.deleted.get(data.id) || null;
|
||||
guild = this.deleted.get(data.id) ?? null;
|
||||
}
|
||||
|
||||
return { guild };
|
||||
|
||||
@@ -5,7 +5,7 @@ const Action = require('./Action');
|
||||
class GuildEmojisUpdateAction extends Action {
|
||||
handle(data) {
|
||||
const guild = this.client.guilds.cache.get(data.guild_id);
|
||||
if (!guild || !guild.emojis) return;
|
||||
if (!guild?.emojis) return;
|
||||
|
||||
const deletions = new Map(guild.emojis.cache);
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ class MessageCreateAction extends Action {
|
||||
if (existing) return { message: existing };
|
||||
const message = channel.messages.add(data);
|
||||
const user = message.author;
|
||||
let member = message.member;
|
||||
const member = message.member;
|
||||
channel.lastMessageID = data.id;
|
||||
if (user) {
|
||||
user.lastMessageID = data.id;
|
||||
|
||||
@@ -31,8 +31,8 @@ class MessageReactionAdd extends Action {
|
||||
|
||||
// Verify reaction
|
||||
if (message.partial && !this.client.options.partials.includes(PartialTypes.REACTION)) return false;
|
||||
const existing = message.reactions.cache.get(data.emoji.id || data.emoji.name);
|
||||
if (existing && existing.users.cache.has(user.id)) return { message, reaction: existing, user };
|
||||
const existing = message.reactions.cache.get(data.emoji.id ?? data.emoji.name);
|
||||
if (existing?.users.cache.has(user.id)) return { message, reaction: existing, user };
|
||||
const reaction = message.reactions.add({
|
||||
emoji: data.emoji,
|
||||
count: message.partial ? null : 0,
|
||||
|
||||
@@ -13,7 +13,7 @@ class MessageReactionRemoveEmoji extends Action {
|
||||
|
||||
const reaction = this.getReaction(data, message);
|
||||
if (!reaction) return false;
|
||||
if (!message.partial) message.reactions.cache.delete(reaction.emoji.id || reaction.emoji.name);
|
||||
if (!message.partial) message.reactions.cache.delete(reaction.emoji.id ?? reaction.emoji.name);
|
||||
|
||||
/**
|
||||
* Emitted when a bot removes an emoji reaction from a cached message.
|
||||
|
||||
@@ -6,18 +6,17 @@ const { Events } = require('../../util/Constants');
|
||||
class PresenceUpdateAction extends Action {
|
||||
handle(data) {
|
||||
let user = this.client.users.cache.get(data.user.id);
|
||||
if (!user && data.user.username) user = this.client.users.add(data.user);
|
||||
if (!user && data.user?.username) user = this.client.users.add(data.user);
|
||||
if (!user) return;
|
||||
|
||||
if (data.user && data.user.username) {
|
||||
if (data.user?.username) {
|
||||
if (!user.equals(data.user)) this.client.actions.UserUpdate.handle(data.user);
|
||||
}
|
||||
|
||||
const guild = this.client.guilds.cache.get(data.guild_id);
|
||||
if (!guild) return;
|
||||
|
||||
let oldPresence = guild.presences.cache.get(user.id);
|
||||
if (oldPresence) oldPresence = oldPresence._clone();
|
||||
const oldPresence = guild.presences.cache.get(user.id)?._clone();
|
||||
let member = guild.members.cache.get(user.id);
|
||||
if (!member && data.status !== 'offline') {
|
||||
member = guild.members.add({
|
||||
@@ -28,7 +27,7 @@ class PresenceUpdateAction extends Action {
|
||||
this.client.emit(Events.GUILD_MEMBER_AVAILABLE, member);
|
||||
}
|
||||
guild.presences.add(Object.assign(data, { guild }));
|
||||
if (member && this.client.listenerCount(Events.PRESENCE_UPDATE) && !member.presence.equals(oldPresence)) {
|
||||
if (this.client.listenerCount(Events.PRESENCE_UPDATE) && member && !member.presence.equals(oldPresence)) {
|
||||
/**
|
||||
* Emitted whenever a guild member's presence (e.g. status, activity) is changed.
|
||||
* @event Client#presenceUpdate
|
||||
|
||||
@@ -11,9 +11,8 @@ class VoiceStateUpdate extends Action {
|
||||
if (guild) {
|
||||
const VoiceState = Structures.get('VoiceState');
|
||||
// Update the state
|
||||
const oldState = guild.voiceStates.cache.has(data.user_id)
|
||||
? guild.voiceStates.cache.get(data.user_id)._clone()
|
||||
: new VoiceState(guild, { user_id: data.user_id });
|
||||
const oldState =
|
||||
guild.voiceStates.cache.get(data.user_id)?._clone() ?? new VoiceState(guild, { user_id: data.user_id });
|
||||
|
||||
const newState = guild.voiceStates.add(data);
|
||||
|
||||
@@ -21,12 +20,12 @@ class VoiceStateUpdate extends Action {
|
||||
let member = guild.members.cache.get(data.user_id);
|
||||
if (member && data.member) {
|
||||
member._patch(data.member);
|
||||
} else if (data.member && data.member.user && data.member.joined_at) {
|
||||
} else if (data.member?.user && data.member.joined_at) {
|
||||
member = guild.members.add(data.member);
|
||||
}
|
||||
|
||||
// Emit event
|
||||
if (member && member.user.id === client.user.id) {
|
||||
if (member?.user.id === client.user.id) {
|
||||
client.emit('debug', `[VOICE] received voice state update: ${JSON.stringify(data)}`);
|
||||
client.voice.onVoiceStateUpdate(data);
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ class WebSocketManager extends EventEmitter {
|
||||
try {
|
||||
await shard.connect();
|
||||
} catch (error) {
|
||||
if (error && error.code && UNRECOVERABLE_CLOSE_CODES.includes(error.code)) {
|
||||
if (error?.code && UNRECOVERABLE_CLOSE_CODES.includes(error.code)) {
|
||||
throw new Error(WSCodes[error.code]);
|
||||
// Undefined if session is invalid, error event for regular closes
|
||||
} else if (!error || error.code) {
|
||||
|
||||
@@ -176,7 +176,7 @@ class WebSocketShard extends EventEmitter {
|
||||
connect() {
|
||||
const { gateway, client } = this.manager;
|
||||
|
||||
if (this.connection && this.connection.readyState === WebSocket.OPEN && this.status === Status.READY) {
|
||||
if (this.connection?.readyState === WebSocket.OPEN && this.status === Status.READY) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ class WebSocketShard extends EventEmitter {
|
||||
this.once(ShardEvents.INVALID_SESSION, onInvalidOrDestroyed);
|
||||
this.once(ShardEvents.DESTROYED, onInvalidOrDestroyed);
|
||||
|
||||
if (this.connection && this.connection.readyState === WebSocket.OPEN) {
|
||||
if (this.connection?.readyState === WebSocket.OPEN) {
|
||||
this.debug('An open connection was found, attempting an immediate identify.');
|
||||
this.identify();
|
||||
return;
|
||||
@@ -306,7 +306,7 @@ class WebSocketShard extends EventEmitter {
|
||||
* @private
|
||||
*/
|
||||
onError(event) {
|
||||
const error = event && event.error ? event.error : event;
|
||||
const error = event?.error ?? event;
|
||||
if (!error) return;
|
||||
|
||||
/**
|
||||
@@ -345,7 +345,7 @@ class WebSocketShard extends EventEmitter {
|
||||
this.debug(`[CLOSE]
|
||||
Event Code: ${event.code}
|
||||
Clean : ${event.wasClean}
|
||||
Reason : ${event.reason || 'No reason received'}`);
|
||||
Reason : ${event.reason ?? 'No reason received'}`);
|
||||
|
||||
this.setHeartbeatTimer(-1);
|
||||
this.setHelloTimeout(-1);
|
||||
@@ -648,7 +648,7 @@ class WebSocketShard extends EventEmitter {
|
||||
* @private
|
||||
*/
|
||||
_send(data) {
|
||||
if (!this.connection || this.connection.readyState !== WebSocket.OPEN) {
|
||||
if (this.connection?.readyState !== WebSocket.OPEN) {
|
||||
this.debug(`Tried to send packet '${JSON.stringify(data)}' but no WebSocket is available!`);
|
||||
this.destroy({ closeCode: 4000 });
|
||||
return;
|
||||
|
||||
@@ -8,7 +8,7 @@ module.exports = (client, { d: data }) => {
|
||||
|
||||
if (channel && !Number.isNaN(time.getTime())) {
|
||||
// Discord sends null for last_pin_timestamp if the last pinned message was removed
|
||||
channel.lastPinTimestamp = time.getTime() || null;
|
||||
channel.lastPinTimestamp = time.getTime() ?? null;
|
||||
|
||||
/**
|
||||
* Emitted whenever the pins of a channel are updated. Due to the nature of the WebSocket event,
|
||||
|
||||
@@ -39,7 +39,7 @@ function message(key, args) {
|
||||
const msg = messages.get(key);
|
||||
if (!msg) throw new Error(`An invalid error message key was used: ${key}.`);
|
||||
if (typeof msg === 'function') return msg(...args);
|
||||
if (args === undefined || args.length === 0) return msg;
|
||||
if (!args?.length) return msg;
|
||||
args.unshift(msg);
|
||||
return String(...args);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ class ApplicationCommandManager extends BaseManager {
|
||||
*/
|
||||
commandPath({ id, guildID } = {}) {
|
||||
let path = this.client.api.applications(this.client.application.id);
|
||||
if (this.guild || guildID) path = path.guilds(this.guild?.id ?? guildID);
|
||||
if (this.guild ?? guildID) path = path.guilds(this.guild?.id ?? guildID);
|
||||
return id ? path.commands(id) : path.commands;
|
||||
}
|
||||
|
||||
@@ -84,9 +84,7 @@ class ApplicationCommandManager extends BaseManager {
|
||||
async fetch(id, { guildID, cache = true, force = false } = {}) {
|
||||
if (typeof id === 'object') {
|
||||
({ guildID, cache = true, force = false } = id);
|
||||
id = undefined;
|
||||
}
|
||||
if (id) {
|
||||
} else if (id) {
|
||||
if (!force) {
|
||||
const existing = this.cache.get(id);
|
||||
if (existing) return existing;
|
||||
|
||||
@@ -67,7 +67,7 @@ class BaseGuildEmojiManager extends BaseManager {
|
||||
if (emoji instanceof ReactionEmoji) return emoji.identifier;
|
||||
if (typeof emoji === 'string') {
|
||||
const res = parseEmoji(emoji);
|
||||
if (res && res.name.length) {
|
||||
if (res?.name.length) {
|
||||
emoji = `${res.animated ? 'a:' : ''}${res.name}${res.id ? `:${res.id}` : ''}`;
|
||||
}
|
||||
if (!emoji.includes('%')) return encodeURIComponent(emoji);
|
||||
|
||||
@@ -17,7 +17,7 @@ class BaseManager {
|
||||
* @private
|
||||
* @readonly
|
||||
*/
|
||||
Object.defineProperty(this, 'holds', { value: Structures.get(holds.name) || holds });
|
||||
Object.defineProperty(this, 'holds', { value: Structures.get(holds.name) ?? holds });
|
||||
|
||||
/**
|
||||
* The client that instantiated this Manager
|
||||
@@ -42,12 +42,12 @@ class BaseManager {
|
||||
}
|
||||
|
||||
add(data, cache = true, { id, extras = [] } = {}) {
|
||||
const existing = this.cache.get(id || data.id);
|
||||
if (existing && existing._patch && cache) existing._patch(data);
|
||||
const existing = this.cache.get(id ?? data.id);
|
||||
if (cache) existing?._patch(data);
|
||||
if (existing) return existing;
|
||||
|
||||
const entry = this.holds ? new this.holds(this.client, data, ...extras) : data;
|
||||
if (cache) this.cache.set(id || entry.id, entry);
|
||||
if (cache) this.cache.set(id ?? entry.id, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ class BaseManager {
|
||||
*/
|
||||
resolve(idOrInstance) {
|
||||
if (idOrInstance instanceof this.holds) return idOrInstance;
|
||||
if (typeof idOrInstance === 'string') return this.cache.get(idOrInstance) || null;
|
||||
if (typeof idOrInstance === 'string') return this.cache.get(idOrInstance) ?? null;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,10 +22,10 @@ class ChannelManager extends BaseManager {
|
||||
add(data, guild, cache = true) {
|
||||
const existing = this.cache.get(data.id);
|
||||
if (existing) {
|
||||
if (existing._patch && cache) existing._patch(data);
|
||||
if (guild) guild.channels?.add(existing);
|
||||
if (ThreadChannelTypes.includes(existing.type) && typeof existing.parent?.threads !== 'undefined') {
|
||||
existing.parent.threads.add(existing);
|
||||
if (cache) existing._patch(data);
|
||||
guild?.channels?.add(existing);
|
||||
if (ThreadChannelTypes.includes(existing.type)) {
|
||||
existing.parent?.threads?.add(existing);
|
||||
}
|
||||
return existing;
|
||||
}
|
||||
|
||||
@@ -115,9 +115,10 @@ class GuildChannelManager extends BaseManager {
|
||||
* ],
|
||||
* })
|
||||
*/
|
||||
async create(name, options = {}) {
|
||||
let { type, topic, nsfw, bitrate, userLimit, parent, permissionOverwrites, position, rateLimitPerUser, reason } =
|
||||
options;
|
||||
async create(
|
||||
name,
|
||||
{ type, topic, nsfw, bitrate, userLimit, parent, permissionOverwrites, position, rateLimitPerUser, reason } = {},
|
||||
) {
|
||||
if (parent) parent = this.client.channels.resolveID(parent);
|
||||
if (permissionOverwrites) {
|
||||
permissionOverwrites = permissionOverwrites.map(o => PermissionOverwrites.resolve(o, this.guild));
|
||||
|
||||
@@ -269,7 +269,7 @@ class GuildMemberManager extends BaseManager {
|
||||
* @example
|
||||
* // Kick a user by ID (or with a user/guild member object)
|
||||
* guild.members.kick('84484653687267328')
|
||||
* .then(user => console.log(`Kicked ${user.username || user.id || user} from ${guild.name}`))
|
||||
* .then(user => console.log(`Kicked ${user.username ?? user.id ?? user} from ${guild.name}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async kick(user, reason) {
|
||||
@@ -356,7 +356,7 @@ class GuildMemberManager extends BaseManager {
|
||||
},
|
||||
});
|
||||
const fetchedMembers = new Collection();
|
||||
const option = query || limit || presences || user_ids;
|
||||
const option = Boolean(query || limit || presences || user_ids);
|
||||
let i = 0;
|
||||
const handler = (members, _, chunk) => {
|
||||
timeout.refresh();
|
||||
|
||||
@@ -68,7 +68,7 @@ class GuildMemberRoleManager {
|
||||
* @readonly
|
||||
*/
|
||||
get premiumSubscriberRole() {
|
||||
return this.cache.find(role => role.tags && role.tags.premiumSubscriberRole) || null;
|
||||
return this.cache.find(role => role.tags?.premiumSubscriberRole) ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,7 +79,7 @@ class GuildMemberRoleManager {
|
||||
*/
|
||||
get botRole() {
|
||||
if (!this.member.user.bot) return null;
|
||||
return this.cache.find(role => role.tags && role.tags.botID === this.member.user.id) || null;
|
||||
return this.cache.find(role => role.tags?.botID === this.member.user.id) ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -150,7 +150,7 @@ class MessageManager extends BaseManager {
|
||||
if (!message) throw new TypeError('INVALID_TYPE', 'message', 'MessageResolvable');
|
||||
|
||||
const data = await this.client.api.channels(this.channel.id).messages(message).crosspost.post();
|
||||
return this.cache.get(data.id) || this.add(data);
|
||||
return this.cache.get(data.id) ?? this.add(data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,7 +40,7 @@ class PresenceManager extends BaseManager {
|
||||
const presenceResolvable = super.resolve(presence);
|
||||
if (presenceResolvable) return presenceResolvable;
|
||||
const UserResolvable = this.client.users.resolveID(presence);
|
||||
return super.resolve(UserResolvable) || null;
|
||||
return super.resolve(UserResolvable);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,7 +19,7 @@ class ReactionManager extends BaseManager {
|
||||
}
|
||||
|
||||
add(data, cache) {
|
||||
return super.add(data, cache, { id: data.emoji.id || data.emoji.name, extras: [this.message] });
|
||||
return super.add(data, cache, { id: data.emoji.id ?? data.emoji.name, extras: [this.message] });
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
class DiscordAPIError extends Error {
|
||||
constructor(error, status, request) {
|
||||
super();
|
||||
const flattened = this.constructor.flattenErrors(error.errors || error).join('\n');
|
||||
const flattened = this.constructor.flattenErrors(error.errors ?? error).join('\n');
|
||||
this.name = 'DiscordAPIError';
|
||||
this.message = error.message && flattened ? `${error.message}\n${flattened}` : error.message || flattened;
|
||||
this.message = error.message && flattened ? `${error.message}\n${flattened}` : error.message ?? flattened;
|
||||
|
||||
/**
|
||||
* The HTTP method used for the request
|
||||
@@ -61,7 +61,7 @@ class DiscordAPIError extends Error {
|
||||
|
||||
if (v._errors) {
|
||||
messages.push(`${newKey}: ${v._errors.map(e => e.message).join(' ')}`);
|
||||
} else if (v.code || v.message) {
|
||||
} else if (v.code ?? v.message) {
|
||||
messages.push(`${v.code ? `${v.code}: ` : ''}${v.message}`.trim());
|
||||
} else if (typeof v === 'string') {
|
||||
messages.push(v);
|
||||
|
||||
@@ -18,7 +18,7 @@ class HTTPError extends Error {
|
||||
* HTTP error code returned from the request
|
||||
* @type {number}
|
||||
*/
|
||||
this.code = code || 500;
|
||||
this.code = code ?? 500;
|
||||
|
||||
/**
|
||||
* The HTTP method used for the request
|
||||
|
||||
@@ -30,7 +30,7 @@ class RESTManager {
|
||||
}
|
||||
|
||||
getAuth() {
|
||||
const token = this.client.token || this.client.accessToken;
|
||||
const token = this.client.token ?? this.client.accessToken;
|
||||
if (token) return `${this.tokenPrefix} ${token}`;
|
||||
throw new Error('TOKEN_MISSING');
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class Shard extends EventEmitter {
|
||||
* Arguments for the shard's process (only when {@link ShardingManager#mode} is `process`)
|
||||
* @type {string[]}
|
||||
*/
|
||||
this.args = manager.shardArgs || [];
|
||||
this.args = manager.shardArgs ?? [];
|
||||
|
||||
/**
|
||||
* Arguments for the shard's process executable (only when {@link ShardingManager#mode} is `process`)
|
||||
@@ -127,14 +127,16 @@ class Shard extends EventEmitter {
|
||||
this._evals.clear();
|
||||
this._fetches.clear();
|
||||
|
||||
const child = this.process ?? this.worker;
|
||||
|
||||
/**
|
||||
* Emitted upon the creation of the shard's child process/worker.
|
||||
* @event Shard#spawn
|
||||
* @param {ChildProcess|Worker} process Child process/worker that was created
|
||||
*/
|
||||
this.emit('spawn', this.process || this.worker);
|
||||
this.emit('spawn', child);
|
||||
|
||||
if (timeout === -1 || timeout === Infinity) return this.process || this.worker;
|
||||
if (timeout === -1 || timeout === Infinity) return child;
|
||||
await new Promise((resolve, reject) => {
|
||||
const cleanup = () => {
|
||||
clearTimeout(spawnTimeoutTimer);
|
||||
@@ -168,7 +170,7 @@ class Shard extends EventEmitter {
|
||||
this.once('disconnect', onDisconnect);
|
||||
this.once('death', onDeath);
|
||||
});
|
||||
return this.process || this.worker;
|
||||
return child;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -242,10 +244,10 @@ class Shard extends EventEmitter {
|
||||
if (this._fetches.has(prop)) return this._fetches.get(prop);
|
||||
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
const child = this.process || this.worker;
|
||||
const child = this.process ?? this.worker;
|
||||
|
||||
const listener = message => {
|
||||
if (!message || message._fetchProp !== prop) return;
|
||||
if (message?._fetchProp !== prop) return;
|
||||
child.removeListener('message', listener);
|
||||
this._fetches.delete(prop);
|
||||
resolve(message._result);
|
||||
@@ -276,10 +278,10 @@ class Shard extends EventEmitter {
|
||||
if (this._evals.has(script)) return this._evals.get(script);
|
||||
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
const child = this.process || this.worker;
|
||||
const child = this.process ?? this.worker;
|
||||
|
||||
const listener = message => {
|
||||
if (!message || message._eval !== script) return;
|
||||
if (message?._eval !== script) return;
|
||||
child.removeListener('message', listener);
|
||||
this._evals.delete(script);
|
||||
if (!message._error) resolve(message._result);
|
||||
@@ -388,7 +390,7 @@ class Shard extends EventEmitter {
|
||||
* @event Shard#death
|
||||
* @param {ChildProcess|Worker} process Child process/worker that exited
|
||||
*/
|
||||
this.emit('death', this.process || this.worker);
|
||||
this.emit('death', this.process ?? this.worker);
|
||||
|
||||
this.ready = false;
|
||||
this.process = null;
|
||||
|
||||
@@ -109,10 +109,10 @@ class ShardClientUtil {
|
||||
*/
|
||||
fetchClientValues(prop, shard) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const parent = this.parentPort || process;
|
||||
const parent = this.parentPort ?? process;
|
||||
|
||||
const listener = message => {
|
||||
if (!message || message._sFetchProp !== prop || message._sFetchPropShard !== shard) return;
|
||||
if (message?._sFetchProp !== prop || message._sFetchPropShard !== shard) return;
|
||||
parent.removeListener('message', listener);
|
||||
if (!message._error) resolve(message._result);
|
||||
else reject(Util.makeError(message._error));
|
||||
@@ -139,7 +139,7 @@ class ShardClientUtil {
|
||||
*/
|
||||
broadcastEval(script, options = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const parent = this.parentPort || process;
|
||||
const parent = this.parentPort ?? process;
|
||||
if (typeof script !== 'function') {
|
||||
reject(new TypeError('SHARDING_INVALID_EVAL_BROADCAST'));
|
||||
return;
|
||||
@@ -147,7 +147,7 @@ class ShardClientUtil {
|
||||
script = `(${script})(this, ${JSON.stringify(options.context)})`;
|
||||
|
||||
const listener = message => {
|
||||
if (!message || message._sEval !== script || message._sEvalShard !== options.shard) return;
|
||||
if (message?._sEval !== script || message._sEvalShard !== options.shard) return;
|
||||
parent.removeListener('message', listener);
|
||||
if (!message._error) resolve(message._result);
|
||||
else reject(Util.makeError(message._error));
|
||||
|
||||
@@ -70,7 +70,7 @@ class ShardingManager extends EventEmitter {
|
||||
* List of shards this sharding manager spawns
|
||||
* @type {string|number[]}
|
||||
*/
|
||||
this.shardList = options.shardList || 'auto';
|
||||
this.shardList = options.shardList ?? 'auto';
|
||||
if (this.shardList !== 'auto') {
|
||||
if (!Array.isArray(this.shardList)) {
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'shardList', 'an array.');
|
||||
@@ -132,7 +132,7 @@ class ShardingManager extends EventEmitter {
|
||||
* Token to use for obtaining the automatic shard count, and passing to shards
|
||||
* @type {?string}
|
||||
*/
|
||||
this.token = options.token ? options.token.replace(/^Bot\s*/i, '') : null;
|
||||
this.token = options.token?.replace(/^Bot\s*/i, '') ?? null;
|
||||
|
||||
/**
|
||||
* A collection of shards that this manager has spawned
|
||||
|
||||
@@ -29,7 +29,7 @@ class Channel extends Base {
|
||||
* * `unknown` - a generic channel of unknown type, could be Channel or GuildChannel
|
||||
* @type {string}
|
||||
*/
|
||||
this.type = type ? type.toLowerCase() : 'unknown';
|
||||
this.type = type?.toLowerCase() ?? 'unknown';
|
||||
|
||||
/**
|
||||
* Whether the channel has been deleted
|
||||
@@ -130,7 +130,8 @@ class Channel extends Base {
|
||||
channel = new PartialGroupDMChannel(client, data);
|
||||
}
|
||||
} else {
|
||||
guild = guild || client.guilds.cache.get(data.guild_id);
|
||||
if (!guild) guild = client.guilds.cache.get(data.guild_id);
|
||||
|
||||
if (guild) {
|
||||
switch (data.type) {
|
||||
case ChannelTypes.TEXT: {
|
||||
|
||||
@@ -10,7 +10,7 @@ class ClientPresence extends Presence {
|
||||
* @param {APIPresence} [data={}] The data for the client presence
|
||||
*/
|
||||
constructor(client, data = {}) {
|
||||
super(client, Object.assign(data, { status: data.status || 'online', user: { id: null } }));
|
||||
super(client, Object.assign(data, { status: data.status ?? 'online', user: { id: null } }));
|
||||
}
|
||||
|
||||
set(presence) {
|
||||
@@ -33,7 +33,7 @@ class ClientPresence extends Presence {
|
||||
activities: [],
|
||||
afk: typeof afk === 'boolean' ? afk : false,
|
||||
since: typeof since === 'number' && !Number.isNaN(since) ? since : null,
|
||||
status: status || this.status,
|
||||
status: status ?? this.status,
|
||||
};
|
||||
if (activities?.length) {
|
||||
for (const [i, activity] of activities.entries()) {
|
||||
|
||||
@@ -56,8 +56,7 @@ class ClientUser extends Structures.get('User') {
|
||||
const newData = await this.client.api.users('@me').patch({ data });
|
||||
this.client.token = newData.token;
|
||||
const { updated } = this.client.actions.UserUpdate.handle(newData);
|
||||
if (updated) return updated;
|
||||
return this;
|
||||
return updated ?? this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -110,17 +110,19 @@ class CommandInteraction extends Interaction {
|
||||
if ('value' in option) result.value = option.value;
|
||||
if ('options' in option) result.options = this._createOptionsCollection(option.options, resolved);
|
||||
|
||||
const user = resolved?.users?.[option.value];
|
||||
if (user) result.user = this.client.users.add(user);
|
||||
if (resolved) {
|
||||
const user = resolved.users?.[option.value];
|
||||
if (user) result.user = this.client.users.add(user);
|
||||
|
||||
const member = resolved?.members?.[option.value];
|
||||
if (member) result.member = this.guild?.members.add({ user, ...member }) ?? member;
|
||||
const member = resolved.members?.[option.value];
|
||||
if (member) result.member = this.guild?.members.add({ user, ...member }) ?? member;
|
||||
|
||||
const channel = resolved?.channels?.[option.value];
|
||||
if (channel) result.channel = this.client.channels.add(channel, this.guild) ?? channel;
|
||||
const channel = resolved.channels?.[option.value];
|
||||
if (channel) result.channel = this.client.channels.add(channel, this.guild) ?? channel;
|
||||
|
||||
const role = resolved?.roles?.[option.value];
|
||||
if (role) result.role = this.guild?.roles.add(role) ?? role;
|
||||
const role = resolved.roles?.[option.value];
|
||||
if (role) result.role = this.guild?.roles.add(role) ?? role;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -59,8 +59,7 @@ class Emoji extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get url() {
|
||||
if (!this.id) return null;
|
||||
return this.client.rest.cdn.Emoji(this.id, this.animated ? 'gif' : 'png');
|
||||
return this.id && this.client.rest.cdn.Emoji(this.id, this.animated ? 'gif' : 'png');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,8 +68,7 @@ class Emoji extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get createdTimestamp() {
|
||||
if (!this.id) return null;
|
||||
return SnowflakeUtil.deconstruct(this.id).timestamp;
|
||||
return this.id && SnowflakeUtil.deconstruct(this.id).timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,8 +77,7 @@ class Emoji extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get createdAt() {
|
||||
if (!this.id) return null;
|
||||
return new Date(this.createdTimestamp);
|
||||
return this.id && new Date(this.createdTimestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -147,13 +147,13 @@ class Guild extends AnonymousGuild {
|
||||
* The full amount of members in this guild
|
||||
* @type {number}
|
||||
*/
|
||||
this.memberCount = data.member_count || this.memberCount;
|
||||
this.memberCount = data.member_count ?? this.memberCount;
|
||||
|
||||
/**
|
||||
* Whether the guild is "large" (has more than large_threshold members, 50 by default)
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.large = Boolean('large' in data ? data.large : this.large);
|
||||
this.large = Boolean(data.large ?? this.large);
|
||||
|
||||
/**
|
||||
* An array of enabled guild features, here are the possible values:
|
||||
@@ -282,7 +282,7 @@ class Guild extends AnonymousGuild {
|
||||
* <info>You will need to fetch the guild using {@link Guild#fetch} if you want to receive this parameter</info>
|
||||
* @type {?number}
|
||||
*/
|
||||
this.maximumPresences = data.max_presences || 25000;
|
||||
this.maximumPresences = data.max_presences ?? 25000;
|
||||
} else if (typeof this.maximumPresences === 'undefined') {
|
||||
this.maximumPresences = null;
|
||||
}
|
||||
@@ -406,8 +406,7 @@ class Guild extends AnonymousGuild {
|
||||
* @returns {?string}
|
||||
*/
|
||||
bannerURL({ format, size } = {}) {
|
||||
if (!this.banner) return null;
|
||||
return this.client.rest.cdn.Banner(this.id, this.banner, format, size);
|
||||
return this.banner && this.client.rest.cdn.Banner(this.id, this.banner, format, size);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -425,8 +424,7 @@ class Guild extends AnonymousGuild {
|
||||
* @returns {?string}
|
||||
*/
|
||||
splashURL({ format, size } = {}) {
|
||||
if (!this.splash) return null;
|
||||
return this.client.rest.cdn.Splash(this.id, this.splash, format, size);
|
||||
return this.splash && this.client.rest.cdn.Splash(this.id, this.splash, format, size);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -435,8 +433,7 @@ class Guild extends AnonymousGuild {
|
||||
* @returns {?string}
|
||||
*/
|
||||
discoverySplashURL({ format, size } = {}) {
|
||||
if (!this.discoverySplash) return null;
|
||||
return this.client.rest.cdn.DiscoverySplash(this.id, this.discoverySplash, format, size);
|
||||
return this.discoverySplash && this.client.rest.cdn.DiscoverySplash(this.id, this.discoverySplash, format, size);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -462,7 +459,7 @@ class Guild extends AnonymousGuild {
|
||||
* @readonly
|
||||
*/
|
||||
get afkChannel() {
|
||||
return this.client.channels.cache.get(this.afkChannelID) || null;
|
||||
return this.client.channels.resolve(this.afkChannelID);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -471,7 +468,7 @@ class Guild extends AnonymousGuild {
|
||||
* @readonly
|
||||
*/
|
||||
get systemChannel() {
|
||||
return this.client.channels.cache.get(this.systemChannelID) || null;
|
||||
return this.client.channels.resolve(this.systemChannelID);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -480,7 +477,7 @@ class Guild extends AnonymousGuild {
|
||||
* @readonly
|
||||
*/
|
||||
get widgetChannel() {
|
||||
return this.client.channels.cache.get(this.widgetChannelID) || null;
|
||||
return this.client.channels.resolve(this.widgetChannelID);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -489,7 +486,7 @@ class Guild extends AnonymousGuild {
|
||||
* @readonly
|
||||
*/
|
||||
get rulesChannel() {
|
||||
return this.client.channels.cache.get(this.rulesChannelID) || null;
|
||||
return this.client.channels.resolve(this.rulesChannelID);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -498,7 +495,7 @@ class Guild extends AnonymousGuild {
|
||||
* @readonly
|
||||
*/
|
||||
get publicUpdatesChannel() {
|
||||
return this.client.channels.cache.get(this.publicUpdatesChannelID) || null;
|
||||
return this.client.channels.resolve(this.publicUpdatesChannelID);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -508,7 +505,7 @@ class Guild extends AnonymousGuild {
|
||||
*/
|
||||
get me() {
|
||||
return (
|
||||
this.members.cache.get(this.client.user.id) ||
|
||||
this.members.resolve(this.client.user.id) ??
|
||||
(this.client.options.partials.includes(PartialTypes.GUILD_MEMBER)
|
||||
? this.members.add({ user: { id: this.client.user.id } }, true)
|
||||
: null)
|
||||
@@ -917,7 +914,7 @@ class Guild extends AnonymousGuild {
|
||||
const welcome_channels = welcomeChannels?.map(welcomeChannelData => {
|
||||
const emoji = this.emojis.resolve(welcomeChannelData.emoji);
|
||||
return {
|
||||
emoji_id: emoji?.id ?? null,
|
||||
emoji_id: emoji && emoji.id,
|
||||
emoji_name: emoji?.name ?? welcomeChannelData.emoji,
|
||||
channel_id: this.channels.resolveID(welcomeChannelData.channel),
|
||||
description: welcomeChannelData.description,
|
||||
|
||||
@@ -332,7 +332,7 @@ class GuildAuditLogsEntry {
|
||||
* The reason of this entry
|
||||
* @type {?string}
|
||||
*/
|
||||
this.reason = data.reason || null;
|
||||
this.reason = data.reason ?? null;
|
||||
|
||||
/**
|
||||
* The user that executed this entry
|
||||
@@ -354,9 +354,9 @@ class GuildAuditLogsEntry {
|
||||
|
||||
/**
|
||||
* Specific property changes
|
||||
* @type {AuditLogChange[]}
|
||||
* @type {?(AuditLogChange[])}
|
||||
*/
|
||||
this.changes = data.changes ? data.changes.map(c => ({ key: c.key, old: c.old_value, new: c.new_value })) : null;
|
||||
this.changes = data.changes?.map(c => ({ key: c.key, old: c.old_value, new: c.new_value })) ?? null;
|
||||
|
||||
/**
|
||||
* The ID of this entry
|
||||
@@ -443,7 +443,7 @@ class GuildAuditLogsEntry {
|
||||
this.target = null;
|
||||
if (targetType === Targets.UNKNOWN) {
|
||||
this.target = this.changes.reduce((o, c) => {
|
||||
o[c.key] = c.new || c.old;
|
||||
o[c.key] = c.new ?? c.old;
|
||||
return o;
|
||||
}, {});
|
||||
this.target.id = data.target_id;
|
||||
@@ -456,12 +456,12 @@ class GuildAuditLogsEntry {
|
||||
this.target = guild.client.guilds.cache.get(data.target_id);
|
||||
} else if (targetType === Targets.WEBHOOK) {
|
||||
this.target =
|
||||
logs.webhooks.get(data.target_id) ||
|
||||
logs.webhooks.get(data.target_id) ??
|
||||
new Webhook(
|
||||
guild.client,
|
||||
this.changes.reduce(
|
||||
(o, c) => {
|
||||
o[c.key] = c.new || c.old;
|
||||
o[c.key] = c.new ?? c.old;
|
||||
return o;
|
||||
},
|
||||
{
|
||||
@@ -473,13 +473,14 @@ class GuildAuditLogsEntry {
|
||||
} else if (targetType === Targets.INVITE) {
|
||||
this.target = guild.members.fetch(guild.client.user.id).then(me => {
|
||||
if (me.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) {
|
||||
const change = this.changes.find(c => c.key === 'code');
|
||||
let change = this.changes.find(c => c.key === 'code');
|
||||
change = change.new ?? change.old;
|
||||
return guild.fetchInvites().then(invites => {
|
||||
this.target = invites.find(i => i.code === (change.new || change.old));
|
||||
this.target = invites.find(i => i.code === change);
|
||||
});
|
||||
} else {
|
||||
this.target = this.changes.reduce((o, c) => {
|
||||
o[c.key] = c.new || c.old;
|
||||
o[c.key] = c.new ?? c.old;
|
||||
return o;
|
||||
}, {});
|
||||
return this.target;
|
||||
@@ -489,16 +490,16 @@ class GuildAuditLogsEntry {
|
||||
// Discord sends a channel id for the MESSAGE_BULK_DELETE action type.
|
||||
this.target =
|
||||
data.action_type === Actions.MESSAGE_BULK_DELETE
|
||||
? guild.channels.cache.get(data.target_id) || { id: data.target_id }
|
||||
? guild.channels.cache.get(data.target_id) ?? { id: data.target_id }
|
||||
: guild.client.users.cache.get(data.target_id);
|
||||
} else if (targetType === Targets.INTEGRATION) {
|
||||
this.target =
|
||||
logs.integrations.get(data.target_id) ||
|
||||
logs.integrations.get(data.target_id) ??
|
||||
new Integration(
|
||||
guild.client,
|
||||
this.changes.reduce(
|
||||
(o, c) => {
|
||||
o[c.key] = c.new || c.old;
|
||||
o[c.key] = c.new ?? c.old;
|
||||
return o;
|
||||
},
|
||||
{ id: data.target_id },
|
||||
@@ -507,10 +508,10 @@ class GuildAuditLogsEntry {
|
||||
);
|
||||
} else if (targetType === Targets.CHANNEL) {
|
||||
this.target =
|
||||
guild.channels.cache.get(data.target_id) ||
|
||||
guild.channels.cache.get(data.target_id) ??
|
||||
this.changes.reduce(
|
||||
(o, c) => {
|
||||
o[c.key] = c.new || c.old;
|
||||
o[c.key] = c.new ?? c.old;
|
||||
return o;
|
||||
},
|
||||
{ id: data.target_id },
|
||||
@@ -522,7 +523,7 @@ class GuildAuditLogsEntry {
|
||||
guild.client,
|
||||
this.changes.reduce(
|
||||
(o, c) => {
|
||||
o[c.key] = c.new || c.old;
|
||||
o[c.key] = c.new ?? c.old;
|
||||
return o;
|
||||
},
|
||||
{
|
||||
@@ -533,7 +534,7 @@ class GuildAuditLogsEntry {
|
||||
),
|
||||
);
|
||||
} else if (data.target_id) {
|
||||
this.target = guild[`${targetType.toLowerCase()}s`]?.cache.get(data.target_id) || { id: data.target_id };
|
||||
this.target = guild[`${targetType.toLowerCase()}s`]?.cache.get(data.target_id) ?? { id: data.target_id };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ class GuildChannel extends Channel {
|
||||
* @readonly
|
||||
*/
|
||||
get parent() {
|
||||
return this.guild.channels.cache.get(this.parentID) || null;
|
||||
return this.guild.channels.resolve(this.parentID);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,10 +106,10 @@ class GuildChannel extends Channel {
|
||||
|
||||
// Handle empty overwrite
|
||||
if (
|
||||
(channelVal === undefined &&
|
||||
(!channelVal &&
|
||||
parentVal.deny.bitfield === Permissions.defaultBit &&
|
||||
parentVal.allow.bitfield === Permissions.defaultBit) ||
|
||||
(parentVal === undefined &&
|
||||
(!parentVal &&
|
||||
channelVal.deny.bitfield === Permissions.defaultBit &&
|
||||
channelVal.allow.bitfield === Permissions.defaultBit)
|
||||
) {
|
||||
@@ -118,8 +118,8 @@ class GuildChannel extends Channel {
|
||||
|
||||
// Compare overwrites
|
||||
return (
|
||||
channelVal !== undefined &&
|
||||
parentVal !== undefined &&
|
||||
typeof channelVal !== 'undefined' &&
|
||||
typeof parentVal !== 'undefined' &&
|
||||
channelVal.deny.bitfield === parentVal.deny.bitfield &&
|
||||
channelVal.allow.bitfield === parentVal.allow.bitfield
|
||||
);
|
||||
@@ -145,15 +145,14 @@ class GuildChannel extends Channel {
|
||||
const member = this.guild.members.resolve(memberOrRole);
|
||||
if (member) return this.memberPermissions(member);
|
||||
const role = this.guild.roles.resolve(memberOrRole);
|
||||
if (role) return this.rolePermissions(role);
|
||||
return null;
|
||||
return role && this.rolePermissions(role);
|
||||
}
|
||||
|
||||
overwritesFor(member, verified = false, roles = null) {
|
||||
if (!verified) member = this.guild.members.resolve(member);
|
||||
if (!member) return [];
|
||||
|
||||
roles = roles || member.roles.cache;
|
||||
if (!roles) roles = member.roles.cache;
|
||||
const roleOverwrites = [];
|
||||
let memberOverwrites;
|
||||
let everyoneOverwrites;
|
||||
@@ -192,20 +191,12 @@ class GuildChannel extends Channel {
|
||||
const overwrites = this.overwritesFor(member, true, roles);
|
||||
|
||||
return permissions
|
||||
.remove(overwrites.everyone ? overwrites.everyone.deny : Permissions.defaultBit)
|
||||
.add(overwrites.everyone ? overwrites.everyone.allow : Permissions.defaultBit)
|
||||
.remove(
|
||||
overwrites.roles.length > Permissions.defaultBit
|
||||
? overwrites.roles.map(role => role.deny)
|
||||
: Permissions.defaultBit,
|
||||
)
|
||||
.add(
|
||||
overwrites.roles.length > Permissions.defaultBit
|
||||
? overwrites.roles.map(role => role.allow)
|
||||
: Permissions.defaultBit,
|
||||
)
|
||||
.remove(overwrites.member ? overwrites.member.deny : Permissions.defaultBit)
|
||||
.add(overwrites.member ? overwrites.member.allow : Permissions.defaultBit)
|
||||
.remove(overwrites.everyone?.deny ?? Permissions.defaultBit)
|
||||
.add(overwrites.everyone?.allow ?? Permissions.defaultBit)
|
||||
.remove(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.deny) : Permissions.defaultBit)
|
||||
.add(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.allow) : Permissions.defaultBit)
|
||||
.remove(overwrites.member?.deny ?? Permissions.defaultBit)
|
||||
.add(overwrites.member?.allow ?? Permissions.defaultBit)
|
||||
.freeze();
|
||||
}
|
||||
|
||||
@@ -222,10 +213,10 @@ class GuildChannel extends Channel {
|
||||
const roleOverwrites = this.permissionOverwrites.get(role.id);
|
||||
|
||||
return role.permissions
|
||||
.remove(everyoneOverwrites ? everyoneOverwrites.deny : Permissions.defaultBit)
|
||||
.add(everyoneOverwrites ? everyoneOverwrites.allow : Permissions.defaultBit)
|
||||
.remove(roleOverwrites ? roleOverwrites.deny : Permissions.defaultBit)
|
||||
.add(roleOverwrites ? roleOverwrites.allow : Permissions.defaultBit)
|
||||
.remove(everyoneOverwrites?.deny ?? Permissions.defaultBit)
|
||||
.add(everyoneOverwrites?.allow ?? Permissions.defaultBit)
|
||||
.remove(roleOverwrites?.deny ?? Permissions.defaultBit)
|
||||
.add(roleOverwrites?.allow ?? Permissions.defaultBit)
|
||||
.freeze();
|
||||
}
|
||||
|
||||
@@ -274,7 +265,7 @@ class GuildChannel extends Channel {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async updateOverwrite(userOrRole, options, overwriteOptions = {}) {
|
||||
const userOrRoleID = this.guild.roles.resolveID(userOrRole) || this.client.users.resolveID(userOrRole);
|
||||
const userOrRoleID = this.guild.roles.resolveID(userOrRole) ?? this.client.users.resolveID(userOrRole);
|
||||
const { reason } = overwriteOptions;
|
||||
const existing = this.permissionOverwrites.get(userOrRoleID);
|
||||
if (existing) {
|
||||
@@ -300,10 +291,10 @@ class GuildChannel extends Channel {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
createOverwrite(userOrRole, options, overwriteOptions = {}) {
|
||||
let userOrRoleID = this.guild.roles.resolveID(userOrRole) || this.client.users.resolveID(userOrRole);
|
||||
let userOrRoleID = this.guild.roles.resolveID(userOrRole) ?? this.client.users.resolveID(userOrRole);
|
||||
let { type, reason } = overwriteOptions;
|
||||
if (typeof type !== 'number') {
|
||||
userOrRole = this.guild.roles.resolve(userOrRole) || this.client.users.resolve(userOrRole);
|
||||
userOrRole = this.guild.roles.resolve(userOrRole) ?? this.client.users.resolve(userOrRole);
|
||||
if (!userOrRole) return Promise.reject(new TypeError('INVALID_TYPE', 'parameter', 'User nor a Role'));
|
||||
userOrRoleID = userOrRole.id;
|
||||
type = userOrRole instanceof Role ? OverwriteTypes.role : OverwriteTypes.member;
|
||||
@@ -410,7 +401,7 @@ class GuildChannel extends Channel {
|
||||
if (data.lockPermissions) {
|
||||
if (data.parentID) {
|
||||
const newParent = this.guild.channels.resolve(data.parentID);
|
||||
if (newParent && newParent.type === 'category') {
|
||||
if (newParent?.type === 'category') {
|
||||
permission_overwrites = newParent.permissionOverwrites.map(o => PermissionOverwrites.resolve(o, this.guild));
|
||||
}
|
||||
} else if (this.parent) {
|
||||
@@ -420,13 +411,13 @@ class GuildChannel extends Channel {
|
||||
|
||||
const newData = await this.client.api.channels(this.id).patch({
|
||||
data: {
|
||||
name: (data.name || this.name).trim(),
|
||||
name: (data.name ?? this.name).trim(),
|
||||
type: ChannelTypes[data.type?.toUpperCase()],
|
||||
topic: data.topic,
|
||||
nsfw: data.nsfw,
|
||||
bitrate: data.bitrate || this.bitrate,
|
||||
user_limit: typeof data.userLimit !== 'undefined' ? data.userLimit : this.userLimit,
|
||||
rtc_region: typeof data.rtcRegion !== 'undefined' ? data.rtcRegion : this.rtcRegion,
|
||||
bitrate: data.bitrate ?? this.bitrate,
|
||||
user_limit: data.userLimit ?? this.userLimit,
|
||||
rtc_region: data.rtcRegion ?? this.rtcRegion,
|
||||
parent_id: data.parentID,
|
||||
lock_permissions: data.lockPermissions,
|
||||
rate_limit_per_user: data.rateLimitPerUser,
|
||||
@@ -476,7 +467,7 @@ class GuildChannel extends Channel {
|
||||
return this.edit(
|
||||
{
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
parentID: channel !== null ? (channel.hasOwnProperty('id') ? channel.id : channel) : null,
|
||||
parentID: channel?.id ?? channel ?? null,
|
||||
lockPermissions,
|
||||
},
|
||||
reason,
|
||||
|
||||
@@ -108,7 +108,7 @@ class GuildEmoji extends BaseGuildEmoji {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
edit(data, reason) {
|
||||
const roles = data.roles ? data.roles.map(r => r.id || r) : undefined;
|
||||
const roles = data.roles?.map(r => r.id ?? r);
|
||||
return this.client.api
|
||||
.guilds(this.guild.id)
|
||||
.emojis(this.id)
|
||||
|
||||
@@ -85,7 +85,7 @@ class GuildMember extends Base {
|
||||
if ('nick' in data) this.nickname = data.nick;
|
||||
if ('joined_at' in data) this.joinedTimestamp = new Date(data.joined_at).getTime();
|
||||
if ('premium_since' in data) {
|
||||
this.premiumSinceTimestamp = data.premium_since === null ? null : new Date(data.premium_since).getTime();
|
||||
this.premiumSinceTimestamp = data.premium_since ? new Date(data.premium_since).getTime() : null;
|
||||
}
|
||||
if ('roles' in data) this._roles = data.roles;
|
||||
this.pending = data.pending ?? false;
|
||||
@@ -121,8 +121,7 @@ class GuildMember extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get lastMessage() {
|
||||
const channel = this.guild.channels.cache.get(this.lastMessageChannelID);
|
||||
return (channel && channel.messages.cache.get(this.lastMessageID)) || null;
|
||||
return this.guild.channels.resolve(this.lastMessageChannelID)?.messages.resolve(this.lastMessageID) ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,7 +132,7 @@ class GuildMember extends Base {
|
||||
get voice() {
|
||||
if (!Structures) Structures = require('../util/Structures');
|
||||
const VoiceState = Structures.get('VoiceState');
|
||||
return this.guild.voiceStates.cache.get(this.id) || new VoiceState(this.guild, { user_id: this.id });
|
||||
return this.guild.voiceStates.cache.get(this.id) ?? new VoiceState(this.guild, { user_id: this.id });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,7 +162,7 @@ class GuildMember extends Base {
|
||||
if (!Structures) Structures = require('../util/Structures');
|
||||
const Presence = Structures.get('Presence');
|
||||
return (
|
||||
this.guild.presences.cache.get(this.id) ||
|
||||
this.guild.presences.cache.get(this.id) ??
|
||||
new Presence(this.client, {
|
||||
user: {
|
||||
id: this.id,
|
||||
@@ -179,8 +178,7 @@ class GuildMember extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get displayColor() {
|
||||
const role = this.roles.color;
|
||||
return (role && role.color) || 0;
|
||||
return this.roles.color?.color ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,8 +187,7 @@ class GuildMember extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get displayHexColor() {
|
||||
const role = this.roles.color;
|
||||
return (role && role.hexColor) || '#000000';
|
||||
return this.roles.color?.hexColor ?? '#000000';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,7 +205,7 @@ class GuildMember extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get displayName() {
|
||||
return this.nickname || this.user.username;
|
||||
return this.nickname ?? this.user.username;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -75,7 +75,7 @@ class GuildPreview extends Base {
|
||||
* The description for this guild
|
||||
* @type {?string}
|
||||
*/
|
||||
this.description = data.description || null;
|
||||
this.description = data.description ?? null;
|
||||
|
||||
if (!this.emojis) {
|
||||
/**
|
||||
@@ -97,8 +97,7 @@ class GuildPreview extends Base {
|
||||
* @returns {?string}
|
||||
*/
|
||||
splashURL({ format, size } = {}) {
|
||||
if (!this.splash) return null;
|
||||
return this.client.rest.cdn.Splash(this.id, this.splash, format, size);
|
||||
return this.splash && this.client.rest.cdn.Splash(this.id, this.splash, format, size);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,8 +106,7 @@ class GuildPreview extends Base {
|
||||
* @returns {?string}
|
||||
*/
|
||||
discoverySplashURL({ format, size } = {}) {
|
||||
if (!this.discoverySplash) return null;
|
||||
return this.client.rest.cdn.DiscoverySplash(this.id, this.discoverySplash, format, size);
|
||||
return this.discoverySplash && this.client.rest.cdn.DiscoverySplash(this.id, this.discoverySplash, format, size);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,8 +115,7 @@ class GuildPreview extends Base {
|
||||
* @returns {?string}
|
||||
*/
|
||||
iconURL({ format, size, dynamic } = {}) {
|
||||
if (!this.icon) return null;
|
||||
return this.client.rest.cdn.Icon(this.id, this.icon, format, size, dynamic);
|
||||
return this.icon && this.client.rest.cdn.Icon(this.id, this.icon, format, size, dynamic);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -202,7 +202,7 @@ class GuildTemplate extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get guild() {
|
||||
return this.client.guilds.cache.get(this.guildID) || null;
|
||||
return this.client.guilds.resolve(this.guildID);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -90,7 +90,7 @@ class Integration extends Base {
|
||||
*/
|
||||
get roles() {
|
||||
const roles = this.guild.roles.cache;
|
||||
return roles.filter(role => role.tags && role.tags.integrationID === this.id);
|
||||
return roles.filter(role => role.tags?.integrationID === this.id);
|
||||
}
|
||||
|
||||
_patch(data) {
|
||||
|
||||
@@ -40,37 +40,37 @@ class Invite extends Base {
|
||||
* The approximate number of online members of the guild this invite is for
|
||||
* @type {?number}
|
||||
*/
|
||||
this.presenceCount = 'approximate_presence_count' in data ? data.approximate_presence_count : null;
|
||||
this.presenceCount = data.approximate_presence_count ?? null;
|
||||
|
||||
/**
|
||||
* The approximate total number of members of the guild this invite is for
|
||||
* @type {?number}
|
||||
*/
|
||||
this.memberCount = 'approximate_member_count' in data ? data.approximate_member_count : null;
|
||||
this.memberCount = data.approximate_member_count ?? null;
|
||||
|
||||
/**
|
||||
* Whether or not this invite is temporary
|
||||
* @type {?boolean}
|
||||
*/
|
||||
this.temporary = 'temporary' in data ? data.temporary : null;
|
||||
this.temporary = data.temporary ?? null;
|
||||
|
||||
/**
|
||||
* The maximum age of the invite, in seconds, 0 if never expires
|
||||
* @type {?number}
|
||||
*/
|
||||
this.maxAge = 'max_age' in data ? data.max_age : null;
|
||||
this.maxAge = data.max_age ?? null;
|
||||
|
||||
/**
|
||||
* How many times this invite has been used
|
||||
* @type {?number}
|
||||
*/
|
||||
this.uses = 'uses' in data ? data.uses : null;
|
||||
this.uses = data.uses ?? null;
|
||||
|
||||
/**
|
||||
* The maximum uses of this invite
|
||||
* @type {?number}
|
||||
*/
|
||||
this.maxUses = 'max_uses' in data ? data.max_uses : null;
|
||||
this.maxUses = data.max_uses ?? null;
|
||||
|
||||
/**
|
||||
* The user who created this invite
|
||||
@@ -103,7 +103,7 @@ class Invite extends Base {
|
||||
* The target type
|
||||
* @type {?TargetType}
|
||||
*/
|
||||
this.targetType = typeof data.target_type === 'number' ? data.target_type : null;
|
||||
this.targetType = data.target_type ?? null;
|
||||
|
||||
/**
|
||||
* The channel the invite is for
|
||||
|
||||
@@ -133,13 +133,13 @@ class Message extends Base {
|
||||
* A list of embeds in the message - e.g. YouTube Player
|
||||
* @type {MessageEmbed[]}
|
||||
*/
|
||||
this.embeds = (data.embeds || []).map(e => new Embed(e, true));
|
||||
this.embeds = data.embeds?.map(e => new Embed(e, true)) ?? [];
|
||||
|
||||
/**
|
||||
* A list of MessageActionRows in the message
|
||||
* @type {MessageActionRow[]}
|
||||
*/
|
||||
this.components = (data.components ?? []).map(c => BaseMessageComponent.create(c, this.client));
|
||||
this.components = data.components?.map(c => BaseMessageComponent.create(c, this.client)) ?? [];
|
||||
|
||||
/**
|
||||
* A collection of attachments in the message - e.g. Pictures - mapped by their ID
|
||||
@@ -180,7 +180,7 @@ class Message extends Base {
|
||||
* @type {ReactionManager}
|
||||
*/
|
||||
this.reactions = new ReactionManager(this);
|
||||
if (data.reactions && data.reactions.length > 0) {
|
||||
if (data.reactions?.length > 0) {
|
||||
for (const reaction of data.reactions) {
|
||||
this.reactions.add(reaction);
|
||||
}
|
||||
@@ -203,7 +203,7 @@ class Message extends Base {
|
||||
* ID of the webhook that sent the message, if applicable
|
||||
* @type {?Snowflake}
|
||||
*/
|
||||
this.webhookID = data.webhook_id || null;
|
||||
this.webhookID = data.webhook_id ?? null;
|
||||
|
||||
/**
|
||||
* Supplemental application information for group activities
|
||||
@@ -312,10 +312,6 @@ class Message extends Base {
|
||||
if ('pinned' in data) this.pinned = data.pinned;
|
||||
if ('tts' in data) this.tts = data.tts;
|
||||
if ('thread' in data) this.thread = this.client.channels.add(data.thread);
|
||||
if ('embeds' in data) this.embeds = data.embeds.map(e => new Embed(e, true));
|
||||
else this.embeds = this.embeds.slice();
|
||||
if ('components' in data) this.components = data.components.map(c => BaseMessageComponent.create(c, this.client));
|
||||
else this.components = this.components.slice();
|
||||
|
||||
if ('attachments' in data) {
|
||||
this.attachments = new Collection();
|
||||
@@ -326,16 +322,19 @@ class Message extends Base {
|
||||
this.attachments = new Collection(this.attachments);
|
||||
}
|
||||
|
||||
this.embeds = data.embeds?.map(e => new Embed(e, true)) ?? this.embeds.slice();
|
||||
this.components = data.components?.map(c => BaseMessageComponent.create(c, this.client)) ?? this.components.slice();
|
||||
|
||||
this.mentions = new Mentions(
|
||||
this,
|
||||
'mentions' in data ? data.mentions : this.mentions.users,
|
||||
'mention_roles' in data ? data.mention_roles : this.mentions.roles,
|
||||
'mention_everyone' in data ? data.mention_everyone : this.mentions.everyone,
|
||||
'mention_channels' in data ? data.mention_channels : this.mentions.crosspostedChannels,
|
||||
data.mentions ?? this.mentions.users,
|
||||
data.mention_roles ?? this.mentions.roles,
|
||||
data.mention_everyone ?? this.mentions.everyone,
|
||||
data.mention_channels ?? this.mentions.crosspostedChannels,
|
||||
data.referenced_message?.author ?? this.mentions.repliedUser,
|
||||
);
|
||||
|
||||
this.flags = new MessageFlags('flags' in data ? data.flags : 0).freeze();
|
||||
this.flags = new MessageFlags(data.flags ?? 0).freeze();
|
||||
|
||||
return clone;
|
||||
}
|
||||
@@ -347,7 +346,7 @@ class Message extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get member() {
|
||||
return this.guild ? this.guild.members.resolve(this.author) || null : null;
|
||||
return this.guild?.members.resolve(this.author) ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -374,7 +373,7 @@ class Message extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get guild() {
|
||||
return this.channel.guild || null;
|
||||
return this.channel.guild ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -434,7 +433,7 @@ class Message extends Base {
|
||||
return new Promise((resolve, reject) => {
|
||||
const collector = this.createReactionCollector(options);
|
||||
collector.once('end', (reactions, reason) => {
|
||||
if (options.errors && options.errors.includes(reason)) reject(reactions);
|
||||
if (options.errors?.includes(reason)) reject(reactions);
|
||||
else resolve(reactions);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -45,7 +45,7 @@ class MessageActionRow extends BaseMessageComponent {
|
||||
* The components in this action row
|
||||
* @type {MessageActionRowComponent[]}
|
||||
*/
|
||||
this.components = (data.components ?? []).map(c => BaseMessageComponent.create(c, null, true));
|
||||
this.components = data.components?.map(c => BaseMessageComponent.create(c, null, true)) ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -72,13 +72,13 @@ class MessageAttachment {
|
||||
* The height of this attachment (if an image or video)
|
||||
* @type {?number}
|
||||
*/
|
||||
this.height = typeof data.height !== 'undefined' ? data.height : null;
|
||||
this.height = data.height ?? null;
|
||||
|
||||
/**
|
||||
* The width of this attachment (if an image or video)
|
||||
* @type {?number}
|
||||
*/
|
||||
this.width = typeof data.width !== 'undefined' ? data.width : null;
|
||||
this.width = data.width ?? null;
|
||||
|
||||
/**
|
||||
* This media type of this attachment
|
||||
|
||||
@@ -114,7 +114,7 @@ class MessageCollector extends Collector {
|
||||
* @returns {void}
|
||||
*/
|
||||
_handleGuildDeletion(guild) {
|
||||
if (this.channel.guild && guild.id === this.channel.guild.id) {
|
||||
if (guild.id === this.channel.guild?.id) {
|
||||
this.stop('guildDelete');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ class MessageComponentInteractionCollector extends Collector {
|
||||
* The source channel from which to collect message component interactions
|
||||
* @type {TextChannel|DMChannel|NewsChannel}
|
||||
*/
|
||||
this.channel = this.message ? this.message.channel : source;
|
||||
this.channel = this.message?.channel ?? source;
|
||||
|
||||
/**
|
||||
* The users which have interacted to components on this collector
|
||||
|
||||
@@ -46,25 +46,25 @@ class MessageEmbed {
|
||||
* @type {string}
|
||||
* @deprecated
|
||||
*/
|
||||
this.type = data.type || 'rich';
|
||||
this.type = data.type ?? 'rich';
|
||||
|
||||
/**
|
||||
* The title of this embed
|
||||
* @type {?string}
|
||||
*/
|
||||
this.title = 'title' in data ? data.title : null;
|
||||
this.title = data.title ?? null;
|
||||
|
||||
/**
|
||||
* The description of this embed
|
||||
* @type {?string}
|
||||
*/
|
||||
this.description = 'description' in data ? data.description : null;
|
||||
this.description = data.description ?? null;
|
||||
|
||||
/**
|
||||
* The URL of this embed
|
||||
* @type {?string}
|
||||
*/
|
||||
this.url = 'url' in data ? data.url : null;
|
||||
this.url = data.url ?? null;
|
||||
|
||||
/**
|
||||
* The color of this embed
|
||||
@@ -111,7 +111,7 @@ class MessageEmbed {
|
||||
this.thumbnail = data.thumbnail
|
||||
? {
|
||||
url: data.thumbnail.url,
|
||||
proxyURL: data.thumbnail.proxyURL || data.thumbnail.proxy_url,
|
||||
proxyURL: data.thumbnail.proxyURL ?? data.thumbnail.proxy_url,
|
||||
height: data.thumbnail.height,
|
||||
width: data.thumbnail.width,
|
||||
}
|
||||
@@ -133,7 +133,7 @@ class MessageEmbed {
|
||||
this.image = data.image
|
||||
? {
|
||||
url: data.image.url,
|
||||
proxyURL: data.image.proxyURL || data.image.proxy_url,
|
||||
proxyURL: data.image.proxyURL ?? data.image.proxy_url,
|
||||
height: data.image.height,
|
||||
width: data.image.width,
|
||||
}
|
||||
@@ -156,7 +156,7 @@ class MessageEmbed {
|
||||
this.video = data.video
|
||||
? {
|
||||
url: data.video.url,
|
||||
proxyURL: data.video.proxyURL || data.video.proxy_url,
|
||||
proxyURL: data.video.proxyURL ?? data.video.proxy_url,
|
||||
height: data.video.height,
|
||||
width: data.video.width,
|
||||
}
|
||||
@@ -179,8 +179,8 @@ class MessageEmbed {
|
||||
? {
|
||||
name: data.author.name,
|
||||
url: data.author.url,
|
||||
iconURL: data.author.iconURL || data.author.icon_url,
|
||||
proxyIconURL: data.author.proxyIconURL || data.author.proxy_icon_url,
|
||||
iconURL: data.author.iconURL ?? data.author.icon_url,
|
||||
proxyIconURL: data.author.proxyIconURL ?? data.author.proxy_icon_url,
|
||||
}
|
||||
: null;
|
||||
|
||||
@@ -217,8 +217,8 @@ class MessageEmbed {
|
||||
this.footer = data.footer
|
||||
? {
|
||||
text: data.footer.text,
|
||||
iconURL: data.footer.iconURL || data.footer.icon_url,
|
||||
proxyIconURL: data.footer.proxyIconURL || data.footer.proxy_icon_url,
|
||||
iconURL: data.footer.iconURL ?? data.footer.icon_url,
|
||||
proxyIconURL: data.footer.proxyIconURL ?? data.footer.proxy_icon_url,
|
||||
}
|
||||
: null;
|
||||
}
|
||||
@@ -395,24 +395,20 @@ class MessageEmbed {
|
||||
type: 'rich',
|
||||
description: this.description,
|
||||
url: this.url,
|
||||
timestamp: this.timestamp ? new Date(this.timestamp) : null,
|
||||
timestamp: this.timestamp && new Date(this.timestamp),
|
||||
color: this.color,
|
||||
fields: this.fields,
|
||||
thumbnail: this.thumbnail,
|
||||
image: this.image,
|
||||
author: this.author
|
||||
? {
|
||||
name: this.author.name,
|
||||
url: this.author.url,
|
||||
icon_url: this.author.iconURL,
|
||||
}
|
||||
: null,
|
||||
footer: this.footer
|
||||
? {
|
||||
text: this.footer.text,
|
||||
icon_url: this.footer.iconURL,
|
||||
}
|
||||
: null,
|
||||
author: this.author && {
|
||||
name: this.author.name,
|
||||
url: this.author.url,
|
||||
icon_url: this.author.iconURL,
|
||||
},
|
||||
footer: this.footer && {
|
||||
text: this.footer.text,
|
||||
icon_url: this.footer.iconURL,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -447,11 +443,7 @@ class MessageEmbed {
|
||||
return fields
|
||||
.flat(2)
|
||||
.map(field =>
|
||||
this.normalizeField(
|
||||
field && field.name,
|
||||
field && field.value,
|
||||
field && typeof field.inline === 'boolean' ? field.inline : false,
|
||||
),
|
||||
this.normalizeField(field.name, field.value, typeof field.inline === 'boolean' ? field.inline : false),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ class MessageMentions {
|
||||
this.crosspostedChannels.set(d.id, {
|
||||
channelID: d.id,
|
||||
guildID: d.guild_id,
|
||||
type: type ? type.toLowerCase() : 'unknown',
|
||||
type: type?.toLowerCase() ?? 'unknown',
|
||||
name: d.name,
|
||||
});
|
||||
}
|
||||
@@ -191,11 +191,9 @@ class MessageMentions {
|
||||
|
||||
if (!ignoreDirect) {
|
||||
const id =
|
||||
this.client.users.resolveID(data) ||
|
||||
(this.guild && this.guild.roles.resolveID(data)) ||
|
||||
this.client.channels.resolveID(data);
|
||||
this.guild?.roles.resolveID(data) ?? this.client.channels.resolveID(data) ?? this.client.users.resolveID(data);
|
||||
|
||||
return this.users.has(id) || this.channels.has(id) || this.roles.has(id);
|
||||
return typeof id === 'string' && (this.users.has(id) || this.channels.has(id) || this.roles.has(id));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -147,7 +147,7 @@ class MessagePayload {
|
||||
let username;
|
||||
let avatarURL;
|
||||
if (isWebhook) {
|
||||
username = this.options.username || this.target.name;
|
||||
username = this.options.username ?? this.target.name;
|
||||
if (this.options.avatarURL) avatarURL = this.options.avatarURL;
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ class MessagePayload {
|
||||
name = findName(attachment);
|
||||
} else {
|
||||
attachment = fileLike.attachment;
|
||||
name = fileLike.name || findName(attachment);
|
||||
name = fileLike.name ?? findName(attachment);
|
||||
}
|
||||
|
||||
const resource = await DataResolver.resolveFile(attachment);
|
||||
|
||||
@@ -105,9 +105,9 @@ class MessageReaction {
|
||||
*/
|
||||
async fetch() {
|
||||
const message = await this.message.fetch();
|
||||
const existing = message.reactions.cache.get(this.emoji.id || this.emoji.name);
|
||||
const existing = message.reactions.cache.get(this.emoji.id ?? this.emoji.name);
|
||||
// The reaction won't get set when it has been completely removed
|
||||
this._patch(existing || { count: 0 });
|
||||
this._patch(existing ?? { count: 0 });
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ class MessageReaction {
|
||||
if (!this.me || user.id !== this.message.client.user.id) this.count--;
|
||||
if (user.id === this.message.client.user.id) this.me = false;
|
||||
if (this.count <= 0 && this.users.cache.size === 0) {
|
||||
this.message.reactions.cache.delete(this.emoji.id || this.emoji.name);
|
||||
this.message.reactions.cache.delete(this.emoji.id ?? this.emoji.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,8 +30,7 @@ class PartialGroupDMChannel extends Channel {
|
||||
* @returns {?string}
|
||||
*/
|
||||
iconURL({ format, size } = {}) {
|
||||
if (!this.icon) return null;
|
||||
return this.client.rest.cdn.GDMIcon(this.id, this.icon, format, size);
|
||||
return this.icon && this.client.rest.cdn.GDMIcon(this.id, this.icon, format, size);
|
||||
}
|
||||
|
||||
delete() {
|
||||
|
||||
@@ -181,7 +181,7 @@ class PermissionOverwrites {
|
||||
};
|
||||
}
|
||||
|
||||
const userOrRole = guild.roles.resolve(overwrite.id) || guild.client.users.resolve(overwrite.id);
|
||||
const userOrRole = guild.roles.resolve(overwrite.id) ?? guild.client.users.resolve(overwrite.id);
|
||||
if (!userOrRole) throw new TypeError('INVALID_TYPE', 'parameter', 'User nor a Role');
|
||||
const type = userOrRole instanceof Role ? OverwriteTypes.role : OverwriteTypes.member;
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ class Presence {
|
||||
* The guild of this presence
|
||||
* @type {?Guild}
|
||||
*/
|
||||
this.guild = data.guild || null;
|
||||
this.guild = data.guild ?? null;
|
||||
|
||||
this.patch(data);
|
||||
}
|
||||
@@ -66,7 +66,7 @@ class Presence {
|
||||
* @readonly
|
||||
*/
|
||||
get user() {
|
||||
return this.client.users.cache.get(this.userID) || null;
|
||||
return this.client.users.resolve(this.userID);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,7 +75,7 @@ class Presence {
|
||||
* @readonly
|
||||
*/
|
||||
get member() {
|
||||
return this.guild.members.cache.get(this.userID) || null;
|
||||
return this.guild.members.resolve(this.userID);
|
||||
}
|
||||
|
||||
patch(data) {
|
||||
@@ -83,19 +83,13 @@ class Presence {
|
||||
* The status of this presence
|
||||
* @type {PresenceStatus}
|
||||
*/
|
||||
this.status = data.status || this.status || 'offline';
|
||||
this.status = data.status ?? this.status ?? 'offline';
|
||||
|
||||
if (data.activities) {
|
||||
/**
|
||||
* The activities of this presence
|
||||
* @type {Activity[]}
|
||||
*/
|
||||
this.activities = data.activities.map(activity => new Activity(this, activity));
|
||||
} else if (data.activity || data.game) {
|
||||
this.activities = [new Activity(this, data.game || data.activity)];
|
||||
} else {
|
||||
this.activities = [];
|
||||
}
|
||||
/**
|
||||
* The activities of this presence
|
||||
* @type {Activity[]}
|
||||
*/
|
||||
this.activities = data.activities?.map(activity => new Activity(this, activity)) ?? [];
|
||||
|
||||
/**
|
||||
* The devices this presence is on
|
||||
@@ -104,14 +98,14 @@ class Presence {
|
||||
* @property {?ClientPresenceStatus} mobile The current presence in the mobile application
|
||||
* @property {?ClientPresenceStatus} desktop The current presence in the desktop application
|
||||
*/
|
||||
this.clientStatus = data.client_status || null;
|
||||
this.clientStatus = data.client_status ?? null;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
_clone() {
|
||||
const clone = Object.assign(Object.create(this), this);
|
||||
if (this.activities) clone.activities = this.activities.map(activity => activity._clone());
|
||||
clone.activities = this.activities.map(activity => activity._clone());
|
||||
return clone;
|
||||
}
|
||||
|
||||
@@ -127,9 +121,9 @@ class Presence {
|
||||
this.status === presence.status &&
|
||||
this.activities.length === presence.activities.length &&
|
||||
this.activities.every((activity, index) => activity.equals(presence.activities[index])) &&
|
||||
this.clientStatus.web === presence.clientStatus.web &&
|
||||
this.clientStatus.mobile === presence.clientStatus.mobile &&
|
||||
this.clientStatus.desktop === presence.clientStatus.desktop)
|
||||
this.clientStatus?.web === presence.clientStatus?.web &&
|
||||
this.clientStatus?.mobile === presence.clientStatus?.mobile &&
|
||||
this.clientStatus?.desktop === presence.clientStatus?.desktop)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -175,25 +169,25 @@ class Activity {
|
||||
* If the activity is being streamed, a link to the stream
|
||||
* @type {?string}
|
||||
*/
|
||||
this.url = data.url || null;
|
||||
this.url = data.url ?? null;
|
||||
|
||||
/**
|
||||
* Details about the activity
|
||||
* @type {?string}
|
||||
*/
|
||||
this.details = data.details || null;
|
||||
this.details = data.details ?? null;
|
||||
|
||||
/**
|
||||
* State of the activity
|
||||
* @type {?string}
|
||||
*/
|
||||
this.state = data.state || null;
|
||||
this.state = data.state ?? null;
|
||||
|
||||
/**
|
||||
* Application ID associated with this activity
|
||||
* @type {?Snowflake}
|
||||
*/
|
||||
this.applicationID = data.application_id || null;
|
||||
this.applicationID = data.application_id ?? null;
|
||||
|
||||
/**
|
||||
* Timestamps for the activity
|
||||
@@ -226,7 +220,7 @@ class Activity {
|
||||
* @property {?string} id ID of the party
|
||||
* @property {number[]} size Size of the party as `[current, max]`
|
||||
*/
|
||||
this.party = data.party || null;
|
||||
this.party = data.party ?? null;
|
||||
|
||||
/**
|
||||
* Assets for rich presence
|
||||
@@ -315,25 +309,25 @@ class RichPresenceAssets {
|
||||
* Hover text for the large image
|
||||
* @type {?string}
|
||||
*/
|
||||
this.largeText = assets.large_text || null;
|
||||
this.largeText = assets.large_text ?? null;
|
||||
|
||||
/**
|
||||
* Hover text for the small image
|
||||
* @type {?string}
|
||||
*/
|
||||
this.smallText = assets.small_text || null;
|
||||
this.smallText = assets.small_text ?? null;
|
||||
|
||||
/**
|
||||
* ID of the large image asset
|
||||
* @type {?Snowflake}
|
||||
*/
|
||||
this.largeImage = assets.large_image || null;
|
||||
this.largeImage = assets.large_image ?? null;
|
||||
|
||||
/**
|
||||
* ID of the small image asset
|
||||
* @type {?Snowflake}
|
||||
*/
|
||||
this.smallImage = assets.small_image || null;
|
||||
this.smallImage = assets.small_image ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -342,11 +336,13 @@ class RichPresenceAssets {
|
||||
* @returns {?string} The small image URL
|
||||
*/
|
||||
smallImageURL({ format, size } = {}) {
|
||||
if (!this.smallImage) return null;
|
||||
return this.activity.presence.client.rest.cdn.AppAsset(this.activity.applicationID, this.smallImage, {
|
||||
format,
|
||||
size,
|
||||
});
|
||||
return (
|
||||
this.smallImage &&
|
||||
this.activity.presence.client.rest.cdn.AppAsset(this.activity.applicationID, this.smallImage, {
|
||||
format,
|
||||
size,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -183,7 +183,7 @@ class ReactionCollector extends Collector {
|
||||
* @returns {void}
|
||||
*/
|
||||
_handleGuildDeletion(guild) {
|
||||
if (this.message.guild && guild.id === this.message.guild.id) {
|
||||
if (guild.id === this.message.guild?.id) {
|
||||
this.stop('guildDelete');
|
||||
}
|
||||
}
|
||||
@@ -194,7 +194,7 @@ class ReactionCollector extends Collector {
|
||||
* @returns {Snowflake|string}
|
||||
*/
|
||||
static key(reaction) {
|
||||
return reaction.emoji.id || reaction.emoji.name;
|
||||
return reaction.emoji.id ?? reaction.emoji.name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -215,11 +215,11 @@ class Role extends Base {
|
||||
return this.client.api.guilds[this.guild.id].roles[this.id]
|
||||
.patch({
|
||||
data: {
|
||||
name: data.name || this.name,
|
||||
color: data.color !== null ? Util.resolveColor(data.color || this.color) : null,
|
||||
hoist: typeof data.hoist !== 'undefined' ? data.hoist : this.hoist,
|
||||
name: data.name ?? this.name,
|
||||
color: data.color !== null ? Util.resolveColor(data.color ?? this.color) : null,
|
||||
hoist: data.hoist ?? this.hoist,
|
||||
permissions: typeof data.permissions !== 'undefined' ? new Permissions(data.permissions) : this.permissions,
|
||||
mentionable: typeof data.mentionable !== 'undefined' ? data.mentionable : this.mentionable,
|
||||
mentionable: data.mentionable ?? this.mentionable,
|
||||
},
|
||||
reason,
|
||||
})
|
||||
|
||||
@@ -32,13 +32,13 @@ class Team extends Base {
|
||||
* The Team's icon hash
|
||||
* @type {?string}
|
||||
*/
|
||||
this.icon = data.icon || null;
|
||||
this.icon = data.icon ?? null;
|
||||
|
||||
/**
|
||||
* The Team's owner id
|
||||
* @type {?string}
|
||||
*/
|
||||
this.ownerID = data.owner_user_id || null;
|
||||
this.ownerID = data.owner_user_id ?? null;
|
||||
|
||||
/**
|
||||
* The Team's members
|
||||
@@ -58,7 +58,7 @@ class Team extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get owner() {
|
||||
return this.members.get(this.ownerID) || null;
|
||||
return this.members.get(this.ownerID) ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -197,7 +197,7 @@ class ThreadChannel extends Channel {
|
||||
async edit(data, reason) {
|
||||
const newData = await this.client.api.channels(this.id).patch({
|
||||
data: {
|
||||
name: (data.name || this.name).trim(),
|
||||
name: (data.name ?? this.name).trim(),
|
||||
archived: data.archived,
|
||||
auto_archive_duration: data.autoArchiveDuration,
|
||||
rate_limit_per_user: data.rateLimitPerUser,
|
||||
|
||||
@@ -141,8 +141,7 @@ class User extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get lastMessage() {
|
||||
const channel = this.client.channels.cache.get(this.lastMessageChannelID);
|
||||
return (channel && channel.messages.cache.get(this.lastMessageID)) || null;
|
||||
return this.client.channels.resolve(this.lastMessageChannelID)?.messages.resolve(this.lastMessageID) ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -185,7 +184,7 @@ class User extends Base {
|
||||
* @returns {string}
|
||||
*/
|
||||
displayAvatarURL(options) {
|
||||
return this.avatarURL(options) || this.defaultAvatarURL;
|
||||
return this.avatarURL(options) ?? this.defaultAvatarURL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -203,8 +202,7 @@ class User extends Base {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
typingIn(channel) {
|
||||
channel = this.client.channels.resolve(channel);
|
||||
return channel._typing.has(this.id);
|
||||
return this.client.channels.resolve(channel)._typing.has(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,8 +221,7 @@ class User extends Base {
|
||||
* @returns {number}
|
||||
*/
|
||||
typingDurationIn(channel) {
|
||||
channel = this.client.channels.resolve(channel);
|
||||
return channel._typing.has(this.id) ? channel._typing.get(this.id).elapsedTime : -1;
|
||||
return this.client.channels.resolve(channel)._typing.get(this.id)?.elapsedTime ?? -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,7 +230,7 @@ class User extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get dmChannel() {
|
||||
return this.client.channels.cache.find(c => c.type === 'dm' && c.recipient.id === this.id) || null;
|
||||
return this.client.channels.cache.find(c => c.type === 'dm' && c.recipient.id === this.id) ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,42 +31,42 @@ class VoiceState extends Base {
|
||||
* Whether this member is deafened server-wide
|
||||
* @type {?boolean}
|
||||
*/
|
||||
this.serverDeaf = 'deaf' in data ? data.deaf : null;
|
||||
this.serverDeaf = data.deaf ?? null;
|
||||
/**
|
||||
* Whether this member is muted server-wide
|
||||
* @type {?boolean}
|
||||
*/
|
||||
this.serverMute = 'mute' in data ? data.mute : null;
|
||||
this.serverMute = data.mute ?? null;
|
||||
/**
|
||||
* Whether this member is self-deafened
|
||||
* @type {?boolean}
|
||||
*/
|
||||
this.selfDeaf = 'self_deaf' in data ? data.self_deaf : null;
|
||||
this.selfDeaf = data.self_deaf ?? null;
|
||||
/**
|
||||
* Whether this member is self-muted
|
||||
* @type {?boolean}
|
||||
*/
|
||||
this.selfMute = 'self_mute' in data ? data.self_mute : null;
|
||||
this.selfMute = data.self_mute ?? null;
|
||||
/**
|
||||
* Whether this member's camera is enabled
|
||||
* @type {?boolean}
|
||||
*/
|
||||
this.selfVideo = 'self_video' in data ? data.self_video : null;
|
||||
this.selfVideo = data.self_video ?? null;
|
||||
/**
|
||||
* The session ID of this member's connection
|
||||
* @type {?string}
|
||||
*/
|
||||
this.sessionID = 'session_id' in data ? data.session_id : null;
|
||||
this.sessionID = data.session_id ?? null;
|
||||
/**
|
||||
* Whether this member is streaming using "Go Live"
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.streaming = data.self_stream || false;
|
||||
this.streaming = data.self_stream ?? false;
|
||||
/**
|
||||
* The ID of the voice or stage channel that this member is in
|
||||
* @type {?Snowflake}
|
||||
*/
|
||||
this.channelID = data.channel_id || null;
|
||||
this.channelID = data.channel_id ?? null;
|
||||
/**
|
||||
* Whether this member is suppressed from speaking. This property is specific to stage channels only.
|
||||
* @type {boolean}
|
||||
@@ -88,7 +88,7 @@ class VoiceState extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get member() {
|
||||
return this.guild.members.cache.get(this.id) || null;
|
||||
return this.guild.members.cache.get(this.id) ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,7 +97,7 @@ class VoiceState extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get channel() {
|
||||
return this.guild.channels.cache.get(this.channelID) || null;
|
||||
return this.guild.channels.cache.get(this.channelID) ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,7 +125,7 @@ class VoiceState extends Base {
|
||||
* @returns {Promise<GuildMember>}
|
||||
*/
|
||||
setMute(mute, reason) {
|
||||
return this.member ? this.member.edit({ mute }, reason) : Promise.reject(new Error('VOICE_STATE_UNCACHED_MEMBER'));
|
||||
return this.member?.edit({ mute }, reason) ?? Promise.reject(new Error('VOICE_STATE_UNCACHED_MEMBER'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,7 +135,7 @@ class VoiceState extends Base {
|
||||
* @returns {Promise<GuildMember>}
|
||||
*/
|
||||
setDeaf(deaf, reason) {
|
||||
return this.member ? this.member.edit({ deaf }, reason) : Promise.reject(new Error('VOICE_STATE_UNCACHED_MEMBER'));
|
||||
return this.member?.edit({ deaf }, reason) ?? Promise.reject(new Error('VOICE_STATE_UNCACHED_MEMBER'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,9 +155,7 @@ class VoiceState extends Base {
|
||||
* @returns {Promise<GuildMember>}
|
||||
*/
|
||||
setChannel(channel, reason) {
|
||||
return this.member
|
||||
? this.member.edit({ channel }, reason)
|
||||
: Promise.reject(new Error('VOICE_STATE_UNCACHED_MEMBER'));
|
||||
return this.member?.edit({ channel }, reason) ?? Promise.reject(new Error('VOICE_STATE_UNCACHED_MEMBER'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -173,8 +171,7 @@ class VoiceState extends Base {
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async setRequestToSpeak(request) {
|
||||
const channel = this.channel;
|
||||
if (channel?.type !== 'stage') throw new Error('VOICE_NOT_STAGE_CHANNEL');
|
||||
if (this.channel?.type !== 'stage') throw new Error('VOICE_NOT_STAGE_CHANNEL');
|
||||
|
||||
if (this.client.user.id !== this.id) throw new Error('VOICE_STATE_NOT_OWN');
|
||||
|
||||
@@ -206,8 +203,7 @@ class VoiceState extends Base {
|
||||
async setSuppressed(suppressed) {
|
||||
if (typeof suppressed !== 'boolean') throw new TypeError('VOICE_STATE_INVALID_TYPE', 'suppressed');
|
||||
|
||||
const channel = this.channel;
|
||||
if (channel?.type !== 'stage') throw new Error('VOICE_NOT_STAGE_CHANNEL');
|
||||
if (this.channel?.type !== 'stage') throw new Error('VOICE_NOT_STAGE_CHANNEL');
|
||||
|
||||
const target = this.client.user.id === this.id ? '@me' : this.id;
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ class Webhook {
|
||||
* @name Webhook#token
|
||||
* @type {?string}
|
||||
*/
|
||||
Object.defineProperty(this, 'token', { value: data.token || null, writable: true, configurable: true });
|
||||
Object.defineProperty(this, 'token', { value: data.token ?? null, writable: true, configurable: true });
|
||||
|
||||
/**
|
||||
* The avatar for the webhook
|
||||
@@ -175,11 +175,7 @@ class Webhook {
|
||||
query: { thread_id: messagePayload.options.threadID, wait: true },
|
||||
auth: false,
|
||||
})
|
||||
.then(d => {
|
||||
const channel = this.client.channels ? this.client.channels.cache.get(d.channel_id) : undefined;
|
||||
if (!channel) return d;
|
||||
return channel.messages.add(d, false);
|
||||
});
|
||||
.then(d => this.client.channels?.cache.get(d.channel_id)?.messages.add(d, false) ?? d);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -212,11 +212,11 @@ class Collector extends EventEmitter {
|
||||
resetTimer({ time, idle } = {}) {
|
||||
if (this._timeout) {
|
||||
this.client.clearTimeout(this._timeout);
|
||||
this._timeout = this.client.setTimeout(() => this.stop('time'), time || this.options.time);
|
||||
this._timeout = this.client.setTimeout(() => this.stop('time'), time ?? this.options.time);
|
||||
}
|
||||
if (this._idletimeout) {
|
||||
this.client.clearTimeout(this._idletimeout);
|
||||
this._idletimeout = this.client.setTimeout(() => this.stop('idle'), idle || this.options.idle);
|
||||
this._idletimeout = this.client.setTimeout(() => this.stop('idle'), idle ?? this.options.idle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ class TextBasedChannel {
|
||||
* @readonly
|
||||
*/
|
||||
get lastMessage() {
|
||||
return this.messages.cache.get(this.lastMessageID) || null;
|
||||
return this.messages.resolve(this.lastMessageID);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -185,7 +185,7 @@ class TextBasedChannel {
|
||||
if (typeof count !== 'undefined' && count < 1) throw new RangeError('TYPING_COUNT');
|
||||
if (this.client.user._typing.has(this.id)) {
|
||||
const entry = this.client.user._typing.get(this.id);
|
||||
entry.count = count || entry.count + 1;
|
||||
entry.count = count ?? entry.count + 1;
|
||||
return entry.promise;
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ class TextBasedChannel {
|
||||
entry.promise = new Promise((resolve, reject) => {
|
||||
const endpoint = this.client.api.channels[this.id].typing;
|
||||
Object.assign(entry, {
|
||||
count: count || 1,
|
||||
count: count ?? 1,
|
||||
interval: this.client.setInterval(() => {
|
||||
endpoint.post().catch(error => {
|
||||
this.client.clearInterval(entry.interval);
|
||||
@@ -252,8 +252,7 @@ class TextBasedChannel {
|
||||
* @readonly
|
||||
*/
|
||||
get typingCount() {
|
||||
if (this.client.user._typing.has(this.id)) return this.client.user._typing.get(this.id).count;
|
||||
return 0;
|
||||
return this.client.user._typing.get(this.id)?.count ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -294,7 +293,7 @@ class TextBasedChannel {
|
||||
return new Promise((resolve, reject) => {
|
||||
const collector = this.createMessageCollector(options);
|
||||
collector.once('end', (collection, reason) => {
|
||||
if (options.errors && options.errors.includes(reason)) {
|
||||
if (options.errors?.includes(reason)) {
|
||||
reject(collection);
|
||||
} else {
|
||||
resolve(collection);
|
||||
@@ -355,7 +354,7 @@ class TextBasedChannel {
|
||||
*/
|
||||
async bulkDelete(messages, filterOld = false) {
|
||||
if (Array.isArray(messages) || messages instanceof Collection) {
|
||||
let messageIDs = messages instanceof Collection ? messages.keyArray() : messages.map(m => m.id || m);
|
||||
let messageIDs = messages instanceof Collection ? messages.keyArray() : messages.map(m => m.id ?? m);
|
||||
if (filterOld) {
|
||||
messageIDs = messageIDs.filter(id => Date.now() - SnowflakeUtil.deconstruct(id).timestamp < 1209600000);
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ class Structures {
|
||||
|
||||
if (!(extended.prototype instanceof structures[structure])) {
|
||||
const prototype = Object.getPrototypeOf(extended);
|
||||
const received = `${extended.name || 'unnamed'}${prototype.name ? ` extends ${prototype.name}` : ''}`;
|
||||
const received = `${extended.name ?? 'unnamed'}${prototype.name ? ` extends ${prototype.name}` : ''}`;
|
||||
throw new Error(
|
||||
'The class/prototype returned from the extender function must extend the existing structure class/prototype' +
|
||||
` (received function ${received}; expected extension of ${structures[structure].name}).`,
|
||||
|
||||
@@ -289,9 +289,8 @@ class Util {
|
||||
static parseEmoji(text) {
|
||||
if (text.includes('%')) text = decodeURIComponent(text);
|
||||
if (!text.includes(':')) return { animated: false, name: text, id: null };
|
||||
const m = text.match(/<?(?:(a):)?(\w{2,32}):(\d{17,19})?>?/);
|
||||
if (!m) return null;
|
||||
return { animated: Boolean(m[1]), name: m[2], id: m[3] || null };
|
||||
const match = text.match(/<?(?:(a):)?(\w{2,32}):(\d{17,19})?>?/);
|
||||
return match && { animated: Boolean(match[1]), name: match[2], id: match[3] ?? null };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -460,7 +459,7 @@ class Util {
|
||||
if (typeof color === 'string') {
|
||||
if (color === 'RANDOM') return Math.floor(Math.random() * (0xffffff + 1));
|
||||
if (color === 'DEFAULT') return 0;
|
||||
color = Colors[color] || parseInt(color.replace('#', ''), 16);
|
||||
color = Colors[color] ?? parseInt(color.replace('#', ''), 16);
|
||||
} else if (Array.isArray(color)) {
|
||||
color = (color[0] << 16) + (color[1] << 8) + color[2];
|
||||
}
|
||||
@@ -511,7 +510,7 @@ class Util {
|
||||
* @private
|
||||
*/
|
||||
static basename(path, ext) {
|
||||
let res = parse(path);
|
||||
const res = parse(path);
|
||||
return ext && res.ext.startsWith(ext) ? res.name : res.base.split('?')[0];
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ client.on('message', m => {
|
||||
if (!m.guild) return;
|
||||
if (m.author.id !== '66564597481480192') return;
|
||||
if (m.content.startsWith('/join')) {
|
||||
const channel = m.guild.channels.cache.get(m.content.split(' ')[1]) || m.member.voice.channel;
|
||||
const channel = m.guild.channels.cache.get(m.content.split(' ')[1]) ?? m.member.voice.channel;
|
||||
if (channel && channel.type === 'voice') {
|
||||
channel.join().then(conn => {
|
||||
conn.receiver.createStream(m.author, true).on('data', b => console.log(b.toString()));
|
||||
|
||||
Reference in New Issue
Block a user