servactory 1.9.6 → 2.0.0.rc3
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/config/locales/en.yml +19 -4
- data/config/locales/ru.yml +21 -6
- data/lib/servactory/configuration/dsl.rb +2 -0
- data/lib/servactory/configuration/factory.rb +8 -0
- data/lib/servactory/configuration/setup.rb +20 -4
- data/lib/servactory/context/workspace/inputs.rb +41 -7
- data/lib/servactory/context/workspace/outputs.rb +1 -1
- data/lib/servactory/context/workspace.rb +0 -1
- data/lib/servactory/dsl.rb +17 -0
- data/lib/servactory/inputs/collection.rb +1 -1
- data/lib/servactory/inputs/dsl.rb +2 -0
- data/lib/servactory/inputs/input.rb +101 -82
- data/lib/servactory/inputs/tools/distributor.rb +24 -0
- data/lib/servactory/inputs/tools/rules.rb +3 -3
- data/lib/servactory/inputs/tools/{find_unnecessary.rb → unnecessary.rb} +4 -4
- data/lib/servactory/inputs/tools/validation.rb +5 -7
- data/lib/servactory/inputs/validations/base.rb +1 -1
- data/lib/servactory/inputs/validations/inclusion.rb +15 -10
- data/lib/servactory/inputs/validations/must.rb +26 -17
- data/lib/servactory/inputs/validations/required.rb +16 -11
- data/lib/servactory/inputs/validations/type.rb +19 -69
- data/lib/servactory/inputs/workspace.rb +6 -3
- data/lib/servactory/internals/dsl.rb +6 -1
- data/lib/servactory/internals/internal.rb +82 -14
- data/lib/servactory/internals/validations/base.rb +1 -1
- data/lib/servactory/internals/validations/type.rb +6 -43
- data/lib/servactory/maintenance/attributes/define_conflict.rb +15 -0
- data/lib/servactory/maintenance/attributes/define_method.rb +17 -0
- data/lib/servactory/maintenance/attributes/option.rb +115 -0
- data/lib/servactory/maintenance/attributes/option_helper.rb +17 -0
- data/lib/servactory/maintenance/attributes/option_helpers_collection.rb +20 -0
- data/lib/servactory/maintenance/attributes/options_collection.rb +48 -0
- data/lib/servactory/maintenance/collection_mode/class_names_collection.rb +16 -0
- data/lib/servactory/maintenance/hash_mode/class_names_collection.rb +16 -0
- data/lib/servactory/maintenance/validations/collection.rb +66 -0
- data/lib/servactory/maintenance/validations/object_schema.rb +116 -0
- data/lib/servactory/maintenance/validations/types.rb +164 -0
- data/lib/servactory/methods/workspace.rb +2 -0
- data/lib/servactory/outputs/dsl.rb +6 -1
- data/lib/servactory/outputs/output.rb +80 -19
- data/lib/servactory/outputs/validations/base.rb +1 -1
- data/lib/servactory/outputs/validations/type.rb +6 -45
- data/lib/servactory/version.rb +5 -4
- metadata +17 -11
- data/lib/servactory/inputs/define_input_conflict.rb +0 -13
- data/lib/servactory/inputs/define_input_method.rb +0 -15
- data/lib/servactory/inputs/option.rb +0 -98
- data/lib/servactory/inputs/option_helper.rb +0 -15
- data/lib/servactory/inputs/option_helpers_collection.rb +0 -18
- data/lib/servactory/inputs/options_collection.rb +0 -46
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module Maintenance
|
5
|
+
module Attributes
|
6
|
+
class DefineMethod
|
7
|
+
attr_reader :name,
|
8
|
+
:content
|
9
|
+
|
10
|
+
def initialize(name:, content:)
|
11
|
+
@name = name.to_sym
|
12
|
+
@content = content
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module Maintenance
|
5
|
+
module Attributes
|
6
|
+
class Option
|
7
|
+
DEFAULT_BODY = ->(key:, body:, message: nil) { { key => body, message: message } }
|
8
|
+
|
9
|
+
private_constant :DEFAULT_BODY
|
10
|
+
|
11
|
+
attr_reader :name,
|
12
|
+
:validation_class,
|
13
|
+
:define_methods,
|
14
|
+
:define_conflicts,
|
15
|
+
:need_for_checks,
|
16
|
+
:body
|
17
|
+
|
18
|
+
# rubocop:disable Metrics/MethodLength
|
19
|
+
def initialize(
|
20
|
+
name:,
|
21
|
+
attribute:,
|
22
|
+
validation_class:,
|
23
|
+
need_for_checks:,
|
24
|
+
body_fallback:,
|
25
|
+
original_value: nil,
|
26
|
+
body_key: nil,
|
27
|
+
body_value: true,
|
28
|
+
define_methods: nil,
|
29
|
+
define_conflicts: nil,
|
30
|
+
with_advanced_mode: true,
|
31
|
+
**options
|
32
|
+
) # do
|
33
|
+
@name = name.to_sym
|
34
|
+
@validation_class = validation_class
|
35
|
+
@define_methods = define_methods
|
36
|
+
@define_conflicts = define_conflicts
|
37
|
+
@need_for_checks = need_for_checks
|
38
|
+
|
39
|
+
@body = prepare_value_for(
|
40
|
+
original_value: original_value,
|
41
|
+
options: options,
|
42
|
+
body_key: body_key,
|
43
|
+
body_value: body_value,
|
44
|
+
body_fallback: body_fallback,
|
45
|
+
with_advanced_mode: with_advanced_mode
|
46
|
+
)
|
47
|
+
|
48
|
+
prepare_methods_for(attribute)
|
49
|
+
end
|
50
|
+
# rubocop:enable Metrics/MethodLength
|
51
|
+
|
52
|
+
def need_for_checks?
|
53
|
+
need_for_checks
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def prepare_value_for(
|
59
|
+
original_value:,
|
60
|
+
options:,
|
61
|
+
body_key:,
|
62
|
+
body_value:,
|
63
|
+
body_fallback:,
|
64
|
+
with_advanced_mode:
|
65
|
+
)
|
66
|
+
return original_value if original_value.present?
|
67
|
+
|
68
|
+
return options.fetch(@name, body_fallback) unless with_advanced_mode
|
69
|
+
|
70
|
+
prepare_advanced_for(
|
71
|
+
body: options.fetch(@name, DEFAULT_BODY.call(key: body_key, body: body_fallback)),
|
72
|
+
body_key: body_key,
|
73
|
+
body_value: body_value,
|
74
|
+
body_fallback: body_fallback
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
def prepare_advanced_for(
|
79
|
+
body:,
|
80
|
+
body_key:,
|
81
|
+
body_value:,
|
82
|
+
body_fallback:
|
83
|
+
)
|
84
|
+
if body.is_a?(Hash)
|
85
|
+
message = body.fetch(:message, nil)
|
86
|
+
|
87
|
+
DEFAULT_BODY.call(
|
88
|
+
key: body_key,
|
89
|
+
body: body.fetch(body_key, message.present? ? body_value : body_fallback),
|
90
|
+
message: message
|
91
|
+
)
|
92
|
+
else
|
93
|
+
DEFAULT_BODY.call(key: body_key, body: body)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def prepare_methods_for(attribute)
|
98
|
+
attribute.instance_eval(define_methods_template) if define_methods_template.present?
|
99
|
+
end
|
100
|
+
|
101
|
+
def define_methods_template
|
102
|
+
return if @define_methods.blank?
|
103
|
+
|
104
|
+
@define_methods_template ||= @define_methods.map do |define_method|
|
105
|
+
<<-RUBY
|
106
|
+
def #{define_method.name}
|
107
|
+
#{define_method.content.call(option: @body)}
|
108
|
+
end
|
109
|
+
RUBY
|
110
|
+
end.join("\n")
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module Maintenance
|
5
|
+
module Attributes
|
6
|
+
class OptionHelper
|
7
|
+
attr_reader :name,
|
8
|
+
:equivalent
|
9
|
+
|
10
|
+
def initialize(name:, equivalent:)
|
11
|
+
@name = name
|
12
|
+
@equivalent = equivalent
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module Maintenance
|
5
|
+
module Attributes
|
6
|
+
class OptionHelpersCollection
|
7
|
+
extend Forwardable
|
8
|
+
def_delegators :@collection, :<<, :find, :merge
|
9
|
+
|
10
|
+
def initialize(collection)
|
11
|
+
@collection = collection
|
12
|
+
end
|
13
|
+
|
14
|
+
def find_by(name:)
|
15
|
+
find { |helper| helper.name == name }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module Maintenance
|
5
|
+
module Attributes
|
6
|
+
class OptionsCollection
|
7
|
+
extend Forwardable
|
8
|
+
def_delegators :@collection, :<<, :filter, :each, :map, :flat_map, :find
|
9
|
+
|
10
|
+
def initialize(*)
|
11
|
+
@collection = Set.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def names
|
15
|
+
map(&:name)
|
16
|
+
end
|
17
|
+
|
18
|
+
def validation_classes
|
19
|
+
filter { |option| option.validation_class.present? }.map(&:validation_class).uniq
|
20
|
+
end
|
21
|
+
|
22
|
+
def options_for_checks
|
23
|
+
filter(&:need_for_checks?).to_h do |option|
|
24
|
+
option_body = if option.body.is_a?(Hash)
|
25
|
+
option.body.key?(:is) ? option.body.fetch(:is) : option.body
|
26
|
+
else
|
27
|
+
option.body
|
28
|
+
end
|
29
|
+
|
30
|
+
[option.name, option_body]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def defined_conflict_code
|
35
|
+
flat_map do |option|
|
36
|
+
option.define_conflicts&.map do |define_input_conflict|
|
37
|
+
define_input_conflict.content.call
|
38
|
+
end
|
39
|
+
end.reject(&:blank?).first
|
40
|
+
end
|
41
|
+
|
42
|
+
def find_by(name:)
|
43
|
+
find { |option| option.name == name }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module Maintenance
|
5
|
+
module CollectionMode
|
6
|
+
class ClassNamesCollection
|
7
|
+
extend Forwardable
|
8
|
+
def_delegators :@collection, :include?
|
9
|
+
|
10
|
+
def initialize(collection)
|
11
|
+
@collection = collection
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module Maintenance
|
5
|
+
module HashMode
|
6
|
+
class ClassNamesCollection
|
7
|
+
extend Forwardable
|
8
|
+
def_delegators :@collection, :include?
|
9
|
+
|
10
|
+
def initialize(collection)
|
11
|
+
@collection = collection
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module Maintenance
|
5
|
+
module Validations
|
6
|
+
class Collection
|
7
|
+
attr_reader :errors
|
8
|
+
|
9
|
+
def self.validate(...)
|
10
|
+
new(...).validate
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(value:, types:, type:)
|
14
|
+
@value = value
|
15
|
+
@types = types
|
16
|
+
@type = type
|
17
|
+
|
18
|
+
@errors = []
|
19
|
+
end
|
20
|
+
|
21
|
+
def validate
|
22
|
+
unless @value.is_a?(prepared_type)
|
23
|
+
add_error(
|
24
|
+
expected_type: prepared_type.name,
|
25
|
+
given_type: @value.class.name
|
26
|
+
)
|
27
|
+
|
28
|
+
return self
|
29
|
+
end
|
30
|
+
|
31
|
+
validate_value!
|
32
|
+
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
def valid?
|
37
|
+
@errors.empty?
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def prepared_type
|
43
|
+
@prepared_type ||= @types.fetch(0, Array)
|
44
|
+
end
|
45
|
+
|
46
|
+
def validate_value!
|
47
|
+
@value.each do |value_item|
|
48
|
+
next if value_item.is_a?(@type)
|
49
|
+
|
50
|
+
add_error(
|
51
|
+
expected_type: @type,
|
52
|
+
given_type: value_item.class.name
|
53
|
+
)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def add_error(expected_type:, given_type:)
|
58
|
+
@errors << {
|
59
|
+
expected_type: expected_type,
|
60
|
+
given_type: given_type
|
61
|
+
}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module Maintenance
|
5
|
+
module Validations
|
6
|
+
class ObjectSchema
|
7
|
+
RESERVED_ATTRIBUTES = %i[type required default].freeze
|
8
|
+
private_constant :RESERVED_ATTRIBUTES
|
9
|
+
|
10
|
+
attr_reader :errors
|
11
|
+
|
12
|
+
def self.validate(...)
|
13
|
+
new(...).validate
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(object:, schema:)
|
17
|
+
@object = object
|
18
|
+
@schema = schema
|
19
|
+
|
20
|
+
@errors = []
|
21
|
+
end
|
22
|
+
|
23
|
+
def validate
|
24
|
+
validate_for(object: @object, schema: @schema)
|
25
|
+
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def valid?
|
30
|
+
@errors.empty?
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def validate_for(object:, schema:, root_schema_key: nil) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
36
|
+
unless object.respond_to?(:fetch)
|
37
|
+
add_error(key_name: root_schema_key, expected_type: Hash.name, given_type: object.class.name)
|
38
|
+
return
|
39
|
+
end
|
40
|
+
|
41
|
+
schema.each do |schema_key, schema_value|
|
42
|
+
attribute_type = schema_value.fetch(:type, String)
|
43
|
+
|
44
|
+
if attribute_type == Hash
|
45
|
+
validate_for(
|
46
|
+
object: object.fetch(schema_key, {}),
|
47
|
+
schema: schema_value.except(*RESERVED_ATTRIBUTES),
|
48
|
+
root_schema_key: schema_key
|
49
|
+
)
|
50
|
+
else
|
51
|
+
is_success = validate_with(
|
52
|
+
object: object,
|
53
|
+
schema_key: schema_key,
|
54
|
+
schema_value: schema_value,
|
55
|
+
attribute_type: attribute_type,
|
56
|
+
attribute_required: schema_value.fetch(:required, true)
|
57
|
+
)
|
58
|
+
|
59
|
+
next if is_success
|
60
|
+
|
61
|
+
add_error(
|
62
|
+
key_name: schema_key,
|
63
|
+
expected_type: attribute_type,
|
64
|
+
given_type: object.fetch(schema_key, nil).class.name
|
65
|
+
)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def validate_with(object:, schema_key:, schema_value:, attribute_type:, attribute_required:) # rubocop:disable Metrics/MethodLength
|
71
|
+
unless should_be_checked_for?(
|
72
|
+
object: object,
|
73
|
+
schema_key: schema_key,
|
74
|
+
schema_value: schema_value,
|
75
|
+
required: attribute_required
|
76
|
+
) # do
|
77
|
+
return true
|
78
|
+
end
|
79
|
+
|
80
|
+
value = object.fetch(schema_key, nil)
|
81
|
+
prepared_value = prepare_value_from(schema_value: schema_value, value: value, required: attribute_required)
|
82
|
+
|
83
|
+
Array(attribute_type).any? { |type| prepared_value.is_a?(type) }
|
84
|
+
end
|
85
|
+
|
86
|
+
def should_be_checked_for?(object:, schema_key:, schema_value:, required:)
|
87
|
+
required || (
|
88
|
+
!required && !fetch_default_from(schema_value).nil?
|
89
|
+
) || (
|
90
|
+
!required && !object.fetch(schema_key, nil).nil?
|
91
|
+
)
|
92
|
+
end
|
93
|
+
|
94
|
+
def prepare_value_from(schema_value:, value:, required:)
|
95
|
+
if !required && !fetch_default_from(schema_value).nil? && value.blank?
|
96
|
+
fetch_default_from(schema_value)
|
97
|
+
else
|
98
|
+
value
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def fetch_default_from(value)
|
103
|
+
value.fetch(:default, nil)
|
104
|
+
end
|
105
|
+
|
106
|
+
def add_error(key_name:, expected_type:, given_type:)
|
107
|
+
@errors << {
|
108
|
+
key_name: key_name,
|
109
|
+
expected_type: expected_type,
|
110
|
+
given_type: given_type
|
111
|
+
}
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Servactory
|
4
|
+
module Maintenance
|
5
|
+
module Validations
|
6
|
+
class Types # rubocop:disable Metrics/ClassLength
|
7
|
+
DEFAULT_MESSAGE = lambda do | # rubocop:disable Metrics/BlockLength
|
8
|
+
service_class_name:,
|
9
|
+
attribute_system_name:,
|
10
|
+
attribute:,
|
11
|
+
value:,
|
12
|
+
key_name:,
|
13
|
+
expected_type:,
|
14
|
+
given_type:
|
15
|
+
| # do
|
16
|
+
if attribute.collection_mode?
|
17
|
+
collection_message = attribute.consists_of.fetch(:message)
|
18
|
+
|
19
|
+
if collection_message.is_a?(Proc)
|
20
|
+
collection_message.call(attribute_system_name => attribute, expected_type: expected_type)
|
21
|
+
elsif collection_message.is_a?(String) && collection_message.present?
|
22
|
+
collection_message
|
23
|
+
elsif value.is_a?(attribute.types.fetch(0, Array))
|
24
|
+
I18n.t(
|
25
|
+
"servactory.#{attribute_system_name.to_s.pluralize}.checks.type.default_error.for_collection.wrong_element_type", # rubocop:disable Layout/LineLength
|
26
|
+
service_class_name: service_class_name,
|
27
|
+
"#{attribute_system_name}_name": attribute.name,
|
28
|
+
expected_type: expected_type,
|
29
|
+
given_type: given_type
|
30
|
+
)
|
31
|
+
else
|
32
|
+
I18n.t(
|
33
|
+
"servactory.#{attribute_system_name.to_s.pluralize}.checks.type.default_error.for_collection.wrong_type", # rubocop:disable Layout/LineLength
|
34
|
+
service_class_name: service_class_name,
|
35
|
+
"#{attribute_system_name}_name": attribute.name,
|
36
|
+
expected_type: attribute.types.fetch(0, Array),
|
37
|
+
given_type: value.class.name
|
38
|
+
)
|
39
|
+
end
|
40
|
+
elsif attribute.hash_mode? && key_name.present?
|
41
|
+
I18n.t(
|
42
|
+
"servactory.#{attribute_system_name.to_s.pluralize}.checks.type.default_error.for_hash.wrong_element_type", # rubocop:disable Layout/LineLength
|
43
|
+
service_class_name: service_class_name,
|
44
|
+
"#{attribute_system_name}_name": attribute.name,
|
45
|
+
key_name: key_name,
|
46
|
+
expected_type: expected_type,
|
47
|
+
given_type: given_type
|
48
|
+
)
|
49
|
+
else
|
50
|
+
I18n.t(
|
51
|
+
"servactory.#{attribute_system_name.to_s.pluralize}.checks.type.default_error.default",
|
52
|
+
service_class_name: service_class_name,
|
53
|
+
"#{attribute_system_name}_name": attribute.name,
|
54
|
+
expected_type: expected_type,
|
55
|
+
given_type: given_type
|
56
|
+
)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private_constant :DEFAULT_MESSAGE
|
61
|
+
|
62
|
+
def self.validate!(...)
|
63
|
+
new(...).validate!
|
64
|
+
end
|
65
|
+
|
66
|
+
def initialize(context:, attribute:, types:, value:, error_callback:)
|
67
|
+
@context = context
|
68
|
+
@attribute = attribute
|
69
|
+
@types = types
|
70
|
+
@value = value
|
71
|
+
@error_callback = error_callback
|
72
|
+
end
|
73
|
+
|
74
|
+
def validate! # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
75
|
+
collection_validator = nil
|
76
|
+
object_schema_validator = nil
|
77
|
+
|
78
|
+
return if prepared_types.any? do |type|
|
79
|
+
if @attribute.collection_mode?
|
80
|
+
collection_validator = Servactory::Maintenance::Validations::Collection.validate(
|
81
|
+
value: @value,
|
82
|
+
types: @attribute.types,
|
83
|
+
type: type
|
84
|
+
)
|
85
|
+
|
86
|
+
collection_validator.valid?
|
87
|
+
elsif @attribute.hash_mode?
|
88
|
+
object_schema_validator = Servactory::Maintenance::Validations::ObjectSchema.validate(
|
89
|
+
object: @value,
|
90
|
+
schema: @attribute.schema
|
91
|
+
)
|
92
|
+
|
93
|
+
object_schema_validator.valid?
|
94
|
+
else
|
95
|
+
@value.is_a?(type)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
if (first_error = collection_validator&.errors&.first).present?
|
100
|
+
return @error_callback.call(
|
101
|
+
message: DEFAULT_MESSAGE,
|
102
|
+
service_class_name: @context.class.name,
|
103
|
+
attribute_system_name: attribute_system_name,
|
104
|
+
attribute: @attribute,
|
105
|
+
value: @value,
|
106
|
+
key_name: nil,
|
107
|
+
expected_type: first_error.fetch(:expected_type),
|
108
|
+
given_type: first_error.fetch(:given_type)
|
109
|
+
)
|
110
|
+
end
|
111
|
+
|
112
|
+
if (first_error = object_schema_validator&.errors&.first).present?
|
113
|
+
return @error_callback.call(
|
114
|
+
message: DEFAULT_MESSAGE,
|
115
|
+
service_class_name: @context.class.name,
|
116
|
+
attribute_system_name: attribute_system_name,
|
117
|
+
attribute: @attribute,
|
118
|
+
value: @value,
|
119
|
+
key_name: first_error.fetch(:key_name),
|
120
|
+
expected_type: first_error.fetch(:expected_type),
|
121
|
+
given_type: first_error.fetch(:given_type)
|
122
|
+
)
|
123
|
+
end
|
124
|
+
|
125
|
+
@error_callback.call(
|
126
|
+
message: DEFAULT_MESSAGE,
|
127
|
+
service_class_name: @context.class.name,
|
128
|
+
attribute_system_name: attribute_system_name,
|
129
|
+
attribute: @attribute,
|
130
|
+
value: @value,
|
131
|
+
key_name: nil,
|
132
|
+
expected_type: prepared_types.join(", "),
|
133
|
+
given_type: @value.class.name
|
134
|
+
)
|
135
|
+
end
|
136
|
+
|
137
|
+
private
|
138
|
+
|
139
|
+
def attribute_system_name
|
140
|
+
@attribute.class.name.demodulize.downcase.to_sym
|
141
|
+
end
|
142
|
+
|
143
|
+
def prepared_types
|
144
|
+
@prepared_types ||=
|
145
|
+
if @attribute.collection_mode?
|
146
|
+
prepared_types_from(Array(@attribute.consists_of.fetch(:type, [])))
|
147
|
+
else
|
148
|
+
prepared_types_from(@types)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def prepared_types_from(types)
|
153
|
+
types.map do |type|
|
154
|
+
if type.is_a?(String)
|
155
|
+
Object.const_get(type)
|
156
|
+
else
|
157
|
+
type
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -17,7 +17,12 @@ module Servactory
|
|
17
17
|
private
|
18
18
|
|
19
19
|
def output(name, **options)
|
20
|
-
collection_of_outputs << Output.new(
|
20
|
+
collection_of_outputs << Output.new(
|
21
|
+
name,
|
22
|
+
collection_mode_class_names: config.collection_mode_class_names,
|
23
|
+
hash_mode_class_names: config.hash_mode_class_names,
|
24
|
+
**options
|
25
|
+
)
|
21
26
|
end
|
22
27
|
|
23
28
|
def collection_of_outputs
|