UNPKG

iracing-data-sdk

Version:

A comprehensive TypeScript SDK for the iRacing Data API with support for all documented endpoints

1,376 lines (1,374 loc) 52.8 kB
// src/types.ts import { z } from "zod"; var AuthRequestSchema = z.object({ email: z.string().email(), password: z.string() }); var AuthResponseSchema = z.object({ authcode: z.string(), ssoCookieValue: z.string(), custId: z.number(), email: z.string().email() }); var HostedCombinedSessionsParamsSchema = z.object({ package_id: z.number().optional() }); var LeagueCustLeagueSessionsParamsSchema = z.object({ mine: z.boolean().optional(), package_id: z.number().optional() }); var LeagueDirectoryParamsSchema = z.object({ search: z.string().optional(), tag: z.string().optional(), restrict_to_member: z.boolean().optional(), restrict_to_recruiting: z.boolean().optional(), restrict_to_friends: z.boolean().optional(), restrict_to_watched: z.boolean().optional(), minimum_roster_count: z.number().optional(), maximum_roster_count: z.number().optional(), lowerbound: z.number().optional(), upperbound: z.number().optional(), sort: z.string().optional(), order: z.string().optional() }); var LeagueGetParamsSchema = z.object({ league_id: z.number(), include_licenses: z.boolean().optional() }); var LeaguePointsSystemsParamsSchema = z.object({ league_id: z.number(), season_id: z.number().optional() }); var LeagueMembershipParamsSchema = z.object({ cust_id: z.number().optional(), include_league: z.boolean().optional() }); var LeagueRosterParamsSchema = z.object({ league_id: z.number(), include_licenses: z.boolean().optional() }); var LeagueSeasonsParamsSchema = z.object({ league_id: z.number(), retired: z.boolean().optional() }); var LeagueSeasonStandingsParamsSchema = z.object({ league_id: z.number(), season_id: z.number(), car_class_id: z.number().optional(), car_id: z.number().optional() }); var LeagueSeasonSessionsParamsSchema = z.object({ league_id: z.number(), season_id: z.number(), results_only: z.boolean().optional() }); var LookupDriversParamsSchema = z.object({ search_term: z.string(), league_id: z.number().optional() }); var MemberGetParamsSchema = z.object({ cust_ids: z.array(z.number()).transform((arr) => arr.join(",")), include_licenses: z.boolean().optional() }); var MemberAwardsParamsSchema = z.object({ cust_id: z.number().optional() }); var MemberAwardInstancesParamsSchema = z.object({ cust_id: z.number().optional(), award_id: z.number() }); var MemberChartDataParamsSchema = z.object({ cust_id: z.number().optional(), category_id: z.number(), chart_type: z.number() }); var MemberProfileParamsSchema = z.object({ cust_id: z.number().optional() }); var ResultsGetParamsSchema = z.object({ subsession_id: z.number(), include_licenses: z.boolean().optional() }); var EventLogParamsSchema = z.object({ subsession_id: z.number(), simsession_number: z.number() }); var LapChartDataParamsSchema = z.object({ subsession_id: z.number(), simsession_number: z.number() }); var LapDataParamsSchema = z.object({ subsession_id: z.number(), simsession_number: z.number(), cust_id: z.number().optional(), team_id: z.number().optional() }); var ResultsSearchHostedParamsSchema = z.object({ start_range_begin: z.string().optional(), start_range_end: z.string().optional(), finish_range_begin: z.string().optional(), finish_range_end: z.string().optional(), cust_id: z.number().optional(), team_id: z.number().optional(), host_cust_id: z.number().optional(), session_name: z.string().optional(), league_id: z.number().optional(), league_season_id: z.number().optional(), car_id: z.number().optional(), track_id: z.number().optional(), category_ids: z.array(z.number()).transform((arr) => arr.join(",")).optional() }); var ResultsSearchSeriesParamsSchema = z.object({ season_year: z.number().optional(), season_quarter: z.number().optional(), start_range_begin: z.string().optional(), start_range_end: z.string().optional(), finish_range_begin: z.string().optional(), finish_range_end: z.string().optional(), cust_id: z.number().optional(), team_id: z.number().optional(), series_id: z.number().optional(), race_week_num: z.number().optional(), official_only: z.boolean().optional(), event_types: z.array(z.number()).transform((arr) => arr.join(",")).optional(), category_ids: z.array(z.number()).transform((arr) => arr.join(",")).optional() }); var SeasonResultsParamsSchema = z.object({ season_id: z.number(), event_type: z.number().optional(), race_week_num: z.number().optional() }); var SeasonListParamsSchema = z.object({ season_year: z.number(), season_quarter: z.number() }); var SeasonRaceGuideParamsSchema = z.object({ from: z.string().optional(), include_end_after_from: z.boolean().optional() }); var SeasonSpectatorSubsessionIdsParamsSchema = z.object({ event_types: z.array(z.number()).transform((arr) => arr.join(",")).optional() }); var SeasonSpectatorSubsessionIdsDetailParamsSchema = z.object({ event_types: z.array(z.number()).transform((arr) => arr.join(",")).optional(), season_ids: z.array(z.number()).transform((arr) => arr.join(",")).optional() }); var SeriesPastSeasonsParamsSchema = z.object({ series_id: z.number() }); var SeriesSeasonsParamsSchema = z.object({ include_series: z.boolean().optional(), season_year: z.number().optional(), season_quarter: z.number().optional() }); var SeriesSeasonListParamsSchema = z.object({ include_series: z.boolean().optional(), season_year: z.number().optional(), season_quarter: z.number().optional() }); var SeriesSeasonScheduleParamsSchema = z.object({ season_id: z.number() }); var StatsMemberBestsParamsSchema = z.object({ cust_id: z.number().optional(), car_id: z.number().optional() }); var StatsMemberCareerParamsSchema = z.object({ cust_id: z.number().optional() }); var StatsMemberDivisionParamsSchema = z.object({ season_id: z.number(), event_type: z.number() }); var StatsMemberRecapParamsSchema = z.object({ cust_id: z.number().optional(), year: z.number().optional(), season: z.number().optional() }); var StatsMemberRecentRacesParamsSchema = z.object({ cust_id: z.number().optional() }); var StatsMemberSummaryParamsSchema = z.object({ cust_id: z.number().optional() }); var StatsMemberYearlyParamsSchema = z.object({ cust_id: z.number().optional() }); var StatsSeasonDriverStandingsParamsSchema = z.object({ season_id: z.number(), car_class_id: z.number(), division: z.number().optional(), race_week_num: z.number().optional() }); var StatsSeasonSupersessionStandingsParamsSchema = z.object({ season_id: z.number(), car_class_id: z.number(), division: z.number().optional(), race_week_num: z.number().optional() }); var StatsSeasonTeamStandingsParamsSchema = z.object({ season_id: z.number(), car_class_id: z.number(), race_week_num: z.number().optional() }); var StatsSeasonTTStandingsParamsSchema = z.object({ season_id: z.number(), car_class_id: z.number(), division: z.number().optional(), race_week_num: z.number().optional() }); var StatsSeasonTTResultsParamsSchema = z.object({ season_id: z.number(), car_class_id: z.number(), race_week_num: z.number(), division: z.number().optional() }); var StatsSeasonQualifyResultsParamsSchema = z.object({ season_id: z.number(), car_class_id: z.number(), race_week_num: z.number(), division: z.number().optional() }); var StatsWorldRecordsParamsSchema = z.object({ car_id: z.number(), track_id: z.number(), season_year: z.number().optional(), season_quarter: z.number().optional() }); var TeamGetParamsSchema = z.object({ team_id: z.number(), include_licenses: z.boolean().optional() }); var TimeAttackMemberSeasonResultsParamsSchema = z.object({ ta_comp_season_id: z.number() }); // src/endpoints.ts var ApiEndpoints = /* @__PURE__ */ ((ApiEndpoints2) => { ApiEndpoints2["AUTH"] = "/auth"; ApiEndpoints2["CAR_ASSETS"] = "/data/car/assets"; ApiEndpoints2["CAR_GET"] = "/data/car/get"; ApiEndpoints2["CARCLASS_GET"] = "/data/carclass/get"; ApiEndpoints2["CONSTANTS_CATEGORIES"] = "/data/constants/categories"; ApiEndpoints2["CONSTANTS_DIVISIONS"] = "/data/constants/divisions"; ApiEndpoints2["CONSTANTS_EVENT_TYPES"] = "/data/constants/event_types"; ApiEndpoints2["DRIVER_STATS_OVAL"] = "/data/driver_stats_by_category/oval"; ApiEndpoints2["DRIVER_STATS_SPORTS_CAR"] = "/data/driver_stats_by_category/sports_car"; ApiEndpoints2["DRIVER_STATS_FORMULA_CAR"] = "/data/driver_stats_by_category/formula_car"; ApiEndpoints2["DRIVER_STATS_ROAD"] = "/data/driver_stats_by_category/road"; ApiEndpoints2["DRIVER_STATS_DIRT_OVAL"] = "/data/driver_stats_by_category/dirt_oval"; ApiEndpoints2["DRIVER_STATS_DIRT_ROAD"] = "/data/driver_stats_by_category/dirt_road"; ApiEndpoints2["HOSTED_COMBINED_SESSIONS"] = "/data/hosted/combined_sessions"; ApiEndpoints2["HOSTED_SESSIONS"] = "/data/hosted/sessions"; ApiEndpoints2["LEAGUE_CUST_LEAGUE_SESSIONS"] = "/data/league/cust_league_sessions"; ApiEndpoints2["LEAGUE_DIRECTORY"] = "/data/league/directory"; ApiEndpoints2["LEAGUE_GET"] = "/data/league/get"; ApiEndpoints2["LEAGUE_GET_POINTS_SYSTEMS"] = "/data/league/get_points_systems"; ApiEndpoints2["LEAGUE_MEMBERSHIP"] = "/data/league/membership"; ApiEndpoints2["LEAGUE_ROSTER"] = "/data/league/roster"; ApiEndpoints2["LEAGUE_SEASONS"] = "/data/league/seasons"; ApiEndpoints2["LEAGUE_SEASON_STANDINGS"] = "/data/league/season_standings"; ApiEndpoints2["LEAGUE_SEASON_SESSIONS"] = "/data/league/season_sessions"; ApiEndpoints2["LOOKUP_COUNTRIES"] = "/data/lookup/countries"; ApiEndpoints2["LOOKUP_DRIVERS"] = "/data/lookup/drivers"; ApiEndpoints2["LOOKUP_FLAIRS"] = "/data/lookup/flairs"; ApiEndpoints2["LOOKUP_GET"] = "/data/lookup/get"; ApiEndpoints2["LOOKUP_LICENSES"] = "/data/lookup/licenses"; ApiEndpoints2["MEMBER_AWARDS"] = "/data/member/awards"; ApiEndpoints2["MEMBER_AWARD_INSTANCES"] = "/data/member/award_instances"; ApiEndpoints2["MEMBER_CHART_DATA"] = "/data/member/chart_data"; ApiEndpoints2["MEMBER_GET"] = "/data/member/get"; ApiEndpoints2["MEMBER_INFO"] = "/data/member/info"; ApiEndpoints2["MEMBER_PARTICIPATION_CREDITS"] = "/data/member/participation_credits"; ApiEndpoints2["MEMBER_PROFILE"] = "/data/member/profile"; ApiEndpoints2["RESULTS_GET"] = "/data/results/get"; ApiEndpoints2["RESULTS_EVENT_LOG"] = "/data/results/event_log"; ApiEndpoints2["RESULTS_LAP_CHART_DATA"] = "/data/results/lap_chart_data"; ApiEndpoints2["RESULTS_LAP_DATA"] = "/data/results/lap_data"; ApiEndpoints2["RESULTS_SEARCH_HOSTED"] = "/data/results/search_hosted"; ApiEndpoints2["RESULTS_SEARCH_SERIES"] = "/data/results/search_series"; ApiEndpoints2["RESULTS_SEASON_RESULTS"] = "/data/results/season_results"; ApiEndpoints2["SEASON_LIST"] = "/data/season/list"; ApiEndpoints2["SEASON_RACE_GUIDE"] = "/data/season/race_guide"; ApiEndpoints2["SEASON_SPECTATOR_SUBSESSIONIDS"] = "/data/season/spectator_subsessionids"; ApiEndpoints2["SEASON_SPECTATOR_SUBSESSIONIDS_DETAIL"] = "/data/season/spectator_subsessionids_detail"; ApiEndpoints2["SERIES_ASSETS"] = "/data/series/assets"; ApiEndpoints2["SERIES_GET"] = "/data/series/get"; ApiEndpoints2["SERIES_PAST_SEASONS"] = "/data/series/past_seasons"; ApiEndpoints2["SERIES_SEASONS"] = "/data/series/seasons"; ApiEndpoints2["SERIES_SEASON_LIST"] = "/data/series/season_list"; ApiEndpoints2["SERIES_SEASON_SCHEDULE"] = "/data/series/season_schedule"; ApiEndpoints2["SERIES_STATS_SERIES"] = "/data/series/stats_series"; ApiEndpoints2["STATS_MEMBER_BESTS"] = "/data/stats/member_bests"; ApiEndpoints2["STATS_MEMBER_CAREER"] = "/data/stats/member_career"; ApiEndpoints2["STATS_MEMBER_DIVISION"] = "/data/stats/member_division"; ApiEndpoints2["STATS_MEMBER_RECAP"] = "/data/stats/member_recap"; ApiEndpoints2["STATS_MEMBER_RECENT_RACES"] = "/data/stats/member_recent_races"; ApiEndpoints2["STATS_MEMBER_SUMMARY"] = "/data/stats/member_summary"; ApiEndpoints2["STATS_MEMBER_YEARLY"] = "/data/stats/member_yearly"; ApiEndpoints2["STATS_SEASON_DRIVER_STANDINGS"] = "/data/stats/season_driver_standings"; ApiEndpoints2["STATS_SEASON_SUPERSESSION_STANDINGS"] = "/data/stats/season_supersession_standings"; ApiEndpoints2["STATS_SEASON_TEAM_STANDINGS"] = "/data/stats/season_team_standings"; ApiEndpoints2["STATS_SEASON_TT_STANDINGS"] = "/data/stats/season_tt_standings"; ApiEndpoints2["STATS_SEASON_TT_RESULTS"] = "/data/stats/season_tt_results"; ApiEndpoints2["STATS_SEASON_QUALIFY_RESULTS"] = "/data/stats/season_qualify_results"; ApiEndpoints2["STATS_WORLD_RECORDS"] = "/data/stats/world_records"; ApiEndpoints2["TEAM_GET"] = "/data/team/get"; ApiEndpoints2["TIME_ATTACK_MEMBER_SEASON_RESULTS"] = "/data/time_attack/member_season_results"; ApiEndpoints2["TRACK_ASSETS"] = "/data/track/assets"; ApiEndpoints2["TRACK_GET"] = "/data/track/get"; return ApiEndpoints2; })(ApiEndpoints || {}); // src/iracingApi.ts import nodeFetch from "node-fetch"; import fetchCookie from "fetch-cookie"; import { CookieJar } from "tough-cookie"; var iRacingSDK = class { /** * Creates a new iRacing SDK instance * * @param options - Configuration options for the SDK */ constructor(options = {}) { this.baseUrl = options.baseUrl || "https://members-ng.iracing.com"; this.cookieJar = new CookieJar(); this.fetchImpl = options.fetchImpl || fetchCookie(nodeFetch, this.cookieJar); this.autoHandleChunkedResponses = options.autoHandleChunkedResponses !== false; } /** * Internal request helper that handles authentication, rate limiting, and error handling * * @param path - API endpoint path * @param options - Fetch options * @param query - Query parameters * @returns Promise resolving to the API response */ async request(path, options = {}, query) { let url = this.baseUrl + path; if (query && Object.keys(query).length > 0) { const params = new URLSearchParams(); for (const [key, value] of Object.entries(query)) { if (value !== void 0) params.append(key, String(value)); } url += `?${params.toString()}`; } console.log(`Requesting: ${url}`); let baseHeaders = { "Content-Type": "application/json", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" }; if (options.headers) { if (options.headers instanceof Headers) { options.headers.forEach((value, key) => { baseHeaders[key] = value; }); } else if (Array.isArray(options.headers)) { for (const [key, value] of options.headers) baseHeaders[key] = value; } else { baseHeaders = { ...baseHeaders, ...options.headers }; } } const res = await this.fetchImpl(url, { ...options, headers: baseHeaders, credentials: "include" }); const limit = res.headers.get("x-ratelimit-limit"); const remaining = res.headers.get("x-ratelimit-remaining"); const reset = res.headers.get("x-ratelimit-reset"); if (limit || remaining || reset) { console.log("[iRacing Rate Limit]", { limit, remaining, reset, resetDate: reset ? new Date(Number(reset) * 1e3).toISOString() : void 0 }); } if (remaining !== null && reset && Number(remaining) <= 1) { const now = Date.now(); const resetMs = Number(reset) * 1e3; const waitMs = resetMs - now; if (waitMs > 0) { console.warn(`[iRacingSDK] Rate limit reached. Waiting ${(waitMs / 1e3).toFixed(1)} seconds until reset...`); await new Promise((res2) => setTimeout(res2, waitMs)); } } if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`); return res.json(); } /** * Authenticate with iRacing and store session cookies * * @param req - Authentication request with email and password * @returns Promise resolving to authentication response */ async authenticate(req) { const parsed = AuthRequestSchema.safeParse(req); if (!parsed.success) throw parsed.error; const email = req.email.toLowerCase(); const passwordConcat = `${req.password}${email}`; let hashBase64; if (typeof window !== "undefined" && window.crypto && window.crypto.subtle) { const hashBuffer = await window.crypto.subtle.digest("SHA-256", new TextEncoder().encode(passwordConcat)); const hashArray = new Uint8Array(hashBuffer); const hashString = Array.from(hashArray).map((b) => String.fromCharCode(b)).join(""); hashBase64 = btoa(hashString); } else if (typeof global !== "undefined" && global.crypto && global.crypto.subtle) { const hashBuffer = await global.crypto.subtle.digest("SHA-256", new TextEncoder().encode(passwordConcat)); hashBase64 = Buffer.from(hashBuffer).toString("base64"); } else { const { createHash } = await import("crypto"); const hashBuffer = createHash("sha256").update(passwordConcat).digest(); hashBase64 = hashBuffer.toString("base64"); } const res = await this.fetchImpl(this.baseUrl + "/auth" /* AUTH */, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email, password: hashBase64 }), credentials: "include" }); if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`); const response = await res.json(); console.log("Authentication response:", JSON.stringify(response, null, 2)); if (response.ssoCookieValue) { this.ssoCookieValue = response.ssoCookieValue; if (response.authcode) { this.authcode = response.authcode; } } else { const setCookie = res.headers.get("set-cookie"); if (setCookie) { const match = setCookie.match(/irsso_membersv2=([^;]+)/); if (match) { this.ssoCookieValue = match[1]; } } if (response.authcode) { this.authcode = response.authcode; } } return response; } /** * Handle chunked responses by fetching data from S3 * * @param response - Response containing chunk_info * @returns Promise resolving to combined chunked data */ async handleChunkedResponse(response) { if (response.link && !response.chunk_info) { console.log(`[iRacingSDK] Processing direct link response: ${response.link}`); const linkResponse = await this.fetchImpl(response.link); if (!linkResponse.ok) { throw new Error(`Failed to fetch linked data: ${linkResponse.status}`); } const contentType = linkResponse.headers.get("content-type"); if (contentType && contentType.includes("text/csv")) { console.log(`[iRacingSDK] Processing CSV response`); const csvText = await linkResponse.text(); return csvText; } const linkData = await linkResponse.json(); console.log(`[iRacingSDK] Successfully fetched linked data`); return linkData; } if (response.data && response.data.chunk_info) { const nestedData = response.data; if (nestedData.chunk_info.num_chunks === 0 || nestedData.chunk_info.rows === 0) { console.log(`[iRacingSDK] No chunks needed (${nestedData.chunk_info.rows} rows)`); return nestedData; } if (nestedData.chunk_info.chunk_file_names && nestedData.chunk_info.chunk_file_names.length > 0) { console.log(`[iRacingSDK] Processing ${nestedData.chunk_info.num_chunks} chunks from nested response`); const chunks2 = []; for (const chunkFileName of nestedData.chunk_info.chunk_file_names) { const chunkUrl = `${nestedData.chunk_info.base_download_url}${chunkFileName}`; console.log(`[iRacingSDK] Fetching chunk: ${chunkUrl}`); const chunkResponse = await this.fetchImpl(chunkUrl); if (!chunkResponse.ok) { throw new Error(`Failed to fetch chunk: ${chunkResponse.status}`); } const chunkData = await chunkResponse.json(); chunks2.push(...chunkData); await new Promise((resolve) => setTimeout(resolve, 100)); } console.log(`[iRacingSDK] Combined ${chunks2.length} records from ${nestedData.chunk_info.num_chunks} chunks`); return { ...nestedData, data: chunks2, chunk_info: nestedData.chunk_info }; } return nestedData; } if (!response.chunk_info) { return response; } const chunkInfo = response.chunk_info; const chunks = []; console.log(`[iRacingSDK] Processing chunked response with ${chunkInfo.total_chunks} chunks`); if (chunkInfo.chunk_file_name && chunkInfo.total_chunks === 1) { const chunkUrl = `${chunkInfo.base_download_url}${chunkInfo.chunk_file_name}`; console.log(`[iRacingSDK] Fetching single chunk: ${chunkUrl}`); const chunkResponse = await this.fetchImpl(chunkUrl); if (!chunkResponse.ok) { throw new Error(`Failed to fetch chunk: ${chunkResponse.status}`); } const chunkData = await chunkResponse.json(); chunks.push(...chunkData); } else if (chunkInfo.chunk_file_names && chunkInfo.chunk_file_names.length > 0) { for (const chunkFileName of chunkInfo.chunk_file_names) { const chunkUrl = `${chunkInfo.base_download_url}${chunkFileName}`; console.log(`[iRacingSDK] Fetching chunk: ${chunkUrl}`); const chunkResponse = await this.fetchImpl(chunkUrl); if (!chunkResponse.ok) { throw new Error(`Failed to fetch chunk: ${chunkResponse.status}`); } const chunkData = await chunkResponse.json(); chunks.push(...chunkData); await new Promise((resolve) => setTimeout(resolve, 100)); } } else { for (let i = 0; i < chunkInfo.total_chunks; i++) { const chunkFileName = `${chunkInfo.chunk_file_name.replace(/\.\w+$/, "")}_${i}.json`; const chunkUrl = `${chunkInfo.base_download_url}${chunkFileName}`; console.log(`[iRacingSDK] Fetching chunk ${i + 1}/${chunkInfo.total_chunks}: ${chunkUrl}`); try { const chunkResponse = await this.fetchImpl(chunkUrl); if (!chunkResponse.ok) { console.warn(`[iRacingSDK] Failed to fetch chunk ${i}: ${chunkResponse.status}`); continue; } const chunkData = await chunkResponse.json(); chunks.push(...chunkData); await new Promise((resolve) => setTimeout(resolve, 100)); } catch (error) { console.warn(`[iRacingSDK] Error fetching chunk ${i}: ${error}`); } } } console.log(`[iRacingSDK] Combined ${chunks.length} records from ${chunkInfo.total_chunks} chunks`); return { ...response, data: chunks, chunk_info: chunkInfo }; } /** * Enhanced request method that handles both regular and chunked responses * * @param path - API endpoint path * @param options - Fetch options * @param query - Query parameters * @param handleChunks - Whether to automatically handle chunked responses * @returns Promise resolving to the API response */ async requestWithChunking(path, options = {}, query, handleChunks) { const response = await this.request(path, options, query); const shouldHandleChunks = handleChunks !== void 0 ? handleChunks : this.autoHandleChunkedResponses; if (shouldHandleChunks && (response.chunk_info || response.link)) { return this.handleChunkedResponse(response); } return response; } // === Car Data === /** * Get car assets including images and logos * Image paths are relative to https://images-static.iracing.com/ * * @returns Promise resolving to car assets data */ async getCarAssets() { return this.requestWithChunking("/data/car/assets" /* CAR_ASSETS */); } /** * Get all available cars * * @returns Promise resolving to car data */ async getCars() { return this.requestWithChunking("/data/car/get" /* CAR_GET */); } // === Car Class Data === /** * Get all car classes * * @returns Promise resolving to car class data */ async getCarClasses() { return this.requestWithChunking("/data/carclass/get" /* CARCLASS_GET */); } // === Constants === /** * Get track categories (constant data) * * @returns Promise resolving to category data */ async getCategories() { return this.request("/data/constants/categories" /* CONSTANTS_CATEGORIES */); } /** * Get divisions (constant data) * * @returns Promise resolving to division data */ async getDivisions() { return this.request("/data/constants/divisions" /* CONSTANTS_DIVISIONS */); } /** * Get event types (constant data) * * @returns Promise resolving to event type data */ async getEventTypes() { return this.request("/data/constants/event_types" /* CONSTANTS_EVENT_TYPES */); } // === Driver Stats by Category === /** * Get driver stats for oval category * * @returns Promise resolving to oval driver stats */ async getDriverStatsOval() { return this.requestWithChunking("/data/driver_stats_by_category/oval" /* DRIVER_STATS_OVAL */); } /** * Get driver stats for sports car category * * @returns Promise resolving to sports car driver stats */ async getDriverStatsSportsCar() { return this.requestWithChunking("/data/driver_stats_by_category/sports_car" /* DRIVER_STATS_SPORTS_CAR */); } /** * Get driver stats for formula car category * * @returns Promise resolving to formula car driver stats */ async getDriverStatsFormulaCar() { return this.requestWithChunking("/data/driver_stats_by_category/formula_car" /* DRIVER_STATS_FORMULA_CAR */); } /** * Get driver stats for road category * * @returns Promise resolving to road driver stats */ async getDriverStatsRoad() { return this.requestWithChunking("/data/driver_stats_by_category/road" /* DRIVER_STATS_ROAD */); } /** * Get driver stats for dirt oval category * * @returns Promise resolving to dirt oval driver stats */ async getDriverStatsDirtOval() { return this.requestWithChunking("/data/driver_stats_by_category/dirt_oval" /* DRIVER_STATS_DIRT_OVAL */); } /** * Get driver stats for dirt road category * * @returns Promise resolving to dirt road driver stats */ async getDriverStatsDirtRoad() { return this.requestWithChunking("/data/driver_stats_by_category/dirt_road" /* DRIVER_STATS_DIRT_ROAD */); } // === Hosted Sessions === /** * Get hosted sessions that can be joined as driver or spectator * Also includes non-league pending sessions for the user * * @param params - Optional parameters to filter sessions * @returns Promise resolving to hosted session data */ async getHostedCombinedSessions(params) { if (params) { const parsed = HostedCombinedSessionsParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; } return this.requestWithChunking("/data/hosted/combined_sessions" /* HOSTED_COMBINED_SESSIONS */, {}, params); } /** * Get hosted sessions that can be joined as driver * Without spectator and non-league pending sessions * * @returns Promise resolving to hosted session data */ async getHostedSessions() { return this.requestWithChunking("/data/hosted/sessions" /* HOSTED_SESSIONS */); } // === League Data === /** * Get customer league sessions * * @param params - Optional parameters to filter sessions * @returns Promise resolving to league session data */ async getLeagueCustSessions(params) { if (params) { const parsed = LeagueCustLeagueSessionsParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; } return this.request("/data/league/cust_league_sessions" /* LEAGUE_CUST_LEAGUE_SESSIONS */, {}, params); } /** * Search league directory * * @param params - Optional search parameters * @returns Promise resolving to league directory data */ async getLeagueDirectory(params) { if (params) { const parsed = LeagueDirectoryParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; } return this.requestWithChunking("/data/league/directory" /* LEAGUE_DIRECTORY */, {}, params); } /** * Get league information * * @param params - League parameters including league ID * @returns Promise resolving to league data */ async getLeague(params) { const parsed = LeagueGetParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.request("/data/league/get" /* LEAGUE_GET */, {}, params); } /** * Get league points systems * * @param params - Parameters including league ID * @returns Promise resolving to points system data */ async getLeaguePointsSystems(params) { const parsed = LeaguePointsSystemsParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.request("/data/league/get_points_systems" /* LEAGUE_GET_POINTS_SYSTEMS */, {}, params); } /** * Get league membership information * * @param params - Optional membership parameters * @returns Promise resolving to membership data */ async getLeagueMembership(params) { if (params) { const parsed = LeagueMembershipParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; } return this.request("/data/league/membership" /* LEAGUE_MEMBERSHIP */, {}, params); } /** * Get league roster * * @param params - Parameters including league ID * @returns Promise resolving to roster data */ async getLeagueRoster(params) { const parsed = LeagueRosterParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.request("/data/league/roster" /* LEAGUE_ROSTER */, {}, params); } /** * Get league seasons * * @param params - Parameters including league ID * @returns Promise resolving to season data */ async getLeagueSeasons(params) { const parsed = LeagueSeasonsParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.request("/data/league/seasons" /* LEAGUE_SEASONS */, {}, params); } /** * Get league season standings * * @param params - Parameters including league and season IDs * @returns Promise resolving to standings data */ async getLeagueSeasonStandings(params) { const parsed = LeagueSeasonStandingsParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.requestWithChunking("/data/league/season_standings" /* LEAGUE_SEASON_STANDINGS */, {}, params); } /** * Get league season sessions * * @param params - Parameters including league and season IDs * @returns Promise resolving to session data */ async getLeagueSeasonSessions(params) { const parsed = LeagueSeasonSessionsParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.request("/data/league/season_sessions" /* LEAGUE_SEASON_SESSIONS */, {}, params); } // === Lookup Data === /** * Get countries lookup data * * @returns Promise resolving to country data */ async getLookupCountries() { return this.requestWithChunking("/data/lookup/countries" /* LOOKUP_COUNTRIES */); } /** * Search for drivers * * @param params - Search parameters including search term * @returns Promise resolving to driver search results */ async getLookupDrivers(params) { const parsed = LookupDriversParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.requestWithChunking("/data/lookup/drivers" /* LOOKUP_DRIVERS */, {}, params); } /** * Get flairs lookup data * Icons are from https://github.com/lipis/flag-icons/ * * @returns Promise resolving to flair data */ async getLookupFlairs() { return this.requestWithChunking("/data/lookup/flairs" /* LOOKUP_FLAIRS */); } /** * Get general lookup data * * @returns Promise resolving to lookup data */ async getLookupGet() { return this.requestWithChunking("/data/lookup/get" /* LOOKUP_GET */); } /** * Get licenses lookup data * * @returns Promise resolving to license data */ async getLookupLicenses() { return this.requestWithChunking("/data/lookup/licenses" /* LOOKUP_LICENSES */); } // === Member Data === /** * Get member awards * * @param params - Optional parameters including customer ID * @returns Promise resolving to award data */ async getMemberAwards(params) { if (params) { const parsed = MemberAwardsParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; } return this.request("/data/member/awards" /* MEMBER_AWARDS */, {}, params); } /** * Get member award instances * * @param params - Parameters including award ID * @returns Promise resolving to award instance data */ async getMemberAwardInstances(params) { const parsed = MemberAwardInstancesParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.request("/data/member/award_instances" /* MEMBER_AWARD_INSTANCES */, {}, params); } /** * Get member chart data * * @param params - Parameters including category and chart type * @returns Promise resolving to chart data */ async getMemberChartData(params) { const parsed = MemberChartDataParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.request("/data/member/chart_data" /* MEMBER_CHART_DATA */, {}, params); } /** * Get member information by customer IDs * * @param params - Parameters including customer IDs * @returns Promise resolving to member data */ async getMembers(params) { const parsed = MemberGetParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.requestWithChunking("/data/member/get" /* MEMBER_GET */, {}, params); } /** * Get authenticated member information * * @returns Promise resolving to member info */ async getMemberInfo() { return this.requestWithChunking("/data/member/info" /* MEMBER_INFO */); } /** * Get member participation credits * * @returns Promise resolving to participation credit data */ async getMemberParticipationCredits() { return this.request("/data/member/participation_credits" /* MEMBER_PARTICIPATION_CREDITS */); } /** * Get member profile * * @param params - Optional parameters including customer ID * @returns Promise resolving to profile data */ async getMemberProfile(params) { if (params) { const parsed = MemberProfileParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; } return this.requestWithChunking("/data/member/profile" /* MEMBER_PROFILE */, {}, params); } // === Results Data === /** * Get results for a subsession * * @param params - Parameters including subsession ID * @returns Promise resolving to result data */ async getResults(params) { const parsed = ResultsGetParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.request("/data/results/get" /* RESULTS_GET */, {}, params); } /** * Get event log for a subsession * * @param params - Parameters including subsession and session number * @returns Promise resolving to event log data */ async getResultsEventLog(params) { const parsed = EventLogParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.request("/data/results/event_log" /* RESULTS_EVENT_LOG */, {}, params); } /** * Get lap chart data for a subsession * * @param params - Parameters including subsession and session number * @returns Promise resolving to lap chart data */ async getResultsLapChartData(params) { const parsed = LapChartDataParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.request("/data/results/lap_chart_data" /* RESULTS_LAP_CHART_DATA */, {}, params); } /** * Get lap data for a subsession * * @param params - Parameters including subsession and session number * @returns Promise resolving to lap data */ async getResultsLapData(params) { const parsed = LapDataParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.request("/data/results/lap_data" /* RESULTS_LAP_DATA */, {}, params); } /** * Search hosted and league session results * Maximum time frame of 90 days * * @param params - Search parameters * @returns Promise resolving to hosted session results */ async getResultsSearchHosted(params) { const parsed = ResultsSearchHostedParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.requestWithChunking("/data/results/search_hosted" /* RESULTS_SEARCH_HOSTED */, {}, params); } /** * Search official series results * Maximum time frame of 90 days * * @param params - Search parameters * @returns Promise resolving to series results */ async getResultsSearchSeries(params) { const parsed = ResultsSearchSeriesParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.requestWithChunking("/data/results/search_series" /* RESULTS_SEARCH_SERIES */, {}, params); } /** * Get season results * * @param params - Parameters including season ID * @returns Promise resolving to season results */ async getResultsSeasonResults(params) { const parsed = SeasonResultsParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.requestWithChunking("/data/results/season_results" /* RESULTS_SEASON_RESULTS */, {}, params); } // === Season Data === /** * Get season list * * @param params - Parameters including season year and quarter * @returns Promise resolving to season list */ async getSeasonList(params) { const parsed = SeasonListParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.requestWithChunking("/data/season/list" /* SEASON_LIST */, {}, params); } /** * Get season race guide * * @param params - Optional parameters for filtering * @returns Promise resolving to race guide data */ async getSeasonRaceGuide(params) { if (params) { const parsed = SeasonRaceGuideParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; } return this.requestWithChunking("/data/season/race_guide" /* SEASON_RACE_GUIDE */, {}, params); } /** * Get spectator subsession IDs * * @param params - Optional parameters for filtering * @returns Promise resolving to spectator subsession IDs */ async getSeasonSpectatorSubsessionIds(params) { if (params) { const parsed = SeasonSpectatorSubsessionIdsParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; } return this.request("/data/season/spectator_subsessionids" /* SEASON_SPECTATOR_SUBSESSIONIDS */, {}, params); } /** * Get detailed spectator subsession information * * @param params - Optional parameters for filtering * @returns Promise resolving to detailed spectator subsession data */ async getSeasonSpectatorSubsessionIdsDetail(params) { if (params) { const parsed = SeasonSpectatorSubsessionIdsDetailParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; } return this.request("/data/season/spectator_subsessionids_detail" /* SEASON_SPECTATOR_SUBSESSIONIDS_DETAIL */, {}, params); } // === Series Data === /** * Get series assets including images and logos * Image paths are relative to https://images-static.iracing.com/ * * @returns Promise resolving to series assets */ async getSeriesAssets() { return this.requestWithChunking("/data/series/assets" /* SERIES_ASSETS */); } /** * Get all series * * @returns Promise resolving to series data */ async getSeries() { return this.requestWithChunking("/data/series/get" /* SERIES_GET */); } /** * Get all seasons for a series * Filter by official:true for seasons with standings * * @param params - Parameters including series ID * @returns Promise resolving to past seasons data */ async getSeriesPastSeasons(params) { const parsed = SeriesPastSeasonsParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.request("/data/series/past_seasons" /* SERIES_PAST_SEASONS */, {}, params); } /** * Get series seasons * * @param params - Optional parameters for filtering * @returns Promise resolving to series seasons */ async getSeriesSeasons(params) { if (params) { const parsed = SeriesSeasonsParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; } return this.requestWithChunking("/data/series/seasons" /* SERIES_SEASONS */, {}, params); } /** * Get series season list * * @param params - Optional parameters for filtering * @returns Promise resolving to series season list */ async getSeriesSeasonList(params) { if (params) { const parsed = SeriesSeasonListParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; } return this.requestWithChunking("/data/series/season_list" /* SERIES_SEASON_LIST */, {}, params); } /** * Get series season schedule * * @param params - Parameters including season ID * @returns Promise resolving to season schedule */ async getSeriesSeasonSchedule(params) { const parsed = SeriesSeasonScheduleParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.request("/data/series/season_schedule" /* SERIES_SEASON_SCHEDULE */, {}, params); } /** * Get series stats * Filter by official:true for series with standings * * @returns Promise resolving to series stats */ async getSeriesStats() { return this.requestWithChunking("/data/series/stats_series" /* SERIES_STATS_SERIES */); } // === Stats Data === /** * Get member best times * * @param params - Optional parameters including customer and car IDs * @returns Promise resolving to member best times */ async getStatsMemberBests(params) { if (params) { const parsed = StatsMemberBestsParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; } return this.requestWithChunking("/data/stats/member_bests" /* STATS_MEMBER_BESTS */, {}, params); } /** * Get member career statistics * * @param params - Optional parameters including customer ID * @returns Promise resolving to member career data */ async getStatsMemberCareer(params) { if (params) { const parsed = StatsMemberCareerParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; } return this.requestWithChunking("/data/stats/member_career" /* STATS_MEMBER_CAREER */, {}, params); } /** * Get member division standings * Always for the authenticated member * * @param params - Parameters including season and event type * @returns Promise resolving to member division data */ async getStatsMemberDivision(params) { const parsed = StatsMemberDivisionParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.request("/data/stats/member_division" /* STATS_MEMBER_DIVISION */, {}, params); } /** * Get member recap statistics * * @param params - Optional parameters including customer ID and time period * @returns Promise resolving to member recap data */ async getStatsMemberRecap(params) { if (params) { const parsed = StatsMemberRecapParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; } return this.requestWithChunking("/data/stats/member_recap" /* STATS_MEMBER_RECAP */, {}, params); } /** * Get member recent races * * @param params - Optional parameters including customer ID * @returns Promise resolving to recent races data */ async getStatsMemberRecentRaces(params) { if (params) { const parsed = StatsMemberRecentRacesParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; } return this.requestWithChunking("/data/stats/member_recent_races" /* STATS_MEMBER_RECENT_RACES */, {}, params); } /** * Get member summary statistics * * @param params - Optional parameters including customer ID * @returns Promise resolving to member summary data */ async getStatsMemberSummary(params) { if (params) { const parsed = StatsMemberSummaryParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; } return this.requestWithChunking("/data/stats/member_summary" /* STATS_MEMBER_SUMMARY */, {}, params); } /** * Get member yearly statistics * * @param params - Optional parameters including customer ID * @returns Promise resolving to yearly statistics */ async getStatsMemberYearly(params) { if (params) { const parsed = StatsMemberYearlyParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; } return this.requestWithChunking("/data/stats/member_yearly" /* STATS_MEMBER_YEARLY */, {}, params); } /** * Get season driver standings * * @param params - Parameters including season and car class IDs * @returns Promise resolving to driver standings */ async getStatsSeasonDriverStandings(params) { const parsed = StatsSeasonDriverStandingsParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.requestWithChunking("/data/stats/season_driver_standings" /* STATS_SEASON_DRIVER_STANDINGS */, {}, params); } /** * Get season supersession standings * * @param params - Parameters including season and car class IDs * @returns Promise resolving to supersession standings */ async getStatsSeasonSupersessionStandings(params) { const parsed = StatsSeasonSupersessionStandingsParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.requestWithChunking("/data/stats/season_supersession_standings" /* STATS_SEASON_SUPERSESSION_STANDINGS */, {}, params); } /** * Get season team standings * * @param params - Parameters including season and car class IDs * @returns Promise resolving to team standings */ async getStatsSeasonTeamStandings(params) { const parsed = StatsSeasonTeamStandingsParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.requestWithChunking("/data/stats/season_team_standings" /* STATS_SEASON_TEAM_STANDINGS */, {}, params); } /** * Get season time trial standings * * @param params - Parameters including season and car class IDs * @returns Promise resolving to time trial standings */ async getStatsSeasonTTStandings(params) { const parsed = StatsSeasonTTStandingsParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.requestWithChunking("/data/stats/season_tt_standings" /* STATS_SEASON_TT_STANDINGS */, {}, params); } /** * Get season time trial results * * @param params - Parameters including season, car class, and race week * @returns Promise resolving to time trial results */ async getStatsSeasonTTResults(params) { const parsed = StatsSeasonTTResultsParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.requestWithChunking("/data/stats/season_tt_results" /* STATS_SEASON_TT_RESULTS */, {}, params); } /** * Get season qualifying results * * @param params - Parameters including season, car class, and race week * @returns Promise resolving to qualifying results */ async getStatsSeasonQualifyResults(params) { const parsed = StatsSeasonQualifyResultsParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.requestWithChunking("/data/stats/season_qualify_results" /* STATS_SEASON_QUALIFY_RESULTS */, {}, params); } /** * Get world records for a car and track combination * * @param params - Parameters including car and track IDs * @returns Promise resolving to world records */ async getStatsWorldRecords(params) { const parsed = StatsWorldRecordsParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.request("/data/stats/world_records" /* STATS_WORLD_RECORDS */, {}, params); } // === Team Data === /** * Get team information * * @param params - Parameters including team ID * @returns Promise resolving to team data */ async getTeam(params) { const parsed = TeamGetParamsSchema.safeParse(params); if (!parsed.success) throw parsed.error; return this.request("/data/team/get" /* TEAM_GET */, {}, params); } // === Time Attack Data === /** * Get time attack member season results * Results for the authenticated member, if any * * @param params - Parameters including competition season ID * @returns Promise resolving to time attack results */ async getTimeAttackMemberSeasonResults(params) { const parsed = TimeAttackMemberSeasonResultsParamsSchema.safeParse(params); if (!parsed.success) throw parsed.err