servactory 3.0.4 → 3.1.0.rc1
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/lib/servactory/actions/action.rb +2 -2
- data/lib/servactory/actions/collection.rb +1 -1
- data/lib/servactory/actions/stages/collection.rb +1 -1
- data/lib/servactory/configuration/config.rb +0 -16
- data/lib/servactory/configuration/configurable.rb +3 -6
- data/lib/servactory/configuration/hash_mode/class_names_collection.rb +1 -4
- data/lib/servactory/configuration/option_helpers/option_helpers_collection.rb +57 -8
- data/lib/servactory/context/warehouse/inputs.rb +28 -15
- data/lib/servactory/context/workspace/inputs.rb +27 -18
- data/lib/servactory/context/workspace/internals.rb +44 -27
- data/lib/servactory/context/workspace/outputs.rb +31 -23
- data/lib/servactory/dsl.rb +1 -1
- data/lib/servactory/info/builder.rb +2 -3
- data/lib/servactory/inputs/collection.rb +14 -21
- data/lib/servactory/inputs/input.rb +6 -103
- data/lib/servactory/inputs/tools/validation.rb +32 -57
- data/lib/servactory/inputs/validations/required.rb +3 -2
- data/lib/servactory/internals/collection.rb +5 -24
- data/lib/servactory/internals/internal.rb +4 -112
- data/lib/servactory/maintenance/attributes/base.rb +135 -0
- data/lib/servactory/maintenance/attributes/collection.rb +109 -0
- data/lib/servactory/maintenance/attributes/option_helper.rb +33 -12
- data/lib/servactory/maintenance/{attributes/options_collection.rb → options/collection.rb} +6 -7
- data/lib/servactory/maintenance/{attributes → options}/define_conflict.rb +1 -1
- data/lib/servactory/maintenance/{attributes → options}/define_method.rb +1 -1
- data/lib/servactory/maintenance/options/helper.rb +23 -0
- data/lib/servactory/maintenance/{attributes → options}/option.rb +50 -27
- data/lib/servactory/maintenance/options/registrar.rb +200 -0
- data/lib/servactory/maintenance/{attributes/validations → validations/checkers}/must.rb +25 -8
- data/lib/servactory/maintenance/{attributes/validations → validations/checkers}/type.rb +6 -5
- data/lib/servactory/maintenance/validations/concerns/error_builder.rb +50 -0
- data/lib/servactory/maintenance/validations/performer.rb +57 -0
- data/lib/servactory/maintenance/validations/support/type_validator.rb +36 -0
- data/lib/servactory/maintenance/{attributes → validations}/translator/must.rb +1 -1
- data/lib/servactory/maintenance/{attributes → validations}/translator/type.rb +1 -1
- data/lib/servactory/outputs/collection.rb +5 -24
- data/lib/servactory/outputs/output.rb +4 -112
- data/lib/servactory/result.rb +48 -39
- data/lib/servactory/tool_kit/dynamic_options/consists_of.rb +2 -4
- data/lib/servactory/tool_kit/dynamic_options/must.rb +2 -2
- data/lib/servactory/tool_kit/dynamic_options/schema.rb +7 -9
- data/lib/servactory/utils.rb +0 -8
- data/lib/servactory/version.rb +3 -3
- data/lib/servactory.rb +4 -0
- metadata +19 -22
- data/lib/servactory/maintenance/attributes/options/registrar.rb +0 -183
- data/lib/servactory/maintenance/attributes/tools/validation.rb +0 -84
- data/lib/servactory/maintenance/attributes/validations/concerns/error_builder.rb +0 -52
- data/lib/servactory/maintenance/validations/types.rb +0 -34
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Servactory
|
|
4
4
|
module Inputs
|
|
5
|
-
class Input
|
|
5
|
+
class Input < Servactory::Maintenance::Attributes::Base
|
|
6
6
|
class Actor
|
|
7
7
|
attr_reader :name,
|
|
8
8
|
:internal_name,
|
|
@@ -38,22 +38,19 @@ module Servactory
|
|
|
38
38
|
# The methods below are required to support the internal work.
|
|
39
39
|
|
|
40
40
|
def input?
|
|
41
|
-
|
|
41
|
+
@attribute.input?
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
def internal?
|
|
45
|
-
|
|
45
|
+
@attribute.internal?
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def output?
|
|
49
|
-
|
|
49
|
+
@attribute.output?
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
-
attr_reader :
|
|
54
|
-
:internal_name,
|
|
55
|
-
:collection_of_options,
|
|
56
|
-
:options
|
|
53
|
+
attr_reader :internal_name
|
|
57
54
|
|
|
58
55
|
# rubocop:disable Style/KeywordParametersOrder
|
|
59
56
|
def initialize(
|
|
@@ -63,49 +60,16 @@ module Servactory
|
|
|
63
60
|
option_helpers:,
|
|
64
61
|
**options
|
|
65
62
|
)
|
|
66
|
-
@name = name
|
|
67
63
|
@internal_name = as.presence || name
|
|
68
|
-
@option_helpers = option_helpers
|
|
69
64
|
|
|
70
|
-
|
|
65
|
+
super(name, *helpers, option_helpers:, **options)
|
|
71
66
|
end
|
|
72
67
|
# rubocop:enable Style/KeywordParametersOrder
|
|
73
68
|
|
|
74
|
-
def method_missing(name, *args, &block)
|
|
75
|
-
option = @collection_of_options.find_by(name:)
|
|
76
|
-
return super if option.nil?
|
|
77
|
-
|
|
78
|
-
option.body
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def respond_to_missing?(name, *)
|
|
82
|
-
@collection_of_options.names.include?(name) || super
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def register_options(helpers:, options:)
|
|
86
|
-
merged_options = augment_options_with_helpers(helpers:, options:)
|
|
87
|
-
options_registrar = create_options_registrar(options: merged_options)
|
|
88
|
-
|
|
89
|
-
@options = merged_options
|
|
90
|
-
@collection_of_options = options_registrar.collection
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def options_for_checks
|
|
94
|
-
@collection_of_options.options_for_checks
|
|
95
|
-
end
|
|
96
|
-
|
|
97
69
|
def conflict_code
|
|
98
70
|
@collection_of_options.defined_conflict_code
|
|
99
71
|
end
|
|
100
72
|
|
|
101
|
-
def system_name
|
|
102
|
-
self.class.name.demodulize.downcase.to_sym
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def i18n_name
|
|
106
|
-
system_name.to_s.pluralize
|
|
107
|
-
end
|
|
108
|
-
|
|
109
73
|
def with_conflicts?
|
|
110
74
|
conflict_code.present?
|
|
111
75
|
end
|
|
@@ -114,24 +78,8 @@ module Servactory
|
|
|
114
78
|
true
|
|
115
79
|
end
|
|
116
80
|
|
|
117
|
-
def internal?
|
|
118
|
-
false
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
def output?
|
|
122
|
-
false
|
|
123
|
-
end
|
|
124
|
-
|
|
125
81
|
private
|
|
126
82
|
|
|
127
|
-
def create_options_registrar(options:)
|
|
128
|
-
Servactory::Maintenance::Attributes::Options::Registrar.register(
|
|
129
|
-
attribute: self,
|
|
130
|
-
options:,
|
|
131
|
-
features: available_feature_options
|
|
132
|
-
)
|
|
133
|
-
end
|
|
134
|
-
|
|
135
83
|
def available_feature_options
|
|
136
84
|
{
|
|
137
85
|
required: true,
|
|
@@ -141,51 +89,6 @@ module Servactory
|
|
|
141
89
|
prepare: true
|
|
142
90
|
}
|
|
143
91
|
end
|
|
144
|
-
|
|
145
|
-
def augment_options_with_helpers(helpers:, options:)
|
|
146
|
-
result_options = options.dup
|
|
147
|
-
merge_standard_helpers_into(target_options: result_options, helpers:) if helpers.present?
|
|
148
|
-
merge_advanced_helpers_into(target_options: result_options, source_options: options)
|
|
149
|
-
result_options
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
def merge_standard_helpers_into(target_options:, helpers:)
|
|
153
|
-
standard_helpers_result = transform_helpers_to_options(helpers:)
|
|
154
|
-
target_options.deep_merge!(standard_helpers_result)
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
def merge_advanced_helpers_into(target_options:, source_options:)
|
|
158
|
-
advanced_helpers = filter_advanced_helpers(options: source_options)
|
|
159
|
-
return if advanced_helpers.blank?
|
|
160
|
-
|
|
161
|
-
advanced_helpers_result = transform_helpers_to_options(helpers: advanced_helpers)
|
|
162
|
-
target_options.deep_merge!(advanced_helpers_result)
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
def filter_advanced_helpers(options:)
|
|
166
|
-
reserved_options = Servactory::Maintenance::Attributes::Options::Registrar::RESERVED_OPTIONS
|
|
167
|
-
options.except(*reserved_options)
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
def transform_helpers_to_options(helpers:)
|
|
171
|
-
helpers.each_with_object({}) do |(helper_name, values), result|
|
|
172
|
-
helper = @option_helpers.find_by(name: helper_name)
|
|
173
|
-
next if helper.blank?
|
|
174
|
-
|
|
175
|
-
transformed_option = transform_helper_to_option(helper:, values:)
|
|
176
|
-
result.deep_merge!(transformed_option) if transformed_option.present?
|
|
177
|
-
end
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
def transform_helper_to_option(helper:, values:)
|
|
181
|
-
return helper.equivalent unless helper.equivalent.is_a?(Proc)
|
|
182
|
-
|
|
183
|
-
if values.is_a?(Hash)
|
|
184
|
-
helper.equivalent.call(**values)
|
|
185
|
-
else
|
|
186
|
-
helper.equivalent.call(values)
|
|
187
|
-
end
|
|
188
|
-
end
|
|
189
92
|
end
|
|
190
93
|
end
|
|
191
94
|
end
|
|
@@ -3,81 +3,56 @@
|
|
|
3
3
|
module Servactory
|
|
4
4
|
module Inputs
|
|
5
5
|
module Tools
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
break if @first_error.present?
|
|
6
|
+
module Validation
|
|
7
|
+
extend self
|
|
8
|
+
|
|
9
|
+
def validate!(context, collection_of_inputs) # rubocop:disable Metrics/MethodLength
|
|
10
|
+
warehouse = context.send(:servactory_service_warehouse)
|
|
11
|
+
first_error = nil
|
|
12
|
+
failed_input = nil
|
|
13
|
+
|
|
14
|
+
collection_of_inputs.each do |input|
|
|
15
|
+
first_error = process_input(context, warehouse, input)
|
|
16
|
+
if first_error.present?
|
|
17
|
+
failed_input = input
|
|
18
|
+
break
|
|
19
|
+
end
|
|
21
20
|
end
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
return if first_error.nil?
|
|
23
|
+
|
|
24
|
+
context.fail_input!(failed_input.name, message: first_error)
|
|
24
25
|
end
|
|
25
26
|
|
|
26
27
|
private
|
|
27
28
|
|
|
28
|
-
def process_input(input)
|
|
29
|
+
def process_input(context, warehouse, input)
|
|
30
|
+
value = warehouse.fetch_input(input.name)
|
|
31
|
+
|
|
29
32
|
input.options_for_checks.each do |check_key, check_options|
|
|
30
|
-
process_option(check_key, check_options
|
|
31
|
-
|
|
33
|
+
error = process_option(context, input, value, check_key, check_options)
|
|
34
|
+
return error if error.present?
|
|
32
35
|
end
|
|
36
|
+
|
|
37
|
+
nil
|
|
33
38
|
end
|
|
34
39
|
|
|
35
|
-
def process_option(check_key, check_options
|
|
36
|
-
validation_classes =
|
|
40
|
+
def process_option(context, input, value, check_key, check_options) # rubocop:disable Metrics/MethodLength
|
|
41
|
+
validation_classes = input.collection_of_options.validation_classes
|
|
37
42
|
return if validation_classes.empty?
|
|
38
43
|
|
|
39
44
|
validation_classes.each do |validation_class|
|
|
40
|
-
error_message =
|
|
41
|
-
|
|
42
|
-
input
|
|
45
|
+
error_message = validation_class.check(
|
|
46
|
+
context:,
|
|
47
|
+
attribute: input,
|
|
48
|
+
value:,
|
|
43
49
|
check_key:,
|
|
44
50
|
check_options:
|
|
45
51
|
)
|
|
46
|
-
|
|
47
|
-
next if error_message.blank?
|
|
48
|
-
|
|
49
|
-
@first_error = error_message
|
|
50
|
-
break
|
|
52
|
+
return error_message if error_message.present?
|
|
51
53
|
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def process_validation_class(
|
|
55
|
-
validation_class:,
|
|
56
|
-
input:,
|
|
57
|
-
check_key:,
|
|
58
|
-
check_options:
|
|
59
|
-
)
|
|
60
|
-
validation_class.check(
|
|
61
|
-
context: @context,
|
|
62
|
-
attribute: input,
|
|
63
|
-
value: @context.send(:servactory_service_warehouse).fetch_input(input.name),
|
|
64
|
-
check_key:,
|
|
65
|
-
check_options:
|
|
66
|
-
)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
########################################################################
|
|
70
|
-
|
|
71
|
-
def validation_classes_from(input)
|
|
72
|
-
@validation_classes_cache ||= input.collection_of_options.validation_classes # rubocop:disable Naming/MemoizedInstanceVariableName
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
########################################################################
|
|
76
|
-
|
|
77
|
-
def raise_errors
|
|
78
|
-
return if @first_error.nil?
|
|
79
54
|
|
|
80
|
-
|
|
55
|
+
nil
|
|
81
56
|
end
|
|
82
57
|
end
|
|
83
58
|
end
|
|
@@ -22,7 +22,7 @@ module Servactory
|
|
|
22
22
|
# end
|
|
23
23
|
# ```
|
|
24
24
|
class Required
|
|
25
|
-
extend Servactory::Maintenance::
|
|
25
|
+
extend Servactory::Maintenance::Validations::Concerns::ErrorBuilder
|
|
26
26
|
|
|
27
27
|
# Validates that a required input has a present value.
|
|
28
28
|
#
|
|
@@ -30,8 +30,9 @@ module Servactory
|
|
|
30
30
|
# @param attribute [Inputs::Input] Input attribute to validate
|
|
31
31
|
# @param value [Object] Value to check for presence
|
|
32
32
|
# @param check_key [Symbol] Must be :required to trigger validation
|
|
33
|
+
# @param check_options [Hash, nil] Unused, accepted for uniform checker interface
|
|
33
34
|
# @return [String, nil] Error message on failure, nil on success
|
|
34
|
-
def self.check(context:, attribute:, value:, check_key:,
|
|
35
|
+
def self.check(context:, attribute:, value:, check_key:, check_options: nil) # rubocop:disable Lint/UnusedMethodArgument
|
|
35
36
|
return unless should_be_checked_for?(attribute, check_key)
|
|
36
37
|
return if Servactory::Utils.value_present?(value)
|
|
37
38
|
|
|
@@ -2,30 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
module Servactory
|
|
4
4
|
module Internals
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def initialize(collection = Set.new)
|
|
11
|
-
@collection = collection
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def only(*names)
|
|
15
|
-
Collection.new(filter { |internal| names.include?(internal.name) })
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def except(*names)
|
|
19
|
-
Collection.new(filter { |internal| names.exclude?(internal.name) })
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def names
|
|
23
|
-
map(&:name)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def find_by(name:)
|
|
27
|
-
find { |internal| internal.name == name }
|
|
28
|
-
end
|
|
5
|
+
# Specialized collection for Internal attributes.
|
|
6
|
+
#
|
|
7
|
+
# Inherits all behavior from the base Attributes::Collection
|
|
8
|
+
# without any overrides.
|
|
9
|
+
class Collection < Servactory::Maintenance::Attributes::Collection
|
|
29
10
|
end
|
|
30
11
|
end
|
|
31
12
|
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Servactory
|
|
4
4
|
module Internals
|
|
5
|
-
class Internal
|
|
5
|
+
class Internal < Servactory::Maintenance::Attributes::Base
|
|
6
6
|
class Actor
|
|
7
7
|
attr_reader :name,
|
|
8
8
|
:types,
|
|
@@ -26,138 +26,30 @@ module Servactory
|
|
|
26
26
|
# The methods below are required to support the internal work.
|
|
27
27
|
|
|
28
28
|
def input?
|
|
29
|
-
|
|
29
|
+
@attribute.input?
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def internal?
|
|
33
|
-
|
|
33
|
+
@attribute.internal?
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def output?
|
|
37
|
-
|
|
37
|
+
@attribute.output?
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
attr_reader :name,
|
|
42
|
-
:collection_of_options,
|
|
43
|
-
:options
|
|
44
|
-
|
|
45
|
-
def initialize(
|
|
46
|
-
name,
|
|
47
|
-
*helpers,
|
|
48
|
-
option_helpers:,
|
|
49
|
-
**options
|
|
50
|
-
)
|
|
51
|
-
@name = name
|
|
52
|
-
@option_helpers = option_helpers
|
|
53
|
-
|
|
54
|
-
register_options(helpers:, options:)
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def method_missing(name, *args, &block)
|
|
58
|
-
option = @collection_of_options.find_by(name:)
|
|
59
|
-
return super if option.nil?
|
|
60
|
-
|
|
61
|
-
option.body
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def respond_to_missing?(name, *)
|
|
65
|
-
@collection_of_options.names.include?(name) || super
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def register_options(helpers:, options:)
|
|
69
|
-
merged_options = augment_options_with_helpers(helpers:, options:)
|
|
70
|
-
options_registrar = create_options_registrar(options: merged_options)
|
|
71
|
-
|
|
72
|
-
@options = merged_options
|
|
73
|
-
@collection_of_options = options_registrar.collection
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def options_for_checks
|
|
77
|
-
@collection_of_options.options_for_checks
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def system_name
|
|
81
|
-
self.class.name.demodulize.downcase.to_sym
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def i18n_name
|
|
85
|
-
system_name.to_s.pluralize
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def input?
|
|
89
|
-
false
|
|
90
|
-
end
|
|
91
|
-
|
|
92
41
|
def internal?
|
|
93
42
|
true
|
|
94
43
|
end
|
|
95
44
|
|
|
96
|
-
def output?
|
|
97
|
-
false
|
|
98
|
-
end
|
|
99
|
-
|
|
100
45
|
private
|
|
101
46
|
|
|
102
|
-
def create_options_registrar(options:)
|
|
103
|
-
Servactory::Maintenance::Attributes::Options::Registrar.register(
|
|
104
|
-
attribute: self,
|
|
105
|
-
options:,
|
|
106
|
-
features: available_feature_options
|
|
107
|
-
)
|
|
108
|
-
end
|
|
109
|
-
|
|
110
47
|
def available_feature_options
|
|
111
48
|
{
|
|
112
49
|
types: true,
|
|
113
50
|
must: true
|
|
114
51
|
}
|
|
115
52
|
end
|
|
116
|
-
|
|
117
|
-
def augment_options_with_helpers(helpers:, options:)
|
|
118
|
-
result_options = options.dup
|
|
119
|
-
merge_standard_helpers_into(target_options: result_options, helpers:) if helpers.present?
|
|
120
|
-
merge_advanced_helpers_into(target_options: result_options, source_options: options)
|
|
121
|
-
result_options
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
def merge_standard_helpers_into(target_options:, helpers:)
|
|
125
|
-
standard_helpers_result = transform_helpers_to_options(helpers:)
|
|
126
|
-
target_options.deep_merge!(standard_helpers_result)
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def merge_advanced_helpers_into(target_options:, source_options:)
|
|
130
|
-
advanced_helpers = filter_advanced_helpers(options: source_options)
|
|
131
|
-
return if advanced_helpers.blank?
|
|
132
|
-
|
|
133
|
-
advanced_helpers_result = transform_helpers_to_options(helpers: advanced_helpers)
|
|
134
|
-
target_options.deep_merge!(advanced_helpers_result)
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
def filter_advanced_helpers(options:)
|
|
138
|
-
reserved_options = Servactory::Maintenance::Attributes::Options::Registrar::RESERVED_OPTIONS
|
|
139
|
-
options.except(*reserved_options)
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
def transform_helpers_to_options(helpers:)
|
|
143
|
-
helpers.each_with_object({}) do |(helper_name, values), result|
|
|
144
|
-
helper = @option_helpers.find_by(name: helper_name)
|
|
145
|
-
next if helper.blank?
|
|
146
|
-
|
|
147
|
-
transformed_option = transform_helper_to_option(helper:, values:)
|
|
148
|
-
result.deep_merge!(transformed_option) if transformed_option.present?
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
def transform_helper_to_option(helper:, values:)
|
|
153
|
-
return helper.equivalent unless helper.equivalent.is_a?(Proc)
|
|
154
|
-
|
|
155
|
-
if values.is_a?(Hash)
|
|
156
|
-
helper.equivalent.call(**values)
|
|
157
|
-
else
|
|
158
|
-
helper.equivalent.call(values)
|
|
159
|
-
end
|
|
160
|
-
end
|
|
161
53
|
end
|
|
162
54
|
end
|
|
163
55
|
end
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Servactory
|
|
4
|
+
module Maintenance
|
|
5
|
+
module Attributes
|
|
6
|
+
class Base
|
|
7
|
+
attr_reader :name,
|
|
8
|
+
:collection_of_options,
|
|
9
|
+
:options
|
|
10
|
+
|
|
11
|
+
def initialize(
|
|
12
|
+
name,
|
|
13
|
+
*helpers,
|
|
14
|
+
option_helpers:,
|
|
15
|
+
**options
|
|
16
|
+
)
|
|
17
|
+
@name = name
|
|
18
|
+
@option_helpers = option_helpers
|
|
19
|
+
|
|
20
|
+
register_options(helpers:, options:)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def method_missing(name, *args, &block)
|
|
24
|
+
option = @collection_of_options.find_by(name:)
|
|
25
|
+
return super if option.nil?
|
|
26
|
+
|
|
27
|
+
option.body_for_access
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def respond_to_missing?(name, *)
|
|
31
|
+
@collection_of_options.names.include?(name) || super
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def register_options(helpers:, options:)
|
|
35
|
+
merged_options = augment_options_with_helpers(helpers:, options:)
|
|
36
|
+
options_registrar = create_options_registrar(options: merged_options)
|
|
37
|
+
|
|
38
|
+
@options = merged_options
|
|
39
|
+
@collection_of_options = options_registrar.collection
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def options_for_checks
|
|
43
|
+
@collection_of_options.options_for_checks
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def system_name
|
|
47
|
+
@system_name ||= self.class.name.demodulize.downcase.to_sym
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def i18n_name
|
|
51
|
+
@i18n_name ||= system_name.to_s.pluralize
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def actor
|
|
55
|
+
@actor ||= self.class::Actor.new(self)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def typed_actor_kwargs
|
|
59
|
+
@typed_actor_kwargs ||= { system_name => actor }.freeze
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def input?
|
|
63
|
+
false
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def internal?
|
|
67
|
+
false
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def output?
|
|
71
|
+
false
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def create_options_registrar(options:)
|
|
77
|
+
Servactory::Maintenance::Options::Registrar.register(
|
|
78
|
+
attribute: self,
|
|
79
|
+
options:,
|
|
80
|
+
features: available_feature_options
|
|
81
|
+
)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def available_feature_options
|
|
85
|
+
raise NotImplementedError, "Subclass must implement available_feature_options"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def augment_options_with_helpers(helpers:, options:)
|
|
89
|
+
result_options = options.dup
|
|
90
|
+
merge_standard_helpers_into(target_options: result_options, helpers:) if helpers.present?
|
|
91
|
+
merge_advanced_helpers_into(target_options: result_options, source_options: options)
|
|
92
|
+
result_options
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def merge_standard_helpers_into(target_options:, helpers:)
|
|
96
|
+
standard_helpers_result = transform_helpers_to_options(helpers:)
|
|
97
|
+
target_options.deep_merge!(standard_helpers_result)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def merge_advanced_helpers_into(target_options:, source_options:)
|
|
101
|
+
advanced_helpers = filter_advanced_helpers(options: source_options)
|
|
102
|
+
return if advanced_helpers.blank?
|
|
103
|
+
|
|
104
|
+
advanced_helpers_result = transform_helpers_to_options(helpers: advanced_helpers)
|
|
105
|
+
target_options.deep_merge!(advanced_helpers_result)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def filter_advanced_helpers(options:)
|
|
109
|
+
reserved_options = Servactory::Maintenance::Options::Registrar::RESERVED_OPTIONS
|
|
110
|
+
options.except(*reserved_options)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def transform_helpers_to_options(helpers:)
|
|
114
|
+
helpers.each_with_object({}) do |(helper_name, values), result|
|
|
115
|
+
helper = @option_helpers.find_by(name: helper_name)
|
|
116
|
+
next if helper.blank?
|
|
117
|
+
|
|
118
|
+
transformed_option = transform_helper_to_option(helper:, values:)
|
|
119
|
+
result.deep_merge!(transformed_option) if transformed_option.present?
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def transform_helper_to_option(helper:, values:)
|
|
124
|
+
return helper.equivalent unless helper.equivalent.is_a?(Proc)
|
|
125
|
+
|
|
126
|
+
if values.is_a?(Hash)
|
|
127
|
+
helper.equivalent.call(**values)
|
|
128
|
+
else
|
|
129
|
+
helper.equivalent.call(values)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|