nhl-api-ts 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +315 -2
- package/dist/api/edge.d.mts +180 -0
- package/dist/api/edge.mjs +184 -0
- package/dist/api/game-center.d.mts +84 -0
- package/dist/api/game-center.mjs +74 -0
- package/dist/api/helpers.d.mts +47 -0
- package/dist/api/helpers.mjs +106 -0
- package/dist/api/misc.d.mts +40 -0
- package/dist/api/misc.mjs +43 -0
- package/dist/api/players.d.mts +28 -0
- package/dist/api/players.mjs +18 -0
- package/dist/api/query/builder.d.mts +22 -0
- package/dist/api/query/builder.mjs +30 -0
- package/dist/api/query/filters.d.mts +93 -0
- package/dist/api/query/filters.mjs +118 -0
- package/dist/api/query/index.d.mts +4 -0
- package/dist/api/query/index.mjs +4 -0
- package/dist/api/query/sorting/goalie-sorts.d.mts +61 -0
- package/dist/api/query/sorting/goalie-sorts.mjs +54 -0
- package/dist/api/query/sorting/sorting-options.d.mts +136 -0
- package/dist/api/query/sorting/sorting-options.mjs +94 -0
- package/dist/api/schedule.d.mts +117 -0
- package/dist/api/schedule.mjs +131 -0
- package/dist/api/standings.d.mts +29 -0
- package/dist/api/standings.mjs +38 -0
- package/dist/api/stats.d.mts +153 -0
- package/dist/api/stats.mjs +166 -0
- package/dist/api/teams.d.mts +59 -0
- package/dist/api/teams.mjs +91 -0
- package/dist/cli/colors.d.mts +14 -0
- package/dist/cli/colors.mjs +13 -0
- package/dist/cli/commands.d.mts +27 -0
- package/dist/cli/commands.mjs +695 -0
- package/dist/cli/run.d.mts +9 -0
- package/dist/cli/run.mjs +313 -0
- package/dist/cli.d.mts +2 -0
- package/dist/cli.mjs +13 -0
- package/dist/config.d.mts +20 -0
- package/dist/config.mjs +4 -0
- package/dist/context.d.mts +6 -0
- package/dist/context.mjs +1 -0
- package/dist/errors.d.mts +35 -0
- package/dist/errors.mjs +49 -0
- package/dist/http-client.d.mts +27 -0
- package/dist/http-client.mjs +95 -0
- package/dist/index.d.mts +22 -0
- package/dist/index.mjs +15 -0
- package/dist/nhl-client.d.mts +101 -0
- package/dist/nhl-client.mjs +40 -0
- package/dist/types/common.d.mts +81 -0
- package/dist/types/common.mjs +2 -0
- package/dist/types/edge.d.mts +1024 -0
- package/dist/types/edge.mjs +1 -0
- package/dist/types/game-center.d.mts +1194 -0
- package/dist/types/game-center.mjs +1 -0
- package/dist/types/helpers.d.mts +17 -0
- package/dist/types/helpers.mjs +1 -0
- package/dist/types/index.d.mts +10 -0
- package/dist/types/index.mjs +1 -0
- package/dist/types/misc.d.mts +68 -0
- package/dist/types/misc.mjs +2 -0
- package/dist/types/players.d.mts +42 -0
- package/dist/types/players.mjs +1 -0
- package/dist/types/schedule.d.mts +456 -0
- package/dist/types/schedule.mjs +1 -0
- package/dist/types/standings.d.mts +104 -0
- package/dist/types/standings.mjs +1 -0
- package/dist/types/stats.d.mts +1086 -0
- package/dist/types/stats.mjs +1 -0
- package/dist/types/teams.d.mts +29 -0
- package/dist/types/teams.mjs +1 -0
- package/dist/utils.d.mts +4 -0
- package/dist/utils.mjs +3 -0
- package/package.json +85 -3
|
@@ -0,0 +1,695 @@
|
|
|
1
|
+
import { buildQuery, isValidQuery } from '#src/api/query/builder.mjs';
|
|
2
|
+
import { filter } from '#src/api/query/filters.mjs';
|
|
3
|
+
import { SKATER_REPORT_TYPES } from '#src/api/query/sorting/sorting-options.mjs';
|
|
4
|
+
/** Thrown for invalid command-line input (exit code 2). */
|
|
5
|
+
export class UsageError extends Error {
|
|
6
|
+
}
|
|
7
|
+
// ---- Reusable argument specs ------------------------------------------------
|
|
8
|
+
const req = (spec) => ({ ...spec, required: true });
|
|
9
|
+
const teamAbbr = req({
|
|
10
|
+
name: 'teamAbbr',
|
|
11
|
+
type: 'string',
|
|
12
|
+
description: 'Team abbreviation, e.g. BUF, TOR',
|
|
13
|
+
});
|
|
14
|
+
const season = {
|
|
15
|
+
name: 'season',
|
|
16
|
+
type: 'string',
|
|
17
|
+
description: 'Season in YYYYYYYY format, e.g. 20232024',
|
|
18
|
+
};
|
|
19
|
+
const gameId = req({
|
|
20
|
+
name: 'gameId',
|
|
21
|
+
type: 'string',
|
|
22
|
+
description: 'Game id, e.g. 2023020280',
|
|
23
|
+
});
|
|
24
|
+
const playerId = req({
|
|
25
|
+
name: 'playerId',
|
|
26
|
+
type: 'string',
|
|
27
|
+
description: 'NHL player id, e.g. 8478402',
|
|
28
|
+
});
|
|
29
|
+
const date = (description = 'Date in YYYY-MM-DD format') => ({
|
|
30
|
+
name: 'date',
|
|
31
|
+
type: 'string',
|
|
32
|
+
description,
|
|
33
|
+
});
|
|
34
|
+
const gameTypeId = {
|
|
35
|
+
name: 'gameTypeId',
|
|
36
|
+
type: 'int',
|
|
37
|
+
description: '1=Preseason, 2=Regular season, 3=Playoffs',
|
|
38
|
+
default: '2',
|
|
39
|
+
};
|
|
40
|
+
const sortExpr = {
|
|
41
|
+
name: 'sortExpr',
|
|
42
|
+
type: 'json',
|
|
43
|
+
description: 'Sort as JSON, e.g. \'[{"property":"points","direction":"DESC"}]\'',
|
|
44
|
+
};
|
|
45
|
+
const start = {
|
|
46
|
+
name: 'start',
|
|
47
|
+
type: 'int',
|
|
48
|
+
description: 'Pagination offset',
|
|
49
|
+
default: '0',
|
|
50
|
+
};
|
|
51
|
+
const limit = (def) => ({
|
|
52
|
+
name: 'limit',
|
|
53
|
+
type: 'int',
|
|
54
|
+
description: 'Max results',
|
|
55
|
+
default: def,
|
|
56
|
+
});
|
|
57
|
+
const factCayenneExp = (def) => ({
|
|
58
|
+
name: 'factCayenneExp',
|
|
59
|
+
type: 'string',
|
|
60
|
+
description: 'Base fact filter expression',
|
|
61
|
+
default: def,
|
|
62
|
+
});
|
|
63
|
+
const defaultCayenneExp = {
|
|
64
|
+
name: 'defaultCayenneExp',
|
|
65
|
+
type: 'string',
|
|
66
|
+
description: 'Overrides the generated cayenneExp filter entirely',
|
|
67
|
+
};
|
|
68
|
+
const apiSleepRate = (def) => ({
|
|
69
|
+
name: 'apiSleepRate',
|
|
70
|
+
type: 'number',
|
|
71
|
+
description: 'Seconds to sleep between per-team requests',
|
|
72
|
+
default: def,
|
|
73
|
+
});
|
|
74
|
+
// ---- Edge -------------------------------------------------------------------
|
|
75
|
+
const edgeSeasonArgs = [
|
|
76
|
+
{ ...season, description: `${season.description}. Defaults to current` },
|
|
77
|
+
{
|
|
78
|
+
name: 'gameType',
|
|
79
|
+
type: 'int',
|
|
80
|
+
description: '2=Regular season, 3=Playoffs (only used with --season)',
|
|
81
|
+
default: '2',
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
const edgeCommand = (name, method, idKind, description) => {
|
|
85
|
+
const idArg = idKind === 'player'
|
|
86
|
+
? [playerId]
|
|
87
|
+
: idKind === 'team'
|
|
88
|
+
? [
|
|
89
|
+
req({
|
|
90
|
+
name: 'teamId',
|
|
91
|
+
type: 'string',
|
|
92
|
+
description: 'NHL team id, e.g. 10',
|
|
93
|
+
}),
|
|
94
|
+
]
|
|
95
|
+
: [];
|
|
96
|
+
return {
|
|
97
|
+
name,
|
|
98
|
+
description,
|
|
99
|
+
args: [...idArg, ...edgeSeasonArgs],
|
|
100
|
+
run: (client, values) =>
|
|
101
|
+
// biome-ignore lint/suspicious/noExplicitAny: dispatch by method name
|
|
102
|
+
client.edge[method].call(client.edge, values),
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
// ---- Stats query-context filters --------------------------------------------
|
|
106
|
+
const queryFilterArgs = [
|
|
107
|
+
{
|
|
108
|
+
name: 'seasonStart',
|
|
109
|
+
type: 'string',
|
|
110
|
+
description: 'Filter: first season, e.g. 20232024',
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: 'seasonEnd',
|
|
114
|
+
type: 'string',
|
|
115
|
+
description: 'Filter: last season (defaults to --season-start)',
|
|
116
|
+
},
|
|
117
|
+
{ name: 'franchiseId', type: 'string', description: 'Filter: franchise id' },
|
|
118
|
+
{
|
|
119
|
+
name: 'gameType',
|
|
120
|
+
type: 'string',
|
|
121
|
+
description: 'Filter: 1=Preseason, 2=Regular, 3=Playoffs',
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: 'position',
|
|
125
|
+
type: 'string',
|
|
126
|
+
description: 'Filter: F=all forwards, C, L, R, D',
|
|
127
|
+
choices: ['F', 'C', 'L', 'R', 'D'],
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: 'nationality',
|
|
131
|
+
type: 'string',
|
|
132
|
+
description: 'Filter: nationality code, e.g. CAN, USA, SWE',
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
name: 'decision',
|
|
136
|
+
type: 'string',
|
|
137
|
+
description: 'Filter: goalie decision',
|
|
138
|
+
choices: ['W', 'L', 'O'],
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: 'draftYear',
|
|
142
|
+
type: 'string',
|
|
143
|
+
description: 'Filter: draft year, e.g. 2020',
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
name: 'draftRound',
|
|
147
|
+
type: 'string',
|
|
148
|
+
description: 'Filter: draft round (requires --draft-year)',
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
name: 'rookie',
|
|
152
|
+
type: 'boolean',
|
|
153
|
+
description: 'Filter: rookies only (--no-rookie for veterans)',
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
name: 'homeRoad',
|
|
157
|
+
type: 'string',
|
|
158
|
+
description: 'Filter: home or road games',
|
|
159
|
+
choices: ['H', 'R'],
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
name: 'opponentFranchiseId',
|
|
163
|
+
type: 'string',
|
|
164
|
+
description: 'Filter: opponent franchise id',
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
name: 'shootCatch',
|
|
168
|
+
type: 'string',
|
|
169
|
+
description: 'Filter: shoots/catches',
|
|
170
|
+
choices: ['L', 'R'],
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
name: 'active',
|
|
174
|
+
type: 'boolean',
|
|
175
|
+
description: 'Filter: active players only',
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
name: 'hallOfFame',
|
|
179
|
+
type: 'boolean',
|
|
180
|
+
description: 'Filter: Hall of Fame players only',
|
|
181
|
+
},
|
|
182
|
+
];
|
|
183
|
+
// biome-ignore lint/suspicious/noExplicitAny: parsed CLI values
|
|
184
|
+
function buildQueryContext(values) {
|
|
185
|
+
const filters = [];
|
|
186
|
+
if (values.gameType !== undefined) {
|
|
187
|
+
filters.push(filter.gameType(values.gameType));
|
|
188
|
+
}
|
|
189
|
+
if (values.seasonStart !== undefined || values.seasonEnd !== undefined) {
|
|
190
|
+
const first = values.seasonStart ?? values.seasonEnd;
|
|
191
|
+
filters.push(filter.season(first, values.seasonEnd ?? first));
|
|
192
|
+
}
|
|
193
|
+
if (values.franchiseId !== undefined) {
|
|
194
|
+
filters.push(filter.franchise(values.franchiseId));
|
|
195
|
+
}
|
|
196
|
+
if (values.position !== undefined) {
|
|
197
|
+
filters.push(filter.position(values.position));
|
|
198
|
+
}
|
|
199
|
+
if (values.nationality !== undefined) {
|
|
200
|
+
filters.push(filter.nationality(values.nationality));
|
|
201
|
+
}
|
|
202
|
+
if (values.decision !== undefined) {
|
|
203
|
+
filters.push(filter.decision(values.decision));
|
|
204
|
+
}
|
|
205
|
+
if (values.draftYear !== undefined) {
|
|
206
|
+
filters.push(filter.draft(values.draftYear, values.draftRound));
|
|
207
|
+
}
|
|
208
|
+
else if (values.draftRound !== undefined) {
|
|
209
|
+
throw new UsageError('--draft-round requires --draft-year');
|
|
210
|
+
}
|
|
211
|
+
if (values.rookie !== undefined) {
|
|
212
|
+
filters.push(filter.experience(values.rookie));
|
|
213
|
+
}
|
|
214
|
+
if (values.homeRoad !== undefined) {
|
|
215
|
+
filters.push(filter.homeRoad(values.homeRoad));
|
|
216
|
+
}
|
|
217
|
+
if (values.opponentFranchiseId !== undefined) {
|
|
218
|
+
filters.push(filter.opponent(values.opponentFranchiseId));
|
|
219
|
+
}
|
|
220
|
+
if (values.shootCatch !== undefined) {
|
|
221
|
+
filters.push(filter.shootCatch(values.shootCatch));
|
|
222
|
+
}
|
|
223
|
+
if (values.active || values.hallOfFame) {
|
|
224
|
+
filters.push(filter.status({
|
|
225
|
+
isActive: values.active,
|
|
226
|
+
isHallOfFame: values.hallOfFame,
|
|
227
|
+
}));
|
|
228
|
+
}
|
|
229
|
+
const context = buildQuery(filters);
|
|
230
|
+
if (!isValidQuery(context)) {
|
|
231
|
+
throw new UsageError(`invalid filters: ${context.errors.join('; ')}`);
|
|
232
|
+
}
|
|
233
|
+
return context;
|
|
234
|
+
}
|
|
235
|
+
// ---- Registry ---------------------------------------------------------------
|
|
236
|
+
export const MODULES = [
|
|
237
|
+
{
|
|
238
|
+
name: 'teams',
|
|
239
|
+
description: 'Teams, rosters and franchises',
|
|
240
|
+
commands: [
|
|
241
|
+
{
|
|
242
|
+
name: 'teams',
|
|
243
|
+
description: 'List all NHL teams with conference, division and franchise info',
|
|
244
|
+
args: [date('Standings date in YYYY-MM-DD format. Defaults to now')],
|
|
245
|
+
run: (client, values) => client.teams.teams(values),
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
name: 'team-roster',
|
|
249
|
+
description: 'Roster for a team and season',
|
|
250
|
+
args: [teamAbbr, req(season)],
|
|
251
|
+
run: (client, values) => client.teams.teamRoster(values),
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
name: 'franchises',
|
|
255
|
+
description: 'All past and current NHL franchises',
|
|
256
|
+
args: [],
|
|
257
|
+
run: (client) => client.teams.franchises(),
|
|
258
|
+
},
|
|
259
|
+
],
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
name: 'standings',
|
|
263
|
+
description: 'League standings',
|
|
264
|
+
commands: [
|
|
265
|
+
{
|
|
266
|
+
name: 'league-standings',
|
|
267
|
+
description: 'Standings for a date, or at the end of a season (--season wins)',
|
|
268
|
+
args: [date('Date in YYYY-MM-DD format. Defaults to now'), season],
|
|
269
|
+
run: (client, values) => client.standings.leagueStandings(values),
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
name: 'season-standing-manifest',
|
|
273
|
+
description: 'Metadata (dates, rules in use) for every NHL season',
|
|
274
|
+
args: [],
|
|
275
|
+
run: (client) => client.standings.seasonStandingManifest(),
|
|
276
|
+
},
|
|
277
|
+
],
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
name: 'schedule',
|
|
281
|
+
description: 'League, team and playoff schedules',
|
|
282
|
+
commands: [
|
|
283
|
+
{
|
|
284
|
+
name: 'daily-schedule',
|
|
285
|
+
description: 'Games on a single date',
|
|
286
|
+
args: [date('Date in YYYY-MM-DD format. Defaults to today')],
|
|
287
|
+
run: (client, values) => client.schedule.dailySchedule(values),
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
name: 'weekly-schedule',
|
|
291
|
+
description: 'Games for the week starting at a date',
|
|
292
|
+
args: [date('Date in YYYY-MM-DD format. Defaults to now')],
|
|
293
|
+
run: (client, values) => client.schedule.weeklySchedule(values),
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
name: 'team-monthly-schedule',
|
|
297
|
+
description: "A team's games for a month",
|
|
298
|
+
args: [
|
|
299
|
+
teamAbbr,
|
|
300
|
+
{
|
|
301
|
+
name: 'month',
|
|
302
|
+
type: 'string',
|
|
303
|
+
description: 'Month in YYYY-MM format. Defaults to now',
|
|
304
|
+
},
|
|
305
|
+
],
|
|
306
|
+
run: (client, values) => client.schedule.teamMonthlySchedule(values),
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
name: 'team-weekly-schedule',
|
|
310
|
+
description: "A team's games for a week",
|
|
311
|
+
args: [teamAbbr, date('Date in YYYY-MM-DD format. Defaults to now')],
|
|
312
|
+
run: (client, values) => client.schedule.teamWeeklySchedule(values),
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
name: 'team-season-schedule',
|
|
316
|
+
description: "A team's full season schedule",
|
|
317
|
+
args: [teamAbbr, req(season)],
|
|
318
|
+
run: (client, values) => client.schedule.teamSeasonSchedule(values),
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
name: 'calendar-schedule',
|
|
322
|
+
description: 'Schedule in calendar format for a date',
|
|
323
|
+
args: [req(date())],
|
|
324
|
+
run: (client, values) => client.schedule.calendarSchedule(values),
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
name: 'playoff-carousel',
|
|
328
|
+
description: 'All playoff series up to the current round',
|
|
329
|
+
args: [req(season)],
|
|
330
|
+
run: (client, values) => client.schedule.playoffCarousel(values),
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
name: 'playoff-series-schedule',
|
|
334
|
+
description: 'Schedule and results for one playoff series',
|
|
335
|
+
args: [
|
|
336
|
+
req(season),
|
|
337
|
+
req({
|
|
338
|
+
name: 'series',
|
|
339
|
+
type: 'string',
|
|
340
|
+
description: 'Series letter: a-h first round ... o final',
|
|
341
|
+
}),
|
|
342
|
+
],
|
|
343
|
+
run: (client, values) => client.schedule.playoffSeriesSchedule(values),
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
name: 'playoff-bracket',
|
|
347
|
+
description: 'Full playoff bracket for a year',
|
|
348
|
+
args: [
|
|
349
|
+
req({ name: 'year', type: 'string', description: 'Year, e.g. 2024' }),
|
|
350
|
+
],
|
|
351
|
+
run: (client, values) => client.schedule.playoffBracket(values),
|
|
352
|
+
},
|
|
353
|
+
],
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
name: 'game-center',
|
|
357
|
+
description: 'Game-level data: boxscores, play-by-play, shifts',
|
|
358
|
+
commands: [
|
|
359
|
+
{
|
|
360
|
+
name: 'boxscore',
|
|
361
|
+
description: 'Full boxscore for a game',
|
|
362
|
+
args: [gameId],
|
|
363
|
+
run: (client, values) => client.gameCenter.boxscore(values),
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
name: 'play-by-play',
|
|
367
|
+
description: 'Every recorded event in a game',
|
|
368
|
+
args: [gameId],
|
|
369
|
+
run: (client, values) => client.gameCenter.playByPlay(values),
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
name: 'match-up',
|
|
373
|
+
description: 'Landing-page game summary',
|
|
374
|
+
args: [gameId],
|
|
375
|
+
run: (client, values) => client.gameCenter.matchUp(values),
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
name: 'daily-scores',
|
|
379
|
+
description: 'Scores for all games on a date',
|
|
380
|
+
args: [date('Date in YYYY-MM-DD format. Defaults to now')],
|
|
381
|
+
run: (client, values) => client.gameCenter.dailyScores(values),
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
name: 'shift-chart-data',
|
|
385
|
+
description: 'Player shift data for a game',
|
|
386
|
+
args: [
|
|
387
|
+
gameId,
|
|
388
|
+
{
|
|
389
|
+
name: 'excludes',
|
|
390
|
+
type: 'list',
|
|
391
|
+
description: 'Comma-separated fields to exclude',
|
|
392
|
+
default: 'eventDetails',
|
|
393
|
+
},
|
|
394
|
+
],
|
|
395
|
+
run: (client, values) => client.gameCenter.shiftChartData(values),
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
name: 'season-series-matchup',
|
|
399
|
+
description: 'Season series record and context for a game',
|
|
400
|
+
args: [gameId],
|
|
401
|
+
run: (client, values) => client.gameCenter.seasonSeriesMatchup(values),
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
name: 'game-story',
|
|
405
|
+
description: 'Narrative game story',
|
|
406
|
+
args: [gameId],
|
|
407
|
+
run: (client, values) => client.gameCenter.gameStory(values),
|
|
408
|
+
},
|
|
409
|
+
],
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
name: 'stats',
|
|
413
|
+
description: 'Player, team and goalie statistics',
|
|
414
|
+
commands: [
|
|
415
|
+
{
|
|
416
|
+
name: 'gametypes-per-season-directory-by-team',
|
|
417
|
+
description: 'Game types a team played each season',
|
|
418
|
+
args: [teamAbbr],
|
|
419
|
+
run: (client, values) => client.stats.gametypesPerSeasonDirectoryByTeam(values),
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
name: 'player-career-stats',
|
|
423
|
+
description: "A player's career stats and bio",
|
|
424
|
+
args: [playerId],
|
|
425
|
+
run: (client, values) => client.stats.playerCareerStats(values),
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
name: 'player-game-log',
|
|
429
|
+
description: "A player's game log for a season",
|
|
430
|
+
args: [
|
|
431
|
+
playerId,
|
|
432
|
+
req({
|
|
433
|
+
name: 'seasonId',
|
|
434
|
+
type: 'string',
|
|
435
|
+
description: 'Season in YYYYYYYY format',
|
|
436
|
+
}),
|
|
437
|
+
req({
|
|
438
|
+
name: 'gameType',
|
|
439
|
+
type: 'int',
|
|
440
|
+
description: '1=Preseason, 2=Regular, 3=Playoffs',
|
|
441
|
+
}),
|
|
442
|
+
],
|
|
443
|
+
run: (client, values) => client.stats.playerGameLog(values),
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
name: 'team-summary',
|
|
447
|
+
description: 'Team summary stats across seasons',
|
|
448
|
+
args: [
|
|
449
|
+
req({
|
|
450
|
+
name: 'startSeason',
|
|
451
|
+
type: 'string',
|
|
452
|
+
description: 'First season, e.g. 20202021',
|
|
453
|
+
}),
|
|
454
|
+
req({
|
|
455
|
+
name: 'endSeason',
|
|
456
|
+
type: 'string',
|
|
457
|
+
description: 'Last season, e.g. 20232024',
|
|
458
|
+
}),
|
|
459
|
+
gameTypeId,
|
|
460
|
+
{
|
|
461
|
+
name: 'isGame',
|
|
462
|
+
type: 'boolean',
|
|
463
|
+
description: 'Game-level rather than season-level stats',
|
|
464
|
+
},
|
|
465
|
+
{
|
|
466
|
+
name: 'isAggregate',
|
|
467
|
+
type: 'boolean',
|
|
468
|
+
description: 'Aggregate across seasons',
|
|
469
|
+
},
|
|
470
|
+
sortExpr,
|
|
471
|
+
start,
|
|
472
|
+
limit('50'),
|
|
473
|
+
factCayenneExp('gamesPlayed>1'),
|
|
474
|
+
defaultCayenneExp,
|
|
475
|
+
],
|
|
476
|
+
run: (client, values) => client.stats.teamSummary(values),
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
name: 'skater-stats-summary',
|
|
480
|
+
description: 'Skater summary stats across seasons',
|
|
481
|
+
args: [
|
|
482
|
+
req({
|
|
483
|
+
name: 'startSeason',
|
|
484
|
+
type: 'string',
|
|
485
|
+
description: 'First season, e.g. 20232024',
|
|
486
|
+
}),
|
|
487
|
+
req({
|
|
488
|
+
name: 'endSeason',
|
|
489
|
+
type: 'string',
|
|
490
|
+
description: 'Last season, e.g. 20232024',
|
|
491
|
+
}),
|
|
492
|
+
{
|
|
493
|
+
name: 'franchiseId',
|
|
494
|
+
type: 'string',
|
|
495
|
+
description: 'Limit to a franchise',
|
|
496
|
+
},
|
|
497
|
+
gameTypeId,
|
|
498
|
+
{
|
|
499
|
+
name: 'aggregate',
|
|
500
|
+
type: 'boolean',
|
|
501
|
+
description: 'Aggregate across seasons',
|
|
502
|
+
},
|
|
503
|
+
sortExpr,
|
|
504
|
+
start,
|
|
505
|
+
limit('25'),
|
|
506
|
+
factCayenneExp('gamesPlayed>=1'),
|
|
507
|
+
defaultCayenneExp,
|
|
508
|
+
],
|
|
509
|
+
run: (client, values) => client.stats.skaterStatsSummary(values),
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
name: 'skater-stats-with-query-context',
|
|
513
|
+
description: 'Skater stats for any report type, filtered with query-builder filters',
|
|
514
|
+
args: [
|
|
515
|
+
req({
|
|
516
|
+
name: 'reportType',
|
|
517
|
+
type: 'string',
|
|
518
|
+
description: `Report type: ${SKATER_REPORT_TYPES.join(', ')}`,
|
|
519
|
+
}),
|
|
520
|
+
...queryFilterArgs,
|
|
521
|
+
sortExpr,
|
|
522
|
+
{
|
|
523
|
+
name: 'aggregate',
|
|
524
|
+
type: 'boolean',
|
|
525
|
+
description: 'Aggregate across seasons',
|
|
526
|
+
},
|
|
527
|
+
start,
|
|
528
|
+
limit('25'),
|
|
529
|
+
],
|
|
530
|
+
run: (client, values) => client.stats.skaterStatsWithQueryContext({
|
|
531
|
+
queryContext: buildQueryContext(values),
|
|
532
|
+
reportType: values.reportType,
|
|
533
|
+
sortExpr: values.sortExpr,
|
|
534
|
+
aggregate: values.aggregate,
|
|
535
|
+
start: values.start,
|
|
536
|
+
limit: values.limit,
|
|
537
|
+
}),
|
|
538
|
+
},
|
|
539
|
+
{
|
|
540
|
+
name: 'goalie-stats-summary',
|
|
541
|
+
description: 'Goalie stats for a report type across seasons',
|
|
542
|
+
args: [
|
|
543
|
+
req({
|
|
544
|
+
name: 'startSeason',
|
|
545
|
+
type: 'string',
|
|
546
|
+
description: 'First season, e.g. 20232024',
|
|
547
|
+
}),
|
|
548
|
+
{
|
|
549
|
+
name: 'endSeason',
|
|
550
|
+
type: 'string',
|
|
551
|
+
description: 'Last season (defaults to --start-season)',
|
|
552
|
+
},
|
|
553
|
+
{
|
|
554
|
+
name: 'statsType',
|
|
555
|
+
type: 'string',
|
|
556
|
+
description: 'Report type: summary, advanced, bios, daysrest, penaltyShots, savesByStrength, shootout, startedVsRelieved',
|
|
557
|
+
default: 'summary',
|
|
558
|
+
},
|
|
559
|
+
gameTypeId,
|
|
560
|
+
{
|
|
561
|
+
name: 'franchiseId',
|
|
562
|
+
type: 'string',
|
|
563
|
+
description: 'Limit to a franchise',
|
|
564
|
+
},
|
|
565
|
+
{
|
|
566
|
+
name: 'aggregate',
|
|
567
|
+
type: 'boolean',
|
|
568
|
+
description: 'Aggregate across seasons',
|
|
569
|
+
},
|
|
570
|
+
sortExpr,
|
|
571
|
+
start,
|
|
572
|
+
limit('25'),
|
|
573
|
+
factCayenneExp(),
|
|
574
|
+
defaultCayenneExp,
|
|
575
|
+
],
|
|
576
|
+
run: (client, values) => client.stats.goalieStatsSummary(values),
|
|
577
|
+
},
|
|
578
|
+
],
|
|
579
|
+
},
|
|
580
|
+
{
|
|
581
|
+
name: 'edge',
|
|
582
|
+
description: 'NHL EDGE puck and player tracking stats',
|
|
583
|
+
commands: [
|
|
584
|
+
edgeCommand('skater-detail', 'skaterDetail', 'player', 'EDGE skater detail stats'),
|
|
585
|
+
edgeCommand('skater-shot-speed-detail', 'skaterShotSpeedDetail', 'player', 'EDGE skater shot speed'),
|
|
586
|
+
edgeCommand('skater-skating-speed-detail', 'skaterSkatingSpeedDetail', 'player', 'EDGE skater skating speed'),
|
|
587
|
+
edgeCommand('skater-shot-location-detail', 'skaterShotLocationDetail', 'player', 'EDGE skater shot locations'),
|
|
588
|
+
edgeCommand('skater-skating-distance-detail', 'skaterSkatingDistanceDetail', 'player', 'EDGE skater skating distance'),
|
|
589
|
+
edgeCommand('skater-comparison', 'skaterComparison', 'player', 'EDGE skater comparison stats'),
|
|
590
|
+
edgeCommand('skater-zone-time', 'skaterZoneTime', 'player', 'EDGE skater zone time'),
|
|
591
|
+
edgeCommand('skater-landing', 'skaterLanding', 'none', 'EDGE skater landing page (league leaders)'),
|
|
592
|
+
edgeCommand('cat-skater-detail', 'catSkaterDetail', 'player', 'CAT (Catch All Tracking) skater detail'),
|
|
593
|
+
edgeCommand('goalie-detail', 'goalieDetail', 'player', 'EDGE goalie detail stats'),
|
|
594
|
+
edgeCommand('goalie-shot-location-detail', 'goalieShotLocationDetail', 'player', 'EDGE goalie shot locations'),
|
|
595
|
+
edgeCommand('goalie-5v5-detail', 'goalie5v5Detail', 'player', 'EDGE goalie 5v5 performance'),
|
|
596
|
+
edgeCommand('goalie-comparison', 'goalieComparison', 'player', 'EDGE goalie comparison stats'),
|
|
597
|
+
edgeCommand('goalie-save-percentage-detail', 'goalieSavePercentageDetail', 'player', 'EDGE goalie save percentage'),
|
|
598
|
+
edgeCommand('goalie-landing', 'goalieLanding', 'none', 'EDGE goalie landing page (league leaders)'),
|
|
599
|
+
edgeCommand('cat-goalie-detail', 'catGoalieDetail', 'player', 'CAT (Catch All Tracking) goalie detail'),
|
|
600
|
+
edgeCommand('team-detail', 'teamDetail', 'team', 'EDGE team detail stats'),
|
|
601
|
+
edgeCommand('team-skating-distance-detail', 'teamSkatingDistanceDetail', 'team', 'EDGE team skating distance'),
|
|
602
|
+
edgeCommand('team-zone-time-details', 'teamZoneTimeDetails', 'team', 'EDGE team zone time'),
|
|
603
|
+
edgeCommand('team-shot-location-detail', 'teamShotLocationDetail', 'team', 'EDGE team shot locations'),
|
|
604
|
+
edgeCommand('team-landing', 'teamLanding', 'none', 'EDGE team landing page (league leaders)'),
|
|
605
|
+
edgeCommand('team-shot-speed-detail', 'teamShotSpeedDetail', 'team', 'EDGE team shot speed'),
|
|
606
|
+
edgeCommand('team-skating-speed-detail', 'teamSkatingSpeedDetail', 'team', 'EDGE team skating speed'),
|
|
607
|
+
],
|
|
608
|
+
},
|
|
609
|
+
{
|
|
610
|
+
name: 'players',
|
|
611
|
+
description: 'Prospects and team rosters',
|
|
612
|
+
commands: [
|
|
613
|
+
{
|
|
614
|
+
name: 'prospects-by-team',
|
|
615
|
+
description: "A team's prospects grouped by position",
|
|
616
|
+
args: [teamAbbr],
|
|
617
|
+
run: (client, values) => client.players.prospectsByTeam(values),
|
|
618
|
+
},
|
|
619
|
+
{
|
|
620
|
+
name: 'players-by-team',
|
|
621
|
+
description: "A team's roster for a season",
|
|
622
|
+
args: [teamAbbr, req(season)],
|
|
623
|
+
run: (client, values) => client.players.playersByTeam(values),
|
|
624
|
+
},
|
|
625
|
+
],
|
|
626
|
+
},
|
|
627
|
+
{
|
|
628
|
+
name: 'misc',
|
|
629
|
+
description: 'Glossary, countries, config and other reference data',
|
|
630
|
+
commands: [
|
|
631
|
+
{
|
|
632
|
+
name: 'glossary',
|
|
633
|
+
description: 'Glossary of stat terms',
|
|
634
|
+
args: [],
|
|
635
|
+
run: (client) => client.misc.glossary(),
|
|
636
|
+
},
|
|
637
|
+
{
|
|
638
|
+
name: 'config',
|
|
639
|
+
description: 'Stats API configuration (report types, filters)',
|
|
640
|
+
args: [],
|
|
641
|
+
run: (client) => client.misc.config(),
|
|
642
|
+
},
|
|
643
|
+
{
|
|
644
|
+
name: 'countries',
|
|
645
|
+
description: 'Countries recognized by the NHL',
|
|
646
|
+
args: [],
|
|
647
|
+
run: (client) => client.misc.countries(),
|
|
648
|
+
},
|
|
649
|
+
{
|
|
650
|
+
name: 'season-specific-rules-and-info',
|
|
651
|
+
description: 'Rules and metadata for every season',
|
|
652
|
+
args: [],
|
|
653
|
+
run: (client) => client.misc.seasonSpecificRulesAndInfo(),
|
|
654
|
+
},
|
|
655
|
+
{
|
|
656
|
+
name: 'draft-year-and-rounds',
|
|
657
|
+
description: 'Number of rounds for each draft year',
|
|
658
|
+
args: [],
|
|
659
|
+
run: (client) => client.misc.draftYearAndRounds(),
|
|
660
|
+
},
|
|
661
|
+
],
|
|
662
|
+
},
|
|
663
|
+
{
|
|
664
|
+
name: 'helpers',
|
|
665
|
+
description: 'Multi-request convenience methods (slow; rate limited)',
|
|
666
|
+
commands: [
|
|
667
|
+
{
|
|
668
|
+
name: 'game-ids-by-season',
|
|
669
|
+
description: 'All game ids in a season (via every team schedule)',
|
|
670
|
+
args: [
|
|
671
|
+
req(season),
|
|
672
|
+
{
|
|
673
|
+
name: 'gameTypes',
|
|
674
|
+
type: 'int-list',
|
|
675
|
+
description: 'Comma-separated game types to include, e.g. 2,3',
|
|
676
|
+
},
|
|
677
|
+
apiSleepRate('1'),
|
|
678
|
+
],
|
|
679
|
+
run: (client, values) => client.helpers.gameIdsBySeason(values),
|
|
680
|
+
},
|
|
681
|
+
{
|
|
682
|
+
name: 'all-players',
|
|
683
|
+
description: 'Every rostered player in a season',
|
|
684
|
+
args: [req(season), apiSleepRate('0.5')],
|
|
685
|
+
run: (client, values) => client.helpers.allPlayers(values),
|
|
686
|
+
},
|
|
687
|
+
{
|
|
688
|
+
name: 'all-players-summary-statistics',
|
|
689
|
+
description: 'Summary stats for every skater in a season, merged with roster info',
|
|
690
|
+
args: [req(season), apiSleepRate('1')],
|
|
691
|
+
run: (client, values) => client.helpers.allPlayersSummaryStatistics(values),
|
|
692
|
+
},
|
|
693
|
+
],
|
|
694
|
+
},
|
|
695
|
+
];
|