refactor: switch api and gateway to V8 (#4879)

Co-authored-by: Jan <66554238+Vaporox@users.noreply.github.com>
This commit is contained in:
Sugden
2021-02-11 17:10:35 +00:00
committed by GitHub
parent ae3c3d80ee
commit ee5bc1a5c4
33 changed files with 372 additions and 364 deletions

View File

@@ -29,9 +29,9 @@ const Structures = require('../util/Structures');
*/ */
class Client extends BaseClient { class Client extends BaseClient {
/** /**
* @param {ClientOptions} [options] Options for the client * @param {ClientOptions} options Options for the client
*/ */
constructor(options = {}) { constructor(options) {
super(Object.assign({ _tokenType: 'Bot' }, options)); super(Object.assign({ _tokenType: 'Bot' }, options));
// Obtain shard details from environment or if present, worker threads // Obtain shard details from environment or if present, worker threads
@@ -457,8 +457,10 @@ class Client extends BaseClient {
* @private * @private
*/ */
_validateOptions(options = this.options) { _validateOptions(options = this.options) {
if (typeof options.ws.intents !== 'undefined') { if (typeof options.intents === 'undefined') {
options.ws.intents = Intents.resolve(options.ws.intents); throw new TypeError('CLIENT_MISSING_INTENTS');
} else {
options.intents = Intents.resolve(options.intents);
} }
if (typeof options.shardCount !== 'number' || isNaN(options.shardCount) || options.shardCount < 1) { if (typeof options.shardCount !== 'number' || isNaN(options.shardCount) || options.shardCount < 1) {
throw new TypeError('CLIENT_INVALID_OPTION', 'shardCount', 'a number greater than or equal to 1'); throw new TypeError('CLIENT_INVALID_OPTION', 'shardCount', 'a number greater than or equal to 1');

View File

@@ -10,9 +10,9 @@ class ChannelCreateAction extends Action {
const channel = client.channels.add(data); const channel = client.channels.add(data);
if (!existing && channel) { if (!existing && channel) {
/** /**
* Emitted whenever a channel is created. * Emitted whenever a guild channel is created.
* @event Client#channelCreate * @event Client#channelCreate
* @param {DMChannel|GuildChannel} channel The channel that was created * @param {GuildChannel} channel The channel that was created
*/ */
client.emit(Events.CHANNEL_CREATE, channel); client.emit(Events.CHANNEL_CREATE, channel);
} }

View File

@@ -6,7 +6,7 @@ const { Events } = require('../../util/Constants');
class MessageCreateAction extends Action { class MessageCreateAction extends Action {
handle(data) { handle(data) {
const client = this.client; const client = this.client;
const channel = client.channels.cache.get(data.channel_id); const channel = this.getChannel(data);
if (channel) { if (channel) {
const existing = channel.messages.cache.get(data.id); const existing = channel.messages.cache.get(data.id);
if (existing) return { message: existing }; if (existing) return { message: existing };

View File

@@ -22,7 +22,6 @@ class PresenceUpdateAction extends Action {
if (!member && data.status !== 'offline') { if (!member && data.status !== 'offline') {
member = guild.members.add({ member = guild.members.add({
user, user,
roles: data.roles,
deaf: false, deaf: false,
mute: false, mute: false,
}); });

View File

@@ -3,6 +3,7 @@
const EventEmitter = require('events'); const EventEmitter = require('events');
const WebSocket = require('../../WebSocket'); const WebSocket = require('../../WebSocket');
const { Status, Events, ShardEvents, OPCodes, WSEvents } = require('../../util/Constants'); const { Status, Events, ShardEvents, OPCodes, WSEvents } = require('../../util/Constants');
const Intents = require('../../util/Intents');
const STATUS_KEYS = Object.keys(Status); const STATUS_KEYS = Object.keys(Status);
const CONNECTION_STATE = Object.keys(WebSocket.WebSocket); const CONNECTION_STATE = Object.keys(WebSocket.WebSocket);
@@ -594,6 +595,7 @@ class WebSocketShard extends EventEmitter {
// Clone the identify payload and assign the token and shard info // Clone the identify payload and assign the token and shard info
const d = { const d = {
...client.options.ws, ...client.options.ws,
intents: Intents.resolve(client.options.intents),
token: client.token, token: client.token,
shard: [this.id, Number(client.options.shardCount)], shard: [this.id, Number(client.options.shardCount)],
}; };

View File

@@ -5,6 +5,7 @@ const { register } = require('./DJSError');
const Messages = { const Messages = {
CLIENT_INVALID_OPTION: (prop, must) => `The ${prop} option must be ${must}`, CLIENT_INVALID_OPTION: (prop, must) => `The ${prop} option must be ${must}`,
CLIENT_INVALID_PROVIDED_SHARDS: 'None of the provided shards were valid.', CLIENT_INVALID_PROVIDED_SHARDS: 'None of the provided shards were valid.',
CLIENT_MISSING_INTENTS: 'Valid intents must be provided for the Client.',
TOKEN_INVALID: 'An invalid token was provided.', TOKEN_INVALID: 'An invalid token was provided.',
TOKEN_MISSING: 'Request to use token, but token was unavailable to the client.', TOKEN_MISSING: 'Request to use token, but token was unavailable to the client.',

View File

@@ -53,7 +53,7 @@ class GuildManager extends BaseManager {
* @property {ColorResolvable} [color] The color of the role, either a hex string or a base 10 number * @property {ColorResolvable} [color] The color of the role, either a hex string or a base 10 number
* @property {boolean} [hoist] Whether or not the role should be hoisted * @property {boolean} [hoist] Whether or not the role should be hoisted
* @property {number} [position] The position of the role * @property {number} [position] The position of the role
* @property {PermissionResolvable|number} [permissions] The permissions of the role * @property {PermissionResolvable} [permissions] The permissions of the role
* @property {boolean} [mentionable] Whether or not the role should be mentionable * @property {boolean} [mentionable] Whether or not the role should be mentionable
*/ */

View File

@@ -115,7 +115,7 @@ class RoleManager extends BaseManager {
create(options = {}) { create(options = {}) {
let { name, color, hoist, permissions, position, mentionable, reason } = options; let { name, color, hoist, permissions, position, mentionable, reason } = options;
if (color) color = resolveColor(color); if (color) color = resolveColor(color);
if (permissions) permissions = Permissions.resolve(permissions); if (permissions) permissions = Permissions.resolve(permissions).toString();
return this.client.api return this.client.api
.guilds(this.guild.id) .guilds(this.guild.id)

View File

@@ -105,7 +105,7 @@ class RequestHandler {
this.limit = limit ? Number(limit) : Infinity; this.limit = limit ? Number(limit) : Infinity;
this.remaining = remaining ? Number(remaining) : 1; this.remaining = remaining ? Number(remaining) : 1;
this.reset = reset ? calculateReset(reset, serverDate) : Date.now(); this.reset = reset ? calculateReset(reset, serverDate) : Date.now();
this.retryAfter = retryAfter ? Number(retryAfter) : -1; this.retryAfter = retryAfter ? Number(retryAfter) * 1000 : -1;
// https://github.com/discordapp/discord-api-docs/issues/182 // https://github.com/discordapp/discord-api-docs/issues/182
if (request.route.includes('reactions')) { if (request.route.includes('reactions')) {

View File

@@ -2,7 +2,6 @@
const { Presence } = require('./Presence'); const { Presence } = require('./Presence');
const { TypeError } = require('../errors'); const { TypeError } = require('../errors');
const Collection = require('../util/Collection');
const { ActivityTypes, OPCodes } = require('../util/Constants'); const { ActivityTypes, OPCodes } = require('../util/Constants');
class ClientPresence extends Presence { class ClientPresence extends Presence {
@@ -14,8 +13,8 @@ class ClientPresence extends Presence {
super(client, Object.assign(data, { status: data.status || 'online', user: { id: null } })); super(client, Object.assign(data, { status: data.status || 'online', user: { id: null } }));
} }
async set(presence) { set(presence) {
const packet = await this._parse(presence); const packet = this._parse(presence);
this.patch(packet); this.patch(packet);
if (typeof presence.shardID === 'undefined') { if (typeof presence.shardID === 'undefined') {
this.client.ws.broadcast({ op: OPCodes.STATUS_UPDATE, d: packet }); this.client.ws.broadcast({ op: OPCodes.STATUS_UPDATE, d: packet });
@@ -29,58 +28,33 @@ class ClientPresence extends Presence {
return this; return this;
} }
async _parse({ status, since, afk, activity }) { _parse({ status, since, afk, activities }) {
const applicationID = activity && (activity.application ? activity.application.id || activity.application : null); const data = {
let assets = new Collection(); activities: [],
if (activity) { afk: typeof afk === 'boolean' ? afk : false,
if (typeof activity.name !== 'string') throw new TypeError('INVALID_TYPE', 'name', 'string'); since: typeof since === 'number' && !Number.isNaN(since) ? since : null,
if (!activity.type) activity.type = 0;
if (activity.assets && applicationID) {
try {
const a = await this.client.api.oauth2.applications(applicationID).assets.get();
for (const asset of a) assets.set(asset.name, asset.id);
} catch {} // eslint-disable-line no-empty
}
}
const packet = {
afk: afk != null ? afk : false, // eslint-disable-line eqeqeq
since: since != null ? since : null, // eslint-disable-line eqeqeq
status: status || this.status, status: status || this.status,
game: activity
? {
type: activity.type,
name: activity.name,
url: activity.url,
details: activity.details || undefined,
state: activity.state || undefined,
assets: activity.assets
? {
large_text: activity.assets.largeText || undefined,
small_text: activity.assets.smallText || undefined,
large_image: assets.get(activity.assets.largeImage) || activity.assets.largeImage,
small_image: assets.get(activity.assets.smallImage) || activity.assets.smallImage,
}
: undefined,
timestamps: activity.timestamps || undefined,
party: activity.party || undefined,
application_id: applicationID || undefined,
secrets: activity.secrets || undefined,
instance: activity.instance || undefined,
}
: null,
}; };
if (activities === null) {
data.activities = null;
return data;
}
if (activities && activities.length) {
for (const [i, activity] of activities.entries()) {
if (typeof activity.name !== 'string') throw new TypeError('INVALID_TYPE', `activities[${i}].name`, 'string');
if (!activity.type) activity.type = 0;
if ((status || afk || since) && !activity) { data.activities.push({
packet.game = this.activities[0] || null; type: typeof activity.type === 'number' ? activity.type : ActivityTypes.indexOf(activity.type),
name: activity.name,
url: activity.url,
});
}
} else if ((status || afk || since) && this.activities.length) {
data.activities.push(...this.activities);
} }
if (packet.game) { return data;
packet.game.type =
typeof packet.game.type === 'number' ? packet.game.type : ActivityTypes.indexOf(packet.game.type);
}
return packet;
} }
} }

View File

@@ -46,16 +46,18 @@ class ClientUser extends Structures.get('User') {
return this.client.presence; return this.client.presence;
} }
edit(data) { /**
return this.client.api * Edits the logged in client.
.users('@me') * @param {Object} data The new data
.patch({ data }) * @param {string} [data.username] The new username
.then(newData => { * @param {BufferResolvable|Base64Resolvable} [data.avatar] The new avatar
this.client.token = newData.token; */
const { updated } = this.client.actions.UserUpdate.handle(newData); async edit(data) {
if (updated) return updated; const newData = await this.client.api.users('@me').patch({ data });
return this; this.client.token = newData.token;
}); const { updated } = this.client.actions.UserUpdate.handle(newData);
if (updated) return updated;
return this;
} }
/** /**
@@ -103,7 +105,7 @@ class ClientUser extends Structures.get('User') {
/** /**
* Sets the full presence of the client user. * Sets the full presence of the client user.
* @param {PresenceData} data Data for the presence * @param {PresenceData} data Data for the presence
* @returns {Promise<Presence>} * @returns {Presence}
* @example * @example
* // Set the client user's presence * // Set the client user's presence
* client.user.setPresence({ activity: { name: 'with discord.js' }, status: 'idle' }) * client.user.setPresence({ activity: { name: 'with discord.js' }, status: 'idle' })
@@ -127,7 +129,7 @@ class ClientUser extends Structures.get('User') {
* Sets the status of the client user. * Sets the status of the client user.
* @param {PresenceStatusData} status Status to change to * @param {PresenceStatusData} status Status to change to
* @param {?number|number[]} [shardID] Shard ID(s) to have the activity set on * @param {?number|number[]} [shardID] Shard ID(s) to have the activity set on
* @returns {Promise<Presence>} * @returns {Presence}
* @example * @example
* // Set the client user's status * // Set the client user's status
* client.user.setStatus('idle') * client.user.setStatus('idle')
@@ -144,14 +146,14 @@ class ClientUser extends Structures.get('User') {
* @type {Object} * @type {Object}
* @property {string} [url] Twitch / YouTube stream URL * @property {string} [url] Twitch / YouTube stream URL
* @property {ActivityType|number} [type] Type of the activity * @property {ActivityType|number} [type] Type of the activity
* @property {?number|number[]} [shardID] Shard Id(s) to have the activity set on * @property {number|number[]} [shardID] Shard Id(s) to have the activity set on
*/ */
/** /**
* Sets the activity the client user is playing. * Sets the activity the client user is playing.
* @param {string|ActivityOptions} [name] Activity being played, or options for setting the activity * @param {string|ActivityOptions} [name] Activity being played, or options for setting the activity
* @param {ActivityOptions} [options] Options for setting the activity * @param {ActivityOptions} [options] Options for setting the activity
* @returns {Promise<Presence>} * @returns {Presence}
* @example * @example
* // Set the client user's activity * // Set the client user's activity
* client.user.setActivity('discord.js', { type: 'WATCHING' }) * client.user.setActivity('discord.js', { type: 'WATCHING' })
@@ -159,19 +161,20 @@ class ClientUser extends Structures.get('User') {
* .catch(console.error); * .catch(console.error);
*/ */
setActivity(name, options = {}) { setActivity(name, options = {}) {
if (!name) return this.setPresence({ activity: null, shardID: options.shardID }); if (!name) return this.setPresence({ activities: null, shardID: options.shardID });
const activity = Object.assign({}, options, typeof name === 'object' ? name : { name }); const activity = Object.assign({}, options, typeof name === 'object' ? name : { name });
return this.setPresence({ activity, shardID: activity.shardID }); return this.setPresence({ activities: [activity], shardID: activity.shardID });
} }
/** /**
* Sets/removes the AFK flag for the client user. * Sets/removes the AFK flag for the client user.
* @param {boolean} afk Whether or not the user is AFK * @param {boolean} afk Whether or not the user is AFK
* @returns {Promise<Presence>} * @param {number|number[]} [shardID] Shard Id(s) to have the AFK flag set on
* @returns {Presence}
*/ */
setAFK(afk) { setAFK(afk, shardID) {
return this.setPresence({ afk }); return this.setPresence({ afk, shardID });
} }
} }

View File

@@ -210,13 +210,6 @@ class Guild extends Base {
*/ */
this.systemChannelID = data.system_channel_id; this.systemChannelID = data.system_channel_id;
/**
* Whether embedded images are enabled on this guild
* @type {boolean}
* @deprecated
*/
this.embedEnabled = data.embed_enabled;
/** /**
* The type of premium tier: * The type of premium tier:
* * 0: NONE * * 0: NONE
@@ -256,15 +249,6 @@ class Guild extends Base {
this.widgetChannelID = data.widget_channel_id; this.widgetChannelID = data.widget_channel_id;
} }
if (typeof data.embed_channel_id !== 'undefined') {
/**
* The embed channel ID, if enabled
* @type {?string}
* @deprecated
*/
this.embedChannelID = data.embed_channel_id;
}
/** /**
* The verification level of the guild * The verification level of the guild
* @type {VerificationLevel} * @type {VerificationLevel}
@@ -585,16 +569,6 @@ class Guild extends Base {
return this.client.channels.cache.get(this.widgetChannelID) || null; return this.client.channels.cache.get(this.widgetChannelID) || null;
} }
/**
* Embed channel for this guild
* @type {?TextChannel}
* @readonly
* @deprecated
*/
get embedChannel() {
return this.client.channels.cache.get(this.embedChannelID) || null;
}
/** /**
* Rules channel for this guild * Rules channel for this guild
* @type {?TextChannel} * @type {?TextChannel}
@@ -688,8 +662,6 @@ class Guild extends Base {
/** /**
* Fetches a collection of integrations to this guild. * Fetches a collection of integrations to this guild.
* Resolves with a collection mapping integrations by their ids. * Resolves with a collection mapping integrations by their ids.
* @param {Object} [options] Options for fetching integrations
* @param {boolean} [options.includeApplications] Whether to include bot and Oauth2 webhook integrations
* @returns {Promise<Collection<string, Integration>>} * @returns {Promise<Collection<string, Integration>>}
* @example * @example
* // Fetch integrations * // Fetch integrations
@@ -697,20 +669,12 @@ class Guild extends Base {
* .then(integrations => console.log(`Fetched ${integrations.size} integrations`)) * .then(integrations => console.log(`Fetched ${integrations.size} integrations`))
* .catch(console.error); * .catch(console.error);
*/ */
fetchIntegrations({ includeApplications = false } = {}) { async fetchIntegrations() {
return this.client.api const data = await this.client.api.guilds(this.id).integrations.get();
.guilds(this.id) return data.reduce(
.integrations.get({ (collection, integration) => collection.set(integration.id, new Integration(this.client, integration, this)),
query: { new Collection(),
include_applications: includeApplications, );
},
})
.then(data =>
data.reduce(
(collection, integration) => collection.set(integration.id, new Integration(this.client, integration, this)),
new Collection(),
),
);
} }
/** /**
@@ -895,20 +859,6 @@ class Guild extends Base {
* @property {?GuildChannelResolvable} channel The widget channel * @property {?GuildChannelResolvable} channel The widget channel
*/ */
/**
* Fetches the guild embed.
* @returns {Promise<GuildWidget>}
* @deprecated
* @example
* // Fetches the guild embed
* guild.fetchEmbed()
* .then(embed => console.log(`The embed is ${embed.enabled ? 'enabled' : 'disabled'}`))
* .catch(console.error);
*/
fetchEmbed() {
return this.fetchWidget();
}
/** /**
* Fetches the guild widget. * Fetches the guild widget.
* @returns {Promise<GuildWidget>} * @returns {Promise<GuildWidget>}
@@ -920,8 +870,8 @@ class Guild extends Base {
*/ */
async fetchWidget() { async fetchWidget() {
const data = await this.client.api.guilds(this.id).widget.get(); const data = await this.client.api.guilds(this.id).widget.get();
this.widgetEnabled = this.embedEnabled = data.enabled; this.widgetEnabled = data.enabled;
this.widgetChannelID = this.embedChannelID = data.channel_id; this.widgetChannelID = data.channel_id;
return { return {
enabled: data.enabled, enabled: data.enabled,
channel: data.channel_id ? this.channels.cache.get(data.channel_id) : null, channel: data.channel_id ? this.channels.cache.get(data.channel_id) : null,
@@ -1367,7 +1317,7 @@ class Guild extends Base {
* @returns {Promise<Guild>} * @returns {Promise<Guild>}
* @example * @example
* guild.setRolePositions([{ role: roleID, position: updatedRoleIndex }]) * guild.setRolePositions([{ role: roleID, position: updatedRoleIndex }])
* .then(guild => console.log(`Role permissions updated for ${guild}`)) * .then(guild => console.log(`Role positions updated for ${guild}`))
* .catch(console.error); * .catch(console.error);
*/ */
setRolePositions(rolePositions) { setRolePositions(rolePositions) {
@@ -1392,17 +1342,6 @@ class Guild extends Base {
); );
} }
/**
* Edits the guild's embed.
* @param {GuildWidgetData} embed The embed for the guild
* @param {string} [reason] Reason for changing the guild's embed
* @returns {Promise<Guild>}
* @deprecated
*/
setEmbed(embed, reason) {
return this.setWidget(embed, reason);
}
/** /**
* Edits the guild's widget. * Edits the guild's widget.
* @param {GuildWidgetData} widget The widget for the guild * @param {GuildWidgetData} widget The widget for the guild
@@ -1464,7 +1403,7 @@ class Guild extends Base {
* @returns {boolean} * @returns {boolean}
*/ */
equals(guild) { equals(guild) {
let equal = return (
guild && guild &&
guild instanceof this.constructor && guild instanceof this.constructor &&
this.id === guild.id && this.id === guild.id &&
@@ -1478,20 +1417,10 @@ class Guild extends Base {
this.icon === guild.icon && this.icon === guild.icon &&
this.ownerID === guild.ownerID && this.ownerID === guild.ownerID &&
this.verificationLevel === guild.verificationLevel && this.verificationLevel === guild.verificationLevel &&
this.embedEnabled === guild.embedEnabled &&
(this.features === guild.features || (this.features === guild.features ||
(this.features.length === guild.features.length && (this.features.length === guild.features.length &&
this.features.every((feat, i) => feat === guild.features[i]))); this.features.every((feat, i) => feat === guild.features[i])))
);
if (equal) {
if (this.embedChannel) {
if (!guild.embedChannel || this.embedChannel.id !== guild.embedChannel.id) equal = false;
} else if (guild.embedChannel) {
equal = false;
}
}
return equal;
} }
/** /**
@@ -1522,7 +1451,7 @@ class Guild extends Base {
/** /**
* Creates a collection of this guild's roles, sorted by their position and IDs. * Creates a collection of this guild's roles, sorted by their position and IDs.
* @returns {Collection<Role>} * @returns {Collection<Snowflake, Role>}
* @private * @private
*/ */
_sortedRoles() { _sortedRoles() {
@@ -1532,7 +1461,7 @@ class Guild extends Base {
/** /**
* Creates a collection of this guild's or a specific category's channels, sorted by their position and IDs. * Creates a collection of this guild's or a specific category's channels, sorted by their position and IDs.
* @param {GuildChannel} [channel] Category to get the channels of * @param {GuildChannel} [channel] Category to get the channels of
* @returns {Collection<GuildChannel>} * @returns {Collection<Snowflake, GuildChannel>}
* @private * @private
*/ */
_sortedChannels(channel) { _sortedChannels(channel) {
@@ -1549,10 +1478,6 @@ class Guild extends Base {
} }
} }
Guild.prototype.setEmbed = deprecate(Guild.prototype.setEmbed, 'Guild#setEmbed: Use setWidget instead');
Guild.prototype.fetchEmbed = deprecate(Guild.prototype.fetchEmbed, 'Guild#fetchEmbed: Use fetchWidget instead');
Guild.prototype.fetchVanityCode = deprecate( Guild.prototype.fetchVanityCode = deprecate(
Guild.prototype.fetchVanityCode, Guild.prototype.fetchVanityCode,
'Guild#fetchVanityCode: Use fetchVanityData() instead', 'Guild#fetchVanityCode: Use fetchVanityData() instead',

View File

@@ -3,7 +3,7 @@
const Integration = require('./Integration'); const Integration = require('./Integration');
const Webhook = require('./Webhook'); const Webhook = require('./Webhook');
const Collection = require('../util/Collection'); const Collection = require('../util/Collection');
const { PartialTypes } = require('../util/Constants'); const { OverwriteTypes, PartialTypes } = require('../util/Constants');
const Permissions = require('../util/Permissions'); const Permissions = require('../util/Permissions');
const Snowflake = require('../util/Snowflake'); const Snowflake = require('../util/Snowflake');
const Util = require('../util/Util'); const Util = require('../util/Util');
@@ -384,16 +384,19 @@ class GuildAuditLogsEntry {
case Actions.CHANNEL_OVERWRITE_CREATE: case Actions.CHANNEL_OVERWRITE_CREATE:
case Actions.CHANNEL_OVERWRITE_UPDATE: case Actions.CHANNEL_OVERWRITE_UPDATE:
case Actions.CHANNEL_OVERWRITE_DELETE: case Actions.CHANNEL_OVERWRITE_DELETE:
switch (data.options.type) { switch (Number(data.options.type)) {
case 'member': case OverwriteTypes.role:
this.extra = guild.members.cache.get(data.options.id) || { id: data.options.id, type: 'member' };
break;
case 'role':
this.extra = guild.roles.cache.get(data.options.id) || { this.extra = guild.roles.cache.get(data.options.id) || {
id: data.options.id, id: data.options.id,
name: data.options.role_name, name: data.options.role_name,
type: 'role', type: OverwriteTypes[OverwriteTypes.role],
};
break;
case OverwriteTypes.member:
this.extra = guild.members.cache.get(data.options.id) || {
id: data.options.id,
type: OverwriteTypes[OverwriteTypes.member],
}; };
break; break;

View File

@@ -7,6 +7,7 @@ const Role = require('./Role');
const { Error, TypeError } = require('../errors'); const { Error, TypeError } = require('../errors');
const Collection = require('../util/Collection'); const Collection = require('../util/Collection');
const { ChannelTypes } = require('../util/Constants'); const { ChannelTypes } = require('../util/Constants');
const { OverwriteTypes } = require('../util/Constants');
const Permissions = require('../util/Permissions'); const Permissions = require('../util/Permissions');
const Util = require('../util/Util'); const Util = require('../util/Util');
@@ -161,12 +162,12 @@ class GuildChannel extends Channel {
const overwrites = this.overwritesFor(member, true, roles); const overwrites = this.overwritesFor(member, true, roles);
return permissions return permissions
.remove(overwrites.everyone ? overwrites.everyone.deny : 0) .remove(overwrites.everyone ? overwrites.everyone.deny : 0n)
.add(overwrites.everyone ? overwrites.everyone.allow : 0) .add(overwrites.everyone ? overwrites.everyone.allow : 0n)
.remove(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.deny) : 0) .remove(overwrites.roles.length > 0n ? overwrites.roles.map(role => role.deny) : 0n)
.add(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.allow) : 0) .add(overwrites.roles.length > 0n ? overwrites.roles.map(role => role.allow) : 0n)
.remove(overwrites.member ? overwrites.member.deny : 0) .remove(overwrites.member ? overwrites.member.deny : 0n)
.add(overwrites.member ? overwrites.member.allow : 0) .add(overwrites.member ? overwrites.member.allow : 0n)
.freeze(); .freeze();
} }
@@ -183,10 +184,10 @@ class GuildChannel extends Channel {
const roleOverwrites = this.permissionOverwrites.get(role.id); const roleOverwrites = this.permissionOverwrites.get(role.id);
return role.permissions return role.permissions
.remove(everyoneOverwrites ? everyoneOverwrites.deny : 0) .remove(everyoneOverwrites ? everyoneOverwrites.deny : 0n)
.add(everyoneOverwrites ? everyoneOverwrites.allow : 0) .add(everyoneOverwrites ? everyoneOverwrites.allow : 0n)
.remove(roleOverwrites ? roleOverwrites.deny : 0) .remove(roleOverwrites ? roleOverwrites.deny : 0n)
.add(roleOverwrites ? roleOverwrites.allow : 0) .add(roleOverwrites ? roleOverwrites.allow : 0n)
.freeze(); .freeze();
} }
@@ -204,13 +205,12 @@ class GuildChannel extends Channel {
* }, * },
* ], 'Needed to change permissions'); * ], 'Needed to change permissions');
*/ */
overwritePermissions(overwrites, reason) { async overwritePermissions(overwrites, reason) {
if (!Array.isArray(overwrites) && !(overwrites instanceof Collection)) { if (!Array.isArray(overwrites) && !(overwrites instanceof Collection)) {
return Promise.reject( throw new TypeError('INVALID_TYPE', 'overwrites', 'Array or Collection of Permission Overwrites', true);
new TypeError('INVALID_TYPE', 'overwrites', 'Array or Collection of Permission Overwrites', true),
);
} }
return this.edit({ permissionOverwrites: overwrites, reason }).then(() => this); await this.edit({ permissionOverwrites: overwrites, reason });
return this;
} }
/** /**
@@ -227,13 +227,17 @@ class GuildChannel extends Channel {
* .then(channel => console.log(channel.permissionOverwrites.get(message.author.id))) * .then(channel => console.log(channel.permissionOverwrites.get(message.author.id)))
* .catch(console.error); * .catch(console.error);
*/ */
updateOverwrite(userOrRole, options, reason) { async updateOverwrite(userOrRole, options, reason) {
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')); if (!userOrRole) return Promise.reject(new TypeError('INVALID_TYPE', 'parameter', 'User nor a Role'));
const existing = this.permissionOverwrites.get(userOrRole.id); const existing = this.permissionOverwrites.get(userOrRole.id);
if (existing) return existing.update(options, reason).then(() => this); if (existing) {
return this.createOverwrite(userOrRole, options, reason); await existing.update(options, reason);
} else {
await this.createOverwrite(userOrRole, options, reason);
}
return this;
} }
/** /**
@@ -254,13 +258,19 @@ class GuildChannel extends Channel {
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')); if (!userOrRole) return Promise.reject(new TypeError('INVALID_TYPE', 'parameter', 'User nor a Role'));
const type = userOrRole instanceof Role ? 'role' : 'member'; const type = userOrRole instanceof Role ? OverwriteTypes.role : OverwriteTypes.member;
const { allow, deny } = PermissionOverwrites.resolveOverwriteOptions(options); const { allow, deny } = PermissionOverwrites.resolveOverwriteOptions(options);
return this.client.api return this.client.api
.channels(this.id) .channels(this.id)
.permissions[userOrRole.id].put({ .permissions(userOrRole.id)
data: { id: userOrRole.id, type, allow: allow.bitfield, deny: deny.bitfield }, .put({
data: {
id: userOrRole.id,
type,
allow,
deny,
},
reason, reason,
}) })
.then(() => this); .then(() => this);

View File

@@ -2,8 +2,8 @@
const Role = require('./Role'); const Role = require('./Role');
const { TypeError } = require('../errors'); const { TypeError } = require('../errors');
const { OverwriteTypes } = require('../util/Constants');
const Permissions = require('../util/Permissions'); const Permissions = require('../util/Permissions');
const Util = require('../util/Util');
/** /**
* Represents a permission overwrite for a role or member in a guild channel. * Represents a permission overwrite for a role or member in a guild channel.
@@ -28,30 +28,23 @@ class PermissionOverwrites {
*/ */
this.id = data.id; this.id = data.id;
/**
* The type of a permission overwrite. It can be one of:
* * member
* * role
* @typedef {string} OverwriteType
*/
/** /**
* The type of this overwrite * The type of this overwrite
* @type {OverwriteType} * @type {OverwriteType}
*/ */
this.type = data.type; this.type = OverwriteTypes[data.type];
/** /**
* The permissions that are denied for the user or role. * The permissions that are denied for the user or role.
* @type {Readonly<Permissions>} * @type {Readonly<Permissions>}
*/ */
this.deny = new Permissions(data.deny).freeze(); this.deny = new Permissions(BigInt(data.deny)).freeze();
/** /**
* The permissions that are allowed for the user or role. * The permissions that are allowed for the user or role.
* @type {Readonly<Permissions>} * @type {Readonly<Permissions>}
*/ */
this.allow = new Permissions(data.allow).freeze(); this.allow = new Permissions(BigInt(data.allow)).freeze();
} }
/** /**
@@ -67,16 +60,22 @@ class PermissionOverwrites {
* .then(channel => console.log(channel.permissionOverwrites.get(message.author.id))) * .then(channel => console.log(channel.permissionOverwrites.get(message.author.id)))
* .catch(console.error); * .catch(console.error);
*/ */
update(options, reason) { async update(options, reason) {
const { allow, deny } = this.constructor.resolveOverwriteOptions(options, this); const { allow, deny } = this.constructor.resolveOverwriteOptions(options, this);
return this.channel.client.api await this.channel.client.api
.channels(this.channel.id) .channels(this.channel.id)
.permissions[this.id].put({ .permissions(this.id)
data: { id: this.id, type: this.type, allow: allow.bitfield, deny: deny.bitfield }, .put({
data: {
id: this.id,
type: OverwriteTypes[this.type],
allow,
deny,
},
reason, reason,
}) });
.then(() => this); return this;
} }
/** /**
@@ -84,12 +83,18 @@ class PermissionOverwrites {
* @param {string} [reason] Reason for deleting this overwrite * @param {string} [reason] Reason for deleting this overwrite
* @returns {Promise<PermissionOverwrites>} * @returns {Promise<PermissionOverwrites>}
*/ */
delete(reason) { async delete(reason) {
return this.channel.client.api.channels[this.channel.id].permissions[this.id].delete({ reason }).then(() => this); await this.channel.client.api.channels(this.channel.id).permissions(this.id).delete({ reason });
return this;
} }
toJSON() { toJSON() {
return Util.flatten(this); return {
id: this.id,
type: OverwriteTypes[this.type],
allow: this.allow,
deny: this.deny,
};
} }
/** /**
@@ -142,9 +147,9 @@ class PermissionOverwrites {
* The raw data for a permission overwrite * The raw data for a permission overwrite
* @typedef {Object} RawOverwriteData * @typedef {Object} RawOverwriteData
* @property {Snowflake} id The id of the overwrite * @property {Snowflake} id The id of the overwrite
* @property {number} allow The permissions to allow * @property {string} allow The permissions to allow
* @property {number} deny The permissions to deny * @property {string} deny The permissions to deny
* @property {OverwriteType} type The type of this OverwriteData * @property {number} type The type of this OverwriteData
*/ */
/** /**
@@ -164,24 +169,29 @@ class PermissionOverwrites {
/** /**
* Resolves an overwrite into {@link RawOverwriteData}. * Resolves an overwrite into {@link RawOverwriteData}.
* @param {OverwriteResolvable} overwrite The overwrite-like data to resolve * @param {OverwriteResolvable} overwrite The overwrite-like data to resolve
* @param {Guild} guild The guild to resolve from * @param {Guild} [guild] The guild to resolve from
* @returns {RawOverwriteData} * @returns {RawOverwriteData}
*/ */
static resolve(overwrite, guild) { static resolve(overwrite, guild) {
if (overwrite instanceof this) return overwrite.toJSON(); if (overwrite instanceof this) return overwrite.toJSON();
if (typeof overwrite.id === 'string' && ['role', 'member'].includes(overwrite.type)) { if (typeof overwrite.id === 'string' && overwrite.type in OverwriteTypes) {
return { ...overwrite, allow: Permissions.resolve(overwrite.allow), deny: Permissions.resolve(overwrite.deny) }; return {
id: overwrite.id,
type: OverwriteTypes[overwrite.type],
allow: Permissions.resolve(overwrite.allow).toString(),
deny: Permissions.resolve(overwrite.deny).toString(),
};
} }
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'); if (!userOrRole) throw new TypeError('INVALID_TYPE', 'parameter', 'User nor a Role');
const type = userOrRole instanceof Role ? 'role' : 'member'; const type = userOrRole instanceof Role ? OverwriteTypes.role : OverwriteTypes.member;
return { return {
id: userOrRole.id, id: userOrRole.id,
type, type,
allow: Permissions.resolve(overwrite.allow), allow: Permissions.resolve(overwrite.allow).toString(),
deny: Permissions.resolve(overwrite.deny), deny: Permissions.resolve(overwrite.deny).toString(),
}; };
} }
} }

View File

@@ -63,7 +63,7 @@ class Role extends Base {
* The permissions of the role * The permissions of the role
* @type {Readonly<Permissions>} * @type {Readonly<Permissions>}
*/ */
this.permissions = new Permissions(data.permissions).freeze(); this.permissions = new Permissions(BigInt(data.permissions)).freeze();
/** /**
* Whether or not the role is managed by an external service * Whether or not the role is managed by an external service
@@ -301,7 +301,7 @@ class Role extends Base {
* .catch(console.error); * .catch(console.error);
* @example * @example
* // Remove all permissions from a role * // Remove all permissions from a role
* role.setPermissions(0) * role.setPermissions(0n)
* .then(updated => console.log(`Updated permissions to ${updated.permissions.bitfield}`)) * .then(updated => console.log(`Updated permissions to ${updated.permissions.bitfield}`))
* .catch(console.error); * .catch(console.error);
*/ */

View File

@@ -245,7 +245,7 @@ class User extends Base {
recipient_id: this.id, recipient_id: this.id,
}, },
}); });
return this.client.actions.ChannelCreate.handle(data).channel; return this.client.channels.add(data);
} }
/** /**
@@ -255,8 +255,9 @@ class User extends Base {
async deleteDM() { async deleteDM() {
const { dmChannel } = this; const { dmChannel } = this;
if (!dmChannel) throw new Error('USER_NO_DMCHANNEL'); if (!dmChannel) throw new Error('USER_NO_DMCHANNEL');
const data = await this.client.api.channels(dmChannel.id).delete(); await this.client.api.channels(dmChannel.id).delete();
return this.client.actions.ChannelDelete.handle(data).channel; this.client.channels.remove(dmChannel.id);
return dmChannel;
} }
/** /**

View File

@@ -7,12 +7,12 @@ const { RangeError } = require('../errors');
*/ */
class BitField { class BitField {
/** /**
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from * @param {BitFieldResolvable} [bits=this.constructor.defaultBit] Bit(s) to read from
*/ */
constructor(bits) { constructor(bits = this.constructor.defaultBit) {
/** /**
* Bitfield of the packed bits * Bitfield of the packed bits
* @type {number} * @type {number|bigint}
*/ */
this.bitfield = this.constructor.resolve(bits); this.bitfield = this.constructor.resolve(bits);
} }
@@ -23,7 +23,7 @@ class BitField {
* @returns {boolean} * @returns {boolean}
*/ */
any(bit) { any(bit) {
return (this.bitfield & this.constructor.resolve(bit)) !== 0; return (this.bitfield & this.constructor.resolve(bit)) !== this.constructor.defaultBit;
} }
/** /**
@@ -71,7 +71,7 @@ class BitField {
* @returns {BitField} These bits or new BitField if the instance is frozen. * @returns {BitField} These bits or new BitField if the instance is frozen.
*/ */
add(...bits) { add(...bits) {
let total = 0; let total = this.constructor.defaultBit;
for (const bit of bits) { for (const bit of bits) {
total |= this.constructor.resolve(bit); total |= this.constructor.resolve(bit);
} }
@@ -86,7 +86,7 @@ class BitField {
* @returns {BitField} These bits or new BitField if the instance is frozen. * @returns {BitField} These bits or new BitField if the instance is frozen.
*/ */
remove(...bits) { remove(...bits) {
let total = 0; let total = this.constructor.defaultBit;
for (const bit of bits) { for (const bit of bits) {
total |= this.constructor.resolve(bit); total |= this.constructor.resolve(bit);
} }
@@ -117,7 +117,7 @@ class BitField {
} }
toJSON() { toJSON() {
return this.bitfield; return typeof this.bitfield === 'number' ? this.bitfield : this.bitfield.toString();
} }
valueOf() { valueOf() {
@@ -133,18 +133,20 @@ class BitField {
* * A bit number (this can be a number literal or a value taken from {@link BitField.FLAGS}) * * A bit number (this can be a number literal or a value taken from {@link BitField.FLAGS})
* * An instance of BitField * * An instance of BitField
* * An Array of BitFieldResolvable * * An Array of BitFieldResolvable
* @typedef {number|BitField|BitFieldResolvable[]} BitFieldResolvable * @typedef {number|bigint|BitField|BitFieldResolvable[]} BitFieldResolvable
*/ */
/** /**
* Resolves bitfields to their numeric form. * Resolves bitfields to their numeric form.
* @param {BitFieldResolvable} [bit=0] - bit(s) to resolve * @param {BitFieldResolvable} [bit] - bit(s) to resolve
* @returns {number} * @returns {number|bigint}
*/ */
static resolve(bit = 0) { static resolve(bit) {
if (typeof bit === 'number' && bit >= 0) return bit; const { defaultBit } = this;
if (typeof bit === 'undefined') return defaultBit;
if (typeof defaultBit === typeof bit && bit >= defaultBit) return bit;
if (bit instanceof BitField) return bit.bitfield; if (bit instanceof BitField) return bit.bitfield;
if (Array.isArray(bit)) return bit.map(p => this.resolve(p)).reduce((prev, p) => prev | p, 0); if (Array.isArray(bit)) return bit.map(p => this.resolve(p)).reduce((prev, p) => prev | p, defaultBit);
if (typeof bit === 'string' && typeof this.FLAGS[bit] !== 'undefined') return this.FLAGS[bit]; if (typeof bit === 'string' && typeof this.FLAGS[bit] !== 'undefined') return this.FLAGS[bit];
throw new RangeError('BITFIELD_INVALID', bit); throw new RangeError('BITFIELD_INVALID', bit);
} }
@@ -158,4 +160,10 @@ class BitField {
*/ */
BitField.FLAGS = {}; BitField.FLAGS = {};
/**
* @type {number|bigint}
* @private
*/
BitField.defaultBit = 0;
module.exports = BitField; module.exports = BitField;

View File

@@ -30,7 +30,8 @@ const { Error, RangeError } = require('../errors');
* @property {number} [restSweepInterval=60] How frequently to delete inactive request buckets, in seconds * @property {number} [restSweepInterval=60] How frequently to delete inactive request buckets, in seconds
* (or 0 for never) * (or 0 for never)
* @property {number} [retryLimit=1] How many times to retry on 5XX errors (Infinity for indefinite amount of retries) * @property {number} [retryLimit=1] How many times to retry on 5XX errors (Infinity for indefinite amount of retries)
* @property {PresenceData} [presence] Presence data to use upon login * @property {PresenceData} [presence={}] Presence data to use upon login
* @property {IntentsResolvable} intents Intents to enable for this connection
* @property {WebsocketOptions} [ws] Options for the WebSocket * @property {WebsocketOptions} [ws] Options for the WebSocket
* @property {HTTPOptions} [http] HTTP options * @property {HTTPOptions} [http] HTTP options
*/ */
@@ -52,7 +53,6 @@ exports.DefaultOptions = {
* @typedef {Object} WebsocketOptions * @typedef {Object} WebsocketOptions
* @property {number} [large_threshold=50] Number of members in a guild after which offline users will no longer be * @property {number} [large_threshold=50] Number of members in a guild after which offline users will no longer be
* sent in the initial guild member list, must be between 50 and 250 * sent in the initial guild member list, must be between 50 and 250
* @property {IntentsResolvable} [intents] Intents to enable for this connection
*/ */
ws: { ws: {
large_threshold: 50, large_threshold: 50,
@@ -62,7 +62,7 @@ exports.DefaultOptions = {
$browser: 'discord.js', $browser: 'discord.js',
$device: 'discord.js', $device: 'discord.js',
}, },
version: 6, version: 8,
}, },
/** /**
@@ -75,7 +75,7 @@ exports.DefaultOptions = {
* @property {string} [template='https://discord.new'] Base url of templates * @property {string} [template='https://discord.new'] Base url of templates
*/ */
http: { http: {
version: 7, version: 8,
api: 'https://discord.com/api', api: 'https://discord.com/api',
cdn: 'https://cdn.discordapp.com', cdn: 'https://cdn.discordapp.com',
invite: 'https://discord.gg', invite: 'https://discord.gg',
@@ -557,6 +557,7 @@ exports.VerificationLevels = ['NONE', 'LOW', 'MEDIUM', 'HIGH', 'VERY_HIGH'];
* * UNKNOWN_GUILD_TEMPLATE * * UNKNOWN_GUILD_TEMPLATE
* * BOT_PROHIBITED_ENDPOINT * * BOT_PROHIBITED_ENDPOINT
* * BOT_ONLY_ENDPOINT * * BOT_ONLY_ENDPOINT
* * ANNOUNCEMENT_EDIT_LIMIT_EXCEEDED
* * CHANNEL_HIT_WRITE_RATELIMIT * * CHANNEL_HIT_WRITE_RATELIMIT
* * MAXIMUM_GUILDS * * MAXIMUM_GUILDS
* * MAXIMUM_FRIENDS * * MAXIMUM_FRIENDS
@@ -593,7 +594,9 @@ exports.VerificationLevels = ['NONE', 'LOW', 'MEDIUM', 'HIGH', 'VERY_HIGH'];
* * CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL * * CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL
* * INVALID_OR_TAKEN_INVITE_CODE * * INVALID_OR_TAKEN_INVITE_CODE
* * CANNOT_EXECUTE_ON_SYSTEM_MESSAGE * * CANNOT_EXECUTE_ON_SYSTEM_MESSAGE
* * CANNOT_EXECUTE_ON_CHANNEL_TYPE
* * INVALID_OAUTH_TOKEN * * INVALID_OAUTH_TOKEN
* * INVALID_RECIPIENTS
* * BULK_DELETE_MESSAGE_TOO_OLD * * BULK_DELETE_MESSAGE_TOO_OLD
* * INVALID_FORM_BODY * * INVALID_FORM_BODY
* * INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT * * INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT
@@ -623,6 +626,7 @@ exports.APIErrors = {
UNKNOWN_GUILD_TEMPLATE: 10057, UNKNOWN_GUILD_TEMPLATE: 10057,
BOT_PROHIBITED_ENDPOINT: 20001, BOT_PROHIBITED_ENDPOINT: 20001,
BOT_ONLY_ENDPOINT: 20002, BOT_ONLY_ENDPOINT: 20002,
ANNOUNCEMENT_EDIT_LIMIT_EXCEEDED: 20022,
CHANNEL_HIT_WRITE_RATELIMIT: 20028, CHANNEL_HIT_WRITE_RATELIMIT: 20028,
MAXIMUM_GUILDS: 30001, MAXIMUM_GUILDS: 30001,
MAXIMUM_FRIENDS: 30002, MAXIMUM_FRIENDS: 30002,
@@ -659,7 +663,9 @@ exports.APIErrors = {
CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL: 50019, CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL: 50019,
INVALID_OR_TAKEN_INVITE_CODE: 50020, INVALID_OR_TAKEN_INVITE_CODE: 50020,
CANNOT_EXECUTE_ON_SYSTEM_MESSAGE: 50021, CANNOT_EXECUTE_ON_SYSTEM_MESSAGE: 50021,
CANNOT_EXECUTE_ON_CHANNEL_TYPE: 50024,
INVALID_OAUTH_TOKEN: 50025, INVALID_OAUTH_TOKEN: 50025,
INVALID_RECIPIENTS: 50033,
BULK_DELETE_MESSAGE_TOO_OLD: 50034, BULK_DELETE_MESSAGE_TOO_OLD: 50034,
INVALID_FORM_BODY: 50035, INVALID_FORM_BODY: 50035,
INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT: 50036, INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT: 50036,
@@ -703,8 +709,26 @@ exports.WebhookTypes = [
'Channel Follower', 'Channel Follower',
]; ];
/**
* An overwrite type:
* * role
* * member
* @typedef {string} OverwriteType
*/
exports.OverwriteTypes = createEnum(['role', 'member']);
function keyMirror(arr) { function keyMirror(arr) {
let tmp = Object.create(null); let tmp = Object.create(null);
for (const value of arr) tmp[value] = value; for (const value of arr) tmp[value] = value;
return tmp; return tmp;
} }
function createEnum(keys) {
const obj = {};
for (const [index, key] of keys.entries()) {
if (key === null) continue;
obj[key] = index;
obj[index] = key;
}
return obj;
}

View File

@@ -15,6 +15,12 @@ class MessageFlags extends BitField {}
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from * @param {BitFieldResolvable} [bits=0] Bit(s) to read from
*/ */
/**
* Bitfield of the packed bits
* @type {number}
* @name MessageFlags#bitfield
*/
/** /**
* Numeric message flags. All available properties: * Numeric message flags. All available properties:
* * `CROSSPOSTED` * * `CROSSPOSTED`

View File

@@ -10,10 +10,9 @@ const BitField = require('./BitField');
*/ */
class Permissions extends BitField { class Permissions extends BitField {
/** /**
* @name Permissions * Bitfield of the packed bits
* @kind constructor * @type {bigint}
* @memberof Permissions * @name Permissions#bitfield
* @param {PermissionResolvable} [bits=0] Bit(s) to read from
*/ */
/** /**
@@ -22,7 +21,7 @@ class Permissions extends BitField {
* * A permission number * * A permission number
* * An instance of Permissions * * An instance of Permissions
* * An Array of PermissionResolvable * * An Array of PermissionResolvable
* @typedef {string|number|Permissions|PermissionResolvable[]} PermissionResolvable * @typedef {string|bigint|Permissions|PermissionResolvable[]} PermissionResolvable
*/ */
/** /**
@@ -79,53 +78,55 @@ class Permissions extends BitField {
* * `MANAGE_ROLES` * * `MANAGE_ROLES`
* * `MANAGE_WEBHOOKS` * * `MANAGE_WEBHOOKS`
* * `MANAGE_EMOJIS` * * `MANAGE_EMOJIS`
* @type {Object} * @type {Object<string, bigint>}
* @see {@link https://discord.com/developers/docs/topics/permissions} * @see {@link https://discord.com/developers/docs/topics/permissions}
*/ */
Permissions.FLAGS = { Permissions.FLAGS = {
CREATE_INSTANT_INVITE: 1 << 0, CREATE_INSTANT_INVITE: 1n << 0n,
KICK_MEMBERS: 1 << 1, KICK_MEMBERS: 1n << 1n,
BAN_MEMBERS: 1 << 2, BAN_MEMBERS: 1n << 2n,
ADMINISTRATOR: 1 << 3, ADMINISTRATOR: 1n << 3n,
MANAGE_CHANNELS: 1 << 4, MANAGE_CHANNELS: 1n << 4n,
MANAGE_GUILD: 1 << 5, MANAGE_GUILD: 1n << 5n,
ADD_REACTIONS: 1 << 6, ADD_REACTIONS: 1n << 6n,
VIEW_AUDIT_LOG: 1 << 7, VIEW_AUDIT_LOG: 1n << 7n,
PRIORITY_SPEAKER: 1 << 8, PRIORITY_SPEAKER: 1n << 8n,
STREAM: 1 << 9, STREAM: 1n << 9n,
VIEW_CHANNEL: 1 << 10, VIEW_CHANNEL: 1n << 10n,
SEND_MESSAGES: 1 << 11, SEND_MESSAGES: 1n << 11n,
SEND_TTS_MESSAGES: 1 << 12, SEND_TTS_MESSAGES: 1n << 12n,
MANAGE_MESSAGES: 1 << 13, MANAGE_MESSAGES: 1n << 13n,
EMBED_LINKS: 1 << 14, EMBED_LINKS: 1n << 14n,
ATTACH_FILES: 1 << 15, ATTACH_FILES: 1n << 15n,
READ_MESSAGE_HISTORY: 1 << 16, READ_MESSAGE_HISTORY: 1n << 16n,
MENTION_EVERYONE: 1 << 17, MENTION_EVERYONE: 1n << 17n,
USE_EXTERNAL_EMOJIS: 1 << 18, USE_EXTERNAL_EMOJIS: 1n << 18n,
VIEW_GUILD_INSIGHTS: 1 << 19, VIEW_GUILD_INSIGHTS: 1n << 19n,
CONNECT: 1 << 20, CONNECT: 1n << 20n,
SPEAK: 1 << 21, SPEAK: 1n << 21n,
MUTE_MEMBERS: 1 << 22, MUTE_MEMBERS: 1n << 22n,
DEAFEN_MEMBERS: 1 << 23, DEAFEN_MEMBERS: 1n << 23n,
MOVE_MEMBERS: 1 << 24, MOVE_MEMBERS: 1n << 24n,
USE_VAD: 1 << 25, USE_VAD: 1n << 25n,
CHANGE_NICKNAME: 1 << 26, CHANGE_NICKNAME: 1n << 26n,
MANAGE_NICKNAMES: 1 << 27, MANAGE_NICKNAMES: 1n << 27n,
MANAGE_ROLES: 1 << 28, MANAGE_ROLES: 1n << 28n,
MANAGE_WEBHOOKS: 1 << 29, MANAGE_WEBHOOKS: 1n << 29n,
MANAGE_EMOJIS: 1 << 30, MANAGE_EMOJIS: 1n << 30n,
}; };
/** /**
* Bitfield representing every permission combined * Bitfield representing every permission combined
* @type {number} * @type {bigint}
*/ */
Permissions.ALL = Object.values(Permissions.FLAGS).reduce((all, p) => all | p, 0); Permissions.ALL = Object.values(Permissions.FLAGS).reduce((all, p) => all | p, 0n);
/** /**
* Bitfield representing the default permissions for users * Bitfield representing the default permissions for users
* @type {number} * @type {bigint}
*/ */
Permissions.DEFAULT = 104324673; Permissions.DEFAULT = BigInt(104324673);
Permissions.defaultBit = BigInt(0);
module.exports = Permissions; module.exports = Permissions;

View File

@@ -16,6 +16,12 @@ class Speaking extends BitField {}
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from * @param {BitFieldResolvable} [bits=0] Bit(s) to read from
*/ */
/**
* Bitfield of the packed bits
* @type {number}
* @name Speaking#bitfield
*/
/** /**
* Numeric speaking flags. All available properties: * Numeric speaking flags. All available properties:
* * `SPEAKING` * * `SPEAKING`

View File

@@ -17,6 +17,12 @@ class SystemChannelFlags extends BitField {}
* @param {SystemChannelFlagsResolvable} [bits=0] Bit(s) to read from * @param {SystemChannelFlagsResolvable} [bits=0] Bit(s) to read from
*/ */
/**
* Bitfield of the packed bits
* @type {number}
* @name SystemChannelFlags#bitfield
*/
/** /**
* Data that can be resolved to give a sytem channel flag bitfield. This can be: * Data that can be resolved to give a sytem channel flag bitfield. This can be:
* * A string (see {@link SystemChannelFlags.FLAGS}) * * A string (see {@link SystemChannelFlags.FLAGS})

View File

@@ -14,6 +14,12 @@ class UserFlags extends BitField {}
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from * @param {BitFieldResolvable} [bits=0] Bit(s) to read from
*/ */
/**
* Bitfield of the packed bits
* @type {number}
* @name UserFlags#bitfield
*/
/** /**
* Numeric user flags. All available properties: * Numeric user flags. All available properties:
* * `DISCORD_EMPLOYEE` * * `DISCORD_EMPLOYEE`

View File

@@ -2,9 +2,11 @@
const assert = require('assert'); const assert = require('assert');
const { token } = require('./auth'); const { token } = require('./auth');
const { Client } = require('../src'); const { Client, Intents } = require('../src');
const client = new Client(); const client = new Client({
intents: Intents.NON_PRIVILEGED,
});
client.on('ready', async () => { client.on('ready', async () => {
try { try {

View File

@@ -9,7 +9,9 @@ const Discord = require('../src');
console.time('magic'); console.time('magic');
const client = new Discord.Client(); const client = new Discord.Client({
intents: Discord.Intents.NON_PRIVILEGED
});
client client
.login(token) .login(token)

View File

@@ -7,7 +7,9 @@ const fetch = require('node-fetch');
const { owner, token } = require('./auth.js'); const { owner, token } = require('./auth.js');
const Discord = require('../src'); const Discord = require('../src');
const client = new Discord.Client(); const client = new Discord.Client({
intents: Discord.Intents.NON_PRIVILEGED,
});
const fill = c => Array(4).fill(c.repeat(1000)); const fill = c => Array(4).fill(c.repeat(1000));
const buffer = l => fetch(l).then(res => res.buffer()); const buffer = l => fetch(l).then(res => res.buffer());

View File

@@ -6,17 +6,13 @@ const Discord = require('../src');
const client = new Discord.Client({ const client = new Discord.Client({
shards: process.argv[2], shards: process.argv[2],
shardCount: process.argv[3], shardCount: process.argv[3],
intents: Discord.Intents.NON_PRIVILEGED,
}); });
client.on('message', msg => { client.on('message', msg => {
if (msg.content.startsWith('?eval') && msg.author.id === '66564597481480192') { if (msg.content.startsWith('?eval') && msg.author.id === '66564597481480192') {
try { try {
const com = eval( const com = eval(msg.content.split(' ').slice(1).join(' '));
msg.content
.split(' ')
.slice(1)
.join(' '),
);
msg.channel.send(com, { code: true }); msg.channel.send(com, { code: true });
} catch (e) { } catch (e) {
msg.channel.send(e, { code: true }); msg.channel.send(e, { code: true });

View File

@@ -8,6 +8,7 @@ const log = (...args) => console.log(process.uptime().toFixed(3), ...args);
const client = new Discord.Client({ const client = new Discord.Client({
shardCount: 2, shardCount: 2,
intents: Discord.Intents.NON_PRIVILEGED,
}); });
client.on('debug', log); client.on('debug', log);

View File

@@ -5,7 +5,10 @@ const ytdl = require('ytdl-core');
const auth = require('./auth.js'); const auth = require('./auth.js');
const Discord = require('../src'); const Discord = require('../src');
const client = new Discord.Client({ partials: [] }); const client = new Discord.Client({
partials: [],
intents: Discord.Intents.NON_PRIVILEGED,
});
client client
.login(auth.token) .login(auth.token)

View File

@@ -7,7 +7,9 @@ const fetch = require('node-fetch');
const { owner, token, webhookChannel, webhookToken } = require('./auth.js'); const { owner, token, webhookChannel, webhookToken } = require('./auth.js');
const Discord = require('../src'); const Discord = require('../src');
const client = new Discord.Client(); const client = new Discord.Client({
intents: Discord.Intents.NON_PRIVILEGED,
});
const fill = c => Array(4).fill(c.repeat(1000)); const fill = c => Array(4).fill(c.repeat(1000));
const buffer = l => fetch(l).then(res => res.buffer()); const buffer = l => fetch(l).then(res => res.buffer());

131
typings/index.d.ts vendored
View File

@@ -9,6 +9,11 @@ declare enum ChannelType {
unknown = 7, unknown = 7,
} }
declare enum OverwriteTypes {
role = 0,
member = 1,
}
declare module 'discord.js' { declare module 'discord.js' {
import BaseCollection from '@discordjs/collection'; import BaseCollection from '@discordjs/collection';
import { ChildProcess } from 'child_process'; import { ChildProcess } from 'child_process';
@@ -47,7 +52,7 @@ declare module 'discord.js' {
export class ActivityFlags extends BitField<ActivityFlagsString> { export class ActivityFlags extends BitField<ActivityFlagsString> {
public static FLAGS: Record<ActivityFlagsString, number>; public static FLAGS: Record<ActivityFlagsString, number>;
public static resolve(bit?: BitFieldResolvable<ActivityFlagsString>): number; public static resolve(bit?: BitFieldResolvable<ActivityFlagsString, number>): number;
} }
export class APIMessage { export class APIMessage {
@@ -118,7 +123,7 @@ declare module 'discord.js' {
} }
export class BaseClient extends EventEmitter { export class BaseClient extends EventEmitter {
constructor(options?: ClientOptions); constructor(options?: ClientOptions | WebhookClientOptions);
private _timeouts: Set<NodeJS.Timeout>; private _timeouts: Set<NodeJS.Timeout>;
private _intervals: Set<NodeJS.Timeout>; private _intervals: Set<NodeJS.Timeout>;
private _immediates: Set<NodeJS.Immediate>; private _immediates: Set<NodeJS.Immediate>;
@@ -127,7 +132,7 @@ declare module 'discord.js' {
private decrementMaxListeners(): void; private decrementMaxListeners(): void;
private incrementMaxListeners(): void; private incrementMaxListeners(): void;
public options: ClientOptions; public options: ClientOptions | WebhookClientOptions;
public clearInterval(interval: NodeJS.Timeout): void; public clearInterval(interval: NodeJS.Timeout): void;
public clearTimeout(timeout: NodeJS.Timeout): void; public clearTimeout(timeout: NodeJS.Timeout): void;
public clearImmediate(timeout: NodeJS.Immediate): void; public clearImmediate(timeout: NodeJS.Immediate): void;
@@ -155,23 +160,23 @@ declare module 'discord.js' {
public broadcast: VoiceBroadcast; public broadcast: VoiceBroadcast;
} }
export class BitField<S extends string> { export class BitField<S extends string, N extends number | bigint = number> {
constructor(bits?: BitFieldResolvable<S>); constructor(bits?: BitFieldResolvable<S, N>);
public bitfield: number; public bitfield: N;
public add(...bits: BitFieldResolvable<S>[]): BitField<S>; public add(...bits: BitFieldResolvable<S, N>[]): BitField<S, N>;
public any(bit: BitFieldResolvable<S>): boolean; public any(bit: BitFieldResolvable<S, N>): boolean;
public equals(bit: BitFieldResolvable<S>): boolean; public equals(bit: BitFieldResolvable<S, N>): boolean;
public freeze(): Readonly<BitField<S>>; public freeze(): Readonly<BitField<S, N>>;
public has(bit: BitFieldResolvable<S>): boolean; public has(bit: BitFieldResolvable<S, N>): boolean;
public missing(bits: BitFieldResolvable<S>, ...hasParam: readonly unknown[]): S[]; public missing(bits: BitFieldResolvable<S, N>, ...hasParam: readonly unknown[]): S[];
public remove(...bits: BitFieldResolvable<S>[]): BitField<S>; public remove(...bits: BitFieldResolvable<S, N>[]): BitField<S, N>;
public serialize(...hasParam: readonly unknown[]): Record<S, boolean>; public serialize(...hasParam: readonly unknown[]): Record<S, boolean>;
public toArray(...hasParam: readonly unknown[]): S[]; public toArray(...hasParam: readonly unknown[]): S[];
public toJSON(): number; public toJSON(): number;
public valueOf(): number; public valueOf(): number;
public [Symbol.iterator](): IterableIterator<S>; public [Symbol.iterator](): IterableIterator<S>;
public static FLAGS: object; public static FLAGS: object;
public static resolve(bit?: BitFieldResolvable<any>): number; public static resolve(bit?: BitFieldResolvable<any, number | bigint>): number | bigint;
} }
export class CategoryChannel extends GuildChannel { export class CategoryChannel extends GuildChannel {
@@ -193,14 +198,15 @@ declare module 'discord.js' {
} }
export class Client extends BaseClient { export class Client extends BaseClient {
constructor(options?: ClientOptions); constructor(options: ClientOptions);
private actions: object; private actions: object;
private _eval(script: string): any; private _eval(script: string): any;
private _validateOptions(options?: ClientOptions): void; private _validateOptions(options: ClientOptions): void;
public channels: ChannelManager; public channels: ChannelManager;
public readonly emojis: BaseGuildEmojiManager; public readonly emojis: BaseGuildEmojiManager;
public guilds: GuildManager; public guilds: GuildManager;
public options: ClientOptions;
public readyAt: Date | null; public readyAt: Date | null;
public readonly readyTimestamp: number | null; public readonly readyTimestamp: number | null;
public shard: ShardClientUtil | null; public shard: ShardClientUtil | null;
@@ -258,13 +264,14 @@ declare module 'discord.js' {
export class ClientUser extends User { export class ClientUser extends User {
public mfaEnabled: boolean; public mfaEnabled: boolean;
public verified: boolean; public verified: boolean;
public setActivity(options?: ActivityOptions): Promise<Presence>; public edit(data: ClientUserEditData): Promise<this>;
public setActivity(name: string, options?: ActivityOptions): Promise<Presence>; public setActivity(options?: ActivityOptions): Presence;
public setActivity(name: string, options?: ActivityOptions): Presence;
public setAFK(afk: boolean): Promise<Presence>; public setAFK(afk: boolean): Promise<Presence>;
public setAvatar(avatar: BufferResolvable | Base64Resolvable): Promise<ClientUser>; public setAvatar(avatar: BufferResolvable | Base64Resolvable): Promise<this>;
public setPresence(data: PresenceData): Promise<Presence>; public setPresence(data: PresenceData): Presence;
public setStatus(status: PresenceStatusData, shardID?: number | number[]): Promise<Presence>; public setStatus(status: PresenceStatusData, shardID?: number | number[]): Presence;
public setUsername(username: string): Promise<ClientUser>; public setUsername(username: string): Promise<this>;
} }
export class ClientVoiceManager { export class ClientVoiceManager {
@@ -517,6 +524,7 @@ declare module 'discord.js' {
MessageTypes: MessageType[]; MessageTypes: MessageType[];
SystemMessageTypes: SystemMessageType[]; SystemMessageTypes: SystemMessageType[];
ActivityTypes: ActivityType[]; ActivityTypes: ActivityType[];
OverwriteTypes: OverwriteTypes;
ExplicitContentFilterLevels: ExplicitContentFilterLevel[]; ExplicitContentFilterLevels: ExplicitContentFilterLevel[];
DefaultMessageNotifications: DefaultMessageNotifications[]; DefaultMessageNotifications: DefaultMessageNotifications[];
VerificationLevels: VerificationLevel[]; VerificationLevels: VerificationLevel[];
@@ -587,9 +595,6 @@ declare module 'discord.js' {
public deleted: boolean; public deleted: boolean;
public description: string | null; public description: string | null;
public discoverySplash: string | null; public discoverySplash: string | null;
public embedChannel: GuildChannel | null;
public embedChannelID: Snowflake | null;
public embedEnabled: boolean;
public emojis: GuildEmojiManager; public emojis: GuildEmojiManager;
public explicitContentFilter: ExplicitContentFilterLevel; public explicitContentFilter: ExplicitContentFilterLevel;
public features: GuildFeatures[]; public features: GuildFeatures[];
@@ -645,8 +650,7 @@ declare module 'discord.js' {
public fetchAuditLogs(options?: GuildAuditLogsFetchOptions): Promise<GuildAuditLogs>; public fetchAuditLogs(options?: GuildAuditLogsFetchOptions): Promise<GuildAuditLogs>;
public fetchBan(user: UserResolvable): Promise<{ user: User; reason: string }>; public fetchBan(user: UserResolvable): Promise<{ user: User; reason: string }>;
public fetchBans(): Promise<Collection<Snowflake, { user: User; reason: string }>>; public fetchBans(): Promise<Collection<Snowflake, { user: User; reason: string }>>;
public fetchEmbed(): Promise<GuildWidget>; public fetchIntegrations(): Promise<Collection<string, Integration>>;
public fetchIntegrations(options?: FetchIntegrationsOptions): Promise<Collection<string, Integration>>;
public fetchInvites(): Promise<Collection<string, Invite>>; public fetchInvites(): Promise<Collection<string, Invite>>;
public fetchPreview(): Promise<GuildPreview>; public fetchPreview(): Promise<GuildPreview>;
public fetchTemplates(): Promise<Collection<GuildTemplate['code'], GuildTemplate>>; public fetchTemplates(): Promise<Collection<GuildTemplate['code'], GuildTemplate>>;
@@ -666,7 +670,6 @@ declare module 'discord.js' {
reason?: string, reason?: string,
): Promise<Guild>; ): Promise<Guild>;
public setDiscoverySplash(discoverySplash: Base64Resolvable | null, reason?: string): Promise<Guild>; public setDiscoverySplash(discoverySplash: Base64Resolvable | null, reason?: string): Promise<Guild>;
public setEmbed(embed: GuildWidgetData, reason?: string): Promise<Guild>;
public setExplicitContentFilter( public setExplicitContentFilter(
explicitContentFilter: ExplicitContentFilterLevel | number, explicitContentFilter: ExplicitContentFilterLevel | number,
reason?: string, reason?: string,
@@ -920,7 +923,7 @@ declare module 'discord.js' {
public static PRIVILEGED: number; public static PRIVILEGED: number;
public static ALL: number; public static ALL: number;
public static NON_PRIVILEGED: number; public static NON_PRIVILEGED: number;
public static resolve(bit?: BitFieldResolvable<IntentsString>): number; public static resolve(bit?: BitFieldResolvable<IntentsString, number>): number;
} }
export class Invite extends Base { export class Invite extends Base {
@@ -1095,7 +1098,7 @@ declare module 'discord.js' {
export class MessageFlags extends BitField<MessageFlagsString> { export class MessageFlags extends BitField<MessageFlagsString> {
public static FLAGS: Record<MessageFlagsString, number>; public static FLAGS: Record<MessageFlagsString, number>;
public static resolve(bit?: BitFieldResolvable<MessageFlagsString>): number; public static resolve(bit?: BitFieldResolvable<MessageFlagsString, number>): number;
} }
export class MessageMentions { export class MessageMentions {
@@ -1189,17 +1192,17 @@ declare module 'discord.js' {
public static resolve(overwrite: OverwriteResolvable, guild: Guild): RawOverwriteData; public static resolve(overwrite: OverwriteResolvable, guild: Guild): RawOverwriteData;
} }
export class Permissions extends BitField<PermissionString> { export class Permissions extends BitField<PermissionString, bigint> {
public any(permission: PermissionResolvable, checkAdmin?: boolean): boolean; public any(permission: PermissionResolvable, checkAdmin?: boolean): boolean;
public has(permission: PermissionResolvable, checkAdmin?: boolean): boolean; public has(permission: PermissionResolvable, checkAdmin?: boolean): boolean;
public missing(bits: BitFieldResolvable<PermissionString>, checkAdmin?: boolean): PermissionString[]; public missing(bits: BitFieldResolvable<PermissionString, bigint>, checkAdmin?: boolean): PermissionString[];
public serialize(checkAdmin?: boolean): Record<PermissionString, boolean>; public serialize(checkAdmin?: boolean): Record<PermissionString, boolean>;
public toArray(checkAdmin?: boolean): PermissionString[]; public toArray(checkAdmin?: boolean): PermissionString[];
public static ALL: number; public static ALL: bigint;
public static DEFAULT: number; public static DEFAULT: bigint;
public static FLAGS: PermissionFlags; public static FLAGS: PermissionFlags;
public static resolve(permission?: PermissionResolvable): number; public static resolve(permission?: PermissionResolvable): bigint;
} }
export class Presence { export class Presence {
@@ -1410,7 +1413,7 @@ declare module 'discord.js' {
export class Speaking extends BitField<SpeakingString> { export class Speaking extends BitField<SpeakingString> {
public static FLAGS: Record<SpeakingString, number>; public static FLAGS: Record<SpeakingString, number>;
public static resolve(bit?: BitFieldResolvable<SpeakingString>): number; public static resolve(bit?: BitFieldResolvable<SpeakingString, number>): number;
} }
export class StoreChannel extends GuildChannel { export class StoreChannel extends GuildChannel {
@@ -1468,7 +1471,7 @@ declare module 'discord.js' {
export class SystemChannelFlags extends BitField<SystemChannelFlagsString> { export class SystemChannelFlags extends BitField<SystemChannelFlagsString> {
public static FLAGS: Record<SystemChannelFlagsString, number>; public static FLAGS: Record<SystemChannelFlagsString, number>;
public static resolve(bit?: BitFieldResolvable<SystemChannelFlagsString>): number; public static resolve(bit?: BitFieldResolvable<SystemChannelFlagsString, number>): number;
} }
export class Team extends Base { export class Team extends Base {
@@ -1548,7 +1551,7 @@ declare module 'discord.js' {
export class UserFlags extends BitField<UserFlagsString> { export class UserFlags extends BitField<UserFlagsString> {
public static FLAGS: Record<UserFlagsString, number>; public static FLAGS: Record<UserFlagsString, number>;
public static resolve(bit?: BitFieldResolvable<UserFlagsString>): number; public static resolve(bit?: BitFieldResolvable<UserFlagsString, number>): number;
} }
export class Util { export class Util {
@@ -1655,7 +1658,7 @@ declare module 'discord.js' {
public voiceManager: ClientVoiceManager; public voiceManager: ClientVoiceManager;
public disconnect(): void; public disconnect(): void;
public play(input: VoiceBroadcast | Readable | string, options?: StreamOptions): StreamDispatcher; public play(input: VoiceBroadcast | Readable | string, options?: StreamOptions): StreamDispatcher;
public setSpeaking(value: BitFieldResolvable<SpeakingString>): void; public setSpeaking(value: BitFieldResolvable<SpeakingString, number>): void;
public on(event: 'authenticated' | 'closing' | 'newSession' | 'ready' | 'reconnecting', listener: () => void): this; public on(event: 'authenticated' | 'closing' | 'newSession' | 'ready' | 'reconnecting', listener: () => void): this;
public on(event: 'debug', listener: (message: string) => void): this; public on(event: 'debug', listener: (message: string) => void): this;
@@ -1756,8 +1759,9 @@ declare module 'discord.js' {
} }
export class WebhookClient extends WebhookMixin(BaseClient) { export class WebhookClient extends WebhookMixin(BaseClient) {
constructor(id: string, token: string, options?: ClientOptions); constructor(id: string, token: string, options?: WebhookClientOptions);
public client: this; public client: this;
public options: WebhookClientOptions;
public token: string; public token: string;
} }
@@ -2157,6 +2161,7 @@ declare module 'discord.js' {
UNKNOWN_GUILD_TEMPLATE: 10057; UNKNOWN_GUILD_TEMPLATE: 10057;
BOT_PROHIBITED_ENDPOINT: 20001; BOT_PROHIBITED_ENDPOINT: 20001;
BOT_ONLY_ENDPOINT: 20002; BOT_ONLY_ENDPOINT: 20002;
ANNOUNCEMENT_EDIT_LIMIT_EXCEEDED: 20022;
CHANNEL_HIT_WRITE_RATELIMIT: 20028; CHANNEL_HIT_WRITE_RATELIMIT: 20028;
MAXIMUM_GUILDS: 30001; MAXIMUM_GUILDS: 30001;
MAXIMUM_FRIENDS: 30002; MAXIMUM_FRIENDS: 30002;
@@ -2323,17 +2328,17 @@ declare module 'discord.js' {
type Base64String = string; type Base64String = string;
type BitFieldResolvable<T extends string> = type BitFieldResolvable<T extends string, N extends number | bigint> =
| RecursiveReadonlyArray<T | number | Readonly<BitField<T>>> | RecursiveReadonlyArray<T | N | Readonly<BitField<T, N>>>
| T | T
| number | N
| Readonly<BitField<T>>; | Readonly<BitField<T, N>>;
type BufferResolvable = Buffer | string; type BufferResolvable = Buffer | string;
interface ChannelCreationOverwrites { interface ChannelCreationOverwrites {
allow?: PermissionResolvable | number; allow?: PermissionResolvable;
deny?: PermissionResolvable | number; deny?: PermissionResolvable;
id: RoleResolvable | UserResolvable; id: RoleResolvable | UserResolvable;
} }
@@ -2366,8 +2371,8 @@ declare module 'discord.js' {
type ChannelResolvable = Channel | Snowflake; type ChannelResolvable = Channel | Snowflake;
interface ClientEvents { interface ClientEvents {
channelCreate: [channel: Channel]; channelCreate: [channel: GuildChannel];
channelDelete: [channel: Channel | PartialDMChannel]; channelDelete: [channel: DMChannel | GuildChannel];
channelPinsUpdate: [channel: Channel | PartialDMChannel, date: Date]; channelPinsUpdate: [channel: Channel | PartialDMChannel, date: Date];
channelUpdate: [oldChannel: Channel, newChannel: Channel]; channelUpdate: [oldChannel: Channel, newChannel: Channel];
debug: [message: string]; debug: [message: string];
@@ -2436,6 +2441,7 @@ declare module 'discord.js' {
restSweepInterval?: number; restSweepInterval?: number;
retryLimit?: number; retryLimit?: number;
presence?: PresenceData; presence?: PresenceData;
intents: BitFieldResolvable<IntentsString, number>;
ws?: WebSocketOptions; ws?: WebSocketOptions;
http?: HTTPOptions; http?: HTTPOptions;
} }
@@ -2448,6 +2454,11 @@ declare module 'discord.js' {
desktop?: ClientPresenceStatus; desktop?: ClientPresenceStatus;
} }
interface ClientUserEditData {
username?: string;
avatar?: BufferResolvable | Base64Resolvable;
}
interface CloseEvent { interface CloseEvent {
wasClean: boolean; wasClean: boolean;
code: number; code: number;
@@ -2571,10 +2582,6 @@ declare module 'discord.js' {
User: typeof User; User: typeof User;
} }
interface FetchIntegrationsOptions {
includeApplications?: boolean;
}
interface FetchMemberOptions { interface FetchMemberOptions {
user: UserResolvable; user: UserResolvable;
cache?: boolean; cache?: boolean;
@@ -2871,7 +2878,7 @@ declare module 'discord.js' {
content?: StringResolvable; content?: StringResolvable;
embed?: MessageEmbed | MessageEmbedOptions | null; embed?: MessageEmbed | MessageEmbedOptions | null;
code?: string | boolean; code?: string | boolean;
flags?: BitFieldResolvable<MessageFlagsString>; flags?: BitFieldResolvable<MessageFlagsString, number>;
allowedMentions?: MessageMentionOptions; allowedMentions?: MessageMentionOptions;
} }
@@ -2999,13 +3006,13 @@ declare module 'discord.js' {
type OverwriteType = 'member' | 'role'; type OverwriteType = 'member' | 'role';
interface PermissionFlags extends Record<PermissionString, number> {} interface PermissionFlags extends Record<PermissionString, bigint> {}
interface PermissionObject extends Record<PermissionString, boolean> {} interface PermissionObject extends Record<PermissionString, boolean> {}
interface PermissionOverwriteOption extends Partial<Record<PermissionString, boolean | null>> {} interface PermissionOverwriteOption extends Partial<Record<PermissionString, boolean | null>> {}
type PermissionResolvable = BitFieldResolvable<PermissionString>; type PermissionResolvable = BitFieldResolvable<PermissionString, bigint>;
type PermissionString = type PermissionString =
| 'CREATE_INSTANT_INVITE' | 'CREATE_INSTANT_INVITE'
@@ -3193,9 +3200,9 @@ declare module 'discord.js' {
interface RawOverwriteData { interface RawOverwriteData {
id: Snowflake; id: Snowflake;
allow: number; allow: string;
deny: number; deny: string;
type: OverwriteType; type: number;
} }
interface ReactionCollectorOptions extends CollectorOptions { interface ReactionCollectorOptions extends CollectorOptions {
@@ -3262,7 +3269,7 @@ declare module 'discord.js' {
type SystemChannelFlagsString = 'WELCOME_MESSAGE_DISABLED' | 'BOOST_MESSAGE_DISABLED'; type SystemChannelFlagsString = 'WELCOME_MESSAGE_DISABLED' | 'BOOST_MESSAGE_DISABLED';
type SystemChannelFlagsResolvable = BitFieldResolvable<SystemChannelFlagsString>; type SystemChannelFlagsResolvable = BitFieldResolvable<SystemChannelFlagsString, number>;
type SystemMessageType = Exclude<MessageType, 'DEFAULT' | 'REPLY'>; type SystemMessageType = Exclude<MessageType, 'DEFAULT' | 'REPLY'>;
@@ -3297,6 +3304,11 @@ declare module 'discord.js' {
type VoiceStatus = number; type VoiceStatus = number;
type WebhookClientOptions = Pick<
ClientOptions,
'allowedMentions' | 'restTimeOffset' | 'restRequestTimeout' | 'retryLimit' | 'http'
>;
interface WebhookEditData { interface WebhookEditData {
name?: string; name?: string;
avatar?: BufferResolvable; avatar?: BufferResolvable;
@@ -3331,7 +3343,6 @@ declare module 'discord.js' {
interface WebSocketOptions { interface WebSocketOptions {
large_threshold?: number; large_threshold?: number;
compress?: boolean; compress?: boolean;
intents?: BitFieldResolvable<IntentsString> | number;
properties?: WebSocketProperties; properties?: WebSocketProperties;
} }

View File

@@ -1,8 +1,10 @@
/// <reference path="index.d.ts" /> /// <reference path="index.d.ts" />
import { Client, Message, MessageAttachment, MessageEmbed } from 'discord.js'; import { Client, Intents, Message, MessageAttachment, MessageEmbed } from 'discord.js';
const client: Client = new Client(); const client: Client = new Client({
intents: Intents.NON_PRIVILEGED,
});
client.on('ready', () => { client.on('ready', () => {
console.log(`Client is logged in as ${client.user!.tag} and ready!`); console.log(`Client is logged in as ${client.user!.tag} and ready!`);