Skip to content

Commit 6e113c6

Browse files
authored
Merge pull request #51 from arpitkuriyal/combineRequired
combine errorMessage of required and dependentRequired
2 parents 93923de + 3a3be1a commit 6e113c6

File tree

6 files changed

+52
-69
lines changed

6 files changed

+52
-69
lines changed

src/error-handlers/dependentRequired.js

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

src/error-handlers/required.js

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,64 @@ 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 required = async (normalizedErrors, instance, localization) => {
11-
/** @type ErrorObject[] */
12-
const errors = [];
11+
/** @type Set<string> */
12+
const required = new Set();
13+
14+
/** @type string[] */
15+
const failedSchemaLocations = [];
1316

1417
if (normalizedErrors["https://json-schema.org/keyword/required"]) {
1518
for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/required"]) {
1619
if (!normalizedErrors["https://json-schema.org/keyword/required"][schemaLocation]) {
20+
failedSchemaLocations.push(schemaLocation);
1721
const keyword = await getSchema(schemaLocation);
1822
/** @type Set<string> */
19-
const required = new Set(Schema.value(keyword));
23+
for (const propertyName of /** @type string[] */ (Schema.value(keyword))) {
24+
required.add(propertyName);
25+
}
2026
for (const propertyName in Instance.value(instance)) {
2127
required.delete(propertyName);
2228
}
23-
errors.push({
24-
message: localization.getRequiredErrorMessage(Instance.uri(instance), [...required]),
25-
instanceLocation: Instance.uri(instance),
26-
schemaLocation: schemaLocation
27-
});
2829
}
2930
}
3031
}
3132

32-
return errors;
33+
if (normalizedErrors["https://json-schema.org/keyword/dependentRequired"]) {
34+
for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/dependentRequired"]) {
35+
if (!normalizedErrors["https://json-schema.org/keyword/dependentRequired"][schemaLocation]) {
36+
const keyword = await getSchema(schemaLocation);
37+
const dependentRequired = /** @type {Record<string, string[]>} */(Schema.value(keyword));
38+
for (const propertyName in dependentRequired) {
39+
if (Instance.has(propertyName, instance)) {
40+
failedSchemaLocations.push(schemaLocation);
41+
for (const requiredPropertyName of dependentRequired[propertyName]) {
42+
required.add(requiredPropertyName);
43+
}
44+
for (const propertyName in Instance.value(instance)) {
45+
required.delete(propertyName);
46+
}
47+
}
48+
}
49+
}
50+
}
51+
}
52+
53+
if (required.size > 0) {
54+
return [
55+
{
56+
message: localization.getRequiredErrorMessage([...required]),
57+
instanceLocation: Instance.uri(instance),
58+
schemaLocation: failedSchemaLocations
59+
}
60+
];
61+
} else {
62+
return [];
63+
}
3364
};
3465

3566
export default required;

src/index.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ import additionalPropertiesErrorHandler from "./error-handlers/additionalPropert
4949
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";
52-
import dependentRequiredErrorHandler from "./error-handlers/dependentRequired.js";
5352
import enumErrorHandler from "./error-handlers/enum.js";
5453
import formatErrorHandler from "./error-handlers/format.js";
5554
import multipleOfErrorHandler from "./error-handlers/multipleOf.js";
@@ -117,7 +116,6 @@ addErrorHandler(anyOfErrorHandler);
117116
addErrorHandler(additionalPropertiesErrorHandler);
118117
addErrorHandler(constErrorHandler);
119118
addErrorHandler(containsErrorHandler);
120-
addErrorHandler(dependentRequiredErrorHandler);
121119
addErrorHandler(enumErrorHandler);
122120
addErrorHandler(formatErrorHandler);
123121
addErrorHandler(arrayRangeErrorHandler);

src/keyword-error-message.test.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -338,9 +338,11 @@ describe("Error messages", async () => {
338338

339339
const result = await betterJsonSchemaErrors(output, schemaUri, instance);
340340
expect(result.errors).to.eql([{
341-
schemaLocation: "https://example.com/main#/required",
341+
schemaLocation: [
342+
"https://example.com/main#/required"
343+
],
342344
instanceLocation: "#",
343-
message: localization.getRequiredErrorMessage("#", ["baz"])
345+
message: localization.getRequiredErrorMessage(["baz"])
344346
}]);
345347
});
346348

@@ -1563,8 +1565,10 @@ describe("Error messages", async () => {
15631565
expect(result.errors).to.eql([
15641566
{
15651567
instanceLocation: "#",
1566-
message: localization.getDependentRequiredErrorMessage("foo", ["baz"]),
1567-
schemaLocation: "https://example.com/main#/dependentRequired"
1568+
message: localization.getRequiredErrorMessage(["baz"]),
1569+
schemaLocation: [
1570+
"https://example.com/main#/dependentRequired"
1571+
]
15681572
}
15691573
]);
15701574
});

src/localization.js

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,9 @@ export class Localization {
137137
});
138138
}
139139

140-
/** @type (instanceLocation: string, missingProperties: string[]) => string */
141-
getRequiredErrorMessage(instanceLocation, missingProperties) {
140+
/** @type (missingProperties: string[]) => string */
141+
getRequiredErrorMessage(missingProperties) {
142142
return this._formatMessage("required-error", {
143-
instanceLocation,
144143
missingProperties: new Intl.ListFormat(this.locale, { type: "conjunction" }).format(missingProperties)
145144
});
146145
}
@@ -225,14 +224,6 @@ export class Localization {
225224
return this._formatMessage("additional-properties-error", { propertyName });
226225
}
227226

228-
/** @type (property: string, missingDependents: string[]) => string */
229-
getDependentRequiredErrorMessage(property, missingDependents) {
230-
return this._formatMessage("dependent-required-error", {
231-
property,
232-
missingDependents: new Intl.ListFormat(this.locale, { type: "conjunction" }).format(missingDependents)
233-
});
234-
}
235-
236227
/**
237228
* @typedef {Object} EnumSuggestionArgs
238229
* @property {"suggestion"} variant

src/translations/en-US.ftl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ number-error-exclusive-minimum = greater than or equal to {$minimum}
1010
number-error-maximum = less than {$maximum}
1111
number-error-exclusive-maximum = less than or equal to {$maximum}
1212
13-
required-error = "{$instanceLocation}" is missing required property(s): {$missingProperties}.
13+
required-error = This instance is missing required property(s): {$missingProperties}.
1414
multiple-of-error = The instance should be a multiple of {$divisor}.
1515
1616
properties-error = Expected object to have {$constraints}
@@ -38,7 +38,6 @@ contains-error-min-max = The array must contain at least {$minContains} and at m
3838
3939
not-error = The instance is not allowed to be used in this schema.
4040
additional-properties-error = The property "{$propertyName}" is not allowed.
41-
dependent-required-error = Property "{$property}" requires property(s): {$missingDependents}.
4241
enum-error = { $variant ->
4342
[suggestion] Unexpected value {$instanceValue}. Did you mean {$suggestion}?
4443
*[fallback] Unexpected value {$instanceValue}. Expected one of: {$allowedValues}.

0 commit comments

Comments
 (0)