feat: Add zod middleware (#6961)
This commit is contained in:
@@ -102,7 +102,8 @@
|
||||
"scrypt-kdf": "^2.0.1",
|
||||
"ulid": "^2.3.0",
|
||||
"uuid": "^9.0.0",
|
||||
"winston": "^3.8.2"
|
||||
"winston": "^3.8.2",
|
||||
"zod": "^3.22.4"
|
||||
},
|
||||
"gitHead": "cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e"
|
||||
}
|
||||
|
||||
73
packages/medusa/src/api-v2/utils/__tests__/validate-body.ts
Normal file
73
packages/medusa/src/api-v2/utils/__tests__/validate-body.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { z } from "zod"
|
||||
import { zodValidator } from "../validate-body"
|
||||
|
||||
describe("zodValidator", () => {
|
||||
it("should validate and return validated", async () => {
|
||||
const schema = z.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
})
|
||||
|
||||
const toValidate = {
|
||||
id: "1",
|
||||
name: "Tony Stark",
|
||||
}
|
||||
|
||||
const validated = await zodValidator(schema, toValidate)
|
||||
|
||||
expect(JSON.stringify(validated)).toBe(
|
||||
JSON.stringify({
|
||||
id: "1",
|
||||
name: "Tony Stark",
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should show human readable error message", async () => {
|
||||
const schema = z
|
||||
.object({
|
||||
id: z.string(),
|
||||
test: z.object({
|
||||
name: z.string(),
|
||||
test2: z.object({
|
||||
name: z.string(),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
.strict()
|
||||
|
||||
const toValidate = {
|
||||
id: "1",
|
||||
name: "Tony Stark",
|
||||
company: "Stark Industries",
|
||||
}
|
||||
|
||||
const errorMessage = await zodValidator(schema, toValidate).catch(
|
||||
(e) => e.message
|
||||
)
|
||||
|
||||
expect(errorMessage).toContain(
|
||||
"Invalid request body: "
|
||||
)
|
||||
})
|
||||
|
||||
it("should allow for non-strict parsing", async () => {
|
||||
const schema = z.object({
|
||||
id: z.string(),
|
||||
})
|
||||
|
||||
const toValidate = {
|
||||
id: "1",
|
||||
name: "Tony Stark",
|
||||
company: "Stark Industries",
|
||||
}
|
||||
|
||||
const validated = await zodValidator(schema, toValidate, { strict: false })
|
||||
|
||||
expect(JSON.stringify(validated)).toBe(
|
||||
JSON.stringify({
|
||||
id: "1",
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
48
packages/medusa/src/api-v2/utils/validate-body.ts
Normal file
48
packages/medusa/src/api-v2/utils/validate-body.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { MedusaError } from "@medusajs/utils"
|
||||
import { NextFunction } from "express"
|
||||
import { z, ZodError } from "zod"
|
||||
import { MedusaRequest, MedusaResponse } from "../../types/routing"
|
||||
|
||||
export async function zodValidator<T>(
|
||||
zodSchema: z.ZodObject<any, any>,
|
||||
body: T,
|
||||
config: { strict?: boolean } = { strict: true }
|
||||
): Promise<z.ZodRawShape> {
|
||||
try {
|
||||
let schema = zodSchema
|
||||
if (config.strict) {
|
||||
schema = schema.strict()
|
||||
}
|
||||
|
||||
return await schema.parseAsync(body)
|
||||
} catch (err) {
|
||||
if (err instanceof ZodError) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Invalid request body: ${JSON.stringify(err.errors)}`
|
||||
)
|
||||
}
|
||||
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
export function validateAndTransformBody(
|
||||
zodSchema: z.ZodObject<any, any>,
|
||||
config?: {
|
||||
strict?: boolean
|
||||
}
|
||||
): (
|
||||
req: MedusaRequest,
|
||||
res: MedusaResponse,
|
||||
next: NextFunction
|
||||
) => Promise<void> {
|
||||
return async (req: MedusaRequest, _: MedusaResponse, next: NextFunction) => {
|
||||
try {
|
||||
req.validatedBody = await zodValidator(zodSchema, req.body, config)
|
||||
next()
|
||||
} catch (e) {
|
||||
next(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8577,6 +8577,7 @@ __metadata:
|
||||
ulid: ^2.3.0
|
||||
uuid: ^9.0.0
|
||||
winston: ^3.8.2
|
||||
zod: ^3.22.4
|
||||
peerDependencies:
|
||||
medusa-interfaces: ^1.3.7
|
||||
typeorm: ^0.3.16
|
||||
@@ -52991,7 +52992,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"zod@npm:3.22.4":
|
||||
"zod@npm:3.22.4, zod@npm:^3.22.4":
|
||||
version: 3.22.4
|
||||
resolution: "zod@npm:3.22.4"
|
||||
checksum: 7578ab283dac0eee66a0ad0fc4a7f28c43e6745aadb3a529f59a4b851aa10872b3890398b3160f257f4b6817b4ce643debdda4fb21a2c040adda7862cab0a587
|
||||
|
||||
Reference in New Issue
Block a user