142 lines
4.6 KiB
TypeScript
142 lines
4.6 KiB
TypeScript
import type { Team } from './apiResponseTypes'
|
|
import { API_URL } from './utilities'
|
|
|
|
interface TeamStandingRaw {
|
|
away_losses: number
|
|
away_wins: number
|
|
div1_losses: number
|
|
div1_wins: number
|
|
div2_losses: number
|
|
div2_wins: number
|
|
div3_losses: number
|
|
div3_wins: number
|
|
div4_losses: number
|
|
div4_wins: number
|
|
div_e_num: number
|
|
div_gb: number
|
|
home_losses: number
|
|
home_wins: number
|
|
id: number
|
|
last8_losses: number
|
|
last8_wins: number
|
|
losses: number
|
|
one_run_losses: number
|
|
one_run_wins: number
|
|
pythag_losses: number
|
|
pythag_wins: number
|
|
run_diff: number
|
|
streak_num: number
|
|
streak_wl: 'w' | 'l'
|
|
team: Team
|
|
wc_e_num: number | null
|
|
wc_gb: number
|
|
wins: number
|
|
}
|
|
|
|
export interface TeamStanding {
|
|
season: number
|
|
teamName: string
|
|
teamAbbreviation: string
|
|
divisionName: string
|
|
divisionAbbreviation: string
|
|
leagueAbbreviation: string
|
|
wins: number
|
|
losses: number
|
|
winPercentage: string,
|
|
last8Record: string,
|
|
pythagRecord: string,
|
|
oneRunRecord: string,
|
|
homeRecord: string,
|
|
awayRecord: string,
|
|
division1Record: string,
|
|
division2Record: string,
|
|
division3Record: string,
|
|
division4Record: string,
|
|
streak: string
|
|
divisionGamesBack: string
|
|
divisionEliminationNumber: string
|
|
wildcardGamesBack: string
|
|
wildcardEliminationNumber: string
|
|
runDifferential: string
|
|
isWildcardTeam: boolean
|
|
}
|
|
|
|
export async function fetchStandings(seasonNumber: number): Promise<TeamStanding[]> {
|
|
const response = await fetch(`${API_URL}/standings?season=${seasonNumber}`)
|
|
|
|
const standingsResponse: {
|
|
count: number
|
|
standings: TeamStandingRaw[]
|
|
} = await response.json()
|
|
const standings: TeamStandingRaw[] = standingsResponse.standings
|
|
|
|
return standings.map(normalizeStanding)
|
|
}
|
|
|
|
export async function fetchStandingByTeam(team: Team): Promise<TeamStanding | undefined> {
|
|
const response = await fetch(`${API_URL}/standings?season=${team.season}`)
|
|
|
|
const standingsResponse: {
|
|
count: number
|
|
standings: TeamStandingRaw[]
|
|
} = await response.json()
|
|
const standings: TeamStandingRaw[] = standingsResponse.standings
|
|
|
|
const teamStanding: TeamStandingRaw | undefined = standings.find(ts => ts.team.sname === team.sname)
|
|
|
|
if (!teamStanding) {
|
|
// throw new Error('standingsService.fetchStandingByTeam - Expected one team standing, found none')
|
|
console.warn('standingsService.fetchStandingByTeam - Expected one team standing, found none')
|
|
return undefined
|
|
}
|
|
|
|
return normalizeStanding(teamStanding)
|
|
}
|
|
|
|
function normalizeStanding(standing: TeamStandingRaw): TeamStanding {
|
|
const totalGamesPlayed = standing.wins + standing.losses
|
|
// round win percentage to 3 decimal places
|
|
const winPercentage: string = totalGamesPlayed ? `${(standing.wins / totalGamesPlayed).toFixed(3)}` : '-'
|
|
|
|
const formattedRunDiff = `${standing.run_diff > 0 ? '+' : ''}${standing.run_diff}`
|
|
const isWildcardTeam = standing.wc_gb !== null || standing.wc_e_num !== null
|
|
|
|
return {
|
|
season: standing.team.season,
|
|
teamName: standing.team.sname,
|
|
teamAbbreviation: standing.team.abbrev,
|
|
divisionName: standing.team.division.division_name,
|
|
divisionAbbreviation: standing.team.division.division_abbrev,
|
|
leagueAbbreviation: standing.team.division.league_abbrev,
|
|
wins: standing.wins,
|
|
losses: standing.losses,
|
|
winPercentage,
|
|
last8Record: `${standing.last8_wins}-${standing.last8_losses}`,
|
|
pythagRecord: `${standing.pythag_wins}-${standing.pythag_losses}`,
|
|
oneRunRecord: `${standing.one_run_wins}-${standing.one_run_losses}`,
|
|
homeRecord: `${standing.home_wins}-${standing.home_losses}`,
|
|
awayRecord: `${standing.away_wins}-${standing.away_losses}`,
|
|
division1Record: `${standing.div1_wins}-${standing.div1_losses}`,
|
|
division2Record: `${standing.div2_wins}-${standing.div2_losses}`,
|
|
division3Record: `${standing.div3_wins}-${standing.div3_losses}`,
|
|
division4Record: `${standing.div4_wins}-${standing.div4_losses}`,
|
|
streak: `${standing.streak_wl.toUpperCase()}${standing.streak_num}`,
|
|
divisionGamesBack: parseGamesBack(standing.div_gb),
|
|
divisionEliminationNumber: parseEliminationNumber(standing.div_e_num),
|
|
wildcardGamesBack: parseGamesBack(standing.wc_gb),
|
|
wildcardEliminationNumber: parseEliminationNumber(standing.wc_e_num),
|
|
runDifferential: formattedRunDiff,
|
|
isWildcardTeam
|
|
}
|
|
}
|
|
|
|
function parseGamesBack(gamesBack: number | null): string {
|
|
if (gamesBack == null) return '-'
|
|
return `${gamesBack < 0 ? '+' : ''}${Math.abs(gamesBack).toFixed(1)}`
|
|
}
|
|
function parseEliminationNumber(eliminationNumber: number | null): string {
|
|
if (eliminationNumber == null) return '-'
|
|
return eliminationNumber <= 0 ? 'E' : `${eliminationNumber}`
|
|
}
|
|
|