express-zod-api 28.1.0 → 28.2.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 +24 -1
- package/README.md +38 -15
- package/dist/index.d.ts +243 -26
- package/dist/index.js +5 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
## Version 28
|
|
4
4
|
|
|
5
|
+
### v28.2.0
|
|
6
|
+
|
|
7
|
+
- Added `createCacheMiddleware()` function for solving most of the caching problems:
|
|
8
|
+
- The function accepts an optional default policy to apply `Cache-Control` header to every response;
|
|
9
|
+
- It returns a Middleware providing several properties and caching helpers to context:
|
|
10
|
+
- `cacheControl` — the parsed request's `Cache-Control` header into a typed object;
|
|
11
|
+
- `ifNoneMatch` — the parsed `If-None-Match` request header into an array of ETags or `"*"`;
|
|
12
|
+
- `ifModifiedSince` — the parsed `If-Modified-Since` request header into a `Date`;
|
|
13
|
+
- `addCachePolicy()` — extends the default policy into the `Cache-Control` response header;
|
|
14
|
+
- `setETag()` — sets the `ETag` response header;
|
|
15
|
+
- `setLastModified()` — sets the `Last-Modified` response header;
|
|
16
|
+
- `setVary()` — sets the `Vary` response header;
|
|
17
|
+
- `setExpires()` — sets the `Expires` response header;
|
|
18
|
+
- `clearSiteData()` — sets the `Clear-Site-Data` header with `cache` directive;
|
|
19
|
+
- `notModified()` — sends an HTTP 304 response and ends the stream;
|
|
20
|
+
- Adjusted the Endpoint execution to skip output validation in case `response.writableEnded` (`notModified` called);
|
|
21
|
+
- Added two shorthand methods to `EndpointsFactory` class: `useCache()` and `useCookies()`.
|
|
22
|
+
|
|
23
|
+
### v28.1.1
|
|
24
|
+
|
|
25
|
+
- Depicting Endpoints built on `new EventStreamFactory({})` (having empty argument) will throw a `ResultHandlerError`:
|
|
26
|
+
- Applies to `Documentation`, `Integration` as well as self-diagnostics (starting the server in development mode).
|
|
27
|
+
|
|
5
28
|
### v28.1.0
|
|
6
29
|
|
|
7
30
|
- Added support for cookie handling:
|
|
@@ -25,7 +48,7 @@
|
|
|
25
48
|
- Supported Node.js versions: `^22.19.0 || ^24.0.0 || ^26.0.0`;
|
|
26
49
|
- Zod compatibility: `^4.3.4` (supports Zod 4.4+ without upper limit);
|
|
27
50
|
- The Zod plugin is no longer installed automatically — it's an optional peer dependency now:
|
|
28
|
-
- To keep using `.example()`, `.label()`, `.remap()
|
|
51
|
+
- To keep using `.example()`, `.label()`, `.remap()` and `.deprecated()` methods on schemas, as well as runtime
|
|
29
52
|
distinguishable brands, install the `@express-zod-api/zod-plugin` manually and import it (ideally at the top of a
|
|
30
53
|
file declaring your `Routing`);
|
|
31
54
|
- Breaking change: `ZodType::brand()` method is no longer patched by the plugin:
|
package/README.md
CHANGED
|
@@ -36,16 +36,17 @@ Start your API server with I/O schema validation and custom middlewares in minut
|
|
|
36
36
|
1. [Customizing input sources](#customizing-input-sources)
|
|
37
37
|
2. [Headers as an input source](#headers-as-an-input-source)
|
|
38
38
|
3. [Cookies](#cookies)
|
|
39
|
-
4. [
|
|
40
|
-
5. [
|
|
41
|
-
6. [
|
|
42
|
-
7. [
|
|
43
|
-
8. [
|
|
44
|
-
9. [
|
|
45
|
-
10. [
|
|
46
|
-
11. [
|
|
47
|
-
12. [
|
|
48
|
-
13. [Testing
|
|
39
|
+
4. [Caching](#caching)
|
|
40
|
+
5. [Response customization](#response-customization)
|
|
41
|
+
6. [Empty response](#empty-response)
|
|
42
|
+
7. [Non-JSON response](#non-json-response) including file downloads
|
|
43
|
+
8. [Error handling](#error-handling)
|
|
44
|
+
9. [Production mode](#production-mode)
|
|
45
|
+
10. [HTML Forms (URL encoded)](#html-forms-url-encoded)
|
|
46
|
+
11. [File uploads](#file-uploads)
|
|
47
|
+
12. [Connect to your own express app](#connect-to-your-own-express-app)
|
|
48
|
+
13. [Testing endpoints](#testing-endpoints)
|
|
49
|
+
14. [Testing middlewares](#testing-middlewares)
|
|
49
50
|
6. [Integration and Documentation](#integration-and-documentation)
|
|
50
51
|
1. [Zod Plugin](#zod-plugin)
|
|
51
52
|
2. [End-to-End Type Safety](#end-to-end-type-safety)
|
|
@@ -842,9 +843,7 @@ as well as `getCookie()` — alternative to the cookies as an input source:
|
|
|
842
843
|
import { createCookieMiddleware, Middleware } from "express-zod-api";
|
|
843
844
|
|
|
844
845
|
const cookieDrivenFactory = factory
|
|
845
|
-
.
|
|
846
|
-
createCookieMiddleware({ httpOnly: true, sameSite: "lax", path: "/" }), // recommended base options
|
|
847
|
-
)
|
|
846
|
+
.useCookies({ httpOnly: true, sameSite: "lax", path: "/" }) // shorthand, recommended base options
|
|
848
847
|
.addMiddleware(
|
|
849
848
|
new Middleware({
|
|
850
849
|
security: { type: "cookie", name: "session" }, // improves Documentation
|
|
@@ -856,12 +855,36 @@ const cookieDrivenFactory = factory
|
|
|
856
855
|
);
|
|
857
856
|
|
|
858
857
|
const sessionSettingEndpoint = cookieDrivenFactory.buildVoid({
|
|
859
|
-
handler: async ({ ctx: {
|
|
858
|
+
handler: async ({ ctx: { setCookie } }) => {
|
|
860
859
|
setCookie("session", "abc123", { httpOnly: false }); // overridden cookie options
|
|
861
860
|
},
|
|
862
861
|
});
|
|
863
862
|
```
|
|
864
863
|
|
|
864
|
+
## Caching
|
|
865
|
+
|
|
866
|
+
Consider the `createCacheMiddleware()` that provides helpers for HTTP caching following the MDN HTTP Caching guide.
|
|
867
|
+
It covers all standard `Cache-Control` directives, conditional request handling, and the "Not Modified" (304) flow:
|
|
868
|
+
|
|
869
|
+
```ts
|
|
870
|
+
import { createCacheMiddleware } from "express-zod-api";
|
|
871
|
+
|
|
872
|
+
const avatarEndpoint = factory
|
|
873
|
+
.useCache({ maxAge: 3600, scope: "public" }) // shorthand, the policy applies to every response
|
|
874
|
+
.build({
|
|
875
|
+
output: z.object({ avatar: z.string() }),
|
|
876
|
+
handler: async ({
|
|
877
|
+
ctx: { ifNoneMatch, setETag, notModified, addCachePolicy },
|
|
878
|
+
}) => {
|
|
879
|
+
const etag = `"avatar-v2"`;
|
|
880
|
+
if (ifNoneMatch?.includes(etag)) return notModified() as never; // skips validation, sends 304
|
|
881
|
+
setETag(etag);
|
|
882
|
+
addCachePolicy({ staleWhileRevalidate: 86400 }); // extends the default policy
|
|
883
|
+
return { avatar: "https://example.com/avatar.png" };
|
|
884
|
+
},
|
|
885
|
+
});
|
|
886
|
+
```
|
|
887
|
+
|
|
865
888
|
## Response customization
|
|
866
889
|
|
|
867
890
|
`ResultHandler` is responsible for transmitting consistent responses containing the endpoint output or an error.
|
|
@@ -960,7 +983,7 @@ it normalizes errors into consistent HTTP responses with sensible status codes.
|
|
|
960
983
|
- `OutputValidationError`: handler violates `output` schema, the default status code is `500`;
|
|
961
984
|
- `HttpError`: can be thrown in handlers with help of `createHttpError()`, its `.statusCode` is used for response;
|
|
962
985
|
- For other errors the default status code is `500`;
|
|
963
|
-
- Routing, parsing and upload issues:
|
|
986
|
+
- Routing, parsing, and upload issues:
|
|
964
987
|
- Handled by `ResultHandler` configured as `errorHandler` (the defaults is `defaultResultHandler`);
|
|
965
988
|
- Parsing errors: passed through as-is (typically `HttpError` with `4XX` code used for response by default);
|
|
966
989
|
- Routing errors: `404` or `405`, based on `hintAllowedMethods` configuration;
|
package/dist/index.d.ts
CHANGED
|
@@ -646,6 +646,196 @@ interface AppConfig extends CommonConfig {
|
|
|
646
646
|
}
|
|
647
647
|
declare function createConfig(config: ServerConfig): ServerConfig;
|
|
648
648
|
declare function createConfig(config: AppConfig): AppConfig;
|
|
649
|
+
/**
|
|
650
|
+
* @desc Directives shared by both request and response Cache-Control headers.
|
|
651
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#cache_directives
|
|
652
|
+
*/
|
|
653
|
+
interface CommonDirectives {
|
|
654
|
+
/**
|
|
655
|
+
* @desc Response: the response remains fresh for N seconds after it was generated.
|
|
656
|
+
* @desc Request: the client will accept a stored response that was generated at most N seconds ago.
|
|
657
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#max-age
|
|
658
|
+
*/
|
|
659
|
+
maxAge?: number;
|
|
660
|
+
/**
|
|
661
|
+
* @desc Forces revalidation with the server before reuse.
|
|
662
|
+
* @desc In a response this tells caches to revalidate; in a request it asks caches to revalidate.
|
|
663
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#no-cache
|
|
664
|
+
*/
|
|
665
|
+
noCache?: boolean;
|
|
666
|
+
/**
|
|
667
|
+
* @desc Prevents storing the response in any cache. In a response this instructs caches not to store.
|
|
668
|
+
* @desc In a request it asks caches not to store the request or its response.
|
|
669
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#no-store
|
|
670
|
+
*/
|
|
671
|
+
noStore?: boolean;
|
|
672
|
+
/**
|
|
673
|
+
* @desc Prevents intermediaries from transforming the response body (e.g. converting images).
|
|
674
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#no-transform
|
|
675
|
+
*/
|
|
676
|
+
noTransform?: boolean;
|
|
677
|
+
/**
|
|
678
|
+
* @desc Allows a stale cached response to be reused for N seconds when the origin server returns an error.
|
|
679
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#stale-if-error
|
|
680
|
+
*/
|
|
681
|
+
staleIfError?: number;
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* @desc Directives that clients send in requests to express their caching preferences.
|
|
685
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#request_directives
|
|
686
|
+
*/
|
|
687
|
+
interface CacheControl extends CommonDirectives {
|
|
688
|
+
/**
|
|
689
|
+
* @desc The client will accept a stored response that is stale for up to N seconds beyond its freshness lifetime.
|
|
690
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#max-stale
|
|
691
|
+
*/
|
|
692
|
+
maxStale?: number;
|
|
693
|
+
/**
|
|
694
|
+
* @desc The client requires a stored response that will remain fresh for at least N more seconds.
|
|
695
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#min-fresh
|
|
696
|
+
*/
|
|
697
|
+
minFresh?: number;
|
|
698
|
+
/**
|
|
699
|
+
* @desc The client wants a response only from the cache. Throw createHttpError(504) in this case.
|
|
700
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#only-if-cached
|
|
701
|
+
*/
|
|
702
|
+
onlyIfCached?: boolean;
|
|
703
|
+
}
|
|
704
|
+
/**
|
|
705
|
+
* @desc Directives that servers send in responses to control how caches store and reuse the response.
|
|
706
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#response_directives
|
|
707
|
+
*/
|
|
708
|
+
interface CachePolicy extends CommonDirectives {
|
|
709
|
+
/**
|
|
710
|
+
* @desc Restricts which caches may store the response.
|
|
711
|
+
* @example "public" — any cache (browser, proxy, CDN); for static assets, responses without user-specific data.
|
|
712
|
+
* @example "private" — browser only; for user-specific and personalized content.
|
|
713
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#response_directives
|
|
714
|
+
*/
|
|
715
|
+
scope?: "public" | "private";
|
|
716
|
+
/**
|
|
717
|
+
* @desc Overrides max-age for shared caches (proxies, CDNs). Ignored by private (browser) caches.
|
|
718
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#s-maxage
|
|
719
|
+
*/
|
|
720
|
+
sMaxAge?: number;
|
|
721
|
+
/**
|
|
722
|
+
* @desc Forces all caches to revalidate stale responses with the origin server before reusing them.
|
|
723
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#must-revalidate
|
|
724
|
+
*/
|
|
725
|
+
mustRevalidate?: boolean;
|
|
726
|
+
/**
|
|
727
|
+
* @desc Forces proxies and CDNs to revalidate stale responses with the origin server before reusing them.
|
|
728
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#proxy-revalidate
|
|
729
|
+
*/
|
|
730
|
+
proxyRevalidate?: boolean;
|
|
731
|
+
/**
|
|
732
|
+
* @desc A cache must understand the caching requirements for the response's status code before storing it.
|
|
733
|
+
* @desc Pair with no-store as a fallback for caches that don't support it.
|
|
734
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#must-understand
|
|
735
|
+
*/
|
|
736
|
+
mustUnderstand?: boolean;
|
|
737
|
+
/**
|
|
738
|
+
* @desc Indicates that the response body will never change while fresh.
|
|
739
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#immutable
|
|
740
|
+
*/
|
|
741
|
+
immutable?: boolean;
|
|
742
|
+
/**
|
|
743
|
+
* @desc Allows a stale response to be served in the background while the cache revalidates it, for up to N seconds.
|
|
744
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#stale-while-revalidate
|
|
745
|
+
*/
|
|
746
|
+
staleWhileRevalidate?: number;
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* @desc Creates a Middleware providing caching helpers.
|
|
750
|
+
* @param defaultPolicy — Optional default Cache-Control policy applied to all responses.
|
|
751
|
+
* @example createCacheMiddleware({ noCache: true, scope: "private" })
|
|
752
|
+
*/
|
|
753
|
+
declare const createCacheMiddleware: (defaultPolicy?: CachePolicy) => Middleware<
|
|
754
|
+
FlatObject,
|
|
755
|
+
{
|
|
756
|
+
/**
|
|
757
|
+
* @desc Provides the parsed If-None-Match request header into an array of ETags. Can also be '*' wildcard.
|
|
758
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/If-None-Match
|
|
759
|
+
*/
|
|
760
|
+
readonly ifNoneMatch: string[] | "*" | undefined;
|
|
761
|
+
/**
|
|
762
|
+
* @desc Provides the parsed If-Modified-Since request header having the timestamp of the client's cached copy.
|
|
763
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/If-Modified-Since
|
|
764
|
+
*/
|
|
765
|
+
readonly ifModifiedSince: Date | undefined;
|
|
766
|
+
/**
|
|
767
|
+
* @desc Provides the parsed Cache-Control request header to reveal the client's caching intent.
|
|
768
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control
|
|
769
|
+
*/
|
|
770
|
+
readonly cacheControl: CacheControl | undefined;
|
|
771
|
+
/**
|
|
772
|
+
* @desc Augments the Cache-Control response header, merging with the defaultPolicy if provided.
|
|
773
|
+
* @desc Pass `undefined` for a directive to unset the default value.
|
|
774
|
+
* @see defaultPolicy
|
|
775
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Caching
|
|
776
|
+
*/
|
|
777
|
+
addCachePolicy: (policy: CachePolicy) => void;
|
|
778
|
+
/**
|
|
779
|
+
* @desc Sets the ETag response header with a unique identifier for this version of the resource.
|
|
780
|
+
* @see ifNoneMatch
|
|
781
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/ETag
|
|
782
|
+
*/
|
|
783
|
+
setETag: (value: string) => void;
|
|
784
|
+
/**
|
|
785
|
+
* @desc Sets the Last-Modified response header to the timestamp when the resource was last changed.
|
|
786
|
+
* @see ifModifiedSince
|
|
787
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Last-Modified
|
|
788
|
+
*/
|
|
789
|
+
setLastModified: (date: Date) => void;
|
|
790
|
+
/**
|
|
791
|
+
* @desc Sets the Vary response header to the list of request headers that influence the response.
|
|
792
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Vary
|
|
793
|
+
*/
|
|
794
|
+
setVary: (...headers: string[]) => void;
|
|
795
|
+
/**
|
|
796
|
+
* @desc Sets the Expires response header with an explicit expiration date. Consider addCachePolicy({ maxAge }).
|
|
797
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Expires
|
|
798
|
+
*/
|
|
799
|
+
setExpires: (date: Date) => void;
|
|
800
|
+
/**
|
|
801
|
+
* @desc Sets the Clear-Site-Data response header with the "cache" directive to remove all cached responses.
|
|
802
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Clear-Site-Data
|
|
803
|
+
*/
|
|
804
|
+
clearSiteData: () => void;
|
|
805
|
+
/**
|
|
806
|
+
* @desc Sends an HTTP 304 Not Modified empty response and ends the response stream.
|
|
807
|
+
* @example return ctx.notModified() as never; // to satisfy the handler's return type
|
|
808
|
+
* @see ifNoneMatch
|
|
809
|
+
* @see ifModifiedSince
|
|
810
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/304
|
|
811
|
+
*/
|
|
812
|
+
notModified: () => void;
|
|
813
|
+
},
|
|
814
|
+
string,
|
|
815
|
+
undefined
|
|
816
|
+
>;
|
|
817
|
+
/**
|
|
818
|
+
* @desc Creates a Middleware providing cookie-setting convenience methods.
|
|
819
|
+
* @param baseOptions — Default options applied to every setCookie / clearCookie call.
|
|
820
|
+
* @example createCookieMiddleware({ httpOnly: true, secure: true, path: "/" })
|
|
821
|
+
*/
|
|
822
|
+
declare const createCookieMiddleware: (baseOptions?: CookieOptions) => Middleware<
|
|
823
|
+
FlatObject,
|
|
824
|
+
{
|
|
825
|
+
/**
|
|
826
|
+
* @desc Reads a cookie value. Checks signedCookies first, then falls back to cookies.
|
|
827
|
+
* @requires cookie-parser
|
|
828
|
+
* @see ServerConfig.cookies
|
|
829
|
+
* */
|
|
830
|
+
getCookie: (name: string) => z.core.util.JSONType | undefined;
|
|
831
|
+
/** @desc Sets a cookie on the response. Express converts non-string values to JSON. */
|
|
832
|
+
setCookie: (name: string, value: string | z.core.util.JSONType, overrides?: CookieOptions) => void;
|
|
833
|
+
/** @desc Clears a cookie on the response. */
|
|
834
|
+
clearCookie: (name: string, overrides?: Omit<CookieOptions, "expires" | "maxAge">) => void;
|
|
835
|
+
},
|
|
836
|
+
string,
|
|
837
|
+
undefined
|
|
838
|
+
>;
|
|
649
839
|
interface BuildProps<
|
|
650
840
|
IN extends IOSchema,
|
|
651
841
|
OUT extends IOSchema | z.ZodVoid,
|
|
@@ -699,6 +889,52 @@ declare class EndpointsFactory<
|
|
|
699
889
|
addMiddleware<RET extends FlatObject, ASCO extends string, AIN extends IOSchema | undefined = undefined>(
|
|
700
890
|
subject: Middleware<CTX, RET, ASCO, AIN> | ConstructorParameters<typeof Middleware<CTX, RET, ASCO, AIN>>[0],
|
|
701
891
|
): EndpointsFactory<Extension<IN, AIN>, (CTX extends Record<string, never> ? RET : CTX) & RET, SCO & ASCO>;
|
|
892
|
+
/** @desc Shorthand for .addMiddleware(createCookieMiddleware()) */
|
|
893
|
+
useCookies(...args: Parameters<typeof createCookieMiddleware>): EndpointsFactory<
|
|
894
|
+
Extension<IN, undefined>,
|
|
895
|
+
(CTX extends Record<string, never>
|
|
896
|
+
? {
|
|
897
|
+
getCookie: (name: string) => z.core.util.JSONType | undefined;
|
|
898
|
+
setCookie: (name: string, value: string | z.core.util.JSONType, overrides?: _$express.CookieOptions) => void;
|
|
899
|
+
clearCookie: (name: string, overrides?: Omit<_$express.CookieOptions, "expires" | "maxAge">) => void;
|
|
900
|
+
}
|
|
901
|
+
: CTX) & {
|
|
902
|
+
getCookie: (name: string) => z.core.util.JSONType | undefined;
|
|
903
|
+
setCookie: (name: string, value: string | z.core.util.JSONType, overrides?: _$express.CookieOptions) => void;
|
|
904
|
+
clearCookie: (name: string, overrides?: Omit<_$express.CookieOptions, "expires" | "maxAge">) => void;
|
|
905
|
+
},
|
|
906
|
+
SCO
|
|
907
|
+
>;
|
|
908
|
+
/** @desc Shorthand for .addMiddleware(createCacheMiddleware()) */
|
|
909
|
+
useCache(...args: Parameters<typeof createCacheMiddleware>): EndpointsFactory<
|
|
910
|
+
Extension<IN, undefined>,
|
|
911
|
+
(CTX extends Record<string, never>
|
|
912
|
+
? {
|
|
913
|
+
readonly ifNoneMatch: string[] | "*" | undefined;
|
|
914
|
+
readonly ifModifiedSince: Date | undefined;
|
|
915
|
+
readonly cacheControl: CacheControl | undefined;
|
|
916
|
+
addCachePolicy: (policy: CachePolicy) => void;
|
|
917
|
+
setETag: (value: string) => void;
|
|
918
|
+
setLastModified: (date: Date) => void;
|
|
919
|
+
setVary: (...headers: string[]) => void;
|
|
920
|
+
setExpires: (date: Date) => void;
|
|
921
|
+
clearSiteData: () => void;
|
|
922
|
+
notModified: () => void;
|
|
923
|
+
}
|
|
924
|
+
: CTX) & {
|
|
925
|
+
readonly ifNoneMatch: string[] | "*" | undefined;
|
|
926
|
+
readonly ifModifiedSince: Date | undefined;
|
|
927
|
+
readonly cacheControl: CacheControl | undefined;
|
|
928
|
+
addCachePolicy: (policy: CachePolicy) => void;
|
|
929
|
+
setETag: (value: string) => void;
|
|
930
|
+
setLastModified: (date: Date) => void;
|
|
931
|
+
setVary: (...headers: string[]) => void;
|
|
932
|
+
setExpires: (date: Date) => void;
|
|
933
|
+
clearSiteData: () => void;
|
|
934
|
+
notModified: () => void;
|
|
935
|
+
},
|
|
936
|
+
SCO
|
|
937
|
+
>;
|
|
702
938
|
use: <R extends Request, S extends Response, AOUT extends FlatObject = Record<string, never>>(
|
|
703
939
|
nativeMw: (request: R, response: S, next: _$express.NextFunction) => any,
|
|
704
940
|
params_1?:
|
|
@@ -740,28 +976,6 @@ declare const defaultEndpointsFactory: EndpointsFactory<undefined, Record<string
|
|
|
740
976
|
* @desc The result handler of this factory expects your endpoint to have the property 'items' in the output schema
|
|
741
977
|
*/
|
|
742
978
|
declare const arrayEndpointsFactory: EndpointsFactory<undefined, Record<string, never>, string>;
|
|
743
|
-
/**
|
|
744
|
-
* @desc Creates a Middleware providing cookie-setting convenience methods.
|
|
745
|
-
* @param baseOptions — Default options applied to every setCookie / clearCookie call.
|
|
746
|
-
* @example createCookieMiddleware({ httpOnly: true, secure: true, path: "/" })
|
|
747
|
-
*/
|
|
748
|
-
declare const createCookieMiddleware: (baseOptions?: CookieOptions) => Middleware<
|
|
749
|
-
FlatObject,
|
|
750
|
-
{
|
|
751
|
-
/**
|
|
752
|
-
* @desc Reads a cookie value. Checks signedCookies first, then falls back to cookies.
|
|
753
|
-
* @requires cookie-parser
|
|
754
|
-
* @see ServerConfig.cookies
|
|
755
|
-
* */
|
|
756
|
-
getCookie: (name: string) => z.core.util.JSONType | undefined;
|
|
757
|
-
/** @desc Sets a cookie on the response. Express converts non-string values to JSON. */
|
|
758
|
-
setCookie: (name: string, value: string | z.core.util.JSONType, overrides?: CookieOptions) => void;
|
|
759
|
-
/** @desc Clears a cookie on the response. */
|
|
760
|
-
clearCookie: (name: string, overrides?: Omit<CookieOptions, "expires" | "maxAge">) => void;
|
|
761
|
-
},
|
|
762
|
-
string,
|
|
763
|
-
undefined
|
|
764
|
-
>;
|
|
765
979
|
declare const attachRouting: (
|
|
766
980
|
config: AppConfig,
|
|
767
981
|
routing: Routing,
|
|
@@ -773,14 +987,14 @@ declare const attachRouting: (
|
|
|
773
987
|
_$qs.ParsedQs,
|
|
774
988
|
Record<string, any>
|
|
775
989
|
>;
|
|
776
|
-
logger:
|
|
990
|
+
logger: BuiltinLogger | AbstractLogger;
|
|
777
991
|
};
|
|
778
992
|
declare const createServer: (
|
|
779
993
|
config: ServerConfig,
|
|
780
994
|
routing: Routing,
|
|
781
995
|
) => Promise<{
|
|
782
996
|
app: _$express_serve_static_core0.Express;
|
|
783
|
-
logger:
|
|
997
|
+
logger: BuiltinLogger | AbstractLogger;
|
|
784
998
|
servers: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>[];
|
|
785
999
|
}>;
|
|
786
1000
|
interface ReqResCommons {
|
|
@@ -958,7 +1172,7 @@ declare const testEndpoint: <LOG extends FlatObject, REQ extends RequestOptions>
|
|
|
958
1172
|
responseMock: _$node_mocks_http0.MockResponse<Response<any, Record<string, any>>>;
|
|
959
1173
|
loggerMock: AbstractLogger &
|
|
960
1174
|
LOG & {
|
|
961
|
-
_getLogs: () => Record<"
|
|
1175
|
+
_getLogs: () => Record<"warn" | "info" | "debug" | "error", unknown[]>;
|
|
962
1176
|
};
|
|
963
1177
|
}>;
|
|
964
1178
|
declare const testMiddleware: <LOG extends FlatObject, REQ extends RequestOptions>({
|
|
@@ -977,7 +1191,7 @@ declare const testMiddleware: <LOG extends FlatObject, REQ extends RequestOption
|
|
|
977
1191
|
responseMock: _$node_mocks_http0.MockResponse<Response<any, Record<string, any>>>;
|
|
978
1192
|
loggerMock: AbstractLogger &
|
|
979
1193
|
LOG & {
|
|
980
|
-
_getLogs: () => Record<"
|
|
1194
|
+
_getLogs: () => Record<"warn" | "info" | "debug" | "error", unknown[]>;
|
|
981
1195
|
};
|
|
982
1196
|
output: FlatObject;
|
|
983
1197
|
}>;
|
|
@@ -1244,6 +1458,8 @@ export {
|
|
|
1244
1458
|
type BasicSecurity,
|
|
1245
1459
|
type BearerSecurity,
|
|
1246
1460
|
BuiltinLogger,
|
|
1461
|
+
type CacheControl,
|
|
1462
|
+
type CachePolicy,
|
|
1247
1463
|
type CommonConfig,
|
|
1248
1464
|
type CookieSecurity,
|
|
1249
1465
|
type Depicter,
|
|
@@ -1274,6 +1490,7 @@ export {
|
|
|
1274
1490
|
arrayEndpointsFactory,
|
|
1275
1491
|
arrayResultHandler,
|
|
1276
1492
|
attachRouting,
|
|
1493
|
+
createCacheMiddleware,
|
|
1277
1494
|
createConfig,
|
|
1278
1495
|
createCookieMiddleware,
|
|
1279
1496
|
createServer,
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{globalRegistry as e,z as t}from"zod";import*as n from"ramda";import r,{isHttpError as i}from"http-errors";import{isPromise as a}from"node:util/types";import o,{blue as s,cyanBright as c,gray as l,green as u,hex as d,italic as f,red as p,whiteBright as m}from"ansis";import{inspect as h}from"node:util";import{performance as g}from"node:perf_hooks";import _ from"express";import ee from"node:http";import te from"node:https";import{setInterval as ne}from"node:timers/promises";import{OpenApiBuilder as re,isReferenceObject as ie,isSchemaObject as v}from"openapi3-ts/oas31";import{createRequest as ae,createResponse as oe}from"node-mocks-http";function se(e){return e}const y={json:`application/json`,upload:`multipart/form-data`,raw:`application/octet-stream`,sse:`text/event-stream`,form:`application/x-www-form-urlencoded`},ce=[`get`,`post`,`put`,`delete`,`patch`],le=[...ce,`head`],b=e=>ce.includes(e),ue=t.object({}),de=/:([A-Za-z0-9_]+)/g,fe=e=>e.match(de)?.map(e=>e.slice(1))||[],pe=e=>{let t=(e.header(`content-type`)||``).toLowerCase().startsWith(y.upload);return`files`in e&&t},me={get:[`query`,`params`],post:[`body`,`params`,`files`],put:[`body`,`params`],patch:[`body`,`params`],delete:[`query`,`params`]},he=[`body`,`query`,`params`],ge=e=>e.method.toLowerCase(),_e=(e,t={})=>{if(e===`options`)return[];let n=e===`head`?`get`:b(e)?e:void 0;return(n?t[n]||me[n]:void 0)||he},ve=(e,t={})=>_e(ge(e),t).filter(t=>t===`files`?pe(e):!0).reduce((t,n)=>Object.assign(t,e[n]),{}),x=e=>e instanceof Error?e:e instanceof t.ZodError?new t.ZodRealError(e.issues):Error(String(e)),S=e=>e instanceof t.ZodError?e.issues.map(({path:e,message:n})=>`${e.length?`${t.core.toDotPath(e)}: `:``}${n}`).join(`; `):e.message,C=(e,t)=>E(e)&&`_zod`in e&&(t?n.path([`_zod`,`def`,`type`],e)===t:!0),w=(e,t,r)=>e.length&&t.length?n.xprod(e,t).map(r):e.concat(t),ye=e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase(),T=(...e)=>{let t=n.chain(e=>e.split(/[^A-Z0-9]/gi),e);return n.chain(e=>e.replaceAll(/[A-Z]+/g,e=>`/${e}`).split(`/`),t).map(ye).join(``)},be=n.tryCatch((e,n)=>typeof t.parse(e,n),n.always(void 0)),E=e=>typeof e==`object`&&!!e,xe=n.memoizeWith(()=>`static`,()=>process.env.NODE_ENV===`production`),Se=(e,t)=>!!t&&e!==`head`,D=`x-brand`,O=t=>{let{[D]:n}=e.get(t)||{};if(typeof n==`symbol`||typeof n==`string`||typeof n==`number`)return n},k=t=>{let{examples:n}=e.get(t)||{};return Array.isArray(n)?n:[]},A=Symbol(`Buffer`),Ce=()=>t.custom(e=>Buffer.isBuffer(e),{error:`Expected Buffer`}).meta({[D]:A}),j=Symbol(`DateIn`),we=({examples:e,...n}={})=>t.union([t.iso.date(),t.iso.datetime(),t.iso.datetime({local:!0})]).meta({examples:e}).transform(e=>new Date(e)).pipe(t.date()).meta({...n,[D]:j}),M=Symbol(`DateOut`),Te=(e={})=>t.date().transform(e=>e.toISOString()).meta({...e,[D]:M});var N=class extends Error{name=`RoutingError`;cause;constructor(e,t,n){super(e),this.cause={method:t,path:n}}},P=class extends Error{name=`DocumentationError`;cause;constructor(e,{method:t,path:n,isResponse:r}){super(e),this.cause=`${r?`Response`:`Input`} schema of an Endpoint assigned to ${t.toUpperCase()} method of ${n} path.`}},Ee=class extends Error{name=`IOSchemaError`},De=class extends Ee{cause;name=`DeepCheckError`;constructor(e){super(`Found`,{cause:e}),this.cause=e}},Oe=class extends Ee{cause;name=`OutputValidationError`;constructor(e){let n=new t.ZodError(e.issues.map(({path:e,...t})=>({...t,path:[`output`,...e]})));super(S(n),{cause:e}),this.cause=e}},F=class extends Ee{cause;name=`InputValidationError`;constructor(e){super(S(e),{cause:e}),this.cause=e}},ke=class extends Error{cause;handled;name=`ResultHandlerError`;constructor(e,t){super(S(e),{cause:e}),this.cause=e,this.handled=t}},Ae=class extends Error{name=`MissingPeerError`;constructor(e){super(`Missing peer dependency: ${e}. Please install it to use the feature.`)}};const je=Symbol(`Form`),Me=e=>(e instanceof t.ZodObject?e:t.object(e)).meta({[D]:je}),I=Symbol(`Upload`),Ne=e=>E(e)&&`name`in e&&`encoding`in e&&`mimetype`in e&&`data`in e&&`tempFilePath`in e&&`truncated`in e&&`size`in e&&`md5`in e&&`mv`in e,Pe=()=>t.custom(e=>Ne(e)&&typeof e.name==`string`&&typeof e.encoding==`string`&&typeof e.mimetype==`string`&&Buffer.isBuffer(e.data)&&typeof e.tempFilePath==`string`&&typeof e.truncated==`boolean`&&typeof e.size==`number`&&typeof e.md5==`string`&&typeof e.mv==`function`,{error:({input:e})=>({message:`Expected file upload, received ${typeof e}`})}).meta({[D]:I}),L=Symbol(`Raw`),Fe=t.object({raw:Ce()}),Ie=e=>Fe.extend(e).meta({[D]:L});function Le(e){return e?Ie(e):Fe.meta({[D]:L})}const Re=(e,{io:r,condition:i})=>n.tryCatch(()=>void t.toJSONSchema(e,{io:r,unrepresentable:`any`,override:({zodSchema:e})=>{if(i(e))throw new De(e)}}),e=>e.cause)(),ze=(e,{io:r})=>{let i=[t.toJSONSchema(e,{io:r,unrepresentable:`any`})];for(let e=0;e<i.length;e++){let t=i[e];if(n.is(Object,t)){if(t.$ref===`#`)return!0;i.push(...n.values(t))}n.is(Array,t)&&i.push(...n.values(t))}return!1},Be=e=>Re(e,{condition:e=>{let t=O(e);return typeof t==`symbol`&&[I,L,je].includes(t)},io:`input`}),Ve=[`nan`,`symbol`,`map`,`set`,`bigint`,`void`,`promise`,`never`,`function`],He=(e,t)=>Re(e,{io:t,condition:e=>{let n=O(e),{type:r}=e._zod.def;return!!(Ve.includes(r)||n===A||t===`input`&&(r===`date`||n===M)||t===`output`&&(n===j||n===L||n===I))}}),Ue=(e,{variant:n,args:r,...i})=>{if(typeof e==`function`&&(e=e(...r)),e instanceof t.ZodType)return[{schema:e,...i}];if(Array.isArray(e)&&!e.length)throw new ke(Error(`At least one ${n} response schema required.`));return(Array.isArray(e)?e:[e]).map(({schema:e,statusCode:t,mimeType:n})=>({schema:e,statusCodes:typeof t==`number`?[t]:t||i.statusCodes,mimeTypes:typeof n==`string`?[n]:n===void 0?i.mimeTypes:n}))},We=(e,t,{url:n},r)=>!e.expose&&t.error(`Server side error`,{error:e,url:n,payload:r}),R=e=>i(e)?e:r(e instanceof F?400:500,S(e),{cause:e.cause||e}),z=e=>xe()&&!e.expose?r(e.statusCode).message:e.message,Ge=e=>Object.entries(e._zod.def.shape).reduce((e,[t,r])=>w(e,k(r).map(n.objOf(t)),([e,t])=>({...e,...t})),[]),Ke=({error:e,logger:t,response:n})=>{t.error(`Result handler failure`,e);let a=z(r(500,`An error occurred while serving the result: ${e.message}.`+(e.handled?`\nOriginal error: ${e.handled.message}.`:``),{expose:i(e.cause)?e.cause.expose:!1}));n.status(500).type(`text/plain`).end(a)};var qe=class{},B=class extends qe{#e;#t;#n;constructor({input:e,security:t,handler:n}){super(),this.#e=e,this.#t=t,this.#n=n}get security(){return this.#t}get schema(){return this.#e}async execute({input:e,...n}){try{let t=await(this.#e||ue).parseAsync(e);return this.#n({...n,input:t})}catch(e){throw e instanceof t.ZodError?new F(e):e}}},Je=class extends B{constructor(e,{provider:t=()=>({}),transformer:n=e=>e}={}){super({handler:async({request:r,response:i})=>{let{promise:o,resolve:s,reject:c}=Promise.withResolvers(),l=e=>{if(e&&e instanceof Error)return c(n(e));s(t(r,i))},u=e(r,i,l);return a(u)&&u.catch(l),o}})}},Ye=class{nest(e){return{...e,"":this}}},Xe=class r extends Ye{#e;#t=n.once(()=>{if(k(this.#e.outputSchema).length||!C(this.#e.outputSchema,`object`))return;let t=Ge(this.#e.outputSchema);if(!t.length)return;let n=this.#e.outputSchema.meta();e.remove(this.#e.outputSchema).add(this.#e.outputSchema,{...n,examples:t})});constructor(e){super(),this.#e=e}#n(e){return new r({...this.#e,...e})}deprecated(){return this.#n({deprecated:!0})}get isDeprecated(){return this.#e.deprecated||!1}get description(){return this.#e.description}get summary(){return this.#e.summary}get methods(){return Object.freeze(this.#e.methods)}get inputSchema(){return this.#e.inputSchema}get outputSchema(){return this.#e.outputSchema}get requestType(){let e=Be(this.#e.inputSchema);if(e){let t=O(e);if(t===I)return`upload`;if(t===L)return`raw`;if(t===je)return`form`}return`json`}getResponses(e){return e===`positive`&&this.#t(),Object.freeze(e===`negative`?this.#e.resultHandler.getNegativeResponse():this.#e.resultHandler.getPositiveResponse(this.#e.outputSchema))}get security(){let e=n.pluck(`security`,this.#e.middlewares||[]);return n.reject(n.isNil,e)}get scopes(){return Object.freeze(this.#e.scopes||[])}get tags(){return Object.freeze(this.#e.tags||[])}getOperationId(e){return this.#e.getOperationId?.(e)}async#r(e){try{return await this.#e.outputSchema.parseAsync(e)}catch(e){throw e instanceof t.ZodError?new Oe(e):e}}async#i({method:e,logger:t,ctx:n,response:r,...i}){for(let a of this.#e.middlewares||[])if(!(e===`options`&&!(a instanceof Je))&&(Object.assign(n,await a.execute({...i,ctx:n,response:r,logger:t})),r.writableEnded)){t.warn(`A middleware has closed the stream. Accumulated context:`,n);break}}async#a({input:e,...n}){let r;try{r=await this.#e.inputSchema.parseAsync(e)}catch(e){throw e instanceof t.ZodError?new F(e):e}return this.#e.handler({...n,input:r})}async#o(e){try{await this.#e.resultHandler.execute(e)}catch(t){Ke({...e,error:new ke(x(t),e.error||void 0)})}}async execute({request:e,response:t,logger:n,config:r}){let i=ge(e),a={},o,s=ve(e,r.inputSources);try{if(await this.#i({method:i,input:s,request:e,response:t,logger:n,ctx:a}),t.writableEnded)return;if(i===`options`)return void t.status(200).end();o={output:await this.#r(await this.#a({input:s,logger:n,ctx:a})),error:null}}catch(e){o={output:null,error:x(e)}}await this.#o({...o,input:s,request:e,response:t,logger:n,ctx:a})}};const Ze=(e,t)=>e&&t?e.and(t):e||t,Qe=(e,t)=>e?e.and(t):t,V={positive:200,negative:400},$e=Object.keys(V);var et=class{#e;constructor(e){this.#e=e}execute(...e){return this.#e(...e)}},H=class extends et{#e;#t;constructor(e){super(e.handler),this.#e=e.positive,this.#t=e.negative}getPositiveResponse(e){return Ue(this.#e,{variant:`positive`,args:[e],statusCodes:[V.positive],mimeTypes:[y.json]})}getNegativeResponse(){return Ue(this.#t,{variant:`negative`,args:[],statusCodes:[V.negative],mimeTypes:[y.json]})}};const tt=t.object({status:t.literal(`error`),error:t.object({message:t.string()})});e.add(tt,{examples:[{status:`error`,error:{message:`Sample error message`}}]});const U=new H({positive:n=>{let r=t.object({status:t.literal(`success`),data:n}),i=k(n);return i.length&&e.add(r,{examples:i.map(e=>({status:`success`,data:e}))}),r},negative:tt,handler:({error:e,input:t,output:n,request:r,response:i,logger:a})=>{if(e){let n=R(e);We(n,a,r,t),i.status(n.statusCode).set(n.headers).json({status:`error`,error:{message:z(n)}});return}i.status(V.positive).json({status:`success`,data:n})}}),nt=t.string();e.add(nt,{examples:[`Sample error message`]});const rt=new H({positive:n=>{let r=n instanceof t.ZodObject&&`items`in n.shape&&n.shape.items instanceof t.ZodArray?n.shape.items:t.array(t.any());if(k(r).length)return r;let i=k(n).filter(e=>E(e)&&`items`in e&&Array.isArray(e.items)).map(e=>e.items);if(i?.length){let t=r.meta();e.remove(r).add(r,{...t,examples:i})}return r},negative:{schema:nt,mimeType:`text/plain`},handler:({response:e,output:t,error:n,logger:r,request:i,input:a})=>{if(n){let t=R(n);We(t,r,i,a),e.status(t.statusCode).type(`text/plain`).send(z(t));return}if(`items`in t&&Array.isArray(t.items)){e.status(V.positive).json(t.items);return}throw Error(`Property 'items' is missing in the endpoint output`)}});var W=class e{resultHandler;schema=void 0;middlewares=[];constructor(e){this.resultHandler=e}#e(t){let n=new e(this.resultHandler);return n.middlewares=this.middlewares.concat(t),n.schema=Ze(this.schema,t.schema),n}addMiddleware(e){return this.#e(e instanceof B?e:new B(e))}use=this.addExpressMiddleware;addExpressMiddleware(...e){return this.#e(new Je(...e))}addContext(e){return this.#e(new B({handler:e}))}build({input:e=ue,output:t,operationId:n,scope:r,tag:i,method:a,...o}){let{middlewares:s,resultHandler:c}=this,l=typeof a==`string`?[a]:a,u=typeof n==`function`?n:e=>n&&`${n}${e===`head`?`__HEAD`:``}`,d=typeof r==`string`?[r]:r||[],f=typeof i==`string`?[i]:i||[];return new Xe({...o,middlewares:s,outputSchema:t,resultHandler:c,scopes:d,tags:f,methods:l,getOperationId:u,inputSchema:Qe(this.schema,e)})}buildVoid({handler:e,...t}){return this.build({...t,output:ue,handler:async t=>(await e(t),{})})}};const it=new W(U),at=new W(rt),ot={debug:s,info:u,warn:d(`#FFA500`),error:p,ctx:c},G={debug:10,info:20,warn:30,error:40},st=e=>E(e)&&Object.keys(G).some(t=>t in e),ct=e=>e in G,lt=(e,t)=>G[e]<G[t],K=n.memoizeWith((e,t)=>`${e}${t}`,(e,t=0)=>Intl.NumberFormat(void 0,{useGrouping:!1,minimumFractionDigits:0,maximumFractionDigits:t,style:`unit`,unitDisplay:`long`,unit:e})),ut=e=>e<1e-6?K(`nanosecond`,3).format(e/1e-6):e<.001?K(`nanosecond`).format(e/1e-6):e<1?K(`microsecond`).format(e/.001):e<1e3?K(`millisecond`).format(e):e<6e4?K(`second`,2).format(e/1e3):K(`minute`,2).format(e/6e4);var dt=class e{config;constructor({color:e=o.isSupported(),level:t=xe()?`warn`:`debug`,depth:n=2,ctx:r={}}={}){this.config={color:e,level:t,depth:n,ctx:r}}format(e){let{depth:t,color:n,level:r}=this.config;return h(e,{depth:t,colors:n,breakLength:r===`debug`?80:1/0,compact:r===`debug`?3:!0})}print(e,t,n){let{level:r,ctx:{requestId:i,...a},color:o}=this.config;if(r===`silent`||lt(e,r))return;let s=[new Date().toISOString()];i&&s.push(o?ot.ctx(i):i),s.push(o?`${ot[e](e)}:`:`${e}:`,t),n!==void 0&&s.push(this.format(n)),Object.keys(a).length>0&&s.push(this.format(a)),console.log(s.join(` `))}debug(e,t){this.print(`debug`,e,t)}info(e,t){this.print(`info`,e,t)}warn(e,t){this.print(`warn`,e,t)}error(e,t){this.print(`error`,e,t)}child(t){return new e({...this.config,ctx:t})}get ctx(){return this.config.ctx}profile(e){let t=g.now();return()=>{let n=g.now()-t,{message:r,severity:i=`debug`,formatter:a=ut}=typeof e==`object`?e:{message:e};this.print(typeof i==`function`?i(n):i,r,a(n))}}};const ft=e=>new B({handler:async({request:t,response:n})=>({getCookie:e=>t.signedCookies?.[e]??t.cookies?.[e],setCookie:(t,r,i)=>{n.cookie(t,r,{...e,...i})},clearCookie:(t,r)=>{n.clearCookie(t,{...e,...r})}})});var pt=class{#e;constructor(...e){this.#e=e}apply(e,t){return t(e,_.static(...this.#e))}};const q=async(e,t=`default`)=>{try{return(await import(e))[t]}catch{}throw new Ae(e)},mt=e=>e.type===`object`,ht=n.mergeDeepWith((e,t)=>{if(Array.isArray(e)&&Array.isArray(t))return n.concat(e,t);if(e===t)return t;throw Error(`Can not flatten properties`,{cause:{a:e,b:t}})}),gt=new Set([`type`,`properties`,`required`,`examples`,`description`,`additionalProperties`]),_t=e=>{for(let t of Object.keys(e))if(!gt.has(t))return!1;return!0},vt=n.pair(!0),yt=(e,t,r)=>!(`allOf`in e)||!e.allOf?[]:e.allOf.map(e=>{if(t===`throw`&&!(e.type===`object`&&_t(e)))throw Error(`Can not merge`);return n.pair(r,e)}),bt=e=>{let t=[];return e.anyOf&&t.push(...n.map(vt,e.anyOf)),e.oneOf&&t.push(...n.map(vt,e.oneOf)),t},xt=(e,t,n,r)=>{if(!E(e.propertyNames))return;let i=[];typeof e.propertyNames.const==`string`&&i.push(e.propertyNames.const),e.propertyNames.enum&&i.push(...e.propertyNames.enum.filter(e=>typeof e==`string`));let a={...Object(e.additionalProperties)};for(let e of i)t.properties[e]??=a;r||n.push(...i)},St=(e,t,r)=>{t.examples?.length&&(r?e.examples=n.concat(e.examples||[],t.examples):e.examples=w(e.examples?.filter(E)||[],t.examples.filter(E),([e,t])=>n.mergeDeepRight(e,t)))},J=(e,t=`coerce`)=>{let r=[n.pair(!1,e)],i={type:`object`,properties:{}},a=[];for(let e=0;e<r.length;e++){let[o,s]=r[e];s.description&&(i.description??=s.description),r.push(...yt(s,t,o)),r.push(...bt(s)),St(i,s,o),mt(s)&&(r.push([o,{examples:Ct(s)}]),s.properties&&(i.properties=(t===`throw`?ht:n.mergeDeepRight)(i.properties,s.properties),!o&&s.required&&a.push(...s.required)),xt(s,i,a,o))}return a.length&&(i.required=[...new Set(a)]),i},Ct=e=>Object.entries(e.properties||{}).reduce((e,[t,r])=>{let{examples:i=[]}=E(r)?r:{};return w(e,i.map(n.objOf(t)),([e,t])=>({...e,...t}))},[]);var wt=class{logger;#e=new WeakMap;constructor(e){this.logger=e}#t(e,n,r){if(!e.isSchemaChecked){for(let e of[`input`,`output`]){let i=[t.toJSONSchema(n[`${e}Schema`],{unrepresentable:`any`})];for(let t=0;t<i.length;t++){let n=i[t];n.type&&n.type!==`object`&&this.logger.warn(`Endpoint ${e} schema is not object-based`,r);for(let e of[`allOf`,`oneOf`,`anyOf`])n[e]&&i.push(...n[e])}}if(n.requestType===`json`){let e=He(n.inputSchema,`input`);e&&this.logger.warn(`The final input schema of the endpoint contains an unsupported JSON payload type.`,{...r,reason:e})}for(let e of $e)for(let{mimeTypes:t,schema:i}of n.getResponses(e)){if(!t?.includes(y.json))continue;let n=He(i,`output`);n&&this.logger.warn(`The final ${e} response schema of the endpoint contains an unsupported JSON payload type.`,{...r,reason:n})}e.isSchemaChecked=!0}}#n(e,n,r,i){if(e.paths.has(r))return;let a=fe(r);if(a.length!==0){e.flat??=J(t.toJSONSchema(n.inputSchema,{unrepresentable:`any`,io:`input`}));for(let t of a)t in e.flat.properties||this.logger.warn(`The input schema of the endpoint is most likely missing the parameter of the path it's assigned to.`,{...i,path:r,param:t});e.paths.add(r)}}check=(e,t,n)=>{let r=this.#e.get(n);r||(r={isSchemaChecked:!1,paths:new Set},this.#e.set(n,r)),this.#t(r,n,{method:e,path:t}),this.#n(r,n,t,{method:e})}};const Tt=e=>(t,...n)=>{e(t,...n),t===`get`&&e(`head`,...n)},Et=e=>{let[t,n]=e.trim().split(/ (.+)/,2);return n&&b(t)?[n,t]:[e]},Dt=e=>e.trim().split(`/`).filter(Boolean).join(`/`),Ot=({recognizeMethodDependentRoutes:e=!0},t,n)=>Object.entries(t).map(([t,r])=>{let[i,a]=e&&b(t)&&r instanceof Ye?[`/`,t]:Et(t);return[[n||``].concat(Dt(i)||[]).join(`/`),r,a]}),kt=(e,t)=>{throw new N(`Route with explicit method can only be assigned with Endpoint`,e,t)},At=(e,t,n)=>{if(!(!n||n.includes(e)))throw new N(`Method ${e} is not supported by the assigned Endpoint.`,e,t)},jt=(e,t,n)=>{let r=`${e} ${t}`;if(n.has(r))throw new N(`Route has a duplicate`,e,t);n.add(r)},Mt=({routing:e,config:t,onEndpoint:n,onStatic:r})=>{let i=Ot(t,e),a=new Set;for(let e=0;e<i.length;e++){let[o,s,c]=i[e];if(s instanceof Ye)if(c)jt(c,o,a),At(c,o,s.methods),n(c,o,s);else{let{methods:e=[`get`]}=s;for(let t of e)jt(t,o,a),n(t,o,s)}else c&&kt(c,o),s instanceof pt?r&&s.apply(o,r):i.splice(e+1,0,...Ot(t,s,o))}},Nt=e=>e.sort((e,t)=>b(t)-+b(e)||e.localeCompare(t)).join(`, `).toUpperCase(),Pt=e=>({method:t},n,i)=>{let a=Nt(e);n.set({Allow:a}),i(r(405,`${t} is not allowed`,{headers:{Allow:a}}))},Ft=e=>({"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":Nt(e),"Access-Control-Allow-Headers":`content-type`}),It=({app:e,getLogger:t,config:r,routing:i,parsers:a})=>{let o=xe()?void 0:new wt(t()),s=new Map;return Mt({routing:i,config:r,onEndpoint:(e,t,i)=>{o?.check(e,t,i);let c=a?.[i.requestType]||[],l=n.pair(c,i);s.has(t)||s.set(t,new Map(r.cors?[[`options`,l]]:[])),s.get(t)?.set(e,l)},onStatic:e.use.bind(e)}),s},Lt=({app:e,config:t,getLogger:n,...r})=>{let i=It({app:e,getLogger:n,config:t,...r}),a=new Map;for(let[r,o]of i){let i=Array.from(o.keys());i.includes(`get`)&&i.push(`head`);for(let[a,[s,c]]of o){let o=[];t.cors&&o.push(async(e,r,a)=>{let o=n(e),s=Ft(i),l=typeof t.cors==`function`?await t.cors({request:e,endpoint:c,logger:o,defaultHeaders:s}):s;r.set(l),a()}),o.push(...s,async(e,r)=>{let i=n(e);return c.execute({request:e,response:r,logger:i,config:t})}),e[a](r,...o)}t.hintAllowedMethods!==!1&&a.set(r,Pt(i))}for(let[t,n]of a)e.all(t,n)},Rt=e=>`_httpMessage`in e&&typeof e._httpMessage==`object`&&e._httpMessage!==null&&`headersSent`in e._httpMessage&&typeof e._httpMessage.headersSent==`boolean`&&`setHeader`in e._httpMessage&&typeof e._httpMessage.setHeader==`function`,zt=e=>`server`in e&&typeof e.server==`object`&&e.server!==null&&`close`in e.server&&typeof e.server.close==`function`,Bt=e=>`encrypted`in e&&typeof e.encrypted==`boolean`&&e.encrypted,Vt=({},e)=>void(!e.headersSent&&e.setHeader(`connection`,`close`)),Ht=e=>{let{promise:t,resolve:n,reject:r}=Promise.withResolvers();return e.close(e=>e?r(e):n()),t},Ut=(e,{timeout:t=1e3,logger:n}={})=>{let r,i=new Set,a=e=>void i.delete(e.destroy()),o=e=>void(Rt(e)?!e._httpMessage.headersSent&&e._httpMessage.setHeader(`connection`,`close`):a(e)),s=e=>void(r?e.destroy():i.add(e.once(`close`,()=>void i.delete(e))));for(let t of e)for(let e of[`connection`,`secureConnection`])t.on(e,s);let c=async()=>{for(let t of e)t.on(`request`,Vt);n?.info(`Graceful shutdown`,{sockets:i.size,timeout:t});for(let e of i)(Bt(e)||zt(e))&&o(e);for await(let e of ne(10,Date.now()))if(i.size===0||Date.now()-e>=t)break;for(let e of i)a(e);return Promise.allSettled(e.map(Ht))};return{sockets:i,shutdown:()=>r??=c()}},Wt=Symbol.for(`express-zod-api`),Gt=({errorHandler:e,getLogger:t})=>async(n,r,i,a)=>n?e.execute({error:x(n),request:r,response:i,input:null,output:null,ctx:{},logger:t(r)}):a(),Kt=({errorHandler:e,getLogger:t})=>async(n,i)=>{let a=r(404,`Can not ${n.method} ${n.path}`),o=t(n);try{await e.execute({request:n,response:i,logger:o,error:a,input:null,output:null,ctx:{}})}catch(e){Ke({response:i,logger:o,error:new ke(x(e),a)})}},qt=e=>(t,{},n)=>{if(Object.values(t?.files||[]).flat().find(({truncated:e})=>e))return n(e);n()},Jt=async({config:e})=>{let t=await q(`cookie-parser`),{secret:n,...r}={...typeof e.cookies==`object`&&e.cookies};return t(n,Object.keys(r).length?r:void 0)},Yt=e=>({log:e.debug.bind(e)}),Xt=async({getLogger:e,config:t})=>{let n=await q(`express-fileupload`),{limitError:r,beforeUpload:i,...a}={...typeof t.upload==`object`&&t.upload},o=[];return o.push(async(t,r,o)=>{let s=e(t);return await i?.({request:t,logger:s}),n({debug:!0,...a,abortOnLimit:!1,parseNested:!0,logger:Yt(s)})(t,r,o)}),r&&o.push(qt(r)),o},Zt=(e,{},t)=>{Buffer.isBuffer(e.body)&&(e.body={raw:e.body}),t()},Qt=({logger:e,config:{childLoggerProvider:t,accessLogger:n=({method:e,path:t},n)=>n.debug(`${e}: ${t}`)}})=>async(r,i,a)=>{let o=await t?.({request:r,parent:e})||e;n?.(r,o),r.res&&(r.res.locals[Wt]={logger:o}),a()},$t=e=>t=>t?.res?.locals[Wt]?.logger||e,en=e=>process.on(`deprecation`,({message:t,namespace:n,name:r,stack:i})=>e.warn(`${r} (${n}): ${t}`,i.split(`
|
|
2
|
-
`).slice(1))),
|
|
1
|
+
import{globalRegistry as e,z as t}from"zod";import*as n from"ramda";import r,{isHttpError as i}from"http-errors";import{isPromise as a}from"node:util/types";import o,{blue as s,cyanBright as c,gray as l,green as u,hex as d,italic as f,red as p,whiteBright as m}from"ansis";import{inspect as h}from"node:util";import{performance as g}from"node:perf_hooks";import _ from"express";import ee from"node:http";import te from"node:https";import{setInterval as ne}from"node:timers/promises";import{OpenApiBuilder as re,isReferenceObject as ie,isSchemaObject as v}from"openapi3-ts/oas31";import{createRequest as ae,createResponse as oe}from"node-mocks-http";function se(e){return e}const y={json:`application/json`,upload:`multipart/form-data`,raw:`application/octet-stream`,sse:`text/event-stream`,form:`application/x-www-form-urlencoded`},ce=[`get`,`post`,`put`,`delete`,`patch`],le=[...ce,`head`],b=e=>ce.includes(e),ue=t.object({}),de=/:([A-Za-z0-9_]+)/g,fe=e=>e.match(de)?.map(e=>e.slice(1))||[],pe=e=>{let t=(e.header(`content-type`)||``).toLowerCase().startsWith(y.upload);return`files`in e&&t},me={get:[`query`,`params`],post:[`body`,`params`,`files`],put:[`body`,`params`],patch:[`body`,`params`],delete:[`query`,`params`]},he=[`body`,`query`,`params`],ge=e=>e.method.toLowerCase(),_e=(e,t={})=>{if(e===`options`)return[];let n=e===`head`?`get`:b(e)?e:void 0;return(n?t[n]||me[n]:void 0)||he},ve=(e,t={})=>_e(ge(e),t).filter(t=>t===`files`?pe(e):!0).reduce((t,n)=>Object.assign(t,e[n]),{}),x=e=>e instanceof Error?e:e instanceof t.ZodError?new t.ZodRealError(e.issues):Error(String(e)),S=e=>e instanceof t.ZodError?e.issues.map(({path:e,message:n})=>`${e.length?`${t.core.toDotPath(e)}: `:``}${n}`).join(`; `):e.message,C=(e,t)=>E(e)&&`_zod`in e&&(t?n.path([`_zod`,`def`,`type`],e)===t:!0),w=(e,t,r)=>e.length&&t.length?n.xprod(e,t).map(r):e.concat(t),ye=e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase(),T=(...e)=>{let t=n.chain(e=>e.split(/[^A-Z0-9]/gi),e);return n.chain(e=>e.replaceAll(/[A-Z]+/g,e=>`/${e}`).split(`/`),t).map(ye).join(``)},be=n.tryCatch((e,n)=>typeof t.parse(e,n),n.always(void 0)),E=e=>typeof e==`object`&&!!e,xe=n.memoizeWith(()=>`static`,()=>process.env.NODE_ENV===`production`),Se=(e,t)=>!!t&&e!==`head`,D=`x-brand`,O=t=>{let{[D]:n}=e.get(t)||{};if(typeof n==`symbol`||typeof n==`string`||typeof n==`number`)return n},k=t=>{let{examples:n}=e.get(t)||{};return Array.isArray(n)?n:[]},A=Symbol(`Buffer`),Ce=()=>t.custom(e=>Buffer.isBuffer(e),{error:`Expected Buffer`}).meta({[D]:A}),j=Symbol(`DateIn`),we=({examples:e,...n}={})=>t.union([t.iso.date(),t.iso.datetime(),t.iso.datetime({local:!0})]).meta({examples:e}).transform(e=>new Date(e)).pipe(t.date()).meta({...n,[D]:j}),M=Symbol(`DateOut`),Te=(e={})=>t.date().transform(e=>e.toISOString()).meta({...e,[D]:M});var N=class extends Error{name=`RoutingError`;cause;constructor(e,t,n){super(e),this.cause={method:t,path:n}}},P=class extends Error{name=`DocumentationError`;cause;constructor(e,{method:t,path:n,isResponse:r}){super(e),this.cause=`${r?`Response`:`Input`} schema of an Endpoint assigned to ${t.toUpperCase()} method of ${n} path.`}},Ee=class extends Error{name=`IOSchemaError`},De=class extends Ee{cause;name=`DeepCheckError`;constructor(e){super(`Found`,{cause:e}),this.cause=e}},Oe=class extends Ee{cause;name=`OutputValidationError`;constructor(e){let n=new t.ZodError(e.issues.map(({path:e,...t})=>({...t,path:[`output`,...e]})));super(S(n),{cause:e}),this.cause=e}},F=class extends Ee{cause;name=`InputValidationError`;constructor(e){super(S(e),{cause:e}),this.cause=e}},I=class extends Error{cause;handled;name=`ResultHandlerError`;constructor(e,t){super(S(e),{cause:e}),this.cause=e,this.handled=t}},ke=class extends Error{name=`MissingPeerError`;constructor(e){super(`Missing peer dependency: ${e}. Please install it to use the feature.`)}};const Ae=Symbol(`Form`),je=e=>(e instanceof t.ZodObject?e:t.object(e)).meta({[D]:Ae}),L=Symbol(`Upload`),Me=e=>E(e)&&`name`in e&&`encoding`in e&&`mimetype`in e&&`data`in e&&`tempFilePath`in e&&`truncated`in e&&`size`in e&&`md5`in e&&`mv`in e,Ne=()=>t.custom(e=>Me(e)&&typeof e.name==`string`&&typeof e.encoding==`string`&&typeof e.mimetype==`string`&&Buffer.isBuffer(e.data)&&typeof e.tempFilePath==`string`&&typeof e.truncated==`boolean`&&typeof e.size==`number`&&typeof e.md5==`string`&&typeof e.mv==`function`,{error:({input:e})=>({message:`Expected file upload, received ${typeof e}`})}).meta({[D]:L}),R=Symbol(`Raw`),Pe=t.object({raw:Ce()}),Fe=e=>Pe.extend(e).meta({[D]:R});function Ie(e){return e?Fe(e):Pe.meta({[D]:R})}const Le=(e,{io:r,condition:i})=>n.tryCatch(()=>void t.toJSONSchema(e,{io:r,unrepresentable:`any`,override:({zodSchema:e})=>{if(i(e))throw new De(e)}}),e=>e.cause)(),Re=(e,{io:r})=>{let i=[t.toJSONSchema(e,{io:r,unrepresentable:`any`})];for(let e=0;e<i.length;e++){let t=i[e];if(n.is(Object,t)){if(t.$ref===`#`)return!0;i.push(...n.values(t))}n.is(Array,t)&&i.push(...n.values(t))}return!1},ze=e=>Le(e,{condition:e=>{let t=O(e);return typeof t==`symbol`&&[L,R,Ae].includes(t)},io:`input`}),Be=[`nan`,`symbol`,`map`,`set`,`bigint`,`void`,`promise`,`never`,`function`],Ve=(e,t)=>Le(e,{io:t,condition:e=>{let n=O(e),{type:r}=e._zod.def;return!!(Be.includes(r)||n===A||t===`input`&&(r===`date`||n===M)||t===`output`&&(n===j||n===R||n===L))}}),He=(e,{variant:n,args:r,...i})=>{if(typeof e==`function`&&(e=e(...r)),e instanceof t.ZodType)return[{schema:e,...i}];if(Array.isArray(e)&&!e.length)throw new I(Error(`At least one ${n} response schema required.`));return(Array.isArray(e)?e:[e]).map(({schema:e,statusCode:t,mimeType:n})=>({schema:e,statusCodes:typeof t==`number`?[t]:t||i.statusCodes,mimeTypes:typeof n==`string`?[n]:n===void 0?i.mimeTypes:n}))},Ue=(e,t,{url:n},r)=>!e.expose&&t.error(`Server side error`,{error:e,url:n,payload:r}),z=e=>i(e)?e:r(e instanceof F?400:500,S(e),{cause:e.cause||e}),B=e=>xe()&&!e.expose?r(e.statusCode).message:e.message,We=e=>Object.entries(e._zod.def.shape).reduce((e,[t,r])=>w(e,k(r).map(n.objOf(t)),([e,t])=>({...e,...t})),[]),Ge=({error:e,logger:t,response:n})=>{t.error(`Result handler failure`,e);let a=B(r(500,`An error occurred while serving the result: ${e.message}.`+(e.handled?`\nOriginal error: ${e.handled.message}.`:``),{expose:i(e.cause)?e.cause.expose:!1}));n.status(500).type(`text/plain`).end(a)};var Ke=class{},V=class extends Ke{#e;#t;#n;constructor({input:e,security:t,handler:n}){super(),this.#e=e,this.#t=t,this.#n=n}get security(){return this.#t}get schema(){return this.#e}async execute({input:e,...n}){try{let t=await(this.#e||ue).parseAsync(e);return this.#n({...n,input:t})}catch(e){throw e instanceof t.ZodError?new F(e):e}}},qe=class extends V{constructor(e,{provider:t=()=>({}),transformer:n=e=>e}={}){super({handler:async({request:r,response:i})=>{let{promise:o,resolve:s,reject:c}=Promise.withResolvers(),l=e=>{if(e&&e instanceof Error)return c(n(e));s(t(r,i))},u=e(r,i,l);return a(u)&&u.catch(l),o}})}},Je=class{nest(e){return{...e,"":this}}},Ye=class r extends Je{#e;#t=n.once(()=>{if(k(this.#e.outputSchema).length||!C(this.#e.outputSchema,`object`))return;let t=We(this.#e.outputSchema);if(!t.length)return;let n=this.#e.outputSchema.meta();e.remove(this.#e.outputSchema).add(this.#e.outputSchema,{...n,examples:t})});constructor(e){super(),this.#e=e}#n(e){return new r({...this.#e,...e})}deprecated(){return this.#n({deprecated:!0})}get isDeprecated(){return this.#e.deprecated||!1}get description(){return this.#e.description}get summary(){return this.#e.summary}get methods(){return Object.freeze(this.#e.methods)}get inputSchema(){return this.#e.inputSchema}get outputSchema(){return this.#e.outputSchema}get requestType(){let e=ze(this.#e.inputSchema);if(e){let t=O(e);if(t===L)return`upload`;if(t===R)return`raw`;if(t===Ae)return`form`}return`json`}getResponses(e){return e===`positive`&&this.#t(),Object.freeze(e===`negative`?this.#e.resultHandler.getNegativeResponse():this.#e.resultHandler.getPositiveResponse(this.#e.outputSchema))}get security(){let e=n.pluck(`security`,this.#e.middlewares||[]);return n.reject(n.isNil,e)}get scopes(){return Object.freeze(this.#e.scopes||[])}get tags(){return Object.freeze(this.#e.tags||[])}getOperationId(e){return this.#e.getOperationId?.(e)}async#r(e){try{return await this.#e.outputSchema.parseAsync(e)}catch(e){throw e instanceof t.ZodError?new Oe(e):e}}async#i({method:e,logger:t,ctx:n,response:r,...i}){for(let a of this.#e.middlewares||[])if(!(e===`options`&&!(a instanceof qe))&&(Object.assign(n,await a.execute({...i,ctx:n,response:r,logger:t})),r.writableEnded)){t.warn(`A middleware has closed the stream. Accumulated context:`,n);break}}async#a({input:e,...n}){let r;try{r=await this.#e.inputSchema.parseAsync(e)}catch(e){throw e instanceof t.ZodError?new F(e):e}return this.#e.handler({...n,input:r})}async#o(e){try{await this.#e.resultHandler.execute(e)}catch(t){Ge({...e,error:new I(x(t),e.error||void 0)})}}async execute({request:e,response:t,logger:n,config:r}){let i=ge(e),a={},o,s=ve(e,r.inputSources);try{if(await this.#i({method:i,input:s,request:e,response:t,logger:n,ctx:a}),t.writableEnded)return;if(i===`options`)return void t.status(200).end();let r=await this.#a({input:s,logger:n,ctx:a});if(t.writableEnded)return;o={output:await this.#r(r),error:null}}catch(e){o={output:null,error:x(e)}}await this.#o({...o,input:s,request:e,response:t,logger:n,ctx:a})}};const Xe=(e,t)=>e&&t?e.and(t):e||t,Ze=(e,t)=>e?e.and(t):t,H={positive:200,negative:400},Qe=Object.keys(H);var $e=class{#e;constructor(e){this.#e=e}execute(...e){return this.#e(...e)}},U=class extends $e{#e;#t;constructor(e){super(e.handler),this.#e=e.positive,this.#t=e.negative}getPositiveResponse(e){return He(this.#e,{variant:`positive`,args:[e],statusCodes:[H.positive],mimeTypes:[y.json]})}getNegativeResponse(){return He(this.#t,{variant:`negative`,args:[],statusCodes:[H.negative],mimeTypes:[y.json]})}};const et=t.object({status:t.literal(`error`),error:t.object({message:t.string()})});e.add(et,{examples:[{status:`error`,error:{message:`Sample error message`}}]});const W=new U({positive:n=>{let r=t.object({status:t.literal(`success`),data:n}),i=k(n);return i.length&&e.add(r,{examples:i.map(e=>({status:`success`,data:e}))}),r},negative:et,handler:({error:e,input:t,output:n,request:r,response:i,logger:a})=>{if(e){let n=z(e);Ue(n,a,r,t),i.status(n.statusCode).set(n.headers).json({status:`error`,error:{message:B(n)}});return}i.status(H.positive).json({status:`success`,data:n})}}),tt=t.string();e.add(tt,{examples:[`Sample error message`]});const nt=new U({positive:n=>{let r=n instanceof t.ZodObject&&`items`in n.shape&&n.shape.items instanceof t.ZodArray?n.shape.items:t.array(t.any());if(k(r).length)return r;let i=k(n).filter(e=>E(e)&&`items`in e&&Array.isArray(e.items)).map(e=>e.items);if(i?.length){let t=r.meta();e.remove(r).add(r,{...t,examples:i})}return r},negative:{schema:tt,mimeType:`text/plain`},handler:({response:e,output:t,error:n,logger:r,request:i,input:a})=>{if(n){let t=z(n);Ue(t,r,i,a),e.status(t.statusCode).type(`text/plain`).send(B(t));return}if(`items`in t&&Array.isArray(t.items)){e.status(H.positive).json(t.items);return}throw Error(`Property 'items' is missing in the endpoint output`)}}),rt=e=>{let t=[];return e.scope&&t.push(e.scope),e.noStore&&t.push(`no-store`),e.noCache&&t.push(`no-cache`),e.maxAge!==void 0&&t.push(`max-age=${e.maxAge}`),e.sMaxAge!==void 0&&t.push(`s-maxage=${e.sMaxAge}`),e.mustRevalidate&&t.push(`must-revalidate`),e.proxyRevalidate&&t.push(`proxy-revalidate`),e.mustUnderstand&&t.push(`must-understand`),e.immutable&&t.push(`immutable`),e.noTransform&&t.push(`no-transform`),e.staleWhileRevalidate!==void 0&&t.push(`stale-while-revalidate=${e.staleWhileRevalidate}`),e.staleIfError!==void 0&&t.push(`stale-if-error=${e.staleIfError}`),t.join(`, `)},it={"max-age":`maxAge`,"max-stale":`maxStale`,"min-fresh":`minFresh`,"stale-if-error":`staleIfError`},at={"no-cache":`noCache`,"no-store":`noStore`,"no-transform":`noTransform`,"only-if-cached":`onlyIfCached`},ot=e=>{if(!e)return;let t={};for(let n of e.toLowerCase().split(`,`)){let[e,r]=n.split(`=`),i=it[e.trim()];if(i){let e=parseInt(r?.trim()??``,10);isNaN(e)||(t[i]=e);continue}let a=at[e.trim()];a&&(t[a]=!0)}return t},st=e=>new V({handler:async({request:t,response:n})=>(e&&n.setHeader(`Cache-Control`,rt(e)),{get ifNoneMatch(){let e=t.headers[`if-none-match`];if(!e)return;let n=e.trim();return n===`*`?n:n.split(`,`).map(e=>e.trim().replace(/^(?:W\/)?"/,``).replace(/"$/,``))},get ifModifiedSince(){let e=t.headers[`if-modified-since`];if(!e)return;let n=new Date(e);return isNaN(n.getTime())?void 0:n},get cacheControl(){return ot(t.headers[`cache-control`])},addCachePolicy:t=>{n.setHeader(`Cache-Control`,rt({...e,...t}))},setETag:e=>{n.setHeader(`ETag`,e.startsWith(`"`)?e:`"${e}"`)},setLastModified:e=>{n.setHeader(`Last-Modified`,e.toUTCString())},setVary:(...e)=>{n.setHeader(`Vary`,e.join(`, `))},setExpires:e=>{n.setHeader(`Expires`,e.toUTCString())},clearSiteData:()=>{n.setHeader(`Clear-Site-Data`,`"cache"`)},notModified:()=>{n.status(304).end()}})}),ct=e=>new V({handler:async({request:t,response:n})=>({getCookie:e=>t.signedCookies?.[e]??t.cookies?.[e],setCookie:(t,r,i)=>{n.cookie(t,r,{...e,...i})},clearCookie:(t,r)=>{n.clearCookie(t,{...e,...r})}})});var G=class e{resultHandler;schema=void 0;middlewares=[];constructor(e){this.resultHandler=e}#e(t){let n=new e(this.resultHandler);return n.middlewares=this.middlewares.concat(t),n.schema=Xe(this.schema,t.schema),n}addMiddleware(e){return this.#e(e instanceof V?e:new V(e))}useCookies(...e){return this.#e(ct(...e))}useCache(...e){return this.#e(st(...e))}use=this.addExpressMiddleware;addExpressMiddleware(...e){return this.#e(new qe(...e))}addContext(e){return this.#e(new V({handler:e}))}build({input:e=ue,output:t,operationId:n,scope:r,tag:i,method:a,...o}){let{middlewares:s,resultHandler:c}=this,l=typeof a==`string`?[a]:a,u=typeof n==`function`?n:e=>n&&`${n}${e===`head`?`__HEAD`:``}`,d=typeof r==`string`?[r]:r||[],f=typeof i==`string`?[i]:i||[];return new Ye({...o,middlewares:s,outputSchema:t,resultHandler:c,scopes:d,tags:f,methods:l,getOperationId:u,inputSchema:Ze(this.schema,e)})}buildVoid({handler:e,...t}){return this.build({...t,output:ue,handler:async t=>(await e(t),{})})}};const lt=new G(W),ut=new G(nt),dt={debug:s,info:u,warn:d(`#FFA500`),error:p,ctx:c},K={debug:10,info:20,warn:30,error:40},ft=e=>E(e)&&Object.keys(K).some(t=>t in e),pt=e=>e in K,mt=(e,t)=>K[e]<K[t],q=n.memoizeWith((e,t)=>`${e}${t}`,(e,t=0)=>Intl.NumberFormat(void 0,{useGrouping:!1,minimumFractionDigits:0,maximumFractionDigits:t,style:`unit`,unitDisplay:`long`,unit:e})),ht=e=>e<1e-6?q(`nanosecond`,3).format(e/1e-6):e<.001?q(`nanosecond`).format(e/1e-6):e<1?q(`microsecond`).format(e/.001):e<1e3?q(`millisecond`).format(e):e<6e4?q(`second`,2).format(e/1e3):q(`minute`,2).format(e/6e4);var gt=class e{config;constructor({color:e=o.isSupported(),level:t=xe()?`warn`:`debug`,depth:n=2,ctx:r={}}={}){this.config={color:e,level:t,depth:n,ctx:r}}format(e){let{depth:t,color:n,level:r}=this.config;return h(e,{depth:t,colors:n,breakLength:r===`debug`?80:1/0,compact:r===`debug`?3:!0})}print(e,t,n){let{level:r,ctx:{requestId:i,...a},color:o}=this.config;if(r===`silent`||mt(e,r))return;let s=[new Date().toISOString()];i&&s.push(o?dt.ctx(i):i),s.push(o?`${dt[e](e)}:`:`${e}:`,t),n!==void 0&&s.push(this.format(n)),Object.keys(a).length>0&&s.push(this.format(a)),console.log(s.join(` `))}debug(e,t){this.print(`debug`,e,t)}info(e,t){this.print(`info`,e,t)}warn(e,t){this.print(`warn`,e,t)}error(e,t){this.print(`error`,e,t)}child(t){return new e({...this.config,ctx:t})}get ctx(){return this.config.ctx}profile(e){let t=g.now();return()=>{let n=g.now()-t,{message:r,severity:i=`debug`,formatter:a=ht}=typeof e==`object`?e:{message:e};this.print(typeof i==`function`?i(n):i,r,a(n))}}},_t=class{#e;constructor(...e){this.#e=e}apply(e,t){return t(e,_.static(...this.#e))}};const J=async(e,t=`default`)=>{try{return(await import(e))[t]}catch{}throw new ke(e)},vt=e=>e.type===`object`,yt=n.mergeDeepWith((e,t)=>{if(Array.isArray(e)&&Array.isArray(t))return n.concat(e,t);if(e===t)return t;throw Error(`Can not flatten properties`,{cause:{a:e,b:t}})}),bt=new Set([`type`,`properties`,`required`,`examples`,`description`,`additionalProperties`]),xt=e=>{for(let t of Object.keys(e))if(!bt.has(t))return!1;return!0},St=n.pair(!0),Ct=(e,t,r)=>!(`allOf`in e)||!e.allOf?[]:e.allOf.map(e=>{if(t===`throw`&&!(e.type===`object`&&xt(e)))throw Error(`Can not merge`);return n.pair(r,e)}),wt=e=>{let t=[];return e.anyOf&&t.push(...n.map(St,e.anyOf)),e.oneOf&&t.push(...n.map(St,e.oneOf)),t},Tt=(e,t,n,r)=>{if(!E(e.propertyNames))return;let i=[];typeof e.propertyNames.const==`string`&&i.push(e.propertyNames.const),e.propertyNames.enum&&i.push(...e.propertyNames.enum.filter(e=>typeof e==`string`));let a={...Object(e.additionalProperties)};for(let e of i)t.properties[e]??=a;r||n.push(...i)},Et=(e,t,r)=>{t.examples?.length&&(r?e.examples=n.concat(e.examples||[],t.examples):e.examples=w(e.examples?.filter(E)||[],t.examples.filter(E),([e,t])=>n.mergeDeepRight(e,t)))},Y=(e,t=`coerce`)=>{let r=[n.pair(!1,e)],i={type:`object`,properties:{}},a=[];for(let[e,o]of r)o.description&&(i.description??=o.description),r.push(...Ct(o,t,e)),r.push(...wt(o)),Et(i,o,e),vt(o)&&(r.push([e,{examples:Dt(o)}]),o.properties&&(i.properties=(t===`throw`?yt:n.mergeDeepRight)(i.properties,o.properties),!e&&o.required&&a.push(...o.required)),Tt(o,i,a,e));return a.length&&(i.required=[...new Set(a)]),i},Dt=e=>Object.entries(e.properties||{}).reduce((e,[t,r])=>{let{examples:i=[]}=E(r)?r:{};return w(e,i.map(n.objOf(t)),([e,t])=>({...e,...t}))},[]);var Ot=class{logger;#e=new WeakMap;constructor(e){this.logger=e}#t(e,n,r){if(!e.isSchemaChecked){for(let e of[`input`,`output`]){let i=[t.toJSONSchema(n[`${e}Schema`],{unrepresentable:`any`})];for(let t of i){t.type&&t.type!==`object`&&this.logger.warn(`Endpoint ${e} schema is not object-based`,r);for(let e of[`allOf`,`oneOf`,`anyOf`])t[e]&&i.push(...t[e])}}if(n.requestType===`json`){let e=Ve(n.inputSchema,`input`);e&&this.logger.warn(`The final input schema of the endpoint contains an unsupported JSON payload type.`,{...r,reason:e})}for(let e of Qe)for(let{mimeTypes:t,schema:i}of n.getResponses(e)){if(!t?.includes(y.json))continue;let n=Ve(i,`output`);n&&this.logger.warn(`The final ${e} response schema of the endpoint contains an unsupported JSON payload type.`,{...r,reason:n})}e.isSchemaChecked=!0}}#n(e,n,r,i){if(e.paths.has(r))return;let a=fe(r);if(a.length!==0){e.flat??=Y(t.toJSONSchema(n.inputSchema,{unrepresentable:`any`,io:`input`}));for(let t of a)t in e.flat.properties||this.logger.warn(`The input schema of the endpoint is most likely missing the parameter of the path it's assigned to.`,{...i,path:r,param:t});e.paths.add(r)}}check=(e,t,n)=>{let r=this.#e.get(n);r||(r={isSchemaChecked:!1,paths:new Set},this.#e.set(n,r)),this.#t(r,n,{method:e,path:t}),this.#n(r,n,t,{method:e})}};const kt=e=>(t,...n)=>{e(t,...n),t===`get`&&e(`head`,...n)},At=e=>{let[t,n]=e.trim().split(/ (.+)/,2);return n&&b(t)?[n,t]:[e]},jt=e=>e.trim().split(`/`).filter(Boolean).join(`/`),Mt=({recognizeMethodDependentRoutes:e=!0},t,n)=>Object.entries(t).map(([t,r])=>{let[i,a]=e&&b(t)&&r instanceof Je?[`/`,t]:At(t);return[[n||``].concat(jt(i)||[]).join(`/`),r,a]}),Nt=(e,t)=>{throw new N(`Route with explicit method can only be assigned with Endpoint`,e,t)},Pt=(e,t,n)=>{if(!(!n||n.includes(e)))throw new N(`Method ${e} is not supported by the assigned Endpoint.`,e,t)},Ft=(e,t,n)=>{let r=`${e} ${t}`;if(n.has(r))throw new N(`Route has a duplicate`,e,t);n.add(r)},It=({routing:e,config:t,onEndpoint:n,onStatic:r})=>{let i=Mt(t,e),a=new Set;for(let e=0;e<i.length;e++){let[o,s,c]=i[e];if(s instanceof Je)if(c)Ft(c,o,a),Pt(c,o,s.methods),n(c,o,s);else{let{methods:e=[`get`]}=s;for(let t of e)Ft(t,o,a),n(t,o,s)}else c&&Nt(c,o),s instanceof _t?r&&s.apply(o,r):i.splice(e+1,0,...Mt(t,s,o))}},Lt=e=>e.sort((e,t)=>b(t)-+b(e)||e.localeCompare(t)).join(`, `).toUpperCase(),Rt=e=>({method:t},n,i)=>{let a=Lt(e);n.set({Allow:a}),i(r(405,`${t} is not allowed`,{headers:{Allow:a}}))},zt=e=>({"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":Lt(e),"Access-Control-Allow-Headers":`content-type`}),Bt=({app:e,getLogger:t,config:r,routing:i,parsers:a})=>{let o=xe()?void 0:new Ot(t()),s=new Map;return It({routing:i,config:r,onEndpoint:(e,t,i)=>{o?.check(e,t,i);let c=a?.[i.requestType]||[],l=n.pair(c,i);s.has(t)||s.set(t,new Map(r.cors?[[`options`,l]]:[])),s.get(t)?.set(e,l)},onStatic:e.use.bind(e)}),s},Vt=({app:e,config:t,getLogger:n,...r})=>{let i=Bt({app:e,getLogger:n,config:t,...r}),a=new Map;for(let[r,o]of i){let i=Array.from(o.keys());i.includes(`get`)&&i.push(`head`);for(let[a,[s,c]]of o){let o=[];t.cors&&o.push(async(e,r,a)=>{let o=n(e),s=zt(i),l=typeof t.cors==`function`?await t.cors({request:e,endpoint:c,logger:o,defaultHeaders:s}):s;r.set(l),a()}),o.push(...s,async(e,r)=>{let i=n(e);return c.execute({request:e,response:r,logger:i,config:t})}),e[a](r,...o)}t.hintAllowedMethods!==!1&&a.set(r,Rt(i))}for(let[t,n]of a)e.all(t,n)},Ht=e=>`_httpMessage`in e&&typeof e._httpMessage==`object`&&e._httpMessage!==null&&`headersSent`in e._httpMessage&&typeof e._httpMessage.headersSent==`boolean`&&`setHeader`in e._httpMessage&&typeof e._httpMessage.setHeader==`function`,Ut=e=>`server`in e&&typeof e.server==`object`&&e.server!==null&&`close`in e.server&&typeof e.server.close==`function`,Wt=e=>`encrypted`in e&&typeof e.encrypted==`boolean`&&e.encrypted,Gt=({},e)=>void(!e.headersSent&&e.setHeader(`connection`,`close`)),Kt=e=>{let{promise:t,resolve:n,reject:r}=Promise.withResolvers();return e.close(e=>e?r(e):n()),t},qt=(e,{timeout:t=1e3,logger:n}={})=>{let r,i=new Set,a=e=>void i.delete(e.destroy()),o=e=>void(Ht(e)?!e._httpMessage.headersSent&&e._httpMessage.setHeader(`connection`,`close`):a(e)),s=e=>void(r?e.destroy():i.add(e.once(`close`,()=>void i.delete(e))));for(let t of e)for(let e of[`connection`,`secureConnection`])t.on(e,s);let c=async()=>{for(let t of e)t.on(`request`,Gt);n?.info(`Graceful shutdown`,{sockets:i.size,timeout:t});for(let e of i)(Wt(e)||Ut(e))&&o(e);for await(let e of ne(10,Date.now()))if(i.size===0||Date.now()-e>=t)break;for(let e of i)a(e);return Promise.allSettled(e.map(Kt))};return{sockets:i,shutdown:()=>r??=c()}},Jt=Symbol.for(`express-zod-api`),Yt=({errorHandler:e,getLogger:t})=>async(n,r,i,a)=>n?e.execute({error:x(n),request:r,response:i,input:null,output:null,ctx:{},logger:t(r)}):a(),Xt=({errorHandler:e,getLogger:t})=>async(n,i)=>{let a=r(404,`Can not ${n.method} ${n.path}`),o=t(n);try{await e.execute({request:n,response:i,logger:o,error:a,input:null,output:null,ctx:{}})}catch(e){Ge({response:i,logger:o,error:new I(x(e),a)})}},Zt=e=>(t,{},n)=>{if(Object.values(t?.files||[]).flat().find(({truncated:e})=>e))return n(e);n()},Qt=async({config:e})=>{let t=await J(`cookie-parser`),{secret:n,...r}={...typeof e.cookies==`object`&&e.cookies};return t(n,Object.keys(r).length?r:void 0)},$t=e=>({log:e.debug.bind(e)}),en=async({getLogger:e,config:t})=>{let n=await J(`express-fileupload`),{limitError:r,beforeUpload:i,...a}={...typeof t.upload==`object`&&t.upload},o=[];return o.push(async(t,r,o)=>{let s=e(t);return await i?.({request:t,logger:s}),n({debug:!0,...a,abortOnLimit:!1,parseNested:!0,logger:$t(s)})(t,r,o)}),r&&o.push(Zt(r)),o},tn=(e,{},t)=>{Buffer.isBuffer(e.body)&&(e.body={raw:e.body}),t()},nn=({logger:e,config:{childLoggerProvider:t,accessLogger:n=({method:e,path:t},n)=>n.debug(`${e}: ${t}`)}})=>async(r,i,a)=>{let o=await t?.({request:r,parent:e})||e;n?.(r,o),r.res&&(r.res.locals[Jt]={logger:o}),a()},rn=e=>t=>t?.res?.locals[Jt]?.logger||e,an=e=>process.on(`deprecation`,({message:t,namespace:n,name:r,stack:i})=>e.warn(`${r} (${n}): ${t}`,i.split(`
|
|
2
|
+
`).slice(1))),on=({servers:e,logger:t,options:{timeout:n,beforeExit:r,events:i=[`SIGINT`,`SIGTERM`]}})=>{let a=qt(e,{logger:t,timeout:n}),o=async()=>{await a.shutdown(),await r?.(),process.exit()};for(let e of i)process.on(e,o)},sn=e=>{if(e.columns<132)return;let t=f(`Proudly supports transgender community.`.padStart(109)),n=f(`Start your API server with I/O schema validation and custom middlewares in minutes.`.padStart(109)),r=f(`Thank you for choosing Express Zod API for your project.`.padStart(132)),i=f(`for Koko`.padEnd(20)),a=d(`#F5A9B8`),o=d(`#5BCEFA`),s=Array(14).fill(o,1,3).fill(a,3,5).fill(m,5,7).fill(a,7,9).fill(o,9,12).fill(l,12,13),c=`
|
|
3
3
|
8888888888 8888888888P 888 d8888 8888888b. 8888888
|
|
4
4
|
888 d88P 888 d88888 888 Y88b 888
|
|
5
5
|
888 d88P 888 d88P888 888 888 888
|
|
@@ -14,8 +14,8 @@ ${i}888${n}
|
|
|
14
14
|
${r}
|
|
15
15
|
`;e.write(c.split(`
|
|
16
16
|
`).map((e,t)=>s[t]?s[t](e):e).join(`
|
|
17
|
-
`))},rn=e=>{e.startupLogo!==!1&&nn(process.stdout);let t=e.errorHandler||U,n=st(e.logger)?e.logger:new dt(e.logger);n.debug(`Running`,{build:`v28.1.0`,env:process.env.NODE_ENV||`development`}),en(n);let r=Qt({logger:n,config:e}),i={getLogger:$t(n),errorHandler:t},a=Kt(i),o=Gt(i);return{...i,logger:n,notFoundHandler:a,catcher:o,loggingMiddleware:r}},an=(e,t)=>{let{logger:n,getLogger:r,notFoundHandler:i,loggingMiddleware:a}=rn(e);return Lt({app:e.app.use(a),routing:t,getLogger:r,config:e}),{notFoundHandler:i,logger:n}},on=async(e,t)=>{let{logger:n,getLogger:r,notFoundHandler:i,catcher:a,loggingMiddleware:o}=rn(e),s=_().disable(`x-powered-by`).set(`query parser`,e.queryParser??`simple`).use(o);if(e.compression){let t=await q(`compression`);s.use(t(typeof e.compression==`object`?e.compression:void 0))}e.cookies&&s.use(await Jt({config:e})),await e.beforeRouting?.({app:s,getLogger:r}),Lt({app:s,routing:t,getLogger:r,config:e,parsers:{json:[e.jsonParser||_.json()],raw:[e.rawParser||_.raw(),Zt],form:[e.formParser||_.urlencoded()],upload:e.upload?await Xt({config:e,getLogger:r}):[]}}),await e.afterRouting?.({app:s,getLogger:r}),s.use(a,i);let c=[],l=(e,t)=>()=>e.listen(t,()=>n.info(`Listening`,t)),u=[];if(e.http){let t=ee.createServer(s);c.push(t),u.push(l(t,e.http.listen))}if(e.https){let t=te.createServer(e.https.options,s);c.push(t),u.push(l(t,e.https.listen))}return c.length||n.warn(`No servers configured.`),e.gracefulShutdown&&tn({logger:n,servers:c,options:e.gracefulShutdown===!0?{}:e.gracefulShutdown}),{app:s,logger:n,servers:u.map(e=>e())}},sn=e=>E(e)&&`or`in e,cn=e=>E(e)&&`and`in e,ln=e=>!cn(e)&&!sn(e),un=e=>{let t=n.filter(ln,e),r=n.chain(n.prop(`and`),n.filter(cn,e)),[i,a]=n.partition(ln,r),o=n.concat(t,i),s=n.filter(sn,e);return n.map(n.prop(`or`),n.concat(s,a)).reduce((e,t)=>w(e,n.map(e=>ln(e)?[e]:e.and,t),([e,t])=>n.concat(e,t)),n.reject(n.isEmpty,[o]))},dn=(e,t)=>cn(e)?n.chain(e=>dn(e,t),e.and):sn(e)?n.chain(e=>dn(e,t),e.or):e.type===t?[e.name]:[],fn=(e,t)=>new Set(n.chain(e=>dn(e,t),e));let pn;const mn=()=>pn??=new Set(`a-im.accept.accept-additions.accept-charset.accept-datetime.accept-encoding.accept-features.accept-language.accept-signature.access-control.access-control-request-headers.access-control-request-method.alpn.alt-used.amp-cache-transform.apply-to-redirect-ref.authorization.available-dictionary.c-ext.c-man.c-opt.c-pep.c-pep-info.cache-control.cal-managed-id.caldav-timezones.capsule-protocol.cdn-loop.cert-not-after.cert-not-before.client-cert.client-cert-chain.close.cmcd-object.cmcd-request.cmcd-session.cmcd-status.cmsd-dynamic.cmsd-static.concealed-auth-export.configuration-context.connection.content-digest.content-disposition.content-encoding.content-id.content-language.content-length.content-location.content-md5.content-range.content-script-type.content-type.cookie.cookie2.cta-common-access-token.dasl.date.dav.default-style.delta-base.deprecation.depth.derived-from.destination.detached-jws.dictionary-id.differential-id.digest.dpop.early-data.ediint-features.expect.expect-ct.ext.forwarded.from.getprofile.hobareg.host.http2-settings.if.if-match.if-modified-since.if-none-match.if-range.if-schedule-tag-match.if-unmodified-since.im.include-referred-token-binding-id.incremental.isolation.keep-alive.label.last-event-id.link.link-template.lock-token.man.max-forwards.memento-datetime.meter.method-check.method-check-expires.mime-version.negotiate.odata-entityid.odata-isolation.odata-maxversion.odata-version.opt.ordering-type.origin.origin-agent-cluster.oscore.oslc-core-version.overwrite.pep.pep-info.permissions-policy.pics-label.ping-from.ping-to.position.pragma.prefer.preference-applied.priority.profileobject.protocol.protocol-info.protocol-query.protocol-request.proxy-authorization.proxy-features.proxy-instruction.range.redirect-ref.referer.referer-root.referrer-policy.repeatability-client-id.repeatability-first-sent.repeatability-request-id.repeatability-result.replay-nonce.reporting-endpoints.repr-digest.safe.schedule-reply.schedule-tag.sec-fetch-storage-access.sec-gpc.sec-purpose.sec-token-binding.sec-websocket-extensions.sec-websocket-key.sec-websocket-protocol.sec-websocket-version.security-scheme.signature.signature-input.slug.soapaction.status-uri.sunset.surrogate-capability.tcn.te.timeout.topic.traceparent.tracestate.trailer.transfer-encoding.ttl.upgrade.urgency.uri.user-agent.variant-vary.via.want-content-digest.want-digest.want-repr-digest.warning.x-content-type-options.x-frame-options`.split(`.`)),hn=`https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString`,gn={integer:0,number:0,string:``,boolean:!1,object:{},null:null,array:[]},_n=e=>e.replace(de,e=>`{${e.slice(1)}}`),vn=({},e)=>{if(e.isResponse)throw new P(`Please use ez.upload() only for input.`,e);return{type:`string`,format:`binary`}},yn=({jsonSchema:e})=>({...e,externalDocs:{description:`raw binary data`,url:`https://swagger.io/specification/#working-with-binary-data`}}),bn=({zodSchema:e,jsonSchema:t})=>{if(!C(e,`union`)||!(`discriminator`in e._zod.def))return t;let n=e._zod.def.discriminator;return{...t,discriminator:t.discriminator??{propertyName:n}}},xn=n.tryCatch(({jsonSchema:e})=>{if(!e.allOf)throw`no allOf`;return J(e,`throw`)},(e,{jsonSchema:t})=>t),Sn=({jsonSchema:e})=>{if(!e.anyOf)return e;let t=e.anyOf[0];return Object.assign(t,{type:On(t.type)})},Y=e=>e,Cn=({jsonSchema:{examples:e,description:t}},n)=>{if(n.isResponse)throw new P(`Please use ez.dateOut() for output.`,n);let r={description:t||`YYYY-MM-DDTHH:mm:ss.sssZ`,type:`string`,format:`date-time`,pattern:`^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?)?Z?$`,externalDocs:{url:hn}};return e?.length&&(r.examples=e),r},wn=({jsonSchema:{examples:e,description:t}},n)=>{if(!n.isResponse)throw new P(`Please use ez.dateIn() for input.`,n);let r={description:t||`YYYY-MM-DDTHH:mm:ss.sssZ`,type:`string`,format:`date-time`,externalDocs:{url:hn}};return e?.length&&(r.examples=e),r},Tn=()=>({type:`string`,format:`bigint`,pattern:`^-?\\d+$`}),En=({zodSchema:e,jsonSchema:t})=>e._zod.def.rest===null?{...t,items:{not:{}}}:t,Dn=e=>{let t=Array.isArray(e.type)?e.type[0]:e.type;return gn?.[t]},On=e=>e===`null`?e:typeof e==`string`?[e,`null`]:e&&[...new Set(e).add(`null`)],kn=({zodSchema:e,jsonSchema:t},n)=>{let r=e._zod.def[n.isResponse?`out`:`in`],i=e._zod.def[n.isResponse?`in`:`out`];if(!C(r,`transform`))return t;let a=Y(Fn(i,{ctx:n}));if(v(a))if(n.isResponse){let e=be(r,Dn(a));if(e&&[`number`,`string`,`boolean`].includes(e))return{...t,type:e}}else{let{type:e,...t}=a;return{...t,format:`${t.format||e} (preprocessed)`}}return t},An=({jsonSchema:e})=>{if(e.type!==`object`)return e;let t=e;return!t.properties||!(`raw`in t.properties)||!E(t.properties.raw)?e:t.properties.raw},jn=e=>e.length?n.fromPairs(n.zip(n.times(e=>`example${e+1}`,e.length),n.map(n.objOf(`value`),e))):void 0,Mn=(e,t)=>t?.has(e)||e.startsWith(`x-`)||mn().has(e),Nn=({path:e,method:t,request:r,inputSources:i,makeRef:a,composition:o,isHeader:s,securityHeaders:c,securityCookies:l,description:u=`${t.toUpperCase()} ${e} Parameter`})=>{let d=J(r),f=fe(e),p=i.includes(`query`),m=i.includes(`params`),h=i.includes(`headers`),g=i.includes(`cookies`)||i.includes(`signedCookies`),_=n=>{if(m&&f.includes(n))return`path`;if(g&&l?.has(n))return`cookie`;if(h&&(s?.(n,t,e)??Mn(n,c)))return`header`;if(p)return`query`};return Object.entries(d.properties).reduce((e,[t,r])=>{if(!E(r))return e;let i=_(t);if(!i)return e;let s=Y(r),c=o===`components`?a(r.id||JSON.stringify(r),s,r.id||T(u,t)):s;return e.concat({name:t,in:i,deprecated:r.deprecated,required:d.required?.includes(t)||!1,description:s.description||u,schema:c,examples:jn(v(s)&&s.examples?.length?s.examples:n.pluck(t,d.examples?.filter(n.both(E,n.has(t)))||[]))})},[])},X={nullable:Sn,union:bn,bigint:Tn,intersection:xn,tuple:En,pipe:kn,[j]:Cn,[M]:wn,[I]:vn,[L]:An,[A]:yn},Pn=(e,t,r)=>{let i=[e,t],a=e=>/schema\d+$/.test(e)?void 0:e;for(let e=0;e<i.length;e++){let o=i[e];if(n.is(Object,o)){if(ie(o)&&!o.$ref.startsWith(`#/components`)){let e=o.$ref.split(`/`).pop(),n=t[e];n&&(o.$ref=r.makeRef(n.id||n,Y(n),n.id||a(e)).$ref);continue}i.push(...n.values(o))}n.is(Array,o)&&i.push(...n.values(o))}return e},Fn=(e,{ctx:n,rules:r=X})=>{let{$defs:i={},properties:a={}}=t.toJSONSchema(t.object({subject:e}),{unrepresentable:`any`,io:n.isResponse?`output`:`input`,override:e=>{let t=O(e.zodSchema),i=r[t&&t in r?t:e.zodSchema._zod.def.type];if(i){let t={...i(e,n)};for(let t in e.jsonSchema)delete e.jsonSchema[t];Object.assign(e.jsonSchema,t)}}});return Pn(E(a.subject)?a.subject:{},i,n)},In=(e,t)=>{if(ie(e))return[e,!1];let r=!1,i=n.map(e=>{let[n,i]=In(e,t);return r||=i,n}),a=n.omit(t),o={properties:a,examples:n.map(a),required:n.without(t),allOf:i,oneOf:i,anyOf:i},s=n.evolve(o,e);return[s,r||!!s.required?.length]},Ln=({method:e,path:t,schema:r,mimeTypes:i,variant:a,makeRef:o,composition:s,hasMultipleStatusCodes:c,statusCode:l,brandHandling:u,description:d=`${e.toUpperCase()} ${t} ${ye(a)} response ${c?l:``}`.trim()})=>{if(!Se(e,i))return{description:d};let f=Y(Fn(r,{rules:{...u,...X},ctx:{isResponse:!0,makeRef:o,path:t,method:e}})),p=[];v(f)&&f.examples&&(p.push(...f.examples),delete f.examples);let m={schema:s===`components`?o(r,f,T(d)):f,examples:jn(p)};return{description:d,content:n.fromPairs(n.xprod(i,[m]))}},Rn=({format:e})=>{let t={type:`http`,scheme:`bearer`};return e&&(t.bearerFormat=e),t},zn=({name:e},t)=>{let n={type:`apiKey`,in:`query`,name:e};return t?.includes(`body`)&&(t?.includes(`query`)?(n[`x-in-alternative`]=`body`,n.description=`${e} CAN also be supplied within the request body`):(n[`x-in-actual`]=`body`,n.description=`${e} MUST be supplied within the request body instead of query`)),n},Bn=({name:e})=>({type:`apiKey`,in:`header`,name:e}),Vn=({name:e})=>({type:`apiKey`,in:`cookie`,name:e}),Hn=({url:e})=>({type:`openIdConnect`,openIdConnectUrl:e}),Un=({flows:e={}})=>({type:`oauth2`,flows:n.map(e=>({...e,scopes:e.scopes||{}}),n.reject(n.isNil,e))}),Wn=(e,t=[])=>{let n=e=>e.type===`basic`?{type:`http`,scheme:`basic`}:e.type===`bearer`?Rn(e):e.type===`input`?zn(e,t):e.type===`header`?Bn(e):e.type===`cookie`?Vn(e):e.type===`openid`?Hn(e):Un(e);return e.map(e=>e.map(n))},Gn=(e,t,n)=>e.map(e=>e.reduce((e,r)=>{let i=n(r),a=[`oauth2`,`openIdConnect`].includes(r.type);return Object.assign(e,{[i]:a?t:[]})},{})),Kn=({schema:e,brandHandling:t,makeRef:n,path:r,method:i})=>Fn(e,{rules:{...t,...X},ctx:{isResponse:!1,makeRef:n,path:r,method:i}}),qn=({method:e,path:t,schema:r,request:i,mimeType:a,makeRef:o,composition:s,paramNames:c,description:l=`${e.toUpperCase()} ${t} Request body`})=>{let[u,d]=In(Y(i),c),f=[];v(u)&&u.examples&&(f.push(...u.examples),delete u.examples);let p={schema:s===`components`?o(r,u,T(l)):u,examples:jn(f.length?f:J(i).examples?.filter(e=>E(e)&&!Array.isArray(e)).map(n.omit(c))||[])},m={description:l,content:{[a]:p}};return(d||a===y.raw)&&(m.required=!0),m},Jn=e=>Object.entries(e).reduce((e,[t,n])=>{if(!n)return e;let r={name:t,description:typeof n==`string`?n:n.description};return typeof n==`object`&&n.url&&(r.externalDocs={url:n.url}),e.concat(r)},[]),Yn=(e,t=50)=>!e||e.length<=t?e:e.slice(0,Math.max(1,t||0)-1)+`…`,Xn=e=>e.length?e.slice():void 0,Zn=({description:e,summary:t=e,trim:n})=>n(t);var Qn=class extends re{#e=new Map;#t=new Map;#n=new Map;#r(e,t,n){let r=this.#n.get(e);if(!r){let t=+!n;do r=`${n??`Schema`}${t?this.#n.size+t:``}`,t++;while(this.rootDoc.components?.schemas?.[r]);this.#n.set(e,r)}return this.addSchema(r,t),{$ref:`#/components/schemas/${r}`}}#i(e,t,n){let r=n||T(t,e),i=this.#t.get(r);if(i===void 0)return this.#t.set(r,1),r;if(n)throw new P(`Duplicated operationId: "${n}"`,{method:t,isResponse:!1,path:e});return i++,this.#t.set(r,i),`${r}${i}`}#a(e){let t=JSON.stringify(e);for(let e in this.rootDoc.components?.securitySchemes||{})if(t===JSON.stringify(this.rootDoc.components?.securitySchemes?.[e]))return e;let n=(this.#e.get(e.type)||0)+1;return this.#e.set(e.type,n),`${e.type.toUpperCase()}_${n}`}constructor({routing:e,config:t,title:r,version:i,serverUrl:a,descriptions:o,brandHandling:s,tags:c,isHeader:l,hasHeadMethod:u=!0,summarizer:d=Zn,composition:f=`inline`}){super(),this.addInfo({title:r,version:i});for(let e of typeof a==`string`?[a]:a)this.addServer({url:e});let p=(e,r,i)=>{let a={path:r,method:e,endpoint:i,composition:f,brandHandling:s,makeRef:this.#r.bind(this)},{description:c,summary:u,scopes:p,inputSchema:m}=i,h=_e(e,t.inputSources),g=this.#i(r,e,i.getOperationId(e)),_=Kn({...a,schema:m}),ee=Nn({...a,inputSources:h,isHeader:l,securityHeaders:fn(i.security,`header`),securityCookies:fn(i.security,`cookie`),request:_,description:o?.requestParameter?.({method:e,path:r,operationId:g})}),te={};for(let t of $e){let n=i.getResponses(t);for(let{mimeTypes:i,schema:s,statusCodes:c}of n)for(let l of c)te[l]=Ln({...a,variant:t,schema:s,mimeTypes:i,statusCode:l,hasMultipleStatusCodes:n.length>1||c.length>1,description:o?.[`${t}Response`]?.({method:e,path:r,operationId:g,statusCode:l})})}let ne=h.includes(`body`)?qn({...a,request:_,paramNames:n.pluck(`name`,ee),schema:m,mimeType:y[i.requestType],description:o?.requestBody?.({method:e,path:r,operationId:g})}):void 0,re=Gn(Wn(un(i.security),h),p,e=>{let t=this.#a(e);return this.addSecurityScheme(t,e),t}),ie={operationId:g,summary:d({summary:u,description:c,trim:Yn}),description:c,deprecated:i.isDeprecated||void 0,tags:Xn(i.tags),parameters:Xn(ee),requestBody:ne,security:Xn(re),responses:te};this.addPath(_n(r),{[e]:ie})};Mt({routing:e,config:t,onEndpoint:u?Tt(p):p}),c&&(this.rootDoc.tags=Jn(c))}};const $n=e=>ae({...e,headers:{"content-type":y.json,...e?.headers}}),er=e=>oe(e),tr=e=>{let t={warn:[],error:[],info:[],debug:[]};return new Proxy(e||{},{get(e,n,r){return n===`_getLogs`?()=>t:ct(n)?(...e)=>t[n].push(e):Reflect.get(e,n,r)}})},nr=({requestProps:e,responseOptions:t,configProps:n,loggerProps:r})=>{let i=$n(e),a=er({req:i,...t});a.req=t?.req||i,i.res=a;let o=tr(r);return{requestMock:i,responseMock:a,loggerMock:o,configMock:{cors:!1,logger:o,...n}}},rr=async({endpoint:e,...t})=>{let{requestMock:n,responseMock:r,loggerMock:i,configMock:a}=nr(t);return await e.execute({request:n,response:r,config:a,logger:i}),{requestMock:n,responseMock:r,loggerMock:i}},ir=async({middleware:e,ctx:t={},...n})=>{let{requestMock:r,responseMock:i,loggerMock:a,configMock:{inputSources:o,errorHandler:s=U}}=nr(n),c={request:r,response:i,logger:a,input:ve(r,o),ctx:t};try{return{requestMock:r,responseMock:i,loggerMock:a,output:await e.execute(c)}}catch(e){return await s.execute({...c,error:x(e),output:null}),{requestMock:r,responseMock:i,loggerMock:a,output:{}}}};var ar=class e{ts;f;exportModifier;asyncModifier;accessModifiers;#e;static#t=/^[A-Za-z_$][A-Za-z0-9_$]*$/;constructor(e){this.ts=e,this.f=this.ts.factory,this.exportModifier=[this.f.createModifier(this.ts.SyntaxKind.ExportKeyword)],this.asyncModifier=[this.f.createModifier(this.ts.SyntaxKind.AsyncKeyword)],this.accessModifiers={public:[this.f.createModifier(this.ts.SyntaxKind.PublicKeyword)],publicStatic:[this.f.createModifier(this.ts.SyntaxKind.PublicKeyword),this.f.createModifier(this.ts.SyntaxKind.StaticKeyword)],protectedReadonly:[this.f.createModifier(this.ts.SyntaxKind.ProtectedKeyword),this.f.createModifier(this.ts.SyntaxKind.ReadonlyKeyword)]},this.#e=[this.ts.SyntaxKind.AnyKeyword,this.ts.SyntaxKind.BigIntKeyword,this.ts.SyntaxKind.BooleanKeyword,this.ts.SyntaxKind.NeverKeyword,this.ts.SyntaxKind.NumberKeyword,this.ts.SyntaxKind.ObjectKeyword,this.ts.SyntaxKind.StringKeyword,this.ts.SyntaxKind.SymbolKeyword,this.ts.SyntaxKind.UndefinedKeyword,this.ts.SyntaxKind.UnknownKeyword,this.ts.SyntaxKind.VoidKeyword]}addJsDoc=(e,t)=>this.ts.addSyntheticLeadingComment(e,this.ts.SyntaxKind.MultiLineCommentTrivia,`* ${t} `,!0);printNode=(e,t)=>{let n=this.ts.createSourceFile(`print.ts`,``,this.ts.ScriptTarget.Latest,!1,this.ts.ScriptKind.TS);return this.ts.createPrinter(t).printNode(this.ts.EmitHint.Unspecified,e,n)};makeId=e=>this.f.createIdentifier(e);makePropertyIdentifier=t=>typeof t==`string`&&e.#t.test(t)?this.makeId(t):this.literally(t);makeTemplate=(e,...t)=>this.f.createTemplateExpression(this.f.createTemplateHead(e),t.map(([e,n=``],r)=>this.f.createTemplateSpan(typeof e==`string`?this.makeId(e):e,r===t.length-1?this.f.createTemplateTail(n):this.f.createTemplateMiddle(n))));makeParam=(e,{type:t,mod:n,initId:r,optional:i}={})=>this.f.createParameterDeclaration(n,void 0,e,i?this.f.createToken(this.ts.SyntaxKind.QuestionToken):void 0,t?this.ensureTypeNode(t):void 0,r?this.makeId(r):void 0);makeParams=e=>Object.entries(e).map(([e,t])=>this.makeParam(e,typeof t==`string`||typeof t==`number`||typeof t==`object`&&`kind`in t?{type:t}:t));makePublicConstructor=(e,t=[])=>this.f.createConstructorDeclaration(this.accessModifiers.public,e,this.f.createBlock(t));ensureTypeNode=(e,t)=>typeof e==`number`?this.f.createKeywordTypeNode(e):typeof e==`string`||this.ts.isIdentifier(e)?this.f.createTypeReferenceNode(e,t&&n.map(this.ensureTypeNode,t)):e;makeRecordStringAny=()=>this.ensureTypeNode(`Record`,[this.ts.SyntaxKind.StringKeyword,this.ts.SyntaxKind.AnyKeyword]);makeUnion=e=>{let t=new Map;for(let n of e)t.set(this.isPrimitive(n)?n.kind:n,n);return this.f.createUnionTypeNode(Array.from(t.values()))};makeInterfaceProp=(e,t,{isOptional:r,hasUndefined:i=r,isDeprecated:a,comment:o}={})=>{let s=this.ensureTypeNode(t),c=this.f.createPropertySignature(void 0,this.makePropertyIdentifier(e),r?this.f.createToken(this.ts.SyntaxKind.QuestionToken):void 0,i?this.makeUnion([s,this.ensureTypeNode(this.ts.SyntaxKind.UndefinedKeyword)]):s),l=n.reject(n.isNil,[a?`@deprecated`:void 0,o]);return l.length?this.addJsDoc(c,l.join(` `)):c};makeOneLine=e=>this.ts.setEmitFlags(e,this.ts.EmitFlags.SingleLine);makeDeconstruction=(...e)=>this.f.createArrayBindingPattern(e.map(e=>this.f.createBindingElement(void 0,void 0,e)));makeConst=(e,t,{type:n,expose:r}={})=>this.f.createVariableStatement(r&&this.exportModifier,this.f.createVariableDeclarationList([this.f.createVariableDeclaration(e,void 0,n?this.ensureTypeNode(n):void 0,t)],this.ts.NodeFlags.Const));makePublicLiteralType=(e,t)=>this.makeType(e,this.makeUnion(n.map(this.makeLiteralType,t)),{expose:!0});makeType=(e,t,{expose:n,comment:r,params:i}={})=>{let a=this.f.createTypeAliasDeclaration(n?this.exportModifier:void 0,e,i&&this.makeTypeParams(i),t);return r?this.addJsDoc(a,r):a};makePublicProperty=(e,t)=>this.f.createPropertyDeclaration(this.accessModifiers.public,e,void 0,this.ensureTypeNode(t),void 0);makePublicMethod=(e,t,n,{typeParams:r,returns:i,isStatic:a}={})=>this.f.createMethodDeclaration(a?this.accessModifiers.publicStatic:this.accessModifiers.public,void 0,e,void 0,r&&this.makeTypeParams(r),t,i,this.f.createBlock(n));makePublicClass=(e,t,{typeParams:n}={})=>this.f.createClassDeclaration(this.exportModifier,e,n&&this.makeTypeParams(n),void 0,t);makeKeyOf=e=>this.f.createTypeOperatorNode(this.ts.SyntaxKind.KeyOfKeyword,this.ensureTypeNode(e));makePromise=e=>this.ensureTypeNode(Promise.name,[e]);makeInterface=(e,t,{expose:n,comment:r}={})=>{let i=this.f.createInterfaceDeclaration(n?this.exportModifier:void 0,e,void 0,void 0,t);return r?this.addJsDoc(i,r):i};makeTypeParams=e=>(Array.isArray(e)?e.map(e=>n.pair(e,void 0)):Object.entries(e)).map(([e,t])=>{let{type:n,init:r}=typeof t==`object`&&`init`in t?t:{type:t};return this.f.createTypeParameterDeclaration([],e,n?this.ensureTypeNode(n):void 0,r?this.ensureTypeNode(r):void 0)});makeArrowFn=(e,t,{isAsync:r}={})=>this.f.createArrowFunction(r?this.asyncModifier:void 0,void 0,Array.isArray(e)?n.map(this.makeParam,e):this.makeParams(e),void 0,void 0,t);makeTernary=(...e)=>{let[t,n,r]=e.map(e=>typeof e==`string`?this.makeId(e):e);return this.f.createConditionalExpression(t,this.f.createToken(this.ts.SyntaxKind.QuestionToken),n,this.f.createToken(this.ts.SyntaxKind.ColonToken),r)};makeCall=(e,...t)=>(...n)=>this.f.createCallExpression(t.reduce((e,t)=>typeof t==`string`||this.ts.isIdentifier(t)?this.f.createPropertyAccessExpression(e,t):this.f.createElementAccessExpression(e,t),typeof e==`string`?this.makeId(e):e),void 0,n.map(e=>typeof e==`string`?this.makeId(e):e));makeNew=(e,...t)=>this.f.createNewExpression(this.makeId(e),void 0,t);makeExtract=(e,t)=>this.ensureTypeNode(`Extract`,[e,t]);makeAssignment=(e,t)=>this.f.createExpressionStatement(this.f.createBinaryExpression(typeof e==`string`?this.makeId(e):e,this.f.createToken(this.ts.SyntaxKind.EqualsToken),t));makeIndexed=(e,t)=>this.f.createIndexedAccessTypeNode(this.ensureTypeNode(e),this.ensureTypeNode(t));makeMaybeAsync=e=>this.makeUnion([this.ensureTypeNode(e),this.makePromise(e)]);makeFnType=(e,t)=>this.f.createFunctionTypeNode(void 0,this.makeParams(e),this.ensureTypeNode(t));literally=e=>typeof e==`number`?this.f.createNumericLiteral(e):typeof e==`bigint`?this.f.createBigIntLiteral(e.toString()):typeof e==`boolean`?e?this.f.createTrue():this.f.createFalse():e===null?this.f.createNull():this.f.createStringLiteral(e);makeLiteralType=e=>this.f.createLiteralTypeNode(this.literally(e));isPrimitive=e=>this.#e.includes(e.kind)};const Z=e=>e;var or=class{serverUrl;api;paths=new Set;tags=new Map;registry=new Map;constructor(e,t){this.serverUrl=t,this.api=new ar(e)}#e={pathType:`Path`,implementationType:`Implementation`,keyParameter:`key`,pathParameter:`path`,paramsArgument:`params`,ctxArgument:`ctx`,methodParameter:`method`,requestParameter:`request`,eventParameter:`event`,dataParameter:`data`,handlerParameter:`handler`,msgParameter:`msg`,parseRequestFn:`parseRequest`,substituteFn:`substitute`,provideMethod:`provide`,onMethod:`on`,implementationArgument:`implementation`,hasBodyConst:`hasBody`,undefinedValue:`undefined`,responseConst:`response`,restConst:`rest`,searchParamsConst:`searchParams`,defaultImplementationConst:`defaultImplementation`,clientConst:`client`,contentTypeConst:`contentType`,isJsonConst:`isJSON`,sourceProp:`source`,methodType:`Method`,someOfType:`SomeOf`,requestType:`Request`,paginationType:`Pagination`};interfaces={input:`Input`,positive:`PositiveResponse`,negative:`NegativeResponse`,encoded:`EncodedResponse`,response:`Response`};makeMethodType=()=>this.api.makePublicLiteralType(this.#e.methodType,le);makeSomeOfType=()=>this.api.makeType(this.#e.someOfType,this.api.makeIndexed(`T`,this.api.makeKeyOf(`T`)),{params:[`T`]});makeRequestType=()=>this.api.makeType(this.#e.requestType,this.api.makeKeyOf(this.interfaces.input),{expose:!0});someOf=({name:e})=>this.api.ensureTypeNode(this.#e.someOfType,[e]);makePathType=()=>this.api.makePublicLiteralType(this.#e.pathType,Array.from(this.paths));makePublicInterfaces=()=>Object.keys(this.interfaces).map(e=>this.api.makeInterface(this.interfaces[e],Array.from(this.registry).map(([t,{store:n,isDeprecated:r}])=>this.api.makeInterfaceProp(t,n[e],{isDeprecated:r})),{expose:!0}));makeEndpointTags=()=>this.api.makeConst(`endpointTags`,this.api.f.createObjectLiteralExpression(Array.from(this.tags).map(([e,t])=>this.api.f.createPropertyAssignment(this.api.makePropertyIdentifier(e),this.api.f.createArrayLiteralExpression(n.map(this.api.literally,t))))),{expose:!0});makeImplementationType=()=>this.api.makeType(this.#e.implementationType,this.api.makeFnType({[this.#e.methodParameter]:this.#e.methodType,[this.#e.pathParameter]:this.api.ts.SyntaxKind.StringKeyword,[this.#e.paramsArgument]:this.api.makeRecordStringAny(),[this.#e.ctxArgument]:{optional:!0,type:`T`}},this.api.makePromise(this.api.ts.SyntaxKind.AnyKeyword)),{expose:!0,params:{T:{init:this.api.ts.SyntaxKind.UnknownKeyword}}});makeParseRequestFn=()=>this.api.makeConst(this.#e.parseRequestFn,this.api.makeArrowFn({[this.#e.requestParameter]:this.api.ts.SyntaxKind.StringKeyword},this.api.f.createAsExpression(this.api.makeCall(this.#e.requestParameter,Z(`split`))(this.api.f.createRegularExpressionLiteral(`/ (.+)/`),this.api.literally(2)),this.api.f.createTupleTypeNode([this.api.ensureTypeNode(this.#e.methodType),this.api.ensureTypeNode(this.#e.pathType)]))));makeSubstituteFn=()=>this.api.makeConst(this.#e.substituteFn,this.api.makeArrowFn({[this.#e.pathParameter]:this.api.ts.SyntaxKind.StringKeyword,[this.#e.paramsArgument]:this.api.makeRecordStringAny()},this.api.f.createBlock([this.api.makeConst(this.#e.restConst,this.api.f.createObjectLiteralExpression([this.api.f.createSpreadAssignment(this.api.makeId(this.#e.paramsArgument))])),this.api.f.createForInStatement(this.api.f.createVariableDeclarationList([this.api.f.createVariableDeclaration(this.#e.keyParameter)],this.api.ts.NodeFlags.Const),this.api.makeId(this.#e.paramsArgument),this.api.f.createBlock([this.api.makeAssignment(this.#e.pathParameter,this.api.makeCall(this.#e.pathParameter,Z(`replace`))(this.api.makeTemplate(`:`,[this.#e.keyParameter]),this.api.makeArrowFn([],this.api.f.createBlock([this.api.f.createExpressionStatement(this.api.f.createDeleteExpression(this.api.f.createElementAccessExpression(this.api.makeId(this.#e.restConst),this.api.makeId(this.#e.keyParameter)))),this.api.f.createReturnStatement(this.api.f.createElementAccessExpression(this.api.makeId(this.#e.paramsArgument),this.api.makeId(this.#e.keyParameter)))]))))])),this.api.f.createReturnStatement(this.api.f.createAsExpression(this.api.f.createArrayLiteralExpression([this.api.makeId(this.#e.pathParameter),this.api.makeId(this.#e.restConst)]),this.api.ensureTypeNode(`const`)))])));makePaginationType=()=>{let e=Z(`nextCursor`),t=Z(`total`),n=Z(`limit`),r=Z(`offset`),i=this.api.f.createTypeLiteralNode([this.api.makeInterfaceProp(e,this.api.makeUnion([this.api.ensureTypeNode(this.api.ts.SyntaxKind.StringKeyword),this.api.makeLiteralType(null)]))]),a=this.api.f.createTypeLiteralNode([t,n,r].map(e=>this.api.makeInterfaceProp(e,this.api.ts.SyntaxKind.NumberKeyword)));return this.api.makeType(this.#e.paginationType,this.api.makeUnion([i,a]))};#t=()=>{let e=this.api.makeId(this.#e.responseConst),t=Z(`nextCursor`),n=Z(`total`),r=Z(`limit`),i=Z(`offset`),a=this.api.f.createBinaryExpression(this.api.literally(t),this.api.ts.SyntaxKind.InKeyword,e),o=this.api.f.createReturnStatement(this.api.f.createBinaryExpression(this.api.f.createPropertyAccessExpression(e,t),this.api.ts.SyntaxKind.ExclamationEqualsEqualsToken,this.api.literally(null))),s=this.api.f.createBinaryExpression(this.api.f.createPropertyAccessExpression(e,i),this.api.ts.SyntaxKind.PlusToken,this.api.f.createPropertyAccessExpression(e,r)),c=this.api.f.createReturnStatement(this.api.f.createBinaryExpression(s,this.api.ts.SyntaxKind.LessThanToken,this.api.f.createPropertyAccessExpression(e,n)));return this.api.makePublicMethod(`hasMore`,[this.api.makeParam(e,{type:this.#e.paginationType})],[this.api.f.createIfStatement(a,o),c],{returns:this.api.ensureTypeNode(this.api.ts.SyntaxKind.BooleanKeyword),isStatic:!0})};#n=()=>this.api.makePublicMethod(this.#e.provideMethod,this.api.makeParams({[this.#e.requestParameter]:`K`,[this.#e.paramsArgument]:this.api.makeIndexed(this.interfaces.input,`K`),[this.#e.ctxArgument]:{optional:!0,type:`T`}}),[this.api.makeConst(this.api.makeDeconstruction(this.#e.methodParameter,this.#e.pathParameter),this.api.makeCall(this.#e.parseRequestFn)(this.#e.requestParameter)),this.api.f.createReturnStatement(this.api.makeCall(this.api.f.createThis(),this.#e.implementationArgument)(this.#e.methodParameter,this.api.f.createSpreadElement(this.api.makeCall(this.#e.substituteFn)(this.#e.pathParameter,this.#e.paramsArgument)),this.#e.ctxArgument))],{typeParams:{K:this.#e.requestType},returns:this.api.makePromise(this.api.makeIndexed(this.interfaces.response,`K`))});makeClientClass=e=>this.api.makePublicClass(e,[this.api.makePublicConstructor([this.api.makeParam(this.#e.implementationArgument,{type:this.api.ensureTypeNode(this.#e.implementationType,[`T`]),mod:this.api.accessModifiers.protectedReadonly,initId:this.#e.defaultImplementationConst})]),this.#n(),this.#t()],{typeParams:[`T`]});#r=e=>this.api.makeTemplate(`?`,[this.api.makeNew(URLSearchParams.name,this.api.makeId(e))]);#i=()=>this.api.makeNew(URL.name,this.api.makeTemplate(``,[this.#e.pathParameter],[this.#e.searchParamsConst]),this.api.literally(this.serverUrl));makeDefaultImplementation=()=>{let e=this.api.f.createPropertyAssignment(Z(`method`),this.api.makeCall(this.#e.methodParameter,Z(`toUpperCase`))()),t=this.api.f.createPropertyAssignment(Z(`headers`),this.api.makeTernary(this.#e.hasBodyConst,this.api.f.createObjectLiteralExpression([this.api.f.createPropertyAssignment(this.api.literally(`Content-Type`),this.api.literally(y.json))]),this.#e.undefinedValue)),n=this.api.f.createPropertyAssignment(Z(`body`),this.api.makeTernary(this.#e.hasBodyConst,this.api.makeCall(JSON[Symbol.toStringTag],Z(`stringify`))(this.#e.paramsArgument),this.#e.undefinedValue)),r=this.api.makeConst(this.#e.responseConst,this.api.f.createAwaitExpression(this.api.makeCall(fetch.name)(this.#i(),this.api.f.createObjectLiteralExpression([e,t,n])))),i=this.api.makeConst(this.#e.hasBodyConst,this.api.f.createLogicalNot(this.api.makeCall(this.api.f.createArrayLiteralExpression([this.api.literally(`get`),this.api.literally(`head`),this.api.literally(`delete`)]),Z(`includes`))(this.#e.methodParameter))),a=this.api.makeConst(this.#e.searchParamsConst,this.api.makeTernary(this.#e.hasBodyConst,this.api.literally(``),this.#r(this.#e.paramsArgument))),o=this.api.makeConst(this.#e.contentTypeConst,this.api.makeCall(this.#e.responseConst,Z(`headers`),Z(`get`))(this.api.literally(`content-type`))),s=this.api.f.createIfStatement(this.api.f.createPrefixUnaryExpression(this.api.ts.SyntaxKind.ExclamationToken,this.api.makeId(this.#e.contentTypeConst)),this.api.f.createReturnStatement()),c=this.api.makeConst(this.#e.isJsonConst,this.api.makeCall(this.#e.contentTypeConst,Z(`startsWith`))(this.api.literally(y.json))),l=this.api.f.createReturnStatement(this.api.makeCall(this.#e.responseConst,this.api.makeTernary(this.#e.isJsonConst,this.api.literally(Z(`json`)),this.api.literally(Z(`text`))))());return this.api.makeConst(this.#e.defaultImplementationConst,this.api.makeArrowFn([this.#e.methodParameter,this.#e.pathParameter,this.#e.paramsArgument],this.api.f.createBlock([i,a,r,o,s,c,l]),{isAsync:!0}),{type:this.#e.implementationType})};#a=()=>this.api.makePublicConstructor(this.api.makeParams({request:`K`,params:this.api.makeIndexed(this.interfaces.input,`K`)}),[this.api.makeConst(this.api.makeDeconstruction(this.#e.pathParameter,this.#e.restConst),this.api.makeCall(this.#e.substituteFn)(this.api.f.createElementAccessExpression(this.api.makeCall(this.#e.parseRequestFn)(this.#e.requestParameter),this.api.literally(1)),this.#e.paramsArgument)),this.api.makeConst(this.#e.searchParamsConst,this.#r(this.#e.restConst)),this.api.makeAssignment(this.api.f.createPropertyAccessExpression(this.api.f.createThis(),this.#e.sourceProp),this.api.makeNew(`EventSource`,this.#i()))]);#o=e=>this.api.f.createTypeLiteralNode([this.api.makeInterfaceProp(Z(`event`),e)]);#s=()=>this.api.makePublicMethod(this.#e.onMethod,this.api.makeParams({[this.#e.eventParameter]:`E`,[this.#e.handlerParameter]:this.api.makeFnType({[this.#e.dataParameter]:this.api.makeIndexed(this.api.makeExtract(`R`,this.api.makeOneLine(this.#o(`E`))),this.api.makeLiteralType(Z(`data`)))},this.api.makeMaybeAsync(this.api.ts.SyntaxKind.VoidKeyword))}),[this.api.f.createExpressionStatement(this.api.makeCall(this.api.f.createThis(),this.#e.sourceProp,Z(`addEventListener`))(this.#e.eventParameter,this.api.makeArrowFn([this.#e.msgParameter],this.api.makeCall(this.#e.handlerParameter)(this.api.makeCall(JSON[Symbol.toStringTag],Z(`parse`))(this.api.f.createPropertyAccessExpression(this.api.f.createParenthesizedExpression(this.api.f.createAsExpression(this.api.makeId(this.#e.msgParameter),this.api.ensureTypeNode(MessageEvent.name))),Z(`data`))))))),this.api.f.createReturnStatement(this.api.f.createThis())],{typeParams:{E:this.api.makeIndexed(`R`,this.api.makeLiteralType(Z(`event`)))}});makeSubscriptionClass=e=>this.api.makePublicClass(e,[this.api.makePublicProperty(this.#e.sourceProp,`EventSource`),this.#a(),this.#s()],{typeParams:{K:this.api.makeExtract(this.#e.requestType,this.api.f.createTemplateLiteralType(this.api.f.createTemplateHead(`get `),[this.api.f.createTemplateLiteralTypeSpan(this.api.ensureTypeNode(this.api.ts.SyntaxKind.StringKeyword),this.api.f.createTemplateTail(``))])),R:this.api.makeExtract(this.api.makeIndexed(this.interfaces.positive,`K`),this.api.makeOneLine(this.#o(this.api.ts.SyntaxKind.StringKeyword)))}});makeUsageStatements=(e,t)=>[this.api.makeConst(this.#e.clientConst,this.api.makeNew(e)),this.api.makeCall(this.#e.clientConst,this.#e.provideMethod)(this.api.literally(`get /v1/user/retrieve`),this.api.f.createObjectLiteralExpression([this.api.f.createPropertyAssignment(`id`,this.api.literally(`10`))])),this.api.makeCall(this.api.makeNew(t,this.api.literally(`get /v1/events/stream`),this.api.f.createObjectLiteralExpression()),this.#e.onMethod)(this.api.literally(`time`),this.api.makeArrowFn([`time`],this.api.f.createBlock([])))]};const sr=(e,{rules:t,onMissing:n,ctx:r={}})=>{let i=O(e),a=i&&i in t?t[i]:t[e._zod.def.type],o=e=>sr(e,{ctx:r,rules:t,onMissing:n});return a?a(e,{...r,next:o}):n(e,r)},cr={name:n.path([`name`,`text`]),type:n.path([`type`]),optional:n.path([`questionToken`])},lr=({_zod:{def:e}},{api:t})=>{let n=e.values.map(e=>e===void 0?t.ensureTypeNode(t.ts.SyntaxKind.UndefinedKeyword):t.makeLiteralType(e));return n.length===1?n[0]:t.makeUnion(n)},ur=({_zod:{def:e}},{next:t,api:n})=>{let{parts:r}=e,i=0,a=()=>{let e=``;for(;i<r.length;){let t=r[i];if(C(t))break;i++,e+=t??``}return e},o=n.f.createTemplateHead(a()),s=[];for(;i<r.length;){let e=t(r[i++]),o=a(),c=i<r.length?n.f.createTemplateMiddle:n.f.createTemplateTail;s.push(n.f.createTemplateLiteralTypeSpan(e,c(o)))}return s.length?n.f.createTemplateLiteralType(o,s):n.makeLiteralType(o.text)},dr=(n,{isResponse:r,next:i,makeAlias:a,api:o})=>{let s=()=>{let a=Object.entries(n._zod.def.shape).map(([n,a])=>{let{description:s,deprecated:c}=e.get(a)||{},l=(r?a._zod.optout:a._zod.optin)===`optional`,u=l&&!(a instanceof t.core.$ZodExactOptional);return o.makeInterfaceProp(n,i(a),{comment:s,isDeprecated:c,isOptional:l,hasUndefined:u})});return o.f.createTypeLiteralNode(a)};return ze(n,{io:r?`output`:`input`})?a(n,s):s()},fr=({_zod:{def:e}},{next:t,api:n})=>n.f.createArrayTypeNode(t(e.element)),pr=({_zod:{def:e}},{api:t})=>t.makeUnion(n.map(t.makeLiteralType,Object.values(e.entries))),mr=({_zod:{def:e}},{next:t,api:n})=>n.makeUnion(e.options.map(t)),hr=({_zod:{def:e}},{next:t,api:n})=>n.makeUnion([t(e.innerType),n.makeLiteralType(null)]),gr=({_zod:{def:e}},{next:t,api:n})=>n.f.createTupleTypeNode(e.items.map(t).concat(e.rest===null?[]:n.f.createRestTypeNode(t(e.rest)))),_r=({_zod:{def:e}},{next:t,api:n})=>{let[r,i]=[e.keyType,e.valueType].map(t),a=n.ensureTypeNode(`Record`,[r,i]);return e.mode===`loose`?n.f.createIntersectionTypeNode([a,n.ensureTypeNode(`Record`,[`PropertyKey`,i])]):a},vr=n.tryCatch((e,t)=>{if(!t.every(e.ts.isTypeLiteralNode))throw Error(`Not objects`);let r=n.chain(n.prop(`members`),t),i=n.uniqWith((...e)=>{if(!n.eqBy(cr.name,...e))return!1;if(n.both(n.eqBy(cr.type),n.eqBy(cr.optional))(...e))return!0;throw Error(`Has conflicting prop`)},r);return e.f.createTypeLiteralNode(i)},(e,t,n)=>t.f.createIntersectionTypeNode(n)),yr=({_zod:{def:e}},{next:t,api:n})=>vr(n,[e.left,e.right].map(t)),Q=e=>({},{api:t})=>t.ensureTypeNode(t.ts.SyntaxKind[e]),$=({_zod:{def:e}},{next:t})=>t(e.innerType),br=(e,t)=>e.ensureTypeNode(t?e.ts.SyntaxKind.UnknownKeyword:e.ts.SyntaxKind.AnyKeyword),xr=({_zod:{def:e}},{next:t,isResponse:n,api:r})=>{let i=e[n?`out`:`in`],a=e[n?`in`:`out`];if(!C(i,`transform`))return t(i);let o=t(a),s={[r.ts.SyntaxKind.AnyKeyword]:``,[r.ts.SyntaxKind.BigIntKeyword]:BigInt(0),[r.ts.SyntaxKind.BooleanKeyword]:!1,[r.ts.SyntaxKind.NumberKeyword]:0,[r.ts.SyntaxKind.ObjectKeyword]:{},[r.ts.SyntaxKind.StringKeyword]:``,[r.ts.SyntaxKind.UndefinedKeyword]:void 0}[o.kind],c=be(i,s),l={number:r.ts.SyntaxKind.NumberKeyword,bigint:r.ts.SyntaxKind.BigIntKeyword,boolean:r.ts.SyntaxKind.BooleanKeyword,string:r.ts.SyntaxKind.StringKeyword,undefined:r.ts.SyntaxKind.UndefinedKeyword,object:r.ts.SyntaxKind.ObjectKeyword};return r.ensureTypeNode(c&&l[c]||br(r,n))},Sr=({},{api:e})=>e.makeLiteralType(null),Cr=({_zod:{def:e}},{makeAlias:t,next:n})=>t(e.getter,()=>n(e.getter())),wr=({},{api:e})=>e.ensureTypeNode(`Buffer`),Tr=(e,{next:t})=>t(e._zod.def.shape.raw),Er={string:Q(`StringKeyword`),number:Q(`NumberKeyword`),bigint:Q(`BigIntKeyword`),boolean:Q(`BooleanKeyword`),any:Q(`AnyKeyword`),undefined:Q(`UndefinedKeyword`),[j]:Q(`StringKeyword`),[M]:Q(`StringKeyword`),never:Q(`NeverKeyword`),void:Q(`UndefinedKeyword`),unknown:Q(`UnknownKeyword`),null:Sr,array:fr,tuple:gr,record:_r,object:dr,literal:lr,template_literal:ur,intersection:yr,union:mr,default:$,enum:pr,optional:$,nonoptional:$,nullable:hr,catch:$,pipe:xr,lazy:Cr,readonly:$,[A]:wr,[L]:Tr},Dr=(e,{brandHandling:t,ctx:n})=>sr(e,{rules:{...t,...Er},onMissing:({},{isResponse:e,api:t})=>br(t,e),ctx:n});var Or=class e extends or{#e=[this.makeSomeOfType()];#t=new Map;#n=[];#r(e,t){let n=this.#t.get(e)?.name?.text;if(!n){n=`Type${this.#t.size+1}`;let r=this.api.makeLiteralType(null);this.#t.set(e,this.api.makeType(n,r)),this.#t.set(e,this.api.makeType(n,t()))}return this.api.ensureTypeNode(n)}constructor({typescript:e,routing:r,config:i,brandHandling:a,variant:o=`client`,clientClassName:s=`Client`,subscriptionClassName:c=`Subscription`,serverUrl:l=`https://example.com`,noBodySchema:u=t.undefined(),hasHeadMethod:d=!0}){super(e,l);let f={makeAlias:this.#r.bind(this),api:this.api},p={brandHandling:a,ctx:{...f,isResponse:!1}},m={brandHandling:a,ctx:{...f,isResponse:!0}},h=(e,t,r)=>{let i=T.bind(null,e,t),{isDeprecated:a,inputSchema:o,tags:s}=r,c=`${e} ${t}`,l=this.api.makeType(i(`input`),Dr(o,p),{comment:c});this.#e.push(l);let d=$e.reduce((t,a)=>{let o=r.getResponses(a),s=n.chain(([t,{schema:n,mimeTypes:r,statusCodes:o}])=>{let s=Se(e,r),l=this.api.makeType(i(a,`variant`,`${t+1}`),Dr(s?n:u,m),{comment:c});return this.#e.push(l),o.map(e=>this.api.makeInterfaceProp(e,l.name))},Array.from(o.entries())),l=this.api.makeInterface(i(a,`response`,`variants`),s,{comment:c});return this.#e.push(l),Object.assign(t,{[a]:l})},{});this.paths.add(t);let f=this.api.makeLiteralType(c),h={input:this.api.ensureTypeNode(l.name),positive:this.someOf(d.positive),negative:this.someOf(d.negative),response:this.api.makeUnion([this.api.makeIndexed(this.interfaces.positive,f),this.api.makeIndexed(this.interfaces.negative,f)]),encoded:this.api.f.createIntersectionTypeNode([this.api.ensureTypeNode(d.positive.name),this.api.ensureTypeNode(d.negative.name)])};this.registry.set(c,{isDeprecated:a,store:h}),this.tags.set(c,s)};Mt({routing:r,config:i,onEndpoint:d?Tt(h):h}),this.#e.unshift(...this.#t.values()),this.#e.push(this.makePathType(),this.makeMethodType(),...this.makePublicInterfaces(),this.makeRequestType()),o!==`types`&&(this.#e.push(this.makeEndpointTags(),this.makeParseRequestFn(),this.makeSubstituteFn(),this.makeImplementationType(),this.makePaginationType(),this.makeDefaultImplementation(),this.makeClientClass(s),this.makeSubscriptionClass(c)),this.#n.push(...this.makeUsageStatements(s,c)))}static async create(t){return new e({...t,typescript:await q(`typescript`)})}#i(e){return this.#n.length?this.#n.map(t=>typeof t==`string`?t:this.api.printNode(t,e)).join(`
|
|
17
|
+
`))},cn=e=>{e.startupLogo!==!1&&sn(process.stdout);let t=e.errorHandler||W,n=ft(e.logger)?e.logger:new gt(e.logger);n.debug(`Running`,{build:`v28.2.0`,env:process.env.NODE_ENV||`development`}),an(n);let r=nn({logger:n,config:e}),i={getLogger:rn(n),errorHandler:t},a=Xt(i),o=Yt(i);return{...i,logger:n,notFoundHandler:a,catcher:o,loggingMiddleware:r}},ln=(e,t)=>{let{logger:n,getLogger:r,notFoundHandler:i,loggingMiddleware:a}=cn(e);return Vt({app:e.app.use(a),routing:t,getLogger:r,config:e}),{notFoundHandler:i,logger:n}},un=async(e,t)=>{let{logger:n,getLogger:r,notFoundHandler:i,catcher:a,loggingMiddleware:o}=cn(e),s=_().disable(`x-powered-by`).set(`query parser`,e.queryParser??`simple`).use(o);if(e.compression){let t=await J(`compression`);s.use(t(typeof e.compression==`object`?e.compression:void 0))}e.cookies&&s.use(await Qt({config:e})),await e.beforeRouting?.({app:s,getLogger:r}),Vt({app:s,routing:t,getLogger:r,config:e,parsers:{json:[e.jsonParser||_.json()],raw:[e.rawParser||_.raw(),tn],form:[e.formParser||_.urlencoded()],upload:e.upload?await en({config:e,getLogger:r}):[]}}),await e.afterRouting?.({app:s,getLogger:r}),s.use(a,i);let c=[],l=(e,t)=>()=>e.listen(t,()=>n.info(`Listening`,t)),u=[];if(e.http){let t=ee.createServer(s);c.push(t),u.push(l(t,e.http.listen))}if(e.https){let t=te.createServer(e.https.options,s);c.push(t),u.push(l(t,e.https.listen))}return c.length||n.warn(`No servers configured.`),e.gracefulShutdown&&on({logger:n,servers:c,options:e.gracefulShutdown===!0?{}:e.gracefulShutdown}),{app:s,logger:n,servers:u.map(e=>e())}},dn=e=>E(e)&&`or`in e,fn=e=>E(e)&&`and`in e,pn=e=>!fn(e)&&!dn(e),mn=e=>{let t=n.filter(pn,e),r=n.chain(n.prop(`and`),n.filter(fn,e)),[i,a]=n.partition(pn,r),o=n.concat(t,i),s=n.filter(dn,e);return n.map(n.prop(`or`),n.concat(s,a)).reduce((e,t)=>w(e,n.map(e=>pn(e)?[e]:e.and,t),([e,t])=>n.concat(e,t)),n.reject(n.isEmpty,[o]))},hn=(e,t)=>fn(e)?n.chain(e=>hn(e,t),e.and):dn(e)?n.chain(e=>hn(e,t),e.or):e.type===t?[e.name]:[],gn=(e,t)=>new Set(n.chain(e=>hn(e,t),e));let _n;const vn=()=>_n??=new Set(`a-im.accept.accept-additions.accept-charset.accept-datetime.accept-encoding.accept-features.accept-language.accept-signature.access-control.access-control-request-headers.access-control-request-method.alpn.alt-used.amp-cache-transform.apply-to-redirect-ref.authorization.available-dictionary.c-ext.c-man.c-opt.c-pep.c-pep-info.cache-control.cal-managed-id.caldav-timezones.capsule-protocol.cdn-loop.cert-not-after.cert-not-before.client-cert.client-cert-chain.close.cmcd-object.cmcd-request.cmcd-session.cmcd-status.cmsd-dynamic.cmsd-static.concealed-auth-export.configuration-context.connection.content-digest.content-disposition.content-encoding.content-id.content-language.content-length.content-location.content-md5.content-range.content-script-type.content-type.cookie.cookie2.cta-common-access-token.dasl.date.dav.default-style.delta-base.deprecation.depth.derived-from.destination.detached-jws.dictionary-id.differential-id.digest.dpop.early-data.ediint-features.expect.expect-ct.ext.forwarded.from.getprofile.hobareg.host.http2-settings.if.if-match.if-modified-since.if-none-match.if-range.if-schedule-tag-match.if-unmodified-since.im.include-referred-token-binding-id.incremental.isolation.keep-alive.label.last-event-id.link.link-template.lock-token.man.max-forwards.memento-datetime.meter.method-check.method-check-expires.mime-version.negotiate.odata-entityid.odata-isolation.odata-maxversion.odata-version.opt.ordering-type.origin.origin-agent-cluster.oscore.oslc-core-version.overwrite.pep.pep-info.permissions-policy.pics-label.ping-from.ping-to.position.pragma.prefer.preference-applied.priority.profileobject.protocol.protocol-info.protocol-query.protocol-request.proxy-authorization.proxy-features.proxy-instruction.range.redirect-ref.referer.referer-root.referrer-policy.repeatability-client-id.repeatability-first-sent.repeatability-request-id.repeatability-result.replay-nonce.reporting-endpoints.repr-digest.safe.schedule-reply.schedule-tag.sec-fetch-storage-access.sec-gpc.sec-purpose.sec-token-binding.sec-websocket-extensions.sec-websocket-key.sec-websocket-protocol.sec-websocket-version.security-scheme.signature.signature-input.slug.soapaction.status-uri.sunset.surrogate-capability.tcn.te.timeout.topic.traceparent.tracestate.trailer.transfer-encoding.ttl.upgrade.urgency.uri.user-agent.variant-vary.via.want-content-digest.want-digest.want-repr-digest.warning.x-content-type-options.x-frame-options`.split(`.`)),yn=`https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString`,bn={integer:0,number:0,string:``,boolean:!1,object:{},null:null,array:[]},xn=e=>e.replace(de,e=>`{${e.slice(1)}}`),Sn=({},e)=>{if(e.isResponse)throw new P(`Please use ez.upload() only for input.`,e);return{type:`string`,format:`binary`}},Cn=({jsonSchema:e})=>({...e,externalDocs:{description:`raw binary data`,url:`https://swagger.io/specification/#working-with-binary-data`}}),wn=({zodSchema:e,jsonSchema:t})=>{if(!C(e,`union`)||!(`discriminator`in e._zod.def))return t;let n=e._zod.def.discriminator;return{...t,discriminator:t.discriminator??{propertyName:n}}},Tn=n.tryCatch(({jsonSchema:e})=>{if(!e.allOf)throw`no allOf`;return Y(e,`throw`)},(e,{jsonSchema:t})=>t),En=({jsonSchema:e})=>{if(!e.anyOf||!e.anyOf.length)return e;let t=e.anyOf[0];return Object.assign(t,{type:Mn(t.type)})},X=e=>e,Dn=({jsonSchema:{examples:e,description:t}},n)=>{if(n.isResponse)throw new P(`Please use ez.dateOut() for output.`,n);let r={description:t||`YYYY-MM-DDTHH:mm:ss.sssZ`,type:`string`,format:`date-time`,pattern:`^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?)?Z?$`,externalDocs:{url:yn}};return e?.length&&(r.examples=e),r},On=({jsonSchema:{examples:e,description:t}},n)=>{if(!n.isResponse)throw new P(`Please use ez.dateIn() for input.`,n);let r={description:t||`YYYY-MM-DDTHH:mm:ss.sssZ`,type:`string`,format:`date-time`,externalDocs:{url:yn}};return e?.length&&(r.examples=e),r},kn=()=>({type:`string`,format:`bigint`,pattern:`^-?\\d+$`}),An=({zodSchema:e,jsonSchema:t})=>e._zod.def.rest===null?{...t,items:{not:{}}}:t,jn=e=>{let t=Array.isArray(e.type)?e.type[0]:e.type;return bn?.[t]},Mn=e=>e===`null`?e:typeof e==`string`?[e,`null`]:e&&[...new Set(e).add(`null`)],Nn=({zodSchema:e,jsonSchema:t},n)=>{let r=e._zod.def[n.isResponse?`out`:`in`],i=e._zod.def[n.isResponse?`in`:`out`];if(!C(r,`transform`))return t;let a=X(Bn(i,{ctx:n}));if(v(a))if(n.isResponse){let e=be(r,jn(a));if(e&&[`number`,`string`,`boolean`].includes(e))return{...t,type:e}}else{let{type:e,...t}=a;return{...t,format:`${t.format||e} (preprocessed)`}}return t},Pn=({jsonSchema:e})=>{if(e.type!==`object`)return e;let t=e;return!t.properties||!(`raw`in t.properties)||!E(t.properties.raw)?e:t.properties.raw},Fn=e=>e.length?n.fromPairs(n.zip(n.times(e=>`example${e+1}`,e.length),n.map(n.objOf(`value`),e))):void 0,In=(e,t)=>t?.has(e)||e.startsWith(`x-`)||vn().has(e),Ln=({path:e,method:t,request:r,inputSources:i,makeRef:a,composition:o,isHeader:s,securityHeaders:c,securityCookies:l,description:u=`${t.toUpperCase()} ${e} Parameter`})=>{let d=Y(r),f=fe(e),p=i.includes(`query`),m=i.includes(`params`),h=i.includes(`headers`),g=i.includes(`cookies`)||i.includes(`signedCookies`),_=n=>{if(m&&f.includes(n))return`path`;if(g&&l?.has(n))return`cookie`;if(h&&(s?.(n,t,e)??In(n,c)))return`header`;if(p)return`query`};return Object.entries(d.properties).reduce((e,[t,r])=>{if(!E(r))return e;let i=_(t);if(!i)return e;let s=X(r),c=o===`components`?a(r.id||JSON.stringify(r),s,r.id||T(u,t)):s;return e.concat({name:t,in:i,deprecated:r.deprecated,required:d.required?.includes(t)||!1,description:s.description||u,schema:c,examples:Fn(v(s)&&s.examples?.length?s.examples:n.pluck(t,d.examples?.filter(n.both(E,n.has(t)))||[]))})},[])},Rn={nullable:En,union:wn,bigint:kn,intersection:Tn,tuple:An,pipe:Nn,[j]:Dn,[M]:On,[L]:Sn,[R]:Pn,[A]:Cn},zn=(e,t,r)=>{let i=[e,t],a=e=>/schema\d+$/.test(e)?void 0:e;for(let e=0;e<i.length;e++){let o=i[e];if(n.is(Object,o)){if(ie(o)&&!o.$ref.startsWith(`#/components`)){let e=o.$ref.split(`/`).pop(),n=t[e];n&&(o.$ref=r.makeRef(n.id||n,X(n),n.id||a(e)).$ref);continue}i.push(...n.values(o))}n.is(Array,o)&&i.push(...n.values(o))}return e},Bn=(e,{ctx:n,rules:r=Rn})=>{let{$defs:i={},properties:a={}}=t.toJSONSchema(t.object({subject:e}),{unrepresentable:`any`,io:n.isResponse?`output`:`input`,override:e=>{let t=O(e.zodSchema),i=r[t&&t in r?t:e.zodSchema._zod.def.type];if(i){let t={...i(e,n)};for(let t in e.jsonSchema)delete e.jsonSchema[t];Object.assign(e.jsonSchema,t)}}});return zn(E(a.subject)?a.subject:{},i,n)},Vn=(e,t)=>{if(ie(e))return[e,!1];let r=!1,i=n.map(e=>{let[n,i]=Vn(e,t);return r||=i,n}),a=n.omit(t),o={properties:a,examples:n.map(a),required:n.without(t),allOf:i,oneOf:i,anyOf:i},s=n.evolve(o,e);return[s,r||!!s.required?.length]},Hn=({method:e,path:t,schema:r,mimeTypes:i,variant:a,makeRef:o,composition:s,hasMultipleStatusCodes:c,statusCode:l,brandHandling:u,description:d=`${e.toUpperCase()} ${t} ${ye(a)} response ${c?l:``}`.trim()})=>{if(!Se(e,i))return{description:d};let f=X(Bn(r,{rules:{...u,...Rn},ctx:{isResponse:!0,makeRef:o,path:t,method:e}})),p=[];v(f)&&f.examples&&(p.push(...f.examples),delete f.examples);let m={schema:s===`components`?o(r,f,T(d)):f,examples:Fn(p)};return{description:d,content:n.fromPairs(n.xprod(i,[m]))}},Un=({format:e})=>{let t={type:`http`,scheme:`bearer`};return e&&(t.bearerFormat=e),t},Wn=({name:e},t)=>{let n={type:`apiKey`,in:`query`,name:e};return t?.includes(`body`)&&(t?.includes(`query`)?(n[`x-in-alternative`]=`body`,n.description=`${e} CAN also be supplied within the request body`):(n[`x-in-actual`]=`body`,n.description=`${e} MUST be supplied within the request body instead of query`)),n},Gn=({name:e})=>({type:`apiKey`,in:`header`,name:e}),Kn=({name:e})=>({type:`apiKey`,in:`cookie`,name:e}),qn=({url:e})=>({type:`openIdConnect`,openIdConnectUrl:e}),Jn=({flows:e={}})=>({type:`oauth2`,flows:n.map(e=>({...e,scopes:e.scopes||{}}),n.reject(n.isNil,e))}),Yn=(e,t=[])=>{let n=e=>e.type===`basic`?{type:`http`,scheme:`basic`}:e.type===`bearer`?Un(e):e.type===`input`?Wn(e,t):e.type===`header`?Gn(e):e.type===`cookie`?Kn(e):e.type===`openid`?qn(e):Jn(e);return e.map(e=>e.map(n))},Xn=(e,t,n)=>e.map(e=>e.reduce((e,r)=>{let i=n(r),a=[`oauth2`,`openIdConnect`].includes(r.type);return Object.assign(e,{[i]:a?t:[]})},{})),Zn=({schema:e,brandHandling:t,makeRef:n,path:r,method:i})=>Bn(e,{rules:{...t,...Rn},ctx:{isResponse:!1,makeRef:n,path:r,method:i}}),Qn=({method:e,path:t,schema:r,request:i,mimeType:a,makeRef:o,composition:s,paramNames:c,description:l=`${e.toUpperCase()} ${t} Request body`})=>{let[u,d]=Vn(X(i),c),f=[];v(u)&&u.examples&&(f.push(...u.examples),delete u.examples);let p={schema:s===`components`?o(r,u,T(l)):u,examples:Fn(f.length?f:Y(i).examples?.filter(e=>E(e)&&!Array.isArray(e)).map(n.omit(c))||[])},m={description:l,content:{[a]:p}};return(d||a===y.raw)&&(m.required=!0),m},$n=e=>Object.entries(e).reduce((e,[t,n])=>{if(!n)return e;let r={name:t,description:typeof n==`string`?n:n.description};return typeof n==`object`&&n.url&&(r.externalDocs={url:n.url}),e.concat(r)},[]),er=(e,t=50)=>!e||e.length<=t?e:e.slice(0,Math.max(1,t||0)-1)+`…`,tr=e=>e.length?e.slice():void 0,nr=({description:e,summary:t=e,trim:n})=>n(t);var rr=class extends re{#e=new Map;#t=new Map;#n=new Map;#r(e,t,n){let r=this.#n.get(e);if(!r){let t=+!n;do r=`${n??`Schema`}${t?this.#n.size+t:``}`,t++;while(this.rootDoc.components?.schemas?.[r]);this.#n.set(e,r)}return this.addSchema(r,t),{$ref:`#/components/schemas/${r}`}}#i(e,t,n){let r=n||T(t,e),i=this.#t.get(r);if(i===void 0)return this.#t.set(r,1),r;if(n)throw new P(`Duplicated operationId: "${n}"`,{method:t,isResponse:!1,path:e});return i++,this.#t.set(r,i),`${r}${i}`}#a(e){let t=JSON.stringify(e);for(let e in this.rootDoc.components?.securitySchemes||{})if(t===JSON.stringify(this.rootDoc.components?.securitySchemes?.[e]))return e;let n=(this.#e.get(e.type)||0)+1;return this.#e.set(e.type,n),`${e.type.toUpperCase()}_${n}`}constructor({routing:e,config:t,title:r,version:i,serverUrl:a,descriptions:o,brandHandling:s,tags:c,isHeader:l,hasHeadMethod:u=!0,summarizer:d=nr,composition:f=`inline`}){super(),this.addInfo({title:r,version:i});for(let e of typeof a==`string`?[a]:a)this.addServer({url:e});let p=(e,r,i)=>{let a={path:r,method:e,endpoint:i,composition:f,brandHandling:s,makeRef:this.#r.bind(this)},{description:c,summary:u,scopes:p,inputSchema:m}=i,h=_e(e,t.inputSources),g=this.#i(r,e,i.getOperationId(e)),_=Zn({...a,schema:m}),ee=Ln({...a,inputSources:h,isHeader:l,securityHeaders:gn(i.security,`header`),securityCookies:gn(i.security,`cookie`),request:_,description:o?.requestParameter?.({method:e,path:r,operationId:g})}),te={};for(let t of Qe){let n=i.getResponses(t);for(let{mimeTypes:i,schema:s,statusCodes:c}of n)for(let l of c)te[l]=Hn({...a,variant:t,schema:s,mimeTypes:i,statusCode:l,hasMultipleStatusCodes:n.length>1||c.length>1,description:o?.[`${t}Response`]?.({method:e,path:r,operationId:g,statusCode:l})})}let ne=h.includes(`body`)?Qn({...a,request:_,paramNames:n.pluck(`name`,ee),schema:m,mimeType:y[i.requestType],description:o?.requestBody?.({method:e,path:r,operationId:g})}):void 0,re=Xn(Yn(mn(i.security),h),p,e=>{let t=this.#a(e);return this.addSecurityScheme(t,e),t}),ie={operationId:g,summary:d({summary:u,description:c,trim:er}),description:c,deprecated:i.isDeprecated||void 0,tags:tr(i.tags),parameters:tr(ee),requestBody:ne,security:tr(re),responses:te};this.addPath(xn(r),{[e]:ie})};It({routing:e,config:t,onEndpoint:u?kt(p):p}),c&&(this.rootDoc.tags=$n(c))}};const ir=e=>ae({...e,headers:{"content-type":y.json,...e?.headers}}),ar=e=>oe(e),or=e=>{let t={warn:[],error:[],info:[],debug:[]};return new Proxy(e||{},{get(e,n,r){return n===`_getLogs`?()=>t:pt(n)?(...e)=>t[n].push(e):Reflect.get(e,n,r)}})},sr=({requestProps:e,responseOptions:t,configProps:n,loggerProps:r})=>{let i=ir(e),a=ar({req:i,...t});a.req=t?.req||i,i.res=a;let o=or(r);return{requestMock:i,responseMock:a,loggerMock:o,configMock:{cors:!1,logger:o,...n}}},cr=async({endpoint:e,...t})=>{let{requestMock:n,responseMock:r,loggerMock:i,configMock:a}=sr(t);return await e.execute({request:n,response:r,config:a,logger:i}),{requestMock:n,responseMock:r,loggerMock:i}},lr=async({middleware:e,ctx:t={},...n})=>{let{requestMock:r,responseMock:i,loggerMock:a,configMock:{inputSources:o,errorHandler:s=W}}=sr(n),c={request:r,response:i,logger:a,input:ve(r,o),ctx:t};try{return{requestMock:r,responseMock:i,loggerMock:a,output:await e.execute(c)}}catch(e){return await s.execute({...c,error:x(e),output:null}),{requestMock:r,responseMock:i,loggerMock:a,output:{}}}};var ur=class e{ts;f;exportModifier;asyncModifier;accessModifiers;#e;static#t=/^[A-Za-z_$][A-Za-z0-9_$]*$/;constructor(e){this.ts=e,this.f=this.ts.factory,this.exportModifier=[this.f.createModifier(this.ts.SyntaxKind.ExportKeyword)],this.asyncModifier=[this.f.createModifier(this.ts.SyntaxKind.AsyncKeyword)],this.accessModifiers={public:[this.f.createModifier(this.ts.SyntaxKind.PublicKeyword)],publicStatic:[this.f.createModifier(this.ts.SyntaxKind.PublicKeyword),this.f.createModifier(this.ts.SyntaxKind.StaticKeyword)],protectedReadonly:[this.f.createModifier(this.ts.SyntaxKind.ProtectedKeyword),this.f.createModifier(this.ts.SyntaxKind.ReadonlyKeyword)]},this.#e=[this.ts.SyntaxKind.AnyKeyword,this.ts.SyntaxKind.BigIntKeyword,this.ts.SyntaxKind.BooleanKeyword,this.ts.SyntaxKind.NeverKeyword,this.ts.SyntaxKind.NumberKeyword,this.ts.SyntaxKind.ObjectKeyword,this.ts.SyntaxKind.StringKeyword,this.ts.SyntaxKind.SymbolKeyword,this.ts.SyntaxKind.UndefinedKeyword,this.ts.SyntaxKind.UnknownKeyword,this.ts.SyntaxKind.VoidKeyword]}addJsDoc=(e,t)=>this.ts.addSyntheticLeadingComment(e,this.ts.SyntaxKind.MultiLineCommentTrivia,`* ${t} `,!0);printNode=(e,t)=>{let n=this.ts.createSourceFile(`print.ts`,``,this.ts.ScriptTarget.Latest,!1,this.ts.ScriptKind.TS);return this.ts.createPrinter(t).printNode(this.ts.EmitHint.Unspecified,e,n)};makeId=e=>this.f.createIdentifier(e);makePropertyIdentifier=t=>typeof t==`string`&&e.#t.test(t)?this.makeId(t):this.literally(t);makeTemplate=(e,...t)=>this.f.createTemplateExpression(this.f.createTemplateHead(e),t.map(([e,n=``],r)=>this.f.createTemplateSpan(typeof e==`string`?this.makeId(e):e,r===t.length-1?this.f.createTemplateTail(n):this.f.createTemplateMiddle(n))));makeParam=(e,{type:t,mod:n,initId:r,optional:i}={})=>this.f.createParameterDeclaration(n,void 0,e,i?this.f.createToken(this.ts.SyntaxKind.QuestionToken):void 0,t?this.ensureTypeNode(t):void 0,r?this.makeId(r):void 0);makeParams=e=>Object.entries(e).map(([e,t])=>this.makeParam(e,typeof t==`string`||typeof t==`number`||typeof t==`object`&&`kind`in t?{type:t}:t));makePublicConstructor=(e,t=[])=>this.f.createConstructorDeclaration(this.accessModifiers.public,e,this.f.createBlock(t));ensureTypeNode=(e,t)=>typeof e==`number`?this.f.createKeywordTypeNode(e):typeof e==`string`||this.ts.isIdentifier(e)?this.f.createTypeReferenceNode(e,t&&n.map(this.ensureTypeNode,t)):e;makeRecordStringAny=()=>this.ensureTypeNode(`Record`,[this.ts.SyntaxKind.StringKeyword,this.ts.SyntaxKind.AnyKeyword]);makeUnion=e=>{let t=new Map;for(let n of e)t.set(this.isPrimitive(n)?n.kind:n,n);return this.f.createUnionTypeNode(Array.from(t.values()))};makeInterfaceProp=(e,t,{isOptional:r,hasUndefined:i=r,isDeprecated:a,comment:o}={})=>{let s=this.ensureTypeNode(t),c=this.f.createPropertySignature(void 0,this.makePropertyIdentifier(e),r?this.f.createToken(this.ts.SyntaxKind.QuestionToken):void 0,i?this.makeUnion([s,this.ensureTypeNode(this.ts.SyntaxKind.UndefinedKeyword)]):s),l=n.reject(n.isNil,[a?`@deprecated`:void 0,o]);return l.length?this.addJsDoc(c,l.join(` `)):c};makeOneLine=e=>this.ts.setEmitFlags(e,this.ts.EmitFlags.SingleLine);makeDeconstruction=(...e)=>this.f.createArrayBindingPattern(e.map(e=>this.f.createBindingElement(void 0,void 0,e)));makeConst=(e,t,{type:n,expose:r}={})=>this.f.createVariableStatement(r&&this.exportModifier,this.f.createVariableDeclarationList([this.f.createVariableDeclaration(e,void 0,n?this.ensureTypeNode(n):void 0,t)],this.ts.NodeFlags.Const));makePublicLiteralType=(e,t)=>this.makeType(e,this.makeUnion(n.map(this.makeLiteralType,t)),{expose:!0});makeType=(e,t,{expose:n,comment:r,params:i}={})=>{let a=this.f.createTypeAliasDeclaration(n?this.exportModifier:void 0,e,i&&this.makeTypeParams(i),t);return r?this.addJsDoc(a,r):a};makePublicProperty=(e,t)=>this.f.createPropertyDeclaration(this.accessModifiers.public,e,void 0,this.ensureTypeNode(t),void 0);makePublicMethod=(e,t,n,{typeParams:r,returns:i,isStatic:a}={})=>this.f.createMethodDeclaration(a?this.accessModifiers.publicStatic:this.accessModifiers.public,void 0,e,void 0,r&&this.makeTypeParams(r),t,i,this.f.createBlock(n));makePublicClass=(e,t,{typeParams:n}={})=>this.f.createClassDeclaration(this.exportModifier,e,n&&this.makeTypeParams(n),void 0,t);makeKeyOf=e=>this.f.createTypeOperatorNode(this.ts.SyntaxKind.KeyOfKeyword,this.ensureTypeNode(e));makePromise=e=>this.ensureTypeNode(Promise.name,[e]);makeInterface=(e,t,{expose:n,comment:r}={})=>{let i=this.f.createInterfaceDeclaration(n?this.exportModifier:void 0,e,void 0,void 0,t);return r?this.addJsDoc(i,r):i};makeTypeParams=e=>(Array.isArray(e)?e.map(e=>n.pair(e,void 0)):Object.entries(e)).map(([e,t])=>{let{type:n,init:r}=typeof t==`object`&&`init`in t?t:{type:t};return this.f.createTypeParameterDeclaration([],e,n?this.ensureTypeNode(n):void 0,r?this.ensureTypeNode(r):void 0)});makeArrowFn=(e,t,{isAsync:r}={})=>this.f.createArrowFunction(r?this.asyncModifier:void 0,void 0,Array.isArray(e)?n.map(this.makeParam,e):this.makeParams(e),void 0,void 0,t);makeTernary=(...e)=>{let[t,n,r]=e.map(e=>typeof e==`string`?this.makeId(e):e);return this.f.createConditionalExpression(t,this.f.createToken(this.ts.SyntaxKind.QuestionToken),n,this.f.createToken(this.ts.SyntaxKind.ColonToken),r)};makeCall=(e,...t)=>(...n)=>this.f.createCallExpression(t.reduce((e,t)=>typeof t==`string`||this.ts.isIdentifier(t)?this.f.createPropertyAccessExpression(e,t):this.f.createElementAccessExpression(e,t),typeof e==`string`?this.makeId(e):e),void 0,n.map(e=>typeof e==`string`?this.makeId(e):e));makeNew=(e,...t)=>this.f.createNewExpression(this.makeId(e),void 0,t);makeExtract=(e,t)=>this.ensureTypeNode(`Extract`,[e,t]);makeAssignment=(e,t)=>this.f.createExpressionStatement(this.f.createBinaryExpression(typeof e==`string`?this.makeId(e):e,this.f.createToken(this.ts.SyntaxKind.EqualsToken),t));makeIndexed=(e,t)=>this.f.createIndexedAccessTypeNode(this.ensureTypeNode(e),this.ensureTypeNode(t));makeMaybeAsync=e=>this.makeUnion([this.ensureTypeNode(e),this.makePromise(e)]);makeFnType=(e,t)=>this.f.createFunctionTypeNode(void 0,this.makeParams(e),this.ensureTypeNode(t));literally=e=>typeof e==`number`?this.f.createNumericLiteral(e):typeof e==`bigint`?this.f.createBigIntLiteral(e.toString()):typeof e==`boolean`?e?this.f.createTrue():this.f.createFalse():e===null?this.f.createNull():this.f.createStringLiteral(e);makeLiteralType=e=>this.f.createLiteralTypeNode(this.literally(e));isPrimitive=e=>this.#e.includes(e.kind)};const Z=e=>e;var dr=class{serverUrl;api;paths=new Set;tags=new Map;registry=new Map;constructor(e,t){this.serverUrl=t,this.api=new ur(e)}#e={pathType:`Path`,implementationType:`Implementation`,keyParameter:`key`,pathParameter:`path`,paramsArgument:`params`,ctxArgument:`ctx`,methodParameter:`method`,requestParameter:`request`,eventParameter:`event`,dataParameter:`data`,handlerParameter:`handler`,msgParameter:`msg`,parseRequestFn:`parseRequest`,substituteFn:`substitute`,provideMethod:`provide`,onMethod:`on`,implementationArgument:`implementation`,hasBodyConst:`hasBody`,undefinedValue:`undefined`,responseConst:`response`,restConst:`rest`,searchParamsConst:`searchParams`,defaultImplementationConst:`defaultImplementation`,clientConst:`client`,contentTypeConst:`contentType`,isJsonConst:`isJSON`,sourceProp:`source`,methodType:`Method`,someOfType:`SomeOf`,requestType:`Request`,paginationType:`Pagination`};interfaces={input:`Input`,positive:`PositiveResponse`,negative:`NegativeResponse`,encoded:`EncodedResponse`,response:`Response`};makeMethodType=()=>this.api.makePublicLiteralType(this.#e.methodType,le);makeSomeOfType=()=>this.api.makeType(this.#e.someOfType,this.api.makeIndexed(`T`,this.api.makeKeyOf(`T`)),{params:[`T`]});makeRequestType=()=>this.api.makeType(this.#e.requestType,this.api.makeKeyOf(this.interfaces.input),{expose:!0});someOf=({name:e})=>this.api.ensureTypeNode(this.#e.someOfType,[e]);makePathType=()=>this.api.makePublicLiteralType(this.#e.pathType,Array.from(this.paths));makePublicInterfaces=()=>Object.keys(this.interfaces).map(e=>this.api.makeInterface(this.interfaces[e],Array.from(this.registry).map(([t,{store:n,isDeprecated:r}])=>this.api.makeInterfaceProp(t,n[e],{isDeprecated:r})),{expose:!0}));makeEndpointTags=()=>this.api.makeConst(`endpointTags`,this.api.f.createObjectLiteralExpression(Array.from(this.tags).map(([e,t])=>this.api.f.createPropertyAssignment(this.api.makePropertyIdentifier(e),this.api.f.createArrayLiteralExpression(n.map(this.api.literally,t))))),{expose:!0});makeImplementationType=()=>this.api.makeType(this.#e.implementationType,this.api.makeFnType({[this.#e.methodParameter]:this.#e.methodType,[this.#e.pathParameter]:this.api.ts.SyntaxKind.StringKeyword,[this.#e.paramsArgument]:this.api.makeRecordStringAny(),[this.#e.ctxArgument]:{optional:!0,type:`T`}},this.api.makePromise(this.api.ts.SyntaxKind.AnyKeyword)),{expose:!0,params:{T:{init:this.api.ts.SyntaxKind.UnknownKeyword}}});makeParseRequestFn=()=>this.api.makeConst(this.#e.parseRequestFn,this.api.makeArrowFn({[this.#e.requestParameter]:this.api.ts.SyntaxKind.StringKeyword},this.api.f.createAsExpression(this.api.makeCall(this.#e.requestParameter,Z(`split`))(this.api.f.createRegularExpressionLiteral(`/ (.+)/`),this.api.literally(2)),this.api.f.createTupleTypeNode([this.api.ensureTypeNode(this.#e.methodType),this.api.ensureTypeNode(this.#e.pathType)]))));makeSubstituteFn=()=>this.api.makeConst(this.#e.substituteFn,this.api.makeArrowFn({[this.#e.pathParameter]:this.api.ts.SyntaxKind.StringKeyword,[this.#e.paramsArgument]:this.api.makeRecordStringAny()},this.api.f.createBlock([this.api.makeConst(this.#e.restConst,this.api.f.createObjectLiteralExpression([this.api.f.createSpreadAssignment(this.api.makeId(this.#e.paramsArgument))])),this.api.f.createForInStatement(this.api.f.createVariableDeclarationList([this.api.f.createVariableDeclaration(this.#e.keyParameter)],this.api.ts.NodeFlags.Const),this.api.makeId(this.#e.paramsArgument),this.api.f.createBlock([this.api.makeAssignment(this.#e.pathParameter,this.api.makeCall(this.#e.pathParameter,Z(`replace`))(this.api.makeTemplate(`:`,[this.#e.keyParameter]),this.api.makeArrowFn([],this.api.f.createBlock([this.api.f.createExpressionStatement(this.api.f.createDeleteExpression(this.api.f.createElementAccessExpression(this.api.makeId(this.#e.restConst),this.api.makeId(this.#e.keyParameter)))),this.api.f.createReturnStatement(this.api.f.createElementAccessExpression(this.api.makeId(this.#e.paramsArgument),this.api.makeId(this.#e.keyParameter)))]))))])),this.api.f.createReturnStatement(this.api.f.createAsExpression(this.api.f.createArrayLiteralExpression([this.api.makeId(this.#e.pathParameter),this.api.makeId(this.#e.restConst)]),this.api.ensureTypeNode(`const`)))])));makePaginationType=()=>{let e=Z(`nextCursor`),t=Z(`total`),n=Z(`limit`),r=Z(`offset`),i=this.api.f.createTypeLiteralNode([this.api.makeInterfaceProp(e,this.api.makeUnion([this.api.ensureTypeNode(this.api.ts.SyntaxKind.StringKeyword),this.api.makeLiteralType(null)]))]),a=this.api.f.createTypeLiteralNode([t,n,r].map(e=>this.api.makeInterfaceProp(e,this.api.ts.SyntaxKind.NumberKeyword)));return this.api.makeType(this.#e.paginationType,this.api.makeUnion([i,a]))};#t=()=>{let e=this.api.makeId(this.#e.responseConst),t=Z(`nextCursor`),n=Z(`total`),r=Z(`limit`),i=Z(`offset`),a=this.api.f.createBinaryExpression(this.api.literally(t),this.api.ts.SyntaxKind.InKeyword,e),o=this.api.f.createReturnStatement(this.api.f.createBinaryExpression(this.api.f.createPropertyAccessExpression(e,t),this.api.ts.SyntaxKind.ExclamationEqualsEqualsToken,this.api.literally(null))),s=this.api.f.createBinaryExpression(this.api.f.createPropertyAccessExpression(e,i),this.api.ts.SyntaxKind.PlusToken,this.api.f.createPropertyAccessExpression(e,r)),c=this.api.f.createReturnStatement(this.api.f.createBinaryExpression(s,this.api.ts.SyntaxKind.LessThanToken,this.api.f.createPropertyAccessExpression(e,n)));return this.api.makePublicMethod(`hasMore`,[this.api.makeParam(e,{type:this.#e.paginationType})],[this.api.f.createIfStatement(a,o),c],{returns:this.api.ensureTypeNode(this.api.ts.SyntaxKind.BooleanKeyword),isStatic:!0})};#n=()=>this.api.makePublicMethod(this.#e.provideMethod,this.api.makeParams({[this.#e.requestParameter]:`K`,[this.#e.paramsArgument]:this.api.makeIndexed(this.interfaces.input,`K`),[this.#e.ctxArgument]:{optional:!0,type:`T`}}),[this.api.makeConst(this.api.makeDeconstruction(this.#e.methodParameter,this.#e.pathParameter),this.api.makeCall(this.#e.parseRequestFn)(this.#e.requestParameter)),this.api.f.createReturnStatement(this.api.makeCall(this.api.f.createThis(),this.#e.implementationArgument)(this.#e.methodParameter,this.api.f.createSpreadElement(this.api.makeCall(this.#e.substituteFn)(this.#e.pathParameter,this.#e.paramsArgument)),this.#e.ctxArgument))],{typeParams:{K:this.#e.requestType},returns:this.api.makePromise(this.api.makeIndexed(this.interfaces.response,`K`))});makeClientClass=e=>this.api.makePublicClass(e,[this.api.makePublicConstructor([this.api.makeParam(this.#e.implementationArgument,{type:this.api.ensureTypeNode(this.#e.implementationType,[`T`]),mod:this.api.accessModifiers.protectedReadonly,initId:this.#e.defaultImplementationConst})]),this.#n(),this.#t()],{typeParams:[`T`]});#r=e=>this.api.makeTemplate(`?`,[this.api.makeNew(URLSearchParams.name,this.api.makeId(e))]);#i=()=>this.api.makeNew(URL.name,this.api.makeTemplate(``,[this.#e.pathParameter],[this.#e.searchParamsConst]),this.api.literally(this.serverUrl));makeDefaultImplementation=()=>{let e=this.api.f.createPropertyAssignment(Z(`method`),this.api.makeCall(this.#e.methodParameter,Z(`toUpperCase`))()),t=this.api.f.createPropertyAssignment(Z(`headers`),this.api.makeTernary(this.#e.hasBodyConst,this.api.f.createObjectLiteralExpression([this.api.f.createPropertyAssignment(this.api.literally(`Content-Type`),this.api.literally(y.json))]),this.#e.undefinedValue)),n=this.api.f.createPropertyAssignment(Z(`body`),this.api.makeTernary(this.#e.hasBodyConst,this.api.makeCall(JSON[Symbol.toStringTag],Z(`stringify`))(this.#e.paramsArgument),this.#e.undefinedValue)),r=this.api.makeConst(this.#e.responseConst,this.api.f.createAwaitExpression(this.api.makeCall(fetch.name)(this.#i(),this.api.f.createObjectLiteralExpression([e,t,n])))),i=this.api.makeConst(this.#e.hasBodyConst,this.api.f.createLogicalNot(this.api.makeCall(this.api.f.createArrayLiteralExpression([this.api.literally(`get`),this.api.literally(`head`),this.api.literally(`delete`)]),Z(`includes`))(this.#e.methodParameter))),a=this.api.makeConst(this.#e.searchParamsConst,this.api.makeTernary(this.#e.hasBodyConst,this.api.literally(``),this.#r(this.#e.paramsArgument))),o=this.api.makeConst(this.#e.contentTypeConst,this.api.makeCall(this.#e.responseConst,Z(`headers`),Z(`get`))(this.api.literally(`content-type`))),s=this.api.f.createIfStatement(this.api.f.createPrefixUnaryExpression(this.api.ts.SyntaxKind.ExclamationToken,this.api.makeId(this.#e.contentTypeConst)),this.api.f.createReturnStatement()),c=this.api.makeConst(this.#e.isJsonConst,this.api.makeCall(this.#e.contentTypeConst,Z(`startsWith`))(this.api.literally(y.json))),l=this.api.f.createReturnStatement(this.api.makeCall(this.#e.responseConst,this.api.makeTernary(this.#e.isJsonConst,this.api.literally(Z(`json`)),this.api.literally(Z(`text`))))());return this.api.makeConst(this.#e.defaultImplementationConst,this.api.makeArrowFn([this.#e.methodParameter,this.#e.pathParameter,this.#e.paramsArgument],this.api.f.createBlock([i,a,r,o,s,c,l]),{isAsync:!0}),{type:this.#e.implementationType})};#a=()=>this.api.makePublicConstructor(this.api.makeParams({request:`K`,params:this.api.makeIndexed(this.interfaces.input,`K`)}),[this.api.makeConst(this.api.makeDeconstruction(this.#e.pathParameter,this.#e.restConst),this.api.makeCall(this.#e.substituteFn)(this.api.f.createElementAccessExpression(this.api.makeCall(this.#e.parseRequestFn)(this.#e.requestParameter),this.api.literally(1)),this.#e.paramsArgument)),this.api.makeConst(this.#e.searchParamsConst,this.#r(this.#e.restConst)),this.api.makeAssignment(this.api.f.createPropertyAccessExpression(this.api.f.createThis(),this.#e.sourceProp),this.api.makeNew(`EventSource`,this.#i()))]);#o=e=>this.api.f.createTypeLiteralNode([this.api.makeInterfaceProp(Z(`event`),e)]);#s=()=>this.api.makePublicMethod(this.#e.onMethod,this.api.makeParams({[this.#e.eventParameter]:`E`,[this.#e.handlerParameter]:this.api.makeFnType({[this.#e.dataParameter]:this.api.makeIndexed(this.api.makeExtract(`R`,this.api.makeOneLine(this.#o(`E`))),this.api.makeLiteralType(Z(`data`)))},this.api.makeMaybeAsync(this.api.ts.SyntaxKind.VoidKeyword))}),[this.api.f.createExpressionStatement(this.api.makeCall(this.api.f.createThis(),this.#e.sourceProp,Z(`addEventListener`))(this.#e.eventParameter,this.api.makeArrowFn([this.#e.msgParameter],this.api.makeCall(this.#e.handlerParameter)(this.api.makeCall(JSON[Symbol.toStringTag],Z(`parse`))(this.api.f.createPropertyAccessExpression(this.api.f.createParenthesizedExpression(this.api.f.createAsExpression(this.api.makeId(this.#e.msgParameter),this.api.ensureTypeNode(MessageEvent.name))),Z(`data`))))))),this.api.f.createReturnStatement(this.api.f.createThis())],{typeParams:{E:this.api.makeIndexed(`R`,this.api.makeLiteralType(Z(`event`)))}});makeSubscriptionClass=e=>this.api.makePublicClass(e,[this.api.makePublicProperty(this.#e.sourceProp,`EventSource`),this.#a(),this.#s()],{typeParams:{K:this.api.makeExtract(this.#e.requestType,this.api.f.createTemplateLiteralType(this.api.f.createTemplateHead(`get `),[this.api.f.createTemplateLiteralTypeSpan(this.api.ensureTypeNode(this.api.ts.SyntaxKind.StringKeyword),this.api.f.createTemplateTail(``))])),R:this.api.makeExtract(this.api.makeIndexed(this.interfaces.positive,`K`),this.api.makeOneLine(this.#o(this.api.ts.SyntaxKind.StringKeyword)))}});makeUsageStatements=(e,t)=>[this.api.makeConst(this.#e.clientConst,this.api.makeNew(e)),this.api.makeCall(this.#e.clientConst,this.#e.provideMethod)(this.api.literally(`get /v1/user/retrieve`),this.api.f.createObjectLiteralExpression([this.api.f.createPropertyAssignment(`id`,this.api.literally(`10`))])),this.api.makeCall(this.api.makeNew(t,this.api.literally(`get /v1/events/stream`),this.api.f.createObjectLiteralExpression()),this.#e.onMethod)(this.api.literally(`time`),this.api.makeArrowFn([`time`],this.api.f.createBlock([])))]};const fr=(e,{rules:t,onMissing:n,ctx:r={}})=>{let i=O(e),a=i&&i in t?t[i]:t[e._zod.def.type],o=e=>fr(e,{ctx:r,rules:t,onMissing:n});return a?a(e,{...r,next:o}):n(e,r)},pr={name:n.path([`name`,`text`]),type:n.path([`type`]),optional:n.path([`questionToken`])},mr=({_zod:{def:e}},{api:t})=>{let n=e.values.map(e=>e===void 0?t.ensureTypeNode(t.ts.SyntaxKind.UndefinedKeyword):t.makeLiteralType(e));return n.length===1?n[0]:t.makeUnion(n)},hr=({_zod:{def:e}},{next:t,api:n})=>{let{parts:r}=e,i=0,a=()=>{let e=``;for(;i<r.length;){let t=r[i];if(C(t))break;i++,e+=t??``}return e},o=n.f.createTemplateHead(a()),s=[];for(;i<r.length;){let e=t(r[i++]),o=a(),c=i<r.length?n.f.createTemplateMiddle:n.f.createTemplateTail;s.push(n.f.createTemplateLiteralTypeSpan(e,c(o)))}return s.length?n.f.createTemplateLiteralType(o,s):n.makeLiteralType(o.text)},gr=(n,{isResponse:r,next:i,makeAlias:a,api:o})=>{let s=()=>{let a=Object.entries(n._zod.def.shape).map(([n,a])=>{let{description:s,deprecated:c}=e.get(a)||{},l=(r?a._zod.optout:a._zod.optin)===`optional`,u=l&&!(a instanceof t.core.$ZodExactOptional);return o.makeInterfaceProp(n,i(a),{comment:s,isDeprecated:c,isOptional:l,hasUndefined:u})});return o.f.createTypeLiteralNode(a)};return Re(n,{io:r?`output`:`input`})?a(n,s):s()},_r=({_zod:{def:e}},{next:t,api:n})=>n.f.createArrayTypeNode(t(e.element)),vr=({_zod:{def:e}},{api:t})=>t.makeUnion(n.map(t.makeLiteralType,Object.values(e.entries))),yr=({_zod:{def:e}},{next:t,api:n})=>n.makeUnion(e.options.map(t)),br=({_zod:{def:e}},{next:t,api:n})=>n.makeUnion([t(e.innerType),n.makeLiteralType(null)]),xr=({_zod:{def:e}},{next:t,api:n})=>n.f.createTupleTypeNode(e.items.map(t).concat(e.rest===null?[]:n.f.createRestTypeNode(t(e.rest)))),Sr=({_zod:{def:e}},{next:t,api:n})=>{let[r,i]=[e.keyType,e.valueType].map(t),a=n.ensureTypeNode(`Record`,[r,i]);return e.mode===`loose`?n.f.createIntersectionTypeNode([a,n.ensureTypeNode(`Record`,[`PropertyKey`,i])]):a},Cr=n.tryCatch((e,t)=>{if(!t.every(e.ts.isTypeLiteralNode))throw Error(`Not objects`);let r=n.chain(n.prop(`members`),t),i=n.uniqWith((...e)=>{if(!n.eqBy(pr.name,...e))return!1;if(n.both(n.eqBy(pr.type),n.eqBy(pr.optional))(...e))return!0;throw Error(`Has conflicting prop`)},r);return e.f.createTypeLiteralNode(i)},(e,t,n)=>t.f.createIntersectionTypeNode(n)),wr=({_zod:{def:e}},{next:t,api:n})=>Cr(n,[e.left,e.right].map(t)),Q=e=>({},{api:t})=>t.ensureTypeNode(t.ts.SyntaxKind[e]),$=({_zod:{def:e}},{next:t})=>t(e.innerType),Tr=(e,t)=>e.ensureTypeNode(t?e.ts.SyntaxKind.UnknownKeyword:e.ts.SyntaxKind.AnyKeyword),Er=({_zod:{def:e}},{next:t,isResponse:n,api:r})=>{let i=e[n?`out`:`in`],a=e[n?`in`:`out`];if(!C(i,`transform`))return t(i);let o=t(a),s={[r.ts.SyntaxKind.AnyKeyword]:``,[r.ts.SyntaxKind.BigIntKeyword]:BigInt(0),[r.ts.SyntaxKind.BooleanKeyword]:!1,[r.ts.SyntaxKind.NumberKeyword]:0,[r.ts.SyntaxKind.ObjectKeyword]:{},[r.ts.SyntaxKind.StringKeyword]:``,[r.ts.SyntaxKind.UndefinedKeyword]:void 0}[o.kind],c=be(i,s),l={number:r.ts.SyntaxKind.NumberKeyword,bigint:r.ts.SyntaxKind.BigIntKeyword,boolean:r.ts.SyntaxKind.BooleanKeyword,string:r.ts.SyntaxKind.StringKeyword,undefined:r.ts.SyntaxKind.UndefinedKeyword,object:r.ts.SyntaxKind.ObjectKeyword};return r.ensureTypeNode(c&&l[c]||Tr(r,n))},Dr=({},{api:e})=>e.makeLiteralType(null),Or=({_zod:{def:e}},{makeAlias:t,next:n})=>t(e.getter,()=>n(e.getter())),kr=({},{api:e})=>e.ensureTypeNode(`Buffer`),Ar=(e,{next:t})=>t(e._zod.def.shape.raw),jr={string:Q(`StringKeyword`),number:Q(`NumberKeyword`),bigint:Q(`BigIntKeyword`),boolean:Q(`BooleanKeyword`),any:Q(`AnyKeyword`),undefined:Q(`UndefinedKeyword`),[j]:Q(`StringKeyword`),[M]:Q(`StringKeyword`),never:Q(`NeverKeyword`),void:Q(`UndefinedKeyword`),unknown:Q(`UnknownKeyword`),null:Dr,array:_r,tuple:xr,record:Sr,object:gr,literal:mr,template_literal:hr,intersection:wr,union:yr,default:$,enum:vr,optional:$,nonoptional:$,nullable:br,catch:$,pipe:Er,lazy:Or,readonly:$,[A]:kr,[R]:Ar},Mr=(e,{brandHandling:t,ctx:n})=>fr(e,{rules:{...t,...jr},onMissing:({},{isResponse:e,api:t})=>Tr(t,e),ctx:n});var Nr=class e extends dr{#e=[this.makeSomeOfType()];#t=new Map;#n=[];#r(e,t){let n=this.#t.get(e)?.name?.text;if(!n){n=`Type${this.#t.size+1}`;let r=this.api.makeLiteralType(null);this.#t.set(e,this.api.makeType(n,r)),this.#t.set(e,this.api.makeType(n,t()))}return this.api.ensureTypeNode(n)}constructor({typescript:e,routing:r,config:i,brandHandling:a,variant:o=`client`,clientClassName:s=`Client`,subscriptionClassName:c=`Subscription`,serverUrl:l=`https://example.com`,noBodySchema:u=t.undefined(),hasHeadMethod:d=!0}){super(e,l);let f={makeAlias:this.#r.bind(this),api:this.api},p={brandHandling:a,ctx:{...f,isResponse:!1}},m={brandHandling:a,ctx:{...f,isResponse:!0}},h=(e,t,r)=>{let i=T.bind(null,e,t),{isDeprecated:a,inputSchema:o,tags:s}=r,c=`${e} ${t}`,l=this.api.makeType(i(`input`),Mr(o,p),{comment:c});this.#e.push(l);let d=Qe.reduce((t,a)=>{let o=r.getResponses(a),s=n.chain(([t,{schema:n,mimeTypes:r,statusCodes:o}])=>{let s=Se(e,r),l=this.api.makeType(i(a,`variant`,`${t+1}`),Mr(s?n:u,m),{comment:c});return this.#e.push(l),o.map(e=>this.api.makeInterfaceProp(e,l.name))},Array.from(o.entries())),l=this.api.makeInterface(i(a,`response`,`variants`),s,{comment:c});return this.#e.push(l),Object.assign(t,{[a]:l})},{});this.paths.add(t);let f=this.api.makeLiteralType(c),h={input:this.api.ensureTypeNode(l.name),positive:this.someOf(d.positive),negative:this.someOf(d.negative),response:this.api.makeUnion([this.api.makeIndexed(this.interfaces.positive,f),this.api.makeIndexed(this.interfaces.negative,f)]),encoded:this.api.f.createIntersectionTypeNode([this.api.ensureTypeNode(d.positive.name),this.api.ensureTypeNode(d.negative.name)])};this.registry.set(c,{isDeprecated:a,store:h}),this.tags.set(c,s)};It({routing:r,config:i,onEndpoint:d?kt(h):h}),this.#e.unshift(...this.#t.values()),this.#e.push(this.makePathType(),this.makeMethodType(),...this.makePublicInterfaces(),this.makeRequestType()),o!==`types`&&(this.#e.push(this.makeEndpointTags(),this.makeParseRequestFn(),this.makeSubstituteFn(),this.makeImplementationType(),this.makePaginationType(),this.makeDefaultImplementation(),this.makeClientClass(s),this.makeSubscriptionClass(c)),this.#n.push(...this.makeUsageStatements(s,c)))}static async create(t){return new e({...t,typescript:await J(`typescript`)})}#i(e){return this.#n.length?this.#n.map(t=>typeof t==`string`?t:this.api.printNode(t,e)).join(`
|
|
18
18
|
`):void 0}print(e){let t=this.#i(e),n=t&&this.api.ts.addSyntheticLeadingComment(this.api.ts.addSyntheticLeadingComment(this.api.f.createEmptyStatement(),this.api.ts.SyntaxKind.SingleLineCommentTrivia,` Usage example:`),this.api.ts.SyntaxKind.MultiLineCommentTrivia,`\n${t}`);return this.#e.concat(n||[]).map((t,n)=>this.api.printNode(t,n<this.#e.length?e:{...e,omitTrailingSemicolon:!0})).join(`
|
|
19
19
|
|
|
20
|
-
`)}async printFormatted({printerOptions:e,format:t}={}){let n=t;if(!n)try{let e=(await
|
|
21
|
-
`)).parse({event:t,data:n}),
|
|
20
|
+
`)}async printFormatted({printerOptions:e,format:t}={}){let n=t;if(!n)try{let e=(await J(`prettier`)).format;n=t=>e(t,{filepath:`client.ts`})}catch{}let r=this.#i(e);this.#n=r&&n?[await n(r)]:this.#n;let i=this.print(e);return n?n(i):i}};const Pr=(e,n)=>t.object({data:n,event:t.literal(e),id:t.string().optional(),retry:t.int().positive().optional()}),Fr=(e,t,n)=>Pr(String(t),e[t]).transform(e=>[`event: ${e.event}`,`data: ${JSON.stringify(e.data)}`,``,``].join(`
|
|
21
|
+
`)).parse({event:t,data:n}),Ir=e=>e.headersSent||e.writeHead(200,{connection:`keep-alive`,"content-type":y.sse,"cache-control":`no-cache`}),Lr=e=>new V({handler:async({request:t,response:n})=>{let r=new AbortController;return t.once(`close`,()=>{r.abort()}),setTimeout(()=>Ir(n),1e4),{isClosed:()=>n.writableEnded||n.closed,signal:r.signal,emit:(t,r)=>{Ir(n),n.write(Fr(e,t,r),`utf-8`),n.flush?.()}}}}),Rr=e=>new U({positive:()=>{let[n,...r]=Object.entries(e).map(([e,t])=>Pr(e,t));if(!n)throw new I(Error(`At least one SSE event is required.`));return{mimeType:y.sse,schema:r.length?t.discriminatedUnion(`event`,[n,...r]):n}},negative:{mimeType:`text/plain`,schema:t.string()},handler:async({response:e,error:t,logger:n,request:r,input:i})=>{if(t){let a=z(t);Ue(a,n,r,i),e.headersSent||e.status(a.statusCode).type(`text/plain`).write(B(a),`utf-8`)}e.end()}});var zr=class extends G{constructor(e){super(Rr(e)),this.middlewares=[Lr(e)]}};const Br=[`total`,`limit`,`offset`],Vr=[`nextCursor`,`limit`];function Hr({style:e,itemSchema:n,itemsName:r=`items`,maxLimit:i=100,defaultLimit:a=20}){if(!Number.isInteger(i)||i<1)throw Error(`ez.paginated: maxLimit must be a positive integer`);if(!Number.isInteger(a)||a<1)throw Error(`ez.paginated: defaultLimit must be a positive integer`);if(a>i)throw Error(`ez.paginated: defaultLimit must not be greater than maxLimit`);if(e===`offset`&&Br.includes(r))throw Error(`ez.paginated: itemsName must not match reserved keys for offset output (${Br.join(`, `)})`);if(e===`cursor`&&Vr.includes(r))throw Error(`ez.paginated: itemsName must not match reserved keys for cursor output (${Vr.join(`, `)})`);let o=t.coerce.number().int().min(1).max(i).default(a).describe(`Page size (number of ${r} per page)`);if(e===`offset`){let e=t.coerce.number().int().min(0).default(0).describe(`Number of ${r} to skip`);return{input:t.object({limit:o,offset:e}),output:t.object({[r]:t.array(n).describe(`Page of ${r}`),total:t.number().int().min(0).describe(`Total number of ${r}`),limit:t.number().int().min(1).describe(`Page size used`),offset:t.number().int().min(0).describe(`Offset used`)})}}let s=t.string().optional().describe(`Cursor for the next page; omit for first page`);return{input:t.object({cursor:s,limit:o}),output:t.object({[r]:t.array(n).describe(`Page of ${r}`),nextCursor:t.string().nullable().describe(`Cursor for the next page, or null if no more pages`),limit:t.number().int().min(1).describe(`Page size used`)})}}const Ur={dateIn:we,dateOut:Te,form:je,upload:Ne,raw:Ie,buffer:Ce,paginated:Hr};export{gt as BuiltinLogger,rr as Documentation,P as DocumentationError,G as EndpointsFactory,zr as EventStreamFactory,F as InputValidationError,Nr as Integration,V as Middleware,ke as MissingPeerError,Oe as OutputValidationError,U as ResultHandler,N as RoutingError,_t as ServeStatic,ut as arrayEndpointsFactory,nt as arrayResultHandler,ln as attachRouting,st as createCacheMiddleware,se as createConfig,ct as createCookieMiddleware,un as createServer,lt as defaultEndpointsFactory,W as defaultResultHandler,z as ensureHttpError,Ur as ez,S as getMessageFromError,cr as testEndpoint,lr as testMiddleware};
|
package/package.json
CHANGED