hypixel-api-reborn 10.0.0 → 11.0.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 (105) hide show
  1. package/.prettierrc +13 -0
  2. package/README.md +28 -16
  3. package/package.json +60 -58
  4. package/src/API/getAPIStatus.js +8 -8
  5. package/src/API/getBoosters.js +6 -6
  6. package/src/API/getGameCounts.js +6 -6
  7. package/src/API/getGuild.js +18 -18
  8. package/src/API/getLeaderboards.js +13 -13
  9. package/src/API/getPlayer.js +22 -27
  10. package/src/API/getRecentGames.js +18 -18
  11. package/src/API/getServerInfo.js +66 -77
  12. package/src/API/getStatus.js +8 -8
  13. package/src/API/getWatchdogStats.js +6 -6
  14. package/src/API/index.js +19 -23
  15. package/src/API/skyblock/getEndedSkyblockAuctions.js +10 -10
  16. package/src/API/skyblock/getSkyblockAuctions.js +64 -64
  17. package/src/API/skyblock/getSkyblockAuctionsByPlayer.js +11 -11
  18. package/src/API/skyblock/getSkyblockBazaar.js +10 -10
  19. package/src/API/skyblock/getSkyblockMember.js +28 -25
  20. package/src/API/skyblock/getSkyblockNews.js +6 -6
  21. package/src/API/skyblock/getSkyblockProfiles.js +44 -41
  22. package/src/Client.js +406 -450
  23. package/src/Errors.js +44 -39
  24. package/src/Private/defaultCache.js +77 -78
  25. package/src/Private/rateLimit.js +79 -98
  26. package/src/Private/requests.js +65 -54
  27. package/src/Private/updater.js +45 -45
  28. package/src/Private/uuidCache.js +37 -33
  29. package/src/Private/validate.js +97 -97
  30. package/src/index.js +82 -83
  31. package/src/structures/APIIncident.js +78 -78
  32. package/src/structures/APIStatus.js +47 -47
  33. package/src/structures/Boosters/Booster.js +83 -87
  34. package/src/structures/Color.js +129 -129
  35. package/src/structures/Game.js +164 -160
  36. package/src/structures/GameCounts.js +151 -151
  37. package/src/structures/Guild/Guild.js +204 -218
  38. package/src/structures/Guild/GuildMember.js +66 -66
  39. package/src/structures/Guild/GuildRank.js +48 -48
  40. package/src/structures/ItemBytes.js +33 -36
  41. package/src/structures/Leaderboard.js +31 -31
  42. package/src/structures/MiniGames/Arcade.js +567 -569
  43. package/src/structures/MiniGames/ArenaBrawl.js +52 -56
  44. package/src/structures/MiniGames/BedWars.js +423 -351
  45. package/src/structures/MiniGames/BlitzSurvivalGames.js +172 -148
  46. package/src/structures/MiniGames/BuildBattle.js +53 -53
  47. package/src/structures/MiniGames/CopsAndCrims.js +90 -90
  48. package/src/structures/MiniGames/Duels.js +694 -630
  49. package/src/structures/MiniGames/MegaWalls.js +137 -137
  50. package/src/structures/MiniGames/MurderMystery.js +93 -93
  51. package/src/structures/MiniGames/Paintball.js +67 -67
  52. package/src/structures/MiniGames/Pit.js +19 -19
  53. package/src/structures/MiniGames/Quakecraft.js +101 -101
  54. package/src/structures/MiniGames/SkyWars.js +508 -559
  55. package/src/structures/MiniGames/SmashHeroes.js +144 -151
  56. package/src/structures/MiniGames/SpeedUHC.js +115 -57
  57. package/src/structures/MiniGames/TNTGames.js +116 -116
  58. package/src/structures/MiniGames/TurboKartRacers.js +201 -176
  59. package/src/structures/MiniGames/UHC.js +164 -143
  60. package/src/structures/MiniGames/VampireZ.js +60 -60
  61. package/src/structures/MiniGames/Walls.js +52 -52
  62. package/src/structures/MiniGames/Warlords.js +62 -62
  63. package/src/structures/MiniGames/WoolWars.js +123 -0
  64. package/src/structures/Pet.js +96 -97
  65. package/src/structures/Pets.js +64 -64
  66. package/src/structures/Player.js +433 -449
  67. package/src/structures/PlayerCosmetics.js +100 -95
  68. package/src/structures/RecentGame.js +57 -57
  69. package/src/structures/ServerInfo.js +78 -78
  70. package/src/structures/SkyBlock/Auctions/Auction.js +104 -104
  71. package/src/structures/SkyBlock/Auctions/AuctionInfo.js +54 -54
  72. package/src/structures/SkyBlock/Auctions/BaseAuction.js +45 -45
  73. package/src/structures/SkyBlock/Auctions/Bid.js +48 -48
  74. package/src/structures/SkyBlock/Auctions/PartialAuction.js +25 -25
  75. package/src/structures/SkyBlock/Bazzar/Order.js +38 -38
  76. package/src/structures/SkyBlock/Bazzar/Product.js +53 -53
  77. package/src/structures/SkyBlock/News/SkyblockNews.js +60 -68
  78. package/src/structures/SkyBlock/SkyblockInventoryItem.js +124 -130
  79. package/src/structures/SkyBlock/SkyblockMember.js +820 -687
  80. package/src/structures/SkyBlock/SkyblockPet.js +71 -71
  81. package/src/structures/SkyBlock/SkyblockProfile.js +60 -60
  82. package/src/structures/Status.js +41 -41
  83. package/src/structures/Watchdog/Stats.js +36 -36
  84. package/src/utils/Constants.js +2789 -809
  85. package/src/utils/SkyblockUtils.js +208 -164
  86. package/src/utils/arrayTools.js +4 -4
  87. package/src/utils/divide.js +5 -5
  88. package/src/utils/guildExp.js +57 -67
  89. package/src/utils/index.js +13 -13
  90. package/src/utils/isGuildID.js +3 -3
  91. package/src/utils/isUUID.js +5 -5
  92. package/src/utils/oscillation.js +15 -23
  93. package/src/utils/removeSnakeCase.js +22 -35
  94. package/src/utils/rgbToHexColor.js +8 -8
  95. package/src/utils/romanize.js +11 -13
  96. package/src/utils/toIGN.js +20 -20
  97. package/src/utils/toUuid.js +19 -19
  98. package/src/utils/varInt.js +17 -21
  99. package/typings/index.d.ts +3532 -2644
  100. package/src/API/getFriends.js +0 -14
  101. package/src/API/getKeyInfo.js +0 -10
  102. package/src/API/getRankedSkyWars.js +0 -11
  103. package/src/structures/Friend.js +0 -38
  104. package/src/structures/KeyInfo.js +0 -42
  105. package/src/structures/MiniGames/SkyWarsRanked.js +0 -45
package/src/Errors.js CHANGED
@@ -1,39 +1,44 @@
1
- /* eslint-disable max-len */
2
- module.exports = {
3
- INVALID_API_KEY: '[hypixel-api-reborn] Invalid API Key! For help join our Discord Server https://discord.gg/NSEBNMM',
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',
6
- 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!',
12
- NO_NICKNAME_UUID: '[hypixel-api-reborn] No nickname or uuid specified.',
13
- NO_UUID: '[hypixel-api-reborn] No uuid specified.',
14
- UUID_NICKNAME_MUST_BE_A_STRING: '[hypixel-api-reborn] Nickname or uuid must be a string.',
15
- MALFORMED_UUID: '[hypixel-api-reborn] Malformed UUID!',
16
- PLAYER_DOES_NOT_EXIST: '[hypixel-api-reborn] Player does not exist.',
17
- 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',
19
- PLAYER_DISABLED_ENDPOINT: '[hypixel-api-reborn] Player has disabled this endpoint.',
20
- NO_GUILD_QUERY: '[hypixel-api-reborn] No guild search query specified.',
21
- INVALID_GUILD_ID: '[hypixel-api-reborn] Specified Guild ID is invalid.',
22
- INVALID_GUILD_SEARCH_PARAMETER: '[hypixel-api-reborn] getGuild() searchParameter must be \'id\', \'guild\' or \'player\'.',
23
- SOMETHING_WENT_WRONG: '[hypixel-api-reborn] Something went wrong. {cause}',
24
- 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.',
30
- INVALID_HEADER_SYNC_OPTION: '[hypixel-api-reborn] Invalid Value for maxSyncHeaders : must be a boolean',
31
- 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.',
33
- UPDATER_REQUEST_NOT_OK: '[hypixel-api-reborn] An error occured checking for updates.',
34
- 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.',
36
- MULTIPLE_INSTANCES: '[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.',
37
- INVALID_HEADERS: '[hypixel-api-reborn] Invalid Headers are provided in ClientOptions. For help join our Discord Server https://discord.gg/NSEBNMM',
38
- INVALID_CACHE_HANDLER: '[hypixel-api-reborn] An invalid cache handler is provideed. For help join our Discord Server https://discord.gg/NSEBNMM'
39
- };
1
+ /* eslint-disable max-len */
2
+ module.exports = {
3
+ INVALID_API_KEY: '[hypixel-api-reborn] Invalid API Key! For help join our Discord Server https://discord.gg/NSEBNMM',
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',
6
+ 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!',
12
+ NO_NICKNAME_UUID: '[hypixel-api-reborn] No nickname or uuid specified.',
13
+ NO_UUID: '[hypixel-api-reborn] No uuid specified.',
14
+ UUID_NICKNAME_MUST_BE_A_STRING: '[hypixel-api-reborn] Nickname or uuid must be a string.',
15
+ MALFORMED_UUID: '[hypixel-api-reborn] Malformed UUID!',
16
+ PLAYER_DOES_NOT_EXIST: '[hypixel-api-reborn] Player does not exist.',
17
+ 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",
19
+ PLAYER_DISABLED_ENDPOINT: '[hypixel-api-reborn] Player has disabled this endpoint.',
20
+ NO_GUILD_QUERY: '[hypixel-api-reborn] No guild search query specified.',
21
+ INVALID_GUILD_ID: '[hypixel-api-reborn] Specified Guild ID is invalid.',
22
+ INVALID_GUILD_SEARCH_PARAMETER: "[hypixel-api-reborn] getGuild() searchParameter must be 'id', 'guild' or 'player'.",
23
+ SOMETHING_WENT_WRONG: '[hypixel-api-reborn] Something went wrong. {cause}',
24
+ 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.',
30
+ INVALID_HEADER_SYNC_OPTION: '[hypixel-api-reborn] Invalid Value for maxSyncHeaders : must be a boolean',
31
+ 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.",
33
+ UPDATER_REQUEST_NOT_OK: '[hypixel-api-reborn] An error occurred checking for updates.',
34
+ 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.',
36
+ MULTIPLE_INSTANCES:
37
+ '[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',
40
+ UNEXPECTED_ERROR:
41
+ "[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
+ 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"
44
+ };
@@ -1,78 +1,77 @@
1
- /**
2
- * This is the default cache implementation, using a Map.
3
- * All cache implementations must have these methods below, they can be async :
4
- * set(key, value) : Sets key to value
5
- * has(key) : Whether there is an entry to this key. (can be an alias to get)
6
- * get(key) : Gets by key (nullish value if not found)
7
- * delete(key) : Deletes by key
8
- * keys() : Array of keys, ordered by time of creation. To help you, the key will be deleted and set in case of an update
9
- * size(): Size of cache (number of keys)
10
- * clear(): Deletes all cache entries
11
- * See JSDoc for more info
12
- */
13
- class Cache {
14
- /**
15
- * Constructor
16
- */
17
- constructor() {
18
- this.storage = new Map();
19
- }
20
- /**
21
- * Sets an entry
22
- * @param {string} key String key
23
- * @param {*} value Any value
24
- * @return {boolean}
25
- */
26
- set(key, value) {
27
- return this.storage.set(key, value);
28
- }
29
- /**
30
- * Check if there's an entry in the cache that has this key
31
- * This doesn't have to return boolean, just a truthy/falsy value
32
- * @param {string} key String key
33
- * @return {boolean} Whether this key exists
34
- */
35
- has(key) {
36
- return this.storage.has(key);
37
- }
38
- /**
39
- * Gets an entry, return a nullish value if not found
40
- * @param {string} key String key
41
- * @return {*}
42
- */
43
- get(key) {
44
- return this.storage.get(key);
45
- }
46
- /**
47
- * Deletes an entry
48
- * @param {string} key String key
49
- * @return {boolean} Preferably, returns a boolean to check if the deletion is actually successful
50
- */
51
- delete(key) {
52
- return this.storage.delete(key);
53
- }
54
- /**
55
- * Returns Array of string (not an iterator preferably, it can break)
56
- * @return {string[]}
57
- */
58
- keys() {
59
- return Array.from(this.storage.keys());
60
- }
61
- /**
62
- * Returns size of cache
63
- * @return {number}
64
- */
65
- size() {
66
- return this.storage.size;
67
- }
68
- /**
69
- * Clears cache
70
- * @return {void}
71
- */
72
- clear() {
73
- this.storage.clear();
74
- }
75
- }
76
-
77
- module.exports = Cache;
78
-
1
+ /**
2
+ * This is the default cache implementation, using a Map.
3
+ * All cache implementations must have these methods below, they can be async :
4
+ * set(key, value) : Sets key to value
5
+ * has(key) : Whether there is an entry to this key. (can be an alias to get)
6
+ * get(key) : Gets by key (nullish value if not found)
7
+ * delete(key) : Deletes by key
8
+ * keys() : Array of keys, ordered by time of creation. To help you, the key will be deleted and set in case of an update
9
+ * size(): Size of cache (number of keys)
10
+ * clear(): Deletes all cache entries
11
+ * See JSDoc for more info
12
+ */
13
+ class Cache {
14
+ /**
15
+ * Constructor
16
+ */
17
+ constructor() {
18
+ this.storage = new Map();
19
+ }
20
+ /**
21
+ * Sets an entry
22
+ * @param {string} key String key
23
+ * @param {*} value Any value
24
+ * @return {boolean}
25
+ */
26
+ set(key, value) {
27
+ return this.storage.set(key, value);
28
+ }
29
+ /**
30
+ * Check if there's an entry in the cache that has this key
31
+ * This doesn't have to return boolean, just a truthy/falsy value
32
+ * @param {string} key String key
33
+ * @return {boolean} Whether this key exists
34
+ */
35
+ has(key) {
36
+ return this.storage.has(key);
37
+ }
38
+ /**
39
+ * Gets an entry, return a nullish value if not found
40
+ * @param {string} key String key
41
+ * @return {*}
42
+ */
43
+ get(key) {
44
+ return this.storage.get(key);
45
+ }
46
+ /**
47
+ * Deletes an entry
48
+ * @param {string} key String key
49
+ * @return {boolean} Preferably, returns a boolean to check if the deletion is actually successful
50
+ */
51
+ delete(key) {
52
+ return this.storage.delete(key);
53
+ }
54
+ /**
55
+ * Returns Array of string (not an iterator preferably, it can break)
56
+ * @return {string[]}
57
+ */
58
+ keys() {
59
+ return Array.from(this.storage.keys());
60
+ }
61
+ /**
62
+ * Returns size of cache
63
+ * @return {number}
64
+ */
65
+ size() {
66
+ return this.storage.size;
67
+ }
68
+ /**
69
+ * Clears cache
70
+ * @return {void}
71
+ */
72
+ clear() {
73
+ this.storage.clear();
74
+ }
75
+ }
76
+
77
+ module.exports = Cache;
@@ -1,98 +1,79 @@
1
- /* eslint-disable @typescript-eslint/no-empty-function */
2
- /* eslint-disable camelcase */
3
- const Errors = require('../Errors');
4
-
5
- /* eslint-disable require-jsdoc */
6
- module.exports = class RateLimit {
7
- constructor () {
8
- this.initialized = 0;
9
- }
10
-
11
- async rateLimitManager () {
12
- if (!this.initialized) return;
13
- this.requests++;
14
- 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;
17
- const cooldown = this.computeCooldownTime();
18
- this.requestQueue[0] = Date.now() + cooldown;
19
- await new Promise((r) => setTimeout(r, cooldown), true);
20
- return;
21
- }
22
-
23
- sync (data) {
24
- this.options.keyLimit = parseInt(data.get('ratelimit-limit'), 10) || this.options.keyLimit;
25
- this.requests = parseInt(data.get('ratelimit-remaining'), 10) || this.requests;
26
- if (data.get('ratelimit-reset') && Math.round(Date.now() / 1000) - (60 - parseInt(data.get('ratelimit-reset'), 10)) !== Math.round(this.lastResetHappenedAt / 1000)) {
27
- clearTimeout(this.resetTimer);
28
- this.resetTimer = setTimeout(this.reset.bind(this), parseInt(data.get('ratelimit-reset'), 10) * 1000);
29
- }
30
- }
31
-
32
- computeCooldownTime () {
33
- const overhead = this.requestQueue[1] <= Date.now() ? 0 : this.requestQueue[1] - Date.now();
34
- const multiplier = Math.floor(this.requests / this.options.keyLimit) + 1;
35
- return overhead + (- overhead - Date.now() + 60000 * multiplier + this.lastResetHappenedAt) / (this.options.keyLimit * multiplier - this.requests);
36
- }
37
-
38
- reset () {
39
- this.requests = this.requests - this.options.keyLimit;
40
- if (this.requests < 0) this.requests = 0;
41
- this.lastResetHappenedAt = Date.now();
42
- this.resetTimer = setTimeout(this.reset.bind(this), 60000);
43
- this.requestQueue = this.requestQueue.filter((x) => x >= Date.now());
44
- }
45
-
46
- rateLimitMonitor () {
47
- this.resetTimer = setTimeout(this.reset.bind(this), 1000 * 60);
48
- }
49
-
50
- init (keyInfo, options, client) {
51
- /**
52
- * Rate limit Options
53
- * @type {RLOptions}
54
- */
55
- this.options = options;
56
- /**
57
- * Requests in past min
58
- * @type {number}
59
- */
60
- this.requests = 0;
61
- /**
62
- * Cooldown
63
- * @type {number}
64
- */
65
- this.cooldownTime = 60000 / this.options.keyLimit; // Initial value
66
- /**
67
- * Request Queue ( Array of timestamps )
68
- * @type {number[]}
69
- */
70
- this.requestQueue = [];
71
- /**
72
- * Client
73
- * @type {Client}
74
- */
75
- this.client = client;
76
- return keyInfo
77
- .then((info) => {
78
- this.requests = info.requestsInPastMin;
79
- this.lastResetHappenedAt = Date.now() - (60 - info.resetsAfter) * 1000; // Computed reset time
80
- this.resetTimer = setTimeout(this.rateLimitMonitor.bind(this), 1000 * info.resetsAfter);
81
- this.initialized = 1;
82
- })
83
- .catch(() => {
84
- client.emit('warn', Errors.RATE_LIMIT_INIT_ERROR);
85
- this.requests = 0;
86
- this.lastResetHappenedAt = Date.now();
87
- this.rateLimitMonitor();
88
- this.initialized = 1;
89
- });
90
- // Still make the requests per min possible
91
- }
92
- };
93
- /**
94
- * @typedef {Object} RLOptions
95
- * @property {number} keyLimit Max request of key per min
96
- * @property {NONE|AUTO|HARD} rateLimit rate limit mode
97
- * @property {boolean} syncWithHeaders Sync rate limits with headers
98
- */
1
+ /* eslint-disable @typescript-eslint/no-empty-function */
2
+ /* eslint-disable camelcase */
3
+ const Errors = require('../Errors');
4
+
5
+ /* eslint-disable require-jsdoc */
6
+ class RateLimit {
7
+ constructor() {
8
+ this.initialized = 0;
9
+ }
10
+
11
+ async rateLimitManager() {
12
+ if (!this.initialized) return;
13
+ this.requests++;
14
+ 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;
17
+ const cooldown = this.computeCooldownTime();
18
+ this.requestQueue[0] = Date.now() + cooldown;
19
+ await new Promise((r) => setTimeout(r, cooldown), true);
20
+ return;
21
+ }
22
+
23
+ sync(data) {
24
+ this.options.keyLimit = parseInt(data.get('ratelimit-limit'), 10) || this.options.keyLimit;
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)) {
27
+ clearTimeout(this.resetTimer);
28
+ this.resetTimer = setTimeout(this.reset.bind(this), parseInt(data.get('ratelimit-reset'), 10) * 1000);
29
+ }
30
+ }
31
+
32
+ computeCooldownTime() {
33
+ const overhead = this.requestQueue[1] <= Date.now() ? 0 : this.requestQueue[1] - Date.now();
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);
36
+ }
37
+
38
+ reset() {
39
+ this.requests = this.requests - this.options.keyLimit;
40
+ if (this.requests < 0) this.requests = 0;
41
+ this.lastResetHappenedAt = Date.now();
42
+ this.resetTimer = setTimeout(this.reset.bind(this), 300000);
43
+ this.requestQueue = this.requestQueue.filter((x) => x >= Date.now());
44
+ }
45
+
46
+ rateLimitMonitor() {
47
+ this.resetTimer = setTimeout(this.reset.bind(this), 1000 * 300);
48
+ }
49
+
50
+ init(keyInfo, options, client) {
51
+ this.options = options;
52
+ this.requests = 0;
53
+ this.cooldownTime = 300000 / this.options.keyLimit; // Initial value
54
+ this.requestQueue = [];
55
+ this.client = client;
56
+ return keyInfo
57
+ .then((info) => {
58
+ this.requests = info.requestsInPastMin;
59
+ this.lastResetHappenedAt = Date.now() - (300 - info.resetsAfter) * 1000; // Computed reset time
60
+ this.resetTimer = setTimeout(this.rateLimitMonitor.bind(this), 1000 * info.resetsAfter);
61
+ this.initialized = 1;
62
+ })
63
+ .catch(() => {
64
+ client.emit('warn', Errors.RATE_LIMIT_INIT_ERROR);
65
+ this.requests = 0;
66
+ this.lastResetHappenedAt = Date.now();
67
+ this.rateLimitMonitor();
68
+ this.initialized = 1;
69
+ });
70
+ // Still make the requests per min possible
71
+ }
72
+ }
73
+ module.exports = RateLimit;
74
+ /**
75
+ * @typedef {Object} RLOptions
76
+ * @property {number} keyLimit Max request of key per min
77
+ * @property {NONE|AUTO|HARD} rateLimit rate limit mode
78
+ * @property {boolean} syncWithHeaders Sync rate limits with headers
79
+ */
@@ -1,54 +1,65 @@
1
- /* eslint-disable require-jsdoc */
2
- const fetch = require('node-fetch');
3
- const BASE_URL = 'https://api.hypixel.net';
4
- const Errors = require('../Errors');
5
- const Cache = require('./defaultCache');
6
-
7
- module.exports = class Requests {
8
- constructor(client, cache) {
9
- if (cache && !this.validateCustomCache()) throw new Error(Errors.INVALID_CACHE_HANDLER);
10
- /**
11
- * @type {Cache}
12
- */
13
- this.cached = cache || new Cache();
14
- this.client = client;
15
- }
16
- async request (endpoint, options = {}) {
17
- options.headers = {'API-Key': this.client.key, ...options.headers};
18
- const res = await fetch(BASE_URL + endpoint, options);
19
- if (res.status >= 500 && res.status < 528) throw new Error(Errors.ERROR_STATUSTEXT.replace(/{statustext}/, `Server Error : ${res.status} ${res.statusText}`));
20
- const parsedRes = await res.json().catch(() => {
21
- throw new Error(Errors.INVALID_RESPONSE_BODY);
22
- });
23
- if (res.status === 400) throw new Error(Errors.ERROR_CODE_CAUSE.replace(/{code}/, '400 Bad Request').replace(/{cause}/, (parsedRes.cause || '')));
24
- if (res.status === 403) throw new Error(Errors.INVALID_API_KEY);
25
- if (res.status !== 200) throw new Error(Errors.ERROR_STATUSTEXT.replace(/{statustext}/, res.statusText));
26
- if (!parsedRes.success) {
27
- throw new Error(Errors.SOMETHING_WENT_WRONG.replace(/{cause}/, res.cause));
28
- }
29
- parsedRes._headers = res.headers;
30
- parsedRes.raw = !!options.raw;
31
- if (options.noCaching) return parsedRes;
32
- // split by question mark : first part is /path, remove /
33
- if (this.client.options.cache && this.client.options.cacheFilter(endpoint.split('?')[0].slice(1))) {
34
- if (this.client.options.cacheSize < await this.cached.size()) await this.cached.delete(Array.from(await this.cached.keys())[0]);
35
- await this.cached.delete(endpoint);
36
- await this.cached.set(endpoint, parsedRes);
37
- if (this.client.options.cacheTime >= 0) setTimeout(() => this.cached.delete(endpoint), 1000 * this.client.options.cacheTime);
38
- }
39
- return parsedRes;
40
- }
41
-
42
- get cache () {
43
- return this.cached;
44
- }
45
-
46
- async sweepCache (amount) {
47
- if (!amount || amount >= await this.cached.size()) return await this.cached.clear();
48
- return await Promise.all(Array.from(await this.cached.keys()).slice(await this.cached.size() - amount).map((x) => this.cached.delete(x)));
49
- }
50
-
51
- validateCustomCache(cache) {
52
- return !!(cache.set && cache.get && cache.delete && cache.keys);
53
- }
54
- };
1
+ /* eslint-disable require-jsdoc */
2
+ const requireFetch = !globalThis.fetch;
3
+ const externalFetch = require('node-fetch');
4
+ const BASE_URL = 'https://api.hypixel.net';
5
+ const Errors = require('../Errors');
6
+ const Cache = require('./defaultCache');
7
+ const Client = require('../Client.js');
8
+
9
+ class Requests {
10
+ constructor(client, cache) {
11
+ if (cache && !this.validateCustomCache()) throw new Error(Errors.INVALID_CACHE_HANDLER);
12
+ this.cached = cache || new Cache();
13
+ this.client = client;
14
+ }
15
+ async request(endpoint, options = {}) {
16
+ options.headers = { 'API-Key': this.client.key, ...options.headers };
17
+ const fetchMethod = requireFetch ? externalFetch : fetch;
18
+ /**
19
+ * @type {externalFetch.Response|Response}
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}`));
23
+ const parsedRes = await res.json().catch(() => {
24
+ throw new Error(Errors.INVALID_RESPONSE_BODY);
25
+ });
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));
31
+ if (!parsedRes.success) {
32
+ throw new Error(Errors.SOMETHING_WENT_WRONG.replace(/{cause}/, res.cause));
33
+ }
34
+ parsedRes._headers = res.headers;
35
+ parsedRes.raw = !!options.raw;
36
+ if (options.noCaching) return parsedRes;
37
+ // split by question mark : first part is /path, remove /
38
+ 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]);
40
+ await this.cached.delete(endpoint);
41
+ await this.cached.set(endpoint, parsedRes);
42
+ if (this.client.options.cacheTime >= 0) setTimeout(() => this.cached.delete(endpoint), 1000 * this.client.options.cacheTime);
43
+ }
44
+ return parsedRes;
45
+ }
46
+
47
+ get cache() {
48
+ return this.cached;
49
+ }
50
+
51
+ async sweepCache(amount) {
52
+ if (!amount || amount >= (await this.cached.size())) return await this.cached.clear();
53
+ return await Promise.all(
54
+ Array.from(await this.cached.keys())
55
+ .slice((await this.cached.size()) - amount)
56
+ .map((x) => this.cached.delete(x))
57
+ );
58
+ }
59
+
60
+ validateCustomCache(cache) {
61
+ return !!(cache.set && cache.get && cache.delete && cache.keys);
62
+ }
63
+ }
64
+
65
+ module.exports = Requests;
@@ -1,45 +1,45 @@
1
- /* eslint-disable no-console */
2
- /* eslint-disable require-jsdoc */
3
- const fetch = require('node-fetch');
4
- const Errors = require('../Errors');
5
- class Updater {
6
- async checkForUpdates () {
7
- const currentVersion = require('../../package.json').version;
8
- const request = await fetch('https://registry.npmjs.org/hypixel-api-reborn');
9
- if (!request.ok) return console.log(Errors.UPDATER_REQUEST_NOT_OK);
10
- const metadata = await request.json();
11
- const latestVersion = metadata['dist-tags'].latest;
12
- const compare = this.compare(currentVersion, latestVersion);
13
- if (compare === -1) {
14
- this.notify(latestVersion);
15
- }
16
- }
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
- compare (a, b) {
32
- const pa = a.split('.');
33
- const pb = b.split('.');
34
- for (let i = 0; i < 3; i++) {
35
- const na = Number(pa[i]);
36
- const nb = Number(pb[i]);
37
- if (na > nb) return 1;
38
- if (nb > na) return -1;
39
- if (!isNaN(na) && isNaN(nb)) return 1;
40
- if (isNaN(na) && !isNaN(nb)) return -1;
41
- }
42
- return 0;
43
- }
44
- }
45
- module.exports = Updater;
1
+ /* eslint-disable no-console */
2
+ /* eslint-disable require-jsdoc */
3
+ const fetch = require('node-fetch');
4
+ const Errors = require('../Errors');
5
+ class Updater {
6
+ async checkForUpdates() {
7
+ const currentVersion = require('../../package.json').version;
8
+ const request = await fetch('https://registry.npmjs.org/hypixel-api-reborn');
9
+ if (!request.ok) return console.log(Errors.UPDATER_REQUEST_NOT_OK);
10
+ const metadata = await request.json();
11
+ const latestVersion = metadata['dist-tags'].latest;
12
+ const compare = this.compare(currentVersion, latestVersion);
13
+ if (compare === -1) {
14
+ this.notify(latestVersion);
15
+ }
16
+ }
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
+ compare(a, b) {
32
+ const pa = a.split('.');
33
+ const pb = b.split('.');
34
+ for (let i = 0; i < 3; i++) {
35
+ const na = Number(pa[i]);
36
+ const nb = Number(pb[i]);
37
+ if (na > nb) return 1;
38
+ if (nb > na) return -1;
39
+ if (!isNaN(na) && isNaN(nb)) return 1;
40
+ if (isNaN(na) && !isNaN(nb)) return -1;
41
+ }
42
+ return 0;
43
+ }
44
+ }
45
+ module.exports = Updater;