Extend Express req.cleanBody type, lodash to pick input variables from schema.shape
This commit is contained in:
8
api/package-lock.json
generated
8
api/package-lock.json
generated
@@ -18,6 +18,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/express": "^5.0.3",
|
"@types/express": "^5.0.3",
|
||||||
|
"@types/lodash": "^4.17.20",
|
||||||
"drizzle-kit": "^0.31.4",
|
"drizzle-kit": "^0.31.4",
|
||||||
"tsx": "^4.20.3",
|
"tsx": "^4.20.3",
|
||||||
"typescript": "^5.8.3"
|
"typescript": "^5.8.3"
|
||||||
@@ -944,6 +945,13 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"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": {
|
"node_modules/@types/mime": {
|
||||||
"version": "1.3.5",
|
"version": "1.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/express": "^5.0.3",
|
"@types/express": "^5.0.3",
|
||||||
|
"@types/lodash": "^4.17.20",
|
||||||
"drizzle-kit": "^0.31.4",
|
"drizzle-kit": "^0.31.4",
|
||||||
"tsx": "^4.20.3",
|
"tsx": "^4.20.3",
|
||||||
"typescript": "^5.8.3"
|
"typescript": "^5.8.3"
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { int, mysqlTable, text, bigint, varchar, double } from 'drizzle-orm/mysql-core';
|
import { int, mysqlTable, text, bigint, varchar, double } from 'drizzle-orm/mysql-core';
|
||||||
|
import { createInsertSchema , createSelectSchema, createUpdateSchema } from 'drizzle-zod';
|
||||||
|
|
||||||
export const productsTable = mysqlTable('products', {
|
export const productsTable = mysqlTable('products', {
|
||||||
id: int().autoincrement().primaryKey(),
|
id: int().autoincrement().primaryKey(),
|
||||||
@@ -6,4 +7,15 @@ export const productsTable = mysqlTable('products', {
|
|||||||
description: text(),
|
description: text(),
|
||||||
image: varchar({ length: 255 }),
|
image: varchar({ length: 255 }),
|
||||||
price: double().notNull(),
|
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,
|
||||||
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import { Request, Response, NextFunction } from 'express';
|
import { Request, Response, NextFunction } from 'express';
|
||||||
import { z, ZodError, ZodTypeAny } from 'zod';
|
import { z, ZodError, ZodTypeAny } from 'zod';
|
||||||
import { ZodObject } from 'zod/v4';
|
import { ZodObject } from 'zod/v4';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
export function validateData(schema: ZodObject) {
|
export function validateData(schema: ZodObject) {
|
||||||
return (req: Request, res: Response, next: NextFunction) => {
|
return (req: Request, res: Response, next: NextFunction) => {
|
||||||
try {
|
try {
|
||||||
schema.parse(req.body);
|
schema.parse(req.body);
|
||||||
|
req.cleanBody = _.pick(req.body, Object.keys(schema.shape));
|
||||||
next();
|
next();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// console.log(error);
|
// console.log(error);
|
||||||
|
|||||||
@@ -7,16 +7,9 @@ import { listProducts,
|
|||||||
} from "./productsController";
|
} from "./productsController";
|
||||||
import { validateData } from "../../middlewares/validationMiddleware";
|
import { validateData } from "../../middlewares/validationMiddleware";
|
||||||
import { z, ZodObject, ZodTypeAny } from 'zod/v4';
|
import { z, ZodObject, ZodTypeAny } from 'zod/v4';
|
||||||
import { createInsertSchema , createSelectSchema, createUpdateSchema } from 'drizzle-zod';
|
import { productsTable, createProductSchema } from "../../db/productsSchema";
|
||||||
import { productsTable } from "../../db/productsSchema";
|
|
||||||
|
|
||||||
// const createProductSchema = z.object({
|
|
||||||
// name: z.string(),
|
|
||||||
// price: z.number({ message: "not a number you idiot."}),
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
|
||||||
const createProductSchema = createInsertSchema(productsTable).omit({id: true});
|
|
||||||
type ProductType = z.infer<typeof createProductSchema>;
|
type ProductType = z.infer<typeof createProductSchema>;
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
import {Request, Response} from 'express';
|
import {Request, Response} from 'express';
|
||||||
import {db} from '../../db/index';
|
import {db} from '../../db/index';
|
||||||
import {eq} from 'drizzle-orm';
|
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) {
|
export async function listProducts(req: Request, res: Response) {
|
||||||
try{
|
try{
|
||||||
@@ -33,9 +36,10 @@ export async function getProductById(req: Request, res: Response) {
|
|||||||
|
|
||||||
export async function createProduct(req: Request, res: Response) {
|
export async function createProduct(req: Request, res: Response) {
|
||||||
try{
|
try{
|
||||||
|
|
||||||
const productId = await db
|
const productId = await db
|
||||||
.insert(productsTable)
|
.insert(productsTable)
|
||||||
.values(req.body)
|
.values(req.cleanBody)
|
||||||
.$returningId()
|
.$returningId()
|
||||||
//const [product] = await db.insert(productsTable).values(req.body).Returning()
|
//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[]
|
//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
11
api/src/type/express/index.d.ts
vendored
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user