From 8bcf8c94e9b8de9c101564a8e4c19c3d8981edb6 Mon Sep 17 00:00:00 2001 From: Almeida Date: Sun, 29 Mar 2026 10:19:42 +0100 Subject: [PATCH] feat(GuildMember): add collectibles (#11468) feat(GuildMember): add collectibles, fix partial update handling --- .../discord.js/src/structures/GuildMember.js | 18 +++++++++++++++++- packages/discord.js/src/structures/User.js | 6 +++--- packages/discord.js/typings/index.d.ts | 1 + 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/packages/discord.js/src/structures/GuildMember.js b/packages/discord.js/src/structures/GuildMember.js index f92e0ead5..334e9beca 100644 --- a/packages/discord.js/src/structures/GuildMember.js +++ b/packages/discord.js/src/structures/GuildMember.js @@ -5,6 +5,7 @@ const { DiscordjsError, ErrorCodes } = require('../errors/index.js'); const { GuildMemberRoleManager } = require('../managers/GuildMemberRoleManager.js'); const { GuildMemberFlagsBitField } = require('../util/GuildMemberFlagsBitField.js'); const { PermissionsBitField } = require('../util/PermissionsBitField.js'); +const { _transformCollectibles } = require('../util/Transformers.js'); const { Base } = require('./Base.js'); const { VoiceState } = require('./VoiceState.js'); @@ -150,6 +151,17 @@ class GuildMember extends Base { } else { this.avatarDecorationData = null; } + + if ('collectibles' in data) { + /** + * The member's collectibles + * + * @type {?Collectibles} + */ + this.collectibles = data.collectibles ? _transformCollectibles(data.collectibles) : null; + } else { + this.collectibles ??= null; + } } _clone() { @@ -599,7 +611,11 @@ class GuildMember extends Base { (this._roles.length === member._roles.length && this._roles.every((role, index) => role === member._roles[index]))) && this.avatarDecorationData?.asset === member.avatarDecorationData?.asset && - this.avatarDecorationData?.skuId === member.avatarDecorationData?.skuId + this.avatarDecorationData?.skuId === member.avatarDecorationData?.skuId && + this.collectibles?.nameplate?.skuId === member.collectibles?.nameplate?.skuId && + this.collectibles?.nameplate?.asset === member.collectibles?.nameplate?.asset && + this.collectibles?.nameplate?.label === member.collectibles?.nameplate?.label && + this.collectibles?.nameplate?.palette === member.collectibles?.nameplate?.palette ); } diff --git a/packages/discord.js/src/structures/User.js b/packages/discord.js/src/structures/User.js index 46e7b26cf..404cbc9d0 100644 --- a/packages/discord.js/src/structures/User.js +++ b/packages/discord.js/src/structures/User.js @@ -170,15 +170,15 @@ class User extends Base { * @property {?NameplateData} nameplate The user's nameplate data */ - if (data.collectibles) { + if ('collectibles' in data) { /** * The user's collectibles * * @type {?Collectibles} */ - this.collectibles = _transformCollectibles(data.collectibles); + this.collectibles = data.collectibles ? _transformCollectibles(data.collectibles) : null; } else { - this.collectibles = null; + this.collectibles ??= null; } /** diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 6b7d67197..be0aeac86 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -1638,6 +1638,7 @@ export class GuildMember extends Base { public avatarDecorationData: AvatarDecorationData | null; public banner: string | null; public get bannable(): boolean; + public collectibles: Collectibles | null; public get dmChannel(): DMChannel | null; public get displayColor(): number; public get displayHexColor(): HexColorString;