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 +4 -4
- data/Gemfile.lock +7 -7
- data/bin/console +15 -0
- data/lib/strum.rb +1 -1
- data/lib/strum/json_schema.rb +10 -0
- data/lib/strum/json_schema/cast.rb +68 -0
- data/lib/strum/json_schema/validate.rb +32 -0
- data/lib/strum/pipe.rb +33 -10
- data/lib/strum/service.rb +28 -26
- data/lib/strum/templates/service_crud/%resources_name%/detect.rb.tt +30 -0
- data/lib/strum/version.rb +1 -1
- metadata +11 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2894aeec506a3e5b1c5cccd983228dc14c6f13bc62166aefc6878007fee03275
|
4
|
+
data.tar.gz: 6c49b3f69a66be577487ee919c6de9c8bba55a5ed46d3813ca6a27e5349bcbf3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 779accb4860d77be95cbace472f22b0379e87584f89fb84d2f219b7b77c428d5190a268fd0fa5c694151b511d8f16b197da5e9e249c5b9c9d23e3b156fd8679a
|
7
|
+
data.tar.gz: a03cb94bfca668a7d6b24956cd6b4c0445c234f932f8508d966a727e5eb9bac3e5d20e070bbf4dc4307c3c891673786d3f9325d4d27165aa5b917e1b2882d6df
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
strum (0.
|
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.
|
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.
|
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.
|
54
|
+
parser (2.7.0.5)
|
55
55
|
ast (~> 2.4.0)
|
56
|
-
public_suffix (4.0.
|
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.
|
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.
|
82
|
+
sequel (5.30.0)
|
83
83
|
sequel-annotate (1.4.0)
|
84
84
|
sequel (>= 4)
|
85
85
|
thor (0.20.3)
|
data/bin/console
ADDED
@@ -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__)
|
data/lib/strum.rb
CHANGED
@@ -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
|
data/lib/strum/pipe.rb
CHANGED
@@ -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
|
-
|
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 |
|
35
|
-
m.on(
|
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
|
-
|
38
|
-
|
39
|
-
|
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
|
-
|
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
|
data/lib/strum/service.rb
CHANGED
@@ -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
|
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.
|
28
|
-
self.
|
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 :
|
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
|
-
|
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
|
-
|
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
|
-
|
172
|
-
handler
|
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 -%>
|
data/lib/strum/version.rb
CHANGED
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.
|
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-
|
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: []
|