UNPKG

iracing-data-sdk

Version:

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

671 lines (515 loc) 21.8 kB
# iRacing Data API SDK A comprehensive TypeScript SDK for the iRacing Data API with **complete coverage of all 76+ documented endpoints**. This professional-grade SDK provides type-safe access to all iRacing data including cars, tracks, series, results, statistics, leagues, and more. ## Features -**Complete API Coverage**: All 76+ iRacing Data API endpoints implemented (100% coverage) -**Strict TypeScript Support**: Full type safety with comprehensive return types for all endpoints -**Chunked Data Handling**: Automatic fetching and combining of large datasets from Amazon S3 -**Runtime Validation**: Zod schema validation for parameters and responses -**Authentication**: Handles iRacing SHA256 authentication with automatic session management -**Rate Limiting**: Automatic rate limit detection and intelligent waiting -**Modern Architecture**: ESM and CommonJS support, built with tsup and modern tooling -**Comprehensive Testing**: Complete test suite with Vitest including chunked response tests -**Professional Quality**: Clean architecture with proper error handling and logging -**Cross-Platform**: Works in both Node.js and browser environments ## Installation ```bash # npm npm install iracing-data-api # yarn yarn add iracing-data-api # pnpm pnpm add iracing-data-api ``` ### Requirements - Node.js 16.0.0 or higher - TypeScript 4.5.0 or higher (for TypeScript projects) ## Quick Start ```typescript import { iRacingSDK } from 'iracing-data-api'; const sdk = new iRacingSDK(); // Authenticate with your iRacing credentials await sdk.authenticate({ email: 'your-email@example.com', password: 'your-password' }); // Get all cars with full type safety const cars = await sdk.getCars(); // Returns CarsResponse console.log(`Found ${cars.cars.length} cars`); // Get your member information const memberInfo = await sdk.getMemberInfo(); // Returns MemberInfoResponse console.log(`Welcome, ${memberInfo.display_name}!`); // Get your recent races const recentRaces = await sdk.getStatsMemberRecentRaces(); // Returns StatsMemberRecentRacesResponse console.log(`You have ${recentRaces.races.length} recent races`); // Search for series results (supports chunked data automatically) const results = await sdk.getResultsSearchSeries({ season_year: 2024, season_quarter: 1, cust_id: memberInfo.cust_id }); // Returns ResultsSearchResponse console.log(`Found ${results.data.length} race results`); ``` ### CommonJS Usage ```javascript const { iRacingSDK } = require('iracing-data-api'); const sdk = new iRacingSDK(); // Same API as above sdk.authenticate({ email: 'your-email', password: 'your-password' }) .then(() => sdk.getCars()) .then(cars => console.log('Cars:', cars)); ``` ## Authentication The SDK handles iRacing's SHA256 authentication automatically with session management. You only need to authenticate once per session: ```typescript const sdk = new iRacingSDK(); try { const authResult = await sdk.authenticate({ email: 'your-email@example.com', password: 'your-password' }); console.log('Authenticated successfully:', authResult); // Now you can make API calls const memberInfo = await sdk.getMemberInfo(); } catch (error) { console.error('Authentication failed:', error.message); } ``` ### Environment Variables For security, consider using environment variables: ```typescript import { iRacingSDK } from 'iracing-data-api'; const sdk = new iRacingSDK(); await sdk.authenticate({ email: process.env.IRACING_EMAIL!, password: process.env.IRACING_PASSWORD! }); ``` ## TypeScript Support The SDK provides **strict type safety** with comprehensive TypeScript support: ### Fully Typed Responses Every API method returns properly typed responses with IntelliSense support: ```typescript // All methods have specific return types const cars: CarsResponse = await sdk.getCars(); const memberInfo: MemberInfoResponse = await sdk.getMemberInfo(); const results: ResultsSearchResponse = await sdk.getResultsSearchSeries({ season_year: 2024, season_quarter: 1 }); // Access typed properties with full autocomplete console.log(cars.cars[0].car_name); // string console.log(memberInfo.display_name); // string console.log(results.data[0].series_name); // string ``` ### Parameter Validation All parameters are validated at both compile-time and runtime: ```typescript // TypeScript catches parameter errors await sdk.getResults({ subsession_id: "invalid" }); // Error: Expected number // Runtime validation with helpful messages await sdk.getLeague({ league_id: 123, include_licenses: true }); // ✅ Valid ``` ### Comprehensive Type Definitions The SDK includes 100+ TypeScript interfaces covering: - **Request Parameters**: All endpoint parameters with proper types - **Response Types**: Complete response structures for all 76+ endpoints - **Data Models**: Car, Track, Member, League, and other data structures - **API Enums**: Categories, divisions, event types, and more ## Automatic Data Fetching The iRacing API often returns links to actual data stored on Amazon S3 (for large datasets) or as CSV files (for driver statistics). The SDK automatically fetches and returns the actual data, not just the links: ### CSV Data Handling Driver statistics endpoints return CSV data that is automatically fetched and returned as strings: ```typescript // These endpoints return CSV data strings, not just links const ovalStats = await sdk.getDriverStatsOval(); // Returns CSV string const roadStats = await sdk.getDriverStatsRoad(); // Returns CSV string // Parse CSV data as needed for your application const lines = ovalStats.split('\n'); const headers = lines[0].split(','); console.log('CSV Headers:', headers); ``` ## Chunked Data Handling Some iRacing API endpoints return large datasets that are split into chunks stored on Amazon S3. The SDK automatically handles this complexity: ### Automatic Chunk Processing ```typescript // Large datasets are automatically fetched and combined const standings = await sdk.getStatsSeasonDriverStandings({ season_id: 3840, car_class_id: 1 }); // The SDK automatically: // 1. Detects chunked responses // 2. Fetches all chunks from S3 // 3. Combines data into a single response console.log(`Found ${standings.standings.length} drivers`); ``` ### Chunked Endpoints The following endpoints support automatic chunked data handling: **Search Results (High Priority)**: - `getResultsSearchHosted()` - Hosted/league session results (90-day max) - `getResultsSearchSeries()` - Official series results (90-day max) **Statistics & Standings (Medium Priority)**: - `getStatsSeasonDriverStandings()` - Season driver standings - `getStatsSeasonSupersessionStandings()` - Supersession standings - `getStatsSeasonTeamStandings()` - Team standings - `getStatsSeasonTTStandings()` - Time trial standings - `getStatsSeasonTTResults()` - Time trial results - `getStatsSeasonQualifyResults()` - Qualifying results - `getResultsSeasonResults()` - Season results - `getLeagueSeasonStandings()` - League standings ### Configuration Options Control chunking behavior per SDK instance: ```typescript // Enable automatic chunking (default) const sdk = new iRacingSDK({ autoHandleChunkedResponses: true }); // Disable automatic chunking (get raw responses) const sdk = new iRacingSDK({ autoHandleChunkedResponses: false }); // With chunking disabled, you get raw responses with chunk_info const response = await sdk.getResultsSearchSeries({ season_year: 2024, season_quarter: 1 }); if (response.chunk_info) { console.log(`Data is chunked: ${response.chunk_info.total_chunks} chunks`); // Handle chunks manually if needed } ``` ## Complete API Coverage This SDK implements **all 76+ iRacing Data API endpoints** organized by category, providing 100% coverage of the official API specification: ### Car Data (3 endpoints) - `getCars()` - Get all available cars - `getCarAssets()` - Get car images and logos (paths relative to https://images-static.iracing.com/) - `getCarClasses()` - Get all car classes ### Constants (3 endpoints) - `getCategories()` - Get track categories (constant data) - `getDivisions()` - Get license divisions (constant data) - `getEventTypes()` - Get event types (constant data) ### Driver Stats by Category (6 endpoints) - `getDriverStatsOval()` - Oval category driver statistics (returns CSV data) - `getDriverStatsSportsCar()` - Sports car category driver statistics (returns CSV data) - `getDriverStatsFormulaCar()` - Formula car category driver statistics (returns CSV data) - `getDriverStatsRoad()` - Road category driver statistics (returns CSV data) - `getDriverStatsDirtOval()` - Dirt oval category driver statistics (returns CSV data) - `getDriverStatsDirtRoad()` - Dirt road category driver statistics (returns CSV data) ### Hosted Sessions (2 endpoints) - `getHostedCombinedSessions(params?)` - Sessions that can be joined as driver or spectator - `getHostedSessions()` - Sessions that can be joined as driver only ### League Data (9 endpoints) - `getLeague(params)` - Get league information by ID - `getLeagueDirectory(params?)` - Search league directory with filters - `getLeagueCustSessions(params?)` - Get customer league sessions - `getLeaguePointsSystems(params)` - Get league points systems - `getLeagueMembership(params?)` - Get league membership information - `getLeagueRoster(params)` - Get league roster with member details - `getLeagueSeasons(params)` - Get league seasons (active and retired) - `getLeagueSeasonStandings(params)` - Get league season standings - `getLeagueSeasonSessions(params)` - Get league season sessions ### Lookup Data (5 endpoints) - `getLookupCountries()` - Get countries lookup data - `getLookupDrivers(params)` - Search for drivers by name or ID - `getLookupFlairs()` - Get flairs/flags (icons from flag-icons) - `getLookupGet()` - Get general lookup data (weather, license levels) - `getLookupLicenses()` - Get licenses lookup data ### Member Data (7 endpoints) - `getMemberInfo()` - Get authenticated member information - `getMembers(params)` - Get member information by customer IDs - `getMemberAwards(params?)` - Get member awards - `getMemberAwardInstances(params)` - Get specific award instances - `getMemberChartData(params)` - Get member chart data (iRating, TT Rating, License/SR) - `getMemberProfile(params?)` - Get member profile information - `getMemberParticipationCredits()` - Get participation credits for authenticated member ### Results Data (7 endpoints) - `getResults(params)` - Get subsession results if authorized - `getResultsEventLog(params)` - Get event log for a subsession - `getResultsLapChartData(params)` - Get lap chart data for a subsession - `getResultsLapData(params)` - Get lap data for a subsession - `getResultsSearchHosted(params)` - Search hosted and league session results (90 day max) - `getResultsSearchSeries(params)` - Search official series results (90 day max) - `getResultsSeasonResults(params)` - Get season results by season ID ### Season Data (4 endpoints) - `getSeasonList(params)` - Get season list by year and quarter - `getSeasonRaceGuide(params?)` - Get race guide with upcoming sessions - `getSeasonSpectatorSubsessionIds(params?)` - Get spectator subsession IDs - `getSeasonSpectatorSubsessionIdsDetail(params?)` - Get detailed spectator subsession data ### Series Data (7 endpoints) - `getSeries()` - Get all series information - `getSeriesAssets()` - Get series images/logos (paths relative to https://images-static.iracing.com/) - `getSeriesPastSeasons(params)` - Get all seasons for a series - `getSeriesSeasons(params?)` - Get series seasons (active or by year/quarter) - `getSeriesSeasonList(params?)` - Get series season list - `getSeriesSeasonSchedule(params)` - Get season schedule by season ID - `getSeriesStats()` - Get series statistics (filter by official:true for standings) ### Statistics (15 endpoints) - `getStatsMemberBests(params?)` - Get member best times by car - `getStatsMemberCareer(params?)` - Get member career statistics - `getStatsMemberDivision(params)` - Get member division standings (authenticated member only) - `getStatsMemberRecap(params?)` - Get member recap by year/season - `getStatsMemberRecentRaces(params?)` - Get member recent races - `getStatsMemberSummary(params?)` - Get member summary statistics - `getStatsMemberYearly(params?)` - Get member yearly statistics - `getStatsSeasonDriverStandings(params)` - Get season driver standings - `getStatsSeasonSupersessionStandings(params)` - Get season supersession standings - `getStatsSeasonTeamStandings(params)` - Get season team standings - `getStatsSeasonTTStandings(params)` - Get season time trial standings - `getStatsSeasonTTResults(params)` - Get season time trial results - `getStatsSeasonQualifyResults(params)` - Get season qualifying results - `getStatsWorldRecords(params)` - Get world records for car/track combination ### Team Data (1 endpoint) - `getTeam(params)` - Get team information by team ID ### Time Attack (1 endpoint) - `getTimeAttackMemberSeasonResults(params)` - Get time attack results for authenticated member ### Track Data (2 endpoints) - `getTracks()` - Get all tracks information - `getTrackAssets()` - Get track images/logos (paths relative to https://images-static.iracing.com/) ## Advanced Usage ### Custom Configuration ```typescript const sdk = new iRacingSDK({ baseUrl: 'https://members-ng.iracing.com', // Default fetchImpl: customFetch, // Custom fetch implementation }); ``` ### Error Handling ```typescript try { const results = await sdk.getResults({ subsession_id: 12345 }); } catch (error) { if (error.message.includes('HTTP error! status: 401')) { // Handle authentication error await sdk.authenticate({ email, password }); } else { // Handle other errors console.error('API Error:', error); } } ``` ### Rate Limiting The SDK automatically handles rate limiting: ```typescript // The SDK will automatically wait when rate limits are reached const cars = await sdk.getCars(); const tracks = await sdk.getTracks(); const series = await sdk.getSeries(); ``` ### TypeScript Support All methods are fully typed with parameter validation: ```typescript // TypeScript will catch this error await sdk.getResults({ subsession_id: 'invalid' }); // Error: Expected number // Correct usage await sdk.getResults({ subsession_id: 12345 }); // Parameters are validated at runtime using Zod await sdk.getLeague({ league_id: 123, include_licenses: true }); ``` ## Comprehensive Examples ### Member Information and Statistics ```typescript // Get your member information const memberInfo = await sdk.getMemberInfo(); console.log(`Welcome, ${memberInfo.display_name}!`); // Get your recent races const recentRaces = await sdk.getStatsMemberRecentRaces(); console.log(`You have ${recentRaces.length} recent races`); // Get your best times const bestTimes = await sdk.getStatsMemberBests(); console.log(`Personal best times across ${bestTimes.length} cars`); // Get your career statistics const careerStats = await sdk.getStatsMemberCareer(); console.log('Career statistics:', careerStats); // Get your yearly statistics const yearlyStats = await sdk.getStatsMemberYearly(); console.log('Yearly statistics:', yearlyStats); ``` ### Series and Season Data ```typescript // Get all series const allSeries = await sdk.getSeries(); console.log(`Found ${allSeries.length} series`); // Get current season list const currentSeasons = await sdk.getSeasonList({ season_year: 2024, season_quarter: 1 }); // Get race guide (upcoming races) const raceGuide = await sdk.getSeasonRaceGuide(); console.log('Upcoming races:', raceGuide); // Get season standings const standings = await sdk.getStatsSeasonDriverStandings({ season_id: 3840, car_class_id: 1, division: 0 // Division 1 (0-indexed) }); ``` ### Results and Historical Data ```typescript // Search for your recent series results const myResults = await sdk.getResultsSearchSeries({ season_year: 2024, season_quarter: 1, cust_id: memberInfo.cust_id }); // Search for hosted sessions const hostedResults = await sdk.getResultsSearchHosted({ start_range_begin: '2024-01-01T00:00:00Z', finish_range_end: '2024-01-31T23:59:59Z', cust_id: memberInfo.cust_id }); // Get detailed results for a specific subsession const detailedResults = await sdk.getResults({ subsession_id: 12345, include_licenses: true }); // Get lap data for a subsession const lapData = await sdk.getResultsLapData({ subsession_id: 12345, simsession_number: 0, // Main event cust_id: memberInfo.cust_id }); ``` ### League Management ```typescript // Search for leagues const leagues = await sdk.getLeagueDirectory({ search: 'GT3', restrict_to_recruiting: true }); // Get league information const leagueInfo = await sdk.getLeague({ league_id: 123, include_licenses: true }); // Get league roster const roster = await sdk.getLeagueRoster({ league_id: 123, include_licenses: true }); // Get league season standings const leagueStandings = await sdk.getLeagueSeasonStandings({ league_id: 123, season_id: 456 }); ``` ### World Records and Best Times ```typescript // Get world records for a car/track combination const worldRecords = await sdk.getStatsWorldRecords({ car_id: 1, // Car ID track_id: 1, // Track ID season_year: 2024 }); // Get time trial results const ttResults = await sdk.getStatsSeasonTTResults({ season_id: 3840, car_class_id: 1, race_week_num: 0 }); // Get qualifying results const qualResults = await sdk.getStatsSeasonQualifyResults({ season_id: 3840, car_class_id: 1, race_week_num: 0 }); ``` ### Asset Management ```typescript // Get car images and information const carAssets = await sdk.getCarAssets(); const cars = await sdk.getCars(); // Get track images and information const trackAssets = await sdk.getTrackAssets(); const tracks = await sdk.getTracks(); // Get series images and information const seriesAssets = await sdk.getSeriesAssets(); const series = await sdk.getSeries(); // Note: Image paths are relative to https://images-static.iracing.com/ ``` ## Development ### Setup ```bash git clone https://github.com/your-org/iracing-data-api.git cd iracing-data-api npm install ``` ### Available Scripts ```bash # Development npm run dev # Watch mode building with tsup npm run build # Build for production (generates CJS, ESM, and .d.ts files) npm run typecheck # TypeScript type checking # Testing npm run test # Run tests with Vitest npm run test:watch # Watch mode testing npm run test:coverage # Generate coverage report with @vitest/coverage-v8 npm run test:ui # Visual test UI with @vitest/ui npm run test:endpoints # Test all 76+ API endpoints npm run test:chunked # Comprehensive chunked data endpoint testing npm run test:chunked-simple # Simple focused chunked data test npm run test:chunked-basic # Basic chunked test with better error handling # Quality & Linting npm run lint # ESLint checking npm run lint:fix # Fix ESLint issues automatically # Documentation npm run docs # Generate API documentation with TypeDoc # Publishing npm run prepare # Runs automatically before publishing npm run prepublishOnly # Runs tests, typecheck, and lint before publishing npm run release # Build and publish to npm ``` ### Project Structure ``` src/ ├── index.ts # Main entry point and exports ├── iracingApi.ts # Main SDK class with all API methods ├── endpoints.ts # API endpoints enum ├── types.ts # TypeScript types and Zod schemas └── __tests__/ └── iracingApi.test.ts # Comprehensive test suite ``` ### Building The project uses `tsup` for building: ```bash npm run build ``` This generates: - `dist/index.js` - CommonJS build - `dist/index.mjs` - ESM build - `dist/index.d.ts` - TypeScript declarations ### Testing Tests are written with Vitest: ```bash npm run test:coverage ``` ## Contributing 1. Fork the repository 2. Create a feature branch 3. Make your changes 4. Add tests for new functionality 5. Ensure all tests pass 6. Submit a pull request ## Key Features Summary - **Complete Coverage**: All 76+ official iRacing Data API endpoints implemented - **Strict Type Safety**: Comprehensive TypeScript support with 100+ response interfaces - **Chunked Data Handling**: Automatic fetching and combining of large datasets from S3 - **Runtime Validation**: Full parameter and response validation using Zod schemas - **Modern Architecture**: Clean, maintainable code with proper separation of concerns - **Authentication**: Handles SHA256 password hashing and session management - **Rate Limiting**: Automatic detection and intelligent waiting - **Error Handling**: Comprehensive error handling with meaningful messages - **Testing**: Complete test suite with mocking, chunking tests, and coverage reporting - **Documentation**: Extensive TSDoc/JSDoc comments throughout - **Dual Module Support**: Both ESM and CommonJS builds included - **Cross-Platform**: Works in Node.js and browser environments ## Support - **Issues**: [GitHub Issues](https://github.com/your-org/iracing-data-api/issues) - **Documentation**: [API Documentation](https://your-org.github.io/iracing-data-api/) - **iRacing API**: [Official iRacing Data API](https://forums.iracing.com/discussion/15068/general-availability-of-data-api/) ## Changelog See [CHANGELOG.md](CHANGELOG.md) for version history. ## License MIT License. See [LICENSE](LICENSE) for details. --- **Note**: This is an unofficial SDK and is not affiliated with iRacing.com Motorsport Simulations, LLC.