Class: Conductor::Worker::JsonSchemaGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/conductor/worker/task_definition_registrar.rb

Overview

JsonSchemaGenerator - Utility for generating JSON Schema from Ruby types Can be extended to work with Sorbet types or RBS annotations

Constant Summary collapse

TYPE_MAP =

Ruby type to JSON Schema type mapping

{
  'String' => 'string',
  'Integer' => 'integer',
  'Float' => 'number',
  'Numeric' => 'number',
  'TrueClass' => 'boolean',
  'FalseClass' => 'boolean',
  'Array' => 'array',
  'Hash' => 'object',
  'NilClass' => 'null',
  'Time' => 'string',
  'Date' => 'string',
  'DateTime' => 'string'
}.freeze

Class Method Summary collapse

Class Method Details

.from_class(klass) ⇒ Hash

Generate a schema from a Ruby class definition Works with Struct, Data (Ruby 3.2+), or classes with attr_accessor

Parameters:

  • klass (Class)

    Ruby class

Returns:

  • (Hash)

    JSON Schema



299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
# File 'lib/conductor/worker/task_definition_registrar.rb', line 299

def self.from_class(klass)
  properties = {}

  # Try to get attribute names
  if klass.respond_to?(:members)
    # Struct or Data
    klass.members.each do |attr|
      properties[attr.to_s] = { 'type' => 'string' }
    end
  elsif klass.instance_methods.include?(:to_h)
    # Has to_h, try to instantiate and inspect
    # Skip this for safety
  end

  {
    '$schema' => 'http://json-schema.org/draft-07/schema#',
    'type' => 'object',
    'title' => klass.name,
    'properties' => properties
  }
end

.from_value(value) ⇒ Hash

Generate JSON Schema from a Ruby value (for inference)

Parameters:

  • value (Object)

    A sample value

Returns:

  • (Hash)

    JSON Schema



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/conductor/worker/task_definition_registrar.rb', line 251

def self.from_value(value)
  case value
  when String
    { 'type' => 'string' }
  when Integer
    { 'type' => 'integer' }
  when Float
    { 'type' => 'number' }
  when TrueClass, FalseClass
    { 'type' => 'boolean' }
  when Array
    if value.empty?
      { 'type' => 'array' }
    else
      { 'type' => 'array', 'items' => from_value(value.first) }
    end
  when Hash
    generate_object_schema(value)
  when Time, DateTime
    { 'type' => 'string', 'format' => 'date-time' }
  when Date
    { 'type' => 'string', 'format' => 'date' }
  when NilClass
    { 'type' => 'null' }
  else
    { 'type' => 'object' }
  end
end

.generate_object_schema(hash) ⇒ Hash

Generate schema from a hash with sample values

Parameters:

  • hash (Hash)

    Hash with sample values

Returns:

  • (Hash)

    JSON Schema



283
284
285
286
287
288
289
290
291
292
293
# File 'lib/conductor/worker/task_definition_registrar.rb', line 283

def self.generate_object_schema(hash)
  properties = {}
  hash.each do |key, value|
    properties[key.to_s] = from_value(value)
  end

  {
    'type' => 'object',
    'properties' => properties
  }
end