@@ -12,6 +12,7 @@ const { ChannelFlagsBitField } = require('../util/ChannelFlagsBitField.js');
1212const { transformGuildForumTag, transformGuildDefaultReaction } = require ( '../util/Channels.js' ) ;
1313const { ThreadChannelTypes } = require ( '../util/Constants.js' ) ;
1414const { resolveImage } = require ( '../util/DataResolver.js' ) ;
15+ const { toSnakeCase } = require ( '../util/Transformers.js' ) ;
1516const { setPosition } = require ( '../util/Util.js' ) ;
1617const { CachedManager } = require ( './CachedManager.js' ) ;
1718const { 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