express-zod-safe 1.5.3 → 1.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ var descriptor = Object.getOwnPropertyDescriptor(_express2.default.request, "que
10
10
  if (descriptor) {
11
11
  Object.defineProperty(_express2.default.request, "query", {
12
12
  get() {
13
- if (this._query) return this._query;
13
+ if (Object.hasOwn(this, "_query")) return this._query;
14
14
  return _optionalChain([descriptor, 'optionalAccess', _ => _.get, 'optionalAccess', _2 => _2.call, 'call', _3 => _3(this)]);
15
15
  },
16
16
  set(query) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/express-zod-safe/express-zod-safe/dist/index.js","../src/index.ts"],"names":[],"mappings":"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","file":"/home/runner/work/express-zod-safe/express-zod-safe/dist/index.js","sourcesContent":[null,"/// <reference types=\"./express.d.ts\" />\nimport type { NextFunction, Request, RequestHandler, Response } from 'express';\nimport express from 'express';\nimport { type ZodError, type ZodRawShape, type ZodSchema, type ZodTypeAny, z } from 'zod';\n\nconst types = ['query', 'params', 'body'] as const;\nconst emptyObjectSchema = z.object({}).strict();\nexport type EmptyValidationSchema = typeof emptyObjectSchema;\n\n/**\n * A ZodSchema type guard.\n * @param schema The Zod schema to check.\n * @returns Whether the provided schema is a ZodSchema.\n */\nfunction isZodSchema(schema: unknown): schema is ZodSchema {\n\treturn !!schema && typeof (schema as ZodSchema).safeParseAsync === 'function';\n}\n\n// Override express@^5 request.query getter to provider setter\nconst descriptor = Object.getOwnPropertyDescriptor(express.request, 'query');\nif (descriptor) {\n\tObject.defineProperty(express.request, 'query', {\n\t\tget(this: Request) {\n\t\t\tif (this._query) return this._query;\n\t\t\treturn descriptor?.get?.call(this);\n\t\t},\n\t\tset(this: Request, query: unknown) {\n\t\t\tthis._query = query;\n\t\t},\n\t\tconfigurable: true,\n\t\tenumerable: true\n\t});\n}\n\n/**\n * Generates a middleware function for Express.js that validates request params, query, and body.\n * This function uses Zod schemas to perform validation against the provided schema definitions.\n *\n * @param schemas - An object containing Zod schemas for params, query, and body. Optional handler for custom error handling.\n * @returns An Express.js middleware function that validates the request based on the provided schemas.\n * It attaches validated data to the request object and sends error details if validation fails.\n * @template TParams - Type definition for params schema.\n * @template TQuery - Type definition for query schema.\n * @template TBody - Type definition for body schema.\n * @example\n * // Example usage in an Express.js route\n * import express from 'express';\n * import validate from 'express-zod-safe';\n * import { z } from 'zod';\n *\n * const app = express();\n *\n * // Define your Zod schemas\n * const params = {\n * userId: z.string().uuid(),\n * };\n * const query = {\n * age: z.coerce.number().optional(),\n * };\n * const body = {\n * name: z.string(),\n * email: z.string().email(),\n * };\n *\n * // Use the validate middleware in your route\n * app.post('/user/:userId', validate({ params, query, body }), (req, res) => {\n * // Your route logic here\n * res.send('User data is valid!');\n * });\n *\n * app.listen(3000, () => console.log('Server running on port 3000'));\n */\nexport default function validate<\n\tTParams extends ValidationSchema = EmptyValidationSchema,\n\tTQuery extends ValidationSchema = EmptyValidationSchema,\n\tTBody extends ValidationSchema = EmptyValidationSchema\n>(schemas: CompleteValidationSchema<TParams, TQuery, TBody>): RequestHandler<ZodOutput<TParams>, any, ZodOutput<TBody>, ZodOutput<TQuery>> {\n\t// Create validation objects for each type\n\tconst validation = {\n\t\tparams: isZodSchema(schemas.params) ? schemas.params : z.object(schemas.params ?? {}).strict(),\n\t\tquery: isZodSchema(schemas.query) ? schemas.query : z.object(schemas.query ?? {}).strict(),\n\t\tbody: isZodSchema(schemas.body) ? schemas.body : z.object(schemas.body ?? {}).strict()\n\t};\n\n\treturn async (req, res, next): Promise<void> => {\n\t\tconst errors: ErrorListItem[] = [];\n\n\t\t// Validate all types (params, query, body)\n\t\tfor (const type of types) {\n\t\t\tconst parsed = await validation[type].safeParseAsync(req[type] ?? {});\n\t\t\tif (parsed.success) req[type] = parsed.data;\n\t\t\telse errors.push({ type, errors: parsed.error });\n\t\t}\n\n\t\t// Return all errors if there are any\n\t\tif (errors.length > 0) {\n\t\t\t// If a custom error handler is provided, use it\n\t\t\tif (schemas.handler) return schemas.handler(errors, req, res, next);\n\n\t\t\tres.status(400).send(errors.map(error => ({ type: error.type, errors: error.errors })));\n\t\t\treturn;\n\t\t}\n\n\t\treturn next();\n\t};\n}\n\n/**\n * Describes the types of data that can be validated: 'query', 'params', or 'body'.\n */\ntype DataType = (typeof types)[number];\n\n/**\n * Defines the structure of an error item, containing the type of validation that failed (params, query, or body)\n * and the associated ZodError.\n */\nexport interface ErrorListItem {\n\ttype: DataType;\n\terrors: ZodError;\n}\n\n/**\n * Represents an Express.js error request handler where the params, query and body are of unknown type as validation failed.\n */\nexport type ErrorRequestHandler<\n\tP = unknown,\n\tResBody = any,\n\tReqBody = unknown,\n\tReqQuery = unknown,\n\tLocalsObj extends Record<string, any> = Record<string, any>\n> = (\n\terr: ErrorListItem[],\n\treq: Request<P, ResBody, ReqBody, ReqQuery, LocalsObj>,\n\tres: Response<ResBody, LocalsObj>,\n\tnext: NextFunction\n) => void | Promise<void>;\n\n/**\n * Represents a generic type for route validation, which can be applied to params, query, or body.\n * Each key-value pair represents a field and its corresponding Zod validation schema.\n */\nexport type ValidationSchema = ZodTypeAny | ZodRawShape;\n\n/**\n * Defines the structure for the schemas provided to the validate middleware.\n * Each property corresponds to a different part of the request (params, query, body)\n * and should be a record of Zod types for validation. Optional handler for custom error handling.\n *\n * @template TParams - Type definition for params schema.\n * @template TQuery - Type definition for query schema.\n * @template TBody - Type definition for body schema.\n */\nexport interface CompleteValidationSchema<\n\tTParams extends ValidationSchema = EmptyValidationSchema,\n\tTQuery extends ValidationSchema = EmptyValidationSchema,\n\tTBody extends ValidationSchema = EmptyValidationSchema\n> {\n\thandler?: ErrorRequestHandler;\n\tparams?: TParams;\n\tquery?: TQuery;\n\tbody?: TBody;\n}\n\n/**\n * Represents the output type of a Zod validation schema.\n * This is used to infer the TypeScript type from a Zod schema,\n * providing typesafe access to the validated data.\n *\n * @template T - The validation type (params, query, or body).\n */\nexport type ZodOutput<T extends ValidationSchema> = T extends ZodRawShape ? z.ZodObject<T>['_output'] : T['_output'];\n\n/**\n * A utility type to ensure other middleware types don't conflict with the validate middleware.\n */\nexport type WeakRequestHandler = RequestHandler<unknown, unknown, unknown, Record<string, unknown>>;\n"]}
1
+ {"version":3,"sources":["/home/runner/work/express-zod-safe/express-zod-safe/dist/index.js","../src/index.ts"],"names":[],"mappings":"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","file":"/home/runner/work/express-zod-safe/express-zod-safe/dist/index.js","sourcesContent":[null,"/// <reference types=\"./express.d.ts\" />\nimport type { NextFunction, Request, RequestHandler, Response } from 'express';\nimport express from 'express';\nimport { type ZodError, type ZodRawShape, type ZodSchema, type ZodTypeAny, z } from 'zod';\n\nconst types = ['query', 'params', 'body'] as const;\nconst emptyObjectSchema = z.object({}).strict();\nexport type EmptyValidationSchema = typeof emptyObjectSchema;\n\n/**\n * A ZodSchema type guard.\n * @param schema The Zod schema to check.\n * @returns Whether the provided schema is a ZodSchema.\n */\nfunction isZodSchema(schema: unknown): schema is ZodSchema {\n\treturn !!schema && typeof (schema as ZodSchema).safeParseAsync === 'function';\n}\n\n// Override express@^5 request.query getter to provider setter\nconst descriptor = Object.getOwnPropertyDescriptor(express.request, 'query');\nif (descriptor) {\n\tObject.defineProperty(express.request, 'query', {\n\t\tget(this: Request) {\n\t\t\tif (Object.hasOwn(this, '_query')) return this._query;\n\t\t\treturn descriptor?.get?.call(this);\n\t\t},\n\t\tset(this: Request, query: unknown) {\n\t\t\tthis._query = query;\n\t\t},\n\t\tconfigurable: true,\n\t\tenumerable: true\n\t});\n}\n\n/**\n * Generates a middleware function for Express.js that validates request params, query, and body.\n * This function uses Zod schemas to perform validation against the provided schema definitions.\n *\n * @param schemas - An object containing Zod schemas for params, query, and body. Optional handler for custom error handling.\n * @returns An Express.js middleware function that validates the request based on the provided schemas.\n * It attaches validated data to the request object and sends error details if validation fails.\n * @template TParams - Type definition for params schema.\n * @template TQuery - Type definition for query schema.\n * @template TBody - Type definition for body schema.\n * @example\n * // Example usage in an Express.js route\n * import express from 'express';\n * import validate from 'express-zod-safe';\n * import { z } from 'zod';\n *\n * const app = express();\n *\n * // Define your Zod schemas\n * const params = {\n * userId: z.string().uuid(),\n * };\n * const query = {\n * age: z.coerce.number().optional(),\n * };\n * const body = {\n * name: z.string(),\n * email: z.string().email(),\n * };\n *\n * // Use the validate middleware in your route\n * app.post('/user/:userId', validate({ params, query, body }), (req, res) => {\n * // Your route logic here\n * res.send('User data is valid!');\n * });\n *\n * app.listen(3000, () => console.log('Server running on port 3000'));\n */\nexport default function validate<\n\tTParams extends ValidationSchema = EmptyValidationSchema,\n\tTQuery extends ValidationSchema = EmptyValidationSchema,\n\tTBody extends ValidationSchema = EmptyValidationSchema\n>(schemas: CompleteValidationSchema<TParams, TQuery, TBody>): RequestHandler<ZodOutput<TParams>, any, ZodOutput<TBody>, ZodOutput<TQuery>> {\n\t// Create validation objects for each type\n\tconst validation = {\n\t\tparams: isZodSchema(schemas.params) ? schemas.params : z.object(schemas.params ?? {}).strict(),\n\t\tquery: isZodSchema(schemas.query) ? schemas.query : z.object(schemas.query ?? {}).strict(),\n\t\tbody: isZodSchema(schemas.body) ? schemas.body : z.object(schemas.body ?? {}).strict()\n\t};\n\n\treturn async (req, res, next): Promise<void> => {\n\t\tconst errors: ErrorListItem[] = [];\n\n\t\t// Validate all types (params, query, body)\n\t\tfor (const type of types) {\n\t\t\tconst parsed = await validation[type].safeParseAsync(req[type] ?? {});\n\t\t\tif (parsed.success) req[type] = parsed.data;\n\t\t\telse errors.push({ type, errors: parsed.error });\n\t\t}\n\n\t\t// Return all errors if there are any\n\t\tif (errors.length > 0) {\n\t\t\t// If a custom error handler is provided, use it\n\t\t\tif (schemas.handler) return schemas.handler(errors, req, res, next);\n\n\t\t\tres.status(400).send(errors.map(error => ({ type: error.type, errors: error.errors })));\n\t\t\treturn;\n\t\t}\n\n\t\treturn next();\n\t};\n}\n\n/**\n * Describes the types of data that can be validated: 'query', 'params', or 'body'.\n */\ntype DataType = (typeof types)[number];\n\n/**\n * Defines the structure of an error item, containing the type of validation that failed (params, query, or body)\n * and the associated ZodError.\n */\nexport interface ErrorListItem {\n\ttype: DataType;\n\terrors: ZodError;\n}\n\n/**\n * Represents an Express.js error request handler where the params, query and body are of unknown type as validation failed.\n */\nexport type ErrorRequestHandler<\n\tP = unknown,\n\tResBody = any,\n\tReqBody = unknown,\n\tReqQuery = unknown,\n\tLocalsObj extends Record<string, any> = Record<string, any>\n> = (\n\terr: ErrorListItem[],\n\treq: Request<P, ResBody, ReqBody, ReqQuery, LocalsObj>,\n\tres: Response<ResBody, LocalsObj>,\n\tnext: NextFunction\n) => void | Promise<void>;\n\n/**\n * Represents a generic type for route validation, which can be applied to params, query, or body.\n * Each key-value pair represents a field and its corresponding Zod validation schema.\n */\nexport type ValidationSchema = ZodTypeAny | ZodRawShape;\n\n/**\n * Defines the structure for the schemas provided to the validate middleware.\n * Each property corresponds to a different part of the request (params, query, body)\n * and should be a record of Zod types for validation. Optional handler for custom error handling.\n *\n * @template TParams - Type definition for params schema.\n * @template TQuery - Type definition for query schema.\n * @template TBody - Type definition for body schema.\n */\nexport interface CompleteValidationSchema<\n\tTParams extends ValidationSchema = EmptyValidationSchema,\n\tTQuery extends ValidationSchema = EmptyValidationSchema,\n\tTBody extends ValidationSchema = EmptyValidationSchema\n> {\n\thandler?: ErrorRequestHandler;\n\tparams?: TParams;\n\tquery?: TQuery;\n\tbody?: TBody;\n}\n\n/**\n * Represents the output type of a Zod validation schema.\n * This is used to infer the TypeScript type from a Zod schema,\n * providing typesafe access to the validated data.\n *\n * @template T - The validation type (params, query, or body).\n */\nexport type ZodOutput<T extends ValidationSchema> = T extends ZodRawShape ? z.ZodObject<T>['_output'] : T['_output'];\n\n/**\n * A utility type to ensure other middleware types don't conflict with the validate middleware.\n */\nexport type WeakRequestHandler = RequestHandler<unknown, unknown, unknown, Record<string, unknown>>;\n"]}
package/dist/index.mjs CHANGED
@@ -10,7 +10,7 @@ var descriptor = Object.getOwnPropertyDescriptor(express.request, "query");
10
10
  if (descriptor) {
11
11
  Object.defineProperty(express.request, "query", {
12
12
  get() {
13
- if (this._query) return this._query;
13
+ if (Object.hasOwn(this, "_query")) return this._query;
14
14
  return descriptor?.get?.call(this);
15
15
  },
16
16
  set(query) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/// <reference types=\"./express.d.ts\" />\nimport type { NextFunction, Request, RequestHandler, Response } from 'express';\nimport express from 'express';\nimport { type ZodError, type ZodRawShape, type ZodSchema, type ZodTypeAny, z } from 'zod';\n\nconst types = ['query', 'params', 'body'] as const;\nconst emptyObjectSchema = z.object({}).strict();\nexport type EmptyValidationSchema = typeof emptyObjectSchema;\n\n/**\n * A ZodSchema type guard.\n * @param schema The Zod schema to check.\n * @returns Whether the provided schema is a ZodSchema.\n */\nfunction isZodSchema(schema: unknown): schema is ZodSchema {\n\treturn !!schema && typeof (schema as ZodSchema).safeParseAsync === 'function';\n}\n\n// Override express@^5 request.query getter to provider setter\nconst descriptor = Object.getOwnPropertyDescriptor(express.request, 'query');\nif (descriptor) {\n\tObject.defineProperty(express.request, 'query', {\n\t\tget(this: Request) {\n\t\t\tif (this._query) return this._query;\n\t\t\treturn descriptor?.get?.call(this);\n\t\t},\n\t\tset(this: Request, query: unknown) {\n\t\t\tthis._query = query;\n\t\t},\n\t\tconfigurable: true,\n\t\tenumerable: true\n\t});\n}\n\n/**\n * Generates a middleware function for Express.js that validates request params, query, and body.\n * This function uses Zod schemas to perform validation against the provided schema definitions.\n *\n * @param schemas - An object containing Zod schemas for params, query, and body. Optional handler for custom error handling.\n * @returns An Express.js middleware function that validates the request based on the provided schemas.\n * It attaches validated data to the request object and sends error details if validation fails.\n * @template TParams - Type definition for params schema.\n * @template TQuery - Type definition for query schema.\n * @template TBody - Type definition for body schema.\n * @example\n * // Example usage in an Express.js route\n * import express from 'express';\n * import validate from 'express-zod-safe';\n * import { z } from 'zod';\n *\n * const app = express();\n *\n * // Define your Zod schemas\n * const params = {\n * userId: z.string().uuid(),\n * };\n * const query = {\n * age: z.coerce.number().optional(),\n * };\n * const body = {\n * name: z.string(),\n * email: z.string().email(),\n * };\n *\n * // Use the validate middleware in your route\n * app.post('/user/:userId', validate({ params, query, body }), (req, res) => {\n * // Your route logic here\n * res.send('User data is valid!');\n * });\n *\n * app.listen(3000, () => console.log('Server running on port 3000'));\n */\nexport default function validate<\n\tTParams extends ValidationSchema = EmptyValidationSchema,\n\tTQuery extends ValidationSchema = EmptyValidationSchema,\n\tTBody extends ValidationSchema = EmptyValidationSchema\n>(schemas: CompleteValidationSchema<TParams, TQuery, TBody>): RequestHandler<ZodOutput<TParams>, any, ZodOutput<TBody>, ZodOutput<TQuery>> {\n\t// Create validation objects for each type\n\tconst validation = {\n\t\tparams: isZodSchema(schemas.params) ? schemas.params : z.object(schemas.params ?? {}).strict(),\n\t\tquery: isZodSchema(schemas.query) ? schemas.query : z.object(schemas.query ?? {}).strict(),\n\t\tbody: isZodSchema(schemas.body) ? schemas.body : z.object(schemas.body ?? {}).strict()\n\t};\n\n\treturn async (req, res, next): Promise<void> => {\n\t\tconst errors: ErrorListItem[] = [];\n\n\t\t// Validate all types (params, query, body)\n\t\tfor (const type of types) {\n\t\t\tconst parsed = await validation[type].safeParseAsync(req[type] ?? {});\n\t\t\tif (parsed.success) req[type] = parsed.data;\n\t\t\telse errors.push({ type, errors: parsed.error });\n\t\t}\n\n\t\t// Return all errors if there are any\n\t\tif (errors.length > 0) {\n\t\t\t// If a custom error handler is provided, use it\n\t\t\tif (schemas.handler) return schemas.handler(errors, req, res, next);\n\n\t\t\tres.status(400).send(errors.map(error => ({ type: error.type, errors: error.errors })));\n\t\t\treturn;\n\t\t}\n\n\t\treturn next();\n\t};\n}\n\n/**\n * Describes the types of data that can be validated: 'query', 'params', or 'body'.\n */\ntype DataType = (typeof types)[number];\n\n/**\n * Defines the structure of an error item, containing the type of validation that failed (params, query, or body)\n * and the associated ZodError.\n */\nexport interface ErrorListItem {\n\ttype: DataType;\n\terrors: ZodError;\n}\n\n/**\n * Represents an Express.js error request handler where the params, query and body are of unknown type as validation failed.\n */\nexport type ErrorRequestHandler<\n\tP = unknown,\n\tResBody = any,\n\tReqBody = unknown,\n\tReqQuery = unknown,\n\tLocalsObj extends Record<string, any> = Record<string, any>\n> = (\n\terr: ErrorListItem[],\n\treq: Request<P, ResBody, ReqBody, ReqQuery, LocalsObj>,\n\tres: Response<ResBody, LocalsObj>,\n\tnext: NextFunction\n) => void | Promise<void>;\n\n/**\n * Represents a generic type for route validation, which can be applied to params, query, or body.\n * Each key-value pair represents a field and its corresponding Zod validation schema.\n */\nexport type ValidationSchema = ZodTypeAny | ZodRawShape;\n\n/**\n * Defines the structure for the schemas provided to the validate middleware.\n * Each property corresponds to a different part of the request (params, query, body)\n * and should be a record of Zod types for validation. Optional handler for custom error handling.\n *\n * @template TParams - Type definition for params schema.\n * @template TQuery - Type definition for query schema.\n * @template TBody - Type definition for body schema.\n */\nexport interface CompleteValidationSchema<\n\tTParams extends ValidationSchema = EmptyValidationSchema,\n\tTQuery extends ValidationSchema = EmptyValidationSchema,\n\tTBody extends ValidationSchema = EmptyValidationSchema\n> {\n\thandler?: ErrorRequestHandler;\n\tparams?: TParams;\n\tquery?: TQuery;\n\tbody?: TBody;\n}\n\n/**\n * Represents the output type of a Zod validation schema.\n * This is used to infer the TypeScript type from a Zod schema,\n * providing typesafe access to the validated data.\n *\n * @template T - The validation type (params, query, or body).\n */\nexport type ZodOutput<T extends ValidationSchema> = T extends ZodRawShape ? z.ZodObject<T>['_output'] : T['_output'];\n\n/**\n * A utility type to ensure other middleware types don't conflict with the validate middleware.\n */\nexport type WeakRequestHandler = RequestHandler<unknown, unknown, unknown, Record<string, unknown>>;\n"],"mappings":";AAEA,OAAO,aAAa;AACpB,SAA2E,SAAS;AAEpF,IAAM,QAAQ,CAAC,SAAS,UAAU,MAAM;AACxC,IAAM,oBAAoB,EAAE,OAAO,CAAC,CAAC,EAAE,OAAO;AAQ9C,SAAS,YAAY,QAAsC;AAC1D,SAAO,CAAC,CAAC,UAAU,OAAQ,OAAqB,mBAAmB;AACpE;AAGA,IAAM,aAAa,OAAO,yBAAyB,QAAQ,SAAS,OAAO;AAC3E,IAAI,YAAY;AACf,SAAO,eAAe,QAAQ,SAAS,SAAS;AAAA,IAC/C,MAAmB;AAClB,UAAI,KAAK,OAAQ,QAAO,KAAK;AAC7B,aAAO,YAAY,KAAK,KAAK,IAAI;AAAA,IAClC;AAAA,IACA,IAAmB,OAAgB;AAClC,WAAK,SAAS;AAAA,IACf;AAAA,IACA,cAAc;AAAA,IACd,YAAY;AAAA,EACb,CAAC;AACF;AAwCe,SAAR,SAIL,SAAyI;AAE1I,QAAM,aAAa;AAAA,IAClB,QAAQ,YAAY,QAAQ,MAAM,IAAI,QAAQ,SAAS,EAAE,OAAO,QAAQ,UAAU,CAAC,CAAC,EAAE,OAAO;AAAA,IAC7F,OAAO,YAAY,QAAQ,KAAK,IAAI,QAAQ,QAAQ,EAAE,OAAO,QAAQ,SAAS,CAAC,CAAC,EAAE,OAAO;AAAA,IACzF,MAAM,YAAY,QAAQ,IAAI,IAAI,QAAQ,OAAO,EAAE,OAAO,QAAQ,QAAQ,CAAC,CAAC,EAAE,OAAO;AAAA,EACtF;AAEA,SAAO,OAAO,KAAK,KAAK,SAAwB;AAC/C,UAAM,SAA0B,CAAC;AAGjC,eAAW,QAAQ,OAAO;AACzB,YAAM,SAAS,MAAM,WAAW,IAAI,EAAE,eAAe,IAAI,IAAI,KAAK,CAAC,CAAC;AACpE,UAAI,OAAO,QAAS,KAAI,IAAI,IAAI,OAAO;AAAA,UAClC,QAAO,KAAK,EAAE,MAAM,QAAQ,OAAO,MAAM,CAAC;AAAA,IAChD;AAGA,QAAI,OAAO,SAAS,GAAG;AAEtB,UAAI,QAAQ,QAAS,QAAO,QAAQ,QAAQ,QAAQ,KAAK,KAAK,IAAI;AAElE,UAAI,OAAO,GAAG,EAAE,KAAK,OAAO,IAAI,YAAU,EAAE,MAAM,MAAM,MAAM,QAAQ,MAAM,OAAO,EAAE,CAAC;AACtF;AAAA,IACD;AAEA,WAAO,KAAK;AAAA,EACb;AACD;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/// <reference types=\"./express.d.ts\" />\nimport type { NextFunction, Request, RequestHandler, Response } from 'express';\nimport express from 'express';\nimport { type ZodError, type ZodRawShape, type ZodSchema, type ZodTypeAny, z } from 'zod';\n\nconst types = ['query', 'params', 'body'] as const;\nconst emptyObjectSchema = z.object({}).strict();\nexport type EmptyValidationSchema = typeof emptyObjectSchema;\n\n/**\n * A ZodSchema type guard.\n * @param schema The Zod schema to check.\n * @returns Whether the provided schema is a ZodSchema.\n */\nfunction isZodSchema(schema: unknown): schema is ZodSchema {\n\treturn !!schema && typeof (schema as ZodSchema).safeParseAsync === 'function';\n}\n\n// Override express@^5 request.query getter to provider setter\nconst descriptor = Object.getOwnPropertyDescriptor(express.request, 'query');\nif (descriptor) {\n\tObject.defineProperty(express.request, 'query', {\n\t\tget(this: Request) {\n\t\t\tif (Object.hasOwn(this, '_query')) return this._query;\n\t\t\treturn descriptor?.get?.call(this);\n\t\t},\n\t\tset(this: Request, query: unknown) {\n\t\t\tthis._query = query;\n\t\t},\n\t\tconfigurable: true,\n\t\tenumerable: true\n\t});\n}\n\n/**\n * Generates a middleware function for Express.js that validates request params, query, and body.\n * This function uses Zod schemas to perform validation against the provided schema definitions.\n *\n * @param schemas - An object containing Zod schemas for params, query, and body. Optional handler for custom error handling.\n * @returns An Express.js middleware function that validates the request based on the provided schemas.\n * It attaches validated data to the request object and sends error details if validation fails.\n * @template TParams - Type definition for params schema.\n * @template TQuery - Type definition for query schema.\n * @template TBody - Type definition for body schema.\n * @example\n * // Example usage in an Express.js route\n * import express from 'express';\n * import validate from 'express-zod-safe';\n * import { z } from 'zod';\n *\n * const app = express();\n *\n * // Define your Zod schemas\n * const params = {\n * userId: z.string().uuid(),\n * };\n * const query = {\n * age: z.coerce.number().optional(),\n * };\n * const body = {\n * name: z.string(),\n * email: z.string().email(),\n * };\n *\n * // Use the validate middleware in your route\n * app.post('/user/:userId', validate({ params, query, body }), (req, res) => {\n * // Your route logic here\n * res.send('User data is valid!');\n * });\n *\n * app.listen(3000, () => console.log('Server running on port 3000'));\n */\nexport default function validate<\n\tTParams extends ValidationSchema = EmptyValidationSchema,\n\tTQuery extends ValidationSchema = EmptyValidationSchema,\n\tTBody extends ValidationSchema = EmptyValidationSchema\n>(schemas: CompleteValidationSchema<TParams, TQuery, TBody>): RequestHandler<ZodOutput<TParams>, any, ZodOutput<TBody>, ZodOutput<TQuery>> {\n\t// Create validation objects for each type\n\tconst validation = {\n\t\tparams: isZodSchema(schemas.params) ? schemas.params : z.object(schemas.params ?? {}).strict(),\n\t\tquery: isZodSchema(schemas.query) ? schemas.query : z.object(schemas.query ?? {}).strict(),\n\t\tbody: isZodSchema(schemas.body) ? schemas.body : z.object(schemas.body ?? {}).strict()\n\t};\n\n\treturn async (req, res, next): Promise<void> => {\n\t\tconst errors: ErrorListItem[] = [];\n\n\t\t// Validate all types (params, query, body)\n\t\tfor (const type of types) {\n\t\t\tconst parsed = await validation[type].safeParseAsync(req[type] ?? {});\n\t\t\tif (parsed.success) req[type] = parsed.data;\n\t\t\telse errors.push({ type, errors: parsed.error });\n\t\t}\n\n\t\t// Return all errors if there are any\n\t\tif (errors.length > 0) {\n\t\t\t// If a custom error handler is provided, use it\n\t\t\tif (schemas.handler) return schemas.handler(errors, req, res, next);\n\n\t\t\tres.status(400).send(errors.map(error => ({ type: error.type, errors: error.errors })));\n\t\t\treturn;\n\t\t}\n\n\t\treturn next();\n\t};\n}\n\n/**\n * Describes the types of data that can be validated: 'query', 'params', or 'body'.\n */\ntype DataType = (typeof types)[number];\n\n/**\n * Defines the structure of an error item, containing the type of validation that failed (params, query, or body)\n * and the associated ZodError.\n */\nexport interface ErrorListItem {\n\ttype: DataType;\n\terrors: ZodError;\n}\n\n/**\n * Represents an Express.js error request handler where the params, query and body are of unknown type as validation failed.\n */\nexport type ErrorRequestHandler<\n\tP = unknown,\n\tResBody = any,\n\tReqBody = unknown,\n\tReqQuery = unknown,\n\tLocalsObj extends Record<string, any> = Record<string, any>\n> = (\n\terr: ErrorListItem[],\n\treq: Request<P, ResBody, ReqBody, ReqQuery, LocalsObj>,\n\tres: Response<ResBody, LocalsObj>,\n\tnext: NextFunction\n) => void | Promise<void>;\n\n/**\n * Represents a generic type for route validation, which can be applied to params, query, or body.\n * Each key-value pair represents a field and its corresponding Zod validation schema.\n */\nexport type ValidationSchema = ZodTypeAny | ZodRawShape;\n\n/**\n * Defines the structure for the schemas provided to the validate middleware.\n * Each property corresponds to a different part of the request (params, query, body)\n * and should be a record of Zod types for validation. Optional handler for custom error handling.\n *\n * @template TParams - Type definition for params schema.\n * @template TQuery - Type definition for query schema.\n * @template TBody - Type definition for body schema.\n */\nexport interface CompleteValidationSchema<\n\tTParams extends ValidationSchema = EmptyValidationSchema,\n\tTQuery extends ValidationSchema = EmptyValidationSchema,\n\tTBody extends ValidationSchema = EmptyValidationSchema\n> {\n\thandler?: ErrorRequestHandler;\n\tparams?: TParams;\n\tquery?: TQuery;\n\tbody?: TBody;\n}\n\n/**\n * Represents the output type of a Zod validation schema.\n * This is used to infer the TypeScript type from a Zod schema,\n * providing typesafe access to the validated data.\n *\n * @template T - The validation type (params, query, or body).\n */\nexport type ZodOutput<T extends ValidationSchema> = T extends ZodRawShape ? z.ZodObject<T>['_output'] : T['_output'];\n\n/**\n * A utility type to ensure other middleware types don't conflict with the validate middleware.\n */\nexport type WeakRequestHandler = RequestHandler<unknown, unknown, unknown, Record<string, unknown>>;\n"],"mappings":";AAEA,OAAO,aAAa;AACpB,SAA2E,SAAS;AAEpF,IAAM,QAAQ,CAAC,SAAS,UAAU,MAAM;AACxC,IAAM,oBAAoB,EAAE,OAAO,CAAC,CAAC,EAAE,OAAO;AAQ9C,SAAS,YAAY,QAAsC;AAC1D,SAAO,CAAC,CAAC,UAAU,OAAQ,OAAqB,mBAAmB;AACpE;AAGA,IAAM,aAAa,OAAO,yBAAyB,QAAQ,SAAS,OAAO;AAC3E,IAAI,YAAY;AACf,SAAO,eAAe,QAAQ,SAAS,SAAS;AAAA,IAC/C,MAAmB;AAClB,UAAI,OAAO,OAAO,MAAM,QAAQ,EAAG,QAAO,KAAK;AAC/C,aAAO,YAAY,KAAK,KAAK,IAAI;AAAA,IAClC;AAAA,IACA,IAAmB,OAAgB;AAClC,WAAK,SAAS;AAAA,IACf;AAAA,IACA,cAAc;AAAA,IACd,YAAY;AAAA,EACb,CAAC;AACF;AAwCe,SAAR,SAIL,SAAyI;AAE1I,QAAM,aAAa;AAAA,IAClB,QAAQ,YAAY,QAAQ,MAAM,IAAI,QAAQ,SAAS,EAAE,OAAO,QAAQ,UAAU,CAAC,CAAC,EAAE,OAAO;AAAA,IAC7F,OAAO,YAAY,QAAQ,KAAK,IAAI,QAAQ,QAAQ,EAAE,OAAO,QAAQ,SAAS,CAAC,CAAC,EAAE,OAAO;AAAA,IACzF,MAAM,YAAY,QAAQ,IAAI,IAAI,QAAQ,OAAO,EAAE,OAAO,QAAQ,QAAQ,CAAC,CAAC,EAAE,OAAO;AAAA,EACtF;AAEA,SAAO,OAAO,KAAK,KAAK,SAAwB;AAC/C,UAAM,SAA0B,CAAC;AAGjC,eAAW,QAAQ,OAAO;AACzB,YAAM,SAAS,MAAM,WAAW,IAAI,EAAE,eAAe,IAAI,IAAI,KAAK,CAAC,CAAC;AACpE,UAAI,OAAO,QAAS,KAAI,IAAI,IAAI,OAAO;AAAA,UAClC,QAAO,KAAK,EAAE,MAAM,QAAQ,OAAO,MAAM,CAAC;AAAA,IAChD;AAGA,QAAI,OAAO,SAAS,GAAG;AAEtB,UAAI,QAAQ,QAAS,QAAO,QAAQ,QAAQ,QAAQ,KAAK,KAAK,IAAI;AAElE,UAAI,OAAO,GAAG,EAAE,KAAK,OAAO,IAAI,YAAU,EAAE,MAAM,MAAM,MAAM,QAAQ,MAAM,OAAO,EAAE,CAAC;AACtF;AAAA,IACD;AAEA,WAAO,KAAK;AAAA,EACb;AACD;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "express-zod-safe",
3
- "version": "1.5.3",
3
+ "version": "1.5.4",
4
4
  "description": "TypeScript-friendly middleware designed for Express applications, leveraging the robustness of Zod schemas to validate incoming request bodies, parameters, and queries.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",