From be12a075ffd3c3fa378976608250e508ecbfcd06 Mon Sep 17 00:00:00 2001 From: Zikeji Date: Mon, 16 Sep 2024 06:30:57 -0400 Subject: [PATCH 1/2] fix: return an empty result properly --- src/util/ResultArray.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/util/ResultArray.ts b/src/util/ResultArray.ts index b07e09f7..d523f2f7 100644 --- a/src/util/ResultArray.ts +++ b/src/util/ResultArray.ts @@ -27,13 +27,18 @@ export function getResultArray< if (!(key in clonedResponse)) { throw new TypeError(`Key "${String(key)}" was not in the response.`); } - const items = clonedResponse[key]; + let items = clonedResponse[key]; const { ratelimit, cached, cloudflareCache } = clonedResponse; if (!Array.isArray(items)) { - throw new TypeError(`Key "${String(key)}" is not an array.`); + if (items !== null) { + throw new TypeError( + `Key "${String(key)}" has an unexpected type ${typeof items}.` + ); + } + items = [] as never; } delete clonedResponse[key]; - const arr = ([...items] as never) as ResultArray; + const arr = [...(items as never[])] as ResultArray; const meta: Omit & DefaultMeta = { ...clonedResponse, }; From 569d24523327cab13e8ec771103b7f5f08023d0d Mon Sep 17 00:00:00 2001 From: Zikeji Date: Mon, 16 Sep 2024 06:31:21 -0400 Subject: [PATCH 2/2] fix: properly type hint the nature of values being undefined in the event a player has never touched Hypixel --- src/helpers/BedwarsLevelInfo.ts | 2 +- src/helpers/SkyWarsLevelInfo.ts | 2 +- src/types/Augmented/Player.ts | 36 ++++++++++++++++----------------- src/types/AugmentedTypes.ts | 2 +- tests/helpers.test.ts | 2 +- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/helpers/BedwarsLevelInfo.ts b/src/helpers/BedwarsLevelInfo.ts index e0188804..a8654ff5 100644 --- a/src/helpers/BedwarsLevelInfo.ts +++ b/src/helpers/BedwarsLevelInfo.ts @@ -43,7 +43,7 @@ export function getBedwarsLevelInfo( const currentExp = typeof data === "number" ? data - : data.stats.Bedwars?.Experience ?? data.stats.Bedwars?.Experience_new; + : data.stats?.Bedwars?.Experience ?? data.stats?.Bedwars?.Experience_new; if (typeof currentExp !== "number" || Number.isNaN(currentExp)) { throw new TypeError( "Data supplied does not contain player Bedwars experience." diff --git a/src/helpers/SkyWarsLevelInfo.ts b/src/helpers/SkyWarsLevelInfo.ts index e09e43a5..cacff826 100644 --- a/src/helpers/SkyWarsLevelInfo.ts +++ b/src/helpers/SkyWarsLevelInfo.ts @@ -90,7 +90,7 @@ export function getSkyWarsLevelInfo( const currentExp = typeof data === "number" ? data - : (data.stats.SkyWars?.skywars_experience as number); + : (data.stats?.SkyWars?.skywars_experience as number); if (typeof currentExp !== "number" || Number.isNaN(currentExp)) { throw new TypeError( "Data supplied does not contain player SkyWars experience." diff --git a/src/types/Augmented/Player.ts b/src/types/Augmented/Player.ts index 175e186c..6ef43d43 100644 --- a/src/types/Augmented/Player.ts +++ b/src/types/Augmented/Player.ts @@ -1,12 +1,12 @@ export type Player = { - _id: string; - uuid: string; - firstLogin: number; - playername: string; - displayname: string; + _id?: string; + uuid?: string; + firstLogin?: number; + playername?: string; + displayname?: string; lastLogin?: number; achievementPoints?: number; - achievementRewardsNew: { + achievementRewardsNew?: { [key: `for_points_${number}`]: number | undefined; }; achievementSync?: { quake_tiered: number }; @@ -23,12 +23,12 @@ export type Player = { }; }; achievementTracking?: string[]; - achievements: { [key: string]: number }; - achievementsOneTime: string[]; + achievements?: { [key: string]: number }; + achievementsOneTime?: string[]; adsense_tokens?: number; - channel: string; - challenges: { - all_time: { + channel?: string; + challenges?: { + all_time?: { [key: string]: number | undefined; }; [key: string]: unknown; @@ -41,7 +41,7 @@ export type Player = { disabledProjectileTrails?: boolean; eugene?: { dailyTwoKExp?: number }; fortuneBuff?: number; - giftingMeta: { + giftingMeta?: { bundlesReceived?: number; realBundlesReceived?: number; bundlesGiven?: number; @@ -75,7 +75,7 @@ export type Player = { levelUp_VIP?: number; levelUp_VIP_PLUS?: number; leveling?: { claimedRewards: number }; - monthlycrates: { + monthlycrates?: { /** keys are in the format of M-YYYY (month is non zero leading, so april 2024 would be 4-2024) */ [key: `${number}-${number}`]: | { @@ -91,9 +91,9 @@ export type Player = { monthlyRankColor?: string; mostRecentGameType?: string; mostRecentMonthlyPackageRank?: string; - networkExp: number; + networkExp?: number; network_update_book?: string; - newPackageRank: string; + newPackageRank?: string; onetime_achievement_menu_sort?: string; outfit?: { BOOTS?: string; @@ -193,7 +193,7 @@ export type Player = { } | undefined; }; - quests: { + quests?: { [key: string]: | { active?: { @@ -209,7 +209,7 @@ export type Player = { | undefined; }; questSettings?: { autoActivate: boolean }; - rankPlusColor: string; + rankPlusColor?: string; rewardHighScore?: number; rewardScore?: number; rewardStreak?: number; @@ -223,7 +223,7 @@ export type Player = { prompt?: boolean; }; spec_first_person?: boolean; - stats: PlayerStats; + stats?: PlayerStats; totalDailyRewards?: number; totalRewards?: number; tourney?: { diff --git a/src/types/AugmentedTypes.ts b/src/types/AugmentedTypes.ts index a9e62920..e2038843 100644 --- a/src/types/AugmentedTypes.ts +++ b/src/types/AugmentedTypes.ts @@ -27,7 +27,7 @@ export type LeaderboardsResponse = Paths.V2Leaderboards.Get.Responses.$200 & export type PlayerResponse = Paths.V2Player.Get.Responses.$200 & Record & { - player: Player; + player: Player | null; }; export type PunishmentStatsResponse = Paths.V2Punishmentstats.Get.Responses.$200 & diff --git a/tests/helpers.test.ts b/tests/helpers.test.ts index 89b005a5..6161dc42 100644 --- a/tests/helpers.test.ts +++ b/tests/helpers.test.ts @@ -170,7 +170,7 @@ describe("Test transformItemData", async function () { const player = await client.player.uuid(""); it("should transform Pit inventory without throwing", async function () { await transformItemData( - player.stats.Pit?.profile.inv_armor.data as number[] + player.stats?.Pit?.profile.inv_armor.data as number[] ); }); it("should throw as invalid data is being given", async function () {