UNPKG

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
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 };