strum 0.0.55 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 442b975d036c77d40e013582ed6c45f27ed77b1ccd01975dbec3aa89d28c2115
4
- data.tar.gz: 6bc0253b8e8b8ab605129e3b34486ca54ba36378528e894d6481b08349af4e38
3
+ metadata.gz: 2894aeec506a3e5b1c5cccd983228dc14c6f13bc62166aefc6878007fee03275
4
+ data.tar.gz: 6c49b3f69a66be577487ee919c6de9c8bba55a5ed46d3813ca6a27e5349bcbf3
5
5
  SHA512:
6
- metadata.gz: 00f7d03f21b91ed6ae174202a7336dacb6c2cef4f2bba369fed16db5812e3188e46938cb0792c170cfe218b4d9cb8df5844109912d000ee89b11f2aad9d5ee01
7
- data.tar.gz: 3eee0dc77298cd2e6e2138932de91bde002208d6709d4128bdf26a00f872019f0ea58fac0271891e609d78908d12857f96cdb53113305f5b49a1fbc6fbdd9173
6
+ metadata.gz: 779accb4860d77be95cbace472f22b0379e87584f89fb84d2f219b7b77c428d5190a268fd0fa5c694151b511d8f16b197da5e9e249c5b9c9d23e3b156fd8679a
7
+ data.tar.gz: a03cb94bfca668a7d6b24956cd6b4c0445c234f932f8508d966a727e5eb9bac3e5d20e070bbf4dc4307c3c891673786d3f9325d4d27165aa5b917e1b2882d6df
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- strum (0.0.55)
4
+ strum (0.1.2)
5
5
  dry-inflector (~> 0.2.0)
6
6
  dry-struct (~> 1.2)
7
7
  json-schema (~> 2.8.1)
@@ -16,7 +16,7 @@ GEM
16
16
  ast (2.4.0)
17
17
  concurrent-ruby (1.1.6)
18
18
  diff-lcs (1.3)
19
- dry-configurable (0.11.3)
19
+ dry-configurable (0.11.5)
20
20
  concurrent-ruby (~> 1.0)
21
21
  dry-core (~> 0.4, >= 0.4.7)
22
22
  dry-equalizer (~> 0.2)
@@ -36,7 +36,7 @@ GEM
36
36
  dry-equalizer (~> 0.3)
37
37
  dry-types (~> 1.3)
38
38
  ice_nine (~> 0.11)
39
- dry-types (1.3.1)
39
+ dry-types (1.4.0)
40
40
  concurrent-ruby (~> 1.0)
41
41
  dry-container (~> 0.3)
42
42
  dry-core (~> 0.4, >= 0.4.4)
@@ -51,9 +51,9 @@ GEM
51
51
  json-schema (2.8.1)
52
52
  addressable (>= 2.4)
53
53
  parallel (1.19.1)
54
- parser (2.7.0.3)
54
+ parser (2.7.0.5)
55
55
  ast (~> 2.4.0)
56
- public_suffix (4.0.3)
56
+ public_suffix (4.0.4)
57
57
  rainbow (3.0.0)
58
58
  rake (10.5.0)
59
59
  reline (0.1.3)
@@ -64,7 +64,7 @@ GEM
64
64
  rspec-mocks (~> 3.9.0)
65
65
  rspec-core (3.9.1)
66
66
  rspec-support (~> 3.9.1)
67
- rspec-expectations (3.9.0)
67
+ rspec-expectations (3.9.1)
68
68
  diff-lcs (>= 1.2.0, < 2.0)
69
69
  rspec-support (~> 3.9.0)
70
70
  rspec-mocks (3.9.1)
@@ -79,7 +79,7 @@ GEM
79
79
  ruby-progressbar (~> 1.7)
80
80
  unicode-display_width (>= 1.4.0, < 1.7)
81
81
  ruby-progressbar (1.10.1)
82
- sequel (5.29.0)
82
+ sequel (5.30.0)
83
83
  sequel-annotate (1.4.0)
84
84
  sequel (>= 4)
85
85
  thor (0.20.3)
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "strum"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
@@ -2,10 +2,10 @@
2
2
 
3
3
  require "strum/version"
4
4
  require "strum/service"
5
- require "strum/chain"
6
5
  require "strum/pipe"
7
6
  require "strum/json"
8
7
  require "strum/deep_keys_to_sym"
8
+ require "strum/json_schema"
9
9
 
10
10
  module Strum
11
11
  class Error < StandardError; end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "strum/json_schema/validate"
4
+ require "strum/json_schema/cast"
5
+
6
+ module Strum
7
+ module JsonSchema
8
+ class NoValue; end
9
+ end
10
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "strum/service"
4
+
5
+ module Strum
6
+ module JsonSchema
7
+ class Cast
8
+ include Strum::Service
9
+
10
+ def call
11
+ output(casted(input, args[:schema]))
12
+ end
13
+
14
+ def audit
15
+ add_error(:schema, :not_found) if !args[:schema].is_a?(Hash)
16
+ end
17
+
18
+ protected
19
+
20
+ def casted(input_data, schema, path = [])
21
+ item = custom_dig(input_data, path)
22
+
23
+ return item if item.is_a?(NoValue)
24
+
25
+ case schema[:type]
26
+ when Array
27
+ schema[:type].reduce(nil) do |type, x|
28
+ new_schema = schema.clone
29
+ new_schema[:type] = x
30
+ type || casted(input_data, new_schema, path)
31
+ end
32
+ when "object"
33
+ if item.is_a?(Hash) && schema[:properties].is_a?(Hash)
34
+ item.map { |key, val| (prop = schema[:properties][key]) ? [key, casted(input_data, prop, path + [key])] : [key, val]}.filter { |pair| !pair[1].is_a?(NoValue) }.to_h
35
+ end
36
+ when "array"
37
+ if item.is_a?(Array) && schema[:items].is_a?(Hash)
38
+ (0..(item.length - 1)).reduce([]) { |res, idx| res << casted(input_data, schema[:items], path + [idx]) }
39
+ end
40
+ when "string"
41
+ item.to_s
42
+ when "integer", "number"
43
+ if item.is_a?(Numeric)
44
+ item
45
+ elsif item.is_a?(String) || item.is_a?(Symbol)
46
+ (item.to_s.to_f % 1) > 0 ? item.to_s.to_f : item.to_s.to_i
47
+ end
48
+ when "boolean"
49
+ item.to_s.downcase == "true"
50
+ when "jsonb"
51
+ if Module.constants.include?(:Sequel) && Sequel.methods.include?(:pg_jsonb_wrap)
52
+ Sequel.pg_jsonb_wrap(item)
53
+ else
54
+ add_error(:schema, "jsonb type is not supported")
55
+ end
56
+ when nil, ""
57
+ item
58
+ else
59
+ add_error(:schema, :invalid_type)
60
+ end
61
+ end
62
+
63
+ def custom_dig(obj, path)
64
+ path.reduce(obj) { |item, x| item.fetch(x) { |_it| return NoValue.new } }
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "strum/service"
4
+ require "json-schema"
5
+
6
+ module Strum
7
+ module JsonSchema
8
+ class Validate
9
+ include Strum::Service
10
+
11
+ def call
12
+ array_errors = JSON::Validator.fully_validate(args[:schema], input, errors_as_objects: true)
13
+ array_errors.each { |error| add_error(*parse_json_schema_error(error)) }
14
+ output(input)
15
+ end
16
+
17
+ def audit
18
+ add_error(:schema, :not_found) if !args[:schema].is_a?(Hash)
19
+ end
20
+
21
+ protected
22
+
23
+ def parse_json_schema_error(error)
24
+ id = error[:fragment].sub(/#/, "input")
25
+ keys = id.split("/")
26
+ last_key = keys.map { |key| key =~ /[0-9]+/ ? "[#{key}]" : ".#{key}" }.join[1..-1]
27
+ value = error[:message][0, error[:message].index(/ in schema/)].sub(error[:fragment], last_key)
28
+ [last_key.to_sym, value]
29
+ end
30
+ end
31
+ end
32
+ end
@@ -4,25 +4,35 @@ module Strum
4
4
  class Pipe
5
5
  include Strum::Service
6
6
 
7
- def self.call(*units, input: {}, unit_input: {}, &block)
7
+ def self.call(*units, args: {}, input: {}, unit_input: {}, &block)
8
8
  pipe_payload = if input.is_a?(Hash) && unit_input.is_a?(Hash)
9
9
  unit_input.merge(input)
10
10
  else
11
11
  input
12
12
  end
13
- new(pipe_payload).execute(*units, input, unit_input, &block)
13
+ new(pipe_payload, args).execute(*units, input, unit_input, &block)
14
14
  end
15
15
 
16
16
  def execute(*units, pipe_inputs, pipe_unit_inputs, &block)
17
17
  audit
18
18
  yield(self) if valid? && block_given?
19
19
  output(pipe_inputs)
20
- while (unit = units.shift) && valid?
20
+ continue = true
21
+ while (unit = units.shift) && valid? && continue
21
22
  service, service_params = unit
22
23
  service_params ||= {}
23
24
  raise Strum::Error, "Unit options must be a Hash" unless service_params.is_a?(Hash)
24
25
 
25
26
  service_options = service_params[:input] || {}
27
+ result_place = service_params[:to]
28
+ unit_args = case service_params[:args]
29
+ when Hash
30
+ service_params[:args]
31
+ when Symbol, String
32
+ { service_params[:args] => service_params[:args] }
33
+ else
34
+ {}
35
+ end
26
36
  clean_output = service_params[:clean_output] || false
27
37
  unit_payload = if !clean_output && service_options.is_a?(Hash) && pipe_unit_inputs.is_a?(Hash) && output_value.is_a?(Hash)
28
38
  pipe_unit_inputs.merge(service_options).merge(output_value)
@@ -30,17 +40,30 @@ module Strum
30
40
  output_value
31
41
  end
32
42
 
33
- service.public_send(:call, unit_payload) do |m|
34
- service_handlers[:on].each do |k, proc|
35
- m.on(k) { |r| proc.call(r) }
43
+ service.public_send(:call, unit_payload, args.merge(unit_args)) do |m|
44
+ service_handlers[:on].each do |key, _handler|
45
+ m.on(key) { |r| hook(k, r) }
36
46
  end
37
- m.success do |result|
38
- if !clean_output && result.is_a?(Hash) && output_value.is_a?(Hash)
39
- output(output_value.merge(result))
47
+
48
+ service_handlers[:success].each do |key, _handler|
49
+ if key
50
+ m.success(key) do |result|
51
+ output(key, result)
52
+ continue = false
53
+ end
40
54
  else
41
- output(result)
55
+ m.success do |result|
56
+ if result_place
57
+ inputs[result_place] = result
58
+ elsif !clean_output && result.is_a?(Hash) && output_value.is_a?(Hash)
59
+ output(output_value.merge(result))
60
+ elsif result
61
+ output(result)
62
+ end
63
+ end
42
64
  end
43
65
  end
66
+
44
67
  m.failure { |errors| add_errors(errors) }
45
68
  end
46
69
  end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require "json-schema"
3
2
 
4
3
  module Strum
5
4
  # Module
@@ -14,19 +13,18 @@ module Strum
14
13
 
15
14
  # Internal: Interactor class methods.
16
15
  module ClassMethods
17
- def call(_input = nil, &block)
18
- new(_input).execute(&block)
16
+ def call(_input, **args, &block)
17
+ new(_input, args).execute(&block)
19
18
  end
20
19
  end
21
20
 
22
21
  # Instance methods
23
- def initialize(_input)
22
+ def initialize(_input, **args)
24
23
  self.strum_errors = {}
25
24
  self.service_handlers = { on: {}, success: {}, failure: {} }
26
25
  self.outputs = {}
27
- self._input = _input
28
- self._input.freeze
29
- self.input = self._input.dup
26
+ self.inputs = args.merge(default: _input)
27
+ self._inputs = inputs.dup.freeze
30
28
  end
31
29
 
32
30
  def execute
@@ -72,7 +70,7 @@ module Strum
72
70
 
73
71
  protected
74
72
 
75
- attr_accessor :_input, :input, :strum_errors, :outputs, :service_handlers
73
+ attr_accessor :inputs, :_inputs, :strum_errors, :outputs, :service_handlers
76
74
 
77
75
  def call
78
76
  raise Failure, "call method must be implemented"
@@ -80,6 +78,22 @@ module Strum
80
78
 
81
79
  def audit; end
82
80
 
81
+ def input
82
+ inputs[:default]
83
+ end
84
+
85
+ def input=(value)
86
+ inputs[:default] = value
87
+ end
88
+
89
+ def _input
90
+ _inputs[:default]
91
+ end
92
+
93
+ def args
94
+ inputs.slice(*inputs.keys - [:default])
95
+ end
96
+
83
97
  def output_value(key = :default)
84
98
  @outputs[key]
85
99
  end
@@ -122,7 +136,7 @@ module Strum
122
136
 
123
137
  def sliced(*keys)
124
138
  if input.is_a?(Hash)
125
- @input = input.slice(*keys)
139
+ self.input = input.slice(*keys)
126
140
  else
127
141
  add_error(:input, :must_be_hash)
128
142
  end
@@ -130,7 +144,7 @@ module Strum
130
144
 
131
145
  def sliced_list(*keys)
132
146
  if input.is_a?(Array)
133
- @input = input.map do |item|
147
+ self.input = input.map do |item|
134
148
  if item.is_a?(Hash)
135
149
  item = item.slice(*keys)
136
150
  else
@@ -142,25 +156,12 @@ module Strum
142
156
  end
143
157
  end
144
158
 
145
- def validated(schema:, list: false)
146
- array_errors = JSON::Validator.fully_validate(schema, @input, errors_as_objects: true, list: list)
147
- array_errors.each{|error| add_error(*self.parse_json_schema_error(error))}
148
- end
149
-
150
- def parse_json_schema_error(error)
151
- pos_match = error[:fragment].match(/([0-9]+)[\/]?/)
152
- pos = pos_match.is_a?(Array) ? pos_match[1] : "_"
153
- key = error[:fragment].sub(/#\//, "").sub(/([0-9]+)[\/]?/, "")
154
- value = "Item ##{pos}. " + error[:message][0, error[:message].index(/ in schema/)].sub(/#\//, "").sub(/([0-9]+)[\/]?/, "")
155
- [key.to_sym, value]
156
- end
157
-
158
159
  def array!
159
160
  self.input = [*input]
160
161
  end
161
162
 
162
163
  private
163
-
164
+
164
165
  def key_to_sym(key)
165
166
  key.to_sym
166
167
  rescue StandardError
@@ -168,8 +169,9 @@ module Strum
168
169
  end
169
170
 
170
171
  def valid_result
171
- handler = service_handlers[:success][((outputs.keys << nil) & service_handlers[:success].keys).first]
172
- handler.is_a?(Proc) ? handler.call(outputs[:default] || outputs) : outputs[:default] || outputs
172
+ handler_key = ((outputs.keys << nil) & service_handlers[:success].keys).first
173
+ handler = service_handlers[:success][handler_key]
174
+ handler.is_a?(Proc) ? handler.call(outputs[handler_key] || outputs[:default]) : outputs[handler_key] || outputs[:default]
173
175
  end
174
176
 
175
177
  def invalid_result
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ <%- namespace_names.each_with_index do |c,i| -%>
4
+ <%= ' ' * i %>module <%= c %>
5
+ <%- end -%>
6
+ <%= ident %>module <%= resources_class_name %>
7
+ <%= ident %> # Strum service
8
+ <%= ident %> # You service description here...
9
+ <%= ident %> class Find
10
+ <%= ident %> include Strum::Service
11
+
12
+ <%= ident %> def call
13
+ <%= ident %> if (<%= resources_name %> = <%= resources_class_name %>::Search(input)).count.eql?(1)
14
+ <%= ident %> output(resources_name: <%= resources_name %>.first)
15
+ <%= ident %> elsif <%= resources_name %>.count > 1
16
+ <%= ident %> add_error(:<%= resource_name %>, :criteria_wrong)
17
+ <%= ident %> else
18
+ <%= ident %> add_error(:<%= resource_name %>, :not_found)
19
+ <%= ident %> end
20
+ <%= ident %> end
21
+
22
+ <%= ident %> def audit
23
+ <%= ident %> @input = @input.slice(:id)
24
+ <%= ident %> required(:id)
25
+ <%= ident %> end
26
+ <%= ident %> end
27
+ <%= ident %>end
28
+ <%- (namespace_names.size - 1).downto(0) do |i| -%>
29
+ <%= ' ' * i %>end
30
+ <%- end -%>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Strum
4
- VERSION = "0.0.55"
4
+ VERSION = "0.1.3"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: strum
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.55
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Serhiy Nazarov
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-07 00:00:00.000000000 Z
11
+ date: 2020-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json-schema
@@ -164,7 +164,7 @@ dependencies:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
166
  version: 1.4.0
167
- description:
167
+ description:
168
168
  email:
169
169
  - sn@nazarov.com.ua
170
170
  executables:
@@ -181,6 +181,7 @@ files:
181
181
  - Gemfile.lock
182
182
  - README.md
183
183
  - Rakefile
184
+ - bin/console
184
185
  - bin/strum
185
186
  - lib/strum.rb
186
187
  - lib/strum/Rakefile
@@ -201,6 +202,9 @@ files:
201
202
  - lib/strum/deep_keys_to_sym.rb
202
203
  - lib/strum/json.rb
203
204
  - lib/strum/json_deserializer.rb
205
+ - lib/strum/json_schema.rb
206
+ - lib/strum/json_schema/cast.rb
207
+ - lib/strum/json_schema/validate.rb
204
208
  - lib/strum/json_serializer.rb
205
209
  - lib/strum/object_to_hash.rb
206
210
  - lib/strum/pipe.rb
@@ -236,6 +240,7 @@ files:
236
240
  - lib/strum/templates/service/%resource_filename%.rb.tt
237
241
  - lib/strum/templates/service_crud/%resources_name%/create.rb.tt
238
242
  - lib/strum/templates/service_crud/%resources_name%/delete.rb.tt
243
+ - lib/strum/templates/service_crud/%resources_name%/detect.rb.tt
239
244
  - lib/strum/templates/service_crud/%resources_name%/find.rb.tt
240
245
  - lib/strum/templates/service_crud/%resources_name%/search.rb.tt
241
246
  - lib/strum/templates/service_crud/%resources_name%/update.rb.tt
@@ -248,7 +253,7 @@ metadata:
248
253
  homepage_uri: https://code.qpard.com/strum/strum
249
254
  source_code_uri: https://code.qpard.com/strum/strum
250
255
  changelog_uri: https://code.qpard.com/strum/strum/CHANGELOG.md
251
- post_install_message:
256
+ post_install_message:
252
257
  rdoc_options: []
253
258
  require_paths:
254
259
  - lib
@@ -264,7 +269,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
264
269
  version: '0'
265
270
  requirements: []
266
271
  rubygems_version: 3.0.3
267
- signing_key:
272
+ signing_key:
268
273
  specification_version: 4
269
274
  summary: Light ruby framework.
270
275
  test_files: []