express-zod-api 29.8.2 → 30.0.0-beta.1
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 +58 -0
- package/README.md +21 -53
- package/SECURITY.md +1 -0
- package/dist/documentation-helpers-Df2sKJq9.js +1 -0
- package/dist/documentation.d.ts +12 -16
- package/dist/documentation.js +1 -1
- package/dist/{errors-Dbnie2Mk.d.ts → errors-masq5u05.d.ts} +6 -20
- package/dist/index.d.ts +179 -397
- package/dist/index.js +3 -3
- package/dist/integration.d.ts +8 -21
- package/dist/integration.js +8 -9
- package/dist/{peer-helpers-BguVeFhx.js → peer-helpers-CURhdLch.js} +1 -1
- package/dist/{routing-oAHiW3zy.d.ts → routing-BE8APxgy.d.ts} +74 -168
- package/dist/routing-walker-BpLERmiE.js +1 -0
- package/package.json +5 -5
- package/dist/documentation-helpers-C5Tkir01.js +0 -1
- package/dist/routing-walker-CelPngqp.js +0 -1
|
@@ -123,42 +123,31 @@ type Base = object & {
|
|
|
123
123
|
/** @desc The type allowed on the top level of Middlewares and Endpoints */
|
|
124
124
|
type IOSchema = z.ZodType<Base>;
|
|
125
125
|
/** EndpointsFactory schema extended type when adding a Middleware */
|
|
126
|
-
type Extension<Current extends IOSchema | undefined, Inc extends IOSchema | undefined> = Current extends IOSchema
|
|
127
|
-
? Inc extends IOSchema
|
|
128
|
-
? z.ZodIntersection<Current, Inc>
|
|
129
|
-
: Current
|
|
130
|
-
: Inc;
|
|
126
|
+
type Extension<Current extends IOSchema | undefined, Inc extends IOSchema | undefined> = Current extends IOSchema ? Inc extends IOSchema ? z.ZodIntersection<Current, Inc> : Current : Inc;
|
|
131
127
|
/** The Endpoint input schema type, condition wrapped into schema to make it z.output-compatible */
|
|
132
|
-
type FinalInputSchema<FIN extends IOSchema | undefined, BIN extends IOSchema> = z.ZodIntersection<
|
|
133
|
-
FIN extends IOSchema ? FIN : BIN,
|
|
134
|
-
BIN
|
|
135
|
-
>;
|
|
128
|
+
type FinalInputSchema<FIN extends IOSchema | undefined, BIN extends IOSchema> = z.ZodIntersection<FIN extends IOSchema ? FIN : BIN, BIN>;
|
|
136
129
|
type ResultSchema<R extends Result> = R extends Result<infer S> ? S : never;
|
|
137
|
-
type DiscriminatedResult =
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
error: Error;
|
|
145
|
-
};
|
|
130
|
+
type DiscriminatedResult = {
|
|
131
|
+
output: FlatObject;
|
|
132
|
+
error: null;
|
|
133
|
+
} | {
|
|
134
|
+
output: null;
|
|
135
|
+
error: Error;
|
|
136
|
+
};
|
|
146
137
|
/**
|
|
147
138
|
* @example InputValidationError —> BadRequest(400)
|
|
148
139
|
* @example Error —> InternalServerError(500)
|
|
149
140
|
* */
|
|
150
141
|
declare const ensureHttpError: (error: Error) => HttpError;
|
|
151
|
-
type Handler$2<RES = unknown> = (
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
},
|
|
161
|
-
) => void | Promise<void>;
|
|
142
|
+
type Handler$2<RES = unknown> = (params: DiscriminatedResult & {
|
|
143
|
+
/** null in case of failure to parse or to find the matching endpoint (error: not found) */
|
|
144
|
+
input: FlatObject | null;
|
|
145
|
+
/** can be empty: check the presence of the required property using the "in" operator */
|
|
146
|
+
ctx: FlatObject;
|
|
147
|
+
request: Request;
|
|
148
|
+
response: Response<RES>;
|
|
149
|
+
logger: ActualLogger;
|
|
150
|
+
}) => void | Promise<void>;
|
|
162
151
|
/**
|
|
163
152
|
* @desc Result definition for ResultHandler: a plain schema (for JSON and default status codes) or custom ApiResponse.
|
|
164
153
|
* @see ApiResponse
|
|
@@ -167,6 +156,7 @@ type Result<S extends z.ZodType = z.ZodType> = S | ApiResponse<S> | ApiResponse<
|
|
|
167
156
|
/** @desc A function that lazily produces a Result definition. */
|
|
168
157
|
type LazyResult<R extends Result, A extends unknown[] = []> = (...args: A) => R;
|
|
169
158
|
declare abstract class AbstractResultHandler {
|
|
159
|
+
#private;
|
|
170
160
|
protected constructor(handler: Handler$2);
|
|
171
161
|
execute(...params: Parameters<Handler$2>): Promise<void>;
|
|
172
162
|
}
|
|
@@ -176,6 +166,7 @@ declare abstract class AbstractResultHandler {
|
|
|
176
166
|
* @see Result
|
|
177
167
|
* */
|
|
178
168
|
declare class ResultHandler<POS extends Result, NEG extends Result> extends AbstractResultHandler {
|
|
169
|
+
#private;
|
|
179
170
|
constructor(params: {
|
|
180
171
|
/** @desc A description of the API response in case of success (schema, status code, MIME type) */
|
|
181
172
|
positive: POS | LazyResult<POS, [IOSchema]>;
|
|
@@ -186,49 +177,45 @@ declare class ResultHandler<POS extends Result, NEG extends Result> extends Abst
|
|
|
186
177
|
});
|
|
187
178
|
}
|
|
188
179
|
/**
|
|
189
|
-
* @desc The default ResultHandler
|
|
190
|
-
* and errors in `{ status: "error", error: { message } }`. Responds with JSON Content-Type.
|
|
180
|
+
* @desc The default ResultHandler relaying Endpoint output and error messages. Responds with JSON Content-Type.
|
|
191
181
|
* Respects the status of errors from createHttpError(), others become InternalServerError (500).
|
|
192
182
|
* @see ensureHttpError
|
|
193
183
|
* */
|
|
194
|
-
declare const defaultResultHandler: ResultHandler<
|
|
195
|
-
z.
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
z.core.$strip
|
|
213
|
-
>
|
|
214
|
-
>;
|
|
184
|
+
declare const defaultResultHandler: ResultHandler<IOSchema, z.ZodObject<{
|
|
185
|
+
message: z.ZodString;
|
|
186
|
+
}, z.core.$strip>>;
|
|
187
|
+
/**
|
|
188
|
+
* @deprecated Use defaultResultHandler for new APIs.
|
|
189
|
+
* @desc For migration purposes: preserves the response shapes of v0–v29.
|
|
190
|
+
* @example `{ status: "success", data: {...} }` and `{ status: "error", error: {...} }`.
|
|
191
|
+
* @todo remove in v31
|
|
192
|
+
* */
|
|
193
|
+
declare const legacyResultHandler: ResultHandler<z.ZodObject<{
|
|
194
|
+
status: z.ZodLiteral<"success">;
|
|
195
|
+
data: IOSchema;
|
|
196
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
197
|
+
status: z.ZodLiteral<"error">;
|
|
198
|
+
error: z.ZodObject<{
|
|
199
|
+
message: z.ZodString;
|
|
200
|
+
}, z.core.$strip>;
|
|
201
|
+
}, z.core.$strip>>;
|
|
215
202
|
/**
|
|
216
203
|
* @deprecated Resist the urge of using it: this handler is designed only to simplify the migration of legacy APIs.
|
|
217
204
|
* @desc Responding with an array is a bad practice keeping your endpoints from evolving without breaking changes.
|
|
218
205
|
* @desc This handler expects your endpoint to have the property 'items' in the output object schema
|
|
219
206
|
* */
|
|
220
|
-
declare const arrayResultHandler: ResultHandler<
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
mimeType: string;
|
|
225
|
-
}
|
|
226
|
-
>;
|
|
207
|
+
declare const arrayResultHandler: ResultHandler<z.ZodArray<z.core.$ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>> | z.ZodArray<z.ZodAny>, {
|
|
208
|
+
schema: z.ZodString;
|
|
209
|
+
mimeType: string;
|
|
210
|
+
}>;
|
|
227
211
|
/** @desc Returns child logger for the given request (if configured) or the configured logger otherwise */
|
|
228
212
|
type GetLogger = (request?: Request) => ActualLogger;
|
|
229
213
|
type InputSource = keyof Pick<Request, "query" | "body" | "files" | "params" | "headers" | "cookies" | "signedCookies">;
|
|
230
214
|
type InputSources = Record<Method, InputSource[]>;
|
|
231
|
-
type ChildLoggerProvider = (params: {
|
|
215
|
+
type ChildLoggerProvider = (params: {
|
|
216
|
+
request: Request;
|
|
217
|
+
parent: ActualLogger;
|
|
218
|
+
}) => ActualLogger | Promise<ActualLogger>;
|
|
232
219
|
type LogAccess = (request: Request, logger: ActualLogger) => void;
|
|
233
220
|
interface CommonConfig {
|
|
234
221
|
/**
|
|
@@ -295,24 +282,15 @@ interface CommonConfig {
|
|
|
295
282
|
* @desc In that case, async refinements and transformations execute twice, so avoid side effects in them.
|
|
296
283
|
* @example true — parses sync schemas ~1.3x faster, but it retries async ones (first request to the endpoint only).
|
|
297
284
|
* @example false — always uses .parseAsync() and does not support compiled schemas (legacy behavior).
|
|
298
|
-
* @default
|
|
299
|
-
* @todo remove in v30 or enable by default
|
|
285
|
+
* @default true
|
|
300
286
|
*/
|
|
301
287
|
trySyncValidation?: boolean;
|
|
302
288
|
}
|
|
303
|
-
type BeforeUpload = (params: {
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
| "safeFileNames"
|
|
309
|
-
| "preserveExtension"
|
|
310
|
-
| "useTempFiles"
|
|
311
|
-
| "tempFileDir"
|
|
312
|
-
| "debug"
|
|
313
|
-
| "uploadTimeout"
|
|
314
|
-
| "limits"
|
|
315
|
-
> & {
|
|
289
|
+
type BeforeUpload = (params: {
|
|
290
|
+
request: Request;
|
|
291
|
+
logger: ActualLogger;
|
|
292
|
+
}) => void | Promise<void>;
|
|
293
|
+
type UploadOptions = Pick<fileUpload.Options, "createParentPath" | "uriDecodeFileNames" | "safeFileNames" | "preserveExtension" | "useTempFiles" | "tempFileDir" | "debug" | "uploadTimeout" | "limits"> & {
|
|
316
294
|
/**
|
|
317
295
|
* @desc The error to throw when the file exceeds the configured fileSize limit (handled by errorHandler).
|
|
318
296
|
* @see limits
|
|
@@ -330,10 +308,7 @@ interface CookieParserOptions extends cookieParser.CookieParseOptions {
|
|
|
330
308
|
/** @desc The secret string or array used by cookie-parser for signed cookies */
|
|
331
309
|
secret?: Parameters<typeof cookieParser>[0];
|
|
332
310
|
}
|
|
333
|
-
type CompressionOptions = Pick<
|
|
334
|
-
compression.CompressionOptions,
|
|
335
|
-
"threshold" | "level" | "strategy" | "chunkSize" | "memLevel"
|
|
336
|
-
>;
|
|
311
|
+
type CompressionOptions = Pick<compression.CompressionOptions, "threshold" | "level" | "strategy" | "chunkSize" | "memLevel">;
|
|
337
312
|
interface GracefulOptions {
|
|
338
313
|
/**
|
|
339
314
|
* @desc Time given to drain ongoing requests before closing the server.
|
|
@@ -549,15 +524,7 @@ interface OAuth2Security<S extends string> {
|
|
|
549
524
|
* @param K is an optional input field used by InputSecurity
|
|
550
525
|
* @param S is an optional union of scopes used by OAuth2Security
|
|
551
526
|
* */
|
|
552
|
-
type Security<K extends string = string, S extends string = string> = (
|
|
553
|
-
| BasicSecurity
|
|
554
|
-
| BearerSecurity
|
|
555
|
-
| InputSecurity<K>
|
|
556
|
-
| HeaderSecurity
|
|
557
|
-
| CookieSecurity
|
|
558
|
-
| OpenIdSecurity
|
|
559
|
-
| OAuth2Security<S>
|
|
560
|
-
) & {
|
|
527
|
+
type Security<K extends string = string, S extends string = string> = (BasicSecurity | BearerSecurity | InputSecurity<K> | HeaderSecurity | CookieSecurity | OpenIdSecurity | OAuth2Security<S>) & {
|
|
561
528
|
deprecated?: boolean;
|
|
562
529
|
};
|
|
563
530
|
declare const frozenSetBrand: unique symbol;
|
|
@@ -607,7 +574,7 @@ declare abstract class AbstractMiddleware {
|
|
|
607
574
|
request: Request;
|
|
608
575
|
response: Response;
|
|
609
576
|
logger: ActualLogger;
|
|
610
|
-
config
|
|
577
|
+
config: CommonConfig;
|
|
611
578
|
}): Promise<FlatObject>;
|
|
612
579
|
}
|
|
613
580
|
/**
|
|
@@ -615,18 +582,9 @@ declare abstract class AbstractMiddleware {
|
|
|
615
582
|
* next middlewares and the Endpoint handler. Can also declare security schemas for Documentation.
|
|
616
583
|
* @see EndpointsFactory#addMiddleware
|
|
617
584
|
* */
|
|
618
|
-
declare class Middleware<
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
SCO extends string,
|
|
622
|
-
IN extends IOSchema | undefined = undefined,
|
|
623
|
-
> extends AbstractMiddleware {
|
|
624
|
-
constructor({
|
|
625
|
-
input,
|
|
626
|
-
security,
|
|
627
|
-
statusCode,
|
|
628
|
-
handler,
|
|
629
|
-
}: {
|
|
585
|
+
declare class Middleware<CTX extends FlatObject, RET extends FlatObject, SCO extends string, IN extends IOSchema | undefined = undefined> extends AbstractMiddleware {
|
|
586
|
+
#private;
|
|
587
|
+
constructor({ input, security, statusCode, handler }: {
|
|
630
588
|
/**
|
|
631
589
|
* @desc Input schema of the Middleware, combining properties from all the enabled input sources
|
|
632
590
|
* @default undefined
|
|
@@ -644,17 +602,13 @@ declare class Middleware<
|
|
|
644
602
|
handler: Handler$1<z.output<IN>, CTX, RET>;
|
|
645
603
|
});
|
|
646
604
|
/** @throws InputValidationError */
|
|
647
|
-
execute({
|
|
648
|
-
input,
|
|
649
|
-
config,
|
|
650
|
-
...rest
|
|
651
|
-
}: {
|
|
605
|
+
execute({ input, config, ...rest }: {
|
|
652
606
|
input: unknown;
|
|
653
607
|
ctx: CTX;
|
|
654
608
|
request: Request;
|
|
655
609
|
response: Response;
|
|
656
610
|
logger: ActualLogger;
|
|
657
|
-
config
|
|
611
|
+
config: CommonConfig;
|
|
658
612
|
}): Promise<RET>;
|
|
659
613
|
}
|
|
660
614
|
/**
|
|
@@ -662,26 +616,15 @@ declare class Middleware<
|
|
|
662
616
|
* Optionally, a `provider` can extend the context, and a `transformer` can convert caught errors.
|
|
663
617
|
* @see EndpointsFactory#addExpressMiddleware
|
|
664
618
|
* */
|
|
665
|
-
declare class ExpressMiddleware<R extends Request, S extends Response, RET extends FlatObject> extends Middleware<
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
transformer,
|
|
675
|
-
statusCode,
|
|
676
|
-
}?: {
|
|
677
|
-
/** @desc Extracts context properties from request and response after the native middleware execution. */
|
|
678
|
-
provider?: (request: R, response: S) => RET | Promise<RET>;
|
|
679
|
-
/** @desc Transforms errors caught from the native middleware before they propagate further. */
|
|
680
|
-
transformer?: (err: Error) => Error;
|
|
681
|
-
/** @desc The status code(s) the Middleware may interrupt the request handling (used by Documentation). */
|
|
682
|
-
statusCode?: number | [number, ...number[]];
|
|
683
|
-
},
|
|
684
|
-
);
|
|
619
|
+
declare class ExpressMiddleware<R extends Request, S extends Response, RET extends FlatObject> extends Middleware<FlatObject, RET, string> {
|
|
620
|
+
constructor(nativeMw: (request: R, response: S, next: NextFunction) => any, { provider, transformer, statusCode }?: {
|
|
621
|
+
/** @desc Extracts context properties from request and response after the native middleware execution. */
|
|
622
|
+
provider?: (request: R, response: S) => RET | Promise<RET>;
|
|
623
|
+
/** @desc Transforms errors caught from the native middleware before they propagate further. */
|
|
624
|
+
transformer?: (err: Error) => Error;
|
|
625
|
+
/** @desc The status code(s) the Middleware may interrupt the request handling (used by Documentation). */
|
|
626
|
+
statusCode?: number | [number, ...number[]];
|
|
627
|
+
});
|
|
685
628
|
}
|
|
686
629
|
type Handler<IN, OUT, CTX> = (params: {
|
|
687
630
|
/** @desc The inputs from the enabled input sources validated against the final input schema (incl. Middlewares) */
|
|
@@ -704,6 +647,7 @@ declare abstract class AbstractEndpoint {
|
|
|
704
647
|
}): Promise<void>;
|
|
705
648
|
}
|
|
706
649
|
declare class Endpoint<IN extends IOSchema, OUT extends IOSchema, CTX extends FlatObject> extends AbstractEndpoint {
|
|
650
|
+
#private;
|
|
707
651
|
constructor(def: {
|
|
708
652
|
deprecated?: boolean;
|
|
709
653
|
middlewares?: AbstractMiddleware[];
|
|
@@ -720,12 +664,7 @@ declare class Endpoint<IN extends IOSchema, OUT extends IOSchema, CTX extends Fl
|
|
|
720
664
|
statusCodes: ReadonlySet<number>;
|
|
721
665
|
});
|
|
722
666
|
deprecated(): this;
|
|
723
|
-
execute({
|
|
724
|
-
request,
|
|
725
|
-
response,
|
|
726
|
-
logger,
|
|
727
|
-
config,
|
|
728
|
-
}: {
|
|
667
|
+
execute({ request, response, logger, config }: {
|
|
729
668
|
request: Request;
|
|
730
669
|
response: Response;
|
|
731
670
|
logger: ActualLogger;
|
|
@@ -734,6 +673,7 @@ declare class Endpoint<IN extends IOSchema, OUT extends IOSchema, CTX extends Fl
|
|
|
734
673
|
}
|
|
735
674
|
type OriginalStatic = typeof express.static;
|
|
736
675
|
declare class ServeStatic {
|
|
676
|
+
#private;
|
|
737
677
|
constructor(...params: Parameters<OriginalStatic>);
|
|
738
678
|
}
|
|
739
679
|
/**
|
|
@@ -747,38 +687,4 @@ declare class ServeStatic {
|
|
|
747
687
|
interface Routing {
|
|
748
688
|
[K: string]: Routing | AbstractEndpoint | ServeStatic;
|
|
749
689
|
}
|
|
750
|
-
export {
|
|
751
|
-
AbstractLogger as A,
|
|
752
|
-
ensureHttpError as C,
|
|
753
|
-
ClientMethod as D,
|
|
754
|
-
IOSchema as E,
|
|
755
|
-
ResponseVariant as M,
|
|
756
|
-
createApiResponse as N,
|
|
757
|
-
Method as O,
|
|
758
|
-
defaultResultHandler as S,
|
|
759
|
-
FinalInputSchema as T,
|
|
760
|
-
ServerConfig as _,
|
|
761
|
-
Handler as a,
|
|
762
|
-
ResultHandler as b,
|
|
763
|
-
Middleware as c,
|
|
764
|
-
FlatObject as d,
|
|
765
|
-
Tag as f,
|
|
766
|
-
CommonConfig as g,
|
|
767
|
-
AppConfig as h,
|
|
768
|
-
Endpoint as i,
|
|
769
|
-
LoggerOverrides as j,
|
|
770
|
-
BuiltinLogger as k,
|
|
771
|
-
EmptyObject as l,
|
|
772
|
-
getMessageFromError as m,
|
|
773
|
-
ServeStatic as n,
|
|
774
|
-
AbstractMiddleware as o,
|
|
775
|
-
TagOverrides as p,
|
|
776
|
-
AbstractEndpoint as r,
|
|
777
|
-
ExpressMiddleware as s,
|
|
778
|
-
Routing as t,
|
|
779
|
-
EmptySchema as u,
|
|
780
|
-
createConfig as v,
|
|
781
|
-
Extension as w,
|
|
782
|
-
arrayResultHandler as x,
|
|
783
|
-
AbstractResultHandler as y,
|
|
784
|
-
};
|
|
690
|
+
export { BuiltinLogger as A, legacyResultHandler as C, IOSchema as D, FinalInputSchema as E, LoggerOverrides as M, ResponseVariant as N, ClientMethod as O, createApiResponse as P, defaultResultHandler as S, Extension as T, ServerConfig as _, Handler as a, ResultHandler as b, Middleware as c, FlatObject as d, Tag as f, CommonConfig as g, AppConfig as h, Endpoint as i, AbstractLogger as j, Method as k, EmptyObject as l, getMessageFromError as m, ServeStatic as n, AbstractMiddleware as o, TagOverrides as p, AbstractEndpoint as r, ExpressMiddleware as s, Routing as t, EmptySchema as u, createConfig as v, ensureHttpError as w, arrayResultHandler as x, AbstractResultHandler as y };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{globalRegistry as e,z as t}from"zod";import*as n from"ramda";import{isPromise as r}from"node:util/types";import i,{isHttpError as a}from"http-errors";import o from"express";const s={json:`application/json`,upload:`multipart/form-data`,raw:`application/octet-stream`,sse:`text/event-stream`,form:`application/x-www-form-urlencoded`},c=[`get`,`post`,`put`,`delete`,`patch`,`query`],l=[...c,`head`],u=Set.prototype.has.bind(new Set(c)),d=t.compile(t.object({})),ee=e=>!!(e._zod.run.__originalRun||e._zod.bag.validator||e._zod.bag.fallbackRun),f=/* @__PURE__ */ new WeakMap,p=e=>{if(ee(e))return e;let n=f.get(e);if(n)return n;let r=t.compile(e);return f.set(e,r),r},m=/:([A-Za-z0-9_]+)/g,te=e=>e.match(m)?.map(e=>e.slice(1))||[],ne=(e,t=1)=>e.replace(m,()=>`:${t++}`),re=e=>{let t=(e.header(`content-type`)||``).toLowerCase().startsWith(s.upload);return`files`in e&&t},ie={get:[`query`,`params`],post:[`body`,`params`,`files`],put:[`body`,`params`],patch:[`body`,`params`],delete:[`query`,`params`],query:[`query`,`body`,`params`]},ae=[`body`,`query`,`params`],h=e=>e.method.toLowerCase(),g=(e,t={})=>{if(e===`options`)return[];let n=e===`head`?`get`:u(e)?e:void 0;return(n?t[n]||ie[n]:void 0)||ae},_=(e,t={})=>{let n=h(e);return g(n,t).filter(t=>t!==`files`||re(e)).reduce((t,n)=>Object.assign(t,e[n]),{})},v=e=>e instanceof Error?e:e instanceof t.ZodError?new t.ZodRealError(e.issues):Error(String(e)),y=async(e,n,{trySyncValidation:r=!0},i)=>{if(!r||i?.isAsync)return e.parseAsync(n);try{return e.parse(n)}catch(r){if(r instanceof t.core.$ZodAsyncError)return i&&(i.isAsync=!0),e.parseAsync(n);throw r}},b=e=>e instanceof t.ZodError?e.issues.map(({path:e,message:n})=>`${e.length?`${t.core.toDotPath(e)}: `:``}${n}`).join(`; `):e.message,x=(e,t)=>w(e)&&`_zod`in e&&(!t||n.path([`_zod`,`def`,`type`],e)===t),S=(e,t,r)=>e.length&&t.length?n.xprod(e,t).map(r):e.concat(t),C=e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase(),oe=(...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(C).join(``)},se=n.tryCatch((e,n)=>typeof t.parse(e,n),n.always(void 0)),w=e=>typeof e==`object`&&!!e,T={_cache:void 0,get env(){return T._cache??=process.env.NODE_ENV??`development`},get isProduction(){return T.env===`production`}},ce=(e,t)=>!!t&&e!==`head`,E=`x-brand`,le=t=>{let{[E]:n}=e.get(t)||{};if(typeof n==`symbol`||typeof n==`string`||typeof n==`number`)return n},D=t=>{let{examples:n}=e.get(t)||{};return Array.isArray(n)?n:[]},O=Symbol(`Buffer`),k=()=>t.custom(e=>Buffer.isBuffer(e),{error:`Expected Buffer`}).meta({[E]:O}),A=Symbol(`DateIn`),ue=({examples:e,...n}={})=>t.union([t.iso.date(),t.iso.datetime({local:!0,offset:!0})]).meta({examples:e}).transform(e=>new Date(e)).pipe(t.date()).meta({...n,[E]:A}),j=Symbol(`DateOut`),de=(e={})=>t.date().transform(e=>e.toISOString()).pipe(t.iso.datetime()).meta({...e,[E]:j});var M=class extends Error{name=`RoutingError`;cause;constructor(e,t,n){super(e),this.cause={method:t,path:n}}},fe=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.`}},N=class extends Error{name=`IOSchemaError`},pe=class extends N{cause;name=`DeepCheckError`;constructor(e){super(`Found`,{cause:e}),this.cause=e}},P=class extends N{cause;name=`OutputValidationError`;constructor(e){let n=new t.ZodError(e.issues.map(({path:e,...t})=>({...t,path:[`output`,...e]})));super(b(n),{cause:e}),this.cause=e}},F=class extends N{cause;name=`InputValidationError`;constructor(e){super(b(e),{cause:e}),this.cause=e}},I=class extends Error{cause;handled;name=`ResultHandlerError`;constructor(e,t){super(b(e),{cause:e}),this.cause=e,this.handled=t}},me=class extends Error{name=`MissingPeerError`;constructor(e){super(`Missing peer dependency: ${e}. Please install it to use the feature.`)}};const L=Symbol(`Upload`),he=e=>w(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,ge=()=>t.custom(e=>he(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({[E]:L}),R=Symbol(`Raw`),z=t.object({raw:k()}),_e=e=>z.extend(e).meta({[E]:R});function ve(e){return e?_e(e):z.meta({[E]:R})}const B=(e,{io:r,condition:i})=>n.tryCatch(()=>void t.toJSONSchema(e,{io:r,unrepresentable:`any`,override:e=>{if(i(e))throw new pe(e)}}),e=>e.cause)(),ye=(e,{io:r})=>{let i=t.toJSONSchema(e,{io:r,unrepresentable:`any`}),{$ref:a}=i,o=[i];for(let e=0;e<o.length;e++){let t=o[e];if(n.is(Object,t)){let{$ref:r}=t;if(r===`#`||e&&r&&r===a)return!0;o.push(...n.values(t))}n.is(Array,t)&&o.push(...n.values(t))}return!1},be=/* @__PURE__ */ new Set([`nan`,`symbol`,`map`,`set`,`bigint`,`void`,`promise`,`never`,`function`]),xe=(e,t)=>B(e,{io:t,condition:({zodSchema:e,jsonSchema:{[E]:n}})=>{let{type:r}=e._zod.def;return!!(be.has(r)||n===O||t===`input`&&(r===`date`||n===j)||t===`output`&&(n===A||n===R||n===L))}}),V=Symbol(`Form`),Se=e=>(e instanceof t.ZodObject?e:t.object(e)).meta({[E]:V});var H=class e extends Set{constructor(e){if(super(),e)for(let t of e)Set.prototype.add.call(this,t)}add(e){throw TypeError(`Can not add to the read only Set`)}delete(e){throw TypeError(`Can not delete from the read only Set`)}clear(){throw TypeError(`Can not clear the read only Set`)}union(t){return new e(super.union(t))}intersection(t){return new e(super.intersection(t))}difference(t){return new e(super.difference(t))}symmetricDifference(t){return new e(super.symmetricDifference(t))}},Ce=class{},U=class extends Ce{#e;#t={isAsync:!1};#n;#r;#i;constructor({input:e,security:t,statusCode:n,handler:r}){super(),this.#e=e&&p(e),this.#n=t,this.#r=new H(typeof n==`number`?[n]:n),this.#i=r}get security(){return this.#n}get schema(){return this.#e}get statusCodes(){return this.#r}async execute({input:e,config:n,...r}){try{let t=await y(this.#e||d,e,n,this.#t);return this.#i({...r,input:t})}catch(e){throw e instanceof t.ZodError?new F(e):e}}},W=class extends U{constructor(e,{provider:t=()=>({}),transformer:n=e=>e,statusCode:i}={}){super({statusCode:i,handler:async({request:i,response:a})=>{let{promise:o,resolve:s,reject:c}=Promise.withResolvers(),l=e=>{if(e&&e instanceof Error)return c(n(e));s(t(i,a))},u=e(i,a,l);return r(u)&&u.catch(l),o}})}};const G={positive:200,negative:400},we=Object.keys(G),K=e=>e<400;function Te(e){return e instanceof t.ZodType?{schema:e}:e}const Ee=(e,{variant:r,args:i})=>{typeof e==`function`&&(e=e(...i));let a={statusCodes:[G[r]],mimeTypes:[s.json]};if(e instanceof t.ZodType)return[{schema:e,...a}];if(Array.isArray(e)&&!e.length)throw new I(/* @__PURE__ */ Error(`At least one ${r} response schema required.`));let o=(Array.isArray(e)?e:[e]).map(({schema:e,statusCode:t,mimeType:n})=>({schema:e,statusCodes:typeof t==`number`?[t]:t||a.statusCodes,mimeTypes:typeof n==`string`?[n]:n===void 0?a.mimeTypes:n})),c=n.chain(n.prop(`statusCodes`),o),l=c.find(e=>K(e)===(r===`negative`));if(l!==void 0)throw new I(/* @__PURE__ */ Error(`The status code ${l} is not valid for a ${r} API response.`));if(o.length>1){let e=n.find(e=>c.indexOf(e)!==c.lastIndexOf(e),c);if(e!==void 0)throw new I(/* @__PURE__ */ Error(`The status code ${e} is used by multiple response schemas.`))}return o},De=(e,t,n)=>{let r=new Set(Array.from(t).filter(e=>K(e)===(n===`positive`)));if(!r.size)return e;if(e.length===1)return e.map(e=>({...e,statusCodes:Array.from(r)}));let i=[],a=e.reduce((e,{statusCodes:t,...n})=>{let a=new Set(t).intersection(r);return a.size?(i.push({...n,statusCodes:Array.from(a)}),e.difference(a)):e},new Set(r));if(a.size){let e=Array.from(a).join(`, `),t=a.size>1;throw new I(/* @__PURE__ */ Error(`The ResultHandler defines multiple ${n} response schemas, but the overriding status code${t?`s`:``} ${e} of the Endpoint ${t?`are`:`is`} not listed for any of them, therefore it is unclear how such override${t?`s`:``} would be handled. Consider adding ${t?`them`:`it`} to ResultHandler.`))}return i},Oe=(e,t,{url:n},r)=>!e.expose&&t.error(`Server side error`,{error:e,url:n,payload:r}),ke=e=>a(e)?e:i(e instanceof F?400:500,b(e),{cause:e.cause||e}),Ae=e=>T.isProduction&&!e.expose?i(e.statusCode).message:e.message,je=e=>Object.entries(e._zod.def.shape).reduce((e,[t,r])=>S(e,D(r).map(n.objOf(t)),([e,t])=>({...e,...t})),[]);var q=class{nest(e){return{...e,"":this}}},Me=class r extends q{#e;#t;#n={isAsync:!1};#r={isAsync:!1};#i=n.once(()=>{if(D(this.#e.outputSchema).length||!x(this.#e.outputSchema,`object`))return;let t=je(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}#a(e){return new r({...this.#e,...e})}deprecated(){return this.#a({deprecated:!0})}get isDeprecated(){return this.#e.deprecated||!1}get description(){return this.#e.description}get summary(){return this.#e.summary}get methods(){return this.#e.methods}get inputSchema(){return this.#e.inputSchema}get outputSchema(){return this.#e.outputSchema}getProbableRequestType(e){return e===`query`?`form`:this.#t??=(()=>{let e,t=t=>!!(e=t),n=!1;return B(this.#e.inputSchema,{io:`input`,condition:({jsonSchema:{[E]:e}})=>e===L?t(`upload`):e===R?t(`raw`):(e===V&&(n=!0),!1)}),e??(n?`form`:`json`)})()}getResponses(e){e===`positive`&&this.#i();let t=e===`negative`?this.#e.resultHandler.getNegativeResponse():this.#e.resultHandler.getPositiveResponse(this.#e.outputSchema);return Object.freeze(this.#e.statusCodes.size?De(t,this.#e.statusCodes,e):t)}get security(){let e=n.pluck(`security`,this.#e.middlewares||[]);return n.reject(n.isNil,e)}get scopes(){return this.#e.scopes}get tags(){return this.#e.tags}getOperationId(e){return this.#e.getOperationId?.(e)}async#o(e,n){try{return await y(this.#e.outputSchema,e,n,this.#r)}catch(e){throw e instanceof t.ZodError?new P(e):e}}async#s({method:e,logger:t,ctx:n,response:r,...i}){for(let a of this.#e.middlewares||[])if((e!==`options`||a instanceof W)&&(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#c({input:e,config:n,...r}){let i;try{i=await y(this.#e.inputSchema,e,n,this.#n)}catch(e){throw e instanceof t.ZodError?new F(e):e}return this.#e.handler({...r,input:i})}async#l(e){await this.#e.resultHandler.execute(e)}async execute({request:e,response:t,logger:n,config:r}){let i=h(e),a={},o,s=_(e,r.inputSources);try{if(await this.#s({method:i,input:s,request:e,response:t,logger:n,ctx:a,config:r}),t.writableEnded)return;if(i===`options`)return void t.status(200).end();let c=await this.#c({input:s,logger:n,config:r,ctx:a});if(t.writableEnded)return;o={output:await this.#o(c,r),error:null}}catch(e){o={output:null,error:v(e)}}await this.#l({...o,input:s,request:e,response:t,logger:n,ctx:a})}},J=class{#e;constructor(...e){this.#e=e}apply(e,t){return t(e,o.static(...this.#e))}};const Y=e=>w(e)&&`or`in e,X=e=>w(e)&&`and`in e,Z=e=>!X(e)&&!Y(e),Ne=e=>{let t=n.filter(Z,e),r=n.chain(n.prop(`and`),n.filter(X,e)),[i,a]=n.partition(Z,r),o=n.concat(t,i),s=n.filter(Y,e);return n.map(n.prop(`or`),n.concat(s,a)).reduce((e,t)=>S(e,n.map(e=>Z(e)?[e]:e.and,t),([e,t])=>n.concat(e,t)),n.reject(n.isEmpty,[o]))},Q=(e,t)=>X(e)?n.chain(e=>Q(e,t),e.and):Y(e)?n.chain(e=>Q(e,t),e.or):e.type===t?[e.name]:[],Pe=(e,t)=>new Set(n.chain(e=>Q(e,t),e)),Fe=e=>(t,...n)=>{e(t,...n),t===`get`&&e(`head`,...n)},Ie=e=>{let[t,n]=e.trim().split(/ (.+)/,2);return n&&u(t)?[n,t]:[e]},Le=e=>e.trim().split(`/`).filter(Boolean).join(`/`),Re=({recognizeMethodDependentRoutes:e=!0},t,n)=>Object.entries(t).map(([t,r])=>{let[i,a]=e&&u(t)&&r instanceof q?[`/`,t]:Ie(t);return[[n||``].concat(Le(i)||[]).join(`/`)||`/`,r,a]}),ze=(e,t)=>{throw new M(`Route with explicit method can only be assigned with Endpoint`,e,t)},Be=(e,t,n)=>{if(n.size&&!n.has(e))throw new M(`Method ${e} is not supported by the assigned Endpoint.`,e,t)},$=(e,t,n)=>{let r=t.includes(`:`)?ne(t):t,i=`${e} ${r}`;if(n.has(i))throw new M(`Route has a duplicate: the normalized path "${r}" is already registered`,e,t);n.add(i)},Ve=({routing:e,config:t,onEndpoint:n,onStatic:r})=>{let i=Re(t,e),a=/* @__PURE__ */ new Set;for(let e=0;e<i.length;e++){let[o,s,c]=i[e];if(s instanceof q){if(c)$(c,o,a),Be(c,o,s.methods),n(c,o,s);else{let{methods:e}=s;for(let t of e.size?e:[`get`])$(t,o,a),n(t,o,s)}}else c&&ze(c,o),s instanceof J?r&&s.apply(o,r):i.splice(e+1,0,...Re(t,s,o))}};export{ce as $,de as A,d as B,ge as C,P as D,me as E,O as F,te as G,_ as H,le as I,x as J,se as K,D as L,ue as M,A as N,I as O,k as P,T as Q,S as R,L as S,F as T,g as U,v as V,b as W,ne as X,oe as Y,m as Z,Se as _,J as a,R as b,Ae as c,Te as d,C as et,G as f,H as g,U as h,Ne as i,j,M as k,Oe as l,W as m,Fe as n,u as nt,Me as o,we as p,w as q,Pe as r,s as rt,ke as s,Ve as t,l as tt,Ee as u,xe as v,fe as w,ve as x,ye as y,p as z};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "express-zod-api",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "30.0.0-beta.1",
|
|
4
4
|
"description": "A Typescript framework to help you get an API server up and running with I/O schema validation and custom middlewares in minutes.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"ramda": "^0.32.0"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
|
-
"@express-zod-api/zod-plugin": "^
|
|
54
|
+
"@express-zod-api/zod-plugin": "^7.0.0-beta.1",
|
|
55
55
|
"@types/compression": "^1.7.5",
|
|
56
56
|
"@types/cookie-parser": "^1.4.10",
|
|
57
57
|
"@types/express": "^5.0.6",
|
|
@@ -63,8 +63,8 @@
|
|
|
63
63
|
"express-fileupload": "^1.5.0",
|
|
64
64
|
"express-rate-limit": "^7.5.1 || ^8.0.0",
|
|
65
65
|
"http-errors": "^2.0.1",
|
|
66
|
-
"typescript": "^
|
|
67
|
-
"zod": "^4.
|
|
66
|
+
"typescript": "^6.0.3",
|
|
67
|
+
"zod": "^4.5.4"
|
|
68
68
|
},
|
|
69
69
|
"peerDependenciesMeta": {
|
|
70
70
|
"@express-zod-api/zod-plugin": {
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
}
|
|
103
103
|
},
|
|
104
104
|
"devDependencies": {
|
|
105
|
-
"@express-zod-api/zod-plugin": "^
|
|
105
|
+
"@express-zod-api/zod-plugin": "^7.0.0-beta.1",
|
|
106
106
|
"@types/compression": "^1.8.1",
|
|
107
107
|
"@types/cookie-parser": "^1.4.10",
|
|
108
108
|
"@types/cors": "^2.8.19",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{$ as e,F as t,G as n,I as r,J as i,K as a,N as o,Q as s,R as c,S as l,W as u,X as d,b as f,j as p,nt as m,q as h,r as g,w as _}from"./routing-walker-CelPngqp.js";import{z as v}from"zod";import*as y from"ramda";import{isReferenceObject as b,isSchemaObject as x}from"openapi3-ts/oas32";const ee=e=>e.type===`object`,te=y.mergeDeepWith((e,t)=>{if(Array.isArray(e)&&Array.isArray(t))return y.concat(e,t);if(e===t)return t;throw Error(`Can not flatten properties`,{cause:{a:e,b:t}})}),S=new Set([`type`,`properties`,`required`,`examples`,`description`,`additionalProperties`]),C=e=>{for(let t of Object.keys(e))if(!S.has(t))return!1;return!0},w=y.pair(!0),ne=(e,t,n)=>!(`allOf`in e)||!e.allOf?[]:e.allOf.map(e=>{if(t===`throw`&&!(e.type===`object`&&C(e)))throw Error(`Can not merge`);return y.pair(n,e)}),re=e=>{let t=[];return e.anyOf&&t.push(...y.map(w,e.anyOf)),e.oneOf&&t.push(...y.map(w,e.oneOf)),t},ie=(e,t,n,r)=>{if(!a(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 o={...Object(e.additionalProperties)};for(let e of i)t.properties[e]??=o;r||n.push(...i)},ae=(e,t,n)=>{t.examples?.length&&(e.examples=n?y.concat(e.examples||[],t.examples):c(e.examples?.filter(a)||[],t.examples.filter(a),([e,t])=>y.mergeDeepRight(e,t)))},T=(e,t=`coerce`)=>{let n=[y.pair(!1,e)],r={type:`object`,properties:{}},i=[];for(let[e,a]of n)a.description&&(r.description??=a.description),n.push(...ne(a,t,e)),n.push(...re(a)),ae(r,a,e),ee(a)&&(n.push([e,{examples:E(a)}]),a.properties&&(r.properties=(t===`throw`?te:y.mergeDeepRight)(r.properties,a.properties),!e&&a.required&&i.push(...a.required)),ie(a,r,i,e));return i.length&&(r.required=[...new Set(i)]),r},E=e=>Object.entries(e.properties||{}).reduce((e,[t,n])=>{let{examples:r=[]}=a(n)?n:{};return c(e,r.map(y.objOf(t)),([e,t])=>({...e,...t}))},[]),D=`x-coerce`,O=new Set([`array`,`object`]),k=(e,t)=>{let n=[e.items,e.prefixItems,e.additionalItems,Object.values(e.properties??{}),e.additionalProperties,e.propertyNames];for(let e of n){if(!a(e))continue;let n=Array.isArray(e)?e:[e];for(let e of n)if(a(e)&&!A(e,t))return!1}return!0},A=(e,t)=>e[`x-coerce`]===!0?!0:e.anyOf?e.anyOf.some(e=>A(e,t)):e.oneOf?e.oneOf.some(e=>A(e,t)):e.allOf?e.allOf.every(e=>A(e,t)):e.type===void 0||e.type===`string`?!0:Array.isArray(e.type)?A({anyOf:e.type.map(t=>({...e,type:t}))},t):t!==`path`&&O.has(e.type)&&k(e,t);let j;const M=()=>j??=new Set([`session`,`session_id`,`sessionId`]);let N;const P=()=>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.connect-udp-bind.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.want-unencoded-digest.warning.x-content-type-options.x-frame-options`.split(`.`)),F={integer:0,number:0,string:``,boolean:!1,object:{},null:null,array:[]},I=e=>e.replace(d,e=>`{${e.slice(1)}}`),L=({},e)=>{if(e.isResponse)throw new _(`Please use ez.upload() only for input.`,e);return{type:`string`,format:`binary`}},R=({jsonSchema:e})=>({...e,externalDocs:{description:`raw binary data`,url:`https://swagger.io/specification/#working-with-binary-data`}}),z=({zodSchema:e,jsonSchema:t})=>{if(!h(e,`union`)||!(`discriminator`in e._zod.def))return t;let n=e._zod.def.discriminator;return{...t,discriminator:t.discriminator??{propertyName:n}}},B=y.tryCatch(({jsonSchema:e})=>{if(!e.allOf)throw`no allOf`;return T(e,`throw`)},(e,{jsonSchema:t})=>t),V=({jsonSchema:e})=>{if(!e.anyOf||!e.anyOf.length)return e;let t=e.anyOf[0];return Object.assign(t,{type:J(t.type)})},H=e=>e,U=({jsonSchema:e},t)=>{if(t.isResponse)throw new _(`Please use ez.dateOut() for output.`,t);return e},W=({jsonSchema:e},t)=>{if(!t.isResponse)throw new _(`Please use ez.dateIn() for input.`,t);return e},G=()=>({type:`string`,format:`bigint`,pattern:`^-?\\d+$`}),K=({zodSchema:e,jsonSchema:t})=>e._zod.def.rest===null?{...t,items:{not:{}}}:t,q=e=>{let t=Array.isArray(e.type)?e.type[0]:e.type;return F?.[t]},J=e=>e===`null`?e:typeof e==`string`?[e,`null`]:e&&[...new Set(e).add(`null`)],oe=new Set([`number`,`string`,`boolean`]),se=({zodSchema:e,jsonSchema:t},r)=>{let i=e._zod.def[r.isResponse?`out`:`in`],a=e._zod.def[r.isResponse?`in`:`out`];if(!h(i,`transform`))return t;let o=H(Z(a,{ctx:r}));if(x(o)){if(r.isResponse){let e=n(i,q(o));if(e&&oe.has(e))return{...t,type:e}}else{let{type:e,...t}=o;return{...t,format:`${t.format||e} (preprocessed)`}}}return t},ce=({jsonSchema:e})=>{if(e.type!==`object`)return e;let t=e;return!t.properties||!(`raw`in t.properties)||!a(t.properties.raw)?e:t.properties.raw},Y=e=>e.length?y.fromPairs(y.zip(y.times(e=>`example${e+1}`,e.length),y.map(y.objOf(`dataValue`),e))):void 0,le=(e,t)=>t?.has(e)||e.startsWith(`x-`)||P().has(e),ue=(e,t)=>t?.has(e)||M().has(e),de=({method:e,path:t,security:n,inputSources:r,isHeader:i,isCookie:a})=>{let o=new Set(u(t)),s=r.includes(`query`),c=r.includes(`body`),l=r.includes(`params`),d=r.includes(`headers`),f=r.includes(`cookies`)||r.includes(`signedCookies`),p;d&&n&&(p=g(n,`header`));let m;f&&n&&(m=g(n,`cookie`));let h=n=>a?.(n,e,t)??ue(n,m);return{pathParams:o,getLocation:n=>{if(l&&o.has(n)&&o.delete(n))return`path`;if(f&&h(n))return`cookie`;if(d&&(i?.(n,e,t)??le(n,p)))return`header`;if(!c){if(s)return`query`;if(f)return`cookie`}},isQueryEnabled:s,isBodyEnabled:c}},fe=({path:e,method:t,flatRequest:n,makeRef:r,composition:o,getLocation:s,description:c=`${t.toUpperCase()} ${e} Parameter`})=>{let l=[];for(let[e,t]of Object.entries(n.properties)){if(!a(t))continue;let u=s(e);if(!u)continue;let d=H(t),f=o===`components`?r(t.id||JSON.stringify(t),d,t.id||i(c,e)):d;l.push({name:e,in:u,deprecated:t.deprecated,required:n.required?.includes(e)||u===`path`,description:d.description||c,schema:f,examples:Y(x(d)&&d.examples?.length?d.examples:y.pluck(e,n.examples?.filter(y.both(a,y.has(e)))||[]))})}return l},X={nullable:V,union:z,bigint:G,intersection:B,tuple:K,pipe:se,[o]:U,[p]:W,[l]:L,[f]:ce,[t]:R},pe=(e,t,n)=>{let r=[e,t],i=e=>/schema\d+$/.test(e)?void 0:e;for(let e=0;e<r.length;e++){let a=r[e];if(y.is(Object,a)){if(b(a)&&!a.$ref.startsWith(`#/components`)){let e=a.$ref.split(`/`).pop(),r=t[e];if(r){let t=r.id||i(e);a.$ref=n.makeRef(t||r,H(r),t).$ref}continue}r.push(...y.values(a))}y.is(Array,a)&&r.push(...y.values(a))}return e},Z=(e,{ctx:t,rules:n=X})=>{let{$defs:i={},properties:o={}}=v.toJSONSchema(v.object({subject:e}),{unrepresentable:`any`,io:t.isResponse?`output`:`input`,override:e=>{let i=v.globalRegistry.get(e.zodSchema)?.id;if(i){let n=t.seenIds.get(i);if(n&&n!==e.zodSchema)throw new _(`The meta id "${i}" is used by two different schemas. Please make the ids unique or reuse the same schema instance.`,t);t.seenIds.set(i,e.zodSchema)}let a=r(e.zodSchema),o=n[a&&a in n?a:e.zodSchema._zod.def.type];if(o){let n={...o(e,t)};for(let t in e.jsonSchema)delete e.jsonSchema[t];Object.assign(e.jsonSchema,n)}}});return pe(a(o.subject)?o.subject:{},i,t)},Q=(e,t)=>{if(b(e))return[e,!1];let n=!1,r=y.map(e=>{let[r,i]=Q(e,t);return n||=i,r}),i=y.omit(t),a={properties:i,examples:y.map(i),required:y.without(t),allOf:r,oneOf:r,anyOf:r},o=y.evolve(a,e);return[o,n||!!o.required?.length]},me=({method:t,path:n,schema:r,mimeTypes:a,variant:o,makeRef:c,composition:l,hasMultipleStatusCodes:u,statusCode:d,brandHandling:f,seenIds:p,description:h=`${t.toUpperCase()} ${n} ${e(o)} response ${u?d:``}`.trim()})=>{if(!s(t,a))return{description:h};let g=H(Z(r,{rules:{...f,...X},ctx:{isResponse:!0,makeRef:c,path:n,method:t,seenIds:p}})),_=[];x(g)&&g.examples&&(_.push(...g.examples),delete g.examples);let v=l===`components`?c(r,g,i(h)):g;return{description:h,content:y.fromPairs(a.map(e=>[e,{[e===m.sse?`itemSchema`:`schema`]:v,examples:Y(_)}]))}},he=({format:e})=>{let t={type:`http`,scheme:`bearer`};return e&&(t.bearerFormat=e),t},ge=({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},_e=({name:e})=>({type:`apiKey`,in:`header`,name:e}),ve=({name:e})=>({type:`apiKey`,in:`cookie`,name:e}),ye=({url:e})=>({type:`openIdConnect`,openIdConnectUrl:e}),be=({flows:e={},oauth2MetadataUrl:t})=>({type:`oauth2`,flows:y.map(e=>({...e,scopes:e.scopes||{}}),y.reject(y.isNil,e)),oauth2MetadataUrl:t}),$=(e,t=[])=>{let n=e=>e.type===`basic`?{type:`http`,scheme:`basic`}:e.type===`bearer`?he(e):e.type===`input`?ge(e,t):e.type===`header`?_e(e):e.type===`cookie`?ve(e):e.type===`openid`?ye(e):be(e);return e.map(e=>e.map(({deprecated:e,...t})=>({...n(t),deprecated:e})))},xe=Set.prototype.has.bind(new Set([`oauth2`,`openIdConnect`])),Se=(e,t,n)=>{let r=Array.from(t);return e.map(e=>{let t={};for(let i of e){let e=n(i);t[e]=xe(i.type)?r:[]}return t})},Ce=({schema:e,brandHandling:t,makeRef:n,path:r,method:i,seenIds:a})=>Z(e,{rules:{...t,...X},ctx:{isResponse:!1,makeRef:n,path:r,method:i,seenIds:a}}),we=({method:e,path:t,bodyJsonSchema:n,hasRequiredBodyProps:r,flatRequest:o,mimeType:s,makeRef:c,composition:l,paramNames:u,description:d=`${e.toUpperCase()} ${t} Request body`})=>{let f=H(n),p=[];x(f)&&f.examples&&(p.push(...f.examples),delete f.examples);let h={schema:l===`components`?c(JSON.stringify(f),f,i(d)):f,examples:Y(p.length?p:o.examples?.filter(e=>a(e)&&!Array.isArray(e)).map(y.omit(u))||[])},g={description:d,content:{[s]:h}};return(r||s===m.raw)&&(g.required=!0),g},Te=e=>Object.entries(e).reduce((e,[t,n])=>{if(!n)return e;if(typeof n==`string`)return e.concat({name:t,description:n});let{url:r,...i}=n,a={...i,name:t};return r&&(a.externalDocs={...a.externalDocs,url:r}),e.concat(a)},[]),Ee=(e,t=50)=>!e||e.length<=t?e:e.slice(0,Math.max(1,t||0)-1)+`…`,De=e=>{let t=Array.from(e);return t.length?t:void 0};export{$ as a,Q as c,I as d,Ee as f,A as h,me as i,de as l,T as m,Ce as n,Se as o,D as p,fe as r,Te as s,we as t,De as u};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{globalRegistry as e,z as t}from"zod";import*as n from"ramda";import{isPromise as r}from"node:util/types";import i,{isHttpError as a}from"http-errors";import o from"express";const s={json:`application/json`,upload:`multipart/form-data`,raw:`application/octet-stream`,sse:`text/event-stream`,form:`application/x-www-form-urlencoded`},c=[`get`,`post`,`put`,`delete`,`patch`,`query`],l=[...c,`head`],u=Set.prototype.has.bind(new Set(c)),d=t.object({}),f=/:([A-Za-z0-9_]+)/g,ee=e=>e.match(f)?.map(e=>e.slice(1))||[],p=(e,t=1)=>e.replace(f,()=>`:${t++}`),te=e=>{let t=(e.header(`content-type`)||``).toLowerCase().startsWith(s.upload);return`files`in e&&t},ne={get:[`query`,`params`],post:[`body`,`params`,`files`],put:[`body`,`params`],patch:[`body`,`params`],delete:[`query`,`params`],query:[`query`,`body`,`params`]},re=[`body`,`query`,`params`],m=e=>e.method.toLowerCase(),h=(e,t={})=>{if(e===`options`)return[];let n=e===`head`?`get`:u(e)?e:void 0;return(n?t[n]||ne[n]:void 0)||re},g=(e,t={})=>{let n=m(e);return h(n,t).filter(t=>t!==`files`||te(e)).reduce((t,n)=>Object.assign(t,e[n]),{})},_=e=>e instanceof Error?e:e instanceof t.ZodError?new t.ZodRealError(e.issues):Error(String(e)),v=async(e,n,{trySyncValidation:r=!1},i)=>{if(!r||i?.isAsync)return e.parseAsync(n);try{return e.parse(n)}catch(r){if(r instanceof t.core.$ZodAsyncError)return i&&(i.isAsync=!0),e.parseAsync(n);throw r}},y=e=>e instanceof t.ZodError?e.issues.map(({path:e,message:n})=>`${e.length?`${t.core.toDotPath(e)}: `:``}${n}`).join(`; `):e.message,b=(e,t)=>C(e)&&`_zod`in e&&(!t||n.path([`_zod`,`def`,`type`],e)===t),x=(e,t,r)=>e.length&&t.length?n.xprod(e,t).map(r):e.concat(t),S=e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase(),ie=(...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(S).join(``)},ae=n.tryCatch((e,n)=>typeof t.parse(e,n),n.always(void 0)),C=e=>typeof e==`object`&&!!e,w={_cache:void 0,get env(){return w._cache??=process.env.NODE_ENV??`development`},get isProduction(){return w.env===`production`}},oe=(e,t)=>!!t&&e!==`head`,T=`x-brand`,se=t=>{let{[T]:n}=e.get(t)||{};if(typeof n==`symbol`||typeof n==`string`||typeof n==`number`)return n},E=t=>{let{examples:n}=e.get(t)||{};return Array.isArray(n)?n:[]},D=Symbol(`Buffer`),O=()=>t.custom(e=>Buffer.isBuffer(e),{error:`Expected Buffer`}).meta({[T]:D}),k=Symbol(`DateIn`),ce=({examples:e,...n}={})=>t.union([t.iso.date(),t.iso.datetime({local:!0,offset:!0})]).meta({examples:e}).transform(e=>new Date(e)).pipe(t.date()).meta({...n,[T]:k}),A=Symbol(`DateOut`),le=(e={})=>t.date().transform(e=>e.toISOString()).pipe(t.iso.datetime()).meta({...e,[T]:A});var j=class extends Error{name=`RoutingError`;cause;constructor(e,t,n){super(e),this.cause={method:t,path:n}}},ue=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.`}},M=class extends Error{name=`IOSchemaError`},de=class extends M{cause;name=`DeepCheckError`;constructor(e){super(`Found`,{cause:e}),this.cause=e}},N=class extends M{cause;name=`OutputValidationError`;constructor(e){let n=new t.ZodError(e.issues.map(({path:e,...t})=>({...t,path:[`output`,...e]})));super(y(n),{cause:e}),this.cause=e}},P=class extends M{cause;name=`InputValidationError`;constructor(e){super(y(e),{cause:e}),this.cause=e}},F=class extends Error{cause;handled;name=`ResultHandlerError`;constructor(e,t){super(y(e),{cause:e}),this.cause=e,this.handled=t}},fe=class extends Error{name=`MissingPeerError`;constructor(e){super(`Missing peer dependency: ${e}. Please install it to use the feature.`)}};const I=Symbol(`Upload`),pe=e=>C(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,me=()=>t.custom(e=>pe(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({[T]:I}),L=Symbol(`Raw`),R=t.object({raw:O()}),he=e=>R.extend(e).meta({[T]:L});function ge(e){return e?he(e):R.meta({[T]:L})}const z=(e,{io:r,condition:i})=>n.tryCatch(()=>void t.toJSONSchema(e,{io:r,unrepresentable:`any`,override:e=>{if(i(e))throw new de(e)}}),e=>e.cause)(),_e=(e,{io:r})=>{let i=t.toJSONSchema(e,{io:r,unrepresentable:`any`}),{$ref:a}=i,o=[i];for(let e=0;e<o.length;e++){let t=o[e];if(n.is(Object,t)){let{$ref:r}=t;if(r===`#`||e&&r&&r===a)return!0;o.push(...n.values(t))}n.is(Array,t)&&o.push(...n.values(t))}return!1},ve=new Set([`nan`,`symbol`,`map`,`set`,`bigint`,`void`,`promise`,`never`,`function`]),ye=(e,t)=>z(e,{io:t,condition:({zodSchema:e,jsonSchema:{[T]:n}})=>{let{type:r}=e._zod.def;return!!(ve.has(r)||n===D||t===`input`&&(r===`date`||n===A)||t===`output`&&(n===k||n===L||n===I))}}),B=Symbol(`Form`),be=e=>(e instanceof t.ZodObject?e:t.object(e)).meta({[T]:B});var V=class e extends Set{constructor(e){if(super(),e)for(let t of e)Set.prototype.add.call(this,t)}add(e){throw TypeError(`Can not add to the read only Set`)}delete(e){throw TypeError(`Can not delete from the read only Set`)}clear(){throw TypeError(`Can not clear the read only Set`)}union(t){return new e(super.union(t))}intersection(t){return new e(super.intersection(t))}difference(t){return new e(super.difference(t))}symmetricDifference(t){return new e(super.symmetricDifference(t))}},xe=class{},H=class extends xe{#e;#t={isAsync:!1};#n;#r;#i;constructor({input:e,security:t,statusCode:n,handler:r}){super(),this.#e=e,this.#n=t,this.#r=new V(typeof n==`number`?[n]:n),this.#i=r}get security(){return this.#n}get schema(){return this.#e}get statusCodes(){return this.#r}async execute({input:e,config:n,...r}){try{let t=await v(this.#e||d,e,n??{},this.#t);return this.#i({...r,input:t})}catch(e){throw e instanceof t.ZodError?new P(e):e}}},U=class extends H{constructor(e,{provider:t=()=>({}),transformer:n=e=>e,statusCode:i}={}){super({statusCode:i,handler:async({request:i,response:a})=>{let{promise:o,resolve:s,reject:c}=Promise.withResolvers(),l=e=>{if(e&&e instanceof Error)return c(n(e));s(t(i,a))},u=e(i,a,l);return r(u)&&u.catch(l),o}})}};const W={positive:200,negative:400},Se=Object.keys(W),G=e=>e<400;function Ce(e){return e instanceof t.ZodType?{schema:e}:e}const we=(e,{variant:r,args:i})=>{typeof e==`function`&&(e=e(...i));let a={statusCodes:[W[r]],mimeTypes:[s.json]};if(e instanceof t.ZodType)return[{schema:e,...a}];if(Array.isArray(e)&&!e.length)throw new F(Error(`At least one ${r} response schema required.`));let o=(Array.isArray(e)?e:[e]).map(({schema:e,statusCode:t,mimeType:n})=>({schema:e,statusCodes:typeof t==`number`?[t]:t||a.statusCodes,mimeTypes:typeof n==`string`?[n]:n===void 0?a.mimeTypes:n})),c=n.chain(n.prop(`statusCodes`),o),l=c.find(e=>G(e)===(r===`negative`));if(l!==void 0)throw new F(Error(`The status code ${l} is not valid for a ${r} API response.`));if(o.length>1){let e=n.find(e=>c.indexOf(e)!==c.lastIndexOf(e),c);if(e!==void 0)throw new F(Error(`The status code ${e} is used by multiple response schemas.`))}return o},Te=(e,t,n)=>{let r=new Set(Array.from(t).filter(e=>G(e)===(n===`positive`)));if(!r.size)return e;if(e.length===1)return e.map(e=>({...e,statusCodes:Array.from(r)}));let i=[],a=e.reduce((e,{statusCodes:t,...n})=>{let a=new Set(t).intersection(r);return a.size?(i.push({...n,statusCodes:Array.from(a)}),e.difference(a)):e},new Set(r));if(a.size){let e=Array.from(a).join(`, `),t=a.size>1;throw new F(Error(`The ResultHandler defines multiple ${n} response schemas, but the overriding status code${t?`s`:``} ${e} of the Endpoint ${t?`are`:`is`} not listed for any of them, therefore it is unclear how such override${t?`s`:``} would be handled. Consider adding ${t?`them`:`it`} to ResultHandler.`))}return i},Ee=(e,t,{url:n},r)=>!e.expose&&t.error(`Server side error`,{error:e,url:n,payload:r}),De=e=>a(e)?e:i(e instanceof P?400:500,y(e),{cause:e.cause||e}),Oe=e=>w.isProduction&&!e.expose?i(e.statusCode).message:e.message,ke=e=>Object.entries(e._zod.def.shape).reduce((e,[t,r])=>x(e,E(r).map(n.objOf(t)),([e,t])=>({...e,...t})),[]);var K=class{nest(e){return{...e,"":this}}},Ae=class r extends K{#e;#t;#n={isAsync:!1};#r={isAsync:!1};#i=n.once(()=>{if(E(this.#e.outputSchema).length||!b(this.#e.outputSchema,`object`))return;let t=ke(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}#a(e){return new r({...this.#e,...e})}deprecated(){return this.#a({deprecated:!0})}get isDeprecated(){return this.#e.deprecated||!1}get description(){return this.#e.description}get summary(){return this.#e.summary}get methods(){return this.#e.methods}get inputSchema(){return this.#e.inputSchema}get outputSchema(){return this.#e.outputSchema}getProbableRequestType(e){return e===`query`?`form`:this.#t??=(()=>{let e,t=t=>!!(e=t),n=!1;return z(this.#e.inputSchema,{io:`input`,condition:({jsonSchema:{[T]:e}})=>e===I?t(`upload`):e===L?t(`raw`):(e===B&&(n=!0),!1)}),e??(n?`form`:`json`)})()}getResponses(e){e===`positive`&&this.#i();let t=e===`negative`?this.#e.resultHandler.getNegativeResponse():this.#e.resultHandler.getPositiveResponse(this.#e.outputSchema);return Object.freeze(this.#e.statusCodes.size?Te(t,this.#e.statusCodes,e):t)}get security(){let e=n.pluck(`security`,this.#e.middlewares||[]);return n.reject(n.isNil,e)}get scopes(){return this.#e.scopes}get tags(){return this.#e.tags}getOperationId(e){return this.#e.getOperationId?.(e)}async#o(e,n){try{return await v(this.#e.outputSchema,e,n,this.#r)}catch(e){throw e instanceof t.ZodError?new N(e):e}}async#s({method:e,logger:t,ctx:n,response:r,...i}){for(let a of this.#e.middlewares||[])if((e!==`options`||a instanceof U)&&(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#c({input:e,config:n,...r}){let i;try{i=await v(this.#e.inputSchema,e,n,this.#n)}catch(e){throw e instanceof t.ZodError?new P(e):e}return this.#e.handler({...r,input:i})}async#l(e){await this.#e.resultHandler.execute(e)}async execute({request:e,response:t,logger:n,config:r}){let i=m(e),a={},o,s=g(e,r.inputSources);try{if(await this.#s({method:i,input:s,request:e,response:t,logger:n,ctx:a,config:r}),t.writableEnded)return;if(i===`options`)return void t.status(200).end();let c=await this.#c({input:s,logger:n,config:r,ctx:a});if(t.writableEnded)return;o={output:await this.#o(c,r),error:null}}catch(e){o={output:null,error:_(e)}}await this.#l({...o,input:s,request:e,response:t,logger:n,ctx:a})}},q=class{#e;constructor(...e){this.#e=e}apply(e,t){return t(e,o.static(...this.#e))}};const J=e=>C(e)&&`or`in e,Y=e=>C(e)&&`and`in e,X=e=>!Y(e)&&!J(e),je=e=>{let t=n.filter(X,e),r=n.chain(n.prop(`and`),n.filter(Y,e)),[i,a]=n.partition(X,r),o=n.concat(t,i),s=n.filter(J,e);return n.map(n.prop(`or`),n.concat(s,a)).reduce((e,t)=>x(e,n.map(e=>X(e)?[e]:e.and,t),([e,t])=>n.concat(e,t)),n.reject(n.isEmpty,[o]))},Z=(e,t)=>Y(e)?n.chain(e=>Z(e,t),e.and):J(e)?n.chain(e=>Z(e,t),e.or):e.type===t?[e.name]:[],Me=(e,t)=>new Set(n.chain(e=>Z(e,t),e)),Ne=e=>(t,...n)=>{e(t,...n),t===`get`&&e(`head`,...n)},Pe=e=>{let[t,n]=e.trim().split(/ (.+)/,2);return n&&u(t)?[n,t]:[e]},Fe=e=>e.trim().split(`/`).filter(Boolean).join(`/`),Q=({recognizeMethodDependentRoutes:e=!0},t,n)=>Object.entries(t).map(([t,r])=>{let[i,a]=e&&u(t)&&r instanceof K?[`/`,t]:Pe(t);return[[n||``].concat(Fe(i)||[]).join(`/`)||`/`,r,a]}),Ie=(e,t)=>{throw new j(`Route with explicit method can only be assigned with Endpoint`,e,t)},Le=(e,t,n)=>{if(n.size&&!n.has(e))throw new j(`Method ${e} is not supported by the assigned Endpoint.`,e,t)},$=(e,t,n)=>{let r=t.includes(`:`)?p(t):t,i=`${e} ${r}`;if(n.has(i))throw new j(`Route has a duplicate: the normalized path "${r}" is already registered`,e,t);n.add(i)},Re=({routing:e,config:t,onEndpoint:n,onStatic:r})=>{let i=Q(t,e),a=new Set;for(let e=0;e<i.length;e++){let[o,s,c]=i[e];if(s instanceof K){if(c)$(c,o,a),Le(c,o,s.methods),n(c,o,s);else{let{methods:e}=s;for(let t of e.size?e:[`get`])$(t,o,a),n(t,o,s)}}else c&&Ie(c,o),s instanceof q?r&&s.apply(o,r):i.splice(e+1,0,...Q(t,s,o))}};export{S as $,le as A,_ as B,me as C,N as D,fe as E,D as F,ae as G,h as H,se as I,ie as J,C as K,E as L,ce as M,k as N,F as O,O as P,oe as Q,x as R,I as S,P as T,y as U,g as V,ee as W,f as X,p as Y,w as Z,be as _,q as a,L as b,Oe as c,Ce as d,l as et,W as f,V as g,H as h,je as i,A as j,j as k,Ee as l,U as m,Ne as n,s as nt,Ae as o,Se as p,b as q,Me as r,De as s,Re as t,u as tt,we as u,ye as v,ue as w,ge as x,_e as y,d as z};
|