fansunited-data-layer 0.13.0 → 0.14.2
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/fansunited/constants.js +5 -0
- package/api/fansunited/constants.js.map +1 -0
- package/api/fansunited/football/competition/index.js +21 -0
- package/api/fansunited/football/competition/index.js.map +1 -0
- package/api/fansunited/football/competition/transformer.js +41 -0
- package/api/fansunited/football/competition/transformer.js.map +1 -0
- package/api/fansunited/football/competitions/index.js +56 -0
- package/api/fansunited/football/competitions/index.js.map +1 -0
- package/api/fansunited/football/competitions/transformer.js +68 -0
- package/api/fansunited/football/competitions/transformer.js.map +1 -0
- package/api/fansunited/football/http.js +7 -0
- package/api/fansunited/football/http.js.map +1 -0
- package/api/fansunited/football/matches/index.js +132 -0
- package/api/fansunited/football/matches/index.js.map +1 -0
- package/api/fansunited/football/matches/transformer.js +148 -0
- package/api/fansunited/football/matches/transformer.js.map +1 -0
- package/api/fansunited/football/players/index.js +60 -0
- package/api/fansunited/football/players/index.js.map +1 -0
- package/api/fansunited/football/players/transformer.js +85 -0
- package/api/fansunited/football/players/transformer.js.map +1 -0
- package/api/fansunited/football/search/index.js +64 -0
- package/api/fansunited/football/search/index.js.map +1 -0
- package/api/fansunited/football/search/transformer.js +114 -0
- package/api/fansunited/football/search/transformer.js.map +1 -0
- package/api/fansunited/football/teams/index.js +66 -0
- package/api/fansunited/football/teams/index.js.map +1 -0
- package/api/fansunited/football/teams/transformer.js +53 -0
- package/api/fansunited/football/teams/transformer.js.map +1 -0
- package/api/fansunited/http.d.ts.map +1 -1
- package/api/fansunited/http.js +70 -0
- package/api/fansunited/http.js.map +1 -0
- package/api/fansunited/search/constants.js +5 -0
- package/api/fansunited/search/constants.js.map +1 -0
- package/api/fansunited/search/http.js +7 -0
- package/api/fansunited/search/http.js.map +1 -0
- package/api/fansunited/search/index.js +308 -0
- package/api/fansunited/search/index.js.map +1 -0
- package/api/fansunited/search/transformer.js +374 -0
- package/api/fansunited/search/transformer.js.map +1 -0
- package/api/fansunited-sdk/loyalty/matches.js +21 -0
- package/api/fansunited-sdk/loyalty/matches.js.map +1 -0
- package/api/fansunited-sdk/loyalty/template.js +52 -0
- package/api/fansunited-sdk/loyalty/template.js.map +1 -0
- package/api/fansunited-sdk/odds/matches.js +109 -0
- package/api/fansunited-sdk/odds/matches.js.map +1 -0
- package/api/sportal365-sports/basketball/games/index.js +32 -0
- package/api/sportal365-sports/basketball/games/index.js.map +1 -0
- package/api/sportal365-sports/basketball/games/transformers/game.js +137 -0
- package/api/sportal365-sports/basketball/games/transformers/game.js.map +1 -0
- package/api/sportal365-sports/basketball/http.js +7 -0
- package/api/sportal365-sports/basketball/http.js.map +1 -0
- package/api/sportal365-sports/constants.js +15 -0
- package/api/sportal365-sports/constants.js.map +1 -0
- package/api/sportal365-sports/football/competitions/index.js +52 -0
- package/api/sportal365-sports/football/competitions/index.js.map +1 -0
- package/api/sportal365-sports/football/competitions/utils.js +92 -0
- package/api/sportal365-sports/football/competitions/utils.js.map +1 -0
- package/api/sportal365-sports/football/http.js +7 -0
- package/api/sportal365-sports/football/http.js.map +1 -0
- package/api/sportal365-sports/football/matches/index.js +206 -0
- package/api/sportal365-sports/football/matches/index.js.map +1 -0
- package/api/sportal365-sports/football/matches/transformers/commentary.js +27 -0
- package/api/sportal365-sports/football/matches/transformers/commentary.js.map +1 -0
- package/api/sportal365-sports/football/matches/transformers/lineup.js +74 -0
- package/api/sportal365-sports/football/matches/transformers/lineup.js.map +1 -0
- package/api/sportal365-sports/football/matches/transformers/match-event.js +60 -0
- package/api/sportal365-sports/football/matches/transformers/match-event.js.map +1 -0
- package/api/sportal365-sports/football/matches/transformers/match.js +195 -0
- package/api/sportal365-sports/football/matches/transformers/match.js.map +1 -0
- package/api/sportal365-sports/football/matches/transformers/odds.js +11 -0
- package/api/sportal365-sports/football/matches/transformers/odds.js.map +1 -0
- package/api/sportal365-sports/football/matches/transformers/statistics.js +41 -0
- package/api/sportal365-sports/football/matches/transformers/statistics.js.map +1 -0
- package/api/sportal365-sports/football/search/index.js +42 -0
- package/api/sportal365-sports/football/search/index.js.map +1 -0
- package/api/sportal365-sports/football/search/search.transformer.js +166 -0
- package/api/sportal365-sports/football/search/search.transformer.js.map +1 -0
- package/api/sportal365-sports/football/standings/index.js +28 -0
- package/api/sportal365-sports/football/standings/index.js.map +1 -0
- package/api/sportal365-sports/football/standings/standing.transformer.js +107 -0
- package/api/sportal365-sports/football/standings/standing.transformer.js.map +1 -0
- package/api/sportal365-sports/football/statistics/index.js +154 -0
- package/api/sportal365-sports/football/statistics/index.js.map +1 -0
- package/api/sportal365-sports/football/statistics/player-career.transformer.js +77 -0
- package/api/sportal365-sports/football/statistics/player-career.transformer.js.map +1 -0
- package/api/sportal365-sports/football/statistics/player-recent.transformer.js +54 -0
- package/api/sportal365-sports/football/statistics/player-recent.transformer.js.map +1 -0
- package/api/sportal365-sports/football/statistics/player-season.transformer.js +147 -0
- package/api/sportal365-sports/football/statistics/player-season.transformer.js.map +1 -0
- package/api/sportal365-sports/football/teams/index.js +73 -0
- package/api/sportal365-sports/football/teams/index.js.map +1 -0
- package/api/sportal365-sports/football/teams/utils.js +196 -0
- package/api/sportal365-sports/football/teams/utils.js.map +1 -0
- package/api/sportal365-sports/http.js +58 -0
- package/api/sportal365-sports/http.js.map +1 -0
- package/api/sportal365-sports/search/http.js +7 -0
- package/api/sportal365-sports/search/http.js.map +1 -0
- package/api/sportal365-sports/search/index.js +61 -0
- package/api/sportal365-sports/search/index.js.map +1 -0
- package/api/sportal365-sports/search/search.transformer.js +254 -0
- package/api/sportal365-sports/search/search.transformer.js.map +1 -0
- package/api/sportal365-sports/shared/odds.transformer.js +65 -0
- package/api/sportal365-sports/shared/odds.transformer.js.map +1 -0
- package/api/sportal365-sports/shared/providerRef.helper.js +31 -0
- package/api/sportal365-sports/shared/providerRef.helper.js.map +1 -0
- package/api/sportal365-sports/standings/http.js +7 -0
- package/api/sportal365-sports/standings/http.js.map +1 -0
- package/api/sportal365-sports/standings/index.js +29 -0
- package/api/sportal365-sports/standings/index.js.map +1 -0
- package/api/sportal365-sports/standings/standing.transformer.js +185 -0
- package/api/sportal365-sports/standings/standing.transformer.js.map +1 -0
- package/api/sportal365-sports/statistics/http.js +7 -0
- package/api/sportal365-sports/statistics/http.js.map +1 -0
- package/api/sportal365-sports/statistics/index.js +25 -0
- package/api/sportal365-sports/statistics/index.js.map +1 -0
- package/api/sportal365-sports/statistics/team-stats.transformer.js +16 -0
- package/api/sportal365-sports/statistics/team-stats.transformer.js.map +1 -0
- package/api/sportal365-sports/tennis/http.js +7 -0
- package/api/sportal365-sports/tennis/http.js.map +1 -0
- package/api/sportal365-sports/tennis/matches/index.js +34 -0
- package/api/sportal365-sports/tennis/matches/index.js.map +1 -0
- package/api/sportal365-sports/tennis/matches/transformers/match.js +193 -0
- package/api/sportal365-sports/tennis/matches/transformers/match.js.map +1 -0
- package/cache/cache-manager.js +136 -0
- package/cache/cache-manager.js.map +1 -0
- package/cache/memory-store.js +29 -0
- package/cache/memory-store.js.map +1 -0
- package/client.js +38 -12337
- package/client.js.map +1 -0
- package/config/index.js +20 -0
- package/config/index.js.map +1 -0
- package/fansunited-data-layer.js +146 -3553
- package/fansunited-data-layer.js.map +1 -0
- package/helpers/competition.helpers.js +11 -0
- package/helpers/competition.helpers.js.map +1 -0
- package/helpers/player.helpers.js +165 -0
- package/helpers/player.helpers.js.map +1 -0
- package/helpers/player.hooks.js +34 -0
- package/helpers/player.hooks.js.map +1 -0
- package/helpers/team.helpers.js +216 -0
- package/helpers/team.helpers.js.map +1 -0
- package/package.json +6 -8
- package/providers/competition/hooks/useCompetitionStats.js +10 -0
- package/providers/competition/hooks/useCompetitionStats.js.map +1 -0
- package/providers/competition/hooks/useGoalDistribution.js +23 -0
- package/providers/competition/hooks/useGoalDistribution.js.map +1 -0
- package/providers/competition/hooks/useMatchHelpers.js +85 -0
- package/providers/competition/hooks/useMatchHelpers.js.map +1 -0
- package/providers/competition/hooks/useStandingsCalculations.js +89 -0
- package/providers/competition/hooks/useStandingsCalculations.js.map +1 -0
- package/providers/competition/hooks/useStandingsHelpers.js +61 -0
- package/providers/competition/hooks/useStandingsHelpers.js.map +1 -0
- package/providers/competition/hooks/useTeamPosition.js +15 -0
- package/providers/competition/hooks/useTeamPosition.js.map +1 -0
- package/providers/competition/hooks/useTeamResultsTable.js +86 -0
- package/providers/competition/hooks/useTeamResultsTable.js.map +1 -0
- package/providers/competition/utils/competitionStats.js +109 -0
- package/providers/competition/utils/competitionStats.js.map +1 -0
- package/providers/competition/utils/goalDistribution.js +64 -0
- package/providers/competition/utils/goalDistribution.js.map +1 -0
- package/providers/competition/utils/standingsCalculations.js +152 -0
- package/providers/competition/utils/standingsCalculations.js.map +1 -0
- package/providers/competition.context.js +14 -0
- package/providers/competition.context.js.map +1 -0
- package/providers/competition.provider.js +187 -0
- package/providers/competition.provider.js.map +1 -0
- package/providers/fansunited-config.context.js +6 -0
- package/providers/fansunited-config.context.js.map +1 -0
- package/providers/fansunited-config.hooks.js +20 -0
- package/providers/fansunited-config.hooks.js.map +1 -0
- package/providers/fansunited-config.provider.js +9 -0
- package/providers/fansunited-config.provider.js.map +1 -0
- package/providers/fansunited-sdk.hook.js +50 -0
- package/providers/fansunited-sdk.hook.js.map +1 -0
- package/providers/leaderboard/hooks/useMatchHelpers.js +30 -0
- package/providers/leaderboard/hooks/useMatchHelpers.js.map +1 -0
- package/providers/leaderboard/hooks/useTemplateHelpers.js +39 -0
- package/providers/leaderboard/hooks/useTemplateHelpers.js.map +1 -0
- package/providers/leaderboard.context.js +14 -0
- package/providers/leaderboard.context.js.map +1 -0
- package/providers/leaderboard.provider.js +98 -0
- package/providers/leaderboard.provider.js.map +1 -0
- package/providers/match/hooks/useBatchMatchOdds.js +72 -0
- package/providers/match/hooks/useBatchMatchOdds.js.map +1 -0
- package/providers/match/hooks/useEventHelpers.js +46 -0
- package/providers/match/hooks/useEventHelpers.js.map +1 -0
- package/providers/match/hooks/useHeadToHeadHelpers.js +52 -0
- package/providers/match/hooks/useHeadToHeadHelpers.js.map +1 -0
- package/providers/match/hooks/useLineupHelpers.js +53 -0
- package/providers/match/hooks/useLineupHelpers.js.map +1 -0
- package/providers/match/hooks/useMatchStandingsCalculations.js +332 -0
- package/providers/match/hooks/useMatchStandingsCalculations.js.map +1 -0
- package/providers/match/hooks/useMatchStatus.js +37 -0
- package/providers/match/hooks/useMatchStatus.js.map +1 -0
- package/providers/match/hooks/useOddsHelpers.js +54 -0
- package/providers/match/hooks/useOddsHelpers.js.map +1 -0
- package/providers/match/hooks/useScoreHelpers.js +34 -0
- package/providers/match/hooks/useScoreHelpers.js.map +1 -0
- package/providers/match/hooks/useStandingsHelpers.js +53 -0
- package/providers/match/hooks/useStandingsHelpers.js.map +1 -0
- package/providers/match/hooks/useStatisticsHelpers.js +40 -0
- package/providers/match/hooks/useStatisticsHelpers.js.map +1 -0
- package/providers/match/hooks/useTeamHelpers.js +38 -0
- package/providers/match/hooks/useTeamHelpers.js.map +1 -0
- package/providers/match/hooks/useTeamStatsHelpers.js +141 -0
- package/providers/match/hooks/useTeamStatsHelpers.js.map +1 -0
- package/providers/match.context.js +14 -0
- package/providers/match.context.js.map +1 -0
- package/providers/match.provider.js +176 -0
- package/providers/match.provider.js.map +1 -0
- package/providers/team/hooks/useFormStats.js +116 -0
- package/providers/team/hooks/useFormStats.js.map +1 -0
- package/providers/team/hooks/useMatchHelpers.js +46 -0
- package/providers/team/hooks/useMatchHelpers.js.map +1 -0
- package/providers/team/hooks/useSquadHelpers.js +67 -0
- package/providers/team/hooks/useSquadHelpers.js.map +1 -0
- package/providers/team.context.js +14 -0
- package/providers/team.context.js.map +1 -0
- package/providers/team.provider.js +98 -0
- package/providers/team.provider.js.map +1 -0
- package/utilities/stats/core/helpers.js +105 -0
- package/utilities/stats/core/helpers.js.map +1 -0
- package/utilities/stats/core/types.js +5 -0
- package/utilities/stats/core/types.js.map +1 -0
- package/utilities/stats/match/headToHead.js +83 -0
- package/utilities/stats/match/headToHead.js.map +1 -0
- package/utilities/stats/match/homeVsAway.js +140 -0
- package/utilities/stats/match/homeVsAway.js.map +1 -0
- package/utilities/stats/match/overUnder.js +91 -0
- package/utilities/stats/match/overUnder.js.map +1 -0
- package/utilities/stats/match/result.js +21 -0
- package/utilities/stats/match/result.js.map +1 -0
- package/utilities/stats/team/commonOpponents.js +77 -0
- package/utilities/stats/team/commonOpponents.js.map +1 -0
- package/utilities/stats/team/goalStats.js +50 -0
- package/utilities/stats/team/goalStats.js.map +1 -0
- package/utilities/stats/team/streaks.js +183 -0
- package/utilities/stats/team/streaks.js.map +1 -0
- package/client.cjs +0 -8
- package/fansunited-data-layer.cjs +0 -1
- package/matches-BvHU-bP0.js +0 -1795
- package/matches-Ci0Ci_Mw.cjs +0 -1
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { transformMatch } from "../matches/transformers/match.js";
|
|
2
|
+
function parseStatValue(value) {
|
|
3
|
+
const parsed = parseInt(value, 10);
|
|
4
|
+
return isNaN(parsed) ? void 0 : parsed;
|
|
5
|
+
}
|
|
6
|
+
function getStatValue(statistics, name) {
|
|
7
|
+
const stat = statistics.find((s) => s.name === name);
|
|
8
|
+
return stat ? parseStatValue(stat.value) : void 0;
|
|
9
|
+
}
|
|
10
|
+
function transformTeam(raw) {
|
|
11
|
+
return {
|
|
12
|
+
id: raw.id,
|
|
13
|
+
name: raw.name,
|
|
14
|
+
uuid: raw.uuid,
|
|
15
|
+
threeLetterCode: raw.three_letter_code,
|
|
16
|
+
type: raw.type,
|
|
17
|
+
logo: raw.assets?.logo?.url
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function transformPlayerRecentStatistics(raw) {
|
|
21
|
+
const stats = raw.aggregated_statistics;
|
|
22
|
+
return {
|
|
23
|
+
playerId: raw.player.id,
|
|
24
|
+
playerName: raw.player.name,
|
|
25
|
+
playerUuid: raw.player.uuid,
|
|
26
|
+
position: raw.player.position,
|
|
27
|
+
teams: raw.teams.map(transformTeam),
|
|
28
|
+
matches: raw.matches.map(transformMatch),
|
|
29
|
+
// Core statistics
|
|
30
|
+
appearances: getStatValue(stats, "played"),
|
|
31
|
+
started: getStatValue(stats, "started"),
|
|
32
|
+
substituteIn: getStatValue(stats, "substitute_in"),
|
|
33
|
+
substituteOut: getStatValue(stats, "substitute_out"),
|
|
34
|
+
minutes: getStatValue(stats, "minutes"),
|
|
35
|
+
minutesSubstitute: getStatValue(stats, "minutes_substitute"),
|
|
36
|
+
// Scoring
|
|
37
|
+
goals: getStatValue(stats, "goals"),
|
|
38
|
+
goalsSubstitute: getStatValue(stats, "goals_substitute"),
|
|
39
|
+
penaltyGoals: getStatValue(stats, "penalty_goals"),
|
|
40
|
+
assists: getStatValue(stats, "assists"),
|
|
41
|
+
// Discipline
|
|
42
|
+
yellowCards: getStatValue(stats, "yellow_cards"),
|
|
43
|
+
redCards: getStatValue(stats, "red_cards"),
|
|
44
|
+
// Raw statistics array
|
|
45
|
+
rawStatistics: stats.map((s) => ({
|
|
46
|
+
name: s.name,
|
|
47
|
+
value: s.value
|
|
48
|
+
}))
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export {
|
|
52
|
+
transformPlayerRecentStatistics
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=player-recent.transformer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"player-recent.transformer.js","sources":["../../../../../src/lib/api/sportal365-sports/football/statistics/player-recent.transformer.ts"],"sourcesContent":["/**\n * Player recent statistics transformation utilities\n * Transforms raw /v2/statistics/players/{id}/recent-statistics responses to canonical FUSports types\n */\n\nimport type { FUSportsPlayerRecentStatistics, FUSportsCareerTeam } from \"../../../../types/canonical\";\nimport type { RawPlayerRecentStatisticsResponse } from \"./player-recent.types\";\nimport type { RawPlayerStatistic, RawTeamInfo } from \"./player-season.types\";\nimport { transformMatch } from \"../matches/transformers/match\";\n\n/**\n * Parse a statistic value to number\n */\nfunction parseStatValue(value: string): number | undefined {\n const parsed = parseInt(value, 10);\n return isNaN(parsed) ? undefined : parsed;\n}\n\n/**\n * Get a specific statistic value by name\n */\nfunction getStatValue(statistics: RawPlayerStatistic[], name: string): number | undefined {\n const stat = statistics.find((s) => s.name === name);\n return stat ? parseStatValue(stat.value) : undefined;\n}\n\n/**\n * Transform raw team info to canonical career team\n */\nfunction transformTeam(raw: RawTeamInfo): FUSportsCareerTeam {\n return {\n id: raw.id,\n name: raw.name,\n uuid: raw.uuid,\n threeLetterCode: raw.three_letter_code,\n type: raw.type,\n logo: raw.assets?.logo?.url,\n };\n}\n\n/**\n * Transform raw player recent statistics response to canonical type\n */\nexport function transformPlayerRecentStatistics(\n raw: RawPlayerRecentStatisticsResponse\n): FUSportsPlayerRecentStatistics {\n const stats = raw.aggregated_statistics;\n\n return {\n playerId: raw.player.id,\n playerName: raw.player.name,\n playerUuid: raw.player.uuid,\n position: raw.player.position,\n\n teams: raw.teams.map(transformTeam),\n matches: raw.matches.map(transformMatch),\n\n // Core statistics\n appearances: getStatValue(stats, \"played\"),\n started: getStatValue(stats, \"started\"),\n substituteIn: getStatValue(stats, \"substitute_in\"),\n substituteOut: getStatValue(stats, \"substitute_out\"),\n minutes: getStatValue(stats, \"minutes\"),\n minutesSubstitute: getStatValue(stats, \"minutes_substitute\"),\n\n // Scoring\n goals: getStatValue(stats, \"goals\"),\n goalsSubstitute: getStatValue(stats, \"goals_substitute\"),\n penaltyGoals: getStatValue(stats, \"penalty_goals\"),\n assists: getStatValue(stats, \"assists\"),\n\n // Discipline\n yellowCards: getStatValue(stats, \"yellow_cards\"),\n redCards: getStatValue(stats, \"red_cards\"),\n\n // Raw statistics array\n rawStatistics: stats.map((s) => ({\n name: s.name,\n value: s.value,\n })),\n };\n}\n"],"names":[],"mappings":";AAaA,SAAS,eAAe,OAAmC;AACvD,QAAM,SAAS,SAAS,OAAO,EAAE;AACjC,SAAO,MAAM,MAAM,IAAI,SAAY;AACvC;AAKA,SAAS,aAAa,YAAkC,MAAkC;AACtF,QAAM,OAAO,WAAW,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AACnD,SAAO,OAAO,eAAe,KAAK,KAAK,IAAI;AAC/C;AAKA,SAAS,cAAc,KAAsC;AACzD,SAAO;AAAA,IACH,IAAI,IAAI;AAAA,IACR,MAAM,IAAI;AAAA,IACV,MAAM,IAAI;AAAA,IACV,iBAAiB,IAAI;AAAA,IACrB,MAAM,IAAI;AAAA,IACV,MAAM,IAAI,QAAQ,MAAM;AAAA,EAAA;AAEhC;AAKO,SAAS,gCACZ,KAC8B;AAC9B,QAAM,QAAQ,IAAI;AAElB,SAAO;AAAA,IACH,UAAU,IAAI,OAAO;AAAA,IACrB,YAAY,IAAI,OAAO;AAAA,IACvB,YAAY,IAAI,OAAO;AAAA,IACvB,UAAU,IAAI,OAAO;AAAA,IAErB,OAAO,IAAI,MAAM,IAAI,aAAa;AAAA,IAClC,SAAS,IAAI,QAAQ,IAAI,cAAc;AAAA;AAAA,IAGvC,aAAa,aAAa,OAAO,QAAQ;AAAA,IACzC,SAAS,aAAa,OAAO,SAAS;AAAA,IACtC,cAAc,aAAa,OAAO,eAAe;AAAA,IACjD,eAAe,aAAa,OAAO,gBAAgB;AAAA,IACnD,SAAS,aAAa,OAAO,SAAS;AAAA,IACtC,mBAAmB,aAAa,OAAO,oBAAoB;AAAA;AAAA,IAG3D,OAAO,aAAa,OAAO,OAAO;AAAA,IAClC,iBAAiB,aAAa,OAAO,kBAAkB;AAAA,IACvD,cAAc,aAAa,OAAO,eAAe;AAAA,IACjD,SAAS,aAAa,OAAO,SAAS;AAAA;AAAA,IAGtC,aAAa,aAAa,OAAO,cAAc;AAAA,IAC/C,UAAU,aAAa,OAAO,WAAW;AAAA;AAAA,IAGzC,eAAe,MAAM,IAAI,CAAC,OAAO;AAAA,MAC7B,MAAM,EAAE;AAAA,MACR,OAAO,EAAE;AAAA,IAAA,EACX;AAAA,EAAA;AAEV;"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
function parseStatValue(value) {
|
|
2
|
+
const parsed = parseInt(value, 10);
|
|
3
|
+
return isNaN(parsed) ? void 0 : parsed;
|
|
4
|
+
}
|
|
5
|
+
function getStatValue(statistics, name) {
|
|
6
|
+
const stat = statistics.find((s) => s.name === name);
|
|
7
|
+
return stat ? parseStatValue(stat.value) : void 0;
|
|
8
|
+
}
|
|
9
|
+
function transformPlayerSeasonStatistics(raw, teamId) {
|
|
10
|
+
const stats = raw.statistics;
|
|
11
|
+
return {
|
|
12
|
+
playerId: raw.player.id,
|
|
13
|
+
seasonId: raw.season.id,
|
|
14
|
+
teamId,
|
|
15
|
+
// Core statistics
|
|
16
|
+
appearances: getStatValue(stats, "played"),
|
|
17
|
+
started: getStatValue(stats, "started"),
|
|
18
|
+
substituteIn: getStatValue(stats, "substitute_in"),
|
|
19
|
+
substituteOut: getStatValue(stats, "substitute_out"),
|
|
20
|
+
minutes: getStatValue(stats, "minutes"),
|
|
21
|
+
minutesSubstitute: getStatValue(stats, "minutes_substitute"),
|
|
22
|
+
// Scoring
|
|
23
|
+
goals: getStatValue(stats, "goals"),
|
|
24
|
+
goalsSubstitute: getStatValue(stats, "goals_substitute"),
|
|
25
|
+
penaltyGoals: getStatValue(stats, "penalty_goals"),
|
|
26
|
+
ownGoals: getStatValue(stats, "own_goals"),
|
|
27
|
+
assists: getStatValue(stats, "assists"),
|
|
28
|
+
// Shooting
|
|
29
|
+
shots: getStatValue(stats, "shots"),
|
|
30
|
+
shotsOnTarget: getStatValue(stats, "shots_on_target"),
|
|
31
|
+
// Discipline
|
|
32
|
+
yellowCards: getStatValue(stats, "yellow_cards"),
|
|
33
|
+
redCards: getStatValue(stats, "red_cards"),
|
|
34
|
+
foulsCommitted: getStatValue(stats, "fouls_committed"),
|
|
35
|
+
penaltiesCommitted: getStatValue(stats, "penalties_committed"),
|
|
36
|
+
// Penalties
|
|
37
|
+
penaltiesMissed: getStatValue(stats, "penalties_missed"),
|
|
38
|
+
// Defensive
|
|
39
|
+
cleansheets: getStatValue(stats, "cleansheets"),
|
|
40
|
+
// Goalkeeper-specific
|
|
41
|
+
saves: getStatValue(stats, "saves"),
|
|
42
|
+
conceded: getStatValue(stats, "conceded"),
|
|
43
|
+
caughtBall: getStatValue(stats, "caught_ball"),
|
|
44
|
+
penaltiesReceived: getStatValue(stats, "penalties_received"),
|
|
45
|
+
// Other
|
|
46
|
+
offsides: getStatValue(stats, "offsides"),
|
|
47
|
+
// Raw statistics array (for any additional stats not mapped above)
|
|
48
|
+
rawStatistics: stats.map((s) => ({
|
|
49
|
+
name: s.name,
|
|
50
|
+
value: s.value
|
|
51
|
+
}))
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function transformPlayerSeasonStatisticsWithoutTeam(raw) {
|
|
55
|
+
const stats = raw.statistics;
|
|
56
|
+
return {
|
|
57
|
+
playerId: raw.player.id,
|
|
58
|
+
seasonId: raw.season.id,
|
|
59
|
+
// Core statistics
|
|
60
|
+
appearances: getStatValue(stats, "played"),
|
|
61
|
+
started: getStatValue(stats, "started"),
|
|
62
|
+
substituteIn: getStatValue(stats, "substitute_in"),
|
|
63
|
+
substituteOut: getStatValue(stats, "substitute_out"),
|
|
64
|
+
minutes: getStatValue(stats, "minutes"),
|
|
65
|
+
minutesSubstitute: getStatValue(stats, "minutes_substitute"),
|
|
66
|
+
// Scoring
|
|
67
|
+
goals: getStatValue(stats, "goals"),
|
|
68
|
+
goalsSubstitute: getStatValue(stats, "goals_substitute"),
|
|
69
|
+
penaltyGoals: getStatValue(stats, "penalty_goals"),
|
|
70
|
+
ownGoals: getStatValue(stats, "own_goals"),
|
|
71
|
+
assists: getStatValue(stats, "assists"),
|
|
72
|
+
// Shooting
|
|
73
|
+
shots: getStatValue(stats, "shots"),
|
|
74
|
+
shotsOnTarget: getStatValue(stats, "shots_on_target"),
|
|
75
|
+
// Discipline
|
|
76
|
+
yellowCards: getStatValue(stats, "yellow_cards"),
|
|
77
|
+
redCards: getStatValue(stats, "red_cards"),
|
|
78
|
+
foulsCommitted: getStatValue(stats, "fouls_committed"),
|
|
79
|
+
penaltiesCommitted: getStatValue(stats, "penalties_committed"),
|
|
80
|
+
// Penalties
|
|
81
|
+
penaltiesMissed: getStatValue(stats, "penalties_missed"),
|
|
82
|
+
// Defensive
|
|
83
|
+
cleansheets: getStatValue(stats, "cleansheets"),
|
|
84
|
+
// Goalkeeper-specific
|
|
85
|
+
saves: getStatValue(stats, "saves"),
|
|
86
|
+
conceded: getStatValue(stats, "conceded"),
|
|
87
|
+
caughtBall: getStatValue(stats, "caught_ball"),
|
|
88
|
+
penaltiesReceived: getStatValue(stats, "penalties_received"),
|
|
89
|
+
// Other
|
|
90
|
+
offsides: getStatValue(stats, "offsides"),
|
|
91
|
+
// Raw statistics array
|
|
92
|
+
rawStatistics: stats.map((s) => ({
|
|
93
|
+
name: s.name,
|
|
94
|
+
value: s.value
|
|
95
|
+
}))
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function addOptional(a, b) {
|
|
99
|
+
if (a === void 0 && b === void 0) return void 0;
|
|
100
|
+
return (a ?? 0) + (b ?? 0);
|
|
101
|
+
}
|
|
102
|
+
function mergePlayerSeasonStatistics(a, b) {
|
|
103
|
+
return {
|
|
104
|
+
playerId: a.playerId,
|
|
105
|
+
seasonId: a.seasonId,
|
|
106
|
+
// Core statistics
|
|
107
|
+
appearances: addOptional(a.appearances, b.appearances),
|
|
108
|
+
started: addOptional(a.started, b.started),
|
|
109
|
+
substituteIn: addOptional(a.substituteIn, b.substituteIn),
|
|
110
|
+
substituteOut: addOptional(a.substituteOut, b.substituteOut),
|
|
111
|
+
minutes: addOptional(a.minutes, b.minutes),
|
|
112
|
+
minutesSubstitute: addOptional(a.minutesSubstitute, b.minutesSubstitute),
|
|
113
|
+
// Scoring
|
|
114
|
+
goals: addOptional(a.goals, b.goals),
|
|
115
|
+
goalsSubstitute: addOptional(a.goalsSubstitute, b.goalsSubstitute),
|
|
116
|
+
penaltyGoals: addOptional(a.penaltyGoals, b.penaltyGoals),
|
|
117
|
+
ownGoals: addOptional(a.ownGoals, b.ownGoals),
|
|
118
|
+
assists: addOptional(a.assists, b.assists),
|
|
119
|
+
// Shooting
|
|
120
|
+
shots: addOptional(a.shots, b.shots),
|
|
121
|
+
shotsOnTarget: addOptional(a.shotsOnTarget, b.shotsOnTarget),
|
|
122
|
+
// Discipline
|
|
123
|
+
yellowCards: addOptional(a.yellowCards, b.yellowCards),
|
|
124
|
+
redCards: addOptional(a.redCards, b.redCards),
|
|
125
|
+
foulsCommitted: addOptional(a.foulsCommitted, b.foulsCommitted),
|
|
126
|
+
penaltiesCommitted: addOptional(a.penaltiesCommitted, b.penaltiesCommitted),
|
|
127
|
+
// Penalties
|
|
128
|
+
penaltiesMissed: addOptional(a.penaltiesMissed, b.penaltiesMissed),
|
|
129
|
+
// Defensive
|
|
130
|
+
cleansheets: addOptional(a.cleansheets, b.cleansheets),
|
|
131
|
+
// Goalkeeper-specific
|
|
132
|
+
saves: addOptional(a.saves, b.saves),
|
|
133
|
+
conceded: addOptional(a.conceded, b.conceded),
|
|
134
|
+
caughtBall: addOptional(a.caughtBall, b.caughtBall),
|
|
135
|
+
penaltiesReceived: addOptional(a.penaltiesReceived, b.penaltiesReceived),
|
|
136
|
+
// Other
|
|
137
|
+
offsides: addOptional(a.offsides, b.offsides),
|
|
138
|
+
// Concatenate raw statistics from both entries
|
|
139
|
+
rawStatistics: [...a.rawStatistics ?? [], ...b.rawStatistics ?? []]
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
export {
|
|
143
|
+
mergePlayerSeasonStatistics,
|
|
144
|
+
transformPlayerSeasonStatistics,
|
|
145
|
+
transformPlayerSeasonStatisticsWithoutTeam
|
|
146
|
+
};
|
|
147
|
+
//# sourceMappingURL=player-season.transformer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"player-season.transformer.js","sources":["../../../../../src/lib/api/sportal365-sports/football/statistics/player-season.transformer.ts"],"sourcesContent":["/**\n * Player season statistics transformation utilities\n * Transforms raw API responses to canonical FUSports types\n */\n\nimport type { FUSportsPlayerSeasonStatistics } from \"../../../../types/canonical\";\nimport type { RawPlayerSeasonStatisticsEntry, RawPlayerStatistic } from \"./player-season.types\";\n\n/**\n * Parse a statistic value to number\n */\nfunction parseStatValue(value: string): number | undefined {\n const parsed = parseInt(value, 10);\n return isNaN(parsed) ? undefined : parsed;\n}\n\n/**\n * Get a specific statistic value by name\n */\nfunction getStatValue(statistics: RawPlayerStatistic[], name: string): number | undefined {\n const stat = statistics.find((s) => s.name === name);\n return stat ? parseStatValue(stat.value) : undefined;\n}\n\n/**\n * Transform raw player season statistics to canonical FUSportsPlayerSeasonStatistics\n */\nexport function transformPlayerSeasonStatistics(\n raw: RawPlayerSeasonStatisticsEntry,\n teamId: string\n): FUSportsPlayerSeasonStatistics {\n const stats = raw.statistics;\n\n return {\n playerId: raw.player.id,\n seasonId: raw.season.id,\n teamId,\n\n // Core statistics\n appearances: getStatValue(stats, \"played\"),\n started: getStatValue(stats, \"started\"),\n substituteIn: getStatValue(stats, \"substitute_in\"),\n substituteOut: getStatValue(stats, \"substitute_out\"),\n minutes: getStatValue(stats, \"minutes\"),\n minutesSubstitute: getStatValue(stats, \"minutes_substitute\"),\n\n // Scoring\n goals: getStatValue(stats, \"goals\"),\n goalsSubstitute: getStatValue(stats, \"goals_substitute\"),\n penaltyGoals: getStatValue(stats, \"penalty_goals\"),\n ownGoals: getStatValue(stats, \"own_goals\"),\n assists: getStatValue(stats, \"assists\"),\n\n // Shooting\n shots: getStatValue(stats, \"shots\"),\n shotsOnTarget: getStatValue(stats, \"shots_on_target\"),\n\n // Discipline\n yellowCards: getStatValue(stats, \"yellow_cards\"),\n redCards: getStatValue(stats, \"red_cards\"),\n foulsCommitted: getStatValue(stats, \"fouls_committed\"),\n penaltiesCommitted: getStatValue(stats, \"penalties_committed\"),\n\n // Penalties\n penaltiesMissed: getStatValue(stats, \"penalties_missed\"),\n\n // Defensive\n cleansheets: getStatValue(stats, \"cleansheets\"),\n\n // Goalkeeper-specific\n saves: getStatValue(stats, \"saves\"),\n conceded: getStatValue(stats, \"conceded\"),\n caughtBall: getStatValue(stats, \"caught_ball\"),\n penaltiesReceived: getStatValue(stats, \"penalties_received\"),\n\n // Other\n offsides: getStatValue(stats, \"offsides\"),\n\n // Raw statistics array (for any additional stats not mapped above)\n rawStatistics: stats.map((s) => ({\n name: s.name,\n value: s.value,\n })),\n };\n}\n\n/**\n * Transform raw player season statistics without a team context.\n * Used when querying by player IDs - no teamId is set.\n */\nexport function transformPlayerSeasonStatisticsWithoutTeam(\n raw: RawPlayerSeasonStatisticsEntry\n): FUSportsPlayerSeasonStatistics {\n const stats = raw.statistics;\n\n return {\n playerId: raw.player.id,\n seasonId: raw.season.id,\n\n // Core statistics\n appearances: getStatValue(stats, \"played\"),\n started: getStatValue(stats, \"started\"),\n substituteIn: getStatValue(stats, \"substitute_in\"),\n substituteOut: getStatValue(stats, \"substitute_out\"),\n minutes: getStatValue(stats, \"minutes\"),\n minutesSubstitute: getStatValue(stats, \"minutes_substitute\"),\n\n // Scoring\n goals: getStatValue(stats, \"goals\"),\n goalsSubstitute: getStatValue(stats, \"goals_substitute\"),\n penaltyGoals: getStatValue(stats, \"penalty_goals\"),\n ownGoals: getStatValue(stats, \"own_goals\"),\n assists: getStatValue(stats, \"assists\"),\n\n // Shooting\n shots: getStatValue(stats, \"shots\"),\n shotsOnTarget: getStatValue(stats, \"shots_on_target\"),\n\n // Discipline\n yellowCards: getStatValue(stats, \"yellow_cards\"),\n redCards: getStatValue(stats, \"red_cards\"),\n foulsCommitted: getStatValue(stats, \"fouls_committed\"),\n penaltiesCommitted: getStatValue(stats, \"penalties_committed\"),\n\n // Penalties\n penaltiesMissed: getStatValue(stats, \"penalties_missed\"),\n\n // Defensive\n cleansheets: getStatValue(stats, \"cleansheets\"),\n\n // Goalkeeper-specific\n saves: getStatValue(stats, \"saves\"),\n conceded: getStatValue(stats, \"conceded\"),\n caughtBall: getStatValue(stats, \"caught_ball\"),\n penaltiesReceived: getStatValue(stats, \"penalties_received\"),\n\n // Other\n offsides: getStatValue(stats, \"offsides\"),\n\n // Raw statistics array\n rawStatistics: stats.map((s) => ({\n name: s.name,\n value: s.value,\n })),\n };\n}\n\n/**\n * Add two optional numbers together. Returns undefined only if both are undefined.\n */\nfunction addOptional(a: number | undefined, b: number | undefined): number | undefined {\n if (a === undefined && b === undefined) return undefined;\n return (a ?? 0) + (b ?? 0);\n}\n\n/**\n * Merge two player season statistics by summing all numeric fields.\n * Used when a player has stats across multiple teams in the same season.\n */\nexport function mergePlayerSeasonStatistics(\n a: FUSportsPlayerSeasonStatistics,\n b: FUSportsPlayerSeasonStatistics\n): FUSportsPlayerSeasonStatistics {\n return {\n playerId: a.playerId,\n seasonId: a.seasonId,\n\n // Core statistics\n appearances: addOptional(a.appearances, b.appearances),\n started: addOptional(a.started, b.started),\n substituteIn: addOptional(a.substituteIn, b.substituteIn),\n substituteOut: addOptional(a.substituteOut, b.substituteOut),\n minutes: addOptional(a.minutes, b.minutes),\n minutesSubstitute: addOptional(a.minutesSubstitute, b.minutesSubstitute),\n\n // Scoring\n goals: addOptional(a.goals, b.goals),\n goalsSubstitute: addOptional(a.goalsSubstitute, b.goalsSubstitute),\n penaltyGoals: addOptional(a.penaltyGoals, b.penaltyGoals),\n ownGoals: addOptional(a.ownGoals, b.ownGoals),\n assists: addOptional(a.assists, b.assists),\n\n // Shooting\n shots: addOptional(a.shots, b.shots),\n shotsOnTarget: addOptional(a.shotsOnTarget, b.shotsOnTarget),\n\n // Discipline\n yellowCards: addOptional(a.yellowCards, b.yellowCards),\n redCards: addOptional(a.redCards, b.redCards),\n foulsCommitted: addOptional(a.foulsCommitted, b.foulsCommitted),\n penaltiesCommitted: addOptional(a.penaltiesCommitted, b.penaltiesCommitted),\n\n // Penalties\n penaltiesMissed: addOptional(a.penaltiesMissed, b.penaltiesMissed),\n\n // Defensive\n cleansheets: addOptional(a.cleansheets, b.cleansheets),\n\n // Goalkeeper-specific\n saves: addOptional(a.saves, b.saves),\n conceded: addOptional(a.conceded, b.conceded),\n caughtBall: addOptional(a.caughtBall, b.caughtBall),\n penaltiesReceived: addOptional(a.penaltiesReceived, b.penaltiesReceived),\n\n // Other\n offsides: addOptional(a.offsides, b.offsides),\n\n // Concatenate raw statistics from both entries\n rawStatistics: [...(a.rawStatistics ?? []), ...(b.rawStatistics ?? [])],\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { getConfig } from "../../../../config/index.js";
|
|
2
|
+
import { footballHttp } from "../http.js";
|
|
3
|
+
import { transformTeam, transformSquad } from "./utils.js";
|
|
4
|
+
import { getFootballPlayerSeasonStatistics } from "../statistics/index.js";
|
|
5
|
+
async function getFootballTeam(teamId, options, config) {
|
|
6
|
+
const finalConfig = config || getConfig();
|
|
7
|
+
const { sportal365Sports } = finalConfig;
|
|
8
|
+
const raw = await footballHttp.get({
|
|
9
|
+
path: `/v2/teams/${teamId}`,
|
|
10
|
+
params: {
|
|
11
|
+
language_code: options?.languageCode ?? sportal365Sports?.languageCode ?? "en",
|
|
12
|
+
optional_data: "form"
|
|
13
|
+
},
|
|
14
|
+
headers: {
|
|
15
|
+
"Accept-Language": options?.languageCode ?? sportal365Sports?.languageCode ?? "en"
|
|
16
|
+
},
|
|
17
|
+
next: options?.next,
|
|
18
|
+
config: finalConfig
|
|
19
|
+
});
|
|
20
|
+
return transformTeam(raw);
|
|
21
|
+
}
|
|
22
|
+
async function getFootballTeamSquad(teamId, options, config) {
|
|
23
|
+
const finalConfig = config || getConfig();
|
|
24
|
+
const { sportal365Sports } = finalConfig;
|
|
25
|
+
const cacheOptions = options?.seasonIds && options.seasonIds.length > 0 ? { revalidate: 0 } : options?.next;
|
|
26
|
+
const raw = await footballHttp.get({
|
|
27
|
+
path: `/v2/teams/${teamId}/squad`,
|
|
28
|
+
params: {
|
|
29
|
+
language_code: options?.languageCode ?? sportal365Sports?.languageCode ?? "en",
|
|
30
|
+
memberStatus: options?.memberStatus ?? "ACTIVE"
|
|
31
|
+
},
|
|
32
|
+
headers: {
|
|
33
|
+
"Accept-Language": options?.languageCode ?? sportal365Sports?.languageCode ?? "en"
|
|
34
|
+
},
|
|
35
|
+
next: cacheOptions,
|
|
36
|
+
config: finalConfig
|
|
37
|
+
});
|
|
38
|
+
const squad = transformSquad(raw);
|
|
39
|
+
if (options?.seasonIds && options.seasonIds.length > 0) {
|
|
40
|
+
try {
|
|
41
|
+
const statsMap = await getFootballPlayerSeasonStatistics(
|
|
42
|
+
{
|
|
43
|
+
seasonIds: options.seasonIds,
|
|
44
|
+
teamId,
|
|
45
|
+
languageCode: options.languageCode,
|
|
46
|
+
next: options.next
|
|
47
|
+
},
|
|
48
|
+
finalConfig
|
|
49
|
+
);
|
|
50
|
+
for (const player of squad.players) {
|
|
51
|
+
const stats = statsMap[player.id];
|
|
52
|
+
if (stats) {
|
|
53
|
+
player.seasonStatistics = stats;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
} catch (error) {
|
|
57
|
+
console.error("[getFootballTeamSquad] Failed to fetch player statistics:", {
|
|
58
|
+
error: error instanceof Error ? error.message : String(error),
|
|
59
|
+
stack: error instanceof Error ? error.stack : void 0,
|
|
60
|
+
teamId,
|
|
61
|
+
seasonIds: options.seasonIds
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
console.warn("[getFootballTeamSquad] No seasonIds provided, skipping stats fetch");
|
|
66
|
+
}
|
|
67
|
+
return squad;
|
|
68
|
+
}
|
|
69
|
+
export {
|
|
70
|
+
getFootballTeam,
|
|
71
|
+
getFootballTeamSquad
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../../src/lib/api/sportal365-sports/football/teams/index.ts"],"sourcesContent":["/**\n * Sportal365 Sports API - Football Teams\n *\n * Fetches team data and transforms to canonical FUSports types.\n */\n\nimport type { FUSportsCompetitor, FUSportsSquad } from \"../../../../types/canonical\";\nimport { getConfig, type DataLayerConfig } from \"../../../../config\";\nimport { footballHttp } from \"../http\";\nimport type { RawTeamProfile, GetFootballTeamOptions } from \"./team.types\";\nimport type { RawSquadResponse, GetFootballTeamSquadOptions } from \"./squad.types\";\nimport { transformTeam, transformSquad } from \"./utils\";\nimport { getFootballPlayerSeasonStatistics } from \"../statistics\";\n\n// Re-export types for options\nexport type { GetFootballTeamOptions } from \"./team.types\";\nexport type { GetFootballTeamSquadOptions } from \"./squad.types\";\n\n/**\n * Get a football team by ID, UUID, or slug\n *\n * Always fetches with `optional_data=form` to include recent match form.\n *\n * @param teamId - The team ID, UUID, or slug\n * @param options - Optional parameters\n * @param config - Optional data layer config (uses singleton if not provided)\n * @returns Canonical FUSportsCompetitor\n *\n * @example\n * ```typescript\n * const team = await getFootballTeam('102');\n * console.log(team.name); // \"Manchester United\"\n * ```\n */\nexport async function getFootballTeam(\n teamId: string,\n options?: GetFootballTeamOptions,\n config?: DataLayerConfig\n): Promise<FUSportsCompetitor> {\n const finalConfig = config || getConfig();\n const { sportal365Sports } = finalConfig;\n\n const raw = await footballHttp.get<RawTeamProfile>({\n path: `/v2/teams/${teamId}`,\n params: {\n language_code: options?.languageCode ?? sportal365Sports?.languageCode ?? \"en\",\n optional_data: \"form\",\n },\n headers: {\n \"Accept-Language\": options?.languageCode ?? sportal365Sports?.languageCode ?? \"en\",\n },\n next: options?.next,\n config: finalConfig,\n });\n\n return transformTeam(raw);\n}\n\n/**\n * Get a football team's squad by team ID, UUID, or slug\n *\n * Optionally fetches player season statistics if seasonIds are provided.\n *\n * @param teamId - The team ID, UUID, or slug\n * @param options - Optional parameters\n * @param config - Optional data layer config (uses singleton if not provided)\n * @returns Canonical FUSportsSquad\n *\n * @example\n * ```typescript\n * const squad = await getFootballTeamSquad('102');\n * console.log(squad.players.length); // Number of players in squad\n * ```\n *\n * @example\n * ```typescript\n * // Fetch squad with season statistics\n * const squad = await getFootballTeamSquad('102', { seasonIds: ['8009707'] });\n * console.log(squad.players[0].seasonStatistics?.goals); // Player goals\n * ```\n */\nexport async function getFootballTeamSquad(\n teamId: string,\n options?: GetFootballTeamSquadOptions,\n config?: DataLayerConfig\n): Promise<FUSportsSquad> {\n const finalConfig = config || getConfig();\n const { sportal365Sports } = finalConfig;\n\n // If seasonIds are provided, we need fresh data to attach stats\n // Use revalidate: 0 to prevent caching issues where stats fail on first load\n const cacheOptions = options?.seasonIds && options.seasonIds.length > 0 ? { revalidate: 0 } : options?.next;\n\n const raw = await footballHttp.get<RawSquadResponse>({\n path: `/v2/teams/${teamId}/squad`,\n params: {\n language_code: options?.languageCode ?? sportal365Sports?.languageCode ?? \"en\",\n memberStatus: options?.memberStatus ?? \"ACTIVE\",\n },\n headers: {\n \"Accept-Language\": options?.languageCode ?? sportal365Sports?.languageCode ?? \"en\",\n },\n next: cacheOptions,\n config: finalConfig,\n });\n\n const squad = transformSquad(raw);\n\n // Fetch player statistics if seasonIds are provided\n if (options?.seasonIds && options.seasonIds.length > 0) {\n try {\n const statsMap = await getFootballPlayerSeasonStatistics(\n {\n seasonIds: options.seasonIds,\n teamId,\n languageCode: options.languageCode,\n next: options.next,\n },\n finalConfig\n );\n\n // Attach statistics to each player\n for (const player of squad.players) {\n const stats = statsMap[player.id];\n if (stats) {\n player.seasonStatistics = stats;\n }\n }\n } catch (error) {\n // Don't fail the entire squad fetch if statistics fail\n // Just continue without stats, but log the error\n console.error(\"[getFootballTeamSquad] Failed to fetch player statistics:\", {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n teamId,\n seasonIds: options.seasonIds,\n });\n }\n } else {\n console.warn(\"[getFootballTeamSquad] No seasonIds provided, skipping stats fetch\");\n }\n\n return squad;\n}\n"],"names":[],"mappings":";;;;AAkCA,eAAsB,gBAClB,QACA,SACA,QAC2B;AAC3B,QAAM,cAAc,UAAU,UAAA;AAC9B,QAAM,EAAE,qBAAqB;AAE7B,QAAM,MAAM,MAAM,aAAa,IAAoB;AAAA,IAC/C,MAAM,aAAa,MAAM;AAAA,IACzB,QAAQ;AAAA,MACJ,eAAe,SAAS,gBAAgB,kBAAkB,gBAAgB;AAAA,MAC1E,eAAe;AAAA,IAAA;AAAA,IAEnB,SAAS;AAAA,MACL,mBAAmB,SAAS,gBAAgB,kBAAkB,gBAAgB;AAAA,IAAA;AAAA,IAElF,MAAM,SAAS;AAAA,IACf,QAAQ;AAAA,EAAA,CACX;AAED,SAAO,cAAc,GAAG;AAC5B;AAyBA,eAAsB,qBAClB,QACA,SACA,QACsB;AACtB,QAAM,cAAc,UAAU,UAAA;AAC9B,QAAM,EAAE,qBAAqB;AAI7B,QAAM,eAAe,SAAS,aAAa,QAAQ,UAAU,SAAS,IAAI,EAAE,YAAY,EAAA,IAAM,SAAS;AAEvG,QAAM,MAAM,MAAM,aAAa,IAAsB;AAAA,IACjD,MAAM,aAAa,MAAM;AAAA,IACzB,QAAQ;AAAA,MACJ,eAAe,SAAS,gBAAgB,kBAAkB,gBAAgB;AAAA,MAC1E,cAAc,SAAS,gBAAgB;AAAA,IAAA;AAAA,IAE3C,SAAS;AAAA,MACL,mBAAmB,SAAS,gBAAgB,kBAAkB,gBAAgB;AAAA,IAAA;AAAA,IAElF,MAAM;AAAA,IACN,QAAQ;AAAA,EAAA,CACX;AAED,QAAM,QAAQ,eAAe,GAAG;AAGhC,MAAI,SAAS,aAAa,QAAQ,UAAU,SAAS,GAAG;AACpD,QAAI;AACA,YAAM,WAAW,MAAM;AAAA,QACnB;AAAA,UACI,WAAW,QAAQ;AAAA,UACnB;AAAA,UACA,cAAc,QAAQ;AAAA,UACtB,MAAM,QAAQ;AAAA,QAAA;AAAA,QAElB;AAAA,MAAA;AAIJ,iBAAW,UAAU,MAAM,SAAS;AAChC,cAAM,QAAQ,SAAS,OAAO,EAAE;AAChC,YAAI,OAAO;AACP,iBAAO,mBAAmB;AAAA,QAC9B;AAAA,MACJ;AAAA,IACJ,SAAS,OAAO;AAGZ,cAAQ,MAAM,6DAA6D;AAAA,QACvE,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,QAC9C;AAAA,QACA,WAAW,QAAQ;AAAA,MAAA,CACtB;AAAA,IACL;AAAA,EACJ,OAAO;AACH,YAAQ,KAAK,oEAAoE;AAAA,EACrF;AAEA,SAAO;AACX;"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { toProviderRefArray } from "../../shared/providerRef.helper.js";
|
|
2
|
+
function transformTeam(raw) {
|
|
3
|
+
return {
|
|
4
|
+
id: raw.id,
|
|
5
|
+
name: raw.name,
|
|
6
|
+
shortName: raw.short_name ?? void 0,
|
|
7
|
+
threeLetterCode: raw.three_letter_code,
|
|
8
|
+
slug: raw.slug,
|
|
9
|
+
type: raw.type === "placeholder" || raw.type === "club" ? "club" : "national",
|
|
10
|
+
gender: raw.gender,
|
|
11
|
+
country: raw.country ? {
|
|
12
|
+
id: raw.country.id,
|
|
13
|
+
name: raw.country.name,
|
|
14
|
+
code: raw.country.code ?? void 0,
|
|
15
|
+
flag: raw.country.assets?.flag?.url,
|
|
16
|
+
providerRef: toProviderRefArray(raw.country.uuid)
|
|
17
|
+
} : void 0,
|
|
18
|
+
// Extended team profile data
|
|
19
|
+
venue: raw.venue ? {
|
|
20
|
+
id: raw.venue.id,
|
|
21
|
+
name: raw.venue.name,
|
|
22
|
+
slug: raw.venue.slug,
|
|
23
|
+
city: raw.venue.city ? {
|
|
24
|
+
id: raw.venue.city.id,
|
|
25
|
+
name: raw.venue.city.name,
|
|
26
|
+
country: raw.venue.city.country ? {
|
|
27
|
+
id: raw.venue.city.country.id,
|
|
28
|
+
name: raw.venue.city.country.name,
|
|
29
|
+
code: raw.venue.city.country.code ?? void 0,
|
|
30
|
+
flag: raw.venue.city.country.assets?.flag?.url,
|
|
31
|
+
providerRef: toProviderRefArray(raw.venue.city.country.uuid)
|
|
32
|
+
} : void 0,
|
|
33
|
+
providerRef: toProviderRefArray(raw.venue.city.uuid ?? void 0)
|
|
34
|
+
} : void 0,
|
|
35
|
+
country: raw.venue.country ? {
|
|
36
|
+
id: raw.venue.country.id,
|
|
37
|
+
name: raw.venue.country.name,
|
|
38
|
+
code: raw.venue.country.code ?? void 0,
|
|
39
|
+
flag: raw.venue.country.assets?.flag?.url,
|
|
40
|
+
providerRef: toProviderRefArray(raw.venue.country.uuid)
|
|
41
|
+
} : void 0,
|
|
42
|
+
profile: raw.venue.profile ? {
|
|
43
|
+
latitude: raw.venue.profile.lat,
|
|
44
|
+
longitude: raw.venue.profile.lng,
|
|
45
|
+
capacity: raw.venue.profile.capacity
|
|
46
|
+
} : void 0,
|
|
47
|
+
assets: raw.venue.assets?.image?.url ? {
|
|
48
|
+
image: raw.venue.assets.image.url
|
|
49
|
+
} : void 0,
|
|
50
|
+
providerRef: toProviderRefArray(raw.venue.uuid)
|
|
51
|
+
} : void 0,
|
|
52
|
+
coach: raw.coach ? {
|
|
53
|
+
id: raw.coach.id,
|
|
54
|
+
name: raw.coach.name,
|
|
55
|
+
slug: raw.coach.slug,
|
|
56
|
+
country: {
|
|
57
|
+
id: raw.coach.country.id,
|
|
58
|
+
name: raw.coach.country.name,
|
|
59
|
+
code: raw.coach.country.code ?? void 0,
|
|
60
|
+
flag: raw.coach.country.assets?.flag?.url,
|
|
61
|
+
providerRef: toProviderRefArray(raw.coach.country.uuid)
|
|
62
|
+
},
|
|
63
|
+
birthdate: raw.coach.birthdate,
|
|
64
|
+
providerRef: toProviderRefArray(raw.coach.uuid)
|
|
65
|
+
} : void 0,
|
|
66
|
+
founded: raw.founded,
|
|
67
|
+
// Assets
|
|
68
|
+
assets: raw.assets ? {
|
|
69
|
+
logo: raw.assets.logo?.url,
|
|
70
|
+
homeKit: raw.assets.home_kit?.url,
|
|
71
|
+
awayKit: raw.assets.away_kit?.url,
|
|
72
|
+
squadImage: raw.assets.squad_image?.url
|
|
73
|
+
} : void 0,
|
|
74
|
+
// Metadata
|
|
75
|
+
metadata: {
|
|
76
|
+
shirtColors: raw.shirt_colors?.map((sc) => ({
|
|
77
|
+
type: sc.type,
|
|
78
|
+
colorCode: sc.color_code
|
|
79
|
+
})),
|
|
80
|
+
socials: raw.social ? {
|
|
81
|
+
website: raw.social.web,
|
|
82
|
+
x: raw.social.twitter_id,
|
|
83
|
+
facebook: raw.social.facebook_id,
|
|
84
|
+
instagram: raw.social.instagram_id,
|
|
85
|
+
wikipedia: raw.social.wikipedia_id
|
|
86
|
+
} : void 0
|
|
87
|
+
},
|
|
88
|
+
// Seasons
|
|
89
|
+
activeSeasons: raw.active_seasons?.map((season) => ({
|
|
90
|
+
id: season.id,
|
|
91
|
+
name: season.name,
|
|
92
|
+
slug: season.slug,
|
|
93
|
+
active: season.status === "ACTIVE",
|
|
94
|
+
providerRef: toProviderRefArray(season.uuid)
|
|
95
|
+
})),
|
|
96
|
+
currentSeason: raw.current_season ? {
|
|
97
|
+
id: raw.current_season.id,
|
|
98
|
+
name: raw.current_season.name,
|
|
99
|
+
slug: raw.current_season.slug,
|
|
100
|
+
active: raw.current_season.status === "ACTIVE",
|
|
101
|
+
providerRef: toProviderRefArray(raw.current_season.uuid)
|
|
102
|
+
} : void 0,
|
|
103
|
+
// Form - map to FUSportsCompetitorForm
|
|
104
|
+
form: raw.form && raw.form.length > 0 ? {
|
|
105
|
+
competitorId: raw.id,
|
|
106
|
+
results: raw.form.map((formMatch) => {
|
|
107
|
+
const isHome = formMatch.participants[0].id === raw.uuid;
|
|
108
|
+
const opponent = isHome ? formMatch.participants[1] : formMatch.participants[0];
|
|
109
|
+
const homeScore = formMatch.result[0]?.results.find((r) => r.position === "1")?.value;
|
|
110
|
+
const awayScore = formMatch.result[0]?.results.find((r) => r.position === "2")?.value;
|
|
111
|
+
const result = formMatch.outcome === "win" ? "W" : formMatch.outcome === "draw" ? "D" : "L";
|
|
112
|
+
return {
|
|
113
|
+
matchId: formMatch.id,
|
|
114
|
+
result,
|
|
115
|
+
score: homeScore && awayScore ? `${homeScore}-${awayScore}` : void 0,
|
|
116
|
+
opponent: {
|
|
117
|
+
id: opponent.id,
|
|
118
|
+
name: opponent.name,
|
|
119
|
+
logo: opponent.display_asset?.url
|
|
120
|
+
},
|
|
121
|
+
date: new Date(formMatch.start_time),
|
|
122
|
+
competition: formMatch.competition ? {
|
|
123
|
+
id: formMatch.competition.id,
|
|
124
|
+
name: formMatch.competition.name
|
|
125
|
+
} : void 0
|
|
126
|
+
};
|
|
127
|
+
}),
|
|
128
|
+
formString: raw.form.map((fm) => fm.outcome === "win" ? "W" : fm.outcome === "draw" ? "D" : "L").join("")
|
|
129
|
+
} : void 0,
|
|
130
|
+
providerRef: toProviderRefArray(raw.uuid)
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function transformSquadPlayer(raw) {
|
|
134
|
+
const player = raw.player;
|
|
135
|
+
return {
|
|
136
|
+
id: player.id,
|
|
137
|
+
name: player.name,
|
|
138
|
+
slug: player.slug,
|
|
139
|
+
position: player.position,
|
|
140
|
+
shirtNumber: raw.shirt_number,
|
|
141
|
+
country: player.country ? {
|
|
142
|
+
id: player.country.id,
|
|
143
|
+
name: player.country.name,
|
|
144
|
+
code: player.country.code ?? void 0,
|
|
145
|
+
flag: player.country.assets?.flag?.url,
|
|
146
|
+
providerRef: toProviderRefArray(player.country.uuid)
|
|
147
|
+
} : void 0,
|
|
148
|
+
gender: player.gender,
|
|
149
|
+
birthdate: player.birthdate,
|
|
150
|
+
profile: {
|
|
151
|
+
height: player.profile?.height ?? void 0,
|
|
152
|
+
weight: player.profile?.weight ?? void 0
|
|
153
|
+
},
|
|
154
|
+
assets: player.assets ? {
|
|
155
|
+
photo: player.assets.thumb?.url,
|
|
156
|
+
photoTransparent: player.assets.thumb_transparent_background?.url
|
|
157
|
+
} : void 0,
|
|
158
|
+
status: raw.status,
|
|
159
|
+
contractType: raw.contract_type,
|
|
160
|
+
contractUntil: raw.contract_until ?? void 0,
|
|
161
|
+
joinedDate: raw.start_date ?? void 0,
|
|
162
|
+
providerRef: toProviderRefArray(player.id)
|
|
163
|
+
// Using player.id as provider reference
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
function transformSquadCoach(raw) {
|
|
167
|
+
return {
|
|
168
|
+
id: raw.id,
|
|
169
|
+
name: raw.name,
|
|
170
|
+
slug: raw.slug,
|
|
171
|
+
country: raw.country ? {
|
|
172
|
+
id: raw.country.id,
|
|
173
|
+
name: raw.country.name,
|
|
174
|
+
code: raw.country.code ?? void 0,
|
|
175
|
+
flag: raw.country.assets?.flag?.url,
|
|
176
|
+
providerRef: toProviderRefArray(raw.country.uuid)
|
|
177
|
+
} : void 0,
|
|
178
|
+
birthdate: raw.birthdate,
|
|
179
|
+
providerRef: toProviderRefArray(raw.uuid)
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
function transformSquad(raw) {
|
|
183
|
+
return {
|
|
184
|
+
teamId: raw.team.id,
|
|
185
|
+
teamName: raw.team.name,
|
|
186
|
+
coach: raw.coach ? transformSquadCoach(raw.coach) : void 0,
|
|
187
|
+
players: raw.players.map(transformSquadPlayer)
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
export {
|
|
191
|
+
transformSquad,
|
|
192
|
+
transformSquadCoach,
|
|
193
|
+
transformSquadPlayer,
|
|
194
|
+
transformTeam
|
|
195
|
+
};
|
|
196
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sources":["../../../../../src/lib/api/sportal365-sports/football/teams/utils.ts"],"sourcesContent":["/**\n * Team transformation utilities\n * Transforms raw API responses to canonical FUSports types\n */\n\nimport type {\n FUSportsTeamCompetitor,\n FUSportsSquad,\n FUSportsSquadMember,\n FUSportsCoach,\n} from \"../../../../types/canonical\";\nimport type { RawTeamProfile } from \"./team.types\";\nimport type { RawSquadResponse, RawSquadPlayer, RawSquadCoach } from \"./squad.types\";\nimport { toProviderRefArray } from \"../../shared\";\n\n/**\n * Transform raw team profile to canonical FUSportsTeamCompetitor\n */\nexport function transformTeam(raw: RawTeamProfile): FUSportsTeamCompetitor {\n return {\n id: raw.id,\n name: raw.name,\n shortName: raw.short_name ?? undefined,\n threeLetterCode: raw.three_letter_code,\n slug: raw.slug,\n type: raw.type === \"placeholder\" || raw.type === \"club\" ? \"club\" : \"national\",\n gender: raw.gender,\n country: raw.country\n ? {\n id: raw.country.id,\n name: raw.country.name,\n code: raw.country.code ?? undefined,\n flag: raw.country.assets?.flag?.url,\n providerRef: toProviderRefArray(raw.country.uuid),\n }\n : undefined,\n\n // Extended team profile data\n venue: raw.venue\n ? {\n id: raw.venue.id,\n name: raw.venue.name,\n slug: raw.venue.slug,\n city: raw.venue.city\n ? {\n id: raw.venue.city.id,\n name: raw.venue.city.name,\n country: raw.venue.city.country\n ? {\n id: raw.venue.city.country.id,\n name: raw.venue.city.country.name,\n code: raw.venue.city.country.code ?? undefined,\n flag: raw.venue.city.country.assets?.flag?.url,\n providerRef: toProviderRefArray(raw.venue.city.country.uuid),\n }\n : undefined,\n providerRef: toProviderRefArray(raw.venue.city.uuid ?? undefined),\n }\n : undefined,\n country: raw.venue.country\n ? {\n id: raw.venue.country.id,\n name: raw.venue.country.name,\n code: raw.venue.country.code ?? undefined,\n flag: raw.venue.country.assets?.flag?.url,\n providerRef: toProviderRefArray(raw.venue.country.uuid),\n }\n : undefined,\n profile: raw.venue.profile\n ? {\n latitude: raw.venue.profile.lat,\n longitude: raw.venue.profile.lng,\n capacity: raw.venue.profile.capacity,\n }\n : undefined,\n assets: raw.venue.assets?.image?.url\n ? {\n image: raw.venue.assets.image.url,\n }\n : undefined,\n providerRef: toProviderRefArray(raw.venue.uuid),\n }\n : undefined,\n\n coach: raw.coach\n ? {\n id: raw.coach.id,\n name: raw.coach.name,\n slug: raw.coach.slug,\n country: {\n id: raw.coach.country.id,\n name: raw.coach.country.name,\n code: raw.coach.country.code ?? undefined,\n flag: raw.coach.country.assets?.flag?.url,\n providerRef: toProviderRefArray(raw.coach.country.uuid),\n },\n birthdate: raw.coach.birthdate,\n providerRef: toProviderRefArray(raw.coach.uuid),\n }\n : undefined,\n\n founded: raw.founded,\n\n // Assets\n assets: raw.assets\n ? {\n logo: raw.assets.logo?.url,\n homeKit: raw.assets.home_kit?.url,\n awayKit: raw.assets.away_kit?.url,\n squadImage: raw.assets.squad_image?.url,\n }\n : undefined,\n\n // Metadata\n metadata: {\n shirtColors: raw.shirt_colors?.map((sc) => ({\n type: sc.type,\n colorCode: sc.color_code,\n })),\n socials: raw.social\n ? {\n website: raw.social.web,\n x: raw.social.twitter_id,\n facebook: raw.social.facebook_id,\n instagram: raw.social.instagram_id,\n wikipedia: raw.social.wikipedia_id,\n }\n : undefined,\n },\n\n // Seasons\n activeSeasons: raw.active_seasons?.map((season) => ({\n id: season.id,\n name: season.name,\n slug: season.slug,\n active: season.status === \"ACTIVE\",\n providerRef: toProviderRefArray(season.uuid),\n })),\n\n currentSeason: raw.current_season\n ? {\n id: raw.current_season.id,\n name: raw.current_season.name,\n slug: raw.current_season.slug,\n active: raw.current_season.status === \"ACTIVE\",\n providerRef: toProviderRefArray(raw.current_season.uuid),\n }\n : undefined,\n\n // Form - map to FUSportsCompetitorForm\n form:\n raw.form && raw.form.length > 0\n ? {\n competitorId: raw.id,\n results: raw.form.map((formMatch) => {\n const isHome = formMatch.participants[0].id === raw.uuid;\n const opponent = isHome ? formMatch.participants[1] : formMatch.participants[0];\n const homeScore = formMatch.result[0]?.results.find((r) => r.position === \"1\")?.value;\n const awayScore = formMatch.result[0]?.results.find((r) => r.position === \"2\")?.value;\n\n // Map outcome to W/D/L format\n const result = formMatch.outcome === \"win\" ? \"W\" : formMatch.outcome === \"draw\" ? \"D\" : \"L\";\n\n return {\n matchId: formMatch.id,\n result,\n score: homeScore && awayScore ? `${homeScore}-${awayScore}` : undefined,\n opponent: {\n id: opponent.id,\n name: opponent.name,\n logo: opponent.display_asset?.url,\n },\n date: new Date(formMatch.start_time),\n competition: formMatch.competition\n ? {\n id: formMatch.competition.id,\n name: formMatch.competition.name,\n }\n : undefined,\n };\n }),\n formString: raw.form\n .map((fm) => (fm.outcome === \"win\" ? \"W\" : fm.outcome === \"draw\" ? \"D\" : \"L\"))\n .join(\"\"),\n }\n : undefined,\n\n providerRef: toProviderRefArray(raw.uuid),\n };\n}\n\n/**\n * Transform raw squad player to canonical FUSportsSquadMember\n */\nexport function transformSquadPlayer(raw: RawSquadPlayer): FUSportsSquadMember {\n const player = raw.player;\n return {\n id: player.id,\n name: player.name,\n slug: player.slug,\n position: player.position,\n shirtNumber: raw.shirt_number,\n country: player.country\n ? {\n id: player.country.id,\n name: player.country.name,\n code: player.country.code ?? undefined,\n flag: player.country.assets?.flag?.url,\n providerRef: toProviderRefArray(player.country.uuid),\n }\n : undefined,\n gender: player.gender,\n birthdate: player.birthdate,\n profile: {\n height: player.profile?.height ?? undefined,\n weight: player.profile?.weight ?? undefined,\n },\n assets: player.assets\n ? {\n photo: player.assets.thumb?.url,\n photoTransparent: player.assets.thumb_transparent_background?.url,\n }\n : undefined,\n status: raw.status,\n contractType: raw.contract_type,\n contractUntil: raw.contract_until ?? undefined,\n joinedDate: raw.start_date ?? undefined,\n providerRef: toProviderRefArray(player.id), // Using player.id as provider reference\n };\n}\n\n/**\n * Transform raw squad coach to canonical FUSportsCoach\n */\nexport function transformSquadCoach(raw: RawSquadCoach): FUSportsCoach {\n return {\n id: raw.id,\n name: raw.name,\n slug: raw.slug,\n country: raw.country\n ? {\n id: raw.country.id,\n name: raw.country.name,\n code: raw.country.code ?? undefined,\n flag: raw.country.assets?.flag?.url,\n providerRef: toProviderRefArray(raw.country.uuid),\n }\n : undefined,\n birthdate: raw.birthdate,\n providerRef: toProviderRefArray(raw.uuid),\n };\n}\n\n/**\n * Transform raw squad response to canonical FUSportsSquad\n */\nexport function transformSquad(raw: RawSquadResponse): FUSportsSquad {\n return {\n teamId: raw.team.id,\n teamName: raw.team.name,\n coach: raw.coach ? transformSquadCoach(raw.coach) : undefined,\n players: raw.players.map(transformSquadPlayer),\n };\n}\n"],"names":[],"mappings":";AAkBO,SAAS,cAAc,KAA6C;AACvE,SAAO;AAAA,IACH,IAAI,IAAI;AAAA,IACR,MAAM,IAAI;AAAA,IACV,WAAW,IAAI,cAAc;AAAA,IAC7B,iBAAiB,IAAI;AAAA,IACrB,MAAM,IAAI;AAAA,IACV,MAAM,IAAI,SAAS,iBAAiB,IAAI,SAAS,SAAS,SAAS;AAAA,IACnE,QAAQ,IAAI;AAAA,IACZ,SAAS,IAAI,UACP;AAAA,MACI,IAAI,IAAI,QAAQ;AAAA,MAChB,MAAM,IAAI,QAAQ;AAAA,MAClB,MAAM,IAAI,QAAQ,QAAQ;AAAA,MAC1B,MAAM,IAAI,QAAQ,QAAQ,MAAM;AAAA,MAChC,aAAa,mBAAmB,IAAI,QAAQ,IAAI;AAAA,IAAA,IAEpD;AAAA;AAAA,IAGN,OAAO,IAAI,QACL;AAAA,MACI,IAAI,IAAI,MAAM;AAAA,MACd,MAAM,IAAI,MAAM;AAAA,MAChB,MAAM,IAAI,MAAM;AAAA,MAChB,MAAM,IAAI,MAAM,OACV;AAAA,QACI,IAAI,IAAI,MAAM,KAAK;AAAA,QACnB,MAAM,IAAI,MAAM,KAAK;AAAA,QACrB,SAAS,IAAI,MAAM,KAAK,UAClB;AAAA,UACI,IAAI,IAAI,MAAM,KAAK,QAAQ;AAAA,UAC3B,MAAM,IAAI,MAAM,KAAK,QAAQ;AAAA,UAC7B,MAAM,IAAI,MAAM,KAAK,QAAQ,QAAQ;AAAA,UACrC,MAAM,IAAI,MAAM,KAAK,QAAQ,QAAQ,MAAM;AAAA,UAC3C,aAAa,mBAAmB,IAAI,MAAM,KAAK,QAAQ,IAAI;AAAA,QAAA,IAE/D;AAAA,QACN,aAAa,mBAAmB,IAAI,MAAM,KAAK,QAAQ,MAAS;AAAA,MAAA,IAEpE;AAAA,MACN,SAAS,IAAI,MAAM,UACb;AAAA,QACI,IAAI,IAAI,MAAM,QAAQ;AAAA,QACtB,MAAM,IAAI,MAAM,QAAQ;AAAA,QACxB,MAAM,IAAI,MAAM,QAAQ,QAAQ;AAAA,QAChC,MAAM,IAAI,MAAM,QAAQ,QAAQ,MAAM;AAAA,QACtC,aAAa,mBAAmB,IAAI,MAAM,QAAQ,IAAI;AAAA,MAAA,IAE1D;AAAA,MACN,SAAS,IAAI,MAAM,UACb;AAAA,QACI,UAAU,IAAI,MAAM,QAAQ;AAAA,QAC5B,WAAW,IAAI,MAAM,QAAQ;AAAA,QAC7B,UAAU,IAAI,MAAM,QAAQ;AAAA,MAAA,IAEhC;AAAA,MACN,QAAQ,IAAI,MAAM,QAAQ,OAAO,MAC3B;AAAA,QACI,OAAO,IAAI,MAAM,OAAO,MAAM;AAAA,MAAA,IAElC;AAAA,MACN,aAAa,mBAAmB,IAAI,MAAM,IAAI;AAAA,IAAA,IAElD;AAAA,IAEN,OAAO,IAAI,QACL;AAAA,MACI,IAAI,IAAI,MAAM;AAAA,MACd,MAAM,IAAI,MAAM;AAAA,MAChB,MAAM,IAAI,MAAM;AAAA,MAChB,SAAS;AAAA,QACL,IAAI,IAAI,MAAM,QAAQ;AAAA,QACtB,MAAM,IAAI,MAAM,QAAQ;AAAA,QACxB,MAAM,IAAI,MAAM,QAAQ,QAAQ;AAAA,QAChC,MAAM,IAAI,MAAM,QAAQ,QAAQ,MAAM;AAAA,QACtC,aAAa,mBAAmB,IAAI,MAAM,QAAQ,IAAI;AAAA,MAAA;AAAA,MAE1D,WAAW,IAAI,MAAM;AAAA,MACrB,aAAa,mBAAmB,IAAI,MAAM,IAAI;AAAA,IAAA,IAElD;AAAA,IAEN,SAAS,IAAI;AAAA;AAAA,IAGb,QAAQ,IAAI,SACN;AAAA,MACI,MAAM,IAAI,OAAO,MAAM;AAAA,MACvB,SAAS,IAAI,OAAO,UAAU;AAAA,MAC9B,SAAS,IAAI,OAAO,UAAU;AAAA,MAC9B,YAAY,IAAI,OAAO,aAAa;AAAA,IAAA,IAExC;AAAA;AAAA,IAGN,UAAU;AAAA,MACN,aAAa,IAAI,cAAc,IAAI,CAAC,QAAQ;AAAA,QACxC,MAAM,GAAG;AAAA,QACT,WAAW,GAAG;AAAA,MAAA,EAChB;AAAA,MACF,SAAS,IAAI,SACP;AAAA,QACI,SAAS,IAAI,OAAO;AAAA,QACpB,GAAG,IAAI,OAAO;AAAA,QACd,UAAU,IAAI,OAAO;AAAA,QACrB,WAAW,IAAI,OAAO;AAAA,QACtB,WAAW,IAAI,OAAO;AAAA,MAAA,IAE1B;AAAA,IAAA;AAAA;AAAA,IAIV,eAAe,IAAI,gBAAgB,IAAI,CAAC,YAAY;AAAA,MAChD,IAAI,OAAO;AAAA,MACX,MAAM,OAAO;AAAA,MACb,MAAM,OAAO;AAAA,MACb,QAAQ,OAAO,WAAW;AAAA,MAC1B,aAAa,mBAAmB,OAAO,IAAI;AAAA,IAAA,EAC7C;AAAA,IAEF,eAAe,IAAI,iBACb;AAAA,MACI,IAAI,IAAI,eAAe;AAAA,MACvB,MAAM,IAAI,eAAe;AAAA,MACzB,MAAM,IAAI,eAAe;AAAA,MACzB,QAAQ,IAAI,eAAe,WAAW;AAAA,MACtC,aAAa,mBAAmB,IAAI,eAAe,IAAI;AAAA,IAAA,IAE3D;AAAA;AAAA,IAGN,MACI,IAAI,QAAQ,IAAI,KAAK,SAAS,IACxB;AAAA,MACI,cAAc,IAAI;AAAA,MAClB,SAAS,IAAI,KAAK,IAAI,CAAC,cAAc;AACjC,cAAM,SAAS,UAAU,aAAa,CAAC,EAAE,OAAO,IAAI;AACpD,cAAM,WAAW,SAAS,UAAU,aAAa,CAAC,IAAI,UAAU,aAAa,CAAC;AAC9E,cAAM,YAAY,UAAU,OAAO,CAAC,GAAG,QAAQ,KAAK,CAAC,MAAM,EAAE,aAAa,GAAG,GAAG;AAChF,cAAM,YAAY,UAAU,OAAO,CAAC,GAAG,QAAQ,KAAK,CAAC,MAAM,EAAE,aAAa,GAAG,GAAG;AAGhF,cAAM,SAAS,UAAU,YAAY,QAAQ,MAAM,UAAU,YAAY,SAAS,MAAM;AAExF,eAAO;AAAA,UACH,SAAS,UAAU;AAAA,UACnB;AAAA,UACA,OAAO,aAAa,YAAY,GAAG,SAAS,IAAI,SAAS,KAAK;AAAA,UAC9D,UAAU;AAAA,YACN,IAAI,SAAS;AAAA,YACb,MAAM,SAAS;AAAA,YACf,MAAM,SAAS,eAAe;AAAA,UAAA;AAAA,UAElC,MAAM,IAAI,KAAK,UAAU,UAAU;AAAA,UACnC,aAAa,UAAU,cACjB;AAAA,YACI,IAAI,UAAU,YAAY;AAAA,YAC1B,MAAM,UAAU,YAAY;AAAA,UAAA,IAEhC;AAAA,QAAA;AAAA,MAEd,CAAC;AAAA,MACD,YAAY,IAAI,KACX,IAAI,CAAC,OAAQ,GAAG,YAAY,QAAQ,MAAM,GAAG,YAAY,SAAS,MAAM,GAAI,EAC5E,KAAK,EAAE;AAAA,IAAA,IAEhB;AAAA,IAEV,aAAa,mBAAmB,IAAI,IAAI;AAAA,EAAA;AAEhD;AAKO,SAAS,qBAAqB,KAA0C;AAC3E,QAAM,SAAS,IAAI;AACnB,SAAO;AAAA,IACH,IAAI,OAAO;AAAA,IACX,MAAM,OAAO;AAAA,IACb,MAAM,OAAO;AAAA,IACb,UAAU,OAAO;AAAA,IACjB,aAAa,IAAI;AAAA,IACjB,SAAS,OAAO,UACV;AAAA,MACI,IAAI,OAAO,QAAQ;AAAA,MACnB,MAAM,OAAO,QAAQ;AAAA,MACrB,MAAM,OAAO,QAAQ,QAAQ;AAAA,MAC7B,MAAM,OAAO,QAAQ,QAAQ,MAAM;AAAA,MACnC,aAAa,mBAAmB,OAAO,QAAQ,IAAI;AAAA,IAAA,IAEvD;AAAA,IACN,QAAQ,OAAO;AAAA,IACf,WAAW,OAAO;AAAA,IAClB,SAAS;AAAA,MACL,QAAQ,OAAO,SAAS,UAAU;AAAA,MAClC,QAAQ,OAAO,SAAS,UAAU;AAAA,IAAA;AAAA,IAEtC,QAAQ,OAAO,SACT;AAAA,MACI,OAAO,OAAO,OAAO,OAAO;AAAA,MAC5B,kBAAkB,OAAO,OAAO,8BAA8B;AAAA,IAAA,IAElE;AAAA,IACN,QAAQ,IAAI;AAAA,IACZ,cAAc,IAAI;AAAA,IAClB,eAAe,IAAI,kBAAkB;AAAA,IACrC,YAAY,IAAI,cAAc;AAAA,IAC9B,aAAa,mBAAmB,OAAO,EAAE;AAAA;AAAA,EAAA;AAEjD;AAKO,SAAS,oBAAoB,KAAmC;AACnE,SAAO;AAAA,IACH,IAAI,IAAI;AAAA,IACR,MAAM,IAAI;AAAA,IACV,MAAM,IAAI;AAAA,IACV,SAAS,IAAI,UACP;AAAA,MACI,IAAI,IAAI,QAAQ;AAAA,MAChB,MAAM,IAAI,QAAQ;AAAA,MAClB,MAAM,IAAI,QAAQ,QAAQ;AAAA,MAC1B,MAAM,IAAI,QAAQ,QAAQ,MAAM;AAAA,MAChC,aAAa,mBAAmB,IAAI,QAAQ,IAAI;AAAA,IAAA,IAEpD;AAAA,IACN,WAAW,IAAI;AAAA,IACf,aAAa,mBAAmB,IAAI,IAAI;AAAA,EAAA;AAEhD;AAKO,SAAS,eAAe,KAAsC;AACjE,SAAO;AAAA,IACH,QAAQ,IAAI,KAAK;AAAA,IACjB,UAAU,IAAI,KAAK;AAAA,IACnB,OAAO,IAAI,QAAQ,oBAAoB,IAAI,KAAK,IAAI;AAAA,IACpD,SAAS,IAAI,QAAQ,IAAI,oBAAoB;AAAA,EAAA;AAErD;"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { getConfig } from "../../config/index.js";
|
|
2
|
+
function createHttpClient(domain) {
|
|
3
|
+
const baseUrl = domain.replace(/\/$/, "");
|
|
4
|
+
function getAuthHeader(config) {
|
|
5
|
+
const { sportal365Sports } = config;
|
|
6
|
+
if (!sportal365Sports) {
|
|
7
|
+
throw new Error("Sportal365 Sports API configuration is missing");
|
|
8
|
+
}
|
|
9
|
+
const credentials = `${sportal365Sports.username}:${sportal365Sports.password}`;
|
|
10
|
+
return `Basic ${btoa(credentials)}`;
|
|
11
|
+
}
|
|
12
|
+
function buildUrl(path) {
|
|
13
|
+
return `${baseUrl}${path}`;
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
async get(options) {
|
|
17
|
+
const finalConfig = options.config || getConfig();
|
|
18
|
+
const { sportal365Sports } = finalConfig;
|
|
19
|
+
if (!sportal365Sports) {
|
|
20
|
+
throw new Error("Sportal365 Sports API configuration is missing");
|
|
21
|
+
}
|
|
22
|
+
const url = new URL(buildUrl(options.path));
|
|
23
|
+
if (options.params) {
|
|
24
|
+
for (const [key, value] of Object.entries(options.params)) {
|
|
25
|
+
if (value === void 0) continue;
|
|
26
|
+
if (Array.isArray(value)) {
|
|
27
|
+
if (value.length > 0) {
|
|
28
|
+
url.searchParams.set(key, value.join(","));
|
|
29
|
+
}
|
|
30
|
+
} else {
|
|
31
|
+
url.searchParams.set(key, value);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const response = await fetch(url.toString(), {
|
|
36
|
+
method: "GET",
|
|
37
|
+
headers: {
|
|
38
|
+
Authorization: getAuthHeader(finalConfig),
|
|
39
|
+
"Content-Type": "application/json",
|
|
40
|
+
"X-Project": sportal365Sports.projectId,
|
|
41
|
+
// Merge custom headers (they can override defaults)
|
|
42
|
+
...options.headers
|
|
43
|
+
},
|
|
44
|
+
signal: sportal365Sports.timeout ? AbortSignal.timeout(sportal365Sports.timeout) : void 0,
|
|
45
|
+
// Next.js cache options for ISR/on-demand revalidation
|
|
46
|
+
...options.next && { next: options.next }
|
|
47
|
+
});
|
|
48
|
+
if (!response.ok) {
|
|
49
|
+
throw new Error(`Sportal365 API error: ${response.status} ${response.statusText}`);
|
|
50
|
+
}
|
|
51
|
+
return response.json();
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export {
|
|
56
|
+
createHttpClient
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +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 the Sportal365 Sports API\n *\n * Handles:\n * - Authentication (Basic Auth)\n * - Project ID header\n * - Timeout\n * - Error handling\n *\n * @param options - Request options\n * @returns Parsed JSON response\n */\n get<T>(options: RequestOptions): Promise<T>;\n}\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 signal: sportal365Sports.timeout ? AbortSignal.timeout(sportal365Sports.timeout) : undefined,\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"],"names":[],"mappings":";AA8DO,SAAS,iBAAiB,QAAsC;AACnE,QAAM,UAAU,OAAO,QAAQ,OAAO,EAAE;AAExC,WAAS,cAAc,QAAiC;AACpD,UAAM,EAAE,qBAAqB;AAC7B,QAAI,CAAC,kBAAkB;AACnB,YAAM,IAAI,MAAM,gDAAgD;AAAA,IACpE;AACA,UAAM,cAAc,GAAG,iBAAiB,QAAQ,IAAI,iBAAiB,QAAQ;AAC7E,WAAO,SAAS,KAAK,WAAW,CAAC;AAAA,EACrC;AAEA,WAAS,SAAS,MAAsB;AACpC,WAAO,GAAG,OAAO,GAAG,IAAI;AAAA,EAC5B;AAEA,SAAO;AAAA,IACH,MAAM,IAAO,SAAqC;AAC9C,YAAM,cAAc,QAAQ,UAAU,UAAA;AACtC,YAAM,EAAE,qBAAqB;AAE7B,UAAI,CAAC,kBAAkB;AACnB,cAAM,IAAI,MAAM,gDAAgD;AAAA,MACpE;AAEA,YAAM,MAAM,IAAI,IAAI,SAAS,QAAQ,IAAI,CAAC;AAG1C,UAAI,QAAQ,QAAQ;AAChB,mBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,MAAM,GAAG;AACvD,cAAI,UAAU,OAAW;AAEzB,cAAI,MAAM,QAAQ,KAAK,GAAG;AACtB,gBAAI,MAAM,SAAS,GAAG;AAClB,kBAAI,aAAa,IAAI,KAAK,MAAM,KAAK,GAAG,CAAC;AAAA,YAC7C;AAAA,UACJ,OAAO;AACH,gBAAI,aAAa,IAAI,KAAK,KAAK;AAAA,UACnC;AAAA,QACJ;AAAA,MACJ;AAEA,YAAM,WAAW,MAAM,MAAM,IAAI,YAAY;AAAA,QACzC,QAAQ;AAAA,QACR,SAAS;AAAA,UACL,eAAe,cAAc,WAAW;AAAA,UACxC,gBAAgB;AAAA,UAChB,aAAa,iBAAiB;AAAA;AAAA,UAE9B,GAAG,QAAQ;AAAA,QAAA;AAAA,QAEf,QAAQ,iBAAiB,UAAU,YAAY,QAAQ,iBAAiB,OAAO,IAAI;AAAA;AAAA,QAEnF,GAAI,QAAQ,QAAQ,EAAE,MAAM,QAAQ,KAAA;AAAA,MAAK,CAC5C;AAED,UAAI,CAAC,SAAS,IAAI;AACd,cAAM,IAAI,MAAM,yBAAyB,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,MACrF;AAEA,aAAO,SAAS,KAAA;AAAA,IACpB;AAAA,EAAA;AAER;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sources":["../../../../src/lib/api/sportal365-sports/search/http.ts"],"sourcesContent":["/**\n * HTTP client for Sports Search API\n */\n\nimport { createHttpClient } from \"../http\";\nimport { SPORTAL365_SPORTS_SEARCH_DOMAIN } from \"../constants\";\n\n/**\n * HTTP client for Sports Search API\n */\nexport const sportsSearchHttp = createHttpClient(SPORTAL365_SPORTS_SEARCH_DOMAIN);\n\n"],"names":[],"mappings":";;AAUO,MAAM,mBAAmB,iBAAiB,+BAA+B;"}
|