@mintlify/validation 0.1.176 → 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/generateExampleFromSchema.js +1 -1
- 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
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export * from './openapi/types/endpoint.js';
|
|
2
|
+
export * from './openapi/types/incrementalEndpoint.js';
|
|
2
3
|
export { OpenApiToEndpointConverter } from './openapi/OpenApiToEndpointConverter.js';
|
|
3
4
|
export { SchemaConverter } from './openapi/SchemaConverter.js';
|
|
4
5
|
export { generateExampleFromSchema } from './openapi/generateExampleFromSchema.js';
|
|
6
|
+
export { generateFirstIncrementalSchema, generateNextIncrementalSchema, } from './openapi/IncrementalEvaluator.js';
|
|
5
7
|
export { validateMintConfig } from './mint-config/validateMintConfig.js';
|
|
6
8
|
export { formatIssue } from './mint-config/formatIssue.js';
|
|
7
9
|
export declare const mintConfigJsonSchema: import("zod-to-json-schema/src/parseDef.js").JsonSchema7Type & {
|
package/dist/index.js
CHANGED
|
@@ -2,9 +2,11 @@ import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
|
2
2
|
import { colorsSchema } from './mint-config/schemas/colors.js';
|
|
3
3
|
import { mintConfigSchema } from './mint-config/schemas/config.js';
|
|
4
4
|
export * from './openapi/types/endpoint.js';
|
|
5
|
+
export * from './openapi/types/incrementalEndpoint.js';
|
|
5
6
|
export { OpenApiToEndpointConverter } from './openapi/OpenApiToEndpointConverter.js';
|
|
6
7
|
export { SchemaConverter } from './openapi/SchemaConverter.js';
|
|
7
8
|
export { generateExampleFromSchema } from './openapi/generateExampleFromSchema.js';
|
|
9
|
+
export { generateFirstIncrementalSchema, generateNextIncrementalSchema, } from './openapi/IncrementalEvaluator.js';
|
|
8
10
|
export { validateMintConfig } from './mint-config/validateMintConfig.js';
|
|
9
11
|
export { formatIssue } from './mint-config/formatIssue.js';
|
|
10
12
|
export const mintConfigJsonSchema = (() => {
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { OpenAPIV3_1 } from 'openapi-types';
|
|
2
|
+
import { IncrementalDataSchemaArray } from './types/incrementalEndpoint.js';
|
|
3
|
+
type Schema3_1 = OpenAPIV3_1.SchemaObject;
|
|
4
|
+
type Ref = OpenAPIV3_1.ReferenceObject;
|
|
5
|
+
type SchemaOrRef = Schema3_1 | Ref;
|
|
6
|
+
type Compositions = 'allOf' | 'oneOf' | 'anyOf' | 'not';
|
|
7
|
+
export type SimpleSchema = Omit<OpenAPIV3_1.SchemaObject, Compositions> & {
|
|
8
|
+
items?: OpenAPIV3_1.SchemaObject;
|
|
9
|
+
};
|
|
10
|
+
export type SumOfProducts = SimpleSchema[][];
|
|
11
|
+
/**
|
|
12
|
+
* Given an OpenAPI 3.1 SchemaObject or ReferenceObject containing any number of
|
|
13
|
+
* refs or compositions, this function returns the schema in sum-of-products form.
|
|
14
|
+
*
|
|
15
|
+
* When given the following schema:
|
|
16
|
+
*
|
|
17
|
+
* ```yaml
|
|
18
|
+
* title: 'A'
|
|
19
|
+
* oneOf:
|
|
20
|
+
* - { title: 'B' }
|
|
21
|
+
* - { title: 'C' }
|
|
22
|
+
* allOf:
|
|
23
|
+
* - { title: 'D' }
|
|
24
|
+
* - { title: 'E' }
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* this function returns the following sum of products:
|
|
28
|
+
*
|
|
29
|
+
* ```js
|
|
30
|
+
* [
|
|
31
|
+
* [{ title: 'B' }, { title: 'D' }, { title: 'E' }, { title: 'A' }],
|
|
32
|
+
* [{ title: 'C' }, { title: 'D' }, { title: 'E' }, { title: 'A' }],
|
|
33
|
+
* ]
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @param schema The schema or ref to reduce
|
|
37
|
+
* @param componentSchemas The value of `document.components.schemas`, to be used when dereferencing
|
|
38
|
+
* @returns The schema in sum-of-products form
|
|
39
|
+
*/
|
|
40
|
+
export declare function reduceToSumOfProducts(schema: SchemaOrRef, componentSchemas: Record<string, Schema3_1> | undefined): SumOfProducts;
|
|
41
|
+
/**
|
|
42
|
+
* This function logically combines an array of simple schemas (schemas that contain no compositions)
|
|
43
|
+
* in preparation for conversion to `IncrementalDataSchema`. This is akin to "multiplying" all of the schemas,
|
|
44
|
+
* to continue our math analogy. The result is a single simple schema, which is easier to work with.
|
|
45
|
+
*
|
|
46
|
+
* How fields are combined depends on the field. For fields like `title` and `description` where
|
|
47
|
+
* it doesn't make sense to combine, we just take the last. For `required` we combine arrays,
|
|
48
|
+
* for `maximum` we take the minimum value, etc.
|
|
49
|
+
*
|
|
50
|
+
* @param schemas An array of simple schemas to combine
|
|
51
|
+
* @param componentSchemas The value of `document.components.schemas`. In this function, it is only used to check if properties are readOnly/writeOnly
|
|
52
|
+
* @param location Whether the schema is part of the request, response, or neither. Used for filtering readOnly/writeOnly properties
|
|
53
|
+
* @returns A single simple schema that satisfies all the input schemas
|
|
54
|
+
*/
|
|
55
|
+
export declare function combineSimpleSchemas(schemas: SimpleSchema[], componentSchemas: Record<string, Schema3_1> | undefined, location?: 'request' | 'response'): SimpleSchema;
|
|
56
|
+
export declare function generateFirstIncrementalSchema(schema: SchemaOrRef | undefined, componentSchemas: Record<string, Schema3_1> | undefined, required?: boolean, location?: 'request' | 'response', contentType?: string): IncrementalDataSchemaArray;
|
|
57
|
+
export declare function generateNextIncrementalSchema(schema: SchemaOrRef, componentSchemas: Record<string, Schema3_1> | undefined, required?: boolean, location?: 'request' | 'response'): IncrementalDataSchemaArray;
|
|
58
|
+
export {};
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import lcm from 'lcm';
|
|
2
|
+
import { inferType } from './SchemaConverter.js';
|
|
3
|
+
import { addKeyIfDefined, copyExampleIfDefined, copyKeyIfDefined, dereference, stringFileFormats, structuredDataContentTypes, } from './utils.js';
|
|
4
|
+
/**
|
|
5
|
+
* Given an OpenAPI 3.1 SchemaObject or ReferenceObject containing any number of
|
|
6
|
+
* refs or compositions, this function returns the schema in sum-of-products form.
|
|
7
|
+
*
|
|
8
|
+
* When given the following schema:
|
|
9
|
+
*
|
|
10
|
+
* ```yaml
|
|
11
|
+
* title: 'A'
|
|
12
|
+
* oneOf:
|
|
13
|
+
* - { title: 'B' }
|
|
14
|
+
* - { title: 'C' }
|
|
15
|
+
* allOf:
|
|
16
|
+
* - { title: 'D' }
|
|
17
|
+
* - { title: 'E' }
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* this function returns the following sum of products:
|
|
21
|
+
*
|
|
22
|
+
* ```js
|
|
23
|
+
* [
|
|
24
|
+
* [{ title: 'B' }, { title: 'D' }, { title: 'E' }, { title: 'A' }],
|
|
25
|
+
* [{ title: 'C' }, { title: 'D' }, { title: 'E' }, { title: 'A' }],
|
|
26
|
+
* ]
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @param schema The schema or ref to reduce
|
|
30
|
+
* @param componentSchemas The value of `document.components.schemas`, to be used when dereferencing
|
|
31
|
+
* @returns The schema in sum-of-products form
|
|
32
|
+
*/
|
|
33
|
+
export function reduceToSumOfProducts(schema, componentSchemas) {
|
|
34
|
+
var _a, _b, _c;
|
|
35
|
+
if ('$ref' in schema) {
|
|
36
|
+
const dereferencedSchema = dereference('schemas', schema.$ref, componentSchemas);
|
|
37
|
+
if (!dereferencedSchema)
|
|
38
|
+
return [[{}]];
|
|
39
|
+
schema = dereferencedSchema;
|
|
40
|
+
}
|
|
41
|
+
if (!schema.oneOf && !schema.allOf && !schema.anyOf && !Array.isArray(schema.type)) {
|
|
42
|
+
return [[schema]];
|
|
43
|
+
}
|
|
44
|
+
const baseSchema = Object.assign({}, schema);
|
|
45
|
+
delete baseSchema.oneOf;
|
|
46
|
+
delete baseSchema.anyOf;
|
|
47
|
+
delete baseSchema.allOf;
|
|
48
|
+
delete baseSchema.not;
|
|
49
|
+
const baseSchemaArr = Object.keys(baseSchema).length > 0
|
|
50
|
+
? Array.isArray(baseSchema.type)
|
|
51
|
+
? [baseSchema.type.map((type) => [Object.assign(Object.assign({}, baseSchema), { type })])]
|
|
52
|
+
: [[[baseSchema]]]
|
|
53
|
+
: [];
|
|
54
|
+
const reducedOneOfs = (_a = schema.oneOf) === null || _a === void 0 ? void 0 : _a.map((subschema) => reduceToSumOfProducts(subschema, componentSchemas));
|
|
55
|
+
const reducedAnyOfs = (_b = schema.anyOf) === null || _b === void 0 ? void 0 : _b.map((subschema) => reduceToSumOfProducts(subschema, componentSchemas));
|
|
56
|
+
const reducedAllOfs = (_c = schema.allOf) === null || _c === void 0 ? void 0 : _c.map((subschema) => reduceToSumOfProducts(subschema, componentSchemas));
|
|
57
|
+
const combinedOneOfs = reducedOneOfs ? [addIncrementalSchemas(reducedOneOfs)] : [];
|
|
58
|
+
const combinedAnyOfs = reducedAnyOfs ? [addIncrementalSchemas(reducedAnyOfs)] : [];
|
|
59
|
+
const multipliedAllOfs = reducedAllOfs ? [multiplyIncrementalSchemas(reducedAllOfs)] : [];
|
|
60
|
+
return multiplyIncrementalSchemas([
|
|
61
|
+
...combinedOneOfs,
|
|
62
|
+
...combinedAnyOfs,
|
|
63
|
+
...multipliedAllOfs,
|
|
64
|
+
...baseSchemaArr,
|
|
65
|
+
]);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Adds an array of schemas in sum-of-products form, returning the result
|
|
69
|
+
* as a single schema in sum-of-products form.
|
|
70
|
+
*
|
|
71
|
+
* (AB + CD) + (E + F) + (G + H) => AB + CD + E + F + G + H
|
|
72
|
+
*/
|
|
73
|
+
function addIncrementalSchemas(schemas) {
|
|
74
|
+
// this one's easy! just concatenate all the sums
|
|
75
|
+
return schemas.flat();
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Multiplies an array of schemas in sum-of-products form, returning the result
|
|
79
|
+
* as a single schema in sum-of-products form.
|
|
80
|
+
*
|
|
81
|
+
* (AB + CD)(E + F)(G + H) => ABEG + ABEH + ABFG + ABFH + CDEG + CDEH + CDFG + CDFH
|
|
82
|
+
*/
|
|
83
|
+
function multiplyIncrementalSchemas(schemas) {
|
|
84
|
+
// walking through this function, we'll use the example (AB + CD)(E + F)(G + H)
|
|
85
|
+
// base case, which allows us to essentially do (G + H)(1) = (G + H)
|
|
86
|
+
if (!schemas[0]) {
|
|
87
|
+
return [[]];
|
|
88
|
+
}
|
|
89
|
+
// now we evaluate using the distributive property:
|
|
90
|
+
// (AB + CD)(EG + EH + FG + FH) = (ABEG + ABEH + ABFG + ABFH) + (CDEG + CDEH + CDFG + CDFH)
|
|
91
|
+
// first, we recursively evaluate all remaining terms so we only have to deal with the situation above.
|
|
92
|
+
// in our scenario, the remaining terms are (E + F)(G + H), which gives us (EG + EH + FG + FH)
|
|
93
|
+
const remainingSumOfProducts = multiplyIncrementalSchemas(schemas.slice(1));
|
|
94
|
+
return schemas[0].flatMap((product /* AB */) => {
|
|
95
|
+
return remainingSumOfProducts.map((remainingProduct /* EF */) => [...product, ...remainingProduct] /* ABEF */);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* This function logically combines an array of simple schemas (schemas that contain no compositions)
|
|
100
|
+
* in preparation for conversion to `IncrementalDataSchema`. This is akin to "multiplying" all of the schemas,
|
|
101
|
+
* to continue our math analogy. The result is a single simple schema, which is easier to work with.
|
|
102
|
+
*
|
|
103
|
+
* How fields are combined depends on the field. For fields like `title` and `description` where
|
|
104
|
+
* it doesn't make sense to combine, we just take the last. For `required` we combine arrays,
|
|
105
|
+
* for `maximum` we take the minimum value, etc.
|
|
106
|
+
*
|
|
107
|
+
* @param schemas An array of simple schemas to combine
|
|
108
|
+
* @param componentSchemas The value of `document.components.schemas`. In this function, it is only used to check if properties are readOnly/writeOnly
|
|
109
|
+
* @param location Whether the schema is part of the request, response, or neither. Used for filtering readOnly/writeOnly properties
|
|
110
|
+
* @returns A single simple schema that satisfies all the input schemas
|
|
111
|
+
*/
|
|
112
|
+
export function combineSimpleSchemas(schemas, componentSchemas, location) {
|
|
113
|
+
return schemas.reduce((acc, curr) => {
|
|
114
|
+
var _a, _b, _c, _d;
|
|
115
|
+
// schemas are meant to be immutable, so copy the type
|
|
116
|
+
let currType = curr.type;
|
|
117
|
+
// don't throw an error if type is being constricted
|
|
118
|
+
if (acc.type === 'integer' && currType === 'number') {
|
|
119
|
+
currType = 'integer';
|
|
120
|
+
}
|
|
121
|
+
else if (acc.type === 'number' && currType === 'integer') {
|
|
122
|
+
acc.type = 'integer';
|
|
123
|
+
}
|
|
124
|
+
else if (acc.type === undefined && currType !== undefined) {
|
|
125
|
+
acc.type = currType;
|
|
126
|
+
}
|
|
127
|
+
else if (acc.type !== undefined && currType === undefined) {
|
|
128
|
+
currType = acc.type;
|
|
129
|
+
}
|
|
130
|
+
if (acc.type !== currType) {
|
|
131
|
+
throw new Error(`${acc.type} vs ${currType}`);
|
|
132
|
+
}
|
|
133
|
+
// we're technically breaking immutability rules here, but it's probably okay because
|
|
134
|
+
// it will be the same every time - we're just normalizing the maximum/minimum
|
|
135
|
+
// and exclusiveMaximum/exclusiveMinimum properties
|
|
136
|
+
for (const schema of [acc, curr]) {
|
|
137
|
+
if (typeof schema.exclusiveMaximum === 'number') {
|
|
138
|
+
if (schema.maximum === undefined || schema.maximum >= schema.exclusiveMaximum) {
|
|
139
|
+
schema.maximum = schema.exclusiveMaximum;
|
|
140
|
+
schema.exclusiveMaximum = true;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
schema.exclusiveMaximum = undefined;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (typeof schema.exclusiveMinimum === 'number') {
|
|
147
|
+
if (schema.minimum === undefined || schema.minimum <= schema.exclusiveMinimum) {
|
|
148
|
+
schema.minimum = schema.exclusiveMinimum;
|
|
149
|
+
schema.exclusiveMinimum = true;
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
schema.exclusiveMinimum = undefined;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
copyKeyIfDefined('title', curr, acc);
|
|
157
|
+
copyKeyIfDefined('description', curr, acc);
|
|
158
|
+
copyKeyIfDefined('format', curr, acc);
|
|
159
|
+
combineKeyIfDefined('multipleOf', curr, acc, lcm);
|
|
160
|
+
combineKeyIfDefined('maxLength', curr, acc, Math.min);
|
|
161
|
+
combineKeyIfDefined('minLength', curr, acc, Math.max);
|
|
162
|
+
combineKeyIfDefined('maxItems', curr, acc, Math.min);
|
|
163
|
+
combineKeyIfDefined('minItems', curr, acc, Math.max);
|
|
164
|
+
combineKeyIfDefined('maxProperties', curr, acc, Math.min);
|
|
165
|
+
combineKeyIfDefined('minProperties', curr, acc, Math.max);
|
|
166
|
+
combineKeyIfDefined('required', curr, acc, (a, b) => b.concat(a.filter((value) => !b.includes(value))));
|
|
167
|
+
combineKeyIfDefined('enum', curr, acc, (a, b) => b.filter((value) => a.includes(value)));
|
|
168
|
+
combineKeyIfDefined('readOnly', curr, acc, (a, b) => a && b);
|
|
169
|
+
combineKeyIfDefined('writeOnly', curr, acc, (a, b) => a && b);
|
|
170
|
+
combineKeyIfDefined('deprecated', curr, acc, (a, b) => a || b);
|
|
171
|
+
const combinedMaximum = combine(curr, acc, 'maximum', Math.min);
|
|
172
|
+
const combinedMinimum = combine(curr, acc, 'minimum', Math.max);
|
|
173
|
+
const exclusiveMaximum = (acc.maximum === combinedMaximum ? acc.exclusiveMaximum : undefined) ||
|
|
174
|
+
(curr.maximum === combinedMinimum ? curr.exclusiveMaximum : undefined);
|
|
175
|
+
addKeyIfDefined('exclusiveMaximum', exclusiveMaximum, acc);
|
|
176
|
+
const exclusiveMinimum = (acc.minimum === combinedMinimum ? acc.exclusiveMinimum : undefined) ||
|
|
177
|
+
(curr.minimum === combinedMinimum ? curr.exclusiveMinimum : undefined);
|
|
178
|
+
addKeyIfDefined('exclusiveMinimum', exclusiveMinimum, acc);
|
|
179
|
+
addKeyIfDefined('maximum', combinedMaximum, acc);
|
|
180
|
+
addKeyIfDefined('minimum', combinedMinimum, acc);
|
|
181
|
+
// don't use coalesce operator, since null is a valid example
|
|
182
|
+
const example1 = ((_a = acc.examples) === null || _a === void 0 ? void 0 : _a[0]) !== undefined ? acc.examples[0] : acc.example;
|
|
183
|
+
const example2 = ((_b = curr.examples) === null || _b === void 0 ? void 0 : _b[0]) !== undefined ? curr.examples[0] : curr.example;
|
|
184
|
+
if (example1 && example2 && typeof example1 === 'object' && typeof example2 === 'object') {
|
|
185
|
+
acc.example = Object.assign(Object.assign({}, example1), example2);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
// don't use coalesce operator, since null is a valid example
|
|
189
|
+
addKeyIfDefined('example', example2 !== undefined ? example2 : example1, acc);
|
|
190
|
+
}
|
|
191
|
+
if (curr.items) {
|
|
192
|
+
const items = (_c = acc.items) !== null && _c !== void 0 ? _c : { allOf: [] };
|
|
193
|
+
items.allOf.push(curr.items);
|
|
194
|
+
acc.items = items;
|
|
195
|
+
}
|
|
196
|
+
if (curr.properties) {
|
|
197
|
+
Object.entries(curr.properties)
|
|
198
|
+
.filter(([_, subschema]) => {
|
|
199
|
+
// dereference just for the readOnly/writeOnly check
|
|
200
|
+
if ('$ref' in subschema) {
|
|
201
|
+
const dereferencedSchema = dereference('schemas', subschema.$ref, componentSchemas);
|
|
202
|
+
if (!dereferencedSchema)
|
|
203
|
+
return true;
|
|
204
|
+
subschema = dereferencedSchema;
|
|
205
|
+
}
|
|
206
|
+
if (subschema.readOnly && location === 'request')
|
|
207
|
+
return false;
|
|
208
|
+
if (subschema.writeOnly && location === 'response')
|
|
209
|
+
return false;
|
|
210
|
+
return true;
|
|
211
|
+
})
|
|
212
|
+
.forEach(([property, subschema]) => {
|
|
213
|
+
var _a;
|
|
214
|
+
const properties = (_a = acc.properties) !== null && _a !== void 0 ? _a : {};
|
|
215
|
+
const currSchemaArr = properties[property];
|
|
216
|
+
if (currSchemaArr) {
|
|
217
|
+
currSchemaArr.allOf.push(subschema);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
properties[property] = { allOf: [subschema] };
|
|
221
|
+
}
|
|
222
|
+
acc.properties = properties;
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
if (curr.additionalProperties === false) {
|
|
226
|
+
acc.additionalProperties = false;
|
|
227
|
+
}
|
|
228
|
+
else if (acc.additionalProperties !== false &&
|
|
229
|
+
curr.additionalProperties &&
|
|
230
|
+
typeof curr.additionalProperties === 'object') {
|
|
231
|
+
const additionalProperties = (_d = acc.additionalProperties) !== null && _d !== void 0 ? _d : { allOf: [] };
|
|
232
|
+
additionalProperties.allOf.push(curr.additionalProperties);
|
|
233
|
+
acc.additionalProperties = additionalProperties;
|
|
234
|
+
}
|
|
235
|
+
return acc;
|
|
236
|
+
}, {});
|
|
237
|
+
}
|
|
238
|
+
const combineKeyIfDefined = (key, source, destination, transform) => {
|
|
239
|
+
addKeyIfDefined(key, combine(source, destination, key, transform), destination);
|
|
240
|
+
};
|
|
241
|
+
const combine = (schema1, schema2, key, transform) => {
|
|
242
|
+
var _a;
|
|
243
|
+
return schema1[key] !== undefined && schema2[key] !== undefined
|
|
244
|
+
? transform(schema1[key], schema2[key])
|
|
245
|
+
: (_a = schema1[key]) !== null && _a !== void 0 ? _a : schema2[key];
|
|
246
|
+
};
|
|
247
|
+
function convertCombinedSchema(schema, required) {
|
|
248
|
+
var _a, _b;
|
|
249
|
+
const sharedProps = {};
|
|
250
|
+
addKeyIfDefined('required', required, sharedProps);
|
|
251
|
+
copyKeyIfDefined('title', schema, sharedProps);
|
|
252
|
+
copyKeyIfDefined('description', schema, sharedProps);
|
|
253
|
+
copyKeyIfDefined('readOnly', schema, sharedProps);
|
|
254
|
+
copyKeyIfDefined('writeOnly', schema, sharedProps);
|
|
255
|
+
copyKeyIfDefined('deprecated', schema, sharedProps);
|
|
256
|
+
if (schema.type === undefined) {
|
|
257
|
+
const inferredType = inferType(schema);
|
|
258
|
+
if (inferredType === undefined) {
|
|
259
|
+
return Object.assign({ type: 'any' }, sharedProps);
|
|
260
|
+
}
|
|
261
|
+
schema.type = inferredType;
|
|
262
|
+
}
|
|
263
|
+
switch (schema.type) {
|
|
264
|
+
case 'boolean':
|
|
265
|
+
const booleanProps = sharedProps;
|
|
266
|
+
copyKeyIfDefined('default', schema, booleanProps);
|
|
267
|
+
copyExampleIfDefined(schema, booleanProps);
|
|
268
|
+
return Object.assign({ type: schema.type }, booleanProps);
|
|
269
|
+
case 'number':
|
|
270
|
+
case 'integer':
|
|
271
|
+
if (schema.enum) {
|
|
272
|
+
const numberEnumProps = sharedProps;
|
|
273
|
+
copyKeyIfDefined('default', schema, numberEnumProps);
|
|
274
|
+
copyExampleIfDefined(schema, numberEnumProps);
|
|
275
|
+
return Object.assign({ type: schema.type === 'number' ? 'enum<number>' : 'enum<integer>', enum: schema.enum.filter((option) => typeof option === 'number') }, numberEnumProps);
|
|
276
|
+
}
|
|
277
|
+
const numberProps = sharedProps;
|
|
278
|
+
copyKeyIfDefined('multipleOf', schema, numberProps);
|
|
279
|
+
copyKeyIfDefined('maximum', schema, numberProps);
|
|
280
|
+
copyKeyIfDefined('exclusiveMaximum', schema, numberProps);
|
|
281
|
+
copyKeyIfDefined('minimum', schema, numberProps);
|
|
282
|
+
copyKeyIfDefined('exclusiveMinimum', schema, numberProps);
|
|
283
|
+
copyKeyIfDefined('default', schema, numberProps);
|
|
284
|
+
copyExampleIfDefined(schema, numberProps);
|
|
285
|
+
return Object.assign({ type: schema.type }, numberProps);
|
|
286
|
+
case 'string':
|
|
287
|
+
if (schema.enum) {
|
|
288
|
+
const stringEnumProps = sharedProps;
|
|
289
|
+
copyKeyIfDefined('default', schema, stringEnumProps);
|
|
290
|
+
copyExampleIfDefined(schema, stringEnumProps);
|
|
291
|
+
return Object.assign({ type: 'enum<string>', enum: schema.enum.filter((option) => typeof option === 'string') }, stringEnumProps);
|
|
292
|
+
}
|
|
293
|
+
if (schema.format && stringFileFormats.includes(schema.format)) {
|
|
294
|
+
const fileProps = sharedProps;
|
|
295
|
+
return Object.assign({ type: 'file', contentEncoding: schema.format }, fileProps);
|
|
296
|
+
}
|
|
297
|
+
const stringProps = sharedProps;
|
|
298
|
+
copyKeyIfDefined('format', schema, stringProps);
|
|
299
|
+
copyKeyIfDefined('pattern', schema, stringProps);
|
|
300
|
+
copyKeyIfDefined('maxLength', schema, stringProps);
|
|
301
|
+
copyKeyIfDefined('minLength', schema, stringProps);
|
|
302
|
+
copyKeyIfDefined('default', schema, stringProps);
|
|
303
|
+
copyExampleIfDefined(schema, stringProps);
|
|
304
|
+
return Object.assign({ type: schema.type }, stringProps);
|
|
305
|
+
case 'array':
|
|
306
|
+
const arrayProps = sharedProps;
|
|
307
|
+
copyKeyIfDefined('maxItems', schema, arrayProps);
|
|
308
|
+
copyKeyIfDefined('minItems', schema, arrayProps);
|
|
309
|
+
copyKeyIfDefined('uniqueItems', schema, arrayProps);
|
|
310
|
+
copyKeyIfDefined('default', schema, arrayProps);
|
|
311
|
+
copyExampleIfDefined(schema, arrayProps);
|
|
312
|
+
return Object.assign({ type: schema.type, items: (_a = schema.items) !== null && _a !== void 0 ? _a : {} }, arrayProps);
|
|
313
|
+
case 'object':
|
|
314
|
+
const objectProperties = sharedProps;
|
|
315
|
+
addKeyIfDefined('requiredProperties', schema.required, objectProperties);
|
|
316
|
+
copyKeyIfDefined('additionalProperties', schema, objectProperties);
|
|
317
|
+
copyKeyIfDefined('maxProperties', schema, objectProperties);
|
|
318
|
+
copyKeyIfDefined('minProperties', schema, objectProperties);
|
|
319
|
+
copyKeyIfDefined('default', schema, objectProperties);
|
|
320
|
+
copyExampleIfDefined(schema, objectProperties);
|
|
321
|
+
return Object.assign({ type: schema.type, properties: (_b = schema.properties) !== null && _b !== void 0 ? _b : {} }, objectProperties);
|
|
322
|
+
case 'null':
|
|
323
|
+
const nullProps = sharedProps;
|
|
324
|
+
copyKeyIfDefined('default', schema, nullProps);
|
|
325
|
+
copyExampleIfDefined(schema, nullProps);
|
|
326
|
+
return Object.assign({ type: schema.type }, nullProps);
|
|
327
|
+
default:
|
|
328
|
+
throw new Error();
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
export function generateFirstIncrementalSchema(schema, componentSchemas, required, location, contentType) {
|
|
332
|
+
if (schema === undefined) {
|
|
333
|
+
// If the content type can feasibly be interpreted as a file (i.e. if it does NOT start
|
|
334
|
+
// with "application/json" or another structured data format), return a file type.
|
|
335
|
+
if (contentType && !structuredDataContentTypes.some((type) => contentType.startsWith(type))) {
|
|
336
|
+
return [{ type: 'file', contentMediaType: contentType }];
|
|
337
|
+
}
|
|
338
|
+
return [{ type: 'any' }];
|
|
339
|
+
}
|
|
340
|
+
return generateNextIncrementalSchema(schema, componentSchemas, required, location);
|
|
341
|
+
}
|
|
342
|
+
export function generateNextIncrementalSchema(schema, componentSchemas, required, location) {
|
|
343
|
+
const sumOfProducts = reduceToSumOfProducts(schema, componentSchemas);
|
|
344
|
+
const incrementalDataSchemaArray = sumOfProducts.flatMap((product) => {
|
|
345
|
+
try {
|
|
346
|
+
const combinedSchema = combineSimpleSchemas(product, componentSchemas, location);
|
|
347
|
+
return [convertCombinedSchema(combinedSchema, required)];
|
|
348
|
+
}
|
|
349
|
+
catch (_a) {
|
|
350
|
+
return [];
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
if (!incrementalDataSchemaArray[0]) {
|
|
354
|
+
// TODO: throw when `safeParse: false`
|
|
355
|
+
return [{ type: 'any' }];
|
|
356
|
+
}
|
|
357
|
+
return [incrementalDataSchemaArray[0], ...incrementalDataSchemaArray.slice(1)];
|
|
358
|
+
}
|
|
@@ -1,16 +1,36 @@
|
|
|
1
1
|
import { OpenAPIV3_1 } from 'openapi-types';
|
|
2
2
|
import { BaseConverter } from './BaseConverter.js';
|
|
3
|
-
import type { Endpoint, HttpMethod } from './types/endpoint.js';
|
|
4
|
-
|
|
3
|
+
import type { ContentSchema, DataSchemaArray, Endpoint, ExampleSchema, HttpMethod, ParameterSections, ResponseSchema } from './types/endpoint.js';
|
|
4
|
+
import { IncrementalDataSchemaArray, IncrementalEndpoint } from './types/incrementalEndpoint.js';
|
|
5
|
+
export declare abstract class BaseOpenApiToEndpointConverter<D> extends BaseConverter {
|
|
5
6
|
readonly document: OpenAPIV3_1.Document;
|
|
6
7
|
readonly path: string;
|
|
7
8
|
readonly method: HttpMethod;
|
|
8
9
|
readonly safeParse: boolean;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
protected pathObject: OpenAPIV3_1.PathItemObject;
|
|
11
|
+
protected operationObject: OpenAPIV3_1.OperationObject;
|
|
12
|
+
protected constructor(document: OpenAPIV3_1.Document, path: string, method: HttpMethod, safeParse?: boolean);
|
|
13
|
+
protected convert(): Endpoint<D>;
|
|
14
|
+
abstract convertParameters(): ParameterSections<D>;
|
|
15
|
+
abstract convertBody(): Record<string, ContentSchema<D>>;
|
|
16
|
+
abstract convertResponses(): ResponseSchema<D>;
|
|
17
|
+
protected convertExamples(examples: Record<string, OpenAPIV3_1.ExampleObject> | undefined, example: unknown | undefined, schemaArray: DataSchemaArray): Record<string, ExampleSchema>;
|
|
14
18
|
private convertCodeSamples;
|
|
15
|
-
|
|
19
|
+
}
|
|
20
|
+
export declare class OpenApiToEndpointConverter extends BaseOpenApiToEndpointConverter<DataSchemaArray> {
|
|
21
|
+
convertBody(): Record<string, ContentSchema<DataSchemaArray>>;
|
|
22
|
+
convertResponses(): ResponseSchema<DataSchemaArray>;
|
|
23
|
+
convertContent(debugPath: string[], content: Record<string, OpenAPIV3_1.MediaTypeObject> | undefined, location: 'request' | 'response', required?: boolean): Record<string, ContentSchema<DataSchemaArray>>;
|
|
24
|
+
convertParameters(): ParameterSections<DataSchemaArray>;
|
|
25
|
+
static convert(spec: OpenAPIV3_1.Document, path: string, method: HttpMethod, safeParse?: boolean): Endpoint<DataSchemaArray>;
|
|
26
|
+
}
|
|
27
|
+
export declare class OpenApiToIncrementalEndpointConverter extends BaseOpenApiToEndpointConverter<IncrementalDataSchemaArray> {
|
|
28
|
+
readonly rawDocument: OpenAPIV3_1.Document;
|
|
29
|
+
private constructor();
|
|
30
|
+
convertParameters(): ParameterSections<IncrementalDataSchemaArray>;
|
|
31
|
+
convertBody(): Record<string, ContentSchema<IncrementalDataSchemaArray>>;
|
|
32
|
+
convertResponses(): ResponseSchema<IncrementalDataSchemaArray>;
|
|
33
|
+
convertContent(debugPath: string[], rawContent: Record<string, OpenAPIV3_1.MediaTypeObject> | undefined, dereferencedContent: Record<string, OpenAPIV3_1.MediaTypeObject> | undefined, location: 'request' | 'response', required?: boolean): Record<string, ContentSchema<IncrementalDataSchemaArray>>;
|
|
34
|
+
private convertWithSchemas;
|
|
35
|
+
static convert(rawDocument: OpenAPIV3_1.Document, resolvedDocument: OpenAPIV3_1.Document, path: string, method: HttpMethod, safeParse?: boolean): IncrementalEndpoint;
|
|
16
36
|
}
|