osrs-json-hiscores 2.12.0 → 2.12.1

Sign up to get free protection for your applications and to get access to all the features.
package/lib/hiscores.js CHANGED
@@ -1,389 +1,397 @@
1
- "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
- return new (P || (P = Promise))(function (resolve, reject) {
16
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
- step((generator = generator.apply(thisArg, _arguments || [])).next());
20
- });
21
- };
22
- var __generator = (this && this.__generator) || function (thisArg, body) {
23
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
- function verb(n) { return function (v) { return step([n, v]); }; }
26
- function step(op) {
27
- if (f) throw new TypeError("Generator is already executing.");
28
- while (_) try {
29
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
- if (y = 0, t) op = [op[0] & 2, t.value];
31
- switch (op[0]) {
32
- case 0: case 1: t = op; break;
33
- case 4: _.label++; return { value: op[1], done: false };
34
- case 5: _.label++; y = op[1]; op = [0]; continue;
35
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
- default:
37
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
- if (t[2]) _.ops.pop();
42
- _.trys.pop(); continue;
43
- }
44
- op = body.call(thisArg, _);
45
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
- }
48
- };
49
- Object.defineProperty(exports, "__esModule", { value: true });
50
- exports.getActivityPage = exports.getSkillPage = exports.getStatsByGamemode = exports.getStats = exports.parseStats = exports.getRSNFormat = void 0;
51
- var jsdom_1 = require("jsdom");
52
- var utils_1 = require("./utils");
53
- /**
54
- * Screen scrapes the hiscores to get the formatted rsn of a player.
55
- *
56
- * @param rsn Username of the player.
57
- * @returns Formatted version of the rsn.
58
- */
59
- function getRSNFormat(rsn) {
60
- return __awaiter(this, void 0, void 0, function () {
61
- var url, response, dom, anchor, _a;
62
- return __generator(this, function (_b) {
63
- switch (_b.label) {
64
- case 0:
65
- if (typeof rsn !== 'string') {
66
- throw Error('RSN must be a string');
67
- }
68
- else if (!/^[a-zA-Z0-9 _-]+$/.test(rsn)) {
69
- throw Error('RSN contains invalid character');
70
- }
71
- else if (rsn.length > 12 || rsn.length < 1) {
72
- throw Error('RSN must be between 1 and 12 characters');
73
- }
74
- url = utils_1.getPlayerTableURL('main', rsn);
75
- _b.label = 1;
76
- case 1:
77
- _b.trys.push([1, 3, , 4]);
78
- return [4 /*yield*/, utils_1.httpGet(url)];
79
- case 2:
80
- response = _b.sent();
81
- dom = new jsdom_1.JSDOM(response.data);
82
- anchor = dom.window.document.querySelector('.personal-hiscores__row.personal-hiscores__row--type-highlight a');
83
- if (anchor) {
84
- return [2 /*return*/, utils_1.rsnFromElement(anchor)];
85
- }
86
- throw Error('Player not found');
87
- case 3:
88
- _a = _b.sent();
89
- throw Error('Player not found');
90
- case 4: return [2 /*return*/];
91
- }
92
- });
93
- });
94
- }
95
- exports.getRSNFormat = getRSNFormat;
96
- /**
97
- * Parses CSV string of raw stats and returns a stats object.
98
- *
99
- * @param csv Raw CSV from the official OSRS API.
100
- * @returns Parsed stats object.
101
- */
102
- function parseStats(csv) {
103
- var splitCSV = csv
104
- .split('\n')
105
- .filter(function (entry) { return !!entry; })
106
- .map(function (stat) { return stat.split(','); });
107
- if (splitCSV.length !==
108
- utils_1.SKILLS.length + utils_1.BH_MODES.length + utils_1.CLUES.length + utils_1.BOSSES.length + 5) {
109
- throw Error(utils_1.INVALID_FORMAT_ERROR);
110
- }
111
- var skillObjects = splitCSV
112
- .filter(function (stat) { return stat.length === 3; })
113
- .map(function (stat) {
114
- var rank = stat[0], level = stat[1], xp = stat[2];
115
- var skill = {
116
- rank: parseInt(rank, 10),
117
- level: parseInt(level, 10),
118
- xp: parseInt(xp, 10)
119
- };
120
- return skill;
121
- });
122
- var activityObjects = splitCSV
123
- .filter(function (stat) { return stat.length === 2; })
124
- .map(function (stat) {
125
- var rank = stat[0], score = stat[1];
126
- var activity = {
127
- rank: parseInt(rank, 10),
128
- score: parseInt(score, 10)
129
- };
130
- return activity;
131
- });
132
- var leaguePoints = activityObjects.splice(0, 1)[0];
133
- var bhObjects = activityObjects.splice(0, utils_1.BH_MODES.length);
134
- var clueObjects = activityObjects.splice(0, utils_1.CLUES.length);
135
- var _a = activityObjects.splice(0, 4), lastManStanding = _a[0], pvpArena = _a[1], soulWarsZeal = _a[2], riftsClosed = _a[3];
136
- var bossObjects = activityObjects.splice(0, utils_1.BOSSES.length);
137
- var skills = skillObjects.reduce(function (prev, curr, index) {
138
- var newSkills = __assign({}, prev);
139
- newSkills[utils_1.SKILLS[index]] = curr;
140
- return newSkills;
141
- }, {});
142
- var bountyHunter = bhObjects.reduce(function (prev, curr, index) {
143
- var newBH = __assign({}, prev);
144
- newBH[utils_1.BH_MODES[index]] = curr;
145
- return newBH;
146
- }, {});
147
- var clues = clueObjects.reduce(function (prev, curr, index) {
148
- var newClues = __assign({}, prev);
149
- newClues[utils_1.CLUES[index]] = curr;
150
- return newClues;
151
- }, {});
152
- var bosses = bossObjects.reduce(function (prev, curr, index) {
153
- var newBosses = __assign({}, prev);
154
- newBosses[utils_1.BOSSES[index]] = curr;
155
- return newBosses;
156
- }, {});
157
- var stats = {
158
- skills: skills,
159
- leaguePoints: leaguePoints,
160
- bountyHunter: bountyHunter,
161
- lastManStanding: lastManStanding,
162
- pvpArena: pvpArena,
163
- soulWarsZeal: soulWarsZeal,
164
- riftsClosed: riftsClosed,
165
- clues: clues,
166
- bosses: bosses
167
- };
168
- return stats;
169
- }
170
- exports.parseStats = parseStats;
171
- /**
172
- * Fetches stats from the OSRS API and consolidates the info into a player object.
173
- *
174
- * **Note:** This function will make up to 5 separate network requests.
175
- * As such, it is highly subject to the performance of the official OSRS API.
176
- *
177
- * @param rsn Username of the player.
178
- * @returns Player object.
179
- */
180
- function getStats(rsn) {
181
- return __awaiter(this, void 0, void 0, function () {
182
- var mainRes, otherResponses, ironRes, hcRes, ultRes, formattedName, player;
183
- return __generator(this, function (_a) {
184
- switch (_a.label) {
185
- case 0:
186
- if (typeof rsn !== 'string') {
187
- throw Error('RSN must be a string');
188
- }
189
- else if (!/^[a-zA-Z0-9 _-]+$/.test(rsn)) {
190
- throw Error('RSN contains invalid character');
191
- }
192
- else if (rsn.length > 12 || rsn.length < 1) {
193
- throw Error('RSN must be between 1 and 12 characters');
194
- }
195
- return [4 /*yield*/, utils_1.httpGet(utils_1.getStatsURL('main', rsn))];
196
- case 1:
197
- mainRes = _a.sent();
198
- if (!(mainRes.status === 200)) return [3 /*break*/, 3];
199
- return [4 /*yield*/, Promise.all([
200
- utils_1.httpGet(utils_1.getStatsURL('ironman', rsn)).catch(function (err) { return err; }),
201
- utils_1.httpGet(utils_1.getStatsURL('hardcore', rsn)).catch(function (err) { return err; }),
202
- utils_1.httpGet(utils_1.getStatsURL('ultimate', rsn)).catch(function (err) { return err; }),
203
- getRSNFormat(rsn).catch(function () { return undefined; })
204
- ])];
205
- case 2:
206
- otherResponses = _a.sent();
207
- ironRes = otherResponses[0], hcRes = otherResponses[1], ultRes = otherResponses[2], formattedName = otherResponses[3];
208
- player = {
209
- name: formattedName !== null && formattedName !== void 0 ? formattedName : rsn,
210
- mode: 'main',
211
- dead: false,
212
- deulted: false,
213
- deironed: false
214
- };
215
- player.main = parseStats(mainRes.data);
216
- if (ironRes.status === 200) {
217
- player.ironman = parseStats(ironRes.data);
218
- if (hcRes.status === 200) {
219
- player.mode = 'hardcore';
220
- player.hardcore = parseStats(hcRes.data);
221
- if (player.ironman.skills.overall.xp !== player.hardcore.skills.overall.xp) {
222
- player.dead = true;
223
- player.mode = 'ironman';
224
- }
225
- if (player.main.skills.overall.xp !== player.ironman.skills.overall.xp) {
226
- player.deironed = true;
227
- player.mode = 'main';
228
- }
229
- }
230
- else if (ultRes.status === 200) {
231
- player.mode = 'ultimate';
232
- player.ultimate = parseStats(ultRes.data);
233
- if (player.ironman.skills.overall.xp !== player.ultimate.skills.overall.xp) {
234
- player.deulted = true;
235
- player.mode = 'ironman';
236
- }
237
- if (player.main.skills.overall.xp !== player.ironman.skills.overall.xp) {
238
- player.deironed = true;
239
- player.mode = 'main';
240
- }
241
- }
242
- else {
243
- player.mode = 'ironman';
244
- if (player.main.skills.overall.xp !== player.ironman.skills.overall.xp) {
245
- player.deironed = true;
246
- player.mode = 'main';
247
- }
248
- }
249
- }
250
- return [2 /*return*/, player];
251
- case 3: throw Error('Player not found');
252
- }
253
- });
254
- });
255
- }
256
- exports.getStats = getStats;
257
- /**
258
- * Fetches stats from the OSRS API and returns them as an object.
259
- *
260
- * @param rsn Username of the player.
261
- * @param mode Gamemode to fetch ranks for.
262
- * @returns Stats object.
263
- */
264
- function getStatsByGamemode(rsn, mode) {
265
- if (mode === void 0) { mode = 'main'; }
266
- return __awaiter(this, void 0, void 0, function () {
267
- var response, stats;
268
- return __generator(this, function (_a) {
269
- switch (_a.label) {
270
- case 0:
271
- if (typeof rsn !== 'string') {
272
- throw Error('RSN must be a string');
273
- }
274
- else if (!/^[a-zA-Z0-9 _-]+$/.test(rsn)) {
275
- throw Error('RSN contains invalid character');
276
- }
277
- else if (rsn.length > 12 || rsn.length < 1) {
278
- throw Error('RSN must be between 1 and 12 characters');
279
- }
280
- else if (!utils_1.GAMEMODES.includes(mode)) {
281
- throw Error('Invalid game mode');
282
- }
283
- return [4 /*yield*/, utils_1.httpGet(utils_1.getStatsURL(mode, rsn))];
284
- case 1:
285
- response = _a.sent();
286
- if (response.status !== 200) {
287
- throw Error('Player not found');
288
- }
289
- stats = parseStats(response.data);
290
- return [2 /*return*/, stats];
291
- }
292
- });
293
- });
294
- }
295
- exports.getStatsByGamemode = getStatsByGamemode;
296
- function getSkillPage(skill, mode, page) {
297
- if (mode === void 0) { mode = 'main'; }
298
- if (page === void 0) { page = 1; }
299
- return __awaiter(this, void 0, void 0, function () {
300
- var url, response, dom, playersHTML, players;
301
- return __generator(this, function (_a) {
302
- switch (_a.label) {
303
- case 0:
304
- if (!utils_1.GAMEMODES.includes(mode)) {
305
- throw Error('Invalid game mode');
306
- }
307
- else if (!Number.isInteger(page) || page < 1) {
308
- throw Error('Page must be an integer greater than 0');
309
- }
310
- else if (!utils_1.SKILLS.includes(skill)) {
311
- throw Error('Invalid skill');
312
- }
313
- url = utils_1.getSkillPageURL(mode, skill, page);
314
- return [4 /*yield*/, utils_1.httpGet(url)];
315
- case 1:
316
- response = _a.sent();
317
- dom = new jsdom_1.JSDOM(response.data);
318
- playersHTML = dom.window.document.querySelectorAll('.personal-hiscores__row');
319
- players = [];
320
- playersHTML.forEach(function (row) {
321
- var rankEl = row.querySelector('td');
322
- var nameEl = row.querySelector('td a');
323
- var levelEl = row.querySelector('td.left + td');
324
- var xpEl = row.querySelector('td.left + td + td');
325
- var isDead = !!row.querySelector('td img');
326
- players.push({
327
- name: utils_1.rsnFromElement(nameEl),
328
- rank: utils_1.numberFromElement(rankEl),
329
- level: utils_1.numberFromElement(levelEl),
330
- xp: utils_1.numberFromElement(xpEl),
331
- dead: isDead
332
- });
333
- });
334
- return [2 /*return*/, players];
335
- }
336
- });
337
- });
338
- }
339
- exports.getSkillPage = getSkillPage;
340
- /**
341
- * Screen scrapes a hiscores page of an activity or boss and returns an array of up to 25 players.
342
- *
343
- * @param activity Name of the activity or boss to fetch hiscores for.
344
- * @param mode Gamemode to fetch ranks for.
345
- * @param page Page number.
346
- * @returns Array of `PlayerActivityRow` objects.
347
- */
348
- function getActivityPage(activity, mode, page) {
349
- if (mode === void 0) { mode = 'main'; }
350
- if (page === void 0) { page = 1; }
351
- return __awaiter(this, void 0, void 0, function () {
352
- var url, response, dom, playersHTML, players;
353
- return __generator(this, function (_a) {
354
- switch (_a.label) {
355
- case 0:
356
- if (!utils_1.GAMEMODES.includes(mode)) {
357
- throw Error('Invalid game mode');
358
- }
359
- else if (!Number.isInteger(page) || page < 1) {
360
- throw Error('Page must be an integer greater than 0');
361
- }
362
- else if (!utils_1.ACTIVITIES.includes(activity)) {
363
- throw Error('Invalid activity');
364
- }
365
- url = utils_1.getActivityPageURL(mode, activity, page);
366
- return [4 /*yield*/, utils_1.httpGet(url)];
367
- case 1:
368
- response = _a.sent();
369
- dom = new jsdom_1.JSDOM(response.data);
370
- playersHTML = dom.window.document.querySelectorAll('.personal-hiscores__row');
371
- players = [];
372
- playersHTML.forEach(function (row) {
373
- var rankEl = row.querySelector('td');
374
- var nameEl = row.querySelector('td a');
375
- var scoreEl = row.querySelector('td.left + td');
376
- var isDead = !!row.querySelector('td img');
377
- players.push({
378
- name: utils_1.rsnFromElement(nameEl),
379
- rank: utils_1.numberFromElement(rankEl),
380
- score: utils_1.numberFromElement(scoreEl),
381
- dead: isDead
382
- });
383
- });
384
- return [2 /*return*/, players];
385
- }
386
- });
387
- });
388
- }
389
- exports.getActivityPage = getActivityPage;
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (_) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ Object.defineProperty(exports, "__esModule", { value: true });
50
+ exports.getActivityPage = exports.getSkillPage = exports.getStatsByGamemode = exports.getStats = exports.parseStats = exports.getRSNFormat = void 0;
51
+ var jsdom_1 = require("jsdom");
52
+ var utils_1 = require("./utils");
53
+ /**
54
+ * Screen scrapes the hiscores to get the formatted rsn of a player.
55
+ *
56
+ * @param rsn Username of the player.
57
+ * @returns Formatted version of the rsn.
58
+ */
59
+ function getRSNFormat(rsn) {
60
+ return __awaiter(this, void 0, void 0, function () {
61
+ var url, response, dom, anchor, _a;
62
+ return __generator(this, function (_b) {
63
+ switch (_b.label) {
64
+ case 0:
65
+ utils_1.validateRSN(rsn);
66
+ url = utils_1.getPlayerTableURL('main', rsn);
67
+ _b.label = 1;
68
+ case 1:
69
+ _b.trys.push([1, 3, , 4]);
70
+ return [4 /*yield*/, utils_1.httpGet(url)];
71
+ case 2:
72
+ response = _b.sent();
73
+ dom = new jsdom_1.JSDOM(response.data);
74
+ anchor = dom.window.document.querySelector('.personal-hiscores__row.personal-hiscores__row--type-highlight a');
75
+ if (anchor) {
76
+ return [2 /*return*/, utils_1.rsnFromElement(anchor)];
77
+ }
78
+ throw Error('Player not found');
79
+ case 3:
80
+ _a = _b.sent();
81
+ throw Error('Player not found');
82
+ case 4: return [2 /*return*/];
83
+ }
84
+ });
85
+ });
86
+ }
87
+ exports.getRSNFormat = getRSNFormat;
88
+ /**
89
+ * Parses CSV string of raw stats and returns a stats object.
90
+ *
91
+ * @param csv Raw CSV from the official OSRS API.
92
+ * @returns Parsed stats object.
93
+ */
94
+ function parseStats(csv) {
95
+ var splitCSV = csv
96
+ .split('\n')
97
+ .filter(function (entry) { return !!entry; })
98
+ .map(function (stat) { return stat.split(','); });
99
+ if (splitCSV.length !==
100
+ utils_1.SKILLS.length + utils_1.BH_MODES.length + utils_1.CLUES.length + utils_1.BOSSES.length + 5) {
101
+ throw Error(utils_1.INVALID_FORMAT_ERROR);
102
+ }
103
+ var skillObjects = splitCSV
104
+ .filter(function (stat) { return stat.length === 3; })
105
+ .map(function (stat) {
106
+ var rank = stat[0], level = stat[1], xp = stat[2];
107
+ var skill = {
108
+ rank: parseInt(rank, 10),
109
+ level: parseInt(level, 10),
110
+ xp: parseInt(xp, 10)
111
+ };
112
+ return skill;
113
+ });
114
+ var activityObjects = splitCSV
115
+ .filter(function (stat) { return stat.length === 2; })
116
+ .map(function (stat) {
117
+ var rank = stat[0], score = stat[1];
118
+ var activity = {
119
+ rank: parseInt(rank, 10),
120
+ score: parseInt(score, 10)
121
+ };
122
+ return activity;
123
+ });
124
+ var leaguePoints = activityObjects.splice(0, 1)[0];
125
+ var bhObjects = activityObjects.splice(0, utils_1.BH_MODES.length);
126
+ var clueObjects = activityObjects.splice(0, utils_1.CLUES.length);
127
+ var _a = activityObjects.splice(0, 4), lastManStanding = _a[0], pvpArena = _a[1], soulWarsZeal = _a[2], riftsClosed = _a[3];
128
+ var bossObjects = activityObjects.splice(0, utils_1.BOSSES.length);
129
+ var skills = skillObjects.reduce(function (prev, curr, index) {
130
+ var newSkills = __assign({}, prev);
131
+ newSkills[utils_1.SKILLS[index]] = curr;
132
+ return newSkills;
133
+ }, {});
134
+ var bountyHunter = bhObjects.reduce(function (prev, curr, index) {
135
+ var newBH = __assign({}, prev);
136
+ newBH[utils_1.BH_MODES[index]] = curr;
137
+ return newBH;
138
+ }, {});
139
+ var clues = clueObjects.reduce(function (prev, curr, index) {
140
+ var newClues = __assign({}, prev);
141
+ newClues[utils_1.CLUES[index]] = curr;
142
+ return newClues;
143
+ }, {});
144
+ var bosses = bossObjects.reduce(function (prev, curr, index) {
145
+ var newBosses = __assign({}, prev);
146
+ newBosses[utils_1.BOSSES[index]] = curr;
147
+ return newBosses;
148
+ }, {});
149
+ var stats = {
150
+ skills: skills,
151
+ leaguePoints: leaguePoints,
152
+ bountyHunter: bountyHunter,
153
+ lastManStanding: lastManStanding,
154
+ pvpArena: pvpArena,
155
+ soulWarsZeal: soulWarsZeal,
156
+ riftsClosed: riftsClosed,
157
+ clues: clues,
158
+ bosses: bosses
159
+ };
160
+ return stats;
161
+ }
162
+ exports.parseStats = parseStats;
163
+ /**
164
+ * Fetches stats from the OSRS API and consolidates the info into a player object.
165
+ *
166
+ * **Note:** This function will make up to 5 separate network requests.
167
+ * As such, it is highly subject to the performance of the official OSRS API.
168
+ *
169
+ * @param rsn Username of the player.
170
+ * @returns Player object.
171
+ */
172
+ function getStats(rsn, options) {
173
+ var _a, _b;
174
+ return __awaiter(this, void 0, void 0, function () {
175
+ var otherGamemodes, shouldGetFormattedRsn, mainRes, emptyResponse_1, getModeStats, formattedName, _c, player, ironRes, hcRes, ultRes;
176
+ var _this = this;
177
+ return __generator(this, function (_d) {
178
+ switch (_d.label) {
179
+ case 0:
180
+ utils_1.validateRSN(rsn);
181
+ otherGamemodes = (_a = options === null || options === void 0 ? void 0 : options.otherGamemodes) !== null && _a !== void 0 ? _a : [
182
+ 'ironman',
183
+ 'hardcore',
184
+ 'ultimate'
185
+ ];
186
+ shouldGetFormattedRsn = (_b = options === null || options === void 0 ? void 0 : options.shouldGetFormattedRsn) !== null && _b !== void 0 ? _b : true;
187
+ return [4 /*yield*/, utils_1.httpGet(utils_1.getStatsURL('main', rsn))];
188
+ case 1:
189
+ mainRes = _d.sent();
190
+ if (!(mainRes.status === 200)) return [3 /*break*/, 9];
191
+ emptyResponse_1 = {
192
+ status: 404,
193
+ data: '',
194
+ statusText: '',
195
+ headers: {},
196
+ config: {}
197
+ };
198
+ getModeStats = function (mode) { return __awaiter(_this, void 0, void 0, function () {
199
+ return __generator(this, function (_a) {
200
+ return [2 /*return*/, otherGamemodes.includes(mode)
201
+ ? utils_1.httpGet(utils_1.getStatsURL(mode, rsn)).catch(function (err) { return err; })
202
+ : emptyResponse_1];
203
+ });
204
+ }); };
205
+ if (!shouldGetFormattedRsn) return [3 /*break*/, 3];
206
+ return [4 /*yield*/, getRSNFormat(rsn).catch(function () { return undefined; })];
207
+ case 2:
208
+ _c = _d.sent();
209
+ return [3 /*break*/, 4];
210
+ case 3:
211
+ _c = undefined;
212
+ _d.label = 4;
213
+ case 4:
214
+ formattedName = _c;
215
+ player = {
216
+ name: formattedName !== null && formattedName !== void 0 ? formattedName : rsn,
217
+ mode: 'main',
218
+ dead: false,
219
+ deulted: false,
220
+ deironed: false
221
+ };
222
+ player.main = parseStats(mainRes.data);
223
+ return [4 /*yield*/, getModeStats('ironman')];
224
+ case 5:
225
+ ironRes = _d.sent();
226
+ if (!(ironRes.status === 200)) return [3 /*break*/, 8];
227
+ player.ironman = parseStats(ironRes.data);
228
+ return [4 /*yield*/, getModeStats('hardcore')];
229
+ case 6:
230
+ hcRes = _d.sent();
231
+ return [4 /*yield*/, getModeStats('ultimate')];
232
+ case 7:
233
+ ultRes = _d.sent();
234
+ if (hcRes.status === 200) {
235
+ player.mode = 'hardcore';
236
+ player.hardcore = parseStats(hcRes.data);
237
+ if (player.ironman.skills.overall.xp !== player.hardcore.skills.overall.xp) {
238
+ player.dead = true;
239
+ player.mode = 'ironman';
240
+ }
241
+ if (player.main.skills.overall.xp !== player.ironman.skills.overall.xp) {
242
+ player.deironed = true;
243
+ player.mode = 'main';
244
+ }
245
+ }
246
+ else if (ultRes.status === 200) {
247
+ player.mode = 'ultimate';
248
+ player.ultimate = parseStats(ultRes.data);
249
+ if (player.ironman.skills.overall.xp !== player.ultimate.skills.overall.xp) {
250
+ player.deulted = true;
251
+ player.mode = 'ironman';
252
+ }
253
+ if (player.main.skills.overall.xp !== player.ironman.skills.overall.xp) {
254
+ player.deironed = true;
255
+ player.mode = 'main';
256
+ }
257
+ }
258
+ else {
259
+ player.mode = 'ironman';
260
+ if (player.main.skills.overall.xp !== player.ironman.skills.overall.xp) {
261
+ player.deironed = true;
262
+ player.mode = 'main';
263
+ }
264
+ }
265
+ _d.label = 8;
266
+ case 8: return [2 /*return*/, player];
267
+ case 9: throw Error('Player not found');
268
+ }
269
+ });
270
+ });
271
+ }
272
+ exports.getStats = getStats;
273
+ /**
274
+ * Fetches stats from the OSRS API and returns them as an object.
275
+ *
276
+ * @param rsn Username of the player.
277
+ * @param mode Gamemode to fetch ranks for.
278
+ * @returns Stats object.
279
+ */
280
+ function getStatsByGamemode(rsn, mode) {
281
+ if (mode === void 0) { mode = 'main'; }
282
+ return __awaiter(this, void 0, void 0, function () {
283
+ var response, stats;
284
+ return __generator(this, function (_a) {
285
+ switch (_a.label) {
286
+ case 0:
287
+ utils_1.validateRSN(rsn);
288
+ if (!utils_1.GAMEMODES.includes(mode)) {
289
+ throw Error('Invalid game mode');
290
+ }
291
+ return [4 /*yield*/, utils_1.httpGet(utils_1.getStatsURL(mode, rsn))];
292
+ case 1:
293
+ response = _a.sent();
294
+ if (response.status !== 200) {
295
+ throw Error('Player not found');
296
+ }
297
+ stats = parseStats(response.data);
298
+ return [2 /*return*/, stats];
299
+ }
300
+ });
301
+ });
302
+ }
303
+ exports.getStatsByGamemode = getStatsByGamemode;
304
+ function getSkillPage(skill, mode, page) {
305
+ if (mode === void 0) { mode = 'main'; }
306
+ if (page === void 0) { page = 1; }
307
+ return __awaiter(this, void 0, void 0, function () {
308
+ var url, response, dom, playersHTML, players;
309
+ return __generator(this, function (_a) {
310
+ switch (_a.label) {
311
+ case 0:
312
+ if (!utils_1.GAMEMODES.includes(mode)) {
313
+ throw Error('Invalid game mode');
314
+ }
315
+ else if (!Number.isInteger(page) || page < 1) {
316
+ throw Error('Page must be an integer greater than 0');
317
+ }
318
+ else if (!utils_1.SKILLS.includes(skill)) {
319
+ throw Error('Invalid skill');
320
+ }
321
+ url = utils_1.getSkillPageURL(mode, skill, page);
322
+ return [4 /*yield*/, utils_1.httpGet(url)];
323
+ case 1:
324
+ response = _a.sent();
325
+ dom = new jsdom_1.JSDOM(response.data);
326
+ playersHTML = dom.window.document.querySelectorAll('.personal-hiscores__row');
327
+ players = [];
328
+ playersHTML.forEach(function (row) {
329
+ var rankEl = row.querySelector('td');
330
+ var nameEl = row.querySelector('td a');
331
+ var levelEl = row.querySelector('td.left + td');
332
+ var xpEl = row.querySelector('td.left + td + td');
333
+ var isDead = !!row.querySelector('td img');
334
+ players.push({
335
+ name: utils_1.rsnFromElement(nameEl),
336
+ rank: utils_1.numberFromElement(rankEl),
337
+ level: utils_1.numberFromElement(levelEl),
338
+ xp: utils_1.numberFromElement(xpEl),
339
+ dead: isDead
340
+ });
341
+ });
342
+ return [2 /*return*/, players];
343
+ }
344
+ });
345
+ });
346
+ }
347
+ exports.getSkillPage = getSkillPage;
348
+ /**
349
+ * Screen scrapes a hiscores page of an activity or boss and returns an array of up to 25 players.
350
+ *
351
+ * @param activity Name of the activity or boss to fetch hiscores for.
352
+ * @param mode Gamemode to fetch ranks for.
353
+ * @param page Page number.
354
+ * @returns Array of `PlayerActivityRow` objects.
355
+ */
356
+ function getActivityPage(activity, mode, page) {
357
+ if (mode === void 0) { mode = 'main'; }
358
+ if (page === void 0) { page = 1; }
359
+ return __awaiter(this, void 0, void 0, function () {
360
+ var url, response, dom, playersHTML, players;
361
+ return __generator(this, function (_a) {
362
+ switch (_a.label) {
363
+ case 0:
364
+ if (!utils_1.GAMEMODES.includes(mode)) {
365
+ throw Error('Invalid game mode');
366
+ }
367
+ else if (!Number.isInteger(page) || page < 1) {
368
+ throw Error('Page must be an integer greater than 0');
369
+ }
370
+ else if (!utils_1.ACTIVITIES.includes(activity)) {
371
+ throw Error('Invalid activity');
372
+ }
373
+ url = utils_1.getActivityPageURL(mode, activity, page);
374
+ return [4 /*yield*/, utils_1.httpGet(url)];
375
+ case 1:
376
+ response = _a.sent();
377
+ dom = new jsdom_1.JSDOM(response.data);
378
+ playersHTML = dom.window.document.querySelectorAll('.personal-hiscores__row');
379
+ players = [];
380
+ playersHTML.forEach(function (row) {
381
+ var rankEl = row.querySelector('td');
382
+ var nameEl = row.querySelector('td a');
383
+ var scoreEl = row.querySelector('td.left + td');
384
+ var isDead = !!row.querySelector('td img');
385
+ players.push({
386
+ name: utils_1.rsnFromElement(nameEl),
387
+ rank: utils_1.numberFromElement(rankEl),
388
+ score: utils_1.numberFromElement(scoreEl),
389
+ dead: isDead
390
+ });
391
+ });
392
+ return [2 /*return*/, players];
393
+ }
394
+ });
395
+ });
396
+ }
397
+ exports.getActivityPage = getActivityPage;