discord.js 15.0.0-dev.1740485111-bb6767113 → 15.0.0-dev.1740615141-b6fda781c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/src/managers/ApplicationEmojiManager.js +3 -3
- package/src/managers/GuildChannelManager.js +22 -19
- package/src/managers/GuildEmojiManager.js +13 -12
- package/src/managers/GuildEmojiRoleManager.js +9 -9
- package/src/managers/GuildMemberManager.js +4 -3
- package/src/managers/GuildMemberRoleManager.js +8 -8
- package/src/managers/GuildStickerManager.js +10 -11
- package/src/managers/MessageManager.js +17 -17
- package/src/managers/PermissionOverwriteManager.js +9 -8
- package/src/managers/RoleManager.js +15 -12
- package/src/sharding/ShardClientUtil.js +3 -3
- package/src/sharding/ShardingManager.js +14 -11
- package/src/structures/GuildChannel.js +5 -5
- package/src/structures/GuildMember.js +3 -3
- package/src/structures/PermissionOverwrites.js +3 -3
- package/src/structures/Role.js +3 -3
- package/src/structures/Webhook.js +3 -2
- package/src/util/BitField.js +2 -2
- package/src/util/Channels.js +41 -43
- package/src/util/Util.js +8 -8
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "discord.js",
|
|
4
|
-
"version": "15.0.0-dev.
|
|
4
|
+
"version": "15.0.0-dev.1740615141-b6fda781c",
|
|
5
5
|
"description": "A powerful library for interacting with the Discord API",
|
|
6
6
|
"main": "./src/index.js",
|
|
7
7
|
"types": "./typings/index.d.ts",
|
|
@@ -62,9 +62,9 @@
|
|
|
62
62
|
"undici": "6.21.1",
|
|
63
63
|
"@discordjs/formatters": "^0.5.0",
|
|
64
64
|
"@discordjs/collection": "^2.1.1",
|
|
65
|
-
"@discordjs/rest": "^2.4.0",
|
|
66
65
|
"@discordjs/util": "^1.1.1",
|
|
67
|
-
"@discordjs/ws": "^2.0.0"
|
|
66
|
+
"@discordjs/ws": "^2.0.0",
|
|
67
|
+
"@discordjs/rest": "^2.4.0"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
70
|
"@favware/cliff-jumper": "^4.1.0",
|
|
@@ -49,10 +49,10 @@ class ApplicationEmojiManager extends CachedManager {
|
|
|
49
49
|
* .catch(console.error);
|
|
50
50
|
*/
|
|
51
51
|
async create({ attachment, name }) {
|
|
52
|
-
|
|
53
|
-
if (!
|
|
52
|
+
const image = await resolveImage(attachment);
|
|
53
|
+
if (!image) throw new DiscordjsTypeError(ErrorCodes.ReqResourceType);
|
|
54
54
|
|
|
55
|
-
const body = { image
|
|
55
|
+
const body = { image, name };
|
|
56
56
|
|
|
57
57
|
const emoji = await this.client.rest.post(Routes.applicationEmojis(this.application.id), { body });
|
|
58
58
|
return this._add(emoji);
|
|
@@ -53,7 +53,7 @@ class GuildChannelManager extends CachedManager {
|
|
|
53
53
|
get channelCountWithoutThreads() {
|
|
54
54
|
return this.cache.reduce((acc, channel) => {
|
|
55
55
|
if (ThreadChannelTypes.includes(channel.type)) return acc;
|
|
56
|
-
return
|
|
56
|
+
return acc + 1;
|
|
57
57
|
}, 0);
|
|
58
58
|
}
|
|
59
59
|
|
|
@@ -184,9 +184,6 @@ class GuildChannelManager extends CachedManager {
|
|
|
184
184
|
defaultForumLayout,
|
|
185
185
|
reason,
|
|
186
186
|
}) {
|
|
187
|
-
parent &&= this.client.channels.resolveId(parent);
|
|
188
|
-
permissionOverwrites &&= permissionOverwrites.map(overwrite => PermissionOverwrites.resolve(overwrite, this.guild));
|
|
189
|
-
|
|
190
187
|
const data = await this.client.rest.post(Routes.guildChannels(this.guild.id), {
|
|
191
188
|
body: {
|
|
192
189
|
name,
|
|
@@ -195,9 +192,11 @@ class GuildChannelManager extends CachedManager {
|
|
|
195
192
|
nsfw,
|
|
196
193
|
bitrate,
|
|
197
194
|
user_limit: userLimit,
|
|
198
|
-
parent_id: parent,
|
|
195
|
+
parent_id: parent && this.client.channels.resolveId(parent),
|
|
199
196
|
position,
|
|
200
|
-
permission_overwrites: permissionOverwrites
|
|
197
|
+
permission_overwrites: permissionOverwrites?.map(overwrite =>
|
|
198
|
+
PermissionOverwrites.resolve(overwrite, this.guild),
|
|
199
|
+
),
|
|
201
200
|
rate_limit_per_user: rateLimitPerUser,
|
|
202
201
|
rtc_region: rtcRegion,
|
|
203
202
|
video_quality_mode: videoQualityMode,
|
|
@@ -235,18 +234,19 @@ class GuildChannelManager extends CachedManager {
|
|
|
235
234
|
* .catch(console.error)
|
|
236
235
|
*/
|
|
237
236
|
async createWebhook({ channel, name, avatar, reason }) {
|
|
238
|
-
const
|
|
239
|
-
if (!
|
|
237
|
+
const channelId = this.resolveId(channel);
|
|
238
|
+
if (!channelId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
|
|
240
239
|
|
|
241
|
-
const
|
|
240
|
+
const resolvedAvatar = await resolveImage(avatar);
|
|
242
241
|
|
|
243
|
-
const data = await this.client.rest.post(Routes.channelWebhooks(
|
|
242
|
+
const data = await this.client.rest.post(Routes.channelWebhooks(channelId), {
|
|
244
243
|
body: {
|
|
245
244
|
name,
|
|
246
|
-
avatar:
|
|
245
|
+
avatar: resolvedAvatar,
|
|
247
246
|
},
|
|
248
247
|
reason,
|
|
249
248
|
});
|
|
249
|
+
|
|
250
250
|
return new Webhook(this.client, data);
|
|
251
251
|
}
|
|
252
252
|
|
|
@@ -361,13 +361,14 @@ class GuildChannelManager extends CachedManager {
|
|
|
361
361
|
* .catch(console.error);
|
|
362
362
|
*/
|
|
363
363
|
async setPosition(channel, position, { relative, reason } = {}) {
|
|
364
|
-
|
|
365
|
-
if (!
|
|
364
|
+
const resolvedChannel = this.resolve(channel);
|
|
365
|
+
if (!resolvedChannel) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
|
|
366
|
+
|
|
366
367
|
const updatedChannels = await setPosition(
|
|
367
|
-
|
|
368
|
+
resolvedChannel,
|
|
368
369
|
position,
|
|
369
370
|
relative,
|
|
370
|
-
this.guild._sortedChannels(
|
|
371
|
+
this.guild._sortedChannels(resolvedChannel),
|
|
371
372
|
this.client,
|
|
372
373
|
Routes.guildChannels(this.guild.id),
|
|
373
374
|
reason,
|
|
@@ -377,7 +378,8 @@ class GuildChannelManager extends CachedManager {
|
|
|
377
378
|
guild_id: this.guild.id,
|
|
378
379
|
channels: updatedChannels,
|
|
379
380
|
});
|
|
380
|
-
|
|
381
|
+
|
|
382
|
+
return resolvedChannel;
|
|
381
383
|
}
|
|
382
384
|
|
|
383
385
|
/**
|
|
@@ -459,17 +461,18 @@ class GuildChannelManager extends CachedManager {
|
|
|
459
461
|
* .catch(console.error);
|
|
460
462
|
*/
|
|
461
463
|
async setPositions(channelPositions) {
|
|
462
|
-
|
|
464
|
+
const resolvedChannelPositions = channelPositions.map(channelPosition => ({
|
|
463
465
|
id: this.client.channels.resolveId(channelPosition.channel),
|
|
464
466
|
position: channelPosition.position,
|
|
465
467
|
lock_permissions: channelPosition.lockPermissions,
|
|
466
468
|
parent_id: channelPosition.parent !== undefined ? this.resolveId(channelPosition.parent) : undefined,
|
|
467
469
|
}));
|
|
468
470
|
|
|
469
|
-
await this.client.rest.patch(Routes.guildChannels(this.guild.id), { body:
|
|
471
|
+
await this.client.rest.patch(Routes.guildChannels(this.guild.id), { body: resolvedChannelPositions });
|
|
472
|
+
|
|
470
473
|
return this.client.actions.GuildChannelsPositionUpdate.handle({
|
|
471
474
|
guild_id: this.guild.id,
|
|
472
|
-
channels:
|
|
475
|
+
channels: resolvedChannelPositions,
|
|
473
476
|
}).guild;
|
|
474
477
|
}
|
|
475
478
|
|
|
@@ -85,11 +85,12 @@ class GuildEmojiManager extends CachedManager {
|
|
|
85
85
|
if (emoji instanceof ApplicationEmoji) return emoji.identifier;
|
|
86
86
|
if (typeof emoji === 'string') {
|
|
87
87
|
const res = parseEmoji(emoji);
|
|
88
|
+
let identifier = emoji;
|
|
88
89
|
if (res?.name.length) {
|
|
89
|
-
|
|
90
|
+
identifier = `${res.animated ? 'a:' : ''}${res.name}${res.id ? `:${res.id}` : ''}`;
|
|
90
91
|
}
|
|
91
|
-
if (!
|
|
92
|
-
return
|
|
92
|
+
if (!identifier.includes('%')) return encodeURIComponent(identifier);
|
|
93
|
+
return identifier;
|
|
93
94
|
}
|
|
94
95
|
return null;
|
|
95
96
|
}
|
|
@@ -119,10 +120,10 @@ class GuildEmojiManager extends CachedManager {
|
|
|
119
120
|
* .catch(console.error);
|
|
120
121
|
*/
|
|
121
122
|
async create({ attachment, name, roles, reason }) {
|
|
122
|
-
|
|
123
|
-
if (!
|
|
123
|
+
const image = await resolveImage(attachment);
|
|
124
|
+
if (!image) throw new DiscordjsTypeError(ErrorCodes.ReqResourceType);
|
|
124
125
|
|
|
125
|
-
const body = { image
|
|
126
|
+
const body = { image, name };
|
|
126
127
|
if (roles) {
|
|
127
128
|
if (!Array.isArray(roles) && !(roles instanceof Collection)) {
|
|
128
129
|
throw new DiscordjsTypeError(
|
|
@@ -222,9 +223,9 @@ class GuildEmojiManager extends CachedManager {
|
|
|
222
223
|
* @returns {Promise<User>}
|
|
223
224
|
*/
|
|
224
225
|
async fetchAuthor(emoji) {
|
|
225
|
-
|
|
226
|
-
if (!
|
|
227
|
-
if (
|
|
226
|
+
const resolvedEmoji = this.resolve(emoji);
|
|
227
|
+
if (!resolvedEmoji) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true);
|
|
228
|
+
if (resolvedEmoji.managed) {
|
|
228
229
|
throw new DiscordjsError(ErrorCodes.EmojiManaged);
|
|
229
230
|
}
|
|
230
231
|
|
|
@@ -234,9 +235,9 @@ class GuildEmojiManager extends CachedManager {
|
|
|
234
235
|
throw new DiscordjsError(ErrorCodes.MissingManageGuildExpressionsPermission, this.guild);
|
|
235
236
|
}
|
|
236
237
|
|
|
237
|
-
const data = await this.client.rest.get(Routes.guildEmoji(this.guild.id,
|
|
238
|
-
|
|
239
|
-
return
|
|
238
|
+
const data = await this.client.rest.get(Routes.guildEmoji(this.guild.id, resolvedEmoji.id));
|
|
239
|
+
resolvedEmoji._patch(data);
|
|
240
|
+
return resolvedEmoji.author;
|
|
240
241
|
}
|
|
241
242
|
}
|
|
242
243
|
|
|
@@ -40,18 +40,18 @@ class GuildEmojiRoleManager extends DataManager {
|
|
|
40
40
|
* @returns {Promise<GuildEmoji>}
|
|
41
41
|
*/
|
|
42
42
|
async add(roleOrRoles) {
|
|
43
|
-
|
|
43
|
+
const roles = Array.isArray(roleOrRoles) || roleOrRoles instanceof Collection ? roleOrRoles : [roleOrRoles];
|
|
44
44
|
|
|
45
|
-
const
|
|
46
|
-
for (const role of
|
|
47
|
-
const
|
|
48
|
-
if (!
|
|
45
|
+
const resolvedRoleIds = [];
|
|
46
|
+
for (const role of roles.values()) {
|
|
47
|
+
const roleId = this.guild.roles.resolveId(role);
|
|
48
|
+
if (!roleId) {
|
|
49
49
|
throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array or Collection', 'roles', role);
|
|
50
50
|
}
|
|
51
|
-
|
|
51
|
+
resolvedRoleIds.push(roleId);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
const newRoles = [...new Set(
|
|
54
|
+
const newRoles = [...new Set(resolvedRoleIds.concat(...this.cache.keys()))];
|
|
55
55
|
return this.set(newRoles);
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -61,10 +61,10 @@ class GuildEmojiRoleManager extends DataManager {
|
|
|
61
61
|
* @returns {Promise<GuildEmoji>}
|
|
62
62
|
*/
|
|
63
63
|
async remove(roleOrRoles) {
|
|
64
|
-
|
|
64
|
+
const roles = Array.isArray(roleOrRoles) || roleOrRoles instanceof Collection ? roleOrRoles : [roleOrRoles];
|
|
65
65
|
|
|
66
66
|
const resolvedRoleIds = [];
|
|
67
|
-
for (const role of
|
|
67
|
+
for (const role of roles.values()) {
|
|
68
68
|
const roleId = this.guild.roles.resolveId(role);
|
|
69
69
|
if (!roleId) {
|
|
70
70
|
throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array or Collection', 'roles', role);
|
|
@@ -220,14 +220,15 @@ class GuildMemberManager extends CachedManager {
|
|
|
220
220
|
limit = 0,
|
|
221
221
|
withPresences: presences,
|
|
222
222
|
users,
|
|
223
|
-
query,
|
|
223
|
+
query: initialQuery,
|
|
224
224
|
time = 120e3,
|
|
225
225
|
nonce = DiscordSnowflake.generate().toString(),
|
|
226
|
-
}
|
|
226
|
+
}) {
|
|
227
227
|
if (nonce.length > 32) throw new DiscordjsRangeError(ErrorCodes.MemberFetchNonceLength);
|
|
228
228
|
|
|
229
|
+
const query = initialQuery || (!users ? '' : undefined);
|
|
230
|
+
|
|
229
231
|
return new Promise((resolve, reject) => {
|
|
230
|
-
if (!query && !users) query = '';
|
|
231
232
|
this.guild.client.ws.send(this.guild.shardId, {
|
|
232
233
|
op: GatewayOpcodes.RequestGuildMembers,
|
|
233
234
|
d: {
|
|
@@ -121,8 +121,8 @@ class GuildMemberRoleManager extends DataManager {
|
|
|
121
121
|
const newRoles = [...new Set(resolvedRoles.concat(...this.cache.keys()))];
|
|
122
122
|
return this.set(newRoles, reason);
|
|
123
123
|
} else {
|
|
124
|
-
|
|
125
|
-
if (
|
|
124
|
+
const resolvedRoleId = this.guild.roles.resolveId(roleOrRoles);
|
|
125
|
+
if (resolvedRoleId === null) {
|
|
126
126
|
throw new DiscordjsTypeError(
|
|
127
127
|
ErrorCodes.InvalidType,
|
|
128
128
|
'roles',
|
|
@@ -130,10 +130,10 @@ class GuildMemberRoleManager extends DataManager {
|
|
|
130
130
|
);
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
await this.client.rest.put(Routes.guildMemberRole(this.guild.id, this.member.id,
|
|
133
|
+
await this.client.rest.put(Routes.guildMemberRole(this.guild.id, this.member.id, resolvedRoleId), { reason });
|
|
134
134
|
|
|
135
135
|
const clone = this.member._clone();
|
|
136
|
-
clone._roles = [...this.cache.keys(),
|
|
136
|
+
clone._roles = [...this.cache.keys(), resolvedRoleId];
|
|
137
137
|
return clone;
|
|
138
138
|
}
|
|
139
139
|
}
|
|
@@ -160,8 +160,8 @@ class GuildMemberRoleManager extends DataManager {
|
|
|
160
160
|
const newRoles = this.cache.filter(role => !resolvedRoles.includes(role.id));
|
|
161
161
|
return this.set(newRoles, reason);
|
|
162
162
|
} else {
|
|
163
|
-
|
|
164
|
-
if (
|
|
163
|
+
const resolvedRoleId = this.guild.roles.resolveId(roleOrRoles);
|
|
164
|
+
if (resolvedRoleId === null) {
|
|
165
165
|
throw new DiscordjsTypeError(
|
|
166
166
|
ErrorCodes.InvalidType,
|
|
167
167
|
'roles',
|
|
@@ -169,10 +169,10 @@ class GuildMemberRoleManager extends DataManager {
|
|
|
169
169
|
);
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
await this.client.rest.delete(Routes.guildMemberRole(this.guild.id, this.member.id,
|
|
172
|
+
await this.client.rest.delete(Routes.guildMemberRole(this.guild.id, this.member.id, resolvedRoleId), { reason });
|
|
173
173
|
|
|
174
174
|
const clone = this.member._clone();
|
|
175
|
-
const newRoles = this.cache.filter(role => role.id !==
|
|
175
|
+
const newRoles = this.cache.filter(role => role.id !== resolvedRoleId);
|
|
176
176
|
clone._roles = [...newRoles.keys()];
|
|
177
177
|
return clone;
|
|
178
178
|
}
|
|
@@ -59,15 +59,14 @@ class GuildStickerManager extends CachedManager {
|
|
|
59
59
|
*/
|
|
60
60
|
async create({ file, name, tags, description, reason } = {}) {
|
|
61
61
|
const resolvedFile = await MessagePayload.resolveFile(file);
|
|
62
|
-
|
|
63
|
-
file = { ...resolvedFile, key: 'file' };
|
|
62
|
+
resolvedFile.key = 'file';
|
|
64
63
|
|
|
65
64
|
const body = { name, tags, description: description ?? '' };
|
|
66
65
|
|
|
67
66
|
const sticker = await this.client.rest.post(Routes.guildStickers(this.guild.id), {
|
|
68
67
|
appendToFormData: true,
|
|
69
68
|
body,
|
|
70
|
-
files: [
|
|
69
|
+
files: [resolvedFile],
|
|
71
70
|
reason,
|
|
72
71
|
});
|
|
73
72
|
return this.client.actions.GuildStickerCreate.handle(this.guild, sticker).sticker;
|
|
@@ -129,10 +128,10 @@ class GuildStickerManager extends CachedManager {
|
|
|
129
128
|
* @returns {Promise<void>}
|
|
130
129
|
*/
|
|
131
130
|
async delete(sticker, reason) {
|
|
132
|
-
|
|
133
|
-
if (!
|
|
131
|
+
const resolvedStickerId = this.resolveId(sticker);
|
|
132
|
+
if (!resolvedStickerId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'sticker', 'StickerResolvable');
|
|
134
133
|
|
|
135
|
-
await this.client.rest.delete(Routes.guildSticker(this.guild.id,
|
|
134
|
+
await this.client.rest.delete(Routes.guildSticker(this.guild.id, resolvedStickerId), { reason });
|
|
136
135
|
}
|
|
137
136
|
|
|
138
137
|
/**
|
|
@@ -171,11 +170,11 @@ class GuildStickerManager extends CachedManager {
|
|
|
171
170
|
* @returns {Promise<?User>}
|
|
172
171
|
*/
|
|
173
172
|
async fetchUser(sticker) {
|
|
174
|
-
|
|
175
|
-
if (!
|
|
176
|
-
const data = await this.client.rest.get(Routes.guildSticker(this.guild.id,
|
|
177
|
-
|
|
178
|
-
return
|
|
173
|
+
const resolvedSticker = this.resolve(sticker);
|
|
174
|
+
if (!resolvedSticker) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'sticker', 'StickerResolvable');
|
|
175
|
+
const data = await this.client.rest.get(Routes.guildSticker(this.guild.id, resolvedSticker.id));
|
|
176
|
+
resolvedSticker._patch(data);
|
|
177
|
+
return resolvedSticker.user;
|
|
179
178
|
}
|
|
180
179
|
}
|
|
181
180
|
|
|
@@ -203,10 +203,10 @@ class MessageManager extends CachedManager {
|
|
|
203
203
|
* @returns {Promise<void>}
|
|
204
204
|
*/
|
|
205
205
|
async pin(message, reason) {
|
|
206
|
-
|
|
207
|
-
if (!
|
|
206
|
+
const messageId = this.resolveId(message);
|
|
207
|
+
if (!messageId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
|
|
208
208
|
|
|
209
|
-
await this.client.rest.put(Routes.channelPin(this.channel.id,
|
|
209
|
+
await this.client.rest.put(Routes.channelPin(this.channel.id, messageId), { reason });
|
|
210
210
|
}
|
|
211
211
|
|
|
212
212
|
/**
|
|
@@ -216,10 +216,10 @@ class MessageManager extends CachedManager {
|
|
|
216
216
|
* @returns {Promise<void>}
|
|
217
217
|
*/
|
|
218
218
|
async unpin(message, reason) {
|
|
219
|
-
|
|
220
|
-
if (!
|
|
219
|
+
const messageId = this.resolveId(message);
|
|
220
|
+
if (!messageId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
|
|
221
221
|
|
|
222
|
-
await this.client.rest.delete(Routes.channelPin(this.channel.id,
|
|
222
|
+
await this.client.rest.delete(Routes.channelPin(this.channel.id, messageId), { reason });
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
/**
|
|
@@ -229,17 +229,17 @@ class MessageManager extends CachedManager {
|
|
|
229
229
|
* @returns {Promise<void>}
|
|
230
230
|
*/
|
|
231
231
|
async react(message, emoji) {
|
|
232
|
-
|
|
233
|
-
if (!
|
|
232
|
+
const messageId = this.resolveId(message);
|
|
233
|
+
if (!messageId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
|
|
234
234
|
|
|
235
|
-
|
|
236
|
-
if (!
|
|
235
|
+
const resolvedEmoji = resolvePartialEmoji(emoji);
|
|
236
|
+
if (!resolvedEmoji) throw new DiscordjsTypeError(ErrorCodes.EmojiType, 'emoji', 'EmojiIdentifierResolvable');
|
|
237
237
|
|
|
238
|
-
const emojiId =
|
|
239
|
-
? `${
|
|
240
|
-
: encodeURIComponent(
|
|
238
|
+
const emojiId = resolvedEmoji.id
|
|
239
|
+
? `${resolvedEmoji.animated ? 'a:' : ''}${resolvedEmoji.name}:${resolvedEmoji.id}`
|
|
240
|
+
: encodeURIComponent(resolvedEmoji.name);
|
|
241
241
|
|
|
242
|
-
await this.client.rest.put(Routes.channelMessageOwnReaction(this.channel.id,
|
|
242
|
+
await this.client.rest.put(Routes.channelMessageOwnReaction(this.channel.id, messageId, emojiId));
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
/**
|
|
@@ -248,10 +248,10 @@ class MessageManager extends CachedManager {
|
|
|
248
248
|
* @returns {Promise<void>}
|
|
249
249
|
*/
|
|
250
250
|
async delete(message) {
|
|
251
|
-
|
|
252
|
-
if (!
|
|
251
|
+
const messageId = this.resolveId(message);
|
|
252
|
+
if (!messageId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
|
|
253
253
|
|
|
254
|
-
await this.client.rest.delete(Routes.channelMessage(this.channel.id,
|
|
254
|
+
await this.client.rest.delete(Routes.channelMessage(this.channel.id, messageId));
|
|
255
255
|
}
|
|
256
256
|
|
|
257
257
|
/**
|
|
@@ -91,19 +91,20 @@ class PermissionOverwriteManager extends CachedManager {
|
|
|
91
91
|
* @returns {Promise<GuildChannel>}
|
|
92
92
|
* @private
|
|
93
93
|
*/
|
|
94
|
-
async upsert(userOrRole, options,
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
94
|
+
async upsert(userOrRole, options, { reason, type } = {}, existing) {
|
|
95
|
+
const userOrRoleId = this.channel.guild.roles.resolveId(userOrRole) ?? this.client.users.resolveId(userOrRole);
|
|
96
|
+
|
|
97
|
+
let resolvedType = type;
|
|
98
|
+
if (typeof resolvedType !== 'number') {
|
|
99
|
+
const resolvedUserOrRole = this.channel.guild.roles.resolve(userOrRole) ?? this.client.users.resolve(userOrRole);
|
|
100
|
+
if (!resolvedUserOrRole) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'parameter', 'User nor a Role');
|
|
101
|
+
resolvedType = resolvedUserOrRole instanceof Role ? OverwriteType.Role : OverwriteType.Member;
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
const { allow, deny } = PermissionOverwrites.resolveOverwriteOptions(options, existing);
|
|
104
105
|
|
|
105
106
|
await this.client.rest.put(Routes.channelPermission(this.channel.id, userOrRoleId), {
|
|
106
|
-
body: { id: userOrRoleId, type, allow, deny },
|
|
107
|
+
body: { id: userOrRoleId, type: resolvedType, allow, deny },
|
|
107
108
|
reason,
|
|
108
109
|
});
|
|
109
110
|
return this.channel;
|
|
@@ -186,11 +186,11 @@ class RoleManager extends CachedManager {
|
|
|
186
186
|
* .catch(console.error);
|
|
187
187
|
*/
|
|
188
188
|
async edit(role, options) {
|
|
189
|
-
|
|
190
|
-
if (!
|
|
189
|
+
const resolvedRole = this.resolve(role);
|
|
190
|
+
if (!resolvedRole) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'role', 'RoleResolvable');
|
|
191
191
|
|
|
192
192
|
if (typeof options.position === 'number') {
|
|
193
|
-
await this.setPosition(
|
|
193
|
+
await this.setPosition(resolvedRole, options.position, { reason: options.reason });
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
let icon = options.icon;
|
|
@@ -210,9 +210,12 @@ class RoleManager extends CachedManager {
|
|
|
210
210
|
unicode_emoji: options.unicodeEmoji,
|
|
211
211
|
};
|
|
212
212
|
|
|
213
|
-
const d = await this.client.rest.patch(Routes.guildRole(this.guild.id,
|
|
213
|
+
const d = await this.client.rest.patch(Routes.guildRole(this.guild.id, resolvedRole.id), {
|
|
214
|
+
body,
|
|
215
|
+
reason: options.reason,
|
|
216
|
+
});
|
|
214
217
|
|
|
215
|
-
const clone =
|
|
218
|
+
const clone = resolvedRole._clone();
|
|
216
219
|
clone._patch(d);
|
|
217
220
|
return clone;
|
|
218
221
|
}
|
|
@@ -247,10 +250,10 @@ class RoleManager extends CachedManager {
|
|
|
247
250
|
* .catch(console.error);
|
|
248
251
|
*/
|
|
249
252
|
async setPosition(role, position, { relative, reason } = {}) {
|
|
250
|
-
|
|
251
|
-
if (!
|
|
253
|
+
const resolvedRole = this.resolve(role);
|
|
254
|
+
if (!resolvedRole) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'role', 'RoleResolvable');
|
|
252
255
|
const updatedRoles = await setPosition(
|
|
253
|
-
|
|
256
|
+
resolvedRole,
|
|
254
257
|
position,
|
|
255
258
|
relative,
|
|
256
259
|
this.guild._sortedRoles(),
|
|
@@ -263,7 +266,7 @@ class RoleManager extends CachedManager {
|
|
|
263
266
|
guild_id: this.guild.id,
|
|
264
267
|
roles: updatedRoles,
|
|
265
268
|
});
|
|
266
|
-
return
|
|
269
|
+
return resolvedRole;
|
|
267
270
|
}
|
|
268
271
|
|
|
269
272
|
/**
|
|
@@ -284,16 +287,16 @@ class RoleManager extends CachedManager {
|
|
|
284
287
|
*/
|
|
285
288
|
async setPositions(rolePositions) {
|
|
286
289
|
// Make sure rolePositions are prepared for API
|
|
287
|
-
|
|
290
|
+
const resolvedRolePositions = rolePositions.map(rolePosition => ({
|
|
288
291
|
id: this.resolveId(rolePosition.role),
|
|
289
292
|
position: rolePosition.position,
|
|
290
293
|
}));
|
|
291
294
|
|
|
292
295
|
// Call the API to update role positions
|
|
293
|
-
await this.client.rest.patch(Routes.guildRoles(this.guild.id), { body:
|
|
296
|
+
await this.client.rest.patch(Routes.guildRoles(this.guild.id), { body: resolvedRolePositions });
|
|
294
297
|
return this.client.actions.GuildRolesPositionUpdate.handle({
|
|
295
298
|
guild_id: this.guild.id,
|
|
296
|
-
roles:
|
|
299
|
+
roles: resolvedRolePositions,
|
|
297
300
|
}).guild;
|
|
298
301
|
}
|
|
299
302
|
|
|
@@ -134,10 +134,10 @@ class ShardClientUtil {
|
|
|
134
134
|
reject(new DiscordjsTypeError(ErrorCodes.ShardingInvalidEvalBroadcast));
|
|
135
135
|
return;
|
|
136
136
|
}
|
|
137
|
-
|
|
137
|
+
const evalScript = `(${script})(this, ${JSON.stringify(options.context)})`;
|
|
138
138
|
|
|
139
139
|
const listener = message => {
|
|
140
|
-
if (message?._sEval !==
|
|
140
|
+
if (message?._sEval !== evalScript || message._sEvalShard !== options.shard) return;
|
|
141
141
|
parent.removeListener('message', listener);
|
|
142
142
|
this.decrementMaxListeners(parent);
|
|
143
143
|
if (!message._error) resolve(message._result);
|
|
@@ -145,7 +145,7 @@ class ShardClientUtil {
|
|
|
145
145
|
};
|
|
146
146
|
this.incrementMaxListeners(parent);
|
|
147
147
|
parent.on('message', listener);
|
|
148
|
-
this.send({ _sEval:
|
|
148
|
+
this.send({ _sEval: evalScript, _sEvalShard: options.shard }).catch(err => {
|
|
149
149
|
parent.removeListener('message', listener);
|
|
150
150
|
this.decrementMaxListeners(parent);
|
|
151
151
|
reject(err);
|
|
@@ -191,28 +191,31 @@ class ShardingManager extends AsyncEventEmitter {
|
|
|
191
191
|
*/
|
|
192
192
|
async spawn({ amount = this.totalShards, delay = 5500, timeout = 30_000 } = {}) {
|
|
193
193
|
// Obtain/verify the number of shards to spawn
|
|
194
|
-
|
|
195
|
-
|
|
194
|
+
let shardAmount = amount;
|
|
195
|
+
if (shardAmount === 'auto') {
|
|
196
|
+
shardAmount = await fetchRecommendedShardCount(this.token);
|
|
196
197
|
} else {
|
|
197
|
-
if (typeof
|
|
198
|
+
if (typeof shardAmount !== 'number' || isNaN(shardAmount)) {
|
|
198
199
|
throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'Amount of shards', 'a number.');
|
|
199
200
|
}
|
|
200
|
-
if (
|
|
201
|
-
|
|
201
|
+
if (shardAmount < 1) {
|
|
202
|
+
throw new DiscordjsRangeError(ErrorCodes.ClientInvalidOption, 'Amount of shards', 'at least 1.');
|
|
203
|
+
}
|
|
204
|
+
if (!Number.isInteger(shardAmount)) {
|
|
202
205
|
throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'Amount of shards', 'an integer.');
|
|
203
206
|
}
|
|
204
207
|
}
|
|
205
208
|
|
|
206
209
|
// Make sure this many shards haven't already been spawned
|
|
207
|
-
if (this.shards.size >=
|
|
208
|
-
if (this.shardList === 'auto' || this.totalShards === 'auto' || this.totalShards !==
|
|
209
|
-
this.shardList = [...Array(
|
|
210
|
+
if (this.shards.size >= shardAmount) throw new DiscordjsError(ErrorCodes.ShardingAlreadySpawned, this.shards.size);
|
|
211
|
+
if (this.shardList === 'auto' || this.totalShards === 'auto' || this.totalShards !== shardAmount) {
|
|
212
|
+
this.shardList = [...Array(shardAmount).keys()];
|
|
210
213
|
}
|
|
211
|
-
if (this.totalShards === 'auto' || this.totalShards !==
|
|
212
|
-
this.totalShards =
|
|
214
|
+
if (this.totalShards === 'auto' || this.totalShards !== shardAmount) {
|
|
215
|
+
this.totalShards = shardAmount;
|
|
213
216
|
}
|
|
214
217
|
|
|
215
|
-
if (this.shardList.some(shardId => shardId >=
|
|
218
|
+
if (this.shardList.some(shardId => shardId >= shardAmount)) {
|
|
216
219
|
throw new DiscordjsRangeError(
|
|
217
220
|
ErrorCodes.ClientInvalidOption,
|
|
218
221
|
'Amount of shards',
|
|
@@ -180,10 +180,10 @@ class GuildChannel extends BaseChannel {
|
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
overwritesFor(member, verified = false, roles = null) {
|
|
183
|
-
|
|
184
|
-
if (!
|
|
183
|
+
const resolvedMember = verified ? member : this.guild.members.resolve(member);
|
|
184
|
+
if (!resolvedMember) return [];
|
|
185
185
|
|
|
186
|
-
roles
|
|
186
|
+
const resolvedRoles = roles ?? resolvedMember.roles.cache;
|
|
187
187
|
const roleOverwrites = [];
|
|
188
188
|
let memberOverwrites;
|
|
189
189
|
let everyoneOverwrites;
|
|
@@ -191,9 +191,9 @@ class GuildChannel extends BaseChannel {
|
|
|
191
191
|
for (const overwrite of this.permissionOverwrites.cache.values()) {
|
|
192
192
|
if (overwrite.id === this.guild.id) {
|
|
193
193
|
everyoneOverwrites = overwrite;
|
|
194
|
-
} else if (
|
|
194
|
+
} else if (resolvedRoles.has(overwrite.id)) {
|
|
195
195
|
roleOverwrites.push(overwrite);
|
|
196
|
-
} else if (overwrite.id ===
|
|
196
|
+
} else if (overwrite.id === resolvedMember.id) {
|
|
197
197
|
memberOverwrites = overwrite;
|
|
198
198
|
}
|
|
199
199
|
}
|
|
@@ -346,9 +346,9 @@ class GuildMember extends Base {
|
|
|
346
346
|
* @returns {Readonly<PermissionsBitField>}
|
|
347
347
|
*/
|
|
348
348
|
permissionsIn(channel) {
|
|
349
|
-
|
|
350
|
-
if (!
|
|
351
|
-
return
|
|
349
|
+
const resolvedChannel = this.guild.channels.resolve(channel);
|
|
350
|
+
if (!resolvedChannel) throw new DiscordjsError(ErrorCodes.GuildChannelResolve);
|
|
351
|
+
return resolvedChannel.permissionsFor(this);
|
|
352
352
|
}
|
|
353
353
|
|
|
354
354
|
/**
|
|
@@ -118,9 +118,9 @@ class PermissionOverwrites extends Base {
|
|
|
118
118
|
* @param {ResolvedOverwriteOptions} initialPermissions The initial permissions
|
|
119
119
|
* @returns {ResolvedOverwriteOptions}
|
|
120
120
|
*/
|
|
121
|
-
static resolveOverwriteOptions(options,
|
|
122
|
-
allow = new PermissionsBitField(allow);
|
|
123
|
-
deny = new PermissionsBitField(deny);
|
|
121
|
+
static resolveOverwriteOptions(options, initialPermissions = {}) {
|
|
122
|
+
const allow = new PermissionsBitField(initialPermissions.allow);
|
|
123
|
+
const deny = new PermissionsBitField(initialPermissions.deny);
|
|
124
124
|
|
|
125
125
|
for (const [perm, value] of Object.entries(options)) {
|
|
126
126
|
if (value === true) {
|
package/src/structures/Role.js
CHANGED
|
@@ -264,9 +264,9 @@ class Role extends Base {
|
|
|
264
264
|
* @returns {Readonly<PermissionsBitField>}
|
|
265
265
|
*/
|
|
266
266
|
permissionsIn(channel, checkAdmin = true) {
|
|
267
|
-
|
|
268
|
-
if (!
|
|
269
|
-
return
|
|
267
|
+
const resolvedChannel = this.guild.channels.resolve(channel);
|
|
268
|
+
if (!resolvedChannel) throw new DiscordjsError(ErrorCodes.GuildChannelResolve);
|
|
269
|
+
return resolvedChannel.rolePermissions(this, checkAdmin);
|
|
270
270
|
}
|
|
271
271
|
|
|
272
272
|
/**
|
|
@@ -275,11 +275,12 @@ class Webhook {
|
|
|
275
275
|
* @param {WebhookEditOptions} options Options for editing the webhook
|
|
276
276
|
* @returns {Promise<Webhook>}
|
|
277
277
|
*/
|
|
278
|
-
async edit({ name = this.name, avatar, channel, reason }) {
|
|
278
|
+
async edit({ name = this.name, avatar: newAvatar, channel: newChannel, reason }) {
|
|
279
|
+
let avatar = newAvatar;
|
|
279
280
|
if (avatar && !(typeof avatar === 'string' && avatar.startsWith('data:'))) {
|
|
280
281
|
avatar = await resolveImage(avatar);
|
|
281
282
|
}
|
|
282
|
-
channel
|
|
283
|
+
const channel = newChannel?.id ?? newChannel;
|
|
283
284
|
const data = await this.client.rest.patch(Routes.webhook(this.id, channel ? undefined : this.token), {
|
|
284
285
|
body: { name, avatar, channel_id: channel },
|
|
285
286
|
reason,
|
package/src/util/BitField.js
CHANGED
|
@@ -57,8 +57,8 @@ class BitField {
|
|
|
57
57
|
* @returns {boolean}
|
|
58
58
|
*/
|
|
59
59
|
has(bit) {
|
|
60
|
-
|
|
61
|
-
return (this.bitfield &
|
|
60
|
+
const resolvedBit = this.constructor.resolve(bit);
|
|
61
|
+
return (this.bitfield & resolvedBit) === resolvedBit;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
/**
|
package/src/util/Channels.js
CHANGED
|
@@ -33,56 +33,54 @@ const getMediaChannel = lazy(() => require('../structures/MediaChannel.js').Medi
|
|
|
33
33
|
*/
|
|
34
34
|
function createChannel(client, data, guild, { allowUnknownGuild } = {}) {
|
|
35
35
|
let channel;
|
|
36
|
-
|
|
36
|
+
let resolvedGuild = guild || client.guilds.cache.get(data.guild_id);
|
|
37
|
+
|
|
38
|
+
if (!data.guild_id && !resolvedGuild) {
|
|
37
39
|
if ((data.recipients && data.type !== ChannelType.GroupDM) || data.type === ChannelType.DM) {
|
|
38
40
|
channel = new (getDMChannel())(client, data);
|
|
39
41
|
} else if (data.type === ChannelType.GroupDM) {
|
|
40
42
|
channel = new (getPartialGroupDMChannel())(client, data);
|
|
41
43
|
}
|
|
42
|
-
} else {
|
|
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
|
-
channel = new (getThreadChannel())(guild, data, client);
|
|
71
|
-
if (!allowUnknownGuild) channel.parent?.threads.cache.set(channel.id, channel);
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
case ChannelType.GuildDirectory:
|
|
75
|
-
channel = new (getDirectoryChannel())(guild, data, client);
|
|
76
|
-
break;
|
|
77
|
-
case ChannelType.GuildForum:
|
|
78
|
-
channel = new (getForumChannel())(guild, data, client);
|
|
79
|
-
break;
|
|
80
|
-
case ChannelType.GuildMedia:
|
|
81
|
-
channel = new (getMediaChannel())(guild, data, client);
|
|
82
|
-
break;
|
|
44
|
+
} else if (resolvedGuild || allowUnknownGuild) {
|
|
45
|
+
switch (data.type) {
|
|
46
|
+
case ChannelType.GuildText: {
|
|
47
|
+
channel = new (getTextChannel())(resolvedGuild, data, client);
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
case ChannelType.GuildVoice: {
|
|
51
|
+
channel = new (getVoiceChannel())(resolvedGuild, data, client);
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
case ChannelType.GuildCategory: {
|
|
55
|
+
channel = new (getCategoryChannel())(resolvedGuild, data, client);
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
case ChannelType.GuildAnnouncement: {
|
|
59
|
+
channel = new (getAnnouncementChannel())(resolvedGuild, data, client);
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
case ChannelType.GuildStageVoice: {
|
|
63
|
+
channel = new (getStageChannel())(resolvedGuild, data, client);
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
case ChannelType.AnnouncementThread:
|
|
67
|
+
case ChannelType.PublicThread:
|
|
68
|
+
case ChannelType.PrivateThread: {
|
|
69
|
+
channel = new (getThreadChannel())(resolvedGuild, data, client);
|
|
70
|
+
if (!allowUnknownGuild) channel.parent?.threads.cache.set(channel.id, channel);
|
|
71
|
+
break;
|
|
83
72
|
}
|
|
84
|
-
|
|
73
|
+
case ChannelType.GuildDirectory:
|
|
74
|
+
channel = new (getDirectoryChannel())(resolvedGuild, data, client);
|
|
75
|
+
break;
|
|
76
|
+
case ChannelType.GuildForum:
|
|
77
|
+
channel = new (getForumChannel())(resolvedGuild, data, client);
|
|
78
|
+
break;
|
|
79
|
+
case ChannelType.GuildMedia:
|
|
80
|
+
channel = new (getMediaChannel())(resolvedGuild, data, client);
|
|
81
|
+
break;
|
|
85
82
|
}
|
|
83
|
+
if (channel && !allowUnknownGuild) resolvedGuild.channels?.cache.set(channel.id, channel);
|
|
86
84
|
}
|
|
87
85
|
return channel;
|
|
88
86
|
}
|
package/src/util/Util.js
CHANGED
|
@@ -21,11 +21,11 @@ function flatten(obj, ...props) {
|
|
|
21
21
|
.filter(key => !key.startsWith('_'))
|
|
22
22
|
.map(key => ({ [key]: true }));
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
const mergedProps = objProps.length ? Object.assign(...objProps, ...props) : Object.assign({}, ...props);
|
|
25
25
|
|
|
26
26
|
const out = {};
|
|
27
27
|
|
|
28
|
-
for (let [prop, newProp] of Object.entries(
|
|
28
|
+
for (let [prop, newProp] of Object.entries(mergedProps)) {
|
|
29
29
|
if (!newProp) continue;
|
|
30
30
|
newProp = newProp === true ? prop : newProp;
|
|
31
31
|
|
|
@@ -96,9 +96,9 @@ async function fetchRecommendedShardCount(token, { guildsPerShard = 1_000, multi
|
|
|
96
96
|
* @returns {?PartialEmoji}
|
|
97
97
|
*/
|
|
98
98
|
function parseEmoji(text) {
|
|
99
|
-
|
|
100
|
-
if (!
|
|
101
|
-
const match =
|
|
99
|
+
const decodedText = text.includes('%') ? decodeURIComponent(text) : text;
|
|
100
|
+
if (!decodedText.includes(':')) return { animated: false, name: decodedText, id: undefined };
|
|
101
|
+
const match = decodedText.match(/<?(?:(a):)?(\w{2,32}):(\d{17,19})?>?/);
|
|
102
102
|
return match && { animated: Boolean(match[1]), name: match[2], id: match[3] };
|
|
103
103
|
}
|
|
104
104
|
|
|
@@ -228,10 +228,10 @@ function getSortableGroupTypes(type) {
|
|
|
228
228
|
*/
|
|
229
229
|
function moveElementInArray(array, element, newIndex, offset = false) {
|
|
230
230
|
const index = array.indexOf(element);
|
|
231
|
-
|
|
232
|
-
if (
|
|
231
|
+
const targetIndex = (offset ? index : 0) + newIndex;
|
|
232
|
+
if (targetIndex > -1 && targetIndex < array.length) {
|
|
233
233
|
const removedElement = array.splice(index, 1)[0];
|
|
234
|
-
array.splice(
|
|
234
|
+
array.splice(targetIndex, 0, removedElement);
|
|
235
235
|
}
|
|
236
236
|
return array.indexOf(element);
|
|
237
237
|
}
|