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.
Files changed (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +315 -2
  3. package/dist/api/edge.d.mts +180 -0
  4. package/dist/api/edge.mjs +184 -0
  5. package/dist/api/game-center.d.mts +84 -0
  6. package/dist/api/game-center.mjs +74 -0
  7. package/dist/api/helpers.d.mts +47 -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 +28 -0
  12. package/dist/api/players.mjs +18 -0
  13. package/dist/api/query/builder.d.mts +22 -0
  14. package/dist/api/query/builder.mjs +30 -0
  15. package/dist/api/query/filters.d.mts +93 -0
  16. package/dist/api/query/filters.mjs +118 -0
  17. package/dist/api/query/index.d.mts +4 -0
  18. package/dist/api/query/index.mjs +4 -0
  19. package/dist/api/query/sorting/goalie-sorts.d.mts +61 -0
  20. package/dist/api/query/sorting/goalie-sorts.mjs +54 -0
  21. package/dist/api/query/sorting/sorting-options.d.mts +136 -0
  22. package/dist/api/query/sorting/sorting-options.mjs +94 -0
  23. package/dist/api/schedule.d.mts +117 -0
  24. package/dist/api/schedule.mjs +131 -0
  25. package/dist/api/standings.d.mts +29 -0
  26. package/dist/api/standings.mjs +38 -0
  27. package/dist/api/stats.d.mts +153 -0
  28. package/dist/api/stats.mjs +166 -0
  29. package/dist/api/teams.d.mts +59 -0
  30. package/dist/api/teams.mjs +91 -0
  31. package/dist/cli/colors.d.mts +14 -0
  32. package/dist/cli/colors.mjs +13 -0
  33. package/dist/cli/commands.d.mts +27 -0
  34. package/dist/cli/commands.mjs +695 -0
  35. package/dist/cli/run.d.mts +9 -0
  36. package/dist/cli/run.mjs +313 -0
  37. package/dist/cli.d.mts +2 -0
  38. package/dist/cli.mjs +13 -0
  39. package/dist/config.d.mts +20 -0
  40. package/dist/config.mjs +4 -0
  41. package/dist/context.d.mts +6 -0
  42. package/dist/context.mjs +1 -0
  43. package/dist/errors.d.mts +35 -0
  44. package/dist/errors.mjs +49 -0
  45. package/dist/http-client.d.mts +27 -0
  46. package/dist/http-client.mjs +95 -0
  47. package/dist/index.d.mts +22 -0
  48. package/dist/index.mjs +15 -0
  49. package/dist/nhl-client.d.mts +101 -0
  50. package/dist/nhl-client.mjs +40 -0
  51. package/dist/types/common.d.mts +81 -0
  52. package/dist/types/common.mjs +2 -0
  53. package/dist/types/edge.d.mts +1024 -0
  54. package/dist/types/edge.mjs +1 -0
  55. package/dist/types/game-center.d.mts +1194 -0
  56. package/dist/types/game-center.mjs +1 -0
  57. package/dist/types/helpers.d.mts +17 -0
  58. package/dist/types/helpers.mjs +1 -0
  59. package/dist/types/index.d.mts +10 -0
  60. package/dist/types/index.mjs +1 -0
  61. package/dist/types/misc.d.mts +68 -0
  62. package/dist/types/misc.mjs +2 -0
  63. package/dist/types/players.d.mts +42 -0
  64. package/dist/types/players.mjs +1 -0
  65. package/dist/types/schedule.d.mts +456 -0
  66. package/dist/types/schedule.mjs +1 -0
  67. package/dist/types/standings.d.mts +104 -0
  68. package/dist/types/standings.mjs +1 -0
  69. package/dist/types/stats.d.mts +1086 -0
  70. package/dist/types/stats.mjs +1 -0
  71. package/dist/types/teams.d.mts +29 -0
  72. package/dist/types/teams.mjs +1 -0
  73. package/dist/utils.d.mts +4 -0
  74. package/dist/utils.mjs +3 -0
  75. package/package.json +85 -3
@@ -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
+ };
@@ -0,0 +1,84 @@
1
+ import type { Context } from '#src/context.mjs';
2
+ import type { Boxscore, DailyScores, GameLanding, GameStory, PlayByPlay, RightRail, ShiftChart } from '#src/types/index.mjs';
3
+ import type { Id } from '#src/utils.mjs';
4
+ /**
5
+ * Get the full boxscore for a specific NHL game, including team scores,
6
+ * shots on goal, and per-player stats.
7
+ *
8
+ * @param params.gameId Game id, e.g. 2023020280
9
+ * @example https://api-web.nhle.com/v1/gamecenter/2023020280/boxscore
10
+ */
11
+ export declare const boxscore: (ctx: Context, { gameId }: {
12
+ gameId: Id;
13
+ }) => Promise<Boxscore>;
14
+ /**
15
+ * Get the full play-by-play feed for a specific NHL game, containing every
16
+ * recorded event (shots, hits, faceoffs, goals, penalties...).
17
+ *
18
+ * @param params.gameId Game id, e.g. 2023020280
19
+ * @example https://api-web.nhle.com/v1/gamecenter/2023020280/play-by-play
20
+ */
21
+ export declare const playByPlay: (ctx: Context, { gameId }: {
22
+ gameId: Id;
23
+ }) => Promise<PlayByPlay>;
24
+ /**
25
+ * Get the landing-page summary for a specific NHL game, including scoring by
26
+ * period, three stars and penalties.
27
+ *
28
+ * @param params.gameId Game id, e.g. 2023020280
29
+ * @example https://api-web.nhle.com/v1/gamecenter/2023020280/landing
30
+ */
31
+ export declare const matchUp: (ctx: Context, { gameId }: {
32
+ gameId: Id;
33
+ }) => Promise<GameLanding>;
34
+ /**
35
+ * Get scores and game states for all NHL games on a given date. Returns the
36
+ * current day's scores when no date is supplied.
37
+ *
38
+ * @param params.date Date in YYYY-MM-DD format. Defaults to "now".
39
+ * @example https://api-web.nhle.com/v1/score/2023-10-15
40
+ */
41
+ export declare const dailyScores: (ctx: Context, { date }?: {
42
+ date?: string;
43
+ }) => Promise<DailyScores>;
44
+ /**
45
+ * Get individual player shift data for a specific game, including start/end
46
+ * times and durations.
47
+ *
48
+ * @param params.gameId Game id, e.g. 2023020280
49
+ * @param params.excludes Fields to exclude from the response. Defaults to ["eventDetails"].
50
+ * @example https://api.nhle.com/stats/rest/en/shiftcharts?cayenneExp=gameId=2023020280 and ...
51
+ */
52
+ export declare const shiftChartData: (ctx: Context, { gameId, excludes }: {
53
+ gameId: Id;
54
+ excludes?: string[];
55
+ }) => Promise<ShiftChart>;
56
+ /**
57
+ * Get the season-series record and contextual stats for a specific game,
58
+ * including team season stats and last games.
59
+ *
60
+ * @param params.gameId Game id, e.g. 2023020280
61
+ * @example https://api-web.nhle.com/v1/gamecenter/2023020280/right-rail
62
+ */
63
+ export declare const seasonSeriesMatchup: (ctx: Context, { gameId }: {
64
+ gameId: Id;
65
+ }) => Promise<RightRail>;
66
+ /**
67
+ * Get the narrative game story for a specific game, including scoring
68
+ * summaries, three stars and team game stats.
69
+ *
70
+ * @param params.gameId Game id, e.g. 2023020280
71
+ * @example https://api-web.nhle.com/v1/wsc/game-story/2023020280
72
+ */
73
+ export declare const gameStory: (ctx: Context, { gameId }: {
74
+ gameId: Id;
75
+ }) => Promise<GameStory>;
76
+ export declare const gameCenterApi: {
77
+ readonly boxscore: typeof boxscore;
78
+ readonly playByPlay: typeof playByPlay;
79
+ readonly matchUp: typeof matchUp;
80
+ readonly dailyScores: typeof dailyScores;
81
+ readonly shiftChartData: typeof shiftChartData;
82
+ readonly seasonSeriesMatchup: typeof seasonSeriesMatchup;
83
+ readonly gameStory: typeof gameStory;
84
+ };
@@ -0,0 +1,74 @@
1
+ import { Endpoint } from '#src/http-client.mjs';
2
+ async function getWeb(ctx, resource) {
3
+ return (await ctx.get(Endpoint.API_WEB_V1, resource)).json();
4
+ }
5
+ /**
6
+ * Get the full boxscore for a specific NHL game, including team scores,
7
+ * shots on goal, and per-player stats.
8
+ *
9
+ * @param params.gameId Game id, e.g. 2023020280
10
+ * @example https://api-web.nhle.com/v1/gamecenter/2023020280/boxscore
11
+ */
12
+ export const boxscore = async (ctx, { gameId }) => getWeb(ctx, `gamecenter/${gameId}/boxscore`);
13
+ /**
14
+ * Get the full play-by-play feed for a specific NHL game, containing every
15
+ * recorded event (shots, hits, faceoffs, goals, penalties...).
16
+ *
17
+ * @param params.gameId Game id, e.g. 2023020280
18
+ * @example https://api-web.nhle.com/v1/gamecenter/2023020280/play-by-play
19
+ */
20
+ export const playByPlay = async (ctx, { gameId }) => getWeb(ctx, `gamecenter/${gameId}/play-by-play`);
21
+ /**
22
+ * Get the landing-page summary for a specific NHL game, including scoring by
23
+ * period, three stars and penalties.
24
+ *
25
+ * @param params.gameId Game id, e.g. 2023020280
26
+ * @example https://api-web.nhle.com/v1/gamecenter/2023020280/landing
27
+ */
28
+ export const matchUp = async (ctx, { gameId }) => getWeb(ctx, `gamecenter/${gameId}/landing`);
29
+ /**
30
+ * Get scores and game states for all NHL games on a given date. Returns the
31
+ * current day's scores when no date is supplied.
32
+ *
33
+ * @param params.date Date in YYYY-MM-DD format. Defaults to "now".
34
+ * @example https://api-web.nhle.com/v1/score/2023-10-15
35
+ */
36
+ export const dailyScores = async (ctx, { date } = {}) => getWeb(ctx, `score/${date ? date : 'now'}`);
37
+ /**
38
+ * Get individual player shift data for a specific game, including start/end
39
+ * times and durations.
40
+ *
41
+ * @param params.gameId Game id, e.g. 2023020280
42
+ * @param params.excludes Fields to exclude from the response. Defaults to ["eventDetails"].
43
+ * @example https://api.nhle.com/stats/rest/en/shiftcharts?cayenneExp=gameId=2023020280 and ...
44
+ */
45
+ export const shiftChartData = async (ctx, { gameId, excludes = ['eventDetails'] }) => {
46
+ const excludeP = excludes.join(',');
47
+ const exprP = `gameId=${gameId} and ((duration != '00:00' and typeCode = 517) or typeCode != 517 )`;
48
+ return (await ctx.get(Endpoint.API_STATS, `en/shiftcharts?cayenneExp=${exprP}&exclude=${excludeP}`)).json();
49
+ };
50
+ /**
51
+ * Get the season-series record and contextual stats for a specific game,
52
+ * including team season stats and last games.
53
+ *
54
+ * @param params.gameId Game id, e.g. 2023020280
55
+ * @example https://api-web.nhle.com/v1/gamecenter/2023020280/right-rail
56
+ */
57
+ export const seasonSeriesMatchup = async (ctx, { gameId }) => getWeb(ctx, `gamecenter/${gameId}/right-rail`);
58
+ /**
59
+ * Get the narrative game story for a specific game, including scoring
60
+ * summaries, three stars and team game stats.
61
+ *
62
+ * @param params.gameId Game id, e.g. 2023020280
63
+ * @example https://api-web.nhle.com/v1/wsc/game-story/2023020280
64
+ */
65
+ export const gameStory = async (ctx, { gameId }) => getWeb(ctx, `wsc/game-story/${gameId}`);
66
+ export const gameCenterApi = {
67
+ boxscore,
68
+ playByPlay,
69
+ matchUp,
70
+ dailyScores,
71
+ shiftChartData,
72
+ seasonSeriesMatchup,
73
+ gameStory,
74
+ };
@@ -0,0 +1,47 @@
1
+ import type { Context } from '#src/context.mjs';
2
+ import type { AllPlayersEntry, PlayerSummaryStatistics } from '#src/types/index.mjs';
3
+ import type { Id } from '#src/utils.mjs';
4
+ /**
5
+ * Gets all game IDs for a specified season by querying every team's
6
+ * schedule. Games appear once per participating team, so ids may repeat.
7
+ *
8
+ * @param params.season Season in YYYYYYYY format, e.g. 20232024
9
+ * @param params.gameTypes Only include these game types (1=Preseason, 2=Regular, 3=Playoffs). Defaults to all.
10
+ * @param params.apiSleepRate Seconds to sleep between team requests. Defaults to 1.
11
+ * @example await client.helpers.gameIdsBySeason({ season: '20232024', gameTypes: [2] })
12
+ */
13
+ export declare const gameIdsBySeason: (ctx: Context, { season, gameTypes, apiSleepRate, }: {
14
+ season: Id;
15
+ gameTypes?: number[];
16
+ apiSleepRate?: number;
17
+ }) => Promise<number[]>;
18
+ /**
19
+ * Gets every rostered player across all NHL teams for a given season. Each
20
+ * player gets a `team` abbreviation and flattened `firstName` / `lastName`.
21
+ *
22
+ * @param params.season Season in YYYYYYYY format, e.g. 20232024
23
+ * @param params.apiSleepRate Seconds to sleep between team requests. Defaults to 0.5.
24
+ * @example await client.helpers.allPlayers({ season: '20232024' })
25
+ */
26
+ export declare const allPlayers: (ctx: Context, { season, apiSleepRate }: {
27
+ season: Id;
28
+ apiSleepRate?: number;
29
+ }) => Promise<AllPlayersEntry[]>;
30
+ /**
31
+ * Gets summary statistics for every skater in a given season, merged with
32
+ * the roster info from `allPlayers` (stat fields win on key collisions).
33
+ * Stat entries without a matching rostered player are included as-is.
34
+ *
35
+ * @param params.season Season in YYYYYYYY format, e.g. 20232024
36
+ * @param params.apiSleepRate Seconds to sleep between team requests. Defaults to 1.
37
+ * @example await client.helpers.allPlayersSummaryStatistics({ season: '20232024' })
38
+ */
39
+ export declare const allPlayersSummaryStatistics: (ctx: Context, { season, apiSleepRate }: {
40
+ season: Id;
41
+ apiSleepRate?: number;
42
+ }) => Promise<PlayerSummaryStatistics[]>;
43
+ export declare const helpersApi: {
44
+ readonly gameIdsBySeason: typeof gameIdsBySeason;
45
+ readonly allPlayers: typeof allPlayers;
46
+ readonly allPlayersSummaryStatistics: typeof allPlayersSummaryStatistics;
47
+ };
@@ -0,0 +1,106 @@
1
+ import { buildQuery } from '#src/api/query/builder.mjs';
2
+ import { filter } from '#src/api/query/filters.mjs';
3
+ import { teamSeasonSchedule } from '#src/api/schedule.mjs';
4
+ import { skaterStatsWithQueryContext } from '#src/api/stats.mjs';
5
+ import { teams as fetchTeams, teamRoster } from '#src/api/teams.mjs';
6
+ /**
7
+ * Gets all game IDs for a specified season by querying every team's
8
+ * schedule. Games appear once per participating team, so ids may repeat.
9
+ *
10
+ * @param params.season Season in YYYYYYYY format, e.g. 20232024
11
+ * @param params.gameTypes Only include these game types (1=Preseason, 2=Regular, 3=Playoffs). Defaults to all.
12
+ * @param params.apiSleepRate Seconds to sleep between team requests. Defaults to 1.
13
+ * @example await client.helpers.gameIdsBySeason({ season: '20232024', gameTypes: [2] })
14
+ */
15
+ export const gameIdsBySeason = async (ctx, { season, gameTypes, apiSleepRate = 1, }) => {
16
+ const teams = await fetchTeams(ctx);
17
+ const gameIds = [];
18
+ for (const team of teams) {
19
+ const teamAbbr = team.abbr ?? '';
20
+ if (!teamAbbr) {
21
+ continue;
22
+ }
23
+ await ctx.sleep(apiSleepRate);
24
+ const schedule = await teamSeasonSchedule(ctx, { teamAbbr, season });
25
+ const games = schedule.games ?? [];
26
+ for (const game of games) {
27
+ const gameType = game.gameType;
28
+ const gameId = game.id;
29
+ if (gameId &&
30
+ (!gameTypes || gameTypes.length === 0 || gameTypes.includes(gameType))) {
31
+ gameIds.push(gameId);
32
+ }
33
+ }
34
+ }
35
+ return gameIds;
36
+ };
37
+ /**
38
+ * Gets every rostered player across all NHL teams for a given season. Each
39
+ * player gets a `team` abbreviation and flattened `firstName` / `lastName`.
40
+ *
41
+ * @param params.season Season in YYYYYYYY format, e.g. 20232024
42
+ * @param params.apiSleepRate Seconds to sleep between team requests. Defaults to 0.5.
43
+ * @example await client.helpers.allPlayers({ season: '20232024' })
44
+ */
45
+ export const allPlayers = async (ctx, { season, apiSleepRate = 0.5 }) => {
46
+ const teams = await fetchTeams(ctx);
47
+ console.error('Fetching all player base stats. This may take a while...');
48
+ const outData = [];
49
+ for (const team of teams) {
50
+ await ctx.sleep(apiSleepRate);
51
+ const players = await teamRoster(ctx, { teamAbbr: team.abbr, season });
52
+ for (const player of [
53
+ ...players.forwards,
54
+ ...players.defensemen,
55
+ ...players.goalies,
56
+ ]) {
57
+ outData.push({
58
+ ...player,
59
+ team: team.abbr,
60
+ firstName: player.firstName.default,
61
+ lastName: player.lastName.default,
62
+ });
63
+ }
64
+ }
65
+ return outData;
66
+ };
67
+ /**
68
+ * Gets summary statistics for every skater in a given season, merged with
69
+ * the roster info from `allPlayers` (stat fields win on key collisions).
70
+ * Stat entries without a matching rostered player are included as-is.
71
+ *
72
+ * @param params.season Season in YYYYYYYY format, e.g. 20232024
73
+ * @param params.apiSleepRate Seconds to sleep between team requests. Defaults to 1.
74
+ * @example await client.helpers.allPlayersSummaryStatistics({ season: '20232024' })
75
+ */
76
+ export const allPlayersSummaryStatistics = async (ctx, { season, apiSleepRate = 1 }) => {
77
+ console.error('WARNING: This method will take a while to run. In the event of rate limiting, you may need to increase the api_sleep_rate.');
78
+ const players = await allPlayers(ctx, { season, apiSleepRate });
79
+ const teams = await fetchTeams(ctx);
80
+ const outData = [];
81
+ for (const team of teams) {
82
+ await ctx.sleep(apiSleepRate);
83
+ const context = buildQuery([
84
+ filter.franchise(team.franchise_id),
85
+ filter.season(season, season),
86
+ ]);
87
+ const data = await skaterStatsWithQueryContext(ctx, {
88
+ reportType: 'summary',
89
+ queryContext: context,
90
+ aggregate: true,
91
+ });
92
+ outData.push(...(data.data ?? []));
93
+ }
94
+ const playerById = new Map(players.map((player) => [player.id, player]));
95
+ return outData.map((statEntry) => {
96
+ const player = statEntry.playerId
97
+ ? playerById.get(statEntry.playerId)
98
+ : undefined;
99
+ return player ? { ...player, ...statEntry } : statEntry;
100
+ });
101
+ };
102
+ export const helpersApi = {
103
+ gameIdsBySeason,
104
+ allPlayers,
105
+ allPlayersSummaryStatistics,
106
+ };
@@ -0,0 +1,40 @@
1
+ import type { Context } from '#src/context.mjs';
2
+ import type { Country, DraftYear, GlossaryEntry, SeasonRules, StatsConfig } from '#src/types/index.mjs';
3
+ /**
4
+ * Gets the full NHL glossary of statistical terms and abbreviations.
5
+ *
6
+ * @example https://api.nhle.com/stats/rest/en/glossary?sort=fullName
7
+ */
8
+ export declare const glossary: (ctx: Context) => Promise<GlossaryEntry[]>;
9
+ /**
10
+ * Gets the stats API configuration, including available report types and
11
+ * filters.
12
+ *
13
+ * @example https://api.nhle.com/stats/rest/en/config
14
+ */
15
+ export declare const config: (ctx: Context) => Promise<StatsConfig>;
16
+ /**
17
+ * Gets the list of countries recognized by the NHL.
18
+ *
19
+ * @example https://api.nhle.com/stats/rest/en/country
20
+ */
21
+ export declare const countries: (ctx: Context) => Promise<Country[]>;
22
+ /**
23
+ * Gets rules and metadata for every NHL season on record.
24
+ *
25
+ * @example https://api.nhle.com/stats/rest/en/season
26
+ */
27
+ export declare const seasonSpecificRulesAndInfo: (ctx: Context) => Promise<SeasonRules[]>;
28
+ /**
29
+ * Gets the number of rounds for each NHL draft year.
30
+ *
31
+ * @example https://api.nhle.com/stats/rest/en/draft
32
+ */
33
+ export declare const draftYearAndRounds: (ctx: Context) => Promise<DraftYear[]>;
34
+ export declare const miscApi: {
35
+ readonly glossary: typeof glossary;
36
+ readonly config: typeof config;
37
+ readonly countries: typeof countries;
38
+ readonly seasonSpecificRulesAndInfo: typeof seasonSpecificRulesAndInfo;
39
+ readonly draftYearAndRounds: typeof draftYearAndRounds;
40
+ };
@@ -0,0 +1,43 @@
1
+ import { Endpoint } from '#src/http-client.mjs';
2
+ async function getData(ctx, resource) {
3
+ const response = await (await ctx.get(Endpoint.API_CORE, resource)).json();
4
+ return response.data ?? [];
5
+ }
6
+ /**
7
+ * Gets the full NHL glossary of statistical terms and abbreviations.
8
+ *
9
+ * @example https://api.nhle.com/stats/rest/en/glossary?sort=fullName
10
+ */
11
+ export const glossary = async (ctx) => getData(ctx, 'stats/rest/en/glossary?sort=fullName');
12
+ /**
13
+ * Gets the stats API configuration, including available report types and
14
+ * filters.
15
+ *
16
+ * @example https://api.nhle.com/stats/rest/en/config
17
+ */
18
+ export const config = async (ctx) => (await ctx.get(Endpoint.API_CORE, 'stats/rest/en/config')).json();
19
+ /**
20
+ * Gets the list of countries recognized by the NHL.
21
+ *
22
+ * @example https://api.nhle.com/stats/rest/en/country
23
+ */
24
+ export const countries = async (ctx) => getData(ctx, 'stats/rest/en/country');
25
+ /**
26
+ * Gets rules and metadata for every NHL season on record.
27
+ *
28
+ * @example https://api.nhle.com/stats/rest/en/season
29
+ */
30
+ export const seasonSpecificRulesAndInfo = async (ctx) => getData(ctx, 'stats/rest/en/season');
31
+ /**
32
+ * Gets the number of rounds for each NHL draft year.
33
+ *
34
+ * @example https://api.nhle.com/stats/rest/en/draft
35
+ */
36
+ export const draftYearAndRounds = async (ctx) => getData(ctx, 'stats/rest/en/draft');
37
+ export const miscApi = {
38
+ glossary,
39
+ config,
40
+ countries,
41
+ seasonSpecificRulesAndInfo,
42
+ draftYearAndRounds,
43
+ };
@@ -0,0 +1,28 @@
1
+ import type { Context } from '#src/context.mjs';
2
+ import type { Prospects, Roster } from '#src/types/index.mjs';
3
+ import type { Id } from '#src/utils.mjs';
4
+ /**
5
+ * Gets prospects for a specific team, grouped by position.
6
+ *
7
+ * @param params.teamAbbr Team abbreviation, e.g. BUF, TOR
8
+ * @example https://api-web.nhle.com/v1/prospects/BUF
9
+ */
10
+ export declare const prospectsByTeam: (ctx: Context, { teamAbbr }: {
11
+ teamAbbr: string;
12
+ }) => Promise<Prospects>;
13
+ /**
14
+ * Gets the roster for a given team and season, grouped by position
15
+ * (forwards, defensemen, goalies). Same data as `teams.teamRoster`.
16
+ *
17
+ * @param params.teamAbbr Team abbreviation, e.g. BUF, TOR
18
+ * @param params.season Season in YYYYYYYY format, e.g. 20232024
19
+ * @example https://api-web.nhle.com/v1/roster/BUF/20232024
20
+ */
21
+ export declare const playersByTeam: (ctx: Context, { teamAbbr, season }: {
22
+ teamAbbr: string;
23
+ season: Id;
24
+ }) => Promise<Roster>;
25
+ export declare const playersApi: {
26
+ readonly prospectsByTeam: typeof prospectsByTeam;
27
+ readonly playersByTeam: typeof playersByTeam;
28
+ };
@@ -0,0 +1,18 @@
1
+ import { Endpoint } from '#src/http-client.mjs';
2
+ /**
3
+ * Gets prospects for a specific team, grouped by position.
4
+ *
5
+ * @param params.teamAbbr Team abbreviation, e.g. BUF, TOR
6
+ * @example https://api-web.nhle.com/v1/prospects/BUF
7
+ */
8
+ export const prospectsByTeam = async (ctx, { teamAbbr }) => (await ctx.get(Endpoint.API_WEB_V1, `prospects/${teamAbbr}`)).json();
9
+ /**
10
+ * Gets the roster for a given team and season, grouped by position
11
+ * (forwards, defensemen, goalies). Same data as `teams.teamRoster`.
12
+ *
13
+ * @param params.teamAbbr Team abbreviation, e.g. BUF, TOR
14
+ * @param params.season Season in YYYYYYYY format, e.g. 20232024
15
+ * @example https://api-web.nhle.com/v1/roster/BUF/20232024
16
+ */
17
+ export const playersByTeam = async (ctx, { teamAbbr, season }) => (await ctx.get(Endpoint.API_WEB_V1, `roster/${teamAbbr}/${season}`)).json();
18
+ export const playersApi = { prospectsByTeam, playersByTeam };
@@ -0,0 +1,22 @@
1
+ import type { Filter } from '#src/api/query/filters.mjs';
2
+ /**
3
+ * A container for query information and validation state: the constructed
4
+ * query string, the original filters, any validation errors and a base fact
5
+ * query (defaults to "gamesPlayed>=1").
6
+ */
7
+ export interface QueryContext {
8
+ readonly query: string;
9
+ readonly filters: readonly Filter[];
10
+ readonly errors: readonly string[];
11
+ readonly factQuery: string;
12
+ }
13
+ /**
14
+ * Builds and validates a query string from a list of filters. Invalid
15
+ * filters are skipped and their errors collected; valid filters are joined
16
+ * with " and ".
17
+ */
18
+ /** Fact filter `buildQuery` applies unless told otherwise. */
19
+ export declare const DEFAULT_FACT_QUERY = "gamesPlayed>=1";
20
+ export declare function buildQuery(filters: readonly Filter[], factQuery?: string): QueryContext;
21
+ /** True if there are no validation errors. */
22
+ export declare function isValidQuery(context: QueryContext): boolean;