Module: FlyIO::SchemaRegistry

Defined in:
lib/fly_io/schema_registry.rb

Class Method Summary collapse

Class Method Details

.build(name, attributes) ⇒ Object



25
26
27
28
# File 'lib/fly_io/schema_registry.rb', line 25

def build(name, attributes)
  install_model_constants!
  Models.const_get(schemas.fetch(name).fetch("x-ruby-class"), false).new(attributes)
end

.coerce(schema, value) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/fly_io/schema_registry.rb', line 30

def coerce(schema, value)
  return value if value.nil? || !schema || !schema.is_a?(Hash)

  schema = resolve(schema)
  if (reference = schema["$resolved_ref"]) && value.is_a?(Hash)
    return build(reference, value)
  end

  schema = flatten_all_of(schema)

  case schema["type"]
  when "array"
    value.is_a?(Array) ? value.map { |item| coerce(schema["items"], item) } : value
  when "object"
    coerce_object(schema, value)
  else
    value
  end
end

.coerce_object(schema, value) ⇒ Object



80
81
82
83
84
85
86
87
# File 'lib/fly_io/schema_registry.rb', line 80

def coerce_object(schema, value)
  return value unless value.is_a?(Hash)

  properties = schema.fetch("properties", {})
  value.each_with_object({}) do |(key, child), result|
    result[key.to_s] = coerce(properties[key.to_s] || schema["additionalProperties"], child)
  end
end

.coerce_property(schema_name, property, value) ⇒ Object



50
51
52
53
# File 'lib/fly_io/schema_registry.rb', line 50

def coerce_property(schema_name, property, value)
  schema = schemas[schema_name]
  coerce(schema&.dig("properties", property), value)
end

.flatten_all_of(schema) ⇒ Object



69
70
71
72
73
74
75
76
77
78
# File 'lib/fly_io/schema_registry.rb', line 69

def flatten_all_of(schema)
  return schema unless schema["allOf"]

  schema["allOf"].reduce(schema.except("allOf")) do |result, member|
    resolved = flatten_all_of(resolve(member).except("$resolved_ref"))
    result.merge(resolved) do |key, left, right|
      key == "properties" ? left.merge(right) : right
    end
  end
end

.install_model_constants!Object



13
14
15
16
17
18
19
20
21
22
23
# File 'lib/fly_io/schema_registry.rb', line 13

def install_model_constants!
  schemas.each do |name, schema|
    constant_name = schema.fetch("x-ruby-class")
    next if Models.const_defined?(constant_name, false)

    schema_name = name
    klass = Class.new(Model)
    klass.const_set(:SCHEMA_NAME, schema_name.freeze)
    Models.const_set(constant_name, klass)
  end
end

.resolve(schema) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/fly_io/schema_registry.rb', line 55

def resolve(schema)
  reference = schema["$ref"]
  return schema unless reference

  name = if reference.start_with?("#/components/schemas/")
           reference.delete_prefix("#/components/schemas/")
         elsif reference.start_with?("#/additional/schemas/")
           reference.delete_prefix("#/additional/schemas/")
         else
           raise FlyIO::ArgumentError, "unsupported schema reference: #{reference}"
         end
  schemas.fetch(name).merge("$resolved_ref" => name)
end

.schemasObject



9
10
11
# File 'lib/fly_io/schema_registry.rb', line 9

def schemas
  @schemas ||= JSON.parse(File.read(File.expand_path("generated/schemas.json", __dir__))).freeze
end