118 lines
3.1 KiB
JavaScript
118 lines
3.1 KiB
JavaScript
/**
|
||
* 通用验证工具函数
|
||
* 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
|