@tahminator/sapling 2.0.3 → 2.0.5-beta.23c37926

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.cjs CHANGED
@@ -23,6 +23,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
23
  //#endregion
24
24
  let express = require("express");
25
25
  express = __toESM(express);
26
+ let swagger_ui_express = require("swagger-ui-express");
27
+ swagger_ui_express = __toESM(swagger_ui_express);
26
28
  //#region src/html/404.ts
27
29
  /**
28
30
  * Default Express.js 404 error page, as a string.
@@ -262,9 +264,13 @@ var ParserError = class ParserError extends ResponseStatusError {
262
264
  };
263
265
  //#endregion
264
266
  //#region src/helper/sapling.ts
265
- const settings = {
267
+ const _settings = {
266
268
  serialize: JSON.stringify,
267
- deserialize: JSON.parse
269
+ deserialize: JSON.parse,
270
+ doc: {
271
+ openApiPath: "/openapi.json",
272
+ swaggerPath: "/swagger.html"
273
+ }
268
274
  };
269
275
  /**
270
276
  * Collection of utility functions which are essential for Sapling to function.
@@ -343,13 +349,13 @@ var Sapling = class Sapling {
343
349
  * @defaultValue `JSON.stringify`
344
350
  */
345
351
  static serialize(value) {
346
- return settings.serialize(value);
352
+ return _settings.serialize(value);
347
353
  }
348
354
  /**
349
355
  * Replace the function used for `serialize`.
350
356
  */
351
357
  static setSerializeFn(fn) {
352
- settings.serialize = fn;
358
+ _settings.serialize = fn;
353
359
  }
354
360
  /**
355
361
  * De-serialize a JSON string back to a JavaScript object.
@@ -361,16 +367,321 @@ var Sapling = class Sapling {
361
367
  * @defaultValue `JSON.parse`
362
368
  */
363
369
  static deserialize(value) {
364
- return settings.deserialize(value);
370
+ return _settings.deserialize(value);
365
371
  }
366
372
  /**
367
373
  * Replace the function used for `deserialize`
368
374
  */
369
375
  static setDeserializeFn(fn) {
370
- settings.deserialize = fn;
376
+ _settings.deserialize = fn;
377
+ }
378
+ static setOpenApiPath(path) {
379
+ _settings.doc.openApiPath = path;
380
+ }
381
+ static setSwaggerPath(path) {
382
+ _settings.doc.swaggerPath = path;
371
383
  }
372
384
  };
373
385
  //#endregion
386
+ //#region src/annotation/request.ts
387
+ const _requestSchemaStore = /* @__PURE__ */ new WeakMap();
388
+ /**
389
+ * Apply to a route method to have `request.body` be parsed by `schema`.
390
+ *
391
+ * This annotation will parse `request.body` & then override `request.body`.
392
+ * You can then just simply cast `request.body` for your use
393
+ *
394
+ * @example
395
+ * ```ts
396
+ * const CREATE_BOOK_REQUEST_BODY_SCHEMA = z.object({
397
+ * name: z.string(),
398
+ * description: z.string().optional(),
399
+ * });
400
+ *
401
+ * ⠀@Controller({ prefix: "/api/book" })
402
+ * class BookController {
403
+ * ⠀@RequestBody(CREATE_BOOK_REQUEST_BODY_SCHEMA)
404
+ * ⠀@POST()
405
+ * public createBook(request: e.Request) {
406
+ * const { name, description } = request.body as unknown as z.infer<
407
+ * typeof CREATE_BOOK_REQUEST_BODY_SCHEMA
408
+ * >;
409
+ * }
410
+ * }
411
+ * ```
412
+ */
413
+ function RequestBody(schema) {
414
+ return (target, propertyKey) => {
415
+ const ctor = target.constructor;
416
+ const fnName = String(propertyKey);
417
+ _setOnce(_getOrCreateRequestSchemaDefinition(ctor, fnName), "body", schema, fnName);
418
+ };
419
+ }
420
+ /**
421
+ * Apply to a route method to have `request.param` be parsed by `schema`.
422
+ *
423
+ * This annotation will parse `request.param` & then override `request.param`.
424
+ * You can then just simply cast `request.param` for your use
425
+ *
426
+ * @example
427
+ * ```ts
428
+ * const GET_BOOK_REQUEST_PARAM_SCHEMA = z.object({
429
+ * bookId: z.string(),
430
+ * });
431
+ *
432
+ * ⠀@Controller({ prefix: "/api/book" })
433
+ * class BookController {
434
+ * ⠀@RequestParam(GET_BOOK_REQUEST_PARAM_SCHEMA)
435
+ * ⠀@GET("/:bookId")
436
+ * public getBook(request: e.Request) {
437
+ * const { bookId } = request.param as unknown as z.infer<
438
+ * typeof GET_BOOK_REQUEST_PARAM_SCHEMA
439
+ * >;
440
+ * }
441
+ * }
442
+ * ```
443
+ */
444
+ function RequestParam(schema) {
445
+ return (target, propertyKey) => {
446
+ const ctor = target.constructor;
447
+ const fnName = String(propertyKey);
448
+ _setOnce(_getOrCreateRequestSchemaDefinition(ctor, fnName), "param", schema, fnName);
449
+ };
450
+ }
451
+ /**
452
+ * Apply to a route method to have `request.query` be parsed by `schema`.
453
+ *
454
+ * This annotation will parse `request.query` & then override `request.query`.
455
+ * You can then just simply cast `request.query` for your use
456
+ *
457
+ * @example
458
+ * ```ts
459
+ * const LIST_BOOKS_REQUEST_QUERY_SCHEMA = z.object({
460
+ * sort: z.enum(["name", "createdAt"]).optional(),
461
+ * q: z.string().optional(),
462
+ * });
463
+ *
464
+ * ⠀@Controller({ prefix: "/api/book" })
465
+ * class BookController {
466
+ * ⠀@RequestQuery(LIST_BOOKS_REQUEST_QUERY_SCHEMA)
467
+ * ⠀@GET()
468
+ * public listBooks(request: e.Request) {
469
+ * const { sort, q } = request.query as unknown as z.infer<
470
+ * typeof LIST_BOOKS_REQUEST_QUERY_SCHEMA
471
+ * >;
472
+ * }
473
+ * }
474
+ * ```
475
+ */
476
+ function RequestQuery(schema) {
477
+ return (target, propertyKey) => {
478
+ const ctor = target.constructor;
479
+ const fnName = String(propertyKey);
480
+ _setOnce(_getOrCreateRequestSchemaDefinition(ctor, fnName), "query", schema, fnName);
481
+ };
482
+ }
483
+ function _getOrCreateRequestSchemaDefinition(ctor, fnName) {
484
+ const byFn = (() => {
485
+ const fn = _requestSchemaStore.get(ctor);
486
+ if (fn) return fn;
487
+ const newFn = /* @__PURE__ */ new Map();
488
+ _requestSchemaStore.set(ctor, newFn);
489
+ return newFn;
490
+ })();
491
+ const existing = byFn.get(fnName);
492
+ if (existing) return existing;
493
+ const created = {};
494
+ byFn.set(fnName, created);
495
+ return created;
496
+ }
497
+ function _setOnce(def, key, schema, fnName) {
498
+ if (def[key]) throw new Error(`Duplicate request schema for "${String(key)}" on method "${fnName}"`);
499
+ def[key] = schema;
500
+ }
501
+ function _getRequestSchemas(ctor, fnName) {
502
+ return _requestSchemaStore.get(ctor)?.get(fnName);
503
+ }
504
+ async function _parseOrThrow(schema, input, kind) {
505
+ const result = await schema["~standard"].validate(input);
506
+ if (result.issues) {
507
+ console.debug(`Failed to parse a schema`);
508
+ throw new ParserError(kind, result.issues, schema["~standard"].vendor);
509
+ }
510
+ return result.value;
511
+ }
512
+ //#endregion
513
+ //#region src/annotation/route.ts
514
+ const _routeStore = /* @__PURE__ */ new WeakMap();
515
+ /**
516
+ * Custom annotation that will store all routes inside of a map,
517
+ * which can then be used to initialize all the routes to the router.
518
+ */
519
+ function _Route({ method, path = "" }) {
520
+ return (target, propertyKey) => {
521
+ const ctor = target.constructor;
522
+ const list = _routeStore.get(ctor) ?? [];
523
+ list.push({
524
+ method,
525
+ path: path ?? "",
526
+ fnName: String(propertyKey)
527
+ });
528
+ _routeStore.set(ctor, list);
529
+ };
530
+ }
531
+ /**
532
+ * Register GET route on the given path (default "") for the given controller.
533
+ */
534
+ const GET = (path = "") => _Route({
535
+ method: "GET",
536
+ path
537
+ });
538
+ /**
539
+ * Register POST route on the given path (default "") for the given controller.
540
+ */
541
+ const POST = (path = "") => _Route({
542
+ method: "POST",
543
+ path
544
+ });
545
+ /**
546
+ * Register PUT route on the given path (default "") for the given controller.
547
+ */
548
+ const PUT = (path = "") => _Route({
549
+ method: "PUT",
550
+ path
551
+ });
552
+ /**
553
+ * Register DELETE route on the given path (default "") for the given controller.
554
+ */
555
+ const DELETE = (path = "") => _Route({
556
+ method: "DELETE",
557
+ path
558
+ });
559
+ /**
560
+ * Register OPTIONS route on the given path (default "") for the given controller.
561
+ */
562
+ const OPTIONS = (path = "") => _Route({
563
+ method: "OPTIONS",
564
+ path
565
+ });
566
+ /**
567
+ * Register PATCH route on the given path (default "") for the given controller.
568
+ */
569
+ const PATCH = (path = "") => _Route({
570
+ method: "PATCH",
571
+ path
572
+ });
573
+ /**
574
+ * Register HEAD route on the given path (default "") for the given controller.
575
+ */
576
+ const HEAD = (path = "") => _Route({
577
+ method: "HEAD",
578
+ path
579
+ });
580
+ /**
581
+ * Register a middleware route on the given path (default "") for the given controller.
582
+ */
583
+ const Middleware = (path = "") => _Route({
584
+ method: "USE",
585
+ path
586
+ });
587
+ /**
588
+ * Given a class constructor, fetch all the routes attached.
589
+ */
590
+ function _getRoutes(ctor) {
591
+ return _routeStore.get(ctor) ?? [];
592
+ }
593
+ //#endregion
594
+ //#region src/helper/openapi.ts
595
+ var OpenAPIGenerator = class {
596
+ constructor() {
597
+ this.controllers = /* @__PURE__ */ new Set();
598
+ this.config = {
599
+ title: "API",
600
+ version: "1.0.0"
601
+ };
602
+ }
603
+ setConfig(config) {
604
+ this.config = config;
605
+ }
606
+ registerController(controllerClass, prefix) {
607
+ this.controllers.add({
608
+ class: controllerClass,
609
+ prefix
610
+ });
611
+ }
612
+ generateSpec() {
613
+ const config = this.config;
614
+ const paths = {};
615
+ for (const { class: controllerClass, prefix } of this.controllers) {
616
+ const routes = _getRoutes(controllerClass);
617
+ for (const route of routes) {
618
+ if (route.method === "USE") continue;
619
+ const schemas = _getRequestSchemas(controllerClass, route.fnName);
620
+ const fullPath = route.path instanceof RegExp ? route.path.source : prefix + route.path;
621
+ const openApiPath = typeof fullPath === "string" ? fullPath.replace(/:(\w+)/g, "{$1}") : fullPath;
622
+ if (!paths[openApiPath]) paths[openApiPath] = {};
623
+ const operation = { responses: { "200": { description: "Successful response" } } };
624
+ const parameters = [];
625
+ if (schemas?.param) {
626
+ const paramSchema = this.toJsonSchema(schemas.param);
627
+ if (paramSchema.type === "object" && paramSchema.properties) for (const [name, schema] of Object.entries(paramSchema.properties)) parameters.push({
628
+ name,
629
+ in: "path",
630
+ required: true,
631
+ schema
632
+ });
633
+ }
634
+ if (schemas?.query) {
635
+ const querySchema = this.toJsonSchema(schemas.query);
636
+ if (querySchema.type === "object" && querySchema.properties) for (const [name, schema] of Object.entries(querySchema.properties)) {
637
+ const isRequired = Array.isArray(querySchema.required) && querySchema.required.includes(name);
638
+ parameters.push({
639
+ name,
640
+ in: "query",
641
+ required: isRequired,
642
+ schema
643
+ });
644
+ }
645
+ }
646
+ if (parameters.length > 0) operation.parameters = parameters;
647
+ if (schemas?.body) operation.requestBody = {
648
+ required: true,
649
+ content: { "application/json": { schema: this.toJsonSchema(schemas.body) } }
650
+ };
651
+ const method = route.method.toLowerCase();
652
+ paths[openApiPath][method] = operation;
653
+ }
654
+ }
655
+ return {
656
+ openapi: "3.0.0",
657
+ info: {
658
+ title: config.title,
659
+ version: config.version,
660
+ description: config.description
661
+ },
662
+ paths
663
+ };
664
+ }
665
+ toJsonSchema(schema) {
666
+ try {
667
+ return schema["~standard"].jsonSchema.output({ target: "openapi-3.0" });
668
+ } catch (e) {
669
+ if (e instanceof Error && e.message.includes("Transforms cannot be represented in JSON Schema")) throw new Error(`${e.message}.\nIt appears that you are using z.transform() - it is highly recommended that you use z.codec instead - https://zod.dev/codecs`);
670
+ throw e;
671
+ }
672
+ }
673
+ };
674
+ const openApiGenerator = new OpenAPIGenerator();
675
+ function _registerControllerClass(controllerClass, prefix) {
676
+ openApiGenerator.registerController(controllerClass, prefix);
677
+ }
678
+ function _setOpenApiConfig(config) {
679
+ openApiGenerator.setConfig(config);
680
+ }
681
+ function _generateOpenApiSpec() {
682
+ return openApiGenerator.generateSpec();
683
+ }
684
+ //#endregion
374
685
  //#region src/types.ts
375
686
  const methodResolve = {
376
687
  GET: "get",
@@ -503,140 +814,6 @@ function _resolve(ctor) {
503
814
  return _InjectableRegistry.get(ctor);
504
815
  }
505
816
  //#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
817
  //#region src/annotation/controller.ts
641
818
  const _ControllerRegistry = /* @__PURE__ */ new WeakMap();
642
819
  /**
@@ -648,6 +825,7 @@ const _ControllerRegistry = /* @__PURE__ */ new WeakMap();
648
825
  function Controller({ prefix = "", deps = [] } = {}) {
649
826
  return (target) => {
650
827
  const targetClass = target;
828
+ _registerControllerClass(target, prefix);
651
829
  const router = (0, express.Router)();
652
830
  const routes = _getRoutes(target);
653
831
  const usedRoutes = /* @__PURE__ */ new Set();
@@ -739,7 +917,7 @@ function __decorate(decorators, target, key, desc) {
739
917
  return c > 3 && r && Object.defineProperty(target, key, r), r;
740
918
  }
741
919
  //#endregion
742
- //#region src/middleware/default/base.ts
920
+ //#region src/middleware/default/error/base.ts
743
921
  let DefaultBaseErrorMiddleware = class DefaultBaseErrorMiddleware {
744
922
  handle(err, _request, _response, _next) {
745
923
  console.error("[Error]", err);
@@ -749,7 +927,17 @@ let DefaultBaseErrorMiddleware = class DefaultBaseErrorMiddleware {
749
927
  __decorate([Middleware()], DefaultBaseErrorMiddleware.prototype, "handle", null);
750
928
  DefaultBaseErrorMiddleware = __decorate([MiddlewareClass()], DefaultBaseErrorMiddleware);
751
929
  //#endregion
752
- //#region src/middleware/default/responsestatus.ts
930
+ //#region src/middleware/default/error/parse.ts
931
+ let DefaultParserErrorMiddleware = class DefaultParserErrorMiddleware {
932
+ handle(err, _request, _response, next) {
933
+ if (err instanceof ParserError) return ResponseEntity.status(err.status).body({ message: err.message });
934
+ next(err);
935
+ }
936
+ };
937
+ __decorate([Middleware()], DefaultParserErrorMiddleware.prototype, "handle", null);
938
+ DefaultParserErrorMiddleware = __decorate([MiddlewareClass()], DefaultParserErrorMiddleware);
939
+ //#endregion
940
+ //#region src/middleware/default/error/responsestatus.ts
753
941
  let DefaultResponseStatusErrorMiddleware = class DefaultResponseStatusErrorMiddleware {
754
942
  handle(err, _request, _response, next) {
755
943
  if (err instanceof ResponseStatusError) return ResponseEntity.status(err.status).body({ message: err.message });
@@ -759,6 +947,41 @@ let DefaultResponseStatusErrorMiddleware = class DefaultResponseStatusErrorMiddl
759
947
  __decorate([Middleware()], DefaultResponseStatusErrorMiddleware.prototype, "handle", null);
760
948
  DefaultResponseStatusErrorMiddleware = __decorate([MiddlewareClass()], DefaultResponseStatusErrorMiddleware);
761
949
  //#endregion
950
+ //#region src/middleware/default/openapi/index.ts
951
+ let DefaultOpenApiMiddleware = class DefaultOpenApiMiddleware {
952
+ handle(_request, _response, _next) {
953
+ return ResponseEntity.ok().body(_generateOpenApiSpec());
954
+ }
955
+ };
956
+ __decorate([GET(_settings.doc.openApiPath)], DefaultOpenApiMiddleware.prototype, "handle", null);
957
+ DefaultOpenApiMiddleware = __decorate([MiddlewareClass()], DefaultOpenApiMiddleware);
958
+ //#endregion
959
+ //#region src/middleware/default/swagger/index.ts
960
+ let Serve = class Serve {
961
+ constructor() {
962
+ this.handlers = swagger_ui_express.default.serve;
963
+ }
964
+ handle(_request, _response, _next) {
965
+ return this.handlers;
966
+ }
967
+ };
968
+ __decorate([Middleware(_settings.doc.swaggerPath)], Serve.prototype, "handle", null);
969
+ Serve = __decorate([MiddlewareClass()], Serve);
970
+ let Setup = class Setup {
971
+ constructor() {
972
+ this.handler = swagger_ui_express.default.setup(void 0, { swaggerOptions: { url: _settings.doc.openApiPath } });
973
+ }
974
+ handle(request, response, next) {
975
+ return this.handler(request, response, next);
976
+ }
977
+ };
978
+ __decorate([Middleware(_settings.doc.swaggerPath)], Setup.prototype, "handle", null);
979
+ Setup = __decorate([MiddlewareClass()], Setup);
980
+ const DefaultSwaggerMiddleware = {
981
+ Serve,
982
+ Setup
983
+ };
984
+ //#endregion
762
985
  exports.Controller = Controller;
763
986
  exports.DELETE = DELETE;
764
987
  Object.defineProperty(exports, "DefaultBaseErrorMiddleware", {
@@ -767,12 +990,25 @@ Object.defineProperty(exports, "DefaultBaseErrorMiddleware", {
767
990
  return DefaultBaseErrorMiddleware;
768
991
  }
769
992
  });
993
+ Object.defineProperty(exports, "DefaultOpenApiMiddleware", {
994
+ enumerable: true,
995
+ get: function() {
996
+ return DefaultOpenApiMiddleware;
997
+ }
998
+ });
999
+ Object.defineProperty(exports, "DefaultParserErrorMiddleware", {
1000
+ enumerable: true,
1001
+ get: function() {
1002
+ return DefaultParserErrorMiddleware;
1003
+ }
1004
+ });
770
1005
  Object.defineProperty(exports, "DefaultResponseStatusErrorMiddleware", {
771
1006
  enumerable: true,
772
1007
  get: function() {
773
1008
  return DefaultResponseStatusErrorMiddleware;
774
1009
  }
775
1010
  });
1011
+ exports.DefaultSwaggerMiddleware = DefaultSwaggerMiddleware;
776
1012
  exports.GET = GET;
777
1013
  exports.HEAD = HEAD;
778
1014
  exports.Html404ErrorPage = Html404ErrorPage;
@@ -797,8 +1033,13 @@ exports._ControllerRegistry = _ControllerRegistry;
797
1033
  exports._InjectableDeps = _InjectableDeps;
798
1034
  exports._InjectableRegistry = _InjectableRegistry;
799
1035
  exports._Route = _Route;
1036
+ exports._generateOpenApiSpec = _generateOpenApiSpec;
800
1037
  exports._getRequestSchemas = _getRequestSchemas;
801
1038
  exports._getRoutes = _getRoutes;
802
1039
  exports._parseOrThrow = _parseOrThrow;
1040
+ exports._registerControllerClass = _registerControllerClass;
803
1041
  exports._resolve = _resolve;
1042
+ exports._setOpenApiConfig = _setOpenApiConfig;
1043
+ exports._settings = _settings;
804
1044
  exports.methodResolve = methodResolve;
1045
+ exports.openApiGenerator = openApiGenerator;