@minisylar/express-typed-router 1.5.0 → 1.6.0

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/README.md CHANGED
@@ -1,11 +1,13 @@
1
1
  # @minisylar/express-typed-router
2
2
 
3
- A strongly-typed Express router with Zod validation and automatic type inference for params, body, query, and middleware.
3
+ A strongly-typed Express router with schema validation and automatic type inference for params, body, query, and middleware.
4
4
 
5
5
  ## Features
6
6
 
7
7
  - 🚀 **Full TypeScript support** with automatic type inference for route parameters
8
- - 🛡️ **Zod validation** for request body, query parameters, and route params
8
+ - 🛡️ **Schema validation** for request body, query parameters, and route params (Zod, Yup, Valibot, Arktype,Joi,Effect,decoders,
9
+ ts.data.json,
10
+ unhoax, etc.)
9
11
  - 🔗 **Express.js compatibility** - works with Express 4 and Express 5
10
12
  - 🤝 **Mix with existing Express routes** - seamlessly integrates with your current codebase
11
13
  - 📝 **JSDoc documentation** with comprehensive examples
@@ -22,32 +24,53 @@ pnpm add @minisylar/express-typed-router
22
24
  yarn add @minisylar/express-typed-router
23
25
  ```
24
26
 
25
- > **Note:** This package requires Express 4.18.0+ or Express 5.0.0+ and Zod 3.25.0+
27
+ > **Note:** This package requires Express 4.18.0+ or Express 5.0.0+. For schema validation the library works with multiple popular schema libraries (examples below).
26
28
 
27
- ### Zod Compatibility
29
+ ### Schema Compatibility
28
30
 
29
- This library supports **both Zod 3 and Zod 4** simultaneously! The library follows [Zod's official recommendations for library authors](https://zod.dev/library-authors) and uses versioned imports internally to ensure compatibility with both versions.
31
+ This library is schema-agnostic: it provides a validation plumbing that works with multiple popular schema libraries. Below are short examples showing how you can use different schema libraries with the router. The router expects a schema-like object that can validate input; most adapters are straightforward.
30
32
 
31
- - **Zod v3.25.0+** - Full support
32
- - ✅ **Zod v4** - Full support including Core and Mini packages
33
- - 🔄 **Runtime detection** - Automatically detects and handles both versions
34
-
35
- You can use schemas from either version or mix them in the same application:
33
+ Example with Zod (v3 or v4):
36
34
 
37
35
  ```typescript
38
- // Works with Zod 4
39
- import { z } from "zod/v4";
36
+ import { z } from "zod"; // or "zod/v4" or "zod/v3" as needed
40
37
  const userSchema = z.object({ name: z.string() });
38
+ router.post("/users", { bodySchema: userSchema }, handler);
39
+ ```
41
40
 
42
- // Also works with Zod 3
43
- import * as z4 from "zod/v3";
44
- const postSchema = z4.object({ title: z4.string() });
41
+ Example with Yup:
45
42
 
46
- // Both schemas work seamlessly with the router
43
+ ```javascript
44
+ import * as yup from "yup";
45
+ const userSchema = yup.object({ name: yup.string().required() });
46
+ // pass the yup schema directly as bodySchema; the router will run validation
47
+ router.post("/users", { bodySchema: userSchema }, handler);
48
+ ```
49
+
50
+ Example with Valibot (valibot):
51
+
52
+ ```typescript
53
+ import { object, string } from "valibot";
54
+ const userSchema = object({ name: string() });
47
55
  router.post("/users", { bodySchema: userSchema }, handler);
48
- router.post("/posts", { bodySchema: postSchema }, handler);
49
56
  ```
50
57
 
58
+ Example with Arktype:
59
+
60
+ ```typescript
61
+ import { object, string } from "arktype";
62
+ const userSchema = object({ name: string() });
63
+ router.post("/users", { bodySchema: userSchema }, handler);
64
+ ```
65
+
66
+ If a schema library needs an adapter (for example to map its errors to the router's error format), add a small wrapper that runs validation and throws the expected error shape. See the project's examples for concrete adapter patterns.
67
+
68
+ Note about Joi: Joi's TypeScript typings do not reliably infer the output type from the runtime schema shape. When using Joi you should either:
69
+
70
+ - provide an explicit generic type for the schema (e.g. `Joi.object<MyType>(...)`),
71
+ - add a variable type annotation (e.g. `const s: Joi.ObjectSchema<MyType> = Joi.object(...)`), or
72
+ - write a small adapter that validates at runtime and exposes a typed result to TypeScript.
73
+
51
74
  ## Quick Start
52
75
 
53
76
  ```javascript
@@ -0,0 +1 @@
1
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));const c=s(require(`express`)),l=s(require(`@standard-schema/utils`));function u(e,t){let n=e;if(n&&n[`~standard`]&&typeof n[`~standard`].validate==`function`){let e=n[`~standard`].validate(t);if(e instanceof Promise)throw TypeError(`Async schema validation is not supported by parseSchema`);if(e.issues)throw new l.SchemaError(e.issues);return e.value}throw TypeError(`Unsupported schema shape for parseSchema`)}function d(e,t){let n=e;if(n&&n[`~standard`]&&typeof n[`~standard`].validate==`function`)return n[`~standard`].validate(t);if(n&&typeof n.safeParse==`function`)return n.safeParse(t);if(n&&typeof n.parse==`function`)try{let e=n.parse(t);return{value:e}}catch(e){return{issues:[{message:e?.message??String(e)}]}}if(n&&typeof n.validate==`function`){let e=n.validate(t);return e&&e.then&&typeof e.then==`function`?e.then(e=>e.error?{issues:[{message:e.error.message}]}:e.issues?{issues:e.issues}:{value:e.value??e}):e&&e.error?{issues:[{message:e.error.message}]}:e&&e.issues?{issues:e.issues}:{value:e.value??e}}return{issues:[{message:`Unsupported schema shape`}]}}function f(e){return typeof e==`object`&&!!e&&`issues`in e&&Array.isArray(e.issues)}var p=class{router;constructor(){this.router=c.default.Router()}useMiddleware(e){return this.router.use(e),this}getRouter(){return this.router}get(e,t,n){return this.registerRoute(`get`,e,t,n)}post(e,t,n){return this.registerRoute(`post`,e,t,n)}put(e,t,n){return this.registerRoute(`put`,e,t,n)}patch(e,t,n){return this.registerRoute(`patch`,e,t,n)}delete(e,t,n){return this.registerRoute(`delete`,e,t,n)}options(e,t,n){return this.registerRoute(`options`,e,t,n)}head(e,t,n){return this.registerRoute(`head`,e,t,n)}all(e,t,n){return this.registerRoute(`all`,e,t,n)}registerRoute(e,t,n,r){let i=[];if(typeof n==`object`){let e=n;e.middleware&&i.push(...e.middleware),e.bodySchema&&i.push(this.createBodyValidationMiddleware(e.bodySchema)),e.querySchema&&i.push(this.createQueryValidationMiddleware(e.querySchema)),i.push(r)}else i.push(n);return this.router[e](t,...i),this}createBodyValidationMiddleware(e){return async(t,n,r)=>{try{let i=d(e,t.body),a=i&&typeof i.then==`function`?await i:i;if(a&&`issues`in a&&a.issues){n.status(400).json({error:`Validation failed`,details:a.errors||a.issues});return}t.body=a&&`value`in a?a.value:a,r()}catch(e){f(e)?n.status(400).json({error:`Validation failed`,details:e.errors||e.issues}):r(e)}}}createQueryValidationMiddleware(e){return async(t,n,r)=>{try{let i=d(e,t.query),a=i&&typeof i.then==`function`?await i:i;if(a&&`issues`in a&&a.issues){n.status(400).json({error:`Validation failed`,details:a.errors||a.issues});return}let o=a&&`value`in a?a.value:a;Object.defineProperty(t,`query`,{value:o,writable:!1,enumerable:!0,configurable:!0}),r()}catch(e){f(e)?n.status(400).json({error:`Validation failed`,details:e.errors||e.issues}):r(e)}}}};function m(){return new p}function h(e){let t=new p;return e?.errorHandler&&t.getRouter().use(e.errorHandler),t}function g(...e){let t=new p;for(let n of e)t=t.useMiddleware(n);return t}exports.createTypedRouter=m,exports.createTypedRouterWithConfig=h,exports.createTypedRouterWithMiddleware=g,exports.isSchemaError=f,exports.parseSchema=u,exports.safeParseSchema=d;
@@ -1,25 +1,37 @@
1
1
  import express, { NextFunction, Request, Response } from "express";
2
- import * as z3 from "zod/v3";
3
- import * as z4 from "zod/v4/core";
2
+ import { StandardSchemaV1 } from "@standard-schema/spec";
4
3
 
5
- //#region src/zod-router.d.ts
4
+ //#region src/schema-router.d.ts
6
5
 
7
- type AnyZodType = z3.ZodTypeAny | z4.$ZodType;
8
- declare function isZod4Schema(schema: AnyZodType): schema is z4.$ZodType;
9
- type InferOutput<T> = T extends z4.$ZodType ? z4.output<T> : T extends z3.ZodTypeAny ? z3.output<T> : T extends {
10
- _output: infer O;
11
- } ? O : T extends {
12
- _type: infer O;
13
- } ? O : unknown;
14
- type InferInput<T> = T extends z4.$ZodType ? z4.input<T> : T extends z3.ZodTypeAny ? z3.input<T> : T extends {
15
- _input: infer I;
16
- } ? I : T extends {
17
- _type: infer I;
18
- } ? I : unknown;
19
- declare function parseSchema<T extends AnyZodType>(schema: T, data: unknown): InferOutput<T>;
20
- type SafeParseResult<T extends AnyZodType> = T extends z4.$ZodType ? ReturnType<typeof z4.safeParse<T>> : T extends z3.ZodTypeAny ? z3.SafeParseReturnType<z3.input<T>, z3.output<T>> : never;
21
- declare function safeParseSchema<T extends AnyZodType>(schema: T, data: unknown): SafeParseResult<T>;
22
- declare function isZodError(error: unknown): error is z3.ZodError;
6
+ type AnyStandardSchema = StandardSchemaV1<any, any>;
7
+ type InferOutput<T> = T extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<T> : unknown;
8
+ type InferInput<T> = T extends StandardSchemaV1 ? StandardSchemaV1.InferInput<T> : unknown;
9
+ type InferFromSafeParse<T> = T extends {
10
+ safeParse: (...args: any[]) => infer R;
11
+ } ? R extends {
12
+ success: true;
13
+ data: infer O;
14
+ } ? O : R extends Promise<infer PR> ? PR extends {
15
+ success: true;
16
+ data: infer O;
17
+ } ? O : never : never : T extends {
18
+ parse: (...args: any[]) => infer R;
19
+ } ? R : never;
20
+ type InferSchemaOutput<T> = T extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<T> : InferFromSafeParse<T>;
21
+ declare function parseSchema<T>(schema: T, data: unknown): InferSchemaOutput<T>;
22
+ type SafeParseResult<T> = StandardSchemaV1.Result<InferSchemaOutput<T>> | {
23
+ value: InferSchemaOutput<T>;
24
+ } | {
25
+ issues: any[];
26
+ } | Promise<StandardSchemaV1.Result<InferSchemaOutput<T>> | {
27
+ value: InferSchemaOutput<T>;
28
+ } | {
29
+ issues: any[];
30
+ }>;
31
+ declare function safeParseSchema<T>(schema: T, data: unknown): SafeParseResult<T>;
32
+ declare function isSchemaError(error: unknown): error is {
33
+ issues: any[];
34
+ };
23
35
  /**
24
36
  * Extract route parameters from Express.js route patterns.
25
37
  *
@@ -28,7 +40,7 @@ declare function isZodError(error: unknown): error is z3.ZodError;
28
40
  * - Multiple parameters: /users/:userId/books/:bookId → { userId: string; bookId: string }
29
41
  * - Parameters with separators: /flights/:from-:to → { from: string; to: string }
30
42
  * - Dot notation: /plantae/:genus.:species → { genus: string; species: string }
31
- * - Regex constraints: /user/:id(\\d+) → { id: string }
43
+ * - Regex constraints: /user/:id(\d+) → { id: string }
32
44
  * - Optional parameters: /posts/:year/:month? → { year: string; month?: string }
33
45
  * - Wildcard parameters: /files/* → { "0": string }
34
46
  * - Multiple wildcards: /a/star/b/star → { "0": string; "1": string }
@@ -89,22 +101,22 @@ type RequestOnlyMiddleware<TReq extends Record<string, any>> = TypedMiddleware<T
89
101
  type LocalsOnlyMiddleware<TLocals extends Record<string, any>> = TypedMiddleware<{}, TLocals>;
90
102
  type InferMiddlewareProps<T extends readonly TypedMiddleware<any, any>[]> = T extends readonly [infer First, ...infer Rest] ? First extends TypedMiddleware<infer FirstReq, any> ? Rest extends readonly TypedMiddleware<any, any>[] ? FirstReq & InferMiddlewareProps<Rest> : FirstReq : {} : {};
91
103
  type InferMiddlewareLocals<T extends readonly TypedMiddleware<any, any>[]> = T extends readonly [infer First, ...infer Rest] ? First extends TypedMiddleware<any, infer FirstLocals> ? Rest extends readonly TypedMiddleware<any, any>[] ? FirstLocals & InferMiddlewareLocals<Rest> : FirstLocals : {} : {};
92
- type ZodRequest<Path extends string = string, BodySchema extends AnyZodType | unknown = unknown, QuerySchema extends AnyZodType | unknown = unknown, MiddlewareProps extends Record<string, any> = {}> = Omit<Request, "params" | "query" | "body"> & {
104
+ type SchemaRequest<Path extends string = string, BodySchema extends AnyStandardSchema | unknown = unknown, QuerySchema extends AnyStandardSchema | unknown = unknown, MiddlewareProps extends Record<string, any> = {}> = Omit<Request, "params" | "query" | "body"> & {
93
105
  params: ExtractRouteParams<Path>;
94
- body: BodySchema extends AnyZodType ? InferOutput<BodySchema> : unknown;
95
- query: QuerySchema extends AnyZodType ? InferOutput<QuerySchema> : unknown;
106
+ body: BodySchema extends unknown ? InferSchemaOutput<BodySchema> : unknown;
107
+ query: QuerySchema extends unknown ? InferSchemaOutput<QuerySchema> : unknown;
96
108
  } & MiddlewareProps;
97
- type ZodRouteHandler<Path extends string = string, BodySchema extends AnyZodType | unknown = unknown, QuerySchema extends AnyZodType | unknown = unknown, MiddlewareProps extends Record<string, any> = {}, ResponseLocals extends Record<string, any> = {}> = (req: ZodRequest<Path, BodySchema, QuerySchema, MiddlewareProps>, res: Response<any, ResponseLocals>, next?: NextFunction) => void | undefined | Promise<void | undefined> | Response | Promise<Response> | Promise<Response | undefined>;
109
+ type SchemaRouteHandler<Path extends string = string, BodySchema extends AnyStandardSchema | unknown = unknown, QuerySchema extends AnyStandardSchema | unknown = unknown, MiddlewareProps extends Record<string, any> = {}, ResponseLocals extends Record<string, any> = {}> = (req: SchemaRequest<Path, BodySchema, QuerySchema, MiddlewareProps>, res: Response<any, ResponseLocals>, next?: NextFunction) => void | undefined | Promise<void | undefined> | Response | Promise<Response> | Promise<Response | undefined>;
98
110
  /**
99
111
  * Options for defining a typed route, including schemas and middleware.
100
112
  *
101
- * @template BodySchema - Zod schema for request body validation.
102
- * @template QuerySchema - Zod schema for query parameter validation.
103
- * @property bodySchema - Optional Zod schema for validating the request body.
104
- * @property querySchema - Optional Zod schema for validating the query string.
113
+ * @template BodySchema - Schema for request body validation.
114
+ * @template QuerySchema - Schema for query parameter validation.
115
+ * @property bodySchema - Optional schema for validating the request body.
116
+ * @property querySchema - Optional schema for validating the query string.
105
117
  * @property middleware - Optional array of TypedMiddleware for this route.
106
118
  */
107
- interface RouteOptions<BodySchema extends AnyZodType | unknown = unknown, QuerySchema extends AnyZodType | unknown = unknown> {
119
+ interface RouteOptions<BodySchema extends AnyStandardSchema | unknown = unknown, QuerySchema extends AnyStandardSchema | unknown = unknown> {
108
120
  bodySchema?: BodySchema;
109
121
  querySchema?: QuerySchema;
110
122
  middleware?: TypedMiddleware<any, any>[];
@@ -130,33 +142,33 @@ declare class TypedRouter<RouterMiddlewareProps extends Record<string, any> = {}
130
142
  * Get the underlying Express router
131
143
  */
132
144
  getRouter(): express.Router;
133
- get<Path extends string>(path: Path, handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
134
- get<Path extends string, BodySchema extends AnyZodType | unknown, QuerySchema extends AnyZodType | unknown>(path: Path, options: RouteOptions<BodySchema, QuerySchema>, handler: ZodRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
145
+ get<Path extends string>(path: Path, handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
146
+ get<Path extends string, BodySchema extends AnyStandardSchema | unknown, QuerySchema extends AnyStandardSchema | unknown>(path: Path, options: RouteOptions<BodySchema, QuerySchema>, handler: SchemaRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
135
147
  get<Path extends string, Middleware extends readonly TypedMiddleware<any, any>[]>(path: Path, options: {
136
148
  middleware: Middleware;
137
- }, handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<Middleware>, RouterLocals & InferMiddlewareLocals<Middleware>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
138
- get<Path extends string, BodySchema extends AnyZodType | unknown, QuerySchema extends AnyZodType | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: RouteOptions<BodySchema, QuerySchema> & {
149
+ }, handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<Middleware>, RouterLocals & InferMiddlewareLocals<Middleware>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
150
+ get<Path extends string, BodySchema extends AnyStandardSchema | unknown, QuerySchema extends AnyStandardSchema | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: RouteOptions<BodySchema, QuerySchema> & {
139
151
  middleware: [...M];
140
152
  },
141
153
  // Using tuple spread pattern
142
- handler: ZodRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
154
+ handler: SchemaRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
143
155
  // Make it readonly for type inference
144
156
  // Make it readonly for type inference
145
157
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
146
- post<Path extends string, BodySchema extends AnyZodType, QuerySchema extends AnyZodType | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
158
+ post<Path extends string, BodySchema extends AnyStandardSchema, QuerySchema extends AnyStandardSchema | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
147
159
  bodySchema: BodySchema;
148
160
  querySchema?: QuerySchema;
149
161
  middleware: [...M];
150
- }, handler: ZodRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
162
+ }, handler: SchemaRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
151
163
  // Make it readonly for type inference
152
164
  // Make it readonly for type inference
153
165
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
154
- post<Path extends string, BodySchema extends AnyZodType, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
166
+ post<Path extends string, BodySchema extends AnyStandardSchema, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
155
167
  bodySchema: BodySchema;
156
168
  middleware: [...M];
157
169
  },
158
170
  // Using tuple spread pattern
159
- handler: ZodRouteHandler<Path, BodySchema, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
171
+ handler: SchemaRouteHandler<Path, BodySchema, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
160
172
  // Make it readonly for type inference
161
173
  // Make it readonly for type inference
162
174
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
@@ -164,26 +176,26 @@ declare class TypedRouter<RouterMiddlewareProps extends Record<string, any> = {}
164
176
  middleware: [...M];
165
177
  },
166
178
  // Using tuple spread pattern
167
- handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
179
+ handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
168
180
  // Make it readonly for type inference
169
181
  // Make it readonly for type inference
170
182
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
171
- post<Path extends string, BodySchema extends AnyZodType | unknown, QuerySchema extends AnyZodType | unknown>(path: Path, options: RouteOptions<BodySchema, QuerySchema>, handler: ZodRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
172
- post<Path extends string>(path: Path, handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
173
- put<Path extends string, BodySchema extends AnyZodType, QuerySchema extends AnyZodType | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
183
+ post<Path extends string, BodySchema extends AnyStandardSchema | unknown, QuerySchema extends AnyStandardSchema | unknown>(path: Path, options: RouteOptions<BodySchema, QuerySchema>, handler: SchemaRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
184
+ post<Path extends string>(path: Path, handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
185
+ put<Path extends string, BodySchema extends AnyStandardSchema, QuerySchema extends AnyStandardSchema | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
174
186
  bodySchema: BodySchema;
175
187
  querySchema?: QuerySchema;
176
188
  middleware: [...M];
177
- }, handler: ZodRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
189
+ }, handler: SchemaRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
178
190
  // Make it readonly for type inference
179
191
  // Make it readonly for type inference
180
192
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
181
- put<Path extends string, BodySchema extends AnyZodType, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
193
+ put<Path extends string, BodySchema extends AnyStandardSchema, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
182
194
  bodySchema: BodySchema;
183
195
  middleware: [...M];
184
196
  },
185
197
  // Using tuple spread pattern
186
- handler: ZodRouteHandler<Path, BodySchema, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
198
+ handler: SchemaRouteHandler<Path, BodySchema, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
187
199
  // Make it readonly for type inference
188
200
  // Make it readonly for type inference
189
201
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
@@ -191,26 +203,26 @@ declare class TypedRouter<RouterMiddlewareProps extends Record<string, any> = {}
191
203
  middleware: [...M];
192
204
  },
193
205
  // Using tuple spread pattern
194
- handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
206
+ handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
195
207
  // Make it readonly for type inference
196
208
  // Make it readonly for type inference
197
209
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
198
- put<Path extends string, BodySchema extends AnyZodType | unknown, QuerySchema extends AnyZodType | unknown>(path: Path, options: RouteOptions<BodySchema, QuerySchema>, handler: ZodRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
199
- put<Path extends string>(path: Path, handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
200
- patch<Path extends string, BodySchema extends AnyZodType, QuerySchema extends AnyZodType | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
210
+ put<Path extends string, BodySchema extends AnyStandardSchema | unknown, QuerySchema extends AnyStandardSchema | unknown>(path: Path, options: RouteOptions<BodySchema, QuerySchema>, handler: SchemaRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
211
+ put<Path extends string>(path: Path, handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
212
+ patch<Path extends string, BodySchema extends AnyStandardSchema, QuerySchema extends AnyStandardSchema | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
201
213
  bodySchema: BodySchema;
202
214
  querySchema?: QuerySchema;
203
215
  middleware: [...M];
204
- }, handler: ZodRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
216
+ }, handler: SchemaRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
205
217
  // Make it readonly for type inference
206
218
  // Make it readonly for type inference
207
219
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
208
- patch<Path extends string, BodySchema extends AnyZodType, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
220
+ patch<Path extends string, BodySchema extends AnyStandardSchema, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
209
221
  bodySchema: BodySchema;
210
222
  middleware: [...M];
211
223
  },
212
224
  // Using tuple spread pattern
213
- handler: ZodRouteHandler<Path, BodySchema, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
225
+ handler: SchemaRouteHandler<Path, BodySchema, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
214
226
  // Make it readonly for type inference
215
227
  // Make it readonly for type inference
216
228
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
@@ -218,111 +230,111 @@ declare class TypedRouter<RouterMiddlewareProps extends Record<string, any> = {}
218
230
  middleware: [...M];
219
231
  },
220
232
  // Using tuple spread pattern
221
- handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
233
+ handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
222
234
  // Make it readonly for type inference
223
235
  // Make it readonly for type inference
224
236
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
225
- patch<Path extends string, BodySchema extends AnyZodType | unknown, QuerySchema extends AnyZodType | unknown>(path: Path, options: RouteOptions<BodySchema, QuerySchema>, handler: ZodRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
226
- patch<Path extends string>(path: Path, handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
227
- delete<Path extends string, QuerySchema extends AnyZodType | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
237
+ patch<Path extends string, BodySchema extends AnyStandardSchema | unknown, QuerySchema extends AnyStandardSchema | unknown>(path: Path, options: RouteOptions<BodySchema, QuerySchema>, handler: SchemaRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
238
+ patch<Path extends string>(path: Path, handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
239
+ delete<Path extends string, QuerySchema extends AnyStandardSchema | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
228
240
  querySchema: QuerySchema;
229
241
  middleware: [...M];
230
242
  },
231
243
  // Using tuple spread pattern
232
- handler: ZodRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
244
+ handler: SchemaRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
233
245
  // Make it readonly for type inference
234
246
  // Make it readonly for type inference
235
247
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
236
- delete<Path extends string, QuerySchema extends AnyZodType | unknown>(path: Path, options: {
248
+ delete<Path extends string, QuerySchema extends AnyStandardSchema | unknown>(path: Path, options: {
237
249
  querySchema: QuerySchema;
238
- }, handler: ZodRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
250
+ }, handler: SchemaRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
239
251
  delete<Path extends string, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
240
252
  middleware: [...M];
241
253
  },
242
254
  // Using tuple spread pattern
243
- handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
255
+ handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
244
256
  // Make it readonly for type inference
245
257
  // Make it readonly for type inference
246
258
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
247
- delete<Path extends string>(path: Path, handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
248
- options<Path extends string, QuerySchema extends AnyZodType | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
259
+ delete<Path extends string>(path: Path, handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
260
+ options<Path extends string, QuerySchema extends AnyStandardSchema | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
249
261
  querySchema: QuerySchema;
250
262
  middleware: [...M];
251
263
  },
252
264
  // Using tuple spread pattern
253
- handler: ZodRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
265
+ handler: SchemaRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
254
266
  // Make it readonly for type inference
255
267
  // Make it readonly for type inference
256
268
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
257
- options<Path extends string, QuerySchema extends AnyZodType | unknown>(path: Path, options: {
269
+ options<Path extends string, QuerySchema extends AnyStandardSchema | unknown>(path: Path, options: {
258
270
  querySchema: QuerySchema;
259
- }, handler: ZodRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
271
+ }, handler: SchemaRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
260
272
  options<Path extends string, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
261
273
  middleware: [...M];
262
274
  },
263
275
  // Using tuple spread pattern
264
- handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
276
+ handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
265
277
  // Make it readonly for type inference
266
278
  // Make it readonly for type inference
267
279
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
268
- options<Path extends string>(path: Path, handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
269
- head<Path extends string, QuerySchema extends AnyZodType | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
280
+ options<Path extends string>(path: Path, handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
281
+ head<Path extends string, QuerySchema extends AnyStandardSchema | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
270
282
  querySchema: QuerySchema;
271
283
  middleware: [...M];
272
284
  },
273
285
  // Using tuple spread pattern
274
- handler: ZodRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
286
+ handler: SchemaRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
275
287
  // Make it readonly for type inference
276
288
  // Make it readonly for type inference
277
289
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
278
- head<Path extends string, QuerySchema extends AnyZodType | unknown>(path: Path, options: {
290
+ head<Path extends string, QuerySchema extends AnyStandardSchema | unknown>(path: Path, options: {
279
291
  querySchema: QuerySchema;
280
- }, handler: ZodRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
292
+ }, handler: SchemaRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
281
293
  head<Path extends string, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
282
294
  middleware: [...M];
283
295
  },
284
296
  // Using tuple spread pattern
285
- handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
297
+ handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
286
298
  // Make it readonly for type inference
287
299
  // Make it readonly for type inference
288
300
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
289
- head<Path extends string>(path: Path, handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
290
- all<Path extends string, BodySchema extends AnyZodType, QuerySchema extends AnyZodType | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
301
+ head<Path extends string>(path: Path, handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
302
+ all<Path extends string, BodySchema extends AnyStandardSchema, QuerySchema extends AnyStandardSchema | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
291
303
  bodySchema: BodySchema;
292
304
  querySchema?: QuerySchema;
293
305
  middleware: [...M];
294
- }, handler: ZodRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
306
+ }, handler: SchemaRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
295
307
  // Make it readonly for type inference
296
308
  // Make it readonly for type inference
297
309
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
298
- all<Path extends string, BodySchema extends AnyZodType, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
310
+ all<Path extends string, BodySchema extends AnyStandardSchema, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
299
311
  bodySchema: BodySchema;
300
312
  middleware: [...M];
301
313
  },
302
314
  // Using tuple spread pattern
303
- handler: ZodRouteHandler<Path, BodySchema, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
315
+ handler: SchemaRouteHandler<Path, BodySchema, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
304
316
  // Make it readonly for type inference
305
317
  // Make it readonly for type inference
306
318
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
307
- all<Path extends string, QuerySchema extends AnyZodType | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
319
+ all<Path extends string, QuerySchema extends AnyStandardSchema | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
308
320
  querySchema: QuerySchema;
309
321
  middleware: [...M];
310
322
  },
311
323
  // Using tuple spread pattern
312
- handler: ZodRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
324
+ handler: SchemaRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
313
325
  // Make it readonly for type inference
314
326
  // Make it readonly for type inference
315
327
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
316
- all<Path extends string, BodySchema extends AnyZodType | unknown, QuerySchema extends AnyZodType | unknown>(path: Path, options: RouteOptions<BodySchema, QuerySchema>, handler: ZodRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
328
+ all<Path extends string, BodySchema extends AnyStandardSchema | unknown, QuerySchema extends AnyStandardSchema | unknown>(path: Path, options: RouteOptions<BodySchema, QuerySchema>, handler: SchemaRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
317
329
  all<Path extends string, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
318
330
  middleware: [...M];
319
331
  },
320
332
  // Using tuple spread pattern
321
- handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
333
+ handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
322
334
  // Make it readonly for type inference
323
335
  // Make it readonly for type inference
324
336
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
325
- all<Path extends string>(path: Path, handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
337
+ all<Path extends string>(path: Path, handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
326
338
  private registerRoute;
327
339
  private createBodyValidationMiddleware;
328
340
  private createQueryValidationMiddleware;
@@ -391,4 +403,4 @@ declare function createTypedRouterWithConfig<RouterMiddlewareProps extends Recor
391
403
  */
392
404
  declare function createTypedRouterWithMiddleware<T extends Record<string, any>>(...middleware: TypedMiddleware<any, any>[]): TypedRouter<T>;
393
405
  //#endregion
394
- export { AnyZodType, ExtractRouteParams, HttpMethod, InferInput, InferOutput, LocalsOnlyMiddleware, RequestOnlyMiddleware, RouteOptions, RouterConfig, SafeParseResult, TypedMiddleware, ZodRequest, ZodRouteHandler, createTypedRouter, createTypedRouterWithConfig, createTypedRouterWithMiddleware, isZod4Schema, isZodError, parseSchema, safeParseSchema };
406
+ export { AnyStandardSchema, ExtractRouteParams, HttpMethod, InferInput, InferOutput, InferSchemaOutput, LocalsOnlyMiddleware, RequestOnlyMiddleware, RouteOptions, RouterConfig, SafeParseResult, SchemaRequest, SchemaRouteHandler, TypedMiddleware, createTypedRouter, createTypedRouterWithConfig, createTypedRouterWithMiddleware, isSchemaError, parseSchema, safeParseSchema };
@@ -1,25 +1,37 @@
1
1
  import express, { NextFunction, Request, Response } from "express";
2
- import * as z3 from "zod/v3";
3
- import * as z4 from "zod/v4/core";
2
+ import { StandardSchemaV1 } from "@standard-schema/spec";
4
3
 
5
- //#region src/zod-router.d.ts
4
+ //#region src/schema-router.d.ts
6
5
 
7
- type AnyZodType = z3.ZodTypeAny | z4.$ZodType;
8
- declare function isZod4Schema(schema: AnyZodType): schema is z4.$ZodType;
9
- type InferOutput<T> = T extends z4.$ZodType ? z4.output<T> : T extends z3.ZodTypeAny ? z3.output<T> : T extends {
10
- _output: infer O;
11
- } ? O : T extends {
12
- _type: infer O;
13
- } ? O : unknown;
14
- type InferInput<T> = T extends z4.$ZodType ? z4.input<T> : T extends z3.ZodTypeAny ? z3.input<T> : T extends {
15
- _input: infer I;
16
- } ? I : T extends {
17
- _type: infer I;
18
- } ? I : unknown;
19
- declare function parseSchema<T extends AnyZodType>(schema: T, data: unknown): InferOutput<T>;
20
- type SafeParseResult<T extends AnyZodType> = T extends z4.$ZodType ? ReturnType<typeof z4.safeParse<T>> : T extends z3.ZodTypeAny ? z3.SafeParseReturnType<z3.input<T>, z3.output<T>> : never;
21
- declare function safeParseSchema<T extends AnyZodType>(schema: T, data: unknown): SafeParseResult<T>;
22
- declare function isZodError(error: unknown): error is z3.ZodError;
6
+ type AnyStandardSchema = StandardSchemaV1<any, any>;
7
+ type InferOutput<T> = T extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<T> : unknown;
8
+ type InferInput<T> = T extends StandardSchemaV1 ? StandardSchemaV1.InferInput<T> : unknown;
9
+ type InferFromSafeParse<T> = T extends {
10
+ safeParse: (...args: any[]) => infer R;
11
+ } ? R extends {
12
+ success: true;
13
+ data: infer O;
14
+ } ? O : R extends Promise<infer PR> ? PR extends {
15
+ success: true;
16
+ data: infer O;
17
+ } ? O : never : never : T extends {
18
+ parse: (...args: any[]) => infer R;
19
+ } ? R : never;
20
+ type InferSchemaOutput<T> = T extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<T> : InferFromSafeParse<T>;
21
+ declare function parseSchema<T>(schema: T, data: unknown): InferSchemaOutput<T>;
22
+ type SafeParseResult<T> = StandardSchemaV1.Result<InferSchemaOutput<T>> | {
23
+ value: InferSchemaOutput<T>;
24
+ } | {
25
+ issues: any[];
26
+ } | Promise<StandardSchemaV1.Result<InferSchemaOutput<T>> | {
27
+ value: InferSchemaOutput<T>;
28
+ } | {
29
+ issues: any[];
30
+ }>;
31
+ declare function safeParseSchema<T>(schema: T, data: unknown): SafeParseResult<T>;
32
+ declare function isSchemaError(error: unknown): error is {
33
+ issues: any[];
34
+ };
23
35
  /**
24
36
  * Extract route parameters from Express.js route patterns.
25
37
  *
@@ -28,7 +40,7 @@ declare function isZodError(error: unknown): error is z3.ZodError;
28
40
  * - Multiple parameters: /users/:userId/books/:bookId → { userId: string; bookId: string }
29
41
  * - Parameters with separators: /flights/:from-:to → { from: string; to: string }
30
42
  * - Dot notation: /plantae/:genus.:species → { genus: string; species: string }
31
- * - Regex constraints: /user/:id(\\d+) → { id: string }
43
+ * - Regex constraints: /user/:id(\d+) → { id: string }
32
44
  * - Optional parameters: /posts/:year/:month? → { year: string; month?: string }
33
45
  * - Wildcard parameters: /files/* → { "0": string }
34
46
  * - Multiple wildcards: /a/star/b/star → { "0": string; "1": string }
@@ -89,22 +101,22 @@ type RequestOnlyMiddleware<TReq extends Record<string, any>> = TypedMiddleware<T
89
101
  type LocalsOnlyMiddleware<TLocals extends Record<string, any>> = TypedMiddleware<{}, TLocals>;
90
102
  type InferMiddlewareProps<T extends readonly TypedMiddleware<any, any>[]> = T extends readonly [infer First, ...infer Rest] ? First extends TypedMiddleware<infer FirstReq, any> ? Rest extends readonly TypedMiddleware<any, any>[] ? FirstReq & InferMiddlewareProps<Rest> : FirstReq : {} : {};
91
103
  type InferMiddlewareLocals<T extends readonly TypedMiddleware<any, any>[]> = T extends readonly [infer First, ...infer Rest] ? First extends TypedMiddleware<any, infer FirstLocals> ? Rest extends readonly TypedMiddleware<any, any>[] ? FirstLocals & InferMiddlewareLocals<Rest> : FirstLocals : {} : {};
92
- type ZodRequest<Path extends string = string, BodySchema extends AnyZodType | unknown = unknown, QuerySchema extends AnyZodType | unknown = unknown, MiddlewareProps extends Record<string, any> = {}> = Omit<Request, "params" | "query" | "body"> & {
104
+ type SchemaRequest<Path extends string = string, BodySchema extends AnyStandardSchema | unknown = unknown, QuerySchema extends AnyStandardSchema | unknown = unknown, MiddlewareProps extends Record<string, any> = {}> = Omit<Request, "params" | "query" | "body"> & {
93
105
  params: ExtractRouteParams<Path>;
94
- body: BodySchema extends AnyZodType ? InferOutput<BodySchema> : unknown;
95
- query: QuerySchema extends AnyZodType ? InferOutput<QuerySchema> : unknown;
106
+ body: BodySchema extends unknown ? InferSchemaOutput<BodySchema> : unknown;
107
+ query: QuerySchema extends unknown ? InferSchemaOutput<QuerySchema> : unknown;
96
108
  } & MiddlewareProps;
97
- type ZodRouteHandler<Path extends string = string, BodySchema extends AnyZodType | unknown = unknown, QuerySchema extends AnyZodType | unknown = unknown, MiddlewareProps extends Record<string, any> = {}, ResponseLocals extends Record<string, any> = {}> = (req: ZodRequest<Path, BodySchema, QuerySchema, MiddlewareProps>, res: Response<any, ResponseLocals>, next?: NextFunction) => void | undefined | Promise<void | undefined> | Response | Promise<Response> | Promise<Response | undefined>;
109
+ type SchemaRouteHandler<Path extends string = string, BodySchema extends AnyStandardSchema | unknown = unknown, QuerySchema extends AnyStandardSchema | unknown = unknown, MiddlewareProps extends Record<string, any> = {}, ResponseLocals extends Record<string, any> = {}> = (req: SchemaRequest<Path, BodySchema, QuerySchema, MiddlewareProps>, res: Response<any, ResponseLocals>, next?: NextFunction) => void | undefined | Promise<void | undefined> | Response | Promise<Response> | Promise<Response | undefined>;
98
110
  /**
99
111
  * Options for defining a typed route, including schemas and middleware.
100
112
  *
101
- * @template BodySchema - Zod schema for request body validation.
102
- * @template QuerySchema - Zod schema for query parameter validation.
103
- * @property bodySchema - Optional Zod schema for validating the request body.
104
- * @property querySchema - Optional Zod schema for validating the query string.
113
+ * @template BodySchema - Schema for request body validation.
114
+ * @template QuerySchema - Schema for query parameter validation.
115
+ * @property bodySchema - Optional schema for validating the request body.
116
+ * @property querySchema - Optional schema for validating the query string.
105
117
  * @property middleware - Optional array of TypedMiddleware for this route.
106
118
  */
107
- interface RouteOptions<BodySchema extends AnyZodType | unknown = unknown, QuerySchema extends AnyZodType | unknown = unknown> {
119
+ interface RouteOptions<BodySchema extends AnyStandardSchema | unknown = unknown, QuerySchema extends AnyStandardSchema | unknown = unknown> {
108
120
  bodySchema?: BodySchema;
109
121
  querySchema?: QuerySchema;
110
122
  middleware?: TypedMiddleware<any, any>[];
@@ -130,33 +142,33 @@ declare class TypedRouter<RouterMiddlewareProps extends Record<string, any> = {}
130
142
  * Get the underlying Express router
131
143
  */
132
144
  getRouter(): express.Router;
133
- get<Path extends string>(path: Path, handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
134
- get<Path extends string, BodySchema extends AnyZodType | unknown, QuerySchema extends AnyZodType | unknown>(path: Path, options: RouteOptions<BodySchema, QuerySchema>, handler: ZodRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
145
+ get<Path extends string>(path: Path, handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
146
+ get<Path extends string, BodySchema extends AnyStandardSchema | unknown, QuerySchema extends AnyStandardSchema | unknown>(path: Path, options: RouteOptions<BodySchema, QuerySchema>, handler: SchemaRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
135
147
  get<Path extends string, Middleware extends readonly TypedMiddleware<any, any>[]>(path: Path, options: {
136
148
  middleware: Middleware;
137
- }, handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<Middleware>, RouterLocals & InferMiddlewareLocals<Middleware>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
138
- get<Path extends string, BodySchema extends AnyZodType | unknown, QuerySchema extends AnyZodType | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: RouteOptions<BodySchema, QuerySchema> & {
149
+ }, handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<Middleware>, RouterLocals & InferMiddlewareLocals<Middleware>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
150
+ get<Path extends string, BodySchema extends AnyStandardSchema | unknown, QuerySchema extends AnyStandardSchema | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: RouteOptions<BodySchema, QuerySchema> & {
139
151
  middleware: [...M];
140
152
  },
141
153
  // Using tuple spread pattern
142
- handler: ZodRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
154
+ handler: SchemaRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
143
155
  // Make it readonly for type inference
144
156
  // Make it readonly for type inference
145
157
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
146
- post<Path extends string, BodySchema extends AnyZodType, QuerySchema extends AnyZodType | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
158
+ post<Path extends string, BodySchema extends AnyStandardSchema, QuerySchema extends AnyStandardSchema | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
147
159
  bodySchema: BodySchema;
148
160
  querySchema?: QuerySchema;
149
161
  middleware: [...M];
150
- }, handler: ZodRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
162
+ }, handler: SchemaRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
151
163
  // Make it readonly for type inference
152
164
  // Make it readonly for type inference
153
165
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
154
- post<Path extends string, BodySchema extends AnyZodType, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
166
+ post<Path extends string, BodySchema extends AnyStandardSchema, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
155
167
  bodySchema: BodySchema;
156
168
  middleware: [...M];
157
169
  },
158
170
  // Using tuple spread pattern
159
- handler: ZodRouteHandler<Path, BodySchema, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
171
+ handler: SchemaRouteHandler<Path, BodySchema, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
160
172
  // Make it readonly for type inference
161
173
  // Make it readonly for type inference
162
174
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
@@ -164,26 +176,26 @@ declare class TypedRouter<RouterMiddlewareProps extends Record<string, any> = {}
164
176
  middleware: [...M];
165
177
  },
166
178
  // Using tuple spread pattern
167
- handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
179
+ handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
168
180
  // Make it readonly for type inference
169
181
  // Make it readonly for type inference
170
182
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
171
- post<Path extends string, BodySchema extends AnyZodType | unknown, QuerySchema extends AnyZodType | unknown>(path: Path, options: RouteOptions<BodySchema, QuerySchema>, handler: ZodRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
172
- post<Path extends string>(path: Path, handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
173
- put<Path extends string, BodySchema extends AnyZodType, QuerySchema extends AnyZodType | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
183
+ post<Path extends string, BodySchema extends AnyStandardSchema | unknown, QuerySchema extends AnyStandardSchema | unknown>(path: Path, options: RouteOptions<BodySchema, QuerySchema>, handler: SchemaRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
184
+ post<Path extends string>(path: Path, handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
185
+ put<Path extends string, BodySchema extends AnyStandardSchema, QuerySchema extends AnyStandardSchema | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
174
186
  bodySchema: BodySchema;
175
187
  querySchema?: QuerySchema;
176
188
  middleware: [...M];
177
- }, handler: ZodRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
189
+ }, handler: SchemaRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
178
190
  // Make it readonly for type inference
179
191
  // Make it readonly for type inference
180
192
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
181
- put<Path extends string, BodySchema extends AnyZodType, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
193
+ put<Path extends string, BodySchema extends AnyStandardSchema, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
182
194
  bodySchema: BodySchema;
183
195
  middleware: [...M];
184
196
  },
185
197
  // Using tuple spread pattern
186
- handler: ZodRouteHandler<Path, BodySchema, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
198
+ handler: SchemaRouteHandler<Path, BodySchema, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
187
199
  // Make it readonly for type inference
188
200
  // Make it readonly for type inference
189
201
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
@@ -191,26 +203,26 @@ declare class TypedRouter<RouterMiddlewareProps extends Record<string, any> = {}
191
203
  middleware: [...M];
192
204
  },
193
205
  // Using tuple spread pattern
194
- handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
206
+ handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
195
207
  // Make it readonly for type inference
196
208
  // Make it readonly for type inference
197
209
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
198
- put<Path extends string, BodySchema extends AnyZodType | unknown, QuerySchema extends AnyZodType | unknown>(path: Path, options: RouteOptions<BodySchema, QuerySchema>, handler: ZodRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
199
- put<Path extends string>(path: Path, handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
200
- patch<Path extends string, BodySchema extends AnyZodType, QuerySchema extends AnyZodType | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
210
+ put<Path extends string, BodySchema extends AnyStandardSchema | unknown, QuerySchema extends AnyStandardSchema | unknown>(path: Path, options: RouteOptions<BodySchema, QuerySchema>, handler: SchemaRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
211
+ put<Path extends string>(path: Path, handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
212
+ patch<Path extends string, BodySchema extends AnyStandardSchema, QuerySchema extends AnyStandardSchema | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
201
213
  bodySchema: BodySchema;
202
214
  querySchema?: QuerySchema;
203
215
  middleware: [...M];
204
- }, handler: ZodRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
216
+ }, handler: SchemaRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
205
217
  // Make it readonly for type inference
206
218
  // Make it readonly for type inference
207
219
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
208
- patch<Path extends string, BodySchema extends AnyZodType, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
220
+ patch<Path extends string, BodySchema extends AnyStandardSchema, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
209
221
  bodySchema: BodySchema;
210
222
  middleware: [...M];
211
223
  },
212
224
  // Using tuple spread pattern
213
- handler: ZodRouteHandler<Path, BodySchema, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
225
+ handler: SchemaRouteHandler<Path, BodySchema, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
214
226
  // Make it readonly for type inference
215
227
  // Make it readonly for type inference
216
228
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
@@ -218,111 +230,111 @@ declare class TypedRouter<RouterMiddlewareProps extends Record<string, any> = {}
218
230
  middleware: [...M];
219
231
  },
220
232
  // Using tuple spread pattern
221
- handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
233
+ handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
222
234
  // Make it readonly for type inference
223
235
  // Make it readonly for type inference
224
236
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
225
- patch<Path extends string, BodySchema extends AnyZodType | unknown, QuerySchema extends AnyZodType | unknown>(path: Path, options: RouteOptions<BodySchema, QuerySchema>, handler: ZodRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
226
- patch<Path extends string>(path: Path, handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
227
- delete<Path extends string, QuerySchema extends AnyZodType | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
237
+ patch<Path extends string, BodySchema extends AnyStandardSchema | unknown, QuerySchema extends AnyStandardSchema | unknown>(path: Path, options: RouteOptions<BodySchema, QuerySchema>, handler: SchemaRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
238
+ patch<Path extends string>(path: Path, handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
239
+ delete<Path extends string, QuerySchema extends AnyStandardSchema | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
228
240
  querySchema: QuerySchema;
229
241
  middleware: [...M];
230
242
  },
231
243
  // Using tuple spread pattern
232
- handler: ZodRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
244
+ handler: SchemaRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
233
245
  // Make it readonly for type inference
234
246
  // Make it readonly for type inference
235
247
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
236
- delete<Path extends string, QuerySchema extends AnyZodType | unknown>(path: Path, options: {
248
+ delete<Path extends string, QuerySchema extends AnyStandardSchema | unknown>(path: Path, options: {
237
249
  querySchema: QuerySchema;
238
- }, handler: ZodRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
250
+ }, handler: SchemaRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
239
251
  delete<Path extends string, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
240
252
  middleware: [...M];
241
253
  },
242
254
  // Using tuple spread pattern
243
- handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
255
+ handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
244
256
  // Make it readonly for type inference
245
257
  // Make it readonly for type inference
246
258
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
247
- delete<Path extends string>(path: Path, handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
248
- options<Path extends string, QuerySchema extends AnyZodType | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
259
+ delete<Path extends string>(path: Path, handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
260
+ options<Path extends string, QuerySchema extends AnyStandardSchema | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
249
261
  querySchema: QuerySchema;
250
262
  middleware: [...M];
251
263
  },
252
264
  // Using tuple spread pattern
253
- handler: ZodRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
265
+ handler: SchemaRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
254
266
  // Make it readonly for type inference
255
267
  // Make it readonly for type inference
256
268
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
257
- options<Path extends string, QuerySchema extends AnyZodType | unknown>(path: Path, options: {
269
+ options<Path extends string, QuerySchema extends AnyStandardSchema | unknown>(path: Path, options: {
258
270
  querySchema: QuerySchema;
259
- }, handler: ZodRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
271
+ }, handler: SchemaRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
260
272
  options<Path extends string, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
261
273
  middleware: [...M];
262
274
  },
263
275
  // Using tuple spread pattern
264
- handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
276
+ handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
265
277
  // Make it readonly for type inference
266
278
  // Make it readonly for type inference
267
279
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
268
- options<Path extends string>(path: Path, handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
269
- head<Path extends string, QuerySchema extends AnyZodType | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
280
+ options<Path extends string>(path: Path, handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
281
+ head<Path extends string, QuerySchema extends AnyStandardSchema | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
270
282
  querySchema: QuerySchema;
271
283
  middleware: [...M];
272
284
  },
273
285
  // Using tuple spread pattern
274
- handler: ZodRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
286
+ handler: SchemaRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
275
287
  // Make it readonly for type inference
276
288
  // Make it readonly for type inference
277
289
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
278
- head<Path extends string, QuerySchema extends AnyZodType | unknown>(path: Path, options: {
290
+ head<Path extends string, QuerySchema extends AnyStandardSchema | unknown>(path: Path, options: {
279
291
  querySchema: QuerySchema;
280
- }, handler: ZodRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
292
+ }, handler: SchemaRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
281
293
  head<Path extends string, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
282
294
  middleware: [...M];
283
295
  },
284
296
  // Using tuple spread pattern
285
- handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
297
+ handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
286
298
  // Make it readonly for type inference
287
299
  // Make it readonly for type inference
288
300
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
289
- head<Path extends string>(path: Path, handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
290
- all<Path extends string, BodySchema extends AnyZodType, QuerySchema extends AnyZodType | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
301
+ head<Path extends string>(path: Path, handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
302
+ all<Path extends string, BodySchema extends AnyStandardSchema, QuerySchema extends AnyStandardSchema | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
291
303
  bodySchema: BodySchema;
292
304
  querySchema?: QuerySchema;
293
305
  middleware: [...M];
294
- }, handler: ZodRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
306
+ }, handler: SchemaRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
295
307
  // Make it readonly for type inference
296
308
  // Make it readonly for type inference
297
309
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
298
- all<Path extends string, BodySchema extends AnyZodType, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
310
+ all<Path extends string, BodySchema extends AnyStandardSchema, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
299
311
  bodySchema: BodySchema;
300
312
  middleware: [...M];
301
313
  },
302
314
  // Using tuple spread pattern
303
- handler: ZodRouteHandler<Path, BodySchema, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
315
+ handler: SchemaRouteHandler<Path, BodySchema, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
304
316
  // Make it readonly for type inference
305
317
  // Make it readonly for type inference
306
318
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
307
- all<Path extends string, QuerySchema extends AnyZodType | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
319
+ all<Path extends string, QuerySchema extends AnyStandardSchema | unknown, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
308
320
  querySchema: QuerySchema;
309
321
  middleware: [...M];
310
322
  },
311
323
  // Using tuple spread pattern
312
- handler: ZodRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
324
+ handler: SchemaRouteHandler<Path, unknown, QuerySchema, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
313
325
  // Make it readonly for type inference
314
326
  // Make it readonly for type inference
315
327
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
316
- all<Path extends string, BodySchema extends AnyZodType | unknown, QuerySchema extends AnyZodType | unknown>(path: Path, options: RouteOptions<BodySchema, QuerySchema>, handler: ZodRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
328
+ all<Path extends string, BodySchema extends AnyStandardSchema | unknown, QuerySchema extends AnyStandardSchema | unknown>(path: Path, options: RouteOptions<BodySchema, QuerySchema>, handler: SchemaRouteHandler<Path, BodySchema, QuerySchema, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
317
329
  all<Path extends string, M extends TypedMiddleware<any, any>[]>(path: Path, options: {
318
330
  middleware: [...M];
319
331
  },
320
332
  // Using tuple spread pattern
321
- handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
333
+ handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps & InferMiddlewareProps<readonly [...M]>,
322
334
  // Make it readonly for type inference
323
335
  // Make it readonly for type inference
324
336
  RouterLocals & InferMiddlewareLocals<readonly [...M]>>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
325
- all<Path extends string>(path: Path, handler: ZodRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
337
+ all<Path extends string>(path: Path, handler: SchemaRouteHandler<Path, unknown, unknown, RouterMiddlewareProps, RouterLocals>): TypedRouter<RouterMiddlewareProps, RouterLocals>;
326
338
  private registerRoute;
327
339
  private createBodyValidationMiddleware;
328
340
  private createQueryValidationMiddleware;
@@ -391,4 +403,4 @@ declare function createTypedRouterWithConfig<RouterMiddlewareProps extends Recor
391
403
  */
392
404
  declare function createTypedRouterWithMiddleware<T extends Record<string, any>>(...middleware: TypedMiddleware<any, any>[]): TypedRouter<T>;
393
405
  //#endregion
394
- export { AnyZodType, ExtractRouteParams, HttpMethod, InferInput, InferOutput, LocalsOnlyMiddleware, RequestOnlyMiddleware, RouteOptions, RouterConfig, SafeParseResult, TypedMiddleware, ZodRequest, ZodRouteHandler, createTypedRouter, createTypedRouterWithConfig, createTypedRouterWithMiddleware, isZod4Schema, isZodError, parseSchema, safeParseSchema };
406
+ export { AnyStandardSchema, ExtractRouteParams, HttpMethod, InferInput, InferOutput, InferSchemaOutput, LocalsOnlyMiddleware, RequestOnlyMiddleware, RouteOptions, RouterConfig, SafeParseResult, SchemaRequest, SchemaRouteHandler, TypedMiddleware, createTypedRouter, createTypedRouterWithConfig, createTypedRouterWithMiddleware, isSchemaError, parseSchema, safeParseSchema };
@@ -0,0 +1 @@
1
+ import e from"express";import{SchemaError as t}from"@standard-schema/utils";function n(e,n){let r=e;if(r&&r[`~standard`]&&typeof r[`~standard`].validate==`function`){let e=r[`~standard`].validate(n);if(e instanceof Promise)throw TypeError(`Async schema validation is not supported by parseSchema`);if(e.issues)throw new t(e.issues);return e.value}throw TypeError(`Unsupported schema shape for parseSchema`)}function r(e,t){let n=e;if(n&&n[`~standard`]&&typeof n[`~standard`].validate==`function`)return n[`~standard`].validate(t);if(n&&typeof n.safeParse==`function`)return n.safeParse(t);if(n&&typeof n.parse==`function`)try{let e=n.parse(t);return{value:e}}catch(e){return{issues:[{message:e?.message??String(e)}]}}if(n&&typeof n.validate==`function`){let e=n.validate(t);return e&&e.then&&typeof e.then==`function`?e.then(e=>e.error?{issues:[{message:e.error.message}]}:e.issues?{issues:e.issues}:{value:e.value??e}):e&&e.error?{issues:[{message:e.error.message}]}:e&&e.issues?{issues:e.issues}:{value:e.value??e}}return{issues:[{message:`Unsupported schema shape`}]}}function i(e){return typeof e==`object`&&!!e&&`issues`in e&&Array.isArray(e.issues)}var a=class{router;constructor(){this.router=e.Router()}useMiddleware(e){return this.router.use(e),this}getRouter(){return this.router}get(e,t,n){return this.registerRoute(`get`,e,t,n)}post(e,t,n){return this.registerRoute(`post`,e,t,n)}put(e,t,n){return this.registerRoute(`put`,e,t,n)}patch(e,t,n){return this.registerRoute(`patch`,e,t,n)}delete(e,t,n){return this.registerRoute(`delete`,e,t,n)}options(e,t,n){return this.registerRoute(`options`,e,t,n)}head(e,t,n){return this.registerRoute(`head`,e,t,n)}all(e,t,n){return this.registerRoute(`all`,e,t,n)}registerRoute(e,t,n,r){let i=[];if(typeof n==`object`){let e=n;e.middleware&&i.push(...e.middleware),e.bodySchema&&i.push(this.createBodyValidationMiddleware(e.bodySchema)),e.querySchema&&i.push(this.createQueryValidationMiddleware(e.querySchema)),i.push(r)}else i.push(n);return this.router[e](t,...i),this}createBodyValidationMiddleware(e){return async(t,n,a)=>{try{let i=r(e,t.body),o=i&&typeof i.then==`function`?await i:i;if(o&&`issues`in o&&o.issues){n.status(400).json({error:`Validation failed`,details:o.errors||o.issues});return}t.body=o&&`value`in o?o.value:o,a()}catch(e){i(e)?n.status(400).json({error:`Validation failed`,details:e.errors||e.issues}):a(e)}}}createQueryValidationMiddleware(e){return async(t,n,a)=>{try{let i=r(e,t.query),o=i&&typeof i.then==`function`?await i:i;if(o&&`issues`in o&&o.issues){n.status(400).json({error:`Validation failed`,details:o.errors||o.issues});return}let s=o&&`value`in o?o.value:o;Object.defineProperty(t,`query`,{value:s,writable:!1,enumerable:!0,configurable:!0}),a()}catch(e){i(e)?n.status(400).json({error:`Validation failed`,details:e.errors||e.issues}):a(e)}}}};function o(){return new a}function s(e){let t=new a;return e?.errorHandler&&t.getRouter().use(e.errorHandler),t}function c(...e){let t=new a;for(let n of e)t=t.useMiddleware(n);return t}export{o as createTypedRouter,s as createTypedRouterWithConfig,c as createTypedRouterWithMiddleware,i as isSchemaError,n as parseSchema,r as safeParseSchema};
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@minisylar/express-typed-router",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "A strongly-typed Express router with Zod validation and automatic type inference for params, body, query, and middleware",
5
5
  "type": "module",
6
- "main": "dist/zod-router.cjs",
7
- "module": "dist/zod-router.js",
8
- "types": "dist/zod-router.d.ts",
6
+ "main": "dist/schema-router.cjs",
7
+ "module": "dist/schema-router.js",
8
+ "types": "dist/schema-router.d.ts",
9
9
  "exports": {
10
10
  ".": {
11
- "import": "./dist/zod-router.js",
12
- "require": "./dist/zod-router.cjs",
13
- "types": "./dist/zod-router.d.ts"
11
+ "import": "./dist/schema-router.js",
12
+ "require": "./dist/schema-router.cjs",
13
+ "types": "./dist/schema-router.d.ts"
14
14
  }
15
15
  },
16
16
  "files": [
@@ -36,10 +36,20 @@
36
36
  "router",
37
37
  "typescript",
38
38
  "zod",
39
+ "yup",
40
+ "effect",
41
+ "joi",
42
+ "valibot",
43
+ "arktype",
44
+ "decoders",
45
+ "ts.data.json",
46
+ "unhoax",
39
47
  "validation",
40
48
  "middleware",
41
49
  "type-safe",
42
- "strongly-typed"
50
+ "strongly-typed",
51
+ "schema",
52
+ "standard schema"
43
53
  ],
44
54
  "author": "Mini-Sylar",
45
55
  "license": "MIT",
@@ -53,8 +63,11 @@
53
63
  "homepage": "https://github.com/Mini-Sylar/express-typed-router#readme",
54
64
  "packageManager": "pnpm@10.11.0",
55
65
  "peerDependencies": {
56
- "express": "^4.18.0 || ^5.0.0",
57
- "zod": "^3.25.0 || ^4.0.0"
66
+ "express": "^4.18.0 || ^5.0.0"
67
+ },
68
+ "dependencies": {
69
+ "@standard-schema/spec": "^1.0.0",
70
+ "@standard-schema/utils": "^0.3.0"
58
71
  },
59
72
  "devDependencies": {
60
73
  "@semantic-release/changelog": "^6.0.3",
@@ -63,9 +76,8 @@
63
76
  "conventional-changelog-conventionalcommits": "^9.1.0",
64
77
  "rimraf": "^6.0.1",
65
78
  "semantic-release": "^24.2.7",
66
- "tsdown": "^0.14.0",
67
- "typescript": "^5.8.3",
68
- "zod": "^3.25.76"
79
+ "tsdown": "^0.14.1",
80
+ "typescript": "^5.9.2"
69
81
  },
70
82
  "engines": {
71
83
  "node": ">=18.0.0"
@@ -1 +0,0 @@
1
- var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));const c=s(require(`express`)),l=s(require(`zod/v3`)),u=s(require(`zod/v4/core`));function d(e){return`_zod`in e}function f(e,t){return d(e)?u.parse(e,t):e.parse(t)}function p(e,t){return d(e)?u.safeParse(e,t):e.safeParse(t)}function m(e){return e instanceof l.ZodError||typeof e==`object`&&!!e&&`issues`in e&&Array.isArray(e.issues)}var h=class{router;constructor(){this.router=c.default.Router()}useMiddleware(e){return this.router.use(e),this}getRouter(){return this.router}get(e,t,n){return this.registerRoute(`get`,e,t,n)}post(e,t,n){return this.registerRoute(`post`,e,t,n)}put(e,t,n){return this.registerRoute(`put`,e,t,n)}patch(e,t,n){return this.registerRoute(`patch`,e,t,n)}delete(e,t,n){return this.registerRoute(`delete`,e,t,n)}options(e,t,n){return this.registerRoute(`options`,e,t,n)}head(e,t,n){return this.registerRoute(`head`,e,t,n)}all(e,t,n){return this.registerRoute(`all`,e,t,n)}registerRoute(e,t,n,r){let i=[];if(typeof n==`object`){let e=n;e.middleware&&i.push(...e.middleware),e.bodySchema&&i.push(this.createBodyValidationMiddleware(e.bodySchema)),e.querySchema&&i.push(this.createQueryValidationMiddleware(e.querySchema)),i.push(r)}else i.push(n);return this.router[e](t,...i),this}createBodyValidationMiddleware(e){return(t,n,r)=>{try{t.body=f(e,t.body),r()}catch(e){m(e)?n.status(400).json({error:`Validation failed`,details:e.errors||e.issues}):r(e)}}}createQueryValidationMiddleware(e){return(t,n,r)=>{try{let n=f(e,t.query);Object.defineProperty(t,`query`,{value:n,writable:!1,enumerable:!0,configurable:!0}),r()}catch(e){m(e)?n.status(400).json({error:`Validation failed`,details:e.errors||e.issues}):r(e)}}}};function g(){return new h}function _(e){let t=new h;return e?.errorHandler&&t.getRouter().use(e.errorHandler),t}function v(...e){let t=new h;for(let n of e)t=t.useMiddleware(n);return t}exports.createTypedRouter=g,exports.createTypedRouterWithConfig=_,exports.createTypedRouterWithMiddleware=v,exports.isZod4Schema=d,exports.isZodError=m,exports.parseSchema=f,exports.safeParseSchema=p;
@@ -1 +0,0 @@
1
- import e from"express";import*as t from"zod/v3";import*as n from"zod/v4/core";function r(e){return`_zod`in e}function i(e,t){return r(e)?n.parse(e,t):e.parse(t)}function a(e,t){return r(e)?n.safeParse(e,t):e.safeParse(t)}function o(e){return e instanceof t.ZodError||typeof e==`object`&&!!e&&`issues`in e&&Array.isArray(e.issues)}var s=class{router;constructor(){this.router=e.Router()}useMiddleware(e){return this.router.use(e),this}getRouter(){return this.router}get(e,t,n){return this.registerRoute(`get`,e,t,n)}post(e,t,n){return this.registerRoute(`post`,e,t,n)}put(e,t,n){return this.registerRoute(`put`,e,t,n)}patch(e,t,n){return this.registerRoute(`patch`,e,t,n)}delete(e,t,n){return this.registerRoute(`delete`,e,t,n)}options(e,t,n){return this.registerRoute(`options`,e,t,n)}head(e,t,n){return this.registerRoute(`head`,e,t,n)}all(e,t,n){return this.registerRoute(`all`,e,t,n)}registerRoute(e,t,n,r){let i=[];if(typeof n==`object`){let e=n;e.middleware&&i.push(...e.middleware),e.bodySchema&&i.push(this.createBodyValidationMiddleware(e.bodySchema)),e.querySchema&&i.push(this.createQueryValidationMiddleware(e.querySchema)),i.push(r)}else i.push(n);return this.router[e](t,...i),this}createBodyValidationMiddleware(e){return(t,n,r)=>{try{t.body=i(e,t.body),r()}catch(e){o(e)?n.status(400).json({error:`Validation failed`,details:e.errors||e.issues}):r(e)}}}createQueryValidationMiddleware(e){return(t,n,r)=>{try{let n=i(e,t.query);Object.defineProperty(t,`query`,{value:n,writable:!1,enumerable:!0,configurable:!0}),r()}catch(e){o(e)?n.status(400).json({error:`Validation failed`,details:e.errors||e.issues}):r(e)}}}};function c(){return new s}function l(e){let t=new s;return e?.errorHandler&&t.getRouter().use(e.errorHandler),t}function u(...e){let t=new s;for(let n of e)t=t.useMiddleware(n);return t}export{c as createTypedRouter,l as createTypedRouterWithConfig,u as createTypedRouterWithMiddleware,r as isZod4Schema,o as isZodError,i as parseSchema,a as safeParseSchema};