hypixel-api-reborn 11.0.1 → 11.2.0

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 (96) hide show
  1. package/.prettierrc +13 -13
  2. package/LICENSE +20 -20
  3. package/README.md +67 -65
  4. package/package.json +20 -18
  5. package/src/API/getAPIStatus.js +1 -1
  6. package/src/API/getAchievements.js +6 -0
  7. package/src/API/getChallenges.js +6 -0
  8. package/src/API/getGuild.js +1 -1
  9. package/src/API/getGuildAchievements.js +6 -0
  10. package/src/API/getLeaderboards.js +3 -1
  11. package/src/API/getPlayer.js +1 -1
  12. package/src/API/getQuests.js +6 -0
  13. package/src/API/getRecentGames.js +1 -1
  14. package/src/API/getServerInfo.js +3 -1
  15. package/src/API/getStatus.js +1 -1
  16. package/src/API/index.js +28 -17
  17. package/src/API/skyblock/getAuction.js +19 -0
  18. package/src/API/skyblock/{getSkyblockAuctions.js → getAuctions.js} +6 -2
  19. package/src/API/skyblock/{getSkyblockAuctionsByPlayer.js → getAuctionsByPlayer.js} +1 -1
  20. package/src/API/skyblock/getBingo.js +8 -0
  21. package/src/API/skyblock/getBingoByPlayer.js +14 -0
  22. package/src/API/skyblock/getFireSales.js +7 -0
  23. package/src/API/skyblock/getGovernment.js +8 -0
  24. package/src/API/skyblock/{getSkyblockMember.js → getMember.js} +10 -6
  25. package/src/API/skyblock/getMuseum.js +14 -0
  26. package/src/API/skyblock/{getSkyblockProfiles.js → getProfiles.js} +14 -12
  27. package/src/Client.js +91 -17
  28. package/src/Errors.js +39 -17
  29. package/src/Private/rateLimit.js +10 -2
  30. package/src/Private/requests.js +20 -8
  31. package/src/Private/updater.js +10 -20
  32. package/src/Private/uuidCache.js +23 -29
  33. package/src/Private/validate.js +20 -9
  34. package/src/index.js +9 -0
  35. package/src/structures/APIIncident.js +3 -9
  36. package/src/structures/Boosters/Booster.js +5 -5
  37. package/src/structures/Color.js +93 -48
  38. package/src/structures/Game.js +3 -1
  39. package/src/structures/Guild/Guild.js +21 -17
  40. package/src/structures/Guild/GuildMember.js +6 -6
  41. package/src/structures/Guild/GuildRank.js +2 -2
  42. package/src/structures/MiniGames/Arcade.js +22 -17
  43. package/src/structures/MiniGames/BedWars.js +152 -24
  44. package/src/structures/MiniGames/Duels.js +84 -23
  45. package/src/structures/MiniGames/MegaWalls.js +3 -1
  46. package/src/structures/MiniGames/MurderMystery.js +2 -2
  47. package/src/structures/MiniGames/Pit.js +231 -2
  48. package/src/structures/MiniGames/PitInventoryItem.js +43 -0
  49. package/src/structures/MiniGames/SkyWars.js +19 -14
  50. package/src/structures/MiniGames/SmashHeroes.js +1 -1
  51. package/src/structures/MiniGames/TNTGames.js +1 -1
  52. package/src/structures/MiniGames/UHC.js +21 -3
  53. package/src/structures/MiniGames/WoolWars.js +1 -1
  54. package/src/structures/Player.js +16 -20
  55. package/src/structures/PlayerCosmetics.js +64 -10
  56. package/src/structures/ServerInfo.js +1 -1
  57. package/src/structures/SkyBlock/Auctions/Auction.js +3 -1
  58. package/src/structures/SkyBlock/Auctions/AuctionInfo.js +1 -0
  59. package/src/structures/SkyBlock/Auctions/BaseAuction.js +1 -0
  60. package/src/structures/SkyBlock/Auctions/Bid.js +1 -0
  61. package/src/structures/SkyBlock/Auctions/PartialAuction.js +1 -0
  62. package/src/structures/SkyBlock/PlayerBingo.js +56 -0
  63. package/src/structures/SkyBlock/SkyblockInventoryItem.js +86 -18
  64. package/src/structures/SkyBlock/SkyblockMember.js +252 -144
  65. package/src/structures/SkyBlock/SkyblockMuseum.js +60 -0
  66. package/src/structures/SkyBlock/SkyblockMuseumItem.js +54 -0
  67. package/src/structures/SkyBlock/SkyblockPet.js +1 -0
  68. package/src/structures/SkyBlock/SkyblockProfile.js +37 -23
  69. package/src/structures/SkyBlock/Static/Bingo.js +102 -0
  70. package/src/structures/SkyBlock/Static/BingoData.js +45 -0
  71. package/src/structures/SkyBlock/Static/Candidate.js +40 -0
  72. package/src/structures/SkyBlock/Static/FireSale.js +55 -0
  73. package/src/structures/SkyBlock/Static/Government.js +74 -0
  74. package/src/structures/SkyBlock/Static/Perk.js +24 -0
  75. package/src/structures/Static/Achievement.js +86 -0
  76. package/src/structures/Static/AchievementTier.js +33 -0
  77. package/src/structures/Static/Achievements.js +30 -0
  78. package/src/structures/Static/Challenges.js +29 -0
  79. package/src/structures/Static/GameAchievements.js +36 -0
  80. package/src/structures/Static/GameChallenges.js +40 -0
  81. package/src/structures/Static/GameQuests.js +24 -0
  82. package/src/structures/Static/GuildAchievements.js +34 -0
  83. package/src/structures/Static/Quest.js +66 -0
  84. package/src/structures/Static/Quests.js +31 -0
  85. package/src/structures/Status.js +2 -2
  86. package/src/utils/Constants.js +385 -42
  87. package/src/utils/SkyblockUtils.js +12 -7
  88. package/src/utils/guildExp.js +4 -1
  89. package/src/utils/removeSnakeCase.js +9 -2
  90. package/src/utils/romanize.js +32 -1
  91. package/src/utils/toIGN.js +6 -2
  92. package/src/utils/toUuid.js +10 -5
  93. package/typings/index.d.ts +989 -297
  94. /package/src/API/skyblock/{getSkyblockBazaar.js → getBazaar.js} +0 -0
  95. /package/src/API/skyblock/{getEndedSkyblockAuctions.js → getEndedAuctions.js} +0 -0
  96. /package/src/API/skyblock/{getSkyblockNews.js → getNews.js} +0 -0
package/src/Client.js CHANGED
@@ -13,7 +13,7 @@ const clients = [];
13
13
  */
14
14
  class Client extends EventEmitter {
15
15
  /**
16
- * @param {string} key API key [(?)](https://stavzdev.is-inside.me/cCMiZdoy.gif)
16
+ * @param {string} key API key
17
17
  * @param {ClientOptions} [options={}] Client options
18
18
  */
19
19
  constructor(key, options = {}) {
@@ -32,20 +32,23 @@ class Client extends EventEmitter {
32
32
  validate.validateOptions(this.options);
33
33
  // eslint-disable-next-line guard-for-in
34
34
  for (const func in API) {
35
- Client.prototype[func] = function (...args) {
35
+ Client.prototype[func] = (...args) => {
36
36
  const lastArg = args[args.length - 1];
37
37
  return API[func].apply(
38
38
  {
39
- _makeRequest: this._makeRequest.bind(this, { ...(validate.cacheSuboptions(lastArg) ? lastArg : {}) }),
39
+ _makeRequest: this._makeRequest.bind(this, validate.cacheSuboptions(lastArg) ? lastArg : {}),
40
40
  ...this
41
41
  },
42
42
  args
43
43
  );
44
44
  };
45
+ }
45
46
 
46
- if (this.options.checkForUpdates) {
47
- updater.checkForUpdates();
48
- }
47
+ if (this.options.checkForUpdates) {
48
+ updater.checkForUpdates().catch(() => {
49
+ // eslint-disable-next-line no-console
50
+ if (!this.options.silent) console.warn('[hypixel-api-reborn] Error whilst checking for updates!');
51
+ });
49
52
  }
50
53
  /**
51
54
  * All cache entries
@@ -53,7 +56,7 @@ class Client extends EventEmitter {
53
56
  */
54
57
  this.cache = this.requests.cache;
55
58
  clients.push(this);
56
- rateLimit.init(this.getPlayer('52d9a36f66ce4cdf9a56ad9724ae9fb4'), this.options, this).then(() => this.emit('ready'));
59
+ rateLimit.init(this.getGameCounts(), this.options, this).then(() => this.emit('ready'));
57
60
  }
58
61
  /**
59
62
  * Private function - make request
@@ -65,10 +68,15 @@ class Client extends EventEmitter {
65
68
  */
66
69
  async _makeRequest(options, url, useRateLimitManager = true) {
67
70
  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 });
71
+ if (url !== '/key' && !options.noCacheCheck && (await this.requests.cache.has(url))) {
72
+ return Object.assign(await this.requests.cache.get(url), { raw: !!options.raw });
73
+ }
69
74
  if (useRateLimitManager) await rateLimit.rateLimitManager();
70
75
  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 } });
76
+ const result = await this.requests.request.call(this.requests, url, {
77
+ ...options,
78
+ headers: { ...options.headers, ...this.options.headers }
79
+ });
72
80
  if (this.options.syncWithHeaders) rateLimit.sync(result._headers);
73
81
  return result;
74
82
  }
@@ -143,6 +151,11 @@ class Client extends EventEmitter {
143
151
  * }).catch(e => {
144
152
  * console.log(e);
145
153
  * })
154
+ * @example
155
+ * // async/await
156
+ * const guild = await hypixel.getGuild('name', 'The Foundation').catch(console.log);
157
+ * console.log(guild.level); // 111
158
+ * console.log(guild.id); // '52e5719284ae51ed0c716c69'
146
159
  */
147
160
  /**
148
161
  * Allows you to get statistics of watchdog, the server anticheat
@@ -156,6 +169,10 @@ class Client extends EventEmitter {
156
169
  * }).catch(e => {
157
170
  * console.log(e);
158
171
  * })
172
+ * @example
173
+ * // async/await
174
+ * const watchdog = await hypixel.getWatchdogStats().catch(console.log);
175
+ * console.log(watchdog.byWatchdogTotal); // 5931897
159
176
  */
160
177
  /**
161
178
  * Allows you to get all active boosters
@@ -169,6 +186,10 @@ class Client extends EventEmitter {
169
186
  * }).catch(e => {
170
187
  * console.log(e);
171
188
  * })
189
+ * @example
190
+ * // async/await
191
+ * const boosters = await hypixel.getBoosters().catch(console.log);
192
+ * console.log(boosters[0].purchaser); // '978ddb705a8e43618e41749178c020b0'
172
193
  */
173
194
  /**
174
195
  * Allows you to get all skyblock profiles of player
@@ -183,13 +204,16 @@ class Client extends EventEmitter {
183
204
  * }).catch(e => {
184
205
  * console.log(e);
185
206
  * })
207
+ * @example
208
+ * const profiles = await hypixel.getSkyblockProfiles('StavZDev').catch(console.log);
209
+ * console.log(profiles[0].members[0].uuid); // '52d9a36f66ce4cdf9a56ad9724ae9fb4'
186
210
  */
187
211
  /**
188
212
  * Allows you to get a player's skyblock member data from all their profiles
189
213
  * @method
190
214
  * @name Client#getSkyblockMember
191
215
  * @param {string} query Player nickname or UUID
192
- * @param {MethodOptions} [options={}] Method options
216
+ * @param {SkyblockMethodOptions} [options={}] Method options
193
217
  * @return {Promise<Map<string,SkyblockMember>>}
194
218
  * @example
195
219
  * hypixel.getSkyblockMember('StavZDev').then(member => {
@@ -198,6 +222,17 @@ class Client extends EventEmitter {
198
222
  * }).catch(e => {
199
223
  * console.log(e);
200
224
  * })
225
+ * @example
226
+ * const member = await hypixel.getSkyblockMember('StavZDev').catch(console.log);
227
+ * console.log(member.get('Cucumber').uuid); // '52d9a36f66ce4cdf9a56ad9724ae9fb4'
228
+ */
229
+ /**
230
+ * Allows you to get a player's skyblock profile museum
231
+ * @method
232
+ * @name Client#getSkyblockMuseum
233
+ * @param {string} query Player nickname or UUID
234
+ * @param {string} profileId Profile ID
235
+ * @return {Promise<SkyblockMuseum>}
201
236
  */
202
237
  /**
203
238
  * Allows you to get the Hypixel API's Status and past Incidents, no key needed.
@@ -312,6 +347,34 @@ class Client extends EventEmitter {
312
347
  * console.log(products[0].productId); // INK_SACK:3
313
348
  * })
314
349
  * .catch(console.log);
350
+ */ /**
351
+ * Allows you to get bingo data
352
+ * @method
353
+ * @name Client#getSkyblockBingo
354
+ * @param {MethodOptions} [options={}] Options
355
+ * @return {Promise<BingoData>}
356
+ */
357
+ /**
358
+ * Allows you to get bingo data of a player
359
+ * @method
360
+ * @name Client#getSkyblockBingoByPlayer
361
+ * @param {string} query UUID / IGN of player
362
+ * @param {PlayerBingoOptions} [options={}] Options
363
+ * @return {Promise<PlayerBingo>}
364
+ */
365
+ /**
366
+ * Allows you to get SB government
367
+ * @method
368
+ * @name Client#getSkyblockGovernment
369
+ * @param {MethodOptions} [options={}] Options
370
+ * @return {Promise<GovernmentData>}
371
+ */
372
+ /**
373
+ * Allows you to get SB government
374
+ * @method
375
+ * @name Client#getSkyblockFireSale
376
+ * @param {MethodOptions} [options={}] Options
377
+ * @return {Promise<FireSale[]>}
315
378
  */
316
379
  /**
317
380
  * Allows you to get skyblock news
@@ -348,16 +411,18 @@ class Client extends EventEmitter {
348
411
  }
349
412
  /**
350
413
  * @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.
414
+ * @prop {boolean} [cache=true] Enable/Disable request caching.
415
+ * @prop {number} [hypixelCacheTime=60] Amount of time in seconds to cache the hypixel api requests.
416
+ * @prop {number} [mojangCacheTime=600] Amount of time in seconds to cache the mojang api requests.
353
417
  * @prop {CacheHandler} [cacheHandler] Custom Cache Handler
354
418
  * @prop {AUTO|HARD|NONE} [rateLimit='AUTO'] Rate limit mode.
355
419
  * @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.
420
+ * @prop {number} [keyLimit=60] Key limit of your key.
357
421
  * @prop {number} [cacheSize=-1] The amount how many results will be cached. (`-1` for infinity)
358
422
  * @prop {boolean} [silent=false] Don't automatically put warnings into console.
359
423
  * @prop {object} [headers={}] Extra Headers ( like User-Agent ) to add to request.
360
- * @prop {boolean} [checkForUpdates=false] Enable/Disable check for new version of hypixel-api-reborn.
424
+ * @prop {boolean} [checkForUpdates=true] Enable/Disable check for new version of hypixel-api-reborn.
425
+ * @prop {boolean|string} [useThirdPartyAPI=false] Enable/Disable Mojang Third Party API
361
426
  */
362
427
  const defaultCache = require('./Private/defaultCache.js');
363
428
  /**
@@ -384,9 +449,10 @@ const defaultCache = require('./Private/defaultCache.js');
384
449
  */
385
450
  /**
386
451
  * @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
452
+ * @property {boolean} [fetchPlayer=false] Raw data
453
+ * @property {boolean} [getMuseum=false] Raw data
454
+ * @property {boolean} [noCacheCheck=false] Disable/Enable cache checking
455
+ * @property {boolean} [noCaching=false] Disable/Enable writing to cache
390
456
  * @property {?boolean} [fetchPlayer=false] Disable/Enable player profile request for each member
391
457
  * @prop {object} [headers={}] Extra Headers ( like User-Agent ) to add to request. Overrides the headers globally provided.
392
458
  */
@@ -403,4 +469,12 @@ const defaultCache = require('./Private/defaultCache.js');
403
469
  * @property {boolean} [includeItemBytes=false] Whether to include item bytes in the result
404
470
  * @prop {object} [headers={}] Extra Headers ( like User-Agent ) to add to request. Overrides the headers globally provided.
405
471
  */
472
+ /**
473
+ * @typedef {object} PlayerBingoOptions
474
+ * @property {boolean} [raw=false] Raw data
475
+ * @property {boolean} [noCacheCheck=false] Disable/Enable cache checking
476
+ * @property {boolean} [noCaching=false] Disable/Enable writing to cache
477
+ * @property {boolean} [fetchBingoData=false] Fetches bingo data to give more information
478
+ * @prop {object} [headers={}] Extra Headers ( like User-Agent ) to add to request. Overrides the headers globally provided.
479
+ */
406
480
  module.exports = Client;
package/src/Errors.js CHANGED
@@ -2,43 +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
- "[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"
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",
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.'
44
66
  };
@@ -23,7 +23,11 @@ class RateLimit {
23
23
  sync(data) {
24
24
  this.options.keyLimit = parseInt(data.get('ratelimit-limit'), 10) || this.options.keyLimit;
25
25
  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)) {
26
+ if (
27
+ data.get('ratelimit-reset') &&
28
+ Math.round(Date.now() / 1000) - (300 - parseInt(data.get('ratelimit-reset'), 10)) !==
29
+ Math.round(this.lastResetHappenedAt / 1000)
30
+ ) {
27
31
  clearTimeout(this.resetTimer);
28
32
  this.resetTimer = setTimeout(this.reset.bind(this), parseInt(data.get('ratelimit-reset'), 10) * 1000);
29
33
  }
@@ -32,7 +36,11 @@ class RateLimit {
32
36
  computeCooldownTime() {
33
37
  const overhead = this.requestQueue[1] <= Date.now() ? 0 : this.requestQueue[1] - Date.now();
34
38
  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);
39
+ return (
40
+ overhead +
41
+ (-overhead - Date.now() + 300000 * multiplier + this.lastResetHappenedAt) /
42
+ (this.options.keyLimit * multiplier - this.requests)
43
+ );
36
44
  }
37
45
 
38
46
  reset() {
@@ -1,7 +1,8 @@
1
1
  /* eslint-disable require-jsdoc */
2
2
  const requireFetch = !globalThis.fetch;
3
- const externalFetch = require('node-fetch');
4
- const BASE_URL = 'https://api.hypixel.net';
3
+ const externalFetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args));
4
+ const fetch = requireFetch ? externalFetch : globalThis.fetch;
5
+ const BASE_URL = 'https://api.hypixel.net/v2';
5
6
  const Errors = require('../Errors');
6
7
  const Cache = require('./defaultCache');
7
8
  const Client = require('../Client.js');
@@ -14,16 +15,23 @@ class Requests {
14
15
  }
15
16
  async request(endpoint, options = {}) {
16
17
  options.headers = { 'API-Key': this.client.key, ...options.headers };
17
- const fetchMethod = requireFetch ? externalFetch : fetch;
18
18
  /**
19
19
  * @type {externalFetch.Response|Response}
20
20
  */
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}`));
21
+ const res = await fetch(BASE_URL + endpoint, options);
22
+ if (res.status >= 500 && res.status < 528) {
23
+ throw new Error(
24
+ Errors.ERROR_STATUSTEXT.replace(/{statustext}/, `Server Error : ${res.status} ${res.statusText}`)
25
+ );
26
+ }
23
27
  const parsedRes = await res.json().catch(() => {
24
28
  throw new Error(Errors.INVALID_RESPONSE_BODY);
25
29
  });
26
- if (res.status === 400) throw new Error(Errors.ERROR_CODE_CAUSE.replace(/{code}/, '400 Bad Request').replace(/{cause}/, parsedRes.cause || ''));
30
+ if (res.status === 400) {
31
+ throw new Error(
32
+ Errors.ERROR_CODE_CAUSE.replace(/{code}/, '400 Bad Request').replace(/{cause}/, parsedRes.cause || '')
33
+ );
34
+ }
27
35
  if (res.status === 403) throw new Error(Errors.INVALID_API_KEY);
28
36
  if (res.status === 422) throw new Error(Errors.UNEXPECTED_ERROR);
29
37
  if (res.status === 429) throw new Error(Errors.RATE_LIMIT_EXCEEDED);
@@ -36,10 +44,14 @@ class Requests {
36
44
  if (options.noCaching) return parsedRes;
37
45
  // split by question mark : first part is /path, remove /
38
46
  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]);
47
+ if (this.client.options.cacheSize < (await this.cached.size())) {
48
+ await this.cached.delete(Array.from(await this.cached.keys())[0]);
49
+ }
40
50
  await this.cached.delete(endpoint);
41
51
  await this.cached.set(endpoint, parsedRes);
42
- if (this.client.options.cacheTime >= 0) setTimeout(() => this.cached.delete(endpoint), 1000 * this.client.options.cacheTime);
52
+ if (this.client.options.hypixelCacheTime >= 0) {
53
+ setTimeout(() => this.cached.delete(endpoint), 1000 * this.client.options.hypixelCacheTime);
54
+ }
43
55
  }
44
56
  return parsedRes;
45
57
  }
@@ -1,33 +1,23 @@
1
- /* eslint-disable no-console */
2
1
  /* eslint-disable require-jsdoc */
3
- const fetch = require('node-fetch');
2
+ /* eslint-disable no-console */
3
+ const requireFetch = !globalThis.fetch;
4
+ const externalFetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args));
5
+ const fetch = requireFetch ? externalFetch : globalThis.fetch;
4
6
  const Errors = require('../Errors');
5
7
  class Updater {
6
8
  async checkForUpdates() {
7
- const currentVersion = require('../../package.json').version;
9
+ const version = require('../../package.json').version;
8
10
  const request = await fetch('https://registry.npmjs.org/hypixel-api-reborn');
9
11
  if (!request.ok) return console.log(Errors.UPDATER_REQUEST_NOT_OK);
10
12
  const metadata = await request.json();
11
- const latestVersion = metadata['dist-tags'].latest;
12
- const compare = this.compare(currentVersion, latestVersion);
13
+ const latest = metadata['dist-tags'].latest;
14
+ const compare = this.compare(version, latest);
13
15
  if (compare === -1) {
14
- this.notify(latestVersion);
16
+ console.log(
17
+ `New version of hypixel-api-reborn is available! Current version: ${version}, Latest version: ${latest}`
18
+ );
15
19
  }
16
20
  }
17
- notify(newVersion) {
18
- console.log(`
19
-
20
- New version of hypixel-api-reborn is available!
21
-
22
- v${newVersion}
23
- Changelog: https://github.com/Hypixel-API-Reborn/hypixel-api-reborn/releases/tag/${newVersion}
24
-
25
- \x1b[33mnpm i hypixel-api-reborn@${newVersion}\x1b[0m
26
- or
27
- \x1b[33myarn add hypixel-api-reborn@${newVersion}\x1b[0m
28
-
29
- `);
30
- }
31
21
  compare(a, b) {
32
22
  const pa = a.split('.');
33
23
  const pb = b.split('.');
@@ -1,37 +1,31 @@
1
1
  /* eslint-disable require-jsdoc */
2
2
  const requireFetch = !globalThis.fetch;
3
- const externalFetch = require('node-fetch');
3
+ const externalFetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args));
4
4
  const fetch = requireFetch ? externalFetch : globalThis.fetch;
5
- const cachedUuids = new Map();
5
+ const NodeCache = require('node-cache');
6
+ const cache = new NodeCache();
6
7
 
7
8
  // TODO - use this for all cache models
8
9
 
9
- async function putCache(response) {
10
- try {
11
- response = await response.json();
12
- cachedUuids.set(response.id, response.name);
13
- setTimeout(deleteCache, 1000 * 60 * 10, response.id);
14
- } catch (e) {
15
- // F
16
- }
17
- }
18
- function deleteCache(id) {
19
- return cachedUuids.delete(id);
20
- }
21
- function response(obj) {
22
- return new fetch.Response(JSON.stringify(obj));
23
- }
24
- function checkHit(query) {
25
- if (cachedUuids.has(query)) return response({ id: query, name: cachedUuids.get(query) });
26
- const reverseSearch = Array.from(cachedUuids.entries()).find((pair) => pair[1].toLowerCase() === query.toLowerCase());
27
- if (reverseSearch) return response({ id: reverseSearch[0], name: query });
28
- return null;
29
- }
30
- module.exports = async (url, query) => {
31
- if (checkHit(query || url)) return checkHit(query || url);
10
+ module.exports = async (url, query, cacheTime) => {
11
+ if (cache.has(query.toLowerCase())) return cache.get(query.toLowerCase());
32
12
  const res = await fetch(url);
33
- const response = await res.clone().json();
34
- // Don't cache 5xx
35
- if (response.error !== 'Internal Server Error' && response.status < 500) setTimeout(putCache, 0, res.clone());
36
- return res;
13
+ const data = await res.json();
14
+ // Don't cache 4xx
15
+ if (res.status >= 400) {
16
+ return {
17
+ status: res.status,
18
+ id: null,
19
+ name: null
20
+ };
21
+ }
22
+
23
+ cache.set(query.toLowerCase(), { status: res.status, id: data.id, name: data.name }, cacheTime);
24
+ cache.set(data.id.toLowerCase(), { status: res.status, id: data.id, name: data.name }, cacheTime);
25
+
26
+ return {
27
+ status: res.status,
28
+ id: data.id,
29
+ name: data.name
30
+ };
37
31
  };
@@ -12,12 +12,20 @@ class Validation {
12
12
  * @private
13
13
  */
14
14
  validateOptions(options) {
15
- if (typeof options.cacheTime !== 'number') throw new Error(Errors.CACHE_TIME_MUST_BE_A_NUMBER);
15
+ if (typeof options.hypixelCacheTime !== 'number') throw new Error(Errors.CACHE_TIME_MUST_BE_A_NUMBER);
16
+ if (typeof options.mojangCacheTime !== 'number') throw new Error(Errors.CACHE_TIME_MUST_BE_A_NUMBER);
16
17
  if (typeof options.cacheSize !== 'number') throw new Error(Errors.CACHE_LIMIT_MUST_BE_A_NUMBER);
17
- if (typeof options.rateLimit !== 'string' || !['AUTO', 'HARD', 'NONE'].includes(options.rateLimit)) throw new Error(Errors.INVALID_RATE_LIMIT_OPTION);
18
+ if (typeof options.rateLimit !== 'string' || !['AUTO', 'HARD', 'NONE'].includes(options.rateLimit)) {
19
+ throw new Error(Errors.INVALID_RATE_LIMIT_OPTION);
20
+ }
18
21
  if (typeof options.keyLimit !== 'number') throw new Error(Errors.INVALID_KEY_LIMIT_OPTION);
19
22
  if (typeof options.syncWithHeaders !== 'boolean') throw new Error(Errors.INVALID_HEADER_SYNC_OPTION);
20
23
  if (typeof options.headers !== 'object') throw new Error(Errors.INVALID_HEADERS);
24
+ if (typeof options.silent !== 'boolean') throw new Error(Errors.INVALID_SILENT_OPTION);
25
+ if (typeof options.checkForUpdates !== 'boolean') throw new Error(Errors.INVALID_UPDATE_OPTION);
26
+ if (!['boolean', 'string'].includes(typeof options.useThirdPartyAPI)) {
27
+ throw new Error(Errors.INVALID_THIRD_PARTY_API_OPTION);
28
+ }
21
29
  }
22
30
 
23
31
  /**
@@ -29,16 +37,19 @@ class Validation {
29
37
  parseOptions(options) {
30
38
  if (typeof options !== 'object' || options === null) throw new Error(Errors.OPTIONS_MUST_BE_AN_OBJECT);
31
39
  return {
32
- cache: options.cache || false,
33
- cacheTime: options.cacheTime || 60,
40
+ cache: options.cache ?? true,
41
+ hypixelCacheTime: options.hypixelCacheTime ?? 60,
42
+ mojangCacheTime: options.mojangCacheTime ?? 600,
34
43
  cacheSize: (options.cacheSize === -1 ? Infinity : options.cacheSize) || Infinity,
35
- cacheFilter: typeof options.cacheFilter === 'function' ? options.cacheFilter : this._handleFilter(options.cacheFilter),
36
- rateLimit: options.rateLimit || 'AUTO',
37
- keyLimit: options.keyLimit || 120,
44
+ cacheFilter:
45
+ typeof options.cacheFilter === 'function' ? options.cacheFilter : this._handleFilter(options.cacheFilter),
46
+ rateLimit: options.rateLimit ?? 'AUTO',
47
+ keyLimit: options.keyLimit ?? 60,
38
48
  syncWithHeaders: !!options.syncWithHeaders,
39
- headers: options.headers || {},
49
+ headers: options.headers ?? {},
40
50
  silent: !!options.silent,
41
- checkForUpdates: options.checkForUpdates || false
51
+ checkForUpdates: options.checkForUpdates ?? true,
52
+ useThirdPartyAPI: options.useThirdPartyAPI ?? false
42
53
  };
43
54
  }
44
55
 
package/src/index.js CHANGED
@@ -14,6 +14,10 @@ module.exports = {
14
14
  Pets: require('./structures/Pets'),
15
15
  PlayerCosmetics: require('./structures/PlayerCosmetics'),
16
16
 
17
+ /* Challenges */
18
+ Challenges: require('./structures/Static/Challenges.js'),
19
+ GameChallenges: require('./structures/Static/GameChallenges.js'),
20
+
17
21
  /* Watchdog */
18
22
  WatchdogStats: require('./structures/Watchdog/Stats.js'),
19
23
 
@@ -27,6 +31,10 @@ module.exports = {
27
31
  SkyblockMember: require('./structures/SkyBlock/SkyblockMember.js'),
28
32
  SkyblockInventoryItem: require('./structures/SkyBlock/SkyblockInventoryItem.js'),
29
33
  SkyblockPet: require('./structures/SkyBlock/SkyblockPet'),
34
+ GovernmentData: require('./structures/SkyBlock/Static/Government.js'),
35
+ Candidate: require('./structures/SkyBlock/Static/Candidate.js'),
36
+ BingoData: require('./structures/SkyBlock/Static/BingoData.js'),
37
+ Bingo: require('./structures/SkyBlock/Static/Bingo.js'),
30
38
 
31
39
  /* Skyblock Auctions */
32
40
  BaseAuction: require('./structures/SkyBlock/Auctions/BaseAuction.js'),
@@ -34,6 +42,7 @@ module.exports = {
34
42
  Auction: require('./structures/SkyBlock/Auctions/Auction.js'),
35
43
  AuctionInfo: require('./structures/SkyBlock/Auctions/AuctionInfo.js'),
36
44
  Bid: require('./structures/SkyBlock/Auctions/Bid.js'),
45
+ FireSale: require('./structures/SkyBlock/Static/FireSale.js'),
37
46
 
38
47
  /* Skyblock Bazaar */
39
48
  Product: require('./structures/SkyBlock/Bazzar/Product.js'),
@@ -42,12 +42,6 @@ class APIIncident {
42
42
  * @type {string|null}
43
43
  */
44
44
  this.snippet = data.contentSnippet || null;
45
- /**
46
- * Content as plain text
47
- * The parsing might be faulty!
48
- * @type {string|null}
49
- */
50
- this.TextContent = (data.content || '').replace(/<[^>]+>/g, '') || null;
51
45
  /**
52
46
  * GUID
53
47
  * @type {string|null}
@@ -64,14 +58,14 @@ class APIIncident {
64
58
  * @type {boolean}
65
59
  * @version >6.0.1
66
60
  */
67
- this.isResolved = this.TextContent.includes('Resolved -') || this.TextContent.includes('Completed -');
61
+ this.isResolved = this.HTMLContent.includes('Resolved -') || this.HTMLContent.includes('Completed -');
68
62
  }
69
63
  /**
70
- * Text Content
64
+ * HTML Content
71
65
  * @return {string}
72
66
  */
73
67
  toString() {
74
- return this.TextContent;
68
+ return this.HTMLContent;
75
69
  }
76
70
  }
77
71
 
@@ -9,27 +9,27 @@ class Booster {
9
9
  constructor(data) {
10
10
  /**
11
11
  * Booster's purchaser's UUID
12
- * @type {String}
12
+ * @type {string}
13
13
  */
14
14
  this.purchaser = data.purchaserUuid;
15
15
  /**
16
16
  * Booster's multiplier
17
- * @type {Number}
17
+ * @type {number}
18
18
  */
19
19
  this.amount = data.amount;
20
20
  /**
21
21
  * Booster's length in seconds
22
- * @type {Number}
22
+ * @type {number}
23
23
  */
24
24
  this.originalLength = data.originalLength;
25
25
  /**
26
26
  * Length remaining in seconds
27
- * @type {Number}
27
+ * @type {number}
28
28
  */
29
29
  this.remaining = data.length;
30
30
  /**
31
31
  * Date activated timestamp
32
- * @type {Number}
32
+ * @type {number}
33
33
  */
34
34
  this.activatedTimestamp = data.dateActivated;
35
35
  /**