@mintlify/validation 0.1.98 → 0.1.100
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 -2
- package/dist/index.js +2 -2
- package/dist/openapi/BaseConverter.d.ts +6 -0
- package/dist/openapi/BaseConverter.js +22 -0
- package/dist/openapi/OpenApiToEndpointConverter.d.ts +15 -0
- package/dist/openapi/OpenApiToEndpointConverter.js +100 -0
- package/dist/openapi/ParametersConverter.d.ts +15 -0
- package/dist/openapi/ParametersConverter.js +50 -0
- package/dist/openapi/SchemaConverter.d.ts +62 -0
- package/dist/openapi/SchemaConverter.js +532 -0
- package/dist/openapi/SecurityConverter.d.ts +12 -0
- package/dist/openapi/SecurityConverter.js +87 -0
- package/dist/openapi/ServersConverter.d.ts +10 -0
- package/dist/openapi/ServersConverter.js +49 -0
- package/dist/openapi/errors.d.ts +21 -0
- package/dist/openapi/errors.js +38 -0
- package/dist/openapi/utils.d.ts +2 -0
- package/dist/openapi/utils.js +12 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/dist/openapi/convertOpenApi.d.ts +0 -16
- package/dist/openapi/convertOpenApi.js +0 -118
- package/dist/openapi/convertParameters.d.ts +0 -9
- package/dist/openapi/convertParameters.js +0 -37
- package/dist/openapi/convertSchema.d.ts +0 -11
- package/dist/openapi/convertSchema.js +0 -462
- package/dist/openapi/convertSecurity.d.ts +0 -14
- package/dist/openapi/convertSecurity.js +0 -74
- package/dist/openapi/convertServers.d.ts +0 -8
- package/dist/openapi/convertServers.js +0 -39
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import { convertParameters } from './convertParameters.js';
|
|
2
|
-
import { convertSchema } from './convertSchema.js';
|
|
3
|
-
import { convertSecurity } from './convertSecurity.js';
|
|
4
|
-
import { convertServers } from './convertServers.js';
|
|
5
|
-
import { generateExampleFromSchema } from './generateExampleFromSchema.js';
|
|
6
|
-
export const generateMessage = (path, messages = []) => {
|
|
7
|
-
const pathString = path
|
|
8
|
-
.map((component) => component.replace('\\', '\\\\').replace('/', '\\/'))
|
|
9
|
-
.join('/');
|
|
10
|
-
return [pathString, ...messages].join('\n');
|
|
11
|
-
};
|
|
12
|
-
export class InvalidSchemaError extends Error {
|
|
13
|
-
constructor(path, ...messages) {
|
|
14
|
-
super(generateMessage(path, messages));
|
|
15
|
-
this.name = 'InvalidSchemaError';
|
|
16
|
-
Object.setPrototypeOf(this, InvalidSchemaError.prototype);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
export class ImpossibleSchemaError extends Error {
|
|
20
|
-
constructor(path, ...messages) {
|
|
21
|
-
super(generateMessage(path, messages));
|
|
22
|
-
this.name = 'ImpossibleSchemaError';
|
|
23
|
-
Object.setPrototypeOf(this, ImpossibleSchemaError.prototype);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
export class ConversionError extends Error {
|
|
27
|
-
constructor(path, ...messages) {
|
|
28
|
-
super(generateMessage(path, messages));
|
|
29
|
-
this.name = 'ConversionError';
|
|
30
|
-
Object.setPrototypeOf(this, ConversionError.prototype);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
export const convertContent = (path, content, required) => {
|
|
34
|
-
if (content === undefined) {
|
|
35
|
-
return {};
|
|
36
|
-
}
|
|
37
|
-
const newEntries = Object.entries(content).map(([contentType, mediaObject]) => {
|
|
38
|
-
const schemaArray = convertSchema([...path, contentType, 'schema'], mediaObject.schema, required);
|
|
39
|
-
const examples = convertExamples(mediaObject.examples, mediaObject.example, schemaArray);
|
|
40
|
-
return [contentType, { schemaArray, examples }];
|
|
41
|
-
});
|
|
42
|
-
return Object.fromEntries(newEntries);
|
|
43
|
-
};
|
|
44
|
-
export const convertExamples = (examples, example, schemaArray) => {
|
|
45
|
-
if (examples && Object.values(examples).some(({ value }) => value !== undefined)) {
|
|
46
|
-
return Object.fromEntries(Object.entries(examples)
|
|
47
|
-
.filter(([_, { value }]) => value !== undefined)
|
|
48
|
-
.map(([key, example]) => [
|
|
49
|
-
key,
|
|
50
|
-
{
|
|
51
|
-
summary: example.summary,
|
|
52
|
-
description: example.description,
|
|
53
|
-
value: example.value,
|
|
54
|
-
},
|
|
55
|
-
]));
|
|
56
|
-
}
|
|
57
|
-
if (example !== undefined) {
|
|
58
|
-
return { example: { value: example } };
|
|
59
|
-
}
|
|
60
|
-
return { example: { value: generateExampleFromSchema(schemaArray[0]) } };
|
|
61
|
-
};
|
|
62
|
-
export const convertResponses = (path, responses) => {
|
|
63
|
-
const newEntries = Object.entries(responses).map(([statusCode, response]) => [
|
|
64
|
-
statusCode,
|
|
65
|
-
convertContent([...path, statusCode, 'content'], response.content),
|
|
66
|
-
]);
|
|
67
|
-
return Object.fromEntries(newEntries);
|
|
68
|
-
};
|
|
69
|
-
export const convertOpenAPIV3_1ToEndpoint = (spec, path, method) => {
|
|
70
|
-
var _a, _b, _c, _d, _e;
|
|
71
|
-
const paths = spec.paths;
|
|
72
|
-
if (paths === undefined) {
|
|
73
|
-
throw new InvalidSchemaError(['#'], 'paths not defined');
|
|
74
|
-
}
|
|
75
|
-
const pathObject = paths[path];
|
|
76
|
-
if (pathObject === undefined) {
|
|
77
|
-
throw new InvalidSchemaError(['#', 'paths'], `path not defined: ${path}`);
|
|
78
|
-
}
|
|
79
|
-
const operationObject = pathObject[method];
|
|
80
|
-
if (operationObject === undefined) {
|
|
81
|
-
throw new InvalidSchemaError(['#', 'paths', path], `operation does not exist: ${method}`);
|
|
82
|
-
}
|
|
83
|
-
const securityRequirements = (_a = operationObject.security) !== null && _a !== void 0 ? _a : spec.security;
|
|
84
|
-
const securitySchemes = (_b = spec.components) === null || _b === void 0 ? void 0 : _b.securitySchemes;
|
|
85
|
-
const security = convertSecurity({
|
|
86
|
-
securityRequirements,
|
|
87
|
-
securitySchemes,
|
|
88
|
-
});
|
|
89
|
-
const pathParameters = pathObject.parameters;
|
|
90
|
-
const operationParameters = operationObject.parameters;
|
|
91
|
-
const parameters = convertParameters({
|
|
92
|
-
path: ['#', 'paths', path],
|
|
93
|
-
method,
|
|
94
|
-
pathParameters: pathParameters,
|
|
95
|
-
operationParameters: operationParameters,
|
|
96
|
-
});
|
|
97
|
-
const servers = convertServers({
|
|
98
|
-
servers: (_d = (_c = operationObject.servers) !== null && _c !== void 0 ? _c : pathObject.servers) !== null && _d !== void 0 ? _d : spec.servers,
|
|
99
|
-
});
|
|
100
|
-
const description = (_e = operationObject.description) !== null && _e !== void 0 ? _e : pathObject === null || pathObject === void 0 ? void 0 : pathObject.description;
|
|
101
|
-
const requestBody = operationObject.requestBody;
|
|
102
|
-
const body = convertContent(['#', 'paths', path, method, 'requestBody', 'content'], requestBody === null || requestBody === void 0 ? void 0 : requestBody.content, requestBody === null || requestBody === void 0 ? void 0 : requestBody.required);
|
|
103
|
-
const deprecated = !!operationObject.deprecated;
|
|
104
|
-
const response = convertResponses(['#', 'paths', path, method, 'responses'], operationObject.responses);
|
|
105
|
-
return {
|
|
106
|
-
description,
|
|
107
|
-
path,
|
|
108
|
-
method,
|
|
109
|
-
servers,
|
|
110
|
-
request: {
|
|
111
|
-
security,
|
|
112
|
-
parameters,
|
|
113
|
-
body,
|
|
114
|
-
},
|
|
115
|
-
response,
|
|
116
|
-
deprecated,
|
|
117
|
-
};
|
|
118
|
-
};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { OpenAPIV3_1 } from 'openapi-types';
|
|
2
|
-
import { ParameterSections } from './types/endpoint.js';
|
|
3
|
-
export type ConvertParametersParams = {
|
|
4
|
-
path: string[];
|
|
5
|
-
method: string;
|
|
6
|
-
pathParameters: OpenAPIV3_1.ParameterObject[] | undefined;
|
|
7
|
-
operationParameters: OpenAPIV3_1.ParameterObject[] | undefined;
|
|
8
|
-
};
|
|
9
|
-
export declare const convertParameters: ({ path, method, pathParameters, operationParameters, }: ConvertParametersParams) => ParameterSections;
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { InvalidSchemaError } from './convertOpenApi.js';
|
|
2
|
-
import { convertSchema, copyKeyIfDefined } from './convertSchema.js';
|
|
3
|
-
export const convertParameters = ({ path, method, pathParameters, operationParameters, }) => {
|
|
4
|
-
const parameterSections = {
|
|
5
|
-
path: {},
|
|
6
|
-
query: {},
|
|
7
|
-
header: {},
|
|
8
|
-
cookie: {},
|
|
9
|
-
};
|
|
10
|
-
pathParameters === null || pathParameters === void 0 ? void 0 : pathParameters.forEach((parameterObject, i) => {
|
|
11
|
-
addParameter({
|
|
12
|
-
path: [...path, 'parameters', i.toString()],
|
|
13
|
-
parameter: parameterObject,
|
|
14
|
-
parameterSections,
|
|
15
|
-
});
|
|
16
|
-
});
|
|
17
|
-
operationParameters === null || operationParameters === void 0 ? void 0 : operationParameters.forEach((parameterObject, i) => {
|
|
18
|
-
addParameter({
|
|
19
|
-
path: [...path, method, 'parameters', i.toString()],
|
|
20
|
-
parameter: parameterObject,
|
|
21
|
-
parameterSections,
|
|
22
|
-
});
|
|
23
|
-
});
|
|
24
|
-
return parameterSections;
|
|
25
|
-
};
|
|
26
|
-
const addParameter = ({ path, parameter, parameterSections }) => {
|
|
27
|
-
if (!['path', 'header', 'query', 'cookie'].includes(parameter.in)) {
|
|
28
|
-
throw new InvalidSchemaError(path, `invalid parameter location: '${parameter.in}'`);
|
|
29
|
-
}
|
|
30
|
-
const location = parameter.in;
|
|
31
|
-
// parameter.schema may be undefined (if the schema is instead defined in parameter.content), but this is likely super rare
|
|
32
|
-
const parameterSchema = parameter.schema;
|
|
33
|
-
copyKeyIfDefined('description', parameter, parameterSchema);
|
|
34
|
-
copyKeyIfDefined('deprecated', parameter, parameterSchema);
|
|
35
|
-
const newParameter = convertSchema([...path, 'schema'], parameter.schema, location === 'path' ? true : parameter.required);
|
|
36
|
-
parameterSections[location][parameter.name] = { schema: newParameter };
|
|
37
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { OpenAPIV3_1 } from 'openapi-types';
|
|
2
|
-
import { DataSchemaArray } from './types/endpoint.js';
|
|
3
|
-
export declare const convertSchema: (path: string[], schema: OpenAPIV3_1.SchemaObject | undefined, required?: boolean) => DataSchemaArray;
|
|
4
|
-
export declare const combineTopLevelSchemas: (path: string[], schema1: OpenAPIV3_1.SchemaObject, schema2: OpenAPIV3_1.SchemaObject) => OpenAPIV3_1.SchemaObject;
|
|
5
|
-
export declare const addKeyIfDefined: <D, K extends keyof D>(key: K, value: D[K], destination: D) => void;
|
|
6
|
-
export declare const copyKeyIfDefined: <D, K extends keyof D>(key: K, source: Pick<D, K>, destination: D) => void;
|
|
7
|
-
export declare const convertProperties: (path: string[], properties: {
|
|
8
|
-
[key: string]: OpenAPIV3_1.SchemaObject;
|
|
9
|
-
} | undefined, required?: string[]) => {
|
|
10
|
-
[key: string]: DataSchemaArray;
|
|
11
|
-
};
|
|
@@ -1,462 +0,0 @@
|
|
|
1
|
-
import lcm from 'lcm';
|
|
2
|
-
import _ from 'lodash';
|
|
3
|
-
import { ConversionError, ImpossibleSchemaError, InvalidSchemaError } from './convertOpenApi.js';
|
|
4
|
-
import { typeList, } from './types/endpoint.js';
|
|
5
|
-
export const convertSchema = (path, schema, required) => {
|
|
6
|
-
if (schema === undefined) {
|
|
7
|
-
throw new InvalidSchemaError(path, 'schema undefined');
|
|
8
|
-
}
|
|
9
|
-
// TODO(ronan): remove when fully migrated to endpoint type, or don't modify schema in evaluateCompositionsRecursive
|
|
10
|
-
schema = _.cloneDeep(schema);
|
|
11
|
-
schema = evaluateCompositionsRecursive(path, schema);
|
|
12
|
-
return convertSchemaRecursive(path, schema, required);
|
|
13
|
-
};
|
|
14
|
-
/**
|
|
15
|
-
* This function should be used to reduce strictly `oneOf` and `anyOf` compositions.
|
|
16
|
-
*
|
|
17
|
-
* @param schemaArray `schema.allOf` or `schema.oneOf`
|
|
18
|
-
* @returns a schema array equivalent to the `schemaArray` argument, but in reduced form
|
|
19
|
-
*/
|
|
20
|
-
const evaluateOptionsCompositions = (path, schemaArray) => {
|
|
21
|
-
const evaluatedArray = schemaArray.flatMap((subschema, i) => {
|
|
22
|
-
var _a;
|
|
23
|
-
try {
|
|
24
|
-
return (_a = evaluateCompositionsRecursive([...path, i.toString()], subschema).oneOf) !== null && _a !== void 0 ? _a : [];
|
|
25
|
-
}
|
|
26
|
-
catch (error) {
|
|
27
|
-
if (error instanceof ImpossibleSchemaError) {
|
|
28
|
-
return [];
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
throw error;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
if (evaluatedArray.length === 0) {
|
|
36
|
-
throw new ImpossibleSchemaError(path, 'no valid options in schema:', JSON.stringify(schemaArray, undefined, 2));
|
|
37
|
-
}
|
|
38
|
-
return evaluatedArray;
|
|
39
|
-
};
|
|
40
|
-
const evaluateCompositionsRecursive = (path, schema) => {
|
|
41
|
-
// evaluate compositions first; we are currently ignoring `not`
|
|
42
|
-
if (schema.oneOf && schema.oneOf.length > 0) {
|
|
43
|
-
schema.oneOf = evaluateOptionsCompositions([...path, 'oneOf'], schema.oneOf);
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
schema.oneOf = [];
|
|
47
|
-
}
|
|
48
|
-
if (schema.anyOf && schema.anyOf.length > 0) {
|
|
49
|
-
schema.anyOf = evaluateOptionsCompositions([...path, 'anyOf'], schema.anyOf);
|
|
50
|
-
}
|
|
51
|
-
if (schema.allOf && schema.allOf.length > 0) {
|
|
52
|
-
const totalAllOfObj = schema.allOf
|
|
53
|
-
.map((subschema, i) => evaluateCompositionsRecursive([...path, 'allOf', i.toString()], subschema))
|
|
54
|
-
.reduce((schema1, schema2, i) => combineReducedSchemas([...path, 'allOf', i.toString()], schema1, schema2), {
|
|
55
|
-
oneOf: [],
|
|
56
|
-
});
|
|
57
|
-
schema.oneOf = multiplySchemaArrays(path, schema.oneOf, totalAllOfObj.oneOf);
|
|
58
|
-
}
|
|
59
|
-
// evaluate subschemas, if present
|
|
60
|
-
if (schema.properties) {
|
|
61
|
-
for (const key in schema.properties) {
|
|
62
|
-
schema.properties[key] = evaluateCompositionsRecursive([...path, 'properties', key], schema.properties[key]);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
if (schema.items) {
|
|
66
|
-
schema.items = evaluateCompositionsRecursive([...path, 'items'], schema.items);
|
|
67
|
-
}
|
|
68
|
-
if (schema.additionalProperties && typeof schema.additionalProperties === 'object') {
|
|
69
|
-
try {
|
|
70
|
-
schema.additionalProperties = evaluateCompositionsRecursive([...path, 'additionalProperties'], schema.additionalProperties);
|
|
71
|
-
}
|
|
72
|
-
catch (error) {
|
|
73
|
-
if (error instanceof ImpossibleSchemaError) {
|
|
74
|
-
// if additionalProperties schema is impossible, rather than error, just disallow additionalProperties
|
|
75
|
-
schema.additionalProperties = false;
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
throw error;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
if (schema.anyOf && schema.anyOf.length > 0) {
|
|
83
|
-
schema.oneOf = multiplySchemaArrays(path, schema.oneOf, schema.anyOf);
|
|
84
|
-
}
|
|
85
|
-
const topLevelSchemaArray = generateTopLevelSchemaArray(schema);
|
|
86
|
-
return { oneOf: multiplySchemaArrays(path, schema.oneOf, topLevelSchemaArray) };
|
|
87
|
-
};
|
|
88
|
-
const generateTopLevelSchemaArray = (schema) => {
|
|
89
|
-
if (schema.nullable) {
|
|
90
|
-
const typedSchema = Object.assign({}, schema);
|
|
91
|
-
delete typedSchema.oneOf;
|
|
92
|
-
delete typedSchema.nullable;
|
|
93
|
-
const nullSchema = Object.assign({}, schema);
|
|
94
|
-
delete nullSchema.oneOf;
|
|
95
|
-
delete nullSchema.nullable;
|
|
96
|
-
nullSchema.type = 'null';
|
|
97
|
-
return [typedSchema, nullSchema];
|
|
98
|
-
}
|
|
99
|
-
if (Array.isArray(schema.type)) {
|
|
100
|
-
if (schema.type.length === 0) {
|
|
101
|
-
const topLevelSchema = Object.assign({}, schema);
|
|
102
|
-
delete topLevelSchema.oneOf;
|
|
103
|
-
delete topLevelSchema.type;
|
|
104
|
-
return [topLevelSchema];
|
|
105
|
-
}
|
|
106
|
-
return schema.type.map((typeString) => {
|
|
107
|
-
const topLevelSchema = Object.assign({}, schema);
|
|
108
|
-
delete topLevelSchema.oneOf;
|
|
109
|
-
topLevelSchema.type = typeString;
|
|
110
|
-
return topLevelSchema;
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
const topLevelSchema = Object.assign({}, schema);
|
|
114
|
-
delete topLevelSchema.oneOf;
|
|
115
|
-
return [topLevelSchema];
|
|
116
|
-
};
|
|
117
|
-
/**
|
|
118
|
-
* Given two arrays representing schema options, return an array representing schema options that satisfy one element in both arrays.
|
|
119
|
-
*
|
|
120
|
-
* It is helpful to think of each array as a union of all the schemas in the array. This function can then be thought of as taking
|
|
121
|
-
* the intersection of the two union types.
|
|
122
|
-
*
|
|
123
|
-
* @param a first array of schema options
|
|
124
|
-
* @param b second array of schema options
|
|
125
|
-
* @returns array of schemas that satisfy both arrays
|
|
126
|
-
*/
|
|
127
|
-
const multiplySchemaArrays = (path, a, b) => {
|
|
128
|
-
if (a.length === 0 && b.length === 0) {
|
|
129
|
-
return [{}];
|
|
130
|
-
}
|
|
131
|
-
if (a.length === 0) {
|
|
132
|
-
return b;
|
|
133
|
-
}
|
|
134
|
-
if (b.length === 0) {
|
|
135
|
-
return a;
|
|
136
|
-
}
|
|
137
|
-
const product = a.flatMap((schema1) => {
|
|
138
|
-
return b.flatMap((schema2) => {
|
|
139
|
-
try {
|
|
140
|
-
const combinedSchema = combineTopLevelSchemas(path, schema1, schema2);
|
|
141
|
-
return [combinedSchema];
|
|
142
|
-
}
|
|
143
|
-
catch (error) {
|
|
144
|
-
if (error instanceof ImpossibleSchemaError) {
|
|
145
|
-
return [];
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
throw error;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
if (product.length === 0) {
|
|
154
|
-
throw new ImpossibleSchemaError(path, 'impossible schema combination:', 'schema array 1:', JSON.stringify(a, undefined, 2), 'schema array 2:', JSON.stringify(b, undefined, 2));
|
|
155
|
-
}
|
|
156
|
-
return product;
|
|
157
|
-
};
|
|
158
|
-
const combineReducedSchemas = (path, schema1, schema2) => {
|
|
159
|
-
var _a, _b;
|
|
160
|
-
return {
|
|
161
|
-
oneOf: multiplySchemaArrays(path, ((_a = schema1.oneOf) !== null && _a !== void 0 ? _a : []), ((_b = schema2.oneOf) !== null && _b !== void 0 ? _b : [])),
|
|
162
|
-
};
|
|
163
|
-
};
|
|
164
|
-
export const combineTopLevelSchemas = (path, schema1, schema2) => {
|
|
165
|
-
var _a, _b, _c, _d;
|
|
166
|
-
let type1 = schema1.type;
|
|
167
|
-
let type2 = schema2.type;
|
|
168
|
-
// don't throw an error if number type is being constricted
|
|
169
|
-
if (type1 === 'integer' && type2 === 'number') {
|
|
170
|
-
type2 = 'integer';
|
|
171
|
-
}
|
|
172
|
-
else if (type1 === 'number' && type2 === 'integer') {
|
|
173
|
-
type1 = 'integer';
|
|
174
|
-
}
|
|
175
|
-
if (type1 && type2 && type1 !== type2) {
|
|
176
|
-
throw new ImpossibleSchemaError(path, `mismatched type in composition: "${type1}" "${type2}"`);
|
|
177
|
-
}
|
|
178
|
-
for (const schema of [schema1, schema2]) {
|
|
179
|
-
if (typeof schema.exclusiveMaximum === 'number') {
|
|
180
|
-
if (schema.maximum === undefined || schema.maximum >= schema.exclusiveMaximum) {
|
|
181
|
-
schema.maximum = schema.exclusiveMaximum;
|
|
182
|
-
schema.exclusiveMaximum = true;
|
|
183
|
-
}
|
|
184
|
-
else {
|
|
185
|
-
schema.exclusiveMaximum = undefined;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
if (typeof schema.exclusiveMinimum === 'number') {
|
|
189
|
-
if (schema.minimum === undefined || schema.minimum <= schema.exclusiveMinimum) {
|
|
190
|
-
schema.minimum = schema.exclusiveMinimum;
|
|
191
|
-
schema.exclusiveMinimum = true;
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
schema.exclusiveMinimum = undefined;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
const combinedSchema = {
|
|
199
|
-
title: takeLast(schema1, schema2, 'title'),
|
|
200
|
-
description: takeLast(schema1, schema2, 'description'),
|
|
201
|
-
format: takeLast(schema1, schema2, 'format'),
|
|
202
|
-
multipleOf: combine(schema1, schema2, 'multipleOf', lcm),
|
|
203
|
-
maximum: combine(schema1, schema2, 'maximum', Math.min),
|
|
204
|
-
minimum: combine(schema1, schema2, 'minimum', Math.max),
|
|
205
|
-
maxLength: combine(schema1, schema2, 'maxLength', Math.min),
|
|
206
|
-
minLength: combine(schema1, schema2, 'minLength', Math.max),
|
|
207
|
-
maxItems: combine(schema1, schema2, 'maxItems', Math.min),
|
|
208
|
-
minItems: combine(schema1, schema2, 'minItems', Math.max),
|
|
209
|
-
maxProperties: combine(schema1, schema2, 'maxProperties', Math.min),
|
|
210
|
-
minProperties: combine(schema1, schema2, 'minProperties', Math.max),
|
|
211
|
-
required: combine(schema1, schema2, 'required', (a, b) => b.concat(a.filter((value) => !b.includes(value)))),
|
|
212
|
-
enum: combine(schema1, schema2, 'enum', (a, b) => b.filter((value) => a.includes(value))),
|
|
213
|
-
readOnly: schema1.readOnly && schema2.readOnly,
|
|
214
|
-
writeOnly: schema1.writeOnly && schema2.writeOnly,
|
|
215
|
-
deprecated: schema1.deprecated && schema2.deprecated,
|
|
216
|
-
};
|
|
217
|
-
combinedSchema.exclusiveMaximum =
|
|
218
|
-
(schema1.maximum === combinedSchema.maximum ? schema1.exclusiveMaximum : undefined) ||
|
|
219
|
-
(schema2.maximum === combinedSchema.maximum ? schema2.exclusiveMaximum : undefined);
|
|
220
|
-
combinedSchema.exclusiveMinimum =
|
|
221
|
-
(schema1.minimum === combinedSchema.minimum ? schema1.exclusiveMinimum : undefined) ||
|
|
222
|
-
(schema2.minimum === combinedSchema.minimum ? schema2.exclusiveMinimum : undefined);
|
|
223
|
-
// don't use coalesce operator, since null is a valid example
|
|
224
|
-
const example1 = ((_a = schema1.examples) === null || _a === void 0 ? void 0 : _a[0]) !== undefined ? schema1.examples[0] : schema1.example;
|
|
225
|
-
const example2 = ((_b = schema2.examples) === null || _b === void 0 ? void 0 : _b[0]) !== undefined ? schema2.examples[0] : schema2.example;
|
|
226
|
-
if (example1 && example2 && typeof example1 === 'object' && typeof example2 === 'object') {
|
|
227
|
-
combinedSchema.example = Object.assign(Object.assign({}, example1), example2);
|
|
228
|
-
}
|
|
229
|
-
else {
|
|
230
|
-
// don't use coalesce operator, since null is a valid example
|
|
231
|
-
combinedSchema.example = example2 !== undefined ? example2 : example1;
|
|
232
|
-
}
|
|
233
|
-
const type = type1 !== null && type1 !== void 0 ? type1 : type2;
|
|
234
|
-
if (type === 'array') {
|
|
235
|
-
return Object.assign({ type, items: combineReducedSchemas([...path, 'items'], (_c = schema1.items) !== null && _c !== void 0 ? _c : {}, (_d = schema2.items) !== null && _d !== void 0 ? _d : {}) }, combinedSchema);
|
|
236
|
-
}
|
|
237
|
-
if (schema1.properties && schema2.properties) {
|
|
238
|
-
const combinedProperties = Object.assign({}, schema1.properties);
|
|
239
|
-
Object.entries(schema2.properties).forEach(([property, schema]) => {
|
|
240
|
-
const schema1Property = combinedProperties[property];
|
|
241
|
-
if (schema1Property) {
|
|
242
|
-
combinedProperties[property] = combineReducedSchemas([...path, 'properties', property], schema1Property, schema);
|
|
243
|
-
}
|
|
244
|
-
else {
|
|
245
|
-
combinedProperties[property] = schema;
|
|
246
|
-
}
|
|
247
|
-
});
|
|
248
|
-
combinedSchema.properties = combinedProperties;
|
|
249
|
-
}
|
|
250
|
-
else if (schema1.properties || schema2.properties) {
|
|
251
|
-
combinedSchema.properties = Object.assign(Object.assign({}, schema1.properties), schema2.properties);
|
|
252
|
-
}
|
|
253
|
-
if (schema1.additionalProperties === false || schema2.additionalProperties === false) {
|
|
254
|
-
combinedSchema.additionalProperties = false;
|
|
255
|
-
}
|
|
256
|
-
else if (schema1.additionalProperties &&
|
|
257
|
-
typeof schema1.additionalProperties === 'object' &&
|
|
258
|
-
schema2.additionalProperties &&
|
|
259
|
-
typeof schema2.additionalProperties === 'object') {
|
|
260
|
-
combinedSchema.additionalProperties = combineReducedSchemas([...path, 'additionalProperties'], schema1.additionalProperties, schema2.additionalProperties);
|
|
261
|
-
}
|
|
262
|
-
else if (schema1.additionalProperties && typeof schema1.additionalProperties === 'object') {
|
|
263
|
-
combinedSchema.additionalProperties = schema1.additionalProperties;
|
|
264
|
-
}
|
|
265
|
-
else if (schema2.additionalProperties && typeof schema2.additionalProperties === 'object') {
|
|
266
|
-
combinedSchema.additionalProperties = schema2.additionalProperties;
|
|
267
|
-
}
|
|
268
|
-
return Object.assign({ type }, combinedSchema);
|
|
269
|
-
};
|
|
270
|
-
export const addKeyIfDefined = (key, value, destination) => {
|
|
271
|
-
if (value !== undefined) {
|
|
272
|
-
destination[key] = value;
|
|
273
|
-
}
|
|
274
|
-
};
|
|
275
|
-
export const copyKeyIfDefined = (key, source, destination) => {
|
|
276
|
-
if (source[key] !== undefined) {
|
|
277
|
-
destination[key] = source[key];
|
|
278
|
-
}
|
|
279
|
-
};
|
|
280
|
-
const copyExampleIfDefined = (source, destination) => {
|
|
281
|
-
var _a;
|
|
282
|
-
const example = ((_a = source.examples) === null || _a === void 0 ? void 0 : _a[0]) !== undefined ? source.examples[0] : source.example;
|
|
283
|
-
if (example !== undefined) {
|
|
284
|
-
destination.example = example;
|
|
285
|
-
}
|
|
286
|
-
};
|
|
287
|
-
const takeLast = (schema1, schema2, key) => {
|
|
288
|
-
var _a;
|
|
289
|
-
return (_a = schema2[key]) !== null && _a !== void 0 ? _a : schema1[key];
|
|
290
|
-
};
|
|
291
|
-
const combine = (schema1, schema2, key, transform) => {
|
|
292
|
-
var _a;
|
|
293
|
-
return schema1[key] !== undefined && schema2[key] !== undefined
|
|
294
|
-
? transform(schema1[key], schema2[key])
|
|
295
|
-
: (_a = schema1[key]) !== null && _a !== void 0 ? _a : schema2[key];
|
|
296
|
-
};
|
|
297
|
-
const convertSchemaRecursive = (path, schema, required) => {
|
|
298
|
-
if (schema.oneOf === undefined || schema.oneOf.length === 0) {
|
|
299
|
-
throw new ConversionError(path, 'missing schema definition');
|
|
300
|
-
}
|
|
301
|
-
const schemaArray = schema.oneOf.map((schema) => {
|
|
302
|
-
const sharedProps = {};
|
|
303
|
-
addKeyIfDefined('required', required, sharedProps);
|
|
304
|
-
copyKeyIfDefined('title', schema, sharedProps);
|
|
305
|
-
copyKeyIfDefined('description', schema, sharedProps);
|
|
306
|
-
copyKeyIfDefined('readOnly', schema, sharedProps);
|
|
307
|
-
copyKeyIfDefined('writeOnly', schema, sharedProps);
|
|
308
|
-
copyKeyIfDefined('deprecated', schema, sharedProps);
|
|
309
|
-
if (schema.type === undefined) {
|
|
310
|
-
const inferredType = inferType(schema);
|
|
311
|
-
if (inferredType === undefined) {
|
|
312
|
-
return Object.assign({ type: 'any' }, sharedProps);
|
|
313
|
-
}
|
|
314
|
-
schema.type = inferredType;
|
|
315
|
-
}
|
|
316
|
-
const type = schema.type;
|
|
317
|
-
if (!typeList.includes(type)) {
|
|
318
|
-
throw new InvalidSchemaError(path, `invalid schema type: ${schema.type}`);
|
|
319
|
-
}
|
|
320
|
-
switch (schema.type) {
|
|
321
|
-
case 'boolean':
|
|
322
|
-
const booleanProps = sharedProps;
|
|
323
|
-
copyKeyIfDefined('default', schema, booleanProps);
|
|
324
|
-
copyExampleIfDefined(schema, booleanProps);
|
|
325
|
-
return Object.assign({ type: schema.type }, booleanProps);
|
|
326
|
-
case 'number':
|
|
327
|
-
case 'integer':
|
|
328
|
-
if (schema.enum) {
|
|
329
|
-
const numberEnumProps = sharedProps;
|
|
330
|
-
copyKeyIfDefined('default', schema, numberEnumProps);
|
|
331
|
-
copyExampleIfDefined(schema, numberEnumProps);
|
|
332
|
-
return Object.assign({ type: schema.type === 'number' ? 'enum<number>' : 'enum<integer>', enum: schema.enum }, numberEnumProps);
|
|
333
|
-
}
|
|
334
|
-
const numberProps = sharedProps;
|
|
335
|
-
copyKeyIfDefined('multipleOf', schema, numberProps);
|
|
336
|
-
copyKeyIfDefined('maximum', schema, numberProps);
|
|
337
|
-
copyKeyIfDefined('exclusiveMaximum', schema, numberProps);
|
|
338
|
-
copyKeyIfDefined('minimum', schema, numberProps);
|
|
339
|
-
copyKeyIfDefined('exclusiveMinimum', schema, numberProps);
|
|
340
|
-
copyKeyIfDefined('default', schema, numberProps);
|
|
341
|
-
copyExampleIfDefined(schema, numberProps);
|
|
342
|
-
return Object.assign({ type: schema.type }, numberProps);
|
|
343
|
-
case 'string':
|
|
344
|
-
if (schema.enum) {
|
|
345
|
-
const stringEnumProps = sharedProps;
|
|
346
|
-
copyKeyIfDefined('default', schema, stringEnumProps);
|
|
347
|
-
copyExampleIfDefined(schema, stringEnumProps);
|
|
348
|
-
return Object.assign({ type: 'enum<string>', enum: schema.enum }, stringEnumProps);
|
|
349
|
-
}
|
|
350
|
-
const stringProps = sharedProps;
|
|
351
|
-
copyKeyIfDefined('format', schema, stringProps);
|
|
352
|
-
copyKeyIfDefined('pattern', schema, stringProps);
|
|
353
|
-
copyKeyIfDefined('maxLength', schema, stringProps);
|
|
354
|
-
copyKeyIfDefined('minLength', schema, stringProps);
|
|
355
|
-
copyKeyIfDefined('default', schema, stringProps);
|
|
356
|
-
copyExampleIfDefined(schema, stringProps);
|
|
357
|
-
return Object.assign({ type: schema.type }, stringProps);
|
|
358
|
-
case 'array':
|
|
359
|
-
const arrayProps = sharedProps;
|
|
360
|
-
const items = typeof schema.items === 'object' && schema.items != null
|
|
361
|
-
? convertSchemaRecursive([...path, 'items'], schema.items)
|
|
362
|
-
: [{ type: 'any' }];
|
|
363
|
-
copyKeyIfDefined('maxItems', schema, arrayProps);
|
|
364
|
-
copyKeyIfDefined('minItems', schema, arrayProps);
|
|
365
|
-
copyKeyIfDefined('uniqueItems', schema, arrayProps);
|
|
366
|
-
copyKeyIfDefined('default', schema, arrayProps);
|
|
367
|
-
copyExampleIfDefined(schema, arrayProps);
|
|
368
|
-
return Object.assign({ type: schema.type, items }, arrayProps);
|
|
369
|
-
case 'object':
|
|
370
|
-
const properties = convertProperties([...path, 'properties'], schema.properties, schema.required);
|
|
371
|
-
const additionalProperties = typeof schema.additionalProperties === 'object' && schema.additionalProperties != null
|
|
372
|
-
? convertSchemaRecursive([...path, 'additionalProperties'], schema.additionalProperties)
|
|
373
|
-
: schema.additionalProperties;
|
|
374
|
-
const objectProperties = sharedProps;
|
|
375
|
-
addKeyIfDefined('additionalProperties', additionalProperties, objectProperties);
|
|
376
|
-
copyKeyIfDefined('maxProperties', schema, objectProperties);
|
|
377
|
-
copyKeyIfDefined('minProperties', schema, objectProperties);
|
|
378
|
-
copyKeyIfDefined('default', schema, objectProperties);
|
|
379
|
-
copyExampleIfDefined(schema, objectProperties);
|
|
380
|
-
return Object.assign({ type: schema.type, properties }, objectProperties);
|
|
381
|
-
case 'null':
|
|
382
|
-
const nullProps = sharedProps;
|
|
383
|
-
copyKeyIfDefined('default', schema, nullProps);
|
|
384
|
-
copyExampleIfDefined(schema, nullProps);
|
|
385
|
-
return Object.assign({ type: schema.type }, nullProps);
|
|
386
|
-
default:
|
|
387
|
-
throw new ImpossibleSchemaError(path, `impossible type reached: ${schema.type}`);
|
|
388
|
-
}
|
|
389
|
-
});
|
|
390
|
-
if (!schemaArray[0]) {
|
|
391
|
-
throw new ConversionError(path, 'missing schema definition in position 0');
|
|
392
|
-
}
|
|
393
|
-
// must unpack first element to satisfy type
|
|
394
|
-
return [schemaArray[0], ...schemaArray.slice(1)];
|
|
395
|
-
};
|
|
396
|
-
export const convertProperties = (path, properties, required) => {
|
|
397
|
-
if (properties === undefined) {
|
|
398
|
-
return {};
|
|
399
|
-
}
|
|
400
|
-
const newEntries = Object.entries(properties).map(([name, schema]) => {
|
|
401
|
-
return [
|
|
402
|
-
name,
|
|
403
|
-
convertSchemaRecursive([...path, name], schema, (required === null || required === void 0 ? void 0 : required.includes(name)) ? true : undefined),
|
|
404
|
-
];
|
|
405
|
-
});
|
|
406
|
-
return Object.fromEntries(newEntries);
|
|
407
|
-
};
|
|
408
|
-
/**
|
|
409
|
-
* Given an OpenAPI 3.1 schema, this function will attempt to determine the schema type
|
|
410
|
-
* based on the properties present in the schema. This is useful for assigning types to
|
|
411
|
-
* schemas that are missing a type.
|
|
412
|
-
*
|
|
413
|
-
* For example, if a schema has no type but has `schema.properties`, we can infer the
|
|
414
|
-
* intended type is `object`.
|
|
415
|
-
*
|
|
416
|
-
* @param schema
|
|
417
|
-
* @returns if exactly one type can be inferred, the string corresponding to that type; otherwise `undefined`
|
|
418
|
-
*/
|
|
419
|
-
const inferType = (schema) => {
|
|
420
|
-
var _a, _b;
|
|
421
|
-
let type = undefined;
|
|
422
|
-
if (schema.format !== undefined ||
|
|
423
|
-
schema.pattern !== undefined ||
|
|
424
|
-
schema.minLength !== undefined ||
|
|
425
|
-
schema.maxLength !== undefined ||
|
|
426
|
-
((_a = schema.enum) === null || _a === void 0 ? void 0 : _a.every((option) => typeof option === 'string'))) {
|
|
427
|
-
if (type !== undefined) {
|
|
428
|
-
return undefined;
|
|
429
|
-
}
|
|
430
|
-
type = 'string';
|
|
431
|
-
}
|
|
432
|
-
if (schema.multipleOf !== undefined ||
|
|
433
|
-
schema.minimum !== undefined ||
|
|
434
|
-
schema.maximum !== undefined ||
|
|
435
|
-
schema.exclusiveMinimum !== undefined ||
|
|
436
|
-
schema.exclusiveMaximum !== undefined ||
|
|
437
|
-
((_b = schema.enum) === null || _b === void 0 ? void 0 : _b.every((option) => typeof option === 'number'))) {
|
|
438
|
-
if (type !== undefined) {
|
|
439
|
-
return undefined;
|
|
440
|
-
}
|
|
441
|
-
type = 'number'; // less specific than 'integer'
|
|
442
|
-
}
|
|
443
|
-
if (schema.items !== undefined ||
|
|
444
|
-
schema.minItems !== undefined ||
|
|
445
|
-
schema.maxItems !== undefined ||
|
|
446
|
-
schema.uniqueItems !== undefined) {
|
|
447
|
-
if (type !== undefined) {
|
|
448
|
-
return undefined;
|
|
449
|
-
}
|
|
450
|
-
type = 'array';
|
|
451
|
-
}
|
|
452
|
-
if (schema.additionalProperties !== undefined ||
|
|
453
|
-
schema.properties !== undefined ||
|
|
454
|
-
schema.minProperties !== undefined ||
|
|
455
|
-
schema.maxProperties !== undefined) {
|
|
456
|
-
if (type !== undefined) {
|
|
457
|
-
return undefined;
|
|
458
|
-
}
|
|
459
|
-
type = 'object';
|
|
460
|
-
}
|
|
461
|
-
return type;
|
|
462
|
-
};
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { OpenAPIV3_1 } from 'openapi-types';
|
|
2
|
-
import { SecurityOption, SecurityParameterSections } from './types/endpoint.js';
|
|
3
|
-
type ConvertSecurityParams = {
|
|
4
|
-
securityRequirements?: OpenAPIV3_1.SecurityRequirementObject[];
|
|
5
|
-
securitySchemes: OpenAPIV3_1.ComponentsObject['securitySchemes'];
|
|
6
|
-
};
|
|
7
|
-
export declare const convertSecurity: ({ securityRequirements, securitySchemes, }: ConvertSecurityParams) => SecurityOption[];
|
|
8
|
-
type AddSecurityParametersParams = {
|
|
9
|
-
securityName: string;
|
|
10
|
-
securityScheme: OpenAPIV3_1.SecuritySchemeObject;
|
|
11
|
-
parameterSections: SecurityParameterSections;
|
|
12
|
-
};
|
|
13
|
-
export declare const addSecurityParameters: ({ securityName, securityScheme, parameterSections, }: AddSecurityParametersParams) => void;
|
|
14
|
-
export {};
|