Skip to content

Commit f13a04d

Browse files
committed
Revert instance as a class
1 parent b0053e2 commit f13a04d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+468
-380
lines changed

annotations/index.d.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
import type { OutputFormat, OutputUnit } from "../lib/index.js";
22
import type { CompiledSchema } from "../lib/experimental.js";
33
import type { JsonNode } from "../lib/json-node.js";
4+
import type { Json } from "@hyperjump/json-pointer";
45

56

67
export const annotate: (
7-
(schemaUrl: string, value: unknown, outputFormat?: OutputFormat) => Promise<Annotator>
8+
(schemaUrl: string, value: Json, outputFormat?: OutputFormat) => Promise<JsonNode>
89
) & (
910
(schemaUrl: string) => Promise<Annotator>
1011
);
1112

13+
export type Annotator = (value: Json, outputFormat?: OutputFormat) => JsonNode;
14+
1215
export const interpret: (compiledSchema: CompiledSchema, value: JsonNode, outputFormat?: OutputFormat) => JsonNode;
1316

14-
export type Annotator = (value: unknown, outputFormat?: OutputFormat) => JsonNode;
17+
export const setAnnotation: (keywordUri: string, schemaLocation: string, value: string) => void;
18+
export const annotation: <A>(instance: JsonNode, keyword: string, dialectUri?: string) => A[];
19+
export const annotatedWith: (instance: JsonNode, keyword: string, dialectUri?: string) => JsonNode[];
1520

1621
export class ValidationError extends Error {
1722
public output: OutputUnit;

annotations/index.js

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1+
import * as JsonPointer from "@hyperjump/json-pointer";
12
import { ValidationError } from "./validation-error.js";
2-
import { getSchema, compile, interpret as validate, BASIC } from "../lib/experimental.js";
3-
import { jsonNodeFromJs } from "../lib/json-node.js";
3+
import { getSchema, compile, interpret as validate, BASIC, getKeywordId } from "../lib/experimental.js";
4+
import * as Instance from "../lib/instance.js";
45

56

67
export const annotate = async (schemaUri, json = undefined, outputFormat = undefined) => {
78
const schema = await getSchema(schemaUri);
89
const compiled = await compile(schema);
9-
const interpretAst = (json, outputFormat) => interpret(compiled, jsonNodeFromJs(json), outputFormat);
10+
const interpretAst = (json, outputFormat) => interpret(compiled, Instance.fromJs(json), outputFormat);
1011

1112
return json === undefined ? interpretAst : interpretAst(json, outputFormat);
1213
};
@@ -20,4 +21,44 @@ export const interpret = ({ ast, schemaUri }, instance, outputFormat = BASIC) =>
2021
return instance;
2122
};
2223

24+
export const setAnnotation = (node, keywordUri, schemaLocation, value) => {
25+
if (!(keywordUri in node.annotations)) {
26+
node.annotations[keywordUri] = {};
27+
}
28+
node.annotations[keywordUri][schemaLocation] = value;
29+
};
30+
31+
export const annotation = (node, keyword, dialect = "https://json-schema.org/validation") => {
32+
const keywordUri = getKeywordId(keyword, dialect);
33+
34+
let currentNode = node.root;
35+
const errors = Object.keys(node.root.errors);
36+
for (let segment of JsonPointer.pointerSegments(node.pointer)) {
37+
segment = segment === "-" && currentNode.typeOf() === "array" ? currentNode.length() : segment;
38+
currentNode = Instance.step(segment, currentNode);
39+
errors.push(...Object.keys(currentNode.errors));
40+
}
41+
42+
const annotations = [];
43+
for (const schemaLocation in node.annotations[keywordUri]) {
44+
if (!errors.some((error) => schemaLocation.startsWith(error))) {
45+
annotations.unshift(node.annotations[keywordUri][schemaLocation]);
46+
}
47+
}
48+
49+
return annotations;
50+
};
51+
52+
export const annotatedWith = (instance, keyword, dialectId = "https://json-schema.org/validation") => {
53+
const nodes = [];
54+
55+
for (const node of Instance.allNodes(instance)) {
56+
if (annotation(node, keyword, dialectId).length > 0) {
57+
nodes.push(node);
58+
}
59+
}
60+
61+
return nodes;
62+
};
63+
2364
export { ValidationError } from "./validation-error.js";

annotations/index.spec.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,19 @@ import path from "node:path";
33
import { fileURLToPath } from "node:url";
44
import { describe, it, expect, beforeEach, beforeAll, afterAll } from "vitest";
55
import { toAbsoluteIri } from "@hyperjump/uri";
6-
import { annotate } from "./index.js";
6+
import { annotate, annotation } from "./index.js";
77
import { registerSchema, unregisterSchema } from "../lib/index.js";
88
import "../stable/index.js";
99
import "../draft-2020-12/index.js";
1010
import "../draft-07/index.js";
1111
import "../draft-06/index.js";
1212
import "../draft-04/index.js";
13+
import * as Instance from "../lib/instance.js";
1314

1415
import type { SchemaObject } from "../lib/index.js";
1516
import type { Annotator } from "./index.js";
16-
import type { JsonNode } from "../lib/json-node.js";
17+
import type { JsonNode } from "../lib/instance.js";
18+
import type { Json } from "@hyperjump/json-pointer";
1719

1820

1921
type Suite = {
@@ -23,7 +25,7 @@ type Suite = {
2325
};
2426

2527
type Subject = {
26-
instance: unknown;
28+
instance: Json;
2729
assertions: Assertion[];
2830
};
2931

@@ -69,14 +71,14 @@ describe("Annotations", () => {
6971
let instance: JsonNode;
7072

7173
beforeEach(() => {
72-
instance = annotator(subject.instance);
74+
instance = annotator(subject.instance); // eslint-disable-line @typescript-eslint/no-unsafe-assignment
7375
});
7476

7577
subject.assertions.forEach((assertion) => {
7678
it(`${assertion.keyword} annotations at '${assertion.location}' should be ${JSON.stringify(assertion.expected)}`, () => {
7779
const dialect: string | undefined = suite.schema.$schema ? toAbsoluteIri(suite.schema.$schema as string) : undefined;
78-
const annotations = instance.get(assertion.location)
79-
?.annotation(assertion.keyword, dialect) ?? [];
80+
const subject = Instance.get(assertion.location, instance);
81+
const annotations = subject ? annotation(subject, assertion.keyword, dialect) : [];
8082
expect(annotations).to.eql(assertion.expected);
8183
});
8284
});

bundle/generate-snapshots.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import "../draft-2019-09/index.js";
77
import "../draft-07/index.js";
88
import "../draft-06/index.js";
99
import "../draft-04/index.js";
10-
import { jsonNodeFromJs } from "../lib/json-node.js";
10+
import * as Instance from "../lib/instance.js";
1111

1212

1313
const suite = testSuite("./bundle/tests");
@@ -25,7 +25,7 @@ const snapshotGenerator = async (version, dialect) => {
2525
loadSchemas(testCase, mainSchemaUri, dialect);
2626
const schema = await getSchema(mainSchemaUri);
2727
const compiledSchema = await compile(schema);
28-
const instance = jsonNodeFromJs(test.instance);
28+
const instance = Instance.fromJs(test.instance);
2929
interpret(compiledSchema, instance);
3030
const expectedOutput = toOutput(instance);
3131
unloadSchemas(testCase, mainSchemaUri);

bundle/test-suite.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { describe, it, expect, beforeAll, afterAll } from "vitest";
33
import { isCompatible, md5, loadSchemas, unloadSchemas, toOutput, testSuite } from "./test-utils.js";
44
import { registerSchema, unregisterSchema } from "../lib/index.js";
55
import { compile, getKeywordName, getSchema, interpret } from "../lib/experimental.js";
6-
import { jsonNodeFromJs } from "../lib/json-node.js";
6+
import * as Instance from "../lib/instance.js";
77
import "../stable/index.js";
88
import "../draft-2020-12/index.js";
99
import "../draft-2019-09/index.js";
@@ -58,7 +58,7 @@ const testRunner = (version: number, dialect: string) => {
5858
it(test.description, async () => {
5959
const schema = await getSchema(mainSchemaUri);
6060
const compiledSchema = await compile(schema);
61-
const instance = jsonNodeFromJs(test.instance);
61+
const instance = Instance.fromJs(test.instance);
6262
interpret(compiledSchema, instance);
6363
const output = toOutput(instance);
6464

bundle/test-utils.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { readFileSync, readdirSync } from "node:fs";
33
import { basename, relative } from "node:path";
44
import { getKeywordName } from "../lib/keywords.js";
55
import { registerSchema, unregisterSchema } from "../lib/index.js";
6-
import { allNodes } from "../lib/json-node.js";
6+
import * as Instance from "../lib/instance.js";
77

88

99
export const testSuite = (path) => {
@@ -105,8 +105,8 @@ export const unloadSchemas = (testCase, retrievalUri) => {
105105

106106
export const toOutput = (root) => {
107107
const output = {};
108-
for (const node of allNodes(root)) {
109-
output[node.uri()] = {
108+
for (const node of Instance.allNodes(root)) {
109+
output[Instance.uri(node)] = {
110110
errors: node.errors,
111111
annotations: node.annotations
112112
};

draft-04/additionalItems.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { pipe, drop, every } from "@hyperjump/pact";
22
import * as Browser from "@hyperjump/browser";
3+
import * as Instance from "../lib/instance.js";
34
import { getKeywordName, Validation } from "../lib/experimental.js";
45

56

@@ -14,12 +15,12 @@ const compile = async (schema, ast, parentSchema) => {
1415
};
1516

1617
const interpret = ([numberOfItems, additionalItems], instance, ast, dynamicAnchors, quiet) => {
17-
if (instance.typeOf() !== "array") {
18+
if (Instance.typeOf(instance) !== "array") {
1819
return true;
1920
}
2021

2122
return pipe(
22-
instance.iter(),
23+
Instance.iter(instance),
2324
drop(numberOfItems),
2425
every((item) => Validation.interpret(additionalItems, item, ast, dynamicAnchors, quiet))
2526
);
@@ -31,7 +32,7 @@ const collectEvaluatedItems = (keywordValue, instance, ast, dynamicAnchors) => {
3132
}
3233

3334
const evaluatedIndexes = new Set();
34-
for (let ndx = keywordValue[0]; ndx < instance.length(); ndx++) {
35+
for (let ndx = keywordValue[0]; ndx < Instance.length(instance); ndx++) {
3536
evaluatedIndexes.add(ndx);
3637
}
3738

draft-04/dependencies.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { pipe, asyncMap, asyncCollectArray } from "@hyperjump/pact";
22
import * as Browser from "@hyperjump/browser";
3+
import * as Instance from "../lib/instance.js";
34
import { Validation } from "../lib/experimental.js";
45

56

@@ -15,9 +16,9 @@ const compile = (schema, ast) => pipe(
1516
);
1617

1718
const interpret = (dependencies, instance, ast, dynamicAnchors, quiet) => {
18-
const value = instance.value();
19+
const value = Instance.value(instance);
1920

20-
return instance.typeOf() !== "object" || dependencies.every(([propertyName, dependency]) => {
21+
return Instance.typeOf(instance) !== "object" || dependencies.every(([propertyName, dependency]) => {
2122
if (!(propertyName in value)) {
2223
return true;
2324
}

draft-04/items.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { pipe, asyncMap, asyncCollectArray, every, zip, take, range, collectSet } from "@hyperjump/pact";
22
import * as Browser from "@hyperjump/browser";
3+
import * as Instance from "../lib/instance.js";
34
import { Validation } from "../lib/experimental.js";
45

56

@@ -18,24 +19,24 @@ const compile = (schema, ast) => {
1819
};
1920

2021
const interpret = (items, instance, ast, dynamicAnchors, quiet) => {
21-
if (instance.typeOf() !== "array") {
22+
if (Instance.typeOf(instance) !== "array") {
2223
return true;
2324
}
2425

2526
if (typeof items === "string") {
26-
return every((itemValue) => Validation.interpret(items, itemValue, ast, dynamicAnchors, quiet), instance.iter());
27+
return every((itemValue) => Validation.interpret(items, itemValue, ast, dynamicAnchors, quiet), Instance.iter(instance));
2728
} else {
2829
return pipe(
29-
zip(items, instance.iter()),
30-
take(instance.length()),
30+
zip(items, Instance.iter(instance)),
31+
take(Instance.length(instance)),
3132
every(([prefixItem, item]) => Validation.interpret(prefixItem, item, ast, dynamicAnchors, quiet))
3233
);
3334
}
3435
};
3536

3637
const collectEvaluatedItems = (items, instance, ast, dynamicAnchors) => {
3738
return interpret(items, instance, ast, dynamicAnchors, true) && (typeof items === "string"
38-
? collectSet(range(0, instance.length()))
39+
? collectSet(range(0, Instance.length(instance)))
3940
: collectSet(range(0, items.length)));
4041
};
4142

draft-04/json-schema-test-suite.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { describe, it, beforeAll, expect, afterAll } from "vitest";
33
import { toAbsoluteIri } from "@hyperjump/uri";
44
import { registerSchema, unregisterSchema, validate } from "./index.js";
55

6+
import type { Json } from "@hyperjump/json-pointer";
67
import type { JsonSchemaDraft04, SchemaObject, Validator } from "./index.js";
78

89

@@ -14,7 +15,7 @@ type Suite = {
1415

1516
type Test = {
1617
description: string;
17-
data: unknown;
18+
data: Json;
1819
valid: boolean;
1920
};
2021

draft-04/maximum.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as Browser from "@hyperjump/browser";
2+
import * as Instance from "../lib/instance.js";
23
import { getKeywordName } from "../lib/experimental.js";
34

45

@@ -13,11 +14,11 @@ const compile = async (schema, _ast, parentSchema) => {
1314
};
1415

1516
const interpret = ([maximum, isExclusive], instance) => {
16-
if (instance.typeOf() !== "number") {
17+
if (Instance.typeOf(instance) !== "number") {
1718
return true;
1819
}
1920

20-
const value = instance.value();
21+
const value = Instance.value(instance);
2122
return isExclusive ? value < maximum : value <= maximum;
2223
};
2324

draft-04/minimum.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as Browser from "@hyperjump/browser";
2+
import * as Instance from "../lib/instance.js";
23
import { getKeywordName } from "../lib/experimental.js";
34

45

@@ -13,11 +14,11 @@ const compile = async (schema, _ast, parentSchema) => {
1314
};
1415

1516
const interpret = ([minimum, isExclusive], instance) => {
16-
if (instance.typeOf() !== "number") {
17+
if (Instance.typeOf(instance) !== "number") {
1718
return true;
1819
}
1920

20-
const value = instance.value();
21+
const value = Instance.value(instance);
2122
return isExclusive ? value > minimum : value >= minimum;
2223
};
2324

draft-06/contains.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { some } from "@hyperjump/pact";
2+
import * as Instance from "../lib/instance.js";
23
import { Validation } from "../lib/experimental.js";
34

45

@@ -7,7 +8,7 @@ const id = "https://json-schema.org/keyword/draft-06/contains";
78
const compile = (schema, ast) => Validation.compile(schema, ast);
89

910
const interpret = (contains, instance, ast, dynamicAnchors, quiet) => {
10-
return instance.typeOf() !== "array" || some((item) => Validation.interpret(contains, item, ast, dynamicAnchors, quiet), instance.iter());
11+
return Instance.typeOf(instance) !== "array" || some((item) => Validation.interpret(contains, item, ast, dynamicAnchors, quiet), Instance.iter(instance));
1112
};
1213

1314
export default { id, compile, interpret };

draft-06/json-schema-test-suite.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { toAbsoluteIri } from "@hyperjump/uri";
44
import { registerSchema, unregisterSchema, validate } from "./index.js";
55

66
import type { JsonSchemaDraft06, SchemaObject, Validator } from "./index.js";
7+
import type { Json } from "@hyperjump/json-pointer";
78

89

910
type Suite = {
@@ -14,7 +15,7 @@ type Suite = {
1415

1516
type Test = {
1617
description: string;
17-
data: unknown;
18+
data: Json;
1819
valid: boolean;
1920
};
2021

draft-07/json-schema-test-suite.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { describe, it, expect, beforeAll, afterAll } from "vitest";
33
import { toAbsoluteIri } from "@hyperjump/uri";
44
import { registerSchema, unregisterSchema, validate } from "./index.js";
55

6+
import type { Json } from "@hyperjump/json-pointer";
67
import type { JsonSchemaDraft07, SchemaObject, Validator } from "./index.js";
78

89

@@ -14,7 +15,7 @@ type Suite = {
1415

1516
type Test = {
1617
description: string;
17-
data: unknown;
18+
data: Json;
1819
valid: boolean;
1920
};
2021

0 commit comments

Comments
 (0)