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.
85 lines (82 loc) • 2.18 kB
JavaScript
import { SchemaRegistry, generateSwaggerUIHTML, getCallLocation, getSwaggerUIAssetDir } from "./swagger-CArZTgxc.js";
import express from "express";
//#region src/express/middlewares/zodValidator.ts
/**
* 默认错误处理函数
*/
const defaultErrorHandler = (error, _req, res) => {
res.status(400).json(error);
};
/**
* 创建类型安全的 Zod 校验中间件
*
* @param options 校验配置选项
* @returns 类型化的Express中间件,提供对应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 (req, res, next) => {
if (body) {
const result = await body.safeParseAsync(req.body);
if (result.success) req.body = result.data;
else {
await onError(result.error, req, res, next);
return;
}
}
if (query) {
const result = await query.safeParseAsync(req.query);
if (result.success) Object.assign(req.query, result.data);
else {
await onError(result.error, req, res, next);
return;
}
}
if (params) {
const result = await params.safeParseAsync(req.params);
if (result.success) req.params = result.data;
else {
await onError(result.error, req, res, next);
return;
}
}
if (headers) {
const result = await headers.safeParseAsync(req.headers);
if (result.success) req.headers = result.data;
else {
await onError(result.error, req, res, next);
return;
}
}
next();
};
}
//#endregion
//#region src/express/swagger.ts
/**
* 设置 SwaggerUI 的静态资源和路由
* @param path SwaggerUI 路径
* @param app Express 应用实例
* @param options 选项
*
* @category Express
*/
function setupSwaggerUI(path, app, options = {}) {
const assetDir = getSwaggerUIAssetDir();
app.use(express.static(assetDir));
app.get(path, (_req, res) => {
const html = generateSwaggerUIHTML(options);
res.setHeader("Content-Type", "text/html");
res.send(html);
});
}
//#endregion
export { setupSwaggerUI, zodValidator };