express-zod-api 27.2.2 → 28.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,53 @@
1
1
  # Changelog
2
2
 
3
+ ## Version 28
4
+
5
+ ### v28.0.0
6
+
7
+ - Supported Node.js versions: `^22.19.0 || ^24.0.0`;
8
+ - The Zod plugin is no longer installed automatically — it's an optional peer dependency now:
9
+ - To keep using `.example()`, `.label()`, `.remap()`, `.deprecated()` and `.brand()` methods on schemas
10
+ install the `@express-zod-api/zod-plugin` manually and import it (ideally at the top of a file declaring `Routing`);
11
+ - Breaking changes to the `createConfig()` argument (object):
12
+ - property `wrongMethodBehavior` (number) changed to `hintAllowedMethods` (boolean);
13
+ - property `methodLikeRouteBehavior` (string literal) changed to `recognizeMethodDependentRoutes` (boolean);
14
+ - Breaking change to the `EndpointsFactory::build()` argument (object):
15
+ - property `shortDescription` renamed to `summary`;
16
+ - Breaking change to the `Documentation` constructor argument (object):
17
+ - property `hasSummaryFromDescription` (boolean) replaced with `summarizer` (function);
18
+ - If used with `false` value, replace it with `summarizer: ({ summary, trim }) => trim(summary)` for same behavior;
19
+ - Featuring `summarizer` option to customize the summary of the Endpoint in the generated Documentation:
20
+ - The function receives `summary`, `description` and the default `trim()` function as arguments;
21
+ - The default summarizer uses `description` as a fallback for missing `summary`;
22
+ - The `trim()` function accepts a string and the limit (default: 50, best practice) that you can now customize;
23
+ - Breaking change to the `Integration` constructor argument (object):
24
+ - property `noContent` renamed to `noBodySchema`;
25
+ - Consider using [the automated migration](https://www.npmjs.com/package/@express-zod-api/migration).
26
+
27
+ ```diff
28
+ createConfig({
29
+ - wrongMethodBehavior: 404,
30
+ + hintAllowedMethods: false,
31
+ - methodLikeRouteBehavior: "path",
32
+ + recognizeMethodDependentRoutes: false,
33
+ });
34
+
35
+ factory.build({
36
+ - shortDescription: "Retrieves the user.",
37
+ + summary: "Retrieves the user.",
38
+ });
39
+
40
+ new Documentation({
41
+ - hasSummaryFromDescription: false,
42
+ + summarizer: ({ summary, trim }) => trim(summary),
43
+ });
44
+
45
+ new Integration({
46
+ - noContent: z.undefined(),
47
+ + noBodySchema: z.undefined(),
48
+ });
49
+ ```
50
+
3
51
  ## Version 27
4
52
 
5
53
  ### v27.2.2
package/README.md CHANGED
@@ -164,7 +164,7 @@ Much can be customized to fit your needs.
164
164
 
165
165
  - [Typescript](https://www.typescriptlang.org/) first.
166
166
  - Web server — [Express.js](https://expressjs.com/) v5.
167
- - Schema validation — [Zod 4.x](https://github.com/colinhacks/zod) including [Zod Plugin](#zod-plugin):
167
+ - Schema validation — [Zod 4.x](https://github.com/colinhacks/zod)
168
168
  - For using with Zod 3.x, install the framework versions below 24.0.0.
169
169
  - Supports any logger having `info()`, `debug()`, `error()` and `warn()` methods;
170
170
  - Built-in console logger with colorful and pretty inspections by default.
@@ -243,7 +243,7 @@ const helloWorldEndpoint = defaultEndpointsFactory.build({
243
243
  Connect your endpoint to the `/v1/hello` route:
244
244
 
245
245
  ```ts
246
- import { Routing } from "express-zod-api";
246
+ import type { Routing } from "express-zod-api";
247
247
 
248
248
  const routing: Routing = {
249
249
  v1: {
@@ -920,7 +920,7 @@ it normalizes errors into consistent HTTP responses with sensible status codes.
920
920
  - Routing, parsing and upload issues:
921
921
  - Handled by `ResultHandler` configured as `errorHandler` (the defaults is `defaultResultHandler`);
922
922
  - Parsing errors: passed through as-is (typically `HttpError` with `4XX` code used for response by default);
923
- - Routing errors: `404` or `405`, based on `wrongMethodBehavior` configuration;
923
+ - Routing errors: `404` or `405`, based on `hintAllowedMethods` configuration;
924
924
  - Upload issues: thrown only if `upload.limitError` is configured (`HttpError::statusCode` can be used for response);
925
925
  - For other errors the default status code is `500`;
926
926
  - `ResultHandler` failures:
@@ -1100,8 +1100,21 @@ expect(output).toEqual({ collectedContext: ["prev"], testLength: 9 });
1100
1100
 
1101
1101
  ## Zod Plugin
1102
1102
 
1103
- Express Zod API augments Zod using [Zod Plugin](https://www.npmjs.com/package/@express-zod-api/zod-plugin),
1104
- adding the runtime helpers the framework relies on.
1103
+ The [@express-zod-api/zod-plugin](https://www.npmjs.com/package/@express-zod-api/zod-plugin) is an optional package
1104
+ that extends Zod with convenience methods:
1105
+
1106
+ - `.brand(name)` — enhanced with a shorthand for `.meta({ "x-brand": name })`;
1107
+ - `.example(value)` — shorthand for `.meta({ examples: [value] })`;
1108
+ - `.deprecated()` — shorthand for `.meta({ deprecated: true })`;
1109
+ - `.label(text)` — shorthand for `.meta({ default: text })` on `ZodDefault`;
1110
+ - `.remap(mapping)` — for renaming `ZodObject` shape properties;
1111
+
1112
+ To benefit from these methods, install `@express-zod-api/zod-plugin` and import it once, preferably at the top of a
1113
+ file declaring your `Routing`.
1114
+
1115
+ ```ts
1116
+ import "@express-zod-api/zod-plugin"; // in your routing.ts file
1117
+ ```
1105
1118
 
1106
1119
  ## End-to-End Type Safety
1107
1120
 
@@ -1162,12 +1175,12 @@ in the generated documentation of your API. Consider the following example:
1162
1175
  import { defaultEndpointsFactory } from "express-zod-api";
1163
1176
 
1164
1177
  const exampleEndpoint = defaultEndpointsFactory.build({
1165
- shortDescription: "Retrieves the user.", // <—— this becomes the summary line
1178
+ summary: "Retrieves the user.",
1166
1179
  description: "The detailed explanaition on what this endpoint does.",
1167
1180
  input: z.object({
1168
1181
  id: z
1169
- .string()
1170
- .example("123") // input examples should be set before transformations
1182
+ .string() // input examples should be set before transformations
1183
+ .example("123") // requires Zod Plugin, or .meta({ examples: ["123"] })
1171
1184
  .transform(Number)
1172
1185
  .describe("the ID of the user"),
1173
1186
  }),
@@ -1175,7 +1188,8 @@ const exampleEndpoint = defaultEndpointsFactory.build({
1175
1188
  });
1176
1189
  ```
1177
1190
 
1178
- You can also use `schema.meta({ id: "UniqueName" })` for custom schema naming.
1191
+ Setting examples via `.example()` requires [Zod Plugin](#zod-plugin). You can also use `.meta({ examples: [] })` and
1192
+ `.meta({ id: "UniqueName" })` for custom schema naming.
1179
1193
  _See the complete example of the generated documentation
1180
1194
  [here](https://github.com/RobinTail/express-zod-api/blob/master/example/example.documentation.yaml)_
1181
1195
 
@@ -1213,18 +1227,18 @@ new Documentation({
1213
1227
 
1214
1228
  ## Deprecated schemas and routes
1215
1229
 
1216
- As your API evolves, you may need to mark some parameters or routes as deprecated before deleting them. For this
1217
- purpose, the `.deprecated()` method is available on each schema and `Endpoint`, it's immutable.
1218
- You can also deprecate all routes the `Endpoint` assigned to by setting `EndpointsFactory::build({ deprecated: true })`.
1230
+ As your API evolves, you may need to mark some parameters or routes as deprecated before deleting them. This can be
1231
+ achieved using the corresponding method or metadata. The `.deprecated()` method on Zod schema requires to install the
1232
+ [Zod Plugin](#zod-plugin). Consider the following example:
1219
1233
 
1220
1234
  ```ts
1221
- import { Routing } from "express-zod-api";
1235
+ import type { Routing } from "express-zod-api";
1222
1236
  import { z } from "zod";
1223
1237
 
1224
1238
  const someEndpoint = factory.build({
1225
1239
  deprecated: true, // deprecates all routes the endpoint assigned to
1226
1240
  input: z.object({
1227
- prop: z.string().deprecated(), // deprecates the property or a path parameter
1241
+ prop: z.string().deprecated(), // requires Zod Plugin, or .meta({ deprecated: true })
1228
1242
  }),
1229
1243
  });
1230
1244
 
@@ -1236,8 +1250,9 @@ const routing: Routing = {
1236
1250
 
1237
1251
  ## Customizable brands handling
1238
1252
 
1239
- You can customize handling rules for your schemas in Documentation and Integration. Use the `.brand()` method on your
1240
- schema to make it special and distinguishable for the framework in runtime. Using symbols is recommended for branding.
1253
+ You can customize handling rules for your schemas in Documentation and Integration. The framework treats your schema
1254
+ specially based on its `x-brand` metadata. When the [Zod Plugin](#zod-plugin) is installed you can conveniently use
1255
+ the `.brand()` enhanced method of the Zod schema, preferably with a symbol argument for its branding.
1241
1256
  After that use the `brandHandling` feature of both constructors to declare your custom implementation. In case you need
1242
1257
  to reuse a handling rule for multiple brands, use the exposed types `Depicter` and `Producer`.
1243
1258
 
@@ -1252,7 +1267,7 @@ import {
1252
1267
  } from "express-zod-api";
1253
1268
 
1254
1269
  const myBrand = Symbol("MamaToldMeImSpecial"); // I recommend to use symbols for this purpose
1255
- const myBrandedSchema = z.string().brand(myBrand);
1270
+ const myBrandedSchema = z.string().brand(myBrand); // requires Zod Plugin, or .meta({ "x-brand": myBrand })
1256
1271
 
1257
1272
  const ruleForDocs: Depicter = (
1258
1273
  { zodSchema, jsonSchema }, // jsonSchema is the default depiction
package/SECURITY.md CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  | Version | Code name | Release | Supported |
6
6
  | ------: | :------------ | :------ | :----------------: |
7
+ | 28.x.x | Koko | 04.2026 | :white_check_mark: |
7
8
  | 27.x.x | Nikki | 02.2026 | :white_check_mark: |
8
9
  | 26.x.x | Lia | 12.2025 | :white_check_mark: |
9
10
  | 25.x.x | Sara | 08.2025 | :white_check_mark: |
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import "@express-zod-api/zod-plugin";
2
1
  import * as _$zod from "zod";
3
2
  import { z } from "zod";
4
3
  import { HttpError } from "http-errors";
@@ -388,7 +387,7 @@ type GetLogger = (request?: Request) => ActualLogger;
388
387
  * @example { "get /v1/books/:bookId": getBookEndpoint }
389
388
  * @example { v1: { "patch /books/:bookId": changeBookEndpoint } }
390
389
  * @example { dependsOnMethod: { get: retrieveEndpoint, post: createEndpoint } }
391
- * @see CommonConfig.methodLikeRouteBehavior
390
+ * @see CommonConfig.recognizeMethodDependentRoutes
392
391
  * */
393
392
  interface Routing {
394
393
  [K: string]: Routing | AbstractEndpoint | ServeStatic;
@@ -422,7 +421,7 @@ declare class Endpoint<IN extends IOSchema, OUT extends IOSchema, CTX extends Fl
422
421
  handler: Handler<z.output<IN>, z.input<OUT>, CTX>;
423
422
  resultHandler: AbstractResultHandler;
424
423
  description?: string;
425
- shortDescription?: string;
424
+ summary?: string;
426
425
  getOperationId?: (method: ClientMethod) => string | undefined;
427
426
  methods?: Method[];
428
427
  scopes?: string[];
@@ -461,20 +460,21 @@ interface CommonConfig {
461
460
  */
462
461
  cors: boolean | HeadersProvider;
463
462
  /**
464
- * @desc How to respond to a request that uses a wrong method to an existing endpoint
465
- * @example 404Not found
466
- * @example 405Method not allowed, incl. the "Allow" header with a list of methods
467
- * @default 405
468
- * */
469
- wrongMethodBehavior?: 404 | 405;
463
+ * @desc Controls how to respond to a request to an existing endpoint with an invalid HTTP method.
464
+ * @example truerespond with status code 405 and "Allow" header containing a list of valid methods
465
+ * @example falserespond with status code 404 (Not found)
466
+ * @default true
467
+ */
468
+ hintAllowedMethods?: boolean;
470
469
  /**
471
- * @desc How to treat Routing keys that look like methods (when assigned with an Endpoint)
472
- * @see Method
473
- * @example "method" the key is treated as method of its parent path
474
- * @example "path"the key is treated as a nested path segment
475
- * @default "method"
476
- * */
477
- methodLikeRouteBehavior?: "method" | "path";
470
+ * @desc Controls how to treat Routing keys matching HTTP methods ("get", "post") and having Endpoint assigned.
471
+ * @example true — treat such keys as HTTP methods complementing their parent paths
472
+ * { users: { get: ... }} becomes GET /users
473
+ * @example falsetreat such keys as nested path segments regardless of the name
474
+ * { users: { get: ... }} remains /users/get
475
+ * @default true
476
+ */
477
+ recognizeMethodDependentRoutes?: boolean;
478
478
  /**
479
479
  * @desc The ResultHandler to use for handling routing, parsing and upload errors
480
480
  * @default defaultResultHandler
@@ -651,10 +651,10 @@ interface BuildProps<
651
651
  output: OUT;
652
652
  /** @desc The Endpoint handler receiving the validated inputs, returns of added Middlewares (ctx) and a logger */
653
653
  handler: Handler<z.output<FinalInputSchema<MIN, IN>>, z.input<OUT>, CTX>;
654
- /** @desc The operation description for the generated Documentation */
654
+ /** @desc The operation description for the generated Documentation (may use Markdown) */
655
655
  description?: string;
656
- /** @desc The operation summary for the generated Documentation (50 symbols max) */
657
- shortDescription?: string;
656
+ /** @desc The operation summary for the generated Documentation (short plain string) */
657
+ summary?: string;
658
658
  /** @desc The operation ID for the generated Documentation (must be unique) */
659
659
  operationId?: string | ((method: ClientMethod) => string);
660
660
  /**
@@ -779,6 +779,8 @@ declare const depictTags: (
779
779
  >
780
780
  >,
781
781
  ) => TagObject[];
782
+ /** @desc Ensures the summary string does not exceed the limit */
783
+ declare const trimSummary: (summary?: string, limit?: number) => string | undefined;
782
784
  type Component = "positiveResponse" | "negativeResponse" | "requestParameter" | "requestBody";
783
785
  /** @desc user defined function that creates a component description from its properties */
784
786
  type Descriptor = (
@@ -786,6 +788,7 @@ type Descriptor = (
786
788
  statusCode?: number;
787
789
  },
788
790
  ) => string;
791
+ type Summarizer = (params: { summary?: string; description?: string; trim: typeof trimSummary }) => string | undefined;
789
792
  interface DocumentationParams {
790
793
  title: string;
791
794
  version: string;
@@ -798,8 +801,12 @@ interface DocumentationParams {
798
801
  * @default () => `${method} ${path} ${component}`
799
802
  * */
800
803
  descriptions?: Partial<Record<Component, Descriptor>>;
801
- /** @default true */
802
- hasSummaryFromDescription?: boolean;
804
+ /**
805
+ * @desc The function that ensures the maximum length for summary fields. Can optionally make them from descriptions.
806
+ * @see defaultSummarizer
807
+ * @see trimSummary
808
+ * */
809
+ summarizer?: Summarizer;
803
810
  /**
804
811
  * @desc Depict the HEAD method for each Endpoint supporting the GET method (feature of Express)
805
812
  * @default true
@@ -839,8 +846,8 @@ declare class Documentation extends OpenApiBuilder {
839
846
  brandHandling,
840
847
  tags,
841
848
  isHeader,
842
- hasSummaryFromDescription,
843
849
  hasHeadMethod,
850
+ summarizer,
844
851
  composition,
845
852
  }: DocumentationParams);
846
853
  }
@@ -916,7 +923,7 @@ declare const testEndpoint: <LOG extends FlatObject, REQ extends RequestOptions>
916
923
  responseMock: _$node_mocks_http0.MockResponse<Response<any, Record<string, any>>>;
917
924
  loggerMock: AbstractLogger &
918
925
  LOG & {
919
- _getLogs: () => Record<"debug" | "info" | "warn" | "error", unknown[]>;
926
+ _getLogs: () => Record<"error" | "debug" | "info" | "warn", unknown[]>;
920
927
  };
921
928
  }>;
922
929
  declare const testMiddleware: <LOG extends FlatObject, REQ extends RequestOptions>({
@@ -935,7 +942,7 @@ declare const testMiddleware: <LOG extends FlatObject, REQ extends RequestOption
935
942
  responseMock: _$node_mocks_http0.MockResponse<Response<any, Record<string, any>>>;
936
943
  loggerMock: AbstractLogger &
937
944
  LOG & {
938
- _getLogs: () => Record<"debug" | "info" | "warn" | "error", unknown[]>;
945
+ _getLogs: () => Record<"error" | "debug" | "info" | "warn", unknown[]>;
939
946
  };
940
947
  output: FlatObject;
941
948
  }>;
@@ -982,7 +989,7 @@ interface IntegrationParams {
982
989
  * @desc The schema to use for responses without body such as 204
983
990
  * @default z.undefined()
984
991
  * */
985
- noContent?: z.ZodType;
992
+ noBodySchema?: z.ZodType;
986
993
  /**
987
994
  * @desc Depict the HEAD method for each Endpoint supporting the GET method (feature of Express)
988
995
  * @default true
@@ -1015,7 +1022,7 @@ declare class Integration extends IntegrationBase {
1015
1022
  clientClassName,
1016
1023
  subscriptionClassName,
1017
1024
  serverUrl,
1018
- noContent,
1025
+ noBodySchema,
1019
1026
  hasHeadMethod,
1020
1027
  }: IntegrationParams);
1021
1028
  static create(params: Omit<IntegrationParams, "typescript">): Promise<Integration>;
@@ -1152,32 +1159,28 @@ declare function paginated<T extends z.ZodType, K extends string = typeof DEFAUL
1152
1159
  ): CursorPaginatedResult<T, K>;
1153
1160
  declare const base: z.ZodObject<
1154
1161
  {
1155
- raw: z.core.$ZodBranded<z.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>, symbol, "out">;
1162
+ raw: z.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>;
1156
1163
  },
1157
1164
  z.core.$strip
1158
1165
  >;
1159
- type Base = ReturnType<typeof base.brand<symbol>>;
1166
+ type Base = typeof base;
1160
1167
  declare const extended: <S extends z.core.$ZodShape>(
1161
1168
  extra: S,
1162
- ) => z.core.$ZodBranded<
1163
- z.ZodObject<
1164
- (
1165
- "raw" & keyof S extends never
1166
- ? {
1167
- raw: z.core.$ZodBranded<z.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>, symbol, "out">;
1168
- } & S
1169
- : ({
1170
- raw: z.core.$ZodBranded<z.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>, symbol, "out">;
1171
- } extends infer T_1 extends z.core.util.SomeObject
1172
- ? { [K in keyof T_1 as K extends keyof S ? never : K]: T_1[K] }
1173
- : never) & { [K_1 in keyof S]: S[K_1] }
1174
- ) extends infer T
1175
- ? { [k in keyof T]: T[k] }
1176
- : never,
1177
- z.core.$strip
1178
- >,
1179
- symbol,
1180
- "out"
1169
+ ) => z.ZodObject<
1170
+ (
1171
+ "raw" & keyof S extends never
1172
+ ? {
1173
+ raw: z.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>;
1174
+ } & S
1175
+ : ({
1176
+ raw: z.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>;
1177
+ } extends infer T_1 extends z.core.util.SomeObject
1178
+ ? { [K in keyof T_1 as K extends keyof S ? never : K]: T_1[K] }
1179
+ : never) & { [K_1 in keyof S]: S[K_1] }
1180
+ ) extends infer T
1181
+ ? { [k in keyof T]: T[k] }
1182
+ : never,
1183
+ z.core.$strip
1181
1184
  >;
1182
1185
  declare function raw(): Base;
1183
1186
  declare function raw<S extends z.core.$ZodShape>(extra: S): ReturnType<typeof extended<S>>;
@@ -1185,34 +1188,18 @@ declare const ez: {
1185
1188
  dateIn: ({
1186
1189
  examples,
1187
1190
  ...rest
1188
- }?: DateInParams) => _$zod_v4_core0.$ZodBranded<
1191
+ }?: DateInParams) => _$zod.ZodPipe<
1189
1192
  _$zod.ZodPipe<
1190
- _$zod.ZodPipe<
1191
- _$zod.ZodUnion<readonly [_$zod.ZodISODate, _$zod.ZodISODateTime, _$zod.ZodISODateTime]>,
1192
- _$zod.ZodTransform<Date, string>
1193
- >,
1194
- _$zod.ZodDate
1193
+ _$zod.ZodUnion<readonly [_$zod.ZodISODate, _$zod.ZodISODateTime, _$zod.ZodISODateTime]>,
1194
+ _$zod.ZodTransform<Date, string>
1195
1195
  >,
1196
- symbol,
1197
- "out"
1198
- >;
1199
- dateOut: (
1200
- meta?: DateOutParams,
1201
- ) => _$zod_v4_core0.$ZodBranded<_$zod.ZodPipe<_$zod.ZodDate, _$zod.ZodTransform<string, Date>>, symbol, "out">;
1202
- form: <S extends _$zod_v4_core0.$ZodShape>(
1203
- base: S | _$zod.ZodObject<S>,
1204
- ) => _$zod_v4_core0.$ZodBranded<_$zod.ZodObject<S, _$zod_v4_core0.$strip>, symbol, "out">;
1205
- upload: () => _$zod_v4_core0.$ZodBranded<
1206
- _$zod.ZodCustom<_$express_fileupload0.UploadedFile, _$express_fileupload0.UploadedFile>,
1207
- symbol,
1208
- "out"
1196
+ _$zod.ZodDate
1209
1197
  >;
1198
+ dateOut: (meta?: DateOutParams) => _$zod.ZodPipe<_$zod.ZodDate, _$zod.ZodTransform<string, Date>>;
1199
+ form: <S extends _$zod_v4_core0.$ZodShape>(base: S | _$zod.ZodObject<S>) => _$zod.ZodObject<S, _$zod_v4_core0.$strip>;
1200
+ upload: () => _$zod.ZodCustom<_$express_fileupload0.UploadedFile, _$express_fileupload0.UploadedFile>;
1210
1201
  raw: typeof raw;
1211
- buffer: () => _$zod_v4_core0.$ZodBranded<
1212
- _$zod.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>,
1213
- symbol,
1214
- "out"
1215
- >;
1202
+ buffer: () => _$zod.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>;
1216
1203
  paginated: typeof paginated;
1217
1204
  };
1218
1205
  export {
package/dist/index.js CHANGED
@@ -1,6 +1,5 @@
1
-
2
- 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{isPromise as o}from"node:util/types";import s,{blue as c,cyanBright as l,gray as u,green as d,hex as f,italic as p,red as m,whiteBright as h}from"ansis";import{inspect as g}from"node:util";import{performance as _}from"node:perf_hooks";import v from"express";import ee from"node:http";import te from"node:https";import{setInterval as y}from"node:timers/promises";import{OpenApiBuilder as ne,isReferenceObject as re,isSchemaObject as b}from"openapi3-ts/oas31";import{createRequest as ie,createResponse as ae}from"node-mocks-http";function oe(e){return e}const x={json:`application/json`,upload:`multipart/form-data`,raw:`application/octet-stream`,sse:`text/event-stream`,form:`application/x-www-form-urlencoded`},se=[`get`,`post`,`put`,`delete`,`patch`],ce=[...se,`head`],S=e=>se.includes(e),le=r.object({}),ue=/:([A-Za-z0-9_]+)/g,de=e=>e.match(ue)?.map(e=>e.slice(1))||[],fe=e=>{let t=(e.header(`content-type`)||``).toLowerCase().startsWith(x.upload);return`files`in e&&t},pe={get:[`query`,`params`],post:[`body`,`params`,`files`],put:[`body`,`params`],patch:[`body`,`params`],delete:[`query`,`params`]},me=[`body`,`query`,`params`],he=e=>e.method.toLowerCase(),ge=(e,t={})=>{if(e===`options`)return[];let n=e===`head`?`get`:S(e)?e:void 0;return(n?t[n]||pe[n]:void 0)||me},_e=(e,t={})=>ge(he(e),t).filter(t=>t===`files`?fe(e):!0).reduce((t,n)=>Object.assign(t,e[n]),{}),C=e=>e instanceof Error?e:e instanceof r.ZodError?new r.ZodRealError(e.issues):Error(String(e)),w=e=>e instanceof r.ZodError?e.issues.map(({path:e,message:t})=>`${e.length?`${r.core.toDotPath(e)}: `:``}${t}`).join(`; `):e.message,T=(e,n)=>O(e)&&`_zod`in e&&(n?t.path([`_zod`,`def`,`type`],e)===n:!0),E=(e,n,r)=>e.length&&n.length?t.xprod(e,n).map(r):e.concat(n),ve=e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase(),D=(...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(ve).join(``)},ye=t.tryCatch((e,t)=>typeof r.parse(e,t),t.always(void 0)),O=e=>typeof e==`object`&&!!e,k=t.memoizeWith(()=>`static`,()=>process.env.NODE_ENV===`production`),be=(e,t)=>!!t&&e!==`head`,A=Symbol(`Buffer`),xe=()=>r.custom(e=>Buffer.isBuffer(e),{error:`Expected Buffer`}).brand(A),j=Symbol(`DateIn`),Se=({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(j).meta(t),M=Symbol(`DateOut`),Ce=(e={})=>r.date().transform(e=>e.toISOString()).brand(M).meta(e);var N=class extends Error{name=`RoutingError`;cause;constructor(e,t,n){super(e),this.cause={method:t,path:n}}},P=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.`}},F=class extends Error{name=`IOSchemaError`},we=class extends F{name=`DeepCheckError`;constructor(e){super(`Found`,{cause:e}),this.cause=e}},Te=class extends F{name=`OutputValidationError`;constructor(e){let t=new r.ZodError(e.issues.map(({path:e,...t})=>({...t,path:[`output`,...e]})));super(w(t),{cause:e}),this.cause=e}},I=class extends F{name=`InputValidationError`;constructor(e){super(w(e),{cause:e}),this.cause=e}},Ee=class extends Error{name=`ResultHandlerError`;constructor(e,t){super(w(e),{cause:e}),this.cause=e,this.handled=t}},De=class extends Error{name=`MissingPeerError`;constructor(e){super(`Missing peer dependency: ${e}. Please install it to use the feature.`)}};const Oe=Symbol(`Form`),ke=e=>(e instanceof r.ZodObject?e:r.object(e)).brand(Oe),L=Symbol(`Upload`),Ae=()=>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(L),R=Symbol(`Raw`),je=r.object({raw:xe()}),Me=e=>je.extend(e).brand(R);function Ne(e){return e?Me(e):je.brand(R)}const Pe=(e,{io:n,condition:i})=>t.tryCatch(()=>void r.toJSONSchema(e,{io:n,unrepresentable:`any`,override:({zodSchema:e})=>{if(i(e))throw new we(e)}}),e=>e.cause)(),Fe=(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},Ie=t=>Pe(t,{condition:t=>{let n=e(t);return typeof n==`symbol`&&[L,R,Oe].includes(n)},io:`input`}),Le=[`nan`,`symbol`,`map`,`set`,`bigint`,`void`,`promise`,`never`,`function`],Re=(t,n)=>Pe(t,{io:n,condition:t=>{let r=e(t),{type:i}=t._zod.def;return!!(Le.includes(i)||r===A||n===`input`&&(i===`date`||r===M)||n===`output`&&(r===j||r===R||r===L))}}),ze=(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 Ee(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}))},Be=(e,t,{url:n},r)=>!e.expose&&t.error(`Server side error`,{error:e,url:n,payload:r}),z=e=>a(e)?e:i(e instanceof I?400:500,w(e),{cause:e.cause||e}),B=e=>k()&&!e.expose?i(e.statusCode).message:e.message,Ve=e=>Object.entries(e._zod.def.shape).reduce((e,[r,i])=>{let{examples:a=[]}=n.get(i)||{};return E(e,a.map(t.objOf(r)),([e,t])=>({...e,...t}))},[]),He=({error:e,logger:t,response:n})=>{t.error(`Result handler failure`,e);let r=B(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 Ue=class{},V=class extends Ue{#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||le).parseAsync(e);return this.#n({...t,input:n})}catch(e){throw e instanceof r.ZodError?new I(e):e}}},We=class extends V{constructor(e,{provider:t=()=>({}),transformer:n=e=>e}={}){super({handler:async({request:r,response:i})=>new Promise((a,s)=>{let c=e=>{if(e&&e instanceof Error)return s(n(e));a(t(r,i))},l=e(r,i,c);o(l)&&l.catch(c)})})}},Ge=class{nest(e){return{...e,"":this}}},Ke=class i extends Ge{#e;#t=t.once(()=>{if(n.get(this.#e.outputSchema)?.examples?.length||!T(this.#e.outputSchema,`object`))return;let e=Ve(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=Ie(this.#e.inputSchema);if(t){let n=e(t);if(n===L)return`upload`;if(n===R)return`raw`;if(n===Oe)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 Te(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 We))&&(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 I(e):e}return this.#e.handler({...t,input:n})}async#o(e){try{await this.#e.resultHandler.execute(e)}catch(t){He({...e,error:new Ee(C(t),e.error||void 0)})}}async execute({request:e,response:t,logger:n,config:r}){let i=he(e),a={},o={output:{},error:null},s=_e(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:C(e)}}await this.#o({...o,input:s,request:e,response:t,logger:n,ctx:a})}};const qe=(e,t)=>e&&t?e.and(t):e||t,Je=(e,t)=>e?e.and(t):t,H={positive:200,negative:400},Ye=Object.keys(H);var Xe=class{#e;constructor(e){this.#e=e}execute(...e){return this.#e(...e)}},U=class extends Xe{#e;#t;constructor(e){super(e.handler),this.#e=e.positive,this.#t=e.negative}getPositiveResponse(e){return ze(this.#e,{variant:`positive`,args:[e],statusCodes:[H.positive],mimeTypes:[x.json]})}getNegativeResponse(){return ze(this.#t,{variant:`negative`,args:[],statusCodes:[H.negative],mimeTypes:[x.json]})}};const Ze=r.object({status:r.literal(`error`),error:r.object({message:r.string()})});n.add(Ze,{examples:[{status:`error`,error:{message:`Sample error message`}}]});const W=new U({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:Ze,handler:({error:e,input:t,output:n,request:r,response:i,logger:a})=>{if(e){let n=z(e);Be(n,a,r,t),i.status(n.statusCode).set(n.headers).json({status:`error`,error:{message:B(n)}});return}i.status(H.positive).json({status:`success`,data:n})}}),Qe=r.string();n.add(Qe,{examples:[`Sample error message`]});const $e=new U({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=>O(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:Qe,mimeType:`text/plain`},handler:({response:e,output:t,error:n,logger:r,request:i,input:a})=>{if(n){let t=z(n);Be(t,r,i,a),e.status(t.statusCode).type(`text/plain`).send(B(t));return}if(`items`in t&&Array.isArray(t.items)){e.status(H.positive).json(t.items);return}throw Error(`Property 'items' is missing in the endpoint output`)}});var G=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=qe(this.schema,t.schema),n}addMiddleware(e){return this.#e(e instanceof V?e:new V(e))}use=this.addExpressMiddleware;addExpressMiddleware(...e){return this.#e(new We(...e))}addContext(e){return this.#e(new V({handler:e}))}build({input:e=le,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 Ke({...o,middlewares:s,outputSchema:t,resultHandler:c,scopes:d,tags:f,methods:l,getOperationId:u,inputSchema:Je(this.schema,e)})}buildVoid({handler:e,...t}){return this.build({...t,output:le,handler:async t=>(await e(t),{})})}};const et=new G(W),tt=new G($e),nt={debug:c,info:d,warn:f(`#FFA500`),error:m,ctx:l},K={debug:10,info:20,warn:30,error:40},rt=e=>O(e)&&Object.keys(K).some(t=>t in e),it=e=>e in K,at=(e,t)=>K[e]<K[t],q=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})),ot=e=>e<1e-6?q(`nanosecond`,3).format(e/1e-6):e<.001?q(`nanosecond`).format(e/1e-6):e<1?q(`microsecond`).format(e/.001):e<1e3?q(`millisecond`).format(e):e<6e4?q(`second`,2).format(e/1e3):q(`minute`,2).format(e/6e4);var st=class e{config;constructor({color:e=s.isSupported(),level:t=k()?`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 g(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`||at(e,r))return;let s=[new Date().toISOString()];i&&s.push(o?nt.ctx(i):i),s.push(o?`${nt[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=_.now();return()=>{let n=_.now()-t,{message:r,severity:i=`debug`,formatter:a=ot}=typeof e==`object`?e:{message:e};this.print(typeof i==`function`?i(n):i,r,a(n))}}},ct=class{#e;constructor(...e){this.#e=e}apply(e,t){return t(e,v.static(...this.#e))}};const J=async(e,t=`default`)=>{try{return(await import(e))[t]}catch{}throw new De(e)},lt=e=>e.type===`object`,ut=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}})}),dt=t.pipe(Object.keys,t.without([`type`,`properties`,`required`,`examples`,`description`,`additionalProperties`]),t.isEmpty),ft=t.pair(!0),Y=(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`&&dt(r)))throw Error(`Can not merge`);return t.pair(e,r)})),o.anyOf&&r.push(...t.map(ft,o.anyOf)),o.oneOf&&r.push(...t.map(ft,o.oneOf)),o.examples?.length&&(e?i.examples=t.concat(i.examples||[],o.examples):i.examples=E(i.examples?.filter(O)||[],o.examples.filter(O),([e,n])=>t.mergeDeepRight(e,n))),lt(o)&&(r.push([e,{examples:pt(o)}]),o.properties&&(i.properties=(n===`throw`?ut:t.mergeDeepRight)(i.properties,o.properties),!e&&o.required&&a.push(...o.required)),O(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},pt=e=>Object.entries(e.properties||{}).reduce((e,[n,r])=>{let{examples:i=[]}=O(r)?r:{};return E(e,i.map(t.objOf(n)),([e,t])=>({...e,...t}))},[]);var mt=class{#e=new WeakMap;constructor(e){this.logger=e}#t(e,t,n){if(!e.isSchemaChecked){for(let e of[`input`,`output`]){let i=[r.toJSONSchema(t[`${e}Schema`],{unrepresentable:`any`})];for(;i.length>0;){let t=i.shift();t.type&&t.type!==`object`&&this.logger.warn(`Endpoint ${e} schema is not object-based`,n);for(let e of[`allOf`,`oneOf`,`anyOf`])t[e]&&i.push(...t[e])}}if(t.requestType===`json`){let e=Re(t.inputSchema,`input`);e&&this.logger.warn(`The final input schema of the endpoint contains an unsupported JSON payload type.`,{...n,reason:e})}for(let e of Ye)for(let{mimeTypes:r,schema:i}of t.getResponses(e)){if(!r?.includes(x.json))continue;let t=Re(i,`output`);t&&this.logger.warn(`The final ${e} response schema of the endpoint contains an unsupported JSON payload type.`,{...n,reason:t})}e.isSchemaChecked=!0}}#n(e,t,n,i){if(e.paths.has(n))return;let a=de(n);if(a.length!==0){e.flat??=Y(r.toJSONSchema(t.inputSchema,{unrepresentable:`any`,io:`input`}));for(let t of a)t in e.flat.properties||this.logger.warn(`The input schema of the endpoint is most likely missing the parameter of the path it's assigned to.`,{...i,path:n,param:t});e.paths.add(n)}}check=(e,t,n)=>{let r=this.#e.get(n);r||(r={isSchemaChecked:!1,paths:new Set},this.#e.set(n,r)),this.#t(r,n,{method:e,path:t}),this.#n(r,n,t,{method:e})}};const ht=e=>(t,...n)=>{e(t,...n),t===`get`&&e(`head`,...n)},gt=e=>{let[t,n]=e.trim().split(/ (.+)/,2);return n&&S(t)?[n,t]:[e]},_t=e=>e.trim().split(`/`).filter(Boolean).join(`/`),vt=({methodLikeRouteBehavior:e=`method`},t,n)=>{let r=e===`method`;return Object.entries(t).map(([e,t])=>{let[i,a]=r&&S(e)&&t instanceof Ge?[`/`,e]:gt(e);return[[n||``].concat(_t(i)||[]).join(`/`),t,a]})},yt=(e,t)=>{throw new N(`Route with explicit method can only be assigned with Endpoint`,e,t)},bt=(e,t,n)=>{if(!(!n||n.includes(e)))throw new N(`Method ${e} is not supported by the assigned Endpoint.`,e,t)},xt=(e,t,n)=>{let r=`${e} ${t}`;if(n.has(r))throw new N(`Route has a duplicate`,e,t);n.add(r)},St=({routing:e,config:t,onEndpoint:n,onStatic:r})=>{let i=vt(t,e),a=new Set;for(;i.length;){let[e,o,s]=i.shift();if(o instanceof Ge)if(s)xt(s,e,a),bt(s,e,o.methods),n(s,e,o);else{let{methods:t=[`get`]}=o;for(let r of t)xt(r,e,a),n(r,e,o)}else s&&yt(s,e),o instanceof ct?r&&o.apply(e,r):i.unshift(...vt(t,o,e))}},Ct=e=>e.sort((e,t)=>S(t)-+S(e)||e.localeCompare(t)).join(`, `).toUpperCase(),wt=e=>({method:t},n,r)=>{let a=Ct(e);n.set({Allow:a}),r(i(405,`${t} is not allowed`,{headers:{Allow:a}}))},Tt=e=>({"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":Ct(e),"Access-Control-Allow-Headers":`content-type`}),Et=({app:e,getLogger:n,config:r,routing:i,parsers:a})=>{let o=k()?void 0:new mt(n()),s=new Map;return St({routing:i,config:r,onEndpoint:(e,n,i)=>{o?.check(e,n,i);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},Dt=({app:e,config:t,getLogger:n,...r})=>{let i=Et({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=Tt(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,wt(i))}for(let[t,n]of a)e.all(t,n)},Ot=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`,kt=e=>`server`in e&&typeof e.server==`object`&&e.server!==null&&`close`in e.server&&typeof e.server.close==`function`,At=e=>`encrypted`in e&&typeof e.encrypted==`boolean`&&e.encrypted,jt=({},e)=>void(!e.headersSent&&e.setHeader(`connection`,`close`)),Mt=e=>new Promise((t,n)=>void e.close(e=>e?n(e):t())),Nt=(e,{timeout:t=1e3,logger:n}={})=>{let r,i=new Set,a=e=>void i.delete(e.destroy()),o=e=>void(Ot(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`,jt);n?.info(`Graceful shutdown`,{sockets:i.size,timeout:t});for(let e of i)(At(e)||kt(e))&&o(e);for await(let e of y(10,Date.now()))if(i.size===0||Date.now()-e>=t)break;for(let e of i)a(e);return Promise.allSettled(e.map(Mt))};return{sockets:i,shutdown:()=>r??=c()}},Pt=Symbol.for(`express-zod-api`),Ft=({errorHandler:e,getLogger:t})=>async(n,r,i,a)=>n?e.execute({error:C(n),request:r,response:i,input:null,output:null,ctx:{},logger:t(r)}):a(),It=({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){He({response:r,logger:o,error:new Ee(C(e),a)})}},Lt=e=>(t,{},n)=>{if(Object.values(t?.files||[]).flat().find(({truncated:e})=>e))return n(e);n()},Rt=e=>({log:e.debug.bind(e)}),zt=async({getLogger:e,config:t})=>{let n=await J(`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:Rt(s)})(t,r,o)}),r&&o.push(Lt(r)),o},Bt=(e,{},t)=>{Buffer.isBuffer(e.body)&&(e.body={raw:e.body}),t()},Vt=({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[Pt]={logger:o}),a()},Ht=e=>t=>t?.res?.locals[Pt]?.logger||e,Ut=e=>process.on(`deprecation`,({message:t,namespace:n,name:r,stack:i})=>e.warn(`${r} (${n}): ${t}`,i.split(`
3
- `).slice(1))),Wt=({servers:e,logger:t,options:{timeout:n,beforeExit:r,events:i=[`SIGINT`,`SIGTERM`]}})=>{let a=Nt(e,{logger:t,timeout:n}),o=async()=>{await a.shutdown(),await r?.(),process.exit()};for(let e of i)process.on(e,o)},Gt=e=>{if(e.columns<132)return;let t=p(`Proudly supports transgender community.`.padStart(109)),n=p(`Start your API server with I/O schema validation and custom middlewares in minutes.`.padStart(109)),r=p(`Thank you for choosing Express Zod API for your project.`.padStart(132)),i=p(`for Nikki`.padEnd(20)),a=f(`#F5A9B8`),o=f(`#5BCEFA`),s=Array(14).fill(o,1,3).fill(a,3,5).fill(h,5,7).fill(a,7,9).fill(o,9,12).fill(u,12,13),c=`
1
+ import{globalRegistry as e,z as t}from"zod";import*as n from"ramda";import r,{isHttpError as i}from"http-errors";import{isPromise as a}from"node:util/types";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 h}from"node:util";import{performance as g}from"node:perf_hooks";import _ from"express";import ee from"node:http";import te from"node:https";import{setInterval as ne}from"node:timers/promises";import{OpenApiBuilder as re,isReferenceObject as ie,isSchemaObject as v}from"openapi3-ts/oas31";import{createRequest as ae,createResponse as oe}from"node-mocks-http";function se(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`},ce=[`get`,`post`,`put`,`delete`,`patch`],le=[...ce,`head`],b=e=>ce.includes(e),ue=t.object({}),de=/:([A-Za-z0-9_]+)/g,fe=e=>e.match(de)?.map(e=>e.slice(1))||[],pe=e=>{let t=(e.header(`content-type`)||``).toLowerCase().startsWith(y.upload);return`files`in e&&t},me={get:[`query`,`params`],post:[`body`,`params`,`files`],put:[`body`,`params`],patch:[`body`,`params`],delete:[`query`,`params`]},he=[`body`,`query`,`params`],ge=e=>e.method.toLowerCase(),_e=(e,t={})=>{if(e===`options`)return[];let n=e===`head`?`get`:b(e)?e:void 0;return(n?t[n]||me[n]:void 0)||he},ve=(e,t={})=>_e(ge(e),t).filter(t=>t===`files`?pe(e):!0).reduce((t,n)=>Object.assign(t,e[n]),{}),x=e=>e instanceof Error?e:e instanceof t.ZodError?new t.ZodRealError(e.issues):Error(String(e)),S=e=>e instanceof t.ZodError?e.issues.map(({path:e,message:n})=>`${e.length?`${t.core.toDotPath(e)}: `:``}${n}`).join(`; `):e.message,C=(e,t)=>E(e)&&`_zod`in e&&(t?n.path([`_zod`,`def`,`type`],e)===t:!0),w=(e,t,r)=>e.length&&t.length?n.xprod(e,t).map(r):e.concat(t),ye=e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase(),T=(...e)=>{let t=n.chain(e=>e.split(/[^A-Z0-9]/gi),e);return n.chain(e=>e.replaceAll(/[A-Z]+/g,e=>`/${e}`).split(`/`),t).map(ye).join(``)},be=n.tryCatch((e,n)=>typeof t.parse(e,n),n.always(void 0)),E=e=>typeof e==`object`&&!!e,xe=n.memoizeWith(()=>`static`,()=>process.env.NODE_ENV===`production`),Se=(e,t)=>!!t&&e!==`head`,D=`x-brand`,O=t=>{let{[D]:n}=e.get(t)||{};if(typeof n==`symbol`||typeof n==`string`||typeof n==`number`)return n},k=t=>{let{examples:n}=e.get(t)||{};return Array.isArray(n)?n:[]},A=Symbol(`Buffer`),Ce=()=>t.custom(e=>Buffer.isBuffer(e),{error:`Expected Buffer`}).meta({[D]:A}),j=Symbol(`DateIn`),we=({examples:e,...n}={})=>t.union([t.iso.date(),t.iso.datetime(),t.iso.datetime({local:!0})]).meta({examples:e}).transform(e=>new Date(e)).pipe(t.date()).meta({...n,[D]:j}),M=Symbol(`DateOut`),Te=(e={})=>t.date().transform(e=>e.toISOString()).meta({...e,[D]:M});var N=class extends Error{name=`RoutingError`;cause;constructor(e,t,n){super(e),this.cause={method:t,path:n}}},P=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.`}},Ee=class extends Error{name=`IOSchemaError`},De=class extends Ee{name=`DeepCheckError`;constructor(e){super(`Found`,{cause:e}),this.cause=e}},Oe=class extends Ee{name=`OutputValidationError`;constructor(e){let n=new t.ZodError(e.issues.map(({path:e,...t})=>({...t,path:[`output`,...e]})));super(S(n),{cause:e}),this.cause=e}},F=class extends Ee{name=`InputValidationError`;constructor(e){super(S(e),{cause:e}),this.cause=e}},ke=class extends Error{name=`ResultHandlerError`;constructor(e,t){super(S(e),{cause:e}),this.cause=e,this.handled=t}},Ae=class extends Error{name=`MissingPeerError`;constructor(e){super(`Missing peer dependency: ${e}. Please install it to use the feature.`)}};const je=Symbol(`Form`),Me=e=>(e instanceof t.ZodObject?e:t.object(e)).meta({[D]:je}),I=Symbol(`Upload`),Ne=()=>t.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}`})}).meta({[D]:I}),L=Symbol(`Raw`),Pe=t.object({raw:Ce()}),Fe=e=>Pe.extend(e).meta({[D]:L});function Ie(e){return e?Fe(e):Pe.meta({[D]:L})}const Le=(e,{io:r,condition:i})=>n.tryCatch(()=>void t.toJSONSchema(e,{io:r,unrepresentable:`any`,override:({zodSchema:e})=>{if(i(e))throw new De(e)}}),e=>e.cause)(),Re=(e,{io:r})=>{let i=[t.toJSONSchema(e,{io:r,unrepresentable:`any`})];for(;i.length;){let e=i.shift();if(n.is(Object,e)){if(e.$ref===`#`)return!0;i.push(...n.values(e))}n.is(Array,e)&&i.push(...n.values(e))}return!1},ze=e=>Le(e,{condition:e=>{let t=O(e);return typeof t==`symbol`&&[I,L,je].includes(t)},io:`input`}),Be=[`nan`,`symbol`,`map`,`set`,`bigint`,`void`,`promise`,`never`,`function`],Ve=(e,t)=>Le(e,{io:t,condition:e=>{let n=O(e),{type:r}=e._zod.def;return!!(Be.includes(r)||n===A||t===`input`&&(r===`date`||n===M)||t===`output`&&(n===j||n===L||n===I))}}),He=(e,{variant:n,args:r,...i})=>{if(typeof e==`function`&&(e=e(...r)),e instanceof t.ZodType)return[{schema:e,...i}];if(Array.isArray(e)&&!e.length)throw new ke(Error(`At least one ${n} 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}))},Ue=(e,t,{url:n},r)=>!e.expose&&t.error(`Server side error`,{error:e,url:n,payload:r}),R=e=>i(e)?e:r(e instanceof F?400:500,S(e),{cause:e.cause||e}),z=e=>xe()&&!e.expose?r(e.statusCode).message:e.message,We=e=>Object.entries(e._zod.def.shape).reduce((e,[t,r])=>w(e,k(r).map(n.objOf(t)),([e,t])=>({...e,...t})),[]),Ge=({error:e,logger:t,response:n})=>{t.error(`Result handler failure`,e);let a=z(r(500,`An error occurred while serving the result: ${e.message}.`+(e.handled?`\nOriginal error: ${e.handled.message}.`:``),{expose:i(e.cause)?e.cause.expose:!1}));n.status(500).type(`text/plain`).end(a)};var Ke=class{},B=class extends Ke{#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,...n}){try{let t=await(this.#e||ue).parseAsync(e);return this.#n({...n,input:t})}catch(e){throw e instanceof t.ZodError?new F(e):e}}},qe=class extends B{constructor(e,{provider:t=()=>({}),transformer:n=e=>e}={}){super({handler:async({request:r,response:i})=>{let{promise:o,resolve:s,reject:c}=Promise.withResolvers(),l=e=>{if(e&&e instanceof Error)return c(n(e));s(t(r,i))},u=e(r,i,l);return a(u)&&u.catch(l),o}})}},Je=class{nest(e){return{...e,"":this}}},Ye=class r extends Je{#e;#t=n.once(()=>{if(k(this.#e.outputSchema).length||!C(this.#e.outputSchema,`object`))return;let t=We(this.#e.outputSchema);if(!t.length)return;let n=this.#e.outputSchema.meta();e.remove(this.#e.outputSchema).add(this.#e.outputSchema,{...n,examples:t})});constructor(e){super(),this.#e=e}#n(e){return new r({...this.#e,...e})}deprecated(){return this.#n({deprecated:!0})}get isDeprecated(){return this.#e.deprecated||!1}get description(){return this.#e.description}get summary(){return this.#e.summary}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 e=ze(this.#e.inputSchema);if(e){let t=O(e);if(t===I)return`upload`;if(t===L)return`raw`;if(t===je)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=n.pluck(`security`,this.#e.middlewares||[]);return n.reject(n.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 t.ZodError?new Oe(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 qe))&&(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,...n}){let r;try{r=await this.#e.inputSchema.parseAsync(e)}catch(e){throw e instanceof t.ZodError?new F(e):e}return this.#e.handler({...n,input:r})}async#o(e){try{await this.#e.resultHandler.execute(e)}catch(t){Ge({...e,error:new ke(x(t),e.error||void 0)})}}async execute({request:e,response:t,logger:n,config:r}){let i=ge(e),a={},o,s=ve(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 Xe=(e,t)=>e&&t?e.and(t):e||t,Ze=(e,t)=>e?e.and(t):t,V={positive:200,negative:400},Qe=Object.keys(V);var $e=class{#e;constructor(e){this.#e=e}execute(...e){return this.#e(...e)}},H=class extends $e{#e;#t;constructor(e){super(e.handler),this.#e=e.positive,this.#t=e.negative}getPositiveResponse(e){return He(this.#e,{variant:`positive`,args:[e],statusCodes:[V.positive],mimeTypes:[y.json]})}getNegativeResponse(){return He(this.#t,{variant:`negative`,args:[],statusCodes:[V.negative],mimeTypes:[y.json]})}};const et=t.object({status:t.literal(`error`),error:t.object({message:t.string()})});e.add(et,{examples:[{status:`error`,error:{message:`Sample error message`}}]});const U=new H({positive:n=>{let r=t.object({status:t.literal(`success`),data:n}),i=k(n);return i.length&&e.add(r,{examples:i.map(e=>({status:`success`,data:e}))}),r},negative:et,handler:({error:e,input:t,output:n,request:r,response:i,logger:a})=>{if(e){let n=R(e);Ue(n,a,r,t),i.status(n.statusCode).set(n.headers).json({status:`error`,error:{message:z(n)}});return}i.status(V.positive).json({status:`success`,data:n})}}),tt=t.string();e.add(tt,{examples:[`Sample error message`]});const nt=new H({positive:n=>{let r=n instanceof t.ZodObject&&`items`in n.shape&&n.shape.items instanceof t.ZodArray?n.shape.items:t.array(t.any());if(k(r).length)return r;let i=k(n).filter(e=>E(e)&&`items`in e&&Array.isArray(e.items)).map(e=>e.items);if(i?.length){let t=r.meta();e.remove(r).add(r,{...t,examples:i})}return r},negative:{schema:tt,mimeType:`text/plain`},handler:({response:e,output:t,error:n,logger:r,request:i,input:a})=>{if(n){let t=R(n);Ue(t,r,i,a),e.status(t.statusCode).type(`text/plain`).send(z(t));return}if(`items`in t&&Array.isArray(t.items)){e.status(V.positive).json(t.items);return}throw Error(`Property 'items' is missing in the endpoint output`)}});var W=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=Xe(this.schema,t.schema),n}addMiddleware(e){return this.#e(e instanceof B?e:new B(e))}use=this.addExpressMiddleware;addExpressMiddleware(...e){return this.#e(new qe(...e))}addContext(e){return this.#e(new B({handler:e}))}build({input:e=ue,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 Ye({...o,middlewares:s,outputSchema:t,resultHandler:c,scopes:d,tags:f,methods:l,getOperationId:u,inputSchema:Ze(this.schema,e)})}buildVoid({handler:e,...t}){return this.build({...t,output:ue,handler:async t=>(await e(t),{})})}};const rt=new W(U),it=new W(nt),at={debug:s,info:u,warn:d(`#FFA500`),error:p,ctx:c},G={debug:10,info:20,warn:30,error:40},ot=e=>E(e)&&Object.keys(G).some(t=>t in e),st=e=>e in G,ct=(e,t)=>G[e]<G[t],K=n.memoizeWith((e,t)=>`${e}${t}`,(e,t=0)=>Intl.NumberFormat(void 0,{useGrouping:!1,minimumFractionDigits:0,maximumFractionDigits:t,style:`unit`,unitDisplay:`long`,unit:e})),lt=e=>e<1e-6?K(`nanosecond`,3).format(e/1e-6):e<.001?K(`nanosecond`).format(e/1e-6):e<1?K(`microsecond`).format(e/.001):e<1e3?K(`millisecond`).format(e):e<6e4?K(`second`,2).format(e/1e3):K(`minute`,2).format(e/6e4);var ut=class e{config;constructor({color:e=o.isSupported(),level:t=xe()?`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 h(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`||ct(e,r))return;let s=[new Date().toISOString()];i&&s.push(o?at.ctx(i):i),s.push(o?`${at[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=g.now();return()=>{let n=g.now()-t,{message:r,severity:i=`debug`,formatter:a=lt}=typeof e==`object`?e:{message:e};this.print(typeof i==`function`?i(n):i,r,a(n))}}},dt=class{#e;constructor(...e){this.#e=e}apply(e,t){return t(e,_.static(...this.#e))}};const q=async(e,t=`default`)=>{try{return(await import(e))[t]}catch{}throw new Ae(e)},ft=e=>e.type===`object`,pt=n.mergeDeepWith((e,t)=>{if(Array.isArray(e)&&Array.isArray(t))return n.concat(e,t);if(e===t)return t;throw Error(`Can not flatten properties`,{cause:{a:e,b:t}})}),mt=n.pipe(Object.keys,n.without([`type`,`properties`,`required`,`examples`,`description`,`additionalProperties`]),n.isEmpty),ht=n.pair(!0),J=(e,t=`coerce`)=>{let r=[n.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(t===`throw`&&!(r.type===`object`&&mt(r)))throw Error(`Can not merge`);return n.pair(e,r)})),o.anyOf&&r.push(...n.map(ht,o.anyOf)),o.oneOf&&r.push(...n.map(ht,o.oneOf)),o.examples?.length&&(e?i.examples=n.concat(i.examples||[],o.examples):i.examples=w(i.examples?.filter(E)||[],o.examples.filter(E),([e,t])=>n.mergeDeepRight(e,t))),ft(o)&&(r.push([e,{examples:gt(o)}]),o.properties&&(i.properties=(t===`throw`?pt:n.mergeDeepRight)(i.properties,o.properties),!e&&o.required&&a.push(...o.required)),E(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},gt=e=>Object.entries(e.properties||{}).reduce((e,[t,r])=>{let{examples:i=[]}=E(r)?r:{};return w(e,i.map(n.objOf(t)),([e,t])=>({...e,...t}))},[]);var _t=class{#e=new WeakMap;constructor(e){this.logger=e}#t(e,n,r){if(!e.isSchemaChecked){for(let e of[`input`,`output`]){let i=[t.toJSONSchema(n[`${e}Schema`],{unrepresentable:`any`})];for(;i.length>0;){let t=i.shift();t.type&&t.type!==`object`&&this.logger.warn(`Endpoint ${e} schema is not object-based`,r);for(let e of[`allOf`,`oneOf`,`anyOf`])t[e]&&i.push(...t[e])}}if(n.requestType===`json`){let e=Ve(n.inputSchema,`input`);e&&this.logger.warn(`The final input schema of the endpoint contains an unsupported JSON payload type.`,{...r,reason:e})}for(let e of Qe)for(let{mimeTypes:t,schema:i}of n.getResponses(e)){if(!t?.includes(y.json))continue;let n=Ve(i,`output`);n&&this.logger.warn(`The final ${e} response schema of the endpoint contains an unsupported JSON payload type.`,{...r,reason:n})}e.isSchemaChecked=!0}}#n(e,n,r,i){if(e.paths.has(r))return;let a=fe(r);if(a.length!==0){e.flat??=J(t.toJSONSchema(n.inputSchema,{unrepresentable:`any`,io:`input`}));for(let t of a)t in e.flat.properties||this.logger.warn(`The input schema of the endpoint is most likely missing the parameter of the path it's assigned to.`,{...i,path:r,param:t});e.paths.add(r)}}check=(e,t,n)=>{let r=this.#e.get(n);r||(r={isSchemaChecked:!1,paths:new Set},this.#e.set(n,r)),this.#t(r,n,{method:e,path:t}),this.#n(r,n,t,{method:e})}};const vt=e=>(t,...n)=>{e(t,...n),t===`get`&&e(`head`,...n)},yt=e=>{let[t,n]=e.trim().split(/ (.+)/,2);return n&&b(t)?[n,t]:[e]},bt=e=>e.trim().split(`/`).filter(Boolean).join(`/`),xt=({recognizeMethodDependentRoutes:e=!0},t,n)=>Object.entries(t).map(([t,r])=>{let[i,a]=e&&b(t)&&r instanceof Je?[`/`,t]:yt(t);return[[n||``].concat(bt(i)||[]).join(`/`),r,a]}),St=(e,t)=>{throw new N(`Route with explicit method can only be assigned with Endpoint`,e,t)},Ct=(e,t,n)=>{if(!(!n||n.includes(e)))throw new N(`Method ${e} is not supported by the assigned Endpoint.`,e,t)},wt=(e,t,n)=>{let r=`${e} ${t}`;if(n.has(r))throw new N(`Route has a duplicate`,e,t);n.add(r)},Tt=({routing:e,config:t,onEndpoint:n,onStatic:r})=>{let i=xt(t,e),a=new Set;for(;i.length;){let[e,o,s]=i.shift();if(o instanceof Je)if(s)wt(s,e,a),Ct(s,e,o.methods),n(s,e,o);else{let{methods:t=[`get`]}=o;for(let r of t)wt(r,e,a),n(r,e,o)}else s&&St(s,e),o instanceof dt?r&&o.apply(e,r):i.unshift(...xt(t,o,e))}},Et=e=>e.sort((e,t)=>b(t)-+b(e)||e.localeCompare(t)).join(`, `).toUpperCase(),Dt=e=>({method:t},n,i)=>{let a=Et(e);n.set({Allow:a}),i(r(405,`${t} is not allowed`,{headers:{Allow:a}}))},Ot=e=>({"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":Et(e),"Access-Control-Allow-Headers":`content-type`}),kt=({app:e,getLogger:t,config:r,routing:i,parsers:a})=>{let o=xe()?void 0:new _t(t()),s=new Map;return Tt({routing:i,config:r,onEndpoint:(e,t,i)=>{o?.check(e,t,i);let c=a?.[i.requestType]||[],l=n.pair(c,i);s.has(t)||s.set(t,new Map(r.cors?[[`options`,l]]:[])),s.get(t)?.set(e,l)},onStatic:e.use.bind(e)}),s},At=({app:e,config:t,getLogger:n,...r})=>{let i=kt({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=Ot(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.hintAllowedMethods!==!1&&a.set(r,Dt(i))}for(let[t,n]of a)e.all(t,n)},jt=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`,Mt=e=>`server`in e&&typeof e.server==`object`&&e.server!==null&&`close`in e.server&&typeof e.server.close==`function`,Nt=e=>`encrypted`in e&&typeof e.encrypted==`boolean`&&e.encrypted,Pt=({},e)=>void(!e.headersSent&&e.setHeader(`connection`,`close`)),Ft=e=>{let{promise:t,resolve:n,reject:r}=Promise.withResolvers();return e.close(e=>e?r(e):n()),t},It=(e,{timeout:t=1e3,logger:n}={})=>{let r,i=new Set,a=e=>void i.delete(e.destroy()),o=e=>void(jt(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`,Pt);n?.info(`Graceful shutdown`,{sockets:i.size,timeout:t});for(let e of i)(Nt(e)||Mt(e))&&o(e);for await(let e of ne(10,Date.now()))if(i.size===0||Date.now()-e>=t)break;for(let e of i)a(e);return Promise.allSettled(e.map(Ft))};return{sockets:i,shutdown:()=>r??=c()}},Lt=Symbol.for(`express-zod-api`),Rt=({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(),zt=({errorHandler:e,getLogger:t})=>async(n,i)=>{let a=r(404,`Can not ${n.method} ${n.path}`),o=t(n);try{await e.execute({request:n,response:i,logger:o,error:a,input:null,output:null,ctx:{}})}catch(e){Ge({response:i,logger:o,error:new ke(x(e),a)})}},Bt=e=>(t,{},n)=>{if(Object.values(t?.files||[]).flat().find(({truncated:e})=>e))return n(e);n()},Vt=e=>({log:e.debug.bind(e)}),Ht=async({getLogger:e,config:t})=>{let n=await q(`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:Vt(s)})(t,r,o)}),r&&o.push(Bt(r)),o},Ut=(e,{},t)=>{Buffer.isBuffer(e.body)&&(e.body={raw:e.body}),t()},Wt=({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[Lt]={logger:o}),a()},Gt=e=>t=>t?.res?.locals[Lt]?.logger||e,Kt=e=>process.on(`deprecation`,({message:t,namespace:n,name:r,stack:i})=>e.warn(`${r} (${n}): ${t}`,i.split(`
2
+ `).slice(1))),qt=({servers:e,logger:t,options:{timeout:n,beforeExit:r,events:i=[`SIGINT`,`SIGTERM`]}})=>{let a=It(e,{logger:t,timeout:n}),o=async()=>{await a.shutdown(),await r?.(),process.exit()};for(let e of i)process.on(e,o)},Jt=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 Koko`.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=`
4
3
  8888888888 8888888888P 888 d8888 8888888b. 8888888
5
4
  888 d88P 888 d88888 888 Y88b 888
6
5
  888 d88P 888 d88P888 888 888 888
@@ -15,8 +14,8 @@ ${i}888${n}
15
14
  ${r}
16
15
  `;e.write(c.split(`
17
16
  `).map((e,t)=>s[t]?s[t](e):e).join(`
18
- `))},Kt=e=>{e.startupLogo!==!1&&Gt(process.stdout);let t=e.errorHandler||W,n=rt(e.logger)?e.logger:new st(e.logger);n.debug(`Running`,{build:`v27.2.2`,env:process.env.NODE_ENV||`development`}),Ut(n);let r=Vt({logger:n,config:e}),i={getLogger:Ht(n),errorHandler:t},a=It(i),o=Ft(i);return{...i,logger:n,notFoundHandler:a,catcher:o,loggingMiddleware:r}},qt=(e,t)=>{let{logger:n,getLogger:r,notFoundHandler:i,loggingMiddleware:a}=Kt(e);return Dt({app:e.app.use(a),routing:t,getLogger:r,config:e}),{notFoundHandler:i,logger:n}},Jt=async(e,t)=>{let{logger:n,getLogger:r,notFoundHandler:i,catcher:a,loggingMiddleware:o}=Kt(e),s=v().disable(`x-powered-by`).set(`query parser`,e.queryParser??`simple`).use(o);if(e.compression){let t=await J(`compression`);s.use(t(typeof e.compression==`object`?e.compression:void 0))}await e.beforeRouting?.({app:s,getLogger:r}),Dt({app:s,routing:t,getLogger:r,config:e,parsers:{json:[e.jsonParser||v.json()],raw:[e.rawParser||v.raw(),Bt],form:[e.formParser||v.urlencoded()],upload:e.upload?await zt({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=ee.createServer(s);c.push(t),u.push(l(t,e.http.listen))}if(e.https){let t=te.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&&Wt({logger:n,servers:c,options:e.gracefulShutdown===!0?{}:e.gracefulShutdown}),{app:s,logger:n,servers:u.map(e=>e())}},Yt=e=>O(e)&&`or`in e,Xt=e=>O(e)&&`and`in e,Zt=e=>!Xt(e)&&!Yt(e),Qt=e=>{let n=t.filter(Zt,e),r=t.chain(t.prop(`and`),t.filter(Xt,e)),[i,a]=t.partition(Zt,r),o=t.concat(n,i),s=t.filter(Yt,e);return t.map(t.prop(`or`),t.concat(s,a)).reduce((e,n)=>E(e,t.map(e=>Zt(e)?[e]:e.and,n),([e,n])=>t.concat(e,n)),t.reject(t.isEmpty,[o]))};var $t=`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.incremental.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 en=`https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString`,tn={integer:0,number:0,string:``,boolean:!1,object:{},null:null,array:[]},nn=e=>e.replace(ue,e=>`{${e.slice(1)}}`),rn=({},e)=>{if(e.isResponse)throw new P(`Please use ez.upload() only for input.`,e);return{type:`string`,format:`binary`}},an=({jsonSchema:e})=>({...e,externalDocs:{description:`raw binary data`,url:`https://swagger.io/specification/#working-with-binary-data`}}),on=({zodSchema:e,jsonSchema:t})=>{if(!T(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 Y(e,`throw`)},(e,{jsonSchema:t})=>t),cn=({jsonSchema:e})=>{if(!e.anyOf)return e;let t=e.anyOf[0];return Object.assign(t,{type:mn(t.type)})},X=e=>e,ln=({jsonSchema:{examples:e,description:t}},n)=>{if(n.isResponse)throw new P(`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:en}};return e?.length&&(r.examples=e),r},un=({jsonSchema:{examples:e,description:t}},n)=>{if(!n.isResponse)throw new P(`Please use ez.dateIn() for input.`,n);let r={description:t||`YYYY-MM-DDTHH:mm:ss.sssZ`,type:`string`,format:`date-time`,externalDocs:{url:en}};return e?.length&&(r.examples=e),r},dn=()=>({type:`string`,format:`bigint`,pattern:`^-?\\d+$`}),fn=({zodSchema:e,jsonSchema:t})=>e._zod.def.rest===null?{...t,items:{not:{}}}:t,pn=e=>{let t=Array.isArray(e.type)?e.type[0]:e.type;return tn?.[t]},mn=e=>e===`null`?e:typeof e==`string`?[e,`null`]:e&&[...new Set(e).add(`null`)],hn=({zodSchema:e,jsonSchema:t},n)=>{let r=e._zod.def[n.isResponse?`out`:`in`],i=e._zod.def[n.isResponse?`in`:`out`];if(!T(r,`transform`))return t;let a=X(Sn(i,{ctx:n}));if(b(a))if(n.isResponse){let e=ye(r,pn(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},gn=({jsonSchema:e})=>{if(e.type!==`object`)return e;let t=e;return!t.properties||!(`raw`in t.properties)||!O(t.properties.raw)?e:t.properties.raw},_n=e=>e.length?t.fromPairs(t.zip(t.times(e=>`example${e+1}`,e.length),t.map(t.objOf(`value`),e))):void 0,vn=(e,t)=>t?.includes(e)||e.startsWith(`x-`)||$t.includes(e),yn=({path:e,method:n,request:r,inputSources:i,makeRef:a,composition:o,isHeader:s,security:c,description:l=`${n.toUpperCase()} ${e} Parameter`})=>{let u=Y(r),d=de(e),f=i.includes(`query`),p=i.includes(`params`),m=i.includes(`headers`),h=e=>p&&d.includes(e),g=t.chain(t.filter(e=>e.type===`header`),c??[]).map(({name:e})=>e),_=t=>m&&(s?.(t,n,e)??vn(t,g));return Object.entries(u.properties).reduce((e,[n,r])=>{if(!O(r))return e;let i=h(n)?`path`:_(n)?`header`:f?`query`:void 0;if(!i)return e;let s=X(r),c=o===`components`?a(r.id||JSON.stringify(r),s,r.id||D(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:_n(b(s)&&s.examples?.length?s.examples:t.pluck(n,u.examples?.filter(t.both(O,t.has(n)))||[]))})},[])},bn={nullable:cn,union:on,bigint:dn,intersection:sn,tuple:fn,pipe:hn,[j]:ln,[M]:un,[L]:rn,[R]:gn,[A]:an},xn=(e,n,r)=>{let i=[e,n];for(;i.length;){let e=i.shift();if(t.is(Object,e)){if(re(e)&&!e.$ref.startsWith(`#/components`)){let t=n[e.$ref.split(`/`).pop()];t&&(e.$ref=r.makeRef(t.id||t,X(t),t.id).$ref);continue}i.push(...t.values(e))}t.is(Array,e)&&i.push(...t.values(e))}return e},Sn=(t,{ctx:n,rules:i=bn})=>{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 xn(O(o.subject)?o.subject:{},a,n)},Cn=(e,n)=>{if(re(e))return[e,!1];let r=!1,i=t.map(e=>{let[t,i]=Cn(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]},wn=({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} ${ve(a)} response ${c?l:``}`.trim()})=>{if(!be(e,i))return{description:d};let f=X(Sn(r,{rules:{...u,...bn},ctx:{isResponse:!0,makeRef:o,path:n,method:e}})),p=[];b(f)&&f.examples&&(p.push(...f.examples),delete f.examples);let m={schema:s===`components`?o(r,f,D(d)):f,examples:_n(p)};return{description:d,content:t.fromPairs(t.xprod(i,[m]))}},Tn=({format:e})=>{let t={type:`http`,scheme:`bearer`};return e&&(t.bearerFormat=e),t},En=({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},Dn=({name:e})=>({type:`apiKey`,in:`header`,name:e}),On=({name:e})=>({type:`apiKey`,in:`cookie`,name:e}),kn=({url:e})=>({type:`openIdConnect`,openIdConnectUrl:e}),An=({flows:e={}})=>({type:`oauth2`,flows:t.map(e=>({...e,scopes:e.scopes||{}}),t.reject(t.isNil,e))}),jn=(e,t=[])=>{let n=e=>e.type===`basic`?{type:`http`,scheme:`basic`}:e.type===`bearer`?Tn(e):e.type===`input`?En(e,t):e.type===`header`?Dn(e):e.type===`cookie`?On(e):e.type===`openid`?kn(e):An(e);return e.map(e=>e.map(n))},Mn=(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:[]})},{})),Nn=({schema:e,brandHandling:t,makeRef:n,path:r,method:i})=>Sn(e,{rules:{...t,...bn},ctx:{isResponse:!1,makeRef:n,path:r,method:i}}),Pn=({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]=Cn(X(i),c),f=[];b(u)&&u.examples&&(f.push(...u.examples),delete u.examples);let p={schema:s===`components`?o(r,u,D(l)):u,examples:_n(f.length?f:Y(i).examples?.filter(e=>O(e)&&!Array.isArray(e)).map(t.omit(c))||[])},m={description:l,content:{[a]:p}};return(d||a===x.raw)&&(m.required=!0),m},Fn=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)},[]),In=e=>e.length<=50?e:e.slice(0,49)+`…`,Ln=e=>e.length?e.slice():void 0;var Rn=class extends ne{#e=new Map;#t=new Map;#n=new Map;#r(e,t,n){let r=this.#n.get(e);if(!r){let t=n?0:1;do r=`${n??`Schema`}${t?this.#n.size+t:``}`,t++;while(this.rootDoc.components?.schemas?.[r]);this.#n.set(e,r)}return this.addSchema(r,t),{$ref:`#/components/schemas/${r}`}}#i(e,t,n){let r=n||D(t,e),i=this.#t.get(r);if(i===void 0)return this.#t.set(r,1),r;if(n)throw new P(`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,h=d?In(d):u&&c?In(c):void 0,g=ge(e,n.inputSources),_=this.#i(r,e,i.getOperationId(e)),v=Nn({...a,schema:m}),ee=Qt(i.security),te=yn({...a,inputSources:g,isHeader:l,security:ee,request:v,description:o?.requestParameter?.call(null,{method:e,path:r,operationId:_})}),y={};for(let t of Ye){let n=i.getResponses(t);for(let{mimeTypes:i,schema:s,statusCodes:c}of n)for(let l of c)y[l]=wn({...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:_,statusCode:l})})}let ne=g.includes(`body`)?Pn({...a,request:v,paramNames:t.pluck(`name`,te),schema:m,mimeType:x[i.requestType],description:o?.requestBody?.call(null,{method:e,path:r,operationId:_})}):void 0,re=Mn(jn(ee,g),p,e=>{let t=this.#a(e);return this.addSecurityScheme(t,e),t}),b={operationId:_,summary:h,description:c,deprecated:i.isDeprecated||void 0,tags:Ln(i.tags),parameters:Ln(te),requestBody:ne,security:Ln(re),responses:y};this.addPath(nn(r),{[e]:b})};St({routing:e,config:n,onEndpoint:d?ht(p):p}),c&&(this.rootDoc.tags=Fn(c))}};const zn=e=>ie({...e,headers:{"content-type":x.json,...e?.headers}}),Bn=e=>ae(e),Vn=e=>{let t={warn:[],error:[],info:[],debug:[]};return new Proxy(e||{},{get(e,n,r){return n===`_getLogs`?()=>t:it(n)?(...e)=>t[n].push(e):Reflect.get(e,n,r)}})},Hn=({requestProps:e,responseOptions:t,configProps:n,loggerProps:r})=>{let i=zn(e),a=Bn({req:i,...t});a.req=t?.req||i,i.res=a;let o=Vn(r);return{requestMock:i,responseMock:a,loggerMock:o,configMock:{cors:!1,logger:o,...n}}},Un=async({endpoint:e,...t})=>{let{requestMock:n,responseMock:r,loggerMock:i,configMock:a}=Hn(t);return await e.execute({request:n,response:r,config:a,logger:i}),{requestMock:n,responseMock:r,loggerMock:i}},Wn=async({middleware:e,ctx:t={},...n})=>{let{requestMock:r,responseMock:i,loggerMock:a,configMock:{inputSources:o,errorHandler:s=W}}=Hn(n),c={request:r,response:i,logger:a,input:_e(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:C(e),output:null}),{requestMock:r,responseMock:i,loggerMock:a,output:{}}}};var Gn=class e{ts;f;exportModifier;asyncModifier;accessModifiers;#e;static#t=/^[A-Za-z_$][A-Za-z0-9_$]*$/;constructor(e){this.ts=e,this.f=this.ts.factory,this.exportModifier=[this.f.createModifier(this.ts.SyntaxKind.ExportKeyword)],this.asyncModifier=[this.f.createModifier(this.ts.SyntaxKind.AsyncKeyword)],this.accessModifiers={public:[this.f.createModifier(this.ts.SyntaxKind.PublicKeyword)],publicStatic:[this.f.createModifier(this.ts.SyntaxKind.PublicKeyword),this.f.createModifier(this.ts.SyntaxKind.StaticKeyword)],protectedReadonly:[this.f.createModifier(this.ts.SyntaxKind.ProtectedKeyword),this.f.createModifier(this.ts.SyntaxKind.ReadonlyKeyword)]},this.#e=[this.ts.SyntaxKind.AnyKeyword,this.ts.SyntaxKind.BigIntKeyword,this.ts.SyntaxKind.BooleanKeyword,this.ts.SyntaxKind.NeverKeyword,this.ts.SyntaxKind.NumberKeyword,this.ts.SyntaxKind.ObjectKeyword,this.ts.SyntaxKind.StringKeyword,this.ts.SyntaxKind.SymbolKeyword,this.ts.SyntaxKind.UndefinedKeyword,this.ts.SyntaxKind.UnknownKeyword,this.ts.SyntaxKind.VoidKeyword]}addJsDoc=(e,t)=>this.ts.addSyntheticLeadingComment(e,this.ts.SyntaxKind.MultiLineCommentTrivia,`* ${t} `,!0);printNode=(e,t)=>{let n=this.ts.createSourceFile(`print.ts`,``,this.ts.ScriptTarget.Latest,!1,this.ts.ScriptKind.TS);return this.ts.createPrinter(t).printNode(this.ts.EmitHint.Unspecified,e,n)};makeId=e=>this.f.createIdentifier(e);makePropertyIdentifier=t=>typeof t==`string`&&e.#t.test(t)?this.makeId(t):this.literally(t);makeTemplate=(e,...t)=>this.f.createTemplateExpression(this.f.createTemplateHead(e),t.map(([e,n=``],r)=>this.f.createTemplateSpan(typeof e==`string`?this.makeId(e):e,r===t.length-1?this.f.createTemplateTail(n):this.f.createTemplateMiddle(n))));makeParam=(e,{type:t,mod:n,initId:r,optional:i}={})=>this.f.createParameterDeclaration(n,void 0,e,i?this.f.createToken(this.ts.SyntaxKind.QuestionToken):void 0,t?this.ensureTypeNode(t):void 0,r?this.makeId(r):void 0);makeParams=e=>Object.entries(e).map(([e,t])=>this.makeParam(e,typeof t==`string`||typeof t==`number`||typeof t==`object`&&`kind`in t?{type:t}:t));makePublicConstructor=(e,t=[])=>this.f.createConstructorDeclaration(this.accessModifiers.public,e,this.f.createBlock(t));ensureTypeNode=(e,n)=>typeof e==`number`?this.f.createKeywordTypeNode(e):typeof e==`string`||this.ts.isIdentifier(e)?this.f.createTypeReferenceNode(e,n&&t.map(this.ensureTypeNode,n)):e;makeRecordStringAny=()=>this.ensureTypeNode(`Record`,[this.ts.SyntaxKind.StringKeyword,this.ts.SyntaxKind.AnyKeyword]);makeUnion=e=>{let t=new Map;for(let n of e)t.set(this.isPrimitive(n)?n.kind:n,n);return this.f.createUnionTypeNode(Array.from(t.values()))};makeInterfaceProp=(e,n,{isOptional:r,hasUndefined:i=r,isDeprecated:a,comment:o}={})=>{let s=this.ensureTypeNode(n),c=this.f.createPropertySignature(void 0,this.makePropertyIdentifier(e),r?this.f.createToken(this.ts.SyntaxKind.QuestionToken):void 0,i?this.makeUnion([s,this.ensureTypeNode(this.ts.SyntaxKind.UndefinedKeyword)]):s),l=t.reject(t.isNil,[a?`@deprecated`:void 0,o]);return l.length?this.addJsDoc(c,l.join(` `)):c};makeOneLine=e=>this.ts.setEmitFlags(e,this.ts.EmitFlags.SingleLine);makeDeconstruction=(...e)=>this.f.createArrayBindingPattern(e.map(e=>this.f.createBindingElement(void 0,void 0,e)));makeConst=(e,t,{type:n,expose:r}={})=>this.f.createVariableStatement(r&&this.exportModifier,this.f.createVariableDeclarationList([this.f.createVariableDeclaration(e,void 0,n?this.ensureTypeNode(n):void 0,t)],this.ts.NodeFlags.Const));makePublicLiteralType=(e,n)=>this.makeType(e,this.makeUnion(t.map(this.makeLiteralType,n)),{expose:!0});makeType=(e,t,{expose:n,comment:r,params:i}={})=>{let a=this.f.createTypeAliasDeclaration(n?this.exportModifier:void 0,e,i&&this.makeTypeParams(i),t);return r?this.addJsDoc(a,r):a};makePublicProperty=(e,t)=>this.f.createPropertyDeclaration(this.accessModifiers.public,e,void 0,this.ensureTypeNode(t),void 0);makePublicMethod=(e,t,n,{typeParams:r,returns:i,isStatic:a}={})=>this.f.createMethodDeclaration(a?this.accessModifiers.publicStatic:this.accessModifiers.public,void 0,e,void 0,r&&this.makeTypeParams(r),t,i,this.f.createBlock(n));makePublicClass=(e,t,{typeParams:n}={})=>this.f.createClassDeclaration(this.exportModifier,e,n&&this.makeTypeParams(n),void 0,t);makeKeyOf=e=>this.f.createTypeOperatorNode(this.ts.SyntaxKind.KeyOfKeyword,this.ensureTypeNode(e));makePromise=e=>this.ensureTypeNode(Promise.name,[e]);makeInterface=(e,t,{expose:n,comment:r}={})=>{let i=this.f.createInterfaceDeclaration(n?this.exportModifier:void 0,e,void 0,void 0,t);return r?this.addJsDoc(i,r):i};makeTypeParams=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 this.f.createTypeParameterDeclaration([],e,n?this.ensureTypeNode(n):void 0,r?this.ensureTypeNode(r):void 0)});makeArrowFn=(e,n,{isAsync:r}={})=>this.f.createArrowFunction(r?this.asyncModifier:void 0,void 0,Array.isArray(e)?t.map(this.makeParam,e):this.makeParams(e),void 0,void 0,n);makeTernary=(...e)=>{let[t,n,r]=e.map(e=>typeof e==`string`?this.makeId(e):e);return this.f.createConditionalExpression(t,this.f.createToken(this.ts.SyntaxKind.QuestionToken),n,this.f.createToken(this.ts.SyntaxKind.ColonToken),r)};makeCall=(e,...t)=>(...n)=>this.f.createCallExpression(t.reduce((e,t)=>typeof t==`string`||this.ts.isIdentifier(t)?this.f.createPropertyAccessExpression(e,t):this.f.createElementAccessExpression(e,t),typeof e==`string`?this.makeId(e):e),void 0,n.map(e=>typeof e==`string`?this.makeId(e):e));makeNew=(e,...t)=>this.f.createNewExpression(this.makeId(e),void 0,t);makeExtract=(e,t)=>this.ensureTypeNode(`Extract`,[e,t]);makeAssignment=(e,t)=>this.f.createExpressionStatement(this.f.createBinaryExpression(typeof e==`string`?this.makeId(e):e,this.f.createToken(this.ts.SyntaxKind.EqualsToken),t));makeIndexed=(e,t)=>this.f.createIndexedAccessTypeNode(this.ensureTypeNode(e),this.ensureTypeNode(t));makeMaybeAsync=e=>this.makeUnion([this.ensureTypeNode(e),this.makePromise(e)]);makeFnType=(e,t)=>this.f.createFunctionTypeNode(void 0,this.makeParams(e),this.ensureTypeNode(t));literally=e=>typeof e==`number`?this.f.createNumericLiteral(e):typeof e==`bigint`?this.f.createBigIntLiteral(e.toString()):typeof e==`boolean`?e?this.f.createTrue():this.f.createFalse():e===null?this.f.createNull():this.f.createStringLiteral(e);makeLiteralType=e=>this.f.createLiteralTypeNode(this.literally(e));isPrimitive=e=>this.#e.includes(e.kind)};const Z=e=>e;var Kn=class{api;paths=new Set;tags=new Map;registry=new Map;constructor(e,t){this.serverUrl=t,this.api=new Gn(e)}#e={pathType:`Path`,implementationType:`Implementation`,keyParameter:`key`,pathParameter:`path`,paramsArgument:`params`,ctxArgument:`ctx`,methodParameter:`method`,requestParameter:`request`,eventParameter:`event`,dataParameter:`data`,handlerParameter:`handler`,msgParameter:`msg`,parseRequestFn:`parseRequest`,substituteFn:`substitute`,provideMethod:`provide`,onMethod:`on`,implementationArgument:`implementation`,hasBodyConst:`hasBody`,undefinedValue:`undefined`,responseConst:`response`,restConst:`rest`,searchParamsConst:`searchParams`,defaultImplementationConst:`defaultImplementation`,clientConst:`client`,contentTypeConst:`contentType`,isJsonConst:`isJSON`,sourceProp:`source`,methodType:`Method`,someOfType:`SomeOf`,requestType:`Request`,paginationType:`Pagination`};interfaces={input:`Input`,positive:`PositiveResponse`,negative:`NegativeResponse`,encoded:`EncodedResponse`,response:`Response`};makeMethodType=()=>this.api.makePublicLiteralType(this.#e.methodType,ce);makeSomeOfType=()=>this.api.makeType(this.#e.someOfType,this.api.makeIndexed(`T`,this.api.makeKeyOf(`T`)),{params:[`T`]});makeRequestType=()=>this.api.makeType(this.#e.requestType,this.api.makeKeyOf(this.interfaces.input),{expose:!0});someOf=({name:e})=>this.api.ensureTypeNode(this.#e.someOfType,[e]);makePathType=()=>this.api.makePublicLiteralType(this.#e.pathType,Array.from(this.paths));makePublicInterfaces=()=>Object.keys(this.interfaces).map(e=>this.api.makeInterface(this.interfaces[e],Array.from(this.registry).map(([t,{store:n,isDeprecated:r}])=>this.api.makeInterfaceProp(t,n[e],{isDeprecated:r})),{expose:!0}));makeEndpointTags=()=>this.api.makeConst(`endpointTags`,this.api.f.createObjectLiteralExpression(Array.from(this.tags).map(([e,n])=>this.api.f.createPropertyAssignment(this.api.makePropertyIdentifier(e),this.api.f.createArrayLiteralExpression(t.map(this.api.literally,n))))),{expose:!0});makeImplementationType=()=>this.api.makeType(this.#e.implementationType,this.api.makeFnType({[this.#e.methodParameter]:this.#e.methodType,[this.#e.pathParameter]:this.api.ts.SyntaxKind.StringKeyword,[this.#e.paramsArgument]:this.api.makeRecordStringAny(),[this.#e.ctxArgument]:{optional:!0,type:`T`}},this.api.makePromise(this.api.ts.SyntaxKind.AnyKeyword)),{expose:!0,params:{T:{init:this.api.ts.SyntaxKind.UnknownKeyword}}});makeParseRequestFn=()=>this.api.makeConst(this.#e.parseRequestFn,this.api.makeArrowFn({[this.#e.requestParameter]:this.api.ts.SyntaxKind.StringKeyword},this.api.f.createAsExpression(this.api.makeCall(this.#e.requestParameter,Z(`split`))(this.api.f.createRegularExpressionLiteral(`/ (.+)/`),this.api.literally(2)),this.api.f.createTupleTypeNode([this.api.ensureTypeNode(this.#e.methodType),this.api.ensureTypeNode(this.#e.pathType)]))));makeSubstituteFn=()=>this.api.makeConst(this.#e.substituteFn,this.api.makeArrowFn({[this.#e.pathParameter]:this.api.ts.SyntaxKind.StringKeyword,[this.#e.paramsArgument]:this.api.makeRecordStringAny()},this.api.f.createBlock([this.api.makeConst(this.#e.restConst,this.api.f.createObjectLiteralExpression([this.api.f.createSpreadAssignment(this.api.makeId(this.#e.paramsArgument))])),this.api.f.createForInStatement(this.api.f.createVariableDeclarationList([this.api.f.createVariableDeclaration(this.#e.keyParameter)],this.api.ts.NodeFlags.Const),this.api.makeId(this.#e.paramsArgument),this.api.f.createBlock([this.api.makeAssignment(this.#e.pathParameter,this.api.makeCall(this.#e.pathParameter,Z(`replace`))(this.api.makeTemplate(`:`,[this.#e.keyParameter]),this.api.makeArrowFn([],this.api.f.createBlock([this.api.f.createExpressionStatement(this.api.f.createDeleteExpression(this.api.f.createElementAccessExpression(this.api.makeId(this.#e.restConst),this.api.makeId(this.#e.keyParameter)))),this.api.f.createReturnStatement(this.api.f.createElementAccessExpression(this.api.makeId(this.#e.paramsArgument),this.api.makeId(this.#e.keyParameter)))]))))])),this.api.f.createReturnStatement(this.api.f.createAsExpression(this.api.f.createArrayLiteralExpression([this.api.makeId(this.#e.pathParameter),this.api.makeId(this.#e.restConst)]),this.api.ensureTypeNode(`const`)))])));makePaginationType=()=>{let e=Z(`nextCursor`),t=Z(`total`),n=Z(`limit`),r=Z(`offset`),i=this.api.f.createTypeLiteralNode([this.api.makeInterfaceProp(e,this.api.makeUnion([this.api.ensureTypeNode(this.api.ts.SyntaxKind.StringKeyword),this.api.makeLiteralType(null)]))]),a=this.api.f.createTypeLiteralNode([t,n,r].map(e=>this.api.makeInterfaceProp(e,this.api.ts.SyntaxKind.NumberKeyword)));return this.api.makeType(this.#e.paginationType,this.api.makeUnion([i,a]))};#t=()=>{let e=this.api.makeId(this.#e.responseConst),t=Z(`nextCursor`),n=Z(`total`),r=Z(`limit`),i=Z(`offset`),a=this.api.f.createBinaryExpression(this.api.literally(t),this.api.ts.SyntaxKind.InKeyword,e),o=this.api.f.createReturnStatement(this.api.f.createBinaryExpression(this.api.f.createPropertyAccessExpression(e,t),this.api.ts.SyntaxKind.ExclamationEqualsEqualsToken,this.api.literally(null))),s=this.api.f.createBinaryExpression(this.api.f.createPropertyAccessExpression(e,i),this.api.ts.SyntaxKind.PlusToken,this.api.f.createPropertyAccessExpression(e,r)),c=this.api.f.createReturnStatement(this.api.f.createBinaryExpression(s,this.api.ts.SyntaxKind.LessThanToken,this.api.f.createPropertyAccessExpression(e,n)));return this.api.makePublicMethod(`hasMore`,[this.api.makeParam(e,{type:this.#e.paginationType})],[this.api.f.createIfStatement(a,o),c],{returns:this.api.ensureTypeNode(this.api.ts.SyntaxKind.BooleanKeyword),isStatic:!0})};#n=()=>this.api.makePublicMethod(this.#e.provideMethod,this.api.makeParams({[this.#e.requestParameter]:`K`,[this.#e.paramsArgument]:this.api.makeIndexed(this.interfaces.input,`K`),[this.#e.ctxArgument]:{optional:!0,type:`T`}}),[this.api.makeConst(this.api.makeDeconstruction(this.#e.methodParameter,this.#e.pathParameter),this.api.makeCall(this.#e.parseRequestFn)(this.#e.requestParameter)),this.api.f.createReturnStatement(this.api.makeCall(this.api.f.createThis(),this.#e.implementationArgument)(this.#e.methodParameter,this.api.f.createSpreadElement(this.api.makeCall(this.#e.substituteFn)(this.#e.pathParameter,this.#e.paramsArgument)),this.#e.ctxArgument))],{typeParams:{K:this.#e.requestType},returns:this.api.makePromise(this.api.makeIndexed(this.interfaces.response,`K`))});makeClientClass=e=>this.api.makePublicClass(e,[this.api.makePublicConstructor([this.api.makeParam(this.#e.implementationArgument,{type:this.api.ensureTypeNode(this.#e.implementationType,[`T`]),mod:this.api.accessModifiers.protectedReadonly,initId:this.#e.defaultImplementationConst})]),this.#n(),this.#t()],{typeParams:[`T`]});#r=e=>this.api.makeTemplate(`?`,[this.api.makeNew(URLSearchParams.name,this.api.makeId(e))]);#i=()=>this.api.makeNew(URL.name,this.api.makeTemplate(``,[this.#e.pathParameter],[this.#e.searchParamsConst]),this.api.literally(this.serverUrl));makeDefaultImplementation=()=>{let e=this.api.f.createPropertyAssignment(Z(`method`),this.api.makeCall(this.#e.methodParameter,Z(`toUpperCase`))()),t=this.api.f.createPropertyAssignment(Z(`headers`),this.api.makeTernary(this.#e.hasBodyConst,this.api.f.createObjectLiteralExpression([this.api.f.createPropertyAssignment(this.api.literally(`Content-Type`),this.api.literally(x.json))]),this.#e.undefinedValue)),n=this.api.f.createPropertyAssignment(Z(`body`),this.api.makeTernary(this.#e.hasBodyConst,this.api.makeCall(JSON[Symbol.toStringTag],Z(`stringify`))(this.#e.paramsArgument),this.#e.undefinedValue)),r=this.api.makeConst(this.#e.responseConst,this.api.f.createAwaitExpression(this.api.makeCall(fetch.name)(this.#i(),this.api.f.createObjectLiteralExpression([e,t,n])))),i=this.api.makeConst(this.#e.hasBodyConst,this.api.f.createLogicalNot(this.api.makeCall(this.api.f.createArrayLiteralExpression([this.api.literally(`get`),this.api.literally(`head`),this.api.literally(`delete`)]),Z(`includes`))(this.#e.methodParameter))),a=this.api.makeConst(this.#e.searchParamsConst,this.api.makeTernary(this.#e.hasBodyConst,this.api.literally(``),this.#r(this.#e.paramsArgument))),o=this.api.makeConst(this.#e.contentTypeConst,this.api.makeCall(this.#e.responseConst,Z(`headers`),Z(`get`))(this.api.literally(`content-type`))),s=this.api.f.createIfStatement(this.api.f.createPrefixUnaryExpression(this.api.ts.SyntaxKind.ExclamationToken,this.api.makeId(this.#e.contentTypeConst)),this.api.f.createReturnStatement()),c=this.api.makeConst(this.#e.isJsonConst,this.api.makeCall(this.#e.contentTypeConst,Z(`startsWith`))(this.api.literally(x.json))),l=this.api.f.createReturnStatement(this.api.makeCall(this.#e.responseConst,this.api.makeTernary(this.#e.isJsonConst,this.api.literally(Z(`json`)),this.api.literally(Z(`text`))))());return this.api.makeConst(this.#e.defaultImplementationConst,this.api.makeArrowFn([this.#e.methodParameter,this.#e.pathParameter,this.#e.paramsArgument],this.api.f.createBlock([i,a,r,o,s,c,l]),{isAsync:!0}),{type:this.#e.implementationType})};#a=()=>this.api.makePublicConstructor(this.api.makeParams({request:`K`,params:this.api.makeIndexed(this.interfaces.input,`K`)}),[this.api.makeConst(this.api.makeDeconstruction(this.#e.pathParameter,this.#e.restConst),this.api.makeCall(this.#e.substituteFn)(this.api.f.createElementAccessExpression(this.api.makeCall(this.#e.parseRequestFn)(this.#e.requestParameter),this.api.literally(1)),this.#e.paramsArgument)),this.api.makeConst(this.#e.searchParamsConst,this.#r(this.#e.restConst)),this.api.makeAssignment(this.api.f.createPropertyAccessExpression(this.api.f.createThis(),this.#e.sourceProp),this.api.makeNew(`EventSource`,this.#i()))]);#o=e=>this.api.f.createTypeLiteralNode([this.api.makeInterfaceProp(Z(`event`),e)]);#s=()=>this.api.makePublicMethod(this.#e.onMethod,this.api.makeParams({[this.#e.eventParameter]:`E`,[this.#e.handlerParameter]:this.api.makeFnType({[this.#e.dataParameter]:this.api.makeIndexed(this.api.makeExtract(`R`,this.api.makeOneLine(this.#o(`E`))),this.api.makeLiteralType(Z(`data`)))},this.api.makeMaybeAsync(this.api.ts.SyntaxKind.VoidKeyword))}),[this.api.f.createExpressionStatement(this.api.makeCall(this.api.f.createThis(),this.#e.sourceProp,Z(`addEventListener`))(this.#e.eventParameter,this.api.makeArrowFn([this.#e.msgParameter],this.api.makeCall(this.#e.handlerParameter)(this.api.makeCall(JSON[Symbol.toStringTag],Z(`parse`))(this.api.f.createPropertyAccessExpression(this.api.f.createParenthesizedExpression(this.api.f.createAsExpression(this.api.makeId(this.#e.msgParameter),this.api.ensureTypeNode(MessageEvent.name))),Z(`data`))))))),this.api.f.createReturnStatement(this.api.f.createThis())],{typeParams:{E:this.api.makeIndexed(`R`,this.api.makeLiteralType(Z(`event`)))}});makeSubscriptionClass=e=>this.api.makePublicClass(e,[this.api.makePublicProperty(this.#e.sourceProp,`EventSource`),this.#a(),this.#s()],{typeParams:{K:this.api.makeExtract(this.#e.requestType,this.api.f.createTemplateLiteralType(this.api.f.createTemplateHead(`get `),[this.api.f.createTemplateLiteralTypeSpan(this.api.ensureTypeNode(this.api.ts.SyntaxKind.StringKeyword),this.api.f.createTemplateTail(``))])),R:this.api.makeExtract(this.api.makeIndexed(this.interfaces.positive,`K`),this.api.makeOneLine(this.#o(this.api.ts.SyntaxKind.StringKeyword)))}});makeUsageStatements=(e,t)=>[this.api.makeConst(this.#e.clientConst,this.api.makeNew(e)),this.api.makeCall(this.#e.clientConst,this.#e.provideMethod)(this.api.literally(`get /v1/user/retrieve`),this.api.f.createObjectLiteralExpression([this.api.f.createPropertyAssignment(`id`,this.api.literally(`10`))])),this.api.makeCall(this.api.makeNew(t,this.api.literally(`get /v1/events/stream`),this.api.f.createObjectLiteralExpression()),this.#e.onMethod)(this.api.literally(`time`),this.api.makeArrowFn([`time`],this.api.f.createBlock([])))]};const qn=(t,{rules:n,onMissing:r,ctx:i={}})=>{let a=e(t),o=a&&a in n?n[a]:n[t._zod.def.type],s=e=>qn(e,{ctx:i,rules:n,onMissing:r});return o?o(t,{...i,next:s}):r(t,i)},Jn={name:t.path([`name`,`text`]),type:t.path([`type`]),optional:t.path([`questionToken`])},Yn=({_zod:{def:e}},{api:t})=>{let n=e.values.map(e=>e===void 0?t.ensureTypeNode(t.ts.SyntaxKind.UndefinedKeyword):t.makeLiteralType(e));return n.length===1?n[0]:t.makeUnion(n)},Xn=({_zod:{def:e}},{next:t,api:n})=>{let r=[...e.parts],i=()=>{let e=``;for(;r.length;){let t=r.shift();if(T(t)){r.unshift(t);break}e+=t??``}return e},a=n.f.createTemplateHead(i()),o=[];for(;r.length;){let e=t(r.shift()),a=i(),s=r.length?n.f.createTemplateMiddle:n.f.createTemplateTail;o.push(n.f.createTemplateLiteralTypeSpan(e,s(a)))}return o.length?n.f.createTemplateLiteralType(a,o):n.makeLiteralType(a.text)},Zn=(e,{isResponse:t,next:i,makeAlias:a,api:o})=>{let s=()=>{let a=Object.entries(e._zod.def.shape).map(([e,a])=>{let{description:s,deprecated:c}=n.get(a)||{},l=(t?a._zod.optout:a._zod.optin)===`optional`,u=l&&!(a instanceof r.core.$ZodExactOptional);return o.makeInterfaceProp(e,i(a),{comment:s,isDeprecated:c,isOptional:l,hasUndefined:u})});return o.f.createTypeLiteralNode(a)};return Fe(e,{io:t?`output`:`input`})?a(e,s):s()},Qn=({_zod:{def:e}},{next:t,api:n})=>n.f.createArrayTypeNode(t(e.element)),$n=({_zod:{def:e}},{api:n})=>n.makeUnion(t.map(n.makeLiteralType,Object.values(e.entries))),er=({_zod:{def:e}},{next:t,api:n})=>n.makeUnion(e.options.map(t)),tr=({_zod:{def:e}},{next:t,api:n})=>n.makeUnion([t(e.innerType),n.makeLiteralType(null)]),nr=({_zod:{def:e}},{next:t,api:n})=>n.f.createTupleTypeNode(e.items.map(t).concat(e.rest===null?[]:n.f.createRestTypeNode(t(e.rest)))),rr=({_zod:{def:e}},{next:t,api:n})=>{let[r,i]=[e.keyType,e.valueType].map(t),a=n.ensureTypeNode(`Record`,[r,i]);return e.mode===`loose`?n.f.createIntersectionTypeNode([a,n.ensureTypeNode(`Record`,[`PropertyKey`,i])]):a},ir=t.tryCatch((e,n)=>{if(!n.every(e.ts.isTypeLiteralNode))throw Error(`Not objects`);let r=t.chain(t.prop(`members`),n),i=t.uniqWith((...e)=>{if(!t.eqBy(Jn.name,...e))return!1;if(t.both(t.eqBy(Jn.type),t.eqBy(Jn.optional))(...e))return!0;throw Error(`Has conflicting prop`)},r);return e.f.createTypeLiteralNode(i)},(e,t,n)=>t.f.createIntersectionTypeNode(n)),ar=({_zod:{def:e}},{next:t,api:n})=>ir(n,[e.left,e.right].map(t)),Q=e=>({},{api:t})=>t.ensureTypeNode(t.ts.SyntaxKind[e]),$=({_zod:{def:e}},{next:t})=>t(e.innerType),or=(e,t)=>e.ensureTypeNode(t?e.ts.SyntaxKind.UnknownKeyword:e.ts.SyntaxKind.AnyKeyword),sr=({_zod:{def:e}},{next:t,isResponse:n,api:r})=>{let i=e[n?`out`:`in`],a=e[n?`in`:`out`];if(!T(i,`transform`))return t(i);let o=t(a),s={[r.ts.SyntaxKind.AnyKeyword]:``,[r.ts.SyntaxKind.BigIntKeyword]:BigInt(0),[r.ts.SyntaxKind.BooleanKeyword]:!1,[r.ts.SyntaxKind.NumberKeyword]:0,[r.ts.SyntaxKind.ObjectKeyword]:{},[r.ts.SyntaxKind.StringKeyword]:``,[r.ts.SyntaxKind.UndefinedKeyword]:void 0}[o.kind],c=ye(i,s),l={number:r.ts.SyntaxKind.NumberKeyword,bigint:r.ts.SyntaxKind.BigIntKeyword,boolean:r.ts.SyntaxKind.BooleanKeyword,string:r.ts.SyntaxKind.StringKeyword,undefined:r.ts.SyntaxKind.UndefinedKeyword,object:r.ts.SyntaxKind.ObjectKeyword};return r.ensureTypeNode(c&&l[c]||or(r,n))},cr=({},{api:e})=>e.makeLiteralType(null),lr=({_zod:{def:e}},{makeAlias:t,next:n})=>t(e.getter,()=>n(e.getter())),ur=({},{api:e})=>e.ensureTypeNode(`Buffer`),dr=(e,{next:t})=>t(e._zod.def.shape.raw),fr={string:Q(`StringKeyword`),number:Q(`NumberKeyword`),bigint:Q(`BigIntKeyword`),boolean:Q(`BooleanKeyword`),any:Q(`AnyKeyword`),undefined:Q(`UndefinedKeyword`),[j]:Q(`StringKeyword`),[M]:Q(`StringKeyword`),never:Q(`NeverKeyword`),void:Q(`UndefinedKeyword`),unknown:Q(`UnknownKeyword`),null:cr,array:Qn,tuple:nr,record:rr,object:Zn,literal:Yn,template_literal:Xn,intersection:ar,union:er,default:$,enum:$n,optional:$,nonoptional:$,nullable:tr,catch:$,pipe:sr,lazy:lr,readonly:$,[A]:ur,[R]:dr},pr=(e,{brandHandling:t,ctx:n})=>qn(e,{rules:{...t,...fr},onMissing:({},{isResponse:e,api:t})=>or(t,e),ctx:n});var mr=class e extends Kn{#e=[this.makeSomeOfType()];#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=this.api.makeLiteralType(null);this.#t.set(e,this.api.makeType(n,r)),this.#t.set(e,this.api.makeType(n,t()))}return this.api.ensureTypeNode(n)}constructor({typescript:e,routing:n,config:i,brandHandling:a,variant:o=`client`,clientClassName:s=`Client`,subscriptionClassName:c=`Subscription`,serverUrl:l=`https://example.com`,noContent:u=r.undefined(),hasHeadMethod:d=!0}){super(e,l);let f={makeAlias:this.#r.bind(this),api:this.api},p={brandHandling:a,ctx:{...f,isResponse:!1}},m={brandHandling:a,ctx:{...f,isResponse:!0}},h=(e,n,r)=>{let i=D.bind(null,e,n),{isDeprecated:a,inputSchema:o,tags:s}=r,c=`${e} ${n}`,l=this.api.makeType(i(`input`),pr(o,p),{comment:c});this.#e.push(l);let d=Ye.reduce((n,a)=>{let o=r.getResponses(a),s=t.chain(([t,{schema:n,mimeTypes:r,statusCodes:o}])=>{let s=be(e,r),l=this.api.makeType(i(a,`variant`,`${t+1}`),pr(s?n:u,m),{comment:c});return this.#e.push(l),o.map(e=>this.api.makeInterfaceProp(e,l.name))},Array.from(o.entries())),l=this.api.makeInterface(i(a,`response`,`variants`),s,{comment:c});return this.#e.push(l),Object.assign(n,{[a]:l})},{});this.paths.add(n);let f=this.api.makeLiteralType(c),h={input:this.api.ensureTypeNode(l.name),positive:this.someOf(d.positive),negative:this.someOf(d.negative),response:this.api.makeUnion([this.api.makeIndexed(this.interfaces.positive,f),this.api.makeIndexed(this.interfaces.negative,f)]),encoded:this.api.f.createIntersectionTypeNode([this.api.ensureTypeNode(d.positive.name),this.api.ensureTypeNode(d.negative.name)])};this.registry.set(c,{isDeprecated:a,store:h}),this.tags.set(c,s)};St({routing:n,config:i,onEndpoint:d?ht(h):h}),this.#e.unshift(...this.#t.values()),this.#e.push(this.makePathType(),this.makeMethodType(),...this.makePublicInterfaces(),this.makeRequestType()),o!==`types`&&(this.#e.push(this.makeEndpointTags(),this.makeParseRequestFn(),this.makeSubstituteFn(),this.makeImplementationType(),this.makePaginationType(),this.makeDefaultImplementation(),this.makeClientClass(s),this.makeSubscriptionClass(c)),this.#n.push(...this.makeUsageStatements(s,c)))}static async create(t){return new e({...t,typescript:await J(`typescript`)})}#i(e){return this.#n.length?this.#n.map(t=>typeof t==`string`?t:this.api.printNode(t,e)).join(`
17
+ `))},Yt=e=>{e.startupLogo!==!1&&Jt(process.stdout);let t=e.errorHandler||U,n=ot(e.logger)?e.logger:new ut(e.logger);n.debug(`Running`,{build:`v28.0.0-beta.3`,env:process.env.NODE_ENV||`development`}),Kt(n);let r=Wt({logger:n,config:e}),i={getLogger:Gt(n),errorHandler:t},a=zt(i),o=Rt(i);return{...i,logger:n,notFoundHandler:a,catcher:o,loggingMiddleware:r}},Xt=(e,t)=>{let{logger:n,getLogger:r,notFoundHandler:i,loggingMiddleware:a}=Yt(e);return At({app:e.app.use(a),routing:t,getLogger:r,config:e}),{notFoundHandler:i,logger:n}},Zt=async(e,t)=>{let{logger:n,getLogger:r,notFoundHandler:i,catcher:a,loggingMiddleware:o}=Yt(e),s=_().disable(`x-powered-by`).set(`query parser`,e.queryParser??`simple`).use(o);if(e.compression){let t=await q(`compression`);s.use(t(typeof e.compression==`object`?e.compression:void 0))}await e.beforeRouting?.({app:s,getLogger:r}),At({app:s,routing:t,getLogger:r,config:e,parsers:{json:[e.jsonParser||_.json()],raw:[e.rawParser||_.raw(),Ut],form:[e.formParser||_.urlencoded()],upload:e.upload?await Ht({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=ee.createServer(s);c.push(t),u.push(l(t,e.http.listen))}if(e.https){let t=te.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&&qt({logger:n,servers:c,options:e.gracefulShutdown===!0?{}:e.gracefulShutdown}),{app:s,logger:n,servers:u.map(e=>e())}},Qt=e=>E(e)&&`or`in e,$t=e=>E(e)&&`and`in e,en=e=>!$t(e)&&!Qt(e),tn=e=>{let t=n.filter(en,e),r=n.chain(n.prop(`and`),n.filter($t,e)),[i,a]=n.partition(en,r),o=n.concat(t,i),s=n.filter(Qt,e);return n.map(n.prop(`or`),n.concat(s,a)).reduce((e,t)=>w(e,n.map(e=>en(e)?[e]:e.and,t),([e,t])=>n.concat(e,t)),n.reject(n.isEmpty,[o]))};var nn=`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.incremental.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 rn=`https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString`,an={integer:0,number:0,string:``,boolean:!1,object:{},null:null,array:[]},on=e=>e.replace(de,e=>`{${e.slice(1)}}`),sn=({},e)=>{if(e.isResponse)throw new P(`Please use ez.upload() only for input.`,e);return{type:`string`,format:`binary`}},cn=({jsonSchema:e})=>({...e,externalDocs:{description:`raw binary data`,url:`https://swagger.io/specification/#working-with-binary-data`}}),ln=({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}}},un=n.tryCatch(({jsonSchema:e})=>{if(!e.allOf)throw`no allOf`;return J(e,`throw`)},(e,{jsonSchema:t})=>t),dn=({jsonSchema:e})=>{if(!e.anyOf)return e;let t=e.anyOf[0];return Object.assign(t,{type:_n(t.type)})},Y=e=>e,fn=({jsonSchema:{examples:e,description:t}},n)=>{if(n.isResponse)throw new P(`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:rn}};return e?.length&&(r.examples=e),r},pn=({jsonSchema:{examples:e,description:t}},n)=>{if(!n.isResponse)throw new P(`Please use ez.dateIn() for input.`,n);let r={description:t||`YYYY-MM-DDTHH:mm:ss.sssZ`,type:`string`,format:`date-time`,externalDocs:{url:rn}};return e?.length&&(r.examples=e),r},mn=()=>({type:`string`,format:`bigint`,pattern:`^-?\\d+$`}),hn=({zodSchema:e,jsonSchema:t})=>e._zod.def.rest===null?{...t,items:{not:{}}}:t,gn=e=>{let t=Array.isArray(e.type)?e.type[0]:e.type;return an?.[t]},_n=e=>e===`null`?e:typeof e==`string`?[e,`null`]:e&&[...new Set(e).add(`null`)],vn=({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=Y(Tn(i,{ctx:n}));if(v(a))if(n.isResponse){let e=be(r,gn(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},yn=({jsonSchema:e})=>{if(e.type!==`object`)return e;let t=e;return!t.properties||!(`raw`in t.properties)||!E(t.properties.raw)?e:t.properties.raw},bn=e=>e.length?n.fromPairs(n.zip(n.times(e=>`example${e+1}`,e.length),n.map(n.objOf(`value`),e))):void 0,xn=(e,t)=>t?.includes(e)||e.startsWith(`x-`)||nn.includes(e),Sn=({path:e,method:t,request:r,inputSources:i,makeRef:a,composition:o,isHeader:s,security:c,description:l=`${t.toUpperCase()} ${e} Parameter`})=>{let u=J(r),d=fe(e),f=i.includes(`query`),p=i.includes(`params`),m=i.includes(`headers`),h=e=>p&&d.includes(e),g=n.chain(n.filter(e=>e.type===`header`),c??[]).map(({name:e})=>e),_=n=>m&&(s?.(n,t,e)??xn(n,g));return Object.entries(u.properties).reduce((e,[t,r])=>{if(!E(r))return e;let i=h(t)?`path`:_(t)?`header`:f?`query`:void 0;if(!i)return e;let s=Y(r),c=o===`components`?a(r.id||JSON.stringify(r),s,r.id||T(l,t)):s;return e.concat({name:t,in:i,deprecated:r.deprecated,required:u.required?.includes(t)||!1,description:s.description||l,schema:c,examples:bn(v(s)&&s.examples?.length?s.examples:n.pluck(t,u.examples?.filter(n.both(E,n.has(t)))||[]))})},[])},Cn={nullable:dn,union:ln,bigint:mn,intersection:un,tuple:hn,pipe:vn,[j]:fn,[M]:pn,[I]:sn,[L]:yn,[A]:cn},wn=(e,t,r)=>{let i=[e,t];for(;i.length;){let e=i.shift();if(n.is(Object,e)){if(ie(e)&&!e.$ref.startsWith(`#/components`)){let n=t[e.$ref.split(`/`).pop()];n&&(e.$ref=r.makeRef(n.id||n,Y(n),n.id).$ref);continue}i.push(...n.values(e))}n.is(Array,e)&&i.push(...n.values(e))}return e},Tn=(e,{ctx:n,rules:r=Cn})=>{let{$defs:i={},properties:a={}}=t.toJSONSchema(t.object({subject:e}),{unrepresentable:`any`,io:n.isResponse?`output`:`input`,override:e=>{let t=O(e.zodSchema),i=r[t&&t in r?t:e.zodSchema._zod.def.type];if(i){let t={...i(e,n)};for(let t in e.jsonSchema)delete e.jsonSchema[t];Object.assign(e.jsonSchema,t)}}});return wn(E(a.subject)?a.subject:{},i,n)},En=(e,t)=>{if(ie(e))return[e,!1];let r=!1,i=n.map(e=>{let[n,i]=En(e,t);return r||=i,n}),a=n.omit(t),o={properties:a,examples:n.map(a),required:n.without(t),allOf:i,oneOf:i,anyOf:i},s=n.evolve(o,e);return[s,r||!!s.required?.length]},Dn=({method:e,path:t,schema:r,mimeTypes:i,variant:a,makeRef:o,composition:s,hasMultipleStatusCodes:c,statusCode:l,brandHandling:u,description:d=`${e.toUpperCase()} ${t} ${ye(a)} response ${c?l:``}`.trim()})=>{if(!Se(e,i))return{description:d};let f=Y(Tn(r,{rules:{...u,...Cn},ctx:{isResponse:!0,makeRef:o,path:t,method:e}})),p=[];v(f)&&f.examples&&(p.push(...f.examples),delete f.examples);let m={schema:s===`components`?o(r,f,T(d)):f,examples:bn(p)};return{description:d,content:n.fromPairs(n.xprod(i,[m]))}},On=({format:e})=>{let t={type:`http`,scheme:`bearer`};return e&&(t.bearerFormat=e),t},kn=({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},An=({name:e})=>({type:`apiKey`,in:`header`,name:e}),jn=({name:e})=>({type:`apiKey`,in:`cookie`,name:e}),Mn=({url:e})=>({type:`openIdConnect`,openIdConnectUrl:e}),Nn=({flows:e={}})=>({type:`oauth2`,flows:n.map(e=>({...e,scopes:e.scopes||{}}),n.reject(n.isNil,e))}),Pn=(e,t=[])=>{let n=e=>e.type===`basic`?{type:`http`,scheme:`basic`}:e.type===`bearer`?On(e):e.type===`input`?kn(e,t):e.type===`header`?An(e):e.type===`cookie`?jn(e):e.type===`openid`?Mn(e):Nn(e);return e.map(e=>e.map(n))},Fn=(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:[]})},{})),In=({schema:e,brandHandling:t,makeRef:n,path:r,method:i})=>Tn(e,{rules:{...t,...Cn},ctx:{isResponse:!1,makeRef:n,path:r,method:i}}),Ln=({method:e,path:t,schema:r,request:i,mimeType:a,makeRef:o,composition:s,paramNames:c,description:l=`${e.toUpperCase()} ${t} Request body`})=>{let[u,d]=En(Y(i),c),f=[];v(u)&&u.examples&&(f.push(...u.examples),delete u.examples);let p={schema:s===`components`?o(r,u,T(l)):u,examples:bn(f.length?f:J(i).examples?.filter(e=>E(e)&&!Array.isArray(e)).map(n.omit(c))||[])},m={description:l,content:{[a]:p}};return(d||a===y.raw)&&(m.required=!0),m},Rn=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,t=50)=>!e||e.length<=t?e:e.slice(0,t-1)+`…`,Bn=e=>e.length?e.slice():void 0,Vn=({description:e,summary:t=e,trim:n})=>n(t);var Hn=class extends re{#e=new Map;#t=new Map;#n=new Map;#r(e,t,n){let r=this.#n.get(e);if(!r){let t=n?0:1;do r=`${n??`Schema`}${t?this.#n.size+t:``}`,t++;while(this.rootDoc.components?.schemas?.[r]);this.#n.set(e,r)}return this.addSchema(r,t),{$ref:`#/components/schemas/${r}`}}#i(e,t,n){let r=n||T(t,e),i=this.#t.get(r);if(i===void 0)return this.#t.set(r,1),r;if(n)throw new P(`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:t,title:r,version:i,serverUrl:a,descriptions:o,brandHandling:s,tags:c,isHeader:l,hasHeadMethod:u=!0,summarizer:d=Vn,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,summary:u,scopes:p,inputSchema:m}=i,h=_e(e,t.inputSources),g=this.#i(r,e,i.getOperationId(e)),_=In({...a,schema:m}),ee=tn(i.security),te=Sn({...a,inputSources:h,isHeader:l,security:ee,request:_,description:o?.requestParameter?.({method:e,path:r,operationId:g})}),ne={};for(let t of Qe){let n=i.getResponses(t);for(let{mimeTypes:i,schema:s,statusCodes:c}of n)for(let l of c)ne[l]=Dn({...a,variant:t,schema:s,mimeTypes:i,statusCode:l,hasMultipleStatusCodes:n.length>1||c.length>1,description:o?.[`${t}Response`]?.({method:e,path:r,operationId:g,statusCode:l})})}let re=h.includes(`body`)?Ln({...a,request:_,paramNames:n.pluck(`name`,te),schema:m,mimeType:y[i.requestType],description:o?.requestBody?.({method:e,path:r,operationId:g})}):void 0,ie=Fn(Pn(ee,h),p,e=>{let t=this.#a(e);return this.addSecurityScheme(t,e),t}),v={operationId:g,summary:d({summary:u,description:c,trim:zn}),description:c,deprecated:i.isDeprecated||void 0,tags:Bn(i.tags),parameters:Bn(te),requestBody:re,security:Bn(ie),responses:ne};this.addPath(on(r),{[e]:v})};Tt({routing:e,config:t,onEndpoint:u?vt(p):p}),c&&(this.rootDoc.tags=Rn(c))}};const Un=e=>ae({...e,headers:{"content-type":y.json,...e?.headers}}),Wn=e=>oe(e),Gn=e=>{let t={warn:[],error:[],info:[],debug:[]};return new Proxy(e||{},{get(e,n,r){return n===`_getLogs`?()=>t:st(n)?(...e)=>t[n].push(e):Reflect.get(e,n,r)}})},Kn=({requestProps:e,responseOptions:t,configProps:n,loggerProps:r})=>{let i=Un(e),a=Wn({req:i,...t});a.req=t?.req||i,i.res=a;let o=Gn(r);return{requestMock:i,responseMock:a,loggerMock:o,configMock:{cors:!1,logger:o,...n}}},qn=async({endpoint:e,...t})=>{let{requestMock:n,responseMock:r,loggerMock:i,configMock:a}=Kn(t);return await e.execute({request:n,response:r,config:a,logger:i}),{requestMock:n,responseMock:r,loggerMock:i}},Jn=async({middleware:e,ctx:t={},...n})=>{let{requestMock:r,responseMock:i,loggerMock:a,configMock:{inputSources:o,errorHandler:s=U}}=Kn(n),c={request:r,response:i,logger:a,input:ve(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:{}}}};var Yn=class e{ts;f;exportModifier;asyncModifier;accessModifiers;#e;static#t=/^[A-Za-z_$][A-Za-z0-9_$]*$/;constructor(e){this.ts=e,this.f=this.ts.factory,this.exportModifier=[this.f.createModifier(this.ts.SyntaxKind.ExportKeyword)],this.asyncModifier=[this.f.createModifier(this.ts.SyntaxKind.AsyncKeyword)],this.accessModifiers={public:[this.f.createModifier(this.ts.SyntaxKind.PublicKeyword)],publicStatic:[this.f.createModifier(this.ts.SyntaxKind.PublicKeyword),this.f.createModifier(this.ts.SyntaxKind.StaticKeyword)],protectedReadonly:[this.f.createModifier(this.ts.SyntaxKind.ProtectedKeyword),this.f.createModifier(this.ts.SyntaxKind.ReadonlyKeyword)]},this.#e=[this.ts.SyntaxKind.AnyKeyword,this.ts.SyntaxKind.BigIntKeyword,this.ts.SyntaxKind.BooleanKeyword,this.ts.SyntaxKind.NeverKeyword,this.ts.SyntaxKind.NumberKeyword,this.ts.SyntaxKind.ObjectKeyword,this.ts.SyntaxKind.StringKeyword,this.ts.SyntaxKind.SymbolKeyword,this.ts.SyntaxKind.UndefinedKeyword,this.ts.SyntaxKind.UnknownKeyword,this.ts.SyntaxKind.VoidKeyword]}addJsDoc=(e,t)=>this.ts.addSyntheticLeadingComment(e,this.ts.SyntaxKind.MultiLineCommentTrivia,`* ${t} `,!0);printNode=(e,t)=>{let n=this.ts.createSourceFile(`print.ts`,``,this.ts.ScriptTarget.Latest,!1,this.ts.ScriptKind.TS);return this.ts.createPrinter(t).printNode(this.ts.EmitHint.Unspecified,e,n)};makeId=e=>this.f.createIdentifier(e);makePropertyIdentifier=t=>typeof t==`string`&&e.#t.test(t)?this.makeId(t):this.literally(t);makeTemplate=(e,...t)=>this.f.createTemplateExpression(this.f.createTemplateHead(e),t.map(([e,n=``],r)=>this.f.createTemplateSpan(typeof e==`string`?this.makeId(e):e,r===t.length-1?this.f.createTemplateTail(n):this.f.createTemplateMiddle(n))));makeParam=(e,{type:t,mod:n,initId:r,optional:i}={})=>this.f.createParameterDeclaration(n,void 0,e,i?this.f.createToken(this.ts.SyntaxKind.QuestionToken):void 0,t?this.ensureTypeNode(t):void 0,r?this.makeId(r):void 0);makeParams=e=>Object.entries(e).map(([e,t])=>this.makeParam(e,typeof t==`string`||typeof t==`number`||typeof t==`object`&&`kind`in t?{type:t}:t));makePublicConstructor=(e,t=[])=>this.f.createConstructorDeclaration(this.accessModifiers.public,e,this.f.createBlock(t));ensureTypeNode=(e,t)=>typeof e==`number`?this.f.createKeywordTypeNode(e):typeof e==`string`||this.ts.isIdentifier(e)?this.f.createTypeReferenceNode(e,t&&n.map(this.ensureTypeNode,t)):e;makeRecordStringAny=()=>this.ensureTypeNode(`Record`,[this.ts.SyntaxKind.StringKeyword,this.ts.SyntaxKind.AnyKeyword]);makeUnion=e=>{let t=new Map;for(let n of e)t.set(this.isPrimitive(n)?n.kind:n,n);return this.f.createUnionTypeNode(Array.from(t.values()))};makeInterfaceProp=(e,t,{isOptional:r,hasUndefined:i=r,isDeprecated:a,comment:o}={})=>{let s=this.ensureTypeNode(t),c=this.f.createPropertySignature(void 0,this.makePropertyIdentifier(e),r?this.f.createToken(this.ts.SyntaxKind.QuestionToken):void 0,i?this.makeUnion([s,this.ensureTypeNode(this.ts.SyntaxKind.UndefinedKeyword)]):s),l=n.reject(n.isNil,[a?`@deprecated`:void 0,o]);return l.length?this.addJsDoc(c,l.join(` `)):c};makeOneLine=e=>this.ts.setEmitFlags(e,this.ts.EmitFlags.SingleLine);makeDeconstruction=(...e)=>this.f.createArrayBindingPattern(e.map(e=>this.f.createBindingElement(void 0,void 0,e)));makeConst=(e,t,{type:n,expose:r}={})=>this.f.createVariableStatement(r&&this.exportModifier,this.f.createVariableDeclarationList([this.f.createVariableDeclaration(e,void 0,n?this.ensureTypeNode(n):void 0,t)],this.ts.NodeFlags.Const));makePublicLiteralType=(e,t)=>this.makeType(e,this.makeUnion(n.map(this.makeLiteralType,t)),{expose:!0});makeType=(e,t,{expose:n,comment:r,params:i}={})=>{let a=this.f.createTypeAliasDeclaration(n?this.exportModifier:void 0,e,i&&this.makeTypeParams(i),t);return r?this.addJsDoc(a,r):a};makePublicProperty=(e,t)=>this.f.createPropertyDeclaration(this.accessModifiers.public,e,void 0,this.ensureTypeNode(t),void 0);makePublicMethod=(e,t,n,{typeParams:r,returns:i,isStatic:a}={})=>this.f.createMethodDeclaration(a?this.accessModifiers.publicStatic:this.accessModifiers.public,void 0,e,void 0,r&&this.makeTypeParams(r),t,i,this.f.createBlock(n));makePublicClass=(e,t,{typeParams:n}={})=>this.f.createClassDeclaration(this.exportModifier,e,n&&this.makeTypeParams(n),void 0,t);makeKeyOf=e=>this.f.createTypeOperatorNode(this.ts.SyntaxKind.KeyOfKeyword,this.ensureTypeNode(e));makePromise=e=>this.ensureTypeNode(Promise.name,[e]);makeInterface=(e,t,{expose:n,comment:r}={})=>{let i=this.f.createInterfaceDeclaration(n?this.exportModifier:void 0,e,void 0,void 0,t);return r?this.addJsDoc(i,r):i};makeTypeParams=e=>(Array.isArray(e)?e.map(e=>n.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 this.f.createTypeParameterDeclaration([],e,n?this.ensureTypeNode(n):void 0,r?this.ensureTypeNode(r):void 0)});makeArrowFn=(e,t,{isAsync:r}={})=>this.f.createArrowFunction(r?this.asyncModifier:void 0,void 0,Array.isArray(e)?n.map(this.makeParam,e):this.makeParams(e),void 0,void 0,t);makeTernary=(...e)=>{let[t,n,r]=e.map(e=>typeof e==`string`?this.makeId(e):e);return this.f.createConditionalExpression(t,this.f.createToken(this.ts.SyntaxKind.QuestionToken),n,this.f.createToken(this.ts.SyntaxKind.ColonToken),r)};makeCall=(e,...t)=>(...n)=>this.f.createCallExpression(t.reduce((e,t)=>typeof t==`string`||this.ts.isIdentifier(t)?this.f.createPropertyAccessExpression(e,t):this.f.createElementAccessExpression(e,t),typeof e==`string`?this.makeId(e):e),void 0,n.map(e=>typeof e==`string`?this.makeId(e):e));makeNew=(e,...t)=>this.f.createNewExpression(this.makeId(e),void 0,t);makeExtract=(e,t)=>this.ensureTypeNode(`Extract`,[e,t]);makeAssignment=(e,t)=>this.f.createExpressionStatement(this.f.createBinaryExpression(typeof e==`string`?this.makeId(e):e,this.f.createToken(this.ts.SyntaxKind.EqualsToken),t));makeIndexed=(e,t)=>this.f.createIndexedAccessTypeNode(this.ensureTypeNode(e),this.ensureTypeNode(t));makeMaybeAsync=e=>this.makeUnion([this.ensureTypeNode(e),this.makePromise(e)]);makeFnType=(e,t)=>this.f.createFunctionTypeNode(void 0,this.makeParams(e),this.ensureTypeNode(t));literally=e=>typeof e==`number`?this.f.createNumericLiteral(e):typeof e==`bigint`?this.f.createBigIntLiteral(e.toString()):typeof e==`boolean`?e?this.f.createTrue():this.f.createFalse():e===null?this.f.createNull():this.f.createStringLiteral(e);makeLiteralType=e=>this.f.createLiteralTypeNode(this.literally(e));isPrimitive=e=>this.#e.includes(e.kind)};const X=e=>e;var Xn=class{api;paths=new Set;tags=new Map;registry=new Map;constructor(e,t){this.serverUrl=t,this.api=new Yn(e)}#e={pathType:`Path`,implementationType:`Implementation`,keyParameter:`key`,pathParameter:`path`,paramsArgument:`params`,ctxArgument:`ctx`,methodParameter:`method`,requestParameter:`request`,eventParameter:`event`,dataParameter:`data`,handlerParameter:`handler`,msgParameter:`msg`,parseRequestFn:`parseRequest`,substituteFn:`substitute`,provideMethod:`provide`,onMethod:`on`,implementationArgument:`implementation`,hasBodyConst:`hasBody`,undefinedValue:`undefined`,responseConst:`response`,restConst:`rest`,searchParamsConst:`searchParams`,defaultImplementationConst:`defaultImplementation`,clientConst:`client`,contentTypeConst:`contentType`,isJsonConst:`isJSON`,sourceProp:`source`,methodType:`Method`,someOfType:`SomeOf`,requestType:`Request`,paginationType:`Pagination`};interfaces={input:`Input`,positive:`PositiveResponse`,negative:`NegativeResponse`,encoded:`EncodedResponse`,response:`Response`};makeMethodType=()=>this.api.makePublicLiteralType(this.#e.methodType,le);makeSomeOfType=()=>this.api.makeType(this.#e.someOfType,this.api.makeIndexed(`T`,this.api.makeKeyOf(`T`)),{params:[`T`]});makeRequestType=()=>this.api.makeType(this.#e.requestType,this.api.makeKeyOf(this.interfaces.input),{expose:!0});someOf=({name:e})=>this.api.ensureTypeNode(this.#e.someOfType,[e]);makePathType=()=>this.api.makePublicLiteralType(this.#e.pathType,Array.from(this.paths));makePublicInterfaces=()=>Object.keys(this.interfaces).map(e=>this.api.makeInterface(this.interfaces[e],Array.from(this.registry).map(([t,{store:n,isDeprecated:r}])=>this.api.makeInterfaceProp(t,n[e],{isDeprecated:r})),{expose:!0}));makeEndpointTags=()=>this.api.makeConst(`endpointTags`,this.api.f.createObjectLiteralExpression(Array.from(this.tags).map(([e,t])=>this.api.f.createPropertyAssignment(this.api.makePropertyIdentifier(e),this.api.f.createArrayLiteralExpression(n.map(this.api.literally,t))))),{expose:!0});makeImplementationType=()=>this.api.makeType(this.#e.implementationType,this.api.makeFnType({[this.#e.methodParameter]:this.#e.methodType,[this.#e.pathParameter]:this.api.ts.SyntaxKind.StringKeyword,[this.#e.paramsArgument]:this.api.makeRecordStringAny(),[this.#e.ctxArgument]:{optional:!0,type:`T`}},this.api.makePromise(this.api.ts.SyntaxKind.AnyKeyword)),{expose:!0,params:{T:{init:this.api.ts.SyntaxKind.UnknownKeyword}}});makeParseRequestFn=()=>this.api.makeConst(this.#e.parseRequestFn,this.api.makeArrowFn({[this.#e.requestParameter]:this.api.ts.SyntaxKind.StringKeyword},this.api.f.createAsExpression(this.api.makeCall(this.#e.requestParameter,X(`split`))(this.api.f.createRegularExpressionLiteral(`/ (.+)/`),this.api.literally(2)),this.api.f.createTupleTypeNode([this.api.ensureTypeNode(this.#e.methodType),this.api.ensureTypeNode(this.#e.pathType)]))));makeSubstituteFn=()=>this.api.makeConst(this.#e.substituteFn,this.api.makeArrowFn({[this.#e.pathParameter]:this.api.ts.SyntaxKind.StringKeyword,[this.#e.paramsArgument]:this.api.makeRecordStringAny()},this.api.f.createBlock([this.api.makeConst(this.#e.restConst,this.api.f.createObjectLiteralExpression([this.api.f.createSpreadAssignment(this.api.makeId(this.#e.paramsArgument))])),this.api.f.createForInStatement(this.api.f.createVariableDeclarationList([this.api.f.createVariableDeclaration(this.#e.keyParameter)],this.api.ts.NodeFlags.Const),this.api.makeId(this.#e.paramsArgument),this.api.f.createBlock([this.api.makeAssignment(this.#e.pathParameter,this.api.makeCall(this.#e.pathParameter,X(`replace`))(this.api.makeTemplate(`:`,[this.#e.keyParameter]),this.api.makeArrowFn([],this.api.f.createBlock([this.api.f.createExpressionStatement(this.api.f.createDeleteExpression(this.api.f.createElementAccessExpression(this.api.makeId(this.#e.restConst),this.api.makeId(this.#e.keyParameter)))),this.api.f.createReturnStatement(this.api.f.createElementAccessExpression(this.api.makeId(this.#e.paramsArgument),this.api.makeId(this.#e.keyParameter)))]))))])),this.api.f.createReturnStatement(this.api.f.createAsExpression(this.api.f.createArrayLiteralExpression([this.api.makeId(this.#e.pathParameter),this.api.makeId(this.#e.restConst)]),this.api.ensureTypeNode(`const`)))])));makePaginationType=()=>{let e=X(`nextCursor`),t=X(`total`),n=X(`limit`),r=X(`offset`),i=this.api.f.createTypeLiteralNode([this.api.makeInterfaceProp(e,this.api.makeUnion([this.api.ensureTypeNode(this.api.ts.SyntaxKind.StringKeyword),this.api.makeLiteralType(null)]))]),a=this.api.f.createTypeLiteralNode([t,n,r].map(e=>this.api.makeInterfaceProp(e,this.api.ts.SyntaxKind.NumberKeyword)));return this.api.makeType(this.#e.paginationType,this.api.makeUnion([i,a]))};#t=()=>{let e=this.api.makeId(this.#e.responseConst),t=X(`nextCursor`),n=X(`total`),r=X(`limit`),i=X(`offset`),a=this.api.f.createBinaryExpression(this.api.literally(t),this.api.ts.SyntaxKind.InKeyword,e),o=this.api.f.createReturnStatement(this.api.f.createBinaryExpression(this.api.f.createPropertyAccessExpression(e,t),this.api.ts.SyntaxKind.ExclamationEqualsEqualsToken,this.api.literally(null))),s=this.api.f.createBinaryExpression(this.api.f.createPropertyAccessExpression(e,i),this.api.ts.SyntaxKind.PlusToken,this.api.f.createPropertyAccessExpression(e,r)),c=this.api.f.createReturnStatement(this.api.f.createBinaryExpression(s,this.api.ts.SyntaxKind.LessThanToken,this.api.f.createPropertyAccessExpression(e,n)));return this.api.makePublicMethod(`hasMore`,[this.api.makeParam(e,{type:this.#e.paginationType})],[this.api.f.createIfStatement(a,o),c],{returns:this.api.ensureTypeNode(this.api.ts.SyntaxKind.BooleanKeyword),isStatic:!0})};#n=()=>this.api.makePublicMethod(this.#e.provideMethod,this.api.makeParams({[this.#e.requestParameter]:`K`,[this.#e.paramsArgument]:this.api.makeIndexed(this.interfaces.input,`K`),[this.#e.ctxArgument]:{optional:!0,type:`T`}}),[this.api.makeConst(this.api.makeDeconstruction(this.#e.methodParameter,this.#e.pathParameter),this.api.makeCall(this.#e.parseRequestFn)(this.#e.requestParameter)),this.api.f.createReturnStatement(this.api.makeCall(this.api.f.createThis(),this.#e.implementationArgument)(this.#e.methodParameter,this.api.f.createSpreadElement(this.api.makeCall(this.#e.substituteFn)(this.#e.pathParameter,this.#e.paramsArgument)),this.#e.ctxArgument))],{typeParams:{K:this.#e.requestType},returns:this.api.makePromise(this.api.makeIndexed(this.interfaces.response,`K`))});makeClientClass=e=>this.api.makePublicClass(e,[this.api.makePublicConstructor([this.api.makeParam(this.#e.implementationArgument,{type:this.api.ensureTypeNode(this.#e.implementationType,[`T`]),mod:this.api.accessModifiers.protectedReadonly,initId:this.#e.defaultImplementationConst})]),this.#n(),this.#t()],{typeParams:[`T`]});#r=e=>this.api.makeTemplate(`?`,[this.api.makeNew(URLSearchParams.name,this.api.makeId(e))]);#i=()=>this.api.makeNew(URL.name,this.api.makeTemplate(``,[this.#e.pathParameter],[this.#e.searchParamsConst]),this.api.literally(this.serverUrl));makeDefaultImplementation=()=>{let e=this.api.f.createPropertyAssignment(X(`method`),this.api.makeCall(this.#e.methodParameter,X(`toUpperCase`))()),t=this.api.f.createPropertyAssignment(X(`headers`),this.api.makeTernary(this.#e.hasBodyConst,this.api.f.createObjectLiteralExpression([this.api.f.createPropertyAssignment(this.api.literally(`Content-Type`),this.api.literally(y.json))]),this.#e.undefinedValue)),n=this.api.f.createPropertyAssignment(X(`body`),this.api.makeTernary(this.#e.hasBodyConst,this.api.makeCall(JSON[Symbol.toStringTag],X(`stringify`))(this.#e.paramsArgument),this.#e.undefinedValue)),r=this.api.makeConst(this.#e.responseConst,this.api.f.createAwaitExpression(this.api.makeCall(fetch.name)(this.#i(),this.api.f.createObjectLiteralExpression([e,t,n])))),i=this.api.makeConst(this.#e.hasBodyConst,this.api.f.createLogicalNot(this.api.makeCall(this.api.f.createArrayLiteralExpression([this.api.literally(`get`),this.api.literally(`head`),this.api.literally(`delete`)]),X(`includes`))(this.#e.methodParameter))),a=this.api.makeConst(this.#e.searchParamsConst,this.api.makeTernary(this.#e.hasBodyConst,this.api.literally(``),this.#r(this.#e.paramsArgument))),o=this.api.makeConst(this.#e.contentTypeConst,this.api.makeCall(this.#e.responseConst,X(`headers`),X(`get`))(this.api.literally(`content-type`))),s=this.api.f.createIfStatement(this.api.f.createPrefixUnaryExpression(this.api.ts.SyntaxKind.ExclamationToken,this.api.makeId(this.#e.contentTypeConst)),this.api.f.createReturnStatement()),c=this.api.makeConst(this.#e.isJsonConst,this.api.makeCall(this.#e.contentTypeConst,X(`startsWith`))(this.api.literally(y.json))),l=this.api.f.createReturnStatement(this.api.makeCall(this.#e.responseConst,this.api.makeTernary(this.#e.isJsonConst,this.api.literally(X(`json`)),this.api.literally(X(`text`))))());return this.api.makeConst(this.#e.defaultImplementationConst,this.api.makeArrowFn([this.#e.methodParameter,this.#e.pathParameter,this.#e.paramsArgument],this.api.f.createBlock([i,a,r,o,s,c,l]),{isAsync:!0}),{type:this.#e.implementationType})};#a=()=>this.api.makePublicConstructor(this.api.makeParams({request:`K`,params:this.api.makeIndexed(this.interfaces.input,`K`)}),[this.api.makeConst(this.api.makeDeconstruction(this.#e.pathParameter,this.#e.restConst),this.api.makeCall(this.#e.substituteFn)(this.api.f.createElementAccessExpression(this.api.makeCall(this.#e.parseRequestFn)(this.#e.requestParameter),this.api.literally(1)),this.#e.paramsArgument)),this.api.makeConst(this.#e.searchParamsConst,this.#r(this.#e.restConst)),this.api.makeAssignment(this.api.f.createPropertyAccessExpression(this.api.f.createThis(),this.#e.sourceProp),this.api.makeNew(`EventSource`,this.#i()))]);#o=e=>this.api.f.createTypeLiteralNode([this.api.makeInterfaceProp(X(`event`),e)]);#s=()=>this.api.makePublicMethod(this.#e.onMethod,this.api.makeParams({[this.#e.eventParameter]:`E`,[this.#e.handlerParameter]:this.api.makeFnType({[this.#e.dataParameter]:this.api.makeIndexed(this.api.makeExtract(`R`,this.api.makeOneLine(this.#o(`E`))),this.api.makeLiteralType(X(`data`)))},this.api.makeMaybeAsync(this.api.ts.SyntaxKind.VoidKeyword))}),[this.api.f.createExpressionStatement(this.api.makeCall(this.api.f.createThis(),this.#e.sourceProp,X(`addEventListener`))(this.#e.eventParameter,this.api.makeArrowFn([this.#e.msgParameter],this.api.makeCall(this.#e.handlerParameter)(this.api.makeCall(JSON[Symbol.toStringTag],X(`parse`))(this.api.f.createPropertyAccessExpression(this.api.f.createParenthesizedExpression(this.api.f.createAsExpression(this.api.makeId(this.#e.msgParameter),this.api.ensureTypeNode(MessageEvent.name))),X(`data`))))))),this.api.f.createReturnStatement(this.api.f.createThis())],{typeParams:{E:this.api.makeIndexed(`R`,this.api.makeLiteralType(X(`event`)))}});makeSubscriptionClass=e=>this.api.makePublicClass(e,[this.api.makePublicProperty(this.#e.sourceProp,`EventSource`),this.#a(),this.#s()],{typeParams:{K:this.api.makeExtract(this.#e.requestType,this.api.f.createTemplateLiteralType(this.api.f.createTemplateHead(`get `),[this.api.f.createTemplateLiteralTypeSpan(this.api.ensureTypeNode(this.api.ts.SyntaxKind.StringKeyword),this.api.f.createTemplateTail(``))])),R:this.api.makeExtract(this.api.makeIndexed(this.interfaces.positive,`K`),this.api.makeOneLine(this.#o(this.api.ts.SyntaxKind.StringKeyword)))}});makeUsageStatements=(e,t)=>[this.api.makeConst(this.#e.clientConst,this.api.makeNew(e)),this.api.makeCall(this.#e.clientConst,this.#e.provideMethod)(this.api.literally(`get /v1/user/retrieve`),this.api.f.createObjectLiteralExpression([this.api.f.createPropertyAssignment(`id`,this.api.literally(`10`))])),this.api.makeCall(this.api.makeNew(t,this.api.literally(`get /v1/events/stream`),this.api.f.createObjectLiteralExpression()),this.#e.onMethod)(this.api.literally(`time`),this.api.makeArrowFn([`time`],this.api.f.createBlock([])))]};const Zn=(e,{rules:t,onMissing:n,ctx:r={}})=>{let i=O(e),a=i&&i in t?t[i]:t[e._zod.def.type],o=e=>Zn(e,{ctx:r,rules:t,onMissing:n});return a?a(e,{...r,next:o}):n(e,r)},Z={name:n.path([`name`,`text`]),type:n.path([`type`]),optional:n.path([`questionToken`])},Qn=({_zod:{def:e}},{api:t})=>{let n=e.values.map(e=>e===void 0?t.ensureTypeNode(t.ts.SyntaxKind.UndefinedKeyword):t.makeLiteralType(e));return n.length===1?n[0]:t.makeUnion(n)},$n=({_zod:{def:e}},{next:t,api:n})=>{let r=[...e.parts],i=()=>{let e=``;for(;r.length;){let t=r.shift();if(C(t)){r.unshift(t);break}e+=t??``}return e},a=n.f.createTemplateHead(i()),o=[];for(;r.length;){let e=t(r.shift()),a=i(),s=r.length?n.f.createTemplateMiddle:n.f.createTemplateTail;o.push(n.f.createTemplateLiteralTypeSpan(e,s(a)))}return o.length?n.f.createTemplateLiteralType(a,o):n.makeLiteralType(a.text)},er=(n,{isResponse:r,next:i,makeAlias:a,api:o})=>{let s=()=>{let a=Object.entries(n._zod.def.shape).map(([n,a])=>{let{description:s,deprecated:c}=e.get(a)||{},l=(r?a._zod.optout:a._zod.optin)===`optional`,u=l&&!(a instanceof t.core.$ZodExactOptional);return o.makeInterfaceProp(n,i(a),{comment:s,isDeprecated:c,isOptional:l,hasUndefined:u})});return o.f.createTypeLiteralNode(a)};return Re(n,{io:r?`output`:`input`})?a(n,s):s()},tr=({_zod:{def:e}},{next:t,api:n})=>n.f.createArrayTypeNode(t(e.element)),nr=({_zod:{def:e}},{api:t})=>t.makeUnion(n.map(t.makeLiteralType,Object.values(e.entries))),rr=({_zod:{def:e}},{next:t,api:n})=>n.makeUnion(e.options.map(t)),ir=({_zod:{def:e}},{next:t,api:n})=>n.makeUnion([t(e.innerType),n.makeLiteralType(null)]),ar=({_zod:{def:e}},{next:t,api:n})=>n.f.createTupleTypeNode(e.items.map(t).concat(e.rest===null?[]:n.f.createRestTypeNode(t(e.rest)))),or=({_zod:{def:e}},{next:t,api:n})=>{let[r,i]=[e.keyType,e.valueType].map(t),a=n.ensureTypeNode(`Record`,[r,i]);return e.mode===`loose`?n.f.createIntersectionTypeNode([a,n.ensureTypeNode(`Record`,[`PropertyKey`,i])]):a},sr=n.tryCatch((e,t)=>{if(!t.every(e.ts.isTypeLiteralNode))throw Error(`Not objects`);let r=n.chain(n.prop(`members`),t),i=n.uniqWith((...e)=>{if(!n.eqBy(Z.name,...e))return!1;if(n.both(n.eqBy(Z.type),n.eqBy(Z.optional))(...e))return!0;throw Error(`Has conflicting prop`)},r);return e.f.createTypeLiteralNode(i)},(e,t,n)=>t.f.createIntersectionTypeNode(n)),cr=({_zod:{def:e}},{next:t,api:n})=>sr(n,[e.left,e.right].map(t)),Q=e=>({},{api:t})=>t.ensureTypeNode(t.ts.SyntaxKind[e]),$=({_zod:{def:e}},{next:t})=>t(e.innerType),lr=(e,t)=>e.ensureTypeNode(t?e.ts.SyntaxKind.UnknownKeyword:e.ts.SyntaxKind.AnyKeyword),ur=({_zod:{def:e}},{next:t,isResponse:n,api:r})=>{let i=e[n?`out`:`in`],a=e[n?`in`:`out`];if(!C(i,`transform`))return t(i);let o=t(a),s={[r.ts.SyntaxKind.AnyKeyword]:``,[r.ts.SyntaxKind.BigIntKeyword]:BigInt(0),[r.ts.SyntaxKind.BooleanKeyword]:!1,[r.ts.SyntaxKind.NumberKeyword]:0,[r.ts.SyntaxKind.ObjectKeyword]:{},[r.ts.SyntaxKind.StringKeyword]:``,[r.ts.SyntaxKind.UndefinedKeyword]:void 0}[o.kind],c=be(i,s),l={number:r.ts.SyntaxKind.NumberKeyword,bigint:r.ts.SyntaxKind.BigIntKeyword,boolean:r.ts.SyntaxKind.BooleanKeyword,string:r.ts.SyntaxKind.StringKeyword,undefined:r.ts.SyntaxKind.UndefinedKeyword,object:r.ts.SyntaxKind.ObjectKeyword};return r.ensureTypeNode(c&&l[c]||lr(r,n))},dr=({},{api:e})=>e.makeLiteralType(null),fr=({_zod:{def:e}},{makeAlias:t,next:n})=>t(e.getter,()=>n(e.getter())),pr=({},{api:e})=>e.ensureTypeNode(`Buffer`),mr=(e,{next:t})=>t(e._zod.def.shape.raw),hr={string:Q(`StringKeyword`),number:Q(`NumberKeyword`),bigint:Q(`BigIntKeyword`),boolean:Q(`BooleanKeyword`),any:Q(`AnyKeyword`),undefined:Q(`UndefinedKeyword`),[j]:Q(`StringKeyword`),[M]:Q(`StringKeyword`),never:Q(`NeverKeyword`),void:Q(`UndefinedKeyword`),unknown:Q(`UnknownKeyword`),null:dr,array:tr,tuple:ar,record:or,object:er,literal:Qn,template_literal:$n,intersection:cr,union:rr,default:$,enum:nr,optional:$,nonoptional:$,nullable:ir,catch:$,pipe:ur,lazy:fr,readonly:$,[A]:pr,[L]:mr},gr=(e,{brandHandling:t,ctx:n})=>Zn(e,{rules:{...t,...hr},onMissing:({},{isResponse:e,api:t})=>lr(t,e),ctx:n});var _r=class e extends Xn{#e=[this.makeSomeOfType()];#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=this.api.makeLiteralType(null);this.#t.set(e,this.api.makeType(n,r)),this.#t.set(e,this.api.makeType(n,t()))}return this.api.ensureTypeNode(n)}constructor({typescript:e,routing:r,config:i,brandHandling:a,variant:o=`client`,clientClassName:s=`Client`,subscriptionClassName:c=`Subscription`,serverUrl:l=`https://example.com`,noBodySchema:u=t.undefined(),hasHeadMethod:d=!0}){super(e,l);let f={makeAlias:this.#r.bind(this),api:this.api},p={brandHandling:a,ctx:{...f,isResponse:!1}},m={brandHandling:a,ctx:{...f,isResponse:!0}},h=(e,t,r)=>{let i=T.bind(null,e,t),{isDeprecated:a,inputSchema:o,tags:s}=r,c=`${e} ${t}`,l=this.api.makeType(i(`input`),gr(o,p),{comment:c});this.#e.push(l);let d=Qe.reduce((t,a)=>{let o=r.getResponses(a),s=n.chain(([t,{schema:n,mimeTypes:r,statusCodes:o}])=>{let s=Se(e,r),l=this.api.makeType(i(a,`variant`,`${t+1}`),gr(s?n:u,m),{comment:c});return this.#e.push(l),o.map(e=>this.api.makeInterfaceProp(e,l.name))},Array.from(o.entries())),l=this.api.makeInterface(i(a,`response`,`variants`),s,{comment:c});return this.#e.push(l),Object.assign(t,{[a]:l})},{});this.paths.add(t);let f=this.api.makeLiteralType(c),h={input:this.api.ensureTypeNode(l.name),positive:this.someOf(d.positive),negative:this.someOf(d.negative),response:this.api.makeUnion([this.api.makeIndexed(this.interfaces.positive,f),this.api.makeIndexed(this.interfaces.negative,f)]),encoded:this.api.f.createIntersectionTypeNode([this.api.ensureTypeNode(d.positive.name),this.api.ensureTypeNode(d.negative.name)])};this.registry.set(c,{isDeprecated:a,store:h}),this.tags.set(c,s)};Tt({routing:r,config:i,onEndpoint:d?vt(h):h}),this.#e.unshift(...this.#t.values()),this.#e.push(this.makePathType(),this.makeMethodType(),...this.makePublicInterfaces(),this.makeRequestType()),o!==`types`&&(this.#e.push(this.makeEndpointTags(),this.makeParseRequestFn(),this.makeSubstituteFn(),this.makeImplementationType(),this.makePaginationType(),this.makeDefaultImplementation(),this.makeClientClass(s),this.makeSubscriptionClass(c)),this.#n.push(...this.makeUsageStatements(s,c)))}static async create(t){return new e({...t,typescript:await q(`typescript`)})}#i(e){return this.#n.length?this.#n.map(t=>typeof t==`string`?t:this.api.printNode(t,e)).join(`
19
18
  `):void 0}print(e){let t=this.#i(e),n=t&&this.api.ts.addSyntheticLeadingComment(this.api.ts.addSyntheticLeadingComment(this.api.f.createEmptyStatement(),this.api.ts.SyntaxKind.SingleLineCommentTrivia,` Usage example:`),this.api.ts.SyntaxKind.MultiLineCommentTrivia,`\n${t}`);return this.#e.concat(n||[]).map((t,n)=>this.api.printNode(t,n<this.#e.length?e:{...e,omitTrailingSemicolon:!0})).join(`
20
19
 
21
- `)}async printFormatted({printerOptions:e,format:t}={}){let n=t;if(!n)try{let e=(await J(`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 hr=(e,t)=>r.object({data:t,event:r.literal(e),id:r.string().optional(),retry:r.int().positive().optional()}),gr=(e,t,n)=>hr(String(t),e[t]).transform(e=>[`event: ${e.event}`,`data: ${JSON.stringify(e.data)}`,``,``].join(`
22
- `)).parse({event:t,data:n}),_r=e=>e.headersSent||e.writeHead(200,{connection:`keep-alive`,"content-type":x.sse,"cache-control":`no-cache`}),vr=e=>new V({handler:async({request:t,response:n})=>{let r=new AbortController;return t.once(`close`,()=>{r.abort()}),setTimeout(()=>_r(n),1e4),{isClosed:()=>n.writableEnded||n.closed,signal:r.signal,emit:(t,r)=>{_r(n),n.write(gr(e,t,r),`utf-8`),n.flush?.()}}}}),yr=e=>new U({positive:()=>{let[t,...n]=Object.entries(e).map(([e,t])=>hr(e,t));return{mimeType:x.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=z(t);Be(a,n,r,i),e.headersSent||e.status(a.statusCode).type(`text/plain`).write(B(a),`utf-8`)}e.end()}});var br=class extends G{constructor(e){super(yr(e)),this.middlewares=[vr(e)]}};const xr=[`total`,`limit`,`offset`],Sr=[`nextCursor`,`limit`];function Cr({style:e,itemSchema:t,itemsName:n=`items`,maxLimit:i=100,defaultLimit:a=20}){if(!Number.isInteger(i)||i<1)throw Error(`ez.paginated: maxLimit must be a positive integer`);if(!Number.isInteger(a)||a<1)throw Error(`ez.paginated: defaultLimit must be a positive integer`);if(a>i)throw Error(`ez.paginated: defaultLimit must not be greater than maxLimit`);if(e===`offset`&&xr.includes(n))throw Error(`ez.paginated: itemsName must not match reserved keys for offset output (${xr.join(`, `)})`);if(e===`cursor`&&Sr.includes(n))throw Error(`ez.paginated: itemsName must not match reserved keys for cursor output (${Sr.join(`, `)})`);let o=r.coerce.number().int().min(1).max(i).default(a).describe(`Page size (number of ${n} per page)`);if(e===`offset`){let e=r.coerce.number().int().min(0).default(0).describe(`Number of ${n} to skip`);return{input:r.object({limit:o,offset:e}),output:r.object({[n]:r.array(t).describe(`Page of ${n}`),total:r.number().int().min(0).describe(`Total number of ${n}`),limit:r.number().int().min(1).describe(`Page size used`),offset:r.number().int().min(0).describe(`Offset used`)})}}let s=r.string().optional().describe(`Cursor for the next page; omit for first page`);return{input:r.object({cursor:s,limit:o}),output:r.object({[n]:r.array(t).describe(`Page of ${n}`),nextCursor:r.string().nullable().describe(`Cursor for the next page, or null if no more pages`),limit:r.number().int().min(1).describe(`Page size used`)})}}const wr={dateIn:Se,dateOut:Ce,form:ke,upload:Ae,raw:Ne,buffer:xe,paginated:Cr};export{st as BuiltinLogger,Rn as Documentation,P as DocumentationError,G as EndpointsFactory,br as EventStreamFactory,I as InputValidationError,mr as Integration,V as Middleware,De as MissingPeerError,Te as OutputValidationError,U as ResultHandler,N as RoutingError,ct as ServeStatic,tt as arrayEndpointsFactory,$e as arrayResultHandler,qt as attachRouting,oe as createConfig,Jt as createServer,et as defaultEndpointsFactory,W as defaultResultHandler,z as ensureHttpError,wr as ez,w as getMessageFromError,Un as testEndpoint,Wn as testMiddleware};
20
+ `)}async printFormatted({printerOptions:e,format:t}={}){let n=t;if(!n)try{let e=(await q(`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 vr=(e,n)=>t.object({data:n,event:t.literal(e),id:t.string().optional(),retry:t.int().positive().optional()}),yr=(e,t,n)=>vr(String(t),e[t]).transform(e=>[`event: ${e.event}`,`data: ${JSON.stringify(e.data)}`,``,``].join(`
21
+ `)).parse({event:t,data:n}),br=e=>e.headersSent||e.writeHead(200,{connection:`keep-alive`,"content-type":y.sse,"cache-control":`no-cache`}),xr=e=>new B({handler:async({request:t,response:n})=>{let r=new AbortController;return t.once(`close`,()=>{r.abort()}),setTimeout(()=>br(n),1e4),{isClosed:()=>n.writableEnded||n.closed,signal:r.signal,emit:(t,r)=>{br(n),n.write(yr(e,t,r),`utf-8`),n.flush?.()}}}}),Sr=e=>new H({positive:()=>{let[n,...r]=Object.entries(e).map(([e,t])=>vr(e,t));return{mimeType:y.sse,schema:r.length?t.discriminatedUnion(`event`,[n,...r]):n}},negative:{mimeType:`text/plain`,schema:t.string()},handler:async({response:e,error:t,logger:n,request:r,input:i})=>{if(t){let a=R(t);Ue(a,n,r,i),e.headersSent||e.status(a.statusCode).type(`text/plain`).write(z(a),`utf-8`)}e.end()}});var Cr=class extends W{constructor(e){super(Sr(e)),this.middlewares=[xr(e)]}};const wr=[`total`,`limit`,`offset`],Tr=[`nextCursor`,`limit`];function Er({style:e,itemSchema:n,itemsName:r=`items`,maxLimit:i=100,defaultLimit:a=20}){if(!Number.isInteger(i)||i<1)throw Error(`ez.paginated: maxLimit must be a positive integer`);if(!Number.isInteger(a)||a<1)throw Error(`ez.paginated: defaultLimit must be a positive integer`);if(a>i)throw Error(`ez.paginated: defaultLimit must not be greater than maxLimit`);if(e===`offset`&&wr.includes(r))throw Error(`ez.paginated: itemsName must not match reserved keys for offset output (${wr.join(`, `)})`);if(e===`cursor`&&Tr.includes(r))throw Error(`ez.paginated: itemsName must not match reserved keys for cursor output (${Tr.join(`, `)})`);let o=t.coerce.number().int().min(1).max(i).default(a).describe(`Page size (number of ${r} per page)`);if(e===`offset`){let e=t.coerce.number().int().min(0).default(0).describe(`Number of ${r} to skip`);return{input:t.object({limit:o,offset:e}),output:t.object({[r]:t.array(n).describe(`Page of ${r}`),total:t.number().int().min(0).describe(`Total number of ${r}`),limit:t.number().int().min(1).describe(`Page size used`),offset:t.number().int().min(0).describe(`Offset used`)})}}let s=t.string().optional().describe(`Cursor for the next page; omit for first page`);return{input:t.object({cursor:s,limit:o}),output:t.object({[r]:t.array(n).describe(`Page of ${r}`),nextCursor:t.string().nullable().describe(`Cursor for the next page, or null if no more pages`),limit:t.number().int().min(1).describe(`Page size used`)})}}const Dr={dateIn:we,dateOut:Te,form:Me,upload:Ne,raw:Ie,buffer:Ce,paginated:Er};export{ut as BuiltinLogger,Hn as Documentation,P as DocumentationError,W as EndpointsFactory,Cr as EventStreamFactory,F as InputValidationError,_r as Integration,B as Middleware,Ae as MissingPeerError,Oe as OutputValidationError,H as ResultHandler,N as RoutingError,dt as ServeStatic,it as arrayEndpointsFactory,nt as arrayResultHandler,Xt as attachRouting,se as createConfig,Zt as createServer,rt as defaultEndpointsFactory,U as defaultResultHandler,R as ensureHttpError,Dr as ez,S as getMessageFromError,qn as testEndpoint,Jn as testMiddleware};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "express-zod-api",
3
- "version": "27.2.2",
3
+ "version": "28.0.0-beta.3",
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": {
@@ -16,7 +16,6 @@
16
16
  "bugs": "https://github.com/RobinTail/express-zod-api/issues",
17
17
  "funding": "https://github.com/sponsors/RobinTail",
18
18
  "type": "module",
19
- "sideEffects": true,
20
19
  "main": "dist/index.js",
21
20
  "types": "dist/index.d.ts",
22
21
  "module": "dist/index.js",
@@ -31,14 +30,13 @@
31
30
  "*.md"
32
31
  ],
33
32
  "engines": {
34
- "node": "^20.19.0 || ^22.12.0 || ^24.0.0"
33
+ "node": "^22.19.0 || ^24.0.0"
35
34
  },
36
35
  "dependencies": {
37
36
  "ansis": "^4.2.0",
38
37
  "node-mocks-http": "^1.17.2",
39
38
  "openapi3-ts": "^4.5.0",
40
- "ramda": "^0.32.0",
41
- "@express-zod-api/zod-plugin": "^4.1.0"
39
+ "ramda": "^0.32.0"
42
40
  },
43
41
  "peerDependencies": {
44
42
  "@types/compression": "^1.7.5",
@@ -50,9 +48,13 @@
50
48
  "express-fileupload": "^1.5.0",
51
49
  "http-errors": "^2.0.1",
52
50
  "typescript": "^5.1.3 || ^6.0.2",
53
- "zod": "^4.3.4"
51
+ "zod": "^4.3.4",
52
+ "@express-zod-api/zod-plugin": "^5.0.0-beta.3"
54
53
  },
55
54
  "peerDependenciesMeta": {
55
+ "@express-zod-api/zod-plugin": {
56
+ "optional": true
57
+ },
56
58
  "@types/compression": {
57
59
  "optional": true
58
60
  },
@@ -94,8 +96,9 @@
94
96
  "node-forge": "^1.3.3",
95
97
  "snakify-ts": "^2.3.0",
96
98
  "typescript": "^6.0.2",
97
- "undici": "^7.16.0",
98
- "zod": "^4.3.4"
99
+ "undici": "^8.0.0",
100
+ "zod": "^4.3.4",
101
+ "@express-zod-api/zod-plugin": "^5.0.0-beta.3"
99
102
  },
100
103
  "keywords": [
101
104
  "nodejs",
@@ -120,7 +123,7 @@
120
123
  "validation"
121
124
  ],
122
125
  "scripts": {
123
- "build": "tsdown --config-loader unrun",
126
+ "build": "tsdown",
124
127
  "pretest": "tsc",
125
128
  "test": "vitest run --coverage",
126
129
  "bench": "vitest bench --run ./bench"