express-zod-api 28.7.4 → 29.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/CHANGELOG.md +63 -39
- package/README.md +27 -20
- package/SECURITY.md +2 -1
- package/dist/index.d.ts +300 -286
- package/dist/index.js +7 -18
- package/package.json +6 -6
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,14 @@ import { HttpError } from "http-errors";
|
|
|
3
3
|
import express, { CookieOptions, IRouter, NextFunction, Request, RequestHandler, Response } from "express";
|
|
4
4
|
import http from "node:http";
|
|
5
5
|
import { ServerOptions } from "node:https";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
InfoObject,
|
|
8
|
+
OpenApiBuilder,
|
|
9
|
+
ReferenceObject,
|
|
10
|
+
SchemaObjectValue,
|
|
11
|
+
ServerObject,
|
|
12
|
+
TagObject,
|
|
13
|
+
} from "openapi3-ts/oas32";
|
|
7
14
|
import { RequestOptions, ResponseOptions } from "node-mocks-http";
|
|
8
15
|
import compression from "compression";
|
|
9
16
|
import fileUpload from "express-fileupload";
|
|
@@ -11,12 +18,12 @@ import cookieParser from "cookie-parser";
|
|
|
11
18
|
import { ListenOptions } from "node:net";
|
|
12
19
|
import { AugmentedRequest, Options, RateLimitInfo, RateLimitRequestHandler } from "express-rate-limit";
|
|
13
20
|
import ts from "typescript";
|
|
14
|
-
declare const methods: ("get" | "post" | "put" | "delete" | "patch")[];
|
|
15
|
-
declare const clientMethods: ("get" | "post" | "put" | "delete" | "patch" | "head")[];
|
|
21
|
+
declare const methods: ("get" | "post" | "put" | "delete" | "patch" | "query")[];
|
|
22
|
+
declare const clientMethods: ("get" | "post" | "put" | "delete" | "patch" | "head" | "query")[];
|
|
16
23
|
/**
|
|
17
24
|
* @desc Methods supported by the framework API to produce Endpoints on EndpointsFactory.
|
|
18
25
|
* @see BuildProps
|
|
19
|
-
* @example "get" | "post" | "put" | "delete" | "patch"
|
|
26
|
+
* @example "get" | "post" | "put" | "delete" | "patch" | "query"
|
|
20
27
|
* */
|
|
21
28
|
type Method = (typeof methods)[number];
|
|
22
29
|
/**
|
|
@@ -148,181 +155,6 @@ type FinalInputSchema<FIN extends IOSchema | undefined, BIN extends IOSchema> =
|
|
|
148
155
|
FIN extends IOSchema ? FIN : BIN,
|
|
149
156
|
BIN
|
|
150
157
|
>;
|
|
151
|
-
type LogicalOr<T> = {
|
|
152
|
-
or: T[];
|
|
153
|
-
};
|
|
154
|
-
type LogicalAnd<T> = {
|
|
155
|
-
and: T[];
|
|
156
|
-
};
|
|
157
|
-
type LogicalContainer<T> = LogicalOr<T | LogicalAnd<T>> | LogicalAnd<T | LogicalOr<T>> | T;
|
|
158
|
-
interface BasicSecurity {
|
|
159
|
-
type: "basic";
|
|
160
|
-
}
|
|
161
|
-
interface BearerSecurity {
|
|
162
|
-
type: "bearer";
|
|
163
|
-
format?: "JWT" | string;
|
|
164
|
-
}
|
|
165
|
-
interface InputSecurity<K extends string> {
|
|
166
|
-
type: "input";
|
|
167
|
-
name: K;
|
|
168
|
-
}
|
|
169
|
-
interface HeaderSecurity {
|
|
170
|
-
type: "header";
|
|
171
|
-
name: string;
|
|
172
|
-
}
|
|
173
|
-
interface CookieSecurity {
|
|
174
|
-
type: "cookie";
|
|
175
|
-
name: string;
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* @see https://swagger.io/docs/specification/authentication/openid-connect-discovery/
|
|
179
|
-
* @desc available scopes has to be provided via the specified URL
|
|
180
|
-
*/
|
|
181
|
-
interface OpenIdSecurity {
|
|
182
|
-
type: "openid";
|
|
183
|
-
url: string;
|
|
184
|
-
}
|
|
185
|
-
interface AuthUrl {
|
|
186
|
-
/**
|
|
187
|
-
* @desc The authorization URL to use for this flow. Can be relative to the API server URL.
|
|
188
|
-
* @see https://swagger.io/docs/specification/api-host-and-base-path/
|
|
189
|
-
*/
|
|
190
|
-
authorizationUrl: string;
|
|
191
|
-
}
|
|
192
|
-
interface TokenUrl {
|
|
193
|
-
/** @desc The token URL to use for this flow. Can be relative to the API server URL. */
|
|
194
|
-
tokenUrl: string;
|
|
195
|
-
}
|
|
196
|
-
interface RefreshUrl {
|
|
197
|
-
/** @desc The URL to be used for obtaining refresh tokens. Can be relative to the API server URL. */
|
|
198
|
-
refreshUrl?: string;
|
|
199
|
-
}
|
|
200
|
-
interface Scopes<K extends string> {
|
|
201
|
-
/** @desc The available scopes for the OAuth2 security and their short descriptions. Optional. */
|
|
202
|
-
scopes?: Record<K, string>;
|
|
203
|
-
}
|
|
204
|
-
type AuthCodeFlow<S extends string> = AuthUrl & TokenUrl & RefreshUrl & Scopes<S>;
|
|
205
|
-
type ImplicitFlow<S extends string> = AuthUrl & RefreshUrl & Scopes<S>;
|
|
206
|
-
type PasswordFlow<S extends string> = TokenUrl & RefreshUrl & Scopes<S>;
|
|
207
|
-
type ClientCredFlow<S extends string> = TokenUrl & RefreshUrl & Scopes<S>;
|
|
208
|
-
/**
|
|
209
|
-
* @see https://swagger.io/docs/specification/authentication/oauth2/
|
|
210
|
-
*/
|
|
211
|
-
interface OAuth2Security<S extends string> {
|
|
212
|
-
type: "oauth2";
|
|
213
|
-
flows?: {
|
|
214
|
-
/** @desc Authorization Code flow (previously called accessCode in OpenAPI 2.0) */
|
|
215
|
-
authorizationCode?: AuthCodeFlow<S>;
|
|
216
|
-
/** @desc Implicit flow */
|
|
217
|
-
implicit?: ImplicitFlow<S>;
|
|
218
|
-
/** @desc Resource Owner Password flow */
|
|
219
|
-
password?: PasswordFlow<S>;
|
|
220
|
-
/** @desc Client Credentials flow (previously called application in OpenAPI 2.0) */
|
|
221
|
-
clientCredentials?: ClientCredFlow<S>;
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* @desc Middleware security schema descriptor
|
|
226
|
-
* @param K is an optional input field used by InputSecurity
|
|
227
|
-
* @param S is an optional union of scopes used by OAuth2Security
|
|
228
|
-
* */
|
|
229
|
-
type Security<K extends string = string, S extends string = string> =
|
|
230
|
-
| BasicSecurity
|
|
231
|
-
| BearerSecurity
|
|
232
|
-
| InputSecurity<K>
|
|
233
|
-
| HeaderSecurity
|
|
234
|
-
| CookieSecurity
|
|
235
|
-
| OpenIdSecurity
|
|
236
|
-
| OAuth2Security<S>;
|
|
237
|
-
type Handler$2<IN, CTX, RET> = (params: {
|
|
238
|
-
/** @desc The inputs from the enabled input sources validated against the input schema of the Middleware. */
|
|
239
|
-
input: IN;
|
|
240
|
-
/**
|
|
241
|
-
* @desc The returns of the previously executed Middlewares (typed when chaining Middlewares).
|
|
242
|
-
* @link https://github.com/RobinTail/express-zod-api/discussions/1250
|
|
243
|
-
* */
|
|
244
|
-
ctx: CTX;
|
|
245
|
-
/** @link https://expressjs.com/en/5x/api.html#req */
|
|
246
|
-
request: Request;
|
|
247
|
-
/** @link https://expressjs.com/en/5x/api.html#res */
|
|
248
|
-
response: Response;
|
|
249
|
-
/** @desc The instance of the configured logger. */
|
|
250
|
-
logger: ActualLogger;
|
|
251
|
-
}) => Promise<RET>;
|
|
252
|
-
declare abstract class AbstractMiddleware {
|
|
253
|
-
abstract execute(params: {
|
|
254
|
-
input: unknown;
|
|
255
|
-
ctx: FlatObject;
|
|
256
|
-
request: Request;
|
|
257
|
-
response: Response;
|
|
258
|
-
logger: ActualLogger;
|
|
259
|
-
}): Promise<FlatObject>;
|
|
260
|
-
}
|
|
261
|
-
/**
|
|
262
|
-
* @desc A Middleware that validates its input schema, executes its handler, and returns context properties available to
|
|
263
|
-
* next middlewares and the Endpoint handler. Can also declare security schemas for Documentation.
|
|
264
|
-
* @see EndpointsFactory#addMiddleware
|
|
265
|
-
* */
|
|
266
|
-
declare class Middleware<
|
|
267
|
-
CTX extends FlatObject,
|
|
268
|
-
RET extends FlatObject,
|
|
269
|
-
SCO extends string,
|
|
270
|
-
IN extends IOSchema | undefined = undefined,
|
|
271
|
-
> extends AbstractMiddleware {
|
|
272
|
-
constructor({
|
|
273
|
-
input,
|
|
274
|
-
security,
|
|
275
|
-
handler,
|
|
276
|
-
}: {
|
|
277
|
-
/**
|
|
278
|
-
* @desc Input schema of the Middleware, combining properties from all the enabled input sources
|
|
279
|
-
* @default undefined
|
|
280
|
-
* @see defaultInputSources
|
|
281
|
-
* */
|
|
282
|
-
input?: IN;
|
|
283
|
-
/**
|
|
284
|
-
* @desc Declaration of the security schemas implemented within the handler (used by Documentation).
|
|
285
|
-
* @see Documentation
|
|
286
|
-
* */
|
|
287
|
-
security?: LogicalContainer<Security<Extract<keyof z.input<IN>, string>, SCO>>;
|
|
288
|
-
/** @desc The handler returning a context available to Endpoints. */
|
|
289
|
-
handler: Handler$2<z.output<IN>, CTX, RET>;
|
|
290
|
-
});
|
|
291
|
-
/** @throws InputValidationError */
|
|
292
|
-
execute({
|
|
293
|
-
input,
|
|
294
|
-
...rest
|
|
295
|
-
}: {
|
|
296
|
-
input: unknown;
|
|
297
|
-
ctx: CTX;
|
|
298
|
-
request: Request;
|
|
299
|
-
response: Response;
|
|
300
|
-
logger: ActualLogger;
|
|
301
|
-
}): Promise<RET>;
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* @desc A wrapper around native Express middlewares that converts them into the framework's Middleware instances.
|
|
305
|
-
* Optionally, a `provider` can extend the context, and a `transformer` can convert caught errors.
|
|
306
|
-
* @see EndpointsFactory#addExpressMiddleware
|
|
307
|
-
* */
|
|
308
|
-
declare class ExpressMiddleware<R extends Request, S extends Response, RET extends FlatObject> extends Middleware<
|
|
309
|
-
FlatObject,
|
|
310
|
-
RET,
|
|
311
|
-
string
|
|
312
|
-
> {
|
|
313
|
-
constructor(
|
|
314
|
-
nativeMw: (request: R, response: S, next: NextFunction) => any,
|
|
315
|
-
{
|
|
316
|
-
provider,
|
|
317
|
-
transformer,
|
|
318
|
-
}?: {
|
|
319
|
-
/** @desc Extracts context properties from request and response after the native middleware execution. */
|
|
320
|
-
provider?: (request: R, response: S) => RET | Promise<RET>;
|
|
321
|
-
/** @desc Transforms errors caught from the native middleware before they propagate further. */
|
|
322
|
-
transformer?: (err: Error) => Error;
|
|
323
|
-
},
|
|
324
|
-
);
|
|
325
|
-
}
|
|
326
158
|
type ResultSchema<R extends Result> = R extends Result<infer S> ? S : never;
|
|
327
159
|
type DiscriminatedResult =
|
|
328
160
|
| {
|
|
@@ -338,7 +170,7 @@ type DiscriminatedResult =
|
|
|
338
170
|
* @example Error —> InternalServerError(500)
|
|
339
171
|
* */
|
|
340
172
|
declare const ensureHttpError: (error: Error) => HttpError;
|
|
341
|
-
type Handler$
|
|
173
|
+
type Handler$2<RES = unknown> = (
|
|
342
174
|
params: DiscriminatedResult & {
|
|
343
175
|
/** null in case of failure to parse or to find the matching endpoint (error: not found) */
|
|
344
176
|
input: FlatObject | null;
|
|
@@ -357,8 +189,8 @@ type Result<S extends z.ZodType = z.ZodType> = S | ApiResponse<S> | ApiResponse<
|
|
|
357
189
|
/** @desc A function that lazily produces a Result definition. */
|
|
358
190
|
type LazyResult<R extends Result, A extends unknown[] = []> = (...args: A) => R;
|
|
359
191
|
declare abstract class AbstractResultHandler {
|
|
360
|
-
protected constructor(handler: Handler$
|
|
361
|
-
execute(...params: Parameters<Handler$
|
|
192
|
+
protected constructor(handler: Handler$2);
|
|
193
|
+
execute(...params: Parameters<Handler$2>): Promise<void>;
|
|
362
194
|
}
|
|
363
195
|
/**
|
|
364
196
|
* @desc The entity responsible to respond consistently. Accepts positive and negative Result definitions.
|
|
@@ -372,7 +204,7 @@ declare class ResultHandler<POS extends Result, NEG extends Result> extends Abst
|
|
|
372
204
|
/** @desc A description of the API response in case of error (schema, status code, MIME type) */
|
|
373
205
|
negative: NEG | LazyResult<NEG>;
|
|
374
206
|
/** @desc The actual implementation to transmit the response in any case */
|
|
375
|
-
handler: Handler$
|
|
207
|
+
handler: Handler$2<z.output<ResultSchema<POS> | ResultSchema<NEG>>>;
|
|
376
208
|
});
|
|
377
209
|
}
|
|
378
210
|
/**
|
|
@@ -414,90 +246,21 @@ declare const arrayResultHandler: ResultHandler<
|
|
|
414
246
|
mimeType: string;
|
|
415
247
|
}
|
|
416
248
|
>;
|
|
417
|
-
type OriginalStatic = typeof express.static;
|
|
418
|
-
declare class ServeStatic {
|
|
419
|
-
constructor(...params: Parameters<OriginalStatic>);
|
|
420
|
-
}
|
|
421
249
|
/** @desc Returns child logger for the given request (if configured) or the configured logger otherwise */
|
|
422
250
|
type GetLogger = (request?: Request) => ActualLogger;
|
|
423
|
-
/**
|
|
424
|
-
* @example { v1: { books: { ":bookId": getBookEndpoint } } }
|
|
425
|
-
* @example { "v1/books/:bookId": getBookEndpoint }
|
|
426
|
-
* @example { "get /v1/books/:bookId": getBookEndpoint }
|
|
427
|
-
* @example { v1: { "patch /books/:bookId": changeBookEndpoint } }
|
|
428
|
-
* @example { dependsOnMethod: { get: retrieveEndpoint, post: createEndpoint } }
|
|
429
|
-
* @see CommonConfig.recognizeMethodDependentRoutes
|
|
430
|
-
* */
|
|
431
|
-
interface Routing {
|
|
432
|
-
[K: string]: Routing | AbstractEndpoint | ServeStatic;
|
|
433
|
-
}
|
|
434
|
-
type Handler<IN, OUT, CTX> = (params: {
|
|
435
|
-
/** @desc The inputs from the enabled input sources validated against the final input schema (incl. Middlewares) */
|
|
436
|
-
input: IN;
|
|
437
|
-
/** @desc The returns of the assigned Middlewares */
|
|
438
|
-
ctx: CTX;
|
|
439
|
-
/** @desc The instance of the configured logger */
|
|
440
|
-
logger: ActualLogger;
|
|
441
|
-
}) => Promise<OUT>;
|
|
442
|
-
declare abstract class AbstractEndpoint {
|
|
443
|
-
/** @desc Enables nested routes within the path assigned to the subject */
|
|
444
|
-
nest(routing: Routing): Routing;
|
|
445
|
-
/** @desc Marks the route as deprecated (makes a copy of the endpoint) */
|
|
446
|
-
abstract deprecated(): this;
|
|
447
|
-
abstract execute(params: {
|
|
448
|
-
request: Request;
|
|
449
|
-
response: Response;
|
|
450
|
-
logger: ActualLogger;
|
|
451
|
-
config: CommonConfig;
|
|
452
|
-
}): Promise<void>;
|
|
453
|
-
}
|
|
454
|
-
declare class Endpoint<IN extends IOSchema, OUT extends IOSchema, CTX extends FlatObject> extends AbstractEndpoint {
|
|
455
|
-
constructor(def: {
|
|
456
|
-
deprecated?: boolean;
|
|
457
|
-
middlewares?: AbstractMiddleware[];
|
|
458
|
-
inputSchema: IN;
|
|
459
|
-
outputSchema: OUT;
|
|
460
|
-
handler: Handler<z.output<IN>, z.input<OUT>, CTX>;
|
|
461
|
-
resultHandler: AbstractResultHandler;
|
|
462
|
-
description?: string;
|
|
463
|
-
summary?: string;
|
|
464
|
-
getOperationId?: (method: ClientMethod) => string | undefined;
|
|
465
|
-
methods?: Method[];
|
|
466
|
-
scopes?: string[];
|
|
467
|
-
tags?: string[];
|
|
468
|
-
});
|
|
469
|
-
deprecated(): this;
|
|
470
|
-
execute({
|
|
471
|
-
request,
|
|
472
|
-
response,
|
|
473
|
-
logger,
|
|
474
|
-
config,
|
|
475
|
-
}: {
|
|
476
|
-
request: Request;
|
|
477
|
-
response: Response;
|
|
478
|
-
logger: ActualLogger;
|
|
479
|
-
config: CommonConfig;
|
|
480
|
-
}): Promise<undefined>;
|
|
481
|
-
}
|
|
482
251
|
type InputSource = keyof Pick<Request, "query" | "body" | "files" | "params" | "headers" | "cookies" | "signedCookies">;
|
|
483
252
|
type InputSources = Record<Method, InputSource[]>;
|
|
484
|
-
type Headers = Record<string, string>;
|
|
485
|
-
type HeadersProvider = (params: {
|
|
486
|
-
/** @desc The default headers to be overridden. */
|
|
487
|
-
defaultHeaders: Headers;
|
|
488
|
-
request: Request;
|
|
489
|
-
endpoint: AbstractEndpoint;
|
|
490
|
-
logger: ActualLogger;
|
|
491
|
-
}) => Headers | Promise<Headers>;
|
|
492
253
|
type ChildLoggerProvider = (params: { request: Request; parent: ActualLogger }) => ActualLogger | Promise<ActualLogger>;
|
|
493
254
|
type LogAccess = (request: Request, logger: ActualLogger) => void;
|
|
494
255
|
interface CommonConfig {
|
|
495
256
|
/**
|
|
496
257
|
* @desc Enables cross-origin resource sharing.
|
|
258
|
+
* @desc You can provide custom middleware or the `cors` package.
|
|
259
|
+
* @example cors({ origin: "https://example.com" }) // import cors from "cors"
|
|
497
260
|
* @link https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
|
498
|
-
* @
|
|
261
|
+
* @link https://www.npmjs.com/package/cors
|
|
499
262
|
*/
|
|
500
|
-
cors: boolean |
|
|
263
|
+
cors: boolean | RequestHandler;
|
|
501
264
|
/**
|
|
502
265
|
* @desc Controls how to respond to a request to an existing endpoint with an invalid HTTP method.
|
|
503
266
|
* @example true — respond with status code 405 and "Allow" header containing a list of valid methods
|
|
@@ -599,12 +362,11 @@ interface GracefulOptions {
|
|
|
599
362
|
/** @desc The hook to call after the server was closed, but before terminating the process. */
|
|
600
363
|
beforeExit?: () => void | Promise<void>;
|
|
601
364
|
}
|
|
602
|
-
/** @todo consider removing Promise to make createServer sync in next major */
|
|
603
365
|
type ServerHook = (params: {
|
|
604
366
|
app: IRouter;
|
|
605
367
|
/** @desc Returns child logger for the given request (if configured) or the configured logger otherwise */
|
|
606
368
|
getLogger: GetLogger;
|
|
607
|
-
}) => void
|
|
369
|
+
}) => void;
|
|
608
370
|
interface HttpConfig {
|
|
609
371
|
/** @desc Port, UNIX socket or custom options. */
|
|
610
372
|
listen: number | string | ListenOptions;
|
|
@@ -619,7 +381,7 @@ interface ServerConfig extends CommonConfig {
|
|
|
619
381
|
/** @desc HTTPS server configuration. */
|
|
620
382
|
https?: HttpsConfig;
|
|
621
383
|
/**
|
|
622
|
-
* @desc Custom JSON parser.
|
|
384
|
+
* @desc Custom JSON parser applied to all incoming requests.
|
|
623
385
|
* @default express.json()
|
|
624
386
|
* @link https://expressjs.com/en/5x/api.html#express.json
|
|
625
387
|
* */
|
|
@@ -651,19 +413,25 @@ interface ServerConfig extends CommonConfig {
|
|
|
651
413
|
*/
|
|
652
414
|
queryParser?: "simple" | "extended" | ((query: string) => object);
|
|
653
415
|
/**
|
|
654
|
-
* @desc Custom
|
|
416
|
+
* @desc Custom parser for Buffer payloads applied to all incoming requests.
|
|
655
417
|
* @default express.raw()
|
|
656
418
|
* @link https://expressjs.com/en/5x/api.html#express.raw
|
|
657
419
|
* */
|
|
658
420
|
rawParser?: RequestHandler;
|
|
659
421
|
/**
|
|
660
|
-
* @desc Custom parser for URL Encoded requests
|
|
422
|
+
* @desc Custom parser for URL Encoded requests applied to all incoming requests.
|
|
661
423
|
* @default express.urlencoded()
|
|
662
424
|
* @link https://expressjs.com/en/5x/api.html#express.urlencoded
|
|
663
425
|
* */
|
|
664
426
|
formParser?: RequestHandler;
|
|
665
427
|
/**
|
|
666
|
-
* @desc A code to execute before
|
|
428
|
+
* @desc A code to execute before the installation of parsers (compression, cookies, CORS, body).
|
|
429
|
+
* @example ({ app }) => { app.use(helmet()); }
|
|
430
|
+
* */
|
|
431
|
+
beforeParsers?: ServerHook;
|
|
432
|
+
/**
|
|
433
|
+
* @desc A code to execute before processing the Routing of your API.
|
|
434
|
+
* @desc Runs after compression, cookies, CORS and body parsers are installed.
|
|
667
435
|
* @desc This can be a good place for express middlewares establishing their own routes.
|
|
668
436
|
* @desc It can help to avoid making a DIY solution based on the attachRouting() approach.
|
|
669
437
|
* @example ({ app }) => { app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument)); }
|
|
@@ -685,6 +453,199 @@ interface AppConfig extends CommonConfig {
|
|
|
685
453
|
}
|
|
686
454
|
declare function createConfig(config: ServerConfig): ServerConfig;
|
|
687
455
|
declare function createConfig(config: AppConfig): AppConfig;
|
|
456
|
+
type LogicalOr<T> = {
|
|
457
|
+
or: T[];
|
|
458
|
+
};
|
|
459
|
+
type LogicalAnd<T> = {
|
|
460
|
+
and: T[];
|
|
461
|
+
};
|
|
462
|
+
type LogicalContainer<T> = LogicalOr<T | LogicalAnd<T>> | LogicalAnd<T | LogicalOr<T>> | T;
|
|
463
|
+
interface BasicSecurity {
|
|
464
|
+
type: "basic";
|
|
465
|
+
}
|
|
466
|
+
interface BearerSecurity {
|
|
467
|
+
type: "bearer";
|
|
468
|
+
format?: "JWT" | string;
|
|
469
|
+
}
|
|
470
|
+
interface InputSecurity<K extends string> {
|
|
471
|
+
type: "input";
|
|
472
|
+
name: K;
|
|
473
|
+
}
|
|
474
|
+
interface HeaderSecurity {
|
|
475
|
+
type: "header";
|
|
476
|
+
name: string;
|
|
477
|
+
}
|
|
478
|
+
interface CookieSecurity {
|
|
479
|
+
type: "cookie";
|
|
480
|
+
name: string;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* @see https://swagger.io/docs/specification/authentication/openid-connect-discovery/
|
|
484
|
+
* @desc available scopes has to be provided via the specified URL
|
|
485
|
+
*/
|
|
486
|
+
interface OpenIdSecurity {
|
|
487
|
+
type: "openid";
|
|
488
|
+
url: string;
|
|
489
|
+
}
|
|
490
|
+
interface AuthUrl {
|
|
491
|
+
/**
|
|
492
|
+
* @desc The authorization URL to use for this flow. Can be relative to the API server URL.
|
|
493
|
+
* @see https://swagger.io/docs/specification/api-host-and-base-path/
|
|
494
|
+
*/
|
|
495
|
+
authorizationUrl: string;
|
|
496
|
+
}
|
|
497
|
+
interface DeviceAuthUrl {
|
|
498
|
+
/** @desc The device authorization URL to use for this flow (RFC 8628). Can be relative to the API server URL. */
|
|
499
|
+
deviceAuthorizationUrl: string;
|
|
500
|
+
}
|
|
501
|
+
interface TokenUrl {
|
|
502
|
+
/** @desc The token URL to use for this flow. Can be relative to the API server URL. */
|
|
503
|
+
tokenUrl: string;
|
|
504
|
+
}
|
|
505
|
+
interface RefreshUrl {
|
|
506
|
+
/** @desc The URL to be used for obtaining refresh tokens. Can be relative to the API server URL. */
|
|
507
|
+
refreshUrl?: string;
|
|
508
|
+
}
|
|
509
|
+
interface Scopes<K extends string> {
|
|
510
|
+
/** @desc The available scopes for the OAuth2 security and their short descriptions. Optional. */
|
|
511
|
+
scopes?: Record<K, string>;
|
|
512
|
+
}
|
|
513
|
+
type AuthCodeFlow<S extends string> = AuthUrl & TokenUrl & RefreshUrl & Scopes<S>;
|
|
514
|
+
type ImplicitFlow<S extends string> = AuthUrl & RefreshUrl & Scopes<S>;
|
|
515
|
+
type PasswordFlow<S extends string> = TokenUrl & RefreshUrl & Scopes<S>;
|
|
516
|
+
type ClientCredFlow<S extends string> = TokenUrl & RefreshUrl & Scopes<S>;
|
|
517
|
+
type DeviceAuthFlow<S extends string> = DeviceAuthUrl & TokenUrl & RefreshUrl & Scopes<S>;
|
|
518
|
+
/**
|
|
519
|
+
* @see https://swagger.io/docs/specification/authentication/oauth2/
|
|
520
|
+
*/
|
|
521
|
+
interface OAuth2Security<S extends string> {
|
|
522
|
+
type: "oauth2";
|
|
523
|
+
/**
|
|
524
|
+
* @desc URL to OAuth 2.0 Authorization Server metadata document
|
|
525
|
+
* @link https://www.rfc-editor.org/rfc/rfc8414
|
|
526
|
+
* */
|
|
527
|
+
oauth2MetadataUrl?: string;
|
|
528
|
+
flows?: {
|
|
529
|
+
/** @desc Authorization Code flow (previously called accessCode in OpenAPI 2.0) */
|
|
530
|
+
authorizationCode?: AuthCodeFlow<S>;
|
|
531
|
+
/** @desc Implicit flow */
|
|
532
|
+
implicit?: ImplicitFlow<S>;
|
|
533
|
+
/** @desc Resource Owner Password flow */
|
|
534
|
+
password?: PasswordFlow<S>;
|
|
535
|
+
/** @desc Client Credentials flow (previously called application in OpenAPI 2.0) */
|
|
536
|
+
clientCredentials?: ClientCredFlow<S>;
|
|
537
|
+
/**
|
|
538
|
+
* @desc Device Authorization flow (OAuth 2.0 Device Authorization Grant)
|
|
539
|
+
* @link https://oauth.net/2/device-flow/
|
|
540
|
+
* */
|
|
541
|
+
deviceAuthorization?: DeviceAuthFlow<S>;
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* @desc Middleware security schema descriptor
|
|
546
|
+
* @param K is an optional input field used by InputSecurity
|
|
547
|
+
* @param S is an optional union of scopes used by OAuth2Security
|
|
548
|
+
* */
|
|
549
|
+
type Security<K extends string = string, S extends string = string> = (
|
|
550
|
+
| BasicSecurity
|
|
551
|
+
| BearerSecurity
|
|
552
|
+
| InputSecurity<K>
|
|
553
|
+
| HeaderSecurity
|
|
554
|
+
| CookieSecurity
|
|
555
|
+
| OpenIdSecurity
|
|
556
|
+
| OAuth2Security<S>
|
|
557
|
+
) & {
|
|
558
|
+
deprecated?: boolean;
|
|
559
|
+
};
|
|
560
|
+
type Handler$1<IN, CTX, RET> = (params: {
|
|
561
|
+
/** @desc The inputs from the enabled input sources validated against the input schema of the Middleware. */
|
|
562
|
+
input: IN;
|
|
563
|
+
/**
|
|
564
|
+
* @desc The returns of the previously executed Middlewares (typed when chaining Middlewares).
|
|
565
|
+
* @link https://github.com/RobinTail/express-zod-api/discussions/1250
|
|
566
|
+
* */
|
|
567
|
+
ctx: CTX;
|
|
568
|
+
/** @link https://expressjs.com/en/5x/api.html#req */
|
|
569
|
+
request: Request;
|
|
570
|
+
/** @link https://expressjs.com/en/5x/api.html#res */
|
|
571
|
+
response: Response;
|
|
572
|
+
/** @desc The instance of the configured logger. */
|
|
573
|
+
logger: ActualLogger;
|
|
574
|
+
}) => Promise<RET>;
|
|
575
|
+
declare abstract class AbstractMiddleware {
|
|
576
|
+
abstract execute(params: {
|
|
577
|
+
input: unknown;
|
|
578
|
+
ctx: FlatObject;
|
|
579
|
+
request: Request;
|
|
580
|
+
response: Response;
|
|
581
|
+
logger: ActualLogger;
|
|
582
|
+
}): Promise<FlatObject>;
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* @desc A Middleware that validates its input schema, executes its handler, and returns context properties available to
|
|
586
|
+
* next middlewares and the Endpoint handler. Can also declare security schemas for Documentation.
|
|
587
|
+
* @see EndpointsFactory#addMiddleware
|
|
588
|
+
* */
|
|
589
|
+
declare class Middleware<
|
|
590
|
+
CTX extends FlatObject,
|
|
591
|
+
RET extends FlatObject,
|
|
592
|
+
SCO extends string,
|
|
593
|
+
IN extends IOSchema | undefined = undefined,
|
|
594
|
+
> extends AbstractMiddleware {
|
|
595
|
+
constructor({
|
|
596
|
+
input,
|
|
597
|
+
security,
|
|
598
|
+
handler,
|
|
599
|
+
}: {
|
|
600
|
+
/**
|
|
601
|
+
* @desc Input schema of the Middleware, combining properties from all the enabled input sources
|
|
602
|
+
* @default undefined
|
|
603
|
+
* @see defaultInputSources
|
|
604
|
+
* */
|
|
605
|
+
input?: IN;
|
|
606
|
+
/**
|
|
607
|
+
* @desc Declaration of the security schemas implemented within the handler (used by Documentation).
|
|
608
|
+
* @see Documentation
|
|
609
|
+
* */
|
|
610
|
+
security?: LogicalContainer<Security<Extract<keyof z.input<IN>, string>, SCO>>;
|
|
611
|
+
/** @desc The handler returning a context available to Endpoints. */
|
|
612
|
+
handler: Handler$1<z.output<IN>, CTX, RET>;
|
|
613
|
+
});
|
|
614
|
+
/** @throws InputValidationError */
|
|
615
|
+
execute({
|
|
616
|
+
input,
|
|
617
|
+
...rest
|
|
618
|
+
}: {
|
|
619
|
+
input: unknown;
|
|
620
|
+
ctx: CTX;
|
|
621
|
+
request: Request;
|
|
622
|
+
response: Response;
|
|
623
|
+
logger: ActualLogger;
|
|
624
|
+
}): Promise<RET>;
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* @desc A wrapper around native Express middlewares that converts them into the framework's Middleware instances.
|
|
628
|
+
* Optionally, a `provider` can extend the context, and a `transformer` can convert caught errors.
|
|
629
|
+
* @see EndpointsFactory#addExpressMiddleware
|
|
630
|
+
* */
|
|
631
|
+
declare class ExpressMiddleware<R extends Request, S extends Response, RET extends FlatObject> extends Middleware<
|
|
632
|
+
FlatObject,
|
|
633
|
+
RET,
|
|
634
|
+
string
|
|
635
|
+
> {
|
|
636
|
+
constructor(
|
|
637
|
+
nativeMw: (request: R, response: S, next: NextFunction) => any,
|
|
638
|
+
{
|
|
639
|
+
provider,
|
|
640
|
+
transformer,
|
|
641
|
+
}?: {
|
|
642
|
+
/** @desc Extracts context properties from request and response after the native middleware execution. */
|
|
643
|
+
provider?: (request: R, response: S) => RET | Promise<RET>;
|
|
644
|
+
/** @desc Transforms errors caught from the native middleware before they propagate further. */
|
|
645
|
+
transformer?: (err: Error) => Error;
|
|
646
|
+
},
|
|
647
|
+
);
|
|
648
|
+
}
|
|
688
649
|
/**
|
|
689
650
|
* @desc Directives shared by both request and response Cache-Control headers.
|
|
690
651
|
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#cache_directives
|
|
@@ -853,6 +814,69 @@ declare const createCacheMiddleware: (defaultPolicy?: CachePolicy) => Middleware
|
|
|
853
814
|
string,
|
|
854
815
|
undefined
|
|
855
816
|
>;
|
|
817
|
+
type OriginalStatic = typeof express.static;
|
|
818
|
+
declare class ServeStatic {
|
|
819
|
+
constructor(...params: Parameters<OriginalStatic>);
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* @example { v1: { books: { ":bookId": getBookEndpoint } } }
|
|
823
|
+
* @example { "v1/books/:bookId": getBookEndpoint }
|
|
824
|
+
* @example { "get /v1/books/:bookId": getBookEndpoint }
|
|
825
|
+
* @example { v1: { "patch /books/:bookId": changeBookEndpoint } }
|
|
826
|
+
* @example { dependsOnMethod: { get: retrieveEndpoint, post: createEndpoint } }
|
|
827
|
+
* @see CommonConfig.recognizeMethodDependentRoutes
|
|
828
|
+
* */
|
|
829
|
+
interface Routing {
|
|
830
|
+
[K: string]: Routing | AbstractEndpoint | ServeStatic;
|
|
831
|
+
}
|
|
832
|
+
type Handler<IN, OUT, CTX> = (params: {
|
|
833
|
+
/** @desc The inputs from the enabled input sources validated against the final input schema (incl. Middlewares) */
|
|
834
|
+
input: IN;
|
|
835
|
+
/** @desc The returns of the assigned Middlewares */
|
|
836
|
+
ctx: CTX;
|
|
837
|
+
/** @desc The instance of the configured logger */
|
|
838
|
+
logger: ActualLogger;
|
|
839
|
+
}) => Promise<OUT>;
|
|
840
|
+
declare abstract class AbstractEndpoint {
|
|
841
|
+
/** @desc Enables nested routes within the path assigned to the subject */
|
|
842
|
+
nest(routing: Routing): Routing;
|
|
843
|
+
/** @desc Marks the route as deprecated (makes a copy of the endpoint) */
|
|
844
|
+
abstract deprecated(): this;
|
|
845
|
+
abstract execute(params: {
|
|
846
|
+
request: Request;
|
|
847
|
+
response: Response;
|
|
848
|
+
logger: ActualLogger;
|
|
849
|
+
config: CommonConfig;
|
|
850
|
+
}): Promise<void>;
|
|
851
|
+
}
|
|
852
|
+
declare class Endpoint<IN extends IOSchema, OUT extends IOSchema, CTX extends FlatObject> extends AbstractEndpoint {
|
|
853
|
+
constructor(def: {
|
|
854
|
+
deprecated?: boolean;
|
|
855
|
+
middlewares?: AbstractMiddleware[];
|
|
856
|
+
inputSchema: IN;
|
|
857
|
+
outputSchema: OUT;
|
|
858
|
+
handler: Handler<z.output<IN>, z.input<OUT>, CTX>;
|
|
859
|
+
resultHandler: AbstractResultHandler;
|
|
860
|
+
description?: string;
|
|
861
|
+
summary?: string;
|
|
862
|
+
getOperationId?: (method: ClientMethod) => string | undefined;
|
|
863
|
+
methods?: Method[];
|
|
864
|
+
scopes?: string[];
|
|
865
|
+
tags?: string[];
|
|
866
|
+
});
|
|
867
|
+
deprecated(): this;
|
|
868
|
+
execute({
|
|
869
|
+
request,
|
|
870
|
+
response,
|
|
871
|
+
logger,
|
|
872
|
+
config,
|
|
873
|
+
}: {
|
|
874
|
+
request: Request;
|
|
875
|
+
response: Response;
|
|
876
|
+
logger: ActualLogger;
|
|
877
|
+
config: CommonConfig;
|
|
878
|
+
}): Promise<undefined>;
|
|
879
|
+
}
|
|
856
880
|
/**
|
|
857
881
|
* @desc Creates a Middleware providing cookie-setting convenience methods.
|
|
858
882
|
* @param baseOptions — Default options applied to every setCookie / clearCookie call.
|
|
@@ -1108,13 +1132,13 @@ declare const attachRouting: (
|
|
|
1108
1132
|
declare const createServer: (
|
|
1109
1133
|
config: ServerConfig,
|
|
1110
1134
|
routing: Routing,
|
|
1111
|
-
) =>
|
|
1135
|
+
) => {
|
|
1112
1136
|
app: import("express-serve-static-core").Express;
|
|
1113
1137
|
logger: AbstractLogger | BuiltinLogger;
|
|
1114
1138
|
servers: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>[];
|
|
1115
|
-
}
|
|
1139
|
+
};
|
|
1116
1140
|
interface ReqResCommons {
|
|
1117
|
-
makeRef: (key: object | string, value:
|
|
1141
|
+
makeRef: (key: object | string, value: SchemaObjectValue | ReferenceObject, proposedName?: string) => ReferenceObject;
|
|
1118
1142
|
path: string;
|
|
1119
1143
|
method: ClientMethod;
|
|
1120
1144
|
}
|
|
@@ -1127,22 +1151,16 @@ type Depicter = (
|
|
|
1127
1151
|
jsonSchema: z.core.JSONSchema.BaseSchema;
|
|
1128
1152
|
},
|
|
1129
1153
|
oasCtx: OpenAPIContext,
|
|
1130
|
-
) => z.core.JSONSchema.BaseSchema |
|
|
1154
|
+
) => z.core.JSONSchema.BaseSchema | SchemaObjectValue;
|
|
1131
1155
|
/** @desc Using defaultIsHeader when returns null or undefined */
|
|
1132
1156
|
type IsHeader = (name: string, method: ClientMethod, path: string) => boolean | null | undefined;
|
|
1133
1157
|
type BrandHandling = Record<string | symbol, Depicter>;
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
description: string;
|
|
1141
|
-
url?: string;
|
|
1142
|
-
}
|
|
1143
|
-
>
|
|
1144
|
-
>,
|
|
1145
|
-
) => TagObject[];
|
|
1158
|
+
interface TagDetails extends Pick<TagObject, "summary" | "description" | "externalDocs" | "kind"> {
|
|
1159
|
+
/** @desc shorthand for externalDocs.url */
|
|
1160
|
+
url?: string;
|
|
1161
|
+
parent?: Tag;
|
|
1162
|
+
}
|
|
1163
|
+
declare const depictTags: (tags: Partial<Record<Tag, string | TagDetails>>) => TagObject[];
|
|
1146
1164
|
/** @desc Ensures the summary string does not exceed the limit */
|
|
1147
1165
|
declare const trimSummary: (summary?: string, limit?: number) => string | undefined;
|
|
1148
1166
|
type Component = `${ResponseVariant}Response` | "requestParameter" | "requestBody";
|
|
@@ -1154,9 +1172,10 @@ type Descriptor = (
|
|
|
1154
1172
|
) => string;
|
|
1155
1173
|
type Summarizer = (params: { summary?: string; description?: string; trim: typeof trimSummary }) => string | undefined;
|
|
1156
1174
|
interface DocumentationParams {
|
|
1157
|
-
title
|
|
1158
|
-
|
|
1159
|
-
|
|
1175
|
+
/** @desc At least title and version properties are required */
|
|
1176
|
+
info: InfoObject;
|
|
1177
|
+
/** @desc Server URL(s) or their complete definitions */
|
|
1178
|
+
server: string | [string, ...string[]] | ServerObject | [ServerObject, ...ServerObject[]];
|
|
1160
1179
|
routing: Routing;
|
|
1161
1180
|
config: CommonConfig;
|
|
1162
1181
|
/**
|
|
@@ -1396,11 +1415,6 @@ declare class Integration extends IntegrationBase {
|
|
|
1396
1415
|
noBodySchema,
|
|
1397
1416
|
hasHeadMethod,
|
|
1398
1417
|
}: IntegrationParams);
|
|
1399
|
-
/**
|
|
1400
|
-
* @deprecated use `new Integration()` without `typescript` option on its argument
|
|
1401
|
-
* @todo remove in the next major — no longer needed
|
|
1402
|
-
* */
|
|
1403
|
-
static create(params: Omit<IntegrationParams, "typescript">): Promise<Integration>;
|
|
1404
1418
|
print(printerOptions?: ts.PrinterOptions): string;
|
|
1405
1419
|
printFormatted({ printerOptions, format: userDefined }?: FormattedPrintingOptions): Promise<string>;
|
|
1406
1420
|
}
|