express-zod-api 12.1.0 → 12.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -0
- package/README.md +52 -37
- package/dist/index.d.mts +55 -7
- package/dist/index.d.ts +55 -7
- package/dist/index.js +9 -9
- package/dist/index.mjs +9 -9
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,50 @@
|
|
|
2
2
|
|
|
3
3
|
## Version 12
|
|
4
4
|
|
|
5
|
+
### v12.3.0
|
|
6
|
+
|
|
7
|
+
- Featuring the ability to customize the `operationId` in the generated documentation.
|
|
8
|
+
- Using the new property of `EndpointsFactory::build()` method you can now override the value of the
|
|
9
|
+
corresponding `operationId` of the endpoint in generated documentation.
|
|
10
|
+
- When using this feature, you must ensure the uniqness of the IDs you specified across your API endpoints.
|
|
11
|
+
- The feature is implemented by [@john-schmitz](https://github.com/john-schmitz).
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { defaultEndpointsFactory } from "express-zod-api";
|
|
15
|
+
|
|
16
|
+
defaultEndpointsFactory.build({
|
|
17
|
+
operationId: "SampleOperation",
|
|
18
|
+
// ...
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### v12.2.0
|
|
23
|
+
|
|
24
|
+
- Featuring a new input source: `headers`.
|
|
25
|
+
- This is an opt-in feature requiring you to specify `headers` entry in the `inputSources` of your configuration.
|
|
26
|
+
- The feature is limited to custom headers only (the ones starting with `x-` prefix).
|
|
27
|
+
- The headers are lowercase when describing their validation schema.
|
|
28
|
+
- Parameters in request headers described the following way are supported by the documentation generator.
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { createConfig, defaultEndpointsFactory } from "express-zod-api";
|
|
32
|
+
import { z } from "zod";
|
|
33
|
+
|
|
34
|
+
createConfig({
|
|
35
|
+
inputSources: {
|
|
36
|
+
get: ["query", "headers"],
|
|
37
|
+
}, // ...
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
defaultEndpointsFactory.build({
|
|
41
|
+
method: "get",
|
|
42
|
+
input: z.object({
|
|
43
|
+
"x-request-id": z.string(), // this one is from request.headers
|
|
44
|
+
id: z.string(), // this one is from request.query
|
|
45
|
+
}), // ...
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
5
49
|
### v12.1.0
|
|
6
50
|
|
|
7
51
|
- This version fixes the issue 1182 introduced in version 10.0.0-beta1, manifesting as Typescript errors `TS4023` and
|
package/README.md
CHANGED
|
@@ -43,12 +43,13 @@ Start your API server with I/O schema validation and custom middlewares in minut
|
|
|
43
43
|
15. [Multiple schemas for one route](#multiple-schemas-for-one-route)
|
|
44
44
|
16. [Serving static files](#serving-static-files)
|
|
45
45
|
17. [Customizing input sources](#customizing-input-sources)
|
|
46
|
-
18. [
|
|
47
|
-
19. [Enabling
|
|
48
|
-
20. [
|
|
49
|
-
21. [
|
|
50
|
-
22. [
|
|
51
|
-
23. [
|
|
46
|
+
18. [Headers as input source](#headers-as-input-source)
|
|
47
|
+
19. [Enabling compression](#enabling-compression)
|
|
48
|
+
20. [Enabling HTTPS](#enabling-https)
|
|
49
|
+
21. [Generating a Frontend Client](#generating-a-frontend-client)
|
|
50
|
+
22. [Creating a documentation](#creating-a-documentation)
|
|
51
|
+
23. [Tagging the endpoints](#tagging-the-endpoints)
|
|
52
|
+
24. [How to test endpoints](#how-to-test-endpoints)
|
|
52
53
|
5. [Caveats](#caveats)
|
|
53
54
|
1. [Coercive schema of Zod](#coercive-schema-of-zod)
|
|
54
55
|
2. [Excessive properties in endpoint output](#excessive-properties-in-endpoint-output)
|
|
@@ -224,8 +225,8 @@ It's _not optional_ to draw your attention to making the appropriate decision, h
|
|
|
224
225
|
[Quick start example](#set-up-config) above, assuming that in most cases you will want to enable this feature.
|
|
225
226
|
See [MDN article](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) for more information.
|
|
226
227
|
|
|
227
|
-
In addition to being a boolean, `cors` can also be assigned a function that
|
|
228
|
-
has several parameters and can be asynchronous.
|
|
228
|
+
In addition to being a boolean, `cors` can also be assigned a function that overrides default CORS headers.
|
|
229
|
+
That function has several parameters and can be asynchronous.
|
|
229
230
|
|
|
230
231
|
```typescript
|
|
231
232
|
import { createConfig } from "express-zod-api";
|
|
@@ -247,32 +248,6 @@ Please note: If you only want to send specific headers on requests to a specific
|
|
|
247
248
|
Middleware can authenticate using input or `request` headers, and can provide endpoint handlers with `options`.
|
|
248
249
|
Inputs of middlewares are also available to endpoint handlers within `input`.
|
|
249
250
|
|
|
250
|
-
Here is an example on how to provide headers of the request.
|
|
251
|
-
|
|
252
|
-
```typescript
|
|
253
|
-
import { createMiddleware } from "express-zod-api";
|
|
254
|
-
|
|
255
|
-
const headersProviderMiddleware = createMiddleware({
|
|
256
|
-
input: z.object({}), // means no inputs
|
|
257
|
-
middleware: async ({ request }) => ({
|
|
258
|
-
headers: request.headers,
|
|
259
|
-
}),
|
|
260
|
-
});
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
By using `.addMiddleware()` method before `.build()` you can connect it to the endpoint:
|
|
264
|
-
|
|
265
|
-
```typescript
|
|
266
|
-
const yourEndpoint = defaultEndpointsFactory
|
|
267
|
-
.addMiddleware(headersProviderMiddleware)
|
|
268
|
-
.build({
|
|
269
|
-
// ...,
|
|
270
|
-
handler: async ({ options }) => {
|
|
271
|
-
// options.headers === request.headers
|
|
272
|
-
},
|
|
273
|
-
});
|
|
274
|
-
```
|
|
275
|
-
|
|
276
251
|
Here is an example of the authentication middleware, that checks a `key` from input and `token` from headers:
|
|
277
252
|
|
|
278
253
|
```typescript
|
|
@@ -304,6 +279,19 @@ const authMiddleware = createMiddleware({
|
|
|
304
279
|
});
|
|
305
280
|
```
|
|
306
281
|
|
|
282
|
+
By using `.addMiddleware()` method before `.build()` you can connect it to the endpoint:
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
const yourEndpoint = defaultEndpointsFactory
|
|
286
|
+
.addMiddleware(authMiddleware)
|
|
287
|
+
.build({
|
|
288
|
+
// ...,
|
|
289
|
+
handler: async ({ options }) => {
|
|
290
|
+
// options.user is the user returned by authMiddleware
|
|
291
|
+
},
|
|
292
|
+
});
|
|
293
|
+
```
|
|
294
|
+
|
|
307
295
|
You can connect the middleware to endpoints factory right away, making it kind of global:
|
|
308
296
|
|
|
309
297
|
```typescript
|
|
@@ -735,13 +723,13 @@ const routing: Routing = {
|
|
|
735
723
|
## Customizing input sources
|
|
736
724
|
|
|
737
725
|
You can customize the list of `request` properties that are combined into `input` that is being validated and available
|
|
738
|
-
to your endpoints and middlewares.
|
|
726
|
+
to your endpoints and middlewares. The order here matters: each next item in the array has a higher priority than its
|
|
727
|
+
previous sibling.
|
|
739
728
|
|
|
740
729
|
```typescript
|
|
741
730
|
import { createConfig } from "express-zod-api";
|
|
742
731
|
|
|
743
732
|
createConfig({
|
|
744
|
-
// ...,
|
|
745
733
|
inputSources: {
|
|
746
734
|
// the defaults are:
|
|
747
735
|
get: ["query", "params"],
|
|
@@ -749,7 +737,34 @@ createConfig({
|
|
|
749
737
|
put: ["body", "params"],
|
|
750
738
|
patch: ["body", "params"],
|
|
751
739
|
delete: ["query", "params"],
|
|
752
|
-
},
|
|
740
|
+
}, // ...
|
|
741
|
+
});
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
## Headers as input source
|
|
745
|
+
|
|
746
|
+
In a similar way you can enable the inclusion of request headers into the input sources. This is an opt-in feature.
|
|
747
|
+
Please note:
|
|
748
|
+
|
|
749
|
+
- only the custom headers (the ones having `x-` prefix) will be combined into the `input`,
|
|
750
|
+
- the request headers acquired that way are lowercase when describing their validation schemas.
|
|
751
|
+
|
|
752
|
+
```typescript
|
|
753
|
+
import { createConfig, defaultEndpointsFactory } from "express-zod-api";
|
|
754
|
+
import { z } from "zod";
|
|
755
|
+
|
|
756
|
+
createConfig({
|
|
757
|
+
inputSources: {
|
|
758
|
+
get: ["query", "headers"],
|
|
759
|
+
}, // ...
|
|
760
|
+
});
|
|
761
|
+
|
|
762
|
+
defaultEndpointsFactory.build({
|
|
763
|
+
method: "get",
|
|
764
|
+
input: z.object({
|
|
765
|
+
"x-request-id": z.string(), // this one is from request.headers
|
|
766
|
+
id: z.string(), // this one is from request.query
|
|
767
|
+
}), // ...
|
|
753
768
|
});
|
|
754
769
|
```
|
|
755
770
|
|
package/dist/index.d.mts
CHANGED
|
@@ -134,8 +134,8 @@ type MethodsDefinition<M extends Method> = {
|
|
|
134
134
|
};
|
|
135
135
|
|
|
136
136
|
type FlatObject = Record<string, any>;
|
|
137
|
-
declare
|
|
138
|
-
declare
|
|
137
|
+
declare const getMessageFromError: (error: Error) => string;
|
|
138
|
+
declare const getStatusCodeFromError: (error: Error) => number;
|
|
139
139
|
declare const getExamples: <T extends z.ZodTypeAny, V extends "original" | "parsed" | undefined>({ schema, variant, validate, }: {
|
|
140
140
|
schema: T;
|
|
141
141
|
/**
|
|
@@ -439,6 +439,7 @@ declare abstract class AbstractEndpoint {
|
|
|
439
439
|
abstract getScopes(): string[];
|
|
440
440
|
abstract getTags(): string[];
|
|
441
441
|
abstract _setSiblingMethods(methods: Method[]): void;
|
|
442
|
+
abstract getOperationId(): string | undefined;
|
|
442
443
|
}
|
|
443
444
|
type EndpointProps<IN extends IOSchema, OUT extends IOSchema, OPT extends FlatObject, M extends Method, POS extends z.ZodTypeAny, NEG extends z.ZodTypeAny, SCO extends string, TAG extends string> = {
|
|
444
445
|
middlewares: AnyMiddlewareDef[];
|
|
@@ -448,6 +449,7 @@ type EndpointProps<IN extends IOSchema, OUT extends IOSchema, OPT extends FlatOb
|
|
|
448
449
|
resultHandler: ResultHandlerDefinition<POS, NEG>;
|
|
449
450
|
description?: string;
|
|
450
451
|
shortDescription?: string;
|
|
452
|
+
operationId?: string;
|
|
451
453
|
} & ({
|
|
452
454
|
scopes?: SCO[];
|
|
453
455
|
} | {
|
|
@@ -476,6 +478,7 @@ declare class Endpoint<IN extends IOSchema, OUT extends IOSchema, OPT extends Fl
|
|
|
476
478
|
getSecurity(): LogicalContainer<Security>;
|
|
477
479
|
getScopes(): SCO[];
|
|
478
480
|
getTags(): TAG[];
|
|
481
|
+
getOperationId(): string | undefined;
|
|
479
482
|
execute({ request, response, logger, config, }: {
|
|
480
483
|
request: Request;
|
|
481
484
|
response: Response;
|
|
@@ -496,24 +499,43 @@ interface LoggerConfig {
|
|
|
496
499
|
type UploadOptions = Pick<fileUpload.Options, "createParentPath" | "uriDecodeFileNames" | "safeFileNames" | "preserveExtension" | "useTempFiles" | "tempFileDir" | "debug" | "uploadTimeout">;
|
|
497
500
|
type CompressionOptions = Pick<compression.CompressionOptions, "threshold" | "level" | "strategy" | "chunkSize" | "memLevel">;
|
|
498
501
|
interface ServerConfig {
|
|
502
|
+
/** @desc Server configuration. */
|
|
499
503
|
server: {
|
|
504
|
+
/** @desc Port or socket. */
|
|
500
505
|
listen: number | string;
|
|
506
|
+
/**
|
|
507
|
+
* @desc Custom JSON parser.
|
|
508
|
+
* @default express.json()
|
|
509
|
+
* */
|
|
501
510
|
jsonParser?: NextHandleFunction;
|
|
511
|
+
/**
|
|
512
|
+
* @desc Enable or configure uploads handling.
|
|
513
|
+
* @default false
|
|
514
|
+
* */
|
|
502
515
|
upload?: boolean | UploadOptions;
|
|
516
|
+
/**
|
|
517
|
+
* @desc Enable or configure response compression.
|
|
518
|
+
* @default false
|
|
519
|
+
*/
|
|
503
520
|
compression?: boolean | CompressionOptions;
|
|
504
521
|
};
|
|
522
|
+
/** @desc Enables HTTPS server as well. */
|
|
505
523
|
https?: {
|
|
524
|
+
/** @desc At least "cert" and "key" options required. */
|
|
506
525
|
options: ServerOptions;
|
|
526
|
+
/** @desc Port or socket. */
|
|
507
527
|
listen: number | string;
|
|
508
528
|
};
|
|
509
529
|
}
|
|
510
530
|
interface AppConfig {
|
|
531
|
+
/** @desc Your custom express app instead. */
|
|
511
532
|
app: Express;
|
|
512
533
|
}
|
|
513
|
-
type InputSource = keyof Pick<Request, "query" | "body" | "files" | "params">;
|
|
534
|
+
type InputSource = keyof Pick<Request, "query" | "body" | "files" | "params" | "headers">;
|
|
514
535
|
type InputSources = Record<Method, InputSource[]>;
|
|
515
536
|
type Headers = Record<string, string>;
|
|
516
537
|
type HeadersProvider = (params: {
|
|
538
|
+
/** @desc The default headers to be overridden. */
|
|
517
539
|
defaultHeaders: Headers;
|
|
518
540
|
request: Request;
|
|
519
541
|
endpoint: AbstractEndpoint;
|
|
@@ -524,11 +546,36 @@ type TagsConfig<TAG extends string> = Record<TAG, string | {
|
|
|
524
546
|
url?: string;
|
|
525
547
|
}>;
|
|
526
548
|
interface CommonConfig<TAG extends string = string> {
|
|
549
|
+
/**
|
|
550
|
+
* @desc Enables cross-origin resource sharing.
|
|
551
|
+
* @link https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
|
552
|
+
* @desc You can override the default CORS headers by setting up a provider function here.
|
|
553
|
+
*/
|
|
527
554
|
cors: boolean | HeadersProvider;
|
|
555
|
+
/**
|
|
556
|
+
* @desc Custom ResultHandlerDefinition for common errors.
|
|
557
|
+
* @default defaultResultHandler
|
|
558
|
+
* @see defaultResultHandler
|
|
559
|
+
*/
|
|
528
560
|
errorHandler?: ResultHandlerDefinition<any, any>;
|
|
561
|
+
/** @desc Logger configuration or your custom winston logger. */
|
|
529
562
|
logger: LoggerConfig | Logger;
|
|
563
|
+
/**
|
|
564
|
+
* @desc You can disable the startup logo.
|
|
565
|
+
* @default true
|
|
566
|
+
*/
|
|
530
567
|
startupLogo?: boolean;
|
|
568
|
+
/**
|
|
569
|
+
* @desc Which properties of request are combined into the input for endpoints and middlewares.
|
|
570
|
+
* @desc The order matters: priority from lowest to highest
|
|
571
|
+
* @default defaultInputSources
|
|
572
|
+
* @see defaultInputSources
|
|
573
|
+
*/
|
|
531
574
|
inputSources?: Partial<InputSources>;
|
|
575
|
+
/**
|
|
576
|
+
* @desc Optional endpoints tagging configuration.
|
|
577
|
+
* @example: { users: "Everything about the users" }
|
|
578
|
+
*/
|
|
532
579
|
tags?: TagsConfig<TAG>;
|
|
533
580
|
}
|
|
534
581
|
declare const createConfig: <TAG extends string, T extends (ServerConfig | AppConfig) & CommonConfig<TAG>>(config: T) => T;
|
|
@@ -539,6 +586,7 @@ type BuildProps<IN extends IOSchema, OUT extends IOSchema, MIN extends IOSchema<
|
|
|
539
586
|
handler: Handler<z.output<ProbableIntersection<MIN, IN>>, z.input<OUT>, OPT>;
|
|
540
587
|
description?: string;
|
|
541
588
|
shortDescription?: string;
|
|
589
|
+
operationId?: string;
|
|
542
590
|
} & ({
|
|
543
591
|
scopes?: SCO[];
|
|
544
592
|
} | {
|
|
@@ -688,7 +736,7 @@ declare const arrayEndpointsFactory: EndpointsFactory<z.ZodArray<any, "many"> &
|
|
|
688
736
|
example: (example: string) => z.ZodString & any;
|
|
689
737
|
}, null, {}, string, string>;
|
|
690
738
|
|
|
691
|
-
declare
|
|
739
|
+
declare const createLogger: (loggerConfig: LoggerConfig) => winston.Logger;
|
|
692
740
|
|
|
693
741
|
declare class DependsOnMethod {
|
|
694
742
|
readonly methods: {
|
|
@@ -711,11 +759,11 @@ interface Routing {
|
|
|
711
759
|
[SEGMENT: string]: Routing | DependsOnMethod | AbstractEndpoint | ServeStatic;
|
|
712
760
|
}
|
|
713
761
|
|
|
714
|
-
declare
|
|
762
|
+
declare const attachRouting: (config: AppConfig & CommonConfig, routing: Routing) => {
|
|
715
763
|
notFoundHandler: express.RequestHandler<express_serve_static_core.ParamsDictionary, any, any, qs.ParsedQs, Record<string, any>>;
|
|
716
764
|
logger: Logger;
|
|
717
765
|
};
|
|
718
|
-
declare
|
|
766
|
+
declare const createServer: (config: ServerConfig & CommonConfig, routing: Routing) => {
|
|
719
767
|
app: express_serve_static_core.Express;
|
|
720
768
|
httpServer: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>;
|
|
721
769
|
httpsServer: https.Server<typeof http.IncomingMessage, typeof http.ServerResponse> | undefined;
|
|
@@ -747,7 +795,7 @@ declare class Documentation extends OpenApiBuilder {
|
|
|
747
795
|
protected lastOperationIdSuffixes: Record<string, number>;
|
|
748
796
|
protected makeRef(name: string, schema: SchemaObject | ReferenceObject): ReferenceObject;
|
|
749
797
|
protected getRef(name: string): ReferenceObject | undefined;
|
|
750
|
-
protected ensureUniqOperationId(path: string, method: Method): string;
|
|
798
|
+
protected ensureUniqOperationId(path: string, method: Method, userDefinedOperationId?: string): string;
|
|
751
799
|
protected ensureUniqSecuritySchemaName(subject: SecuritySchemeObject): string;
|
|
752
800
|
constructor({ routing, config, title, version, serverUrl, successfulResponseDescription, errorResponseDescription, hasSummaryFromDescription, composition, serializer, }: DocumentationParams);
|
|
753
801
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -134,8 +134,8 @@ type MethodsDefinition<M extends Method> = {
|
|
|
134
134
|
};
|
|
135
135
|
|
|
136
136
|
type FlatObject = Record<string, any>;
|
|
137
|
-
declare
|
|
138
|
-
declare
|
|
137
|
+
declare const getMessageFromError: (error: Error) => string;
|
|
138
|
+
declare const getStatusCodeFromError: (error: Error) => number;
|
|
139
139
|
declare const getExamples: <T extends z.ZodTypeAny, V extends "original" | "parsed" | undefined>({ schema, variant, validate, }: {
|
|
140
140
|
schema: T;
|
|
141
141
|
/**
|
|
@@ -439,6 +439,7 @@ declare abstract class AbstractEndpoint {
|
|
|
439
439
|
abstract getScopes(): string[];
|
|
440
440
|
abstract getTags(): string[];
|
|
441
441
|
abstract _setSiblingMethods(methods: Method[]): void;
|
|
442
|
+
abstract getOperationId(): string | undefined;
|
|
442
443
|
}
|
|
443
444
|
type EndpointProps<IN extends IOSchema, OUT extends IOSchema, OPT extends FlatObject, M extends Method, POS extends z.ZodTypeAny, NEG extends z.ZodTypeAny, SCO extends string, TAG extends string> = {
|
|
444
445
|
middlewares: AnyMiddlewareDef[];
|
|
@@ -448,6 +449,7 @@ type EndpointProps<IN extends IOSchema, OUT extends IOSchema, OPT extends FlatOb
|
|
|
448
449
|
resultHandler: ResultHandlerDefinition<POS, NEG>;
|
|
449
450
|
description?: string;
|
|
450
451
|
shortDescription?: string;
|
|
452
|
+
operationId?: string;
|
|
451
453
|
} & ({
|
|
452
454
|
scopes?: SCO[];
|
|
453
455
|
} | {
|
|
@@ -476,6 +478,7 @@ declare class Endpoint<IN extends IOSchema, OUT extends IOSchema, OPT extends Fl
|
|
|
476
478
|
getSecurity(): LogicalContainer<Security>;
|
|
477
479
|
getScopes(): SCO[];
|
|
478
480
|
getTags(): TAG[];
|
|
481
|
+
getOperationId(): string | undefined;
|
|
479
482
|
execute({ request, response, logger, config, }: {
|
|
480
483
|
request: Request;
|
|
481
484
|
response: Response;
|
|
@@ -496,24 +499,43 @@ interface LoggerConfig {
|
|
|
496
499
|
type UploadOptions = Pick<fileUpload.Options, "createParentPath" | "uriDecodeFileNames" | "safeFileNames" | "preserveExtension" | "useTempFiles" | "tempFileDir" | "debug" | "uploadTimeout">;
|
|
497
500
|
type CompressionOptions = Pick<compression.CompressionOptions, "threshold" | "level" | "strategy" | "chunkSize" | "memLevel">;
|
|
498
501
|
interface ServerConfig {
|
|
502
|
+
/** @desc Server configuration. */
|
|
499
503
|
server: {
|
|
504
|
+
/** @desc Port or socket. */
|
|
500
505
|
listen: number | string;
|
|
506
|
+
/**
|
|
507
|
+
* @desc Custom JSON parser.
|
|
508
|
+
* @default express.json()
|
|
509
|
+
* */
|
|
501
510
|
jsonParser?: NextHandleFunction;
|
|
511
|
+
/**
|
|
512
|
+
* @desc Enable or configure uploads handling.
|
|
513
|
+
* @default false
|
|
514
|
+
* */
|
|
502
515
|
upload?: boolean | UploadOptions;
|
|
516
|
+
/**
|
|
517
|
+
* @desc Enable or configure response compression.
|
|
518
|
+
* @default false
|
|
519
|
+
*/
|
|
503
520
|
compression?: boolean | CompressionOptions;
|
|
504
521
|
};
|
|
522
|
+
/** @desc Enables HTTPS server as well. */
|
|
505
523
|
https?: {
|
|
524
|
+
/** @desc At least "cert" and "key" options required. */
|
|
506
525
|
options: ServerOptions;
|
|
526
|
+
/** @desc Port or socket. */
|
|
507
527
|
listen: number | string;
|
|
508
528
|
};
|
|
509
529
|
}
|
|
510
530
|
interface AppConfig {
|
|
531
|
+
/** @desc Your custom express app instead. */
|
|
511
532
|
app: Express;
|
|
512
533
|
}
|
|
513
|
-
type InputSource = keyof Pick<Request, "query" | "body" | "files" | "params">;
|
|
534
|
+
type InputSource = keyof Pick<Request, "query" | "body" | "files" | "params" | "headers">;
|
|
514
535
|
type InputSources = Record<Method, InputSource[]>;
|
|
515
536
|
type Headers = Record<string, string>;
|
|
516
537
|
type HeadersProvider = (params: {
|
|
538
|
+
/** @desc The default headers to be overridden. */
|
|
517
539
|
defaultHeaders: Headers;
|
|
518
540
|
request: Request;
|
|
519
541
|
endpoint: AbstractEndpoint;
|
|
@@ -524,11 +546,36 @@ type TagsConfig<TAG extends string> = Record<TAG, string | {
|
|
|
524
546
|
url?: string;
|
|
525
547
|
}>;
|
|
526
548
|
interface CommonConfig<TAG extends string = string> {
|
|
549
|
+
/**
|
|
550
|
+
* @desc Enables cross-origin resource sharing.
|
|
551
|
+
* @link https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
|
552
|
+
* @desc You can override the default CORS headers by setting up a provider function here.
|
|
553
|
+
*/
|
|
527
554
|
cors: boolean | HeadersProvider;
|
|
555
|
+
/**
|
|
556
|
+
* @desc Custom ResultHandlerDefinition for common errors.
|
|
557
|
+
* @default defaultResultHandler
|
|
558
|
+
* @see defaultResultHandler
|
|
559
|
+
*/
|
|
528
560
|
errorHandler?: ResultHandlerDefinition<any, any>;
|
|
561
|
+
/** @desc Logger configuration or your custom winston logger. */
|
|
529
562
|
logger: LoggerConfig | Logger;
|
|
563
|
+
/**
|
|
564
|
+
* @desc You can disable the startup logo.
|
|
565
|
+
* @default true
|
|
566
|
+
*/
|
|
530
567
|
startupLogo?: boolean;
|
|
568
|
+
/**
|
|
569
|
+
* @desc Which properties of request are combined into the input for endpoints and middlewares.
|
|
570
|
+
* @desc The order matters: priority from lowest to highest
|
|
571
|
+
* @default defaultInputSources
|
|
572
|
+
* @see defaultInputSources
|
|
573
|
+
*/
|
|
531
574
|
inputSources?: Partial<InputSources>;
|
|
575
|
+
/**
|
|
576
|
+
* @desc Optional endpoints tagging configuration.
|
|
577
|
+
* @example: { users: "Everything about the users" }
|
|
578
|
+
*/
|
|
532
579
|
tags?: TagsConfig<TAG>;
|
|
533
580
|
}
|
|
534
581
|
declare const createConfig: <TAG extends string, T extends (ServerConfig | AppConfig) & CommonConfig<TAG>>(config: T) => T;
|
|
@@ -539,6 +586,7 @@ type BuildProps<IN extends IOSchema, OUT extends IOSchema, MIN extends IOSchema<
|
|
|
539
586
|
handler: Handler<z.output<ProbableIntersection<MIN, IN>>, z.input<OUT>, OPT>;
|
|
540
587
|
description?: string;
|
|
541
588
|
shortDescription?: string;
|
|
589
|
+
operationId?: string;
|
|
542
590
|
} & ({
|
|
543
591
|
scopes?: SCO[];
|
|
544
592
|
} | {
|
|
@@ -688,7 +736,7 @@ declare const arrayEndpointsFactory: EndpointsFactory<z.ZodArray<any, "many"> &
|
|
|
688
736
|
example: (example: string) => z.ZodString & any;
|
|
689
737
|
}, null, {}, string, string>;
|
|
690
738
|
|
|
691
|
-
declare
|
|
739
|
+
declare const createLogger: (loggerConfig: LoggerConfig) => winston.Logger;
|
|
692
740
|
|
|
693
741
|
declare class DependsOnMethod {
|
|
694
742
|
readonly methods: {
|
|
@@ -711,11 +759,11 @@ interface Routing {
|
|
|
711
759
|
[SEGMENT: string]: Routing | DependsOnMethod | AbstractEndpoint | ServeStatic;
|
|
712
760
|
}
|
|
713
761
|
|
|
714
|
-
declare
|
|
762
|
+
declare const attachRouting: (config: AppConfig & CommonConfig, routing: Routing) => {
|
|
715
763
|
notFoundHandler: express.RequestHandler<express_serve_static_core.ParamsDictionary, any, any, qs.ParsedQs, Record<string, any>>;
|
|
716
764
|
logger: Logger;
|
|
717
765
|
};
|
|
718
|
-
declare
|
|
766
|
+
declare const createServer: (config: ServerConfig & CommonConfig, routing: Routing) => {
|
|
719
767
|
app: express_serve_static_core.Express;
|
|
720
768
|
httpServer: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>;
|
|
721
769
|
httpsServer: https.Server<typeof http.IncomingMessage, typeof http.ServerResponse> | undefined;
|
|
@@ -747,7 +795,7 @@ declare class Documentation extends OpenApiBuilder {
|
|
|
747
795
|
protected lastOperationIdSuffixes: Record<string, number>;
|
|
748
796
|
protected makeRef(name: string, schema: SchemaObject | ReferenceObject): ReferenceObject;
|
|
749
797
|
protected getRef(name: string): ReferenceObject | undefined;
|
|
750
|
-
protected ensureUniqOperationId(path: string, method: Method): string;
|
|
798
|
+
protected ensureUniqOperationId(path: string, method: Method, userDefinedOperationId?: string): string;
|
|
751
799
|
protected ensureUniqSecuritySchemaName(subject: SecuritySchemeObject): string;
|
|
752
800
|
constructor({ routing, config, title, version, serverUrl, successfulResponseDescription, errorResponseDescription, hasSummaryFromDescription, composition, serializer, }: DocumentationParams);
|
|
753
801
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var Ar=Object.create;var Pe=Object.defineProperty;var Ir=Object.getOwnPropertyDescriptor;var Cr=Object.getOwnPropertyNames;var Nr=Object.getPrototypeOf,wr=Object.prototype.hasOwnProperty;var wt=(e,t)=>{for(var r in t)Pe(e,r,{get:t[r],enumerable:!0})},Mt=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Cr(t))!wr.call(e,n)&&n!==r&&Pe(e,n,{get:()=>t[n],enumerable:!(o=Ir(t,n))||o.enumerable});return e};var R=(e,t,r)=>(r=e!=null?Ar(Nr(e)):{},Mt(t||!e||!e.__esModule?Pe(r,"default",{value:e,enumerable:!0}):r,e)),Mr=e=>Mt(Pe({},"__esModule",{value:!0}),e);var un={};wt(un,{AbstractEndpoint:()=>X,DependsOnMethod:()=>le,DependsOnMethodError:()=>se,Documentation:()=>Fe,DocumentationError:()=>P,EndpointsFactory:()=>pe,InputValidationError:()=>U,Integration:()=>Be,OutputValidationError:()=>V,RoutingError:()=>Q,ServeStatic:()=>me,arrayEndpointsFactory:()=>Gt,arrayResultHandler:()=>ze,attachRouting:()=>Xt,createConfig:()=>zt,createHttpError:()=>Zr.default,createLogger:()=>Oe,createMiddleware:()=>Le,createResultHandler:()=>De,createServer:()=>er,defaultEndpointsFactory:()=>_t,defaultResultHandler:()=>W,ez:()=>Ct,getExamples:()=>k,getMessageFromError:()=>L,getStatusCodeFromError:()=>xe,testEndpoint:()=>mr,withMeta:()=>j});module.exports=Mr(un);var Dt={silent:!0,warn:!0,debug:!0},zt=e=>e;var F=require("zod");var kt=require("http-errors"),Ht=require("crypto"),b=require("zod");var Ze=require("ramda"),E="expressZodApiMeta",Dr=e=>{let t=e.constructor,r=(0,Ze.clone)(e._def);return r[E]=r[E]||{examples:[]},new t(r)},j=e=>{let t=Dr(e);return Object.defineProperties(t,{example:{get:()=>r=>{let o=j(t);return o._def[E].examples.push(r),o}}}),t},vt=e=>E in e._def?typeof e._def[E]=="object"&&e._def[E]!==null:!1,jt=(e,t)=>{if(!vt(e))return;let r=e._def;return t in r[E]?r[E][t]:void 0},Ee=(e,t)=>{if(!vt(e))return t;let r=j(t),o=ye(r._def[E].examples,e._def[E].examples);if(r._def[E].examples=[],o.type==="single")r._def[E].examples=o.value;else for(let[n,s]of o.value)r._def[E].examples.push((0,Ze.mergeDeepRight)({...n},{...s}));return r};var Lt=R(require("mime")),J=Lt.default.getType("json")||"application/json",ge="multipart/form-data";var C=require("zod"),zr="ZodUpload",vr=e=>typeof e=="object"&&e!==null&&"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.mimetype=="string"&&typeof e.data=="object"&&typeof e.tempFilePath=="string"&&typeof e.truncated=="boolean"&&typeof e.size=="number"&&typeof e.md5=="string"&&typeof e.mv=="function",oe=class e extends C.ZodType{_parse(t){let{ctx:r}=this._processInputParams(t);return r.parsedType!==C.ZodParsedType.object||!vr(r.data)?((0,C.addIssueToContext)(r,{code:C.ZodIssueCode.custom,message:`Expected file upload, received ${r.parsedType}`}),C.INVALID):(0,C.OK)(r.data)}static create=()=>new e({typeName:zr})};var et=/:([A-Za-z0-9_]+)/g,jr=e=>{let r=(e.header("content-type")||"").slice(0,ge.length).toLowerCase()===ge;return"files"in e&&r},Ae={get:["query","params"],post:["body","params","files"],put:["body","params"],patch:["body","params"],delete:["query","params"]},Lr=["body","query","params"],tt=e=>e.method.toLowerCase(),rt=e=>e.startsWith("x-"),kr=e=>Object.entries(e.headers).reduce((t,[r,o])=>rt(r)?{...t,[r]:o}:t,{}),Ut=(e,t)=>{let r=tt(e);if(r==="options")return{};let o=Lr;return r in Ae&&(o=Ae[r]),t&&r in t&&(o=t[r]||o),o.filter(n=>n==="files"?jr(e):!0).reduce((n,s)=>({...n,...s==="headers"?kr(e):e[s]}),{})},ot=e=>typeof e=="object"&&"level"in e&&"color"in e&&Object.keys(Dt).includes(e.level)&&typeof e.color=="boolean",Ie=e=>!isNaN(e.getTime()),ne=e=>e instanceof Error?e:new Error(typeof e=="symbol"?e.toString():`${e}`),L=e=>e instanceof b.z.ZodError?e.issues.map(({path:t,message:r})=>(t.length?[t.join("/")]:[]).concat(r).join(": ")).join("; "):e instanceof V?`output${e.originalError.issues[0]?.path.length>0?"/":": "}${e.message}`:e.message,xe=e=>e instanceof kt.HttpError?e.statusCode:e instanceof U?400:500,nt=({logger:e,request:t,input:r,error:o,statusCode:n})=>{n===500&&e.error(`Internal server error
|
|
2
2
|
${o.stack}
|
|
3
|
-
`,{url:t.url,payload:r})},
|
|
4
|
-
Caused by ${n?"response":"input"} schema of an Endpoint assigned to ${r.toUpperCase()} method of ${o} path.`;super(s)}},
|
|
5
|
-
Original error: ${e.originalError.message}.`:""))};var
|
|
3
|
+
`,{url:t.url,payload:r})},k=({schema:e,variant:t="original",validate:r=t==="parsed"})=>{let o=jt(e,"examples")||[];if(!r&&t==="original")return o;let n=[];for(let s of o){let a=e.safeParse(s);a.success&&n.push(t==="parsed"?a.data:s)}return n},ye=(e,t)=>{if(e.length===0)return{type:"single",value:t};if(t.length===0)return{type:"single",value:e};let r=[];for(let o of e)for(let n of t)r.push([o,n]);return{type:"tuple",value:r}},st=e=>{let t=e.match(et);return t?t.map(r=>r.slice(1)):[]},he=e=>e.reduce((t,r)=>t||r,!1),q=e=>e instanceof b.z.ZodEffects&&e._def.effect.type!=="refinement"?!0:e instanceof b.z.ZodUnion?he(e.options.map(q)):e instanceof b.z.ZodIntersection?he([e._def.left,e._def.right].map(q)):!1,M=e=>e instanceof oe?!0:e instanceof b.z.ZodObject?he(Object.values(e.shape).map(M)):e instanceof b.z.ZodUnion?he(e.options.map(M)):e instanceof b.z.ZodIntersection?he([e._def.left,e._def.right].map(M)):e instanceof b.z.ZodOptional||e instanceof b.z.ZodNullable?M(e.unwrap()):e instanceof b.z.ZodEffects||e instanceof b.z.ZodTransformer?M(e._def.schema):e instanceof b.z.ZodRecord?M(e._def.valueType):e instanceof b.z.ZodArray?M(e._def.type):e instanceof b.z.ZodDefault?M(e._def.innerType):!1,Te=e=>"coerce"in e._def&&typeof e._def.coerce=="boolean"?e._def.coerce:!1,H=(e,t,r)=>[t].concat(e.split("/")).concat(r||[]).flatMap(o=>o.split(/[^A-Z0-9]/gi)).map(o=>o.slice(0,1).toUpperCase()+o.slice(1).toLowerCase()).join(""),Ce=e=>(0,Ht.createHash)("sha1").update(JSON.stringify(e),"utf8").digest("hex"),Ne=({effect:e,sample:t})=>{try{return typeof e.transform(t,{addIssue:()=>{},path:[]})}catch{return}},it=e=>typeof e=="string"?{message:e}:e||{};var Q=class extends Error{name="RoutingError"},se=class extends Q{name="DependsOnMethodError"},P=class extends Error{name="DocumentationError";constructor({message:t,method:r,path:o,isResponse:n}){let s=`${t}
|
|
4
|
+
Caused by ${n?"response":"input"} schema of an Endpoint assigned to ${r.toUpperCase()} method of ${o} path.`;super(s)}},B=class extends Error{name="IOSchemaError"},V=class extends B{name="OutputValidationError";originalError;constructor(t){super(L(t)),this.originalError=t}},U=class extends B{name="InputValidationError";originalError;constructor(t){super(L(t)),this.originalError=t}},ie=class extends Error{name="ResultHandlerError";originalError;constructor(t,r){super(t),this.originalError=r||void 0}};var K=e=>typeof e=="object"&&e!==null,we=e=>({and:e.reduce((t,r)=>t.concat(K(r)&&"and"in r?r.and:r),[])}),Me=(e,t)=>{if(K(e)){if("and"in e)return{and:e.and.map(r=>K(r)&&"or"in r?{or:r.or.map(t)}:t(r))};if("or"in e)return{or:e.or.map(r=>K(r)&&"and"in r?{and:r.and.map(t)}:t(r))}}return t(e)},at=e=>e.and.reduce((t,r)=>{let o=ye(t.or,K(r)&&"or"in r?r.or:[r]);return o.type==="single"?t.or.push(...o.value):t.or=o.value.map(we),t},{or:[]}),ae=(e,t)=>{if(K(e)){if("and"in e){if(K(t)){if("and"in t)return we([e,t]);if("or"in t)return ae(at(e),t)}return we([e,t])}if("or"in e){if(K(t)){if("and"in t)return ae(t,e);if("or"in t){let r=ye(e.or,t.or);return{or:r.type==="single"?r.value:r.value.map(we)}}}return ae(e,{and:[t]})}}return K(t)&&("and"in t||"or"in t)?ae(t,e):{and:[e,t]}};var w=require("zod");var de={positive:200,negative:400},De=e=>e,W=De({getPositiveResponse:e=>{let t=k({schema:e}),r=j(w.z.object({status:w.z.literal("success"),data:e}));return t.reduce((o,n)=>o.example({status:"success",data:n}),r)},getNegativeResponse:()=>j(w.z.object({status:w.z.literal("error"),error:w.z.object({message:w.z.string()})})).example({status:"error",error:{message:L(new Error("Sample error message"))}}),handler:({error:e,input:t,output:r,request:o,response:n,logger:s})=>{if(!e){n.status(de.positive).json({status:"success",data:r});return}let a=xe(e);nt({logger:s,statusCode:a,request:o,error:e,input:t}),n.status(a).json({status:"error",error:{message:L(e)}})}}),ze=De({getPositiveResponse:e=>{let t=k({schema:e}),r=j("shape"in e&&"items"in e.shape&&e.shape.items instanceof w.z.ZodArray?e.shape.items:w.z.array(w.z.any()));return t.reduce((o,n)=>typeof n=="object"&&n!==null&&"items"in n&&Array.isArray(n.items)?o.example(n.items):o,r)},getNegativeResponse:()=>j(w.z.string()).example(L(new Error("Sample error message"))),handler:({response:e,output:t,error:r,logger:o,request:n,input:s})=>{if(r){let a=xe(r);nt({logger:o,statusCode:a,request:n,error:r,input:s}),e.status(a).send(r.message);return}"items"in t&&Array.isArray(t.items)?e.status(200).json(t.items):e.status(500).send("Property 'items' is missing in the endpoint output")}}),ve=({error:e,logger:t,response:r})=>{t.error(`Result handler failure: ${e.message}.`),r.status(500).end(`An error occurred while serving the result: ${e.message}.`+(e.originalError?`
|
|
5
|
+
Original error: ${e.originalError.message}.`:""))};var Kt=(e,t=[J])=>{if(e instanceof F.z.ZodType)return t;let{mimeTypes:r,mimeType:o}=e;return o?[o]:r||t},X=class{},je=class extends X{#e;#t=[];#i=[];#o=[];#a;#d;#p;#c;#r;#n=[];#s=[];#l;constructor({middlewares:t,inputSchema:r,outputSchema:o,handler:n,resultHandler:s,description:a,shortDescription:p,...d}){super(),[{name:"input schema",schema:r},{name:"output schema",schema:o}].forEach(({name:l,schema:g})=>{if(q(g))throw new B(`Using transformations on the top level of endpoint ${l} is not allowed.`)}),this.#o=t,this.#l=d.operationId;let c={positive:s.getPositiveResponse(o),negative:s.getNegativeResponse()};this.#a={input:M(r)?[ge]:[J],positive:Kt(c.positive),negative:Kt(c.negative)},this.#r={input:r,output:o,positive:c.positive instanceof F.z.ZodType?c.positive:c.positive.schema,negative:c.negative instanceof F.z.ZodType?c.negative:c.negative.schema},this.#d={positive:c.positive instanceof F.z.ZodType?de.positive:c.positive.statusCode||de.positive,negative:c.negative instanceof F.z.ZodType?de.negative:c.negative.statusCode||de.negative},this.#p=n,this.#c=s,this.#e={long:a,short:p},"scopes"in d&&d.scopes&&this.#n.push(...d.scopes),"scope"in d&&d.scope&&this.#n.push(d.scope),"tags"in d&&d.tags&&this.#s.push(...d.tags),"tag"in d&&d.tag&&this.#s.push(d.tag),"methods"in d?this.#t=d.methods:this.#t=[d.method]}_setSiblingMethods(t){this.#i=t}getDescription(t){return this.#e[t]}getMethods(){return this.#t}getSchema(t){return this.#r[t]}getMimeTypes(t){return this.#a[t]}getStatusCode(t){return this.#d[t]}getSecurity(){return this.#o.reduce((t,r)=>r.security?ae(t,r.security):t,{and:[]})}getScopes(){return this.#n}getTags(){return this.#s}getOperationId(){return this.#l}#m(){return{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":this.#t.concat(this.#i).concat("options").join(", ").toUpperCase(),"Access-Control-Allow-Headers":"content-type"}}async#u(t){try{return await this.#r.output.parseAsync(t)}catch(r){throw r instanceof F.z.ZodError?new V(r):r}}async#f({method:t,input:r,request:o,response:n,logger:s}){let a={},p=!1;for(let d of this.#o){if(t==="options"&&d.type==="proprietary")continue;let c;try{c=await d.input.parseAsync(r)}catch(l){throw l instanceof F.z.ZodError?new U(l):l}if(Object.assign(a,await d.middleware({input:c,options:a,request:o,response:n,logger:s})),p="writableEnded"in n&&n.writableEnded,p){s.warn(`The middleware ${d.middleware.name} has closed the stream. Accumulated options:`,a);break}}return{options:a,isStreamClosed:p}}async#y({input:t,options:r,logger:o}){let n;try{n=await this.#r.input.parseAsync(t)}catch(s){throw s instanceof F.z.ZodError?new U(s):s}return this.#p({input:n,options:r,logger:o})}async#g({error:t,request:r,response:o,logger:n,input:s,output:a}){try{await this.#c.handler({error:t,output:a,request:r,response:o,logger:n,input:s})}catch(p){ve({logger:n,response:o,error:new ie(ne(p).message,t)})}}async execute({request:t,response:r,logger:o,config:n}){let s=tt(t),a,p=null;if(n.cors){let c=this.#m();typeof n.cors=="function"&&(c=await n.cors({request:t,logger:o,endpoint:this,defaultHeaders:c}));for(let l in c)r.set(l,c[l])}let d=Ut(t,n.inputSources);try{let{options:c,isStreamClosed:l}=await this.#f({method:s,input:d,request:t,response:r,logger:o});if(l)return;if(s==="options"){r.status(200).end();return}a=await this.#u(await this.#y({input:d,options:c,logger:o}))}catch(c){p=ne(c)}await this.#g({input:d,output:a,request:t,response:r,error:p,logger:o})}};var Ft=["get","post","put","delete","patch"];var dt=require("zod");var $t=(e,t)=>{let r=e.map(({input:n})=>n).concat(t),o=r.reduce((n,s)=>n.and(s));return r.reduce((n,s)=>Ee(s,n),o)};var Le=e=>{if(q(e.input))throw new B("Using transformations on the top level of middleware input schema is not allowed.");return{...e,type:"proprietary"}};var pe=class e{resultHandler;middlewares=[];constructor(t){this.resultHandler="resultHandler"in t?t.resultHandler:t}static#e(t,r){let o=new e(r);return o.middlewares=t,o}addMiddleware(t){return e.#e(this.middlewares.concat(t),this.resultHandler)}use=this.addExpressMiddleware;addExpressMiddleware(t,r){let o=r?.transformer||(a=>a),n=r?.provider||(()=>({})),s={type:"express",input:dt.z.object({}),middleware:async({request:a,response:p})=>new Promise((d,c)=>{t(a,p,g=>{if(g&&g instanceof Error)return c(o(g));d(n(a,p))})})};return e.#e(this.middlewares.concat(s),this.resultHandler)}addOptions(t){return e.#e(this.middlewares.concat(Le({input:dt.z.object({}),middleware:async()=>t})),this.resultHandler)}build({input:t,handler:r,output:o,...n}){let{middlewares:s,resultHandler:a}=this;return new je({handler:r,middlewares:s,outputSchema:o,resultHandler:a,inputSchema:$t(s,t),...n})}},_t=new pe(W),Gt=new pe(ze);var qt=require("util"),ce=require("triple-beam"),Se=R(require("winston")),{combine:Hr,colorize:Ur,timestamp:Kr,printf:Fr}=Se.default.format,Oe=e=>{let t=s=>{let{[ce.LEVEL]:a,[ce.MESSAGE]:p,[ce.SPLAT]:d,...c}=s;return(0,qt.inspect)(c,!1,1,e.color)},r=s=>Fr(({timestamp:a,message:p,level:d,durationMs:c,...l})=>(typeof p=="object"&&(l={...l,...p},p="[No message]"),`${a} ${d}: ${p}`+(c===void 0?"":` duration: ${c}ms`)+(Object.keys(l).length===0?"":" "+(s?t(l):JSON.stringify(l))))),o=[Kr()],n={handleExceptions:!0};switch(e.color&&o.push(Ur()),e.level){case"debug":n.level="debug",o.push(r(!0));break;case"silent":case"warn":default:n.level="warn",o.push(r())}return n.format=Hr(...o),Se.default.createLogger({silent:e.level==="silent",levels:Se.default.config.npm.levels,transports:[new Se.default.transports.Console(n)],exitOnError:!1})};var le=class{constructor(t){this.methods=t;Object.keys(t).forEach(r=>{if(r in t&&!(t[r]?.getMethods()||[]).includes(r))throw new se(`The endpoint assigned to the '${r}' parameter must have at least this method in its specification.
|
|
6
6
|
This error should prevent mistakes during the development process.
|
|
7
7
|
Example:
|
|
8
8
|
|
|
@@ -13,8 +13,8 @@ new ${this.constructor.name}({
|
|
|
13
13
|
...
|
|
14
14
|
})
|
|
15
15
|
});
|
|
16
|
-
`)})}};var
|
|
17
|
-
The error caused by ${o?`'${o}' route that has a '${s}'`:`'${s}'`} entry.`);let p=`${o||""}${s?`/${s}`:""}`;if(a instanceof X){let d=a.getMethods().slice();n&&d.push("options"),d.forEach(c=>{t(a,p,c)})}else if(a instanceof me)r&&a.apply(p,r);else if(a instanceof le){if(Object.entries(a.methods).forEach(([d,c])=>{t(c,p,d)}),n&&Object.keys(a.methods).length>0){let[d,...c]=Object.keys(a.methods),l=a.methods[d];l._setSiblingMethods(c),t(l,p,"options")}}else ee({onEndpoint:t,onStatic:r,hasCors:n,routing:a,parentPath:p})})};var
|
|
16
|
+
`)})}};var Vt=R(require("express")),me=class{params;constructor(...t){this.params=t}apply(t,r){return r(t,Vt.default.static(...this.params))}};var ee=({routing:e,onEndpoint:t,onStatic:r,parentPath:o,hasCors:n})=>{Object.entries(e).forEach(([s,a])=>{if(s=s.trim(),s.match(/\//))throw new Q(`Routing elements should not contain '/' character.
|
|
17
|
+
The error caused by ${o?`'${o}' route that has a '${s}'`:`'${s}'`} entry.`);let p=`${o||""}${s?`/${s}`:""}`;if(a instanceof X){let d=a.getMethods().slice();n&&d.push("options"),d.forEach(c=>{t(a,p,c)})}else if(a instanceof me)r&&a.apply(p,r);else if(a instanceof le){if(Object.entries(a.methods).forEach(([d,c])=>{t(c,p,d)}),n&&Object.keys(a.methods).length>0){let[d,...c]=Object.keys(a.methods),l=a.methods[d];l._setSiblingMethods(c),t(l,p,"options")}}else ee({onEndpoint:t,onStatic:r,hasCors:n,routing:a,parentPath:p})})};var Bt=()=>`
|
|
18
18
|
\x1B[94m\x1B[39m
|
|
19
19
|
\x1B[94m\x1B[39m
|
|
20
20
|
\x1B[94m8888888888 8888888888P 888 d8888 8888888b. 8888888 \x1B[39m
|
|
@@ -31,7 +31,7 @@ The error caused by ${o?`'${o}' route that has a '${s}'`:`'${s}'`} entry.`);let
|
|
|
31
31
|
\x1B[90m\x1B[3m Thank you for choosing Express Zod API for your project.\x1B[23m\x1B[39m\x1B[0m\x1B[0m
|
|
32
32
|
\x1B[0m\x1B[0m
|
|
33
33
|
\x1B[0m\x1B[0m
|
|
34
|
-
`.trim();var at=({app:e,logger:t,config:r,routing:o})=>{r.startupLogo!==!1&&console.log(qt()),ee({routing:o,hasCors:!!r.cors,onEndpoint:(n,s,a)=>{e[a](s,async(p,d)=>{t.info(`${p.method}: ${s}`),await n.execute({request:p,response:d,logger:t,config:r})})},onStatic:(n,s)=>{e.use(n,s)}})};var Ue=b(require("express")),Vt=b(require("compression")),Bt=b(require("express-fileupload")),Yt=b(require("https"));var dt=b(require("http-errors")),Hr=(e,t)=>(r,o,n,s)=>{if(!r)return s();e.handler({error:(0,dt.default)(400,ne(r).message),request:o,response:n,logger:t,input:o.body,output:null})},Jt=(e,t)=>(r,o)=>{let n=(0,dt.default)(404,`Can not ${r.method} ${r.path}`);try{e.handler({request:r,response:o,logger:t,error:n,input:null,output:null})}catch(s){je({response:o,logger:t,error:new ie(ne(s).message,n)})}};function Qt(e,t){let r=tt(e.logger)?Re(e.logger):e.logger;at({app:e.app,routing:t,logger:r,config:e});let o=e.errorHandler||W;return{notFoundHandler:Jt(o,r),logger:r}}function Wt(e,t){let r=tt(e.logger)?Re(e.logger):e.logger,o=(0,Ue.default)();o.disable("x-powered-by");let n=e.errorHandler||W,s=e.server.compression?(0,Vt.default)({...typeof e.server.compression=="object"?e.server.compression:{}}):void 0,a=e.server.jsonParser||(0,Ue.json)(),p=e.server.upload?(0,Bt.default)({...typeof e.server.upload=="object"?e.server.upload:{},abortOnLimit:!1,parseNested:!0}):void 0,d=[].concat(s||[]).concat(a).concat(p||[]);o.use(d),o.use(Hr(n,r)),at({app:o,routing:t,logger:r,config:e}),o.use(Jt(n,r));let c=o.listen(e.server.listen,()=>{r.info(`Listening ${e.server.listen}`)}),l;return e.https&&(l=Yt.default.createServer(e.https.options,o).listen(e.https.listen,()=>{r.info(`Listening ${e.https.listen}`)})),{app:o,httpServer:c,httpsServer:l,logger:r}}var pr=require("openapi3-ts/oas30");var F=require("openapi3-ts/oas30"),ue=require("ramda"),x=require("zod");var T=require("zod");var pt=/^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d+)?)?Z?$/,Kr="ZodDateIn",He=class e extends T.ZodType{_parse(t){let{status:r,ctx:o}=this._processInputParams(t);if(o.parsedType!==T.ZodParsedType.string)return(0,T.addIssueToContext)(o,{code:T.ZodIssueCode.invalid_type,expected:T.ZodParsedType.string,received:o.parsedType}),T.INVALID;pt.test(o.data)||((0,T.addIssueToContext)(o,{code:T.ZodIssueCode.invalid_string,validation:"regex"}),r.dirty());let n=new Date(o.data);return Ce(n)?{status:r.value,value:n}:((0,T.addIssueToContext)(o,{code:T.ZodIssueCode.invalid_date}),T.INVALID)}static create=()=>new e({typeName:Kr})};var te=({schema:e,onEach:t,rules:r,onMissing:o,...n})=>{let s="typeName"in e._def?r[e._def.typeName]:void 0,p=s?s({schema:e,...n,next:c=>te({...c,...n,onEach:t,rules:r,onMissing:o})}):o({schema:e,...n}),d=t&&t({schema:e,prev:p,...n});return d?{...p,...d}:p};var Xt=50,tr="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString",Fr={integer:0,number:0,string:"",boolean:!1,object:{},null:null,array:[]},rr=e=>e.replace(Xe,t=>`{${t.slice(1)}}`),$r=({schema:{_def:{innerType:e,defaultValue:t}},next:r})=>({...r({schema:e}),default:t()}),_r=({schema:{_def:{innerType:e}},next:t})=>t({schema:e}),Gr=()=>({format:"any"}),qr=e=>{if(e.isResponse)throw new C({message:"Please use z.upload() only for input.",...e});return{type:"string",format:"binary"}},Vr=({schema:{isBinary:e,isBase64:t},...r})=>{if(!r.isResponse)throw new C({message:"Please use z.file() only within ResultHandler.",...r});return{type:"string",format:e?"binary":t?"byte":"file"}},Br=({schema:{options:e},next:t})=>({oneOf:e.map(r=>t({schema:r}))}),Yr=({schema:{options:e,discriminator:t},next:r})=>({discriminator:{propertyName:t},oneOf:Array.from(e.values()).map(o=>r({schema:o}))}),Jr=({schema:{_def:{left:e,right:t}},next:r})=>({allOf:[e,t].map(o=>r({schema:o}))}),Qr=({schema:e,next:t})=>t({schema:e.unwrap()}),Wr=({schema:e,next:t})=>t({schema:e._def.innerType}),Xr=({schema:e,next:t})=>({nullable:!0,...t({schema:e.unwrap()})}),er=({schema:e})=>({type:typeof Object.values(e.enum)[0],enum:Object.values(e.enum)}),eo=({schema:{value:e}})=>({type:typeof e,enum:[e]}),to=({schema:e,isResponse:t,...r})=>{let o=Object.keys(e.shape).filter(n=>{let s=e.shape[n];return!(t&&Oe(s)?s instanceof x.z.ZodOptional:s.isOptional())});return{type:"object",properties:Ke({schema:e,isResponse:t,...r}),...o.length?{required:o}:{}}},ro=()=>({type:"string",nullable:!0,format:"null"}),oo=e=>{if(e.isResponse)throw new C({message:"Please use z.dateOut() for output.",...e});return{description:"YYYY-MM-DDTHH:mm:ss.sssZ",type:"string",format:"date-time",pattern:pt.source,externalDocs:{url:tr}}},no=e=>{if(!e.isResponse)throw new C({message:"Please use z.dateIn() for input.",...e});return{description:"YYYY-MM-DDTHH:mm:ss.sssZ",type:"string",format:"date-time",externalDocs:{url:tr}}},so=e=>{throw new C({message:`Using z.date() within ${e.isResponse?"output":"input"} schema is forbidden. Please use z.date${e.isResponse?"Out":"In"}() instead. Check out the documentation for details.`,...e})},io=()=>({type:"boolean"}),ao=()=>({type:"integer",format:"bigint"}),po=({schema:{keySchema:e,valueSchema:t},...r})=>{if(e instanceof x.z.ZodEnum||e instanceof x.z.ZodNativeEnum){let o=Object.values(e.enum),n=o.reduce((s,a)=>({...s,[a]:t}),{});return{type:"object",properties:Ke({schema:x.z.object(n),...r}),...o.length?{required:o}:{}}}if(e instanceof x.z.ZodLiteral)return{type:"object",properties:Ke({schema:x.z.object({[e.value]:t}),...r}),required:[e.value]};if(e instanceof x.z.ZodUnion&&e.options.reduce((n,s)=>n&&s instanceof x.z.ZodLiteral,!0)){let n=e.options.reduce((s,a)=>({...s,[a.value]:t}),{});return{type:"object",properties:Ke({schema:x.z.object(n),...r}),required:e.options.map(s=>s.value)}}return{type:"object",additionalProperties:r.next({schema:t})}},co=({schema:{_def:e,element:t},next:r})=>({type:"array",items:r({schema:t}),...e.minLength!==null&&{minItems:e.minLength.value},...e.maxLength!==null&&{maxItems:e.maxLength.value}}),lo=({schema:{items:e},next:t})=>{let r=e.map(o=>t({schema:o}));return{type:"array",minItems:r.length,maxItems:r.length,items:{oneOf:r,format:"tuple",...r.length>0&&{description:r.map((o,n)=>`${n}: ${(0,F.isSchemaObject)(o)?o.type:o.$ref}`).join(", ")}}}},mo=({schema:{isEmail:e,isURL:t,minLength:r,maxLength:o,isUUID:n,isCUID:s,isCUID2:a,isULID:p,isIP:d,isEmoji:c,isDatetime:l,_def:{checks:h}}})=>{let g=h.find(f=>f.kind==="regex"),S=h.find(f=>f.kind==="datetime"),P=g?g.regex:S?S.offset?new RegExp("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(([+-]\\d{2}:\\d{2})|Z)$"):new RegExp("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"):void 0;return{type:"string",...l&&{format:"date-time"},...e&&{format:"email"},...t&&{format:"url"},...n&&{format:"uuid"},...s&&{format:"cuid"},...a&&{format:"cuid2"},...p&&{format:"ulid"},...d&&{format:"ip"},...c&&{format:"emoji"},...r!==null&&{minLength:r},...o!==null&&{maxLength:o},...P&&{pattern:`/${P.source}/${P.flags}`}}},uo=({schema:e})=>{let t=e._def.checks.find(({kind:s})=>s==="min"),r=t?t.inclusive:!0,o=e._def.checks.find(({kind:s})=>s==="max"),n=o?o.inclusive:!0;return{type:e.isInt?"integer":"number",format:e.isInt?"int64":"double",minimum:e.minValue===null?e.isInt?Number.MIN_SAFE_INTEGER:Number.MIN_VALUE:e.minValue,exclusiveMinimum:!r,maximum:e.maxValue===null?e.isInt?Number.MAX_SAFE_INTEGER:Number.MAX_VALUE:e.maxValue,exclusiveMaximum:!n}},Ke=({schema:{shape:e},next:t})=>Object.keys(e).reduce((r,o)=>({...r,[o]:t({schema:e[o]})}),{}),fo=e=>{let t=Array.isArray(e.type)?e.type[0]:e.type;return Fr?.[t]},yo=({schema:e,isResponse:t,next:r})=>{let o=r({schema:e.innerType()}),{effect:n}=e._def;if(t&&n.type==="transform"&&(0,F.isSchemaObject)(o)){let s=Me({effect:n,sample:fo(o)});return s&&["number","string","boolean"].includes(s)?{type:s}:r({schema:x.z.any()})}if(!t&&n.type==="preprocess"&&(0,F.isSchemaObject)(o)){let{type:s,...a}=o;return{...a,format:`${a.format||s} (preprocessed)`}}return o},go=({schema:e,isResponse:t,next:r})=>r({schema:e._def[t?"out":"in"]}),ho=({schema:e,next:t})=>t({schema:e.unwrap()}),xo=({next:e,schema:t,serializer:r,getRef:o,makeRef:n})=>{let s=r(t.schema);return o(s)||(()=>(n(s,{}),n(s,e({schema:t.schema}))))()},or=(e,t,r=[])=>{let o=L({schema:e,variant:t?"parsed":"original",validate:!0});return o.length===0?{}:{examples:o.reduce((n,s,a)=>({...n,[`example${a+1}`]:{value:typeof s=="object"&&!Array.isArray(s)?(0,ue.omit)(r,s):s}}),{})}},To=(e,t,r)=>{let o=L({schema:e,variant:t?"parsed":"original",validate:!0});return o.length===0?{}:{examples:o.reduce((n,s,a)=>r in s?{...n,[`example${a+1}`]:{value:s[r]}}:n,{})}};function Pe(e,t){if(e instanceof x.z.ZodObject)return e;let r;if(e instanceof x.z.ZodUnion||e instanceof x.z.ZodDiscriminatedUnion)r=Array.from(e.options.values()).map(o=>Pe(o,t)).reduce((o,n)=>o.merge(n.partial()),x.z.object({}));else if(e instanceof x.z.ZodEffects){if(G(e))throw new C({message:`Using transformations on the top level of ${t.isResponse?"response":"input"} schema is not allowed.`,...t});r=Pe(e._def.schema,t)}else r=Pe(e._def.left,t).merge(Pe(e._def.right,t));return Ee(e,r)}var nr=({path:e,method:t,endpoint:r,inputSources:o,serializer:n,getRef:s,makeRef:a,composition:p,clue:d="parameter"})=>{let c=r.getSchema("input"),l=Pe(c,{path:e,method:t,isResponse:!1}).shape,h=ot(e),g=o.includes("query"),S=o.includes("params"),P=f=>S&&h.includes(f);return Object.keys(l).filter(f=>g||P(f)).map(f=>{let E=te({schema:l[f],isResponse:!1,rules:lt,onEach:mt,onMissing:ut,serializer:n,getRef:s,makeRef:a,path:e,method:t}),y=p==="components"?a(k(e,t,`${d} ${f}`),E):E;return{name:f,in:P(f)?"path":"query",required:!l[f].isOptional(),description:(0,F.isSchemaObject)(E)&&E.description||`${t.toUpperCase()} ${e} ${d}`,schema:y,...To(c,!1,f)}})},lt={ZodString:mo,ZodNumber:uo,ZodBigInt:ao,ZodBoolean:io,ZodDateIn:oo,ZodDateOut:no,ZodNull:ro,ZodArray:co,ZodTuple:lo,ZodRecord:po,ZodObject:to,ZodLiteral:eo,ZodIntersection:Jr,ZodUnion:Br,ZodFile:Vr,ZodUpload:qr,ZodAny:Gr,ZodDefault:$r,ZodEnum:er,ZodNativeEnum:er,ZodEffects:yo,ZodOptional:Qr,ZodNullable:Xr,ZodDiscriminatedUnion:Yr,ZodBranded:ho,ZodDate:so,ZodCatch:_r,ZodPipeline:go,ZodLazy:xo,ZodReadonly:Wr},mt=({schema:e,isResponse:t,prev:r})=>{if((0,F.isReferenceObject)(r))return{};let{description:o}=e,n=e instanceof x.z.ZodLazy,s=r.type!==void 0,a=t&&Oe(e),p=!n&&s&&!a&&e.isNullable(),d=n?[]:L({schema:e,variant:t?"parsed":"original",validate:!0});return{...o&&{description:o},...p&&{nullable:!0},...d.length>0&&{example:d[0]}}},ut=({schema:e,...t})=>{throw new C({message:`Zod type ${e.constructor.name} is unsupported.`,...t})},ct=(e,t)=>{if((0,F.isReferenceObject)(e))return e;let r=e.properties?(0,ue.omit)(t,e.properties):void 0,o=e.example?(0,ue.omit)(t,e.example):void 0,n=e.required?e.required.filter(p=>!t.includes(p)):void 0,s=e.allOf?e.allOf.map(p=>ct(p,t)):void 0,a=e.oneOf?e.oneOf.map(p=>ct(p,t)):void 0;return(0,ue.omit)(Object.entries({properties:r,required:n,example:o,allOf:s,oneOf:a}).filter(([{},p])=>p===void 0).map(([p])=>p),{...e,properties:r,required:n,example:o,allOf:s,oneOf:a})},sr=e=>(0,F.isSchemaObject)(e)?(0,ue.omit)(["example"],e):e,ft=({method:e,path:t,endpoint:r,isPositive:o,serializer:n,getRef:s,makeRef:a,composition:p,clue:d="response"})=>{let c=r.getSchema(o?"positive":"negative"),l=r.getMimeTypes(o?"positive":"negative"),h=sr(te({schema:c,isResponse:!0,rules:lt,onEach:mt,onMissing:ut,serializer:n,getRef:s,makeRef:a,path:t,method:e})),g=or(c,!0),S=p==="components"?a(k(t,e,d),h):h;return{description:`${e.toUpperCase()} ${t} ${d}`,content:l.reduce((P,f)=>({...P,[f]:{schema:S,...g}}),{})}},So=()=>({type:"http",scheme:"basic"}),Oo=({format:e})=>({type:"http",scheme:"bearer",...e&&{bearerFormat:e}}),bo=({name:e})=>({type:"apiKey",in:"query",name:e}),Ro=({name:e})=>({type:"apiKey",in:"header",name:e}),Po=({name:e})=>({type:"apiKey",in:"cookie",name:e}),Zo=({url:e})=>({type:"openIdConnect",openIdConnectUrl:e}),Ao=({flows:e={}})=>({type:"oauth2",flows:Object.keys(e).reduce((t,r)=>{let o=e[r];if(!o)return t;let{scopes:n={},...s}=o;return{...t,[r]:{...s,scopes:n}}},{})}),ir=e=>{let t={basic:So,bearer:Oo,input:bo,header:Ro,cookie:Po,openid:Zo,oauth2:Ao};return De(e,r=>t[r.type](r))},Fe=e=>{if(typeof e=="object"){if("or"in e)return e.or.map(t=>("and"in t?t.and:[t]).reduce((r,{name:o,scopes:n})=>({...r,[o]:n}),{}));if("and"in e)return Fe(st(e))}return Fe({or:[e]})},ar=({method:e,path:t,endpoint:r,serializer:o,getRef:n,makeRef:s,composition:a,clue:p="request body"})=>{let d=ot(t),c=sr(ct(te({schema:r.getSchema("input"),isResponse:!1,rules:lt,onEach:mt,onMissing:ut,serializer:o,getRef:n,makeRef:s,path:t,method:e}),d)),l=or(r.getSchema("input"),!1,d),h=a==="components"?s(k(t,e,p),c):c;return{description:`${e.toUpperCase()} ${t} ${p}`,content:r.getMimeTypes("input").reduce((g,S)=>({...g,[S]:{schema:h,...l}}),{})}},dr=e=>Object.keys(e).map(t=>{let r=e[t];return{name:t,description:typeof r=="string"?r:r.description,...typeof r=="object"&&r.url&&{externalDocs:{url:r.url}}}}),yt=e=>e.length<=Xt?e:e.slice(0,Xt-1)+"\u2026";var $e=class extends pr.OpenApiBuilder{lastSecuritySchemaIds={};lastOperationIdSuffixes={};makeRef(t,r){return this.addSchema(t,r),this.getRef(t)}getRef(t){return t in(this.rootDoc.components?.schemas||{})?{$ref:`#/components/schemas/${t}`}:void 0}ensureUniqOperationId(t,r){let o=k(t,r);return o in this.lastOperationIdSuffixes?(this.lastOperationIdSuffixes[o]++,`${o}${this.lastOperationIdSuffixes[o]}`):(this.lastOperationIdSuffixes[o]=1,o)}ensureUniqSecuritySchemaName(t){let r=JSON.stringify(t);for(let o in this.rootDoc.components?.securitySchemes||{})if(r===JSON.stringify(this.rootDoc.components?.securitySchemes?.[o]))return o;return this.lastSecuritySchemaIds[t.type]=(this.lastSecuritySchemaIds?.[t.type]||0)+1,`${t.type.toUpperCase()}_${this.lastSecuritySchemaIds[t.type]}`}constructor({routing:t,config:r,title:o,version:n,serverUrl:s,successfulResponseDescription:a="Successful response",errorResponseDescription:p="Error response",hasSummaryFromDescription:d=!0,composition:c="inline",serializer:l=Ne}){super(),this.addInfo({title:o,version:n}).addServer({url:s}),ee({routing:t,onEndpoint:(g,S,P)=>{let f=P,E={path:S,method:f,endpoint:g,composition:c,serializer:l,getRef:this.getRef.bind(this),makeRef:this.makeRef.bind(this)},[y,w]=["short","long"].map(g.getDescription.bind(g)),Y=r.inputSources?.[f]||Ie[f],fe=nr({...E,inputSources:Y}),N={operationId:this.ensureUniqOperationId(S,f),responses:{[g.getStatusCode("positive")]:ft({...E,clue:a,isPositive:!0}),[g.getStatusCode("negative")]:ft({...E,clue:p,isPositive:!1})}};w&&(N.description=w,d&&y===void 0&&(N.summary=yt(w))),y&&(N.summary=yt(y)),g.getTags().length>0&&(N.tags=g.getTags()),fe.length>0&&(N.parameters=fe),Y.includes("body")&&(N.requestBody=ar(E));let ye=Fe(De(ir(g.getSecurity()),ge=>{let It=this.ensureUniqSecuritySchemaName(ge),Pr=["oauth2","openIdConnect"].includes(ge.type)?g.getScopes():[];return this.addSecurityScheme(It,ge),{name:It,scopes:Pr}}));ye.length>0&&(N.security=ye);let We=rr(S);this.addPath(We,{[f]:N})}}),this.rootDoc.tags=r.tags?dr(r.tags):[]}};var gt=b(require("http"));var Eo=e=>({method:"GET",header:jest.fn(()=>J),...e}),Io=e=>{let t={writableEnded:!1,statusCode:200,statusMessage:gt.default.STATUS_CODES[200],set:jest.fn(()=>t),setHeader:jest.fn(()=>t),header:jest.fn(()=>t),status:jest.fn(r=>(t.statusCode=r,t.statusMessage=gt.default.STATUS_CODES[r],t)),json:jest.fn(()=>t),send:jest.fn(()=>t),end:jest.fn(()=>(t.writableEnded=!0,t)),...e};return t},cr=async({endpoint:e,requestProps:t,responseProps:r,configProps:o,loggerProps:n,__noJest:s})=>{if(!jest||s)throw new Error("You need to install Jest in order to use testEndpoint().");let a=Eo(t),p=Io(r),d={info:jest.fn(),warn:jest.fn(),error:jest.fn(),debug:jest.fn(),...n},c={cors:!1,logger:d,...o};return await e.execute({request:a,response:p,config:c,logger:d}),{requestMock:a,responseMock:p,loggerMock:d}};var _=b(require("typescript"));var z=b(require("typescript")),i=z.default.factory,re=[i.createModifier(z.default.SyntaxKind.ExportKeyword)],Co=[i.createModifier(z.default.SyntaxKind.AsyncKeyword)],No=[i.createModifier(z.default.SyntaxKind.PublicKeyword),i.createModifier(z.default.SyntaxKind.ReadonlyKeyword)],lr=[i.createModifier(z.default.SyntaxKind.ProtectedKeyword),i.createModifier(z.default.SyntaxKind.ReadonlyKeyword)],Mo=i.createTemplateHead(""),wo=i.createTemplateTail(""),Do=i.createTemplateMiddle(" "),ht=e=>i.createTemplateLiteralType(Mo,e.map((t,r)=>i.createTemplateLiteralTypeSpan(i.createTypeReferenceNode(t),r===e.length-1?wo:Do))),xt=ht(["M","P"]),_e=(e,t,r)=>i.createParameterDeclaration(r,void 0,e,void 0,t,void 0),Ge=(e,t)=>Object.keys(e).reduce((r,o)=>r.concat(_e(o,e[o],t)),[]),Tt=(e,t)=>i.createExpressionWithTypeArguments(i.createIdentifier("Record"),[typeof e=="number"?i.createKeywordTypeNode(e):i.createTypeReferenceNode(e),i.createKeywordTypeNode(t)]),mr=e=>i.createConstructorDeclaration(void 0,e,i.createBlock([])),St=(e,t)=>i.createPropertySignature(void 0,`"${e}"`,void 0,i.createTypeReferenceNode(t)),Ot=(e,t)=>i.createVariableDeclarationList([i.createVariableDeclaration(e,void 0,void 0,t)],z.default.NodeFlags.Const),bt=(e,t)=>i.createTypeAliasDeclaration(re,e,void 0,i.createUnionTypeNode(t.map(r=>i.createLiteralTypeNode(i.createStringLiteral(r))))),qe=(e,t)=>i.createTypeAliasDeclaration(re,e,void 0,t),ur=(e,t,r)=>i.createPropertyDeclaration(No,e,void 0,t,r),fr=(e,t,r=[])=>i.createClassDeclaration(re,e,void 0,void 0,[t,...r]),yr=(e,t)=>i.createTypeReferenceNode("Promise",[i.createIndexedAccessTypeNode(i.createTypeReferenceNode(e),t)]),gr=()=>i.createTypeReferenceNode("Promise",[i.createKeywordTypeNode(z.default.SyntaxKind.AnyKeyword)]),Rt=(e,t,r)=>i.createInterfaceDeclaration(re,e,void 0,t,r),hr=e=>Object.keys(e).reduce((t,r)=>t.concat(i.createTypeParameterDeclaration([],r,i.createTypeReferenceNode(e[r]))),[]),xr=(e,t)=>i.createArrowFunction(Co,void 0,e.map(r=>_e(r)),void 0,void 0,i.createCallExpression(i.createPropertyAccessExpression(i.createThis(),"implementation"),void 0,t)),Pt=(e,t,r)=>i.createCallExpression(i.createPropertyAccessExpression(i.createCallExpression(i.createPropertyAccessExpression(i.createIdentifier("Object"),"keys"),void 0,[i.createIdentifier(e)]),"reduce"),void 0,[i.createArrowFunction(void 0,void 0,Ge({acc:void 0,key:void 0}),void 0,void 0,t),r]);var u=b(require("typescript")),br=require("zod");var $=b(require("typescript")),{factory:Ve}=$.default,Zt=(e,t)=>{$.default.addSyntheticLeadingComment(e,$.default.SyntaxKind.MultiLineCommentTrivia,`* ${t} `,!0)},Be=(e,t,r)=>{let o=Ve.createTypeAliasDeclaration(void 0,Ve.createIdentifier(t),void 0,e);return r&&Zt(o,r),o},Tr=(e,t)=>{let r=$.default.createSourceFile("print.ts","",$.default.ScriptTarget.Latest,!1,$.default.ScriptKind.TS);return $.default.createPrinter(t).printNode($.default.EmitHint.Unspecified,e,r)},zo=/^[A-Za-z_$][A-Za-z0-9_$]*$/,Sr=e=>zo.test(e)?Ve.createIdentifier(e):Ve.createStringLiteral(e);var{factory:m}=u.default,vo={[u.default.SyntaxKind.AnyKeyword]:"",[u.default.SyntaxKind.BigIntKeyword]:BigInt(0),[u.default.SyntaxKind.BooleanKeyword]:!1,[u.default.SyntaxKind.NumberKeyword]:0,[u.default.SyntaxKind.ObjectKeyword]:{},[u.default.SyntaxKind.StringKeyword]:"",[u.default.SyntaxKind.UndefinedKeyword]:void 0},jo=({schema:{value:e}})=>m.createLiteralTypeNode(typeof e=="number"?m.createNumericLiteral(e):typeof e=="boolean"?e?m.createTrue():m.createFalse():m.createStringLiteral(e)),Lo=({schema:{shape:e},isResponse:t,next:r,optionalPropStyle:{withQuestionMark:o}})=>{let n=Object.entries(e).map(([s,a])=>{let p=t&&Oe(a)?a instanceof br.z.ZodOptional:a.isOptional(),d=m.createPropertySignature(void 0,Sr(s),p&&o?m.createToken(u.default.SyntaxKind.QuestionToken):void 0,r({schema:a}));return a.description&&Zt(d,a.description),d});return m.createTypeLiteralNode(n)},ko=({schema:{element:e},next:t})=>m.createArrayTypeNode(t({schema:e})),Uo=({schema:{options:e}})=>m.createUnionTypeNode(e.map(t=>m.createLiteralTypeNode(m.createStringLiteral(t)))),Or=({schema:{options:e},next:t})=>m.createUnionTypeNode(e.map(r=>t({schema:r}))),Ho=e=>vo?.[e.kind],Ko=({schema:e,next:t,isResponse:r})=>{let o=t({schema:e.innerType()}),n=e._def.effect;if(r&&n.type==="transform"){let s=Me({effect:n,sample:Ho(o)}),a={number:u.default.SyntaxKind.NumberKeyword,bigint:u.default.SyntaxKind.BigIntKeyword,boolean:u.default.SyntaxKind.BooleanKeyword,string:u.default.SyntaxKind.StringKeyword,undefined:u.default.SyntaxKind.UndefinedKeyword,object:u.default.SyntaxKind.ObjectKeyword};return m.createKeywordTypeNode(s&&a[s]||u.default.SyntaxKind.AnyKeyword)}return o},Fo=({schema:e})=>m.createUnionTypeNode(Object.values(e.enum).map(t=>m.createLiteralTypeNode(typeof t=="number"?m.createNumericLiteral(t):m.createStringLiteral(t)))),$o=({next:e,schema:t,optionalPropStyle:{withUndefined:r}})=>{let o=e({schema:t.unwrap()});return r?m.createUnionTypeNode([o,m.createKeywordTypeNode(u.default.SyntaxKind.UndefinedKeyword)]):o},_o=({next:e,schema:t})=>m.createUnionTypeNode([e({schema:t.unwrap()}),m.createLiteralTypeNode(m.createNull())]),Go=({next:e,schema:{items:t}})=>m.createTupleTypeNode(t.map(r=>e({schema:r}))),qo=({next:e,schema:{keySchema:t,valueSchema:r}})=>m.createExpressionWithTypeArguments(m.createIdentifier("Record"),[e({schema:t}),e({schema:r})]),Vo=({next:e,schema:t})=>m.createIntersectionTypeNode([t._def.left,t._def.right].map(r=>e({schema:r}))),Bo=({next:e,schema:t})=>e({schema:t._def.innerType}),B=e=>()=>m.createKeywordTypeNode(e),Yo=({next:e,schema:t})=>e({schema:t.unwrap()}),Jo=({next:e,schema:t})=>e({schema:t._def.innerType}),Qo=({next:e,schema:t})=>e({schema:t._def.innerType}),Wo=({schema:e,next:t,isResponse:r})=>t({schema:e._def[r?"out":"in"]}),Xo=()=>m.createLiteralTypeNode(m.createNull()),en=({getAlias:e,makeAlias:t,next:r,serializer:o,schema:n})=>{let s=`Type${o(n.schema)}`;return e(s)||(()=>(t(s,m.createLiteralTypeNode(m.createNull())),t(s,r({schema:n.schema}))))()},tn={ZodString:B(u.default.SyntaxKind.StringKeyword),ZodNumber:B(u.default.SyntaxKind.NumberKeyword),ZodBigInt:B(u.default.SyntaxKind.BigIntKeyword),ZodBoolean:B(u.default.SyntaxKind.BooleanKeyword),ZodDateIn:B(u.default.SyntaxKind.StringKeyword),ZodDateOut:B(u.default.SyntaxKind.StringKeyword),ZodNull:Xo,ZodArray:ko,ZodTuple:Go,ZodRecord:qo,ZodObject:Lo,ZodLiteral:jo,ZodIntersection:Vo,ZodUnion:Or,ZodFile:B(u.default.SyntaxKind.StringKeyword),ZodAny:B(u.default.SyntaxKind.AnyKeyword),ZodDefault:Bo,ZodEnum:Uo,ZodNativeEnum:Fo,ZodEffects:Ko,ZodOptional:$o,ZodNullable:_o,ZodDiscriminatedUnion:Or,ZodBranded:Yo,ZodCatch:Qo,ZodPipeline:Wo,ZodLazy:en,ZodReadonly:Jo},At=({schema:e,...t})=>te({schema:e,rules:tn,onMissing:()=>m.createKeywordTypeNode(u.default.SyntaxKind.AnyKeyword),...t});var Ye=class{agg=[];registry={};paths=[];aliases={};getAlias(t){return t in this.aliases?i.createTypeReferenceNode(t):void 0}makeAlias(t,r){return this.aliases[t]=Be(r,t),this.getAlias(t)}constructor({routing:t,variant:r="client",serializer:o=Ne,optionalPropStyle:n={withQuestionMark:!0,withUndefined:!0}}){ee({routing:t,onEndpoint:(y,w,Y)=>{let fe=k(w,Y,"input"),N=k(w,Y,"response"),ye={serializer:o,getAlias:this.getAlias.bind(this),makeAlias:this.makeAlias.bind(this),optionalPropStyle:n},We=At({...ye,schema:y.getSchema("input"),isResponse:!1}),ge=At({...ye,isResponse:!0,schema:y.getSchema("positive").or(y.getSchema("negative"))});this.agg.push(Be(We,fe),Be(ge,N)),Y!=="options"&&(this.paths.push(w),this.registry[`${Y} ${w}`]={in:fe,out:N,isJson:y.getMimeTypes("positive").includes(J),tags:y.getTags()})}}),this.agg=Object.values(this.aliases).concat(this.agg);let s=bt("Path",this.paths),a=bt("Method",Ht),p=qe("MethodPath",ht([a.name,s.name])),d=[i.createHeritageClause(_.default.SyntaxKind.ExtendsKeyword,[Tt(p.name,_.default.SyntaxKind.AnyKeyword)])],c=Rt("Input",d,Object.keys(this.registry).map(y=>St(y,this.registry[y].in))),l=Rt("Response",d,Object.keys(this.registry).map(y=>St(y,this.registry[y].out)));if(this.agg.push(s,a,p,c,l),r==="types")return;let h=i.createVariableStatement(re,Ot("jsonEndpoints",i.createObjectLiteralExpression(Object.keys(this.registry).filter(y=>this.registry[y].isJson).map(y=>i.createPropertyAssignment(`"${y}"`,i.createTrue()))))),g=i.createVariableStatement(re,Ot("endpointTags",i.createObjectLiteralExpression(Object.keys(this.registry).map(y=>i.createPropertyAssignment(`"${y}"`,i.createArrayLiteralExpression(this.registry[y].tags.map(w=>i.createStringLiteral(w)))))))),S=qe("Provider",i.createFunctionTypeNode(hr({M:a.name,P:s.name}),Ge({method:i.createTypeReferenceNode("M"),path:i.createTypeReferenceNode("P"),params:i.createIndexedAccessTypeNode(i.createTypeReferenceNode(c.name),xt)}),yr(l.name,xt))),P=qe("Implementation",i.createFunctionTypeNode(void 0,Ge({method:i.createTypeReferenceNode(a.name),path:i.createKeywordTypeNode(_.default.SyntaxKind.StringKeyword),params:Tt(_.default.SyntaxKind.StringKeyword,_.default.SyntaxKind.AnyKeyword)}),gr())),f=i.createTemplateExpression(i.createTemplateHead(":"),[i.createTemplateSpan(i.createIdentifier("key"),i.createTemplateTail(""))]),E=fr("ExpressZodAPIClient",mr([_e("implementation",i.createTypeReferenceNode(P.name),lr)]),[ur("provide",i.createTypeReferenceNode(S.name),xr(["method","path","params"],[i.createIdentifier("method"),Pt("params",i.createCallExpression(i.createPropertyAccessExpression(i.createIdentifier("acc"),"replace"),void 0,[f,i.createElementAccessExpression(i.createIdentifier("params"),i.createIdentifier("key"))]),i.createIdentifier("path")),Pt("params",i.createConditionalExpression(i.createBinaryExpression(i.createCallExpression(i.createPropertyAccessExpression(i.createIdentifier("path"),"indexOf"),void 0,[f]),_.default.SyntaxKind.GreaterThanEqualsToken,i.createNumericLiteral(0)),void 0,i.createIdentifier("acc"),void 0,i.createObjectLiteralExpression([i.createSpreadAssignment(i.createIdentifier("acc")),i.createPropertyAssignment(i.createComputedPropertyName(i.createIdentifier("key")),i.createElementAccessExpression(i.createIdentifier("params"),i.createIdentifier("key")))])),i.createObjectLiteralExpression())]))]);_.default.addSyntheticLeadingComment(E,_.default.SyntaxKind.MultiLineCommentTrivia,`
|
|
34
|
+
`.trim();var pt=({app:e,logger:t,config:r,routing:o})=>{r.startupLogo!==!1&&console.log(Bt()),ee({routing:o,hasCors:!!r.cors,onEndpoint:(n,s,a)=>{e[a](s,async(p,d)=>{t.info(`${p.method}: ${s}`),await n.execute({request:p,response:d,logger:t,config:r})})},onStatic:(n,s)=>{e.use(n,s)}})};var ke=R(require("express")),Yt=R(require("compression")),Jt=R(require("express-fileupload")),Qt=R(require("https"));var ct=R(require("http-errors")),$r=(e,t)=>(r,o,n,s)=>{if(!r)return s();e.handler({error:(0,ct.default)(400,ne(r).message),request:o,response:n,logger:t,input:o.body,output:null})},Wt=(e,t)=>(r,o)=>{let n=(0,ct.default)(404,`Can not ${r.method} ${r.path}`);try{e.handler({request:r,response:o,logger:t,error:n,input:null,output:null})}catch(s){ve({response:o,logger:t,error:new ie(ne(s).message,n)})}},Xt=(e,t)=>{let r=ot(e.logger)?Oe(e.logger):e.logger;pt({app:e.app,routing:t,logger:r,config:e});let o=e.errorHandler||W;return{notFoundHandler:Wt(o,r),logger:r}},er=(e,t)=>{let r=ot(e.logger)?Oe(e.logger):e.logger,o=(0,ke.default)();o.disable("x-powered-by");let n=e.errorHandler||W,s=e.server.compression?(0,Yt.default)({...typeof e.server.compression=="object"?e.server.compression:{}}):void 0,a=e.server.jsonParser||(0,ke.json)(),p=e.server.upload?(0,Jt.default)({...typeof e.server.upload=="object"?e.server.upload:{},abortOnLimit:!1,parseNested:!0}):void 0,d=[].concat(s||[]).concat(a).concat(p||[]);o.use(d),o.use($r(n,r)),pt({app:o,routing:t,logger:r,config:e}),o.use(Wt(n,r));let c=o.listen(e.server.listen,()=>{r.info(`Listening ${e.server.listen}`)}),l;return e.https&&(l=Qt.default.createServer(e.https.options,o).listen(e.https.listen,()=>{r.info(`Listening ${e.https.listen}`)})),{app:o,httpServer:c,httpsServer:l,logger:r}};var lr=require("openapi3-ts/oas30");var $=require("openapi3-ts/oas30"),ue=require("ramda"),x=require("zod");var T=require("zod");var lt=/^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d+)?)?Z?$/,_r="ZodDateIn",He=class e extends T.ZodType{_parse(t){let{status:r,ctx:o}=this._processInputParams(t);if(o.parsedType!==T.ZodParsedType.string)return(0,T.addIssueToContext)(o,{code:T.ZodIssueCode.invalid_type,expected:T.ZodParsedType.string,received:o.parsedType}),T.INVALID;lt.test(o.data)||((0,T.addIssueToContext)(o,{code:T.ZodIssueCode.invalid_string,validation:"regex"}),r.dirty());let n=new Date(o.data);return Ie(n)?{status:r.value,value:n}:((0,T.addIssueToContext)(o,{code:T.ZodIssueCode.invalid_date}),T.INVALID)}static create=()=>new e({typeName:_r})};var te=({schema:e,onEach:t,rules:r,onMissing:o,...n})=>{let s="typeName"in e._def?r[e._def.typeName]:void 0,p=s?s({schema:e,...n,next:c=>te({...c,...n,onEach:t,rules:r,onMissing:o})}):o({schema:e,...n}),d=t&&t({schema:e,prev:p,...n});return d?{...p,...d}:p};var tr=50,or="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString",Gr={integer:0,number:0,string:"",boolean:!1,object:{},null:null,array:[]},nr=e=>e.replace(et,t=>`{${t.slice(1)}}`),qr=({schema:{_def:{innerType:e,defaultValue:t}},next:r})=>({...r({schema:e}),default:t()}),Vr=({schema:{_def:{innerType:e}},next:t})=>t({schema:e}),Br=()=>({format:"any"}),Yr=e=>{if(e.isResponse)throw new P({message:"Please use z.upload() only for input.",...e});return{type:"string",format:"binary"}},Jr=({schema:{isBinary:e,isBase64:t},...r})=>{if(!r.isResponse)throw new P({message:"Please use z.file() only within ResultHandler.",...r});return{type:"string",format:e?"binary":t?"byte":"file"}},Qr=({schema:{options:e},next:t})=>({oneOf:e.map(r=>t({schema:r}))}),Wr=({schema:{options:e,discriminator:t},next:r})=>({discriminator:{propertyName:t},oneOf:Array.from(e.values()).map(o=>r({schema:o}))}),Xr=({schema:{_def:{left:e,right:t}},next:r})=>({allOf:[e,t].map(o=>r({schema:o}))}),eo=({schema:e,next:t})=>t({schema:e.unwrap()}),to=({schema:e,next:t})=>t({schema:e._def.innerType}),ro=({schema:e,next:t})=>({nullable:!0,...t({schema:e.unwrap()})}),rr=({schema:e})=>({type:typeof Object.values(e.enum)[0],enum:Object.values(e.enum)}),oo=({schema:{value:e}})=>({type:typeof e,enum:[e]}),no=({schema:e,isResponse:t,...r})=>{let o=Object.keys(e.shape).filter(n=>{let s=e.shape[n];return!(t&&Te(s)?s instanceof x.z.ZodOptional:s.isOptional())});return{type:"object",properties:Ue({schema:e,isResponse:t,...r}),...o.length?{required:o}:{}}},so=()=>({type:"string",nullable:!0,format:"null"}),io=e=>{if(e.isResponse)throw new P({message:"Please use z.dateOut() for output.",...e});return{description:"YYYY-MM-DDTHH:mm:ss.sssZ",type:"string",format:"date-time",pattern:lt.source,externalDocs:{url:or}}},ao=e=>{if(!e.isResponse)throw new P({message:"Please use z.dateIn() for input.",...e});return{description:"YYYY-MM-DDTHH:mm:ss.sssZ",type:"string",format:"date-time",externalDocs:{url:or}}},po=e=>{throw new P({message:`Using z.date() within ${e.isResponse?"output":"input"} schema is forbidden. Please use z.date${e.isResponse?"Out":"In"}() instead. Check out the documentation for details.`,...e})},co=()=>({type:"boolean"}),lo=()=>({type:"integer",format:"bigint"}),mo=({schema:{keySchema:e,valueSchema:t},...r})=>{if(e instanceof x.z.ZodEnum||e instanceof x.z.ZodNativeEnum){let o=Object.values(e.enum),n=o.reduce((s,a)=>({...s,[a]:t}),{});return{type:"object",properties:Ue({schema:x.z.object(n),...r}),...o.length?{required:o}:{}}}if(e instanceof x.z.ZodLiteral)return{type:"object",properties:Ue({schema:x.z.object({[e.value]:t}),...r}),required:[e.value]};if(e instanceof x.z.ZodUnion&&e.options.reduce((n,s)=>n&&s instanceof x.z.ZodLiteral,!0)){let n=e.options.reduce((s,a)=>({...s,[a.value]:t}),{});return{type:"object",properties:Ue({schema:x.z.object(n),...r}),required:e.options.map(s=>s.value)}}return{type:"object",additionalProperties:r.next({schema:t})}},uo=({schema:{_def:e,element:t},next:r})=>({type:"array",items:r({schema:t}),...e.minLength!==null&&{minItems:e.minLength.value},...e.maxLength!==null&&{maxItems:e.maxLength.value}}),fo=({schema:{items:e},next:t})=>{let r=e.map(o=>t({schema:o}));return{type:"array",minItems:r.length,maxItems:r.length,items:{oneOf:r,format:"tuple",...r.length>0&&{description:r.map((o,n)=>`${n}: ${(0,$.isSchemaObject)(o)?o.type:o.$ref}`).join(", ")}}}},yo=({schema:{isEmail:e,isURL:t,minLength:r,maxLength:o,isUUID:n,isCUID:s,isCUID2:a,isULID:p,isIP:d,isEmoji:c,isDatetime:l,_def:{checks:g}}})=>{let y=g.find(h=>h.kind==="regex"),S=g.find(h=>h.kind==="datetime"),I=y?y.regex:S?S.offset?new RegExp("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(([+-]\\d{2}:\\d{2})|Z)$"):new RegExp("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"):void 0;return{type:"string",...l&&{format:"date-time"},...e&&{format:"email"},...t&&{format:"url"},...n&&{format:"uuid"},...s&&{format:"cuid"},...a&&{format:"cuid2"},...p&&{format:"ulid"},...d&&{format:"ip"},...c&&{format:"emoji"},...r!==null&&{minLength:r},...o!==null&&{maxLength:o},...I&&{pattern:`/${I.source}/${I.flags}`}}},go=({schema:e})=>{let t=e._def.checks.find(({kind:s})=>s==="min"),r=t?t.inclusive:!0,o=e._def.checks.find(({kind:s})=>s==="max"),n=o?o.inclusive:!0;return{type:e.isInt?"integer":"number",format:e.isInt?"int64":"double",minimum:e.minValue===null?e.isInt?Number.MIN_SAFE_INTEGER:Number.MIN_VALUE:e.minValue,exclusiveMinimum:!r,maximum:e.maxValue===null?e.isInt?Number.MAX_SAFE_INTEGER:Number.MAX_VALUE:e.maxValue,exclusiveMaximum:!n}},Ue=({schema:{shape:e},next:t})=>Object.keys(e).reduce((r,o)=>({...r,[o]:t({schema:e[o]})}),{}),ho=e=>{let t=Array.isArray(e.type)?e.type[0]:e.type;return Gr?.[t]},xo=({schema:e,isResponse:t,next:r})=>{let o=r({schema:e.innerType()}),{effect:n}=e._def;if(t&&n.type==="transform"&&(0,$.isSchemaObject)(o)){let s=Ne({effect:n,sample:ho(o)});return s&&["number","string","boolean"].includes(s)?{type:s}:r({schema:x.z.any()})}if(!t&&n.type==="preprocess"&&(0,$.isSchemaObject)(o)){let{type:s,...a}=o;return{...a,format:`${a.format||s} (preprocessed)`}}return o},To=({schema:e,isResponse:t,next:r})=>r({schema:e._def[t?"out":"in"]}),So=({schema:e,next:t})=>t({schema:e.unwrap()}),Oo=({next:e,schema:t,serializer:r,getRef:o,makeRef:n})=>{let s=r(t.schema);return o(s)||(()=>(n(s,{}),n(s,e({schema:t.schema}))))()},sr=(e,t,r=[])=>{let o=k({schema:e,variant:t?"parsed":"original",validate:!0});return o.length===0?{}:{examples:o.reduce((n,s,a)=>({...n,[`example${a+1}`]:{value:typeof s=="object"&&!Array.isArray(s)?(0,ue.omit)(r,s):s}}),{})}},bo=(e,t,r)=>{let o=k({schema:e,variant:t?"parsed":"original",validate:!0});return o.length===0?{}:{examples:o.reduce((n,s,a)=>r in s?{...n,[`example${a+1}`]:{value:s[r]}}:n,{})}},be=(e,t)=>{if(e instanceof x.z.ZodObject)return e;let r;if(e instanceof x.z.ZodUnion||e instanceof x.z.ZodDiscriminatedUnion)r=Array.from(e.options.values()).map(o=>be(o,t)).reduce((o,n)=>o.merge(n.partial()),x.z.object({}));else if(e instanceof x.z.ZodEffects){if(q(e))throw new P({message:`Using transformations on the top level of ${t.isResponse?"response":"input"} schema is not allowed.`,...t});r=be(e._def.schema,t)}else r=be(e._def.left,t).merge(be(e._def.right,t));return Ee(e,r)},ir=({path:e,method:t,endpoint:r,inputSources:o,serializer:n,getRef:s,makeRef:a,composition:p,clue:d="parameter"})=>{let c=r.getSchema("input"),l=be(c,{path:e,method:t,isResponse:!1}).shape,g=st(e),y=o.includes("query"),S=o.includes("params"),I=o.includes("headers"),h=m=>S&&g.includes(m),z=m=>I&&rt(m);return Object.keys(l).filter(m=>y||h(m)).map(m=>{let O=te({schema:l[m],isResponse:!1,rules:ut,onEach:ft,onMissing:yt,serializer:n,getRef:s,makeRef:a,path:e,method:t}),v=p==="components"?a(H(e,t,`${d} ${m}`),O):O;return{name:m,in:h(m)?"path":z(m)?"header":"query",required:!l[m].isOptional(),description:(0,$.isSchemaObject)(O)&&O.description||`${t.toUpperCase()} ${e} ${d}`,schema:v,...bo(c,!1,m)}})},ut={ZodString:yo,ZodNumber:go,ZodBigInt:lo,ZodBoolean:co,ZodDateIn:io,ZodDateOut:ao,ZodNull:so,ZodArray:uo,ZodTuple:fo,ZodRecord:mo,ZodObject:no,ZodLiteral:oo,ZodIntersection:Xr,ZodUnion:Qr,ZodFile:Jr,ZodUpload:Yr,ZodAny:Br,ZodDefault:qr,ZodEnum:rr,ZodNativeEnum:rr,ZodEffects:xo,ZodOptional:eo,ZodNullable:ro,ZodDiscriminatedUnion:Wr,ZodBranded:So,ZodDate:po,ZodCatch:Vr,ZodPipeline:To,ZodLazy:Oo,ZodReadonly:to},ft=({schema:e,isResponse:t,prev:r})=>{if((0,$.isReferenceObject)(r))return{};let{description:o}=e,n=e instanceof x.z.ZodLazy,s=r.type!==void 0,a=t&&Te(e),p=!n&&s&&!a&&e.isNullable(),d=n?[]:k({schema:e,variant:t?"parsed":"original",validate:!0});return{...o&&{description:o},...p&&{nullable:!0},...d.length>0&&{example:d[0]}}},yt=({schema:e,...t})=>{throw new P({message:`Zod type ${e.constructor.name} is unsupported.`,...t})},mt=(e,t)=>{if((0,$.isReferenceObject)(e))return e;let r=e.properties?(0,ue.omit)(t,e.properties):void 0,o=e.example?(0,ue.omit)(t,e.example):void 0,n=e.required?e.required.filter(p=>!t.includes(p)):void 0,s=e.allOf?e.allOf.map(p=>mt(p,t)):void 0,a=e.oneOf?e.oneOf.map(p=>mt(p,t)):void 0;return(0,ue.omit)(Object.entries({properties:r,required:n,example:o,allOf:s,oneOf:a}).filter(([{},p])=>p===void 0).map(([p])=>p),{...e,properties:r,required:n,example:o,allOf:s,oneOf:a})},ar=e=>(0,$.isSchemaObject)(e)?(0,ue.omit)(["example"],e):e,gt=({method:e,path:t,endpoint:r,isPositive:o,serializer:n,getRef:s,makeRef:a,composition:p,clue:d="response"})=>{let c=r.getSchema(o?"positive":"negative"),l=r.getMimeTypes(o?"positive":"negative"),g=ar(te({schema:c,isResponse:!0,rules:ut,onEach:ft,onMissing:yt,serializer:n,getRef:s,makeRef:a,path:t,method:e})),y=sr(c,!0),S=p==="components"?a(H(t,e,d),g):g;return{description:`${e.toUpperCase()} ${t} ${d}`,content:l.reduce((I,h)=>({...I,[h]:{schema:S,...y}}),{})}},Ro=()=>({type:"http",scheme:"basic"}),Po=({format:e})=>({type:"http",scheme:"bearer",...e&&{bearerFormat:e}}),Zo=({name:e})=>({type:"apiKey",in:"query",name:e}),Eo=({name:e})=>({type:"apiKey",in:"header",name:e}),Ao=({name:e})=>({type:"apiKey",in:"cookie",name:e}),Io=({url:e})=>({type:"openIdConnect",openIdConnectUrl:e}),Co=({flows:e={}})=>({type:"oauth2",flows:Object.keys(e).reduce((t,r)=>{let o=e[r];if(!o)return t;let{scopes:n={},...s}=o;return{...t,[r]:{...s,scopes:n}}},{})}),dr=e=>{let t={basic:Ro,bearer:Po,input:Zo,header:Eo,cookie:Ao,openid:Io,oauth2:Co};return Me(e,r=>t[r.type](r))},Ke=e=>{if(typeof e=="object"){if("or"in e)return e.or.map(t=>("and"in t?t.and:[t]).reduce((r,{name:o,scopes:n})=>({...r,[o]:n}),{}));if("and"in e)return Ke(at(e))}return Ke({or:[e]})},pr=({method:e,path:t,endpoint:r,serializer:o,getRef:n,makeRef:s,composition:a,clue:p="request body"})=>{let d=st(t),c=ar(mt(te({schema:r.getSchema("input"),isResponse:!1,rules:ut,onEach:ft,onMissing:yt,serializer:o,getRef:n,makeRef:s,path:t,method:e}),d)),l=sr(r.getSchema("input"),!1,d),g=a==="components"?s(H(t,e,p),c):c;return{description:`${e.toUpperCase()} ${t} ${p}`,content:r.getMimeTypes("input").reduce((y,S)=>({...y,[S]:{schema:g,...l}}),{})}},cr=e=>Object.keys(e).map(t=>{let r=e[t];return{name:t,description:typeof r=="string"?r:r.description,...typeof r=="object"&&r.url&&{externalDocs:{url:r.url}}}}),ht=e=>e.length<=tr?e:e.slice(0,tr-1)+"\u2026";var Fe=class extends lr.OpenApiBuilder{lastSecuritySchemaIds={};lastOperationIdSuffixes={};makeRef(t,r){return this.addSchema(t,r),this.getRef(t)}getRef(t){return t in(this.rootDoc.components?.schemas||{})?{$ref:`#/components/schemas/${t}`}:void 0}ensureUniqOperationId(t,r,o){if(o){if(o in this.lastOperationIdSuffixes)throw new P({message:`Duplicated operationId: "${o}"`,method:r,isResponse:!1,path:t});return this.lastOperationIdSuffixes[o]=1,o}let n=H(t,r);return n in this.lastOperationIdSuffixes?(this.lastOperationIdSuffixes[n]++,`${n}${this.lastOperationIdSuffixes[n]}`):(this.lastOperationIdSuffixes[n]=1,n)}ensureUniqSecuritySchemaName(t){let r=JSON.stringify(t);for(let o in this.rootDoc.components?.securitySchemes||{})if(r===JSON.stringify(this.rootDoc.components?.securitySchemes?.[o]))return o;return this.lastSecuritySchemaIds[t.type]=(this.lastSecuritySchemaIds?.[t.type]||0)+1,`${t.type.toUpperCase()}_${this.lastSecuritySchemaIds[t.type]}`}constructor({routing:t,config:r,title:o,version:n,serverUrl:s,successfulResponseDescription:a="Successful response",errorResponseDescription:p="Error response",hasSummaryFromDescription:d=!0,composition:c="inline",serializer:l=Ce}){super(),this.addInfo({title:o,version:n}).addServer({url:s}),ee({routing:t,onEndpoint:(y,S,I)=>{let h=I,z={path:S,method:h,endpoint:y,composition:c,serializer:l,getRef:this.getRef.bind(this),makeRef:this.makeRef.bind(this)},[m,O]=["short","long"].map(y.getDescription.bind(y)),v=r.inputSources?.[h]||Ae[h],fe=ir({...z,inputSources:v}),N={operationId:this.ensureUniqOperationId(S,h,y.getOperationId()),responses:{[y.getStatusCode("positive")]:gt({...z,clue:a,isPositive:!0}),[y.getStatusCode("negative")]:gt({...z,clue:p,isPositive:!1})}};O&&(N.description=O,d&&m===void 0&&(N.summary=ht(O))),m&&(N.summary=ht(m)),y.getTags().length>0&&(N.tags=y.getTags()),fe.length>0&&(N.parameters=fe),v.includes("body")&&(N.requestBody=pr(z));let Re=Ke(Me(dr(y.getSecurity()),Xe=>{let Nt=this.ensureUniqSecuritySchemaName(Xe),Er=["oauth2","openIdConnect"].includes(Xe.type)?y.getScopes():[];return this.addSecurityScheme(Nt,Xe),{name:Nt,scopes:Er}}));Re.length>0&&(N.security=Re);let We=nr(S);this.addPath(We,{[h]:N})}}),this.rootDoc.tags=r.tags?cr(r.tags):[]}};var xt=R(require("http"));var No=e=>({method:"GET",header:jest.fn(()=>J),...e}),wo=e=>{let t={writableEnded:!1,statusCode:200,statusMessage:xt.default.STATUS_CODES[200],set:jest.fn(()=>t),setHeader:jest.fn(()=>t),header:jest.fn(()=>t),status:jest.fn(r=>(t.statusCode=r,t.statusMessage=xt.default.STATUS_CODES[r],t)),json:jest.fn(()=>t),send:jest.fn(()=>t),end:jest.fn(()=>(t.writableEnded=!0,t)),...e};return t},mr=async({endpoint:e,requestProps:t,responseProps:r,configProps:o,loggerProps:n,__noJest:s})=>{if(!jest||s)throw new Error("You need to install Jest in order to use testEndpoint().");let a=No(t),p=wo(r),d={info:jest.fn(),warn:jest.fn(),error:jest.fn(),debug:jest.fn(),...n},c={cors:!1,logger:d,...o};return await e.execute({request:a,response:p,config:c,logger:d}),{requestMock:a,responseMock:p,loggerMock:d}};var G=R(require("typescript"));var D=R(require("typescript")),i=D.default.factory,re=[i.createModifier(D.default.SyntaxKind.ExportKeyword)],Mo=[i.createModifier(D.default.SyntaxKind.AsyncKeyword)],Do=[i.createModifier(D.default.SyntaxKind.PublicKeyword),i.createModifier(D.default.SyntaxKind.ReadonlyKeyword)],ur=[i.createModifier(D.default.SyntaxKind.ProtectedKeyword),i.createModifier(D.default.SyntaxKind.ReadonlyKeyword)],zo=i.createTemplateHead(""),vo=i.createTemplateTail(""),jo=i.createTemplateMiddle(" "),Tt=e=>i.createTemplateLiteralType(zo,e.map((t,r)=>i.createTemplateLiteralTypeSpan(i.createTypeReferenceNode(t),r===e.length-1?vo:jo))),St=Tt(["M","P"]),$e=(e,t,r)=>i.createParameterDeclaration(r,void 0,e,void 0,t,void 0),_e=(e,t)=>Object.keys(e).reduce((r,o)=>r.concat($e(o,e[o],t)),[]),Ot=(e,t)=>i.createExpressionWithTypeArguments(i.createIdentifier("Record"),[typeof e=="number"?i.createKeywordTypeNode(e):i.createTypeReferenceNode(e),i.createKeywordTypeNode(t)]),fr=e=>i.createConstructorDeclaration(void 0,e,i.createBlock([])),bt=(e,t)=>i.createPropertySignature(void 0,`"${e}"`,void 0,i.createTypeReferenceNode(t)),Rt=(e,t)=>i.createVariableDeclarationList([i.createVariableDeclaration(e,void 0,void 0,t)],D.default.NodeFlags.Const),Pt=(e,t)=>i.createTypeAliasDeclaration(re,e,void 0,i.createUnionTypeNode(t.map(r=>i.createLiteralTypeNode(i.createStringLiteral(r))))),Ge=(e,t)=>i.createTypeAliasDeclaration(re,e,void 0,t),yr=(e,t,r)=>i.createPropertyDeclaration(Do,e,void 0,t,r),gr=(e,t,r=[])=>i.createClassDeclaration(re,e,void 0,void 0,[t,...r]),hr=(e,t)=>i.createTypeReferenceNode("Promise",[i.createIndexedAccessTypeNode(i.createTypeReferenceNode(e),t)]),xr=()=>i.createTypeReferenceNode("Promise",[i.createKeywordTypeNode(D.default.SyntaxKind.AnyKeyword)]),Zt=(e,t,r)=>i.createInterfaceDeclaration(re,e,void 0,t,r),Tr=e=>Object.keys(e).reduce((t,r)=>t.concat(i.createTypeParameterDeclaration([],r,i.createTypeReferenceNode(e[r]))),[]),Sr=(e,t)=>i.createArrowFunction(Mo,void 0,e.map(r=>$e(r)),void 0,void 0,i.createCallExpression(i.createPropertyAccessExpression(i.createThis(),"implementation"),void 0,t)),Et=(e,t,r)=>i.createCallExpression(i.createPropertyAccessExpression(i.createCallExpression(i.createPropertyAccessExpression(i.createIdentifier("Object"),"keys"),void 0,[i.createIdentifier(e)]),"reduce"),void 0,[i.createArrowFunction(void 0,void 0,_e({acc:void 0,key:void 0}),void 0,void 0,t),r]);var f=R(require("typescript")),Pr=require("zod");var _=R(require("typescript")),{factory:qe}=_.default,At=(e,t)=>{_.default.addSyntheticLeadingComment(e,_.default.SyntaxKind.MultiLineCommentTrivia,`* ${t} `,!0)},Ve=(e,t,r)=>{let o=qe.createTypeAliasDeclaration(void 0,qe.createIdentifier(t),void 0,e);return r&&At(o,r),o},Or=(e,t)=>{let r=_.default.createSourceFile("print.ts","",_.default.ScriptTarget.Latest,!1,_.default.ScriptKind.TS);return _.default.createPrinter(t).printNode(_.default.EmitHint.Unspecified,e,r)},Lo=/^[A-Za-z_$][A-Za-z0-9_$]*$/,br=e=>Lo.test(e)?qe.createIdentifier(e):qe.createStringLiteral(e);var{factory:u}=f.default,ko={[f.default.SyntaxKind.AnyKeyword]:"",[f.default.SyntaxKind.BigIntKeyword]:BigInt(0),[f.default.SyntaxKind.BooleanKeyword]:!1,[f.default.SyntaxKind.NumberKeyword]:0,[f.default.SyntaxKind.ObjectKeyword]:{},[f.default.SyntaxKind.StringKeyword]:"",[f.default.SyntaxKind.UndefinedKeyword]:void 0},Ho=({schema:{value:e}})=>u.createLiteralTypeNode(typeof e=="number"?u.createNumericLiteral(e):typeof e=="boolean"?e?u.createTrue():u.createFalse():u.createStringLiteral(e)),Uo=({schema:{shape:e},isResponse:t,next:r,optionalPropStyle:{withQuestionMark:o}})=>{let n=Object.entries(e).map(([s,a])=>{let p=t&&Te(a)?a instanceof Pr.z.ZodOptional:a.isOptional(),d=u.createPropertySignature(void 0,br(s),p&&o?u.createToken(f.default.SyntaxKind.QuestionToken):void 0,r({schema:a}));return a.description&&At(d,a.description),d});return u.createTypeLiteralNode(n)},Ko=({schema:{element:e},next:t})=>u.createArrayTypeNode(t({schema:e})),Fo=({schema:{options:e}})=>u.createUnionTypeNode(e.map(t=>u.createLiteralTypeNode(u.createStringLiteral(t)))),Rr=({schema:{options:e},next:t})=>u.createUnionTypeNode(e.map(r=>t({schema:r}))),$o=e=>ko?.[e.kind],_o=({schema:e,next:t,isResponse:r})=>{let o=t({schema:e.innerType()}),n=e._def.effect;if(r&&n.type==="transform"){let s=Ne({effect:n,sample:$o(o)}),a={number:f.default.SyntaxKind.NumberKeyword,bigint:f.default.SyntaxKind.BigIntKeyword,boolean:f.default.SyntaxKind.BooleanKeyword,string:f.default.SyntaxKind.StringKeyword,undefined:f.default.SyntaxKind.UndefinedKeyword,object:f.default.SyntaxKind.ObjectKeyword};return u.createKeywordTypeNode(s&&a[s]||f.default.SyntaxKind.AnyKeyword)}return o},Go=({schema:e})=>u.createUnionTypeNode(Object.values(e.enum).map(t=>u.createLiteralTypeNode(typeof t=="number"?u.createNumericLiteral(t):u.createStringLiteral(t)))),qo=({next:e,schema:t,optionalPropStyle:{withUndefined:r}})=>{let o=e({schema:t.unwrap()});return r?u.createUnionTypeNode([o,u.createKeywordTypeNode(f.default.SyntaxKind.UndefinedKeyword)]):o},Vo=({next:e,schema:t})=>u.createUnionTypeNode([e({schema:t.unwrap()}),u.createLiteralTypeNode(u.createNull())]),Bo=({next:e,schema:{items:t}})=>u.createTupleTypeNode(t.map(r=>e({schema:r}))),Yo=({next:e,schema:{keySchema:t,valueSchema:r}})=>u.createExpressionWithTypeArguments(u.createIdentifier("Record"),[e({schema:t}),e({schema:r})]),Jo=({next:e,schema:t})=>u.createIntersectionTypeNode([t._def.left,t._def.right].map(r=>e({schema:r}))),Qo=({next:e,schema:t})=>e({schema:t._def.innerType}),Y=e=>()=>u.createKeywordTypeNode(e),Wo=({next:e,schema:t})=>e({schema:t.unwrap()}),Xo=({next:e,schema:t})=>e({schema:t._def.innerType}),en=({next:e,schema:t})=>e({schema:t._def.innerType}),tn=({schema:e,next:t,isResponse:r})=>t({schema:e._def[r?"out":"in"]}),rn=()=>u.createLiteralTypeNode(u.createNull()),on=({getAlias:e,makeAlias:t,next:r,serializer:o,schema:n})=>{let s=`Type${o(n.schema)}`;return e(s)||(()=>(t(s,u.createLiteralTypeNode(u.createNull())),t(s,r({schema:n.schema}))))()},nn={ZodString:Y(f.default.SyntaxKind.StringKeyword),ZodNumber:Y(f.default.SyntaxKind.NumberKeyword),ZodBigInt:Y(f.default.SyntaxKind.BigIntKeyword),ZodBoolean:Y(f.default.SyntaxKind.BooleanKeyword),ZodDateIn:Y(f.default.SyntaxKind.StringKeyword),ZodDateOut:Y(f.default.SyntaxKind.StringKeyword),ZodNull:rn,ZodArray:Ko,ZodTuple:Bo,ZodRecord:Yo,ZodObject:Uo,ZodLiteral:Ho,ZodIntersection:Jo,ZodUnion:Rr,ZodFile:Y(f.default.SyntaxKind.StringKeyword),ZodAny:Y(f.default.SyntaxKind.AnyKeyword),ZodDefault:Qo,ZodEnum:Fo,ZodNativeEnum:Go,ZodEffects:_o,ZodOptional:qo,ZodNullable:Vo,ZodDiscriminatedUnion:Rr,ZodBranded:Wo,ZodCatch:en,ZodPipeline:tn,ZodLazy:on,ZodReadonly:Xo},It=({schema:e,...t})=>te({schema:e,rules:nn,onMissing:()=>u.createKeywordTypeNode(f.default.SyntaxKind.AnyKeyword),...t});var Be=class{agg=[];registry={};paths=[];aliases={};getAlias(t){return t in this.aliases?i.createTypeReferenceNode(t):void 0}makeAlias(t,r){return this.aliases[t]=Ve(r,t),this.getAlias(t)}constructor({routing:t,variant:r="client",serializer:o=Ce,optionalPropStyle:n={withQuestionMark:!0,withUndefined:!0}}){ee({routing:t,onEndpoint:(m,O,v)=>{let fe=H(O,v,"input"),Qe=H(O,v,"response"),N={serializer:o,getAlias:this.getAlias.bind(this),makeAlias:this.makeAlias.bind(this),optionalPropStyle:n},Re=It({...N,schema:m.getSchema("input"),isResponse:!1}),We=It({...N,isResponse:!0,schema:m.getSchema("positive").or(m.getSchema("negative"))});this.agg.push(Ve(Re,fe),Ve(We,Qe)),v!=="options"&&(this.paths.push(O),this.registry[`${v} ${O}`]={in:fe,out:Qe,isJson:m.getMimeTypes("positive").includes(J),tags:m.getTags()})}}),this.agg=Object.values(this.aliases).concat(this.agg);let s=Pt("Path",this.paths),a=Pt("Method",Ft),p=Ge("MethodPath",Tt([a.name,s.name])),d=[i.createHeritageClause(G.default.SyntaxKind.ExtendsKeyword,[Ot(p.name,G.default.SyntaxKind.AnyKeyword)])],c=Zt("Input",d,Object.keys(this.registry).map(m=>bt(m,this.registry[m].in))),l=Zt("Response",d,Object.keys(this.registry).map(m=>bt(m,this.registry[m].out)));if(this.agg.push(s,a,p,c,l),r==="types")return;let g=i.createVariableStatement(re,Rt("jsonEndpoints",i.createObjectLiteralExpression(Object.keys(this.registry).filter(m=>this.registry[m].isJson).map(m=>i.createPropertyAssignment(`"${m}"`,i.createTrue()))))),y=i.createVariableStatement(re,Rt("endpointTags",i.createObjectLiteralExpression(Object.keys(this.registry).map(m=>i.createPropertyAssignment(`"${m}"`,i.createArrayLiteralExpression(this.registry[m].tags.map(O=>i.createStringLiteral(O)))))))),S=Ge("Provider",i.createFunctionTypeNode(Tr({M:a.name,P:s.name}),_e({method:i.createTypeReferenceNode("M"),path:i.createTypeReferenceNode("P"),params:i.createIndexedAccessTypeNode(i.createTypeReferenceNode(c.name),St)}),hr(l.name,St))),I=Ge("Implementation",i.createFunctionTypeNode(void 0,_e({method:i.createTypeReferenceNode(a.name),path:i.createKeywordTypeNode(G.default.SyntaxKind.StringKeyword),params:Ot(G.default.SyntaxKind.StringKeyword,G.default.SyntaxKind.AnyKeyword)}),xr())),h=i.createTemplateExpression(i.createTemplateHead(":"),[i.createTemplateSpan(i.createIdentifier("key"),i.createTemplateTail(""))]),z=gr("ExpressZodAPIClient",fr([$e("implementation",i.createTypeReferenceNode(I.name),ur)]),[yr("provide",i.createTypeReferenceNode(S.name),Sr(["method","path","params"],[i.createIdentifier("method"),Et("params",i.createCallExpression(i.createPropertyAccessExpression(i.createIdentifier("acc"),"replace"),void 0,[h,i.createElementAccessExpression(i.createIdentifier("params"),i.createIdentifier("key"))]),i.createIdentifier("path")),Et("params",i.createConditionalExpression(i.createBinaryExpression(i.createCallExpression(i.createPropertyAccessExpression(i.createIdentifier("path"),"indexOf"),void 0,[h]),G.default.SyntaxKind.GreaterThanEqualsToken,i.createNumericLiteral(0)),void 0,i.createIdentifier("acc"),void 0,i.createObjectLiteralExpression([i.createSpreadAssignment(i.createIdentifier("acc")),i.createPropertyAssignment(i.createComputedPropertyName(i.createIdentifier("key")),i.createElementAccessExpression(i.createIdentifier("params"),i.createIdentifier("key")))])),i.createObjectLiteralExpression())]))]);G.default.addSyntheticLeadingComment(z,G.default.SyntaxKind.MultiLineCommentTrivia,`
|
|
35
35
|
export const exampleImplementation: Implementation = async (
|
|
36
36
|
method,
|
|
37
37
|
path,
|
|
@@ -52,6 +52,6 @@ export const exampleImplementation: Implementation = async (
|
|
|
52
52
|
|
|
53
53
|
const client = new ExpressZodAPIClient(exampleImplementation);
|
|
54
54
|
client.provide("get", "/v1/user/retrieve", { id: "10" });
|
|
55
|
-
`,!0),this.agg.push(
|
|
55
|
+
`,!0),this.agg.push(g,y,S,I,z)}print(t){return this.agg.map(r=>Or(r,t)).join(`
|
|
56
56
|
|
|
57
|
-
`)}};var
|
|
57
|
+
`)}};var Ct={};wt(Ct,{dateIn:()=>ln,dateOut:()=>mn,file:()=>pn,upload:()=>cn});var Z=require("zod");var sn="ZodDateOut",Ye=class e extends Z.ZodType{_parse(t){let{status:r,ctx:o}=this._processInputParams(t);return o.parsedType!==Z.ZodParsedType.date?((0,Z.addIssueToContext)(o,{code:Z.ZodIssueCode.invalid_type,expected:Z.ZodParsedType.date,received:o.parsedType}),Z.INVALID):Ie(o.data)?{status:r.value,value:o.data.toISOString()}:((0,Z.addIssueToContext)(o,{code:Z.ZodIssueCode.invalid_date}),Z.INVALID)}static create=()=>new e({typeName:sn})};var A=require("zod");var an="ZodFile",dn=/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/,Je=class e extends A.ZodType{_parse(t){let{status:r,ctx:o}=this._processInputParams(t);if(o.parsedType!==A.ZodParsedType.string)return(0,A.addIssueToContext)(o,{code:A.ZodIssueCode.invalid_type,expected:A.ZodParsedType.string,received:o.parsedType}),A.INVALID;for(let n of this._def.checks)n.kind==="base64"&&(dn.test(o.data)||((0,A.addIssueToContext)(o,{code:A.ZodIssueCode.custom,message:n.message}),r.dirty()));return{status:r.value,value:o.data}}binary=t=>new e({...this._def,checks:[...this._def.checks,{kind:"binary",...it(t)}]});base64=t=>new e({...this._def,checks:[...this._def.checks,{kind:"base64",...it(t)}]});get isBinary(){return!!this._def.checks.find(t=>t.kind==="binary")}get isBase64(){return!!this._def.checks.find(t=>t.kind==="base64")}static create=()=>new e({checks:[],typeName:an})};var pn=Je.create,cn=oe.create,ln=He.create,mn=Ye.create;var Zr=R(require("http-errors"));0&&(module.exports={AbstractEndpoint,DependsOnMethod,DependsOnMethodError,Documentation,DocumentationError,EndpointsFactory,InputValidationError,Integration,OutputValidationError,RoutingError,ServeStatic,arrayEndpointsFactory,arrayResultHandler,attachRouting,createConfig,createHttpError,createLogger,createMiddleware,createResultHandler,createServer,defaultEndpointsFactory,defaultResultHandler,ez,getExamples,getMessageFromError,getStatusCodeFromError,testEndpoint,withMeta});
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
var
|
|
1
|
+
var lr=Object.defineProperty;var mr=(e,t)=>{for(var r in t)lr(e,r,{get:t[r],enumerable:!0})};var St={silent:!0,warn:!0,debug:!0},ur=e=>e;import{z as H}from"zod";import{HttpError as Er}from"http-errors";import{createHash as Ar}from"crypto";import{z as O}from"zod";import{clone as fr,mergeDeepRight as yr}from"ramda";var b="expressZodApiMeta",gr=e=>{let t=e.constructor,r=fr(e._def);return r[b]=r[b]||{examples:[]},new t(r)},D=e=>{let t=gr(e);return Object.defineProperties(t,{example:{get:()=>r=>{let o=D(t);return o._def[b].examples.push(r),o}}}),t},Ot=e=>b in e._def?typeof e._def[b]=="object"&&e._def[b]!==null:!1,bt=(e,t)=>{if(!Ot(e))return;let r=e._def;return t in r[b]?r[b][t]:void 0},ye=(e,t)=>{if(!Ot(e))return t;let r=D(t),o=oe(r._def[b].examples,e._def[b].examples);if(r._def[b].examples=[],o.type==="single")r._def[b].examples=o.value;else for(let[n,s]of o.value)r._def[b].examples.push(yr({...n},{...s}));return r};import hr from"mime";var $=hr.getType("json")||"application/json",ne="multipart/form-data";import{INVALID as xr,OK as Tr,ZodIssueCode as Sr,ZodParsedType as Or,ZodType as br,addIssueToContext as Rr}from"zod";var Pr="ZodUpload",Zr=e=>typeof e=="object"&&e!==null&&"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.mimetype=="string"&&typeof e.data=="object"&&typeof e.tempFilePath=="string"&&typeof e.truncated=="boolean"&&typeof e.size=="number"&&typeof e.md5=="string"&&typeof e.mv=="function",B=class e extends br{_parse(t){let{ctx:r}=this._processInputParams(t);return r.parsedType!==Or.object||!Zr(r.data)?(Rr(r,{code:Sr.custom,message:`Expected file upload, received ${r.parsedType}`}),xr):Tr(r.data)}static create=()=>new e({typeName:Pr})};var Ue=/:([A-Za-z0-9_]+)/g,Ir=e=>{let r=(e.header("content-type")||"").slice(0,ne.length).toLowerCase()===ne;return"files"in e&&r},ge={get:["query","params"],post:["body","params","files"],put:["body","params"],patch:["body","params"],delete:["query","params"]},Cr=["body","query","params"],Ke=e=>e.method.toLowerCase(),Fe=e=>e.startsWith("x-"),Nr=e=>Object.entries(e.headers).reduce((t,[r,o])=>Fe(r)?{...t,[r]:o}:t,{}),Rt=(e,t)=>{let r=Ke(e);if(r==="options")return{};let o=Cr;return r in ge&&(o=ge[r]),t&&r in t&&(o=t[r]||o),o.filter(n=>n==="files"?Ir(e):!0).reduce((n,s)=>({...n,...s==="headers"?Nr(e):e[s]}),{})},$e=e=>typeof e=="object"&&"level"in e&&"color"in e&&Object.keys(St).includes(e.level)&&typeof e.color=="boolean",he=e=>!isNaN(e.getTime()),Y=e=>e instanceof Error?e:new Error(typeof e=="symbol"?e.toString():`${e}`),v=e=>e instanceof O.ZodError?e.issues.map(({path:t,message:r})=>(t.length?[t.join("/")]:[]).concat(r).join(": ")).join("; "):e instanceof _?`output${e.originalError.issues[0]?.path.length>0?"/":": "}${e.message}`:e.message,xe=e=>e instanceof Er?e.statusCode:e instanceof L?400:500,_e=({logger:e,request:t,input:r,error:o,statusCode:n})=>{n===500&&e.error(`Internal server error
|
|
2
2
|
${o.stack}
|
|
3
|
-
`,{url:t.url,payload:r})},
|
|
4
|
-
Caused by ${n?"response":"input"} schema of an Endpoint assigned to ${r.toUpperCase()} method of ${o} path.`;super(s)}},
|
|
5
|
-
Original error: ${e.originalError.message}.`:""))};var
|
|
3
|
+
`,{url:t.url,payload:r})},j=({schema:e,variant:t="original",validate:r=t==="parsed"})=>{let o=bt(e,"examples")||[];if(!r&&t==="original")return o;let n=[];for(let s of o){let a=e.safeParse(s);a.success&&n.push(t==="parsed"?a.data:s)}return n},oe=(e,t)=>{if(e.length===0)return{type:"single",value:t};if(t.length===0)return{type:"single",value:e};let r=[];for(let o of e)for(let n of t)r.push([o,n]);return{type:"tuple",value:r}},Ge=e=>{let t=e.match(Ue);return t?t.map(r=>r.slice(1)):[]},se=e=>e.reduce((t,r)=>t||r,!1),z=e=>e instanceof O.ZodEffects&&e._def.effect.type!=="refinement"?!0:e instanceof O.ZodUnion?se(e.options.map(z)):e instanceof O.ZodIntersection?se([e._def.left,e._def.right].map(z)):!1,E=e=>e instanceof B?!0:e instanceof O.ZodObject?se(Object.values(e.shape).map(E)):e instanceof O.ZodUnion?se(e.options.map(E)):e instanceof O.ZodIntersection?se([e._def.left,e._def.right].map(E)):e instanceof O.ZodOptional||e instanceof O.ZodNullable?E(e.unwrap()):e instanceof O.ZodEffects||e instanceof O.ZodTransformer?E(e._def.schema):e instanceof O.ZodRecord?E(e._def.valueType):e instanceof O.ZodArray?E(e._def.type):e instanceof O.ZodDefault?E(e._def.innerType):!1,ie=e=>"coerce"in e._def&&typeof e._def.coerce=="boolean"?e._def.coerce:!1,N=(e,t,r)=>[t].concat(e.split("/")).concat(r||[]).flatMap(o=>o.split(/[^A-Z0-9]/gi)).map(o=>o.slice(0,1).toUpperCase()+o.slice(1).toLowerCase()).join(""),Te=e=>Ar("sha1").update(JSON.stringify(e),"utf8").digest("hex"),Se=({effect:e,sample:t})=>{try{return typeof e.transform(t,{addIssue:()=>{},path:[]})}catch{return}},qe=e=>typeof e=="string"?{message:e}:e||{};var J=class extends Error{name="RoutingError"},ae=class extends J{name="DependsOnMethodError"},R=class extends Error{name="DocumentationError";constructor({message:t,method:r,path:o,isResponse:n}){let s=`${t}
|
|
4
|
+
Caused by ${n?"response":"input"} schema of an Endpoint assigned to ${r.toUpperCase()} method of ${o} path.`;super(s)}},k=class extends Error{name="IOSchemaError"},_=class extends k{name="OutputValidationError";originalError;constructor(t){super(v(t)),this.originalError=t}},L=class extends k{name="InputValidationError";originalError;constructor(t){super(v(t)),this.originalError=t}},Q=class extends Error{name="ResultHandlerError";originalError;constructor(t,r){super(t),this.originalError=r||void 0}};var w=e=>typeof e=="object"&&e!==null,Oe=e=>({and:e.reduce((t,r)=>t.concat(w(r)&&"and"in r?r.and:r),[])}),be=(e,t)=>{if(w(e)){if("and"in e)return{and:e.and.map(r=>w(r)&&"or"in r?{or:r.or.map(t)}:t(r))};if("or"in e)return{or:e.or.map(r=>w(r)&&"and"in r?{and:r.and.map(t)}:t(r))}}return t(e)},Ve=e=>e.and.reduce((t,r)=>{let o=oe(t.or,w(r)&&"or"in r?r.or:[r]);return o.type==="single"?t.or.push(...o.value):t.or=o.value.map(Oe),t},{or:[]}),W=(e,t)=>{if(w(e)){if("and"in e){if(w(t)){if("and"in t)return Oe([e,t]);if("or"in t)return W(Ve(e),t)}return Oe([e,t])}if("or"in e){if(w(t)){if("and"in t)return W(t,e);if("or"in t){let r=oe(e.or,t.or);return{or:r.type==="single"?r.value:r.value.map(Oe)}}}return W(e,{and:[t]})}}return w(t)&&("and"in t||"or"in t)?W(t,e):{and:[e,t]}};import{z as A}from"zod";var X={positive:200,negative:400},Be=e=>e,ee=Be({getPositiveResponse:e=>{let t=j({schema:e}),r=D(A.object({status:A.literal("success"),data:e}));return t.reduce((o,n)=>o.example({status:"success",data:n}),r)},getNegativeResponse:()=>D(A.object({status:A.literal("error"),error:A.object({message:A.string()})})).example({status:"error",error:{message:v(new Error("Sample error message"))}}),handler:({error:e,input:t,output:r,request:o,response:n,logger:s})=>{if(!e){n.status(X.positive).json({status:"success",data:r});return}let a=xe(e);_e({logger:s,statusCode:a,request:o,error:e,input:t}),n.status(a).json({status:"error",error:{message:v(e)}})}}),Ye=Be({getPositiveResponse:e=>{let t=j({schema:e}),r=D("shape"in e&&"items"in e.shape&&e.shape.items instanceof A.ZodArray?e.shape.items:A.array(A.any()));return t.reduce((o,n)=>typeof n=="object"&&n!==null&&"items"in n&&Array.isArray(n.items)?o.example(n.items):o,r)},getNegativeResponse:()=>D(A.string()).example(v(new Error("Sample error message"))),handler:({response:e,output:t,error:r,logger:o,request:n,input:s})=>{if(r){let a=xe(r);_e({logger:o,statusCode:a,request:n,error:r,input:s}),e.status(a).send(r.message);return}"items"in t&&Array.isArray(t.items)?e.status(200).json(t.items):e.status(500).send("Property 'items' is missing in the endpoint output")}}),Re=({error:e,logger:t,response:r})=>{t.error(`Result handler failure: ${e.message}.`),r.status(500).end(`An error occurred while serving the result: ${e.message}.`+(e.originalError?`
|
|
5
|
+
Original error: ${e.originalError.message}.`:""))};var Pt=(e,t=[$])=>{if(e instanceof H.ZodType)return t;let{mimeTypes:r,mimeType:o}=e;return o?[o]:r||t},te=class{},Pe=class extends te{#e;#t=[];#i=[];#o=[];#a;#d;#p;#c;#r;#n=[];#s=[];#l;constructor({middlewares:t,inputSchema:r,outputSchema:o,handler:n,resultHandler:s,description:a,shortDescription:p,...d}){super(),[{name:"input schema",schema:r},{name:"output schema",schema:o}].forEach(({name:l,schema:g})=>{if(z(g))throw new k(`Using transformations on the top level of endpoint ${l} is not allowed.`)}),this.#o=t,this.#l=d.operationId;let c={positive:s.getPositiveResponse(o),negative:s.getNegativeResponse()};this.#a={input:E(r)?[ne]:[$],positive:Pt(c.positive),negative:Pt(c.negative)},this.#r={input:r,output:o,positive:c.positive instanceof H.ZodType?c.positive:c.positive.schema,negative:c.negative instanceof H.ZodType?c.negative:c.negative.schema},this.#d={positive:c.positive instanceof H.ZodType?X.positive:c.positive.statusCode||X.positive,negative:c.negative instanceof H.ZodType?X.negative:c.negative.statusCode||X.negative},this.#p=n,this.#c=s,this.#e={long:a,short:p},"scopes"in d&&d.scopes&&this.#n.push(...d.scopes),"scope"in d&&d.scope&&this.#n.push(d.scope),"tags"in d&&d.tags&&this.#s.push(...d.tags),"tag"in d&&d.tag&&this.#s.push(d.tag),"methods"in d?this.#t=d.methods:this.#t=[d.method]}_setSiblingMethods(t){this.#i=t}getDescription(t){return this.#e[t]}getMethods(){return this.#t}getSchema(t){return this.#r[t]}getMimeTypes(t){return this.#a[t]}getStatusCode(t){return this.#d[t]}getSecurity(){return this.#o.reduce((t,r)=>r.security?W(t,r.security):t,{and:[]})}getScopes(){return this.#n}getTags(){return this.#s}getOperationId(){return this.#l}#m(){return{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":this.#t.concat(this.#i).concat("options").join(", ").toUpperCase(),"Access-Control-Allow-Headers":"content-type"}}async#u(t){try{return await this.#r.output.parseAsync(t)}catch(r){throw r instanceof H.ZodError?new _(r):r}}async#f({method:t,input:r,request:o,response:n,logger:s}){let a={},p=!1;for(let d of this.#o){if(t==="options"&&d.type==="proprietary")continue;let c;try{c=await d.input.parseAsync(r)}catch(l){throw l instanceof H.ZodError?new L(l):l}if(Object.assign(a,await d.middleware({input:c,options:a,request:o,response:n,logger:s})),p="writableEnded"in n&&n.writableEnded,p){s.warn(`The middleware ${d.middleware.name} has closed the stream. Accumulated options:`,a);break}}return{options:a,isStreamClosed:p}}async#y({input:t,options:r,logger:o}){let n;try{n=await this.#r.input.parseAsync(t)}catch(s){throw s instanceof H.ZodError?new L(s):s}return this.#p({input:n,options:r,logger:o})}async#g({error:t,request:r,response:o,logger:n,input:s,output:a}){try{await this.#c.handler({error:t,output:a,request:r,response:o,logger:n,input:s})}catch(p){Re({logger:n,response:o,error:new Q(Y(p).message,t)})}}async execute({request:t,response:r,logger:o,config:n}){let s=Ke(t),a,p=null;if(n.cors){let c=this.#m();typeof n.cors=="function"&&(c=await n.cors({request:t,logger:o,endpoint:this,defaultHeaders:c}));for(let l in c)r.set(l,c[l])}let d=Rt(t,n.inputSources);try{let{options:c,isStreamClosed:l}=await this.#f({method:s,input:d,request:t,response:r,logger:o});if(l)return;if(s==="options"){r.status(200).end();return}a=await this.#u(await this.#y({input:d,options:c,logger:o}))}catch(c){p=Y(c)}await this.#g({input:d,output:a,request:t,response:r,error:p,logger:o})}};var Zt=["get","post","put","delete","patch"];import{z as At}from"zod";var Et=(e,t)=>{let r=e.map(({input:n})=>n).concat(t),o=r.reduce((n,s)=>n.and(s));return r.reduce((n,s)=>ye(s,n),o)};var Je=e=>{if(z(e.input))throw new k("Using transformations on the top level of middleware input schema is not allowed.");return{...e,type:"proprietary"}};var de=class e{resultHandler;middlewares=[];constructor(t){this.resultHandler="resultHandler"in t?t.resultHandler:t}static#e(t,r){let o=new e(r);return o.middlewares=t,o}addMiddleware(t){return e.#e(this.middlewares.concat(t),this.resultHandler)}use=this.addExpressMiddleware;addExpressMiddleware(t,r){let o=r?.transformer||(a=>a),n=r?.provider||(()=>({})),s={type:"express",input:At.object({}),middleware:async({request:a,response:p})=>new Promise((d,c)=>{t(a,p,g=>{if(g&&g instanceof Error)return c(o(g));d(n(a,p))})})};return e.#e(this.middlewares.concat(s),this.resultHandler)}addOptions(t){return e.#e(this.middlewares.concat(Je({input:At.object({}),middleware:async()=>t})),this.resultHandler)}build({input:t,handler:r,output:o,...n}){let{middlewares:s,resultHandler:a}=this;return new Pe({handler:r,middlewares:s,outputSchema:o,resultHandler:a,inputSchema:Et(s,t),...n})}},wr=new de(ee),Mr=new de(Ye);import{inspect as Dr}from"util";import{LEVEL as zr,MESSAGE as vr,SPLAT as jr}from"triple-beam";import Ze from"winston";var{combine:Lr,colorize:kr,timestamp:Hr,printf:Ur}=Ze.format,Ee=e=>{let t=s=>{let{[zr]:a,[vr]:p,[jr]:d,...c}=s;return Dr(c,!1,1,e.color)},r=s=>Ur(({timestamp:a,message:p,level:d,durationMs:c,...l})=>(typeof p=="object"&&(l={...l,...p},p="[No message]"),`${a} ${d}: ${p}`+(c===void 0?"":` duration: ${c}ms`)+(Object.keys(l).length===0?"":" "+(s?t(l):JSON.stringify(l))))),o=[Hr()],n={handleExceptions:!0};switch(e.color&&o.push(kr()),e.level){case"debug":n.level="debug",o.push(r(!0));break;case"silent":case"warn":default:n.level="warn",o.push(r())}return n.format=Lr(...o),Ze.createLogger({silent:e.level==="silent",levels:Ze.config.npm.levels,transports:[new Ze.transports.Console(n)],exitOnError:!1})};var pe=class{constructor(t){this.methods=t;Object.keys(t).forEach(r=>{if(r in t&&!(t[r]?.getMethods()||[]).includes(r))throw new ae(`The endpoint assigned to the '${r}' parameter must have at least this method in its specification.
|
|
6
6
|
This error should prevent mistakes during the development process.
|
|
7
7
|
Example:
|
|
8
8
|
|
|
@@ -13,8 +13,8 @@ new ${this.constructor.name}({
|
|
|
13
13
|
...
|
|
14
14
|
})
|
|
15
15
|
});
|
|
16
|
-
`)})}};import
|
|
17
|
-
The error caused by ${o?`'${o}' route that has a '${s}'`:`'${s}'`} entry.`);let p=`${o||""}${s?`/${s}`:""}`;if(a instanceof te){let d=a.getMethods().slice();n&&d.push("options"),d.forEach(c=>{t(a,p,c)})}else if(a instanceof
|
|
16
|
+
`)})}};import Kr from"express";var ce=class{params;constructor(...t){this.params=t}apply(t,r){return r(t,Kr.static(...this.params))}};var G=({routing:e,onEndpoint:t,onStatic:r,parentPath:o,hasCors:n})=>{Object.entries(e).forEach(([s,a])=>{if(s=s.trim(),s.match(/\//))throw new J(`Routing elements should not contain '/' character.
|
|
17
|
+
The error caused by ${o?`'${o}' route that has a '${s}'`:`'${s}'`} entry.`);let p=`${o||""}${s?`/${s}`:""}`;if(a instanceof te){let d=a.getMethods().slice();n&&d.push("options"),d.forEach(c=>{t(a,p,c)})}else if(a instanceof ce)r&&a.apply(p,r);else if(a instanceof pe){if(Object.entries(a.methods).forEach(([d,c])=>{t(c,p,d)}),n&&Object.keys(a.methods).length>0){let[d,...c]=Object.keys(a.methods),l=a.methods[d];l._setSiblingMethods(c),t(l,p,"options")}}else G({onEndpoint:t,onStatic:r,hasCors:n,routing:a,parentPath:p})})};var It=()=>`
|
|
18
18
|
\x1B[94m\x1B[39m
|
|
19
19
|
\x1B[94m\x1B[39m
|
|
20
20
|
\x1B[94m8888888888 8888888888P 888 d8888 8888888b. 8888888 \x1B[39m
|
|
@@ -31,7 +31,7 @@ The error caused by ${o?`'${o}' route that has a '${s}'`:`'${s}'`} entry.`);let
|
|
|
31
31
|
\x1B[90m\x1B[3m Thank you for choosing Express Zod API for your project.\x1B[23m\x1B[39m\x1B[0m\x1B[0m
|
|
32
32
|
\x1B[0m\x1B[0m
|
|
33
33
|
\x1B[0m\x1B[0m
|
|
34
|
-
`.trim();var Ye=({app:e,logger:t,config:r,routing:o})=>{r.startupLogo!==!1&&console.log(At()),G({routing:o,hasCors:!!r.cors,onEndpoint:(n,s,a)=>{e[a](s,async(p,d)=>{t.info(`${p.method}: ${s}`),await n.execute({request:p,response:d,logger:t,config:r})})},onStatic:(n,s)=>{e.use(n,s)}})};import Ur,{json as Hr}from"express";import Kr from"compression";import Fr from"express-fileupload";import $r from"https";import Et from"http-errors";var _r=(e,t)=>(r,o,n,s)=>{if(!r)return s();e.handler({error:Et(400,Y(r).message),request:o,response:n,logger:t,input:o.body,output:null})},It=(e,t)=>(r,o)=>{let n=Et(404,`Can not ${r.method} ${r.path}`);try{e.handler({request:r,response:o,logger:t,error:n,input:null,output:null})}catch(s){Pe({response:o,logger:t,error:new Q(Y(s).message,n)})}};function Gr(e,t){let r=Ke(e.logger)?Ee(e.logger):e.logger;Ye({app:e.app,routing:t,logger:r,config:e});let o=e.errorHandler||ee;return{notFoundHandler:It(o,r),logger:r}}function qr(e,t){let r=Ke(e.logger)?Ee(e.logger):e.logger,o=Ur();o.disable("x-powered-by");let n=e.errorHandler||ee,s=e.server.compression?Kr({...typeof e.server.compression=="object"?e.server.compression:{}}):void 0,a=e.server.jsonParser||Hr(),p=e.server.upload?Fr({...typeof e.server.upload=="object"?e.server.upload:{},abortOnLimit:!1,parseNested:!0}):void 0,d=[].concat(s||[]).concat(a).concat(p||[]);o.use(d),o.use(_r(n,r)),Ye({app:o,routing:t,logger:r,config:e}),o.use(It(n,r));let c=o.listen(e.server.listen,()=>{r.info(`Listening ${e.server.listen}`)}),l;return e.https&&(l=$r.createServer(e.https.options,o).listen(e.https.listen,()=>{r.info(`Listening ${e.https.listen}`)})),{app:o,httpServer:c,httpsServer:l,logger:r}}import{OpenApiBuilder as zo}from"openapi3-ts/oas30";import{isReferenceObject as Dt,isSchemaObject as ye}from"openapi3-ts/oas30";import{omit as fe}from"ramda";import{z as x}from"zod";import{INVALID as Ct,ZodIssueCode as Je,ZodParsedType as Nt,ZodType as Vr,addIssueToContext as Qe}from"zod";var We=/^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d+)?)?Z?$/,Br="ZodDateIn",Ie=class e extends Vr{_parse(t){let{status:r,ctx:o}=this._processInputParams(t);if(o.parsedType!==Nt.string)return Qe(o,{code:Je.invalid_type,expected:Nt.string,received:o.parsedType}),Ct;We.test(o.data)||(Qe(o,{code:Je.invalid_string,validation:"regex"}),r.dirty());let n=new Date(o.data);return xe(n)?{status:r.value,value:n}:(Qe(o,{code:Je.invalid_date}),Ct)}static create=()=>new e({typeName:Br})};var q=({schema:e,onEach:t,rules:r,onMissing:o,...n})=>{let s="typeName"in e._def?r[e._def.typeName]:void 0,p=s?s({schema:e,...n,next:c=>q({...c,...n,onEach:t,rules:r,onMissing:o})}):o({schema:e,...n}),d=t&&t({schema:e,prev:p,...n});return d?{...p,...d}:p};var Mt=50,zt="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString",Yr={integer:0,number:0,string:"",boolean:!1,object:{},null:null,array:[]},vt=e=>e.replace(Ue,t=>`{${t.slice(1)}}`),Jr=({schema:{_def:{innerType:e,defaultValue:t}},next:r})=>({...r({schema:e}),default:t()}),Qr=({schema:{_def:{innerType:e}},next:t})=>t({schema:e}),Wr=()=>({format:"any"}),Xr=e=>{if(e.isResponse)throw new Z({message:"Please use z.upload() only for input.",...e});return{type:"string",format:"binary"}},eo=({schema:{isBinary:e,isBase64:t},...r})=>{if(!r.isResponse)throw new Z({message:"Please use z.file() only within ResultHandler.",...r});return{type:"string",format:e?"binary":t?"byte":"file"}},to=({schema:{options:e},next:t})=>({oneOf:e.map(r=>t({schema:r}))}),ro=({schema:{options:e,discriminator:t},next:r})=>({discriminator:{propertyName:t},oneOf:Array.from(e.values()).map(o=>r({schema:o}))}),oo=({schema:{_def:{left:e,right:t}},next:r})=>({allOf:[e,t].map(o=>r({schema:o}))}),no=({schema:e,next:t})=>t({schema:e.unwrap()}),so=({schema:e,next:t})=>t({schema:e._def.innerType}),io=({schema:e,next:t})=>({nullable:!0,...t({schema:e.unwrap()})}),wt=({schema:e})=>({type:typeof Object.values(e.enum)[0],enum:Object.values(e.enum)}),ao=({schema:{value:e}})=>({type:typeof e,enum:[e]}),po=({schema:e,isResponse:t,...r})=>{let o=Object.keys(e.shape).filter(n=>{let s=e.shape[n];return!(t&&de(s)?s instanceof x.ZodOptional:s.isOptional())});return{type:"object",properties:Ce({schema:e,isResponse:t,...r}),...o.length?{required:o}:{}}},co=()=>({type:"string",nullable:!0,format:"null"}),lo=e=>{if(e.isResponse)throw new Z({message:"Please use z.dateOut() for output.",...e});return{description:"YYYY-MM-DDTHH:mm:ss.sssZ",type:"string",format:"date-time",pattern:We.source,externalDocs:{url:zt}}},mo=e=>{if(!e.isResponse)throw new Z({message:"Please use z.dateIn() for input.",...e});return{description:"YYYY-MM-DDTHH:mm:ss.sssZ",type:"string",format:"date-time",externalDocs:{url:zt}}},uo=e=>{throw new Z({message:`Using z.date() within ${e.isResponse?"output":"input"} schema is forbidden. Please use z.date${e.isResponse?"Out":"In"}() instead. Check out the documentation for details.`,...e})},fo=()=>({type:"boolean"}),yo=()=>({type:"integer",format:"bigint"}),go=({schema:{keySchema:e,valueSchema:t},...r})=>{if(e instanceof x.ZodEnum||e instanceof x.ZodNativeEnum){let o=Object.values(e.enum),n=o.reduce((s,a)=>({...s,[a]:t}),{});return{type:"object",properties:Ce({schema:x.object(n),...r}),...o.length?{required:o}:{}}}if(e instanceof x.ZodLiteral)return{type:"object",properties:Ce({schema:x.object({[e.value]:t}),...r}),required:[e.value]};if(e instanceof x.ZodUnion&&e.options.reduce((n,s)=>n&&s instanceof x.ZodLiteral,!0)){let n=e.options.reduce((s,a)=>({...s,[a.value]:t}),{});return{type:"object",properties:Ce({schema:x.object(n),...r}),required:e.options.map(s=>s.value)}}return{type:"object",additionalProperties:r.next({schema:t})}},ho=({schema:{_def:e,element:t},next:r})=>({type:"array",items:r({schema:t}),...e.minLength!==null&&{minItems:e.minLength.value},...e.maxLength!==null&&{maxItems:e.maxLength.value}}),xo=({schema:{items:e},next:t})=>{let r=e.map(o=>t({schema:o}));return{type:"array",minItems:r.length,maxItems:r.length,items:{oneOf:r,format:"tuple",...r.length>0&&{description:r.map((o,n)=>`${n}: ${ye(o)?o.type:o.$ref}`).join(", ")}}}},To=({schema:{isEmail:e,isURL:t,minLength:r,maxLength:o,isUUID:n,isCUID:s,isCUID2:a,isULID:p,isIP:d,isEmoji:c,isDatetime:l,_def:{checks:h}}})=>{let g=h.find(f=>f.kind==="regex"),T=h.find(f=>f.kind==="datetime"),O=g?g.regex:T?T.offset?new RegExp("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(([+-]\\d{2}:\\d{2})|Z)$"):new RegExp("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"):void 0;return{type:"string",...l&&{format:"date-time"},...e&&{format:"email"},...t&&{format:"url"},...n&&{format:"uuid"},...s&&{format:"cuid"},...a&&{format:"cuid2"},...p&&{format:"ulid"},...d&&{format:"ip"},...c&&{format:"emoji"},...r!==null&&{minLength:r},...o!==null&&{maxLength:o},...O&&{pattern:`/${O.source}/${O.flags}`}}},So=({schema:e})=>{let t=e._def.checks.find(({kind:s})=>s==="min"),r=t?t.inclusive:!0,o=e._def.checks.find(({kind:s})=>s==="max"),n=o?o.inclusive:!0;return{type:e.isInt?"integer":"number",format:e.isInt?"int64":"double",minimum:e.minValue===null?e.isInt?Number.MIN_SAFE_INTEGER:Number.MIN_VALUE:e.minValue,exclusiveMinimum:!r,maximum:e.maxValue===null?e.isInt?Number.MAX_SAFE_INTEGER:Number.MAX_VALUE:e.maxValue,exclusiveMaximum:!n}},Ce=({schema:{shape:e},next:t})=>Object.keys(e).reduce((r,o)=>({...r,[o]:t({schema:e[o]})}),{}),Oo=e=>{let t=Array.isArray(e.type)?e.type[0]:e.type;return Yr?.[t]},bo=({schema:e,isResponse:t,next:r})=>{let o=r({schema:e.innerType()}),{effect:n}=e._def;if(t&&n.type==="transform"&&ye(o)){let s=Oe({effect:n,sample:Oo(o)});return s&&["number","string","boolean"].includes(s)?{type:s}:r({schema:x.any()})}if(!t&&n.type==="preprocess"&&ye(o)){let{type:s,...a}=o;return{...a,format:`${a.format||s} (preprocessed)`}}return o},Ro=({schema:e,isResponse:t,next:r})=>r({schema:e._def[t?"out":"in"]}),Po=({schema:e,next:t})=>t({schema:e.unwrap()}),Zo=({next:e,schema:t,serializer:r,getRef:o,makeRef:n})=>{let s=r(t.schema);return o(s)||(()=>(n(s,{}),n(s,e({schema:t.schema}))))()},jt=(e,t,r=[])=>{let o=v({schema:e,variant:t?"parsed":"original",validate:!0});return o.length===0?{}:{examples:o.reduce((n,s,a)=>({...n,[`example${a+1}`]:{value:typeof s=="object"&&!Array.isArray(s)?fe(r,s):s}}),{})}},Ao=(e,t,r)=>{let o=v({schema:e,variant:t?"parsed":"original",validate:!0});return o.length===0?{}:{examples:o.reduce((n,s,a)=>r in s?{...n,[`example${a+1}`]:{value:s[r]}}:n,{})}};function ue(e,t){if(e instanceof x.ZodObject)return e;let r;if(e instanceof x.ZodUnion||e instanceof x.ZodDiscriminatedUnion)r=Array.from(e.options.values()).map(o=>ue(o,t)).reduce((o,n)=>o.merge(n.partial()),x.object({}));else if(e instanceof x.ZodEffects){if(D(e))throw new Z({message:`Using transformations on the top level of ${t.isResponse?"response":"input"} schema is not allowed.`,...t});r=ue(e._def.schema,t)}else r=ue(e._def.left,t).merge(ue(e._def.right,t));return ge(e,r)}var Lt=({path:e,method:t,endpoint:r,inputSources:o,serializer:n,getRef:s,makeRef:a,composition:p,clue:d="parameter"})=>{let c=r.getSchema("input"),l=ue(c,{path:e,method:t,isResponse:!1}).shape,h=$e(e),g=o.includes("query"),T=o.includes("params"),O=f=>T&&h.includes(f);return Object.keys(l).filter(f=>g||O(f)).map(f=>{let R=q({schema:l[f],isResponse:!1,rules:et,onEach:tt,onMissing:rt,serializer:n,getRef:s,makeRef:a,path:e,method:t}),y=p==="components"?a(C(e,t,`${d} ${f}`),R):R;return{name:f,in:O(f)?"path":"query",required:!l[f].isOptional(),description:ye(R)&&R.description||`${t.toUpperCase()} ${e} ${d}`,schema:y,...Ao(c,!1,f)}})},et={ZodString:To,ZodNumber:So,ZodBigInt:yo,ZodBoolean:fo,ZodDateIn:lo,ZodDateOut:mo,ZodNull:co,ZodArray:ho,ZodTuple:xo,ZodRecord:go,ZodObject:po,ZodLiteral:ao,ZodIntersection:oo,ZodUnion:to,ZodFile:eo,ZodUpload:Xr,ZodAny:Wr,ZodDefault:Jr,ZodEnum:wt,ZodNativeEnum:wt,ZodEffects:bo,ZodOptional:no,ZodNullable:io,ZodDiscriminatedUnion:ro,ZodBranded:Po,ZodDate:uo,ZodCatch:Qr,ZodPipeline:Ro,ZodLazy:Zo,ZodReadonly:so},tt=({schema:e,isResponse:t,prev:r})=>{if(Dt(r))return{};let{description:o}=e,n=e instanceof x.ZodLazy,s=r.type!==void 0,a=t&&de(e),p=!n&&s&&!a&&e.isNullable(),d=n?[]:v({schema:e,variant:t?"parsed":"original",validate:!0});return{...o&&{description:o},...p&&{nullable:!0},...d.length>0&&{example:d[0]}}},rt=({schema:e,...t})=>{throw new Z({message:`Zod type ${e.constructor.name} is unsupported.`,...t})},Xe=(e,t)=>{if(Dt(e))return e;let r=e.properties?fe(t,e.properties):void 0,o=e.example?fe(t,e.example):void 0,n=e.required?e.required.filter(p=>!t.includes(p)):void 0,s=e.allOf?e.allOf.map(p=>Xe(p,t)):void 0,a=e.oneOf?e.oneOf.map(p=>Xe(p,t)):void 0;return fe(Object.entries({properties:r,required:n,example:o,allOf:s,oneOf:a}).filter(([{},p])=>p===void 0).map(([p])=>p),{...e,properties:r,required:n,example:o,allOf:s,oneOf:a})},kt=e=>ye(e)?fe(["example"],e):e,ot=({method:e,path:t,endpoint:r,isPositive:o,serializer:n,getRef:s,makeRef:a,composition:p,clue:d="response"})=>{let c=r.getSchema(o?"positive":"negative"),l=r.getMimeTypes(o?"positive":"negative"),h=kt(q({schema:c,isResponse:!0,rules:et,onEach:tt,onMissing:rt,serializer:n,getRef:s,makeRef:a,path:t,method:e})),g=jt(c,!0),T=p==="components"?a(C(t,e,d),h):h;return{description:`${e.toUpperCase()} ${t} ${d}`,content:l.reduce((O,f)=>({...O,[f]:{schema:T,...g}}),{})}},Eo=()=>({type:"http",scheme:"basic"}),Io=({format:e})=>({type:"http",scheme:"bearer",...e&&{bearerFormat:e}}),Co=({name:e})=>({type:"apiKey",in:"query",name:e}),No=({name:e})=>({type:"apiKey",in:"header",name:e}),Mo=({name:e})=>({type:"apiKey",in:"cookie",name:e}),wo=({url:e})=>({type:"openIdConnect",openIdConnectUrl:e}),Do=({flows:e={}})=>({type:"oauth2",flows:Object.keys(e).reduce((t,r)=>{let o=e[r];if(!o)return t;let{scopes:n={},...s}=o;return{...t,[r]:{...s,scopes:n}}},{})}),Ut=e=>{let t={basic:Eo,bearer:Io,input:Co,header:No,cookie:Mo,openid:wo,oauth2:Do};return Re(e,r=>t[r.type](r))},Ne=e=>{if(typeof e=="object"){if("or"in e)return e.or.map(t=>("and"in t?t.and:[t]).reduce((r,{name:o,scopes:n})=>({...r,[o]:n}),{}));if("and"in e)return Ne(Ge(e))}return Ne({or:[e]})},Ht=({method:e,path:t,endpoint:r,serializer:o,getRef:n,makeRef:s,composition:a,clue:p="request body"})=>{let d=$e(t),c=kt(Xe(q({schema:r.getSchema("input"),isResponse:!1,rules:et,onEach:tt,onMissing:rt,serializer:o,getRef:n,makeRef:s,path:t,method:e}),d)),l=jt(r.getSchema("input"),!1,d),h=a==="components"?s(C(t,e,p),c):c;return{description:`${e.toUpperCase()} ${t} ${p}`,content:r.getMimeTypes("input").reduce((g,T)=>({...g,[T]:{schema:h,...l}}),{})}},Kt=e=>Object.keys(e).map(t=>{let r=e[t];return{name:t,description:typeof r=="string"?r:r.description,...typeof r=="object"&&r.url&&{externalDocs:{url:r.url}}}}),nt=e=>e.length<=Mt?e:e.slice(0,Mt-1)+"\u2026";var st=class extends zo{lastSecuritySchemaIds={};lastOperationIdSuffixes={};makeRef(t,r){return this.addSchema(t,r),this.getRef(t)}getRef(t){return t in(this.rootDoc.components?.schemas||{})?{$ref:`#/components/schemas/${t}`}:void 0}ensureUniqOperationId(t,r){let o=C(t,r);return o in this.lastOperationIdSuffixes?(this.lastOperationIdSuffixes[o]++,`${o}${this.lastOperationIdSuffixes[o]}`):(this.lastOperationIdSuffixes[o]=1,o)}ensureUniqSecuritySchemaName(t){let r=JSON.stringify(t);for(let o in this.rootDoc.components?.securitySchemes||{})if(r===JSON.stringify(this.rootDoc.components?.securitySchemes?.[o]))return o;return this.lastSecuritySchemaIds[t.type]=(this.lastSecuritySchemaIds?.[t.type]||0)+1,`${t.type.toUpperCase()}_${this.lastSecuritySchemaIds[t.type]}`}constructor({routing:t,config:r,title:o,version:n,serverUrl:s,successfulResponseDescription:a="Successful response",errorResponseDescription:p="Error response",hasSummaryFromDescription:d=!0,composition:c="inline",serializer:l=Se}){super(),this.addInfo({title:o,version:n}).addServer({url:s}),G({routing:t,onEndpoint:(g,T,O)=>{let f=O,R={path:T,method:f,endpoint:g,composition:c,serializer:l,getRef:this.getRef.bind(this),makeRef:this.makeRef.bind(this)},[y,A]=["short","long"].map(g.getDescription.bind(g)),F=r.inputSources?.[f]||he[f],re=Lt({...R,inputSources:F}),P={operationId:this.ensureUniqOperationId(T,f),responses:{[g.getStatusCode("positive")]:ot({...R,clue:a,isPositive:!0}),[g.getStatusCode("negative")]:ot({...R,clue:p,isPositive:!1})}};A&&(P.description=A,d&&y===void 0&&(P.summary=nt(A))),y&&(P.summary=nt(y)),g.getTags().length>0&&(P.tags=g.getTags()),re.length>0&&(P.parameters=re),F.includes("body")&&(P.requestBody=Ht(R));let oe=Ne(Re(Ut(g.getSecurity()),ne=>{let ht=this.ensureUniqSecuritySchemaName(ne),dr=["oauth2","openIdConnect"].includes(ne.type)?g.getScopes():[];return this.addSecurityScheme(ht,ne),{name:ht,scopes:dr}}));oe.length>0&&(P.security=oe);let ke=vt(T);this.addPath(ke,{[f]:P})}}),this.rootDoc.tags=r.tags?Kt(r.tags):[]}};import Ft from"http";var vo=e=>({method:"GET",header:jest.fn(()=>$),...e}),jo=e=>{let t={writableEnded:!1,statusCode:200,statusMessage:Ft.STATUS_CODES[200],set:jest.fn(()=>t),setHeader:jest.fn(()=>t),header:jest.fn(()=>t),status:jest.fn(r=>(t.statusCode=r,t.statusMessage=Ft.STATUS_CODES[r],t)),json:jest.fn(()=>t),send:jest.fn(()=>t),end:jest.fn(()=>(t.writableEnded=!0,t)),...e};return t},Lo=async({endpoint:e,requestProps:t,responseProps:r,configProps:o,loggerProps:n,__noJest:s})=>{if(!jest||s)throw new Error("You need to install Jest in order to use testEndpoint().");let a=vo(t),p=jo(r),d={info:jest.fn(),warn:jest.fn(),error:jest.fn(),debug:jest.fn(),...n},c={cors:!1,logger:d,...o};return await e.execute({request:a,response:p,config:c,logger:d}),{requestMock:a,responseMock:p,loggerMock:d}};import K from"typescript";import M from"typescript";var i=M.factory,V=[i.createModifier(M.SyntaxKind.ExportKeyword)],ko=[i.createModifier(M.SyntaxKind.AsyncKeyword)],Uo=[i.createModifier(M.SyntaxKind.PublicKeyword),i.createModifier(M.SyntaxKind.ReadonlyKeyword)],$t=[i.createModifier(M.SyntaxKind.ProtectedKeyword),i.createModifier(M.SyntaxKind.ReadonlyKeyword)],Ho=i.createTemplateHead(""),Ko=i.createTemplateTail(""),Fo=i.createTemplateMiddle(" "),it=e=>i.createTemplateLiteralType(Ho,e.map((t,r)=>i.createTemplateLiteralTypeSpan(i.createTypeReferenceNode(t),r===e.length-1?Ko:Fo))),at=it(["M","P"]),Me=(e,t,r)=>i.createParameterDeclaration(r,void 0,e,void 0,t,void 0),we=(e,t)=>Object.keys(e).reduce((r,o)=>r.concat(Me(o,e[o],t)),[]),dt=(e,t)=>i.createExpressionWithTypeArguments(i.createIdentifier("Record"),[typeof e=="number"?i.createKeywordTypeNode(e):i.createTypeReferenceNode(e),i.createKeywordTypeNode(t)]),_t=e=>i.createConstructorDeclaration(void 0,e,i.createBlock([])),pt=(e,t)=>i.createPropertySignature(void 0,`"${e}"`,void 0,i.createTypeReferenceNode(t)),ct=(e,t)=>i.createVariableDeclarationList([i.createVariableDeclaration(e,void 0,void 0,t)],M.NodeFlags.Const),lt=(e,t)=>i.createTypeAliasDeclaration(V,e,void 0,i.createUnionTypeNode(t.map(r=>i.createLiteralTypeNode(i.createStringLiteral(r))))),De=(e,t)=>i.createTypeAliasDeclaration(V,e,void 0,t),Gt=(e,t,r)=>i.createPropertyDeclaration(Uo,e,void 0,t,r),qt=(e,t,r=[])=>i.createClassDeclaration(V,e,void 0,void 0,[t,...r]),Vt=(e,t)=>i.createTypeReferenceNode("Promise",[i.createIndexedAccessTypeNode(i.createTypeReferenceNode(e),t)]),Bt=()=>i.createTypeReferenceNode("Promise",[i.createKeywordTypeNode(M.SyntaxKind.AnyKeyword)]),mt=(e,t,r)=>i.createInterfaceDeclaration(V,e,void 0,t,r),Yt=e=>Object.keys(e).reduce((t,r)=>t.concat(i.createTypeParameterDeclaration([],r,i.createTypeReferenceNode(e[r]))),[]),Jt=(e,t)=>i.createArrowFunction(ko,void 0,e.map(r=>Me(r)),void 0,void 0,i.createCallExpression(i.createPropertyAccessExpression(i.createThis(),"implementation"),void 0,t)),ut=(e,t,r)=>i.createCallExpression(i.createPropertyAccessExpression(i.createCallExpression(i.createPropertyAccessExpression(i.createIdentifier("Object"),"keys"),void 0,[i.createIdentifier(e)]),"reduce"),void 0,[i.createArrowFunction(void 0,void 0,we({acc:void 0,key:void 0}),void 0,void 0,t),r]);import u from"typescript";import{z as _o}from"zod";import U from"typescript";var{factory:ze}=U,ft=(e,t)=>{U.addSyntheticLeadingComment(e,U.SyntaxKind.MultiLineCommentTrivia,`* ${t} `,!0)},ve=(e,t,r)=>{let o=ze.createTypeAliasDeclaration(void 0,ze.createIdentifier(t),void 0,e);return r&&ft(o,r),o},Qt=(e,t)=>{let r=U.createSourceFile("print.ts","",U.ScriptTarget.Latest,!1,U.ScriptKind.TS);return U.createPrinter(t).printNode(U.EmitHint.Unspecified,e,r)},$o=/^[A-Za-z_$][A-Za-z0-9_$]*$/,Wt=e=>$o.test(e)?ze.createIdentifier(e):ze.createStringLiteral(e);var{factory:m}=u,Go={[u.SyntaxKind.AnyKeyword]:"",[u.SyntaxKind.BigIntKeyword]:BigInt(0),[u.SyntaxKind.BooleanKeyword]:!1,[u.SyntaxKind.NumberKeyword]:0,[u.SyntaxKind.ObjectKeyword]:{},[u.SyntaxKind.StringKeyword]:"",[u.SyntaxKind.UndefinedKeyword]:void 0},qo=({schema:{value:e}})=>m.createLiteralTypeNode(typeof e=="number"?m.createNumericLiteral(e):typeof e=="boolean"?e?m.createTrue():m.createFalse():m.createStringLiteral(e)),Vo=({schema:{shape:e},isResponse:t,next:r,optionalPropStyle:{withQuestionMark:o}})=>{let n=Object.entries(e).map(([s,a])=>{let p=t&&de(a)?a instanceof _o.ZodOptional:a.isOptional(),d=m.createPropertySignature(void 0,Wt(s),p&&o?m.createToken(u.SyntaxKind.QuestionToken):void 0,r({schema:a}));return a.description&&ft(d,a.description),d});return m.createTypeLiteralNode(n)},Bo=({schema:{element:e},next:t})=>m.createArrayTypeNode(t({schema:e})),Yo=({schema:{options:e}})=>m.createUnionTypeNode(e.map(t=>m.createLiteralTypeNode(m.createStringLiteral(t)))),Xt=({schema:{options:e},next:t})=>m.createUnionTypeNode(e.map(r=>t({schema:r}))),Jo=e=>Go?.[e.kind],Qo=({schema:e,next:t,isResponse:r})=>{let o=t({schema:e.innerType()}),n=e._def.effect;if(r&&n.type==="transform"){let s=Oe({effect:n,sample:Jo(o)}),a={number:u.SyntaxKind.NumberKeyword,bigint:u.SyntaxKind.BigIntKeyword,boolean:u.SyntaxKind.BooleanKeyword,string:u.SyntaxKind.StringKeyword,undefined:u.SyntaxKind.UndefinedKeyword,object:u.SyntaxKind.ObjectKeyword};return m.createKeywordTypeNode(s&&a[s]||u.SyntaxKind.AnyKeyword)}return o},Wo=({schema:e})=>m.createUnionTypeNode(Object.values(e.enum).map(t=>m.createLiteralTypeNode(typeof t=="number"?m.createNumericLiteral(t):m.createStringLiteral(t)))),Xo=({next:e,schema:t,optionalPropStyle:{withUndefined:r}})=>{let o=e({schema:t.unwrap()});return r?m.createUnionTypeNode([o,m.createKeywordTypeNode(u.SyntaxKind.UndefinedKeyword)]):o},en=({next:e,schema:t})=>m.createUnionTypeNode([e({schema:t.unwrap()}),m.createLiteralTypeNode(m.createNull())]),tn=({next:e,schema:{items:t}})=>m.createTupleTypeNode(t.map(r=>e({schema:r}))),rn=({next:e,schema:{keySchema:t,valueSchema:r}})=>m.createExpressionWithTypeArguments(m.createIdentifier("Record"),[e({schema:t}),e({schema:r})]),on=({next:e,schema:t})=>m.createIntersectionTypeNode([t._def.left,t._def.right].map(r=>e({schema:r}))),nn=({next:e,schema:t})=>e({schema:t._def.innerType}),H=e=>()=>m.createKeywordTypeNode(e),sn=({next:e,schema:t})=>e({schema:t.unwrap()}),an=({next:e,schema:t})=>e({schema:t._def.innerType}),dn=({next:e,schema:t})=>e({schema:t._def.innerType}),pn=({schema:e,next:t,isResponse:r})=>t({schema:e._def[r?"out":"in"]}),cn=()=>m.createLiteralTypeNode(m.createNull()),ln=({getAlias:e,makeAlias:t,next:r,serializer:o,schema:n})=>{let s=`Type${o(n.schema)}`;return e(s)||(()=>(t(s,m.createLiteralTypeNode(m.createNull())),t(s,r({schema:n.schema}))))()},mn={ZodString:H(u.SyntaxKind.StringKeyword),ZodNumber:H(u.SyntaxKind.NumberKeyword),ZodBigInt:H(u.SyntaxKind.BigIntKeyword),ZodBoolean:H(u.SyntaxKind.BooleanKeyword),ZodDateIn:H(u.SyntaxKind.StringKeyword),ZodDateOut:H(u.SyntaxKind.StringKeyword),ZodNull:cn,ZodArray:Bo,ZodTuple:tn,ZodRecord:rn,ZodObject:Vo,ZodLiteral:qo,ZodIntersection:on,ZodUnion:Xt,ZodFile:H(u.SyntaxKind.StringKeyword),ZodAny:H(u.SyntaxKind.AnyKeyword),ZodDefault:nn,ZodEnum:Yo,ZodNativeEnum:Wo,ZodEffects:Qo,ZodOptional:Xo,ZodNullable:en,ZodDiscriminatedUnion:Xt,ZodBranded:sn,ZodCatch:dn,ZodPipeline:pn,ZodLazy:ln,ZodReadonly:an},yt=({schema:e,...t})=>q({schema:e,rules:mn,onMissing:()=>m.createKeywordTypeNode(u.SyntaxKind.AnyKeyword),...t});var gt=class{agg=[];registry={};paths=[];aliases={};getAlias(t){return t in this.aliases?i.createTypeReferenceNode(t):void 0}makeAlias(t,r){return this.aliases[t]=ve(r,t),this.getAlias(t)}constructor({routing:t,variant:r="client",serializer:o=Se,optionalPropStyle:n={withQuestionMark:!0,withUndefined:!0}}){G({routing:t,onEndpoint:(y,A,F)=>{let re=C(A,F,"input"),P=C(A,F,"response"),oe={serializer:o,getAlias:this.getAlias.bind(this),makeAlias:this.makeAlias.bind(this),optionalPropStyle:n},ke=yt({...oe,schema:y.getSchema("input"),isResponse:!1}),ne=yt({...oe,isResponse:!0,schema:y.getSchema("positive").or(y.getSchema("negative"))});this.agg.push(ve(ke,re),ve(ne,P)),F!=="options"&&(this.paths.push(A),this.registry[`${F} ${A}`]={in:re,out:P,isJson:y.getMimeTypes("positive").includes($),tags:y.getTags()})}}),this.agg=Object.values(this.aliases).concat(this.agg);let s=lt("Path",this.paths),a=lt("Method",Rt),p=De("MethodPath",it([a.name,s.name])),d=[i.createHeritageClause(K.SyntaxKind.ExtendsKeyword,[dt(p.name,K.SyntaxKind.AnyKeyword)])],c=mt("Input",d,Object.keys(this.registry).map(y=>pt(y,this.registry[y].in))),l=mt("Response",d,Object.keys(this.registry).map(y=>pt(y,this.registry[y].out)));if(this.agg.push(s,a,p,c,l),r==="types")return;let h=i.createVariableStatement(V,ct("jsonEndpoints",i.createObjectLiteralExpression(Object.keys(this.registry).filter(y=>this.registry[y].isJson).map(y=>i.createPropertyAssignment(`"${y}"`,i.createTrue()))))),g=i.createVariableStatement(V,ct("endpointTags",i.createObjectLiteralExpression(Object.keys(this.registry).map(y=>i.createPropertyAssignment(`"${y}"`,i.createArrayLiteralExpression(this.registry[y].tags.map(A=>i.createStringLiteral(A)))))))),T=De("Provider",i.createFunctionTypeNode(Yt({M:a.name,P:s.name}),we({method:i.createTypeReferenceNode("M"),path:i.createTypeReferenceNode("P"),params:i.createIndexedAccessTypeNode(i.createTypeReferenceNode(c.name),at)}),Vt(l.name,at))),O=De("Implementation",i.createFunctionTypeNode(void 0,we({method:i.createTypeReferenceNode(a.name),path:i.createKeywordTypeNode(K.SyntaxKind.StringKeyword),params:dt(K.SyntaxKind.StringKeyword,K.SyntaxKind.AnyKeyword)}),Bt())),f=i.createTemplateExpression(i.createTemplateHead(":"),[i.createTemplateSpan(i.createIdentifier("key"),i.createTemplateTail(""))]),R=qt("ExpressZodAPIClient",_t([Me("implementation",i.createTypeReferenceNode(O.name),$t)]),[Gt("provide",i.createTypeReferenceNode(T.name),Jt(["method","path","params"],[i.createIdentifier("method"),ut("params",i.createCallExpression(i.createPropertyAccessExpression(i.createIdentifier("acc"),"replace"),void 0,[f,i.createElementAccessExpression(i.createIdentifier("params"),i.createIdentifier("key"))]),i.createIdentifier("path")),ut("params",i.createConditionalExpression(i.createBinaryExpression(i.createCallExpression(i.createPropertyAccessExpression(i.createIdentifier("path"),"indexOf"),void 0,[f]),K.SyntaxKind.GreaterThanEqualsToken,i.createNumericLiteral(0)),void 0,i.createIdentifier("acc"),void 0,i.createObjectLiteralExpression([i.createSpreadAssignment(i.createIdentifier("acc")),i.createPropertyAssignment(i.createComputedPropertyName(i.createIdentifier("key")),i.createElementAccessExpression(i.createIdentifier("params"),i.createIdentifier("key")))])),i.createObjectLiteralExpression())]))]);K.addSyntheticLeadingComment(R,K.SyntaxKind.MultiLineCommentTrivia,`
|
|
34
|
+
`.trim();var Qe=({app:e,logger:t,config:r,routing:o})=>{r.startupLogo!==!1&&console.log(It()),G({routing:o,hasCors:!!r.cors,onEndpoint:(n,s,a)=>{e[a](s,async(p,d)=>{t.info(`${p.method}: ${s}`),await n.execute({request:p,response:d,logger:t,config:r})})},onStatic:(n,s)=>{e.use(n,s)}})};import Fr,{json as $r}from"express";import _r from"compression";import Gr from"express-fileupload";import qr from"https";import Ct from"http-errors";var Vr=(e,t)=>(r,o,n,s)=>{if(!r)return s();e.handler({error:Ct(400,Y(r).message),request:o,response:n,logger:t,input:o.body,output:null})},Nt=(e,t)=>(r,o)=>{let n=Ct(404,`Can not ${r.method} ${r.path}`);try{e.handler({request:r,response:o,logger:t,error:n,input:null,output:null})}catch(s){Re({response:o,logger:t,error:new Q(Y(s).message,n)})}},Br=(e,t)=>{let r=$e(e.logger)?Ee(e.logger):e.logger;Qe({app:e.app,routing:t,logger:r,config:e});let o=e.errorHandler||ee;return{notFoundHandler:Nt(o,r),logger:r}},Yr=(e,t)=>{let r=$e(e.logger)?Ee(e.logger):e.logger,o=Fr();o.disable("x-powered-by");let n=e.errorHandler||ee,s=e.server.compression?_r({...typeof e.server.compression=="object"?e.server.compression:{}}):void 0,a=e.server.jsonParser||$r(),p=e.server.upload?Gr({...typeof e.server.upload=="object"?e.server.upload:{},abortOnLimit:!1,parseNested:!0}):void 0,d=[].concat(s||[]).concat(a).concat(p||[]);o.use(d),o.use(Vr(n,r)),Qe({app:o,routing:t,logger:r,config:e}),o.use(Nt(n,r));let c=o.listen(e.server.listen,()=>{r.info(`Listening ${e.server.listen}`)}),l;return e.https&&(l=qr.createServer(e.https.options,o).listen(e.https.listen,()=>{r.info(`Listening ${e.https.listen}`)})),{app:o,httpServer:c,httpsServer:l,logger:r}};import{OpenApiBuilder as Lo}from"openapi3-ts/oas30";import{isReferenceObject as vt,isSchemaObject as ue}from"openapi3-ts/oas30";import{omit as me}from"ramda";import{z as x}from"zod";import{INVALID as wt,ZodIssueCode as We,ZodParsedType as Mt,ZodType as Jr,addIssueToContext as Xe}from"zod";var et=/^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d+)?)?Z?$/,Qr="ZodDateIn",Ae=class e extends Jr{_parse(t){let{status:r,ctx:o}=this._processInputParams(t);if(o.parsedType!==Mt.string)return Xe(o,{code:We.invalid_type,expected:Mt.string,received:o.parsedType}),wt;et.test(o.data)||(Xe(o,{code:We.invalid_string,validation:"regex"}),r.dirty());let n=new Date(o.data);return he(n)?{status:r.value,value:n}:(Xe(o,{code:We.invalid_date}),wt)}static create=()=>new e({typeName:Qr})};var q=({schema:e,onEach:t,rules:r,onMissing:o,...n})=>{let s="typeName"in e._def?r[e._def.typeName]:void 0,p=s?s({schema:e,...n,next:c=>q({...c,...n,onEach:t,rules:r,onMissing:o})}):o({schema:e,...n}),d=t&&t({schema:e,prev:p,...n});return d?{...p,...d}:p};var Dt=50,jt="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString",Wr={integer:0,number:0,string:"",boolean:!1,object:{},null:null,array:[]},Lt=e=>e.replace(Ue,t=>`{${t.slice(1)}}`),Xr=({schema:{_def:{innerType:e,defaultValue:t}},next:r})=>({...r({schema:e}),default:t()}),eo=({schema:{_def:{innerType:e}},next:t})=>t({schema:e}),to=()=>({format:"any"}),ro=e=>{if(e.isResponse)throw new R({message:"Please use z.upload() only for input.",...e});return{type:"string",format:"binary"}},oo=({schema:{isBinary:e,isBase64:t},...r})=>{if(!r.isResponse)throw new R({message:"Please use z.file() only within ResultHandler.",...r});return{type:"string",format:e?"binary":t?"byte":"file"}},no=({schema:{options:e},next:t})=>({oneOf:e.map(r=>t({schema:r}))}),so=({schema:{options:e,discriminator:t},next:r})=>({discriminator:{propertyName:t},oneOf:Array.from(e.values()).map(o=>r({schema:o}))}),io=({schema:{_def:{left:e,right:t}},next:r})=>({allOf:[e,t].map(o=>r({schema:o}))}),ao=({schema:e,next:t})=>t({schema:e.unwrap()}),po=({schema:e,next:t})=>t({schema:e._def.innerType}),co=({schema:e,next:t})=>({nullable:!0,...t({schema:e.unwrap()})}),zt=({schema:e})=>({type:typeof Object.values(e.enum)[0],enum:Object.values(e.enum)}),lo=({schema:{value:e}})=>({type:typeof e,enum:[e]}),mo=({schema:e,isResponse:t,...r})=>{let o=Object.keys(e.shape).filter(n=>{let s=e.shape[n];return!(t&&ie(s)?s instanceof x.ZodOptional:s.isOptional())});return{type:"object",properties:Ie({schema:e,isResponse:t,...r}),...o.length?{required:o}:{}}},uo=()=>({type:"string",nullable:!0,format:"null"}),fo=e=>{if(e.isResponse)throw new R({message:"Please use z.dateOut() for output.",...e});return{description:"YYYY-MM-DDTHH:mm:ss.sssZ",type:"string",format:"date-time",pattern:et.source,externalDocs:{url:jt}}},yo=e=>{if(!e.isResponse)throw new R({message:"Please use z.dateIn() for input.",...e});return{description:"YYYY-MM-DDTHH:mm:ss.sssZ",type:"string",format:"date-time",externalDocs:{url:jt}}},go=e=>{throw new R({message:`Using z.date() within ${e.isResponse?"output":"input"} schema is forbidden. Please use z.date${e.isResponse?"Out":"In"}() instead. Check out the documentation for details.`,...e})},ho=()=>({type:"boolean"}),xo=()=>({type:"integer",format:"bigint"}),To=({schema:{keySchema:e,valueSchema:t},...r})=>{if(e instanceof x.ZodEnum||e instanceof x.ZodNativeEnum){let o=Object.values(e.enum),n=o.reduce((s,a)=>({...s,[a]:t}),{});return{type:"object",properties:Ie({schema:x.object(n),...r}),...o.length?{required:o}:{}}}if(e instanceof x.ZodLiteral)return{type:"object",properties:Ie({schema:x.object({[e.value]:t}),...r}),required:[e.value]};if(e instanceof x.ZodUnion&&e.options.reduce((n,s)=>n&&s instanceof x.ZodLiteral,!0)){let n=e.options.reduce((s,a)=>({...s,[a.value]:t}),{});return{type:"object",properties:Ie({schema:x.object(n),...r}),required:e.options.map(s=>s.value)}}return{type:"object",additionalProperties:r.next({schema:t})}},So=({schema:{_def:e,element:t},next:r})=>({type:"array",items:r({schema:t}),...e.minLength!==null&&{minItems:e.minLength.value},...e.maxLength!==null&&{maxItems:e.maxLength.value}}),Oo=({schema:{items:e},next:t})=>{let r=e.map(o=>t({schema:o}));return{type:"array",minItems:r.length,maxItems:r.length,items:{oneOf:r,format:"tuple",...r.length>0&&{description:r.map((o,n)=>`${n}: ${ue(o)?o.type:o.$ref}`).join(", ")}}}},bo=({schema:{isEmail:e,isURL:t,minLength:r,maxLength:o,isUUID:n,isCUID:s,isCUID2:a,isULID:p,isIP:d,isEmoji:c,isDatetime:l,_def:{checks:g}}})=>{let y=g.find(h=>h.kind==="regex"),T=g.find(h=>h.kind==="datetime"),P=y?y.regex:T?T.offset?new RegExp("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(([+-]\\d{2}:\\d{2})|Z)$"):new RegExp("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$"):void 0;return{type:"string",...l&&{format:"date-time"},...e&&{format:"email"},...t&&{format:"url"},...n&&{format:"uuid"},...s&&{format:"cuid"},...a&&{format:"cuid2"},...p&&{format:"ulid"},...d&&{format:"ip"},...c&&{format:"emoji"},...r!==null&&{minLength:r},...o!==null&&{maxLength:o},...P&&{pattern:`/${P.source}/${P.flags}`}}},Ro=({schema:e})=>{let t=e._def.checks.find(({kind:s})=>s==="min"),r=t?t.inclusive:!0,o=e._def.checks.find(({kind:s})=>s==="max"),n=o?o.inclusive:!0;return{type:e.isInt?"integer":"number",format:e.isInt?"int64":"double",minimum:e.minValue===null?e.isInt?Number.MIN_SAFE_INTEGER:Number.MIN_VALUE:e.minValue,exclusiveMinimum:!r,maximum:e.maxValue===null?e.isInt?Number.MAX_SAFE_INTEGER:Number.MAX_VALUE:e.maxValue,exclusiveMaximum:!n}},Ie=({schema:{shape:e},next:t})=>Object.keys(e).reduce((r,o)=>({...r,[o]:t({schema:e[o]})}),{}),Po=e=>{let t=Array.isArray(e.type)?e.type[0]:e.type;return Wr?.[t]},Zo=({schema:e,isResponse:t,next:r})=>{let o=r({schema:e.innerType()}),{effect:n}=e._def;if(t&&n.type==="transform"&&ue(o)){let s=Se({effect:n,sample:Po(o)});return s&&["number","string","boolean"].includes(s)?{type:s}:r({schema:x.any()})}if(!t&&n.type==="preprocess"&&ue(o)){let{type:s,...a}=o;return{...a,format:`${a.format||s} (preprocessed)`}}return o},Eo=({schema:e,isResponse:t,next:r})=>r({schema:e._def[t?"out":"in"]}),Ao=({schema:e,next:t})=>t({schema:e.unwrap()}),Io=({next:e,schema:t,serializer:r,getRef:o,makeRef:n})=>{let s=r(t.schema);return o(s)||(()=>(n(s,{}),n(s,e({schema:t.schema}))))()},kt=(e,t,r=[])=>{let o=j({schema:e,variant:t?"parsed":"original",validate:!0});return o.length===0?{}:{examples:o.reduce((n,s,a)=>({...n,[`example${a+1}`]:{value:typeof s=="object"&&!Array.isArray(s)?me(r,s):s}}),{})}},Co=(e,t,r)=>{let o=j({schema:e,variant:t?"parsed":"original",validate:!0});return o.length===0?{}:{examples:o.reduce((n,s,a)=>r in s?{...n,[`example${a+1}`]:{value:s[r]}}:n,{})}},le=(e,t)=>{if(e instanceof x.ZodObject)return e;let r;if(e instanceof x.ZodUnion||e instanceof x.ZodDiscriminatedUnion)r=Array.from(e.options.values()).map(o=>le(o,t)).reduce((o,n)=>o.merge(n.partial()),x.object({}));else if(e instanceof x.ZodEffects){if(z(e))throw new R({message:`Using transformations on the top level of ${t.isResponse?"response":"input"} schema is not allowed.`,...t});r=le(e._def.schema,t)}else r=le(e._def.left,t).merge(le(e._def.right,t));return ye(e,r)},Ht=({path:e,method:t,endpoint:r,inputSources:o,serializer:n,getRef:s,makeRef:a,composition:p,clue:d="parameter"})=>{let c=r.getSchema("input"),l=le(c,{path:e,method:t,isResponse:!1}).shape,g=Ge(e),y=o.includes("query"),T=o.includes("params"),P=o.includes("headers"),h=m=>T&&g.includes(m),I=m=>P&&Fe(m);return Object.keys(l).filter(m=>y||h(m)).map(m=>{let S=q({schema:l[m],isResponse:!1,rules:rt,onEach:ot,onMissing:nt,serializer:n,getRef:s,makeRef:a,path:e,method:t}),C=p==="components"?a(N(e,t,`${d} ${m}`),S):S;return{name:m,in:h(m)?"path":I(m)?"header":"query",required:!l[m].isOptional(),description:ue(S)&&S.description||`${t.toUpperCase()} ${e} ${d}`,schema:C,...Co(c,!1,m)}})},rt={ZodString:bo,ZodNumber:Ro,ZodBigInt:xo,ZodBoolean:ho,ZodDateIn:fo,ZodDateOut:yo,ZodNull:uo,ZodArray:So,ZodTuple:Oo,ZodRecord:To,ZodObject:mo,ZodLiteral:lo,ZodIntersection:io,ZodUnion:no,ZodFile:oo,ZodUpload:ro,ZodAny:to,ZodDefault:Xr,ZodEnum:zt,ZodNativeEnum:zt,ZodEffects:Zo,ZodOptional:ao,ZodNullable:co,ZodDiscriminatedUnion:so,ZodBranded:Ao,ZodDate:go,ZodCatch:eo,ZodPipeline:Eo,ZodLazy:Io,ZodReadonly:po},ot=({schema:e,isResponse:t,prev:r})=>{if(vt(r))return{};let{description:o}=e,n=e instanceof x.ZodLazy,s=r.type!==void 0,a=t&&ie(e),p=!n&&s&&!a&&e.isNullable(),d=n?[]:j({schema:e,variant:t?"parsed":"original",validate:!0});return{...o&&{description:o},...p&&{nullable:!0},...d.length>0&&{example:d[0]}}},nt=({schema:e,...t})=>{throw new R({message:`Zod type ${e.constructor.name} is unsupported.`,...t})},tt=(e,t)=>{if(vt(e))return e;let r=e.properties?me(t,e.properties):void 0,o=e.example?me(t,e.example):void 0,n=e.required?e.required.filter(p=>!t.includes(p)):void 0,s=e.allOf?e.allOf.map(p=>tt(p,t)):void 0,a=e.oneOf?e.oneOf.map(p=>tt(p,t)):void 0;return me(Object.entries({properties:r,required:n,example:o,allOf:s,oneOf:a}).filter(([{},p])=>p===void 0).map(([p])=>p),{...e,properties:r,required:n,example:o,allOf:s,oneOf:a})},Ut=e=>ue(e)?me(["example"],e):e,st=({method:e,path:t,endpoint:r,isPositive:o,serializer:n,getRef:s,makeRef:a,composition:p,clue:d="response"})=>{let c=r.getSchema(o?"positive":"negative"),l=r.getMimeTypes(o?"positive":"negative"),g=Ut(q({schema:c,isResponse:!0,rules:rt,onEach:ot,onMissing:nt,serializer:n,getRef:s,makeRef:a,path:t,method:e})),y=kt(c,!0),T=p==="components"?a(N(t,e,d),g):g;return{description:`${e.toUpperCase()} ${t} ${d}`,content:l.reduce((P,h)=>({...P,[h]:{schema:T,...y}}),{})}},No=()=>({type:"http",scheme:"basic"}),wo=({format:e})=>({type:"http",scheme:"bearer",...e&&{bearerFormat:e}}),Mo=({name:e})=>({type:"apiKey",in:"query",name:e}),Do=({name:e})=>({type:"apiKey",in:"header",name:e}),zo=({name:e})=>({type:"apiKey",in:"cookie",name:e}),vo=({url:e})=>({type:"openIdConnect",openIdConnectUrl:e}),jo=({flows:e={}})=>({type:"oauth2",flows:Object.keys(e).reduce((t,r)=>{let o=e[r];if(!o)return t;let{scopes:n={},...s}=o;return{...t,[r]:{...s,scopes:n}}},{})}),Kt=e=>{let t={basic:No,bearer:wo,input:Mo,header:Do,cookie:zo,openid:vo,oauth2:jo};return be(e,r=>t[r.type](r))},Ce=e=>{if(typeof e=="object"){if("or"in e)return e.or.map(t=>("and"in t?t.and:[t]).reduce((r,{name:o,scopes:n})=>({...r,[o]:n}),{}));if("and"in e)return Ce(Ve(e))}return Ce({or:[e]})},Ft=({method:e,path:t,endpoint:r,serializer:o,getRef:n,makeRef:s,composition:a,clue:p="request body"})=>{let d=Ge(t),c=Ut(tt(q({schema:r.getSchema("input"),isResponse:!1,rules:rt,onEach:ot,onMissing:nt,serializer:o,getRef:n,makeRef:s,path:t,method:e}),d)),l=kt(r.getSchema("input"),!1,d),g=a==="components"?s(N(t,e,p),c):c;return{description:`${e.toUpperCase()} ${t} ${p}`,content:r.getMimeTypes("input").reduce((y,T)=>({...y,[T]:{schema:g,...l}}),{})}},$t=e=>Object.keys(e).map(t=>{let r=e[t];return{name:t,description:typeof r=="string"?r:r.description,...typeof r=="object"&&r.url&&{externalDocs:{url:r.url}}}}),it=e=>e.length<=Dt?e:e.slice(0,Dt-1)+"\u2026";var at=class extends Lo{lastSecuritySchemaIds={};lastOperationIdSuffixes={};makeRef(t,r){return this.addSchema(t,r),this.getRef(t)}getRef(t){return t in(this.rootDoc.components?.schemas||{})?{$ref:`#/components/schemas/${t}`}:void 0}ensureUniqOperationId(t,r,o){if(o){if(o in this.lastOperationIdSuffixes)throw new R({message:`Duplicated operationId: "${o}"`,method:r,isResponse:!1,path:t});return this.lastOperationIdSuffixes[o]=1,o}let n=N(t,r);return n in this.lastOperationIdSuffixes?(this.lastOperationIdSuffixes[n]++,`${n}${this.lastOperationIdSuffixes[n]}`):(this.lastOperationIdSuffixes[n]=1,n)}ensureUniqSecuritySchemaName(t){let r=JSON.stringify(t);for(let o in this.rootDoc.components?.securitySchemes||{})if(r===JSON.stringify(this.rootDoc.components?.securitySchemes?.[o]))return o;return this.lastSecuritySchemaIds[t.type]=(this.lastSecuritySchemaIds?.[t.type]||0)+1,`${t.type.toUpperCase()}_${this.lastSecuritySchemaIds[t.type]}`}constructor({routing:t,config:r,title:o,version:n,serverUrl:s,successfulResponseDescription:a="Successful response",errorResponseDescription:p="Error response",hasSummaryFromDescription:d=!0,composition:c="inline",serializer:l=Te}){super(),this.addInfo({title:o,version:n}).addServer({url:s}),G({routing:t,onEndpoint:(y,T,P)=>{let h=P,I={path:T,method:h,endpoint:y,composition:c,serializer:l,getRef:this.getRef.bind(this),makeRef:this.makeRef.bind(this)},[m,S]=["short","long"].map(y.getDescription.bind(y)),C=r.inputSources?.[h]||ge[h],re=Ht({...I,inputSources:C}),Z={operationId:this.ensureUniqOperationId(T,h,y.getOperationId()),responses:{[y.getStatusCode("positive")]:st({...I,clue:a,isPositive:!0}),[y.getStatusCode("negative")]:st({...I,clue:p,isPositive:!1})}};S&&(Z.description=S,d&&m===void 0&&(Z.summary=it(S))),m&&(Z.summary=it(m)),y.getTags().length>0&&(Z.tags=y.getTags()),re.length>0&&(Z.parameters=re),C.includes("body")&&(Z.requestBody=Ft(I));let fe=Ce(be(Kt(y.getSecurity()),He=>{let Tt=this.ensureUniqSecuritySchemaName(He),cr=["oauth2","openIdConnect"].includes(He.type)?y.getScopes():[];return this.addSecurityScheme(Tt,He),{name:Tt,scopes:cr}}));fe.length>0&&(Z.security=fe);let ke=Lt(T);this.addPath(ke,{[h]:Z})}}),this.rootDoc.tags=r.tags?$t(r.tags):[]}};import _t from"http";var ko=e=>({method:"GET",header:jest.fn(()=>$),...e}),Ho=e=>{let t={writableEnded:!1,statusCode:200,statusMessage:_t.STATUS_CODES[200],set:jest.fn(()=>t),setHeader:jest.fn(()=>t),header:jest.fn(()=>t),status:jest.fn(r=>(t.statusCode=r,t.statusMessage=_t.STATUS_CODES[r],t)),json:jest.fn(()=>t),send:jest.fn(()=>t),end:jest.fn(()=>(t.writableEnded=!0,t)),...e};return t},Uo=async({endpoint:e,requestProps:t,responseProps:r,configProps:o,loggerProps:n,__noJest:s})=>{if(!jest||s)throw new Error("You need to install Jest in order to use testEndpoint().");let a=ko(t),p=Ho(r),d={info:jest.fn(),warn:jest.fn(),error:jest.fn(),debug:jest.fn(),...n},c={cors:!1,logger:d,...o};return await e.execute({request:a,response:p,config:c,logger:d}),{requestMock:a,responseMock:p,loggerMock:d}};import F from"typescript";import M from"typescript";var i=M.factory,V=[i.createModifier(M.SyntaxKind.ExportKeyword)],Ko=[i.createModifier(M.SyntaxKind.AsyncKeyword)],Fo=[i.createModifier(M.SyntaxKind.PublicKeyword),i.createModifier(M.SyntaxKind.ReadonlyKeyword)],Gt=[i.createModifier(M.SyntaxKind.ProtectedKeyword),i.createModifier(M.SyntaxKind.ReadonlyKeyword)],$o=i.createTemplateHead(""),_o=i.createTemplateTail(""),Go=i.createTemplateMiddle(" "),dt=e=>i.createTemplateLiteralType($o,e.map((t,r)=>i.createTemplateLiteralTypeSpan(i.createTypeReferenceNode(t),r===e.length-1?_o:Go))),pt=dt(["M","P"]),Ne=(e,t,r)=>i.createParameterDeclaration(r,void 0,e,void 0,t,void 0),we=(e,t)=>Object.keys(e).reduce((r,o)=>r.concat(Ne(o,e[o],t)),[]),ct=(e,t)=>i.createExpressionWithTypeArguments(i.createIdentifier("Record"),[typeof e=="number"?i.createKeywordTypeNode(e):i.createTypeReferenceNode(e),i.createKeywordTypeNode(t)]),qt=e=>i.createConstructorDeclaration(void 0,e,i.createBlock([])),lt=(e,t)=>i.createPropertySignature(void 0,`"${e}"`,void 0,i.createTypeReferenceNode(t)),mt=(e,t)=>i.createVariableDeclarationList([i.createVariableDeclaration(e,void 0,void 0,t)],M.NodeFlags.Const),ut=(e,t)=>i.createTypeAliasDeclaration(V,e,void 0,i.createUnionTypeNode(t.map(r=>i.createLiteralTypeNode(i.createStringLiteral(r))))),Me=(e,t)=>i.createTypeAliasDeclaration(V,e,void 0,t),Vt=(e,t,r)=>i.createPropertyDeclaration(Fo,e,void 0,t,r),Bt=(e,t,r=[])=>i.createClassDeclaration(V,e,void 0,void 0,[t,...r]),Yt=(e,t)=>i.createTypeReferenceNode("Promise",[i.createIndexedAccessTypeNode(i.createTypeReferenceNode(e),t)]),Jt=()=>i.createTypeReferenceNode("Promise",[i.createKeywordTypeNode(M.SyntaxKind.AnyKeyword)]),ft=(e,t,r)=>i.createInterfaceDeclaration(V,e,void 0,t,r),Qt=e=>Object.keys(e).reduce((t,r)=>t.concat(i.createTypeParameterDeclaration([],r,i.createTypeReferenceNode(e[r]))),[]),Wt=(e,t)=>i.createArrowFunction(Ko,void 0,e.map(r=>Ne(r)),void 0,void 0,i.createCallExpression(i.createPropertyAccessExpression(i.createThis(),"implementation"),void 0,t)),yt=(e,t,r)=>i.createCallExpression(i.createPropertyAccessExpression(i.createCallExpression(i.createPropertyAccessExpression(i.createIdentifier("Object"),"keys"),void 0,[i.createIdentifier(e)]),"reduce"),void 0,[i.createArrowFunction(void 0,void 0,we({acc:void 0,key:void 0}),void 0,void 0,t),r]);import f from"typescript";import{z as Vo}from"zod";import U from"typescript";var{factory:De}=U,gt=(e,t)=>{U.addSyntheticLeadingComment(e,U.SyntaxKind.MultiLineCommentTrivia,`* ${t} `,!0)},ze=(e,t,r)=>{let o=De.createTypeAliasDeclaration(void 0,De.createIdentifier(t),void 0,e);return r&>(o,r),o},Xt=(e,t)=>{let r=U.createSourceFile("print.ts","",U.ScriptTarget.Latest,!1,U.ScriptKind.TS);return U.createPrinter(t).printNode(U.EmitHint.Unspecified,e,r)},qo=/^[A-Za-z_$][A-Za-z0-9_$]*$/,er=e=>qo.test(e)?De.createIdentifier(e):De.createStringLiteral(e);var{factory:u}=f,Bo={[f.SyntaxKind.AnyKeyword]:"",[f.SyntaxKind.BigIntKeyword]:BigInt(0),[f.SyntaxKind.BooleanKeyword]:!1,[f.SyntaxKind.NumberKeyword]:0,[f.SyntaxKind.ObjectKeyword]:{},[f.SyntaxKind.StringKeyword]:"",[f.SyntaxKind.UndefinedKeyword]:void 0},Yo=({schema:{value:e}})=>u.createLiteralTypeNode(typeof e=="number"?u.createNumericLiteral(e):typeof e=="boolean"?e?u.createTrue():u.createFalse():u.createStringLiteral(e)),Jo=({schema:{shape:e},isResponse:t,next:r,optionalPropStyle:{withQuestionMark:o}})=>{let n=Object.entries(e).map(([s,a])=>{let p=t&&ie(a)?a instanceof Vo.ZodOptional:a.isOptional(),d=u.createPropertySignature(void 0,er(s),p&&o?u.createToken(f.SyntaxKind.QuestionToken):void 0,r({schema:a}));return a.description&>(d,a.description),d});return u.createTypeLiteralNode(n)},Qo=({schema:{element:e},next:t})=>u.createArrayTypeNode(t({schema:e})),Wo=({schema:{options:e}})=>u.createUnionTypeNode(e.map(t=>u.createLiteralTypeNode(u.createStringLiteral(t)))),tr=({schema:{options:e},next:t})=>u.createUnionTypeNode(e.map(r=>t({schema:r}))),Xo=e=>Bo?.[e.kind],en=({schema:e,next:t,isResponse:r})=>{let o=t({schema:e.innerType()}),n=e._def.effect;if(r&&n.type==="transform"){let s=Se({effect:n,sample:Xo(o)}),a={number:f.SyntaxKind.NumberKeyword,bigint:f.SyntaxKind.BigIntKeyword,boolean:f.SyntaxKind.BooleanKeyword,string:f.SyntaxKind.StringKeyword,undefined:f.SyntaxKind.UndefinedKeyword,object:f.SyntaxKind.ObjectKeyword};return u.createKeywordTypeNode(s&&a[s]||f.SyntaxKind.AnyKeyword)}return o},tn=({schema:e})=>u.createUnionTypeNode(Object.values(e.enum).map(t=>u.createLiteralTypeNode(typeof t=="number"?u.createNumericLiteral(t):u.createStringLiteral(t)))),rn=({next:e,schema:t,optionalPropStyle:{withUndefined:r}})=>{let o=e({schema:t.unwrap()});return r?u.createUnionTypeNode([o,u.createKeywordTypeNode(f.SyntaxKind.UndefinedKeyword)]):o},on=({next:e,schema:t})=>u.createUnionTypeNode([e({schema:t.unwrap()}),u.createLiteralTypeNode(u.createNull())]),nn=({next:e,schema:{items:t}})=>u.createTupleTypeNode(t.map(r=>e({schema:r}))),sn=({next:e,schema:{keySchema:t,valueSchema:r}})=>u.createExpressionWithTypeArguments(u.createIdentifier("Record"),[e({schema:t}),e({schema:r})]),an=({next:e,schema:t})=>u.createIntersectionTypeNode([t._def.left,t._def.right].map(r=>e({schema:r}))),dn=({next:e,schema:t})=>e({schema:t._def.innerType}),K=e=>()=>u.createKeywordTypeNode(e),pn=({next:e,schema:t})=>e({schema:t.unwrap()}),cn=({next:e,schema:t})=>e({schema:t._def.innerType}),ln=({next:e,schema:t})=>e({schema:t._def.innerType}),mn=({schema:e,next:t,isResponse:r})=>t({schema:e._def[r?"out":"in"]}),un=()=>u.createLiteralTypeNode(u.createNull()),fn=({getAlias:e,makeAlias:t,next:r,serializer:o,schema:n})=>{let s=`Type${o(n.schema)}`;return e(s)||(()=>(t(s,u.createLiteralTypeNode(u.createNull())),t(s,r({schema:n.schema}))))()},yn={ZodString:K(f.SyntaxKind.StringKeyword),ZodNumber:K(f.SyntaxKind.NumberKeyword),ZodBigInt:K(f.SyntaxKind.BigIntKeyword),ZodBoolean:K(f.SyntaxKind.BooleanKeyword),ZodDateIn:K(f.SyntaxKind.StringKeyword),ZodDateOut:K(f.SyntaxKind.StringKeyword),ZodNull:un,ZodArray:Qo,ZodTuple:nn,ZodRecord:sn,ZodObject:Jo,ZodLiteral:Yo,ZodIntersection:an,ZodUnion:tr,ZodFile:K(f.SyntaxKind.StringKeyword),ZodAny:K(f.SyntaxKind.AnyKeyword),ZodDefault:dn,ZodEnum:Wo,ZodNativeEnum:tn,ZodEffects:en,ZodOptional:rn,ZodNullable:on,ZodDiscriminatedUnion:tr,ZodBranded:pn,ZodCatch:ln,ZodPipeline:mn,ZodLazy:fn,ZodReadonly:cn},ht=({schema:e,...t})=>q({schema:e,rules:yn,onMissing:()=>u.createKeywordTypeNode(f.SyntaxKind.AnyKeyword),...t});var xt=class{agg=[];registry={};paths=[];aliases={};getAlias(t){return t in this.aliases?i.createTypeReferenceNode(t):void 0}makeAlias(t,r){return this.aliases[t]=ze(r,t),this.getAlias(t)}constructor({routing:t,variant:r="client",serializer:o=Te,optionalPropStyle:n={withQuestionMark:!0,withUndefined:!0}}){G({routing:t,onEndpoint:(m,S,C)=>{let re=N(S,C,"input"),Le=N(S,C,"response"),Z={serializer:o,getAlias:this.getAlias.bind(this),makeAlias:this.makeAlias.bind(this),optionalPropStyle:n},fe=ht({...Z,schema:m.getSchema("input"),isResponse:!1}),ke=ht({...Z,isResponse:!0,schema:m.getSchema("positive").or(m.getSchema("negative"))});this.agg.push(ze(fe,re),ze(ke,Le)),C!=="options"&&(this.paths.push(S),this.registry[`${C} ${S}`]={in:re,out:Le,isJson:m.getMimeTypes("positive").includes($),tags:m.getTags()})}}),this.agg=Object.values(this.aliases).concat(this.agg);let s=ut("Path",this.paths),a=ut("Method",Zt),p=Me("MethodPath",dt([a.name,s.name])),d=[i.createHeritageClause(F.SyntaxKind.ExtendsKeyword,[ct(p.name,F.SyntaxKind.AnyKeyword)])],c=ft("Input",d,Object.keys(this.registry).map(m=>lt(m,this.registry[m].in))),l=ft("Response",d,Object.keys(this.registry).map(m=>lt(m,this.registry[m].out)));if(this.agg.push(s,a,p,c,l),r==="types")return;let g=i.createVariableStatement(V,mt("jsonEndpoints",i.createObjectLiteralExpression(Object.keys(this.registry).filter(m=>this.registry[m].isJson).map(m=>i.createPropertyAssignment(`"${m}"`,i.createTrue()))))),y=i.createVariableStatement(V,mt("endpointTags",i.createObjectLiteralExpression(Object.keys(this.registry).map(m=>i.createPropertyAssignment(`"${m}"`,i.createArrayLiteralExpression(this.registry[m].tags.map(S=>i.createStringLiteral(S)))))))),T=Me("Provider",i.createFunctionTypeNode(Qt({M:a.name,P:s.name}),we({method:i.createTypeReferenceNode("M"),path:i.createTypeReferenceNode("P"),params:i.createIndexedAccessTypeNode(i.createTypeReferenceNode(c.name),pt)}),Yt(l.name,pt))),P=Me("Implementation",i.createFunctionTypeNode(void 0,we({method:i.createTypeReferenceNode(a.name),path:i.createKeywordTypeNode(F.SyntaxKind.StringKeyword),params:ct(F.SyntaxKind.StringKeyword,F.SyntaxKind.AnyKeyword)}),Jt())),h=i.createTemplateExpression(i.createTemplateHead(":"),[i.createTemplateSpan(i.createIdentifier("key"),i.createTemplateTail(""))]),I=Bt("ExpressZodAPIClient",qt([Ne("implementation",i.createTypeReferenceNode(P.name),Gt)]),[Vt("provide",i.createTypeReferenceNode(T.name),Wt(["method","path","params"],[i.createIdentifier("method"),yt("params",i.createCallExpression(i.createPropertyAccessExpression(i.createIdentifier("acc"),"replace"),void 0,[h,i.createElementAccessExpression(i.createIdentifier("params"),i.createIdentifier("key"))]),i.createIdentifier("path")),yt("params",i.createConditionalExpression(i.createBinaryExpression(i.createCallExpression(i.createPropertyAccessExpression(i.createIdentifier("path"),"indexOf"),void 0,[h]),F.SyntaxKind.GreaterThanEqualsToken,i.createNumericLiteral(0)),void 0,i.createIdentifier("acc"),void 0,i.createObjectLiteralExpression([i.createSpreadAssignment(i.createIdentifier("acc")),i.createPropertyAssignment(i.createComputedPropertyName(i.createIdentifier("key")),i.createElementAccessExpression(i.createIdentifier("params"),i.createIdentifier("key")))])),i.createObjectLiteralExpression())]))]);F.addSyntheticLeadingComment(I,F.SyntaxKind.MultiLineCommentTrivia,`
|
|
35
35
|
export const exampleImplementation: Implementation = async (
|
|
36
36
|
method,
|
|
37
37
|
path,
|
|
@@ -52,6 +52,6 @@ export const exampleImplementation: Implementation = async (
|
|
|
52
52
|
|
|
53
53
|
const client = new ExpressZodAPIClient(exampleImplementation);
|
|
54
54
|
client.provide("get", "/v1/user/retrieve", { id: "10" });
|
|
55
|
-
`,!0),this.agg.push(
|
|
55
|
+
`,!0),this.agg.push(g,y,T,P,I)}print(t){return this.agg.map(r=>Xt(r,t)).join(`
|
|
56
56
|
|
|
57
|
-
`)}};var
|
|
57
|
+
`)}};var pr={};mr(pr,{dateIn:()=>Pn,dateOut:()=>Zn,file:()=>bn,upload:()=>Rn});import{INVALID as rr,ZodIssueCode as or,ZodParsedType as nr,ZodType as gn,addIssueToContext as sr}from"zod";var hn="ZodDateOut",ve=class e extends gn{_parse(t){let{status:r,ctx:o}=this._processInputParams(t);return o.parsedType!==nr.date?(sr(o,{code:or.invalid_type,expected:nr.date,received:o.parsedType}),rr):he(o.data)?{status:r.value,value:o.data.toISOString()}:(sr(o,{code:or.invalid_date}),rr)}static create=()=>new e({typeName:hn})};import{INVALID as xn,ZodIssueCode as ir,ZodParsedType as ar,ZodType as Tn,addIssueToContext as dr}from"zod";var Sn="ZodFile",On=/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/,je=class e extends Tn{_parse(t){let{status:r,ctx:o}=this._processInputParams(t);if(o.parsedType!==ar.string)return dr(o,{code:ir.invalid_type,expected:ar.string,received:o.parsedType}),xn;for(let n of this._def.checks)n.kind==="base64"&&(On.test(o.data)||(dr(o,{code:ir.custom,message:n.message}),r.dirty()));return{status:r.value,value:o.data}}binary=t=>new e({...this._def,checks:[...this._def.checks,{kind:"binary",...qe(t)}]});base64=t=>new e({...this._def,checks:[...this._def.checks,{kind:"base64",...qe(t)}]});get isBinary(){return!!this._def.checks.find(t=>t.kind==="binary")}get isBase64(){return!!this._def.checks.find(t=>t.kind==="base64")}static create=()=>new e({checks:[],typeName:Sn})};var bn=je.create,Rn=B.create,Pn=Ae.create,Zn=ve.create;import Xa from"http-errors";export{te as AbstractEndpoint,pe as DependsOnMethod,ae as DependsOnMethodError,at as Documentation,R as DocumentationError,de as EndpointsFactory,L as InputValidationError,xt as Integration,_ as OutputValidationError,J as RoutingError,ce as ServeStatic,Mr as arrayEndpointsFactory,Ye as arrayResultHandler,Br as attachRouting,ur as createConfig,Xa as createHttpError,Ee as createLogger,Je as createMiddleware,Be as createResultHandler,Yr as createServer,wr as defaultEndpointsFactory,ee as defaultResultHandler,pr as ez,j as getExamples,v as getMessageFromError,xe as getStatusCodeFromError,Uo as testEndpoint,D as withMeta};
|
package/package.json
CHANGED