json_schemer 2.1.1 → 2.4.0

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: 1981782f2342c7123beb0374680037bc11f3be72a8e4be0a213cfb7691643415
4
- data.tar.gz: e8b6c605ba1ce2a2751ac90167f53c27fad975140ab9a0e8328c2b04ce8fe732
3
+ metadata.gz: 04dbbf738ea9253437566fb50075ee7603fd0b536324181aebb0573c32c7f7bc
4
+ data.tar.gz: 29337d5892b33a2f74e435370986f059d7dd9762352bea610e7668dca3171e09
5
5
  SHA512:
6
- metadata.gz: 4d4c6e6c3660560a602b5610559efe37b5839f1142af6486e350bd207cad49e37a00f397d555878957b14951da95745092240bd14417e2ffd02826f053099952
7
- data.tar.gz: 8dc561414463ceeacf7bbd0be95be9c441a50919cdb839ff8366fa0268d96d91e4947985bd7bab406f3c163e913bf7ca923a38e22d777d2549af3329f91c14f2
6
+ metadata.gz: 90f1510bcc40ad9500904453dee34434b91ef45b8ab7d8be84dc728aae4d4c1a4556037f1ae8b48595198529973fe2d1e5c20a64e5aeb9871cd6fddd23636268
7
+ data.tar.gz: c7e8a861d8f763d5248d79d486d8b253b9f81e40952e896d53b7dad84bdd5197a70224008e79de5cf5b6e7a3e9a8e646bd8af4188ae6a87c4a7ac9011998f36f
@@ -6,8 +6,12 @@ jobs:
6
6
  fail-fast: false
7
7
  matrix:
8
8
  os: [ubuntu-latest, windows-latest, macos-latest]
9
- ruby: [2.5, 2.6, 2.7, 3.0, 3.1, 3.2, head, jruby, jruby-head, truffleruby, truffleruby-head]
9
+ ruby: [2.7, 3.0, 3.1, 3.2, 3.3, 3.4, head, jruby, jruby-head, truffleruby, truffleruby-head]
10
10
  exclude:
11
+ - os: ubuntu-latest
12
+ ruby: head
13
+ - os: macos-latest
14
+ ruby: head
11
15
  - os: windows-latest
12
16
  ruby: truffleruby
13
17
  - os: windows-latest
data/CHANGELOG.md CHANGED
@@ -1,5 +1,50 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.4.0] - 2025-02-01
4
+
5
+ ### Bug Fixes
6
+
7
+ - Store schema resource file URIs as strings to prevent conflicts: https://github.com/davishmcclurg/json_schemer/pull/189
8
+ - Require OpenAPI `discriminator` instances to be objects: https://github.com/davishmcclurg/json_schemer/pull/206
9
+ - Pass configuration options to subschemas: https://github.com/davishmcclurg/json_schemer/pull/208
10
+ - Check applicable instance types in OpenAPI `format` extensions: https://github.com/davishmcclurg/json_schemer/pull/209
11
+ - Use correct max values for OpenAPI `int32`/`int64` formats: https://github.com/davishmcclurg/json_schemer/commit/386c2a6fe089350c61775716643ef0600898060e
12
+
13
+ [2.4.0]: https://github.com/davishmcclurg/json_schemer/releases/tag/v2.4.0
14
+
15
+ ## [2.3.0] - 2024-05-30
16
+
17
+ ### Ruby Versions
18
+
19
+ - Ruby 2.5 and 2.6 are no longer supported.
20
+
21
+ ### Bug Fixes
22
+
23
+ - Remove `base64` runtime dependency: https://github.com/davishmcclurg/json_schemer/pull/182
24
+ - Relax `uuid` format validation: https://github.com/davishmcclurg/json_schemer/pull/183
25
+
26
+ [2.3.0]: https://github.com/davishmcclurg/json_schemer/releases/tag/v2.3.0
27
+
28
+ ## [2.2.0] - 2024-03-02
29
+
30
+ ### Bug Fixes
31
+
32
+ - Support symbol keys when accessing original instance: https://github.com/davishmcclurg/json_schemer/commit/d52c130e9967919c6cf1c9dbc3f0babfb8b01cf8
33
+ - Support custom keywords in nested schemas: https://github.com/davishmcclurg/json_schemer/commit/93c85a5006981347c7e9a4c11b73c6bdb65d8ba2
34
+ - Stringify instance location for custom keywords: https://github.com/davishmcclurg/json_schemer/commit/513c99130b9e7986b09881e7efd3fb7143744754
35
+ - Reduce unhelpful error output in `unevaluated` keywords: https://github.com/davishmcclurg/json_schemer/pull/164
36
+ - Handle parse errors during schema validation: https://github.com/davishmcclurg/json_schemer/pull/171
37
+ - Follow refs when finding default property values: https://github.com/davishmcclurg/json_schemer/pull/175
38
+
39
+ ### Features
40
+
41
+ - Global configuration with `Configuration` object: https://github.com/davishmcclurg/json_schemer/pull/170
42
+ - Symbol key property defaults with `insert_property_defaults: :symbol`: https://github.com/davishmcclurg/json_schemer/commit/a72473dc84199107ddedc8998950e5b82273232a
43
+ - Consistent schema type support for schema validation methods: https://github.com/davishmcclurg/json_schemer/commit/bbcd0cea20cbaa61cf2bdae5f53840861cae54b8
44
+ - Validation option support for schema validation methods: https://github.com/davishmcclurg/json_schemer/commit/2eeef77de522f127619b7d0faa51e0d7e40977ad
45
+
46
+ [2.2.0]: https://github.com/davishmcclurg/json_schemer/releases/tag/v2.2.0
47
+
3
48
  ## [2.1.1] - 2023-11-28
4
49
 
5
50
  ### Bug Fixes
data/Gemfile.lock CHANGED
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- json_schemer (2.1.1)
4
+ json_schemer (2.4.0)
5
+ bigdecimal
5
6
  hana (~> 1.3)
6
7
  regexp_parser (~> 2.0)
7
8
  simpleidn (~> 0.2)
@@ -9,35 +10,36 @@ PATH
9
10
  GEM
10
11
  remote: https://rubygems.org/
11
12
  specs:
12
- concurrent-ruby (1.2.2)
13
- docile (1.4.0)
13
+ base64 (0.2.0)
14
+ bigdecimal (3.1.9)
15
+ bigdecimal (3.1.9-java)
16
+ concurrent-ruby (1.3.5)
17
+ csv (3.3.2)
18
+ docile (1.4.1)
14
19
  hana (1.3.7)
15
- i18n (1.14.1)
20
+ i18n (1.14.6)
16
21
  concurrent-ruby (~> 1.0)
17
22
  i18n-debug (1.2.0)
18
23
  i18n (< 2)
19
- minitest (5.15.0)
20
- rake (13.0.6)
21
- regexp_parser (2.8.2)
24
+ minitest (5.25.4)
25
+ rake (13.2.1)
26
+ regexp_parser (2.10.0)
22
27
  simplecov (0.22.0)
23
28
  docile (~> 1.1)
24
29
  simplecov-html (~> 0.11)
25
30
  simplecov_json_formatter (~> 0.1)
26
- simplecov-html (0.12.3)
31
+ simplecov-html (0.13.1)
27
32
  simplecov_json_formatter (0.1.4)
28
- simpleidn (0.2.1)
29
- unf (~> 0.1.4)
30
- unf (0.1.4)
31
- unf_ext
32
- unf (0.1.4-java)
33
- unf_ext (0.0.9.1)
33
+ simpleidn (0.2.3)
34
34
 
35
35
  PLATFORMS
36
36
  java
37
37
  ruby
38
38
 
39
39
  DEPENDENCIES
40
- bundler (~> 2.0)
40
+ base64
41
+ bundler (~> 2.4.0)
42
+ csv
41
43
  i18n
42
44
  i18n-debug
43
45
  json_schemer!
@@ -46,4 +48,4 @@ DEPENDENCIES
46
48
  simplecov (~> 0.22)
47
49
 
48
50
  BUNDLED WITH
49
- 2.3.25
51
+ 2.4.22
data/README.md CHANGED
@@ -95,18 +95,6 @@ JSONSchemer.validate_schema({ '$id' => '#invalid' }).to_a
95
95
  # "type"=>"pattern",
96
96
  # "error"=>"string at `/$id` does not match pattern: ^[^#]*#?$"}]
97
97
 
98
- JSONSchemer.schema({ '$id' => 'valid' }).valid_schema?
99
- # => true
100
-
101
- JSONSchemer.schema({ '$id' => '#invalid' }).validate_schema.to_a
102
- # => [{"data"=>"#invalid",
103
- # "data_pointer"=>"/$id",
104
- # "schema"=>{"$ref"=>"#/$defs/uriReferenceString", "$comment"=>"Non-empty fragments not allowed.", "pattern"=>"^[^#]*#?$"},
105
- # "schema_pointer"=>"/properties/$id",
106
- # "root_schema"=>{...meta schema},
107
- # "type"=>"pattern",
108
- # "error"=>"string at `/$id` does not match pattern: ^[^#]*#?$"}]
109
-
110
98
  # subschemas
111
99
 
112
100
  schema = {
@@ -212,7 +200,8 @@ JSONSchemer.schema(
212
200
  },
213
201
 
214
202
  # insert default property values during validation
215
- # true/false
203
+ # string keys by default (use `:symbol` to insert symbol keys)
204
+ # true/false/:symbol
216
205
  # default: false
217
206
  insert_property_defaults: true,
218
207
 
@@ -256,6 +245,20 @@ JSONSchemer.schema(
256
245
  )
257
246
  ```
258
247
 
248
+ ## Global Configuration
249
+
250
+ Configuration options can be set globally by modifying `JSONSchemer.configuration`. Global options are applied to any new schemas at creation time (global configuration changes are not reflected in existing schemas). They can be overridden with the regular keyword arguments described [above](#options).
251
+
252
+ ```ruby
253
+ # configuration block
254
+ JSONSchemer.configure do |config|
255
+ config.regexp_resolver = 'ecma'
256
+ end
257
+
258
+ # configuration accessors
259
+ JSONSchemer.configuration.insert_property_defaults = true
260
+ ```
261
+
259
262
  ## Custom Error Messages
260
263
 
261
264
  Error messages can be customized using the `x-error` keyword and/or [I18n](https://github.com/ruby-i18n/i18n) translations. `x-error` takes precedence if both are defined.
@@ -495,7 +498,13 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
495
498
 
496
499
  ## Build Status
497
500
 
498
- ![Build Status](https://github.com/davishmcclurg/json_schemer/workflows/ci/badge.svg)
501
+ ![CI](https://github.com/davishmcclurg/json_schemer/actions/workflows/ci.yml/badge.svg)
502
+ ![JSON Schema Versions](https://img.shields.io/endpoint?url=https%3A%2F%2Fbowtie.report%2Fbadges%2Fruby-json_schemer%2Fsupported_versions.json)<br>
503
+ ![Draft 2020-12](https://img.shields.io/endpoint?url=https%3A%2F%2Fbowtie.report%2Fbadges%2Fruby-json_schemer%2Fcompliance%2Fdraft2020-12.json)
504
+ ![Draft 2019-09](https://img.shields.io/endpoint?url=https%3A%2F%2Fbowtie.report%2Fbadges%2Fruby-json_schemer%2Fcompliance%2Fdraft2019-09.json)
505
+ ![Draft 7](https://img.shields.io/endpoint?url=https%3A%2F%2Fbowtie.report%2Fbadges%2Fruby-json_schemer%2Fcompliance%2Fdraft7.json)
506
+ ![Draft 6](https://img.shields.io/endpoint?url=https%3A%2F%2Fbowtie.report%2Fbadges%2Fruby-json_schemer%2Fcompliance%2Fdraft6.json)
507
+ ![Draft 4](https://img.shields.io/endpoint?url=https%3A%2F%2Fbowtie.report%2Fbadges%2Fruby-json_schemer%2Fcompliance%2Fdraft4.json)
499
508
 
500
509
  ## Contributing
501
510
 
data/json_schemer.gemspec CHANGED
@@ -20,15 +20,18 @@ 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.5'
23
+ spec.required_ruby_version = '>= 2.7'
24
24
 
25
- spec.add_development_dependency "bundler", "~> 2.0"
25
+ spec.add_development_dependency "base64"
26
+ spec.add_development_dependency "bundler", "~> 2.4.0"
26
27
  spec.add_development_dependency "rake", "~> 13.0"
27
28
  spec.add_development_dependency "minitest", "~> 5.0"
28
29
  spec.add_development_dependency "simplecov", "~> 0.22"
30
+ spec.add_development_dependency "csv"
29
31
  spec.add_development_dependency "i18n"
30
32
  spec.add_development_dependency "i18n-debug"
31
33
 
34
+ spec.add_runtime_dependency "bigdecimal"
32
35
  spec.add_runtime_dependency "hana", "~> 1.3"
33
36
  spec.add_runtime_dependency "regexp_parser", "~> 2.0"
34
37
  spec.add_runtime_dependency "simpleidn", "~> 0.2"
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+ module JSONSchemer
3
+ Configuration = Struct.new(
4
+ :base_uri, :meta_schema, :vocabulary, :format, :formats, :content_encodings, :content_media_types, :keywords,
5
+ :before_property_validation, :after_property_validation, :insert_property_defaults, :property_default_resolver,
6
+ :ref_resolver, :regexp_resolver, :output_format, :resolve_enumerators, :access_mode,
7
+ keyword_init: true
8
+ ) do
9
+ def initialize(
10
+ base_uri: URI('json-schemer://schema'),
11
+ meta_schema: Draft202012::BASE_URI.to_s,
12
+ vocabulary: nil,
13
+ format: true,
14
+ formats: {},
15
+ content_encodings: {},
16
+ content_media_types: {},
17
+ keywords: {},
18
+ before_property_validation: [],
19
+ after_property_validation: [],
20
+ insert_property_defaults: false,
21
+ property_default_resolver: nil,
22
+ ref_resolver: proc { |uri| raise UnknownRef, uri.to_s },
23
+ regexp_resolver: 'ruby',
24
+ output_format: 'classic',
25
+ resolve_enumerators: false,
26
+ access_mode: nil
27
+ )
28
+ super
29
+ end
30
+ end
31
+ end
@@ -2,7 +2,7 @@
2
2
  module JSONSchemer
3
3
  module ContentEncoding
4
4
  BASE64 = proc do |instance|
5
- [true, Base64.strict_decode64(instance)]
5
+ [true, instance.unpack1("m0")]
6
6
  rescue
7
7
  [false, nil]
8
8
  end
@@ -300,7 +300,7 @@ module JSONSchemer
300
300
  end
301
301
 
302
302
  def false_schema_error(formatted_instance_location:, **)
303
- "object property at #{formatted_instance_location} is not defined and schema does not allow additional properties"
303
+ "object property at #{formatted_instance_location} is a disallowed additional property"
304
304
  end
305
305
 
306
306
  def parse
@@ -8,6 +8,10 @@ module JSONSchemer
8
8
  "array items at #{formatted_instance_location} do not match `unevaluatedItems` schema"
9
9
  end
10
10
 
11
+ def false_schema_error(formatted_instance_location:, **)
12
+ "array item at #{formatted_instance_location} is a disallowed unevaluated item"
13
+ end
14
+
11
15
  def parse
12
16
  subschema(value)
13
17
  end
@@ -18,7 +22,7 @@ module JSONSchemer
18
22
  unevaluated_items = instance.size.times.to_set
19
23
 
20
24
  context.adjacent_results.each_value do |adjacent_result|
21
- collect_unevaluated_items(adjacent_result, instance_location, unevaluated_items)
25
+ collect_unevaluated_items(adjacent_result, unevaluated_items)
22
26
  end
23
27
 
24
28
  nested = unevaluated_items.map do |index|
@@ -30,8 +34,7 @@ module JSONSchemer
30
34
 
31
35
  private
32
36
 
33
- def collect_unevaluated_items(result, instance_location, unevaluated_items)
34
- return unless result.valid && result.instance_location == instance_location
37
+ def collect_unevaluated_items(result, unevaluated_items)
35
38
  case result.source
36
39
  when Applicator::PrefixItems
37
40
  unevaluated_items.subtract(0..result.annotation)
@@ -41,7 +44,9 @@ module JSONSchemer
41
44
  unevaluated_items.subtract(result.annotation)
42
45
  end
43
46
  result.nested&.each do |subresult|
44
- collect_unevaluated_items(subresult, instance_location, unevaluated_items)
47
+ if subresult.valid && subresult.instance_location == result.instance_location
48
+ collect_unevaluated_items(subresult, unevaluated_items)
49
+ end
45
50
  end
46
51
  end
47
52
  end
@@ -51,6 +56,10 @@ module JSONSchemer
51
56
  "object properties at #{formatted_instance_location} do not match `unevaluatedProperties` schema"
52
57
  end
53
58
 
59
+ def false_schema_error(formatted_instance_location:, **)
60
+ "object property at #{formatted_instance_location} is a disallowed unevaluated property"
61
+ end
62
+
54
63
  def parse
55
64
  subschema(value)
56
65
  end
@@ -61,7 +70,7 @@ module JSONSchemer
61
70
  evaluated_keys = Set[]
62
71
 
63
72
  context.adjacent_results.each_value do |adjacent_result|
64
- collect_evaluated_keys(adjacent_result, instance_location, evaluated_keys)
73
+ collect_evaluated_keys(adjacent_result, evaluated_keys)
65
74
  end
66
75
 
67
76
  evaluated = instance.reject do |key, _value|
@@ -77,14 +86,15 @@ module JSONSchemer
77
86
 
78
87
  private
79
88
 
80
- def collect_evaluated_keys(result, instance_location, evaluated_keys)
81
- return unless result.valid && result.instance_location == instance_location
89
+ def collect_evaluated_keys(result, evaluated_keys)
82
90
  case result.source
83
91
  when Applicator::Properties, Applicator::PatternProperties, Applicator::AdditionalProperties, UnevaluatedProperties
84
92
  evaluated_keys.merge(result.annotation)
85
93
  end
86
94
  result.nested&.each do |subresult|
87
- collect_evaluated_keys(subresult, instance_location, evaluated_keys)
95
+ if subresult.valid && subresult.instance_location == result.instance_location
96
+ collect_evaluated_keys(subresult, evaluated_keys)
97
+ end
88
98
  end
89
99
  end
90
100
  end
@@ -4,6 +4,10 @@ module JSONSchemer
4
4
  module Vocab
5
5
  module Validation
6
6
  class Type < Keyword
7
+ def self.valid_integer?(instance)
8
+ instance.is_a?(Numeric) && (instance.is_a?(Integer) || instance.floor == instance)
9
+ end
10
+
7
11
  def error(formatted_instance_location:, **)
8
12
  case value
9
13
  when 'null'
@@ -45,7 +49,7 @@ module JSONSchemer
45
49
  when 'number'
46
50
  instance.is_a?(Numeric)
47
51
  when 'integer'
48
- instance.is_a?(Numeric) && (instance.is_a?(Integer) || instance.floor == instance)
52
+ self.class.valid_integer?(instance)
49
53
  when 'string'
50
54
  instance.is_a?(String)
51
55
  when 'array'
@@ -4,9 +4,8 @@ module JSONSchemer
4
4
  module Vocab
5
5
  module Validation
6
6
  class Type < Draft202012::Vocab::Validation::Type
7
- private
8
- def valid_type(type, instance)
9
- type == 'integer' ? instance.is_a?(Integer) : super
7
+ def self.valid_integer?(instance)
8
+ instance.is_a?(Integer)
10
9
  end
11
10
  end
12
11
 
@@ -74,10 +74,10 @@ module JSONSchemer
74
74
  IP_REGEX = /\A[\h:.]+\z/.freeze
75
75
  INVALID_QUERY_REGEX = /\s/.freeze
76
76
  IRI_ESCAPE_REGEX = /[^[:ascii:]]/
77
- UUID_REGEX = /\A\h{8}-\h{4}-\h{4}-[89AB]\h{3}-\h{12}\z/i
77
+ UUID_REGEX = /\A\h{8}-\h{4}-\h{4}-\h{4}-\h{12}\z/i
78
78
  NIL_UUID = '00000000-0000-0000-0000-000000000000'
79
- ASCII_8BIT_TO_PERCENT_ENCODED = 256.times.each_with_object({}) do |byte, out|
80
- out[-byte.chr] = -sprintf('%%%02X', byte)
79
+ BINARY_TO_PERCENT_ENCODED = 256.times.each_with_object({}) do |byte, out|
80
+ out[-byte.chr(Encoding::BINARY)] = -sprintf('%%%02X', byte)
81
81
  end.freeze
82
82
 
83
83
  class << self
@@ -88,10 +88,9 @@ module JSONSchemer
88
88
  include URITemplate
89
89
 
90
90
  def percent_encode(data, regexp)
91
- data = data.dup
92
- data.force_encoding(Encoding::ASCII_8BIT)
93
- data.gsub!(regexp, ASCII_8BIT_TO_PERCENT_ENCODED)
94
- data.force_encoding(Encoding::US_ASCII)
91
+ binary = data.b
92
+ binary.gsub!(regexp, BINARY_TO_PERCENT_ENCODED)
93
+ binary.force_encoding(data.encoding)
95
94
  end
96
95
 
97
96
  def valid_date_time?(data)
@@ -45,8 +45,11 @@ module JSONSchemer
45
45
  end
46
46
 
47
47
  def subschema(value, keyword = nil, **options)
48
+ options[:configuration] ||= schema.configuration
48
49
  options[:base_uri] ||= schema.base_uri
49
50
  options[:meta_schema] ||= schema.meta_schema
51
+ options[:ref_resolver] ||= schema.ref_resolver
52
+ options[:regexp_resolver] ||= schema.regexp_resolver
50
53
  Schema.new(value, self, root, keyword, **options)
51
54
  end
52
55
  end
@@ -8,16 +8,14 @@ module JSONSchemer
8
8
  case version
9
9
  when /\A3\.1\.\d+\z/
10
10
  @document_schema = JSONSchemer.openapi31_document
11
- json_schema_dialect = document.fetch('jsonSchemaDialect') { OpenAPI31::BASE_URI.to_s }
11
+ meta_schema = document.fetch('jsonSchemaDialect') { OpenAPI31::BASE_URI.to_s }
12
12
  when /\A3\.0\.\d+\z/
13
13
  @document_schema = JSONSchemer.openapi30_document
14
- json_schema_dialect = OpenAPI30::BASE_URI.to_s
14
+ meta_schema = OpenAPI30::BASE_URI.to_s
15
15
  else
16
16
  raise UnsupportedOpenAPIVersion, version
17
17
  end
18
18
 
19
- meta_schema = META_SCHEMAS_BY_BASE_URI_STR[json_schema_dialect] || raise(UnsupportedMetaSchema, json_schema_dialect)
20
-
21
19
  @schema = JSONSchemer.schema(@document, :meta_schema => meta_schema, **options)
22
20
  end
23
21
 
@@ -4,8 +4,10 @@ module JSONSchemer
4
4
  BASE_URI = URI('json-schemer://openapi30/schema')
5
5
  # https://spec.openapis.org/oas/v3.0.3#data-types
6
6
  FORMATS = OpenAPI31::FORMATS.merge(
7
- 'byte' => proc { |instance, _value| ContentEncoding::BASE64.call(instance).first },
8
- 'binary' => proc { |instance, _value| instance.is_a?(String) && instance.encoding == Encoding::ASCII_8BIT },
7
+ 'int32' => proc { |instance, _format| !Draft4::Vocab::Validation::Type.valid_integer?(instance) || instance.floor.bit_length < 32 },
8
+ 'int64' => proc { |instance, _format| !Draft4::Vocab::Validation::Type.valid_integer?(instance) || instance.floor.bit_length < 64 },
9
+ 'byte' => proc { |instance, _value| !instance.is_a?(String) || ContentEncoding::BASE64.call(instance).first },
10
+ 'binary' => proc { |instance, _value| !instance.is_a?(String) || instance.encoding == Encoding::BINARY },
9
11
  'date' => Format::DATE
10
12
  )
11
13
  SCHEMA = {
@@ -4,10 +4,10 @@ module JSONSchemer
4
4
  BASE_URI = URI('https://spec.openapis.org/oas/3.1/dialect/base')
5
5
  # https://spec.openapis.org/oas/v3.1.0#data-types
6
6
  FORMATS = {
7
- 'int32' => proc { |instance, _format| instance.is_a?(Integer) && instance.bit_length <= 32 },
8
- 'int64' => proc { |instance, _format| instance.is_a?(Integer) && instance.bit_length <= 64 },
9
- 'float' => proc { |instance, _format| instance.is_a?(Float) },
10
- 'double' => proc { |instance, _format| instance.is_a?(Float) },
7
+ 'int32' => proc { |instance, _format| !Draft202012::Vocab::Validation::Type.valid_integer?(instance) || instance.floor.bit_length < 32 },
8
+ 'int64' => proc { |instance, _format| !Draft202012::Vocab::Validation::Type.valid_integer?(instance) || instance.floor.bit_length < 64 },
9
+ 'float' => proc { |instance, _format| !instance.is_a?(Numeric) || instance.is_a?(Float) },
10
+ 'double' => proc { |instance, _format| !instance.is_a?(Numeric) || instance.is_a?(Float) },
11
11
  'password' => proc { |_instance, _format| true }
12
12
  }
13
13
  SCHEMA = {
@@ -100,7 +100,7 @@ module JSONSchemer
100
100
  end
101
101
 
102
102
  def validate(instance, instance_location, keyword_location, context)
103
- return result(instance, instance_location, keyword_location, true) unless instance.is_a?(Hash)
103
+ return result(instance, instance_location, keyword_location, false) unless instance.is_a?(Hash)
104
104
 
105
105
  property_name = value.fetch('propertyName')
106
106
 
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+ module JSONSchemer
3
+ class Resources
4
+ def initialize
5
+ @resources = {}
6
+ end
7
+
8
+ def [](uri)
9
+ @resources[uri.to_s]
10
+ end
11
+
12
+ def []=(uri, resource)
13
+ @resources[uri.to_s] = resource
14
+ end
15
+
16
+ def fetch(uri)
17
+ @resources.fetch(uri.to_s)
18
+ end
19
+
20
+ def key?(uri)
21
+ @resources.key?(uri.to_s)
22
+ end
23
+ end
24
+ end
@@ -191,6 +191,7 @@ module JSONSchemer
191
191
 
192
192
  def insert_property_defaults(context)
193
193
  instance_locations = {}
194
+ instance_locations.compare_by_identity
194
195
 
195
196
  results = [[self, true]]
196
197
  while (result, valid = results.pop)
@@ -201,8 +202,8 @@ module JSONSchemer
201
202
 
202
203
  if result.source.is_a?(Schema::PROPERTIES_KEYWORD_CLASS) && result.instance.is_a?(Hash)
203
204
  result.source.parsed.each do |property, schema|
204
- next if result.instance.key?(property) || !schema.parsed.key?('default')
205
- default = schema.parsed.fetch('default')
205
+ next if result.instance.key?(property)
206
+ next unless default = default_keyword_instance(schema)
206
207
  instance_location = Location.join(result.instance_location, property)
207
208
  keyword_location = Location.join(Location.join(result.keyword_location, property), default.keyword)
208
209
  default_result = default.validate(nil, instance_location, keyword_location, nil)
@@ -225,5 +226,17 @@ module JSONSchemer
225
226
 
226
227
  inserted
227
228
  end
229
+
230
+ private
231
+
232
+ def default_keyword_instance(schema)
233
+ schema.parsed.fetch('default') do
234
+ schema.parsed.find do |_keyword, keyword_instance|
235
+ next unless keyword_instance.respond_to?(:ref_schema)
236
+ next unless default = default_keyword_instance(keyword_instance.ref_schema)
237
+ break default
238
+ end
239
+ end
240
+ end
228
241
  end
229
242
  end
@@ -4,28 +4,27 @@ module JSONSchemer
4
4
  Context = Struct.new(:instance, :dynamic_scope, :adjacent_results, :short_circuit, :access_mode) do
5
5
  def original_instance(instance_location)
6
6
  Hana::Pointer.parse(Location.resolve(instance_location)).reduce(instance) do |obj, token|
7
- obj.fetch(obj.is_a?(Array) ? token.to_i : token)
7
+ if obj.is_a?(Array)
8
+ obj.fetch(token.to_i)
9
+ elsif !obj.key?(token) && obj.key?(token.to_sym)
10
+ obj.fetch(token.to_sym)
11
+ else
12
+ obj.fetch(token)
13
+ end
8
14
  end
9
15
  end
10
16
  end
11
17
 
18
+ extend Forwardable
12
19
  include Output
13
20
 
14
- DEFAULT_SCHEMA = Draft202012::BASE_URI.to_s.freeze
15
21
  SCHEMA_KEYWORD_CLASS = Draft202012::Vocab::Core::Schema
16
22
  VOCABULARY_KEYWORD_CLASS = Draft202012::Vocab::Core::Vocabulary
17
23
  ID_KEYWORD_CLASS = Draft202012::Vocab::Core::Id
18
24
  UNKNOWN_KEYWORD_CLASS = Draft202012::Vocab::Core::UnknownKeyword
19
25
  NOT_KEYWORD_CLASS = Draft202012::Vocab::Applicator::Not
20
26
  PROPERTIES_KEYWORD_CLASS = Draft202012::Vocab::Applicator::Properties
21
- DEFAULT_BASE_URI = URI('json-schemer://schema').freeze
22
- DEFAULT_FORMATS = {}.freeze
23
- DEFAULT_CONTENT_ENCODINGS = {}.freeze
24
- DEFAULT_CONTENT_MEDIA_TYPES = {}.freeze
25
- DEFAULT_KEYWORDS = {}.freeze
26
- DEFAULT_BEFORE_PROPERTY_VALIDATION = [].freeze
27
- DEFAULT_AFTER_PROPERTY_VALIDATION = [].freeze
28
- DEFAULT_REF_RESOLVER = proc { |uri| raise UnknownRef, uri.to_s }
27
+
29
28
  NET_HTTP_REF_RESOLVER = proc { |uri| JSON.parse(Net::HTTP.get(uri)) }
30
29
  RUBY_REGEXP_RESOLVER = proc { |pattern| Regexp.new(pattern) }
31
30
  ECMA_REGEXP_RESOLVER = proc { |pattern| Regexp.new(EcmaRegexp.ruby_equivalent(pattern)) }
@@ -40,33 +39,38 @@ module JSONSchemer
40
39
  false
41
40
  end
42
41
  end
42
+ SYMBOL_PROPERTY_DEFAULT_RESOLVER = proc do |instance, property, results_with_tree_validity|
43
+ DEFAULT_PROPERTY_DEFAULT_RESOLVER.call(instance, property.to_sym, results_with_tree_validity)
44
+ end
43
45
 
44
46
  attr_accessor :base_uri, :meta_schema, :keywords, :keyword_order
45
- attr_reader :value, :parent, :root, :parsed
46
- attr_reader :vocabulary, :format, :formats, :content_encodings, :content_media_types, :custom_keywords, :before_property_validation, :after_property_validation, :insert_property_defaults, :property_default_resolver
47
+ attr_reader :value, :parent, :root, :configuration, :parsed
48
+ def_delegators :@configuration, :vocabulary, :format, :formats, :content_encodings, :content_media_types, :before_property_validation, :after_property_validation, :insert_property_defaults
49
+ def_delegator :@configuration, :keywords, :custom_keywords
47
50
 
48
51
  def initialize(
49
52
  value,
50
53
  parent = nil,
51
54
  root = self,
52
55
  keyword = nil,
53
- base_uri: DEFAULT_BASE_URI,
54
- meta_schema: nil,
55
- vocabulary: nil,
56
- format: true,
57
- formats: DEFAULT_FORMATS,
58
- content_encodings: DEFAULT_CONTENT_ENCODINGS,
59
- content_media_types: DEFAULT_CONTENT_MEDIA_TYPES,
60
- keywords: DEFAULT_KEYWORDS,
61
- before_property_validation: DEFAULT_BEFORE_PROPERTY_VALIDATION,
62
- after_property_validation: DEFAULT_AFTER_PROPERTY_VALIDATION,
63
- insert_property_defaults: false,
64
- property_default_resolver: DEFAULT_PROPERTY_DEFAULT_RESOLVER,
65
- ref_resolver: DEFAULT_REF_RESOLVER,
66
- regexp_resolver: 'ruby',
67
- output_format: 'classic',
68
- resolve_enumerators: false,
69
- access_mode: nil
56
+ configuration: JSONSchemer.configuration,
57
+ base_uri: configuration.base_uri,
58
+ meta_schema: configuration.meta_schema,
59
+ vocabulary: configuration.vocabulary,
60
+ format: configuration.format,
61
+ formats: configuration.formats,
62
+ content_encodings: configuration.content_encodings,
63
+ content_media_types: configuration.content_media_types,
64
+ keywords: configuration.keywords,
65
+ before_property_validation: configuration.before_property_validation,
66
+ after_property_validation: configuration.after_property_validation,
67
+ insert_property_defaults: configuration.insert_property_defaults,
68
+ property_default_resolver: configuration.property_default_resolver,
69
+ ref_resolver: configuration.ref_resolver,
70
+ regexp_resolver: configuration.regexp_resolver,
71
+ output_format: configuration.output_format,
72
+ resolve_enumerators: configuration.resolve_enumerators,
73
+ access_mode: configuration.access_mode
70
74
  )
71
75
  @value = deep_stringify_keys(value)
72
76
  @parent = parent
@@ -75,21 +79,25 @@ module JSONSchemer
75
79
  @schema = self
76
80
  @base_uri = base_uri
77
81
  @meta_schema = meta_schema
78
- @vocabulary = vocabulary
79
- @format = format
80
- @formats = formats
81
- @content_encodings = content_encodings
82
- @content_media_types = content_media_types
83
- @custom_keywords = keywords
84
- @before_property_validation = Array(before_property_validation)
85
- @after_property_validation = Array(after_property_validation)
86
- @insert_property_defaults = insert_property_defaults
87
- @property_default_resolver = property_default_resolver
88
- @original_ref_resolver = ref_resolver
89
- @original_regexp_resolver = regexp_resolver
90
- @output_format = output_format
91
- @resolve_enumerators = resolve_enumerators
92
- @access_mode = access_mode
82
+ @configuration = Configuration.new(
83
+ :base_uri => base_uri,
84
+ :meta_schema => meta_schema,
85
+ :vocabulary => vocabulary,
86
+ :format => format,
87
+ :formats => formats,
88
+ :content_encodings => content_encodings,
89
+ :content_media_types => content_media_types,
90
+ :keywords => keywords,
91
+ :before_property_validation => Array(before_property_validation),
92
+ :after_property_validation => Array(after_property_validation),
93
+ :insert_property_defaults => insert_property_defaults,
94
+ :property_default_resolver => property_default_resolver,
95
+ :ref_resolver => ref_resolver,
96
+ :regexp_resolver => regexp_resolver,
97
+ :output_format => output_format,
98
+ :resolve_enumerators => resolve_enumerators,
99
+ :access_mode => access_mode
100
+ )
93
101
  @parsed = parse
94
102
  end
95
103
 
@@ -97,7 +105,7 @@ module JSONSchemer
97
105
  validate(instance, :output_format => 'flag', **options).fetch('valid')
98
106
  end
99
107
 
100
- def validate(instance, output_format: @output_format, resolve_enumerators: @resolve_enumerators, access_mode: @access_mode)
108
+ def validate(instance, output_format: @configuration.output_format, resolve_enumerators: @configuration.resolve_enumerators, access_mode: @configuration.access_mode)
101
109
  instance_location = Location.root
102
110
  context = Context.new(instance, [], nil, (!insert_property_defaults && output_format == 'flag'), access_mode)
103
111
  result = validate_instance(deep_stringify_keys(instance), instance_location, root_keyword_location, context)
@@ -109,12 +117,12 @@ module JSONSchemer
109
117
  output
110
118
  end
111
119
 
112
- def valid_schema?
113
- meta_schema.valid?(value)
120
+ def valid_schema?(**options)
121
+ meta_schema.valid?(value, **options)
114
122
  end
115
123
 
116
- def validate_schema
117
- meta_schema.validate(value)
124
+ def validate_schema(**options)
125
+ meta_schema.validate(value, **options)
118
126
  end
119
127
 
120
128
  def ref(value)
@@ -142,10 +150,11 @@ module JSONSchemer
142
150
  adjacent_results[keyword_instance.class] = keyword_result
143
151
  end
144
152
 
145
- if custom_keywords.any?
146
- custom_keywords.each do |custom_keyword, callable|
153
+ if root.custom_keywords.any?
154
+ resolved_instance_location = Location.resolve(instance_location)
155
+ root.custom_keywords.each do |custom_keyword, callable|
147
156
  if value.key?(custom_keyword)
148
- [*callable.call(instance, value, instance_location)].each do |custom_keyword_result|
157
+ [*callable.call(instance, value, resolved_instance_location)].each do |custom_keyword_result|
149
158
  custom_keyword_valid = custom_keyword_result == true
150
159
  valid &&= custom_keyword_valid
151
160
  type = custom_keyword_result.is_a?(String) ? custom_keyword_result : custom_keyword
@@ -184,16 +193,9 @@ module JSONSchemer
184
193
  uri.fragment = nil
185
194
  remote_schema = JSONSchemer.schema(
186
195
  ref_resolver.call(uri) || raise(InvalidRefResolution, uri.to_s),
196
+ :configuration => configuration,
187
197
  :base_uri => uri,
188
198
  :meta_schema => meta_schema,
189
- :format => format,
190
- :formats => formats,
191
- :content_encodings => content_encodings,
192
- :content_media_types => content_media_types,
193
- :keywords => custom_keywords,
194
- :before_property_validation => before_property_validation,
195
- :after_property_validation => after_property_validation,
196
- :property_default_resolver => property_default_resolver,
197
199
  :ref_resolver => ref_resolver,
198
200
  :regexp_resolver => regexp_resolver
199
201
  )
@@ -331,7 +333,7 @@ module JSONSchemer
331
333
  end
332
334
 
333
335
  def resources
334
- @resources ||= { :lexical => {}, :dynamic => {} }
336
+ @resources ||= { :lexical => Resources.new, :dynamic => Resources.new }
335
337
  end
336
338
 
337
339
  def error(formatted_instance_location:, **options)
@@ -342,6 +344,21 @@ module JSONSchemer
342
344
  end
343
345
  end
344
346
 
347
+ def ref_resolver
348
+ @ref_resolver ||= @configuration.ref_resolver == 'net/http' ? CachedResolver.new(&NET_HTTP_REF_RESOLVER) : @configuration.ref_resolver
349
+ end
350
+
351
+ def regexp_resolver
352
+ @regexp_resolver ||= case @configuration.regexp_resolver
353
+ when 'ecma'
354
+ CachedResolver.new(&ECMA_REGEXP_RESOLVER)
355
+ when 'ruby'
356
+ CachedResolver.new(&RUBY_REGEXP_RESOLVER)
357
+ else
358
+ @configuration.regexp_resolver
359
+ end
360
+ end
361
+
345
362
  def inspect
346
363
  "#<#{self.class.name} @value=#{@value.inspect} @parent=#{@parent.inspect} @keyword=#{@keyword.inspect}>"
347
364
  end
@@ -353,8 +370,8 @@ module JSONSchemer
353
370
 
354
371
  if value.is_a?(Hash) && value.key?('$schema')
355
372
  @parsed['$schema'] = SCHEMA_KEYWORD_CLASS.new(value.fetch('$schema'), self, '$schema')
356
- elsif root == self && !meta_schema
357
- SCHEMA_KEYWORD_CLASS.new(DEFAULT_SCHEMA, self, '$schema')
373
+ elsif meta_schema.is_a?(String)
374
+ SCHEMA_KEYWORD_CLASS.new(meta_schema, self, '$schema')
358
375
  end
359
376
 
360
377
  if value.is_a?(Hash) && value.key?('$vocabulary')
@@ -394,18 +411,11 @@ module JSONSchemer
394
411
  @root_keyword_location ||= Location.root
395
412
  end
396
413
 
397
- def ref_resolver
398
- @ref_resolver ||= @original_ref_resolver == 'net/http' ? CachedResolver.new(&NET_HTTP_REF_RESOLVER) : @original_ref_resolver
399
- end
400
-
401
- def regexp_resolver
402
- @regexp_resolver ||= case @original_regexp_resolver
403
- when 'ecma'
404
- CachedResolver.new(&ECMA_REGEXP_RESOLVER)
405
- when 'ruby'
406
- CachedResolver.new(&RUBY_REGEXP_RESOLVER)
414
+ def property_default_resolver
415
+ @property_default_resolver ||= if @configuration.property_default_resolver
416
+ @configuration.property_default_resolver
407
417
  else
408
- @original_regexp_resolver
418
+ insert_property_defaults == :symbol ? SYMBOL_PROPERTY_DEFAULT_RESOLVER : DEFAULT_PROPERTY_DEFAULT_RESOLVER
409
419
  end
410
420
  end
411
421
 
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module JSONSchemer
3
- VERSION = '2.1.1'
3
+ VERSION = '2.4.0'
4
4
  end
data/lib/json_schemer.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
- require 'base64'
3
2
  require 'bigdecimal'
3
+ require 'forwardable'
4
4
  require 'ipaddr'
5
5
  require 'json'
6
6
  require 'net/http'
@@ -59,10 +59,11 @@ require 'json_schemer/openapi30/meta'
59
59
  require 'json_schemer/openapi30/vocab/base'
60
60
  require 'json_schemer/openapi30/vocab'
61
61
  require 'json_schemer/openapi'
62
+ require 'json_schemer/configuration'
63
+ require 'json_schemer/resources'
62
64
  require 'json_schemer/schema'
63
65
 
64
66
  module JSONSchemer
65
- class UnsupportedMetaSchema < StandardError; end
66
67
  class UnsupportedOpenAPIVersion < StandardError; end
67
68
  class UnknownRef < StandardError; end
68
69
  class UnknownFormat < StandardError; end
@@ -104,42 +105,32 @@ module JSONSchemer
104
105
 
105
106
  WINDOWS_URI_PATH_REGEX = /\A\/[a-z]:/i
106
107
 
108
+ # :nocov:
109
+ URI_PARSER = URI.const_defined?(:RFC2396_PARSER) ? URI::RFC2396_PARSER : URI::DEFAULT_PARSER
110
+ # :nocov:
111
+
107
112
  FILE_URI_REF_RESOLVER = proc do |uri|
108
113
  raise InvalidFileURI, 'must use `file` scheme' unless uri.scheme == 'file'
109
114
  raise InvalidFileURI, 'cannot have a host (use `file:///`)' if uri.host && !uri.host.empty?
110
115
  path = uri.path
111
116
  path = path[1..-1] if path.match?(WINDOWS_URI_PATH_REGEX)
112
- JSON.parse(File.read(URI::DEFAULT_PARSER.unescape(path)))
117
+ JSON.parse(File.read(URI_PARSER.unescape(path)))
113
118
  end
114
119
 
115
120
  class << self
116
- def schema(schema, meta_schema: draft202012, **options)
117
- case schema
118
- when String
119
- schema = JSON.parse(schema)
120
- when Pathname
121
- base_uri = URI.parse(File.join('file:', URI::DEFAULT_PARSER.escape(schema.realpath.to_s)))
122
- options[:base_uri] = base_uri
123
- schema = if options.key?(:ref_resolver)
124
- FILE_URI_REF_RESOLVER.call(base_uri)
125
- else
126
- ref_resolver = CachedResolver.new(&FILE_URI_REF_RESOLVER)
127
- options[:ref_resolver] = ref_resolver
128
- ref_resolver.call(base_uri)
129
- end
130
- end
131
- unless meta_schema.is_a?(Schema)
132
- meta_schema = META_SCHEMAS_BY_BASE_URI_STR[meta_schema] || raise(UnsupportedMetaSchema, meta_schema)
133
- end
134
- Schema.new(schema, :meta_schema => meta_schema, **options)
121
+ def schema(schema, **options)
122
+ schema = resolve(schema, options)
123
+ Schema.new(schema, **options)
135
124
  end
136
125
 
137
126
  def valid_schema?(schema, **options)
138
- schema(schema, **options).valid_schema?
127
+ schema = resolve(schema, options)
128
+ meta_schema(schema, options).valid?(schema, **options.slice(:output_format, :resolve_enumerators, :access_mode))
139
129
  end
140
130
 
141
131
  def validate_schema(schema, **options)
142
- schema(schema, **options).validate_schema
132
+ schema = resolve(schema, options)
133
+ meta_schema(schema, options).validate(schema, **options.slice(:output_format, :resolve_enumerators, :access_mode))
143
134
  end
144
135
 
145
136
  def draft202012
@@ -245,6 +236,44 @@ module JSONSchemer
245
236
  def openapi(document, **options)
246
237
  OpenAPI.new(document, **options)
247
238
  end
239
+
240
+ def configuration
241
+ @configuration ||= Configuration.new
242
+ end
243
+
244
+ def configure
245
+ yield configuration
246
+ end
247
+
248
+ private
249
+
250
+ def resolve(schema, options)
251
+ case schema
252
+ when String
253
+ JSON.parse(schema)
254
+ when Pathname
255
+ base_uri = URI.parse(File.join('file:', URI_PARSER.escape(schema.realpath.to_s)))
256
+ options[:base_uri] = base_uri
257
+ if options.key?(:ref_resolver)
258
+ FILE_URI_REF_RESOLVER.call(base_uri)
259
+ else
260
+ ref_resolver = CachedResolver.new(&FILE_URI_REF_RESOLVER)
261
+ options[:ref_resolver] = ref_resolver
262
+ ref_resolver.call(base_uri)
263
+ end
264
+ else
265
+ schema
266
+ end
267
+ end
268
+
269
+ def meta_schema(schema, options)
270
+ parseable_schema = {}
271
+ if schema.is_a?(Hash)
272
+ meta_schema = schema['$schema'] || schema[:'$schema']
273
+ parseable_schema['$schema'] = meta_schema if meta_schema.is_a?(String)
274
+ end
275
+ schema(parseable_schema, **options).meta_schema
276
+ end
248
277
  end
249
278
 
250
279
  META_SCHEMA_CALLABLES_BY_BASE_URI_STR = {
metadata CHANGED
@@ -1,29 +1,42 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json_schemer
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Harsha
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2023-11-28 00:00:00.000000000 Z
10
+ date: 2025-02-02 00:00:00.000000000 Z
12
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: base64
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :development
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
13
26
  - !ruby/object:Gem::Dependency
14
27
  name: bundler
15
28
  requirement: !ruby/object:Gem::Requirement
16
29
  requirements:
17
30
  - - "~>"
18
31
  - !ruby/object:Gem::Version
19
- version: '2.0'
32
+ version: 2.4.0
20
33
  type: :development
21
34
  prerelease: false
22
35
  version_requirements: !ruby/object:Gem::Requirement
23
36
  requirements:
24
37
  - - "~>"
25
38
  - !ruby/object:Gem::Version
26
- version: '2.0'
39
+ version: 2.4.0
27
40
  - !ruby/object:Gem::Dependency
28
41
  name: rake
29
42
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +79,20 @@ dependencies:
66
79
  - - "~>"
67
80
  - !ruby/object:Gem::Version
68
81
  version: '0.22'
82
+ - !ruby/object:Gem::Dependency
83
+ name: csv
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
69
96
  - !ruby/object:Gem::Dependency
70
97
  name: i18n
71
98
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +121,20 @@ dependencies:
94
121
  - - ">="
95
122
  - !ruby/object:Gem::Version
96
123
  version: '0'
124
+ - !ruby/object:Gem::Dependency
125
+ name: bigdecimal
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ type: :runtime
132
+ prerelease: false
133
+ version_requirements: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
97
138
  - !ruby/object:Gem::Dependency
98
139
  name: hana
99
140
  requirement: !ruby/object:Gem::Requirement
@@ -136,7 +177,6 @@ dependencies:
136
177
  - - "~>"
137
178
  - !ruby/object:Gem::Version
138
179
  version: '0.2'
139
- description:
140
180
  email:
141
181
  - davishmcclurg@gmail.com
142
182
  executables:
@@ -160,6 +200,7 @@ files:
160
200
  - json_schemer.gemspec
161
201
  - lib/json_schemer.rb
162
202
  - lib/json_schemer/cached_resolver.rb
203
+ - lib/json_schemer/configuration.rb
163
204
  - lib/json_schemer/content.rb
164
205
  - lib/json_schemer/draft201909/meta.rb
165
206
  - lib/json_schemer/draft201909/vocab.rb
@@ -203,6 +244,7 @@ files:
203
244
  - lib/json_schemer/openapi31/vocab.rb
204
245
  - lib/json_schemer/openapi31/vocab/base.rb
205
246
  - lib/json_schemer/output.rb
247
+ - lib/json_schemer/resources.rb
206
248
  - lib/json_schemer/result.rb
207
249
  - lib/json_schemer/schema.rb
208
250
  - lib/json_schemer/version.rb
@@ -210,7 +252,6 @@ homepage: https://github.com/davishmcclurg/json_schemer
210
252
  licenses:
211
253
  - MIT
212
254
  metadata: {}
213
- post_install_message:
214
255
  rdoc_options: []
215
256
  require_paths:
216
257
  - lib
@@ -218,15 +259,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
218
259
  requirements:
219
260
  - - ">="
220
261
  - !ruby/object:Gem::Version
221
- version: '2.5'
262
+ version: '2.7'
222
263
  required_rubygems_version: !ruby/object:Gem::Requirement
223
264
  requirements:
224
265
  - - ">="
225
266
  - !ruby/object:Gem::Version
226
267
  version: '0'
227
268
  requirements: []
228
- rubygems_version: 3.4.10
229
- signing_key:
269
+ rubygems_version: 3.6.2
230
270
  specification_version: 4
231
271
  summary: JSON Schema validator. Supports drafts 4, 6, 7, 2019-09, 2020-12, OpenAPI
232
272
  3.0, and OpenAPI 3.1.