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
@@ -0,0 +1,83 @@
1
+ import type { Context } from '#src/context.mjs';
2
+ import type { Id, JsonObject } from '#src/utils.mjs';
3
+ /**
4
+ * Get the full boxscore for a specific NHL game, including team scores,
5
+ * shots on goal, and per-player stats.
6
+ *
7
+ * @param params.gameId Game id, e.g. 2023020280
8
+ * @example https://api-web.nhle.com/v1/gamecenter/2023020280/boxscore
9
+ */
10
+ export declare const boxscore: (ctx: Context, { gameId }: {
11
+ gameId: Id;
12
+ }) => Promise<JsonObject>;
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 declare const playByPlay: (ctx: Context, { gameId }: {
21
+ gameId: Id;
22
+ }) => Promise<JsonObject>;
23
+ /**
24
+ * Get the landing-page summary for a specific NHL game, including scoring by
25
+ * period, three stars and penalties.
26
+ *
27
+ * @param params.gameId Game id, e.g. 2023020280
28
+ * @example https://api-web.nhle.com/v1/gamecenter/2023020280/landing
29
+ */
30
+ export declare const matchUp: (ctx: Context, { gameId }: {
31
+ gameId: Id;
32
+ }) => Promise<JsonObject>;
33
+ /**
34
+ * Get scores and game states for all NHL games on a given date. Returns the
35
+ * current day's scores when no date is supplied.
36
+ *
37
+ * @param params.date Date in YYYY-MM-DD format. Defaults to "now".
38
+ * @example https://api-web.nhle.com/v1/score/2023-10-15
39
+ */
40
+ export declare const dailyScores: (ctx: Context, { date }?: {
41
+ date?: string;
42
+ }) => Promise<JsonObject>;
43
+ /**
44
+ * Get individual player shift data for a specific game, including start/end
45
+ * times and durations.
46
+ *
47
+ * @param params.gameId Game id, e.g. 2023020280
48
+ * @param params.excludes Fields to exclude from the response. Defaults to ["eventDetails"].
49
+ * @example https://api.nhle.com/stats/rest/en/shiftcharts?cayenneExp=gameId=2023020280 and ...
50
+ */
51
+ export declare const shiftChartData: (ctx: Context, { gameId, excludes }: {
52
+ gameId: Id;
53
+ excludes?: string[];
54
+ }) => Promise<JsonObject>;
55
+ /**
56
+ * Get the season-series record and contextual stats for a specific game,
57
+ * including team season stats and last games.
58
+ *
59
+ * @param params.gameId Game id, e.g. 2023020280
60
+ * @example https://api-web.nhle.com/v1/gamecenter/2023020280/right-rail
61
+ */
62
+ export declare const seasonSeriesMatchup: (ctx: Context, { gameId }: {
63
+ gameId: Id;
64
+ }) => Promise<JsonObject>;
65
+ /**
66
+ * Get the narrative game story for a specific game, including scoring
67
+ * summaries, three stars and team game stats.
68
+ *
69
+ * @param params.gameId Game id, e.g. 2023020280
70
+ * @example https://api-web.nhle.com/v1/wsc/game-story/2023020280
71
+ */
72
+ export declare const gameStory: (ctx: Context, { gameId }: {
73
+ gameId: Id;
74
+ }) => Promise<JsonObject>;
75
+ export declare const gameCenterApi: {
76
+ readonly boxscore: typeof boxscore;
77
+ readonly playByPlay: typeof playByPlay;
78
+ readonly matchUp: typeof matchUp;
79
+ readonly dailyScores: typeof dailyScores;
80
+ readonly shiftChartData: typeof shiftChartData;
81
+ readonly seasonSeriesMatchup: typeof seasonSeriesMatchup;
82
+ readonly gameStory: typeof gameStory;
83
+ };
@@ -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,46 @@
1
+ import type { Context } from '#src/context.mjs';
2
+ import type { Id, JsonObject } from '#src/utils.mjs';
3
+ /**
4
+ * Gets all game IDs for a specified season by querying every team's
5
+ * schedule. Games appear once per participating team, so ids may repeat.
6
+ *
7
+ * @param params.season Season in YYYYYYYY format, e.g. 20232024
8
+ * @param params.gameTypes Only include these game types (1=Preseason, 2=Regular, 3=Playoffs). Defaults to all.
9
+ * @param params.apiSleepRate Seconds to sleep between team requests. Defaults to 1.
10
+ * @example await client.helpers.gameIdsBySeason({ season: '20232024', gameTypes: [2] })
11
+ */
12
+ export declare const gameIdsBySeason: (ctx: Context, { season, gameTypes, apiSleepRate, }: {
13
+ season: Id;
14
+ gameTypes?: number[];
15
+ apiSleepRate?: number;
16
+ }) => Promise<number[]>;
17
+ /**
18
+ * Gets every rostered player across all NHL teams for a given season. Each
19
+ * player gets a `team` abbreviation and flattened `firstName` / `lastName`.
20
+ *
21
+ * @param params.season Season in YYYYYYYY format, e.g. 20232024
22
+ * @param params.apiSleepRate Seconds to sleep between team requests. Defaults to 0.5.
23
+ * @example await client.helpers.allPlayers({ season: '20232024' })
24
+ */
25
+ export declare const allPlayers: (ctx: Context, { season, apiSleepRate }: {
26
+ season: Id;
27
+ apiSleepRate?: number;
28
+ }) => Promise<JsonObject[]>;
29
+ /**
30
+ * Gets summary statistics for every skater in a given season, merged with
31
+ * the roster info from `allPlayers` (stat fields win on key collisions).
32
+ * Stat entries without a matching rostered player are included as-is.
33
+ *
34
+ * @param params.season Season in YYYYYYYY format, e.g. 20232024
35
+ * @param params.apiSleepRate Seconds to sleep between team requests. Defaults to 1.
36
+ * @example await client.helpers.allPlayersSummaryStatistics({ season: '20232024' })
37
+ */
38
+ export declare const allPlayersSummaryStatistics: (ctx: Context, { season, apiSleepRate }: {
39
+ season: Id;
40
+ apiSleepRate?: number;
41
+ }) => Promise<JsonObject[]>;
42
+ export declare const helpersApi: {
43
+ readonly gameIdsBySeason: typeof gameIdsBySeason;
44
+ readonly allPlayers: typeof allPlayers;
45
+ readonly allPlayersSummaryStatistics: typeof allPlayersSummaryStatistics;
46
+ };
@@ -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 { JsonObject } from '#src/utils.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<JsonObject[]>;
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<JsonObject>;
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<JsonObject[]>;
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<JsonObject[]>;
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<JsonObject[]>;
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,27 @@
1
+ import type { Context } from '#src/context.mjs';
2
+ import type { Id, JsonObject } from '#src/utils.mjs';
3
+ /**
4
+ * Gets prospects for a specific team, grouped by position.
5
+ *
6
+ * @param params.teamAbbr Team abbreviation, e.g. BUF, TOR
7
+ * @example https://api-web.nhle.com/v1/prospects/BUF
8
+ */
9
+ export declare const prospectsByTeam: (ctx: Context, { teamAbbr }: {
10
+ teamAbbr: string;
11
+ }) => Promise<JsonObject>;
12
+ /**
13
+ * Gets the roster for a given team and season, grouped by position
14
+ * (forwards, defensemen, goalies). Same data as `teams.teamRoster`.
15
+ *
16
+ * @param params.teamAbbr Team abbreviation, e.g. BUF, TOR
17
+ * @param params.season Season in YYYYYYYY format, e.g. 20232024
18
+ * @example https://api-web.nhle.com/v1/roster/BUF/20232024
19
+ */
20
+ export declare const playersByTeam: (ctx: Context, { teamAbbr, season }: {
21
+ teamAbbr: string;
22
+ season: Id;
23
+ }) => Promise<JsonObject>;
24
+ export declare const playersApi: {
25
+ readonly prospectsByTeam: typeof prospectsByTeam;
26
+ readonly playersByTeam: typeof playersByTeam;
27
+ };
@@ -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,20 @@
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
+ export declare function buildQuery(filters: readonly Filter[], factQuery?: string): QueryContext;
19
+ /** True if there are no validation errors. */
20
+ export declare function isValidQuery(context: QueryContext): boolean;
@@ -0,0 +1,28 @@
1
+ import { toQuery, validateFilter } from '#src/api/query/filters.mjs';
2
+ /**
3
+ * Builds and validates a query string from a list of filters. Invalid
4
+ * filters are skipped and their errors collected; valid filters are joined
5
+ * with " and ".
6
+ */
7
+ export function buildQuery(filters, factQuery = 'gamesPlayed>=1') {
8
+ const outputFilters = [];
9
+ const errors = [];
10
+ for (const filter of filters) {
11
+ const error = validateFilter(filter);
12
+ if (error) {
13
+ errors.push(error);
14
+ continue;
15
+ }
16
+ outputFilters.push(toQuery(filter));
17
+ }
18
+ return {
19
+ query: outputFilters.join(' and '),
20
+ filters,
21
+ errors,
22
+ factQuery,
23
+ };
24
+ }
25
+ /** True if there are no validation errors. */
26
+ export function isValidQuery(context) {
27
+ return context.errors.length === 0;
28
+ }
@@ -0,0 +1,3 @@
1
+ export declare class InvalidQueryValueException extends Error {
2
+ constructor(message: string);
3
+ }
@@ -0,0 +1,6 @@
1
+ export class InvalidQueryValueException extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = 'InvalidQueryValueException';
5
+ }
6
+ }
@@ -0,0 +1,4 @@
1
+ export declare abstract class QueryBase {
2
+ abstract toQuery(): string;
3
+ abstract validate(): boolean | undefined;
4
+ }
@@ -0,0 +1,2 @@
1
+ export class QueryBase {
2
+ }
@@ -0,0 +1,13 @@
1
+ import { QueryBase } from '#src/api/query/filters/base.mjs';
2
+ export declare class DecisionQuery extends QueryBase {
3
+ readonly decision: string;
4
+ private readonly decisionQ;
5
+ /**
6
+ * Decision filter. W=win, L=loss, O=overtime loss.
7
+ * @param decision W, L, O
8
+ */
9
+ constructor(decision: string);
10
+ toString(): string;
11
+ toQuery(): string;
12
+ validate(): boolean;
13
+ }
@@ -0,0 +1,26 @@
1
+ import { InvalidQueryValueException } from '#src/api/query/errors.mjs';
2
+ import { QueryBase } from '#src/api/query/filters/base.mjs';
3
+ export class DecisionQuery extends QueryBase {
4
+ decision;
5
+ decisionQ = 'decision';
6
+ /**
7
+ * Decision filter. W=win, L=loss, O=overtime loss.
8
+ * @param decision W, L, O
9
+ */
10
+ constructor(decision) {
11
+ super();
12
+ this.decision = decision;
13
+ }
14
+ toString() {
15
+ return `DecisionQuery: Value=${this.decision}`;
16
+ }
17
+ toQuery() {
18
+ return `${this.decisionQ}='${this.decision}'`;
19
+ }
20
+ validate() {
21
+ if (!['W', 'L', 'O'].includes(this.decision)) {
22
+ throw new InvalidQueryValueException('Decision value must be one of [W, L, O]');
23
+ }
24
+ return true;
25
+ }
26
+ }
@@ -0,0 +1,15 @@
1
+ import { QueryBase } from '#src/api/query/filters/base.mjs';
2
+ import type { Id } from '#src/utils.mjs';
3
+ export declare class DraftQuery extends QueryBase {
4
+ readonly year: Id;
5
+ readonly round?: Id;
6
+ private readonly yearQ;
7
+ private readonly roundQ;
8
+ /**
9
+ * @param year Draft year
10
+ * @param draftRound Optional draft round. The API seems to default this to "1".
11
+ */
12
+ constructor(year: Id, draftRound?: Id);
13
+ toQuery(): string;
14
+ validate(): boolean;
15
+ }
@@ -0,0 +1,27 @@
1
+ import { QueryBase } from '#src/api/query/filters/base.mjs';
2
+ export class DraftQuery extends QueryBase {
3
+ year;
4
+ round;
5
+ yearQ = 'draftYear';
6
+ roundQ = 'draftRound';
7
+ /**
8
+ * @param year Draft year
9
+ * @param draftRound Optional draft round. The API seems to default this to "1".
10
+ */
11
+ constructor(year, draftRound) {
12
+ super();
13
+ this.year = year;
14
+ this.round = draftRound;
15
+ }
16
+ toQuery() {
17
+ let query = `${this.yearQ}=${this.year}`;
18
+ if (this.round) {
19
+ query += ' and ';
20
+ query += `${this.roundQ}=${this.round}`;
21
+ }
22
+ return query;
23
+ }
24
+ validate() {
25
+ return true;
26
+ }
27
+ }
@@ -0,0 +1,9 @@
1
+ import { QueryBase } from '#src/api/query/filters/base.mjs';
2
+ export declare class ExperienceQuery extends QueryBase {
3
+ readonly isRookie: boolean;
4
+ private readonly experienceQ;
5
+ /** Experience filter. true = rookies only, false = veterans only. */
6
+ constructor(isRookie: boolean);
7
+ toQuery(): string;
8
+ validate(): boolean;
9
+ }
@@ -0,0 +1,17 @@
1
+ import { QueryBase } from '#src/api/query/filters/base.mjs';
2
+ export class ExperienceQuery extends QueryBase {
3
+ isRookie;
4
+ experienceQ = 'isRookie';
5
+ /** Experience filter. true = rookies only, false = veterans only. */
6
+ constructor(isRookie) {
7
+ super();
8
+ this.isRookie = isRookie;
9
+ }
10
+ toQuery() {
11
+ const val = this.isRookie ? '1' : '0';
12
+ return `${this.experienceQ}='${val}'`;
13
+ }
14
+ validate() {
15
+ return true;
16
+ }
17
+ }
@@ -0,0 +1,9 @@
1
+ import { QueryBase } from '#src/api/query/filters/base.mjs';
2
+ import type { Id } from '#src/utils.mjs';
3
+ export declare class FranchiseQuery extends QueryBase {
4
+ readonly franchiseId: Id;
5
+ private readonly franchiseQ;
6
+ constructor(franchiseId: Id);
7
+ toQuery(): string;
8
+ validate(): boolean;
9
+ }
@@ -0,0 +1,15 @@
1
+ import { QueryBase } from '#src/api/query/filters/base.mjs';
2
+ export class FranchiseQuery extends QueryBase {
3
+ franchiseId;
4
+ franchiseQ = 'franchiseId';
5
+ constructor(franchiseId) {
6
+ super();
7
+ this.franchiseId = franchiseId;
8
+ }
9
+ toQuery() {
10
+ return `${this.franchiseQ}=${this.franchiseId}`;
11
+ }
12
+ validate() {
13
+ return true;
14
+ }
15
+ }
@@ -0,0 +1,10 @@
1
+ import { QueryBase } from '#src/api/query/filters/base.mjs';
2
+ import type { Id } from '#src/utils.mjs';
3
+ export declare class GameTypeQuery extends QueryBase {
4
+ readonly gameType: Id;
5
+ private readonly gameTypeQ;
6
+ /** @param gameType 1=Preseason, 2=Regular season, 3=Playoffs */
7
+ constructor(gameType: Id);
8
+ toQuery(): string;
9
+ validate(): boolean;
10
+ }