| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 |
- import { z } from '@hono/zod-openapi';
- export async function parseWithAwait<T>(schema: z.ZodSchema<T>, data: unknown): Promise<T> {
- // 先尝试同步解析,捕获 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<any> {
- const clonedData = JSON.parse(JSON.stringify(data, (_, 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;
- }
- }
|