@hyperjump/json-schema 1.7.3 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -56
- package/annotations/annotated-instance.d.ts +4 -82
- package/annotations/annotated-instance.js +31 -33
- package/annotations/index.d.ts +7 -3
- package/annotations/index.js +8 -108
- package/draft-04/additionalItems.js +1 -1
- package/draft-04/items.js +1 -1
- package/lib/core.js +8 -50
- package/lib/experimental.d.ts +6 -7
- package/lib/experimental.js +6 -2
- package/lib/index.d.ts +5 -2
- package/lib/instance.d.ts +24 -23
- package/lib/instance.js +133 -38
- package/lib/keywords/additionalProperties.js +12 -7
- package/lib/keywords/allOf.js +7 -1
- package/lib/keywords/comment.js +4 -3
- package/lib/keywords/const.js +1 -1
- package/lib/keywords/contentEncoding.js +12 -2
- package/lib/keywords/contentMediaType.js +12 -2
- package/lib/keywords/contentSchema.js +8 -3
- package/lib/keywords/default.js +12 -2
- package/lib/keywords/dependentRequired.js +12 -3
- package/lib/keywords/dependentSchemas.js +12 -3
- package/lib/keywords/deprecated.js +12 -2
- package/lib/keywords/description.js +12 -2
- package/lib/keywords/enum.js +5 -2
- package/lib/keywords/examples.js +12 -2
- package/lib/keywords/format.js +12 -2
- package/lib/keywords/items.js +9 -6
- package/lib/keywords/maxContains.js +6 -2
- package/lib/keywords/maxItems.js +3 -1
- package/lib/keywords/maxLength.js +3 -1
- package/lib/keywords/minContains.js +6 -2
- package/lib/keywords/minItems.js +3 -1
- package/lib/keywords/minLength.js +3 -1
- package/lib/keywords/oneOf.js +0 -4
- package/lib/keywords/pattern.js +3 -1
- package/lib/keywords/patternProperties.js +18 -9
- package/lib/keywords/prefixItems.js +21 -6
- package/lib/keywords/properties.js +16 -7
- package/lib/keywords/propertyDependencies.js +18 -6
- package/lib/keywords/propertyNames.js +13 -5
- package/lib/keywords/readOnly.js +12 -2
- package/lib/keywords/title.js +12 -2
- package/lib/keywords/unevaluatedItems.js +14 -7
- package/lib/keywords/unevaluatedProperties.js +15 -8
- package/lib/keywords/uniqueItems.js +1 -1
- package/lib/keywords/unknown.js +12 -2
- package/lib/keywords/validation.js +24 -27
- package/lib/keywords/writeOnly.js +12 -2
- package/lib/keywords.js +5 -0
- package/lib/output.js +43 -0
- package/lib/schema.js +4 -2
- package/openapi-3-0/discriminator.js +12 -2
- package/openapi-3-0/example.js +12 -2
- package/openapi-3-0/externalDocs.js +12 -2
- package/openapi-3-0/index.js +2 -2
- package/openapi-3-0/nullable.js +8 -2
- package/openapi-3-0/xml.js +12 -2
- package/openapi-3-1/index.js +2 -2
- package/package.json +3 -3
- package/bundle/README.md +0 -134
- package/lib/keywords/meta-data.js +0 -7
package/lib/keywords/enum.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import jsonStringify from "
|
|
1
|
+
import jsonStringify from "json-stringify-deterministic";
|
|
2
2
|
import { pipe, asyncMap, asyncCollectArray } from "@hyperjump/pact";
|
|
3
3
|
import * as Browser from "@hyperjump/browser";
|
|
4
4
|
import * as Instance from "../instance.js";
|
|
@@ -13,6 +13,9 @@ const compile = (schema) => pipe(
|
|
|
13
13
|
asyncCollectArray
|
|
14
14
|
);
|
|
15
15
|
|
|
16
|
-
const interpret = (enum_, instance) =>
|
|
16
|
+
const interpret = (enum_, instance) => {
|
|
17
|
+
const instanceValue = jsonStringify(Instance.value(instance));
|
|
18
|
+
return enum_.some((enumValue) => instanceValue === enumValue);
|
|
19
|
+
};
|
|
17
20
|
|
|
18
21
|
export default { id, compile, interpret };
|
package/lib/keywords/examples.js
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Browser from "@hyperjump/browser";
|
|
2
|
+
import * as Instance from "../../annotations/annotated-instance.js";
|
|
2
3
|
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
const id = "https://json-schema.org/keyword/examples";
|
|
6
|
+
|
|
7
|
+
const compile = (schema) => Browser.value(schema);
|
|
8
|
+
|
|
9
|
+
const interpret = (examples, instance, _ast, _dynamicAnchors, _quiet, schemaLocation) => {
|
|
10
|
+
Instance.setAnnotation(instance, id, schemaLocation, examples);
|
|
11
|
+
return true;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default { id, compile, interpret };
|
package/lib/keywords/format.js
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Browser from "@hyperjump/browser";
|
|
2
|
+
import * as Instance from "../../annotations/annotated-instance.js";
|
|
2
3
|
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
const id = "https://json-schema.org/keyword/format";
|
|
6
|
+
|
|
7
|
+
const compile = (schema) => Browser.value(schema);
|
|
8
|
+
|
|
9
|
+
const interpret = (format, instance, _ast, _dynamicAnchors, _quiet, schemaLocation) => {
|
|
10
|
+
Instance.setAnnotation(instance, id, schemaLocation, format);
|
|
11
|
+
return true;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default { id, compile, interpret };
|
package/lib/keywords/items.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { drop } from "@hyperjump/pact";
|
|
2
2
|
import * as Browser from "@hyperjump/browser";
|
|
3
3
|
import * as Instance from "../instance.js";
|
|
4
4
|
import { getKeywordName, Validation } from "../experimental.js";
|
|
@@ -19,11 +19,14 @@ const interpret = ([numberOfPrefixItems, items], instance, ast, dynamicAnchors,
|
|
|
19
19
|
return true;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
let isValid = true;
|
|
23
|
+
for (const item of drop(numberOfPrefixItems, Instance.iter(instance))) {
|
|
24
|
+
if (!Validation.interpret(items, item, ast, dynamicAnchors, quiet)) {
|
|
25
|
+
isValid = false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return isValid;
|
|
27
30
|
};
|
|
28
31
|
|
|
29
32
|
const collectEvaluatedItems = (keywordValue, instance, ast, dynamicAnchors) => {
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Browser from "@hyperjump/browser";
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
const id = "https://json-schema.org/keyword/maxContains";
|
|
5
|
+
const compile = (schema) => Browser.value(schema);
|
|
6
|
+
const interpret = () => true;
|
|
7
|
+
|
|
8
|
+
export default { id, compile, interpret };
|
package/lib/keywords/maxItems.js
CHANGED
|
@@ -5,6 +5,8 @@ import * as Instance from "../instance.js";
|
|
|
5
5
|
const id = "https://json-schema.org/keyword/maxItems";
|
|
6
6
|
|
|
7
7
|
const compile = (schema) => Browser.value(schema);
|
|
8
|
-
const interpret = (maxItems, instance) =>
|
|
8
|
+
const interpret = (maxItems, instance) => {
|
|
9
|
+
return Instance.typeOf(instance) !== "array" || Instance.length(instance) <= maxItems;
|
|
10
|
+
};
|
|
9
11
|
|
|
10
12
|
export default { id, compile, interpret };
|
|
@@ -5,6 +5,8 @@ import * as Instance from "../instance.js";
|
|
|
5
5
|
const id = "https://json-schema.org/keyword/maxLength";
|
|
6
6
|
|
|
7
7
|
const compile = (schema) => Browser.value(schema);
|
|
8
|
-
const interpret = (maxLength, instance) =>
|
|
8
|
+
const interpret = (maxLength, instance) => {
|
|
9
|
+
return Instance.typeOf(instance) !== "string" || [...Instance.value(instance)].length <= maxLength;
|
|
10
|
+
};
|
|
9
11
|
|
|
10
12
|
export default { id, compile, interpret };
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Browser from "@hyperjump/browser";
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
const id = "https://json-schema.org/keyword/minContains";
|
|
5
|
+
const compile = (schema) => Browser.value(schema);
|
|
6
|
+
const interpret = () => true;
|
|
7
|
+
|
|
8
|
+
export default { id, compile, interpret };
|
package/lib/keywords/minItems.js
CHANGED
|
@@ -5,6 +5,8 @@ import * as Instance from "../instance.js";
|
|
|
5
5
|
const id = "https://json-schema.org/keyword/minItems";
|
|
6
6
|
|
|
7
7
|
const compile = (schema) => Browser.value(schema);
|
|
8
|
-
const interpret = (minItems, instance) =>
|
|
8
|
+
const interpret = (minItems, instance) => {
|
|
9
|
+
return Instance.typeOf(instance) !== "array" || Instance.length(instance) >= minItems;
|
|
10
|
+
};
|
|
9
11
|
|
|
10
12
|
export default { id, compile, interpret };
|
|
@@ -5,6 +5,8 @@ import * as Instance from "../instance.js";
|
|
|
5
5
|
const id = "https://json-schema.org/keyword/minLength";
|
|
6
6
|
|
|
7
7
|
const compile = (schema) => Browser.value(schema);
|
|
8
|
-
const interpret = (minLength, instance) =>
|
|
8
|
+
const interpret = (minLength, instance) => {
|
|
9
|
+
return Instance.typeOf(instance) !== "string" || [...Instance.value(instance)].length >= minLength;
|
|
10
|
+
};
|
|
9
11
|
|
|
10
12
|
export default { id, compile, interpret };
|
package/lib/keywords/oneOf.js
CHANGED
package/lib/keywords/pattern.js
CHANGED
|
@@ -5,6 +5,8 @@ import * as Instance from "../instance.js";
|
|
|
5
5
|
const id = "https://json-schema.org/keyword/pattern";
|
|
6
6
|
|
|
7
7
|
const compile = (schema) => new RegExp(Browser.value(schema), "u");
|
|
8
|
-
const interpret = (pattern, instance) =>
|
|
8
|
+
const interpret = (pattern, instance) => {
|
|
9
|
+
return Instance.typeOf(instance) !== "string" || pattern.test(Instance.value(instance));
|
|
10
|
+
};
|
|
9
11
|
|
|
10
12
|
export default { id, compile, interpret };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { pipe, asyncMap, asyncCollectArray
|
|
1
|
+
import { pipe, asyncMap, asyncCollectArray } from "@hyperjump/pact";
|
|
2
2
|
import * as Browser from "@hyperjump/browser";
|
|
3
3
|
import * as Instance from "../instance.js";
|
|
4
4
|
import { Validation } from "../experimental.js";
|
|
@@ -16,13 +16,21 @@ const compile = (schema, ast) => pipe(
|
|
|
16
16
|
);
|
|
17
17
|
|
|
18
18
|
const interpret = (patternProperties, instance, ast, dynamicAnchors, quiet) => {
|
|
19
|
-
|
|
20
|
-
return
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
if (Instance.typeOf(instance) !== "object") {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let isValid = true;
|
|
24
|
+
for (const [pattern, schemaUri] of patternProperties) {
|
|
25
|
+
for (const [propertyNameNode, propertyValue] of Instance.entries(instance)) {
|
|
26
|
+
const propertyName = Instance.value(propertyNameNode);
|
|
27
|
+
if (pattern.test(propertyName) && !Validation.interpret(schemaUri, propertyValue, ast, dynamicAnchors, quiet)) {
|
|
28
|
+
isValid = false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return isValid;
|
|
26
34
|
};
|
|
27
35
|
|
|
28
36
|
const collectEvaluatedProperties = (patternProperties, instance, ast, dynamicAnchors) => {
|
|
@@ -32,7 +40,8 @@ const collectEvaluatedProperties = (patternProperties, instance, ast, dynamicAnc
|
|
|
32
40
|
|
|
33
41
|
const evaluatedPropertyNames = new Set();
|
|
34
42
|
for (const [pattern, propertySchema] of patternProperties) {
|
|
35
|
-
for (const [
|
|
43
|
+
for (const [propertyNameNode, property] of Instance.entries(instance)) {
|
|
44
|
+
const propertyName = Instance.value(propertyNameNode);
|
|
36
45
|
if (pattern.test(propertyName)) {
|
|
37
46
|
if (!Validation.interpret(propertySchema, property, ast, dynamicAnchors, true)) {
|
|
38
47
|
return false;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { pipe, asyncMap, asyncCollectArray,
|
|
1
|
+
import { pipe, asyncMap, asyncCollectArray, zip } from "@hyperjump/pact";
|
|
2
2
|
import * as Browser from "@hyperjump/browser";
|
|
3
3
|
import * as Instance from "../instance.js";
|
|
4
4
|
import { Validation } from "../experimental.js";
|
|
@@ -13,11 +13,26 @@ const compile = (schema, ast) => pipe(
|
|
|
13
13
|
);
|
|
14
14
|
|
|
15
15
|
const interpret = (prefixItems, instance, ast, dynamicAnchors, quiet) => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
if (Instance.typeOf(instance) !== "array") {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
let isValid = true;
|
|
21
|
+
let index = 0;
|
|
22
|
+
const instanceLength = Instance.length(instance);
|
|
23
|
+
for (const [schemaUri, item] of zip(prefixItems, Instance.iter(instance))) {
|
|
24
|
+
if (index >= instanceLength) {
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (!Validation.interpret(schemaUri, item, ast, dynamicAnchors, quiet)) {
|
|
29
|
+
isValid = false;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
index++;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return isValid;
|
|
21
36
|
};
|
|
22
37
|
|
|
23
38
|
const collectEvaluatedItems = (items, instance, ast, dynamicAnchors) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { pipe, asyncMap, asyncCollectObject
|
|
1
|
+
import { pipe, asyncMap, asyncCollectObject } from "@hyperjump/pact";
|
|
2
2
|
import * as Browser from "@hyperjump/browser";
|
|
3
3
|
import * as Instance from "../instance.js";
|
|
4
4
|
import { Validation } from "../experimental.js";
|
|
@@ -13,11 +13,19 @@ const compile = (schema, ast) => pipe(
|
|
|
13
13
|
);
|
|
14
14
|
|
|
15
15
|
const interpret = (properties, instance, ast, dynamicAnchors, quiet) => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
if (Instance.typeOf(instance) !== "object") {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
let isValid = true;
|
|
21
|
+
for (const [propertyNameNode, property] of Instance.entries(instance)) {
|
|
22
|
+
const propertyName = Instance.value(propertyNameNode);
|
|
23
|
+
if (propertyName in properties && !Validation.interpret(properties[propertyName], property, ast, dynamicAnchors, quiet)) {
|
|
24
|
+
isValid = false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return isValid;
|
|
21
29
|
};
|
|
22
30
|
|
|
23
31
|
const collectEvaluatedProperties = (properties, instance, ast, dynamicAnchors) => {
|
|
@@ -26,7 +34,8 @@ const collectEvaluatedProperties = (properties, instance, ast, dynamicAnchors) =
|
|
|
26
34
|
}
|
|
27
35
|
|
|
28
36
|
const evaluatedPropertyNames = new Set();
|
|
29
|
-
for (const [
|
|
37
|
+
for (const [propertyNameNode, property] of Instance.entries(instance)) {
|
|
38
|
+
const propertyName = Instance.value(propertyNameNode);
|
|
30
39
|
if (propertyName in properties) {
|
|
31
40
|
if (!Validation.interpret(properties[propertyName], property, ast, dynamicAnchors, true)) {
|
|
32
41
|
return false;
|
|
@@ -21,12 +21,24 @@ const compile = (schema, ast) => {
|
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
const interpret = (propertyDependencies, instance, ast, dynamicAnchors, quiet) => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
if (Instance.typeOf(instance) !== "object") {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let isValid = true;
|
|
29
|
+
const instanceValue = Instance.value(instance);
|
|
30
|
+
for (const [propertyName, valueMappings] of Object.entries(propertyDependencies)) {
|
|
31
|
+
const propertyValue = instanceValue[propertyName];
|
|
32
|
+
if (
|
|
33
|
+
Instance.has(propertyName, instance)
|
|
34
|
+
&& propertyValue in valueMappings
|
|
35
|
+
&& !Validation.interpret(valueMappings[propertyValue], instance, ast, dynamicAnchors, quiet)
|
|
36
|
+
) {
|
|
37
|
+
isValid = false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return isValid;
|
|
30
42
|
};
|
|
31
43
|
|
|
32
44
|
const collectEvaluatedProperties = (propertyDependencies, instance, ast, dynamicAnchors) => {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { every } from "@hyperjump/pact";
|
|
2
|
-
import * as Instance from "../instance.js";
|
|
3
1
|
import { Validation } from "../experimental.js";
|
|
2
|
+
import * as Instance from "../instance.js";
|
|
4
3
|
|
|
5
4
|
|
|
6
5
|
const id = "https://json-schema.org/keyword/propertyNames";
|
|
@@ -8,9 +7,18 @@ const id = "https://json-schema.org/keyword/propertyNames";
|
|
|
8
7
|
const compile = (schema, ast) => Validation.compile(schema, ast);
|
|
9
8
|
|
|
10
9
|
const interpret = (propertyNames, instance, ast, dynamicAnchors) => {
|
|
11
|
-
|
|
12
|
-
return
|
|
13
|
-
}
|
|
10
|
+
if (Instance.typeOf(instance) !== "object") {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let isValid = true;
|
|
15
|
+
for (const key of Instance.keys(instance)) {
|
|
16
|
+
if (!Validation.interpret(propertyNames, key, ast, dynamicAnchors, true)) {
|
|
17
|
+
isValid = false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return isValid;
|
|
14
22
|
};
|
|
15
23
|
|
|
16
24
|
export default { id, compile, interpret };
|
package/lib/keywords/readOnly.js
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Browser from "@hyperjump/browser";
|
|
2
|
+
import * as Instance from "../../annotations/annotated-instance.js";
|
|
2
3
|
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
const id = "https://json-schema.org/keyword/readOnly";
|
|
6
|
+
|
|
7
|
+
const compile = (schema) => Browser.value(schema);
|
|
8
|
+
|
|
9
|
+
const interpret = (readOnly, instance, _ast, _dynamicAnchors, _quiet, schemaLocation) => {
|
|
10
|
+
Instance.setAnnotation(instance, id, schemaLocation, readOnly);
|
|
11
|
+
return true;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default { id, compile, interpret };
|
package/lib/keywords/title.js
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Browser from "@hyperjump/browser";
|
|
2
|
+
import * as Instance from "../../annotations/annotated-instance.js";
|
|
2
3
|
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
const id = "https://json-schema.org/keyword/title";
|
|
6
|
+
|
|
7
|
+
const compile = (schema) => Browser.value(schema);
|
|
8
|
+
|
|
9
|
+
const interpret = (title, instance, _ast, _dynamicAnchors, _quiet, schemaLocation) => {
|
|
10
|
+
Instance.setAnnotation(instance, id, schemaLocation, title);
|
|
11
|
+
return true;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default { id, compile, interpret };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { canonicalUri } from "../schema.js";
|
|
1
|
+
import { zip, range } from "@hyperjump/pact";
|
|
3
2
|
import * as Instance from "../instance.js";
|
|
3
|
+
import { canonicalUri } from "../schema.js";
|
|
4
4
|
import { Validation } from "../experimental.js";
|
|
5
5
|
|
|
6
6
|
|
|
@@ -16,11 +16,18 @@ const interpret = ([schemaUrl, unevaluatedItems], instance, ast, dynamicAnchors,
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
const itemIndexes = Validation.collectEvaluatedItems(schemaUrl, instance, ast, dynamicAnchors, true);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
if (itemIndexes === false) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let isValid = true;
|
|
24
|
+
for (const [item, index] of zip(Instance.iter(instance), range(0))) {
|
|
25
|
+
if (!itemIndexes.has(index) && !Validation.interpret(unevaluatedItems, item, ast, dynamicAnchors, quiet)) {
|
|
26
|
+
isValid = false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return isValid;
|
|
24
31
|
};
|
|
25
32
|
|
|
26
33
|
const collectEvaluatedItems = (keywordValue, instance, ast, dynamicAnchors) => {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { pipe, filter, every } from "@hyperjump/pact";
|
|
2
|
-
import * as Instance from "../instance.js";
|
|
3
1
|
import { Validation, canonicalUri } from "../experimental.js";
|
|
2
|
+
import * as Instance from "../instance.js";
|
|
4
3
|
|
|
5
4
|
|
|
6
5
|
const id = "https://json-schema.org/keyword/unevaluatedProperties";
|
|
@@ -15,12 +14,19 @@ const interpret = ([schemaUrl, unevaluatedProperties], instance, ast, dynamicAnc
|
|
|
15
14
|
}
|
|
16
15
|
|
|
17
16
|
const evaluatedPropertyNames = Validation.collectEvaluatedProperties(schemaUrl, instance, ast, dynamicAnchors, true);
|
|
17
|
+
if (evaluatedPropertyNames === false) {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let isValid = true;
|
|
22
|
+
for (const [propertyNameNode, property] of Instance.entries(instance)) {
|
|
23
|
+
const propertyName = Instance.value(propertyNameNode);
|
|
24
|
+
if (!evaluatedPropertyNames.has(propertyName) && !Validation.interpret(unevaluatedProperties, property, ast, dynamicAnchors, quiet)) {
|
|
25
|
+
isValid = false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
18
28
|
|
|
19
|
-
return
|
|
20
|
-
Instance.entries(instance),
|
|
21
|
-
filter(([propertyName]) => !evaluatedPropertyNames.has(propertyName)),
|
|
22
|
-
every(([, property]) => Validation.interpret(unevaluatedProperties, property, ast, dynamicAnchors, quiet))
|
|
23
|
-
);
|
|
29
|
+
return isValid;
|
|
24
30
|
};
|
|
25
31
|
|
|
26
32
|
const collectEvaluatedProperties = ([schemaUrl, unevaluatedProperties], instance, ast, dynamicAnchors) => {
|
|
@@ -34,7 +40,8 @@ const collectEvaluatedProperties = ([schemaUrl, unevaluatedProperties], instance
|
|
|
34
40
|
return false;
|
|
35
41
|
}
|
|
36
42
|
|
|
37
|
-
for (const [
|
|
43
|
+
for (const [propertyNameNode, property] of Instance.entries(instance)) {
|
|
44
|
+
const propertyName = Instance.value(propertyNameNode);
|
|
38
45
|
if (!evaluatedPropertyNames.has(propertyName)) {
|
|
39
46
|
if (!Validation.interpret(unevaluatedProperties, property, ast, dynamicAnchors, true)) {
|
|
40
47
|
return false;
|
package/lib/keywords/unknown.js
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Browser from "@hyperjump/browser";
|
|
2
|
+
import * as Instance from "../../annotations/annotated-instance.js";
|
|
2
3
|
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
const id = "https://json-schema.org/keyword/unknown";
|
|
6
|
+
|
|
7
|
+
const compile = (schema) => Browser.value(schema);
|
|
8
|
+
|
|
9
|
+
const interpret = (value, instance, _ast, _dynamicAnchors, _quiet, schemaLocation) => {
|
|
10
|
+
Instance.setAnnotation(instance, id, schemaLocation, value);
|
|
11
|
+
return true;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default { id, compile, interpret };
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { value, entries } from "@hyperjump/browser";
|
|
2
2
|
import { pipe, asyncMap, asyncCollectArray } from "@hyperjump/pact";
|
|
3
3
|
import { append as pointerAppend } from "@hyperjump/json-pointer";
|
|
4
|
-
import { publishAsync
|
|
5
|
-
import * as Instance from "../instance.js";
|
|
4
|
+
import { publishAsync } from "../pubsub.js";
|
|
6
5
|
import { toAbsoluteUri } from "../common.js";
|
|
7
6
|
import { canonicalUri, getKeyword, getKeywordByName } from "../experimental.js";
|
|
8
7
|
|
|
@@ -47,31 +46,29 @@ const compile = async (schema, ast) => {
|
|
|
47
46
|
const interpret = (url, instance, ast, dynamicAnchors, quiet = false) => {
|
|
48
47
|
dynamicAnchors = { ...ast.metaData[toAbsoluteUri(url)].dynamicAnchors, ...dynamicAnchors };
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
!quiet && publish("result.end");
|
|
74
|
-
return isValid;
|
|
49
|
+
let isSchemaValid = true;
|
|
50
|
+
if (typeof ast[url] === "boolean") {
|
|
51
|
+
isSchemaValid = ast[url];
|
|
52
|
+
} else {
|
|
53
|
+
for (const [keywordId, schemaUrl, keywordValue] of ast[url]) {
|
|
54
|
+
instance.valid = getKeyword(keywordId).interpret(keywordValue, instance, ast, dynamicAnchors, quiet, url);
|
|
55
|
+
if (!instance.valid) {
|
|
56
|
+
if (!quiet) {
|
|
57
|
+
instance.errors[schemaUrl] = keywordId;
|
|
58
|
+
}
|
|
59
|
+
isSchemaValid = false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!isSchemaValid) {
|
|
65
|
+
if (!quiet) {
|
|
66
|
+
instance.errors[url] = id;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
instance.valid = isSchemaValid;
|
|
71
|
+
return isSchemaValid;
|
|
75
72
|
};
|
|
76
73
|
|
|
77
74
|
const emptyPropertyNames = new Set();
|
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Browser from "@hyperjump/browser";
|
|
2
|
+
import * as Instance from "../../annotations/annotated-instance.js";
|
|
2
3
|
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
const id = "https://json-schema.org/keyword/writeOnly";
|
|
6
|
+
|
|
7
|
+
const compile = (schema) => Browser.value(schema);
|
|
8
|
+
|
|
9
|
+
const interpret = (writeOnly, instance, _ast, _dynamicAnchors, _quiet, schemaLocation) => {
|
|
10
|
+
Instance.setAnnotation(instance, id, schemaLocation, writeOnly);
|
|
11
|
+
return true;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default { id, compile, interpret };
|
package/lib/keywords.js
CHANGED
package/lib/output.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { allNodes } from "./instance.js";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
const outputFormats = {};
|
|
5
|
+
|
|
6
|
+
export const toOutputFormat = (node, outputFormat) => {
|
|
7
|
+
if (outputFormat in outputFormats) {
|
|
8
|
+
return outputFormats[outputFormat](node);
|
|
9
|
+
} else {
|
|
10
|
+
throw Error(`The '${outputFormat}' error format is not supported`);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
outputFormats.FLAG = (instance) => {
|
|
15
|
+
return { valid: instance.valid };
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
outputFormats.BASIC = (instance) => {
|
|
19
|
+
const output = {
|
|
20
|
+
valid: instance.valid
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
if (!instance.valid) {
|
|
24
|
+
output.errors = [];
|
|
25
|
+
|
|
26
|
+
for (const child of allNodes(instance)) {
|
|
27
|
+
for (const [absoluteKeywordLocation, keyword] of Object.entries(child.errors).reverse()) {
|
|
28
|
+
if (!child.valid) {
|
|
29
|
+
output.errors.unshift({
|
|
30
|
+
keyword,
|
|
31
|
+
absoluteKeywordLocation,
|
|
32
|
+
instanceLocation: child.uri(),
|
|
33
|
+
valid: child.valid
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
output.errors.pop();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return output;
|
|
43
|
+
};
|