Skip to content
49 changes: 49 additions & 0 deletions src/error-handlers/draft-04/dependencies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { getSchema } from "@hyperjump/json-schema/experimental";
import * as Schema from "@hyperjump/browser";
import * as Instance from "@hyperjump/json-schema/instance/experimental";
import { getErrors } from "../../json-schema-errors.js";

/**
* @import { ErrorHandler, ErrorObject } from "../../index.d.ts"
*/

/** @type ErrorHandler */
const dependenciesErrorHandler = async (normalizedErrors, instance, localization) => {
/** @type ErrorObject[] */
const errors = [];

for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/draft-04/dependencies"]) {
if (typeof normalizedErrors["https://json-schema.org/keyword/draft-04/dependencies"][schemaLocation] === "boolean") {
continue;
}

const dependentSchemaOutputs = normalizedErrors["https://json-schema.org/keyword/draft-04/dependencies"][schemaLocation];
for (const dependentSchemaOutput of dependentSchemaOutputs) {
const dependentSchemaErrors = await getErrors(dependentSchemaOutput, instance, localization);
errors.push(...dependentSchemaErrors);
}

const dependencies = await getSchema(schemaLocation);
for await (const [propertyName, dependency] of Schema.entries(dependencies)) {
if (!Instance.has(propertyName, instance)) {
continue;
}

if (Schema.typeOf(dependency) !== "array") {
continue;
}

const dependentRequired = /** @type {string[]} */ (Schema.value(dependency));
const missing = dependentRequired.filter((required) => !Instance.has(required, instance));
errors.push({
message: localization.getRequiredErrorMessage(missing),
instanceLocation: Instance.uri(instance),
schemaLocations: [schemaLocation]
});
}
}

return errors;
};

export default dependenciesErrorHandler;
55 changes: 55 additions & 0 deletions src/error-handlers/draft-04/maximum.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { getSchema } from "@hyperjump/json-schema/experimental";
import * as Schema from "@hyperjump/browser";
import * as Instance from "@hyperjump/json-schema/instance/experimental";

/**
* @import { ErrorHandler, ErrorObject } from "../../index.d.ts"
*/

/** @type ErrorHandler */
const maximumErrorHandler = async (normalizedErrors, instance, localization) => {
/** @type ErrorObject[] */
const errors = [];

for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/draft-04/maximum"]) {
if (normalizedErrors["https://json-schema.org/keyword/draft-04/maximum"][schemaLocation]) {
continue;
}

const parentLocation = pointerPop(schemaLocation);

let exclusive = false;
for (const exclusiveLocation in normalizedErrors["https://json-schema.org/keyword/draft-04/exclusiveMaximum"]) {
const exclusiveParentLocation = pointerPop(exclusiveLocation);
if (exclusiveParentLocation === parentLocation) {
const exclusiveNode = await getSchema(exclusiveLocation);
exclusive = /** @type boolean */ (Schema.value(exclusiveNode));
break;
}
}

const keywordNode = await getSchema(schemaLocation);
const maximum = /** @type number */ (Schema.value(keywordNode));

if (exclusive) {
errors.push({
message: localization.getExclusiveMaximumErrorMessage(maximum),
instanceLocation: Instance.uri(instance),
schemaLocations: [schemaLocation]
});
} else {
errors.push({
message: localization.getMaximumErrorMessage(maximum),
instanceLocation: Instance.uri(instance),
schemaLocations: [schemaLocation]
});
}
}

return errors;
};

/** @type (pointer: string) => string */
const pointerPop = (pointer) => pointer.replace(/\/[^/]+$/, "");

export default maximumErrorHandler;
55 changes: 55 additions & 0 deletions src/error-handlers/draft-04/minimum.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { getSchema } from "@hyperjump/json-schema/experimental";
import * as Schema from "@hyperjump/browser";
import * as Instance from "@hyperjump/json-schema/instance/experimental";

/**
* @import { ErrorHandler, ErrorObject } from "../../index.d.ts"
*/

/** @type ErrorHandler */
const minimumErrorHandler = async (normalizedErrors, instance, localization) => {
/** @type ErrorObject[] */
const errors = [];

for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/draft-04/minimum"]) {
if (normalizedErrors["https://json-schema.org/keyword/draft-04/minimum"][schemaLocation]) {
continue;
}

const parentLocation = pointerPop(schemaLocation);

let exclusive = false;
for (const exclusiveLocation in normalizedErrors["https://json-schema.org/keyword/draft-04/exclusiveMinimum"]) {
const exclusiveParentLocation = pointerPop(exclusiveLocation);
if (exclusiveParentLocation === parentLocation) {
const exclusiveNode = await getSchema(exclusiveLocation);
exclusive = /** @type boolean */ (Schema.value(exclusiveNode));
break;
}
}

const keywordNode = await getSchema(schemaLocation);
const minimum = /** @type number */ (Schema.value(keywordNode));

if (exclusive) {
errors.push({
message: localization.getExclusiveMinimumErrorMessage(minimum),
instanceLocation: Instance.uri(instance),
schemaLocations: [schemaLocation]
});
} else {
errors.push({
message: localization.getMinimumErrorMessage(minimum),
instanceLocation: Instance.uri(instance),
schemaLocations: [schemaLocation]
});
}
}

return errors;
};

/** @type (pointer: string) => string */
const pointerPop = (pointer) => pointer.replace(/\/[^/]+$/, "");

export default minimumErrorHandler;
3 changes: 2 additions & 1 deletion src/hyperjump-json-schema.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
validate
} from "@hyperjump/json-schema/draft-2020-12";
import "@hyperjump/json-schema/draft-2019-09";
import "@hyperjump/json-schema/draft-04";
import "@hyperjump/json-schema/formats";
import { BASIC } from "@hyperjump/json-schema/experimental";
import { jsonSchemaErrors } from "../src/index.js";
Expand Down Expand Up @@ -184,4 +185,4 @@ runTests("https://json-schema.org/draft/2020-12/schema", 2020);
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);
runTests("http://json-schema.org/draft-04/schema", 4);
16 changes: 16 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,27 @@ import anyOfNormalizationHandler from "./normalization-handlers/anyOf.js";
import constNormalizationHandler from "./normalization-handlers/const.js";
import containsNormalizationHandler from "./normalization-handlers/contains.js";
import definitionsNormalizationHandler from "./normalization-handlers/definitions.js";
import dependenciesNormalizationHandler from "./normalization-handlers/draft-04/dependencies.js";
import dependentRequiredNormalizationHandler from "./normalization-handlers/dependentRequired.js";
import dependentSchemasNormalizationHandler from "./normalization-handlers/dependentSchemas.js";
import dynamicRefNormalizationHandler from "./normalization-handlers/dynamicRef.js";
import elseNormalizationHandler from "./normalization-handlers/else.js";
import enumNormalizationHandler from "./normalization-handlers/enum.js";
import exclusiveMaximumDraft04NormalizationHandler from "./normalization-handlers/draft-04/exclusiveMaximum.js";
import exclusiveMaximumNormalizationHandler from "./normalization-handlers/exclusiveMaximum.js";
import exclusiveMinimumDraft04NormalizationHandler from "./normalization-handlers/draft-04/exclusiveMinimum.js";
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 maximumDraft04NormalizationHandler from "./normalization-handlers/draft-04/maximum.js";
import maximumNormalizationHandler from "./normalization-handlers/maximum.js";
import maxContainsNormalizationHandler from "./normalization-handlers/maxContains.js";
import maxItemsNormalizationHandler from "./normalization-handlers/maxItems.js";
import maxLengthNormalizationHandler from "./normalization-handlers/maxLength.js";
import maxPropertiesNormalizationHandler from "./normalization-handlers/maxProperties.js";
import minimumDraft04NormalizationHandler from "./normalization-handlers/draft-04/minimum.js";
import minimumNormalizationHandler from "./normalization-handlers/minimum.js";
import minContainsNormalizationHandler from "./normalization-handlers/minContains.js";
import minItemsNormalizationHandler from "./normalization-handlers/minItems.js";
Expand Down Expand Up @@ -51,15 +56,18 @@ import anyOfErrorHandler from "./error-handlers/anyOf.js";
import booleanSchemaErrorHandler from "./error-handlers/boolean-schema.js";
import constErrorHandler from "./error-handlers/const.js";
import containsErrorHandler from "./error-handlers/contains.js";
import dependenciesErrorHandler from "./error-handlers/draft-04/dependencies.js";
import dependentRequiredErrorHandler from "./error-handlers/dependentRequired.js";
import enumErrorHandler from "./error-handlers/enum.js";
import exclusiveMaximumErrorHandler from "./error-handlers/exclusiveMaximum.js";
import exclusiveMinimumErrorHandler from "./error-handlers/exclusiveMinimum.js";
import formatErrorHandler from "./error-handlers/format.js";
import maximumDraft04ErrorHandler from "./error-handlers/draft-04/maximum.js";
import maximumErrorHandler from "./error-handlers/maximum.js";
import maxItemsErrorHandler from "./error-handlers/maxItems.js";
import maxLengthErrorHandler from "./error-handlers/maxLength.js";
import maxPropertiesErrorHandler from "./error-handlers/maxProperties.js";
import minimumDraft04ErrorHandler from "./error-handlers/draft-04/minimum.js";
import minimumErrorHandler from "./error-handlers/minimum.js";
import minItemsErrorHandler from "./error-handlers/minItems.js";
import minLengthErrorHandler from "./error-handlers/minLength.js";
Expand All @@ -80,6 +88,7 @@ setNormalizationHandler("https://json-schema.org/keyword/anyOf", anyOfNormalizat
setNormalizationHandler("https://json-schema.org/keyword/const", constNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/contains", containsNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/definitions", definitionsNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/draft-04/dependencies", dependenciesNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/dependentRequired", dependentRequiredNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/dependentSchemas", dependentSchemasNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/draft-2020-12/dynamicRef", dynamicRefNormalizationHandler);
Expand All @@ -95,13 +104,17 @@ setNormalizationHandler("https://json-schema.org/keyword/draft-04/format", forma
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/draft-04/exclusiveMaximum", exclusiveMaximumDraft04NormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/exclusiveMaximum", exclusiveMaximumNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/draft-04/exclusiveMinimum", exclusiveMinimumDraft04NormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/exclusiveMinimum", exclusiveMinimumNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/draft-04/maximum", maximumDraft04NormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/maximum", maximumNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/maxContains", maxContainsNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/maxItems", maxItemsNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/maxLength", maxLengthNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/maxProperties", maxPropertiesNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/draft-04/minimum", minimumDraft04NormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/minimum", minimumNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/minContains", minContainsNormalizationHandler);
setNormalizationHandler("https://json-schema.org/keyword/minItems", minItemsNormalizationHandler);
Expand All @@ -128,15 +141,18 @@ addErrorHandler(anyOfErrorHandler);
addErrorHandler(booleanSchemaErrorHandler);
addErrorHandler(constErrorHandler);
addErrorHandler(containsErrorHandler);
addErrorHandler(dependenciesErrorHandler);
addErrorHandler(dependentRequiredErrorHandler);
addErrorHandler(enumErrorHandler);
addErrorHandler(exclusiveMaximumErrorHandler);
addErrorHandler(exclusiveMinimumErrorHandler);
addErrorHandler(formatErrorHandler);
addErrorHandler(maximumDraft04ErrorHandler);
addErrorHandler(maximumErrorHandler);
addErrorHandler(maxItemsErrorHandler);
addErrorHandler(maxLengthErrorHandler);
addErrorHandler(maxPropertiesErrorHandler);
addErrorHandler(minimumDraft04ErrorHandler);
addErrorHandler(minimumErrorHandler);
addErrorHandler(minItemsErrorHandler);
addErrorHandler(minLengthErrorHandler);
Expand Down
30 changes: 30 additions & 0 deletions src/normalization-handlers/draft-04/dependencies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
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 | string[]][]> */
const dependenciesNormalizationHandler = {
evaluate(dependencies, instance, context) {
/** @type NormalizedOutput[] */
const outputs = [];

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

for (const [propertyName, dependency] of dependencies) {
if (!Instance.has(propertyName, instance) || typeof dependency !== "string") {
continue;
}

outputs.push(evaluateSchema(dependency, instance, context));
}

return outputs;
}
};

export default dependenciesNormalizationHandler;
11 changes: 11 additions & 0 deletions src/normalization-handlers/draft-04/exclusiveMaximum.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* @import { NormalizationHandler } from "../../index.d.ts"
*/

/** @type NormalizationHandler */
const exclusiveMaximumNormalizationHandler = {
evaluate() {
}
};

export default exclusiveMaximumNormalizationHandler;
11 changes: 11 additions & 0 deletions src/normalization-handlers/draft-04/exclusiveMinimum.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* @import { NormalizationHandler } from "../../index.d.ts"
*/

/** @type NormalizationHandler */
const exclusiveMinimumNormalizationHandler = {
evaluate() {
}
};

export default exclusiveMinimumNormalizationHandler;
11 changes: 11 additions & 0 deletions src/normalization-handlers/draft-04/maximum.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* @import { NormalizationHandler } from "../../index.d.ts"
*/

/** @type NormalizationHandler */
const maximumNormalizationHandler = {
evaluate() {
}
};

export default maximumNormalizationHandler;
11 changes: 11 additions & 0 deletions src/normalization-handlers/draft-04/minimum.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* @import { NormalizationHandler } from "../../index.d.ts"
*/

/** @type NormalizationHandler */
const minimumNormalizationHandler = {
evaluate() {
}
};

export default minimumNormalizationHandler;
2 changes: 2 additions & 0 deletions src/test-suite/tests/boolean-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"tests": [
{
"description": "false schema on a property",
"compatibility": "6",
"schema": {
"properties": {
"foo": false
Expand All @@ -23,6 +24,7 @@
},
{
"description": "true schema on a property",
"compatibility": "6",
"schema": {
"properties": {
"foo": true,
Expand Down
Loading