json-schema-library 11.3.0 → 11.4.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 +21 -2
- package/README.md +44 -35
- package/bowtie/bowtie.test.ts +80 -0
- package/bowtie/package.json +1 -1
- package/dist/chunk-350yNsax.cjs +1 -0
- package/dist/formats.cjs +2 -0
- package/dist/formats.cjs.map +1 -0
- package/dist/formats.d.cts +8 -0
- package/dist/formats.d.mts +8 -0
- package/dist/formats.mjs +2 -0
- package/dist/formats.mjs.map +1 -0
- package/dist/index.cjs +2 -1
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +4 -4
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +2 -1
- package/dist/index.mjs.map +1 -0
- package/dist/jlib.js +2 -2
- package/dist/jlibFormats.iife.js +1 -0
- package/dist/jlibRemote.iife.js +1 -0
- package/dist/{remotes/index.cjs → remotes.cjs} +2 -1
- package/dist/remotes.cjs.map +1 -0
- package/dist/remotes.d.cts +8 -0
- package/dist/remotes.d.mts +8 -0
- package/dist/{remotes/index.mjs → remotes.mjs} +2 -1
- package/dist/remotes.mjs.map +1 -0
- package/dist/{types-B2wwNWyo.d.cts → types-BDjKcTVR.d.cts} +6 -3
- package/dist/{types-BhTU1l2h.d.mts → types-CqkCJmt8.d.mts} +6 -3
- package/package.json +21 -15
- package/src/SchemaNode.ts +15 -19
- package/src/compileSchema.ts +1 -3
- package/src/errors/errors.ts +3 -2
- package/src/formats/additionalFormats.ts +118 -0
- package/src/formats/formats.ts +3 -111
- package/src/keywords/$defs.ts +3 -0
- package/src/keywords/additionalProperties.ts +1 -0
- package/src/keywords/allOf.ts +2 -5
- package/src/keywords/anyOf.ts +2 -4
- package/src/keywords/dependencies.ts +2 -0
- package/src/keywords/dependentSchemas.ts +2 -3
- package/src/keywords/format.ts +8 -0
- package/src/keywords/ifthenelse.ts +4 -9
- package/src/keywords/oneOf.ts +2 -5
- package/src/keywords/patternProperties.ts +5 -1
- package/src/keywords/prefixItems.ts +14 -9
- package/src/keywords/properties.ts +2 -3
- package/src/keywords/propertyDependencies.ts +2 -3
- package/src/keywords/propertyNames.ts +1 -1
- package/src/utils/collectValidationErrors.ts +9 -0
- package/src/validateSchema.test.ts +29 -30
- package/tsconfig.json +1 -0
- package/tsconfig.test.json +1 -0
- package/tsdown.config.ts +5 -2
- package/tsdown.iife.config.ts +29 -8
- package/dist/remotes/index.d.cts +0 -7
- package/dist/remotes/index.d.mts +0 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,28 @@
|
|
|
1
1
|
## Changelog
|
|
2
2
|
|
|
3
|
+
### v11.4.0
|
|
4
|
+
|
|
5
|
+
- added schema annotation on `compileSchema` for unknown format
|
|
6
|
+
- replaced option `withSchemaAnnotations` in favor of always creating all annotations
|
|
7
|
+
|
|
8
|
+
**Breaking change**: Moved some large format-validators to separate entry point:
|
|
9
|
+
|
|
10
|
+
- the following format-validators have been moved to a separate entry point "json-schema-library/formats": `hostname`, `idn-email`, `ipv4`, `ipv6`, `uri`, `uri-reference`, `uri-template`
|
|
11
|
+
- the following additional format-validators are available through "json-schema-library/formats": `iri`, `iri-reference`, `idn-hostname`
|
|
12
|
+
|
|
13
|
+
_Use the following to add the additional format validators to drafts per default:_
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { addFormats } from "json-schema-library/formats";
|
|
17
|
+
import { draft04, draft06, draft07, draft2019, draft2020 } from "json-schema-library";
|
|
18
|
+
// add additional formats to the following drafts
|
|
19
|
+
addFormats([draft04, draft06, draft07, draft2019, draft2020]);
|
|
20
|
+
```
|
|
21
|
+
|
|
3
22
|
### v11.3.0
|
|
4
23
|
|
|
5
|
-
- added option
|
|
6
|
-
- added properties to merge when
|
|
24
|
+
- added option `draft` as fallback for a missing `$schema` id
|
|
25
|
+
- added setting for properties to merge when resolving a `$ref` to `settings.PROPERTIES_TO_MERGE`
|
|
7
26
|
|
|
8
27
|
### v11.2.0
|
|
9
28
|
|
package/README.md
CHANGED
|
@@ -46,6 +46,11 @@ console.log(schemaNode.getDraftVersion()); // draft-07
|
|
|
46
46
|
|
|
47
47
|
## Overview
|
|
48
48
|
|
|
49
|
+
[compileSchema](#compileschema) ·
|
|
50
|
+
[validate input schema](#validate-input-schema) ·
|
|
51
|
+
[SchemaNode](#schemanode) ·
|
|
52
|
+
[Draft Support](#draft-support)
|
|
53
|
+
|
|
49
54
|
### compileSchema
|
|
50
55
|
|
|
51
56
|
Use `compileSchema` once to turn a JSON Schema into a tree of SchemaNodes. After that, you'll work with individual nodes in the tree. You can also pass an options object to `compileSchema` to customize how the nodes are created.
|
|
@@ -54,25 +59,25 @@ Use `compileSchema` once to turn a JSON Schema into a tree of SchemaNodes. After
|
|
|
54
59
|
type CompileOptions = {
|
|
55
60
|
// set of drafts to use
|
|
56
61
|
drafts: Draft[];
|
|
62
|
+
/** fallback draft version in case no draft_is specified by `schema.$schema` */
|
|
63
|
+
draft?: string;
|
|
57
64
|
// a context to share
|
|
58
65
|
remote: SchemaNode;
|
|
59
66
|
// if format-validations should create errors. Defaults to true
|
|
60
67
|
formatAssertion: boolean | "meta-schema";
|
|
61
68
|
/** set to true to throw an Error on errors in input schema. Defaults to false */
|
|
62
69
|
throwOnInvalidSchema?: boolean;
|
|
63
|
-
/** set to true to collect unknown keywords of input schema in `node.schemaAnnotations`. Defaults to false */
|
|
64
|
-
withSchemaAnnotations?: boolean;
|
|
65
70
|
/** set to true to throw an Error when encountering an unresolvable ref */
|
|
66
71
|
throwOnInvalidRef?: boolean;
|
|
67
72
|
// default options for all calls to node.getData()
|
|
68
73
|
getDataDefaultOptions?: {
|
|
69
|
-
//
|
|
74
|
+
// add all properties (required and optional) to the generated data
|
|
70
75
|
addOptionalProps?: boolean;
|
|
71
|
-
//
|
|
76
|
+
// remove data that does not match input schema. Defaults to false
|
|
72
77
|
removeInvalidData?: boolean;
|
|
73
|
-
//
|
|
78
|
+
// set to false to take default values as they are and not extend them. Defaults to true
|
|
74
79
|
extendDefaults?: boolean;
|
|
75
|
-
//
|
|
80
|
+
// limits how often a $ref should be followed before aborting. Prevents infinite data-structure. Defaults to 1
|
|
76
81
|
recursionLimit?: number;
|
|
77
82
|
};
|
|
78
83
|
};
|
|
@@ -251,7 +256,19 @@ Note that rootNodes will change when working across remote schema (using $ref).
|
|
|
251
256
|
|
|
252
257
|
### Draft Support
|
|
253
258
|
|
|
254
|
-
_json-schema-library_ fully supports all core features of draft versions draft-04, draft-06, draft-07, draft-2019-09 and draft-2020-12. Additionally,
|
|
259
|
+
_json-schema-library_ fully supports all core features of draft versions draft-04, draft-06, draft-07, draft-2019-09 and draft-2020-12. Additionally, all JSON Schema format validators are supported:
|
|
260
|
+
|
|
261
|
+
- The following formats are **available per default**: `date`, `date-time`, `duration`, `email`, `json-pointer`, `relative-json-pointer`, `regex`, `time`, `url`, `uuid`
|
|
262
|
+
- **Add remaining format** validators `hostname`, `idn-email`, `ipv4`, `ipv6`, `uri`, `uri-reference`, `uri-template` to drafts with:
|
|
263
|
+
|
|
264
|
+
```ts
|
|
265
|
+
import { addFormats } from "json-schema-library/formats";
|
|
266
|
+
import { draft04, draft06, draft07, draft2019, draft2020 } from "json-schema-library";
|
|
267
|
+
// add additional formats to the following drafts
|
|
268
|
+
addFormats([draft04, draft06, draft07, draft2019, draft2020]);
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
You can always override or extend format validation as is documented in [draft customization](#draft-customization).
|
|
255
272
|
|
|
256
273
|
<details><summary>Overview draft support</summary>
|
|
257
274
|
|
|
@@ -268,17 +285,6 @@ Please note that these benchmarks refer to validation only. _json-schema-library
|
|
|
268
285
|
|
|
269
286
|
</details>
|
|
270
287
|
|
|
271
|
-
<details><summary>Overview format validation support</summary>
|
|
272
|
-
|
|
273
|
-
---
|
|
274
|
-
|
|
275
|
-
- **`❌ unsupported formats`** iri, iri-reference, idn-hostname
|
|
276
|
-
- **`✅ supported formats`**: date, date-time, date, duration, ecmascript-regex, email, hostname, idn-email, ipv4, ipv6, json-pointer, regex, relative-json-pointer, time, unknown, uri-reference, uri-template, uri, uuid
|
|
277
|
-
|
|
278
|
-
---
|
|
279
|
-
|
|
280
|
-
</details>
|
|
281
|
-
|
|
282
288
|
## SchemaNode methods
|
|
283
289
|
|
|
284
290
|
[addRemoteSchema](#addremoteschema) ·
|
|
@@ -435,6 +441,22 @@ schemaNode.getNodeRef("https://sagold.com/remote#/properties/character");
|
|
|
435
441
|
const someNode = node.compileSchema({ prefixItems: [{ type: "string" }, { $ref: "#/$defs/string" }] });
|
|
436
442
|
```
|
|
437
443
|
|
|
444
|
+
#### custom error messages
|
|
445
|
+
|
|
446
|
+
You can set custom errors messages locally by using the errors-keyword:
|
|
447
|
+
|
|
448
|
+
```ts
|
|
449
|
+
const { errors } = compileSchema({
|
|
450
|
+
type: "array",
|
|
451
|
+
minItems: 2,
|
|
452
|
+
errorMessages: {
|
|
453
|
+
"min-items-error": "Custom error {{minItems}}"
|
|
454
|
+
}
|
|
455
|
+
}).validate([1]);
|
|
456
|
+
|
|
457
|
+
assert.deepEqual(errors[0].message, "Custom error 2");
|
|
458
|
+
```
|
|
459
|
+
|
|
438
460
|
### createSchema
|
|
439
461
|
|
|
440
462
|
`createSchema` returns a simple JSON Schema for the input data.
|
|
@@ -892,7 +914,8 @@ if (node) {
|
|
|
892
914
|
}
|
|
893
915
|
```
|
|
894
916
|
|
|
895
|
-
|
|
917
|
+
> [!CAUTION]
|
|
918
|
+
> `getNode` returns the root of the current schema. If a remote schema was resolved, the returned node will be the remote-schema root - not the initial schema-root you passed in to compileSchema
|
|
896
919
|
|
|
897
920
|
### reduceNode
|
|
898
921
|
|
|
@@ -1150,7 +1173,7 @@ console.log(errors); /// [{ code: "type-error", value: "data", pointer: "#", ...
|
|
|
1150
1173
|
|
|
1151
1174
|
## Draft Customization
|
|
1152
1175
|
|
|
1153
|
-
[
|
|
1176
|
+
[Extending a Draft](#extending-a-draft) · [Overwrite format validator](#overwrite-a-format-validator) · [Keyword](#keyword)
|
|
1154
1177
|
|
|
1155
1178
|
_json-schema-library_ uses the concept of **drafts** to support different versions of the JSON Schema specification — such as Draft 04, Draft 07, or 2020-12 — and to allow customization of schema behavior.
|
|
1156
1179
|
|
|
@@ -1549,21 +1572,7 @@ const myDraft = extendDraft(draft2020, {
|
|
|
1549
1572
|
});
|
|
1550
1573
|
```
|
|
1551
1574
|
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
You can set custom errors messages locally by using the errors-keyword:
|
|
1555
|
-
|
|
1556
|
-
```ts
|
|
1557
|
-
const { errors } = compileSchema({
|
|
1558
|
-
type: "array",
|
|
1559
|
-
minItems: 2,
|
|
1560
|
-
errorMessages: {
|
|
1561
|
-
"min-items-error": "Custom error {{minItems}}"
|
|
1562
|
-
}
|
|
1563
|
-
}).validate([1]);
|
|
1564
|
-
|
|
1565
|
-
assert.deepEqual(errors[0].message, "Custom error 2");
|
|
1566
|
-
```
|
|
1575
|
+
## Settings
|
|
1567
1576
|
|
|
1568
1577
|
### regexFlags
|
|
1569
1578
|
|
package/bowtie/bowtie.test.ts
CHANGED
|
@@ -14,6 +14,86 @@ const isErrorResponse = (value: unknown): value is ErrorResponse =>
|
|
|
14
14
|
const remote = compileSchema({ $id: "draft2020-12" });
|
|
15
15
|
remotes.map((schema: JsonSchema) => remote.addRemoteSchema(schema.$id ?? schema.id, schema));
|
|
16
16
|
|
|
17
|
+
describe("bowtie (draft4)", async () => {
|
|
18
|
+
before(async () => {
|
|
19
|
+
await runCommand({ cmd: "start", version: 1 });
|
|
20
|
+
await runCommand({ cmd: "dialect", dialect: "http://json-schema.org/draft-04/schema#" });
|
|
21
|
+
});
|
|
22
|
+
after(async () => runCommand({ cmd: "stop" }));
|
|
23
|
+
|
|
24
|
+
const registry = {
|
|
25
|
+
"http://localhost:1234/draft4/name.json": {
|
|
26
|
+
definitions: { orNull: { anyOf: [{ type: "null" }, { $ref: "#" }] } },
|
|
27
|
+
type: "string"
|
|
28
|
+
},
|
|
29
|
+
"http://localhost:1234/v1/nested-absolute-ref-to-string.json": {
|
|
30
|
+
$defs: { bar: { $id: "http://localhost:1234/v1/the-nested-id.json", type: "string" } },
|
|
31
|
+
$ref: "http://localhost:1234/v1/the-nested-id.json"
|
|
32
|
+
},
|
|
33
|
+
"http://localhost:1234/nested/string.json": { type: "string" },
|
|
34
|
+
"http://localhost:1234/baseUriChange/folderInteger.json": { type: "integer" },
|
|
35
|
+
"http://localhost:1234/draft4/subSchemas.json": {
|
|
36
|
+
definitions: { integer: { type: "integer" }, refToInteger: { $ref: "#/definitions/integer" } }
|
|
37
|
+
},
|
|
38
|
+
"http://localhost:1234/v1/different-id-ref-string.json": {
|
|
39
|
+
$id: "http://localhost:1234/v1/real-id-ref-string.json",
|
|
40
|
+
$defs: { bar: { type: "string" } },
|
|
41
|
+
$ref: "#/$defs/bar"
|
|
42
|
+
},
|
|
43
|
+
"http://localhost:1234/v1/urn-ref-string.json": {
|
|
44
|
+
$id: "urn:uuid:feebdaed-ffff-0000-ff01-0000deadbeef",
|
|
45
|
+
$defs: { bar: { type: "string" } },
|
|
46
|
+
$ref: "#/$defs/bar"
|
|
47
|
+
},
|
|
48
|
+
"http://localhost:1234/integer.json": { type: "integer" },
|
|
49
|
+
"http://localhost:1234/nested/foo-ref-string.json": {
|
|
50
|
+
type: "object",
|
|
51
|
+
properties: { foo: { $ref: "string.json" } }
|
|
52
|
+
},
|
|
53
|
+
"http://localhost:1234/baseUriChangeFolder/folderInteger.json": { type: "integer" },
|
|
54
|
+
"http://localhost:1234/draft4/locationIndependentIdentifier.json": {
|
|
55
|
+
definitions: { refToInteger: { $ref: "#foo" }, A: { id: "#foo", type: "integer" } }
|
|
56
|
+
},
|
|
57
|
+
"http://localhost:1234/baseUriChangeFolderInSubschema/folderInteger.json": { type: "integer" }
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
it("Location-independent identifier in remote ref - additional items match schema", async () => {
|
|
61
|
+
const response = await runCommand({
|
|
62
|
+
cmd: "run",
|
|
63
|
+
seq: 1,
|
|
64
|
+
case: {
|
|
65
|
+
description: "Location-independent identifier in remote ref",
|
|
66
|
+
schema: {
|
|
67
|
+
$ref: "http://localhost:1234/draft4/locationIndependentIdentifier.json#/definitions/refToInteger"
|
|
68
|
+
},
|
|
69
|
+
registry,
|
|
70
|
+
tests: [{ description: "integer is valid", instance: 1, valid: true }]
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
assert(isRunCmdResponse(response));
|
|
74
|
+
assert(!isErrorResponse(response.results[0]));
|
|
75
|
+
assert.equal(response.results[0].valid, true);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("Location-independent identifier in remote ref - additional items do not match schema", async () => {
|
|
79
|
+
const response = await runCommand({
|
|
80
|
+
cmd: "run",
|
|
81
|
+
seq: 1,
|
|
82
|
+
case: {
|
|
83
|
+
description: "Location-independent identifier in remote ref",
|
|
84
|
+
schema: {
|
|
85
|
+
$ref: "http://localhost:1234/draft4/locationIndependentIdentifier.json#/definitions/refToInteger"
|
|
86
|
+
},
|
|
87
|
+
registry,
|
|
88
|
+
tests: [{ description: "string is invalid", instance: "foo", valid: false }]
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
assert(isRunCmdResponse(response));
|
|
92
|
+
assert(!isErrorResponse(response.results[0]));
|
|
93
|
+
assert.equal(response.results[0].valid, false);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
17
97
|
describe("bowtie (draft7)", async () => {
|
|
18
98
|
before(async () => {
|
|
19
99
|
await runCommand({ cmd: "start", version: 1 });
|
package/bowtie/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),s=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=(n,r,a)=>(a=n==null?{}:e(i(n)),s(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return o}});
|