-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
support JSON Schema 2019-09 (formerly draft-08) #44
Comments
Hey, are there any plans to support 2019-09-validation as well? |
Supporting 2019-09 would include validation. Looks like there's a new 2020-12 version as well. |
👋 Any news on that? |
No news at the moment. I recently quit my job though so I may have more time to look into the changes. |
hi @davishmcclurg, thank you for a great gem! any news on supporting 2019-09 or 2020-12? |
I'd love to see this as well. |
@davishmcclurg I started working on this here: https://github.com/ekzo-dev/json_schemer/tree/feature/draft2019-09 I also adjusted test suite to run draft2019-09 ref tests, but some of them still fail because some other core changes need to be implemented as well. |
Lots of stuff here. The main goal is to support the newer JSON Schema drafts (2020-12 and 2019-09) including output formats and annotations. The biggest change is pulling individual keywords into separate classes which contain parsing and validation logic. All drafts now use the same `Schema` class with the new "vocabularies" concept handling behavior differences. Each draft has its own meta schema (meta.rb), vocabularies (vocab.rb), and, if necessary, keyword classes (vocab/*.rb). Most keywords are defined in the latest draft with previous drafts removing/adding things from there. Old drafts (4, 6, and 7) only have a single vocabulary because they predate the concept. `Schema` contains some logic but I tried to keep as much as possible in keyword classes. `Schema` and `Keyword` have a similar interface (`value`, `keyword`, `parent`, etc) and share some code using the `Output` module because it didn't feel quite right to have `Schema` be a subclass of `Keyword`. There are two basic methods for schemas and keywords: `#parse`: parses the provided definition (generates relevant subschemas, side effects, etc). Basically anything that can be done before data validation. `#validate`: iterates through the parsed schema/keywords, validates data, and returns a `Result` object (possibly with nested results). One exception is `Ref`, which doesn't resolve refs at parse time because of a circular dependency when generating meta schemas. Output formats (introduced in 2019-09) are supported via `Result`. I think the only tricky thing there is that nested results are returned as enumerators instead of arrays for performance reasons. This matches the "classic" behavior as well. 2019-09 also introduced "annotations" which are used for some validations (`unevaluatedProperties`, `unevaluatedItems`, etc) and are returned with successful results in a similar format to errors. The "classic" output format drops them to match existing behavior. Notes: - `Location` is used for performance reasons so that JSON pointer resolution can be cached and deferred until output time. - `instance_location` isn't cached between validations because it's possibly unbounded. - `ref_resolver` and `regexp_resolver` are lazily created for performanc reasons. Known breaking changes (so far): - Custom keyword output - `not` and `dependencies` output - Property validation hooks (`before_property_validation` and `after_property_validation`) are now called immediately surrounding `properties` validation. Previously, `before_property_validation` was called before all "object" validations (`dependencies`, `patternProperties`, `additionalProperties`, etc) and `after_property_validation` was called after. Related: - #27 - #44 - #116
Hi @ekzobrain—I appreciate the contribution! I've actually been working for the last couple months on a rewrite to support the latest drafts: https://github.com/davishmcclurg/json_schemer/compare/next There are a lot of changes there so I probably won't be able to include yours, but let me know if you want to help out elsewhere because there are still some things to finish up. |
@davishmcclurg Hi. You've done a great work! Of course my changes are not applicable here because it is a major architecture rewrite. I may help with testing - we have tens of thousands compex schemas (some of them are up to 8000 rows in source), which are now build on Draft 7, but we need to migrate them to at least Draft 2019-09, or may be even 2020-12 as you already support it. What is the currect state of your work, what's remaining undone? |
It would be great if you could help with testing. There are a few small things I'm still planning to get done (docs, cleanup, etc), but that branch should be working and ready for you to test.
I agree the error output is not that helpful— |
Ok, I'll give you feedback about my tests and error output in about a week |
Lots of stuff here. The main goal is to support the newer JSON Schema drafts (2020-12 and 2019-09) including output formats and annotations. The biggest change is pulling individual keywords into separate classes which contain parsing and validation logic. All drafts now use the same `Schema` class with the new "vocabularies" concept handling behavior differences. Each draft has its own meta schema (meta.rb), vocabularies (vocab.rb), and, if necessary, keyword classes (vocab/*.rb). Most keywords are defined in the latest draft with previous drafts removing/adding things from there. Old drafts (4, 6, and 7) only have a single vocabulary because they predate the concept. `Schema` contains some logic but I tried to keep as much as possible in keyword classes. `Schema` and `Keyword` have a similar interface (`value`, `keyword`, `parent`, etc) and share some code using the `Output` module because it didn't feel quite right to have `Schema` be a subclass of `Keyword`. There are two basic methods for schemas and keywords: `#parse`: parses the provided definition (generates relevant subschemas, side effects, etc). Basically anything that can be done before data validation. `#validate`: iterates through the parsed schema/keywords, validates data, and returns a `Result` object (possibly with nested results). One exception is `Ref`, which doesn't resolve refs at parse time because of a circular dependency when generating meta schemas. Output formats (introduced in 2019-09) are supported via `Result`. I think the only tricky thing there is that nested results are returned as enumerators instead of arrays for performance reasons. This matches the "classic" behavior as well. 2019-09 also introduced "annotations" which are used for some validations (`unevaluatedProperties`, `unevaluatedItems`, etc) and are returned with successful results in a similar format to errors. The "classic" output format drops them to match existing behavior. Notes: - `Location` is used for performance reasons so that JSON pointer resolution can be cached and deferred until output time. - `instance_location` isn't cached between validations because it's possibly unbounded. - `ref_resolver` and `regexp_resolver` are lazily created for performanc reasons. Known breaking changes (so far): - Custom keyword output - `not` and `dependencies` output - Property validation hooks (`before_property_validation` and `after_property_validation`) are now called immediately surrounding `properties` validation. Previously, `before_property_validation` was called before all "object" validations (`dependencies`, `patternProperties`, `additionalProperties`, etc) and `after_property_validation` was called after. Related: - #27 - #44 - #116
@ekzobrain I just added a commit to that branch that adds more descriptive error messages. I don't think it addresses your concerns (eg, |
Lots of stuff here. The main goal is to support the newer JSON Schema drafts (2020-12 and 2019-09) including output formats and annotations. The biggest change is pulling individual keywords into separate classes which contain parsing and validation logic. All drafts now use the same `Schema` class with the new "vocabularies" concept handling behavior differences. Each draft has its own meta schema (meta.rb), vocabularies (vocab.rb), and, if necessary, keyword classes (vocab/*.rb). Most keywords are defined in the latest draft with previous drafts removing/adding things from there. Old drafts (4, 6, and 7) only have a single vocabulary because they predate the concept. `Schema` contains some logic but I tried to keep as much as possible in keyword classes. `Schema` and `Keyword` have a similar interface (`value`, `keyword`, `parent`, etc) and share some code using the `Output` module because it didn't feel quite right to have `Schema` be a subclass of `Keyword`. There are two basic methods for schemas and keywords: `#parse`: parses the provided definition (generates relevant subschemas, side effects, etc). Basically anything that can be done before data validation. `#validate`: iterates through the parsed schema/keywords, validates data, and returns a `Result` object (possibly with nested results). One exception is `Ref`, which doesn't resolve refs at parse time because of a circular dependency when generating meta schemas. Output formats (introduced in 2019-09) are supported via `Result`. I think the only tricky thing there is that nested results are returned as enumerators instead of arrays for performance reasons. This matches the "classic" behavior as well. 2019-09 also introduced "annotations" which are used for some validations (`unevaluatedProperties`, `unevaluatedItems`, etc) and are returned with successful results in a similar format to errors. The "classic" output format drops them to match existing behavior. Notes: - `Location` is used for performance reasons so that JSON pointer resolution can be cached and deferred until output time. - `instance_location` isn't cached between validations because it's possibly unbounded. - `ref_resolver` and `regexp_resolver` are lazily created for performanc reasons. Known breaking changes (so far): - Custom keyword output - `not` and `dependencies` output - Property validation hooks (`before_property_validation` and `after_property_validation`) are now called immediately surrounding `properties` validation. Previously, `before_property_validation` was called before all "object" validations (`dependencies`, `patternProperties`, `additionalProperties`, etc) and `after_property_validation` was called after. Related: - #27 - #44 - #116
Features: - Draft 2020-12 support - Draft 2019-09 support - Output formats - Annotations - OpenAPI 3.1 schema support - OpenAPI 3.0 schema support - `insert_property_defaults` in conditional subschemas - Error messages - Non-string schema and data keys See individual commits for more details. Closes: - #27 - #44 - #55 - #91 - #94 - #116 - #123
Features: - Draft 2020-12 support - Draft 2019-09 support - Output formats - Annotations - OpenAPI 3.1 schema support - OpenAPI 3.0 schema support - `insert_property_defaults` in conditional subschemas - Error messages - Non-string schema and data keys See individual commits for more details. Closes: - #27 - #44 - #55 - #91 - #94 - #116 - #123
@ekzobrain have you had a chance to test things out? I've got a PR open now that I'm planning to merge in a couple weeks. It would be helpful if you could test it out before I merge. Let me know! |
@davishmcclurg Just to give you another point of reference. Our team has a fairly complex schema spread across a couple dozen files. It's using draft-7 but I switched to 2020-12 to try against the big rewrite commit (6de2a04) earlier this week. Our suite of >1000 examples that tests both valid and invalid data fully passed on the new version. I wanted to experiment with |
Thanks @neilpa-inv! I appreciate the feedback |
@davishmcclurg I've started testing against my files and faced an issue with Draft 7 schema. I've attached an example schema and data files. This code throws an exception "JSONSchemer::InvalidRefPointer: /definitions/n1:TStatementForm1": schemer = JSONSchemer.schema(Pathname.new('schema.json'))
schemer.validate(Pathname.new('data.json')) While this code returns JSONSchemer.valid_schema?(Pathname.new('schema.json')) |
Looks like the issue is you're using other keywords (ie,
To get around it, you can wrap the "allOf": [{ "$ref": "#/definitions/n1:TStatementForm1" }], |
But shouldn't the |
|
I know about this rule, but always thought, that it is relative only for validation vocabulary keywords. Your 1.0 version worked correctly with this schema and other validators that I know and use also handle it correctly, for example: https://www.jsonschemavalidator.net/ |
I don't think that's the case since there's a json-schema-test-suite test for ignoring Looks like the I'll look into supporting |
Lots of stuff here. The main goal is to support the newer JSON Schema drafts (2020-12 and 2019-09) including output formats and annotations. The biggest change is pulling individual keywords into separate classes which contain parsing and validation logic. All drafts now use the same `Schema` class with the new "vocabularies" concept handling behavior differences. Each draft has its own meta schema (meta.rb), vocabularies (vocab.rb), and, if necessary, keyword classes (vocab/*.rb). Most keywords are defined in the latest draft with previous drafts removing/adding things from there. Old drafts (4, 6, and 7) only have a single vocabulary because they predate the concept. `Schema` contains some logic but I tried to keep as much as possible in keyword classes. `Schema` and `Keyword` have a similar interface (`value`, `keyword`, `parent`, etc) and share some code using the `Output` module because it didn't feel quite right to have `Schema` be a subclass of `Keyword`. There are two basic methods for schemas and keywords: `#parse`: parses the provided definition (generates relevant subschemas, side effects, etc). Basically anything that can be done before data validation. `#validate`: iterates through the parsed schema/keywords, validates data, and returns a `Result` object (possibly with nested results). One exception is `Ref`, which doesn't resolve refs at parse time because of a circular dependency when generating meta schemas. Output formats (introduced in 2019-09) are supported via `Result`. I think the only tricky thing there is that nested results are returned as enumerators instead of arrays for performance reasons. This matches the "classic" behavior as well. 2019-09 also introduced "annotations" which are used for some validations (`unevaluatedProperties`, `unevaluatedItems`, etc) and are returned with successful results in a similar format to errors. The "classic" output format drops them to match existing behavior. Notes: - `Location` is used for performance reasons so that JSON pointer resolution can be cached and deferred until output time. - `instance_location` isn't cached between validations because it's possibly unbounded. - `ref_resolver` and `regexp_resolver` are lazily created for performanc reasons. Known breaking changes (so far): - Custom keyword output - `not` and `dependencies` output - Property validation hooks (`before_property_validation` and `after_property_validation`) are now called immediately surrounding `properties` validation. Previously, `before_property_validation` was called before all "object" validations (`dependencies`, `patternProperties`, `additionalProperties`, etc) and `after_property_validation` was called after. Related: - #27 - #44 - #116
I don't think this is really correct according to the [specification][0], but it matches the previous behavior and seems useful. Drafts after 7 don't have a problem because they allow all keywords as `$ref` siblings. Related: - #44 (comment) - json-schema-org/JSON-Schema-Test-Suite#458 [0]: https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-01#section-8.3
Features: - Draft 2020-12 support - Draft 2019-09 support - Output formats - Annotations - OpenAPI 3.1 schema support - OpenAPI 3.0 schema support - `insert_property_defaults` in conditional subschemas - Error messages - Non-string schema and data keys - Schema bundling See individual commits for more details. Closes: - #27 - #44 - #55 - #91 - #94 - #116 - #123 - #136
@ekzobrain I updated that branch to make |
@davishmcclurg It now works as expected. schemer = JSONSchemer.schema(Pathname.new('schema.json'))
e = schemer.validate(JSON.parse(File.read('data.json')))
e.each { |e| puts e['error'] } # or JSONSchemer::Errors.pretty(e) And compare output with this validator: https://www.jsonschemavalidator.net/ , it gives a correct error tree for all nested schemas (especially for oneOf) and it is easy to find an actual source of the problem. It would be great to try to mimic their output messages as close as possible. |
And another notice is about public API. JSONSchemer.validate() method supports passing a Pathname, but resolved file contents is processed as string and not JSON.parse()'d as JSONSchemer.schema() does. schemer = JSONSchemer.schema(Pathname.new('schema.json'))
schemer.valid?(Pathname.new('data.json')) |
If you want a tree of errors, try "detailed" output{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:TSomeDocument/oneOf",
"instanceLocation": "/header/appliedDocument/0",
"error": "instance at `/header/appliedDocument/0` does not match exactly one `oneOf` schema",
"errors": [
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/0/properties/otherDocument/$ref/properties/documentTypes/items/$ref/oneOf",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:DocumentTypes/oneOf",
"instanceLocation": "/header/appliedDocument/0/otherDocument/documentTypes/0",
"error": "instance at `/header/appliedDocument/0/otherDocument/documentTypes/0` does not match exactly one `oneOf` schema",
"errors": [
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/0/properties/otherDocument/$ref/properties/documentTypes/items/$ref/oneOf/0/additionalProperties",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:DocumentTypes/oneOf/0/additionalProperties",
"instanceLocation": "/header/appliedDocument/0/otherDocument/documentTypes/0/testAddProp",
"error": "instance at `/header/appliedDocument/0/otherDocument/documentTypes/0/testAddProp` does not match schema"
},
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/0/properties/otherDocument/$ref/properties/documentTypes/items/$ref/oneOf/1",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:DocumentTypes/oneOf/1",
"instanceLocation": "/header/appliedDocument/0/otherDocument/documentTypes/0",
"error": "instance at `/header/appliedDocument/0/otherDocument/documentTypes/0` does not match schema",
"errors": [
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/0/properties/otherDocument/$ref/properties/documentTypes/items/$ref/oneOf/1/propertyNames/pattern",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:DocumentTypes/oneOf/1/propertyNames/pattern",
"instanceLocation": "/header/appliedDocument/0/otherDocument/documentTypes/0",
"error": "string at `/header/appliedDocument/0/otherDocument/documentTypes/0` does not match pattern: ^(?!documentTypeCode$).*"
},
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/0/properties/otherDocument/$ref/properties/documentTypes/items/$ref/oneOf/1/required",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:DocumentTypes/oneOf/1/required",
"instanceLocation": "/header/appliedDocument/0/otherDocument/documentTypes/0",
"error": "hash at `/header/appliedDocument/0/otherDocument/documentTypes/0` is missing required keys: [\"representativeDocTypeCode\"]"
}
]
}
]
},
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/1",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:TSomeDocument/oneOf/1",
"instanceLocation": "/header/appliedDocument/0",
"error": "instance at `/header/appliedDocument/0` does not match schema",
"errors": [
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/1/propertyNames/pattern",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:TSomeDocument/oneOf/1/propertyNames/pattern",
"instanceLocation": "/header/appliedDocument/0",
"error": "string at `/header/appliedDocument/0` does not match pattern: ^(?!otherDocument$|idDocument$|powerOfAttorney$|mapPlanDocument$|legalAct$|confirmPrivilege$).*"
},
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/1/required",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:TSomeDocument/oneOf/1/required",
"instanceLocation": "/header/appliedDocument/0",
"error": "hash at `/header/appliedDocument/0` is missing required keys: [\"paymentDocument\"]"
}
]
},
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/2",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:TSomeDocument/oneOf/2",
"instanceLocation": "/header/appliedDocument/0",
"error": "instance at `/header/appliedDocument/0` does not match schema",
"errors": [
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/2/propertyNames/pattern",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:TSomeDocument/oneOf/2/propertyNames/pattern",
"instanceLocation": "/header/appliedDocument/0",
"error": "string at `/header/appliedDocument/0` does not match pattern: ^(?!otherDocument$|paymentDocument$|powerOfAttorney$|mapPlanDocument$|legalAct$|confirmPrivilege$).*"
},
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/2/required",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:TSomeDocument/oneOf/2/required",
"instanceLocation": "/header/appliedDocument/0",
"error": "hash at `/header/appliedDocument/0` is missing required keys: [\"idDocument\"]"
}
]
},
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/3",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:TSomeDocument/oneOf/3",
"instanceLocation": "/header/appliedDocument/0",
"error": "instance at `/header/appliedDocument/0` does not match schema",
"errors": [
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/3/propertyNames/pattern",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:TSomeDocument/oneOf/3/propertyNames/pattern",
"instanceLocation": "/header/appliedDocument/0",
"error": "string at `/header/appliedDocument/0` does not match pattern: ^(?!otherDocument$|paymentDocument$|idDocument$|mapPlanDocument$|legalAct$|confirmPrivilege$).*"
},
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/3/required",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:TSomeDocument/oneOf/3/required",
"instanceLocation": "/header/appliedDocument/0",
"error": "hash at `/header/appliedDocument/0` is missing required keys: [\"powerOfAttorney\"]"
}
]
},
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/4",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:TSomeDocument/oneOf/4",
"instanceLocation": "/header/appliedDocument/0",
"error": "instance at `/header/appliedDocument/0` does not match schema",
"errors": [
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/4/propertyNames/pattern",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:TSomeDocument/oneOf/4/propertyNames/pattern",
"instanceLocation": "/header/appliedDocument/0",
"error": "string at `/header/appliedDocument/0` does not match pattern: ^(?!otherDocument$|paymentDocument$|idDocument$|powerOfAttorney$|legalAct$|confirmPrivilege$).*"
},
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/4/required",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:TSomeDocument/oneOf/4/required",
"instanceLocation": "/header/appliedDocument/0",
"error": "hash at `/header/appliedDocument/0` is missing required keys: [\"mapPlanDocument\"]"
}
]
},
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/5",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:TSomeDocument/oneOf/5",
"instanceLocation": "/header/appliedDocument/0",
"error": "instance at `/header/appliedDocument/0` does not match schema",
"errors": [
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/5/propertyNames/pattern",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:TSomeDocument/oneOf/5/propertyNames/pattern",
"instanceLocation": "/header/appliedDocument/0",
"error": "string at `/header/appliedDocument/0` does not match pattern: ^(?!otherDocument$|paymentDocument$|idDocument$|powerOfAttorney$|mapPlanDocument$|confirmPrivilege$).*"
},
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/5/required",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:TSomeDocument/oneOf/5/required",
"instanceLocation": "/header/appliedDocument/0",
"error": "hash at `/header/appliedDocument/0` is missing required keys: [\"legalAct\"]"
}
]
},
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/6",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:TSomeDocument/oneOf/6",
"instanceLocation": "/header/appliedDocument/0",
"error": "instance at `/header/appliedDocument/0` does not match schema",
"errors": [
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/6/propertyNames/pattern",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:TSomeDocument/oneOf/6/propertyNames/pattern",
"instanceLocation": "/header/appliedDocument/0",
"error": "string at `/header/appliedDocument/0` does not match pattern: ^(?!otherDocument$|paymentDocument$|idDocument$|powerOfAttorney$|mapPlanDocument$|legalAct$).*"
},
{
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/6/required",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:TSomeDocument/oneOf/6/required",
"instanceLocation": "/header/appliedDocument/0",
"error": "hash at `/header/appliedDocument/0` is missing required keys: [\"confirmPrivilege\"]"
}
]
}
]
} Is that close to what you're hoping for?
That's an interesting idea. I'm hesitant because |
I updated the branch to show a more useful error message: {
"valid": false,
"keywordLocation": "/$ref/properties/header/$ref/properties/appliedDocument/items/$ref/oneOf/0/properties/otherDocument/$ref/properties/documentTypes/items/$ref/oneOf/0/additionalProperties",
"absoluteKeywordLocation": "file:///Users/dharsha/Downloads/example2/schema.json#/definitions/n1:DocumentTypes/oneOf/0/additionalProperties",
"instanceLocation": "/header/appliedDocument/0/otherDocument/documentTypes/0/testAddProp",
"error": "property at `/header/appliedDocument/0/otherDocument/documentTypes/0/testAddProp` is not defined and schema does not allow additional properties"
}
I believe the behavior currently matches what's in the spec for the detailed output format, specifically:
That's likely why
This one's tricky because it's a
Yes, I updated this as well.
Did this work in previous versions? I believe json_schemer/lib/json_schemer/schema/base.rb Lines 441 to 448 in be345af
|
Seems like this is a new schema and I did not try it with previous versions... But that doesn't change my suggestion to add callback options for those :) |
Also I think it is better to rename |
👍 please open a separate issue to keep track of the suggestion.
Good call. @ekzobrain I appreciate the testing and suggestions. Did you run into any other issues testing things out with your schemas? |
I don't think this is really correct according to the [specification][0], but it matches the previous behavior and seems useful. Drafts after 7 don't have a problem because they allow all keywords as `$ref` siblings. Related: - #44 (comment) - json-schema-org/JSON-Schema-Test-Suite#458 [0]: https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-01#section-8.3
Features: - Draft 2020-12 support - Draft 2019-09 support - Output formats - Annotations - OpenAPI 3.1 schema support - OpenAPI 3.0 schema support - `insert_property_defaults` in conditional subschemas - Error messages - Non-string schema and data keys - Schema bundling See individual commits for more details. Closes: - #27 - #44 - #55 - #91 - #94 - #116 - #123 - #136
Currently not. I think it's time to make a release, if you are ready, and then move forward. |
No description provided.
The text was updated successfully, but these errors were encountered: