strum 0.0.55 → 0.1.3

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.
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: []