Skip to content

Commit 37129e0

Browse files
committed
feat(hypixel-api): create hypixel api client
1 parent afed076 commit 37129e0

8 files changed

Lines changed: 371 additions & 0 deletions

File tree

.vscode/launch.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@
4848
"cwd": "${workspaceFolder}",
4949
"runtimeArgs": ["verify-server", "start"],
5050
"outputCapture": "std"
51+
},
52+
{
53+
"type": "node",
54+
"request": "launch",
55+
"name": "Prod API",
56+
"runtimeExecutable": "yarn",
57+
"cwd": "${workspaceFolder}",
58+
"runtimeArgs": ["api", "prod-start"],
59+
"outputCapture": "std"
5160
}
5261
]
5362
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "@statsify/hypixel-api-client",
3+
"version": "0.0.0",
4+
"main": "dist/index.js",
5+
"types": "src/index.ts",
6+
"scripts": {
7+
"build": "swc src --config-file ../../.swcrc --out-dir dist",
8+
"test:types": "tsc --noEmit",
9+
"lint": "TIMING=1 eslint './{src,tests}/**/*.{ts,tsx,js,jsx}' --fix"
10+
},
11+
"dependencies": {
12+
"@statsify/util": "workspace:^",
13+
"axios": "^0.27.2"
14+
}
15+
}
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/**
2+
* Copyright (c) Statsify
3+
*
4+
* This source code is licensed under the GNU GPL v3 license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
* https://github.com/Statsify/statsify/blob/main/LICENSE
7+
*/
8+
9+
import Axios, { AxiosError, AxiosInstance } from "axios";
10+
import { HypixelPlayer } from "./types";
11+
import { setTimeout } from "node:timers/promises";
12+
13+
export class HypixelKeyRejectedError extends Error {
14+
public constructor(message: string) {
15+
super(message);
16+
this.name = "EHYAPIKEY";
17+
}
18+
}
19+
20+
export class HypixelAPIError extends Error {
21+
public constructor(message: string) {
22+
super(message);
23+
this.name = "EHYAPI";
24+
}
25+
}
26+
27+
export type HypixelAPIConfig = {
28+
key: string;
29+
autoSleep: boolean;
30+
};
31+
32+
export class HypixelAPI {
33+
public limit: number;
34+
public remaining: number;
35+
36+
private axios: AxiosInstance;
37+
private config: HypixelAPIConfig;
38+
39+
public constructor(config: HypixelAPIConfig) {
40+
this.axios = Axios.create({
41+
baseURL: "https://api.hypixel.net/",
42+
headers: { "API-KEY": config.key },
43+
});
44+
this.config = config;
45+
}
46+
47+
public player(uuid: string): Promise<HypixelPlayer | undefined> {
48+
return this.get<HypixelPlayer>("player", { uuid });
49+
}
50+
51+
public friends(uuid: string) {
52+
return this.get("friends", { uuid });
53+
}
54+
55+
public recentgames(uuid: string) {
56+
return this.get("recentgames", { uuid });
57+
}
58+
59+
public status(uuid: string) {
60+
return this.get("status", { uuid });
61+
}
62+
63+
public guild(params: { id?: string; player?: string; name?: string }) {
64+
return this.get("guild", params);
65+
}
66+
67+
public boosters() {
68+
return this.get("boosters");
69+
}
70+
71+
public counts() {
72+
return this.get("counts");
73+
}
74+
75+
public leaderboards() {
76+
return this.get("leaderboards");
77+
}
78+
79+
public punishmentstats() {
80+
return this.get("punishmentstats");
81+
}
82+
83+
public skyblockNews() {
84+
return this.get("skyblock/news");
85+
}
86+
87+
public skyblockAuction(params: { uuid?: string; player?: string; profile?: string }) {
88+
return this.get("skyblock/auction", params);
89+
}
90+
91+
public skyblockAuctions(page: number) {
92+
return this.get("skyblock/auctions", { page: `${page}` });
93+
}
94+
95+
public skyblockAuctionsEnded() {
96+
return this.get("skyblock/auctions_ended");
97+
}
98+
99+
public skyblockBazaar() {
100+
return this.get("skyblock/bazaar");
101+
}
102+
103+
public skyblockProfile(profile: string) {
104+
return this.get("skyblock/profile", { profile });
105+
}
106+
107+
public skyblockProfiles(uuid: string) {
108+
return this.get("skyblock/profiles", { uuid });
109+
}
110+
111+
public skyblockBingo(uuid: string) {
112+
return this.get("skyblock/bingo", { uuid });
113+
}
114+
115+
public skyblockFiresales() {
116+
return this.get("skyblock/firesales");
117+
}
118+
119+
public async getResource(
120+
resource:
121+
| "games"
122+
| "achievements"
123+
| "challenges"
124+
| "quests"
125+
| "guilds/achievements"
126+
| "vanity/pets"
127+
| "vanity/companions"
128+
| "skyblock/collections"
129+
| "skyblock/skills"
130+
| "skyblock/items"
131+
| "skyblock/election"
132+
| "skyblock/bingo"
133+
) {
134+
const response = await Axios.get(resource, {
135+
baseURL: "https://api.hypixel.net/resources/",
136+
});
137+
return response.data;
138+
}
139+
140+
private async get<T>(
141+
endpoint: string,
142+
params?: Record<string, string | undefined>
143+
): Promise<T | undefined> {
144+
try {
145+
const response = await this.axios.get(endpoint, { params });
146+
147+
this.limit = Number(response.headers["rateLimit-limit"]);
148+
this.remaining = Number(response.headers["rateLimit-remaining"]);
149+
150+
return response.data;
151+
} catch (error: any) {
152+
switch (error.code) {
153+
case 429: {
154+
if (this.config.autoSleep) {
155+
await setTimeout(
156+
Number((error as AxiosError)?.response?.headers?.["retry-after"] ?? 60) *
157+
1000
158+
);
159+
return await this.get(endpoint, params);
160+
} else {
161+
throw error;
162+
}
163+
}
164+
165+
case 403: {
166+
throw new HypixelKeyRejectedError(
167+
`Hypixel API key "${this.config.key}" was rejected!`
168+
);
169+
}
170+
171+
case 500: {
172+
throw new HypixelAPIError(
173+
"The Hypixel API has encountered an error with our request!"
174+
);
175+
}
176+
177+
default: {
178+
throw error;
179+
}
180+
}
181+
}
182+
}
183+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* Copyright (c) Statsify
3+
*
4+
* This source code is licensed under the GNU GPL v3 license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
* https://github.com/Statsify/statsify/blob/main/LICENSE
7+
*/
8+
9+
export declare class BaseHypixelResponse {
10+
public success: boolean;
11+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* Copyright (c) Statsify
3+
*
4+
* This source code is licensed under the GNU GPL v3 license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
* https://github.com/Statsify/statsify/blob/main/LICENSE
7+
*/
8+
9+
export * from "./base-hypixel-response";
10+
export * from "./player";
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/**
2+
* Copyright (c) Statsify
3+
*
4+
* This source code is licensed under the GNU GPL v3 license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
* https://github.com/Statsify/statsify/blob/main/LICENSE
7+
*/
8+
9+
import { BaseHypixelResponse } from "./base-hypixel-response";
10+
import { HypixelNormalRanks } from "./ranks";
11+
12+
declare class HypixelPlayerStats {
13+
public SkyWars?: { [key: string]: any };
14+
public HungerGames?: { [key: string]: any };
15+
public Walls?: { [key: string]: any };
16+
public BattleGround?: { [key: string]: any };
17+
public UHC?: { [key: string]: any };
18+
public Walls3?: { [key: string]: any };
19+
public Arcade?: { [key: string]: any };
20+
public Quake?: { [key: string]: any };
21+
public SpeedUHC?: { [key: string]: any };
22+
public TNTGames?: { [key: string]: any };
23+
public Arena?: { [key: string]: any };
24+
public Paintball?: { [key: string]: any };
25+
public MCGO?: { [key: string]: any };
26+
public VampireZ?: { [key: string]: any };
27+
public GingerBread?: { [key: string]: any };
28+
public SuperSmash?: { [key: string]: any };
29+
public TrueCombat?: { [key: string]: any };
30+
public SkyClash?: { [key: string]: any };
31+
public Bedwars?: { [key: string]: any };
32+
public Duels?: { [key: string]: any };
33+
public MurderMystery?: { [key: string]: any };
34+
public BuildBattle?: { [key: string]: any };
35+
public Legacy?: { [key: string]: any };
36+
public Pit?: { [key: string]: any };
37+
public Housing?: { [key: string]: any };
38+
public WoolGames?: { [key: string]: any };
39+
}
40+
41+
export declare class HypixelPlayerChallenges {
42+
[key: string]: number;
43+
}
44+
45+
export declare class HypixelPlayerQuest {
46+
public completions?: { time: number }[];
47+
public active?: {
48+
started?: number;
49+
objectives?: { [key: string]: number };
50+
};
51+
}
52+
53+
export declare class HypixelPlayer extends BaseHypixelResponse {
54+
[key: string]: any;
55+
56+
/**
57+
* The mongo ID of the player in hypixel
58+
*/
59+
public _id?: string;
60+
61+
/**
62+
* The players UUID
63+
*/
64+
public uuid?: string;
65+
66+
/**
67+
* The timestamp of the players first login to hypixel
68+
*/
69+
public firstLogin?: number;
70+
71+
/**
72+
* The name of the player all lowercase
73+
*/
74+
public playername?: string;
75+
76+
/**
77+
* The name of the player
78+
*/
79+
public displayname?: string;
80+
81+
/**
82+
* Known previous names of the player
83+
*/
84+
public knownAliases?: string[];
85+
86+
/**
87+
* Known previous names of the player all lowercased
88+
*/
89+
public knownAliasesLower?: string[];
90+
91+
public achievementsOneTime?: string[];
92+
public networkExp?: number;
93+
public karma?: number;
94+
public stats?: HypixelPlayerStats;
95+
public achievements?: Record<string, number>;
96+
public newPackageRank?: HypixelNormalRanks;
97+
public totalRewards?: number;
98+
public totalDailyRewards?: number;
99+
public rewardStreak?: number;
100+
public rewardScore?: number;
101+
public rewardHighScore?: number;
102+
public achievementPoints?: number;
103+
public challenges?: {
104+
[key: string]: Record<string, HypixelPlayerChallenges>;
105+
all_time?: Record<string, HypixelPlayerChallenges>;
106+
};
107+
public quests?: Record<string, HypixelPlayerQuest>;
108+
public parkourCheckpointBests?: { [key: string]: number[] };
109+
public parkourCompletions?: {
110+
[key: string]: { timeStart?: number; timeTook?: number }[];
111+
};
112+
public rankPlusColor?: string;
113+
public monthlyPackageRank?: "NONE" | "SUPERSTAR";
114+
public monthlyRankColor?: "GOLD" | "AQUA";
115+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* Copyright (c) Statsify
3+
*
4+
* This source code is licensed under the GNU GPL v3 license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
* https://github.com/Statsify/statsify/blob/main/LICENSE
7+
*/
8+
9+
export enum HypixelNormalRanks {
10+
"NONE",
11+
"NORMAL",
12+
"VIP",
13+
"VIP_PLUS",
14+
"MVP",
15+
"MVP_PLUS",
16+
}
17+
18+
export enum HypixelSpecialRanks {
19+
"YOUTUBER",
20+
"ADMIN",
21+
"GAME_MASTER",
22+
}
23+
24+
export type HypixelRanks = HypixelNormalRanks | HypixelSpecialRanks;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"extends": "../../tsconfig.base.json",
3+
"include": ["src"]
4+
}

0 commit comments

Comments
 (0)