mlb 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -1
  3. data/LICENSE.txt +1 -1
  4. data/README.md +329 -32
  5. data/lib/mlb/affiliates.rb +28 -0
  6. data/lib/mlb/alumni.rb +30 -0
  7. data/lib/mlb/attendance.rb +28 -0
  8. data/lib/mlb/attendance_record.rb +157 -0
  9. data/lib/mlb/award.rb +126 -0
  10. data/lib/mlb/awards.rb +32 -0
  11. data/lib/mlb/baseball_stat.rb +65 -0
  12. data/lib/mlb/baseball_stats.rb +12 -0
  13. data/lib/mlb/boxscore.rb +81 -0
  14. data/lib/mlb/boxscore_team_stats.rb +210 -0
  15. data/lib/mlb/client.rb +71 -1
  16. data/lib/mlb/coaches.rb +28 -0
  17. data/lib/mlb/code_description_type.rb +45 -0
  18. data/lib/mlb/collection.rb +48 -0
  19. data/lib/mlb/comparable_by_attribute.rb +56 -0
  20. data/lib/mlb/conference.rb +39 -0
  21. data/lib/mlb/conferences.rb +33 -0
  22. data/lib/mlb/connection.rb +130 -7
  23. data/lib/mlb/context_metrics.rb +90 -0
  24. data/lib/mlb/division.rb +26 -6
  25. data/lib/mlb/divisions.rb +24 -18
  26. data/lib/mlb/draft.rb +83 -0
  27. data/lib/mlb/draft_pick.rb +155 -0
  28. data/lib/mlb/error_handler.rb +21 -1
  29. data/lib/mlb/errors/bad_gateway.rb +6 -1
  30. data/lib/mlb/errors/bad_request.rb +1 -0
  31. data/lib/mlb/errors/client_error.rb +1 -0
  32. data/lib/mlb/errors/connection_exception.rb +1 -0
  33. data/lib/mlb/errors/error.rb +1 -0
  34. data/lib/mlb/errors/forbidden.rb +1 -0
  35. data/lib/mlb/errors/gateway_timeout.rb +6 -1
  36. data/lib/mlb/errors/gone.rb +1 -0
  37. data/lib/mlb/errors/http_error.rb +22 -2
  38. data/lib/mlb/errors/internal_server_error.rb +1 -0
  39. data/lib/mlb/errors/network_error.rb +6 -1
  40. data/lib/mlb/errors/not_acceptable.rb +1 -0
  41. data/lib/mlb/errors/not_found.rb +1 -0
  42. data/lib/mlb/errors/payload_too_large.rb +1 -0
  43. data/lib/mlb/errors/retryable.rb +15 -0
  44. data/lib/mlb/errors/server_error.rb +1 -0
  45. data/lib/mlb/errors/service_unavailable.rb +6 -1
  46. data/lib/mlb/errors/too_many_redirects.rb +1 -0
  47. data/lib/mlb/errors/too_many_requests.rb +6 -1
  48. data/lib/mlb/errors/unauthorized.rb +1 -0
  49. data/lib/mlb/errors/unprocessable_entity.rb +1 -0
  50. data/lib/mlb/event_type.rb +61 -0
  51. data/lib/mlb/event_types.rb +12 -0
  52. data/lib/mlb/free_agent.rb +78 -0
  53. data/lib/mlb/free_agents.rb +34 -0
  54. data/lib/mlb/game_changes.rb +87 -0
  55. data/lib/mlb/game_content.rb +251 -0
  56. data/lib/mlb/game_data.rb +155 -0
  57. data/lib/mlb/game_pace.rb +173 -0
  58. data/lib/mlb/game_status.rb +94 -0
  59. data/lib/mlb/game_statuses.rb +12 -0
  60. data/lib/mlb/game_type.rb +98 -0
  61. data/lib/mlb/game_types.rb +12 -0
  62. data/lib/mlb/handedness.rb +30 -9
  63. data/lib/mlb/high_low.rb +121 -0
  64. data/lib/mlb/hit_trajectories.rb +12 -0
  65. data/lib/mlb/hit_trajectory.rb +6 -0
  66. data/lib/mlb/home_run_derby.rb +285 -0
  67. data/lib/mlb/id_description_type.rb +44 -0
  68. data/lib/mlb/inning_score.rb +87 -0
  69. data/lib/mlb/job.rb +58 -0
  70. data/lib/mlb/job_type.rb +39 -0
  71. data/lib/mlb/job_types.rb +12 -0
  72. data/lib/mlb/jobs.rb +87 -0
  73. data/lib/mlb/language.rb +48 -0
  74. data/lib/mlb/languages.rb +12 -0
  75. data/lib/mlb/leader.rb +79 -0
  76. data/lib/mlb/leaders.rb +68 -0
  77. data/lib/mlb/league.rb +97 -14
  78. data/lib/mlb/league_leader_type.rb +21 -0
  79. data/lib/mlb/league_leader_types.rb +12 -0
  80. data/lib/mlb/leagues.rb +24 -18
  81. data/lib/mlb/linescore.rb +342 -0
  82. data/lib/mlb/linescore_teams.rb +89 -0
  83. data/lib/mlb/live_feed.rb +130 -0
  84. data/lib/mlb/logical_event.rb +17 -0
  85. data/lib/mlb/logical_events.rb +12 -0
  86. data/lib/mlb/metric.rb +48 -0
  87. data/lib/mlb/metrics.rb +12 -0
  88. data/lib/mlb/people_changes.rb +34 -0
  89. data/lib/mlb/personnel.rb +28 -0
  90. data/lib/mlb/pitch_code.rb +90 -0
  91. data/lib/mlb/pitch_codes.rb +12 -0
  92. data/lib/mlb/pitch_type.rb +6 -0
  93. data/lib/mlb/pitch_types.rb +12 -0
  94. data/lib/mlb/platform.rb +30 -0
  95. data/lib/mlb/platforms.rb +12 -0
  96. data/lib/mlb/play.rb +300 -0
  97. data/lib/mlb/play_by_play.rb +52 -0
  98. data/lib/mlb/player.rb +186 -0
  99. data/lib/mlb/player_game_stats.rb +350 -0
  100. data/lib/mlb/player_stat.rb +70 -0
  101. data/lib/mlb/players.rb +42 -11
  102. data/lib/mlb/position.rb +68 -0
  103. data/lib/mlb/positions.rb +12 -0
  104. data/lib/mlb/postseason_schedule.rb +41 -0
  105. data/lib/mlb/postseason_series.rb +54 -0
  106. data/lib/mlb/redirect_handler.rb +80 -21
  107. data/lib/mlb/request_builder.rb +33 -2
  108. data/lib/mlb/review_reason.rb +6 -0
  109. data/lib/mlb/review_reasons.rb +12 -0
  110. data/lib/mlb/roster.rb +16 -12
  111. data/lib/mlb/roster_entry.rb +38 -0
  112. data/lib/mlb/roster_type.rb +39 -0
  113. data/lib/mlb/roster_types.rb +12 -0
  114. data/lib/mlb/schedule.rb +33 -0
  115. data/lib/mlb/schedule_date.rb +37 -0
  116. data/lib/mlb/schedule_event_type.rb +25 -0
  117. data/lib/mlb/schedule_event_types.rb +12 -0
  118. data/lib/mlb/scheduled_game.rb +321 -0
  119. data/lib/mlb/season.rb +74 -0
  120. data/lib/mlb/season_date_info.rb +4 -0
  121. data/lib/mlb/seasons.rb +36 -0
  122. data/lib/mlb/single_team_stats.rb +33 -0
  123. data/lib/mlb/situation_code.rb +116 -0
  124. data/lib/mlb/situation_codes.rb +12 -0
  125. data/lib/mlb/skies.rb +12 -0
  126. data/lib/mlb/sky.rb +6 -0
  127. data/lib/mlb/sport.rb +18 -5
  128. data/lib/mlb/sport_players.rb +30 -0
  129. data/lib/mlb/sports.rb +17 -7
  130. data/lib/mlb/standings.rb +47 -0
  131. data/lib/mlb/standings_record.rb +108 -0
  132. data/lib/mlb/standings_type.rb +25 -0
  133. data/lib/mlb/standings_types.rb +12 -0
  134. data/lib/mlb/stat_group.rb +21 -0
  135. data/lib/mlb/stat_groups.rb +12 -0
  136. data/lib/mlb/stat_type.rb +21 -0
  137. data/lib/mlb/stat_types.rb +12 -0
  138. data/lib/mlb/stat_values.rb +158 -0
  139. data/lib/mlb/stats.rb +41 -0
  140. data/lib/mlb/status.rb +17 -0
  141. data/lib/mlb/streaks.rb +184 -0
  142. data/lib/mlb/team.rb +66 -7
  143. data/lib/mlb/team_history.rb +28 -0
  144. data/lib/mlb/team_leader.rb +59 -0
  145. data/lib/mlb/team_leaders.rb +45 -0
  146. data/lib/mlb/team_record.rb +285 -0
  147. data/lib/mlb/team_stat.rb +50 -0
  148. data/lib/mlb/team_stats.rb +52 -0
  149. data/lib/mlb/teams.rb +28 -18
  150. data/lib/mlb/tied_games.rb +32 -0
  151. data/lib/mlb/transaction.rb +128 -0
  152. data/lib/mlb/transactions.rb +11 -6
  153. data/lib/mlb/uniforms.rb +97 -0
  154. data/lib/mlb/utils.rb +45 -0
  155. data/lib/mlb/venue.rb +10 -0
  156. data/lib/mlb/venues.rb +28 -18
  157. data/lib/mlb/version.rb +2 -1
  158. data/lib/mlb/win_probability.rb +64 -0
  159. data/lib/mlb/wind_direction.rb +6 -0
  160. data/lib/mlb/wind_directions.rb +12 -0
  161. data/lib/mlb.rb +64 -0
  162. data/sig/equalizer.rbs +3 -0
  163. data/sig/mlb.rbs +1972 -103
  164. data/sig/shale.rbs +29 -0
  165. metadata +137 -14
@@ -0,0 +1,184 @@
1
+ require "shale"
2
+ require_relative "player"
3
+ require_relative "team"
4
+
5
+ module MLB
6
+ # Represents a player's active streak (hitting streak, on-base streak, etc.)
7
+ class PlayerStreak < Shale::Mapper
8
+ include Equalizer.new(:player_id, :streak_type, :current_streak)
9
+
10
+ STREAK_HITTING = "hittingStreak".freeze
11
+ STREAK_ON_BASE = "onBaseStreak".freeze
12
+
13
+ # @!attribute [rw] player_id
14
+ # Returns the player ID
15
+ # @api public
16
+ # @example
17
+ # streak.player_id #=> 660271
18
+ # @return [Integer] the player ID
19
+ attribute :player_id, Shale::Type::Integer
20
+
21
+ # @!attribute [rw] player_name
22
+ # Returns the player name
23
+ # @api public
24
+ # @example
25
+ # streak.player_name #=> "Shohei Ohtani"
26
+ # @return [String] the player name
27
+ attribute :player_name, Shale::Type::String
28
+
29
+ # @!attribute [rw] streak_type
30
+ # Returns the streak type
31
+ # @api public
32
+ # @example
33
+ # streak.streak_type #=> "hittingStreak"
34
+ # @return [String] the streak type
35
+ attribute :streak_type, Shale::Type::String
36
+
37
+ # @!attribute [rw] current_streak
38
+ # Returns the current streak length
39
+ # @api public
40
+ # @example
41
+ # streak.current_streak #=> 15
42
+ # @return [Integer] the current streak
43
+ attribute :current_streak, Shale::Type::Integer
44
+
45
+ # @!attribute [rw] current_streak_stat
46
+ # Returns the stat during the streak
47
+ # @api public
48
+ # @example
49
+ # streak.current_streak_stat #=> "20-for-58"
50
+ # @return [String] the streak stat
51
+ attribute :current_streak_stat, Shale::Type::String
52
+
53
+ # @!attribute [rw] team
54
+ # Returns the player's team
55
+ # @api public
56
+ # @example
57
+ # streak.team #=> #<MLB::Team>
58
+ # @return [Team] the team
59
+ attribute :team, Team
60
+
61
+ # Returns whether this is a hitting streak
62
+ #
63
+ # @api public
64
+ # @example
65
+ # streak.hitting_streak? #=> true
66
+ # @return [Boolean] whether this is a hitting streak
67
+ def hitting_streak? = streak_type.eql?(STREAK_HITTING)
68
+
69
+ # Returns whether this is an on-base streak
70
+ #
71
+ # @api public
72
+ # @example
73
+ # streak.on_base_streak? #=> false
74
+ # @return [Boolean] whether this is an on-base streak
75
+ def on_base_streak? = streak_type.eql?(STREAK_ON_BASE)
76
+
77
+ json do
78
+ map "playerId", to: :player_id
79
+ map "playerName", to: :player_name
80
+ map "streakType", to: :streak_type
81
+ map "currentStreak", to: :current_streak
82
+ map "currentStreakStat", to: :current_streak_stat
83
+ map "team", to: :team
84
+ end
85
+ end
86
+
87
+ # Represents a streaks category
88
+ class StreakCategory < Shale::Mapper
89
+ CATEGORY_HITTING = "hittingStreak".freeze
90
+ CATEGORY_ON_BASE = "onBaseStreak".freeze
91
+
92
+ # @!attribute [rw] category_type
93
+ # Returns the streak category type
94
+ # @api public
95
+ # @example
96
+ # category.category_type #=> "hittingStreak"
97
+ # @return [String] the category type
98
+ attribute :category_type, Shale::Type::String
99
+
100
+ # @!attribute [rw] streaks
101
+ # Returns the streaks
102
+ # @api public
103
+ # @example
104
+ # category.streaks #=> [#<MLB::PlayerStreak>, ...]
105
+ # @return [Array<PlayerStreak>] the streaks
106
+ attribute :streaks, PlayerStreak, collection: true
107
+
108
+ # Returns whether this is a hitting streak category
109
+ #
110
+ # @api public
111
+ # @example
112
+ # category.hitting_streak? #=> true
113
+ # @return [Boolean] whether this is a hitting streak category
114
+ def hitting_streak? = category_type.eql?(CATEGORY_HITTING)
115
+
116
+ # Returns whether this is an on-base streak category
117
+ #
118
+ # @api public
119
+ # @example
120
+ # category.on_base_streak? #=> false
121
+ # @return [Boolean] whether this is an on-base streak category
122
+ def on_base_streak? = category_type.eql?(CATEGORY_ON_BASE)
123
+
124
+ json do
125
+ map "streakType", to: :category_type
126
+ map "streaks", to: :streaks
127
+ end
128
+ end
129
+
130
+ # Provides methods for fetching streak data from the API
131
+ class Streaks < Shale::Mapper
132
+ # @!attribute [rw] streak_stats
133
+ # Returns the streak categories
134
+ # @api public
135
+ # @example
136
+ # streaks.streak_stats #=> [#<MLB::StreakCategory>, ...]
137
+ # @return [Array<StreakCategory>] the streak categories
138
+ attribute :streak_stats, StreakCategory, collection: true
139
+
140
+ json do
141
+ map "streakStats", to: :streak_stats
142
+ end
143
+
144
+ # Retrieves hitting streaks
145
+ #
146
+ # @api public
147
+ # @example Get current hitting streaks
148
+ # MLB::Streaks.hitting(season: 2024)
149
+ # @param season [Integer, nil] the season year (defaults to current year)
150
+ # @param limit [Integer] the maximum number of results (defaults to 10)
151
+ # @return [Array<PlayerStreak>] the hitting streaks
152
+ def self.hitting(season: nil, limit: 10)
153
+ find(streak_type: "hittingStreak", season:, limit:)
154
+ end
155
+
156
+ # Retrieves on-base streaks
157
+ #
158
+ # @api public
159
+ # @example Get current on-base streaks
160
+ # MLB::Streaks.on_base(season: 2024)
161
+ # @param season [Integer, nil] the season year (defaults to current year)
162
+ # @param limit [Integer] the maximum number of results (defaults to 10)
163
+ # @return [Array<PlayerStreak>] the on-base streaks
164
+ def self.on_base(season: nil, limit: 10)
165
+ find(streak_type: "onBaseStreak", season:, limit:)
166
+ end
167
+
168
+ # Retrieves streaks by type
169
+ #
170
+ # @api public
171
+ # @example Get hitting streaks
172
+ # MLB::Streaks.find(streak_type: "hittingStreak", season: 2024)
173
+ # @param streak_type [String] the streak type
174
+ # @param season [Integer, nil] the season year (defaults to current year)
175
+ # @param limit [Integer] the maximum number of results (defaults to 10)
176
+ # @return [Array<PlayerStreak>] the streaks
177
+ def self.find(streak_type:, season: nil, limit: 10)
178
+ season ||= Utils.current_season
179
+ params = {streakType: streak_type, season:, limit:}
180
+ response = CLIENT.get("stats/streaks?#{Utils.build_query(params)}")
181
+ from_json(response).streak_stats.first&.streaks || []
182
+ end
183
+ end
184
+ end
data/lib/mlb/team.rb CHANGED
@@ -1,14 +1,54 @@
1
+ require "equalizer"
1
2
  require "shale"
2
3
  require_relative "division"
3
4
  require_relative "league"
4
5
  require_relative "sport"
5
6
  require_relative "venue"
6
7
 
8
+ # Ruby interface to the MLB Stats API
7
9
  module MLB
10
+ # Represents a team
8
11
  class Team < Shale::Mapper
12
+ include Equalizer.new(:id)
13
+
14
+ ALL_STAR_YES = "Y".freeze
15
+ ALL_STAR_NO = "N".freeze
16
+
17
+ # Team ID constants
18
+ AZ = 109
19
+ ATH = 133
20
+ ATL = 144
21
+ BAL = 110
22
+ BOS = 111
23
+ CHC = 112
24
+ CWS = 145
25
+ CIN = 113
26
+ CLE = 114
27
+ COL = 115
28
+ DET = 116
29
+ HOU = 117
30
+ KC = 118
31
+ LAA = 108
32
+ LAD = 119
33
+ MIA = 146
34
+ MIL = 158
35
+ MIN = 142
36
+ NYM = 121
37
+ NYY = 147
38
+ PHI = 143
39
+ PIT = 134
40
+ SD = 135
41
+ SF = 137
42
+ SEA = 136
43
+ STL = 138
44
+ TB = 139
45
+ TEX = 140
46
+ TOR = 141
47
+ WSH = 120
48
+
49
+ attribute :id, Shale::Type::Integer
9
50
  attribute :spring_league, League
10
51
  attribute :all_star_status, Shale::Type::String
11
- attribute :id, Shale::Type::Integer
12
52
  attribute :name, Shale::Type::String
13
53
  attribute :link, Shale::Type::String
14
54
  attribute :season, Shale::Type::Integer
@@ -28,8 +68,22 @@ module MLB
28
68
  attribute :club_name, Shale::Type::String
29
69
  attribute :active, Shale::Type::Boolean
30
70
 
71
+ # Returns whether the team is active
72
+ #
73
+ # @api public
74
+ # @example
75
+ # team.active?
76
+ # @return [Boolean, nil] true if the team is active
31
77
  alias_method :active?, :active
32
78
 
79
+ # Returns whether this is an All-Star team
80
+ #
81
+ # @api public
82
+ # @example
83
+ # team.all_star? #=> false
84
+ # @return [Boolean] whether this is an All-Star team
85
+ def all_star? = all_star_status.eql?(ALL_STAR_YES)
86
+
33
87
  json do
34
88
  map "springLeague", to: :spring_league
35
89
  map "allStarStatus", to: :all_star_status
@@ -54,12 +108,17 @@ module MLB
54
108
  map "active", to: :active
55
109
  end
56
110
 
57
- def roster(season: Time.now.year)
58
- params = {season:}
59
- query_string = URI.encode_www_form(params)
60
- response = CLIENT.get("teams/#{id}/roster?#{query_string}")
61
- roster = Roster.from_json(response)
62
- roster.roster
111
+ # Retrieves the team's roster
112
+ #
113
+ # @api public
114
+ # @example
115
+ # team.roster
116
+ # @param season [Integer, nil] the season year (defaults to current year)
117
+ # @return [Array<RosterEntry>] list of roster entries
118
+ def roster(season: nil)
119
+ season ||= Utils.current_season
120
+ response = CLIENT.get("teams/#{id}/roster?#{Utils.build_query(season:)}")
121
+ Roster.from_json(response).roster
63
122
  end
64
123
  end
65
124
  end
@@ -0,0 +1,28 @@
1
+ require "shale"
2
+ require_relative "team"
3
+
4
+ module MLB
5
+ # Provides methods for fetching team history from the API
6
+ class TeamHistory < Shale::Mapper
7
+ attribute :teams, Team, collection: true
8
+
9
+ json do
10
+ map "teams", to: :teams
11
+ end
12
+
13
+ # Retrieves historical team records
14
+ #
15
+ # @api public
16
+ # @example Get history for a team
17
+ # MLB::TeamHistory.find(team: 147)
18
+ # @example Get history for a team object
19
+ # MLB::TeamHistory.find(team: Team.new(id: 147))
20
+ # @param team [Integer, Team] the team ID or Team object
21
+ # @return [Array<Team>] historical team records
22
+ def self.find(team:)
23
+ params = {teamIds: Utils.extract_id(team)}
24
+ response = CLIENT.get("teams/history?#{Utils.build_query(params)}")
25
+ from_json(response).teams
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,59 @@
1
+ require "equalizer"
2
+ require "shale"
3
+ require_relative "player"
4
+ require_relative "team"
5
+
6
+ module MLB
7
+ # Represents a team leader entry
8
+ class TeamLeader < Shale::Mapper
9
+ include Equalizer.new(:rank, :person)
10
+
11
+ # @!attribute [rw] rank
12
+ # Returns the leader's rank
13
+ # @api public
14
+ # @example
15
+ # leader.rank #=> 1
16
+ # @return [Integer] the rank
17
+ attribute :rank, Shale::Type::Integer
18
+
19
+ # @!attribute [rw] value
20
+ # Returns the stat value
21
+ # @api public
22
+ # @example
23
+ # leader.value #=> "58"
24
+ # @return [String] the stat value
25
+ attribute :value, Shale::Type::String
26
+
27
+ # @!attribute [rw] person
28
+ # Returns the player
29
+ # @api public
30
+ # @example
31
+ # leader.person #=> #<MLB::Player>
32
+ # @return [Player] the player
33
+ attribute :person, Player
34
+
35
+ # @!attribute [rw] team
36
+ # Returns the team
37
+ # @api public
38
+ # @example
39
+ # leader.team #=> #<MLB::Team>
40
+ # @return [Team] the team
41
+ attribute :team, Team
42
+
43
+ # @!attribute [rw] season
44
+ # Returns the season
45
+ # @api public
46
+ # @example
47
+ # leader.season #=> "2024"
48
+ # @return [String] the season
49
+ attribute :season, Shale::Type::String
50
+
51
+ json do
52
+ map "rank", to: :rank
53
+ map "value", to: :value
54
+ map "person", to: :person
55
+ map "team", to: :team
56
+ map "season", to: :season
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,45 @@
1
+ require "shale"
2
+ require_relative "team_leader"
3
+
4
+ module MLB
5
+ # Represents a team leader category
6
+ class TeamLeaderCategory < Shale::Mapper
7
+ attribute :leader_category, Shale::Type::String
8
+ attribute :season, Shale::Type::String
9
+ attribute :leaders, TeamLeader, collection: true
10
+
11
+ json do
12
+ map "leaderCategory", to: :leader_category
13
+ map "season", to: :season
14
+ map "leaders", to: :leaders
15
+ end
16
+ end
17
+
18
+ # Provides methods for fetching team leaders from the API
19
+ class TeamLeaders < Shale::Mapper
20
+ attribute :team_leaders, TeamLeaderCategory, collection: true
21
+
22
+ json do
23
+ map "teamLeaders", to: :team_leaders
24
+ end
25
+
26
+ # Retrieves team leaders for a category
27
+ #
28
+ # @api public
29
+ # @example Get team leaders for home runs
30
+ # MLB::TeamLeaders.find(team: 147, category: "homeRuns", season: 2024)
31
+ # @example Get team leaders with a team object
32
+ # MLB::TeamLeaders.find(team: Team.new(id: 147), category: "homeRuns")
33
+ # @param team [Integer, Team] the team ID or Team object
34
+ # @param category [String] the leader category
35
+ # @param season [Integer, nil] the season year (defaults to current year)
36
+ # @return [Array<TeamLeader>] the team leaders
37
+ def self.find(team:, category:, season: nil)
38
+ season ||= Utils.current_season
39
+ team_id = Utils.extract_id(team)
40
+ params = {leaderCategories: category, season:}
41
+ response = CLIENT.get("teams/#{team_id}/leaders?#{Utils.build_query(params)}")
42
+ from_json(response).team_leaders.first&.leaders || []
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,285 @@
1
+ require "equalizer"
2
+ require "shale"
3
+ require_relative "team"
4
+
5
+ module MLB
6
+ # Represents a team's league record (wins/losses)
7
+ class LeagueRecord < Shale::Mapper
8
+ # @!attribute [rw] wins
9
+ # Returns the number of wins
10
+ # @api public
11
+ # @example
12
+ # league_record.wins #=> 94
13
+ # @return [Integer] the number of wins
14
+ attribute :wins, Shale::Type::Integer
15
+
16
+ # @!attribute [rw] losses
17
+ # Returns the number of losses
18
+ # @api public
19
+ # @example
20
+ # league_record.losses #=> 68
21
+ # @return [Integer] the number of losses
22
+ attribute :losses, Shale::Type::Integer
23
+
24
+ # @!attribute [rw] ties
25
+ # Returns the number of ties
26
+ # @api public
27
+ # @example
28
+ # league_record.ties #=> 0
29
+ # @return [Integer] the number of ties
30
+ attribute :ties, Shale::Type::Integer
31
+
32
+ # @!attribute [rw] pct
33
+ # Returns the winning percentage
34
+ # @api public
35
+ # @example
36
+ # league_record.pct #=> ".580"
37
+ # @return [String] the winning percentage
38
+ attribute :pct, Shale::Type::String
39
+ end
40
+
41
+ # Represents a team's streak information
42
+ class Streak < Shale::Mapper
43
+ # @!attribute [rw] streak_code
44
+ # Returns the streak code
45
+ # @api public
46
+ # @example
47
+ # streak.streak_code #=> "W3"
48
+ # @return [String] the streak code
49
+ attribute :streak_code, Shale::Type::String
50
+
51
+ # @!attribute [rw] streak_type
52
+ # Returns the streak type
53
+ # @api public
54
+ # @example
55
+ # streak.streak_type #=> "wins"
56
+ # @return [String] the streak type
57
+ attribute :streak_type, Shale::Type::String
58
+
59
+ # @!attribute [rw] streak_number
60
+ # Returns the streak length
61
+ # @api public
62
+ # @example
63
+ # streak.streak_number #=> 3
64
+ # @return [Integer] the streak length
65
+ attribute :streak_number, Shale::Type::Integer
66
+
67
+ # Winning streak type value
68
+ WINS = "wins".freeze
69
+ # Losing streak type value
70
+ LOSSES = "losses".freeze
71
+
72
+ # Returns whether this is a winning streak
73
+ #
74
+ # @api public
75
+ # @example
76
+ # streak.winning? #=> true
77
+ # @return [Boolean] true if this is a winning streak
78
+ def winning? = streak_type.eql?(WINS)
79
+
80
+ # Returns whether this is a losing streak
81
+ #
82
+ # @api public
83
+ # @example
84
+ # streak.losing? #=> false
85
+ # @return [Boolean] true if this is a losing streak
86
+ def losing? = streak_type.eql?(LOSSES)
87
+
88
+ json do
89
+ map "streakCode", to: :streak_code
90
+ map "streakType", to: :streak_type
91
+ map "streakNumber", to: :streak_number
92
+ end
93
+ end
94
+
95
+ # Represents a team's record in the standings
96
+ class TeamRecord < Shale::Mapper
97
+ include Equalizer.new(:team)
98
+
99
+ # @!attribute [rw] team
100
+ # Returns the team
101
+ # @api public
102
+ # @example
103
+ # team_record.team #=> #<MLB::Team>
104
+ # @return [Team] the team
105
+ attribute :team, Team
106
+
107
+ # @!attribute [rw] season
108
+ # Returns the season year
109
+ # @api public
110
+ # @example
111
+ # team_record.season #=> "2024"
112
+ # @return [String] the season year
113
+ attribute :season, Shale::Type::String
114
+
115
+ # @!attribute [rw] streak
116
+ # Returns the current streak
117
+ # @api public
118
+ # @example
119
+ # team_record.streak #=> #<MLB::Streak>
120
+ # @return [Streak] the current streak
121
+ attribute :streak, Streak
122
+
123
+ # @!attribute [rw] division_rank
124
+ # Returns the division rank
125
+ # @api public
126
+ # @example
127
+ # team_record.division_rank #=> "1"
128
+ # @return [String] the division rank
129
+ attribute :division_rank, Shale::Type::String
130
+
131
+ # @!attribute [rw] league_rank
132
+ # Returns the league rank
133
+ # @api public
134
+ # @example
135
+ # team_record.league_rank #=> "1"
136
+ # @return [String] the league rank
137
+ attribute :league_rank, Shale::Type::String
138
+
139
+ attribute :wildcard_rank, Shale::Type::String
140
+
141
+ # @!attribute [rw] games_played
142
+ # Returns the number of games played
143
+ # @api public
144
+ # @example
145
+ # team_record.games_played #=> 162
146
+ # @return [Integer] the number of games played
147
+ attribute :games_played, Shale::Type::Integer
148
+
149
+ # @!attribute [rw] games_back
150
+ # Returns games behind the division leader
151
+ # @api public
152
+ # @example
153
+ # team_record.games_back #=> "3.0"
154
+ # @return [String] games behind the division leader
155
+ attribute :games_back, Shale::Type::String
156
+
157
+ attribute :wildcard_games_back, Shale::Type::String
158
+
159
+ # @!attribute [rw] league_record
160
+ # Returns the league record
161
+ # @api public
162
+ # @example
163
+ # team_record.league_record #=> #<MLB::LeagueRecord>
164
+ # @return [LeagueRecord] the league record
165
+ attribute :league_record, LeagueRecord
166
+
167
+ # @!attribute [rw] wins
168
+ # Returns the number of wins
169
+ # @api public
170
+ # @example
171
+ # team_record.wins #=> 94
172
+ # @return [Integer] the number of wins
173
+ attribute :wins, Shale::Type::Integer
174
+
175
+ # @!attribute [rw] losses
176
+ # Returns the number of losses
177
+ # @api public
178
+ # @example
179
+ # team_record.losses #=> 68
180
+ # @return [Integer] the number of losses
181
+ attribute :losses, Shale::Type::Integer
182
+
183
+ # @!attribute [rw] runs_scored
184
+ # Returns the runs scored
185
+ # @api public
186
+ # @example
187
+ # team_record.runs_scored #=> 815
188
+ # @return [Integer] the runs scored
189
+ attribute :runs_scored, Shale::Type::Integer
190
+
191
+ # @!attribute [rw] runs_allowed
192
+ # Returns the runs allowed
193
+ # @api public
194
+ # @example
195
+ # team_record.runs_allowed #=> 668
196
+ # @return [Integer] the runs allowed
197
+ attribute :runs_allowed, Shale::Type::Integer
198
+
199
+ # @!attribute [rw] run_differential
200
+ # Returns the run differential
201
+ # @api public
202
+ # @example
203
+ # team_record.run_differential #=> 147
204
+ # @return [Integer] the run differential
205
+ attribute :run_differential, Shale::Type::Integer
206
+
207
+ # @!attribute [rw] winning_percentage
208
+ # Returns the winning percentage
209
+ # @api public
210
+ # @example
211
+ # team_record.winning_percentage #=> ".580"
212
+ # @return [String] the winning percentage
213
+ attribute :winning_percentage, Shale::Type::String
214
+
215
+ # @!attribute [rw] division_champ
216
+ # Returns whether the team is a division champion
217
+ # @api public
218
+ # @example
219
+ # team_record.division_champ #=> true
220
+ # @return [Boolean] whether the team is a division champion
221
+ attribute :division_champ, Shale::Type::Boolean
222
+
223
+ # @!attribute [rw] division_leader
224
+ # Returns whether the team leads the division
225
+ # @api public
226
+ # @example
227
+ # team_record.division_leader #=> true
228
+ # @return [Boolean] whether the team leads the division
229
+ attribute :division_leader, Shale::Type::Boolean
230
+
231
+ # @!attribute [rw] clinched
232
+ # Returns whether the team has clinched a playoff spot
233
+ # @api public
234
+ # @example
235
+ # team_record.clinched #=> true
236
+ # @return [Boolean] whether the team has clinched
237
+ attribute :clinched, Shale::Type::Boolean
238
+
239
+ # @!method division_champ?
240
+ # Returns whether the team is a division champion
241
+ # @api public
242
+ # @example
243
+ # team_record.division_champ? #=> true
244
+ # @return [Boolean, nil] whether the team is a division champion
245
+ alias_method :division_champ?, :division_champ
246
+
247
+ # @!method division_leader?
248
+ # Returns whether the team leads the division
249
+ # @api public
250
+ # @example
251
+ # team_record.division_leader? #=> true
252
+ # @return [Boolean, nil] whether the team leads the division
253
+ alias_method :division_leader?, :division_leader
254
+
255
+ # @!method clinched?
256
+ # Returns whether the team has clinched a playoff spot
257
+ # @api public
258
+ # @example
259
+ # team_record.clinched? #=> true
260
+ # @return [Boolean, nil] whether the team has clinched
261
+ alias_method :clinched?, :clinched
262
+
263
+ json do
264
+ map "team", to: :team
265
+ map "season", to: :season
266
+ map "streak", to: :streak
267
+ map "divisionRank", to: :division_rank
268
+ map "leagueRank", to: :league_rank
269
+ map "wildCardRank", to: :wildcard_rank
270
+ map "gamesPlayed", to: :games_played
271
+ map "gamesBack", to: :games_back
272
+ map "wildCardGamesBack", to: :wildcard_games_back
273
+ map "leagueRecord", to: :league_record
274
+ map "wins", to: :wins
275
+ map "losses", to: :losses
276
+ map "runsScored", to: :runs_scored
277
+ map "runsAllowed", to: :runs_allowed
278
+ map "runDifferential", to: :run_differential
279
+ map "winningPercentage", to: :winning_percentage
280
+ map "divisionChamp", to: :division_champ
281
+ map "divisionLeader", to: :division_leader
282
+ map "clinched", to: :clinched
283
+ end
284
+ end
285
+ end