servactory 3.0.0 → 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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/lib/servactory/actions/action.rb +2 -2
  3. data/lib/servactory/actions/collection.rb +1 -1
  4. data/lib/servactory/actions/stages/collection.rb +1 -1
  5. data/lib/servactory/configuration/option_helpers/option_helpers_collection.rb +60 -2
  6. data/lib/servactory/context/warehouse/inputs.rb +28 -15
  7. data/lib/servactory/context/workspace/inputs.rb +27 -18
  8. data/lib/servactory/context/workspace/internals.rb +44 -27
  9. data/lib/servactory/context/workspace/outputs.rb +31 -23
  10. data/lib/servactory/dsl.rb +1 -1
  11. data/lib/servactory/info/builder.rb +2 -3
  12. data/lib/servactory/inputs/collection.rb +14 -21
  13. data/lib/servactory/inputs/input.rb +6 -103
  14. data/lib/servactory/inputs/tools/validation.rb +32 -57
  15. data/lib/servactory/inputs/validations/required.rb +3 -2
  16. data/lib/servactory/internals/collection.rb +5 -24
  17. data/lib/servactory/internals/internal.rb +4 -112
  18. data/lib/servactory/maintenance/attributes/base.rb +135 -0
  19. data/lib/servactory/maintenance/attributes/collection.rb +109 -0
  20. data/lib/servactory/maintenance/attributes/option_helper.rb +33 -12
  21. data/lib/servactory/maintenance/{attributes/options_collection.rb → options/collection.rb} +6 -7
  22. data/lib/servactory/maintenance/{attributes → options}/define_conflict.rb +1 -1
  23. data/lib/servactory/maintenance/{attributes → options}/define_method.rb +1 -1
  24. data/lib/servactory/maintenance/options/helper.rb +23 -0
  25. data/lib/servactory/maintenance/{attributes → options}/option.rb +50 -27
  26. data/lib/servactory/maintenance/options/registrar.rb +200 -0
  27. data/lib/servactory/maintenance/{attributes/validations → validations/checkers}/must.rb +25 -8
  28. data/lib/servactory/maintenance/{attributes/validations → validations/checkers}/type.rb +6 -5
  29. data/lib/servactory/maintenance/validations/concerns/error_builder.rb +50 -0
  30. data/lib/servactory/maintenance/validations/performer.rb +57 -0
  31. data/lib/servactory/maintenance/validations/support/type_validator.rb +36 -0
  32. data/lib/servactory/maintenance/{attributes → validations}/translator/must.rb +1 -1
  33. data/lib/servactory/maintenance/{attributes → validations}/translator/type.rb +1 -1
  34. data/lib/servactory/outputs/collection.rb +5 -24
  35. data/lib/servactory/outputs/output.rb +4 -112
  36. data/lib/servactory/result.rb +48 -39
  37. data/lib/servactory/tool_kit/dynamic_options/must.rb +2 -2
  38. data/lib/servactory/tool_kit/dynamic_options/schema.rb +5 -5
  39. data/lib/servactory/utils.rb +0 -8
  40. data/lib/servactory/version.rb +2 -2
  41. metadata +16 -13
  42. data/lib/servactory/maintenance/attributes/options/registrar.rb +0 -183
  43. data/lib/servactory/maintenance/attributes/tools/validation.rb +0 -84
  44. data/lib/servactory/maintenance/attributes/validations/concerns/error_builder.rb +0 -52
  45. data/lib/servactory/maintenance/validations/types.rb +0 -34
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1b84875a142c1878a68ea71f3874019a8028bc8eff3836706d3079107b06761b
4
- data.tar.gz: 2a47fd738513716831e2fd491266e1c122a1200bcff9737d90a47087e95f2f64
3
+ metadata.gz: 1c4398d2ffb193d4acd86b96f02871198d13d4e8b31ec96dddaa05c3966f1525
4
+ data.tar.gz: bf35a15c0d771ef1c6362d573e2fbd5a04a0021cb0a80d847f37b23d5dff3b76
5
5
  SHA512:
6
- metadata.gz: 502fdff740f4a46378ee1b8664279fbc2cebfb7fe4fa01025a30499d3504ae1ae84b1ead432e28b1e23d59a572ba685690c88e681633bcb02020df5756e6328d
7
- data.tar.gz: 14482adc188d556373eaa482502f2bd59533ca5a8e3d6b590109cb6cf18755c9ae34a77df79baa7d654fd0657b7202821d2983447c8485525b62445bd4ac7898
6
+ metadata.gz: baa8f5c12c6edbf0786d807611a759f8fd54b3f087967ea981942843e3a19b2f1026f607bc52ad9c5f4dd42830216582e4e54d38bef5e00fa48dea47bbe84210
7
+ data.tar.gz: c8af2b260386c4c2711a6b034bb116ad843cfb57c5e2b3181d59e9b9d38692ec562afc69bd5b33b46820c20972c0904e9921dfd1516e1576ec8622439ae1b382
@@ -13,11 +13,11 @@ module Servactory
13
13
  @position = position
14
14
 
15
15
  @is_condition_opposite = false
16
- @condition = options.fetch(:if, nil)
16
+ @condition = options[:if]
17
17
 
18
18
  return unless @condition.nil?
19
19
 
20
- @condition = options.fetch(:unless, nil)
20
+ @condition = options[:unless]
21
21
 
22
22
  @is_condition_opposite = true unless @condition.nil?
23
23
  end
@@ -67,7 +67,7 @@ module Servactory
67
67
  # sorted = actions.sorted_by_position
68
68
  # sorted.each { |action| puts action.position }
69
69
  def sorted_by_position
70
- Collection.new(sort_by(&:position))
70
+ @sorted_by_position ||= Collection.new(sort_by(&:position))
71
71
  end
72
72
  end
73
73
  end
@@ -13,7 +13,7 @@ module Servactory
13
13
  end
14
14
 
15
15
  def sorted_by_position
16
- Collection.new(sort_by(&:position))
16
+ @sorted_by_position ||= Collection.new(sort_by(&:position))
17
17
  end
18
18
  end
19
19
  end
@@ -3,26 +3,84 @@
3
3
  module Servactory
4
4
  module Configuration
5
5
  module OptionHelpers
6
+ # Collection wrapper for managing option helper objects.
7
+ #
8
+ # ## Purpose
9
+ #
10
+ # OptionHelpersCollection provides a unified interface for storing and
11
+ # querying Helper instances used by the configuration system.
12
+ # It wraps a Set to ensure uniqueness and delegates common enumeration methods.
13
+ #
14
+ # ## Usage
15
+ #
16
+ # The collection is used internally by the configuration system
17
+ # to manage registered option helpers:
18
+ #
19
+ # ```ruby
20
+ # collection = OptionHelpersCollection.new
21
+ # collection << helper
22
+ #
23
+ # collection.find_by(name: :must) # => helper instance
24
+ # collection.dynamic_options # => filtered OptionHelpersCollection
25
+ # ```
26
+ #
27
+ # ## Performance
28
+ #
29
+ # The collection uses memoization for frequently accessed data:
30
+ # - `helpers_index` - cached hash for O(1) lookups by name
31
+ #
6
32
  class OptionHelpersCollection
7
33
  extend Forwardable
8
34
 
9
- def_delegators :@collection, :<<, :filter, :map, :find, :merge
35
+ def_delegators :@collection,
36
+ :<<,
37
+ :filter,
38
+ :each_with_object,
39
+ :map,
40
+ :merge
10
41
 
42
+ # Initializes the collection with an optional pre-built Set.
43
+ #
44
+ # @param collection [Set] initial set of helpers
45
+ # @return [OptionHelpersCollection]
11
46
  def initialize(collection = Set.new)
12
47
  @collection = collection
13
48
  end
14
49
 
50
+ # Duplicates the collection, resetting memoized caches.
51
+ #
52
+ # @param original [OptionHelpersCollection] the collection being duplicated
53
+ # @return [void]
15
54
  def initialize_dup(original)
16
55
  super
17
56
  @collection = original.instance_variable_get(:@collection).dup
57
+ @helpers_index = nil
18
58
  end
19
59
 
60
+ # Returns a new collection containing only dynamic option helpers.
61
+ #
62
+ # @return [OptionHelpersCollection] filtered collection of dynamic helpers
20
63
  def dynamic_options
21
64
  OptionHelpersCollection.new(filter(&:dynamic_option?))
22
65
  end
23
66
 
67
+ # Finds a helper by its name using indexed lookup.
68
+ #
69
+ # @param name [Symbol] the helper name to find
70
+ # @return [Maintenance::Options::Helper, nil] the found helper or nil
24
71
  def find_by(name:)
25
- find { |helper| helper.name == name }
72
+ helpers_index[name]
73
+ end
74
+
75
+ private
76
+
77
+ # Builds and caches a hash index for O(1) helper lookups.
78
+ #
79
+ # @return [Hash{Symbol => Maintenance::Options::Helper}] helper names mapped to Helper instances
80
+ def helpers_index
81
+ @helpers_index ||= each_with_object({}) do |helper, index|
82
+ index[helper.name] = helper
83
+ end
26
84
  end
27
85
  end
28
86
  end
@@ -29,42 +29,55 @@ module Servactory
29
29
  @arguments.keys
30
30
  end
31
31
 
32
- # Merges new arguments into storage.
32
+ # Merges new arguments into storage and defines accessor methods.
33
33
  #
34
34
  # @param arguments [Hash] Input name-value pairs to merge
35
- # @return [Hash] Updated arguments hash
35
+ # @return [void]
36
36
  def merge!(arguments)
37
37
  @arguments.merge!(arguments)
38
+ define_methods_for!(arguments)
38
39
  end
39
40
 
40
- # Delegates method calls to stored inputs.
41
+ # Raises error for any method call not pre-defined as a singleton accessor.
41
42
  #
42
43
  # Supports predicate methods when enabled in config.
43
44
  #
44
45
  # @param name [Symbol] Method name (input or predicate)
45
46
  # @param _args [Array] Method arguments (unused)
46
- # @return [Object] Input value or predicate result
47
+ # @raise [Exception] Failure exception for undefined input
47
48
  def method_missing(name, *_args)
48
49
  predicate = @context.config.predicate_methods_enabled && name.end_with?("?")
49
-
50
50
  input_name = predicate ? name.to_s.chomp("?").to_sym : name
51
-
52
- input_value = @arguments.fetch(input_name) { raise_error_for(input_name) }
53
-
54
- predicate ? Servactory::Utils.query_attribute(input_value) : input_value
51
+ raise_error_for(input_name)
55
52
  end
56
53
 
57
- # Checks if method corresponds to stored input.
54
+ # Returns false since all valid methods are defined as singleton methods.
58
55
  #
59
- # @param name [Symbol] Method name to check
60
- # @param _include_private [Boolean] Include private methods in check
61
- # @return [Boolean] True if input exists for this method
62
- def respond_to_missing?(name, *)
63
- @arguments.fetch(name) { raise_error_for(name) }
56
+ # @return [Boolean] Always false
57
+ def respond_to_missing?(*)
58
+ false
64
59
  end
65
60
 
66
61
  private
67
62
 
63
+ # Defines singleton accessor methods for given arguments.
64
+ #
65
+ # @param arguments [Hash] Input name-value pairs to define methods for
66
+ # @return [void]
67
+ def define_methods_for!(arguments)
68
+ arguments.each_key do |name|
69
+ define_singleton_method(name) do
70
+ @arguments.fetch(name) { raise_error_for(name) }
71
+ end
72
+
73
+ next unless @context.config.predicate_methods_enabled
74
+
75
+ define_singleton_method(:"#{name}?") do
76
+ Servactory::Utils.query_attribute(@arguments.fetch(name) { raise_error_for(name) })
77
+ end
78
+ end
79
+ end
80
+
68
81
  # Raises error for undefined input.
69
82
  #
70
83
  # @param input_name [Symbol] Name of undefined input
@@ -7,6 +7,8 @@ module Servactory
7
7
  def initialize(context:, collection_of_inputs:)
8
8
  @context = context
9
9
  @collection_of_inputs = collection_of_inputs
10
+
11
+ define_attribute_methods!
10
12
  end
11
13
 
12
14
  def only(*names)
@@ -24,41 +26,48 @@ module Servactory
24
26
  def method_missing(name, *_args)
25
27
  if name.to_s.end_with?("=")
26
28
  prepared_name = name.to_s.delete("=").to_sym
27
-
28
29
  raise_error_for(:assign, prepared_name)
29
30
  else
30
- fetch_with(name:) { raise_error_for(:fetch, name) }
31
+ raise_error_for(:fetch, name)
31
32
  end
32
33
  end
33
34
 
34
- def respond_to_missing?(name, *)
35
- @collection_of_inputs.names.include?(name) || super
35
+ def respond_to_missing?(*)
36
+ false
36
37
  end
37
38
 
38
39
  private
39
40
 
40
- # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Lint/UnusedMethodArgument
41
- def fetch_with(name:, &block)
42
- predicate = @context.config.predicate_methods_enabled && name.end_with?("?")
41
+ def define_attribute_methods!
42
+ @collection_of_inputs.each do |input|
43
+ define_singleton_method(input.internal_name) do
44
+ fetch_value(attribute: input)
45
+ end
43
46
 
44
- input_name = predicate ? name.to_s.chomp("?").to_sym : name
47
+ next unless @context.config.predicate_methods_enabled
45
48
 
46
- input = @collection_of_inputs.find_by(name: input_name)
47
-
48
- return yield if input.nil?
49
+ define_singleton_method(:"#{input.internal_name}?") do
50
+ fetch_predicate(attribute: input)
51
+ end
52
+ end
53
+ end
49
54
 
50
- input_value = @context.send(:servactory_service_warehouse).fetch_input(input.name)
55
+ def fetch_value(attribute:)
56
+ value = @context.send(:servactory_service_warehouse).fetch_input(attribute.name)
51
57
 
52
- if input.optional? && !input.default.nil? && !Servactory::Utils.value_present?(input_value)
53
- input_value = input.default
58
+ if attribute.optional? && !attribute.default.nil? && !Servactory::Utils.value_present?(value)
59
+ value = attribute.default
54
60
  end
55
61
 
56
- input_prepare = input.prepare[:in]
57
- input_value = input_prepare.call(value: input_value) if input_prepare
62
+ prepare = attribute.prepare[:in]
63
+ value = prepare.call(value:) if prepare
64
+
65
+ value
66
+ end
58
67
 
59
- predicate ? Servactory::Utils.query_attribute(input_value) : input_value
68
+ def fetch_predicate(attribute:)
69
+ Servactory::Utils.query_attribute(fetch_value(attribute:))
60
70
  end
61
- # rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Lint/UnusedMethodArgument
62
71
 
63
72
  def raise_error_for(type, name)
64
73
  message_text = @context.send(:servactory_service_info).translate(
@@ -7,6 +7,9 @@ module Servactory
7
7
  def initialize(context:, collection_of_internals:)
8
8
  @context = context
9
9
  @collection_of_internals = collection_of_internals
10
+ @validated_attributes = Set.new
11
+
12
+ define_attribute_methods!
10
13
  end
11
14
 
12
15
  def only(*names)
@@ -21,55 +24,69 @@ module Servactory
21
24
  .to_h { |internal| [internal.name, send(internal.name)] }
22
25
  end
23
26
 
24
- def method_missing(name, *args)
27
+ def method_missing(name, *_args)
25
28
  if name.to_s.end_with?("=")
26
29
  prepared_name = name.to_s.delete("=").to_sym
27
-
28
- assign_with(prepared_name:, value: args.pop) { raise_error_for(:assign, prepared_name) }
30
+ raise_error_for(:assign, prepared_name)
29
31
  else
30
- fetch_with(name:) { raise_error_for(:fetch, name) }
32
+ raise_error_for(:fetch, name)
31
33
  end
32
34
  end
33
35
 
34
- def respond_to_missing?(name, *)
35
- @collection_of_internals.names.include?(name) || super
36
+ def respond_to_missing?(*)
37
+ false
36
38
  end
37
39
 
38
40
  private
39
41
 
40
- def assign_with(prepared_name:, value:, &block) # rubocop:disable Lint/UnusedMethodArgument
41
- return yield unless @collection_of_internals.names.include?(prepared_name)
42
+ def define_attribute_methods! # rubocop:disable Metrics/MethodLength
43
+ @collection_of_internals.each do |internal|
44
+ define_singleton_method(internal.name) do
45
+ fetch_value(attribute: internal)
46
+ end
42
47
 
43
- internal = @collection_of_internals.find_by(name: prepared_name) # ::Servactory::Internals::Internal
48
+ define_singleton_method(:"#{internal.name}=") do |value|
49
+ assign_value(attribute: internal, value:)
50
+ end
44
51
 
45
- return yield if internal.nil?
52
+ next unless @context.config.predicate_methods_enabled
46
53
 
47
- Servactory::Maintenance::Attributes::Tools::Validation.validate!(
54
+ define_singleton_method(:"#{internal.name}?") do
55
+ fetch_predicate(attribute: internal)
56
+ end
57
+ end
58
+ end
59
+
60
+ def assign_value(attribute:, value:)
61
+ @validated_attributes.delete(attribute.name)
62
+
63
+ Servactory::Maintenance::Validations::Performer.validate!(
48
64
  context: @context,
49
- attribute: internal,
65
+ attribute:,
50
66
  value:
51
67
  )
52
68
 
53
- @context.send(:servactory_service_warehouse).assign_internal(internal.name, value)
54
- end
69
+ @context.send(:servactory_service_warehouse).assign_internal(attribute.name, value)
55
70
 
56
- def fetch_with(name:, &block) # rubocop:disable Metrics/MethodLength, Lint/UnusedMethodArgument
57
- predicate = @context.config.predicate_methods_enabled && name.end_with?("?")
58
-
59
- internal_name = predicate ? name.to_s.chomp("?").to_sym : name
60
- internal = @collection_of_internals.find_by(name: internal_name)
71
+ @validated_attributes << attribute.name
72
+ end
61
73
 
62
- return yield if internal.nil?
74
+ def fetch_value(attribute:)
75
+ value = @context.send(:servactory_service_warehouse).fetch_internal(attribute.name)
63
76
 
64
- internal_value = @context.send(:servactory_service_warehouse).fetch_internal(internal.name)
77
+ if @validated_attributes.exclude?(attribute.name)
78
+ Servactory::Maintenance::Validations::Performer.validate!(
79
+ context: @context,
80
+ attribute:,
81
+ value:
82
+ )
83
+ end
65
84
 
66
- Servactory::Maintenance::Attributes::Tools::Validation.validate!(
67
- context: @context,
68
- attribute: internal,
69
- value: internal_value
70
- )
85
+ value
86
+ end
71
87
 
72
- predicate ? Servactory::Utils.query_attribute(internal_value) : internal_value
88
+ def fetch_predicate(attribute:)
89
+ Servactory::Utils.query_attribute(fetch_value(attribute:))
73
90
  end
74
91
 
75
92
  def raise_error_for(type, name)
@@ -7,6 +7,8 @@ module Servactory
7
7
  def initialize(context:, collection_of_outputs:)
8
8
  @context = context
9
9
  @collection_of_outputs = collection_of_outputs
10
+
11
+ define_attribute_methods!
10
12
  end
11
13
 
12
14
  def only(*names)
@@ -21,49 +23,55 @@ module Servactory
21
23
  .to_h { |output| [output.name, send(output.name)] }
22
24
  end
23
25
 
24
- def method_missing(name, *args)
26
+ def method_missing(name, *_args)
25
27
  if name.to_s.end_with?("=")
26
28
  prepared_name = name.to_s.delete("=").to_sym
27
-
28
- assign_with(prepared_name:, value: args.pop) { raise_error_for(:assign, prepared_name) }
29
+ raise_error_for(:assign, prepared_name)
29
30
  else
30
- fetch_with(name:) { raise_error_for(:fetch, name) }
31
+ raise_error_for(:fetch, name)
31
32
  end
32
33
  end
33
34
 
34
- def respond_to_missing?(name, *)
35
- @collection_of_outputs.names.include?(name) || super
35
+ def respond_to_missing?(*)
36
+ false
36
37
  end
37
38
 
38
39
  private
39
40
 
40
- def assign_with(prepared_name:, value:, &block) # rubocop:disable Lint/UnusedMethodArgument
41
- return yield unless @collection_of_outputs.names.include?(prepared_name)
41
+ def define_attribute_methods! # rubocop:disable Metrics/MethodLength
42
+ @collection_of_outputs.each do |output|
43
+ define_singleton_method(output.name) do
44
+ fetch_value(attribute: output)
45
+ end
46
+
47
+ define_singleton_method(:"#{output.name}=") do |value|
48
+ assign_value(attribute: output, value:)
49
+ end
42
50
 
43
- output = @collection_of_outputs.find_by(name: prepared_name)
51
+ next unless @context.config.predicate_methods_enabled
44
52
 
45
- return yield if output.nil?
53
+ define_singleton_method(:"#{output.name}?") do
54
+ fetch_predicate(attribute: output)
55
+ end
56
+ end
57
+ end
46
58
 
47
- Servactory::Maintenance::Attributes::Tools::Validation.validate!(
59
+ def assign_value(attribute:, value:)
60
+ Servactory::Maintenance::Validations::Performer.validate!(
48
61
  context: @context,
49
- attribute: output,
62
+ attribute:,
50
63
  value:
51
64
  )
52
65
 
53
- @context.send(:servactory_service_warehouse).assign_output(output.name, value)
66
+ @context.send(:servactory_service_warehouse).assign_output(attribute.name, value)
54
67
  end
55
68
 
56
- def fetch_with(name:, &block) # rubocop:disable Lint/UnusedMethodArgument
57
- predicate = @context.config.predicate_methods_enabled && name.end_with?("?")
58
-
59
- output_name = predicate ? name.to_s.chomp("?").to_sym : name
60
- output = @collection_of_outputs.find_by(name: output_name)
61
-
62
- return yield if output.nil?
63
-
64
- output_value = @context.send(:servactory_service_warehouse).fetch_output(output.name)
69
+ def fetch_value(attribute:)
70
+ @context.send(:servactory_service_warehouse).fetch_output(attribute.name)
71
+ end
65
72
 
66
- predicate ? Servactory::Utils.query_attribute(output_value) : output_value
73
+ def fetch_predicate(attribute:)
74
+ Servactory::Utils.query_attribute(fetch_value(attribute:))
67
75
  end
68
76
 
69
77
  def raise_error_for(type, name)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Servactory
4
4
  module DSL
5
- STROMA = Stroma::Matrix.define(:my_lib) do
5
+ STROMA = Stroma::Matrix.define(:servactory) do
6
6
  register(:configuration, Configuration::DSL)
7
7
  register(:info, Info::DSL)
8
8
  register(:context, Context::DSL)
@@ -138,15 +138,14 @@ module Servactory
138
138
  end
139
139
 
140
140
  def extract_message_from_value(value:)
141
- value.is_a?(Hash) ? value.fetch(:message, nil) : nil
141
+ value.is_a?(Hash) ? value[:message] : nil
142
142
  end
143
143
 
144
144
  def enrich_options_with_common_fields(attribute:, options:)
145
- actor = attribute.class::Actor.new(attribute)
146
145
  must = attribute.collection_of_options.find_by(name: :must)
147
146
 
148
147
  options.merge(
149
- actor:,
148
+ actor: attribute.actor,
150
149
  types: attribute.types,
151
150
  must: must&.value
152
151
  )
@@ -2,29 +2,22 @@
2
2
 
3
3
  module Servactory
4
4
  module Inputs
5
- class Collection
6
- extend Forwardable
5
+ # Specialized collection for Input attributes.
6
+ #
7
+ # Overrides `lookup_name` to use `internal_name` instead of `name`,
8
+ # supporting the `as:` parameter that renames inputs internally.
9
+ # Adds `flat_map` delegation for input-specific enumeration needs.
10
+ class Collection < Servactory::Maintenance::Attributes::Collection
11
+ def_delegators :@collection, :flat_map
7
12
 
8
- def_delegators :@collection, :<<, :filter, :each, :map, :flat_map, :to_h, :merge, :find
13
+ private
9
14
 
10
- def initialize(collection = Set.new)
11
- @collection = collection
12
- end
13
-
14
- def only(*names)
15
- Collection.new(filter { |input| names.include?(input.internal_name) })
16
- end
17
-
18
- def except(*names)
19
- Collection.new(filter { |input| names.exclude?(input.internal_name) })
20
- end
21
-
22
- def names
23
- map(&:name)
24
- end
25
-
26
- def find_by(name:)
27
- find { |input| input.internal_name == name }
15
+ # Returns `internal_name` for indexing, supporting the `as:` parameter.
16
+ #
17
+ # @param attribute [Object] the input attribute
18
+ # @return [Symbol] the internal name used for lookup
19
+ def lookup_name(attribute)
20
+ attribute.internal_name
28
21
  end
29
22
  end
30
23
  end