Support JSON Schema 2019 and 2020#1166
Conversation
src/languageservice/parser/schemaValidation/baseValidator.ts
Dismissed
Show dismissed
Hide dismissed
src/languageservice/parser/schemaValidation/baseValidator.ts
Dismissed
Show dismissed
Hide dismissed
src/languageservice/parser/schemaValidation/baseValidator.ts
Dismissed
Show dismissed
Hide dismissed
| // eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
| _node: ObjectASTNode, | ||
| // eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
| _schema: JSONSchema, |
Check warning
Code scanning / ESLint
Disallow unused variables Warning
| // eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
| _validationResult: ValidationResult, | ||
| // eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
| _matchingSchemas: ISchemaCollector, |
Check warning
Code scanning / ESLint
Disallow unused variables Warning
| // eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
| _matchingSchemas: ISchemaCollector, | ||
| // eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
| _options: Options |
Check warning
Code scanning / ESLint
Disallow unused variables Warning
|
|
||
| const propertyNode = child.type === 'property' ? child : (child.parent as ASTNode); | ||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| const keyNode = (propertyNode as any).keyNode; |
Check warning
Code scanning / ESLint
Disallow the `any` type Warning
Signed-off-by: Morgan Chang <shin19991207@gmail.com>
Signed-off-by: Morgan Chang <shin19991207@gmail.com>
…pendencies for backward compatibility Signed-off-by: Morgan Chang <shin19991207@gmail.com>
… to contains and unevaluatedItems Signed-off-by: Morgan Chang <shin19991207@gmail.com>
2aa38a8 to
9d322fa
Compare
Update baseValidator (split out from the original jsonParser07)
updated $ref resolution to support sibling keywords for Draft-2019+ and fixed $ref resolution bug for Draft-07 and earlier
Signed-off-by: Morgan Chang <shin19991207@gmail.com>
…ma Document Signed-off-by: Morgan Chang <shin19991207@gmail.com>
Signed-off-by: Morgan Chang <shin19991207@gmail.com>
Signed-off-by: Morgan Chang <shin19991207@gmail.com>
Signed-off-by: Morgan Chang <shin19991207@gmail.com>
…pendencies for backward compatibility Signed-off-by: Morgan Chang <shin19991207@gmail.com>
… to contains and unevaluatedItems Signed-off-by: Morgan Chang <shin19991207@gmail.com>
Update baseValidator (split out from the original jsonParser07)
updated $ref resolution to support sibling keywords for Draft-2019+ and fixed $ref resolution bug for Draft-07 and earlier
Signed-off-by: Morgan Chang <shin19991207@gmail.com>
…ma Document Signed-off-by: Morgan Chang <shin19991207@gmail.com>
…language-server into chang-patch-2019-2020
Signed-off-by: Morgan Chang <shin19991207@gmail.com>
Signed-off-by: Morgan Chang <shin19991207@gmail.com>
Signed-off-by: Morgan Chang <shin19991207@gmail.com>
Signed-off-by: Morgan Chang <shin19991207@gmail.com>
…ans on the schema and use a post‑order pass in _indexSchemaResources for meta-validation instead Signed-off-by: Morgan Chang <shin19991207@gmail.com>
Signed-off-by: Morgan Chang <shin19991207@gmail.com>
|
I'm trying out a bunch of the schemas from this repo: https://github.com/json-schema-org/JSON-Schema-Test-Suite This case doesn't seem to work properly: https://github.com/json-schema-org/JSON-Schema-Test-Suite/blob/main/tests/draft2019-09/recursiveRef.json#L319 |
|
@datho7561 Thanks for catching those! I only discovered the JSON‑Schema‑Test‑Suite repo last week, so I had only added the recursive/dynamic reference tests. I’ll pull in more automated tests from it .... |
Signed-off-by: Morgan Chang <shin19991207@gmail.com>
Signed-off-by: Morgan Chang <shin19991207@gmail.com>
…rg/JSON-Schema-Test-Suite Signed-off-by: Morgan Chang <shin19991207@gmail.com>
Signed-off-by: Morgan Chang <shin19991207@gmail.com>
datho7561
left a comment
There was a problem hiding this comment.
Works well, it's well tested, and the refactoring seems to have cleaned up the code a lot. Thanks, Morgan! Well done!
What does this PR do?
Changes
Refactor / architecture
Draft 2019-09 support
$anchorresolution$defsresolution (renamed +definitionscompat)definitions)$id$recursiveAnchor/$recursiveRef$refresolution updated to support sibling keywords$vocabularydependentSchemasunevaluatedItemsunevaluatedPropertiesdependentRequiredcontains+minContains/maxContainsDraft 2020-12 support
prefixItems+items$dynamicAnchor/$dynamicRefcontainsandunevaluatedItemssafeCreateUnicodeRegExp()For Compound Schema Document:
$schemafield is validated against its own dialect’s meta‑schema; mixed‑dialect schemas are cloned with subschemas replaced by{}at dialect boundaries to prevent validation conflictsAdditional fixes
The current implementation of
$refresolution is incorrect, as sibling keywords are not being ignored as required by Draft‑07 (and earlier). According to the JSON Schema Draft‑07 specification (Section 8.3), "An object schema with a "$ref" property MUST be interpreted as a "$ref" reference. ... All other properties in a "$ref" object MUST be ignored."Using the following schema:
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "value": { "$ref": "#/definitions/A", "type": "number" } }, "required": ["value"], "definitions": { "A": { "type": "string" } } }Draft‑07 requires the
"type": "number"keyword to be ignored, because it is a sibling of$ref. Validation should therefore use only the referenced schema{ "type": "string" }.Expected results:
value: "hello"=> validvalue: 1=> Incorrect type. Expected "string".However, the current implementation produces:
value: "hello"=> Incorrect type. Expected "number".value: 1=> validThis PR updates the behavior to correctly ignore sibling keywords and match the expected Draft‑07 semantics.
This should fix Rejects schemas where $ref refers to $id or $anchor #823.
Fixes base‑URI/$id resolution:
Example 1: root $id changes base for relative $ref
{ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://www.schemastore.org/", "type": "object", "properties": { "pkg": { "$ref": "package.json" } } } # pkg: 123Before fix: ref is resolved against the retrieval URL file:///…/package.json and gives “Problems loading reference...” error
After fix: use base from $id, so it resolves to https://www.schemastore.org/package.json and validates pkg.
Example 2: plain‑name fragment from $id
{ "$schema": "http://json-schema.org/draft-07/schema#", "definitions": { "Name": { "$id": "#Thing", "type": "string", "minLength": 2 } }, "$ref": "#Thing" } # ABefore fix: #Thing is treated as an unresolved
$refand gives “$ref 'Thing' … cannot be resolved” error.After fix: #Thing resolves to definitions.Name and validates minLength
Example 3: embedded resource $id
{ "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "x": { "$ref": "other.json#bar" } }, "required": ["x"], "defs": { "B": { "$id": "other.json", "$defs": { "X": { "$anchor": "bar", "type": "string", "minLength": 2 } } } } } # x: ABefore fix: attempts to fetch other.json externally and gives "Problems loading reference..." error
After fix: resolves to the embedded resource and validates minLength
What issues does this PR fix or reference?
#856
#1112
Should also:
Is it tested? How?
Footnotes
Meta‑validation support for Draft‑2019/2020 was added in PR https://github.com/redhat-developer/yaml-language-server/pull/1164 ↩ ↩2