-
-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: PermissionOverwriteManager (#5318)
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
- Loading branch information
1 parent
a11a105
commit e7ad2fe
Showing
5 changed files
with
212 additions
and
146 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
'use strict'; | ||
|
||
const BaseManager = require('./BaseManager'); | ||
const { TypeError } = require('../errors'); | ||
const PermissionOverwrites = require('../structures/PermissionOverwrites'); | ||
const Role = require('../structures/Role'); | ||
const Collection = require('../util/Collection'); | ||
const { OverwriteTypes } = require('../util/Constants'); | ||
|
||
/** | ||
* Manages API methods for guild channel permission overwrites and stores their cache. | ||
* @extends {BaseManager} | ||
*/ | ||
class PermissionOverwriteManager extends BaseManager { | ||
constructor(channel, iterable) { | ||
super(channel.client, iterable, PermissionOverwrites); | ||
|
||
/** | ||
* The channel of the permission overwrite this manager belongs to | ||
* @type {GuildChannel} | ||
*/ | ||
this.channel = channel; | ||
} | ||
|
||
/** | ||
* The cache of this Manager | ||
* @type {Collection<Snowflake, PermissionOverwrites>} | ||
* @name PermissionOverwriteManager#cache | ||
*/ | ||
|
||
add(data, cache) { | ||
return super.add(data, cache, { extras: [this.channel] }); | ||
} | ||
|
||
/** | ||
* Replaces the permission overwrites in this channel. | ||
* @param {OverwriteResolvable[]|Collection<Snowflake, OverwriteResolvable>} overwrites | ||
* Permission overwrites the channel gets updated with | ||
* @param {string} [reason] Reason for updating the channel overwrites | ||
* @returns {Promise<GuildChannel>} | ||
* @example | ||
* message.channel.permissionOverwrites.set([ | ||
* { | ||
* id: message.author.id, | ||
* deny: [Permissions.FLAGS.VIEW_CHANNEL], | ||
* }, | ||
* ], 'Needed to change permissions'); | ||
*/ | ||
set(overwrites, reason) { | ||
if (!Array.isArray(overwrites) && !(overwrites instanceof Collection)) { | ||
throw new TypeError('INVALID_TYPE', 'overwrites', 'Array or Collection of Permission Overwrites', true); | ||
} | ||
return this.channel.edit({ permissionOverwrites: overwrites, reason }); | ||
} | ||
|
||
/** | ||
* Extra information about the overwrite | ||
* @typedef {Object} GuildChannelOverwriteOptions | ||
* @property {string} [reason] Reason for creating/editing this overwrite | ||
* @property {number} [type] The type of overwrite, either `0` for a role or `1` for a member. Use this to bypass | ||
* automatic resolution of type that results in an error for uncached structure | ||
*/ | ||
|
||
/** | ||
* Creates or edits permission overwrites for a user or role in this channel. | ||
* @param {RoleResolvable|UserResolvable} userOrRole The user or role to update | ||
* @param {PermissionOverwriteOptions} options The options for the update | ||
* @param {GuildChannelOverwriteOptions} [overwriteOptions] The extra information for the update | ||
* @param {PermissionOverwrites} [existing] The existing overwrites to merge with this update | ||
* @returns {Promise<GuildChannel>} | ||
* @private | ||
*/ | ||
async upsert(userOrRole, options, overwriteOptions = {}, existing) { | ||
let userOrRoleID = this.channel.guild.roles.resolveID(userOrRole) ?? this.client.users.resolveID(userOrRole); | ||
let { type, reason } = overwriteOptions; | ||
if (typeof type !== 'number') { | ||
userOrRole = this.channel.guild.roles.resolve(userOrRole) ?? this.client.users.resolve(userOrRole); | ||
if (!userOrRole) return Promise.reject(new TypeError('INVALID_TYPE', 'parameter', 'User nor a Role')); | ||
type = userOrRole instanceof Role ? OverwriteTypes.role : OverwriteTypes.member; | ||
} | ||
|
||
const { allow, deny } = PermissionOverwrites.resolveOverwriteOptions(options, existing); | ||
|
||
await this.client.api | ||
.channels(this.channel.id) | ||
.permissions(userOrRoleID) | ||
.put({ | ||
data: { id: userOrRoleID, type, allow, deny }, | ||
reason, | ||
}); | ||
return this.channel; | ||
} | ||
|
||
/** | ||
* Creates permission overwrites for a user or role in this channel, or replaces them if already present. | ||
* @param {RoleResolvable|UserResolvable} userOrRole The user or role to update | ||
* @param {PermissionOverwriteOptions} options The options for the update | ||
* @param {GuildChannelOverwriteOptions} [overwriteOptions] The extra information for the update | ||
* @returns {Promise<GuildChannel>} | ||
* @example | ||
* // Create or Replace permission overwrites for a message author | ||
* message.channel.permissionOverwrites.create(message.author, { | ||
* SEND_MESSAGES: false | ||
* }) | ||
* .then(channel => console.log(channel.permissionOverwrites.cache.get(message.author.id))) | ||
* .catch(console.error); | ||
*/ | ||
create(userOrRole, options, overwriteOptions) { | ||
return this.upsert(userOrRole, options, overwriteOptions); | ||
} | ||
|
||
/** | ||
* Edits permission overwrites for a user or role in this channel, or creates an entry if not already present. | ||
* @param {RoleResolvable|UserResolvable} userOrRole The user or role to update | ||
* @param {PermissionOverwriteOptions} options The options for the update | ||
* @param {GuildChannelOverwriteOptions} [overwriteOptions] The extra information for the update | ||
* @returns {Promise<GuildChannel>} | ||
* @example | ||
* // Edit or Create permission overwrites for a message author | ||
* message.channel.permissionOverwrites.edit(message.author, { | ||
* SEND_MESSAGES: false | ||
* }) | ||
* .then(channel => console.log(channel.permissionOverwrites.cache.get(message.author.id))) | ||
* .catch(console.error); | ||
*/ | ||
edit(userOrRole, options, overwriteOptions) { | ||
userOrRole = this.channel.guild.roles.resolveID(userOrRole) ?? this.client.users.resolveID(userOrRole); | ||
const existing = this.cache.get(userOrRole); | ||
return this.upsert(userOrRole, options, overwriteOptions, existing); | ||
} | ||
|
||
/** | ||
* Deletes permission overwrites for a user or role in this channel. | ||
* @param {UserResolvable|RoleResolvable} userOrRole The user or role to delete | ||
* @param {string} [reason] The reason for deleting the overwrite | ||
* @returns {GuildChannel} | ||
*/ | ||
async delete(userOrRole, reason) { | ||
userOrRole = this.channel.guild.roles.resolveID(userOrRole) ?? this.client.users.resolveID(userOrRole); | ||
if (!userOrRole) throw new TypeError('INVALID_TYPE', 'parameter', 'User nor a Role'); | ||
|
||
await this.client.api.channels(this.channel.id).permissions(userOrRole.id).delete({ reason }); | ||
return this.channel; | ||
} | ||
} | ||
|
||
module.exports = PermissionOverwriteManager; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.