UNPKG

@kubb/plugin-oas

Version:

OpenAPI Specification (OAS) plugin for Kubb, providing core functionality for parsing and processing OpenAPI/Swagger schemas for code generation.

352 lines (347 loc) • 12.5 kB
'use strict'; var chunk7RFNM43R_cjs = require('./chunk-7RFNM43R.cjs'); var chunkQJMOOF2A_cjs = require('./chunk-QJMOOF2A.cjs'); require('./chunk-DTD4ZUDA.cjs'); var chunkNFLZLRQS_cjs = require('./chunk-NFLZLRQS.cjs'); var chunkYWMMI3MO_cjs = require('./chunk-YWMMI3MO.cjs'); require('./chunk-ZVFL3NXX.cjs'); require('./chunk-Z2NREI4X.cjs'); var core = require('@kubb/core'); var transformers = require('@kubb/core/transformers'); var pLimit = require('p-limit'); var path = require('path'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var transformers__default = /*#__PURE__*/_interopDefault(transformers); var pLimit__default = /*#__PURE__*/_interopDefault(pLimit); var path__default = /*#__PURE__*/_interopDefault(path); var OperationGenerator = class extends core.BaseGenerator { #getOptions(operation, method) { const { override = [] } = this.context; const operationId = operation.getOperationId({ friendlyCase: true }); const contentType = operation.getContentType(); return override.find(({ pattern, type }) => { switch (type) { case "tag": return operation.getTags().some((tag) => tag.name.match(pattern)); case "operationId": return !!operationId.match(pattern); case "path": return !!operation.path.match(pattern); case "method": return !!method.match(pattern); case "contentType": return !!contentType.match(pattern); default: return false; } })?.options || {}; } #isExcluded(operation, method) { const { exclude = [] } = this.context; const operationId = operation.getOperationId({ friendlyCase: true }); const contentType = operation.getContentType(); return exclude.some(({ pattern, type }) => { switch (type) { case "tag": return operation.getTags().some((tag) => tag.name.match(pattern)); case "operationId": return !!operationId.match(pattern); case "path": return !!operation.path.match(pattern); case "method": return !!method.match(pattern); case "contentType": return !!contentType.match(pattern); default: return false; } }); } #isIncluded(operation, method) { const { include = [] } = this.context; const operationId = operation.getOperationId({ friendlyCase: true }); const contentType = operation.getContentType(); return include.some(({ pattern, type }) => { switch (type) { case "tag": return operation.getTags().some((tag) => tag.name.match(pattern)); case "operationId": return !!operationId.match(pattern); case "path": return !!operation.path.match(pattern); case "method": return !!method.match(pattern); case "contentType": return !!contentType.match(pattern); default: return false; } }); } getSchemas(operation, { resolveName = (name) => name } = {}) { const operationId = operation.getOperationId({ friendlyCase: true }); const method = operation.method; const operationName = transformers__default.default.pascalCase(operationId); const resolveKeys = (schema) => schema?.properties ? Object.keys(schema.properties) : void 0; const pathParamsSchema = this.context.oas.getParametersSchema(operation, "path"); const queryParamsSchema = this.context.oas.getParametersSchema(operation, "query"); const headerParamsSchema = this.context.oas.getParametersSchema(operation, "header"); const requestSchema = this.context.oas.getRequestSchema(operation); const statusCodes = operation.getResponseStatusCodes().map((statusCode) => { const name = statusCode === "default" ? "error" : statusCode; const schema = this.context.oas.getResponseSchema(operation, statusCode); const keys = resolveKeys(schema); return { name: resolveName(transformers__default.default.pascalCase(`${operationId} ${name}`)), description: operation.getResponseByStatusCode(statusCode)?.description, schema, operation, operationName, statusCode: name === "error" ? void 0 : Number(statusCode), keys, keysToOmit: keys?.filter((key) => schema?.properties?.[key]?.writeOnly) }; }); const successful = statusCodes.filter((item) => item.statusCode?.toString().startsWith("2")); const errors = statusCodes.filter((item) => item.statusCode?.toString().startsWith("4") || item.statusCode?.toString().startsWith("5")); return { pathParams: pathParamsSchema ? { name: resolveName(transformers__default.default.pascalCase(`${operationId} PathParams`)), operation, operationName, schema: pathParamsSchema, keys: resolveKeys(pathParamsSchema) } : void 0, queryParams: queryParamsSchema ? { name: resolveName(transformers__default.default.pascalCase(`${operationId} QueryParams`)), operation, operationName, schema: queryParamsSchema, keys: resolveKeys(queryParamsSchema) || [] } : void 0, headerParams: headerParamsSchema ? { name: resolveName(transformers__default.default.pascalCase(`${operationId} HeaderParams`)), operation, operationName, schema: headerParamsSchema, keys: resolveKeys(headerParamsSchema) } : void 0, request: requestSchema ? { name: resolveName(transformers__default.default.pascalCase(`${operationId} ${method === "get" ? "queryRequest" : "mutationRequest"}`)), description: operation.schema.requestBody?.description, operation, operationName, schema: requestSchema, keys: resolveKeys(requestSchema), keysToOmit: resolveKeys(requestSchema)?.filter((key) => requestSchema.properties?.[key]?.readOnly) } : void 0, response: { name: resolveName(transformers__default.default.pascalCase(`${operationId} ${method === "get" ? "queryResponse" : "mutationResponse"}`)), operation, operationName, schema: { oneOf: successful.map((item) => ({ ...item.schema, $ref: item.name })) || void 0 } }, responses: successful, errors, statusCodes }; } async getOperations() { const { oas } = this.context; const paths = oas.getPaths(); return Object.entries(paths).flatMap( ([path2, methods]) => Object.entries(methods).map((values) => { const [method, operation] = values; if (this.#isExcluded(operation, method)) { return null; } if (this.context.include && !this.#isIncluded(operation, method)) { return null; } return operation ? { path: path2, method, operation } : null; }).filter(Boolean) ); } async build(...generators) { const operations = await this.getOperations(); const generatorLimit = pLimit__default.default(1); const operationLimit = pLimit__default.default(10); const writeTasks = generators.map( (generator) => generatorLimit(async () => { const operationTasks = operations.map( ({ operation, method }) => operationLimit(async () => { const options = this.#getOptions(operation, method); const result = await generator.operation?.({ instance: this, operation, options: { ...this.options, ...options } }); return result ?? []; }) ); const operationResults = await Promise.all(operationTasks); const opResultsFlat = operationResults.flat(); const operationsResult = await generator.operations?.({ instance: this, operations: operations.map((op) => op.operation), options: this.options }); return [...opResultsFlat, ...operationsResult ?? []]; }) ); const nestedResults = await Promise.all(writeTasks); return nestedResults.flat(); } }; var pluginOasName = "plugin-oas"; var pluginOas = core.createPlugin((options) => { const { output = { path: "schemas" }, group, validate = true, generators = [chunkQJMOOF2A_cjs.jsonGenerator], serverIndex, contentType, oasClass, discriminator = "strict" } = options; let oas; const getOas = async ({ config, logger }) => { oas = await chunk7RFNM43R_cjs.parseFromConfig(config, oasClass); oas.setOptions({ contentType, discriminator }); try { if (validate) { await oas.valdiate(); } } catch (e) { const error = e; logger.emit("warning", error?.message); } return oas; }; return { name: pluginOasName, options: { output, validate, discriminator, ...options }, context() { const { config, logger } = this; return { getOas() { return getOas({ config, logger }); }, async getBaseURL() { const oasInstance = await this.getOas(); if (serverIndex) { return oasInstance.api.servers?.at(serverIndex)?.url; } return void 0; } }; }, resolvePath(baseName, pathMode, options2) { const root = path__default.default.resolve(this.config.root, this.config.output.path); const mode = pathMode ?? core.FileManager.getMode(path__default.default.resolve(root, output.path)); if (mode === "single") { return path__default.default.resolve(root, output.path); } if (group && (options2?.group?.path || options2?.group?.tag)) { const groupName = group?.name ? group.name : (ctx) => { if (group?.type === "path") { return `${ctx.group.split("/")[1]}`; } return `${transformers.camelCase(ctx.group)}Controller`; }; return path__default.default.resolve( root, output.path, groupName({ group: group.type === "path" ? options2.group.path : options2.group.tag }), baseName ); } return path__default.default.resolve(root, output.path, baseName); }, async buildStart() { if (!output) { return; } const oas2 = await getOas({ config: this.config, logger: this.logger }); await oas2.dereference(); const schemaGenerator = new chunkNFLZLRQS_cjs.SchemaGenerator( { unknownType: "unknown", emptySchemaType: "unknown", dateType: "date", transformers: {}, ...this.plugin.options }, { oas: oas2, pluginManager: this.pluginManager, plugin: this.plugin, contentType, include: void 0, override: void 0, mode: "split", output: output.path } ); const schemaFiles = await schemaGenerator.build(...generators); await this.addFile(...schemaFiles); const operationGenerator = new OperationGenerator(this.plugin.options, { oas: oas2, pluginManager: this.pluginManager, plugin: this.plugin, contentType, exclude: void 0, include: void 0, override: void 0, mode: "split" }); const operationFiles = await operationGenerator.build(...generators); await this.addFile(...operationFiles); } }; }); Object.defineProperty(exports, "createGenerator", { enumerable: true, get: function () { return chunkQJMOOF2A_cjs.createGenerator; } }); Object.defineProperty(exports, "createReactGenerator", { enumerable: true, get: function () { return chunkQJMOOF2A_cjs.createReactGenerator; } }); Object.defineProperty(exports, "SchemaGenerator", { enumerable: true, get: function () { return chunkNFLZLRQS_cjs.SchemaGenerator; } }); Object.defineProperty(exports, "isKeyword", { enumerable: true, get: function () { return chunkYWMMI3MO_cjs.isKeyword; } }); Object.defineProperty(exports, "schemaKeywords", { enumerable: true, get: function () { return chunkYWMMI3MO_cjs.schemaKeywords; } }); exports.OperationGenerator = OperationGenerator; exports.pluginOas = pluginOas; exports.pluginOasName = pluginOasName; //# sourceMappingURL=index.cjs.map //# sourceMappingURL=index.cjs.map