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.
Files changed (261) hide show
  1. package/api/fansunited/constants.js +5 -0
  2. package/api/fansunited/constants.js.map +1 -0
  3. package/api/fansunited/football/competition/index.js +21 -0
  4. package/api/fansunited/football/competition/index.js.map +1 -0
  5. package/api/fansunited/football/competition/transformer.js +41 -0
  6. package/api/fansunited/football/competition/transformer.js.map +1 -0
  7. package/api/fansunited/football/competitions/index.js +56 -0
  8. package/api/fansunited/football/competitions/index.js.map +1 -0
  9. package/api/fansunited/football/competitions/transformer.js +68 -0
  10. package/api/fansunited/football/competitions/transformer.js.map +1 -0
  11. package/api/fansunited/football/http.js +7 -0
  12. package/api/fansunited/football/http.js.map +1 -0
  13. package/api/fansunited/football/matches/index.js +132 -0
  14. package/api/fansunited/football/matches/index.js.map +1 -0
  15. package/api/fansunited/football/matches/transformer.js +148 -0
  16. package/api/fansunited/football/matches/transformer.js.map +1 -0
  17. package/api/fansunited/football/players/index.js +60 -0
  18. package/api/fansunited/football/players/index.js.map +1 -0
  19. package/api/fansunited/football/players/transformer.js +85 -0
  20. package/api/fansunited/football/players/transformer.js.map +1 -0
  21. package/api/fansunited/football/search/index.js +64 -0
  22. package/api/fansunited/football/search/index.js.map +1 -0
  23. package/api/fansunited/football/search/transformer.js +114 -0
  24. package/api/fansunited/football/search/transformer.js.map +1 -0
  25. package/api/fansunited/football/teams/index.js +66 -0
  26. package/api/fansunited/football/teams/index.js.map +1 -0
  27. package/api/fansunited/football/teams/transformer.js +53 -0
  28. package/api/fansunited/football/teams/transformer.js.map +1 -0
  29. package/api/fansunited/http.js +74 -0
  30. package/api/fansunited/http.js.map +1 -0
  31. package/api/fansunited/search/constants.js +5 -0
  32. package/api/fansunited/search/constants.js.map +1 -0
  33. package/api/fansunited/search/http.js +7 -0
  34. package/api/fansunited/search/http.js.map +1 -0
  35. package/api/fansunited/search/index.js +308 -0
  36. package/api/fansunited/search/index.js.map +1 -0
  37. package/api/fansunited/search/transformer.js +374 -0
  38. package/api/fansunited/search/transformer.js.map +1 -0
  39. package/api/fansunited-sdk/loyalty/matches.js +21 -0
  40. package/api/fansunited-sdk/loyalty/matches.js.map +1 -0
  41. package/api/fansunited-sdk/loyalty/template.js +52 -0
  42. package/api/fansunited-sdk/loyalty/template.js.map +1 -0
  43. package/api/fansunited-sdk/odds/matches.js +109 -0
  44. package/api/fansunited-sdk/odds/matches.js.map +1 -0
  45. package/api/sportal365-sports/basketball/games/index.js +32 -0
  46. package/api/sportal365-sports/basketball/games/index.js.map +1 -0
  47. package/api/sportal365-sports/basketball/games/transformers/game.js +137 -0
  48. package/api/sportal365-sports/basketball/games/transformers/game.js.map +1 -0
  49. package/api/sportal365-sports/basketball/http.js +7 -0
  50. package/api/sportal365-sports/basketball/http.js.map +1 -0
  51. package/api/sportal365-sports/constants.js +15 -0
  52. package/api/sportal365-sports/constants.js.map +1 -0
  53. package/api/sportal365-sports/football/competitions/index.js +52 -0
  54. package/api/sportal365-sports/football/competitions/index.js.map +1 -0
  55. package/api/sportal365-sports/football/competitions/utils.js +92 -0
  56. package/api/sportal365-sports/football/competitions/utils.js.map +1 -0
  57. package/api/sportal365-sports/football/http.js +7 -0
  58. package/api/sportal365-sports/football/http.js.map +1 -0
  59. package/api/sportal365-sports/football/index.d.ts +2 -2
  60. package/api/sportal365-sports/football/index.d.ts.map +1 -1
  61. package/api/sportal365-sports/football/matches/index.js +206 -0
  62. package/api/sportal365-sports/football/matches/index.js.map +1 -0
  63. package/api/sportal365-sports/football/matches/transformers/commentary.js +27 -0
  64. package/api/sportal365-sports/football/matches/transformers/commentary.js.map +1 -0
  65. package/api/sportal365-sports/football/matches/transformers/lineup.js +74 -0
  66. package/api/sportal365-sports/football/matches/transformers/lineup.js.map +1 -0
  67. package/api/sportal365-sports/football/matches/transformers/match-event.js +60 -0
  68. package/api/sportal365-sports/football/matches/transformers/match-event.js.map +1 -0
  69. package/api/sportal365-sports/football/matches/transformers/match.js +195 -0
  70. package/api/sportal365-sports/football/matches/transformers/match.js.map +1 -0
  71. package/api/sportal365-sports/football/matches/transformers/odds.js +11 -0
  72. package/api/sportal365-sports/football/matches/transformers/odds.js.map +1 -0
  73. package/api/sportal365-sports/football/matches/transformers/statistics.js +41 -0
  74. package/api/sportal365-sports/football/matches/transformers/statistics.js.map +1 -0
  75. package/api/sportal365-sports/football/search/index.js +42 -0
  76. package/api/sportal365-sports/football/search/index.js.map +1 -0
  77. package/api/sportal365-sports/football/search/search.transformer.js +166 -0
  78. package/api/sportal365-sports/football/search/search.transformer.js.map +1 -0
  79. package/api/sportal365-sports/football/standings/index.js +28 -0
  80. package/api/sportal365-sports/football/standings/index.js.map +1 -0
  81. package/api/sportal365-sports/football/standings/standing.transformer.js +107 -0
  82. package/api/sportal365-sports/football/standings/standing.transformer.js.map +1 -0
  83. package/api/sportal365-sports/football/statistics/index.d.ts +46 -1
  84. package/api/sportal365-sports/football/statistics/index.d.ts.map +1 -1
  85. package/api/sportal365-sports/football/statistics/index.js +154 -0
  86. package/api/sportal365-sports/football/statistics/index.js.map +1 -0
  87. package/api/sportal365-sports/football/statistics/player-career.transformer.d.ts +11 -0
  88. package/api/sportal365-sports/football/statistics/player-career.transformer.d.ts.map +1 -0
  89. package/api/sportal365-sports/football/statistics/player-career.transformer.js +77 -0
  90. package/api/sportal365-sports/football/statistics/player-career.transformer.js.map +1 -0
  91. package/api/sportal365-sports/football/statistics/player-career.types.d.ts +115 -0
  92. package/api/sportal365-sports/football/statistics/player-career.types.d.ts.map +1 -0
  93. package/api/sportal365-sports/football/statistics/player-recent.transformer.d.ts +11 -0
  94. package/api/sportal365-sports/football/statistics/player-recent.transformer.d.ts.map +1 -0
  95. package/api/sportal365-sports/football/statistics/player-recent.transformer.js +54 -0
  96. package/api/sportal365-sports/football/statistics/player-recent.transformer.js.map +1 -0
  97. package/api/sportal365-sports/football/statistics/player-recent.types.d.ts +31 -0
  98. package/api/sportal365-sports/football/statistics/player-recent.types.d.ts.map +1 -0
  99. package/api/sportal365-sports/football/statistics/player-season.transformer.js +147 -0
  100. package/api/sportal365-sports/football/statistics/player-season.transformer.js.map +1 -0
  101. package/api/sportal365-sports/football/teams/index.js +73 -0
  102. package/api/sportal365-sports/football/teams/index.js.map +1 -0
  103. package/api/sportal365-sports/football/teams/utils.js +196 -0
  104. package/api/sportal365-sports/football/teams/utils.js.map +1 -0
  105. package/api/sportal365-sports/http.js +58 -0
  106. package/api/sportal365-sports/http.js.map +1 -0
  107. package/api/sportal365-sports/index.d.ts +2 -2
  108. package/api/sportal365-sports/index.d.ts.map +1 -1
  109. package/api/sportal365-sports/search/http.js +7 -0
  110. package/api/sportal365-sports/search/http.js.map +1 -0
  111. package/api/sportal365-sports/search/index.js +61 -0
  112. package/api/sportal365-sports/search/index.js.map +1 -0
  113. package/api/sportal365-sports/search/search.transformer.js +254 -0
  114. package/api/sportal365-sports/search/search.transformer.js.map +1 -0
  115. package/api/sportal365-sports/shared/odds.transformer.js +65 -0
  116. package/api/sportal365-sports/shared/odds.transformer.js.map +1 -0
  117. package/api/sportal365-sports/shared/providerRef.helper.js +31 -0
  118. package/api/sportal365-sports/shared/providerRef.helper.js.map +1 -0
  119. package/api/sportal365-sports/standings/http.js +7 -0
  120. package/api/sportal365-sports/standings/http.js.map +1 -0
  121. package/api/sportal365-sports/standings/index.js +29 -0
  122. package/api/sportal365-sports/standings/index.js.map +1 -0
  123. package/api/sportal365-sports/standings/standing.transformer.js +185 -0
  124. package/api/sportal365-sports/standings/standing.transformer.js.map +1 -0
  125. package/api/sportal365-sports/statistics/http.js +7 -0
  126. package/api/sportal365-sports/statistics/http.js.map +1 -0
  127. package/api/sportal365-sports/statistics/index.js +25 -0
  128. package/api/sportal365-sports/statistics/index.js.map +1 -0
  129. package/api/sportal365-sports/statistics/team-stats.transformer.js +16 -0
  130. package/api/sportal365-sports/statistics/team-stats.transformer.js.map +1 -0
  131. package/api/sportal365-sports/tennis/http.js +7 -0
  132. package/api/sportal365-sports/tennis/http.js.map +1 -0
  133. package/api/sportal365-sports/tennis/matches/index.js +34 -0
  134. package/api/sportal365-sports/tennis/matches/index.js.map +1 -0
  135. package/api/sportal365-sports/tennis/matches/transformers/match.js +193 -0
  136. package/api/sportal365-sports/tennis/matches/transformers/match.js.map +1 -0
  137. package/cache/cache-manager.js +136 -0
  138. package/cache/cache-manager.js.map +1 -0
  139. package/cache/memory-store.js +29 -0
  140. package/cache/memory-store.js.map +1 -0
  141. package/client.js +38 -12337
  142. package/client.js.map +1 -0
  143. package/config/index.js +20 -0
  144. package/config/index.js.map +1 -0
  145. package/fansunited-data-layer.js +146 -3551
  146. package/fansunited-data-layer.js.map +1 -0
  147. package/helpers/competition.helpers.js +11 -0
  148. package/helpers/competition.helpers.js.map +1 -0
  149. package/helpers/player.helpers.js +165 -0
  150. package/helpers/player.helpers.js.map +1 -0
  151. package/helpers/player.hooks.js +34 -0
  152. package/helpers/player.hooks.js.map +1 -0
  153. package/helpers/team.helpers.js +216 -0
  154. package/helpers/team.helpers.js.map +1 -0
  155. package/index.d.ts +3 -3
  156. package/index.d.ts.map +1 -1
  157. package/package.json +6 -8
  158. package/providers/competition/hooks/useCompetitionStats.js +10 -0
  159. package/providers/competition/hooks/useCompetitionStats.js.map +1 -0
  160. package/providers/competition/hooks/useGoalDistribution.js +23 -0
  161. package/providers/competition/hooks/useGoalDistribution.js.map +1 -0
  162. package/providers/competition/hooks/useMatchHelpers.js +85 -0
  163. package/providers/competition/hooks/useMatchHelpers.js.map +1 -0
  164. package/providers/competition/hooks/useStandingsCalculations.js +89 -0
  165. package/providers/competition/hooks/useStandingsCalculations.js.map +1 -0
  166. package/providers/competition/hooks/useStandingsHelpers.js +61 -0
  167. package/providers/competition/hooks/useStandingsHelpers.js.map +1 -0
  168. package/providers/competition/hooks/useTeamPosition.js +15 -0
  169. package/providers/competition/hooks/useTeamPosition.js.map +1 -0
  170. package/providers/competition/hooks/useTeamResultsTable.js +86 -0
  171. package/providers/competition/hooks/useTeamResultsTable.js.map +1 -0
  172. package/providers/competition/utils/competitionStats.js +109 -0
  173. package/providers/competition/utils/competitionStats.js.map +1 -0
  174. package/providers/competition/utils/goalDistribution.js +64 -0
  175. package/providers/competition/utils/goalDistribution.js.map +1 -0
  176. package/providers/competition/utils/standingsCalculations.js +152 -0
  177. package/providers/competition/utils/standingsCalculations.js.map +1 -0
  178. package/providers/competition.context.js +14 -0
  179. package/providers/competition.context.js.map +1 -0
  180. package/providers/competition.provider.js +187 -0
  181. package/providers/competition.provider.js.map +1 -0
  182. package/providers/fansunited-config.context.js +6 -0
  183. package/providers/fansunited-config.context.js.map +1 -0
  184. package/providers/fansunited-config.hooks.js +20 -0
  185. package/providers/fansunited-config.hooks.js.map +1 -0
  186. package/providers/fansunited-config.provider.js +9 -0
  187. package/providers/fansunited-config.provider.js.map +1 -0
  188. package/providers/fansunited-sdk.hook.js +50 -0
  189. package/providers/fansunited-sdk.hook.js.map +1 -0
  190. package/providers/leaderboard/hooks/useMatchHelpers.js +30 -0
  191. package/providers/leaderboard/hooks/useMatchHelpers.js.map +1 -0
  192. package/providers/leaderboard/hooks/useTemplateHelpers.js +39 -0
  193. package/providers/leaderboard/hooks/useTemplateHelpers.js.map +1 -0
  194. package/providers/leaderboard.context.js +14 -0
  195. package/providers/leaderboard.context.js.map +1 -0
  196. package/providers/leaderboard.provider.js +98 -0
  197. package/providers/leaderboard.provider.js.map +1 -0
  198. package/providers/match/hooks/useBatchMatchOdds.js +72 -0
  199. package/providers/match/hooks/useBatchMatchOdds.js.map +1 -0
  200. package/providers/match/hooks/useEventHelpers.js +46 -0
  201. package/providers/match/hooks/useEventHelpers.js.map +1 -0
  202. package/providers/match/hooks/useHeadToHeadHelpers.js +52 -0
  203. package/providers/match/hooks/useHeadToHeadHelpers.js.map +1 -0
  204. package/providers/match/hooks/useLineupHelpers.js +53 -0
  205. package/providers/match/hooks/useLineupHelpers.js.map +1 -0
  206. package/providers/match/hooks/useMatchStandingsCalculations.js +332 -0
  207. package/providers/match/hooks/useMatchStandingsCalculations.js.map +1 -0
  208. package/providers/match/hooks/useMatchStatus.js +37 -0
  209. package/providers/match/hooks/useMatchStatus.js.map +1 -0
  210. package/providers/match/hooks/useOddsHelpers.js +54 -0
  211. package/providers/match/hooks/useOddsHelpers.js.map +1 -0
  212. package/providers/match/hooks/useScoreHelpers.js +34 -0
  213. package/providers/match/hooks/useScoreHelpers.js.map +1 -0
  214. package/providers/match/hooks/useStandingsHelpers.js +53 -0
  215. package/providers/match/hooks/useStandingsHelpers.js.map +1 -0
  216. package/providers/match/hooks/useStatisticsHelpers.js +40 -0
  217. package/providers/match/hooks/useStatisticsHelpers.js.map +1 -0
  218. package/providers/match/hooks/useTeamHelpers.js +38 -0
  219. package/providers/match/hooks/useTeamHelpers.js.map +1 -0
  220. package/providers/match/hooks/useTeamStatsHelpers.js +141 -0
  221. package/providers/match/hooks/useTeamStatsHelpers.js.map +1 -0
  222. package/providers/match.context.js +14 -0
  223. package/providers/match.context.js.map +1 -0
  224. package/providers/match.provider.js +176 -0
  225. package/providers/match.provider.js.map +1 -0
  226. package/providers/team/hooks/useFormStats.js +116 -0
  227. package/providers/team/hooks/useFormStats.js.map +1 -0
  228. package/providers/team/hooks/useMatchHelpers.js +46 -0
  229. package/providers/team/hooks/useMatchHelpers.js.map +1 -0
  230. package/providers/team/hooks/useSquadHelpers.js +67 -0
  231. package/providers/team/hooks/useSquadHelpers.js.map +1 -0
  232. package/providers/team.context.js +14 -0
  233. package/providers/team.context.js.map +1 -0
  234. package/providers/team.provider.js +98 -0
  235. package/providers/team.provider.js.map +1 -0
  236. package/types/canonical/index.d.ts +1 -1
  237. package/types/canonical/index.d.ts.map +1 -1
  238. package/types/canonical/statistics.types.d.ts +102 -0
  239. package/types/canonical/statistics.types.d.ts.map +1 -1
  240. package/utilities/stats/core/helpers.js +105 -0
  241. package/utilities/stats/core/helpers.js.map +1 -0
  242. package/utilities/stats/core/types.js +5 -0
  243. package/utilities/stats/core/types.js.map +1 -0
  244. package/utilities/stats/match/headToHead.js +83 -0
  245. package/utilities/stats/match/headToHead.js.map +1 -0
  246. package/utilities/stats/match/homeVsAway.js +140 -0
  247. package/utilities/stats/match/homeVsAway.js.map +1 -0
  248. package/utilities/stats/match/overUnder.js +91 -0
  249. package/utilities/stats/match/overUnder.js.map +1 -0
  250. package/utilities/stats/match/result.js +21 -0
  251. package/utilities/stats/match/result.js.map +1 -0
  252. package/utilities/stats/team/commonOpponents.js +77 -0
  253. package/utilities/stats/team/commonOpponents.js.map +1 -0
  254. package/utilities/stats/team/goalStats.js +50 -0
  255. package/utilities/stats/team/goalStats.js.map +1 -0
  256. package/utilities/stats/team/streaks.js +183 -0
  257. package/utilities/stats/team/streaks.js.map +1 -0
  258. package/client.cjs +0 -8
  259. package/fansunited-data-layer.cjs +0 -1
  260. package/matches-CB-dSXEA.js +0 -1633
  261. 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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"}