servactory 3.0.0.rc1 → 3.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/lib/servactory/dsl.rb +9 -9
- data/lib/servactory/maintenance/attributes/option.rb +1 -5
- data/lib/servactory/maintenance/attributes/options_collection.rb +75 -3
- data/lib/servactory/tool_kit/dynamic_options/target.rb +19 -23
- data/lib/servactory/version.rb +1 -1
- data/lib/servactory.rb +2 -0
- metadata +2 -47
- data/lib/servactory/stroma/dsl.rb +0 -118
- data/lib/servactory/stroma/entry.rb +0 -32
- data/lib/servactory/stroma/exceptions/base.rb +0 -45
- data/lib/servactory/stroma/exceptions/invalid_hook_type.rb +0 -29
- data/lib/servactory/stroma/exceptions/key_already_registered.rb +0 -32
- data/lib/servactory/stroma/exceptions/registry_frozen.rb +0 -33
- data/lib/servactory/stroma/exceptions/registry_not_finalized.rb +0 -33
- data/lib/servactory/stroma/exceptions/unknown_hook_target.rb +0 -39
- data/lib/servactory/stroma/hooks/applier.rb +0 -63
- data/lib/servactory/stroma/hooks/collection.rb +0 -103
- data/lib/servactory/stroma/hooks/factory.rb +0 -80
- data/lib/servactory/stroma/hooks/hook.rb +0 -74
- data/lib/servactory/stroma/registry.rb +0 -94
- data/lib/servactory/stroma/settings/collection.rb +0 -90
- data/lib/servactory/stroma/settings/registry_settings.rb +0 -88
- data/lib/servactory/stroma/settings/setting.rb +0 -113
- data/lib/servactory/stroma/state.rb +0 -59
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5972f03405d88ae923f1e000479449e281af67b9d22b52010d2131dc1023cc15
|
|
4
|
+
data.tar.gz: 6c7c495d158deee0453114fb637897a2431d7ce4efc4e522a0716ec28a7dd89b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 82e84edd70b3ee47a91944bd60e5d9bec1cf33b18ca5d008d40973685c796cfa31b48de2f0599764c864db535959cd86a073ed30725c1fe1af49a98ce4bd72ab
|
|
7
|
+
data.tar.gz: 585a53ba4491246e5e4aaec23568e074a2d142d467b9d44bc551d629bce2047fcfd99d89c0bdcb897e9a28e9f7037b9128396107fe6c01083ff0b4298ee11f71
|
data/lib/servactory/dsl.rb
CHANGED
|
@@ -16,17 +16,17 @@ module Servactory
|
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
Stroma::Registry.register(:configuration, Configuration::DSL)
|
|
20
|
-
Stroma::Registry.register(:info, Info::DSL)
|
|
21
|
-
Stroma::Registry.register(:context, Context::DSL)
|
|
22
|
-
Stroma::Registry.register(:inputs, Inputs::DSL)
|
|
23
|
-
Stroma::Registry.register(:internals, Internals::DSL)
|
|
24
|
-
Stroma::Registry.register(:outputs, Outputs::DSL)
|
|
25
|
-
Stroma::Registry.register(:actions, Actions::DSL)
|
|
26
|
-
Stroma::Registry.finalize!
|
|
19
|
+
::Stroma::Registry.register(:configuration, Configuration::DSL)
|
|
20
|
+
::Stroma::Registry.register(:info, Info::DSL)
|
|
21
|
+
::Stroma::Registry.register(:context, Context::DSL)
|
|
22
|
+
::Stroma::Registry.register(:inputs, Inputs::DSL)
|
|
23
|
+
::Stroma::Registry.register(:internals, Internals::DSL)
|
|
24
|
+
::Stroma::Registry.register(:outputs, Outputs::DSL)
|
|
25
|
+
::Stroma::Registry.register(:actions, Actions::DSL)
|
|
26
|
+
::Stroma::Registry.finalize!
|
|
27
27
|
|
|
28
28
|
def self.included(base)
|
|
29
|
-
base.include(Stroma::DSL)
|
|
29
|
+
base.include(::Stroma::DSL)
|
|
30
30
|
|
|
31
31
|
Extensions.registry.each { |extension| base.include(extension) }
|
|
32
32
|
end
|
|
@@ -136,11 +136,7 @@ module Servactory
|
|
|
136
136
|
return if @define_methods.blank?
|
|
137
137
|
|
|
138
138
|
@define_methods.map do |define_method|
|
|
139
|
-
|
|
140
|
-
def #{define_method.name};
|
|
141
|
-
#{define_method.content.call(option: @body)};
|
|
142
|
-
end
|
|
143
|
-
RUBY
|
|
139
|
+
"def #{define_method.name}; #{define_method.content.call(option: @body)}; end"
|
|
144
140
|
end.join("; ")
|
|
145
141
|
end
|
|
146
142
|
end
|
|
@@ -3,19 +3,64 @@
|
|
|
3
3
|
module Servactory
|
|
4
4
|
module Maintenance
|
|
5
5
|
module Attributes
|
|
6
|
+
# Collection wrapper for managing Option objects.
|
|
7
|
+
#
|
|
8
|
+
# ## Purpose
|
|
9
|
+
#
|
|
10
|
+
# OptionsCollection provides a unified interface for storing and querying
|
|
11
|
+
# Option instances associated with service attributes (inputs, internals, outputs).
|
|
12
|
+
# It wraps a Set to ensure uniqueness and delegates common enumeration methods.
|
|
13
|
+
#
|
|
14
|
+
# ## Usage
|
|
15
|
+
#
|
|
16
|
+
# The collection is used internally by Input, Internal, and Output classes
|
|
17
|
+
# to manage their registered options:
|
|
18
|
+
#
|
|
19
|
+
# ```ruby
|
|
20
|
+
# collection = OptionsCollection.new
|
|
21
|
+
# collection << Option.new(name: :required, ...)
|
|
22
|
+
# collection << Option.new(name: :types, ...)
|
|
23
|
+
#
|
|
24
|
+
# collection.names # => [:required, :types]
|
|
25
|
+
# collection.find_by(name: :required) # => Option instance
|
|
26
|
+
# ```
|
|
27
|
+
#
|
|
28
|
+
# ## Performance
|
|
29
|
+
#
|
|
30
|
+
# The collection uses memoization for frequently accessed data:
|
|
31
|
+
# - `validation_classes` - cached list of unique validation classes
|
|
32
|
+
# - `options_for_checks` - cached hash for validation pipeline
|
|
33
|
+
# - `options_index` - cached hash for O(1) lookups by name
|
|
34
|
+
#
|
|
6
35
|
class OptionsCollection
|
|
7
36
|
extend Forwardable
|
|
8
37
|
|
|
9
|
-
def_delegators :@collection,
|
|
38
|
+
def_delegators :@collection,
|
|
39
|
+
:<<,
|
|
40
|
+
:filter,
|
|
41
|
+
:each, :each_with_object,
|
|
42
|
+
:map, :flat_map,
|
|
43
|
+
:find,
|
|
44
|
+
:size,
|
|
45
|
+
:empty?
|
|
10
46
|
|
|
47
|
+
# Initializes an empty collection.
|
|
48
|
+
#
|
|
49
|
+
# @return [OptionsCollection]
|
|
11
50
|
def initialize
|
|
12
51
|
@collection = Set.new
|
|
13
52
|
end
|
|
14
53
|
|
|
54
|
+
# Returns all option names in the collection.
|
|
55
|
+
#
|
|
56
|
+
# @return [Array<Symbol>] list of option names
|
|
15
57
|
def names
|
|
16
58
|
map(&:name)
|
|
17
59
|
end
|
|
18
60
|
|
|
61
|
+
# Returns unique validation classes from all options.
|
|
62
|
+
#
|
|
63
|
+
# @return [Array<Class>] deduplicated list of validation classes
|
|
19
64
|
def validation_classes
|
|
20
65
|
@validation_classes ||=
|
|
21
66
|
filter { |option| option.validation_class.present? }
|
|
@@ -23,24 +68,47 @@ module Servactory
|
|
|
23
68
|
.uniq
|
|
24
69
|
end
|
|
25
70
|
|
|
71
|
+
# Returns options that need validation checks as a hash.
|
|
72
|
+
#
|
|
73
|
+
# @return [Hash{Symbol => Object}] option names mapped to normalized bodies
|
|
26
74
|
def options_for_checks
|
|
27
|
-
filter(&:need_for_checks?).to_h do |option|
|
|
75
|
+
@options_for_checks ||= filter(&:need_for_checks?).to_h do |option|
|
|
28
76
|
[option.name, extract_normalized_body_from(option:)]
|
|
29
77
|
end
|
|
30
78
|
end
|
|
31
79
|
|
|
80
|
+
# Returns the first conflict code found among options.
|
|
81
|
+
#
|
|
82
|
+
# @return [Object, nil] conflict code or nil if no conflicts
|
|
32
83
|
def defined_conflict_code
|
|
33
84
|
flat_map { |option| resolve_conflicts_from(option:) }
|
|
34
85
|
.reject(&:blank?)
|
|
35
86
|
.first
|
|
36
87
|
end
|
|
37
88
|
|
|
89
|
+
# Finds an option by its name using indexed lookup.
|
|
90
|
+
#
|
|
91
|
+
# @param name [Symbol] the option name to find
|
|
92
|
+
# @return [Option, nil] the found option or nil
|
|
38
93
|
def find_by(name:)
|
|
39
|
-
|
|
94
|
+
options_index[name]
|
|
40
95
|
end
|
|
41
96
|
|
|
42
97
|
private
|
|
43
98
|
|
|
99
|
+
# Builds and caches a hash index for O(1) option lookups.
|
|
100
|
+
#
|
|
101
|
+
# @return [Hash{Symbol => Option}] option names mapped to Option instances
|
|
102
|
+
def options_index
|
|
103
|
+
@options_index ||= each_with_object({}) do |option, index|
|
|
104
|
+
index[option.name] = option
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Extracts the normalized body value from an option.
|
|
109
|
+
#
|
|
110
|
+
# @param option [Option] the option to extract from
|
|
111
|
+
# @return [Object] the :is value if body is a Hash with :is key, otherwise the full body
|
|
44
112
|
def extract_normalized_body_from(option:)
|
|
45
113
|
body = option.body
|
|
46
114
|
return body unless body.is_a?(Hash)
|
|
@@ -48,6 +116,10 @@ module Servactory
|
|
|
48
116
|
body.key?(:is) ? body.fetch(:is) : body
|
|
49
117
|
end
|
|
50
118
|
|
|
119
|
+
# Resolves conflict codes from an option's define_conflicts.
|
|
120
|
+
#
|
|
121
|
+
# @param option [Option] the option to check for conflicts
|
|
122
|
+
# @return [Array<Object>] array of conflict codes (may contain nils/blanks)
|
|
51
123
|
def resolve_conflicts_from(option:)
|
|
52
124
|
return [] unless option.define_conflicts
|
|
53
125
|
|
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
module Servactory
|
|
4
4
|
module ToolKit
|
|
5
5
|
module DynamicOptions
|
|
6
|
-
# Validates that attribute value matches one of the target
|
|
6
|
+
# Validates that Class-typed attribute value matches one of the target classes.
|
|
7
7
|
#
|
|
8
8
|
# ## Purpose
|
|
9
9
|
#
|
|
10
|
-
# Target provides
|
|
11
|
-
# It ensures that the
|
|
12
|
-
# supporting both single
|
|
13
|
-
# This is useful for
|
|
14
|
-
#
|
|
10
|
+
# Target provides class matching validation for Class-typed attributes.
|
|
11
|
+
# It ensures that the passed class is one of the specified target classes,
|
|
12
|
+
# supporting both single class and arrays of acceptable classes.
|
|
13
|
+
# This is useful for validating service classes, strategy patterns,
|
|
14
|
+
# or any scenario where specific classes are expected.
|
|
15
15
|
#
|
|
16
16
|
# ## Usage
|
|
17
17
|
#
|
|
@@ -38,22 +38,18 @@ module Servactory
|
|
|
38
38
|
#
|
|
39
39
|
# ```ruby
|
|
40
40
|
# class ProcessOrderService < ApplicationService::Base
|
|
41
|
-
# input :
|
|
42
|
-
# input :
|
|
43
|
-
# input :model_class, type: Class, target: { in: [User, Admin] }
|
|
41
|
+
# input :service_class, type: Class, target: UserService
|
|
42
|
+
# input :handler_class, type: Class, target: [CreateHandler, UpdateHandler]
|
|
44
43
|
# end
|
|
45
44
|
# ```
|
|
46
45
|
#
|
|
47
46
|
# ## Simple Mode
|
|
48
47
|
#
|
|
49
|
-
# Specify target
|
|
48
|
+
# Specify target class directly or as an array:
|
|
50
49
|
#
|
|
51
50
|
# ```ruby
|
|
52
|
-
#
|
|
53
|
-
#
|
|
54
|
-
# input :priority, type: Integer, target: [1, 2, 3]
|
|
55
|
-
# input :model_class, type: Class, target: [User, Admin]
|
|
56
|
-
# end
|
|
51
|
+
# input :service_class, type: Class, target: UserService
|
|
52
|
+
# input :handler_class, type: Class, target: [CreateHandler, UpdateHandler]
|
|
57
53
|
# ```
|
|
58
54
|
#
|
|
59
55
|
# ## Advanced Mode
|
|
@@ -64,19 +60,19 @@ module Servactory
|
|
|
64
60
|
# With static message:
|
|
65
61
|
#
|
|
66
62
|
# ```ruby
|
|
67
|
-
# input :
|
|
68
|
-
# in: [
|
|
69
|
-
# message: "Input `
|
|
63
|
+
# input :handler_class, type: Class, target: {
|
|
64
|
+
# in: [CreateHandler, UpdateHandler],
|
|
65
|
+
# message: "Input `handler_class` must be one of: CreateHandler, UpdateHandler"
|
|
70
66
|
# }
|
|
71
67
|
# ```
|
|
72
68
|
#
|
|
73
69
|
# With dynamic lambda message:
|
|
74
70
|
#
|
|
75
71
|
# ```ruby
|
|
76
|
-
# input :
|
|
77
|
-
# in: [
|
|
72
|
+
# input :handler_class, type: Class, target: {
|
|
73
|
+
# in: [CreateHandler, UpdateHandler],
|
|
78
74
|
# message: lambda do |input:, value:, option_value:, **|
|
|
79
|
-
# "Input `#{input.name}`
|
|
75
|
+
# "Input `#{input.name}` received `#{value}`, expected: #{Array(option_value).map(&:name).join(', ')}"
|
|
80
76
|
# end
|
|
81
77
|
# }
|
|
82
78
|
# ```
|
|
@@ -88,8 +84,8 @@ module Servactory
|
|
|
88
84
|
#
|
|
89
85
|
# ## Validation Rules
|
|
90
86
|
#
|
|
91
|
-
# -
|
|
92
|
-
# - Supports single
|
|
87
|
+
# - Class must exactly match one of the target classes
|
|
88
|
+
# - Supports single class or array of classes
|
|
93
89
|
# - Optional inputs with nil value validate against default
|
|
94
90
|
#
|
|
95
91
|
# ## Important Notes
|
data/lib/servactory/version.rb
CHANGED
data/lib/servactory.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: servactory
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.0.0.
|
|
4
|
+
version: 3.0.0.rc3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Anton Sokolov
|
|
@@ -23,34 +23,6 @@ dependencies:
|
|
|
23
23
|
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '5.1'
|
|
26
|
-
- !ruby/object:Gem::Dependency
|
|
27
|
-
name: base64
|
|
28
|
-
requirement: !ruby/object:Gem::Requirement
|
|
29
|
-
requirements:
|
|
30
|
-
- - ">="
|
|
31
|
-
- !ruby/object:Gem::Version
|
|
32
|
-
version: '0.2'
|
|
33
|
-
type: :runtime
|
|
34
|
-
prerelease: false
|
|
35
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
-
requirements:
|
|
37
|
-
- - ">="
|
|
38
|
-
- !ruby/object:Gem::Version
|
|
39
|
-
version: '0.2'
|
|
40
|
-
- !ruby/object:Gem::Dependency
|
|
41
|
-
name: bigdecimal
|
|
42
|
-
requirement: !ruby/object:Gem::Requirement
|
|
43
|
-
requirements:
|
|
44
|
-
- - ">="
|
|
45
|
-
- !ruby/object:Gem::Version
|
|
46
|
-
version: '3.1'
|
|
47
|
-
type: :runtime
|
|
48
|
-
prerelease: false
|
|
49
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
-
requirements:
|
|
51
|
-
- - ">="
|
|
52
|
-
- !ruby/object:Gem::Version
|
|
53
|
-
version: '3.1'
|
|
54
26
|
- !ruby/object:Gem::Dependency
|
|
55
27
|
name: i18n
|
|
56
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -66,7 +38,7 @@ dependencies:
|
|
|
66
38
|
- !ruby/object:Gem::Version
|
|
67
39
|
version: '1.14'
|
|
68
40
|
- !ruby/object:Gem::Dependency
|
|
69
|
-
name:
|
|
41
|
+
name: stroma
|
|
70
42
|
requirement: !ruby/object:Gem::Requirement
|
|
71
43
|
requirements:
|
|
72
44
|
- - ">="
|
|
@@ -312,23 +284,6 @@ files:
|
|
|
312
284
|
- lib/servactory/outputs/dsl.rb
|
|
313
285
|
- lib/servactory/outputs/output.rb
|
|
314
286
|
- lib/servactory/result.rb
|
|
315
|
-
- lib/servactory/stroma/dsl.rb
|
|
316
|
-
- lib/servactory/stroma/entry.rb
|
|
317
|
-
- lib/servactory/stroma/exceptions/base.rb
|
|
318
|
-
- lib/servactory/stroma/exceptions/invalid_hook_type.rb
|
|
319
|
-
- lib/servactory/stroma/exceptions/key_already_registered.rb
|
|
320
|
-
- lib/servactory/stroma/exceptions/registry_frozen.rb
|
|
321
|
-
- lib/servactory/stroma/exceptions/registry_not_finalized.rb
|
|
322
|
-
- lib/servactory/stroma/exceptions/unknown_hook_target.rb
|
|
323
|
-
- lib/servactory/stroma/hooks/applier.rb
|
|
324
|
-
- lib/servactory/stroma/hooks/collection.rb
|
|
325
|
-
- lib/servactory/stroma/hooks/factory.rb
|
|
326
|
-
- lib/servactory/stroma/hooks/hook.rb
|
|
327
|
-
- lib/servactory/stroma/registry.rb
|
|
328
|
-
- lib/servactory/stroma/settings/collection.rb
|
|
329
|
-
- lib/servactory/stroma/settings/registry_settings.rb
|
|
330
|
-
- lib/servactory/stroma/settings/setting.rb
|
|
331
|
-
- lib/servactory/stroma/state.rb
|
|
332
287
|
- lib/servactory/test_kit/fake_type.rb
|
|
333
288
|
- lib/servactory/test_kit/result.rb
|
|
334
289
|
- lib/servactory/test_kit/rspec/helpers.rb
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Servactory
|
|
4
|
-
module Stroma
|
|
5
|
-
# Main integration point between Stroma and service classes.
|
|
6
|
-
#
|
|
7
|
-
# ## Purpose
|
|
8
|
-
#
|
|
9
|
-
# Module that provides the core Stroma functionality to service classes:
|
|
10
|
-
# - Includes all registered DSL modules
|
|
11
|
-
# - Provides extensions block for hook registration
|
|
12
|
-
# - Handles inheritance with proper state copying
|
|
13
|
-
#
|
|
14
|
-
# ## Usage
|
|
15
|
-
#
|
|
16
|
-
# ```ruby
|
|
17
|
-
# class MyService
|
|
18
|
-
# include Servactory::Stroma::DSL
|
|
19
|
-
#
|
|
20
|
-
# extensions do
|
|
21
|
-
# before :actions, MyExtension
|
|
22
|
-
# end
|
|
23
|
-
# end
|
|
24
|
-
# ```
|
|
25
|
-
#
|
|
26
|
-
# ## Extension Settings Access
|
|
27
|
-
#
|
|
28
|
-
# Extensions access their settings through the stroma.settings hierarchy:
|
|
29
|
-
#
|
|
30
|
-
# ```ruby
|
|
31
|
-
# # In ClassMethods:
|
|
32
|
-
# stroma.settings[:actions][:authorization][:method_name] = :authorize
|
|
33
|
-
#
|
|
34
|
-
# # In InstanceMethods:
|
|
35
|
-
# self.class.stroma.settings[:actions][:authorization][:method_name]
|
|
36
|
-
# ```
|
|
37
|
-
#
|
|
38
|
-
# ## Integration
|
|
39
|
-
#
|
|
40
|
-
# Included by Servactory::DSL which is included by Servactory::Base.
|
|
41
|
-
# Provides ClassMethods with: stroma, inherited, extensions.
|
|
42
|
-
module DSL
|
|
43
|
-
def self.included(base)
|
|
44
|
-
base.extend(ClassMethods)
|
|
45
|
-
|
|
46
|
-
Registry.entries.each do |entry|
|
|
47
|
-
base.include(entry.extension)
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
# Class-level methods for Stroma integration.
|
|
52
|
-
#
|
|
53
|
-
# ## Purpose
|
|
54
|
-
#
|
|
55
|
-
# Provides access to Stroma state and hooks DSL at the class level.
|
|
56
|
-
# Handles proper duplication during inheritance.
|
|
57
|
-
#
|
|
58
|
-
# ## Key Methods
|
|
59
|
-
#
|
|
60
|
-
# - `stroma` - Access the State container
|
|
61
|
-
# - `inherited` - Copy state to child classes
|
|
62
|
-
# - `extensions` - DSL block for hook registration
|
|
63
|
-
module ClassMethods
|
|
64
|
-
def self.extended(base)
|
|
65
|
-
base.instance_variable_set(:@stroma, State.new)
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
# Handles inheritance by duplicating Stroma state.
|
|
69
|
-
#
|
|
70
|
-
# Creates an independent copy of hooks and settings for the child class,
|
|
71
|
-
# then applies all registered hooks to the child.
|
|
72
|
-
#
|
|
73
|
-
# @param child [Class] The child class being created
|
|
74
|
-
# @return [void]
|
|
75
|
-
def inherited(child)
|
|
76
|
-
super
|
|
77
|
-
|
|
78
|
-
child.instance_variable_set(:@stroma, stroma.dup)
|
|
79
|
-
|
|
80
|
-
Hooks::Applier.new(child, child.stroma.hooks).apply!
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
# Returns the Stroma state for this service class.
|
|
84
|
-
#
|
|
85
|
-
# @return [State] The Stroma state container
|
|
86
|
-
#
|
|
87
|
-
# @example Accessing hooks
|
|
88
|
-
# stroma.hooks.before(:actions)
|
|
89
|
-
#
|
|
90
|
-
# @example Accessing settings
|
|
91
|
-
# stroma.settings[:actions][:authorization][:method_name]
|
|
92
|
-
def stroma
|
|
93
|
-
@stroma ||= State.new
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
private
|
|
97
|
-
|
|
98
|
-
# DSL block for registering hooks.
|
|
99
|
-
#
|
|
100
|
-
# Evaluates the block in the context of a Hooks::Factory,
|
|
101
|
-
# allowing before/after hook registration.
|
|
102
|
-
#
|
|
103
|
-
# @yield Block with before/after DSL calls
|
|
104
|
-
# @return [void]
|
|
105
|
-
#
|
|
106
|
-
# @example
|
|
107
|
-
# extensions do
|
|
108
|
-
# before :actions, AuthorizationExtension
|
|
109
|
-
# after :outputs, LoggingExtension
|
|
110
|
-
# end
|
|
111
|
-
def extensions(&block)
|
|
112
|
-
@stroma_hooks_factory ||= Hooks::Factory.new(stroma.hooks)
|
|
113
|
-
@stroma_hooks_factory.instance_eval(&block)
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
end
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Servactory
|
|
4
|
-
module Stroma
|
|
5
|
-
# Represents a registered DSL entry in the Stroma registry.
|
|
6
|
-
#
|
|
7
|
-
# ## Purpose
|
|
8
|
-
#
|
|
9
|
-
# Immutable value object that holds information about a DSL module
|
|
10
|
-
# registered in the Stroma system. Each entry has a unique key
|
|
11
|
-
# and references a Module that will be included in service classes.
|
|
12
|
-
#
|
|
13
|
-
# ## Attributes
|
|
14
|
-
#
|
|
15
|
-
# - `key` (Symbol): Unique identifier for the DSL module (:inputs, :outputs, :actions)
|
|
16
|
-
# - `extension` (Module): The actual DSL module to be included
|
|
17
|
-
#
|
|
18
|
-
# ## Usage
|
|
19
|
-
#
|
|
20
|
-
# Entries are created internally by Registry.register:
|
|
21
|
-
#
|
|
22
|
-
# ```ruby
|
|
23
|
-
# Stroma::Registry.register(:inputs, Servactory::Inputs::DSL)
|
|
24
|
-
# # Creates: Entry.new(key: :inputs, extension: Servactory::Inputs::DSL)
|
|
25
|
-
# ```
|
|
26
|
-
#
|
|
27
|
-
# ## Immutability
|
|
28
|
-
#
|
|
29
|
-
# Entry is immutable (Data object) - once created, it cannot be modified.
|
|
30
|
-
Entry = Data.define(:key, :extension)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Servactory
|
|
4
|
-
module Stroma
|
|
5
|
-
module Exceptions
|
|
6
|
-
# Base exception class for all Stroma-specific exceptions
|
|
7
|
-
#
|
|
8
|
-
# ## Purpose
|
|
9
|
-
#
|
|
10
|
-
# Serves as the parent class for all custom exceptions in the Stroma subsystem.
|
|
11
|
-
# Allows catching all Stroma-related exceptions with a single rescue clause.
|
|
12
|
-
#
|
|
13
|
-
# ## Usage
|
|
14
|
-
#
|
|
15
|
-
# All Stroma exceptions inherit from this base class:
|
|
16
|
-
#
|
|
17
|
-
# ```ruby
|
|
18
|
-
# begin
|
|
19
|
-
# Servactory::Stroma::Registry.register(:custom, CustomModule)
|
|
20
|
-
# rescue Servactory::Stroma::Exceptions::Base => e
|
|
21
|
-
# # Catches any Stroma-specific exception
|
|
22
|
-
# handle_stroma_error(e)
|
|
23
|
-
# end
|
|
24
|
-
# ```
|
|
25
|
-
#
|
|
26
|
-
# ## Integration
|
|
27
|
-
#
|
|
28
|
-
# Can be used in application error handlers for centralized error handling:
|
|
29
|
-
#
|
|
30
|
-
# ```ruby
|
|
31
|
-
# rescue_from Servactory::Stroma::Exceptions::Base, with: :handle_stroma_error
|
|
32
|
-
# ```
|
|
33
|
-
#
|
|
34
|
-
# ## Subclasses
|
|
35
|
-
#
|
|
36
|
-
# - RegistryFrozen - Raised when modifying a finalized registry
|
|
37
|
-
# - RegistryNotFinalized - Raised when accessing registry before finalization
|
|
38
|
-
# - KeyAlreadyRegistered - Raised when registering a duplicate key
|
|
39
|
-
# - UnknownHookTarget - Raised when using an invalid hook target key
|
|
40
|
-
# - InvalidHookType - Raised when using an invalid hook type (:before/:after)
|
|
41
|
-
class Base < StandardError
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Servactory
|
|
4
|
-
module Stroma
|
|
5
|
-
module Exceptions
|
|
6
|
-
# Raised when an invalid hook type is provided.
|
|
7
|
-
#
|
|
8
|
-
# ## Purpose
|
|
9
|
-
#
|
|
10
|
-
# Ensures that only valid hook types (:before, :after) are used
|
|
11
|
-
# when creating Servactory::Stroma::Hooks::Hook objects. Provides fail-fast
|
|
12
|
-
# behavior during class definition rather than silent failures at runtime.
|
|
13
|
-
#
|
|
14
|
-
# ## Usage
|
|
15
|
-
#
|
|
16
|
-
# ```ruby
|
|
17
|
-
# # This will raise InvalidHookType:
|
|
18
|
-
# Servactory::Stroma::Hooks::Hook.new(
|
|
19
|
-
# type: :invalid,
|
|
20
|
-
# target_key: :actions,
|
|
21
|
-
# extension: MyModule
|
|
22
|
-
# )
|
|
23
|
-
# # => Servactory::Stroma::Exceptions::InvalidHookType:
|
|
24
|
-
# # Invalid hook type: :invalid. Valid types: :before, :after
|
|
25
|
-
# ```
|
|
26
|
-
class InvalidHookType < Base; end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Servactory
|
|
4
|
-
module Stroma
|
|
5
|
-
module Exceptions
|
|
6
|
-
# Raised when registering a duplicate key in the registry
|
|
7
|
-
#
|
|
8
|
-
# ## Purpose
|
|
9
|
-
#
|
|
10
|
-
# Indicates that a DSL module key has already been registered.
|
|
11
|
-
# Each DSL module must have a unique key in the registry.
|
|
12
|
-
#
|
|
13
|
-
# ## Usage
|
|
14
|
-
#
|
|
15
|
-
# Raised when attempting to register a duplicate key:
|
|
16
|
-
#
|
|
17
|
-
# ```ruby
|
|
18
|
-
# Servactory::Stroma::Registry.register(:inputs, Inputs::DSL)
|
|
19
|
-
# Servactory::Stroma::Registry.register(:inputs, AnotherModule)
|
|
20
|
-
# # Raises: Servactory::Stroma::Exceptions::KeyAlreadyRegistered
|
|
21
|
-
# ```
|
|
22
|
-
#
|
|
23
|
-
# ## Integration
|
|
24
|
-
#
|
|
25
|
-
# This exception typically indicates a configuration error - each
|
|
26
|
-
# DSL module should only be registered once. Check for duplicate
|
|
27
|
-
# registrations in your initialization code.
|
|
28
|
-
class KeyAlreadyRegistered < Base
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Servactory
|
|
4
|
-
module Stroma
|
|
5
|
-
module Exceptions
|
|
6
|
-
# Raised when attempting to modify a finalized registry
|
|
7
|
-
#
|
|
8
|
-
# ## Purpose
|
|
9
|
-
#
|
|
10
|
-
# Indicates that the Stroma::Registry has been finalized and cannot accept
|
|
11
|
-
# new module registrations. The registry is finalized once during gem
|
|
12
|
-
# initialization and remains immutable thereafter.
|
|
13
|
-
#
|
|
14
|
-
# ## Usage
|
|
15
|
-
#
|
|
16
|
-
# Raised when attempting to register modules after finalize!:
|
|
17
|
-
#
|
|
18
|
-
# ```ruby
|
|
19
|
-
# Servactory::Stroma::Registry.finalize!
|
|
20
|
-
# Servactory::Stroma::Registry.register(:custom, CustomModule)
|
|
21
|
-
# # Raises: Servactory::Stroma::Exceptions::RegistryFrozen
|
|
22
|
-
# ```
|
|
23
|
-
#
|
|
24
|
-
# ## Integration
|
|
25
|
-
#
|
|
26
|
-
# This exception typically indicates a programming error - module
|
|
27
|
-
# registration should only occur during application boot, before
|
|
28
|
-
# any service classes are defined.
|
|
29
|
-
class RegistryFrozen < Base
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|