UNPKG

rocket-league-stats

Version:
1 lines 19.5 kB
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { AllStats, GenericOptions, InitializeOptions, OverviewStats, Platform, PlaylistStats, TPlaylists, Userinfo } from './types/internal';\r\nimport type { SegmentOverviewStats, SegmentPlaylistStats, Segments, SegmentsPlaylist, TrackerResponse } from './types/tracker';\r\n\r\nexport type { AllStats, GenericOptions, InitializeOptions, OverviewStats, Platform, PlaylistStats, TPlaylists, Userinfo };\r\n\r\nexport const PLATFORM = {\r\n Steam: 'steam',\r\n Epic: 'epic',\r\n Playstation: 'psn',\r\n Xbox: 'xbl',\r\n} as const;\r\n\r\nconst BASE_URL = `https://api.tracker.gg/api/v2/rocket-league/standard/profile/`;\r\n\r\n/**\r\n * Get the roman numeral of the division number\r\n * @param num - The number to convert to roman numeral\r\n * @returns The roman numeral of the number\r\n * @example\r\n * getRomanNumeral(1) // 'I'\r\n * getRomanNumeral(2) // 'II'\r\n */\r\nexport const getRomanNumeral = (num: number): string => {\r\n if (num > 4 || num < 1) return '';\r\n const roman = ['I', 'II', 'III', 'IV'];\r\n return roman[num - 1];\r\n};\r\n\r\n/**\r\n * Fetch data from the tracker network\r\n * @param url - The url to fetch the data from tracker network\r\n * @returns The user data from the tracker network\r\n * @example\r\n * fetchData('https://api.tracker.gg/api/v2/rocket-league/standard/profile/steam/76561198126577610')\r\n */\r\nconst fetchData = (url: string): Promise<TrackerResponse> =>\r\n new Promise((resolve, reject) => {\r\n fetch(url, {\r\n method: 'GET',\r\n headers: {\r\n Origin: 'https://rocketleague.tracker.network',\r\n Referer: 'https://rocketleague.tracker.network/',\r\n },\r\n })\r\n .then((res) => res.json())\r\n .then((json) => resolve(json))\r\n .catch((err) => reject(err));\r\n });\r\n\r\n/**\r\n * Rocket League Stats API\r\n * @param platform - The platform of the user\r\n * @param username - The username of the user\r\n * @param options - The options for the API\r\n * @example\r\n * const api = new API(PLATFORM.EPIC, 'lil McNugget')\r\n * const data = await api.fetchUser()\r\n * console.log(data)\r\n * @throws {Error} - If the user is not found\r\n * @throws {Error} - If the user data is not found\r\n */\r\nexport class API {\r\n private platform: Platform;\r\n private username: string;\r\n private raw: TrackerResponse | undefined = undefined;\r\n private expiresAfter: number = 1000 * 60; // 1 minute\r\n private lastFetch: number = 0;\r\n\r\n constructor(platform: Platform, username: string, options?: InitializeOptions) {\r\n this.platform = platform;\r\n this.username = username;\r\n if (options?.expiresAfter) this.expiresAfter = options.expiresAfter;\r\n }\r\n\r\n /**\r\n * Fetch the user data from the tracker network\r\n * @returns The user data from the tracker network\r\n * @example\r\n * const api = new API(PLATFORM.EPIC, 'lil McNugget')\r\n * const data = await api.fetchUser()\r\n * console.log(data)\r\n * @throws {Error} - If the user is not found\r\n * @throws {Error} - If the user data is not found\r\n *\r\n */\r\n public async fetchUser() {\r\n this.raw = await fetchData(`${BASE_URL}${this.platform}/${this.username}`);\r\n if ((this.raw.errors?.length ?? 0) > 0) throw new Error(this.raw?.errors?.[0]?.message);\r\n this.lastFetch = Date.now();\r\n return this.raw;\r\n }\r\n /**\r\n * Get the overview stats of the user\r\n * @returns The overview stats of the user\r\n * @example\r\n * const api = new API(PLATFORM.EPIC, 'lil McNugget')\r\n * const data = await api.overview()\r\n * console.log(data)\r\n * @throws {Error} - If the overview data is not found\r\n * @throws {Error} - If the user data is not found\r\n */\r\n public async overview(options?: GenericOptions): Promise<OverviewStats> {\r\n if (!this.raw) await this.fetchUser();\r\n if (!this.raw) throw new Error('No data found');\r\n if (this.lastFetch + this.expiresAfter < Date.now() || options?.fresh) await this.fetchUser();\r\n\r\n const data = this.raw.data.segments.find((x) => x.type === 'overview');\r\n if (!data) throw new Error('No overview data found');\r\n\r\n const stats = data.stats as SegmentOverviewStats;\r\n\r\n return {\r\n assists: stats.assists.value,\r\n goals: stats.goals.value,\r\n goalShotRatio: stats.goalShotRatio.value,\r\n mVPs: stats.mVPs.value,\r\n saves: stats.saves.value,\r\n score: stats.score.value,\r\n seasonRewardLevel: stats.seasonRewardLevel.value,\r\n seasonRewardWins: stats.seasonRewardWins.value,\r\n shots: stats.shots.value,\r\n tRNRating: stats.tRNRating.value,\r\n wins: stats.wins.value,\r\n };\r\n }\r\n\r\n /**\r\n * Return the stats of the user formatted\r\n * @private\r\n * @param stats - The stats of the user\r\n * @returns The formatted stats of the user\r\n */\r\n private returnStats(stats: SegmentPlaylistStats): PlaylistStats {\r\n return {\r\n division: stats.division.value,\r\n deltaUp: stats.division.metadata.deltaUp ?? null,\r\n deltaDown: stats.division.metadata.deltaDown ?? null,\r\n matchesPlayed: stats.matchesPlayed.value,\r\n peakRating: stats.peakRating.value,\r\n rank: stats.tier.metadata.name,\r\n rating: stats.rating.value,\r\n tier: stats.tier.value,\r\n winStreak: stats.winStreak.displayValue === '0' ? 0 : parseInt(stats.winStreak.displayValue, 10),\r\n };\r\n }\r\n\r\n /**\r\n * Get the rank data of the user\r\n * @private\r\n * @param playlistName - The name of the playlist\r\n * @param options - The options for the API\r\n * @returns The rank data of the user\r\n */\r\n private async getRankData(playlistName: TPlaylists, options?: GenericOptions) {\r\n if (!this.raw) await this.fetchUser();\r\n if (!this.raw) throw new Error('No data found');\r\n if (this.lastFetch + this.expiresAfter < Date.now() || options?.fresh) await this.fetchUser();\r\n\r\n const data = this.raw.data.segments.find((x) => x?.metadata?.name === playlistName);\r\n if (!data) throw new Error(`No ${playlistName} data found`);\r\n const stats = data.stats as SegmentPlaylistStats;\r\n\r\n return this.returnStats(stats);\r\n }\r\n\r\n /**\r\n * Get the 1v1 rank data of the user\r\n * @param options - The options for the API\r\n * @returns The 1v1 rank data of the user\r\n * @example\r\n * const api = new API(PLATFORM.EPIC, 'lil McNugget')\r\n * const data = await api.get1v1()\r\n * console.log(data)\r\n * @throws {Error} - If the 1v1 data is not found\r\n * @throws {Error} - If the user data is not found\r\n */\r\n public get1v1(options?: GenericOptions): Promise<PlaylistStats> {\r\n return this.getRankData('Ranked Duel 1v1', options);\r\n }\r\n\r\n /**\r\n * Get the 2v2 rank data of the user\r\n * @param options - The options for the API\r\n * @returns The 2v2 rank data of the user\r\n * @example\r\n * const api = new API(PLATFORM.EPIC, 'lil McNugget')\r\n * const data = await api.get2v2()\r\n * console.log(data)\r\n * @throws {Error} - If the 2v2 data is not found\r\n * @throws {Error} - If the user data is not found\r\n */\r\n public get2v2(options?: GenericOptions): Promise<PlaylistStats> {\r\n return this.getRankData('Ranked Doubles 2v2', options);\r\n }\r\n\r\n /**\r\n * Get the 3v3 rank data of the user\r\n * @param options - The options for the API\r\n * @returns The 3v3 rank data of the user\r\n * @example\r\n * const api = new API(PLATFORM.EPIC, 'lil McNugget')\r\n * const data = await api.get3v3()\r\n * console.log(data)\r\n * @throws {Error} - If the 3v3 data is not found\r\n * @throws {Error} - If the user data is not found\r\n */\r\n public get3v3(options?: GenericOptions): Promise<PlaylistStats> {\r\n return this.getRankData('Ranked Standard 3v3', options);\r\n }\r\n\r\n /**\r\n * Get the Hoops rank data of the user\r\n * @param options - The options for the API\r\n * @returns The Hoops rank data of the user\r\n * @example\r\n * const api = new API(PLATFORM.EPIC, 'lil McNugget')\r\n * const data = await api.getHoops()\r\n * console.log(data)\r\n * @throws {Error} - If the Hoops data is not found\r\n * @throws {Error} - If the user data is not found\r\n */\r\n public getHoops(options?: GenericOptions): Promise<PlaylistStats> {\r\n return this.getRankData('Hoops', options);\r\n }\r\n\r\n /**\r\n * Get the Rumble rank data of the user\r\n * @param options - The options for the API\r\n * @returns The Rumble rank data of the user\r\n * @example\r\n * const api = new API(PLATFORM.EPIC, 'lil McNugget')\r\n * const data = await api.getRumble()\r\n * console.log(data)\r\n * @throws {Error} - If the Rumble data is not found\r\n * @throws {Error} - If the user data is not found\r\n */\r\n public getRumble(options?: GenericOptions): Promise<PlaylistStats> {\r\n return this.getRankData('Rumble', options);\r\n }\r\n\r\n /**\r\n * Get the Dropshot rank data of the user\r\n * @param options - The options for the API\r\n * @returns The Dropshot rank data of the user\r\n * @example\r\n * const api = new API(PLATFORM.EPIC, 'lil McNugget')\r\n * const data = await api.getDropshot()\r\n * console.log(data)\r\n * @throws {Error} - If the Dropshot data is not found\r\n * @throws {Error} - If the user data is not found\r\n */\r\n public getDropshot(options?: GenericOptions): Promise<PlaylistStats> {\r\n return this.getRankData('Dropshot', options);\r\n }\r\n\r\n /**\r\n * Get the Snowday rank data of the user\r\n * @param options - The options for the API\r\n * @returns The Snowday rank data of the user\r\n * @example\r\n * const api = new API(PLATFORM.EPIC, 'lil McNugget')\r\n * const data = await api.getSnowday()\r\n * console.log(data)\r\n * @throws {Error} - If the Snowday data is not found\r\n * @throws {Error} - If the user data is not found\r\n */\r\n public getSnowday(options?: GenericOptions): Promise<PlaylistStats> {\r\n return this.getRankData('Snowday', options);\r\n }\r\n\r\n /**\r\n * Get the Tournament rank data of the user\r\n * @param options - The options for the API\r\n * @returns The Tournament rank data of the user\r\n * @example\r\n * const api = new API(PLATFORM.EPIC, 'lil McNugget')\r\n * const data = await api.getTournament()\r\n * console.log(data)\r\n * @throws {Error} - If the Tournament data is not found\r\n * @throws {Error} - If the user data is not found\r\n */\r\n public getTournament(options?: GenericOptions): Promise<PlaylistStats> {\r\n return this.getRankData('Tournament Matches', options);\r\n }\r\n\r\n /**\r\n * Get the user data\r\n * @description Get all ranks and overview data for the user\r\n * @param options - The options for the API\r\n * @returns The user data\r\n * @example\r\n * const api = new API(PLATFORM.EPIC, 'lil McNugget')\r\n * const data = await api.getData()\r\n * console.log(data)\r\n * @throws {Error} - If the user data is not found\r\n * @throws {Error} - If the overview data is not found\r\n */\r\n public async getData(options?: GenericOptions) {\r\n const result = {} as AllStats;\r\n result.overview = await this.overview(options);\r\n result.gamemodes = {} as AllStats['gamemodes'];\r\n if (!this.raw) await this.fetchUser();\r\n if (!this.raw) throw new Error('No data found');\r\n\r\n const playlists = this.raw.data.segments.filter((x) => x.type === 'playlist') as (SegmentsPlaylist & Segments)[];\r\n for (const playlist of playlists) {\r\n if (playlist) {\r\n const stats = playlist.stats as SegmentPlaylistStats;\r\n result.gamemodes[playlist.metadata.name] = {} as PlaylistStats;\r\n result.gamemodes[playlist.metadata.name]['rank'] = stats.tier.metadata.name;\r\n result.gamemodes[playlist.metadata.name] = this.returnStats(stats);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n /**\r\n * Get the userinfo of the user\r\n * @param options - The options for the API\r\n * @returns The userinfo of the user\r\n * @example\r\n * const api = new API(PLATFORM.EPIC, 'lil McNugget')\r\n * const data = await api.getUserinfo()\r\n * console.log(data)\r\n * @throws {Error} - If the user data is not found\r\n * @throws {Error} - If the userinfo data is not found\r\n */\r\n public async getUserinfo(options?: GenericOptions): Promise<Userinfo> {\r\n if (!this.raw) await this.fetchUser();\r\n if (!this.raw) throw new Error('No data found');\r\n if (this.lastFetch + this.expiresAfter < Date.now() || options?.fresh) await this.fetchUser();\r\n\r\n const platform = this.raw.data.platformInfo;\r\n\r\n return {\r\n platform: platform.platformSlug,\r\n uuid: platform.platformUserId,\r\n name: platform.platformUserHandle,\r\n userid: platform.platformUserIdentifier,\r\n avatar: platform.avatarUrl,\r\n };\r\n }\r\n /**\r\n * Get the raw data of the user\r\n * @param options - The options for the API\r\n * @returns The raw data of the user\r\n * @example\r\n * const api = new API(PLATFORM.EPIC, 'lil McNugget')\r\n * const data = await api.getRaw()\r\n * console.log(data)\r\n * @throws {Error} - If the user data is not found\r\n * @throws {Error} - If the raw data is not found\r\n */\r\n public async getRaw(options?: GenericOptions): Promise<TrackerResponse> {\r\n if (!this.raw) await this.fetchUser();\r\n if (!this.raw) throw new Error('No data found');\r\n if (this.lastFetch + this.expiresAfter < Date.now() || options?.fresh) await this.fetchUser();\r\n return this.raw;\r\n }\r\n}\r\n"],"mappings":"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","names":[]}