Compare commits

...

67 Commits

Author SHA1 Message Date
maxswa
e4d2b10488 v2.13.1 2023-04-12 21:51:49 -04:00
Max Swartwout
0cfd0e2471 Merge pull request #73 from davidvorona/main
Fix spelling of Calvar'ion
2023-04-12 21:50:54 -04:00
David Vorona
9c284ad4b0 Fix spelling of Calvar'ion 2023-04-12 10:26:06 -07:00
Max Swartwout
ec60a72c08 Merge pull request #71 from maxswa/fix-gh-workflow
Update GH action versions.
2023-04-12 13:04:45 -04:00
maxswa
d45e2efcfd Update GH action versions. 2023-04-12 13:00:18 -04:00
maxswa
f80b417121 v2.13.0 2023-04-12 12:53:39 -04:00
maxswa
415fe2f02b Update np 2023-04-12 12:50:41 -04:00
Max Swartwout
968799176f Merge pull request #70 from maxswa/wilderness-boss-variants
Add wilderness boss variants.
2023-04-12 12:46:11 -04:00
maxswa
f45ae67813 Add wilderness boss variants. 2023-04-12 12:42:37 -04:00
maxswa
7724636b40 v2.12.1 2023-03-19 23:33:33 -04:00
maxswa
3954b04acc Add publishConfig to package.json 2023-03-19 23:33:03 -04:00
Max Swartwout
ee7389455c Merge pull request #68 from maxswa/add-options
Add `validateRSN`, `GetStatsOptions`
2023-03-19 23:28:34 -04:00
maxswa
54c11635e0 Add GetStatsOptions for getStats 2023-03-19 23:14:10 -04:00
maxswa
dc799cf363 Add validateRSN helper function. 2023-03-19 22:38:45 -04:00
maxswa
d4c7aaff2a v2.12.0 2023-02-19 18:31:43 -05:00
Max Swartwout
03c089ebff Merge pull request #66 from maxswa/account-builds
Add new `Gamemode`s
2023-02-19 18:31:00 -05:00
Max Swartwout
96641d875a Merge pull request #65 from maxswa/dependabot/npm_and_yarn/http-cache-semantics-4.1.1
Bump http-cache-semantics from 4.1.0 to 4.1.1
2023-02-19 18:28:33 -05:00
maxswa
b2bdd3d2ce Add new Gamemodes 2023-02-19 18:27:56 -05:00
dependabot[bot]
a4ddfaf199 Bump http-cache-semantics from 4.1.0 to 4.1.1
Bumps [http-cache-semantics](https://github.com/kornelski/http-cache-semantics) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/kornelski/http-cache-semantics/releases)
- [Commits](https://github.com/kornelski/http-cache-semantics/compare/v4.1.0...v4.1.1)

---
updated-dependencies:
- dependency-name: http-cache-semantics
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-03 04:54:08 +00:00
maxswa
efbcdfc709 v2.11.0 2023-01-13 11:21:51 -05:00
Max Swartwout
fe913aba1f Merge pull request #64 from davidvorona/add-muspah
Add phantom muspah
2023-01-12 15:30:21 -05:00
Max Swartwout
1497653bab Merge pull request #63 from maxswa/dependabot/npm_and_yarn/json5-1.0.2
Bump json5 from 1.0.1 to 1.0.2
2023-01-12 15:29:38 -05:00
David Vorona
f76de38eb1 Add phantom muspah 2023-01-11 11:45:59 -08:00
dependabot[bot]
2f1d10b309 Bump json5 from 1.0.1 to 1.0.2
Bumps [json5](https://github.com/json5/json5) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v1.0.1...v1.0.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-06 22:36:14 +00:00
Max Swartwout
f08424cb81 Update build badge in README 2022-12-19 12:24:03 -05:00
maxswa
69088db3b6 v2.10.2 2022-12-15 23:24:59 +00:00
Max Swartwout
9cc89735cd Merge pull request #61 from maxswa/get-rsn-format-highlight-row
Fix `getRSNFormat`
2022-12-15 18:15:34 -05:00
Max Swartwout
a126ae4fc7 Merge pull request #58 from maxswa/dependabot/npm_and_yarn/minimatch-3.1.2
Bump minimatch from 3.0.4 to 3.1.2
2022-12-15 18:11:34 -05:00
Max Swartwout
52f3df1838 Merge pull request #59 from maxswa/dependabot/npm_and_yarn/qs-6.5.3
Bump qs from 6.5.2 to 6.5.3
2022-12-15 18:11:23 -05:00
maxswa
2891bbddc4 Fix getRSNFormat 2022-12-15 18:09:21 -05:00
dependabot[bot]
e2ea2fe33d Bump qs from 6.5.2 to 6.5.3
Bumps [qs](https://github.com/ljharb/qs) from 6.5.2 to 6.5.3.
- [Release notes](https://github.com/ljharb/qs/releases)
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.5.2...v6.5.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-09 06:28:03 +00:00
maxswa
b7ae812f45 v2.10.1 2022-12-04 14:17:36 -05:00
dependabot[bot]
240628d9cc Bump minimatch from 3.0.4 to 3.1.2
Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2.
- [Release notes](https://github.com/isaacs/minimatch/releases)
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-04 19:14:24 +00:00
Max Swartwout
b754663f6d Merge pull request #56 from APKiwi/main
Added "-" as a valid character in "getStats"
2022-12-04 14:13:51 -05:00
Max Swartwout
0678f7c979 Merge pull request #57 from maxswa/dependabot/npm_and_yarn/decode-uri-component-0.2.2
Bump decode-uri-component from 0.2.0 to 0.2.2
2022-12-04 14:13:27 -05:00
dependabot[bot]
2a60283a93 Bump decode-uri-component from 0.2.0 to 0.2.2
Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

---
updated-dependencies:
- dependency-name: decode-uri-component
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-03 13:49:33 +00:00
SirKhaoz
b912731cf9 Added "-" as a valid character in "getStats" 2022-11-04 21:56:39 +13:00
maxswa
cf44c57ec6 v2.10.0 2022-08-24 08:25:48 -04:00
Max Swartwout
3f34c9ab61 Merge pull request #55 from maxswa/toa
Add Tombs of Amascut.
2022-08-24 08:24:58 -04:00
maxswa
1ef73b6b0c Add Tombs of Amascut. 2022-08-24 07:48:05 -04:00
maxswa
08ecf68689 v2.9.0 2022-07-17 13:08:27 -04:00
Max Swartwout
ab3ee70237 Merge pull request #53 from maxswa/dependabot/npm_and_yarn/jsdom-16.5.0
Bump jsdom from 16.4.0 to 16.5.0
2022-07-17 13:06:51 -04:00
Max Swartwout
cad20d41cb Merge pull request #54 from davidvorona/pvp-arena
Add support for PvP Arena activity
2022-07-17 13:02:32 -04:00
David Vorona
2877b9c8a1 Add support for PvP Arena activity 2022-07-15 14:29:06 -07:00
dependabot[bot]
afbb22749a Bump jsdom from 16.4.0 to 16.5.0
Bumps [jsdom](https://github.com/jsdom/jsdom) from 16.4.0 to 16.5.0.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/master/Changelog.md)
- [Commits](https://github.com/jsdom/jsdom/compare/16.4.0...16.5.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-23 04:56:25 +00:00
maxswa
eebf76a34c v2.8.0 2022-04-18 15:50:35 -04:00
Max Swartwout
e60442a7ce Merge pull request #50 from maxswa/dependabot/npm_and_yarn/minimist-1.2.6
Bump minimist from 1.2.5 to 1.2.6
2022-04-18 15:47:45 -04:00
Max Swartwout
1132a085e1 Merge pull request #52 from molo-pl/main
Add support for Rifts Closed
2022-04-18 15:47:35 -04:00
molo-pl
a2a34a46e3 Add support for Rifts Closed 2022-04-15 11:30:56 +02:00
dependabot[bot]
71a76a12fd Bump minimist from 1.2.5 to 1.2.6
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-28 13:26:44 +00:00
Max Swartwout
3a72315498 Merge pull request #49 from maxswa/dependabot/npm_and_yarn/follow-redirects-1.14.8
Bump follow-redirects from 1.14.7 to 1.14.8
2022-02-15 14:37:28 -05:00
dependabot[bot]
c1c9833ad0 Bump follow-redirects from 1.14.7 to 1.14.8
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.7 to 1.14.8.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.7...v1.14.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-12 12:01:29 +00:00
Max Swartwout
9fe03746e1 Merge pull request #48 from maxswa/dependabot/npm_and_yarn/follow-redirects-1.14.7
Bump follow-redirects from 1.14.4 to 1.14.7
2022-01-18 10:42:22 -05:00
dependabot[bot]
66a4fb47a6 Bump follow-redirects from 1.14.4 to 1.14.7
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.4 to 1.14.7.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.4...v1.14.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-13 14:22:21 +00:00
Max Swartwout
83c44148a7 Merge pull request #47 from maxswa/fix-tests-nex
Fix tests
2022-01-05 21:54:48 -05:00
maxswa
44dea6b35c Add line for nex in lynxTitanStats.csv 2022-01-05 21:50:28 -05:00
maxswa
0bf491638c v2.7.0 2022-01-05 10:04:11 -05:00
Max Swartwout
febca534b0 Merge pull request #45 from maxswa/add-nex
Add Nex.
2022-01-05 09:57:56 -05:00
Max Swartwout
8daee5c39b Merge pull request #46 from molo-pl/main
Throw error for unknown hiscores CSV format
2022-01-05 09:52:42 -05:00
molo-pl
f98cf8aaaa Throw error for unknown hiscores CSV format 2022-01-04 23:05:34 +01:00
maxswa
5d9f6a6bac Add Nex. 2021-12-19 21:40:09 -05:00
Max Swartwout
8737b50a82 Merge pull request #44 from maxswa/dependabot/npm_and_yarn/axios-0.21.2
Bump axios from 0.21.1 to 0.21.2
2021-09-27 16:38:12 -04:00
dependabot[bot]
1255e7e3d2 Bump axios from 0.21.1 to 0.21.2
Bumps [axios](https://github.com/axios/axios) from 0.21.1 to 0.21.2.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/master/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.21.1...v0.21.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-27 20:36:33 +00:00
Max Swartwout
f4135d0b0f Merge pull request #42 from maxswa/dependabot/npm_and_yarn/path-parse-1.0.7
Bump path-parse from 1.0.6 to 1.0.7
2021-09-27 16:36:09 -04:00
Max Swartwout
6135ff459c Merge pull request #43 from maxswa/dependabot/npm_and_yarn/tmpl-1.0.5
Bump tmpl from 1.0.4 to 1.0.5
2021-09-27 16:36:00 -04:00
dependabot[bot]
9fb7e4cebc Bump tmpl from 1.0.4 to 1.0.5
Bumps [tmpl](https://github.com/daaku/nodejs-tmpl) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/daaku/nodejs-tmpl/releases)
- [Commits](https://github.com/daaku/nodejs-tmpl/commits/v1.0.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-21 04:35:18 +00:00
dependabot[bot]
11350b2444 Bump path-parse from 1.0.6 to 1.0.7
Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/jbgutierrez/path-parse/releases)
- [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7)

---
updated-dependencies:
- dependency-name: path-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-11 02:52:55 +00:00
13 changed files with 4892 additions and 3223 deletions

View File

@@ -10,19 +10,19 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3.3.0
- uses: borales/actions-yarn@v2.0.0 - uses: borales/actions-yarn@v4.2.0
with: with:
cmd: install cmd: install
- uses: borales/actions-yarn@v2.0.0 - uses: borales/actions-yarn@v4.2.0
with: with:
cmd: lint cmd: lint
- uses: borales/actions-yarn@v2.0.0 - uses: borales/actions-yarn@v4.2.0
with: with:
cmd: format cmd: format
- uses: borales/actions-yarn@v2.0.0 - uses: borales/actions-yarn@v4.2.0
with: with:
cmd: build cmd: build
- uses: borales/actions-yarn@v2.0.0 - uses: borales/actions-yarn@v4.2.0
with: with:
cmd: test cmd: test

View File

@@ -3,7 +3,7 @@
[![npm](https://img.shields.io/npm/v/osrs-json-hiscores.svg?style=flat-square)](https://www.npmjs.com/package/osrs-json-hiscores) [![npm](https://img.shields.io/npm/v/osrs-json-hiscores.svg?style=flat-square)](https://www.npmjs.com/package/osrs-json-hiscores)
[![downloads](https://img.shields.io/npm/dm/osrs-json-hiscores.svg?style=flat-square)](https://npm-stat.com/charts.html?package=osrs-json-hiscores) [![downloads](https://img.shields.io/npm/dm/osrs-json-hiscores.svg?style=flat-square)](https://npm-stat.com/charts.html?package=osrs-json-hiscores)
[![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/workflow/status/maxswa/osrs-json-hiscores/CI?style=flat-square)](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!**
@@ -109,7 +109,9 @@ Activities consist of all levels of clue scrolls as well as minigames and bosses
| Bounty Hunter (Rogue) | `rogueBH` | | Bounty Hunter (Rogue) | `rogueBH` |
| Bounty Hunter (Hunter) | `hunterBH` | | Bounty Hunter (Hunter) | `hunterBH` |
| Last Man Standing | `lastManStanding` | | Last Man Standing | `lastManStanding` |
| PvP Arena | `pvpArena` |
| Soul Wars Zeal | `soulWarsZeal` | | Soul Wars Zeal | `soulWarsZeal` |
| Rifts Closed | `riftsClosed` |
### Leagues ### Leagues
@@ -123,9 +125,11 @@ 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` |
| Artio | `artio` |
| Barrows Chests | `barrows` | | Barrows Chests | `barrows` |
| Bryophyta | `bryophyta` | | Bryophyta | `bryophyta` |
| Callisto | `callisto` | | Callisto | `callisto` |
| Calvar'ion | `calvarion` |
| Cerberus | `cerberus` | | Cerberus | `cerberus` |
| Chambers Of Xeric | `chambersOfXeric` | | Chambers Of Xeric | `chambersOfXeric` |
| Chambers Of Xeric: Challenge Mode | `chambersOfXericChallengeMode` | | Chambers Of Xeric: Challenge Mode | `chambersOfXericChallengeMode` |
@@ -148,18 +152,23 @@ Activities consist of all levels of clue scrolls as well as minigames and bosses
| Kreearra | `kreeArra` | | Kreearra | `kreeArra` |
| K'ril Tsutsaroth | `krilTsutsaroth` | | K'ril Tsutsaroth | `krilTsutsaroth` |
| Mimic | `mimic` | | Mimic | `mimic` |
| Nex | `nex` |
| The Nightmare of Ashihama | `nightmare` | | The Nightmare of Ashihama | `nightmare` |
| Phosani's Nightmare | `phosanisNightmare` | | Phosani's Nightmare | `phosanisNightmare` |
| Obor | `obor` | | Obor | `obor` |
| Phantom Muspah | `phantomMuspah` |
| Sarachnis | `sarachnis` | | Sarachnis | `sarachnis` |
| Scorpia | `scorpia` | | Scorpia | `scorpia` |
| Skotizo | `skotizo` | | Skotizo | `skotizo` |
| Spindel | `spindel` |
| Tempoross | `tempoross` | | Tempoross | `tempoross` |
| The Gauntlet | `gauntlet` | | The Gauntlet | `gauntlet` |
| The Corrupted Gauntlet | `corruptedGauntlet` | | The Corrupted Gauntlet | `corruptedGauntlet` |
| Theatre Of Blood | `theatreOfBlood` | | Theatre Of Blood | `theatreOfBlood` |
| Theatre Of Blood: Hard Mode | `theatreOfBloodHardMode` | | Theatre Of Blood: Hard Mode | `theatreOfBloodHardMode` |
| Thermonuclear Smoke Devil | `thermonuclearSmokeDevil` | | Thermonuclear Smoke Devil | `thermonuclearSmokeDevil` |
| Tombs of Amascut | `tombsOfAmascut` |
| Tombs of Amascut: Expert Mode | `tombsOfAmascutExpertMode` |
| TzKal-Zuk | `tzKalZuk` | | TzKal-Zuk | `tzKalZuk` |
| TzTok-Jad | `tzTokJad` | | TzTok-Jad | `tzTokJad` |
| Venenatis | `venenatis` | | Venenatis | `venenatis` |
@@ -191,7 +200,9 @@ Activities consist of all levels of clue scrolls as well as minigames and bosses
leaguePoints: {}, leaguePoints: {},
bountyHunter: {}, bountyHunter: {},
lastManStanding: {}, lastManStanding: {},
pvpArena: {},
soulWarsZeal: {}, soulWarsZeal: {},
riftsClosed: {},
bosses: {} bosses: {}
} }
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -11,7 +11,8 @@ import {
getPlayerTableURL, getPlayerTableURL,
getSkillPageURL, getSkillPageURL,
getStatsURL, getStatsURL,
BOSSES BOSSES,
INVALID_FORMAT_ERROR
} from '../src/index'; } from '../src/index';
const B0ATY_NAME = 'B0ATY'; const B0ATY_NAME = 'B0ATY';
@@ -86,12 +87,16 @@ test('Parse CSV to json', () => {
392,250 392,250
1,6143 1,6143
4814,898 4814,898
13,4057
37,225 37,225
25,1110
382,2780 382,2780
944,3000 944,3000
704,892
1981,1452 1981,1452
4981,23 4981,23
888,1046 888,1046
444,792
613,4856 613,4856
102,4038 102,4038
156,334 156,334
@@ -114,18 +119,23 @@ test('Parse CSV to json', () => {
625,2391 625,2391
120,2981 120,2981
1,109 1,109
99,39002
3,22666 3,22666
2,84 2,84
26,323 26,323
44,6233
201,1101 201,1101
82,3404 82,3404
5085,61 5085,61
678,903
18823,23 18823,23
63,375 63,375
2870,6 2870,6
6984,138 6984,138
23,923141 23,923141
4043,2000 4043,2000
4073,1020
289,13070
489,8 489,8
967,47 967,47
11155,223 11155,223
@@ -168,7 +178,9 @@ test('Parse CSV to json', () => {
rogue: { rank: 89912, score: 37 } rogue: { rank: 89912, score: 37 }
}, },
lastManStanding: { rank: 4814, score: 898 }, lastManStanding: { rank: 4814, score: 898 },
pvpArena: { rank: 13, score: 4057 },
soulWarsZeal: { rank: 37, score: 225 }, soulWarsZeal: { rank: 37, score: 225 },
riftsClosed: { rank: 25, score: 1110 },
clues: { clues: {
all: { rank: 32, score: 12148 }, all: { rank: 32, score: 12148 },
beginner: { rank: 3105, score: 76 }, beginner: { rank: 3105, score: 76 },
@@ -181,9 +193,11 @@ 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 },
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 },
callisto: { rank: 888, score: 1046 }, callisto: { rank: 888, score: 1046 },
calvarion: { rank: 444, score: 792 },
cerberus: { rank: 613, score: 4856 }, cerberus: { rank: 613, score: 4856 },
chambersOfXeric: { rank: 102, score: 4038 }, chambersOfXeric: { rank: 102, score: 4038 },
chambersOfXericChallengeMode: { rank: 156, score: 334 }, chambersOfXericChallengeMode: { rank: 156, score: 334 },
@@ -206,18 +220,23 @@ test('Parse CSV to json', () => {
kreeArra: { rank: 625, score: 2391 }, kreeArra: { rank: 625, score: 2391 },
krilTsutsaroth: { rank: 120, score: 2981 }, krilTsutsaroth: { rank: 120, score: 2981 },
mimic: { rank: 1, score: 109 }, mimic: { rank: 1, score: 109 },
nex: { rank: 99, score: 39002 },
nightmare: { rank: 3, score: 22666 }, nightmare: { rank: 3, score: 22666 },
phosanisNightmare: { rank: 2, score: 84 }, phosanisNightmare: { rank: 2, score: 84 },
obor: { rank: 26, score: 323 }, obor: { rank: 26, score: 323 },
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 },
skotizo: { rank: 5085, score: 61 }, skotizo: { rank: 5085, score: 61 },
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 },
theatreOfBlood: { rank: 6984, score: 138 }, theatreOfBlood: { rank: 6984, score: 138 },
theatreOfBloodHardMode: { rank: 23, score: 923141 }, theatreOfBloodHardMode: { rank: 23, score: 923141 },
thermonuclearSmokeDevil: { rank: 4043, score: 2000 }, thermonuclearSmokeDevil: { rank: 4043, score: 2000 },
tombsOfAmascut: { rank: 4073, score: 1020 },
tombsOfAmascutExpertMode: { rank: 289, score: 13070 },
tzKalZuk: { rank: 489, score: 8 }, tzKalZuk: { rank: 489, score: 8 },
tzTokJad: { rank: 967, score: 47 }, tzTokJad: { rank: 967, score: 47 },
venenatis: { rank: 11155, score: 223 }, venenatis: { rank: 11155, score: 223 },
@@ -232,6 +251,18 @@ test('Parse CSV to json', () => {
expect(parseStats(csv)).toStrictEqual(expectedOutput); expect(parseStats(csv)).toStrictEqual(expectedOutput);
}); });
test('Parse CSV with unknown activity', () => {
const statsWithUnknownActivity = `${lynxTitanStats}
-1,-1`;
expect(() => parseStats(statsWithUnknownActivity)).toThrow(
INVALID_FORMAT_ERROR
);
});
test('Parse invalid CSV', () => {
expect(() => parseStats('invalid')).toThrow(INVALID_FORMAT_ERROR);
});
describe('Get name format', () => { describe('Get name format', () => {
it('gets a name with a space', async () => { it('gets a name with a space', async () => {
const data = await getRSNFormat(LYNX_TITAN_SPACE_NAME); const data = await getRSNFormat(LYNX_TITAN_SPACE_NAME);
@@ -444,7 +475,9 @@ test('Get non-existent player', async () => {
}); });
test('Get stats by gamemode', async () => { test('Get stats by gamemode', async () => {
const { skills, bosses } = await getStatsByGamemode(LYNX_TITAN_FORMATTED_NAME); const { skills, bosses } = await getStatsByGamemode(
LYNX_TITAN_FORMATTED_NAME
);
expect(skills).toMatchObject({ expect(skills).toMatchObject({
overall: { rank: expect.any(Number), level: 2277, xp: 4600000000 }, overall: { rank: expect.any(Number), level: 2277, xp: 4600000000 },
@@ -478,3 +511,50 @@ test('Get stats by gamemode', async () => {
expect.assertions(2); expect.assertions(2);
}); });
describe('Get stats options', () => {
const rsn = 'player';
let axiosMock: jest.Mock;
beforeEach(() => {
axios.get = jest.fn(
(url) =>
new Promise<any>((resolve) =>
resolve(
url === getPlayerTableURL('main', rsn)
? { data: lynxTitanNamePage }
: { status: 200, data: lynxTitanStats }
)
)
);
axiosMock = axios.get as any;
axiosMock.mockClear();
});
it('fetches all gamemodes and formatted RSN when no options provided', async () => {
await getStats(rsn);
expect(axiosMock.mock.calls.map((val) => val[0])).toEqual([
getStatsURL('main', rsn),
getPlayerTableURL('main', rsn),
getStatsURL('ironman', rsn),
getStatsURL('hardcore', rsn),
getStatsURL('ultimate', rsn)
]);
});
it('skips fetching formatted RSN when option is provided', async () => {
await getStats(rsn, { shouldGetFormattedRsn: false });
expect(
axiosMock.mock.calls.some(
(val) => val[0] === getPlayerTableURL('main', rsn)
)
).toBeFalsy();
});
it('skips fetching game mode when option is provided', async () => {
await getStats(rsn, {
otherGamemodes: ['ironman', 'ultimate']
});
expect(
axiosMock.mock.calls.some(
(val) => val[0] === getStatsURL('hardcore', rsn)
)
).toBeFalsy();
});
});

File diff suppressed because it is too large Load Diff

View File

@@ -81,3 +81,12 @@
-1,-1 -1,-1
-1,-1 -1,-1
-1,-1 -1,-1
-1,-1
-1,-1
-1,-1
-1,-1
-1,-1
-1,-1
-1,-1
-1,-1
-1,-1
Can't render this file because it has a wrong number of fields in line 25.

View File

@@ -1,6 +1,6 @@
{ {
"name": "osrs-json-hiscores", "name": "osrs-json-hiscores",
"version": "2.6.0", "version": "2.13.1",
"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",
@@ -30,6 +30,9 @@
"stats", "stats",
"skills" "skills"
], ],
"publishConfig": {
"registry": "https://registry.npmjs.org"
},
"author": "maxswa", "author": "maxswa",
"license": "ISC", "license": "ISC",
"bugs": { "bugs": {
@@ -106,7 +109,7 @@
"husky": "^5.2.0", "husky": "^5.2.0",
"jest": "^26.6.3", "jest": "^26.6.3",
"lint-staged": "^10.5.4", "lint-staged": "^10.5.4",
"np": "6.5.0", "np": "^7.7.0",
"prettier": "^2.2.1", "prettier": "^2.2.1",
"ts-jest": "^26.5.4", "ts-jest": "^26.5.4",
"typescript": "^4.2.3" "typescript": "^4.2.3"

View File

@@ -1,4 +1,5 @@
import { JSDOM } from 'jsdom'; import { AxiosResponse } from 'axios';
import { BinaryData, JSDOM } from 'jsdom';
import { import {
Player, Player,
Activity, Activity,
@@ -12,7 +13,8 @@ import {
PlayerSkillRow, PlayerSkillRow,
ActivityName, ActivityName,
PlayerActivityRow, PlayerActivityRow,
Bosses Bosses,
GetStatsOptions
} from './types'; } from './types';
import { import {
getStatsURL, getStatsURL,
@@ -27,7 +29,9 @@ import {
rsnFromElement, rsnFromElement,
getActivityPageURL, getActivityPageURL,
httpGet, httpGet,
BOSSES BOSSES,
INVALID_FORMAT_ERROR,
validateRSN
} from './utils'; } from './utils';
/** /**
@@ -37,24 +41,19 @@ import {
* @returns Formatted version of the rsn. * @returns Formatted version of the rsn.
*/ */
export async function getRSNFormat(rsn: string): Promise<string> { export async function getRSNFormat(rsn: string): Promise<string> {
if (typeof rsn !== 'string') { validateRSN(rsn);
throw Error('RSN must be a string');
} else if (!/^[a-zA-Z0-9 _-]+$/.test(rsn)) {
throw Error('RSN contains invalid character');
} else if (rsn.length > 12 || rsn.length < 1) {
throw Error('RSN must be between 1 and 12 characters');
}
const url = getPlayerTableURL('main', rsn); const url = getPlayerTableURL('main', rsn);
try { try {
const response = await httpGet(url); const response = await httpGet<string | Buffer | BinaryData | undefined>(
const dom = new JSDOM(response.data); url
const spans = dom.window.document.querySelectorAll(
'span[style="color:#AA0022;"]'
); );
if (spans.length >= 2) { const dom = new JSDOM(response.data);
const nameSpan = spans[1]; const anchor = dom.window.document.querySelector(
return rsnFromElement(nameSpan); '.personal-hiscores__row.personal-hiscores__row--type-highlight a'
);
if (anchor) {
return rsnFromElement(anchor);
} }
throw Error('Player not found'); throw Error('Player not found');
} catch { } catch {
@@ -74,6 +73,13 @@ export function parseStats(csv: string): Stats {
.filter((entry) => !!entry) .filter((entry) => !!entry)
.map((stat) => stat.split(',')); .map((stat) => stat.split(','));
if (
splitCSV.length !==
SKILLS.length + BH_MODES.length + CLUES.length + BOSSES.length + 5
) {
throw Error(INVALID_FORMAT_ERROR);
}
const skillObjects: Skill[] = splitCSV const skillObjects: Skill[] = splitCSV
.filter((stat) => stat.length === 3) .filter((stat) => stat.length === 3)
.map((stat) => { .map((stat) => {
@@ -100,7 +106,12 @@ export function parseStats(csv: string): Stats {
const [leaguePoints] = activityObjects.splice(0, 1); const [leaguePoints] = activityObjects.splice(0, 1);
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, soulWarsZeal] = activityObjects.splice(0, 2); const [
lastManStanding,
pvpArena,
soulWarsZeal,
riftsClosed
] = activityObjects.splice(0, 4);
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) => {
@@ -132,7 +143,9 @@ export function parseStats(csv: string): Stats {
leaguePoints, leaguePoints,
bountyHunter, bountyHunter,
lastManStanding, lastManStanding,
pvpArena,
soulWarsZeal, soulWarsZeal,
riftsClosed,
clues, clues,
bosses bosses
}; };
@@ -149,25 +162,36 @@ export function parseStats(csv: string): Stats {
* @param rsn Username of the player. * @param rsn Username of the player.
* @returns Player object. * @returns Player object.
*/ */
export async function getStats(rsn: string): Promise<Player> { export async function getStats(
if (typeof rsn !== 'string') { rsn: string,
throw Error('RSN must be a string'); options?: GetStatsOptions
} else if (!/^[a-zA-Z0-9 _]+$/.test(rsn)) { ): Promise<Player> {
throw Error('RSN contains invalid character'); validateRSN(rsn);
} else if (rsn.length > 12 || rsn.length < 1) { const otherGamemodes = options?.otherGamemodes ?? [
throw Error('RSN must be between 1 and 12 characters'); 'ironman',
} 'hardcore',
'ultimate'
];
const shouldGetFormattedRsn = options?.shouldGetFormattedRsn ?? true;
const mainRes = await httpGet(getStatsURL('main', rsn)); const mainRes = await httpGet<string>(getStatsURL('main', rsn));
if (mainRes.status === 200) { if (mainRes.status === 200) {
const otherResponses = await Promise.all([ const emptyResponse: AxiosResponse<string> = {
httpGet(getStatsURL('ironman', rsn)).catch((err) => err), status: 404,
httpGet(getStatsURL('hardcore', rsn)).catch((err) => err), data: '',
httpGet(getStatsURL('ultimate', rsn)).catch((err) => err), statusText: '',
getRSNFormat(rsn).catch(() => undefined) headers: {},
]); config: {}
};
const [ironRes, hcRes, ultRes, formattedName] = otherResponses; const getModeStats = async (
mode: Extract<Gamemode, 'ironman' | 'hardcore' | 'ultimate'>
): Promise<AxiosResponse<string>> =>
otherGamemodes.includes(mode)
? httpGet<string>(getStatsURL(mode, rsn)).catch((err) => err)
: emptyResponse;
const formattedName = shouldGetFormattedRsn
? await getRSNFormat(rsn).catch(() => undefined)
: undefined;
const player: Player = { const player: Player = {
name: formattedName ?? rsn, name: formattedName ?? rsn,
@@ -178,8 +202,11 @@ export async function getStats(rsn: string): Promise<Player> {
}; };
player.main = parseStats(mainRes.data); player.main = parseStats(mainRes.data);
const ironRes = await getModeStats('ironman');
if (ironRes.status === 200) { if (ironRes.status === 200) {
player.ironman = parseStats(ironRes.data); player.ironman = parseStats(ironRes.data);
const hcRes = await getModeStats('hardcore');
const ultRes = await getModeStats('ultimate');
if (hcRes.status === 200) { if (hcRes.status === 200) {
player.mode = 'hardcore'; player.mode = 'hardcore';
player.hardcore = parseStats(hcRes.data); player.hardcore = parseStats(hcRes.data);
@@ -237,16 +264,11 @@ export async function getStatsByGamemode(
rsn: string, rsn: string,
mode: Gamemode = 'main' mode: Gamemode = 'main'
): Promise<Stats> { ): Promise<Stats> {
if (typeof rsn !== 'string') { validateRSN(rsn);
throw Error('RSN must be a string'); if (!GAMEMODES.includes(mode)) {
} else if (!/^[a-zA-Z0-9 _]+$/.test(rsn)) {
throw Error('RSN contains invalid character');
} else if (rsn.length > 12 || rsn.length < 1) {
throw Error('RSN must be between 1 and 12 characters');
} else if (!GAMEMODES.includes(mode)) {
throw Error('Invalid game mode'); throw Error('Invalid game mode');
} }
const response = await httpGet(getStatsURL(mode, rsn)); const response = await httpGet<string>(getStatsURL(mode, rsn));
if (response.status !== 200) { if (response.status !== 200) {
throw Error('Player not found'); throw Error('Player not found');
} }
@@ -269,7 +291,7 @@ export async function getSkillPage(
} }
const url = getSkillPageURL(mode, skill, page); const url = getSkillPageURL(mode, skill, page);
const response = await httpGet(url); const response = await httpGet<string | Buffer | BinaryData | undefined>(url);
const dom = new JSDOM(response.data); const dom = new JSDOM(response.data);
const playersHTML = dom.window.document.querySelectorAll( const playersHTML = dom.window.document.querySelectorAll(
'.personal-hiscores__row' '.personal-hiscores__row'
@@ -317,7 +339,7 @@ export async function getActivityPage(
} }
const url = getActivityPageURL(mode, activity, page); const url = getActivityPageURL(mode, activity, page);
const response = await httpGet(url); const response = await httpGet<string | Buffer | BinaryData | undefined>(url);
const dom = new JSDOM(response.data); const dom = new JSDOM(response.data);
const playersHTML = dom.window.document.querySelectorAll( const playersHTML = dom.window.document.querySelectorAll(
'.personal-hiscores__row' '.personal-hiscores__row'

View File

@@ -5,7 +5,10 @@ export type Gamemode =
| 'hardcore' | 'hardcore'
| 'deadman' | 'deadman'
| 'seasonal' | 'seasonal'
| 'tournament'; | 'tournament'
| 'skiller'
| 'oneDefence'
| 'freshStart';
export interface Skill { export interface Skill {
rank: number; rank: number;
@@ -64,9 +67,11 @@ export type BH = { [Type in BHType]: Activity };
export type Boss = export type Boss =
| 'abyssalSire' | 'abyssalSire'
| 'alchemicalHydra' | 'alchemicalHydra'
| 'artio'
| 'barrows' | 'barrows'
| 'bryophyta' | 'bryophyta'
| 'callisto' | 'callisto'
| 'calvarion'
| 'cerberus' | 'cerberus'
| 'chambersOfXeric' | 'chambersOfXeric'
| 'chambersOfXericChallengeMode' | 'chambersOfXericChallengeMode'
@@ -89,18 +94,23 @@ export type Boss =
| 'kreeArra' | 'kreeArra'
| 'krilTsutsaroth' | 'krilTsutsaroth'
| 'mimic' | 'mimic'
| 'nex'
| 'nightmare' | 'nightmare'
| 'phosanisNightmare' | 'phosanisNightmare'
| 'obor' | 'obor'
| 'phantomMuspah'
| 'sarachnis' | 'sarachnis'
| 'scorpia' | 'scorpia'
| 'skotizo' | 'skotizo'
| 'spindel'
| 'tempoross' | 'tempoross'
| 'gauntlet' | 'gauntlet'
| 'corruptedGauntlet' | 'corruptedGauntlet'
| 'theatreOfBlood' | 'theatreOfBlood'
| 'theatreOfBloodHardMode' | 'theatreOfBloodHardMode'
| 'thermonuclearSmokeDevil' | 'thermonuclearSmokeDevil'
| 'tombsOfAmascut'
| 'tombsOfAmascutExpertMode'
| 'tzKalZuk' | 'tzKalZuk'
| 'tzTokJad' | 'tzTokJad'
| 'venenatis' | 'venenatis'
@@ -117,7 +127,9 @@ export type ActivityName =
| 'hunterBH' | 'hunterBH'
| 'rogueBH' | 'rogueBH'
| 'lastManStanding' | 'lastManStanding'
| 'pvpArena'
| 'soulWarsZeal' | 'soulWarsZeal'
| 'riftsClosed'
| 'allClues' | 'allClues'
| 'beginnerClues' | 'beginnerClues'
| 'easyClues' | 'easyClues'
@@ -133,7 +145,9 @@ export interface Stats {
leaguePoints: Activity; leaguePoints: Activity;
bountyHunter: BH; bountyHunter: BH;
lastManStanding: Activity; lastManStanding: Activity;
pvpArena: Activity;
soulWarsZeal: Activity; soulWarsZeal: Activity;
riftsClosed: Activity;
bosses: Bosses; bosses: Bosses;
} }
export type Modes = { [M in Gamemode]?: Stats }; export type Modes = { [M in Gamemode]?: Stats };
@@ -155,3 +169,16 @@ export interface PlayerActivityRow extends Activity {
name: string; name: string;
dead: boolean; dead: boolean;
} }
export interface GetStatsOptions {
/**
* Other game modes to fetch ranks for.
* @defaultvalue `['ironman', 'hardcore', 'ultimate']`
*/
otherGamemodes?: Extract<Gamemode, 'ironman' | 'hardcore' | 'ultimate'>[];
/**
* If true, the formatted RSN will be fetched. Otherwise it will return the provided, unformatted RSN.
* @defaultvalue `true`
*/
shouldGetFormattedRsn?: boolean;
}

View File

@@ -22,7 +22,10 @@ export const GAMEMODE_URL: GamemodeUrl = {
ultimate: `${BASE_URL}_ultimate/`, ultimate: `${BASE_URL}_ultimate/`,
deadman: `${BASE_URL}_deadman/`, deadman: `${BASE_URL}_deadman/`,
seasonal: `${BASE_URL}_seasonal/`, seasonal: `${BASE_URL}_seasonal/`,
tournament: `${BASE_URL}_tournament/` tournament: `${BASE_URL}_tournament/`,
skiller: `${BASE_URL}_skiller/`,
oneDefence: `${BASE_URL}_skiller_defence/`,
freshStart: `${BASE_URL}_fresh_start/`
}; };
export const SKILLS: SkillName[] = [ export const SKILLS: SkillName[] = [
'overall', 'overall',
@@ -72,9 +75,11 @@ export const GAMEMODES: Gamemode[] = [
export const BOSSES: Boss[] = [ export const BOSSES: Boss[] = [
'abyssalSire', 'abyssalSire',
'alchemicalHydra', 'alchemicalHydra',
'artio',
'barrows', 'barrows',
'bryophyta', 'bryophyta',
'callisto', 'callisto',
'calvarion',
'cerberus', 'cerberus',
'chambersOfXeric', 'chambersOfXeric',
'chambersOfXericChallengeMode', 'chambersOfXericChallengeMode',
@@ -97,18 +102,23 @@ export const BOSSES: Boss[] = [
'kreeArra', 'kreeArra',
'krilTsutsaroth', 'krilTsutsaroth',
'mimic', 'mimic',
'nex',
'nightmare', 'nightmare',
'phosanisNightmare', 'phosanisNightmare',
'obor', 'obor',
'phantomMuspah',
'sarachnis', 'sarachnis',
'scorpia', 'scorpia',
'skotizo', 'skotizo',
'spindel',
'tempoross', 'tempoross',
'gauntlet', 'gauntlet',
'corruptedGauntlet', 'corruptedGauntlet',
'theatreOfBlood', 'theatreOfBlood',
'theatreOfBloodHardMode', 'theatreOfBloodHardMode',
'thermonuclearSmokeDevil', 'thermonuclearSmokeDevil',
'tombsOfAmascut',
'tombsOfAmascutExpertMode',
'tzKalZuk', 'tzKalZuk',
'tzTokJad', 'tzTokJad',
'venenatis', 'venenatis',
@@ -130,7 +140,9 @@ export const ACTIVITIES: ActivityName[] = [
'eliteClues', 'eliteClues',
'masterClues', 'masterClues',
'lastManStanding', 'lastManStanding',
'pvpArena',
'soulWarsZeal', 'soulWarsZeal',
'riftsClosed',
...BOSSES ...BOSSES
]; ];
@@ -141,9 +153,11 @@ 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',
artio: 'Artio',
barrows: 'Barrows Chests', barrows: 'Barrows Chests',
bryophyta: 'Bryophyta', bryophyta: 'Bryophyta',
callisto: 'Callisto', callisto: 'Callisto',
calvarion: "Calvar'ion",
cerberus: 'Cerberus', cerberus: 'Cerberus',
chambersOfXeric: 'Chambers of Xeric', chambersOfXeric: 'Chambers of Xeric',
chambersOfXericChallengeMode: 'Chambers of Xeric: Challenge Mode', chambersOfXericChallengeMode: 'Chambers of Xeric: Challenge Mode',
@@ -166,18 +180,23 @@ export const FORMATTED_BOSS_NAMES: FormattedBossNames = {
kreeArra: "Kree'Arra", kreeArra: "Kree'Arra",
krilTsutsaroth: "K'ril Tsutsaroth", krilTsutsaroth: "K'ril Tsutsaroth",
mimic: 'Mimic', mimic: 'Mimic',
nex: 'Nex',
nightmare: 'The Nightmare of Ashihama', nightmare: 'The Nightmare of Ashihama',
phosanisNightmare: "Phosani's Nightmare", phosanisNightmare: "Phosani's Nightmare",
obor: 'Obor', obor: 'Obor',
phantomMuspah: 'Phantom Muspah',
sarachnis: 'Sarachnis', sarachnis: 'Sarachnis',
scorpia: 'Scorpia', scorpia: 'Scorpia',
skotizo: 'Skotizo', skotizo: 'Skotizo',
spindel: 'Spindel',
tempoross: 'Tempoross', tempoross: 'Tempoross',
gauntlet: 'The Gauntlet', gauntlet: 'The Gauntlet',
corruptedGauntlet: 'The Corrupted Gauntlet', corruptedGauntlet: 'The Corrupted Gauntlet',
theatreOfBlood: 'Theatre of Blood', theatreOfBlood: 'Theatre of Blood',
theatreOfBloodHardMode: 'Theatre of Blood: Hard Mode', theatreOfBloodHardMode: 'Theatre of Blood: Hard Mode',
thermonuclearSmokeDevil: 'Thermonuclear Smoke Devil', thermonuclearSmokeDevil: 'Thermonuclear Smoke Devil',
tombsOfAmascut: 'Tombs of Amascut',
tombsOfAmascutExpertMode: 'Tombs of Amascut: Expert Mode',
tzKalZuk: 'TzKal-Zuk', tzKalZuk: 'TzKal-Zuk',
tzTokJad: 'TzTok-Jad', tzTokJad: 'TzTok-Jad',
venenatis: 'Venenatis', venenatis: 'Venenatis',
@@ -243,5 +262,9 @@ export const FORMATTED_BH_NAMES: FormattedBHNames = {
}; };
export const FORMATTED_LMS = 'Last Man Standing'; export const FORMATTED_LMS = 'Last Man Standing';
export const FORMATTED_PVP_ARENA = 'PvP Arena';
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_RIFTS_CLOSED = 'Rifts Closed';
export const INVALID_FORMAT_ERROR = 'Invalid hiscores format';

View File

@@ -96,10 +96,25 @@ export const rsnFromElement = (el: Element | null) => {
* @param url URL to run a `GET` request against. * @param url URL to run a `GET` request against.
* @returns Axios response. * @returns Axios response.
*/ */
export const httpGet = (url: string) => export const httpGet = <Response>(url: string) =>
axios.get(url, { axios.get<Response>(url, {
headers: { headers: {
// without User-Agent header requests may be rejected by DDoS protection mechanism // without User-Agent header requests may be rejected by DDoS protection mechanism
'User-Agent': ua.firefox(80) 'User-Agent': ua.firefox(80)
} }
}); });
/**
* Validates that a provided RSN has the same username restrictions as Jagex.
* @param rsn Username to validate.
* @throws Error if the RSN fails validation.
*/
export const validateRSN = (rsn: string) => {
if (typeof rsn !== 'string') {
throw Error('RSN must be a string');
} else if (!/^[a-zA-Z0-9 _-]+$/.test(rsn)) {
throw Error('RSN contains invalid character');
} else if (rsn.length > 12 || rsn.length < 1) {
throw Error('RSN must be between 1 and 12 characters');
}
};

792
yarn.lock

File diff suppressed because it is too large Load Diff