@hyperjump/json-schema 1.0.0 → 1.1.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 +29 -0
- package/lib/openapi.js +29 -0
- package/openapi-3-0/dialect.js +174 -0
- package/openapi-3-0/discriminator.js +4 -0
- package/openapi-3-0/example.js +4 -0
- package/openapi-3-0/externalDocs.js +4 -0
- package/openapi-3-0/index.d.ts +60 -0
- package/openapi-3-0/index.js +77 -0
- package/openapi-3-0/nullable.js +4 -0
- package/openapi-3-0/schema/2021-09-28.js +1404 -0
- package/openapi-3-0/type.js +16 -0
- package/openapi-3-0/xml.js +4 -0
- package/openapi-3-1/dialect/base.js +21 -0
- package/openapi-3-1/index.d.ts +88 -0
- package/openapi-3-1/index.js +48 -0
- package/openapi-3-1/meta/base.js +76 -0
- package/openapi-3-1/schema/2022-10-07.js +1440 -0
- package/openapi-3-1/schema-base/2022-10-07.js +23 -0
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -4,6 +4,10 @@ A collection of modules for working with JSON Schemas.
|
|
|
4
4
|
|
|
5
5
|
* Validate JSON-compatible values against a JSON Schema
|
|
6
6
|
* Dialects: draft-2020-12, draft-2019-09, draft-07, draft-06, draft-04
|
|
7
|
+
* OpenAPI
|
|
8
|
+
* Versions/Dialects: 3.0, 3.1
|
|
9
|
+
* Validate an OpenAPI document
|
|
10
|
+
* Validate values against a schema from an OpenAPI document
|
|
7
11
|
* Schemas can reference other schemas using a different dialect
|
|
8
12
|
* Work directly with schemas on the filesystem or HTTP
|
|
9
13
|
* Create custom keywords, vocabularies, and dialects
|
|
@@ -126,6 +130,31 @@ const isString = await validate(`file://${__dirname}/string.schema.yaml`);
|
|
|
126
130
|
const output = isString("foo");
|
|
127
131
|
```
|
|
128
132
|
|
|
133
|
+
**Open API**
|
|
134
|
+
|
|
135
|
+
The OpenAPI 3.0 and 3.1 meta-schemas are pre-loaded and the OpenAPI JSON Schema
|
|
136
|
+
dialects for each of those versions is supported. A document with a Content-Type
|
|
137
|
+
of `application/openapi+json` (web) or a file extension of `openapi.json`
|
|
138
|
+
(filesystem) is understood as an OpenAPI document.
|
|
139
|
+
|
|
140
|
+
Use the pattern `@hyperjump/json-schema/*` to import the version you need. The
|
|
141
|
+
available versions are `openapi-3-0` for 3.0 and `openapi-3-1` for 3.1.
|
|
142
|
+
|
|
143
|
+
YAML support isn't built in, but you can add it by writing a MediaTypePlugin.
|
|
144
|
+
You can use the one at `lib/openapi.js` as an example and replacing the JSON
|
|
145
|
+
parts with YAML.
|
|
146
|
+
|
|
147
|
+
```javascript
|
|
148
|
+
import { addSchema, validate } from "@hyperjump/json-schema/openapi-3-1";
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
// Validate an OpenAPI document
|
|
152
|
+
const output = await validate("https://spec.openapis.org/oas/3.1/schema-base", openapi);
|
|
153
|
+
|
|
154
|
+
// Validate an instance against a schema in an OpenAPI document
|
|
155
|
+
const output = await validate(`file://${__dirname}/example.openapi.json#/components/schemas/foo`, 42);
|
|
156
|
+
```
|
|
157
|
+
|
|
129
158
|
## API
|
|
130
159
|
These are available from any of the exports that refer to a version of JSON
|
|
131
160
|
Schema, such as `@hyperjump/json-schema/draft-2020-12`.
|
package/lib/openapi.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { addMediaTypePlugin } from "./media-types.js";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
const is31 = RegExp.prototype.test.bind(/^3\.1\.\d+(-.+)?$/);
|
|
5
|
+
const is30 = RegExp.prototype.test.bind(/^3\.0\.\d+(-.+)?$/);
|
|
6
|
+
|
|
7
|
+
addMediaTypePlugin("application/openapi+json", {
|
|
8
|
+
parse: async (response, contentTypeParameters) => {
|
|
9
|
+
const doc = await response.json();
|
|
10
|
+
|
|
11
|
+
let defaultDialect;
|
|
12
|
+
const version = doc.openapi || contentTypeParameters.version;
|
|
13
|
+
|
|
14
|
+
if (is30(version)) {
|
|
15
|
+
defaultDialect = "https://spec.openapis.org/oas/3.0/schema";
|
|
16
|
+
} else if (is31(version)) {
|
|
17
|
+
if (!("jsonSchemaDialect" in doc) || doc.jsonSchemaDialect === "https://spec.openapis.org/oas/3.1/dialect/base") {
|
|
18
|
+
defaultDialect = "https://spec.openapis.org/oas/3.1/schema-base";
|
|
19
|
+
} else {
|
|
20
|
+
defaultDialect = `https://spec.openapis.org/oas/3.1/schema-${encodeURIComponent(doc.jsonSchemaDialect)}`;
|
|
21
|
+
}
|
|
22
|
+
} else {
|
|
23
|
+
throw Error("Invalid OpenAPI document. Add the 'openapi' field and try again.");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return [doc, defaultDialect];
|
|
27
|
+
},
|
|
28
|
+
matcher: (path) => /(\/|\.)openapi\.json$/.test(path)
|
|
29
|
+
});
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
"id": "https://spec.openapis.org/oas/3.0/dialect",
|
|
3
|
+
"$schema": "http://json-schema.org/draft-04/schema#",
|
|
4
|
+
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"title": { "type": "string" },
|
|
8
|
+
"multipleOf": {
|
|
9
|
+
"type": "number",
|
|
10
|
+
"minimum": 0,
|
|
11
|
+
"exclusiveMinimum": true
|
|
12
|
+
},
|
|
13
|
+
"maximum": { "type": "number" },
|
|
14
|
+
"exclusiveMaximum": {
|
|
15
|
+
"type": "boolean",
|
|
16
|
+
"default": false
|
|
17
|
+
},
|
|
18
|
+
"minimum": { "type": "number" },
|
|
19
|
+
"exclusiveMinimum": {
|
|
20
|
+
"type": "boolean",
|
|
21
|
+
"default": false
|
|
22
|
+
},
|
|
23
|
+
"maxLength": { "$ref": "#/definitions/positiveInteger" },
|
|
24
|
+
"minLength": { "$ref": "#/definitions/positiveIntegerDefault0" },
|
|
25
|
+
"pattern": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"format": "regex"
|
|
28
|
+
},
|
|
29
|
+
"maxItems": { "$ref": "#/definitions/positiveInteger" },
|
|
30
|
+
"minItems": { "$ref": "#/definitions/positiveIntegerDefault0" },
|
|
31
|
+
"uniqueItems": {
|
|
32
|
+
"type": "boolean",
|
|
33
|
+
"default": false
|
|
34
|
+
},
|
|
35
|
+
"maxProperties": { "$ref": "#/definitions/positiveInteger" },
|
|
36
|
+
"minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" },
|
|
37
|
+
"required": {
|
|
38
|
+
"type": "array",
|
|
39
|
+
"items": { "type": "string" },
|
|
40
|
+
"minItems": 1,
|
|
41
|
+
"uniqueItems": true
|
|
42
|
+
},
|
|
43
|
+
"enum": {
|
|
44
|
+
"type": "array",
|
|
45
|
+
"minItems": 1,
|
|
46
|
+
"uniqueItems": false
|
|
47
|
+
},
|
|
48
|
+
"type": { "enum": ["array", "boolean", "integer", "number", "object", "string"] },
|
|
49
|
+
"not": { "$ref": "#" },
|
|
50
|
+
"allOf": { "$ref": "#/definitions/schemaArray" },
|
|
51
|
+
"oneOf": { "$ref": "#/definitions/schemaArray" },
|
|
52
|
+
"anyOf": { "$ref": "#/definitions/schemaArray" },
|
|
53
|
+
"items": { "$ref": "#" },
|
|
54
|
+
"properties": {
|
|
55
|
+
"type": "object",
|
|
56
|
+
"additionalProperties": { "$ref": "#" }
|
|
57
|
+
},
|
|
58
|
+
"additionalProperties": {
|
|
59
|
+
"anyOf": [
|
|
60
|
+
{ "type": "boolean" },
|
|
61
|
+
{ "$ref": "#" }
|
|
62
|
+
],
|
|
63
|
+
"default": {}
|
|
64
|
+
},
|
|
65
|
+
"description": { "type": "string" },
|
|
66
|
+
"format": { "type": "string" },
|
|
67
|
+
"default": {},
|
|
68
|
+
"nullable": {
|
|
69
|
+
"type": "boolean",
|
|
70
|
+
"default": false
|
|
71
|
+
},
|
|
72
|
+
"discriminator": { "$ref": "#/definitions/Discriminator" },
|
|
73
|
+
"readOnly": {
|
|
74
|
+
"type": "boolean",
|
|
75
|
+
"default": false
|
|
76
|
+
},
|
|
77
|
+
"writeOnly": {
|
|
78
|
+
"type": "boolean",
|
|
79
|
+
"default": false
|
|
80
|
+
},
|
|
81
|
+
"example": {},
|
|
82
|
+
"externalDocs": { "$ref": "#/definitions/ExternalDocumentation" },
|
|
83
|
+
"deprecated": {
|
|
84
|
+
"type": "boolean",
|
|
85
|
+
"default": false
|
|
86
|
+
},
|
|
87
|
+
"xml": { "$ref": "#/definitions/XML" },
|
|
88
|
+
"$ref": {
|
|
89
|
+
"type": "string",
|
|
90
|
+
"format": "uri"
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"patternProperties": {
|
|
94
|
+
"^x-": {}
|
|
95
|
+
},
|
|
96
|
+
"additionalProperties": false,
|
|
97
|
+
|
|
98
|
+
"anyOf": [
|
|
99
|
+
{
|
|
100
|
+
"not": { "required": ["$ref"] }
|
|
101
|
+
},
|
|
102
|
+
{ "maxProperties": 1 }
|
|
103
|
+
],
|
|
104
|
+
|
|
105
|
+
"definitions": {
|
|
106
|
+
"schemaArray": {
|
|
107
|
+
"type": "array",
|
|
108
|
+
"minItems": 1,
|
|
109
|
+
"items": { "$ref": "#" }
|
|
110
|
+
},
|
|
111
|
+
"positiveInteger": {
|
|
112
|
+
"type": "integer",
|
|
113
|
+
"minimum": 0
|
|
114
|
+
},
|
|
115
|
+
"positiveIntegerDefault0": {
|
|
116
|
+
"allOf": [{ "$ref": "#/definitions/positiveInteger" }, { "default": 0 }]
|
|
117
|
+
},
|
|
118
|
+
"Discriminator": {
|
|
119
|
+
"type": "object",
|
|
120
|
+
"required": [
|
|
121
|
+
"propertyName"
|
|
122
|
+
],
|
|
123
|
+
"properties": {
|
|
124
|
+
"propertyName": {
|
|
125
|
+
"type": "string"
|
|
126
|
+
},
|
|
127
|
+
"mapping": {
|
|
128
|
+
"type": "object",
|
|
129
|
+
"additionalProperties": {
|
|
130
|
+
"type": "string"
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
"ExternalDocumentation": {
|
|
136
|
+
"type": "object",
|
|
137
|
+
"required": ["url"],
|
|
138
|
+
"properties": {
|
|
139
|
+
"description": { "type": "string" },
|
|
140
|
+
"url": {
|
|
141
|
+
"type": "string",
|
|
142
|
+
"format": "uri-reference"
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
"patternProperties": {
|
|
146
|
+
"^x-": {}
|
|
147
|
+
},
|
|
148
|
+
"additionalProperties": false
|
|
149
|
+
},
|
|
150
|
+
"XML": {
|
|
151
|
+
"type": "object",
|
|
152
|
+
"properties": {
|
|
153
|
+
"name": { "type": "string" },
|
|
154
|
+
"namespace": {
|
|
155
|
+
"type": "string",
|
|
156
|
+
"format": "uri"
|
|
157
|
+
},
|
|
158
|
+
"prefix": { "type": "string" },
|
|
159
|
+
"attribute": {
|
|
160
|
+
"type": "boolean",
|
|
161
|
+
"default": false
|
|
162
|
+
},
|
|
163
|
+
"wrapped": {
|
|
164
|
+
"type": "boolean",
|
|
165
|
+
"default": false
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
"patternProperties": {
|
|
169
|
+
"^x-": {}
|
|
170
|
+
},
|
|
171
|
+
"additionalProperties": false
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { Json } from "@hyperjump/json-pointer";
|
|
2
|
+
import type { JsonSchemaType } from "../lib/common.js";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export type OasSchema30 = {
|
|
6
|
+
$ref: string;
|
|
7
|
+
} | {
|
|
8
|
+
title?: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
default?: Json;
|
|
11
|
+
multipleOf?: number;
|
|
12
|
+
maximum?: number;
|
|
13
|
+
exclusiveMaximum?: boolean;
|
|
14
|
+
minimum?: number;
|
|
15
|
+
exclusiveMinimum?: boolean;
|
|
16
|
+
maxLength?: number;
|
|
17
|
+
minLength?: number;
|
|
18
|
+
pattern?: string;
|
|
19
|
+
items?: OasSchema30;
|
|
20
|
+
maxItems?: number;
|
|
21
|
+
minItems?: number;
|
|
22
|
+
uniqueItems?: boolean;
|
|
23
|
+
maxProperties?: number;
|
|
24
|
+
minProperties?: number;
|
|
25
|
+
required?: string[];
|
|
26
|
+
additionalProperties?: boolean | OasSchema30;
|
|
27
|
+
properties?: Record<string, OasSchema30>;
|
|
28
|
+
enum?: Json[];
|
|
29
|
+
type?: JsonSchemaType;
|
|
30
|
+
nullable?: boolean;
|
|
31
|
+
format?: "date-time" | "email" | "hostname" | "ipv4" | "ipv6" | "uri" | "int32" | "int64" | "float" | "double" | "byte" | "binary" | "date" | "password";
|
|
32
|
+
allOf?: OasSchema30[];
|
|
33
|
+
anyOf?: OasSchema30[];
|
|
34
|
+
oneOf?: OasSchema30[];
|
|
35
|
+
not?: OasSchema30;
|
|
36
|
+
example: Json;
|
|
37
|
+
discriminator: Discriminator;
|
|
38
|
+
externalDocs: ExternalDocs;
|
|
39
|
+
xml: Xml;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
type Discriminator = {
|
|
43
|
+
propertyName: string;
|
|
44
|
+
mappings: Record<string, string>;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
type ExternalDocs = {
|
|
48
|
+
url: string;
|
|
49
|
+
description: string;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
type Xml = {
|
|
53
|
+
name: string;
|
|
54
|
+
namespace: string;
|
|
55
|
+
prefix: string;
|
|
56
|
+
attribute: boolean;
|
|
57
|
+
wrapped: boolean;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export * from "../lib/index.js";
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { addKeyword, defineVocabulary, loadDialect } from "../lib/keywords.js";
|
|
2
|
+
import { addSchema } from "../lib/core.js";
|
|
3
|
+
import "../lib/openapi.js";
|
|
4
|
+
|
|
5
|
+
import dialectSchema from "./dialect.js";
|
|
6
|
+
import schema20210928 from "./schema/2021-09-28.js";
|
|
7
|
+
|
|
8
|
+
import discriminator from "./discriminator.js";
|
|
9
|
+
import example from "./example.js";
|
|
10
|
+
import externalDocs from "./externalDocs.js";
|
|
11
|
+
import nullable from "./nullable.js";
|
|
12
|
+
import type from "./type.js";
|
|
13
|
+
import xml from "./xml.js";
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
addKeyword(discriminator);
|
|
17
|
+
addKeyword(example);
|
|
18
|
+
addKeyword(externalDocs);
|
|
19
|
+
addKeyword(nullable);
|
|
20
|
+
addKeyword(type);
|
|
21
|
+
addKeyword(xml);
|
|
22
|
+
|
|
23
|
+
const jsonSchemaVersion = "https://spec.openapis.org/oas/3.0/dialect";
|
|
24
|
+
|
|
25
|
+
defineVocabulary(jsonSchemaVersion, {
|
|
26
|
+
"$ref": "https://json-schema.org/keyword/draft-04/ref",
|
|
27
|
+
"additionalProperties": "https://json-schema.org/keyword/additionalProperties",
|
|
28
|
+
"allOf": "https://json-schema.org/keyword/allOf",
|
|
29
|
+
"anyOf": "https://json-schema.org/keyword/anyOf",
|
|
30
|
+
"default": "https://json-schema.org/keyword/default",
|
|
31
|
+
"deprecated": "https://json-schema.org/keyword/deprecated",
|
|
32
|
+
"description": "https://json-schema.org/keyword/description",
|
|
33
|
+
"discriminator": "https://spec.openapis.org/oas/3.0/keyword/discriminator",
|
|
34
|
+
"enum": "https://json-schema.org/keyword/enum",
|
|
35
|
+
"example": "https://spec.openapis.org/oas/3.0/keyword/example",
|
|
36
|
+
"exclusiveMaximum": "https://json-schema.org/keyword/draft-04/exclusiveMaximum",
|
|
37
|
+
"exclusiveMinimum": "https://json-schema.org/keyword/draft-04/exclusiveMinimum",
|
|
38
|
+
"externalDocs": "https://spec.openapis.org/oas/3.0/keyword/externalDocs",
|
|
39
|
+
"format": "https://json-schema.org/keyword/format",
|
|
40
|
+
"items": "https://json-schema.org/keyword/draft-04/items",
|
|
41
|
+
"maxItems": "https://json-schema.org/keyword/maxItems",
|
|
42
|
+
"maxLength": "https://json-schema.org/keyword/maxLength",
|
|
43
|
+
"maxProperties": "https://json-schema.org/keyword/maxProperties",
|
|
44
|
+
"maximum": "https://json-schema.org/keyword/draft-04/maximum",
|
|
45
|
+
"minItems": "https://json-schema.org/keyword/minItems",
|
|
46
|
+
"minLength": "https://json-schema.org/keyword/minLength",
|
|
47
|
+
"minProperties": "https://json-schema.org/keyword/minProperties",
|
|
48
|
+
"minimum": "https://json-schema.org/keyword/draft-04/minimum",
|
|
49
|
+
"multipleOf": "https://json-schema.org/keyword/multipleOf",
|
|
50
|
+
"not": "https://json-schema.org/keyword/not",
|
|
51
|
+
"nullable": "https://spec.openapis.org/oas/3.0/keyword/nullable",
|
|
52
|
+
"oneOf": "https://json-schema.org/keyword/oneOf",
|
|
53
|
+
"pattern": "https://json-schema.org/keyword/pattern",
|
|
54
|
+
"properties": "https://json-schema.org/keyword/properties",
|
|
55
|
+
"readOnly": "https://json-schema.org/keyword/readOnly",
|
|
56
|
+
"required": "https://json-schema.org/keyword/required",
|
|
57
|
+
"title": "https://json-schema.org/keyword/title",
|
|
58
|
+
"type": "https://spec.openapis.org/oas/3.0/keyword/type",
|
|
59
|
+
"uniqueItems": "https://json-schema.org/keyword/uniqueItems",
|
|
60
|
+
"writeOnly": "https://json-schema.org/keyword/writeOnly",
|
|
61
|
+
"xml": "https://spec.openapis.org/oas/3.0/keyword/xml"
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
loadDialect(jsonSchemaVersion, {
|
|
65
|
+
[jsonSchemaVersion]: true
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
loadDialect("https://spec.openapis.org/oas/3.0/schema", {
|
|
69
|
+
[jsonSchemaVersion]: true
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
addSchema(dialectSchema);
|
|
73
|
+
|
|
74
|
+
addSchema(schema20210928, "https://spec.openapis.org/oas/3.0/schema");
|
|
75
|
+
addSchema(schema20210928, "https://spec.openapis.org/oas/3.0/schema/latest");
|
|
76
|
+
|
|
77
|
+
export * from "../draft-04/index.js";
|