Module: Autonoma::Schema

Defined in:
lib/autonoma/schema.rb

Constant Summary collapse

VALID_TYPES =
Set.new(%w[string integer number boolean timestamp date uuid json]).freeze

Class Method Summary collapse

Class Method Details

.build_schema_from_factories(factories, scope_field) ⇒ Object

Build the SDK’s discover-time schema from registered factories.



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/autonoma/schema.rb', line 58

def self.build_schema_from_factories(factories, scope_field)
  models = []

  (factories || {}).each do |entity, factory|
    if factory.input_fields.nil? || factory.input_fields.empty?
      raise ArgumentError,
            "Factory \"#{entity}\" has no input_fields. " \
            "Every factory must declare input_fields in define_factory(...)."
    end

    models << ModelInfo.new(
      name: entity,
      table_name: camel_to_snake(entity),
      fields: fields_from_input_fields(factory.input_fields)
    )
  end

  SchemaInfo.new(
    models: models,
    edges: [],
    relations: [],
    scope_field: scope_field
  )
end

.field_type_from_class(type_str) ⇒ Object

Map a Ruby type string to the SDK’s coarse type string.



8
9
10
11
12
13
# File 'lib/autonoma/schema.rb', line 8

def self.field_type_from_class(type_str)
  return "string" if type_str.nil?

  normalized = type_str.to_s.downcase
  VALID_TYPES.include?(normalized) ? normalized : "string"
end

.schema_to_wire(schema) ⇒ Object

Serialise a SchemaInfo to the JSON shape the dashboard expects.



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/autonoma/schema.rb', line 84

def self.schema_to_wire(schema)
  {
    "models" => schema.models.map do |m|
      {
        "name" => m.name,
        "tableName" => m.table_name,
        "fields" => m.fields.map do |f|
          {
            "name" => f.name,
            "type" => f.type,
            "isRequired" => f.is_required,
            "isId" => f.is_id,
            "hasDefault" => f.has_default
          }
        end
      }
    end,
    "edges" => schema.edges.map do |e|
      {
        "from" => e.from_model,
        "to" => e.to_model,
        "localField" => e.local_field,
        "foreignField" => e.foreign_field,
        "nullable" => e.nullable
      }
    end,
    "relations" => schema.relations.map do |r|
      {
        "parentModel" => r.parent_model,
        "childModel" => r.child_model,
        "parentField" => r.parent_field,
        "childField" => r.child_field
      }
    end,
    "scopeField" => schema.scope_field
  }
end

.validate_input(fields, input_fields) ⇒ Object

Validate input fields hash: strip unknown keys, check required fields.



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/autonoma/schema.rb', line 123

def self.validate_input(fields, input_fields)
  known_names = Set.new
  required_names = []

  (input_fields || []).each do |f|
    name = (f[:name] || f["name"]).to_s
    known_names.add(name)
    req = f[:required].nil? ? f["required"] : f[:required]
    required_names << name if req
  end

  # Strip unknown keys
  validated = fields.select { |k, _| known_names.include?(k.to_s) }

  # Check required fields
  missing = required_names.select { |name| !validated.key?(name) && !validated.key?(name.to_sym) }
  unless missing.empty?
    raise Errors.invalid_body("missing required fields: #{missing.join(", ")}")
  end

  validated
end