@hyperjump/json-schema 1.4.1 → 1.4.2
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 +21 -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,17 @@ 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
|
+
const idToken = getKeywordName(embeddedDialectId, "https://json-schema.org/keyword/id");
|
|
81
|
+
if (typeof subject[idToken] === "string") {
|
|
82
|
+
subject[idToken] = resolveUri(subject[idToken], id);
|
|
83
|
+
add(subject, undefined, dialectId);
|
|
84
|
+
return Reference.cons(subject[idToken], subject);
|
|
85
|
+
}
|
|
86
|
+
|
|
77
87
|
// Legacy id
|
|
78
|
-
const legacyIdToken = getKeywordName(
|
|
88
|
+
const legacyIdToken = getKeywordName(embeddedDialectId, "https://json-schema.org/keyword/draft-04/id");
|
|
79
89
|
if (typeof subject[legacyIdToken] === "string") {
|
|
80
90
|
if (subject[legacyIdToken][0] === "#") {
|
|
81
91
|
const anchor = decodeURIComponent(subject[legacyIdToken].slice(1));
|
|
@@ -89,13 +99,10 @@ const processSchema = (subject, id, dialectId, pointer, anchors, dynamicAnchors)
|
|
|
89
99
|
delete subject[legacyIdToken];
|
|
90
100
|
}
|
|
91
101
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
subject[idToken] = resolveUri(subject[idToken], id);
|
|
97
|
-
add(subject, undefined, dialectId);
|
|
98
|
-
return Reference.cons(subject[idToken], subject);
|
|
102
|
+
const dynamicAnchorToken = getKeywordName(dialectId, "https://json-schema.org/keyword/dynamicAnchor");
|
|
103
|
+
if (typeof subject[dynamicAnchorToken] === "string") {
|
|
104
|
+
dynamicAnchors[subject[dynamicAnchorToken]] = `${id}#${encodeURI(pointer)}`;
|
|
105
|
+
delete subject[dynamicAnchorToken];
|
|
99
106
|
}
|
|
100
107
|
|
|
101
108
|
// Legacy dynamic anchor
|
|
@@ -106,12 +113,6 @@ const processSchema = (subject, id, dialectId, pointer, anchors, dynamicAnchors)
|
|
|
106
113
|
delete subject[legacyDynamicAnchorToken];
|
|
107
114
|
}
|
|
108
115
|
|
|
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
116
|
const anchorToken = getKeywordName(dialectId, "https://json-schema.org/keyword/anchor");
|
|
116
117
|
if (typeof subject[anchorToken] === "string") {
|
|
117
118
|
anchors[subject[anchorToken]] = pointer;
|
|
@@ -157,7 +158,7 @@ const nil = {
|
|
|
157
158
|
|
|
158
159
|
export const get = async (url, contextDoc = nil) => {
|
|
159
160
|
const resolvedUrl = resolveUri(url, contextDoc.id);
|
|
160
|
-
const id =
|
|
161
|
+
const id = toAbsoluteIri(resolvedUrl);
|
|
161
162
|
const fragment = uriFragment(resolvedUrl);
|
|
162
163
|
|
|
163
164
|
if (!hasStoredSchema(id)) {
|
|
@@ -170,7 +171,7 @@ export const get = async (url, contextDoc = nil) => {
|
|
|
170
171
|
const [schema, contextDialectId] = await parseResponse(response);
|
|
171
172
|
|
|
172
173
|
// Try to determine the dialect from the meta-schema if it isn't already known
|
|
173
|
-
const dialectId =
|
|
174
|
+
const dialectId = toAbsoluteIri(schema.$schema || contextDialectId || defaultDialectId);
|
|
174
175
|
if (!hasDialect(dialectId) && !hasStoredSchema(dialectId)) {
|
|
175
176
|
await get(dialectId);
|
|
176
177
|
}
|