import {z} from 'zod' export type GetApiValorantV2EsportsVlrMatchesMatchIdArgs = {match_id: number}; export type GetApiValorantV2EsportsVlrMatchesMatchIdOptions = {baseUrl?: string | undefined, apiKeyHeader?: string | undefined, fetch?: typeof fetch | undefined}; export const esportsV2TeamEconomyRoundWon = z.object({rounds: z.number().int().gte(0), won: z.number().int().gte(0)}); export const esportsV2TeamEconomy = z.object({eco: esportsV2TeamEconomyRoundWon, full_buy: esportsV2TeamEconomyRoundWon, pistol_won: z.number().int().gte(0), semi_eco: esportsV2TeamEconomyRoundWon, team_name: z.string()}); export const esportsV2MatchEconomy = z.object({teams: z.array(esportsV2TeamEconomy)}); export const esportsV2MatchGameRound = z.object({round: z.number().int().gte(0), winning_site: z.string(), winning_team: z.number().int().gte(0)}); export const esportsV2MatchPlayer = z.object({id: z.number().int().gte(0), name: z.string(), nation: z.string(), slug: z.string()}); export const esportsV2MatchGamePlayerStats = z.object({acs: z.number().int().gte(0).nullable().optional(), adr: z.number().nullable().optional(), assists: z.number().int().gte(0).nullable().optional(), deaths: z.number().int().gte(0).nullable().optional(), first_deaths: z.number().int().gte(0).nullable().optional(), first_kills: z.number().int().gte(0).nullable().optional(), fk_diff: z.number().int().nullable().optional(), hs_pct: z.number().nullable().optional(), kast: z.number().nullable().optional(), kd_diff: z.number().int().nullable().optional(), kills: z.number().int().gte(0).nullable().optional(), rating: z.number().nullable().optional()}); export const esportsV2MatchGamePlayer = z.object({agent: z.string(), player: esportsV2MatchPlayer, stats: esportsV2MatchGamePlayerStats}); export const esportsV2MatchGameTeam = z.object({is_winner: z.boolean(), name: z.string(), players: z.array(esportsV2MatchGamePlayer), score: z.number().int().gte(0).nullable().optional(), score_ct: z.number().int().gte(0).nullable().optional(), score_t: z.number().int().gte(0).nullable().optional()}); export const esportsV2MatchGame = z.object({duration_in_s: z.number().int().gte(0).nullable().optional(), map: z.string(), picked_by: z.number().int().gte(0).nullable().optional(), rounds: z.array(esportsV2MatchGameRound), teams: z.array(esportsV2MatchGameTeam)}); export const esportsV2HeadToHeadEvent = z.object({icon: z.string(), name: z.string(), series: z.string()}); export const esportsV2IdSlug = z.object({id: z.number().int().gte(0), slug: z.string()}); export const esportsV2HeadToHeadScore = z.object({team_1: z.number().int().gte(0), team_2: z.number().int().gte(0), winner_team: z.number().int().gte(0)}); export const esportsV2HeadToHeadMatch = z.object({date: z.string(), event: esportsV2HeadToHeadEvent, match: esportsV2IdSlug, score: esportsV2HeadToHeadScore}); export const esportsV2MatchEvent = z.object({icon: z.string(), id: z.number().int().gte(0), series: z.string(), slug: z.string(), title: z.string()}); export const esportsV2MatchHeader = z.object({date: z.string(), event: esportsV2MatchEvent, format: z.string(), note: z.string(), patch: z.string(), status: z.string()}); export const esportsV2PastMatchOpponent = z.object({logo: z.string(), name: z.string()}); export const esportsV2PastMatchScore = z.object({against: z.number().int().gte(0), for: z.number().int().gte(0)}); export const esportsV2PastMatch = z.object({date: z.string(), is_win: z.boolean(), match: esportsV2IdSlug, opponent: esportsV2PastMatchOpponent, score: esportsV2PastMatchScore}); export const esportsV2TeamPastMatches = z.object({matches: z.array(esportsV2PastMatch), team: z.number().int().gte(0)}); export const esportsV2KillMatrixEntry = z.object({deaths: z.number().int().gte(0), killer: z.number().int().gte(0), kills: z.number().int().gte(0), victim: z.number().int().gte(0)}); export const esportsV2PlayerPerformanceClutches = z.object({"1v1": z.number().int().gte(0), "1v2": z.number().int().gte(0), "1v3": z.number().int().gte(0), "1v4": z.number().int().gte(0), "1v5": z.number().int().gte(0)}); export const esportsV2PlayerPerformanceMultiKills = z.object({"2k": z.number().int().gte(0), "3k": z.number().int().gte(0), "4k": z.number().int().gte(0), "5k": z.number().int().gte(0)}); export const esportsV2PlayerPerformancePlayer = z.object({id: z.number().int().gte(0), name: z.string()}); export const esportsV2PlayerPerformance = z.object({clutches: esportsV2PlayerPerformanceClutches, defuses: z.number().int().gte(0), econ_rating: z.number().int().gte(0), multi_kills: esportsV2PlayerPerformanceMultiKills, plants: z.number().int().gte(0), player: esportsV2PlayerPerformancePlayer}); export const esportsV2MatchPerformance = z.object({kill_matrix: z.array(esportsV2KillMatrixEntry), player_performances: z.array(esportsV2PlayerPerformance)}); export const esportsV2MatchStream = z.object({link: z.string(), name: z.string()}); export const esportsV2MatchHeaderTeam = z.object({icon: z.string(), id: z.number().int().gte(0), name: z.string(), score: z.number().int().gte(0).nullable().optional(), slug: z.string(), url: z.string()}); export const esportsV2Match = z.object({economy: esportsV2MatchEconomy.nullable().optional(), games: z.array(esportsV2MatchGame), head_to_head: z.array(esportsV2HeadToHeadMatch), metadata: esportsV2MatchHeader, past_matches: z.array(esportsV2TeamPastMatches), performance: esportsV2MatchPerformance.nullable().optional(), streams: z.array(esportsV2MatchStream), teams: z.array(esportsV2MatchHeaderTeam), vods: z.array(esportsV2MatchStream)}); export const esportsV2MatchesResponse = z.object({data: esportsV2Match, status: z.number().int().gte(0)}); 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 VLR match details (v2) * * GET /valorant/v2/esports/vlr/matches/{match_id} * * Also accepts auth: api_key_query */ export const getApiValorantV2EsportsVlrMatchesMatchId = async (args: GetApiValorantV2EsportsVlrMatchesMatchIdArgs, options?: GetApiValorantV2EsportsVlrMatchesMatchIdOptions) => { const {baseUrl = "https://api.henrikdev.xyz", fetch: fetchFn = fetch, apiKeyHeader} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (apiKeyHeader !== undefined) headers.set("Authorization", apiKeyHeader) const url = `${baseUrl.replace(/\/+$/, '')}/valorant/v2/esports/vlr/matches/${encodeURIComponent(String(args.match_id))}${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(esportsV2MatchesResponse, await res.json()) };