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
JavaScript
// 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