/** * 通用验证工具函数 * Common validation utility functions */ import * as v from 'valibot'; /** * 将 Valibot 验证错误转换为自定义格式 * Convert Valibot validation errors to custom format */ export function formatValidationErrors(issues) { return issues.map(issue => ({ field: issue.path?.map(p => p.key).join('.') || 'unknown', message: issue.message, code: issue.type || 'VALIDATION_ERROR', })); } /** * 安全解析数据 * Safely parse data with validation */ export function safeParseData(schema, data) { try { const result = v.safeParse(schema, data); if (result.success) { return { success: true, data: result.output, }; } else { return { success: false, errors: formatValidationErrors(result.issues), }; } } catch (error) { return { success: false, errors: [ { field: 'unknown', message: error instanceof Error ? error.message : '验证过程中发生未知错误', code: 'UNKNOWN_ERROR', }, ], }; } } /** * 解析并验证数据,失败时抛出错误 * Parse and validate data, throw error on failure */ export function parseData(schema, data) { const result = safeParseData(schema, data); if (!result.success) { const error = new Error('数据验证失败'); error.statusCode = 400; error.validationErrors = result.errors; throw error; } return result.data; } /** * 创建验证中间件函数(用于 API) * Create validation middleware function (for API) */ export function createValidationMiddleware(schema) { return (data) => { return parseData(schema, data); }; } /** * 验证查询参数 * Validate query parameters */ export function validateQuery(schema, query) { // 转换查询参数中的数字字符串 const processedQuery = Object.entries(query).reduce((acc, [key, value]) => { if (value === undefined || value === null || value === '') { return acc; } // 尝试转换数字 if (typeof value === 'string' && !isNaN(Number(value))) { acc[key] = Number(value); } else { acc[key] = value; } return acc; }, {}); return parseData(schema, processedQuery); } /** * 验证请求体数据 * Validate request body data */ export function validateBody(schema, body) { return parseData(schema, body); } /** * 验证路径参数 * Validate path parameters */ export function validateParams(schema, params) { // 转换路径参数中的数字字符串 const processedParams = Object.entries(params).reduce((acc, [key, value]) => { if (typeof value === 'string' && !isNaN(Number(value))) { acc[key] = Number(value); } else { acc[key] = value; } return acc; }, {}); return parseData(schema, processedParams); } //# sourceMappingURL=validation.js.map