@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.
Files changed (37) hide show
  1. package/README.md +14 -20
  2. package/annotations/index.js +27 -7
  3. package/bundle/index.js +39 -227
  4. package/draft-04/additionalItems.js +13 -19
  5. package/draft-04/items.js +26 -14
  6. package/draft-2020-12/dynamicRef.js +20 -8
  7. package/lib/core.js +19 -4
  8. package/lib/evaluation-plugins/annotations.js +32 -0
  9. package/lib/evaluation-plugins/basic-output.js +34 -0
  10. package/lib/evaluation-plugins/detailed-output.js +36 -0
  11. package/lib/experimental.d.ts +18 -5
  12. package/lib/experimental.js +3 -0
  13. package/lib/instance.js +12 -3
  14. package/lib/keywords/additionalProperties.js +8 -22
  15. package/lib/keywords/allOf.js +1 -29
  16. package/lib/keywords/anyOf.js +1 -27
  17. package/lib/keywords/conditional.js +1 -27
  18. package/lib/keywords/contains.js +14 -18
  19. package/lib/keywords/dependentSchemas.js +1 -21
  20. package/lib/keywords/dynamicRef.js +19 -6
  21. package/lib/keywords/else.js +2 -19
  22. package/lib/keywords/if.js +1 -9
  23. package/lib/keywords/itemPattern.js +5 -9
  24. package/lib/keywords/items.js +5 -14
  25. package/lib/keywords/oneOf.js +1 -33
  26. package/lib/keywords/patternProperties.js +7 -25
  27. package/lib/keywords/prefixItems.js +2 -5
  28. package/lib/keywords/properties.js +6 -22
  29. package/lib/keywords/propertyDependencies.js +1 -20
  30. package/lib/keywords/propertyNames.js +1 -1
  31. package/lib/keywords/ref.js +1 -3
  32. package/lib/keywords/then.js +2 -19
  33. package/lib/keywords/unevaluatedItems.js +44 -20
  34. package/lib/keywords/unevaluatedProperties.js +40 -26
  35. package/lib/keywords/validation.js +31 -129
  36. package/lib/keywords.js +30 -30
  37. 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
+ };
@@ -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
- dynamicAnchors: Anchors;
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>;
@@ -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 = entry.map((property) => fromJs(property, uri, propertyPointer, propertyNode));
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
- const pointer = uriFragment(uri);
66
- return reduce((node, segment) => {
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 (!isDefinedProperty.test(propertyName) && !Validation.interpret(additionalProperties, property, context)) {
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
- const collectEvaluatedProperties = ([isDefinedProperty, additionalProperties], instance, context) => {
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 };
@@ -23,32 +23,4 @@ const interpret = (allOf, instance, ast, dynamicAnchors, quiet) => {
23
23
 
24
24
  const simpleApplicator = true;
25
25
 
26
- const collectEvaluatedProperties = (allOf, instance, context) => {
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 };
@@ -16,30 +16,4 @@ const interpret = (anyOf, instance, ast, dynamicAnchors, quiet) => {
16
16
  return matches.length > 0;
17
17
  };
18
18
 
19
- const collectEvaluatedProperties = (anyOf, instance, context) => {
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, collectEvaluatedProperties, collectEvaluatedItems };
38
+ export default { id, compile, interpret };
@@ -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
- const matches = Instance.typeOf(instance) !== "array" || pipe(
25
- Instance.iter(instance),
26
- filter((item) => Validation.interpret(contains, item, context)),
27
- reduce((matches) => matches + 1, 0)
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
- const collectEvaluatedItems = (keywordValue, instance, context) => {
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
- const collectEvaluatedProperties = (dependentSchemas, instance, context) => {
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 evaluate = (strategy, fragment, instance, context) => {
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 strategy(context.dynamicAnchors[fragment], instance, context);
20
+ return Validation.interpret(context.dynamicAnchors[fragment], instance, context);
20
21
  };
21
22
 
22
23
  const simpleApplicator = true;
23
24
 
24
- const interpret = (...args) => evaluate(Validation.interpret, ...args);
25
- const collectEvaluatedProperties = (...args) => evaluate(Validation.collectEvaluatedProperties, ...args);
26
- const collectEvaluatedItems = (...args) => evaluate(Validation.collectEvaluatedItems, ...args);
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, collectEvaluatedProperties, collectEvaluatedItems };
41
+ export default { id, compile, interpret, simpleApplicator, plugin };
@@ -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, errors: [], annotations: [], oututFormat: FLAG })
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
- const collectEvaluatedProperties = ([ifSchema, elseSchema], instance, context) => {
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 };
@@ -10,12 +10,4 @@ const interpret = (ifSchema, instance, context) => {
10
10
  return true;
11
11
  };
12
12
 
13
- const collectEvaluatedProperties = (ifSchema, instance, context) => {
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 evaluate = (strategy, nfa, instance, context) => {
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(strategy, state.transition, item, context);
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 = (strategy, transitions, instance, context) => {
79
+ const transition = (transitions, instance, context) => {
80
80
  for (const schema in transitions) {
81
- if (strategy(schema, instance, context)) {
81
+ if (Validation.interpret(schema, instance, context)) {
82
82
  return transitions[schema];
83
83
  }
84
84
  }
85
85
  };
86
86
 
87
- const interpret = (...args) => evaluate(Validation.interpret, ...args);
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 };
@@ -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
- const collectEvaluatedItems = (keywordValue, instance, context) => {
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 };
@@ -22,36 +22,4 @@ const interpret = (oneOf, instance, context) => {
22
22
  return validCount === 1;
23
23
  };
24
24
 
25
- const collectEvaluatedProperties = (oneOf, instance, context) => {
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(propertySchema, property, context)) {
49
- return false;
28
+ if (!Validation.interpret(schemaUri, propertyValue, context)) {
29
+ isValid = false;
50
30
  }
51
31
 
52
- evaluatedPropertyNames.add(propertyName);
32
+ context.evaluatedProperties?.add(propertyName);
53
33
  }
54
34
  }
55
35
  }
56
36
 
57
- return evaluatedPropertyNames;
37
+ return isValid;
58
38
  };
59
39
 
60
- export default { id, compile, interpret, simpleApplicator, collectEvaluatedProperties };
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
- const collectEvaluatedItems = (items, instance, context) => {
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 };