From bf7ea14c4bb4491350f7fe0e63991e55061b72c5 Mon Sep 17 00:00:00 2001 From: Danial Raza Date: Sat, 21 Jun 2025 14:04:01 +0200 Subject: [PATCH 1/3] feat(GuildMember): add `avatarDecorationData` --- .../discord.js/src/structures/GuildMember.js | 28 ++++++++++++++++++- packages/discord.js/typings/index.d.ts | 4 ++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/packages/discord.js/src/structures/GuildMember.js b/packages/discord.js/src/structures/GuildMember.js index 6c428284cb85..a930f345436f 100644 --- a/packages/discord.js/src/structures/GuildMember.js +++ b/packages/discord.js/src/structures/GuildMember.js @@ -133,6 +133,20 @@ class GuildMember extends Base { } else { this.flags ??= new GuildMemberFlagsBitField().freeze(); } + + if (data.avatar_decoration_data) { + /** + * The member avatar decoration's data + * + * @type {?AvatarDecorationData} + */ + this.avatarDecorationData = { + asset: data.avatar_decoration_data.asset, + skuId: data.avatar_decoration_data.sku_id, + }; + } else { + this.avatarDecorationData = null; + } } _clone() { @@ -181,6 +195,15 @@ class GuildMember extends Base { return this.avatar && this.client.rest.cdn.guildMemberAvatar(this.guild.id, this.id, this.avatar, options); } + /** + * A link to the member's avatar decoration. + * + * @returns {?string} + */ + avatarDecorationURL() { + return this.avatarDecorationData ? this.client.rest.cdn.avatarDecoration(this.avatarDecorationData.asset) : null; + } + /** * A link to the member's banner. * @@ -560,7 +583,9 @@ class GuildMember extends Base { this.flags.bitfield === member.flags.bitfield && (this._roles === member._roles || (this._roles.length === member._roles.length && - this._roles.every((role, index) => role === member._roles[index]))) + this._roles.every((role, index) => role === member._roles[index]))) && + this.avatarDecorationData?.asset === member.avatarDecorationData?.asset && + this.avatarDecorationData?.skuId === member.avatarDecorationData?.skuId ); } @@ -587,6 +612,7 @@ class GuildMember extends Base { json.bannerURL = this.bannerURL(); json.displayAvatarURL = this.displayAvatarURL(); json.displayBannerURL = this.displayBannerURL(); + json.avatarDecorationURL = this.avatarDecorationURL(); return json; } } diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index ed2da0646c0f..578515bf1570 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -1596,6 +1596,7 @@ export class GuildMember extends Base { private constructor(client: Client, data: unknown, guild: Guild); private readonly _roles: Snowflake[]; public avatar: string | null; + public avatarDecorationData: AvatarDecorationData | null; public banner: string | null; public get bannable(): boolean; public get dmChannel(): DMChannel | null; @@ -1623,6 +1624,7 @@ export class GuildMember extends Base { public user: User; public get voice(): VoiceState; public avatarURL(options?: ImageURLOptions): string | null; + public avatarDecorationURL(): string | null; public bannerURL(options?: ImageURLOptions): string | null; public ban(options?: BanOptions): Promise; public disableCommunicationUntil(timeout: DateResolvable | null, reason?: string): Promise; @@ -3534,7 +3536,7 @@ export class User extends Base { public get tag(): string; public username: string; public avatarURL(options?: ImageURLOptions): string | null; - public avatarDecorationURL(options?: BaseImageURLOptions): string | null; + public avatarDecorationURL(): string | null; public bannerURL(options?: ImageURLOptions): string | null | undefined; public createDM(force?: boolean): Promise; public deleteDM(): Promise; From 99bf9cac18e410545884444b9753b6a0e59455f7 Mon Sep 17 00:00:00 2001 From: Danial Raza Date: Sat, 21 Jun 2025 14:37:41 +0200 Subject: [PATCH 2/3] feat: add `displayAvatarDecoration()` --- packages/discord.js/src/structures/GuildMember.js | 8 ++++++++ packages/discord.js/typings/index.d.ts | 1 + 2 files changed, 9 insertions(+) diff --git a/packages/discord.js/src/structures/GuildMember.js b/packages/discord.js/src/structures/GuildMember.js index a930f345436f..a38ec1f4ee6f 100644 --- a/packages/discord.js/src/structures/GuildMember.js +++ b/packages/discord.js/src/structures/GuildMember.js @@ -236,6 +236,14 @@ class GuildMember extends Base { return this.bannerURL(options) ?? this.user.bannerURL(options); } + /** + * A link to the member's guild avatar decoration if they have one. + * Otherwise, a link to their {@link User#avatarDecorationURL} will be returned. + */ + displayAvatarDecorationURL() { + return this.avatarDecorationURL() ?? this.user.avatarDecorationURL(); + } + /** * The time this member joined the guild * diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 578515bf1570..5858f8e3f6b5 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -1634,6 +1634,7 @@ export class GuildMember extends Base { public deleteDM(): Promise; public displayAvatarURL(options?: ImageURLOptions): string; public displayBannerURL(options?: ImageURLOptions): string | null; + public displayAvatarDecorationURL(): string | null; public edit(options: GuildMemberEditOptions): Promise; public isCommunicationDisabled(): this is GuildMember & { readonly communicationDisabledUntil: Date; From b282c2dad6bdf9ff3b1cedb513912fb108117ffc Mon Sep 17 00:00:00 2001 From: Danial Raza Date: Sat, 21 Jun 2025 14:47:46 +0200 Subject: [PATCH 3/3] docs: missing `@returns` --- packages/discord.js/src/structures/GuildMember.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/discord.js/src/structures/GuildMember.js b/packages/discord.js/src/structures/GuildMember.js index a38ec1f4ee6f..3be4822e071c 100644 --- a/packages/discord.js/src/structures/GuildMember.js +++ b/packages/discord.js/src/structures/GuildMember.js @@ -239,6 +239,8 @@ class GuildMember extends Base { /** * A link to the member's guild avatar decoration if they have one. * Otherwise, a link to their {@link User#avatarDecorationURL} will be returned. + * + * @returns {?string} */ displayAvatarDecorationURL() { return this.avatarDecorationURL() ?? this.user.avatarDecorationURL();