api-morph
Version:
A modern TypeScript-first OpenAPI document generator that analyzes your code and JSDoc comments to automatically generate comprehensive and accurate API documentation.
88 lines (85 loc) • 2.21 kB
JavaScript
import { SchemaRegistry, generateSwaggerUIHTML, getCallLocation, getSwaggerUIAssetDir } from "./swagger-CArZTgxc.js";
import serve from "koa-static";
//#region src/koa/middlewares/zodValidator.ts
/**
* 默认错误处理函数
*/
const defaultErrorHandler = (error, ctx) => {
ctx.status = 400;
ctx.body = error;
};
/**
* 创建类型安全的 Koa Zod 校验中间件
*
* @param options 校验配置选项
* @returns 类型化的Koa中间件,提供对应schema字段的类型提示
*/
function zodValidator(options) {
const { body, query, params, headers, onError = defaultErrorHandler } = options;
const location = getCallLocation();
const registry = SchemaRegistry.getInstance();
registry.register(location, {
body,
query,
params,
headers
});
return async (ctx, next) => {
if (body) {
const result = await body.safeParseAsync(ctx.request.body);
if (result.success) ctx.request.body = result.data;
else {
await onError(result.error, ctx, next);
return;
}
}
if (query) {
const result = await query.safeParseAsync(ctx.query);
if (result.success) ctx.query = result.data;
else {
await onError(result.error, ctx, next);
return;
}
}
if (params) {
const result = await params.safeParseAsync(ctx.params);
if (result.success) ctx.params = result.data;
else {
await onError(result.error, ctx, next);
return;
}
}
if (headers) {
const result = await headers.safeParseAsync(ctx.headers);
if (result.success) ctx.headers = result.data;
else {
await onError(result.error, ctx, next);
return;
}
}
await next();
};
}
//#endregion
//#region src/koa/swagger.ts
/**
* 设置 SwaggerUI 的静态资源和路由
* @param path SwaggerUI 路径
* @param app Koa 应用实例
* @param options 选项
*
* @category Koa
*/
function setupSwaggerUI(path, app, options = {}) {
const assetDir = getSwaggerUIAssetDir();
app.use(serve(assetDir));
app.use(async (ctx, next) => {
if (ctx.path === path && ctx.method === "GET") {
const html = generateSwaggerUIHTML(options);
ctx.set("Content-Type", "text/html");
ctx.body = html;
} else await next();
});
}
//#endregion
export { setupSwaggerUI, zodValidator };