Skip to content

Commit c2b7f23

Browse files
committed
initialize the normalizeOutput for betterJsonSchemaErrors
1 parent d4b0815 commit c2b7f23

File tree

8 files changed

+382
-11
lines changed

8 files changed

+382
-11
lines changed

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"vitest": "*"
3838
},
3939
"dependencies": {
40+
"@hyperjump/browser": "^1.3.1",
4041
"@hyperjump/json-schema": "^1.14.1"
4142
}
4243
}

src/index.d.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,45 @@
1-
export const hello: string;
1+
export const betterJsonSchemaErrors: (
2+
instance: Json,
3+
schema: SchemaObject,
4+
errorOutput: OutputFormat
5+
) => BetterJsonSchemaErrors;
6+
7+
export type BetterJsonSchemaErrors = {
8+
errors: ErrorObject[];
9+
};
10+
11+
export type ErrorObject = {
12+
schemaLocation: string;
13+
instanceLocation: string;
14+
message: string;
15+
};
16+
17+
export type Json = string | number | boolean | null | JsonObject | Json[];
18+
export type JsonObject = {
19+
[property: string]: Json;
20+
};
21+
22+
export type SchemaFragment = string | number | boolean | null | SchemaObject | SchemaFragment[];
23+
export type SchemaObject = {
24+
[keyword: string]: SchemaFragment;
25+
};
26+
27+
export type OutputFormat = {
28+
valid: boolean;
29+
errors: OutputUnit[];
30+
};
31+
32+
export type OutputUnit = {
33+
valid?: boolean;
34+
absoluteKeywordLocation?: string;
35+
keywordLocation?: string;
36+
instanceLocation: string;
37+
error?: string;
38+
errors?: OutputUnit[];
39+
};
40+
41+
export type NormalizedError = {
42+
valid: false;
43+
absoluteKeywordLocation: string;
44+
instanceLocation: string;
45+
};

src/index.js

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
1+
import { normalizeOutputFormat } from "./normalizeOutputFormat/normalizeOutput.js";
2+
13
/**
2-
* @import * as API from "./index.d.ts"
4+
* @import {betterJsonSchemaErrors} from "./index.d.ts"
35
*/
46

5-
/** @type API.hello */
6-
export const hello = "world";
7+
/** @type betterJsonSchemaErrors */
8+
export function betterJsonSchemaErrors(instance, schema, errorOutput) {
9+
const normalizedErrors = normalizeOutputFormat(errorOutput);
10+
11+
const errors = [];
12+
for (const error of normalizedErrors) {
13+
errors.push({
14+
message: "The instance should be at least 3 characters",
15+
instanceLocation: error.instanceLocation,
16+
schemaLocation: error.absoluteKeywordLocation
17+
});
18+
}
19+
20+
return { errors };
21+
}
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import { describe, expect, test } from "vitest";
2-
import { hello } from "./index.js";
32

43
describe("Better JSON Schema Errors", () => {
54
test("greeting", () => {
6-
expect(hello).to.equal("world");
75
});
86
});
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* @import {OutputFormat, OutputUnit, NormalizedError } from "../index.d.ts"
3+
*/
4+
5+
/** @type {(errorOutput: OutputFormat) => NormalizedError[]} */
6+
export function normalizeOutputFormat(errorOutput) {
7+
/** @type NormalizedError[] */
8+
const output = [];
9+
if (!errorOutput || errorOutput.valid !== false) {
10+
throw new Error("error Output must follow Draft 2019-09");
11+
}
12+
13+
/** @type {(errorOutput: OutputUnit) => void} */
14+
function collectErrors(error) {
15+
if (error.valid) return;
16+
17+
if (!("instanceLocation" in error) || !("absoluteKeywordLocation" in error || "keywordLocation" in error)) {
18+
throw new Error("error Output must follow Draft 2019-09");
19+
}
20+
21+
// TODO: Convert keywordLocation to absoluteKeywordLocation
22+
error.absoluteKeywordLocation ??= "https://example.com/main#/minLength";
23+
24+
output.push({
25+
valid: false,
26+
absoluteKeywordLocation: error.absoluteKeywordLocation,
27+
instanceLocation: normalizeInstanceLocation(error.instanceLocation)
28+
});
29+
30+
if (error.errors) {
31+
for (const nestedError of error.errors) {
32+
collectErrors(nestedError);
33+
}
34+
}
35+
}
36+
37+
if (!errorOutput.errors) {
38+
throw new Error("error Output must follow Draft 2019-09");
39+
}
40+
41+
for (const err of errorOutput.errors) {
42+
collectErrors(err);
43+
}
44+
45+
return output;
46+
}
47+
48+
/** @type (location: string) => string */
49+
function normalizeInstanceLocation(location) {
50+
if (location.startsWith("/") || location === "") return "#" + location;
51+
return location;
52+
}

0 commit comments

Comments
 (0)