Skip to content

Commit 6aa71be

Browse files
committed
Improve setting annotation in keyword handler
1 parent 5bcd959 commit 6aa71be

23 files changed

+73
-199
lines changed

Diff for: README.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,10 @@ These are available from the `@hyperjump/json-schema/experimental` export.
547547
* collectExternalIds?: (visited: Set\<string>, parentSchema: Browser, schema: Browser) => Set\<string>
548548
If the keyword is an applicator, it will need to implement this
549549
function to work properly with the [bundle](#bundling) feature.
550+
* annotation?: (compiledKeywordValue: any) => any
551+
552+
If the keyword is an annotation, it will need to implement this
553+
function to return the annotation.
550554
551555
* **ValidationContext**: object
552556
* ast: AST
@@ -696,7 +700,7 @@ Schema.
696700
697701
### Usage
698702
An annotated JSON document is represented as a
699-
(JsonNode)[#/instance-api-experimental] AST. You can use this AST to traverse
703+
(JsonNode)[#instance-api-experimental] AST. You can use this AST to traverse
700704
the data structure and get annotations for the values it represents.
701705
702706
```javascript

Diff for: annotations/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export const annotate = async (schemaUri, json = undefined, outputFormat = undef
1616
export const interpret = ({ ast, schemaUri }, instance, outputFormat = BASIC) => {
1717
const errors = [];
1818
const annotations = [];
19-
const context = { ast, schemaUri, dynamicAnchors: {}, errors, annotations, outputFormat };
19+
const context = { ast, dynamicAnchors: {}, errors, annotations, outputFormat };
2020
const valid = Validation.interpret(schemaUri, instance, context);
2121

2222
if (!valid) {

Diff for: bundle/generate-snapshots.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const snapshotGenerator = async (version, dialect) => {
3030
const instance = Instance.fromJs(test.instance);
3131
const errors = [];
3232
const annotations = [];
33-
const context = { ast, schemaUri, dynamicAnchors: {}, errors, annotations, outputFormat: BASIC };
33+
const context = { ast, dynamicAnchors: {}, errors, annotations, outputFormat: BASIC };
3434
const valid = Validation.interpret(schemaUri, instance, context);
3535

3636
const expectedOutput = { valid, errors, annotations };

Diff for: bundle/test-suite.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ const testRunner = (version: number, dialect: string) => {
6060
const instance = Instance.fromJs(test.instance);
6161
const errors: OutputUnit[] = [];
6262
const annotations: OutputUnit[] = [];
63-
const context = { ast, schemaUri, dynamicAnchors: {}, errors, annotations, outputFormat: BASIC };
63+
const context = { ast, dynamicAnchors: {}, errors, annotations, outputFormat: BASIC };
6464
const valid = Validation.interpret(schemaUri, instance, context);
6565

6666
const output = { valid, errors, annotations };

Diff for: lib/core.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export const compile = async (schema) => {
3232

3333
export const interpret = curry(({ ast, schemaUri }, instance, outputFormat = FLAG) => {
3434
const errors = [];
35-
const context = { ast, schemaUri, dynamicAnchors: {}, errors, annotations: [], outputFormat };
35+
const context = { ast, dynamicAnchors: {}, errors, annotations: [], outputFormat };
3636
const valid = Validation.interpret(schemaUri, instance, context);
3737
return outputFormat === FLAG || valid ? { valid } : { valid, errors };
3838
});

Diff for: lib/experimental.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@ export type Keyword<A> = {
7373
collectEvaluatedProperties?: (compiledKeywordValue: A, instance: JsonNode, context: ValidationContext, isTop?: boolean) => Set<string> | false;
7474
collectEvaluatedItems?: (compiledKeywordValue: A, instance: JsonNode, context: ValidationContext, isTop?: boolean) => Set<number> | false;
7575
collectExternalIds?: (visited: Set<string>, parentSchema: Browser<SchemaDocument>, schema: Browser<SchemaDocument>) => Promise<Set<string>>;
76+
annotation?: <B>(compiledKeywordValue: A) => B;
7677
};
7778

7879
export type ValidationContext = {
7980
ast: AST;
80-
schemaUri: string;
8181
dynamicAnchors: Anchors;
8282
errors: OutputUnit[];
8383
annotations: OutputUnit[];

Diff for: lib/keywords/contentEncoding.js

+3-12
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
import * as Browser from "@hyperjump/browser";
2-
import * as Instance from "../../annotations/annotated-instance.js";
32

43

54
const id = "https://json-schema.org/keyword/contentEncoding";
65

76
const compile = (schema) => Browser.value(schema);
7+
const interpret = () => true;
8+
const annotation = (contentEncoding) => contentEncoding;
89

9-
const interpret = (contentEncoding, instance, { annotations, schemaUri }) => {
10-
annotations.push({
11-
keyword: id,
12-
absoluteKeywordLocation: schemaUri,
13-
instanceLocation: Instance.uri(instance),
14-
annotation: contentEncoding
15-
});
16-
return true;
17-
};
18-
19-
export default { id, compile, interpret };
10+
export default { id, compile, interpret, annotation };

Diff for: lib/keywords/contentMediaType.js

+3-12
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
import * as Browser from "@hyperjump/browser";
2-
import * as Instance from "../../annotations/annotated-instance.js";
32

43

54
const id = "https://json-schema.org/keyword/contentMediaType";
65

76
const compile = (schema) => Browser.value(schema);
7+
const interpret = () => true;
8+
const annotation = (contentMediaType) => contentMediaType;
89

9-
const interpret = (contentMediaType, instance, { annotations, schemaUri }) => {
10-
annotations.push({
11-
keyword: id,
12-
absoluteKeywordLocation: schemaUri,
13-
instanceLocation: Instance.uri(instance),
14-
annotation: contentMediaType
15-
});
16-
return true;
17-
};
18-
19-
export default { id, compile, interpret };
10+
export default { id, compile, interpret, annotation };

Diff for: lib/keywords/contentSchema.js

+3-12
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
import { canonicalUri } from "../schema.js";
2-
import * as Instance from "../../annotations/annotated-instance.js";
32

43

54
const id = "https://json-schema.org/keyword/contentSchema";
65

76
const compile = (contentSchema) => canonicalUri(contentSchema);
7+
const interpret = () => true;
8+
const annotation = (contentSchema) => contentSchema;
89

9-
const interpret = (contentSchema, instance, { annotations, schemaUri }) => {
10-
annotations.push({
11-
keyword: id,
12-
absoluteKeywordLocation: schemaUri,
13-
instanceLocation: Instance.uri(instance),
14-
annotation: contentSchema
15-
});
16-
return true;
17-
};
18-
19-
export default { id, compile, interpret };
10+
export default { id, compile, interpret, annotation };

Diff for: lib/keywords/default.js

+3-12
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
import * as Browser from "@hyperjump/browser";
2-
import * as Instance from "../../annotations/annotated-instance.js";
32

43

54
const id = "https://json-schema.org/keyword/default";
65

76
const compile = (schema) => Browser.value(schema);
7+
const interpret = () => true;
8+
const annotation = (value) => value;
89

9-
const interpret = (value, instance, { annotations, schemaUri }) => {
10-
annotations.push({
11-
keyword: id,
12-
absoluteKeywordLocation: schemaUri,
13-
instanceLocation: Instance.uri(instance),
14-
annotation: value
15-
});
16-
return true;
17-
};
18-
19-
export default { id, compile, interpret };
10+
export default { id, compile, interpret, annotation };

Diff for: lib/keywords/deprecated.js

+3-12
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
import * as Browser from "@hyperjump/browser";
2-
import * as Instance from "../../annotations/annotated-instance.js";
32

43

54
const id = "https://json-schema.org/keyword/deprecated";
65

76
const compile = (schema) => Browser.value(schema);
7+
const interpret = () => true;
8+
const annotation = (deprecated) => deprecated;
89

9-
const interpret = (deprecated, instance, { annotations, schemaUri }) => {
10-
annotations.push({
11-
keyword: id,
12-
absoluteKeywordLocation: schemaUri,
13-
instanceLocation: Instance.uri(instance),
14-
annotation: deprecated
15-
});
16-
return true;
17-
};
18-
19-
export default { id, compile, interpret };
10+
export default { id, compile, interpret, annotation };

Diff for: lib/keywords/description.js

+3-12
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
import * as Browser from "@hyperjump/browser";
2-
import * as Instance from "../../annotations/annotated-instance.js";
32

43

54
const id = "https://json-schema.org/keyword/description";
65

76
const compile = (schema) => Browser.value(schema);
7+
const interpret = () => true;
8+
const annotation = (description) => description;
89

9-
const interpret = (description, instance, { annotations, schemaUri }) => {
10-
annotations.push({
11-
keyword: id,
12-
absoluteKeywordLocation: schemaUri,
13-
instanceLocation: Instance.uri(instance),
14-
annotation: description
15-
});
16-
return true;
17-
};
18-
19-
export default { id, compile, interpret };
10+
export default { id, compile, interpret, annotation };

Diff for: lib/keywords/examples.js

+3-12
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
import * as Browser from "@hyperjump/browser";
2-
import * as Instance from "../../annotations/annotated-instance.js";
32

43

54
const id = "https://json-schema.org/keyword/examples";
65

76
const compile = (schema) => Browser.value(schema);
7+
const interpret = () => true;
8+
const annotation = (examples) => examples;
89

9-
const interpret = (examples, instance, { annotations, schemaUri }) => {
10-
annotations.push({
11-
keyword: id,
12-
absoluteKeywordLocation: schemaUri,
13-
instanceLocation: Instance.uri(instance),
14-
annotation: examples
15-
});
16-
return true;
17-
};
18-
19-
export default { id, compile, interpret };
10+
export default { id, compile, interpret, annotation };

Diff for: lib/keywords/format.js

+3-12
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
import * as Browser from "@hyperjump/browser";
2-
import * as Instance from "../../annotations/annotated-instance.js";
32

43

54
const id = "https://json-schema.org/keyword/format";
65

76
const compile = (schema) => Browser.value(schema);
7+
const interpret = () => true;
8+
const annotation = (format) => format;
89

9-
const interpret = (format, instance, { annotations, schemaUri }) => {
10-
annotations.push({
11-
keyword: id,
12-
absoluteKeywordLocation: schemaUri,
13-
instanceLocation: Instance.uri(instance),
14-
annotation: format
15-
});
16-
return true;
17-
};
18-
19-
export default { id, compile, interpret };
10+
export default { id, compile, interpret, annotation };

Diff for: lib/keywords/readOnly.js

+3-12
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
import * as Browser from "@hyperjump/browser";
2-
import * as Instance from "../../annotations/annotated-instance.js";
32

43

54
const id = "https://json-schema.org/keyword/readOnly";
65

76
const compile = (schema) => Browser.value(schema);
7+
const interpret = () => true;
8+
const annotation = (readOnly) => readOnly;
89

9-
const interpret = (readOnly, instance, { annotations, schemaUri }) => {
10-
annotations.push({
11-
keyword: id,
12-
absoluteKeywordLocation: schemaUri,
13-
instanceLocation: Instance.uri(instance),
14-
annotation: readOnly
15-
});
16-
return true;
17-
};
18-
19-
export default { id, compile, interpret };
10+
export default { id, compile, interpret, annotation };

Diff for: lib/keywords/title.js

+3-12
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
import * as Browser from "@hyperjump/browser";
2-
import * as Instance from "../../annotations/annotated-instance.js";
32

43

54
const id = "https://json-schema.org/keyword/title";
65

76
const compile = (schema) => Browser.value(schema);
7+
const interpret = () => true;
8+
const annotation = (title) => title;
89

9-
const interpret = (title, instance, { annotations, schemaUri }) => {
10-
annotations.push({
11-
keyword: id,
12-
absoluteKeywordLocation: schemaUri,
13-
instanceLocation: Instance.uri(instance),
14-
annotation: title
15-
});
16-
return true;
17-
};
18-
19-
export default { id, compile, interpret };
10+
export default { id, compile, interpret, annotation };

Diff for: lib/keywords/unknown.js

+3-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import * as Browser from "@hyperjump/browser";
2-
import * as Instance from "../../annotations/annotated-instance.js";
32
import { pointerSegments } from "@hyperjump/json-pointer";
43

54

@@ -10,15 +9,7 @@ const compile = (schema) => {
109
return [keywordName, Browser.value(schema)];
1110
};
1211

13-
const interpret = ([keywordName, value], instance, { annotations, schemaUri }) => {
14-
const keywordId = `${id}#${keywordName}`;
15-
annotations.push({
16-
keyword: keywordId,
17-
absoluteKeywordLocation: schemaUri,
18-
instanceLocation: Instance.uri(instance),
19-
annotation: value
20-
});
21-
return true;
22-
};
12+
const interpret = () => true;
13+
const annotation = ([, value]) => value;
2314

24-
export default { id, compile, interpret };
15+
export default { id, compile, interpret, annotation };

Diff for: lib/keywords/validation.js

+15-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ const interpret = (url, instance, { ast, dynamicAnchors, errors, annotations, ou
6464

6565
let isSchemaValid = true;
6666
for (const [keywordId, schemaUri, keywordValue] of ast[url]) {
67-
const context = { ast, dynamicAnchors, schemaUri, errors: [], annotations: [], outputFormat };
67+
const context = { ast, dynamicAnchors, errors: [], annotations: [], outputFormat };
6868
const keywordHandler = getKeyword(keywordId);
6969
if (!keywordHandler.interpret(keywordValue, instance, context)) {
7070
isSchemaValid = false;
@@ -88,6 +88,20 @@ const interpret = (url, instance, { ast, dynamicAnchors, errors, annotations, ou
8888
errors.push(...context.errors);
8989
}
9090
} else {
91+
if (outputFormat === FLAG) {
92+
continue;
93+
}
94+
95+
if (keywordHandler.annotation) {
96+
const outputUnit = {
97+
keyword: keywordId,
98+
absoluteKeywordLocation: schemaUri,
99+
instanceLocation: Instance.uri(instance),
100+
annotation: keywordHandler.annotation(keywordValue)
101+
};
102+
schemaAnnotations.push(outputUnit);
103+
}
104+
91105
schemaAnnotations.push(...context.annotations);
92106
}
93107
}

Diff for: lib/keywords/writeOnly.js

+3-12
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
import * as Browser from "@hyperjump/browser";
2-
import * as Instance from "../../annotations/annotated-instance.js";
32

43

54
const id = "https://json-schema.org/keyword/writeOnly";
65

76
const compile = (schema) => Browser.value(schema);
7+
const interpret = () => true;
8+
const annotation = (writeOnly) => writeOnly;
89

9-
const interpret = (writeOnly, instance, { annotations, schemaUri }) => {
10-
annotations.push({
11-
keyword: id,
12-
absoluteKeywordLocation: schemaUri,
13-
instanceLocation: Instance.uri(instance),
14-
annotation: writeOnly
15-
});
16-
return true;
17-
};
18-
19-
export default { id, compile, interpret };
10+
export default { id, compile, interpret, annotation };

Diff for: openapi-3-0/discriminator.js

+3-12
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
import * as Browser from "@hyperjump/browser";
2-
import * as Instance from "../annotations/annotated-instance.js";
32

43

54
const id = "https://spec.openapis.org/oas/3.0/keyword/discriminator";
65

76
const compile = (schema) => Browser.value(schema);
7+
const interpret = () => true;
8+
const annotation = (discriminator) => discriminator;
89

9-
const interpret = (discriminator, instance, { annotations, schemaUri }) => {
10-
annotations.push({
11-
keyword: id,
12-
absoluteKeywordLocation: schemaUri,
13-
instanceLocation: Instance.uri(instance),
14-
annotation: discriminator
15-
});
16-
return true;
17-
};
18-
19-
export default { id, compile, interpret };
10+
export default { id, compile, interpret, annotation };

0 commit comments

Comments
 (0)