@hyperjump/json-schema 1.13.0 → 1.14.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 +14 -20
- package/annotations/index.js +27 -7
- package/bundle/index.js +39 -227
- package/draft-04/additionalItems.js +13 -19
- package/draft-04/items.js +26 -14
- package/draft-2020-12/dynamicRef.js +20 -8
- package/lib/core.js +19 -4
- package/lib/evaluation-plugins/annotations.js +32 -0
- package/lib/evaluation-plugins/basic-output.js +34 -0
- package/lib/evaluation-plugins/detailed-output.js +36 -0
- package/lib/experimental.d.ts +18 -5
- package/lib/experimental.js +3 -0
- package/lib/instance.js +12 -3
- package/lib/keywords/additionalProperties.js +8 -22
- package/lib/keywords/allOf.js +1 -29
- package/lib/keywords/anyOf.js +1 -27
- package/lib/keywords/conditional.js +1 -27
- package/lib/keywords/contains.js +14 -18
- package/lib/keywords/dependentSchemas.js +1 -21
- package/lib/keywords/dynamicRef.js +19 -6
- package/lib/keywords/else.js +2 -19
- package/lib/keywords/if.js +1 -9
- package/lib/keywords/itemPattern.js +5 -9
- package/lib/keywords/items.js +5 -14
- package/lib/keywords/oneOf.js +1 -33
- package/lib/keywords/patternProperties.js +7 -25
- package/lib/keywords/prefixItems.js +2 -5
- package/lib/keywords/properties.js +6 -22
- package/lib/keywords/propertyDependencies.js +1 -20
- package/lib/keywords/propertyNames.js +1 -1
- package/lib/keywords/ref.js +1 -3
- package/lib/keywords/then.js +2 -19
- package/lib/keywords/unevaluatedItems.js +44 -20
- package/lib/keywords/unevaluatedProperties.js +40 -26
- package/lib/keywords/validation.js +31 -129
- package/lib/keywords.js +30 -30
- package/package.json +1 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Validation } from "../experimental.js";
|
|
2
|
+
import * as Instance from "../instance.js";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export const basicOutputPlugin = {
|
|
6
|
+
beforeSchema(_url, _intance, context) {
|
|
7
|
+
context.errors ??= [];
|
|
8
|
+
},
|
|
9
|
+
beforeKeyword(_node, _instance, context) {
|
|
10
|
+
context.errors = [];
|
|
11
|
+
},
|
|
12
|
+
afterKeyword(node, instance, context, valid, schemaContext, keyword) {
|
|
13
|
+
if (!valid) {
|
|
14
|
+
if (!keyword.simpleApplicator) {
|
|
15
|
+
const [keywordId, schemaUri] = node;
|
|
16
|
+
schemaContext.errors.push({
|
|
17
|
+
keyword: keywordId,
|
|
18
|
+
absoluteKeywordLocation: schemaUri,
|
|
19
|
+
instanceLocation: Instance.uri(instance)
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
schemaContext.errors.push(...context.errors);
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
afterSchema(url, instance, context, valid) {
|
|
26
|
+
if (typeof context.ast[url] === "boolean" && !valid) {
|
|
27
|
+
context.errors.push({
|
|
28
|
+
keyword: Validation.id,
|
|
29
|
+
absoluteKeywordLocation: url,
|
|
30
|
+
instanceLocation: Instance.uri(instance)
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Validation } from "../experimental.js";
|
|
2
|
+
import * as Instance from "../instance.js";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export const detailedOutputPlugin = {
|
|
6
|
+
beforeSchema(_url, _instance, context) {
|
|
7
|
+
context.errors ??= [];
|
|
8
|
+
},
|
|
9
|
+
beforeKeyword(_node, _instance, context) {
|
|
10
|
+
context.errors = [];
|
|
11
|
+
},
|
|
12
|
+
afterKeyword(node, instance, context, valid, schemaContext) {
|
|
13
|
+
if (!valid) {
|
|
14
|
+
const [keywordId, schemaUri] = node;
|
|
15
|
+
const outputUnit = {
|
|
16
|
+
keyword: keywordId,
|
|
17
|
+
absoluteKeywordLocation: schemaUri,
|
|
18
|
+
instanceLocation: Instance.uri(instance)
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
schemaContext.errors.push(outputUnit);
|
|
22
|
+
if (context.errors.length > 0) {
|
|
23
|
+
outputUnit.errors = context.errors;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
afterSchema(url, instance, context, valid) {
|
|
28
|
+
if (typeof context.ast[url] === "boolean" && !valid) {
|
|
29
|
+
context.errors.push({
|
|
30
|
+
keyword: Validation.id,
|
|
31
|
+
absoluteKeywordLocation: url,
|
|
32
|
+
instanceLocation: Instance.uri(instance)
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
};
|
package/lib/experimental.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export type CompiledSchema = {
|
|
|
18
18
|
|
|
19
19
|
type AST = {
|
|
20
20
|
metaData: Record<string, MetaData>;
|
|
21
|
+
plugins: Set<EvaluationPlugin<unknown>>;
|
|
21
22
|
} & Record<string, Node<unknown>[] | boolean>;
|
|
22
23
|
|
|
23
24
|
type Node<A> = [keywordId: string, schemaUri: string, keywordValue: A];
|
|
@@ -70,18 +71,30 @@ export type Keyword<A> = {
|
|
|
70
71
|
compile: (schema: Browser<SchemaDocument>, ast: AST, parentSchema: Browser<SchemaDocument>) => Promise<A>;
|
|
71
72
|
interpret: (compiledKeywordValue: A, instance: JsonNode, context: ValidationContext) => boolean;
|
|
72
73
|
simpleApplicator: boolean;
|
|
73
|
-
collectEvaluatedProperties?: (compiledKeywordValue: A, instance: JsonNode, context: ValidationContext, isTop?: boolean) => Set<string> | false;
|
|
74
|
-
collectEvaluatedItems?: (compiledKeywordValue: A, instance: JsonNode, context: ValidationContext, isTop?: boolean) => Set<number> | false;
|
|
75
|
-
collectExternalIds?: (visited: Set<string>, parentSchema: Browser<SchemaDocument>, schema: Browser<SchemaDocument>) => Promise<Set<string>>;
|
|
76
74
|
annotation?: <B>(compiledKeywordValue: A, instance: JsonNode) => B | undefined;
|
|
77
75
|
};
|
|
78
76
|
|
|
79
77
|
export type ValidationContext = {
|
|
80
78
|
ast: AST;
|
|
81
|
-
|
|
79
|
+
plugins: EvaluationPlugin<unknown>[];
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export type EvaluationPlugin<Context> = {
|
|
83
|
+
beforeSchema(url: string, instance: JsonNode, context: Context): void;
|
|
84
|
+
beforeKeyword(keywordNode: Node<unknown>, instance: JsonNode, context: Context, schemaContext: Context, keyword: Keyword): void;
|
|
85
|
+
afterKeyword(keywordNode: Node<unknown>, instance: JsonNode, context: Context, valid: boolean, schemaContext: Context, keyword: Keyword): void;
|
|
86
|
+
afterSchema(url: string, instance: JsonNode, context: Context, valid: boolean): void;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export const basicOutputPlugin: EvaluationPlugin<ErrorsContext>;
|
|
90
|
+
export const detailedOutputPlugin: EvaluationPlugin<ErrorsContext>;
|
|
91
|
+
export type ErrorsContext = {
|
|
82
92
|
errors: OutputUnit[];
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export const annotationsPlugin: EvaluationPlugin<AnnotationsContext>;
|
|
96
|
+
export type AnnotationsContext = {
|
|
83
97
|
annotations: OutputUnit[];
|
|
84
|
-
outputFormat: OutputFormat;
|
|
85
98
|
};
|
|
86
99
|
|
|
87
100
|
export const Validation: Keyword<string>;
|
package/lib/experimental.js
CHANGED
|
@@ -6,3 +6,6 @@ export {
|
|
|
6
6
|
} from "./keywords.js";
|
|
7
7
|
export { getSchema, toSchema, canonicalUri, buildSchemaDocument } from "./schema.js";
|
|
8
8
|
export { default as Validation } from "./keywords/validation.js";
|
|
9
|
+
export { basicOutputPlugin } from "./evaluation-plugins/basic-output.js";
|
|
10
|
+
export { detailedOutputPlugin } from "./evaluation-plugins/detailed-output.js";
|
|
11
|
+
export { annotationsPlugin } from "./evaluation-plugins/annotations.js";
|
package/lib/instance.js
CHANGED
|
@@ -27,7 +27,8 @@ export const fromJs = (value, uri = "", pointer = "", parent = undefined) => {
|
|
|
27
27
|
objectNode.children = Object.entries(value).map((entry) => {
|
|
28
28
|
const propertyPointer = JsonPointer.append(entry[0], pointer);
|
|
29
29
|
const propertyNode = cons(uri, propertyPointer, undefined, "property", [], objectNode);
|
|
30
|
-
propertyNode.children =
|
|
30
|
+
propertyNode.children[0] = fromJs(entry[0], uri, "*" + propertyPointer, propertyNode);
|
|
31
|
+
propertyNode.children[1] = fromJs(entry[1], uri, propertyPointer, propertyNode);
|
|
31
32
|
return propertyNode;
|
|
32
33
|
});
|
|
33
34
|
return objectNode;
|
|
@@ -62,11 +63,19 @@ export const get = (uri, instance) => {
|
|
|
62
63
|
throw Error(`Reference '${uri}' is not local to '${instance.baseUri}'`);
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
let isPropertyNamePointer = false;
|
|
67
|
+
let pointer = uriFragment(uri);
|
|
68
|
+
if (pointer.startsWith("*")) {
|
|
69
|
+
pointer = pointer.slice(1);
|
|
70
|
+
isPropertyNamePointer = true;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const result = reduce((node, segment) => {
|
|
67
74
|
segment = segment === "-" && typeOf(node) === "array" ? length(node) : segment;
|
|
68
75
|
return step(segment, node);
|
|
69
76
|
}, instance.root, JsonPointer.pointerSegments(pointer));
|
|
77
|
+
|
|
78
|
+
return isPropertyNamePointer ? result.parent.children[0] : result;
|
|
70
79
|
};
|
|
71
80
|
|
|
72
81
|
export const uri = (node) => `${node.baseUri}#${encodeURI(node.pointer)}`;
|
|
@@ -39,9 +39,15 @@ const interpret = ([isDefinedProperty, additionalProperties], instance, context)
|
|
|
39
39
|
let isValid = true;
|
|
40
40
|
for (const [propertyNameNode, property] of Instance.entries(instance)) {
|
|
41
41
|
const propertyName = Instance.value(propertyNameNode);
|
|
42
|
-
if (
|
|
42
|
+
if (isDefinedProperty.test(propertyName)) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!Validation.interpret(additionalProperties, property, context)) {
|
|
43
47
|
isValid = false;
|
|
44
48
|
}
|
|
49
|
+
|
|
50
|
+
context.evaluatedProperties?.add(propertyName);
|
|
45
51
|
}
|
|
46
52
|
|
|
47
53
|
return isValid;
|
|
@@ -49,24 +55,4 @@ const interpret = ([isDefinedProperty, additionalProperties], instance, context)
|
|
|
49
55
|
|
|
50
56
|
const simpleApplicator = true;
|
|
51
57
|
|
|
52
|
-
|
|
53
|
-
if (Instance.typeOf(instance) !== "object") {
|
|
54
|
-
return true;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const evaluatedPropertyNames = new Set();
|
|
58
|
-
for (const [propertyNameNode, property] of Instance.entries(instance)) {
|
|
59
|
-
const propertyName = Instance.value(propertyNameNode);
|
|
60
|
-
if (!isDefinedProperty.test(propertyName)) {
|
|
61
|
-
if (!Validation.interpret(additionalProperties, property, context)) {
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
evaluatedPropertyNames.add(propertyName);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return evaluatedPropertyNames;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
export default { id, compile, interpret, simpleApplicator, collectEvaluatedProperties };
|
|
58
|
+
export default { id, compile, interpret, simpleApplicator };
|
package/lib/keywords/allOf.js
CHANGED
|
@@ -23,32 +23,4 @@ const interpret = (allOf, instance, ast, dynamicAnchors, quiet) => {
|
|
|
23
23
|
|
|
24
24
|
const simpleApplicator = true;
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
const evaluatedPropertyNames = new Set();
|
|
28
|
-
for (const schemaUrl of allOf) {
|
|
29
|
-
const propertyNames = Validation.collectEvaluatedProperties(schemaUrl, instance, context);
|
|
30
|
-
if (!propertyNames) {
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
propertyNames.forEach(evaluatedPropertyNames.add, evaluatedPropertyNames);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return evaluatedPropertyNames;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const collectEvaluatedItems = (allOf, instance, context) => {
|
|
41
|
-
const evaluatedItemIndexes = new Set();
|
|
42
|
-
for (const schemaUrl of allOf) {
|
|
43
|
-
const itemIndexes = Validation.collectEvaluatedItems(schemaUrl, instance, context);
|
|
44
|
-
if (!itemIndexes) {
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
itemIndexes.forEach(evaluatedItemIndexes.add, evaluatedItemIndexes);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return evaluatedItemIndexes;
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
export default { id, compile, interpret, simpleApplicator, collectEvaluatedProperties, collectEvaluatedItems };
|
|
26
|
+
export default { id, compile, interpret, simpleApplicator };
|
package/lib/keywords/anyOf.js
CHANGED
|
@@ -16,30 +16,4 @@ const interpret = (anyOf, instance, ast, dynamicAnchors, quiet) => {
|
|
|
16
16
|
return matches.length > 0;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
let evaluatedPropertyNames = false;
|
|
21
|
-
for (const schemaUrl of anyOf) {
|
|
22
|
-
const propertyNames = Validation.collectEvaluatedProperties(schemaUrl, instance, context);
|
|
23
|
-
if (propertyNames) {
|
|
24
|
-
evaluatedPropertyNames ||= new Set();
|
|
25
|
-
propertyNames.forEach(evaluatedPropertyNames.add, evaluatedPropertyNames);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return evaluatedPropertyNames;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const collectEvaluatedItems = (anyOf, instance, context) => {
|
|
33
|
-
let evaluatedItemIndexes = false;
|
|
34
|
-
for (const schemaUrl of anyOf) {
|
|
35
|
-
const itemIndexes = Validation.collectEvaluatedItems(schemaUrl, instance, context);
|
|
36
|
-
if (itemIndexes) {
|
|
37
|
-
evaluatedItemIndexes ||= new Set();
|
|
38
|
-
itemIndexes.forEach(evaluatedItemIndexes.add, evaluatedItemIndexes);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return evaluatedItemIndexes;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export default { id, compile, interpret, collectEvaluatedProperties, collectEvaluatedItems };
|
|
19
|
+
export default { id, compile, interpret };
|
|
@@ -25,32 +25,6 @@ const interpret = (conditional, instance, context) => {
|
|
|
25
25
|
return true;
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
const collectEvaluatedProperties = (conditional, instance, context) => {
|
|
29
|
-
for (let index = 0; index < conditional.length; index += 2) {
|
|
30
|
-
const unevaluatedProperties = Validation.collectEvaluatedProperties(conditional[index], instance, context);
|
|
31
|
-
if (index + 1 === conditional.length) {
|
|
32
|
-
return unevaluatedProperties;
|
|
33
|
-
} else if (unevaluatedProperties !== false) {
|
|
34
|
-
return Validation.collectEvaluatedProperties(conditional[index + 1], instance, context);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return new Set();
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const collectEvaluatedItems = (conditional, instance, context) => {
|
|
42
|
-
for (let index = 0; index < conditional.length; index += 2) {
|
|
43
|
-
const unevaluatedItems = Validation.collectEvaluatedItems(conditional[index], instance, context);
|
|
44
|
-
if (index + 1 === conditional.length) {
|
|
45
|
-
return unevaluatedItems;
|
|
46
|
-
} else if (unevaluatedItems !== false) {
|
|
47
|
-
return Validation.collectEvaluatedItems(conditional[index + 1], instance, context);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return new Set();
|
|
52
|
-
};
|
|
53
|
-
|
|
54
28
|
const schemaFlatten = async function* (iter, depth = 1) {
|
|
55
29
|
for await (const n of iter) {
|
|
56
30
|
if (depth > 0 && Browser.typeOf(n) === "array") {
|
|
@@ -61,4 +35,4 @@ const schemaFlatten = async function* (iter, depth = 1) {
|
|
|
61
35
|
}
|
|
62
36
|
};
|
|
63
37
|
|
|
64
|
-
export default { id, compile, interpret
|
|
38
|
+
export default { id, compile, interpret };
|
package/lib/keywords/contains.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { pipe, filter, reduce, zip, range, map, collectSet } from "@hyperjump/pact";
|
|
2
1
|
import * as Browser from "@hyperjump/browser";
|
|
3
2
|
import * as Instance from "../instance.js";
|
|
4
3
|
import { getKeywordName, Validation } from "../experimental.js";
|
|
@@ -21,23 +20,20 @@ const compile = async (schema, ast, parentSchema) => {
|
|
|
21
20
|
};
|
|
22
21
|
|
|
23
22
|
const interpret = ({ contains, minContains, maxContains }, instance, context) => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
if (Instance.typeOf(instance) !== "array") {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let matches = 0;
|
|
28
|
+
let index = 0;
|
|
29
|
+
for (const item of Instance.iter(instance)) {
|
|
30
|
+
if (Validation.interpret(contains, item, context)) {
|
|
31
|
+
matches++;
|
|
32
|
+
context.evaluatedItems?.add(index);
|
|
33
|
+
}
|
|
34
|
+
index++;
|
|
35
|
+
}
|
|
29
36
|
return matches >= minContains && matches <= maxContains;
|
|
30
37
|
};
|
|
31
38
|
|
|
32
|
-
|
|
33
|
-
return interpret(keywordValue, instance, context)
|
|
34
|
-
&& Instance.typeOf(instance) === "array"
|
|
35
|
-
&& pipe(
|
|
36
|
-
zip(Instance.iter(instance), range(0)),
|
|
37
|
-
filter(([item]) => Validation.interpret(keywordValue.contains, item, context)),
|
|
38
|
-
map(([, itemIndex]) => itemIndex),
|
|
39
|
-
collectSet
|
|
40
|
-
);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export default { id, compile, interpret, collectEvaluatedItems };
|
|
39
|
+
export default { id, compile, interpret };
|
|
@@ -29,24 +29,4 @@ const interpret = (dependentSchemas, instance, context) => {
|
|
|
29
29
|
|
|
30
30
|
const simpleApplicator = true;
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
if (Instance.typeOf(instance) !== "object") {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const evaluatedPropertyNames = new Set();
|
|
38
|
-
for (const [propertyName, dependentSchema] of dependentSchemas) {
|
|
39
|
-
if (Instance.has(propertyName, instance)) {
|
|
40
|
-
const propertyNames = Validation.collectEvaluatedProperties(dependentSchema, instance, context);
|
|
41
|
-
if (propertyNames === false) {
|
|
42
|
-
return false;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
propertyNames.forEach(Set.prototype.add.bind(evaluatedPropertyNames));
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return evaluatedPropertyNames;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
export default { id, compile, interpret, simpleApplicator, collectEvaluatedProperties };
|
|
32
|
+
export default { id, compile, interpret, simpleApplicator };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as Browser from "@hyperjump/browser";
|
|
2
2
|
import { Validation } from "../experimental.js";
|
|
3
|
+
import { toAbsoluteUri } from "../common.js";
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
const id = "https://json-schema.org/keyword/dynamicRef";
|
|
@@ -12,17 +13,29 @@ const compile = async (schema, ast) => {
|
|
|
12
13
|
return reference;
|
|
13
14
|
};
|
|
14
15
|
|
|
15
|
-
const
|
|
16
|
+
const interpret = (fragment, instance, context) => {
|
|
16
17
|
if (!(fragment in context.dynamicAnchors)) {
|
|
17
18
|
throw Error(`No dynamic anchor found for "${fragment}"`);
|
|
18
19
|
}
|
|
19
|
-
return
|
|
20
|
+
return Validation.interpret(context.dynamicAnchors[fragment], instance, context);
|
|
20
21
|
};
|
|
21
22
|
|
|
22
23
|
const simpleApplicator = true;
|
|
23
24
|
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
const plugin = {
|
|
26
|
+
beforeSchema(url, _instance, context) {
|
|
27
|
+
context.dynamicAnchors = {
|
|
28
|
+
...context.ast.metaData[toAbsoluteUri(url)].dynamicAnchors,
|
|
29
|
+
...context.dynamicAnchors
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
beforeKeyword(_url, _instance, context, schemaContext) {
|
|
33
|
+
context.dynamicAnchors = schemaContext.dynamicAnchors;
|
|
34
|
+
},
|
|
35
|
+
afterKeyword() {
|
|
36
|
+
},
|
|
37
|
+
afterSchema() {
|
|
38
|
+
}
|
|
39
|
+
};
|
|
27
40
|
|
|
28
|
-
export default { id, compile, interpret, simpleApplicator,
|
|
41
|
+
export default { id, compile, interpret, simpleApplicator, plugin };
|
package/lib/keywords/else.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as Browser from "@hyperjump/browser";
|
|
2
|
-
import { FLAG } from "../index.js";
|
|
3
2
|
import { getKeywordName, Validation } from "../experimental.js";
|
|
4
3
|
|
|
5
4
|
|
|
@@ -17,26 +16,10 @@ const compile = async (schema, ast, parentSchema) => {
|
|
|
17
16
|
|
|
18
17
|
const interpret = ([ifSchema, elseSchema], instance, context) => {
|
|
19
18
|
return ifSchema === undefined
|
|
20
|
-
|| Validation.interpret(ifSchema, instance, { ...context,
|
|
19
|
+
|| Validation.interpret(ifSchema, instance, { ...context, plugins: context.ast.plugins })
|
|
21
20
|
|| Validation.interpret(elseSchema, instance, context);
|
|
22
21
|
};
|
|
23
22
|
|
|
24
23
|
const simpleApplicator = true;
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
if (ifSchema === undefined || Validation.interpret(ifSchema, instance, context)) {
|
|
28
|
-
return new Set();
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return Validation.collectEvaluatedProperties(elseSchema, instance, context);
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
const collectEvaluatedItems = ([ifSchema, elseSchema], instance, context) => {
|
|
35
|
-
if (ifSchema === undefined || Validation.interpret(ifSchema, instance, context)) {
|
|
36
|
-
return new Set();
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return Validation.collectEvaluatedItems(elseSchema, instance, context);
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export default { id, compile, interpret, simpleApplicator, collectEvaluatedProperties, collectEvaluatedItems };
|
|
25
|
+
export default { id, compile, interpret, simpleApplicator };
|
package/lib/keywords/if.js
CHANGED
|
@@ -10,12 +10,4 @@ const interpret = (ifSchema, instance, context) => {
|
|
|
10
10
|
return true;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
return Validation.collectEvaluatedProperties(ifSchema, instance, context) || new Set();
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const collectEvaluatedItems = (ifSchema, instance, context) => {
|
|
18
|
-
return Validation.collectEvaluatedItems(ifSchema, instance, context) || new Set();
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export default { id, compile, interpret, collectEvaluatedProperties, collectEvaluatedItems };
|
|
13
|
+
export default { id, compile, interpret };
|
|
@@ -39,7 +39,7 @@ const compile = async (schema, ast) => {
|
|
|
39
39
|
.reduce(union);
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
-
const
|
|
42
|
+
const interpret = (nfa, instance, context) => {
|
|
43
43
|
if (Instance.typeOf(instance) !== "array") {
|
|
44
44
|
return true;
|
|
45
45
|
}
|
|
@@ -51,7 +51,7 @@ const evaluate = (strategy, nfa, instance, context) => {
|
|
|
51
51
|
const nextStates = [];
|
|
52
52
|
|
|
53
53
|
for (const state of currentStates) {
|
|
54
|
-
const nextState = transition(
|
|
54
|
+
const nextState = transition(state.transition, item, context);
|
|
55
55
|
if (nextState) {
|
|
56
56
|
addNextState(nextState, nextStates, []);
|
|
57
57
|
}
|
|
@@ -76,16 +76,12 @@ const addNextState = (state, nextStates, visited) => {
|
|
|
76
76
|
}
|
|
77
77
|
};
|
|
78
78
|
|
|
79
|
-
const transition = (
|
|
79
|
+
const transition = (transitions, instance, context) => {
|
|
80
80
|
for (const schema in transitions) {
|
|
81
|
-
if (
|
|
81
|
+
if (Validation.interpret(schema, instance, context)) {
|
|
82
82
|
return transitions[schema];
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
};
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
const collectEvalatedProperties = (...args) => evaluate(Validation.collectEvaluatedProperties, ...args);
|
|
89
|
-
const collectEvalatedItems = (...args) => evaluate(Validation.collectEvaluatedItems, ...args);
|
|
90
|
-
|
|
91
|
-
export default { id, compile, interpret, collectEvalatedProperties, collectEvalatedItems };
|
|
87
|
+
export default { id, compile, interpret };
|
package/lib/keywords/items.js
CHANGED
|
@@ -20,10 +20,14 @@ const interpret = ([numberOfPrefixItems, items], instance, context) => {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
let isValid = true;
|
|
23
|
+
let index = numberOfPrefixItems;
|
|
23
24
|
for (const item of drop(numberOfPrefixItems, Instance.iter(instance))) {
|
|
24
25
|
if (!Validation.interpret(items, item, context)) {
|
|
25
26
|
isValid = false;
|
|
26
27
|
}
|
|
28
|
+
|
|
29
|
+
context.evaluatedItems?.add(index);
|
|
30
|
+
index++;
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
return isValid;
|
|
@@ -31,17 +35,4 @@ const interpret = ([numberOfPrefixItems, items], instance, context) => {
|
|
|
31
35
|
|
|
32
36
|
const simpleApplicator = true;
|
|
33
37
|
|
|
34
|
-
|
|
35
|
-
if (!interpret(keywordValue, instance, context)) {
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const evaluatedIndexes = new Set();
|
|
40
|
-
for (let ndx = keywordValue[0]; ndx < Instance.length(instance); ndx++) {
|
|
41
|
-
evaluatedIndexes.add(ndx);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return evaluatedIndexes;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
export default { id, compile, interpret, simpleApplicator, collectEvaluatedItems };
|
|
38
|
+
export default { id, compile, interpret, simpleApplicator };
|
package/lib/keywords/oneOf.js
CHANGED
|
@@ -22,36 +22,4 @@ const interpret = (oneOf, instance, context) => {
|
|
|
22
22
|
return validCount === 1;
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
let evaluatedProperties = false;
|
|
27
|
-
for (const schemaUrl of oneOf) {
|
|
28
|
-
const propertyNames = Validation.collectEvaluatedProperties(schemaUrl, instance, context);
|
|
29
|
-
if (propertyNames) {
|
|
30
|
-
if (evaluatedProperties) {
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
evaluatedProperties = propertyNames;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return evaluatedProperties;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const collectEvaluatedItems = (oneOf, instance, context) => {
|
|
42
|
-
let evaluatedItemIndexes = false;
|
|
43
|
-
for (const schemaUrl of oneOf) {
|
|
44
|
-
const itemIndexes = Validation.collectEvaluatedItems(schemaUrl, instance, context);
|
|
45
|
-
if (itemIndexes) {
|
|
46
|
-
if (evaluatedItemIndexes) {
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
evaluatedItemIndexes = itemIndexes;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return evaluatedItemIndexes;
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
export default { id, compile, interpret, collectEvaluatedProperties, collectEvaluatedItems };
|
|
25
|
+
export default { id, compile, interpret };
|
|
@@ -23,38 +23,20 @@ const interpret = (patternProperties, instance, context) => {
|
|
|
23
23
|
let isValid = true;
|
|
24
24
|
for (const [pattern, schemaUri] of patternProperties) {
|
|
25
25
|
for (const [propertyNameNode, propertyValue] of Instance.entries(instance)) {
|
|
26
|
-
const propertyName = Instance.value(propertyNameNode);
|
|
27
|
-
if (pattern.test(propertyName) && !Validation.interpret(schemaUri, propertyValue, context)) {
|
|
28
|
-
isValid = false;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return isValid;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const simpleApplicator = true;
|
|
37
|
-
|
|
38
|
-
const collectEvaluatedProperties = (patternProperties, instance, context) => {
|
|
39
|
-
if (Instance.typeOf(instance) !== "object") {
|
|
40
|
-
return false;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const evaluatedPropertyNames = new Set();
|
|
44
|
-
for (const [pattern, propertySchema] of patternProperties) {
|
|
45
|
-
for (const [propertyNameNode, property] of Instance.entries(instance)) {
|
|
46
26
|
const propertyName = Instance.value(propertyNameNode);
|
|
47
27
|
if (pattern.test(propertyName)) {
|
|
48
|
-
if (!Validation.interpret(
|
|
49
|
-
|
|
28
|
+
if (!Validation.interpret(schemaUri, propertyValue, context)) {
|
|
29
|
+
isValid = false;
|
|
50
30
|
}
|
|
51
31
|
|
|
52
|
-
|
|
32
|
+
context.evaluatedProperties?.add(propertyName);
|
|
53
33
|
}
|
|
54
34
|
}
|
|
55
35
|
}
|
|
56
36
|
|
|
57
|
-
return
|
|
37
|
+
return isValid;
|
|
58
38
|
};
|
|
59
39
|
|
|
60
|
-
|
|
40
|
+
const simpleApplicator = true;
|
|
41
|
+
|
|
42
|
+
export default { id, compile, interpret, simpleApplicator };
|
|
@@ -29,6 +29,7 @@ const interpret = (prefixItems, instance, context) => {
|
|
|
29
29
|
isValid = false;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
context.evaluatedItems?.add(index);
|
|
32
33
|
index++;
|
|
33
34
|
}
|
|
34
35
|
|
|
@@ -37,8 +38,4 @@ const interpret = (prefixItems, instance, context) => {
|
|
|
37
38
|
|
|
38
39
|
const simpleApplicator = true;
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
return interpret(items, instance, context) && new Set(items.map((_item, ndx) => ndx));
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export default { id, compile, interpret, simpleApplicator, collectEvaluatedItems };
|
|
41
|
+
export default { id, compile, interpret, simpleApplicator };
|