Skip to content

Commit fe1ff62

Browse files
committed
Create an EvaluationPlugin for the normalized format
1 parent c67137e commit fe1ff62

2 files changed

Lines changed: 1599 additions & 0 deletions

File tree

src/output-plugin.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import * as Instance from "@hyperjump/json-schema/instance/experimental";
2+
3+
/**
4+
* @import { EvaluationPlugin, ValidationContext } from "@hyperjump/json-schema/experimental"
5+
* @import { NormalizedOutput } from "./index.js"
6+
*/
7+
8+
/**
9+
* @typedef {ValidationContext & {
10+
* output: NormalizedOutput;
11+
* subSchemaOutput?: NormalizedOutput[];
12+
* }} ErrorsContext
13+
*/
14+
15+
/** @implements EvaluationPlugin<ErrorsContext> */
16+
export class JsonSchemaErrorsOutputPlugin {
17+
/** @type NonNullable<EvaluationPlugin<ErrorsContext>["beforeSchema"]> */
18+
beforeSchema(_url, _instance, context) {
19+
context.output = {};
20+
}
21+
22+
/** @type NonNullable<EvaluationPlugin<ErrorsContext>["beforeKeyword"]> */
23+
beforeKeyword(_node, _instance, context, schemaContext) {
24+
context.output = schemaContext.output;
25+
}
26+
27+
/** @type NonNullable<EvaluationPlugin<ErrorsContext>["afterKeyword"]> */
28+
afterKeyword(keywordNode, instance, context, valid, schemaContext, keyword) {
29+
const [keywordUri, schemaLocation] = keywordNode;
30+
31+
if (keyword.simpleApplicator) {
32+
for (const subSchemaOutput of context.subSchemaOutput ?? []) {
33+
mergeOutput(schemaContext.output, subSchemaOutput);
34+
}
35+
} else {
36+
schemaContext.output[Instance.uri(instance)] ??= {};
37+
schemaContext.output[Instance.uri(instance)][keywordUri] ??= {};
38+
schemaContext.output[Instance.uri(instance)][keywordUri][schemaLocation] = valid
39+
|| (context.subSchemaOutput ?? valid);
40+
}
41+
}
42+
43+
/** @type NonNullable<EvaluationPlugin<ErrorsContext>["afterSchema"]> */
44+
afterSchema(url, instance, context, valid) {
45+
if (typeof context.ast[url] === "boolean" && !valid) {
46+
context.output[Instance.uri(instance)] ??= {};
47+
context.output[Instance.uri(instance)]["https://json-schema.org/validation"] ??= {};
48+
context.output[Instance.uri(instance)]["https://json-schema.org/validation"][url] = valid;
49+
}
50+
51+
context.subSchemaOutput ??= [];
52+
context.subSchemaOutput.push(context.output);
53+
54+
this.output = context.output;
55+
}
56+
}
57+
58+
/** @type (a: NormalizedOutput, b: NormalizedOutput) => void */
59+
const mergeOutput = (a, b) => {
60+
for (const instanceLocation in b) {
61+
a[instanceLocation] ??= {};
62+
for (const keywordUri in b[instanceLocation]) {
63+
a[instanceLocation][keywordUri] ??= {};
64+
65+
Object.assign(a[instanceLocation][keywordUri], b[instanceLocation][keywordUri]);
66+
}
67+
}
68+
};

0 commit comments

Comments
 (0)