@hyperjump/json-schema 1.6.7 → 1.7.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 +247 -255
- package/annotations/annotated-instance.js +3 -3
- package/annotations/index.d.ts +7 -1
- package/annotations/index.js +3 -3
- package/bundle/index.d.ts +1 -5
- package/bundle/index.js +112 -156
- package/draft-04/additionalItems.js +6 -7
- package/draft-04/dependencies.js +5 -5
- package/draft-04/index.js +2 -2
- package/draft-04/items.js +5 -5
- package/draft-04/maximum.js +8 -8
- package/draft-04/minimum.js +8 -8
- package/draft-06/contains.js +2 -2
- package/draft-06/index.js +3 -2
- package/draft-07/index.js +3 -2
- package/draft-2019-09/index.js +9 -11
- package/draft-2020-12/dynamicRef.js +5 -5
- package/draft-2020-12/index.js +11 -13
- package/lib/common.d.ts +1 -1
- package/lib/common.js +44 -60
- package/lib/configuration.js +0 -6
- package/lib/core.js +32 -30
- package/lib/experimental.d.ts +75 -5
- package/lib/experimental.js +2 -2
- package/lib/index.d.ts +43 -11
- package/lib/index.js +11 -11
- package/lib/instance.d.ts +1 -17
- package/lib/instance.js +3 -3
- package/lib/keywords/additionalProperties.js +12 -13
- package/lib/keywords/allOf.js +3 -3
- package/lib/keywords/anyOf.js +3 -3
- package/lib/keywords/conditional.js +6 -7
- package/lib/keywords/const.js +2 -2
- package/lib/keywords/contains.js +14 -35
- package/lib/keywords/contentSchema.js +1 -1
- package/lib/keywords/definitions.js +2 -2
- package/lib/keywords/dependentRequired.js +4 -4
- package/lib/keywords/dependentSchemas.js +5 -5
- package/lib/keywords/dynamicRef.js +10 -5
- package/lib/keywords/else.js +5 -6
- package/lib/keywords/enum.js +4 -4
- package/lib/keywords/exclusiveMaximum.js +3 -3
- package/lib/keywords/exclusiveMinimum.js +3 -3
- package/lib/keywords/if.js +1 -1
- package/lib/keywords/itemPattern.js +17 -14
- package/lib/keywords/items.js +6 -7
- package/lib/keywords/maxItems.js +3 -3
- package/lib/keywords/maxLength.js +3 -3
- package/lib/keywords/maxProperties.js +3 -3
- package/lib/keywords/maximum.js +3 -3
- package/lib/keywords/meta-data.js +1 -1
- package/lib/keywords/minItems.js +3 -3
- package/lib/keywords/minLength.js +3 -3
- package/lib/keywords/minProperties.js +3 -3
- package/lib/keywords/minimum.js +3 -3
- package/lib/keywords/multipleOf.js +3 -3
- package/lib/keywords/not.js +1 -1
- package/lib/keywords/oneOf.js +3 -3
- package/lib/keywords/pattern.js +3 -3
- package/lib/keywords/patternProperties.js +5 -5
- package/lib/keywords/prefixItems.js +5 -5
- package/lib/keywords/properties.js +5 -5
- package/lib/keywords/propertyDependencies.js +6 -7
- package/lib/keywords/propertyNames.js +2 -2
- package/lib/keywords/ref.js +2 -7
- package/lib/keywords/requireAllExcept.js +8 -9
- package/lib/keywords/required.js +3 -3
- package/lib/keywords/then.js +5 -5
- package/lib/keywords/type.js +9 -3
- package/lib/keywords/unevaluatedItems.js +4 -4
- package/lib/keywords/unevaluatedProperties.js +4 -5
- package/lib/keywords/uniqueItems.js +3 -3
- package/lib/keywords/validation.js +11 -23
- package/lib/keywords.js +27 -14
- package/lib/openapi.js +19 -6
- package/lib/schema.js +236 -227
- package/openapi-3-0/index.js +5 -5
- package/openapi-3-0/type.js +13 -7
- package/openapi-3-1/index.js +22 -21
- package/openapi-3-1/{schema-base/2022-10-07.js → schema-base.js} +12 -2
- package/openapi-3-1/schema-draft-04.js +33 -0
- package/openapi-3-1/schema-draft-06.js +33 -0
- package/openapi-3-1/schema-draft-07.js +33 -0
- package/openapi-3-1/schema-draft-2019-09.js +33 -0
- package/openapi-3-1/schema-draft-2020-12.js +33 -0
- package/package.json +11 -11
- package/stable/index.js +10 -10
- package/annotations/validation-error.d.ts +0 -8
- package/draft-2019-09/contains.js +0 -44
- package/lib/configuration.d.ts +0 -9
- package/lib/context-uri.browser.js +0 -1
- package/lib/context-uri.js +0 -4
- package/lib/core.d.ts +0 -48
- package/lib/fetch.browser.js +0 -1
- package/lib/fetch.js +0 -20
- package/lib/invalid-schema-error.d.ts +0 -8
- package/lib/keywords.d.ts +0 -19
- package/lib/media-types.d.ts +0 -11
- package/lib/media-types.js +0 -48
- package/lib/reference.d.ts +0 -11
- package/lib/reference.js +0 -11
- package/lib/schema.d.ts +0 -60
- /package/openapi-3-0/{schema/2021-09-28.js → schema.js} +0 -0
- /package/openapi-3-1/{schema/2022-10-07.js → schema.js} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { toAbsoluteIri } from "@hyperjump/uri";
|
|
2
2
|
import { nil as nilInstance, get } from "../lib/instance.js";
|
|
3
3
|
import { getKeywordId } from "../lib/keywords.js";
|
|
4
4
|
|
|
@@ -8,13 +8,13 @@ const defaultDialectId = "https://json-schema.org/validation";
|
|
|
8
8
|
export const nil = { ...nilInstance, annotations: {} };
|
|
9
9
|
export const cons = (instance, id = undefined) => ({
|
|
10
10
|
...nil,
|
|
11
|
-
id: id ?
|
|
11
|
+
id: id ? toAbsoluteIri(id) : "",
|
|
12
12
|
instance,
|
|
13
13
|
value: instance
|
|
14
14
|
});
|
|
15
15
|
|
|
16
16
|
export const annotation = (instance, keyword, dialectId = defaultDialectId) => {
|
|
17
|
-
const keywordId = getKeywordId(
|
|
17
|
+
const keywordId = getKeywordId(keyword, dialectId);
|
|
18
18
|
return instance.annotations[instance.pointer]?.[keywordId] || [];
|
|
19
19
|
};
|
|
20
20
|
|
package/annotations/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { OutputFormat } from "../lib/
|
|
1
|
+
import type { OutputFormat, OutputUnit } from "../lib/index.js";
|
|
2
2
|
import type { AnnotatedJsonDocument } from "./annotated-instance.js";
|
|
3
3
|
|
|
4
4
|
|
|
@@ -9,3 +9,9 @@ export const annotate: (
|
|
|
9
9
|
);
|
|
10
10
|
|
|
11
11
|
export type Annotator = (value: unknown, outputFormat?: OutputFormat) => AnnotatedJsonDocument;
|
|
12
|
+
|
|
13
|
+
export class ValidationError extends Error {
|
|
14
|
+
public output: OutputUnit;
|
|
15
|
+
|
|
16
|
+
public constructor(output: OutputUnit);
|
|
17
|
+
}
|
package/annotations/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { subscribe, unsubscribe } from "../lib/pubsub.js";
|
|
2
|
-
import { compile, interpret as validate, BASIC } from "../lib/core.js";
|
|
3
|
-
import { getKeyword } from "../lib/keywords.js";
|
|
4
2
|
import * as Instance from "./annotated-instance.js";
|
|
5
3
|
import { ValidationError } from "./validation-error.js";
|
|
4
|
+
import { getSchema, getKeyword, compile, interpret as validate, BASIC } from "../lib/experimental.js";
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
export const annotate = async (schemaUri, json = undefined, outputFormat = undefined) => {
|
|
9
8
|
loadKeywordSupport();
|
|
10
|
-
const
|
|
9
|
+
const schema = await getSchema(schemaUri);
|
|
10
|
+
const compiled = await compile(schema);
|
|
11
11
|
const interpretAst = (json, outputFormat) => interpret(compiled, Instance.cons(json), outputFormat);
|
|
12
12
|
|
|
13
13
|
return json === undefined ? interpretAst : interpretAst(json, outputFormat);
|
package/bundle/index.d.ts
CHANGED
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
import type { SchemaObject } from "../lib/
|
|
1
|
+
import type { SchemaObject } from "../lib/index.js";
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
export const bundle: <A = SchemaObject>(uri: string, options?: BundleOptions) => Promise<A>;
|
|
5
|
-
export const FULL: "full";
|
|
6
|
-
export const FLAT: "flat";
|
|
7
5
|
export const URI: "uri";
|
|
8
6
|
export const UUID: "uuid";
|
|
9
7
|
|
|
10
8
|
export type BundleOptions = {
|
|
11
9
|
alwaysIncludeDialect?: boolean;
|
|
12
|
-
bundleMode?: BundleMode;
|
|
13
10
|
definitionNamingStrategy?: DefinitionNamingStrategy;
|
|
14
11
|
externalSchemas?: string[];
|
|
15
12
|
};
|
|
16
13
|
|
|
17
|
-
export type BundleMode = "full" | "flat";
|
|
18
14
|
export type DefinitionNamingStrategy = "uri" | "uuid";
|
package/bundle/index.js
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
|
+
import curry from "just-curry-it";
|
|
1
2
|
import { v4 as uuid } from "uuid";
|
|
3
|
+
import * as Browser from "@hyperjump/browser";
|
|
2
4
|
import * as JsonPointer from "@hyperjump/json-pointer";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
import { asyncCollectSet, asyncFilter, asyncFlatten, asyncMap, pipe } from "@hyperjump/pact";
|
|
6
|
+
import { resolveUri } from "@hyperjump/uri";
|
|
7
|
+
import {
|
|
8
|
+
Validation,
|
|
9
|
+
canonicalUri, getSchema, toSchema,
|
|
10
|
+
getKeywordName, getKeyword, getKeywordByName
|
|
11
|
+
} from "../lib/experimental.js";
|
|
8
12
|
|
|
9
13
|
|
|
10
|
-
export const FULL = "full", FLAT = "flat";
|
|
11
14
|
export const URI = "uri", UUID = "uuid";
|
|
12
15
|
|
|
13
16
|
const defaultOptions = {
|
|
14
17
|
alwaysIncludeDialect: false,
|
|
15
|
-
bundleMode: FLAT,
|
|
16
18
|
definitionNamingStrategy: URI,
|
|
17
19
|
externalSchemas: []
|
|
18
20
|
};
|
|
@@ -21,30 +23,35 @@ export const bundle = async (url, options = {}) => {
|
|
|
21
23
|
loadKeywordSupport();
|
|
22
24
|
const fullOptions = { ...defaultOptions, ...options };
|
|
23
25
|
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
+
const mainSchema = await getSchema(url);
|
|
27
|
+
const contextUri = mainSchema.document.baseUri;
|
|
28
|
+
const contextDialectId = mainSchema.document.dialectId;
|
|
29
|
+
const bundled = toSchema(mainSchema);
|
|
26
30
|
|
|
27
|
-
const
|
|
28
|
-
includeEmbedded: fullOptions.bundleMode === FULL
|
|
29
|
-
});
|
|
31
|
+
const externalIds = await Validation.collectExternalIds(new Set(), mainSchema, mainSchema);
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
// Bundle
|
|
34
|
+
const bundlingLocation = "/" + getKeywordName(contextDialectId, "https://json-schema.org/keyword/definitions");
|
|
32
35
|
if (JsonPointer.get(bundlingLocation, bundled) === undefined && externalIds.size > 0) {
|
|
33
36
|
JsonPointer.assign(bundlingLocation, bundled, {});
|
|
34
37
|
}
|
|
35
38
|
|
|
36
|
-
for (const uri of externalIds
|
|
37
|
-
const externalSchema = await
|
|
38
|
-
const embeddedSchema =
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
for (const uri of externalIds) {
|
|
40
|
+
const externalSchema = await getSchema(uri);
|
|
41
|
+
const embeddedSchema = toSchema(externalSchema, {
|
|
42
|
+
selfIdentify: true,
|
|
43
|
+
contextUri: contextUri,
|
|
44
|
+
includeDialect: fullOptions.alwaysIncludeDialect ? "always" : "auto",
|
|
45
|
+
contextDialectId: contextDialectId
|
|
42
46
|
});
|
|
43
47
|
let id;
|
|
44
48
|
if (fullOptions.definitionNamingStrategy === URI) {
|
|
45
|
-
const idToken = getKeywordName(externalSchema.dialectId, "https://json-schema.org/keyword/id")
|
|
46
|
-
|| getKeywordName(externalSchema.dialectId, "https://json-schema.org/keyword/draft-04/id");
|
|
49
|
+
const idToken = getKeywordName(externalSchema.document.dialectId, "https://json-schema.org/keyword/id")
|
|
50
|
+
|| getKeywordName(externalSchema.document.dialectId, "https://json-schema.org/keyword/draft-04/id");
|
|
47
51
|
id = embeddedSchema[idToken];
|
|
52
|
+
if (id in JsonPointer.get(bundlingLocation, bundled)) {
|
|
53
|
+
id = resolveUri(id, contextUri);
|
|
54
|
+
}
|
|
48
55
|
} else if (fullOptions.definitionNamingStrategy === UUID) {
|
|
49
56
|
id = uuid();
|
|
50
57
|
} else {
|
|
@@ -57,74 +64,76 @@ export const bundle = async (url, options = {}) => {
|
|
|
57
64
|
return bundled;
|
|
58
65
|
};
|
|
59
66
|
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const externalIds = new Set([...subSchemaUris]
|
|
65
|
-
.map(toAbsoluteUri)
|
|
66
|
-
.filter((uri) => !options.externalSchemas.includes(uri)));
|
|
67
|
-
externalIds.delete(toAbsoluteUri(schemaUri));
|
|
68
|
-
|
|
69
|
-
return externalIds;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
Validation.collectExternalIds = (schemaUri, externalIds, ast, dynamicAnchors) => {
|
|
73
|
-
if (externalIds.has(schemaUri) || typeof ast[schemaUri] === "boolean") {
|
|
74
|
-
return;
|
|
67
|
+
Validation.collectExternalIds = curry(async (visited, parentSchema, schema) => {
|
|
68
|
+
const uri = canonicalUri(schema);
|
|
69
|
+
if (visited.has(uri) || Browser.typeOf(schema) === "boolean") {
|
|
70
|
+
return new Set();
|
|
75
71
|
}
|
|
76
|
-
externalIds.add(schemaUri);
|
|
77
|
-
|
|
78
|
-
const id = toAbsoluteUri(schemaUri);
|
|
79
|
-
for (const [keywordId, , keywordValue] of ast[schemaUri]) {
|
|
80
|
-
const keyword = getKeyword(keywordId);
|
|
81
72
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
73
|
+
visited.add(uri);
|
|
74
|
+
|
|
75
|
+
const externalIds = await pipe(
|
|
76
|
+
Browser.entries(schema),
|
|
77
|
+
asyncMap(async ([keyword, keywordSchema]) => {
|
|
78
|
+
const keywordHandler = getKeywordByName(keyword, schema.document.dialectId);
|
|
79
|
+
|
|
80
|
+
return "collectExternalIds" in keywordHandler
|
|
81
|
+
? await keywordHandler.collectExternalIds(visited, schema, keywordSchema)
|
|
82
|
+
: new Set();
|
|
83
|
+
}),
|
|
84
|
+
asyncFlatten,
|
|
85
|
+
asyncCollectSet
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
if (parentSchema.document.baseUri !== schema.document.baseUri
|
|
89
|
+
&& (!(schema.document.baseUri in parentSchema.document.embedded) || schema.document.baseUri in parentSchema._cache)
|
|
90
|
+
) {
|
|
91
|
+
externalIds.add(schema.document.baseUri);
|
|
87
92
|
}
|
|
88
|
-
|
|
93
|
+
|
|
94
|
+
return externalIds;
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const collectExternalIdsFromArrayOfSchemas = (visited, parentSchema, schema) => pipe(
|
|
98
|
+
Browser.iter(schema),
|
|
99
|
+
asyncMap(Validation.collectExternalIds(visited, parentSchema)),
|
|
100
|
+
asyncFlatten,
|
|
101
|
+
asyncCollectSet
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
const collectExternalIdsFromObjectOfSchemas = async (visited, parentSchema, schema) => pipe(
|
|
105
|
+
Browser.values(schema),
|
|
106
|
+
asyncMap(Validation.collectExternalIds(visited, parentSchema)),
|
|
107
|
+
asyncFlatten,
|
|
108
|
+
asyncCollectSet
|
|
109
|
+
);
|
|
89
110
|
|
|
90
111
|
const loadKeywordSupport = () => {
|
|
91
112
|
// Stable
|
|
92
113
|
|
|
93
114
|
const additionalProperties = getKeyword("https://json-schema.org/keyword/additionalProperties");
|
|
94
115
|
if (additionalProperties) {
|
|
95
|
-
additionalProperties.collectExternalIds =
|
|
96
|
-
if (typeof additionalProperties === "string") {
|
|
97
|
-
Validation.collectExternalIds(additionalProperties, externalIds, ast, dynamicAnchors);
|
|
98
|
-
}
|
|
99
|
-
};
|
|
116
|
+
additionalProperties.collectExternalIds = Validation.collectExternalIds;
|
|
100
117
|
}
|
|
101
118
|
|
|
102
119
|
const allOf = getKeyword("https://json-schema.org/keyword/allOf");
|
|
103
120
|
if (allOf) {
|
|
104
|
-
allOf.collectExternalIds =
|
|
105
|
-
allOf.forEach((schemaUri) => Validation.collectExternalIds(schemaUri, externalIds, ast, dynamicAnchors));
|
|
106
|
-
};
|
|
121
|
+
allOf.collectExternalIds = collectExternalIdsFromArrayOfSchemas;
|
|
107
122
|
}
|
|
108
123
|
|
|
109
124
|
const anyOf = getKeyword("https://json-schema.org/keyword/anyOf");
|
|
110
125
|
if (anyOf) {
|
|
111
|
-
anyOf.collectExternalIds =
|
|
112
|
-
anyOf.forEach((schemaUri) => Validation.collectExternalIds(schemaUri, externalIds, ast, dynamicAnchors));
|
|
113
|
-
};
|
|
126
|
+
anyOf.collectExternalIds = collectExternalIdsFromArrayOfSchemas;
|
|
114
127
|
}
|
|
115
128
|
|
|
116
129
|
const contains = getKeyword("https://json-schema.org/keyword/contains");
|
|
117
130
|
if (contains) {
|
|
118
|
-
contains.collectExternalIds =
|
|
119
|
-
Validation.collectExternalIds(contains, externalIds, ast, dynamicAnchors);
|
|
120
|
-
};
|
|
131
|
+
contains.collectExternalIds = Validation.collectExternalIds;
|
|
121
132
|
}
|
|
122
133
|
|
|
123
134
|
const dependentSchemas = getKeyword("https://json-schema.org/keyword/dependentSchemas");
|
|
124
135
|
if (dependentSchemas) {
|
|
125
|
-
dependentSchemas.collectExternalIds =
|
|
126
|
-
Object.values(dependentSchemas).forEach(([, schemaUri]) => Validation.collectExternalIds(schemaUri, externalIds, ast, dynamicAnchors));
|
|
127
|
-
};
|
|
136
|
+
dependentSchemas.collectExternalIds = collectExternalIdsFromObjectOfSchemas;
|
|
128
137
|
}
|
|
129
138
|
|
|
130
139
|
const if_ = getKeyword("https://json-schema.org/keyword/if");
|
|
@@ -134,23 +143,17 @@ const loadKeywordSupport = () => {
|
|
|
134
143
|
|
|
135
144
|
const then = getKeyword("https://json-schema.org/keyword/then");
|
|
136
145
|
if (then) {
|
|
137
|
-
then.collectExternalIds =
|
|
138
|
-
Validation.collectExternalIds(then, externalIds, ast, dynamicAnchors);
|
|
139
|
-
};
|
|
146
|
+
then.collectExternalIds = Validation.collectExternalIds;
|
|
140
147
|
}
|
|
141
148
|
|
|
142
149
|
const else_ = getKeyword("https://json-schema.org/keyword/else");
|
|
143
150
|
if (else_) {
|
|
144
|
-
else_.collectExternalIds =
|
|
145
|
-
Validation.collectExternalIds(elseSchema, externalIds, ast, dynamicAnchors);
|
|
146
|
-
};
|
|
151
|
+
else_.collectExternalIds = Validation.collectExternalIds;
|
|
147
152
|
}
|
|
148
153
|
|
|
149
154
|
const items = getKeyword("https://json-schema.org/keyword/items");
|
|
150
155
|
if (items) {
|
|
151
|
-
items.collectExternalIds =
|
|
152
|
-
Validation.collectExternalIds(items, externalIds, ast, dynamicAnchors);
|
|
153
|
-
};
|
|
156
|
+
items.collectExternalIds = Validation.collectExternalIds;
|
|
154
157
|
}
|
|
155
158
|
|
|
156
159
|
const not = getKeyword("https://json-schema.org/keyword/not");
|
|
@@ -160,30 +163,22 @@ const loadKeywordSupport = () => {
|
|
|
160
163
|
|
|
161
164
|
const oneOf = getKeyword("https://json-schema.org/keyword/oneOf");
|
|
162
165
|
if (oneOf) {
|
|
163
|
-
oneOf.collectExternalIds =
|
|
164
|
-
oneOf.forEach((schemaUri) => Validation.collectExternalIds(schemaUri, externalIds, ast, dynamicAnchors));
|
|
165
|
-
};
|
|
166
|
+
oneOf.collectExternalIds = collectExternalIdsFromArrayOfSchemas;
|
|
166
167
|
}
|
|
167
168
|
|
|
168
169
|
const patternProperties = getKeyword("https://json-schema.org/keyword/patternProperties");
|
|
169
170
|
if (patternProperties) {
|
|
170
|
-
patternProperties.collectExternalIds =
|
|
171
|
-
patternProperties.forEach(([, schemaUri]) => Validation.collectExternalIds(schemaUri, externalIds, ast, dynamicAnchors));
|
|
172
|
-
};
|
|
171
|
+
patternProperties.collectExternalIds = collectExternalIdsFromObjectOfSchemas;
|
|
173
172
|
}
|
|
174
173
|
|
|
175
174
|
const prefixItems = getKeyword("https://json-schema.org/keyword/prefixItems");
|
|
176
175
|
if (prefixItems) {
|
|
177
|
-
prefixItems.collectExternalIds =
|
|
178
|
-
tupleItems.forEach((schemaUri) => Validation.collectExternalIds(schemaUri, externalIds, ast, dynamicAnchors));
|
|
179
|
-
};
|
|
176
|
+
prefixItems.collectExternalIds = collectExternalIdsFromArrayOfSchemas;
|
|
180
177
|
}
|
|
181
178
|
|
|
182
179
|
const properties = getKeyword("https://json-schema.org/keyword/properties");
|
|
183
180
|
if (properties) {
|
|
184
|
-
properties.collectExternalIds =
|
|
185
|
-
Object.values(properties).forEach((schemaUri) => Validation.collectExternalIds(schemaUri, externalIds, ast, dynamicAnchors));
|
|
186
|
-
};
|
|
181
|
+
properties.collectExternalIds = collectExternalIdsFromObjectOfSchemas;
|
|
187
182
|
}
|
|
188
183
|
|
|
189
184
|
const propertyNames = getKeyword("https://json-schema.org/keyword/propertyNames");
|
|
@@ -198,119 +193,80 @@ const loadKeywordSupport = () => {
|
|
|
198
193
|
|
|
199
194
|
const unevaluatedItems = getKeyword("https://json-schema.org/keyword/unevaluatedItems");
|
|
200
195
|
if (unevaluatedItems) {
|
|
201
|
-
unevaluatedItems.collectExternalIds =
|
|
202
|
-
Validation.collectExternalIds(unevaluatedItems, externalIds, ast, dynamicAnchors);
|
|
203
|
-
};
|
|
196
|
+
unevaluatedItems.collectExternalIds = Validation.collectExternalIds;
|
|
204
197
|
}
|
|
205
198
|
|
|
206
199
|
const unevaluatedProperties = getKeyword("https://json-schema.org/keyword/unevaluatedProperties");
|
|
207
200
|
if (unevaluatedProperties) {
|
|
208
|
-
unevaluatedProperties.collectExternalIds =
|
|
209
|
-
Validation.collectExternalIds(unevaluatedProperties, externalIds, ast, dynamicAnchors);
|
|
210
|
-
};
|
|
201
|
+
unevaluatedProperties.collectExternalIds = Validation.collectExternalIds;
|
|
211
202
|
}
|
|
212
203
|
|
|
213
204
|
// Draft-04
|
|
214
205
|
|
|
215
206
|
const additionalItems4 = getKeyword("https://json-schema.org/keyword/draft-04/additionalItems");
|
|
216
207
|
if (additionalItems4) {
|
|
217
|
-
additionalItems4.collectExternalIds =
|
|
218
|
-
if (typeof additionalItems === "string") {
|
|
219
|
-
Validation.collectExternalIds(additionalItems, externalIds, ast, dynamicAnchors);
|
|
220
|
-
}
|
|
221
|
-
};
|
|
208
|
+
additionalItems4.collectExternalIds = Validation.collectExternalIds;
|
|
222
209
|
}
|
|
223
210
|
|
|
224
211
|
const dependencies = getKeyword("https://json-schema.org/keyword/draft-04/dependencies");
|
|
225
212
|
if (dependencies) {
|
|
226
|
-
dependencies.collectExternalIds = (
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
213
|
+
dependencies.collectExternalIds = (visited, parentSchema, schema) => pipe(
|
|
214
|
+
Browser.values(schema),
|
|
215
|
+
asyncFilter((subSchema) => Browser.typeOf(subSchema) === "object"),
|
|
216
|
+
asyncMap(Validation.collectExternalIds(visited, parentSchema)),
|
|
217
|
+
asyncFlatten,
|
|
218
|
+
asyncCollectSet
|
|
219
|
+
);
|
|
233
220
|
}
|
|
234
221
|
|
|
235
222
|
const items4 = getKeyword("https://json-schema.org/keyword/draft-04/items");
|
|
236
223
|
if (items4) {
|
|
237
|
-
items4.collectExternalIds = (
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
} else {
|
|
241
|
-
items.forEach((schemaUri) => Validation.collectExternalIds(schemaUri, externalIds, ast, dynamicAnchors));
|
|
242
|
-
}
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
const ref4 = getKeyword("https://json-schema.org/keyword/draft-04/ref");
|
|
247
|
-
if (ref4) {
|
|
248
|
-
ref4.collectExternalIds = Validation.collectExternalIds;
|
|
224
|
+
items4.collectExternalIds = (visited, parentSchema, schema) => Browser.typeOf(schema) === "array"
|
|
225
|
+
? collectExternalIdsFromArrayOfSchemas(visited, parentSchema, schema)
|
|
226
|
+
: Validation.collectExternalIds(visited, parentSchema, schema);
|
|
249
227
|
}
|
|
250
228
|
|
|
251
229
|
// Draft-06
|
|
252
230
|
|
|
253
231
|
const contains6 = getKeyword("https://json-schema.org/keyword/draft-06/contains");
|
|
254
232
|
if (contains6) {
|
|
255
|
-
contains6.collectExternalIds =
|
|
256
|
-
Validation.collectExternalIds(contains, externalIds, ast, dynamicAnchors);
|
|
257
|
-
};
|
|
233
|
+
contains6.collectExternalIds = Validation.collectExternalIds;
|
|
258
234
|
}
|
|
259
235
|
|
|
260
236
|
// Draft-2019-09
|
|
261
237
|
|
|
262
238
|
const contains19 = getKeyword("https://json-schema.org/keyword/draft-2019-09/contains");
|
|
263
239
|
if (contains19) {
|
|
264
|
-
contains19.collectExternalIds =
|
|
265
|
-
Validation.collectExternalIds(contains, externalIds, ast, dynamicAnchors);
|
|
266
|
-
};
|
|
240
|
+
contains19.collectExternalIds = Validation.collectExternalIds;
|
|
267
241
|
}
|
|
268
242
|
|
|
269
|
-
//
|
|
243
|
+
// Extensions
|
|
270
244
|
|
|
271
245
|
const propertyDependencies = getKeyword("https://json-schema.org/keyword/propertyDependencies");
|
|
272
246
|
if (propertyDependencies) {
|
|
273
|
-
propertyDependencies.collectExternalIds = (
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
247
|
+
propertyDependencies.collectExternalIds = (visited, parentSchema, schema) => pipe(
|
|
248
|
+
Browser.values(schema),
|
|
249
|
+
asyncMap((mapping) => Browser.values(mapping)),
|
|
250
|
+
asyncFlatten,
|
|
251
|
+
asyncMap(Validation.collectExternalIds(visited, parentSchema)),
|
|
252
|
+
asyncFlatten,
|
|
253
|
+
asyncCollectSet
|
|
254
|
+
);
|
|
280
255
|
}
|
|
281
256
|
|
|
282
257
|
const conditional = getKeyword("https://json-schema.org/keyword/conditional");
|
|
283
258
|
if (conditional) {
|
|
284
|
-
conditional.collectExternalIds =
|
|
285
|
-
for (const schema of conditional) {
|
|
286
|
-
Validation.collectExternalIds(schema, externalIds, ast, dynamicAnchors);
|
|
287
|
-
}
|
|
288
|
-
};
|
|
259
|
+
conditional.collectExternalIds = collectExternalIdsFromArrayOfSchemas;
|
|
289
260
|
}
|
|
290
261
|
|
|
291
262
|
const itemPattern = getKeyword("https://json-schema.org/keyword/itemPattern");
|
|
292
263
|
if (itemPattern) {
|
|
293
|
-
itemPattern.collectExternalIds = (
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
264
|
+
itemPattern.collectExternalIds = (visited, parentSchema, schema) => pipe(
|
|
265
|
+
Browser.iter(schema),
|
|
266
|
+
asyncFilter((item) => Browser.typeOf(item) === "object"),
|
|
267
|
+
asyncMap(Validation.collectExternalIds(visited, parentSchema)),
|
|
268
|
+
asyncFlatten,
|
|
269
|
+
asyncCollectSet
|
|
270
|
+
);
|
|
298
271
|
}
|
|
299
|
-
|
|
300
|
-
const collectNfaSchemas = function* (node, visited = new Set()) {
|
|
301
|
-
if (visited.has(node)) {
|
|
302
|
-
return;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
visited.add(node);
|
|
306
|
-
|
|
307
|
-
for (const schema in node.transition) {
|
|
308
|
-
yield schema;
|
|
309
|
-
yield* collectNfaSchemas(node.transition[schema], visited);
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
for (const epsilon of node.epsilonTransitions) {
|
|
313
|
-
yield* collectNfaSchemas(epsilon, visited);
|
|
314
|
-
}
|
|
315
|
-
};
|
|
316
272
|
};
|
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
import { pipe, drop, every } from "@hyperjump/pact";
|
|
2
|
+
import * as Browser from "@hyperjump/browser";
|
|
2
3
|
import * as Instance from "../lib/instance.js";
|
|
3
|
-
import
|
|
4
|
-
import Validation from "../lib/keywords/validation.js";
|
|
5
|
-
import { getKeywordName } from "../lib/keywords.js";
|
|
4
|
+
import { getKeywordName, Validation } from "../lib/experimental.js";
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
const id = "https://json-schema.org/keyword/draft-04/additionalItems";
|
|
9
8
|
|
|
10
9
|
const compile = async (schema, ast, parentSchema) => {
|
|
11
|
-
const itemsKeywordName = getKeywordName(schema.dialectId, "https://json-schema.org/keyword/draft-04/items");
|
|
12
|
-
const items = await
|
|
13
|
-
const numberOfItems =
|
|
10
|
+
const itemsKeywordName = getKeywordName(schema.document.dialectId, "https://json-schema.org/keyword/draft-04/items");
|
|
11
|
+
const items = await Browser.step(itemsKeywordName, parentSchema);
|
|
12
|
+
const numberOfItems = Browser.typeOf(items) === "array" ? Browser.length(items) : Number.MAX_SAFE_INTEGER;
|
|
14
13
|
|
|
15
14
|
return [numberOfItems, await Validation.compile(schema, ast)];
|
|
16
15
|
};
|
|
17
16
|
|
|
18
17
|
const interpret = ([numberOfItems, additionalItems], instance, ast, dynamicAnchors, quiet) => {
|
|
19
|
-
if (
|
|
18
|
+
if (Instance.typeOf(instance) !== "array") {
|
|
20
19
|
return true;
|
|
21
20
|
}
|
|
22
21
|
|
package/draft-04/dependencies.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { pipe, asyncMap, asyncCollectArray } from "@hyperjump/pact";
|
|
2
|
+
import * as Browser from "@hyperjump/browser";
|
|
2
3
|
import * as Instance from "../lib/instance.js";
|
|
3
|
-
import
|
|
4
|
-
import Validation from "../lib/keywords/validation.js";
|
|
4
|
+
import { Validation } from "../lib/experimental.js";
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
const id = "https://json-schema.org/keyword/draft-04/dependencies";
|
|
8
8
|
|
|
9
9
|
const compile = (schema, ast) => pipe(
|
|
10
|
-
|
|
10
|
+
Browser.entries(schema),
|
|
11
11
|
asyncMap(async ([key, dependency]) => [
|
|
12
12
|
key,
|
|
13
|
-
|
|
13
|
+
Browser.typeOf(dependency) === "array" ? Browser.value(dependency) : await Validation.compile(dependency, ast)
|
|
14
14
|
]),
|
|
15
15
|
asyncCollectArray
|
|
16
16
|
);
|
|
@@ -18,7 +18,7 @@ const compile = (schema, ast) => pipe(
|
|
|
18
18
|
const interpret = (dependencies, instance, ast, dynamicAnchors, quiet) => {
|
|
19
19
|
const value = Instance.value(instance);
|
|
20
20
|
|
|
21
|
-
return
|
|
21
|
+
return Instance.typeOf(instance) !== "object" || dependencies.every(([propertyName, dependency]) => {
|
|
22
22
|
if (!(propertyName in value)) {
|
|
23
23
|
return true;
|
|
24
24
|
}
|
package/draft-04/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { addKeyword, defineVocabulary, loadDialect } from "../lib/keywords.js";
|
|
2
|
-
import {
|
|
2
|
+
import { registerSchema } from "../lib/index.js";
|
|
3
3
|
import metaSchema from "./schema.js";
|
|
4
4
|
import additionalItems from "./additionalItems.js";
|
|
5
5
|
import dependencies from "./dependencies.js";
|
|
@@ -64,6 +64,6 @@ loadDialect(jsonSchemaVersion, {
|
|
|
64
64
|
[jsonSchemaVersion]: true
|
|
65
65
|
}, true);
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
registerSchema(metaSchema);
|
|
68
68
|
|
|
69
69
|
export * from "../lib/index.js";
|
package/draft-04/items.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { pipe, asyncMap, asyncCollectArray, every, zip, take, range, collectSet } from "@hyperjump/pact";
|
|
2
|
+
import * as Browser from "@hyperjump/browser";
|
|
2
3
|
import * as Instance from "../lib/instance.js";
|
|
3
|
-
import
|
|
4
|
-
import Validation from "../lib/keywords/validation.js";
|
|
4
|
+
import { Validation } from "../lib/experimental.js";
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
const id = "https://json-schema.org/keyword/draft-04/items";
|
|
8
8
|
|
|
9
9
|
const compile = (schema, ast) => {
|
|
10
|
-
if (
|
|
10
|
+
if (Browser.typeOf(schema) === "array") {
|
|
11
11
|
return pipe(
|
|
12
|
-
|
|
12
|
+
Browser.iter(schema),
|
|
13
13
|
asyncMap((itemSchema) => Validation.compile(itemSchema, ast)),
|
|
14
14
|
asyncCollectArray
|
|
15
15
|
);
|
|
@@ -19,7 +19,7 @@ const compile = (schema, ast) => {
|
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
const interpret = (items, instance, ast, dynamicAnchors, quiet) => {
|
|
22
|
-
if (
|
|
22
|
+
if (Instance.typeOf(instance) !== "array") {
|
|
23
23
|
return true;
|
|
24
24
|
}
|
|
25
25
|
|
package/draft-04/maximum.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
+
import * as Browser from "@hyperjump/browser";
|
|
1
2
|
import * as Instance from "../lib/instance.js";
|
|
2
|
-
import
|
|
3
|
-
import { getKeywordName } from "../lib/keywords.js";
|
|
3
|
+
import { getKeywordName } from "../lib/experimental.js";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
const id = "https://json-schema.org/keyword/draft-04/maximum";
|
|
7
7
|
|
|
8
|
-
const compile = async (schema,
|
|
9
|
-
const exclusiveMaximumKeyword = getKeywordName(schema.dialectId, "https://json-schema.org/keyword/draft-04/exclusiveMaximum");
|
|
10
|
-
const exclusiveMaximum = await
|
|
11
|
-
const isExclusive =
|
|
8
|
+
const compile = async (schema, _ast, parentSchema) => {
|
|
9
|
+
const exclusiveMaximumKeyword = getKeywordName(schema.document.dialectId, "https://json-schema.org/keyword/draft-04/exclusiveMaximum");
|
|
10
|
+
const exclusiveMaximum = await Browser.step(exclusiveMaximumKeyword, parentSchema);
|
|
11
|
+
const isExclusive = Browser.value(exclusiveMaximum);
|
|
12
12
|
|
|
13
|
-
return [
|
|
13
|
+
return [Browser.value(schema), isExclusive];
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
const interpret = ([maximum, isExclusive], instance) => {
|
|
17
|
-
if (
|
|
17
|
+
if (Instance.typeOf(instance) !== "number") {
|
|
18
18
|
return true;
|
|
19
19
|
}
|
|
20
20
|
|
package/draft-04/minimum.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
+
import * as Browser from "@hyperjump/browser";
|
|
1
2
|
import * as Instance from "../lib/instance.js";
|
|
2
|
-
import
|
|
3
|
-
import { getKeywordName } from "../lib/keywords.js";
|
|
3
|
+
import { getKeywordName } from "../lib/experimental.js";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
const id = "https://json-schema.org/keyword/draft-04/minimum";
|
|
7
7
|
|
|
8
|
-
const compile = async (schema,
|
|
9
|
-
const exclusiveMinimumKeyword = getKeywordName(schema.dialectId, "https://json-schema.org/keyword/draft-04/exclusiveMinimum");
|
|
10
|
-
const exclusiveMinimum = await
|
|
11
|
-
const isExclusive =
|
|
8
|
+
const compile = async (schema, _ast, parentSchema) => {
|
|
9
|
+
const exclusiveMinimumKeyword = getKeywordName(schema.document.dialectId, "https://json-schema.org/keyword/draft-04/exclusiveMinimum");
|
|
10
|
+
const exclusiveMinimum = await Browser.step(exclusiveMinimumKeyword, parentSchema);
|
|
11
|
+
const isExclusive = Browser.value(exclusiveMinimum);
|
|
12
12
|
|
|
13
|
-
return [
|
|
13
|
+
return [Browser.value(schema), isExclusive];
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
const interpret = ([minimum, isExclusive], instance) => {
|
|
17
|
-
if (
|
|
17
|
+
if (Instance.typeOf(instance) !== "number") {
|
|
18
18
|
return true;
|
|
19
19
|
}
|
|
20
20
|
|