buddy

node MVC discord bot
Log | Files | Refs | README

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;