hypixel-api-reborn 11.1.0 → 11.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/.prettierrc +3 -3
  2. package/README.md +6 -4
  3. package/eslint.config.mjs +71 -0
  4. package/package.json +21 -25
  5. package/src/API/getAchievements.js +7 -0
  6. package/src/API/getBoosters.js +1 -0
  7. package/src/API/getChallenges.js +7 -0
  8. package/src/API/getGameCounts.js +1 -0
  9. package/src/API/getGuild.js +5 -4
  10. package/src/API/getGuildAchievements.js +7 -0
  11. package/src/API/getLeaderboards.js +4 -2
  12. package/src/API/getPlayer.js +2 -1
  13. package/src/API/getQuests.js +7 -0
  14. package/src/API/getRecentGames.js +6 -10
  15. package/src/API/getServerInfo.js +42 -37
  16. package/src/API/getStatus.js +2 -1
  17. package/src/API/getWatchdogStats.js +1 -0
  18. package/src/API/index.js +28 -17
  19. package/src/API/skyblock/getAuction.js +21 -0
  20. package/src/API/skyblock/{getSkyblockAuctions.js → getAuctions.js} +19 -12
  21. package/src/API/skyblock/{getSkyblockAuctionsByPlayer.js → getAuctionsByPlayer.js} +2 -2
  22. package/src/API/skyblock/{getSkyblockBazaar.js → getBazaar.js} +1 -3
  23. package/src/API/skyblock/getBingo.js +7 -0
  24. package/src/API/skyblock/getBingoByPlayer.js +14 -0
  25. package/src/API/skyblock/{getEndedSkyblockAuctions.js → getEndedAuctions.js} +1 -0
  26. package/src/API/skyblock/getFireSales.js +7 -0
  27. package/src/API/skyblock/getGovernment.js +7 -0
  28. package/src/API/skyblock/{getSkyblockMember.js → getMember.js} +10 -3
  29. package/src/API/skyblock/getMuseum.js +15 -0
  30. package/src/API/skyblock/{getSkyblockNews.js → getNews.js} +1 -0
  31. package/src/API/skyblock/{getSkyblockProfiles.js → getProfiles.js} +14 -7
  32. package/src/Client.js +127 -25
  33. package/src/Errors.js +38 -17
  34. package/src/Private/rateLimit.js +17 -13
  35. package/src/Private/requests.js +27 -16
  36. package/src/Private/updater.js +11 -8
  37. package/src/Private/uuidCache.js +23 -30
  38. package/src/Private/validate.js +33 -22
  39. package/src/index.js +9 -0
  40. package/src/structures/APIIncident.js +4 -11
  41. package/src/structures/APIStatus.js +0 -1
  42. package/src/structures/Boosters/Booster.js +14 -13
  43. package/src/structures/Color.js +93 -48
  44. package/src/structures/Game.js +4 -2
  45. package/src/structures/Guild/Guild.js +35 -48
  46. package/src/structures/Guild/GuildMember.js +8 -8
  47. package/src/structures/Guild/GuildRank.js +2 -2
  48. package/src/structures/MiniGames/Arcade.js +242 -235
  49. package/src/structures/MiniGames/ArenaBrawl.js +11 -11
  50. package/src/structures/MiniGames/BedWars.js +262 -131
  51. package/src/structures/MiniGames/BlitzSurvivalGames.js +24 -23
  52. package/src/structures/MiniGames/CopsAndCrims.js +1 -0
  53. package/src/structures/MiniGames/Duels.js +92 -33
  54. package/src/structures/MiniGames/MegaWalls.js +3 -1
  55. package/src/structures/MiniGames/MurderMystery.js +2 -2
  56. package/src/structures/MiniGames/Pit.js +230 -2
  57. package/src/structures/MiniGames/PitInventoryItem.js +43 -0
  58. package/src/structures/MiniGames/SkyWars.js +211 -195
  59. package/src/structures/MiniGames/SmashHeroes.js +37 -35
  60. package/src/structures/MiniGames/SpeedUHC.js +17 -4
  61. package/src/structures/MiniGames/TNTGames.js +1 -1
  62. package/src/structures/MiniGames/UHC.js +33 -14
  63. package/src/structures/MiniGames/WoolWars.js +6 -5
  64. package/src/structures/Pet.js +1 -1
  65. package/src/structures/Player.js +26 -121
  66. package/src/structures/PlayerCosmetics.js +67 -12
  67. package/src/structures/ServerInfo.js +1 -1
  68. package/src/structures/SkyBlock/Auctions/Auction.js +3 -1
  69. package/src/structures/SkyBlock/Auctions/AuctionInfo.js +3 -1
  70. package/src/structures/SkyBlock/Auctions/BaseAuction.js +2 -1
  71. package/src/structures/SkyBlock/Auctions/Bid.js +1 -0
  72. package/src/structures/SkyBlock/Auctions/PartialAuction.js +1 -0
  73. package/src/structures/SkyBlock/News/SkyblockNews.js +15 -15
  74. package/src/structures/SkyBlock/PlayerBingo.js +49 -0
  75. package/src/structures/SkyBlock/SkyblockInventoryItem.js +76 -32
  76. package/src/structures/SkyBlock/SkyblockMember.js +252 -289
  77. package/src/structures/SkyBlock/SkyblockMuseum.js +60 -0
  78. package/src/structures/SkyBlock/SkyblockMuseumItem.js +54 -0
  79. package/src/structures/SkyBlock/SkyblockPet.js +3 -3
  80. package/src/structures/SkyBlock/SkyblockProfile.js +37 -23
  81. package/src/structures/SkyBlock/Static/Bingo.js +101 -0
  82. package/src/structures/SkyBlock/Static/BingoData.js +45 -0
  83. package/src/structures/SkyBlock/Static/Candidate.js +40 -0
  84. package/src/structures/SkyBlock/Static/FireSale.js +55 -0
  85. package/src/structures/SkyBlock/Static/Government.js +74 -0
  86. package/src/structures/SkyBlock/Static/Perk.js +24 -0
  87. package/src/structures/Static/Achievement.js +87 -0
  88. package/src/structures/Static/AchievementTier.js +33 -0
  89. package/src/structures/Static/Achievements.js +30 -0
  90. package/src/structures/Static/Challenges.js +29 -0
  91. package/src/structures/Static/GameAchievements.js +36 -0
  92. package/src/structures/Static/GameChallenges.js +40 -0
  93. package/src/structures/Static/GameQuests.js +24 -0
  94. package/src/structures/Static/GuildAchievements.js +34 -0
  95. package/src/structures/Static/Quest.js +66 -0
  96. package/src/structures/Static/Quests.js +31 -0
  97. package/src/structures/Status.js +2 -2
  98. package/src/utils/Constants.js +384 -543
  99. package/src/utils/{guildExp.js → Guild.js} +46 -13
  100. package/src/utils/Player.js +112 -0
  101. package/src/utils/SkyblockUtils.js +448 -186
  102. package/src/utils/arrayTools.js +1 -1
  103. package/src/utils/divide.js +1 -1
  104. package/src/utils/index.js +2 -1
  105. package/src/utils/isGuildID.js +1 -1
  106. package/src/utils/oscillation.js +4 -2
  107. package/src/utils/removeSnakeCase.js +19 -8
  108. package/src/utils/rgbToHexColor.js +1 -1
  109. package/src/utils/romanize.js +35 -4
  110. package/src/utils/toUuid.js +12 -7
  111. package/src/utils/varInt.js +2 -2
  112. package/typings/index.d.ts +1246 -446
  113. package/src/utils/toIGN.js +0 -20
@@ -0,0 +1,7 @@
1
+ module.exports = async function () {
2
+ const GovernmentData = require('../../structures/SkyBlock/Static/Government.js');
3
+ // eslint-disable-next-line no-underscore-dangle
4
+ const res = await this._makeRequest('/resources/skyblock/election');
5
+ if (res.raw) return res;
6
+ return new GovernmentData(res);
7
+ };
@@ -1,10 +1,12 @@
1
1
  const Errors = require('../../Errors');
2
2
  const toUuid = require('../../utils/toUuid');
3
3
  const getPlayer = require('../getPlayer');
4
- module.exports = async function (query, options = { fetchPlayer: false }) {
4
+ module.exports = async function (query, options = { fetchPlayer: false, getMuseum: false }) {
5
5
  const SkyblockMember = require('../../structures/SkyBlock/SkyblockMember');
6
+ const getSkyblockMuseum = require('../skyblock/getMuseum');
6
7
  if (!query) throw new Error(Errors.NO_NICKNAME_UUID);
7
- query = await toUuid(query);
8
+ query = await toUuid(query, this.options.mojangCacheTime, this.options.useThirdPartyAPI);
9
+ // eslint-disable-next-line no-underscore-dangle
8
10
  const res = await this._makeRequest(`/skyblock/profiles?uuid=${query}`);
9
11
  if (res.raw) return res;
10
12
  if (!res.profiles || !res.profiles.length) throw new Error(Errors.NO_SKYBLOCK_PROFILES);
@@ -16,9 +18,14 @@ module.exports = async function (query, options = { fetchPlayer: false }) {
16
18
  profile.cute_name,
17
19
  new SkyblockMember({
18
20
  uuid: query,
21
+ profileId: profile.profile_id,
19
22
  profileName: profile.cute_name,
20
23
  gameMode: profile.game_mode || null,
21
- m: profile.members[query]
24
+ m: profile.members[query],
25
+ banking: profile.banking,
26
+ communityUpgrades: profile.community_upgrades,
27
+ museum: options.getMuseum ? await getSkyblockMuseum.call(this, query, profile.profile_id) : null,
28
+ selected: profile.selected
22
29
  })
23
30
  );
24
31
  }
@@ -0,0 +1,15 @@
1
+ const Errors = require('../../Errors');
2
+ const toUuid = require('../../utils/toUuid');
3
+ module.exports = async function (query, profileId) {
4
+ const SkyblockMuseum = require('../../structures/SkyBlock/SkyblockMuseum');
5
+ if (!query) throw new Error(Errors.NO_NICKNAME_UUID);
6
+ query = await toUuid(query, this.options.mojangCacheTime, this.options.useThirdPartyAPI);
7
+ // eslint-disable-next-line no-underscore-dangle
8
+ const res = await this._makeRequest(`/skyblock/museum?uuid=${query}&profile=${profileId}`);
9
+ if (res.raw) return res;
10
+ return new SkyblockMuseum({
11
+ uuid: query,
12
+ m: res,
13
+ profileId: profileId
14
+ });
15
+ };
@@ -1,5 +1,6 @@
1
1
  const SkyblockNews = require('../../structures/SkyBlock/News/SkyblockNews');
2
2
  module.exports = async function () {
3
+ // eslint-disable-next-line no-underscore-dangle
3
4
  const res = await this._makeRequest('/skyblock/news');
4
5
  if (res.raw) return res;
5
6
  return res.items.map((i) => new SkyblockNews(i));
@@ -1,10 +1,12 @@
1
1
  const Errors = require('../../Errors');
2
2
  const toUuid = require('../../utils/toUuid');
3
3
  const getPlayer = require('../getPlayer');
4
- module.exports = async function (query, options = { fetchPlayer: false }) {
4
+ module.exports = async function (query, options = { fetchPlayer: false, getMuseum: false }) {
5
5
  const SkyblockProfile = require('../../structures/SkyBlock/SkyblockProfile');
6
+ const getSkyblockMuseum = require('../skyblock/getMuseum');
6
7
  if (!query) throw new Error(Errors.NO_NICKNAME_UUID);
7
- query = await toUuid(query);
8
+ query = await toUuid(query, this.options.mojangCacheTime, this.options.useThirdPartyAPI);
9
+ // eslint-disable-next-line no-underscore-dangle
8
10
  const res = await this._makeRequest(`/skyblock/profiles?uuid=${query}`);
9
11
  if (res.raw) return res;
10
12
  if (!res.profiles || !res.profiles.length) throw new Error(Errors.NO_SKYBLOCK_PROFILES);
@@ -28,11 +30,16 @@ module.exports = async function (query, options = { fetchPlayer: false }) {
28
30
  }
29
31
 
30
32
  profiles.push({
31
- profile_id: res.profiles[i].profile_id,
32
- profile_name: res.profiles[i].cute_name,
33
- members: res.profiles[i].members,
34
- me: query,
35
- selected: res.profiles[i].selected
33
+ uuid: query,
34
+ profileId: res.profiles[i].profile_id,
35
+ profileName: res.profiles[i].cute_name,
36
+ gameMode: res.profiles[i].game_mode || null,
37
+ m: res.profiles[i].members[query],
38
+ banking: res.profiles[i].banking,
39
+ communityUpgrades: res.profiles[i].community_upgrades,
40
+ museum: options.getMuseum ? await getSkyblockMuseum.call(this, query, res.profiles[i].profile_id) : null,
41
+ selected: res.profiles[i].selected,
42
+ members: res.profiles[i].members
36
43
  });
37
44
  }
38
45
 
package/src/Client.js CHANGED
@@ -1,19 +1,43 @@
1
- /* eslint-disable require-jsdoc */
2
- /* eslint-disable max-len */
3
- const validate = new (require('./Private/validate'))();
4
1
  const rateLimit = new (require('./Private/rateLimit'))();
5
- const Requests = require('./Private/requests');
2
+ const validate = new (require('./Private/validate'))();
6
3
  const updater = new (require('./Private/updater'))();
4
+ const Requests = require('./Private/requests');
5
+ const EventEmitter = require('events');
7
6
  const Errors = require('./Errors');
8
7
  const API = require('./API/index');
9
- const EventEmitter = require('events');
10
8
  const clients = [];
9
+
10
+ /* eslint-disable */
11
+ const Player = require('./structures/Player');
12
+ const Guild = require('./structures/Guild/Guild');
13
+ const WatchdogStats = require('./structures/Watchdog/Stats');
14
+ const Booster = require('./structures/Boosters/Booster');
15
+ const SkyblockProfile = require('./structures/SkyBlock/SkyblockProfile');
16
+ const SkyblockMember = require('./structures/SkyBlock/SkyblockMember');
17
+ const SkyblockMuseum = require('./structures/SkyBlock/SkyblockMuseum');
18
+ const APIStatus = require('./structures/APIStatus');
19
+ const Leaderboard = require('./structures/Leaderboard');
20
+ const ServerInfo = require('./structures/ServerInfo');
21
+ const RecentGame = require('./structures/RecentGame');
22
+ const Status = require('./structures/Status');
23
+ const Auction = require('./structures/SkyBlock/Auctions/Auction');
24
+ const AuctionInfo = require('./structures/SkyBlock/Auctions/AuctionInfo');
25
+ const PartialAuction = require('./structures/SkyBlock/Auctions/PartialAuction');
26
+ const Product = require('./structures/SkyBlock/Bazzar/Product');
27
+ const BingoData = require('./structures/SkyBlock/Static/BingoData');
28
+ const PlayerBingo = require('./structures/SkyBlock/PlayerBingo');
29
+ const GovernmentData = require('./structures/SkyBlock/Static/Government');
30
+ const FireSale = require('./structures/SkyBlock/Static/FireSale');
31
+ const SkyblockNews = require('./structures/SkyBlock/News/SkyblockNews');
32
+ const GameCounts = require('./structures/GameCounts');
33
+ /* eslint-enable */
34
+
11
35
  /**
12
36
  * Client class
13
37
  */
14
38
  class Client extends EventEmitter {
15
39
  /**
16
- * @param {string} key API key [(?)](https://stavzdev.is-inside.me/cCMiZdoy.gif)
40
+ * @param {string} key API key
17
41
  * @param {ClientOptions} [options={}] Client options
18
42
  */
19
43
  constructor(key, options = {}) {
@@ -30,13 +54,14 @@ class Client extends EventEmitter {
30
54
  this.key = validate.validateKey(key);
31
55
  this.options = validate.parseOptions(options);
32
56
  validate.validateOptions(this.options);
33
- // eslint-disable-next-line guard-for-in
57
+
34
58
  for (const func in API) {
35
- Client.prototype[func] = function (...args) {
59
+ Client.prototype[func] = (...args) => {
36
60
  const lastArg = args[args.length - 1];
37
61
  return API[func].apply(
38
62
  {
39
- _makeRequest: this._makeRequest.bind(this, { ...(validate.cacheSuboptions(lastArg) ? lastArg : {}) }),
63
+ // eslint-disable-next-line no-underscore-dangle
64
+ _makeRequest: this._makeRequest.bind(this, validate.cacheSuboptions(lastArg) ? lastArg : {}),
40
65
  ...this
41
66
  },
42
67
  args
@@ -45,7 +70,10 @@ class Client extends EventEmitter {
45
70
  }
46
71
 
47
72
  if (this.options.checkForUpdates) {
48
- updater.checkForUpdates();
73
+ updater.checkForUpdates().catch(() => {
74
+ // eslint-disable-next-line no-console
75
+ if (!this.options.silent) console.warn('[hypixel-api-reborn] Error whilst checking for updates!');
76
+ });
49
77
  }
50
78
  /**
51
79
  * All cache entries
@@ -53,7 +81,7 @@ class Client extends EventEmitter {
53
81
  */
54
82
  this.cache = this.requests.cache;
55
83
  clients.push(this);
56
- rateLimit.init(this.getPlayer('52d9a36f66ce4cdf9a56ad9724ae9fb4'), this.options, this).then(() => this.emit('ready'));
84
+ rateLimit.init(this.getGameCounts(), this.options, this).then(() => this.emit('ready'));
57
85
  }
58
86
  /**
59
87
  * Private function - make request
@@ -65,16 +93,22 @@ class Client extends EventEmitter {
65
93
  */
66
94
  async _makeRequest(options, url, useRateLimitManager = true) {
67
95
  if (!url) return;
68
- if (url !== '/key' && !options.noCacheCheck && (await this.requests.cache.has(url))) return Object.assign(await this.requests.cache.get(url), { raw: !!options.raw });
96
+ if ('/key' !== url && !options.noCacheCheck && (await this.requests.cache.has(url))) {
97
+ return Object.assign(await this.requests.cache.get(url), { raw: Boolean(options.raw) });
98
+ }
69
99
  if (useRateLimitManager) await rateLimit.rateLimitManager();
70
100
  this.emit('outgoingRequest', url, { ...options, headers: { ...options.headers, ...this.options.headers } });
71
- const result = await this.requests.request.call(this.requests, url, { ...options, headers: { ...options.headers, ...this.options.headers } });
101
+ const result = await this.requests.request.call(this.requests, url, {
102
+ ...options,
103
+ headers: { ...options.headers, ...this.options.headers }
104
+ });
105
+ // eslint-disable-next-line no-underscore-dangle
72
106
  if (this.options.syncWithHeaders) rateLimit.sync(result._headers);
73
107
  return result;
74
108
  }
75
109
  /**
76
110
  * Emitted when rate limiter is ready. ( You don't have to wait for this event to emit UNLESS you are planning to do data scraping which means spamming requests )
77
- * @event
111
+ * @event ready
78
112
  * @name Client#ready
79
113
  * @example
80
114
  * // This example gets player's uuid.
@@ -86,14 +120,14 @@ class Client extends EventEmitter {
86
120
  */
87
121
  /**
88
122
  * Emitted when a request is going to be sent
89
- * @event
123
+ * @event outgoingRequest
90
124
  * @name Client#outgoingRequest
91
125
  * @param {string} url URL
92
126
  * @param {object} [options] Options, if any
93
127
  */
94
128
  /**
95
129
  * Emitted when there is a warning.
96
- * @event
130
+ * @event warn
97
131
  * @name Client#warn
98
132
  * @param {string} error Warning Message
99
133
  */
@@ -132,7 +166,7 @@ class Client extends EventEmitter {
132
166
  * Allows you to get statistics of hypixel guild
133
167
  * @method
134
168
  * @name Client#getGuild
135
- * @param {id|name|player} searchParameter Search for guild by id, name or player (if player is in guild)
169
+ * @param {'id'|'name'|'player'} searchParameter Search for guild by id, name or player (if player is in guild)
136
170
  * @param {string} query Guild ID, Guild name or player uuid/nickname
137
171
  * @param {MethodOptions} [options={}] Method options
138
172
  * @return {Promise<Guild>}
@@ -143,6 +177,11 @@ class Client extends EventEmitter {
143
177
  * }).catch(e => {
144
178
  * console.log(e);
145
179
  * })
180
+ * @example
181
+ * // async/await
182
+ * const guild = await hypixel.getGuild('name', 'The Foundation').catch(console.log);
183
+ * console.log(guild.level); // 111
184
+ * console.log(guild.id); // '52e5719284ae51ed0c716c69'
146
185
  */
147
186
  /**
148
187
  * Allows you to get statistics of watchdog, the server anticheat
@@ -156,6 +195,10 @@ class Client extends EventEmitter {
156
195
  * }).catch(e => {
157
196
  * console.log(e);
158
197
  * })
198
+ * @example
199
+ * // async/await
200
+ * const watchdog = await hypixel.getWatchdogStats().catch(console.log);
201
+ * console.log(watchdog.byWatchdogTotal); // 5931897
159
202
  */
160
203
  /**
161
204
  * Allows you to get all active boosters
@@ -169,6 +212,10 @@ class Client extends EventEmitter {
169
212
  * }).catch(e => {
170
213
  * console.log(e);
171
214
  * })
215
+ * @example
216
+ * // async/await
217
+ * const boosters = await hypixel.getBoosters().catch(console.log);
218
+ * console.log(boosters[0].purchaser); // '978ddb705a8e43618e41749178c020b0'
172
219
  */
173
220
  /**
174
221
  * Allows you to get all skyblock profiles of player
@@ -183,13 +230,16 @@ class Client extends EventEmitter {
183
230
  * }).catch(e => {
184
231
  * console.log(e);
185
232
  * })
233
+ * @example
234
+ * const profiles = await hypixel.getSkyblockProfiles('StavZDev').catch(console.log);
235
+ * console.log(profiles[0].members[0].uuid); // '52d9a36f66ce4cdf9a56ad9724ae9fb4'
186
236
  */
187
237
  /**
188
238
  * Allows you to get a player's skyblock member data from all their profiles
189
239
  * @method
190
240
  * @name Client#getSkyblockMember
191
241
  * @param {string} query Player nickname or UUID
192
- * @param {MethodOptions} [options={}] Method options
242
+ * @param {SkyblockMethodOptions} [options={}] Method options
193
243
  * @return {Promise<Map<string,SkyblockMember>>}
194
244
  * @example
195
245
  * hypixel.getSkyblockMember('StavZDev').then(member => {
@@ -198,6 +248,17 @@ class Client extends EventEmitter {
198
248
  * }).catch(e => {
199
249
  * console.log(e);
200
250
  * })
251
+ * @example
252
+ * const member = await hypixel.getSkyblockMember('StavZDev').catch(console.log);
253
+ * console.log(member.get('Cucumber').uuid); // '52d9a36f66ce4cdf9a56ad9724ae9fb4'
254
+ */
255
+ /**
256
+ * Allows you to get a player's skyblock profile museum
257
+ * @method
258
+ * @name Client#getSkyblockMuseum
259
+ * @param {string} query Player nickname or UUID
260
+ * @param {string} profileId Profile ID
261
+ * @return {Promise<SkyblockMuseum>}
201
262
  */
202
263
  /**
203
264
  * Allows you to get the Hypixel API's Status and past Incidents, no key needed.
@@ -313,6 +374,35 @@ class Client extends EventEmitter {
313
374
  * })
314
375
  * .catch(console.log);
315
376
  */
377
+ /**
378
+ * Allows you to get bingo data
379
+ * @method
380
+ * @name Client#getSkyblockBingo
381
+ * @param {MethodOptions} [options={}] Options
382
+ * @return {Promise<BingoData>}
383
+ */
384
+ /**
385
+ * Allows you to get bingo data of a player
386
+ * @method
387
+ * @name Client#getSkyblockBingoByPlayer
388
+ * @param {string} query UUID / IGN of player
389
+ * @param {PlayerBingoOptions} [options={}] Options
390
+ * @return {Promise<PlayerBingo>}
391
+ */
392
+ /**
393
+ * Allows you to get SB government
394
+ * @method
395
+ * @name Client#getSkyblockGovernment
396
+ * @param {MethodOptions} [options={}] Options
397
+ * @return {Promise<GovernmentData>}
398
+ */
399
+ /**
400
+ * Allows you to get SB government
401
+ * @method
402
+ * @name Client#getSkyblockFireSale
403
+ * @param {MethodOptions} [options={}] Options
404
+ * @return {Promise<FireSale[]>}
405
+ */
316
406
  /**
317
407
  * Allows you to get skyblock news
318
408
  * @method
@@ -348,17 +438,20 @@ class Client extends EventEmitter {
348
438
  }
349
439
  /**
350
440
  * @typedef {object} ClientOptions
351
- * @prop {boolean} [cache=false] Enable/Disable request caching.
352
- * @prop {number} [cacheTime=60] Amount of time in seconds to cache the requests.
441
+ * @prop {boolean} [cache=true] Enable/Disable request caching.
442
+ * @prop {number} [hypixelCacheTime=60] Amount of time in seconds to cache the hypixel api requests.
443
+ * @prop {number} [mojangCacheTime=600] Amount of time in seconds to cache the mojang api requests.
353
444
  * @prop {CacheHandler} [cacheHandler] Custom Cache Handler
354
- * @prop {AUTO|HARD|NONE} [rateLimit='AUTO'] Rate limit mode.
445
+ * @prop {'AUTO'|'HARD'|'NONE'} [rateLimit='AUTO'] Rate limit mode.
355
446
  * @prop {boolean} [syncWithHeaders=false] Sync with headers rate limit information. Usually not necessary nor recommended ( because of latency )
356
- * @prop {number} [keyLimit=120] Key limit of your key.
447
+ * @prop {number} [keyLimit=60] Key limit of your key.
357
448
  * @prop {number} [cacheSize=-1] The amount how many results will be cached. (`-1` for infinity)
358
449
  * @prop {boolean} [silent=false] Don't automatically put warnings into console.
359
450
  * @prop {object} [headers={}] Extra Headers ( like User-Agent ) to add to request.
360
451
  * @prop {boolean} [checkForUpdates=true] Enable/Disable check for new version of hypixel-api-reborn.
452
+ * @prop {boolean|string} [useThirdPartyAPI=false] Enable/Disable Mojang Third Party API
361
453
  */
454
+ // eslint-disable-next-line no-unused-vars
362
455
  const defaultCache = require('./Private/defaultCache.js');
363
456
  /**
364
457
  * @typedef {defaultCache} Cache
@@ -384,9 +477,10 @@ const defaultCache = require('./Private/defaultCache.js');
384
477
  */
385
478
  /**
386
479
  * @typedef {object} SkyblockMethodOptions
387
- * @property {boolean} [raw=false] Raw data
388
- * @property {?boolean} [noCacheCheck=false] Disable/Enable cache checking
389
- * @property {?boolean} [noCaching=false] Disable/Enable writing to cache
480
+ * @property {boolean} [fetchPlayer=false] Raw data
481
+ * @property {boolean} [getMuseum=false] Raw data
482
+ * @property {boolean} [noCacheCheck=false] Disable/Enable cache checking
483
+ * @property {boolean} [noCaching=false] Disable/Enable writing to cache
390
484
  * @property {?boolean} [fetchPlayer=false] Disable/Enable player profile request for each member
391
485
  * @prop {object} [headers={}] Extra Headers ( like User-Agent ) to add to request. Overrides the headers globally provided.
392
486
  */
@@ -403,4 +497,12 @@ const defaultCache = require('./Private/defaultCache.js');
403
497
  * @property {boolean} [includeItemBytes=false] Whether to include item bytes in the result
404
498
  * @prop {object} [headers={}] Extra Headers ( like User-Agent ) to add to request. Overrides the headers globally provided.
405
499
  */
500
+ /**
501
+ * @typedef {object} PlayerBingoOptions
502
+ * @property {boolean} [raw=false] Raw data
503
+ * @property {boolean} [noCacheCheck=false] Disable/Enable cache checking
504
+ * @property {boolean} [noCaching=false] Disable/Enable writing to cache
505
+ * @property {boolean} [fetchBingoData=false] Fetches bingo data to give more information
506
+ * @prop {object} [headers={}] Extra Headers ( like User-Agent ) to add to request. Overrides the headers globally provided.
507
+ */
406
508
  module.exports = Client;
package/src/Errors.js CHANGED
@@ -2,44 +2,65 @@
2
2
  module.exports = {
3
3
  INVALID_API_KEY: '[hypixel-api-reborn] Invalid API Key! For help join our Discord Server https://discord.gg/NSEBNMM',
4
4
  NO_API_KEY: '[hypixel-api-reborn] No API Key specified! For help join our Discord Server https://discord.gg/NSEBNMM',
5
- ERROR_CODE_CAUSE: '[hypixel-api-reborn] Code: {code} - {cause}! For help join our Discord Server https://discord.gg/NSEBNMM',
5
+ ERROR_CODE_CAUSE:
6
+ '[hypixel-api-reborn] Code: {code} - {cause}! For help join our Discord Server https://discord.gg/NSEBNMM',
6
7
  ERROR_STATUSTEXT: '[hypixel-api-reborn] {statustext}! For help join our Discord Server https://discord.gg/NSEBNMM',
7
- KEY_MUST_BE_A_STRING: '[hypixel-api-reborn] Specified API Key must be a string! For help join our Discord Server https://discord.gg/NSEBNMM',
8
- OPTIONS_MUST_BE_AN_OBJECT: '[hypixel-api-reborn] Options must be an object! For help join our Discord Server https://discord.gg/NSEBNMM',
9
- CACHE_TIME_MUST_BE_A_NUMBER: '[hypixel-api-reborn] Cache Time must be a number! For help join our Discord Server https://discord.gg/NSEBNMM',
10
- CACHE_LIMIT_MUST_BE_A_NUMBER: '[hypixel-api-reborn] Cache Limit must be a number! For help join our Discord Server https://discord.gg/NSEBNMM',
11
- CACHE_FILTER_INVALID: '[hypixel-api-reborn] Cache Filter must be a function returning a boolean, an object, an array, or a string!',
8
+ KEY_MUST_BE_A_STRING:
9
+ '[hypixel-api-reborn] Specified API Key must be a string! For help join our Discord Server https://discord.gg/NSEBNMM',
10
+ OPTIONS_MUST_BE_AN_OBJECT:
11
+ '[hypixel-api-reborn] Options must be an object! For help join our Discord Server https://discord.gg/NSEBNMM',
12
+ CACHE_TIME_MUST_BE_A_NUMBER:
13
+ '[hypixel-api-reborn] Cache Time must be a number! For help join our Discord Server https://discord.gg/NSEBNMM',
14
+ CACHE_LIMIT_MUST_BE_A_NUMBER:
15
+ '[hypixel-api-reborn] Cache Limit must be a number! For help join our Discord Server https://discord.gg/NSEBNMM',
16
+ CACHE_FILTER_INVALID:
17
+ '[hypixel-api-reborn] Cache Filter must be a function returning a boolean, an object, an array, or a string!',
12
18
  NO_NICKNAME_UUID: '[hypixel-api-reborn] No nickname or uuid specified.',
13
19
  NO_UUID: '[hypixel-api-reborn] No uuid specified.',
14
20
  UUID_NICKNAME_MUST_BE_A_STRING: '[hypixel-api-reborn] Nickname or uuid must be a string.',
15
21
  MALFORMED_UUID: '[hypixel-api-reborn] Malformed UUID!',
16
22
  PLAYER_DOES_NOT_EXIST: '[hypixel-api-reborn] Player does not exist.',
17
23
  PLAYER_HAS_NEVER_LOGGED: '[hypixel-api-reborn] Player has never logged into Hypixel.',
18
- PLAYER_IS_INACTIVE: "[hypixel-api-reborn] No records of recent games because player hasn't been online for more than 3 days or is lacking data to determine the cause of an empty response",
24
+ PLAYER_IS_INACTIVE:
25
+ "[hypixel-api-reborn] No records of recent games because player hasn't been online for more than 3 days or is lacking data to determine the cause of an empty response",
19
26
  PLAYER_DISABLED_ENDPOINT: '[hypixel-api-reborn] Player has disabled this endpoint.',
20
27
  NO_GUILD_QUERY: '[hypixel-api-reborn] No guild search query specified.',
21
28
  INVALID_GUILD_ID: '[hypixel-api-reborn] Specified Guild ID is invalid.',
22
29
  INVALID_GUILD_SEARCH_PARAMETER: "[hypixel-api-reborn] getGuild() searchParameter must be 'id', 'guild' or 'player'.",
23
30
  SOMETHING_WENT_WRONG: '[hypixel-api-reborn] Something went wrong. {cause}',
24
31
  GUILD_DOES_NOT_EXIST: '[hypixel-api-reborn] Guild does not exist.',
25
- PAGE_INDEX_ERROR: '[hypixel-api-reborn] Invalid page index. Must be an integer, an array of 2 integers, or a keyword. For help join our Discord Server https://discord.gg/NSEBNMM',
26
- INVALID_OPTION_VALUE: '[hypixel-api-reborn] Invalid option value! For help join our Discord Server https://discord.gg/NSEBNMM',
27
- INVALID_RESPONSE_BODY: '[hypixel-api-reborn] An error occurred while converting to JSON. Perhaps this is due to an update or maintenance. For help join our Discord Server https://discord.gg/NSEBNMM',
28
- INVALID_RATE_LIMIT_OPTION: "[hypixel-api-reborn] Rate Limit provided in Client options must be 'HARD', 'AUTO', or 'NONE'. For help join our Discord Server https://discord.gg/NSEBNMM",
29
- INVALID_KEY_LIMIT_OPTION: '[hypixel-api-reborn] Key Limit provided in Client options must be an integer representing the amount of requests possible in one minute with your key.',
32
+ PAGE_INDEX_ERROR:
33
+ '[hypixel-api-reborn] Invalid page index. Must be an integer, an array of 2 integers, or a keyword. For help join our Discord Server https://discord.gg/NSEBNMM',
34
+ INVALID_OPTION_VALUE:
35
+ '[hypixel-api-reborn] Invalid option value! For help join our Discord Server https://discord.gg/NSEBNMM',
36
+ INVALID_RESPONSE_BODY:
37
+ '[hypixel-api-reborn] An error occurred while converting to JSON. Perhaps this is due to an update or maintenance. For help join our Discord Server https://discord.gg/NSEBNMM',
38
+ INVALID_RATE_LIMIT_OPTION:
39
+ "[hypixel-api-reborn] Rate Limit provided in Client options must be 'HARD', 'AUTO', or 'NONE'. For help join our Discord Server https://discord.gg/NSEBNMM",
40
+ INVALID_KEY_LIMIT_OPTION:
41
+ '[hypixel-api-reborn] Key Limit provided in Client options must be an integer representing the amount of requests possible in one minute with your key.',
30
42
  INVALID_HEADER_SYNC_OPTION: '[hypixel-api-reborn] Invalid Value for maxSyncHeaders : must be a boolean',
31
43
  INVALID_BURST_OPTION: '[hypixel-api-reborn] maxBurstRequests provided in Client options must be a number',
32
- NODE_VERSION_ERR: "[hypixel-api-reborn] You are using a version of Nodejs that doesn't support certain features we use. Please upgrade to version 14 or above.",
44
+ NODE_VERSION_ERR:
45
+ "[hypixel-api-reborn] You are using a version of Nodejs that doesn't support certain features we use. Please upgrade to version 14 or above.",
33
46
  UPDATER_REQUEST_NOT_OK: '[hypixel-api-reborn] An error occurred checking for updates.',
34
47
  CONNECTION_ERROR: '[hypixel-api-reborn] Failed to connect.',
35
- RATE_LIMIT_INIT_ERROR: '[hypixel-api-reborn] An error happened whilst initializing rate limit. We strongly recommend restarting the code as this can lead to desynchronization.',
48
+ RATE_LIMIT_INIT_ERROR:
49
+ '[hypixel-api-reborn] An error happened whilst initializing rate limit. We strongly recommend restarting the code as this can lead to desynchronization.',
36
50
  MULTIPLE_INSTANCES:
37
51
  '[hypixel-api-reborn] Multiple instances of hypixel-api-reborn are found so we merged them for you. Please refrain from spawning multiple instances in the future. For more information, join our Discord Server https://discord.gg/NSEBNMM.',
38
- INVALID_HEADERS: '[hypixel-api-reborn] Invalid Headers are provided in ClientOptions. For help join our Discord Server https://discord.gg/NSEBNMM',
39
- INVALID_CACHE_HANDLER: '[hypixel-api-reborn] An invalid cache handler is provideed. For help join our Discord Server https://discord.gg/NSEBNMM',
52
+ INVALID_HEADERS:
53
+ '[hypixel-api-reborn] Invalid Headers are provided in ClientOptions. For help join our Discord Server https://discord.gg/NSEBNMM',
54
+ INVALID_CACHE_HANDLER:
55
+ '[hypixel-api-reborn] An invalid cache handler is provideed. For help join our Discord Server https://discord.gg/NSEBNMM',
40
56
  UNEXPECTED_ERROR:
41
57
  "[hypixel-api-reborn] The data provided to hypixel API is malformed and thus not recognized by hypixel, but this shouldn't be your fault. Please report this error in our Discord Server https://discord.gg/NSEBNMM or GitHub. ",
42
58
  RATE_LIMIT_EXCEEDED:
43
59
  "[hypixel-api-reborn] The rate limitations on your API Key has been exceeded. There might be an outage (Check Hypixel's status page), or you simply did too many requests in a short time. Hint: Enable rate limit options! They can help you avoid this error! For help join our Discord Server https://discord.gg/NSEBNMM",
44
- NO_SKYBLOCK_PROFILES: '[hypixel-api-reborn] The player has no skyblock profiles.'
60
+ NO_SKYBLOCK_PROFILES: '[hypixel-api-reborn] The player has no skyblock profiles.',
61
+ INVALID_SILENT_OPTION: '[hypixel-api-reborn] Invalid Value for silent : must be a boolean',
62
+ INVALID_UPDATE_OPTION: '[hypixel-api-reborn] Invalid Value for update : must be a boolean',
63
+ INVALID_THIRD_PARTY_API_OPTION: '[hypixel-api-reborn] Invalid Third Party API option : must be a boolean or string',
64
+ BAD_AUCTION_FILTER:
65
+ '[hypixel-api-reborn] Unexpected filter for Client#getSkyblockAuction. Expected one of "PLAYER", "AUCTION", "PROFILE", but got something else.'
45
66
  };
@@ -1,8 +1,5 @@
1
- /* eslint-disable @typescript-eslint/no-empty-function */
2
- /* eslint-disable camelcase */
3
1
  const Errors = require('../Errors');
4
2
 
5
- /* eslint-disable require-jsdoc */
6
3
  class RateLimit {
7
4
  constructor() {
8
5
  this.initialized = 0;
@@ -12,18 +9,21 @@ class RateLimit {
12
9
  if (!this.initialized) return;
13
10
  this.requests++;
14
11
  this.requestQueue.unshift(Date.now());
15
- if (this.options.rateLimit === 'NONE' || !this.requestQueue.length) return;
16
- if (this.options.rateLimit === 'AUTO' && this.requests <= this.options.keyLimit / 2) return;
12
+ if ('NONE' === this.options.rateLimit || !this.requestQueue.length) return;
13
+ if ('AUTO' === this.options.rateLimit && this.requests <= this.options.keyLimit / 2) return;
17
14
  const cooldown = this.computeCooldownTime();
18
15
  this.requestQueue[0] = Date.now() + cooldown;
19
- await new Promise((r) => setTimeout(r, cooldown), true);
20
- return;
16
+ return await new Promise((r) => setTimeout(r, cooldown), true);
21
17
  }
22
18
 
23
19
  sync(data) {
24
20
  this.options.keyLimit = parseInt(data.get('ratelimit-limit'), 10) || this.options.keyLimit;
25
21
  this.requests = parseInt(data.get('ratelimit-remaining'), 10) || this.requests;
26
- if (data.get('ratelimit-reset') && Math.round(Date.now() / 1000) - (300 - parseInt(data.get('ratelimit-reset'), 10)) !== Math.round(this.lastResetHappenedAt / 1000)) {
22
+ if (
23
+ data.get('ratelimit-reset') &&
24
+ Math.round(Date.now() / 1000) - (300 - parseInt(data.get('ratelimit-reset'), 10)) !==
25
+ Math.round(this.lastResetHappenedAt / 1000)
26
+ ) {
27
27
  clearTimeout(this.resetTimer);
28
28
  this.resetTimer = setTimeout(this.reset.bind(this), parseInt(data.get('ratelimit-reset'), 10) * 1000);
29
29
  }
@@ -32,12 +32,16 @@ class RateLimit {
32
32
  computeCooldownTime() {
33
33
  const overhead = this.requestQueue[1] <= Date.now() ? 0 : this.requestQueue[1] - Date.now();
34
34
  const multiplier = Math.floor(this.requests / this.options.keyLimit) + 1;
35
- return overhead + (-overhead - Date.now() + 300000 * multiplier + this.lastResetHappenedAt) / (this.options.keyLimit * multiplier - this.requests);
35
+ return (
36
+ overhead +
37
+ (-overhead - Date.now() + 300000 * multiplier + this.lastResetHappenedAt) /
38
+ (this.options.keyLimit * multiplier - this.requests)
39
+ );
36
40
  }
37
41
 
38
42
  reset() {
39
43
  this.requests = this.requests - this.options.keyLimit;
40
- if (this.requests < 0) this.requests = 0;
44
+ if (0 > this.requests) this.requests = 0;
41
45
  this.lastResetHappenedAt = Date.now();
42
46
  this.resetTimer = setTimeout(this.reset.bind(this), 300000);
43
47
  this.requestQueue = this.requestQueue.filter((x) => x >= Date.now());
@@ -50,13 +54,13 @@ class RateLimit {
50
54
  init(keyInfo, options, client) {
51
55
  this.options = options;
52
56
  this.requests = 0;
53
- this.cooldownTime = 300000 / this.options.keyLimit; // Initial value
57
+ this.cooldownTime = 300000 / this.options.keyLimit;
54
58
  this.requestQueue = [];
55
59
  this.client = client;
56
60
  return keyInfo
57
61
  .then((info) => {
58
62
  this.requests = info.requestsInPastMin;
59
- this.lastResetHappenedAt = Date.now() - (300 - info.resetsAfter) * 1000; // Computed reset time
63
+ this.lastResetHappenedAt = Date.now() - (300 - info.resetsAfter) * 1000;
60
64
  this.resetTimer = setTimeout(this.rateLimitMonitor.bind(this), 1000 * info.resetsAfter);
61
65
  this.initialized = 1;
62
66
  })
@@ -74,6 +78,6 @@ module.exports = RateLimit;
74
78
  /**
75
79
  * @typedef {Object} RLOptions
76
80
  * @property {number} keyLimit Max request of key per min
77
- * @property {NONE|AUTO|HARD} rateLimit rate limit mode
81
+ * @property {'NONE'|'AUTO'|'HARD'} rateLimit rate limit mode
78
82
  * @property {boolean} syncWithHeaders Sync rate limits with headers
79
83
  */
@@ -1,10 +1,9 @@
1
- /* eslint-disable require-jsdoc */
2
1
  const requireFetch = !globalThis.fetch;
3
- const externalFetch = require('node-fetch');
2
+ const externalFetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args));
3
+ const fetch = requireFetch ? externalFetch : globalThis.fetch;
4
4
  const BASE_URL = 'https://api.hypixel.net/v2';
5
- const Errors = require('../Errors');
6
5
  const Cache = require('./defaultCache');
7
- const Client = require('../Client.js');
6
+ const Errors = require('../Errors');
8
7
 
9
8
  class Requests {
10
9
  constructor(client, cache) {
@@ -14,32 +13,44 @@ class Requests {
14
13
  }
15
14
  async request(endpoint, options = {}) {
16
15
  options.headers = { 'API-Key': this.client.key, ...options.headers };
17
- const fetchMethod = requireFetch ? externalFetch : fetch;
18
16
  /**
19
17
  * @type {externalFetch.Response|Response}
20
18
  */
21
- const res = await fetchMethod(BASE_URL + endpoint, options);
22
- if (res.status >= 500 && res.status < 528) throw new Error(Errors.ERROR_STATUSTEXT.replace(/{statustext}/, `Server Error : ${res.status} ${res.statusText}`));
19
+ const res = await fetch(BASE_URL + endpoint, options);
20
+ if (500 <= res.status && 528 > res.status) {
21
+ throw new Error(
22
+ Errors.ERROR_STATUSTEXT.replace(/{statustext}/, `Server Error : ${res.status} ${res.statusText}`)
23
+ );
24
+ }
23
25
  const parsedRes = await res.json().catch(() => {
24
26
  throw new Error(Errors.INVALID_RESPONSE_BODY);
25
27
  });
26
- if (res.status === 400) throw new Error(Errors.ERROR_CODE_CAUSE.replace(/{code}/, '400 Bad Request').replace(/{cause}/, parsedRes.cause || ''));
27
- if (res.status === 403) throw new Error(Errors.INVALID_API_KEY);
28
- if (res.status === 422) throw new Error(Errors.UNEXPECTED_ERROR);
29
- if (res.status === 429) throw new Error(Errors.RATE_LIMIT_EXCEEDED);
30
- if (res.status !== 200) throw new Error(Errors.ERROR_STATUSTEXT.replace(/{statustext}/, res.statusText));
28
+ if (400 === res.status) {
29
+ throw new Error(
30
+ Errors.ERROR_CODE_CAUSE.replace(/{code}/, '400 Bad Request').replace(/{cause}/, parsedRes.cause || '')
31
+ );
32
+ }
33
+ if (403 === res.status) throw new Error(Errors.INVALID_API_KEY);
34
+ if (422 === res.status) throw new Error(Errors.UNEXPECTED_ERROR);
35
+ if (429 === res.status) throw new Error(Errors.RATE_LIMIT_EXCEEDED);
36
+ if (200 !== res.status) throw new Error(Errors.ERROR_STATUSTEXT.replace(/{statustext}/, res.statusText));
31
37
  if (!parsedRes.success) {
32
38
  throw new Error(Errors.SOMETHING_WENT_WRONG.replace(/{cause}/, res.cause));
33
39
  }
40
+ // eslint-disable-next-line no-underscore-dangle
34
41
  parsedRes._headers = res.headers;
35
- parsedRes.raw = !!options.raw;
42
+ parsedRes.raw = Boolean(options.raw);
36
43
  if (options.noCaching) return parsedRes;
37
44
  // split by question mark : first part is /path, remove /
38
45
  if (this.client.options.cache && this.client.options.cacheFilter(endpoint.split('?')[0].slice(1))) {
39
- if (this.client.options.cacheSize < (await this.cached.size())) await this.cached.delete(Array.from(await this.cached.keys())[0]);
46
+ if (this.client.options.cacheSize < (await this.cached.size())) {
47
+ await this.cached.delete(Array.from(await this.cached.keys())[0]);
48
+ }
40
49
  await this.cached.delete(endpoint);
41
50
  await this.cached.set(endpoint, parsedRes);
42
- if (this.client.options.cacheTime >= 0) setTimeout(() => this.cached.delete(endpoint), 1000 * this.client.options.cacheTime);
51
+ if (0 <= this.client.options.hypixelCacheTime) {
52
+ setTimeout(() => this.cached.delete(endpoint), 1000 * this.client.options.hypixelCacheTime);
53
+ }
43
54
  }
44
55
  return parsedRes;
45
56
  }
@@ -58,7 +69,7 @@ class Requests {
58
69
  }
59
70
 
60
71
  validateCustomCache(cache) {
61
- return !!(cache.set && cache.get && cache.delete && cache.keys);
72
+ return Boolean(cache.set && cache.get && cache.delete && cache.keys);
62
73
  }
63
74
  }
64
75