From 88e85b6efac416d119b854edf1fe589e5f958716 Mon Sep 17 00:00:00 2001 From: Almeida Date: Sun, 15 Oct 2023 20:19:11 +0100 Subject: [PATCH 1/4] feat(User): add `avatarDecorationData` --- packages/discord.js/src/structures/User.js | 26 +++++++++++++++++++++- packages/discord.js/typings/index.d.ts | 9 +++++++- packages/rest/__tests__/CDN.test.ts | 8 +++++++ packages/rest/src/lib/CDN.ts | 21 ++++++++++++++++- 4 files changed, 61 insertions(+), 3 deletions(-) diff --git a/packages/discord.js/src/structures/User.js b/packages/discord.js/src/structures/User.js index 4e38d2da4d42..fa2950062b47 100644 --- a/packages/discord.js/src/structures/User.js +++ b/packages/discord.js/src/structures/User.js @@ -127,11 +127,31 @@ class User extends Base { /** * The user avatar decoration's hash * @type {?string} + * @deprecated Use `avatarDecorationData` instead */ this.avatarDecoration = data.avatar_decoration; } else { this.avatarDecoration ??= null; } + + /** + * @typedef {Object} AvatarDecorationData + * @property {string} asset The avatar decoration hash + * @property {Snowflake} skuId The id of the avatar decoration's SKU + */ + + if (data.avatar_decoration_data) { + /** + * The user 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; + } } /** @@ -172,10 +192,14 @@ class User extends Base { /** * A link to the user's avatar decoration. - * @param {BaseImageURLOptions} [options={}] Options for the image URL + * @param {ImageURLOptions} [options={}] Options for the image URL * @returns {?string} */ avatarDecorationURL(options = {}) { + if (this.avatarDecorationData) { + return this.client.rest.cdn.avatarDecoration(this.avatarDecorationData.asset, options); + } + return this.avatarDecoration && this.client.rest.cdn.avatarDecoration(this.id, this.avatarDecoration, options); } diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 1a80284102b0..73f0a8228373 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -3131,13 +3131,20 @@ export class Typing extends Base { }; } +export interface AvatarDecorationData { + asset: string; + skuId: Snowflake; +} + export class User extends PartialTextBasedChannel(Base) { protected constructor(client: Client, data: RawUserData); private _equals(user: APIUser): boolean; public accentColor: number | null | undefined; public avatar: string | null; + /** @deprecated Use {@link avatarDecorationData} instead */ public avatarDecoration: string | null; + public avatarDecorationData: AvatarDecorationData | null; public banner: string | null | undefined; public bot: boolean; public get createdAt(): Date; @@ -3155,7 +3162,7 @@ export class User extends PartialTextBasedChannel(Base) { public get tag(): string; public username: string; public avatarURL(options?: ImageURLOptions): string | null; - public avatarDecorationURL(options?: BaseImageURLOptions): string | null; + public avatarDecorationURL(options?: ImageURLOptions): string | null; public bannerURL(options?: ImageURLOptions): string | null | undefined; public createDM(force?: boolean): Promise; public deleteDM(): Promise; diff --git a/packages/rest/__tests__/CDN.test.ts b/packages/rest/__tests__/CDN.test.ts index 8efe234e587d..a06c041999ff 100644 --- a/packages/rest/__tests__/CDN.test.ts +++ b/packages/rest/__tests__/CDN.test.ts @@ -29,6 +29,14 @@ test('avatar dynamic-not-animated', () => { expect(cdn.avatar(id, hash)).toEqual(`${base}/avatars/${id}/${hash}.webp`); }); +test('avatar decoration default', () => { + expect(cdn.avatarDecoration(id, hash)).toEqual(`${base}/avatar-decorations/${id}/${hash}.webp`); +}); + +test('avatar decoration presets default', () => { + expect(cdn.avatarDecoration(hash)).toEqual(`${base}/avatar-decoration-presets/${hash}.webp`); +}); + test('banner default', () => { expect(cdn.banner(id, hash)).toEqual(`${base}/banners/${id}/${hash}.webp`); }); diff --git a/packages/rest/src/lib/CDN.ts b/packages/rest/src/lib/CDN.ts index 6ef6f67e2b27..dd21c96819ad 100644 --- a/packages/rest/src/lib/CDN.ts +++ b/packages/rest/src/lib/CDN.ts @@ -97,9 +97,18 @@ export class CDN { return this.dynamicMakeURL(`/avatars/${id}/${avatarHash}`, avatarHash, options); } + /** + * Generates a user avatar decoration preset URL. + * + * @param asset - The avatar decoration hash + * @param options - Optional options for the avatar decoration preset + */ + public avatarDecoration(asset: string, options?: Readonly): string; + /** * Generates a user avatar decoration URL. * + * @deprecated This overload is deprecated. Pass an hash instead. * @param userId - The id of the user * @param userAvatarDecoration - The hash provided by Discord for this avatar decoration * @param options - Optional options for the avatar decoration @@ -108,8 +117,18 @@ export class CDN { userId: string, userAvatarDecoration: string, options?: Readonly, + ): string; + + public avatarDecoration( + userIdOrAsset: string, + assetOrOptions?: Readonly | string, + options?: Readonly, ): string { - return this.makeURL(`/avatar-decorations/${userId}/${userAvatarDecoration}`, options); + if (typeof assetOrOptions === 'string') { + return this.makeURL(`/avatar-decorations/${userIdOrAsset}/${assetOrOptions}`, options); + } + + return this.dynamicMakeURL(`/avatar-decoration-presets/${userIdOrAsset}`, userIdOrAsset, assetOrOptions); } /** From a4417d78cd5f4750eebd47515ae7f18e89256432 Mon Sep 17 00:00:00 2001 From: Almeida Date: Thu, 2 Nov 2023 01:39:36 +0000 Subject: [PATCH 2/4] fix: remove options --- packages/discord.js/src/structures/User.js | 4 ++-- packages/discord.js/typings/index.d.ts | 2 +- packages/rest/__tests__/CDN.test.ts | 4 ++-- packages/rest/src/lib/CDN.ts | 14 +++++++------- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/discord.js/src/structures/User.js b/packages/discord.js/src/structures/User.js index fa2950062b47..a66f6eb10ff5 100644 --- a/packages/discord.js/src/structures/User.js +++ b/packages/discord.js/src/structures/User.js @@ -192,12 +192,12 @@ class User extends Base { /** * A link to the user's avatar decoration. - * @param {ImageURLOptions} [options={}] Options for the image URL + * @param {BaseImageURLOptions} [options={}] Options for the image URL * @returns {?string} */ avatarDecorationURL(options = {}) { if (this.avatarDecorationData) { - return this.client.rest.cdn.avatarDecoration(this.avatarDecorationData.asset, options); + return this.client.rest.cdn.avatarDecoration(this.avatarDecorationData.asset); } return this.avatarDecoration && this.client.rest.cdn.avatarDecoration(this.id, this.avatarDecoration, options); diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 73f0a8228373..1f4954a5293f 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -3162,7 +3162,7 @@ export class User extends PartialTextBasedChannel(Base) { public get tag(): string; public username: string; public avatarURL(options?: ImageURLOptions): string | null; - public avatarDecorationURL(options?: ImageURLOptions): string | null; + public avatarDecorationURL(options?: BaseImageURLOptions): string | null; public bannerURL(options?: ImageURLOptions): string | null | undefined; public createDM(force?: boolean): Promise; public deleteDM(): Promise; diff --git a/packages/rest/__tests__/CDN.test.ts b/packages/rest/__tests__/CDN.test.ts index a06c041999ff..ed2600f4f614 100644 --- a/packages/rest/__tests__/CDN.test.ts +++ b/packages/rest/__tests__/CDN.test.ts @@ -33,8 +33,8 @@ test('avatar decoration default', () => { expect(cdn.avatarDecoration(id, hash)).toEqual(`${base}/avatar-decorations/${id}/${hash}.webp`); }); -test('avatar decoration presets default', () => { - expect(cdn.avatarDecoration(hash)).toEqual(`${base}/avatar-decoration-presets/${hash}.webp`); +test('avatar decoration preset', () => { + expect(cdn.avatarDecoration(hash)).toEqual(`${base}/avatar-decoration-presets/${hash}.png`); }); test('banner default', () => { diff --git a/packages/rest/src/lib/CDN.ts b/packages/rest/src/lib/CDN.ts index dd21c96819ad..7d2ac6540c1e 100644 --- a/packages/rest/src/lib/CDN.ts +++ b/packages/rest/src/lib/CDN.ts @@ -101,14 +101,13 @@ export class CDN { * Generates a user avatar decoration preset URL. * * @param asset - The avatar decoration hash - * @param options - Optional options for the avatar decoration preset */ - public avatarDecoration(asset: string, options?: Readonly): string; + public avatarDecoration(asset: string): string; /** * Generates a user avatar decoration URL. * - * @deprecated This overload is deprecated. Pass an hash instead. + * @deprecated This overload is deprecated. Pass a hash instead. * @param userId - The id of the user * @param userAvatarDecoration - The hash provided by Discord for this avatar decoration * @param options - Optional options for the avatar decoration @@ -116,19 +115,20 @@ export class CDN { public avatarDecoration( userId: string, userAvatarDecoration: string, + // eslint-disable-next-line @typescript-eslint/unified-signatures options?: Readonly, ): string; public avatarDecoration( userIdOrAsset: string, - assetOrOptions?: Readonly | string, + userAvatarDecoration?: string, options?: Readonly, ): string { - if (typeof assetOrOptions === 'string') { - return this.makeURL(`/avatar-decorations/${userIdOrAsset}/${assetOrOptions}`, options); + if (userAvatarDecoration) { + return this.makeURL(`/avatar-decorations/${userIdOrAsset}/${userAvatarDecoration}`, options); } - return this.dynamicMakeURL(`/avatar-decoration-presets/${userIdOrAsset}`, userIdOrAsset, assetOrOptions); + return this.makeURL(`/avatar-decoration-presets/${userIdOrAsset}`, { extension: 'png' }); } /** From e1b80543dcaee3079543be517dbc43cfcdde60c1 Mon Sep 17 00:00:00 2001 From: Almeida Date: Sun, 3 Dec 2023 01:20:28 +0000 Subject: [PATCH 3/4] fix(User): check avatar decoration in equals() methods --- packages/discord.js/src/structures/User.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/discord.js/src/structures/User.js b/packages/discord.js/src/structures/User.js index a66f6eb10ff5..196425a8f42f 100644 --- a/packages/discord.js/src/structures/User.js +++ b/packages/discord.js/src/structures/User.js @@ -310,7 +310,10 @@ class User extends Base { this.avatar === user.avatar && this.flags?.bitfield === user.flags?.bitfield && this.banner === user.banner && - this.accentColor === user.accentColor + this.accentColor === user.accentColor && + this.avatarDecoration === user.avatarDecoration && + this.avatarDecorationData?.asset === user.avatarDecorationData?.asset && + this.avatarDecorationData?.skuId === user.avatarDecorationData?.skuId ); } @@ -330,7 +333,12 @@ class User extends Base { this.avatar === user.avatar && this.flags?.bitfield === user.public_flags && ('banner' in user ? this.banner === user.banner : true) && - ('accent_color' in user ? this.accentColor === user.accent_color : true) + ('accent_color' in user ? this.accentColor === user.accent_color : true) && + ('avatar_decoration' in user ? this.avatarDecoration === user.avatar_decoration : true) && + ('avatar_decoration_data' in user + ? this.avatarDecorationData?.asset === user.avatar_decoration_data?.asset && + this.avatarDecorationData?.skuId === user.avatar_decoration_data?.sku_id + : true) ); } From dbf8c1e5fe5b282a3c0fd273a43f9dc5f08e2894 Mon Sep 17 00:00:00 2001 From: Jiralite <33201955+Jiralite@users.noreply.github.com> Date: Thu, 30 May 2024 17:31:57 +0100 Subject: [PATCH 4/4] docs: Add full reference --- packages/discord.js/typings/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index c3118aa6823c..bab1780b242c 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -3322,7 +3322,7 @@ export class User extends Base { public accentColor: number | null | undefined; public avatar: string | null; - /** @deprecated Use {@link avatarDecorationData} instead */ + /** @deprecated Use {@link User.avatarDecorationData} instead */ public avatarDecoration: string | null; public avatarDecorationData: AvatarDecorationData | null; public banner: string | null | undefined;