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,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ class PickemTeamTransformer < BaseTransform
6
+ def initialize(nested: false)
7
+ @nested = nested
8
+ @function = compose_function
9
+ super(nested)
10
+ end
11
+
12
+ private
13
+
14
+ def compose_function
15
+ t(:guard, ->(data) { data.key?(:team) }, t(:unwrap, :team))
16
+ .>> rename_team_name_to_name
17
+ .>> transform_manager
18
+ .>> transform_week_picks
19
+ .>> instantiate
20
+ end
21
+
22
+ # When a team is returned by itself, or as a Group subresource, it has the key `name`.
23
+ # When a team is returned inside Group standings, it has the key `team_name`.
24
+ def rename_team_name_to_name
25
+ t(:rename_keys, team_name: :name)
26
+ end
27
+
28
+ def transform_manager
29
+ Team::ManagerTransformer.new
30
+ end
31
+
32
+ def transform_week_picks
33
+ PickemTeam::WeekPicksTransformer.new
34
+ end
35
+
36
+ def instantiate
37
+ @nested ? t(:no_op) : Instantiator.new(YFantasy::PickemTeam)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ module Player
6
+ class OwnershipPercentageTransformer < BaseTransform
7
+ def initialize
8
+ @function = compose_function
9
+ super
10
+ end
11
+
12
+ private
13
+
14
+ def compose_function
15
+ fn = t(:rename_keys, percent_owned: :ownership_percentage)
16
+ t(:guard, ->(data) { data.key?(:percent_owned) }, fn)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ module Player
6
+ class StatsTransformer < 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?(:player_advanced_stats) }, advanced_stats_transform)
16
+ .>> t(:guard, ->(data) { data.key?(:player_stats) }, player_stats_transform)
17
+ end
18
+
19
+ def player_stats_transform
20
+ fn = DefaultTransformer.new(:stats) >> t(:rename_keys, stats: :standard_stats)
21
+ t(:map_value, :player_stats, fn) >> t(:rename_keys, player_stats: :stats)
22
+ end
23
+
24
+ def advanced_stats_transform
25
+ KeyUnwrapper.new(:player_advanced_stats, :stats)
26
+ .>> t(:rename_keys, stat: :advanced_stats)
27
+ .>> t(:nest, :player_stats, [:advanced_stats])
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ class PlayerTransformer < BaseTransform
6
+ def initialize(nested: false)
7
+ @nested = nested
8
+ @function = compose_function
9
+ super(nested)
10
+ end
11
+
12
+ private
13
+
14
+ def compose_function
15
+ t(:guard, ->(data) { data.key?(:player) }, t(:unwrap, :player))
16
+ .>> transform_ownership_percentage
17
+ .>> transform_stats
18
+ .>> instantiate
19
+ end
20
+
21
+ def transform_ownership_percentage
22
+ Player::OwnershipPercentageTransformer.new
23
+ end
24
+
25
+ def transform_stats
26
+ Player::StatsTransformer.new
27
+ end
28
+
29
+ def instantiate
30
+ @nested ? t(:no_op) : Instantiator.new(YFantasy::Player)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ class StatCategoriesTransformer < BaseTransform
6
+ def initialize
7
+ @function = compose_function
8
+ super
9
+ end
10
+
11
+ private
12
+
13
+ def compose_function
14
+ fn = t(:map_value, :stat_categories, t(:dig_value, :stats, :stat))
15
+ t(:guard, ->(data) { data.key?(:stat_categories) }, fn)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ class StatModifiersTransformer < BaseTransform
6
+ def initialize
7
+ @function = compose_function
8
+ super
9
+ end
10
+
11
+ private
12
+
13
+ def compose_function
14
+ fn = t(:map_value, :stat_modifiers, t(:dig_value, :stats, :stat))
15
+ t(:guard, ->(data) { data.key?(:stat_modifiers) }, fn)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ module T
6
+ extend Dry::Transformer::Registry
7
+
8
+ import Dry::Transformer::ArrayTransformations
9
+ import Dry::Transformer::Coercions
10
+ import Dry::Transformer::Conditional
11
+ import Dry::Transformer::HashTransformations
12
+
13
+ # https://philadelphiaencyclopedia.org/essays/jawn/
14
+ def self.pluralize(jawn)
15
+ jawn = jawn.to_s
16
+ jawn.end_with?("s") ? jawn : "#{jawn}s"
17
+ end
18
+
19
+ def self.singularize(jawn)
20
+ jawn = jawn.to_s
21
+ jawn.end_with?("s") ? jawn[0...-1] : jawn
22
+ end
23
+
24
+ def self.floatize(value)
25
+ (value == "-") ? 0.0 : Types::Coercible::Float.call(value)
26
+ end
27
+
28
+ def self.dig_value(data, *keys)
29
+ data&.dig(*keys)
30
+ end
31
+
32
+ def self.wrap_in_array(data)
33
+ return data if data.is_a?(Array)
34
+ return [] if data.nil?
35
+
36
+ [data]
37
+ end
38
+
39
+ def self.no_op(data)
40
+ data
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ module Team
6
+ class ManagerTransformer < BaseTransform
7
+ def initialize
8
+ @function = compose_function
9
+ end
10
+
11
+ private
12
+
13
+ def compose_function
14
+ DefaultTransformer.new(:managers) >> t(:map_value, :managers, t(:wrap_in_array))
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ module Team
6
+ class RosterTransformer < 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?(:roster) }, transform_players)
16
+ end
17
+
18
+ def transform_players
19
+ map_players_fn = t(:map_array, Transformations.player_transformer(nested: true))
20
+ fn = DefaultTransformer.new(:players) >> t(:map_value, :players, map_players_fn)
21
+
22
+ t(:map_value, :roster, ->(data) { fn.call(data) })
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ module Team
6
+ class StandingsTransformer < 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, :team_standings, transform_record_data)
16
+ t(:guard, ->(data) { data.key?(:team_standings) }, fn)
17
+ end
18
+
19
+ def transform_record_data
20
+ lambda do |data|
21
+ if data[:outcome_totals]
22
+ data[:total_wins] = data.dig(:outcome_totals, :wins)
23
+ data[:total_losses] = data.dig(:outcome_totals, :losses)
24
+ data[:total_ties] = data.dig(:outcome_totals, :ties)
25
+ data[:win_percentage] = data.dig(:outcome_totals, :percentage)
26
+ data.delete(:outcome_totals)
27
+ end
28
+
29
+ if data[:divisional_outcome_totals]
30
+ data[:divisional_wins] = data.dig(:divisional_outcome_totals, :wins)
31
+ data[:divisional_losses] = data.dig(:divisional_outcome_totals, :losses)
32
+ data[:divisional_ties] = data.dig(:divisional_outcome_totals, :ties)
33
+ data.delete(:divisional_outcome_totals)
34
+ end
35
+
36
+ data
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ module Team
6
+ class StatsTransformer < 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?(:team_stats) }, team_stats_transform)
16
+ .>> t(:guard, ->(data) { data.key?(:team_remaining_games) }, team_remaining_games_transform)
17
+ .>> t(:nest, :stats, [:team_stats, :team_points, :team_projected_points, :team_remaining_games])
18
+ end
19
+
20
+ def team_stats_transform
21
+ t(:map_value, :team_stats, DefaultTransformer.new(:stats))
22
+ end
23
+
24
+ def team_remaining_games_transform
25
+ t(:map_value, :team_remaining_games, KeyUnwrapper.new(:total))
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ class TeamTransformer < BaseTransform
6
+ def initialize(nested: false)
7
+ @nested = nested
8
+ @function = compose_function
9
+ super(nested)
10
+ end
11
+
12
+ private
13
+
14
+ def compose_function
15
+ t(:guard, ->(data) { data.key?(:team) }, t(:unwrap, :team))
16
+ .>> transform_managers
17
+ .>> transform_draft_results
18
+ .>> transform_roster
19
+ .>> transform_standings
20
+ .>> transform_stats
21
+ .>> transform_matchups
22
+ .>> instantiate
23
+ end
24
+
25
+ def transform_managers
26
+ Team::ManagerTransformer.new
27
+ end
28
+
29
+ def transform_draft_results
30
+ DefaultTransformer.new(:draft_results)
31
+ end
32
+
33
+ def transform_matchups
34
+ @nested ? t(:no_op) : MatchupsTransformer.new
35
+ end
36
+
37
+ def transform_roster
38
+ Team::RosterTransformer.new
39
+ end
40
+
41
+ def transform_standings
42
+ Team::StandingsTransformer.new
43
+ end
44
+
45
+ def transform_stats
46
+ Team::StatsTransformer.new
47
+ end
48
+
49
+ def instantiate
50
+ @nested ? t(:no_op) : Instantiator.new(YFantasy::Team)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ class UserTransformer < BaseTransform
6
+ def initialize
7
+ @function = compose_function
8
+ end
9
+
10
+ private
11
+
12
+ def compose_function
13
+ KeyUnwrapper.new(:users, :user) >> t(:reject_keys, [:guid])
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ module Transformations
5
+ def self.transformer_for(resource, nested: false)
6
+ method = "#{resource}_transformer"
7
+ nested ? public_send(method, nested: true) : public_send(method)
8
+ end
9
+
10
+ def self.game_transformer
11
+ @@game_transformer ||= GameTransformer.new
12
+ end
13
+
14
+ def self.group_transformer(nested: false)
15
+ if nested
16
+ @@group_transformer_nested ||= GroupTransformer.new(nested: true)
17
+ else
18
+ @@group_transformer ||= GroupTransformer.new
19
+ end
20
+ end
21
+
22
+ def self.league_transformer(nested: false)
23
+ if nested
24
+ @@league_transformer_nested ||= LeagueTransformer.new(nested: true)
25
+ else
26
+ @@league_transformer ||= LeagueTransformer.new
27
+ end
28
+ end
29
+
30
+ def self.pickem_team_transformer(nested: false)
31
+ if nested
32
+ @@pickem_team_transformer_nested ||= PickemTeamTransformer.new(nested: true)
33
+ else
34
+ @@pickem_team_transformer ||= PickemTeamTransformer.new
35
+ end
36
+ end
37
+
38
+ def self.player_transformer(nested: false)
39
+ if nested
40
+ @@player_transformer_nested ||= PlayerTransformer.new(nested: true)
41
+ else
42
+ @@player_transformer ||= PlayerTransformer.new
43
+ end
44
+ end
45
+
46
+ def self.team_transformer(nested: false)
47
+ if nested
48
+ @@team_transformer_nested ||= TeamTransformer.new(nested: true)
49
+ else
50
+ @@team_transformer ||= TeamTransformer.new
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YFantasy
4
+ VERSION = "0.1.0"
5
+ end
data/lib/y_fantasy.rb ADDED
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+ require "json"
5
+
6
+ require "dry-initializer"
7
+ require "dry-configurable"
8
+ require "dry-transformer"
9
+ require "dry-types"
10
+ require "dry-validation"
11
+
12
+ require "zeitwerk"
13
+ loader = Zeitwerk::Loader.for_gem
14
+ loader.collapse("#{__dir__}/y_fantasy/concerns")
15
+ loader.collapse("#{__dir__}/y_fantasy/resources")
16
+ loader.collapse("#{__dir__}/y_fantasy/resources/shared_subresources")
17
+ loader.inflector.inflect("cli" => "CLI")
18
+ loader.setup
19
+
20
+ module YFantasy
21
+ extend Dry::Configurable
22
+
23
+ setting :yahoo_client_id, default: ENV["YAHOO_CLIENT_ID"]
24
+ setting :yahoo_client_secret, default: ENV["YAHOO_CLIENT_SECRET"]
25
+ setting :yahoo_username, default: ENV["YAHOO_USERNAME"]
26
+ setting :yahoo_password, default: ENV["YAHOO_PASSWORD"]
27
+ setting :yahoo_refresh_token, default: ENV["YAHOO_REFRESH_TOKEN"]
28
+ setting :automate_login, default: false
29
+ setting :manual_login_timeout_seconds, default: 30
30
+
31
+ module Types
32
+ include Dry.Types()
33
+ end
34
+ end
35
+
36
+ loader.eager_load_dir("#{__dir__}/y_fantasy/resources")
data/sig/y_fantasy.rbs ADDED
@@ -0,0 +1,4 @@
1
+ module YFantasy
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
data/y_fantasy.gemspec ADDED
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/y_fantasy/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "y_fantasy"
7
+ spec.version = YFantasy::VERSION
8
+ spec.authors = ["Erik Aylward"]
9
+ spec.email = ["y_fantasy_gem@proton.me"]
10
+
11
+ spec.summary = "Ruby wrapper for the Yahoo Fantasy Sports API"
12
+ spec.homepage = "https://github.com/eaylward8/y_fantasy"
13
+ spec.license = "MIT"
14
+ spec.required_ruby_version = ">= 2.6.0"
15
+
16
+ spec.metadata["homepage_uri"] = spec.homepage
17
+ spec.metadata["source_code_uri"] = "https://github.com/eaylward8/y_fantasy"
18
+ spec.metadata["changelog_uri"] = "https://github.com/eaylward8/y_fantasy/blob/master/CHANGELOG.md"
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
23
+ `git ls-files -z`.split("\x0").reject do |f|
24
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
25
+ end
26
+ end
27
+ spec.bindir = "exe"
28
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
29
+ spec.require_paths = ["lib"]
30
+
31
+ spec.add_dependency "dry-initializer", "~> 3.0"
32
+ spec.add_dependency "dry-configurable", "~> 1.0"
33
+ spec.add_dependency "dry-transformer", "~> 1.0"
34
+ spec.add_dependency "dry-types", "~> 1.0"
35
+ spec.add_dependency "dry-validation", "~> 1.0"
36
+ spec.add_dependency "mechanize", "~> 2.9"
37
+ spec.add_dependency "ox", "~> 2.14"
38
+ spec.add_dependency "thor", "~> 1.3"
39
+ spec.add_dependency "zeitwerk", "~> 2.5"
40
+
41
+ spec.add_development_dependency "bundler", "~> 2.3"
42
+ spec.add_development_dependency "factory_bot", "~> 6.5"
43
+ spec.add_development_dependency "pry-byebug", "~> 3.10"
44
+ spec.add_development_dependency "rake", "~> 13.0"
45
+ spec.add_development_dependency "rspec", "~> 3.0"
46
+ spec.add_development_dependency "simplecov", "~> 0.20"
47
+ spec.add_development_dependency "standard", "~> 1.10"
48
+ spec.add_development_dependency "webmock", "~> 3.0"
49
+ end