import {z} from 'zod' export type GetApiEventsnextPhpArgs = {id: number}; export type GetApiEventsnextPhpOptions = {baseUrl?: string | undefined, fetch?: typeof fetch | undefined}; export const eventSchema = z.object({idEvent: z.string().optional(), idAPIfootball: z.string().nullable().optional(), strEvent: z.string().optional(), strEventAlternate: z.string().nullable().optional(), strFilename: z.string().optional(), strSport: z.string().nullable().optional(), idLeague: z.string().nullable().optional(), strLeague: z.string().nullable().optional(), strLeagueBadge: z.string().nullable().optional(), strSeason: z.string().nullable().optional(), strDescriptionEN: z.string().nullable().optional(), strHomeTeam: z.string().nullable().optional(), strAwayTeam: z.string().nullable().optional(), intHomeScore: z.string().nullable().optional(), intRound: z.string().nullable().optional(), intAwayScore: z.string().nullable().optional(), intSpectators: z.string().nullable().optional(), strOfficial: z.string().nullable().optional(), strTimestamp: z.string().nullable().optional(), dateEvent: z.string().nullable().optional(), dateEventLocal: z.string().nullable().optional(), strTime: z.string().nullable().optional(), strTimeLocal: z.string().nullable().optional(), strGroup: z.string().nullable().optional(), idHomeTeam: z.string().nullable().optional(), strHomeTeamBadge: z.string().nullable().optional(), idAwayTeam: z.string().nullable().optional(), strAwayTeamBadge: z.string().nullable().optional(), intScore: z.string().nullable().optional(), intScoreVotes: z.string().nullable().optional(), strResult: z.string().nullable().optional(), idVenue: z.string().nullable().optional(), strVenue: z.string().nullable().optional(), strCountry: z.string().nullable().optional(), strCity: z.string().nullable().optional(), strPoster: z.string().nullable().optional(), strSquare: z.string().nullable().optional(), strFanart: z.string().nullable().optional(), strThumb: z.string().nullable().optional(), strBanner: z.string().nullable().optional(), strMap: z.string().nullable().optional(), strTweet1: z.string().nullable().optional(), strTweet2: z.string().nullable().optional(), strTweet3: z.string().nullable().optional(), strVideo: z.string().nullable().optional(), strStatus: z.string().nullable().optional(), strPostponed: z.string().nullable().optional(), strLocked: z.string().nullable().optional()}); export const eventsList = z.array(eventSchema); export const eventsResponse = z.object({events: eventsList.optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Get Next Events * * GET /eventsnext.php */ export const getApiEventsnextPhp = async (args: GetApiEventsnextPhpArgs, options?: GetApiEventsnextPhpOptions) => { const {baseUrl = "https://www.thesportsdb.com/api/v1/json/123", fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.id != null) query.append("id", String(args.id)) const url = `${baseUrl.replace(/\/+$/, '')}/eventsnext.php${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(eventsResponse, await res.json()) };