{"_id":"express-zod-validations","_rev":"3-e5712e37045412d217bdb35f4a5ac6fb","name":"express-zod-validations","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"express-zod-validations","version":"0.1.0","keywords":["express-middleware","validation-middleware","zod-validation","request-validation","input-validation","data-validations","schema-validation","input-sanitization","custom-middleware","express","middleware","zod"],"author":{"name":"Mattia Malonni"},"license":"MIT","_id":"express-zod-validations@0.1.0","maintainers":[{"name":"mattiamalonni","email":"mattia.malonni@gmail.com"}],"homepage":"https://github.com/mattiamalonni/express-zod-validations#readme","bugs":{"url":"https://github.com/mattiamalonni/express-zod-validations/issues"},"dist":{"shasum":"6c248994bcbcd182e57d0c199b215abf6f43a333","tarball":"https://registry.npmjs.org/express-zod-validations/-/express-zod-validations-0.1.0.tgz","fileCount":4,"integrity":"sha512-Qj22ZGTa7p4xmaJPNcg4JcyyjFkkfAg3AGCFbt8vJ8lO+l5zG8QSZ3rIK6CnKr/z3bXrsaSOVV1KZqvpckKfvg==","signatures":[{"sig":"MEYCIQDKW0paI9dTwYHMQsqqYZQ6eomL/j6vr273FJmqnZh6XQIhAJck/whXpNqiDQCem6YXXwd15SuNkPqmGepiVLaTBh3v","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":11772},"main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"b82506dcbc895fca71868f600e40f83f32935317","scripts":{"build":"tsc -p tsconfig.json"},"_npmUser":{"name":"mattiamalonni","email":"mattia.malonni@gmail.com"},"repository":{"url":"git+https://github.com/mattiamalonni/express-zod-validations.git","type":"git"},"_npmVersion":"11.7.0","description":"Express middleware to validate request (headers, params, query, body) using Zod","directories":{},"_nodeVersion":"20.19.0","_hasShrinkwrap":false,"devDependencies":{"zod":"^4","express":"^5","typescript":"^5","@types/node":"^20","@types/express":"^5"},"peerDependencies":{"zod":"^4","express":"^5"},"_npmOperationalInternal":{"tmp":"tmp/express-zod-validations_0.1.0_1766075148062_0.4943675129447862","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"express-zod-validations","version":"0.1.1","keywords":["express-middleware","validation-middleware","zod-validation","request-validation","input-validation","data-validations","schema-validation","input-sanitization","custom-middleware","express","middleware","zod"],"author":{"name":"Mattia Malonni"},"license":"MIT","_id":"express-zod-validations@0.1.1","maintainers":[{"name":"mattiamalonni","email":"mattia.malonni@gmail.com"}],"homepage":"https://github.com/mattiamalonni/express-zod-validations#readme","bugs":{"url":"https://github.com/mattiamalonni/express-zod-validations/issues"},"dist":{"shasum":"eeb067599472e476a986d01a69570a65f2fc1b41","tarball":"https://registry.npmjs.org/express-zod-validations/-/express-zod-validations-0.1.1.tgz","fileCount":4,"integrity":"sha512-qKMbm6cSMkl5p6iRV/eZKapFCKAOsbxRJUUEZo9fQm5dq0mlz8TdYyGdB/jVkUAf9nCuwK1BTUr+SuI1se+Pqw==","signatures":[{"sig":"MEUCIQDW5eS1teR7vwNvFOE0KuJupH7GURnJ3wT8PypLsvTQPAIgPsTqQ+xs3xpXZD2hcChKPrlW3t6PTVC5NeVSFjyT7Mg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/express-zod-validations@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":12421},"main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"02e5ec620eaf896ebc49f066af4530ae2d3924ee","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:04849dfb-c40c-44a5-8c4d-81fac2ca2b75"}},"repository":{"url":"git+https://github.com/mattiamalonni/express-zod-validations.git","type":"git"},"_npmVersion":"11.7.0","description":"Express middleware to validate request (headers, params, query, body) using Zod","directories":{},"_nodeVersion":"20.19.6","_hasShrinkwrap":false,"devDependencies":{"zod":"^4","vitest":"^4.0.16","express":"^5","supertest":"^7.1.4","typescript":"^5","@types/node":"^20","@types/express":"^5","@types/supertest":"^6.0.3"},"peerDependencies":{"zod":"^4","express":"^5"},"_npmOperationalInternal":{"tmp":"tmp/express-zod-validations_0.1.1_1766142704313_0.5183392285538351","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"express-zod-validations","version":"0.1.2","description":"Express middleware to validate request (headers, params, query, body) using Zod","author":{"name":"Mattia Malonni"},"license":"MIT","keywords":["express-middleware","validation-middleware","zod-validation","request-validation","input-validation","data-validations","schema-validation","input-sanitization","custom-middleware","express","middleware","zod"],"repository":{"type":"git","url":"git+https://github.com/mattiamalonni/express-zod-validations.git"},"type":"module","main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"scripts":{"build":"tsc -p tsconfig.json","test":"vitest run","lint":"eslint .","format":"prettier --write ."},"peerDependencies":{"express":"^5","zod":"^4"},"devDependencies":{"@eslint/js":"^10.0.1","@types/express":"^5","@types/node":"^20","@types/supertest":"^6.0.3","eslint":"^10.7.0","eslint-config-prettier":"^10.1.8","express":"^5","prettier":"^3.9.5","supertest":"^7.1.4","typescript":"^5","typescript-eslint":"^8.64.0","vitest":"^4.0.16","zod":"^4"},"gitHead":"4671b4a4f1ba7e8a1722a522ee2157dbb0ccf91a","_id":"express-zod-validations@0.1.2","bugs":{"url":"https://github.com/mattiamalonni/express-zod-validations/issues"},"homepage":"https://github.com/mattiamalonni/express-zod-validations#readme","_nodeVersion":"20.20.2","_npmVersion":"11.18.0","dist":{"integrity":"sha512-ISRo/Em8BEbeKMBKOaDKHGKTzTqUWuohpiRS/XmM6WPYMpYH74dfR+v9zxPK9K4qYPjLSENq4KOV1awuU8bJXQ==","shasum":"5c2ef8151d7cadc06d7fc00aa1359c60b6819e22","tarball":"https://registry.npmjs.org/express-zod-validations/-/express-zod-validations-0.1.2.tgz","fileCount":4,"unpackedSize":12970,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/express-zod-validations@0.1.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC/9Ht+ODBXpayqno0+Xyisufp7ZzrBKrGQjJ50+4utegIhAIZkgY5pmFwttIp9tbD3jBhDNbLg6qY2mc9UWdw45NpF"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:04849dfb-c40c-44a5-8c4d-81fac2ca2b75"}},"directories":{},"maintainers":[{"name":"mattiamalonni","email":"mattia.malonni@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/express-zod-validations_0.1.2_1784209115252_0.9872947866182136"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-18T16:25:48.061Z","modified":"2026-07-16T13:38:35.726Z","0.1.0":"2025-12-18T16:25:48.218Z","0.1.1":"2025-12-19T11:11:44.511Z","0.1.2":"2026-07-16T13:38:35.404Z"},"bugs":{"url":"https://github.com/mattiamalonni/express-zod-validations/issues"},"author":{"name":"Mattia Malonni"},"license":"MIT","homepage":"https://github.com/mattiamalonni/express-zod-validations#readme","keywords":["express-middleware","validation-middleware","zod-validation","request-validation","input-validation","data-validations","schema-validation","input-sanitization","custom-middleware","express","middleware","zod"],"repository":{"type":"git","url":"git+https://github.com/mattiamalonni/express-zod-validations.git"},"description":"Express middleware to validate request (headers, params, query, body) using Zod","maintainers":[{"name":"mattiamalonni","email":"mattia.malonni@gmail.com"}],"readme":"# express-zod-validations\n\n[![npm version](https://badge.fury.io/js/express-zod-validations.svg)](https://www.npmjs.com/package/express-zod-validations)\n[![Publish](https://github.com/mattiamalonni/express-zod-validations/actions/workflows/publish.yml/badge.svg)](https://github.com/mattiamalonni/express-zod-validations/actions/workflows/publish.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue.svg)](https://www.typescriptlang.org/)\n\nType-safe Express middleware for validating requests using [Zod](https://github.com/colinhacks/zod).\n\n## Features\n\n- 🛡️ **Type-safe validation** - Full TypeScript support with Zod schemas\n- 🚀 **Async by default** - Uses `safeParseAsync` for async transformations\n- 🎯 **Granular validation** - Validate body, params, query, and headers independently\n- 🔧 **Flexible error handling** - Choose between storing or throwing validation errors\n- 📦 **Zero config** - Works out of the box with sensible defaults\n\n## Installation\n\n```bash\nnpm install express-zod-validations zod express\n```\n\n## Quick Start\n\n```typescript\nimport express from \"express\";\nimport { z } from \"zod\";\nimport { validateBody } from \"express-zod-validations\";\n\nconst app = express();\napp.use(express.json());\n\n// Define your schema\nconst userSchema = z.object({\n  name: z.string().min(2),\n  email: z.email(),\n  age: z.number().int().positive().optional(),\n});\n\n// Use it in your route\napp.post(\"/users\", validateBody(userSchema), (req, res) => {\n  // Access validated data\n  const user = req.validationValues.body;\n\n  // Check for errors (if throwErrors is false)\n  if (req.validationErrors?.body) {\n    return res.status(400).json({ errors: req.validationErrors.body.errors });\n  }\n\n  res.json({ message: \"User created\", user });\n});\n\napp.listen(3000);\n```\n\n## Usage\n\n### Validate Different Request Parts\n\n```typescript\nimport { z } from \"zod\";\nimport {\n  validateBody,\n  validateParams,\n  validateQuery,\n  validateHeaders,\n} from \"express-zod-validations\";\n\n// Body validation\napp.post(\"/users\", validateBody(z.object({ name: z.string() })), handler);\n\n// URL params validation\napp.get(\n  \"/users/:id\",\n  validateParams(z.object({ id: z.uuid() })),\n  handler,\n);\n\n// Query string validation\napp.get(\n  \"/users\",\n  validateQuery(z.object({ page: z.coerce.number().int().min(1).default(1) })),\n  handler,\n);\n\n// Headers validation\napp.get(\n  \"/protected\",\n  validateHeaders(\n    z.object({ authorization: z.string().startsWith(\"Bearer \") }),\n  ),\n  handler,\n);\n```\n\n### Validate Multiple Parts at Once\n\n```typescript\nimport { z } from \"zod\";\nimport validate from \"express-zod-validations\";\n\napp.put(\n  \"/posts/:id\",\n  validate({\n    params: z.object({ id: z.string().length(24) }),\n    body: z.object({ title: z.string(), content: z.string().min(10) }),\n    headers: z.object({ authorization: z.string() }),\n  }),\n  (req, res) => {\n    // All validated values are available\n    const { params, body, headers } = req.validationValues;\n    res.json({ params, body });\n  },\n);\n```\n\n### Chain Multiple Validators\n\n```typescript\napp.put(\n  \"/posts/:id\",\n  validateHeaders(authSchema),\n  validateParams(idSchema),\n  validateBody(postSchema),\n  postsController.update,\n);\n```\n\n## Configuration\n\n### Global Configuration\n\nSet default behavior for all validations:\n\n```typescript\nimport express from \"express\";\nimport { expressZodValidations } from \"express-zod-validations\";\n\nconst app = express();\n\napp.use(\n  expressZodValidations({\n    throwErrors: true, // Throw errors instead of storing them\n    overwriteRequest: true, // Replace req.body, req.params, etc. with parsed values\n  }),\n);\n```\n\n#### Options\n\n- **`throwErrors`** (default: `false`)\n  When `true`, validation errors are passed to `next(error)`, triggering your Express error handler.\n  When `false`, errors are stored in `req.validationErrors` and execution continues.\n\n- **`overwriteRequest`** (default: `false`)\n  When `true`, replaces `req.body`, `req.params`, etc. with the parsed and transformed values from Zod.\n  When `false`, parsed values are stored in `req.validationValues`.\n\n### Per-Route Validation Options\n\nPass Zod parsing options as a second parameter:\n\n```typescript\nvalidateBody(userSchema, {\n  errorMap: (issue, ctx) => ({\n    message: `Custom error: ${issue.path.join(\".\")}`,\n  }),\n});\n```\n\n## Accessing Validation Results\n\n### Validated Values\n\n```typescript\napp.post(\"/users\", validateBody(userSchema), (req, res) => {\n  // Original request body (untransformed)\n  console.log(req.body);\n\n  // Validated and transformed data\n  console.log(req.validationValues.body);\n});\n```\n\n### Validation Errors\n\nWhen `throwErrors` is `false`, errors are accessible via `req.validationErrors`:\n\n```typescript\napp.post(\"/users\", validateBody(userSchema), (req, res) => {\n  if (req.validationErrors?.body) {\n    return res.status(400).json({\n      error: \"Validation failed\",\n      issues: req.validationErrors.body.errors,\n    });\n  }\n\n  // Process valid data\n  res.json(req.validationValues.body);\n});\n```\n\n## TypeScript Support\n\nThe middleware extends the Express `Request` type:\n\n```typescript\nimport { ValidationRequest } from \"express-zod-validations\";\n\napp.post(\"/users\", validateBody(userSchema), (req: ValidationRequest, res) => {\n  // TypeScript knows about validationValues and validationErrors\n  req.validationValues.body;\n  req.validationErrors?.body;\n});\n```\n\n## Error Handling\n\n### Option 1: Store Errors (Default)\n\n```typescript\napp.post(\"/users\", validateBody(userSchema), (req, res) => {\n  if (req.validationErrors?.body) {\n    return res.status(400).json({ errors: req.validationErrors.body.errors });\n  }\n  // Handle valid request\n});\n```\n\n### Option 2: Throw Errors\n\n```typescript\n// Enable globally\napp.use(expressZodValidations({ throwErrors: true }));\n\n// Add error handler\napp.use((err, req, res, next) => {\n  if (err.name === \"ZodError\") {\n    return res.status(400).json({ errors: err.errors });\n  }\n  next(err);\n});\n```\n\n## Advanced Examples\n\n### Query String Coercion\n\nQuery parameters are always strings. Use `z.coerce` for automatic type conversion:\n\n```typescript\nconst paginationSchema = z.object({\n  page: z.coerce.number().int().min(1).default(1),\n  limit: z.coerce.number().int().min(1).max(100).default(20),\n  sort: z.enum([\"asc\", \"desc\"]).default(\"asc\"),\n});\n\napp.get(\"/posts\", validateQuery(paginationSchema), (req, res) => {\n  const { page, limit, sort } = req.validationValues.query;\n  // page and limit are numbers, not strings\n});\n```\n\n### Transform and Sanitize Data\n\n```typescript\nconst createUserSchema = z.object({\n  email: z.email().toLowerCase(),\n  name: z.string().trim().min(2),\n  bio: z\n    .string()\n    .trim()\n    .optional()\n    .transform((val) => val || null),\n});\n\napp.post(\"/users\", validateBody(createUserSchema), (req, res) => {\n  // Email is lowercased, name is trimmed, empty bio becomes null\n  const user = req.validationValues.body;\n});\n```\n\n### Allow Unknown Fields\n\nBy default, Zod strips unknown properties. To change this:\n\n```typescript\n// Allow extra fields\nconst schema = z.object({ name: z.string() }).passthrough();\n\n// Strict mode - error on extra fields\nconst strictSchema = z.object({ name: z.string() }).strict();\n```\n\n## API Reference\n\n### Functions\n\n- `validate(props, options?)` - Validate multiple request parts\n- `validateBody(schema, options?)` - Validate request body\n- `validateParams(schema, options?)` - Validate URL parameters\n- `validateQuery(schema, options?)` - Validate query string\n- `validateHeaders(schema, options?)` - Validate headers\n- `expressZodValidations(config)` - Set global configuration\n\n### Types\n\n- `ValidationRequest` - Extended Express Request with validation fields\n- `ValidationConfigs` - Configuration options type\n- `ValidationErrors` - Validation errors object type\n- `ValidationValues` - Validated values object type\n\n## License\n\nMIT\n","readmeFilename":"README.md"}