Skip to content

Commit 3de558d

Browse files
committed
Support schema self-identification and throw on unsupported keywords
1 parent 23ed690 commit 3de558d

File tree

2 files changed

+37
-7
lines changed

2 files changed

+37
-7
lines changed

src/index.js

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,14 @@ import { Output } from "./output.js";
2424

2525
/** @type (schema: Json, instance: Json) => Output */
2626
export const validate = (schema, instance) => {
27-
registerSchema(schema, "");
28-
const schemaNode = /** @type NonNullable<JsonNode> */ (schemaRegistry.get(""));
27+
// Determine schema identifier
28+
const uri = typeof schema === "object" && schema !== null && !Array.isArray(schema)
29+
&& typeof schema.$id === "string" ? schema.$id : "";
30+
registerSchema(schema, uri);
2931

32+
const schemaNode = /** @type NonNullable<JsonNode> */ (schemaRegistry.get(uri));
33+
34+
// Verify the dialect is supported
3035
if (schemaNode.jsonType === "object" && jsonObjectHas("$schema", schemaNode)) {
3136
const $schema = jsonPointerStep("$schema", schemaNode);
3237
if ($schema.jsonType === "string" && $schema.value !== "https://json-schema.org/draft/2020-12/schema") {
@@ -36,7 +41,7 @@ export const validate = (schema, instance) => {
3641

3742
const output = validateSchema(schemaNode, toJsonNode(instance));
3843

39-
schemaRegistry.delete("");
44+
schemaRegistry.delete(uri);
4045

4146
return output;
4247
};
@@ -625,3 +630,31 @@ keywordHandlers.set("uniqueItems", (uniqueItemsNode, instanceNode) => {
625630
const isValid = new Set(normalizedItems).size === normalizedItems.length;
626631
return new Output(isValid, uniqueItemsNode, instanceNode);
627632
});
633+
634+
keywordHandlers.set("$id", (idNode, instanceNode, schemaNode) => {
635+
if (!idNode.location.endsWith("#/$id")) {
636+
throw Error(`Embedded schemas are not supported. Found at ${schemaNode.location}`);
637+
}
638+
639+
return new Output(true, idNode, instanceNode);
640+
});
641+
642+
keywordHandlers.set("$anchor", (anchorNode) => {
643+
throw Error(`The '$anchor' keyword is not supported. Found at ${anchorNode.location}`);
644+
});
645+
646+
keywordHandlers.set("$dynamicAnchor", (dynamicAnchorNode) => {
647+
throw Error(`The '$dynamicAnchor' keyword is not supported. Found at ${dynamicAnchorNode.location}`);
648+
});
649+
650+
keywordHandlers.set("$dynamicRef", (dynamicRefNode) => {
651+
throw Error(`The '$dynamicRef' keyword is not supported. Found at ${dynamicRefNode.location}`);
652+
});
653+
654+
keywordHandlers.set("unevaluatedProperties", (unevaluatedPropertiesNode) => {
655+
throw Error(`The 'unevaluatedProperties' keyword is not supported. Found at ${unevaluatedPropertiesNode.location}`);
656+
});
657+
658+
keywordHandlers.set("unevaluatedItems", (unevaluatedItemsNode) => {
659+
throw Error(`The 'unevaluatedItems' keyword is not supported. Found at ${unevaluatedItemsNode.location}`);
660+
});

src/json-schema-test-suite.test.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const skip = new Set([
3030
"|defs.json",
3131
"|dynamicRef.json",
3232
"|not.json|collect annotations inside a 'not', even if collection is disabled",
33+
"|ref.json|remote ref, containing refs itself",
3334
"|ref.json|Recursive references between schemas",
3435
"|ref.json|ref creates new scope when adjacent to keywords",
3536
"|ref.json|refs with relative uris and defs",
@@ -38,7 +39,6 @@ const skip = new Set([
3839
"|ref.json|order of evaluation: $id and $ref",
3940
"|ref.json|order of evaluation: $id and $anchor and $ref",
4041
"|ref.json|simple URN base URI with $ref via the URN",
41-
"|ref.json|URN base URI with URN and JSON pointer ref",
4242
"|ref.json|URN base URI with URN and anchor ref",
4343
"|ref.json|URN ref with nested pointer ref",
4444
"|ref.json|ref to if",
@@ -49,10 +49,7 @@ const skip = new Set([
4949
"|refRemote.json|base URI change",
5050
"|refRemote.json|base URI change - change folder",
5151
"|refRemote.json|base URI change - change folder in subschema",
52-
"|refRemote.json|root ref in remote ref",
53-
"|refRemote.json|remote ref with ref to defs",
5452
"|refRemote.json|Location-independent identifier in remote ref",
55-
"|refRemote.json|retrieved nested refs resolve relative to their URI not $id",
5653
"|refRemote.json|remote HTTP ref with nested absolute ref",
5754
"|refRemote.json|$ref to $ref finds detached $anchor",
5855
"|unevaluatedItems.json",

0 commit comments

Comments
 (0)