From 5a611be8debad3ecff5c97dbbe66f6d025687108 Mon Sep 17 00:00:00 2001 From: Danial Raza Date: Tue, 15 Jul 2025 01:35:00 +0200 Subject: [PATCH] feat(User): add `collectibles` (#10939) * feat(User): add `collectibles` * docs: nullable collectibles and nameplate data Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com> --------- Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com> --- packages/discord.js/src/structures/User.js | 37 +++++++++++++++++++- packages/discord.js/src/util/APITypes.js | 5 +++ packages/discord.js/src/util/Transformers.js | 21 +++++++++++ packages/discord.js/typings/index.d.ts | 13 +++++++ 4 files changed, 75 insertions(+), 1 deletion(-) diff --git a/packages/discord.js/src/structures/User.js b/packages/discord.js/src/structures/User.js index e2fa4cab4..0f0e84e22 100644 --- a/packages/discord.js/src/structures/User.js +++ b/packages/discord.js/src/structures/User.js @@ -3,6 +3,7 @@ const { userMention } = require('@discordjs/formatters'); const { calculateUserDefaultAvatarIndex } = require('@discordjs/rest'); const { DiscordSnowflake } = require('@sapphire/snowflake'); +const { _transformCollectibles } = require('../util/Transformers.js'); const { UserFlagsBitField } = require('../util/UserFlagsBitField.js'); const { Base } = require('./Base.js'); @@ -151,6 +152,30 @@ class User extends Base { } else { this.avatarDecorationData = null; } + + /** + * @typedef {Object} NameplateData + * @property {Snowflake} skuId The id of the nameplate's SKU + * @property {string} asset The nameplate's asset path + * @property {string} label The nameplate's label + * @property {NameplatePalette} palette Background color of the nameplate + */ + + /** + * @typedef {Object} Collectibles + * @property {?NameplateData} nameplate The user's nameplate data + */ + + if (data.collectibles) { + /** + * The user's collectibles + * + * @type {?Collectibles} + */ + this.collectibles = _transformCollectibles(data.collectibles); + } else { + this.collectibles = null; + } } /** @@ -338,7 +363,11 @@ class User extends Base { this.banner === user.banner && this.accentColor === user.accentColor && this.avatarDecorationData?.asset === user.avatarDecorationData?.asset && - this.avatarDecorationData?.skuId === user.avatarDecorationData?.skuId + this.avatarDecorationData?.skuId === user.avatarDecorationData?.skuId && + this.collectibles?.nameplate?.skuId === user.collectibles?.nameplate?.skuId && + this.collectibles?.nameplate?.asset === user.collectibles?.nameplate?.asset && + this.collectibles?.nameplate?.label === user.collectibles?.nameplate?.label && + this.collectibles?.nameplate?.palette === user.collectibles?.nameplate?.palette ); } @@ -363,6 +392,12 @@ class User extends Base { ('avatar_decoration_data' in user ? this.avatarDecorationData?.asset === user.avatar_decoration_data?.asset && this.avatarDecorationData?.skuId === user.avatar_decoration_data?.sku_id + : true) && + ('collectibles' in user + ? this.collectibles?.nameplate?.skuId === user.collectibles?.nameplate?.sku_id && + this.collectibles?.nameplate?.asset === user.collectibles?.nameplate?.asset && + this.collectibles?.nameplate?.label === user.collectibles?.nameplate?.label && + this.collectibles?.nameplate?.palette === user.collectibles?.nameplate?.palette : true) ); } diff --git a/packages/discord.js/src/util/APITypes.js b/packages/discord.js/src/util/APITypes.js index 95e4825ab..92377d3d5 100644 --- a/packages/discord.js/src/util/APITypes.js +++ b/packages/discord.js/src/util/APITypes.js @@ -549,6 +549,11 @@ * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/MessageFlags} */ +/** + * @external NameplatePalette + * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/NameplatePalette} + */ + /** * @external OAuth2Scopes * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/OAuth2Scopes} diff --git a/packages/discord.js/src/util/Transformers.js b/packages/discord.js/src/util/Transformers.js index 5609d03b0..2b73fa3bb 100644 --- a/packages/discord.js/src/util/Transformers.js +++ b/packages/discord.js/src/util/Transformers.js @@ -92,8 +92,29 @@ function _transformAPIIncidentsData(data) { }; } +/** + * Transforms a collectibles object to a camel-cased variant. + * + * @param {APICollectibles} collectibles The collectibles to transform + * @returns {Collectibles} + * @ignore + */ +function _transformCollectibles(collectibles) { + if (!collectibles.nameplate) return { nameplate: null }; + + return { + nameplate: { + skuId: collectibles.nameplate.sku_id, + asset: collectibles.nameplate.asset, + label: collectibles.nameplate.label, + palette: collectibles.nameplate.palette, + }, + }; +} + exports.toSnakeCase = toSnakeCase; exports._transformAPIAutoModerationAction = _transformAPIAutoModerationAction; exports._transformAPIMessageInteractionMetadata = _transformAPIMessageInteractionMetadata; exports._transformGuildScheduledEventRecurrenceRule = _transformGuildScheduledEventRecurrenceRule; exports._transformAPIIncidentsData = _transformAPIIncidentsData; +exports._transformCollectibles = _transformCollectibles; diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 3a786889f..c39dd4db6 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -170,6 +170,7 @@ import { MessageFlags, MessageReferenceType, MessageType, + NameplatePalette, OAuth2Scopes, OverwriteType, PermissionFlagsBits, @@ -3509,6 +3510,17 @@ export interface AvatarDecorationData { skuId: Snowflake; } +export interface NameplateData { + asset: string; + label: string; + palette: NameplatePalette; + skuId: Snowflake; +} + +export interface Collectibles { + nameplate: NameplateData | null; +} + export interface UnfurledMediaItemData { url: string; } @@ -3531,6 +3543,7 @@ export class User extends Base { public bot: boolean; public get createdAt(): Date; public get createdTimestamp(): number; + public collectibles: Collectibles | null; public discriminator: string; public get displayName(): string; public get defaultAvatarURL(): string;