servactory 2.16.0 → 3.0.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/README.md +38 -9
- data/config/locales/de.yml +134 -0
- data/config/locales/en.yml +15 -0
- data/config/locales/es.yml +134 -0
- data/config/locales/fr.yml +134 -0
- data/config/locales/it.yml +134 -0
- data/config/locales/ru.yml +15 -0
- data/lib/generators/README.md +45 -0
- data/lib/generators/servactory/base.rb +82 -0
- data/lib/generators/servactory/extension/USAGE +54 -0
- data/lib/generators/servactory/extension/extension_generator.rb +41 -0
- data/lib/generators/servactory/extension/templates/extension.rb.tt +62 -0
- data/lib/generators/servactory/install/USAGE +27 -0
- data/lib/generators/servactory/install/install_generator.rb +94 -0
- data/lib/generators/servactory/{templates/services/application_service/base.rb → install/templates/application_service/base.rb.tt} +29 -19
- data/lib/generators/servactory/{templates/services/application_service/exceptions.rb → install/templates/application_service/exceptions.rb.tt} +1 -1
- data/lib/generators/servactory/{templates/services/application_service/result.rb → install/templates/application_service/result.rb.tt} +1 -1
- data/lib/generators/servactory/rspec/USAGE +46 -0
- data/lib/generators/servactory/rspec/rspec_generator.rb +95 -0
- data/lib/generators/servactory/rspec/templates/service_spec.rb.tt +58 -0
- data/lib/generators/servactory/service/USAGE +51 -0
- data/lib/generators/servactory/service/service_generator.rb +56 -0
- data/lib/generators/servactory/service/templates/service.rb.tt +22 -0
- data/lib/servactory/actions/collection.rb +56 -1
- data/lib/servactory/actions/dsl.rb +11 -11
- data/lib/servactory/actions/tools/rules.rb +1 -1
- data/lib/servactory/actions/tools/runner.rb +111 -28
- data/lib/servactory/base.rb +1 -7
- data/lib/servactory/configuration/actions/aliases/collection.rb +5 -0
- data/lib/servactory/configuration/actions/rescue_handlers/collection.rb +5 -0
- data/lib/servactory/configuration/actions/shortcuts/collection.rb +5 -0
- data/lib/servactory/configuration/collection_mode/class_names_collection.rb +5 -0
- data/lib/servactory/configuration/config.rb +36 -0
- data/lib/servactory/configuration/configurable.rb +95 -0
- data/lib/servactory/configuration/dsl.rb +3 -27
- data/lib/servactory/configuration/factory.rb +20 -20
- data/lib/servactory/configuration/hash_mode/class_names_collection.rb +5 -0
- data/lib/servactory/configuration/option_helpers/option_helpers_collection.rb +5 -0
- data/lib/servactory/context/warehouse/inputs.rb +2 -2
- data/lib/servactory/context/workspace/inputs.rb +2 -2
- data/lib/servactory/context/workspace/internals.rb +2 -2
- data/lib/servactory/context/workspace/outputs.rb +2 -2
- data/lib/servactory/context/workspace.rb +11 -7
- data/lib/servactory/dsl.rb +10 -8
- data/lib/servactory/maintenance/attributes/tools/validation.rb +1 -1
- data/lib/servactory/result.rb +2 -2
- data/lib/servactory/stroma/dsl.rb +118 -0
- data/lib/servactory/stroma/entry.rb +32 -0
- data/lib/servactory/stroma/exceptions/base.rb +45 -0
- data/lib/servactory/stroma/exceptions/invalid_hook_type.rb +29 -0
- data/lib/servactory/stroma/exceptions/key_already_registered.rb +32 -0
- data/lib/servactory/stroma/exceptions/registry_frozen.rb +33 -0
- data/lib/servactory/stroma/exceptions/registry_not_finalized.rb +33 -0
- data/lib/servactory/stroma/exceptions/unknown_hook_target.rb +39 -0
- data/lib/servactory/stroma/hooks/applier.rb +63 -0
- data/lib/servactory/stroma/hooks/collection.rb +103 -0
- data/lib/servactory/stroma/hooks/factory.rb +80 -0
- data/lib/servactory/stroma/hooks/hook.rb +74 -0
- data/lib/servactory/stroma/registry.rb +94 -0
- data/lib/servactory/stroma/settings/collection.rb +90 -0
- data/lib/servactory/stroma/settings/registry_settings.rb +88 -0
- data/lib/servactory/stroma/settings/setting.rb +113 -0
- data/lib/servactory/stroma/state.rb +59 -0
- data/lib/servactory/test_kit/fake_type.rb +23 -0
- data/lib/servactory/test_kit/result.rb +45 -0
- data/lib/servactory/test_kit/rspec/helpers/argument_matchers.rb +97 -0
- data/lib/servactory/test_kit/rspec/helpers/concerns/error_messages.rb +179 -0
- data/lib/servactory/test_kit/rspec/helpers/concerns/service_class_validation.rb +74 -0
- data/lib/servactory/test_kit/rspec/helpers/fluent.rb +110 -0
- data/lib/servactory/test_kit/rspec/helpers/input_validator.rb +149 -0
- data/lib/servactory/test_kit/rspec/helpers/legacy.rb +228 -0
- data/lib/servactory/test_kit/rspec/helpers/mock_executor.rb +256 -0
- data/lib/servactory/test_kit/rspec/helpers/output_validator.rb +121 -0
- data/lib/servactory/test_kit/rspec/helpers/service_mock_builder.rb +422 -0
- data/lib/servactory/test_kit/rspec/helpers/service_mock_config.rb +129 -0
- data/lib/servactory/test_kit/rspec/helpers.rb +51 -84
- data/lib/servactory/test_kit/rspec/matchers/base/attribute_matcher.rb +324 -0
- data/lib/servactory/test_kit/rspec/matchers/base/submatcher.rb +133 -0
- data/lib/servactory/test_kit/rspec/matchers/base/submatcher_context.rb +101 -0
- data/lib/servactory/test_kit/rspec/matchers/base/submatcher_registry.rb +205 -0
- data/lib/servactory/test_kit/rspec/matchers/concerns/attribute_data_access.rb +100 -0
- data/lib/servactory/test_kit/rspec/matchers/concerns/error_message_builder.rb +106 -0
- data/lib/servactory/test_kit/rspec/matchers/concerns/value_comparison.rb +97 -0
- data/lib/servactory/test_kit/rspec/matchers/have_service_input_matcher.rb +89 -219
- data/lib/servactory/test_kit/rspec/matchers/have_service_internal_matcher.rb +74 -166
- data/lib/servactory/test_kit/rspec/matchers/have_service_output_matcher.rb +238 -0
- data/lib/servactory/test_kit/rspec/matchers/result/be_failure_service_matcher.rb +257 -0
- data/lib/servactory/test_kit/rspec/matchers/result/be_success_service_matcher.rb +185 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/input/default_submatcher.rb +81 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/input/optional_submatcher.rb +62 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/input/required_submatcher.rb +93 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/input/valid_with_submatcher.rb +271 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/shared/consists_of_submatcher.rb +85 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/shared/inclusion_submatcher.rb +120 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/shared/message_submatcher.rb +115 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/shared/must_submatcher.rb +82 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/shared/schema_submatcher.rb +102 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/shared/target_submatcher.rb +125 -0
- data/lib/servactory/test_kit/rspec/matchers/submatchers/shared/types_submatcher.rb +77 -0
- data/lib/servactory/test_kit/rspec/matchers.rb +126 -285
- data/lib/servactory/test_kit/utils/faker.rb +62 -2
- data/lib/servactory/tool_kit/dynamic_options/consists_of.rb +166 -0
- data/lib/servactory/tool_kit/dynamic_options/format.rb +195 -8
- data/lib/servactory/tool_kit/dynamic_options/inclusion.rb +219 -17
- data/lib/servactory/tool_kit/dynamic_options/max.rb +143 -0
- data/lib/servactory/tool_kit/dynamic_options/min.rb +143 -0
- data/lib/servactory/tool_kit/dynamic_options/multiple_of.rb +157 -8
- data/lib/servactory/tool_kit/dynamic_options/must.rb +194 -0
- data/lib/servactory/tool_kit/dynamic_options/schema.rb +226 -2
- data/lib/servactory/tool_kit/dynamic_options/target.rb +252 -0
- data/lib/servactory/version.rb +3 -3
- data/lib/servactory.rb +4 -0
- metadata +73 -25
- data/lib/generators/servactory/install_generator.rb +0 -21
- data/lib/generators/servactory/rspec_generator.rb +0 -88
- data/lib/generators/servactory/service_generator.rb +0 -49
- data/lib/servactory/configuration/setup.rb +0 -97
- data/lib/servactory/test_kit/rspec/matchers/have_service_attribute_matchers/consists_of_matcher.rb +0 -68
- data/lib/servactory/test_kit/rspec/matchers/have_service_attribute_matchers/inclusion_matcher.rb +0 -73
- data/lib/servactory/test_kit/rspec/matchers/have_service_attribute_matchers/message_matcher.rb +0 -91
- data/lib/servactory/test_kit/rspec/matchers/have_service_attribute_matchers/must_matcher.rb +0 -72
- data/lib/servactory/test_kit/rspec/matchers/have_service_attribute_matchers/schema_matcher.rb +0 -92
- data/lib/servactory/test_kit/rspec/matchers/have_service_attribute_matchers/types_matcher.rb +0 -72
- data/lib/servactory/test_kit/rspec/matchers/have_service_input_matchers/default_matcher.rb +0 -69
- data/lib/servactory/test_kit/rspec/matchers/have_service_input_matchers/optional_matcher.rb +0 -63
- data/lib/servactory/test_kit/rspec/matchers/have_service_input_matchers/required_matcher.rb +0 -81
- data/lib/servactory/test_kit/rspec/matchers/have_service_input_matchers/valid_with_matcher.rb +0 -199
|
@@ -3,16 +3,48 @@
|
|
|
3
3
|
module Servactory
|
|
4
4
|
module Actions
|
|
5
5
|
module Tools
|
|
6
|
+
# Executes service actions within stages.
|
|
7
|
+
#
|
|
8
|
+
# ## Purpose
|
|
9
|
+
#
|
|
10
|
+
# Orchestrates the execution of service actions, handling stage wrappers,
|
|
11
|
+
# rollbacks, and conditional execution (only_if/only_unless). Provides
|
|
12
|
+
# the core execution engine for Servactory services.
|
|
13
|
+
#
|
|
14
|
+
# ## Usage
|
|
15
|
+
#
|
|
16
|
+
# ```ruby
|
|
17
|
+
# Runner.run!(context, collection_of_stages)
|
|
18
|
+
# ```
|
|
19
|
+
#
|
|
20
|
+
# ## Integration
|
|
21
|
+
#
|
|
22
|
+
# Called by Servactory::Context::Callable to execute all actions
|
|
23
|
+
# defined in a service. Works with Stages::Collection and Actions::Collection.
|
|
6
24
|
class Runner
|
|
25
|
+
# Runs the service actions.
|
|
26
|
+
#
|
|
27
|
+
# @param context [Object] The service context
|
|
28
|
+
# @param collection_of_stages [Stages::Collection] The stages to execute
|
|
29
|
+
# @return [void]
|
|
7
30
|
def self.run!(...)
|
|
8
31
|
new(...).run!
|
|
9
32
|
end
|
|
10
33
|
|
|
34
|
+
# Creates a new runner instance.
|
|
35
|
+
#
|
|
36
|
+
# @param context [Object] The service context with inputs/internals/outputs
|
|
37
|
+
# @param collection_of_stages [Stages::Collection] Collection of stages to execute
|
|
11
38
|
def initialize(context, collection_of_stages)
|
|
12
39
|
@context = context
|
|
13
40
|
@collection_of_stages = collection_of_stages
|
|
14
41
|
end
|
|
15
42
|
|
|
43
|
+
# Executes all stages in position order.
|
|
44
|
+
#
|
|
45
|
+
# Falls back to calling the service's `call` method if no stages defined.
|
|
46
|
+
#
|
|
47
|
+
# @return [void]
|
|
16
48
|
def run!
|
|
17
49
|
return use_call if @collection_of_stages.empty?
|
|
18
50
|
|
|
@@ -23,24 +55,42 @@ module Servactory
|
|
|
23
55
|
|
|
24
56
|
private
|
|
25
57
|
|
|
58
|
+
# Falls back to the service's call method when no stages defined.
|
|
59
|
+
#
|
|
60
|
+
# @return [void]
|
|
26
61
|
def use_call
|
|
27
62
|
@context.send(:call)
|
|
28
63
|
end
|
|
29
64
|
|
|
65
|
+
# Executes a single stage with its actions.
|
|
66
|
+
#
|
|
67
|
+
# Handles wrapper execution, rollbacks, and conditional skipping.
|
|
68
|
+
#
|
|
69
|
+
# @param stage [Stages::Stage] The stage to execute
|
|
70
|
+
# @return [void]
|
|
30
71
|
def call_stage(stage)
|
|
31
|
-
return if
|
|
72
|
+
return if should_skip?(stage)
|
|
32
73
|
|
|
33
|
-
wrapper = stage.wrapper
|
|
34
|
-
rollback = stage.rollback
|
|
35
74
|
actions = stage.actions.sorted_by_position
|
|
36
75
|
|
|
37
|
-
if wrapper.is_a?(Proc)
|
|
38
|
-
call_wrapper_with_actions(wrapper, rollback, actions)
|
|
76
|
+
if stage.wrapper.is_a?(Proc)
|
|
77
|
+
call_wrapper_with_actions(stage.wrapper, stage.rollback, actions)
|
|
78
|
+
elsif stage.rollback.present?
|
|
79
|
+
call_actions_with_rollback(stage.rollback, actions)
|
|
39
80
|
else
|
|
40
81
|
call_actions(actions)
|
|
41
82
|
end
|
|
42
83
|
end
|
|
43
84
|
|
|
85
|
+
# Executes actions within a wrapper proc.
|
|
86
|
+
#
|
|
87
|
+
# Handles exceptions by calling rollback if defined,
|
|
88
|
+
# otherwise fails the service with the exception details.
|
|
89
|
+
#
|
|
90
|
+
# @param wrapper [Proc] The wrapper proc (e.g., transaction block)
|
|
91
|
+
# @param rollback [Symbol, nil] Optional rollback method name
|
|
92
|
+
# @param actions [Collection] Actions to execute within wrapper
|
|
93
|
+
# @return [void]
|
|
44
94
|
def call_wrapper_with_actions(wrapper, rollback, actions) # rubocop:disable Metrics/MethodLength
|
|
45
95
|
wrapper.call(methods: -> { call_actions(actions) }, context: @context)
|
|
46
96
|
rescue StandardError => e
|
|
@@ -56,47 +106,80 @@ module Servactory
|
|
|
56
106
|
end
|
|
57
107
|
end
|
|
58
108
|
|
|
109
|
+
# Executes actions with rollback support but no wrapper.
|
|
110
|
+
#
|
|
111
|
+
# If an exception occurs, calls the rollback method with the exception.
|
|
112
|
+
#
|
|
113
|
+
# @param rollback [Symbol] The rollback method name
|
|
114
|
+
# @param actions [Collection] Actions to execute
|
|
115
|
+
# @return [void]
|
|
116
|
+
def call_actions_with_rollback(rollback, actions)
|
|
117
|
+
call_actions(actions)
|
|
118
|
+
rescue StandardError => e
|
|
119
|
+
@context.send(rollback, e)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Executes a collection of actions in order.
|
|
123
|
+
#
|
|
124
|
+
# @param actions [Collection] Actions to execute
|
|
125
|
+
# @return [void]
|
|
59
126
|
def call_actions(actions)
|
|
60
127
|
actions.each do |action|
|
|
61
|
-
next if
|
|
128
|
+
next if should_skip?(action)
|
|
62
129
|
|
|
63
130
|
call_action(action)
|
|
64
131
|
end
|
|
65
132
|
end
|
|
66
133
|
|
|
134
|
+
# Executes a single action by name.
|
|
135
|
+
#
|
|
136
|
+
# @param action [Action] The action to execute
|
|
137
|
+
# @return [void]
|
|
138
|
+
# @raise [StandardError] Re-raises unless handled by rescue handler
|
|
67
139
|
def call_action(action)
|
|
68
140
|
@context.send(action.name)
|
|
69
141
|
rescue StandardError => e
|
|
70
142
|
rescue_with_handler(e) || raise
|
|
71
143
|
end
|
|
72
144
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
is_condition_opposite =
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
is_condition_opposite ? !result : result
|
|
145
|
+
# Determines if an entity (stage or action) should be skipped.
|
|
146
|
+
#
|
|
147
|
+
# Uses the entity's condition and is_condition_opposite flag:
|
|
148
|
+
# - only_if: skips if condition is NOT met
|
|
149
|
+
# - only_unless: skips if condition IS met
|
|
150
|
+
#
|
|
151
|
+
# @param entity [Stages::Stage, Action] The entity to check
|
|
152
|
+
# @return [Boolean] true if entity should be skipped
|
|
153
|
+
def should_skip?(entity)
|
|
154
|
+
condition_result = condition_met?(entity.condition)
|
|
155
|
+
|
|
156
|
+
# only_if (is_condition_opposite = false): skip if condition is NOT met
|
|
157
|
+
# only_unless (is_condition_opposite = true): skip if condition IS met
|
|
158
|
+
entity.is_condition_opposite ? condition_result : !condition_result
|
|
89
159
|
end
|
|
90
160
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
161
|
+
# Evaluates a condition value.
|
|
162
|
+
#
|
|
163
|
+
# Handles nil (always true), boolean, and Proc conditions.
|
|
164
|
+
#
|
|
165
|
+
# @param condition [Proc, Boolean, nil] The condition to evaluate
|
|
166
|
+
# @return [Boolean] true if condition is met
|
|
167
|
+
def condition_met?(condition)
|
|
168
|
+
return true if condition.nil?
|
|
169
|
+
|
|
170
|
+
if condition.is_a?(Proc)
|
|
171
|
+
condition.call(context: @context)
|
|
172
|
+
else
|
|
173
|
+
Servactory::Utils.true?(condition)
|
|
174
|
+
end
|
|
96
175
|
end
|
|
97
176
|
|
|
177
|
+
# Attempts to handle an exception with configured rescue handlers.
|
|
178
|
+
#
|
|
179
|
+
# @param exception [Exception] The exception to handle
|
|
180
|
+
# @return [Exception, nil] The exception if handled, nil otherwise
|
|
98
181
|
def rescue_with_handler(exception) # rubocop:disable Metrics/MethodLength
|
|
99
|
-
_, handler = @context.
|
|
182
|
+
_, handler = @context.config.action_rescue_handlers.reverse_each.detect do |class_or_name, _|
|
|
100
183
|
if (detected_exception = Servactory::Utils.constantize_class(class_or_name))
|
|
101
184
|
detected_exception === exception # rubocop:disable Style/CaseEquality
|
|
102
185
|
end
|
data/lib/servactory/base.rb
CHANGED
|
@@ -2,13 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Servactory
|
|
4
4
|
class Base
|
|
5
|
-
include
|
|
6
|
-
include Info::DSL
|
|
7
|
-
include Context::DSL
|
|
8
|
-
include Inputs::DSL
|
|
9
|
-
include Internals::DSL
|
|
10
|
-
include Outputs::DSL
|
|
11
|
-
include Actions::DSL
|
|
5
|
+
include Servactory::DSL
|
|
12
6
|
|
|
13
7
|
private_class_method :new
|
|
14
8
|
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Servactory
|
|
4
|
+
module Configuration
|
|
5
|
+
class Config
|
|
6
|
+
attr_accessor :input_exception_class,
|
|
7
|
+
:internal_exception_class,
|
|
8
|
+
:output_exception_class,
|
|
9
|
+
:failure_class,
|
|
10
|
+
:success_class,
|
|
11
|
+
:result_class,
|
|
12
|
+
:action_shortcuts,
|
|
13
|
+
:action_aliases,
|
|
14
|
+
:input_option_helpers,
|
|
15
|
+
:internal_option_helpers,
|
|
16
|
+
:output_option_helpers,
|
|
17
|
+
:collection_mode_class_names,
|
|
18
|
+
:hash_mode_class_names,
|
|
19
|
+
:action_rescue_handlers,
|
|
20
|
+
:i18n_root_key,
|
|
21
|
+
:predicate_methods_enabled
|
|
22
|
+
|
|
23
|
+
def initialize_dup(original) # rubocop:disable Metrics/AbcSize
|
|
24
|
+
super
|
|
25
|
+
@action_shortcuts = original.action_shortcuts.dup
|
|
26
|
+
@action_aliases = original.action_aliases.dup
|
|
27
|
+
@input_option_helpers = original.input_option_helpers.dup
|
|
28
|
+
@internal_option_helpers = original.internal_option_helpers.dup
|
|
29
|
+
@output_option_helpers = original.output_option_helpers.dup
|
|
30
|
+
@collection_mode_class_names = original.collection_mode_class_names.dup
|
|
31
|
+
@hash_mode_class_names = original.hash_mode_class_names.dup
|
|
32
|
+
@action_rescue_handlers = original.action_rescue_handlers.dup
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Servactory
|
|
4
|
+
module Configuration
|
|
5
|
+
module Configurable
|
|
6
|
+
def self.included(base)
|
|
7
|
+
base.extend(ClassMethods)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
module ClassMethods
|
|
11
|
+
def self.extended(base)
|
|
12
|
+
base.instance_variable_set(:@config, base.send(:build_default_config))
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
attr_reader :config
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def build_default_config # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
20
|
+
Config.new.tap do |config|
|
|
21
|
+
# NOTE: Internal (MUST be first - used by option_helpers)
|
|
22
|
+
config.collection_mode_class_names =
|
|
23
|
+
CollectionMode::ClassNamesCollection.new(default_collection_mode_class_names)
|
|
24
|
+
config.hash_mode_class_names =
|
|
25
|
+
HashMode::ClassNamesCollection.new(default_hash_mode_class_names)
|
|
26
|
+
|
|
27
|
+
# NOTE: Exception classes
|
|
28
|
+
config.input_exception_class = Servactory::Exceptions::Input
|
|
29
|
+
config.internal_exception_class = Servactory::Exceptions::Internal
|
|
30
|
+
config.output_exception_class = Servactory::Exceptions::Output
|
|
31
|
+
config.failure_class = Servactory::Exceptions::Failure
|
|
32
|
+
config.success_class = Servactory::Exceptions::Success
|
|
33
|
+
|
|
34
|
+
# NOTE: Result
|
|
35
|
+
config.result_class = Servactory::Result
|
|
36
|
+
|
|
37
|
+
# NOTE: Actions
|
|
38
|
+
config.action_shortcuts = Actions::Shortcuts::Collection.new
|
|
39
|
+
config.action_aliases = Actions::Aliases::Collection.new
|
|
40
|
+
|
|
41
|
+
# NOTE: Option helpers (uses collection_mode_class_names)
|
|
42
|
+
config.input_option_helpers =
|
|
43
|
+
OptionHelpers::OptionHelpersCollection.new(default_input_option_helpers(config))
|
|
44
|
+
config.internal_option_helpers =
|
|
45
|
+
OptionHelpers::OptionHelpersCollection.new(default_internal_option_helpers(config))
|
|
46
|
+
config.output_option_helpers =
|
|
47
|
+
OptionHelpers::OptionHelpersCollection.new(default_output_option_helpers(config))
|
|
48
|
+
|
|
49
|
+
# NOTE: Other
|
|
50
|
+
config.action_rescue_handlers = Actions::RescueHandlers::Collection.new
|
|
51
|
+
config.i18n_root_key = "servactory"
|
|
52
|
+
config.predicate_methods_enabled = true
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def default_collection_mode_class_names
|
|
57
|
+
Set[Array, Set]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def default_hash_mode_class_names
|
|
61
|
+
Set[Hash]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def default_input_option_helpers(config)
|
|
65
|
+
Set[
|
|
66
|
+
Servactory::Maintenance::Attributes::OptionHelper
|
|
67
|
+
.new(name: :optional, equivalent: { required: false }),
|
|
68
|
+
Servactory::ToolKit::DynamicOptions::ConsistsOf
|
|
69
|
+
.use(collection_mode_class_names: config.collection_mode_class_names),
|
|
70
|
+
Servactory::ToolKit::DynamicOptions::Schema.use(default_hash_mode_class_names:),
|
|
71
|
+
Servactory::ToolKit::DynamicOptions::Inclusion.use
|
|
72
|
+
]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def default_internal_option_helpers(config)
|
|
76
|
+
Set[
|
|
77
|
+
Servactory::ToolKit::DynamicOptions::ConsistsOf
|
|
78
|
+
.use(collection_mode_class_names: config.collection_mode_class_names),
|
|
79
|
+
Servactory::ToolKit::DynamicOptions::Schema.use(default_hash_mode_class_names:),
|
|
80
|
+
Servactory::ToolKit::DynamicOptions::Inclusion.use
|
|
81
|
+
]
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def default_output_option_helpers(config)
|
|
85
|
+
Set[
|
|
86
|
+
Servactory::ToolKit::DynamicOptions::ConsistsOf
|
|
87
|
+
.use(collection_mode_class_names: config.collection_mode_class_names),
|
|
88
|
+
Servactory::ToolKit::DynamicOptions::Schema.use(default_hash_mode_class_names:),
|
|
89
|
+
Servactory::ToolKit::DynamicOptions::Inclusion.use
|
|
90
|
+
]
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -5,38 +5,14 @@ module Servactory
|
|
|
5
5
|
module DSL
|
|
6
6
|
def self.included(base)
|
|
7
7
|
base.extend(ClassMethods)
|
|
8
|
+
base.include(Configurable)
|
|
8
9
|
end
|
|
9
10
|
|
|
10
11
|
module ClassMethods
|
|
11
|
-
def inherited(child)
|
|
12
|
+
def inherited(child)
|
|
12
13
|
super
|
|
13
14
|
|
|
14
|
-
child.config
|
|
15
|
-
child.config.internal_exception_class = config.internal_exception_class
|
|
16
|
-
child.config.output_exception_class = config.output_exception_class
|
|
17
|
-
|
|
18
|
-
child.config.success_class = config.success_class
|
|
19
|
-
child.config.failure_class = config.failure_class
|
|
20
|
-
|
|
21
|
-
child.config.result_class = config.result_class
|
|
22
|
-
|
|
23
|
-
child.config.collection_mode_class_names = config.collection_mode_class_names
|
|
24
|
-
|
|
25
|
-
child.config.input_option_helpers = config.input_option_helpers
|
|
26
|
-
child.config.internal_option_helpers = config.internal_option_helpers
|
|
27
|
-
child.config.output_option_helpers = config.output_option_helpers
|
|
28
|
-
|
|
29
|
-
child.config.action_aliases = config.action_aliases
|
|
30
|
-
child.config.action_shortcuts = config.action_shortcuts
|
|
31
|
-
child.config.action_rescue_handlers = config.action_rescue_handlers
|
|
32
|
-
|
|
33
|
-
child.config.i18n_root_key = config.i18n_root_key
|
|
34
|
-
|
|
35
|
-
child.config.predicate_methods_enabled = config.predicate_methods_enabled
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def config
|
|
39
|
-
@config ||= Servactory::Configuration::Setup.new
|
|
15
|
+
child.instance_variable_set(:@config, config.dup)
|
|
40
16
|
end
|
|
41
17
|
|
|
42
18
|
private
|
|
@@ -39,12 +39,24 @@ module Servactory
|
|
|
39
39
|
raise_error_about_wrong_result_class_with(:result_class, result_class)
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
def
|
|
43
|
-
|
|
42
|
+
def action_shortcuts(array, hash = {}) # rubocop:disable Metrics/MethodLength
|
|
43
|
+
prepared = array.to_h do |action_shortcut|
|
|
44
|
+
[
|
|
45
|
+
action_shortcut,
|
|
46
|
+
{
|
|
47
|
+
prefix: action_shortcut,
|
|
48
|
+
suffix: nil
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
prepared = prepared.merge(hash)
|
|
54
|
+
|
|
55
|
+
@config.action_shortcuts.merge(prepared)
|
|
44
56
|
end
|
|
45
57
|
|
|
46
|
-
def
|
|
47
|
-
@config.
|
|
58
|
+
def action_aliases(action_aliases)
|
|
59
|
+
@config.action_aliases.merge(action_aliases)
|
|
48
60
|
end
|
|
49
61
|
|
|
50
62
|
def input_option_helpers(input_option_helpers)
|
|
@@ -59,24 +71,12 @@ module Servactory
|
|
|
59
71
|
@config.output_option_helpers.merge(output_option_helpers)
|
|
60
72
|
end
|
|
61
73
|
|
|
62
|
-
def
|
|
63
|
-
@config.
|
|
74
|
+
def collection_mode_class_names(collection_mode_class_names)
|
|
75
|
+
@config.collection_mode_class_names.merge(collection_mode_class_names)
|
|
64
76
|
end
|
|
65
77
|
|
|
66
|
-
def
|
|
67
|
-
|
|
68
|
-
[
|
|
69
|
-
action_shortcut,
|
|
70
|
-
{
|
|
71
|
-
prefix: action_shortcut,
|
|
72
|
-
suffix: nil
|
|
73
|
-
}
|
|
74
|
-
]
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
prepared = prepared.merge(hash)
|
|
78
|
-
|
|
79
|
-
@config.action_shortcuts.merge(prepared)
|
|
78
|
+
def hash_mode_class_names(hash_mode_class_names)
|
|
79
|
+
@config.hash_mode_class_names.merge(hash_mode_class_names)
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
def i18n_root_key(value)
|
|
@@ -12,6 +12,11 @@ module Servactory
|
|
|
12
12
|
@collection = collection
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
def initialize_dup(original)
|
|
16
|
+
super
|
|
17
|
+
@collection = original.instance_variable_get(:@collection).dup
|
|
18
|
+
end
|
|
19
|
+
|
|
15
20
|
def dynamic_options
|
|
16
21
|
OptionHelpersCollection.new(filter(&:dynamic_option?))
|
|
17
22
|
end
|
|
@@ -21,11 +21,11 @@ module Servactory
|
|
|
21
21
|
##########################################################################
|
|
22
22
|
|
|
23
23
|
def method_missing(name, *_args)
|
|
24
|
-
input_name = @context.
|
|
24
|
+
input_name = @context.config.predicate_methods_enabled ? name.to_s.chomp("?").to_sym : name
|
|
25
25
|
|
|
26
26
|
input_value = @arguments.fetch(input_name) { raise_error_for(input_name) }
|
|
27
27
|
|
|
28
|
-
if name.to_s.end_with?("?") && @context.
|
|
28
|
+
if name.to_s.end_with?("?") && @context.config.predicate_methods_enabled
|
|
29
29
|
Servactory::Utils.query_attribute(input_value)
|
|
30
30
|
else
|
|
31
31
|
input_value
|
|
@@ -39,7 +39,7 @@ module Servactory
|
|
|
39
39
|
|
|
40
40
|
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Lint/UnusedMethodArgument
|
|
41
41
|
def fetch_with(name:, &block)
|
|
42
|
-
input_name = @context.
|
|
42
|
+
input_name = @context.config.predicate_methods_enabled ? name.to_s.chomp("?").to_sym : name
|
|
43
43
|
|
|
44
44
|
input = @collection_of_inputs.find_by(name: input_name)
|
|
45
45
|
|
|
@@ -54,7 +54,7 @@ module Servactory
|
|
|
54
54
|
input_prepare = input.prepare.fetch(:in, nil)
|
|
55
55
|
input_value = input_prepare.call(value: input_value) if input_prepare.present?
|
|
56
56
|
|
|
57
|
-
if name.to_s.end_with?("?") && @context.
|
|
57
|
+
if name.to_s.end_with?("?") && @context.config.predicate_methods_enabled
|
|
58
58
|
Servactory::Utils.query_attribute(input_value)
|
|
59
59
|
else
|
|
60
60
|
input_value
|
|
@@ -54,7 +54,7 @@ module Servactory
|
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
def fetch_with(name:, &block) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Lint/UnusedMethodArgument
|
|
57
|
-
internal_name = @context.
|
|
57
|
+
internal_name = @context.config.predicate_methods_enabled ? name.to_s.chomp("?").to_sym : name
|
|
58
58
|
internal = @collection_of_internals.find_by(name: internal_name)
|
|
59
59
|
|
|
60
60
|
return yield if internal.nil?
|
|
@@ -67,7 +67,7 @@ module Servactory
|
|
|
67
67
|
value: internal_value
|
|
68
68
|
)
|
|
69
69
|
|
|
70
|
-
if name.to_s.end_with?("?") && @context.
|
|
70
|
+
if name.to_s.end_with?("?") && @context.config.predicate_methods_enabled
|
|
71
71
|
Servactory::Utils.query_attribute(internal_value)
|
|
72
72
|
else
|
|
73
73
|
internal_value
|
|
@@ -54,14 +54,14 @@ module Servactory
|
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
def fetch_with(name:, &block) # rubocop:disable Metrics/AbcSize, Lint/UnusedMethodArgument
|
|
57
|
-
output_name = @context.
|
|
57
|
+
output_name = @context.config.predicate_methods_enabled ? name.to_s.chomp("?").to_sym : name
|
|
58
58
|
output = @collection_of_outputs.find_by(name: output_name)
|
|
59
59
|
|
|
60
60
|
return yield if output.nil?
|
|
61
61
|
|
|
62
62
|
output_value = @context.send(:servactory_service_warehouse).fetch_output(output.name)
|
|
63
63
|
|
|
64
|
-
if name.to_s.end_with?("?") && @context.
|
|
64
|
+
if name.to_s.end_with?("?") && @context.config.predicate_methods_enabled
|
|
65
65
|
Servactory::Utils.query_attribute(output_value)
|
|
66
66
|
else
|
|
67
67
|
output_value
|
|
@@ -8,7 +8,7 @@ module Servactory
|
|
|
8
8
|
|
|
9
9
|
def initialize(context)
|
|
10
10
|
@class_name = context.class.name
|
|
11
|
-
@i18n_root_key = context.
|
|
11
|
+
@i18n_root_key = context.config.i18n_root_key
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def translate(key, **options)
|
|
@@ -42,11 +42,11 @@ module Servactory
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
def success!
|
|
45
|
-
raise
|
|
45
|
+
raise config.success_class.new(context: self)
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def fail_input!(input_name, message:, meta: nil)
|
|
49
|
-
raise
|
|
49
|
+
raise config.input_exception_class.new(
|
|
50
50
|
context: self,
|
|
51
51
|
input_name:,
|
|
52
52
|
message:,
|
|
@@ -55,7 +55,7 @@ module Servactory
|
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def fail_internal!(internal_name, message:, meta: nil)
|
|
58
|
-
raise
|
|
58
|
+
raise config.internal_exception_class.new(
|
|
59
59
|
context: self,
|
|
60
60
|
internal_name:,
|
|
61
61
|
message:,
|
|
@@ -64,7 +64,7 @@ module Servactory
|
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
def fail_output!(output_name, message:, meta: nil)
|
|
67
|
-
raise
|
|
67
|
+
raise config.output_exception_class.new(
|
|
68
68
|
context: self,
|
|
69
69
|
output_name:,
|
|
70
70
|
message:,
|
|
@@ -73,13 +73,17 @@ module Servactory
|
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
def fail!(type = :base, message:, meta: nil)
|
|
76
|
-
raise
|
|
76
|
+
raise config.failure_class.new(type:, message:, meta:)
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
def fail_result!(service_result)
|
|
80
80
|
fail!(service_result.error.type, message: service_result.error.message, meta: service_result.error.meta)
|
|
81
81
|
end
|
|
82
82
|
|
|
83
|
+
def config
|
|
84
|
+
self.class.config
|
|
85
|
+
end
|
|
86
|
+
|
|
83
87
|
private
|
|
84
88
|
|
|
85
89
|
attr_reader :collection_of_inputs,
|
|
@@ -114,7 +118,7 @@ module Servactory
|
|
|
114
118
|
end
|
|
115
119
|
|
|
116
120
|
def call
|
|
117
|
-
raise
|
|
121
|
+
raise config.failure_class.new(
|
|
118
122
|
type: :base,
|
|
119
123
|
message: servactory_service_info.translate(
|
|
120
124
|
"methods.call.not_used"
|