UNPKG

openapi-typescript

Version:

Convert OpenAPI 3.0 & 3.1 schemas to TypeScript

177 lines (166 loc) 6.93 kB
import type { ComponentsObject, GlobalContext } from "../types.js"; import { escObjKey, getEntries, getSchemaObjectComment, indent, tsOptionalProperty, tsReadonly } from "../utils.js"; import transformHeaderObject from "./header-object.js"; import transformParameterObject from "./parameter-object.js"; import transformPathItemObject from "./path-item-object.js"; import transformRequestBodyObject from "./request-body-object.js"; import transformResponseObject from "./response-object.js"; import transformSchemaObjectMap from "./schema-object-map.js"; import transformSchemaObject from "./schema-object.js"; export default function transformComponentsObject(components: ComponentsObject, ctx: GlobalContext): string { let { indentLv } = ctx; const output: string[] = ["{"]; indentLv++; // schemas if (components.schemas) { const schemas = transformSchemaObjectMap(components.schemas, { path: "#/components/schemas/", ctx: { ...ctx, indentLv } }); output.push(indent(`schemas: ${schemas};`, indentLv)); } else { output.push(indent("schemas: never;", indentLv)); } // responses if (components.responses) { output.push(indent("responses: {", indentLv)); indentLv++; for (const [name, responseObject] of getEntries(components.responses, ctx.alphabetize, ctx.excludeDeprecated)) { const c = getSchemaObjectComment(responseObject, indentLv); if (c) output.push(indent(c, indentLv)); let key = escObjKey(name); if (ctx.immutableTypes) key = tsReadonly(key); if ("$ref" in responseObject) { output.push(indent(`${key}: ${transformSchemaObject(responseObject, { path: `#/components/responses/${name}`, ctx })};`, indentLv)); } else { const responseType = transformResponseObject(responseObject, { path: `#/components/responses/${name}`, ctx: { ...ctx, indentLv }, }); output.push(indent(`${key}: ${responseType};`, indentLv)); } } indentLv--; output.push(indent("};", indentLv)); } else { output.push(indent("responses: never;", indentLv)); } // parameters if (components.parameters) { const parameters: string[] = []; indentLv++; let isEveryParameterOptional = true; for (const [name, parameterObject] of getEntries(components.parameters, ctx.alphabetize, ctx.excludeDeprecated)) { const c = getSchemaObjectComment(parameterObject, indentLv); if (c) parameters.push(indent(c, indentLv)); let key = escObjKey(name); if (ctx.immutableTypes) key = tsReadonly(key); if ("$ref" in parameterObject) { parameters.push(indent(`${key}: ${transformSchemaObject(parameterObject, { path: `#/components/parameters/${name}`, ctx })};`, indentLv)); isEveryParameterOptional = false; } else { if (parameterObject.in !== "path" && !parameterObject.required) { key = tsOptionalProperty(key); } else { isEveryParameterOptional = false; } const parameterType = transformParameterObject(parameterObject, { path: `#/components/parameters/${name}`, ctx: { ...ctx, indentLv }, }); parameters.push(indent(`${key}: ${parameterType};`, indentLv)); } } indentLv--; const parametersKey = isEveryParameterOptional ? tsOptionalProperty("parameters") : "parameters"; output.push(indent(`${parametersKey}: {`, indentLv), ...parameters, indent("};", indentLv)); } else { output.push(indent("parameters: never;", indentLv)); } // requestBodies if (components.requestBodies) { output.push(indent("requestBodies: {", indentLv)); indentLv++; for (const [name, requestBodyObject] of getEntries(components.requestBodies, ctx.alphabetize, ctx.excludeDeprecated)) { const c = getSchemaObjectComment(requestBodyObject, indentLv); if (c) output.push(indent(c, indentLv)); let key = escObjKey(name); if ("$ref" in requestBodyObject) { if (ctx.immutableTypes) key = tsReadonly(key); output.push( indent( `${key}: ${transformSchemaObject(requestBodyObject, { path: `#/components/requestBodies/${name}`, ctx: { ...ctx, indentLv }, })};`, indentLv, ), ); } else { if (!requestBodyObject.required) key = tsOptionalProperty(key); if (ctx.immutableTypes) key = tsReadonly(key); const requestBodyType = transformRequestBodyObject(requestBodyObject, { path: `#/components/requestBodies/${name}`, ctx: { ...ctx, indentLv }, }); output.push(indent(`${key}: ${requestBodyType};`, indentLv)); } } indentLv--; output.push(indent("};", indentLv)); } else { output.push(indent("requestBodies: never;", indentLv)); } // headers if (components.headers) { output.push(indent("headers: {", indentLv)); indentLv++; for (const [name, headerObject] of getEntries(components.headers, ctx.alphabetize, ctx.excludeDeprecated)) { const c = getSchemaObjectComment(headerObject, indentLv); if (c) output.push(indent(c, indentLv)); let key = escObjKey(name); if (ctx.immutableTypes) key = tsReadonly(key); if ("$ref" in headerObject) { output.push(indent(`${key}: ${transformSchemaObject(headerObject, { path: `#/components/headers/${name}`, ctx })};`, indentLv)); } else { const headerType = transformHeaderObject(headerObject, { path: `#/components/headers/${name}`, ctx: { ...ctx, indentLv }, }); output.push(indent(`${key}: ${headerType};`, indentLv)); } } indentLv--; output.push(indent("};", indentLv)); } else { output.push(indent("headers: never;", indentLv)); } // pathItems if (components.pathItems) { output.push(indent("pathItems: {", indentLv)); indentLv++; for (const [name, pathItemObject] of getEntries(components.pathItems, ctx.alphabetize, ctx.excludeDeprecated)) { let key = escObjKey(name); if (ctx.immutableTypes) key = tsReadonly(key); if ("$ref" in pathItemObject) { const c = getSchemaObjectComment(pathItemObject, indentLv); if (c) output.push(indent(c, indentLv)); output.push(indent(`${key}: ${transformSchemaObject(pathItemObject, { path: `#/components/pathItems/${name}`, ctx })};`, indentLv)); } else { output.push( indent( `${key}: ${transformPathItemObject(pathItemObject, { path: `#/components/pathItems/${name}`, ctx: { ...ctx, indentLv }, })};`, indentLv, ), ); } } indentLv--; output.push(indent("};", indentLv)); } else { output.push(indent("pathItems: never;", indentLv)); } indentLv--; output.push(indent("}", indentLv)); return output.join("\n"); }