Skip to content

Commit 3555432

Browse files
committed
refactor: remove async schema lookups from error handlers & wiring with getErrors
1 parent d71a75a commit 3555432

23 files changed

Lines changed: 207 additions & 167 deletions

src/error-handlers/anyOf.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { getErrors } from "../json-schema-errors.js";
77
*/
88

99
/** @type ErrorHandler */
10-
const anyOfErrorHandler = async (normalizedErrors, instance, localization) => {
10+
const anyOfErrorHandler = (normalizedErrors, instance, localization, resolver) => {
1111
/** @type ErrorObject[] */
1212
const errors = [];
1313

@@ -51,13 +51,13 @@ const anyOfErrorHandler = async (normalizedErrors, instance, localization) => {
5151
}
5252

5353
// The alternative passed all the filters
54-
alternatives.push(await getErrors(alternative, instance, localization));
54+
alternatives.push(getErrors(alternative, instance, localization, resolver));
5555
}
5656

5757
// If all alternatives were filtered out, default to returning all of them
5858
if (alternatives.length === 0) {
5959
for (const alternative of anyOf) {
60-
alternatives.push(await getErrors(alternative, instance, localization));
60+
alternatives.push(getErrors(alternative, instance, localization, resolver));
6161
}
6262
}
6363

src/error-handlers/boolean-schema.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import * as Instance from "@hyperjump/json-schema/instance/experimental";
55
*/
66

77
/** @type ErrorHandler */
8-
const booleanSchemaErrorHandler = async (normalizedErrors, instance, localization) => {
8+
const booleanSchemaErrorHandler = (normalizedErrors, instance, localization) => {
99
/** @type ErrorObject[] */
1010
const errors = [];
1111

src/error-handlers/contains.js

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
1-
import { getSchema } from "@hyperjump/json-schema/experimental";
2-
import * as Schema from "@hyperjump/browser";
31
import * as Instance from "@hyperjump/json-schema/instance/experimental";
42

53
/**
64
* @import { ContainsRange, ErrorHandler, ErrorObject } from "../index.d.ts"
75
*/
86

97
/** @type ErrorHandler */
10-
const containsErrorHandler = async (normalizedErrors, instance, localization) => {
8+
const containsErrorHandler = (normalizedErrors, instance, localization, resolver) => {
9+
/** @type {{
10+
* getSiblingKeywordValue?: (schemaLocation: string, siblingKeywordUri: string) =>
11+
* { keywordLocation: string; keywordValue: unknown } | undefined
12+
* } | undefined} */
13+
if (!resolver?.getSiblingKeywordValue) {
14+
throw new Error("Missing resolver.getSiblingKeywordValue in error handler context");
15+
}
16+
1117
/** @type ErrorObject[] */
1218
const errors = [];
1319

@@ -27,24 +33,16 @@ const containsErrorHandler = async (normalizedErrors, instance, localization) =>
2733

2834
/** @type ContainsRange */
2935
const range = {};
30-
const parentLocation = pointerPop(schemaLocation);
31-
32-
for (const minContainsLocation in normalizedErrors["https://json-schema.org/keyword/minContains"]) {
33-
if (pointerPop(minContainsLocation) === parentLocation) {
34-
const minContainsNode = await getSchema(minContainsLocation);
35-
range.minContains = /** @type number */ (Schema.value(minContainsNode));
36-
schemaLocations.push(minContainsLocation);
37-
break;
38-
}
36+
const minContains = resolver.getSiblingKeywordValue(schemaLocation, "https://json-schema.org/keyword/minContains");
37+
if (minContains) {
38+
range.minContains = /** @type number */ (minContains.keywordValue);
39+
schemaLocations.push(minContains.keywordLocation);
3940
}
4041

41-
for (const maxContainsLocation in normalizedErrors["https://json-schema.org/keyword/maxContains"]) {
42-
if (pointerPop(maxContainsLocation) === parentLocation) {
43-
const maxContainsNode = await getSchema(maxContainsLocation);
44-
range.maxContains = /** @type number */ (Schema.value(maxContainsNode));
45-
schemaLocations.push(maxContainsLocation);
46-
break;
47-
}
42+
const maxContains = resolver.getSiblingKeywordValue(schemaLocation, "https://json-schema.org/keyword/maxContains");
43+
if (maxContains) {
44+
range.maxContains = /** @type number */ (maxContains.keywordValue);
45+
schemaLocations.push(maxContains.keywordLocation);
4846
}
4947

5048
errors.push({
@@ -58,7 +56,4 @@ const containsErrorHandler = async (normalizedErrors, instance, localization) =>
5856
return errors;
5957
};
6058

61-
/** @type (pointer: string) => string */
62-
const pointerPop = (pointer) => pointer.replace(/\/[^/]+$/, "");
63-
6459
export default containsErrorHandler;

src/error-handlers/draft-04/dependencies.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { getErrors } from "../../json-schema-errors.js";
55
*/
66

77
/** @type ErrorHandler */
8-
const dependenciesErrorHandler = async (normalizedErrors, instance, localization) => {
8+
const dependenciesErrorHandler = (normalizedErrors, instance, localization, resolver) => {
99
/** @type ErrorObject[] */
1010
const errors = [];
1111

@@ -16,7 +16,7 @@ const dependenciesErrorHandler = async (normalizedErrors, instance, localization
1616

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

src/error-handlers/format.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
import { getSchema } from "@hyperjump/json-schema/experimental";
2-
import * as Schema from "@hyperjump/browser";
31
import * as Instance from "@hyperjump/json-schema/instance/experimental";
42

53
/**
64
* @import { ErrorHandler, ErrorObject } from "../index.d.ts"
75
*/
86

97
/** @type ErrorHandler */
10-
const formatErrorHandler = async (normalizedErrors, instance, localization) => {
8+
const formatErrorHandler = (normalizedErrors, instance, localization, resolver) => {
9+
if (!resolver?.getCompiledKeywordValue) {
10+
throw new Error("Missing resolver.getCompiledKeywordValue in error handler context");
11+
}
12+
1113
/** @type ErrorObject[] */
1214
const errors = [];
1315

@@ -26,8 +28,7 @@ const formatErrorHandler = async (normalizedErrors, instance, localization) => {
2628
continue;
2729
}
2830

29-
const keyword = await getSchema(schemaLocation);
30-
const format = /** @type string */ (Schema.value(keyword));
31+
const format = /** @type string */ (resolver.getCompiledKeywordValue(schemaLocation));
3132

3233
errors.push({
3334
message: localization.getFormatErrorMessage(format),

src/error-handlers/maxItems.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
import { getSchema } from "@hyperjump/json-schema/experimental";
2-
import * as Schema from "@hyperjump/browser";
31
import * as Instance from "@hyperjump/json-schema/instance/experimental";
42

53
/**
64
* @import { ErrorHandler, ErrorObject } from "../index.d.ts"
75
*/
86

97
/** @type ErrorHandler */
10-
const maxItemsErrorHandler = async (normalizedErrors, instance, localization) => {
8+
const maxItemsErrorHandler = (normalizedErrors, instance, localization, resolver) => {
9+
if (!resolver?.getCompiledKeywordValue) {
10+
throw new Error("Missing resolver.getCompiledKeywordValue in error handler context");
11+
}
12+
1113
/** @type ErrorObject[] */
1214
const errors = [];
1315
let lowestMaxItems = Infinity;
@@ -18,8 +20,7 @@ const maxItemsErrorHandler = async (normalizedErrors, instance, localization) =>
1820
continue;
1921
}
2022

21-
const keyword = await getSchema(schemaLocation);
22-
const maxItems = /** @type number */ (Schema.value(keyword));
23+
const maxItems = /** @type number */ (resolver.getCompiledKeywordValue(schemaLocation));
2324

2425
if (maxItems < lowestMaxItems) {
2526
lowestMaxItems = maxItems;

src/error-handlers/maxLength.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
import { getSchema } from "@hyperjump/json-schema/experimental";
2-
import * as Schema from "@hyperjump/browser";
31
import * as Instance from "@hyperjump/json-schema/instance/experimental";
42

53
/**
64
* @import { ErrorHandler, ErrorObject } from "../index.d.ts"
75
*/
86

97
/** @type ErrorHandler */
10-
const maxLengthErrorHandler = async (normalizedErrors, instance, localization) => {
8+
const maxLengthErrorHandler = (normalizedErrors, instance, localization, resolver) => {
9+
if (!resolver?.getCompiledKeywordValue) {
10+
throw new Error("Missing resolver.getCompiledKeywordValue in error handler context");
11+
}
12+
1113
/** @type ErrorObject[] */
1214
const errors = [];
1315
let lowestMaxLength = Infinity;
@@ -18,8 +20,7 @@ const maxLengthErrorHandler = async (normalizedErrors, instance, localization) =
1820
continue;
1921
}
2022

21-
const keyword = await getSchema(schemaLocation);
22-
const maxLength = /** @type number */ (Schema.value(keyword));
23+
const maxLength = /** @type number */ (resolver.getCompiledKeywordValue(schemaLocation));
2324

2425
if (maxLength < lowestMaxLength) {
2526
lowestMaxLength = maxLength;

src/error-handlers/maxProperties.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
import { getSchema } from "@hyperjump/json-schema/experimental";
2-
import * as Schema from "@hyperjump/browser";
31
import * as Instance from "@hyperjump/json-schema/instance/experimental";
42

53
/**
64
* @import { ErrorHandler, ErrorObject } from "../index.d.ts"
75
*/
86

97
/** @type ErrorHandler */
10-
const maxPropertiesErrorHandler = async (normalizedErrors, instance, localization) => {
8+
const maxPropertiesErrorHandler = (normalizedErrors, instance, localization, resolver) => {
9+
if (!resolver?.getCompiledKeywordValue) {
10+
throw new Error("Missing resolver.getCompiledKeywordValue in error handler context");
11+
}
12+
1113
/** @type ErrorObject[] */
1214
const errors = [];
1315
let lowestMaxProperties = Infinity;
@@ -17,8 +19,7 @@ const maxPropertiesErrorHandler = async (normalizedErrors, instance, localizatio
1719
continue;
1820
}
1921

20-
const keyword = await getSchema(schemaLocation);
21-
const maxProperties = /** @type number */ (Schema.value(keyword));
22+
const maxProperties = /** @type number */ (resolver.getCompiledKeywordValue(schemaLocation));
2223

2324
if (maxProperties < lowestMaxProperties) {
2425
lowestMaxProperties = maxProperties;

src/error-handlers/maximum.js

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
1-
import { getSchema } from "@hyperjump/json-schema/experimental";
2-
import * as Schema from "@hyperjump/browser";
31
import * as Instance from "@hyperjump/json-schema/instance/experimental";
42

53
/**
64
* @import { ErrorHandler } from "../index.d.ts"
75
*/
86

97
/** @type ErrorHandler */
10-
const maximumErrorHandler = async (normalizedErrors, instance, localization) => {
8+
const maximumErrorHandler = (normalizedErrors, instance, localization, resolver) => {
9+
/** @type {{
10+
* getCompiledKeywordValue?: (schemaLocation: string) => unknown;
11+
* getSiblingKeywordValue?: (schemaLocation: string, siblingKeywordUri: string) =>
12+
* { keywordLocation: string; keywordValue: unknown } | undefined
13+
* } | undefined} */
14+
if (!resolver?.getCompiledKeywordValue || !resolver.getSiblingKeywordValue) {
15+
throw new Error("Missing resolver functions in error handler context");
16+
}
17+
1118
let lowestMaximum = Infinity;
1219
let isExclusive = false;
1320

@@ -19,8 +26,7 @@ const maximumErrorHandler = async (normalizedErrors, instance, localization) =>
1926
continue;
2027
}
2128

22-
const keyword = await getSchema(schemaLocation);
23-
const maximum = /** @type number */ (Schema.value(keyword));
29+
const maximum = /** @type number */ (resolver.getCompiledKeywordValue(schemaLocation));
2430
if (maximum < lowestMaximum) {
2531
lowestMaximum = maximum;
2632
schemaLocations = [schemaLocation];
@@ -32,8 +38,7 @@ const maximumErrorHandler = async (normalizedErrors, instance, localization) =>
3238
continue;
3339
}
3440

35-
const keyword = await getSchema(schemaLocation);
36-
const exclusiveMaximum = /** @type number */ (Schema.value(keyword));
41+
const exclusiveMaximum = /** @type number */ (resolver.getCompiledKeywordValue(schemaLocation));
3742
if (exclusiveMaximum < lowestMaximum) {
3843
lowestMaximum = exclusiveMaximum;
3944
isExclusive = true;
@@ -46,26 +51,15 @@ const maximumErrorHandler = async (normalizedErrors, instance, localization) =>
4651
continue;
4752
}
4853

49-
const parentLocation = pointerPop(schemaLocation);
50-
/** @type string */
51-
let exclusiveLocation = "";
52-
for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/draft-04/exclusiveMaximum"]) {
53-
const exclusiveParentLocation = pointerPop(schemaLocation);
54-
if (exclusiveParentLocation === parentLocation) {
55-
const exclusiveNode = await getSchema(schemaLocation);
56-
if (Schema.value(exclusiveNode)) {
57-
exclusiveLocation = schemaLocation;
58-
}
59-
break;
60-
}
61-
}
62-
63-
const keywordNode = await getSchema(schemaLocation);
64-
const maximum = /** @type number */ (Schema.value(keywordNode));
54+
const draft04Maximum = /** @type [number, boolean] */ (resolver.getCompiledKeywordValue(schemaLocation));
55+
const maximum = draft04Maximum[0];
56+
const exclusive = draft04Maximum[1];
57+
const exclusiveKeyword = resolver.getSiblingKeywordValue(schemaLocation, "https://json-schema.org/keyword/draft-04/exclusiveMaximum");
58+
const exclusiveLocation = exclusive && exclusiveKeyword ? exclusiveKeyword.keywordLocation : "";
6559

6660
if (maximum < lowestMaximum) {
6761
lowestMaximum = maximum;
68-
isExclusive = !!exclusiveLocation;
62+
isExclusive = exclusive;
6963
schemaLocations = exclusiveLocation ? [schemaLocation, exclusiveLocation] : [schemaLocation];
7064
}
7165
}
@@ -87,7 +81,4 @@ const maximumErrorHandler = async (normalizedErrors, instance, localization) =>
8781
}
8882
};
8983

90-
/** @type (pointer: string) => string */
91-
const pointerPop = (pointer) => pointer.replace(/\/[^/]+$/, "");
92-
9384
export default maximumErrorHandler;

src/error-handlers/minItems.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
import { getSchema } from "@hyperjump/json-schema/experimental";
2-
import * as Schema from "@hyperjump/browser";
31
import * as Instance from "@hyperjump/json-schema/instance/experimental";
42

53
/**
64
* @import { ErrorHandler, ErrorObject } from "../index.d.ts"
75
*/
86

97
/** @type ErrorHandler */
10-
const minItemsErrorHandler = async (normalizedErrors, instance, localization) => {
8+
const minItemsErrorHandler = (normalizedErrors, instance, localization, resolver) => {
9+
if (!resolver?.getCompiledKeywordValue) {
10+
throw new Error("Missing resolver.getCompiledKeywordValue in error handler context");
11+
}
12+
1113
/** @type ErrorObject[] */
1214
const errors = [];
1315
let highestMinItem = 0;
@@ -18,8 +20,7 @@ const minItemsErrorHandler = async (normalizedErrors, instance, localization) =>
1820
continue;
1921
}
2022

21-
const keyword = await getSchema(schemaLocation);
22-
const minItems = /** @type number */ (Schema.value(keyword));
23+
const minItems = /** @type number */ (resolver.getCompiledKeywordValue(schemaLocation));
2324

2425
if (minItems > highestMinItem) {
2526
highestMinItem = minItems;

0 commit comments

Comments
 (0)