json_schemer 1.0.0 → 1.0.2

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: 93264835a6cd46b1c657876bda6a68c53a130c36390e84c316f6ffad3d00194f
4
- data.tar.gz: 6bc567c682cb103cc673dade1f0a46a0b7500973acf6915acd7d7093de7a74e3
3
+ metadata.gz: 57b910832ad52857f782a9e0c9d17247b3d298493e2876d4d87dcc7bd72c623e
4
+ data.tar.gz: 4f36b7e698c0de3b9cac3d5fc54572dfd2288f28e0e29c7475f162cf5e878c95
5
5
  SHA512:
6
- metadata.gz: 5e0fe51563031e2bcce3331cd13b251a0e8007740c9d5b70e59a03b5151114e221ad50b24358094ccc33b31fcabb0b62e76674a966d5c8bf3ed872accd839f4f
7
- data.tar.gz: 2835c05bbb368718f20e8ec435def32619b3876d7c1e78259f92ac8b57d0f45b27cc6a9481fc101efe8e0456054ddfffc8d05ad60f37b63f8e2475e95b81e368
6
+ metadata.gz: 6cb5d43a92de555b7fb72febcd305990b94ed7764bfb300a158ec3ee864e4d7c9944afa4ff4726ce30e57af0325a8bb9e295e281b4b981cc459f44ddd3e507da
7
+ data.tar.gz: f41eab50d37542486c230fcbe14a57c7dbb6564acac9815a3ff4b9977a7683a9703162d59650e34c3dc640693fa919c6b607403e575b233c77468fcc39f0703b
data/Gemfile.lock CHANGED
@@ -1,11 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- json_schemer (1.0.0)
4
+ json_schemer (1.0.2)
5
5
  hana (~> 1.3)
6
6
  regexp_parser (~> 2.0)
7
7
  simpleidn (~> 0.2)
8
- uri_template (~> 0.7)
9
8
 
10
9
  GEM
11
10
  remote: https://rubygems.org/
@@ -27,7 +26,6 @@ GEM
27
26
  unf_ext
28
27
  unf (0.1.4-java)
29
28
  unf_ext (0.0.8.2)
30
- uri_template (0.7.0)
31
29
 
32
30
  PLATFORMS
33
31
  java
data/json_schemer.gemspec CHANGED
@@ -30,5 +30,4 @@ Gem::Specification.new do |spec|
30
30
  spec.add_runtime_dependency "hana", "~> 1.3"
31
31
  spec.add_runtime_dependency "regexp_parser", "~> 2.0"
32
32
  spec.add_runtime_dependency "simpleidn", "~> 0.2"
33
- spec.add_runtime_dependency "uri_template", "~> 0.7"
34
33
  end
@@ -2,19 +2,26 @@
2
2
  module JSONSchemer
3
3
  class EcmaRegexp
4
4
  class Syntax < Regexp::Syntax::Base
5
- implements :anchor, Anchor::Extended
6
- implements :assertion, Assertion::All
7
- implements :backref, Backreference::Plain + Backreference::Name
8
- implements :escape, Escape::Basic + %i[control backspace form_feed newline carriage tab vertical_tab] + Escape::Unicode + Escape::Meta + Escape::Hex + Escape::Octal
9
- implements :property, UnicodeProperty::All
10
- implements :nonproperty, UnicodeProperty::All
11
- implements :free_space, %i[whitespace]
12
- implements :group, Group::Basic + Group::Named + Group::Passive
13
- implements :literal, Literal::All
14
- implements :meta, Meta::Extended
15
- implements :quantifier, Quantifier::Greedy + Quantifier::Reluctant + Quantifier::Interval + Quantifier::IntervalReluctant
16
- implements :set, CharacterSet::Basic
17
- implements :type, CharacterType::Extended
5
+ # regexp_parser >= 2.3.0 uses syntax classes directly instead of instances
6
+ # :nocov:
7
+ SYNTAX = respond_to?(:implements) ? self : new
8
+ # :nocov:
9
+ SYNTAX.implements :anchor, Anchor::Extended
10
+ SYNTAX.implements :assertion, Assertion::All
11
+ # literal %i[number] to support regexp_parser < 2.2.0 (Backreference::Plain)
12
+ SYNTAX.implements :backref, %i[number] + Backreference::Name
13
+ # :meta_sequence, :bell, and :escape are not supported in ecma
14
+ SYNTAX.implements :escape, Escape::Basic + (Escape::Control - %i[meta_sequence]) + (Escape::ASCII - %i[bell escape]) + Escape::Unicode + Escape::Meta + Escape::Hex + Escape::Octal
15
+ SYNTAX.implements :property, UnicodeProperty::All
16
+ SYNTAX.implements :nonproperty, UnicodeProperty::All
17
+ # :comment is not supported in ecma
18
+ SYNTAX.implements :free_space, (FreeSpace::All - %i[comment])
19
+ SYNTAX.implements :group, Group::Basic + Group::Named + Group::Passive
20
+ SYNTAX.implements :literal, Literal::All
21
+ SYNTAX.implements :meta, Meta::Extended
22
+ SYNTAX.implements :quantifier, Quantifier::Greedy + Quantifier::Reluctant + Quantifier::Interval + Quantifier::IntervalReluctant
23
+ SYNTAX.implements :set, CharacterSet::Basic
24
+ SYNTAX.implements :type, CharacterType::Extended
18
25
  end
19
26
 
20
27
  RUBY_EQUIVALENTS = {
@@ -31,7 +38,7 @@ module JSONSchemer
31
38
  class << self
32
39
  def ruby_equivalent(pattern)
33
40
  Regexp::Scanner.scan(pattern).map do |type, token, text|
34
- Syntax.check!(*Syntax.normalize(type, token))
41
+ Syntax::SYNTAX.check!(*Syntax::SYNTAX.normalize(type, token))
35
42
  RUBY_EQUIVALENTS.dig(type, token) || text
36
43
  rescue Regexp::Syntax::NotImplementedError
37
44
  raise InvalidEcmaRegexp, "invalid token #{text.inspect} (#{type}:#{token}) in #{pattern.inspect}"
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+ module JSONSchemer
3
+ module Format
4
+ module URITemplate
5
+ # https://datatracker.ietf.org/doc/html/rfc6570
6
+ PCT_ENCODED = '%\h{2}' # pct-encoded = "%" HEXDIG HEXDIG
7
+ EXPLODE = '\*' # explode = "*"
8
+ MAX_LENGTH = '[1-9]\d{0,3}' # max-length = %x31-39 0*3DIGIT ; positive integer < 10000
9
+ PREFIX = ":#{MAX_LENGTH}" # prefix = ":" max-length
10
+ MODIFIER_LEVEL4 = "#{PREFIX}|#{EXPLODE}" # modifier-level4 = prefix / explode
11
+ VARCHAR = "(\\w|#{PCT_ENCODED})" # varchar = ALPHA / DIGIT / "_" / pct-encoded
12
+ VARNAME = "#{VARCHAR}(\\.?#{VARCHAR})*" # varname = varchar *( ["."] varchar )
13
+ VARSPEC = "#{VARNAME}(#{MODIFIER_LEVEL4})?" # varspec = varname [ modifier-level4 ]
14
+ VARIABLE_LIST = "#{VARSPEC}(,#{VARSPEC})*" # variable-list = varspec *( "," varspec )
15
+ OPERATOR = '[+#./;?&=,!@|]' # operator = op-level2 / op-level3 / op-reserve
16
+ # op-level2 = "+" / "#"
17
+ # op-level3 = "." / "/" / ";" / "?" / "&"
18
+ # op-reserve = "=" / "," / "!" / "@" / "|"
19
+ EXPRESSION = "{#{OPERATOR}?#{VARIABLE_LIST}}" # expression = "{" [ operator ] variable-list "}"
20
+ LITERALS = "[^\\x00-\\x20\\x7F\"%'<>\\\\^`{|}]|#{PCT_ENCODED}" # literals = %x21 / %x23-24 / %x26 / %x28-3B / %x3D / %x3F-5B
21
+ # / %x5D / %x5F / %x61-7A / %x7E / ucschar / iprivate
22
+ # / pct-encoded
23
+ # ; any Unicode character except: CTL, SP,
24
+ # ; DQUOTE, "'", "%" (aside from pct-encoded),
25
+ # ; "<", ">", "\", "^", "`", "{", "|", "}"
26
+ URI_TEMPLATE = "(#{LITERALS}|#{EXPRESSION})*" # URI-Template = *( literals / expression )
27
+ URI_TEMPLATE_REGEX = /\A#{URI_TEMPLATE}\z/
28
+
29
+ def valid_uri_template?(data)
30
+ URI_TEMPLATE_REGEX.match?(data)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -2,6 +2,7 @@
2
2
  module JSONSchemer
3
3
  module Format
4
4
  include Hostname
5
+ include URITemplate
5
6
 
6
7
  # this is no good
7
8
  EMAIL_REGEX = /\A[^@\s]+@([\p{L}\d-]+\.)+[\p{L}\d\-]{2,}\z/i.freeze
@@ -65,7 +66,7 @@ module JSONSchemer
65
66
  def valid_date_time?(data)
66
67
  return false if HOUR_24_REGEX.match?(data)
67
68
  datetime = DateTime.rfc3339(data)
68
- return false if LEAP_SECOND_REGEX.match?(data) && datetime.to_time.utc.strftime('%H:%M') != '23:59'
69
+ return false if LEAP_SECOND_REGEX.match?(data) && datetime.new_offset.strftime('%H:%M') != '23:59'
69
70
  DATE_TIME_OFFSET_REGEX.match?(data)
70
71
  rescue ArgumentError
71
72
  false
@@ -115,13 +116,6 @@ module JSONSchemer
115
116
  end.force_encoding(Encoding::US_ASCII)
116
117
  end
117
118
 
118
- def valid_uri_template?(data)
119
- URITemplate.new(data)
120
- true
121
- rescue URITemplate::Invalid
122
- false
123
- end
124
-
125
119
  def valid_json_pointer?(data)
126
120
  JSON_POINTER_REGEX.match?(data)
127
121
  end
@@ -32,7 +32,7 @@ module JSONSchemer
32
32
  end
33
33
 
34
34
  JSON_POINTER_TOKEN_ESCAPE_CHARS = { '~' => '~0', '/' => '~1' }
35
- JSON_POINTER_TOKEN_ESCAPE_REGEXP = Regexp.union(JSON_POINTER_TOKEN_ESCAPE_CHARS.keys)
35
+ JSON_POINTER_TOKEN_ESCAPE_REGEX = Regexp.union(JSON_POINTER_TOKEN_ESCAPE_CHARS.keys)
36
36
 
37
37
  class << self
38
38
  def draft_name
@@ -330,10 +330,10 @@ module JSONSchemer
330
330
  child(resolve_ref(ref_uri), base_uri: ref_uri)
331
331
  end
332
332
 
333
- ref_schema, ref_schema_pointer = ref_object.ids[ref_uri] || [ref_object.root, '']
333
+ ref_schema, ref_schema_pointer, ref_parent_base_uri = ref_object.ids[ref_uri] || [ref_object.root, '', ref_uri]
334
334
 
335
335
  ref_uri_pointer_parts = Hana::Pointer.parse(URI.decode_www_form_component(ref_uri_pointer))
336
- schema, base_uri = ref_uri_pointer_parts.reduce([ref_schema, ref_uri]) do |(obj, uri), token|
336
+ schema, base_uri = ref_uri_pointer_parts.reduce([ref_schema, ref_parent_base_uri]) do |(obj, uri), token|
337
337
  if obj.is_a?(Array)
338
338
  [obj.fetch(token.to_i), uri]
339
339
  else
@@ -624,7 +624,7 @@ module JSONSchemer
624
624
  end
625
625
 
626
626
  def escape_json_pointer_token(token)
627
- token.gsub(JSON_POINTER_TOKEN_ESCAPE_REGEXP, JSON_POINTER_TOKEN_ESCAPE_CHARS)
627
+ token.gsub(JSON_POINTER_TOKEN_ESCAPE_REGEX, JSON_POINTER_TOKEN_ESCAPE_CHARS)
628
628
  end
629
629
 
630
630
  def join_uri(a, b)
@@ -646,16 +646,18 @@ module JSONSchemer
646
646
  if schema.is_a?(Array)
647
647
  schema.each_with_index { |subschema, index| resolve_ids(subschema, ids, base_uri, "#{pointer}/#{index}") }
648
648
  elsif schema.is_a?(Hash)
649
- uri = join_uri(base_uri, schema[id_keyword])
649
+ if schema.key?(id_keyword)
650
+ parent_base_uri = base_uri
651
+ base_uri = join_uri(base_uri, schema[id_keyword])
652
+ ids[base_uri] ||= [schema, pointer, parent_base_uri]
653
+ end
650
654
  schema.each do |key, value|
651
655
  case key
652
- when id_keyword
653
- ids[uri] ||= [schema, pointer]
654
656
  when 'items', 'allOf', 'anyOf', 'oneOf', 'additionalItems', 'contains', 'additionalProperties', 'propertyNames', 'if', 'then', 'else', 'not'
655
- resolve_ids(value, ids, uri, "#{pointer}/#{key}")
657
+ resolve_ids(value, ids, base_uri, "#{pointer}/#{key}")
656
658
  when 'properties', 'patternProperties', 'definitions', 'dependencies'
657
659
  value.each do |subkey, subvalue|
658
- resolve_ids(subvalue, ids, uri, "#{pointer}/#{key}/#{subkey}")
660
+ resolve_ids(subvalue, ids, base_uri, "#{pointer}/#{key}/#{subkey}")
659
661
  end
660
662
  end
661
663
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module JSONSchemer
3
- VERSION = '1.0.0'
3
+ VERSION = '1.0.2'
4
4
  end
data/lib/json_schemer.rb CHANGED
@@ -12,10 +12,10 @@ require 'uri'
12
12
  require 'hana'
13
13
  require 'regexp_parser'
14
14
  require 'simpleidn'
15
- require 'uri_template'
16
15
 
17
16
  require 'json_schemer/version'
18
17
  require 'json_schemer/format/hostname'
18
+ require 'json_schemer/format/uri_template'
19
19
  require 'json_schemer/format'
20
20
  require 'json_schemer/errors'
21
21
  require 'json_schemer/cached_resolver'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json_schemer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Harsha
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-26 00:00:00.000000000 Z
11
+ date: 2023-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -108,20 +108,6 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0.2'
111
- - !ruby/object:Gem::Dependency
112
- name: uri_template
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - "~>"
116
- - !ruby/object:Gem::Version
117
- version: '0.7'
118
- type: :runtime
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - "~>"
123
- - !ruby/object:Gem::Version
124
- version: '0.7'
125
111
  description:
126
112
  email:
127
113
  - davishmcclurg@gmail.com
@@ -150,6 +136,7 @@ files:
150
136
  - lib/json_schemer/errors.rb
151
137
  - lib/json_schemer/format.rb
152
138
  - lib/json_schemer/format/hostname.rb
139
+ - lib/json_schemer/format/uri_template.rb
153
140
  - lib/json_schemer/schema/base.rb
154
141
  - lib/json_schemer/schema/draft4.json
155
142
  - lib/json_schemer/schema/draft4.rb