strum 0.0.56 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce5316836aff5a84ce5be1cb3af9445b5ebc80ba3c739626483929bb9ff7538d
4
- data.tar.gz: ed3b056c7ab24e67efd4cae7e0ac5ddd31f981099c6911b9e11b659bd42af315
3
+ metadata.gz: e42ae1ed242ca62b4424ebeb549eaccbd54f3b66348fb31bc7d65f457efdf1a0
4
+ data.tar.gz: a86f1a2c6d32b9c211b68702514411da590801ecbc6637b40a5a88f9d47f6699
5
5
  SHA512:
6
- metadata.gz: 622ed6bc448d6f0124b09d159ae9801478a8ef526cbb56ec4f948647f38ea7fc54df863722e5512e0e2b2391db07239dd7ef93d282f994ecf8e7cc3acfe28dc9
7
- data.tar.gz: db63d55f2a5ec36480e02f5dacf922f252f1a504a64af59c68fda4f500460436cc325702642a983c29e375d72a859c2b3aad1879edbf82257e2adf72a5a16586
6
+ metadata.gz: dfa1308d4b365e7ab7a0d945dadcc0289908e8e17760d2cde18741a3206ebd618d4d300250f92158825906a0c472866474084c24151da7e12baad9b670b3448f
7
+ data.tar.gz: 64482d3661a03579d1944723969d74e7b2f4c582e0e3386eb05391ab6796c6740e5acf8c95452c156fe2d05c5cdf8ac604a84261623166a5697a4b8c2e591bec
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- strum (0.0.56)
4
+ strum (0.1.0)
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,7 +51,7 @@ 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
56
  public_suffix (4.0.3)
57
57
  rainbow (3.0.0)
@@ -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,102 @@
1
+ require "strum/service"
2
+ require "json-schema"
3
+
4
+ module Strum
5
+ module JsonSchema
6
+ class Validate
7
+ include Strum::Service
8
+
9
+ def call
10
+ array_errors = JSON::Validator.fully_validate(args[:schema], input, errors_as_objects: true)
11
+ array_errors.each { |error| add_error(*self.parse_json_schema_error(error)) }
12
+ output(input)
13
+ end
14
+
15
+ def audit
16
+ add_error(:schema, :not_found) if !args[:schema].is_a?(Hash)
17
+ end
18
+
19
+ protected
20
+
21
+ def parse_json_schema_error(error)
22
+ id = error[:fragment].sub(/#/, "input")
23
+ keys = id.split("/")
24
+ last_key_idx = keys.rindex { |key| key !~ /[0-9]+/ }
25
+ last_key = keys.map { |key| key =~ /[0-9]+/ ? "[#{key}]" : ".#{key}" }.join[1..-1]
26
+ value = error[:message][0, error[:message].index(/ in schema/)].sub(error[:fragment], last_key)
27
+ [last_key.to_sym, value]
28
+ end
29
+ end
30
+
31
+ class Cast
32
+ include Strum::Service
33
+
34
+ def call
35
+ output(casted(input, args[:schema]))
36
+ end
37
+
38
+ def audit
39
+ add_error(:schema, :not_found) if !args[:schema].is_a?(Hash)
40
+ end
41
+
42
+ protected
43
+
44
+ def casted(input_data, schema)
45
+ @input_data = input_data
46
+
47
+ def rec_casted(schema, path = [])
48
+ item = self.custom_dig(@input_data, path)
49
+
50
+ if item.is_a?(NoValue)
51
+ return item
52
+ end
53
+
54
+ case schema[:type]
55
+ when Array
56
+ schema[:type].reduce(nil) do |type, x|
57
+ new_schema = schema.clone
58
+ new_schema[:type] = x
59
+ type ||= rec_casted(new_schema, path)
60
+ end
61
+ when "object"
62
+ if item.is_a?(Hash) && schema[:properties].is_a?(Hash)
63
+ schema[:properties].map { |key, val| [key, rec_casted(val, path + [key])] }.filter { |pair| !pair[1].is_a?(NoValue) }.to_h
64
+ end
65
+ when "array"
66
+ if item.is_a?(Array) && schema[:items].is_a?(Hash)
67
+ (0..(item.length - 1)).reduce([]) { |res, idx| res << rec_casted(schema[:items], path + [idx]) }
68
+ end
69
+ when "string"
70
+ item.to_s
71
+ when "integer"
72
+ if item.is_a?(Numeric)
73
+ item
74
+ elsif item.is_a?(String) || item.is_a?(Symbol)
75
+ item.to_s.to_i
76
+ end
77
+ when "boolean"
78
+ item.to_s.downcase == "true"
79
+ when "jsonb"
80
+ if (Module.constants.include?(:Sequel)) && (Sequel.methods.include?(:pg_jsonb_wrap))
81
+ Sequel.pg_jsonb_wrap(item)
82
+ else
83
+ add_error(:schema, "jsonb type is not supported")
84
+ end
85
+ when nil, ""
86
+ item
87
+ else
88
+ add_error(:schema, :invalid_type)
89
+ end
90
+ end
91
+
92
+ rec_casted(schema)
93
+ end
94
+
95
+ def custom_dig(obj, path)
96
+ path.reduce(obj) { |item, x| item.fetch(x) { |it| return NoValue.new } }
97
+ end
98
+ end
99
+
100
+ class NoValue; end
101
+ end
102
+ end
@@ -4,13 +4,13 @@ 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)
@@ -24,6 +24,15 @@ module Strum
24
24
  raise Strum::Error, "Unit options must be a Hash" unless service_params.is_a?(Hash)
25
25
 
26
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
27
36
  clean_output = service_params[:clean_output] || false
28
37
  unit_payload = if !clean_output && service_options.is_a?(Hash) && pipe_unit_inputs.is_a?(Hash) && output_value.is_a?(Hash)
29
38
  pipe_unit_inputs.merge(service_options).merge(output_value)
@@ -31,21 +40,21 @@ module Strum
31
40
  output_value
32
41
  end
33
42
 
34
- service.public_send(:call, unit_payload) do |m|
35
- service_handlers[:on].each do |k, _handler|
36
- m.on(k) { |r| hook(k, 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) }
37
46
  end
38
47
 
39
- service_handlers[:success].each do |k, _handler|
40
- if k
41
- m.success(k) do |result|
42
- output(k, result)
48
+ service_handlers[:success].each do |key, _handler|
49
+ if key
50
+ m.success(key) do |result|
51
+ output(key, result)
43
52
  continue = false
44
53
  end
45
54
  else
46
55
  m.success do |result|
47
- if result.nil?
48
- # do nothing if service hasn't result
56
+ if result_place
57
+ inputs[result_place] = result
49
58
  elsif !clean_output && result.is_a?(Hash) && output_value.is_a?(Hash)
50
59
  output(output_value.merge(result))
51
60
  else
@@ -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,19 +156,6 @@ 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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Strum
4
- VERSION = "0.0.56"
4
+ VERSION = "0.1.0"
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.56
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Serhiy Nazarov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-18 00:00:00.000000000 Z
11
+ date: 2020-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json-schema
@@ -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,7 @@ 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
204
206
  - lib/strum/json_serializer.rb
205
207
  - lib/strum/object_to_hash.rb
206
208
  - lib/strum/pipe.rb