json_schemer 0.2.25 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd29a78d2cbd45dc0409c551d0e3c11e39a801204bab75e22ded249c4ef8edf8
4
- data.tar.gz: 9d0556d1f4723ae50b9a038595f44ffdc9c0dcc8d05d9b9771f58248fc88a764
3
+ metadata.gz: 460e70448c0b37c65fd4e51f046036336b17121cc716c197fe80f2e2517f45e7
4
+ data.tar.gz: f06d11eab9bb88c45a018c8913d6a5d2e33162064c9f995e5772beb811e68ed6
5
5
  SHA512:
6
- metadata.gz: d3bb75eb37c9ad70776fbf8d7fc5c1d7cc4a79bf7c68e2430dbf30f256fb0a3e1cddf718fa1799486814058d98455ef47b62baa514b1b49beafe0c7fc6a489dc
7
- data.tar.gz: eea979521c2d65afef0325f94513ecf64bf604c562af41afae2ec258a4449b70a28aee927be925681ceecc434ba716271d7bbc6a713f8413b0f22710b7ed7c9c
6
+ metadata.gz: 83549b328ba3067ed206a8bdea448e34ba274c7c5a7857d38793d74f0691339f845b0e39fdbb0ff8c3869dfbaf0dcd13380c458c80397b100a848f96443bf691
7
+ data.tar.gz: 106314824f1805e7d2306c10c696d4503b54b4d9203321e37816242c30598c3870ec40ade53dc08692ec3b2a35f18360c96211f0b8af44fd4414931da4e5b1e5
@@ -6,12 +6,8 @@ jobs:
6
6
  fail-fast: false
7
7
  matrix:
8
8
  os: [ubuntu-latest, windows-latest, macos-latest]
9
- ruby: [2.4, 2.5, 2.6, 2.7, 3.0, 3.1, 3.2, head, jruby, jruby-head, truffleruby, truffleruby-head]
9
+ ruby: [2.5, 2.6, 2.7, 3.0, 3.1, 3.2, head, jruby, jruby-head, truffleruby, truffleruby-head]
10
10
  exclude:
11
- - os: windows-latest
12
- ruby: jruby
13
- - os: windows-latest
14
- ruby: jruby-head
15
11
  - os: windows-latest
16
12
  ruby: truffleruby
17
13
  - os: windows-latest
data/CHANGELOG.md ADDED
@@ -0,0 +1,18 @@
1
+ # Changelog
2
+
3
+ ## [1.0.0] - 2023-05-26
4
+
5
+ ### Breaking Changes
6
+
7
+ - Ruby 2.4 is no longer supported.
8
+ - The default `regexp_resolver` is now `ruby`, which passes patterns directly to `Regexp`. The previous default, `ecma`, rewrites patterns to behave more like Javascript (ECMA-262) regular expressions:
9
+ - Beginning of string: `^` -> `\A`
10
+ - End of string: `$` -> `\z`
11
+ - Space: `\s` -> `[\t\r\n\f\v\uFEFF\u2029\p{Zs}]`
12
+ - Non-space: `\S` -> `[^\t\r\n\f\v\uFEFF\u2029\p{Zs}]`
13
+ - Invalid ECMA-262 regular expressions raise `JSONSchemer::InvalidEcmaRegexp` when `regexp_resolver` is set to `ecma`.
14
+ - Embedded subschemas (ie, subschemas referenced by `$id`) can only be found under "known" keywords (eg, `definitions`). Previously, the entire schema object was scanned for `$id`.
15
+ - Empty fragments are now removed from `$ref` URIs before calling `ref_resolver`.
16
+ - Refs that are fragment-only JSON pointers with special characters must use the proper encoding (eg, `"$ref": "#/definitions/some-%7Bid%7D"`).
17
+
18
+ [1.0.0]: https://github.com/davishmcclurg/json_schemer/releases/tag/v1.0.0
data/Gemfile.lock CHANGED
@@ -1,19 +1,15 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- json_schemer (0.2.25)
5
- ecma-re-validator (~> 0.3)
4
+ json_schemer (1.0.1)
6
5
  hana (~> 1.3)
7
6
  regexp_parser (~> 2.0)
8
7
  simpleidn (~> 0.2)
9
- uri_template (~> 0.7)
10
8
 
11
9
  GEM
12
10
  remote: https://rubygems.org/
13
11
  specs:
14
12
  docile (1.4.0)
15
- ecma-re-validator (0.3.0)
16
- regexp_parser (~> 2.0)
17
13
  hana (1.3.7)
18
14
  minitest (5.15.0)
19
15
  rake (13.0.6)
@@ -30,7 +26,6 @@ GEM
30
26
  unf_ext
31
27
  unf (0.1.4-java)
32
28
  unf_ext (0.0.8.2)
33
- uri_template (0.7.0)
34
29
 
35
30
  PLATFORMS
36
31
  java
data/README.md CHANGED
@@ -45,7 +45,12 @@ schemer.valid?({ 'abc' => 10 })
45
45
  # error validation (`validate` returns an enumerator)
46
46
 
47
47
  schemer.validate({ 'abc' => 10 }).to_a
48
- # => [{"data"=>10, "schema"=>{"type"=>"integer", "minimum"=>11}, "pointer"=>"#/abc", "type"=>"minimum"}]
48
+ # => [{"data"=>10,
49
+ # "data_pointer"=>"/abc",
50
+ # "schema"=>{"type"=>"integer", "minimum"=>11},
51
+ # "schema_pointer"=>"/properties/abc",
52
+ # "root_schema"=>{"type"=>"object", "properties"=>{"abc"=>{"type"=>"integer", "minimum"=>11}}},
53
+ # "type"=>"minimum"}]
49
54
 
50
55
  # default property values
51
56
 
@@ -74,6 +79,30 @@ schemer = JSONSchemer.schema(schema)
74
79
 
75
80
  schema = '{ "type": "integer" }'
76
81
  schemer = JSONSchemer.schema(schema)
82
+
83
+ # schema validation
84
+
85
+ JSONSchemer.valid_schema?({ '$id' => '#valid' })
86
+ # => true
87
+
88
+ JSONSchemer.validate_schema({ '$id' => nil }).to_a
89
+ # => [{"data"=>nil,
90
+ # "data_pointer"=>"/$id",
91
+ # "schema"=>{"type"=>"string", "format"=>"uri-reference"},
92
+ # "schema_pointer"=>"/properties/$id",
93
+ # "root_schema"=>{...meta schema},
94
+ # "type"=>"string"}]
95
+
96
+ JSONSchemer.schema({ '$id' => '#valid' }).valid_schema?
97
+ # => true
98
+
99
+ JSONSchemer.schema({ '$id' => nil }).validate_schema.to_a
100
+ # => [{"data"=>nil,
101
+ # "data_pointer"=>"/$id",
102
+ # "schema"=>{"type"=>"string", "format"=>"uri-reference"},
103
+ # "schema_pointer"=>"/properties/$id",
104
+ # "root_schema"=>{...meta schema},
105
+ # "type"=>"string"}]
77
106
  ```
78
107
 
79
108
  ## Options
@@ -113,8 +142,9 @@ JSONSchemer.schema(
113
142
  ref_resolver: 'net/http',
114
143
 
115
144
  # use different method to match regexes
116
- # 'ecma'/'ruby'/proc/lambda/respond_to?(:call)
117
- # default: 'ecma'
145
+ # 'ruby'/'ecma'/proc/lambda/respond_to?(:call)
146
+ # 'ruby': proc { |pattern| Regexp.new(pattern) }
147
+ # default: 'ruby'
118
148
  regexp_resolver: proc do |pattern|
119
149
  RE2::Regexp.new(pattern)
120
150
  end
data/json_schemer.gemspec CHANGED
@@ -20,16 +20,14 @@ Gem::Specification.new do |spec|
20
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
21
  spec.require_paths = ["lib"]
22
22
 
23
- spec.required_ruby_version = '>= 2.4'
23
+ spec.required_ruby_version = '>= 2.5'
24
24
 
25
25
  spec.add_development_dependency "bundler", "~> 2.0"
26
26
  spec.add_development_dependency "rake", "~> 13.0"
27
27
  spec.add_development_dependency "minitest", "~> 5.0"
28
28
  spec.add_development_dependency "simplecov", "~> 0.22"
29
29
 
30
- spec.add_runtime_dependency "ecma-re-validator", "~> 0.3"
31
30
  spec.add_runtime_dependency "hana", "~> 1.3"
32
31
  spec.add_runtime_dependency "regexp_parser", "~> 2.0"
33
32
  spec.add_runtime_dependency "simpleidn", "~> 0.2"
34
- spec.add_runtime_dependency "uri_template", "~> 0.7"
35
33
  end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+ module JSONSchemer
3
+ class EcmaRegexp
4
+ class Syntax < Regexp::Syntax::Base
5
+ # regexp_parser >= 2.3.0 uses syntax classes directly instead of instances
6
+ # :nocov:
7
+ SYNTAX = respond_to?(:implements) ? self : new
8
+ # :nocov:
9
+ SYNTAX.implements :anchor, Anchor::Extended
10
+ SYNTAX.implements :assertion, Assertion::All
11
+ # literal %i[number] to support regexp_parser < 2.2.0 (Backreference::Plain)
12
+ SYNTAX.implements :backref, %i[number] + Backreference::Name
13
+ # :meta_sequence, :bell, and :escape are not supported in ecma
14
+ SYNTAX.implements :escape, Escape::Basic + (Escape::Control - %i[meta_sequence]) + (Escape::ASCII - %i[bell escape]) + Escape::Unicode + Escape::Meta + Escape::Hex + Escape::Octal
15
+ SYNTAX.implements :property, UnicodeProperty::All
16
+ SYNTAX.implements :nonproperty, UnicodeProperty::All
17
+ # :comment is not supported in ecma
18
+ SYNTAX.implements :free_space, (FreeSpace::All - %i[comment])
19
+ SYNTAX.implements :group, Group::Basic + Group::Named + Group::Passive
20
+ SYNTAX.implements :literal, Literal::All
21
+ SYNTAX.implements :meta, Meta::Extended
22
+ SYNTAX.implements :quantifier, Quantifier::Greedy + Quantifier::Reluctant + Quantifier::Interval + Quantifier::IntervalReluctant
23
+ SYNTAX.implements :set, CharacterSet::Basic
24
+ SYNTAX.implements :type, CharacterType::Extended
25
+ end
26
+
27
+ RUBY_EQUIVALENTS = {
28
+ :anchor => {
29
+ :bol => '\A',
30
+ :eol => '\z'
31
+ },
32
+ :type => {
33
+ :space => '[\t\r\n\f\v\uFEFF\u2029\p{Zs}]',
34
+ :nonspace => '[^\t\r\n\f\v\uFEFF\u2029\p{Zs}]'
35
+ }
36
+ }.freeze
37
+
38
+ class << self
39
+ def ruby_equivalent(pattern)
40
+ Regexp::Scanner.scan(pattern).map do |type, token, text|
41
+ Syntax::SYNTAX.check!(*Syntax::SYNTAX.normalize(type, token))
42
+ RUBY_EQUIVALENTS.dig(type, token) || text
43
+ rescue Regexp::Syntax::NotImplementedError
44
+ raise InvalidEcmaRegexp, "invalid token #{text.inspect} (#{type}:#{token}) in #{pattern.inspect}"
45
+ end.join
46
+ rescue Regexp::Scanner::ScannerError
47
+ raise InvalidEcmaRegexp, "invalid pattern #{pattern.inspect}"
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+ module JSONSchemer
3
+ module Format
4
+ module URITemplate
5
+ # https://datatracker.ietf.org/doc/html/rfc6570
6
+ PCT_ENCODED = '%\h{2}' # pct-encoded = "%" HEXDIG HEXDIG
7
+ EXPLODE = '\*' # explode = "*"
8
+ MAX_LENGTH = '[1-9]\d{0,3}' # max-length = %x31-39 0*3DIGIT ; positive integer < 10000
9
+ PREFIX = ":#{MAX_LENGTH}" # prefix = ":" max-length
10
+ MODIFIER_LEVEL4 = "#{PREFIX}|#{EXPLODE}" # modifier-level4 = prefix / explode
11
+ VARCHAR = "(\\w|#{PCT_ENCODED})" # varchar = ALPHA / DIGIT / "_" / pct-encoded
12
+ VARNAME = "#{VARCHAR}(\\.?#{VARCHAR})*" # varname = varchar *( ["."] varchar )
13
+ VARSPEC = "#{VARNAME}(#{MODIFIER_LEVEL4})?" # varspec = varname [ modifier-level4 ]
14
+ VARIABLE_LIST = "#{VARSPEC}(,#{VARSPEC})*" # variable-list = varspec *( "," varspec )
15
+ OPERATOR = '[+#./;?&=,!@|]' # operator = op-level2 / op-level3 / op-reserve
16
+ # op-level2 = "+" / "#"
17
+ # op-level3 = "." / "/" / ";" / "?" / "&"
18
+ # op-reserve = "=" / "," / "!" / "@" / "|"
19
+ EXPRESSION = "{#{OPERATOR}?#{VARIABLE_LIST}}" # expression = "{" [ operator ] variable-list "}"
20
+ LITERALS = "[^\\x00-\\x20\\x7F\"%'<>\\\\^`{|}]|#{PCT_ENCODED}" # literals = %x21 / %x23-24 / %x26 / %x28-3B / %x3D / %x3F-5B
21
+ # / %x5D / %x5F / %x61-7A / %x7E / ucschar / iprivate
22
+ # / pct-encoded
23
+ # ; any Unicode character except: CTL, SP,
24
+ # ; DQUOTE, "'", "%" (aside from pct-encoded),
25
+ # ; "<", ">", "\", "^", "`", "{", "|", "}"
26
+ URI_TEMPLATE = "(#{LITERALS}|#{EXPRESSION})*" # URI-Template = *( literals / expression )
27
+ URI_TEMPLATE_REGEX = /\A#{URI_TEMPLATE}\z/
28
+
29
+ def valid_uri_template?(data)
30
+ URI_TEMPLATE_REGEX.match?(data)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -2,6 +2,7 @@
2
2
  module JSONSchemer
3
3
  module Format
4
4
  include Hostname
5
+ include URITemplate
5
6
 
6
7
  # this is no good
7
8
  EMAIL_REGEX = /\A[^@\s]+@([\p{L}\d-]+\.)+[\p{L}\d\-]{2,}\z/i.freeze
@@ -49,7 +50,7 @@ module JSONSchemer
49
50
  when 'relative-json-pointer'
50
51
  valid_relative_json_pointer?(data)
51
52
  when 'regex'
52
- EcmaReValidator.valid?(data)
53
+ valid_regex?(data)
53
54
  else
54
55
  raise UnknownFormat, format
55
56
  end
@@ -115,13 +116,6 @@ module JSONSchemer
115
116
  end.force_encoding(Encoding::US_ASCII)
116
117
  end
117
118
 
118
- def valid_uri_template?(data)
119
- URITemplate.new(data)
120
- true
121
- rescue URITemplate::Invalid
122
- false
123
- end
124
-
125
119
  def valid_json_pointer?(data)
126
120
  JSON_POINTER_REGEX.match?(data)
127
121
  end
@@ -129,5 +123,11 @@ module JSONSchemer
129
123
  def valid_relative_json_pointer?(data)
130
124
  RELATIVE_JSON_POINTER_REGEX.match?(data)
131
125
  end
126
+
127
+ def valid_regex?(data)
128
+ !!EcmaRegexp.ruby_equivalent(data)
129
+ rescue InvalidEcmaRegexp
130
+ false
131
+ end
132
132
  end
133
133
  end
@@ -4,40 +4,27 @@ module JSONSchemer
4
4
  class Base
5
5
  include Format
6
6
 
7
- Instance = Struct.new(:data, :data_pointer, :schema, :schema_pointer, :parent_uri, :before_property_validation, :after_property_validation) do
7
+ Instance = Struct.new(:data, :data_pointer, :schema, :schema_pointer, :base_uri, :before_property_validation, :after_property_validation) do
8
8
  def merge(
9
9
  data: self.data,
10
10
  data_pointer: self.data_pointer,
11
11
  schema: self.schema,
12
12
  schema_pointer: self.schema_pointer,
13
- parent_uri: self.parent_uri,
13
+ base_uri: self.base_uri,
14
14
  before_property_validation: self.before_property_validation,
15
15
  after_property_validation: self.after_property_validation
16
16
  )
17
- self.class.new(data, data_pointer, schema, schema_pointer, parent_uri, before_property_validation, after_property_validation)
17
+ self.class.new(data, data_pointer, schema, schema_pointer, base_uri, before_property_validation, after_property_validation)
18
18
  end
19
19
  end
20
20
 
21
21
  ID_KEYWORD = '$id'
22
22
  DEFAULT_REF_RESOLVER = proc { |uri| raise UnknownRef, uri.to_s }
23
23
  NET_HTTP_REF_RESOLVER = proc { |uri| JSON.parse(Net::HTTP.get(uri)) }
24
+ RUBY_REGEXP_RESOLVER = proc { |pattern| Regexp.new(pattern) }
25
+ ECMA_REGEXP_RESOLVER = proc { |pattern| Regexp.new(EcmaRegexp.ruby_equivalent(pattern)) }
24
26
  BOOLEANS = Set[true, false].freeze
25
27
 
26
- RUBY_REGEX_ANCHORS_TO_ECMA_262 = {
27
- :bos => 'A',
28
- :eos => 'z',
29
- :bol => '\A',
30
- :eol => '\z'
31
- }.freeze
32
-
33
- ECMA_262_REGEXP_RESOLVER = proc do |pattern|
34
- Regexp.new(
35
- Regexp::Scanner.scan(pattern).map do |type, token, text|
36
- type == :anchor ? RUBY_REGEX_ANCHORS_TO_ECMA_262.fetch(token, text) : text
37
- end.join
38
- )
39
- end
40
-
41
28
  INSERT_DEFAULT_PROPERTY = proc do |data, property, property_schema, _parent|
42
29
  if !data.key?(property) && property_schema.is_a?(Hash) && property_schema.key?('default')
43
30
  data[property] = property_schema.fetch('default').clone
@@ -45,10 +32,25 @@ module JSONSchemer
45
32
  end
46
33
 
47
34
  JSON_POINTER_TOKEN_ESCAPE_CHARS = { '~' => '~0', '/' => '~1' }
48
- JSON_POINTER_TOKEN_ESCAPE_REGEXP = Regexp.union(JSON_POINTER_TOKEN_ESCAPE_CHARS.keys)
35
+ JSON_POINTER_TOKEN_ESCAPE_REGEX = Regexp.union(JSON_POINTER_TOKEN_ESCAPE_CHARS.keys)
36
+
37
+ class << self
38
+ def draft_name
39
+ name.split('::').last.downcase
40
+ end
41
+
42
+ def meta_schema
43
+ @meta_schema ||= JSON.parse(Pathname.new(__dir__).join("#{draft_name}.json").read).freeze
44
+ end
45
+
46
+ def meta_schemer
47
+ @meta_schemer ||= JSONSchemer.schema(meta_schema)
48
+ end
49
+ end
49
50
 
50
51
  def initialize(
51
52
  schema,
53
+ base_uri: nil,
52
54
  format: true,
53
55
  insert_property_defaults: false,
54
56
  before_property_validation: nil,
@@ -56,10 +58,11 @@ module JSONSchemer
56
58
  formats: nil,
57
59
  keywords: nil,
58
60
  ref_resolver: DEFAULT_REF_RESOLVER,
59
- regexp_resolver: 'ecma'
61
+ regexp_resolver: 'ruby'
60
62
  )
61
63
  raise InvalidSymbolKey, 'schemas must use string keys' if schema.is_a?(Hash) && !schema.empty? && !schema.first.first.is_a?(String)
62
64
  @root = schema
65
+ @base_uri = base_uri
63
66
  @format = format
64
67
  @before_property_validation = [*before_property_validation]
65
68
  @before_property_validation.unshift(INSERT_DEFAULT_PROPERTY) if insert_property_defaults
@@ -69,24 +72,34 @@ module JSONSchemer
69
72
  @ref_resolver = ref_resolver == 'net/http' ? CachedResolver.new(&NET_HTTP_REF_RESOLVER) : ref_resolver
70
73
  @regexp_resolver = case regexp_resolver
71
74
  when 'ecma'
72
- CachedResolver.new(&ECMA_262_REGEXP_RESOLVER)
75
+ CachedResolver.new(&ECMA_REGEXP_RESOLVER)
73
76
  when 'ruby'
74
- CachedResolver.new(&Regexp.method(:new))
77
+ CachedResolver.new(&RUBY_REGEXP_RESOLVER)
75
78
  else
76
79
  regexp_resolver
77
80
  end
78
81
  end
79
82
 
80
83
  def valid?(data)
81
- valid_instance?(Instance.new(data, '', root, '', nil, @before_property_validation, @after_property_validation))
84
+ valid_instance?(Instance.new(data, '', root, '', @base_uri, @before_property_validation, @after_property_validation))
82
85
  end
83
86
 
84
87
  def validate(data)
85
- validate_instance(Instance.new(data, '', root, '', nil, @before_property_validation, @after_property_validation))
88
+ validate_instance(Instance.new(data, '', root, '', @base_uri, @before_property_validation, @after_property_validation))
89
+ end
90
+
91
+ def valid_schema?
92
+ self.class.meta_schemer.valid?(root)
93
+ end
94
+
95
+ def validate_schema
96
+ self.class.meta_schemer.validate(root)
86
97
  end
87
98
 
88
99
  protected
89
100
 
101
+ attr_reader :root
102
+
90
103
  def valid_instance?(instance)
91
104
  validate_instance(instance).none?
92
105
  end
@@ -116,13 +129,13 @@ module JSONSchemer
116
129
  ref = schema['$ref']
117
130
  id = schema[id_keyword]
118
131
 
119
- instance.parent_uri = join_uri(instance.parent_uri, id)
120
-
121
132
  if ref
122
133
  validate_ref(instance, ref, &block)
123
134
  return
124
135
  end
125
136
 
137
+ instance.base_uri = join_uri(instance.base_uri, id)
138
+
126
139
  if format? && custom_format?(format)
127
140
  validate_custom_format(instance, formats.fetch(format), &block)
128
141
  end
@@ -224,7 +237,7 @@ module JSONSchemer
224
237
 
225
238
  private
226
239
 
227
- attr_reader :root, :formats, :keywords, :ref_resolver, :regexp_resolver
240
+ attr_reader :formats, :keywords, :ref_resolver, :regexp_resolver
228
241
 
229
242
  def id_keyword
230
243
  ID_KEYWORD
@@ -242,10 +255,11 @@ module JSONSchemer
242
255
  !custom_format?(format) && supported_format?(format)
243
256
  end
244
257
 
245
- def child(schema)
258
+ def child(schema, base_uri:)
246
259
  JSONSchemer.schema(
247
260
  schema,
248
261
  default_schema_class: self.class,
262
+ base_uri: base_uri,
249
263
  format: format?,
250
264
  formats: formats,
251
265
  keywords: keywords,
@@ -302,50 +316,38 @@ module JSONSchemer
302
316
  end
303
317
 
304
318
  def validate_ref(instance, ref, &block)
305
- if ref.start_with?('#')
306
- schema_pointer = ref.slice(1..-1)
307
- if valid_json_pointer?(schema_pointer)
308
- ref_pointer = Hana::Pointer.new(URI.decode_www_form_component(schema_pointer))
309
- subinstance = instance.merge(
310
- schema: ref_pointer.eval(root),
311
- schema_pointer: schema_pointer,
312
- parent_uri: (pointer_uri(root, ref_pointer) || instance.parent_uri)
313
- )
314
- validate_instance(subinstance, &block)
315
- return
316
- end
317
- end
318
-
319
- ref_uri = join_uri(instance.parent_uri, ref)
319
+ ref_uri = join_uri(instance.base_uri, ref)
320
320
 
321
+ ref_uri_pointer = ''
321
322
  if valid_json_pointer?(ref_uri.fragment)
322
- ref_pointer = Hana::Pointer.new(URI.decode_www_form_component(ref_uri.fragment))
323
- ref_root = resolve_ref(ref_uri)
324
- ref_object = child(ref_root)
325
- subinstance = instance.merge(
326
- schema: ref_pointer.eval(ref_root),
327
- schema_pointer: ref_uri.fragment,
328
- parent_uri: (pointer_uri(ref_root, ref_pointer) || ref_uri)
329
- )
330
- ref_object.validate_instance(subinstance, &block)
331
- elsif id = ids[ref_uri.to_s]
332
- subinstance = instance.merge(
333
- schema: id.fetch(:schema),
334
- schema_pointer: id.fetch(:pointer),
335
- parent_uri: ref_uri
336
- )
337
- validate_instance(subinstance, &block)
323
+ ref_uri_pointer = ref_uri.fragment
324
+ ref_uri.fragment = nil
325
+ end
326
+
327
+ ref_object = if ids.key?(ref_uri) || ref_uri.to_s == @base_uri.to_s
328
+ self
338
329
  else
339
- ref_root = resolve_ref(ref_uri)
340
- ref_object = child(ref_root)
341
- id = ref_object.ids[ref_uri.to_s] || { schema: ref_root, pointer: '' }
342
- subinstance = instance.merge(
343
- schema: id.fetch(:schema),
344
- schema_pointer: id.fetch(:pointer),
345
- parent_uri: ref_uri
346
- )
347
- ref_object.validate_instance(subinstance, &block)
330
+ child(resolve_ref(ref_uri), base_uri: ref_uri)
331
+ end
332
+
333
+ ref_schema, ref_schema_pointer = ref_object.ids[ref_uri] || [ref_object.root, '']
334
+
335
+ ref_uri_pointer_parts = Hana::Pointer.parse(URI.decode_www_form_component(ref_uri_pointer))
336
+ schema, base_uri = ref_uri_pointer_parts.reduce([ref_schema, ref_uri]) do |(obj, uri), token|
337
+ if obj.is_a?(Array)
338
+ [obj.fetch(token.to_i), uri]
339
+ else
340
+ [obj.fetch(token), join_uri(uri, obj[id_keyword])]
341
+ end
348
342
  end
343
+
344
+ subinstance = instance.merge(
345
+ schema: schema,
346
+ schema_pointer: "#{ref_schema_pointer}#{ref_uri_pointer}",
347
+ base_uri: base_uri
348
+ )
349
+
350
+ ref_object.validate_instance(subinstance, &block)
349
351
  end
350
352
 
351
353
  def validate_custom_format(instance, custom_format)
@@ -622,12 +624,12 @@ module JSONSchemer
622
624
  end
623
625
 
624
626
  def escape_json_pointer_token(token)
625
- token.gsub(JSON_POINTER_TOKEN_ESCAPE_REGEXP, JSON_POINTER_TOKEN_ESCAPE_CHARS)
627
+ token.gsub(JSON_POINTER_TOKEN_ESCAPE_REGEX, JSON_POINTER_TOKEN_ESCAPE_CHARS)
626
628
  end
627
629
 
628
630
  def join_uri(a, b)
629
631
  b = URI.parse(b) if b
630
- if a && b && a.relative? && b.relative?
632
+ uri = if a && b && a.relative? && b.relative?
631
633
  b
632
634
  elsif a && b
633
635
  URI.join(a, b)
@@ -636,34 +638,26 @@ module JSONSchemer
636
638
  else
637
639
  a
638
640
  end
641
+ uri.fragment = nil if uri.is_a?(URI) && uri.fragment == ''
642
+ uri
639
643
  end
640
644
 
641
- def pointer_uri(schema, pointer)
642
- uri_parts = nil
643
- pointer.reduce(schema) do |obj, token|
644
- next obj.fetch(token.to_i) if obj.is_a?(Array)
645
- if obj_id = obj[id_keyword]
646
- uri_parts ||= []
647
- uri_parts << obj_id
648
- end
649
- obj.fetch(token)
650
- end
651
- uri_parts ? URI.join(*uri_parts) : nil
652
- end
653
-
654
- def resolve_ids(schema, ids = {}, parent_uri = nil, pointer = '')
645
+ def resolve_ids(schema, ids = {}, base_uri = @base_uri, pointer = '')
655
646
  if schema.is_a?(Array)
656
- schema.each_with_index { |subschema, index| resolve_ids(subschema, ids, parent_uri, "#{pointer}/#{index}") }
647
+ schema.each_with_index { |subschema, index| resolve_ids(subschema, ids, base_uri, "#{pointer}/#{index}") }
657
648
  elsif schema.is_a?(Hash)
658
- uri = join_uri(parent_uri, schema[id_keyword])
649
+ uri = join_uri(base_uri, schema[id_keyword])
659
650
  schema.each do |key, value|
660
- if key == id_keyword && uri != parent_uri
661
- ids[uri.to_s] = {
662
- schema: schema,
663
- pointer: pointer
664
- }
651
+ case key
652
+ when id_keyword
653
+ ids[uri] ||= [schema, pointer]
654
+ when 'items', 'allOf', 'anyOf', 'oneOf', 'additionalItems', 'contains', 'additionalProperties', 'propertyNames', 'if', 'then', 'else', 'not'
655
+ resolve_ids(value, ids, uri, "#{pointer}/#{key}")
656
+ when 'properties', 'patternProperties', 'definitions', 'dependencies'
657
+ value.each do |subkey, subvalue|
658
+ resolve_ids(subvalue, ids, uri, "#{pointer}/#{key}/#{subkey}")
659
+ end
665
660
  end
666
- resolve_ids(value, ids, uri, "#{pointer}/#{key}")
667
661
  end
668
662
  end
669
663
  ids
@@ -0,0 +1,149 @@
1
+ {
2
+ "id": "http://json-schema.org/draft-04/schema#",
3
+ "$schema": "http://json-schema.org/draft-04/schema#",
4
+ "description": "Core schema meta-schema",
5
+ "definitions": {
6
+ "schemaArray": {
7
+ "type": "array",
8
+ "minItems": 1,
9
+ "items": { "$ref": "#" }
10
+ },
11
+ "positiveInteger": {
12
+ "type": "integer",
13
+ "minimum": 0
14
+ },
15
+ "positiveIntegerDefault0": {
16
+ "allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ]
17
+ },
18
+ "simpleTypes": {
19
+ "enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ]
20
+ },
21
+ "stringArray": {
22
+ "type": "array",
23
+ "items": { "type": "string" },
24
+ "minItems": 1,
25
+ "uniqueItems": true
26
+ }
27
+ },
28
+ "type": "object",
29
+ "properties": {
30
+ "id": {
31
+ "type": "string"
32
+ },
33
+ "$schema": {
34
+ "type": "string"
35
+ },
36
+ "title": {
37
+ "type": "string"
38
+ },
39
+ "description": {
40
+ "type": "string"
41
+ },
42
+ "default": {},
43
+ "multipleOf": {
44
+ "type": "number",
45
+ "minimum": 0,
46
+ "exclusiveMinimum": true
47
+ },
48
+ "maximum": {
49
+ "type": "number"
50
+ },
51
+ "exclusiveMaximum": {
52
+ "type": "boolean",
53
+ "default": false
54
+ },
55
+ "minimum": {
56
+ "type": "number"
57
+ },
58
+ "exclusiveMinimum": {
59
+ "type": "boolean",
60
+ "default": false
61
+ },
62
+ "maxLength": { "$ref": "#/definitions/positiveInteger" },
63
+ "minLength": { "$ref": "#/definitions/positiveIntegerDefault0" },
64
+ "pattern": {
65
+ "type": "string",
66
+ "format": "regex"
67
+ },
68
+ "additionalItems": {
69
+ "anyOf": [
70
+ { "type": "boolean" },
71
+ { "$ref": "#" }
72
+ ],
73
+ "default": {}
74
+ },
75
+ "items": {
76
+ "anyOf": [
77
+ { "$ref": "#" },
78
+ { "$ref": "#/definitions/schemaArray" }
79
+ ],
80
+ "default": {}
81
+ },
82
+ "maxItems": { "$ref": "#/definitions/positiveInteger" },
83
+ "minItems": { "$ref": "#/definitions/positiveIntegerDefault0" },
84
+ "uniqueItems": {
85
+ "type": "boolean",
86
+ "default": false
87
+ },
88
+ "maxProperties": { "$ref": "#/definitions/positiveInteger" },
89
+ "minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" },
90
+ "required": { "$ref": "#/definitions/stringArray" },
91
+ "additionalProperties": {
92
+ "anyOf": [
93
+ { "type": "boolean" },
94
+ { "$ref": "#" }
95
+ ],
96
+ "default": {}
97
+ },
98
+ "definitions": {
99
+ "type": "object",
100
+ "additionalProperties": { "$ref": "#" },
101
+ "default": {}
102
+ },
103
+ "properties": {
104
+ "type": "object",
105
+ "additionalProperties": { "$ref": "#" },
106
+ "default": {}
107
+ },
108
+ "patternProperties": {
109
+ "type": "object",
110
+ "additionalProperties": { "$ref": "#" },
111
+ "default": {}
112
+ },
113
+ "dependencies": {
114
+ "type": "object",
115
+ "additionalProperties": {
116
+ "anyOf": [
117
+ { "$ref": "#" },
118
+ { "$ref": "#/definitions/stringArray" }
119
+ ]
120
+ }
121
+ },
122
+ "enum": {
123
+ "type": "array",
124
+ "minItems": 1,
125
+ "uniqueItems": true
126
+ },
127
+ "type": {
128
+ "anyOf": [
129
+ { "$ref": "#/definitions/simpleTypes" },
130
+ {
131
+ "type": "array",
132
+ "items": { "$ref": "#/definitions/simpleTypes" },
133
+ "minItems": 1,
134
+ "uniqueItems": true
135
+ }
136
+ ]
137
+ },
138
+ "format": { "type": "string" },
139
+ "allOf": { "$ref": "#/definitions/schemaArray" },
140
+ "anyOf": { "$ref": "#/definitions/schemaArray" },
141
+ "oneOf": { "$ref": "#/definitions/schemaArray" },
142
+ "not": { "$ref": "#" }
143
+ },
144
+ "dependencies": {
145
+ "exclusiveMaximum": [ "maximum" ],
146
+ "exclusiveMinimum": [ "minimum" ]
147
+ },
148
+ "default": {}
149
+ }
@@ -0,0 +1,155 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-06/schema#",
3
+ "$id": "http://json-schema.org/draft-06/schema#",
4
+ "title": "Core schema meta-schema",
5
+ "definitions": {
6
+ "schemaArray": {
7
+ "type": "array",
8
+ "minItems": 1,
9
+ "items": { "$ref": "#" }
10
+ },
11
+ "nonNegativeInteger": {
12
+ "type": "integer",
13
+ "minimum": 0
14
+ },
15
+ "nonNegativeIntegerDefault0": {
16
+ "allOf": [
17
+ { "$ref": "#/definitions/nonNegativeInteger" },
18
+ { "default": 0 }
19
+ ]
20
+ },
21
+ "simpleTypes": {
22
+ "enum": [
23
+ "array",
24
+ "boolean",
25
+ "integer",
26
+ "null",
27
+ "number",
28
+ "object",
29
+ "string"
30
+ ]
31
+ },
32
+ "stringArray": {
33
+ "type": "array",
34
+ "items": { "type": "string" },
35
+ "uniqueItems": true,
36
+ "default": []
37
+ }
38
+ },
39
+ "type": ["object", "boolean"],
40
+ "properties": {
41
+ "$id": {
42
+ "type": "string",
43
+ "format": "uri-reference"
44
+ },
45
+ "$schema": {
46
+ "type": "string",
47
+ "format": "uri"
48
+ },
49
+ "$ref": {
50
+ "type": "string",
51
+ "format": "uri-reference"
52
+ },
53
+ "title": {
54
+ "type": "string"
55
+ },
56
+ "description": {
57
+ "type": "string"
58
+ },
59
+ "default": {},
60
+ "examples": {
61
+ "type": "array",
62
+ "items": {}
63
+ },
64
+ "multipleOf": {
65
+ "type": "number",
66
+ "exclusiveMinimum": 0
67
+ },
68
+ "maximum": {
69
+ "type": "number"
70
+ },
71
+ "exclusiveMaximum": {
72
+ "type": "number"
73
+ },
74
+ "minimum": {
75
+ "type": "number"
76
+ },
77
+ "exclusiveMinimum": {
78
+ "type": "number"
79
+ },
80
+ "maxLength": { "$ref": "#/definitions/nonNegativeInteger" },
81
+ "minLength": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
82
+ "pattern": {
83
+ "type": "string",
84
+ "format": "regex"
85
+ },
86
+ "additionalItems": { "$ref": "#" },
87
+ "items": {
88
+ "anyOf": [
89
+ { "$ref": "#" },
90
+ { "$ref": "#/definitions/schemaArray" }
91
+ ],
92
+ "default": {}
93
+ },
94
+ "maxItems": { "$ref": "#/definitions/nonNegativeInteger" },
95
+ "minItems": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
96
+ "uniqueItems": {
97
+ "type": "boolean",
98
+ "default": false
99
+ },
100
+ "contains": { "$ref": "#" },
101
+ "maxProperties": { "$ref": "#/definitions/nonNegativeInteger" },
102
+ "minProperties": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
103
+ "required": { "$ref": "#/definitions/stringArray" },
104
+ "additionalProperties": { "$ref": "#" },
105
+ "definitions": {
106
+ "type": "object",
107
+ "additionalProperties": { "$ref": "#" },
108
+ "default": {}
109
+ },
110
+ "properties": {
111
+ "type": "object",
112
+ "additionalProperties": { "$ref": "#" },
113
+ "default": {}
114
+ },
115
+ "patternProperties": {
116
+ "type": "object",
117
+ "additionalProperties": { "$ref": "#" },
118
+ "propertyNames": { "format": "regex" },
119
+ "default": {}
120
+ },
121
+ "dependencies": {
122
+ "type": "object",
123
+ "additionalProperties": {
124
+ "anyOf": [
125
+ { "$ref": "#" },
126
+ { "$ref": "#/definitions/stringArray" }
127
+ ]
128
+ }
129
+ },
130
+ "propertyNames": { "$ref": "#" },
131
+ "const": {},
132
+ "enum": {
133
+ "type": "array",
134
+ "minItems": 1,
135
+ "uniqueItems": true
136
+ },
137
+ "type": {
138
+ "anyOf": [
139
+ { "$ref": "#/definitions/simpleTypes" },
140
+ {
141
+ "type": "array",
142
+ "items": { "$ref": "#/definitions/simpleTypes" },
143
+ "minItems": 1,
144
+ "uniqueItems": true
145
+ }
146
+ ]
147
+ },
148
+ "format": { "type": "string" },
149
+ "allOf": { "$ref": "#/definitions/schemaArray" },
150
+ "anyOf": { "$ref": "#/definitions/schemaArray" },
151
+ "oneOf": { "$ref": "#/definitions/schemaArray" },
152
+ "not": { "$ref": "#" }
153
+ },
154
+ "default": {}
155
+ }
@@ -0,0 +1,172 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "http://json-schema.org/draft-07/schema#",
4
+ "title": "Core schema meta-schema",
5
+ "definitions": {
6
+ "schemaArray": {
7
+ "type": "array",
8
+ "minItems": 1,
9
+ "items": { "$ref": "#" }
10
+ },
11
+ "nonNegativeInteger": {
12
+ "type": "integer",
13
+ "minimum": 0
14
+ },
15
+ "nonNegativeIntegerDefault0": {
16
+ "allOf": [
17
+ { "$ref": "#/definitions/nonNegativeInteger" },
18
+ { "default": 0 }
19
+ ]
20
+ },
21
+ "simpleTypes": {
22
+ "enum": [
23
+ "array",
24
+ "boolean",
25
+ "integer",
26
+ "null",
27
+ "number",
28
+ "object",
29
+ "string"
30
+ ]
31
+ },
32
+ "stringArray": {
33
+ "type": "array",
34
+ "items": { "type": "string" },
35
+ "uniqueItems": true,
36
+ "default": []
37
+ }
38
+ },
39
+ "type": ["object", "boolean"],
40
+ "properties": {
41
+ "$id": {
42
+ "type": "string",
43
+ "format": "uri-reference"
44
+ },
45
+ "$schema": {
46
+ "type": "string",
47
+ "format": "uri"
48
+ },
49
+ "$ref": {
50
+ "type": "string",
51
+ "format": "uri-reference"
52
+ },
53
+ "$comment": {
54
+ "type": "string"
55
+ },
56
+ "title": {
57
+ "type": "string"
58
+ },
59
+ "description": {
60
+ "type": "string"
61
+ },
62
+ "default": true,
63
+ "readOnly": {
64
+ "type": "boolean",
65
+ "default": false
66
+ },
67
+ "writeOnly": {
68
+ "type": "boolean",
69
+ "default": false
70
+ },
71
+ "examples": {
72
+ "type": "array",
73
+ "items": true
74
+ },
75
+ "multipleOf": {
76
+ "type": "number",
77
+ "exclusiveMinimum": 0
78
+ },
79
+ "maximum": {
80
+ "type": "number"
81
+ },
82
+ "exclusiveMaximum": {
83
+ "type": "number"
84
+ },
85
+ "minimum": {
86
+ "type": "number"
87
+ },
88
+ "exclusiveMinimum": {
89
+ "type": "number"
90
+ },
91
+ "maxLength": { "$ref": "#/definitions/nonNegativeInteger" },
92
+ "minLength": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
93
+ "pattern": {
94
+ "type": "string",
95
+ "format": "regex"
96
+ },
97
+ "additionalItems": { "$ref": "#" },
98
+ "items": {
99
+ "anyOf": [
100
+ { "$ref": "#" },
101
+ { "$ref": "#/definitions/schemaArray" }
102
+ ],
103
+ "default": true
104
+ },
105
+ "maxItems": { "$ref": "#/definitions/nonNegativeInteger" },
106
+ "minItems": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
107
+ "uniqueItems": {
108
+ "type": "boolean",
109
+ "default": false
110
+ },
111
+ "contains": { "$ref": "#" },
112
+ "maxProperties": { "$ref": "#/definitions/nonNegativeInteger" },
113
+ "minProperties": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
114
+ "required": { "$ref": "#/definitions/stringArray" },
115
+ "additionalProperties": { "$ref": "#" },
116
+ "definitions": {
117
+ "type": "object",
118
+ "additionalProperties": { "$ref": "#" },
119
+ "default": {}
120
+ },
121
+ "properties": {
122
+ "type": "object",
123
+ "additionalProperties": { "$ref": "#" },
124
+ "default": {}
125
+ },
126
+ "patternProperties": {
127
+ "type": "object",
128
+ "additionalProperties": { "$ref": "#" },
129
+ "propertyNames": { "format": "regex" },
130
+ "default": {}
131
+ },
132
+ "dependencies": {
133
+ "type": "object",
134
+ "additionalProperties": {
135
+ "anyOf": [
136
+ { "$ref": "#" },
137
+ { "$ref": "#/definitions/stringArray" }
138
+ ]
139
+ }
140
+ },
141
+ "propertyNames": { "$ref": "#" },
142
+ "const": true,
143
+ "enum": {
144
+ "type": "array",
145
+ "items": true,
146
+ "minItems": 1,
147
+ "uniqueItems": true
148
+ },
149
+ "type": {
150
+ "anyOf": [
151
+ { "$ref": "#/definitions/simpleTypes" },
152
+ {
153
+ "type": "array",
154
+ "items": { "$ref": "#/definitions/simpleTypes" },
155
+ "minItems": 1,
156
+ "uniqueItems": true
157
+ }
158
+ ]
159
+ },
160
+ "format": { "type": "string" },
161
+ "contentMediaType": { "type": "string" },
162
+ "contentEncoding": { "type": "string" },
163
+ "if": { "$ref": "#" },
164
+ "then": { "$ref": "#" },
165
+ "else": { "$ref": "#" },
166
+ "allOf": { "$ref": "#/definitions/schemaArray" },
167
+ "anyOf": { "$ref": "#/definitions/schemaArray" },
168
+ "oneOf": { "$ref": "#/definitions/schemaArray" },
169
+ "not": { "$ref": "#" }
170
+ },
171
+ "default": true
172
+ }
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module JSONSchemer
3
- VERSION = '0.2.25'
3
+ VERSION = '1.0.1'
4
4
  end
data/lib/json_schemer.rb CHANGED
@@ -9,17 +9,17 @@ require 'set'
9
9
  require 'time'
10
10
  require 'uri'
11
11
 
12
- require 'ecma-re-validator'
13
12
  require 'hana'
14
13
  require 'regexp_parser'
15
14
  require 'simpleidn'
16
- require 'uri_template'
17
15
 
18
16
  require 'json_schemer/version'
19
17
  require 'json_schemer/format/hostname'
18
+ require 'json_schemer/format/uri_template'
20
19
  require 'json_schemer/format'
21
20
  require 'json_schemer/errors'
22
21
  require 'json_schemer/cached_resolver'
22
+ require 'json_schemer/ecma_regexp'
23
23
  require 'json_schemer/schema/base'
24
24
  require 'json_schemer/schema/draft4'
25
25
  require 'json_schemer/schema/draft6'
@@ -33,7 +33,9 @@ module JSONSchemer
33
33
  class InvalidRegexpResolution < StandardError; end
34
34
  class InvalidFileURI < StandardError; end
35
35
  class InvalidSymbolKey < StandardError; end
36
+ class InvalidEcmaRegexp < StandardError; end
36
37
 
38
+ DEFAULT_SCHEMA_CLASS = Schema::Draft7
37
39
  SCHEMA_CLASS_BY_META_SCHEMA = {
38
40
  'http://json-schema.org/schema#' => Schema::Draft4, # Version-less $schema deprecated after Draft 4
39
41
  'http://json-schema.org/draft-04/schema#' => Schema::Draft4,
@@ -52,33 +54,38 @@ module JSONSchemer
52
54
  end
53
55
 
54
56
  class << self
55
- def schema(schema, default_schema_class: Schema::Draft7, **options)
57
+ def schema(schema, default_schema_class: DEFAULT_SCHEMA_CLASS, **options)
56
58
  case schema
57
59
  when String
58
60
  schema = JSON.parse(schema)
59
61
  when Pathname
60
- uri = URI.parse(File.join('file:', URI::DEFAULT_PARSER.escape(schema.realpath.to_s)))
61
- if options.key?(:ref_resolver)
62
- schema = FILE_URI_REF_RESOLVER.call(uri)
62
+ base_uri = URI.parse(File.join('file:', URI::DEFAULT_PARSER.escape(schema.realpath.to_s)))
63
+ options[:base_uri] = base_uri
64
+ schema = if options.key?(:ref_resolver)
65
+ FILE_URI_REF_RESOLVER.call(base_uri)
63
66
  else
64
67
  ref_resolver = CachedResolver.new(&FILE_URI_REF_RESOLVER)
65
- schema = ref_resolver.call(uri)
66
68
  options[:ref_resolver] = ref_resolver
69
+ ref_resolver.call(base_uri)
67
70
  end
68
- schema[draft_class(schema, default_schema_class)::ID_KEYWORD] ||= uri.to_s
69
71
  end
70
- draft_class(schema, default_schema_class).new(schema, **options)
71
- end
72
-
73
- private
74
72
 
75
- def draft_class(schema, default_schema_class)
76
- if schema.is_a?(Hash) && schema.key?('$schema')
73
+ schema_class = if schema.is_a?(Hash) && schema.key?('$schema')
77
74
  meta_schema = schema.fetch('$schema')
78
75
  SCHEMA_CLASS_BY_META_SCHEMA[meta_schema] || raise(UnsupportedMetaSchema, meta_schema)
79
76
  else
80
77
  default_schema_class
81
78
  end
79
+
80
+ schema_class.new(schema, **options)
81
+ end
82
+
83
+ def valid_schema?(schema, default_schema_class: DEFAULT_SCHEMA_CLASS)
84
+ schema(schema, default_schema_class: default_schema_class).valid_schema?
85
+ end
86
+
87
+ def validate_schema(schema, default_schema_class: DEFAULT_SCHEMA_CLASS)
88
+ schema(schema, default_schema_class: default_schema_class).validate_schema
82
89
  end
83
90
  end
84
91
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json_schemer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.25
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Harsha
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-26 00:00:00.000000000 Z
11
+ date: 2023-05-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,20 +66,6 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0.22'
69
- - !ruby/object:Gem::Dependency
70
- name: ecma-re-validator
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '0.3'
76
- type: :runtime
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '0.3'
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: hana
85
71
  requirement: !ruby/object:Gem::Requirement
@@ -122,20 +108,6 @@ dependencies:
122
108
  - - "~>"
123
109
  - !ruby/object:Gem::Version
124
110
  version: '0.2'
125
- - !ruby/object:Gem::Dependency
126
- name: uri_template
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - "~>"
130
- - !ruby/object:Gem::Version
131
- version: '0.7'
132
- type: :runtime
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - "~>"
137
- - !ruby/object:Gem::Version
138
- version: '0.7'
139
111
  description:
140
112
  email:
141
113
  - davishmcclurg@gmail.com
@@ -146,6 +118,7 @@ extra_rdoc_files: []
146
118
  files:
147
119
  - ".github/workflows/ci.yml"
148
120
  - ".gitignore"
121
+ - CHANGELOG.md
149
122
  - Gemfile
150
123
  - Gemfile.lock
151
124
  - LICENSE.txt
@@ -159,12 +132,17 @@ files:
159
132
  - json_schemer.gemspec
160
133
  - lib/json_schemer.rb
161
134
  - lib/json_schemer/cached_resolver.rb
135
+ - lib/json_schemer/ecma_regexp.rb
162
136
  - lib/json_schemer/errors.rb
163
137
  - lib/json_schemer/format.rb
164
138
  - lib/json_schemer/format/hostname.rb
139
+ - lib/json_schemer/format/uri_template.rb
165
140
  - lib/json_schemer/schema/base.rb
141
+ - lib/json_schemer/schema/draft4.json
166
142
  - lib/json_schemer/schema/draft4.rb
143
+ - lib/json_schemer/schema/draft6.json
167
144
  - lib/json_schemer/schema/draft6.rb
145
+ - lib/json_schemer/schema/draft7.json
168
146
  - lib/json_schemer/schema/draft7.rb
169
147
  - lib/json_schemer/version.rb
170
148
  homepage: https://github.com/davishmcclurg/json_schemer
@@ -179,7 +157,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
179
157
  requirements:
180
158
  - - ">="
181
159
  - !ruby/object:Gem::Version
182
- version: '2.4'
160
+ version: '2.5'
183
161
  required_rubygems_version: !ruby/object:Gem::Requirement
184
162
  requirements:
185
163
  - - ">="