class Dry::Schema::JSONSchema::SchemaCompiler
@api private
Constants
- IDENTITY
- PREDICATE_TO_TYPE
- TO_INTEGER
- UnknownConversionError
An error raised when a predicate cannot be converted
Attributes
keys[R]
@api private
required[R]
@api private
Public Class Methods
new(root: false, loose: false)
click to toggle source
@api private
# File lib/dry/schema/extensions/json_schema/schema_compiler.rb, line 61 def initialize(root: false, loose: false) @keys = EMPTY_HASH.dup @required = Set.new @root = root @loose = loose end
Public Instance Methods
call(ast)
click to toggle source
@api private
# File lib/dry/schema/extensions/json_schema/schema_compiler.rb, line 79 def call(ast) visit(ast) end
fetch_filled_options(type, _target)
click to toggle source
@api private
# File lib/dry/schema/extensions/json_schema/schema_compiler.rb, line 182 def fetch_filled_options(type, _target) case type when "string" {minLength: 1} when "array" raise_unknown_conversion_error!(:type, :array) unless loose? {not: {type: "null"}} else {not: {type: "null"}} end end
fetch_type_opts_for_predicate(name, rest, target)
click to toggle source
@api private
# File lib/dry/schema/extensions/json_schema/schema_compiler.rb, line 170 def fetch_type_opts_for_predicate(name, rest, target) type_opts = PREDICATE_TO_TYPE.fetch(name) do raise_unknown_conversion_error!(:predicate, name) unless loose? EMPTY_HASH end.dup type_opts.transform_values! { |v| v.respond_to?(:call) ? v.call(rest[0][1], target) : v } type_opts.merge!(fetch_filled_options(target[:type], target)) if name == :filled? type_opts end
loose?()
click to toggle source
@api private
# File lib/dry/schema/extensions/json_schema/schema_compiler.rb, line 213 def loose? @loose end
merge_opts!(orig_opts, new_opts)
click to toggle source
@api private
# File lib/dry/schema/extensions/json_schema/schema_compiler.rb, line 196 def merge_opts!(orig_opts, new_opts) new_type = new_opts[:type] orig_type = orig_opts[:type] if orig_type && new_type && orig_type != new_type new_opts[:type] = [orig_type, new_type] end orig_opts.merge!(new_opts) end
raise_unknown_conversion_error!(type, name)
click to toggle source
# File lib/dry/schema/extensions/json_schema/schema_compiler.rb, line 217 def raise_unknown_conversion_error!(type, name) message = <<~MSG Could not find an equivalent conversion for #{type} #{name.inspect}. This means that your generated JSON schema may be missing this validation. You can ignore this by generating the schema in "loose" mode, i.e.: my_schema.json_schema(loose: true) MSG raise UnknownConversionError, message.chomp end
root?()
click to toggle source
@api private
# File lib/dry/schema/extensions/json_schema/schema_compiler.rb, line 208 def root? @root end
to_hash()
click to toggle source
@api private
# File lib/dry/schema/extensions/json_schema/schema_compiler.rb, line 69 def to_hash result = {} result[:$schema] = "http://json-schema.org/draft-06/schema#" if root? result.merge!(type: "object", properties: keys, required: required.to_a) result end
Also aliased as: to_h
visit(node, opts = EMPTY_HASH)
click to toggle source
@api private
# File lib/dry/schema/extensions/json_schema/schema_compiler.rb, line 84 def visit(node, opts = EMPTY_HASH) meth, rest = node public_send(:"visit_#{meth}", rest, opts) end
visit_and(node, opts = EMPTY_HASH)
click to toggle source
@api private
# File lib/dry/schema/extensions/json_schema/schema_compiler.rb, line 104 def visit_and(node, opts = EMPTY_HASH) left, right = node # We need to know the type first to apply filled macro if left[1][0] == :filled? visit(right, opts) visit(left, opts) else visit(left, opts) visit(right, opts) end end
visit_each(node, opts = EMPTY_HASH)
click to toggle source
@api private
# File lib/dry/schema/extensions/json_schema/schema_compiler.rb, line 125 def visit_each(node, opts = EMPTY_HASH) visit(node, opts.merge(member: true)) end
visit_implication(node, opts = EMPTY_HASH)
click to toggle source
@api private
# File lib/dry/schema/extensions/json_schema/schema_compiler.rb, line 118 def visit_implication(node, opts = EMPTY_HASH) node.each do |el| visit(el, **opts, required: false) end end
visit_key(node, opts = EMPTY_HASH)
click to toggle source
@api private
# File lib/dry/schema/extensions/json_schema/schema_compiler.rb, line 130 def visit_key(node, opts = EMPTY_HASH) name, rest = node if opts.fetch(:required, :true) required << name.to_s else opts.delete(:required) end visit(rest, opts.merge(key: name)) end
visit_not(node, opts = EMPTY_HASH)
click to toggle source
@api private
# File lib/dry/schema/extensions/json_schema/schema_compiler.rb, line 143 def visit_not(node, opts = EMPTY_HASH) _name, rest = node visit_predicate(rest, opts) end
visit_predicate(node, opts = EMPTY_HASH)
click to toggle source
@api private
# File lib/dry/schema/extensions/json_schema/schema_compiler.rb, line 150 def visit_predicate(node, opts = EMPTY_HASH) name, rest = node if name.equal?(:key?) prop_name = rest[0][1] keys[prop_name] = {} else target = keys[opts[:key]] type_opts = fetch_type_opts_for_predicate(name, rest, target) if target[:type]&.include?("array") target[:items] ||= {} merge_opts!(target[:items], type_opts) else merge_opts!(target, type_opts) end end end
visit_set(node, opts = EMPTY_HASH)
click to toggle source
@api private
# File lib/dry/schema/extensions/json_schema/schema_compiler.rb, line 90 def visit_set(node, opts = EMPTY_HASH) target = (key = opts[:key]) ? self.class.new : self node.map { |child| target.visit(child, opts) } return unless key target_info = opts[:member] ? {items: target.to_h} : target.to_h type = opts[:member] ? "array" : "object" keys.update(key => {**keys[key], type: type, **target_info}) end