Module: Liminal::Components

Defined in:
lib/liminal/components.rb

Overview

Generic OpenAPI component registration with normalized collision checks.

Class Method Summary collapse

Class Method Details

.normalize_name(name) ⇒ Object

Return the canonical, immutable OpenAPI component key for name.



49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/liminal/components.rb', line 49

def normalize_name(name)
  unless name.is_a?(String) || name.is_a?(Symbol)
    raise InvalidComponentNameError,
          "Component name must be a String or Symbol; received #{name.class}."
  end

  logical_name = name.to_s.dup.freeze
  return logical_name if NAME_PATTERN.match?(logical_name)

  expectation = "one or more letters, digits, periods, hyphens, or underscores"
  raise InvalidComponentNameError,
        "Invalid component name #{logical_name.inspect}; expected #{expectation}."
end

.reference(name) ⇒ Object



43
44
45
46
# File 'lib/liminal/components.rb', line 43

def reference(name)
  logical_name = normalize_name(name)
  {"$ref" => "#/components/schemas/#{logical_name}".freeze}.freeze
end

.register(document:, name:, schema:) ⇒ Hash

Register schema under name and return its local component reference.

Parameters:

  • document (Hash)

    mutable OpenAPI document

  • name (String, Symbol)

    logical component name

  • schema (Hash)

    Schema Object to register

Returns:

  • (Hash)

    a string-keyed local $ref

Raises:

  • (ArgumentError)


17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/liminal/components.rb', line 17

def register(document:, name:, schema:)
  raise ArgumentError, "document must be a Hash" unless document.is_a?(Hash)
  raise ArgumentError, "schema must be a Hash" unless schema.is_a?(Hash)

  logical_name = normalize_name(name)
  normalized_schema = Schema.normalize(schema)
  schemas = schema_map(document)
  existing_keys = logical_keys(schemas, logical_name)
  if existing_keys.length > 1
    raise ComponentCollisionError,
          "Component #{logical_name.inspect} is registered under both String and Symbol keys."
  end

  if existing_keys.one?
    existing = Schema.normalize(schemas.fetch(existing_keys.first))
    unless existing == normalized_schema
      raise ComponentCollisionError,
            "Component #{logical_name.inspect} is already registered with a different schema."
    end
  else
    schemas[logical_name] = normalized_schema
  end

  reference(logical_name)
end