express-zod-api 24.6.0 → 25.0.0-beta.2

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/dist/index.d.cts DELETED
@@ -1,942 +0,0 @@
1
- import * as zod_v4 from 'zod/v4';
2
- import { z } from 'zod/v4';
3
- import * as zod_v4_core from 'zod/v4/core';
4
- import { $ZodTypeInternals, $ZodType, SomeType, $ZodDefaultInternals, $ZodDefault, $ZodShape, $ZodLooseShape, $ZodObjectConfig, $strip, $ZodObjectInternals, $ZodObject, JSONSchema } from 'zod/v4/core';
5
- import compression from 'compression';
6
- import * as express from 'express';
7
- import express__default, { Request, Response, NextFunction, RequestHandler, IRouter } from 'express';
8
- import * as express_fileupload from 'express-fileupload';
9
- import express_fileupload__default from 'express-fileupload';
10
- import https, { ServerOptions } from 'node:https';
11
- import { HttpError } from 'http-errors';
12
- import { ListenOptions } from 'node:net';
13
- import * as qs from 'qs';
14
- import * as express_serve_static_core from 'express-serve-static-core';
15
- import http from 'node:http';
16
- import { SchemaObject, ReferenceObject, TagObject, OpenApiBuilder } from 'openapi3-ts/oas31';
17
- import * as node_mocks_http from 'node-mocks-http';
18
- import { RequestOptions, ResponseOptions } from 'node-mocks-http';
19
- import ts from 'typescript';
20
-
21
- /**
22
- * @fileoverview Mapping utils for Zod Runtime Plugin (remap)
23
- * @link https://stackoverflow.com/questions/55454125/typescript-remapping-object-properties-in-typesafe
24
- */
25
- type TuplesFromObject<T> = {
26
- [P in keyof T]: [P, T[P]];
27
- }[keyof T];
28
- type GetKeyByValue<T, V> = TuplesFromObject<T> extends infer TT ? TT extends [infer P, V] ? P : never : never;
29
- type Remap<T, U extends {
30
- [P in keyof T]?: V;
31
- }, V extends string> = {
32
- [P in NonNullable<U[keyof U]>]: T[GetKeyByValue<U, P>];
33
- };
34
- type Intact<T, U> = {
35
- [K in Exclude<keyof T, keyof U>]: T[K];
36
- };
37
-
38
- /** @todo remove when typed, https://github.com/ramda/types/pull/140 */
39
- declare module "ramda" {
40
- function renameKeys<V extends string, T extends object, U extends {
41
- [P in keyof T]?: V;
42
- }>(mapping: U): (subject: T) => Remap<T, U, V>;
43
- }
44
- declare module "zod/v4/core" {
45
- interface GlobalMeta {
46
- default?: unknown;
47
- }
48
- }
49
- declare module "zod/v4" {
50
- interface ZodType<out Output = unknown, out Input = unknown, out Internals extends $ZodTypeInternals<Output, Input> = $ZodTypeInternals<Output, Input>> extends $ZodType<Output, Input, Internals> {
51
- /** @desc Alias for .meta({examples}), but argument is typed to ensure the correct placement for transformations */
52
- example(example: z.output<this>): this;
53
- deprecated(): this;
54
- }
55
- interface ZodDefault<T extends SomeType = $ZodType> extends z._ZodType<$ZodDefaultInternals<T>>, $ZodDefault<T> {
56
- /** @desc Change the default value in the generated Documentation to a label, alias for .meta({ default }) */
57
- label(label: string): this;
58
- }
59
- interface ZodObject<out Shape extends $ZodShape = $ZodLooseShape, out Config extends $ZodObjectConfig = $strip> extends z._ZodType<$ZodObjectInternals<Shape, Config>>, $ZodObject<Shape, Config> {
60
- remap<V extends string, U extends {
61
- [P in keyof Shape]?: V;
62
- }>(mapping: U): z.ZodPipe<z.ZodPipe<this, z.ZodTransform>, // internal type simplified
63
- z.ZodObject<Remap<Shape, U, V> & Intact<Shape, U>, Config>>;
64
- remap<U extends $ZodShape>(mapper: (subject: Shape) => U): z.ZodPipe<z.ZodPipe<this, z.ZodTransform>, z.ZodObject<U>>;
65
- }
66
- }
67
-
68
- declare const methods: ("delete" | "get" | "post" | "put" | "patch")[];
69
- type Method = (typeof methods)[number];
70
-
71
- /** @desc this type does not allow props assignment, but it works for reading them when merged with another interface */
72
- type EmptyObject = z.output<EmptySchema>;
73
- /** Avoiding z.ZodObject<Record<string, never>, $strip>, because its z.output<> is generic "object" (external issue) */
74
- type EmptySchema = z.ZodRecord<z.ZodString, z.ZodNever>;
75
- type FlatObject = Record<string, unknown>;
76
- /** @link https://stackoverflow.com/a/65492934 */
77
- type NoNever<T, F> = [T] extends [never] ? F : T;
78
- /**
79
- * @desc Using module augmentation approach you can specify tags as the keys of this interface
80
- * @example declare module "express-zod-api" { interface TagOverrides { users: unknown } }
81
- * @link https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
82
- * */
83
- interface TagOverrides {
84
- }
85
- type Tag = NoNever<keyof TagOverrides, string>;
86
- declare const getMessageFromError: (error: Error) => string;
87
-
88
- declare const severity: {
89
- debug: number;
90
- info: number;
91
- warn: number;
92
- error: number;
93
- };
94
- type Severity = keyof typeof severity;
95
- /** @desc You can use any logger compatible with this type. */
96
- type AbstractLogger = Record<Severity, (message: string, meta?: any) => any>;
97
- /**
98
- * @desc Using module augmentation approach you can set the type of the actual logger used
99
- * @example declare module "express-zod-api" { interface LoggerOverrides extends winston.Logger {} }
100
- * @link https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
101
- * */
102
- interface LoggerOverrides {
103
- }
104
- type ActualLogger = AbstractLogger & LoggerOverrides;
105
-
106
- interface Context extends FlatObject {
107
- requestId?: string;
108
- }
109
- interface BuiltinLoggerConfig {
110
- /**
111
- * @desc The minimal severity to log or "silent" to disable logging
112
- * @example "debug" also enables pretty output for inspected entities
113
- * */
114
- level: "silent" | "warn" | "info" | "debug";
115
- /** @desc Enables colors on printed severity and inspected entities */
116
- color: boolean;
117
- /**
118
- * @desc Control how deeply entities should be inspected
119
- * @example null
120
- * @example Infinity
121
- * */
122
- depth: number | null;
123
- /**
124
- * @desc Context: the metadata applicable for each logged entry, used by .child() method
125
- * @see childLoggerProvider
126
- * */
127
- ctx: Context;
128
- }
129
- interface ProfilerOptions {
130
- message: string;
131
- /** @default "debug" */
132
- severity?: Severity | ((ms: number) => Severity);
133
- /** @default formatDuration - adaptive units and limited fraction */
134
- formatter?: (ms: number) => string | number;
135
- }
136
- /** @desc Built-in console logger with optional colorful inspections */
137
- declare class BuiltinLogger implements AbstractLogger {
138
- protected readonly config: BuiltinLoggerConfig;
139
- /** @example new BuiltinLogger({ level: "debug", color: true, depth: 4 }) */
140
- constructor({ color, level, depth, ctx, }?: Partial<BuiltinLoggerConfig>);
141
- protected format(subject: unknown): string;
142
- protected print(method: Severity, message: string, meta?: unknown): void;
143
- debug(message: string, meta?: unknown): void;
144
- info(message: string, meta?: unknown): void;
145
- warn(message: string, meta?: unknown): void;
146
- error(message: string, meta?: unknown): void;
147
- child(ctx: Context): BuiltinLogger;
148
- /**
149
- * @desc The argument used for instance created by .child() method
150
- * @see ChildLoggerProvider
151
- * */
152
- get ctx(): Context;
153
- /** @desc Measures the duration until you invoke the returned callback */
154
- profile(message: string): () => void;
155
- profile(options: ProfilerOptions): () => void;
156
- }
157
-
158
- type LogicalOr<T> = {
159
- or: T[];
160
- };
161
- type LogicalAnd<T> = {
162
- and: T[];
163
- };
164
- type LogicalContainer<T> = LogicalOr<T | LogicalAnd<T>> | LogicalAnd<T | LogicalOr<T>> | T;
165
-
166
- interface BasicSecurity {
167
- type: "basic";
168
- }
169
- interface BearerSecurity {
170
- type: "bearer";
171
- format?: "JWT" | string;
172
- }
173
- interface InputSecurity<K extends string> {
174
- type: "input";
175
- name: K;
176
- }
177
- interface HeaderSecurity {
178
- type: "header";
179
- name: string;
180
- }
181
- interface CookieSecurity {
182
- type: "cookie";
183
- name: string;
184
- }
185
- /**
186
- * @see https://swagger.io/docs/specification/authentication/openid-connect-discovery/
187
- * @desc available scopes has to be provided via the specified URL
188
- */
189
- interface OpenIdSecurity {
190
- type: "openid";
191
- url: string;
192
- }
193
- interface AuthUrl {
194
- /**
195
- * @desc The authorization URL to use for this flow. Can be relative to the API server URL.
196
- * @see https://swagger.io/docs/specification/api-host-and-base-path/
197
- */
198
- authorizationUrl: string;
199
- }
200
- interface TokenUrl {
201
- /** @desc The token URL to use for this flow. Can be relative to the API server URL. */
202
- tokenUrl: string;
203
- }
204
- interface RefreshUrl {
205
- /** @desc The URL to be used for obtaining refresh tokens. Can be relative to the API server URL. */
206
- refreshUrl?: string;
207
- }
208
- interface Scopes<K extends string> {
209
- /** @desc The available scopes for the OAuth2 security and their short descriptions. Optional. */
210
- scopes?: Record<K, string>;
211
- }
212
- type AuthCodeFlow<S extends string> = AuthUrl & TokenUrl & RefreshUrl & Scopes<S>;
213
- type ImplicitFlow<S extends string> = AuthUrl & RefreshUrl & Scopes<S>;
214
- type PasswordFlow<S extends string> = TokenUrl & RefreshUrl & Scopes<S>;
215
- type ClientCredFlow<S extends string> = TokenUrl & RefreshUrl & Scopes<S>;
216
- /**
217
- * @see https://swagger.io/docs/specification/authentication/oauth2/
218
- */
219
- interface OAuth2Security<S extends string> {
220
- type: "oauth2";
221
- flows?: {
222
- /** @desc Authorization Code flow (previously called accessCode in OpenAPI 2.0) */
223
- authorizationCode?: AuthCodeFlow<S>;
224
- /** @desc Implicit flow */
225
- implicit?: ImplicitFlow<S>;
226
- /** @desc Resource Owner Password flow */
227
- password?: PasswordFlow<S>;
228
- /** @desc Client Credentials flow (previously called application in OpenAPI 2.0) */
229
- clientCredentials?: ClientCredFlow<S>;
230
- };
231
- }
232
- /**
233
- * @desc Middleware security schema descriptor
234
- * @param K is an optional input field used by InputSecurity
235
- * @param S is an optional union of scopes used by OAuth2Security
236
- * */
237
- type Security<K extends string = string, S extends string = string> = BasicSecurity | BearerSecurity | InputSecurity<K> | HeaderSecurity | CookieSecurity | OpenIdSecurity | OAuth2Security<S>;
238
-
239
- type Handler$2<IN, OPT, OUT> = (params: {
240
- /** @desc The inputs from the enabled input sources validated against the input schema of the Middleware */
241
- input: IN;
242
- /**
243
- * @desc The returns of the previously executed Middlewares (typed when chaining Middlewares)
244
- * @link https://github.com/RobinTail/express-zod-api/discussions/1250
245
- * */
246
- options: OPT;
247
- /** @link https://expressjs.com/en/5x/api.html#req */
248
- request: Request;
249
- /** @link https://expressjs.com/en/5x/api.html#res */
250
- response: Response;
251
- /** @desc The instance of the configured logger */
252
- logger: ActualLogger;
253
- }) => Promise<OUT>;
254
- declare abstract class AbstractMiddleware {
255
- abstract execute(params: {
256
- input: unknown;
257
- options: FlatObject;
258
- request: Request;
259
- response: Response;
260
- logger: ActualLogger;
261
- }): Promise<FlatObject>;
262
- }
263
- declare class Middleware<OPT extends FlatObject, OUT extends FlatObject, SCO extends string, IN extends IOSchema = EmptySchema> extends AbstractMiddleware {
264
- #private;
265
- constructor({ input, security, handler, }: {
266
- /**
267
- * @desc Input schema of the Middleware, combining properties from all the enabled input sources
268
- * @default z.object({})
269
- * @see defaultInputSources
270
- * */
271
- input?: IN;
272
- /** @desc Declaration of the security schemas implemented within the handler */
273
- security?: LogicalContainer<Security<Extract<keyof z.input<IN>, string>, SCO>>;
274
- /** @desc The handler returning options available to Endpoints */
275
- handler: Handler$2<z.output<IN>, OPT, OUT>;
276
- });
277
- /** @throws InputValidationError */
278
- execute({ input, ...rest }: {
279
- input: unknown;
280
- options: OPT;
281
- request: Request;
282
- response: Response;
283
- logger: ActualLogger;
284
- }): Promise<OUT>;
285
- }
286
- declare class ExpressMiddleware<R extends Request, S extends Response, OUT extends FlatObject> extends Middleware<FlatObject, OUT, string> {
287
- constructor(nativeMw: (request: R, response: S, next: NextFunction) => void | Promise<void>, { provider, transformer, }?: {
288
- provider?: (request: R, response: S) => OUT | Promise<OUT>;
289
- transformer?: (err: Error) => Error;
290
- });
291
- }
292
-
293
- type Base$1 = object & {
294
- [Symbol.iterator]?: never;
295
- };
296
- /** @desc The type allowed on the top level of Middlewares and Endpoints */
297
- type IOSchema = z.ZodType<Base$1>;
298
- type ConditionalIntersection<Current extends IOSchema | undefined, Inc extends IOSchema> = z.ZodIntersection<Current extends IOSchema ? Current : Inc, Inc>;
299
-
300
- declare class DependsOnMethod extends Routable {
301
- #private;
302
- constructor(endpoints: Partial<Record<Method, AbstractEndpoint>>);
303
- deprecated(): this;
304
- }
305
-
306
- type OriginalStatic = typeof express__default.static;
307
- declare class ServeStatic {
308
- #private;
309
- constructor(...params: Parameters<OriginalStatic>);
310
- }
311
-
312
- /** @public this is the user facing configuration */
313
- interface ApiResponse<S extends z.ZodType> {
314
- schema: S;
315
- /** @default 200 for a positive and 400 for a negative response */
316
- statusCode?: number | [number, ...number[]];
317
- /**
318
- * @example null is for no content, such as 204 and 302
319
- * @default "application/json"
320
- * */
321
- mimeType?: string | [string, ...string[]] | null;
322
- }
323
-
324
- type ResultSchema<R extends Result> = R extends Result<infer S> ? S : never;
325
- type DiscriminatedResult = {
326
- output: FlatObject;
327
- error: null;
328
- } | {
329
- output: null;
330
- error: Error;
331
- };
332
- /**
333
- * @example InputValidationError —> BadRequest(400)
334
- * @example Error —> InternalServerError(500)
335
- * */
336
- declare const ensureHttpError: (error: Error) => HttpError;
337
-
338
- type Handler$1<RES = unknown> = (params: DiscriminatedResult & {
339
- /** null in case of failure to parse or to find the matching endpoint (error: not found) */
340
- input: FlatObject | null;
341
- /** can be empty: check presence of the required property using "in" operator */
342
- options: FlatObject;
343
- request: Request;
344
- response: Response<RES>;
345
- logger: ActualLogger;
346
- }) => void | Promise<void>;
347
- type Result<S extends z.ZodType = z.ZodType> = S | ApiResponse<S> | ApiResponse<S>[];
348
- type LazyResult<R extends Result, A extends unknown[] = []> = (...args: A) => R;
349
- declare abstract class AbstractResultHandler {
350
- #private;
351
- protected constructor(handler: Handler$1);
352
- execute(...params: Parameters<Handler$1>): void | Promise<void>;
353
- }
354
- declare class ResultHandler<POS extends Result, NEG extends Result> extends AbstractResultHandler {
355
- #private;
356
- constructor(params: {
357
- /** @desc A description of the API response in case of success (schema, status code, MIME type) */
358
- positive: POS | LazyResult<POS, [IOSchema]>;
359
- /** @desc A description of the API response in case of error (schema, status code, MIME type) */
360
- negative: NEG | LazyResult<NEG>;
361
- /** @desc The actual implementation to transmit the response in any case */
362
- handler: Handler$1<z.output<ResultSchema<POS> | ResultSchema<NEG>>>;
363
- });
364
- }
365
- declare const defaultResultHandler: ResultHandler<z.ZodObject<{
366
- status: z.ZodLiteral<"success">;
367
- data: IOSchema;
368
- }, z.core.$strip>, z.ZodObject<{
369
- status: z.ZodLiteral<"error">;
370
- error: z.ZodObject<{
371
- message: z.ZodString;
372
- }, z.core.$strip>;
373
- }, z.core.$strip>>;
374
- /**
375
- * @deprecated Resist the urge of using it: this handler is designed only to simplify the migration of legacy APIs.
376
- * @desc Responding with array is a bad practice keeping your endpoints from evolving without breaking changes.
377
- * @desc This handler expects your endpoint to have the property 'items' in the output object schema
378
- * */
379
- declare const arrayResultHandler: ResultHandler<z.ZodArray<z.core.$ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>> | z.ZodArray<z.ZodAny>, z.ZodString>;
380
-
381
- /** @desc Returns child logger for the given request (if configured) or the configured logger otherwise */
382
- type GetLogger = (request?: Request) => ActualLogger;
383
-
384
- /**
385
- * @example { v1: { books: { ":bookId": getBookEndpoint } } }
386
- * @example { "v1/books/:bookId": getBookEndpoint }
387
- * @example { "get /v1/books/:bookId": getBookEndpoint }
388
- * @example { v1: { "patch /books/:bookId": changeBookEndpoint } }
389
- * */
390
- interface Routing {
391
- [K: string]: Routing | DependsOnMethod | AbstractEndpoint | ServeStatic;
392
- }
393
-
394
- declare abstract class Routable {
395
- /** @desc Marks the route as deprecated (makes a copy of the endpoint) */
396
- abstract deprecated(): this;
397
- /** @desc Enables nested routes within the path assigned to the subject */
398
- nest(routing: Routing): Routing;
399
- }
400
-
401
- type Handler<IN, OUT, OPT> = (params: {
402
- /** @desc The inputs from the enabled input sources validated against the final input schema (incl. Middlewares) */
403
- input: IN;
404
- /** @desc The returns of the assigned Middlewares */
405
- options: OPT;
406
- /** @desc The instance of the configured logger */
407
- logger: ActualLogger;
408
- }) => Promise<OUT>;
409
- declare abstract class AbstractEndpoint extends Routable {
410
- abstract execute(params: {
411
- request: Request;
412
- response: Response;
413
- logger: ActualLogger;
414
- config: CommonConfig;
415
- }): Promise<void>;
416
- }
417
- declare class Endpoint<IN extends IOSchema, OUT extends IOSchema, OPT extends FlatObject> extends AbstractEndpoint {
418
- #private;
419
- constructor(def: {
420
- deprecated?: boolean;
421
- middlewares?: AbstractMiddleware[];
422
- inputSchema: IN;
423
- outputSchema: OUT;
424
- handler: Handler<z.output<IN>, z.input<OUT>, OPT>;
425
- resultHandler: AbstractResultHandler;
426
- description?: string;
427
- shortDescription?: string;
428
- getOperationId?: (method: Method) => string | undefined;
429
- methods?: Method[];
430
- scopes?: string[];
431
- tags?: string[];
432
- });
433
- deprecated(): this;
434
- execute({ request, response, logger, config, }: {
435
- request: Request;
436
- response: Response;
437
- logger: ActualLogger;
438
- config: CommonConfig;
439
- }): Promise<undefined>;
440
- }
441
-
442
- type InputSource = keyof Pick<Request, "query" | "body" | "files" | "params" | "headers">;
443
- type InputSources = Record<Method, InputSource[]>;
444
- type Headers = Record<string, string>;
445
- type HeadersProvider = (params: {
446
- /** @desc The default headers to be overridden. */
447
- defaultHeaders: Headers;
448
- request: Request;
449
- endpoint: AbstractEndpoint;
450
- logger: ActualLogger;
451
- }) => Headers | Promise<Headers>;
452
- type ChildLoggerProvider = (params: {
453
- request: Request;
454
- parent: ActualLogger;
455
- }) => ActualLogger | Promise<ActualLogger>;
456
- type LogAccess = (request: Request, logger: ActualLogger) => void;
457
- interface CommonConfig {
458
- /**
459
- * @desc Enables cross-origin resource sharing.
460
- * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
461
- * @desc You can override the default CORS headers by setting up a provider function here.
462
- */
463
- cors: boolean | HeadersProvider;
464
- /**
465
- * @desc How to respond to a request that uses a wrong method to an existing endpoint
466
- * @example 404 — Not found
467
- * @example 405 — Method not allowed, incl. the "Allow" header with a list of methods
468
- * @default 405
469
- * */
470
- wrongMethodBehavior?: 404 | 405;
471
- /**
472
- * @desc The ResultHandler to use for handling routing, parsing and upload errors
473
- * @default defaultResultHandler
474
- * @see defaultResultHandler
475
- */
476
- errorHandler?: AbstractResultHandler;
477
- /**
478
- * @desc Built-in logger configuration or an instance of any compatible logger.
479
- * @example { level: "debug", color: true }
480
- * @default { level: NODE_ENV === "production" ? "warn" : "debug", color: isSupported(), depth: 2 }
481
- * */
482
- logger?: Partial<BuiltinLoggerConfig> | AbstractLogger;
483
- /**
484
- * @desc A child logger returned by this function can override the logger in all handlers for each request
485
- * @example ({ parent }) => parent.child({ requestId: uuid() })
486
- * */
487
- childLoggerProvider?: ChildLoggerProvider;
488
- /**
489
- * @desc The function for producing access logs
490
- * @default ({ method, path }, logger) => logger.debug(`${method}: ${path}`)
491
- * @example null — disables the feature
492
- * */
493
- accessLogger?: null | LogAccess;
494
- /**
495
- * @desc You can disable the startup logo.
496
- * @default true
497
- */
498
- startupLogo?: boolean;
499
- /**
500
- * @desc Which properties of request are combined into the input for endpoints and middlewares.
501
- * @desc The order matters: priority from lowest to highest
502
- * @default defaultInputSources
503
- * @see defaultInputSources
504
- */
505
- inputSources?: Partial<InputSources>;
506
- }
507
- type BeforeUpload = (params: {
508
- request: Request;
509
- logger: ActualLogger;
510
- }) => void | Promise<void>;
511
- type UploadOptions = Pick<express_fileupload__default.Options, "createParentPath" | "uriDecodeFileNames" | "safeFileNames" | "preserveExtension" | "useTempFiles" | "tempFileDir" | "debug" | "uploadTimeout" | "limits"> & {
512
- /**
513
- * @desc The error to throw when the file exceeds the configured fileSize limit (handled by errorHandler).
514
- * @see limits
515
- * @override limitHandler
516
- * @example createHttpError(413, "The file is too large")
517
- * */
518
- limitError?: Error;
519
- /**
520
- * @desc A handler to execute before uploading — it can be used for restrictions by throwing an error.
521
- * @example ({ request }) => { throw createHttpError(403, "Not authorized"); }
522
- * */
523
- beforeUpload?: BeforeUpload;
524
- };
525
- type CompressionOptions = Pick<compression.CompressionOptions, "threshold" | "level" | "strategy" | "chunkSize" | "memLevel">;
526
- interface GracefulOptions {
527
- /**
528
- * @desc Time given to drain ongoing requests before closing the server.
529
- * @default 1000
530
- * */
531
- timeout?: number;
532
- /**
533
- * @desc Process event (Signal) that triggers the graceful shutdown.
534
- * @see Signals
535
- * @default [SIGINT, SIGTERM]
536
- * */
537
- events?: string[];
538
- /** @desc The hook to call after the server was closed, but before terminating the process. */
539
- beforeExit?: () => void | Promise<void>;
540
- }
541
- type BeforeRouting = (params: {
542
- app: IRouter;
543
- /** @desc Returns child logger for the given request (if configured) or the configured logger otherwise */
544
- getLogger: GetLogger;
545
- }) => void | Promise<void>;
546
- interface HttpConfig {
547
- /** @desc Port, UNIX socket or custom options. */
548
- listen: number | string | ListenOptions;
549
- }
550
- interface HttpsConfig extends HttpConfig {
551
- /** @desc At least "cert" and "key" options required. */
552
- options: ServerOptions;
553
- }
554
- interface ServerConfig extends CommonConfig {
555
- /** @desc HTTP server configuration. */
556
- http?: HttpConfig;
557
- /** @desc HTTPS server configuration. */
558
- https?: HttpsConfig;
559
- /**
560
- * @desc Custom JSON parser.
561
- * @default express.json()
562
- * @link https://expressjs.com/en/4x/api.html#express.json
563
- * */
564
- jsonParser?: RequestHandler;
565
- /**
566
- * @desc Enable or configure uploads handling.
567
- * @requires express-fileupload
568
- * */
569
- upload?: boolean | UploadOptions;
570
- /**
571
- * @desc Enable or configure response compression.
572
- * @requires compression
573
- */
574
- compression?: boolean | CompressionOptions;
575
- /**
576
- * @desc Custom raw parser (assigns Buffer to request body)
577
- * @default express.raw()
578
- * @link https://expressjs.com/en/4x/api.html#express.raw
579
- * */
580
- rawParser?: RequestHandler;
581
- /**
582
- * @desc Custom parser for URL Encoded requests used for submitting HTML forms
583
- * @default express.urlencoded()
584
- * @link https://expressjs.com/en/4x/api.html#express.urlencoded
585
- * */
586
- formParser?: RequestHandler;
587
- /**
588
- * @desc A code to execute before processing the Routing of your API (and before parsing).
589
- * @desc This can be a good place for express middlewares establishing their own routes.
590
- * @desc It can help to avoid making a DIY solution based on the attachRouting() approach.
591
- * @example ({ app }) => { app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument)); }
592
- * */
593
- beforeRouting?: BeforeRouting;
594
- /**
595
- * @desc Rejects new connections and attempts to finish ongoing ones in the specified time before exit.
596
- * */
597
- gracefulShutdown?: boolean | GracefulOptions;
598
- }
599
- interface AppConfig extends CommonConfig {
600
- /** @desc Your custom express app or express router instead. */
601
- app: IRouter;
602
- }
603
- declare function createConfig(config: ServerConfig): ServerConfig;
604
- declare function createConfig(config: AppConfig): AppConfig;
605
-
606
- interface BuildProps<IN extends IOSchema, OUT extends IOSchema | z.ZodVoid, MIN extends IOSchema | undefined, OPT extends FlatObject, SCO extends string> {
607
- /**
608
- * @desc Input schema of the Endpoint, combining properties from all the enabled input sources (path params, headers)
609
- * @default z.object({})
610
- * @see defaultInputSources
611
- * */
612
- input?: IN;
613
- /** @desc The schema by which the returns of the Endpoint handler is validated */
614
- output: OUT;
615
- /** @desc The Endpoint handler receiving the validated inputs, returns of added Middlewares (options) and a logger */
616
- handler: Handler<z.output<ConditionalIntersection<MIN, IN>>, z.input<OUT>, OPT>;
617
- /** @desc The operation description for the generated Documentation */
618
- description?: string;
619
- /** @desc The operation summary for the generated Documentation (50 symbols max) */
620
- shortDescription?: string;
621
- /** @desc The operation ID for the generated Documentation (must be unique) */
622
- operationId?: string | ((method: Method) => string);
623
- /**
624
- * @desc HTTP method(s) this endpoint can handle
625
- * @default "get" unless the Endpoint is assigned within DependsOnMethod
626
- * @see DependsOnMethod
627
- * */
628
- method?: Method | [Method, ...Method[]];
629
- /**
630
- * @desc Scope(s) from the list of the ones defined by the added Middlewares having "oauth2" security type
631
- * @see OAuth2Security
632
- * */
633
- scope?: SCO | SCO[];
634
- /**
635
- * @desc Tag(s) for generating Documentation. For establishing constraints:
636
- * @see TagOverrides
637
- * */
638
- tag?: Tag | Tag[];
639
- /** @desc Marks the operation deprecated in the generated Documentation */
640
- deprecated?: boolean;
641
- }
642
- declare class EndpointsFactory<IN extends IOSchema | undefined = undefined, OUT extends FlatObject = EmptyObject, SCO extends string = string> {
643
- #private;
644
- protected resultHandler: AbstractResultHandler;
645
- protected middlewares: AbstractMiddleware[];
646
- constructor(resultHandler: AbstractResultHandler);
647
- addMiddleware<AOUT extends FlatObject, ASCO extends string, AIN extends IOSchema = EmptySchema>(subject: Middleware<OUT, AOUT, ASCO, AIN> | ConstructorParameters<typeof Middleware<OUT, AOUT, ASCO, AIN>>[0]): EndpointsFactory<ConditionalIntersection<IN, AIN>, OUT & AOUT, SCO & ASCO>;
648
- use: <R extends Request, S extends Response, AOUT extends FlatObject = Record<string, never>>(nativeMw: (request: R, response: S, next: express.NextFunction) => void | Promise<void>, params_1?: {
649
- provider?: ((request: R, response: S) => AOUT | Promise<AOUT>) | undefined;
650
- transformer?: (err: Error) => Error;
651
- } | undefined) => EndpointsFactory<IN, OUT & AOUT, SCO>;
652
- addExpressMiddleware<R extends Request, S extends Response, AOUT extends FlatObject = EmptyObject>(...params: ConstructorParameters<typeof ExpressMiddleware<R, S, AOUT>>): EndpointsFactory<IN, OUT & AOUT, SCO>;
653
- addOptions<AOUT extends FlatObject>(getOptions: () => Promise<AOUT>): EndpointsFactory<IN, OUT & AOUT, SCO>;
654
- build<BOUT extends IOSchema, BIN extends IOSchema = EmptySchema>({ input, output: outputSchema, operationId, scope, tag, method, ...rest }: BuildProps<BIN, BOUT, IN, OUT, SCO>): Endpoint<ConditionalIntersection<IN, BIN>, BOUT, OUT>;
655
- /** @desc shorthand for returning {} while having output schema z.object({}) */
656
- buildVoid<BIN extends IOSchema = EmptySchema>({ handler, ...rest }: Omit<BuildProps<BIN, z.ZodVoid, IN, OUT, SCO>, "output">): Endpoint<ConditionalIntersection<IN, BIN>, z.ZodObject<{}, z.core.$strip>, OUT>;
657
- }
658
- declare const defaultEndpointsFactory: EndpointsFactory<undefined, Record<string, never>, string>;
659
- /**
660
- * @deprecated Resist the urge of using it: this factory is designed only to simplify the migration of legacy APIs.
661
- * @desc Responding with array is a bad practice keeping your endpoints from evolving without breaking changes.
662
- * @desc The result handler of this factory expects your endpoint to have the property 'items' in the output schema
663
- */
664
- declare const arrayEndpointsFactory: EndpointsFactory<undefined, Record<string, never>, string>;
665
-
666
- declare const attachRouting: (config: AppConfig, routing: Routing) => {
667
- notFoundHandler: express__default.RequestHandler<express_serve_static_core.ParamsDictionary, any, any, qs.ParsedQs, Record<string, any>>;
668
- logger: AbstractLogger | BuiltinLogger;
669
- };
670
- declare const createServer: (config: ServerConfig, routing: Routing) => Promise<{
671
- app: express_serve_static_core.Express;
672
- logger: AbstractLogger | BuiltinLogger;
673
- servers: (http.Server<typeof http.IncomingMessage, typeof http.ServerResponse> | https.Server<typeof http.IncomingMessage, typeof http.ServerResponse>)[];
674
- }>;
675
-
676
- interface ReqResCommons {
677
- makeRef: (key: object | string, subject: SchemaObject | ReferenceObject, name?: string) => ReferenceObject;
678
- path: string;
679
- method: Method;
680
- }
681
- interface OpenAPIContext extends ReqResCommons {
682
- isResponse: boolean;
683
- }
684
- type Depicter = (zodCtx: {
685
- zodSchema: $ZodType;
686
- jsonSchema: JSONSchema.BaseSchema;
687
- }, oasCtx: OpenAPIContext) => JSONSchema.BaseSchema | SchemaObject;
688
- /** @desc Using defaultIsHeader when returns null or undefined */
689
- type IsHeader = (name: string, method: Method, path: string) => boolean | null | undefined;
690
- type BrandHandling = Record<string | symbol, Depicter>;
691
- declare const depictTags: (tags: Partial<Record<Tag, string | {
692
- description: string;
693
- url?: string;
694
- }>>) => TagObject[];
695
-
696
- type Component = "positiveResponse" | "negativeResponse" | "requestParameter" | "requestBody";
697
- /** @desc user defined function that creates a component description from its properties */
698
- type Descriptor = (props: Record<"method" | "path" | "operationId", string> & {
699
- statusCode?: number;
700
- }) => string;
701
- interface DocumentationParams {
702
- title: string;
703
- version: string;
704
- serverUrl: string | [string, ...string[]];
705
- routing: Routing;
706
- config: CommonConfig;
707
- /**
708
- * @desc Descriptions of various components based on their properties (method, path, operationId).
709
- * @desc When composition set to "components", component name is generated from this description
710
- * @default () => `${method} ${path} ${component}`
711
- * */
712
- descriptions?: Partial<Record<Component, Descriptor>>;
713
- /** @default true */
714
- hasSummaryFromDescription?: boolean;
715
- /** @default inline */
716
- composition?: "inline" | "components";
717
- /**
718
- * @desc Handling rules for your own branded schemas.
719
- * @desc Keys: brands (recommended to use unique symbols).
720
- * @desc Values: functions having Zod context as first argument, second one is the framework context.
721
- * @example { MyBrand: ( { zodSchema, jsonSchema } ) => ({ type: "object" })
722
- */
723
- brandHandling?: BrandHandling;
724
- /**
725
- * @desc Ability to configure recognition of headers among other input data
726
- * @desc Only applicable when "headers" is present within inputSources config option
727
- * @see defaultIsHeader
728
- * @link https://www.iana.org/assignments/http-fields/http-fields.xhtml
729
- * */
730
- isHeader?: IsHeader;
731
- /**
732
- * @desc Extended description of tags used in endpoints. For enforcing constraints:
733
- * @see TagOverrides
734
- * @example { users: "About users", files: { description: "About files", url: "https://example.com" } }
735
- * */
736
- tags?: Parameters<typeof depictTags>[0];
737
- }
738
- declare class Documentation extends OpenApiBuilder {
739
- #private;
740
- constructor({ routing, config, title, version, serverUrl, descriptions, brandHandling, tags, isHeader, hasSummaryFromDescription, composition, }: DocumentationParams);
741
- }
742
-
743
- /** @desc An error related to the wrong Routing declaration */
744
- declare class RoutingError extends Error {
745
- name: string;
746
- readonly cause: {
747
- method: Method;
748
- path: string;
749
- };
750
- constructor(message: string, method: Method, path: string);
751
- }
752
- /**
753
- * @desc An error related to the generating of the documentation
754
- * */
755
- declare class DocumentationError extends Error {
756
- name: string;
757
- readonly cause: string;
758
- constructor(message: string, { method, path, isResponse, }: Pick<OpenAPIContext, "path" | "method" | "isResponse">);
759
- }
760
- /** @desc An error related to the input and output schemas declaration */
761
- declare class IOSchemaError extends Error {
762
- name: string;
763
- }
764
- /** @desc An error of validating the Endpoint handler's returns against the Endpoint output schema */
765
- declare class OutputValidationError extends IOSchemaError {
766
- readonly cause: z.ZodError;
767
- name: string;
768
- constructor(cause: z.ZodError);
769
- }
770
- /** @desc An error of validating the input sources against the Middleware or Endpoint input schema */
771
- declare class InputValidationError extends IOSchemaError {
772
- readonly cause: z.ZodError;
773
- name: string;
774
- constructor(cause: z.ZodError);
775
- }
776
- declare class MissingPeerError extends Error {
777
- name: string;
778
- constructor(module: string);
779
- }
780
-
781
- interface TestingProps<REQ, LOG> {
782
- /**
783
- * @desc Additional properties to set on Request mock
784
- * @default { method: "GET", headers: { "content-type": "application/json" } }
785
- * */
786
- requestProps?: REQ;
787
- /**
788
- * @link https://www.npmjs.com/package/node-mocks-http
789
- * @default { req: requestMock }
790
- * */
791
- responseOptions?: ResponseOptions;
792
- /**
793
- * @desc Additional properties to set on config mock
794
- * @default { cors: false, logger }
795
- * */
796
- configProps?: Partial<CommonConfig>;
797
- /**
798
- * @desc Additional properties to set on logger mock
799
- * @default { info, warn, error, debug }
800
- * */
801
- loggerProps?: LOG;
802
- }
803
- declare const testEndpoint: <LOG extends FlatObject, REQ extends RequestOptions>({ endpoint, ...rest }: TestingProps<REQ, LOG> & {
804
- /** @desc The endpoint to test */
805
- endpoint: AbstractEndpoint;
806
- }) => Promise<{
807
- requestMock: node_mocks_http.MockRequest<Request<express_serve_static_core.ParamsDictionary, any, any, qs.ParsedQs, Record<string, any>> & REQ>;
808
- responseMock: node_mocks_http.MockResponse<Response<any, Record<string, any>>>;
809
- loggerMock: AbstractLogger & LOG & {
810
- _getLogs: () => Record<"error" | "debug" | "info" | "warn", unknown[]>;
811
- };
812
- }>;
813
- declare const testMiddleware: <LOG extends FlatObject, REQ extends RequestOptions>({ middleware, options, ...rest }: TestingProps<REQ, LOG> & {
814
- /** @desc The middleware to test */
815
- middleware: AbstractMiddleware;
816
- /** @desc The aggregated output from previously executed middlewares */
817
- options?: FlatObject;
818
- }) => Promise<{
819
- requestMock: node_mocks_http.MockRequest<Request<express_serve_static_core.ParamsDictionary, any, any, qs.ParsedQs, Record<string, any>> & REQ>;
820
- responseMock: node_mocks_http.MockResponse<Response<any, Record<string, any>>>;
821
- loggerMock: AbstractLogger & LOG & {
822
- _getLogs: () => Record<"error" | "debug" | "info" | "warn", unknown[]>;
823
- };
824
- output: FlatObject;
825
- }>;
826
-
827
- declare abstract class IntegrationBase {
828
- #private;
829
- private readonly serverUrl;
830
- protected constructor(serverUrl: string);
831
- }
832
-
833
- interface NextHandlerInc<U> {
834
- next: (schema: $ZodType) => U;
835
- }
836
- interface PrevInc<U> {
837
- prev: U;
838
- }
839
- type SchemaHandler<U, Context extends FlatObject = EmptyObject, Variant extends "regular" | "each" | "last" = "regular"> = (schema: any, // eslint-disable-line @typescript-eslint/no-explicit-any -- for assignment compatibility
840
- ctx: Context & (Variant extends "regular" ? NextHandlerInc<U> : Variant extends "each" ? PrevInc<U> : Context)) => U;
841
- type HandlingRules<U, Context extends FlatObject = EmptyObject, K extends string | symbol = string | symbol> = Partial<Record<K, SchemaHandler<U, Context>>>;
842
-
843
- interface ZTSContext extends FlatObject {
844
- isResponse: boolean;
845
- makeAlias: (key: object, produce: () => ts.TypeNode) => ts.TypeNode;
846
- }
847
- type Producer = SchemaHandler<ts.TypeNode, ZTSContext>;
848
-
849
- interface IntegrationParams {
850
- routing: Routing;
851
- /**
852
- * @desc What should be generated
853
- * @example "types" — types of your endpoint requests and responses (for a DIY solution)
854
- * @example "client" — an entity for performing typed requests and receiving typed responses
855
- * @default "client"
856
- * */
857
- variant?: "types" | "client";
858
- /** @default Client */
859
- clientClassName?: string;
860
- /** @default Subscription */
861
- subscriptionClassName?: string;
862
- /**
863
- * @desc The API URL to use in the generated code
864
- * @default https://example.com
865
- * */
866
- serverUrl?: string;
867
- /**
868
- * @desc The schema to use for responses without body such as 204
869
- * @default z.undefined()
870
- * */
871
- noContent?: z.ZodType;
872
- /**
873
- * @desc Handling rules for your own branded schemas.
874
- * @desc Keys: brands (recommended to use unique symbols).
875
- * @desc Values: functions having schema as first argument that you should assign type to, second one is a context.
876
- * @example { MyBrand: ( schema: typeof myBrandSchema, { next } ) => createKeywordTypeNode(SyntaxKind.AnyKeyword)
877
- */
878
- brandHandling?: HandlingRules<ts.TypeNode, ZTSContext>;
879
- }
880
- interface FormattedPrintingOptions {
881
- /** @desc Typescript printer options */
882
- printerOptions?: ts.PrinterOptions;
883
- /**
884
- * @desc Typescript code formatter
885
- * @default prettier.format
886
- * */
887
- format?: (program: string) => Promise<string>;
888
- }
889
- declare class Integration extends IntegrationBase {
890
- #private;
891
- constructor({ routing, brandHandling, variant, clientClassName, subscriptionClassName, serverUrl, noContent, }: IntegrationParams);
892
- print(printerOptions?: ts.PrinterOptions): string;
893
- printFormatted({ printerOptions, format: userDefined, }?: FormattedPrintingOptions): Promise<string>;
894
- }
895
-
896
- type EventsMap = Record<string, z.ZodType>;
897
- interface Emitter<E extends EventsMap> extends FlatObject {
898
- /** @desc Returns true when the connection was closed or terminated */
899
- isClosed: () => boolean;
900
- /** @desc Sends an event to the stream according to the declared schema */
901
- emit: <K extends keyof E>(event: K, data: z.input<E[K]>) => void;
902
- }
903
- declare class EventStreamFactory<E extends EventsMap> extends EndpointsFactory<undefined, Emitter<E>> {
904
- constructor(events: E);
905
- }
906
-
907
- /**
908
- * @since zod 3.25.44
909
- * @link https://github.com/colinhacks/zod/pull/4586
910
- * */
911
- declare const getExamples: (subject: $ZodType) => ReadonlyArray<unknown>;
912
-
913
- declare const base: z.ZodObject<{
914
- raw: z.core.$ZodBranded<z.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>, symbol>;
915
- }, z.core.$strip>;
916
- type Base = ReturnType<typeof base.brand<symbol>>;
917
- declare const extended: <S extends $ZodShape>(extra: S) => z.core.$ZodBranded<z.ZodObject<("raw" & keyof S extends never ? {
918
- raw: z.core.$ZodBranded<z.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>, symbol>;
919
- } & S : ({
920
- raw: z.core.$ZodBranded<z.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>, symbol>;
921
- } extends infer T_2 extends z.core.util.SomeObject ? { [K in keyof T_2 as K extends keyof S ? never : K]: {
922
- raw: z.core.$ZodBranded<z.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>, symbol>;
923
- }[K]; } : never) & { [K_1 in keyof S]: S[K_1]; }) extends infer T ? { [k in keyof T]: ("raw" & keyof S extends never ? {
924
- raw: z.core.$ZodBranded<z.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>, symbol>;
925
- } & S : ({
926
- raw: z.core.$ZodBranded<z.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>, symbol>;
927
- } extends infer T_1 extends z.core.util.SomeObject ? { [K in keyof T_1 as K extends keyof S ? never : K]: {
928
- raw: z.core.$ZodBranded<z.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>, symbol>;
929
- }[K]; } : never) & { [K_1 in keyof S]: S[K_1]; })[k]; } : never, z.core.$strip>, symbol>;
930
- declare function raw(): Base;
931
- declare function raw<S extends $ZodShape>(extra: S): ReturnType<typeof extended<S>>;
932
-
933
- declare const ez: {
934
- dateIn: ({ examples, ...rest }?: Parameters<zod_v4.ZodString["meta"]>[0]) => zod_v4_core.$ZodBranded<zod_v4.ZodPipe<zod_v4.ZodPipe<zod_v4.ZodUnion<readonly [zod_v4.ZodISODate, zod_v4.ZodISODateTime, zod_v4.ZodISODateTime]>, zod_v4.ZodTransform<Date, string>>, zod_v4.ZodDate>, symbol>;
935
- dateOut: (meta?: Parameters<zod_v4.ZodString["meta"]>[0]) => zod_v4_core.$ZodBranded<zod_v4.ZodPipe<zod_v4.ZodDate, zod_v4.ZodTransform<string, Date>>, symbol>;
936
- form: <S extends zod_v4_core.$ZodShape>(base: S | zod_v4.ZodObject<S>) => zod_v4_core.$ZodBranded<zod_v4.ZodObject<S, zod_v4_core.$strip>, symbol>;
937
- upload: () => zod_v4_core.$ZodBranded<zod_v4.ZodCustom<express_fileupload.UploadedFile, express_fileupload.UploadedFile>, symbol>;
938
- raw: typeof raw;
939
- buffer: () => zod_v4_core.$ZodBranded<zod_v4.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>, symbol>;
940
- };
941
-
942
- export { type ApiResponse, type AppConfig, type BasicSecurity, type BearerSecurity, BuiltinLogger, type CommonConfig, type CookieSecurity, DependsOnMethod, type Depicter, Documentation, DocumentationError, EndpointsFactory, EventStreamFactory, type FlatObject, type HeaderSecurity, type IOSchema, type InputSecurity, InputValidationError, Integration, type LoggerOverrides, type Method, Middleware, MissingPeerError, type OAuth2Security, type OpenIdSecurity, OutputValidationError, type Producer, ResultHandler, type Routing, RoutingError, ServeStatic, type ServerConfig, type TagOverrides, arrayEndpointsFactory, arrayResultHandler, attachRouting, createConfig, createServer, defaultEndpointsFactory, defaultResultHandler, ensureHttpError, ez, getExamples, getMessageFromError, testEndpoint, testMiddleware };