fansunited-data-layer 0.14.4 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api/sportal365-sports/basketball/http.d.ts +1 -4
- package/api/sportal365-sports/basketball/http.d.ts.map +1 -1
- package/api/sportal365-sports/basketball/http.js +2 -3
- package/api/sportal365-sports/basketball/http.js.map +1 -1
- package/api/sportal365-sports/constants.d.ts +4 -11
- package/api/sportal365-sports/constants.d.ts.map +1 -1
- package/api/sportal365-sports/constants.js +1 -11
- package/api/sportal365-sports/constants.js.map +1 -1
- package/api/sportal365-sports/football/http.d.ts +7 -4
- package/api/sportal365-sports/football/http.d.ts.map +1 -1
- package/api/sportal365-sports/football/http.js +5 -3
- package/api/sportal365-sports/football/http.js.map +1 -1
- package/api/sportal365-sports/football/statistics/index.js +2 -2
- package/api/sportal365-sports/football/statistics/index.js.map +1 -1
- package/api/sportal365-sports/http.d.ts +14 -7
- package/api/sportal365-sports/http.d.ts.map +1 -1
- package/api/sportal365-sports/http.js +37 -1
- package/api/sportal365-sports/http.js.map +1 -1
- package/api/sportal365-sports/search/http.d.ts +1 -4
- package/api/sportal365-sports/search/http.d.ts.map +1 -1
- package/api/sportal365-sports/search/http.js +2 -3
- package/api/sportal365-sports/search/http.js.map +1 -1
- package/api/sportal365-sports/standings/http.d.ts +1 -4
- package/api/sportal365-sports/standings/http.d.ts.map +1 -1
- package/api/sportal365-sports/standings/http.js +2 -3
- package/api/sportal365-sports/standings/http.js.map +1 -1
- package/api/sportal365-sports/statistics/http.d.ts +1 -4
- package/api/sportal365-sports/statistics/http.d.ts.map +1 -1
- package/api/sportal365-sports/statistics/http.js +2 -3
- package/api/sportal365-sports/statistics/http.js.map +1 -1
- package/api/sportal365-sports/tennis/http.d.ts +1 -4
- package/api/sportal365-sports/tennis/http.d.ts.map +1 -1
- package/api/sportal365-sports/tennis/http.js +2 -3
- package/api/sportal365-sports/tennis/http.js.map +1 -1
- package/api/sportal365-sports/tennis/matches/transformers/match.d.ts.map +1 -1
- package/api/sportal365-sports/tennis/matches/transformers/match.js +23 -19
- package/api/sportal365-sports/tennis/matches/transformers/match.js.map +1 -1
- package/api/sportal365-sports/tennis/matches/types.d.ts +13 -0
- package/api/sportal365-sports/tennis/matches/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Basketball HTTP client
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* HTTP client configured for the Sportal365 Basketball API
|
|
2
|
+
* Basketball HTTP client — routed through the lsdapi proxy.
|
|
6
3
|
*/
|
|
7
4
|
export declare const basketballHttp: import("../http").Sportal365HttpClient;
|
|
8
5
|
//# sourceMappingURL=http.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/sportal365-sports/basketball/http.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/sportal365-sports/basketball/http.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,eAAO,MAAM,cAAc,wCAAmC,CAAC"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
const basketballHttp = createHttpClient(SPORTAL365_BASKETBALL_DOMAIN);
|
|
1
|
+
import { createProxyClient } from "../http.js";
|
|
2
|
+
const basketballHttp = createProxyClient("/basketball");
|
|
4
3
|
export {
|
|
5
4
|
basketballHttp
|
|
6
5
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sources":["../../../../src/lib/api/sportal365-sports/basketball/http.ts"],"sourcesContent":["/**\n * Basketball HTTP client
|
|
1
|
+
{"version":3,"file":"http.js","sources":["../../../../src/lib/api/sportal365-sports/basketball/http.ts"],"sourcesContent":["/**\n * Basketball HTTP client — routed through the lsdapi proxy.\n */\n\nimport { createProxyClient } from \"../http\";\n\nexport const basketballHttp = createProxyClient(\"/basketball\");\n"],"names":[],"mappings":";AAMO,MAAM,iBAAiB,kBAAkB,aAAa;"}
|
|
@@ -3,16 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Each Sportal365 API has its own domain based on the sport/functionality.
|
|
5
5
|
*/
|
|
6
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* Football API direct domain — used by `footballLegacyHttp` for endpoints the
|
|
8
|
+
* lsdapi proxy does not yet expose (currently: player recent statistics).
|
|
9
|
+
*/
|
|
7
10
|
export declare const SPORTAL365_FOOTBALL_DOMAIN = "https://football.api.sportal365.com";
|
|
8
|
-
/** Basketball API domain */
|
|
9
|
-
export declare const SPORTAL365_BASKETBALL_DOMAIN = "https://basketball.api.sportal365.com";
|
|
10
|
-
/** Tennis API domain */
|
|
11
|
-
export declare const SPORTAL365_TENNIS_DOMAIN = "https://tennis.api.sportal365.com";
|
|
12
|
-
/** Statistics API domain */
|
|
13
|
-
export declare const SPORTAL365_STATISTICS_DOMAIN = "https://sports-statistics.api.sportal365.com";
|
|
14
|
-
/** Sports Search API domain */
|
|
15
|
-
export declare const SPORTAL365_SPORTS_SEARCH_DOMAIN = "https://sports-search.api.sportal365.com";
|
|
16
|
-
/** Standings API domain */
|
|
17
|
-
export declare const SPORTAL365_STANDINGS_DOMAIN = "https://standing.api.sportal365.com";
|
|
18
11
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/lib/api/sportal365-sports/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/lib/api/sportal365-sports/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;GAGG;AACH,eAAO,MAAM,0BAA0B,wCAAwC,CAAC"}
|
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
const SPORTAL365_FOOTBALL_DOMAIN = "https://football.api.sportal365.com";
|
|
2
|
-
const SPORTAL365_BASKETBALL_DOMAIN = "https://basketball.api.sportal365.com";
|
|
3
|
-
const SPORTAL365_TENNIS_DOMAIN = "https://tennis.api.sportal365.com";
|
|
4
|
-
const SPORTAL365_STATISTICS_DOMAIN = "https://sports-statistics.api.sportal365.com";
|
|
5
|
-
const SPORTAL365_SPORTS_SEARCH_DOMAIN = "https://sports-search.api.sportal365.com";
|
|
6
|
-
const SPORTAL365_STANDINGS_DOMAIN = "https://standing.api.sportal365.com";
|
|
7
2
|
export {
|
|
8
|
-
|
|
9
|
-
SPORTAL365_FOOTBALL_DOMAIN,
|
|
10
|
-
SPORTAL365_SPORTS_SEARCH_DOMAIN,
|
|
11
|
-
SPORTAL365_STANDINGS_DOMAIN,
|
|
12
|
-
SPORTAL365_STATISTICS_DOMAIN,
|
|
13
|
-
SPORTAL365_TENNIS_DOMAIN
|
|
3
|
+
SPORTAL365_FOOTBALL_DOMAIN
|
|
14
4
|
};
|
|
15
5
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sources":["../../../src/lib/api/sportal365-sports/constants.ts"],"sourcesContent":["/**\n * Sportal365 API Domain Constants\n *\n * Each Sportal365 API has its own domain based on the sport/functionality.\n */\n\n
|
|
1
|
+
{"version":3,"file":"constants.js","sources":["../../../src/lib/api/sportal365-sports/constants.ts"],"sourcesContent":["/**\n * Sportal365 API Domain Constants\n *\n * Each Sportal365 API has its own domain based on the sport/functionality.\n */\n\n/**\n * Football API direct domain — used by `footballLegacyHttp` for endpoints the\n * lsdapi proxy does not yet expose (currently: player recent statistics).\n */\nexport const SPORTAL365_FOOTBALL_DOMAIN = \"https://football.api.sportal365.com\";\n"],"names":[],"mappings":"AAUO,MAAM,6BAA6B;"}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Football HTTP
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*
|
|
2
|
+
* Football HTTP clients.
|
|
3
|
+
*
|
|
4
|
+
* `footballHttp` goes through the lsdapi proxy and is the default for every
|
|
5
|
+
* football endpoint. `footballLegacyHttp` hits Sportal365 directly with Basic
|
|
6
|
+
* Auth — only used for routes the proxy does not yet expose (currently:
|
|
7
|
+
* `getFootballPlayerRecentStatistics`).
|
|
6
8
|
*/
|
|
7
9
|
export declare const footballHttp: import("../http").Sportal365HttpClient;
|
|
10
|
+
export declare const footballLegacyHttp: import("../http").Sportal365HttpClient;
|
|
8
11
|
//# sourceMappingURL=http.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/sportal365-sports/football/http.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/sportal365-sports/football/http.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,eAAO,MAAM,YAAY,wCAAiC,CAAC;AAE3D,eAAO,MAAM,kBAAkB,wCAA+C,CAAC"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { createHttpClient } from "../http.js";
|
|
1
|
+
import { createProxyClient, createHttpClient } from "../http.js";
|
|
2
2
|
import { SPORTAL365_FOOTBALL_DOMAIN } from "../constants.js";
|
|
3
|
-
const footballHttp =
|
|
3
|
+
const footballHttp = createProxyClient("/football");
|
|
4
|
+
const footballLegacyHttp = createHttpClient(SPORTAL365_FOOTBALL_DOMAIN);
|
|
4
5
|
export {
|
|
5
|
-
footballHttp
|
|
6
|
+
footballHttp,
|
|
7
|
+
footballLegacyHttp
|
|
6
8
|
};
|
|
7
9
|
//# sourceMappingURL=http.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sources":["../../../../src/lib/api/sportal365-sports/football/http.ts"],"sourcesContent":["/**\n * Football HTTP
|
|
1
|
+
{"version":3,"file":"http.js","sources":["../../../../src/lib/api/sportal365-sports/football/http.ts"],"sourcesContent":["/**\n * Football HTTP clients.\n *\n * `footballHttp` goes through the lsdapi proxy and is the default for every\n * football endpoint. `footballLegacyHttp` hits Sportal365 directly with Basic\n * Auth — only used for routes the proxy does not yet expose (currently:\n * `getFootballPlayerRecentStatistics`).\n */\n\nimport { createHttpClient, createProxyClient } from \"../http\";\nimport { SPORTAL365_FOOTBALL_DOMAIN } from \"../constants\";\n\nexport const footballHttp = createProxyClient(\"/football\");\n\nexport const footballLegacyHttp = createHttpClient(SPORTAL365_FOOTBALL_DOMAIN);\n"],"names":[],"mappings":";;AAYO,MAAM,eAAe,kBAAkB,WAAW;AAElD,MAAM,qBAAqB,iBAAiB,0BAA0B;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getConfig } from "../../../../config/index.js";
|
|
2
|
-
import { footballHttp } from "../http.js";
|
|
2
|
+
import { footballHttp, footballLegacyHttp } from "../http.js";
|
|
3
3
|
import { transformPlayerSeasonStatistics, transformPlayerSeasonStatisticsWithoutTeam, mergePlayerSeasonStatistics } from "./player-season.transformer.js";
|
|
4
4
|
import { transformPlayerCareerStatistics } from "./player-career.transformer.js";
|
|
5
5
|
import { transformPlayerRecentStatistics } from "./player-recent.transformer.js";
|
|
@@ -129,7 +129,7 @@ async function getFootballPlayerRecentStatistics(options, config) {
|
|
|
129
129
|
if (teamId) {
|
|
130
130
|
params.team_id = teamId;
|
|
131
131
|
}
|
|
132
|
-
const raw = await
|
|
132
|
+
const raw = await footballLegacyHttp.get({
|
|
133
133
|
path: `/v2/statistics/players/${playerId}/recent-statistics`,
|
|
134
134
|
params,
|
|
135
135
|
headers: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../../src/lib/api/sportal365-sports/football/statistics/index.ts"],"sourcesContent":["/**\n * Sportal365 Sports API - Football Statistics\n *\n * Fetches player statistics and transforms to canonical FUSports types.\n */\n\nimport type { FUSportsPlayerSeasonStatistics, FUSportsPlayerCareerStatistics, FUSportsPlayerRecentStatistics } from \"../../../../types/canonical\";\nimport { getConfig, type DataLayerConfig } from \"../../../../config\";\nimport { footballHttp } from \"../http\";\nimport type {\n RawPlayerSeasonStatisticsResponse,\n GetFootballPlayerSeasonStatisticsOptions,\n GetFootballPlayerSeasonStatisticsByPlayerIdsOptions,\n} from \"./player-season.types\";\nimport {\n transformPlayerSeasonStatistics,\n transformPlayerSeasonStatisticsWithoutTeam,\n mergePlayerSeasonStatistics,\n} from \"./player-season.transformer\";\nimport type {\n RawPlayerCareerStatisticsResponse,\n GetFootballPlayerCareerStatisticsOptions,\n} from \"./player-career.types\";\nimport { transformPlayerCareerStatistics } from \"./player-career.transformer\";\nimport type {\n RawPlayerRecentStatisticsResponse,\n GetFootballPlayerRecentStatisticsOptions,\n} from \"./player-recent.types\";\nimport { transformPlayerRecentStatistics } from \"./player-recent.transformer\";\n\n// Re-export types for options\nexport type {\n GetFootballPlayerSeasonStatisticsOptions,\n GetFootballPlayerSeasonStatisticsByPlayerIdsOptions,\n} from \"./player-season.types\";\n\nexport type { GetFootballPlayerCareerStatisticsOptions } from \"./player-career.types\";\n\nexport type { GetFootballPlayerRecentStatisticsOptions } from \"./player-recent.types\";\n\n/**\n * Get player season statistics for a team\n *\n * Fetches statistics for all players in a team for the specified season(s).\n *\n * By default, results are cached for 10 minutes (600 seconds).\n * You can override this by passing a custom `next` option.\n *\n * @param options - Required parameters (seasonIds, teamId)\n * @param config - Optional data layer config (uses singleton if not provided)\n * @returns Map of player ID to canonical FUSportsPlayerSeasonStatistics\n *\n * @example\n * ```typescript\n * const stats = await getFootballPlayerSeasonStatistics({\n * seasonIds: ['8009707'],\n * teamId: '102'\n * });\n * console.log(stats['179118']?.goals); // Player goals\n * ```\n *\n * @example\n * ```typescript\n * // Custom cache duration (5 minutes)\n * const stats = await getFootballPlayerSeasonStatistics({\n * seasonIds: ['8009707'],\n * teamId: '102',\n * next: { revalidate: 300 }\n * });\n * ```\n */\nexport async function getFootballPlayerSeasonStatistics(\n options: GetFootballPlayerSeasonStatisticsOptions,\n config?: DataLayerConfig\n): Promise<Record<string, FUSportsPlayerSeasonStatistics>> {\n const finalConfig = config || getConfig();\n const { sportal365Sports } = finalConfig;\n\n const { seasonIds, teamId, languageCode, next } = options;\n\n // Disable caching to prevent caching of failed/empty responses\n // This ensures we always get fresh data and don't cache API errors\n const cacheOptions = next ?? { revalidate: 0 };\n\n const params = {\n season_ids: seasonIds.join(\",\"),\n team_id: teamId,\n language_code: languageCode ?? sportal365Sports?.languageCode ?? \"en\",\n };\n\n const raw = await footballHttp.get<RawPlayerSeasonStatisticsResponse>({\n path: `/v2/statistics/players/season`,\n params,\n headers: {\n \"Accept-Language\": languageCode ?? sportal365Sports?.languageCode ?? \"en\",\n },\n next: cacheOptions,\n config: finalConfig,\n });\n\n // Validate response structure\n if (!raw.statistics) {\n console.error(\"[getFootballPlayerSeasonStatistics] Invalid API response - missing statistics array:\", {\n teamId,\n seasonIds,\n response: raw,\n });\n return {};\n }\n\n // Check if statistics array is empty\n if (raw.statistics.length === 0) {\n console.warn(\"[getFootballPlayerSeasonStatistics] API returned empty statistics array:\", {\n teamId,\n seasonIds,\n hint: \"This could be due to: wrong credentials, wrong project header, no data for this team/season, or API issue\",\n });\n\n // Throw an error instead of returning empty object\n // This prevents Next.js from caching the failed response\n throw new Error(\n `No player statistics found for team ${teamId} in seasons ${seasonIds.join(\", \")}. ` +\n `This could be due to: wrong credentials, wrong X-Project header, or no data available for this team/season.`\n );\n }\n\n // Transform to a map of playerId -> statistics\n const result: Record<string, FUSportsPlayerSeasonStatistics> = {};\n\n for (const entry of raw.statistics) {\n const playerId = entry.player.id;\n result[playerId] = transformPlayerSeasonStatistics(entry, teamId);\n }\n\n return result;\n}\n\n/**\n * Get player season statistics by player IDs\n *\n * Fetches statistics for specific players in the specified season(s).\n * Stats are aggregated across all teams the player has played for.\n *\n * @param options - Required parameters (playerIds, seasonIds)\n * @param config - Optional data layer config (uses singleton if not provided)\n * @returns Map of player ID to canonical FUSportsPlayerSeasonStatistics\n *\n * @example\n * ```typescript\n * const stats = await getFootballPlayerSeasonStatisticsByPlayerIds({\n * playerIds: ['39870'],\n * seasonIds: ['4368438']\n * });\n * console.log(stats['39870']?.goals); // Player goals across all teams\n * ```\n */\nexport async function getFootballPlayerSeasonStatisticsByPlayerIds(\n options: GetFootballPlayerSeasonStatisticsByPlayerIdsOptions,\n config?: DataLayerConfig\n): Promise<Record<string, FUSportsPlayerSeasonStatistics>> {\n const finalConfig = config || getConfig();\n const { sportal365Sports } = finalConfig;\n\n const { playerIds, seasonIds, languageCode, next } = options;\n\n const cacheOptions = next ?? { revalidate: 0 };\n\n const params = {\n player_ids: playerIds.join(\",\"),\n season_ids: seasonIds.join(\",\"),\n language_code: languageCode ?? sportal365Sports?.languageCode ?? \"en\",\n };\n\n const raw = await footballHttp.get<RawPlayerSeasonStatisticsResponse>({\n path: `/v2/statistics/players/season`,\n params,\n headers: {\n \"Accept-Language\": languageCode ?? sportal365Sports?.languageCode ?? \"en\",\n },\n next: cacheOptions,\n config: finalConfig,\n });\n\n if (!raw.statistics) {\n console.error(\"[getFootballPlayerSeasonStatisticsByPlayerIds] Invalid API response - missing statistics array:\", {\n playerIds,\n seasonIds,\n response: raw,\n });\n return {};\n }\n\n if (raw.statistics.length === 0) {\n return {};\n }\n\n // Transform and merge stats per player (a player may have entries for multiple teams)\n const result: Record<string, FUSportsPlayerSeasonStatistics> = {};\n\n for (const entry of raw.statistics) {\n const playerId = entry.player.id;\n const transformed = transformPlayerSeasonStatisticsWithoutTeam(entry);\n\n if (result[playerId]) {\n result[playerId] = mergePlayerSeasonStatistics(result[playerId], transformed);\n } else {\n result[playerId] = transformed;\n }\n }\n\n return result;\n}\n\n/**\n * Get a player's career statistics across all tournaments and teams\n *\n * Fetches statistics throughout a player's entire career, broken down by\n * tournament season and team.\n *\n * @param options - Required parameters (playerId)\n * @param config - Optional data layer config (uses singleton if not provided)\n * @returns Player career statistics with per-season-per-team entries\n *\n * @example\n * ```typescript\n * const career = await getFootballPlayerCareerStatistics({\n * playerId: '3400' // or slug: 'cristiano-ronaldo-3400'\n * });\n * console.log(career.playerName); // \"Cristiano Ronaldo\"\n * console.log(career.entries[0].goals); // Goals in first entry\n * ```\n */\nexport async function getFootballPlayerCareerStatistics(\n options: GetFootballPlayerCareerStatisticsOptions,\n config?: DataLayerConfig\n): Promise<FUSportsPlayerCareerStatistics> {\n const finalConfig = config || getConfig();\n const { sportal365Sports } = finalConfig;\n\n const { playerId, languageCode, next } = options;\n\n const cacheOptions = next ?? { revalidate: 0 };\n\n const raw = await footballHttp.get<RawPlayerCareerStatisticsResponse>({\n path: `/players/${playerId}/statistics`,\n params: {\n language_code: languageCode ?? sportal365Sports?.languageCode ?? \"en\",\n },\n headers: {\n \"Accept-Language\": languageCode ?? sportal365Sports?.languageCode ?? \"en\",\n },\n next: cacheOptions,\n config: finalConfig,\n });\n\n if (!Array.isArray(raw) || raw.length === 0) {\n throw new Error(\n `No career statistics found for player ${playerId}. ` +\n `This could be due to: invalid player ID/slug, wrong credentials, or no data available.`\n );\n }\n\n return transformPlayerCareerStatistics(raw);\n}\n\n/**\n * Get a player's recent statistics from their last N matches\n *\n * Fetches aggregated statistics and match details for a player's most recent matches.\n * Optionally filter by tournament or team.\n *\n * @param options - Required parameters (playerId), optional filters (matches, tournamentIds, teamId)\n * @param config - Optional data layer config (uses singleton if not provided)\n * @returns Player recent statistics with matches and aggregated stats\n *\n * @example\n * ```typescript\n * const recent = await getFootballPlayerRecentStatistics({\n * playerId: '3400',\n * matches: 5\n * });\n * console.log(recent.goals); // Goals in last 5 matches\n * console.log(recent.matches.length); // 5\n * ```\n */\nexport async function getFootballPlayerRecentStatistics(\n options: GetFootballPlayerRecentStatisticsOptions,\n config?: DataLayerConfig\n): Promise<FUSportsPlayerRecentStatistics> {\n const finalConfig = config || getConfig();\n const { sportal365Sports } = finalConfig;\n\n const { playerId, matches, tournamentIds, teamId, languageCode, next } = options;\n\n const cacheOptions = next ?? { revalidate: 0 };\n\n const params: Record<string, string> = {\n language_code: languageCode ?? sportal365Sports?.languageCode ?? \"en\",\n };\n\n if (matches != null) {\n params.matches = String(matches);\n }\n if (tournamentIds?.length) {\n params.tournament_ids = tournamentIds.join(\",\");\n }\n if (teamId) {\n params.team_id = teamId;\n }\n\n const raw = await footballHttp.get<RawPlayerRecentStatisticsResponse>({\n path: `/v2/statistics/players/${playerId}/recent-statistics`,\n params,\n headers: {\n \"Accept-Language\": languageCode ?? sportal365Sports?.languageCode ?? \"en\",\n },\n next: cacheOptions,\n config: finalConfig,\n });\n\n if (!raw.player || !raw.matches) {\n throw new Error(\n `No recent statistics found for player ${playerId}. ` +\n `This could be due to: invalid player ID, wrong credentials, or no data available.`\n );\n }\n\n return transformPlayerRecentStatistics(raw);\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../../src/lib/api/sportal365-sports/football/statistics/index.ts"],"sourcesContent":["/**\n * Sportal365 Sports API - Football Statistics\n *\n * Fetches player statistics and transforms to canonical FUSports types.\n */\n\nimport type { FUSportsPlayerSeasonStatistics, FUSportsPlayerCareerStatistics, FUSportsPlayerRecentStatistics } from \"../../../../types/canonical\";\nimport { getConfig, type DataLayerConfig } from \"../../../../config\";\nimport { footballHttp, footballLegacyHttp } from \"../http\";\nimport type {\n RawPlayerSeasonStatisticsResponse,\n GetFootballPlayerSeasonStatisticsOptions,\n GetFootballPlayerSeasonStatisticsByPlayerIdsOptions,\n} from \"./player-season.types\";\nimport {\n transformPlayerSeasonStatistics,\n transformPlayerSeasonStatisticsWithoutTeam,\n mergePlayerSeasonStatistics,\n} from \"./player-season.transformer\";\nimport type {\n RawPlayerCareerStatisticsResponse,\n GetFootballPlayerCareerStatisticsOptions,\n} from \"./player-career.types\";\nimport { transformPlayerCareerStatistics } from \"./player-career.transformer\";\nimport type {\n RawPlayerRecentStatisticsResponse,\n GetFootballPlayerRecentStatisticsOptions,\n} from \"./player-recent.types\";\nimport { transformPlayerRecentStatistics } from \"./player-recent.transformer\";\n\n// Re-export types for options\nexport type {\n GetFootballPlayerSeasonStatisticsOptions,\n GetFootballPlayerSeasonStatisticsByPlayerIdsOptions,\n} from \"./player-season.types\";\n\nexport type { GetFootballPlayerCareerStatisticsOptions } from \"./player-career.types\";\n\nexport type { GetFootballPlayerRecentStatisticsOptions } from \"./player-recent.types\";\n\n/**\n * Get player season statistics for a team\n *\n * Fetches statistics for all players in a team for the specified season(s).\n *\n * By default, results are cached for 10 minutes (600 seconds).\n * You can override this by passing a custom `next` option.\n *\n * @param options - Required parameters (seasonIds, teamId)\n * @param config - Optional data layer config (uses singleton if not provided)\n * @returns Map of player ID to canonical FUSportsPlayerSeasonStatistics\n *\n * @example\n * ```typescript\n * const stats = await getFootballPlayerSeasonStatistics({\n * seasonIds: ['8009707'],\n * teamId: '102'\n * });\n * console.log(stats['179118']?.goals); // Player goals\n * ```\n *\n * @example\n * ```typescript\n * // Custom cache duration (5 minutes)\n * const stats = await getFootballPlayerSeasonStatistics({\n * seasonIds: ['8009707'],\n * teamId: '102',\n * next: { revalidate: 300 }\n * });\n * ```\n */\nexport async function getFootballPlayerSeasonStatistics(\n options: GetFootballPlayerSeasonStatisticsOptions,\n config?: DataLayerConfig\n): Promise<Record<string, FUSportsPlayerSeasonStatistics>> {\n const finalConfig = config || getConfig();\n const { sportal365Sports } = finalConfig;\n\n const { seasonIds, teamId, languageCode, next } = options;\n\n // Disable caching to prevent caching of failed/empty responses\n // This ensures we always get fresh data and don't cache API errors\n const cacheOptions = next ?? { revalidate: 0 };\n\n const params = {\n season_ids: seasonIds.join(\",\"),\n team_id: teamId,\n language_code: languageCode ?? sportal365Sports?.languageCode ?? \"en\",\n };\n\n const raw = await footballHttp.get<RawPlayerSeasonStatisticsResponse>({\n path: `/v2/statistics/players/season`,\n params,\n headers: {\n \"Accept-Language\": languageCode ?? sportal365Sports?.languageCode ?? \"en\",\n },\n next: cacheOptions,\n config: finalConfig,\n });\n\n // Validate response structure\n if (!raw.statistics) {\n console.error(\"[getFootballPlayerSeasonStatistics] Invalid API response - missing statistics array:\", {\n teamId,\n seasonIds,\n response: raw,\n });\n return {};\n }\n\n // Check if statistics array is empty\n if (raw.statistics.length === 0) {\n console.warn(\"[getFootballPlayerSeasonStatistics] API returned empty statistics array:\", {\n teamId,\n seasonIds,\n hint: \"This could be due to: wrong credentials, wrong project header, no data for this team/season, or API issue\",\n });\n\n // Throw an error instead of returning empty object\n // This prevents Next.js from caching the failed response\n throw new Error(\n `No player statistics found for team ${teamId} in seasons ${seasonIds.join(\", \")}. ` +\n `This could be due to: wrong credentials, wrong X-Project header, or no data available for this team/season.`\n );\n }\n\n // Transform to a map of playerId -> statistics\n const result: Record<string, FUSportsPlayerSeasonStatistics> = {};\n\n for (const entry of raw.statistics) {\n const playerId = entry.player.id;\n result[playerId] = transformPlayerSeasonStatistics(entry, teamId);\n }\n\n return result;\n}\n\n/**\n * Get player season statistics by player IDs\n *\n * Fetches statistics for specific players in the specified season(s).\n * Stats are aggregated across all teams the player has played for.\n *\n * @param options - Required parameters (playerIds, seasonIds)\n * @param config - Optional data layer config (uses singleton if not provided)\n * @returns Map of player ID to canonical FUSportsPlayerSeasonStatistics\n *\n * @example\n * ```typescript\n * const stats = await getFootballPlayerSeasonStatisticsByPlayerIds({\n * playerIds: ['39870'],\n * seasonIds: ['4368438']\n * });\n * console.log(stats['39870']?.goals); // Player goals across all teams\n * ```\n */\nexport async function getFootballPlayerSeasonStatisticsByPlayerIds(\n options: GetFootballPlayerSeasonStatisticsByPlayerIdsOptions,\n config?: DataLayerConfig\n): Promise<Record<string, FUSportsPlayerSeasonStatistics>> {\n const finalConfig = config || getConfig();\n const { sportal365Sports } = finalConfig;\n\n const { playerIds, seasonIds, languageCode, next } = options;\n\n const cacheOptions = next ?? { revalidate: 0 };\n\n const params = {\n player_ids: playerIds.join(\",\"),\n season_ids: seasonIds.join(\",\"),\n language_code: languageCode ?? sportal365Sports?.languageCode ?? \"en\",\n };\n\n const raw = await footballHttp.get<RawPlayerSeasonStatisticsResponse>({\n path: `/v2/statistics/players/season`,\n params,\n headers: {\n \"Accept-Language\": languageCode ?? sportal365Sports?.languageCode ?? \"en\",\n },\n next: cacheOptions,\n config: finalConfig,\n });\n\n if (!raw.statistics) {\n console.error(\"[getFootballPlayerSeasonStatisticsByPlayerIds] Invalid API response - missing statistics array:\", {\n playerIds,\n seasonIds,\n response: raw,\n });\n return {};\n }\n\n if (raw.statistics.length === 0) {\n return {};\n }\n\n // Transform and merge stats per player (a player may have entries for multiple teams)\n const result: Record<string, FUSportsPlayerSeasonStatistics> = {};\n\n for (const entry of raw.statistics) {\n const playerId = entry.player.id;\n const transformed = transformPlayerSeasonStatisticsWithoutTeam(entry);\n\n if (result[playerId]) {\n result[playerId] = mergePlayerSeasonStatistics(result[playerId], transformed);\n } else {\n result[playerId] = transformed;\n }\n }\n\n return result;\n}\n\n/**\n * Get a player's career statistics across all tournaments and teams\n *\n * Fetches statistics throughout a player's entire career, broken down by\n * tournament season and team.\n *\n * @param options - Required parameters (playerId)\n * @param config - Optional data layer config (uses singleton if not provided)\n * @returns Player career statistics with per-season-per-team entries\n *\n * @example\n * ```typescript\n * const career = await getFootballPlayerCareerStatistics({\n * playerId: '3400' // or slug: 'cristiano-ronaldo-3400'\n * });\n * console.log(career.playerName); // \"Cristiano Ronaldo\"\n * console.log(career.entries[0].goals); // Goals in first entry\n * ```\n */\nexport async function getFootballPlayerCareerStatistics(\n options: GetFootballPlayerCareerStatisticsOptions,\n config?: DataLayerConfig\n): Promise<FUSportsPlayerCareerStatistics> {\n const finalConfig = config || getConfig();\n const { sportal365Sports } = finalConfig;\n\n const { playerId, languageCode, next } = options;\n\n const cacheOptions = next ?? { revalidate: 0 };\n\n const raw = await footballHttp.get<RawPlayerCareerStatisticsResponse>({\n path: `/players/${playerId}/statistics`,\n params: {\n language_code: languageCode ?? sportal365Sports?.languageCode ?? \"en\",\n },\n headers: {\n \"Accept-Language\": languageCode ?? sportal365Sports?.languageCode ?? \"en\",\n },\n next: cacheOptions,\n config: finalConfig,\n });\n\n if (!Array.isArray(raw) || raw.length === 0) {\n throw new Error(\n `No career statistics found for player ${playerId}. ` +\n `This could be due to: invalid player ID/slug, wrong credentials, or no data available.`\n );\n }\n\n return transformPlayerCareerStatistics(raw);\n}\n\n/**\n * Get a player's recent statistics from their last N matches\n *\n * Fetches aggregated statistics and match details for a player's most recent matches.\n * Optionally filter by tournament or team.\n *\n * @param options - Required parameters (playerId), optional filters (matches, tournamentIds, teamId)\n * @param config - Optional data layer config (uses singleton if not provided)\n * @returns Player recent statistics with matches and aggregated stats\n *\n * @example\n * ```typescript\n * const recent = await getFootballPlayerRecentStatistics({\n * playerId: '3400',\n * matches: 5\n * });\n * console.log(recent.goals); // Goals in last 5 matches\n * console.log(recent.matches.length); // 5\n * ```\n */\nexport async function getFootballPlayerRecentStatistics(\n options: GetFootballPlayerRecentStatisticsOptions,\n config?: DataLayerConfig\n): Promise<FUSportsPlayerRecentStatistics> {\n const finalConfig = config || getConfig();\n const { sportal365Sports } = finalConfig;\n\n const { playerId, matches, tournamentIds, teamId, languageCode, next } = options;\n\n const cacheOptions = next ?? { revalidate: 0 };\n\n const params: Record<string, string> = {\n language_code: languageCode ?? sportal365Sports?.languageCode ?? \"en\",\n };\n\n if (matches != null) {\n params.matches = String(matches);\n }\n if (tournamentIds?.length) {\n params.tournament_ids = tournamentIds.join(\",\");\n }\n if (teamId) {\n params.team_id = teamId;\n }\n\n const raw = await footballLegacyHttp.get<RawPlayerRecentStatisticsResponse>({\n path: `/v2/statistics/players/${playerId}/recent-statistics`,\n params,\n headers: {\n \"Accept-Language\": languageCode ?? sportal365Sports?.languageCode ?? \"en\",\n },\n next: cacheOptions,\n config: finalConfig,\n });\n\n if (!raw.player || !raw.matches) {\n throw new Error(\n `No recent statistics found for player ${playerId}. ` +\n `This could be due to: invalid player ID, wrong credentials, or no data available.`\n );\n }\n\n return transformPlayerRecentStatistics(raw);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -27,13 +27,7 @@ export interface RequestOptions {
|
|
|
27
27
|
}
|
|
28
28
|
export interface Sportal365HttpClient {
|
|
29
29
|
/**
|
|
30
|
-
* Make a GET request to
|
|
31
|
-
*
|
|
32
|
-
* Handles:
|
|
33
|
-
* - Authentication (Basic Auth)
|
|
34
|
-
* - Project ID header
|
|
35
|
-
* - Timeout
|
|
36
|
-
* - Error handling
|
|
30
|
+
* Make a GET request to a Sportal365 Sports API (direct or via lsdapi proxy).
|
|
37
31
|
*
|
|
38
32
|
* @param options - Request options
|
|
39
33
|
* @returns Parsed JSON response
|
|
@@ -56,4 +50,17 @@ export interface Sportal365HttpClient {
|
|
|
56
50
|
* ```
|
|
57
51
|
*/
|
|
58
52
|
export declare function createHttpClient(domain: string): Sportal365HttpClient;
|
|
53
|
+
/**
|
|
54
|
+
* Create an HTTP client that talks to the lsdapi proxy mirror of a Sportal365 API.
|
|
55
|
+
*
|
|
56
|
+
* The proxy mirrors each Sportal365 subdomain as a path prefix on a single host:
|
|
57
|
+
* `football.api.sportal365.com` → `sports.lsdapi.com/football`, etc. Image URLs
|
|
58
|
+
* in responses come back already rewritten to `assets.lsdapi.com`, so no
|
|
59
|
+
* client-side hashing is needed.
|
|
60
|
+
*
|
|
61
|
+
* Auth is by query params (`client_id`, `key`) — no Basic Auth, no `X-Project`.
|
|
62
|
+
*
|
|
63
|
+
* @param prefix - Path prefix on the proxy (e.g., '/football', '/basketball')
|
|
64
|
+
*/
|
|
65
|
+
export declare function createProxyClient(prefix: string): Sportal365HttpClient;
|
|
59
66
|
//# sourceMappingURL=http.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../src/lib/api/sportal365-sports/http.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/D;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC7B,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC5B,iEAAiE;IACjE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC3B,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IACvD,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,2DAA2D;IAC3D,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,kEAAkE;IAClE,MAAM,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACjC
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../src/lib/api/sportal365-sports/http.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/D;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC7B,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC5B,iEAAiE;IACjE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC3B,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IACvD,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,2DAA2D;IAC3D,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,kEAAkE;IAClE,MAAM,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACjC;;;;;OAKG;IACH,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC/C;AAYD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,oBAAoB,CA8DrE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,oBAAoB,CAoCtE"}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { getConfig } from "../../config/index.js";
|
|
2
|
+
const LSDAPI_PROXY_BASE = "https://sports.lsdapi.com";
|
|
3
|
+
const LSDAPI_CLIENT_ID = "demo";
|
|
4
|
+
const LSDAPI_KEY = "AIzaSyCq4iSKixO5OYastH9BuqT0SKjQl2aztm8";
|
|
2
5
|
function createHttpClient(domain) {
|
|
3
6
|
const baseUrl = domain.replace(/\/$/, "");
|
|
4
7
|
function getAuthHeader(config) {
|
|
@@ -51,7 +54,40 @@ function createHttpClient(domain) {
|
|
|
51
54
|
}
|
|
52
55
|
};
|
|
53
56
|
}
|
|
57
|
+
function createProxyClient(prefix) {
|
|
58
|
+
const baseUrl = LSDAPI_PROXY_BASE + (prefix.startsWith("/") ? prefix : `/${prefix}`);
|
|
59
|
+
return {
|
|
60
|
+
async get(options) {
|
|
61
|
+
const url = new URL(baseUrl + options.path);
|
|
62
|
+
if (options.params) {
|
|
63
|
+
for (const [key, value] of Object.entries(options.params)) {
|
|
64
|
+
if (value === void 0) continue;
|
|
65
|
+
if (Array.isArray(value)) {
|
|
66
|
+
if (value.length > 0) url.searchParams.set(key, value.join(","));
|
|
67
|
+
} else {
|
|
68
|
+
url.searchParams.set(key, value);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
url.searchParams.set("client_id", LSDAPI_CLIENT_ID);
|
|
73
|
+
url.searchParams.set("key", LSDAPI_KEY);
|
|
74
|
+
const response = await fetch(url.toString(), {
|
|
75
|
+
method: "GET",
|
|
76
|
+
headers: {
|
|
77
|
+
"Content-Type": "application/json",
|
|
78
|
+
...options.headers
|
|
79
|
+
},
|
|
80
|
+
...options.next && { next: options.next }
|
|
81
|
+
});
|
|
82
|
+
if (!response.ok) {
|
|
83
|
+
throw new Error(`lsdapi proxy error: ${response.status} ${response.statusText}`);
|
|
84
|
+
}
|
|
85
|
+
return response.json();
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
54
89
|
export {
|
|
55
|
-
createHttpClient
|
|
90
|
+
createHttpClient,
|
|
91
|
+
createProxyClient
|
|
56
92
|
};
|
|
57
93
|
//# sourceMappingURL=http.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sources":["../../../src/lib/api/sportal365-sports/http.ts"],"sourcesContent":["/**\n * Sportal365 Sports API - HTTP client factory\n * Creates sport-specific HTTP clients for Sportal365 APIs\n */\n\nimport { getConfig, type DataLayerConfig } from \"../../config\";\n\n/**\n * Next.js cache options for fetch requests\n * @see https://nextjs.org/docs/app/api-reference/functions/fetch#optionsnext\n */\nexport interface NextCacheOptions {\n /** Time in seconds to cache the response. Set to 0 to disable caching. */\n revalidate?: number | false;\n /** Cache tags for on-demand revalidation with revalidateTag() */\n tags?: string[];\n}\n\nexport interface RequestOptions {\n /** API path (e.g., '/v2/matches/123') */\n path: string;\n /** Query parameters */\n params?: Record<string, string | string[] | undefined>;\n /** Custom headers to include in the request */\n headers?: Record<string, string>;\n /** Next.js cache options for ISR/on-demand revalidation */\n next?: NextCacheOptions;\n /** Optional data layer config (uses singleton if not provided) */\n config?: DataLayerConfig;\n}\n\nexport interface Sportal365HttpClient {\n /**\n * Make a GET request to
|
|
1
|
+
{"version":3,"file":"http.js","sources":["../../../src/lib/api/sportal365-sports/http.ts"],"sourcesContent":["/**\n * Sportal365 Sports API - HTTP client factory\n * Creates sport-specific HTTP clients for Sportal365 APIs\n */\n\nimport { getConfig, type DataLayerConfig } from \"../../config\";\n\n/**\n * Next.js cache options for fetch requests\n * @see https://nextjs.org/docs/app/api-reference/functions/fetch#optionsnext\n */\nexport interface NextCacheOptions {\n /** Time in seconds to cache the response. Set to 0 to disable caching. */\n revalidate?: number | false;\n /** Cache tags for on-demand revalidation with revalidateTag() */\n tags?: string[];\n}\n\nexport interface RequestOptions {\n /** API path (e.g., '/v2/matches/123') */\n path: string;\n /** Query parameters */\n params?: Record<string, string | string[] | undefined>;\n /** Custom headers to include in the request */\n headers?: Record<string, string>;\n /** Next.js cache options for ISR/on-demand revalidation */\n next?: NextCacheOptions;\n /** Optional data layer config (uses singleton if not provided) */\n config?: DataLayerConfig;\n}\n\nexport interface Sportal365HttpClient {\n /**\n * Make a GET request to a Sportal365 Sports API (direct or via lsdapi proxy).\n *\n * @param options - Request options\n * @returns Parsed JSON response\n */\n get<T>(options: RequestOptions): Promise<T>;\n}\n\n/** Base host of the FansUnited lsdapi proxy that mirrors Sportal365 APIs. */\nconst LSDAPI_PROXY_BASE = \"https://sports.lsdapi.com\";\n\n/**\n * Hardcoded credentials for the lsdapi proxy. Single-tenant for now; promote\n * to config if a second consumer ever needs different values.\n */\nconst LSDAPI_CLIENT_ID = \"demo\";\nconst LSDAPI_KEY = \"AIzaSyCq4iSKixO5OYastH9BuqT0SKjQl2aztm8\";\n\n/**\n * Create an HTTP client for a specific Sportal365 API domain\n *\n * @param domain - The base URL for the API (e.g., 'https://football.api.sportal365.com')\n * @returns HTTP client configured for the specified domain\n *\n * @example\n * ```typescript\n * import { createHttpClient } from '../http';\n * import { SPORTAL365_FOOTBALL_DOMAIN } from '../constants';\n *\n * const footballHttp = createHttpClient(SPORTAL365_FOOTBALL_DOMAIN);\n * const data = await footballHttp.get({ path: '/v2/matches/123' });\n * ```\n */\nexport function createHttpClient(domain: string): Sportal365HttpClient {\n const baseUrl = domain.replace(/\\/$/, \"\");\n\n function getAuthHeader(config: DataLayerConfig): string {\n const { sportal365Sports } = config;\n if (!sportal365Sports) {\n throw new Error(\"Sportal365 Sports API configuration is missing\");\n }\n const credentials = `${sportal365Sports.username}:${sportal365Sports.password}`;\n return `Basic ${btoa(credentials)}`;\n }\n\n function buildUrl(path: string): string {\n return `${baseUrl}${path}`;\n }\n\n return {\n async get<T>(options: RequestOptions): Promise<T> {\n const finalConfig = options.config || getConfig();\n const { sportal365Sports } = finalConfig;\n\n if (!sportal365Sports) {\n throw new Error(\"Sportal365 Sports API configuration is missing\");\n }\n\n const url = new URL(buildUrl(options.path));\n\n // Add query parameters\n if (options.params) {\n for (const [key, value] of Object.entries(options.params)) {\n if (value === undefined) continue;\n\n if (Array.isArray(value)) {\n if (value.length > 0) {\n url.searchParams.set(key, value.join(\",\"));\n }\n } else {\n url.searchParams.set(key, value);\n }\n }\n }\n\n const response = await fetch(url.toString(), {\n method: \"GET\",\n headers: {\n Authorization: getAuthHeader(finalConfig),\n \"Content-Type\": \"application/json\",\n \"X-Project\": sportal365Sports.projectId,\n // Merge custom headers (they can override defaults)\n ...options.headers,\n },\n // Next.js cache options for ISR/on-demand revalidation\n ...(options.next && { next: options.next }),\n });\n\n if (!response.ok) {\n throw new Error(`Sportal365 API error: ${response.status} ${response.statusText}`);\n }\n\n return response.json();\n },\n };\n}\n\n/**\n * Create an HTTP client that talks to the lsdapi proxy mirror of a Sportal365 API.\n *\n * The proxy mirrors each Sportal365 subdomain as a path prefix on a single host:\n * `football.api.sportal365.com` → `sports.lsdapi.com/football`, etc. Image URLs\n * in responses come back already rewritten to `assets.lsdapi.com`, so no\n * client-side hashing is needed.\n *\n * Auth is by query params (`client_id`, `key`) — no Basic Auth, no `X-Project`.\n *\n * @param prefix - Path prefix on the proxy (e.g., '/football', '/basketball')\n */\nexport function createProxyClient(prefix: string): Sportal365HttpClient {\n const baseUrl = LSDAPI_PROXY_BASE + (prefix.startsWith(\"/\") ? prefix : `/${prefix}`);\n\n return {\n async get<T>(options: RequestOptions): Promise<T> {\n const url = new URL(baseUrl + options.path);\n\n if (options.params) {\n for (const [key, value] of Object.entries(options.params)) {\n if (value === undefined) continue;\n if (Array.isArray(value)) {\n if (value.length > 0) url.searchParams.set(key, value.join(\",\"));\n } else {\n url.searchParams.set(key, value);\n }\n }\n }\n url.searchParams.set(\"client_id\", LSDAPI_CLIENT_ID);\n url.searchParams.set(\"key\", LSDAPI_KEY);\n\n const response = await fetch(url.toString(), {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...options.headers,\n },\n ...(options.next && { next: options.next }),\n });\n\n if (!response.ok) {\n throw new Error(`lsdapi proxy error: ${response.status} ${response.statusText}`);\n }\n\n return response.json();\n },\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* HTTP client
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* HTTP client for Sports Search API
|
|
2
|
+
* Sports Search HTTP client — routed through the lsdapi proxy.
|
|
6
3
|
*/
|
|
7
4
|
export declare const sportsSearchHttp: import("../http").Sportal365HttpClient;
|
|
8
5
|
//# sourceMappingURL=http.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/sportal365-sports/search/http.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/sportal365-sports/search/http.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,eAAO,MAAM,gBAAgB,wCAAsC,CAAC"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
const sportsSearchHttp = createHttpClient(SPORTAL365_SPORTS_SEARCH_DOMAIN);
|
|
1
|
+
import { createProxyClient } from "../http.js";
|
|
2
|
+
const sportsSearchHttp = createProxyClient("/sports-search");
|
|
4
3
|
export {
|
|
5
4
|
sportsSearchHttp
|
|
6
5
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sources":["../../../../src/lib/api/sportal365-sports/search/http.ts"],"sourcesContent":["/**\n * HTTP client
|
|
1
|
+
{"version":3,"file":"http.js","sources":["../../../../src/lib/api/sportal365-sports/search/http.ts"],"sourcesContent":["/**\n * Sports Search HTTP client — routed through the lsdapi proxy.\n */\n\nimport { createProxyClient } from \"../http\";\n\nexport const sportsSearchHttp = createProxyClient(\"/sports-search\");\n"],"names":[],"mappings":";AAMO,MAAM,mBAAmB,kBAAkB,gBAAgB;"}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Standings
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* HTTP client configured for the Sportal365 Standings API
|
|
2
|
+
* Standings HTTP client — routed through the lsdapi proxy.
|
|
6
3
|
*/
|
|
7
4
|
export declare const standingsHttp: import("../http").Sportal365HttpClient;
|
|
8
5
|
//# sourceMappingURL=http.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/sportal365-sports/standings/http.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/sportal365-sports/standings/http.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,eAAO,MAAM,aAAa,wCAAiC,CAAC"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
const standingsHttp = createHttpClient(SPORTAL365_STANDINGS_DOMAIN);
|
|
1
|
+
import { createProxyClient } from "../http.js";
|
|
2
|
+
const standingsHttp = createProxyClient("/standing");
|
|
4
3
|
export {
|
|
5
4
|
standingsHttp
|
|
6
5
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sources":["../../../../src/lib/api/sportal365-sports/standings/http.ts"],"sourcesContent":["/**\n * Standings
|
|
1
|
+
{"version":3,"file":"http.js","sources":["../../../../src/lib/api/sportal365-sports/standings/http.ts"],"sourcesContent":["/**\n * Standings HTTP client — routed through the lsdapi proxy.\n */\n\nimport { createProxyClient } from \"../http\";\n\nexport const standingsHttp = createProxyClient(\"/standing\");\n"],"names":[],"mappings":";AAMO,MAAM,gBAAgB,kBAAkB,WAAW;"}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Statistics HTTP client
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* HTTP client configured for the Sportal365 Statistics API
|
|
2
|
+
* Statistics HTTP client — routed through the lsdapi proxy.
|
|
6
3
|
*/
|
|
7
4
|
export declare const statisticsHttp: import("../http").Sportal365HttpClient;
|
|
8
5
|
//# sourceMappingURL=http.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/sportal365-sports/statistics/http.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/sportal365-sports/statistics/http.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,eAAO,MAAM,cAAc,wCAA0C,CAAC"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
const statisticsHttp = createHttpClient(SPORTAL365_STATISTICS_DOMAIN);
|
|
1
|
+
import { createProxyClient } from "../http.js";
|
|
2
|
+
const statisticsHttp = createProxyClient("/sports-statistics");
|
|
4
3
|
export {
|
|
5
4
|
statisticsHttp
|
|
6
5
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sources":["../../../../src/lib/api/sportal365-sports/statistics/http.ts"],"sourcesContent":["/**\n * Statistics HTTP client
|
|
1
|
+
{"version":3,"file":"http.js","sources":["../../../../src/lib/api/sportal365-sports/statistics/http.ts"],"sourcesContent":["/**\n * Statistics HTTP client — routed through the lsdapi proxy.\n */\n\nimport { createProxyClient } from \"../http\";\n\nexport const statisticsHttp = createProxyClient(\"/sports-statistics\");\n"],"names":[],"mappings":";AAMO,MAAM,iBAAiB,kBAAkB,oBAAoB;"}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Tennis HTTP client
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* HTTP client configured for the Sportal365 Tennis API
|
|
2
|
+
* Tennis HTTP client — routed through the lsdapi proxy.
|
|
6
3
|
*/
|
|
7
4
|
export declare const tennisHttp: import("../http").Sportal365HttpClient;
|
|
8
5
|
//# sourceMappingURL=http.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/sportal365-sports/tennis/http.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/sportal365-sports/tennis/http.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,eAAO,MAAM,UAAU,wCAA+B,CAAC"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
const tennisHttp = createHttpClient(SPORTAL365_TENNIS_DOMAIN);
|
|
1
|
+
import { createProxyClient } from "../http.js";
|
|
2
|
+
const tennisHttp = createProxyClient("/tennis");
|
|
4
3
|
export {
|
|
5
4
|
tennisHttp
|
|
6
5
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sources":["../../../../src/lib/api/sportal365-sports/tennis/http.ts"],"sourcesContent":["/**\n * Tennis HTTP client
|
|
1
|
+
{"version":3,"file":"http.js","sources":["../../../../src/lib/api/sportal365-sports/tennis/http.ts"],"sourcesContent":["/**\n * Tennis HTTP client — routed through the lsdapi proxy.\n */\n\nimport { createProxyClient } from \"../http\";\n\nexport const tennisHttp = createProxyClient(\"/tennis\");\n"],"names":[],"mappings":";AAMO,MAAM,aAAa,kBAAkB,SAAS;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"match.d.ts","sourceRoot":"","sources":["../../../../../../src/lib/api/sportal365-sports/tennis/matches/transformers/match.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACR,aAAa,
|
|
1
|
+
{"version":3,"file":"match.d.ts","sourceRoot":"","sources":["../../../../../../src/lib/api/sportal365-sports/tennis/matches/transformers/match.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACR,aAAa,EAWhB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EACR,cAAc,EAIjB,MAAM,UAAU,CAAC;AA2NlB;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,aAAa,CA8CvE"}
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import { transformOdds } from "../../../shared/odds.transformer.js";
|
|
2
2
|
import { toProviderRefArray } from "../../../shared/providerRef.helper.js";
|
|
3
|
+
function transformCountry(rawCountry) {
|
|
4
|
+
if (!rawCountry) return void 0;
|
|
5
|
+
return {
|
|
6
|
+
id: rawCountry.id,
|
|
7
|
+
name: rawCountry.name,
|
|
8
|
+
flag: rawCountry.assets?.flag?.url
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function transformPlayerAssets(rawAssets) {
|
|
12
|
+
const headshot = rawAssets?.headshot?.url;
|
|
13
|
+
if (!headshot) return void 0;
|
|
14
|
+
return { logo: headshot, photo: headshot };
|
|
15
|
+
}
|
|
3
16
|
function transformStatus(raw) {
|
|
4
17
|
const typeMap = {
|
|
5
18
|
FINISHED: "finished",
|
|
@@ -25,11 +38,9 @@ function transformParticipant(raw) {
|
|
|
25
38
|
shortName: raw.short_name,
|
|
26
39
|
threeLetterCode: raw.three_letter_code,
|
|
27
40
|
type: "player",
|
|
28
|
-
country: raw.details?.[0]?.country
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
} : void 0,
|
|
32
|
-
gender: raw.details?.[0]?.gender
|
|
41
|
+
country: transformCountry(raw.details?.[0]?.country),
|
|
42
|
+
gender: raw.details?.[0]?.gender,
|
|
43
|
+
assets: transformPlayerAssets(raw.details?.[0]?.assets ?? raw.assets)
|
|
33
44
|
};
|
|
34
45
|
return player;
|
|
35
46
|
} else if (raw.type === "TEAM_DOUBLE" && raw.details && raw.details.length === 2) {
|
|
@@ -39,11 +50,9 @@ function transformParticipant(raw) {
|
|
|
39
50
|
shortName: raw.details[0].short_name,
|
|
40
51
|
threeLetterCode: raw.details[0].three_letter_code,
|
|
41
52
|
type: "player",
|
|
42
|
-
country: raw.details[0].country
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
} : void 0,
|
|
46
|
-
gender: raw.details[0].gender
|
|
53
|
+
country: transformCountry(raw.details[0].country),
|
|
54
|
+
gender: raw.details[0].gender,
|
|
55
|
+
assets: transformPlayerAssets(raw.details[0].assets)
|
|
47
56
|
};
|
|
48
57
|
const player2 = {
|
|
49
58
|
id: raw.details[1].id,
|
|
@@ -51,11 +60,9 @@ function transformParticipant(raw) {
|
|
|
51
60
|
shortName: raw.details[1].short_name,
|
|
52
61
|
threeLetterCode: raw.details[1].three_letter_code,
|
|
53
62
|
type: "player",
|
|
54
|
-
country: raw.details[1].country
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
} : void 0,
|
|
58
|
-
gender: raw.details[1].gender
|
|
63
|
+
country: transformCountry(raw.details[1].country),
|
|
64
|
+
gender: raw.details[1].gender,
|
|
65
|
+
assets: transformPlayerAssets(raw.details[1].assets)
|
|
59
66
|
};
|
|
60
67
|
const pair = {
|
|
61
68
|
id: raw.id,
|
|
@@ -73,10 +80,7 @@ function transformParticipant(raw) {
|
|
|
73
80
|
shortName: raw.short_name,
|
|
74
81
|
threeLetterCode: raw.three_letter_code,
|
|
75
82
|
type: "national",
|
|
76
|
-
country: raw.details?.[0]?.country
|
|
77
|
-
id: raw.details[0].country.id,
|
|
78
|
-
name: raw.details[0].country.name
|
|
79
|
-
} : void 0,
|
|
83
|
+
country: transformCountry(raw.details?.[0]?.country),
|
|
80
84
|
gender: raw.details?.[0]?.gender
|
|
81
85
|
};
|
|
82
86
|
return team;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"match.js","sources":["../../../../../../src/lib/api/sportal365-sports/tennis/matches/transformers/match.ts"],"sourcesContent":["/**\n * Tennis match transformation utilities\n * Transforms raw Tennis API match responses to canonical FUSports types\n */\n\nimport type {\n FUSportsMatch,\n FUSportsMatchStatus,\n FUSportsMatchTiming,\n FUSportsCompetitor,\n FUSportsPlayerCompetitor,\n FUSportsPairCompetitor,\n FUSportsTeamCompetitor,\n FUSportsCompetition,\n FUSportsMatchScore,\n FUSportsMatchWinner,\n} from \"../../../../../types/canonical\";\nimport type { RawTennisMatch, RawTennisParticipant } from \"../types\";\nimport { toProviderRefArray, transformOdds } from \"../../../shared\";\n\n/**\n * Transform raw tennis status to canonical format\n */\nfunction transformStatus(raw: RawTennisMatch[\"status\"]): FUSportsMatchStatus {\n const typeMap: Record<string, FUSportsMatchStatus[\"code\"]> = {\n FINISHED: \"finished\",\n NOT_STARTED: \"not_started\",\n LIVE: \"live\",\n INTERRUPTED: \"interrupted\",\n CANCELLED: \"cancelled\",\n POSTPONED: \"postponed\",\n };\n\n const normalizedType = raw.type.toUpperCase();\n return {\n code: typeMap[normalizedType] ?? \"not_started\",\n name: raw.name,\n shortName: raw.short_name,\n type: normalizedType as FUSportsMatchStatus[\"type\"],\n };\n}\n\n/**\n * Transform raw tennis participant to canonical competitor\n * Tennis can have: individual players, pairs (doubles), or teams\n */\nfunction transformParticipant(raw: RawTennisParticipant): FUSportsCompetitor {\n if (raw.type === \"PLAYER\") {\n // Single player\n const player: FUSportsPlayerCompetitor = {\n id: raw.id,\n name: raw.name,\n shortName: raw.short_name,\n threeLetterCode: raw.three_letter_code,\n type: \"player\",\n country: raw.details?.[0]?.country\n ? {\n id: raw.details[0].country.id,\n name: raw.details[0].country.name,\n }\n : undefined,\n gender: raw.details?.[0]?.gender as FUSportsPlayerCompetitor[\"gender\"],\n };\n return player;\n } else if (raw.type === \"TEAM_DOUBLE\" && raw.details && raw.details.length === 2) {\n // Pair/doubles team\n const player1: FUSportsPlayerCompetitor = {\n id: raw.details[0].id,\n name: raw.details[0].name,\n shortName: raw.details[0].short_name,\n threeLetterCode: raw.details[0].three_letter_code,\n type: \"player\",\n country: raw.details[0].country\n ? {\n id: raw.details[0].country.id,\n name: raw.details[0].country.name,\n }\n : undefined,\n gender: raw.details[0].gender as FUSportsPlayerCompetitor[\"gender\"],\n };\n\n const player2: FUSportsPlayerCompetitor = {\n id: raw.details[1].id,\n name: raw.details[1].name,\n shortName: raw.details[1].short_name,\n threeLetterCode: raw.details[1].three_letter_code,\n type: \"player\",\n country: raw.details[1].country\n ? {\n id: raw.details[1].country.id,\n name: raw.details[1].country.name,\n }\n : undefined,\n gender: raw.details[1].gender as FUSportsPlayerCompetitor[\"gender\"],\n };\n\n const pair: FUSportsPairCompetitor = {\n id: raw.id,\n name: raw.name,\n shortName: raw.short_name,\n threeLetterCode: raw.three_letter_code,\n type: \"pair\",\n players: [player1, player2],\n };\n return pair;\n } else {\n // Team (for team competitions like Davis Cup)\n const team: FUSportsTeamCompetitor = {\n id: raw.id,\n name: raw.name,\n shortName: raw.short_name,\n threeLetterCode: raw.three_letter_code,\n type: \"national\",\n country: raw.details?.[0]?.country\n ? {\n id: raw.details[0].country.id,\n name: raw.details[0].country.name,\n }\n : undefined,\n gender: raw.details?.[0]?.gender as FUSportsTeamCompetitor[\"gender\"],\n };\n return team;\n }\n}\n\n/**\n * Transform raw tennis timing to canonical format\n */\nfunction transformTiming(raw: RawTennisMatch): FUSportsMatchTiming {\n return {\n kickoffTime: new Date(raw.scheduled_start_time),\n phaseStartedAt: raw.started_at ? new Date(raw.started_at) : undefined,\n finishedAt: raw.finished_at ? new Date(raw.finished_at) : undefined,\n };\n}\n\n/**\n * Transform raw tennis competition to canonical format\n */\nfunction transformCompetition(raw: RawTennisMatch): FUSportsCompetition | undefined {\n if (!raw.tournament) return undefined;\n\n const tournament = raw.tournament;\n return {\n id: tournament.competition?.id ?? tournament.id,\n name: tournament.competition?.name ?? tournament.name,\n slug: tournament.competition?.slug ?? tournament.slug,\n type: \"TOURNAMENT\" as const,\n gender: tournament.gender as FUSportsCompetition[\"gender\"],\n region: \"INTERNATIONAL\" as const,\n country: tournament.country\n ? {\n id: tournament.country.id,\n name: tournament.country.name,\n }\n : undefined,\n };\n}\n\n/**\n * Transform raw tennis score to canonical format\n * Tennis scores are an array of sets with games\n */\nfunction transformScore(raw: RawTennisMatch): FUSportsMatchScore | undefined {\n if (!raw.results || raw.results.length === 0) return undefined;\n\n // Individual set entries have codes \"set1\", \"set2\", \"set3\", etc.\n // Other entries: \"gamescore\", \"setswon\", \"runningscore\", \"finalresult\"\n const setResults = raw.results.filter((r) => /^set\\d+$/i.test(r.type.code));\n if (setResults.length === 0) return undefined;\n\n const periods: Array<{ competitorOne: string; competitorTwo: string }> = [];\n\n for (const result of setResults) {\n const val1 = result.values.find((v) => v.position === \"1\");\n const val2 = result.values.find((v) => v.position === \"2\");\n\n if (!val1 || !val2 || val1.value == null || val2.value == null) continue;\n\n periods.push({\n competitorOne: val1.value,\n competitorTwo: val2.value,\n });\n }\n\n if (periods.length === 0) return undefined;\n\n // Use the \"setswon\" entry for the total sets score if available — more reliable than counting\n const setsWonResult = raw.results.find((r) => r.type.code === \"setswon\");\n const setsWonVal1 = setsWonResult?.values.find((v) => v.position === \"1\");\n const setsWonVal2 = setsWonResult?.values.find((v) => v.position === \"2\");\n\n let totalSetsOne: number;\n let totalSetsTwo: number;\n\n if (setsWonVal1?.value != null && setsWonVal2?.value != null) {\n totalSetsOne = parseInt(setsWonVal1.value);\n totalSetsTwo = parseInt(setsWonVal2.value);\n } else {\n // Fallback: count set wins from individual set entries\n totalSetsOne = periods.filter((p) => parseInt(p.competitorOne) > parseInt(p.competitorTwo)).length;\n totalSetsTwo = periods.filter((p) => parseInt(p.competitorTwo) > parseInt(p.competitorOne)).length;\n }\n\n return {\n competitorOne: String(totalSetsOne),\n competitorTwo: String(totalSetsTwo),\n breakdown: {\n total: {\n competitorOne: String(totalSetsOne),\n competitorTwo: String(totalSetsTwo),\n },\n periods,\n },\n };\n}\n\n/**\n * Transform raw tennis winner to canonical format\n */\nfunction transformWinner(raw: RawTennisMatch): FUSportsMatchWinner | undefined {\n const winner = raw.participants.find((p) => p.winner === \"YES\");\n if (!winner) return undefined;\n\n return {\n competitorId: winner.id,\n };\n}\n\n/**\n * Transform raw tennis match response to canonical FUSportsMatch\n */\nexport function transformTennisMatch(raw: RawTennisMatch): FUSportsMatch {\n const participants = raw.participants.sort((a, b) => a.position - b.position);\n\n return {\n id: raw.id,\n slug: raw.slug,\n sport: \"tennis\",\n status: transformStatus(raw.status),\n timing: transformTiming(raw),\n\n competitorOne: transformParticipant(participants[0]),\n competitorTwo: transformParticipant(participants[1]),\n\n competition: transformCompetition(raw),\n round: raw.round\n ? {\n id: raw.round.id,\n key: raw.round.uuid,\n name: raw.round.name,\n type: \"REGULAR\",\n providerRef: toProviderRefArray(raw.round.uuid),\n }\n : undefined,\n\n score: transformScore(raw),\n\n winner: transformWinner(raw),\n\n odds: raw.odds ? transformOdds(raw.odds) : undefined,\n\n coverage: raw.coverage?.type === \"NOT_LIVE\" ? \"UNKNOWN\" : (raw.coverage?.type as FUSportsMatch[\"coverage\"]),\n\n metadata: {\n matchType: raw.type,\n bestOfSets: raw.best_of_sets,\n surface: raw.tournament?.surface,\n indoorOutdoor: raw.tournament?.indoor_outdoor,\n },\n\n providerRef: [\n {\n provider: \"sportal365-tennis\",\n id: raw.id,\n },\n ],\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"match.js","sources":["../../../../../../src/lib/api/sportal365-sports/tennis/matches/transformers/match.ts"],"sourcesContent":["/**\n * Tennis match transformation utilities\n * Transforms raw Tennis API match responses to canonical FUSports types\n */\n\nimport type {\n FUSportsMatch,\n FUSportsMatchStatus,\n FUSportsMatchTiming,\n FUSportsCompetitor,\n FUSportsPlayerCompetitor,\n FUSportsPairCompetitor,\n FUSportsTeamCompetitor,\n FUSportsCompetition,\n FUSportsMatchScore,\n FUSportsMatchWinner,\n FUSportsCountry,\n} from \"../../../../../types/canonical\";\nimport type {\n RawTennisMatch,\n RawTennisParticipant,\n RawTennisCountry,\n RawTennisPlayerAssets,\n} from \"../types\";\nimport { toProviderRefArray, transformOdds } from \"../../../shared\";\n\n/**\n * Transform a raw tennis country to canonical, including the flag URL when present.\n */\nfunction transformCountry(rawCountry: RawTennisCountry | undefined): FUSportsCountry | undefined {\n if (!rawCountry) return undefined;\n return {\n id: rawCountry.id,\n name: rawCountry.name,\n flag: rawCountry.assets?.flag?.url,\n };\n}\n\n/**\n * Pull the player headshot out of raw assets and expose it as both logo and photo,\n * matching how the canonical player competitor surfaces visual assets.\n */\nfunction transformPlayerAssets(\n rawAssets: RawTennisPlayerAssets | undefined,\n): FUSportsPlayerCompetitor[\"assets\"] | undefined {\n const headshot = rawAssets?.headshot?.url;\n if (!headshot) return undefined;\n return { logo: headshot, photo: headshot };\n}\n\n/**\n * Transform raw tennis status to canonical format\n */\nfunction transformStatus(raw: RawTennisMatch[\"status\"]): FUSportsMatchStatus {\n const typeMap: Record<string, FUSportsMatchStatus[\"code\"]> = {\n FINISHED: \"finished\",\n NOT_STARTED: \"not_started\",\n LIVE: \"live\",\n INTERRUPTED: \"interrupted\",\n CANCELLED: \"cancelled\",\n POSTPONED: \"postponed\",\n };\n\n const normalizedType = raw.type.toUpperCase();\n return {\n code: typeMap[normalizedType] ?? \"not_started\",\n name: raw.name,\n shortName: raw.short_name,\n type: normalizedType as FUSportsMatchStatus[\"type\"],\n };\n}\n\n/**\n * Transform raw tennis participant to canonical competitor\n * Tennis can have: individual players, pairs (doubles), or teams\n */\nfunction transformParticipant(raw: RawTennisParticipant): FUSportsCompetitor {\n if (raw.type === \"PLAYER\") {\n // Single player\n const player: FUSportsPlayerCompetitor = {\n id: raw.id,\n name: raw.name,\n shortName: raw.short_name,\n threeLetterCode: raw.three_letter_code,\n type: \"player\",\n country: transformCountry(raw.details?.[0]?.country),\n gender: raw.details?.[0]?.gender as FUSportsPlayerCompetitor[\"gender\"],\n assets: transformPlayerAssets(raw.details?.[0]?.assets ?? raw.assets),\n };\n return player;\n } else if (raw.type === \"TEAM_DOUBLE\" && raw.details && raw.details.length === 2) {\n // Pair/doubles team\n const player1: FUSportsPlayerCompetitor = {\n id: raw.details[0].id,\n name: raw.details[0].name,\n shortName: raw.details[0].short_name,\n threeLetterCode: raw.details[0].three_letter_code,\n type: \"player\",\n country: transformCountry(raw.details[0].country),\n gender: raw.details[0].gender as FUSportsPlayerCompetitor[\"gender\"],\n assets: transformPlayerAssets(raw.details[0].assets),\n };\n\n const player2: FUSportsPlayerCompetitor = {\n id: raw.details[1].id,\n name: raw.details[1].name,\n shortName: raw.details[1].short_name,\n threeLetterCode: raw.details[1].three_letter_code,\n type: \"player\",\n country: transformCountry(raw.details[1].country),\n gender: raw.details[1].gender as FUSportsPlayerCompetitor[\"gender\"],\n assets: transformPlayerAssets(raw.details[1].assets),\n };\n\n const pair: FUSportsPairCompetitor = {\n id: raw.id,\n name: raw.name,\n shortName: raw.short_name,\n threeLetterCode: raw.three_letter_code,\n type: \"pair\",\n players: [player1, player2],\n };\n return pair;\n } else {\n // Team (for team competitions like Davis Cup)\n const team: FUSportsTeamCompetitor = {\n id: raw.id,\n name: raw.name,\n shortName: raw.short_name,\n threeLetterCode: raw.three_letter_code,\n type: \"national\",\n country: transformCountry(raw.details?.[0]?.country),\n gender: raw.details?.[0]?.gender as FUSportsTeamCompetitor[\"gender\"],\n };\n return team;\n }\n}\n\n/**\n * Transform raw tennis timing to canonical format\n */\nfunction transformTiming(raw: RawTennisMatch): FUSportsMatchTiming {\n return {\n kickoffTime: new Date(raw.scheduled_start_time),\n phaseStartedAt: raw.started_at ? new Date(raw.started_at) : undefined,\n finishedAt: raw.finished_at ? new Date(raw.finished_at) : undefined,\n };\n}\n\n/**\n * Transform raw tennis competition to canonical format\n */\nfunction transformCompetition(raw: RawTennisMatch): FUSportsCompetition | undefined {\n if (!raw.tournament) return undefined;\n\n const tournament = raw.tournament;\n return {\n id: tournament.competition?.id ?? tournament.id,\n name: tournament.competition?.name ?? tournament.name,\n slug: tournament.competition?.slug ?? tournament.slug,\n type: \"TOURNAMENT\" as const,\n gender: tournament.gender as FUSportsCompetition[\"gender\"],\n region: \"INTERNATIONAL\" as const,\n country: tournament.country\n ? {\n id: tournament.country.id,\n name: tournament.country.name,\n }\n : undefined,\n };\n}\n\n/**\n * Transform raw tennis score to canonical format\n * Tennis scores are an array of sets with games\n */\nfunction transformScore(raw: RawTennisMatch): FUSportsMatchScore | undefined {\n if (!raw.results || raw.results.length === 0) return undefined;\n\n // Individual set entries have codes \"set1\", \"set2\", \"set3\", etc.\n // Other entries: \"gamescore\", \"setswon\", \"runningscore\", \"finalresult\"\n const setResults = raw.results.filter((r) => /^set\\d+$/i.test(r.type.code));\n if (setResults.length === 0) return undefined;\n\n const periods: Array<{ competitorOne: string; competitorTwo: string }> = [];\n\n for (const result of setResults) {\n const val1 = result.values.find((v) => v.position === \"1\");\n const val2 = result.values.find((v) => v.position === \"2\");\n\n if (!val1 || !val2 || val1.value == null || val2.value == null) continue;\n\n periods.push({\n competitorOne: val1.value,\n competitorTwo: val2.value,\n });\n }\n\n if (periods.length === 0) return undefined;\n\n // Use the \"setswon\" entry for the total sets score if available — more reliable than counting\n const setsWonResult = raw.results.find((r) => r.type.code === \"setswon\");\n const setsWonVal1 = setsWonResult?.values.find((v) => v.position === \"1\");\n const setsWonVal2 = setsWonResult?.values.find((v) => v.position === \"2\");\n\n let totalSetsOne: number;\n let totalSetsTwo: number;\n\n if (setsWonVal1?.value != null && setsWonVal2?.value != null) {\n totalSetsOne = parseInt(setsWonVal1.value);\n totalSetsTwo = parseInt(setsWonVal2.value);\n } else {\n // Fallback: count set wins from individual set entries\n totalSetsOne = periods.filter((p) => parseInt(p.competitorOne) > parseInt(p.competitorTwo)).length;\n totalSetsTwo = periods.filter((p) => parseInt(p.competitorTwo) > parseInt(p.competitorOne)).length;\n }\n\n return {\n competitorOne: String(totalSetsOne),\n competitorTwo: String(totalSetsTwo),\n breakdown: {\n total: {\n competitorOne: String(totalSetsOne),\n competitorTwo: String(totalSetsTwo),\n },\n periods,\n },\n };\n}\n\n/**\n * Transform raw tennis winner to canonical format\n */\nfunction transformWinner(raw: RawTennisMatch): FUSportsMatchWinner | undefined {\n const winner = raw.participants.find((p) => p.winner === \"YES\");\n if (!winner) return undefined;\n\n return {\n competitorId: winner.id,\n };\n}\n\n/**\n * Transform raw tennis match response to canonical FUSportsMatch\n */\nexport function transformTennisMatch(raw: RawTennisMatch): FUSportsMatch {\n const participants = raw.participants.sort((a, b) => a.position - b.position);\n\n return {\n id: raw.id,\n slug: raw.slug,\n sport: \"tennis\",\n status: transformStatus(raw.status),\n timing: transformTiming(raw),\n\n competitorOne: transformParticipant(participants[0]),\n competitorTwo: transformParticipant(participants[1]),\n\n competition: transformCompetition(raw),\n round: raw.round\n ? {\n id: raw.round.id,\n key: raw.round.uuid,\n name: raw.round.name,\n type: \"REGULAR\",\n providerRef: toProviderRefArray(raw.round.uuid),\n }\n : undefined,\n\n score: transformScore(raw),\n\n winner: transformWinner(raw),\n\n odds: raw.odds ? transformOdds(raw.odds) : undefined,\n\n coverage: raw.coverage?.type === \"NOT_LIVE\" ? \"UNKNOWN\" : (raw.coverage?.type as FUSportsMatch[\"coverage\"]),\n\n metadata: {\n matchType: raw.type,\n bestOfSets: raw.best_of_sets,\n surface: raw.tournament?.surface,\n indoorOutdoor: raw.tournament?.indoor_outdoor,\n },\n\n providerRef: [\n {\n provider: \"sportal365-tennis\",\n id: raw.id,\n },\n ],\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -3,11 +3,21 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type { NextCacheOptions } from "../../http";
|
|
5
5
|
import type { RawMatchOdd } from "../../shared/odds.types";
|
|
6
|
+
export interface RawTennisAsset {
|
|
7
|
+
url: string;
|
|
8
|
+
}
|
|
9
|
+
export interface RawTennisCountryAssets {
|
|
10
|
+
flag?: RawTennisAsset;
|
|
11
|
+
}
|
|
12
|
+
export interface RawTennisPlayerAssets {
|
|
13
|
+
headshot?: RawTennisAsset;
|
|
14
|
+
}
|
|
6
15
|
export interface RawTennisCountry {
|
|
7
16
|
id: string;
|
|
8
17
|
name: string;
|
|
9
18
|
slug: string;
|
|
10
19
|
entity_type: string;
|
|
20
|
+
assets?: RawTennisCountryAssets;
|
|
11
21
|
}
|
|
12
22
|
export interface RawTennisPlayer {
|
|
13
23
|
id: string;
|
|
@@ -36,6 +46,7 @@ export interface RawTennisParticipantProfile {
|
|
|
36
46
|
entity_type: string;
|
|
37
47
|
short_name?: string;
|
|
38
48
|
three_letter_code?: string;
|
|
49
|
+
assets?: RawTennisPlayerAssets;
|
|
39
50
|
}
|
|
40
51
|
export interface RawTennisParticipant {
|
|
41
52
|
id: string;
|
|
@@ -48,6 +59,8 @@ export interface RawTennisParticipant {
|
|
|
48
59
|
three_letter_code?: string;
|
|
49
60
|
entity_type: string;
|
|
50
61
|
current_server?: "NOT_AVAILABLE" | "YES" | "NO";
|
|
62
|
+
/** Fallback assets attached directly to the participant (some payloads carry headshot here instead of in details[0]) */
|
|
63
|
+
assets?: RawTennisPlayerAssets;
|
|
51
64
|
}
|
|
52
65
|
export interface RawTennisStatus {
|
|
53
66
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/lib/api/sportal365-sports/tennis/matches/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAM3D,MAAM,WAAW,gBAAgB;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/lib/api/sportal365-sports/tennis/matches/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"description": "A TypeScript library for fetching and transforming sports data from multiple API providers. Returns clean, canonical types that are provider-agnostic.",
|
|
5
5
|
"homepage": "https://fansunited.com/",
|
|
6
6
|
"private": false,
|
|
7
|
-
"version": "0.
|
|
7
|
+
"version": "0.15.0",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"sideEffects": false,
|
|
10
10
|
"module": "./fansunited-data-layer.js",
|