Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/hyperjump-json-schema.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
unregisterSchema,
validate
} from "@hyperjump/json-schema/draft-2020-12";
import "@hyperjump/json-schema/draft-2019-09";
import "@hyperjump/json-schema/formats";
import { BASIC } from "@hyperjump/json-schema/experimental";
import { jsonSchemaErrors } from "../src/index.js";
Expand Down Expand Up @@ -180,7 +181,7 @@ const getMessage = await (async function () {
}());

runTests("https://json-schema.org/draft/2020-12/schema", 2020);
// runTests("https://json-schema.org/draft/2019-09/schema", 2019);
runTests("https://json-schema.org/draft/2019-09/schema", 2019);
// runTests("http://json-schema.org/draft-07/schema", 7);
// runTests("http://json-schema.org/draft-06/schema", 6);
// runTests("http://json-schema.org/draft-04/schema", 4);
4 changes: 4 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { addErrorHandler, setNormalizationHandler } from "./json-schema-errors.js";

// Normalization Handlers
import additionalItemsNormalizationHandler from "./normalization-handlers/draft-04/additionalItems.js";
import additionalPropertiesNormalizationHandler from "./normalization-handlers/additionalProperties.js";
import allOfNormalizationHandler from "./normalization-handlers/allOf.js";
import anyOfNormalizationHandler from "./normalization-handlers/anyOf.js";
Expand All @@ -16,6 +17,7 @@ import exclusiveMaximumNormalizationHandler from "./normalization-handlers/exclu
import exclusiveMinimumNormalizationHandler from "./normalization-handlers/exclusiveMinimum.js";
import formatNormalizationHandler from "./normalization-handlers/format.js";
import ifNormalizationHandler from "./normalization-handlers/if.js";
import itemsDraft04NormalizationHandler from "./normalization-handlers/draft-04/items.js";
import itemsNormalizationHandler from "./normalization-handlers/items.js";
import maximumNormalizationHandler from "./normalization-handlers/maximum.js";
import maxContainsNormalizationHandler from "./normalization-handlers/maxContains.js";
Expand Down Expand Up @@ -71,6 +73,7 @@ import typeErrorHandler from "./error-handlers/type.js";
import uniqueItemsErrorHandler from "./error-handlers/uniqueItems.js";
import unknownErrorHandler from "./error-handlers/unknown.js";

setNormalizationHandler("https://json-schema.org/keyword/draft-04/additionalItems", additionalItemsNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/additionalProperties", additionalPropertiesNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/allOf", allOfNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/anyOf", anyOfNormalizationHandler);
Expand All @@ -90,6 +93,7 @@ setNormalizationHandler("https://json-schema.org/keyword/draft-07/format", forma
setNormalizationHandler("https://json-schema.org/keyword/draft-06/format", formatNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/draft-04/format", formatNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/if", ifNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/draft-04/items", itemsDraft04NormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/items", itemsNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/exclusiveMaximum", exclusiveMaximumNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/exclusiveMinimum", exclusiveMinimumNormalizationHandler);
Expand Down
28 changes: 28 additions & 0 deletions src/normalization-handlers/draft-04/additionalItems.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { evaluateSchema } from "../../json-schema-errors.js";
import * as Instance from "@hyperjump/json-schema/instance/experimental";
import * as Pact from "@hyperjump/pact";

/**
* @import { NormalizationHandler, NormalizedOutput } from "../../index.d.ts"
*/

/** @type NormalizationHandler<[number, string]> */
const additionalItemsNormalizationHandler = {
evaluate([numberOfItems, additionalItems], instance, context) {
/** @type NormalizedOutput[] */
const outputs = [];

if (Instance.typeOf(instance) !== "array") {
return outputs;
}

for (const itemNode of Pact.drop(numberOfItems, Instance.iter(instance))) {
outputs.push(evaluateSchema(additionalItems, itemNode, context));
}

return outputs;
},
simpleApplicator: true
};

export default additionalItemsNormalizationHandler;
36 changes: 36 additions & 0 deletions src/normalization-handlers/draft-04/items.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { evaluateSchema } from "../../json-schema-errors.js";
import * as Instance from "@hyperjump/json-schema/instance/experimental";

/**
* @import { NormalizationHandler, NormalizedOutput } from "../../index.d.ts"
*/

/** @type NormalizationHandler<string | string[]> */
const itemsDraft04NormalizationHandler = {
evaluate(items, instance, context) {
/** @type NormalizedOutput[] */
const outputs = [];

if (Instance.typeOf(instance) !== "array") {
return outputs;
}

if (typeof items === "string") {
for (const itemNode of Instance.iter(instance)) {
outputs.push(evaluateSchema(items, itemNode, context));
}
} else {
for (const [index, schemaLocation] of items.entries()) {
const itemNode = Instance.step(String(index), instance);
if (itemNode) {
outputs.push(evaluateSchema(schemaLocation, itemNode, context));
}
}
}

return outputs;
},
simpleApplicator: true
};

export default itemsDraft04NormalizationHandler;
83 changes: 75 additions & 8 deletions src/test-suite/tests/items.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,24 @@
"description": "The items keyword",
"tests": [
{
"description": "items with false schema",
"description": "all items",
"schema": {
"items": { "type": "number" }
},
"instance": [42, "foo"],
"errors": [
{
"messageId": "type-message",
"messageParams": {
"expectedTypes": { "or": ["number"] }
},
"instanceLocation": "#/1",
"schemaLocations": ["#/items/type"]
}
]
},
{
"description": "prefixItems/items with false schema",
"compatibility": "2020",
"schema": {
"prefixItems": [{ "type": "number" }],
Expand All @@ -21,7 +38,24 @@
]
},
{
"description": "items with object schema",
"description": "items/additionalItems with false schema",
"compatibility": "<=2019",
"schema": {
"items": [{ "type": "number" }],
"additionalItems": false
},
"instance": [42, "foo"],
"errors": [
{
"messageId": "boolean-schema-message",
"messageParams": {},
"instanceLocation": "#/1",
"schemaLocations": ["#/additionalItems"]
}
]
},
{
"description": "prefix/items with object schema",
"compatibility": "2020",
"schema": {
"prefixItems": [{ "type": "number" }],
Expand All @@ -39,24 +73,57 @@
}
]
},
{
"description": "items/additionalItems with object schema",
"compatibility": "<=2019",
"schema": {
"items": [{ "type": "number" }],
"additionalItems": { "type": "string" }
},
"instance": [42, null],
"errors": [
{
"messageId": "type-message",
"messageParams": {
"expectedTypes": { "or": ["string"] }
},
"instanceLocation": "#/1",
"schemaLocations": ["#/additionalItems/type"]
}
]
},
{
"description": "items on a non-object",
"compatibility": "2020",
"schema": {
"prefixItems": [{ "type": "number" }],
"items": { "type": "string" }
},
"instance": 42,
"errors": []
},
{
"description": "additionalItems on a non-array",
"compatibility": "<=2019",
"schema": {
"additionalItems": { "type": "string" }
},
"instance": 42,
"errors": []
},
{
"description": "items pass",
"compatibility": "2020",
"schema": {
"prefixItems": [{ "type": "number" }],
"items": { "type": "string" }
"items": { "type": "number" }
},
"instance": [42, "foo"],
"instance": [42, 24],
"errors": []
},
{
"description": "additionalItems pass",
"compatibility": "<=2019",
"schema": {
"additionalItems": { "type": "number" }
},
"instance": [42, 24],
"errors": []
}
]
Expand Down
59 changes: 58 additions & 1 deletion src/test-suite/tests/prefixItems.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,24 @@
}
]
},
{
"description": "array-form items",
"compatibility": "<=2019",
"schema": {
"items": [{ "type": "number" }]
},
"instance": ["foo"],
"errors": [
{
"messageId": "type-message",
"messageParams": {
"expectedTypes": { "or": ["number"] }
},
"instanceLocation": "#/0",
"schemaLocations": ["#/items/0/type"]
}
]
},
{
"description": "prefixItems with fewer items than are defined",
"compatibility": "2020",
Expand All @@ -43,21 +61,60 @@
]
},
{
"description": "prefixItems on an non-object",
"description": "array-form items with fewer items than are defined",
"compatibility": "<=2019",
"schema": {
"items": [
{ "type": "number" },
{ "type": "string" }
]
},
"instance": ["foo"],
"errors": [
{
"messageId": "type-message",
"messageParams": {
"expectedTypes": { "or": ["number"] }
},
"instanceLocation": "#/0",
"schemaLocations": ["#/items/0/type"]
}
]
},
{
"description": "prefixItems on an non-array",
"compatibility": "2020",
"schema": {
"prefixItems": [{ "type": "number" }]
},
"instance": 42,
"errors": []
},
{
"description": "array-form items on an non-array",
"compatibility": "<=2019",
"schema": {
"items": [{ "type": "number" }]
},
"instance": 42,
"errors": []
},
{
"description": "prefixItems pass",
"schema": {
"prefixItems": [{ "type": "number" }]
},
"instance": { "foo": 42 },
"errors": []
},
{
"description": "array-form items pass",
"compatibility": "<=2019",
"schema": {
"items": [{ "type": "number" }]
},
"instance": { "foo": 42 },
"errors": []
}
]
}