@mintlify/validation 0.1.177 → 0.1.178
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/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/openapi/IncrementalEvaluator.d.ts +58 -0
- package/dist/openapi/IncrementalEvaluator.js +358 -0
- package/dist/openapi/OpenApiToEndpointConverter.d.ts +28 -8
- package/dist/openapi/OpenApiToEndpointConverter.js +136 -42
- package/dist/openapi/ParametersConverter.d.ts +16 -2
- package/dist/openapi/ParametersConverter.js +61 -1
- package/dist/openapi/SchemaConverter.d.ts +14 -0
- package/dist/openapi/SchemaConverter.js +2 -15
- package/dist/openapi/findRefsUsed.d.ts +1 -0
- package/dist/openapi/findRefsUsed.js +20 -0
- package/dist/openapi/types/endpoint.d.ts +17 -17
- package/dist/openapi/types/incrementalEndpoint.d.ts +17 -0
- package/dist/openapi/types/incrementalEndpoint.js +1 -0
- package/dist/openapi/utils.d.ts +8 -0
- package/dist/openapi/utils.js +24 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { BaseConverter } from './BaseConverter.js';
|
|
2
|
-
import {
|
|
2
|
+
import { generateFirstIncrementalSchema } from './IncrementalEvaluator.js';
|
|
3
|
+
import { IncrementalParametersConverter, ParametersConverter } from './ParametersConverter.js';
|
|
3
4
|
import { SchemaConverter } from './SchemaConverter.js';
|
|
4
5
|
import { SecurityConverter } from './SecurityConverter.js';
|
|
5
6
|
import { ServersConverter } from './ServersConverter.js';
|
|
6
7
|
import { InvalidSchemaError } from './errors.js';
|
|
8
|
+
import { findRefsUsed } from './findRefsUsed.js';
|
|
7
9
|
import { generateExampleFromSchema } from './generateExampleFromSchema.js';
|
|
8
|
-
|
|
10
|
+
import { dereference } from './utils.js';
|
|
11
|
+
export class BaseOpenApiToEndpointConverter extends BaseConverter {
|
|
9
12
|
constructor(document, path, method, safeParse = false) {
|
|
10
13
|
super(safeParse);
|
|
11
14
|
this.document = document;
|
|
12
15
|
this.path = path;
|
|
13
16
|
this.method = method;
|
|
14
17
|
this.safeParse = safeParse;
|
|
15
|
-
}
|
|
16
|
-
convert() {
|
|
17
|
-
var _a, _b, _c, _d, _e;
|
|
18
18
|
const paths = this.document.paths;
|
|
19
19
|
if (paths === undefined) {
|
|
20
20
|
throw new InvalidSchemaError(['#'], 'paths not defined');
|
|
@@ -23,25 +23,27 @@ export class OpenApiToEndpointConverter extends BaseConverter {
|
|
|
23
23
|
if (pathObject === undefined) {
|
|
24
24
|
throw new InvalidSchemaError(['#', 'paths'], `path not defined: ${this.path}`);
|
|
25
25
|
}
|
|
26
|
+
this.pathObject = pathObject;
|
|
26
27
|
const operationObject = pathObject[this.method];
|
|
27
28
|
if (operationObject === undefined) {
|
|
28
29
|
throw new InvalidSchemaError(['#', 'paths', this.path], `operation does not exist: ${this.method}`);
|
|
29
30
|
}
|
|
30
|
-
|
|
31
|
+
this.operationObject = operationObject;
|
|
32
|
+
}
|
|
33
|
+
convert() {
|
|
34
|
+
var _a, _b, _c, _d, _e;
|
|
35
|
+
const securityRequirements = (_a = this.operationObject.security) !== null && _a !== void 0 ? _a : this.document.security;
|
|
31
36
|
const securitySchemes = (_b = this.document.components) === null || _b === void 0 ? void 0 : _b.securitySchemes;
|
|
32
37
|
const security = SecurityConverter.convert(securityRequirements, securitySchemes, this.safeParse);
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
const parameters = ParametersConverter.convert(this.method, pathParameters, operationParameters, ['#', 'paths', this.path], this.safeParse);
|
|
36
|
-
const servers = ServersConverter.convert((_d = (_c = operationObject.servers) !== null && _c !== void 0 ? _c : pathObject.servers) !== null && _d !== void 0 ? _d : this.document.servers);
|
|
38
|
+
const parameters = this.convertParameters();
|
|
39
|
+
const servers = ServersConverter.convert((_d = (_c = this.operationObject.servers) !== null && _c !== void 0 ? _c : this.pathObject.servers) !== null && _d !== void 0 ? _d : this.document.servers);
|
|
37
40
|
// title is a bit too specific to take from the path object
|
|
38
|
-
const title = operationObject.summary;
|
|
39
|
-
const description = (_e = operationObject.description) !== null && _e !== void 0 ? _e : pathObject.description;
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
const
|
|
44
|
-
const response = this.convertResponses(['#', 'paths', this.path, this.method, 'responses'], operationObject.responses);
|
|
41
|
+
const title = this.operationObject.summary;
|
|
42
|
+
const description = (_e = this.operationObject.description) !== null && _e !== void 0 ? _e : this.pathObject.description;
|
|
43
|
+
const body = this.convertBody();
|
|
44
|
+
const deprecated = !!this.operationObject.deprecated;
|
|
45
|
+
const codeSamples = this.convertCodeSamples(['#', 'paths', this.path, this.method], this.operationObject);
|
|
46
|
+
const response = this.convertResponses();
|
|
45
47
|
return {
|
|
46
48
|
title,
|
|
47
49
|
description,
|
|
@@ -58,24 +60,6 @@ export class OpenApiToEndpointConverter extends BaseConverter {
|
|
|
58
60
|
deprecated,
|
|
59
61
|
};
|
|
60
62
|
}
|
|
61
|
-
convertContent(debugPath, content, location, required) {
|
|
62
|
-
if (content === undefined) {
|
|
63
|
-
return {};
|
|
64
|
-
}
|
|
65
|
-
const newEntries = Object.entries(content).map(([contentType, mediaObject]) => {
|
|
66
|
-
const schemaArray = SchemaConverter.convert({
|
|
67
|
-
schema: mediaObject.schema,
|
|
68
|
-
path: [...debugPath, contentType, 'schema'],
|
|
69
|
-
required,
|
|
70
|
-
location,
|
|
71
|
-
contentType,
|
|
72
|
-
safeParse: this.safeParse,
|
|
73
|
-
});
|
|
74
|
-
const examples = this.convertExamples(mediaObject.examples, mediaObject.example, schemaArray);
|
|
75
|
-
return [contentType, { schemaArray, examples }];
|
|
76
|
-
});
|
|
77
|
-
return Object.fromEntries(newEntries);
|
|
78
|
-
}
|
|
79
63
|
convertExamples(examples, example, schemaArray) {
|
|
80
64
|
if (examples && Object.values(examples).some(({ value }) => value !== undefined)) {
|
|
81
65
|
return Object.fromEntries(Object.entries(examples)
|
|
@@ -94,13 +78,6 @@ export class OpenApiToEndpointConverter extends BaseConverter {
|
|
|
94
78
|
}
|
|
95
79
|
return { example: { value: generateExampleFromSchema(schemaArray[0]) } };
|
|
96
80
|
}
|
|
97
|
-
convertResponses(debugPath, responses) {
|
|
98
|
-
const newEntries = Object.entries(responses).map(([statusCode, response]) => [
|
|
99
|
-
statusCode,
|
|
100
|
-
this.convertContent([...debugPath, statusCode, 'content'], response.content, 'response'),
|
|
101
|
-
]);
|
|
102
|
-
return Object.fromEntries(newEntries);
|
|
103
|
-
}
|
|
104
81
|
convertCodeSamples(debugPath, operation) {
|
|
105
82
|
let key;
|
|
106
83
|
let rawCodeSamples;
|
|
@@ -140,7 +117,124 @@ export class OpenApiToEndpointConverter extends BaseConverter {
|
|
|
140
117
|
});
|
|
141
118
|
return codeSamples;
|
|
142
119
|
}
|
|
120
|
+
}
|
|
121
|
+
export class OpenApiToEndpointConverter extends BaseOpenApiToEndpointConverter {
|
|
122
|
+
convertBody() {
|
|
123
|
+
const requestBody = this.operationObject.requestBody;
|
|
124
|
+
return this.convertContent(['#', 'paths', this.path, this.method, 'requestBody', 'content'], requestBody === null || requestBody === void 0 ? void 0 : requestBody.content, 'request', requestBody === null || requestBody === void 0 ? void 0 : requestBody.required);
|
|
125
|
+
}
|
|
126
|
+
convertResponses() {
|
|
127
|
+
const responses = this.operationObject.responses;
|
|
128
|
+
if (!responses)
|
|
129
|
+
return {};
|
|
130
|
+
const newEntries = Object.entries(responses).map(([statusCode, response]) => [
|
|
131
|
+
statusCode,
|
|
132
|
+
this.convertContent(['#', 'paths', this.path, this.method, 'responses', statusCode, 'content'], response.content, 'response'),
|
|
133
|
+
]);
|
|
134
|
+
return Object.fromEntries(newEntries);
|
|
135
|
+
}
|
|
136
|
+
convertContent(debugPath, content, location, required) {
|
|
137
|
+
if (content === undefined) {
|
|
138
|
+
return {};
|
|
139
|
+
}
|
|
140
|
+
const newEntries = Object.entries(content).map(([contentType, mediaObject]) => {
|
|
141
|
+
const schemaArray = SchemaConverter.convert({
|
|
142
|
+
schema: mediaObject.schema,
|
|
143
|
+
path: [...debugPath, contentType, 'schema'],
|
|
144
|
+
required,
|
|
145
|
+
location,
|
|
146
|
+
contentType,
|
|
147
|
+
safeParse: this.safeParse,
|
|
148
|
+
});
|
|
149
|
+
const examples = this.convertExamples(mediaObject.examples, mediaObject.example, schemaArray);
|
|
150
|
+
return [contentType, { schemaArray, examples }];
|
|
151
|
+
});
|
|
152
|
+
return Object.fromEntries(newEntries);
|
|
153
|
+
}
|
|
154
|
+
convertParameters() {
|
|
155
|
+
const pathParameters = this.pathObject.parameters;
|
|
156
|
+
const operationParameters = this.operationObject.parameters;
|
|
157
|
+
return ParametersConverter.convert(this.method, pathParameters, operationParameters, ['#', 'paths', this.path], this.safeParse);
|
|
158
|
+
}
|
|
143
159
|
static convert(spec, path, method, safeParse) {
|
|
144
160
|
return new OpenApiToEndpointConverter(spec, path, method, safeParse).convert();
|
|
145
161
|
}
|
|
146
162
|
}
|
|
163
|
+
export class OpenApiToIncrementalEndpointConverter extends BaseOpenApiToEndpointConverter {
|
|
164
|
+
constructor(rawDocument, document, path, method, safeParse = false) {
|
|
165
|
+
super(document, path, method, safeParse);
|
|
166
|
+
this.rawDocument = rawDocument;
|
|
167
|
+
}
|
|
168
|
+
convertParameters() {
|
|
169
|
+
var _a, _b, _c, _d, _e;
|
|
170
|
+
const pathParameters = (_b = (_a = this.rawDocument.paths) === null || _a === void 0 ? void 0 : _a[this.path]) === null || _b === void 0 ? void 0 : _b.parameters;
|
|
171
|
+
const operationParameters = (_e = (_d = (_c = this.rawDocument.paths) === null || _c === void 0 ? void 0 : _c[this.path]) === null || _d === void 0 ? void 0 : _d[this.method]) === null || _e === void 0 ? void 0 : _e.parameters;
|
|
172
|
+
return IncrementalParametersConverter.convert(this.rawDocument, this.method, pathParameters, operationParameters, ['#', 'paths', this.path], this.safeParse);
|
|
173
|
+
}
|
|
174
|
+
convertBody() {
|
|
175
|
+
var _a, _b, _c, _d;
|
|
176
|
+
let rawRequestBody = (_c = (_b = (_a = this.rawDocument.paths) === null || _a === void 0 ? void 0 : _a[this.path]) === null || _b === void 0 ? void 0 : _b[this.method]) === null || _c === void 0 ? void 0 : _c.requestBody;
|
|
177
|
+
if (rawRequestBody && '$ref' in rawRequestBody) {
|
|
178
|
+
rawRequestBody = dereference('requestBodies', rawRequestBody.$ref, (_d = this.rawDocument.components) === null || _d === void 0 ? void 0 : _d.requestBodies);
|
|
179
|
+
}
|
|
180
|
+
if (!rawRequestBody || '$ref' in rawRequestBody)
|
|
181
|
+
return {};
|
|
182
|
+
const requestBody = this.operationObject.requestBody;
|
|
183
|
+
return this.convertContent(['#', 'paths', this.path, this.method, 'requestBody', 'content'], rawRequestBody.content, requestBody === null || requestBody === void 0 ? void 0 : requestBody.content, 'request', requestBody === null || requestBody === void 0 ? void 0 : requestBody.required);
|
|
184
|
+
}
|
|
185
|
+
convertResponses() {
|
|
186
|
+
var _a, _b, _c;
|
|
187
|
+
const rawResponses = (_c = (_b = (_a = this.rawDocument.paths) === null || _a === void 0 ? void 0 : _a[this.path]) === null || _b === void 0 ? void 0 : _b[this.method]) === null || _c === void 0 ? void 0 : _c.responses;
|
|
188
|
+
if (!rawResponses)
|
|
189
|
+
return {};
|
|
190
|
+
const newEntries = Object.entries(rawResponses).map(([statusCode, rawResponse]) => {
|
|
191
|
+
var _a, _b;
|
|
192
|
+
if ('$ref' in rawResponse) {
|
|
193
|
+
const dereferencedRes = dereference('responses', rawResponse.$ref, (_a = this.rawDocument.components) === null || _a === void 0 ? void 0 : _a.responses);
|
|
194
|
+
if (!dereferencedRes || '$ref' in dereferencedRes)
|
|
195
|
+
throw Error();
|
|
196
|
+
rawResponse = dereferencedRes;
|
|
197
|
+
}
|
|
198
|
+
const response = (_b = this.operationObject.responses) === null || _b === void 0 ? void 0 : _b[statusCode];
|
|
199
|
+
return [
|
|
200
|
+
statusCode,
|
|
201
|
+
this.convertContent(['#', 'paths', this.path, this.method, 'responses', statusCode, 'content'], rawResponse.content, response === null || response === void 0 ? void 0 : response.content, 'response'),
|
|
202
|
+
];
|
|
203
|
+
});
|
|
204
|
+
return Object.fromEntries(newEntries);
|
|
205
|
+
}
|
|
206
|
+
convertContent(debugPath, rawContent, dereferencedContent, location, required) {
|
|
207
|
+
if (!rawContent || !dereferencedContent) {
|
|
208
|
+
return {};
|
|
209
|
+
}
|
|
210
|
+
const newEntries = Object.entries(rawContent).map(([contentType, mediaObject]) => {
|
|
211
|
+
var _a;
|
|
212
|
+
const incrementalSchemaArray = generateFirstIncrementalSchema(mediaObject.schema, (_a = this.rawDocument.components) === null || _a === void 0 ? void 0 : _a.schemas, required, location, contentType);
|
|
213
|
+
// still need to generate schemaArray so we can generate examples
|
|
214
|
+
const dereferencedMediaObject = dereferencedContent[contentType];
|
|
215
|
+
const schemaArray = SchemaConverter.convert({
|
|
216
|
+
schema: dereferencedMediaObject === null || dereferencedMediaObject === void 0 ? void 0 : dereferencedMediaObject.schema,
|
|
217
|
+
path: [...debugPath, contentType, 'schema'],
|
|
218
|
+
required,
|
|
219
|
+
location,
|
|
220
|
+
contentType,
|
|
221
|
+
safeParse: this.safeParse,
|
|
222
|
+
});
|
|
223
|
+
const examples = this.convertExamples(dereferencedMediaObject === null || dereferencedMediaObject === void 0 ? void 0 : dereferencedMediaObject.examples, dereferencedMediaObject === null || dereferencedMediaObject === void 0 ? void 0 : dereferencedMediaObject.example, schemaArray);
|
|
224
|
+
return [contentType, { schemaArray: incrementalSchemaArray, examples }];
|
|
225
|
+
});
|
|
226
|
+
return Object.fromEntries(newEntries);
|
|
227
|
+
}
|
|
228
|
+
convertWithSchemas() {
|
|
229
|
+
var _a, _b, _c;
|
|
230
|
+
const endpointWithoutSchemas = this.convert();
|
|
231
|
+
const refsUsed = new Set();
|
|
232
|
+
findRefsUsed(endpointWithoutSchemas, (_a = this.rawDocument.components) === null || _a === void 0 ? void 0 : _a.schemas, refsUsed);
|
|
233
|
+
const newEntries = Object.entries((_c = (_b = this.rawDocument.components) === null || _b === void 0 ? void 0 : _b.schemas) !== null && _c !== void 0 ? _c : {}).filter(([schemaName]) => refsUsed.has(schemaName));
|
|
234
|
+
const schemas = Object.fromEntries(newEntries);
|
|
235
|
+
return Object.assign(Object.assign({}, endpointWithoutSchemas), { schemas });
|
|
236
|
+
}
|
|
237
|
+
static convert(rawDocument, resolvedDocument, path, method, safeParse) {
|
|
238
|
+
return new OpenApiToIncrementalEndpointConverter(rawDocument, resolvedDocument, path, method, safeParse).convertWithSchemas();
|
|
239
|
+
}
|
|
240
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { OpenAPIV3_1 } from 'openapi-types';
|
|
2
2
|
import { BaseConverter } from './BaseConverter.js';
|
|
3
|
-
import { ParameterSections } from './types/endpoint.js';
|
|
3
|
+
import { DataSchemaArray, ParameterSections } from './types/endpoint.js';
|
|
4
|
+
import { IncrementalDataSchemaArray } from './types/incrementalEndpoint.js';
|
|
4
5
|
export declare class ParametersConverter extends BaseConverter {
|
|
5
6
|
readonly method: string;
|
|
6
7
|
readonly pathParameters: OpenAPIV3_1.ParameterObject[] | undefined;
|
|
@@ -11,5 +12,18 @@ export declare class ParametersConverter extends BaseConverter {
|
|
|
11
12
|
private constructor();
|
|
12
13
|
private convert;
|
|
13
14
|
private addParameter;
|
|
14
|
-
static convert(method: string, pathParameters: OpenAPIV3_1.ParameterObject[] | undefined, operationParameters: OpenAPIV3_1.ParameterObject[] | undefined, path: string[], safeParse?: boolean): ParameterSections
|
|
15
|
+
static convert(method: string, pathParameters: OpenAPIV3_1.ParameterObject[] | undefined, operationParameters: OpenAPIV3_1.ParameterObject[] | undefined, path: string[], safeParse?: boolean): ParameterSections<DataSchemaArray>;
|
|
16
|
+
}
|
|
17
|
+
export declare class IncrementalParametersConverter extends BaseConverter {
|
|
18
|
+
readonly rawDocument: OpenAPIV3_1.Document;
|
|
19
|
+
readonly method: string;
|
|
20
|
+
readonly pathParameters: (OpenAPIV3_1.ParameterObject | OpenAPIV3_1.ReferenceObject)[] | undefined;
|
|
21
|
+
readonly operationParameters: (OpenAPIV3_1.ParameterObject | OpenAPIV3_1.ReferenceObject)[] | undefined;
|
|
22
|
+
readonly path: string[];
|
|
23
|
+
readonly safeParse: boolean;
|
|
24
|
+
private parameterSections;
|
|
25
|
+
private constructor();
|
|
26
|
+
private convert;
|
|
27
|
+
private addParameter;
|
|
28
|
+
static convert(rawDocument: OpenAPIV3_1.Document, method: string, pathParameters: (OpenAPIV3_1.ParameterObject | OpenAPIV3_1.ReferenceObject)[] | undefined, operationParameters: (OpenAPIV3_1.ParameterObject | OpenAPIV3_1.ReferenceObject)[] | undefined, path: string[], safeParse?: boolean): ParameterSections<IncrementalDataSchemaArray>;
|
|
15
29
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { BaseConverter } from './BaseConverter.js';
|
|
2
|
+
import { generateFirstIncrementalSchema } from './IncrementalEvaluator.js';
|
|
2
3
|
import { SchemaConverter } from './SchemaConverter.js';
|
|
3
4
|
import { InvalidSchemaError } from './errors.js';
|
|
4
|
-
import { copyKeyIfDefined } from './utils.js';
|
|
5
|
+
import { copyKeyIfDefined, dereference } from './utils.js';
|
|
5
6
|
export class ParametersConverter extends BaseConverter {
|
|
6
7
|
constructor(method, pathParameters, operationParameters, path, safeParse = false) {
|
|
7
8
|
super(safeParse);
|
|
@@ -48,3 +49,62 @@ export class ParametersConverter extends BaseConverter {
|
|
|
48
49
|
return new ParametersConverter(method, pathParameters, operationParameters, path, safeParse).convert();
|
|
49
50
|
}
|
|
50
51
|
}
|
|
52
|
+
export class IncrementalParametersConverter extends BaseConverter {
|
|
53
|
+
constructor(rawDocument, method, pathParameters, operationParameters, path, safeParse = false) {
|
|
54
|
+
super(safeParse);
|
|
55
|
+
this.rawDocument = rawDocument;
|
|
56
|
+
this.method = method;
|
|
57
|
+
this.pathParameters = pathParameters;
|
|
58
|
+
this.operationParameters = operationParameters;
|
|
59
|
+
this.path = path;
|
|
60
|
+
this.safeParse = safeParse;
|
|
61
|
+
this.parameterSections = {
|
|
62
|
+
path: {},
|
|
63
|
+
query: {},
|
|
64
|
+
header: {},
|
|
65
|
+
cookie: {},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
convert() {
|
|
69
|
+
var _a, _b;
|
|
70
|
+
(_a = this.pathParameters) === null || _a === void 0 ? void 0 : _a.forEach((parameterObject, i) => {
|
|
71
|
+
this.addParameter([...this.path, 'parameters', i.toString()], parameterObject);
|
|
72
|
+
});
|
|
73
|
+
(_b = this.operationParameters) === null || _b === void 0 ? void 0 : _b.forEach((parameterObject, i) => {
|
|
74
|
+
this.addParameter([...this.path, this.method, 'parameters', i.toString()], parameterObject);
|
|
75
|
+
});
|
|
76
|
+
return this.parameterSections;
|
|
77
|
+
}
|
|
78
|
+
addParameter(path, parameter) {
|
|
79
|
+
var _a, _b, _c;
|
|
80
|
+
if ('$ref' in parameter) {
|
|
81
|
+
const dereferencedParam = dereference('parameters', parameter.$ref, (_a = this.rawDocument.components) === null || _a === void 0 ? void 0 : _a.parameters);
|
|
82
|
+
if (!dereferencedParam || '$ref' in dereferencedParam) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
parameter = dereferencedParam;
|
|
86
|
+
}
|
|
87
|
+
if (!['path', 'header', 'query', 'cookie'].includes(parameter.in)) {
|
|
88
|
+
this.handleNewError(InvalidSchemaError, path, `invalid parameter location: '${parameter.in}'`);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const location = parameter.in;
|
|
92
|
+
// parameter.schema may be undefined (if the schema is instead defined in parameter.content), but this is likely super rare
|
|
93
|
+
let schema = parameter.schema;
|
|
94
|
+
if (schema && '$ref' in schema) {
|
|
95
|
+
schema = dereference('schemas', schema.$ref, (_b = this.rawDocument.components) === null || _b === void 0 ? void 0 : _b.schemas);
|
|
96
|
+
}
|
|
97
|
+
if (!schema) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
// maintain immutability
|
|
101
|
+
const schemaCopy = Object.assign({}, schema);
|
|
102
|
+
copyKeyIfDefined('description', parameter, schemaCopy);
|
|
103
|
+
copyKeyIfDefined('deprecated', parameter, schemaCopy);
|
|
104
|
+
const incrementalSchema = generateFirstIncrementalSchema(schemaCopy, (_c = this.rawDocument.components) === null || _c === void 0 ? void 0 : _c.schemas, location === 'path' ? true : parameter.required);
|
|
105
|
+
this.parameterSections[location][parameter.name] = { schema: incrementalSchema };
|
|
106
|
+
}
|
|
107
|
+
static convert(rawDocument, method, pathParameters, operationParameters, path, safeParse) {
|
|
108
|
+
return new IncrementalParametersConverter(rawDocument, method, pathParameters, operationParameters, path, safeParse).convert();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -62,3 +62,17 @@ export declare class SchemaConverter extends BaseConverter {
|
|
|
62
62
|
safeParse?: boolean;
|
|
63
63
|
}): DataSchemaArray;
|
|
64
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Given an OpenAPI 3.1 schema, this function will attempt to determine the schema type
|
|
67
|
+
* based on the properties present in the schema. This is useful for assigning types to
|
|
68
|
+
* schemas that are missing a type.
|
|
69
|
+
*
|
|
70
|
+
* For example, if a schema has no type but has `schema.properties`, we can infer the
|
|
71
|
+
* intended type is `object`.
|
|
72
|
+
*
|
|
73
|
+
* Used in the Conversion step.
|
|
74
|
+
*
|
|
75
|
+
* @param schema
|
|
76
|
+
* @returns if exactly one type can be inferred, the string corresponding to that type; otherwise `undefined`
|
|
77
|
+
*/
|
|
78
|
+
export declare const inferType: (schema: Omit<OpenAPIV3_1.SchemaObject, "type">) => OpenAPIV3_1.ArraySchemaObjectType | OpenAPIV3_1.NonArraySchemaObjectType | undefined;
|
|
@@ -2,13 +2,7 @@ import lcm from 'lcm';
|
|
|
2
2
|
import _ from 'lodash';
|
|
3
3
|
import { BaseConverter } from './BaseConverter.js';
|
|
4
4
|
import { ConversionError, ImpossibleSchemaError, InvalidSchemaError } from './errors.js';
|
|
5
|
-
import { addKeyIfDefined, copyKeyIfDefined } from './utils.js';
|
|
6
|
-
const structuredDataContentTypes = [
|
|
7
|
-
'multipart/form-data',
|
|
8
|
-
'application/json',
|
|
9
|
-
'application/x-www-form-urlencoded',
|
|
10
|
-
];
|
|
11
|
-
const stringFileFormats = ['binary', 'base64'];
|
|
5
|
+
import { addKeyIfDefined, copyExampleIfDefined, copyKeyIfDefined, stringFileFormats, structuredDataContentTypes, } from './utils.js';
|
|
12
6
|
export class SchemaConverter extends BaseConverter {
|
|
13
7
|
constructor(schema, required, path = ['#'], location, contentType, safeParse = false) {
|
|
14
8
|
super(safeParse);
|
|
@@ -484,13 +478,6 @@ export class SchemaConverter extends BaseConverter {
|
|
|
484
478
|
return new SchemaConverter(schema, required, path, location, contentType, safeParse).convert();
|
|
485
479
|
}
|
|
486
480
|
}
|
|
487
|
-
const copyExampleIfDefined = (source, destination) => {
|
|
488
|
-
var _a;
|
|
489
|
-
const example = ((_a = source.examples) === null || _a === void 0 ? void 0 : _a[0]) !== undefined ? source.examples[0] : source.example;
|
|
490
|
-
if (example !== undefined) {
|
|
491
|
-
destination.example = example;
|
|
492
|
-
}
|
|
493
|
-
};
|
|
494
481
|
const takeLast = (schema1, schema2, key) => {
|
|
495
482
|
var _a;
|
|
496
483
|
return (_a = schema2[key]) !== null && _a !== void 0 ? _a : schema1[key];
|
|
@@ -514,7 +501,7 @@ const combine = (schema1, schema2, key, transform) => {
|
|
|
514
501
|
* @param schema
|
|
515
502
|
* @returns if exactly one type can be inferred, the string corresponding to that type; otherwise `undefined`
|
|
516
503
|
*/
|
|
517
|
-
const inferType = (schema) => {
|
|
504
|
+
export const inferType = (schema) => {
|
|
518
505
|
var _a, _b;
|
|
519
506
|
let type = undefined;
|
|
520
507
|
if (schema.format !== undefined ||
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function findRefsUsed(schema: unknown, components: Record<string, unknown> | undefined, refsUsed: Set<string>): void;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const schemaPrefix = '#/components/schemas/';
|
|
2
|
+
export function findRefsUsed(schema, components = {}, refsUsed) {
|
|
3
|
+
function traverse(value) {
|
|
4
|
+
if (typeof value === 'object' && value !== null) {
|
|
5
|
+
if ('$ref' in value &&
|
|
6
|
+
typeof value.$ref === 'string' &&
|
|
7
|
+
value.$ref.startsWith(schemaPrefix)) {
|
|
8
|
+
const schemaName = value.$ref.slice(schemaPrefix.length);
|
|
9
|
+
if (!refsUsed.has(schemaName)) {
|
|
10
|
+
refsUsed.add(schemaName);
|
|
11
|
+
traverse(components[schemaName]);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
for (const val of Object.values(value)) {
|
|
15
|
+
traverse(val);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
traverse(schema);
|
|
20
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export type Endpoint = {
|
|
1
|
+
export type Endpoint<D = DataSchemaArray> = {
|
|
2
2
|
title?: string;
|
|
3
3
|
description?: string;
|
|
4
4
|
path: string;
|
|
5
5
|
method: HttpMethod;
|
|
6
6
|
servers?: Server[];
|
|
7
|
-
request: RequestSchema
|
|
8
|
-
response: ResponseSchema
|
|
7
|
+
request: RequestSchema<D>;
|
|
8
|
+
response: ResponseSchema<D>;
|
|
9
9
|
deprecated: boolean;
|
|
10
10
|
};
|
|
11
11
|
export type Server = {
|
|
@@ -29,10 +29,10 @@ export type ServerVariableStringEnumSchema = {
|
|
|
29
29
|
};
|
|
30
30
|
export declare const httpMethods: readonly ["get", "put", "post", "delete", "options", "head", "patch", "trace"];
|
|
31
31
|
export type HttpMethod = (typeof httpMethods)[number];
|
|
32
|
-
export type RequestSchema = {
|
|
32
|
+
export type RequestSchema<D> = {
|
|
33
33
|
security: SecurityOption[];
|
|
34
|
-
parameters: ParameterSections
|
|
35
|
-
body: BodySchema
|
|
34
|
+
parameters: ParameterSections<D>;
|
|
35
|
+
body: BodySchema<D>;
|
|
36
36
|
codeSamples?: CodeSample[];
|
|
37
37
|
};
|
|
38
38
|
export type CodeSample = {
|
|
@@ -40,11 +40,11 @@ export type CodeSample = {
|
|
|
40
40
|
lang: string;
|
|
41
41
|
source: string;
|
|
42
42
|
};
|
|
43
|
-
export type BodySchema = {
|
|
44
|
-
[contentType: string]: ContentSchema
|
|
43
|
+
export type BodySchema<D> = {
|
|
44
|
+
[contentType: string]: ContentSchema<D>;
|
|
45
45
|
};
|
|
46
|
-
export type ContentSchema = {
|
|
47
|
-
schemaArray:
|
|
46
|
+
export type ContentSchema<D> = {
|
|
47
|
+
schemaArray: D;
|
|
48
48
|
examples: {
|
|
49
49
|
[title: string]: ExampleSchema;
|
|
50
50
|
};
|
|
@@ -54,15 +54,15 @@ export type ExampleSchema = {
|
|
|
54
54
|
description?: string;
|
|
55
55
|
value: unknown;
|
|
56
56
|
};
|
|
57
|
-
export type ParameterSchema = {
|
|
58
|
-
schema:
|
|
57
|
+
export type ParameterSchema<D> = {
|
|
58
|
+
schema: D;
|
|
59
59
|
};
|
|
60
|
-
export type ParameterGroup = {
|
|
61
|
-
[name: string]: ParameterSchema
|
|
60
|
+
export type ParameterGroup<D> = {
|
|
61
|
+
[name: string]: ParameterSchema<D>;
|
|
62
62
|
};
|
|
63
63
|
export type ParameterLocation = 'query' | 'header' | 'cookie' | 'path';
|
|
64
64
|
type NonPathParameterLocation = Exclude<ParameterLocation, 'path'>;
|
|
65
|
-
export type ParameterSections = Record<ParameterLocation, ParameterGroup
|
|
65
|
+
export type ParameterSections<D> = Record<ParameterLocation, ParameterGroup<D>>;
|
|
66
66
|
export type SecurityOption = {
|
|
67
67
|
title: string;
|
|
68
68
|
parameters: SecurityParameterSections;
|
|
@@ -85,8 +85,8 @@ export type SecurityParameterGroup = {
|
|
|
85
85
|
[name: string]: SecurityParameterSchema;
|
|
86
86
|
};
|
|
87
87
|
export type SecurityParameterSections = Record<NonPathParameterLocation, SecurityParameterGroup>;
|
|
88
|
-
export type ResponseSchema = {
|
|
89
|
-
[code: string]: BodySchema
|
|
88
|
+
export type ResponseSchema<D> = {
|
|
89
|
+
[code: string]: BodySchema<D>;
|
|
90
90
|
};
|
|
91
91
|
export type DataSchemaArray = [DataSchema, ...DataSchema[]];
|
|
92
92
|
export declare const typeList: readonly ["boolean", "string", "number", "integer", "object", "array", "enum<string>", "enum<number>", "enum<integer>", "file", "null", "any"];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { OpenAPIV3_1 } from 'openapi-types';
|
|
2
|
+
import { BooleanSchema, StringSchema, NumberSchema, ObjectSchema, ArraySchema, StringEnumSchema, NumberEnumSchema, FileSchema, NullSchema, AnySchema, Endpoint } from './endpoint.js';
|
|
3
|
+
export type IncrementalEndpoint = Endpoint<IncrementalDataSchemaArray> & {
|
|
4
|
+
schemas: Record<string, OpenAPIV3_1.SchemaObject>;
|
|
5
|
+
};
|
|
6
|
+
export type IncrementalDataSchemaArray = [IncrementalDataSchema, ...IncrementalDataSchema[]];
|
|
7
|
+
export type IncrementalDataSchema = BooleanSchema | StringSchema | NumberSchema | IncrementalObjectSchema | IncrementalArraySchema | StringEnumSchema | NumberEnumSchema | FileSchema | NullSchema | AnySchema;
|
|
8
|
+
export type IncrementalObjectSchema = Omit<ObjectSchema, 'additionalProperties' | 'properties'> & {
|
|
9
|
+
additionalProperties?: boolean | OpenAPIV3_1.SchemaObject;
|
|
10
|
+
properties: {
|
|
11
|
+
[key: string]: OpenAPIV3_1.SchemaObject;
|
|
12
|
+
};
|
|
13
|
+
requiredProperties?: string[];
|
|
14
|
+
};
|
|
15
|
+
export type IncrementalArraySchema = Omit<ArraySchema, 'items'> & {
|
|
16
|
+
items: OpenAPIV3_1.SchemaObject;
|
|
17
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/openapi/utils.d.ts
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
|
+
import { OpenAPIV3_1 } from 'openapi-types';
|
|
2
|
+
import { DataSchema } from './types/endpoint.js';
|
|
3
|
+
export declare const stringFileFormats: string[];
|
|
4
|
+
export declare const structuredDataContentTypes: string[];
|
|
5
|
+
type ComponentsSection = keyof OpenAPIV3_1.ComponentsObject;
|
|
6
|
+
export declare function dereference<S extends ComponentsSection>(section: S, $ref: string, components: Record<string, NonNullable<OpenAPIV3_1.ComponentsObject[S]>[string]> | undefined): NonNullable<OpenAPIV3_1.ComponentsObject[S]>[string] | undefined;
|
|
1
7
|
export declare const addKeyIfDefined: <D, K extends keyof D>(key: K, value: D[K] | undefined, destination: D) => void;
|
|
2
8
|
export declare const copyKeyIfDefined: <D, K extends keyof D>(key: K, source: Pick<D, K>, destination: D) => void;
|
|
9
|
+
export declare const copyExampleIfDefined: (source: Pick<OpenAPIV3_1.SchemaObject, "example" | "examples">, destination: Pick<DataSchema, "example">) => void;
|
|
10
|
+
export {};
|
package/dist/openapi/utils.js
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
export const stringFileFormats = ['binary', 'base64'];
|
|
2
|
+
export const structuredDataContentTypes = [
|
|
3
|
+
'multipart/form-data',
|
|
4
|
+
'application/json',
|
|
5
|
+
'application/x-www-form-urlencoded',
|
|
6
|
+
];
|
|
7
|
+
export function dereference(section, $ref, components) {
|
|
8
|
+
const sectionPrefix = `#/components/${section}/`;
|
|
9
|
+
if (!$ref.startsWith(sectionPrefix))
|
|
10
|
+
return undefined;
|
|
11
|
+
const key = $ref.slice(sectionPrefix.length);
|
|
12
|
+
const value = components === null || components === void 0 ? void 0 : components[key];
|
|
13
|
+
// if a $ref points to another $ref, just fall back
|
|
14
|
+
if (value && '$ref' in value)
|
|
15
|
+
return undefined;
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
1
18
|
export const addKeyIfDefined = (key, value, destination) => {
|
|
2
19
|
if (value !== undefined) {
|
|
3
20
|
destination[key] = value;
|
|
@@ -10,3 +27,10 @@ export const copyKeyIfDefined = (key, source, destination) => {
|
|
|
10
27
|
destination[key] = source[key];
|
|
11
28
|
}
|
|
12
29
|
};
|
|
30
|
+
export const copyExampleIfDefined = (source, destination) => {
|
|
31
|
+
var _a;
|
|
32
|
+
const example = ((_a = source.examples) === null || _a === void 0 ? void 0 : _a[0]) !== undefined ? source.examples[0] : source.example;
|
|
33
|
+
if (example !== undefined) {
|
|
34
|
+
destination.example = example;
|
|
35
|
+
}
|
|
36
|
+
};
|