brackt/app/services/standings-sync/nhl.ts

79 lines
2.3 KiB
TypeScript
Raw Normal View History

import type { FetchedStandingsRecord, StandingsSyncAdapter } from "./types";
const NHL_STANDINGS_URL = "https://api-web.nhle.com/v1/standings/now";
interface NhlTeamRecord {
teamName: { default: string };
teamAbbrev: { default: string };
teamLogo?: string;
conferenceName: string;
divisionName: string;
gamesPlayed: number;
wins: number;
losses: number;
otLosses: number;
points: number;
pointPctg: number;
winPctg: number;
l10Wins: number;
l10Losses: number;
l10OtLosses: number;
streakCode: string; // "W" or "L"
streakCount: number;
homeWins: number;
homeLosses: number;
homeOtLosses: number;
roadWins: number;
roadLosses: number;
roadOtLosses: number;
conferenceSequence: number;
divisionSequence: number;
leagueSequence: number;
teamId?: number;
}
interface NhlStandingsResponse {
standings: NhlTeamRecord[];
}
export class NhlStandingsAdapter implements StandingsSyncAdapter {
async fetchStandings(): Promise<FetchedStandingsRecord[]> {
const response = await fetch(NHL_STANDINGS_URL);
if (!response.ok) {
throw new Error(`NHL standings API returned ${response.status}: ${response.statusText}`);
}
const json = (await response.json()) as NhlStandingsResponse;
if (!json.standings || !Array.isArray(json.standings)) {
throw new Error("Unexpected NHL standings API response shape");
}
return json.standings.map((team, index): FetchedStandingsRecord => {
const homeRecord = `${team.homeWins}-${team.homeLosses}-${team.homeOtLosses}`;
const awayRecord = `${team.roadWins}-${team.roadLosses}-${team.roadOtLosses}`;
const streak = `${team.streakCode}${team.streakCount}`;
const lastTen = `${team.l10Wins}-${team.l10Losses}-${team.l10OtLosses}`;
return {
teamName: team.teamName.default,
externalTeamId: team.teamAbbrev?.default ?? String(index),
wins: team.wins,
losses: team.losses,
otLosses: team.otLosses,
winPct: team.winPctg ?? 0,
gamesPlayed: team.gamesPlayed,
conference: team.conferenceName,
division: team.divisionName,
conferenceRank: team.conferenceSequence,
divisionRank: team.divisionSequence,
leagueRank: team.leagueSequence,
streak,
lastTen,
homeRecord,
awayRecord,
};
});
}
}