import { z } from '@hono/zod-openapi'; export async function parseWithAwait(schema: z.ZodSchema, data: unknown): Promise { // 先尝试同步解析,捕获 Promise 错误 const syncResult = schema.safeParse(data); if (!syncResult.success) { // 提取 Promise 错误的路径信息 const promiseErrors = syncResult.error.issues.filter(issue => issue.code === 'invalid_type' && issue.message.includes('received Promise') ); if (promiseErrors.length > 0) { // 根据路径直接 await Promise const processedData = await resolvePromisesByPath(data, promiseErrors); // 重新解析处理后的数据 return schema.parse(processedData) as T; } throw syncResult.error; } return syncResult.data as T; } async function resolvePromisesByPath(data: any, promiseErrors: any[]): Promise { const clonedData = JSON.parse(JSON.stringify(data, (key, value) => { // 保留 Promise 对象,不进行序列化 return typeof value?.then === 'function' ? value : value; })); // 根据错误路径逐个处理 Promise for (const error of promiseErrors) { const path = error.path; const promiseValue = getValueByPath(data, path); if (promiseValue && typeof promiseValue.then === 'function') { const resolvedValue = await promiseValue; setValueByPath(clonedData, path, resolvedValue); } } return clonedData; } function getValueByPath(obj: any, path: (string | number)[]): any { return path.reduce((current, key) => current?.[key], obj); } function setValueByPath(obj: any, path: (string | number)[], value: any): void { const lastKey = path[path.length - 1]; const parentPath = path.slice(0, -1); const parent = getValueByPath(obj, parentPath); if (parent) { parent[lastKey] = value; } }