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
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Servactory
|
|
4
|
-
module Stroma
|
|
5
|
-
module Exceptions
|
|
6
|
-
# Raised when accessing registry before finalization
|
|
7
|
-
#
|
|
8
|
-
# ## Purpose
|
|
9
|
-
#
|
|
10
|
-
# Indicates that the Stroma::Registry was accessed before finalize! was called.
|
|
11
|
-
# The registry must be finalized before it can be used to ensure all DSL modules
|
|
12
|
-
# are registered in the correct order.
|
|
13
|
-
#
|
|
14
|
-
# ## Usage
|
|
15
|
-
#
|
|
16
|
-
# Raised when accessing registry methods before finalization:
|
|
17
|
-
#
|
|
18
|
-
# ```ruby
|
|
19
|
-
# # Before finalize! is called
|
|
20
|
-
# Servactory::Stroma::Registry.entries
|
|
21
|
-
# # Raises: Servactory::Stroma::Exceptions::RegistryNotFinalized
|
|
22
|
-
# ```
|
|
23
|
-
#
|
|
24
|
-
# ## Integration
|
|
25
|
-
#
|
|
26
|
-
# This exception typically indicates that Servactory::DSL module was not
|
|
27
|
-
# properly loaded. Ensure servactory gem is properly required before
|
|
28
|
-
# defining service classes.
|
|
29
|
-
class RegistryNotFinalized < Base
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Servactory
|
|
4
|
-
module Stroma
|
|
5
|
-
module Exceptions
|
|
6
|
-
# Raised when using an invalid hook target key
|
|
7
|
-
#
|
|
8
|
-
# ## Purpose
|
|
9
|
-
#
|
|
10
|
-
# Indicates that an unknown key was used as a hook target in the
|
|
11
|
-
# extensions block. Only registered DSL module keys can be used
|
|
12
|
-
# as hook targets.
|
|
13
|
-
#
|
|
14
|
-
# ## Usage
|
|
15
|
-
#
|
|
16
|
-
# Raised when using an invalid key in extensions block:
|
|
17
|
-
#
|
|
18
|
-
# ```ruby
|
|
19
|
-
# class ApplicationService::Base
|
|
20
|
-
# include Servactory::DSL
|
|
21
|
-
#
|
|
22
|
-
# extensions do
|
|
23
|
-
# before :unknown_key, SomeModule
|
|
24
|
-
# # Raises: Servactory::Stroma::Exceptions::UnknownHookTarget
|
|
25
|
-
# end
|
|
26
|
-
# end
|
|
27
|
-
# ```
|
|
28
|
-
#
|
|
29
|
-
# ## Integration
|
|
30
|
-
#
|
|
31
|
-
# Valid hook target keys are determined by registered DSL modules:
|
|
32
|
-
# :configuration, :info, :context, :inputs, :internals, :outputs, :actions
|
|
33
|
-
#
|
|
34
|
-
# Check Servactory::Stroma::Registry.keys for the list of valid targets.
|
|
35
|
-
class UnknownHookTarget < Base
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Servactory
|
|
4
|
-
module Stroma
|
|
5
|
-
module Hooks
|
|
6
|
-
# Applies registered hooks to a target class.
|
|
7
|
-
#
|
|
8
|
-
# ## Purpose
|
|
9
|
-
#
|
|
10
|
-
# Iterates through all registered DSL modules and includes corresponding
|
|
11
|
-
# before/after hooks in the target class. For each registry entry,
|
|
12
|
-
# before hooks are included first, then after hooks.
|
|
13
|
-
#
|
|
14
|
-
# ## Usage
|
|
15
|
-
#
|
|
16
|
-
# ```ruby
|
|
17
|
-
# applier = Servactory::Stroma::Hooks::Applier.new(ChildService, hooks)
|
|
18
|
-
# applier.apply!
|
|
19
|
-
# # ChildService now includes all hook modules
|
|
20
|
-
# ```
|
|
21
|
-
#
|
|
22
|
-
# ## Integration
|
|
23
|
-
#
|
|
24
|
-
# Called by Servactory::Stroma::DSL.inherited after duplicating
|
|
25
|
-
# parent's configuration. Uses Registry.entries to determine
|
|
26
|
-
# hook application order.
|
|
27
|
-
class Applier
|
|
28
|
-
# Creates a new applier for applying hooks to a class.
|
|
29
|
-
#
|
|
30
|
-
# @param target_class [Class] The class to apply hooks to
|
|
31
|
-
# @param hooks [Collection] The hooks collection to apply
|
|
32
|
-
def initialize(target_class, hooks)
|
|
33
|
-
@target_class = target_class
|
|
34
|
-
@hooks = hooks
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Applies all registered hooks to the target class.
|
|
38
|
-
#
|
|
39
|
-
# For each registry entry, includes before hooks first,
|
|
40
|
-
# then after hooks. Does nothing if hooks collection is empty.
|
|
41
|
-
#
|
|
42
|
-
# @return [void]
|
|
43
|
-
#
|
|
44
|
-
# @example
|
|
45
|
-
# applier.apply!
|
|
46
|
-
# # Target class now includes all extension modules
|
|
47
|
-
def apply!
|
|
48
|
-
return if @hooks.empty?
|
|
49
|
-
|
|
50
|
-
Registry.entries.each do |entry|
|
|
51
|
-
@hooks.before(entry.key).each do |hook|
|
|
52
|
-
@target_class.include(hook.extension)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
@hooks.after(entry.key).each do |hook|
|
|
56
|
-
@target_class.include(hook.extension)
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Servactory
|
|
4
|
-
module Stroma
|
|
5
|
-
module Hooks
|
|
6
|
-
# Mutable collection manager for Hook objects.
|
|
7
|
-
#
|
|
8
|
-
# ## Purpose
|
|
9
|
-
#
|
|
10
|
-
# Stores Hook objects and provides query methods to retrieve hooks
|
|
11
|
-
# by type and target key. Supports proper duplication during class
|
|
12
|
-
# inheritance to ensure configuration isolation.
|
|
13
|
-
#
|
|
14
|
-
# ## Usage
|
|
15
|
-
#
|
|
16
|
-
# ```ruby
|
|
17
|
-
# hooks = Servactory::Stroma::Hooks::Collection.new
|
|
18
|
-
# hooks.add(:before, :actions, MyModule)
|
|
19
|
-
# hooks.add(:after, :actions, AnotherModule)
|
|
20
|
-
#
|
|
21
|
-
# hooks.before(:actions) # => [Hook(...)]
|
|
22
|
-
# hooks.after(:actions) # => [Hook(...)]
|
|
23
|
-
# hooks.empty? # => false
|
|
24
|
-
# hooks.size # => 2
|
|
25
|
-
# ```
|
|
26
|
-
#
|
|
27
|
-
# ## Integration
|
|
28
|
-
#
|
|
29
|
-
# Stored in Servactory::Stroma::State and used by
|
|
30
|
-
# Servactory::Stroma::Hooks::Applier to apply hooks to classes.
|
|
31
|
-
# Properly duplicated during class inheritance via initialize_dup.
|
|
32
|
-
class Collection
|
|
33
|
-
extend Forwardable
|
|
34
|
-
|
|
35
|
-
# @!method each
|
|
36
|
-
# Iterates over all hooks in the collection.
|
|
37
|
-
# @yield [Hook] Each hook in the collection
|
|
38
|
-
# @!method map
|
|
39
|
-
# Maps over all hooks in the collection.
|
|
40
|
-
# @yield [Hook] Each hook in the collection
|
|
41
|
-
# @return [Array] Mapped results
|
|
42
|
-
# @!method size
|
|
43
|
-
# Returns the number of hooks in the collection.
|
|
44
|
-
# @return [Integer] Number of hooks
|
|
45
|
-
# @!method empty?
|
|
46
|
-
# Checks if the collection is empty.
|
|
47
|
-
# @return [Boolean] true if no hooks registered
|
|
48
|
-
def_delegators :@collection, :each, :map, :size, :empty?
|
|
49
|
-
|
|
50
|
-
# Creates a new hooks collection.
|
|
51
|
-
#
|
|
52
|
-
# @param collection [Set] Initial collection of hooks (default: empty Set)
|
|
53
|
-
def initialize(collection = Set.new)
|
|
54
|
-
@collection = collection
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# Creates a deep copy during inheritance.
|
|
58
|
-
#
|
|
59
|
-
# @param original [Collection] The original collection being duplicated
|
|
60
|
-
# @return [void]
|
|
61
|
-
def initialize_dup(original)
|
|
62
|
-
super
|
|
63
|
-
@collection = original.instance_variable_get(:@collection).dup
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# Adds a new hook to the collection.
|
|
67
|
-
#
|
|
68
|
-
# @param type [Symbol] Hook type (:before or :after)
|
|
69
|
-
# @param target_key [Symbol] Registry key to hook into
|
|
70
|
-
# @param extension [Module] Extension module to include
|
|
71
|
-
# @return [Set] The updated collection
|
|
72
|
-
#
|
|
73
|
-
# @example
|
|
74
|
-
# hooks.add(:before, :actions, ValidationModule)
|
|
75
|
-
def add(type, target_key, extension)
|
|
76
|
-
@collection << Hook.new(type:, target_key:, extension:)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# Returns all before hooks for a given key.
|
|
80
|
-
#
|
|
81
|
-
# @param key [Symbol] The target key to filter by
|
|
82
|
-
# @return [Array<Hook>] Hooks that run before the target
|
|
83
|
-
#
|
|
84
|
-
# @example
|
|
85
|
-
# hooks.before(:actions) # => [Hook(type: :before, ...)]
|
|
86
|
-
def before(key)
|
|
87
|
-
@collection.select { |hook| hook.before? && hook.target_key == key }
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
# Returns all after hooks for a given key.
|
|
91
|
-
#
|
|
92
|
-
# @param key [Symbol] The target key to filter by
|
|
93
|
-
# @return [Array<Hook>] Hooks that run after the target
|
|
94
|
-
#
|
|
95
|
-
# @example
|
|
96
|
-
# hooks.after(:actions) # => [Hook(type: :after, ...)]
|
|
97
|
-
def after(key)
|
|
98
|
-
@collection.select { |hook| hook.after? && hook.target_key == key }
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
end
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Servactory
|
|
4
|
-
module Stroma
|
|
5
|
-
module Hooks
|
|
6
|
-
# DSL interface for registering hooks in extensions block.
|
|
7
|
-
#
|
|
8
|
-
# ## Purpose
|
|
9
|
-
#
|
|
10
|
-
# Provides the `before` and `after` methods used within the extensions
|
|
11
|
-
# block to register hooks. Validates that target keys exist in Registry
|
|
12
|
-
# before adding hooks.
|
|
13
|
-
#
|
|
14
|
-
# ## Usage
|
|
15
|
-
#
|
|
16
|
-
# ```ruby
|
|
17
|
-
# class ApplicationService::Base < Servactory::Base
|
|
18
|
-
# extensions do
|
|
19
|
-
# before :actions, ValidationModule
|
|
20
|
-
# after :outputs, LoggingModule
|
|
21
|
-
# end
|
|
22
|
-
# end
|
|
23
|
-
# ```
|
|
24
|
-
#
|
|
25
|
-
# ## Integration
|
|
26
|
-
#
|
|
27
|
-
# Created by DSL.extensions method and receives instance_eval of the block.
|
|
28
|
-
# Validates keys against Registry.keys and raises UnknownHookTarget
|
|
29
|
-
# for invalid keys.
|
|
30
|
-
class Factory
|
|
31
|
-
# Creates a new factory for registering hooks.
|
|
32
|
-
#
|
|
33
|
-
# @param hooks [Collection] The hooks collection to add to
|
|
34
|
-
def initialize(hooks)
|
|
35
|
-
@hooks = hooks
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# Registers one or more before hooks for a target key.
|
|
39
|
-
#
|
|
40
|
-
# @param key [Symbol] The registry key to hook before
|
|
41
|
-
# @param extensions [Array<Module>] Extension modules to include
|
|
42
|
-
# @raise [Exceptions::UnknownHookTarget] If key is not registered
|
|
43
|
-
#
|
|
44
|
-
# @example
|
|
45
|
-
# before :actions, ValidationModule, AuthorizationModule
|
|
46
|
-
def before(key, *extensions)
|
|
47
|
-
validate_key!(key)
|
|
48
|
-
extensions.each { |extension| @hooks.add(:before, key, extension) }
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
# Registers one or more after hooks for a target key.
|
|
52
|
-
#
|
|
53
|
-
# @param key [Symbol] The registry key to hook after
|
|
54
|
-
# @param extensions [Array<Module>] Extension modules to include
|
|
55
|
-
# @raise [Exceptions::UnknownHookTarget] If key is not registered
|
|
56
|
-
#
|
|
57
|
-
# @example
|
|
58
|
-
# after :outputs, LoggingModule, AuditModule
|
|
59
|
-
def after(key, *extensions)
|
|
60
|
-
validate_key!(key)
|
|
61
|
-
extensions.each { |extension| @hooks.add(:after, key, extension) }
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
private
|
|
65
|
-
|
|
66
|
-
# Validates that the key exists in the Registry.
|
|
67
|
-
#
|
|
68
|
-
# @param key [Symbol] The key to validate
|
|
69
|
-
# @raise [Exceptions::UnknownHookTarget] If key is not registered
|
|
70
|
-
def validate_key!(key)
|
|
71
|
-
return if Registry.key?(key)
|
|
72
|
-
|
|
73
|
-
raise Exceptions::UnknownHookTarget,
|
|
74
|
-
"Unknown hook target: #{key.inspect}. " \
|
|
75
|
-
"Valid keys: #{Registry.keys.map(&:inspect).join(', ')}"
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
end
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Servactory
|
|
4
|
-
module Stroma
|
|
5
|
-
module Hooks
|
|
6
|
-
# Valid hook types for Hook validation.
|
|
7
|
-
VALID_HOOK_TYPES = %i[before after].freeze
|
|
8
|
-
private_constant :VALID_HOOK_TYPES
|
|
9
|
-
|
|
10
|
-
# Immutable value object representing a hook configuration.
|
|
11
|
-
#
|
|
12
|
-
# ## Purpose
|
|
13
|
-
#
|
|
14
|
-
# Defines when and where an extension module should be included
|
|
15
|
-
# relative to a registered DSL module. Hook is immutable - once
|
|
16
|
-
# created, it cannot be modified.
|
|
17
|
-
#
|
|
18
|
-
# ## Attributes
|
|
19
|
-
#
|
|
20
|
-
# @!attribute [r] type
|
|
21
|
-
# @return [Symbol] Either :before or :after
|
|
22
|
-
# @!attribute [r] target_key
|
|
23
|
-
# @return [Symbol] Key of the DSL module to hook into (:inputs, :actions, etc.)
|
|
24
|
-
# @!attribute [r] extension
|
|
25
|
-
# @return [Module] The module to include at the hook point
|
|
26
|
-
#
|
|
27
|
-
# ## Usage
|
|
28
|
-
#
|
|
29
|
-
# ```ruby
|
|
30
|
-
# hook = Servactory::Stroma::Hooks::Hook.new(
|
|
31
|
-
# type: :before,
|
|
32
|
-
# target_key: :actions,
|
|
33
|
-
# extension: MyExtension
|
|
34
|
-
# )
|
|
35
|
-
# hook.before? # => true
|
|
36
|
-
# hook.after? # => false
|
|
37
|
-
# ```
|
|
38
|
-
#
|
|
39
|
-
# ## Immutability
|
|
40
|
-
#
|
|
41
|
-
# Hook is a Data object - frozen and immutable after creation.
|
|
42
|
-
Hook = Data.define(:type, :target_key, :extension) do
|
|
43
|
-
# Initializes a new Hook with validation.
|
|
44
|
-
#
|
|
45
|
-
# @param type [Symbol] Hook type (:before or :after)
|
|
46
|
-
# @param target_key [Symbol] Registry key to hook into
|
|
47
|
-
# @param extension [Module] Extension module to include
|
|
48
|
-
# @raise [Exceptions::InvalidHookType] If type is invalid
|
|
49
|
-
def initialize(type:, target_key:, extension:)
|
|
50
|
-
if VALID_HOOK_TYPES.exclude?(type)
|
|
51
|
-
raise Exceptions::InvalidHookType,
|
|
52
|
-
"Invalid hook type: #{type.inspect}. Valid types: #{VALID_HOOK_TYPES.map(&:inspect).join(', ')}"
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
super
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
# Checks if this is a before hook.
|
|
59
|
-
#
|
|
60
|
-
# @return [Boolean] true if type is :before
|
|
61
|
-
def before?
|
|
62
|
-
type == :before
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
# Checks if this is an after hook.
|
|
66
|
-
#
|
|
67
|
-
# @return [Boolean] true if type is :after
|
|
68
|
-
def after?
|
|
69
|
-
type == :after
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Servactory
|
|
4
|
-
module Stroma
|
|
5
|
-
# Manages global registration of DSL modules for Servactory.
|
|
6
|
-
#
|
|
7
|
-
# ## Purpose
|
|
8
|
-
#
|
|
9
|
-
# Singleton registry that stores all DSL modules that will be included
|
|
10
|
-
# in service classes. Implements two-phase lifecycle: registration
|
|
11
|
-
# followed by finalization.
|
|
12
|
-
#
|
|
13
|
-
# ## Usage
|
|
14
|
-
#
|
|
15
|
-
# ```ruby
|
|
16
|
-
# # During gem initialization:
|
|
17
|
-
# Servactory::Stroma::Registry.register(:inputs, Servactory::Inputs::DSL)
|
|
18
|
-
# Servactory::Stroma::Registry.register(:outputs, Servactory::Outputs::DSL)
|
|
19
|
-
# Servactory::Stroma::Registry.finalize!
|
|
20
|
-
#
|
|
21
|
-
# # After finalization:
|
|
22
|
-
# Servactory::Stroma::Registry.keys # => [:inputs, :outputs]
|
|
23
|
-
# Servactory::Stroma::Registry.key?(:inputs) # => true
|
|
24
|
-
# ```
|
|
25
|
-
#
|
|
26
|
-
# ## Integration
|
|
27
|
-
#
|
|
28
|
-
# Used by Servactory::Stroma::DSL to include all registered modules in service classes.
|
|
29
|
-
# Used by Servactory::Stroma::Hooks::Factory to validate hook target keys.
|
|
30
|
-
#
|
|
31
|
-
# ## Thread Safety
|
|
32
|
-
#
|
|
33
|
-
# Registration must occur during single-threaded boot phase.
|
|
34
|
-
# After finalization, all read operations are thread-safe.
|
|
35
|
-
class Registry
|
|
36
|
-
include Singleton
|
|
37
|
-
|
|
38
|
-
class << self
|
|
39
|
-
delegate :register,
|
|
40
|
-
:finalize!,
|
|
41
|
-
:entries,
|
|
42
|
-
:keys,
|
|
43
|
-
:key?,
|
|
44
|
-
to: :instance
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def initialize
|
|
48
|
-
@entries = []
|
|
49
|
-
@finalized = false
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def register(key, extension)
|
|
53
|
-
raise Exceptions::RegistryFrozen, "Registry is finalized" if @finalized
|
|
54
|
-
|
|
55
|
-
if @entries.any? { |e| e.key == key }
|
|
56
|
-
raise Exceptions::KeyAlreadyRegistered, "Key #{key.inspect} already registered"
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
@entries << Entry.new(key:, extension:)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def finalize!
|
|
63
|
-
return if @finalized
|
|
64
|
-
|
|
65
|
-
@entries.freeze
|
|
66
|
-
@finalized = true
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def entries
|
|
70
|
-
ensure_finalized!
|
|
71
|
-
@entries
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def keys
|
|
75
|
-
ensure_finalized!
|
|
76
|
-
@entries.map(&:key)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def key?(key)
|
|
80
|
-
ensure_finalized!
|
|
81
|
-
@entries.any? { |e| e.key == key }
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
private
|
|
85
|
-
|
|
86
|
-
def ensure_finalized!
|
|
87
|
-
return if @finalized
|
|
88
|
-
|
|
89
|
-
raise Exceptions::RegistryNotFinalized,
|
|
90
|
-
"Registry not finalized. Call Stroma::Registry.finalize! after registration."
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
end
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Servactory
|
|
4
|
-
module Stroma
|
|
5
|
-
module Settings
|
|
6
|
-
# Top-level hierarchical container for extension settings.
|
|
7
|
-
#
|
|
8
|
-
# ## Purpose
|
|
9
|
-
#
|
|
10
|
-
# Provides two-level hierarchical access to extension settings:
|
|
11
|
-
# registry_key -> extension_name -> setting values.
|
|
12
|
-
# Auto-vivifies RegistrySettings on first access.
|
|
13
|
-
#
|
|
14
|
-
# ## Usage
|
|
15
|
-
#
|
|
16
|
-
# ```ruby
|
|
17
|
-
# settings = Servactory::Stroma::Settings::Collection.new
|
|
18
|
-
# settings[:actions][:authorization][:method_name] = :authorize
|
|
19
|
-
# settings[:actions][:transactional][:enabled] = true
|
|
20
|
-
#
|
|
21
|
-
# settings.keys # => [:actions]
|
|
22
|
-
# settings.empty? # => false
|
|
23
|
-
# settings.to_h # => { actions: { authorization: { method_name: :authorize }, ... } }
|
|
24
|
-
# ```
|
|
25
|
-
#
|
|
26
|
-
# ## Integration
|
|
27
|
-
#
|
|
28
|
-
# Stored in Servactory::Stroma::State alongside Hooks::Collection.
|
|
29
|
-
# Accessed via `stroma.settings` in service classes.
|
|
30
|
-
# Properly duplicated during class inheritance via initialize_dup.
|
|
31
|
-
class Collection
|
|
32
|
-
extend Forwardable
|
|
33
|
-
|
|
34
|
-
# @!method each
|
|
35
|
-
# Iterates over all registry key settings.
|
|
36
|
-
# @yield [key, settings] Each registry key and its RegistrySettings
|
|
37
|
-
# @!method keys
|
|
38
|
-
# Returns all registry keys with settings.
|
|
39
|
-
# @return [Array<Symbol>] List of registry keys
|
|
40
|
-
# @!method size
|
|
41
|
-
# Returns the number of registry keys configured.
|
|
42
|
-
# @return [Integer] Number of registry keys
|
|
43
|
-
# @!method empty?
|
|
44
|
-
# Checks if no settings are configured.
|
|
45
|
-
# @return [Boolean] true if empty
|
|
46
|
-
# @!method map
|
|
47
|
-
# Maps over all registry key settings.
|
|
48
|
-
# @yield [key, settings] Each registry key and its RegistrySettings
|
|
49
|
-
# @return [Array] Mapped results
|
|
50
|
-
def_delegators :@storage, :each, :keys, :size, :empty?, :map
|
|
51
|
-
|
|
52
|
-
# Creates a new settings collection.
|
|
53
|
-
#
|
|
54
|
-
# @param storage [Hash] Initial storage (default: empty Hash)
|
|
55
|
-
def initialize(storage = {})
|
|
56
|
-
@storage = storage
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# Creates a deep copy during inheritance.
|
|
60
|
-
#
|
|
61
|
-
# @param original [Collection] The original collection being duplicated
|
|
62
|
-
# @return [void]
|
|
63
|
-
def initialize_dup(original)
|
|
64
|
-
super
|
|
65
|
-
@storage = original.instance_variable_get(:@storage).transform_values(&:dup)
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
# Accesses or creates RegistrySettings for a registry key.
|
|
69
|
-
#
|
|
70
|
-
# Auto-vivifies a new RegistrySettings on first access.
|
|
71
|
-
#
|
|
72
|
-
# @param registry_key [Symbol] The registry key (e.g., :actions)
|
|
73
|
-
# @return [RegistrySettings] Settings for that registry key
|
|
74
|
-
#
|
|
75
|
-
# @example
|
|
76
|
-
# settings[:actions][:authorization][:method_name] = :authorize
|
|
77
|
-
def [](registry_key)
|
|
78
|
-
@storage[registry_key.to_sym] ||= RegistrySettings.new
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
# Converts to a nested Hash.
|
|
82
|
-
#
|
|
83
|
-
# @return [Hash] Deep nested hash of all settings
|
|
84
|
-
def to_h
|
|
85
|
-
@storage.transform_values(&:to_h)
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
end
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Servactory
|
|
4
|
-
module Stroma
|
|
5
|
-
module Settings
|
|
6
|
-
# Collection of Setting objects for one registry key.
|
|
7
|
-
#
|
|
8
|
-
# ## Purpose
|
|
9
|
-
#
|
|
10
|
-
# Groups extension settings by registry key (e.g., :actions).
|
|
11
|
-
# Provides auto-vivifying access to individual Setting objects.
|
|
12
|
-
# This is the middle layer in the settings hierarchy.
|
|
13
|
-
#
|
|
14
|
-
# ## Usage
|
|
15
|
-
#
|
|
16
|
-
# ```ruby
|
|
17
|
-
# settings = Servactory::Stroma::Settings::RegistrySettings.new
|
|
18
|
-
# settings[:authorization][:method_name] = :authorize
|
|
19
|
-
# settings[:transactional][:enabled] = true
|
|
20
|
-
#
|
|
21
|
-
# settings.keys # => [:authorization, :transactional]
|
|
22
|
-
# settings.empty? # => false
|
|
23
|
-
# ```
|
|
24
|
-
#
|
|
25
|
-
# ## Integration
|
|
26
|
-
#
|
|
27
|
-
# Used by Collection as second-level container.
|
|
28
|
-
# Properly duplicated during class inheritance via initialize_dup.
|
|
29
|
-
class RegistrySettings
|
|
30
|
-
extend Forwardable
|
|
31
|
-
|
|
32
|
-
# @!method each
|
|
33
|
-
# Iterates over all extension settings.
|
|
34
|
-
# @yield [name, setting] Each extension name and its Setting
|
|
35
|
-
# @!method keys
|
|
36
|
-
# Returns all extension names.
|
|
37
|
-
# @return [Array<Symbol>] List of extension names
|
|
38
|
-
# @!method size
|
|
39
|
-
# Returns the number of extensions configured.
|
|
40
|
-
# @return [Integer] Number of extensions
|
|
41
|
-
# @!method empty?
|
|
42
|
-
# Checks if no extensions are configured.
|
|
43
|
-
# @return [Boolean] true if empty
|
|
44
|
-
# @!method map
|
|
45
|
-
# Maps over all extension settings.
|
|
46
|
-
# @yield [name, setting] Each extension name and its Setting
|
|
47
|
-
# @return [Array] Mapped results
|
|
48
|
-
def_delegators :@storage, :each, :keys, :size, :empty?, :map
|
|
49
|
-
|
|
50
|
-
# Creates a new registry settings container.
|
|
51
|
-
#
|
|
52
|
-
# @param storage [Hash] Initial storage (default: empty Hash)
|
|
53
|
-
def initialize(storage = {})
|
|
54
|
-
@storage = storage
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# Creates a deep copy during inheritance.
|
|
58
|
-
#
|
|
59
|
-
# @param original [RegistrySettings] The original being duplicated
|
|
60
|
-
# @return [void]
|
|
61
|
-
def initialize_dup(original)
|
|
62
|
-
super
|
|
63
|
-
@storage = original.instance_variable_get(:@storage).transform_values(&:dup)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# Accesses or creates a Setting for an extension.
|
|
67
|
-
#
|
|
68
|
-
# Auto-vivifies a new Setting on first access.
|
|
69
|
-
#
|
|
70
|
-
# @param extension_name [Symbol] The extension name
|
|
71
|
-
# @return [Setting] The extension's setting container
|
|
72
|
-
#
|
|
73
|
-
# @example
|
|
74
|
-
# settings[:authorization][:method_name] = :authorize
|
|
75
|
-
def [](extension_name)
|
|
76
|
-
@storage[extension_name.to_sym] ||= Setting.new
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# Converts to a nested Hash.
|
|
80
|
-
#
|
|
81
|
-
# @return [Hash] Nested hash of all settings
|
|
82
|
-
def to_h
|
|
83
|
-
@storage.transform_values(&:to_h)
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|