express-zod-api 25.6.1 → 26.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/README.md +33 -43
- package/SECURITY.md +2 -1
- package/dist/index.d.ts +56 -56
- package/dist/index.js +6 -6
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,44 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Version 26
|
|
4
|
+
|
|
5
|
+
### v26.0.0
|
|
6
|
+
|
|
7
|
+
- Supported `http-errors` versions: `^2.0.1`;
|
|
8
|
+
- Supported `zod` versions: `^4.1.13`:
|
|
9
|
+
- This Zod patch contains an [important fix](https://github.com/colinhacks/zod/pull/5452) that makes the
|
|
10
|
+
`globalRegistry` truly global across both CJS and ESM bundles of the Zod distribution;
|
|
11
|
+
- The issue was found and reported by [@shadone](https://github.com/shadone);
|
|
12
|
+
- The new version of the Zod plugin now also extends the CJS exports of Zod:
|
|
13
|
+
- This fixes the "TypeError: example is not a function" in CJS and removes the requirement to use an ESM environment;
|
|
14
|
+
- The issue was reported by [@squishykid](https://github.com/squishykid) and addressed earlier in [v25.5.3](#v2553);
|
|
15
|
+
- `DependsOnMethod` removed:
|
|
16
|
+
- You can now specify methods as direct keys of an assigned object in `Routing`;
|
|
17
|
+
- That object can still contain nested paths as before;
|
|
18
|
+
- Keys matching lowercase HTTP methods are treated according to the new config setting `methodLikeRouteBehavior`:
|
|
19
|
+
- `method` — when assigned with an Endpoint, the key is treated as a method of its parent path (default);
|
|
20
|
+
- `path` — the key is always treated as a nested path segment;
|
|
21
|
+
- The `options` property has been renamed to `ctx` in the argument of:
|
|
22
|
+
- `Middleware::handler()`,
|
|
23
|
+
- `ResultHandler::handler()`,
|
|
24
|
+
- The `handler` of the `EndpointsFactory::build()` argument,
|
|
25
|
+
- `testMiddleware()`;
|
|
26
|
+
- `EndpointsFactory::addOptions()` renamed to `addContext()`;
|
|
27
|
+
- The `Integration::constructor()` argument object now requires a `config` property, similar to `Documentation`;
|
|
28
|
+
- Consider [the automated migration](https://www.npmjs.com/package/@express-zod-api/migration).
|
|
29
|
+
|
|
30
|
+
```patch
|
|
31
|
+
const routing: Routing = {
|
|
32
|
+
- "/v1/users": new DependsOnMethod({
|
|
33
|
+
+ "/v1/users": {
|
|
34
|
+
get: getUserEndpoint,
|
|
35
|
+
- }).nest({
|
|
36
|
+
create: makeUserEndpoint
|
|
37
|
+
- }),
|
|
38
|
+
+ },
|
|
39
|
+
};
|
|
40
|
+
```
|
|
41
|
+
|
|
3
42
|
## Version 25
|
|
4
43
|
|
|
5
44
|
### v25.6.1
|
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. [
|
|
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,6 +86,7 @@ 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/shadone.png" alt="@shadone" width="50" />](https://github.com/shadone)
|
|
89
90
|
[<img src="https://github.com/squishykid.png" alt="@squishykid" width="50" />](https://github.com/squishykid)
|
|
90
91
|
[<img src="https://github.com/jakub-msqt.png" alt="@jakub-msqt" width="50" />](https://github.com/jakub-msqt)
|
|
91
92
|
[<img src="https://github.com/misha-z1nchuk.png" alt="@misha-z1nchuk" width="50" />](https://github.com/misha-z1nchuk)
|
|
@@ -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 `
|
|
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 },
|
|
237
|
-
logger.debug("
|
|
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,
|
|
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:
|
|
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 `
|
|
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
|
|
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 ({
|
|
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 `
|
|
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 ({
|
|
381
|
+
handler: async ({ ctx: { user } }) => ({}), // user from authMiddleware
|
|
387
382
|
});
|
|
388
383
|
```
|
|
389
384
|
|
|
390
|
-
##
|
|
385
|
+
## Context
|
|
391
386
|
|
|
392
|
-
|
|
393
|
-
|
|
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.
|
|
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: ({
|
|
415
|
-
// necessary to check
|
|
416
|
-
if ("db" in
|
|
417
|
-
|
|
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 [
|
|
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 `
|
|
1049
|
-
from
|
|
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 ({
|
|
1059
|
-
|
|
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
|
-
|
|
1062
|
+
ctx: { prev: "accumulated" }, // responseOptions, configProps, loggerProps
|
|
1068
1063
|
});
|
|
1069
1064
|
expect(loggerMock._getLogs().error).toHaveLength(0);
|
|
1070
|
-
expect(output).toEqual({
|
|
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
|
|
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
|
|
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:
|
|
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 ({
|
|
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/SECURITY.md
CHANGED
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
| Version | Code name | Release | Supported |
|
|
6
6
|
| ------: | :------------ | :------ | :----------------: |
|
|
7
|
+
| 26.x.x | Lia | 12.2025 | :white_check_mark: |
|
|
7
8
|
| 25.x.x | Sara | 08.2025 | :white_check_mark: |
|
|
8
9
|
| 24.x.x | Ashley | 06.2025 | :white_check_mark: |
|
|
9
10
|
| 23.x.x | Sonia | 04.2025 | :white_check_mark: |
|
|
10
11
|
| 22.x.x | Tai | 01.2025 | :white_check_mark: |
|
|
11
|
-
| 21.x.x | Kesaria | 11.2024 |
|
|
12
|
+
| 21.x.x | Kesaria | 11.2024 | :x: |
|
|
12
13
|
| 20.x.x | Zoey | 06.2024 | :x: |
|
|
13
14
|
| 19.x.x | Dime | 05.2024 | :x: |
|
|
14
15
|
| 18.x.x | Victoria | 04.2024 | :x: |
|
package/dist/index.d.ts
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
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<
|
|
254
|
+
}) => Promise<RET>;
|
|
255
255
|
declare abstract class AbstractMiddleware {
|
|
256
256
|
abstract execute(params: {
|
|
257
257
|
input: unknown;
|
|
258
|
-
|
|
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<
|
|
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
|
|
280
|
-
handler: Handler$2<z.output<IN>,
|
|
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
|
-
|
|
288
|
+
ctx: CTX;
|
|
289
289
|
request: Request;
|
|
290
290
|
response: Response;
|
|
291
291
|
logger: ActualLogger;
|
|
292
|
-
}): Promise<
|
|
292
|
+
}): Promise<RET>;
|
|
293
293
|
}
|
|
294
|
-
declare class ExpressMiddleware<R extends Request, S$1 extends Response,
|
|
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) =>
|
|
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
|
-
|
|
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 |
|
|
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,
|
|
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
|
-
|
|
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
|
|
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,
|
|
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>,
|
|
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,
|
|
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 (
|
|
640
|
-
handler: Handler<z.output<FinalInputSchema<MIN, IN>>, z.input<OUT>,
|
|
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
|
|
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,
|
|
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<
|
|
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>,
|
|
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>,
|
|
678
|
-
|
|
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,
|
|
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,
|
|
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
|
/**
|
|
@@ -878,13 +876,13 @@ declare const testEndpoint: <LOG extends FlatObject, REQ extends RequestOptions>
|
|
|
878
876
|
}>;
|
|
879
877
|
declare const testMiddleware: <LOG extends FlatObject, REQ extends RequestOptions>({
|
|
880
878
|
middleware,
|
|
881
|
-
|
|
879
|
+
ctx,
|
|
882
880
|
...rest
|
|
883
881
|
}: TestingProps<REQ, LOG> & {
|
|
884
882
|
/** @desc The middleware to test */
|
|
885
883
|
middleware: AbstractMiddleware;
|
|
886
|
-
/** @desc The aggregated
|
|
887
|
-
|
|
884
|
+
/** @desc The aggregated returns of previously executed middlewares */
|
|
885
|
+
ctx?: FlatObject;
|
|
888
886
|
}) => Promise<{
|
|
889
887
|
requestMock: node_mocks_http0.MockRequest<Request<express_serve_static_core0.ParamsDictionary, any, any, qs0.ParsedQs, Record<string, any>> & REQ>;
|
|
890
888
|
responseMock: node_mocks_http0.MockResponse<Response<any, Record<string, any>>>;
|
|
@@ -923,6 +921,7 @@ type Producer = SchemaHandler<ts.TypeNode, ZTSContext>;
|
|
|
923
921
|
//#region src/integration.d.ts
|
|
924
922
|
interface IntegrationParams {
|
|
925
923
|
routing: Routing;
|
|
924
|
+
config: CommonConfig;
|
|
926
925
|
/**
|
|
927
926
|
* @desc What should be generated
|
|
928
927
|
* @example "types" — types of your endpoint requests and responses (for a DIY solution)
|
|
@@ -970,6 +969,7 @@ declare class Integration extends IntegrationBase {
|
|
|
970
969
|
#private;
|
|
971
970
|
constructor({
|
|
972
971
|
routing,
|
|
972
|
+
config,
|
|
973
973
|
brandHandling,
|
|
974
974
|
variant,
|
|
975
975
|
clientClassName,
|
|
@@ -1035,4 +1035,4 @@ declare const ez: {
|
|
|
1035
1035
|
buffer: () => zod_v4_core0.$ZodBranded<zod0.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>, symbol>;
|
|
1036
1036
|
};
|
|
1037
1037
|
//#endregion
|
|
1038
|
-
export { type ApiResponse, type AppConfig, type BasicSecurity, type BearerSecurity, BuiltinLogger, type CommonConfig, type CookieSecurity,
|
|
1038
|
+
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))),
|
|
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]=r&&b(e)&&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.1`,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)=>
|
|
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`,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
|
|
21
|
-
`)).parse({event:t,data:n}),
|
|
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": "
|
|
3
|
+
"version": "26.0.0",
|
|
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": "^
|
|
41
|
+
"@express-zod-api/zod-plugin": "^3.0.0"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"@types/compression": "^1.7.5",
|
|
@@ -48,9 +48,9 @@
|
|
|
48
48
|
"compression": "^1.8.0",
|
|
49
49
|
"express": "^5.1.0",
|
|
50
50
|
"express-fileupload": "^1.5.0",
|
|
51
|
-
"http-errors": "^2.0.
|
|
51
|
+
"http-errors": "^2.0.1",
|
|
52
52
|
"typescript": "^5.1.3",
|
|
53
|
-
"zod": "^4.
|
|
53
|
+
"zod": "^4.1.13"
|
|
54
54
|
},
|
|
55
55
|
"peerDependenciesMeta": {
|
|
56
56
|
"@types/compression": {
|
|
@@ -87,12 +87,12 @@
|
|
|
87
87
|
"depd": "^2.0.0",
|
|
88
88
|
"express": "^5.1.0",
|
|
89
89
|
"express-fileupload": "^1.5.1",
|
|
90
|
-
"http-errors": "^2.0.
|
|
90
|
+
"http-errors": "^2.0.1",
|
|
91
91
|
"node-forge": "^1.3.2",
|
|
92
92
|
"snakify-ts": "^2.3.0",
|
|
93
93
|
"typescript": "^5.9.2",
|
|
94
94
|
"undici": "^7.10.0",
|
|
95
|
-
"zod": "^4.
|
|
95
|
+
"zod": "^4.1.13"
|
|
96
96
|
},
|
|
97
97
|
"keywords": [
|
|
98
98
|
"nodejs",
|