我必须编写 zod express 验证器中间件,该中间件对 zod-express-middleware 进行了稍微修改这是我的自定义请求验证器导出类型 ErrorListItem = {类型:'Query' |'Params'|...
我必须编写 zod express 验证器中间件,该中间件对 zod-express-middleware
这是我的自定义请求验证器
export type ErrorListItem = {
type: 'Query' | 'Params' | 'Body' | 'Response';
errors: ZodError<any>;
};
type RequestSchemas<TParams, TQuery, TBody, TResponse> = Partial<{
params: ZodSchema<TParams>;
query: ZodSchema<TQuery>;
body: ZodSchema<TBody>;
response: ZodSchema<TResponse>;
}>;
type RequestCallback<TParams, TQuery, TBody, TResponse> = (
data: {
params: TParams;
body: TBody;
query: TQuery;
},
req: Express.Request,
res: Express.Response
) => Promise<TResponse>;
type ValidatedRequest = (
req: Express.Request,
res: Express.Response,
next: Express.NextFunction
) => Promise<void>;
export const doValidatedRequest =
<TParams, TQuery, TBody, TResponse>(
schemas: RequestSchemas<TParams, TQuery, TBody, TResponse>,
cb: RequestCallback<TParams, TQuery, TBody, TResponse>,
succesStatusCode: number = 200
): ValidatedRequest =>
async (req, res, next) => {
try {
const errors: ErrorListItem[] = [];
const requestData = {
params: {} as any,
body: {} as any,
query: {} as any
};
if (schemas.params) {
const parsedParams = schemas.params.safeParse(req.params);
if (parsedParams.success) {
requestData.params = parsedParams.data;
} else {
errors.push({ type: 'Params', errors: parsedParams.error });
}
}
if (schemas.body) {
const parsedBody = schemas.body.safeParse(req.body);
if (parsedBody.success) {
requestData.body = parsedBody.data;
} else {
errors.push({ type: 'Body', errors: parsedBody.error });
}
}
if (schemas.query) {
const parsedQuery = schemas.query.safeParse(req.query);
if (parsedQuery.success) {
requestData.query = parsedQuery.data;
} else {
errors.push({ type: 'Query', errors: parsedQuery.error });
}
}
if (errors.length) {
next(errors);
}
const response = await cb(requestData, req, res);
if (schemas.response) {
const parsedResponse = schemas.response.safeParse(response);
if (parsedResponse.success) {
res.status(succesStatusCode).json(parsedResponse.data);
} else {
errors.push({ type: 'Response', errors: parsedResponse.error });
}
} else {
// Response not specified and thus not expected
res.status(succesStatusCode).json(response);
}
} catch (error) {
next(error);
}
};
现在当我尝试使用它
router.get('/', doValidatedRequest({}, async ({}, req, res) => someFunction(req, res));
或者
router.get('/:id', doValidatedRequest({
query: z.object({
id: z.string()
}),
}, async ({ query: { id }}) => someFunction(id));
我经常收到 eslint 错误 Promise returned in function argument where a void return was expected. eslint(@typescript-eslint/no-misused-promises)
我如何定义 someFunction
const someFunction = async (): Promise<void> => { // do something }
const someFunction = async (): Promise<string> => { return "OK" }
const someFunction = async (id: string): Promise<string> => { return id }
const someFunction = (): void => { // do something }
const someFunction = (): string => { return "OK" }
const someFunction = (id: string): string => { return id }
有人能发现这是为什么吗?我似乎找不到原因,我也想知道这是否还会在某个时候引起其他问题。我该如何改进这个中间件?
这个想法是,这可以用来验证请求参数和响应,如果需要,将经过验证且类型正确的参数传递给控制器函数,然后将可选验证的响应传递给验证器,然后将响应发送回请求者。