feat: Add zod middleware (#6961)

This commit is contained in:
Oli Juhl
2024-04-05 16:24:31 +02:00
committed by GitHub
parent ee73031d0e
commit 5ba74ec5fc
4 changed files with 125 additions and 2 deletions

View File

@@ -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"
}

View 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",
})
)
})
})

View 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)
}
}
}

View File

@@ -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