mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-10 00:23:30 +01:00
refactor: switch api and gateway to V8 (#4879)
Co-authored-by: Jan <66554238+Vaporox@users.noreply.github.com>
This commit is contained in:
@@ -29,9 +29,9 @@ const Structures = require('../util/Structures');
|
||||
*/
|
||||
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));
|
||||
|
||||
// Obtain shard details from environment or if present, worker threads
|
||||
@@ -457,8 +457,10 @@ class Client extends BaseClient {
|
||||
* @private
|
||||
*/
|
||||
_validateOptions(options = this.options) {
|
||||
if (typeof options.ws.intents !== 'undefined') {
|
||||
options.ws.intents = Intents.resolve(options.ws.intents);
|
||||
if (typeof options.intents === 'undefined') {
|
||||
throw new TypeError('CLIENT_MISSING_INTENTS');
|
||||
} else {
|
||||
options.intents = Intents.resolve(options.intents);
|
||||
}
|
||||
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');
|
||||
|
||||
@@ -10,9 +10,9 @@ class ChannelCreateAction extends Action {
|
||||
const channel = client.channels.add(data);
|
||||
if (!existing && channel) {
|
||||
/**
|
||||
* Emitted whenever a channel is created.
|
||||
* Emitted whenever a guild channel is created.
|
||||
* @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);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ const { Events } = require('../../util/Constants');
|
||||
class MessageCreateAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const channel = client.channels.cache.get(data.channel_id);
|
||||
const channel = this.getChannel(data);
|
||||
if (channel) {
|
||||
const existing = channel.messages.cache.get(data.id);
|
||||
if (existing) return { message: existing };
|
||||
|
||||
@@ -22,7 +22,6 @@ class PresenceUpdateAction extends Action {
|
||||
if (!member && data.status !== 'offline') {
|
||||
member = guild.members.add({
|
||||
user,
|
||||
roles: data.roles,
|
||||
deaf: false,
|
||||
mute: false,
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
const EventEmitter = require('events');
|
||||
const WebSocket = require('../../WebSocket');
|
||||
const { Status, Events, ShardEvents, OPCodes, WSEvents } = require('../../util/Constants');
|
||||
const Intents = require('../../util/Intents');
|
||||
|
||||
const STATUS_KEYS = Object.keys(Status);
|
||||
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
|
||||
const d = {
|
||||
...client.options.ws,
|
||||
intents: Intents.resolve(client.options.intents),
|
||||
token: client.token,
|
||||
shard: [this.id, Number(client.options.shardCount)],
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@ const { register } = require('./DJSError');
|
||||
const Messages = {
|
||||
CLIENT_INVALID_OPTION: (prop, must) => `The ${prop} option must be ${must}`,
|
||||
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_MISSING: 'Request to use token, but token was unavailable to the client.',
|
||||
|
||||
@@ -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 {boolean} [hoist] Whether or not the role should be hoisted
|
||||
* @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
|
||||
*/
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ class RoleManager extends BaseManager {
|
||||
create(options = {}) {
|
||||
let { name, color, hoist, permissions, position, mentionable, reason } = options;
|
||||
if (color) color = resolveColor(color);
|
||||
if (permissions) permissions = Permissions.resolve(permissions);
|
||||
if (permissions) permissions = Permissions.resolve(permissions).toString();
|
||||
|
||||
return this.client.api
|
||||
.guilds(this.guild.id)
|
||||
|
||||
@@ -105,7 +105,7 @@ class RequestHandler {
|
||||
this.limit = limit ? Number(limit) : Infinity;
|
||||
this.remaining = remaining ? Number(remaining) : 1;
|
||||
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
|
||||
if (request.route.includes('reactions')) {
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
const { Presence } = require('./Presence');
|
||||
const { TypeError } = require('../errors');
|
||||
const Collection = require('../util/Collection');
|
||||
const { ActivityTypes, OPCodes } = require('../util/Constants');
|
||||
|
||||
class ClientPresence extends Presence {
|
||||
@@ -14,8 +13,8 @@ class ClientPresence extends Presence {
|
||||
super(client, Object.assign(data, { status: data.status || 'online', user: { id: null } }));
|
||||
}
|
||||
|
||||
async set(presence) {
|
||||
const packet = await this._parse(presence);
|
||||
set(presence) {
|
||||
const packet = this._parse(presence);
|
||||
this.patch(packet);
|
||||
if (typeof presence.shardID === 'undefined') {
|
||||
this.client.ws.broadcast({ op: OPCodes.STATUS_UPDATE, d: packet });
|
||||
@@ -29,58 +28,33 @@ class ClientPresence extends Presence {
|
||||
return this;
|
||||
}
|
||||
|
||||
async _parse({ status, since, afk, activity }) {
|
||||
const applicationID = activity && (activity.application ? activity.application.id || activity.application : null);
|
||||
let assets = new Collection();
|
||||
if (activity) {
|
||||
if (typeof activity.name !== 'string') throw new TypeError('INVALID_TYPE', 'name', 'string');
|
||||
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
|
||||
_parse({ status, since, afk, activities }) {
|
||||
const data = {
|
||||
activities: [],
|
||||
afk: typeof afk === 'boolean' ? afk : false,
|
||||
since: typeof since === 'number' && !Number.isNaN(since) ? since : null,
|
||||
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) {
|
||||
packet.game = this.activities[0] || null;
|
||||
data.activities.push({
|
||||
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) {
|
||||
packet.game.type =
|
||||
typeof packet.game.type === 'number' ? packet.game.type : ActivityTypes.indexOf(packet.game.type);
|
||||
}
|
||||
|
||||
return packet;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,16 +46,18 @@ class ClientUser extends Structures.get('User') {
|
||||
return this.client.presence;
|
||||
}
|
||||
|
||||
edit(data) {
|
||||
return this.client.api
|
||||
.users('@me')
|
||||
.patch({ data })
|
||||
.then(newData => {
|
||||
this.client.token = newData.token;
|
||||
const { updated } = this.client.actions.UserUpdate.handle(newData);
|
||||
if (updated) return updated;
|
||||
return this;
|
||||
});
|
||||
/**
|
||||
* Edits the logged in client.
|
||||
* @param {Object} data The new data
|
||||
* @param {string} [data.username] The new username
|
||||
* @param {BufferResolvable|Base64Resolvable} [data.avatar] The new avatar
|
||||
*/
|
||||
async edit(data) {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,7 +105,7 @@ class ClientUser extends Structures.get('User') {
|
||||
/**
|
||||
* Sets the full presence of the client user.
|
||||
* @param {PresenceData} data Data for the presence
|
||||
* @returns {Promise<Presence>}
|
||||
* @returns {Presence}
|
||||
* @example
|
||||
* // Set the client user's presence
|
||||
* 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.
|
||||
* @param {PresenceStatusData} status Status to change to
|
||||
* @param {?number|number[]} [shardID] Shard ID(s) to have the activity set on
|
||||
* @returns {Promise<Presence>}
|
||||
* @returns {Presence}
|
||||
* @example
|
||||
* // Set the client user's status
|
||||
* client.user.setStatus('idle')
|
||||
@@ -144,14 +146,14 @@ class ClientUser extends Structures.get('User') {
|
||||
* @type {Object}
|
||||
* @property {string} [url] Twitch / YouTube stream URL
|
||||
* @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.
|
||||
* @param {string|ActivityOptions} [name] Activity being played, or options for setting the activity
|
||||
* @param {ActivityOptions} [options] Options for setting the activity
|
||||
* @returns {Promise<Presence>}
|
||||
* @returns {Presence}
|
||||
* @example
|
||||
* // Set the client user's activity
|
||||
* client.user.setActivity('discord.js', { type: 'WATCHING' })
|
||||
@@ -159,19 +161,20 @@ class ClientUser extends Structures.get('User') {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
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 });
|
||||
return this.setPresence({ activity, shardID: activity.shardID });
|
||||
return this.setPresence({ activities: [activity], shardID: activity.shardID });
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets/removes the AFK flag for the client user.
|
||||
* @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) {
|
||||
return this.setPresence({ afk });
|
||||
setAFK(afk, shardID) {
|
||||
return this.setPresence({ afk, shardID });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -210,13 +210,6 @@ class Guild extends Base {
|
||||
*/
|
||||
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:
|
||||
* * 0: NONE
|
||||
@@ -256,15 +249,6 @@ class Guild extends Base {
|
||||
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
|
||||
* @type {VerificationLevel}
|
||||
@@ -585,16 +569,6 @@ class Guild extends Base {
|
||||
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
|
||||
* @type {?TextChannel}
|
||||
@@ -688,8 +662,6 @@ class Guild extends Base {
|
||||
/**
|
||||
* Fetches a collection of integrations to this guild.
|
||||
* 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>>}
|
||||
* @example
|
||||
* // Fetch integrations
|
||||
@@ -697,20 +669,12 @@ class Guild extends Base {
|
||||
* .then(integrations => console.log(`Fetched ${integrations.size} integrations`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
fetchIntegrations({ includeApplications = false } = {}) {
|
||||
return this.client.api
|
||||
.guilds(this.id)
|
||||
.integrations.get({
|
||||
query: {
|
||||
include_applications: includeApplications,
|
||||
},
|
||||
})
|
||||
.then(data =>
|
||||
data.reduce(
|
||||
(collection, integration) => collection.set(integration.id, new Integration(this.client, integration, this)),
|
||||
new Collection(),
|
||||
),
|
||||
);
|
||||
async fetchIntegrations() {
|
||||
const data = await this.client.api.guilds(this.id).integrations.get();
|
||||
return 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @returns {Promise<GuildWidget>}
|
||||
@@ -920,8 +870,8 @@ class Guild extends Base {
|
||||
*/
|
||||
async fetchWidget() {
|
||||
const data = await this.client.api.guilds(this.id).widget.get();
|
||||
this.widgetEnabled = this.embedEnabled = data.enabled;
|
||||
this.widgetChannelID = this.embedChannelID = data.channel_id;
|
||||
this.widgetEnabled = data.enabled;
|
||||
this.widgetChannelID = data.channel_id;
|
||||
return {
|
||||
enabled: data.enabled,
|
||||
channel: data.channel_id ? this.channels.cache.get(data.channel_id) : null,
|
||||
@@ -1367,7 +1317,7 @@ class Guild extends Base {
|
||||
* @returns {Promise<Guild>}
|
||||
* @example
|
||||
* 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);
|
||||
*/
|
||||
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.
|
||||
* @param {GuildWidgetData} widget The widget for the guild
|
||||
@@ -1464,7 +1403,7 @@ class Guild extends Base {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
equals(guild) {
|
||||
let equal =
|
||||
return (
|
||||
guild &&
|
||||
guild instanceof this.constructor &&
|
||||
this.id === guild.id &&
|
||||
@@ -1478,20 +1417,10 @@ class Guild extends Base {
|
||||
this.icon === guild.icon &&
|
||||
this.ownerID === guild.ownerID &&
|
||||
this.verificationLevel === guild.verificationLevel &&
|
||||
this.embedEnabled === guild.embedEnabled &&
|
||||
(this.features === guild.features ||
|
||||
(this.features.length === guild.features.length &&
|
||||
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;
|
||||
this.features.every((feat, i) => feat === guild.features[i])))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1522,7 +1451,7 @@ class Guild extends Base {
|
||||
|
||||
/**
|
||||
* Creates a collection of this guild's roles, sorted by their position and IDs.
|
||||
* @returns {Collection<Role>}
|
||||
* @returns {Collection<Snowflake, Role>}
|
||||
* @private
|
||||
*/
|
||||
_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.
|
||||
* @param {GuildChannel} [channel] Category to get the channels of
|
||||
* @returns {Collection<GuildChannel>}
|
||||
* @returns {Collection<Snowflake, GuildChannel>}
|
||||
* @private
|
||||
*/
|
||||
_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,
|
||||
'Guild#fetchVanityCode: Use fetchVanityData() instead',
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
const Integration = require('./Integration');
|
||||
const Webhook = require('./Webhook');
|
||||
const Collection = require('../util/Collection');
|
||||
const { PartialTypes } = require('../util/Constants');
|
||||
const { OverwriteTypes, PartialTypes } = require('../util/Constants');
|
||||
const Permissions = require('../util/Permissions');
|
||||
const Snowflake = require('../util/Snowflake');
|
||||
const Util = require('../util/Util');
|
||||
@@ -384,16 +384,19 @@ class GuildAuditLogsEntry {
|
||||
case Actions.CHANNEL_OVERWRITE_CREATE:
|
||||
case Actions.CHANNEL_OVERWRITE_UPDATE:
|
||||
case Actions.CHANNEL_OVERWRITE_DELETE:
|
||||
switch (data.options.type) {
|
||||
case 'member':
|
||||
this.extra = guild.members.cache.get(data.options.id) || { id: data.options.id, type: 'member' };
|
||||
break;
|
||||
|
||||
case 'role':
|
||||
switch (Number(data.options.type)) {
|
||||
case OverwriteTypes.role:
|
||||
this.extra = guild.roles.cache.get(data.options.id) || {
|
||||
id: data.options.id,
|
||||
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;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ const Role = require('./Role');
|
||||
const { Error, TypeError } = require('../errors');
|
||||
const Collection = require('../util/Collection');
|
||||
const { ChannelTypes } = require('../util/Constants');
|
||||
const { OverwriteTypes } = require('../util/Constants');
|
||||
const Permissions = require('../util/Permissions');
|
||||
const Util = require('../util/Util');
|
||||
|
||||
@@ -161,12 +162,12 @@ class GuildChannel extends Channel {
|
||||
const overwrites = this.overwritesFor(member, true, roles);
|
||||
|
||||
return permissions
|
||||
.remove(overwrites.everyone ? overwrites.everyone.deny : 0)
|
||||
.add(overwrites.everyone ? overwrites.everyone.allow : 0)
|
||||
.remove(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.deny) : 0)
|
||||
.add(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.allow) : 0)
|
||||
.remove(overwrites.member ? overwrites.member.deny : 0)
|
||||
.add(overwrites.member ? overwrites.member.allow : 0)
|
||||
.remove(overwrites.everyone ? overwrites.everyone.deny : 0n)
|
||||
.add(overwrites.everyone ? overwrites.everyone.allow : 0n)
|
||||
.remove(overwrites.roles.length > 0n ? overwrites.roles.map(role => role.deny) : 0n)
|
||||
.add(overwrites.roles.length > 0n ? overwrites.roles.map(role => role.allow) : 0n)
|
||||
.remove(overwrites.member ? overwrites.member.deny : 0n)
|
||||
.add(overwrites.member ? overwrites.member.allow : 0n)
|
||||
.freeze();
|
||||
}
|
||||
|
||||
@@ -183,10 +184,10 @@ class GuildChannel extends Channel {
|
||||
const roleOverwrites = this.permissionOverwrites.get(role.id);
|
||||
|
||||
return role.permissions
|
||||
.remove(everyoneOverwrites ? everyoneOverwrites.deny : 0)
|
||||
.add(everyoneOverwrites ? everyoneOverwrites.allow : 0)
|
||||
.remove(roleOverwrites ? roleOverwrites.deny : 0)
|
||||
.add(roleOverwrites ? roleOverwrites.allow : 0)
|
||||
.remove(everyoneOverwrites ? everyoneOverwrites.deny : 0n)
|
||||
.add(everyoneOverwrites ? everyoneOverwrites.allow : 0n)
|
||||
.remove(roleOverwrites ? roleOverwrites.deny : 0n)
|
||||
.add(roleOverwrites ? roleOverwrites.allow : 0n)
|
||||
.freeze();
|
||||
}
|
||||
|
||||
@@ -204,13 +205,12 @@ class GuildChannel extends Channel {
|
||||
* },
|
||||
* ], 'Needed to change permissions');
|
||||
*/
|
||||
overwritePermissions(overwrites, reason) {
|
||||
async overwritePermissions(overwrites, reason) {
|
||||
if (!Array.isArray(overwrites) && !(overwrites instanceof Collection)) {
|
||||
return Promise.reject(
|
||||
new TypeError('INVALID_TYPE', 'overwrites', 'Array or Collection of Permission Overwrites', true),
|
||||
);
|
||||
throw 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)))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
updateOverwrite(userOrRole, options, reason) {
|
||||
async updateOverwrite(userOrRole, options, reason) {
|
||||
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'));
|
||||
|
||||
const existing = this.permissionOverwrites.get(userOrRole.id);
|
||||
if (existing) return existing.update(options, reason).then(() => this);
|
||||
return this.createOverwrite(userOrRole, options, reason);
|
||||
if (existing) {
|
||||
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);
|
||||
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);
|
||||
|
||||
return this.client.api
|
||||
.channels(this.id)
|
||||
.permissions[userOrRole.id].put({
|
||||
data: { id: userOrRole.id, type, allow: allow.bitfield, deny: deny.bitfield },
|
||||
.permissions(userOrRole.id)
|
||||
.put({
|
||||
data: {
|
||||
id: userOrRole.id,
|
||||
type,
|
||||
allow,
|
||||
deny,
|
||||
},
|
||||
reason,
|
||||
})
|
||||
.then(() => this);
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
const Role = require('./Role');
|
||||
const { TypeError } = require('../errors');
|
||||
const { OverwriteTypes } = require('../util/Constants');
|
||||
const Permissions = require('../util/Permissions');
|
||||
const Util = require('../util/Util');
|
||||
|
||||
/**
|
||||
* Represents a permission overwrite for a role or member in a guild channel.
|
||||
@@ -28,30 +28,23 @@ class PermissionOverwrites {
|
||||
*/
|
||||
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
|
||||
* @type {OverwriteType}
|
||||
*/
|
||||
this.type = data.type;
|
||||
this.type = OverwriteTypes[data.type];
|
||||
|
||||
/**
|
||||
* The permissions that are denied for the user or role.
|
||||
* @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.
|
||||
* @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)))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
update(options, reason) {
|
||||
async update(options, reason) {
|
||||
const { allow, deny } = this.constructor.resolveOverwriteOptions(options, this);
|
||||
|
||||
return this.channel.client.api
|
||||
await this.channel.client.api
|
||||
.channels(this.channel.id)
|
||||
.permissions[this.id].put({
|
||||
data: { id: this.id, type: this.type, allow: allow.bitfield, deny: deny.bitfield },
|
||||
.permissions(this.id)
|
||||
.put({
|
||||
data: {
|
||||
id: this.id,
|
||||
type: OverwriteTypes[this.type],
|
||||
allow,
|
||||
deny,
|
||||
},
|
||||
reason,
|
||||
})
|
||||
.then(() => this);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,12 +83,18 @@ class PermissionOverwrites {
|
||||
* @param {string} [reason] Reason for deleting this overwrite
|
||||
* @returns {Promise<PermissionOverwrites>}
|
||||
*/
|
||||
delete(reason) {
|
||||
return this.channel.client.api.channels[this.channel.id].permissions[this.id].delete({ reason }).then(() => this);
|
||||
async delete(reason) {
|
||||
await this.channel.client.api.channels(this.channel.id).permissions(this.id).delete({ reason });
|
||||
return this;
|
||||
}
|
||||
|
||||
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
|
||||
* @typedef {Object} RawOverwriteData
|
||||
* @property {Snowflake} id The id of the overwrite
|
||||
* @property {number} allow The permissions to allow
|
||||
* @property {number} deny The permissions to deny
|
||||
* @property {OverwriteType} type The type of this OverwriteData
|
||||
* @property {string} allow The permissions to allow
|
||||
* @property {string} deny The permissions to deny
|
||||
* @property {number} type The type of this OverwriteData
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -164,24 +169,29 @@ class PermissionOverwrites {
|
||||
/**
|
||||
* Resolves an overwrite into {@link RawOverwriteData}.
|
||||
* @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}
|
||||
*/
|
||||
static resolve(overwrite, guild) {
|
||||
if (overwrite instanceof this) return overwrite.toJSON();
|
||||
if (typeof overwrite.id === 'string' && ['role', 'member'].includes(overwrite.type)) {
|
||||
return { ...overwrite, allow: Permissions.resolve(overwrite.allow), deny: Permissions.resolve(overwrite.deny) };
|
||||
if (typeof overwrite.id === 'string' && overwrite.type in OverwriteTypes) {
|
||||
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);
|
||||
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 {
|
||||
id: userOrRole.id,
|
||||
type,
|
||||
allow: Permissions.resolve(overwrite.allow),
|
||||
deny: Permissions.resolve(overwrite.deny),
|
||||
allow: Permissions.resolve(overwrite.allow).toString(),
|
||||
deny: Permissions.resolve(overwrite.deny).toString(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ class Role extends Base {
|
||||
* The permissions of the role
|
||||
* @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
|
||||
@@ -301,7 +301,7 @@ class Role extends Base {
|
||||
* .catch(console.error);
|
||||
* @example
|
||||
* // Remove all permissions from a role
|
||||
* role.setPermissions(0)
|
||||
* role.setPermissions(0n)
|
||||
* .then(updated => console.log(`Updated permissions to ${updated.permissions.bitfield}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
|
||||
@@ -245,7 +245,7 @@ class User extends Base {
|
||||
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() {
|
||||
const { dmChannel } = this;
|
||||
if (!dmChannel) throw new Error('USER_NO_DMCHANNEL');
|
||||
const data = await this.client.api.channels(dmChannel.id).delete();
|
||||
return this.client.actions.ChannelDelete.handle(data).channel;
|
||||
await this.client.api.channels(dmChannel.id).delete();
|
||||
this.client.channels.remove(dmChannel.id);
|
||||
return dmChannel;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,12 +7,12 @@ const { RangeError } = require('../errors');
|
||||
*/
|
||||
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
|
||||
* @type {number}
|
||||
* @type {number|bigint}
|
||||
*/
|
||||
this.bitfield = this.constructor.resolve(bits);
|
||||
}
|
||||
@@ -23,7 +23,7 @@ class BitField {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
add(...bits) {
|
||||
let total = 0;
|
||||
let total = this.constructor.defaultBit;
|
||||
for (const bit of bits) {
|
||||
total |= this.constructor.resolve(bit);
|
||||
}
|
||||
@@ -86,7 +86,7 @@ class BitField {
|
||||
* @returns {BitField} These bits or new BitField if the instance is frozen.
|
||||
*/
|
||||
remove(...bits) {
|
||||
let total = 0;
|
||||
let total = this.constructor.defaultBit;
|
||||
for (const bit of bits) {
|
||||
total |= this.constructor.resolve(bit);
|
||||
}
|
||||
@@ -117,7 +117,7 @@ class BitField {
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return this.bitfield;
|
||||
return typeof this.bitfield === 'number' ? this.bitfield : this.bitfield.toString();
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
@@ -133,18 +133,20 @@ class BitField {
|
||||
* * A bit number (this can be a number literal or a value taken from {@link BitField.FLAGS})
|
||||
* * An instance of BitField
|
||||
* * An Array of BitFieldResolvable
|
||||
* @typedef {number|BitField|BitFieldResolvable[]} BitFieldResolvable
|
||||
* @typedef {number|bigint|BitField|BitFieldResolvable[]} BitFieldResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves bitfields to their numeric form.
|
||||
* @param {BitFieldResolvable} [bit=0] - bit(s) to resolve
|
||||
* @returns {number}
|
||||
* @param {BitFieldResolvable} [bit] - bit(s) to resolve
|
||||
* @returns {number|bigint}
|
||||
*/
|
||||
static resolve(bit = 0) {
|
||||
if (typeof bit === 'number' && bit >= 0) return bit;
|
||||
static resolve(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 (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];
|
||||
throw new RangeError('BITFIELD_INVALID', bit);
|
||||
}
|
||||
@@ -158,4 +160,10 @@ class BitField {
|
||||
*/
|
||||
BitField.FLAGS = {};
|
||||
|
||||
/**
|
||||
* @type {number|bigint}
|
||||
* @private
|
||||
*/
|
||||
BitField.defaultBit = 0;
|
||||
|
||||
module.exports = BitField;
|
||||
|
||||
@@ -30,7 +30,8 @@ const { Error, RangeError } = require('../errors');
|
||||
* @property {number} [restSweepInterval=60] How frequently to delete inactive request buckets, in seconds
|
||||
* (or 0 for never)
|
||||
* @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 {HTTPOptions} [http] HTTP options
|
||||
*/
|
||||
@@ -52,7 +53,6 @@ exports.DefaultOptions = {
|
||||
* @typedef {Object} WebsocketOptions
|
||||
* @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
|
||||
* @property {IntentsResolvable} [intents] Intents to enable for this connection
|
||||
*/
|
||||
ws: {
|
||||
large_threshold: 50,
|
||||
@@ -62,7 +62,7 @@ exports.DefaultOptions = {
|
||||
$browser: '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
|
||||
*/
|
||||
http: {
|
||||
version: 7,
|
||||
version: 8,
|
||||
api: 'https://discord.com/api',
|
||||
cdn: 'https://cdn.discordapp.com',
|
||||
invite: 'https://discord.gg',
|
||||
@@ -557,6 +557,7 @@ exports.VerificationLevels = ['NONE', 'LOW', 'MEDIUM', 'HIGH', 'VERY_HIGH'];
|
||||
* * UNKNOWN_GUILD_TEMPLATE
|
||||
* * BOT_PROHIBITED_ENDPOINT
|
||||
* * BOT_ONLY_ENDPOINT
|
||||
* * ANNOUNCEMENT_EDIT_LIMIT_EXCEEDED
|
||||
* * CHANNEL_HIT_WRITE_RATELIMIT
|
||||
* * MAXIMUM_GUILDS
|
||||
* * MAXIMUM_FRIENDS
|
||||
@@ -593,7 +594,9 @@ exports.VerificationLevels = ['NONE', 'LOW', 'MEDIUM', 'HIGH', 'VERY_HIGH'];
|
||||
* * CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL
|
||||
* * INVALID_OR_TAKEN_INVITE_CODE
|
||||
* * CANNOT_EXECUTE_ON_SYSTEM_MESSAGE
|
||||
* * CANNOT_EXECUTE_ON_CHANNEL_TYPE
|
||||
* * INVALID_OAUTH_TOKEN
|
||||
* * INVALID_RECIPIENTS
|
||||
* * BULK_DELETE_MESSAGE_TOO_OLD
|
||||
* * INVALID_FORM_BODY
|
||||
* * INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT
|
||||
@@ -623,6 +626,7 @@ exports.APIErrors = {
|
||||
UNKNOWN_GUILD_TEMPLATE: 10057,
|
||||
BOT_PROHIBITED_ENDPOINT: 20001,
|
||||
BOT_ONLY_ENDPOINT: 20002,
|
||||
ANNOUNCEMENT_EDIT_LIMIT_EXCEEDED: 20022,
|
||||
CHANNEL_HIT_WRITE_RATELIMIT: 20028,
|
||||
MAXIMUM_GUILDS: 30001,
|
||||
MAXIMUM_FRIENDS: 30002,
|
||||
@@ -659,7 +663,9 @@ exports.APIErrors = {
|
||||
CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL: 50019,
|
||||
INVALID_OR_TAKEN_INVITE_CODE: 50020,
|
||||
CANNOT_EXECUTE_ON_SYSTEM_MESSAGE: 50021,
|
||||
CANNOT_EXECUTE_ON_CHANNEL_TYPE: 50024,
|
||||
INVALID_OAUTH_TOKEN: 50025,
|
||||
INVALID_RECIPIENTS: 50033,
|
||||
BULK_DELETE_MESSAGE_TOO_OLD: 50034,
|
||||
INVALID_FORM_BODY: 50035,
|
||||
INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT: 50036,
|
||||
@@ -703,8 +709,26 @@ exports.WebhookTypes = [
|
||||
'Channel Follower',
|
||||
];
|
||||
|
||||
/**
|
||||
* An overwrite type:
|
||||
* * role
|
||||
* * member
|
||||
* @typedef {string} OverwriteType
|
||||
*/
|
||||
exports.OverwriteTypes = createEnum(['role', 'member']);
|
||||
|
||||
function keyMirror(arr) {
|
||||
let tmp = Object.create(null);
|
||||
for (const value of arr) tmp[value] = value;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,12 @@ class MessageFlags extends BitField {}
|
||||
* @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:
|
||||
* * `CROSSPOSTED`
|
||||
|
||||
@@ -10,10 +10,9 @@ const BitField = require('./BitField');
|
||||
*/
|
||||
class Permissions extends BitField {
|
||||
/**
|
||||
* @name Permissions
|
||||
* @kind constructor
|
||||
* @memberof Permissions
|
||||
* @param {PermissionResolvable} [bits=0] Bit(s) to read from
|
||||
* Bitfield of the packed bits
|
||||
* @type {bigint}
|
||||
* @name Permissions#bitfield
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -22,7 +21,7 @@ class Permissions extends BitField {
|
||||
* * A permission number
|
||||
* * An instance of Permissions
|
||||
* * 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_WEBHOOKS`
|
||||
* * `MANAGE_EMOJIS`
|
||||
* @type {Object}
|
||||
* @type {Object<string, bigint>}
|
||||
* @see {@link https://discord.com/developers/docs/topics/permissions}
|
||||
*/
|
||||
Permissions.FLAGS = {
|
||||
CREATE_INSTANT_INVITE: 1 << 0,
|
||||
KICK_MEMBERS: 1 << 1,
|
||||
BAN_MEMBERS: 1 << 2,
|
||||
ADMINISTRATOR: 1 << 3,
|
||||
MANAGE_CHANNELS: 1 << 4,
|
||||
MANAGE_GUILD: 1 << 5,
|
||||
ADD_REACTIONS: 1 << 6,
|
||||
VIEW_AUDIT_LOG: 1 << 7,
|
||||
PRIORITY_SPEAKER: 1 << 8,
|
||||
STREAM: 1 << 9,
|
||||
VIEW_CHANNEL: 1 << 10,
|
||||
SEND_MESSAGES: 1 << 11,
|
||||
SEND_TTS_MESSAGES: 1 << 12,
|
||||
MANAGE_MESSAGES: 1 << 13,
|
||||
EMBED_LINKS: 1 << 14,
|
||||
ATTACH_FILES: 1 << 15,
|
||||
READ_MESSAGE_HISTORY: 1 << 16,
|
||||
MENTION_EVERYONE: 1 << 17,
|
||||
USE_EXTERNAL_EMOJIS: 1 << 18,
|
||||
VIEW_GUILD_INSIGHTS: 1 << 19,
|
||||
CONNECT: 1 << 20,
|
||||
SPEAK: 1 << 21,
|
||||
MUTE_MEMBERS: 1 << 22,
|
||||
DEAFEN_MEMBERS: 1 << 23,
|
||||
MOVE_MEMBERS: 1 << 24,
|
||||
USE_VAD: 1 << 25,
|
||||
CHANGE_NICKNAME: 1 << 26,
|
||||
MANAGE_NICKNAMES: 1 << 27,
|
||||
MANAGE_ROLES: 1 << 28,
|
||||
MANAGE_WEBHOOKS: 1 << 29,
|
||||
MANAGE_EMOJIS: 1 << 30,
|
||||
CREATE_INSTANT_INVITE: 1n << 0n,
|
||||
KICK_MEMBERS: 1n << 1n,
|
||||
BAN_MEMBERS: 1n << 2n,
|
||||
ADMINISTRATOR: 1n << 3n,
|
||||
MANAGE_CHANNELS: 1n << 4n,
|
||||
MANAGE_GUILD: 1n << 5n,
|
||||
ADD_REACTIONS: 1n << 6n,
|
||||
VIEW_AUDIT_LOG: 1n << 7n,
|
||||
PRIORITY_SPEAKER: 1n << 8n,
|
||||
STREAM: 1n << 9n,
|
||||
VIEW_CHANNEL: 1n << 10n,
|
||||
SEND_MESSAGES: 1n << 11n,
|
||||
SEND_TTS_MESSAGES: 1n << 12n,
|
||||
MANAGE_MESSAGES: 1n << 13n,
|
||||
EMBED_LINKS: 1n << 14n,
|
||||
ATTACH_FILES: 1n << 15n,
|
||||
READ_MESSAGE_HISTORY: 1n << 16n,
|
||||
MENTION_EVERYONE: 1n << 17n,
|
||||
USE_EXTERNAL_EMOJIS: 1n << 18n,
|
||||
VIEW_GUILD_INSIGHTS: 1n << 19n,
|
||||
CONNECT: 1n << 20n,
|
||||
SPEAK: 1n << 21n,
|
||||
MUTE_MEMBERS: 1n << 22n,
|
||||
DEAFEN_MEMBERS: 1n << 23n,
|
||||
MOVE_MEMBERS: 1n << 24n,
|
||||
USE_VAD: 1n << 25n,
|
||||
CHANGE_NICKNAME: 1n << 26n,
|
||||
MANAGE_NICKNAMES: 1n << 27n,
|
||||
MANAGE_ROLES: 1n << 28n,
|
||||
MANAGE_WEBHOOKS: 1n << 29n,
|
||||
MANAGE_EMOJIS: 1n << 30n,
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @type {number}
|
||||
* @type {bigint}
|
||||
*/
|
||||
Permissions.DEFAULT = 104324673;
|
||||
Permissions.DEFAULT = BigInt(104324673);
|
||||
|
||||
Permissions.defaultBit = BigInt(0);
|
||||
|
||||
module.exports = Permissions;
|
||||
|
||||
@@ -16,6 +16,12 @@ class Speaking extends BitField {}
|
||||
* @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:
|
||||
* * `SPEAKING`
|
||||
|
||||
@@ -17,6 +17,12 @@ class SystemChannelFlags extends BitField {}
|
||||
* @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:
|
||||
* * A string (see {@link SystemChannelFlags.FLAGS})
|
||||
|
||||
@@ -14,6 +14,12 @@ class UserFlags extends BitField {}
|
||||
* @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:
|
||||
* * `DISCORD_EMPLOYEE`
|
||||
|
||||
Reference in New Issue
Block a user