Skip to content

Commit 9b766af

Browse files
JamieB-gujamesmockettmarjisound
authored
Valibot schemas for football matches (#15362)
Allows us to request and validate this data from frontend client-side, which we'll want to do for the new match header to poll for scores and other data. Co-authored-by: James M <1166188+jamesmockett@users.noreply.github.com> Co-authored-by: Marjan K <15894063+marjisound@users.noreply.github.com>
1 parent d5a6927 commit 9b766af

3 files changed

Lines changed: 752 additions & 1374 deletions

File tree

dotcom-rendering/src/frontend/feFootballMatchListPage.ts

Lines changed: 94 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,113 @@
1+
import {
2+
boolean,
3+
literal,
4+
number,
5+
object,
6+
optional,
7+
type Output,
8+
string,
9+
variant,
10+
} from 'valibot';
111
import type {
212
FECompetitionSummary,
313
FEFootballCompetition,
414
FEFootballDataPage,
5-
FERound,
615
} from './feFootballDataPage';
716

8-
type FEStage = {
9-
stageNumber: string;
10-
};
17+
const stageSchema = object({
18+
stageNumber: string(),
19+
});
1120

12-
type FEVenue = {
13-
id: string;
14-
name: string;
15-
};
21+
const roundSchema = object({
22+
roundNumber: string(),
23+
name: optional(string()),
24+
});
1625

17-
type FEMatchCompetition = {
18-
id: string;
19-
name: string;
20-
};
26+
const venueSchema = object({
27+
id: string(),
28+
name: string(),
29+
});
2130

22-
export type FEMatchDayTeam = {
23-
id: string;
24-
name: string;
25-
score?: number;
26-
htScore?: number;
27-
aggregateScore?: number;
28-
scorers?: string;
29-
};
31+
const matchCompetitionSchema = object({
32+
id: string(),
33+
name: string(),
34+
});
3035

31-
type Official = {
32-
id: string;
33-
name: string;
34-
};
36+
const matchDayTeamSchema = object({
37+
id: string(),
38+
name: string(),
39+
score: optional(number()),
40+
htScore: optional(number()),
41+
aggregateScore: optional(number()),
42+
scorers: optional(string()),
43+
});
3544

36-
type FEFootballMatchData = {
37-
id: string;
38-
date: string;
39-
stage: FEStage;
40-
round: FERound;
41-
leg: string;
42-
homeTeam: FEMatchDayTeam;
43-
awayTeam: FEMatchDayTeam;
44-
venue?: FEVenue;
45-
comments?: string;
46-
};
45+
const officialSchema = object({
46+
id: string(),
47+
name: string(),
48+
});
4749

48-
export type FELive = FEFootballMatchData & {
49-
type: 'LiveMatch';
50-
status: string;
51-
attendance?: string;
52-
referee?: Official;
53-
};
50+
const footballMatchDataSchema = object({
51+
id: string(),
52+
date: string(),
53+
stage: stageSchema,
54+
round: roundSchema,
55+
leg: string(),
56+
homeTeam: matchDayTeamSchema,
57+
awayTeam: matchDayTeamSchema,
58+
venue: optional(venueSchema),
59+
comments: optional(string()),
60+
});
5461

55-
export type FEFixture = FEFootballMatchData & {
56-
type: 'Fixture';
57-
competition?: FEMatchCompetition;
58-
};
62+
const liveSchema = object({
63+
...footballMatchDataSchema.entries,
64+
type: literal('LiveMatch'),
65+
status: string(),
66+
attendance: optional(string()),
67+
referee: optional(officialSchema),
68+
});
5969

60-
export type FEMatchDay = FEFootballMatchData & {
61-
type: 'MatchDay';
62-
liveMatch: boolean;
63-
result: boolean;
64-
previewAvailable: boolean;
65-
reportAvailable: boolean;
66-
lineupsAvailable: boolean;
67-
matchStatus: string;
68-
attendance?: string;
69-
referee?: Official;
70-
competition?: FEMatchCompetition;
71-
};
70+
const fixtureSchema = object({
71+
...footballMatchDataSchema.entries,
72+
type: literal('Fixture'),
73+
competition: optional(matchCompetitionSchema),
74+
});
7275

73-
export type FEResult = FEFootballMatchData & {
74-
type: 'Result';
75-
reportAvailable: boolean;
76-
attendance?: string;
77-
referee?: Official;
78-
};
76+
const matchDaySchema = object({
77+
...footballMatchDataSchema.entries,
78+
type: literal('MatchDay'),
79+
liveMatch: boolean(),
80+
result: boolean(),
81+
previewAvailable: boolean(),
82+
reportAvailable: boolean(),
83+
lineupsAvailable: boolean(),
84+
matchStatus: string(),
85+
attendance: optional(string()),
86+
referee: optional(officialSchema),
87+
competition: optional(matchCompetitionSchema),
88+
});
89+
90+
const resultSchema = object({
91+
...footballMatchDataSchema.entries,
92+
type: literal('Result'),
93+
reportAvailable: boolean(),
94+
attendance: optional(string()),
95+
referee: optional(officialSchema),
96+
});
97+
98+
export const feFootballMatchSchema = variant('type', [
99+
fixtureSchema,
100+
matchDaySchema,
101+
resultSchema,
102+
liveSchema,
103+
]);
79104

80-
export type FEFootballMatch = FEFixture | FEMatchDay | FEResult | FELive;
105+
export type FELive = Output<typeof liveSchema>;
106+
export type FEFixture = Output<typeof fixtureSchema>;
107+
export type FEMatchDay = Output<typeof matchDaySchema>;
108+
export type FEResult = Output<typeof resultSchema>;
109+
export type FEFootballMatch = Output<typeof feFootballMatchSchema>;
110+
export type FEMatchDayTeam = Output<typeof matchDayTeamSchema>;
81111

82112
export type FECompetitionMatch = {
83113
competitionSummary: FECompetitionSummary;

0 commit comments

Comments
 (0)