@hyperjump/json-schema 1.16.4 → 1.17.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 +105 -16
- package/annotations/annotated-instance.js +1 -1
- package/draft-04/format.js +31 -0
- package/draft-04/index.js +3 -1
- package/draft-06/format.js +34 -0
- package/draft-06/index.js +3 -1
- package/draft-07/format.js +42 -0
- package/draft-07/index.js +3 -1
- package/draft-2019-09/format-assertion.js +44 -0
- package/draft-2019-09/format.js +44 -0
- package/draft-2019-09/index.js +5 -1
- package/draft-2020-12/format-assertion.js +43 -0
- package/draft-2020-12/index.js +6 -2
- package/formats/handlers/date-time.js +7 -0
- package/formats/handlers/date.js +7 -0
- package/formats/handlers/draft-04/hostname.js +7 -0
- package/formats/handlers/duration.js +7 -0
- package/formats/handlers/email.js +7 -0
- package/formats/handlers/hostname.js +7 -0
- package/formats/handlers/idn-email.js +7 -0
- package/formats/handlers/idn-hostname.js +7 -0
- package/formats/handlers/ipv4.js +7 -0
- package/formats/handlers/ipv6.js +7 -0
- package/formats/handlers/iri-reference.js +7 -0
- package/formats/handlers/iri.js +7 -0
- package/formats/handlers/json-pointer.js +7 -0
- package/formats/handlers/regex.js +7 -0
- package/formats/handlers/relative-json-pointer.js +7 -0
- package/formats/handlers/time.js +7 -0
- package/formats/handlers/uri-reference.js +7 -0
- package/formats/handlers/uri-template.js +7 -0
- package/formats/handlers/uri.js +7 -0
- package/formats/handlers/uuid.js +7 -0
- package/formats/index.js +12 -0
- package/formats/lite.js +43 -0
- package/lib/configuration.js +7 -2
- package/lib/experimental.d.ts +8 -0
- package/lib/experimental.js +1 -0
- package/lib/keywords/dynamicRef.js +1 -1
- package/lib/keywords/format.js +35 -2
- package/lib/keywords.js +25 -3
- package/openapi-3-0/index.js +1 -1
- package/openapi-3-1/index.d.ts +66 -17
- package/openapi-3-1/schema-draft-2019-09.js +1 -1
- package/openapi-3-1/schema-draft-2020-12.js +1 -1
- package/openapi-3-2/dialect/base.js +2 -2
- package/openapi-3-2/index.d.ts +326 -2
- package/openapi-3-2/index.js +2 -4
- package/openapi-3-2/meta/base.js +30 -5
- package/openapi-3-2/schema-base.js +2 -3
- package/openapi-3-2/schema-draft-04.js +2 -2
- package/openapi-3-2/schema-draft-06.js +2 -2
- package/openapi-3-2/schema-draft-07.js +2 -2
- package/openapi-3-2/schema-draft-2019-09.js +3 -3
- package/openapi-3-2/schema-draft-2020-12.js +3 -3
- package/openapi-3-2/schema.js +1661 -1
- package/package.json +9 -5
- package/v1/extension-tests/conditional.json +289 -0
- package/v1/extension-tests/itemPattern.json +462 -0
- package/{stable → v1}/index.d.ts +2 -2
- package/{stable → v1}/index.js +25 -30
- package/{stable → v1}/meta/applicator.js +1 -3
- package/{stable → v1}/meta/content.js +1 -3
- package/{stable → v1}/meta/core.js +5 -4
- package/v1/meta/format.js +8 -0
- package/{stable → v1}/meta/meta-data.js +1 -3
- package/{stable → v1}/meta/unevaluated.js +1 -3
- package/{stable → v1}/meta/validation.js +1 -3
- package/v1/schema.js +24 -0
- package/stable/meta/format-annotation.js +0 -10
- package/stable/meta/format-assertion.js +0 -10
- package/stable/validation.js +0 -24
package/formats/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { addFormat } from "../lib/keywords.js";
|
|
2
|
+
|
|
3
|
+
import idnEmail from "./handlers/idn-email.js";
|
|
4
|
+
import hostname from "./handlers/hostname.js";
|
|
5
|
+
import idnHostname from "./handlers/idn-hostname.js";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
addFormat(idnEmail);
|
|
9
|
+
addFormat(hostname);
|
|
10
|
+
addFormat(idnHostname);
|
|
11
|
+
|
|
12
|
+
export * from "./lite.js";
|
package/formats/lite.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { addFormat } from "../lib/keywords.js";
|
|
2
|
+
|
|
3
|
+
import draft04Hostname from "./handlers/draft-04/hostname.js";
|
|
4
|
+
import dateTime from "./handlers/date-time.js";
|
|
5
|
+
import date from "./handlers/date.js";
|
|
6
|
+
import time from "./handlers/time.js";
|
|
7
|
+
import duration from "./handlers/duration.js";
|
|
8
|
+
import email from "./handlers/email.js";
|
|
9
|
+
import ipv4 from "./handlers/ipv4.js";
|
|
10
|
+
import ipv6 from "./handlers/ipv6.js";
|
|
11
|
+
import uri from "./handlers/uri.js";
|
|
12
|
+
import uriReference from "./handlers/uri-reference.js";
|
|
13
|
+
import iri from "./handlers/iri.js";
|
|
14
|
+
import iriReference from "./handlers/iri-reference.js";
|
|
15
|
+
import uuid from "./handlers/uuid.js";
|
|
16
|
+
import uriTemplate from "./handlers/uri-template.js";
|
|
17
|
+
import jsonPointer from "./handlers/json-pointer.js";
|
|
18
|
+
import relativeJsonPointer from "./handlers/relative-json-pointer.js";
|
|
19
|
+
import regex from "./handlers/regex.js";
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
addFormat(draft04Hostname);
|
|
23
|
+
addFormat(dateTime);
|
|
24
|
+
addFormat(date);
|
|
25
|
+
addFormat(time);
|
|
26
|
+
addFormat(duration);
|
|
27
|
+
addFormat(email);
|
|
28
|
+
addFormat(ipv4);
|
|
29
|
+
addFormat(ipv6);
|
|
30
|
+
addFormat(uri);
|
|
31
|
+
addFormat(uriReference);
|
|
32
|
+
addFormat(iri);
|
|
33
|
+
addFormat(iriReference);
|
|
34
|
+
addFormat(uuid);
|
|
35
|
+
addFormat(uriTemplate);
|
|
36
|
+
addFormat(jsonPointer);
|
|
37
|
+
addFormat(relativeJsonPointer);
|
|
38
|
+
addFormat(regex);
|
|
39
|
+
|
|
40
|
+
export {
|
|
41
|
+
getShouldValidateFormat,
|
|
42
|
+
setShouldValidateFormat
|
|
43
|
+
} from "../lib/configuration.js";
|
package/lib/configuration.js
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
let metaSchemaOutputFormat;
|
|
2
|
-
let shouldValidateSchema = true;
|
|
3
|
-
|
|
4
2
|
export const getMetaSchemaOutputFormat = () => metaSchemaOutputFormat;
|
|
5
3
|
export const setMetaSchemaOutputFormat = (format) => {
|
|
6
4
|
metaSchemaOutputFormat = format;
|
|
7
5
|
};
|
|
8
6
|
|
|
7
|
+
let shouldValidateSchema = true;
|
|
9
8
|
export const getShouldValidateSchema = () => shouldValidateSchema;
|
|
10
9
|
export const setShouldValidateSchema = (isEnabled) => {
|
|
11
10
|
shouldValidateSchema = isEnabled;
|
|
12
11
|
};
|
|
12
|
+
|
|
13
|
+
let shouldValidateFormat;
|
|
14
|
+
export const getShouldValidateFormat = () => shouldValidateFormat;
|
|
15
|
+
export const setShouldValidateFormat = (isEnabled) => {
|
|
16
|
+
shouldValidateFormat = isEnabled;
|
|
17
|
+
};
|
package/lib/experimental.d.ts
CHANGED
|
@@ -61,11 +61,19 @@ export const getKeywordName: (dialectId: string, keywordId: string) => string;
|
|
|
61
61
|
export const getKeyword: <A>(id: string) => Keyword<A>;
|
|
62
62
|
export const getKeywordByName: <A>(keywordName: string, dialectId: string) => Keyword<A>;
|
|
63
63
|
export const getKeywordId: (keywordName: string, dialectId: string) => string;
|
|
64
|
+
export const addFormat: (format: Format) => void;
|
|
65
|
+
export const setFormatHandler: (keywordUri: string, formatName: string, formatUri: string) => void;
|
|
66
|
+
export const removeFormatHandler: (keywordUri: string, formatName: string) => void;
|
|
64
67
|
export const defineVocabulary: (id: string, keywords: Record<string, string>) => void;
|
|
65
68
|
export const loadDialect: (dialectId: string, dialect: Record<string, boolean>, allowUnknownKeywords?: boolean) => void;
|
|
66
69
|
export const unloadDialect: (dialectId: string) => void;
|
|
67
70
|
export const hasDialect: (dialectId: string) => boolean;
|
|
68
71
|
|
|
72
|
+
export type Format = {
|
|
73
|
+
id: string;
|
|
74
|
+
handler: (value: Json) => boolean;
|
|
75
|
+
};
|
|
76
|
+
|
|
69
77
|
export type Keyword<A, Context extends ValidationContext = ValidationContext> = {
|
|
70
78
|
id: string;
|
|
71
79
|
compile: (schema: Browser<SchemaDocument>, ast: AST, parentSchema: Browser<SchemaDocument>) => Promise<A>;
|
package/lib/experimental.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { compile, interpret, BASIC, DETAILED } from "./core.js";
|
|
2
2
|
export {
|
|
3
3
|
addKeyword, getKeyword, getKeywordByName, getKeywordName, getKeywordId,
|
|
4
|
+
addFormat, setFormatHandler, removeFormatHandler,
|
|
4
5
|
defineVocabulary,
|
|
5
6
|
loadDialect, unloadDialect, hasDialect
|
|
6
7
|
} from "./keywords.js";
|
|
@@ -10,7 +10,7 @@ const compile = async (schema, ast) => {
|
|
|
10
10
|
const self = await Browser.get(schema.document.baseUri, schema);
|
|
11
11
|
await Validation.compile(self, ast);
|
|
12
12
|
|
|
13
|
-
return reference;
|
|
13
|
+
return reference.startsWith("#") ? reference.slice(1) : reference;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
const interpret = (fragment, instance, context) => {
|
package/lib/keywords/format.js
CHANGED
|
@@ -1,10 +1,43 @@
|
|
|
1
1
|
import * as Browser from "@hyperjump/browser";
|
|
2
|
+
import * as Instance from "../instance.js";
|
|
3
|
+
import { getFormatHandler } from "../keywords.js";
|
|
2
4
|
|
|
3
5
|
|
|
4
6
|
const id = "https://json-schema.org/keyword/format";
|
|
5
7
|
|
|
6
8
|
const compile = (schema) => Browser.value(schema);
|
|
7
|
-
|
|
9
|
+
|
|
10
|
+
const interpret = (format, instance) => {
|
|
11
|
+
const handler = getFormatHandler(formats[format]);
|
|
12
|
+
if (!handler) {
|
|
13
|
+
throw Error(`The '${format}' format is not supported.`);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return handler(Instance.value(instance));
|
|
17
|
+
};
|
|
18
|
+
|
|
8
19
|
const annotation = (format) => format;
|
|
9
20
|
|
|
10
|
-
|
|
21
|
+
const formats = {
|
|
22
|
+
"date-time": "https://json-schema.org/format/date-time",
|
|
23
|
+
"date": "https://json-schema.org/format/date",
|
|
24
|
+
"time": "https://json-schema.org/format/time",
|
|
25
|
+
"duration": "https://json-schema.org/format/duration",
|
|
26
|
+
"email": "https://json-schema.org/format/email",
|
|
27
|
+
"idn-email": "https://json-schema.org/format/idn-email",
|
|
28
|
+
"hostname": "https://json-schema.org/format/hostname",
|
|
29
|
+
"idn-hostname": "https://json-schema.org/format/idn-hostname",
|
|
30
|
+
"ipv4": "https://json-schema.org/format/ipv4",
|
|
31
|
+
"ipv6": "https://json-schema.org/format/ipv6",
|
|
32
|
+
"uri": "https://json-schema.org/format/uri",
|
|
33
|
+
"uri-reference": "https://json-schema.org/format/uri-reference",
|
|
34
|
+
"iri": "https://json-schema.org/format/iri",
|
|
35
|
+
"iri-reference": "https://json-schema.org/format/iri-reference",
|
|
36
|
+
"uuid": "https://json-schema.org/format/uuid",
|
|
37
|
+
"uri-template": "https://json-schema.org/format/uri-template",
|
|
38
|
+
"json-pointer": "https://json-schema.org/format/json-pointer",
|
|
39
|
+
"relative-json-pointer": "https://json-schema.org/format/relative-json-pointer",
|
|
40
|
+
"regex": "https://json-schema.org/format/regex"
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export default { id, compile, interpret, annotation, formats };
|
package/lib/keywords.js
CHANGED
|
@@ -34,6 +34,23 @@ export const defineVocabulary = (id, keywords) => {
|
|
|
34
34
|
_vocabularies[id] = keywords;
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
+
const _formats = {};
|
|
38
|
+
export const addFormat = (format) => {
|
|
39
|
+
_formats[format.id] = format.handler;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const getFormatHandler = (formatUri) => {
|
|
43
|
+
return _formats[formatUri];
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const setFormatHandler = (keywordUri, formatName, formatUri) => {
|
|
47
|
+
_keywords[keywordUri].formats[formatName] = formatUri;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export const removeFormatHandler = (keywordUri, formatName) => {
|
|
51
|
+
delete _keywords[keywordUri].formats[formatName];
|
|
52
|
+
};
|
|
53
|
+
|
|
37
54
|
const _dialects = {};
|
|
38
55
|
|
|
39
56
|
export const getKeywordId = (keyword, dialectId) => {
|
|
@@ -74,9 +91,14 @@ export const loadDialect = (dialectId, dialect, allowUnknownKeywords = false, is
|
|
|
74
91
|
if (vocabularyId in _vocabularies) {
|
|
75
92
|
for (const keyword in _vocabularies[vocabularyId]) {
|
|
76
93
|
let keywordId = _vocabularies[vocabularyId][keyword];
|
|
77
|
-
if (!
|
|
78
|
-
|
|
79
|
-
|
|
94
|
+
if (!dialect[vocabularyId]) {
|
|
95
|
+
if (vocabularyId === "https://json-schema.org/draft/2019-09/vocab/format") {
|
|
96
|
+
// Handle inconsistent 2019-09 behavior
|
|
97
|
+
keywordId = "https://json-schema.org/keyword/draft-2019-09/format";
|
|
98
|
+
} else if (!(keywordId in _keywords)) {
|
|
99
|
+
// Allow keyword to be ignored
|
|
100
|
+
keywordId = `https://json-schema.org/keyword/unknown#${keyword}`;
|
|
101
|
+
}
|
|
80
102
|
}
|
|
81
103
|
_dialects[dialectId].keywords[keyword] = keywordId;
|
|
82
104
|
}
|
package/openapi-3-0/index.js
CHANGED
|
@@ -38,7 +38,7 @@ defineVocabulary(jsonSchemaVersion, {
|
|
|
38
38
|
"exclusiveMaximum": "https://json-schema.org/keyword/draft-04/exclusiveMaximum",
|
|
39
39
|
"exclusiveMinimum": "https://json-schema.org/keyword/draft-04/exclusiveMinimum",
|
|
40
40
|
"externalDocs": "https://spec.openapis.org/oas/3.0/keyword/externalDocs",
|
|
41
|
-
"format": "https://json-schema.org/keyword/format",
|
|
41
|
+
"format": "https://json-schema.org/keyword/draft-04/format",
|
|
42
42
|
"items": "https://json-schema.org/keyword/draft-04/items",
|
|
43
43
|
"maxItems": "https://json-schema.org/keyword/maxItems",
|
|
44
44
|
"maxLength": "https://json-schema.org/keyword/maxLength",
|
package/openapi-3-1/index.d.ts
CHANGED
|
@@ -180,18 +180,55 @@ type ExternalDocumentation = {
|
|
|
180
180
|
url: string;
|
|
181
181
|
};
|
|
182
182
|
|
|
183
|
-
type Parameter = {
|
|
183
|
+
export type Parameter = {
|
|
184
184
|
name: string;
|
|
185
|
-
in: "query" | "header" | "path" | "cookie";
|
|
186
185
|
description?: string;
|
|
187
186
|
required?: boolean;
|
|
188
187
|
deprecated?: boolean;
|
|
189
188
|
allowEmptyValue?: boolean;
|
|
190
|
-
|
|
189
|
+
} & (
|
|
190
|
+
(
|
|
191
|
+
{
|
|
192
|
+
in: "path";
|
|
193
|
+
required: true;
|
|
194
|
+
} & (
|
|
195
|
+
({ style?: "matrix" | "label" | "simple" } & SchemaParameter)
|
|
196
|
+
| ContentParameter
|
|
197
|
+
)
|
|
198
|
+
) | (
|
|
199
|
+
{
|
|
200
|
+
in: "query";
|
|
201
|
+
} & (
|
|
202
|
+
({ style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject" } & SchemaParameter)
|
|
203
|
+
| ContentParameter
|
|
204
|
+
)
|
|
205
|
+
) | (
|
|
206
|
+
{
|
|
207
|
+
in: "header";
|
|
208
|
+
} & (
|
|
209
|
+
({ style?: "simple" } & SchemaParameter)
|
|
210
|
+
| ContentParameter
|
|
211
|
+
)
|
|
212
|
+
) | (
|
|
213
|
+
{
|
|
214
|
+
in: "cookie";
|
|
215
|
+
} & (
|
|
216
|
+
({ style?: "form" } & SchemaParameter)
|
|
217
|
+
| ContentParameter
|
|
218
|
+
)
|
|
219
|
+
)
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
type ContentParameter = {
|
|
223
|
+
schema?: never;
|
|
224
|
+
content: Record<string, MediaType | Reference>;
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
type SchemaParameter = {
|
|
191
228
|
explode?: boolean;
|
|
192
229
|
allowReserved?: boolean;
|
|
193
|
-
schema
|
|
194
|
-
content?:
|
|
230
|
+
schema: OasSchema32;
|
|
231
|
+
content?: never;
|
|
195
232
|
} & Examples;
|
|
196
233
|
|
|
197
234
|
type RequestBody = {
|
|
@@ -237,7 +274,7 @@ type Link = {
|
|
|
237
274
|
parameters?: Record<string, string>;
|
|
238
275
|
requestBody?: Json;
|
|
239
276
|
description?: string;
|
|
240
|
-
|
|
277
|
+
server?: Server;
|
|
241
278
|
};
|
|
242
279
|
|
|
243
280
|
type Header = {
|
|
@@ -259,25 +296,37 @@ type Tag = {
|
|
|
259
296
|
type Reference = {
|
|
260
297
|
$ref: string;
|
|
261
298
|
summary?: string;
|
|
262
|
-
|
|
299
|
+
description?: string;
|
|
263
300
|
};
|
|
264
301
|
|
|
265
302
|
type SecurityScheme = {
|
|
266
|
-
type: "apiKey"
|
|
303
|
+
type: "apiKey";
|
|
267
304
|
description?: string;
|
|
268
|
-
name
|
|
269
|
-
in
|
|
270
|
-
|
|
305
|
+
name: string;
|
|
306
|
+
in: "query" | "header" | "cookie";
|
|
307
|
+
} | {
|
|
308
|
+
type: "http";
|
|
309
|
+
description?: string;
|
|
310
|
+
scheme: string;
|
|
271
311
|
bearerFormat?: string;
|
|
272
|
-
|
|
273
|
-
|
|
312
|
+
} | {
|
|
313
|
+
type: "mutualTLS";
|
|
314
|
+
description?: string;
|
|
315
|
+
} | {
|
|
316
|
+
type: "oauth2";
|
|
317
|
+
description?: string;
|
|
318
|
+
flows: OauthFlows;
|
|
319
|
+
} | {
|
|
320
|
+
type: "openIdConnect";
|
|
321
|
+
description?: string;
|
|
322
|
+
openIdConnectUrl: string;
|
|
274
323
|
};
|
|
275
324
|
|
|
276
325
|
type OauthFlows = {
|
|
277
|
-
implicit
|
|
278
|
-
|
|
279
|
-
clientCredentials
|
|
280
|
-
authorizationCode
|
|
326
|
+
implicit?: Implicit;
|
|
327
|
+
password?: Password;
|
|
328
|
+
clientCredentials?: ClientCredentials;
|
|
329
|
+
authorizationCode?: AuthorizationCode;
|
|
281
330
|
};
|
|
282
331
|
|
|
283
332
|
type Implicit = {
|
|
@@ -23,7 +23,7 @@ export default {
|
|
|
23
23
|
"dialect": { "const": "https://json-schema.org/draft/2019-09/schema" },
|
|
24
24
|
|
|
25
25
|
"schema": {
|
|
26
|
-
"$
|
|
26
|
+
"$dynamicAnchor": "meta",
|
|
27
27
|
"$ref": "https://spec.openapis.org/oas/3.1/dialect/base",
|
|
28
28
|
"properties": {
|
|
29
29
|
"$schema": { "$ref": "#/$defs/dialect" }
|
|
@@ -23,7 +23,7 @@ export default {
|
|
|
23
23
|
"dialect": { "const": "https://json-schema.org/draft/2020-12/schema" },
|
|
24
24
|
|
|
25
25
|
"schema": {
|
|
26
|
-
"$
|
|
26
|
+
"$dynamicAnchor": "meta",
|
|
27
27
|
"$ref": "https://spec.openapis.org/oas/3.1/dialect/base",
|
|
28
28
|
"properties": {
|
|
29
29
|
"$schema": { "$ref": "#/$defs/dialect" }
|
|
@@ -13,10 +13,10 @@ export default {
|
|
|
13
13
|
"$dynamicAnchor": "meta",
|
|
14
14
|
|
|
15
15
|
"title": "OpenAPI 3.2 Schema Object Dialect",
|
|
16
|
-
"description": "A JSON Schema dialect describing schemas found in OpenAPI v3.2 Descriptions",
|
|
16
|
+
"description": "A JSON Schema dialect describing schemas found in OpenAPI v3.2.x Descriptions",
|
|
17
17
|
|
|
18
18
|
"allOf": [
|
|
19
19
|
{ "$ref": "https://json-schema.org/draft/2020-12/schema" },
|
|
20
|
-
{ "$ref": "https://spec.openapis.org/oas/3.2/meta
|
|
20
|
+
{ "$ref": "https://spec.openapis.org/oas/3.2/meta" }
|
|
21
21
|
]
|
|
22
22
|
};
|