express-zod-api 25.6.0 → 26.0.0-beta.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,42 @@
1
1
  # Changelog
2
2
 
3
+ ## Version 26
4
+
5
+ ### v26.0.0
6
+
7
+ - Supported `zod` versions: `^4.1.13`:
8
+ - This Zod patch contains an [important fix](https://github.com/colinhacks/zod/pull/5452) that makes the
9
+ `globalRegistry` really global across both CJS and ESM bundles of Zod distribution;
10
+ - The issue was found and reported by [@shadone](https://github.com/shadone);
11
+ - New version of Zod plugin now also extends the CJS exports of Zod:
12
+ - This fixes the "TypeError: example is not a function" in CJS and removes the requirement to use ESM environment;
13
+ - The issue reported by [@squishykid](https://github.com/squishykid), and addressed earlier in [v25.5.3](#v2553);
14
+ - `DependsOnMethod` removed:
15
+ - You can now specify methods as direct keys of an assigned object in `Routing`;
16
+ - That object can still contain nested paths as before;
17
+ - The keys matching lowercase HTTP methods are treated according to the new config setting `methodLikeRouteBehavior`:
18
+ - `method` — when assigned with an Endpoint the key is treated as method of its parent path (default);
19
+ - `path` — the key is always treated as a nested path segment;
20
+ - `options` property renamed to `ctx` in argument of:
21
+ - `Middleware::handler()`,
22
+ - `ResultHandler::handler()`,
23
+ - `handler` of `EndpointsFactory::build()` argument,
24
+ - `testMiddleware()`;
25
+ - `EndpointsFactory::addOptions()` renamed to `addContext()`;
26
+ - The `Integration::constructor()` argument object now requires `config` property, similar to `Documentation`;
27
+
28
+ ```patch
29
+ const routing: Routing = {
30
+ - "/v1/users": new DependsOnMethod({
31
+ + "/v1/users": {
32
+ get: getUserEndpoint,
33
+ - }).nest({
34
+ create: makeUserEndpoint
35
+ - }),
36
+ + },
37
+ };
38
+ ```
39
+
3
40
  ## Version 25
4
41
 
5
42
  ### v25.6.0
package/README.md CHANGED
@@ -19,7 +19,7 @@ Start your API server with I/O schema validation and custom middlewares in minut
19
19
  4. [Basic features](#basic-features)
20
20
  1. [Routing](#routing) including static file serving
21
21
  2. [Middlewares](#middlewares)
22
- 3. [Options](#options)
22
+ 3. [Context](#context)
23
23
  4. [Using native express middlewares](#using-native-express-middlewares)
24
24
  5. [Refinements](#refinements)
25
25
  6. [Query string parser](#query-string-parser)
@@ -86,61 +86,62 @@ Therefore, many basic tasks can be accomplished faster and easier, in particular
86
86
 
87
87
  These people contributed to the improvement of the framework by reporting bugs, making changes and suggesting ideas:
88
88
 
89
- [<img src="https://github.com/squishykid.png" alt="@squishykid" width="50px" />](https://github.com/squishykid)
90
- [<img src="https://github.com/jakub-msqt.png" alt="@jakub-msqt" width="50px" />](https://github.com/jakub-msqt)
91
- [<img src="https://github.com/misha-z1nchuk.png" alt="@misha-z1nchuk" width="50px" />](https://github.com/misha-z1nchuk)
92
- [<img src="https://github.com/GreaterTamarack.png" alt="@GreaterTamarack" width="50px" />](https://github.com/GreaterTamarack)
93
- [<img src="https://github.com/pepegc.png" alt="@pepegc" width="50px" />](https://github.com/pepegc)
94
- [<img src="https://github.com/MichaelHindley.png" alt="@MichaelHindley" width="50px" />](https://github.com/MichaelHindley)
95
- [<img src="https://github.com/zoton2.png" alt="@zoton2" width="50px" />](https://github.com/zoton2)
96
- [<img src="https://github.com/ThomasKientz.png" alt="@ThomasKientz" width="50px" />](https://github.com/ThomasKientz)
97
- [<img src="https://github.com/james10424.png" alt="@james10424" width="50px" />](https://github.com/james10424)
98
- [<img src="https://github.com/HeikoOsigus.png" alt="@HeikoOsigus" width="50px" />](https://github.com/HeikoOsigus)
99
- [<img src="https://github.com/crgeary.png" alt="@crgeary" width="50px" />](https://github.com/crgeary)
100
- [<img src="https://github.com/williamgcampbell.png" alt="@williamgcampbell" width="50px" />](https://github.com/williamgcampbell)
101
- [<img src="https://github.com/gmorgen1.png" alt="@gmorgen1" width="50px" />](https://github.com/gmorgen1)
102
- [<img src="https://github.com/danmichaelo.png" alt="@danmichaelo" width="50px" />](https://github.com/danmichaelo)
103
- [<img src="https://github.com/APTy.png" alt="@APTy" width="50px" />](https://github.com/APTy)
104
- [<img src="https://github.com/LufyCZ.png" alt="@LufyCZ" width="50px" />](https://github.com/LufyCZ)
105
- [<img src="https://github.com/mlms13.png" alt="@mlms13" width="50px" />](https://github.com/mlms13)
106
- [<img src="https://github.com/bobgubko.png" alt="@bobgubko" width="50px" />](https://github.com/bobgubko)
107
- [<img src="https://github.com/LucWag.png" alt="@LucWag" width="50px" />](https://github.com/LucWag)
108
- [<img src="https://github.com/HenriJ.png" alt="@HenriJ" width="50px" />](https://github.com/HenriJ)
109
- [<img src="https://github.com/JonParton.png" alt="@JonParton" width="50px" />](https://github.com/JonParton)
110
- [<img src="https://github.com/t1nky.png" alt="@t1nky" width="50px" />](https://github.com/t1nky)
111
- [<img src="https://github.com/Tomtec331.png" alt="@Tomtec331" width="50px" />](https://github.com/Tomtec331)
112
- [<img src="https://github.com/rottmann.png" alt="@rottmann" width="50px" />](https://github.com/rottmann)
113
- [<img src="https://github.com/boarush.png" alt="@boarush" width="50px" />](https://github.com/boarush)
114
- [<img src="https://github.com/shawncarr.png" alt="@shawncarr" width="50px" />](https://github.com/shawncarr)
115
- [<img src="https://github.com/ben-xD.png" alt="@ben-xD" width="50px" />](https://github.com/ben-xD)
116
- [<img src="https://github.com/daniel-white.png" alt="@daniel-white" width="50px" />](https://github.com/daniel-white)
117
- [<img src="https://github.com/kotsmile.png" alt="@kotsmile" width="50px" />](https://github.com/kotsmile)
118
- [<img src="https://github.com/arlyon.png" alt="@arlyon" width="50px" />](https://github.com/arlyon)
119
- [<img src="https://github.com/elee1766.png" alt="@elee1766" width="50px" />](https://github.com/elee1766)
120
- [<img src="https://github.com/danclaytondev.png" alt="@danclaytondev" width="50px" />](https://github.com/danclaytondev)
121
- [<img src="https://github.com/huyhoang160593.png" alt="@huyhoang160593" width="50px" />](https://github.com/huyhoang160593)
122
- [<img src="https://github.com/sarahssharkey.png" alt="@sarahssharkey" width="50px" />](https://github.com/sarahssharkey)
123
- [<img src="https://github.com/master-chu.png" alt="@master-chu" width="50px" />](https://github.com/master-chu)
124
- [<img src="https://github.com/alindsay55661.png" alt="@alindsay55661" width="50px" />](https://github.com/alindsay55661)
125
- [<img src="https://github.com/john-schmitz.png" alt="@john-schmitz" width="50px" />](https://github.com/john-schmitz)
126
- [<img src="https://github.com/miki725.png" alt="@miki725" width="50px" />](https://github.com/miki725)
127
- [<img src="https://github.com/dev-m1-macbook.png" alt="@dev-m1-macbook" width="50px" />](https://github.com/dev-m1-macbook)
128
- [<img src="https://github.com/McMerph.png" alt="@McMerph" width="50px" />](https://github.com/McMerph)
129
- [<img src="https://github.com/niklashigi.png" alt="@niklashigi" width="50px" />](https://github.com/niklashigi)
130
- [<img src="https://github.com/maxcohn.png" alt="@maxcohn" width="50px" />](https://github.com/maxcohn)
131
- [<img src="https://github.com/VideoSystemsTech.png" alt="@VideoSystemsTech" width="50px" />](https://github.com/VideoSystemsTech)
132
- [<img src="https://github.com/TheWisestOne.png" alt="@TheWisestOne" width="50px" />](https://github.com/TheWisestOne)
133
- [<img src="https://github.com/lazylace37.png" alt="@lazylace37" width="50px" />](https://github.com/lazylace37)
134
- [<img src="https://github.com/leosuncin.png" alt="@leosuncin" width="50px" />](https://github.com/leosuncin)
135
- [<img src="https://github.com/kirdk.png" alt="@kirdk" width="50px" />](https://github.com/kirdk)
136
- [<img src="https://github.com/johngeorgewright.png" alt="@johngeorgewright" width="50px" />](https://github.com/johngeorgewright)
137
- [<img src="https://github.com/ssteuteville.png" alt="@ssteuteville" width="50px" />](https://github.com/ssteuteville)
138
- [<img src="https://github.com/foxfirecodes.png" alt="@foxfirecodes" width="50px" />](https://github.com/foxfirecodes)
139
- [<img src="https://github.com/HardCoreQual.png" alt="@HardCoreQual" width="50px" />](https://github.com/HardCoreQual)
140
- [<img src="https://github.com/hellovai.png" alt="@hellovai" width="50px" />](https://github.com/hellovai)
141
- [<img src="https://github.com/Isaac-Leonard.png" alt="@Isaac-Leonard" width="50px" />](https://github.com/Isaac-Leonard)
142
- [<img src="https://github.com/digimuza.png" alt="@digimuza" width="50px" />](https://github.com/digimuza)
143
- [<img src="https://github.com/glitch452.png" alt="@glitch452" width="50px" />](https://github.com/glitch452)
89
+ [<img src="https://github.com/shadone.png" alt="@shadone" width="50" />](https://github.com/shadone)
90
+ [<img src="https://github.com/squishykid.png" alt="@squishykid" width="50" />](https://github.com/squishykid)
91
+ [<img src="https://github.com/jakub-msqt.png" alt="@jakub-msqt" width="50" />](https://github.com/jakub-msqt)
92
+ [<img src="https://github.com/misha-z1nchuk.png" alt="@misha-z1nchuk" width="50" />](https://github.com/misha-z1nchuk)
93
+ [<img src="https://github.com/GreaterTamarack.png" alt="@GreaterTamarack" width="50" />](https://github.com/GreaterTamarack)
94
+ [<img src="https://github.com/pepegc.png" alt="@pepegc" width="50" />](https://github.com/pepegc)
95
+ [<img src="https://github.com/MichaelHindley.png" alt="@MichaelHindley" width="50" />](https://github.com/MichaelHindley)
96
+ [<img src="https://github.com/zoton2.png" alt="@zoton2" width="50" />](https://github.com/zoton2)
97
+ [<img src="https://github.com/ThomasKientz.png" alt="@ThomasKientz" width="50" />](https://github.com/ThomasKientz)
98
+ [<img src="https://github.com/james10424.png" alt="@james10424" width="50" />](https://github.com/james10424)
99
+ [<img src="https://github.com/HeikoOsigus.png" alt="@HeikoOsigus" width="50" />](https://github.com/HeikoOsigus)
100
+ [<img src="https://github.com/crgeary.png" alt="@crgeary" width="50" />](https://github.com/crgeary)
101
+ [<img src="https://github.com/williamgcampbell.png" alt="@williamgcampbell" width="50" />](https://github.com/williamgcampbell)
102
+ [<img src="https://github.com/gmorgen1.png" alt="@gmorgen1" width="50" />](https://github.com/gmorgen1)
103
+ [<img src="https://github.com/danmichaelo.png" alt="@danmichaelo" width="50" />](https://github.com/danmichaelo)
104
+ [<img src="https://github.com/APTy.png" alt="@APTy" width="50" />](https://github.com/APTy)
105
+ [<img src="https://github.com/LufyCZ.png" alt="@LufyCZ" width="50" />](https://github.com/LufyCZ)
106
+ [<img src="https://github.com/mlms13.png" alt="@mlms13" width="50" />](https://github.com/mlms13)
107
+ [<img src="https://github.com/bobgubko.png" alt="@bobgubko" width="50" />](https://github.com/bobgubko)
108
+ [<img src="https://github.com/LucWag.png" alt="@LucWag" width="50" />](https://github.com/LucWag)
109
+ [<img src="https://github.com/HenriJ.png" alt="@HenriJ" width="50" />](https://github.com/HenriJ)
110
+ [<img src="https://github.com/JonParton.png" alt="@JonParton" width="50" />](https://github.com/JonParton)
111
+ [<img src="https://github.com/t1nky.png" alt="@t1nky" width="50" />](https://github.com/t1nky)
112
+ [<img src="https://github.com/Tomtec331.png" alt="@Tomtec331" width="50" />](https://github.com/Tomtec331)
113
+ [<img src="https://github.com/rottmann.png" alt="@rottmann" width="50" />](https://github.com/rottmann)
114
+ [<img src="https://github.com/boarush.png" alt="@boarush" width="50" />](https://github.com/boarush)
115
+ [<img src="https://github.com/shawncarr.png" alt="@shawncarr" width="50" />](https://github.com/shawncarr)
116
+ [<img src="https://github.com/ben-xD.png" alt="@ben-xD" width="50" />](https://github.com/ben-xD)
117
+ [<img src="https://github.com/daniel-white.png" alt="@daniel-white" width="50" />](https://github.com/daniel-white)
118
+ [<img src="https://github.com/kotsmile.png" alt="@kotsmile" width="50" />](https://github.com/kotsmile)
119
+ [<img src="https://github.com/arlyon.png" alt="@arlyon" width="50" />](https://github.com/arlyon)
120
+ [<img src="https://github.com/elee1766.png" alt="@elee1766" width="50" />](https://github.com/elee1766)
121
+ [<img src="https://github.com/danclaytondev.png" alt="@danclaytondev" width="50" />](https://github.com/danclaytondev)
122
+ [<img src="https://github.com/huyhoang160593.png" alt="@huyhoang160593" width="50" />](https://github.com/huyhoang160593)
123
+ [<img src="https://github.com/sarahssharkey.png" alt="@sarahssharkey" width="50" />](https://github.com/sarahssharkey)
124
+ [<img src="https://github.com/master-chu.png" alt="@master-chu" width="50" />](https://github.com/master-chu)
125
+ [<img src="https://github.com/alindsay55661.png" alt="@alindsay55661" width="50" />](https://github.com/alindsay55661)
126
+ [<img src="https://github.com/john-schmitz.png" alt="@john-schmitz" width="50" />](https://github.com/john-schmitz)
127
+ [<img src="https://github.com/miki725.png" alt="@miki725" width="50" />](https://github.com/miki725)
128
+ [<img src="https://github.com/dev-m1-macbook.png" alt="@dev-m1-macbook" width="50" />](https://github.com/dev-m1-macbook)
129
+ [<img src="https://github.com/McMerph.png" alt="@McMerph" width="50" />](https://github.com/McMerph)
130
+ [<img src="https://github.com/niklashigi.png" alt="@niklashigi" width="50" />](https://github.com/niklashigi)
131
+ [<img src="https://github.com/maxcohn.png" alt="@maxcohn" width="50" />](https://github.com/maxcohn)
132
+ [<img src="https://github.com/VideoSystemsTech.png" alt="@VideoSystemsTech" width="50" />](https://github.com/VideoSystemsTech)
133
+ [<img src="https://github.com/TheWisestOne.png" alt="@TheWisestOne" width="50" />](https://github.com/TheWisestOne)
134
+ [<img src="https://github.com/lazylace37.png" alt="@lazylace37" width="50" />](https://github.com/lazylace37)
135
+ [<img src="https://github.com/leosuncin.png" alt="@leosuncin" width="50" />](https://github.com/leosuncin)
136
+ [<img src="https://github.com/kirdk.png" alt="@kirdk" width="50" />](https://github.com/kirdk)
137
+ [<img src="https://github.com/johngeorgewright.png" alt="@johngeorgewright" width="50" />](https://github.com/johngeorgewright)
138
+ [<img src="https://github.com/ssteuteville.png" alt="@ssteuteville" width="50" />](https://github.com/ssteuteville)
139
+ [<img src="https://github.com/foxfirecodes.png" alt="@foxfirecodes" width="50" />](https://github.com/foxfirecodes)
140
+ [<img src="https://github.com/HardCoreQual.png" alt="@HardCoreQual" width="50" />](https://github.com/HardCoreQual)
141
+ [<img src="https://github.com/hellovai.png" alt="@hellovai" width="50" />](https://github.com/hellovai)
142
+ [<img src="https://github.com/Isaac-Leonard.png" alt="@Isaac-Leonard" width="50" />](https://github.com/Isaac-Leonard)
143
+ [<img src="https://github.com/digimuza.png" alt="@digimuza" width="50" />](https://github.com/digimuza)
144
+ [<img src="https://github.com/glitch452.png" alt="@glitch452" width="50" />](https://github.com/glitch452)
144
145
 
145
146
  # How it works
146
147
 
@@ -149,7 +150,7 @@ These people contributed to the improvement of the framework by reporting bugs,
149
150
  The API operates object schemas for input and output validation.
150
151
  The object being validated is the combination of certain `request` properties.
151
152
  It is available to the endpoint handler as the `input` parameter.
152
- Middlewares have access to all `request` properties, they can provide endpoints with `options`.
153
+ Middlewares have access to all `request` properties, they can provide endpoints with `ctx` (context).
153
154
  The object returned by the endpoint handler is called `output`. It goes to the `ResultHandler` which is
154
155
  responsible for transmitting consistent responses containing the `output` or possible error.
155
156
  Much can be customized to fit your needs.
@@ -185,12 +186,6 @@ pnpm add -D @types/express @types/node @types/http-errors
185
186
 
186
187
  ## Environment preparation
187
188
 
188
- Ensure running your code as [ESM](https://nodejs.org/api/esm.html#enabling) by either:
189
-
190
- - setting `"type": "module"` in your `package.json`;
191
- - or using `.mts` file extension;
192
- - or using `tsx` or `vite-node` or similar tools.
193
-
194
189
  Enable the following `compilerOptions` in your `tsconfig.json` to make it work as expected:
195
190
 
196
191
  ```json
@@ -233,8 +228,8 @@ const helloWorldEndpoint = defaultEndpointsFactory.build({
233
228
  output: z.object({
234
229
  greetings: z.string(),
235
230
  }),
236
- handler: async ({ input: { name }, options, logger }) => {
237
- logger.debug("Options:", options); // middlewares provide options
231
+ handler: async ({ input: { name }, ctx, logger }) => {
232
+ logger.debug("Context:", ctx); // middlewares provide ctx
238
233
  return { greetings: `Hello, ${name || "World"}. Happy coding!` };
239
234
  },
240
235
  });
@@ -288,7 +283,7 @@ in one place, illustrating how you can structure your API using whichever method
288
283
  architecture — or even mix them seamlessly.
289
284
 
290
285
  ```ts
291
- import { Routing, DependsOnMethod, ServeStatic } from "express-zod-api";
286
+ import { Routing, ServeStatic } from "express-zod-api";
292
287
 
293
288
  const routing: Routing = {
294
289
  // flat syntax — /v1/users
@@ -306,12 +301,12 @@ const routing: Routing = {
306
301
  // mixed syntax with explicit method — /v1/user/:id
307
302
  "delete /user/:id": deleteUserEndpoint,
308
303
  // method-based routing — /v1/account
309
- account: new DependsOnMethod({
304
+ account: {
310
305
  get: endpointA,
311
306
  delete: endpointA,
312
307
  post: endpointB,
313
308
  patch: endpointB,
314
- }),
309
+ },
315
310
  },
316
311
  // static file serving — /public serves files from ./assets
317
312
  public: new ServeStatic("assets", {
@@ -329,7 +324,7 @@ When the method is not specified, the one(s) supported by the Endpoint applied (
329
324
 
330
325
  ## Middlewares
331
326
 
332
- Middleware can authenticate using input or `request` headers, and can provide endpoint handlers with `options`.
327
+ Middleware can authenticate using input or `request` headers, and can provide endpoint handlers with `ctx`.
333
328
  Inputs of middlewares are also available to endpoint handlers within `input`.
334
329
 
335
330
  Here is an example of the authentication middleware, that checks a `key` from input and `token` from headers:
@@ -356,7 +351,7 @@ const authMiddleware = new Middleware({
356
351
  if (!user) throw createHttpError(401, "Invalid key");
357
352
  if (request.headers.token !== user.token)
358
353
  throw createHttpError(401, "Invalid token");
359
- return { user }; // provides endpoints with options.user
354
+ return { user }; // provides endpoints with ctx.user
360
355
  },
361
356
  });
362
357
  ```
@@ -367,7 +362,7 @@ By using `.addMiddleware()` method before `.build()` you can connect it to the e
367
362
  const yourEndpoint = defaultEndpointsFactory
368
363
  .addMiddleware(authMiddleware)
369
364
  .build({
370
- handler: async ({ options: { user } }) => {
365
+ handler: async ({ ctx: { user } }) => {
371
366
  // user is the one returned by authMiddleware
372
367
  }, // ...
373
368
  });
@@ -375,7 +370,7 @@ const yourEndpoint = defaultEndpointsFactory
375
370
 
376
371
  You can create a new factory by connecting as many middlewares as you want — they will be executed in the specified
377
372
  order for all the endpoints produced on that factory. You may also use a shorter inline syntax within the
378
- `.addMiddleware()` method, and have access to the output of the previously executed middlewares in chain as `options`:
373
+ `.addMiddleware()` method, and have access to the output of the previously executed middlewares in chain as `ctx`:
379
374
 
380
375
  ```ts
381
376
  import { defaultEndpointsFactory } from "express-zod-api";
@@ -383,20 +378,20 @@ import { defaultEndpointsFactory } from "express-zod-api";
383
378
  const factory = defaultEndpointsFactory
384
379
  .addMiddleware(authMiddleware) // add Middleware instance or use shorter syntax:
385
380
  .addMiddleware({
386
- handler: async ({ options: { user } }) => ({}), // user from authMiddleware
381
+ handler: async ({ ctx: { user } }) => ({}), // user from authMiddleware
387
382
  });
388
383
  ```
389
384
 
390
- ## Options
385
+ ## Context
391
386
 
392
- In case you'd like to provide your endpoints with options that do not depend on Request, like non-persistent connection
393
- to a database, consider shorthand method `addOptions`. For static options consider reusing `const` across your files.
387
+ If you need to provide your endpoints with a context that does not depend on Request, like non-persistent database
388
+ connection, consider shorthand method `addContext`. For static values consider reusing a `const` across your files.
394
389
 
395
390
  ```ts
396
391
  import { readFile } from "node:fs/promises";
397
392
  import { defaultEndpointsFactory } from "express-zod-api";
398
393
 
399
- const endpointsFactory = defaultEndpointsFactory.addOptions(async () => {
394
+ const endpointsFactory = defaultEndpointsFactory.addContext(async () => {
400
395
  // caution: new connection on every request:
401
396
  const db = mongoose.connect("mongodb://connection.string");
402
397
  const privateKey = await readFile("private-key.pem", "utf-8");
@@ -411,10 +406,10 @@ custom [Result Handler](#response-customization):
411
406
  import { ResultHandler } from "express-zod-api";
412
407
 
413
408
  const resultHandlerWithCleanup = new ResultHandler({
414
- handler: ({ options }) => {
415
- // necessary to check for certain option presence:
416
- if ("db" in options && options.db) {
417
- options.db.connection.close(); // sample cleanup
409
+ handler: ({ ctx }) => {
410
+ // necessary to check the presence of a certain property:
411
+ if ("db" in ctx && ctx.db) {
412
+ ctx.db.connection.close(); // sample cleanup
418
413
  }
419
414
  },
420
415
  });
@@ -446,7 +441,7 @@ const config = createConfig({
446
441
 
447
442
  In case you need a special processing of `request`, or to modify the `response` for selected endpoints, use the method
448
443
  `addExpressMiddleware()` of `EndpointsFactory` (or its alias `use()`). The method has two optional features: a provider
449
- of [options](#options) and an error transformer for adjusting the response status code.
444
+ of a [context](#context) and an error transformer for adjusting the response status code.
450
445
 
451
446
  ```ts
452
447
  import { defaultEndpointsFactory } from "express-zod-api";
@@ -1045,8 +1040,8 @@ test("should respond successfully", async () => {
1045
1040
 
1046
1041
  ## Testing middlewares
1047
1042
 
1048
- Middlewares can also be tested individually using the `testMiddleware()` method. You can also pass `options` collected
1049
- from outputs of previous middlewares, if the one being tested somehow depends on them. Possible errors would be handled
1043
+ Middlewares can also be tested individually using the `testMiddleware()` method. You can also pass `ctx` collected
1044
+ from returns of previous middlewares, if the one being tested somehow depends on it. Possible errors would be handled
1050
1045
  either by `errorHandler` configured within given `configProps` or `defaultResultHandler`.
1051
1046
 
1052
1047
  ```ts
@@ -1055,8 +1050,8 @@ import { Middleware, testMiddleware } from "express-zod-api";
1055
1050
 
1056
1051
  const middleware = new Middleware({
1057
1052
  input: z.object({ test: z.string() }),
1058
- handler: async ({ options, input: { test } }) => ({
1059
- collectedOptions: Object.keys(options),
1053
+ handler: async ({ ctx, input: { test } }) => ({
1054
+ collectedContext: Object.keys(ctx),
1060
1055
  testLength: test.length,
1061
1056
  }),
1062
1057
  });
@@ -1064,10 +1059,10 @@ const middleware = new Middleware({
1064
1059
  const { output, responseMock, loggerMock } = await testMiddleware({
1065
1060
  middleware,
1066
1061
  requestProps: { method: "POST", body: { test: "something" } },
1067
- options: { prev: "accumulated" }, // responseOptions, configProps, loggerProps
1062
+ ctx: { prev: "accumulated" }, // responseOptions, configProps, loggerProps
1068
1063
  });
1069
1064
  expect(loggerMock._getLogs().error).toHaveLength(0);
1070
- expect(output).toEqual({ collectedOptions: ["prev"], testLength: 9 });
1065
+ expect(output).toEqual({ collectedContext: ["prev"], testLength: 9 });
1071
1066
  ```
1072
1067
 
1073
1068
  # Integration and Documentation
@@ -1087,6 +1082,7 @@ import { Integration } from "express-zod-api";
1087
1082
 
1088
1083
  const client = new Integration({
1089
1084
  routing,
1085
+ config,
1090
1086
  variant: "client", // <— optional, see also "types" for a DIY solution
1091
1087
  });
1092
1088
 
@@ -1183,11 +1179,11 @@ new Documentation({
1183
1179
  ## Deprecated schemas and routes
1184
1180
 
1185
1181
  As your API evolves, you may need to mark some parameters or routes as deprecated before deleting them. For this
1186
- purpose, the `.deprecated()` method is available on each schema, `Endpoint` and `DependsOnMethod`, it's immutable.
1182
+ purpose, the `.deprecated()` method is available on each schema and `Endpoint`, it's immutable.
1187
1183
  You can also deprecate all routes the `Endpoint` assigned to by setting `EndpointsFactory::build({ deprecated: true })`.
1188
1184
 
1189
1185
  ```ts
1190
- import { Routing, DependsOnMethod } from "express-zod-api";
1186
+ import { Routing } from "express-zod-api";
1191
1187
  import { z } from "zod";
1192
1188
 
1193
1189
  const someEndpoint = factory.build({
@@ -1199,8 +1195,7 @@ const someEndpoint = factory.build({
1199
1195
 
1200
1196
  const routing: Routing = {
1201
1197
  v1: oldEndpoint.deprecated(), // deprecates the /v1 path
1202
- v2: new DependsOnMethod({ get: oldEndpoint }).deprecated(), // deprecates the /v2 path
1203
- v3: someEndpoint, // the path is assigned with initially deprecated endpoint (also deprecated)
1198
+ v2: someEndpoint, // the path is assigned with initially deprecated endpoint (also deprecated)
1204
1199
  };
1205
1200
  ```
1206
1201
 
@@ -1378,7 +1373,7 @@ const subscriptionEndpoint = new EventStreamFactory({
1378
1373
  time: z.int().positive(),
1379
1374
  }).buildVoid({
1380
1375
  input: z.object({}), // optional input schema
1381
- handler: async ({ options: { emit, isClosed, signal } }) => {
1376
+ handler: async ({ ctx: { emit, isClosed, signal } }) => {
1382
1377
  while (!isClosed()) {
1383
1378
  emit("time", Date.now());
1384
1379
  await setTimeout(1000);
@@ -1395,11 +1390,6 @@ framework, [Zod Sockets](https://github.com/RobinTail/zod-sockets), which has si
1395
1390
  There are some well-known issues and limitations, or third party bugs that cannot be fixed in the usual way, but you
1396
1391
  should be aware of them.
1397
1392
 
1398
- ## TypeError: example is not a function
1399
-
1400
- If you face this error then [switch your environment to ESM](#environment-preparation).
1401
- See [issue 2981](https://github.com/RobinTail/express-zod-api/issues/2981) for details.
1402
-
1403
1393
  ## Excessive properties in endpoint output
1404
1394
 
1405
1395
  The schema validator removes excessive properties by default. However, Typescript
package/dist/index.d.ts CHANGED
@@ -15,8 +15,8 @@ import compression from "compression";
15
15
  import * as express_fileupload0 from "express-fileupload";
16
16
  import fileUpload from "express-fileupload";
17
17
  import { ListenOptions } from "node:net";
18
- import * as express_serve_static_core2 from "express-serve-static-core";
19
- import * as qs2 from "qs";
18
+ import * as express_serve_static_core0 from "express-serve-static-core";
19
+ import * as qs0 from "qs";
20
20
  import * as zod_v4_core0 from "zod/v4/core";
21
21
 
22
22
  //#region src/method.d.ts
@@ -237,31 +237,31 @@ interface OAuth2Security<S$1 extends string> {
237
237
  type Security<K$1 extends string = string, S$1 extends string = string> = BasicSecurity | BearerSecurity | InputSecurity<K$1> | HeaderSecurity | CookieSecurity | OpenIdSecurity | OAuth2Security<S$1>;
238
238
  //#endregion
239
239
  //#region src/middleware.d.ts
240
- type Handler$2<IN, OPT, OUT> = (params: {
240
+ type Handler$2<IN, CTX, RET> = (params: {
241
241
  /** @desc The inputs from the enabled input sources validated against the input schema of the Middleware */
242
242
  input: IN;
243
243
  /**
244
244
  * @desc The returns of the previously executed Middlewares (typed when chaining Middlewares)
245
245
  * @link https://github.com/RobinTail/express-zod-api/discussions/1250
246
246
  * */
247
- options: OPT;
247
+ ctx: CTX;
248
248
  /** @link https://expressjs.com/en/5x/api.html#req */
249
249
  request: Request;
250
250
  /** @link https://expressjs.com/en/5x/api.html#res */
251
251
  response: Response;
252
252
  /** @desc The instance of the configured logger */
253
253
  logger: ActualLogger;
254
- }) => Promise<OUT>;
254
+ }) => Promise<RET>;
255
255
  declare abstract class AbstractMiddleware {
256
256
  abstract execute(params: {
257
257
  input: unknown;
258
- options: FlatObject;
258
+ ctx: FlatObject;
259
259
  request: Request;
260
260
  response: Response;
261
261
  logger: ActualLogger;
262
262
  }): Promise<FlatObject>;
263
263
  }
264
- declare class Middleware<OPT extends FlatObject, OUT extends FlatObject, SCO extends string, IN extends IOSchema | undefined = undefined> extends AbstractMiddleware {
264
+ declare class Middleware<CTX extends FlatObject, RET extends FlatObject, SCO extends string, IN extends IOSchema | undefined = undefined> extends AbstractMiddleware {
265
265
  #private;
266
266
  constructor({
267
267
  input,
@@ -276,8 +276,8 @@ declare class Middleware<OPT extends FlatObject, OUT extends FlatObject, SCO ext
276
276
  input?: IN;
277
277
  /** @desc Declaration of the security schemas implemented within the handler */
278
278
  security?: LogicalContainer<Security<Extract<keyof z.input<IN>, string>, SCO>>;
279
- /** @desc The handler returning options available to Endpoints */
280
- handler: Handler$2<z.output<IN>, OPT, OUT>;
279
+ /** @desc The handler returning a context available to Endpoints */
280
+ handler: Handler$2<z.output<IN>, CTX, RET>;
281
281
  });
282
282
  /** @throws InputValidationError */
283
283
  execute({
@@ -285,36 +285,22 @@ declare class Middleware<OPT extends FlatObject, OUT extends FlatObject, SCO ext
285
285
  ...rest
286
286
  }: {
287
287
  input: unknown;
288
- options: OPT;
288
+ ctx: CTX;
289
289
  request: Request;
290
290
  response: Response;
291
291
  logger: ActualLogger;
292
- }): Promise<OUT>;
292
+ }): Promise<RET>;
293
293
  }
294
- declare class ExpressMiddleware<R extends Request, S$1 extends Response, OUT extends FlatObject> extends Middleware<FlatObject, OUT, string> {
294
+ declare class ExpressMiddleware<R extends Request, S$1 extends Response, RET extends FlatObject> extends Middleware<FlatObject, RET, string> {
295
295
  constructor(nativeMw: (request: R, response: S$1, next: NextFunction) => any, {
296
296
  provider,
297
297
  transformer
298
298
  }?: {
299
- provider?: (request: R, response: S$1) => OUT | Promise<OUT>;
299
+ provider?: (request: R, response: S$1) => RET | Promise<RET>;
300
300
  transformer?: (err: Error) => Error;
301
301
  });
302
302
  }
303
303
  //#endregion
304
- //#region src/depends-on-method.d.ts
305
- declare class DependsOnMethod extends Routable {
306
- #private;
307
- constructor(endpoints: Partial<Record<Method, AbstractEndpoint>>);
308
- deprecated(): this;
309
- }
310
- //#endregion
311
- //#region src/serve-static.d.ts
312
- type OriginalStatic = typeof express.static;
313
- declare class ServeStatic {
314
- #private;
315
- constructor(...params: Parameters<OriginalStatic>);
316
- }
317
- //#endregion
318
304
  //#region src/result-helpers.d.ts
319
305
  type ResultSchema<R extends Result> = R extends Result<infer S> ? S : never;
320
306
  type DiscriminatedResult = {
@@ -335,7 +321,7 @@ type Handler$1<RES = unknown> = (params: DiscriminatedResult & {
335
321
  /** null in case of failure to parse or to find the matching endpoint (error: not found) */
336
322
  input: FlatObject | null;
337
323
  /** can be empty: check presence of the required property using "in" operator */
338
- options: FlatObject;
324
+ ctx: FlatObject;
339
325
  request: Request;
340
326
  response: Response<RES>;
341
327
  logger: ActualLogger;
@@ -377,6 +363,13 @@ declare const arrayResultHandler: ResultHandler<z.ZodArray<z.core.$ZodType<unkno
377
363
  mimeType: string;
378
364
  }>;
379
365
  //#endregion
366
+ //#region src/serve-static.d.ts
367
+ type OriginalStatic = typeof express.static;
368
+ declare class ServeStatic {
369
+ #private;
370
+ constructor(...params: Parameters<OriginalStatic>);
371
+ }
372
+ //#endregion
380
373
  //#region src/server-helpers.d.ts
381
374
  /** @desc Returns child logger for the given request (if configured) or the configured logger otherwise */
382
375
  type GetLogger = (request?: Request) => ActualLogger;
@@ -387,29 +380,27 @@ type GetLogger = (request?: Request) => ActualLogger;
387
380
  * @example { "v1/books/:bookId": getBookEndpoint }
388
381
  * @example { "get /v1/books/:bookId": getBookEndpoint }
389
382
  * @example { v1: { "patch /books/:bookId": changeBookEndpoint } }
383
+ * @example { dependsOnMethod: { get: retrieveEndpoint, post: createEndpoint } }
384
+ * @see CommonConfig.methodLikeRouteBehavior
390
385
  * */
391
386
  interface Routing {
392
- [K: string]: Routing | DependsOnMethod | AbstractEndpoint | ServeStatic;
393
- }
394
- //#endregion
395
- //#region src/routable.d.ts
396
- declare abstract class Routable {
397
- /** @desc Marks the route as deprecated (makes a copy of the endpoint) */
398
- abstract deprecated(): this;
399
- /** @desc Enables nested routes within the path assigned to the subject */
400
- nest(routing: Routing): Routing;
387
+ [K: string]: Routing | AbstractEndpoint | ServeStatic;
401
388
  }
402
389
  //#endregion
403
390
  //#region src/endpoint.d.ts
404
- type Handler<IN, OUT, OPT> = (params: {
391
+ type Handler<IN, OUT, CTX> = (params: {
405
392
  /** @desc The inputs from the enabled input sources validated against the final input schema (incl. Middlewares) */
406
393
  input: IN;
407
394
  /** @desc The returns of the assigned Middlewares */
408
- options: OPT;
395
+ ctx: CTX;
409
396
  /** @desc The instance of the configured logger */
410
397
  logger: ActualLogger;
411
398
  }) => Promise<OUT>;
412
- declare abstract class AbstractEndpoint extends Routable {
399
+ declare abstract class AbstractEndpoint {
400
+ /** @desc Enables nested routes within the path assigned to the subject */
401
+ nest(routing: Routing): Routing;
402
+ /** @desc Marks the route as deprecated (makes a copy of the endpoint) */
403
+ abstract deprecated(): this;
413
404
  abstract execute(params: {
414
405
  request: Request;
415
406
  response: Response;
@@ -417,14 +408,14 @@ declare abstract class AbstractEndpoint extends Routable {
417
408
  config: CommonConfig;
418
409
  }): Promise<void>;
419
410
  }
420
- declare class Endpoint<IN extends IOSchema, OUT extends IOSchema, OPT extends FlatObject> extends AbstractEndpoint {
411
+ declare class Endpoint<IN extends IOSchema, OUT extends IOSchema, CTX extends FlatObject> extends AbstractEndpoint {
421
412
  #private;
422
413
  constructor(def: {
423
414
  deprecated?: boolean;
424
415
  middlewares?: AbstractMiddleware[];
425
416
  inputSchema: IN;
426
417
  outputSchema: OUT;
427
- handler: Handler<z.output<IN>, z.input<OUT>, OPT>;
418
+ handler: Handler<z.output<IN>, z.input<OUT>, CTX>;
428
419
  resultHandler: AbstractResultHandler;
429
420
  description?: string;
430
421
  shortDescription?: string;
@@ -477,6 +468,14 @@ interface CommonConfig {
477
468
  * @default 405
478
469
  * */
479
470
  wrongMethodBehavior?: 404 | 405;
471
+ /**
472
+ * @desc How to treat Routing keys that look like methods (when assigned with an Endpoint)
473
+ * @see Method
474
+ * @example "method" — the key is treated as method of its parent path
475
+ * @example "path" — the key is treated as a nested path segment
476
+ * @default "method"
477
+ * */
478
+ methodLikeRouteBehavior?: "method" | "path";
480
479
  /**
481
480
  * @desc The ResultHandler to use for handling routing, parsing and upload errors
482
481
  * @default defaultResultHandler
@@ -627,7 +626,7 @@ declare function createConfig(config: ServerConfig): ServerConfig;
627
626
  declare function createConfig(config: AppConfig): AppConfig;
628
627
  //#endregion
629
628
  //#region src/endpoints-factory.d.ts
630
- interface BuildProps<IN extends IOSchema, OUT extends IOSchema | z.ZodVoid, MIN extends IOSchema | undefined, OPT extends FlatObject, SCO extends string> {
629
+ interface BuildProps<IN extends IOSchema, OUT extends IOSchema | z.ZodVoid, MIN extends IOSchema | undefined, CTX extends FlatObject, SCO extends string> {
631
630
  /**
632
631
  * @desc Input schema of the Endpoint, combining properties from all the enabled input sources (path params, headers)
633
632
  * @default z.object({})
@@ -636,8 +635,8 @@ interface BuildProps<IN extends IOSchema, OUT extends IOSchema | z.ZodVoid, MIN
636
635
  input?: IN;
637
636
  /** @desc The schema by which the returns of the Endpoint handler is validated */
638
637
  output: OUT;
639
- /** @desc The Endpoint handler receiving the validated inputs, returns of added Middlewares (options) and a logger */
640
- handler: Handler<z.output<FinalInputSchema<MIN, IN>>, z.input<OUT>, OPT>;
638
+ /** @desc The Endpoint handler receiving the validated inputs, returns of added Middlewares (ctx) and a logger */
639
+ handler: Handler<z.output<FinalInputSchema<MIN, IN>>, z.input<OUT>, CTX>;
641
640
  /** @desc The operation description for the generated Documentation */
642
641
  description?: string;
643
642
  /** @desc The operation summary for the generated Documentation (50 symbols max) */
@@ -646,8 +645,7 @@ interface BuildProps<IN extends IOSchema, OUT extends IOSchema | z.ZodVoid, MIN
646
645
  operationId?: string | ((method: ClientMethod) => string);
647
646
  /**
648
647
  * @desc HTTP method(s) this endpoint can handle
649
- * @default "get" unless the Endpoint is assigned within DependsOnMethod
650
- * @see DependsOnMethod
648
+ * @default "get" unless method is explicitly defined in Routing keys
651
649
  * */
652
650
  method?: Method | [Method, ...Method[]];
653
651
  /**
@@ -663,19 +661,19 @@ interface BuildProps<IN extends IOSchema, OUT extends IOSchema | z.ZodVoid, MIN
663
661
  /** @desc Marks the operation deprecated in the generated Documentation */
664
662
  deprecated?: boolean;
665
663
  }
666
- declare class EndpointsFactory<IN extends IOSchema | undefined = undefined, OUT extends FlatObject = EmptyObject, SCO extends string = string> {
664
+ declare class EndpointsFactory<IN extends IOSchema | undefined = undefined, CTX extends FlatObject = EmptyObject, SCO extends string = string> {
667
665
  #private;
668
666
  protected resultHandler: AbstractResultHandler;
669
667
  protected schema: IN;
670
668
  protected middlewares: AbstractMiddleware[];
671
669
  constructor(resultHandler: AbstractResultHandler);
672
- addMiddleware<AOUT extends FlatObject, ASCO extends string, AIN extends IOSchema | undefined = undefined>(subject: Middleware<OUT, AOUT, ASCO, AIN> | ConstructorParameters<typeof Middleware<OUT, AOUT, ASCO, AIN>>[0]): EndpointsFactory<Extension<IN, AIN>, OUT & AOUT, SCO & ASCO>;
670
+ addMiddleware<RET extends FlatObject, ASCO extends string, AIN extends IOSchema | undefined = undefined>(subject: Middleware<CTX, RET, ASCO, AIN> | ConstructorParameters<typeof Middleware<CTX, RET, ASCO, AIN>>[0]): EndpointsFactory<Extension<IN, AIN>, CTX & RET, SCO & ASCO>;
673
671
  use: <R extends Request, S$1 extends Response, AOUT extends FlatObject = Record<string, never>>(nativeMw: (request: R, response: S$1, next: express0.NextFunction) => any, params_1?: {
674
672
  provider?: ((request: R, response: S$1) => AOUT | Promise<AOUT>) | undefined;
675
673
  transformer?: (err: Error) => Error;
676
- } | undefined) => EndpointsFactory<Extension<IN, undefined>, OUT & AOUT, SCO>;
677
- addExpressMiddleware<R extends Request, S$1 extends Response, AOUT extends FlatObject = EmptyObject>(...params: ConstructorParameters<typeof ExpressMiddleware<R, S$1, AOUT>>): EndpointsFactory<Extension<IN, undefined>, OUT & AOUT, SCO>;
678
- addOptions<AOUT extends FlatObject>(getOptions: () => Promise<AOUT>): EndpointsFactory<Extension<IN, undefined>, OUT & AOUT, SCO>;
674
+ } | undefined) => EndpointsFactory<Extension<IN, undefined>, CTX & AOUT, SCO>;
675
+ addExpressMiddleware<R extends Request, S$1 extends Response, AOUT extends FlatObject = EmptyObject>(...params: ConstructorParameters<typeof ExpressMiddleware<R, S$1, AOUT>>): EndpointsFactory<Extension<IN, undefined>, CTX & AOUT, SCO>;
676
+ addContext<RET extends FlatObject>(getContext: () => Promise<RET>): EndpointsFactory<Extension<IN, undefined>, CTX & RET, SCO>;
679
677
  build<BOUT extends IOSchema, BIN extends IOSchema = EmptySchema>({
680
678
  input,
681
679
  output: outputSchema,
@@ -684,12 +682,12 @@ declare class EndpointsFactory<IN extends IOSchema | undefined = undefined, OUT
684
682
  tag,
685
683
  method,
686
684
  ...rest
687
- }: BuildProps<BIN, BOUT, IN, OUT, SCO>): Endpoint<FinalInputSchema<IN, BIN>, BOUT, OUT>;
685
+ }: BuildProps<BIN, BOUT, IN, CTX, SCO>): Endpoint<FinalInputSchema<IN, BIN>, BOUT, CTX>;
688
686
  /** @desc shorthand for returning {} while having output schema z.object({}) */
689
687
  buildVoid<BIN extends IOSchema = EmptySchema>({
690
688
  handler,
691
689
  ...rest
692
- }: Omit<BuildProps<BIN, z.ZodVoid, IN, OUT, SCO>, "output">): Endpoint<FinalInputSchema<IN, BIN>, z.ZodObject<{}, z.core.$strip>, OUT>;
690
+ }: Omit<BuildProps<BIN, z.ZodVoid, IN, CTX, SCO>, "output">): Endpoint<FinalInputSchema<IN, BIN>, z.ZodObject<{}, z.core.$strip>, CTX>;
693
691
  }
694
692
  declare const defaultEndpointsFactory: EndpointsFactory<undefined, Record<string, never>, string>;
695
693
  /**
@@ -701,11 +699,11 @@ declare const arrayEndpointsFactory: EndpointsFactory<undefined, Record<string,
701
699
  //#endregion
702
700
  //#region src/server.d.ts
703
701
  declare const attachRouting: (config: AppConfig, routing: Routing) => {
704
- notFoundHandler: express.RequestHandler<express_serve_static_core2.ParamsDictionary, any, any, qs2.ParsedQs, Record<string, any>>;
702
+ notFoundHandler: express.RequestHandler<express_serve_static_core0.ParamsDictionary, any, any, qs0.ParsedQs, Record<string, any>>;
705
703
  logger: AbstractLogger | BuiltinLogger;
706
704
  };
707
705
  declare const createServer: (config: ServerConfig, routing: Routing) => Promise<{
708
- app: express_serve_static_core2.Express;
706
+ app: express_serve_static_core0.Express;
709
707
  logger: AbstractLogger | BuiltinLogger;
710
708
  servers: (http.Server<typeof http.IncomingMessage, typeof http.ServerResponse> | https.Server<typeof http.IncomingMessage, typeof http.ServerResponse>)[];
711
709
  }>;
@@ -754,6 +752,7 @@ interface DocumentationParams {
754
752
  /**
755
753
  * @desc Depict the HEAD method for each Endpoint supporting the GET method (feature of Express)
756
754
  * @default true
755
+ * @todo move to config
757
756
  * */
758
757
  hasHeadMethod?: boolean;
759
758
  /** @default inline */
@@ -870,26 +869,26 @@ declare const testEndpoint: <LOG extends FlatObject, REQ extends RequestOptions>
870
869
  /** @desc The endpoint to test */
871
870
  endpoint: AbstractEndpoint;
872
871
  }) => Promise<{
873
- requestMock: node_mocks_http0.MockRequest<Request<express_serve_static_core2.ParamsDictionary, any, any, qs2.ParsedQs, Record<string, any>> & REQ>;
872
+ requestMock: node_mocks_http0.MockRequest<Request<express_serve_static_core0.ParamsDictionary, any, any, qs0.ParsedQs, Record<string, any>> & REQ>;
874
873
  responseMock: node_mocks_http0.MockResponse<Response<any, Record<string, any>>>;
875
874
  loggerMock: AbstractLogger & LOG & {
876
- _getLogs: () => Record<"error" | "debug" | "info" | "warn", unknown[]>;
875
+ _getLogs: () => Record<"debug" | "info" | "warn" | "error", unknown[]>;
877
876
  };
878
877
  }>;
879
878
  declare const testMiddleware: <LOG extends FlatObject, REQ extends RequestOptions>({
880
879
  middleware,
881
- options,
880
+ ctx,
882
881
  ...rest
883
882
  }: TestingProps<REQ, LOG> & {
884
883
  /** @desc The middleware to test */
885
884
  middleware: AbstractMiddleware;
886
- /** @desc The aggregated output from previously executed middlewares */
887
- options?: FlatObject;
885
+ /** @desc The aggregated returns of previously executed middlewares */
886
+ ctx?: FlatObject;
888
887
  }) => Promise<{
889
- requestMock: node_mocks_http0.MockRequest<Request<express_serve_static_core2.ParamsDictionary, any, any, qs2.ParsedQs, Record<string, any>> & REQ>;
888
+ requestMock: node_mocks_http0.MockRequest<Request<express_serve_static_core0.ParamsDictionary, any, any, qs0.ParsedQs, Record<string, any>> & REQ>;
890
889
  responseMock: node_mocks_http0.MockResponse<Response<any, Record<string, any>>>;
891
890
  loggerMock: AbstractLogger & LOG & {
892
- _getLogs: () => Record<"error" | "debug" | "info" | "warn", unknown[]>;
891
+ _getLogs: () => Record<"debug" | "info" | "warn" | "error", unknown[]>;
893
892
  };
894
893
  output: FlatObject;
895
894
  }>;
@@ -923,6 +922,7 @@ type Producer = SchemaHandler<ts.TypeNode, ZTSContext>;
923
922
  //#region src/integration.d.ts
924
923
  interface IntegrationParams {
925
924
  routing: Routing;
925
+ config: CommonConfig;
926
926
  /**
927
927
  * @desc What should be generated
928
928
  * @example "types" — types of your endpoint requests and responses (for a DIY solution)
@@ -947,6 +947,7 @@ interface IntegrationParams {
947
947
  /**
948
948
  * @desc Depict the HEAD method for each Endpoint supporting the GET method (feature of Express)
949
949
  * @default true
950
+ * @todo move to config
950
951
  * */
951
952
  hasHeadMethod?: boolean;
952
953
  /**
@@ -970,6 +971,7 @@ declare class Integration extends IntegrationBase {
970
971
  #private;
971
972
  constructor({
972
973
  routing,
974
+ config,
973
975
  brandHandling,
974
976
  variant,
975
977
  clientClassName,
@@ -1035,4 +1037,4 @@ declare const ez: {
1035
1037
  buffer: () => zod_v4_core0.$ZodBranded<zod0.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>, symbol>;
1036
1038
  };
1037
1039
  //#endregion
1038
- export { type ApiResponse, type AppConfig, type BasicSecurity, type BearerSecurity, BuiltinLogger, type CommonConfig, type CookieSecurity, DependsOnMethod, type Depicter, Documentation, DocumentationError, EndpointsFactory, EventStreamFactory, type FlatObject, type HeaderSecurity, type IOSchema, type InputSecurity, InputValidationError, Integration, type LoggerOverrides, type Method, Middleware, MissingPeerError, type OAuth2Security, type OpenIdSecurity, OutputValidationError, type Producer, ResultHandler, type Routing, RoutingError, ServeStatic, type ServerConfig, type TagOverrides, arrayEndpointsFactory, arrayResultHandler, attachRouting, createConfig, createServer, defaultEndpointsFactory, defaultResultHandler, ensureHttpError, ez, getMessageFromError, testEndpoint, testMiddleware };
1040
+ export { type ApiResponse, type AppConfig, type BasicSecurity, type BearerSecurity, BuiltinLogger, type CommonConfig, type CookieSecurity, type Depicter, Documentation, DocumentationError, EndpointsFactory, EventStreamFactory, type FlatObject, type HeaderSecurity, type IOSchema, type InputSecurity, InputValidationError, Integration, type LoggerOverrides, type Method, Middleware, MissingPeerError, type OAuth2Security, type OpenIdSecurity, OutputValidationError, type Producer, ResultHandler, type Routing, RoutingError, ServeStatic, type ServerConfig, type TagOverrides, arrayEndpointsFactory, arrayResultHandler, attachRouting, createConfig, createServer, defaultEndpointsFactory, defaultResultHandler, ensureHttpError, ez, getMessageFromError, testEndpoint, testMiddleware };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import{getBrand as e}from"@express-zod-api/zod-plugin";import*as t from"ramda";import{globalRegistry as n,z as r}from"zod";import i,{isHttpError as a}from"http-errors";import o,{blue as s,cyanBright as c,gray as l,green as u,hex as d,italic as f,red as p,whiteBright as m}from"ansis";import{inspect as ee}from"node:util";import{performance as h}from"node:perf_hooks";import g from"express";import te from"node:http";import ne from"node:https";import{setInterval as re}from"node:timers/promises";import{OpenApiBuilder as ie,isReferenceObject as ae,isSchemaObject as _}from"openapi3-ts/oas31";import{createRequest as oe,createResponse as se}from"node-mocks-http";import v from"typescript";function ce(e){return e}const y={json:`application/json`,upload:`multipart/form-data`,raw:`application/octet-stream`,sse:`text/event-stream`,form:`application/x-www-form-urlencoded`},le=[`get`,`post`,`put`,`delete`,`patch`],ue=[...le,`head`],b=e=>le.includes(e),de=r.object({}),fe=/:([A-Za-z0-9_]+)/g,pe=e=>e.match(fe)?.map(e=>e.slice(1))||[],me=e=>{let t=(e.header(`content-type`)||``).toLowerCase().startsWith(y.upload);return`files`in e&&t},he={get:[`query`,`params`],post:[`body`,`params`,`files`],put:[`body`,`params`],patch:[`body`,`params`],delete:[`query`,`params`]},ge=[`body`,`query`,`params`],_e=e=>e.method.toLowerCase(),ve=(e,t={})=>{if(e===`options`)return[];let n=e===`head`?`get`:b(e)?e:void 0;return(n?t[n]||he[n]:void 0)||ge},ye=(e,t={})=>ve(_e(e),t).filter(t=>t===`files`?me(e):!0).reduce((t,n)=>Object.assign(t,e[n]),{}),x=e=>e instanceof Error?e:e instanceof r.ZodError?new r.ZodRealError(e.issues):Error(String(e)),S=e=>e instanceof r.ZodError?e.issues.map(({path:e,message:t})=>`${e.length?`${r.core.toDotPath(e)}: `:``}${t}`).join(`; `):e.message,C=(e,n)=>T(e)&&`_zod`in e&&(n?t.path([`_zod`,`def`,`type`],e)===n:!0),be=(e,n,r)=>e.length&&n.length?t.xprod(e,n).map(r):e.concat(n),xe=e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase(),w=(...e)=>{let n=t.chain(e=>e.split(/[^A-Z0-9]/gi),e);return t.chain(e=>e.replaceAll(/[A-Z]+/g,e=>`/${e}`).split(`/`),n).map(xe).join(``)},Se=t.tryCatch((e,t)=>typeof r.parse(e,t),t.always(void 0)),T=e=>typeof e==`object`&&!!e,Ce=t.memoizeWith(()=>`static`,()=>process.env.NODE_ENV===`production`),we=(e,t)=>!!t&&e!==`head`,Te=Symbol(`Buffer`),Ee=()=>r.custom(e=>Buffer.isBuffer(e),{error:`Expected Buffer`}).brand(Te),De=Symbol(`DateIn`),Oe=({examples:e,...t}={})=>r.union([r.iso.date(),r.iso.datetime(),r.iso.datetime({local:!0})]).meta({examples:e}).transform(e=>new Date(e)).pipe(r.date()).brand(De).meta(t),ke=Symbol(`DateOut`),Ae=(e={})=>r.date().transform(e=>e.toISOString()).brand(ke).meta(e);var je=class extends Error{name=`RoutingError`;cause;constructor(e,t,n){super(e),this.cause={method:t,path:n}}},E=class extends Error{name=`DocumentationError`;cause;constructor(e,{method:t,path:n,isResponse:r}){super(e),this.cause=`${r?`Response`:`Input`} schema of an Endpoint assigned to ${t.toUpperCase()} method of ${n} path.`}},Me=class extends Error{name=`IOSchemaError`},Ne=class extends Me{name=`DeepCheckError`;constructor(e){super(`Found`,{cause:e}),this.cause=e}},Pe=class extends Me{name=`OutputValidationError`;constructor(e){let t=new r.ZodError(e.issues.map(({path:e,...t})=>({...t,path:[`output`,...e]})));super(S(t),{cause:e}),this.cause=e}},D=class extends Me{name=`InputValidationError`;constructor(e){super(S(e),{cause:e}),this.cause=e}},Fe=class extends Error{name=`ResultHandlerError`;constructor(e,t){super(S(e),{cause:e}),this.cause=e,this.handled=t}},Ie=class extends Error{name=`MissingPeerError`;constructor(e){super(`Missing peer dependency: ${e}. Please install it to use the feature.`)}};const Le=Symbol(`Form`),Re=e=>(e instanceof r.ZodObject?e:r.object(e)).brand(Le),O=Symbol(`Upload`),ze=()=>r.custom(e=>typeof e==`object`&&!!e&&`name`in e&&`encoding`in e&&`mimetype`in e&&`data`in e&&`tempFilePath`in e&&`truncated`in e&&`size`in e&&`md5`in e&&`mv`in e&&typeof e.name==`string`&&typeof e.encoding==`string`&&typeof e.mimetype==`string`&&Buffer.isBuffer(e.data)&&typeof e.tempFilePath==`string`&&typeof e.truncated==`boolean`&&typeof e.size==`number`&&typeof e.md5==`string`&&typeof e.mv==`function`,{error:({input:e})=>({message:`Expected file upload, received ${typeof e}`})}).brand(O),k=Symbol(`Raw`),Be=r.object({raw:Ee()}),Ve=e=>Be.extend(e).brand(k);function He(e){return e?Ve(e):Be.brand(k)}const Ue=(e,{io:n,condition:i})=>t.tryCatch(()=>void r.toJSONSchema(e,{io:n,unrepresentable:`any`,override:({zodSchema:e})=>{if(i(e))throw new Ne(e)}}),e=>e.cause)(),We=(e,{io:n})=>{let i=[r.toJSONSchema(e,{io:n,unrepresentable:`any`})];for(;i.length;){let e=i.shift();if(t.is(Object,e)){if(e.$ref===`#`)return!0;i.push(...t.values(e))}t.is(Array,e)&&i.push(...t.values(e))}return!1},Ge=t=>Ue(t,{condition:t=>{let n=e(t);return typeof n==`symbol`&&[O,k,Le].includes(n)},io:`input`}),Ke=[`nan`,`symbol`,`map`,`set`,`bigint`,`void`,`promise`,`never`,`function`],qe=(t,n)=>Ue(t,{io:n,condition:t=>{let r=e(t),{type:i}=t._zod.def;return!!(Ke.includes(i)||r===Te||n===`input`&&(i===`date`||r===ke)||n===`output`&&(r===De||r===k||r===O))}}),Je=(e,{variant:t,args:n,...i})=>{if(typeof e==`function`&&(e=e(...n)),e instanceof r.ZodType)return[{schema:e,...i}];if(Array.isArray(e)&&!e.length)throw new Fe(Error(`At least one ${t} response schema required.`));return(Array.isArray(e)?e:[e]).map(({schema:e,statusCode:t,mimeType:n})=>({schema:e,statusCodes:typeof t==`number`?[t]:t||i.statusCodes,mimeTypes:typeof n==`string`?[n]:n===void 0?i.mimeTypes:n}))},Ye=(e,t,{url:n},r)=>!e.expose&&t.error(`Server side error`,{error:e,url:n,payload:r}),A=e=>a(e)?e:i(e instanceof D?400:500,S(e),{cause:e.cause||e}),j=e=>Ce()&&!e.expose?i(e.statusCode).message:e.message,Xe=e=>Object.entries(e._zod.def.shape).reduce((e,[r,i])=>{let{examples:a=[]}=n.get(i)||{};return be(e,a.map(t.objOf(r)),([e,t])=>({...e,...t}))},[]),Ze=({error:e,logger:t,response:n})=>{t.error(`Result handler failure`,e);let r=j(i(500,`An error occurred while serving the result: ${e.message}.`+(e.handled?`\nOriginal error: ${e.handled.message}.`:``),{expose:a(e.cause)?e.cause.expose:!1}));n.status(500).type(`text/plain`).end(r)};var Qe=class{},M=class extends Qe{#e;#t;#n;constructor({input:e,security:t,handler:n}){super(),this.#e=e,this.#t=t,this.#n=n}get security(){return this.#t}get schema(){return this.#e}async execute({input:e,...t}){try{let n=await(this.#e||de).parseAsync(e);return this.#n({...t,input:n})}catch(e){throw e instanceof r.ZodError?new D(e):e}}},$e=class extends M{constructor(e,{provider:t=()=>({}),transformer:n=e=>e}={}){super({handler:async({request:r,response:i})=>new Promise((a,o)=>{let s=e=>{if(e&&e instanceof Error)return o(n(e));a(t(r,i))};e(r,i,s)?.catch(s)})})}},et=class{nest(e){return Object.assign(e,{"":this})}},tt=class extends et{},nt=class i extends tt{#e;#t=t.once(()=>{if(n.get(this.#e.outputSchema)?.examples?.length||!C(this.#e.outputSchema,`object`))return;let e=Xe(this.#e.outputSchema);if(!e.length)return;let t=this.#e.outputSchema.meta();n.remove(this.#e.outputSchema).add(this.#e.outputSchema,{...t,examples:e})});constructor(e){super(),this.#e=e}#n(e){return new i({...this.#e,...e})}deprecated(){return this.#n({deprecated:!0})}get isDeprecated(){return this.#e.deprecated||!1}get description(){return this.#e.description}get shortDescription(){return this.#e.shortDescription}get methods(){return Object.freeze(this.#e.methods)}get inputSchema(){return this.#e.inputSchema}get outputSchema(){return this.#t(),this.#e.outputSchema}get requestType(){let t=Ge(this.#e.inputSchema);if(t){let n=e(t);if(n===O)return`upload`;if(n===k)return`raw`;if(n===Le)return`form`}return`json`}getResponses(e){return e===`positive`&&this.#t(),Object.freeze(e===`negative`?this.#e.resultHandler.getNegativeResponse():this.#e.resultHandler.getPositiveResponse(this.#e.outputSchema))}get security(){let e=t.pluck(`security`,this.#e.middlewares||[]);return t.reject(t.isNil,e)}get scopes(){return Object.freeze(this.#e.scopes||[])}get tags(){return Object.freeze(this.#e.tags||[])}getOperationId(e){return this.#e.getOperationId?.(e)}async#r(e){try{return await this.#e.outputSchema.parseAsync(e)}catch(e){throw e instanceof r.ZodError?new Pe(e):e}}async#i({method:e,logger:t,options:n,response:r,...i}){for(let a of this.#e.middlewares||[])if(!(e===`options`&&!(a instanceof $e))&&(Object.assign(n,await a.execute({...i,options:n,response:r,logger:t})),r.writableEnded)){t.warn(`A middleware has closed the stream. Accumulated options:`,n);break}}async#a({input:e,...t}){let n;try{n=await this.#e.inputSchema.parseAsync(e)}catch(e){throw e instanceof r.ZodError?new D(e):e}return this.#e.handler({...t,input:n})}async#o(e){try{await this.#e.resultHandler.execute(e)}catch(t){Ze({...e,error:new Fe(x(t),e.error||void 0)})}}async execute({request:e,response:t,logger:n,config:r}){let i=_e(e),a={},o={output:{},error:null},s=ye(e,r.inputSources);try{if(await this.#i({method:i,input:s,request:e,response:t,logger:n,options:a}),t.writableEnded)return;if(i===`options`)return void t.status(200).end();o={output:await this.#r(await this.#a({input:s,logger:n,options:a})),error:null}}catch(e){o={output:null,error:x(e)}}await this.#o({...o,input:s,request:e,response:t,logger:n,options:a})}};const rt=(e,t)=>e&&t?e.and(t):e||t,it=(e,t)=>e?e.and(t):t,N={positive:200,negative:400},at=Object.keys(N);var ot=class{#e;constructor(e){this.#e=e}execute(...e){return this.#e(...e)}},P=class extends ot{#e;#t;constructor(e){super(e.handler),this.#e=e.positive,this.#t=e.negative}getPositiveResponse(e){return Je(this.#e,{variant:`positive`,args:[e],statusCodes:[N.positive],mimeTypes:[y.json]})}getNegativeResponse(){return Je(this.#t,{variant:`negative`,args:[],statusCodes:[N.negative],mimeTypes:[y.json]})}};const st=r.object({status:r.literal(`error`),error:r.object({message:r.string()})});n.add(st,{examples:[{status:`error`,error:{message:`Sample error message`}}]});const F=new P({positive:e=>{let t=r.object({status:r.literal(`success`),data:e}),{examples:i}=n.get(e)||{};return i?.length&&n.add(t,{examples:i.map(e=>({status:`success`,data:e}))}),t},negative:st,handler:({error:e,input:t,output:n,request:r,response:i,logger:a})=>{if(e){let n=A(e);Ye(n,a,r,t),i.status(n.statusCode).set(n.headers).json({status:`error`,error:{message:j(n)}});return}i.status(N.positive).json({status:`success`,data:n})}}),ct=r.string();n.add(ct,{examples:[`Sample error message`]});const lt=new P({positive:e=>{let t=e instanceof r.ZodObject&&`items`in e.shape&&e.shape.items instanceof r.ZodArray?e.shape.items:r.array(r.any());if(n.get(t)?.examples?.length)return t;let i=n.get(e)?.examples?.filter(e=>T(e)&&`items`in e&&Array.isArray(e.items)).map(e=>e.items);if(i?.length){let e=t.meta();n.remove(t).add(t,{...e,examples:i})}return t},negative:{schema:ct,mimeType:`text/plain`},handler:({response:e,output:t,error:n,logger:r,request:i,input:a})=>{if(n){let t=A(n);Ye(t,r,i,a),e.status(t.statusCode).type(`text/plain`).send(j(t));return}if(`items`in t&&Array.isArray(t.items)){e.status(N.positive).json(t.items);return}throw Error(`Property 'items' is missing in the endpoint output`)}});var ut=class e{schema=void 0;middlewares=[];constructor(e){this.resultHandler=e}#e(t){let n=new e(this.resultHandler);return n.middlewares=this.middlewares.concat(t),n.schema=rt(this.schema,t.schema),n}addMiddleware(e){return this.#e(e instanceof M?e:new M(e))}use=this.addExpressMiddleware;addExpressMiddleware(...e){return this.#e(new $e(...e))}addOptions(e){return this.#e(new M({handler:e}))}build({input:e=de,output:t,operationId:n,scope:r,tag:i,method:a,...o}){let{middlewares:s,resultHandler:c}=this,l=typeof a==`string`?[a]:a,u=typeof n==`function`?n:e=>n&&`${n}${e===`head`?`__HEAD`:``}`,d=typeof r==`string`?[r]:r||[],f=typeof i==`string`?[i]:i||[];return new nt({...o,middlewares:s,outputSchema:t,resultHandler:c,scopes:d,tags:f,methods:l,getOperationId:u,inputSchema:it(this.schema,e)})}buildVoid({handler:e,...t}){return this.build({...t,output:de,handler:async t=>(await e(t),{})})}};const dt=new ut(F),ft=new ut(lt),pt={debug:s,info:u,warn:d(`#FFA500`),error:p,ctx:c},mt={debug:10,info:20,warn:30,error:40},ht=e=>T(e)&&Object.keys(mt).some(t=>t in e),gt=e=>e in mt,_t=(e,t)=>mt[e]<mt[t],I=t.memoizeWith((e,t)=>`${e}${t}`,(e,t=0)=>Intl.NumberFormat(void 0,{useGrouping:!1,minimumFractionDigits:0,maximumFractionDigits:t,style:`unit`,unitDisplay:`long`,unit:e})),vt=e=>e<1e-6?I(`nanosecond`,3).format(e/1e-6):e<.001?I(`nanosecond`).format(e/1e-6):e<1?I(`microsecond`).format(e/.001):e<1e3?I(`millisecond`).format(e):e<6e4?I(`second`,2).format(e/1e3):I(`minute`,2).format(e/6e4);var yt=class e{config;constructor({color:e=o.isSupported(),level:t=Ce()?`warn`:`debug`,depth:n=2,ctx:r={}}={}){this.config={color:e,level:t,depth:n,ctx:r}}format(e){let{depth:t,color:n,level:r}=this.config;return ee(e,{depth:t,colors:n,breakLength:r===`debug`?80:1/0,compact:r===`debug`?3:!0})}print(e,t,n){let{level:r,ctx:{requestId:i,...a},color:o}=this.config;if(r===`silent`||_t(e,r))return;let s=[new Date().toISOString()];i&&s.push(o?pt.ctx(i):i),s.push(o?`${pt[e](e)}:`:`${e}:`,t),n!==void 0&&s.push(this.format(n)),Object.keys(a).length>0&&s.push(this.format(a)),console.log(s.join(` `))}debug(e,t){this.print(`debug`,e,t)}info(e,t){this.print(`info`,e,t)}warn(e,t){this.print(`warn`,e,t)}error(e,t){this.print(`error`,e,t)}child(t){return new e({...this.config,ctx:t})}get ctx(){return this.config.ctx}profile(e){let t=h.now();return()=>{let n=h.now()-t,{message:r,severity:i=`debug`,formatter:a=vt}=typeof e==`object`?e:{message:e};this.print(typeof i==`function`?i(n):i,r,a(n))}}},bt=class e extends et{#e;constructor(e){super(),this.#e=e}get entries(){let e=t.filter(e=>!!e[1],Object.entries(this.#e));return Object.freeze(e)}deprecated(){return new e(Object.entries(this.#e).reduce((e,[t,n])=>Object.assign(e,{[t]:n.deprecated()}),{}))}},xt=class{#e;constructor(...e){this.#e=e}apply(e,t){return t(e,g.static(...this.#e))}};const St=async(e,t=`default`)=>{try{return(await import(e))[t]}catch{}throw new Ie(e)},Ct=e=>e.type===`object`,wt=t.mergeDeepWith((e,n)=>{if(Array.isArray(e)&&Array.isArray(n))return t.concat(e,n);if(e===n)return n;throw Error(`Can not flatten properties`,{cause:{a:e,b:n}})}),Tt=t.pipe(Object.keys,t.without([`type`,`properties`,`required`,`examples`,`description`,`additionalProperties`]),t.isEmpty),Et=t.pair(!0),Dt=(e,n=`coerce`)=>{let r=[t.pair(!1,e)],i={type:`object`,properties:{}},a=[];for(;r.length;){let[e,o]=r.shift();if(o.description&&(i.description??=o.description),o.allOf&&r.push(...o.allOf.map(r=>{if(n===`throw`&&!(r.type===`object`&&Tt(r)))throw Error(`Can not merge`);return t.pair(e,r)})),o.anyOf&&r.push(...t.map(Et,o.anyOf)),o.oneOf&&r.push(...t.map(Et,o.oneOf)),o.examples?.length&&(e?i.examples=t.concat(i.examples||[],o.examples):i.examples=be(i.examples?.filter(T)||[],o.examples.filter(T),([e,n])=>t.mergeDeepRight(e,n))),Ct(o)&&(r.push([e,{examples:Ot(o)}]),o.properties&&(i.properties=(n===`throw`?wt:t.mergeDeepRight)(i.properties,o.properties),!e&&o.required&&a.push(...o.required)),T(o.propertyNames))){let t=[];typeof o.propertyNames.const==`string`&&t.push(o.propertyNames.const),o.propertyNames.enum&&t.push(...o.propertyNames.enum.filter(e=>typeof e==`string`));let n={...Object(o.additionalProperties)};for(let e of t)i.properties[e]??=n;e||a.push(...t)}}return a.length&&(i.required=[...new Set(a)]),i},Ot=e=>Object.entries(e.properties||{}).reduce((e,[n,r])=>{let{examples:i=[]}=T(r)?r:{};return be(e,i.map(t.objOf(n)),([e,t])=>({...e,...t}))},[]);var kt=class{#e=new WeakSet;#t=new WeakMap;constructor(e){this.logger=e}checkSchema(e,t){if(!this.#e.has(e)){for(let n of[`input`,`output`]){let i=[r.toJSONSchema(e[`${n}Schema`],{unrepresentable:`any`})];for(;i.length>0;){let e=i.shift();e.type&&e.type!==`object`&&this.logger.warn(`Endpoint ${n} schema is not object-based`,t);for(let t of[`allOf`,`oneOf`,`anyOf`])e[t]&&i.push(...e[t])}}if(e.requestType===`json`){let n=qe(e.inputSchema,`input`);n&&this.logger.warn(`The final input schema of the endpoint contains an unsupported JSON payload type.`,Object.assign(t,{reason:n}))}for(let n of at)for(let{mimeTypes:r,schema:i}of e.getResponses(n)){if(!r?.includes(y.json))continue;let e=qe(i,`output`);e&&this.logger.warn(`The final ${n} response schema of the endpoint contains an unsupported JSON payload type.`,Object.assign(t,{reason:e}))}this.#e.add(e)}}checkPathParams(e,t,n){let i=this.#t.get(t);if(i?.paths.includes(e))return;let a=pe(e);if(a.length===0)return;let o=i?.flat||Dt(r.toJSONSchema(t.inputSchema,{unrepresentable:`any`,io:`input`}));for(let t of a)t in o.properties||this.logger.warn(`The input schema of the endpoint is most likely missing the parameter of the path it's assigned to.`,Object.assign(n,{path:e,param:t}));i?i.paths.push(e):this.#t.set(t,{flat:o,paths:[e]})}};const At=e=>(t,...n)=>{e(t,...n),t===`get`&&e(`head`,...n)},jt=e=>{let[t,n]=e.trim().split(/ (.+)/,2);return n&&b(t)?[n,t]:[e]},Mt=e=>e.trim().split(`/`).filter(Boolean).join(`/`),Nt=(e,t)=>Object.entries(e).map(([e,n])=>{let[r,i]=jt(e);return[[t||``].concat(Mt(r)||[]).join(`/`),n,i]}),Pt=(e,t)=>{throw new je(`Route with explicit method can only be assigned with Endpoint`,e,t)},Ft=(e,t,n)=>{if(!(!n||n.includes(e)))throw new je(`Method ${e} is not supported by the assigned Endpoint.`,e,t)},It=(e,t,n)=>{let r=`${e} ${t}`;if(n.has(r))throw new je(`Route has a duplicate`,e,t);n.add(r)},Lt=({routing:e,onEndpoint:t,onStatic:n})=>{let r=Nt(e),i=new Set;for(;r.length;){let[e,a,o]=r.shift();if(a instanceof tt)if(o)It(o,e,i),Ft(o,e,a.methods),t(o,e,a);else{let{methods:n=[`get`]}=a;for(let r of n)It(r,e,i),t(r,e,a)}else if(o&&Pt(o,e),a instanceof xt)n&&a.apply(e,n);else if(a instanceof bt)for(let[n,r]of a.entries){let{methods:a}=r;It(n,e,i),Ft(n,e,a),t(n,e,r)}else r.unshift(...Nt(a,e))}},Rt=e=>e.sort((e,t)=>b(t)-+b(e)||e.localeCompare(t)).join(`, `).toUpperCase(),zt=e=>({method:t},n,r)=>{let a=Rt(e);n.set({Allow:a}),r(i(405,`${t} is not allowed`,{headers:{Allow:a}}))},Bt=e=>({"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":Rt(e),"Access-Control-Allow-Headers":`content-type`}),Vt=({app:e,getLogger:n,config:r,routing:i,parsers:a})=>{let o=Ce()?void 0:new kt(n()),s=new Map;return Lt({routing:i,onEndpoint:(e,n,i)=>{o?.checkSchema(i,{path:n,method:e}),o?.checkPathParams(n,i,{method:e});let c=a?.[i.requestType]||[],l=t.pair(c,i);s.has(n)||s.set(n,new Map(r.cors?[[`options`,l]]:[])),s.get(n)?.set(e,l)},onStatic:e.use.bind(e)}),s},Ht=({app:e,config:t,getLogger:n,...r})=>{let i=Vt({app:e,getLogger:n,config:t,...r}),a=new Map;for(let[r,o]of i){let i=Array.from(o.keys());i.includes(`get`)&&i.push(`head`);for(let[a,[s,c]]of o){let o=s.slice().concat(async(e,r)=>{let i=n(e);return c.execute({request:e,response:r,logger:i,config:t})});t.cors&&o.unshift(async(e,r,a)=>{let o=n(e),s=Bt(i),l=typeof t.cors==`function`?await t.cors({request:e,endpoint:c,logger:o,defaultHeaders:s}):s;r.set(l),a()}),e[a](r,...o)}t.wrongMethodBehavior!==404&&a.set(r,zt(i))}for(let[t,n]of a)e.all(t,n)},Ut=e=>`_httpMessage`in e&&typeof e._httpMessage==`object`&&e._httpMessage!==null&&`headersSent`in e._httpMessage&&typeof e._httpMessage.headersSent==`boolean`&&`setHeader`in e._httpMessage&&typeof e._httpMessage.setHeader==`function`,Wt=e=>`server`in e&&typeof e.server==`object`&&e.server!==null&&`close`in e.server&&typeof e.server.close==`function`,Gt=e=>`encrypted`in e&&typeof e.encrypted==`boolean`&&e.encrypted,Kt=({},e)=>void(!e.headersSent&&e.setHeader(`connection`,`close`)),qt=e=>new Promise((t,n)=>void e.close(e=>e?n(e):t())),Jt=(e,{timeout:t=1e3,logger:n}={})=>{let r,i=new Set,a=e=>void i.delete(e.destroy()),o=e=>void(Ut(e)?!e._httpMessage.headersSent&&e._httpMessage.setHeader(`connection`,`close`):a(e)),s=e=>void(r?e.destroy():i.add(e.once(`close`,()=>void i.delete(e))));for(let t of e)for(let e of[`connection`,`secureConnection`])t.on(e,s);let c=async()=>{for(let t of e)t.on(`request`,Kt);n?.info(`Graceful shutdown`,{sockets:i.size,timeout:t});for(let e of i)(Gt(e)||Wt(e))&&o(e);for await(let e of re(10,Date.now()))if(i.size===0||Date.now()-e>=t)break;for(let e of i)a(e);return Promise.allSettled(e.map(qt))};return{sockets:i,shutdown:()=>r??=c()}},Yt=Symbol.for(`express-zod-api`),Xt=({errorHandler:e,getLogger:t})=>async(n,r,i,a)=>n?e.execute({error:x(n),request:r,response:i,input:null,output:null,options:{},logger:t(r)}):a(),Zt=({errorHandler:e,getLogger:t})=>async(n,r)=>{let a=i(404,`Can not ${n.method} ${n.path}`),o=t(n);try{await e.execute({request:n,response:r,logger:o,error:a,input:null,output:null,options:{}})}catch(e){Ze({response:r,logger:o,error:new Fe(x(e),a)})}},Qt=e=>(t,{},n)=>{if(Object.values(t?.files||[]).flat().find(({truncated:e})=>e))return n(e);n()},$t=e=>({log:e.debug.bind(e)}),en=async({getLogger:e,config:t})=>{let n=await St(`express-fileupload`),{limitError:r,beforeUpload:i,...a}={...typeof t.upload==`object`&&t.upload},o=[];return o.push(async(t,r,o)=>{let s=e(t);return await i?.({request:t,logger:s}),n({debug:!0,...a,abortOnLimit:!1,parseNested:!0,logger:$t(s)})(t,r,o)}),r&&o.push(Qt(r)),o},tn=(e,{},t)=>{Buffer.isBuffer(e.body)&&(e.body={raw:e.body}),t()},nn=({logger:e,config:{childLoggerProvider:t,accessLogger:n=({method:e,path:t},n)=>n.debug(`${e}: ${t}`)}})=>async(r,i,a)=>{let o=await t?.({request:r,parent:e})||e;n?.(r,o),r.res&&(r.res.locals[Yt]={logger:o}),a()},rn=e=>t=>t?.res?.locals[Yt]?.logger||e,an=e=>process.on(`deprecation`,({message:t,namespace:n,name:r,stack:i})=>e.warn(`${r} (${n}): ${t}`,i.split(`
2
- `).slice(1))),on=({servers:e,logger:t,options:{timeout:n,beforeExit:r,events:i=[`SIGINT`,`SIGTERM`]}})=>{let a=Jt(e,{logger:t,timeout:n}),o=async()=>{await a.shutdown(),await r?.(),process.exit()};for(let e of i)process.on(e,o)},sn=e=>{if(e.columns<132)return;let t=f(`Proudly supports transgender community.`.padStart(109)),n=f(`Start your API server with I/O schema validation and custom middlewares in minutes.`.padStart(109)),r=f(`Thank you for choosing Express Zod API for your project.`.padStart(132)),i=f(`for Sara`.padEnd(20)),a=d(`#F5A9B8`),o=d(`#5BCEFA`),s=Array(14).fill(o,1,3).fill(a,3,5).fill(m,5,7).fill(a,7,9).fill(o,9,12).fill(l,12,13),c=`
1
+ import{getBrand as e}from"@express-zod-api/zod-plugin";import*as t from"ramda";import{globalRegistry as n,z as r}from"zod";import i,{isHttpError as a}from"http-errors";import o,{blue as s,cyanBright as c,gray as l,green as u,hex as d,italic as f,red as p,whiteBright as m}from"ansis";import{inspect as ee}from"node:util";import{performance as h}from"node:perf_hooks";import g from"express";import te from"node:http";import ne from"node:https";import{setInterval as re}from"node:timers/promises";import{OpenApiBuilder as ie,isReferenceObject as ae,isSchemaObject as _}from"openapi3-ts/oas31";import{createRequest as oe,createResponse as se}from"node-mocks-http";import v from"typescript";function ce(e){return e}const y={json:`application/json`,upload:`multipart/form-data`,raw:`application/octet-stream`,sse:`text/event-stream`,form:`application/x-www-form-urlencoded`},le=[`get`,`post`,`put`,`delete`,`patch`],ue=[...le,`head`],b=e=>le.includes(e),de=r.object({}),fe=/:([A-Za-z0-9_]+)/g,pe=e=>e.match(fe)?.map(e=>e.slice(1))||[],me=e=>{let t=(e.header(`content-type`)||``).toLowerCase().startsWith(y.upload);return`files`in e&&t},he={get:[`query`,`params`],post:[`body`,`params`,`files`],put:[`body`,`params`],patch:[`body`,`params`],delete:[`query`,`params`]},ge=[`body`,`query`,`params`],_e=e=>e.method.toLowerCase(),ve=(e,t={})=>{if(e===`options`)return[];let n=e===`head`?`get`:b(e)?e:void 0;return(n?t[n]||he[n]:void 0)||ge},ye=(e,t={})=>ve(_e(e),t).filter(t=>t===`files`?me(e):!0).reduce((t,n)=>Object.assign(t,e[n]),{}),x=e=>e instanceof Error?e:e instanceof r.ZodError?new r.ZodRealError(e.issues):Error(String(e)),S=e=>e instanceof r.ZodError?e.issues.map(({path:e,message:t})=>`${e.length?`${r.core.toDotPath(e)}: `:``}${t}`).join(`; `):e.message,C=(e,n)=>T(e)&&`_zod`in e&&(n?t.path([`_zod`,`def`,`type`],e)===n:!0),be=(e,n,r)=>e.length&&n.length?t.xprod(e,n).map(r):e.concat(n),xe=e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase(),w=(...e)=>{let n=t.chain(e=>e.split(/[^A-Z0-9]/gi),e);return t.chain(e=>e.replaceAll(/[A-Z]+/g,e=>`/${e}`).split(`/`),n).map(xe).join(``)},Se=t.tryCatch((e,t)=>typeof r.parse(e,t),t.always(void 0)),T=e=>typeof e==`object`&&!!e,Ce=t.memoizeWith(()=>`static`,()=>process.env.NODE_ENV===`production`),we=(e,t)=>!!t&&e!==`head`,E=Symbol(`Buffer`),Te=()=>r.custom(e=>Buffer.isBuffer(e),{error:`Expected Buffer`}).brand(E),D=Symbol(`DateIn`),Ee=({examples:e,...t}={})=>r.union([r.iso.date(),r.iso.datetime(),r.iso.datetime({local:!0})]).meta({examples:e}).transform(e=>new Date(e)).pipe(r.date()).brand(D).meta(t),O=Symbol(`DateOut`),De=(e={})=>r.date().transform(e=>e.toISOString()).brand(O).meta(e);var k=class extends Error{name=`RoutingError`;cause;constructor(e,t,n){super(e),this.cause={method:t,path:n}}},A=class extends Error{name=`DocumentationError`;cause;constructor(e,{method:t,path:n,isResponse:r}){super(e),this.cause=`${r?`Response`:`Input`} schema of an Endpoint assigned to ${t.toUpperCase()} method of ${n} path.`}},Oe=class extends Error{name=`IOSchemaError`},ke=class extends Oe{name=`DeepCheckError`;constructor(e){super(`Found`,{cause:e}),this.cause=e}},Ae=class extends Oe{name=`OutputValidationError`;constructor(e){let t=new r.ZodError(e.issues.map(({path:e,...t})=>({...t,path:[`output`,...e]})));super(S(t),{cause:e}),this.cause=e}},j=class extends Oe{name=`InputValidationError`;constructor(e){super(S(e),{cause:e}),this.cause=e}},je=class extends Error{name=`ResultHandlerError`;constructor(e,t){super(S(e),{cause:e}),this.cause=e,this.handled=t}},Me=class extends Error{name=`MissingPeerError`;constructor(e){super(`Missing peer dependency: ${e}. Please install it to use the feature.`)}};const Ne=Symbol(`Form`),Pe=e=>(e instanceof r.ZodObject?e:r.object(e)).brand(Ne),M=Symbol(`Upload`),Fe=()=>r.custom(e=>typeof e==`object`&&!!e&&`name`in e&&`encoding`in e&&`mimetype`in e&&`data`in e&&`tempFilePath`in e&&`truncated`in e&&`size`in e&&`md5`in e&&`mv`in e&&typeof e.name==`string`&&typeof e.encoding==`string`&&typeof e.mimetype==`string`&&Buffer.isBuffer(e.data)&&typeof e.tempFilePath==`string`&&typeof e.truncated==`boolean`&&typeof e.size==`number`&&typeof e.md5==`string`&&typeof e.mv==`function`,{error:({input:e})=>({message:`Expected file upload, received ${typeof e}`})}).brand(M),N=Symbol(`Raw`),Ie=r.object({raw:Te()}),Le=e=>Ie.extend(e).brand(N);function Re(e){return e?Le(e):Ie.brand(N)}const ze=(e,{io:n,condition:i})=>t.tryCatch(()=>void r.toJSONSchema(e,{io:n,unrepresentable:`any`,override:({zodSchema:e})=>{if(i(e))throw new ke(e)}}),e=>e.cause)(),Be=(e,{io:n})=>{let i=[r.toJSONSchema(e,{io:n,unrepresentable:`any`})];for(;i.length;){let e=i.shift();if(t.is(Object,e)){if(e.$ref===`#`)return!0;i.push(...t.values(e))}t.is(Array,e)&&i.push(...t.values(e))}return!1},Ve=t=>ze(t,{condition:t=>{let n=e(t);return typeof n==`symbol`&&[M,N,Ne].includes(n)},io:`input`}),He=[`nan`,`symbol`,`map`,`set`,`bigint`,`void`,`promise`,`never`,`function`],Ue=(t,n)=>ze(t,{io:n,condition:t=>{let r=e(t),{type:i}=t._zod.def;return!!(He.includes(i)||r===E||n===`input`&&(i===`date`||r===O)||n===`output`&&(r===D||r===N||r===M))}}),We=(e,{variant:t,args:n,...i})=>{if(typeof e==`function`&&(e=e(...n)),e instanceof r.ZodType)return[{schema:e,...i}];if(Array.isArray(e)&&!e.length)throw new je(Error(`At least one ${t} response schema required.`));return(Array.isArray(e)?e:[e]).map(({schema:e,statusCode:t,mimeType:n})=>({schema:e,statusCodes:typeof t==`number`?[t]:t||i.statusCodes,mimeTypes:typeof n==`string`?[n]:n===void 0?i.mimeTypes:n}))},Ge=(e,t,{url:n},r)=>!e.expose&&t.error(`Server side error`,{error:e,url:n,payload:r}),Ke=e=>a(e)?e:i(e instanceof j?400:500,S(e),{cause:e.cause||e}),qe=e=>Ce()&&!e.expose?i(e.statusCode).message:e.message,Je=e=>Object.entries(e._zod.def.shape).reduce((e,[r,i])=>{let{examples:a=[]}=n.get(i)||{};return be(e,a.map(t.objOf(r)),([e,t])=>({...e,...t}))},[]),Ye=({error:e,logger:t,response:n})=>{t.error(`Result handler failure`,e);let r=qe(i(500,`An error occurred while serving the result: ${e.message}.`+(e.handled?`\nOriginal error: ${e.handled.message}.`:``),{expose:a(e.cause)?e.cause.expose:!1}));n.status(500).type(`text/plain`).end(r)};var Xe=class{},P=class extends Xe{#e;#t;#n;constructor({input:e,security:t,handler:n}){super(),this.#e=e,this.#t=t,this.#n=n}get security(){return this.#t}get schema(){return this.#e}async execute({input:e,...t}){try{let n=await(this.#e||de).parseAsync(e);return this.#n({...t,input:n})}catch(e){throw e instanceof r.ZodError?new j(e):e}}},Ze=class extends P{constructor(e,{provider:t=()=>({}),transformer:n=e=>e}={}){super({handler:async({request:r,response:i})=>new Promise((a,o)=>{let s=e=>{if(e&&e instanceof Error)return o(n(e));a(t(r,i))};e(r,i,s)?.catch(s)})})}},Qe=class{nest(e){return{...e,"":this}}},$e=class i extends Qe{#e;#t=t.once(()=>{if(n.get(this.#e.outputSchema)?.examples?.length||!C(this.#e.outputSchema,`object`))return;let e=Je(this.#e.outputSchema);if(!e.length)return;let t=this.#e.outputSchema.meta();n.remove(this.#e.outputSchema).add(this.#e.outputSchema,{...t,examples:e})});constructor(e){super(),this.#e=e}#n(e){return new i({...this.#e,...e})}deprecated(){return this.#n({deprecated:!0})}get isDeprecated(){return this.#e.deprecated||!1}get description(){return this.#e.description}get shortDescription(){return this.#e.shortDescription}get methods(){return Object.freeze(this.#e.methods)}get inputSchema(){return this.#e.inputSchema}get outputSchema(){return this.#t(),this.#e.outputSchema}get requestType(){let t=Ve(this.#e.inputSchema);if(t){let n=e(t);if(n===M)return`upload`;if(n===N)return`raw`;if(n===Ne)return`form`}return`json`}getResponses(e){return e===`positive`&&this.#t(),Object.freeze(e===`negative`?this.#e.resultHandler.getNegativeResponse():this.#e.resultHandler.getPositiveResponse(this.#e.outputSchema))}get security(){let e=t.pluck(`security`,this.#e.middlewares||[]);return t.reject(t.isNil,e)}get scopes(){return Object.freeze(this.#e.scopes||[])}get tags(){return Object.freeze(this.#e.tags||[])}getOperationId(e){return this.#e.getOperationId?.(e)}async#r(e){try{return await this.#e.outputSchema.parseAsync(e)}catch(e){throw e instanceof r.ZodError?new Ae(e):e}}async#i({method:e,logger:t,ctx:n,response:r,...i}){for(let a of this.#e.middlewares||[])if(!(e===`options`&&!(a instanceof Ze))&&(Object.assign(n,await a.execute({...i,ctx:n,response:r,logger:t})),r.writableEnded)){t.warn(`A middleware has closed the stream. Accumulated context:`,n);break}}async#a({input:e,...t}){let n;try{n=await this.#e.inputSchema.parseAsync(e)}catch(e){throw e instanceof r.ZodError?new j(e):e}return this.#e.handler({...t,input:n})}async#o(e){try{await this.#e.resultHandler.execute(e)}catch(t){Ye({...e,error:new je(x(t),e.error||void 0)})}}async execute({request:e,response:t,logger:n,config:r}){let i=_e(e),a={},o={output:{},error:null},s=ye(e,r.inputSources);try{if(await this.#i({method:i,input:s,request:e,response:t,logger:n,ctx:a}),t.writableEnded)return;if(i===`options`)return void t.status(200).end();o={output:await this.#r(await this.#a({input:s,logger:n,ctx:a})),error:null}}catch(e){o={output:null,error:x(e)}}await this.#o({...o,input:s,request:e,response:t,logger:n,ctx:a})}};const et=(e,t)=>e&&t?e.and(t):e||t,tt=(e,t)=>e?e.and(t):t,F={positive:200,negative:400},nt=Object.keys(F);var rt=class{#e;constructor(e){this.#e=e}execute(...e){return this.#e(...e)}},it=class extends rt{#e;#t;constructor(e){super(e.handler),this.#e=e.positive,this.#t=e.negative}getPositiveResponse(e){return We(this.#e,{variant:`positive`,args:[e],statusCodes:[F.positive],mimeTypes:[y.json]})}getNegativeResponse(){return We(this.#t,{variant:`negative`,args:[],statusCodes:[F.negative],mimeTypes:[y.json]})}};const at=r.object({status:r.literal(`error`),error:r.object({message:r.string()})});n.add(at,{examples:[{status:`error`,error:{message:`Sample error message`}}]});const ot=new it({positive:e=>{let t=r.object({status:r.literal(`success`),data:e}),{examples:i}=n.get(e)||{};return i?.length&&n.add(t,{examples:i.map(e=>({status:`success`,data:e}))}),t},negative:at,handler:({error:e,input:t,output:n,request:r,response:i,logger:a})=>{if(e){let n=Ke(e);Ge(n,a,r,t),i.status(n.statusCode).set(n.headers).json({status:`error`,error:{message:qe(n)}});return}i.status(F.positive).json({status:`success`,data:n})}}),st=r.string();n.add(st,{examples:[`Sample error message`]});const ct=new it({positive:e=>{let t=e instanceof r.ZodObject&&`items`in e.shape&&e.shape.items instanceof r.ZodArray?e.shape.items:r.array(r.any());if(n.get(t)?.examples?.length)return t;let i=n.get(e)?.examples?.filter(e=>T(e)&&`items`in e&&Array.isArray(e.items)).map(e=>e.items);if(i?.length){let e=t.meta();n.remove(t).add(t,{...e,examples:i})}return t},negative:{schema:st,mimeType:`text/plain`},handler:({response:e,output:t,error:n,logger:r,request:i,input:a})=>{if(n){let t=Ke(n);Ge(t,r,i,a),e.status(t.statusCode).type(`text/plain`).send(qe(t));return}if(`items`in t&&Array.isArray(t.items)){e.status(F.positive).json(t.items);return}throw Error(`Property 'items' is missing in the endpoint output`)}});var lt=class e{schema=void 0;middlewares=[];constructor(e){this.resultHandler=e}#e(t){let n=new e(this.resultHandler);return n.middlewares=this.middlewares.concat(t),n.schema=et(this.schema,t.schema),n}addMiddleware(e){return this.#e(e instanceof P?e:new P(e))}use=this.addExpressMiddleware;addExpressMiddleware(...e){return this.#e(new Ze(...e))}addContext(e){return this.#e(new P({handler:e}))}build({input:e=de,output:t,operationId:n,scope:r,tag:i,method:a,...o}){let{middlewares:s,resultHandler:c}=this,l=typeof a==`string`?[a]:a,u=typeof n==`function`?n:e=>n&&`${n}${e===`head`?`__HEAD`:``}`,d=typeof r==`string`?[r]:r||[],f=typeof i==`string`?[i]:i||[];return new $e({...o,middlewares:s,outputSchema:t,resultHandler:c,scopes:d,tags:f,methods:l,getOperationId:u,inputSchema:tt(this.schema,e)})}buildVoid({handler:e,...t}){return this.build({...t,output:de,handler:async t=>(await e(t),{})})}};const ut=new lt(ot),dt=new lt(ct),ft={debug:s,info:u,warn:d(`#FFA500`),error:p,ctx:c},pt={debug:10,info:20,warn:30,error:40},mt=e=>T(e)&&Object.keys(pt).some(t=>t in e),ht=e=>e in pt,gt=(e,t)=>pt[e]<pt[t],I=t.memoizeWith((e,t)=>`${e}${t}`,(e,t=0)=>Intl.NumberFormat(void 0,{useGrouping:!1,minimumFractionDigits:0,maximumFractionDigits:t,style:`unit`,unitDisplay:`long`,unit:e})),_t=e=>e<1e-6?I(`nanosecond`,3).format(e/1e-6):e<.001?I(`nanosecond`).format(e/1e-6):e<1?I(`microsecond`).format(e/.001):e<1e3?I(`millisecond`).format(e):e<6e4?I(`second`,2).format(e/1e3):I(`minute`,2).format(e/6e4);var vt=class e{config;constructor({color:e=o.isSupported(),level:t=Ce()?`warn`:`debug`,depth:n=2,ctx:r={}}={}){this.config={color:e,level:t,depth:n,ctx:r}}format(e){let{depth:t,color:n,level:r}=this.config;return ee(e,{depth:t,colors:n,breakLength:r===`debug`?80:1/0,compact:r===`debug`?3:!0})}print(e,t,n){let{level:r,ctx:{requestId:i,...a},color:o}=this.config;if(r===`silent`||gt(e,r))return;let s=[new Date().toISOString()];i&&s.push(o?ft.ctx(i):i),s.push(o?`${ft[e](e)}:`:`${e}:`,t),n!==void 0&&s.push(this.format(n)),Object.keys(a).length>0&&s.push(this.format(a)),console.log(s.join(` `))}debug(e,t){this.print(`debug`,e,t)}info(e,t){this.print(`info`,e,t)}warn(e,t){this.print(`warn`,e,t)}error(e,t){this.print(`error`,e,t)}child(t){return new e({...this.config,ctx:t})}get ctx(){return this.config.ctx}profile(e){let t=h.now();return()=>{let n=h.now()-t,{message:r,severity:i=`debug`,formatter:a=_t}=typeof e==`object`?e:{message:e};this.print(typeof i==`function`?i(n):i,r,a(n))}}},yt=class{#e;constructor(...e){this.#e=e}apply(e,t){return t(e,g.static(...this.#e))}};const bt=async(e,t=`default`)=>{try{return(await import(e))[t]}catch{}throw new Me(e)},xt=e=>e.type===`object`,St=t.mergeDeepWith((e,n)=>{if(Array.isArray(e)&&Array.isArray(n))return t.concat(e,n);if(e===n)return n;throw Error(`Can not flatten properties`,{cause:{a:e,b:n}})}),Ct=t.pipe(Object.keys,t.without([`type`,`properties`,`required`,`examples`,`description`,`additionalProperties`]),t.isEmpty),wt=t.pair(!0),Tt=(e,n=`coerce`)=>{let r=[t.pair(!1,e)],i={type:`object`,properties:{}},a=[];for(;r.length;){let[e,o]=r.shift();if(o.description&&(i.description??=o.description),o.allOf&&r.push(...o.allOf.map(r=>{if(n===`throw`&&!(r.type===`object`&&Ct(r)))throw Error(`Can not merge`);return t.pair(e,r)})),o.anyOf&&r.push(...t.map(wt,o.anyOf)),o.oneOf&&r.push(...t.map(wt,o.oneOf)),o.examples?.length&&(e?i.examples=t.concat(i.examples||[],o.examples):i.examples=be(i.examples?.filter(T)||[],o.examples.filter(T),([e,n])=>t.mergeDeepRight(e,n))),xt(o)&&(r.push([e,{examples:Et(o)}]),o.properties&&(i.properties=(n===`throw`?St:t.mergeDeepRight)(i.properties,o.properties),!e&&o.required&&a.push(...o.required)),T(o.propertyNames))){let t=[];typeof o.propertyNames.const==`string`&&t.push(o.propertyNames.const),o.propertyNames.enum&&t.push(...o.propertyNames.enum.filter(e=>typeof e==`string`));let n={...Object(o.additionalProperties)};for(let e of t)i.properties[e]??=n;e||a.push(...t)}}return a.length&&(i.required=[...new Set(a)]),i},Et=e=>Object.entries(e.properties||{}).reduce((e,[n,r])=>{let{examples:i=[]}=T(r)?r:{};return be(e,i.map(t.objOf(n)),([e,t])=>({...e,...t}))},[]);var Dt=class{#e=new WeakSet;#t=new WeakMap;constructor(e){this.logger=e}checkSchema(e,t){if(!this.#e.has(e)){for(let n of[`input`,`output`]){let i=[r.toJSONSchema(e[`${n}Schema`],{unrepresentable:`any`})];for(;i.length>0;){let e=i.shift();e.type&&e.type!==`object`&&this.logger.warn(`Endpoint ${n} schema is not object-based`,t);for(let t of[`allOf`,`oneOf`,`anyOf`])e[t]&&i.push(...e[t])}}if(e.requestType===`json`){let n=Ue(e.inputSchema,`input`);n&&this.logger.warn(`The final input schema of the endpoint contains an unsupported JSON payload type.`,Object.assign(t,{reason:n}))}for(let n of nt)for(let{mimeTypes:r,schema:i}of e.getResponses(n)){if(!r?.includes(y.json))continue;let e=Ue(i,`output`);e&&this.logger.warn(`The final ${n} response schema of the endpoint contains an unsupported JSON payload type.`,Object.assign(t,{reason:e}))}this.#e.add(e)}}checkPathParams(e,t,n){let i=this.#t.get(t);if(i?.paths.includes(e))return;let a=pe(e);if(a.length===0)return;let o=i?.flat||Tt(r.toJSONSchema(t.inputSchema,{unrepresentable:`any`,io:`input`}));for(let t of a)t in o.properties||this.logger.warn(`The input schema of the endpoint is most likely missing the parameter of the path it's assigned to.`,Object.assign(n,{path:e,param:t}));i?i.paths.push(e):this.#t.set(t,{flat:o,paths:[e]})}};const Ot=e=>(t,...n)=>{e(t,...n),t===`get`&&e(`head`,...n)},kt=e=>{let[t,n]=e.trim().split(/ (.+)/,2);return n&&b(t)?[n,t]:[e]},At=e=>e.trim().split(`/`).filter(Boolean).join(`/`),jt=({methodLikeRouteBehavior:e=`method`},t,n)=>{let r=e===`method`;return Object.entries(t).map(([e,t])=>{let[i,a]=b(e)&&r&&t instanceof Qe?[`/`,e]:kt(e);return[[n||``].concat(At(i)||[]).join(`/`),t,a]})},Mt=(e,t)=>{throw new k(`Route with explicit method can only be assigned with Endpoint`,e,t)},Nt=(e,t,n)=>{if(!(!n||n.includes(e)))throw new k(`Method ${e} is not supported by the assigned Endpoint.`,e,t)},Pt=(e,t,n)=>{let r=`${e} ${t}`;if(n.has(r))throw new k(`Route has a duplicate`,e,t);n.add(r)},Ft=({routing:e,config:t,onEndpoint:n,onStatic:r})=>{let i=jt(t,e),a=new Set;for(;i.length;){let[e,o,s]=i.shift();if(o instanceof Qe)if(s)Pt(s,e,a),Nt(s,e,o.methods),n(s,e,o);else{let{methods:t=[`get`]}=o;for(let r of t)Pt(r,e,a),n(r,e,o)}else s&&Mt(s,e),o instanceof yt?r&&o.apply(e,r):i.unshift(...jt(t,o,e))}},It=e=>e.sort((e,t)=>b(t)-+b(e)||e.localeCompare(t)).join(`, `).toUpperCase(),Lt=e=>({method:t},n,r)=>{let a=It(e);n.set({Allow:a}),r(i(405,`${t} is not allowed`,{headers:{Allow:a}}))},Rt=e=>({"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":It(e),"Access-Control-Allow-Headers":`content-type`}),zt=({app:e,getLogger:n,config:r,routing:i,parsers:a})=>{let o=Ce()?void 0:new Dt(n()),s=new Map;return Ft({routing:i,config:r,onEndpoint:(e,n,i)=>{o?.checkSchema(i,{path:n,method:e}),o?.checkPathParams(n,i,{method:e});let c=a?.[i.requestType]||[],l=t.pair(c,i);s.has(n)||s.set(n,new Map(r.cors?[[`options`,l]]:[])),s.get(n)?.set(e,l)},onStatic:e.use.bind(e)}),s},Bt=({app:e,config:t,getLogger:n,...r})=>{let i=zt({app:e,getLogger:n,config:t,...r}),a=new Map;for(let[r,o]of i){let i=Array.from(o.keys());i.includes(`get`)&&i.push(`head`);for(let[a,[s,c]]of o){let o=s.slice().concat(async(e,r)=>{let i=n(e);return c.execute({request:e,response:r,logger:i,config:t})});t.cors&&o.unshift(async(e,r,a)=>{let o=n(e),s=Rt(i),l=typeof t.cors==`function`?await t.cors({request:e,endpoint:c,logger:o,defaultHeaders:s}):s;r.set(l),a()}),e[a](r,...o)}t.wrongMethodBehavior!==404&&a.set(r,Lt(i))}for(let[t,n]of a)e.all(t,n)},Vt=e=>`_httpMessage`in e&&typeof e._httpMessage==`object`&&e._httpMessage!==null&&`headersSent`in e._httpMessage&&typeof e._httpMessage.headersSent==`boolean`&&`setHeader`in e._httpMessage&&typeof e._httpMessage.setHeader==`function`,Ht=e=>`server`in e&&typeof e.server==`object`&&e.server!==null&&`close`in e.server&&typeof e.server.close==`function`,Ut=e=>`encrypted`in e&&typeof e.encrypted==`boolean`&&e.encrypted,Wt=({},e)=>void(!e.headersSent&&e.setHeader(`connection`,`close`)),Gt=e=>new Promise((t,n)=>void e.close(e=>e?n(e):t())),Kt=(e,{timeout:t=1e3,logger:n}={})=>{let r,i=new Set,a=e=>void i.delete(e.destroy()),o=e=>void(Vt(e)?!e._httpMessage.headersSent&&e._httpMessage.setHeader(`connection`,`close`):a(e)),s=e=>void(r?e.destroy():i.add(e.once(`close`,()=>void i.delete(e))));for(let t of e)for(let e of[`connection`,`secureConnection`])t.on(e,s);let c=async()=>{for(let t of e)t.on(`request`,Wt);n?.info(`Graceful shutdown`,{sockets:i.size,timeout:t});for(let e of i)(Ut(e)||Ht(e))&&o(e);for await(let e of re(10,Date.now()))if(i.size===0||Date.now()-e>=t)break;for(let e of i)a(e);return Promise.allSettled(e.map(Gt))};return{sockets:i,shutdown:()=>r??=c()}},qt=Symbol.for(`express-zod-api`),Jt=({errorHandler:e,getLogger:t})=>async(n,r,i,a)=>n?e.execute({error:x(n),request:r,response:i,input:null,output:null,ctx:{},logger:t(r)}):a(),Yt=({errorHandler:e,getLogger:t})=>async(n,r)=>{let a=i(404,`Can not ${n.method} ${n.path}`),o=t(n);try{await e.execute({request:n,response:r,logger:o,error:a,input:null,output:null,ctx:{}})}catch(e){Ye({response:r,logger:o,error:new je(x(e),a)})}},Xt=e=>(t,{},n)=>{if(Object.values(t?.files||[]).flat().find(({truncated:e})=>e))return n(e);n()},Zt=e=>({log:e.debug.bind(e)}),Qt=async({getLogger:e,config:t})=>{let n=await bt(`express-fileupload`),{limitError:r,beforeUpload:i,...a}={...typeof t.upload==`object`&&t.upload},o=[];return o.push(async(t,r,o)=>{let s=e(t);return await i?.({request:t,logger:s}),n({debug:!0,...a,abortOnLimit:!1,parseNested:!0,logger:Zt(s)})(t,r,o)}),r&&o.push(Xt(r)),o},$t=(e,{},t)=>{Buffer.isBuffer(e.body)&&(e.body={raw:e.body}),t()},en=({logger:e,config:{childLoggerProvider:t,accessLogger:n=({method:e,path:t},n)=>n.debug(`${e}: ${t}`)}})=>async(r,i,a)=>{let o=await t?.({request:r,parent:e})||e;n?.(r,o),r.res&&(r.res.locals[qt]={logger:o}),a()},tn=e=>t=>t?.res?.locals[qt]?.logger||e,nn=e=>process.on(`deprecation`,({message:t,namespace:n,name:r,stack:i})=>e.warn(`${r} (${n}): ${t}`,i.split(`
2
+ `).slice(1))),rn=({servers:e,logger:t,options:{timeout:n,beforeExit:r,events:i=[`SIGINT`,`SIGTERM`]}})=>{let a=Kt(e,{logger:t,timeout:n}),o=async()=>{await a.shutdown(),await r?.(),process.exit()};for(let e of i)process.on(e,o)},an=e=>{if(e.columns<132)return;let t=f(`Proudly supports transgender community.`.padStart(109)),n=f(`Start your API server with I/O schema validation and custom middlewares in minutes.`.padStart(109)),r=f(`Thank you for choosing Express Zod API for your project.`.padStart(132)),i=f(`for Lia`.padEnd(20)),a=d(`#F5A9B8`),o=d(`#5BCEFA`),s=Array(14).fill(o,1,3).fill(a,3,5).fill(m,5,7).fill(a,7,9).fill(o,9,12).fill(l,12,13),c=`
3
3
  8888888888 8888888888P 888 d8888 8888888b. 8888888
4
4
  888 d88P 888 d88888 888 Y88b 888
5
5
  888 d88P 888 d88P888 888 888 888
@@ -14,8 +14,8 @@ ${i}888${n}
14
14
  ${r}
15
15
  `;e.write(c.split(`
16
16
  `).map((e,t)=>s[t]?s[t](e):e).join(`
17
- `))},cn=e=>{e.startupLogo!==!1&&sn(process.stdout);let t=e.errorHandler||F,n=ht(e.logger)?e.logger:new yt(e.logger);n.debug(`Running`,{build:`v25.6.0`,env:process.env.NODE_ENV||`development`}),an(n);let r=nn({logger:n,config:e}),i={getLogger:rn(n),errorHandler:t},a=Zt(i),o=Xt(i);return{...i,logger:n,notFoundHandler:a,catcher:o,loggingMiddleware:r}},ln=(e,t)=>{let{logger:n,getLogger:r,notFoundHandler:i,loggingMiddleware:a}=cn(e);return Ht({app:e.app.use(a),routing:t,getLogger:r,config:e}),{notFoundHandler:i,logger:n}},un=async(e,t)=>{let{logger:n,getLogger:r,notFoundHandler:i,catcher:a,loggingMiddleware:o}=cn(e),s=g().disable(`x-powered-by`).set(`query parser`,e.queryParser??`simple`).use(o);if(e.compression){let t=await St(`compression`);s.use(t(typeof e.compression==`object`?e.compression:void 0))}await e.beforeRouting?.({app:s,getLogger:r}),Ht({app:s,routing:t,getLogger:r,config:e,parsers:{json:[e.jsonParser||g.json()],raw:[e.rawParser||g.raw(),tn],form:[e.formParser||g.urlencoded()],upload:e.upload?await en({config:e,getLogger:r}):[]}}),await e.afterRouting?.({app:s,getLogger:r}),s.use(a,i);let c=[],l=(e,t)=>()=>e.listen(t,()=>n.info(`Listening`,t)),u=[];if(e.http){let t=te.createServer(s);c.push(t),u.push(l(t,e.http.listen))}if(e.https){let t=ne.createServer(e.https.options,s);c.push(t),u.push(l(t,e.https.listen))}return c.length||n.warn(`No servers configured.`),e.gracefulShutdown&&on({logger:n,servers:c,options:e.gracefulShutdown===!0?{}:e.gracefulShutdown}),{app:s,logger:n,servers:u.map(e=>e())}},dn=e=>T(e)&&`or`in e,fn=e=>T(e)&&`and`in e,pn=e=>!fn(e)&&!dn(e),mn=e=>{let n=t.filter(pn,e),r=t.chain(t.prop(`and`),t.filter(fn,e)),[i,a]=t.partition(pn,r),o=t.concat(n,i),s=t.filter(dn,e);return t.map(t.prop(`or`),t.concat(s,a)).reduce((e,n)=>be(e,t.map(e=>pn(e)?[e]:e.and,n),([e,n])=>t.concat(e,n)),t.reject(t.isEmpty,[o]))};var hn=`a-im.accept.accept-additions.accept-ch.accept-charset.accept-datetime.accept-encoding.accept-features.accept-language.accept-signature.access-control.access-control-request-headers.access-control-request-method.alpn.alt-used.alternates.amp-cache-transform.apply-to-redirect-ref.authentication-control.authentication-info.authorization.available-dictionary.c-ext.c-man.c-opt.c-pep.c-pep-info.cache-control.cal-managed-id.caldav-timezones.capsule-protocol.cert-not-after.cert-not-before.client-cert.client-cert-chain.close.cmcd-object.cmcd-request.cmcd-session.cmcd-status.cmsd-dynamic.cmsd-static.concealed-auth-export.configuration-context.connection.content-digest.content-disposition.content-encoding.content-id.content-language.content-length.content-location.content-md5.content-range.content-script-type.content-type.cookie.cookie2.cross-origin-embedder-policy.cross-origin-embedder-policy-report-only.cross-origin-opener-policy.cross-origin-opener-policy-report-only.cross-origin-resource-policy.cta-common-access-token.dasl.date.dav.default-style.delta-base.deprecation.depth.derived-from.destination.detached-jws.differential-id.dictionary-id.digest.dpop.dpop-nonce.early-data.ediint-features.expect.expect-ct.ext.forwarded.from.getprofile.hobareg.host.http2-settings.if.if-match.if-modified-since.if-none-match.if-range.if-schedule-tag-match.if-unmodified-since.im.include-referred-token-binding-id.isolation.keep-alive.label.last-event-id.link.link-template.lock-token.man.max-forwards.memento-datetime.meter.method-check.method-check-expires.mime-version.negotiate.nel.odata-entityid.odata-isolation.odata-maxversion.odata-version.opt.ordering-type.origin.origin-agent-cluster.oscore.oslc-core-version.overwrite.p3p.pep.pep-info.permissions-policy.pics-label.ping-from.ping-to.position.pragma.prefer.preference-applied.priority.profileobject.protocol.protocol-info.protocol-query.protocol-request.proxy-authorization.proxy-features.proxy-instruction.public.public-key-pins.public-key-pins-report-only.range.redirect-ref.referer.referer-root.referrer-policy.repeatability-client-id.repeatability-first-sent.repeatability-request-id.repeatability-result.replay-nonce.reporting-endpoints.repr-digest.safe.schedule-reply.schedule-tag.sec-fetch-storage-access.sec-gpc.sec-purpose.sec-token-binding.sec-websocket-extensions.sec-websocket-key.sec-websocket-protocol.sec-websocket-version.security-scheme.setprofile.signature.signature-input.slug.soapaction.status-uri.sunset.surrogate-capability.tcn.te.timeout.topic.traceparent.tracestate.trailer.transfer-encoding.ttl.upgrade.urgency.uri.use-as-dictionary.user-agent.variant-vary.via.want-content-digest.want-digest.want-repr-digest.warning.x-content-type-options.x-frame-options`.split(`.`);const gn=`https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString`,_n={integer:0,number:0,string:``,boolean:!1,object:{},null:null,array:[]},vn=e=>e.replace(fe,e=>`{${e.slice(1)}}`),yn=({},e)=>{if(e.isResponse)throw new E(`Please use ez.upload() only for input.`,e);return{type:`string`,format:`binary`}},bn=({jsonSchema:e})=>({...e,externalDocs:{description:`raw binary data`,url:`https://swagger.io/specification/#working-with-binary-data`}}),xn=({zodSchema:e,jsonSchema:t})=>{if(!C(e,`union`)||!(`discriminator`in e._zod.def))return t;let n=e._zod.def.discriminator;return{...t,discriminator:t.discriminator??{propertyName:n}}},Sn=t.tryCatch(({jsonSchema:e})=>{if(!e.allOf)throw`no allOf`;return Dt(e,`throw`)},(e,{jsonSchema:t})=>t),Cn=({jsonSchema:e})=>{if(!e.anyOf)return e;let t=e.anyOf[0];return Object.assign(t,{type:kn(t.type)})},L=e=>e,wn=({jsonSchema:{examples:e,description:t}},n)=>{if(n.isResponse)throw new E(`Please use ez.dateOut() for output.`,n);let r={description:t||`YYYY-MM-DDTHH:mm:ss.sssZ`,type:`string`,format:`date-time`,pattern:`^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?)?Z?$`,externalDocs:{url:gn}};return e?.length&&(r.examples=e),r},Tn=({jsonSchema:{examples:e,description:t}},n)=>{if(!n.isResponse)throw new E(`Please use ez.dateIn() for input.`,n);let r={description:t||`YYYY-MM-DDTHH:mm:ss.sssZ`,type:`string`,format:`date-time`,externalDocs:{url:gn}};return e?.length&&(r.examples=e),r},En=()=>({type:`string`,format:`bigint`,pattern:`^-?\\d+$`}),Dn=({zodSchema:e,jsonSchema:t})=>e._zod.def.rest===null?{...t,items:{not:{}}}:t,On=e=>{let t=Array.isArray(e.type)?e.type[0]:e.type;return _n?.[t]},kn=e=>e===`null`?e:typeof e==`string`?[e,`null`]:e&&[...new Set(e).add(`null`)],An=({zodSchema:e,jsonSchema:t},n)=>{let r=e._zod.def[n.isResponse?`out`:`in`],i=e._zod.def[n.isResponse?`in`:`out`];if(!C(r,`transform`))return t;let a=L(Ln(i,{ctx:n}));if(_(a))if(n.isResponse){let e=Se(r,On(a));if(e&&[`number`,`string`,`boolean`].includes(e))return{...t,type:e}}else{let{type:e,...t}=a;return{...t,format:`${t.format||e} (preprocessed)`}}return t},jn=({jsonSchema:e})=>{if(e.type!==`object`)return e;let t=e;return!t.properties||!(`raw`in t.properties)||!T(t.properties.raw)?e:t.properties.raw},Mn=e=>e.length?t.fromPairs(t.zip(t.times(e=>`example${e+1}`,e.length),t.map(t.objOf(`value`),e))):void 0,Nn=(e,t)=>t?.includes(e)||e.startsWith(`x-`)||hn.includes(e),Pn=({path:e,method:n,request:r,inputSources:i,makeRef:a,composition:o,isHeader:s,security:c,description:l=`${n.toUpperCase()} ${e} Parameter`})=>{let u=Dt(r),d=pe(e),f=i.includes(`query`),p=i.includes(`params`),m=i.includes(`headers`),ee=e=>p&&d.includes(e),h=t.chain(t.filter(e=>e.type===`header`),c??[]).map(({name:e})=>e),g=t=>m&&(s?.(t,n,e)??Nn(t,h));return Object.entries(u.properties).reduce((e,[n,r])=>{if(!T(r))return e;let i=ee(n)?`path`:g(n)?`header`:f?`query`:void 0;if(!i)return e;let s=L(r),c=o===`components`?a(r.id||JSON.stringify(r),s,w(l,n)):s;return e.concat({name:n,in:i,deprecated:r.deprecated,required:u.required?.includes(n)||!1,description:s.description||l,schema:c,examples:Mn(_(s)&&s.examples?.length?s.examples:t.pluck(n,u.examples?.filter(t.both(T,t.has(n)))||[]))})},[])},Fn={nullable:Cn,union:xn,bigint:En,intersection:Sn,tuple:Dn,pipe:An,[De]:wn,[ke]:Tn,[O]:yn,[k]:jn,[Te]:bn},In=(e,n,r)=>{let i=[e,n];for(;i.length;){let e=i.shift();if(t.is(Object,e)){if(ae(e)&&!e.$ref.startsWith(`#/components`)){let t=n[e.$ref.split(`/`).pop()];t&&(e.$ref=r.makeRef(t.id||t,L(t)).$ref);continue}i.push(...t.values(e))}t.is(Array,e)&&i.push(...t.values(e))}return e},Ln=(t,{ctx:n,rules:i=Fn})=>{let{$defs:a={},properties:o={}}=r.toJSONSchema(r.object({subject:t}),{unrepresentable:`any`,io:n.isResponse?`output`:`input`,override:t=>{let r=e(t.zodSchema),a=i[r&&r in i?r:t.zodSchema._zod.def.type];if(a){let e={...a(t,n)};for(let e in t.jsonSchema)delete t.jsonSchema[e];Object.assign(t.jsonSchema,e)}}});return In(T(o.subject)?o.subject:{},a,n)},Rn=(e,n)=>{if(ae(e))return[e,!1];let r=!1,i=t.map(e=>{let[t,i]=Rn(e,n);return r||=i,t}),a=t.omit(n),o={properties:a,examples:t.map(a),required:t.without(n),allOf:i,oneOf:i,anyOf:i},s=t.evolve(o,e);return[s,r||!!s.required?.length]},zn=({method:e,path:n,schema:r,mimeTypes:i,variant:a,makeRef:o,composition:s,hasMultipleStatusCodes:c,statusCode:l,brandHandling:u,description:d=`${e.toUpperCase()} ${n} ${xe(a)} response ${c?l:``}`.trim()})=>{if(!we(e,i))return{description:d};let f=L(Ln(r,{rules:{...u,...Fn},ctx:{isResponse:!0,makeRef:o,path:n,method:e}})),p=[];_(f)&&f.examples&&(p.push(...f.examples),delete f.examples);let m={schema:s===`components`?o(r,f,w(d)):f,examples:Mn(p)};return{description:d,content:t.fromPairs(t.xprod(i,[m]))}},Bn=({format:e})=>{let t={type:`http`,scheme:`bearer`};return e&&(t.bearerFormat=e),t},Vn=({name:e},t)=>{let n={type:`apiKey`,in:`query`,name:e};return t?.includes(`body`)&&(t?.includes(`query`)?(n[`x-in-alternative`]=`body`,n.description=`${e} CAN also be supplied within the request body`):(n[`x-in-actual`]=`body`,n.description=`${e} MUST be supplied within the request body instead of query`)),n},Hn=({name:e})=>({type:`apiKey`,in:`header`,name:e}),Un=({name:e})=>({type:`apiKey`,in:`cookie`,name:e}),Wn=({url:e})=>({type:`openIdConnect`,openIdConnectUrl:e}),Gn=({flows:e={}})=>({type:`oauth2`,flows:t.map(e=>({...e,scopes:e.scopes||{}}),t.reject(t.isNil,e))}),Kn=(e,t=[])=>{let n=e=>e.type===`basic`?{type:`http`,scheme:`basic`}:e.type===`bearer`?Bn(e):e.type===`input`?Vn(e,t):e.type===`header`?Hn(e):e.type===`cookie`?Un(e):e.type===`openid`?Wn(e):Gn(e);return e.map(e=>e.map(n))},qn=(e,t,n)=>e.map(e=>e.reduce((e,r)=>{let i=n(r),a=[`oauth2`,`openIdConnect`].includes(r.type);return Object.assign(e,{[i]:a?t:[]})},{})),Jn=({schema:e,brandHandling:t,makeRef:n,path:r,method:i})=>Ln(e,{rules:{...t,...Fn},ctx:{isResponse:!1,makeRef:n,path:r,method:i}}),Yn=({method:e,path:n,schema:r,request:i,mimeType:a,makeRef:o,composition:s,paramNames:c,description:l=`${e.toUpperCase()} ${n} Request body`})=>{let[u,d]=Rn(L(i),c),f=[];_(u)&&u.examples&&(f.push(...u.examples),delete u.examples);let p={schema:s===`components`?o(r,u,w(l)):u,examples:Mn(f.length?f:Dt(i).examples?.filter(e=>T(e)&&!Array.isArray(e)).map(t.omit(c))||[])},m={description:l,content:{[a]:p}};return(d||a===y.raw)&&(m.required=!0),m},Xn=e=>Object.entries(e).reduce((e,[t,n])=>{if(!n)return e;let r={name:t,description:typeof n==`string`?n:n.description};return typeof n==`object`&&n.url&&(r.externalDocs={url:n.url}),e.concat(r)},[]),Zn=e=>e.length<=50?e:e.slice(0,49)+`…`,Qn=e=>e.length?e.slice():void 0;var $n=class extends ie{#e=new Map;#t=new Map;#n=new Map;#r(e,t,n=this.#n.get(e)){return n||(n=`Schema${this.#n.size+1}`,this.#n.set(e,n)),this.addSchema(n,t),{$ref:`#/components/schemas/${n}`}}#i(e,t,n){let r=n||w(t,e),i=this.#t.get(r);if(i===void 0)return this.#t.set(r,1),r;if(n)throw new E(`Duplicated operationId: "${n}"`,{method:t,isResponse:!1,path:e});return i++,this.#t.set(r,i),`${r}${i}`}#a(e){let t=JSON.stringify(e);for(let e in this.rootDoc.components?.securitySchemes||{})if(t===JSON.stringify(this.rootDoc.components?.securitySchemes?.[e]))return e;let n=(this.#e.get(e.type)||0)+1;return this.#e.set(e.type,n),`${e.type.toUpperCase()}_${n}`}constructor({routing:e,config:n,title:r,version:i,serverUrl:a,descriptions:o,brandHandling:s,tags:c,isHeader:l,hasSummaryFromDescription:u=!0,hasHeadMethod:d=!0,composition:f=`inline`}){super(),this.addInfo({title:r,version:i});for(let e of typeof a==`string`?[a]:a)this.addServer({url:e});let p=(e,r,i)=>{let a={path:r,method:e,endpoint:i,composition:f,brandHandling:s,makeRef:this.#r.bind(this)},{description:c,shortDescription:d,scopes:p,inputSchema:m}=i,ee=d?Zn(d):u&&c?Zn(c):void 0,h=ve(e,n.inputSources),g=this.#i(r,e,i.getOperationId(e)),te=Jn({...a,schema:m}),ne=mn(i.security),re=Pn({...a,inputSources:h,isHeader:l,security:ne,request:te,description:o?.requestParameter?.call(null,{method:e,path:r,operationId:g})}),ie={};for(let t of at){let n=i.getResponses(t);for(let{mimeTypes:i,schema:s,statusCodes:c}of n)for(let l of c)ie[l]=zn({...a,variant:t,schema:s,mimeTypes:i,statusCode:l,hasMultipleStatusCodes:n.length>1||c.length>1,description:o?.[`${t}Response`]?.call(null,{method:e,path:r,operationId:g,statusCode:l})})}let ae=h.includes(`body`)?Yn({...a,request:te,paramNames:t.pluck(`name`,re),schema:m,mimeType:y[i.requestType],description:o?.requestBody?.call(null,{method:e,path:r,operationId:g})}):void 0,_=qn(Kn(ne,h),p,e=>{let t=this.#a(e);return this.addSecurityScheme(t,e),t}),oe={operationId:g,summary:ee,description:c,deprecated:i.isDeprecated||void 0,tags:Qn(i.tags),parameters:Qn(re),requestBody:ae,security:Qn(_),responses:ie};this.addPath(vn(r),{[e]:oe})};Lt({routing:e,onEndpoint:d?At(p):p}),c&&(this.rootDoc.tags=Xn(c))}};const er=e=>oe({...e,headers:{"content-type":y.json,...e?.headers}}),tr=e=>se(e),nr=e=>{let t={warn:[],error:[],info:[],debug:[]};return new Proxy(e||{},{get(e,n,r){return n===`_getLogs`?()=>t:gt(n)?(...e)=>t[n].push(e):Reflect.get(e,n,r)}})},rr=({requestProps:e,responseOptions:t,configProps:n,loggerProps:r})=>{let i=er(e),a=tr({req:i,...t});a.req=t?.req||i,i.res=a;let o=nr(r);return{requestMock:i,responseMock:a,loggerMock:o,configMock:{cors:!1,logger:o,...n}}},ir=async({endpoint:e,...t})=>{let{requestMock:n,responseMock:r,loggerMock:i,configMock:a}=rr(t);return await e.execute({request:n,response:r,config:a,logger:i}),{requestMock:n,responseMock:r,loggerMock:i}},ar=async({middleware:e,options:t={},...n})=>{let{requestMock:r,responseMock:i,loggerMock:a,configMock:{inputSources:o,errorHandler:s=F}}=rr(n),c={request:r,response:i,logger:a,input:ye(r,o),options:t};try{return{requestMock:r,responseMock:i,loggerMock:a,output:await e.execute(c)}}catch(e){return await s.execute({...c,error:x(e),output:null}),{requestMock:r,responseMock:i,loggerMock:a,output:{}}}},R=v.factory,or=[R.createModifier(v.SyntaxKind.ExportKeyword)],sr=[R.createModifier(v.SyntaxKind.AsyncKeyword)],cr={public:[R.createModifier(v.SyntaxKind.PublicKeyword)],protectedReadonly:[R.createModifier(v.SyntaxKind.ProtectedKeyword),R.createModifier(v.SyntaxKind.ReadonlyKeyword)]},lr=(e,t)=>v.addSyntheticLeadingComment(e,v.SyntaxKind.MultiLineCommentTrivia,`* ${t} `,!0),ur=(e,t)=>{let n=v.createSourceFile(`print.ts`,``,v.ScriptTarget.Latest,!1,v.ScriptKind.TS);return v.createPrinter(t).printNode(v.EmitHint.Unspecified,e,n)},dr=/^[A-Za-z_$][A-Za-z0-9_$]*$/,fr=e=>typeof e==`string`&&dr.test(e)?R.createIdentifier(e):Y(e),pr=(e,...t)=>R.createTemplateExpression(R.createTemplateHead(e),t.map(([e,n=``],r)=>R.createTemplateSpan(e,r===t.length-1?R.createTemplateTail(n):R.createTemplateMiddle(n)))),mr=(e,{type:t,mod:n,init:r,optional:i}={})=>R.createParameterDeclaration(n,void 0,e,i?R.createToken(v.SyntaxKind.QuestionToken):void 0,t?B(t):void 0,r),z=e=>Object.entries(e).map(([e,t])=>mr(e,typeof t==`string`||typeof t==`number`||typeof t==`object`&&`kind`in t?{type:t}:t)),hr=(e,t=[])=>R.createConstructorDeclaration(cr.public,e,R.createBlock(t)),B=(e,n)=>typeof e==`number`?R.createKeywordTypeNode(e):typeof e==`string`||v.isIdentifier(e)?R.createTypeReferenceNode(e,n&&t.map(B,n)):e,gr=B(`Record`,[v.SyntaxKind.StringKeyword,v.SyntaxKind.AnyKeyword]),V=e=>{let t=new Map;for(let n of e)t.set(Pr(n)?n.kind:n,n);return R.createUnionTypeNode(Array.from(t.values()))},_r=(e,n,{isOptional:r,isDeprecated:i,comment:a}={})=>{let o=B(n),s=R.createPropertySignature(void 0,fr(e),r?R.createToken(v.SyntaxKind.QuestionToken):void 0,r?V([o,B(v.SyntaxKind.UndefinedKeyword)]):o),c=t.reject(t.isNil,[i?`@deprecated`:void 0,a]);return c.length?lr(s,c.join(` `)):s},vr=e=>v.setEmitFlags(e,v.EmitFlags.SingleLine),yr=(...e)=>R.createArrayBindingPattern(e.map(e=>R.createBindingElement(void 0,void 0,e))),H=(e,t,{type:n,expose:r}={})=>R.createVariableStatement(r&&or,R.createVariableDeclarationList([R.createVariableDeclaration(e,void 0,n?B(n):void 0,t)],v.NodeFlags.Const)),br=(e,n)=>U(e,V(t.map(X,n)),{expose:!0}),U=(e,t,{expose:n,comment:r,params:i}={})=>{let a=R.createTypeAliasDeclaration(n?or:void 0,e,i&&Dr(i),t);return r?lr(a,r):a},xr=(e,t)=>R.createPropertyDeclaration(cr.public,e,void 0,B(t),void 0),Sr=(e,t,n,{typeParams:r,returns:i}={})=>R.createMethodDeclaration(cr.public,void 0,e,void 0,r&&Dr(r),t,i,R.createBlock(n)),Cr=(e,t,{typeParams:n}={})=>R.createClassDeclaration(or,e,n&&Dr(n),void 0,t),wr=e=>R.createTypeOperatorNode(v.SyntaxKind.KeyOfKeyword,B(e)),Tr=e=>B(Promise.name,[e]),Er=(e,t,{expose:n,comment:r}={})=>{let i=R.createInterfaceDeclaration(n?or:void 0,e,void 0,void 0,t);return r?lr(i,r):i},Dr=e=>(Array.isArray(e)?e.map(e=>t.pair(e,void 0)):Object.entries(e)).map(([e,t])=>{let{type:n,init:r}=typeof t==`object`&&`init`in t?t:{type:t};return R.createTypeParameterDeclaration([],e,n?B(n):void 0,r?B(r):void 0)}),W=(e,n,{isAsync:r}={})=>R.createArrowFunction(r?sr:void 0,void 0,Array.isArray(e)?t.map(mr,e):z(e),void 0,void 0,n),G=e=>e,Or=(e,t,n)=>R.createConditionalExpression(e,R.createToken(v.SyntaxKind.QuestionToken),t,R.createToken(v.SyntaxKind.ColonToken),n),K=(e,...t)=>(...n)=>R.createCallExpression(t.reduce((e,t)=>typeof t==`string`||v.isIdentifier(t)?R.createPropertyAccessExpression(e,t):R.createElementAccessExpression(e,t),typeof e==`string`?R.createIdentifier(e):e),void 0,n),q=(e,...t)=>R.createNewExpression(R.createIdentifier(e),void 0,t),kr=(e,t)=>B(`Extract`,[e,t]),Ar=(e,t)=>R.createExpressionStatement(R.createBinaryExpression(e,R.createToken(v.SyntaxKind.EqualsToken),t)),J=(e,t)=>R.createIndexedAccessTypeNode(B(e),B(t)),jr=e=>V([B(e),Tr(e)]),Mr=(e,t)=>R.createFunctionTypeNode(void 0,z(e),B(t)),Y=e=>typeof e==`number`?R.createNumericLiteral(e):typeof e==`bigint`?R.createBigIntLiteral(e.toString()):typeof e==`boolean`?e?R.createTrue():R.createFalse():e===null?R.createNull():R.createStringLiteral(e),X=e=>R.createLiteralTypeNode(Y(e)),Nr=[v.SyntaxKind.AnyKeyword,v.SyntaxKind.BigIntKeyword,v.SyntaxKind.BooleanKeyword,v.SyntaxKind.NeverKeyword,v.SyntaxKind.NumberKeyword,v.SyntaxKind.ObjectKeyword,v.SyntaxKind.StringKeyword,v.SyntaxKind.SymbolKeyword,v.SyntaxKind.UndefinedKeyword,v.SyntaxKind.UnknownKeyword,v.SyntaxKind.VoidKeyword],Pr=e=>Nr.includes(e.kind);var Fr=class{paths=new Set;tags=new Map;registry=new Map;#e={pathType:R.createIdentifier(`Path`),implementationType:R.createIdentifier(`Implementation`),keyParameter:R.createIdentifier(`key`),pathParameter:R.createIdentifier(`path`),paramsArgument:R.createIdentifier(`params`),ctxArgument:R.createIdentifier(`ctx`),methodParameter:R.createIdentifier(`method`),requestParameter:R.createIdentifier(`request`),eventParameter:R.createIdentifier(`event`),dataParameter:R.createIdentifier(`data`),handlerParameter:R.createIdentifier(`handler`),msgParameter:R.createIdentifier(`msg`),parseRequestFn:R.createIdentifier(`parseRequest`),substituteFn:R.createIdentifier(`substitute`),provideMethod:R.createIdentifier(`provide`),onMethod:R.createIdentifier(`on`),implementationArgument:R.createIdentifier(`implementation`),hasBodyConst:R.createIdentifier(`hasBody`),undefinedValue:R.createIdentifier(`undefined`),responseConst:R.createIdentifier(`response`),restConst:R.createIdentifier(`rest`),searchParamsConst:R.createIdentifier(`searchParams`),defaultImplementationConst:R.createIdentifier(`defaultImplementation`),clientConst:R.createIdentifier(`client`),contentTypeConst:R.createIdentifier(`contentType`),isJsonConst:R.createIdentifier(`isJSON`),sourceProp:R.createIdentifier(`source`)};interfaces={input:R.createIdentifier(`Input`),positive:R.createIdentifier(`PositiveResponse`),negative:R.createIdentifier(`NegativeResponse`),encoded:R.createIdentifier(`EncodedResponse`),response:R.createIdentifier(`Response`)};methodType=br(`Method`,ue);someOfType=U(`SomeOf`,J(`T`,wr(`T`)),{params:[`T`]});requestType=U(`Request`,wr(this.interfaces.input),{expose:!0});constructor(e){this.serverUrl=e}someOf=({name:e})=>B(this.someOfType.name,[e]);makePathType=()=>br(this.#e.pathType,Array.from(this.paths));makePublicInterfaces=()=>Object.keys(this.interfaces).map(e=>Er(this.interfaces[e],Array.from(this.registry).map(([t,{store:n,isDeprecated:r}])=>_r(t,n[e],{isDeprecated:r})),{expose:!0}));makeEndpointTags=()=>H(`endpointTags`,R.createObjectLiteralExpression(Array.from(this.tags).map(([e,n])=>R.createPropertyAssignment(fr(e),R.createArrayLiteralExpression(t.map(Y,n))))),{expose:!0});makeImplementationType=()=>U(this.#e.implementationType,Mr({[this.#e.methodParameter.text]:this.methodType.name,[this.#e.pathParameter.text]:v.SyntaxKind.StringKeyword,[this.#e.paramsArgument.text]:gr,[this.#e.ctxArgument.text]:{optional:!0,type:`T`}},Tr(v.SyntaxKind.AnyKeyword)),{expose:!0,params:{T:{init:v.SyntaxKind.UnknownKeyword}}});makeParseRequestFn=()=>H(this.#e.parseRequestFn,W({[this.#e.requestParameter.text]:v.SyntaxKind.StringKeyword},R.createAsExpression(K(this.#e.requestParameter,G(`split`))(R.createRegularExpressionLiteral(`/ (.+)/`),Y(2)),R.createTupleTypeNode([B(this.methodType.name),B(this.#e.pathType)]))));makeSubstituteFn=()=>H(this.#e.substituteFn,W({[this.#e.pathParameter.text]:v.SyntaxKind.StringKeyword,[this.#e.paramsArgument.text]:gr},R.createBlock([H(this.#e.restConst,R.createObjectLiteralExpression([R.createSpreadAssignment(this.#e.paramsArgument)])),R.createForInStatement(R.createVariableDeclarationList([R.createVariableDeclaration(this.#e.keyParameter)],v.NodeFlags.Const),this.#e.paramsArgument,R.createBlock([Ar(this.#e.pathParameter,K(this.#e.pathParameter,G(`replace`))(pr(`:`,[this.#e.keyParameter]),W([],R.createBlock([R.createExpressionStatement(R.createDeleteExpression(R.createElementAccessExpression(this.#e.restConst,this.#e.keyParameter))),R.createReturnStatement(R.createElementAccessExpression(this.#e.paramsArgument,this.#e.keyParameter))]))))])),R.createReturnStatement(R.createAsExpression(R.createArrayLiteralExpression([this.#e.pathParameter,this.#e.restConst]),B(`const`)))])));#t=()=>Sr(this.#e.provideMethod,z({[this.#e.requestParameter.text]:`K`,[this.#e.paramsArgument.text]:J(this.interfaces.input,`K`),[this.#e.ctxArgument.text]:{optional:!0,type:`T`}}),[H(yr(this.#e.methodParameter,this.#e.pathParameter),K(this.#e.parseRequestFn)(this.#e.requestParameter)),R.createReturnStatement(K(R.createThis(),this.#e.implementationArgument)(this.#e.methodParameter,R.createSpreadElement(K(this.#e.substituteFn)(this.#e.pathParameter,this.#e.paramsArgument)),this.#e.ctxArgument))],{typeParams:{K:this.requestType.name},returns:Tr(J(this.interfaces.response,`K`))});makeClientClass=e=>Cr(e,[hr([mr(this.#e.implementationArgument,{type:B(this.#e.implementationType,[`T`]),mod:cr.protectedReadonly,init:this.#e.defaultImplementationConst})]),this.#t()],{typeParams:[`T`]});#n=e=>pr(`?`,[q(URLSearchParams.name,e)]);#r=()=>q(URL.name,pr(``,[this.#e.pathParameter],[this.#e.searchParamsConst]),Y(this.serverUrl));makeDefaultImplementation=()=>{let e=R.createPropertyAssignment(G(`method`),K(this.#e.methodParameter,G(`toUpperCase`))()),t=R.createPropertyAssignment(G(`headers`),Or(this.#e.hasBodyConst,R.createObjectLiteralExpression([R.createPropertyAssignment(Y(`Content-Type`),Y(y.json))]),this.#e.undefinedValue)),n=R.createPropertyAssignment(G(`body`),Or(this.#e.hasBodyConst,K(JSON[Symbol.toStringTag],G(`stringify`))(this.#e.paramsArgument),this.#e.undefinedValue)),r=H(this.#e.responseConst,R.createAwaitExpression(K(fetch.name)(this.#r(),R.createObjectLiteralExpression([e,t,n])))),i=H(this.#e.hasBodyConst,R.createLogicalNot(K(R.createArrayLiteralExpression([Y(`get`),Y(`head`),Y(`delete`)]),G(`includes`))(this.#e.methodParameter))),a=H(this.#e.searchParamsConst,Or(this.#e.hasBodyConst,Y(``),this.#n(this.#e.paramsArgument))),o=H(this.#e.contentTypeConst,K(this.#e.responseConst,G(`headers`),G(`get`))(Y(`content-type`))),s=R.createIfStatement(R.createPrefixUnaryExpression(v.SyntaxKind.ExclamationToken,this.#e.contentTypeConst),R.createReturnStatement()),c=H(this.#e.isJsonConst,K(this.#e.contentTypeConst,G(`startsWith`))(Y(y.json))),l=R.createReturnStatement(K(this.#e.responseConst,Or(this.#e.isJsonConst,Y(G(`json`)),Y(G(`text`))))());return H(this.#e.defaultImplementationConst,W([this.#e.methodParameter,this.#e.pathParameter,this.#e.paramsArgument],R.createBlock([i,a,r,o,s,c,l]),{isAsync:!0}),{type:this.#e.implementationType})};#i=()=>hr(z({request:`K`,params:J(this.interfaces.input,`K`)}),[H(yr(this.#e.pathParameter,this.#e.restConst),K(this.#e.substituteFn)(R.createElementAccessExpression(K(this.#e.parseRequestFn)(this.#e.requestParameter),Y(1)),this.#e.paramsArgument)),H(this.#e.searchParamsConst,this.#n(this.#e.restConst)),Ar(R.createPropertyAccessExpression(R.createThis(),this.#e.sourceProp),q(`EventSource`,this.#r()))]);#a=e=>R.createTypeLiteralNode([_r(G(`event`),e)]);#o=()=>Sr(this.#e.onMethod,z({[this.#e.eventParameter.text]:`E`,[this.#e.handlerParameter.text]:Mr({[this.#e.dataParameter.text]:J(kr(`R`,vr(this.#a(`E`))),X(G(`data`)))},jr(v.SyntaxKind.VoidKeyword))}),[R.createExpressionStatement(K(R.createThis(),this.#e.sourceProp,G(`addEventListener`))(this.#e.eventParameter,W([this.#e.msgParameter],K(this.#e.handlerParameter)(K(JSON[Symbol.toStringTag],G(`parse`))(R.createPropertyAccessExpression(R.createParenthesizedExpression(R.createAsExpression(this.#e.msgParameter,B(MessageEvent.name))),G(`data`))))))),R.createReturnStatement(R.createThis())],{typeParams:{E:J(`R`,X(G(`event`)))}});makeSubscriptionClass=e=>Cr(e,[xr(this.#e.sourceProp,`EventSource`),this.#i(),this.#o()],{typeParams:{K:kr(this.requestType.name,R.createTemplateLiteralType(R.createTemplateHead(`get `),[R.createTemplateLiteralTypeSpan(B(v.SyntaxKind.StringKeyword),R.createTemplateTail(``))])),R:kr(J(this.interfaces.positive,`K`),vr(this.#a(v.SyntaxKind.StringKeyword)))}});makeUsageStatements=(e,t)=>[H(this.#e.clientConst,q(e)),K(this.#e.clientConst,this.#e.provideMethod)(Y(`get /v1/user/retrieve`),R.createObjectLiteralExpression([R.createPropertyAssignment(`id`,Y(`10`))])),K(q(t,Y(`get /v1/events/stream`),R.createObjectLiteralExpression()),this.#e.onMethod)(Y(`time`),W([`time`],R.createBlock([])))]};const Ir=(t,{onEach:n,rules:r,onMissing:i,ctx:a={}})=>{let o=e(t),s=o&&o in r?r[o]:r[t._zod.def.type],c=e=>Ir(e,{ctx:a,onEach:n,rules:r,onMissing:i}),l=s?s(t,{...a,next:c}):i(t,a),u=n&&n(t,{prev:l,...a});return u?{...l,...u}:l},{factory:Z}=v,Lr={[v.SyntaxKind.AnyKeyword]:``,[v.SyntaxKind.BigIntKeyword]:BigInt(0),[v.SyntaxKind.BooleanKeyword]:!1,[v.SyntaxKind.NumberKeyword]:0,[v.SyntaxKind.ObjectKeyword]:{},[v.SyntaxKind.StringKeyword]:``,[v.SyntaxKind.UndefinedKeyword]:void 0},Rr={name:t.path([`name`,`text`]),type:t.path([`type`]),optional:t.path([`questionToken`])},zr=({_zod:{def:e}})=>{let t=e.values.map(e=>e===void 0?B(v.SyntaxKind.UndefinedKeyword):X(e));return t.length===1?t[0]:V(t)},Br=({_zod:{def:e}},{next:t})=>{let n=[...e.parts],r=()=>{let e=``;for(;n.length;){let t=n.shift();if(C(t)){n.unshift(t);break}e+=t??``}return e},i=Z.createTemplateHead(r()),a=[];for(;n.length;){let e=t(n.shift()),i=r(),o=n.length?Z.createTemplateMiddle:Z.createTemplateTail;a.push(Z.createTemplateLiteralTypeSpan(e,o(i)))}return a.length?Z.createTemplateLiteralType(i,a):X(i.text)},Vr=(e,{isResponse:t,next:r,makeAlias:i})=>{let a=()=>{let i=Object.entries(e._zod.def.shape).map(([e,i])=>{let{description:a,deprecated:o}=n.get(i)||{};return _r(e,r(i),{comment:a,isDeprecated:o,isOptional:(t?i._zod.optout:i._zod.optin)===`optional`})});return Z.createTypeLiteralNode(i)};return We(e,{io:t?`output`:`input`})?i(e,a):a()},Hr=({_zod:{def:e}},{next:t})=>Z.createArrayTypeNode(t(e.element)),Ur=({_zod:{def:e}})=>V(Object.values(e.entries).map(X)),Wr=({_zod:{def:e}},{next:t})=>V(e.options.map(t)),Gr=e=>Lr?.[e.kind],Kr=({_zod:{def:e}},{next:t})=>V([t(e.innerType),X(null)]),qr=({_zod:{def:e}},{next:t})=>Z.createTupleTypeNode(e.items.map(t).concat(e.rest===null?[]:Z.createRestTypeNode(t(e.rest)))),Jr=({_zod:{def:e}},{next:t})=>B(`Record`,[e.keyType,e.valueType].map(t)),Yr=t.tryCatch(e=>{if(!e.every(v.isTypeLiteralNode))throw Error(`Not objects`);let n=t.chain(t.prop(`members`),e),r=t.uniqWith((...e)=>{if(!t.eqBy(Rr.name,...e))return!1;if(t.both(t.eqBy(Rr.type),t.eqBy(Rr.optional))(...e))return!0;throw Error(`Has conflicting prop`)},n);return Z.createTypeLiteralNode(r)},(e,t)=>Z.createIntersectionTypeNode(t)),Xr=({_zod:{def:e}},{next:t})=>Yr([e.left,e.right].map(t)),Q=e=>()=>B(e),$=({_zod:{def:e}},{next:t})=>t(e.innerType),Zr=e=>B(e?v.SyntaxKind.UnknownKeyword:v.SyntaxKind.AnyKeyword),Qr=({_zod:{def:e}},{next:t,isResponse:n})=>{let r=e[n?`out`:`in`],i=e[n?`in`:`out`];if(!C(r,`transform`))return t(r);let a=Se(r,Gr(t(i))),o={number:v.SyntaxKind.NumberKeyword,bigint:v.SyntaxKind.BigIntKeyword,boolean:v.SyntaxKind.BooleanKeyword,string:v.SyntaxKind.StringKeyword,undefined:v.SyntaxKind.UndefinedKeyword,object:v.SyntaxKind.ObjectKeyword};return B(a&&o[a]||Zr(n))},$r=()=>X(null),ei=({_zod:{def:e}},{makeAlias:t,next:n})=>t(e.getter,()=>n(e.getter())),ti=()=>B(`Buffer`),ni=(e,{next:t})=>t(e._zod.def.shape.raw),ri={string:Q(v.SyntaxKind.StringKeyword),number:Q(v.SyntaxKind.NumberKeyword),bigint:Q(v.SyntaxKind.BigIntKeyword),boolean:Q(v.SyntaxKind.BooleanKeyword),any:Q(v.SyntaxKind.AnyKeyword),undefined:Q(v.SyntaxKind.UndefinedKeyword),[De]:Q(v.SyntaxKind.StringKeyword),[ke]:Q(v.SyntaxKind.StringKeyword),never:Q(v.SyntaxKind.NeverKeyword),void:Q(v.SyntaxKind.UndefinedKeyword),unknown:Q(v.SyntaxKind.UnknownKeyword),null:$r,array:Hr,tuple:qr,record:Jr,object:Vr,literal:zr,template_literal:Br,intersection:Xr,union:Wr,default:$,enum:Ur,optional:$,nonoptional:$,nullable:Kr,catch:$,pipe:Qr,lazy:ei,readonly:$,[Te]:ti,[k]:ni},ii=(e,{brandHandling:t,ctx:n})=>Ir(e,{rules:{...t,...ri},onMissing:({},{isResponse:e})=>Zr(e),ctx:n});var ai=class extends Fr{#e=[this.someOfType];#t=new Map;#n=[];#r(e,t){let n=this.#t.get(e)?.name?.text;if(!n){n=`Type${this.#t.size+1}`;let r=X(null);this.#t.set(e,U(n,r)),this.#t.set(e,U(n,t()))}return B(n)}constructor({routing:e,brandHandling:n,variant:i=`client`,clientClassName:a=`Client`,subscriptionClassName:o=`Subscription`,serverUrl:s=`https://example.com`,noContent:c=r.undefined(),hasHeadMethod:l=!0}){super(s);let u={makeAlias:this.#r.bind(this)},d={brandHandling:n,ctx:{...u,isResponse:!1}},f={brandHandling:n,ctx:{...u,isResponse:!0}},p=(e,n,r)=>{let i=w.bind(null,e,n),{isDeprecated:a,inputSchema:o,tags:s}=r,l=`${e} ${n}`,u=U(i(`input`),ii(o,d),{comment:l});this.#e.push(u);let p=at.reduce((n,a)=>{let o=r.getResponses(a),s=t.chain(([t,{schema:n,mimeTypes:r,statusCodes:o}])=>{let s=we(e,r),u=U(i(a,`variant`,`${t+1}`),ii(s?n:c,f),{comment:l});return this.#e.push(u),o.map(e=>_r(e,u.name))},Array.from(o.entries())),u=Er(i(a,`response`,`variants`),s,{comment:l});return this.#e.push(u),Object.assign(n,{[a]:u})},{});this.paths.add(n);let m=X(l),ee={input:B(u.name),positive:this.someOf(p.positive),negative:this.someOf(p.negative),response:V([J(this.interfaces.positive,m),J(this.interfaces.negative,m)]),encoded:R.createIntersectionTypeNode([B(p.positive.name),B(p.negative.name)])};this.registry.set(l,{isDeprecated:a,store:ee}),this.tags.set(l,s)};Lt({routing:e,onEndpoint:l?At(p):p}),this.#e.unshift(...this.#t.values()),this.#e.push(this.makePathType(),this.methodType,...this.makePublicInterfaces(),this.requestType),i!==`types`&&(this.#e.push(this.makeEndpointTags(),this.makeParseRequestFn(),this.makeSubstituteFn(),this.makeImplementationType(),this.makeDefaultImplementation(),this.makeClientClass(a),this.makeSubscriptionClass(o)),this.#n.push(...this.makeUsageStatements(a,o)))}#i(e){return this.#n.length?this.#n.map(t=>typeof t==`string`?t:ur(t,e)).join(`
18
- `):void 0}print(e){let t=this.#i(e),n=t&&v.addSyntheticLeadingComment(v.addSyntheticLeadingComment(R.createEmptyStatement(),v.SyntaxKind.SingleLineCommentTrivia,` Usage example:`),v.SyntaxKind.MultiLineCommentTrivia,`\n${t}`);return this.#e.concat(n||[]).map((t,n)=>ur(t,n<this.#e.length?e:{...e,omitTrailingSemicolon:!0})).join(`
17
+ `))},on=e=>{e.startupLogo!==!1&&an(process.stdout);let t=e.errorHandler||ot,n=mt(e.logger)?e.logger:new vt(e.logger);n.debug(`Running`,{build:`v26.0.0-beta.2`,env:process.env.NODE_ENV||`development`}),nn(n);let r=en({logger:n,config:e}),i={getLogger:tn(n),errorHandler:t},a=Yt(i),o=Jt(i);return{...i,logger:n,notFoundHandler:a,catcher:o,loggingMiddleware:r}},sn=(e,t)=>{let{logger:n,getLogger:r,notFoundHandler:i,loggingMiddleware:a}=on(e);return Bt({app:e.app.use(a),routing:t,getLogger:r,config:e}),{notFoundHandler:i,logger:n}},cn=async(e,t)=>{let{logger:n,getLogger:r,notFoundHandler:i,catcher:a,loggingMiddleware:o}=on(e),s=g().disable(`x-powered-by`).set(`query parser`,e.queryParser??`simple`).use(o);if(e.compression){let t=await bt(`compression`);s.use(t(typeof e.compression==`object`?e.compression:void 0))}await e.beforeRouting?.({app:s,getLogger:r}),Bt({app:s,routing:t,getLogger:r,config:e,parsers:{json:[e.jsonParser||g.json()],raw:[e.rawParser||g.raw(),$t],form:[e.formParser||g.urlencoded()],upload:e.upload?await Qt({config:e,getLogger:r}):[]}}),await e.afterRouting?.({app:s,getLogger:r}),s.use(a,i);let c=[],l=(e,t)=>()=>e.listen(t,()=>n.info(`Listening`,t)),u=[];if(e.http){let t=te.createServer(s);c.push(t),u.push(l(t,e.http.listen))}if(e.https){let t=ne.createServer(e.https.options,s);c.push(t),u.push(l(t,e.https.listen))}return c.length||n.warn(`No servers configured.`),e.gracefulShutdown&&rn({logger:n,servers:c,options:e.gracefulShutdown===!0?{}:e.gracefulShutdown}),{app:s,logger:n,servers:u.map(e=>e())}},ln=e=>T(e)&&`or`in e,un=e=>T(e)&&`and`in e,dn=e=>!un(e)&&!ln(e),fn=e=>{let n=t.filter(dn,e),r=t.chain(t.prop(`and`),t.filter(un,e)),[i,a]=t.partition(dn,r),o=t.concat(n,i),s=t.filter(ln,e);return t.map(t.prop(`or`),t.concat(s,a)).reduce((e,n)=>be(e,t.map(e=>dn(e)?[e]:e.and,n),([e,n])=>t.concat(e,n)),t.reject(t.isEmpty,[o]))};var pn=`a-im.accept.accept-additions.accept-ch.accept-charset.accept-datetime.accept-encoding.accept-features.accept-language.accept-signature.access-control.access-control-request-headers.access-control-request-method.alpn.alt-used.alternates.amp-cache-transform.apply-to-redirect-ref.authentication-control.authentication-info.authorization.available-dictionary.c-ext.c-man.c-opt.c-pep.c-pep-info.cache-control.cal-managed-id.caldav-timezones.capsule-protocol.cert-not-after.cert-not-before.client-cert.client-cert-chain.close.cmcd-object.cmcd-request.cmcd-session.cmcd-status.cmsd-dynamic.cmsd-static.concealed-auth-export.configuration-context.connection.content-digest.content-disposition.content-encoding.content-id.content-language.content-length.content-location.content-md5.content-range.content-script-type.content-type.cookie.cookie2.cross-origin-embedder-policy.cross-origin-embedder-policy-report-only.cross-origin-opener-policy.cross-origin-opener-policy-report-only.cross-origin-resource-policy.cta-common-access-token.dasl.date.dav.default-style.delta-base.deprecation.depth.derived-from.destination.detached-jws.differential-id.dictionary-id.digest.dpop.dpop-nonce.early-data.ediint-features.expect.expect-ct.ext.forwarded.from.getprofile.hobareg.host.http2-settings.if.if-match.if-modified-since.if-none-match.if-range.if-schedule-tag-match.if-unmodified-since.im.include-referred-token-binding-id.isolation.keep-alive.label.last-event-id.link.link-template.lock-token.man.max-forwards.memento-datetime.meter.method-check.method-check-expires.mime-version.negotiate.nel.odata-entityid.odata-isolation.odata-maxversion.odata-version.opt.ordering-type.origin.origin-agent-cluster.oscore.oslc-core-version.overwrite.p3p.pep.pep-info.permissions-policy.pics-label.ping-from.ping-to.position.pragma.prefer.preference-applied.priority.profileobject.protocol.protocol-info.protocol-query.protocol-request.proxy-authorization.proxy-features.proxy-instruction.public.public-key-pins.public-key-pins-report-only.range.redirect-ref.referer.referer-root.referrer-policy.repeatability-client-id.repeatability-first-sent.repeatability-request-id.repeatability-result.replay-nonce.reporting-endpoints.repr-digest.safe.schedule-reply.schedule-tag.sec-fetch-storage-access.sec-gpc.sec-purpose.sec-token-binding.sec-websocket-extensions.sec-websocket-key.sec-websocket-protocol.sec-websocket-version.security-scheme.setprofile.signature.signature-input.slug.soapaction.status-uri.sunset.surrogate-capability.tcn.te.timeout.topic.traceparent.tracestate.trailer.transfer-encoding.ttl.upgrade.urgency.uri.use-as-dictionary.user-agent.variant-vary.via.want-content-digest.want-digest.want-repr-digest.warning.x-content-type-options.x-frame-options`.split(`.`);const mn=`https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString`,hn={integer:0,number:0,string:``,boolean:!1,object:{},null:null,array:[]},gn=e=>e.replace(fe,e=>`{${e.slice(1)}}`),_n=({},e)=>{if(e.isResponse)throw new A(`Please use ez.upload() only for input.`,e);return{type:`string`,format:`binary`}},vn=({jsonSchema:e})=>({...e,externalDocs:{description:`raw binary data`,url:`https://swagger.io/specification/#working-with-binary-data`}}),yn=({zodSchema:e,jsonSchema:t})=>{if(!C(e,`union`)||!(`discriminator`in e._zod.def))return t;let n=e._zod.def.discriminator;return{...t,discriminator:t.discriminator??{propertyName:n}}},bn=t.tryCatch(({jsonSchema:e})=>{if(!e.allOf)throw`no allOf`;return Tt(e,`throw`)},(e,{jsonSchema:t})=>t),xn=({jsonSchema:e})=>{if(!e.anyOf)return e;let t=e.anyOf[0];return Object.assign(t,{type:Dn(t.type)})},L=e=>e,Sn=({jsonSchema:{examples:e,description:t}},n)=>{if(n.isResponse)throw new A(`Please use ez.dateOut() for output.`,n);let r={description:t||`YYYY-MM-DDTHH:mm:ss.sssZ`,type:`string`,format:`date-time`,pattern:`^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?)?Z?$`,externalDocs:{url:mn}};return e?.length&&(r.examples=e),r},Cn=({jsonSchema:{examples:e,description:t}},n)=>{if(!n.isResponse)throw new A(`Please use ez.dateIn() for input.`,n);let r={description:t||`YYYY-MM-DDTHH:mm:ss.sssZ`,type:`string`,format:`date-time`,externalDocs:{url:mn}};return e?.length&&(r.examples=e),r},wn=()=>({type:`string`,format:`bigint`,pattern:`^-?\\d+$`}),Tn=({zodSchema:e,jsonSchema:t})=>e._zod.def.rest===null?{...t,items:{not:{}}}:t,En=e=>{let t=Array.isArray(e.type)?e.type[0]:e.type;return hn?.[t]},Dn=e=>e===`null`?e:typeof e==`string`?[e,`null`]:e&&[...new Set(e).add(`null`)],On=({zodSchema:e,jsonSchema:t},n)=>{let r=e._zod.def[n.isResponse?`out`:`in`],i=e._zod.def[n.isResponse?`in`:`out`];if(!C(r,`transform`))return t;let a=L(Fn(i,{ctx:n}));if(_(a))if(n.isResponse){let e=Se(r,En(a));if(e&&[`number`,`string`,`boolean`].includes(e))return{...t,type:e}}else{let{type:e,...t}=a;return{...t,format:`${t.format||e} (preprocessed)`}}return t},kn=({jsonSchema:e})=>{if(e.type!==`object`)return e;let t=e;return!t.properties||!(`raw`in t.properties)||!T(t.properties.raw)?e:t.properties.raw},An=e=>e.length?t.fromPairs(t.zip(t.times(e=>`example${e+1}`,e.length),t.map(t.objOf(`value`),e))):void 0,jn=(e,t)=>t?.includes(e)||e.startsWith(`x-`)||pn.includes(e),Mn=({path:e,method:n,request:r,inputSources:i,makeRef:a,composition:o,isHeader:s,security:c,description:l=`${n.toUpperCase()} ${e} Parameter`})=>{let u=Tt(r),d=pe(e),f=i.includes(`query`),p=i.includes(`params`),m=i.includes(`headers`),ee=e=>p&&d.includes(e),h=t.chain(t.filter(e=>e.type===`header`),c??[]).map(({name:e})=>e),g=t=>m&&(s?.(t,n,e)??jn(t,h));return Object.entries(u.properties).reduce((e,[n,r])=>{if(!T(r))return e;let i=ee(n)?`path`:g(n)?`header`:f?`query`:void 0;if(!i)return e;let s=L(r),c=o===`components`?a(r.id||JSON.stringify(r),s,w(l,n)):s;return e.concat({name:n,in:i,deprecated:r.deprecated,required:u.required?.includes(n)||!1,description:s.description||l,schema:c,examples:An(_(s)&&s.examples?.length?s.examples:t.pluck(n,u.examples?.filter(t.both(T,t.has(n)))||[]))})},[])},Nn={nullable:xn,union:yn,bigint:wn,intersection:bn,tuple:Tn,pipe:On,[D]:Sn,[O]:Cn,[M]:_n,[N]:kn,[E]:vn},Pn=(e,n,r)=>{let i=[e,n];for(;i.length;){let e=i.shift();if(t.is(Object,e)){if(ae(e)&&!e.$ref.startsWith(`#/components`)){let t=n[e.$ref.split(`/`).pop()];t&&(e.$ref=r.makeRef(t.id||t,L(t)).$ref);continue}i.push(...t.values(e))}t.is(Array,e)&&i.push(...t.values(e))}return e},Fn=(t,{ctx:n,rules:i=Nn})=>{let{$defs:a={},properties:o={}}=r.toJSONSchema(r.object({subject:t}),{unrepresentable:`any`,io:n.isResponse?`output`:`input`,override:t=>{let r=e(t.zodSchema),a=i[r&&r in i?r:t.zodSchema._zod.def.type];if(a){let e={...a(t,n)};for(let e in t.jsonSchema)delete t.jsonSchema[e];Object.assign(t.jsonSchema,e)}}});return Pn(T(o.subject)?o.subject:{},a,n)},In=(e,n)=>{if(ae(e))return[e,!1];let r=!1,i=t.map(e=>{let[t,i]=In(e,n);return r||=i,t}),a=t.omit(n),o={properties:a,examples:t.map(a),required:t.without(n),allOf:i,oneOf:i,anyOf:i},s=t.evolve(o,e);return[s,r||!!s.required?.length]},Ln=({method:e,path:n,schema:r,mimeTypes:i,variant:a,makeRef:o,composition:s,hasMultipleStatusCodes:c,statusCode:l,brandHandling:u,description:d=`${e.toUpperCase()} ${n} ${xe(a)} response ${c?l:``}`.trim()})=>{if(!we(e,i))return{description:d};let f=L(Fn(r,{rules:{...u,...Nn},ctx:{isResponse:!0,makeRef:o,path:n,method:e}})),p=[];_(f)&&f.examples&&(p.push(...f.examples),delete f.examples);let m={schema:s===`components`?o(r,f,w(d)):f,examples:An(p)};return{description:d,content:t.fromPairs(t.xprod(i,[m]))}},Rn=({format:e})=>{let t={type:`http`,scheme:`bearer`};return e&&(t.bearerFormat=e),t},zn=({name:e},t)=>{let n={type:`apiKey`,in:`query`,name:e};return t?.includes(`body`)&&(t?.includes(`query`)?(n[`x-in-alternative`]=`body`,n.description=`${e} CAN also be supplied within the request body`):(n[`x-in-actual`]=`body`,n.description=`${e} MUST be supplied within the request body instead of query`)),n},Bn=({name:e})=>({type:`apiKey`,in:`header`,name:e}),Vn=({name:e})=>({type:`apiKey`,in:`cookie`,name:e}),Hn=({url:e})=>({type:`openIdConnect`,openIdConnectUrl:e}),Un=({flows:e={}})=>({type:`oauth2`,flows:t.map(e=>({...e,scopes:e.scopes||{}}),t.reject(t.isNil,e))}),Wn=(e,t=[])=>{let n=e=>e.type===`basic`?{type:`http`,scheme:`basic`}:e.type===`bearer`?Rn(e):e.type===`input`?zn(e,t):e.type===`header`?Bn(e):e.type===`cookie`?Vn(e):e.type===`openid`?Hn(e):Un(e);return e.map(e=>e.map(n))},Gn=(e,t,n)=>e.map(e=>e.reduce((e,r)=>{let i=n(r),a=[`oauth2`,`openIdConnect`].includes(r.type);return Object.assign(e,{[i]:a?t:[]})},{})),Kn=({schema:e,brandHandling:t,makeRef:n,path:r,method:i})=>Fn(e,{rules:{...t,...Nn},ctx:{isResponse:!1,makeRef:n,path:r,method:i}}),qn=({method:e,path:n,schema:r,request:i,mimeType:a,makeRef:o,composition:s,paramNames:c,description:l=`${e.toUpperCase()} ${n} Request body`})=>{let[u,d]=In(L(i),c),f=[];_(u)&&u.examples&&(f.push(...u.examples),delete u.examples);let p={schema:s===`components`?o(r,u,w(l)):u,examples:An(f.length?f:Tt(i).examples?.filter(e=>T(e)&&!Array.isArray(e)).map(t.omit(c))||[])},m={description:l,content:{[a]:p}};return(d||a===y.raw)&&(m.required=!0),m},Jn=e=>Object.entries(e).reduce((e,[t,n])=>{if(!n)return e;let r={name:t,description:typeof n==`string`?n:n.description};return typeof n==`object`&&n.url&&(r.externalDocs={url:n.url}),e.concat(r)},[]),Yn=e=>e.length<=50?e:e.slice(0,49)+`…`,Xn=e=>e.length?e.slice():void 0;var Zn=class extends ie{#e=new Map;#t=new Map;#n=new Map;#r(e,t,n=this.#n.get(e)){return n||(n=`Schema${this.#n.size+1}`,this.#n.set(e,n)),this.addSchema(n,t),{$ref:`#/components/schemas/${n}`}}#i(e,t,n){let r=n||w(t,e),i=this.#t.get(r);if(i===void 0)return this.#t.set(r,1),r;if(n)throw new A(`Duplicated operationId: "${n}"`,{method:t,isResponse:!1,path:e});return i++,this.#t.set(r,i),`${r}${i}`}#a(e){let t=JSON.stringify(e);for(let e in this.rootDoc.components?.securitySchemes||{})if(t===JSON.stringify(this.rootDoc.components?.securitySchemes?.[e]))return e;let n=(this.#e.get(e.type)||0)+1;return this.#e.set(e.type,n),`${e.type.toUpperCase()}_${n}`}constructor({routing:e,config:n,title:r,version:i,serverUrl:a,descriptions:o,brandHandling:s,tags:c,isHeader:l,hasSummaryFromDescription:u=!0,hasHeadMethod:d=!0,composition:f=`inline`}){super(),this.addInfo({title:r,version:i});for(let e of typeof a==`string`?[a]:a)this.addServer({url:e});let p=(e,r,i)=>{let a={path:r,method:e,endpoint:i,composition:f,brandHandling:s,makeRef:this.#r.bind(this)},{description:c,shortDescription:d,scopes:p,inputSchema:m}=i,ee=d?Yn(d):u&&c?Yn(c):void 0,h=ve(e,n.inputSources),g=this.#i(r,e,i.getOperationId(e)),te=Kn({...a,schema:m}),ne=fn(i.security),re=Mn({...a,inputSources:h,isHeader:l,security:ne,request:te,description:o?.requestParameter?.call(null,{method:e,path:r,operationId:g})}),ie={};for(let t of nt){let n=i.getResponses(t);for(let{mimeTypes:i,schema:s,statusCodes:c}of n)for(let l of c)ie[l]=Ln({...a,variant:t,schema:s,mimeTypes:i,statusCode:l,hasMultipleStatusCodes:n.length>1||c.length>1,description:o?.[`${t}Response`]?.call(null,{method:e,path:r,operationId:g,statusCode:l})})}let ae=h.includes(`body`)?qn({...a,request:te,paramNames:t.pluck(`name`,re),schema:m,mimeType:y[i.requestType],description:o?.requestBody?.call(null,{method:e,path:r,operationId:g})}):void 0,_=Gn(Wn(ne,h),p,e=>{let t=this.#a(e);return this.addSecurityScheme(t,e),t}),oe={operationId:g,summary:ee,description:c,deprecated:i.isDeprecated||void 0,tags:Xn(i.tags),parameters:Xn(re),requestBody:ae,security:Xn(_),responses:ie};this.addPath(gn(r),{[e]:oe})};Ft({routing:e,config:n,onEndpoint:d?Ot(p):p}),c&&(this.rootDoc.tags=Jn(c))}};const Qn=e=>oe({...e,headers:{"content-type":y.json,...e?.headers}}),$n=e=>se(e),er=e=>{let t={warn:[],error:[],info:[],debug:[]};return new Proxy(e||{},{get(e,n,r){return n===`_getLogs`?()=>t:ht(n)?(...e)=>t[n].push(e):Reflect.get(e,n,r)}})},tr=({requestProps:e,responseOptions:t,configProps:n,loggerProps:r})=>{let i=Qn(e),a=$n({req:i,...t});a.req=t?.req||i,i.res=a;let o=er(r);return{requestMock:i,responseMock:a,loggerMock:o,configMock:{cors:!1,logger:o,...n}}},nr=async({endpoint:e,...t})=>{let{requestMock:n,responseMock:r,loggerMock:i,configMock:a}=tr(t);return await e.execute({request:n,response:r,config:a,logger:i}),{requestMock:n,responseMock:r,loggerMock:i}},rr=async({middleware:e,ctx:t={},...n})=>{let{requestMock:r,responseMock:i,loggerMock:a,configMock:{inputSources:o,errorHandler:s=ot}}=tr(n),c={request:r,response:i,logger:a,input:ye(r,o),ctx:t};try{return{requestMock:r,responseMock:i,loggerMock:a,output:await e.execute(c)}}catch(e){return await s.execute({...c,error:x(e),output:null}),{requestMock:r,responseMock:i,loggerMock:a,output:{}}}},R=v.factory,ir=[R.createModifier(v.SyntaxKind.ExportKeyword)],ar=[R.createModifier(v.SyntaxKind.AsyncKeyword)],or={public:[R.createModifier(v.SyntaxKind.PublicKeyword)],protectedReadonly:[R.createModifier(v.SyntaxKind.ProtectedKeyword),R.createModifier(v.SyntaxKind.ReadonlyKeyword)]},sr=(e,t)=>v.addSyntheticLeadingComment(e,v.SyntaxKind.MultiLineCommentTrivia,`* ${t} `,!0),cr=(e,t)=>{let n=v.createSourceFile(`print.ts`,``,v.ScriptTarget.Latest,!1,v.ScriptKind.TS);return v.createPrinter(t).printNode(v.EmitHint.Unspecified,e,n)},lr=/^[A-Za-z_$][A-Za-z0-9_$]*$/,ur=e=>typeof e==`string`&&lr.test(e)?R.createIdentifier(e):Y(e),dr=(e,...t)=>R.createTemplateExpression(R.createTemplateHead(e),t.map(([e,n=``],r)=>R.createTemplateSpan(e,r===t.length-1?R.createTemplateTail(n):R.createTemplateMiddle(n)))),fr=(e,{type:t,mod:n,init:r,optional:i}={})=>R.createParameterDeclaration(n,void 0,e,i?R.createToken(v.SyntaxKind.QuestionToken):void 0,t?B(t):void 0,r),z=e=>Object.entries(e).map(([e,t])=>fr(e,typeof t==`string`||typeof t==`number`||typeof t==`object`&&`kind`in t?{type:t}:t)),pr=(e,t=[])=>R.createConstructorDeclaration(or.public,e,R.createBlock(t)),B=(e,n)=>typeof e==`number`?R.createKeywordTypeNode(e):typeof e==`string`||v.isIdentifier(e)?R.createTypeReferenceNode(e,n&&t.map(B,n)):e,mr=B(`Record`,[v.SyntaxKind.StringKeyword,v.SyntaxKind.AnyKeyword]),V=e=>{let t=new Map;for(let n of e)t.set(Mr(n)?n.kind:n,n);return R.createUnionTypeNode(Array.from(t.values()))},hr=(e,n,{isOptional:r,isDeprecated:i,comment:a}={})=>{let o=B(n),s=R.createPropertySignature(void 0,ur(e),r?R.createToken(v.SyntaxKind.QuestionToken):void 0,r?V([o,B(v.SyntaxKind.UndefinedKeyword)]):o),c=t.reject(t.isNil,[i?`@deprecated`:void 0,a]);return c.length?sr(s,c.join(` `)):s},gr=e=>v.setEmitFlags(e,v.EmitFlags.SingleLine),_r=(...e)=>R.createArrayBindingPattern(e.map(e=>R.createBindingElement(void 0,void 0,e))),H=(e,t,{type:n,expose:r}={})=>R.createVariableStatement(r&&ir,R.createVariableDeclarationList([R.createVariableDeclaration(e,void 0,n?B(n):void 0,t)],v.NodeFlags.Const)),vr=(e,n)=>U(e,V(t.map(X,n)),{expose:!0}),U=(e,t,{expose:n,comment:r,params:i}={})=>{let a=R.createTypeAliasDeclaration(n?ir:void 0,e,i&&Tr(i),t);return r?sr(a,r):a},yr=(e,t)=>R.createPropertyDeclaration(or.public,e,void 0,B(t),void 0),br=(e,t,n,{typeParams:r,returns:i}={})=>R.createMethodDeclaration(or.public,void 0,e,void 0,r&&Tr(r),t,i,R.createBlock(n)),xr=(e,t,{typeParams:n}={})=>R.createClassDeclaration(ir,e,n&&Tr(n),void 0,t),Sr=e=>R.createTypeOperatorNode(v.SyntaxKind.KeyOfKeyword,B(e)),Cr=e=>B(Promise.name,[e]),wr=(e,t,{expose:n,comment:r}={})=>{let i=R.createInterfaceDeclaration(n?ir:void 0,e,void 0,void 0,t);return r?sr(i,r):i},Tr=e=>(Array.isArray(e)?e.map(e=>t.pair(e,void 0)):Object.entries(e)).map(([e,t])=>{let{type:n,init:r}=typeof t==`object`&&`init`in t?t:{type:t};return R.createTypeParameterDeclaration([],e,n?B(n):void 0,r?B(r):void 0)}),W=(e,n,{isAsync:r}={})=>R.createArrowFunction(r?ar:void 0,void 0,Array.isArray(e)?t.map(fr,e):z(e),void 0,void 0,n),G=e=>e,Er=(e,t,n)=>R.createConditionalExpression(e,R.createToken(v.SyntaxKind.QuestionToken),t,R.createToken(v.SyntaxKind.ColonToken),n),K=(e,...t)=>(...n)=>R.createCallExpression(t.reduce((e,t)=>typeof t==`string`||v.isIdentifier(t)?R.createPropertyAccessExpression(e,t):R.createElementAccessExpression(e,t),typeof e==`string`?R.createIdentifier(e):e),void 0,n),q=(e,...t)=>R.createNewExpression(R.createIdentifier(e),void 0,t),Dr=(e,t)=>B(`Extract`,[e,t]),Or=(e,t)=>R.createExpressionStatement(R.createBinaryExpression(e,R.createToken(v.SyntaxKind.EqualsToken),t)),J=(e,t)=>R.createIndexedAccessTypeNode(B(e),B(t)),kr=e=>V([B(e),Cr(e)]),Ar=(e,t)=>R.createFunctionTypeNode(void 0,z(e),B(t)),Y=e=>typeof e==`number`?R.createNumericLiteral(e):typeof e==`bigint`?R.createBigIntLiteral(e.toString()):typeof e==`boolean`?e?R.createTrue():R.createFalse():e===null?R.createNull():R.createStringLiteral(e),X=e=>R.createLiteralTypeNode(Y(e)),jr=[v.SyntaxKind.AnyKeyword,v.SyntaxKind.BigIntKeyword,v.SyntaxKind.BooleanKeyword,v.SyntaxKind.NeverKeyword,v.SyntaxKind.NumberKeyword,v.SyntaxKind.ObjectKeyword,v.SyntaxKind.StringKeyword,v.SyntaxKind.SymbolKeyword,v.SyntaxKind.UndefinedKeyword,v.SyntaxKind.UnknownKeyword,v.SyntaxKind.VoidKeyword],Mr=e=>jr.includes(e.kind);var Nr=class{paths=new Set;tags=new Map;registry=new Map;#e={pathType:R.createIdentifier(`Path`),implementationType:R.createIdentifier(`Implementation`),keyParameter:R.createIdentifier(`key`),pathParameter:R.createIdentifier(`path`),paramsArgument:R.createIdentifier(`params`),ctxArgument:R.createIdentifier(`ctx`),methodParameter:R.createIdentifier(`method`),requestParameter:R.createIdentifier(`request`),eventParameter:R.createIdentifier(`event`),dataParameter:R.createIdentifier(`data`),handlerParameter:R.createIdentifier(`handler`),msgParameter:R.createIdentifier(`msg`),parseRequestFn:R.createIdentifier(`parseRequest`),substituteFn:R.createIdentifier(`substitute`),provideMethod:R.createIdentifier(`provide`),onMethod:R.createIdentifier(`on`),implementationArgument:R.createIdentifier(`implementation`),hasBodyConst:R.createIdentifier(`hasBody`),undefinedValue:R.createIdentifier(`undefined`),responseConst:R.createIdentifier(`response`),restConst:R.createIdentifier(`rest`),searchParamsConst:R.createIdentifier(`searchParams`),defaultImplementationConst:R.createIdentifier(`defaultImplementation`),clientConst:R.createIdentifier(`client`),contentTypeConst:R.createIdentifier(`contentType`),isJsonConst:R.createIdentifier(`isJSON`),sourceProp:R.createIdentifier(`source`)};interfaces={input:R.createIdentifier(`Input`),positive:R.createIdentifier(`PositiveResponse`),negative:R.createIdentifier(`NegativeResponse`),encoded:R.createIdentifier(`EncodedResponse`),response:R.createIdentifier(`Response`)};methodType=vr(`Method`,ue);someOfType=U(`SomeOf`,J(`T`,Sr(`T`)),{params:[`T`]});requestType=U(`Request`,Sr(this.interfaces.input),{expose:!0});constructor(e){this.serverUrl=e}someOf=({name:e})=>B(this.someOfType.name,[e]);makePathType=()=>vr(this.#e.pathType,Array.from(this.paths));makePublicInterfaces=()=>Object.keys(this.interfaces).map(e=>wr(this.interfaces[e],Array.from(this.registry).map(([t,{store:n,isDeprecated:r}])=>hr(t,n[e],{isDeprecated:r})),{expose:!0}));makeEndpointTags=()=>H(`endpointTags`,R.createObjectLiteralExpression(Array.from(this.tags).map(([e,n])=>R.createPropertyAssignment(ur(e),R.createArrayLiteralExpression(t.map(Y,n))))),{expose:!0});makeImplementationType=()=>U(this.#e.implementationType,Ar({[this.#e.methodParameter.text]:this.methodType.name,[this.#e.pathParameter.text]:v.SyntaxKind.StringKeyword,[this.#e.paramsArgument.text]:mr,[this.#e.ctxArgument.text]:{optional:!0,type:`T`}},Cr(v.SyntaxKind.AnyKeyword)),{expose:!0,params:{T:{init:v.SyntaxKind.UnknownKeyword}}});makeParseRequestFn=()=>H(this.#e.parseRequestFn,W({[this.#e.requestParameter.text]:v.SyntaxKind.StringKeyword},R.createAsExpression(K(this.#e.requestParameter,G(`split`))(R.createRegularExpressionLiteral(`/ (.+)/`),Y(2)),R.createTupleTypeNode([B(this.methodType.name),B(this.#e.pathType)]))));makeSubstituteFn=()=>H(this.#e.substituteFn,W({[this.#e.pathParameter.text]:v.SyntaxKind.StringKeyword,[this.#e.paramsArgument.text]:mr},R.createBlock([H(this.#e.restConst,R.createObjectLiteralExpression([R.createSpreadAssignment(this.#e.paramsArgument)])),R.createForInStatement(R.createVariableDeclarationList([R.createVariableDeclaration(this.#e.keyParameter)],v.NodeFlags.Const),this.#e.paramsArgument,R.createBlock([Or(this.#e.pathParameter,K(this.#e.pathParameter,G(`replace`))(dr(`:`,[this.#e.keyParameter]),W([],R.createBlock([R.createExpressionStatement(R.createDeleteExpression(R.createElementAccessExpression(this.#e.restConst,this.#e.keyParameter))),R.createReturnStatement(R.createElementAccessExpression(this.#e.paramsArgument,this.#e.keyParameter))]))))])),R.createReturnStatement(R.createAsExpression(R.createArrayLiteralExpression([this.#e.pathParameter,this.#e.restConst]),B(`const`)))])));#t=()=>br(this.#e.provideMethod,z({[this.#e.requestParameter.text]:`K`,[this.#e.paramsArgument.text]:J(this.interfaces.input,`K`),[this.#e.ctxArgument.text]:{optional:!0,type:`T`}}),[H(_r(this.#e.methodParameter,this.#e.pathParameter),K(this.#e.parseRequestFn)(this.#e.requestParameter)),R.createReturnStatement(K(R.createThis(),this.#e.implementationArgument)(this.#e.methodParameter,R.createSpreadElement(K(this.#e.substituteFn)(this.#e.pathParameter,this.#e.paramsArgument)),this.#e.ctxArgument))],{typeParams:{K:this.requestType.name},returns:Cr(J(this.interfaces.response,`K`))});makeClientClass=e=>xr(e,[pr([fr(this.#e.implementationArgument,{type:B(this.#e.implementationType,[`T`]),mod:or.protectedReadonly,init:this.#e.defaultImplementationConst})]),this.#t()],{typeParams:[`T`]});#n=e=>dr(`?`,[q(URLSearchParams.name,e)]);#r=()=>q(URL.name,dr(``,[this.#e.pathParameter],[this.#e.searchParamsConst]),Y(this.serverUrl));makeDefaultImplementation=()=>{let e=R.createPropertyAssignment(G(`method`),K(this.#e.methodParameter,G(`toUpperCase`))()),t=R.createPropertyAssignment(G(`headers`),Er(this.#e.hasBodyConst,R.createObjectLiteralExpression([R.createPropertyAssignment(Y(`Content-Type`),Y(y.json))]),this.#e.undefinedValue)),n=R.createPropertyAssignment(G(`body`),Er(this.#e.hasBodyConst,K(JSON[Symbol.toStringTag],G(`stringify`))(this.#e.paramsArgument),this.#e.undefinedValue)),r=H(this.#e.responseConst,R.createAwaitExpression(K(fetch.name)(this.#r(),R.createObjectLiteralExpression([e,t,n])))),i=H(this.#e.hasBodyConst,R.createLogicalNot(K(R.createArrayLiteralExpression([Y(`get`),Y(`head`),Y(`delete`)]),G(`includes`))(this.#e.methodParameter))),a=H(this.#e.searchParamsConst,Er(this.#e.hasBodyConst,Y(``),this.#n(this.#e.paramsArgument))),o=H(this.#e.contentTypeConst,K(this.#e.responseConst,G(`headers`),G(`get`))(Y(`content-type`))),s=R.createIfStatement(R.createPrefixUnaryExpression(v.SyntaxKind.ExclamationToken,this.#e.contentTypeConst),R.createReturnStatement()),c=H(this.#e.isJsonConst,K(this.#e.contentTypeConst,G(`startsWith`))(Y(y.json))),l=R.createReturnStatement(K(this.#e.responseConst,Er(this.#e.isJsonConst,Y(G(`json`)),Y(G(`text`))))());return H(this.#e.defaultImplementationConst,W([this.#e.methodParameter,this.#e.pathParameter,this.#e.paramsArgument],R.createBlock([i,a,r,o,s,c,l]),{isAsync:!0}),{type:this.#e.implementationType})};#i=()=>pr(z({request:`K`,params:J(this.interfaces.input,`K`)}),[H(_r(this.#e.pathParameter,this.#e.restConst),K(this.#e.substituteFn)(R.createElementAccessExpression(K(this.#e.parseRequestFn)(this.#e.requestParameter),Y(1)),this.#e.paramsArgument)),H(this.#e.searchParamsConst,this.#n(this.#e.restConst)),Or(R.createPropertyAccessExpression(R.createThis(),this.#e.sourceProp),q(`EventSource`,this.#r()))]);#a=e=>R.createTypeLiteralNode([hr(G(`event`),e)]);#o=()=>br(this.#e.onMethod,z({[this.#e.eventParameter.text]:`E`,[this.#e.handlerParameter.text]:Ar({[this.#e.dataParameter.text]:J(Dr(`R`,gr(this.#a(`E`))),X(G(`data`)))},kr(v.SyntaxKind.VoidKeyword))}),[R.createExpressionStatement(K(R.createThis(),this.#e.sourceProp,G(`addEventListener`))(this.#e.eventParameter,W([this.#e.msgParameter],K(this.#e.handlerParameter)(K(JSON[Symbol.toStringTag],G(`parse`))(R.createPropertyAccessExpression(R.createParenthesizedExpression(R.createAsExpression(this.#e.msgParameter,B(MessageEvent.name))),G(`data`))))))),R.createReturnStatement(R.createThis())],{typeParams:{E:J(`R`,X(G(`event`)))}});makeSubscriptionClass=e=>xr(e,[yr(this.#e.sourceProp,`EventSource`),this.#i(),this.#o()],{typeParams:{K:Dr(this.requestType.name,R.createTemplateLiteralType(R.createTemplateHead(`get `),[R.createTemplateLiteralTypeSpan(B(v.SyntaxKind.StringKeyword),R.createTemplateTail(``))])),R:Dr(J(this.interfaces.positive,`K`),gr(this.#a(v.SyntaxKind.StringKeyword)))}});makeUsageStatements=(e,t)=>[H(this.#e.clientConst,q(e)),K(this.#e.clientConst,this.#e.provideMethod)(Y(`get /v1/user/retrieve`),R.createObjectLiteralExpression([R.createPropertyAssignment(`id`,Y(`10`))])),K(q(t,Y(`get /v1/events/stream`),R.createObjectLiteralExpression()),this.#e.onMethod)(Y(`time`),W([`time`],R.createBlock([])))]};const Pr=(t,{onEach:n,rules:r,onMissing:i,ctx:a={}})=>{let o=e(t),s=o&&o in r?r[o]:r[t._zod.def.type],c=e=>Pr(e,{ctx:a,onEach:n,rules:r,onMissing:i}),l=s?s(t,{...a,next:c}):i(t,a),u=n&&n(t,{prev:l,...a});return u?{...l,...u}:l},{factory:Z}=v,Fr={[v.SyntaxKind.AnyKeyword]:``,[v.SyntaxKind.BigIntKeyword]:BigInt(0),[v.SyntaxKind.BooleanKeyword]:!1,[v.SyntaxKind.NumberKeyword]:0,[v.SyntaxKind.ObjectKeyword]:{},[v.SyntaxKind.StringKeyword]:``,[v.SyntaxKind.UndefinedKeyword]:void 0},Ir={name:t.path([`name`,`text`]),type:t.path([`type`]),optional:t.path([`questionToken`])},Lr=({_zod:{def:e}})=>{let t=e.values.map(e=>e===void 0?B(v.SyntaxKind.UndefinedKeyword):X(e));return t.length===1?t[0]:V(t)},Rr=({_zod:{def:e}},{next:t})=>{let n=[...e.parts],r=()=>{let e=``;for(;n.length;){let t=n.shift();if(C(t)){n.unshift(t);break}e+=t??``}return e},i=Z.createTemplateHead(r()),a=[];for(;n.length;){let e=t(n.shift()),i=r(),o=n.length?Z.createTemplateMiddle:Z.createTemplateTail;a.push(Z.createTemplateLiteralTypeSpan(e,o(i)))}return a.length?Z.createTemplateLiteralType(i,a):X(i.text)},zr=(e,{isResponse:t,next:r,makeAlias:i})=>{let a=()=>{let i=Object.entries(e._zod.def.shape).map(([e,i])=>{let{description:a,deprecated:o}=n.get(i)||{};return hr(e,r(i),{comment:a,isDeprecated:o,isOptional:(t?i._zod.optout:i._zod.optin)===`optional`})});return Z.createTypeLiteralNode(i)};return Be(e,{io:t?`output`:`input`})?i(e,a):a()},Br=({_zod:{def:e}},{next:t})=>Z.createArrayTypeNode(t(e.element)),Vr=({_zod:{def:e}})=>V(Object.values(e.entries).map(X)),Hr=({_zod:{def:e}},{next:t})=>V(e.options.map(t)),Ur=e=>Fr?.[e.kind],Wr=({_zod:{def:e}},{next:t})=>V([t(e.innerType),X(null)]),Gr=({_zod:{def:e}},{next:t})=>Z.createTupleTypeNode(e.items.map(t).concat(e.rest===null?[]:Z.createRestTypeNode(t(e.rest)))),Kr=({_zod:{def:e}},{next:t})=>B(`Record`,[e.keyType,e.valueType].map(t)),qr=t.tryCatch(e=>{if(!e.every(v.isTypeLiteralNode))throw Error(`Not objects`);let n=t.chain(t.prop(`members`),e),r=t.uniqWith((...e)=>{if(!t.eqBy(Ir.name,...e))return!1;if(t.both(t.eqBy(Ir.type),t.eqBy(Ir.optional))(...e))return!0;throw Error(`Has conflicting prop`)},n);return Z.createTypeLiteralNode(r)},(e,t)=>Z.createIntersectionTypeNode(t)),Jr=({_zod:{def:e}},{next:t})=>qr([e.left,e.right].map(t)),Q=e=>()=>B(e),$=({_zod:{def:e}},{next:t})=>t(e.innerType),Yr=e=>B(e?v.SyntaxKind.UnknownKeyword:v.SyntaxKind.AnyKeyword),Xr=({_zod:{def:e}},{next:t,isResponse:n})=>{let r=e[n?`out`:`in`],i=e[n?`in`:`out`];if(!C(r,`transform`))return t(r);let a=Se(r,Ur(t(i))),o={number:v.SyntaxKind.NumberKeyword,bigint:v.SyntaxKind.BigIntKeyword,boolean:v.SyntaxKind.BooleanKeyword,string:v.SyntaxKind.StringKeyword,undefined:v.SyntaxKind.UndefinedKeyword,object:v.SyntaxKind.ObjectKeyword};return B(a&&o[a]||Yr(n))},Zr=()=>X(null),Qr=({_zod:{def:e}},{makeAlias:t,next:n})=>t(e.getter,()=>n(e.getter())),$r=()=>B(`Buffer`),ei=(e,{next:t})=>t(e._zod.def.shape.raw),ti={string:Q(v.SyntaxKind.StringKeyword),number:Q(v.SyntaxKind.NumberKeyword),bigint:Q(v.SyntaxKind.BigIntKeyword),boolean:Q(v.SyntaxKind.BooleanKeyword),any:Q(v.SyntaxKind.AnyKeyword),undefined:Q(v.SyntaxKind.UndefinedKeyword),[D]:Q(v.SyntaxKind.StringKeyword),[O]:Q(v.SyntaxKind.StringKeyword),never:Q(v.SyntaxKind.NeverKeyword),void:Q(v.SyntaxKind.UndefinedKeyword),unknown:Q(v.SyntaxKind.UnknownKeyword),null:Zr,array:Br,tuple:Gr,record:Kr,object:zr,literal:Lr,template_literal:Rr,intersection:Jr,union:Hr,default:$,enum:Vr,optional:$,nonoptional:$,nullable:Wr,catch:$,pipe:Xr,lazy:Qr,readonly:$,[E]:$r,[N]:ei},ni=(e,{brandHandling:t,ctx:n})=>Pr(e,{rules:{...t,...ti},onMissing:({},{isResponse:e})=>Yr(e),ctx:n});var ri=class extends Nr{#e=[this.someOfType];#t=new Map;#n=[];#r(e,t){let n=this.#t.get(e)?.name?.text;if(!n){n=`Type${this.#t.size+1}`;let r=X(null);this.#t.set(e,U(n,r)),this.#t.set(e,U(n,t()))}return B(n)}constructor({routing:e,config:n,brandHandling:i,variant:a=`client`,clientClassName:o=`Client`,subscriptionClassName:s=`Subscription`,serverUrl:c=`https://example.com`,noContent:l=r.undefined(),hasHeadMethod:u=!0}){super(c);let d={makeAlias:this.#r.bind(this)},f={brandHandling:i,ctx:{...d,isResponse:!1}},p={brandHandling:i,ctx:{...d,isResponse:!0}},m=(e,n,r)=>{let i=w.bind(null,e,n),{isDeprecated:a,inputSchema:o,tags:s}=r,c=`${e} ${n}`,u=U(i(`input`),ni(o,f),{comment:c});this.#e.push(u);let d=nt.reduce((n,a)=>{let o=r.getResponses(a),s=t.chain(([t,{schema:n,mimeTypes:r,statusCodes:o}])=>{let s=we(e,r),u=U(i(a,`variant`,`${t+1}`),ni(s?n:l,p),{comment:c});return this.#e.push(u),o.map(e=>hr(e,u.name))},Array.from(o.entries())),u=wr(i(a,`response`,`variants`),s,{comment:c});return this.#e.push(u),Object.assign(n,{[a]:u})},{});this.paths.add(n);let m=X(c),ee={input:B(u.name),positive:this.someOf(d.positive),negative:this.someOf(d.negative),response:V([J(this.interfaces.positive,m),J(this.interfaces.negative,m)]),encoded:R.createIntersectionTypeNode([B(d.positive.name),B(d.negative.name)])};this.registry.set(c,{isDeprecated:a,store:ee}),this.tags.set(c,s)};Ft({routing:e,config:n,onEndpoint:u?Ot(m):m}),this.#e.unshift(...this.#t.values()),this.#e.push(this.makePathType(),this.methodType,...this.makePublicInterfaces(),this.requestType),a!==`types`&&(this.#e.push(this.makeEndpointTags(),this.makeParseRequestFn(),this.makeSubstituteFn(),this.makeImplementationType(),this.makeDefaultImplementation(),this.makeClientClass(o),this.makeSubscriptionClass(s)),this.#n.push(...this.makeUsageStatements(o,s)))}#i(e){return this.#n.length?this.#n.map(t=>typeof t==`string`?t:cr(t,e)).join(`
18
+ `):void 0}print(e){let t=this.#i(e),n=t&&v.addSyntheticLeadingComment(v.addSyntheticLeadingComment(R.createEmptyStatement(),v.SyntaxKind.SingleLineCommentTrivia,` Usage example:`),v.SyntaxKind.MultiLineCommentTrivia,`\n${t}`);return this.#e.concat(n||[]).map((t,n)=>cr(t,n<this.#e.length?e:{...e,omitTrailingSemicolon:!0})).join(`
19
19
 
20
- `)}async printFormatted({printerOptions:e,format:t}={}){let n=t;if(!n)try{let e=(await St(`prettier`)).format;n=t=>e(t,{filepath:`client.ts`})}catch{}let r=this.#i(e);this.#n=r&&n?[await n(r)]:this.#n;let i=this.print(e);return n?n(i):i}};const oi=(e,t)=>r.object({data:t,event:r.literal(e),id:r.string().optional(),retry:r.int().positive().optional()}),si=(e,t,n)=>oi(String(t),e[t]).transform(e=>[`event: ${e.event}`,`data: ${JSON.stringify(e.data)}`,``,``].join(`
21
- `)).parse({event:t,data:n}),ci=e=>e.headersSent||e.writeHead(200,{connection:`keep-alive`,"content-type":y.sse,"cache-control":`no-cache`}),li=e=>new M({handler:async({request:t,response:n})=>{let r=new AbortController;return t.once(`close`,()=>{r.abort()}),setTimeout(()=>ci(n),1e4),{isClosed:()=>n.writableEnded||n.closed,signal:r.signal,emit:(t,r)=>{ci(n),n.write(si(e,t,r),`utf-8`),n.flush?.()}}}}),ui=e=>new P({positive:()=>{let[t,...n]=Object.entries(e).map(([e,t])=>oi(e,t));return{mimeType:y.sse,schema:n.length?r.discriminatedUnion(`event`,[t,...n]):t}},negative:{mimeType:`text/plain`,schema:r.string()},handler:async({response:e,error:t,logger:n,request:r,input:i})=>{if(t){let a=A(t);Ye(a,n,r,i),e.headersSent||e.status(a.statusCode).type(`text/plain`).write(j(a),`utf-8`)}e.end()}});var di=class extends ut{constructor(e){super(ui(e)),this.middlewares=[li(e)]}};const fi={dateIn:Oe,dateOut:Ae,form:Re,upload:ze,raw:He,buffer:Ee};export{yt as BuiltinLogger,bt as DependsOnMethod,$n as Documentation,E as DocumentationError,ut as EndpointsFactory,di as EventStreamFactory,D as InputValidationError,ai as Integration,M as Middleware,Ie as MissingPeerError,Pe as OutputValidationError,P as ResultHandler,je as RoutingError,xt as ServeStatic,ft as arrayEndpointsFactory,lt as arrayResultHandler,ln as attachRouting,ce as createConfig,un as createServer,dt as defaultEndpointsFactory,F as defaultResultHandler,A as ensureHttpError,fi as ez,S as getMessageFromError,ir as testEndpoint,ar as testMiddleware};
20
+ `)}async printFormatted({printerOptions:e,format:t}={}){let n=t;if(!n)try{let e=(await bt(`prettier`)).format;n=t=>e(t,{filepath:`client.ts`})}catch{}let r=this.#i(e);this.#n=r&&n?[await n(r)]:this.#n;let i=this.print(e);return n?n(i):i}};const ii=(e,t)=>r.object({data:t,event:r.literal(e),id:r.string().optional(),retry:r.int().positive().optional()}),ai=(e,t,n)=>ii(String(t),e[t]).transform(e=>[`event: ${e.event}`,`data: ${JSON.stringify(e.data)}`,``,``].join(`
21
+ `)).parse({event:t,data:n}),oi=e=>e.headersSent||e.writeHead(200,{connection:`keep-alive`,"content-type":y.sse,"cache-control":`no-cache`}),si=e=>new P({handler:async({request:t,response:n})=>{let r=new AbortController;return t.once(`close`,()=>{r.abort()}),setTimeout(()=>oi(n),1e4),{isClosed:()=>n.writableEnded||n.closed,signal:r.signal,emit:(t,r)=>{oi(n),n.write(ai(e,t,r),`utf-8`),n.flush?.()}}}}),ci=e=>new it({positive:()=>{let[t,...n]=Object.entries(e).map(([e,t])=>ii(e,t));return{mimeType:y.sse,schema:n.length?r.discriminatedUnion(`event`,[t,...n]):t}},negative:{mimeType:`text/plain`,schema:r.string()},handler:async({response:e,error:t,logger:n,request:r,input:i})=>{if(t){let a=Ke(t);Ge(a,n,r,i),e.headersSent||e.status(a.statusCode).type(`text/plain`).write(qe(a),`utf-8`)}e.end()}});var li=class extends lt{constructor(e){super(ci(e)),this.middlewares=[si(e)]}};const ui={dateIn:Ee,dateOut:De,form:Pe,upload:Fe,raw:Re,buffer:Te};export{vt as BuiltinLogger,Zn as Documentation,A as DocumentationError,lt as EndpointsFactory,li as EventStreamFactory,j as InputValidationError,ri as Integration,P as Middleware,Me as MissingPeerError,Ae as OutputValidationError,it as ResultHandler,k as RoutingError,yt as ServeStatic,dt as arrayEndpointsFactory,ct as arrayResultHandler,sn as attachRouting,ce as createConfig,cn as createServer,ut as defaultEndpointsFactory,ot as defaultResultHandler,Ke as ensureHttpError,ui as ez,S as getMessageFromError,nr as testEndpoint,rr as testMiddleware};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "express-zod-api",
3
- "version": "25.6.0",
3
+ "version": "26.0.0-beta.2",
4
4
  "description": "A Typescript framework to help you get an API server up and running with I/O schema validation and custom middlewares in minutes.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -38,7 +38,7 @@
38
38
  "node-mocks-http": "^1.17.2",
39
39
  "openapi3-ts": "^4.5.0",
40
40
  "ramda": "^0.32.0",
41
- "@express-zod-api/zod-plugin": "^2.1.0"
41
+ "@express-zod-api/zod-plugin": "^3.0.0-beta.2"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "@types/compression": "^1.7.5",
@@ -50,7 +50,7 @@
50
50
  "express-fileupload": "^1.5.0",
51
51
  "http-errors": "^2.0.0",
52
52
  "typescript": "^5.1.3",
53
- "zod": "^4.0.0"
53
+ "zod": "^4.1.13"
54
54
  },
55
55
  "peerDependenciesMeta": {
56
56
  "@types/compression": {
@@ -92,7 +92,7 @@
92
92
  "snakify-ts": "^2.3.0",
93
93
  "typescript": "^5.9.2",
94
94
  "undici": "^7.10.0",
95
- "zod": "^4.0.0"
95
+ "zod": "^4.1.13"
96
96
  },
97
97
  "keywords": [
98
98
  "nodejs",