UNPKG

@matveymirman/iracing-node-api

Version:
180 lines (179 loc) 6.54 kB
import Axios from 'axios'; import { wrapper } from 'axios-cookiejar-support'; import { SHA256, enc } from 'crypto-js'; import StatusCodes from 'http-status-codes'; import { CookieJar } from 'tough-cookie'; import UserAgent from 'user-agents'; class IracingClient { authenticated; apiClient; email; password; interval; options; agent; constructor(email, password, options = { shouldUseInterval: true }) { if (!email || !password) { throw new Error(`Iracing Api: Unable to initialze client. Missing email or password`); } this.email = email; this.password = password; this.options = options; this.authenticated = false; this.agent = new UserAgent({ platform: 'Win32' }); this.apiClient = wrapper(Axios.create({ jar: new CookieJar(), withCredentials: true, baseURL: 'https://members-ng.iracing.com', headers: { 'User-Agent': this.agent.toString() } })); this.signIn(); this.interval = null; this.handleError(); } handleError() { this.apiClient.interceptors.response.use(async (config) => { if (config.status === StatusCodes.UNAUTHORIZED || config.status === StatusCodes.FORBIDDEN) { this.authenticated = false; this.signIn(); } return config; }, (error) => { if (error.status === StatusCodes.UNAUTHORIZED || error.status === StatusCodes.FORBIDDEN) { this.authenticated = false; this.signIn(); } }); } encodeCredentials(email, password) { const hash = SHA256(password + email.toLowerCase()); return enc.Base64.stringify(hash); } async signIn() { const hash = this.encodeCredentials(this.email, this.password); try { const res = await this.apiClient.post('/auth', { email: this.email, password: hash }); if (res?.data?.authcode) { this.authenticated = true; } } catch (error) { throw error; } } async getResource(resourceLink = '') { if (!resourceLink) { throw new Error('Missing resource url'); } try { const res = await this.apiClient.get(resourceLink); return res.data; } catch (error) { throw error; } } async getCarAssets() { try { await this.signIn(); const res = await this.apiClient.get('/data/car/assets'); const assets = await this.getResource(res.data?.link); return assets; } catch (error) { throw error; } } async getTrackData() { await this.signIn(); const res = await this.apiClient.get('/data/track/get'); const trackData = await this.getResource(res.data?.link); return trackData; } async getTrackAssets() { await this.signIn(); const res = await this.apiClient.get('/data/track/assets'); const data = await this.getResource(res.data?.link); return data; } async getCarData() { await this.signIn(); const res = await this.apiClient.get('/data/car/get'); const carData = await this.getResource(res.data?.link); return carData; } async getSessionResults(subsessionId) { await this.signIn(); const res = await this.apiClient.get(`/data/results/get?subsession_id=${subsessionId}`); const results = await this.getResource(res.data?.link); return results; } async getSessionLogs(subsessionId, sessionNumber) { await this.signIn(); const res = await this.apiClient.get(`/data/results/event_log?subsession_id=${subsessionId}&simsession_number=${sessionNumber}`); const logs = await this.getResource(res.data?.link); return logs; } async getLapChartData(subsessionId, sessionNumber) { await this.signIn(); const res = await this.apiClient.get(`/data/results/lap_chart_data?subsession_id=${subsessionId}&simsession_number=${sessionNumber}`); const signedData = await this.getResource(res.data?.link); return signedData; } async getMemberStatsHistory(category, chart_type, memberId) { await this.signIn(); const types = { iRating: 1, 'tt-rating': 2, sr: 3 }; const categories = { oval: 1, road: 2, 'dirt-oval': 3, dirt: 4 }; const res = await this.apiClient.get(`/data/member/chart_data?category_id=${categories[category]}&chart_type=${types[chart_type]}&cust_id=${memberId}`); const signedResponse = await this.getResource(res.data?.link); return signedResponse; } async getMember(memberId) { await this.signIn(); const res = await this.apiClient.get(`data/member/get?cust_ids=${memberId}`); const signedResponse = await this.getResource(res.data?.link); return (signedResponse.members.find((member) => member.cust_id === memberId) ?? null); } async getLeague(leagueId) { await this.signIn(); const res = await this.apiClient.get(`data/league/get?league_id=${leagueId}`); const signedData = await this.getResource(res.data?.link); return signedData; } async getLeagueSeasons(leagueId, getRetired) { await this.signIn(); const res = await this.apiClient.get(`data/league/seasons?league_id=${leagueId}&retired=${getRetired || false}`); const signedData = await this.getResource(res.data?.link); return signedData; } async getLeagueRoster(leagueId) { await this.signIn(); const res = await this.apiClient.get(`data/league/roster?league_id=${leagueId}`); const signedData = await this.getResource(res.data?.data_url); return signedData; } async getLeagueSeasonSesssions(leagueId, seasonId) { await this.signIn(); const res = await this.apiClient.get(`data/league/season_sessions?league_id=${leagueId}&season_id=${seasonId}`); const signedData = await this.getResource(res.data?.link); return signedData; } } export default IracingClient;