refactor(BitField): base class for Permissions, ActivityFlags, Speaking (#2765)

* abstract BitField from Permissions

* reduce useless code, improve docs

* add a ReadOnly identifier to the return type of Bitfield#freeze()

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#partial-readonly-record-and-pick

* fix the RangeError

* update docs, convert Speaking and ActivityFlags to bitfields

* fix some docs

* Fix Speaking BitField oops

* docs for oops

* more incorrect docs

* Fix incorrectly named property

* add new classes to index

* fix missing @extends docs

* default bitfield resolve to 0, and cleanup defaulting everywhere

Also removes GuildMember#missiongPermissions() alias that had incorrect behavior

* Breaking: Rename Overwrite allowed and denied to allow and deny

To be consistent with the api's naming

* fix setSpeaking usage to bitfields instead of booleans

* fix speaking bug in playChunk

* docs: Updated typings

* fix: BitFieldResolvable should use RecursiveArray

* bugfix/requested change

* typings: Cleanup (#2)

* typings: Fix BitField#{toArray,@@iterator} output type

* typings: correct PermissionOverwrites property names and nitpicks
This commit is contained in:
bdistin
2018-08-21 04:56:41 -05:00
committed by SpaceEEC
parent 6be8172539
commit c62f01f0e4
18 changed files with 339 additions and 242 deletions

View File

@@ -76,8 +76,8 @@ class GuildChannel extends Channel {
return !this.permissionOverwrites.find((value, key) => {
const testVal = this.parent.permissionOverwrites.get(key);
return testVal === undefined ||
testVal.denied.bitfield !== value.denied.bitfield ||
testVal.allowed.bitfield !== value.allowed.bitfield;
testVal.deny.bitfield !== value.deny.bitfield ||
testVal.allow.bitfield !== value.allow.bitfield;
});
}
@@ -133,7 +133,7 @@ class GuildChannel extends Channel {
/**
* Gets the overall set of permissions for a member in this channel, taking into account channel overwrites.
* @param {GuildMember} member The member to obtain the overall permissions for
* @returns {Permissions}
* @returns {ReadOnly<Permissions>}
* @private
*/
memberPermissions(member) {
@@ -147,19 +147,19 @@ class GuildChannel extends Channel {
const overwrites = this.overwritesFor(member, true, roles);
return permissions
.remove(overwrites.everyone ? overwrites.everyone.denied : 0)
.add(overwrites.everyone ? overwrites.everyone.allowed : 0)
.remove(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.denied) : 0)
.add(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.allowed) : 0)
.remove(overwrites.member ? overwrites.member.denied : 0)
.add(overwrites.member ? overwrites.member.allowed : 0)
.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)
.freeze();
}
/**
* Gets the overall set of permissions for a role in this channel, taking into account channel overwrites.
* @param {Role} role The role to obtain the overall permissions for
* @returns {Permissions}
* @returns {ReadOnly<Permissions>}
* @private
*/
rolePermissions(role) {
@@ -169,10 +169,10 @@ class GuildChannel extends Channel {
const roleOverwrites = this.permissionOverwrites.get(role.id);
return role.permissions
.remove(everyoneOverwrites ? everyoneOverwrites.denied : 0)
.add(everyoneOverwrites ? everyoneOverwrites.allowed : 0)
.remove(roleOverwrites ? roleOverwrites.denied : 0)
.add(roleOverwrites ? roleOverwrites.allowed : 0)
.remove(everyoneOverwrites ? everyoneOverwrites.deny : 0)
.add(everyoneOverwrites ? everyoneOverwrites.allow : 0)
.remove(roleOverwrites ? roleOverwrites.deny : 0)
.add(roleOverwrites ? roleOverwrites.allow : 0)
.freeze();
}
@@ -188,7 +188,7 @@ class GuildChannel extends Channel {
* overwrites: [
* {
* id: message.author.id,
* denied: ['VIEW_CHANNEL'],
* deny: ['VIEW_CHANNEL'],
* },
* ],
* reason: 'Needed to change permissions'
@@ -227,8 +227,8 @@ class GuildChannel extends Channel {
* .catch(console.error);
*/
updateOverwrite(userOrRole, options, reason) {
const allow = new Permissions(0);
const deny = new Permissions(0);
const allow = new Permissions();
const deny = new Permissions();
let type;
const role = this.guild.roles.get(userOrRole);
@@ -245,20 +245,20 @@ class GuildChannel extends Channel {
const prevOverwrite = this.permissionOverwrites.get(userOrRole.id);
if (prevOverwrite) {
allow.add(prevOverwrite.allowed);
deny.add(prevOverwrite.denied);
allow.add(prevOverwrite.allow);
deny.add(prevOverwrite.deny);
}
for (const perm in options) {
if (options[perm] === true) {
allow.add(Permissions.FLAGS[perm] || 0);
deny.remove(Permissions.FLAGS[perm] || 0);
allow.add(Permissions.FLAGS[perm]);
deny.remove(Permissions.FLAGS[perm]);
} else if (options[perm] === false) {
allow.remove(Permissions.FLAGS[perm] || 0);
deny.add(Permissions.FLAGS[perm] || 0);
allow.remove(Permissions.FLAGS[perm]);
deny.add(Permissions.FLAGS[perm]);
} else if (options[perm] === null) {
allow.remove(Permissions.FLAGS[perm] || 0);
deny.remove(Permissions.FLAGS[perm] || 0);
allow.remove(Permissions.FLAGS[perm]);
deny.remove(Permissions.FLAGS[perm]);
}
}
@@ -274,8 +274,8 @@ class GuildChannel extends Channel {
lockPermissions() {
if (!this.parent) return Promise.reject(new Error('GUILD_CHANNEL_ORPHAN'));
const permissionOverwrites = this.parent.permissionOverwrites.map(overwrite => ({
deny: overwrite.denied.bitfield,
allow: overwrite.allowed.bitfield,
deny: overwrite.deny.bitfield,
allow: overwrite.allow.bitfield,
id: overwrite.id,
type: overwrite.type,
}));

View File

@@ -168,7 +168,7 @@ class GuildMember extends Base {
/**
* The overall set of permissions for this member, taking only roles into account
* @type {Permissions}
* @type {ReadOnly<Permissions>}
* @readonly
*/
get permissions() {
@@ -209,7 +209,7 @@ class GuildMember extends Base {
* Returns `channel.permissionsFor(guildMember)`. Returns permissions for a member in a guild channel,
* taking into account roles and permission overwrites.
* @param {ChannelResolvable} channel The guild channel to use as context
* @returns {?Permissions}
* @returns {ReadOnly<Permissions>}
*/
permissionsIn(channel) {
channel = this.guild.channels.resolve(channel);
@@ -230,16 +230,6 @@ class GuildMember extends Base {
return this.roles.some(r => r.permissions.has(permission, checkAdmin));
}
/**
* Checks whether the roles of this member allows them to perform specific actions, and lists any missing permissions.
* @param {PermissionResolvable} permissions The permissions to check for
* @param {boolean} [explicit=false] Whether to require the member to explicitly have the exact permissions
* @returns {PermissionResolvable[]}
*/
missingPermissions(permissions, explicit = false) {
return this.permissions.missing(permissions, explicit);
}
/**
* The data for editing a guild member.
* @typedef {Object} GuildMemberEditData

View File

@@ -39,15 +39,15 @@ class PermissionOverwrites {
/**
* The permissions that are denied for the user or role.
* @type {Permissions}
* @type {ReadOnly<Permissions>}
*/
this.denied = new Permissions(data.deny).freeze();
this.deny = new Permissions(data.deny).freeze();
/**
* The permissions that are allowed for the user or role.
* @type {Permissions}
* @type {ReadOnly<Permissions>}
*/
this.allowed = new Permissions(data.allow).freeze();
this.allow = new Permissions(data.allow).freeze();
}
/**

View File

@@ -1,5 +1,6 @@
const Util = require('../util/Util');
const { ActivityTypes, ActivityFlags } = require('../util/Constants');
const ActivityFlags = require('../util/ActivityFlags');
const { ActivityTypes } = require('../util/Constants');
/**
* Activity sent in a message.
@@ -150,15 +151,12 @@ class Activity {
this.assets = data.assets ? new RichPresenceAssets(this, data.assets) : null;
this.syncID = data.sync_id;
this._flags = data.flags;
}
get flags() {
const flags = [];
for (const [name, flag] of Object.entries(ActivityFlags)) {
if ((this._flags & flag) === flag) flags.push(name);
}
return flags;
/**
* Flags that describe the activity
* @type {ReadoOnly<ActivityFlags>}
*/
this.flags = new ActivityFlags(data.flags).freeze();
}
/**

View File

@@ -54,7 +54,7 @@ class Role extends Base {
/**
* The permissions of the role
* @type {Permissions}
* @type {ReadOnly<Permissions>}
*/
this.permissions = new Permissions(data.permissions).freeze();
@@ -203,7 +203,7 @@ class Role extends Base {
* Returns `channel.permissionsFor(role)`. Returns permissions for a role in a guild channel,
* taking into account permission overwrites.
* @param {ChannelResolvable} channel The guild channel to use as context
* @returns {?Permissions}
* @returns {ReadOnly<Permissions>}
*/
permissionsIn(channel) {
channel = this.guild.channels.resolve(channel);

View File

@@ -14,8 +14,8 @@ module.exports = function resolvePermissions(overwrites) {
}
return {
allow: Permissions.resolve(overwrite.allowed || 0),
deny: Permissions.resolve(overwrite.denied || 0),
allow: Permissions.resolve(overwrite.allow),
deny: Permissions.resolve(overwrite.deny),
type: overwrite.type,
id: overwrite.id,
};