PermissionOverwrites.js (5938B)
1 'use strict'; 2 3 const Role = require('./Role'); 4 const { TypeError } = require('../errors'); 5 const Permissions = require('../util/Permissions'); 6 const Util = require('../util/Util'); 7 8 /** 9 * Represents a permission overwrite for a role or member in a guild channel. 10 */ 11 class PermissionOverwrites { 12 constructor(guildChannel, data) { 13 /** 14 * The GuildChannel this overwrite is for 15 * @name PermissionOverwrites#channel 16 * @type {GuildChannel} 17 * @readonly 18 */ 19 Object.defineProperty(this, 'channel', { value: guildChannel }); 20 21 if (data) this._patch(data); 22 } 23 24 _patch(data) { 25 /** 26 * The ID of this overwrite, either a user ID or a role ID 27 * @type {Snowflake} 28 */ 29 this.id = data.id; 30 31 /** 32 * The type of a permission overwrite. It can be one of: 33 * * member 34 * * role 35 * @typedef {string} OverwriteType 36 */ 37 38 /** 39 * The type of this overwrite 40 * @type {OverwriteType} 41 */ 42 this.type = data.type; 43 44 /** 45 * The permissions that are denied for the user or role. 46 * @type {Readonly<Permissions>} 47 */ 48 this.deny = new Permissions(data.deny).freeze(); 49 50 /** 51 * The permissions that are allowed for the user or role. 52 * @type {Readonly<Permissions>} 53 */ 54 this.allow = new Permissions(data.allow).freeze(); 55 } 56 57 /** 58 * Updates this permissionOverwrites. 59 * @param {PermissionOverwriteOptions} options The options for the update 60 * @param {string} [reason] Reason for creating/editing this overwrite 61 * @returns {Promise<PermissionOverwrites>} 62 * @example 63 * // Update permission overwrites 64 * permissionOverwrites.update({ 65 * SEND_MESSAGES: false 66 * }) 67 * .then(channel => console.log(channel.permissionOverwrites.get(message.author.id))) 68 * .catch(console.error); 69 */ 70 update(options, reason) { 71 const { allow, deny } = this.constructor.resolveOverwriteOptions(options, this); 72 73 return this.channel.client.api 74 .channels(this.channel.id) 75 .permissions[this.id].put({ 76 data: { id: this.id, type: this.type, allow: allow.bitfield, deny: deny.bitfield }, 77 reason, 78 }) 79 .then(() => this); 80 } 81 82 /** 83 * Deletes this Permission Overwrite. 84 * @param {string} [reason] Reason for deleting this overwrite 85 * @returns {Promise<PermissionOverwrites>} 86 */ 87 delete(reason) { 88 return this.channel.client.api.channels[this.channel.id].permissions[this.id].delete({ reason }).then(() => this); 89 } 90 91 toJSON() { 92 return Util.flatten(this); 93 } 94 95 /** 96 * An object mapping permission flags to `true` (enabled), `null` (unset) or `false` (disabled). 97 * ```js 98 * { 99 * 'SEND_MESSAGES': true, 100 * 'EMBED_LINKS': null, 101 * 'ATTACH_FILES': false, 102 * } 103 * ``` 104 * @typedef {Object} PermissionOverwriteOptions 105 */ 106 107 /** 108 * @typedef {object} ResolvedOverwriteOptions 109 * @property {Permissions} allow The allowed permissions 110 * @property {Permissions} deny The denied permissions 111 */ 112 113 /** 114 * Resolves bitfield permissions overwrites from an object. 115 * @param {PermissionOverwriteOptions} options The options for the update 116 * @param {Object} initialPermissions The initial permissions 117 * @param {PermissionResolvable} initialPermissions.allow Initial allowed permissions 118 * @param {PermissionResolvable} initialPermissions.deny Initial denied permissions 119 * @returns {ResolvedOverwriteOptions} 120 */ 121 static resolveOverwriteOptions(options, { allow, deny } = {}) { 122 allow = new Permissions(allow); 123 deny = new Permissions(deny); 124 125 for (const [perm, value] of Object.entries(options)) { 126 if (value === true) { 127 allow.add(Permissions.FLAGS[perm]); 128 deny.remove(Permissions.FLAGS[perm]); 129 } else if (value === false) { 130 allow.remove(Permissions.FLAGS[perm]); 131 deny.add(Permissions.FLAGS[perm]); 132 } else if (value === null) { 133 allow.remove(Permissions.FLAGS[perm]); 134 deny.remove(Permissions.FLAGS[perm]); 135 } 136 } 137 138 return { allow, deny }; 139 } 140 141 /** 142 * The raw data for a permission overwrite 143 * @typedef {Object} RawOverwriteData 144 * @property {Snowflake} id The id of the overwrite 145 * @property {number} allow The permissions to allow 146 * @property {number} deny The permissions to deny 147 * @property {OverwriteType} type The type of this OverwriteData 148 */ 149 150 /** 151 * Data that can be resolved into {@link RawOverwriteData} 152 * @typedef {PermissionOverwrites|OverwriteData} OverwriteResolvable 153 */ 154 155 /** 156 * Data that can be used for a permission overwrite 157 * @typedef {Object} OverwriteData 158 * @property {GuildMemberResolvable|RoleResolvable} id Member or role this overwrite is for 159 * @property {PermissionResolvable} [allow] The permissions to allow 160 * @property {PermissionResolvable} [deny] The permissions to deny 161 * @property {OverwriteType} [type] The type of this OverwriteData 162 */ 163 164 /** 165 * Resolves an overwrite into {@link RawOverwriteData}. 166 * @param {OverwriteResolvable} overwrite The overwrite-like data to resolve 167 * @param {Guild} guild The guild to resolve from 168 * @returns {RawOverwriteData} 169 */ 170 static resolve(overwrite, guild) { 171 if (overwrite instanceof this) return overwrite.toJSON(); 172 if (typeof overwrite.id === 'string' && ['role', 'member'].includes(overwrite.type)) { 173 return { ...overwrite, allow: Permissions.resolve(overwrite.allow), deny: Permissions.resolve(overwrite.deny) }; 174 } 175 176 const userOrRole = guild.roles.resolve(overwrite.id) || guild.client.users.resolve(overwrite.id); 177 if (!userOrRole) throw new TypeError('INVALID_TYPE', 'parameter', 'User nor a Role', true); 178 const type = userOrRole instanceof Role ? 'role' : 'member'; 179 180 return { 181 id: userOrRole.id, 182 type, 183 allow: Permissions.resolve(overwrite.allow), 184 deny: Permissions.resolve(overwrite.deny), 185 }; 186 } 187 } 188 189 module.exports = PermissionOverwrites;