UNPKG

@kubb/plugin-oas

Version:

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

324 lines (320 loc) • 12.1 kB
const require_chunk = require('./chunk-CbDLau6x.cjs'); const require_generators = require('./generators--9_lTBjl.cjs'); const require_SchemaGenerator = require('./SchemaGenerator-Bg5O155W.cjs'); require('./getFooter-BWck5e2D.cjs'); const require_SchemaMapper = require('./SchemaMapper-BUV8vhg0.cjs'); require('./getSchemas-BTCpbjet.cjs'); let __kubb_core = require("@kubb/core"); let __kubb_core_transformers = require("@kubb/core/transformers"); __kubb_core_transformers = require_chunk.__toESM(__kubb_core_transformers); let node_path = require("node:path"); node_path = require_chunk.__toESM(node_path); let __kubb_oas = require("@kubb/oas"); //#region src/OperationGenerator.ts var OperationGenerator = class extends __kubb_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 = __kubb_core_transformers.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(__kubb_core_transformers.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(__kubb_core_transformers.default.pascalCase(`${operationId} PathParams`)), operation, operationName, schema: pathParamsSchema, keys: resolveKeys(pathParamsSchema) } : void 0, queryParams: queryParamsSchema ? { name: resolveName(__kubb_core_transformers.default.pascalCase(`${operationId} QueryParams`)), operation, operationName, schema: queryParamsSchema, keys: resolveKeys(queryParamsSchema) || [] } : void 0, headerParams: headerParamsSchema ? { name: resolveName(__kubb_core_transformers.default.pascalCase(`${operationId} HeaderParams`)), operation, operationName, schema: headerParamsSchema, keys: resolveKeys(headerParamsSchema) } : void 0, request: requestSchema ? { name: resolveName(__kubb_core_transformers.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(__kubb_core_transformers.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(([path$1, 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: path$1, method, operation } : null; }).filter(Boolean)); } async build(...generators) { const operations = await this.getOperations(); const generatorLimit = require_SchemaGenerator.pLimit(1); const operationLimit = require_SchemaGenerator.pLimit(10); const writeTasks = generators.map((generator) => generatorLimit(async () => { const operationTasks = operations.map(({ operation, method }) => operationLimit(async () => { const options = this.#getOptions(operation, method); if (generator.type === "react") { await require_SchemaGenerator.buildOperation(operation, { config: this.context.pluginManager.config, fabric: this.context.fabric, Component: generator.Operation, generator: this, plugin: { ...this.context.plugin, options: { ...this.options, ...options } } }); return []; } return await generator.operation?.({ generator: this, config: this.context.pluginManager.config, operation, plugin: { ...this.context.plugin, options: { ...this.options, ...options } } }) ?? []; })); const opResultsFlat = (await Promise.all(operationTasks)).flat(); if (generator.type === "react") { await require_SchemaGenerator.buildOperations(operations.map((op) => op.operation), { fabric: this.context.fabric, config: this.context.pluginManager.config, Component: generator.Operations, generator: this, plugin: this.context.plugin }); return []; } const operationsResult = await generator.operations?.({ generator: this, config: this.context.pluginManager.config, operations: operations.map((op) => op.operation), plugin: this.context.plugin }); return [...opResultsFlat, ...operationsResult ?? []]; })); return (await Promise.all(writeTasks)).flat(); } }; //#endregion //#region src/plugin.ts const pluginOasName = "plugin-oas"; const pluginOas = (0, __kubb_core.definePlugin)((options) => { const { output = { path: "schemas" }, group, validate = true, generators = [require_generators.jsonGenerator], serverIndex, contentType, oasClass, discriminator = "strict" } = options; const getOas = async ({ config }) => { const oas = await (0, __kubb_oas.parseFromConfig)(config, oasClass); oas.setOptions({ contentType, discriminator }); try { if (validate) await oas.valdiate(); } catch (e) { const error = e; console.warn(error?.message); } return oas; }; return { name: pluginOasName, options: { output, validate, discriminator, ...options }, inject() { const config = this.config; let oas; return { async getOas() { if (!oas) oas = await getOas({ config }); return oas; }, async getBaseURL() { const oas$1 = await getOas({ config }); if (serverIndex) return oas$1.api.servers?.at(serverIndex)?.url; } }; }, resolvePath(baseName, pathMode, options$1) { const root = node_path.default.resolve(this.config.root, this.config.output.path); if ((pathMode ?? (0, __kubb_core.getMode)(node_path.default.resolve(root, output.path))) === "single") /** * when output is a file then we will always append to the same file(output file), see fileManager.addOrAppend * Other plugins then need to call addOrAppend instead of just add from the fileManager class */ return node_path.default.resolve(root, output.path); if (group && (options$1?.group?.path || options$1?.group?.tag)) { const groupName = group?.name ? group.name : (ctx) => { if (group?.type === "path") return `${ctx.group.split("/")[1]}`; return `${(0, __kubb_core_transformers.camelCase)(ctx.group)}Controller`; }; return node_path.default.resolve(root, output.path, groupName({ group: group.type === "path" ? options$1.group.path : options$1.group.tag }), baseName); } return node_path.default.resolve(root, output.path, baseName); }, async install() { if (!output) return; const oas = await this.getOas(); await oas.dereference(); const schemaFiles = await new require_SchemaGenerator.SchemaGenerator({ unknownType: "unknown", emptySchemaType: "unknown", dateType: "date", transformers: {}, ...this.plugin.options }, { fabric: this.fabric, oas, pluginManager: this.pluginManager, plugin: this.plugin, contentType, include: void 0, override: void 0, mode: "split", output: output.path }).build(...generators); await this.upsertFile(...schemaFiles); const operationFiles = await new OperationGenerator(this.plugin.options, { fabric: this.fabric, oas, pluginManager: this.pluginManager, plugin: this.plugin, contentType, exclude: void 0, include: void 0, override: void 0, mode: "split" }).build(...generators); await this.upsertFile(...operationFiles); } }; }); //#endregion //#region src/index.ts /** * @deprecated use `import { createGenerator } from '@kubb/plugin-oas/generators'` */ const createGenerator = require_generators.createGenerator; /** * @deprecated use `import { createReactGenerator } from '@kubb/plugin-oas/generators'` */ const createReactGenerator = require_generators.createReactGenerator; //#endregion exports.OperationGenerator = OperationGenerator; exports.SchemaGenerator = require_SchemaGenerator.SchemaGenerator; exports.buildOperation = require_SchemaGenerator.buildOperation; exports.buildOperations = require_SchemaGenerator.buildOperations; exports.buildSchema = require_SchemaGenerator.buildSchema; exports.createGenerator = createGenerator; exports.createReactGenerator = createReactGenerator; exports.isKeyword = require_SchemaMapper.isKeyword; exports.pluginOas = pluginOas; exports.pluginOasName = pluginOasName; exports.schemaKeywords = require_SchemaMapper.schemaKeywords; //# sourceMappingURL=index.cjs.map