1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
import { z } from "zod";
export const SportsTeam = z.object({
league: z.string(), // ESPN path, e.g. "baseball/mlb"
team: z.string(), // name/abbrev substring, e.g. "Cubs"
});
export type SportsTeam = z.infer<typeof SportsTeam>;
export const SportsConfig = z.object({
// Leagues to show ALL games for (e.g. "basketball/nba" → every game). Empty by
// default: a dashboard is about my teams, not full slates. Opt into a league here.
leagues: z.array(z.string()).default([]),
// Favorite teams — these teams' games always surface (yesterday's result +
// today, or the next game when they're not playing today).
teams: z.array(SportsTeam).default([]),
});
export type SportsConfig = z.infer<typeof SportsConfig>;
export const SportsPayload = z.object({
games: z.array(
z.object({
league: z.string(),
status: z.string(),
// "pre" = scheduled, "in" = live, "post" = final
state: z.string().nullable().default(null),
home: z.string(),
away: z.string(),
homeScore: z.string().nullable(),
awayScore: z.string().nullable(),
startTime: z.string().nullable(),
// True when the game involves one of my favorite teams (drives the
// Favorites vs Leagues split in the TUI and paper).
favorite: z.boolean().default(false),
}),
),
});
export type SportsPayload = z.infer<typeof SportsPayload>;
|