Extend Express req.cleanBody type, lodash to pick input variables from schema.shape

This commit is contained in:
Justin xzHome
2025-07-09 21:40:47 +09:00
parent b35d8f76df
commit fd08431f7b
7 changed files with 42 additions and 11 deletions

8
api/package-lock.json generated
View File

@@ -18,6 +18,7 @@
},
"devDependencies": {
"@types/express": "^5.0.3",
"@types/lodash": "^4.17.20",
"drizzle-kit": "^0.31.4",
"tsx": "^4.20.3",
"typescript": "^5.8.3"
@@ -944,6 +945,13 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/lodash": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/mime": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",

View File

@@ -24,6 +24,7 @@
},
"devDependencies": {
"@types/express": "^5.0.3",
"@types/lodash": "^4.17.20",
"drizzle-kit": "^0.31.4",
"tsx": "^4.20.3",
"typescript": "^5.8.3"

View File

@@ -1,4 +1,5 @@
import { int, mysqlTable, text, bigint, varchar, double } from 'drizzle-orm/mysql-core';
import { createInsertSchema , createSelectSchema, createUpdateSchema } from 'drizzle-zod';
export const productsTable = mysqlTable('products', {
id: int().autoincrement().primaryKey(),
@@ -6,4 +7,15 @@ export const productsTable = mysqlTable('products', {
description: text(),
image: varchar({ length: 255 }),
price: double().notNull(),
});
});
// const createProductSchema = z.object({
// name: z.string(),
// price: z.number({ message: "not a number you idiot."}),
// });
export const createProductSchema = createInsertSchema(productsTable).omit({
id: true,
});

View File

@@ -1,11 +1,13 @@
import { Request, Response, NextFunction } from 'express';
import { z, ZodError, ZodTypeAny } from 'zod';
import { ZodObject } from 'zod/v4';
import _ from 'lodash';
export function validateData(schema: ZodObject) {
return (req: Request, res: Response, next: NextFunction) => {
try {
schema.parse(req.body);
req.cleanBody = _.pick(req.body, Object.keys(schema.shape));
next();
} catch (error) {
// console.log(error);

View File

@@ -7,16 +7,9 @@ import { listProducts,
} from "./productsController";
import { validateData } from "../../middlewares/validationMiddleware";
import { z, ZodObject, ZodTypeAny } from 'zod/v4';
import { createInsertSchema , createSelectSchema, createUpdateSchema } from 'drizzle-zod';
import { productsTable } from "../../db/productsSchema";
// const createProductSchema = z.object({
// name: z.string(),
// price: z.number({ message: "not a number you idiot."}),
// });
import { productsTable, createProductSchema } from "../../db/productsSchema";
const createProductSchema = createInsertSchema(productsTable).omit({id: true});
type ProductType = z.infer<typeof createProductSchema>;
const router = Router();

View File

@@ -1,7 +1,10 @@
import {Request, Response} from 'express';
import {db} from '../../db/index';
import {eq} from 'drizzle-orm';
import { productsTable } from '../../db/productsSchema';
import { productsTable, createProductSchema } from "../../db/productsSchema";
import _ from 'lodash';
export async function listProducts(req: Request, res: Response) {
try{
@@ -33,9 +36,10 @@ export async function getProductById(req: Request, res: Response) {
export async function createProduct(req: Request, res: Response) {
try{
const productId = await db
.insert(productsTable)
.values(req.body)
.values(req.cleanBody)
.$returningId()
//const [product] = await db.insert(productsTable).values(req.body).Returning()
//Postgresql can return series of products so we can capture the first one from array[]

11
api/src/type/express/index.d.ts vendored Normal file
View File

@@ -0,0 +1,11 @@
// to make the file a module and avoid the TypeScript error
export {};
declare global {
namespace Express {
export interface Request {
userId?: Number;
cleanBody?: any
}
}
}