@tahminator/sapling 2.0.3 → 2.0.5-beta.2f539758

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/README.md CHANGED
@@ -200,12 +200,71 @@ class UserController {
200
200
  }
201
201
  ```
202
202
 
203
- Make sure to register an error handler middleware:
203
+ Sapling ships with default error middlewares, and you can also write your own.
204
+ Register error middlewares after your regular middlewares and controllers:
204
205
 
205
206
  ```typescript
206
- Sapling.loadResponseStatusErrorMiddleware(app, (err, req, res, next) => {
207
- res.status(err.status).json({ error: err.message });
208
- });
207
+ import {
208
+ DefaultBaseErrorMiddleware,
209
+ DefaultResponseStatusErrorMiddleware,
210
+ } from "@tahminator/sapling";
211
+
212
+ // regular middlewares & controllers first
213
+ const middlewares: Class<any>[] = [CookieParserMiddleware];
214
+ middlewares.map(Sapling.resolve).forEach((r) => app.use(r));
215
+
216
+ const controllers: Class<any>[] = [UserController];
217
+ controllers.map(Sapling.resolve).forEach((r) => app.use(r));
218
+
219
+ // error middlewares last
220
+ const errorMiddlewares: Class<any>[] = [
221
+ DefaultResponseStatusErrorMiddleware,
222
+ DefaultBaseErrorMiddleware,
223
+ ];
224
+ errorMiddlewares.map(Sapling.resolve).forEach((r) => app.use(r));
225
+ ```
226
+
227
+ You can also write your own error middlewares. A specific handler should call
228
+ `next(err)` when it does not handle the error, and a base handler should be last
229
+ and return a response:
230
+
231
+ ```typescript
232
+ @MiddlewareClass()
233
+ class ResponseStatusErrorMiddleware {
234
+ @Middleware()
235
+ handle(
236
+ err: unknown,
237
+ _request: Request,
238
+ _response: Response,
239
+ next: NextFunction,
240
+ ) {
241
+ if (err instanceof ResponseStatusError) {
242
+ return ResponseEntity.status(err.status).body({ message: err.message });
243
+ }
244
+
245
+ // MUST call next(err) to continue the chain
246
+ next(err);
247
+ }
248
+ }
249
+
250
+ @MiddlewareClass()
251
+ class BaseErrorMiddleware {
252
+ @Middleware()
253
+ handle(
254
+ err: unknown,
255
+ _request: Request,
256
+ _response: Response,
257
+ _next: NextFunction,
258
+ ) {
259
+ console.error("[Error]", err);
260
+
261
+ return ResponseEntity.status(500).body({
262
+ message: "Internal Server Error",
263
+ });
264
+
265
+ // no next(err) since last middleware in chain, we are done propagating
266
+ }
267
+ }
209
268
  ```
210
269
 
211
270
  ### Middleware
@@ -234,10 +293,41 @@ class CookieParserMiddleware {
234
293
  // Register it like any controller
235
294
  app.use(Sapling.resolve(CookieParserMiddleware));
236
295
 
296
+ // Register middlewares before controllers
297
+ app.use(Sapling.resolve(UserController));
298
+
237
299
  // You can also still choose to load plugins the Express.js way
238
300
  app.use(cookieParser());
239
301
  ```
240
302
 
303
+ You can also write custom middlewares as well. It is functionally the same way as Express: call `next()` explicitly to
304
+ continue down the chain:
305
+
306
+ ```typescript
307
+ import { MiddlewareClass, Middleware } from "@tahminator/sapling";
308
+ import { NextFunction, Request, Response } from "express";
309
+
310
+ @MiddlewareClass()
311
+ class RequestTimerMiddleware {
312
+ @Middleware()
313
+ handle(request: Request, _response: Response, next: NextFunction) {
314
+ const start = Date.now();
315
+
316
+ request.on("finish", () => {
317
+ const elapsedMs = Date.now() - start;
318
+ console.log(`[Request] ${request.method} ${request.path} ${elapsedMs}ms`);
319
+ });
320
+
321
+ // MUST call next() to continue the chain
322
+ next();
323
+ }
324
+ }
325
+
326
+ // Register middlewares before controllers
327
+ app.use(Sapling.resolve(RequestTimerMiddleware));
328
+ app.use(Sapling.resolve(UserController));
329
+ ```
330
+
241
331
  ### Request Validation
242
332
 
243
333
  Validate and transform request bodies, route params, and query strings at the controller level using `@RequestBody`, `@RequestParam`, and `@RequestQuery`. These decorators accept any [Standard Schema](https://github.com/standard-schema/standard-schema) compatible validator (Zod, Valibot, ArkType, etc.).
package/dist/index.cjs CHANGED
@@ -264,7 +264,8 @@ var ParserError = class ParserError extends ResponseStatusError {
264
264
  //#region src/helper/sapling.ts
265
265
  const settings = {
266
266
  serialize: JSON.stringify,
267
- deserialize: JSON.parse
267
+ deserialize: JSON.parse,
268
+ openapi: { path: "/openapi.json" }
268
269
  };
269
270
  /**
270
271
  * Collection of utility functions which are essential for Sapling to function.
@@ -369,7 +370,304 @@ var Sapling = class Sapling {
369
370
  static setDeserializeFn(fn) {
370
371
  settings.deserialize = fn;
371
372
  }
373
+ static setOpenApiPath(path) {
374
+ settings.openapi.path = path;
375
+ }
376
+ };
377
+ //#endregion
378
+ //#region src/annotation/request.ts
379
+ const _requestSchemaStore = /* @__PURE__ */ new WeakMap();
380
+ /**
381
+ * Apply to a route method to have `request.body` be parsed by `schema`.
382
+ *
383
+ * This annotation will parse `request.body` & then override `request.body`.
384
+ * You can then just simply cast `request.body` for your use
385
+ *
386
+ * @example
387
+ * ```ts
388
+ * const CREATE_BOOK_REQUEST_BODY_SCHEMA = z.object({
389
+ * name: z.string(),
390
+ * description: z.string().optional(),
391
+ * });
392
+ *
393
+ * ⠀@Controller({ prefix: "/api/book" })
394
+ * class BookController {
395
+ * ⠀@RequestBody(CREATE_BOOK_REQUEST_BODY_SCHEMA)
396
+ * ⠀@POST()
397
+ * public createBook(request: e.Request) {
398
+ * const { name, description } = request.body as unknown as z.infer<
399
+ * typeof CREATE_BOOK_REQUEST_BODY_SCHEMA
400
+ * >;
401
+ * }
402
+ * }
403
+ * ```
404
+ */
405
+ function RequestBody(schema) {
406
+ return (target, propertyKey) => {
407
+ const ctor = target.constructor;
408
+ const fnName = String(propertyKey);
409
+ _setOnce(_getOrCreateRequestSchemaDefinition(ctor, fnName), "body", schema, fnName);
410
+ };
411
+ }
412
+ /**
413
+ * Apply to a route method to have `request.param` be parsed by `schema`.
414
+ *
415
+ * This annotation will parse `request.param` & then override `request.param`.
416
+ * You can then just simply cast `request.param` for your use
417
+ *
418
+ * @example
419
+ * ```ts
420
+ * const GET_BOOK_REQUEST_PARAM_SCHEMA = z.object({
421
+ * bookId: z.string(),
422
+ * });
423
+ *
424
+ * ⠀@Controller({ prefix: "/api/book" })
425
+ * class BookController {
426
+ * ⠀@RequestParam(GET_BOOK_REQUEST_PARAM_SCHEMA)
427
+ * ⠀@GET("/:bookId")
428
+ * public getBook(request: e.Request) {
429
+ * const { bookId } = request.param as unknown as z.infer<
430
+ * typeof GET_BOOK_REQUEST_PARAM_SCHEMA
431
+ * >;
432
+ * }
433
+ * }
434
+ * ```
435
+ */
436
+ function RequestParam(schema) {
437
+ return (target, propertyKey) => {
438
+ const ctor = target.constructor;
439
+ const fnName = String(propertyKey);
440
+ _setOnce(_getOrCreateRequestSchemaDefinition(ctor, fnName), "param", schema, fnName);
441
+ };
442
+ }
443
+ /**
444
+ * Apply to a route method to have `request.query` be parsed by `schema`.
445
+ *
446
+ * This annotation will parse `request.query` & then override `request.query`.
447
+ * You can then just simply cast `request.query` for your use
448
+ *
449
+ * @example
450
+ * ```ts
451
+ * const LIST_BOOKS_REQUEST_QUERY_SCHEMA = z.object({
452
+ * sort: z.enum(["name", "createdAt"]).optional(),
453
+ * q: z.string().optional(),
454
+ * });
455
+ *
456
+ * ⠀@Controller({ prefix: "/api/book" })
457
+ * class BookController {
458
+ * ⠀@RequestQuery(LIST_BOOKS_REQUEST_QUERY_SCHEMA)
459
+ * ⠀@GET()
460
+ * public listBooks(request: e.Request) {
461
+ * const { sort, q } = request.query as unknown as z.infer<
462
+ * typeof LIST_BOOKS_REQUEST_QUERY_SCHEMA
463
+ * >;
464
+ * }
465
+ * }
466
+ * ```
467
+ */
468
+ function RequestQuery(schema) {
469
+ return (target, propertyKey) => {
470
+ const ctor = target.constructor;
471
+ const fnName = String(propertyKey);
472
+ _setOnce(_getOrCreateRequestSchemaDefinition(ctor, fnName), "query", schema, fnName);
473
+ };
474
+ }
475
+ function _getOrCreateRequestSchemaDefinition(ctor, fnName) {
476
+ const byFn = (() => {
477
+ const fn = _requestSchemaStore.get(ctor);
478
+ if (fn) return fn;
479
+ const newFn = /* @__PURE__ */ new Map();
480
+ _requestSchemaStore.set(ctor, newFn);
481
+ return newFn;
482
+ })();
483
+ const existing = byFn.get(fnName);
484
+ if (existing) return existing;
485
+ const created = {};
486
+ byFn.set(fnName, created);
487
+ return created;
488
+ }
489
+ function _setOnce(def, key, schema, fnName) {
490
+ if (def[key]) throw new Error(`Duplicate request schema for "${String(key)}" on method "${fnName}"`);
491
+ def[key] = schema;
492
+ }
493
+ function _getRequestSchemas(ctor, fnName) {
494
+ return _requestSchemaStore.get(ctor)?.get(fnName);
495
+ }
496
+ async function _parseOrThrow(schema, input, kind) {
497
+ const result = await schema["~standard"].validate(input);
498
+ if (result.issues) {
499
+ console.debug(`Failed to parse a schema`);
500
+ throw new ParserError(kind, result.issues, schema["~standard"].vendor);
501
+ }
502
+ return result.value;
503
+ }
504
+ //#endregion
505
+ //#region src/annotation/route.ts
506
+ const _routeStore = /* @__PURE__ */ new WeakMap();
507
+ /**
508
+ * Custom annotation that will store all routes inside of a map,
509
+ * which can then be used to initialize all the routes to the router.
510
+ */
511
+ function _Route({ method, path = "" }) {
512
+ return (target, propertyKey) => {
513
+ const ctor = target.constructor;
514
+ const list = _routeStore.get(ctor) ?? [];
515
+ list.push({
516
+ method,
517
+ path: path ?? "",
518
+ fnName: String(propertyKey)
519
+ });
520
+ _routeStore.set(ctor, list);
521
+ };
522
+ }
523
+ /**
524
+ * Register GET route on the given path (default "") for the given controller.
525
+ */
526
+ const GET = (path = "") => _Route({
527
+ method: "GET",
528
+ path
529
+ });
530
+ /**
531
+ * Register POST route on the given path (default "") for the given controller.
532
+ */
533
+ const POST = (path = "") => _Route({
534
+ method: "POST",
535
+ path
536
+ });
537
+ /**
538
+ * Register PUT route on the given path (default "") for the given controller.
539
+ */
540
+ const PUT = (path = "") => _Route({
541
+ method: "PUT",
542
+ path
543
+ });
544
+ /**
545
+ * Register DELETE route on the given path (default "") for the given controller.
546
+ */
547
+ const DELETE = (path = "") => _Route({
548
+ method: "DELETE",
549
+ path
550
+ });
551
+ /**
552
+ * Register OPTIONS route on the given path (default "") for the given controller.
553
+ */
554
+ const OPTIONS = (path = "") => _Route({
555
+ method: "OPTIONS",
556
+ path
557
+ });
558
+ /**
559
+ * Register PATCH route on the given path (default "") for the given controller.
560
+ */
561
+ const PATCH = (path = "") => _Route({
562
+ method: "PATCH",
563
+ path
564
+ });
565
+ /**
566
+ * Register HEAD route on the given path (default "") for the given controller.
567
+ */
568
+ const HEAD = (path = "") => _Route({
569
+ method: "HEAD",
570
+ path
571
+ });
572
+ /**
573
+ * Register a middleware route on the given path (default "") for the given controller.
574
+ */
575
+ const Middleware = (path = "") => _Route({
576
+ method: "USE",
577
+ path
578
+ });
579
+ /**
580
+ * Given a class constructor, fetch all the routes attached.
581
+ */
582
+ function _getRoutes(ctor) {
583
+ return _routeStore.get(ctor) ?? [];
584
+ }
585
+ //#endregion
586
+ //#region src/helper/openapi.ts
587
+ var OpenAPIGenerator = class {
588
+ constructor() {
589
+ this.controllers = /* @__PURE__ */ new Set();
590
+ this.config = {
591
+ title: "API",
592
+ version: "1.0.0"
593
+ };
594
+ }
595
+ setConfig(config) {
596
+ this.config = config;
597
+ }
598
+ registerController(controllerClass, prefix) {
599
+ this.controllers.add({
600
+ class: controllerClass,
601
+ prefix
602
+ });
603
+ }
604
+ generateSpec() {
605
+ const config = this.config;
606
+ const paths = {};
607
+ for (const { class: controllerClass, prefix } of this.controllers) {
608
+ const routes = _getRoutes(controllerClass);
609
+ for (const route of routes) {
610
+ if (route.method === "USE") continue;
611
+ const schemas = _getRequestSchemas(controllerClass, route.fnName);
612
+ const fullPath = route.path instanceof RegExp ? route.path.source : prefix + route.path;
613
+ const openApiPath = typeof fullPath === "string" ? fullPath.replace(/:(\w+)/g, "{$1}") : fullPath;
614
+ if (!paths[openApiPath]) paths[openApiPath] = {};
615
+ const operation = { responses: { "200": { description: "Successful response" } } };
616
+ const parameters = [];
617
+ if (schemas?.param) {
618
+ const paramSchema = this.toJsonSchema(schemas.param);
619
+ if (paramSchema.type === "object" && paramSchema.properties) for (const [name, schema] of Object.entries(paramSchema.properties)) parameters.push({
620
+ name,
621
+ in: "path",
622
+ required: true,
623
+ schema
624
+ });
625
+ }
626
+ if (schemas?.query) {
627
+ const querySchema = this.toJsonSchema(schemas.query);
628
+ if (querySchema.type === "object" && querySchema.properties) for (const [name, schema] of Object.entries(querySchema.properties)) {
629
+ const isRequired = Array.isArray(querySchema.required) && querySchema.required.includes(name);
630
+ parameters.push({
631
+ name,
632
+ in: "query",
633
+ required: isRequired,
634
+ schema
635
+ });
636
+ }
637
+ }
638
+ if (parameters.length > 0) operation.parameters = parameters;
639
+ if (schemas?.body) operation.requestBody = {
640
+ required: true,
641
+ content: { "application/json": { schema: this.toJsonSchema(schemas.body) } }
642
+ };
643
+ const method = route.method.toLowerCase();
644
+ paths[openApiPath][method] = operation;
645
+ }
646
+ }
647
+ return {
648
+ openapi: "3.0.0",
649
+ info: {
650
+ title: config.title,
651
+ version: config.version,
652
+ description: config.description
653
+ },
654
+ paths
655
+ };
656
+ }
657
+ toJsonSchema(schema) {
658
+ return schema["~standard"].jsonSchema.output({ target: "openapi-3.0" });
659
+ }
372
660
  };
661
+ const openApiGenerator = new OpenAPIGenerator();
662
+ function _registerControllerClass(controllerClass, prefix) {
663
+ openApiGenerator.registerController(controllerClass, prefix);
664
+ }
665
+ function setOpenApiConfig(config) {
666
+ openApiGenerator.setConfig(config);
667
+ }
668
+ function generateOpenApiSpec() {
669
+ return openApiGenerator.generateSpec();
670
+ }
373
671
  //#endregion
374
672
  //#region src/types.ts
375
673
  const methodResolve = {
@@ -503,140 +801,6 @@ function _resolve(ctor) {
503
801
  return _InjectableRegistry.get(ctor);
504
802
  }
505
803
  //#endregion
506
- //#region src/annotation/request.ts
507
- const _requestSchemaStore = /* @__PURE__ */ new WeakMap();
508
- function _getOrCreateRequestSchemaDefinition(ctor, fnName) {
509
- const byFn = (() => {
510
- const fn = _requestSchemaStore.get(ctor);
511
- if (fn) return fn;
512
- const newFn = /* @__PURE__ */ new Map();
513
- _requestSchemaStore.set(ctor, newFn);
514
- return newFn;
515
- })();
516
- const existing = byFn.get(fnName);
517
- if (existing) return existing;
518
- const created = {};
519
- byFn.set(fnName, created);
520
- return created;
521
- }
522
- function _setOnce(def, key, schema, fnName) {
523
- if (def[key]) throw new Error(`Duplicate request schema for "${String(key)}" on method "${fnName}"`);
524
- def[key] = schema;
525
- }
526
- function RequestBody(schema) {
527
- return (target, propertyKey) => {
528
- const ctor = target.constructor;
529
- const fnName = String(propertyKey);
530
- _setOnce(_getOrCreateRequestSchemaDefinition(ctor, fnName), "body", schema, fnName);
531
- };
532
- }
533
- function RequestParam(schema) {
534
- return (target, propertyKey) => {
535
- const ctor = target.constructor;
536
- const fnName = String(propertyKey);
537
- _setOnce(_getOrCreateRequestSchemaDefinition(ctor, fnName), "param", schema, fnName);
538
- };
539
- }
540
- function RequestQuery(schema) {
541
- return (target, propertyKey) => {
542
- const ctor = target.constructor;
543
- const fnName = String(propertyKey);
544
- _setOnce(_getOrCreateRequestSchemaDefinition(ctor, fnName), "query", schema, fnName);
545
- };
546
- }
547
- function _getRequestSchemas(ctor, fnName) {
548
- return _requestSchemaStore.get(ctor)?.get(fnName);
549
- }
550
- async function _parseOrThrow(schema, input, kind) {
551
- const result = await schema["~standard"].validate(input);
552
- if (result.issues) {
553
- console.debug(`Failed to parse a schema`);
554
- throw new ParserError(kind, result.issues, schema["~standard"].vendor);
555
- }
556
- return result.value;
557
- }
558
- //#endregion
559
- //#region src/annotation/route.ts
560
- const _routeStore = /* @__PURE__ */ new WeakMap();
561
- /**
562
- * Custom annotation that will store all routes inside of a map,
563
- * which can then be used to initialize all the routes to the router.
564
- */
565
- function _Route({ method, path = "" }) {
566
- return (target, propertyKey) => {
567
- const ctor = target.constructor;
568
- const list = _routeStore.get(ctor) ?? [];
569
- list.push({
570
- method,
571
- path: path ?? "",
572
- fnName: String(propertyKey)
573
- });
574
- _routeStore.set(ctor, list);
575
- };
576
- }
577
- /**
578
- * Register GET route on the given path (default "") for the given controller.
579
- */
580
- const GET = (path = "") => _Route({
581
- method: "GET",
582
- path
583
- });
584
- /**
585
- * Register POST route on the given path (default "") for the given controller.
586
- */
587
- const POST = (path = "") => _Route({
588
- method: "POST",
589
- path
590
- });
591
- /**
592
- * Register PUT route on the given path (default "") for the given controller.
593
- */
594
- const PUT = (path = "") => _Route({
595
- method: "PUT",
596
- path
597
- });
598
- /**
599
- * Register DELETE route on the given path (default "") for the given controller.
600
- */
601
- const DELETE = (path = "") => _Route({
602
- method: "DELETE",
603
- path
604
- });
605
- /**
606
- * Register OPTIONS route on the given path (default "") for the given controller.
607
- */
608
- const OPTIONS = (path = "") => _Route({
609
- method: "OPTIONS",
610
- path
611
- });
612
- /**
613
- * Register PATCH route on the given path (default "") for the given controller.
614
- */
615
- const PATCH = (path = "") => _Route({
616
- method: "PATCH",
617
- path
618
- });
619
- /**
620
- * Register HEAD route on the given path (default "") for the given controller.
621
- */
622
- const HEAD = (path = "") => _Route({
623
- method: "HEAD",
624
- path
625
- });
626
- /**
627
- * Register a middleware route on the given path (default "") for the given controller.
628
- */
629
- const Middleware = (path = "") => _Route({
630
- method: "USE",
631
- path
632
- });
633
- /**
634
- * Given a class constructor, fetch all the routes attached.
635
- */
636
- function _getRoutes(ctor) {
637
- return _routeStore.get(ctor) ?? [];
638
- }
639
- //#endregion
640
804
  //#region src/annotation/controller.ts
641
805
  const _ControllerRegistry = /* @__PURE__ */ new WeakMap();
642
806
  /**
@@ -648,6 +812,7 @@ const _ControllerRegistry = /* @__PURE__ */ new WeakMap();
648
812
  function Controller({ prefix = "", deps = [] } = {}) {
649
813
  return (target) => {
650
814
  const targetClass = target;
815
+ _registerControllerClass(target, prefix);
651
816
  const router = (0, express.Router)();
652
817
  const routes = _getRoutes(target);
653
818
  const usedRoutes = /* @__PURE__ */ new Set();
@@ -739,7 +904,7 @@ function __decorate(decorators, target, key, desc) {
739
904
  return c > 3 && r && Object.defineProperty(target, key, r), r;
740
905
  }
741
906
  //#endregion
742
- //#region src/middleware/default/base.ts
907
+ //#region src/middleware/default/error/base.ts
743
908
  let DefaultBaseErrorMiddleware = class DefaultBaseErrorMiddleware {
744
909
  handle(err, _request, _response, _next) {
745
910
  console.error("[Error]", err);
@@ -749,7 +914,17 @@ let DefaultBaseErrorMiddleware = class DefaultBaseErrorMiddleware {
749
914
  __decorate([Middleware()], DefaultBaseErrorMiddleware.prototype, "handle", null);
750
915
  DefaultBaseErrorMiddleware = __decorate([MiddlewareClass()], DefaultBaseErrorMiddleware);
751
916
  //#endregion
752
- //#region src/middleware/default/responsestatus.ts
917
+ //#region src/middleware/default/error/parse.ts
918
+ let DefaultParserErrorMiddleware = class DefaultParserErrorMiddleware {
919
+ handle(err, _request, _response, next) {
920
+ if (err instanceof ParserError) return ResponseEntity.status(err.status).body({ message: err.message });
921
+ next(err);
922
+ }
923
+ };
924
+ __decorate([Middleware()], DefaultParserErrorMiddleware.prototype, "handle", null);
925
+ DefaultParserErrorMiddleware = __decorate([MiddlewareClass()], DefaultParserErrorMiddleware);
926
+ //#endregion
927
+ //#region src/middleware/default/error/responsestatus.ts
753
928
  let DefaultResponseStatusErrorMiddleware = class DefaultResponseStatusErrorMiddleware {
754
929
  handle(err, _request, _response, next) {
755
930
  if (err instanceof ResponseStatusError) return ResponseEntity.status(err.status).body({ message: err.message });
@@ -759,6 +934,15 @@ let DefaultResponseStatusErrorMiddleware = class DefaultResponseStatusErrorMiddl
759
934
  __decorate([Middleware()], DefaultResponseStatusErrorMiddleware.prototype, "handle", null);
760
935
  DefaultResponseStatusErrorMiddleware = __decorate([MiddlewareClass()], DefaultResponseStatusErrorMiddleware);
761
936
  //#endregion
937
+ //#region src/middleware/default/openapi/index.ts
938
+ let DefaultOpenApiMiddleware = class DefaultOpenApiMiddleware {
939
+ handle(_request, _response, _next) {
940
+ return ResponseEntity.ok().body(generateOpenApiSpec());
941
+ }
942
+ };
943
+ __decorate([GET("/openapi.json")], DefaultOpenApiMiddleware.prototype, "handle", null);
944
+ DefaultOpenApiMiddleware = __decorate([MiddlewareClass()], DefaultOpenApiMiddleware);
945
+ //#endregion
762
946
  exports.Controller = Controller;
763
947
  exports.DELETE = DELETE;
764
948
  Object.defineProperty(exports, "DefaultBaseErrorMiddleware", {
@@ -767,6 +951,18 @@ Object.defineProperty(exports, "DefaultBaseErrorMiddleware", {
767
951
  return DefaultBaseErrorMiddleware;
768
952
  }
769
953
  });
954
+ Object.defineProperty(exports, "DefaultOpenApiMiddleware", {
955
+ enumerable: true,
956
+ get: function() {
957
+ return DefaultOpenApiMiddleware;
958
+ }
959
+ });
960
+ Object.defineProperty(exports, "DefaultParserErrorMiddleware", {
961
+ enumerable: true,
962
+ get: function() {
963
+ return DefaultParserErrorMiddleware;
964
+ }
965
+ });
770
966
  Object.defineProperty(exports, "DefaultResponseStatusErrorMiddleware", {
771
967
  enumerable: true,
772
968
  get: function() {
@@ -800,5 +996,9 @@ exports._Route = _Route;
800
996
  exports._getRequestSchemas = _getRequestSchemas;
801
997
  exports._getRoutes = _getRoutes;
802
998
  exports._parseOrThrow = _parseOrThrow;
999
+ exports._registerControllerClass = _registerControllerClass;
803
1000
  exports._resolve = _resolve;
1001
+ exports.generateOpenApiSpec = generateOpenApiSpec;
804
1002
  exports.methodResolve = methodResolve;
1003
+ exports.openApiGenerator = openApiGenerator;
1004
+ exports.setOpenApiConfig = setOpenApiConfig;