vlr-stats-scraper 1.4.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +326 -170
- package/index.mjs +20 -17
- package/main.mjs +122 -47
- package/package.json +1 -1
- package/scripts/db.mjs +130 -102
- package/scripts/player-info-scraper.mjs +126 -127
- package/scripts/player-link-scraper.mjs +36 -9
package/README.md
CHANGED
|
@@ -1,170 +1,326 @@
|
|
|
1
|
-
# vlr-stats-scraper
|
|
2
|
-
|
|
3
|
-
Scrapes player stats from [vlr.gg](https://www.vlr.gg) and stores them in a local SQLite
|
|
4
|
-
database, grouped by tournament or stage, so you can pull a backlog of players.
|
|
5
|
-
|
|
6
|
-
## Setup
|
|
7
|
-
|
|
8
|
-
Requires Node.js 18+ and a [Hyperbrowser](https://hyperbrowser.ai) API key for scraping.
|
|
9
|
-
|
|
10
|
-
```bash
|
|
11
|
-
npm install vlr-stats-scraper
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
Create a `.env` file in the directory you run it from:
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
HYPERBROWSER_API_KEY=your_key_here
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## CLI usage
|
|
21
|
-
|
|
22
|
-
The package installs a `valstats` command.
|
|
23
|
-
|
|
24
|
-
| Command | What it does |
|
|
25
|
-
| --- | --- |
|
|
26
|
-
| `valstats <link> <year> <event-name>` | Scrape every player on an event page and save them under that event |
|
|
27
|
-
| `valstats --
|
|
28
|
-
| `valstats --
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
- `
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
2.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
1
|
+
# vlr-stats-scraper
|
|
2
|
+
|
|
3
|
+
Scrapes player stats from [vlr.gg](https://www.vlr.gg) and stores them in a local SQLite
|
|
4
|
+
database, grouped by tournament or stage, so you can pull a backlog of players.
|
|
5
|
+
|
|
6
|
+
## Setup
|
|
7
|
+
|
|
8
|
+
Requires Node.js 18+ and a [Hyperbrowser](https://hyperbrowser.ai) API key for scraping.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install vlr-stats-scraper
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Create a `.env` file in the directory you run it from:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
HYPERBROWSER_API_KEY=your_key_here
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## CLI usage
|
|
21
|
+
|
|
22
|
+
The package installs a `valstats` command.
|
|
23
|
+
|
|
24
|
+
| Command | What it does |
|
|
25
|
+
| --- | --- |
|
|
26
|
+
| `valstats <link> <year> <event-name>` | Scrape every player on an event page and save them under that event |
|
|
27
|
+
| `valstats --search <name \| link>` | Print the stats of every saved player whose name starts with `name`, or of one player scraped live from a link |
|
|
28
|
+
| `valstats --player <link> <event-name> <year> [region]` | Scrape one player and add them to an event that's already saved |
|
|
29
|
+
| `valstats --clear-event <event-name>` | Remove one event and its players |
|
|
30
|
+
| `valstats --clear` | Wipe the whole database (asks for confirmation) |
|
|
31
|
+
|
|
32
|
+
### Scraping an event
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npx valstats <link> <year> <event-name>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npx valstats https://www.vlr.gg/event/2977/vct-2026-americas-stage-2/group-stage 2026 "Stage 2"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
- `link` — the vlr.gg event/group-stage page to scrape.
|
|
43
|
+
- `year` — the year the event took place.
|
|
44
|
+
- `event-name` — a label for this tournament/stage (used to group players together later).
|
|
45
|
+
|
|
46
|
+
What happens:
|
|
47
|
+
|
|
48
|
+
1. The event page is scraped for its title and every player profile linked on it.
|
|
49
|
+
2. The region is read from the event title and saved on every player (not on the event):
|
|
50
|
+
|
|
51
|
+
| Title contains | Region |
|
|
52
|
+
| --- | --- |
|
|
53
|
+
| `America` (e.g. "VCT 2026: Americas Stage 2") | `AMER` |
|
|
54
|
+
| `EMEA` | `EMEA` |
|
|
55
|
+
| `Pacific` | `PAC` |
|
|
56
|
+
| `China` | `CN` |
|
|
57
|
+
| none of these (e.g. Masters, Champions) | `null` |
|
|
58
|
+
|
|
59
|
+
3. Each player is scraped using vlr.gg's **all-time** timespan, saved to `players.db` in your
|
|
60
|
+
current directory under that event, and printed to the console.
|
|
61
|
+
|
|
62
|
+
If the event page can't be scraped, nothing is saved or deleted.
|
|
63
|
+
|
|
64
|
+
Running it again with an event name and year that are already saved replaces that event's
|
|
65
|
+
players with the freshly scraped ones. A player who is already saved under a different event
|
|
66
|
+
gets a new, separate row for this event, so their stats from each event are kept apart (see
|
|
67
|
+
[Data storage](#data-storage)).
|
|
68
|
+
|
|
69
|
+
### Viewing a player's stats
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npx valstats --search tenz # every saved player with "tenz" in their name
|
|
73
|
+
npx valstats --search ten # matches names starting with "ten": tenz, tenten, ... (not "kitten")
|
|
74
|
+
npx valstats --search https://www.vlr.gg/player/9/tenz # scrape a player live without saving
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
- `--search <name>` searches `players.db` and prints every player whose name starts with
|
|
78
|
+
those characters (case-insensitive). Names are the ones from the vlr.gg profile URL,
|
|
79
|
+
e.g. `tenz`. Nothing is scraped. A player saved under several events is printed once per
|
|
80
|
+
event, labelled with the event name and year, e.g. `tenz (Champs, 2026)`.
|
|
81
|
+
- `--search <link>` scrapes that profile live using the all-time timespan. The result is
|
|
82
|
+
printed but not saved to the database.
|
|
83
|
+
|
|
84
|
+
For each player, their team, past teams, nationality, region, winnings, top agents and
|
|
85
|
+
average K:D are printed, followed by a table of their stats on their top 3 agents.
|
|
86
|
+
|
|
87
|
+
### Adding a player to an event by hand
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npx valstats --player <link> <event-name> <year> [region]
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
npx valstats --player https://www.vlr.gg/player/9/tenz "Stage 2" 2026 # region copied from the event's other players
|
|
95
|
+
npx valstats --player https://www.vlr.gg/player/9/tenz "Stage 2" 2026 AMER # region set explicitly
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Scrapes one player and saves them under an event that's already in `players.db`, e.g. a player
|
|
99
|
+
the event page missed. The event is checked before scraping, so a mistyped name or year fails
|
|
100
|
+
straight away without using a scrape. If you leave out `region`, the player gets the same
|
|
101
|
+
region as the players already saved under that event.
|
|
102
|
+
|
|
103
|
+
### Clearing data
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
npx valstats --clear-event "Stage 2" # remove one event and its players
|
|
107
|
+
npx valstats --clear # wipe the whole database (type "yes" to confirm)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Clearing one event only removes that event's player rows. The same player's saves under other
|
|
111
|
+
events are kept.
|
|
112
|
+
|
|
113
|
+
## What gets scraped
|
|
114
|
+
|
|
115
|
+
Each player is stored as an object like this:
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
{
|
|
119
|
+
name: 'tenz', // from the profile URL
|
|
120
|
+
team: 'Sentinels', // current team
|
|
121
|
+
past_teams: ['Cloud9', ...], // previous teams
|
|
122
|
+
winnings: '$123,456', // total event winnings
|
|
123
|
+
most_played_agents: ['Jett', ...], // top 3 agents by usage
|
|
124
|
+
avg_kda: 1.23, // average K:D across those top 3 agents
|
|
125
|
+
nationality: 'Canada',
|
|
126
|
+
region: 'AMER', // from the event title, or null
|
|
127
|
+
stats: [ // full agent stat rows for the top 3 agents,
|
|
128
|
+
{ Agent: 'Jett', 'K:D': '1.25', ... } // keyed by vlr.gg's column headers
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Library usage
|
|
134
|
+
|
|
135
|
+
```js
|
|
136
|
+
import {
|
|
137
|
+
scrapePlayer,
|
|
138
|
+
scrapeWebsite,
|
|
139
|
+
savePlayer,
|
|
140
|
+
saveEvent,
|
|
141
|
+
getPlayersByEvent,
|
|
142
|
+
getRandomPlayerFromEvent,
|
|
143
|
+
} from 'vlr-stats-scraper';
|
|
144
|
+
|
|
145
|
+
const { playerLinks, region } = await scrapeWebsite('https://www.vlr.gg/event/.../group-stage');
|
|
146
|
+
const eventId = saveEvent({ name: 'Stage 2', year: 2026 });
|
|
147
|
+
|
|
148
|
+
for (const link of playerLinks) {
|
|
149
|
+
const player = await scrapePlayer(link, region);
|
|
150
|
+
if (player) {
|
|
151
|
+
savePlayer(eventId, player);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const roster = getPlayersByEvent('Stage 2');
|
|
156
|
+
const pick = getRandomPlayerFromEvent('Stage 2');
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Upgrading from 1.x
|
|
160
|
+
|
|
161
|
+
2.0.0 changes how players are stored and has breaking API changes:
|
|
162
|
+
|
|
163
|
+
| 1.x | 2.0.0 |
|
|
164
|
+
| --- | --- |
|
|
165
|
+
| `savePlayer(player)` then `addPlayerToEvent(eventId, player.name)` | `savePlayer(eventId, player)`. `addPlayerToEvent` is removed. |
|
|
166
|
+
| `scrapeWebsite(url)` returns `string[]` | Returns `{ playerLinks, region }` |
|
|
167
|
+
| One row per player, shared across events | One row per player **per event** (see [Data storage](#data-storage)) |
|
|
168
|
+
| `valstats --player <name>` | `valstats --search <name>`. `--player` now adds a player to an event. |
|
|
169
|
+
| Region typed in at a prompt and saved on the event | Region read from the event title and saved on each player only |
|
|
170
|
+
| `saveEvent({ name, url, region, year, stage })` | `saveEvent({ name, url, year, stage })` |
|
|
171
|
+
|
|
172
|
+
Existing `players.db` files are migrated automatically the first time they're opened.
|
|
173
|
+
|
|
174
|
+
### Exports
|
|
175
|
+
|
|
176
|
+
#### Scraping
|
|
177
|
+
|
|
178
|
+
| Function | Returns | Description |
|
|
179
|
+
| --- | --- | --- |
|
|
180
|
+
| `scrapeWebsite(url)` | `Promise<{ playerLinks, region }>` | Scrapes an event page. `playerLinks` is every player profile link on it (with `?timespan=all`); `region` is read from the event title (`'AMER'`, `'EMEA'`, `'PAC'`, `'CN'` or `null`). Returns `undefined` if scraping fails. |
|
|
181
|
+
| `scrapePlayer(url, region)` | `Promise<Player>` | Scrapes one player's profile page into a player object (see above). `region` is stored as-is. Returns `undefined` if scraping fails. |
|
|
182
|
+
|
|
183
|
+
#### Players
|
|
184
|
+
|
|
185
|
+
A player is saved separately for each event, so the same player can have different stats in
|
|
186
|
+
different events. Players read from the database also have `id`, `event_id`, `event_name` and
|
|
187
|
+
`event_year`.
|
|
188
|
+
|
|
189
|
+
| Function | Returns | Description |
|
|
190
|
+
| --- | --- | --- |
|
|
191
|
+
| `savePlayer(eventId, player)` | `number` | Saves a player's stats for one event and returns the row's id. Re-saving the same player in the same event updates them. |
|
|
192
|
+
| `getPlayerById(id)` | `Player \| null` | Looks up one saved player row by id. |
|
|
193
|
+
| `getPlayer(name)` | `Player \| null` | The player as they were in their most recent event. |
|
|
194
|
+
| `getPlayerHistory(name)` | `Player[]` | Every saved version of a player, one per event, newest first. |
|
|
195
|
+
| `searchPlayers(query)` | `Player[]` | Every player whose name starts with `query` (case-insensitive), sorted by name, one entry per event. |
|
|
196
|
+
| `getAllPlayers()` | `Player[]` | Every player row in the database. |
|
|
197
|
+
| `getRandomPlayer()` | `Player \| null` | A random player row from the whole database. |
|
|
198
|
+
|
|
199
|
+
#### Events (tournaments / stages)
|
|
200
|
+
|
|
201
|
+
| Function | Returns | Description |
|
|
202
|
+
| --- | --- | --- |
|
|
203
|
+
| `saveEvent({ name, url, year, stage })` | `number` | Creates or updates an event by name and returns its id. Only `name` is required. |
|
|
204
|
+
| `getEvents()` | `Event[]` | Every saved event. |
|
|
205
|
+
| `getEventByName(name)` | `Event \| undefined` | Looks up an event by name. |
|
|
206
|
+
| `getEventId(name, year)` | `number \| undefined` | The id of the event with that name and year. |
|
|
207
|
+
| `getPlayersByEvent(eventName)` | `Player[]` | Every player saved under an event. |
|
|
208
|
+
| `getRandomPlayerFromEvent(eventName)` | `Player \| null` | A random player from one event. |
|
|
209
|
+
|
|
210
|
+
#### Clearing
|
|
211
|
+
|
|
212
|
+
| Function | Returns | Description |
|
|
213
|
+
| --- | --- | --- |
|
|
214
|
+
| `emptyEvent(eventName)` | `boolean` | Removes an event's players but keeps the event so it can be re-scraped. `false` if the event doesn't exist. |
|
|
215
|
+
| `clearEvent(eventName)` | `boolean` | Removes an event and its players. `false` if the event doesn't exist. |
|
|
216
|
+
| `clearDatabase()` | — | Deletes every event and player. |
|
|
217
|
+
|
|
218
|
+
`emptyEvent` and `clearEvent` only delete that event's player rows, so the same player's saves in
|
|
219
|
+
other events are kept.
|
|
220
|
+
|
|
221
|
+
## Data storage
|
|
222
|
+
|
|
223
|
+
Player and event data is stored in a `players.db` SQLite file created in whichever
|
|
224
|
+
directory you run the tool from. It has two tables, and **every player row belongs to exactly
|
|
225
|
+
one event**:
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
events players
|
|
229
|
+
────────────── ────────────────────────────
|
|
230
|
+
id (PK) ◄───────────────────── event_id (which event this row is from)
|
|
231
|
+
name (unique) id (PK) (unique per row)
|
|
232
|
+
url name
|
|
233
|
+
year team, past_teams, winnings,
|
|
234
|
+
stage most_played_agents, avg_kda,
|
|
235
|
+
nationality, region, stats
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
- `events` — one row per tournament/stage. Region isn't stored here; it's on each player.
|
|
239
|
+
- `players` — one row per player **per event**. `past_teams`, `most_played_agents` and `stats`
|
|
240
|
+
are stored as JSON and parsed back automatically when read.
|
|
241
|
+
|
|
242
|
+
A player's stats change over time, so the same player in two events is saved as two separate
|
|
243
|
+
rows, each with the stats they had when that event was scraped.
|
|
244
|
+
|
|
245
|
+
### Example
|
|
246
|
+
|
|
247
|
+
**events**
|
|
248
|
+
|
|
249
|
+
| id | name | year |
|
|
250
|
+
|----|---------|------|
|
|
251
|
+
| 1 | Masters | 2025 |
|
|
252
|
+
| 2 | Champs | 2026 |
|
|
253
|
+
|
|
254
|
+
**players**
|
|
255
|
+
|
|
256
|
+
| id | event_id | name | avg_kda |
|
|
257
|
+
|----|----------|-------|---------|
|
|
258
|
+
| 1 | 1 | tenz | 1.10 |
|
|
259
|
+
| 2 | 2 | tenz | 1.35 |
|
|
260
|
+
| 3 | 2 | aspas | 1.40 |
|
|
261
|
+
|
|
262
|
+
`tenz` has two rows: one for how they played at Masters and one for Champs. Each has its own
|
|
263
|
+
`id` and stats.
|
|
264
|
+
|
|
265
|
+
### Rules the database enforces
|
|
266
|
+
|
|
267
|
+
- **One copy of a player per event.** `(event_id, name)` is unique, so re-scraping Champs
|
|
268
|
+
updates tenz's Champs row instead of adding another one. Their Masters row isn't touched.
|
|
269
|
+
- **Every player row must point to a real event.** Foreign keys are enforced, so saving a
|
|
270
|
+
player under an event id that doesn't exist fails.
|
|
271
|
+
- **Deleting an event deletes its players.** Player rows are removed along with their event
|
|
272
|
+
(`ON DELETE CASCADE`).
|
|
273
|
+
|
|
274
|
+
### Which function reads what
|
|
275
|
+
|
|
276
|
+
| You want… | Function | What it does |
|
|
277
|
+
|---|---|---|
|
|
278
|
+
| Save a scraped player | `savePlayer(eventId, player)` | Inserts or updates that player's row for the event and returns its `id` |
|
|
279
|
+
| An event's roster | `getPlayersByEvent('Champs')` | Every row whose `event_id` matches that event |
|
|
280
|
+
| A player's latest version | `getPlayer('tenz')` | Their row from the newest event (highest year) |
|
|
281
|
+
| Every version of a player | `getPlayerHistory('tenz')` | All their rows, newest first |
|
|
282
|
+
| One specific row | `getPlayerById(2)` | Looks a row up by `id` |
|
|
283
|
+
| Search by name | `searchPlayers('ten')` | Partial match, one result per player per event |
|
|
284
|
+
| Re-scrape an event | `emptyEvent('Champs')` | Deletes that event's players but keeps the event |
|
|
285
|
+
| Remove an event | `clearEvent('Champs')` | Deletes the event, and its players go with it |
|
|
286
|
+
|
|
287
|
+
Every player read from the database also has `event_name` and `event_year`, so you can tell
|
|
288
|
+
which event a row came from without a separate lookup.
|
|
289
|
+
|
|
290
|
+
### What happens when you scrape an event
|
|
291
|
+
|
|
292
|
+
```
|
|
293
|
+
valstats <link> <year> <event-name>
|
|
294
|
+
│
|
|
295
|
+
▼
|
|
296
|
+
Already saved with this name + year? ──yes──► emptyEvent(name)
|
|
297
|
+
│ (delete its old player rows)
|
|
298
|
+
▼ │
|
|
299
|
+
saveEvent(...) ◄─────────────────────────────────────┘
|
|
300
|
+
(create or update the event, get its id)
|
|
301
|
+
│
|
|
302
|
+
▼
|
|
303
|
+
For each player on the event page:
|
|
304
|
+
scrapePlayer(link) ──► savePlayer(eventId, player)
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Migrating older databases
|
|
308
|
+
|
|
309
|
+
Older versions stored one shared row per player and linked players to events through an
|
|
310
|
+
`event_players` table (or `tournaments` / `tournament_players` before that). These are
|
|
311
|
+
migrated automatically the first time the database is opened:
|
|
312
|
+
|
|
313
|
+
```
|
|
314
|
+
Before After
|
|
315
|
+
players: tenz players: id 1, tenz, event_id 1
|
|
316
|
+
event_players: (1, tenz), (2, tenz) ──► id 2, tenz, event_id 2
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Each player is copied into a row for every event they were linked to, and `event_players` is
|
|
320
|
+
removed. Older versions overwrote a player's stats on every scrape, so migrated rows for the
|
|
321
|
+
same player all start with the same (most recent) stats. Players who weren't linked to any
|
|
322
|
+
event are dropped.
|
|
323
|
+
|
|
324
|
+
## License
|
|
325
|
+
|
|
326
|
+
ISC
|
package/index.mjs
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
export { default as scrapePlayer } from './scripts/player-info-scraper.mjs';
|
|
2
|
-
export { scrapeWebsite } from './scripts/player-link-scraper.mjs';
|
|
3
|
-
export {
|
|
4
|
-
savePlayer,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
1
|
+
export { default as scrapePlayer } from './scripts/player-info-scraper.mjs';
|
|
2
|
+
export { scrapeWebsite } from './scripts/player-link-scraper.mjs';
|
|
3
|
+
export {
|
|
4
|
+
savePlayer,
|
|
5
|
+
getPlayerById,
|
|
6
|
+
getPlayer,
|
|
7
|
+
getPlayerHistory,
|
|
8
|
+
searchPlayers,
|
|
9
|
+
getAllPlayers,
|
|
10
|
+
getRandomPlayer,
|
|
11
|
+
saveEvent,
|
|
12
|
+
getEvents,
|
|
13
|
+
getEventByName,
|
|
14
|
+
getEventId,
|
|
15
|
+
getPlayersByEvent,
|
|
16
|
+
getRandomPlayerFromEvent,
|
|
17
|
+
emptyEvent,
|
|
18
|
+
clearEvent,
|
|
19
|
+
clearDatabase,
|
|
20
|
+
} from './scripts/db.mjs';
|