Skip to content

Commit e173f76

Browse files
committed
add validation
1 parent 3a9b9ee commit e173f76

1 file changed

Lines changed: 106 additions & 0 deletions

File tree

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
const formatValidationErrors = (error) => {
2+
if (!error) return ["Invalid request"];
3+
4+
if (Array.isArray(error)) {
5+
return error
6+
.map((item) => item?.message || item?.msg || (typeof item === "string" ? item : null))
7+
.filter(Boolean);
8+
}
9+
10+
if (Array.isArray(error.errors)) {
11+
return error.errors
12+
.map((item) => item?.message || item?.msg || (typeof item === "string" ? item : null))
13+
.filter(Boolean);
14+
}
15+
16+
if (Array.isArray(error.details)) {
17+
return error.details
18+
.map((detail) => detail?.message || detail?.msg || (typeof detail === "string" ? detail : null))
19+
.filter(Boolean);
20+
}
21+
22+
if (Array.isArray(error.issues)) {
23+
return error.issues
24+
.map((issue) => issue?.message || issue?.msg || (typeof issue === "string" ? issue : null))
25+
.filter(Boolean);
26+
}
27+
28+
if (error.message) return [error.message];
29+
30+
return ["Invalid request"];
31+
};
32+
33+
export const validate = (schema, source = "body") => (req, res, next) => {
34+
if (!schema) return next();
35+
36+
const data = req[source];
37+
38+
try {
39+
if (typeof schema.safeParse === "function") {
40+
const result = schema.safeParse(data);
41+
if (!result.success) {
42+
res.status(400);
43+
const errors = formatValidationErrors(result.error);
44+
return next(new Error(errors.join(", ")));
45+
}
46+
req[source] = result.data;
47+
return next();
48+
}
49+
50+
if (typeof schema.parse === "function") {
51+
const parsed = schema.parse(data);
52+
req[source] = parsed;
53+
return next();
54+
}
55+
56+
if (typeof schema.validate === "function") {
57+
const { error, value } = schema.validate(data, {
58+
abortEarly: false,
59+
stripUnknown: true,
60+
});
61+
if (error) {
62+
res.status(400);
63+
const errors = formatValidationErrors(error);
64+
return next(new Error(errors.join(", ")));
65+
}
66+
if (value !== undefined) {
67+
req[source] = value;
68+
}
69+
return next();
70+
}
71+
72+
if (typeof schema === "function") {
73+
const result = schema(data, req);
74+
if (result === true || result === undefined) return next();
75+
if (result === false) {
76+
res.status(400);
77+
return next(new Error("Validation failed"));
78+
}
79+
if (typeof result === "string") {
80+
res.status(400);
81+
return next(new Error(result));
82+
}
83+
if (Array.isArray(result)) {
84+
res.status(400);
85+
return next(new Error(result.join(", ")));
86+
}
87+
if (result && result.error) {
88+
res.status(400);
89+
const errors = formatValidationErrors(result.error);
90+
return next(new Error(errors.join(", ")));
91+
}
92+
return next();
93+
}
94+
95+
return next();
96+
} catch (error) {
97+
if (res.statusCode === 200) {
98+
res.status(400);
99+
}
100+
return next(error);
101+
}
102+
};
103+
104+
export const validateBody = (schema) => validate(schema, "body");
105+
export const validateParams = (schema) => validate(schema, "params");
106+
export const validateQuery = (schema) => validate(schema, "query");

0 commit comments

Comments
 (0)