Module: Ai2Web::Schema
- Defined in:
- lib/ai2web/schema.rb
Overview
Minimal JSON-Schema-subset validator for action input schemas. Port of @ai2web/core validateSchema: pragmatic (object with typed/required properties, primitives, arrays, enum) rather than the whole of JSON Schema. Used by the server to validate incoming requests against an action's declared input_schema.
Class Method Summary collapse
- .type_of(value) ⇒ Object
-
.validate_schema(value, schema, path = "input") ⇒ Object
Validate a value against a JSON-Schema-subset.
Class Method Details
.type_of(value) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/ai2web/schema.rb', line 16 def type_of(value) case value when nil then "null" when true, false then "boolean" when Integer, Float then "number" when String then "string" when Array then "array" when Hash then "object" else "unknown" end end |
.validate_schema(value, schema, path = "input") ⇒ Object
Validate a value against a JSON-Schema-subset. An empty/absent schema accepts anything.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/ai2web/schema.rb', line 29 def validate_schema(value, schema, path = "input") errors = [] schema = Util.deep_stringify(schema) return SchemaResult.new(true, errors) unless schema.is_a?(Hash) && !schema.empty? value = Util.deep_stringify(value) declared = schema["type"] has_declared = declared.is_a?(String) && !declared.empty? if has_declared ok = if declared == "integer" value.is_a?(Integer) && value != true && value != false else type_of(value) == declared end unless ok errors << "#{path}: expected #{declared}, got #{type_of(value)}" return SchemaResult.new(false, errors) # wrong base type: stop end end enum = schema["enum"] errors << "#{path}: value is not one of the allowed options" if enum.is_a?(Array) && !enum.include?(value) is_object = value.is_a?(Hash) if (declared == "object" || (!has_declared && is_object)) && is_object props = schema["properties"].is_a?(Hash) ? schema["properties"] : {} (schema["required"] || []).each do |key| errors << "#{path}.#{key}: required" unless value.key?(key) end props.each do |key, sub| errors.concat(validate_schema(value[key], sub, "#{path}.#{key}").errors) if value.key?(key) end end if (declared == "array" || (!has_declared && value.is_a?(Array))) && value.is_a?(Array) && schema["items"] value.each_with_index do |item, i| errors.concat(validate_schema(item, schema["items"], "#{path}[#{i}]").errors) end end SchemaResult.new(errors.empty?, errors) end |