@hyperjump/json-schema 1.4.1 → 1.4.3
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/lib/common.js +6 -1
- package/lib/instance.js +3 -2
- package/lib/keywords.js +6 -3
- package/lib/schema.js +25 -20
- package/package.json +1 -1
package/lib/common.js
CHANGED
|
@@ -22,7 +22,12 @@ export const resolveUri = (uri, baseUri) => {
|
|
|
22
22
|
return resolved;
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
export const toAbsoluteUri = (uri) =>
|
|
25
|
+
export const toAbsoluteUri = (uri) => {
|
|
26
|
+
const position = uri.indexOf("#");
|
|
27
|
+
const end = position === -1 ? uri.length : position;
|
|
28
|
+
return uri.slice(0, end);
|
|
29
|
+
};
|
|
30
|
+
|
|
26
31
|
export const uriFragment = (uri) => decodeURIComponent(parseIriReference(uri).fragment || "");
|
|
27
32
|
|
|
28
33
|
const CHAR_BACKWARD_SLASH = 47;
|
package/lib/instance.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { append as pointerAppend } from "@hyperjump/json-pointer";
|
|
2
|
+
import { toAbsoluteIri } from "@hyperjump/uri";
|
|
2
3
|
import curry from "just-curry-it";
|
|
3
|
-
import {
|
|
4
|
+
import { jsonTypeOf } from "./common.js";
|
|
4
5
|
import * as Reference from "./reference.js";
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
export const nil = { id: undefined, pointer: "", instance: undefined, value: undefined };
|
|
8
9
|
export const cons = (instance, id = undefined) => ({
|
|
9
10
|
...nil,
|
|
10
|
-
id: id ?
|
|
11
|
+
id: id ? toAbsoluteIri(id) : "",
|
|
11
12
|
instance,
|
|
12
13
|
value: instance
|
|
13
14
|
});
|
package/lib/keywords.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { toAbsoluteUri } from "./common.js";
|
|
2
|
+
|
|
3
|
+
|
|
1
4
|
const _keywords = {};
|
|
2
|
-
export const getKeyword = (id) => _keywords[id];
|
|
5
|
+
export const getKeyword = (id) => _keywords[toAbsoluteUri(id)];
|
|
3
6
|
|
|
4
7
|
export const addKeyword = (keywordHandler) => {
|
|
5
8
|
_keywords[keywordHandler.id] = keywordHandler;
|
|
@@ -13,7 +16,7 @@ export const defineVocabulary = (id, keywords) => {
|
|
|
13
16
|
const _dialects = {};
|
|
14
17
|
const _allowUnknownKeywords = {};
|
|
15
18
|
export const getKeywordId = (dialectId, keyword) => _dialects[dialectId]?.[keyword]
|
|
16
|
-
|| _allowUnknownKeywords[dialectId] &&
|
|
19
|
+
|| (_allowUnknownKeywords[dialectId] || keyword[0] === "@") && `https://json-schema.org/keyword/unknown#${keyword}`;
|
|
17
20
|
export const getKeywordName = (dialectId, keywordId) => {
|
|
18
21
|
for (const keyword in _dialects[dialectId]) {
|
|
19
22
|
if (_dialects[dialectId][keyword] === keywordId) {
|
|
@@ -35,7 +38,7 @@ export const loadDialect = (dialectId, dialect, allowUnknownKeywords = false) =>
|
|
|
35
38
|
.forEach(([keyword, keywordId]) => {
|
|
36
39
|
if (!(keywordId in _keywords) && !isRequired) {
|
|
37
40
|
// Allow keyword to be ignored
|
|
38
|
-
keywordId =
|
|
41
|
+
keywordId = `https://json-schema.org/keyword/unknown#${keyword}`;
|
|
39
42
|
}
|
|
40
43
|
_dialects[dialectId][keyword] = keywordId;
|
|
41
44
|
});
|
package/lib/schema.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import curry from "just-curry-it";
|
|
2
2
|
import * as Pact from "@hyperjump/pact";
|
|
3
3
|
import { nil as nilPointer, append as pointerAppend, get as pointerGet } from "@hyperjump/json-pointer";
|
|
4
|
-
import {
|
|
4
|
+
import { toAbsoluteIri } from "@hyperjump/uri";
|
|
5
|
+
import { jsonTypeOf, resolveUri, uriFragment, pathRelative, jsonStringify } from "./common.js";
|
|
5
6
|
import fetch from "./fetch.js";
|
|
6
7
|
import { hasDialect, loadDialect, getKeywordName } from "./keywords.js";
|
|
7
8
|
import { parseResponse, acceptableMediaTypes } from "./media-types.js";
|
|
@@ -18,7 +19,7 @@ export const add = (schema, retrievalUri = undefined, contextDialectId = undefin
|
|
|
18
19
|
schema = JSON.parse(JSON.stringify(schema));
|
|
19
20
|
|
|
20
21
|
// Dialect / JSON Schema Version
|
|
21
|
-
const dialectId =
|
|
22
|
+
const dialectId = toAbsoluteIri(schema.$schema || contextDialectId || defaultDialectId);
|
|
22
23
|
delete schema.$schema;
|
|
23
24
|
|
|
24
25
|
if (!hasDialect(dialectId)) {
|
|
@@ -32,10 +33,10 @@ export const add = (schema, retrievalUri = undefined, contextDialectId = undefin
|
|
|
32
33
|
throw Error(`Unable to determine an identifier for the schema. Use the '${idToken}' keyword or pass a retrievalUri when loading the schema.`);
|
|
33
34
|
}
|
|
34
35
|
const internalUrl = resolveUri(schema[idToken] || retrievalUri, retrievalUri);
|
|
35
|
-
const id =
|
|
36
|
+
const id = toAbsoluteIri(internalUrl);
|
|
36
37
|
delete schema[idToken];
|
|
37
38
|
if (retrievalUri) {
|
|
38
|
-
const externalId =
|
|
39
|
+
const externalId = toAbsoluteIri(retrievalUri);
|
|
39
40
|
schemaStoreAlias[externalId] = id;
|
|
40
41
|
}
|
|
41
42
|
|
|
@@ -74,8 +75,21 @@ export const add = (schema, retrievalUri = undefined, contextDialectId = undefin
|
|
|
74
75
|
|
|
75
76
|
const processSchema = (subject, id, dialectId, pointer, anchors, dynamicAnchors) => {
|
|
76
77
|
if (jsonTypeOf(subject, "object")) {
|
|
78
|
+
// Embedded Schema
|
|
79
|
+
const embeddedDialectId = typeof subject.$schema === "string" ? toAbsoluteIri(subject.$schema) : dialectId;
|
|
80
|
+
if (!hasDialect(embeddedDialectId)) {
|
|
81
|
+
throw Error(`Encountered unknown dialect '${embeddedDialectId}'`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const idToken = getKeywordName(embeddedDialectId, "https://json-schema.org/keyword/id");
|
|
85
|
+
if (typeof subject[idToken] === "string") {
|
|
86
|
+
subject[idToken] = resolveUri(subject[idToken], id);
|
|
87
|
+
add(subject, undefined, dialectId);
|
|
88
|
+
return Reference.cons(subject[idToken], subject);
|
|
89
|
+
}
|
|
90
|
+
|
|
77
91
|
// Legacy id
|
|
78
|
-
const legacyIdToken = getKeywordName(
|
|
92
|
+
const legacyIdToken = getKeywordName(embeddedDialectId, "https://json-schema.org/keyword/draft-04/id");
|
|
79
93
|
if (typeof subject[legacyIdToken] === "string") {
|
|
80
94
|
if (subject[legacyIdToken][0] === "#") {
|
|
81
95
|
const anchor = decodeURIComponent(subject[legacyIdToken].slice(1));
|
|
@@ -89,13 +103,10 @@ const processSchema = (subject, id, dialectId, pointer, anchors, dynamicAnchors)
|
|
|
89
103
|
delete subject[legacyIdToken];
|
|
90
104
|
}
|
|
91
105
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
subject[idToken] = resolveUri(subject[idToken], id);
|
|
97
|
-
add(subject, undefined, dialectId);
|
|
98
|
-
return Reference.cons(subject[idToken], subject);
|
|
106
|
+
const dynamicAnchorToken = getKeywordName(dialectId, "https://json-schema.org/keyword/dynamicAnchor");
|
|
107
|
+
if (typeof subject[dynamicAnchorToken] === "string") {
|
|
108
|
+
dynamicAnchors[subject[dynamicAnchorToken]] = `${id}#${encodeURI(pointer)}`;
|
|
109
|
+
delete subject[dynamicAnchorToken];
|
|
99
110
|
}
|
|
100
111
|
|
|
101
112
|
// Legacy dynamic anchor
|
|
@@ -106,12 +117,6 @@ const processSchema = (subject, id, dialectId, pointer, anchors, dynamicAnchors)
|
|
|
106
117
|
delete subject[legacyDynamicAnchorToken];
|
|
107
118
|
}
|
|
108
119
|
|
|
109
|
-
const dynamicAnchorToken = getKeywordName(dialectId, "https://json-schema.org/keyword/dynamicAnchor");
|
|
110
|
-
if (typeof subject[dynamicAnchorToken] === "string") {
|
|
111
|
-
dynamicAnchors[subject[dynamicAnchorToken]] = `${id}#${encodeURI(pointer)}`;
|
|
112
|
-
delete subject[dynamicAnchorToken];
|
|
113
|
-
}
|
|
114
|
-
|
|
115
120
|
const anchorToken = getKeywordName(dialectId, "https://json-schema.org/keyword/anchor");
|
|
116
121
|
if (typeof subject[anchorToken] === "string") {
|
|
117
122
|
anchors[subject[anchorToken]] = pointer;
|
|
@@ -157,7 +162,7 @@ const nil = {
|
|
|
157
162
|
|
|
158
163
|
export const get = async (url, contextDoc = nil) => {
|
|
159
164
|
const resolvedUrl = resolveUri(url, contextDoc.id);
|
|
160
|
-
const id =
|
|
165
|
+
const id = toAbsoluteIri(resolvedUrl);
|
|
161
166
|
const fragment = uriFragment(resolvedUrl);
|
|
162
167
|
|
|
163
168
|
if (!hasStoredSchema(id)) {
|
|
@@ -170,7 +175,7 @@ export const get = async (url, contextDoc = nil) => {
|
|
|
170
175
|
const [schema, contextDialectId] = await parseResponse(response);
|
|
171
176
|
|
|
172
177
|
// Try to determine the dialect from the meta-schema if it isn't already known
|
|
173
|
-
const dialectId =
|
|
178
|
+
const dialectId = toAbsoluteIri(schema.$schema || contextDialectId || defaultDialectId);
|
|
174
179
|
if (!hasDialect(dialectId) && !hasStoredSchema(dialectId)) {
|
|
175
180
|
await get(dialectId);
|
|
176
181
|
}
|