Added zValidator wrapper for returning default error response

This commit is contained in:
sianida26 2024-05-08 00:25:41 +07:00
parent 790b9731c2
commit 199758150d
2 changed files with 103 additions and 95 deletions

View File

@ -10,6 +10,7 @@ import { hashPassword } from "../../utils/passwordUtils";
import { rolesToUsers } from "../../drizzle/schema/rolesToUsers";
import { rolesSchema } from "../../drizzle/schema/roles";
import HonoEnv from "../../types/HonoEnv";
import requestValidator from "../../utils/requestValidator";
const userFormSchema = z.object({
name: z.string().min(1).max(255),
@ -54,7 +55,7 @@ const usersRoute = new Hono<HonoEnv>()
})
.get(
"/",
zValidator(
requestValidator(
"query",
z.object({
includeTrashed: z.string().default("false"),
@ -86,7 +87,7 @@ const usersRoute = new Hono<HonoEnv>()
//get user by id
.get(
"/:id",
zValidator(
requestValidator(
"query",
z.object({
includeTrashed: z.string().default("false"),
@ -144,111 +145,75 @@ const usersRoute = new Hono<HonoEnv>()
}
)
//create user
.post(
"/",
zValidator("form", userFormSchema, (result) => {
if (!result.success) {
let errors = result.error.flatten().fieldErrors as Record<
string,
string[]
>;
let firstErrors: Record<string, string> = {};
for (let field in errors) {
firstErrors[field] = errors[field][0]; // Grabbing the first error message for each field
}
throw new HTTPException(422, {
message: JSON.stringify(firstErrors),
});
.post("/", requestValidator("form", userFormSchema), async (c) => {
const userData = c.req.valid("form");
const user = await db
.insert(users)
.values({
name: userData.name,
username: userData.username,
email: userData.email,
password: await hashPassword(userData.password),
isEnabled: userData.isEnabled.toLowerCase() === "true",
})
.returning();
if (userData.roles) {
const roles = JSON.parse(userData.roles) as string[];
console.log(roles);
if (roles.length) {
await db.insert(rolesToUsers).values(
roles.map((role) => ({
userId: user[0].id,
roleId: role,
}))
);
}
}),
async (c) => {
const userData = c.req.valid("form");
const user = await db
.insert(users)
.values({
name: userData.name,
username: userData.username,
email: userData.email,
password: await hashPassword(userData.password),
isEnabled: userData.isEnabled.toLowerCase() === "true",
})
.returning();
if (userData.roles) {
const roles = JSON.parse(userData.roles) as string[];
console.log(roles);
if (roles.length) {
await db.insert(rolesToUsers).values(
roles.map((role) => ({
userId: user[0].id,
roleId: role,
}))
);
}
}
return c.json(
{
message: "User created successfully",
},
201
);
}
)
return c.json(
{
message: "User created successfully",
},
201
);
})
//update user
.patch(
"/:id",
zValidator("form", userUpdateSchema, (result) => {
if (!result.success) {
let errors = result.error.flatten().fieldErrors as Record<
string,
string[]
>;
let firstErrors: Record<string, string> = {};
for (let field in errors) {
firstErrors[field] = errors[field][0]; // Grabbing the first error message for each field
}
throw new HTTPException(422, {
message: JSON.stringify(firstErrors),
});
}
}),
async (c) => {
const userId = c.req.param("id");
const userData = c.req.valid("form");
.patch("/:id", requestValidator("form", userUpdateSchema), async (c) => {
const userId = c.req.param("id");
const userData = c.req.valid("form");
const user = await db
.select()
.from(users)
.where(and(eq(users.id, userId), isNull(users.deletedAt)));
const user = await db
.select()
.from(users)
.where(and(eq(users.id, userId), isNull(users.deletedAt)));
if (!user[0]) return c.notFound();
if (!user[0]) return c.notFound();
await db
.update(users)
.set({
...userData,
...(userData.password
? { password: await hashPassword(userData.password) }
: {}),
updatedAt: new Date(),
isEnabled: userData.isEnabled.toLowerCase() === "true",
})
.where(eq(users.id, userId));
await db
.update(users)
.set({
...userData,
...(userData.password
? { password: await hashPassword(userData.password) }
: {}),
updatedAt: new Date(),
isEnabled: userData.isEnabled.toLowerCase() === "true",
})
.where(eq(users.id, userId));
return c.json({
message: "User updated successfully",
});
}
)
return c.json({
message: "User updated successfully",
});
})
//delete user
.delete(
"/:id",
zValidator(
requestValidator(
"form",
z.object({
skipTrash: z.string().default("false"),

View File

@ -0,0 +1,43 @@
import { zValidator } from "@hono/zod-validator";
import DashboardError from "../errors/DashboardError";
type ValidatorParameters = Parameters<typeof zValidator>;
/**
* Creates a request validator using the Zod schema.
* This middleware function is designed for use with the Hono framework to validate incoming requests.
* If the validation fails, it throws a `DashboardError` with detailed information about the validation errors.
*
* @param parameters - Parameters expected by `zValidator`. The first parameter is the Zod schema,
* the second is options for the Zod validator, and the third is a custom error handler.
* @returns A middleware function that validates the request against the provided schema.
*/
const requestValidator = (...parameters: ValidatorParameters) => {
return zValidator(
parameters[0],
parameters[1],
parameters[2] ??
((result) => {
if (!result.success) {
let errors = result.error.flatten().fieldErrors as Record<
string,
string[]
>;
let firstErrors: Record<string, string> = {};
for (let field in errors) {
firstErrors[field] = errors[field][0]; // Grabbing the first error message for each field
}
throw new DashboardError({
errorCode: "INVALID_FORM_DATA",
message:
"Validation failed. Please check your input and try again.",
formErrors: firstErrors,
severity: "LOW",
statusCode: 422,
});
}
})
);
};
export default requestValidator;