Skip to content

Commit d5c9546

Browse files
committed
fix(guildChannel): better channel editing
1 parent 180dd60 commit d5c9546

File tree

1 file changed

+52
-30
lines changed

1 file changed

+52
-30
lines changed

packages/discord.js/src/managers/GuildChannelManager.js

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const { ChannelFlagsBitField } = require('../util/ChannelFlagsBitField.js');
1212
const { transformGuildForumTag, transformGuildDefaultReaction } = require('../util/Channels.js');
1313
const { ThreadChannelTypes } = require('../util/Constants.js');
1414
const { resolveImage } = require('../util/DataResolver.js');
15+
const { toSnakeCase } = require('../util/Transformers.js');
1516
const { setPosition } = require('../util/Util.js');
1617
const { CachedManager } = require('./CachedManager.js');
1718
const { GuildTextThreadManager } = require('./GuildTextThreadManager.js');
@@ -298,7 +299,7 @@ class GuildChannelManager extends CachedManager {
298299
/**
299300
* Edits the channel.
300301
*
301-
* @param {GuildChannelResolvable} channel The channel to edit
302+
* @param {GuildChannelResolvable} channel The channel to edit. Can be the id of an uncached channel if not editing position or locking permissions
302303
* @param {GuildChannelEditOptions} options Options for editing the channel
303304
* @returns {Promise<GuildChannel>}
304305
* @example
@@ -308,13 +309,17 @@ class GuildChannelManager extends CachedManager {
308309
* .catch(console.error);
309310
*/
310311
async edit(channel, options) {
311-
const resolvedChannel = this.resolve(channel);
312-
if (!resolvedChannel) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
312+
// Let uncached channels be edited if they don't need to lock to a parent without passing parent_id
313+
const resolvedChannelId = this.resolveId(channel);
314+
if (!resolvedChannelId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
313315

314316
const parentId = options.parent && this.client.channels.resolveId(options.parent);
315317

316318
if (options.position !== undefined) {
317-
await this.setPosition(resolvedChannel, options.position, { position: options.position, reason: options.reason });
319+
await this.setPosition(resolvedChannelId, options.position, {
320+
position: options.position,
321+
reason: options.reason,
322+
});
318323
}
319324

320325
let permission_overwrites = options.permissionOverwrites?.map(overwrite =>
@@ -329,36 +334,53 @@ class GuildChannelManager extends CachedManager {
329334
PermissionOverwrites.resolve(overwrite, this.guild),
330335
);
331336
}
332-
} else if (resolvedChannel.parent) {
333-
permission_overwrites = resolvedChannel.parent.permissionOverwrites.cache.map(overwrite =>
334-
PermissionOverwrites.resolve(overwrite, this.guild),
335-
);
337+
} else {
338+
const resolvedChannel = this.resolve(channel);
339+
if (!resolvedChannel) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
340+
if (resolvedChannel.parent) {
341+
permission_overwrites = resolvedChannel.parent.permissionOverwrites.cache.map(overwrite =>
342+
PermissionOverwrites.resolve(overwrite, this.guild),
343+
);
344+
}
336345
}
337346
}
338347

339-
const newData = await this.client.rest.patch(Routes.channel(resolvedChannel.id), {
340-
body: {
341-
name: options.name,
342-
type: options.type,
343-
topic: options.topic,
344-
nsfw: options.nsfw,
345-
bitrate: options.bitrate,
346-
user_limit: options.userLimit,
347-
rtc_region: options.rtcRegion,
348-
video_quality_mode: options.videoQualityMode,
349-
parent_id: parentId,
350-
lock_permissions: options.lockPermissions,
351-
rate_limit_per_user: options.rateLimitPerUser,
352-
default_auto_archive_duration: options.defaultAutoArchiveDuration,
353-
permission_overwrites,
354-
available_tags: options.availableTags?.map(availableTag => transformGuildForumTag(availableTag)),
355-
default_reaction_emoji:
356-
options.defaultReactionEmoji && transformGuildDefaultReaction(options.defaultReactionEmoji),
357-
default_thread_rate_limit_per_user: options.defaultThreadRateLimitPerUser,
358-
flags: 'flags' in options ? ChannelFlagsBitField.resolve(options.flags) : undefined,
359-
default_sort_order: options.defaultSortOrder,
360-
default_forum_layout: options.defaultForumLayout,
348+
const snakeCaseBody = Object.assign(
349+
// Remove properties we don't want to pass to the API in the body
350+
{
351+
set parent(_) {},
352+
set position(_) {},
353+
set reason(_) {},
361354
},
355+
toSnakeCase(options),
356+
);
357+
358+
// This overwrites a passed snake_case version if a camelCase version OR `parent` is passed
359+
if (parentId) {
360+
snakeCaseBody.parent_id = parentId;
361+
}
362+
363+
// This overwrites a passed snake_case version if a camelCase version is passed
364+
if (permission_overwrites) {
365+
snakeCaseBody.permission_overwrites = permission_overwrites;
366+
}
367+
368+
if (snakeCaseBody.available_tags) {
369+
snakeCaseBody.available_tags = snakeCaseBody.available_tags.map(availableTag =>
370+
'emoji' in availableTag ? transformGuildForumTag(availableTag) : availableTag,
371+
);
372+
}
373+
374+
if (snakeCaseBody.default_reaction_emoji?.id) {
375+
snakeCaseBody.default_reaction_emoji = transformGuildDefaultReaction(snakeCaseBody.default_reaction_emoji);
376+
}
377+
378+
if (snakeCaseBody.flags) {
379+
snakeCaseBody.flags = ChannelFlagsBitField.resolve(snakeCaseBody.flags);
380+
}
381+
382+
const newData = await this.client.rest.patch(Routes.channel(resolvedChannelId), {
383+
body: snakeCaseBody,
362384
reason: options.reason,
363385
});
364386

0 commit comments

Comments
 (0)