json_schemer 1.0.3 → 2.0.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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +1 -6
  3. data/CHANGELOG.md +25 -0
  4. data/Gemfile.lock +1 -1
  5. data/README.md +137 -14
  6. data/json_schemer.gemspec +1 -1
  7. data/lib/json_schemer/draft201909/meta.rb +335 -0
  8. data/lib/json_schemer/draft201909/vocab/applicator.rb +104 -0
  9. data/lib/json_schemer/draft201909/vocab/core.rb +45 -0
  10. data/lib/json_schemer/draft201909/vocab.rb +31 -0
  11. data/lib/json_schemer/draft202012/meta.rb +361 -0
  12. data/lib/json_schemer/draft202012/vocab/applicator.rb +382 -0
  13. data/lib/json_schemer/draft202012/vocab/content.rb +44 -0
  14. data/lib/json_schemer/draft202012/vocab/core.rb +154 -0
  15. data/lib/json_schemer/draft202012/vocab/format_annotation.rb +31 -0
  16. data/lib/json_schemer/draft202012/vocab/format_assertion.rb +29 -0
  17. data/lib/json_schemer/draft202012/vocab/meta_data.rb +30 -0
  18. data/lib/json_schemer/draft202012/vocab/unevaluated.rb +94 -0
  19. data/lib/json_schemer/draft202012/vocab/validation.rb +286 -0
  20. data/lib/json_schemer/draft202012/vocab.rb +103 -0
  21. data/lib/json_schemer/draft4/meta.rb +155 -0
  22. data/lib/json_schemer/draft4/vocab/validation.rb +39 -0
  23. data/lib/json_schemer/draft4/vocab.rb +18 -0
  24. data/lib/json_schemer/draft6/meta.rb +161 -0
  25. data/lib/json_schemer/draft6/vocab.rb +16 -0
  26. data/lib/json_schemer/draft7/meta.rb +178 -0
  27. data/lib/json_schemer/draft7/vocab/validation.rb +69 -0
  28. data/lib/json_schemer/draft7/vocab.rb +30 -0
  29. data/lib/json_schemer/errors.rb +1 -0
  30. data/lib/json_schemer/format/duration.rb +23 -0
  31. data/lib/json_schemer/format/json_pointer.rb +18 -0
  32. data/lib/json_schemer/format.rb +52 -26
  33. data/lib/json_schemer/keyword.rb +41 -0
  34. data/lib/json_schemer/location.rb +25 -0
  35. data/lib/json_schemer/openapi.rb +40 -0
  36. data/lib/json_schemer/openapi30/document.rb +1673 -0
  37. data/lib/json_schemer/openapi30/meta.rb +26 -0
  38. data/lib/json_schemer/openapi30/vocab/base.rb +18 -0
  39. data/lib/json_schemer/openapi30/vocab.rb +12 -0
  40. data/lib/json_schemer/openapi31/document.rb +1559 -0
  41. data/lib/json_schemer/openapi31/meta.rb +128 -0
  42. data/lib/json_schemer/openapi31/vocab/base.rb +89 -0
  43. data/lib/json_schemer/openapi31/vocab.rb +18 -0
  44. data/lib/json_schemer/output.rb +55 -0
  45. data/lib/json_schemer/result.rb +168 -0
  46. data/lib/json_schemer/schema.rb +390 -0
  47. data/lib/json_schemer/version.rb +1 -1
  48. data/lib/json_schemer.rb +197 -24
  49. metadata +42 -10
  50. data/lib/json_schemer/schema/base.rb +0 -677
  51. data/lib/json_schemer/schema/draft4.json +0 -149
  52. data/lib/json_schemer/schema/draft4.rb +0 -44
  53. data/lib/json_schemer/schema/draft6.json +0 -155
  54. data/lib/json_schemer/schema/draft6.rb +0 -25
  55. data/lib/json_schemer/schema/draft7.json +0 -172
  56. data/lib/json_schemer/schema/draft7.rb +0 -32
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+ module JSONSchemer
3
+ module Draft201909
4
+ module Vocab
5
+ module Applicator
6
+ class Items < Keyword
7
+ def error(formatted_instance_location:, **)
8
+ "array items at #{formatted_instance_location} do not match `items` schema(s)"
9
+ end
10
+
11
+ def parse
12
+ if value.is_a?(Array)
13
+ value.map.with_index do |subschema, index|
14
+ subschema(subschema, index.to_s)
15
+ end
16
+ else
17
+ subschema(value)
18
+ end
19
+ end
20
+
21
+ def validate(instance, instance_location, keyword_location, context)
22
+ return result(instance, instance_location, keyword_location, true) unless instance.is_a?(Array)
23
+
24
+ nested = if parsed.is_a?(Array)
25
+ instance.take(parsed.size).map.with_index do |item, index|
26
+ parsed.fetch(index).validate_instance(item, join_location(instance_location, index.to_s), join_location(keyword_location, index.to_s), context)
27
+ end
28
+ else
29
+ instance.map.with_index do |item, index|
30
+ parsed.validate_instance(item, join_location(instance_location, index.to_s), keyword_location, context)
31
+ end
32
+ end
33
+
34
+ result(instance, instance_location, keyword_location, nested.all?(&:valid), nested, :annotation => (nested.size - 1))
35
+ end
36
+ end
37
+
38
+ class AdditionalItems < Keyword
39
+ def error(formatted_instance_location:, **)
40
+ "array items at #{formatted_instance_location} do not match `additionalItems` schema"
41
+ end
42
+
43
+ def parse
44
+ subschema(value)
45
+ end
46
+
47
+ def validate(instance, instance_location, keyword_location, context)
48
+ return result(instance, instance_location, keyword_location, true) unless instance.is_a?(Array)
49
+
50
+ evaluated_index = context.adjacent_results[Items]&.annotation
51
+ offset = evaluated_index ? (evaluated_index + 1) : instance.size
52
+
53
+ nested = instance.slice(offset..-1).map.with_index do |item, index|
54
+ parsed.validate_instance(item, join_location(instance_location, (offset + index).to_s), keyword_location, context)
55
+ end
56
+
57
+ result(instance, instance_location, keyword_location, nested.all?(&:valid), nested, :annotation => nested.any?)
58
+ end
59
+ end
60
+
61
+ class UnevaluatedItems < Keyword
62
+ def error(formatted_instance_location:, **)
63
+ "array items at #{formatted_instance_location} do not match `unevaluatedItems` schema"
64
+ end
65
+
66
+ def parse
67
+ subschema(value)
68
+ end
69
+
70
+ def validate(instance, instance_location, keyword_location, context)
71
+ return result(instance, instance_location, keyword_location, true) unless instance.is_a?(Array)
72
+
73
+ unevaluated_items = instance.size.times.to_set
74
+
75
+ context.adjacent_results.each_value do |adjacent_result|
76
+ collect_unevaluated_items(adjacent_result, instance_location, unevaluated_items)
77
+ end
78
+
79
+ nested = unevaluated_items.map do |index|
80
+ parsed.validate_instance(instance.fetch(index), join_location(instance_location, index.to_s), keyword_location, context)
81
+ end
82
+
83
+ result(instance, instance_location, keyword_location, nested.all?(&:valid), nested, :annotation => nested.any?)
84
+ end
85
+
86
+ private
87
+
88
+ def collect_unevaluated_items(result, instance_location, unevaluated_items)
89
+ return unless result.valid && result.instance_location == instance_location
90
+ case result.source
91
+ when Items
92
+ unevaluated_items.subtract(0..result.annotation)
93
+ when AdditionalItems, UnevaluatedItems
94
+ unevaluated_items.clear if result.annotation
95
+ end
96
+ result.nested&.each do |nested_result|
97
+ collect_unevaluated_items(nested_result, instance_location, unevaluated_items)
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+ module JSONSchemer
3
+ module Draft201909
4
+ module Vocab
5
+ module Core
6
+ class RecursiveAnchor < Keyword
7
+ def parse
8
+ root.resources[:dynamic][schema.base_uri] = schema if value == true
9
+ value
10
+ end
11
+ end
12
+
13
+ class RecursiveRef < Keyword
14
+ def ref_uri
15
+ @ref_uri ||= URI.join(schema.base_uri, value)
16
+ end
17
+
18
+ def ref_schema
19
+ @ref_schema ||= root.resolve_ref(ref_uri)
20
+ end
21
+
22
+ def recursive_anchor
23
+ return @recursive_anchor if defined?(@recursive_anchor)
24
+ @recursive_anchor = (ref_schema.parsed['$recursiveAnchor']&.parsed == true)
25
+ end
26
+
27
+ def validate(instance, instance_location, keyword_location, context)
28
+ schema = ref_schema
29
+
30
+ if recursive_anchor
31
+ context.dynamic_scope.each do |ancestor|
32
+ if ancestor.root.resources.fetch(:dynamic).key?(ancestor.base_uri)
33
+ schema = ancestor.root.resources.fetch(:dynamic).fetch(ancestor.base_uri)
34
+ break
35
+ end
36
+ end
37
+ end
38
+
39
+ schema.validate_instance(instance, instance_location, keyword_location, context)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+ module JSONSchemer
3
+ module Draft201909
4
+ module Vocab
5
+ CORE = Draft202012::Vocab::CORE.dup
6
+ CORE.delete('$dynamicAnchor')
7
+ CORE.delete('$dynamicRef')
8
+ CORE.merge!(
9
+ # https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-02#section-8.2.4.2
10
+ '$recursiveAnchor' => Core::RecursiveAnchor,
11
+ '$recursiveRef' => Core::RecursiveRef
12
+ )
13
+
14
+ APPLICATOR = Draft202012::Vocab::APPLICATOR.dup
15
+ APPLICATOR.delete('prefixItems')
16
+ APPLICATOR.merge!(
17
+ # https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-02#section-9.3.1
18
+ 'items' => Applicator::Items,
19
+ 'additionalItems' => Applicator::AdditionalItems,
20
+ 'unevaluatedItems' => Applicator::UnevaluatedItems,
21
+ # https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-02#section-9.3.2.4
22
+ 'unevaluatedProperties' => Draft202012::Vocab::Unevaluated::UnevaluatedProperties
23
+ )
24
+
25
+ VALIDATION = Draft202012::Vocab::VALIDATION
26
+ FORMAT = Draft202012::Vocab::FORMAT_ANNOTATION
27
+ CONTENT = Draft202012::Vocab::CONTENT
28
+ META_DATA = Draft202012::Vocab::META_DATA
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,361 @@
1
+ # frozen_string_literal: true
2
+ module JSONSchemer
3
+ module Draft202012
4
+ BASE_URI = URI('https://json-schema.org/draft/2020-12/schema')
5
+ SCHEMA = {
6
+ '$schema' => 'https://json-schema.org/draft/2020-12/schema',
7
+ '$id' => 'https://json-schema.org/draft/2020-12/schema',
8
+ '$vocabulary' => {
9
+ 'https://json-schema.org/draft/2020-12/vocab/core' => true,
10
+ 'https://json-schema.org/draft/2020-12/vocab/applicator' => true,
11
+ 'https://json-schema.org/draft/2020-12/vocab/unevaluated' => true,
12
+ 'https://json-schema.org/draft/2020-12/vocab/validation' => true,
13
+ 'https://json-schema.org/draft/2020-12/vocab/meta-data' => true,
14
+ 'https://json-schema.org/draft/2020-12/vocab/format-annotation' => true,
15
+ 'https://json-schema.org/draft/2020-12/vocab/content' => true
16
+ },
17
+ '$dynamicAnchor' => 'meta',
18
+ 'title' => 'Core and Validation specifications meta-schema',
19
+ 'allOf' => [
20
+ {'$ref' => 'meta/core'},
21
+ {'$ref' => 'meta/applicator'},
22
+ {'$ref' => 'meta/unevaluated'},
23
+ {'$ref' => 'meta/validation'},
24
+ {'$ref' => 'meta/meta-data'},
25
+ {'$ref' => 'meta/format-annotation'},
26
+ {'$ref' => 'meta/content'}
27
+ ],
28
+ 'type' => ['object', 'boolean'],
29
+ '$comment' => 'This meta-schema also defines keywords that have appeared in previous drafts in order to prevent incompatible extensions as they remain in common use.',
30
+ 'properties' => {
31
+ 'definitions' => {
32
+ '$comment' => '"definitions" has been replaced by "$defs".',
33
+ 'type' => 'object',
34
+ 'additionalProperties' => { '$dynamicRef' => '#meta' },
35
+ 'deprecated' => true,
36
+ 'default' => {}
37
+ },
38
+ 'dependencies' => {
39
+ '$comment' => '"dependencies" has been split and replaced by "dependentSchemas" and "dependentRequired" in order to serve their differing semantics.',
40
+ 'type' => 'object',
41
+ 'additionalProperties' => {
42
+ 'anyOf' => [
43
+ { '$dynamicRef' => '#meta' },
44
+ { '$ref' => 'meta/validation#/$defs/stringArray' }
45
+ ]
46
+ },
47
+ 'deprecated' => true,
48
+ 'default' => {}
49
+ },
50
+ '$recursiveAnchor' => {
51
+ '$comment' => '"$recursiveAnchor" has been replaced by "$dynamicAnchor".',
52
+ '$ref' => 'meta/core#/$defs/anchorString',
53
+ 'deprecated' => true
54
+ },
55
+ '$recursiveRef' => {
56
+ '$comment' => '"$recursiveRef" has been replaced by "$dynamicRef".',
57
+ '$ref' => 'meta/core#/$defs/uriReferenceString',
58
+ 'deprecated' => true
59
+ }
60
+ }
61
+ }
62
+
63
+ module Meta
64
+ CORE = {
65
+ '$schema' => 'https://json-schema.org/draft/2020-12/schema',
66
+ '$id' => 'https://json-schema.org/draft/2020-12/meta/core',
67
+ '$vocabulary' => {
68
+ 'https://json-schema.org/draft/2020-12/vocab/core' => true
69
+ },
70
+ '$dynamicAnchor' => 'meta',
71
+ 'title' => 'Core vocabulary meta-schema',
72
+ 'type' => ['object', 'boolean'],
73
+ 'properties' => {
74
+ '$id' => {
75
+ '$ref' => '#/$defs/uriReferenceString',
76
+ '$comment' => 'Non-empty fragments not allowed.',
77
+ 'pattern' => '^[^#]*#?$'
78
+ },
79
+ '$schema' => { '$ref' => '#/$defs/uriString' },
80
+ '$ref' => { '$ref' => '#/$defs/uriReferenceString' },
81
+ '$anchor' => { '$ref' => '#/$defs/anchorString' },
82
+ '$dynamicRef' => { '$ref' => '#/$defs/uriReferenceString' },
83
+ '$dynamicAnchor' => { '$ref' => '#/$defs/anchorString' },
84
+ '$vocabulary' => {
85
+ 'type' => 'object',
86
+ 'propertyNames' => { '$ref' => '#/$defs/uriString' },
87
+ 'additionalProperties' => {
88
+ 'type' => 'boolean'
89
+ }
90
+ },
91
+ '$comment' => {
92
+ 'type' => 'string'
93
+ },
94
+ '$defs' => {
95
+ 'type' => 'object',
96
+ 'additionalProperties' => { '$dynamicRef' => '#meta' }
97
+ }
98
+ },
99
+ '$defs' => {
100
+ 'anchorString' => {
101
+ 'type' => 'string',
102
+ 'pattern' => '^[A-Za-z_][-A-Za-z0-9._]*$'
103
+ },
104
+ 'uriString' => {
105
+ 'type' => 'string',
106
+ 'format' => 'uri'
107
+ },
108
+ 'uriReferenceString' => {
109
+ 'type' => 'string',
110
+ 'format' => 'uri-reference'
111
+ }
112
+ }
113
+ }
114
+ APPLICATOR = {
115
+ '$schema' => 'https://json-schema.org/draft/2020-12/schema',
116
+ '$id' => 'https://json-schema.org/draft/2020-12/meta/applicator',
117
+ '$vocabulary' => {
118
+ 'https://json-schema.org/draft/2020-12/vocab/applicator' => true
119
+ },
120
+ '$dynamicAnchor' => 'meta',
121
+ 'title' => 'Applicator vocabulary meta-schema',
122
+ 'type' => ['object', 'boolean'],
123
+ 'properties' => {
124
+ 'prefixItems' => { '$ref' => '#/$defs/schemaArray' },
125
+ 'items' => { '$dynamicRef' => '#meta' },
126
+ 'contains' => { '$dynamicRef' => '#meta' },
127
+ 'additionalProperties' => { '$dynamicRef' => '#meta' },
128
+ 'properties' => {
129
+ 'type' => 'object',
130
+ 'additionalProperties' => { '$dynamicRef' => '#meta' },
131
+ 'default' => {}
132
+ },
133
+ 'patternProperties' => {
134
+ 'type' => 'object',
135
+ 'additionalProperties' => { '$dynamicRef' => '#meta' },
136
+ 'propertyNames' => { 'format' => 'regex' },
137
+ 'default' => {}
138
+ },
139
+ 'dependentSchemas' => {
140
+ 'type' => 'object',
141
+ 'additionalProperties' => { '$dynamicRef' => '#meta' },
142
+ 'default' => {}
143
+ },
144
+ 'propertyNames' => { '$dynamicRef' => '#meta' },
145
+ 'if' => { '$dynamicRef' => '#meta' },
146
+ 'then' => { '$dynamicRef' => '#meta' },
147
+ 'else' => { '$dynamicRef' => '#meta' },
148
+ 'allOf' => { '$ref' => '#/$defs/schemaArray' },
149
+ 'anyOf' => { '$ref' => '#/$defs/schemaArray' },
150
+ 'oneOf' => { '$ref' => '#/$defs/schemaArray' },
151
+ 'not' => { '$dynamicRef' => '#meta' }
152
+ },
153
+ '$defs' => {
154
+ 'schemaArray' => {
155
+ 'type' => 'array',
156
+ 'minItems' => 1,
157
+ 'items' => { '$dynamicRef' => '#meta' }
158
+ }
159
+ }
160
+ }
161
+ UNEVALUATED = {
162
+ '$schema' => 'https://json-schema.org/draft/2020-12/schema',
163
+ '$id' => 'https://json-schema.org/draft/2020-12/meta/unevaluated',
164
+ '$vocabulary' => {
165
+ 'https://json-schema.org/draft/2020-12/vocab/unevaluated' => true
166
+ },
167
+ '$dynamicAnchor' => 'meta',
168
+ 'title' => 'Unevaluated applicator vocabulary meta-schema',
169
+ 'type' => ['object', 'boolean'],
170
+ 'properties' => {
171
+ 'unevaluatedItems' => { '$dynamicRef' => '#meta' },
172
+ 'unevaluatedProperties' => { '$dynamicRef' => '#meta' }
173
+ }
174
+ }
175
+ VALIDATION = {
176
+ '$schema' => 'https://json-schema.org/draft/2020-12/schema',
177
+ '$id' => 'https://json-schema.org/draft/2020-12/meta/validation',
178
+ '$vocabulary' => {
179
+ 'https://json-schema.org/draft/2020-12/vocab/validation' => true
180
+ },
181
+ '$dynamicAnchor' => 'meta',
182
+ 'title' => 'Validation vocabulary meta-schema',
183
+ 'type' => ['object', 'boolean'],
184
+ 'properties' => {
185
+ 'type' => {
186
+ 'anyOf' => [
187
+ { '$ref' => '#/$defs/simpleTypes' },
188
+ {
189
+ 'type' => 'array',
190
+ 'items' => { '$ref' => '#/$defs/simpleTypes' },
191
+ 'minItems' => 1,
192
+ 'uniqueItems' => true
193
+ }
194
+ ]
195
+ },
196
+ 'const' => true,
197
+ 'enum' => {
198
+ 'type' => 'array',
199
+ 'items' => true
200
+ },
201
+ 'multipleOf' => {
202
+ 'type' => 'number',
203
+ 'exclusiveMinimum' => 0
204
+ },
205
+ 'maximum' => {
206
+ 'type' => 'number'
207
+ },
208
+ 'exclusiveMaximum' => {
209
+ 'type' => 'number'
210
+ },
211
+ 'minimum' => {
212
+ 'type' => 'number'
213
+ },
214
+ 'exclusiveMinimum' => {
215
+ 'type' => 'number'
216
+ },
217
+ 'maxLength' => { '$ref' => '#/$defs/nonNegativeInteger' },
218
+ 'minLength' => { '$ref' => '#/$defs/nonNegativeIntegerDefault0' },
219
+ 'pattern' => {
220
+ 'type' => 'string',
221
+ 'format' => 'regex'
222
+ },
223
+ 'maxItems' => { '$ref' => '#/$defs/nonNegativeInteger' },
224
+ 'minItems' => { '$ref' => '#/$defs/nonNegativeIntegerDefault0' },
225
+ 'uniqueItems' => {
226
+ 'type' => 'boolean',
227
+ 'default' => false
228
+ },
229
+ 'maxContains' => { '$ref' => '#/$defs/nonNegativeInteger' },
230
+ 'minContains' => {
231
+ '$ref' => '#/$defs/nonNegativeInteger',
232
+ 'default' => 1
233
+ },
234
+ 'maxProperties' => { '$ref' => '#/$defs/nonNegativeInteger' },
235
+ 'minProperties' => { '$ref' => '#/$defs/nonNegativeIntegerDefault0' },
236
+ 'required' => { '$ref' => '#/$defs/stringArray' },
237
+ 'dependentRequired' => {
238
+ 'type' => 'object',
239
+ 'additionalProperties' => {
240
+ '$ref' => '#/$defs/stringArray'
241
+ }
242
+ }
243
+ },
244
+ '$defs' => {
245
+ 'nonNegativeInteger' => {
246
+ 'type' => 'integer',
247
+ 'minimum' => 0
248
+ },
249
+ 'nonNegativeIntegerDefault0' => {
250
+ '$ref' => '#/$defs/nonNegativeInteger',
251
+ 'default' => 0
252
+ },
253
+ 'simpleTypes' => {
254
+ 'enum' => [
255
+ 'array',
256
+ 'boolean',
257
+ 'integer',
258
+ 'null',
259
+ 'number',
260
+ 'object',
261
+ 'string'
262
+ ]
263
+ },
264
+ 'stringArray' => {
265
+ 'type' => 'array',
266
+ 'items' => { 'type' => 'string' },
267
+ 'uniqueItems' => true,
268
+ 'default' => []
269
+ }
270
+ }
271
+ }
272
+ META_DATA = {
273
+ '$schema' => 'https://json-schema.org/draft/2020-12/schema',
274
+ '$id' => 'https://json-schema.org/draft/2020-12/meta/meta-data',
275
+ '$vocabulary' => {
276
+ 'https://json-schema.org/draft/2020-12/vocab/meta-data' => true
277
+ },
278
+ '$dynamicAnchor' => 'meta',
279
+ 'title' => 'Meta-data vocabulary meta-schema',
280
+ 'type' => ['object', 'boolean'],
281
+ 'properties' => {
282
+ 'title' => {
283
+ 'type' => 'string'
284
+ },
285
+ 'description' => {
286
+ 'type' => 'string'
287
+ },
288
+ 'default' => true,
289
+ 'deprecated' => {
290
+ 'type' => 'boolean',
291
+ 'default' => false
292
+ },
293
+ 'readOnly' => {
294
+ 'type' => 'boolean',
295
+ 'default' => false
296
+ },
297
+ 'writeOnly' => {
298
+ 'type' => 'boolean',
299
+ 'default' => false
300
+ },
301
+ 'examples' => {
302
+ 'type' => 'array',
303
+ 'items' => true
304
+ }
305
+ }
306
+ }
307
+ FORMAT_ANNOTATION = {
308
+ '$schema' => 'https://json-schema.org/draft/2020-12/schema',
309
+ '$id' => 'https://json-schema.org/draft/2020-12/meta/format-annotation',
310
+ '$vocabulary' => {
311
+ 'https://json-schema.org/draft/2020-12/vocab/format-annotation' => true
312
+ },
313
+ '$dynamicAnchor' => 'meta',
314
+ 'title' => 'Format vocabulary meta-schema for annotation results',
315
+ 'type' => ['object', 'boolean'],
316
+ 'properties' => {
317
+ 'format' => { 'type' => 'string' }
318
+ }
319
+ }
320
+ FORMAT_ASSERTION = {
321
+ '$schema' => 'https://json-schema.org/draft/2020-12/schema',
322
+ '$id' => 'https://json-schema.org/draft/2020-12/meta/format-assertion',
323
+ '$vocabulary' => {
324
+ 'https://json-schema.org/draft/2020-12/vocab/format-assertion' => true
325
+ },
326
+ '$dynamicAnchor' => 'meta',
327
+ 'title' => 'Format vocabulary meta-schema for assertion results',
328
+ 'type' => ['object', 'boolean'],
329
+ 'properties' => {
330
+ 'format' => { 'type' => 'string' }
331
+ }
332
+ }
333
+ CONTENT = {
334
+ '$schema' => 'https://json-schema.org/draft/2020-12/schema',
335
+ '$id' => 'https://json-schema.org/draft/2020-12/meta/content',
336
+ '$vocabulary' => {
337
+ 'https://json-schema.org/draft/2020-12/vocab/content' => true
338
+ },
339
+ '$dynamicAnchor' => 'meta',
340
+ 'title' => 'Content vocabulary meta-schema',
341
+ 'type' => ['object', 'boolean'],
342
+ 'properties' => {
343
+ 'contentEncoding' => { 'type' => 'string' },
344
+ 'contentMediaType' => { 'type' => 'string' },
345
+ 'contentSchema' => { '$dynamicRef' => '#meta' }
346
+ }
347
+ }
348
+
349
+ SCHEMAS = {
350
+ URI('https://json-schema.org/draft/2020-12/meta/core') => CORE,
351
+ URI('https://json-schema.org/draft/2020-12/meta/applicator') => APPLICATOR,
352
+ URI('https://json-schema.org/draft/2020-12/meta/unevaluated') => UNEVALUATED,
353
+ URI('https://json-schema.org/draft/2020-12/meta/validation') => VALIDATION,
354
+ URI('https://json-schema.org/draft/2020-12/meta/meta-data') => META_DATA,
355
+ URI('https://json-schema.org/draft/2020-12/meta/format-annotation') => FORMAT_ANNOTATION,
356
+ URI('https://json-schema.org/draft/2020-12/meta/format-assertion') => FORMAT_ASSERTION,
357
+ URI('https://json-schema.org/draft/2020-12/meta/content') => CONTENT
358
+ }
359
+ end
360
+ end
361
+ end