json-schema-library 11.4.1 → 11.5.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/CHANGELOG.md +6 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -1
- package/dist/index.d.mts +4 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/jlib.js +2 -2
- package/package.json +1 -1
- package/src/SchemaNode.ts +5 -2
- package/src/compileSchema.test.ts +24 -0
- package/src/compileSchema.ts +15 -2
- package/src/draftEditor.ts +1 -0
- package/src/settings.ts +2 -0
- package/src/validateSchema.test.ts +10 -1
package/package.json
CHANGED
package/src/SchemaNode.ts
CHANGED
|
@@ -41,7 +41,7 @@ import { getNode } from "./getNode";
|
|
|
41
41
|
import { getNodeChild } from "./getNodeChild";
|
|
42
42
|
import { DataNode } from "./methods/toDataNodes";
|
|
43
43
|
|
|
44
|
-
const { DYNAMIC_PROPERTIES, REGEX_FLAGS, DECLARATOR_ONEOF } = settings;
|
|
44
|
+
const { DYNAMIC_PROPERTIES, REGEX_FLAGS, DECLARATOR_ONEOF, VALID_ANNOTATION_KEYWORDS } = settings;
|
|
45
45
|
|
|
46
46
|
export function isSchemaNode(value: unknown): value is SchemaNode {
|
|
47
47
|
return isObject(value) && Array.isArray(value?.reducers) && Array.isArray(value?.resolvers);
|
|
@@ -624,7 +624,10 @@ export function addKeywords(node: SchemaNode) {
|
|
|
624
624
|
.map((keyword) => execKeyword(keyword, node));
|
|
625
625
|
|
|
626
626
|
keys.filter(
|
|
627
|
-
(key) =>
|
|
627
|
+
(key) =>
|
|
628
|
+
!key.startsWith("x-") &&
|
|
629
|
+
!VALID_ANNOTATION_KEYWORDS.includes(key) &&
|
|
630
|
+
node.context.keywords.find((keyword) => keyword.keyword === key) == null
|
|
628
631
|
).forEach((keyword) => {
|
|
629
632
|
errors.push(
|
|
630
633
|
node.createAnnotation("unknown-keyword-warning", {
|
|
@@ -84,6 +84,30 @@ describe("compileSchema draft-version", () => {
|
|
|
84
84
|
});
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
+
describe("compileSchema remotes", () => {
|
|
88
|
+
it("should add list of remotes to returned SchemaNode node", () => {
|
|
89
|
+
const node = compileSchema(
|
|
90
|
+
{
|
|
91
|
+
type: "object",
|
|
92
|
+
required: ["string", "number"],
|
|
93
|
+
properties: {
|
|
94
|
+
string: { $ref: "https://remote-a.com/schema" },
|
|
95
|
+
number: { $ref: "https://remote-b.com/schema" }
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
drafts: [draft2020],
|
|
100
|
+
remotes: [
|
|
101
|
+
{ $id: "https://remote-a.com/schema", type: "string", default: "a" },
|
|
102
|
+
{ $id: "https://remote-b.com/schema", type: "number", default: 9 }
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
const data = node.getData();
|
|
107
|
+
assert.deepEqual(data, { string: "a", number: 9 });
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
87
111
|
describe("compileSchema vocabulary", () => {
|
|
88
112
|
it("should add remote schema on compile", () => {
|
|
89
113
|
const remote = compileSchema({
|
package/src/compileSchema.ts
CHANGED
|
@@ -67,6 +67,7 @@ export type CompileOptions = {
|
|
|
67
67
|
* Set node and its remote schemata as remote schemata for this node and schema to resolve $ref
|
|
68
68
|
*/
|
|
69
69
|
remote?: SchemaNode;
|
|
70
|
+
remotes?: JsonSchema[];
|
|
70
71
|
/**
|
|
71
72
|
* Enables `format`-keyword assertions when this is set tor `true` or sets assertion as defined by
|
|
72
73
|
* the given meta-schema. Set to `false` to deactivate format validation.
|
|
@@ -94,6 +95,18 @@ function getDraft(drafts: Draft[], $schema: string) {
|
|
|
94
95
|
* node will be reused for each task, but will create a compiledNode for bound data.
|
|
95
96
|
*/
|
|
96
97
|
export function compileSchema(schema: JsonSchema | BooleanSchema, options: CompileOptions = {}) {
|
|
98
|
+
let remote = options.remote;
|
|
99
|
+
if (Array.isArray(options.remotes) && options.remotes.length > 0 && !options.remote) {
|
|
100
|
+
const remotes = [...options.remotes];
|
|
101
|
+
remotes.forEach((remote, index) => {
|
|
102
|
+
if (remote.$id == null) {
|
|
103
|
+
throw new Error(`required $id on remotes[${index}] is missing`);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
remote = compileSchema(remotes.shift()!);
|
|
107
|
+
remotes.forEach((r) => remote?.addRemoteSchema(r.$id, r));
|
|
108
|
+
}
|
|
109
|
+
|
|
97
110
|
let formatAssertion = options.formatAssertion ?? true;
|
|
98
111
|
const drafts = options.drafts ?? defaultDrafts;
|
|
99
112
|
const draft = getDraft(drafts, isJsonSchema(schema) ? (options.draft ?? schema.$schema) : undefined);
|
|
@@ -110,7 +123,7 @@ export function compileSchema(schema: JsonSchema | BooleanSchema, options: Compi
|
|
|
110
123
|
context: {
|
|
111
124
|
remotes: {},
|
|
112
125
|
dynamicAnchors: {},
|
|
113
|
-
...(
|
|
126
|
+
...(remote?.context ?? {}),
|
|
114
127
|
anchors: {},
|
|
115
128
|
refs: {},
|
|
116
129
|
...copy(pick(draft, "methods", "keywords", "version", "formats", "errors")),
|
|
@@ -125,7 +138,7 @@ export function compileSchema(schema: JsonSchema | BooleanSchema, options: Compi
|
|
|
125
138
|
node.context.rootNode = node;
|
|
126
139
|
node.context.remotes[(isJsonSchema(schema) ? schema.$id : undefined) ?? "#"] = node;
|
|
127
140
|
|
|
128
|
-
if (
|
|
141
|
+
if (remote) {
|
|
129
142
|
const metaSchema = getRef(node, node.schema.$schema);
|
|
130
143
|
if (isSchemaNode(metaSchema) && metaSchema.schema.$vocabulary) {
|
|
131
144
|
const vocabs = Object.keys(metaSchema.schema.$vocabulary);
|
package/src/draftEditor.ts
CHANGED
package/src/settings.ts
CHANGED
|
@@ -18,6 +18,8 @@ export default {
|
|
|
18
18
|
"propertyDependencies"
|
|
19
19
|
],
|
|
20
20
|
REGEX_FLAGS: "u",
|
|
21
|
+
/** additional keywords that should not produce an unknown-keyword-warning */
|
|
22
|
+
VALID_ANNOTATION_KEYWORDS: ["title", "description", "default"],
|
|
21
23
|
/**
|
|
22
24
|
* properties to keep from a $ref-schema when resolving a $ref (recursively)
|
|
23
25
|
* this allows to overwrite specified properties locally on a $ref-definition
|
|
@@ -263,7 +263,7 @@ describe("validateSchema", () => {
|
|
|
263
263
|
assert.equal(schemaAnnotations.length, 1);
|
|
264
264
|
assert.equal(schemaAnnotations[0].data.pointer, "#/properties/headline/options");
|
|
265
265
|
});
|
|
266
|
-
it("should return
|
|
266
|
+
it("should not return unknown keywords starting with 'x-'", () => {
|
|
267
267
|
const { schemaAnnotations } = compileSchema({
|
|
268
268
|
properties: {
|
|
269
269
|
headline: {
|
|
@@ -274,6 +274,15 @@ describe("validateSchema", () => {
|
|
|
274
274
|
});
|
|
275
275
|
assert.equal(schemaAnnotations.length, 0);
|
|
276
276
|
});
|
|
277
|
+
it("should not return valid annotation keywords", () => {
|
|
278
|
+
const { schemaAnnotations } = compileSchema({
|
|
279
|
+
type: "string",
|
|
280
|
+
title: "input",
|
|
281
|
+
description: "any string",
|
|
282
|
+
default: "hey"
|
|
283
|
+
});
|
|
284
|
+
assert.equal(schemaAnnotations.length, 0);
|
|
285
|
+
});
|
|
277
286
|
it("should return removed keywords from old drafts as annotation", () => {
|
|
278
287
|
const { schemaAnnotations } = compileSchema({
|
|
279
288
|
properties: {
|