nhl-api-ts 0.0.0-stage → 0.1.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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +295 -2
  3. package/dist/api/edge.d.mts +179 -0
  4. package/dist/api/edge.mjs +184 -0
  5. package/dist/api/game-center.d.mts +83 -0
  6. package/dist/api/game-center.mjs +74 -0
  7. package/dist/api/helpers.d.mts +46 -0
  8. package/dist/api/helpers.mjs +106 -0
  9. package/dist/api/misc.d.mts +40 -0
  10. package/dist/api/misc.mjs +43 -0
  11. package/dist/api/players.d.mts +27 -0
  12. package/dist/api/players.mjs +18 -0
  13. package/dist/api/query/builder.d.mts +20 -0
  14. package/dist/api/query/builder.mjs +28 -0
  15. package/dist/api/query/errors.d.mts +3 -0
  16. package/dist/api/query/errors.mjs +6 -0
  17. package/dist/api/query/filters/base.d.mts +4 -0
  18. package/dist/api/query/filters/base.mjs +2 -0
  19. package/dist/api/query/filters/decision.d.mts +13 -0
  20. package/dist/api/query/filters/decision.mjs +26 -0
  21. package/dist/api/query/filters/draft.d.mts +15 -0
  22. package/dist/api/query/filters/draft.mjs +27 -0
  23. package/dist/api/query/filters/experience.d.mts +9 -0
  24. package/dist/api/query/filters/experience.mjs +17 -0
  25. package/dist/api/query/filters/franchise.d.mts +9 -0
  26. package/dist/api/query/filters/franchise.mjs +15 -0
  27. package/dist/api/query/filters/game-type.d.mts +10 -0
  28. package/dist/api/query/filters/game-type.mjs +16 -0
  29. package/dist/api/query/filters/goalie-sorts.d.mts +3 -0
  30. package/dist/api/query/filters/goalie-sorts.mjs +55 -0
  31. package/dist/api/query/filters/home-road.d.mts +9 -0
  32. package/dist/api/query/filters/home-road.mjs +16 -0
  33. package/dist/api/query/filters/index.d.mts +14 -0
  34. package/dist/api/query/filters/index.mjs +14 -0
  35. package/dist/api/query/filters/nationality.d.mts +12 -0
  36. package/dist/api/query/filters/nationality.mjs +19 -0
  37. package/dist/api/query/filters/opponent.d.mts +10 -0
  38. package/dist/api/query/filters/opponent.mjs +16 -0
  39. package/dist/api/query/filters/position.d.mts +16 -0
  40. package/dist/api/query/filters/position.mjs +28 -0
  41. package/dist/api/query/filters/season.d.mts +14 -0
  42. package/dist/api/query/filters/season.mjs +24 -0
  43. package/dist/api/query/filters/shoot-catch.d.mts +9 -0
  44. package/dist/api/query/filters/shoot-catch.mjs +16 -0
  45. package/dist/api/query/filters/status.d.mts +20 -0
  46. package/dist/api/query/filters/status.mjs +28 -0
  47. package/dist/api/query/filters.d.mts +93 -0
  48. package/dist/api/query/filters.mjs +118 -0
  49. package/dist/api/query/index.d.mts +4 -0
  50. package/dist/api/query/index.mjs +4 -0
  51. package/dist/api/query/sorting/goalie-sorts.d.mts +6 -0
  52. package/dist/api/query/sorting/goalie-sorts.mjs +59 -0
  53. package/dist/api/query/sorting/sorting-options.d.mts +11 -0
  54. package/dist/api/query/sorting/sorting-options.mjs +93 -0
  55. package/dist/api/schedule.d.mts +116 -0
  56. package/dist/api/schedule.mjs +131 -0
  57. package/dist/api/standings.d.mts +28 -0
  58. package/dist/api/standings.mjs +38 -0
  59. package/dist/api/stats.d.mts +148 -0
  60. package/dist/api/stats.mjs +148 -0
  61. package/dist/api/teams.d.mts +58 -0
  62. package/dist/api/teams.mjs +91 -0
  63. package/dist/cli/colors.d.mts +14 -0
  64. package/dist/cli/colors.mjs +13 -0
  65. package/dist/cli/commands.d.mts +27 -0
  66. package/dist/cli/commands.mjs +695 -0
  67. package/dist/cli/run.d.mts +9 -0
  68. package/dist/cli/run.mjs +313 -0
  69. package/dist/cli.d.mts +2 -0
  70. package/dist/cli.mjs +13 -0
  71. package/dist/config.d.mts +20 -0
  72. package/dist/config.mjs +4 -0
  73. package/dist/context.d.mts +6 -0
  74. package/dist/context.mjs +1 -0
  75. package/dist/errors.d.mts +35 -0
  76. package/dist/errors.mjs +49 -0
  77. package/dist/http-client.d.mts +27 -0
  78. package/dist/http-client.mjs +95 -0
  79. package/dist/index.d.mts +21 -0
  80. package/dist/index.mjs +15 -0
  81. package/dist/logging.d.mts +14 -0
  82. package/dist/logging.mjs +13 -0
  83. package/dist/nhl-client.d.mts +97 -0
  84. package/dist/nhl-client.mjs +40 -0
  85. package/dist/utils.d.mts +5 -0
  86. package/dist/utils.mjs +3 -0
  87. package/package.json +77 -3
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Andrew Angelle
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,296 @@
1
- # Temporary Holding Version
1
+ # nhl-api-ts
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ TypeScript SDK **and** command line tool for the NHL API and NHL EDGE stats.
4
+
5
+ Every SDK method is also available as a CLI command.
6
+
7
+ - Zero runtime dependencies (uses the built-in `fetch`)
8
+ - Node.js >= 24, ESM only
9
+ - Fully typed
10
+
11
+ ## Documentation
12
+
13
+ - [Concepts](docs/concepts.md): ID formats, the two NHL APIs, "now" redirects, pagination, retries
14
+ - [Errors](docs/errors.md): every error, its cause and the fix
15
+ - [Recipes](docs/recipes/): [filtered stats](docs/recipes/filter-skater-stats.md),
16
+ [pagination](docs/recipes/paginate-stats.md), [live scores](docs/recipes/live-scores.md),
17
+ [season-wide data](docs/recipes/season-wide-data.md), [retries](docs/recipes/retries.md),
18
+ [CLI + jq](docs/recipes/cli-and-jq.md), [testing](docs/recipes/testing.md)
19
+ - [Examples](examples/): runnable scripts
20
+ - [API report](api-report.md): the full public TypeScript API
21
+ - [OpenAPI](openapi.yaml): every HTTP path the SDK calls
22
+ - [Migration guide](MIGRATION.md): breaking changes between versions
23
+ - For LLMs and agents: [llms.txt](llms.txt), [llms-full.txt](llms-full.txt),
24
+ [Agent Skill](skills/nhl-api-ts/SKILL.md)
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ pnpm add nhl-api-ts # SDK
30
+ pnpm add -g nhl-api-ts # CLI (`nhl-api-ts` on your PATH)
31
+ # or run the CLI without installing:
32
+ npx nhl-api-ts --help
33
+ ```
34
+
35
+ ## SDK quick start
36
+
37
+ ```ts
38
+ import { createNHLClient } from 'nhl-api-ts';
39
+
40
+ const client = createNHLClient();
41
+
42
+ const teams = await client.teams.teams();
43
+ const standings = await client.standings.leagueStandings();
44
+ const games = await client.schedule.dailySchedule();
45
+ ```
46
+
47
+ Every method is `async` and takes a single options object:
48
+
49
+ ```ts
50
+ await client.gameCenter.boxscore({ gameId: '2023020280' });
51
+ await client.edge.skaterDetail({ playerId: 8478402, season: 20232024 });
52
+ await client.stats.teamSummary({ startSeason: 20202021, endSeason: 20232024 });
53
+ ```
54
+
55
+ IDs and seasons accept either strings or numbers.
56
+
57
+ ## Configuration
58
+
59
+ ```ts
60
+ const client = createNHLClient({
61
+ debug: true, // log each request URL to stderr (default false)
62
+ timeout: 30, // seconds (default 10)
63
+ followRedirects: true, // "/now" endpoints redirect to today's data (default true)
64
+ });
65
+ ```
66
+
67
+ ## API modules
68
+
69
+ All methods below live on `client.<module>`. Parameters in `[brackets]` are
70
+ optional.
71
+
72
+ ### teams
73
+
74
+ - `teams({ [date] })` — all teams with conference, division and `franchise_id`
75
+ - `teamRoster({ teamAbbr, season })`
76
+ - `franchises()`
77
+
78
+ ### standings
79
+
80
+ - `leagueStandings({ [date], [season] })` — `season` uses that season's final standings
81
+ - `seasonStandingManifest()`
82
+
83
+ ### schedule
84
+
85
+ - `dailySchedule({ [date] })` — date is validated/normalized (`2024-10-9` → `2024-10-09`)
86
+ - `weeklySchedule({ [date] })`
87
+ - `teamMonthlySchedule({ teamAbbr, [month] })`
88
+ - `teamWeeklySchedule({ teamAbbr, [date] })`
89
+ - `teamSeasonSchedule({ teamAbbr, season })`
90
+ - `calendarSchedule({ date })`
91
+ - `playoffCarousel({ season })`
92
+ - `playoffSeriesSchedule({ season, series })`
93
+ - `playoffBracket({ year })`
94
+
95
+ ### gameCenter
96
+
97
+ - `boxscore({ gameId })`
98
+ - `playByPlay({ gameId })`
99
+ - `matchUp({ gameId })`
100
+ - `dailyScores({ [date] })`
101
+ - `shiftChartData({ gameId, [excludes] })`
102
+ - `seasonSeriesMatchup({ gameId })`
103
+ - `gameStory({ gameId })`
104
+
105
+ ### stats
106
+
107
+ - `gametypesPerSeasonDirectoryByTeam({ teamAbbr })`
108
+ - `playerCareerStats({ playerId })`
109
+ - `playerGameLog({ playerId, seasonId, gameType })`
110
+ - `teamSummary({ startSeason, endSeason, [gameTypeId], [isGame], [isAggregate], [sortExpr], [start], [limit], [factCayenneExp], [defaultCayenneExp] })`
111
+ - `skaterStatsSummary({ startSeason, endSeason, [franchiseId], [gameTypeId], [aggregate], [sortExpr], [start], [limit], [factCayenneExp], [defaultCayenneExp] })`
112
+ - `skaterStatsWithQueryContext({ queryContext, reportType, [sortExpr], [aggregate], [start], [limit] })`
113
+ - `goalieStatsSummary({ startSeason, [endSeason], [statsType], [gameTypeId], [franchiseId], [aggregate], [sortExpr], [start], [limit], [factCayenneExp], [defaultCayenneExp] })`
114
+
115
+ ### edge
116
+
117
+ Every EDGE method takes `[season]` and `[gameType]` (2 = regular season, the
118
+ default; 3 = playoffs). Without `season` the current season (`/now`) is used.
119
+
120
+ - Skaters (`{ playerId }`): `skaterDetail`, `skaterShotSpeedDetail`,
121
+ `skaterSkatingSpeedDetail`, `skaterShotLocationDetail`,
122
+ `skaterSkatingDistanceDetail`, `skaterComparison`, `skaterZoneTime`,
123
+ `catSkaterDetail`
124
+ - Goalies (`{ playerId }`): `goalieDetail`, `goalieShotLocationDetail`,
125
+ `goalie5v5Detail`, `goalieComparison`, `goalieSavePercentageDetail`,
126
+ `catGoalieDetail`
127
+ - Teams (`{ teamId }`): `teamDetail`, `teamSkatingDistanceDetail`,
128
+ `teamZoneTimeDetails`, `teamShotLocationDetail`, `teamShotSpeedDetail`,
129
+ `teamSkatingSpeedDetail`
130
+ - Landing pages (no id): `skaterLanding`, `goalieLanding`, `teamLanding`
131
+
132
+ ### players
133
+
134
+ - `prospectsByTeam({ teamAbbr })`
135
+ - `playersByTeam({ teamAbbr, season })`
136
+
137
+ ### misc
138
+
139
+ - `glossary()`, `config()`, `countries()`, `seasonSpecificRulesAndInfo()`,
140
+ `draftYearAndRounds()`
141
+
142
+ ### helpers
143
+
144
+ These make one or more requests per team and sleep `apiSleepRate` seconds
145
+ between teams to avoid rate limiting.
146
+
147
+ - `gameIdsBySeason({ season, [gameTypes], [apiSleepRate] })`
148
+ - `allPlayers({ season, [apiSleepRate] })`
149
+ - `allPlayersSummaryStatistics({ season, [apiSleepRate] })`
150
+
151
+ ## Query builder
152
+
153
+ ```ts
154
+ import { createNHLClient, buildQuery, isValidQuery, filter, PositionTypes } from 'nhl-api-ts';
155
+
156
+ const client = createNHLClient();
157
+
158
+ const context = buildQuery([
159
+ filter.gameType('2'),
160
+ filter.season('20232024', '20232024'),
161
+ filter.position(PositionTypes.ALL_FORWARDS),
162
+ filter.draft('2015', '1'),
163
+ ]);
164
+
165
+ if (!isValidQuery(context)) console.error(context.errors);
166
+
167
+ const { data, total } = await client.stats.skaterStatsWithQueryContext({
168
+ queryContext: context,
169
+ reportType: 'summary',
170
+ aggregate: true,
171
+ });
172
+ ```
173
+
174
+ Available filters: `filter.decision`, `filter.draft`, `filter.experience`,
175
+ `filter.franchise`, `filter.gameType`, `filter.homeRoad`,
176
+ `filter.nationality`, `filter.opponent`, `filter.position`, `filter.season`,
177
+ `filter.shootCatch`, `filter.status`.
178
+
179
+ Skater report types: `summary`, `bios`, `faceoffpercentages`, `faceoffwins`,
180
+ `goalsForAgainst`, `realtime`, `penalties`, `penaltykill`, `penaltyShots`,
181
+ `powerplay`, `puckPossessions`, `summaryshooting`, `percentages`,
182
+ `scoringRates`, `scoringpergame`, `shootout`, `shottype`, `timeonice`.
183
+
184
+ ## Errors
185
+
186
+ HTTP failures throw exceptions that all extend `NHLApiException`, which has
187
+ `statusCode` and `errorCode`:
188
+
189
+ | Status | Exception |
190
+ | ------ | ---------------------------- |
191
+ | 400 | `BadRequestException` |
192
+ | 401 | `UnauthorizedException` |
193
+ | 404 | `ResourceNotFoundException` |
194
+ | 429 | `RateLimitExceededException` |
195
+ | 5xx | `ServerErrorException` |
196
+ | other | `NHLApiException` |
197
+
198
+ Invalid input (bad dates, unknown seasons) throws a `RangeError`.
199
+
200
+ ```ts
201
+ import { ResourceNotFoundException } from 'nhl-api-ts';
202
+
203
+ try {
204
+ await client.gameCenter.boxscore({ gameId: 1 });
205
+ } catch (err) {
206
+ if (err instanceof ResourceNotFoundException) console.log(err.statusCode); // 404
207
+ }
208
+ ```
209
+
210
+ ## CLI
211
+
212
+ ```
213
+ nhl-api-ts <module> <command> [args] [options]
214
+ ```
215
+
216
+ Modules and commands are the kebab-case names of the SDK modules and methods,
217
+ and options are the kebab-case parameter names. Required parameters can be
218
+ passed positionally, in order, or as flags. Results are printed to stdout as
219
+ JSON.
220
+
221
+ ```bash
222
+ nhl-api-ts --help # list modules
223
+ nhl-api-ts edge --help # list a module's commands
224
+ nhl-api-ts stats team-summary --help # a command's arguments and options
225
+
226
+ nhl-api-ts teams teams
227
+ nhl-api-ts schedule daily-schedule --date 2024-10-09
228
+ nhl-api-ts game-center boxscore 2023020280
229
+ nhl-api-ts game-center shift-chart-data 2023020280 --excludes eventDetails,playerStats
230
+ nhl-api-ts standings league-standings --season 20222023
231
+ nhl-api-ts edge skater-detail 8478402 --season 20232024 --game-type 3
232
+ nhl-api-ts stats team-summary 20202021 20232024 --game-type-id 3 --limit 5
233
+ nhl-api-ts stats goalie-stats-summary 20232024 --stats-type advanced
234
+ nhl-api-ts helpers game-ids-by-season 20232024 --game-types 2,3
235
+ ```
236
+
237
+ The query builder is available through filter flags on
238
+ `stats skater-stats-with-query-context`:
239
+
240
+ ```bash
241
+ nhl-api-ts stats skater-stats-with-query-context summary \
242
+ --season-start 20232024 --position F --nationality SWE --rookie --limit 10
243
+ ```
244
+
245
+ Filter flags: `--season-start`, `--season-end`, `--franchise-id`,
246
+ `--game-type`, `--position` (F/C/L/R/D), `--nationality`, `--decision`
247
+ (W/L/O), `--draft-year`, `--draft-round`, `--rookie` / `--no-rookie`,
248
+ `--home-road` (H/R), `--opponent-franchise-id`, `--shoot-catch` (L/R),
249
+ `--active`, `--hall-of-fame`.
250
+
251
+ Global options:
252
+
253
+ | Option | Description |
254
+ | ----------------------- | --------------------------------- |
255
+ | `--compact` | Print JSON on a single line |
256
+ | `--debug` | Log request URLs to stderr |
257
+ | `--timeout <seconds>` | Request timeout (default 10) |
258
+ | `--no-follow-redirects` | Do not follow HTTP redirects |
259
+ | `-v`, `--version` | Print the version |
260
+
261
+ Exit codes: `0` success, `1` API or network error, `2` invalid usage.
262
+ Progress and warning messages from `helpers` go to stderr, so stdout is always
263
+ clean JSON.
264
+
265
+ Pipe output to `jq` to slice it:
266
+
267
+ ```bash
268
+ nhl-api-ts teams teams --compact | jq -r '.[].abbr'
269
+ ```
270
+
271
+ ## Development
272
+
273
+ ```bash
274
+ pnpm install
275
+ pnpm test # node:test, runs the TypeScript sources directly
276
+ pnpm typecheck
277
+ pnpm lint:check
278
+ pnpm build # emits dist/
279
+ ```
280
+
281
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for the full set of checks, and
282
+ [AGENTS.md](AGENTS.md) for repository conventions.
283
+
284
+ Try the CLI from source:
285
+
286
+ ```bash
287
+ node --conditions=source src/cli.mts --help
288
+ ```
289
+
290
+ ## Credits
291
+
292
+ Ported from [nhl-api-py](https://github.com/coreyjs/nhl-api-py).
293
+
294
+ ## License
295
+
296
+ [MIT](LICENSE)
@@ -0,0 +1,179 @@
1
+ import type { Context } from '#src/context.mjs';
2
+ import type { Id, JsonObject } from '#src/utils.mjs';
3
+ export interface EdgeSeasonParams {
4
+ /** Season in YYYYYYYY format, e.g. 20232024. Defaults to the current season ("now"). */
5
+ season?: Id;
6
+ /** 2=Regular season (default), 3=Playoffs. Ignored when `season` is omitted. */
7
+ gameType?: number;
8
+ }
9
+ export interface EdgePlayerParams extends EdgeSeasonParams {
10
+ /** NHL player id, e.g. 8478402 */
11
+ playerId: Id;
12
+ }
13
+ export interface EdgeTeamParams extends EdgeSeasonParams {
14
+ /** NHL team id, e.g. 10 */
15
+ teamId: Id;
16
+ }
17
+ /**
18
+ * Get NHL EDGE skater detail statistics for a specific player.
19
+ *
20
+ * @example await client.edge.skaterDetail({ playerId: 8478402, season: '20232024', gameType: 2 })
21
+ */
22
+ export declare const skaterDetail: (ctx: Context, params: EdgePlayerParams) => Promise<JsonObject>;
23
+ /**
24
+ * Get NHL EDGE shot speed details for a specific skater.
25
+ *
26
+ * @example await client.edge.skaterShotSpeedDetail({ playerId: 8478402, season: '20232024', gameType: 2 })
27
+ */
28
+ export declare const skaterShotSpeedDetail: (ctx: Context, params: EdgePlayerParams) => Promise<JsonObject>;
29
+ /**
30
+ * Get NHL EDGE skating speed details for a specific skater.
31
+ *
32
+ * @example await client.edge.skaterSkatingSpeedDetail({ playerId: 8478402, season: '20232024', gameType: 2 })
33
+ */
34
+ export declare const skaterSkatingSpeedDetail: (ctx: Context, params: EdgePlayerParams) => Promise<JsonObject>;
35
+ /**
36
+ * Get NHL EDGE shot location details for a specific skater.
37
+ *
38
+ * @example await client.edge.skaterShotLocationDetail({ playerId: 8478402, season: '20232024', gameType: 2 })
39
+ */
40
+ export declare const skaterShotLocationDetail: (ctx: Context, params: EdgePlayerParams) => Promise<JsonObject>;
41
+ /**
42
+ * Get NHL EDGE skating distance details for a specific skater.
43
+ *
44
+ * @example await client.edge.skaterSkatingDistanceDetail({ playerId: 8478402, season: '20232024', gameType: 2 })
45
+ */
46
+ export declare const skaterSkatingDistanceDetail: (ctx: Context, params: EdgePlayerParams) => Promise<JsonObject>;
47
+ /**
48
+ * Get NHL EDGE comparison statistics for a specific skater.
49
+ *
50
+ * @example await client.edge.skaterComparison({ playerId: 8478402, season: '20232024', gameType: 2 })
51
+ */
52
+ export declare const skaterComparison: (ctx: Context, params: EdgePlayerParams) => Promise<JsonObject>;
53
+ /**
54
+ * Get NHL EDGE zone time details for a specific skater.
55
+ *
56
+ * @example await client.edge.skaterZoneTime({ playerId: 8478402, season: '20232024', gameType: 2 })
57
+ */
58
+ export declare const skaterZoneTime: (ctx: Context, params: EdgePlayerParams) => Promise<JsonObject>;
59
+ /**
60
+ * Get NHL EDGE skater landing page data.
61
+ *
62
+ * @example await client.edge.skaterLanding({ season: '20232024' })
63
+ */
64
+ export declare const skaterLanding: (ctx: Context, params?: EdgeSeasonParams) => Promise<JsonObject>;
65
+ /**
66
+ * Get NHL CAT (Catch All Tracking) EDGE skater details.
67
+ *
68
+ * @example await client.edge.catSkaterDetail({ playerId: 8478402, season: '20232024', gameType: 2 })
69
+ */
70
+ export declare const catSkaterDetail: (ctx: Context, params: EdgePlayerParams) => Promise<JsonObject>;
71
+ /**
72
+ * Get NHL EDGE goalie detail statistics for a specific player.
73
+ *
74
+ * @example await client.edge.goalieDetail({ playerId: 8478402, season: '20232024', gameType: 2 })
75
+ */
76
+ export declare const goalieDetail: (ctx: Context, params: EdgePlayerParams) => Promise<JsonObject>;
77
+ /**
78
+ * Get NHL EDGE shot location details for a specific goalie.
79
+ *
80
+ * @example await client.edge.goalieShotLocationDetail({ playerId: 8478402, season: '20232024', gameType: 2 })
81
+ */
82
+ export declare const goalieShotLocationDetail: (ctx: Context, params: EdgePlayerParams) => Promise<JsonObject>;
83
+ /**
84
+ * Get NHL EDGE 5v5 performance details for a specific goalie.
85
+ *
86
+ * @example await client.edge.goalie5v5Detail({ playerId: 8478402, season: '20232024', gameType: 2 })
87
+ */
88
+ export declare const goalie5v5Detail: (ctx: Context, params: EdgePlayerParams) => Promise<JsonObject>;
89
+ /**
90
+ * Get NHL EDGE comparison statistics for a specific goalie.
91
+ *
92
+ * @example await client.edge.goalieComparison({ playerId: 8478402, season: '20232024', gameType: 2 })
93
+ */
94
+ export declare const goalieComparison: (ctx: Context, params: EdgePlayerParams) => Promise<JsonObject>;
95
+ /**
96
+ * Get NHL EDGE save percentage details for a specific goalie.
97
+ *
98
+ * @example await client.edge.goalieSavePercentageDetail({ playerId: 8478402, season: '20232024', gameType: 2 })
99
+ */
100
+ export declare const goalieSavePercentageDetail: (ctx: Context, params: EdgePlayerParams) => Promise<JsonObject>;
101
+ /**
102
+ * Get NHL EDGE goalie landing page data.
103
+ *
104
+ * @example await client.edge.goalieLanding({ season: '20232024' })
105
+ */
106
+ export declare const goalieLanding: (ctx: Context, params?: EdgeSeasonParams) => Promise<JsonObject>;
107
+ /**
108
+ * Get NHL CAT (Catch All Tracking) EDGE goalie details.
109
+ *
110
+ * @example await client.edge.catGoalieDetail({ playerId: 8478402, season: '20232024', gameType: 2 })
111
+ */
112
+ export declare const catGoalieDetail: (ctx: Context, params: EdgePlayerParams) => Promise<JsonObject>;
113
+ /**
114
+ * Get NHL EDGE team detail statistics for a specific team.
115
+ *
116
+ * @example await client.edge.teamDetail({ teamId: 10 })
117
+ */
118
+ export declare const teamDetail: (ctx: Context, params: EdgeTeamParams) => Promise<JsonObject>;
119
+ /**
120
+ * Get NHL EDGE skating distance details for a specific team.
121
+ *
122
+ * @example await client.edge.teamSkatingDistanceDetail({ teamId: 10 })
123
+ */
124
+ export declare const teamSkatingDistanceDetail: (ctx: Context, params: EdgeTeamParams) => Promise<JsonObject>;
125
+ /**
126
+ * Get NHL EDGE zone time details for a specific team.
127
+ *
128
+ * @example await client.edge.teamZoneTimeDetails({ teamId: 10 })
129
+ */
130
+ export declare const teamZoneTimeDetails: (ctx: Context, params: EdgeTeamParams) => Promise<JsonObject>;
131
+ /**
132
+ * Get NHL EDGE shot location details for a specific team.
133
+ *
134
+ * @example await client.edge.teamShotLocationDetail({ teamId: 10 })
135
+ */
136
+ export declare const teamShotLocationDetail: (ctx: Context, params: EdgeTeamParams) => Promise<JsonObject>;
137
+ /**
138
+ * Get NHL EDGE team landing page data.
139
+ *
140
+ * @example await client.edge.teamLanding({ season: '20232024' })
141
+ */
142
+ export declare const teamLanding: (ctx: Context, params?: EdgeSeasonParams) => Promise<JsonObject>;
143
+ /**
144
+ * Get NHL EDGE shot speed details for a specific team.
145
+ *
146
+ * @example await client.edge.teamShotSpeedDetail({ teamId: 10 })
147
+ */
148
+ export declare const teamShotSpeedDetail: (ctx: Context, params: EdgeTeamParams) => Promise<JsonObject>;
149
+ /**
150
+ * Get NHL EDGE skating speed details for a specific team.
151
+ *
152
+ * @example await client.edge.teamSkatingSpeedDetail({ teamId: 10 })
153
+ */
154
+ export declare const teamSkatingSpeedDetail: (ctx: Context, params: EdgeTeamParams) => Promise<JsonObject>;
155
+ export declare const edgeApi: {
156
+ readonly skaterDetail: typeof skaterDetail;
157
+ readonly skaterShotSpeedDetail: typeof skaterShotSpeedDetail;
158
+ readonly skaterSkatingSpeedDetail: typeof skaterSkatingSpeedDetail;
159
+ readonly skaterShotLocationDetail: typeof skaterShotLocationDetail;
160
+ readonly skaterSkatingDistanceDetail: typeof skaterSkatingDistanceDetail;
161
+ readonly skaterComparison: typeof skaterComparison;
162
+ readonly skaterZoneTime: typeof skaterZoneTime;
163
+ readonly skaterLanding: typeof skaterLanding;
164
+ readonly catSkaterDetail: typeof catSkaterDetail;
165
+ readonly goalieDetail: typeof goalieDetail;
166
+ readonly goalieShotLocationDetail: typeof goalieShotLocationDetail;
167
+ readonly goalie5v5Detail: typeof goalie5v5Detail;
168
+ readonly goalieComparison: typeof goalieComparison;
169
+ readonly goalieSavePercentageDetail: typeof goalieSavePercentageDetail;
170
+ readonly goalieLanding: typeof goalieLanding;
171
+ readonly catGoalieDetail: typeof catGoalieDetail;
172
+ readonly teamDetail: typeof teamDetail;
173
+ readonly teamSkatingDistanceDetail: typeof teamSkatingDistanceDetail;
174
+ readonly teamZoneTimeDetails: typeof teamZoneTimeDetails;
175
+ readonly teamShotLocationDetail: typeof teamShotLocationDetail;
176
+ readonly teamLanding: typeof teamLanding;
177
+ readonly teamShotSpeedDetail: typeof teamShotSpeedDetail;
178
+ readonly teamSkatingSpeedDetail: typeof teamSkatingSpeedDetail;
179
+ };
@@ -0,0 +1,184 @@
1
+ import { Endpoint } from '#src/http-client.mjs';
2
+ /** "<path>/<id>/now" when no season is given, else "<path>/<id>/<season>/<gameType>". */
3
+ function edgeResource(path, id, { season, gameType = 2 }) {
4
+ const base = id === undefined ? path : `${path}/${id}`;
5
+ if (season === undefined || season === null) {
6
+ return `${base}/now`;
7
+ }
8
+ return `${base}/${season}/${gameType}`;
9
+ }
10
+ async function getEdge(ctx, path, id, params) {
11
+ return (await ctx.get(Endpoint.API_WEB_V1, edgeResource(path, id, params))).json();
12
+ }
13
+ // ========================
14
+ // SKATER ENDPOINTS
15
+ // ========================
16
+ /**
17
+ * Get NHL EDGE skater detail statistics for a specific player.
18
+ *
19
+ * @example await client.edge.skaterDetail({ playerId: 8478402, season: '20232024', gameType: 2 })
20
+ */
21
+ export const skaterDetail = async (ctx, params) => getEdge(ctx, 'edge/skater-detail', params.playerId, params);
22
+ /**
23
+ * Get NHL EDGE shot speed details for a specific skater.
24
+ *
25
+ * @example await client.edge.skaterShotSpeedDetail({ playerId: 8478402, season: '20232024', gameType: 2 })
26
+ */
27
+ export const skaterShotSpeedDetail = async (ctx, params) => getEdge(ctx, 'edge/skater-shot-speed-detail', params.playerId, params);
28
+ /**
29
+ * Get NHL EDGE skating speed details for a specific skater.
30
+ *
31
+ * @example await client.edge.skaterSkatingSpeedDetail({ playerId: 8478402, season: '20232024', gameType: 2 })
32
+ */
33
+ export const skaterSkatingSpeedDetail = async (ctx, params) => getEdge(ctx, 'edge/skater-skating-speed-detail', params.playerId, params);
34
+ /**
35
+ * Get NHL EDGE shot location details for a specific skater.
36
+ *
37
+ * @example await client.edge.skaterShotLocationDetail({ playerId: 8478402, season: '20232024', gameType: 2 })
38
+ */
39
+ export const skaterShotLocationDetail = async (ctx, params) => getEdge(ctx, 'edge/skater-shot-location-detail', params.playerId, params);
40
+ /**
41
+ * Get NHL EDGE skating distance details for a specific skater.
42
+ *
43
+ * @example await client.edge.skaterSkatingDistanceDetail({ playerId: 8478402, season: '20232024', gameType: 2 })
44
+ */
45
+ export const skaterSkatingDistanceDetail = async (ctx, params) => getEdge(ctx, 'edge/skater-skating-distance-detail', params.playerId, params);
46
+ /**
47
+ * Get NHL EDGE comparison statistics for a specific skater.
48
+ *
49
+ * @example await client.edge.skaterComparison({ playerId: 8478402, season: '20232024', gameType: 2 })
50
+ */
51
+ export const skaterComparison = async (ctx, params) => getEdge(ctx, 'edge/skater-comparison', params.playerId, params);
52
+ /**
53
+ * Get NHL EDGE zone time details for a specific skater.
54
+ *
55
+ * @example await client.edge.skaterZoneTime({ playerId: 8478402, season: '20232024', gameType: 2 })
56
+ */
57
+ export const skaterZoneTime = async (ctx, params) => getEdge(ctx, 'edge/skater-zone-time', params.playerId, params);
58
+ /**
59
+ * Get NHL EDGE skater landing page data.
60
+ *
61
+ * @example await client.edge.skaterLanding({ season: '20232024' })
62
+ */
63
+ export const skaterLanding = async (ctx, params = {}) => getEdge(ctx, 'edge/skater-landing', undefined, params);
64
+ /**
65
+ * Get NHL CAT (Catch All Tracking) EDGE skater details.
66
+ *
67
+ * @example await client.edge.catSkaterDetail({ playerId: 8478402, season: '20232024', gameType: 2 })
68
+ */
69
+ export const catSkaterDetail = async (ctx, params) => getEdge(ctx, 'cat/edge/skater-detail', params.playerId, params);
70
+ // ========================
71
+ // GOALIE ENDPOINTS
72
+ // ========================
73
+ /**
74
+ * Get NHL EDGE goalie detail statistics for a specific player.
75
+ *
76
+ * @example await client.edge.goalieDetail({ playerId: 8478402, season: '20232024', gameType: 2 })
77
+ */
78
+ export const goalieDetail = async (ctx, params) => getEdge(ctx, 'edge/goalie-detail', params.playerId, params);
79
+ /**
80
+ * Get NHL EDGE shot location details for a specific goalie.
81
+ *
82
+ * @example await client.edge.goalieShotLocationDetail({ playerId: 8478402, season: '20232024', gameType: 2 })
83
+ */
84
+ export const goalieShotLocationDetail = async (ctx, params) => getEdge(ctx, 'edge/goalie-shot-location-detail', params.playerId, params);
85
+ /**
86
+ * Get NHL EDGE 5v5 performance details for a specific goalie.
87
+ *
88
+ * @example await client.edge.goalie5v5Detail({ playerId: 8478402, season: '20232024', gameType: 2 })
89
+ */
90
+ export const goalie5v5Detail = async (ctx, params) => getEdge(ctx, 'edge/goalie-5v5-detail', params.playerId, params);
91
+ /**
92
+ * Get NHL EDGE comparison statistics for a specific goalie.
93
+ *
94
+ * @example await client.edge.goalieComparison({ playerId: 8478402, season: '20232024', gameType: 2 })
95
+ */
96
+ export const goalieComparison = async (ctx, params) => getEdge(ctx, 'edge/goalie-comparison', params.playerId, params);
97
+ /**
98
+ * Get NHL EDGE save percentage details for a specific goalie.
99
+ *
100
+ * @example await client.edge.goalieSavePercentageDetail({ playerId: 8478402, season: '20232024', gameType: 2 })
101
+ */
102
+ export const goalieSavePercentageDetail = async (ctx, params) => getEdge(ctx, 'edge/goalie-save-percentage-detail', params.playerId, params);
103
+ /**
104
+ * Get NHL EDGE goalie landing page data.
105
+ *
106
+ * @example await client.edge.goalieLanding({ season: '20232024' })
107
+ */
108
+ export const goalieLanding = async (ctx, params = {}) => getEdge(ctx, 'edge/goalie-landing', undefined, params);
109
+ /**
110
+ * Get NHL CAT (Catch All Tracking) EDGE goalie details.
111
+ *
112
+ * @example await client.edge.catGoalieDetail({ playerId: 8478402, season: '20232024', gameType: 2 })
113
+ */
114
+ export const catGoalieDetail = async (ctx, params) => getEdge(ctx, 'cat/edge/goalie-detail', params.playerId, params);
115
+ // ========================
116
+ // TEAM ENDPOINTS
117
+ // ========================
118
+ /**
119
+ * Get NHL EDGE team detail statistics for a specific team.
120
+ *
121
+ * @example await client.edge.teamDetail({ teamId: 10 })
122
+ */
123
+ export const teamDetail = async (ctx, params) => getEdge(ctx, 'edge/team-detail', params.teamId, params);
124
+ /**
125
+ * Get NHL EDGE skating distance details for a specific team.
126
+ *
127
+ * @example await client.edge.teamSkatingDistanceDetail({ teamId: 10 })
128
+ */
129
+ export const teamSkatingDistanceDetail = async (ctx, params) => getEdge(ctx, 'edge/team-skating-distance-detail', params.teamId, params);
130
+ /**
131
+ * Get NHL EDGE zone time details for a specific team.
132
+ *
133
+ * @example await client.edge.teamZoneTimeDetails({ teamId: 10 })
134
+ */
135
+ export const teamZoneTimeDetails = async (ctx, params) => getEdge(ctx, 'edge/team-zone-time-details', params.teamId, params);
136
+ /**
137
+ * Get NHL EDGE shot location details for a specific team.
138
+ *
139
+ * @example await client.edge.teamShotLocationDetail({ teamId: 10 })
140
+ */
141
+ export const teamShotLocationDetail = async (ctx, params) => getEdge(ctx, 'edge/team-shot-location-detail', params.teamId, params);
142
+ /**
143
+ * Get NHL EDGE team landing page data.
144
+ *
145
+ * @example await client.edge.teamLanding({ season: '20232024' })
146
+ */
147
+ export const teamLanding = async (ctx, params = {}) => getEdge(ctx, 'edge/team-landing', undefined, params);
148
+ /**
149
+ * Get NHL EDGE shot speed details for a specific team.
150
+ *
151
+ * @example await client.edge.teamShotSpeedDetail({ teamId: 10 })
152
+ */
153
+ export const teamShotSpeedDetail = async (ctx, params) => getEdge(ctx, 'edge/team-shot-speed-detail', params.teamId, params);
154
+ /**
155
+ * Get NHL EDGE skating speed details for a specific team.
156
+ *
157
+ * @example await client.edge.teamSkatingSpeedDetail({ teamId: 10 })
158
+ */
159
+ export const teamSkatingSpeedDetail = async (ctx, params) => getEdge(ctx, 'edge/team-skating-speed-detail', params.teamId, params);
160
+ export const edgeApi = {
161
+ skaterDetail,
162
+ skaterShotSpeedDetail,
163
+ skaterSkatingSpeedDetail,
164
+ skaterShotLocationDetail,
165
+ skaterSkatingDistanceDetail,
166
+ skaterComparison,
167
+ skaterZoneTime,
168
+ skaterLanding,
169
+ catSkaterDetail,
170
+ goalieDetail,
171
+ goalieShotLocationDetail,
172
+ goalie5v5Detail,
173
+ goalieComparison,
174
+ goalieSavePercentageDetail,
175
+ goalieLanding,
176
+ catGoalieDetail,
177
+ teamDetail,
178
+ teamSkatingDistanceDetail,
179
+ teamZoneTimeDetails,
180
+ teamShotLocationDetail,
181
+ teamLanding,
182
+ teamShotSpeedDetail,
183
+ teamSkatingSpeedDetail,
184
+ };