-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathunevaluatedProperties.ts
89 lines (79 loc) · 3.2 KB
/
unevaluatedProperties.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import { isObject } from "../utils/isObject";
import { SchemaNode } from "../types";
import { Keyword, JsonSchemaValidatorParams, ValidationResult } from "../Keyword";
import { validateNode } from "../validateNode";
import { isPropertyEvaluated } from "../isPropertyEvaluated";
export const unevaluatedPropertiesKeyword: Keyword = {
id: "unevaluatedProperties",
keyword: "unevaluatedProperties",
parse: parseUnevaluatedProperties,
addValidate: ({ schema }) => schema.unevaluatedProperties != null,
validate: validateUnevaluatedProperties
};
export function parseUnevaluatedProperties(node: SchemaNode) {
if (!isObject(node.schema.unevaluatedProperties)) {
return;
}
node.unevaluatedProperties = node.compileSchema(
node.schema.unevaluatedProperties,
`${node.evaluationPath}/unevaluatedProperties`,
`${node.schemaLocation}/unevaluatedProperties`
);
}
// @todo we should use collected annotation to evaluated unevaluate properties
function validateUnevaluatedProperties({ node, data, pointer, path }: JsonSchemaValidatorParams) {
if (!isObject(data)) {
return undefined;
}
const unevaluated = Object.keys(data);
if (unevaluated.length === 0) {
return undefined;
}
const errors: ValidationResult[] = [];
for (let i = 0; i < unevaluated.length; i += 1) {
const propertyName = unevaluated[i];
if (isPropertyEvaluated({ node, data, key: propertyName, pointer, path })) {
continue;
}
const { node: child } = node.getNodeChild(propertyName, data, { pointer, path });
if (child === undefined) {
if (node.unevaluatedProperties) {
const validationResult = validateNode(
node.unevaluatedProperties,
data[propertyName],
`${pointer}/${propertyName}`,
path
);
errors.push(...validationResult);
} else if (node.schema.unevaluatedProperties === false) {
errors.push(
node.createError("unevaluated-property-error", {
pointer: `${pointer}/${propertyName}`,
value: JSON.stringify(data[propertyName]),
schema: node.schema
})
);
}
}
if (child && validateNode(child, data[propertyName], `${pointer}/${propertyName}`, path).length > 0) {
if (node.unevaluatedProperties) {
const validationResult = validateNode(
node.unevaluatedProperties,
data[propertyName],
`${pointer}/${propertyName}`,
path
);
errors.push(...validationResult);
} else if (node.schema.unevaluatedProperties === false) {
errors.push(
node.createError("unevaluated-property-error", {
pointer: `${pointer}/${propertyName}`,
value: JSON.stringify(data[propertyName]),
schema: node.schema
})
);
}
}
}
return errors;
}