Skip to content

Commit b37548d

Browse files
Unify minimum/maximum error handlers with draft-04 compatibility (#163)
* Add unified handlers for minimum/maximum along with draft04 compatiblity * Remove individual error handlers for max/min and retain individual normalization handlers * Rename combinedMaximum/Minimum to Maximum/Minimum * A little cleanup --------- Co-authored-by: Jason Desrosiers <jdesrosi@gmail.com>
1 parent 2e5511a commit b37548d

9 files changed

Lines changed: 287 additions & 202 deletions

File tree

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

Lines changed: 0 additions & 56 deletions
This file was deleted.

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

Lines changed: 0 additions & 56 deletions
This file was deleted.

src/error-handlers/exclusiveMaximum.js

Lines changed: 0 additions & 32 deletions
This file was deleted.

src/error-handlers/exclusiveMinimum.js

Lines changed: 0 additions & 32 deletions
This file was deleted.

src/error-handlers/maximum.js

Lines changed: 70 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ import * as Schema from "@hyperjump/browser";
33
import * as Instance from "@hyperjump/json-schema/instance/experimental";
44

55
/**
6-
* @import { ErrorHandler, ErrorObject } from "../index.d.ts"
6+
* @import { ErrorHandler } from "../index.d.ts"
77
*/
88

99
/** @type ErrorHandler */
1010
const maximumErrorHandler = async (normalizedErrors, instance, localization) => {
11-
/** @type ErrorObject[] */
12-
const errors = [];
11+
let lowestMaximum = Infinity;
12+
let isExclusive = false;
13+
14+
/** @type string[] */
15+
let schemaLocations = [];
1316

1417
for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/maximum"]) {
1518
if (normalizedErrors["https://json-schema.org/keyword/maximum"][schemaLocation]) {
@@ -18,15 +21,73 @@ const maximumErrorHandler = async (normalizedErrors, instance, localization) =>
1821

1922
const keyword = await getSchema(schemaLocation);
2023
const maximum = /** @type number */ (Schema.value(keyword));
24+
if (maximum < lowestMaximum) {
25+
lowestMaximum = maximum;
26+
schemaLocations = [schemaLocation];
27+
}
28+
}
2129

22-
errors.push({
23-
message: localization.getMaximumErrorMessage(maximum),
24-
instanceLocation: Instance.uri(instance),
25-
schemaLocations: [schemaLocation]
26-
});
30+
for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/exclusiveMaximum"]) {
31+
if (normalizedErrors["https://json-schema.org/keyword/exclusiveMaximum"][schemaLocation]) {
32+
continue;
33+
}
34+
35+
const keyword = await getSchema(schemaLocation);
36+
const exclusiveMaximum = /** @type number */ (Schema.value(keyword));
37+
if (exclusiveMaximum < lowestMaximum) {
38+
lowestMaximum = exclusiveMaximum;
39+
isExclusive = true;
40+
schemaLocations = [schemaLocation];
41+
}
42+
}
43+
44+
for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/draft-04/maximum"]) {
45+
if (normalizedErrors["https://json-schema.org/keyword/draft-04/maximum"][schemaLocation]) {
46+
continue;
47+
}
48+
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));
65+
66+
if (maximum < lowestMaximum) {
67+
lowestMaximum = maximum;
68+
isExclusive = !!exclusiveLocation;
69+
schemaLocations = exclusiveLocation ? [schemaLocation, exclusiveLocation] : [schemaLocation];
70+
}
2771
}
2872

29-
return errors;
73+
if (lowestMaximum === Infinity) {
74+
return [];
75+
} else if (isExclusive) {
76+
return [{
77+
message: localization.getExclusiveMaximumErrorMessage(lowestMaximum),
78+
instanceLocation: Instance.uri(instance),
79+
schemaLocations: schemaLocations
80+
}];
81+
} else {
82+
return [{
83+
message: localization.getMaximumErrorMessage(lowestMaximum),
84+
instanceLocation: Instance.uri(instance),
85+
schemaLocations: schemaLocations
86+
}];
87+
}
3088
};
3189

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

src/error-handlers/minimum.js

Lines changed: 70 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ import * as Schema from "@hyperjump/browser";
33
import * as Instance from "@hyperjump/json-schema/instance/experimental";
44

55
/**
6-
* @import { ErrorHandler, ErrorObject } from "../index.d.ts"
6+
* @import { ErrorHandler } from "../index.d.ts"
77
*/
88

99
/** @type ErrorHandler */
1010
const minimumErrorHandler = async (normalizedErrors, instance, localization) => {
11-
/** @type ErrorObject[] */
12-
const errors = [];
11+
let highestMinimum = -Infinity;
12+
let isExclusive = false;
13+
/** @type string[] */
14+
let schemaLocations = [];
1315

1416
for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/minimum"]) {
1517
if (normalizedErrors["https://json-schema.org/keyword/minimum"][schemaLocation]) {
@@ -19,14 +21,73 @@ const minimumErrorHandler = async (normalizedErrors, instance, localization) =>
1921
const keyword = await getSchema(schemaLocation);
2022
const minimum = /** @type number */ (Schema.value(keyword));
2123

22-
errors.push({
23-
message: localization.getMinimumErrorMessage(minimum),
24-
instanceLocation: Instance.uri(instance),
25-
schemaLocations: [schemaLocation]
26-
});
24+
if (minimum > highestMinimum) {
25+
highestMinimum = minimum;
26+
schemaLocations = [schemaLocation];
27+
}
28+
}
29+
30+
for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/exclusiveMinimum"]) {
31+
if (
32+
normalizedErrors["https://json-schema.org/keyword/exclusiveMinimum"][schemaLocation]) {
33+
continue;
34+
}
35+
36+
const keyword = await getSchema(schemaLocation);
37+
const exclusiveMinimum = /** @type number */ (Schema.value(keyword));
38+
39+
if (exclusiveMinimum > highestMinimum) {
40+
highestMinimum = exclusiveMinimum;
41+
isExclusive = true;
42+
schemaLocations = [schemaLocation];
43+
}
44+
}
45+
for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/draft-04/minimum"]) {
46+
if (normalizedErrors["https://json-schema.org/keyword/draft-04/minimum"][schemaLocation]) {
47+
continue;
48+
}
49+
50+
const parentLocation = pointerPop(schemaLocation);
51+
52+
let exclusiveLocation = "";
53+
for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/draft-04/exclusiveMinimum"]) {
54+
const exclusiveParentLocation = pointerPop(schemaLocation);
55+
if (exclusiveParentLocation === parentLocation) {
56+
const exclusiveNode = await getSchema(schemaLocation);
57+
if (Schema.value(exclusiveNode)) {
58+
exclusiveLocation = schemaLocation;
59+
}
60+
break;
61+
}
62+
}
63+
64+
const keywordNode = await getSchema(schemaLocation);
65+
const minimum = /** @type number */ (Schema.value(keywordNode));
66+
if (minimum > highestMinimum) {
67+
highestMinimum = minimum;
68+
isExclusive = !!exclusiveLocation;
69+
schemaLocations = exclusiveLocation ? [schemaLocation, exclusiveLocation] : [schemaLocation];
70+
}
2771
}
2872

29-
return errors;
73+
if (highestMinimum === -Infinity) {
74+
return [];
75+
} else if (isExclusive) {
76+
return [{
77+
message: localization.getExclusiveMinimumErrorMessage(highestMinimum),
78+
instanceLocation: Instance.uri(instance),
79+
schemaLocations: schemaLocations
80+
}];
81+
} else {
82+
return [{
83+
message: localization.getMinimumErrorMessage(highestMinimum),
84+
instanceLocation: Instance.uri(instance),
85+
schemaLocations: schemaLocations
86+
}];
87+
}
3088
};
3189

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

0 commit comments

Comments
 (0)