json_schemer 1.0.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +1 -6
- data/CHANGELOG.md +25 -0
- data/Gemfile.lock +2 -2
- data/README.md +137 -14
- data/json_schemer.gemspec +1 -1
- data/lib/json_schemer/draft201909/meta.rb +335 -0
- data/lib/json_schemer/draft201909/vocab/applicator.rb +104 -0
- data/lib/json_schemer/draft201909/vocab/core.rb +45 -0
- data/lib/json_schemer/draft201909/vocab.rb +31 -0
- data/lib/json_schemer/draft202012/meta.rb +361 -0
- data/lib/json_schemer/draft202012/vocab/applicator.rb +382 -0
- data/lib/json_schemer/draft202012/vocab/content.rb +44 -0
- data/lib/json_schemer/draft202012/vocab/core.rb +154 -0
- data/lib/json_schemer/draft202012/vocab/format_annotation.rb +31 -0
- data/lib/json_schemer/draft202012/vocab/format_assertion.rb +29 -0
- data/lib/json_schemer/draft202012/vocab/meta_data.rb +30 -0
- data/lib/json_schemer/draft202012/vocab/unevaluated.rb +94 -0
- data/lib/json_schemer/draft202012/vocab/validation.rb +286 -0
- data/lib/json_schemer/draft202012/vocab.rb +103 -0
- data/lib/json_schemer/draft4/meta.rb +155 -0
- data/lib/json_schemer/draft4/vocab/validation.rb +39 -0
- data/lib/json_schemer/draft4/vocab.rb +18 -0
- data/lib/json_schemer/draft6/meta.rb +161 -0
- data/lib/json_schemer/draft6/vocab.rb +16 -0
- data/lib/json_schemer/draft7/meta.rb +178 -0
- data/lib/json_schemer/draft7/vocab/validation.rb +69 -0
- data/lib/json_schemer/draft7/vocab.rb +30 -0
- data/lib/json_schemer/errors.rb +1 -0
- data/lib/json_schemer/format/duration.rb +23 -0
- data/lib/json_schemer/format/email.rb +56 -0
- data/lib/json_schemer/format/json_pointer.rb +18 -0
- data/lib/json_schemer/format.rb +53 -34
- data/lib/json_schemer/keyword.rb +41 -0
- data/lib/json_schemer/location.rb +25 -0
- data/lib/json_schemer/openapi.rb +40 -0
- data/lib/json_schemer/openapi30/document.rb +1673 -0
- data/lib/json_schemer/openapi30/meta.rb +26 -0
- data/lib/json_schemer/openapi30/vocab/base.rb +18 -0
- data/lib/json_schemer/openapi30/vocab.rb +12 -0
- data/lib/json_schemer/openapi31/document.rb +1559 -0
- data/lib/json_schemer/openapi31/meta.rb +128 -0
- data/lib/json_schemer/openapi31/vocab/base.rb +89 -0
- data/lib/json_schemer/openapi31/vocab.rb +18 -0
- data/lib/json_schemer/output.rb +55 -0
- data/lib/json_schemer/result.rb +168 -0
- data/lib/json_schemer/schema.rb +390 -0
- data/lib/json_schemer/version.rb +1 -1
- data/lib/json_schemer.rb +198 -24
- metadata +43 -10
- data/lib/json_schemer/schema/base.rb +0 -677
- data/lib/json_schemer/schema/draft4.json +0 -149
- data/lib/json_schemer/schema/draft4.rb +0 -44
- data/lib/json_schemer/schema/draft6.json +0 -155
- data/lib/json_schemer/schema/draft6.rb +0 -25
- data/lib/json_schemer/schema/draft7.json +0 -172
- data/lib/json_schemer/schema/draft7.rb +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed0173ca9146797b3576cf21870b4d7163ea05354912d0d0be21d6e89d54d16c
|
4
|
+
data.tar.gz: 1913f580bebb4d874be1a8d196a7b197156613b4240407855b9145fe03acf38b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ae6cbd519a54752d739192b3438c61abd81db1f11af409a48fe77b37205c395ca577f7fadbf2819134e942d5708d4a80a59f9d39c5e0e3d42a0144b78b70426
|
7
|
+
data.tar.gz: 216ac23667163998671a455298cc699a170452095acd0ef661b69a63a879f54d6c12f2676e5ab919472bd66794c6b7ab68687153f2c45ee7898e12be4ff7368c
|
data/.github/workflows/ci.yml
CHANGED
@@ -19,9 +19,4 @@ jobs:
|
|
19
19
|
with:
|
20
20
|
ruby-version: ${{ matrix.ruby }}
|
21
21
|
bundler-cache: true
|
22
|
-
- run:
|
23
|
-
mkdir -p tmp/gems
|
24
|
-
gem build json_schemer.gemspec
|
25
|
-
gem install --local --ignore-dependencies --no-document --install-dir tmp/gems json_schemer-*.gem
|
26
|
-
rm json_schemer-*.gem
|
27
|
-
bin/rake test
|
22
|
+
- run: bin/rake test
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,30 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [2.0.0] - XXXX-XX-XX
|
4
|
+
|
5
|
+
For 2.0.0, much of the codebase was rewritten to simplify support for the two new JSON Schema draft versions (2019-09 and 2020-12). The major change is moving each keyword into its own class and organizing them into vocabularies. [Output formats](https://json-schema.org/draft/2020-12/json-schema-core.html#section-12) and [annotations](https://json-schema.org/draft/2020-12/json-schema-core.html#section-7.7) from the new drafts are also supported. The known breaking changes are listed below, but there may be others that haven't been identified.
|
6
|
+
|
7
|
+
### Breaking Changes
|
8
|
+
|
9
|
+
- The default meta schema is now Draft 2020-12. Other meta schemas can be specified using `meta_schema`.
|
10
|
+
- Schemas use `json-schemer://schema` as the default base URI. Relative `$id` and `$ref` values are joined to the default base URI and are always absolute. For example, the schema `{ '$id' => 'foo', '$ref' => 'bar' }` uses `json-schemer://schema/foo` as the base URI and passes `json-schemer://schema/bar` to the ref resolver. For relative refs, `URI#path` can be used in the ref resolver to access the relative portion, ie: `URI('json-schemer://schema/bar').path => "/bar"`.
|
11
|
+
- Property validation hooks (`before_property_validation` and `after_property_validation`) run immediately before and after `properties` validation. Previously, `before_property_validation` ran before all "object" validations (`dependencies`, `patternProperties`, `additionalProperties`, etc) and `after_property_validation` was called after them.
|
12
|
+
- `insert_property_defaults` now inserts defaults in conditional subschemas when possible (if there's only one default or if there's only one unique default from a valid subtree).
|
13
|
+
- Error output
|
14
|
+
- Special characters in `schema_pointer` are no longer percent encoded (eg, `definitions/foo\"bar` instead of `/definitions/foo%22bar`)
|
15
|
+
- Keyword validation order changed so errors may be returned in a different order (eg, `items` errors before `contains`).
|
16
|
+
- Array `dependencies` return `"type": "dependencies"` errors instead of `"required"` and point to the schema that contains the `dependencies` keyword.
|
17
|
+
- `not` errors point to the schema that contains the `not` keyword (instead of the schema defined by the `not` keyword).
|
18
|
+
- Custom keyword errors are now always wrapped in regular error hashes. Returned strings are used to set `type`:
|
19
|
+
```
|
20
|
+
>> JSONSchemer.schema({ 'x' => 'y' }, :keywords => { 'x' => proc { false } }).validate({}).to_a
|
21
|
+
=> [{"data"=>{}, "data_pointer"=>"", "schema"=>{"x"=>"y"}, "schema_pointer"=>"", "root_schema"=>{"x"=>"y"}, "type"=>"x"}]
|
22
|
+
>> JSONSchemer.schema({ 'x' => 'y' }, :keywords => { 'x' => proc { 'wrong!' } }).validate({}).to_a
|
23
|
+
=> [{"data"=>{}, "data_pointer"=>"", "schema"=>{"x"=>"y"}, "schema_pointer"=>"", "root_schema"=>{"x"=>"y"}, "type"=>"wrong!"}]
|
24
|
+
```
|
25
|
+
|
26
|
+
[2.0.0]: https://github.com/davishmcclurg/json_schemer/releases/tag/v2.0.0
|
27
|
+
|
3
28
|
## [1.0.0] - 2023-05-26
|
4
29
|
|
5
30
|
### Breaking Changes
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
json_schemer (
|
4
|
+
json_schemer (2.0.0)
|
5
5
|
hana (~> 1.3)
|
6
6
|
regexp_parser (~> 2.0)
|
7
7
|
simpleidn (~> 0.2)
|
@@ -13,7 +13,7 @@ GEM
|
|
13
13
|
hana (1.3.7)
|
14
14
|
minitest (5.15.0)
|
15
15
|
rake (13.0.6)
|
16
|
-
regexp_parser (2.
|
16
|
+
regexp_parser (2.8.1)
|
17
17
|
simplecov (0.22.0)
|
18
18
|
docile (~> 1.1)
|
19
19
|
simplecov-html (~> 0.11)
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# JSONSchemer
|
2
2
|
|
3
|
-
JSON Schema validator. Supports drafts 4, 6, and
|
3
|
+
JSON Schema validator. Supports drafts 4, 6, 7, 2019-09, 2020-12, OpenAPI 3.0, and OpenAPI 3.1.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -50,7 +50,8 @@ schemer.validate({ 'abc' => 10 }).to_a
|
|
50
50
|
# "schema"=>{"type"=>"integer", "minimum"=>11},
|
51
51
|
# "schema_pointer"=>"/properties/abc",
|
52
52
|
# "root_schema"=>{"type"=>"object", "properties"=>{"abc"=>{"type"=>"integer", "minimum"=>11}}},
|
53
|
-
# "type"=>"minimum"
|
53
|
+
# "type"=>"minimum",
|
54
|
+
# "error"=>"number at `/abc` is less than: 11"}]
|
54
55
|
|
55
56
|
# default property values
|
56
57
|
|
@@ -82,27 +83,77 @@ schemer = JSONSchemer.schema(schema)
|
|
82
83
|
|
83
84
|
# schema validation
|
84
85
|
|
85
|
-
JSONSchemer.valid_schema?({ '$id' => '
|
86
|
+
JSONSchemer.valid_schema?({ '$id' => 'valid' })
|
86
87
|
# => true
|
87
88
|
|
88
|
-
JSONSchemer.validate_schema({ '$id' =>
|
89
|
-
# => [{"data"=>
|
89
|
+
JSONSchemer.validate_schema({ '$id' => '#invalid' }).to_a
|
90
|
+
# => [{"data"=>"#invalid",
|
90
91
|
# "data_pointer"=>"/$id",
|
91
|
-
# "schema"=>{"
|
92
|
+
# "schema"=>{"$ref"=>"#/$defs/uriReferenceString", "$comment"=>"Non-empty fragments not allowed.", "pattern"=>"^[^#]*#?$"},
|
92
93
|
# "schema_pointer"=>"/properties/$id",
|
93
94
|
# "root_schema"=>{...meta schema},
|
94
|
-
# "type"=>"
|
95
|
+
# "type"=>"pattern",
|
96
|
+
# "error"=>"string at `/$id` does not match pattern: ^[^#]*#?$"}]
|
95
97
|
|
96
|
-
JSONSchemer.schema({ '$id' => '
|
98
|
+
JSONSchemer.schema({ '$id' => 'valid' }).valid_schema?
|
97
99
|
# => true
|
98
100
|
|
99
|
-
JSONSchemer.schema({ '$id' =>
|
100
|
-
# => [{"data"=>
|
101
|
+
JSONSchemer.schema({ '$id' => '#invalid' }).validate_schema.to_a
|
102
|
+
# => [{"data"=>"#invalid",
|
101
103
|
# "data_pointer"=>"/$id",
|
102
|
-
# "schema"=>{"
|
104
|
+
# "schema"=>{"$ref"=>"#/$defs/uriReferenceString", "$comment"=>"Non-empty fragments not allowed.", "pattern"=>"^[^#]*#?$"},
|
103
105
|
# "schema_pointer"=>"/properties/$id",
|
104
106
|
# "root_schema"=>{...meta schema},
|
105
|
-
# "type"=>"
|
107
|
+
# "type"=>"pattern",
|
108
|
+
# "error"=>"string at `/$id` does not match pattern: ^[^#]*#?$"}]
|
109
|
+
|
110
|
+
# subschemas
|
111
|
+
|
112
|
+
schema = {
|
113
|
+
'type' => 'integer',
|
114
|
+
'$defs' => {
|
115
|
+
'foo' => {
|
116
|
+
'type' => 'string'
|
117
|
+
}
|
118
|
+
}
|
119
|
+
}
|
120
|
+
schemer = JSONSchemer.schema(schema)
|
121
|
+
|
122
|
+
schemer.ref('#/$defs/foo').validate(1).to_a
|
123
|
+
# => [{"data"=>1,
|
124
|
+
# "data_pointer"=>"",
|
125
|
+
# "schema"=>{"type"=>"string"},
|
126
|
+
# "schema_pointer"=>"/$defs/foo",
|
127
|
+
# "root_schema"=>{"type"=>"integer", "$defs"=>{"foo"=>{"type"=>"string"}}},
|
128
|
+
# "type"=>"string",
|
129
|
+
# "error"=>"instance at root is not a string"}]
|
130
|
+
|
131
|
+
# schema bundling (https://json-schema.org/draft/2020-12/json-schema-core.html#section-9.3)
|
132
|
+
|
133
|
+
schema = {
|
134
|
+
'$id' => 'http://example.com/schema',
|
135
|
+
'allOf' => [
|
136
|
+
{ '$ref' => 'schema/one' },
|
137
|
+
{ '$ref' => 'schema/two' }
|
138
|
+
]
|
139
|
+
}
|
140
|
+
refs = {
|
141
|
+
URI('http://example.com/schema/one') => {
|
142
|
+
'type' => 'integer'
|
143
|
+
},
|
144
|
+
URI('http://example.com/schema/two') => {
|
145
|
+
'minimum' => 11
|
146
|
+
}
|
147
|
+
}
|
148
|
+
schemer = JSONSchemer.schema(schema, :ref_resolver => refs.to_proc)
|
149
|
+
|
150
|
+
schemer.bundle
|
151
|
+
# => {"$id"=>"http://example.com/schema",
|
152
|
+
# "allOf"=>[{"$ref"=>"schema/one"}, {"$ref"=>"schema/two"}],
|
153
|
+
# "$schema"=>"https://json-schema.org/draft/2020-12/schema",
|
154
|
+
# "$defs"=>
|
155
|
+
# {"http://example.com/schema/one"=>{"type"=>"integer", "$id"=>"http://example.com/schema/one", "$schema"=>"https://json-schema.org/draft/2020-12/schema"},
|
156
|
+
# "http://example.com/schema/two"=>{"minimum"=>11, "$id"=>"http://example.com/schema/two", "$schema"=>"https://json-schema.org/draft/2020-12/schema"}}}
|
106
157
|
```
|
107
158
|
|
108
159
|
## Options
|
@@ -111,7 +162,20 @@ JSONSchemer.schema({ '$id' => nil }).validate_schema.to_a
|
|
111
162
|
JSONSchemer.schema(
|
112
163
|
schema,
|
113
164
|
|
114
|
-
#
|
165
|
+
# meta schema to use for vocabularies (keyword behavior) and schema validation
|
166
|
+
# String/JSONSchemer::Schema
|
167
|
+
# 'https://json-schema.org/draft/2020-12/schema': JSONSchemer.draft202012
|
168
|
+
# 'https://json-schema.org/draft/2019-09/schema': JSONSchemer.draft201909
|
169
|
+
# 'http://json-schema.org/draft-07/schema#': JSONSchemer.draft7
|
170
|
+
# 'http://json-schema.org/draft-06/schema#': JSONSchemer.draft6
|
171
|
+
# 'http://json-schema.org/draft-04/schema#': JSONSchemer.draft4
|
172
|
+
# 'http://json-schema.org/schema#': JSONSchemer.draft4
|
173
|
+
# 'https://spec.openapis.org/oas/3.1/dialect/base': JSONSchemer.openapi31
|
174
|
+
# 'json-schemer://openapi30/schema': JSONSchemer.openapi30
|
175
|
+
# default: JSONSchemer.draft202012
|
176
|
+
meta_schema: 'https://json-schema.org/draft/2020-12/schema',
|
177
|
+
|
178
|
+
# validate `format` (https://json-schema.org/draft/2020-12/json-schema-validation.html#section-7)
|
115
179
|
# true/false
|
116
180
|
# default: true
|
117
181
|
format: true,
|
@@ -147,10 +211,69 @@ JSONSchemer.schema(
|
|
147
211
|
# default: 'ruby'
|
148
212
|
regexp_resolver: proc do |pattern|
|
149
213
|
RE2::Regexp.new(pattern)
|
150
|
-
end
|
214
|
+
end,
|
215
|
+
|
216
|
+
# output formatting (https://json-schema.org/draft/2020-12/json-schema-core.html#section-12)
|
217
|
+
# 'classic'/'flag'/'basic'/'detailed'/'verbose'
|
218
|
+
# default: 'classic'
|
219
|
+
output_format: 'basic',
|
220
|
+
|
221
|
+
# validate `readOnly`/`writeOnly` keywords (https://spec.openapis.org/oas/v3.0.3#fixed-fields-19)
|
222
|
+
# 'read'/'write'/nil
|
223
|
+
# default: nil
|
224
|
+
access_mode: 'read'
|
151
225
|
)
|
152
226
|
```
|
153
227
|
|
228
|
+
## OpenAPI
|
229
|
+
|
230
|
+
```ruby
|
231
|
+
document = JSONSchemer.openapi({
|
232
|
+
'openapi' => '3.1.0',
|
233
|
+
'info' => {
|
234
|
+
'title' => 'example'
|
235
|
+
},
|
236
|
+
'components' => {
|
237
|
+
'schemas' => {
|
238
|
+
'example' => {
|
239
|
+
'type' => 'integer'
|
240
|
+
}
|
241
|
+
}
|
242
|
+
}
|
243
|
+
})
|
244
|
+
|
245
|
+
# document validation using meta schema
|
246
|
+
|
247
|
+
document.valid?
|
248
|
+
# => false
|
249
|
+
|
250
|
+
document.validate.to_a
|
251
|
+
# => [{"data"=>{"title"=>"example"},
|
252
|
+
# "data_pointer"=>"/info",
|
253
|
+
# "schema"=>{...info schema},
|
254
|
+
# "schema_pointer"=>"/$defs/info",
|
255
|
+
# "root_schema"=>{...meta schema},
|
256
|
+
# "type"=>"required",
|
257
|
+
# "details"=>{"missing_keys"=>["version"]}},
|
258
|
+
# ...]
|
259
|
+
|
260
|
+
# data validation using schema by name (in `components/schemas`)
|
261
|
+
|
262
|
+
document.schema('example').valid?(1)
|
263
|
+
# => true
|
264
|
+
|
265
|
+
document.schema('example').valid?('one')
|
266
|
+
# => false
|
267
|
+
|
268
|
+
# data validation using schema by ref
|
269
|
+
|
270
|
+
document.ref('#/components/schemas/example').valid?(1)
|
271
|
+
# => true
|
272
|
+
|
273
|
+
document.ref('#/components/schemas/example').valid?('one')
|
274
|
+
# => false
|
275
|
+
```
|
276
|
+
|
154
277
|
## CLI
|
155
278
|
|
156
279
|
The `json_schemer` executable takes a JSON schema file as the first argument followed by one or more JSON data files to validate. If there are any validation errors, it outputs them and returns an error code.
|
data/json_schemer.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["David Harsha"]
|
10
10
|
spec.email = ["davishmcclurg@gmail.com"]
|
11
11
|
|
12
|
-
spec.summary = "JSON Schema validator. Supports drafts 4, 6, and
|
12
|
+
spec.summary = "JSON Schema validator. Supports drafts 4, 6, 7, 2019-09, 2020-12, OpenAPI 3.0, and OpenAPI 3.1."
|
13
13
|
spec.homepage = "https://github.com/davishmcclurg/json_schemer"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
@@ -0,0 +1,335 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module JSONSchemer
|
3
|
+
module Draft201909
|
4
|
+
BASE_URI = URI('https://json-schema.org/draft/2019-09/schema')
|
5
|
+
SCHEMA = {
|
6
|
+
'$schema' => 'https://json-schema.org/draft/2019-09/schema',
|
7
|
+
'$id' => 'https://json-schema.org/draft/2019-09/schema',
|
8
|
+
'$vocabulary' => {
|
9
|
+
'https://json-schema.org/draft/2019-09/vocab/core' => true,
|
10
|
+
'https://json-schema.org/draft/2019-09/vocab/applicator' => true,
|
11
|
+
'https://json-schema.org/draft/2019-09/vocab/validation' => true,
|
12
|
+
'https://json-schema.org/draft/2019-09/vocab/meta-data' => true,
|
13
|
+
'https://json-schema.org/draft/2019-09/vocab/format' => false,
|
14
|
+
'https://json-schema.org/draft/2019-09/vocab/content' => true
|
15
|
+
},
|
16
|
+
'$recursiveAnchor' => true,
|
17
|
+
'title' => 'Core and Validation specifications meta-schema',
|
18
|
+
'allOf' => [
|
19
|
+
{'$ref' => 'meta/core'},
|
20
|
+
{'$ref' => 'meta/applicator'},
|
21
|
+
{'$ref' => 'meta/validation'},
|
22
|
+
{'$ref' => 'meta/meta-data'},
|
23
|
+
{'$ref' => 'meta/format'},
|
24
|
+
{'$ref' => 'meta/content'}
|
25
|
+
],
|
26
|
+
'type' => ['object', 'boolean'],
|
27
|
+
'properties' => {
|
28
|
+
'definitions' => {
|
29
|
+
'$comment' => 'While no longer an official keyword as it is replaced by $defs, this keyword is retained in the meta-schema to prevent incompatible extensions as it remains in common use.',
|
30
|
+
'type' => 'object',
|
31
|
+
'additionalProperties' => { '$recursiveRef' => '#' },
|
32
|
+
'default' => {}
|
33
|
+
},
|
34
|
+
'dependencies' => {
|
35
|
+
'$comment' => '"dependencies" is no longer a keyword, but schema authors should avoid redefining it to facilitate a smooth transition to "dependentSchemas" and "dependentRequired"',
|
36
|
+
'type' => 'object',
|
37
|
+
'additionalProperties' => {
|
38
|
+
'anyOf' => [
|
39
|
+
{ '$recursiveRef' => '#' },
|
40
|
+
{ '$ref' => 'meta/validation#/$defs/stringArray' }
|
41
|
+
]
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
module Meta
|
48
|
+
CORE = {
|
49
|
+
'$schema' => 'https://json-schema.org/draft/2019-09/schema',
|
50
|
+
'$id' => 'https://json-schema.org/draft/2019-09/meta/core',
|
51
|
+
'$vocabulary' => {
|
52
|
+
'https://json-schema.org/draft/2019-09/vocab/core' => true
|
53
|
+
},
|
54
|
+
'$recursiveAnchor' => true,
|
55
|
+
'title' => 'Core vocabulary meta-schema',
|
56
|
+
'type' => ['object', 'boolean'],
|
57
|
+
'properties' => {
|
58
|
+
'$id' => {
|
59
|
+
'type' => 'string',
|
60
|
+
'format' => 'uri-reference',
|
61
|
+
'$comment' => 'Non-empty fragments not allowed.',
|
62
|
+
'pattern' => '^[^#]*#?$'
|
63
|
+
},
|
64
|
+
'$schema' => {
|
65
|
+
'type' => 'string',
|
66
|
+
'format' => 'uri'
|
67
|
+
},
|
68
|
+
'$anchor' => {
|
69
|
+
'type' => 'string',
|
70
|
+
'pattern' => '^[A-Za-z][-A-Za-z0-9.:_]*$'
|
71
|
+
},
|
72
|
+
'$ref' => {
|
73
|
+
'type' => 'string',
|
74
|
+
'format' => 'uri-reference'
|
75
|
+
},
|
76
|
+
'$recursiveRef' => {
|
77
|
+
'type' => 'string',
|
78
|
+
'format' => 'uri-reference'
|
79
|
+
},
|
80
|
+
'$recursiveAnchor' => {
|
81
|
+
'type' => 'boolean',
|
82
|
+
'default' => false
|
83
|
+
},
|
84
|
+
'$vocabulary' => {
|
85
|
+
'type' => 'object',
|
86
|
+
'propertyNames' => {
|
87
|
+
'type' => 'string',
|
88
|
+
'format' => 'uri'
|
89
|
+
},
|
90
|
+
'additionalProperties' => {
|
91
|
+
'type' => 'boolean'
|
92
|
+
}
|
93
|
+
},
|
94
|
+
'$comment' => {
|
95
|
+
'type' => 'string'
|
96
|
+
},
|
97
|
+
'$defs' => {
|
98
|
+
'type' => 'object',
|
99
|
+
'additionalProperties' => { '$recursiveRef' => '#' },
|
100
|
+
'default' => {}
|
101
|
+
}
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
APPLICATOR = {
|
106
|
+
'$schema' => 'https://json-schema.org/draft/2019-09/schema',
|
107
|
+
'$id' => 'https://json-schema.org/draft/2019-09/meta/applicator',
|
108
|
+
'$vocabulary' => {
|
109
|
+
'https://json-schema.org/draft/2019-09/vocab/applicator' => true
|
110
|
+
},
|
111
|
+
'$recursiveAnchor' => true,
|
112
|
+
'title' => 'Applicator vocabulary meta-schema',
|
113
|
+
'type' => ['object', 'boolean'],
|
114
|
+
'properties' => {
|
115
|
+
'additionalItems' => { '$recursiveRef' => '#' },
|
116
|
+
'unevaluatedItems' => { '$recursiveRef' => '#' },
|
117
|
+
'items' => {
|
118
|
+
'anyOf' => [
|
119
|
+
{ '$recursiveRef' => '#' },
|
120
|
+
{ '$ref' => '#/$defs/schemaArray' }
|
121
|
+
]
|
122
|
+
},
|
123
|
+
'contains' => { '$recursiveRef' => '#' },
|
124
|
+
'additionalProperties' => { '$recursiveRef' => '#' },
|
125
|
+
'unevaluatedProperties' => { '$recursiveRef' => '#' },
|
126
|
+
'properties' => {
|
127
|
+
'type' => 'object',
|
128
|
+
'additionalProperties' => { '$recursiveRef' => '#' },
|
129
|
+
'default' => {}
|
130
|
+
},
|
131
|
+
'patternProperties' => {
|
132
|
+
'type' => 'object',
|
133
|
+
'additionalProperties' => { '$recursiveRef' => '#' },
|
134
|
+
'propertyNames' => { 'format' => 'regex' },
|
135
|
+
'default' => {}
|
136
|
+
},
|
137
|
+
'dependentSchemas' => {
|
138
|
+
'type' => 'object',
|
139
|
+
'additionalProperties' => {
|
140
|
+
'$recursiveRef' => '#'
|
141
|
+
}
|
142
|
+
},
|
143
|
+
'propertyNames' => { '$recursiveRef' => '#' },
|
144
|
+
'if' => { '$recursiveRef' => '#' },
|
145
|
+
'then' => { '$recursiveRef' => '#' },
|
146
|
+
'else' => { '$recursiveRef' => '#' },
|
147
|
+
'allOf' => { '$ref' => '#/$defs/schemaArray' },
|
148
|
+
'anyOf' => { '$ref' => '#/$defs/schemaArray' },
|
149
|
+
'oneOf' => { '$ref' => '#/$defs/schemaArray' },
|
150
|
+
'not' => { '$recursiveRef' => '#' }
|
151
|
+
},
|
152
|
+
'$defs' => {
|
153
|
+
'schemaArray' => {
|
154
|
+
'type' => 'array',
|
155
|
+
'minItems' => 1,
|
156
|
+
'items' => { '$recursiveRef' => '#' }
|
157
|
+
}
|
158
|
+
}
|
159
|
+
}
|
160
|
+
|
161
|
+
VALIDATION = {
|
162
|
+
'$schema' => 'https://json-schema.org/draft/2019-09/schema',
|
163
|
+
'$id' => 'https://json-schema.org/draft/2019-09/meta/validation',
|
164
|
+
'$vocabulary' => {
|
165
|
+
'https://json-schema.org/draft/2019-09/vocab/validation' => true
|
166
|
+
},
|
167
|
+
'$recursiveAnchor' => true,
|
168
|
+
'title' => 'Validation vocabulary meta-schema',
|
169
|
+
'type' => ['object', 'boolean'],
|
170
|
+
'properties' => {
|
171
|
+
'multipleOf' => {
|
172
|
+
'type' => 'number',
|
173
|
+
'exclusiveMinimum' => 0
|
174
|
+
},
|
175
|
+
'maximum' => {
|
176
|
+
'type' => 'number'
|
177
|
+
},
|
178
|
+
'exclusiveMaximum' => {
|
179
|
+
'type' => 'number'
|
180
|
+
},
|
181
|
+
'minimum' => {
|
182
|
+
'type' => 'number'
|
183
|
+
},
|
184
|
+
'exclusiveMinimum' => {
|
185
|
+
'type' => 'number'
|
186
|
+
},
|
187
|
+
'maxLength' => { '$ref' => '#/$defs/nonNegativeInteger' },
|
188
|
+
'minLength' => { '$ref' => '#/$defs/nonNegativeIntegerDefault0' },
|
189
|
+
'pattern' => {
|
190
|
+
'type' => 'string',
|
191
|
+
'format' => 'regex'
|
192
|
+
},
|
193
|
+
'maxItems' => { '$ref' => '#/$defs/nonNegativeInteger' },
|
194
|
+
'minItems' => { '$ref' => '#/$defs/nonNegativeIntegerDefault0' },
|
195
|
+
'uniqueItems' => {
|
196
|
+
'type' => 'boolean',
|
197
|
+
'default' => false
|
198
|
+
},
|
199
|
+
'maxContains' => { '$ref' => '#/$defs/nonNegativeInteger' },
|
200
|
+
'minContains' => {
|
201
|
+
'$ref' => '#/$defs/nonNegativeInteger',
|
202
|
+
'default' => 1
|
203
|
+
},
|
204
|
+
'maxProperties' => { '$ref' => '#/$defs/nonNegativeInteger' },
|
205
|
+
'minProperties' => { '$ref' => '#/$defs/nonNegativeIntegerDefault0' },
|
206
|
+
'required' => { '$ref' => '#/$defs/stringArray' },
|
207
|
+
'dependentRequired' => {
|
208
|
+
'type' => 'object',
|
209
|
+
'additionalProperties' => {
|
210
|
+
'$ref' => '#/$defs/stringArray'
|
211
|
+
}
|
212
|
+
},
|
213
|
+
'const' => true,
|
214
|
+
'enum' => {
|
215
|
+
'type' => 'array',
|
216
|
+
'items' => true
|
217
|
+
},
|
218
|
+
'type' => {
|
219
|
+
'anyOf' => [
|
220
|
+
{ '$ref' => '#/$defs/simpleTypes' },
|
221
|
+
{
|
222
|
+
'type' => 'array',
|
223
|
+
'items' => { '$ref' => '#/$defs/simpleTypes' },
|
224
|
+
'minItems' => 1,
|
225
|
+
'uniqueItems' => true
|
226
|
+
}
|
227
|
+
]
|
228
|
+
}
|
229
|
+
},
|
230
|
+
'$defs' => {
|
231
|
+
'nonNegativeInteger' => {
|
232
|
+
'type' => 'integer',
|
233
|
+
'minimum' => 0
|
234
|
+
},
|
235
|
+
'nonNegativeIntegerDefault0' => {
|
236
|
+
'$ref' => '#/$defs/nonNegativeInteger',
|
237
|
+
'default' => 0
|
238
|
+
},
|
239
|
+
'simpleTypes' => {
|
240
|
+
'enum' => [
|
241
|
+
'array',
|
242
|
+
'boolean',
|
243
|
+
'integer',
|
244
|
+
'null',
|
245
|
+
'number',
|
246
|
+
'object',
|
247
|
+
'string'
|
248
|
+
]
|
249
|
+
},
|
250
|
+
'stringArray' => {
|
251
|
+
'type' => 'array',
|
252
|
+
'items' => { 'type' => 'string' },
|
253
|
+
'uniqueItems' => true,
|
254
|
+
'default' => []
|
255
|
+
}
|
256
|
+
}
|
257
|
+
}
|
258
|
+
|
259
|
+
META_DATA = {
|
260
|
+
'$schema' => 'https://json-schema.org/draft/2019-09/schema',
|
261
|
+
'$id' => 'https://json-schema.org/draft/2019-09/meta/meta-data',
|
262
|
+
'$vocabulary' => {
|
263
|
+
'https://json-schema.org/draft/2019-09/vocab/meta-data' => true
|
264
|
+
},
|
265
|
+
'$recursiveAnchor' => true,
|
266
|
+
'title' => 'Meta-data vocabulary meta-schema',
|
267
|
+
'type' => ['object', 'boolean'],
|
268
|
+
'properties' => {
|
269
|
+
'title' => {
|
270
|
+
'type' => 'string'
|
271
|
+
},
|
272
|
+
'description' => {
|
273
|
+
'type' => 'string'
|
274
|
+
},
|
275
|
+
'default' => true,
|
276
|
+
'deprecated' => {
|
277
|
+
'type' => 'boolean',
|
278
|
+
'default' => false
|
279
|
+
},
|
280
|
+
'readOnly' => {
|
281
|
+
'type' => 'boolean',
|
282
|
+
'default' => false
|
283
|
+
},
|
284
|
+
'writeOnly' => {
|
285
|
+
'type' => 'boolean',
|
286
|
+
'default' => false
|
287
|
+
},
|
288
|
+
'examples' => {
|
289
|
+
'type' => 'array',
|
290
|
+
'items' => true
|
291
|
+
}
|
292
|
+
}
|
293
|
+
}
|
294
|
+
|
295
|
+
FORMAT = {
|
296
|
+
'$schema' => 'https://json-schema.org/draft/2019-09/schema',
|
297
|
+
'$id' => 'https://json-schema.org/draft/2019-09/meta/format',
|
298
|
+
'$vocabulary' => {
|
299
|
+
'https://json-schema.org/draft/2019-09/vocab/format' => true
|
300
|
+
},
|
301
|
+
'$recursiveAnchor' => true,
|
302
|
+
'title' => 'Format vocabulary meta-schema',
|
303
|
+
'type' => ['object', 'boolean'],
|
304
|
+
'properties' => {
|
305
|
+
'format' => { 'type' => 'string' }
|
306
|
+
}
|
307
|
+
}
|
308
|
+
|
309
|
+
CONTENT = {
|
310
|
+
'$schema' => 'https://json-schema.org/draft/2019-09/schema',
|
311
|
+
'$id' => 'https://json-schema.org/draft/2019-09/meta/content',
|
312
|
+
'$vocabulary' => {
|
313
|
+
'https://json-schema.org/draft/2019-09/vocab/content' => true
|
314
|
+
},
|
315
|
+
'$recursiveAnchor' => true,
|
316
|
+
'title' => 'Content vocabulary meta-schema',
|
317
|
+
'type' => ['object', 'boolean'],
|
318
|
+
'properties' => {
|
319
|
+
'contentMediaType' => { 'type' => 'string' },
|
320
|
+
'contentEncoding' => { 'type' => 'string' },
|
321
|
+
'contentSchema' => { '$recursiveRef' => '#' }
|
322
|
+
}
|
323
|
+
}
|
324
|
+
|
325
|
+
SCHEMAS = {
|
326
|
+
URI('https://json-schema.org/draft/2019-09/meta/core') => CORE,
|
327
|
+
URI('https://json-schema.org/draft/2019-09/meta/applicator') => APPLICATOR,
|
328
|
+
URI('https://json-schema.org/draft/2019-09/meta/validation') => VALIDATION,
|
329
|
+
URI('https://json-schema.org/draft/2019-09/meta/meta-data') => META_DATA,
|
330
|
+
URI('https://json-schema.org/draft/2019-09/meta/format') => FORMAT,
|
331
|
+
URI('https://json-schema.org/draft/2019-09/meta/content') => CONTENT
|
332
|
+
}
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|