json_skooma 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +22 -0
- data/LICENSE.txt +21 -0
- data/README.md +107 -0
- data/data/draft-2019-09/README.md +60 -0
- data/data/draft-2019-09/hyper-schema.json +26 -0
- data/data/draft-2019-09/links.json +91 -0
- data/data/draft-2019-09/meta/applicator.json +56 -0
- data/data/draft-2019-09/meta/content.json +17 -0
- data/data/draft-2019-09/meta/core.json +57 -0
- data/data/draft-2019-09/meta/format.json +14 -0
- data/data/draft-2019-09/meta/hyper-schema.json +29 -0
- data/data/draft-2019-09/meta/meta-data.json +37 -0
- data/data/draft-2019-09/meta/validation.json +98 -0
- data/data/draft-2019-09/output/hyper-schema.json +62 -0
- data/data/draft-2019-09/output/schema.json +86 -0
- data/data/draft-2019-09/output/verbose-example.json +130 -0
- data/data/draft-2019-09/schema.json +42 -0
- data/data/draft-2020-12/README.md +89 -0
- data/data/draft-2020-12/adr/README.md +15 -0
- data/data/draft-2020-12/archive/hyper-schema.json +28 -0
- data/data/draft-2020-12/archive/links.json +93 -0
- data/data/draft-2020-12/archive/meta/hyper-schema.json +30 -0
- data/data/draft-2020-12/hyper-schema.json +27 -0
- data/data/draft-2020-12/links.json +85 -0
- data/data/draft-2020-12/meta/applicator.json +48 -0
- data/data/draft-2020-12/meta/content.json +17 -0
- data/data/draft-2020-12/meta/core.json +51 -0
- data/data/draft-2020-12/meta/format-annotation.json +14 -0
- data/data/draft-2020-12/meta/format-assertion.json +14 -0
- data/data/draft-2020-12/meta/hyper-schema.json +29 -0
- data/data/draft-2020-12/meta/meta-data.json +37 -0
- data/data/draft-2020-12/meta/unevaluated.json +15 -0
- data/data/draft-2020-12/meta/validation.json +98 -0
- data/data/draft-2020-12/output/hyper-schema.json +62 -0
- data/data/draft-2020-12/output/schema.json +96 -0
- data/data/draft-2020-12/output/verbose-example.json +130 -0
- data/data/draft-2020-12/schema.json +58 -0
- data/lib/json_skooma/dialects/draft201909.rb +137 -0
- data/lib/json_skooma/dialects/draft202012.rb +146 -0
- data/lib/json_skooma/formatters.rb +135 -0
- data/lib/json_skooma/inflector.rb +13 -0
- data/lib/json_skooma/json_node.rb +100 -0
- data/lib/json_skooma/json_pointer.rb +79 -0
- data/lib/json_skooma/json_schema.rb +176 -0
- data/lib/json_skooma/keywords/applicator/additional_properties.rb +37 -0
- data/lib/json_skooma/keywords/applicator/all_of.rb +25 -0
- data/lib/json_skooma/keywords/applicator/any_of.rb +26 -0
- data/lib/json_skooma/keywords/applicator/contains.rb +31 -0
- data/lib/json_skooma/keywords/applicator/dependent_schemas.rb +35 -0
- data/lib/json_skooma/keywords/applicator/else.rb +22 -0
- data/lib/json_skooma/keywords/applicator/if.rb +17 -0
- data/lib/json_skooma/keywords/applicator/items.rb +36 -0
- data/lib/json_skooma/keywords/applicator/not.rb +19 -0
- data/lib/json_skooma/keywords/applicator/one_of.rb +35 -0
- data/lib/json_skooma/keywords/applicator/pattern_properties.rb +46 -0
- data/lib/json_skooma/keywords/applicator/prefix_items.rb +31 -0
- data/lib/json_skooma/keywords/applicator/properties.rb +34 -0
- data/lib/json_skooma/keywords/applicator/property_names.rb +25 -0
- data/lib/json_skooma/keywords/applicator/then.rb +22 -0
- data/lib/json_skooma/keywords/base.rb +74 -0
- data/lib/json_skooma/keywords/base_annotation.rb +12 -0
- data/lib/json_skooma/keywords/content/content_encoding.rb +12 -0
- data/lib/json_skooma/keywords/content/content_media_type.rb +12 -0
- data/lib/json_skooma/keywords/content/content_schema.rb +19 -0
- data/lib/json_skooma/keywords/core/anchor.rb +22 -0
- data/lib/json_skooma/keywords/core/comment.rb +12 -0
- data/lib/json_skooma/keywords/core/defs.rb +13 -0
- data/lib/json_skooma/keywords/core/dynamic_anchor.rb +22 -0
- data/lib/json_skooma/keywords/core/dynamic_ref.rb +67 -0
- data/lib/json_skooma/keywords/core/id.rb +28 -0
- data/lib/json_skooma/keywords/core/ref.rb +35 -0
- data/lib/json_skooma/keywords/core/schema.rb +26 -0
- data/lib/json_skooma/keywords/core/vocabulary.rb +34 -0
- data/lib/json_skooma/keywords/draft_2019_09/additional_items.rb +40 -0
- data/lib/json_skooma/keywords/draft_2019_09/items.rb +41 -0
- data/lib/json_skooma/keywords/draft_2019_09/recursive_anchor.rb +12 -0
- data/lib/json_skooma/keywords/draft_2019_09/recursive_ref.rb +46 -0
- data/lib/json_skooma/keywords/draft_2019_09/unevaluated_items.rb +56 -0
- data/lib/json_skooma/keywords/format_annotation/format.rb +27 -0
- data/lib/json_skooma/keywords/meta_data/default.rb +11 -0
- data/lib/json_skooma/keywords/meta_data/deprecated.rb +11 -0
- data/lib/json_skooma/keywords/meta_data/description.rb +11 -0
- data/lib/json_skooma/keywords/meta_data/examples.rb +11 -0
- data/lib/json_skooma/keywords/meta_data/read_only.rb +11 -0
- data/lib/json_skooma/keywords/meta_data/title.rb +11 -0
- data/lib/json_skooma/keywords/meta_data/write_only.rb +11 -0
- data/lib/json_skooma/keywords/unevaluated/unevaluated_items.rb +59 -0
- data/lib/json_skooma/keywords/unevaluated/unevaluated_properties.rb +43 -0
- data/lib/json_skooma/keywords/unknown.rb +21 -0
- data/lib/json_skooma/keywords/validation/const.rb +17 -0
- data/lib/json_skooma/keywords/validation/dependent_required.rb +24 -0
- data/lib/json_skooma/keywords/validation/enum.rb +19 -0
- data/lib/json_skooma/keywords/validation/exclusive_maximum.rb +18 -0
- data/lib/json_skooma/keywords/validation/exclusive_minimum.rb +18 -0
- data/lib/json_skooma/keywords/validation/max_contains.rb +24 -0
- data/lib/json_skooma/keywords/validation/max_items.rb +18 -0
- data/lib/json_skooma/keywords/validation/max_length.rb +18 -0
- data/lib/json_skooma/keywords/validation/max_properties.rb +18 -0
- data/lib/json_skooma/keywords/validation/maximum.rb +18 -0
- data/lib/json_skooma/keywords/validation/min_contains.rb +31 -0
- data/lib/json_skooma/keywords/validation/min_items.rb +18 -0
- data/lib/json_skooma/keywords/validation/min_length.rb +18 -0
- data/lib/json_skooma/keywords/validation/min_properties.rb +18 -0
- data/lib/json_skooma/keywords/validation/minimum.rb +18 -0
- data/lib/json_skooma/keywords/validation/multiple_of.rb +20 -0
- data/lib/json_skooma/keywords/validation/pattern.rb +23 -0
- data/lib/json_skooma/keywords/validation/required.rb +19 -0
- data/lib/json_skooma/keywords/validation/type.rb +26 -0
- data/lib/json_skooma/keywords/validation/unique_items.rb +20 -0
- data/lib/json_skooma/keywords/value_schemas.rb +87 -0
- data/lib/json_skooma/memoizable.rb +21 -0
- data/lib/json_skooma/metaschema.rb +32 -0
- data/lib/json_skooma/registry.rb +130 -0
- data/lib/json_skooma/result.rb +125 -0
- data/lib/json_skooma/sources.rb +55 -0
- data/lib/json_skooma/validators/base.rb +31 -0
- data/lib/json_skooma/validators/date.rb +18 -0
- data/lib/json_skooma/validators/date_time.rb +24 -0
- data/lib/json_skooma/validators/duration.rb +25 -0
- data/lib/json_skooma/validators/email.rb +36 -0
- data/lib/json_skooma/validators/hostname.rb +17 -0
- data/lib/json_skooma/validators/idn_email.rb +30 -0
- data/lib/json_skooma/validators/idn_hostname.rb +15 -0
- data/lib/json_skooma/validators/ipv4.rb +20 -0
- data/lib/json_skooma/validators/ipv6.rb +16 -0
- data/lib/json_skooma/validators/iri.rb +47 -0
- data/lib/json_skooma/validators/iri_reference.rb +15 -0
- data/lib/json_skooma/validators/json_pointer.rb +19 -0
- data/lib/json_skooma/validators/regex.rb +15 -0
- data/lib/json_skooma/validators/relative_json_pointer.rb +18 -0
- data/lib/json_skooma/validators/time.rb +32 -0
- data/lib/json_skooma/validators/uri.rb +60 -0
- data/lib/json_skooma/validators/uri_reference.rb +15 -0
- data/lib/json_skooma/validators/uri_template.rb +26 -0
- data/lib/json_skooma/validators/uuid.rb +15 -0
- data/lib/json_skooma/validators.rb +17 -0
- data/lib/json_skooma/version.rb +5 -0
- data/lib/json_skooma/vocabulary.rb +12 -0
- data/lib/json_skooma.rb +39 -0
- metadata +244 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "uri/idna"
|
4
|
+
|
5
|
+
module JSONSkooma
|
6
|
+
module Validators
|
7
|
+
class IdnHostname < Base
|
8
|
+
def call(data)
|
9
|
+
URI::IDNA.register(ulabel: data.value)
|
10
|
+
rescue URI::IDNA::Error => e
|
11
|
+
raise FormatError, "#{data} is not a valid IDN hostname: #{e.message}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "ipaddr"
|
4
|
+
|
5
|
+
module JSONSkooma
|
6
|
+
module Validators
|
7
|
+
class Ipv4 < Base
|
8
|
+
self.class
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def call(data)
|
12
|
+
ip = IPAddr.new "#{data.value}/24"
|
13
|
+
raise FormatError, "must be a valid IPv4 address" unless ip.ipv4?
|
14
|
+
rescue IPAddr::Error => e
|
15
|
+
raise FormatError, e.message
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "ipaddr"
|
4
|
+
|
5
|
+
module JSONSkooma
|
6
|
+
module Validators
|
7
|
+
class Ipv6 < Base
|
8
|
+
def call(data)
|
9
|
+
ip = IPAddr.new "#{data.value}/64"
|
10
|
+
raise FormatError, "must be a valid IPv6 address" unless ip.ipv6? && ip.zone_id.nil?
|
11
|
+
rescue IPAddr::Error => e
|
12
|
+
raise FormatError, e.message
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Validators
|
5
|
+
class Iri < Base
|
6
|
+
UCSCHAR = /[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\u{10000}-\u{1FFFD}]/.freeze
|
7
|
+
IPRIVATE = /[\uE000-\uF8FF\u{F0000}-\u{FFFFD}\u{10000}-\u{1FFFD}\u{20000}-\u{2FFFD}\u{30000}-\u{3FFFD}\u{40000}-\u{4FFFD}\u{50000}-\u{5FFFD}\u{60000}-\u{6FFFD}\u{70000}-\u{7FFFD}\u{80000}-\u{8FFFD}\u{90000}-\u{9FFFD}\u{A0000}-\u{AFFFD}\u{B0000}-\u{BFFFD}\u{C0000}-\u{CFFFD}\u{D0000}-\u{DFFFD}\u{E1000}-\u{EFFFD}]/.freeze
|
8
|
+
IUNRESERVED = /#{Uri::UNRESERVED}|#{UCSCHAR}/.freeze
|
9
|
+
|
10
|
+
IPCHAR = /#{IUNRESERVED}|#{Uri::PCT_ENCODED}|#{Uri::SUB_DELIMS}|[:@]/.freeze
|
11
|
+
|
12
|
+
IQUERY = /(?:#{IPCHAR}|#{IPRIVATE}|[?\/])*/.freeze
|
13
|
+
IFRAGMENT = /(?:#{IPCHAR}|[?\/])*/.freeze
|
14
|
+
|
15
|
+
ISEGMENT = /#{IPCHAR}*/.freeze
|
16
|
+
ISEGMENT_NZ = /#{IPCHAR}+/.freeze
|
17
|
+
ISEGMENT_NZ_NC = /(?:#{IUNRESERVED}|#{Uri::PCT_ENCODED}|#{Uri::SUB_DELIMS}|@)+/.freeze
|
18
|
+
|
19
|
+
IPATH_ABEMPTY = /(?:\/#{ISEGMENT})*/.freeze
|
20
|
+
IPATH_ABSOLUTE = /\/(?:#{ISEGMENT_NZ}(?:\/#{ISEGMENT})*)?/.freeze
|
21
|
+
IPATH_NOSCHEME = /#{ISEGMENT_NZ_NC}(?:\/#{ISEGMENT})*/.freeze
|
22
|
+
IPATH_ROOTLESS = /#{ISEGMENT_NZ}(?:\/#{ISEGMENT})*/.freeze
|
23
|
+
IPATH_OLD = /#{IPATH_ABEMPTY}|#{IPATH_ABSOLUTE}|#{IPATH_NOSCHEME}|#{IPATH_ROOTLESS}|/.freeze
|
24
|
+
|
25
|
+
IREG_NAME = /(?:#{IUNRESERVED}|#{Uri::PCT_ENCODED}|#{Uri::SUB_DELIMS})*/.freeze
|
26
|
+
IHOST = /#{Uri::IP_LITERAL}|#{Uri::IPV4_ADDRESS}|#{IREG_NAME}/.freeze
|
27
|
+
IUSERINFO = /(?:#{IUNRESERVED}|#{Uri::PCT_ENCODED}|#{Uri::SUB_DELIMS}|:)*/.freeze
|
28
|
+
IAUTHORITY = /(?:#{IUSERINFO}@)?#{IHOST}(?::#{Uri::PORT})?/.freeze
|
29
|
+
|
30
|
+
IHIER_PART = /(?:\/\/#{IAUTHORITY}#{IPATH_ABEMPTY})|#{IPATH_ABSOLUTE}|#{IPATH_ROOTLESS}|/.freeze
|
31
|
+
|
32
|
+
IRI = /#{Uri::SCHEME}:#{IHIER_PART}(?:\?#{IQUERY})?(?:##{IFRAGMENT})?/.freeze
|
33
|
+
|
34
|
+
IRELATIVE_PATH = /(?:\/\/#{IAUTHORITY}#{IPATH_ABEMPTY})|#{IPATH_ABSOLUTE}|#{IPATH_NOSCHEME}|/
|
35
|
+
IRELATIVE_REF = /#{IRELATIVE_PATH}(?:\?#{IQUERY})?(?:##{IFRAGMENT})?/.freeze
|
36
|
+
IRI_REFERENCE = /#{IRI}|#{IRELATIVE_REF}/.freeze
|
37
|
+
|
38
|
+
REGEX = /\A#{IRI}\z/.freeze
|
39
|
+
|
40
|
+
def call(data)
|
41
|
+
return if REGEX.match?(data.value)
|
42
|
+
|
43
|
+
raise FormatError, "#{data} is not a valid IRI"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Validators
|
5
|
+
class IriReference < Base
|
6
|
+
REGEX = /\A#{Iri::IRI_REFERENCE}\z/.freeze
|
7
|
+
|
8
|
+
def call(data)
|
9
|
+
return if REGEX.match?(data.value)
|
10
|
+
|
11
|
+
raise FormatError, "#{data} is not a valid IRI reference"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Validators
|
5
|
+
class JSONPointer < Base
|
6
|
+
ESC = /~[01]/
|
7
|
+
UNESC = /[\u0000-\u002E\u0030-\u007d\u007F-\u{10FFFF}]/
|
8
|
+
TOKEN = /(#{ESC}|#{UNESC})*/
|
9
|
+
JSON_POINTER = /(\/#{TOKEN})*/
|
10
|
+
REGEXP = /\A#{JSON_POINTER}\z/
|
11
|
+
|
12
|
+
def call(data)
|
13
|
+
return if REGEXP.match?(data)
|
14
|
+
|
15
|
+
raise FormatError, "#{data} is not a valid JSON pointer"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "regexp_parser"
|
4
|
+
|
5
|
+
module JSONSkooma
|
6
|
+
module Validators
|
7
|
+
class Regex < Base
|
8
|
+
def call(data)
|
9
|
+
Regexp::Parser.parse(data)
|
10
|
+
rescue Regexp::Scanner::ScannerError => e
|
11
|
+
raise FormatError, e.message
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Validators
|
5
|
+
class RelativeJSONPointer < Base
|
6
|
+
NN_INT = /0|[1-9][0-9]*/
|
7
|
+
INDEX = /[+-]#{NN_INT}/
|
8
|
+
RELATIVE_JSON_POINTER = /(#{NN_INT}(#{INDEX})?#{JSONPointer::JSON_POINTER})|(#{NN_INT}#)/
|
9
|
+
REGEXP = /\A#{RELATIVE_JSON_POINTER}\z/
|
10
|
+
|
11
|
+
def call(data)
|
12
|
+
return if REGEXP.match?(data)
|
13
|
+
|
14
|
+
raise FormatError, "#{data} is not a valid JSON pointer"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Validators
|
5
|
+
class Time < Base
|
6
|
+
REGEXP = /\A#{DateTime::FULL_TIME}\z/
|
7
|
+
|
8
|
+
def call(data)
|
9
|
+
match = REGEXP.match(data)
|
10
|
+
|
11
|
+
if match.nil? || !valid_leap_seconds?(match)
|
12
|
+
raise FormatError, "must be a valid RFC 3339 time string"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def valid_leap_seconds?(match)
|
19
|
+
return true if match[:s].to_i != 60
|
20
|
+
|
21
|
+
time = match[:h].to_i * 60 + match[:m].to_i
|
22
|
+
if match[:on]
|
23
|
+
sign = (match[:on] == "+") ? -1 : 1
|
24
|
+
time += sign * (match[:oh].to_i * 60 + match[:om].to_i)
|
25
|
+
time = time % (60 * 24)
|
26
|
+
end
|
27
|
+
leap_time = 23 * 60 + 59
|
28
|
+
time == leap_time
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Validators
|
5
|
+
class Uri < Base
|
6
|
+
SUB_DELIMS = /[!$&'()*+,;=]/.freeze
|
7
|
+
GEN_DELIMS = /[:\/?#\[\]@]/.freeze
|
8
|
+
RESERVED = /(?:#{GEN_DELIMS}|#{SUB_DELIMS})/.freeze
|
9
|
+
UNRESERVED = /[A-Za-z\d\-._~]/.freeze
|
10
|
+
PCT_ENCODED = /%\h{2}/.freeze
|
11
|
+
PCHAR = /(?:#{UNRESERVED}|#{PCT_ENCODED}|#{SUB_DELIMS}|[:@])/.freeze
|
12
|
+
FRAGMENT = /(?:#{PCHAR}|[?\/])*/.freeze
|
13
|
+
QUERY = FRAGMENT
|
14
|
+
|
15
|
+
SEGMENT = /#{PCHAR}*/.freeze
|
16
|
+
SEGMENT_NZ = /#{PCHAR}+/.freeze
|
17
|
+
SEGMENT_NZ_NC = /(?:#{UNRESERVED}|#{PCT_ENCODED}|#{SUB_DELIMS}|@)+/.freeze
|
18
|
+
|
19
|
+
PATH_ABEMPTY = /(?:\/#{SEGMENT})*/.freeze
|
20
|
+
PATH_ABSOLUTE = /\/(?:#{SEGMENT_NZ}(?:\/#{SEGMENT})*)?/.freeze
|
21
|
+
PATH_NOSCHEME = /#{SEGMENT_NZ_NC}(?:\/#{SEGMENT})*/.freeze
|
22
|
+
PATH_ROOTLESS = /#{SEGMENT_NZ}(?:\/#{SEGMENT})*/.freeze
|
23
|
+
PATH = /(?:#{PATH_ABEMPTY}|#{PATH_ABSOLUTE}|#{PATH_NOSCHEME}|#{PATH_ROOTLESS})?/.freeze
|
24
|
+
|
25
|
+
IPV4_ADDRESS = /((25[0-5]|(2[0-4]|1\d|[1-9])?\d)\.?\b){4}/
|
26
|
+
H16 = /\h{1,4}/
|
27
|
+
LS32 = /(?:#{H16}:#{H16})|#{IPV4_ADDRESS}/
|
28
|
+
IPV6_ADDRESS = /(?:#{H16}:){6}#{LS32}|::(?:#{H16}:){5}#{LS32}|(?:#{H16})?::(?:#{H16}:){4}#{LS32}|(?:(?:#{H16}:){0,1}#{H16})?::(?:#{H16}:){3}#{LS32}|(?:(?:#{H16}:){0,2}#{H16})?::(?:#{H16}:){2}#{LS32}|(?:(?:#{H16}:){0,3}#{H16})?::(?:#{H16}:){1}#{LS32}|(?:(?:#{H16}:){0,4}#{H16})?::#{LS32}|(?:(?:#{H16}:){0,5}#{H16})?::#{H16}|(?:(?:#{H16}:){0,6}#{H16})?::/.freeze
|
29
|
+
|
30
|
+
IPV_FUTURE = /v\h+\.(?:#{UNRESERVED}|#{SUB_DELIMS}|:)+/.freeze
|
31
|
+
IP_LITERAL = /\[(?:#{IPV6_ADDRESS}|#{IPV_FUTURE})\]/.freeze
|
32
|
+
|
33
|
+
PORT = /\d*/.freeze
|
34
|
+
REG_NAME = /(?:#{UNRESERVED}|#{PCT_ENCODED}|#{SUB_DELIMS})*/.freeze
|
35
|
+
HOST = /(?:#{IP_LITERAL}|#{IPV4_ADDRESS}|#{REG_NAME})/.freeze
|
36
|
+
USERINFO = /(?:#{UNRESERVED}|#{PCT_ENCODED}|#{SUB_DELIMS}|:)*/.freeze
|
37
|
+
AUTHORITY = /(?:#{USERINFO}@)?#{HOST}(?::#{PORT})?/.freeze
|
38
|
+
|
39
|
+
SCHEME = /[a-zA-Z][a-zA-Z\d+.-]*/.freeze
|
40
|
+
|
41
|
+
HIER_PART = /(?:(?:\/\/#{AUTHORITY}#{PATH_ABEMPTY})|#{PATH_ABSOLUTE}|#{PATH_ROOTLESS})?/.freeze
|
42
|
+
|
43
|
+
URI = /#{SCHEME}:#{HIER_PART}(?:\?#{QUERY})?(?:##{FRAGMENT})?/.freeze
|
44
|
+
|
45
|
+
# ABSOLUTE_URI = /#{SCHEME}:#{HIER_PART}(?:\?#{QUERY})?/.freeze
|
46
|
+
|
47
|
+
RELATIVE_PART = /(?:(?:\/\/#{AUTHORITY}#{PATH_ABEMPTY})|#{PATH_ABSOLUTE}|#{PATH_NOSCHEME})?/.freeze
|
48
|
+
RELATIVE_REF = /#{RELATIVE_PART}(?:\?#{QUERY})?(?:##{FRAGMENT})?/.freeze
|
49
|
+
URI_REFERENCE = /#{URI}|#{RELATIVE_REF}/.freeze
|
50
|
+
|
51
|
+
REGEX = /\A#{URI}\z/.freeze
|
52
|
+
|
53
|
+
def call(data)
|
54
|
+
return if REGEX.match?(data.value)
|
55
|
+
|
56
|
+
raise FormatError, "#{data} is not a valid URI"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Validators
|
5
|
+
class UriReference < Base
|
6
|
+
REGEX = /\A#{Uri::URI_REFERENCE}\z/.freeze
|
7
|
+
|
8
|
+
def call(data)
|
9
|
+
return if REGEX.match?(data.value)
|
10
|
+
|
11
|
+
raise FormatError, "#{data} is not a valid URI reference"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Validators
|
5
|
+
class UriTemplate < Base
|
6
|
+
PCT = /%\h\h/
|
7
|
+
VAR_CHAR = /[A-Za-z\d_]|(#{PCT})/
|
8
|
+
VAR_NAME = /#{VAR_CHAR}(\.?#{VAR_CHAR})*/
|
9
|
+
MOD4 = /(:[1-9]\d{0,3}|(\*)?)/
|
10
|
+
VAR_SPEC = /#{VAR_NAME}(#{MOD4})?/
|
11
|
+
VAR_LIST = /#{VAR_SPEC}(,#{VAR_SPEC})*/
|
12
|
+
OPERATOR = /[+#.\/;?&=,!@|]/
|
13
|
+
EXPRESSION = /\{#{OPERATOR}?#{VAR_LIST}\}/
|
14
|
+
LITERALS = /[^\x00-\x20\x7F"'%<>\\^`{|}]/
|
15
|
+
URI_TEMPLATE = /((#{LITERALS})|(#{EXPRESSION}))*/
|
16
|
+
|
17
|
+
REGEXP = /\A#{URI_TEMPLATE}\z/
|
18
|
+
|
19
|
+
def call(data)
|
20
|
+
return if REGEXP.match?(data)
|
21
|
+
|
22
|
+
raise FormatError, "#{data} is not a valid URI template"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Validators
|
5
|
+
class Uuid < Base
|
6
|
+
REGEXP = /\A\h{8}-\h{4}-\h{4}-\h{4}-\h{12}\z/
|
7
|
+
|
8
|
+
def call(data)
|
9
|
+
return if REGEXP.match?(data)
|
10
|
+
|
11
|
+
raise FormatError, "#{data} is not a valid UUID"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Validators
|
5
|
+
class FormatError < StandardError; end
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_accessor :validators
|
9
|
+
|
10
|
+
def register(name, validator)
|
11
|
+
validators[name] = validator
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
self.validators = {}
|
16
|
+
end
|
17
|
+
end
|
data/lib/json_skooma.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
require "zeitwerk"
|
5
|
+
|
6
|
+
require_relative "json_skooma/inflector"
|
7
|
+
|
8
|
+
loader = Zeitwerk::Loader.for_gem
|
9
|
+
loader.inflector = JSONSkooma::Inflector.new
|
10
|
+
loader.setup
|
11
|
+
|
12
|
+
module JSONSkooma
|
13
|
+
DATA_DIR = File.join(__dir__, "..", "data")
|
14
|
+
|
15
|
+
class Error < StandardError; end
|
16
|
+
|
17
|
+
class << self
|
18
|
+
attr_accessor :dialects
|
19
|
+
|
20
|
+
def register_dialect(version_key, dialect)
|
21
|
+
dialects[version_key] = dialect
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_registry(*schema_dialects, name: Registry::DEFAULT_NAME, assert_formats: false)
|
25
|
+
registry = Registry.new(name: name)
|
26
|
+
|
27
|
+
schema_dialects.each do |version_key|
|
28
|
+
dialects.fetch(version_key).call(registry, assert_formats: assert_formats)
|
29
|
+
end
|
30
|
+
|
31
|
+
registry
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
self.dialects = {}
|
36
|
+
|
37
|
+
register_dialect("2019-09", Dialects::Draft201909)
|
38
|
+
register_dialect("2020-12", Dialects::Draft202012)
|
39
|
+
end
|
metadata
ADDED
@@ -0,0 +1,244 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: json_skooma
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Svyatoslav Kryukov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-09-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: zeitwerk
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: hana
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: regexp_parser
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: uri-idna
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.1'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.1'
|
69
|
+
description: I bring some sugar for your JSONs.
|
70
|
+
email:
|
71
|
+
- s.g.kryukov@yandex.ru
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- CHANGELOG.md
|
77
|
+
- LICENSE.txt
|
78
|
+
- README.md
|
79
|
+
- data/draft-2019-09/README.md
|
80
|
+
- data/draft-2019-09/hyper-schema.json
|
81
|
+
- data/draft-2019-09/links.json
|
82
|
+
- data/draft-2019-09/meta/applicator.json
|
83
|
+
- data/draft-2019-09/meta/content.json
|
84
|
+
- data/draft-2019-09/meta/core.json
|
85
|
+
- data/draft-2019-09/meta/format.json
|
86
|
+
- data/draft-2019-09/meta/hyper-schema.json
|
87
|
+
- data/draft-2019-09/meta/meta-data.json
|
88
|
+
- data/draft-2019-09/meta/validation.json
|
89
|
+
- data/draft-2019-09/output/hyper-schema.json
|
90
|
+
- data/draft-2019-09/output/schema.json
|
91
|
+
- data/draft-2019-09/output/verbose-example.json
|
92
|
+
- data/draft-2019-09/schema.json
|
93
|
+
- data/draft-2020-12/README.md
|
94
|
+
- data/draft-2020-12/adr/README.md
|
95
|
+
- data/draft-2020-12/archive/hyper-schema.json
|
96
|
+
- data/draft-2020-12/archive/links.json
|
97
|
+
- data/draft-2020-12/archive/meta/hyper-schema.json
|
98
|
+
- data/draft-2020-12/hyper-schema.json
|
99
|
+
- data/draft-2020-12/links.json
|
100
|
+
- data/draft-2020-12/meta/applicator.json
|
101
|
+
- data/draft-2020-12/meta/content.json
|
102
|
+
- data/draft-2020-12/meta/core.json
|
103
|
+
- data/draft-2020-12/meta/format-annotation.json
|
104
|
+
- data/draft-2020-12/meta/format-assertion.json
|
105
|
+
- data/draft-2020-12/meta/hyper-schema.json
|
106
|
+
- data/draft-2020-12/meta/meta-data.json
|
107
|
+
- data/draft-2020-12/meta/unevaluated.json
|
108
|
+
- data/draft-2020-12/meta/validation.json
|
109
|
+
- data/draft-2020-12/output/hyper-schema.json
|
110
|
+
- data/draft-2020-12/output/schema.json
|
111
|
+
- data/draft-2020-12/output/verbose-example.json
|
112
|
+
- data/draft-2020-12/schema.json
|
113
|
+
- lib/json_skooma.rb
|
114
|
+
- lib/json_skooma/dialects/draft201909.rb
|
115
|
+
- lib/json_skooma/dialects/draft202012.rb
|
116
|
+
- lib/json_skooma/formatters.rb
|
117
|
+
- lib/json_skooma/inflector.rb
|
118
|
+
- lib/json_skooma/json_node.rb
|
119
|
+
- lib/json_skooma/json_pointer.rb
|
120
|
+
- lib/json_skooma/json_schema.rb
|
121
|
+
- lib/json_skooma/keywords/applicator/additional_properties.rb
|
122
|
+
- lib/json_skooma/keywords/applicator/all_of.rb
|
123
|
+
- lib/json_skooma/keywords/applicator/any_of.rb
|
124
|
+
- lib/json_skooma/keywords/applicator/contains.rb
|
125
|
+
- lib/json_skooma/keywords/applicator/dependent_schemas.rb
|
126
|
+
- lib/json_skooma/keywords/applicator/else.rb
|
127
|
+
- lib/json_skooma/keywords/applicator/if.rb
|
128
|
+
- lib/json_skooma/keywords/applicator/items.rb
|
129
|
+
- lib/json_skooma/keywords/applicator/not.rb
|
130
|
+
- lib/json_skooma/keywords/applicator/one_of.rb
|
131
|
+
- lib/json_skooma/keywords/applicator/pattern_properties.rb
|
132
|
+
- lib/json_skooma/keywords/applicator/prefix_items.rb
|
133
|
+
- lib/json_skooma/keywords/applicator/properties.rb
|
134
|
+
- lib/json_skooma/keywords/applicator/property_names.rb
|
135
|
+
- lib/json_skooma/keywords/applicator/then.rb
|
136
|
+
- lib/json_skooma/keywords/base.rb
|
137
|
+
- lib/json_skooma/keywords/base_annotation.rb
|
138
|
+
- lib/json_skooma/keywords/content/content_encoding.rb
|
139
|
+
- lib/json_skooma/keywords/content/content_media_type.rb
|
140
|
+
- lib/json_skooma/keywords/content/content_schema.rb
|
141
|
+
- lib/json_skooma/keywords/core/anchor.rb
|
142
|
+
- lib/json_skooma/keywords/core/comment.rb
|
143
|
+
- lib/json_skooma/keywords/core/defs.rb
|
144
|
+
- lib/json_skooma/keywords/core/dynamic_anchor.rb
|
145
|
+
- lib/json_skooma/keywords/core/dynamic_ref.rb
|
146
|
+
- lib/json_skooma/keywords/core/id.rb
|
147
|
+
- lib/json_skooma/keywords/core/ref.rb
|
148
|
+
- lib/json_skooma/keywords/core/schema.rb
|
149
|
+
- lib/json_skooma/keywords/core/vocabulary.rb
|
150
|
+
- lib/json_skooma/keywords/draft_2019_09/additional_items.rb
|
151
|
+
- lib/json_skooma/keywords/draft_2019_09/items.rb
|
152
|
+
- lib/json_skooma/keywords/draft_2019_09/recursive_anchor.rb
|
153
|
+
- lib/json_skooma/keywords/draft_2019_09/recursive_ref.rb
|
154
|
+
- lib/json_skooma/keywords/draft_2019_09/unevaluated_items.rb
|
155
|
+
- lib/json_skooma/keywords/format_annotation/format.rb
|
156
|
+
- lib/json_skooma/keywords/meta_data/default.rb
|
157
|
+
- lib/json_skooma/keywords/meta_data/deprecated.rb
|
158
|
+
- lib/json_skooma/keywords/meta_data/description.rb
|
159
|
+
- lib/json_skooma/keywords/meta_data/examples.rb
|
160
|
+
- lib/json_skooma/keywords/meta_data/read_only.rb
|
161
|
+
- lib/json_skooma/keywords/meta_data/title.rb
|
162
|
+
- lib/json_skooma/keywords/meta_data/write_only.rb
|
163
|
+
- lib/json_skooma/keywords/unevaluated/unevaluated_items.rb
|
164
|
+
- lib/json_skooma/keywords/unevaluated/unevaluated_properties.rb
|
165
|
+
- lib/json_skooma/keywords/unknown.rb
|
166
|
+
- lib/json_skooma/keywords/validation/const.rb
|
167
|
+
- lib/json_skooma/keywords/validation/dependent_required.rb
|
168
|
+
- lib/json_skooma/keywords/validation/enum.rb
|
169
|
+
- lib/json_skooma/keywords/validation/exclusive_maximum.rb
|
170
|
+
- lib/json_skooma/keywords/validation/exclusive_minimum.rb
|
171
|
+
- lib/json_skooma/keywords/validation/max_contains.rb
|
172
|
+
- lib/json_skooma/keywords/validation/max_items.rb
|
173
|
+
- lib/json_skooma/keywords/validation/max_length.rb
|
174
|
+
- lib/json_skooma/keywords/validation/max_properties.rb
|
175
|
+
- lib/json_skooma/keywords/validation/maximum.rb
|
176
|
+
- lib/json_skooma/keywords/validation/min_contains.rb
|
177
|
+
- lib/json_skooma/keywords/validation/min_items.rb
|
178
|
+
- lib/json_skooma/keywords/validation/min_length.rb
|
179
|
+
- lib/json_skooma/keywords/validation/min_properties.rb
|
180
|
+
- lib/json_skooma/keywords/validation/minimum.rb
|
181
|
+
- lib/json_skooma/keywords/validation/multiple_of.rb
|
182
|
+
- lib/json_skooma/keywords/validation/pattern.rb
|
183
|
+
- lib/json_skooma/keywords/validation/required.rb
|
184
|
+
- lib/json_skooma/keywords/validation/type.rb
|
185
|
+
- lib/json_skooma/keywords/validation/unique_items.rb
|
186
|
+
- lib/json_skooma/keywords/value_schemas.rb
|
187
|
+
- lib/json_skooma/memoizable.rb
|
188
|
+
- lib/json_skooma/metaschema.rb
|
189
|
+
- lib/json_skooma/registry.rb
|
190
|
+
- lib/json_skooma/result.rb
|
191
|
+
- lib/json_skooma/sources.rb
|
192
|
+
- lib/json_skooma/validators.rb
|
193
|
+
- lib/json_skooma/validators/base.rb
|
194
|
+
- lib/json_skooma/validators/date.rb
|
195
|
+
- lib/json_skooma/validators/date_time.rb
|
196
|
+
- lib/json_skooma/validators/duration.rb
|
197
|
+
- lib/json_skooma/validators/email.rb
|
198
|
+
- lib/json_skooma/validators/hostname.rb
|
199
|
+
- lib/json_skooma/validators/idn_email.rb
|
200
|
+
- lib/json_skooma/validators/idn_hostname.rb
|
201
|
+
- lib/json_skooma/validators/ipv4.rb
|
202
|
+
- lib/json_skooma/validators/ipv6.rb
|
203
|
+
- lib/json_skooma/validators/iri.rb
|
204
|
+
- lib/json_skooma/validators/iri_reference.rb
|
205
|
+
- lib/json_skooma/validators/json_pointer.rb
|
206
|
+
- lib/json_skooma/validators/regex.rb
|
207
|
+
- lib/json_skooma/validators/relative_json_pointer.rb
|
208
|
+
- lib/json_skooma/validators/time.rb
|
209
|
+
- lib/json_skooma/validators/uri.rb
|
210
|
+
- lib/json_skooma/validators/uri_reference.rb
|
211
|
+
- lib/json_skooma/validators/uri_template.rb
|
212
|
+
- lib/json_skooma/validators/uuid.rb
|
213
|
+
- lib/json_skooma/version.rb
|
214
|
+
- lib/json_skooma/vocabulary.rb
|
215
|
+
homepage: https://github.com/skryukov/json_skooma
|
216
|
+
licenses:
|
217
|
+
- MIT
|
218
|
+
metadata:
|
219
|
+
bug_tracker_uri: https://github.com/skryukov/json_skooma/issues
|
220
|
+
changelog_uri: https://github.com/skryukov/json_skooma/blob/main/CHANGELOG.md
|
221
|
+
documentation_uri: https://github.com/skryukov/json_skooma/blob/main/README.md
|
222
|
+
homepage_uri: https://github.com/skryukov/json_skooma
|
223
|
+
source_code_uri: https://github.com/skryukov/json_skooma
|
224
|
+
rubygems_mfa_required: 'true'
|
225
|
+
post_install_message:
|
226
|
+
rdoc_options: []
|
227
|
+
require_paths:
|
228
|
+
- lib
|
229
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
230
|
+
requirements:
|
231
|
+
- - ">="
|
232
|
+
- !ruby/object:Gem::Version
|
233
|
+
version: 2.6.0
|
234
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
235
|
+
requirements:
|
236
|
+
- - ">="
|
237
|
+
- !ruby/object:Gem::Version
|
238
|
+
version: '0'
|
239
|
+
requirements: []
|
240
|
+
rubygems_version: 3.3.7
|
241
|
+
signing_key:
|
242
|
+
specification_version: 4
|
243
|
+
summary: I bring some sugar for your JSONs.
|
244
|
+
test_files: []
|