fansunited-data-layer 0.12.1 → 0.14.1
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.js +74 -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/index.d.ts +2 -2
- package/api/sportal365-sports/football/index.d.ts.map +1 -1
- 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.d.ts +46 -1
- package/api/sportal365-sports/football/statistics/index.d.ts.map +1 -1
- 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.d.ts +11 -0
- package/api/sportal365-sports/football/statistics/player-career.transformer.d.ts.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-career.types.d.ts +115 -0
- package/api/sportal365-sports/football/statistics/player-career.types.d.ts.map +1 -0
- package/api/sportal365-sports/football/statistics/player-recent.transformer.d.ts +11 -0
- package/api/sportal365-sports/football/statistics/player-recent.transformer.d.ts.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-recent.types.d.ts +31 -0
- package/api/sportal365-sports/football/statistics/player-recent.types.d.ts.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/index.d.ts +2 -2
- package/api/sportal365-sports/index.d.ts.map +1 -1
- 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 -3551
- 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/index.d.ts +3 -3
- package/index.d.ts.map +1 -1
- 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/types/canonical/index.d.ts +1 -1
- package/types/canonical/index.d.ts.map +1 -1
- package/types/canonical/statistics.types.d.ts +102 -0
- package/types/canonical/statistics.types.d.ts.map +1 -1
- 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-CB-dSXEA.js +0 -1633
- package/matches-DvC2VSyO.cjs +0 -1
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
function calculateStreak(matches, teamId, filter, venueFilter) {
|
|
2
|
+
const teamMatches = matches.filter((m) => {
|
|
3
|
+
const isHome = m.competitorOne.id === teamId;
|
|
4
|
+
const isAway = m.competitorTwo.id === teamId;
|
|
5
|
+
if (!isHome && !isAway) return false;
|
|
6
|
+
if (m.status?.type !== "FINISHED") return false;
|
|
7
|
+
if (venueFilter === "home" && !isHome) return false;
|
|
8
|
+
if (venueFilter === "away" && !isAway) return false;
|
|
9
|
+
return true;
|
|
10
|
+
}).sort((a, b) => new Date(b.timing.kickoffTime).getTime() - new Date(a.timing.kickoffTime).getTime());
|
|
11
|
+
if (teamMatches.length === 0) return null;
|
|
12
|
+
let streak = 0;
|
|
13
|
+
for (const match of teamMatches) {
|
|
14
|
+
const isHome = match.competitorOne.id === teamId;
|
|
15
|
+
if (filter(match, teamId, isHome)) {
|
|
16
|
+
streak++;
|
|
17
|
+
} else {
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return streak > 0 ? streak : null;
|
|
22
|
+
}
|
|
23
|
+
const streakFilters = {
|
|
24
|
+
win: (m, _teamId, isHome) => {
|
|
25
|
+
const teamScore = isHome ? parseInt(m.score?.competitorOne || "0") : parseInt(m.score?.competitorTwo || "0");
|
|
26
|
+
const oppScore = isHome ? parseInt(m.score?.competitorTwo || "0") : parseInt(m.score?.competitorOne || "0");
|
|
27
|
+
return teamScore > oppScore;
|
|
28
|
+
},
|
|
29
|
+
draw: (m) => {
|
|
30
|
+
return m.score?.competitorOne === m.score?.competitorTwo;
|
|
31
|
+
},
|
|
32
|
+
loss: (m, _teamId, isHome) => {
|
|
33
|
+
const teamScore = isHome ? parseInt(m.score?.competitorOne || "0") : parseInt(m.score?.competitorTwo || "0");
|
|
34
|
+
const oppScore = isHome ? parseInt(m.score?.competitorTwo || "0") : parseInt(m.score?.competitorOne || "0");
|
|
35
|
+
return teamScore < oppScore;
|
|
36
|
+
},
|
|
37
|
+
noWin: (m, teamId, isHome) => !streakFilters.win(m, teamId, isHome),
|
|
38
|
+
noDraw: (m) => !streakFilters.draw(m),
|
|
39
|
+
noDefeat: (m, teamId, isHome) => !streakFilters.loss(m, teamId, isHome),
|
|
40
|
+
scored: (m, _teamId, isHome) => {
|
|
41
|
+
const teamScore = isHome ? parseInt(m.score?.competitorOne || "0") : parseInt(m.score?.competitorTwo || "0");
|
|
42
|
+
return teamScore >= 1;
|
|
43
|
+
},
|
|
44
|
+
conceded: (m, _teamId, isHome) => {
|
|
45
|
+
const oppScore = isHome ? parseInt(m.score?.competitorTwo || "0") : parseInt(m.score?.competitorOne || "0");
|
|
46
|
+
return oppScore >= 1;
|
|
47
|
+
},
|
|
48
|
+
noGoalScored: (m, teamId, isHome) => !streakFilters.scored(m, teamId, isHome),
|
|
49
|
+
noGoalConceded: (m, teamId, isHome) => !streakFilters.conceded(m, teamId, isHome),
|
|
50
|
+
over25: (m) => {
|
|
51
|
+
const total = parseInt(m.score?.competitorOne || "0") + parseInt(m.score?.competitorTwo || "0");
|
|
52
|
+
return total > 2;
|
|
53
|
+
},
|
|
54
|
+
under25: (m) => {
|
|
55
|
+
const total = parseInt(m.score?.competitorOne || "0") + parseInt(m.score?.competitorTwo || "0");
|
|
56
|
+
return total < 3;
|
|
57
|
+
},
|
|
58
|
+
scoredTwice: (m, _teamId, isHome) => {
|
|
59
|
+
const teamScore = isHome ? parseInt(m.score?.competitorOne || "0") : parseInt(m.score?.competitorTwo || "0");
|
|
60
|
+
return teamScore >= 2;
|
|
61
|
+
},
|
|
62
|
+
concededTwice: (m, _teamId, isHome) => {
|
|
63
|
+
const oppScore = isHome ? parseInt(m.score?.competitorTwo || "0") : parseInt(m.score?.competitorOne || "0");
|
|
64
|
+
return oppScore >= 2;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
function getTeamStreaks(matches, teamId, venueFilter) {
|
|
68
|
+
return {
|
|
69
|
+
win: calculateStreak(matches, teamId, streakFilters.win, venueFilter),
|
|
70
|
+
draw: calculateStreak(matches, teamId, streakFilters.draw, venueFilter),
|
|
71
|
+
loss: calculateStreak(matches, teamId, streakFilters.loss, venueFilter),
|
|
72
|
+
noWin: calculateStreak(matches, teamId, streakFilters.noWin, venueFilter),
|
|
73
|
+
noDraw: calculateStreak(matches, teamId, streakFilters.noDraw, venueFilter),
|
|
74
|
+
noDefeat: calculateStreak(matches, teamId, streakFilters.noDefeat, venueFilter),
|
|
75
|
+
scored: calculateStreak(matches, teamId, streakFilters.scored, venueFilter),
|
|
76
|
+
conceded: calculateStreak(matches, teamId, streakFilters.conceded, venueFilter),
|
|
77
|
+
noGoalScored: calculateStreak(matches, teamId, streakFilters.noGoalScored, venueFilter),
|
|
78
|
+
noGoalConceded: calculateStreak(matches, teamId, streakFilters.noGoalConceded, venueFilter),
|
|
79
|
+
over25: calculateStreak(matches, teamId, streakFilters.over25, venueFilter),
|
|
80
|
+
under25: calculateStreak(matches, teamId, streakFilters.under25, venueFilter),
|
|
81
|
+
scoredTwice: calculateStreak(matches, teamId, streakFilters.scoredTwice, venueFilter),
|
|
82
|
+
concededTwice: calculateStreak(matches, teamId, streakFilters.concededTwice, venueFilter)
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function getTeamStreaksComparison(matches, homeTeamId, awayTeamId) {
|
|
86
|
+
const homeTeamHomeStreaks = getTeamStreaks(matches, homeTeamId, "home");
|
|
87
|
+
const homeTeamTotalStreaks = getTeamStreaks(matches, homeTeamId);
|
|
88
|
+
const awayTeamAwayStreaks = getTeamStreaks(matches, awayTeamId, "away");
|
|
89
|
+
const awayTeamTotalStreaks = getTeamStreaks(matches, awayTeamId);
|
|
90
|
+
return [
|
|
91
|
+
{
|
|
92
|
+
label: "Consecutive wins",
|
|
93
|
+
homeTeam: { home: homeTeamHomeStreaks.win, total: homeTeamTotalStreaks.win },
|
|
94
|
+
awayTeam: { total: awayTeamTotalStreaks.win, home: awayTeamAwayStreaks.win },
|
|
95
|
+
colorType: "neutral"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
label: "Consecutive draws",
|
|
99
|
+
homeTeam: { home: homeTeamHomeStreaks.draw, total: homeTeamTotalStreaks.draw },
|
|
100
|
+
awayTeam: { total: awayTeamTotalStreaks.draw, home: awayTeamAwayStreaks.draw },
|
|
101
|
+
colorType: "neutral"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
label: "Consecutive defeats",
|
|
105
|
+
homeTeam: { home: homeTeamHomeStreaks.loss, total: homeTeamTotalStreaks.loss },
|
|
106
|
+
awayTeam: { total: awayTeamTotalStreaks.loss, home: awayTeamAwayStreaks.loss },
|
|
107
|
+
colorType: "neutral"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
label: "No win",
|
|
111
|
+
homeTeam: { home: homeTeamHomeStreaks.noWin, total: homeTeamTotalStreaks.noWin },
|
|
112
|
+
awayTeam: { total: awayTeamTotalStreaks.noWin, home: awayTeamAwayStreaks.noWin },
|
|
113
|
+
colorType: "negative"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
label: "No draw",
|
|
117
|
+
homeTeam: { home: homeTeamHomeStreaks.noDraw, total: homeTeamTotalStreaks.noDraw },
|
|
118
|
+
awayTeam: { total: awayTeamTotalStreaks.noDraw, home: awayTeamAwayStreaks.noDraw },
|
|
119
|
+
colorType: "neutral"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
label: "No defeat",
|
|
123
|
+
homeTeam: { home: homeTeamHomeStreaks.noDefeat, total: homeTeamTotalStreaks.noDefeat },
|
|
124
|
+
awayTeam: { total: awayTeamTotalStreaks.noDefeat, home: awayTeamAwayStreaks.noDefeat },
|
|
125
|
+
colorType: "positive"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
label: "Scored at least once",
|
|
129
|
+
homeTeam: { home: homeTeamHomeStreaks.scored, total: homeTeamTotalStreaks.scored },
|
|
130
|
+
awayTeam: { total: awayTeamTotalStreaks.scored, home: awayTeamAwayStreaks.scored },
|
|
131
|
+
colorType: "positive"
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
label: "Conceded at least once",
|
|
135
|
+
homeTeam: { home: homeTeamHomeStreaks.conceded, total: homeTeamTotalStreaks.conceded },
|
|
136
|
+
awayTeam: { total: awayTeamTotalStreaks.conceded, home: awayTeamAwayStreaks.conceded },
|
|
137
|
+
colorType: "negative"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
label: "No goal scored",
|
|
141
|
+
homeTeam: { home: homeTeamHomeStreaks.noGoalScored, total: homeTeamTotalStreaks.noGoalScored },
|
|
142
|
+
awayTeam: { total: awayTeamTotalStreaks.noGoalScored, home: awayTeamAwayStreaks.noGoalScored },
|
|
143
|
+
colorType: "neutral"
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
label: "No goal conceded",
|
|
147
|
+
homeTeam: { home: homeTeamHomeStreaks.noGoalConceded, total: homeTeamTotalStreaks.noGoalConceded },
|
|
148
|
+
awayTeam: { total: awayTeamTotalStreaks.noGoalConceded, home: awayTeamAwayStreaks.noGoalConceded },
|
|
149
|
+
colorType: "neutral"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
label: "GS + GC over 2.5",
|
|
153
|
+
homeTeam: { home: homeTeamHomeStreaks.over25, total: homeTeamTotalStreaks.over25 },
|
|
154
|
+
awayTeam: { total: awayTeamTotalStreaks.over25, home: awayTeamAwayStreaks.over25 },
|
|
155
|
+
colorType: "neutral"
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
label: "GS + GC under 2.5",
|
|
159
|
+
homeTeam: { home: homeTeamHomeStreaks.under25, total: homeTeamTotalStreaks.under25 },
|
|
160
|
+
awayTeam: { total: awayTeamTotalStreaks.under25, home: awayTeamAwayStreaks.under25 },
|
|
161
|
+
colorType: "neutral"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
label: "Scored at least twice",
|
|
165
|
+
homeTeam: { home: homeTeamHomeStreaks.scoredTwice, total: homeTeamTotalStreaks.scoredTwice },
|
|
166
|
+
awayTeam: { total: awayTeamTotalStreaks.scoredTwice, home: awayTeamAwayStreaks.scoredTwice },
|
|
167
|
+
colorType: "positive"
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
label: "Conceded at least twice",
|
|
171
|
+
homeTeam: { home: homeTeamHomeStreaks.concededTwice, total: homeTeamTotalStreaks.concededTwice },
|
|
172
|
+
awayTeam: { total: awayTeamTotalStreaks.concededTwice, home: awayTeamAwayStreaks.concededTwice },
|
|
173
|
+
colorType: "negative"
|
|
174
|
+
}
|
|
175
|
+
];
|
|
176
|
+
}
|
|
177
|
+
export {
|
|
178
|
+
calculateStreak,
|
|
179
|
+
getTeamStreaks,
|
|
180
|
+
getTeamStreaksComparison,
|
|
181
|
+
streakFilters
|
|
182
|
+
};
|
|
183
|
+
//# sourceMappingURL=streaks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streaks.js","sources":["../../../../src/lib/utilities/stats/team/streaks.ts"],"sourcesContent":["/**\n * Team streak calculations (consecutive results).\n */\n\nimport type { FUSportsMatch } from \"../../../types/canonical\";\nimport type { MatchFilter, VenueFilter } from \"../core/types\";\n\nexport interface StreakData {\n home: number | null;\n total: number | null;\n}\n\nexport interface StreakRow {\n label: string;\n homeTeam: StreakData;\n awayTeam: StreakData;\n colorType: \"positive\" | \"negative\" | \"neutral\";\n}\n\n/**\n * Calculate streak for a team based on a filter condition.\n * Returns how many consecutive recent matches satisfy the condition.\n */\nexport function calculateStreak(\n matches: FUSportsMatch[],\n teamId: string,\n filter: MatchFilter,\n venueFilter?: VenueFilter\n): number | null {\n // Get team's finished matches sorted by date (most recent first)\n const teamMatches = matches\n .filter((m) => {\n const isHome = m.competitorOne.id === teamId;\n const isAway = m.competitorTwo.id === teamId;\n if (!isHome && !isAway) return false;\n if (m.status?.type !== \"FINISHED\") return false;\n if (venueFilter === \"home\" && !isHome) return false;\n if (venueFilter === \"away\" && !isAway) return false;\n return true;\n })\n .sort((a, b) => new Date(b.timing.kickoffTime).getTime() - new Date(a.timing.kickoffTime).getTime());\n\n if (teamMatches.length === 0) return null;\n\n let streak = 0;\n for (const match of teamMatches) {\n const isHome = match.competitorOne.id === teamId;\n if (filter(match, teamId, isHome)) {\n streak++;\n } else {\n break;\n }\n }\n return streak > 0 ? streak : null;\n}\n\n/**\n * Predefined streak filter functions.\n */\nexport const streakFilters = {\n win: (m: FUSportsMatch, _teamId: string, isHome: boolean) => {\n const teamScore = isHome ? parseInt(m.score?.competitorOne || \"0\") : parseInt(m.score?.competitorTwo || \"0\");\n const oppScore = isHome ? parseInt(m.score?.competitorTwo || \"0\") : parseInt(m.score?.competitorOne || \"0\");\n return teamScore > oppScore;\n },\n draw: (m: FUSportsMatch) => {\n return m.score?.competitorOne === m.score?.competitorTwo;\n },\n loss: (m: FUSportsMatch, _teamId: string, isHome: boolean) => {\n const teamScore = isHome ? parseInt(m.score?.competitorOne || \"0\") : parseInt(m.score?.competitorTwo || \"0\");\n const oppScore = isHome ? parseInt(m.score?.competitorTwo || \"0\") : parseInt(m.score?.competitorOne || \"0\");\n return teamScore < oppScore;\n },\n noWin: (m: FUSportsMatch, teamId: string, isHome: boolean) => !streakFilters.win(m, teamId, isHome),\n noDraw: (m: FUSportsMatch) => !streakFilters.draw(m),\n noDefeat: (m: FUSportsMatch, teamId: string, isHome: boolean) => !streakFilters.loss(m, teamId, isHome),\n scored: (m: FUSportsMatch, _teamId: string, isHome: boolean) => {\n const teamScore = isHome ? parseInt(m.score?.competitorOne || \"0\") : parseInt(m.score?.competitorTwo || \"0\");\n return teamScore >= 1;\n },\n conceded: (m: FUSportsMatch, _teamId: string, isHome: boolean) => {\n const oppScore = isHome ? parseInt(m.score?.competitorTwo || \"0\") : parseInt(m.score?.competitorOne || \"0\");\n return oppScore >= 1;\n },\n noGoalScored: (m: FUSportsMatch, teamId: string, isHome: boolean) => !streakFilters.scored(m, teamId, isHome),\n noGoalConceded: (m: FUSportsMatch, teamId: string, isHome: boolean) => !streakFilters.conceded(m, teamId, isHome),\n over25: (m: FUSportsMatch) => {\n const total = parseInt(m.score?.competitorOne || \"0\") + parseInt(m.score?.competitorTwo || \"0\");\n return total > 2;\n },\n under25: (m: FUSportsMatch) => {\n const total = parseInt(m.score?.competitorOne || \"0\") + parseInt(m.score?.competitorTwo || \"0\");\n return total < 3;\n },\n scoredTwice: (m: FUSportsMatch, _teamId: string, isHome: boolean) => {\n const teamScore = isHome ? parseInt(m.score?.competitorOne || \"0\") : parseInt(m.score?.competitorTwo || \"0\");\n return teamScore >= 2;\n },\n concededTwice: (m: FUSportsMatch, _teamId: string, isHome: boolean) => {\n const oppScore = isHome ? parseInt(m.score?.competitorTwo || \"0\") : parseInt(m.score?.competitorOne || \"0\");\n return oppScore >= 2;\n },\n};\n\n/**\n * Get all streaks for a team.\n */\nexport function getTeamStreaks(\n matches: FUSportsMatch[],\n teamId: string,\n venueFilter?: VenueFilter\n): Record<string, number | null> {\n return {\n win: calculateStreak(matches, teamId, streakFilters.win, venueFilter),\n draw: calculateStreak(matches, teamId, streakFilters.draw, venueFilter),\n loss: calculateStreak(matches, teamId, streakFilters.loss, venueFilter),\n noWin: calculateStreak(matches, teamId, streakFilters.noWin, venueFilter),\n noDraw: calculateStreak(matches, teamId, streakFilters.noDraw, venueFilter),\n noDefeat: calculateStreak(matches, teamId, streakFilters.noDefeat, venueFilter),\n scored: calculateStreak(matches, teamId, streakFilters.scored, venueFilter),\n conceded: calculateStreak(matches, teamId, streakFilters.conceded, venueFilter),\n noGoalScored: calculateStreak(matches, teamId, streakFilters.noGoalScored, venueFilter),\n noGoalConceded: calculateStreak(matches, teamId, streakFilters.noGoalConceded, venueFilter),\n over25: calculateStreak(matches, teamId, streakFilters.over25, venueFilter),\n under25: calculateStreak(matches, teamId, streakFilters.under25, venueFilter),\n scoredTwice: calculateStreak(matches, teamId, streakFilters.scoredTwice, venueFilter),\n concededTwice: calculateStreak(matches, teamId, streakFilters.concededTwice, venueFilter),\n };\n}\n\n/**\n * Get team streaks comparison for two teams.\n */\nexport function getTeamStreaksComparison(\n matches: FUSportsMatch[],\n homeTeamId: string,\n awayTeamId: string\n): StreakRow[] {\n // Get streaks for home team (home venue and total)\n const homeTeamHomeStreaks = getTeamStreaks(matches, homeTeamId, \"home\");\n const homeTeamTotalStreaks = getTeamStreaks(matches, homeTeamId);\n\n // Get streaks for away team (away venue and total)\n const awayTeamAwayStreaks = getTeamStreaks(matches, awayTeamId, \"away\");\n const awayTeamTotalStreaks = getTeamStreaks(matches, awayTeamId);\n\n return [\n {\n label: \"Consecutive wins\",\n homeTeam: { home: homeTeamHomeStreaks.win, total: homeTeamTotalStreaks.win },\n awayTeam: { total: awayTeamTotalStreaks.win, home: awayTeamAwayStreaks.win },\n colorType: \"neutral\",\n },\n {\n label: \"Consecutive draws\",\n homeTeam: { home: homeTeamHomeStreaks.draw, total: homeTeamTotalStreaks.draw },\n awayTeam: { total: awayTeamTotalStreaks.draw, home: awayTeamAwayStreaks.draw },\n colorType: \"neutral\",\n },\n {\n label: \"Consecutive defeats\",\n homeTeam: { home: homeTeamHomeStreaks.loss, total: homeTeamTotalStreaks.loss },\n awayTeam: { total: awayTeamTotalStreaks.loss, home: awayTeamAwayStreaks.loss },\n colorType: \"neutral\",\n },\n {\n label: \"No win\",\n homeTeam: { home: homeTeamHomeStreaks.noWin, total: homeTeamTotalStreaks.noWin },\n awayTeam: { total: awayTeamTotalStreaks.noWin, home: awayTeamAwayStreaks.noWin },\n colorType: \"negative\",\n },\n {\n label: \"No draw\",\n homeTeam: { home: homeTeamHomeStreaks.noDraw, total: homeTeamTotalStreaks.noDraw },\n awayTeam: { total: awayTeamTotalStreaks.noDraw, home: awayTeamAwayStreaks.noDraw },\n colorType: \"neutral\",\n },\n {\n label: \"No defeat\",\n homeTeam: { home: homeTeamHomeStreaks.noDefeat, total: homeTeamTotalStreaks.noDefeat },\n awayTeam: { total: awayTeamTotalStreaks.noDefeat, home: awayTeamAwayStreaks.noDefeat },\n colorType: \"positive\",\n },\n {\n label: \"Scored at least once\",\n homeTeam: { home: homeTeamHomeStreaks.scored, total: homeTeamTotalStreaks.scored },\n awayTeam: { total: awayTeamTotalStreaks.scored, home: awayTeamAwayStreaks.scored },\n colorType: \"positive\",\n },\n {\n label: \"Conceded at least once\",\n homeTeam: { home: homeTeamHomeStreaks.conceded, total: homeTeamTotalStreaks.conceded },\n awayTeam: { total: awayTeamTotalStreaks.conceded, home: awayTeamAwayStreaks.conceded },\n colorType: \"negative\",\n },\n {\n label: \"No goal scored\",\n homeTeam: { home: homeTeamHomeStreaks.noGoalScored, total: homeTeamTotalStreaks.noGoalScored },\n awayTeam: { total: awayTeamTotalStreaks.noGoalScored, home: awayTeamAwayStreaks.noGoalScored },\n colorType: \"neutral\",\n },\n {\n label: \"No goal conceded\",\n homeTeam: { home: homeTeamHomeStreaks.noGoalConceded, total: homeTeamTotalStreaks.noGoalConceded },\n awayTeam: { total: awayTeamTotalStreaks.noGoalConceded, home: awayTeamAwayStreaks.noGoalConceded },\n colorType: \"neutral\",\n },\n {\n label: \"GS + GC over 2.5\",\n homeTeam: { home: homeTeamHomeStreaks.over25, total: homeTeamTotalStreaks.over25 },\n awayTeam: { total: awayTeamTotalStreaks.over25, home: awayTeamAwayStreaks.over25 },\n colorType: \"neutral\",\n },\n {\n label: \"GS + GC under 2.5\",\n homeTeam: { home: homeTeamHomeStreaks.under25, total: homeTeamTotalStreaks.under25 },\n awayTeam: { total: awayTeamTotalStreaks.under25, home: awayTeamAwayStreaks.under25 },\n colorType: \"neutral\",\n },\n {\n label: \"Scored at least twice\",\n homeTeam: { home: homeTeamHomeStreaks.scoredTwice, total: homeTeamTotalStreaks.scoredTwice },\n awayTeam: { total: awayTeamTotalStreaks.scoredTwice, home: awayTeamAwayStreaks.scoredTwice },\n colorType: \"positive\",\n },\n {\n label: \"Conceded at least twice\",\n homeTeam: { home: homeTeamHomeStreaks.concededTwice, total: homeTeamTotalStreaks.concededTwice },\n awayTeam: { total: awayTeamTotalStreaks.concededTwice, home: awayTeamAwayStreaks.concededTwice },\n colorType: \"negative\",\n },\n ];\n}\n"],"names":[],"mappings":"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"}
|