Compare commits

...

52 Commits

Author SHA1 Message Date
maxswa
fd24890f67 v2.21.0 2025-02-24 19:09:05 -05:00
Max Swartwout
3ba434978a Merge pull request #103 from maxswa/dependabot/npm_and_yarn/cross-spawn-7.0.6
Bump cross-spawn from 7.0.3 to 7.0.6
2025-02-24 19:07:17 -05:00
Max Swartwout
44ecdf5434 Merge pull request #106 from evanw555/add-collections-titans
Add Collections Logged, Royal Titans
2025-02-24 19:06:56 -05:00
maxswa
99fc97f05e Fix csv parsing, tests. 2025-02-24 19:03:56 -05:00
Evan Williams
b3fc5846f3 Add Collections Logged, Royal Titans 2025-02-07 00:50:49 -08:00
dependabot[bot]
1deed9f450 Bump cross-spawn from 7.0.3 to 7.0.6
Bumps [cross-spawn](https://github.com/moxystudio/node-cross-spawn) from 7.0.3 to 7.0.6.
- [Changelog](https://github.com/moxystudio/node-cross-spawn/blob/master/CHANGELOG.md)
- [Commits](https://github.com/moxystudio/node-cross-spawn/compare/v7.0.3...v7.0.6)

---
updated-dependencies:
- dependency-name: cross-spawn
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-18 22:43:06 +00:00
maxswa
0be3f0b636 v2.20.0 2024-09-25 12:11:27 -04:00
Max Swartwout
ec1ed53669 Merge pull request #102 from maxswa/varlamore-part-2
Add Amoxliatl, The Hueycoatl
2024-09-25 11:59:54 -04:00
maxswa
d0f5285470 Add Amoxliatl, The Hueycoatl 2024-09-25 11:56:09 -04:00
maxswa
9c56e44344 v2.19.0 2024-08-30 01:30:49 -04:00
Max Swartwout
e5b3075ebd Merge pull request #101 from maxswa/dependabot/npm_and_yarn/axios-1.7.4
Bump axios from 1.6.2 to 1.7.4
2024-08-30 01:07:29 -04:00
dependabot[bot]
8bb50b73b2 Bump axios from 1.6.2 to 1.7.4
Bumps [axios](https://github.com/axios/axios) from 1.6.2 to 1.7.4.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.6.2...v1.7.4)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-30 05:05:04 +00:00
Max Swartwout
cb482ad720 Merge pull request #98 from maxswa/dependabot/npm_and_yarn/ws-8.17.1
Bump ws from 8.13.0 to 8.17.1
2024-08-30 01:04:53 -04:00
Max Swartwout
0fbd85aa07 Merge pull request #100 from maxswa/dependabot/npm_and_yarn/micromatch-4.0.8
Bump micromatch from 4.0.2 to 4.0.8
2024-08-30 01:04:39 -04:00
Max Swartwout
e634b107b1 Merge pull request #99 from Not-Jayden/araxxor
Add Araxxor
2024-08-30 01:04:26 -04:00
dependabot[bot]
29db21493c Bump micromatch from 4.0.2 to 4.0.8
Bumps [micromatch](https://github.com/micromatch/micromatch) from 4.0.2 to 4.0.8.
- [Release notes](https://github.com/micromatch/micromatch/releases)
- [Changelog](https://github.com/micromatch/micromatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/micromatch/compare/4.0.2...4.0.8)

---
updated-dependencies:
- dependency-name: micromatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-30 04:14:53 +00:00
Jayden Carey
b117cfcf41 add araxxor 2024-08-29 00:17:36 +08:00
dependabot[bot]
d895326d9f Bump ws from 8.13.0 to 8.17.1
Bumps [ws](https://github.com/websockets/ws) from 8.13.0 to 8.17.1.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/8.13.0...8.17.1)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-18 06:40:44 +00:00
maxswa
1f7a25d421 v2.18.0 2024-03-20 19:23:50 -04:00
Max Swartwout
057812681b Merge pull request #95 from maxswa/varlamore-part-one
Add Colosseum Glory, Lunar Chests, Sol Heredit
2024-03-20 19:21:55 -04:00
Max Swartwout
ee510ec69a Merge pull request #94 from maxswa/dependabot/npm_and_yarn/follow-redirects-1.15.6
Bump follow-redirects from 1.15.4 to 1.15.6
2024-03-20 19:19:55 -04:00
maxswa
6adcb02545 Add Colosseum Glory, Lunar Chests, Sol Heredit 2024-03-20 19:18:35 -04:00
dependabot[bot]
dacbd90189 Bump follow-redirects from 1.15.4 to 1.15.6
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.4 to 1.15.6.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-16 23:16:39 +00:00
maxswa
3b502cb7cf v2.17.0 2024-01-24 11:25:48 -05:00
Max Swartwout
b3f81e66eb Merge pull request #88 from maxswa/scurrius
Add Scurrius
2024-01-24 11:24:34 -05:00
Max Swartwout
01150b6234 Merge pull request #93 from maxswa/update-readme-json-api
Add reference to official JSON API in README
2024-01-19 18:43:47 -05:00
maxswa
ca4d75f2c7 Add reference to official JSON API in README. 2024-01-19 18:37:14 -05:00
Max Swartwout
03b2ef42d2 Merge pull request #91 from maxswa/dependabot/npm_and_yarn/follow-redirects-1.15.4
Bump follow-redirects from 1.15.3 to 1.15.4
2024-01-19 18:18:24 -05:00
dependabot[bot]
7e2603b235 Bump follow-redirects from 1.15.3 to 1.15.4
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.3 to 1.15.4.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.3...v1.15.4)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-11 04:36:21 +00:00
maxswa
92452e240c Add Scurrius 2023-12-30 23:25:32 -05:00
maxswa
d01b36422e v2.16.3 2023-12-17 20:17:17 -05:00
Max Swartwout
3bc1352838 Merge pull request #90 from maxswa/deadman-points
Add Deadman Points
2023-12-17 20:16:28 -05:00
maxswa
91066b5366 Add deadmanPoints 2023-12-17 20:13:06 -05:00
maxswa
4872d04301 v2.16.2 2023-11-26 19:53:20 -05:00
Max Swartwout
55312ba0fd Merge pull request #85 from seditionist/main
Add Custom Errors
2023-11-26 19:52:07 -05:00
maxswa
331a448503 Disabled eslint rule. 2023-11-26 19:43:35 -05:00
maxswa
84c704a846 Add test for excluded gamemodes. 2023-11-26 19:42:46 -05:00
seditionist
561495632c Fix gamemode checks 2023-11-26 18:55:26 -05:00
seditionist
bdfdf1eb14 Merge branch 'maxswa-main' 2023-11-26 18:23:31 -05:00
seditionist
e349776060 Merge branch 'main' of github.com:maxswa/osrs-json-hiscores into maxswa-main
# Conflicts:
#	src/hiscores.ts
2023-11-26 18:20:03 -05:00
seditionist
546bc5acf7 Remove unnecessary type cast 2023-11-26 17:43:38 -05:00
seditionist
66528cd9d9 Restore error message constants 2023-11-26 17:42:55 -05:00
maxswa
99ea3fb722 v2.16.1 2023-11-25 22:07:55 -05:00
Max Swartwout
7f16d26e3c Merge pull request #89 from maxswa/bump-axios
Bump `axios`
2023-11-25 22:06:07 -05:00
maxswa
ed9fcf47b3 Bump axios 2023-11-25 22:04:48 -05:00
Max Swartwout
bb935bb6c9 Merge pull request #86 from maxswa/dependabot/npm_and_yarn/babel/traverse-7.23.2
Bump @babel/traverse from 7.22.8 to 7.23.2
2023-11-25 21:36:52 -05:00
dependabot[bot]
d046fffa9e Bump @babel/traverse from 7.22.8 to 7.23.2
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.22.8 to 7.23.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: "@babel/traverse"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-19 11:00:07 +00:00
seditionist
5483e54d78 cleanup 2023-08-17 00:58:37 -04:00
seditionist
97532b0c03 fix tests 2023-08-17 00:35:22 -04:00
seditionist
f9a56e2b3a update hiscores to throw new custom errors 2023-08-17 00:32:23 -04:00
seditionist
9f43f0c39f update validRSN to use InvalidRSNError 2023-08-17 00:12:27 -04:00
seditionist
d67ffa3e20 created custom errors 2023-08-17 00:11:18 -04:00
15 changed files with 5153 additions and 4723 deletions

View File

@@ -5,22 +5,24 @@
[![types](https://img.shields.io/npm/types/osrs-json-hiscores.svg?style=flat-square)](https://github.com/maxswa/osrs-json-hiscores/blob/master/src/types.ts) [![types](https://img.shields.io/npm/types/osrs-json-hiscores.svg?style=flat-square)](https://github.com/maxswa/osrs-json-hiscores/blob/master/src/types.ts)
[![build](https://img.shields.io/github/actions/workflow/status/maxswa/osrs-json-hiscores/main.yml?style=flat-square&branch=main)](https://github.com/maxswa/osrs-json-hiscores/actions/workflows/main.yml?query=branch%3Amain) [![build](https://img.shields.io/github/actions/workflow/status/maxswa/osrs-json-hiscores/main.yml?style=flat-square&branch=main)](https://github.com/maxswa/osrs-json-hiscores/actions/workflows/main.yml?query=branch%3Amain)
**The Old School Runescape API wrapper that does more!** **The Old School RuneScape API wrapper that does more!**
## What it does ## What it does
The official hiscores API for Old School Runescape (OSRS) returns CSV. The official hiscores API for Old School RuneScape (OSRS) can return CSV or a simple JSON array.
This wrapper converts it to json and provides extra information about the given player. By comparing player info it infers the player's game mode, as well as any previous modes (de-ultimated, de-ironed and/or died as a hardcore ironman). This wrapper converts the hiscores data into a more usable JSON object and provides extra information about the given player. By comparing player info it infers the player's game mode, as well as any previous modes (de-ultimated, de-ironed and/or died as a hardcore ironman).
Additional functions are provided that screen-scrape the OSRS leaderboards and return a list of players as json. Additional functions are provided that screen-scrape the OSRS leaderboards and return a list of players as json. Also simple utility functions are provided to fetch the raw responses from Jagex's APIs, if desired.
`osrs-json-hiscores` has TypeScript support, with full definitions for all functions and custom data types. `osrs-json-hiscores` has TypeScript support, with full definitions for all functions and custom data types.
--- ---
### Disclaimer ### Disclaimer
Jagex does not provide `Access-Control-Allow-Origin` headers in their responses. This means that [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) will block all browser requests to their hiscores API. In order to get around this, osrs-json-hiscores should be installed on the server side and exposed to the front end via a simple API. Here is an example of this in use: [codesandbox.io/s/osrs-json-hiscores-demo](https://codesandbox.io/s/osrs-json-hiscores-demo-qz656) Jagex does not provide `Access-Control-Allow-Origin` headers in their responses. This means that [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) will block all browser requests to their hiscores API. In order to get around this, osrs-json-hiscores needs to be installed on the server side and exposed to the front end via a simple API. Here is an example of this in use: [codesandbox.io/s/osrs-json-hiscores-demo](https://codesandbox.io/s/osrs-json-hiscores-demo-qz656)
TLDR: You cannot use this library directly in your client side app e.g. React or Vue, you must set up a server which uses this lib internally and have your client fetch data from your server.
--- ---
@@ -42,27 +44,14 @@ $ yarn add osrs-json-hiscores
Install the package and then import it into your project: Install the package and then import it into your project:
```javascript ```typescript
const hiscores = require('osrs-json-hiscores'); import { getStatsByGamemode, getSkillPage } from 'osrs-json-hiscores';
``` ```
Once you import it you can call the functions asynchronously: Once you import it you can call the functions asynchronously:
```javascript ```typescript
hiscores const stats = await getStatsByGamemode('Lynx Titan');
.getStats('Lynx Titan')
.then((res) => console.log(res))
.catch((err) => console.error(err));
```
If you are using TypeScript or transpiling your JS you can use ES6 syntax:
```javascript
import hiscores, { getSkillPage } from 'osrs-json-hiscores';
// ...
const stats = await hiscores.getStats('Lynx Titan');
const topPage = await getSkillPage('overall'); const topPage = await getSkillPage('overall');
``` ```
@@ -81,9 +70,8 @@ const topPage = await getSkillPage('overall');
`getSkillPage` and `getActivityPage` require a skill / activity and optionally a gamemode and page: `getSkillPage` and `getActivityPage` require a skill / activity and optionally a gamemode and page:
```javascript ```typescript
hiscores getSkillPage('attack', 'main', 1)
.getSkillPage('attack', 'main', 1)
.then((res) => console.log(res)) .then((res) => console.log(res))
.catch((err) => console.error(err)); .catch((err) => console.error(err));
``` ```
@@ -105,7 +93,7 @@ Activities consist of all levels of clue scrolls as well as minigames and bosses
### Minigames ### Minigames
| Minigame | Param | | Minigame | Param |
| ------------------------------- | :---------------: | | ------------------------------- | :-----------------: |
| Bounty Hunter (Legacy - Rogue) | `rogueBH` | | Bounty Hunter (Legacy - Rogue) | `rogueBH` |
| Bounty Hunter (Legacy - Hunter) | `hunterBH` | | Bounty Hunter (Legacy - Hunter) | `hunterBH` |
| Bounty Hunter (Rogue) | `rogueBHV2` | | Bounty Hunter (Rogue) | `rogueBHV2` |
@@ -114,12 +102,15 @@ Activities consist of all levels of clue scrolls as well as minigames and bosses
| PvP Arena - Rank | `pvpArena` | | PvP Arena - Rank | `pvpArena` |
| Soul Wars Zeal | `soulWarsZeal` | | Soul Wars Zeal | `soulWarsZeal` |
| Rifts closed | `riftsClosed` | | Rifts closed | `riftsClosed` |
| Colosseum Glory | `colosseumGlory` |
| Collections Logged | `collectionsLogged` |
### Leagues ### Points
| Activity | Param | | Activity | Param |
| ------------- | :------------: | | -------------- | :-------------: |
| League Points | `leaguePoints` | | League Points | `leaguePoints` |
| Deadman Points | `deadmanPoints` |
### Bosses ### Bosses
@@ -127,6 +118,8 @@ Activities consist of all levels of clue scrolls as well as minigames and bosses
| --------------------------------- | :----------------------------: | | --------------------------------- | :----------------------------: |
| Abyssal Sire | `abyssalSire` | | Abyssal Sire | `abyssalSire` |
| Alchemical Hydra | `alchemicalHydra` | | Alchemical Hydra | `alchemicalHydra` |
| Amoxliatl | `amoxliatl` |
| Araxxor | `araxxor` |
| Artio | `artio` | | Artio | `artio` |
| Barrows Chests | `barrows` | | Barrows Chests | `barrows` |
| Bryophyta | `bryophyta` | | Bryophyta | `bryophyta` |
@@ -154,6 +147,7 @@ Activities consist of all levels of clue scrolls as well as minigames and bosses
| Kraken | `kraken` | | Kraken | `kraken` |
| Kreearra | `kreeArra` | | Kreearra | `kreeArra` |
| K'ril Tsutsaroth | `krilTsutsaroth` | | K'ril Tsutsaroth | `krilTsutsaroth` |
| Lunar Chests | `lunarChests` |
| Mimic | `mimic` | | Mimic | `mimic` |
| Nex | `nex` | | Nex | `nex` |
| Nightmare | `nightmare` | | Nightmare | `nightmare` |
@@ -162,12 +156,16 @@ Activities consist of all levels of clue scrolls as well as minigames and bosses
| Phantom Muspah | `phantomMuspah` | | Phantom Muspah | `phantomMuspah` |
| Sarachnis | `sarachnis` | | Sarachnis | `sarachnis` |
| Scorpia | `scorpia` | | Scorpia | `scorpia` |
| Scurrius | `scurrius` |
| Skotizo | `skotizo` | | Skotizo | `skotizo` |
| Sol Heredit | `solHeredit` |
| Spindel | `spindel` | | Spindel | `spindel` |
| Tempoross | `tempoross` | | Tempoross | `tempoross` |
| The Gauntlet | `gauntlet` | | The Gauntlet | `gauntlet` |
| The Corrupted Gauntlet | `corruptedGauntlet` | | The Corrupted Gauntlet | `corruptedGauntlet` |
| The Hueycoatl | `hueycoatl` |
| The Leviathan | `leviathan` | | The Leviathan | `leviathan` |
| The Royal Titans | `royalTitans` |
| The Whisperer | `whisperer` | | The Whisperer | `whisperer` |
| Theatre Of Blood | `theatreOfBlood` | | Theatre Of Blood | `theatreOfBlood` |
| Theatre Of Blood: Hard Mode | `theatreOfBloodHardMode` | | Theatre Of Blood: Hard Mode | `theatreOfBloodHardMode` |
@@ -188,7 +186,7 @@ Activities consist of all levels of clue scrolls as well as minigames and bosses
`getStats` returns a player object that looks like this: `getStats` returns a player object that looks like this:
```javascript ```typescript
{ {
name: 'Lynx Titan', name: 'Lynx Titan',
mode: 'main', mode: 'main',
@@ -209,6 +207,8 @@ Activities consist of all levels of clue scrolls as well as minigames and bosses
pvpArena: {}, pvpArena: {},
soulWarsZeal: {}, soulWarsZeal: {},
riftsClosed: {}, riftsClosed: {},
colosseumGlory: {},
collectionsLogged: {},
bosses: {} bosses: {}
} }
} }
@@ -216,7 +216,7 @@ Activities consist of all levels of clue scrolls as well as minigames and bosses
`getSkillPage` returns and array of 25 players (This represents a page on the hiscores): `getSkillPage` returns and array of 25 players (This represents a page on the hiscores):
```javascript ```typescript
[ [
{ rank: 1, name: 'Lynx Titan', level: 2277, xp: 4600000000, dead: false }, { rank: 1, name: 'Lynx Titan', level: 2277, xp: 4600000000, dead: false },
{}, {},
@@ -229,7 +229,7 @@ Activities consist of all levels of clue scrolls as well as minigames and bosses
Get the properly formatted name of any skill, boss, clue or other activity: Get the properly formatted name of any skill, boss, clue or other activity:
```javascript ```typescript
// kril === "K'ril Tsutsaroth" // kril === "K'ril Tsutsaroth"
const kril = FORMATTED_BOSS_NAMES['krilTsutsaroth']; const kril = FORMATTED_BOSS_NAMES['krilTsutsaroth'];
``` ```

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,98 +1,108 @@
3923,2277,792976020 2210,2277,1150073045
23024,99,29963318 23988,99,33320012
12244,99,28197154 3114,99,51215128
2261,99,134139762 1203,99,200000000
4074,99,112054504 1372,99,196290925
7166,99,101083246 3458,99,159426771
3747,99,15110682 2746,99,17744970
4516,99,50824811 2031,99,91566360
126288,99,13353110 161852,99,13386665
24800,99,16366466 25801,99,19461878
49293,99,13453226 64826,99,13473417
20784,99,16654289 26528,99,16672481
16376,99,19114676 20829,99,19483653
42069,99,14055874 58378,99,14103220
9305,99,16527135 13188,99,16573909
25135,99,14657869 36283,99,15061037
35831,99,13233130 17137,99,14670565
6197,99,15739327 8751,99,16169665
48215,99,13963265 60803,99,14390315
4786,99,33830972 1718,99,57850681
3402,99,62531484 2117,99,110369178
4314,99,22733194 5540,99,22739567
14826,99,17399368 22326,99,18052465
1009,99,17989158 1467,99,18050183
-1,-1 -1,-1
22270,10
10481,3
149217,8
103672,7
253,9508
713,825
71,6000
1943,1600
42364,287
467,436
1634,360
12937,2521
-1,-1 -1,-1
5222,14780 38135,10
3007,1060 19368,3
2578,2192 146220,8
84703,594 100923,7
19500,143 433,9802
3335,1830 1542,825
191697,5 158,6000
27457,293 2572,1606
43607,58 47979,311
17384,1905 1081,460
171607,33 880,600
2074,501 4258,6785
78908,50
135830,26
48781,287
2112,2000
138748,41
31297,707
40908,698
31273,714
76034,25
2391,688
17409,1228
60841,474
1895,2140
19948,159
1855,2046
46423,579
107879,1908
9791,920
2050,1444
848,33
24797,620
4157,744
4154,500
880,217
15860,251
60424,119
100429,26
358191,9
1131,1569
33908,273
165651,7
64278,201
1533,583
748,700
21700,250
13200,7
6622,3066
87093,35
2449,502
14541,2
-1,-1 -1,-1
1048,1432 7596,14780
138,7096 8124,1060
58203,51 10438,43487
13949,2780 1114,1155
827440,62 3497,2192
153191,25 3204,4796
216690,274 1087,984
2230,2328
51533,143
4243,1830
256985,5
54424,293
114691,58
11700,2657
211708,34
1779,736
24958,215
46504,116
66096,287
3133,2000
26682,198
19337,1078
25021,1062
19290,1088
89474,25
7535,1320
23251,1228
82016,477
876,3642
7073,310
2476,2046
55411,580
68801,2899
4608,1740
3079,1444
8344,324
540,53
38395,626
4176,749
5519,500
1394,217
26127,379
49730,249
57206,91
6106,1245
185920,29
3232,49
4276,1569
57314,273
256794,7
113862,201
1969,538
12346,671
5606,149
550,2450
25557,310
1391,538
9325,3066
131996,37
214,1720
8902,7
148385,8
6120,2113
287,7096
97368,51
15591,2780
1000405,67
213696,25
240082,340
Can't render this file because it has a wrong number of fields in line 25.

View File

@@ -3,192 +3,676 @@
{ {
"id": 0, "id": 0,
"name": "Overall", "name": "Overall",
"rank": 3923, "rank": 2210,
"level": 2277, "level": 2277,
"xp": 792976020 "xp": 1150073045
},
{
"id": 1,
"name": "Attack",
"rank": 23988,
"level": 99,
"xp": 33320012
},
{
"id": 2,
"name": "Defence",
"rank": 3114,
"level": 99,
"xp": 51215128
},
{
"id": 3,
"name": "Strength",
"rank": 1203,
"level": 99,
"xp": 200000000
}, },
{ "id": 1, "name": "Attack", "rank": 23024, "level": 99, "xp": 29963318 },
{ "id": 2, "name": "Defence", "rank": 12244, "level": 99, "xp": 28197154 },
{ "id": 3, "name": "Strength", "rank": 2261, "level": 99, "xp": 134139762 },
{ {
"id": 4, "id": 4,
"name": "Hitpoints", "name": "Hitpoints",
"rank": 4074, "rank": 1372,
"level": 99, "level": 99,
"xp": 112054504 "xp": 196290925
},
{
"id": 5,
"name": "Ranged",
"rank": 3458,
"level": 99,
"xp": 159426771
},
{
"id": 6,
"name": "Prayer",
"rank": 2746,
"level": 99,
"xp": 17744970
},
{
"id": 7,
"name": "Magic",
"rank": 2031,
"level": 99,
"xp": 91566360
},
{
"id": 8,
"name": "Cooking",
"rank": 161852,
"level": 99,
"xp": 13386665
}, },
{ "id": 5, "name": "Ranged", "rank": 7166, "level": 99, "xp": 101083246 },
{ "id": 6, "name": "Prayer", "rank": 3747, "level": 99, "xp": 15110682 },
{ "id": 7, "name": "Magic", "rank": 4516, "level": 99, "xp": 50824811 },
{ "id": 8, "name": "Cooking", "rank": 126288, "level": 99, "xp": 13353110 },
{ {
"id": 9, "id": 9,
"name": "Woodcutting", "name": "Woodcutting",
"rank": 24800, "rank": 25801,
"level": 99, "level": 99,
"xp": 16366466 "xp": 19461878
}, },
{ {
"id": 10, "id": 10,
"name": "Fletching", "name": "Fletching",
"rank": 49293, "rank": 64826,
"level": 99, "level": 99,
"xp": 13453226 "xp": 13473417
},
{
"id": 11,
"name": "Fishing",
"rank": 26528,
"level": 99,
"xp": 16672481
}, },
{ "id": 11, "name": "Fishing", "rank": 20784, "level": 99, "xp": 16654289 },
{ {
"id": 12, "id": 12,
"name": "Firemaking", "name": "Firemaking",
"rank": 16376, "rank": 20829,
"level": 99, "level": 99,
"xp": 19114676 "xp": 19483653
}, },
{ {
"id": 13, "id": 13,
"name": "Crafting", "name": "Crafting",
"rank": 42069, "rank": 58378,
"level": 99, "level": 99,
"xp": 14055874 "xp": 14103220
},
{
"id": 14,
"name": "Smithing",
"rank": 13188,
"level": 99,
"xp": 16573909
},
{
"id": 15,
"name": "Mining",
"rank": 36283,
"level": 99,
"xp": 15061037
}, },
{ "id": 14, "name": "Smithing", "rank": 9305, "level": 99, "xp": 16527135 },
{ "id": 15, "name": "Mining", "rank": 25135, "level": 99, "xp": 14657869 },
{ {
"id": 16, "id": 16,
"name": "Herblore", "name": "Herblore",
"rank": 35831, "rank": 17137,
"level": 99, "level": 99,
"xp": 13233130 "xp": 14670565
},
{
"id": 17,
"name": "Agility",
"rank": 8751,
"level": 99,
"xp": 16169665
}, },
{ "id": 17, "name": "Agility", "rank": 6197, "level": 99, "xp": 15739327 },
{ {
"id": 18, "id": 18,
"name": "Thieving", "name": "Thieving",
"rank": 48215, "rank": 60803,
"level": 99, "level": 99,
"xp": 13963265 "xp": 14390315
},
{
"id": 19,
"name": "Slayer",
"rank": 1718,
"level": 99,
"xp": 57850681
},
{
"id": 20,
"name": "Farming",
"rank": 2117,
"level": 99,
"xp": 110369178
}, },
{ "id": 19, "name": "Slayer", "rank": 4786, "level": 99, "xp": 33830972 },
{ "id": 20, "name": "Farming", "rank": 3402, "level": 99, "xp": 62531484 },
{ {
"id": 21, "id": 21,
"name": "Runecraft", "name": "Runecraft",
"rank": 4314, "rank": 5540,
"level": 99, "level": 99,
"xp": 22733194 "xp": 22739567
},
{
"id": 22,
"name": "Hunter",
"rank": 22326,
"level": 99,
"xp": 18052465
}, },
{ "id": 22, "name": "Hunter", "rank": 14826, "level": 99, "xp": 17399368 },
{ {
"id": 23, "id": 23,
"name": "Construction", "name": "Construction",
"rank": 1009, "rank": 1467,
"level": 99, "level": 99,
"xp": 17989158 "xp": 18050183
} }
], ],
"activities": [ "activities": [
{ "id": 0, "name": "League Points", "rank": -1, "score": -1 }, {
{ "id": 1, "name": "Bounty Hunter - Hunter", "rank": 22270, "score": 10 }, "id": 0,
{ "id": 2, "name": "Bounty Hunter - Rogue", "rank": 10481, "score": 3 }, "name": "League Points",
"rank": -1,
"score": -1
},
{
"id": 1,
"name": "Deadman Points",
"rank": -1,
"score": -1
},
{
"id": 2,
"name": "Bounty Hunter - Hunter",
"rank": 38135,
"score": 10
},
{ {
"id": 3, "id": 3,
"name": "Bounty Hunter (Legacy) - Hunter", "name": "Bounty Hunter - Rogue",
"rank": 149217, "rank": 19368,
"score": 8 "score": 3
}, },
{ {
"id": 4, "id": 4,
"name": "Bounty Hunter (Legacy) - Hunter",
"rank": 146220,
"score": 8
},
{
"id": 5,
"name": "Bounty Hunter (Legacy) - Rogue", "name": "Bounty Hunter (Legacy) - Rogue",
"rank": 103672, "rank": 100923,
"score": 7 "score": 7
}, },
{ "id": 5, "name": "Clue Scrolls (all)", "rank": 253, "score": 9508 }, {
{ "id": 6, "name": "Clue Scrolls (beginner)", "rank": 713, "score": 825 }, "id": 6,
{ "id": 7, "name": "Clue Scrolls (easy)", "rank": 71, "score": 6000 }, "name": "Clue Scrolls (all)",
{ "id": 8, "name": "Clue Scrolls (medium)", "rank": 1943, "score": 1600 }, "rank": 433,
{ "id": 9, "name": "Clue Scrolls (hard)", "rank": 42364, "score": 287 }, "score": 9802
{ "id": 10, "name": "Clue Scrolls (elite)", "rank": 467, "score": 436 }, },
{ "id": 11, "name": "Clue Scrolls (master)", "rank": 1634, "score": 360 }, {
{ "id": 12, "name": "LMS - Rank", "rank": 12937, "score": 2521 }, "id": 7,
{ "id": 13, "name": "PvP Arena - Rank", "rank": -1, "score": -1 }, "name": "Clue Scrolls (beginner)",
{ "id": 14, "name": "Soul Wars Zeal", "rank": 5222, "score": 14780 }, "rank": 1542,
{ "id": 15, "name": "Rifts closed", "rank": 3007, "score": 1060 }, "score": 825
{ "id": 16, "name": "Abyssal Sire", "rank": 2578, "score": 2192 }, },
{ "id": 17, "name": "Alchemical Hydra", "rank": 84703, "score": 594 }, {
{ "id": 18, "name": "Artio", "rank": 19500, "score": 143 }, "id": 8,
{ "id": 19, "name": "Barrows Chests", "rank": 3335, "score": 1830 }, "name": "Clue Scrolls (easy)",
{ "id": 20, "name": "Bryophyta", "rank": 191697, "score": 5 }, "rank": 158,
{ "id": 21, "name": "Callisto", "rank": 27457, "score": 293 }, "score": 6000
{ "id": 22, "name": "Calvar'ion", "rank": 43607, "score": 58 }, },
{ "id": 23, "name": "Cerberus", "rank": 17384, "score": 1905 }, {
{ "id": 24, "name": "Chambers of Xeric", "rank": 171607, "score": 33 }, "id": 9,
"name": "Clue Scrolls (medium)",
"rank": 2572,
"score": 1606
},
{
"id": 10,
"name": "Clue Scrolls (hard)",
"rank": 47979,
"score": 311
},
{
"id": 11,
"name": "Clue Scrolls (elite)",
"rank": 1081,
"score": 460
},
{
"id": 12,
"name": "Clue Scrolls (master)",
"rank": 880,
"score": 600
},
{
"id": 13,
"name": "LMS - Rank",
"rank": 4258,
"score": 6785
},
{
"id": 14,
"name": "PvP Arena - Rank",
"rank": -1,
"score": -1
},
{
"id": 15,
"name": "Soul Wars Zeal",
"rank": 7596,
"score": 14780
},
{
"id": 16,
"name": "Rifts closed",
"rank": 8124,
"score": 1060
},
{
"id": 17,
"name": "Colosseum Glory",
"rank": 10438,
"score": 43487
},
{
"id": 18,
"name": "Collections Logged",
"rank": 1114,
"score": 1155
},
{
"id": 19,
"name": "Abyssal Sire",
"rank": 3497,
"score": 2192
},
{
"id": 20,
"name": "Alchemical Hydra",
"rank": 3204,
"score": 4796
},
{
"id": 21,
"name": "Amoxliatl",
"rank": 1087,
"score": 984
},
{
"id": 22,
"name": "Araxxor",
"rank": 2230,
"score": 2328
},
{
"id": 23,
"name": "Artio",
"rank": 51533,
"score": 143
},
{
"id": 24,
"name": "Barrows Chests",
"rank": 4243,
"score": 1830
},
{ {
"id": 25, "id": 25,
"name": "Chambers of Xeric: Challenge Mode", "name": "Bryophyta",
"rank": 2074, "rank": 256985,
"score": 501 "score": 5
},
{
"id": 26,
"name": "Callisto",
"rank": 54424,
"score": 293
},
{
"id": 27,
"name": "Calvar'ion",
"rank": 114691,
"score": 58
},
{
"id": 28,
"name": "Cerberus",
"rank": 11700,
"score": 2657
},
{
"id": 29,
"name": "Chambers of Xeric",
"rank": 211708,
"score": 34
},
{
"id": 30,
"name": "Chambers of Xeric: Challenge Mode",
"rank": 1779,
"score": 736
},
{
"id": 31,
"name": "Chaos Elemental",
"rank": 24958,
"score": 215
},
{
"id": 32,
"name": "Chaos Fanatic",
"rank": 46504,
"score": 116
},
{
"id": 33,
"name": "Commander Zilyana",
"rank": 66096,
"score": 287
},
{
"id": 34,
"name": "Corporeal Beast",
"rank": 3133,
"score": 2000
},
{
"id": 35,
"name": "Crazy Archaeologist",
"rank": 26682,
"score": 198
},
{
"id": 36,
"name": "Dagannoth Prime",
"rank": 19337,
"score": 1078
},
{
"id": 37,
"name": "Dagannoth Rex",
"rank": 25021,
"score": 1062
},
{
"id": 38,
"name": "Dagannoth Supreme",
"rank": 19290,
"score": 1088
},
{
"id": 39,
"name": "Deranged Archaeologist",
"rank": 89474,
"score": 25
},
{
"id": 40,
"name": "Duke Sucellus",
"rank": 7535,
"score": 1320
},
{
"id": 41,
"name": "General Graardor",
"rank": 23251,
"score": 1228
},
{
"id": 42,
"name": "Giant Mole",
"rank": 82016,
"score": 477
},
{
"id": 43,
"name": "Grotesque Guardians",
"rank": 876,
"score": 3642
},
{
"id": 44,
"name": "Hespori",
"rank": 7073,
"score": 310
},
{
"id": 45,
"name": "Kalphite Queen",
"rank": 2476,
"score": 2046
},
{
"id": 46,
"name": "King Black Dragon",
"rank": 55411,
"score": 580
},
{
"id": 47,
"name": "Kraken",
"rank": 68801,
"score": 2899
},
{
"id": 48,
"name": "Kree'Arra",
"rank": 4608,
"score": 1740
},
{
"id": 49,
"name": "K'ril Tsutsaroth",
"rank": 3079,
"score": 1444
},
{
"id": 50,
"name": "Lunar Chests",
"rank": 8344,
"score": 324
},
{
"id": 51,
"name": "Mimic",
"rank": 540,
"score": 53
},
{
"id": 52,
"name": "Nex",
"rank": 38395,
"score": 626
},
{
"id": 53,
"name": "Nightmare",
"rank": 4176,
"score": 749
},
{
"id": 54,
"name": "Phosani's Nightmare",
"rank": 5519,
"score": 500
},
{
"id": 55,
"name": "Obor",
"rank": 1394,
"score": 217
},
{
"id": 56,
"name": "Phantom Muspah",
"rank": 26127,
"score": 379
},
{
"id": 57,
"name": "Sarachnis",
"rank": 49730,
"score": 249
},
{
"id": 58,
"name": "Scorpia",
"rank": 57206,
"score": 91
},
{
"id": 59,
"name": "Scurrius",
"rank": 6106,
"score": 1245
},
{
"id": 60,
"name": "Skotizo",
"rank": 185920,
"score": 29
}, },
{ "id": 26, "name": "Chaos Elemental", "rank": 78908, "score": 50 },
{ "id": 27, "name": "Chaos Fanatic", "rank": 135830, "score": 26 },
{ "id": 28, "name": "Commander Zilyana", "rank": 48781, "score": 287 },
{ "id": 29, "name": "Corporeal Beast", "rank": 2112, "score": 2000 },
{ "id": 30, "name": "Crazy Archaeologist", "rank": 138748, "score": 41 },
{ "id": 31, "name": "Dagannoth Prime", "rank": 31297, "score": 707 },
{ "id": 32, "name": "Dagannoth Rex", "rank": 40908, "score": 698 },
{ "id": 33, "name": "Dagannoth Supreme", "rank": 31273, "score": 714 },
{ "id": 34, "name": "Deranged Archaeologist", "rank": 76034, "score": 25 },
{ "id": 35, "name": "Duke Sucellus", "rank": 2391, "score": 688 },
{ "id": 36, "name": "General Graardor", "rank": 17409, "score": 1228 },
{ "id": 37, "name": "Giant Mole", "rank": 60841, "score": 474 },
{ "id": 38, "name": "Grotesque Guardians", "rank": 1895, "score": 2140 },
{ "id": 39, "name": "Hespori", "rank": 19948, "score": 159 },
{ "id": 40, "name": "Kalphite Queen", "rank": 1855, "score": 2046 },
{ "id": 41, "name": "King Black Dragon", "rank": 46423, "score": 579 },
{ "id": 42, "name": "Kraken", "rank": 107879, "score": 1908 },
{ "id": 43, "name": "Kree'Arra", "rank": 9791, "score": 920 },
{ "id": 44, "name": "K'ril Tsutsaroth", "rank": 2050, "score": 1444 },
{ "id": 45, "name": "Mimic", "rank": 848, "score": 33 },
{ "id": 46, "name": "Nex", "rank": 24797, "score": 620 },
{ "id": 47, "name": "Nightmare", "rank": 4157, "score": 744 },
{ "id": 48, "name": "Phosani's Nightmare", "rank": 4154, "score": 500 },
{ "id": 49, "name": "Obor", "rank": 880, "score": 217 },
{ "id": 50, "name": "Phantom Muspah", "rank": 15860, "score": 251 },
{ "id": 51, "name": "Sarachnis", "rank": 60424, "score": 119 },
{ "id": 52, "name": "Scorpia", "rank": 100429, "score": 26 },
{ "id": 53, "name": "Skotizo", "rank": 358191, "score": 9 },
{ "id": 54, "name": "Spindel", "rank": 1131, "score": 1569 },
{ "id": 55, "name": "Tempoross", "rank": 33908, "score": 273 },
{ "id": 56, "name": "The Gauntlet", "rank": 165651, "score": 7 },
{ "id": 57, "name": "The Corrupted Gauntlet", "rank": 64278, "score": 201 },
{ "id": 58, "name": "The Leviathan", "rank": 1533, "score": 583 },
{ "id": 59, "name": "The Whisperer", "rank": 748, "score": 700 },
{ "id": 60, "name": "Theatre of Blood", "rank": 21700, "score": 250 },
{ {
"id": 61, "id": 61,
"name": "Theatre of Blood: Hard Mode", "name": "Sol Heredit",
"rank": 13200, "rank": 3232,
"score": 7 "score": 49
}, },
{ {
"id": 62, "id": 62,
"name": "Thermonuclear Smoke Devil", "name": "Spindel",
"rank": 6622, "rank": 4276,
"score": 3066 "score": 1569
},
{
"id": 63,
"name": "Tempoross",
"rank": 57314,
"score": 273
}, },
{ "id": 63, "name": "Tombs of Amascut", "rank": 87093, "score": 35 },
{ {
"id": 64, "id": 64,
"name": "Tombs of Amascut: Expert Mode", "name": "The Gauntlet",
"rank": 2449, "rank": 256794,
"score": 502 "score": 7
}, },
{ "id": 65, "name": "TzKal-Zuk", "rank": 14541, "score": 2 }, {
{ "id": 66, "name": "TzTok-Jad", "rank": -1, "score": -1 }, "id": 65,
{ "id": 67, "name": "Vardorvis", "rank": 1048, "score": 1432 }, "name": "The Corrupted Gauntlet",
{ "id": 68, "name": "Venenatis", "rank": 138, "score": 7096 }, "rank": 113862,
{ "id": 69, "name": "Vet'ion", "rank": 58203, "score": 51 }, "score": 201
{ "id": 70, "name": "Vorkath", "rank": 13949, "score": 2780 }, },
{ "id": 71, "name": "Wintertodt", "rank": 827440, "score": 62 }, {
{ "id": 72, "name": "Zalcano", "rank": 153191, "score": 25 }, "id": 66,
{ "id": 73, "name": "Zulrah", "rank": 216690, "score": 274 } "name": "The Hueycoatl",
"rank": 1969,
"score": 538
},
{
"id": 67,
"name": "The Leviathan",
"rank": 12346,
"score": 671
},
{
"id": 68,
"name": "The Royal Titans",
"rank": 5606,
"score": 149
},
{
"id": 69,
"name": "The Whisperer",
"rank": 550,
"score": 2450
},
{
"id": 70,
"name": "Theatre of Blood",
"rank": 25557,
"score": 310
},
{
"id": 71,
"name": "Theatre of Blood: Hard Mode",
"rank": 1391,
"score": 538
},
{
"id": 72,
"name": "Thermonuclear Smoke Devil",
"rank": 9325,
"score": 3066
},
{
"id": 73,
"name": "Tombs of Amascut",
"rank": 131996,
"score": 37
},
{
"id": 74,
"name": "Tombs of Amascut: Expert Mode",
"rank": 214,
"score": 1720
},
{
"id": 75,
"name": "TzKal-Zuk",
"rank": 8902,
"score": 7
},
{
"id": 76,
"name": "TzTok-Jad",
"rank": 148385,
"score": 8
},
{
"id": 77,
"name": "Vardorvis",
"rank": 6120,
"score": 2113
},
{
"id": 78,
"name": "Venenatis",
"rank": 287,
"score": 7096
},
{
"id": 79,
"name": "Vet'ion",
"rank": 97368,
"score": 51
},
{
"id": 80,
"name": "Vorkath",
"rank": 15591,
"score": 2780
},
{
"id": 81,
"name": "Wintertodt",
"rank": 1000405,
"score": 67
},
{
"id": 82,
"name": "Zalcano",
"rank": 213696,
"score": 25
},
{
"id": 83,
"name": "Zulrah",
"rank": 240082,
"score": 340
}
] ]
} }

View File

@@ -12,7 +12,7 @@ import {
getSkillPageURL, getSkillPageURL,
getStatsURL, getStatsURL,
BOSSES, BOSSES,
INVALID_FORMAT_ERROR, InvalidFormatError,
BH_MODES, BH_MODES,
parseJsonStats, parseJsonStats,
HiscoresResponse HiscoresResponse
@@ -86,6 +86,7 @@ test('Parse CSV to json', () => {
810,99,37688883 810,99,37688883
92,99,32005622 92,99,32005622
23423,478 23423,478
89554,301
89914,35 89914,35
99834,25 99834,25
99831,23 99831,23
@@ -101,8 +102,12 @@ test('Parse CSV to json', () => {
13,4057 13,4057
37,225 37,225
25,1110 25,1110
7827,43249
1114,1155
382,2780 382,2780
944,3000 944,3000
561,398429
37,111
704,892 704,892
1981,1452 1981,1452
4981,23 4981,23
@@ -130,6 +135,7 @@ test('Parse CSV to json', () => {
41643,1477 41643,1477
625,2391 625,2391
120,2981 120,2981
54,2958
1,109 1,109
99,39002 99,39002
3,22666 3,22666
@@ -138,12 +144,16 @@ test('Parse CSV to json', () => {
44,6233 44,6233
201,1101 201,1101
82,3404 82,3404
555,7079
5085,61 5085,61
8731,1423
678,903 678,903
18823,23 18823,23
63,375 63,375
2870,6 2870,6
891,9102
2871,7 2871,7
5606,149
2872,8 2872,8
6984,138 6984,138
23,923141 23,923141
@@ -188,6 +198,7 @@ test('Parse CSV to json', () => {
construction: { rank: 92, level: 99, xp: 32005622 } construction: { rank: 92, level: 99, xp: 32005622 }
}, },
leaguePoints: { rank: 23423, score: 478 }, leaguePoints: { rank: 23423, score: 478 },
deadmanPoints: { rank: 89554, score: 301 },
bountyHunter: { bountyHunter: {
hunterV2: { rank: 89914, score: 35 }, hunterV2: { rank: 89914, score: 35 },
rogueV2: { rank: 99834, score: 25 }, rogueV2: { rank: 99834, score: 25 },
@@ -198,6 +209,8 @@ test('Parse CSV to json', () => {
pvpArena: { rank: 13, score: 4057 }, pvpArena: { rank: 13, score: 4057 },
soulWarsZeal: { rank: 37, score: 225 }, soulWarsZeal: { rank: 37, score: 225 },
riftsClosed: { rank: 25, score: 1110 }, riftsClosed: { rank: 25, score: 1110 },
colosseumGlory: { rank: 7827, score: 43249 },
collectionsLogged: { rank: 1114, score: 1155 },
clues: { clues: {
all: { rank: 32, score: 12148 }, all: { rank: 32, score: 12148 },
beginner: { rank: 3105, score: 76 }, beginner: { rank: 3105, score: 76 },
@@ -210,6 +223,8 @@ test('Parse CSV to json', () => {
bosses: { bosses: {
abyssalSire: { rank: 382, score: 2780 }, abyssalSire: { rank: 382, score: 2780 },
alchemicalHydra: { rank: 944, score: 3000 }, alchemicalHydra: { rank: 944, score: 3000 },
amoxliatl: { rank: 561, score: 398429 },
araxxor: { rank: 37, score: 111 },
artio: { rank: 704, score: 892 }, artio: { rank: 704, score: 892 },
barrows: { rank: 1981, score: 1452 }, barrows: { rank: 1981, score: 1452 },
bryophyta: { rank: 4981, score: 23 }, bryophyta: { rank: 4981, score: 23 },
@@ -237,6 +252,7 @@ test('Parse CSV to json', () => {
kraken: { rank: 41643, score: 1477 }, kraken: { rank: 41643, score: 1477 },
kreeArra: { rank: 625, score: 2391 }, kreeArra: { rank: 625, score: 2391 },
krilTsutsaroth: { rank: 120, score: 2981 }, krilTsutsaroth: { rank: 120, score: 2981 },
lunarChests: { rank: 54, score: 2958 },
mimic: { rank: 1, score: 109 }, mimic: { rank: 1, score: 109 },
nex: { rank: 99, score: 39002 }, nex: { rank: 99, score: 39002 },
nightmare: { rank: 3, score: 22666 }, nightmare: { rank: 3, score: 22666 },
@@ -245,12 +261,16 @@ test('Parse CSV to json', () => {
phantomMuspah: { rank: 44, score: 6233 }, phantomMuspah: { rank: 44, score: 6233 },
sarachnis: { rank: 201, score: 1101 }, sarachnis: { rank: 201, score: 1101 },
scorpia: { rank: 82, score: 3404 }, scorpia: { rank: 82, score: 3404 },
scurrius: { rank: 555, score: 7079 },
skotizo: { rank: 5085, score: 61 }, skotizo: { rank: 5085, score: 61 },
solHeredit: { rank: 8731, score: 1423 },
spindel: { rank: 678, score: 903 }, spindel: { rank: 678, score: 903 },
tempoross: { rank: 18823, score: 23 }, tempoross: { rank: 18823, score: 23 },
gauntlet: { rank: 63, score: 375 }, gauntlet: { rank: 63, score: 375 },
corruptedGauntlet: { rank: 2870, score: 6 }, corruptedGauntlet: { rank: 2870, score: 6 },
hueycoatl: { rank: 891, score: 9102 },
leviathan: { rank: 2871, score: 7 }, leviathan: { rank: 2871, score: 7 },
royalTitans: { rank: 5606, score: 149 },
whisperer: { rank: 2872, score: 8 }, whisperer: { rank: 2872, score: 8 },
theatreOfBlood: { rank: 6984, score: 138 }, theatreOfBlood: { rank: 6984, score: 138 },
theatreOfBloodHardMode: { rank: 23, score: 923141 }, theatreOfBloodHardMode: { rank: 23, score: 923141 },
@@ -276,12 +296,12 @@ test('Parse CSV with unknown activity', () => {
const statsWithUnknownActivity = `${lynxTitanStats} const statsWithUnknownActivity = `${lynxTitanStats}
-1,-1`; -1,-1`;
expect(() => parseStats(statsWithUnknownActivity)).toThrow( expect(() => parseStats(statsWithUnknownActivity)).toThrow(
INVALID_FORMAT_ERROR InvalidFormatError
); );
}); });
test('Parse invalid CSV', () => { test('Parse invalid CSV', () => {
expect(() => parseStats('invalid')).toThrow(INVALID_FORMAT_ERROR); expect(() => parseStats('invalid')).toThrow(InvalidFormatError);
}); });
describe('Get name format', () => { describe('Get name format', () => {
@@ -580,6 +600,12 @@ describe('Get stats options', () => {
) )
).toBeFalsy(); ).toBeFalsy();
}); });
it('omits excluded gamemodes', async () => {
const response = await getStats(rsn, {
otherGamemodes: ['ironman', 'ultimate']
});
expect(response.hardcore).toBeUndefined();
});
}); });
test('CSV and JSON parsing outputs identical object', async () => { test('CSV and JSON parsing outputs identical object', async () => {

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,68 @@
{ {
"skills": [ "skills": [
{ "id": 0, "name": "Overall", "rank": 1, "level": 2277, "xp": 4600000000 }, {
{ "id": 1, "name": "Attack", "rank": 15, "level": 99, "xp": 200000000 }, "id": 0,
{ "id": 2, "name": "Defence", "rank": 28, "level": 99, "xp": 200000000 }, "name": "Overall",
{ "id": 3, "name": "Strength", "rank": 18, "level": 99, "xp": 200000000 }, "rank": 1,
{ "id": 4, "name": "Hitpoints", "rank": 7, "level": 99, "xp": 200000000 }, "level": 2277,
{ "id": 5, "name": "Ranged", "rank": 8, "level": 99, "xp": 200000000 }, "xp": 4600000000
{ "id": 6, "name": "Prayer", "rank": 11, "level": 99, "xp": 200000000 }, },
{ "id": 7, "name": "Magic", "rank": 32, "level": 99, "xp": 200000000 }, {
{ "id": 8, "name": "Cooking", "rank": 157, "level": 99, "xp": 200000000 }, "id": 1,
"name": "Attack",
"rank": 15,
"level": 99,
"xp": 200000000
},
{
"id": 2,
"name": "Defence",
"rank": 28,
"level": 99,
"xp": 200000000
},
{
"id": 3,
"name": "Strength",
"rank": 18,
"level": 99,
"xp": 200000000
},
{
"id": 4,
"name": "Hitpoints",
"rank": 7,
"level": 99,
"xp": 200000000
},
{
"id": 5,
"name": "Ranged",
"rank": 8,
"level": 99,
"xp": 200000000
},
{
"id": 6,
"name": "Prayer",
"rank": 11,
"level": 99,
"xp": 200000000
},
{
"id": 7,
"name": "Magic",
"rank": 30,
"level": 99,
"xp": 200000000
},
{
"id": 8,
"name": "Cooking",
"rank": 149,
"level": 99,
"xp": 200000000
},
{ {
"id": 9, "id": 9,
"name": "Woodcutting", "name": "Woodcutting",
@@ -16,8 +70,20 @@
"level": 99, "level": 99,
"xp": 200000000 "xp": 200000000
}, },
{ "id": 10, "name": "Fletching", "rank": 12, "level": 99, "xp": 200000000 }, {
{ "id": 11, "name": "Fishing", "rank": 9, "level": 99, "xp": 200000000 }, "id": 10,
"name": "Fletching",
"rank": 12,
"level": 99,
"xp": 200000000
},
{
"id": 11,
"name": "Fishing",
"rank": 9,
"level": 99,
"xp": 200000000
},
{ {
"id": 12, "id": 12,
"name": "Firemaking", "name": "Firemaking",
@@ -25,16 +91,76 @@
"level": 99, "level": 99,
"xp": 200000000 "xp": 200000000
}, },
{ "id": 13, "name": "Crafting", "rank": 4, "level": 99, "xp": 200000000 }, {
{ "id": 14, "name": "Smithing", "rank": 3, "level": 99, "xp": 200000000 }, "id": 13,
{ "id": 15, "name": "Mining", "rank": 25, "level": 99, "xp": 200000000 }, "name": "Crafting",
{ "id": 16, "name": "Herblore", "rank": 5, "level": 99, "xp": 200000000 }, "rank": 4,
{ "id": 17, "name": "Agility", "rank": 24, "level": 99, "xp": 200000000 }, "level": 99,
{ "id": 18, "name": "Thieving", "rank": 12, "level": 99, "xp": 200000000 }, "xp": 200000000
{ "id": 19, "name": "Slayer", "rank": 2, "level": 99, "xp": 200000000 }, },
{ "id": 20, "name": "Farming", "rank": 19, "level": 99, "xp": 200000000 }, {
{ "id": 21, "name": "Runecraft", "rank": 7, "level": 99, "xp": 200000000 }, "id": 14,
{ "id": 22, "name": "Hunter", "rank": 4, "level": 99, "xp": 200000000 }, "name": "Smithing",
"rank": 3,
"level": 99,
"xp": 200000000
},
{
"id": 15,
"name": "Mining",
"rank": 23,
"level": 99,
"xp": 200000000
},
{
"id": 16,
"name": "Herblore",
"rank": 5,
"level": 99,
"xp": 200000000
},
{
"id": 17,
"name": "Agility",
"rank": 24,
"level": 99,
"xp": 200000000
},
{
"id": 18,
"name": "Thieving",
"rank": 12,
"level": 99,
"xp": 200000000
},
{
"id": 19,
"name": "Slayer",
"rank": 2,
"level": 99,
"xp": 200000000
},
{
"id": 20,
"name": "Farming",
"rank": 19,
"level": 99,
"xp": 200000000
},
{
"id": 21,
"name": "Runecraft",
"rank": 6,
"level": 99,
"xp": 200000000
},
{
"id": 22,
"name": "Hunter",
"rank": 3,
"level": 99,
"xp": 200000000
},
{ {
"id": 23, "id": 23,
"name": "Construction", "name": "Construction",
@@ -44,104 +170,509 @@
} }
], ],
"activities": [ "activities": [
{ "id": 0, "name": "League Points", "rank": -1, "score": -1 }, {
{ "id": 1, "name": "Bounty Hunter - Hunter", "rank": -1, "score": -1 }, "id": 0,
{ "id": 2, "name": "Bounty Hunter - Rogue", "rank": -1, "score": -1 }, "name": "League Points",
"rank": -1,
"score": -1
},
{
"id": 1,
"name": "Deadman Points",
"rank": -1,
"score": -1
},
{
"id": 2,
"name": "Bounty Hunter - Hunter",
"rank": -1,
"score": -1
},
{ {
"id": 3, "id": 3,
"name": "Bounty Hunter (Legacy) - Hunter", "name": "Bounty Hunter - Rogue",
"rank": -1, "rank": -1,
"score": -1 "score": -1
}, },
{ {
"id": 4, "id": 4,
"name": "Bounty Hunter (Legacy) - Hunter",
"rank": -1,
"score": -1
},
{
"id": 5,
"name": "Bounty Hunter (Legacy) - Rogue", "name": "Bounty Hunter (Legacy) - Rogue",
"rank": -1, "rank": -1,
"score": -1 "score": -1
}, },
{ "id": 5, "name": "Clue Scrolls (all)", "rank": 769527, "score": 22 }, {
{ "id": 6, "name": "Clue Scrolls (beginner)", "rank": -1, "score": -1 }, "id": 6,
{ "id": 7, "name": "Clue Scrolls (easy)", "rank": -1, "score": -1 }, "name": "Clue Scrolls (all)",
{ "id": 8, "name": "Clue Scrolls (medium)", "rank": -1, "score": -1 }, "rank": 937868,
{ "id": 9, "name": "Clue Scrolls (hard)", "rank": 483333, "score": 22 }, "score": 22
{ "id": 10, "name": "Clue Scrolls (elite)", "rank": -1, "score": -1 }, },
{ "id": 11, "name": "Clue Scrolls (master)", "rank": -1, "score": -1 }, {
{ "id": 12, "name": "LMS - Rank", "rank": -1, "score": -1 }, "id": 7,
{ "id": 13, "name": "PvP Arena - Rank", "rank": -1, "score": -1 }, "name": "Clue Scrolls (beginner)",
{ "id": 14, "name": "Soul Wars Zeal", "rank": -1, "score": -1 }, "rank": -1,
{ "id": 15, "name": "Rifts closed", "rank": -1, "score": -1 }, "score": -1
{ "id": 16, "name": "Abyssal Sire", "rank": -1, "score": -1 }, },
{ "id": 17, "name": "Alchemical Hydra", "rank": -1, "score": -1 }, {
{ "id": 18, "name": "Artio", "rank": -1, "score": -1 }, "id": 8,
{ "id": 19, "name": "Barrows Chests", "rank": -1, "score": -1 }, "name": "Clue Scrolls (easy)",
{ "id": 20, "name": "Bryophyta", "rank": -1, "score": -1 }, "rank": -1,
{ "id": 21, "name": "Callisto", "rank": -1, "score": -1 }, "score": -1
{ "id": 22, "name": "Calvar'ion", "rank": -1, "score": -1 }, },
{ "id": 23, "name": "Cerberus", "rank": -1, "score": -1 }, {
{ "id": 24, "name": "Chambers of Xeric", "rank": -1, "score": -1 }, "id": 9,
"name": "Clue Scrolls (medium)",
"rank": -1,
"score": -1
},
{
"id": 10,
"name": "Clue Scrolls (hard)",
"rank": 578038,
"score": 22
},
{
"id": 11,
"name": "Clue Scrolls (elite)",
"rank": -1,
"score": -1
},
{
"id": 12,
"name": "Clue Scrolls (master)",
"rank": -1,
"score": -1
},
{
"id": 13,
"name": "LMS - Rank",
"rank": -1,
"score": -1
},
{
"id": 14,
"name": "PvP Arena - Rank",
"rank": -1,
"score": -1
},
{
"id": 15,
"name": "Soul Wars Zeal",
"rank": -1,
"score": -1
},
{
"id": 16,
"name": "Rifts closed",
"rank": -1,
"score": -1
},
{
"id": 17,
"name": "Colosseum Glory",
"rank": -1,
"score": -1
},
{
"id": 18,
"name": "Collections Logged",
"rank": -1,
"score": -1
},
{
"id": 19,
"name": "Abyssal Sire",
"rank": -1,
"score": -1
},
{
"id": 20,
"name": "Alchemical Hydra",
"rank": -1,
"score": -1
},
{
"id": 21,
"name": "Amoxliatl",
"rank": -1,
"score": -1
},
{
"id": 22,
"name": "Araxxor",
"rank": -1,
"score": -1
},
{
"id": 23,
"name": "Artio",
"rank": -1,
"score": -1
},
{
"id": 24,
"name": "Barrows Chests",
"rank": -1,
"score": -1
},
{ {
"id": 25, "id": 25,
"name": "Bryophyta",
"rank": -1,
"score": -1
},
{
"id": 26,
"name": "Callisto",
"rank": -1,
"score": -1
},
{
"id": 27,
"name": "Calvar'ion",
"rank": -1,
"score": -1
},
{
"id": 28,
"name": "Cerberus",
"rank": -1,
"score": -1
},
{
"id": 29,
"name": "Chambers of Xeric",
"rank": -1,
"score": -1
},
{
"id": 30,
"name": "Chambers of Xeric: Challenge Mode", "name": "Chambers of Xeric: Challenge Mode",
"rank": -1, "rank": -1,
"score": -1 "score": -1
}, },
{ "id": 26, "name": "Chaos Elemental", "rank": -1, "score": -1 }, {
{ "id": 27, "name": "Chaos Fanatic", "rank": -1, "score": -1 }, "id": 31,
{ "id": 28, "name": "Commander Zilyana", "rank": -1, "score": -1 }, "name": "Chaos Elemental",
{ "id": 29, "name": "Corporeal Beast", "rank": -1, "score": -1 }, "rank": -1,
{ "id": 30, "name": "Crazy Archaeologist", "rank": -1, "score": -1 }, "score": -1
{ "id": 31, "name": "Dagannoth Prime", "rank": -1, "score": -1 }, },
{ "id": 32, "name": "Dagannoth Rex", "rank": -1, "score": -1 }, {
{ "id": 33, "name": "Dagannoth Supreme", "rank": -1, "score": -1 }, "id": 32,
{ "id": 34, "name": "Deranged Archaeologist", "rank": -1, "score": -1 }, "name": "Chaos Fanatic",
{ "id": 35, "name": "Duke Sucellus", "rank": -1, "score": -1 }, "rank": -1,
{ "id": 36, "name": "General Graardor", "rank": -1, "score": -1 }, "score": -1
{ "id": 37, "name": "Giant Mole", "rank": -1, "score": -1 }, },
{ "id": 38, "name": "Grotesque Guardians", "rank": -1, "score": -1 }, {
{ "id": 39, "name": "Hespori", "rank": -1, "score": -1 }, "id": 33,
{ "id": 40, "name": "Kalphite Queen", "rank": -1, "score": -1 }, "name": "Commander Zilyana",
{ "id": 41, "name": "King Black Dragon", "rank": -1, "score": -1 }, "rank": -1,
{ "id": 42, "name": "Kraken", "rank": -1, "score": -1 }, "score": -1
{ "id": 43, "name": "Kree'Arra", "rank": -1, "score": -1 }, },
{ "id": 44, "name": "K'ril Tsutsaroth", "rank": -1, "score": -1 }, {
{ "id": 45, "name": "Mimic", "rank": -1, "score": -1 }, "id": 34,
{ "id": 46, "name": "Nex", "rank": -1, "score": -1 }, "name": "Corporeal Beast",
{ "id": 47, "name": "Nightmare", "rank": -1, "score": -1 }, "rank": -1,
{ "id": 48, "name": "Phosani's Nightmare", "rank": -1, "score": -1 }, "score": -1
{ "id": 49, "name": "Obor", "rank": -1, "score": -1 }, },
{ "id": 50, "name": "Phantom Muspah", "rank": -1, "score": -1 }, {
{ "id": 51, "name": "Sarachnis", "rank": -1, "score": -1 }, "id": 35,
{ "id": 52, "name": "Scorpia", "rank": -1, "score": -1 }, "name": "Crazy Archaeologist",
{ "id": 53, "name": "Skotizo", "rank": -1, "score": -1 }, "rank": -1,
{ "id": 54, "name": "Spindel", "rank": -1, "score": -1 }, "score": -1
{ "id": 55, "name": "Tempoross", "rank": -1, "score": -1 }, },
{ "id": 56, "name": "The Gauntlet", "rank": -1, "score": -1 }, {
{ "id": 57, "name": "The Corrupted Gauntlet", "rank": -1, "score": -1 }, "id": 36,
{ "id": 58, "name": "The Leviathan", "rank": -1, "score": -1 }, "name": "Dagannoth Prime",
{ "id": 59, "name": "The Whisperer", "rank": -1, "score": -1 }, "rank": -1,
{ "id": 60, "name": "Theatre of Blood", "rank": -1, "score": -1 }, "score": -1
},
{
"id": 37,
"name": "Dagannoth Rex",
"rank": -1,
"score": -1
},
{
"id": 38,
"name": "Dagannoth Supreme",
"rank": -1,
"score": -1
},
{
"id": 39,
"name": "Deranged Archaeologist",
"rank": -1,
"score": -1
},
{
"id": 40,
"name": "Duke Sucellus",
"rank": -1,
"score": -1
},
{
"id": 41,
"name": "General Graardor",
"rank": -1,
"score": -1
},
{
"id": 42,
"name": "Giant Mole",
"rank": -1,
"score": -1
},
{
"id": 43,
"name": "Grotesque Guardians",
"rank": -1,
"score": -1
},
{
"id": 44,
"name": "Hespori",
"rank": -1,
"score": -1
},
{
"id": 45,
"name": "Kalphite Queen",
"rank": -1,
"score": -1
},
{
"id": 46,
"name": "King Black Dragon",
"rank": -1,
"score": -1
},
{
"id": 47,
"name": "Kraken",
"rank": -1,
"score": -1
},
{
"id": 48,
"name": "Kree'Arra",
"rank": -1,
"score": -1
},
{
"id": 49,
"name": "K'ril Tsutsaroth",
"rank": -1,
"score": -1
},
{
"id": 50,
"name": "Lunar Chests",
"rank": -1,
"score": -1
},
{
"id": 51,
"name": "Mimic",
"rank": -1,
"score": -1
},
{
"id": 52,
"name": "Nex",
"rank": -1,
"score": -1
},
{
"id": 53,
"name": "Nightmare",
"rank": -1,
"score": -1
},
{
"id": 54,
"name": "Phosani's Nightmare",
"rank": -1,
"score": -1
},
{
"id": 55,
"name": "Obor",
"rank": -1,
"score": -1
},
{
"id": 56,
"name": "Phantom Muspah",
"rank": -1,
"score": -1
},
{
"id": 57,
"name": "Sarachnis",
"rank": -1,
"score": -1
},
{
"id": 58,
"name": "Scorpia",
"rank": -1,
"score": -1
},
{
"id": 59,
"name": "Scurrius",
"rank": -1,
"score": -1
},
{
"id": 60,
"name": "Skotizo",
"rank": -1,
"score": -1
},
{ {
"id": 61, "id": 61,
"name": "Sol Heredit",
"rank": -1,
"score": -1
},
{
"id": 62,
"name": "Spindel",
"rank": -1,
"score": -1
},
{
"id": 63,
"name": "Tempoross",
"rank": -1,
"score": -1
},
{
"id": 64,
"name": "The Gauntlet",
"rank": -1,
"score": -1
},
{
"id": 65,
"name": "The Corrupted Gauntlet",
"rank": -1,
"score": -1
},
{
"id": 66,
"name": "The Hueycoatl",
"rank": -1,
"score": -1
},
{
"id": 67,
"name": "The Leviathan",
"rank": -1,
"score": -1
},
{
"id": 68,
"name": "The Royal Titans",
"rank": -1,
"score": -1
},
{
"id": 69,
"name": "The Whisperer",
"rank": -1,
"score": -1
},
{
"id": 70,
"name": "Theatre of Blood",
"rank": -1,
"score": -1
},
{
"id": 71,
"name": "Theatre of Blood: Hard Mode", "name": "Theatre of Blood: Hard Mode",
"rank": -1, "rank": -1,
"score": -1 "score": -1
}, },
{ "id": 62, "name": "Thermonuclear Smoke Devil", "rank": -1, "score": -1 },
{ "id": 63, "name": "Tombs of Amascut", "rank": -1, "score": -1 },
{ {
"id": 64, "id": 72,
"name": "Thermonuclear Smoke Devil",
"rank": -1,
"score": -1
},
{
"id": 73,
"name": "Tombs of Amascut",
"rank": -1,
"score": -1
},
{
"id": 74,
"name": "Tombs of Amascut: Expert Mode", "name": "Tombs of Amascut: Expert Mode",
"rank": -1, "rank": -1,
"score": -1 "score": -1
}, },
{ "id": 65, "name": "TzKal-Zuk", "rank": -1, "score": -1 }, {
{ "id": 66, "name": "TzTok-Jad", "rank": 198, "score": 186 }, "id": 75,
{ "id": 67, "name": "Vardorvis", "rank": -1, "score": -1 }, "name": "TzKal-Zuk",
{ "id": 68, "name": "Venenatis", "rank": -1, "score": -1 }, "rank": -1,
{ "id": 69, "name": "Vet'ion", "rank": -1, "score": -1 }, "score": -1
{ "id": 70, "name": "Vorkath", "rank": -1, "score": -1 }, },
{ "id": 71, "name": "Wintertodt", "rank": -1, "score": -1 }, {
{ "id": 72, "name": "Zalcano", "rank": -1, "score": -1 }, "id": 76,
{ "id": 73, "name": "Zulrah", "rank": -1, "score": -1 } "name": "TzTok-Jad",
"rank": 317,
"score": 186
},
{
"id": 77,
"name": "Vardorvis",
"rank": -1,
"score": -1
},
{
"id": 78,
"name": "Venenatis",
"rank": -1,
"score": -1
},
{
"id": 79,
"name": "Vet'ion",
"rank": -1,
"score": -1
},
{
"id": 80,
"name": "Vorkath",
"rank": -1,
"score": -1
},
{
"id": 81,
"name": "Wintertodt",
"rank": -1,
"score": -1
},
{
"id": 82,
"name": "Zalcano",
"rank": -1,
"score": -1
},
{
"id": 83,
"name": "Zulrah",
"rank": -1,
"score": -1
}
] ]
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "osrs-json-hiscores", "name": "osrs-json-hiscores",
"version": "2.16.0", "version": "2.21.0",
"description": "The Old School Runescape API wrapper that does more!", "description": "The Old School Runescape API wrapper that does more!",
"main": "lib/index.js", "main": "lib/index.js",
"types": "lib/index.d.ts", "types": "lib/index.d.ts",
@@ -67,7 +67,10 @@
], ],
"ignorePatterns": [ "ignorePatterns": [
"**/@types/*" "**/@types/*"
] ],
"rules": {
"max-classes-per-file": "off"
}
}, },
"prettier": { "prettier": {
"trailingComma": "none", "trailingComma": "none",
@@ -92,7 +95,7 @@
"testEnvironment": "node" "testEnvironment": "node"
}, },
"dependencies": { "dependencies": {
"axios": "^0.21.1", "axios": "^1.6.2",
"jsdom": "^22.1.0", "jsdom": "^22.1.0",
"useragent-generator": "^1.1.0" "useragent-generator": "^1.1.0"
}, },

View File

@@ -1,4 +1,4 @@
import { AxiosRequestConfig, AxiosResponse } from 'axios'; import axios, { AxiosRequestConfig } from 'axios';
import { BinaryData, JSDOM } from 'jsdom'; import { BinaryData, JSDOM } from 'jsdom';
import { import {
Player, Player,
@@ -31,9 +31,10 @@ import {
getActivityPageURL, getActivityPageURL,
httpGet, httpGet,
BOSSES, BOSSES,
INVALID_FORMAT_ERROR, InvalidFormatError,
PlayerNotFoundError,
HiScoresError,
validateRSN, validateRSN,
PLAYER_NOT_FOUND_ERROR,
FORMATTED_SKILL_NAMES, FORMATTED_SKILL_NAMES,
FORMATTED_BH_NAMES, FORMATTED_BH_NAMES,
FORMATTED_CLUE_NAMES, FORMATTED_CLUE_NAMES,
@@ -42,7 +43,10 @@ import {
FORMATTED_LMS, FORMATTED_LMS,
FORMATTED_PVP_ARENA, FORMATTED_PVP_ARENA,
FORMATTED_SOUL_WARS, FORMATTED_SOUL_WARS,
FORMATTED_RIFTS_CLOSED FORMATTED_RIFTS_CLOSED,
FORMATTED_DEADMAN_POINTS,
FORMATTED_COLOSSEUM_GLORY,
FORMATTED_COLLECTIONS_LOGGED
} from './utils'; } from './utils';
/** /**
@@ -64,8 +68,12 @@ export async function getOfficialStats(
try { try {
const response = await httpGet<HiscoresResponse>(url, config); const response = await httpGet<HiscoresResponse>(url, config);
return response.data; return response.data;
} catch { } catch (err) {
throw Error(PLAYER_NOT_FOUND_ERROR); if (!axios.isAxiosError(err)) throw err;
if (err.response?.status === 404) throw new PlayerNotFoundError();
throw new HiScoresError();
} }
} }
@@ -95,9 +103,9 @@ export async function getRSNFormat(
if (anchor) { if (anchor) {
return rsnFromElement(anchor); return rsnFromElement(anchor);
} }
throw Error(PLAYER_NOT_FOUND_ERROR); throw new PlayerNotFoundError();
} catch { } catch {
throw Error(PLAYER_NOT_FOUND_ERROR); throw new HiScoresError();
} }
} }
@@ -151,19 +159,25 @@ export function parseJsonStats(json: HiscoresResponse): Stats {
const bosses = reduceActivity(BOSSES, FORMATTED_BOSS_NAMES); const bosses = reduceActivity(BOSSES, FORMATTED_BOSS_NAMES);
const leaguePoints = getActivity(FORMATTED_LEAGUE_POINTS); const leaguePoints = getActivity(FORMATTED_LEAGUE_POINTS);
const deadmanPoints = getActivity(FORMATTED_DEADMAN_POINTS);
const lastManStanding = getActivity(FORMATTED_LMS); const lastManStanding = getActivity(FORMATTED_LMS);
const pvpArena = getActivity(FORMATTED_PVP_ARENA); const pvpArena = getActivity(FORMATTED_PVP_ARENA);
const soulWarsZeal = getActivity(FORMATTED_SOUL_WARS); const soulWarsZeal = getActivity(FORMATTED_SOUL_WARS);
const riftsClosed = getActivity(FORMATTED_RIFTS_CLOSED); const riftsClosed = getActivity(FORMATTED_RIFTS_CLOSED);
const colosseumGlory = getActivity(FORMATTED_COLOSSEUM_GLORY);
const collectionsLogged = getActivity(FORMATTED_COLLECTIONS_LOGGED);
const stats: Stats = { const stats: Stats = {
skills, skills,
leaguePoints, leaguePoints,
deadmanPoints,
bountyHunter, bountyHunter,
lastManStanding, lastManStanding,
pvpArena, pvpArena,
soulWarsZeal, soulWarsZeal,
riftsClosed, riftsClosed,
colosseumGlory,
collectionsLogged,
clues, clues,
bosses bosses
}; };
@@ -183,11 +197,8 @@ export function parseStats(csv: string): Stats {
.filter((entry) => !!entry) .filter((entry) => !!entry)
.map((stat) => stat.split(',')); .map((stat) => stat.split(','));
if ( if (splitCSV.length !== SKILLS.length + ACTIVITIES.length) {
splitCSV.length !== throw new InvalidFormatError();
SKILLS.length + BH_MODES.length + CLUES.length + BOSSES.length + 5
) {
throw Error(INVALID_FORMAT_ERROR);
} }
const skillObjects: Skill[] = splitCSV const skillObjects: Skill[] = splitCSV
@@ -213,11 +224,17 @@ export function parseStats(csv: string): Stats {
return activity; return activity;
}); });
const [leaguePoints] = activityObjects.splice(0, 1); const [leaguePoints, deadmanPoints] = activityObjects.splice(0, 2);
const bhObjects = activityObjects.splice(0, BH_MODES.length); const bhObjects = activityObjects.splice(0, BH_MODES.length);
const clueObjects = activityObjects.splice(0, CLUES.length); const clueObjects = activityObjects.splice(0, CLUES.length);
const [lastManStanding, pvpArena, soulWarsZeal, riftsClosed] = const [
activityObjects.splice(0, 4); lastManStanding,
pvpArena,
soulWarsZeal,
riftsClosed,
colosseumGlory,
collectionsLogged
] = activityObjects.splice(0, 6);
const bossObjects = activityObjects.splice(0, BOSSES.length); const bossObjects = activityObjects.splice(0, BOSSES.length);
const skills: Skills = skillObjects.reduce<Skills>((prev, curr, index) => { const skills: Skills = skillObjects.reduce<Skills>((prev, curr, index) => {
@@ -247,11 +264,14 @@ export function parseStats(csv: string): Stats {
const stats: Stats = { const stats: Stats = {
skills, skills,
leaguePoints, leaguePoints,
deadmanPoints,
bountyHunter, bountyHunter,
lastManStanding, lastManStanding,
pvpArena, pvpArena,
soulWarsZeal, soulWarsZeal,
riftsClosed, riftsClosed,
colosseumGlory,
collectionsLogged,
clues, clues,
bosses bosses
}; };
@@ -280,32 +300,19 @@ export async function getStats(
]; ];
const shouldGetFormattedRsn = options?.shouldGetFormattedRsn ?? true; const shouldGetFormattedRsn = options?.shouldGetFormattedRsn ?? true;
const mainRes = await httpGet<HiscoresResponse>( const main = await getOfficialStats(rsn, 'main', options?.axiosConfigs?.main);
getStatsURL('main', rsn, true),
options?.axiosConfigs?.main
);
if (mainRes.status === 200) {
const emptyResponse: AxiosResponse<HiscoresResponse> = {
status: 404,
data: { skills: [], activities: [] },
statusText: '',
headers: {},
config: {}
};
const getModeStats = async ( const getModeStats = async (
mode: Extract<Gamemode, 'ironman' | 'hardcore' | 'ultimate'> mode: Extract<Gamemode, 'ironman' | 'hardcore' | 'ultimate'>
): Promise<AxiosResponse<HiscoresResponse>> => ): Promise<HiscoresResponse | undefined> =>
otherGamemodes.includes(mode) otherGamemodes.includes(mode)
? httpGet<HiscoresResponse>( ? getOfficialStats(rsn, mode, options?.axiosConfigs?.[mode]).catch(
getStatsURL(mode, rsn, true),
options?.axiosConfigs?.[mode]
).catch((err) => err)
: emptyResponse;
const formattedName = shouldGetFormattedRsn
? await getRSNFormat(rsn, options?.axiosConfigs?.rsn).catch(
() => undefined () => undefined
) )
: undefined; : undefined;
const formattedName = shouldGetFormattedRsn
? await getRSNFormat(rsn, options?.axiosConfigs?.rsn).catch(() => undefined)
: undefined;
const player: Player = { const player: Player = {
name: formattedName ?? rsn, name: formattedName ?? rsn,
@@ -314,48 +321,42 @@ export async function getStats(
deulted: false, deulted: false,
deironed: false deironed: false
}; };
player.main = parseJsonStats(mainRes.data); player.main = parseJsonStats(main);
const ironRes = await getModeStats('ironman'); const iron = await getModeStats('ironman');
if (ironRes.status === 200) { if (iron) {
player.ironman = parseJsonStats(ironRes.data); player.ironman = parseJsonStats(iron);
const hcRes = await getModeStats('hardcore'); const hc = await getModeStats('hardcore');
const ultRes = await getModeStats('ultimate'); const ult = await getModeStats('ultimate');
if (hcRes.status === 200) { if (hc) {
player.mode = 'hardcore'; player.mode = 'hardcore';
player.hardcore = parseJsonStats(hcRes.data); player.hardcore = parseJsonStats(hc);
if ( if (
player.ironman.skills.overall.xp !== player.hardcore.skills.overall.xp player.ironman.skills.overall.xp !== player.hardcore.skills.overall.xp
) { ) {
player.dead = true; player.dead = true;
player.mode = 'ironman'; player.mode = 'ironman';
} }
if ( if (player.main.skills.overall.xp !== player.ironman.skills.overall.xp) {
player.main.skills.overall.xp !== player.ironman.skills.overall.xp
) {
player.deironed = true; player.deironed = true;
player.mode = 'main'; player.mode = 'main';
} }
} else if (ultRes.status === 200) { } else if (ult) {
player.mode = 'ultimate'; player.mode = 'ultimate';
player.ultimate = parseJsonStats(ultRes.data); player.ultimate = parseJsonStats(ult);
if ( if (
player.ironman.skills.overall.xp !== player.ultimate.skills.overall.xp player.ironman.skills.overall.xp !== player.ultimate.skills.overall.xp
) { ) {
player.deulted = true; player.deulted = true;
player.mode = 'ironman'; player.mode = 'ironman';
} }
if ( if (player.main.skills.overall.xp !== player.ironman.skills.overall.xp) {
player.main.skills.overall.xp !== player.ironman.skills.overall.xp
) {
player.deironed = true; player.deironed = true;
player.mode = 'main'; player.mode = 'main';
} }
} else { } else {
player.mode = 'ironman'; player.mode = 'ironman';
if ( if (player.main.skills.overall.xp !== player.ironman.skills.overall.xp) {
player.main.skills.overall.xp !== player.ironman.skills.overall.xp
) {
player.deironed = true; player.deironed = true;
player.mode = 'main'; player.mode = 'main';
} }
@@ -364,8 +365,6 @@ export async function getStats(
return player; return player;
} }
throw Error(PLAYER_NOT_FOUND_ERROR);
}
/** /**
* Fetches stats from the OSRS API and returns them as an object. * Fetches stats from the OSRS API and returns them as an object.

View File

@@ -69,6 +69,8 @@ export type BH = { [Type in BHType]: Activity };
export type Boss = export type Boss =
| 'abyssalSire' | 'abyssalSire'
| 'alchemicalHydra' | 'alchemicalHydra'
| 'amoxliatl'
| 'araxxor'
| 'artio' | 'artio'
| 'barrows' | 'barrows'
| 'bryophyta' | 'bryophyta'
@@ -96,6 +98,7 @@ export type Boss =
| 'kraken' | 'kraken'
| 'kreeArra' | 'kreeArra'
| 'krilTsutsaroth' | 'krilTsutsaroth'
| 'lunarChests'
| 'mimic' | 'mimic'
| 'nex' | 'nex'
| 'nightmare' | 'nightmare'
@@ -104,12 +107,16 @@ export type Boss =
| 'phantomMuspah' | 'phantomMuspah'
| 'sarachnis' | 'sarachnis'
| 'scorpia' | 'scorpia'
| 'scurrius'
| 'skotizo' | 'skotizo'
| 'solHeredit'
| 'spindel' | 'spindel'
| 'tempoross' | 'tempoross'
| 'gauntlet' | 'gauntlet'
| 'corruptedGauntlet' | 'corruptedGauntlet'
| 'hueycoatl'
| 'leviathan' | 'leviathan'
| 'royalTitans'
| 'whisperer' | 'whisperer'
| 'theatreOfBlood' | 'theatreOfBlood'
| 'theatreOfBloodHardMode' | 'theatreOfBloodHardMode'
@@ -130,6 +137,7 @@ export type Bosses = { [Type in Boss]: Activity };
export type ActivityName = export type ActivityName =
| 'leaguePoints' | 'leaguePoints'
| 'deadmanPoints'
| 'hunterBHV2' | 'hunterBHV2'
| 'rogueBHV2' | 'rogueBHV2'
| 'hunterBH' | 'hunterBH'
@@ -145,17 +153,28 @@ export type ActivityName =
| 'hardClues' | 'hardClues'
| 'eliteClues' | 'eliteClues'
| 'masterClues' | 'masterClues'
| 'colosseumGlory'
| 'collectionsLogged'
| Boss; | Boss;
export interface Stats { export interface Stats {
skills: Skills; skills: Skills;
clues: Clues; clues: Clues;
/**
* Will only contain rank and score data for the `seasonal` gamemode.
*/
leaguePoints: Activity; leaguePoints: Activity;
/**
* Will only contain rank and score data for the `tournament` gamemode.
*/
deadmanPoints: Activity;
bountyHunter: BH; bountyHunter: BH;
lastManStanding: Activity; lastManStanding: Activity;
pvpArena: Activity; pvpArena: Activity;
soulWarsZeal: Activity; soulWarsZeal: Activity;
riftsClosed: Activity; riftsClosed: Activity;
colosseumGlory: Activity;
collectionsLogged: Activity;
bosses: Bosses; bosses: Bosses;
} }
export type Modes = { [M in Gamemode]?: Stats }; export type Modes = { [M in Gamemode]?: Stats };

View File

@@ -76,6 +76,8 @@ export const GAMEMODES: Gamemode[] = [
export const BOSSES: Boss[] = [ export const BOSSES: Boss[] = [
'abyssalSire', 'abyssalSire',
'alchemicalHydra', 'alchemicalHydra',
'amoxliatl',
'araxxor',
'artio', 'artio',
'barrows', 'barrows',
'bryophyta', 'bryophyta',
@@ -103,6 +105,7 @@ export const BOSSES: Boss[] = [
'kraken', 'kraken',
'kreeArra', 'kreeArra',
'krilTsutsaroth', 'krilTsutsaroth',
'lunarChests',
'mimic', 'mimic',
'nex', 'nex',
'nightmare', 'nightmare',
@@ -111,12 +114,16 @@ export const BOSSES: Boss[] = [
'phantomMuspah', 'phantomMuspah',
'sarachnis', 'sarachnis',
'scorpia', 'scorpia',
'scurrius',
'skotizo', 'skotizo',
'solHeredit',
'spindel', 'spindel',
'tempoross', 'tempoross',
'gauntlet', 'gauntlet',
'corruptedGauntlet', 'corruptedGauntlet',
'hueycoatl',
'leviathan', 'leviathan',
'royalTitans',
'whisperer', 'whisperer',
'theatreOfBlood', 'theatreOfBlood',
'theatreOfBloodHardMode', 'theatreOfBloodHardMode',
@@ -135,6 +142,7 @@ export const BOSSES: Boss[] = [
]; ];
export const ACTIVITIES: ActivityName[] = [ export const ACTIVITIES: ActivityName[] = [
'leaguePoints', 'leaguePoints',
'deadmanPoints',
'hunterBHV2', 'hunterBHV2',
'rogueBHV2', 'rogueBHV2',
'hunterBH', 'hunterBH',
@@ -150,6 +158,8 @@ export const ACTIVITIES: ActivityName[] = [
'pvpArena', 'pvpArena',
'soulWarsZeal', 'soulWarsZeal',
'riftsClosed', 'riftsClosed',
'colosseumGlory',
'collectionsLogged',
...BOSSES ...BOSSES
]; ];
@@ -160,6 +170,8 @@ export type FormattedBossNames = {
export const FORMATTED_BOSS_NAMES: FormattedBossNames = { export const FORMATTED_BOSS_NAMES: FormattedBossNames = {
abyssalSire: 'Abyssal Sire', abyssalSire: 'Abyssal Sire',
alchemicalHydra: 'Alchemical Hydra', alchemicalHydra: 'Alchemical Hydra',
amoxliatl: 'Amoxliatl',
araxxor: 'Araxxor',
artio: 'Artio', artio: 'Artio',
barrows: 'Barrows Chests', barrows: 'Barrows Chests',
bryophyta: 'Bryophyta', bryophyta: 'Bryophyta',
@@ -187,6 +199,7 @@ export const FORMATTED_BOSS_NAMES: FormattedBossNames = {
kraken: 'Kraken', kraken: 'Kraken',
kreeArra: "Kree'Arra", kreeArra: "Kree'Arra",
krilTsutsaroth: "K'ril Tsutsaroth", krilTsutsaroth: "K'ril Tsutsaroth",
lunarChests: 'Lunar Chests',
mimic: 'Mimic', mimic: 'Mimic',
nex: 'Nex', nex: 'Nex',
nightmare: 'Nightmare', nightmare: 'Nightmare',
@@ -195,12 +208,16 @@ export const FORMATTED_BOSS_NAMES: FormattedBossNames = {
phantomMuspah: 'Phantom Muspah', phantomMuspah: 'Phantom Muspah',
sarachnis: 'Sarachnis', sarachnis: 'Sarachnis',
scorpia: 'Scorpia', scorpia: 'Scorpia',
scurrius: 'Scurrius',
skotizo: 'Skotizo', skotizo: 'Skotizo',
solHeredit: 'Sol Heredit',
spindel: 'Spindel', spindel: 'Spindel',
tempoross: 'Tempoross', tempoross: 'Tempoross',
gauntlet: 'The Gauntlet', gauntlet: 'The Gauntlet',
corruptedGauntlet: 'The Corrupted Gauntlet', corruptedGauntlet: 'The Corrupted Gauntlet',
hueycoatl: 'The Hueycoatl',
leviathan: 'The Leviathan', leviathan: 'The Leviathan',
royalTitans: 'The Royal Titans',
whisperer: 'The Whisperer', whisperer: 'The Whisperer',
theatreOfBlood: 'Theatre of Blood', theatreOfBlood: 'Theatre of Blood',
theatreOfBloodHardMode: 'Theatre of Blood: Hard Mode', theatreOfBloodHardMode: 'Theatre of Blood: Hard Mode',
@@ -278,7 +295,47 @@ export const FORMATTED_LMS = 'LMS - Rank';
export const FORMATTED_PVP_ARENA = 'PvP Arena - Rank'; export const FORMATTED_PVP_ARENA = 'PvP Arena - Rank';
export const FORMATTED_SOUL_WARS = 'Soul Wars Zeal'; export const FORMATTED_SOUL_WARS = 'Soul Wars Zeal';
export const FORMATTED_LEAGUE_POINTS = 'League Points'; export const FORMATTED_LEAGUE_POINTS = 'League Points';
export const FORMATTED_DEADMAN_POINTS = 'Deadman Points';
export const FORMATTED_RIFTS_CLOSED = 'Rifts closed'; export const FORMATTED_RIFTS_CLOSED = 'Rifts closed';
export const FORMATTED_COLOSSEUM_GLORY = 'Colosseum Glory';
export const FORMATTED_COLLECTIONS_LOGGED = 'Collections Logged';
export const INVALID_FORMAT_ERROR = 'Invalid hiscores format'; export const INVALID_FORMAT_ERROR = 'Invalid hiscores format';
export const PLAYER_NOT_FOUND_ERROR = 'Player not found'; export const PLAYER_NOT_FOUND_ERROR = 'Player not found';
export const HISCORES_ERROR = 'HiScores not responding';
export class InvalidFormatError extends Error {
__proto__ = Error;
constructor() {
super(INVALID_FORMAT_ERROR);
Object.setPrototypeOf(this, InvalidFormatError.prototype);
}
}
export class InvalidRSNError extends Error {
__proto__ = Error;
constructor(message: string) {
super(message);
Object.setPrototypeOf(this, InvalidRSNError.prototype);
}
}
export class PlayerNotFoundError extends Error {
__proto__ = Error;
constructor() {
super(PLAYER_NOT_FOUND_ERROR);
Object.setPrototypeOf(this, PlayerNotFoundError.prototype);
}
}
export class HiScoresError extends Error {
__proto__ = Error;
constructor() {
super(HISCORES_ERROR);
Object.setPrototypeOf(this, HiScoresError.prototype);
}
}

View File

@@ -7,7 +7,8 @@ import {
SCORES_URL, SCORES_URL,
SKILLS, SKILLS,
ACTIVITIES, ACTIVITIES,
JSON_STATS_URL JSON_STATS_URL,
InvalidRSNError
} from './constants'; } from './constants';
/** /**
@@ -119,10 +120,10 @@ export const httpGet = <Response>(
*/ */
export const validateRSN = (rsn: string) => { export const validateRSN = (rsn: string) => {
if (typeof rsn !== 'string') { if (typeof rsn !== 'string') {
throw Error('RSN must be a string'); throw new InvalidRSNError('RSN must be a string');
} else if (!/^[a-zA-Z0-9 _-]+$/.test(rsn)) { } else if (!/^[a-zA-Z0-9 _-]+$/.test(rsn)) {
throw Error('RSN contains invalid character'); throw new InvalidRSNError('RSN contains invalid character');
} else if (rsn.length > 12 || rsn.length < 1) { } else if (rsn.length > 12 || rsn.length < 1) {
throw Error('RSN must be between 1 and 12 characters'); throw new InvalidRSNError('RSN must be between 1 and 12 characters');
} }
}; };

View File

@@ -6,10 +6,7 @@
"outDir": "./lib", "outDir": "./lib",
"strict": true, "strict": true,
"lib": ["ES2015", "DOM", "DOM.Iterable"], "lib": ["ES2015", "DOM", "DOM.Iterable"],
"typeRoots": [ "typeRoots": ["./node_modules/@types", "./src/@types"]
"./node_modules/@types",
"./src/@types"
]
}, },
"include": ["src"], "include": ["src"],
"exclude": ["node_modules", "**/__tests__/*"] "exclude": ["node_modules", "**/__tests__/*"]

167
yarn.lock
View File

@@ -29,6 +29,14 @@
dependencies: dependencies:
"@babel/highlight" "^7.22.5" "@babel/highlight" "^7.22.5"
"@babel/code-frame@^7.22.13":
version "7.22.13"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e"
integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==
dependencies:
"@babel/highlight" "^7.22.13"
chalk "^2.4.2"
"@babel/compat-data@^7.22.9": "@babel/compat-data@^7.22.9":
version "7.22.9" version "7.22.9"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730"
@@ -55,7 +63,7 @@
json5 "^2.2.2" json5 "^2.2.2"
semver "^6.3.1" semver "^6.3.1"
"@babel/generator@^7.22.7", "@babel/generator@^7.22.9", "@babel/generator@^7.7.2": "@babel/generator@^7.22.9", "@babel/generator@^7.7.2":
version "7.22.9" version "7.22.9"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.9.tgz#572ecfa7a31002fa1de2a9d91621fd895da8493d" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.9.tgz#572ecfa7a31002fa1de2a9d91621fd895da8493d"
integrity sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw== integrity sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw==
@@ -65,6 +73,16 @@
"@jridgewell/trace-mapping" "^0.3.17" "@jridgewell/trace-mapping" "^0.3.17"
jsesc "^2.5.1" jsesc "^2.5.1"
"@babel/generator@^7.23.0":
version "7.23.0"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420"
integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==
dependencies:
"@babel/types" "^7.23.0"
"@jridgewell/gen-mapping" "^0.3.2"
"@jridgewell/trace-mapping" "^0.3.17"
jsesc "^2.5.1"
"@babel/helper-compilation-targets@^7.22.9": "@babel/helper-compilation-targets@^7.22.9":
version "7.22.9" version "7.22.9"
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz#f9d0a7aaaa7cd32a3f31c9316a69f5a9bcacb892" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz#f9d0a7aaaa7cd32a3f31c9316a69f5a9bcacb892"
@@ -76,18 +94,23 @@
lru-cache "^5.1.1" lru-cache "^5.1.1"
semver "^6.3.1" semver "^6.3.1"
"@babel/helper-environment-visitor@^7.22.20":
version "7.22.20"
resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167"
integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==
"@babel/helper-environment-visitor@^7.22.5": "@babel/helper-environment-visitor@^7.22.5":
version "7.22.5" version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98"
integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==
"@babel/helper-function-name@^7.22.5": "@babel/helper-function-name@^7.23.0":
version "7.22.5" version "7.23.0"
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759"
integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ== integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==
dependencies: dependencies:
"@babel/template" "^7.22.5" "@babel/template" "^7.22.15"
"@babel/types" "^7.22.5" "@babel/types" "^7.23.0"
"@babel/helper-hoist-variables@^7.22.5": "@babel/helper-hoist-variables@^7.22.5":
version "7.22.5" version "7.22.5"
@@ -148,6 +171,11 @@
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed"
integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==
"@babel/helper-validator-identifier@^7.22.20":
version "7.22.20"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0"
integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==
"@babel/helper-validator-identifier@^7.22.5": "@babel/helper-validator-identifier@^7.22.5":
version "7.22.5" version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193"
@@ -176,6 +204,15 @@
chalk "^2.0.0" chalk "^2.0.0"
js-tokens "^4.0.0" js-tokens "^4.0.0"
"@babel/highlight@^7.22.13":
version "7.22.20"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54"
integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==
dependencies:
"@babel/helper-validator-identifier" "^7.22.20"
chalk "^2.4.2"
js-tokens "^4.0.0"
"@babel/highlight@^7.22.5": "@babel/highlight@^7.22.5":
version "7.22.5" version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031"
@@ -195,6 +232,11 @@
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.7.tgz#df8cf085ce92ddbdbf668a7f186ce848c9036cae" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.7.tgz#df8cf085ce92ddbdbf668a7f186ce848c9036cae"
integrity sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q== integrity sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==
"@babel/parser@^7.22.15", "@babel/parser@^7.23.0":
version "7.23.0"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719"
integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==
"@babel/plugin-syntax-async-generators@^7.8.4": "@babel/plugin-syntax-async-generators@^7.8.4":
version "7.8.4" version "7.8.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d"
@@ -293,6 +335,15 @@
dependencies: dependencies:
"@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5"
"@babel/template@^7.22.15":
version "7.22.15"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38"
integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==
dependencies:
"@babel/code-frame" "^7.22.13"
"@babel/parser" "^7.22.15"
"@babel/types" "^7.22.15"
"@babel/template@^7.22.5": "@babel/template@^7.22.5":
version "7.22.5" version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec"
@@ -312,18 +363,18 @@
"@babel/types" "^7.12.7" "@babel/types" "^7.12.7"
"@babel/traverse@^7.22.6", "@babel/traverse@^7.22.8": "@babel/traverse@^7.22.6", "@babel/traverse@^7.22.8":
version "7.22.8" version "7.23.2"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.8.tgz#4d4451d31bc34efeae01eac222b514a77aa4000e" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8"
integrity sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw== integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==
dependencies: dependencies:
"@babel/code-frame" "^7.22.5" "@babel/code-frame" "^7.22.13"
"@babel/generator" "^7.22.7" "@babel/generator" "^7.23.0"
"@babel/helper-environment-visitor" "^7.22.5" "@babel/helper-environment-visitor" "^7.22.20"
"@babel/helper-function-name" "^7.22.5" "@babel/helper-function-name" "^7.23.0"
"@babel/helper-hoist-variables" "^7.22.5" "@babel/helper-hoist-variables" "^7.22.5"
"@babel/helper-split-export-declaration" "^7.22.6" "@babel/helper-split-export-declaration" "^7.22.6"
"@babel/parser" "^7.22.7" "@babel/parser" "^7.23.0"
"@babel/types" "^7.22.5" "@babel/types" "^7.23.0"
debug "^4.1.0" debug "^4.1.0"
globals "^11.1.0" globals "^11.1.0"
@@ -345,6 +396,15 @@
"@babel/helper-validator-identifier" "^7.22.5" "@babel/helper-validator-identifier" "^7.22.5"
to-fast-properties "^2.0.0" to-fast-properties "^2.0.0"
"@babel/types@^7.22.15", "@babel/types@^7.23.0":
version "7.23.0"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb"
integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==
dependencies:
"@babel/helper-string-parser" "^7.22.5"
"@babel/helper-validator-identifier" "^7.22.20"
to-fast-properties "^2.0.0"
"@bcoe/v8-coverage@^0.2.3": "@bcoe/v8-coverage@^0.2.3":
version "0.2.3" version "0.2.3"
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
@@ -1227,12 +1287,14 @@ available-typed-arrays@^1.0.5:
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7"
integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==
axios@^0.21.1: axios@^1.6.2:
version "0.21.2" version "1.7.4"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.2.tgz#21297d5084b2aeeb422f5d38e7be4fbb82239017" resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.4.tgz#4c8ded1b43683c8dd362973c393f3ede24052aa2"
integrity sha512-87otirqUw3e8CzHTMO+/9kh/FSgXt/eVDvipijwDtEuwbkySWZ9SBm6VEubmJ/kLKEoLQV/POhxXFb66bfekfg== integrity sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==
dependencies: dependencies:
follow-redirects "^1.14.0" follow-redirects "^1.15.6"
form-data "^4.0.0"
proxy-from-env "^1.1.0"
babel-jest@^29.6.1: babel-jest@^29.6.1:
version "29.6.1" version "29.6.1"
@@ -1321,12 +1383,12 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0" balanced-match "^1.0.0"
concat-map "0.0.1" concat-map "0.0.1"
braces@^3.0.1, braces@^3.0.2: braces@^3.0.3:
version "3.0.2" version "3.0.3"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
dependencies: dependencies:
fill-range "^7.0.1" fill-range "^7.1.1"
browserslist@^4.21.9: browserslist@^4.21.9:
version "4.21.9" version "4.21.9"
@@ -1667,9 +1729,9 @@ cosmiconfig@^7.0.0:
yaml "^1.10.0" yaml "^1.10.0"
cross-spawn@^7.0.2, cross-spawn@^7.0.3: cross-spawn@^7.0.2, cross-spawn@^7.0.3:
version "7.0.3" version "7.0.6"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
dependencies: dependencies:
path-key "^3.1.0" path-key "^3.1.0"
shebang-command "^2.0.0" shebang-command "^2.0.0"
@@ -2330,10 +2392,10 @@ file-entry-cache@^6.0.1:
dependencies: dependencies:
flat-cache "^3.0.4" flat-cache "^3.0.4"
fill-range@^7.0.1: fill-range@^7.1.1:
version "7.0.1" version "7.1.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
dependencies: dependencies:
to-regex-range "^5.0.1" to-regex-range "^5.0.1"
@@ -2366,10 +2428,10 @@ flatted@^3.1.0:
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469"
integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==
follow-redirects@^1.14.0: follow-redirects@^1.15.6:
version "1.14.8" version "1.15.6"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b"
integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA== integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==
for-each@^0.3.3: for-each@^0.3.3:
version "0.3.3" version "0.3.3"
@@ -4030,20 +4092,12 @@ merge2@^1.3.0, merge2@^1.4.1:
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
micromatch@^4.0.2: micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5:
version "4.0.2" version "4.0.8"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
dependencies: dependencies:
braces "^3.0.1" braces "^3.0.3"
picomatch "^2.0.5"
micromatch@^4.0.4, micromatch@^4.0.5:
version "4.0.5"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
dependencies:
braces "^3.0.2"
picomatch "^2.3.1" picomatch "^2.3.1"
mime-db@1.45.0: mime-db@1.45.0:
@@ -4605,7 +4659,7 @@ picocolors@^1.0.0:
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: picomatch@^2.0.4, picomatch@^2.2.1:
version "2.2.2" version "2.2.2"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
@@ -4671,6 +4725,11 @@ prompts@^2.0.1:
kleur "^3.0.3" kleur "^3.0.3"
sisteransi "^1.0.5" sisteransi "^1.0.5"
proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
psl@^1.1.33: psl@^1.1.33:
version "1.8.0" version "1.8.0"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
@@ -5780,9 +5839,9 @@ write-file-atomic@^4.0.2:
signal-exit "^3.0.7" signal-exit "^3.0.7"
ws@^8.13.0: ws@^8.13.0:
version "8.13.0" version "8.17.1"
resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b"
integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==
xdg-basedir@^4.0.0: xdg-basedir@^4.0.0:
version "4.0.0" version "4.0.0"