@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
JavaScript
;
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