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,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module Draft201909
|
6
|
+
class UnevaluatedItems < Base
|
7
|
+
self.key = "unevaluatedItems"
|
8
|
+
self.instance_types = %w[array]
|
9
|
+
self.value_schema = :schema
|
10
|
+
self.depends_on = %w[
|
11
|
+
items additionalItems
|
12
|
+
if then else allOf anyOf oneOf not
|
13
|
+
]
|
14
|
+
|
15
|
+
def evaluate(instance, result)
|
16
|
+
last_evaluated_item = -1
|
17
|
+
|
18
|
+
result.parent.collect_annotations(instance, "items") do |i|
|
19
|
+
next result.discard if i == true
|
20
|
+
|
21
|
+
last_evaluated_item = i if i > last_evaluated_item
|
22
|
+
end
|
23
|
+
|
24
|
+
result.parent.collect_annotations(instance, "additionalItems") do |i|
|
25
|
+
next result.discard if i == true
|
26
|
+
end
|
27
|
+
|
28
|
+
result.parent.collect_annotations(instance, "unevaluatedItems") do |i|
|
29
|
+
next result.discard if i == true
|
30
|
+
end
|
31
|
+
|
32
|
+
annotation = nil
|
33
|
+
error = []
|
34
|
+
|
35
|
+
instance.each_with_index do |item, index|
|
36
|
+
next if last_evaluated_item >= index
|
37
|
+
|
38
|
+
if json.evaluate(item, result).passed?
|
39
|
+
annotation = true
|
40
|
+
else
|
41
|
+
error << index
|
42
|
+
# reset to passed for the next iteration
|
43
|
+
result.success
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
if error.any?
|
48
|
+
result.failure(error)
|
49
|
+
else
|
50
|
+
result.annotate(annotation)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module FormatAnnotation
|
6
|
+
class Format < Base
|
7
|
+
self.key = "format"
|
8
|
+
|
9
|
+
def initialize(parent_schema, value)
|
10
|
+
super
|
11
|
+
if parent_schema.registry.format_enabled?(value)
|
12
|
+
@validator = Validators.validators[value]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def evaluate(instance, result)
|
17
|
+
result.annotate(json)
|
18
|
+
return result.skip_assertion unless @validator&.assert?(instance)
|
19
|
+
|
20
|
+
@validator.call(instance)
|
21
|
+
rescue Validators::FormatError => e
|
22
|
+
result.failure("The instance is invalid against the #{json.value} format: #{e}")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module Unevaluated
|
6
|
+
class UnevaluatedItems < Base
|
7
|
+
self.key = "unevaluatedItems"
|
8
|
+
self.instance_types = %w[array]
|
9
|
+
self.value_schema = :schema
|
10
|
+
self.depends_on = %w[
|
11
|
+
prefixItems items contains
|
12
|
+
if then else allOf anyOf oneOf not
|
13
|
+
]
|
14
|
+
|
15
|
+
def evaluate(instance, result)
|
16
|
+
last_evaluated_item = -1
|
17
|
+
|
18
|
+
result.parent.collect_annotations(instance, "prefixItems") do |i|
|
19
|
+
next result.discard if i == true
|
20
|
+
|
21
|
+
last_evaluated_item = i if i > last_evaluated_item
|
22
|
+
end
|
23
|
+
|
24
|
+
result.parent.collect_annotations(instance, "items") do |i|
|
25
|
+
next result.discard if i == true
|
26
|
+
end
|
27
|
+
|
28
|
+
result.parent.collect_annotations(instance, "unevaluatedItems") do |i|
|
29
|
+
next result.discard if i == true
|
30
|
+
end
|
31
|
+
|
32
|
+
contains_indices = Set.new
|
33
|
+
result.parent.collect_annotations(instance, "contains") { |i| contains_indices += Set.new(i) }
|
34
|
+
annotation = nil
|
35
|
+
error = []
|
36
|
+
|
37
|
+
instance.each_with_index do |item, index|
|
38
|
+
next if last_evaluated_item >= index
|
39
|
+
next if contains_indices.include?(index)
|
40
|
+
|
41
|
+
if json.evaluate(item, result).passed?
|
42
|
+
annotation = true
|
43
|
+
else
|
44
|
+
error << index
|
45
|
+
# reset to passed for the next iteration
|
46
|
+
result.success
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
if error.any?
|
51
|
+
result.failure(error)
|
52
|
+
else
|
53
|
+
result.annotate(annotation)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module Unevaluated
|
6
|
+
class UnevaluatedProperties < Base
|
7
|
+
self.key = "unevaluatedProperties"
|
8
|
+
self.instance_types = %w[object]
|
9
|
+
self.value_schema = :schema
|
10
|
+
self.depends_on = %w[
|
11
|
+
properties patternProperties additionalProperties
|
12
|
+
if then else dependentSchemas allOf anyOf oneOf not
|
13
|
+
]
|
14
|
+
|
15
|
+
def evaluate(instance, result)
|
16
|
+
evaluated_names = Set.new
|
17
|
+
result.parent.collect_annotations(instance, "properties") { |name| evaluated_names += Set.new(name) }
|
18
|
+
result.parent.collect_annotations(instance, "patternProperties") { |name| evaluated_names += Set.new(name) }
|
19
|
+
result.parent.collect_annotations(instance, "additionalProperties") { |name| evaluated_names += Set.new(name) }
|
20
|
+
result.parent.collect_annotations(instance, "unevaluatedProperties") { |name| evaluated_names += Set.new(name) }
|
21
|
+
|
22
|
+
annotation = []
|
23
|
+
error = []
|
24
|
+
instance.each do |name, item|
|
25
|
+
next if evaluated_names.include?(name)
|
26
|
+
|
27
|
+
if json.evaluate(item, result).passed?
|
28
|
+
annotation << name
|
29
|
+
else
|
30
|
+
error << name
|
31
|
+
# reset to success for the next iteration
|
32
|
+
result.success
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
return result.failure(error) if error.any?
|
37
|
+
|
38
|
+
result.annotate(annotation)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module Unknown
|
6
|
+
class << self
|
7
|
+
def [](key)
|
8
|
+
@unknown_keywords ||= {}
|
9
|
+
@unknown_keywords[key] ||= Class.new(Keywords::Base) do
|
10
|
+
self.key = key
|
11
|
+
|
12
|
+
def evaluate(instance, result)
|
13
|
+
result.annotate(json.value)
|
14
|
+
result.skip_assertion
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module Validation
|
6
|
+
class Const < Base
|
7
|
+
self.key = "const"
|
8
|
+
|
9
|
+
def evaluate(instance, result)
|
10
|
+
return if instance == json
|
11
|
+
|
12
|
+
result.failure("The instance value #{instance.value.inspect} must be equal to the defined constant #{json.value.inspect}")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module Validation
|
6
|
+
class DependentRequired < Base
|
7
|
+
self.key = "dependentRequired"
|
8
|
+
self.instance_types = "object"
|
9
|
+
|
10
|
+
def evaluate(instance, result)
|
11
|
+
missing = {}
|
12
|
+
json.each do |name, dependents|
|
13
|
+
next unless instance.key?(name)
|
14
|
+
|
15
|
+
missing_deps = dependents.reject { |dep| instance.key?(dep) }
|
16
|
+
missing[name] = missing_deps if missing_deps.any?
|
17
|
+
end
|
18
|
+
|
19
|
+
result.failure("The object is missing dependent properties #{missing}") if missing.any?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module Validation
|
6
|
+
class Enum < Base
|
7
|
+
self.key = "enum"
|
8
|
+
|
9
|
+
def evaluate(instance, result)
|
10
|
+
return if json.include?(instance)
|
11
|
+
|
12
|
+
result.failure(
|
13
|
+
"The instance value #{instance.value.inspect} must be equal to one of the elements in the defined enumeration: #{json.value}"
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module Validation
|
6
|
+
class ExclusiveMaximum < Base
|
7
|
+
self.key = "exclusiveMaximum"
|
8
|
+
self.instance_types = "number"
|
9
|
+
|
10
|
+
def evaluate(instance, result)
|
11
|
+
if instance >= json
|
12
|
+
result.failure("The value must be less than #{json.value})")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module Validation
|
6
|
+
class ExclusiveMinimum < Base
|
7
|
+
self.key = "exclusiveMinimum"
|
8
|
+
self.instance_types = "number"
|
9
|
+
|
10
|
+
def evaluate(instance, result)
|
11
|
+
if instance <= json
|
12
|
+
result.failure("The value must be greater than #{json.value})")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module Validation
|
6
|
+
class MaxContains < Base
|
7
|
+
self.key = "maxContains"
|
8
|
+
self.instance_types = %w[array]
|
9
|
+
self.depends_on = %w[contains]
|
10
|
+
|
11
|
+
def evaluate(instance, result)
|
12
|
+
contains = result.sibling(instance, "contains")
|
13
|
+
return if contains.nil?
|
14
|
+
|
15
|
+
if contains.annotation && contains.annotation.length > json
|
16
|
+
result.failure(
|
17
|
+
"The array has too many elements matching the contains subschema (maximum #{json.value})"
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module Validation
|
6
|
+
class MaxItems < Base
|
7
|
+
self.key = "maxItems"
|
8
|
+
self.instance_types = "array"
|
9
|
+
|
10
|
+
def evaluate(instance, result)
|
11
|
+
if instance.length > json
|
12
|
+
result.failure("The array has too many elements (maximum #{json.value})")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module Validation
|
6
|
+
class MaxLength < Base
|
7
|
+
self.key = "maxLength"
|
8
|
+
self.instance_types = "string"
|
9
|
+
|
10
|
+
def evaluate(instance, result)
|
11
|
+
if instance.length > json
|
12
|
+
result.failure("The text is too long (maximum #{json.value} characters))")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module Validation
|
6
|
+
class MaxProperties < Base
|
7
|
+
self.key = "maxProperties"
|
8
|
+
self.instance_types = "object"
|
9
|
+
|
10
|
+
def evaluate(instance, result)
|
11
|
+
if instance.length > json
|
12
|
+
result.failure("The object has too many properties (maximum #{json.value})")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module Validation
|
6
|
+
class Maximum < Base
|
7
|
+
self.key = "maximum"
|
8
|
+
self.instance_types = "number"
|
9
|
+
|
10
|
+
def evaluate(instance, result)
|
11
|
+
if instance > json
|
12
|
+
result.failure("The value may not be greater than #{json.value})")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module Validation
|
6
|
+
class MinContains < Base
|
7
|
+
self.key = "minContains"
|
8
|
+
self.instance_types = %w[array]
|
9
|
+
self.depends_on = %w[contains maxContains]
|
10
|
+
|
11
|
+
def evaluate(instance, result)
|
12
|
+
contains = result.sibling(instance, "contains")
|
13
|
+
return if contains.nil?
|
14
|
+
|
15
|
+
contains_count = contains.annotation&.count || 0
|
16
|
+
|
17
|
+
valid = contains_count >= json
|
18
|
+
|
19
|
+
if valid && !contains.valid?
|
20
|
+
max_contains = result.sibling(instance, "maxContains")
|
21
|
+
contains.success if !max_contains || max_contains.valid?
|
22
|
+
end
|
23
|
+
|
24
|
+
return if valid
|
25
|
+
|
26
|
+
result.failure("The array has too few elements matching the `contains` subschema (minimum #{json.value})")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module Validation
|
6
|
+
class MinItems < Base
|
7
|
+
self.key = "minItems"
|
8
|
+
self.instance_types = "array"
|
9
|
+
|
10
|
+
def evaluate(instance, result)
|
11
|
+
if instance.length < json
|
12
|
+
result.failure("The array has too few elements (minimum #{json.value})")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module Validation
|
6
|
+
class MinLength < Base
|
7
|
+
self.key = "minLength"
|
8
|
+
self.instance_types = "string"
|
9
|
+
|
10
|
+
def evaluate(instance, result)
|
11
|
+
if instance.length < json
|
12
|
+
result.failure("The text is too short (minimum #{json.value} characters))")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module Validation
|
6
|
+
class MinProperties < Base
|
7
|
+
self.key = "minProperties"
|
8
|
+
self.instance_types = "object"
|
9
|
+
|
10
|
+
def evaluate(instance, result)
|
11
|
+
if instance.length < json
|
12
|
+
result.failure("The object has too few properties (minimum #{json.value})")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module Validation
|
6
|
+
class Minimum < Base
|
7
|
+
self.key = "minimum"
|
8
|
+
self.instance_types = "number"
|
9
|
+
|
10
|
+
def evaluate(instance, result)
|
11
|
+
if instance < json
|
12
|
+
result.failure("The value may not be less than #{json.value})")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bigdecimal"
|
4
|
+
|
5
|
+
module JSONSkooma
|
6
|
+
module Keywords
|
7
|
+
module Validation
|
8
|
+
class MultipleOf < Base
|
9
|
+
self.key = "multipleOf"
|
10
|
+
self.instance_types = "number"
|
11
|
+
|
12
|
+
def evaluate(instance, result)
|
13
|
+
if BigDecimal(instance.value.to_s).modulo(BigDecimal(json.value.to_s)).nonzero?
|
14
|
+
result.failure("The value must be a multiple of #{json.value}")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module Validation
|
6
|
+
class Pattern < Base
|
7
|
+
self.key = "pattern"
|
8
|
+
self.instance_types = %w[string]
|
9
|
+
|
10
|
+
def initialize(parent_schema, value)
|
11
|
+
super
|
12
|
+
@regexp = Regexp.new(value)
|
13
|
+
end
|
14
|
+
|
15
|
+
def evaluate(instance, result)
|
16
|
+
return if @regexp.match(instance)
|
17
|
+
|
18
|
+
result.failure("The text must match the regular expression #{json.value}")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSONSkooma
|
4
|
+
module Keywords
|
5
|
+
module Validation
|
6
|
+
class Required < Base
|
7
|
+
self.key = "required"
|
8
|
+
self.instance_types = "object"
|
9
|
+
|
10
|
+
def evaluate(instance, result)
|
11
|
+
missing_keys = json - instance.keys
|
12
|
+
return if missing_keys.empty?
|
13
|
+
|
14
|
+
result.failure("The object is missing required properties #{json.value}")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|