Skip to content

Commit 9380015

Browse files
Fix: Add support for format keyword across all JSON Schema dialects (#95)
* fixed:format test failure Signed-off-by: Diya <[email protected]> * fix lint error * removed repition in format test * fixed repetition and lint errors --------- Signed-off-by: Diya <[email protected]>
1 parent 1df7e01 commit 9380015

File tree

4 files changed

+81
-33
lines changed

4 files changed

+81
-33
lines changed

src/error-handlers/format.js

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,32 @@ const format = async (normalizedErrors, instance, localization) => {
1111
/** @type ErrorObject[] */
1212
const errors = [];
1313

14-
if (normalizedErrors["https://json-schema.org/keyword/format"]) {
15-
for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/format"]) {
16-
if (!normalizedErrors["https://json-schema.org/keyword/format"][schemaLocation]) {
17-
const keyword = await getSchema(schemaLocation);
18-
errors.push({
19-
message: localization.getFormatErrorMessage(Schema.value(keyword)),
20-
instanceLocation: Instance.uri(instance),
21-
schemaLocation: schemaLocation
22-
});
14+
const formats = [
15+
"https://json-schema.org/keyword/draft-2020-12/format",
16+
"https://json-schema.org/keyword/draft-2019-09/format",
17+
"https://json-schema.org/keyword/draft-07/format",
18+
"https://json-schema.org/keyword/draft-06/format",
19+
"https://json-schema.org/keyword/draft-04/format"
20+
];
21+
22+
for (const formatKeyword of formats) {
23+
if (!normalizedErrors[formatKeyword]) {
24+
continue;
25+
}
26+
27+
for (const schemaLocation in normalizedErrors[formatKeyword]) {
28+
const valid = normalizedErrors[formatKeyword][schemaLocation];
29+
if (valid) {
30+
continue;
2331
}
32+
33+
const keyword = await getSchema(schemaLocation);
34+
35+
errors.push({
36+
message: localization.getFormatErrorMessage(Schema.value(keyword)),
37+
instanceLocation: Instance.uri(instance),
38+
schemaLocation
39+
});
2440
}
2541
}
2642

src/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import arrayRangeErrorHandler from "./error-handlers/array-range-handler.js";
5050
import constErrorHandler from "./error-handlers/const.js";
5151
import containsErrorHandler from "./error-handlers/contains.js";
5252
import enumErrorHandler from "./error-handlers/enum.js";
53+
import format from "./normalization-handlers/format.js";
5354
import formatErrorHandler from "./error-handlers/format.js";
5455
import multipleOfErrorHandler from "./error-handlers/multipleOf.js";
5556
import notErrorHandler from "./error-handlers/not.js";
@@ -83,6 +84,11 @@ setNormalizationHandler("https://json-schema.org/keyword/dependentSchema", depen
8384
setNormalizationHandler("https://json-schema.org/keyword/definitions", definitions);
8485
setNormalizationHandler("https://json-schema.org/keyword/else", elseKeyword);
8586
setNormalizationHandler("https://json-schema.org/keyword/enum", enumKeyword);
87+
setNormalizationHandler("https://json-schema.org/keyword/draft-2020-12/format", format);
88+
setNormalizationHandler("https://json-schema.org/keyword/draft-2019-09/format", format);
89+
setNormalizationHandler("https://json-schema.org/keyword/draft-07/format", format);
90+
setNormalizationHandler("https://json-schema.org/keyword/draft-06/format", format);
91+
setNormalizationHandler("https://json-schema.org/keyword/draft-04/format", format);
8692
setNormalizationHandler("https://json-schema/keyword/exclusiveMaximum", exclusiveMaximum);
8793
setNormalizationHandler("https://json-schema/keyword/exclusiveMinimum", exclusiveMinimum);
8894
setNormalizationHandler("https://json-schema.org/keyword/items", items);

src/keyword-error-message.test.js

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ import { registerSchema } from "@hyperjump/json-schema/draft-2020-12";
44
import { unregisterSchema } from "@hyperjump/json-schema";
55
import { getSchemaDescription } from "./schema-descriptions.js";
66
import { Localization } from "./localization.js";
7+
import "@hyperjump/json-schema/draft-04";
8+
import "@hyperjump/json-schema/draft-06";
9+
import "@hyperjump/json-schema/draft-2019-09";
10+
import "@hyperjump/json-schema/draft-07";
711

812
/**
913
* @import { OutputFormat} from "./index.d.ts"
@@ -639,33 +643,43 @@ describe("Error messages", async () => {
639643
}]);
640644
});
641645

642-
test("format: email", async () => {
643-
registerSchema({
644-
$schema: "https://json-schema.org/draft/2020-12/schema",
645-
format: "email"
646-
}, schemaUri);
646+
const dialects = [
647+
{ name: "draft-2020-12", schema: "https://json-schema.org/draft/2020-12/schema" },
648+
{ name: "draft-2019-09", schema: "https://json-schema.org/draft/2019-09/schema" },
649+
{ name: "draft-07", schema: "http://json-schema.org/draft-07/schema" },
650+
{ name: "draft-06", schema: "http://json-schema.org/draft-06/schema" },
651+
{ name: "draft-04", schema: "http://json-schema.org/draft-04/schema" }
652+
];
653+
654+
for (const { name, schema } of dialects) {
655+
test(`format: email (${name})`, async () => {
656+
registerSchema({
657+
$schema: schema,
658+
format: "email"
659+
}, schemaUri);
660+
661+
const instance = "not-an-email";
662+
const output = {
663+
valid: false,
664+
errors: [
665+
{
666+
absoluteKeywordLocation: "https://example.com/main#/format",
667+
instanceLocation: "#"
668+
}
669+
]
670+
};
647671

648-
const instance = "not-an-email";
649-
const output = {
650-
valid: false,
651-
errors: [
672+
const result = await betterJsonSchemaErrors(output, schemaUri, instance);
673+
674+
expect(result.errors).to.eql([
652675
{
653-
absoluteKeywordLocation: "https://example.com/main#/format",
654-
instanceLocation: "#"
676+
schemaLocation: "https://example.com/main#/format",
677+
instanceLocation: "#",
678+
message: localization.getFormatErrorMessage("email")
655679
}
656-
]
657-
};
658-
659-
const result = await betterJsonSchemaErrors(output, schemaUri, instance);
660-
expect(result.errors).to.eql([
661-
{
662-
schemaLocation: "https://example.com/main#/format",
663-
instanceLocation: "#",
664-
message: localization.getFormatErrorMessage("email")
665-
}
666-
]);
667-
});
668-
680+
]);
681+
});
682+
}
669683
test("pattern", async () => {
670684
registerSchema({
671685
$schema: "https://json-schema.org/draft/2020-12/schema",
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* @import { KeywordHandler } from "../index.d.ts"
3+
*/
4+
5+
/** @type KeywordHandler */
6+
const format = {
7+
appliesTo() {
8+
return true;
9+
}
10+
};
11+
12+
export default format;

0 commit comments

Comments
 (0)