json-schema 2.8.0 → 5.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +82 -11
  3. data/lib/json-schema/attribute.rb +13 -14
  4. data/lib/json-schema/attributes/additionalitems.rb +1 -0
  5. data/lib/json-schema/attributes/additionalproperties.rb +3 -6
  6. data/lib/json-schema/attributes/allof.rb +6 -4
  7. data/lib/json-schema/attributes/anyof.rb +2 -2
  8. data/lib/json-schema/attributes/const.rb +15 -0
  9. data/lib/json-schema/attributes/dependencies.rb +1 -6
  10. data/lib/json-schema/attributes/dependencies_v4.rb +11 -0
  11. data/lib/json-schema/attributes/disallow.rb +2 -1
  12. data/lib/json-schema/attributes/divisibleby.rb +1 -1
  13. data/lib/json-schema/attributes/enum.rb +2 -2
  14. data/lib/json-schema/attributes/extends.rb +7 -7
  15. data/lib/json-schema/attributes/format.rb +2 -1
  16. data/lib/json-schema/attributes/formats/custom.rb +1 -1
  17. data/lib/json-schema/attributes/formats/date.rb +2 -1
  18. data/lib/json-schema/attributes/formats/date_time.rb +3 -2
  19. data/lib/json-schema/attributes/formats/date_time_v4.rb +2 -1
  20. data/lib/json-schema/attributes/formats/ip.rb +1 -1
  21. data/lib/json-schema/attributes/formats/time.rb +1 -1
  22. data/lib/json-schema/attributes/formats/uri.rb +2 -1
  23. data/lib/json-schema/attributes/items.rb +1 -0
  24. data/lib/json-schema/attributes/limit.rb +0 -127
  25. data/lib/json-schema/attributes/limits/items.rb +15 -0
  26. data/lib/json-schema/attributes/limits/length.rb +15 -0
  27. data/lib/json-schema/attributes/limits/max_items.rb +15 -0
  28. data/lib/json-schema/attributes/limits/max_length.rb +15 -0
  29. data/lib/json-schema/attributes/limits/max_properties.rb +15 -0
  30. data/lib/json-schema/attributes/limits/maximum.rb +15 -0
  31. data/lib/json-schema/attributes/limits/maximum_inclusive.rb +11 -0
  32. data/lib/json-schema/attributes/limits/min_items.rb +15 -0
  33. data/lib/json-schema/attributes/limits/min_length.rb +15 -0
  34. data/lib/json-schema/attributes/limits/min_properties.rb +15 -0
  35. data/lib/json-schema/attributes/limits/minimum.rb +15 -0
  36. data/lib/json-schema/attributes/limits/minimum_inclusive.rb +11 -0
  37. data/lib/json-schema/attributes/limits/numeric.rb +16 -0
  38. data/lib/json-schema/attributes/limits/properties.rb +15 -0
  39. data/lib/json-schema/attributes/maxdecimal.rb +1 -1
  40. data/lib/json-schema/attributes/not.rb +2 -2
  41. data/lib/json-schema/attributes/oneof.rb +2 -4
  42. data/lib/json-schema/attributes/patternproperties.rb +2 -1
  43. data/lib/json-schema/attributes/properties.rb +9 -17
  44. data/lib/json-schema/attributes/properties_v4.rb +13 -0
  45. data/lib/json-schema/attributes/propertynames.rb +23 -0
  46. data/lib/json-schema/attributes/ref.rb +8 -8
  47. data/lib/json-schema/attributes/required.rb +4 -3
  48. data/lib/json-schema/attributes/type.rb +3 -2
  49. data/lib/json-schema/attributes/type_v4.rb +1 -1
  50. data/lib/json-schema/errors/validation_error.rb +5 -6
  51. data/lib/json-schema/schema/reader.rb +3 -1
  52. data/lib/json-schema/schema/validator.rb +3 -3
  53. data/lib/json-schema/schema.rb +3 -4
  54. data/lib/json-schema/util/array_set.rb +1 -1
  55. data/lib/json-schema/util/uri.rb +98 -75
  56. data/lib/json-schema/util/uuid.rb +203 -226
  57. data/lib/json-schema/validator.rb +122 -115
  58. data/lib/json-schema/validators/draft1.rb +21 -23
  59. data/lib/json-schema/validators/draft2.rb +22 -24
  60. data/lib/json-schema/validators/draft3.rb +26 -28
  61. data/lib/json-schema/validators/draft4.rb +34 -36
  62. data/lib/json-schema/validators/draft6.rb +36 -36
  63. data/lib/json-schema/validators/hyper-draft1.rb +2 -3
  64. data/lib/json-schema/validators/hyper-draft2.rb +2 -3
  65. data/lib/json-schema/validators/hyper-draft3.rb +2 -3
  66. data/lib/json-schema/validators/hyper-draft4.rb +2 -3
  67. data/lib/json-schema/validators/hyper-draft6.rb +2 -3
  68. data/lib/json-schema.rb +2 -3
  69. data/resources/draft-06.json +41 -41
  70. metadata +67 -31
@@ -28,6 +28,7 @@ module JSON
28
28
  # a schema should not be read.
29
29
  class ReadRefused < ReadError
30
30
  private
31
+
31
32
  def error_message
32
33
  "Read of #{type_string} at #{location} refused"
33
34
  end
@@ -36,6 +37,7 @@ module JSON
36
37
  # Raised by {JSON::Schema::Reader} when an attempt to read a schema fails
37
38
  class ReadFailed < ReadError
38
39
  private
40
+
39
41
  def error_message
40
42
  "Read of #{type_string} at #{location} failed"
41
43
  end
@@ -118,7 +120,7 @@ module JSON
118
120
 
119
121
  def read_uri(uri)
120
122
  if accept_uri?(uri)
121
- open(uri.to_s).read
123
+ URI.open(uri.to_s).read
122
124
  else
123
125
  raise JSON::Schema::ReadRefused.new(uri.to_s, :uri)
124
126
  end
@@ -4,7 +4,7 @@ module JSON
4
4
  attr_accessor :attributes, :formats, :uri, :names
5
5
  attr_reader :default_formats
6
6
 
7
- def initialize()
7
+ def initialize
8
8
  @attributes = {}
9
9
  @formats = {}
10
10
  @default_formats = {}
@@ -14,13 +14,13 @@ module JSON
14
14
  end
15
15
 
16
16
  def extend_schema_definition(schema_uri)
17
- warn "[DEPRECATION NOTICE] The preferred way to extend a Validator is by subclassing, rather than #extend_schema_definition. This method will be removed in version >= 3."
17
+ warn '[DEPRECATION NOTICE] The preferred way to extend a Validator is by subclassing, rather than #extend_schema_definition. This method will be removed in version >= 3.'
18
18
  validator = JSON::Validator.validator_for_uri(schema_uri)
19
19
  @attributes.merge!(validator.attributes)
20
20
  end
21
21
 
22
22
  def validate(current_schema, data, fragments, processor, options = {})
23
- current_schema.schema.each do |attr_name,attribute|
23
+ current_schema.schema.each do |attr_name, _attribute|
24
24
  if @attributes.has_key?(attr_name.to_s)
25
25
  @attributes[attr_name.to_s].validate(current_schema, data, fragments, processor, self, options)
26
26
  end
@@ -2,15 +2,14 @@ require 'pathname'
2
2
 
3
3
  module JSON
4
4
  class Schema
5
-
6
5
  attr_accessor :schema, :uri, :validator
7
6
 
8
- def initialize(schema,uri,parent_validator=nil)
7
+ def initialize(schema, uri, parent_validator = nil)
9
8
  @schema = schema
10
9
  @uri = uri
11
10
 
12
11
  # If there is an ID on this schema, use it to generate the URI
13
- if @schema['id'] && @schema['id'].kind_of?(String)
12
+ if @schema['id'].is_a?(String)
14
13
  temp_uri = JSON::Util::URI.parse(@schema['id'])
15
14
  if temp_uri.relative?
16
15
  temp_uri = uri.join(temp_uri)
@@ -36,7 +35,7 @@ module JSON
36
35
  def self.stringify(schema)
37
36
  case schema
38
37
  when Hash then
39
- Hash[schema.map { |key, value| [key.to_s, stringify(schema[key])] }]
38
+ schema.map { |key, _value| [key.to_s, stringify(schema[key])] }.to_h
40
39
  when Array then
41
40
  schema.map do |schema_item|
42
41
  stringify(schema_item)
@@ -7,7 +7,7 @@ class ArraySet < Array
7
7
  def include?(obj)
8
8
  if !defined? @values
9
9
  @values = Set.new
10
- self.each { |x| @values << convert_to_float_if_numeric(x) }
10
+ each { |x| @values << convert_to_float_if_numeric(x) }
11
11
  end
12
12
  @values.include?(convert_to_float_if_numeric(obj))
13
13
  end
@@ -1,109 +1,132 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'addressable/uri'
2
4
 
3
5
  module JSON
4
6
  module Util
5
- module URI
7
+ # @api private
8
+ class URI < Addressable::URI
6
9
  SUPPORTED_PROTOCOLS = %w(http https ftp tftp sftp ssh svn+ssh telnet nntp gopher wais ldap prospero)
7
10
 
8
- def self.normalized_uri(uri, base_path = Dir.pwd)
9
- @normalize_cache ||= {}
10
- normalized_uri = @normalize_cache[uri]
11
-
12
- if !normalized_uri
13
- normalized_uri = parse(uri)
14
- # Check for absolute path
15
- if normalized_uri.relative?
16
- data = normalized_uri
17
- data = File.join(base_path, data) if data.path[0,1] != "/"
18
- normalized_uri = file_uri(data)
19
- end
20
- @normalize_cache[uri] = normalized_uri.freeze
21
- end
22
-
23
- normalized_uri
24
- end
11
+ class << self
12
+ alias unescape_uri unescape
25
13
 
26
- def self.absolutize_ref(ref, base)
27
- ref_uri = strip_fragment(ref.dup)
28
-
29
- return ref_uri if ref_uri.absolute?
30
- return parse(base) if ref_uri.path.empty?
14
+ # @param uri [String, Addressable::URI]
15
+ # @return [Addressable::URI, nil]
16
+ def parse(uri)
17
+ super(uri)
18
+ rescue Addressable::URI::InvalidURIError => e
19
+ raise JSON::Schema::UriError, e.message
20
+ end
31
21
 
32
- uri = strip_fragment(base.dup).join(ref_uri.path)
33
- normalized_uri(uri)
34
- end
22
+ # @param uri [String, Addressable::URI]
23
+ # @return [Addressable::URI, nil]
24
+ def file_uri(uri)
25
+ convert_path(parse(uri).path)
26
+ end
35
27
 
36
- def self.normalize_ref(ref, base)
37
- ref_uri = parse(ref)
38
- base_uri = parse(base)
28
+ # @param uri [String, Addressable::URI
29
+ # @return [String]
30
+ def unescaped_path(uri)
31
+ parse(uri).unescaped_path
32
+ end
39
33
 
40
- ref_uri.defer_validation do
41
- if ref_uri.relative?
42
- ref_uri.merge!(base_uri)
34
+ # Strips the fragment from the URI.
35
+ # @param uri [String, Addressable::URI]
36
+ # @return [Addressable::URI]
37
+ def strip_fragment(uri)
38
+ parse(uri).strip_fragment
39
+ end
43
40
 
44
- # Check for absolute path
45
- path, fragment = ref.to_s.split("#")
46
- if path.nil? || path == ''
47
- ref_uri.path = base_uri.path
48
- elsif path[0,1] == "/"
49
- ref_uri.path = Pathname.new(path).cleanpath.to_s
50
- else
51
- ref_uri.join!(path)
52
- end
41
+ # @param uri [String, Addressable::URI]
42
+ # @return [Addressable::URI]
43
+ def normalized_uri(uri, base_path = Dir.pwd)
44
+ parse(uri).normalized_uri(base_path)
45
+ end
53
46
 
54
- ref_uri.fragment = fragment
55
- end
47
+ # Normalizes the reference URI based on the provided base URI
48
+ #
49
+ # @param ref [String, Addressable::URI]
50
+ # @param base [String, Addressable::URI]
51
+ # @return [Addressable::URI]
52
+ def normalize_ref(ref, base)
53
+ parse(ref).normalize_ref(base)
54
+ end
56
55
 
57
- ref_uri.fragment = "" if ref_uri.fragment.nil? || ref_uri.fragment.empty?
56
+ def absolutize_ref(ref, base)
57
+ parse(ref).absolutize_ref(base)
58
58
  end
59
+ end
59
60
 
60
- ref_uri
61
+ # Unencodes any percent encoded characters within a path component.
62
+ #
63
+ # @return [String]
64
+ def unescaped_path
65
+ self.class.unescape_component(path)
61
66
  end
62
67
 
63
- def self.parse(uri)
64
- if uri.is_a?(Addressable::URI)
65
- return uri.dup
68
+ # Strips the fragment from the URI.
69
+ # @return [Addressable::URI] a new instance of URI without a fragment
70
+ def strip_fragment
71
+ if fragment.nil? || fragment.empty?
72
+ self
66
73
  else
67
- @parse_cache ||= {}
68
- parsed_uri = @parse_cache[uri]
69
- if parsed_uri
70
- parsed_uri.dup
71
- else
72
- @parse_cache[uri] = Addressable::URI.parse(uri)
73
- end
74
+ merge(fragment: '')
74
75
  end
75
- rescue Addressable::URI::InvalidURIError => e
76
- raise JSON::Schema::UriError.new(e.message)
77
76
  end
78
77
 
79
- def self.strip_fragment(uri)
80
- parsed_uri = parse(uri)
81
- if parsed_uri.fragment.nil? || parsed_uri.fragment.empty?
82
- parsed_uri
78
+ # Normalizes the URI based on the provided base path.
79
+ #
80
+ # @param base_path [String] the base path to use for relative URIs. Defaults to the current working directory.
81
+ # @return [Addressable::URI] the normalized URI or nil
82
+ def normalized_uri(base_path = Dir.pwd)
83
+ if relative?
84
+ if path[0, 1] == '/'
85
+ self.class.file_uri(self)
86
+ else
87
+ self.class.file_uri(File.join(base_path, self))
88
+ end
83
89
  else
84
- parsed_uri.merge(:fragment => "")
90
+ self
85
91
  end
86
92
  end
87
93
 
88
- def self.file_uri(uri)
89
- parsed_uri = parse(uri)
94
+ # @param base [Addressable::URI, String]
95
+ # @return [Addressable::URI]
96
+ def normalize_ref(base)
97
+ base_uri = self.class.parse(base)
98
+ defer_validation do
99
+ if relative?
100
+ # Check for absolute path
101
+ path, fragment = to_s.split('#')
102
+ merge!(base_uri)
90
103
 
91
- Addressable::URI.convert_path(parsed_uri.path)
92
- end
104
+ if path.nil? || path == ''
105
+ self.path = base_uri.path
106
+ elsif path[0, 1] == '/'
107
+ self.path = Pathname.new(path).cleanpath.to_s
108
+ else
109
+ join!(path)
110
+ end
93
111
 
94
- def self.unescape_uri(uri)
95
- Addressable::URI.unescape(uri)
96
- end
112
+ self.fragment = fragment
113
+ end
97
114
 
98
- def self.unescaped_path(uri)
99
- parsed_uri = parse(uri)
115
+ self.fragment = '' if self.fragment.nil? || self.fragment.empty?
116
+ end
100
117
 
101
- Addressable::URI.unescape(parsed_uri.path)
118
+ self
102
119
  end
103
120
 
104
- def self.clear_cache
105
- @parse_cache = {}
106
- @normalize_cache = {}
121
+ # @param base [Addressable::URI, String]
122
+ # @return [Addressable::URI]
123
+ def absolutize_ref(base)
124
+ ref = strip_fragment
125
+ if ref.absolute?
126
+ ref
127
+ else
128
+ self.class.strip_fragment(base).join(ref.path).normalized_uri
129
+ end
107
130
  end
108
131
  end
109
132
  end