Class: LcpSdk::SchemaValidator

Inherits:
Object
  • Object
show all
Defined in:
lib/schema_validator.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(schema_documents) ⇒ SchemaValidator

Returns a new instance of SchemaValidator.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/schema_validator.rb', line 9

def initialize(schema_documents)
  require "json_schemer"
  # Keep a private copy so self-references in core.json can be made
  # fragment-local without mutating the caller's canonical documents.
  @documents = schema_documents.transform_values do |document|
    JSON.parse(JSON.generate(document))
  end
  @documents.each_value do |document|
    rewrite_core_refs(document) if document["$id"] == "https://lcp.dev/schemas/core.json"
  end
  @ids = {}
  @documents.each do |name, document|
    id = document.fetch("$id", name)
    @ids[normalize(name)] = id
    @ids[normalize(id)] = id
  end
end

Class Method Details

.from_directory(root) ⇒ Object



27
28
29
30
31
32
33
34
# File 'lib/schema_validator.rb', line 27

def self.from_directory(root)
  documents = {}
  Dir.glob(File.join(root, "**", "*.json")).each do |path|
    name = path.delete_prefix("#{root}/")
    documents[name] = JSON.parse(File.read(path))
  end
  new(documents)
end

Instance Method Details

#validate(schema_name, instance) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/schema_validator.rb', line 36

def validate(schema_name, instance)
  id = @ids.fetch(normalize(schema_name)) { raise KeyError, "unknown LCP schema: #{schema_name}" }
  schema = @documents.values.find { |candidate| candidate["$id"] == id } || @documents.fetch(schema_name)
  errors = JSONSchemer.schema(schema, ref_resolver: lambda do |uri|
    reference = uri.to_s
    @documents.values.find { |candidate| candidate["$id"].to_s == reference } ||
      @documents[reference] ||
      @documents[reference.sub(%r{.*/}, "")]
  end).validate(instance).to_a
  raise SchemaValidationError, "LCP schema validation failed for #{schema_name}: #{errors.first}" unless errors.empty?
  true
end

#validate_envelope(envelope) ⇒ Object



49
50
51
52
53
54
# File 'lib/schema_validator.rb', line 49

def validate_envelope(envelope)
  validate("schemas/envelope.json", envelope)
  type = envelope.dig("lcp", "message", "type")
  raise SchemaValidationError, "missing lcp.message.type" unless type.is_a?(String)
  validate("schemas/#{type}.json", envelope.dig("lcp", "payload"))
end

#validate_offer(offer) ⇒ Object



56
57
58
# File 'lib/schema_validator.rb', line 56

def validate_offer(offer)
  validate("schemas/offer.json", offer)
end

#validate_vertical(vertical, attributes) ⇒ Object



60
61
62
# File 'lib/schema_validator.rb', line 60

def validate_vertical(vertical, attributes)
  validate("verticals/#{vertical}.json", attributes)
end