UNPKG

autosnippet

Version:

Extract code patterns into a knowledge base for AI coding assistants

96 lines (95 loc) 2.91 kB
/** * validate.ts — Express Zod 校验中间件 * * 用法: * import { validate, validateQuery } from '../middleware/validate.js'; * router.post('/batch-enable', validate(BatchEnableBody), async (req, res) => { ... }); * router.get('/search', validateQuery(SearchQuery), async (req, res) => { ... }); * * 校验通过后: * - req.body / req.query 被替换为 Zod parse 后的数据(已应用 defaults + coercion) * - handler 中直接使用,类型安全 * * 校验失败: * - 返回 400 + 结构化 VALIDATION_ERROR(包含 fieldErrors / formErrors) * * @module http/middleware/validate */ /** * 校验 req.body 的中间件工厂 * * @param schema Zod schema(通常为 z.object) * @returns Express 中间件 */ export function validate(schema) { return (req, res, next) => { const result = schema.safeParse(req.body ?? {}); if (!result.success) { res.status(400).json({ success: false, error: { code: 'VALIDATION_ERROR', message: 'Request body validation failed', details: result.error.flatten(), }, }); return; } // 替换为 parsed + defaulted 数据 req.body = result.data; next(); }; } /** * 校验 req.query 的中间件工厂 * * @param schema Zod schema * @returns Express 中间件 */ export function validateQuery(schema) { return (req, res, next) => { const result = schema.safeParse(req.query); if (!result.success) { res.status(400).json({ success: false, error: { code: 'VALIDATION_ERROR', message: 'Query parameter validation failed', details: result.error.flatten(), }, }); return; } // Express 5: req.query is a read-only getter, use defineProperty to override Object.defineProperty(req, 'query', { value: result.data, writable: true, configurable: true }); next(); }; } /** * 校验 req.params 的中间件工厂 * * @param schema Zod schema * @returns Express 中间件 */ export function validateParams(schema) { return (req, res, next) => { const result = schema.safeParse(req.params); if (!result.success) { res.status(400).json({ success: false, error: { code: 'VALIDATION_ERROR', message: 'Path parameter validation failed', details: result.error.flatten(), }, }); return; } Object.defineProperty(req, 'params', { value: result.data, writable: true, configurable: true, }); next(); }; }