steel_wheel 0.5.1 → 0.6.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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +2 -0
  3. data/.github/workflows/ruby.yml +21 -26
  4. data/.gitignore +0 -0
  5. data/.rspec +0 -0
  6. data/.rubocop.yml +188 -0
  7. data/.ruby-version +1 -1
  8. data/.travis.yml +0 -0
  9. data/CODE_OF_CONDUCT.md +0 -0
  10. data/Gemfile +10 -0
  11. data/Gemfile.lock +114 -95
  12. data/LICENSE.txt +0 -0
  13. data/README.md +307 -4
  14. data/Rakefile +7 -1
  15. data/assets/action_diagram.png +0 -0
  16. data/bin/console +1 -0
  17. data/lib/generators/steel_wheel/application_handler/USAGE +8 -0
  18. data/lib/generators/steel_wheel/application_handler/application_handler_generator.rb +12 -0
  19. data/lib/generators/steel_wheel/application_handler/templates/handler_template.rb +4 -0
  20. data/lib/generators/steel_wheel/command/USAGE +0 -0
  21. data/lib/generators/steel_wheel/command/command_generator.rb +10 -10
  22. data/lib/generators/steel_wheel/command/templates/command_template.rb +3 -1
  23. data/lib/generators/steel_wheel/handler/USAGE +0 -0
  24. data/lib/generators/steel_wheel/handler/handler_generator.rb +10 -10
  25. data/lib/generators/steel_wheel/handler/templates/handler_template.rb +13 -7
  26. data/lib/generators/steel_wheel/params/USAGE +0 -0
  27. data/lib/generators/steel_wheel/params/params_generator.rb +10 -10
  28. data/lib/generators/steel_wheel/params/templates/params_template.rb +3 -1
  29. data/lib/generators/steel_wheel/query/USAGE +0 -0
  30. data/lib/generators/steel_wheel/query/query_generator.rb +10 -10
  31. data/lib/generators/steel_wheel/query/templates/query_template.rb +3 -1
  32. data/lib/steel_wheel/command.rb +8 -2
  33. data/lib/steel_wheel/handler.rb +86 -29
  34. data/lib/steel_wheel/params.rb +10 -1
  35. data/lib/steel_wheel/query.rb +7 -1
  36. data/lib/steel_wheel/response.rb +10 -5
  37. data/lib/steel_wheel/skip_active_model_errors_keys.rb +12 -1
  38. data/lib/steel_wheel/version.rb +3 -1
  39. data/lib/steel_wheel.rb +3 -1
  40. data/steel_wheel.gemspec +6 -11
  41. metadata +21 -101
  42. data/lib/generators/steel_wheel/generic_generator.rb +0 -23
@@ -1,50 +1,107 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SteelWheel
2
- class Handler < FlowObject::Base
3
- from :params
4
- to :response
4
+ # Base class that defines main flow
5
+ class Handler
6
+ include Nina
7
+ include ActiveModel::Validations
8
+
9
+ attr_reader :user_defined_callbacks
10
+
11
+ builder :main do
12
+ factory :params, produces: SteelWheel::Params
13
+ factory :query, produces: SteelWheel::Query
14
+ factory :command, produces: SteelWheel::Command
15
+ factory :response, produces: SteelWheel::Response
16
+ end
17
+
18
+ def self.define(flow: :main, &block)
19
+ builders[flow].subclass(&block)
20
+ end
21
+
22
+ # Runs validation on objects
23
+ class Validator
24
+ include ActiveModel::Validations
25
+ attr_accessor :http_status
26
+
27
+ def self.run(flow)
28
+ validator = new
29
+ [flow.params, flow.query, flow.command].each do |obj|
30
+ break if validator.errors.any?
31
+
32
+ validator.validate(obj)
33
+ end
34
+ flow.status = validator.http_status || :ok
35
+ flow.errors.merge!(validator.errors)
36
+ end
37
+
38
+ def validate(object)
39
+ return if object.valid?
40
+
41
+ self.http_status ||= object.http_status
42
+ errors.merge!(object.errors) if errors.empty?
43
+ end
44
+ end
45
+
46
+ def initialize(&callbacks)
47
+ @user_defined_callbacks = callbacks
48
+ end
5
49
 
6
- input :params, base_class: SteelWheel::Params
7
- flow do
8
- stage :query, base_class: SteelWheel::Query
9
- stage :command, base_class: SteelWheel::Command
50
+ def on_params_created(params)
51
+ # NOOP
10
52
  end
11
- output :response, base_class: SteelWheel::Response
12
53
 
13
- def self.halt_flow?(object, id)
14
- !object.valid?
54
+ def on_query_created(query)
55
+ # NOOP
15
56
  end
16
57
 
17
- def on_params_failure
18
- output.status = :bad_request
19
- output.errors.merge!(output.params.errors)
58
+ def on_command_created(command)
59
+ # NOOP
20
60
  end
21
61
 
22
- def on_query_failure
23
- output.status = output.query.http_status
24
- output.errors.merge!(output.query.errors)
62
+ def on_response_created(response)
63
+ # NOOP
25
64
  end
26
65
 
27
- def on_command_failure
28
- output.status = output.command.http_status
29
- output.errors.merge!(output.command.errors)
66
+ def on_failure(flow)
67
+ # NOOP
30
68
  end
31
69
 
32
- def on_success
70
+ def on_success(flow)
33
71
  # NOOP
34
72
  end
35
73
 
74
+ def self.base_class_for(factory, flow: :main)
75
+ builders[flow].abstract_factory.factories[factory].base_class
76
+ end
77
+
36
78
  def self.handle(input:, flow: :main, &block)
37
- call(input: input, flow: flow) do |callbacks|
38
- callbacks.flow_initialized(&block) if block
39
- end
79
+ new.handle(input: input, flow: flow, &block)
80
+ end
81
+
82
+ def handle(input:, flow: :main, &block)
83
+ object = configure_builder(flow).wrap(delegate: true) { |i| i.params(input) }
84
+ yield(object) if block
85
+ Validator.run(object)
86
+ object.success? ? on_success(object) : on_failure(object)
87
+ object
40
88
  end
41
89
 
42
- alias_method(:flow, :output)
43
- class << self
44
- alias_method :params, :params_input
45
- alias_method :query, :query_stage
46
- alias_method :command, :command_stage
47
- alias_method :response, :response_output
90
+ private
91
+
92
+ def configure_builder(flow)
93
+ builder = self.class.builders[flow].with_callbacks(&required_callbacks)
94
+ builder = builder.with_callbacks(&user_defined_callbacks) if user_defined_callbacks
95
+ builder
96
+ end
97
+
98
+ def required_callbacks
99
+ lambda do |c|
100
+ c.params { |o| on_params_created(o) }
101
+ c.query { |o| on_query_created(o) }
102
+ c.command { |o| on_command_created(o) }
103
+ c.response { |o| on_response_created(o) }
104
+ end
48
105
  end
49
106
  end
50
107
  end
@@ -1,3 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SteelWheel
2
- class Params < EasyParams::Base; end
4
+ # Base class for params
5
+ class Params < EasyParams::Base
6
+ def http_status
7
+ return :ok if errors.empty?
8
+
9
+ :bad_request
10
+ end
11
+ end
3
12
  end
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SteelWheel
4
+ # Base class for queries
2
5
  class Query
3
6
  include Memery
4
7
  include ActiveModel::Validations
@@ -8,7 +11,10 @@ module SteelWheel
8
11
  end
9
12
 
10
13
  def http_status
11
- errors.keys.first
14
+ return :ok if errors.empty?
15
+ return errors.keys.first unless defined?(ActiveModel::Error)
16
+
17
+ errors.map(&:type).first
12
18
  end
13
19
  end
14
20
  end
@@ -1,14 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SteelWheel
4
+ # Base class for responses
2
5
  class Response
3
6
  attr_accessor :status
4
- attr_writer :errors
7
+
5
8
  include ActiveModel::Validations
6
9
 
7
- def self.generic_validation_keys(*keys)
8
- include SteelWheel::SkipActiveModelErrorsKeys[*keys]
9
- end
10
+ unless defined?(ActiveModel::Error)
11
+ def self.generic_validation_keys(*keys)
12
+ include SteelWheel::SkipActiveModelErrorsKeys[*keys]
13
+ end
10
14
 
11
- generic_validation_keys(:not_found, :forbidden, :unprocessable_entity)
15
+ generic_validation_keys(:not_found, :forbidden, :unprocessable_entity, :bad_request, :unauthorized)
16
+ end
12
17
 
13
18
  def self.name
14
19
  'SteelWheel::Response'
@@ -1,7 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SteelWheel
4
+ # Allows to treat some error codes as :base
5
+ # EX:
6
+ # generic_validation_keys :not_found
7
+ # errors.add(:not_found, 'Can not find')
8
+ # errors.full_messages => ['Can not find']
9
+ # not ['Not found an not find']
2
10
  module SkipActiveModelErrorsKeys
3
11
  def self.build_module
4
- mod = Module.new do
12
+ Module.new do
5
13
  class << self
6
14
  attr_accessor :skip_keys
7
15
 
@@ -12,6 +20,7 @@ module SteelWheel
12
20
  end
13
21
  end
14
22
 
23
+ # rubocop:disable Metrics/MethodLength
15
24
  def self.patch_errors_method_on_instance(mod, klass)
16
25
  class << klass
17
26
  alias_method :__new__, :new
@@ -21,11 +30,13 @@ module SteelWheel
21
30
  instance = __new__(*args)
22
31
  instance.errors.define_singleton_method :full_message do |attribute, message|
23
32
  return message if mod.skip_keys.include?(attribute)
33
+
24
34
  super(attribute, message)
25
35
  end
26
36
  instance
27
37
  end
28
38
  end
39
+ # rubocop:enable Metrics/MethodLength
29
40
 
30
41
  def self.[](*skip_keys)
31
42
  mod = build_module
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SteelWheel
2
- VERSION = '0.5.1'.freeze
4
+ VERSION = '0.6.0'
3
5
  end
data/lib/steel_wheel.rb CHANGED
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'ostruct'
2
4
  require 'easy_params'
3
- require 'flow_object'
5
+ require 'nina'
4
6
  require 'json'
5
7
  require 'active_model'
6
8
  require 'memery'
data/steel_wheel.gemspec CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  lib = File.expand_path('lib', __dir__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
5
  require 'steel_wheel/version'
@@ -23,7 +25,7 @@ Gem::Specification.new do |spec|
23
25
  # spec.metadata['changelog_uri'] = 'TODO: Put your gem's CHANGELOG.md URL here.'
24
26
  else
25
27
  raise 'RubyGems 2.0 or newer is required to protect against ' \
26
- 'public gem pushes.'
28
+ 'public gem pushes.'
27
29
  end
28
30
 
29
31
  # Specify which files should be added to the gem when it is released.
@@ -34,20 +36,13 @@ Gem::Specification.new do |spec|
34
36
  spec.bindir = 'exe'
35
37
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
36
38
  spec.require_paths = ['lib']
37
- spec.required_ruby_version = '>= 2.4'
39
+ spec.required_ruby_version = '>= 2.6'
38
40
 
39
41
  version_string = ['>= 3.2', '< 8']
40
42
 
41
43
  spec.add_runtime_dependency 'railties', version_string
42
44
 
45
+ spec.add_dependency 'easy_params', '~> 0.3'
43
46
  spec.add_dependency 'memery', '~> 1'
44
- spec.add_dependency 'easy_params', '~> 0.1.2'
45
- spec.add_dependency 'flow_object', '~> 0.3.1'
46
-
47
- spec.add_development_dependency 'bundler', '~> 1.17'
48
- spec.add_development_dependency 'pry', '~> 0.10'
49
- spec.add_development_dependency 'rake', '>= 12.3.3'
50
- spec.add_development_dependency 'rspec', '~> 3.0'
51
- spec.add_development_dependency 'simplecov', '0.17'
52
- spec.add_development_dependency 'rspec_vars_helper', '~> 0.1'
47
+ spec.add_dependency 'nina', '~> 0.1.2'
53
48
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: steel_wheel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrii Baran
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-01-29 00:00:00.000000000 Z
11
+ date: 2023-07-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -30,132 +30,48 @@ dependencies:
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '8'
33
- - !ruby/object:Gem::Dependency
34
- name: memery
35
- requirement: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - "~>"
38
- - !ruby/object:Gem::Version
39
- version: '1'
40
- type: :runtime
41
- prerelease: false
42
- version_requirements: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - "~>"
45
- - !ruby/object:Gem::Version
46
- version: '1'
47
33
  - !ruby/object:Gem::Dependency
48
34
  name: easy_params
49
35
  requirement: !ruby/object:Gem::Requirement
50
36
  requirements:
51
37
  - - "~>"
52
38
  - !ruby/object:Gem::Version
53
- version: 0.1.2
39
+ version: '0.3'
54
40
  type: :runtime
55
41
  prerelease: false
56
42
  version_requirements: !ruby/object:Gem::Requirement
57
43
  requirements:
58
44
  - - "~>"
59
45
  - !ruby/object:Gem::Version
60
- version: 0.1.2
46
+ version: '0.3'
61
47
  - !ruby/object:Gem::Dependency
62
- name: flow_object
48
+ name: memery
63
49
  requirement: !ruby/object:Gem::Requirement
64
50
  requirements:
65
51
  - - "~>"
66
52
  - !ruby/object:Gem::Version
67
- version: 0.3.1
53
+ version: '1'
68
54
  type: :runtime
69
55
  prerelease: false
70
56
  version_requirements: !ruby/object:Gem::Requirement
71
57
  requirements:
72
58
  - - "~>"
73
59
  - !ruby/object:Gem::Version
74
- version: 0.3.1
75
- - !ruby/object:Gem::Dependency
76
- name: bundler
77
- requirement: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - "~>"
80
- - !ruby/object:Gem::Version
81
- version: '1.17'
82
- type: :development
83
- prerelease: false
84
- version_requirements: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - "~>"
87
- - !ruby/object:Gem::Version
88
- version: '1.17'
89
- - !ruby/object:Gem::Dependency
90
- name: pry
91
- requirement: !ruby/object:Gem::Requirement
92
- requirements:
93
- - - "~>"
94
- - !ruby/object:Gem::Version
95
- version: '0.10'
96
- type: :development
97
- prerelease: false
98
- version_requirements: !ruby/object:Gem::Requirement
99
- requirements:
100
- - - "~>"
101
- - !ruby/object:Gem::Version
102
- version: '0.10'
103
- - !ruby/object:Gem::Dependency
104
- name: rake
105
- requirement: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - ">="
108
- - !ruby/object:Gem::Version
109
- version: 12.3.3
110
- type: :development
111
- prerelease: false
112
- version_requirements: !ruby/object:Gem::Requirement
113
- requirements:
114
- - - ">="
115
- - !ruby/object:Gem::Version
116
- version: 12.3.3
117
- - !ruby/object:Gem::Dependency
118
- name: rspec
119
- requirement: !ruby/object:Gem::Requirement
120
- requirements:
121
- - - "~>"
122
- - !ruby/object:Gem::Version
123
- version: '3.0'
124
- type: :development
125
- prerelease: false
126
- version_requirements: !ruby/object:Gem::Requirement
127
- requirements:
128
- - - "~>"
129
- - !ruby/object:Gem::Version
130
- version: '3.0'
131
- - !ruby/object:Gem::Dependency
132
- name: simplecov
133
- requirement: !ruby/object:Gem::Requirement
134
- requirements:
135
- - - '='
136
- - !ruby/object:Gem::Version
137
- version: '0.17'
138
- type: :development
139
- prerelease: false
140
- version_requirements: !ruby/object:Gem::Requirement
141
- requirements:
142
- - - '='
143
- - !ruby/object:Gem::Version
144
- version: '0.17'
60
+ version: '1'
145
61
  - !ruby/object:Gem::Dependency
146
- name: rspec_vars_helper
62
+ name: nina
147
63
  requirement: !ruby/object:Gem::Requirement
148
64
  requirements:
149
65
  - - "~>"
150
66
  - !ruby/object:Gem::Version
151
- version: '0.1'
152
- type: :development
67
+ version: 0.1.2
68
+ type: :runtime
153
69
  prerelease: false
154
70
  version_requirements: !ruby/object:Gem::Requirement
155
71
  requirements:
156
72
  - - "~>"
157
73
  - !ruby/object:Gem::Version
158
- version: '0.1'
74
+ version: 0.1.2
159
75
  description: Tiny DSL for code in controllers
160
76
  email:
161
77
  - andriy.baran.v@gmail.com
@@ -163,9 +79,11 @@ executables: []
163
79
  extensions: []
164
80
  extra_rdoc_files: []
165
81
  files:
82
+ - ".codeclimate.yml"
166
83
  - ".github/workflows/ruby.yml"
167
84
  - ".gitignore"
168
85
  - ".rspec"
86
+ - ".rubocop.yml"
169
87
  - ".ruby-version"
170
88
  - ".travis.yml"
171
89
  - CODE_OF_CONDUCT.md
@@ -177,10 +95,12 @@ files:
177
95
  - assets/action_diagram.png
178
96
  - bin/console
179
97
  - bin/setup
98
+ - lib/generators/steel_wheel/application_handler/USAGE
99
+ - lib/generators/steel_wheel/application_handler/application_handler_generator.rb
100
+ - lib/generators/steel_wheel/application_handler/templates/handler_template.rb
180
101
  - lib/generators/steel_wheel/command/USAGE
181
102
  - lib/generators/steel_wheel/command/command_generator.rb
182
103
  - lib/generators/steel_wheel/command/templates/command_template.rb
183
- - lib/generators/steel_wheel/generic_generator.rb
184
104
  - lib/generators/steel_wheel/handler/USAGE
185
105
  - lib/generators/steel_wheel/handler/handler_generator.rb
186
106
  - lib/generators/steel_wheel/handler/templates/handler_template.rb
@@ -206,7 +126,7 @@ metadata:
206
126
  allowed_push_host: https://rubygems.org
207
127
  homepage_uri: https://github.com/andriy-baran/steel_wheel
208
128
  source_code_uri: https://github.com/andriy-baran/steel_wheel
209
- post_install_message:
129
+ post_install_message:
210
130
  rdoc_options: []
211
131
  require_paths:
212
132
  - lib
@@ -214,15 +134,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
214
134
  requirements:
215
135
  - - ">="
216
136
  - !ruby/object:Gem::Version
217
- version: '2.4'
137
+ version: '2.6'
218
138
  required_rubygems_version: !ruby/object:Gem::Requirement
219
139
  requirements:
220
140
  - - ">="
221
141
  - !ruby/object:Gem::Version
222
142
  version: '0'
223
143
  requirements: []
224
- rubygems_version: 3.2.30
225
- signing_key:
144
+ rubygems_version: 3.2.22
145
+ signing_key:
226
146
  specification_version: 4
227
147
  summary: Adds operations to your rails code
228
148
  test_files: []
@@ -1,23 +0,0 @@
1
- module SteelWheel
2
- class GenericGenerator < Rails::Generators::NamedBase
3
- def self.setup_templates_root(templates_relative_path)
4
- source_root File.expand_path(templates_relative_path, __dir__)
5
- end
6
-
7
- def self.on_revoke(&block)
8
- block_given? ? @on_revoke = block : @on_revoke
9
- end
10
-
11
- def self.on_invoke(&block)
12
- block_given? ? @on_invoke = block : @on_invoke
13
- end
14
-
15
- def copy_files
16
- if behavior == :revoke
17
- instance_eval(&self.class.on_revoke)
18
- elsif behavior == :invoke
19
- instance_eval(&self.class.on_invoke)
20
- end
21
- end
22
- end
23
- end