@samchon/openapi
Advanced tools
Comparing version 0.1.18 to 0.1.19
@@ -53,10 +53,10 @@ "use strict"; | ||
.map((p) => { | ||
var _a, _b, _c, _d, _e, _f; | ||
var _a, _b, _c, _d, _e, _f, _g, _h; | ||
if (!TypeChecker.isReference(p)) | ||
return convertParameter(p); | ||
return convertParameter((_a = doc.components) !== null && _a !== void 0 ? _a : {})(p); | ||
const found = p.$ref.startsWith("#/components/headers/") | ||
? (_b = (_a = doc.components) === null || _a === void 0 ? void 0 : _a.headers) === null || _b === void 0 ? void 0 : _b[(_c = p.$ref.split("/").pop()) !== null && _c !== void 0 ? _c : ""] | ||
: (_e = (_d = doc.components) === null || _d === void 0 ? void 0 : _d.parameters) === null || _e === void 0 ? void 0 : _e[(_f = p.$ref.split("/").pop()) !== null && _f !== void 0 ? _f : ""]; | ||
? (_c = (_b = doc.components) === null || _b === void 0 ? void 0 : _b.headers) === null || _c === void 0 ? void 0 : _c[(_d = p.$ref.split("/").pop()) !== null && _d !== void 0 ? _d : ""] | ||
: (_f = (_e = doc.components) === null || _e === void 0 ? void 0 : _e.parameters) === null || _f === void 0 ? void 0 : _f[(_g = p.$ref.split("/").pop()) !== null && _g !== void 0 ? _g : ""]; | ||
return found !== undefined | ||
? convertParameter(Object.assign(Object.assign({}, found), { in: "header" })) | ||
? convertParameter((_h = doc.components) !== null && _h !== void 0 ? _h : {})(Object.assign(Object.assign({}, found), { in: "header" })) | ||
: undefined; | ||
@@ -74,5 +74,5 @@ }) | ||
}; | ||
const convertParameter = (input) => (Object.assign(Object.assign({}, input), { schema: convertSchema(input.schema) })); | ||
const convertParameter = (components) => (input) => (Object.assign(Object.assign({}, input), { schema: convertSchema(components)(input.schema) })); | ||
const convertRequestBody = (doc) => (input) => { | ||
var _a, _b, _c; | ||
var _a, _b, _c, _d; | ||
if (TypeChecker.isReference(input)) { | ||
@@ -84,6 +84,8 @@ const found = (_b = (_a = doc.components) === null || _a === void 0 ? void 0 : _a.requestBodies) === null || _b === void 0 ? void 0 : _b[(_c = input.$ref.split("/").pop()) !== null && _c !== void 0 ? _c : ""]; | ||
} | ||
return Object.assign(Object.assign({}, input), { content: input.content ? convertContent(input.content) : undefined }); | ||
return Object.assign(Object.assign({}, input), { content: input.content | ||
? convertContent((_d = doc.components) !== null && _d !== void 0 ? _d : {})(input.content) | ||
: undefined }); | ||
}; | ||
const convertResponse = (doc) => (input) => { | ||
var _a, _b, _c; | ||
var _a, _b, _c, _d; | ||
if (TypeChecker.isReference(input)) { | ||
@@ -95,3 +97,5 @@ const found = (_b = (_a = doc.components) === null || _a === void 0 ? void 0 : _a.responses) === null || _b === void 0 ? void 0 : _b[(_c = input.$ref.split("/").pop()) !== null && _c !== void 0 ? _c : ""]; | ||
} | ||
return Object.assign(Object.assign({}, input), { content: input.content ? convertContent(input.content) : undefined, headers: input.headers | ||
return Object.assign(Object.assign({}, input), { content: input.content | ||
? convertContent((_d = doc.components) !== null && _d !== void 0 ? _d : {})(input.content) | ||
: undefined, headers: input.headers | ||
? Object.fromEntries(Object.entries(input.headers) | ||
@@ -102,10 +106,10 @@ .filter(([_, v]) => v !== undefined) | ||
(() => { | ||
var _a, _b, _c; | ||
var _a, _b, _c, _d, _e; | ||
if (TypeChecker.isReference(value) === false) | ||
return convertParameter(Object.assign(Object.assign({}, value), { in: "header" })); | ||
return convertParameter((_a = doc.components) !== null && _a !== void 0 ? _a : {})(Object.assign(Object.assign({}, value), { in: "header" })); | ||
const found = value.$ref.startsWith("#/components/headers/") | ||
? (_b = (_a = doc.components) === null || _a === void 0 ? void 0 : _a.headers) === null || _b === void 0 ? void 0 : _b[(_c = value.$ref.split("/").pop()) !== null && _c !== void 0 ? _c : ""] | ||
? (_c = (_b = doc.components) === null || _b === void 0 ? void 0 : _b.headers) === null || _c === void 0 ? void 0 : _c[(_d = value.$ref.split("/").pop()) !== null && _d !== void 0 ? _d : ""] | ||
: undefined; | ||
return found !== undefined | ||
? convertParameter(Object.assign(Object.assign({}, found), { in: "header" })) | ||
? convertParameter((_e = doc.components) !== null && _e !== void 0 ? _e : {})(Object.assign(Object.assign({}, found), { in: "header" })) | ||
: undefined; | ||
@@ -117,7 +121,9 @@ })(), | ||
}; | ||
const convertContent = (record) => Object.fromEntries(Object.entries(record) | ||
const convertContent = (components) => (record) => Object.fromEntries(Object.entries(record) | ||
.filter(([_, v]) => v !== undefined) | ||
.map(([key, value]) => [ | ||
key, | ||
Object.assign(Object.assign({}, value), { schema: value.schema ? convertSchema(value.schema) : undefined }), | ||
Object.assign(Object.assign({}, value), { schema: value.schema | ||
? convertSchema(components)(value.schema) | ||
: undefined }), | ||
])); | ||
@@ -131,7 +137,7 @@ /* ----------------------------------------------------------- | ||
.filter(([_, v]) => v !== undefined) | ||
.map(([key, value]) => [key, convertSchema(value)])) | ||
.map(([key, value]) => [key, convertSchema(input)(value)])) | ||
: undefined, | ||
securitySchemes: input.securitySchemes, | ||
}); | ||
const convertSchema = (input) => { | ||
const convertSchema = (components) => (input) => { | ||
const union = []; | ||
@@ -187,2 +193,4 @@ const attribute = Object.assign({ title: input.title, description: input.description }, Object.fromEntries(Object.entries(input).filter(([key, value]) => key.startsWith("x-") && value !== undefined))); | ||
schema.anyOf.forEach(visit); | ||
else if (TypeChecker.isAllOf(schema)) | ||
union.push(convertAllOfSchema(components)(schema)); | ||
// ATOMIC TYPE CASE (CONSIDER ENUM VALUES) | ||
@@ -232,6 +240,6 @@ else if (TypeChecker.isBoolean(schema)) | ||
items: undefined, | ||
prefixItems: schema.items.map(convertSchema), | ||
prefixItems: schema.items.map(convertSchema(components)), | ||
additionalItems: typeof schema.additionalItems === "object" && | ||
schema.additionalItems !== null | ||
? convertSchema(schema.additionalItems) | ||
? convertSchema(components)(schema.additionalItems) | ||
: schema.additionalItems, | ||
@@ -242,6 +250,6 @@ })); | ||
items: undefined, | ||
prefixItems: schema.prefixItems.map(convertSchema), | ||
prefixItems: schema.prefixItems.map(convertSchema(components)), | ||
additionalItems: typeof schema.additionalItems === "object" && | ||
schema.additionalItems !== null | ||
? convertSchema(schema.additionalItems) | ||
? convertSchema(components)(schema.additionalItems) | ||
: schema.additionalItems, | ||
@@ -256,3 +264,3 @@ })); | ||
union.push(Object.assign(Object.assign({}, schema), { | ||
items: convertSchema(schema.items), | ||
items: convertSchema(components)(schema.items), | ||
prefixItems: undefined, | ||
@@ -268,3 +276,3 @@ additionalItems: undefined, | ||
.filter(([_, v]) => v !== undefined) | ||
.map(([key, value]) => [key, convertSchema(value)])) | ||
.map(([key, value]) => [key, convertSchema(components)(value)])) | ||
: undefined, | ||
@@ -274,3 +282,3 @@ additionalProperties: schema.additionalProperties | ||
schema.additionalProperties !== null | ||
? convertSchema(schema.additionalProperties) | ||
? convertSchema(components)(schema.additionalProperties) | ||
: schema.additionalProperties | ||
@@ -297,2 +305,31 @@ : undefined, | ||
}; | ||
const convertAllOfSchema = (components) => (input) => { | ||
const objects = input.allOf.map((schema) => retrieveObject(components)(schema)); | ||
if (objects.some((obj) => obj === null)) | ||
return Object.assign({ type: undefined }, { | ||
allOf: undefined, | ||
}); | ||
return Object.assign(Object.assign(Object.assign({}, input), { type: "object", properties: Object.fromEntries(objects | ||
.map((o) => { var _a; return Object.entries((_a = o === null || o === void 0 ? void 0 : o.properties) !== null && _a !== void 0 ? _a : {}); }) | ||
.flat() | ||
.map(([key, value]) => [key, convertSchema(components)(value)])) }), { | ||
allOf: undefined, | ||
}); | ||
}; | ||
const retrieveObject = (components) => (input, visited = new Set()) => { | ||
var _a, _b, _c, _d, _e, _f; | ||
if (TypeChecker.isObject(input)) | ||
return input.properties !== undefined && !input.additionalProperties | ||
? input | ||
: null; | ||
else if (visited.has(input)) | ||
return null; | ||
else | ||
visited.add(input); | ||
if (TypeChecker.isReference(input)) | ||
return retrieveObject(components)((_c = (_a = components.schemas) === null || _a === void 0 ? void 0 : _a[(_b = input.$ref.split("/").pop()) !== null && _b !== void 0 ? _b : ""]) !== null && _c !== void 0 ? _c : {}, visited); | ||
else if (TypeChecker.isRecursiveReference(input)) | ||
return retrieveObject(components)((_f = (_d = components.schemas) === null || _d === void 0 ? void 0 : _d[(_e = input.$recursiveRef.split("/").pop()) !== null && _e !== void 0 ? _e : ""]) !== null && _f !== void 0 ? _f : {}, visited); | ||
return null; | ||
}; | ||
let TypeChecker; | ||
@@ -310,4 +347,5 @@ (function (TypeChecker) { | ||
undefined; | ||
TypeChecker.isAllOf = (schema) => schema.allOf !== undefined; | ||
TypeChecker.isAnyOf = (schema) => schema.anyOf !== undefined; | ||
TypeChecker.isOneOf = (schema) => schema.oneOf !== undefined; | ||
TypeChecker.isAnyOf = (schema) => schema.anyOf !== undefined; | ||
TypeChecker.isNullOnly = (schema) => schema.type === "null"; | ||
@@ -314,0 +352,0 @@ TypeChecker.isMixed = (schema) => Array.isArray(schema.type); |
@@ -6,3 +6,3 @@ import { OpenApi } from "../OpenApi"; | ||
const convertComponents: (input: OpenApiV3.IComponents) => OpenApi.IComponents; | ||
const convertSchema: (input: OpenApiV3.IJsonSchema) => OpenApi.IJsonSchema; | ||
const convertSchema: (components: OpenApiV3.IComponents) => (input: OpenApiV3.IJsonSchema) => OpenApi.IJsonSchema; | ||
namespace TypeChecker { | ||
@@ -16,6 +16,7 @@ const isBoolean: (schema: OpenApiV3.IJsonSchema) => schema is OpenApiV3.IJsonSchema.IBoolean; | ||
const isReference: (schema: OpenApiV3.IJsonSchema) => schema is OpenApiV3.IJsonSchema.IReference<string>; | ||
const isAllOf: (schema: OpenApiV3.IJsonSchema) => schema is OpenApiV3.IJsonSchema.IAllOf; | ||
const isAnyOf: (schema: OpenApiV3.IJsonSchema) => schema is OpenApiV3.IJsonSchema.IAnyOf; | ||
const isOneOf: (schema: OpenApiV3.IJsonSchema) => schema is OpenApiV3.IJsonSchema.IOneOf; | ||
const isAnyOf: (schema: OpenApiV3.IJsonSchema) => schema is OpenApiV3.IJsonSchema.IAnyOf; | ||
const isNullOnly: (schema: OpenApiV3.IJsonSchema) => schema is OpenApiV3.IJsonSchema.INullOnly; | ||
} | ||
} |
@@ -39,10 +39,10 @@ "use strict"; | ||
.map((p) => { | ||
var _a, _b, _c, _d, _e, _f; | ||
var _a, _b, _c, _d, _e, _f, _g, _h; | ||
if (!TypeChecker.isReference(p)) | ||
return convertParameter(p); | ||
return convertParameter((_a = doc.components) !== null && _a !== void 0 ? _a : {})(p); | ||
const found = p.$ref.startsWith("#/components/headers/") | ||
? (_b = (_a = doc.components) === null || _a === void 0 ? void 0 : _a.headers) === null || _b === void 0 ? void 0 : _b[(_c = p.$ref.split("/").pop()) !== null && _c !== void 0 ? _c : ""] | ||
: (_e = (_d = doc.components) === null || _d === void 0 ? void 0 : _d.parameters) === null || _e === void 0 ? void 0 : _e[(_f = p.$ref.split("/").pop()) !== null && _f !== void 0 ? _f : ""]; | ||
? (_c = (_b = doc.components) === null || _b === void 0 ? void 0 : _b.headers) === null || _c === void 0 ? void 0 : _c[(_d = p.$ref.split("/").pop()) !== null && _d !== void 0 ? _d : ""] | ||
: (_f = (_e = doc.components) === null || _e === void 0 ? void 0 : _e.parameters) === null || _f === void 0 ? void 0 : _f[(_g = p.$ref.split("/").pop()) !== null && _g !== void 0 ? _g : ""]; | ||
return found !== undefined | ||
? convertParameter(Object.assign(Object.assign({}, found), { in: "header" })) | ||
? convertParameter((_h = doc.components) !== null && _h !== void 0 ? _h : {})(Object.assign(Object.assign({}, found), { in: "header" })) | ||
: undefined; | ||
@@ -60,5 +60,5 @@ }) | ||
}; | ||
const convertParameter = (input) => (Object.assign(Object.assign({}, input), { schema: OpenApiV3Converter.convertSchema(input.schema) })); | ||
const convertParameter = (components) => (input) => (Object.assign(Object.assign({}, input), { schema: OpenApiV3Converter.convertSchema(components)(input.schema) })); | ||
const convertRequestBody = (doc) => (input) => { | ||
var _a, _b, _c; | ||
var _a, _b, _c, _d; | ||
if (TypeChecker.isReference(input)) { | ||
@@ -70,6 +70,8 @@ const found = (_b = (_a = doc.components) === null || _a === void 0 ? void 0 : _a.requestBodies) === null || _b === void 0 ? void 0 : _b[(_c = input.$ref.split("/").pop()) !== null && _c !== void 0 ? _c : ""]; | ||
} | ||
return Object.assign(Object.assign({}, input), { content: input.content ? convertContent(input.content) : undefined }); | ||
return Object.assign(Object.assign({}, input), { content: input.content | ||
? convertContent((_d = doc.components) !== null && _d !== void 0 ? _d : {})(input.content) | ||
: undefined }); | ||
}; | ||
const convertResponse = (doc) => (input) => { | ||
var _a, _b, _c; | ||
var _a, _b, _c, _d; | ||
if (TypeChecker.isReference(input)) { | ||
@@ -81,3 +83,5 @@ const found = (_b = (_a = doc.components) === null || _a === void 0 ? void 0 : _a.responses) === null || _b === void 0 ? void 0 : _b[(_c = input.$ref.split("/").pop()) !== null && _c !== void 0 ? _c : ""]; | ||
} | ||
return Object.assign(Object.assign({}, input), { content: input.content ? convertContent(input.content) : undefined, headers: input.headers | ||
return Object.assign(Object.assign({}, input), { content: input.content | ||
? convertContent((_d = doc.components) !== null && _d !== void 0 ? _d : {})(input.content) | ||
: undefined, headers: input.headers | ||
? Object.fromEntries(Object.entries(input.headers) | ||
@@ -88,10 +92,10 @@ .filter(([_, v]) => v !== undefined) | ||
(() => { | ||
var _a, _b, _c; | ||
var _a, _b, _c, _d, _e; | ||
if (TypeChecker.isReference(value) === false) | ||
return convertParameter(Object.assign(Object.assign({}, value), { in: "header" })); | ||
return convertParameter((_a = doc.components) !== null && _a !== void 0 ? _a : {})(Object.assign(Object.assign({}, value), { in: "header" })); | ||
const found = value.$ref.startsWith("#/components/headers/") | ||
? (_b = (_a = doc.components) === null || _a === void 0 ? void 0 : _a.headers) === null || _b === void 0 ? void 0 : _b[(_c = value.$ref.split("/").pop()) !== null && _c !== void 0 ? _c : ""] | ||
? (_c = (_b = doc.components) === null || _b === void 0 ? void 0 : _b.headers) === null || _c === void 0 ? void 0 : _c[(_d = value.$ref.split("/").pop()) !== null && _d !== void 0 ? _d : ""] | ||
: undefined; | ||
return found !== undefined | ||
? convertParameter(Object.assign(Object.assign({}, found), { in: "header" })) | ||
? convertParameter((_e = doc.components) !== null && _e !== void 0 ? _e : {})(Object.assign(Object.assign({}, found), { in: "header" })) | ||
: undefined; | ||
@@ -103,7 +107,9 @@ })(), | ||
}; | ||
const convertContent = (record) => Object.fromEntries(Object.entries(record) | ||
const convertContent = (components) => (record) => Object.fromEntries(Object.entries(record) | ||
.filter(([_, v]) => v !== undefined) | ||
.map(([key, value]) => [ | ||
key, | ||
Object.assign(Object.assign({}, value), { schema: value.schema ? OpenApiV3Converter.convertSchema(value.schema) : undefined }), | ||
Object.assign(Object.assign({}, value), { schema: value.schema | ||
? OpenApiV3Converter.convertSchema(components)(value.schema) | ||
: undefined }), | ||
])); | ||
@@ -117,7 +123,7 @@ /* ----------------------------------------------------------- | ||
.filter(([_, v]) => v !== undefined) | ||
.map(([key, value]) => [key, OpenApiV3Converter.convertSchema(value)])) | ||
.map(([key, value]) => [key, OpenApiV3Converter.convertSchema(input)(value)])) | ||
: undefined, | ||
securitySchemes: input.securitySchemes, | ||
}); | ||
OpenApiV3Converter.convertSchema = (input) => { | ||
OpenApiV3Converter.convertSchema = (components) => (input) => { | ||
const nullable = { value: false }; | ||
@@ -129,3 +135,4 @@ const union = []; | ||
// NULLABLE PROPERTY | ||
if (schema.nullable === true) | ||
if (schema.nullable === | ||
true) | ||
nullable.value || (nullable.value = true); | ||
@@ -137,2 +144,4 @@ // UNION TYPE CASE | ||
schema.oneOf.forEach(visit); | ||
else if (TypeChecker.isAllOf(schema)) | ||
union.push(convertAllOfSchema(components)(schema)); | ||
// ATOMIC TYPE CASE (CONSIDER ENUM VALUES) | ||
@@ -149,3 +158,3 @@ else if (TypeChecker.isBoolean(schema) || | ||
else if (TypeChecker.isArray(schema)) | ||
union.push(Object.assign(Object.assign({}, schema), { items: OpenApiV3Converter.convertSchema(schema.items) })); | ||
union.push(Object.assign(Object.assign({}, schema), { items: OpenApiV3Converter.convertSchema(components)(schema.items) })); | ||
else if (TypeChecker.isObject(schema)) | ||
@@ -156,3 +165,6 @@ union.push(Object.assign(Object.assign({}, schema), { | ||
.filter(([_, v]) => v !== undefined) | ||
.map(([key, value]) => [key, OpenApiV3Converter.convertSchema(value)])) | ||
.map(([key, value]) => [ | ||
key, | ||
OpenApiV3Converter.convertSchema(components)(value), | ||
])) | ||
: undefined, | ||
@@ -162,3 +174,3 @@ additionalProperties: schema.additionalProperties | ||
schema.additionalProperties !== null | ||
? OpenApiV3Converter.convertSchema(schema.additionalProperties) | ||
? OpenApiV3Converter.convertSchema(components)(schema.additionalProperties) | ||
: schema.additionalProperties | ||
@@ -181,2 +193,29 @@ : undefined, | ||
}; | ||
const convertAllOfSchema = (components) => (input) => { | ||
const objects = input.allOf.map((schema) => retrieveObject(components)(schema)); | ||
if (objects.some((obj) => obj === null)) | ||
return Object.assign({ type: undefined }, { | ||
allOf: undefined, | ||
}); | ||
return Object.assign(Object.assign(Object.assign({}, input), { type: "object", properties: Object.fromEntries(objects | ||
.map((o) => { var _a; return Object.entries((_a = o === null || o === void 0 ? void 0 : o.properties) !== null && _a !== void 0 ? _a : {}); }) | ||
.flat() | ||
.map(([key, value]) => [key, OpenApiV3Converter.convertSchema(components)(value)])) }), { | ||
allOf: undefined, | ||
}); | ||
}; | ||
const retrieveObject = (components) => (input, visited = new Set()) => { | ||
var _a, _b, _c; | ||
if (TypeChecker.isObject(input)) | ||
return input.properties !== undefined && !input.additionalProperties | ||
? input | ||
: null; | ||
else if (visited.has(input)) | ||
return null; | ||
else | ||
visited.add(input); | ||
if (TypeChecker.isReference(input)) | ||
return retrieveObject(components)((_c = (_a = components.schemas) === null || _a === void 0 ? void 0 : _a[(_b = input.$ref.split("/").pop()) !== null && _b !== void 0 ? _b : ""]) !== null && _c !== void 0 ? _c : {}, visited); | ||
return null; | ||
}; | ||
let TypeChecker; | ||
@@ -191,6 +230,7 @@ (function (TypeChecker) { | ||
TypeChecker.isReference = (schema) => schema.$ref !== undefined; | ||
TypeChecker.isAllOf = (schema) => schema.allOf !== undefined; | ||
TypeChecker.isAnyOf = (schema) => schema.anyOf !== undefined; | ||
TypeChecker.isOneOf = (schema) => schema.oneOf !== undefined; | ||
TypeChecker.isAnyOf = (schema) => schema.anyOf !== undefined; | ||
TypeChecker.isNullOnly = (schema) => schema.type === "null"; | ||
})(TypeChecker = OpenApiV3Converter.TypeChecker || (OpenApiV3Converter.TypeChecker = {})); | ||
})(OpenApiV3Converter || (exports.OpenApiV3Converter = OpenApiV3Converter = {})); |
@@ -83,3 +83,3 @@ /** | ||
} | ||
type IJsonSchema = IJsonSchema.IBoolean | IJsonSchema.IInteger | IJsonSchema.INumber | IJsonSchema.IString | IJsonSchema.IArray | IJsonSchema.IObject | IJsonSchema.IReference | IJsonSchema.IUnknown | IJsonSchema.INullOnly | IJsonSchema.IAllOf | IJsonSchema.IAnyOf | IJsonSchema.IOneOf; | ||
type IJsonSchema = IJsonSchema.IBoolean | IJsonSchema.IInteger | IJsonSchema.INumber | IJsonSchema.IString | IJsonSchema.IArray | IJsonSchema.IObject | IJsonSchema.IReference | IJsonSchema.IUnknown | IJsonSchema.INullOnly | IJsonSchema.IAnyOf | IJsonSchema.IOneOf; | ||
namespace IJsonSchema { | ||
@@ -86,0 +86,0 @@ interface IBoolean extends __ISignificant<"boolean"> { |
{ | ||
"name": "@samchon/openapi", | ||
"version": "0.1.18", | ||
"version": "0.1.19", | ||
"description": "OpenAPI definitions and converters for 'typia' and 'nestia'.", | ||
@@ -38,3 +38,3 @@ "main": "./lib/index.js", | ||
"typescript-transform-paths": "^3.4.7", | ||
"typia": "^5.5.10" | ||
"typia": "^6.0.3" | ||
}, | ||
@@ -41,0 +41,0 @@ "files": [ |
@@ -51,2 +51,3 @@ import { OpenApi } from "../OpenApi"; | ||
}; | ||
const convertPathItem = | ||
@@ -81,2 +82,3 @@ (doc: OpenApiV3_1.IDocument) => | ||
}); | ||
const convertOperation = | ||
@@ -91,3 +93,4 @@ (doc: OpenApiV3_1.IDocument) => | ||
.map((p) => { | ||
if (!TypeChecker.isReference(p)) return convertParameter(p); | ||
if (!TypeChecker.isReference(p)) | ||
return convertParameter(doc.components ?? {})(p); | ||
const found: | ||
@@ -99,3 +102,3 @@ | Omit<OpenApiV3_1.IOperation.IParameter, "in"> | ||
return found !== undefined | ||
? convertParameter({ | ||
? convertParameter(doc.components ?? {})({ | ||
...found, | ||
@@ -122,8 +125,11 @@ in: "header", | ||
}); | ||
const convertParameter = ( | ||
input: OpenApiV3_1.IOperation.IParameter, | ||
): OpenApi.IOperation.IParameter => ({ | ||
...input, | ||
schema: convertSchema(input.schema), | ||
}); | ||
const convertParameter = | ||
(components: OpenApiV3_1.IComponents) => | ||
( | ||
input: OpenApiV3_1.IOperation.IParameter, | ||
): OpenApi.IOperation.IParameter => ({ | ||
...input, | ||
schema: convertSchema(components)(input.schema), | ||
}); | ||
const convertRequestBody = | ||
@@ -144,5 +150,8 @@ (doc: OpenApiV3_1.IDocument) => | ||
...input, | ||
content: input.content ? convertContent(input.content) : undefined, | ||
content: input.content | ||
? convertContent(doc.components ?? {})(input.content) | ||
: undefined, | ||
}; | ||
}; | ||
const convertResponse = | ||
@@ -163,3 +172,5 @@ (doc: OpenApiV3_1.IDocument) => | ||
...input, | ||
content: input.content ? convertContent(input.content) : undefined, | ||
content: input.content | ||
? convertContent(doc.components ?? {})(input.content) | ||
: undefined, | ||
headers: input.headers | ||
@@ -175,3 +186,3 @@ ? Object.fromEntries( | ||
if (TypeChecker.isReference(value) === false) | ||
return convertParameter({ | ||
return convertParameter(doc.components ?? {})({ | ||
...value, | ||
@@ -190,3 +201,6 @@ in: "header", | ||
return found !== undefined | ||
? convertParameter({ ...found, in: "header" }) | ||
? convertParameter(doc.components ?? {})({ | ||
...found, | ||
in: "header", | ||
}) | ||
: undefined!; | ||
@@ -201,20 +215,25 @@ })(), | ||
}; | ||
const convertContent = ( | ||
record: Record<string, OpenApiV3_1.IOperation.IMediaType>, | ||
): Record<string, OpenApi.IOperation.IMediaType> => | ||
Object.fromEntries( | ||
Object.entries(record) | ||
.filter(([_, v]) => v !== undefined) | ||
.map( | ||
([key, value]) => | ||
[ | ||
key, | ||
{ | ||
...value, | ||
schema: value.schema ? convertSchema(value.schema) : undefined, | ||
}, | ||
] as const, | ||
), | ||
); | ||
const convertContent = | ||
(components: OpenApiV3_1.IComponents) => | ||
( | ||
record: Record<string, OpenApiV3_1.IOperation.IMediaType>, | ||
): Record<string, OpenApi.IOperation.IMediaType> => | ||
Object.fromEntries( | ||
Object.entries(record) | ||
.filter(([_, v]) => v !== undefined) | ||
.map( | ||
([key, value]) => | ||
[ | ||
key, | ||
{ | ||
...value, | ||
schema: value.schema | ||
? convertSchema(components)(value.schema) | ||
: undefined, | ||
}, | ||
] as const, | ||
), | ||
); | ||
/* ----------------------------------------------------------- | ||
@@ -230,3 +249,3 @@ DEFINITIONS | ||
.filter(([_, v]) => v !== undefined) | ||
.map(([key, value]) => [key, convertSchema(value)] as const), | ||
.map(([key, value]) => [key, convertSchema(input)(value)] as const), | ||
) | ||
@@ -236,254 +255,315 @@ : undefined, | ||
}); | ||
const convertSchema = ( | ||
input: OpenApiV3_1.IJsonSchema, | ||
): OpenApi.IJsonSchema => { | ||
const union: OpenApi.IJsonSchema[] = []; | ||
const attribute: OpenApi.IJsonSchema.__IAttribute = { | ||
title: input.title, | ||
description: input.description, | ||
...Object.fromEntries( | ||
Object.entries(input).filter( | ||
([key, value]) => key.startsWith("x-") && value !== undefined, | ||
const convertSchema = | ||
(components: OpenApiV3_1.IComponents) => | ||
(input: OpenApiV3_1.IJsonSchema): OpenApi.IJsonSchema => { | ||
const union: OpenApi.IJsonSchema[] = []; | ||
const attribute: OpenApi.IJsonSchema.__IAttribute = { | ||
title: input.title, | ||
description: input.description, | ||
...Object.fromEntries( | ||
Object.entries(input).filter( | ||
([key, value]) => key.startsWith("x-") && value !== undefined, | ||
), | ||
), | ||
), | ||
}; | ||
const nullable: { value: boolean } = { value: false }; | ||
}; | ||
const nullable: { value: boolean } = { value: false }; | ||
const visit = (schema: OpenApiV3_1.IJsonSchema): void => { | ||
// NULLABLE PROPERTY | ||
if ( | ||
(schema as OpenApiV3_1.IJsonSchema.__ISignificant<any>).nullable === | ||
true | ||
) | ||
nullable.value ||= true; | ||
// MIXED TYPE CASE | ||
if (TypeChecker.isMixed(schema)) { | ||
if (schema.const !== undefined) | ||
visit({ | ||
...schema, | ||
...{ | ||
type: undefined, | ||
oneOf: undefined, | ||
allOf: undefined, | ||
}, | ||
}); | ||
if (schema.oneOf !== undefined) | ||
visit({ | ||
...schema, | ||
...{ | ||
type: undefined, | ||
const: undefined, | ||
allOf: undefined, | ||
}, | ||
}); | ||
if (schema.anyOf !== undefined) | ||
visit({ | ||
...schema, | ||
...{ | ||
type: undefined, | ||
const: undefined, | ||
oneOf: undefined, | ||
}, | ||
}); | ||
for (const type of schema.type) | ||
if (type === "boolean" || type === "number" || type === "string") | ||
const visit = (schema: OpenApiV3_1.IJsonSchema): void => { | ||
// NULLABLE PROPERTY | ||
if ( | ||
(schema as OpenApiV3_1.IJsonSchema.__ISignificant<any>).nullable === | ||
true | ||
) | ||
nullable.value ||= true; | ||
// MIXED TYPE CASE | ||
if (TypeChecker.isMixed(schema)) { | ||
if (schema.const !== undefined) | ||
visit({ | ||
...schema, | ||
...{ | ||
enum: schema.enum?.length | ||
? schema.enum.filter((x) => typeof x === type) | ||
: undefined, | ||
type: undefined, | ||
oneOf: undefined, | ||
allOf: undefined, | ||
}, | ||
type: type as any, | ||
}); | ||
else if (type === "integer") | ||
if (schema.oneOf !== undefined) | ||
visit({ | ||
...schema, | ||
...{ | ||
enum: schema.enum?.length | ||
? schema.enum.filter((x) => Number.isInteger(x)) | ||
: undefined, | ||
type: undefined, | ||
const: undefined, | ||
allOf: undefined, | ||
}, | ||
type: type as any, | ||
}); | ||
else visit({ ...schema, type: type as any }); | ||
} | ||
// UNION TYPE CASE | ||
else if (TypeChecker.isOneOf(schema)) schema.oneOf.forEach(visit); | ||
else if (TypeChecker.isAnyOf(schema)) schema.anyOf.forEach(visit); | ||
// ATOMIC TYPE CASE (CONSIDER ENUM VALUES) | ||
else if (TypeChecker.isBoolean(schema)) | ||
if (schema.enum?.length) | ||
for (const value of schema.enum) | ||
if (schema.anyOf !== undefined) | ||
visit({ | ||
...schema, | ||
...{ | ||
type: undefined, | ||
const: undefined, | ||
oneOf: undefined, | ||
}, | ||
}); | ||
for (const type of schema.type) | ||
if (type === "boolean" || type === "number" || type === "string") | ||
visit({ | ||
...schema, | ||
...{ | ||
enum: schema.enum?.length | ||
? schema.enum.filter((x) => typeof x === type) | ||
: undefined, | ||
}, | ||
type: type as any, | ||
}); | ||
else if (type === "integer") | ||
visit({ | ||
...schema, | ||
...{ | ||
enum: schema.enum?.length | ||
? schema.enum.filter((x) => Number.isInteger(x)) | ||
: undefined, | ||
}, | ||
type: type as any, | ||
}); | ||
else visit({ ...schema, type: type as any }); | ||
} | ||
// UNION TYPE CASE | ||
else if (TypeChecker.isOneOf(schema)) schema.oneOf.forEach(visit); | ||
else if (TypeChecker.isAnyOf(schema)) schema.anyOf.forEach(visit); | ||
else if (TypeChecker.isAllOf(schema)) | ||
union.push(convertAllOfSchema(components)(schema)); | ||
// ATOMIC TYPE CASE (CONSIDER ENUM VALUES) | ||
else if (TypeChecker.isBoolean(schema)) | ||
if (schema.enum?.length) | ||
for (const value of schema.enum) | ||
union.push({ | ||
const: value, | ||
...({ | ||
...schema, | ||
type: undefined as any, | ||
enum: undefined, | ||
default: undefined, | ||
} satisfies OpenApiV3_1.IJsonSchema.IBoolean as any), | ||
} satisfies OpenApi.IJsonSchema.IConstant); | ||
else | ||
union.push({ | ||
const: value, | ||
...({ | ||
...schema, | ||
type: undefined as any, | ||
...schema, | ||
...{ | ||
enum: undefined, | ||
default: undefined, | ||
} satisfies OpenApiV3_1.IJsonSchema.IBoolean as any), | ||
} satisfies OpenApi.IJsonSchema.IConstant); | ||
else | ||
union.push({ | ||
...schema, | ||
...{ | ||
enum: undefined, | ||
}, | ||
}); | ||
else if (TypeChecker.isInteger(schema) || TypeChecker.isNumber(schema)) | ||
if (schema.enum?.length) | ||
for (const value of schema.enum) | ||
}, | ||
}); | ||
else if (TypeChecker.isInteger(schema) || TypeChecker.isNumber(schema)) | ||
if (schema.enum?.length) | ||
for (const value of schema.enum) | ||
union.push({ | ||
const: value, | ||
...({ | ||
...schema, | ||
type: undefined as any, | ||
enum: undefined, | ||
default: undefined, | ||
minimum: undefined, | ||
maximum: undefined, | ||
exclusiveMinimum: undefined, | ||
exclusiveMaximum: undefined, | ||
multipleOf: undefined, | ||
} satisfies OpenApiV3_1.IJsonSchema.IInteger as any), | ||
} satisfies OpenApi.IJsonSchema.IConstant); | ||
else | ||
union.push({ | ||
const: value, | ||
...({ | ||
...schema, | ||
type: undefined as any, | ||
...schema, | ||
...{ | ||
enum: undefined, | ||
default: undefined, | ||
minimum: undefined, | ||
maximum: undefined, | ||
exclusiveMinimum: undefined, | ||
exclusiveMaximum: undefined, | ||
multipleOf: undefined, | ||
} satisfies OpenApiV3_1.IJsonSchema.IInteger as any), | ||
} satisfies OpenApi.IJsonSchema.IConstant); | ||
else | ||
union.push({ | ||
...schema, | ||
...{ | ||
enum: undefined, | ||
}, | ||
...(typeof schema.exclusiveMinimum === "number" | ||
? { | ||
minimum: schema.exclusiveMinimum, | ||
exclusiveMinimum: true, | ||
} | ||
: { | ||
exclusiveMinimum: schema.exclusiveMinimum, | ||
}), | ||
...(typeof schema.exclusiveMaximum === "number" | ||
? { | ||
maximum: schema.exclusiveMaximum, | ||
exclusiveMaximum: true, | ||
} | ||
: { | ||
exclusiveMaximum: schema.exclusiveMaximum, | ||
}), | ||
}); | ||
else if (TypeChecker.isString(schema)) | ||
if (schema.enum?.length) | ||
for (const value of schema.enum) | ||
}, | ||
...(typeof schema.exclusiveMinimum === "number" | ||
? { | ||
minimum: schema.exclusiveMinimum, | ||
exclusiveMinimum: true, | ||
} | ||
: { | ||
exclusiveMinimum: schema.exclusiveMinimum, | ||
}), | ||
...(typeof schema.exclusiveMaximum === "number" | ||
? { | ||
maximum: schema.exclusiveMaximum, | ||
exclusiveMaximum: true, | ||
} | ||
: { | ||
exclusiveMaximum: schema.exclusiveMaximum, | ||
}), | ||
}); | ||
else if (TypeChecker.isString(schema)) | ||
if (schema.enum?.length) | ||
for (const value of schema.enum) | ||
union.push({ | ||
const: value, | ||
...({ | ||
...schema, | ||
type: undefined as any, | ||
enum: undefined, | ||
default: undefined, | ||
} satisfies OpenApiV3_1.IJsonSchema.IString as any), | ||
} satisfies OpenApi.IJsonSchema.IConstant); | ||
else | ||
union.push({ | ||
const: value, | ||
...({ | ||
...schema, | ||
type: undefined as any, | ||
...schema, | ||
...{ | ||
enum: undefined, | ||
default: undefined, | ||
} satisfies OpenApiV3_1.IJsonSchema.IString as any), | ||
} satisfies OpenApi.IJsonSchema.IConstant); | ||
else | ||
}, | ||
}); | ||
// ARRAY TYPE CASE (CONSIDER TUPLE) | ||
else if (TypeChecker.isArray(schema)) { | ||
if (Array.isArray(schema.items)) | ||
union.push({ | ||
...schema, | ||
...{ | ||
items: undefined!, | ||
prefixItems: schema.items.map(convertSchema(components)), | ||
additionalItems: | ||
typeof schema.additionalItems === "object" && | ||
schema.additionalItems !== null | ||
? convertSchema(components)(schema.additionalItems) | ||
: schema.additionalItems, | ||
}, | ||
} satisfies OpenApi.IJsonSchema.ITuple); | ||
else if (Array.isArray(schema.prefixItems)) | ||
union.push({ | ||
...schema, | ||
...{ | ||
items: undefined!, | ||
prefixItems: schema.prefixItems.map(convertSchema(components)), | ||
additionalItems: | ||
typeof schema.additionalItems === "object" && | ||
schema.additionalItems !== null | ||
? convertSchema(components)(schema.additionalItems) | ||
: schema.additionalItems, | ||
}, | ||
}); | ||
else if (schema.items === undefined) | ||
union.push({ | ||
...schema, | ||
...{ | ||
items: undefined!, | ||
prefixItems: [], | ||
}, | ||
}); | ||
else | ||
union.push({ | ||
...schema, | ||
...{ | ||
items: convertSchema(components)(schema.items), | ||
prefixItems: undefined, | ||
additionalItems: undefined, | ||
}, | ||
}); | ||
} | ||
// OBJECT TYPE CASE | ||
else if (TypeChecker.isObject(schema)) | ||
union.push({ | ||
...schema, | ||
...{ | ||
enum: undefined, | ||
properties: schema.properties | ||
? Object.fromEntries( | ||
Object.entries(schema.properties) | ||
.filter(([_, v]) => v !== undefined) | ||
.map( | ||
([key, value]) => | ||
[key, convertSchema(components)(value)] as const, | ||
), | ||
) | ||
: undefined, | ||
additionalProperties: schema.additionalProperties | ||
? typeof schema.additionalProperties === "object" && | ||
schema.additionalProperties !== null | ||
? convertSchema(components)(schema.additionalProperties) | ||
: schema.additionalProperties | ||
: undefined, | ||
}, | ||
}); | ||
// ARRAY TYPE CASE (CONSIDER TUPLE) | ||
else if (TypeChecker.isArray(schema)) { | ||
if (Array.isArray(schema.items)) | ||
else if (TypeChecker.isRecursiveReference(schema)) | ||
union.push({ | ||
...schema, | ||
...{ | ||
items: undefined!, | ||
prefixItems: schema.items.map(convertSchema), | ||
additionalItems: | ||
typeof schema.additionalItems === "object" && | ||
schema.additionalItems !== null | ||
? convertSchema(schema.additionalItems) | ||
: schema.additionalItems, | ||
$ref: schema.$recursiveRef, | ||
$recursiveRef: undefined, | ||
}, | ||
} satisfies OpenApi.IJsonSchema.ITuple); | ||
else if (Array.isArray(schema.prefixItems)) | ||
union.push({ | ||
...schema, | ||
...{ | ||
items: undefined!, | ||
prefixItems: schema.prefixItems.map(convertSchema), | ||
additionalItems: | ||
typeof schema.additionalItems === "object" && | ||
schema.additionalItems !== null | ||
? convertSchema(schema.additionalItems) | ||
: schema.additionalItems, | ||
}, | ||
}); | ||
else if (schema.items === undefined) | ||
union.push({ | ||
...schema, | ||
...{ | ||
items: undefined!, | ||
prefixItems: [], | ||
}, | ||
}); | ||
else | ||
union.push({ | ||
...schema, | ||
...{ | ||
items: convertSchema(schema.items), | ||
prefixItems: undefined, | ||
additionalItems: undefined, | ||
}, | ||
}); | ||
} | ||
// OBJECT TYPE CASE | ||
else if (TypeChecker.isObject(schema)) | ||
union.push({ | ||
...schema, | ||
// THE OTHERS | ||
else union.push(schema); | ||
}; | ||
visit(input); | ||
if ( | ||
nullable.value === true && | ||
!union.some((e) => (e as OpenApi.IJsonSchema.INull).type === "null") | ||
) | ||
union.push({ type: "null" }); | ||
return { | ||
...(union.length === 0 | ||
? { type: undefined } | ||
: union.length === 1 | ||
? { ...union[0] } | ||
: { oneOf: union.map((u) => ({ ...u, nullable: undefined })) }), | ||
...attribute, | ||
...{ nullable: undefined }, | ||
}; | ||
}; | ||
const convertAllOfSchema = | ||
(components: OpenApiV3_1.IComponents) => | ||
(input: OpenApiV3_1.IJsonSchema.IAllOf): OpenApi.IJsonSchema => { | ||
const objects: Array<OpenApiV3_1.IJsonSchema.IObject | null> = | ||
input.allOf.map((schema) => retrieveObject(components)(schema)); | ||
if (objects.some((obj) => obj === null)) | ||
return { | ||
type: undefined, | ||
...{ | ||
properties: schema.properties | ||
? Object.fromEntries( | ||
Object.entries(schema.properties) | ||
.filter(([_, v]) => v !== undefined) | ||
.map( | ||
([key, value]) => [key, convertSchema(value)] as const, | ||
), | ||
) | ||
: undefined, | ||
additionalProperties: schema.additionalProperties | ||
? typeof schema.additionalProperties === "object" && | ||
schema.additionalProperties !== null | ||
? convertSchema(schema.additionalProperties) | ||
: schema.additionalProperties | ||
: undefined, | ||
allOf: undefined, | ||
}, | ||
}); | ||
else if (TypeChecker.isRecursiveReference(schema)) | ||
union.push({ | ||
...schema, | ||
...{ | ||
$ref: schema.$recursiveRef, | ||
$recursiveRef: undefined, | ||
}, | ||
}); | ||
// THE OTHERS | ||
else union.push(schema); | ||
}; | ||
return { | ||
...input, | ||
type: "object", | ||
properties: Object.fromEntries( | ||
objects | ||
.map((o) => Object.entries(o?.properties ?? {})) | ||
.flat() | ||
.map( | ||
([key, value]) => | ||
[key, convertSchema(components)(value)] as const, | ||
), | ||
), | ||
...{ | ||
allOf: undefined, | ||
}, | ||
}; | ||
}; | ||
visit(input); | ||
if ( | ||
nullable.value === true && | ||
!union.some((e) => (e as OpenApi.IJsonSchema.INull).type === "null") | ||
) | ||
union.push({ type: "null" }); | ||
return { | ||
...(union.length === 0 | ||
? { type: undefined } | ||
: union.length === 1 | ||
? { ...union[0] } | ||
: { oneOf: union.map((u) => ({ ...u, nullable: undefined })) }), | ||
...attribute, | ||
...{ nullable: undefined }, | ||
const retrieveObject = | ||
(components: OpenApiV3_1.IComponents) => | ||
( | ||
input: OpenApiV3_1.IJsonSchema, | ||
visited: Set<OpenApiV3_1.IJsonSchema> = new Set(), | ||
): OpenApiV3_1.IJsonSchema.IObject | null => { | ||
if (TypeChecker.isObject(input)) | ||
return input.properties !== undefined && !input.additionalProperties | ||
? input | ||
: null; | ||
else if (visited.has(input)) return null; | ||
else visited.add(input); | ||
if (TypeChecker.isReference(input)) | ||
return retrieveObject(components)( | ||
components.schemas?.[input.$ref.split("/").pop() ?? ""] ?? {}, | ||
visited, | ||
); | ||
else if (TypeChecker.isRecursiveReference(input)) | ||
return retrieveObject(components)( | ||
components.schemas?.[input.$recursiveRef.split("/").pop() ?? ""] ?? | ||
{}, | ||
visited, | ||
); | ||
return null; | ||
}; | ||
}; | ||
@@ -528,6 +608,6 @@ namespace TypeChecker { | ||
undefined; | ||
export const isOneOf = ( | ||
export const isAllOf = ( | ||
schema: OpenApiV3_1.IJsonSchema, | ||
): schema is OpenApiV3_1.IJsonSchema.IOneOf => | ||
(schema as OpenApiV3_1.IJsonSchema.IOneOf).oneOf !== undefined; | ||
): schema is OpenApiV3_1.IJsonSchema.IAllOf => | ||
(schema as OpenApiV3_1.IJsonSchema.IAllOf).allOf !== undefined; | ||
export const isAnyOf = ( | ||
@@ -537,2 +617,6 @@ schema: OpenApiV3_1.IJsonSchema, | ||
(schema as OpenApiV3_1.IJsonSchema.IAnyOf).anyOf !== undefined; | ||
export const isOneOf = ( | ||
schema: OpenApiV3_1.IJsonSchema, | ||
): schema is OpenApiV3_1.IJsonSchema.IOneOf => | ||
(schema as OpenApiV3_1.IJsonSchema.IOneOf).oneOf !== undefined; | ||
export const isNullOnly = ( | ||
@@ -539,0 +623,0 @@ schema: OpenApiV3_1.IJsonSchema, |
@@ -53,2 +53,3 @@ import { OpenApi } from "../OpenApi"; | ||
}); | ||
const convertOperation = | ||
@@ -63,3 +64,4 @@ (doc: OpenApiV3.IDocument) => | ||
.map((p) => { | ||
if (!TypeChecker.isReference(p)) return convertParameter(p); | ||
if (!TypeChecker.isReference(p)) | ||
return convertParameter(doc.components ?? {})(p); | ||
const found: | ||
@@ -71,3 +73,3 @@ | Omit<OpenApiV3.IOperation.IParameter, "in"> | ||
return found !== undefined | ||
? convertParameter({ | ||
? convertParameter(doc.components ?? {})({ | ||
...found, | ||
@@ -94,8 +96,11 @@ in: "header", | ||
}); | ||
const convertParameter = ( | ||
input: OpenApiV3.IOperation.IParameter, | ||
): OpenApi.IOperation.IParameter => ({ | ||
...input, | ||
schema: convertSchema(input.schema), | ||
}); | ||
const convertParameter = | ||
(components: OpenApiV3.IComponents) => | ||
( | ||
input: OpenApiV3.IOperation.IParameter, | ||
): OpenApi.IOperation.IParameter => ({ | ||
...input, | ||
schema: convertSchema(components)(input.schema), | ||
}); | ||
const convertRequestBody = | ||
@@ -116,5 +121,8 @@ (doc: OpenApiV3.IDocument) => | ||
...input, | ||
content: input.content ? convertContent(input.content) : undefined, | ||
content: input.content | ||
? convertContent(doc.components ?? {})(input.content) | ||
: undefined, | ||
}; | ||
}; | ||
const convertResponse = | ||
@@ -135,3 +143,5 @@ (doc: OpenApiV3.IDocument) => | ||
...input, | ||
content: input.content ? convertContent(input.content) : undefined, | ||
content: input.content | ||
? convertContent(doc.components ?? {})(input.content) | ||
: undefined, | ||
headers: input.headers | ||
@@ -147,3 +157,3 @@ ? Object.fromEntries( | ||
if (TypeChecker.isReference(value) === false) | ||
return convertParameter({ | ||
return convertParameter(doc.components ?? {})({ | ||
...value, | ||
@@ -162,3 +172,3 @@ in: "header", | ||
return found !== undefined | ||
? convertParameter({ | ||
? convertParameter(doc.components ?? {})({ | ||
...found, | ||
@@ -176,20 +186,25 @@ in: "header", | ||
}; | ||
const convertContent = ( | ||
record: Record<string, OpenApiV3.IOperation.IMediaType>, | ||
): Record<string, OpenApi.IOperation.IMediaType> => | ||
Object.fromEntries( | ||
Object.entries(record) | ||
.filter(([_, v]) => v !== undefined) | ||
.map( | ||
([key, value]) => | ||
[ | ||
key, | ||
{ | ||
...value, | ||
schema: value.schema ? convertSchema(value.schema) : undefined, | ||
}, | ||
] as const, | ||
), | ||
); | ||
const convertContent = | ||
(components: OpenApiV3.IComponents) => | ||
( | ||
record: Record<string, OpenApiV3.IOperation.IMediaType>, | ||
): Record<string, OpenApi.IOperation.IMediaType> => | ||
Object.fromEntries( | ||
Object.entries(record) | ||
.filter(([_, v]) => v !== undefined) | ||
.map( | ||
([key, value]) => | ||
[ | ||
key, | ||
{ | ||
...value, | ||
schema: value.schema | ||
? convertSchema(components)(value.schema) | ||
: undefined, | ||
}, | ||
] as const, | ||
), | ||
); | ||
/* ----------------------------------------------------------- | ||
@@ -205,3 +220,3 @@ DEFINITIONS | ||
.filter(([_, v]) => v !== undefined) | ||
.map(([key, value]) => [key, convertSchema(value)]), | ||
.map(([key, value]) => [key, convertSchema(input)(value)]), | ||
) | ||
@@ -211,84 +226,142 @@ : undefined, | ||
}); | ||
export const convertSchema = ( | ||
input: OpenApiV3.IJsonSchema, | ||
): OpenApi.IJsonSchema => { | ||
const nullable: { value: boolean } = { value: false }; | ||
const union: OpenApi.IJsonSchema[] = []; | ||
const attribute: OpenApi.IJsonSchema.__IAttribute = { | ||
title: input.title, | ||
description: input.description, | ||
...Object.fromEntries( | ||
Object.entries(input).filter( | ||
([key, value]) => key.startsWith("x-") && value !== undefined, | ||
export const convertSchema = | ||
(components: OpenApiV3.IComponents) => | ||
(input: OpenApiV3.IJsonSchema): OpenApi.IJsonSchema => { | ||
const nullable: { value: boolean } = { value: false }; | ||
const union: OpenApi.IJsonSchema[] = []; | ||
const attribute: OpenApi.IJsonSchema.__IAttribute = { | ||
title: input.title, | ||
description: input.description, | ||
...Object.fromEntries( | ||
Object.entries(input).filter( | ||
([key, value]) => key.startsWith("x-") && value !== undefined, | ||
), | ||
), | ||
), | ||
}; | ||
const visit = (schema: OpenApiV3.IJsonSchema): void => { | ||
// NULLABLE PROPERTY | ||
if ( | ||
(schema as OpenApiV3.IJsonSchema.__ISignificant<any>).nullable === true | ||
) | ||
nullable.value ||= true; | ||
// UNION TYPE CASE | ||
if (TypeChecker.isAnyOf(schema)) schema.anyOf.forEach(visit); | ||
else if (TypeChecker.isOneOf(schema)) schema.oneOf.forEach(visit); | ||
// ATOMIC TYPE CASE (CONSIDER ENUM VALUES) | ||
else if ( | ||
TypeChecker.isBoolean(schema) || | ||
TypeChecker.isInteger(schema) || | ||
TypeChecker.isNumber(schema) || | ||
TypeChecker.isString(schema) | ||
) | ||
if (schema.enum?.length) | ||
union.push(...schema.enum.map((value) => ({ const: value }))); | ||
else | ||
}; | ||
const visit = (schema: OpenApiV3.IJsonSchema): void => { | ||
// NULLABLE PROPERTY | ||
if ( | ||
(schema as OpenApiV3.IJsonSchema.__ISignificant<any>).nullable === | ||
true | ||
) | ||
nullable.value ||= true; | ||
// UNION TYPE CASE | ||
if (TypeChecker.isAnyOf(schema)) schema.anyOf.forEach(visit); | ||
else if (TypeChecker.isOneOf(schema)) schema.oneOf.forEach(visit); | ||
else if (TypeChecker.isAllOf(schema)) | ||
union.push(convertAllOfSchema(components)(schema)); | ||
// ATOMIC TYPE CASE (CONSIDER ENUM VALUES) | ||
else if ( | ||
TypeChecker.isBoolean(schema) || | ||
TypeChecker.isInteger(schema) || | ||
TypeChecker.isNumber(schema) || | ||
TypeChecker.isString(schema) | ||
) | ||
if (schema.enum?.length) | ||
union.push(...schema.enum.map((value) => ({ const: value }))); | ||
else | ||
union.push({ | ||
...schema, | ||
...{ enum: undefined }, | ||
}); | ||
// INSTANCE TYPE CASE | ||
else if (TypeChecker.isArray(schema)) | ||
union.push({ | ||
...schema, | ||
...{ enum: undefined }, | ||
items: convertSchema(components)(schema.items), | ||
}); | ||
// INSTANCE TYPE CASE | ||
else if (TypeChecker.isArray(schema)) | ||
union.push({ | ||
...schema, | ||
items: convertSchema(schema.items), | ||
}); | ||
else if (TypeChecker.isObject(schema)) | ||
union.push({ | ||
...schema, | ||
else if (TypeChecker.isObject(schema)) | ||
union.push({ | ||
...schema, | ||
...{ | ||
properties: schema.properties | ||
? Object.fromEntries( | ||
Object.entries(schema.properties) | ||
.filter(([_, v]) => v !== undefined) | ||
.map(([key, value]) => [ | ||
key, | ||
convertSchema(components)(value), | ||
]), | ||
) | ||
: undefined, | ||
additionalProperties: schema.additionalProperties | ||
? typeof schema.additionalProperties === "object" && | ||
schema.additionalProperties !== null | ||
? convertSchema(components)(schema.additionalProperties) | ||
: schema.additionalProperties | ||
: undefined, | ||
}, | ||
}); | ||
else if (TypeChecker.isReference(schema)) union.push(schema); | ||
else union.push(schema); | ||
}; | ||
visit(input); | ||
if ( | ||
nullable.value === true && | ||
!union.some((e) => (e as OpenApi.IJsonSchema.INull).type === "null") | ||
) | ||
union.push({ type: "null" }); | ||
return { | ||
...(union.length === 0 | ||
? { type: undefined } | ||
: union.length === 1 | ||
? { ...union[0] } | ||
: { oneOf: union.map((u) => ({ ...u, nullable: undefined })) }), | ||
...attribute, | ||
...{ nullable: undefined }, | ||
}; | ||
}; | ||
const convertAllOfSchema = | ||
(components: OpenApiV3.IComponents) => | ||
(input: OpenApiV3.IJsonSchema.IAllOf): OpenApi.IJsonSchema => { | ||
const objects: Array<OpenApiV3.IJsonSchema.IObject | null> = | ||
input.allOf.map((schema) => retrieveObject(components)(schema)); | ||
if (objects.some((obj) => obj === null)) | ||
return { | ||
type: undefined, | ||
...{ | ||
properties: schema.properties | ||
? Object.fromEntries( | ||
Object.entries(schema.properties) | ||
.filter(([_, v]) => v !== undefined) | ||
.map(([key, value]) => [key, convertSchema(value)]), | ||
) | ||
: undefined, | ||
additionalProperties: schema.additionalProperties | ||
? typeof schema.additionalProperties === "object" && | ||
schema.additionalProperties !== null | ||
? convertSchema(schema.additionalProperties) | ||
: schema.additionalProperties | ||
: undefined, | ||
allOf: undefined, | ||
}, | ||
}); | ||
else if (TypeChecker.isReference(schema)) union.push(schema); | ||
else union.push(schema); | ||
}; | ||
return { | ||
...input, | ||
type: "object", | ||
properties: Object.fromEntries( | ||
objects | ||
.map((o) => Object.entries(o?.properties ?? {})) | ||
.flat() | ||
.map( | ||
([key, value]) => | ||
[key, convertSchema(components)(value)] as const, | ||
), | ||
), | ||
...{ | ||
allOf: undefined, | ||
}, | ||
}; | ||
}; | ||
visit(input); | ||
if ( | ||
nullable.value === true && | ||
!union.some((e) => (e as OpenApi.IJsonSchema.INull).type === "null") | ||
) | ||
union.push({ type: "null" }); | ||
return { | ||
...(union.length === 0 | ||
? { type: undefined } | ||
: union.length === 1 | ||
? { ...union[0] } | ||
: { oneOf: union.map((u) => ({ ...u, nullable: undefined })) }), | ||
...attribute, | ||
...{ nullable: undefined }, | ||
const retrieveObject = | ||
(components: OpenApiV3.IComponents) => | ||
( | ||
input: OpenApiV3.IJsonSchema, | ||
visited: Set<OpenApiV3.IJsonSchema> = new Set(), | ||
): OpenApiV3.IJsonSchema.IObject | null => { | ||
if (TypeChecker.isObject(input)) | ||
return input.properties !== undefined && !input.additionalProperties | ||
? input | ||
: null; | ||
else if (visited.has(input)) return null; | ||
else visited.add(input); | ||
if (TypeChecker.isReference(input)) | ||
return retrieveObject(components)( | ||
components.schemas?.[input.$ref.split("/").pop() ?? ""] ?? {}, | ||
visited, | ||
); | ||
return null; | ||
}; | ||
}; | ||
@@ -324,6 +397,6 @@ export namespace TypeChecker { | ||
(schema as OpenApiV3.IJsonSchema.IReference).$ref !== undefined; | ||
export const isOneOf = ( | ||
export const isAllOf = ( | ||
schema: OpenApiV3.IJsonSchema, | ||
): schema is OpenApiV3.IJsonSchema.IOneOf => | ||
(schema as OpenApiV3.IJsonSchema.IOneOf).oneOf !== undefined; | ||
): schema is OpenApiV3.IJsonSchema.IAllOf => | ||
(schema as OpenApiV3.IJsonSchema.IAllOf).allOf !== undefined; | ||
export const isAnyOf = ( | ||
@@ -333,2 +406,6 @@ schema: OpenApiV3.IJsonSchema, | ||
(schema as OpenApiV3.IJsonSchema.IAnyOf).anyOf !== undefined; | ||
export const isOneOf = ( | ||
schema: OpenApiV3.IJsonSchema, | ||
): schema is OpenApiV3.IJsonSchema.IOneOf => | ||
(schema as OpenApiV3.IJsonSchema.IOneOf).oneOf !== undefined; | ||
export const isNullOnly = ( | ||
@@ -335,0 +412,0 @@ schema: OpenApiV3.IJsonSchema, |
@@ -62,2 +62,3 @@ import { OpenApi } from "../OpenApi"; | ||
}); | ||
const convertOperation = | ||
@@ -108,2 +109,3 @@ (doc: SwaggerV2.IDocument) => | ||
}); | ||
const convertParameter = ( | ||
@@ -128,2 +130,3 @@ input: SwaggerV2.IOperation.IGeneralParameter, | ||
}); | ||
const convertResponse = | ||
@@ -192,2 +195,3 @@ (doc: SwaggerV2.IDocument) => | ||
}); | ||
const convertSecurityScheme = ( | ||
@@ -252,2 +256,3 @@ input: SwaggerV2.ISecurityDefinition, | ||
}; | ||
const convertSchema = (input: SwaggerV2.IJsonSchema): OpenApi.IJsonSchema => { | ||
@@ -254,0 +259,0 @@ const nullable: { value: boolean } = { value: false }; |
@@ -128,3 +128,2 @@ /** | ||
| IJsonSchema.INullOnly | ||
| IJsonSchema.IAllOf | ||
| IJsonSchema.IAnyOf | ||
@@ -131,0 +130,0 @@ | IJsonSchema.IOneOf; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
239335
5822