json_skooma 0.1.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.
- 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
|