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