11'use strict' ;
22
3+ const { process } = require ( 'node:process' ) ;
34const { setTimeout, clearTimeout } = require ( 'node:timers' ) ;
45const { Collection } = require ( '@discordjs/collection' ) ;
56const { makeURLSearchParams } = require ( '@discordjs/rest' ) ;
@@ -10,10 +11,13 @@ const { DiscordjsError, DiscordjsTypeError, DiscordjsRangeError, ErrorCodes } =
1011const BaseGuildVoiceChannel = require ( '../structures/BaseGuildVoiceChannel' ) ;
1112const { GuildMember } = require ( '../structures/GuildMember' ) ;
1213const { Role } = require ( '../structures/Role' ) ;
14+ const { resolveImage } = require ( '../util/DataResolver' ) ;
1315const Events = require ( '../util/Events' ) ;
1416const { GuildMemberFlagsBitField } = require ( '../util/GuildMemberFlagsBitField' ) ;
1517const Partials = require ( '../util/Partials' ) ;
1618
19+ let deprecatedEmittedForEditSoleNickname = false ;
20+
1721/**
1822 * Manages API methods for GuildMembers and stores their cache.
1923 * @extends {CachedManager }
@@ -336,8 +340,8 @@ class GuildMemberManager extends CachedManager {
336340 */
337341
338342 /**
339- * Edits a member of the guild.
340- * <info>The user must be a member of the guild</info>
343+ * Edits a member of a guild.
344+ *
341345 * @param {UserResolvable } user The member to edit
342346 * @param {GuildMemberEditOptions } options The options to provide
343347 * @returns {Promise<GuildMember> }
@@ -372,20 +376,69 @@ class GuildMemberManager extends CachedManager {
372376 }
373377
374378 let endpoint ;
379+
375380 if ( id === this . client . user . id ) {
376381 const keys = Object . keys ( options ) ;
377- if ( keys . length === 1 && keys [ 0 ] === 'nick' ) endpoint = Routes . guildMember ( this . guild . id ) ;
378- else endpoint = Routes . guildMember ( this . guild . id , id ) ;
379- } else {
380- endpoint = Routes . guildMember ( this . guild . id , id ) ;
382+
383+ if ( keys . length === 1 && keys [ 0 ] === 'nick' ) {
384+ // For modifying the current application's nickname only, we use the /guilds/{guild.id}/members/@me endpoint.
385+ // This endpoint only requires the CHANGE_NICKNAME permission.
386+ // The other endpoint would require the MANAGE_NICKNAMES permission.
387+ // In v15, this will be split out, so emit a deprecation.
388+ endpoint = Routes . guildMember ( this . guild . id , '@me' ) ;
389+
390+ if ( ! deprecatedEmittedForEditSoleNickname ) {
391+ process . emitWarning (
392+ // eslint-disable-next-line max-len
393+ "You should use GuildMemberManager#editMe() when changing your nickname. Due to Discord's API changes, GuildMemberManager#edit() will end up requiring MANAGE_NICKNAMES in v15." ,
394+ 'DeprecationWarning' ,
395+ ) ;
396+
397+ deprecatedEmittedForEditSoleNickname = true ;
398+ }
399+ }
381400 }
401+
402+ endpoint ??= Routes . guildMember ( this . guild . id , id ) ;
382403 const d = await this . client . rest . patch ( endpoint , { body : options , reason } ) ;
383404
384405 const clone = this . cache . get ( id ) ?. _clone ( ) ;
385406 clone ?. _patch ( d ) ;
386407 return clone ?? this . _add ( d , false ) ;
387408 }
388409
410+ /**
411+ * The data for editing the current application's guild member.
412+ *
413+ * @typedef {Object } GuildMemberEditMeOptions
414+ * @property {?string } [nick] The nickname to set
415+ * @property {?(BufferResolvable|Base64Resolvable) } [banner] The banner to set
416+ * @property {?(BufferResolvable|Base64Resolvable) } [avatar] The avatar to set
417+ * @property {?string } [bio] The bio to set
418+ * @property {string } [reason] The reason to use
419+ */
420+
421+ /**
422+ * Edits the current application's guild member in a guild.
423+ *
424+ * @param {GuildMemberEditMeOptions } options The options to provide
425+ * @returns {Promise<GuildMember> }
426+ */
427+ async editMe ( { reason, ...options } ) {
428+ const data = await this . client . rest . patch ( Routes . guildMember ( this . guild . id , '@me' ) , {
429+ body : {
430+ ...options ,
431+ banner : options . banner && ( await resolveImage ( options . banner ) ) ,
432+ avatar : options . avatar && ( await resolveImage ( options . avatar ) ) ,
433+ } ,
434+ reason,
435+ } ) ;
436+
437+ const clone = this . me ?. _clone ( ) ;
438+ clone ?. _patch ( data ) ;
439+ return clone ?? this . _add ( data , false ) ;
440+ }
441+
389442 /**
390443 * Options used for pruning guild members.
391444 * <info>It's recommended to set {@link GuildPruneMembersOptions#count options.count}
0 commit comments