Skip to content

Commit ba77800

Browse files
committed
used hyperjump pact for better performance
1 parent 8487e28 commit ba77800

2 files changed

Lines changed: 84 additions & 92 deletions

File tree

src/error-handlers/anyOf.js

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,69 @@
11
import * as Instance from "@hyperjump/json-schema/instance/experimental";
2+
import * as JsonPointer from "@hyperjump/json-pointer";
3+
import * as Pact from "@hyperjump/pact";
24
import { getErrors } from "../json-schema-errors.js";
35

46
/**
57
* @import { ErrorHandler, ErrorObject, NormalizedOutput } from "../index.d.ts"
68
*/
79

8-
/** @type (alternative: NormalizedOutput, propLocation: string) => boolean */
9-
const propertyPasses = (alternative, propLocation) => {
10-
const propOutput = alternative[propLocation];
11-
if (!propOutput || Object.keys(propOutput).length === 0) return false;
12-
return Object.values(propOutput).every((keywordResults) =>
13-
Object.values(keywordResults).every((v) => v === true)
14-
);
15-
};
16-
1710
/** @type ErrorHandler */
1811
const anyOfErrorHandler = async (normalizedErrors, instance, localization) => {
1912
/** @type ErrorObject[] */
2013
const errors = [];
2114

22-
for (const schemaLocation in normalizedErrors[
23-
"https://json-schema.org/keyword/anyOf"
24-
]) {
25-
const anyOf
26-
= normalizedErrors["https://json-schema.org/keyword/anyOf"][schemaLocation];
15+
for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/anyOf"]) {
16+
const anyOf = normalizedErrors["https://json-schema.org/keyword/anyOf"][schemaLocation];
2717
if (typeof anyOf === "boolean") {
2818
continue;
2919
}
3020
const instanceLocation = Instance.uri(instance);
3121
let filtered = anyOf;
3222

3323
if (Instance.typeOf(instance) === "object") {
34-
const instanceProps = new Set(
35-
[...Instance.keys(instance)].map(
36-
(keyNode) => /** @type {string} */ (Instance.value(keyNode))
24+
const instanceProps = Pact.collectSet(
25+
Pact.map(
26+
(keyNode) => /** @type {string} */ (Instance.value(keyNode)),
27+
Instance.keys(instance)
3728
)
3829
);
3930
const prefix = `${instanceLocation}/`;
4031

41-
filtered = filtered.filter((alternative) => {
32+
filtered = [];
33+
for (const alternative of anyOf) {
34+
const typeResults = alternative[instanceLocation]["https://json-schema.org/keyword/type"];
35+
if (typeResults && !Object.values(typeResults).every((isValid) => isValid)) {
36+
continue;
37+
}
38+
4239
const declaredProps = Object.keys(alternative)
4340
.filter((loc) => loc.startsWith(prefix))
44-
.map((loc) => loc.slice(prefix.length));
41+
.map((loc) => /** @type {string} */ (Pact.head(JsonPointer.pointerSegments(loc.slice(prefix.length - 1)))));
4542

46-
if (declaredProps.length === 0) return true;
47-
return declaredProps.some((prop) => instanceProps.has(prop));
48-
});
43+
if (declaredProps.length > 0 && !declaredProps.some((prop) => instanceProps.has(prop))) {
44+
continue;
45+
}
4946

50-
filtered = filtered.filter((alternative) =>
51-
[...instanceProps].some((prop) =>
52-
propertyPasses(alternative, `${instanceLocation}/${prop}`)
53-
)
54-
);
47+
if (!Pact.some((prop) => propertyPasses(alternative[JsonPointer.append(prop, instanceLocation)]), instanceProps)) {
48+
continue;
49+
}
5550

56-
if (filtered.length === 0) {
57-
filtered = anyOf;
51+
filtered.push(alternative);
5852
}
5953
} else {
60-
filtered = filtered.filter((alternative) => {
61-
const typeResults
62-
= alternative[instanceLocation]?.[
63-
"https://json-schema.org/keyword/type"
64-
];
65-
return (
66-
!typeResults || Object.values(typeResults).every((isValid) => isValid)
67-
);
68-
});
69-
70-
if (filtered.length === 0) {
71-
filtered = anyOf;
54+
filtered = [];
55+
for (const alternative of anyOf) {
56+
const typeResults = alternative[instanceLocation]["https://json-schema.org/keyword/type"];
57+
if (!typeResults || Object.values(typeResults).every((isValid) => isValid)) {
58+
filtered.push(alternative);
59+
}
7260
}
7361
}
7462

63+
if (filtered.length === 0) {
64+
filtered = anyOf;
65+
}
66+
7567
const alternatives = [];
7668
for (const alternative of filtered) {
7769
alternatives.push(await getErrors(alternative, instance, localization));
@@ -92,4 +84,12 @@ const anyOfErrorHandler = async (normalizedErrors, instance, localization) => {
9284
return errors;
9385
};
9486

87+
/** @type (propOutput: NormalizedOutput[string] | undefined) => boolean */
88+
const propertyPasses = (propOutput) => {
89+
if (!propOutput || Object.keys(propOutput).length === 0) return false;
90+
return Object.values(propOutput).every((keywordResults) =>
91+
Object.values(keywordResults).every((v) => v === true)
92+
);
93+
};
94+
9595
export default anyOfErrorHandler;

src/error-handlers/oneOf.js

Lines changed: 43 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,19 @@
11
import * as Instance from "@hyperjump/json-schema/instance/experimental";
2+
import * as JsonPointer from "@hyperjump/json-pointer";
3+
import * as Pact from "@hyperjump/pact";
24
import { getErrors } from "../json-schema-errors.js";
35

46
/**
57
* @import { ErrorHandler, ErrorObject, NormalizedOutput } from "../index.d.ts"
68
*/
79

8-
/** @type (alternative: NormalizedOutput, propLocation: string) => boolean */
9-
const propertyPasses = (alternative, propLocation) => {
10-
const propOutput = alternative[propLocation];
11-
if (!propOutput || Object.keys(propOutput).length === 0) return false;
12-
return Object.values(propOutput).every((keywordResults) =>
13-
Object.values(keywordResults).every((v) => v === true)
14-
);
15-
};
16-
1710
/** @type ErrorHandler */
1811
const oneOfErrorHandler = async (normalizedErrors, instance, localization) => {
1912
/** @type ErrorObject[] */
2013
const errors = [];
2114

22-
for (const schemaLocation in normalizedErrors[
23-
"https://json-schema.org/keyword/oneOf"
24-
]) {
25-
const oneOf
26-
= normalizedErrors["https://json-schema.org/keyword/oneOf"][schemaLocation];
15+
for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/oneOf"]) {
16+
const oneOf = normalizedErrors["https://json-schema.org/keyword/oneOf"][schemaLocation];
2717
if (typeof oneOf === "boolean") {
2818
continue;
2919
}
@@ -35,11 +25,7 @@ const oneOfErrorHandler = async (normalizedErrors, instance, localization) => {
3525
const failingAlternatives = [];
3626

3727
for (const alternative of oneOf) {
38-
const alternativeErrors = await getErrors(
39-
alternative,
40-
instance,
41-
localization
42-
);
28+
const alternativeErrors = await getErrors(alternative, instance, localization);
4329
if (alternativeErrors.length) {
4430
failingAlternatives.push(alternativeErrors);
4531
} else {
@@ -64,54 +50,52 @@ const oneOfErrorHandler = async (normalizedErrors, instance, localization) => {
6450
let filtered = oneOf;
6551

6652
if (Instance.typeOf(instance) === "object") {
67-
const instanceProps = new Set(
68-
[...Instance.keys(instance)].map(
69-
(keyNode) => /** @type {string} */ (Instance.value(keyNode))
53+
const instanceProps = Pact.collectSet(
54+
Pact.map(
55+
(keyNode) => /** @type {string} */ (Instance.value(keyNode)),
56+
Instance.keys(instance)
7057
)
7158
);
7259
const prefix = `${instanceLocation}/`;
7360

74-
filtered = filtered.filter((alternative) => {
61+
filtered = [];
62+
for (const alternative of oneOf) {
63+
const typeResults = alternative[instanceLocation]["https://json-schema.org/keyword/type"];
64+
if (typeResults && !Object.values(typeResults).every((isValid) => isValid)) {
65+
continue;
66+
}
67+
7568
const declaredProps = Object.keys(alternative)
7669
.filter((loc) => loc.startsWith(prefix))
77-
.map((loc) => loc.slice(prefix.length));
70+
.map((loc) => /** @type {string} */ (Pact.head(JsonPointer.pointerSegments(loc.slice(prefix.length - 1)))));
7871

79-
if (declaredProps.length === 0) return true;
80-
return declaredProps.some((prop) => instanceProps.has(prop));
81-
});
72+
if (declaredProps.length > 0 && !declaredProps.some((prop) => instanceProps.has(prop))) {
73+
continue;
74+
}
8275

83-
filtered = filtered.filter((alternative) =>
84-
[...instanceProps].some((prop) =>
85-
propertyPasses(alternative, `${instanceLocation}/${prop}`)
86-
)
87-
);
76+
if (!Pact.some((prop) => propertyPasses(alternative[JsonPointer.append(prop, instanceLocation)]), instanceProps)) {
77+
continue;
78+
}
8879

89-
if (filtered.length === 0) {
90-
filtered = oneOf;
80+
filtered.push(alternative);
9181
}
9282
} else {
93-
filtered = filtered.filter((alternative) => {
94-
const typeResults
95-
= alternative[instanceLocation]?.[
96-
"https://json-schema.org/keyword/type"
97-
];
98-
return (
99-
!typeResults || Object.values(typeResults).every((isValid) => isValid)
100-
);
101-
});
102-
103-
if (filtered.length === 0) {
104-
filtered = oneOf;
83+
filtered = [];
84+
for (const alternative of oneOf) {
85+
const typeResults = alternative[instanceLocation]["https://json-schema.org/keyword/type"];
86+
if (!typeResults || Object.values(typeResults).every((isValid) => isValid)) {
87+
filtered.push(alternative);
88+
}
10589
}
10690
}
10791

92+
if (filtered.length === 0) {
93+
filtered = oneOf;
94+
}
95+
10896
const alternatives = [];
10997
for (const alternative of filtered) {
110-
const alternativeErrors = await getErrors(
111-
alternative,
112-
instance,
113-
localization
114-
);
98+
const alternativeErrors = await getErrors(alternative, instance, localization);
11599
if (alternativeErrors.length) {
116100
alternatives.push(alternativeErrors);
117101
}
@@ -136,4 +120,12 @@ const oneOfErrorHandler = async (normalizedErrors, instance, localization) => {
136120
return errors;
137121
};
138122

123+
/** @type (propOutput: NormalizedOutput[string] | undefined) => boolean */
124+
const propertyPasses = (propOutput) => {
125+
if (!propOutput || Object.keys(propOutput).length === 0) return false;
126+
return Object.values(propOutput).every((keywordResults) =>
127+
Object.values(keywordResults).every((v) => v === true)
128+
);
129+
};
130+
139131
export default oneOfErrorHandler;

0 commit comments

Comments
 (0)