y_fantasy 0.1.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 (85) hide show
  1. checksums.yaml +7 -0
  2. data/.pryrc +8 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +20 -0
  5. data/.standard.yml +2 -0
  6. data/CHANGELOG.md +5 -0
  7. data/CODE_OF_CONDUCT.md +3 -0
  8. data/Gemfile +5 -0
  9. data/Gemfile.lock +220 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +41 -0
  12. data/Rakefile +12 -0
  13. data/exe/y_fantasy +9 -0
  14. data/lib/y_fantasy/api/authentication.rb +177 -0
  15. data/lib/y_fantasy/api/client.rb +84 -0
  16. data/lib/y_fantasy/api/subresource_param_builder.rb +138 -0
  17. data/lib/y_fantasy/api/url_builder.rb +91 -0
  18. data/lib/y_fantasy/cli.rb +46 -0
  19. data/lib/y_fantasy/concerns/subresourceable.rb +87 -0
  20. data/lib/y_fantasy/ref/nfl.rb +57 -0
  21. data/lib/y_fantasy/resources/base_resource.rb +117 -0
  22. data/lib/y_fantasy/resources/base_subresource.rb +31 -0
  23. data/lib/y_fantasy/resources/game/game_week.rb +26 -0
  24. data/lib/y_fantasy/resources/game/position_type.rb +20 -0
  25. data/lib/y_fantasy/resources/game.rb +136 -0
  26. data/lib/y_fantasy/resources/group/settings.rb +53 -0
  27. data/lib/y_fantasy/resources/group/standings.rb +11 -0
  28. data/lib/y_fantasy/resources/group.rb +76 -0
  29. data/lib/y_fantasy/resources/league/scoreboard.rb +12 -0
  30. data/lib/y_fantasy/resources/league/settings.rb +51 -0
  31. data/lib/y_fantasy/resources/league/standings.rb +25 -0
  32. data/lib/y_fantasy/resources/league.rb +187 -0
  33. data/lib/y_fantasy/resources/pickem_team/pick.rb +31 -0
  34. data/lib/y_fantasy/resources/pickem_team/week_pick.rb +28 -0
  35. data/lib/y_fantasy/resources/pickem_team.rb +98 -0
  36. data/lib/y_fantasy/resources/player/draft_analysis.rb +26 -0
  37. data/lib/y_fantasy/resources/player/ownership_percentage.rb +26 -0
  38. data/lib/y_fantasy/resources/player/stat_collection.rb +32 -0
  39. data/lib/y_fantasy/resources/player.rb +157 -0
  40. data/lib/y_fantasy/resources/shared_subresources/draft_result.rb +39 -0
  41. data/lib/y_fantasy/resources/shared_subresources/matchup.rb +61 -0
  42. data/lib/y_fantasy/resources/shared_subresources/roster_position.rb +38 -0
  43. data/lib/y_fantasy/resources/shared_subresources/stat.rb +16 -0
  44. data/lib/y_fantasy/resources/shared_subresources/stat_category.rb +22 -0
  45. data/lib/y_fantasy/resources/shared_subresources/stat_modifier.rb +10 -0
  46. data/lib/y_fantasy/resources/shared_subresources/stat_winner.rb +8 -0
  47. data/lib/y_fantasy/resources/team/manager.rb +23 -0
  48. data/lib/y_fantasy/resources/team/roster.rb +18 -0
  49. data/lib/y_fantasy/resources/team/standings.rb +33 -0
  50. data/lib/y_fantasy/resources/team/stat_collection.rb +38 -0
  51. data/lib/y_fantasy/resources/team.rb +175 -0
  52. data/lib/y_fantasy/subresource_validator.rb +67 -0
  53. data/lib/y_fantasy/transformations/base_transform.rb +62 -0
  54. data/lib/y_fantasy/transformations/collection_transformer.rb +22 -0
  55. data/lib/y_fantasy/transformations/default_transformer.rb +22 -0
  56. data/lib/y_fantasy/transformations/game/position_types_transformer.rb +21 -0
  57. data/lib/y_fantasy/transformations/game_transformer.rb +54 -0
  58. data/lib/y_fantasy/transformations/group_transformer.rb +39 -0
  59. data/lib/y_fantasy/transformations/instantiator.rb +25 -0
  60. data/lib/y_fantasy/transformations/key_unwrapper.rb +12 -0
  61. data/lib/y_fantasy/transformations/league/scoreboard_transformer.rb +21 -0
  62. data/lib/y_fantasy/transformations/league/settings_transformer.rb +25 -0
  63. data/lib/y_fantasy/transformations/league/standings_transformer.rb +22 -0
  64. data/lib/y_fantasy/transformations/league_transformer.rb +57 -0
  65. data/lib/y_fantasy/transformations/matchups_transformer.rb +22 -0
  66. data/lib/y_fantasy/transformations/pickem_team/week_picks_transformer.rb +29 -0
  67. data/lib/y_fantasy/transformations/pickem_team_transformer.rb +41 -0
  68. data/lib/y_fantasy/transformations/player/ownership_percentage_transformer.rb +21 -0
  69. data/lib/y_fantasy/transformations/player/stats_transformer.rb +32 -0
  70. data/lib/y_fantasy/transformations/player_transformer.rb +34 -0
  71. data/lib/y_fantasy/transformations/stat_categories_transformer.rb +19 -0
  72. data/lib/y_fantasy/transformations/stat_modifiers_transformer.rb +19 -0
  73. data/lib/y_fantasy/transformations/t.rb +44 -0
  74. data/lib/y_fantasy/transformations/team/manager_transformer.rb +19 -0
  75. data/lib/y_fantasy/transformations/team/roster_transformer.rb +27 -0
  76. data/lib/y_fantasy/transformations/team/standings_transformer.rb +42 -0
  77. data/lib/y_fantasy/transformations/team/stats_transformer.rb +30 -0
  78. data/lib/y_fantasy/transformations/team_transformer.rb +54 -0
  79. data/lib/y_fantasy/transformations/user_transformer.rb +17 -0
  80. data/lib/y_fantasy/transformations.rb +54 -0
  81. data/lib/y_fantasy/version.rb +5 -0
  82. data/lib/y_fantasy.rb +36 -0
  83. data/sig/y_fantasy.rbs +4 -0
  84. data/y_fantasy.gemspec +49 -0
  85. metadata +364 -0
@@ -0,0 +1,175 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ # Represents a fantasy team in a Yahoo Fantasy Sports league
5
+ class Team < BaseResource
6
+ # --- REQUIRED ATTRIBUTES ------------------------------------------------------------------------------------------
7
+
8
+ # @!attribute [r] team_key
9
+ # @return [String] the unique key for this team
10
+ option :team_key
11
+
12
+ # @!attribute [r] team_id
13
+ # @return [Integer] the ID for this team
14
+ option :team_id, type: Types::Coercible::Integer
15
+
16
+ # @!attribute [r] has_draft_grade
17
+ # @return [Boolean] whether this team has a draft grade
18
+ option :has_draft_grade, type: Types::Params::Bool
19
+
20
+ # @!attribute [r] league_scoring_type
21
+ # @return [String] the scoring type of the league (e.g. "head", "point")
22
+ option :league_scoring_type
23
+
24
+ # @!attribute [r] managers
25
+ # @return [Array<Manager>] Array of team managers
26
+ option :managers, type: array_of(Manager)
27
+
28
+ # @!attribute [r] name
29
+ # @return [String] the name of the team
30
+ option :name
31
+
32
+ # @!attribute [r] number_of_moves
33
+ # @return [Integer] the number of roster moves made by this team
34
+ option :number_of_moves, type: Types::Coercible::Integer
35
+
36
+ # @!attribute [r] number_of_trades
37
+ # @return [Integer] the number of trades made by this team
38
+ option :number_of_trades, type: Types::Coercible::Integer
39
+
40
+ # @!attribute [r] roster_adds
41
+ # @return [String] the roster adds information for this team
42
+ option :roster_adds
43
+
44
+ # @!attribute [r] team_logos
45
+ # @return [Hash] the team logo information
46
+ option :team_logos, type: ->(h) { h[:team_logo] }
47
+
48
+ # @!attribute [r] url
49
+ # @return [String] the URL to the team's Yahoo Fantasy page
50
+ option :url
51
+
52
+ # --- OPTIONAL ATTRIBUTES ------------------------------------------------------------------------------------------
53
+
54
+ # @!attribute [r] clinched_playoffs
55
+ # @return [Boolean, nil] whether this team has clinched a playoff spot
56
+ option :clinched_playoffs, optional: true, type: Types::Params::Bool
57
+
58
+ # @!attribute [r] division_id
59
+ # @return [Integer, nil] the ID of the division this team belongs to
60
+ option :division_id, optional: true, type: Types::Coercible::Integer
61
+
62
+ # @!attribute [r] draft_grade
63
+ # @return [String, nil] the grade assigned to this team's draft
64
+ option :draft_grade, optional: true
65
+
66
+ # @!attribute [r] draft_recap_url
67
+ # @return [String, nil] the URL to this team's draft recap
68
+ option :draft_recap_url, optional: true
69
+
70
+ # @!attribute [r] faab_balance
71
+ # @return [Integer, nil] the remaining Free Agent Acquisition Budget (FAAB) for this team
72
+ option :faab_balance, optional: true, type: Types::Coercible::Integer
73
+
74
+ # @!attribute [r] waiver_priority
75
+ # @return [Integer, nil] This team's waiver priority
76
+ option :waiver_priority, optional: true, type: Types::Coercible::Integer
77
+
78
+ # @!attribute [r] league_key
79
+ # @return [String, nil] the key of the league this team belongs to
80
+ option :league_key, optional: true
81
+
82
+ # @!attribute [r] league
83
+ # @return [League, nil] the league this team belongs to
84
+ option :league, optional: true
85
+
86
+ # --- SUBRESOURCES -------------------------------------------------------------------------------------------------
87
+
88
+ # @!attribute [r] draft_results
89
+ # @return [Array<DraftResult>, nil] the draft results for this team
90
+ option :draft_results, optional: true, type: array_of(DraftResult)
91
+
92
+ # @!attribute [r] matchups
93
+ # @return [Array<Matchup>] the matchups for this team
94
+ option :matchups, optional: true, type: array_of(Matchup), default: -> { [] }
95
+
96
+ # @!attribute [r] roster
97
+ # @return [Roster, nil] the roster for this team
98
+ option :roster, optional: true, type: instance_of(Roster)
99
+
100
+ # @!attribute [r] stats
101
+ # @return [StatCollection, nil] the stat collection for this team
102
+ option :stats, optional: true, type: instance_of(StatCollection), default: -> {}
103
+
104
+ # @!attribute [r] team_standings
105
+ # @return [Standings, nil] the standings for this team
106
+ option :team_standings, optional: true, type: instance_of(Standings)
107
+
108
+ has_subresource :draft_results, klass: DraftResult
109
+ has_subresource :matchups, klass: Matchup
110
+ has_subresource :roster, klass: Roster
111
+ has_subresource :stats, klass: StatCollection
112
+ has_subresource :team_standings, klass: Standings
113
+
114
+ def_delegators :team_standings, :rank, :playoff_seed, :wins, :losses, :ties, :points_for, :points_against
115
+
116
+ # --- INSTANCE METHODS ---------------------------------------------------------------------------------------------
117
+
118
+ # Returns the primary manager of the team
119
+ # @return [Manager] the primary manager (non-comanager) of the team
120
+ def manager
121
+ managers.find { |manager| !manager.is_comanager }
122
+ end
123
+
124
+ # Returns a hash of simplified standings information for the team
125
+ # @return [Hash] a hash containing key standings information
126
+ def simple_standings
127
+ {
128
+ team_key: team_key,
129
+ name: name,
130
+ rank: rank,
131
+ playoff_seed: playoff_seed,
132
+ wins: wins,
133
+ losses: losses,
134
+ ties: ties,
135
+ points_for: points_for,
136
+ points_against: points_against
137
+ }
138
+ end
139
+
140
+ # Returns the league key for this team
141
+ # @return [String] the league key
142
+ def league_key
143
+ @league_key ||= team_key.sub(/\.t\.\d+/, "")
144
+ end
145
+
146
+ # Returns the league this team belongs to
147
+ # @return [League] the league object
148
+ def league
149
+ @league ||= League.find(league_key)
150
+ end
151
+
152
+ # Gets the matchups for this team for a specific week
153
+ # @param week [Integer] the week number to get matchups for
154
+ # @return [Array<Matchup>] the matchups for the specified week
155
+ def matchups_for_week(week)
156
+ @matchups = self.class.find(team_key, with: :matchups, week: week).matchups
157
+ end
158
+
159
+ # Gets the roster for this team for a specific week
160
+ # @param week [Integer] the week number to get the roster for
161
+ # @param player_stats [Boolean] Whether to include player stats
162
+ # @return [Roster] the roster for the specified week
163
+ def roster_for_week(week, player_stats: false)
164
+ with = player_stats ? {roster: {players: :stats}} : :roster
165
+ @roster = self.class.find(team_key, with: with, week: week).roster
166
+ end
167
+
168
+ # Gets the stats for this team for a specific week
169
+ # @param week [Integer] the week number to get stats for
170
+ # @return [StatCollection] the stats for the specified week
171
+ def stats_for_week(week)
172
+ @stats = self.class.find(team_key, with: :stats, week: week).stats
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ class SubresourceValidator
5
+ def self.validate!(klass, subresources = [])
6
+ new(klass, subresources).validate!
7
+ end
8
+
9
+ def initialize(klass, subresources = [])
10
+ @contract = Contract.new(klass: klass)
11
+ @subresources = Array(subresources)
12
+ end
13
+
14
+ def validate!
15
+ return true if @subresources.empty?
16
+
17
+ result = @contract.call(subresources: @subresources)
18
+ return true if result.success?
19
+
20
+ raise InvalidSubresourceError.new(result.errors.to_h.to_s)
21
+ end
22
+
23
+ class Contract < Dry::Validation::Contract
24
+ option :klass
25
+
26
+ params do
27
+ required(:subresources).value(:array)
28
+ end
29
+
30
+ # TODO: Simplify this. It's gotten too complicated.
31
+ rule(:subresources).each do
32
+ fail_msg = "#{value} is not a valid subresource of #{klass}"
33
+ next key.failure(fail_msg) unless value.is_a?(Symbol) || value.is_a?(Hash)
34
+
35
+ if value.is_a?(Symbol)
36
+ next if klass.subresource_tree.key?(value)
37
+
38
+ key.failure(fail_msg)
39
+ elsif value.is_a?(Hash)
40
+ if value.keys.size > 1
41
+ next key.failure("Nested subresources should contain a single top-level key. Found: #{value.keys}")
42
+ end
43
+
44
+ sub, nested_subs = value.keys.first, value.values
45
+ valid_nested_subs = klass.subresource_tree.dig(sub)
46
+ next key.failure(fail_msg) if !valid_nested_subs
47
+
48
+ nested_subs.each do |nested_sub|
49
+ if nested_sub.is_a?(Hash)
50
+ nested_klass = YFantasy.const_get(Transformations::T.singularize(nested_sub.keys.first).capitalize)
51
+ next if SubresourceValidator.new(nested_klass, Array(nested_sub.values.first))
52
+ end
53
+
54
+ next if valid_nested_subs.include?(nested_sub)
55
+ key.failure("#{nested_sub} is not a valid subresource of #{sub}")
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ class InvalidSubresourceError < StandardError
62
+ def initialize(msg = "Invalid subresource(s)")
63
+ super
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ # Base class for all transformations in the YFantasy module.
6
+ #
7
+ # @abstract Subclasses must set @function instance variable
8
+ # @example Creating a custom transformation
9
+ # class MyTransform < BaseTransform
10
+ # def initialize(param)
11
+ # @function = ->(data) { transform_data(data, param) }
12
+ # end
13
+ #
14
+ # private
15
+ #
16
+ # def transform_data(data, param)
17
+ # # transformation logic here
18
+ # end
19
+ # end
20
+ class BaseTransform
21
+ extend Forwardable
22
+
23
+ # Delegates transformation-related methods to the @function object
24
+ # @!method >>(other)
25
+ # Function composition - chains this transformation with another
26
+ # @param other [#call] Another callable object to compose with
27
+ # @return [Proc] A new composed function
28
+ # @!method call(*args)
29
+ # Invokes the transformation function
30
+ # @param args Arguments to pass to the transformation
31
+ # @return [Object] The transformed result
32
+ # @!method [](*args)
33
+ # Alias for call
34
+ # @param args Arguments to pass to the transformation
35
+ # @return [Object] The transformed result
36
+ def_delegators :@function, :>>, :call, :[]
37
+
38
+ # Initializes a new transformation instance
39
+ # @param args [Array] Arguments for initialization (used by subclasses)
40
+ # @raise [RuntimeError] If @function is not properly set by the subclass
41
+ def initialize(*args)
42
+ ensure_function_set
43
+ end
44
+
45
+ # Helper method to call transformations provided by Dry::Transformer (see T module)
46
+ # @param args [Array] Arguments to pass to Dry::Transformer
47
+ # @return [Object] A new transformation object
48
+ def t(*args)
49
+ T[*args]
50
+ end
51
+
52
+ # Ensures that the transformation function is properly set
53
+ # @raise [RuntimeError] If @function is not callable or does not respond to the required methods
54
+ # @return [nil] if the function is properly set
55
+ def ensure_function_set
56
+ return if @function.respond_to?(:>>) && @function.respond_to?(:call)
57
+
58
+ raise "Subclass must set @function instance variable"
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ class CollectionTransformer < BaseTransform
6
+ def initialize(collection)
7
+ @collection = collection.to_sym
8
+ @resource = T[:singularize].call(collection).to_sym
9
+ @function = compose_function
10
+ end
11
+
12
+ private
13
+
14
+ def compose_function
15
+ UserTransformer.new
16
+ .>> t(:dig_value, @collection, @resource)
17
+ .>> t(:wrap_in_array)
18
+ .>> t(:map_array, Transformations.transformer_for(@resource))
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ class DefaultTransformer < BaseTransform
6
+ def initialize(resource)
7
+ @resource = resource
8
+ @function = compose_function
9
+ super
10
+ end
11
+
12
+ private
13
+
14
+ def compose_function
15
+ plural = t(:pluralize, @resource).call.to_sym
16
+ singular = t(:singularize, @resource).call.to_sym
17
+
18
+ t(:guard, t(:dig_value, plural, singular), t(:map_value, plural, t(:dig_value, singular)))
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ module Game
6
+ class PositionTypesTransformer < BaseTransform
7
+ def initialize
8
+ @function = compose_function
9
+ super
10
+ end
11
+
12
+ private
13
+
14
+ def compose_function
15
+ fn = DefaultTransformer.new(:position_types) >> t(:map_value, :position_types, t(:wrap_in_array))
16
+ t(:guard, ->(data) { data.key?(:position_types) }, fn)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ class GameTransformer < BaseTransform
6
+ def initialize
7
+ @function = compose_function
8
+ super
9
+ end
10
+
11
+ private
12
+
13
+ def compose_function
14
+ t(:guard, ->(data) { data.key?(:game) }, t(:unwrap, :game))
15
+ .>> transform_game_weeks
16
+ .>> transform_groups
17
+ .>> transform_leagues
18
+ .>> transform_position_types
19
+ .>> transform_roster_positions
20
+ .>> transform_stat_categories
21
+ .>> Instantiator.new(YFantasy::Game)
22
+ end
23
+
24
+ def transform_game_weeks
25
+ DefaultTransformer.new(:game_weeks)
26
+ end
27
+
28
+ def transform_groups
29
+ map_groups_fn = t(:map_array, Transformations.group_transformer(nested: true))
30
+ # wrap_in_array is needed when there is only 1 group
31
+ fn = DefaultTransformer.new(:groups) >> t(:map_value, :groups, t(:wrap_in_array) >> map_groups_fn)
32
+ t(:guard, ->(data) { !data[:groups].nil? }, fn)
33
+ end
34
+
35
+ def transform_leagues
36
+ map_leagues_fn = t(:map_array, Transformations.league_transformer(nested: true))
37
+ fn = DefaultTransformer.new(:leagues) >> t(:map_value, :leagues, t(:wrap_in_array) >> map_leagues_fn)
38
+ t(:guard, ->(data) { !data[:leagues].nil? }, fn)
39
+ end
40
+
41
+ def transform_position_types
42
+ Game::PositionTypesTransformer.new
43
+ end
44
+
45
+ def transform_roster_positions
46
+ DefaultTransformer.new(:roster_positions)
47
+ end
48
+
49
+ def transform_stat_categories
50
+ StatCategoriesTransformer.new
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ class GroupTransformer < BaseTransform
6
+ def initialize(nested: false)
7
+ @nested = nested
8
+ @function = compose_function
9
+ super
10
+ end
11
+
12
+ private
13
+
14
+ def compose_function
15
+ t(:guard, ->(data) { data.key?(:group) }, t(:unwrap, :group))
16
+ .>> transform_teams
17
+ .>> transform_standings
18
+ .>> instantiate
19
+ end
20
+
21
+ def transform_teams
22
+ DefaultTransformer.new(:teams) >> t(:map_value, :teams, map_teams_fn)
23
+ end
24
+
25
+ def transform_standings
26
+ map_standings_fn = t(:map_value, :standings, t(:rename_keys, team: :teams) >> t(:map_value, :teams, map_teams_fn))
27
+ t(:guard, ->(data) { data.key?(:standings) }, map_standings_fn)
28
+ end
29
+
30
+ def map_teams_fn
31
+ t(:map_array, Transformations.pickem_team_transformer(nested: true))
32
+ end
33
+
34
+ def instantiate
35
+ @nested ? t(:no_op) : Instantiator.new(YFantasy::Group)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ class Instantiator < BaseTransform
6
+ def initialize(klass, collection: false)
7
+ @klass = klass
8
+ @collection = collection
9
+ @function = compose_function
10
+ super(klass)
11
+ end
12
+
13
+ private
14
+
15
+ def compose_function
16
+ fn = t(->(data) { data.is_a?(Hash) ? @klass.new(**data) : data })
17
+ for_collection? ? t(:map_array, fn) : fn
18
+ end
19
+
20
+ def for_collection?
21
+ @collection
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ class KeyUnwrapper < BaseTransform
6
+ def initialize(*keys)
7
+ @function = keys.map { |key| t(:unwrap, key) }.inject(:>>)
8
+ super
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ module League
6
+ class ScoreboardTransformer < BaseTransform
7
+ def initialize
8
+ @function = compose_function
9
+ super
10
+ end
11
+
12
+ private
13
+
14
+ def compose_function
15
+ fn = t(:map_value, :scoreboard, MatchupsTransformer.new)
16
+ t(:guard, ->(data) { data.key?(:scoreboard) }, fn)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ module League
6
+ class SettingsTransformer < BaseTransform
7
+ def initialize
8
+ @function = compose_function
9
+ super
10
+ end
11
+
12
+ private
13
+
14
+ def compose_function
15
+ fn = t(
16
+ :map_value,
17
+ :settings,
18
+ DefaultTransformer.new(:roster_positions) >> StatCategoriesTransformer.new >> StatModifiersTransformer.new
19
+ )
20
+ t(:guard, ->(data) { data.key?(:settings) }, fn)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ module League
6
+ class StandingsTransformer < BaseTransform
7
+ def initialize
8
+ @function = compose_function
9
+ super
10
+ end
11
+
12
+ private
13
+
14
+ def compose_function
15
+ map_teams_fn = t(:map_array, Transformations.team_transformer(nested: true))
16
+ map_standings_fn = t(:map_value, :standings, DefaultTransformer.new(:teams) >> t(:map_value, :teams, map_teams_fn))
17
+ t(:guard, ->(data) { data.key?(:standings) }, map_standings_fn)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ class LeagueTransformer < BaseTransform
6
+ def initialize(nested: false)
7
+ @nested = nested
8
+ @function = compose_function
9
+ super
10
+ end
11
+
12
+ private
13
+
14
+ def compose_function
15
+ t(:guard, ->(data) { data.key?(:league) }, t(:unwrap, :league))
16
+ .>> transform_draft_results
17
+ .>> transform_scoreboard
18
+ .>> transform_settings
19
+ .>> transform_standings
20
+ .>> transform_players
21
+ .>> transform_teams
22
+ .>> instantiate
23
+ end
24
+
25
+ def transform_draft_results
26
+ DefaultTransformer.new(:draft_results)
27
+ end
28
+
29
+ def transform_scoreboard
30
+ League::ScoreboardTransformer.new
31
+ end
32
+
33
+ def transform_settings
34
+ League::SettingsTransformer.new
35
+ end
36
+
37
+ def transform_standings
38
+ League::StandingsTransformer.new
39
+ end
40
+
41
+ def transform_players
42
+ map_players_fn = t(:map_array, Transformations.player_transformer(nested: true))
43
+ DefaultTransformer.new(:players) >> t(:map_value, :players, map_players_fn)
44
+ end
45
+
46
+ def transform_teams
47
+ map_teams_fn = t(:map_array, Transformations.team_transformer(nested: true))
48
+ # wrap_in_array is needed when there is only 1 team. This can happen when requesting data scoped to current user.
49
+ DefaultTransformer.new(:teams) >> t(:map_value, :teams, t(:wrap_in_array) >> map_teams_fn)
50
+ end
51
+
52
+ def instantiate
53
+ @nested ? t(:no_op) : Instantiator.new(YFantasy::League)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ class MatchupsTransformer < BaseTransform
6
+ def initialize
7
+ @function = compose_function
8
+ super
9
+ end
10
+
11
+ private
12
+
13
+ def compose_function
14
+ map_teams_fn = t(:map_array, Transformations.team_transformer(nested: true))
15
+ map_matchups_fn = t(:map_array, DefaultTransformer.new(:teams) >> t(:map_value, :teams, map_teams_fn))
16
+ # wrap_in_array is needed when requesting a team's matchup for a single week
17
+ fn = DefaultTransformer.new(:matchups) >> t(:map_value, :matchups, t(:wrap_in_array) >> map_matchups_fn)
18
+ t(:guard, ->(data) { !data[:matchups].nil? }, fn)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ module PickemTeam
6
+ class WeekPicksTransformer < BaseTransform
7
+ def initialize
8
+ @function = compose_function
9
+ super
10
+ end
11
+
12
+ private
13
+
14
+ def compose_function
15
+ t(:guard, ->(data) { data.key?(:week_picks) }, transform_week_picks)
16
+ end
17
+
18
+ def transform_week_picks
19
+ map_week_picks_fn = t(:map_array, transform_picks)
20
+ DefaultTransformer.new(:week_picks) >> t(:map_value, :week_picks, map_week_picks_fn)
21
+ end
22
+
23
+ def transform_picks
24
+ DefaultTransformer.new(:picks) >> t(:map_value, :picks, t(:wrap_in_array))
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end