json-schema 2.8.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +66 -9
  3. data/lib/json-schema/attributes/const.rb +15 -0
  4. data/lib/json-schema/attributes/dependencies.rb +0 -6
  5. data/lib/json-schema/attributes/dependencies_v4.rb +11 -0
  6. data/lib/json-schema/attributes/divisibleby.rb +1 -1
  7. data/lib/json-schema/attributes/formats/custom.rb +1 -1
  8. data/lib/json-schema/attributes/formats/date.rb +1 -1
  9. data/lib/json-schema/attributes/formats/date_time.rb +1 -1
  10. data/lib/json-schema/attributes/formats/date_time_v4.rb +1 -1
  11. data/lib/json-schema/attributes/formats/ip.rb +1 -1
  12. data/lib/json-schema/attributes/formats/time.rb +1 -1
  13. data/lib/json-schema/attributes/formats/uri.rb +1 -1
  14. data/lib/json-schema/attributes/limit.rb +0 -127
  15. data/lib/json-schema/attributes/limits/items.rb +15 -0
  16. data/lib/json-schema/attributes/limits/length.rb +15 -0
  17. data/lib/json-schema/attributes/limits/max_items.rb +15 -0
  18. data/lib/json-schema/attributes/limits/max_length.rb +15 -0
  19. data/lib/json-schema/attributes/limits/max_properties.rb +15 -0
  20. data/lib/json-schema/attributes/limits/maximum.rb +15 -0
  21. data/lib/json-schema/attributes/limits/maximum_inclusive.rb +11 -0
  22. data/lib/json-schema/attributes/limits/min_items.rb +15 -0
  23. data/lib/json-schema/attributes/limits/min_length.rb +15 -0
  24. data/lib/json-schema/attributes/limits/min_properties.rb +15 -0
  25. data/lib/json-schema/attributes/limits/minimum.rb +15 -0
  26. data/lib/json-schema/attributes/limits/minimum_inclusive.rb +11 -0
  27. data/lib/json-schema/attributes/limits/numeric.rb +16 -0
  28. data/lib/json-schema/attributes/limits/properties.rb +15 -0
  29. data/lib/json-schema/attributes/properties.rb +0 -8
  30. data/lib/json-schema/attributes/properties_v4.rb +13 -0
  31. data/lib/json-schema/schema/reader.rb +1 -1
  32. data/lib/json-schema/validator.rb +27 -33
  33. data/lib/json-schema/validators/draft6.rb +3 -2
  34. data/lib/json-schema.rb +1 -2
  35. data/resources/draft-06.json +34 -34
  36. metadata +27 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 598f5a11313e53a8a719936d8bbe08bddb6d07b3
4
- data.tar.gz: d9a1cde316718f0fdfd042f737bcb3d1b637d313
2
+ SHA256:
3
+ metadata.gz: ab17ffc9133c3115ad9bb2f4b37338ee71d1994bf62849e7557b7e41a9d1d8e9
4
+ data.tar.gz: 3c44c431d8997fa255613bd6235fdd82b3c7c15ecc9e1077a1d41ff33b31c69b
5
5
  SHA512:
6
- metadata.gz: e28327d9e15a145572c347c2124a9645a4e303cbad1641dde72dad47536f2071eb0fcc9628b439bb24d6f109cf1fd146d8cba2728236d2a88717a29db20fe875
7
- data.tar.gz: b414849b2f9e74d7bfcfb0198ff11739caeb08eebd4929a5bd6e445b1a89c3b79c916b453f2c3d9cde05719f997e5b6eac0835534cbacc2bdb9016c296c8228f
6
+ metadata.gz: 999689f22f02b64395c78b537ee86f6f0390e9cb2dc57e14293d310999bf11b5633b2fe16f1ca4c773bedb90e002452617f3df6926ff955deb84cca5446381ce
7
+ data.tar.gz: 71f12207a56541aab4ba1157d74e988295aff34e181daeb8937ed1e8bdc7a81025baaad536a0634da49527d63c71d341d433832cb56672b60f7fd920dcecda1a
data/README.md CHANGED
@@ -1,9 +1,11 @@
1
- [![Gem Version](https://badge.fury.io/rb/json-schema.svg)](https://badge.fury.io/rb/json-schema)
2
- [![Travis](https://travis-ci.org/ruby-json-schema/json-schema.svg?branch=master)](https://travis-ci.org/ruby-json-schema/json-schema)
3
- [![Code Climate](https://codeclimate.com/github/ruby-json-schema/json-schema/badges/gpa.svg)](https://codeclimate.com/github/ruby-json-schema/json-schema)
1
+ # Ruby JSON Schema Validator
4
2
 
5
- Ruby JSON Schema Validator
6
- ==========================
3
+ [![License](https://img.shields.io/github/license/voxpupuli/json-schema.svg)](https://github.com/voxpupuli/json-schema/blob/master/LICENSE)
4
+ [![Test](https://github.com/voxpupuli/json-schema/actions/workflows/test.yml/badge.svg)](https://github.com/voxpupuli/json-schema/actions/workflows/test.yml)
5
+ [![Release](https://github.com/voxpupuli/json-schema/actions/workflows/release.yml/badge.svg)](https://github.com/voxpupuli/json-schema/actions/workflows/release.yml)
6
+ [![RubyGem Version](https://img.shields.io/gem/v/json-schema.svg)](https://rubygems.org/gems/json-schema)
7
+ [![RubyGem Downloads](https://img.shields.io/gem/dt/json-schema.svg)](https://rubygems.org/gems/json-schema)
8
+ [![Donated by Iain Beeston](https://img.shields.io/badge/donated%20by-Iain%20Beeston-fb7047.svg)](#transfer-notice)
7
9
 
8
10
  This library is intended to provide Ruby with an interface for validating JSON
9
11
  objects against a JSON schema conforming to [JSON Schema Draft
@@ -17,7 +19,7 @@ Additional Resources
17
19
  --------------------
18
20
 
19
21
  - [Google Groups](https://groups.google.com/forum/#!forum/ruby-json-schema)
20
- - #ruby-json-schema on chat.freenode.net
22
+ - #voxpupuli on irc.libera.chat
21
23
 
22
24
  Version 2.0.0 Upgrade Notes
23
25
  ---------------------------
@@ -27,6 +29,14 @@ default**, so schemas that do not declare a validator using the `$schema`
27
29
  keyword will use Draft-04 now instead of Draft-03. This is the reason for the
28
30
  major version upgrade.
29
31
 
32
+ Version 3.0.0 Upgrade Notes
33
+ ---------------------------
34
+
35
+ All individual changes are documented in the CHANGELOG.md. The biggest change
36
+ is that the new version only supports Ruby 2.5 and newer. Take a look into the
37
+ gemspec file to see the currently supported Ruby version and also
38
+ `.github/workflows/test.yml` to see the Ruby versions we test on.
39
+
30
40
  Installation
31
41
  ------------
32
42
 
@@ -39,8 +49,8 @@ gem install json-schema
39
49
  From the git repo:
40
50
 
41
51
  ```sh
42
- $ gem build json-schema.gemspec
43
- $ gem install json-schema-2.5.2.gem
52
+ gem build json-schema.gemspec
53
+ gem install json-schema-*.gem
44
54
  ```
45
55
 
46
56
  Validation
@@ -166,7 +176,7 @@ JSON::Validator.validate(schema, [{"a" => 1}, {"a" => 2}, {"a" => 3}])
166
176
  JSON::Validator.fully_validate(schema, { "a" => "taco" }, :errors_as_objects => true)
167
177
 
168
178
  #
169
- # with the `:strict` option, all properties are condisidered to have `"required": true` and all objects `"additionalProperties": false`
179
+ # with the `:strict` option, all properties are considered to have `"required": true` and all objects `"additionalProperties": false`
170
180
  #
171
181
 
172
182
  # => true
@@ -375,6 +385,33 @@ schema = {
375
385
  errors = JSON::Validator.fully_validate(schema, {"a" => "23"})
376
386
  ```
377
387
 
388
+ Validating a JSON Schema
389
+ ------------------------
390
+
391
+ To validate that a JSON Schema conforms to the JSON Schema standard,
392
+ you need to validate your schema against the metaschema for the appropriate
393
+ JSON Schema Draft. All of the normal validation methods can be used
394
+ for this. First retrieve the appropriate metaschema from the internal
395
+ cache (using `JSON::Validator.validator_for_name()` or
396
+ `JSON::Validator.validator_for_uri()`) and then simply validate your
397
+ schema against it.
398
+
399
+
400
+ ```ruby
401
+ require "json-schema"
402
+
403
+ schema = {
404
+ "type" => "object",
405
+ "properties" => {
406
+ "a" => {"type" => "integer"}
407
+ }
408
+ }
409
+
410
+ metaschema = JSON::Validator.validator_for_name("draft4").metaschema
411
+ # => true
412
+ JSON::Validator.validate(metaschema, schema)
413
+ ```
414
+
378
415
  Controlling Remote Schema Reading
379
416
  ---------------------------------
380
417
 
@@ -445,3 +482,23 @@ value is of the correct datatype (e.g., an instance value is validated to be an
445
482
  integer or a float in the case of 'utc-millisec').
446
483
 
447
484
  Additionally, JSON::Validator does not handle any json hyperschema attributes.
485
+
486
+ # Transfer Notice
487
+
488
+ This plugin was originally authored by [Iain Beeston](https://github.com/iainbeeston).
489
+ The maintainer preferred that [Vox Pupuli](https://voxpupuli.org/) take ownership of the module for future improvement and maintenance.
490
+ Existing pull requests and issues were transferred, please fork and continue to contribute [here](https://github.com/voxpupuli/json-schema).
491
+
492
+ # License
493
+
494
+ This gem is licensed unter the [MIT license](LICENSE.md).
495
+
496
+ ## Release information
497
+
498
+ To make a new release, please do:
499
+ * update the version in VERSION.yml
500
+ * Install gems with `bundle install --with release --path .vendor`
501
+ * generate the changelog with `bundle exec rake changelog`
502
+ * Check if the new version matches the closed issues/PRs in the changelog
503
+ * Create a PR with it
504
+ * After it got merged, push a tag. GitHub actions will do the actual release to rubygems and GitHub Packages
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attribute'
2
+
3
+ module JSON
4
+ class Schema
5
+ class ConstAttribute < Attribute
6
+ def self.validate(current_schema, data, fragments, processor, validator, options = {})
7
+ const_value = current_schema.schema['const']
8
+ unless const_value == data
9
+ message = "The property '#{build_fragment(fragments)}' value #{data.inspect} did not match constant '#{const_value}'"
10
+ validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -34,11 +34,5 @@ module JSON
34
34
  value.is_a?(String) || value.is_a?(Array) || value.is_a?(Hash)
35
35
  end
36
36
  end
37
-
38
- class DependenciesV4Attribute < DependenciesAttribute
39
- def self.accept_value?(value)
40
- value.is_a?(Array) || value.is_a?(Hash)
41
- end
42
- end
43
37
  end
44
38
  end
@@ -0,0 +1,11 @@
1
+ require 'json-schema/attributes/dependencies'
2
+
3
+ module JSON
4
+ class Schema
5
+ class DependenciesV4Attribute < DependenciesAttribute
6
+ def self.accept_value?(value)
7
+ value.is_a?(Array) || value.is_a?(Hash)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -12,7 +12,7 @@ module JSON
12
12
 
13
13
  factor = current_schema.schema[keyword]
14
14
 
15
- if factor == 0 || factor == 0.0 || (BigDecimal.new(data.to_s) % BigDecimal.new(factor.to_s)).to_f != 0
15
+ if factor == 0 || factor == 0.0 || (BigDecimal(data.to_s) % BigDecimal(factor.to_s)).to_f != 0
16
16
  message = "The property '#{build_fragment(fragments)}' was not divisible by #{factor}"
17
17
  validation_error(processor, message, fragments, current_schema, self, options[:record_errors])
18
18
  end
@@ -1,4 +1,4 @@
1
- require 'json-schema/attribute'
1
+ require 'json-schema/attributes/format'
2
2
  require 'json-schema/errors/custom_format_error'
3
3
 
4
4
  module JSON
@@ -1,4 +1,4 @@
1
- require 'json-schema/attribute'
1
+ require 'json-schema/attributes/format'
2
2
 
3
3
  module JSON
4
4
  class Schema
@@ -1,4 +1,4 @@
1
- require 'json-schema/attribute'
1
+ require 'json-schema/attributes/format'
2
2
 
3
3
  module JSON
4
4
  class Schema
@@ -1,4 +1,4 @@
1
- require 'json-schema/attribute'
1
+ require 'json-schema/attributes/format'
2
2
 
3
3
  module JSON
4
4
  class Schema
@@ -11,7 +11,7 @@ module JSON
11
11
  begin
12
12
  ip = IPAddr.new(data)
13
13
  rescue ArgumentError => e
14
- raise e unless e.message == 'invalid address'
14
+ raise e unless e.message.start_with?('invalid address')
15
15
  end
16
16
 
17
17
  family = ip_version == 6 ? Socket::AF_INET6 : Socket::AF_INET
@@ -1,4 +1,4 @@
1
- require 'json-schema/attribute'
1
+ require 'json-schema/attributes/format'
2
2
 
3
3
  module JSON
4
4
  class Schema
@@ -1,4 +1,4 @@
1
- require 'json-schema/attribute'
1
+ require 'json-schema/attributes/format'
2
2
  require 'json-schema/errors/uri_error'
3
3
 
4
4
  module JSON
@@ -48,132 +48,5 @@ module JSON
48
48
  raise NotImplementedError
49
49
  end
50
50
  end
51
-
52
- class MinLengthAttribute < LimitAttribute
53
- def self.acceptable_type
54
- String
55
- end
56
-
57
- def self.limit_name
58
- 'minLength'
59
- end
60
-
61
- def self.error_message(schema)
62
- "was not of a minimum string length of #{limit(schema)}"
63
- end
64
-
65
- def self.value(data)
66
- data.length
67
- end
68
- end
69
-
70
- class MaxLengthAttribute < MinLengthAttribute
71
- def self.limit_name
72
- 'maxLength'
73
- end
74
-
75
- def self.error_message(schema)
76
- "was not of a maximum string length of #{limit(schema)}"
77
- end
78
- end
79
-
80
- class MinItemsAttribute < LimitAttribute
81
- def self.acceptable_type
82
- Array
83
- end
84
-
85
- def self.value(data)
86
- data.length
87
- end
88
-
89
- def self.limit_name
90
- 'minItems'
91
- end
92
-
93
- def self.error_message(schema)
94
- "did not contain a minimum number of items #{limit(schema)}"
95
- end
96
- end
97
-
98
- class MaxItemsAttribute < MinItemsAttribute
99
- def self.limit_name
100
- 'maxItems'
101
- end
102
-
103
- def self.error_message(schema)
104
- "had more items than the allowed #{limit(schema)}"
105
- end
106
- end
107
-
108
- class MinPropertiesAttribute < LimitAttribute
109
- def self.acceptable_type
110
- Hash
111
- end
112
-
113
- def self.value(data)
114
- data.size
115
- end
116
-
117
- def self.limit_name
118
- 'minProperties'
119
- end
120
-
121
- def self.error_message(schema)
122
- "did not contain a minimum number of properties #{limit(schema)}"
123
- end
124
- end
125
-
126
- class MaxPropertiesAttribute < MinPropertiesAttribute
127
- def self.limit_name
128
- 'maxProperties'
129
- end
130
-
131
- def self.error_message(schema)
132
- "had more properties than the allowed #{limit(schema)}"
133
- end
134
- end
135
-
136
- class NumericLimitAttribute < LimitAttribute
137
- def self.acceptable_type
138
- Numeric
139
- end
140
-
141
- def self.error_message(schema)
142
- exclusivity = exclusive?(schema) ? 'exclusively' : 'inclusively'
143
- format("did not have a %s value of %s, %s", limit_name, limit(schema), exclusivity)
144
- end
145
- end
146
-
147
- class MaximumAttribute < NumericLimitAttribute
148
- def self.limit_name
149
- 'maximum'
150
- end
151
-
152
- def self.exclusive?(schema)
153
- schema['exclusiveMaximum']
154
- end
155
- end
156
-
157
- class MaximumInclusiveAttribute < MaximumAttribute
158
- def self.exclusive?(schema)
159
- schema['maximumCanEqual'] == false
160
- end
161
- end
162
-
163
- class MinimumAttribute < NumericLimitAttribute
164
- def self.limit_name
165
- 'minimum'
166
- end
167
-
168
- def self.exclusive?(schema)
169
- schema['exclusiveMinimum']
170
- end
171
- end
172
-
173
- class MinimumInclusiveAttribute < MinimumAttribute
174
- def self.exclusive?(schema)
175
- schema['minimumCanEqual'] == false
176
- end
177
- end
178
51
  end
179
52
  end
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attributes/limit'
2
+
3
+ module JSON
4
+ class Schema
5
+ class ItemsLimitAttribute < LimitAttribute
6
+ def self.acceptable_type
7
+ Array
8
+ end
9
+
10
+ def self.value(data)
11
+ data.length
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attributes/limit'
2
+
3
+ module JSON
4
+ class Schema
5
+ class LengthLimitAttribute < LimitAttribute
6
+ def self.acceptable_type
7
+ String
8
+ end
9
+
10
+ def self.value(data)
11
+ data.length
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attributes/limits/items'
2
+
3
+ module JSON
4
+ class Schema
5
+ class MaxItemsAttribute < ItemsLimitAttribute
6
+ def self.limit_name
7
+ 'maxItems'
8
+ end
9
+
10
+ def self.error_message(schema)
11
+ "had more items than the allowed #{limit(schema)}"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attributes/limits/length'
2
+
3
+ module JSON
4
+ class Schema
5
+ class MaxLengthAttribute < LengthLimitAttribute
6
+ def self.limit_name
7
+ 'maxLength'
8
+ end
9
+
10
+ def self.error_message(schema)
11
+ "was not of a maximum string length of #{limit(schema)}"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attributes/limits/properties'
2
+
3
+ module JSON
4
+ class Schema
5
+ class MaxPropertiesAttribute < PropertiesLimitAttribute
6
+ def self.limit_name
7
+ 'maxProperties'
8
+ end
9
+
10
+ def self.error_message(schema)
11
+ "had more properties than the allowed #{limit(schema)}"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attributes/limits/numeric'
2
+
3
+ module JSON
4
+ class Schema
5
+ class MaximumAttribute < NumericLimitAttribute
6
+ def self.limit_name
7
+ 'maximum'
8
+ end
9
+
10
+ def self.exclusive?(schema)
11
+ schema['exclusiveMaximum']
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ require 'json-schema/attributes/limits/maximum'
2
+
3
+ module JSON
4
+ class Schema
5
+ class MaximumInclusiveAttribute < MaximumAttribute
6
+ def self.exclusive?(schema)
7
+ schema['maximumCanEqual'] == false
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attributes/limits/items'
2
+
3
+ module JSON
4
+ class Schema
5
+ class MinItemsAttribute < ItemsLimitAttribute
6
+ def self.limit_name
7
+ 'minItems'
8
+ end
9
+
10
+ def self.error_message(schema)
11
+ "did not contain a minimum number of items #{limit(schema)}"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attributes/limits/length'
2
+
3
+ module JSON
4
+ class Schema
5
+ class MinLengthAttribute < LengthLimitAttribute
6
+ def self.limit_name
7
+ 'minLength'
8
+ end
9
+
10
+ def self.error_message(schema)
11
+ "was not of a minimum string length of #{limit(schema)}"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attributes/limits/properties'
2
+
3
+ module JSON
4
+ class Schema
5
+ class MinPropertiesAttribute < PropertiesLimitAttribute
6
+ def self.limit_name
7
+ 'minProperties'
8
+ end
9
+
10
+ def self.error_message(schema)
11
+ "did not contain a minimum number of properties #{limit(schema)}"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attributes/limits/numeric'
2
+
3
+ module JSON
4
+ class Schema
5
+ class MinimumAttribute < NumericLimitAttribute
6
+ def self.limit_name
7
+ 'minimum'
8
+ end
9
+
10
+ def self.exclusive?(schema)
11
+ schema['exclusiveMinimum']
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ require 'json-schema/attributes/limits/minimum'
2
+
3
+ module JSON
4
+ class Schema
5
+ class MinimumInclusiveAttribute < MinimumAttribute
6
+ def self.exclusive?(schema)
7
+ schema['minimumCanEqual'] == false
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ require 'json-schema/attributes/limit'
2
+
3
+ module JSON
4
+ class Schema
5
+ class NumericLimitAttribute < LimitAttribute
6
+ def self.acceptable_type
7
+ Numeric
8
+ end
9
+
10
+ def self.error_message(schema)
11
+ exclusivity = exclusive?(schema) ? 'exclusively' : 'inclusively'
12
+ format("did not have a %s value of %s, %s", limit_name, limit(schema), exclusivity)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ require 'json-schema/attributes/limit'
2
+
3
+ module JSON
4
+ class Schema
5
+ class PropertiesLimitAttribute < LimitAttribute
6
+ def self.acceptable_type
7
+ Hash
8
+ end
9
+
10
+ def self.value(data)
11
+ data.size
12
+ end
13
+ end
14
+ end
15
+ end
@@ -62,13 +62,5 @@ module JSON
62
62
  end
63
63
  end
64
64
  end
65
-
66
- class PropertiesV4Attribute < PropertiesAttribute
67
- # draft4 relies on its own RequiredAttribute validation at a higher level, rather than
68
- # as an attribute of individual properties.
69
- def self.required?(schema, options)
70
- options[:strict] == true
71
- end
72
- end
73
65
  end
74
66
  end
@@ -0,0 +1,13 @@
1
+ require 'json-schema/attributes/properties'
2
+
3
+ module JSON
4
+ class Schema
5
+ class PropertiesV4Attribute < PropertiesAttribute
6
+ # draft4 relies on its own RequiredAttribute validation at a higher level, rather than
7
+ # as an attribute of individual properties.
8
+ def self.required?(schema, options)
9
+ options[:strict] == true
10
+ end
11
+ end
12
+ end
13
+ end
@@ -118,7 +118,7 @@ module JSON
118
118
 
119
119
  def read_uri(uri)
120
120
  if accept_uri?(uri)
121
- open(uri.to_s).read
121
+ URI.open(uri.to_s).read
122
122
  else
123
123
  raise JSON::Schema::ReadRefused.new(uri.to_s, :uri)
124
124
  end
@@ -4,6 +4,7 @@ require 'bigdecimal'
4
4
  require 'digest/sha1'
5
5
  require 'date'
6
6
  require 'thread'
7
+ require 'timeout'
7
8
  require 'yaml'
8
9
 
9
10
  require 'json-schema/schema/reader'
@@ -41,8 +42,7 @@ module JSON
41
42
  @options = @@default_opts.clone.merge(opts)
42
43
  @errors = []
43
44
 
44
- validator = self.class.validator_for_name(@options[:version])
45
- @options[:version] = validator
45
+ configured_validator = self.class.validator_for_name(@options[:version])
46
46
  @options[:schema_reader] ||= self.class.schema_reader
47
47
 
48
48
  @validation_options = @options[:record_errors] ? {:record_errors => true} : {}
@@ -50,19 +50,16 @@ module JSON
50
50
  @validation_options[:strict] = true if @options[:strict] == true
51
51
  @validation_options[:clear_cache] = true if !@@cache_schemas || @options[:clear_cache]
52
52
 
53
- @@mutex.synchronize { @base_schema = initialize_schema(schema_data) }
53
+ @@mutex.synchronize { @base_schema = initialize_schema(schema_data, configured_validator) }
54
54
  @original_data = data
55
55
  @data = initialize_data(data)
56
56
  @@mutex.synchronize { build_schemas(@base_schema) }
57
57
 
58
58
  # validate the schema, if requested
59
59
  if @options[:validate_schema]
60
- if @base_schema.schema["$schema"]
61
- base_validator = self.class.validator_for_name(@base_schema.schema["$schema"])
62
- end
63
- metaschema = base_validator ? base_validator.metaschema : validator.metaschema
64
60
  # Don't clear the cache during metaschema validation!
65
- self.class.validate!(metaschema, @base_schema.schema, {:clear_cache => false})
61
+ meta_validator = self.class.new(@base_schema.validator.metaschema, @base_schema.schema, {:clear_cache => false})
62
+ meta_validator.validate
66
63
  end
67
64
 
68
65
  # If the :fragment option is set, try and validate against the fragment
@@ -73,38 +70,35 @@ module JSON
73
70
 
74
71
  def schema_from_fragment(base_schema, fragment)
75
72
  schema_uri = base_schema.uri
76
- fragments = fragment.split("/")
73
+ fragments = fragment.split("/").map { |f| f.gsub('~0', '~').gsub('~1', '/') }
77
74
 
78
75
  # ensure the first element was a hash, per the fragment spec
79
76
  if fragments.shift != "#"
80
77
  raise JSON::Schema::SchemaError.new("Invalid fragment syntax in :fragment option")
81
78
  end
82
79
 
80
+ schema_fragment = base_schema.schema
83
81
  fragments.each do |f|
84
- if base_schema.is_a?(JSON::Schema) #test if fragment is a JSON:Schema instance
85
- if !base_schema.schema.has_key?(f)
86
- raise JSON::Schema::SchemaError.new("Invalid fragment resolution for :fragment option")
87
- end
88
- base_schema = base_schema.schema[f]
89
- elsif base_schema.is_a?(Hash)
90
- if !base_schema.has_key?(f)
91
- raise JSON::Schema::SchemaError.new("Invalid fragment resolution for :fragment option")
92
- end
93
- base_schema = JSON::Schema.new(base_schema[f],schema_uri,@options[:version])
94
- elsif base_schema.is_a?(Array)
95
- if base_schema[f.to_i].nil?
96
- raise JSON::Schema::SchemaError.new("Invalid fragment resolution for :fragment option")
97
- end
98
- base_schema = JSON::Schema.new(base_schema[f.to_i],schema_uri,@options[:version])
99
- else
100
- raise JSON::Schema::SchemaError.new("Invalid schema encountered when resolving :fragment option")
82
+ case schema_fragment
83
+ when Hash
84
+ schema_fragment = schema_fragment[f]
85
+ when Array
86
+ schema_fragment = schema_fragment[f.to_i]
101
87
  end
102
88
  end
103
89
 
90
+ unless schema_fragment.is_a?(Hash)
91
+ raise JSON::Schema::SchemaError.new("Invalid fragment resolution for :fragment option")
92
+ end
93
+
94
+ schema = JSON::Schema.new(schema_fragment, schema_uri, base_schema.validator)
95
+
104
96
  if @options[:list]
105
- base_schema.to_array_schema
97
+ schema.to_array_schema
98
+ elsif schema.is_a?(Hash)
99
+ JSON::Schema.new(schema, schema_uri, @options[:version])
106
100
  else
107
- base_schema
101
+ schema
108
102
  end
109
103
  end
110
104
 
@@ -517,12 +511,12 @@ module JSON
517
511
  @@fake_uuid_generator.call(schema)
518
512
  end
519
513
 
520
- def initialize_schema(schema)
514
+ def initialize_schema(schema, default_validator)
521
515
  if schema.is_a?(String)
522
516
  begin
523
517
  # Build a fake URI for this
524
518
  schema_uri = JSON::Util::URI.parse(fake_uuid(schema))
525
- schema = JSON::Schema.new(self.class.parse(schema), schema_uri, @options[:version])
519
+ schema = JSON::Schema.new(JSON::Validator.parse(schema), schema_uri, default_validator)
526
520
  if @options[:list] && @options[:fragment].nil?
527
521
  schema = schema.to_array_schema
528
522
  end
@@ -552,7 +546,7 @@ module JSON
552
546
  elsif schema.is_a?(Hash)
553
547
  schema_uri = JSON::Util::URI.parse(fake_uuid(serialize(schema)))
554
548
  schema = JSON::Schema.stringify(schema)
555
- schema = JSON::Schema.new(schema, schema_uri, @options[:version])
549
+ schema = JSON::Schema.new(schema, schema_uri, default_validator)
556
550
  if @options[:list] && @options[:fragment].nil?
557
551
  schema = schema.to_array_schema
558
552
  end
@@ -578,7 +572,7 @@ module JSON
578
572
  begin
579
573
  json_uri = Util::URI.normalized_uri(data)
580
574
  data = self.class.parse(custom_open(json_uri))
581
- rescue JSON::Schema::JsonLoadError
575
+ rescue JSON::Schema::JsonLoadError, JSON::Schema::UriError
582
576
  # Silently discard the error - use the data as-is
583
577
  end
584
578
  end
@@ -591,7 +585,7 @@ module JSON
591
585
  uri = Util::URI.normalized_uri(uri) if uri.is_a?(String)
592
586
  if uri.absolute? && Util::URI::SUPPORTED_PROTOCOLS.include?(uri.scheme)
593
587
  begin
594
- open(uri.to_s).read
588
+ URI.open(uri.to_s).read
595
589
  rescue OpenURI::HTTPError, Timeout::Error => e
596
590
  raise JSON::Schema::JsonLoadError, e.message
597
591
  end
@@ -34,6 +34,7 @@ module JSON
34
34
  "additionalItems" => JSON::Schema::AdditionalItemsAttribute,
35
35
  "dependencies" => JSON::Schema::DependenciesV4Attribute,
36
36
  "extends" => JSON::Schema::ExtendsAttribute,
37
+ "const" => JSON::Schema::ConstAttribute,
37
38
  "$ref" => JSON::Schema::RefAttribute
38
39
  }
39
40
  @default_formats = {
@@ -43,8 +44,8 @@ module JSON
43
44
  'uri' => UriFormat
44
45
  }
45
46
  @formats = @default_formats.clone
46
- @uri = JSON::Util::URI.parse("http://json-schema.org/draft-06/schema#")
47
- @names = ["draft6", "http://json-schema.org/draft-06/schema#"]
47
+ @uri = JSON::Util::URI.parse("http://json-schema.org/draft/schema#")
48
+ @names = ["draft6", "http://json-schema.org/draft/schema#"]
48
49
  @metaschema_name = "draft-06.json"
49
50
  end
50
51
 
data/lib/json-schema.rb CHANGED
@@ -14,6 +14,5 @@ require 'json-schema/schema'
14
14
  require 'json-schema/schema/reader'
15
15
  require 'json-schema/validator'
16
16
 
17
- Dir[File.join(File.dirname(__FILE__), "json-schema/attributes/*.rb")].each {|file| require file }
18
- Dir[File.join(File.dirname(__FILE__), "json-schema/attributes/formats/*.rb")].each {|file| require file }
17
+ Dir[File.join(File.dirname(__FILE__), "json-schema/attributes/**/*.rb")].each {|file| require file }
19
18
  Dir[File.join(File.dirname(__FILE__), "json-schema/validators/*.rb")].sort!.each {|file| require file }
@@ -1,7 +1,7 @@
1
1
  {
2
- "id": "http://json-schema.org/draft-06/schema#",
3
- "$schema": "http://json-schema.org/draft-06/schema#",
4
- "description": "Core schema meta-schema",
2
+ "$schema": "http://json-schema.org/draft/schema#",
3
+ "$id": "http://json-schema.org/draft/schema#",
4
+ "title": "Core schema meta-schema",
5
5
  "definitions": {
6
6
  "schemaArray": {
7
7
  "type": "array",
@@ -13,28 +13,43 @@
13
13
  "minimum": 0
14
14
  },
15
15
  "positiveIntegerDefault0": {
16
- "allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ]
16
+ "allOf": [
17
+ { "$ref": "#/definitions/positiveInteger" },
18
+ { "default": 0 }
19
+ ]
17
20
  },
18
21
  "simpleTypes": {
19
- "enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ]
22
+ "enum": [
23
+ "array",
24
+ "boolean",
25
+ "integer",
26
+ "null",
27
+ "number",
28
+ "object",
29
+ "string"
30
+ ]
20
31
  },
21
32
  "stringArray": {
22
33
  "type": "array",
23
34
  "items": { "type": "string" },
24
- "minItems": 1,
25
- "uniqueItems": true
35
+ "uniqueItems": true,
36
+ "defaultItems": []
26
37
  }
27
38
  },
28
- "type": "object",
39
+ "type": ["object", "boolean"],
29
40
  "properties": {
30
- "id": {
41
+ "$id": {
31
42
  "type": "string",
32
- "format": "uri"
43
+ "format": "uri-reference"
33
44
  },
34
45
  "$schema": {
35
46
  "type": "string",
36
47
  "format": "uri"
37
48
  },
49
+ "$ref": {
50
+ "type": "string",
51
+ "format": "uri-reference"
52
+ },
38
53
  "title": {
39
54
  "type": "string"
40
55
  },
@@ -44,22 +59,19 @@
44
59
  "default": {},
45
60
  "multipleOf": {
46
61
  "type": "number",
47
- "minimum": 0,
48
- "exclusiveMinimum": true
62
+ "exclusiveMinimum": 0
49
63
  },
50
64
  "maximum": {
51
65
  "type": "number"
52
66
  },
53
67
  "exclusiveMaximum": {
54
- "type": "boolean",
55
- "default": false
68
+ "type": "number"
56
69
  },
57
70
  "minimum": {
58
71
  "type": "number"
59
72
  },
60
73
  "exclusiveMinimum": {
61
- "type": "boolean",
62
- "default": false
74
+ "type": "number"
63
75
  },
64
76
  "maxLength": { "$ref": "#/definitions/positiveInteger" },
65
77
  "minLength": { "$ref": "#/definitions/positiveIntegerDefault0" },
@@ -67,13 +79,7 @@
67
79
  "type": "string",
68
80
  "format": "regex"
69
81
  },
70
- "additionalItems": {
71
- "anyOf": [
72
- { "type": "boolean" },
73
- { "$ref": "#" }
74
- ],
75
- "default": {}
76
- },
82
+ "additionalItems": { "$ref": "#" },
77
83
  "items": {
78
84
  "anyOf": [
79
85
  { "$ref": "#" },
@@ -87,16 +93,11 @@
87
93
  "type": "boolean",
88
94
  "default": false
89
95
  },
96
+ "contains": { "$ref": "#" },
90
97
  "maxProperties": { "$ref": "#/definitions/positiveInteger" },
91
98
  "minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" },
92
99
  "required": { "$ref": "#/definitions/stringArray" },
93
- "additionalProperties": {
94
- "anyOf": [
95
- { "type": "boolean" },
96
- { "$ref": "#" }
97
- ],
98
- "default": {}
99
- },
100
+ "additionalProperties": { "$ref": "#" },
100
101
  "definitions": {
101
102
  "type": "object",
102
103
  "additionalProperties": { "$ref": "#" },
@@ -121,6 +122,8 @@
121
122
  ]
122
123
  }
123
124
  },
125
+ "propertyNames": { "$ref": "#" },
126
+ "const": {},
124
127
  "enum": {
125
128
  "type": "array",
126
129
  "minItems": 1,
@@ -137,14 +140,11 @@
137
140
  }
138
141
  ]
139
142
  },
143
+ "format": { "type": "string" },
140
144
  "allOf": { "$ref": "#/definitions/schemaArray" },
141
145
  "anyOf": { "$ref": "#/definitions/schemaArray" },
142
146
  "oneOf": { "$ref": "#/definitions/schemaArray" },
143
147
  "not": { "$ref": "#" }
144
148
  },
145
- "dependencies": {
146
- "exclusiveMaximum": [ "maximum" ],
147
- "exclusiveMinimum": [ "minimum" ]
148
- },
149
149
  "default": {}
150
150
  }
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json-schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenny Hoxworth
8
+ - Vox Pupuli
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2017-02-07 00:00:00.000000000 Z
12
+ date: 2022-05-03 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: rake
@@ -72,16 +73,16 @@ dependencies:
72
73
  requirements:
73
74
  - - ">="
74
75
  - !ruby/object:Gem::Version
75
- version: '2.4'
76
+ version: '2.8'
76
77
  type: :runtime
77
78
  prerelease: false
78
79
  version_requirements: !ruby/object:Gem::Requirement
79
80
  requirements:
80
81
  - - ">="
81
82
  - !ruby/object:Gem::Version
82
- version: '2.4'
83
+ version: '2.8'
83
84
  description:
84
- email: hoxworth@gmail.com
85
+ email: voxpupuli@groups.io
85
86
  executables: []
86
87
  extensions: []
87
88
  extra_rdoc_files:
@@ -96,7 +97,9 @@ files:
96
97
  - lib/json-schema/attributes/additionalproperties.rb
97
98
  - lib/json-schema/attributes/allof.rb
98
99
  - lib/json-schema/attributes/anyof.rb
100
+ - lib/json-schema/attributes/const.rb
99
101
  - lib/json-schema/attributes/dependencies.rb
102
+ - lib/json-schema/attributes/dependencies_v4.rb
100
103
  - lib/json-schema/attributes/disallow.rb
101
104
  - lib/json-schema/attributes/divisibleby.rb
102
105
  - lib/json-schema/attributes/enum.rb
@@ -111,6 +114,20 @@ files:
111
114
  - lib/json-schema/attributes/formats/uri.rb
112
115
  - lib/json-schema/attributes/items.rb
113
116
  - lib/json-schema/attributes/limit.rb
117
+ - lib/json-schema/attributes/limits/items.rb
118
+ - lib/json-schema/attributes/limits/length.rb
119
+ - lib/json-schema/attributes/limits/max_items.rb
120
+ - lib/json-schema/attributes/limits/max_length.rb
121
+ - lib/json-schema/attributes/limits/max_properties.rb
122
+ - lib/json-schema/attributes/limits/maximum.rb
123
+ - lib/json-schema/attributes/limits/maximum_inclusive.rb
124
+ - lib/json-schema/attributes/limits/min_items.rb
125
+ - lib/json-schema/attributes/limits/min_length.rb
126
+ - lib/json-schema/attributes/limits/min_properties.rb
127
+ - lib/json-schema/attributes/limits/minimum.rb
128
+ - lib/json-schema/attributes/limits/minimum_inclusive.rb
129
+ - lib/json-schema/attributes/limits/numeric.rb
130
+ - lib/json-schema/attributes/limits/properties.rb
114
131
  - lib/json-schema/attributes/maxdecimal.rb
115
132
  - lib/json-schema/attributes/multipleof.rb
116
133
  - lib/json-schema/attributes/not.rb
@@ -119,6 +136,7 @@ files:
119
136
  - lib/json-schema/attributes/patternproperties.rb
120
137
  - lib/json-schema/attributes/properties.rb
121
138
  - lib/json-schema/attributes/properties_optional.rb
139
+ - lib/json-schema/attributes/properties_v4.rb
122
140
  - lib/json-schema/attributes/ref.rb
123
141
  - lib/json-schema/attributes/required.rb
124
142
  - lib/json-schema/attributes/type.rb
@@ -153,7 +171,7 @@ files:
153
171
  - resources/draft-03.json
154
172
  - resources/draft-04.json
155
173
  - resources/draft-06.json
156
- homepage: http://github.com/ruby-json-schema/json-schema/tree/master
174
+ homepage: http://github.com/voxpupuli/json-schema/
157
175
  licenses:
158
176
  - MIT
159
177
  metadata: {}
@@ -165,15 +183,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
165
183
  requirements:
166
184
  - - ">="
167
185
  - !ruby/object:Gem::Version
168
- version: '1.9'
186
+ version: '2.5'
169
187
  required_rubygems_version: !ruby/object:Gem::Requirement
170
188
  requirements:
171
189
  - - ">="
172
190
  - !ruby/object:Gem::Version
173
- version: '1.8'
191
+ version: '2.5'
174
192
  requirements: []
175
- rubyforge_project:
176
- rubygems_version: 2.6.8
193
+ rubygems_version: 3.3.7
177
194
  signing_key:
178
195
  specification_version: 4
179
196
  summary: Ruby JSON Schema Validator