json-schema 2.8.0 → 3.0.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.
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