UNPKG

openapi2aspida

Version:

Convert OpenAPI 3.0 or Swagger 2.0 definitions into aspida

359 lines 17.2 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const converters_1 = require("./builderUtils/converters"); const getDirName_1 = __importDefault(require("./builderUtils/getDirName")); const headers2Props_1 = __importDefault(require("./builderUtils/headers2Props")); const parameters2Props_1 = __importDefault(require("./builderUtils/parameters2Props")); const props2String_1 = require("./builderUtils/props2String"); const requestBodies2Props_1 = __importDefault(require("./builderUtils/requestBodies2Props")); const resolvers_1 = require("./builderUtils/resolvers"); const responses2Props_1 = __importDefault(require("./builderUtils/responses2Props")); const schemas2Props_1 = __importDefault(require("./builderUtils/schemas2Props")); const methodNames = ['get', 'post', 'put', 'delete', 'head', 'options', 'patch']; const getParamsList = (openapi, params) => params?.map((p) => ((0, converters_1.isRefObject)(p) ? (0, resolvers_1.resolveParamsRef)(openapi, p.$ref) : p)) || []; exports.default = (openapi) => { const files = []; const schemas = (0, schemas2Props_1.default)(openapi.components?.schemas, openapi) || []; const parameters = (0, parameters2Props_1.default)(openapi.components?.parameters, openapi) || []; const requestBodies = (0, requestBodies2Props_1.default)(openapi.components?.requestBodies) || []; const responses = (0, responses2Props_1.default)(openapi.components?.responses) || []; const headers = (0, headers2Props_1.default)(openapi.components?.headers) || []; files.push(...Object.keys(openapi.paths) .map((path) => { const methodProps = Object.keys(openapi.paths[path]).filter((method) => methodNames.includes(method)); const file = [ ...path .replace(/\/$/, '') .split('/') .slice(1) .map((p) => (0, getDirName_1.default)(p, [ ...getParamsList(openapi, openapi.paths[path].parameters), ...methodProps.reduce((prev, c) => [ ...prev, ...getParamsList(openapi, openapi.paths[path][c]?.parameters), ], []), ], openapi)), 'index', ]; const methods = methodProps .map((method) => { const target = openapi.paths[path][method]; if (target.deprecated) return null; const params = []; if (target.parameters || openapi.paths[path].parameters) { const reqRefHeaders = []; const reqHeaders = []; const refQuery = []; const query = []; let queryRequired = false; [...(openapi.paths[path].parameters || []), ...(target.parameters || [])].forEach((p) => { if ((0, converters_1.isRefObject)(p)) { const ref = (0, resolvers_1.resolveParamsRef)(openapi, p.$ref); const val = { isArray: false, isEnum: false, nullable: false, description: ref.description ?? null, value: (0, converters_1.$ref2Type)(p.$ref), }; switch (ref.in) { case 'header': reqRefHeaders.push(val); break; case 'query': refQuery.push(val); queryRequired = queryRequired || (ref.required ?? false); break; default: break; } } else { const value = (0, converters_1.schema2value)(p.schema); if (!value) return; const prop = { name: (0, converters_1.getPropertyName)(p.name), required: p.required ?? false, description: p.description ?? null, values: [value], }; switch (p.in) { case 'header': reqHeaders.push(prop); break; case 'query': query.push(prop); queryRequired = queryRequired || (p.required ?? false); break; default: break; } } }); if (reqHeaders.length || reqRefHeaders.length) { params.push({ name: 'reqHeaders', required: false, description: null, values: [ ...reqRefHeaders, ...(reqHeaders.length ? [ { isArray: false, isEnum: false, nullable: false, description: null, value: reqHeaders, }, ] : []), ], }); } if (refQuery.length || query.length) { params.push({ name: 'query', required: queryRequired, description: null, values: [ ...refQuery, ...(query.length ? [ { isArray: false, isEnum: false, nullable: false, description: null, value: query, }, ] : []), ], }); } } if (target.responses) { const code = Object.keys(target.responses).find((code) => code.match(/^(20\d|30\d)$/)); if (code) { params.push({ name: 'status', required: true, description: null, values: [ { isArray: false, isEnum: false, nullable: false, description: null, value: code, }, ], }); const res = target.responses[code]; const ref = (0, converters_1.isRefObject)(res) ? (0, resolvers_1.resolveResRef)(openapi, res.$ref) : res; const content = (ref.content && Object.entries(ref.content).find(([key]) => key.startsWith('application/'))?.[1]) ?? ref.content?.[Object.keys(ref.content)[0]]; if (content?.schema) { const val = (0, converters_1.schema2value)(content.schema, true); if (val !== null) { params.push({ name: 'resBody', required: true, description: ref.description, values: [val], }); } } if (ref.headers) { params.push({ name: 'resHeaders', required: true, description: null, values: [ { isArray: false, isEnum: false, nullable: false, description: null, value: Object.keys(ref.headers) .map((header) => { const headerData = ref.headers[header]; const val = (0, converters_1.isRefObject)(headerData) ? { isArray: false, isEnum: false, description: null, value: (0, converters_1.$ref2Type)(headerData.$ref), } : (0, converters_1.schema2value)(headerData.schema); return (val && { name: (0, converters_1.getPropertyName)(header), required: (0, converters_1.isRefObject)(headerData) ? true : (headerData.required ?? true), description: (0, converters_1.isRefObject)(headerData) ? null : headerData.description, values: [val], }); }) .filter((v) => !!v), }, ], }); } } } if (target.requestBody) { let reqFormat = ''; let reqBody = null; let required = true; let description = null; if ((0, converters_1.isRefObject)(target.requestBody)) { const ref = (0, resolvers_1.resolveReqRef)(openapi, target.requestBody.$ref); if (ref.content['multipart/form-data']?.schema) { reqFormat = 'FormData'; } else if (ref.content['application/x-www-form-urlencoded']?.schema) { reqFormat = 'URLSearchParams'; } reqBody = { isArray: false, isEnum: false, nullable: false, description: null, value: (0, converters_1.$ref2Type)(target.requestBody.$ref), }; required = ref.required ?? true; description = ref.description ?? null; } else { required = target.requestBody.required ?? true; description = target.requestBody.description ?? null; if (target.requestBody.content['multipart/form-data']?.schema) { reqFormat = 'FormData'; reqBody = (0, converters_1.schema2value)(target.requestBody.content['multipart/form-data'].schema); } else if (target.requestBody.content['application/x-www-form-urlencoded']?.schema) { reqFormat = 'URLSearchParams'; reqBody = (0, converters_1.schema2value)(target.requestBody.content['application/x-www-form-urlencoded'].schema); } else { const content = target.requestBody.content && Object.entries(target.requestBody.content).find(([key]) => key.startsWith('application/'))?.[1]; if (content?.schema) reqBody = (0, converters_1.schema2value)(content.schema); } } if (reqFormat) { params.push({ name: 'reqFormat', required: true, description: null, values: [ { isArray: false, isEnum: false, nullable: false, description: null, value: reqFormat, }, ], }); } if (reqBody) { params.push({ name: 'reqBody', required, description, values: [reqBody], }); } } return { name: method, required: true, description: target.description ?? null, values: [ { isArray: false, isEnum: false, nullable: false, description: null, value: params, }, ], }; }) .filter((method) => !!method); if (methods.length) { const methodsText = (0, props2String_1.props2String)(methods, ''); const hasBinary = methodsText.includes(converters_1.BINARY_TYPE); const hasTypes = /( |<)Types\./.test(methodsText); return { file, methods: `/* eslint-disable */\nimport type { DefineMethods } from 'aspida';\n${hasBinary ? "import type { ReadStream } from 'fs';\n" : ''}${hasTypes ? `import type * as Types from '${file.map(() => '').join('../')}@types';\n` : ''}\nexport type Methods = DefineMethods<${methodsText}>;\n`, }; } else { return { file, methods: '' }; } }) .filter((file) => file.methods)); const typesText = parameters.length + schemas.length + requestBodies.length + responses.length + headers.length ? [ ...parameters.map((p) => ({ name: p.name, description: null, text: typeof p.prop === 'string' ? p.prop : (0, props2String_1.props2String)([p.prop], ''), })), ...schemas.map((s) => ({ name: s.name, description: s.value.description, text: (0, props2String_1.value2String)(s.value, '').replace(/\n {2}/g, '\n'), })), ...requestBodies.map((r) => ({ name: r.name, description: null, text: typeof r.value === 'string' ? r.value : (0, props2String_1.value2String)(r.value, '').replace(/\n {2}/g, '\n'), })), ...responses.map((r) => ({ name: r.name, description: null, text: typeof r.value === 'string' ? r.value : (0, props2String_1.value2String)(r.value, '').replace(/\n {2}/g, '\n'), })), ...headers.map((h) => ({ name: h.name, description: typeof h.value === 'string' ? null : h.value.description, text: typeof h.value === 'string' ? h.value : (0, props2String_1.value2String)(h.value, '').replace(/\n {2}/g, '\n'), })), ] .map((p) => `\n${(0, props2String_1.description2Doc)(p.description, '')}export type ${p.name} = ${p.text}\n`) .join('') .replace(/(\W)Types\./g, '$1') .replace(/\]\?:/g, ']:') : null; return { openapi, // for api-types baseURL: openapi.servers?.[0]?.url || '', types: typesText && `/* eslint-disable */${typesText.includes(converters_1.BINARY_TYPE) ? "\nimport type { ReadStream } from 'fs'\n" : ''}${typesText}`, files, }; }; //# sourceMappingURL=buildV3.js.map