express-zod-safe 3.2.0 → 3.2.1

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/cjs/index.cjs ADDED
@@ -0,0 +1,9 @@
1
+ const mod = require('../dist/index.js');
2
+ const validate = mod.default || mod;
3
+
4
+ module.exports = validate;
5
+ module.exports.default = validate;
6
+ module.exports.DEFAULT_OPTIONS = mod.DEFAULT_OPTIONS;
7
+ module.exports.defaultErrorHandler = mod.defaultErrorHandler;
8
+ module.exports.setGlobalErrorHandler = mod.setGlobalErrorHandler;
9
+ module.exports.setGlobalOptions = mod.setGlobalOptions;
package/dist/index.cjs ADDED
@@ -0,0 +1,9 @@
1
+ const mod = require('../dist/index.js');
2
+ const validate = mod.default || mod;
3
+
4
+ module.exports = validate;
5
+ module.exports.default = validate;
6
+ module.exports.DEFAULT_OPTIONS = mod.DEFAULT_OPTIONS;
7
+ module.exports.defaultErrorHandler = mod.defaultErrorHandler;
8
+ module.exports.setGlobalErrorHandler = mod.setGlobalErrorHandler;
9
+ module.exports.setGlobalOptions = mod.setGlobalOptions;
package/dist/index.js CHANGED
@@ -1,6 +1,44 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/index.ts
2
- var _express = require('express'); var _express2 = _interopRequireDefault(_express);
3
- var _zod = require('zod');
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ DEFAULT_OPTIONS: () => DEFAULT_OPTIONS,
34
+ default: () => validate,
35
+ defaultErrorHandler: () => defaultErrorHandler,
36
+ setGlobalErrorHandler: () => setGlobalErrorHandler,
37
+ setGlobalOptions: () => setGlobalOptions
38
+ });
39
+ module.exports = __toCommonJS(index_exports);
40
+ var import_express = __toESM(require("express"));
41
+ var import_zod = require("zod");
4
42
  var types = ["query", "params", "body"];
5
43
  var defaultErrorHandler = (errors, _req, res) => {
6
44
  res.status(400).send(errors.map((error) => ({ type: error.type, errors: error.errors.issues })));
@@ -17,12 +55,12 @@ var setGlobalOptions = (newOptions) => {
17
55
  function isZodType(schema) {
18
56
  return !!schema && typeof schema.safeParseAsync === "function";
19
57
  }
20
- var descriptor = Object.getOwnPropertyDescriptor(_express2.default.request, "query");
58
+ var descriptor = Object.getOwnPropertyDescriptor(import_express.default.request, "query");
21
59
  if (descriptor) {
22
- Object.defineProperty(_express2.default.request, "query", {
60
+ Object.defineProperty(import_express.default.request, "query", {
23
61
  get() {
24
62
  if (Object.hasOwn(this, "_query")) return this._query;
25
- return _optionalChain([descriptor, 'optionalAccess', _ => _.get, 'optionalAccess', _2 => _2.call, 'call', _3 => _3(this)]);
63
+ return descriptor?.get?.call(this);
26
64
  },
27
65
  set(query) {
28
66
  this._query = query;
@@ -32,8 +70,8 @@ if (descriptor) {
32
70
  });
33
71
  }
34
72
  function validate(schemas) {
35
- const zodObject = options.defaultSchemaObject === "strict" ? _zod.z.strictObject : _zod.z.object;
36
- const missingSchemaHandler = options.missingSchemaBehavior === "empty" ? zodObject({}) : _zod.z.any();
73
+ const zodObject = options.defaultSchemaObject === "strict" ? import_zod.z.strictObject : import_zod.z.object;
74
+ const missingSchemaHandler = options.missingSchemaBehavior === "empty" ? zodObject({}) : import_zod.z.any();
37
75
  const validation = {
38
76
  params: missingSchemaHandler,
39
77
  query: missingSchemaHandler,
@@ -47,12 +85,12 @@ function validate(schemas) {
47
85
  return async (req, res, next) => {
48
86
  const errors = [];
49
87
  for (const type of types) {
50
- const parsed = await validation[type].safeParseAsync(_nullishCoalesce(req[type], () => ( {})));
88
+ const parsed = await validation[type].safeParseAsync(req[type] ?? {});
51
89
  if (parsed.success) req[type] = parsed.data;
52
90
  else errors.push({ type, errors: parsed.error });
53
91
  }
54
92
  if (errors.length > 0) {
55
- const handler = _nullishCoalesce(schemas.handler, () => ( options.handler));
93
+ const handler = schemas.handler ?? options.handler;
56
94
  return handler(errors, req, res, next);
57
95
  }
58
96
  return next();
@@ -61,11 +99,11 @@ function validate(schemas) {
61
99
  function setGlobalErrorHandler(handler) {
62
100
  options.handler = handler;
63
101
  }
64
-
65
-
66
-
67
-
68
-
69
-
70
- exports.DEFAULT_OPTIONS = DEFAULT_OPTIONS; exports.default = validate; exports.defaultErrorHandler = defaultErrorHandler; exports.setGlobalErrorHandler = setGlobalErrorHandler; exports.setGlobalOptions = setGlobalOptions;
102
+ // Annotate the CommonJS export names for ESM import in node:
103
+ 0 && (module.exports = {
104
+ DEFAULT_OPTIONS,
105
+ defaultErrorHandler,
106
+ setGlobalErrorHandler,
107
+ setGlobalOptions
108
+ });
71
109
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["c:\\Users\\angus\\Documents\\Development\\express-zod-safe\\dist\\index.js"],"names":[],"mappings":"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","file":"C:\\Users\\angus\\Documents\\Development\\express-zod-safe\\dist\\index.js","sourcesContent":[null]}
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 ZodType, z } from 'zod';\n\nconst types = ['query', 'params', 'body'] as const;\n\nexport const defaultErrorHandler: ErrorRequestHandler = (errors, _req, res) => {\n\tres.status(400).send(errors.map(error => ({ type: error.type, errors: error.errors.issues })));\n};\n\nexport interface ValidateRequestGlobalOptions {\n\t/**\n\t * The error handler to use for all routes if no handler is provided in the schema.\n\t */\n\thandler: ErrorRequestHandler;\n\t/**\n\t * The default schema object type to use for validation when a plain object is provided.\n\t *\n\t * When using `validate({ query: { a: z.string() } })`:\n\t * - `'strict'` (default): Uses `z.strictObject`, which rejects extra properties.\n\t * For example, `GET /?a=1&b=2` will fail validation.\n\t * - `'lax'`: Uses `z.object`, which allows extra properties.\n\t * For example, `GET /?a=1&b=2` will succeed, and `req.query` will only contain `{ a: '1' }`.\n\t *\n\t * Note: If you pass a Zod object directly (e.g., `validate({ query: z.object({ a: z.string() }) })`),\n\t * this option has no effect as the provided Zod object is used as-is.\n\t *\n\t * @default 'strict'\n\t * @example\n\t * ```ts\n\t * // Allow extra properties in query params\n\t * setGlobalOptions({ defaultSchemaObject: 'lax' });\n\t *\n\t * app.get('/user', validate({ query: { id: z.string() } }), (req, res) => {\n\t * \t// GET /user?id=123&extra=value will succeed\n\t * \t// req.query will be { id: '123' }\n\t * });\n\t * ```\n\t */\n\tdefaultSchemaObject: 'strict' | 'lax';\n\t/**\n\t * The behavior when a schema is not provided for a particular input type (params, query, or body).\n\t *\n\t * - `'empty'` (default): Validates against an empty strict object (`z.strictObject({})`), which rejects any input.\n\t * - `'any'`: Skips validation entirely for that input type, allowing any data to pass through.\n\t * This is useful when using nested routers where different parts of the route validate different inputs.\n\t *\n\t * @default 'empty'\n\t */\n\tmissingSchemaBehavior: 'empty' | 'any';\n}\n\n/**\n * The default global options for request validation.\n *\n * Default values:\n * - `defaultSchemaObject: 'strict'`\n * - `missingSchemaBehavior: 'empty'`\n * - `handler`: The default error handler sends a 400 status with an array of validation errors (see: {@link defaultErrorHandler}):\n * ```ts\n * (errors, _req, res) => {\n * \tres.status(400).send(errors.map(error => ({ type: error.type, errors: error.errors.issues })));\n * }\n * ```\n */\nexport const DEFAULT_OPTIONS: ValidateRequestGlobalOptions = {\n\thandler: defaultErrorHandler,\n\tdefaultSchemaObject: 'strict',\n\tmissingSchemaBehavior: 'empty'\n};\n\n/**\n * The options object used by the validation middleware.\n * Initialised with {@link DEFAULT_OPTIONS} and can be modified using {@link setGlobalOptions}.\n */\nconst options: ValidateRequestGlobalOptions = DEFAULT_OPTIONS;\n\n/**\n * Sets the global {@link options} for request validation.\n *\n * @param newOptions Partial options to merge with the current global options.\n * @example\n * // Change the error handler\n * setGlobalOptions({\n * \thandler: (errors, req, res) => {\n * \t\tres.status(422).json({ validationErrors: errors });\n * \t}\n * });\n *\n * // Change default schema object type\n * setGlobalOptions({ defaultSchemaObject: 'lax' });\n *\n * // Change missing schema behavior\n * setGlobalOptions({ missingSchemaBehavior: 'any' });\n *\n * // Change all options\n * setGlobalOptions({\n * \thandler: customHandler,\n * \tdefaultSchemaObject: 'lax',\n * \tmissingSchemaBehavior: 'any'\n * });\n */\nexport const setGlobalOptions = (newOptions: Partial<ValidateRequestGlobalOptions>) => {\n\tObject.assign(options, newOptions);\n};\n\n/**\n * A ZodType type guard.\n * @param schema The Zod schema to check.\n * @returns Whether the provided schema is a ZodType.\n */\nfunction isZodType(schema: unknown): schema is ZodType {\n\treturn !!schema && typeof (schema as ZodType).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 * **Missing Schema Behavior**: If a schema is not provided for a particular input type (params, query, or body),\n * the behavior is controlled by the {@link ValidateRequestGlobalOptions.missingSchemaBehavior} option:\n * - `'empty'` (default): Validates against an empty strict object, rejecting any input\n * - `'any'`: Skips validation entirely, allowing any data to pass through\n *\n * This allows you to validate only the parts of the request you care about when using nested routers.\n *\n * @param schemas - An object containing Zod schemas for params, query, and body. All fields are optional.\n * If a field is omitted, behavior depends on {@link ValidateRequestGlobalOptions.missingSchemaBehavior}.\n * 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 * app.use(express.json());\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 * // Only validate params, allow any query or body\n * setGlobalOptions({ missingSchemaBehavior: 'any' });\n * app.use('/:id', validate({ params: { id: z.string().uuid() } }), nestedRouter);\n *\n * app.listen(3000, () => console.log('Server running on port 3000'));\n */\nexport default function validate<TParams extends ValidationSchema, TQuery extends ValidationSchema, TBody extends ValidationSchema>(\n\tschemas: CompleteValidationSchema<TParams, TQuery, TBody>\n): RequestHandler<ZodOutput<TParams>, any, ZodOutput<TBody>, ZodOutput<TQuery>> {\n\t// Set validation objects for each type\n\tconst zodObject = options.defaultSchemaObject === 'strict' ? z.strictObject : z.object;\n\n\t// Initialise validation objects for each type\n\tconst missingSchemaHandler = options.missingSchemaBehavior === 'empty' ? zodObject({}) : z.any();\n\tconst validation: Record<DataType, ZodType> = {\n\t\tparams: missingSchemaHandler,\n\t\tquery: missingSchemaHandler,\n\t\tbody: missingSchemaHandler\n\t};\n\n\tfor (const type of types) {\n\t\tif (schemas[type]) {\n\t\t\tvalidation[type] = isZodType(schemas[type]) ? schemas[type] : zodObject(schemas[type]);\n\t\t}\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\t// biome-ignore lint/suspicious/noExplicitAny: type specified in function signature\n\t\t\tif (parsed.success) req[type] = parsed.data as any;\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\tconst handler = schemas.handler ?? options.handler;\n\t\t\treturn handler(errors, req, res, next);\n\t\t}\n\n\t\treturn next();\n\t};\n}\n\n/**\n * Sets the global error handler for all routes.\n * @param handler The error handler to set.\n * @deprecated Use {@link setGlobalOptions} instead.\n */\nexport function setGlobalErrorHandler(handler: ErrorRequestHandler): void {\n\toptions.handler = handler;\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\nexport type Unvalidated = unknown;\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 = Unvalidated,\n\tResBody = any,\n\tReqBody = Unvalidated,\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 = ZodType | 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 = ValidationSchema,\n\tTQuery extends ValidationSchema = ValidationSchema,\n\tTBody extends ValidationSchema = ValidationSchema\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 | undefined> = T extends ValidationSchema\n\t? z.output<T extends ZodRawShape ? z.ZodObject<T> : T>\n\t: Unvalidated;\n\n/**\n * A utility type to ensure other middleware types don't conflict with the validate middleware.\n */\nexport type WeakRequestHandler = RequestHandler<Unvalidated, Unvalidated, Unvalidated, Unvalidated>;\n\n/**\n * A utility type to ensure the Request is typed correctly.\n * @template T - The validation schema to be applied to the request params, query and body.\n * @example\n * import { ValidatedRequest } from 'express-zod-safe';\n * import { z } from 'zod';\n *\n * const schema = {\n * \tquery: {\n * \t\tname: z.string().min(3).max(10),\n * \t\tage: z.coerce.number().min(18)\n * \t},\n * \tbody: {\n * \t\ttitle: z.string().max(4)\n * \t},\n * \tparams: {\n * \t\tid: z.coerce.number()\n * \t}\n * };\n *\n * const requestHandler = (req: ValidatedRequest<typeof schema>, res: Response) => {\n * \tconst { name, age } = req.query;\n * \tconst { id } = req.params;\n * const { title } = req.body;\n *\n * \tres.send(`Hello ${title} ${name}! (Your age is ${age} and your ID is ${id})`);\n * };\n *\n * app.post('/handler/:id', validate(schema), requestHandler);\n */\nexport type ValidatedRequest<T extends CompleteValidationSchema> = Request<\n\tZodOutput<T['params']>,\n\tany,\n\tZodOutput<T['body']>,\n\tZodOutput<T['query']>\n>;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,qBAAoB;AACpB,iBAAiE;AAEjE,IAAM,QAAQ,CAAC,SAAS,UAAU,MAAM;AAEjC,IAAM,sBAA2C,CAAC,QAAQ,MAAM,QAAQ;AAC9E,MAAI,OAAO,GAAG,EAAE,KAAK,OAAO,IAAI,YAAU,EAAE,MAAM,MAAM,MAAM,QAAQ,MAAM,OAAO,OAAO,EAAE,CAAC;AAC9F;AAyDO,IAAM,kBAAgD;AAAA,EAC5D,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,uBAAuB;AACxB;AAMA,IAAM,UAAwC;AA2BvC,IAAM,mBAAmB,CAAC,eAAsD;AACtF,SAAO,OAAO,SAAS,UAAU;AAClC;AAOA,SAAS,UAAU,QAAoC;AACtD,SAAO,CAAC,CAAC,UAAU,OAAQ,OAAmB,mBAAmB;AAClE;AAGA,IAAM,aAAa,OAAO,yBAAyB,eAAAA,QAAQ,SAAS,OAAO;AAC3E,IAAI,YAAY;AACf,SAAO,eAAe,eAAAA,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;AAsDe,SAAR,SACN,SAC+E;AAE/E,QAAM,YAAY,QAAQ,wBAAwB,WAAW,aAAE,eAAe,aAAE;AAGhF,QAAM,uBAAuB,QAAQ,0BAA0B,UAAU,UAAU,CAAC,CAAC,IAAI,aAAE,IAAI;AAC/F,QAAM,aAAwC;AAAA,IAC7C,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACP;AAEA,aAAW,QAAQ,OAAO;AACzB,QAAI,QAAQ,IAAI,GAAG;AAClB,iBAAW,IAAI,IAAI,UAAU,QAAQ,IAAI,CAAC,IAAI,QAAQ,IAAI,IAAI,UAAU,QAAQ,IAAI,CAAC;AAAA,IACtF;AAAA,EACD;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;AAEpE,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,YAAM,UAAU,QAAQ,WAAW,QAAQ;AAC3C,aAAO,QAAQ,QAAQ,KAAK,KAAK,IAAI;AAAA,IACtC;AAEA,WAAO,KAAK;AAAA,EACb;AACD;AAOO,SAAS,sBAAsB,SAAoC;AACzE,UAAQ,UAAU;AACnB;","names":["express"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "express-zod-safe",
3
- "version": "3.2.0",
3
+ "version": "3.2.1",
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",
@@ -13,12 +13,12 @@
13
13
  },
14
14
  "require": {
15
15
  "types": "./dist/index.d.ts",
16
- "default": "./dist/index.js"
16
+ "default": "./dist/index.cjs"
17
17
  }
18
18
  }
19
19
  },
20
20
  "scripts": {
21
- "build": "tsup",
21
+ "build": "tsup && node postbuild.js",
22
22
  "lint": "biome check --fix",
23
23
  "test": "node --import=tsx --test test/index.test.ts && tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
24
24
  "test:debug": "node --import=tsx --test --inspect-brk test/index.test.ts"
@@ -49,6 +49,7 @@
49
49
  "@angablue/biome-config": "^1.1.1",
50
50
  "@biomejs/biome": "^2.3.11",
51
51
  "@types/node": "^25.0.8",
52
+ "node-mocks-http": "^1.17.2",
52
53
  "tsup": "^8.5.1",
53
54
  "tsx": "^4.21.0",
54
55
  "typescript": "^5.9.3",