hypixel-api-reborn 11.1.0 → 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 (93) hide show
  1. package/.prettierrc +3 -3
  2. package/README.md +5 -3
  3. package/package.json +20 -18
  4. package/src/API/getAchievements.js +6 -0
  5. package/src/API/getChallenges.js +6 -0
  6. package/src/API/getGuild.js +1 -1
  7. package/src/API/getGuildAchievements.js +6 -0
  8. package/src/API/getLeaderboards.js +3 -1
  9. package/src/API/getPlayer.js +1 -1
  10. package/src/API/getQuests.js +6 -0
  11. package/src/API/getRecentGames.js +1 -1
  12. package/src/API/getServerInfo.js +3 -1
  13. package/src/API/getStatus.js +1 -1
  14. package/src/API/index.js +28 -17
  15. package/src/API/skyblock/getAuction.js +19 -0
  16. package/src/API/skyblock/{getSkyblockAuctions.js → getAuctions.js} +6 -2
  17. package/src/API/skyblock/{getSkyblockAuctionsByPlayer.js → getAuctionsByPlayer.js} +1 -1
  18. package/src/API/skyblock/getBingo.js +8 -0
  19. package/src/API/skyblock/getBingoByPlayer.js +14 -0
  20. package/src/API/skyblock/getFireSales.js +7 -0
  21. package/src/API/skyblock/getGovernment.js +8 -0
  22. package/src/API/skyblock/{getSkyblockMember.js → getMember.js} +9 -3
  23. package/src/API/skyblock/getMuseum.js +14 -0
  24. package/src/API/skyblock/{getSkyblockProfiles.js → getProfiles.js} +13 -7
  25. package/src/Client.js +88 -14
  26. package/src/Errors.js +38 -17
  27. package/src/Private/rateLimit.js +10 -2
  28. package/src/Private/requests.js +19 -7
  29. package/src/Private/updater.js +9 -5
  30. package/src/Private/uuidCache.js +23 -29
  31. package/src/Private/validate.js +20 -9
  32. package/src/index.js +9 -0
  33. package/src/structures/APIIncident.js +3 -9
  34. package/src/structures/Boosters/Booster.js +5 -5
  35. package/src/structures/Color.js +93 -48
  36. package/src/structures/Game.js +3 -1
  37. package/src/structures/Guild/Guild.js +21 -17
  38. package/src/structures/Guild/GuildMember.js +6 -6
  39. package/src/structures/Guild/GuildRank.js +2 -2
  40. package/src/structures/MiniGames/Arcade.js +22 -17
  41. package/src/structures/MiniGames/BedWars.js +152 -24
  42. package/src/structures/MiniGames/Duels.js +84 -23
  43. package/src/structures/MiniGames/MegaWalls.js +3 -1
  44. package/src/structures/MiniGames/MurderMystery.js +2 -2
  45. package/src/structures/MiniGames/Pit.js +231 -2
  46. package/src/structures/MiniGames/PitInventoryItem.js +43 -0
  47. package/src/structures/MiniGames/SkyWars.js +19 -14
  48. package/src/structures/MiniGames/SmashHeroes.js +1 -1
  49. package/src/structures/MiniGames/TNTGames.js +1 -1
  50. package/src/structures/MiniGames/UHC.js +21 -3
  51. package/src/structures/Player.js +16 -20
  52. package/src/structures/PlayerCosmetics.js +64 -10
  53. package/src/structures/ServerInfo.js +1 -1
  54. package/src/structures/SkyBlock/Auctions/Auction.js +3 -1
  55. package/src/structures/SkyBlock/Auctions/AuctionInfo.js +1 -0
  56. package/src/structures/SkyBlock/Auctions/BaseAuction.js +1 -0
  57. package/src/structures/SkyBlock/Auctions/Bid.js +1 -0
  58. package/src/structures/SkyBlock/Auctions/PartialAuction.js +1 -0
  59. package/src/structures/SkyBlock/PlayerBingo.js +56 -0
  60. package/src/structures/SkyBlock/SkyblockInventoryItem.js +86 -18
  61. package/src/structures/SkyBlock/SkyblockMember.js +252 -144
  62. package/src/structures/SkyBlock/SkyblockMuseum.js +60 -0
  63. package/src/structures/SkyBlock/SkyblockMuseumItem.js +54 -0
  64. package/src/structures/SkyBlock/SkyblockPet.js +1 -0
  65. package/src/structures/SkyBlock/SkyblockProfile.js +37 -23
  66. package/src/structures/SkyBlock/Static/Bingo.js +102 -0
  67. package/src/structures/SkyBlock/Static/BingoData.js +45 -0
  68. package/src/structures/SkyBlock/Static/Candidate.js +40 -0
  69. package/src/structures/SkyBlock/Static/FireSale.js +55 -0
  70. package/src/structures/SkyBlock/Static/Government.js +74 -0
  71. package/src/structures/SkyBlock/Static/Perk.js +24 -0
  72. package/src/structures/Static/Achievement.js +86 -0
  73. package/src/structures/Static/AchievementTier.js +33 -0
  74. package/src/structures/Static/Achievements.js +30 -0
  75. package/src/structures/Static/Challenges.js +29 -0
  76. package/src/structures/Static/GameAchievements.js +36 -0
  77. package/src/structures/Static/GameChallenges.js +40 -0
  78. package/src/structures/Static/GameQuests.js +24 -0
  79. package/src/structures/Static/GuildAchievements.js +34 -0
  80. package/src/structures/Static/Quest.js +66 -0
  81. package/src/structures/Static/Quests.js +31 -0
  82. package/src/structures/Status.js +2 -2
  83. package/src/utils/Constants.js +382 -41
  84. package/src/utils/SkyblockUtils.js +12 -7
  85. package/src/utils/guildExp.js +4 -1
  86. package/src/utils/removeSnakeCase.js +9 -2
  87. package/src/utils/romanize.js +32 -1
  88. package/src/utils/toIGN.js +6 -2
  89. package/src/utils/toUuid.js +10 -5
  90. package/typings/index.d.ts +985 -295
  91. /package/src/API/skyblock/{getSkyblockBazaar.js → getBazaar.js} +0 -0
  92. /package/src/API/skyblock/{getEndedSkyblockAuctions.js → getEndedAuctions.js} +0 -0
  93. /package/src/API/skyblock/{getSkyblockNews.js → getNews.js} +0 -0
@@ -0,0 +1,54 @@
1
+ const SkyblockInventoryItem = require('./SkyblockInventoryItem');
2
+ /**
3
+ * Item class
4
+ */
5
+ class SkyblockMuseumItem {
6
+ /**
7
+ * @param {object} data Item data
8
+ */
9
+ constructor(data) {
10
+ /**
11
+ * Item name
12
+ * @type {string|null}
13
+ **/
14
+ this.name = data.name;
15
+ /**
16
+ * Item
17
+ * @type {SkyblockInventoryItem}
18
+ */
19
+ this.items = [];
20
+ data.decoded.forEach((item) => {
21
+ if (!item.tag) return;
22
+ this.items.push(new SkyblockInventoryItem(item));
23
+ });
24
+ /**
25
+ * Donated Time
26
+ * @type {number}
27
+ */
28
+ this.donatedTime = data.donatedTime;
29
+ /**
30
+ * Donated Time as Date
31
+ * @type {Date}
32
+ */
33
+ this.donatedTimeAt = new Date(data.donatedTime);
34
+ /**
35
+ * Borrowing
36
+ * @type {boolean}
37
+ */
38
+ this.borrowing = data.borrowing;
39
+ /**
40
+ * Featured Slot
41
+ * @type {string|null}
42
+ */
43
+ this.featuredSlot = data.featuredSlot;
44
+ }
45
+ /**
46
+ * Item Name
47
+ * @return {string}
48
+ */
49
+ toString() {
50
+ return this.name;
51
+ }
52
+ }
53
+
54
+ module.exports = SkyblockMuseumItem;
@@ -38,6 +38,7 @@ class SkyblockPet {
38
38
  * Skyblock Pet score
39
39
  * @type {number}
40
40
  */
41
+ // eslint-disable-next-line camelcase
41
42
  this.petScore = pet_score[data.tier] || 0;
42
43
  /**
43
44
  * Skyblock Pet held item
@@ -12,27 +12,55 @@ class SkyblockProfile {
12
12
  * Skyblock profile ID
13
13
  * @type {string}
14
14
  */
15
- this.profileId = data.profile_id;
15
+ this.profileId = data.profileId;
16
16
  /**
17
17
  * Skyblock profile name
18
18
  * @type {string}
19
19
  */
20
- this.profileName = data.profile_name;
20
+ this.profileName = data.profileName;
21
21
  /**
22
- * Skyblock profile members
23
- * @type {SkyblockMember[]}
22
+ * Profile's gamemode
23
+ * @type {string|null}
24
24
  */
25
- this.members = edit(data.members, this.profileName).map((m) => new SkyblockMember(m));
25
+ this.gameMode = data.gameMode;
26
26
  /**
27
- * Queried player's member stats
28
- * @type {SkyblockMember}
27
+ * Profile's banking
28
+ * @type {object}
29
29
  */
30
- this.me = this.members.find((x) => x.uuid === data.me);
30
+ this.banking = data.banking;
31
31
  /**
32
- * Is the profile selected
32
+ * Profile's community upgrades
33
+ * @type {object}
34
+ */
35
+ this.communityUpgrades = data.communityUpgrades;
36
+ /**
37
+ * Profile is selected
33
38
  * @type {boolean}
34
39
  */
35
40
  this.selected = data.selected;
41
+ /**
42
+ * Skyblock profile members
43
+ * @type {SkyblockMember[]}
44
+ */
45
+ this.members = Object.keys(data.members).map(
46
+ (uuid) =>
47
+ new SkyblockMember({
48
+ uuid: uuid,
49
+ profileId: this.profileId,
50
+ profileName: this.profileName,
51
+ gameMode: this.gameMode,
52
+ m: data.members[uuid],
53
+ banking: this.banking,
54
+ communityUpgrades: this.communityUpgrades,
55
+ museum: null,
56
+ selected: this.selected
57
+ })
58
+ );
59
+ /**
60
+ * Queried player's member stats
61
+ * @type {SkyblockMember}
62
+ */
63
+ this.me = this.members.find((x) => x.uuid === data.uuid);
36
64
  }
37
65
  /**
38
66
  * Profile Name
@@ -43,18 +71,4 @@ class SkyblockProfile {
43
71
  }
44
72
  }
45
73
 
46
- // eslint-disable-next-line require-jsdoc
47
- function edit(members, profileName) {
48
- const edited = [];
49
- Object.keys(members).forEach((k) => {
50
- const m = members[k];
51
- edited.push({
52
- uuid: k,
53
- profileName,
54
- m
55
- });
56
- });
57
- return edited;
58
- }
59
-
60
74
  module.exports = SkyblockProfile;
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Bingo class
3
+ */
4
+ class Bingo {
5
+ /**
6
+ * Constructor
7
+ * @param {Object} data data
8
+ * @param {number} position Position
9
+ */
10
+ constructor(data, position = 0) {
11
+ /**
12
+ * Name of this bingo goal
13
+ * @type {string}
14
+ */
15
+ this.name = data.name;
16
+ /**
17
+ * string ID (code name)
18
+ * @type {string}
19
+ */
20
+ this.id = data.id;
21
+ const [row, column] = parsePosition(position);
22
+ /**
23
+ * 1-indexed row
24
+ * @type {number|null}
25
+ */
26
+ this.row = row;
27
+ /**
28
+ * 1-indexed colmun
29
+ * @type {number|null}
30
+ */
31
+ this.column = column;
32
+ /**
33
+ * Bingo lore, with color codes
34
+ * @type {string}
35
+ */
36
+ this.rawLore = data.lore;
37
+ /**
38
+ * Bingo lore in plain text
39
+ * @type {string}
40
+ */
41
+ this.lore = data.lore?.replace?.(/§([1-9]|[a-l])|§/gm, '') || null;
42
+ /**
43
+ * Only available for TIERED bingos
44
+ * Shows you the requirement for each tier of this achievement
45
+ * @type {number[]}
46
+ */
47
+ this.tiers = Array.isArray(data.tiers) ? data.tiers.map((x) => parseInt(x, 10) || 0) : null;
48
+ /**
49
+ * Only available for TIERED bingos
50
+ * Difference between each tier requirement, if it is constant
51
+ * @type {number|null}
52
+ */
53
+ this.tierStep = this.#getTierStep();
54
+ /**
55
+ * Only available for ONE_TIERED bingos
56
+ * @type {number|null}
57
+ */
58
+ this.requiredAmount = parseInt(data.requiredAmount, 10) ?? null;
59
+ /**
60
+ * Type of Bingo
61
+ * ONE_TIME means the goal doesn't have a specific amount
62
+ * ONE_TIER means the goal specifies 1 amount to achieve
63
+ * TIERED means the goal specifies more than 1 amount to achieve
64
+ * @type {'ONE_TIME'|'ONE_TIER'|'TIERED'}
65
+ */
66
+ this.type = this.tiers ? 'TIERED' : this.requiredAmount ? 'ONE_TIER' : 'ONE_TIME';
67
+ }
68
+ /**
69
+ * As string
70
+ * BEWARE this returns ID to assure compatibility with PlayerBingo
71
+ * @return {string}
72
+ */
73
+ toString() {
74
+ return this.id;
75
+ }
76
+ /**
77
+ * Gets tier step, if constant
78
+ * @private
79
+ * @returns {number|null}
80
+ */
81
+ #getTierStep() {
82
+ if (this.type !== 'TIERED') return null;
83
+ // No step possible
84
+ if (this.tiers.length < 2) return null;
85
+ const hypotheticStep = this.tiers[1] - this.tiers[0];
86
+ // Check if every 2 elements have the same step
87
+ const isConstant = this.tiers.slice(1).every((el, index) => {
88
+ return hypotheticStep === this.tiers[index - 1] - el;
89
+ });
90
+ if (!isConstant) return null;
91
+ return hypotheticStep;
92
+ }
93
+ }
94
+
95
+ // eslint-disable-next-line require-jsdoc
96
+ function parsePosition(position) {
97
+ const x = (position % 5) + 1;
98
+ const y = Math.floor(position / 5) + 1;
99
+ return [x, y];
100
+ }
101
+
102
+ module.exports = Bingo;
@@ -0,0 +1,45 @@
1
+ const Bingo = require('./Bingo.js');
2
+
3
+ /**
4
+ * SB Bingo Class
5
+ */
6
+ class BingoData {
7
+ /**
8
+ * constructor
9
+ * @param {Object} data
10
+ */
11
+ constructor(data) {
12
+ /**
13
+ * Last time this resource was updated
14
+ * @type {number}
15
+ */
16
+ this.lastUpdatedTimestamp = parseInt(data.lastUpdated, 10);
17
+ /**
18
+ * Last time this resource was updated, as Date
19
+ * @type {Date|null}
20
+ */
21
+ this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp);
22
+ /**
23
+ * Bingo ID
24
+ * @type {number|null}
25
+ */
26
+ this.id = parseInt(data.id, 10) || null;
27
+ /**
28
+ * Goals
29
+ * @type {Bingo[]|null}
30
+ */
31
+ this.goals = Array.isArray(data.goals) ? data.goals.map((goal, index) => new Bingo(goal, index)) : null;
32
+ }
33
+ /**
34
+ * Gets a goal on the bingo table by row and column
35
+ * @param {number} column Column number (starts at 1)
36
+ * @param {number} row Row number (starts at 1)
37
+ * @returns {Bingo|undefined}
38
+ */
39
+ getGoal(column, row) {
40
+ if (!this.goals || this.goals.length < 1) return;
41
+ return this.goals.find((goal) => goal.row === row && goal.column === column);
42
+ }
43
+ }
44
+
45
+ module.exports = BingoData;
@@ -0,0 +1,40 @@
1
+ const Perk = require('./Perk');
2
+ /**
3
+ * Candidate class
4
+ */
5
+ class Candidate {
6
+ /**
7
+ * Constructor
8
+ * @param {Object} data data
9
+ * @param {boolean} [isMayor=false] if this candidate is the current mayor
10
+ */
11
+ constructor(data, isMayor = false) {
12
+ /**
13
+ * Mayor's name
14
+ * @type {string}
15
+ */
16
+ this.name = data.name;
17
+ /**
18
+ * Mayor's Key Benefit (in 1 word)
19
+ * @type {string}
20
+ */
21
+ this.keyBenefit = data.key;
22
+ /**
23
+ * Perks
24
+ * @type {Perk[]}
25
+ */
26
+ this.perks = data.perks.map((x) => new Perk(x));
27
+ /**
28
+ * If this candidate is the current mayor
29
+ * @type {boolean}
30
+ */
31
+ this.isMayor = isMayor || false;
32
+ /**
33
+ * The number of votes received by this candidate
34
+ * @type {number}
35
+ */
36
+ this.votesReceived = parseInt(data.votes, 10) || 0;
37
+ }
38
+ }
39
+
40
+ module.exports = Candidate;
@@ -0,0 +1,55 @@
1
+ /**
2
+ * SB Fire Sale
3
+ */
4
+ class FireSale {
5
+ /**
6
+ * constructor
7
+ * @param {Object} data
8
+ */
9
+ constructor(data) {
10
+ /**
11
+ * Item ID
12
+ * @type {string|null}
13
+ */
14
+ this.itemId = data.item_id || null;
15
+ /**
16
+ * Start Timestamp as a unix
17
+ * @type {number}
18
+ */
19
+ this.startTimestamp = parseInt(data.start, 10);
20
+ /**
21
+ * Start Date
22
+ * @type {Date}
23
+ */
24
+ this.startAt = new Date(this.startTimestamp);
25
+ /**
26
+ * End Timestamp as a unix
27
+ * @type {number}
28
+ */
29
+ this.endTimestamp = parseInt(data.end, 10);
30
+ /**
31
+ * End Date
32
+ * @type {Date}
33
+ */
34
+ this.endAt = new Date(this.endTimestamp);
35
+ /**
36
+ * Amount of items being sold
37
+ * @type {number}
38
+ */
39
+ this.amount = data.amount || 0;
40
+ /**
41
+ * Price
42
+ * @type {number}
43
+ */
44
+ this.price = data.price || 0;
45
+ }
46
+ /**
47
+ * Item Id
48
+ * @return {string|null}
49
+ */
50
+ toString() {
51
+ return this.itemId;
52
+ }
53
+ }
54
+
55
+ module.exports = FireSale;
@@ -0,0 +1,74 @@
1
+ const Candidate = require('./Candidate');
2
+
3
+ /**
4
+ * SB Government Class
5
+ */
6
+ class GovernmentData {
7
+ /**
8
+ * constructor
9
+ * @param {Object} data
10
+ */
11
+ constructor(data) {
12
+ /**
13
+ * Last time this resource was updated
14
+ * @type {number}
15
+ */
16
+ this.lastUpdatedTimestamp = parseInt(data.lastUpdated, 10);
17
+ /**
18
+ * Last time this resource was updated, as Date
19
+ * @type {Date|null}
20
+ */
21
+ this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp);
22
+ const lastElectionResults = data.mayor.election.candidates.map((x) => new Candidate(x, x.name === data.mayor.name));
23
+ /**
24
+ * A map of last election results for each candidate
25
+ * Sorted ascendingly by votes received
26
+ * @type {Map<string, Candidate>}
27
+ */
28
+ this.lastElectionResults = new Map(
29
+ lastElectionResults
30
+ .sort((a, b) => a.votesReceived - b.votesReceived)
31
+ .reverse()
32
+ .map((x) => [x.name, x])
33
+ );
34
+ /**
35
+ * The mayor
36
+ * @type {Candidate}
37
+ */
38
+ this.mayor = this.lastElectionResults.get(data.mayor.name);
39
+ /**
40
+ * The year the mayor will be running for
41
+ * @type {number}
42
+ */
43
+ this.runningYear = parseInt(data.mayor.election.year, 10) || 0;
44
+ const thisElection = data.current?.candidates.map((x) => new Candidate(x, x.name === data.mayor.name)) || null;
45
+ /**
46
+ * Current elections, valid for next year
47
+ * Sorted ascendingly by votes received
48
+ * RESULTS MIGHT BE TEMPORARY
49
+ * @type {Map<string, Candidate>|null}
50
+ */
51
+ this.currentElectionResults = thisElection
52
+ ? new Map(
53
+ thisElection
54
+ .sort((a, b) => a.votesReceived - b.votesReceived)
55
+ .reverse()
56
+ .map((x) => [x.name, x])
57
+ )
58
+ : null;
59
+ /**
60
+ * The year the current election will be effective for
61
+ * @type {number|null}
62
+ */
63
+ this.currentElectionFor = parseInt(data.current?.year, 10) || null;
64
+ }
65
+ /**
66
+ * Current Mayor
67
+ * @return {string}
68
+ */
69
+ toString() {
70
+ return this.mayor.name;
71
+ }
72
+ }
73
+
74
+ module.exports = GovernmentData;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Candidate class
3
+ */
4
+ class Perk {
5
+ /**
6
+ * Constructor
7
+ * @param {Object} data data
8
+ * @param {boolean} [isMayor=false] if this candidate is the current mayor
9
+ */
10
+ constructor(data) {
11
+ /**
12
+ * Perk's Name
13
+ * @type {string}
14
+ */
15
+ this.name = data.name;
16
+ /**
17
+ * Perk's Description
18
+ * @type {string}
19
+ */
20
+ this.description = data.description;
21
+ }
22
+ }
23
+
24
+ module.exports = Perk;
@@ -0,0 +1,86 @@
1
+ const AchievementTier = require('./AchievementTier');
2
+
3
+ /**
4
+ * Achievement Class
5
+ */
6
+ class Achievement {
7
+ /**
8
+ * constructor
9
+ * @param {string} achievementName Name of achievement
10
+ * @param {Object} data
11
+ */
12
+ constructor(achievementName, data) {
13
+ /**
14
+ * Name of achievement, trimmed trailing spaces
15
+ * @type {string}
16
+ */
17
+ this.name = data.name.trim();
18
+ /**
19
+ * Code name of achievement
20
+ * @type {string}
21
+ */
22
+ this.codeName = achievementName;
23
+ /**
24
+ * Description, trimmed trailing spaces
25
+ * @type {string}
26
+ */
27
+ this.description = data.description.trim();
28
+ /**
29
+ * Type of achievement
30
+ * @type {'ONE_TIME'|'TIERED'}
31
+ */
32
+ this.type = data.tiers ? 'TIERED' : 'ONE_TIME';
33
+ /**
34
+ * ONLY AVAILABLE IN PERSONAL ONE TIME ACHIEVEMENTS, last checked April 26th
35
+ * Unlock rate of this achievement
36
+ * Local : Fraction of players that have played the game and gotten this achievement (0 to 1 inclusive)
37
+ * Global : Fraction of players that have played Hypixel and gotten this achievement (0 to 1 inclusive)
38
+ * ...percentage : In percentage (0 to 100 inclusive)
39
+ * @type {Record<'local'|'localPercentage'|'global'|'globalPercentage', number>|null}
40
+ */
41
+ this.rarity = {
42
+ local: parseFloat(data.gamePercentUnlocked) || 0,
43
+ localPercentage: parseFloat(data.gamePercentUnlocked) * 100 || 0,
44
+ global: data.globalPercentUnlocked,
45
+ globalPercentage: parseFloat(data.globalPercentUnlocked) * 100 || 0
46
+ };
47
+ /**
48
+ * ONLY AVAILABLE FOR TIERED
49
+ * @type {AchievementTier|null}
50
+ */
51
+ this.tierInformation = this.type === 'TIERED' ? new AchievementTier(data.tiers) : null;
52
+
53
+ const { totalPoints, totalAmount } = this.type === 'TIERED' ? collectAll(this.tierInformation) : {};
54
+ /**
55
+ * Total points worth (sum of all tiers if tiered)
56
+ * This is always 0 for Guild Achievements
57
+ * @type {number}
58
+ */
59
+ this.points = this.type === 'ONE_TIME' ? parseInt(data.points, 10) : totalPoints;
60
+ /**
61
+ * Total amount required to reach max tier, only for tiered
62
+ * @type {number|null}
63
+ */
64
+ this.totalAmountRequired = this.type === 'TIERED' ? totalAmount : null;
65
+ }
66
+ /**
67
+ * As string
68
+ * @return {string}
69
+ */
70
+ toString() {
71
+ return this.achievementName;
72
+ }
73
+ }
74
+
75
+ // eslint-disable-next-line require-jsdoc
76
+ function collectAll(data) {
77
+ const mTier = data.maxTier;
78
+ let totalPoints = 0;
79
+ let totalAmount = 0;
80
+ for (let i = 1; i <= mTier; i++) {
81
+ totalPoints += data.getTier(i).pointsRewarded;
82
+ totalAmount += data.getTier(i).amountRequired;
83
+ }
84
+ return { totalPoints, totalAmount };
85
+ }
86
+ module.exports = Achievement;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * AchievementTier class
3
+ */
4
+ class AchievementTier {
5
+ /**
6
+ * @param {Record<string, number>} data
7
+ */
8
+ constructor(data) {
9
+ /**
10
+ * Maximum tier reachable
11
+ * getTier will be take any integer from 1 to this number (inclusive)
12
+ * @type {number}
13
+ */
14
+ this.maxTier = data.length;
15
+ // Still make sure it is well sorted
16
+ this._tierInfo = data.sort(({ tier: tierA }, { tier: tierB }) => Number(tierA) - Number(tierB));
17
+ }
18
+ /**
19
+ * Gets information for tier
20
+ * @param {number} tier Tier number (1-indexed!)
21
+ * @returns {Record<'pointsRewarded'|'amountRequired', number>}
22
+ */
23
+ getTier(tier) {
24
+ const index = tier - 1;
25
+ const info = this._tierInfo[index];
26
+ return {
27
+ pointsRewarded: parseInt(info.points, 10) || 0,
28
+ amountRequired: parseInt(info.amount, 10) || 0
29
+ };
30
+ }
31
+ }
32
+
33
+ module.exports = AchievementTier;
@@ -0,0 +1,30 @@
1
+ const GameAchievements = require('./GameAchievements.js');
2
+
3
+ /**
4
+ * Achievement class
5
+ */
6
+ class Achievements {
7
+ /**
8
+ * @param {object} data data
9
+ */
10
+ constructor(data) {
11
+ /**
12
+ * Last time this resource was updated
13
+ * @type {number}
14
+ */
15
+ this.lastUpdatedTimestamp = parseInt(data.lastUpdated, 10);
16
+ /**
17
+ * Last time this resource was updated, as Date
18
+ * @type {Date|null}
19
+ */
20
+ this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp);
21
+ /**
22
+ * @type {Record<StaticGameNames, GameAchievements>}
23
+ */
24
+ this.achievementsPerGame = Object.fromEntries(
25
+ Object.entries(data.achievements).map(([game, data]) => [game, new GameAchievements(game, data)])
26
+ );
27
+ }
28
+ }
29
+
30
+ module.exports = Achievements;
@@ -0,0 +1,29 @@
1
+ const GameChallenges = require('./GameChallenges.js');
2
+ /**
3
+ * Achievement class
4
+ */
5
+ class Challenges {
6
+ /**
7
+ * @param {object} data data
8
+ */
9
+ constructor(data) {
10
+ /**
11
+ * Last time this resource was updated
12
+ * @type {number}
13
+ */
14
+ this.lastUpdatedTimestamp = parseInt(data.lastUpdated, 10);
15
+ /**
16
+ * Last time this resource was updated, as Date
17
+ * @type {Date|null}
18
+ */
19
+ this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp);
20
+ /**
21
+ * @type {Record<StaticGameNames, GameChallenges>}
22
+ */
23
+ this.challengesPerGame = Object.fromEntries(
24
+ Object.entries(data.challenges).map(([game, data]) => [game, new GameChallenges(game, data)])
25
+ );
26
+ }
27
+ }
28
+
29
+ module.exports = Challenges;