@tahminator/sapling 2.0.5-beta.ac279593 → 2.0.5-beta.e0403942

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
@@ -48,6 +48,7 @@ const Html404ErrorPage = (error) => `<!DOCTYPE html>
48
48
  * You can either return `new RedirectView(url)` or `RedirectView.redirect(url)` inside of a controller method.
49
49
  */
50
50
  var RedirectView = class RedirectView {
51
+ _url;
51
52
  constructor(url) {
52
53
  this._url = url;
53
54
  }
@@ -143,8 +144,10 @@ let HttpStatus = /* @__PURE__ */ function(HttpStatus) {
143
144
  * @typeParam T - the type of the response body
144
145
  */
145
146
  var ResponseEntity = class {
147
+ _statusCode;
148
+ _headers = {};
149
+ _body;
146
150
  constructor(body, headers = {}, statusCode = 200) {
147
- this._headers = {};
148
151
  this._body = body;
149
152
  this._headers = headers;
150
153
  this._statusCode = statusCode;
@@ -197,8 +200,9 @@ var ResponseEntity = class {
197
200
  * ensuring type safety when constructing the response.
198
201
  */
199
202
  var ResponseEntityBuilder = class {
203
+ _statusCode;
204
+ _headers = {};
200
205
  constructor(statusCode) {
201
- this._headers = {};
202
206
  this._statusCode = statusCode;
203
207
  }
204
208
  /**
@@ -230,6 +234,7 @@ var ResponseEntityBuilder = class {
230
234
  * @see {@link Sapling.loadResponseStatusErrorMiddleware}
231
235
  */
232
236
  var ResponseStatusError = class ResponseStatusError extends Error {
237
+ status;
233
238
  constructor(status, message) {
234
239
  super(message ?? "Something went wrong.");
235
240
  this.status = status;
@@ -241,26 +246,27 @@ var ResponseStatusError = class ResponseStatusError extends Error {
241
246
  //#endregion
242
247
  //#region src/helper/error/parse.ts
243
248
  /**
244
- * This error should be thrown when some data cannot be parsed by a given schema.
249
+ * This error should be thrown when some data cannot be parsed by a given Standard Schema compatible schema.
245
250
  */
246
251
  var ParserError = class ParserError extends ResponseStatusError {
247
- constructor(location, issues, vendor) {
248
- super(400, ParserError.formatMessage(location, issues, vendor));
252
+ constructor(location, issues, vendor, functionName) {
253
+ super(400, ParserError.formatMessage(location, issues, vendor, functionName));
249
254
  Object.setPrototypeOf(this, new.target.prototype);
250
255
  }
251
- static formatMessage(location, issues, vendor) {
256
+ static formatMessage(location, issues, vendor, functionName) {
252
257
  const formatted = issues.map((i) => {
253
258
  const path = Array.isArray(i.path) ? i.path.map((seg) => typeof seg === "object" && seg ? String(seg.key) : String(seg)).join(".") : "";
254
259
  return path ? `${path}: ${i.message}` : i.message;
255
260
  }).join("; ");
256
- return `${vendor} failed to parse ${(() => {
257
- switch (location) {
258
- case "reqbody": return "request body";
259
- case "reqparams": return "request params";
260
- case "reqquery": return "request query";
261
- case "resbody": return "response body";
262
- }
263
- })()}: ${formatted}`;
261
+ return `Failed to parse ${this.getPrettyLocationString(location)} with ${vendor} on ${functionName}: ${formatted}`;
262
+ }
263
+ static getPrettyLocationString(location) {
264
+ switch (location) {
265
+ case "reqbody": return "request body";
266
+ case "reqparams": return "request params";
267
+ case "reqquery": return "request query";
268
+ case "resbody": return "response body";
269
+ }
264
270
  }
265
271
  };
266
272
  //#endregion
@@ -270,7 +276,11 @@ const _settings = {
270
276
  deserialize: JSON.parse,
271
277
  doc: {
272
278
  openApiPath: "/openapi.json",
273
- swaggerPath: "/swagger.html"
279
+ swaggerPath: "/swagger.html",
280
+ metadata: {
281
+ title: "API",
282
+ version: "1.0.0"
283
+ }
274
284
  }
275
285
  };
276
286
  /**
@@ -376,12 +386,59 @@ var Sapling = class Sapling {
376
386
  static setDeserializeFn(fn) {
377
387
  _settings.deserialize = fn;
378
388
  }
379
- static setOpenApiPath(path) {
380
- _settings.doc.openApiPath = path;
381
- }
382
- static setSwaggerPath(path) {
383
- _settings.doc.swaggerPath = path;
384
- }
389
+ /**
390
+ * Modify extra settings
391
+ */
392
+ static Extras = {
393
+ /**
394
+ * Modify default settings applied to OpenAPI & Swagger
395
+ */
396
+ swaggerAndOpenApi: {
397
+ /**
398
+ * Set base OpenAPI metadata values.
399
+ *
400
+ * @default { title: "API", version: "1.0.0" }
401
+ */
402
+ setMetadata(metadata) {
403
+ _settings.doc.metadata = metadata;
404
+ },
405
+ /**
406
+ * change default endpoint that will serve OpenAPI spec.
407
+ * Swagger will also load this endpoint on load.
408
+ *
409
+ * @default `/openapi.json`
410
+ */
411
+ setOpenApiPath(path) {
412
+ _settings.doc.openApiPath = path;
413
+ },
414
+ /**
415
+ * change Swagger endpoint.
416
+ *
417
+ * @default `/swagger.html`
418
+ */
419
+ setSwaggerPath(path) {
420
+ _settings.doc.swaggerPath = path;
421
+ }
422
+ } };
423
+ /**
424
+ * This method can be used in a `@MiddlewareClass` to register any libraries
425
+ * that expect you to register multiple registers at once. An example is `swagger-ui-express`
426
+ *
427
+ * @example
428
+ * ```ts
429
+ * ⠀@MiddlewareClass()
430
+ * class Serve {
431
+ * // `swagger.serve` returns multiple Express handlers for all the assets and routes
432
+ * // that will be served
433
+ * private readonly handlers: RequestHandler[] = swagger.serve;
434
+ *
435
+ * ⠀@Middleware(_settings.doc.swaggerPath)
436
+ * handle(request: Request, response: Response, next: NextFunction) {
437
+ * return Sapling.chainHandlers(this.handlers, request, response, next);
438
+ * }
439
+ * }
440
+ * ```
441
+ */
385
442
  static chainHandlers(handlers, request, response, next, index = 0) {
386
443
  if (index >= handlers.length) {
387
444
  next();
@@ -478,18 +535,7 @@ function _getRoutes(ctor) {
478
535
  return _routeStore.get(ctor) ?? [];
479
536
  }
480
537
  //#endregion
481
- //#region src/utils.ts
482
- function _getOrCreateMap(store, ctor) {
483
- const existing = store.get(ctor);
484
- if (existing) return existing;
485
- const created = /* @__PURE__ */ new Map();
486
- store.set(ctor, created);
487
- return created;
488
- }
489
- //#endregion
490
538
  //#region src/annotation/schema.ts
491
- const _routeSchemaStore = /* @__PURE__ */ new WeakMap();
492
- const _controllerSchemaStore = /* @__PURE__ */ new WeakMap();
493
539
  function ControllerSchema(options) {
494
540
  return (target) => {
495
541
  _setControllerSchema(target, options);
@@ -501,8 +547,17 @@ function RouteSchema(options) {
501
547
  _setRouteSchema(ctor, String(propertyKey), options);
502
548
  };
503
549
  }
550
+ const _routeSchemaStore = /* @__PURE__ */ new WeakMap();
551
+ const _controllerSchemaStore = /* @__PURE__ */ new WeakMap();
552
+ function getOrCreateRouteSchemaStore(store, ctor) {
553
+ const existing = store.get(ctor);
554
+ if (existing) return existing;
555
+ const created = /* @__PURE__ */ new Map();
556
+ store.set(ctor, created);
557
+ return created;
558
+ }
504
559
  function _setRouteSchema(ctor, fnName, options) {
505
- _getOrCreateMap(_routeSchemaStore, ctor).set(fnName, options);
560
+ getOrCreateRouteSchemaStore(_routeSchemaStore, ctor).set(fnName, options);
506
561
  }
507
562
  function _setControllerSchema(ctor, options) {
508
563
  _controllerSchemaStore.set(ctor, options);
@@ -514,26 +569,78 @@ function _getControllerSchema(ctor) {
514
569
  return _controllerSchemaStore.get(ctor);
515
570
  }
516
571
  //#endregion
572
+ //#region src/annotation/validator.ts
573
+ const _validatorSchemaStore = /* @__PURE__ */ new WeakMap();
574
+ function ResponseBody(schema) {
575
+ return (target, propertyKey) => {
576
+ const ctor = target.constructor;
577
+ const fnName = String(propertyKey);
578
+ _saveValidatorSchema(_getOrCreateSchemaDefinition(ctor, fnName), "responseBody", schema, fnName);
579
+ };
580
+ }
581
+ function RequestBody(schema) {
582
+ return (target, propertyKey) => {
583
+ const ctor = target.constructor;
584
+ const fnName = String(propertyKey);
585
+ _saveValidatorSchema(_getOrCreateSchemaDefinition(ctor, fnName), "requestBody", schema, fnName);
586
+ };
587
+ }
588
+ function RequestParam(schema) {
589
+ return (target, propertyKey) => {
590
+ const ctor = target.constructor;
591
+ const fnName = String(propertyKey);
592
+ _saveValidatorSchema(_getOrCreateSchemaDefinition(ctor, fnName), "requestParam", schema, fnName);
593
+ };
594
+ }
595
+ function RequestQuery(schema) {
596
+ return (target, propertyKey) => {
597
+ const ctor = target.constructor;
598
+ const fnName = String(propertyKey);
599
+ _saveValidatorSchema(_getOrCreateSchemaDefinition(ctor, fnName), "requestQuery", schema, fnName);
600
+ };
601
+ }
602
+ function getOrCreateValidatorSchemaStore(store, ctor) {
603
+ const existing = store.get(ctor);
604
+ if (existing) return existing;
605
+ const created = /* @__PURE__ */ new Map();
606
+ store.set(ctor, created);
607
+ return created;
608
+ }
609
+ function _getOrCreateSchemaDefinition(ctor, fnName) {
610
+ const byFn = getOrCreateValidatorSchemaStore(_validatorSchemaStore, ctor);
611
+ const existing = byFn.get(fnName);
612
+ if (existing) return existing;
613
+ const created = {};
614
+ byFn.set(fnName, created);
615
+ return created;
616
+ }
617
+ async function _parseOrThrow(schema, input, location, fnName) {
618
+ const result = await schema["~standard"].validate(input);
619
+ if (result.issues) throw new ParserError(location, result.issues, schema["~standard"].vendor, fnName);
620
+ return result.value;
621
+ }
622
+ function _saveValidatorSchema(def, key, schema, fnName) {
623
+ if (def[key]) throw new Error(`Duplicate schema for "${String(key)}" on method "${fnName}"`);
624
+ def[key] = schema;
625
+ }
626
+ function _getValidatorSchema(ctor, fnName) {
627
+ return _validatorSchemaStore.get(ctor)?.get(fnName);
628
+ }
629
+ //#endregion
517
630
  //#region src/helper/openapi.ts
518
631
  var OpenAPIGenerator = class {
519
- constructor() {
520
- this.controllers = /* @__PURE__ */ new Set();
521
- this.config = {
522
- title: "API",
523
- version: "1.0.0"
524
- };
525
- }
526
- setConfig(config) {
527
- this.config = config;
528
- }
632
+ controllers = /* @__PURE__ */ new Set();
529
633
  registerController(controllerClass, prefix) {
530
634
  this.controllers.add({
531
635
  class: controllerClass,
532
636
  prefix
533
637
  });
534
638
  }
639
+ get metadata() {
640
+ return _settings.doc.metadata;
641
+ }
535
642
  generateSpec() {
536
- const config = this.config;
643
+ const metadata = this.metadata;
537
644
  const paths = {};
538
645
  const tags = [];
539
646
  for (const { class: controllerClass, prefix } of this.controllers) {
@@ -559,14 +666,19 @@ var OpenAPIGenerator = class {
559
666
  };
560
667
  } else responses["200"] = { description: "Successful response" };
561
668
  if (routeSchema?.responses) for (const resp of routeSchema.responses) {
562
- const responseSchema = this.toJsonSchema(resp.schema, "output");
563
- responses[String(resp.statusCode)] = {
564
- description: resp.description ?? responseSchema.description ?? `Response ${resp.statusCode}`,
565
- content: { "application/json": { schema: responseSchema } }
669
+ const statusCode = String(resp.statusCode);
670
+ const existingResponse = responses[statusCode];
671
+ const existingSchema = existingResponse && "content" in existingResponse ? existingResponse.content?.["application/json"]?.schema : void 0;
672
+ const responseSchema = resp.schema ? this.toJsonSchema(resp.schema, "output") : statusCode === "200" ? existingSchema : void 0;
673
+ responses[statusCode] = {
674
+ ...existingResponse,
675
+ description: resp.description ?? responseSchema?.description ?? existingResponse?.description ?? `Response ${resp.statusCode}`,
676
+ ...responseSchema ? { content: { "application/json": { schema: responseSchema } } } : {}
566
677
  };
567
678
  }
568
679
  const operation = {
569
680
  responses,
681
+ summary: routeSchema?.summary,
570
682
  description: routeSchema?.description,
571
683
  tags: controllerSchema?.title ? [controllerSchema.title] : void 0
572
684
  };
@@ -614,9 +726,9 @@ var OpenAPIGenerator = class {
614
726
  return {
615
727
  openapi: "3.0.0",
616
728
  info: {
617
- title: config.title,
618
- version: config.version,
619
- description: config.description
729
+ title: metadata.title,
730
+ version: metadata.version,
731
+ description: metadata.description
620
732
  },
621
733
  tags: tags.length > 0 ? tags : void 0,
622
734
  paths
@@ -625,21 +737,17 @@ var OpenAPIGenerator = class {
625
737
  toJsonSchema(schema, direction = "output") {
626
738
  try {
627
739
  const jsonSchema = schema["~standard"].jsonSchema;
628
- if (direction === "input" && jsonSchema.input) return jsonSchema.input({ target: "openapi-3.0" });
629
- return jsonSchema.output({ target: "openapi-3.0" });
740
+ return direction === "input" ? jsonSchema.input({ target: "openapi-3.0" }) : jsonSchema.output({ target: "openapi-3.0" });
630
741
  } catch (e) {
631
- 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`);
742
+ 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`, { cause: e });
632
743
  throw e;
633
744
  }
634
745
  }
635
746
  };
636
747
  const openApiGenerator = new OpenAPIGenerator();
637
- function _registerControllerClass(controllerClass, prefix) {
748
+ function _registerController(controllerClass, prefix) {
638
749
  openApiGenerator.registerController(controllerClass, prefix);
639
750
  }
640
- function setOpenApiConfig(config) {
641
- openApiGenerator.setConfig(config);
642
- }
643
751
  function generateOpenApiSpec() {
644
752
  return openApiGenerator.generateSpec();
645
753
  }
@@ -776,60 +884,6 @@ function _resolve(ctor) {
776
884
  return _InjectableRegistry.get(ctor);
777
885
  }
778
886
  //#endregion
779
- //#region src/annotation/validator.ts
780
- const _validatorSchemaStore = /* @__PURE__ */ new WeakMap();
781
- function ResponseBody(schema) {
782
- return (target, propertyKey) => {
783
- const ctor = target.constructor;
784
- const fnName = String(propertyKey);
785
- _setOnce(_getOrCreateSchemaDefinition(ctor, fnName), "responseBody", schema, fnName);
786
- };
787
- }
788
- function RequestBody(schema) {
789
- return (target, propertyKey) => {
790
- const ctor = target.constructor;
791
- const fnName = String(propertyKey);
792
- _setOnce(_getOrCreateSchemaDefinition(ctor, fnName), "requestBody", schema, fnName);
793
- };
794
- }
795
- function RequestParam(schema) {
796
- return (target, propertyKey) => {
797
- const ctor = target.constructor;
798
- const fnName = String(propertyKey);
799
- _setOnce(_getOrCreateSchemaDefinition(ctor, fnName), "requestParam", schema, fnName);
800
- };
801
- }
802
- function RequestQuery(schema) {
803
- return (target, propertyKey) => {
804
- const ctor = target.constructor;
805
- const fnName = String(propertyKey);
806
- _setOnce(_getOrCreateSchemaDefinition(ctor, fnName), "requestQuery", schema, fnName);
807
- };
808
- }
809
- function _getOrCreateSchemaDefinition(ctor, fnName) {
810
- const byFn = _getOrCreateMap(_validatorSchemaStore, ctor);
811
- const existing = byFn.get(fnName);
812
- if (existing) return existing;
813
- const created = {};
814
- byFn.set(fnName, created);
815
- return created;
816
- }
817
- async function _parseOrThrow(schema, input, kind) {
818
- const result = await schema["~standard"].validate(input);
819
- if (result.issues) {
820
- console.debug(`Failed to parse a schema`);
821
- throw new ParserError(kind, result.issues, schema["~standard"].vendor);
822
- }
823
- return result.value;
824
- }
825
- function _getValidatorSchema(ctor, fnName) {
826
- return _validatorSchemaStore.get(ctor)?.get(fnName);
827
- }
828
- function _setOnce(def, key, schema, fnName) {
829
- if (def[key]) throw new Error(`Duplicate schema for "${String(key)}" on method "${fnName}"`);
830
- def[key] = schema;
831
- }
832
- //#endregion
833
887
  //#region src/annotation/controller.ts
834
888
  const _ControllerRegistry = /* @__PURE__ */ new WeakMap();
835
889
  /**
@@ -841,7 +895,7 @@ const _ControllerRegistry = /* @__PURE__ */ new WeakMap();
841
895
  function Controller({ prefix = "", deps = [] } = {}) {
842
896
  return (target) => {
843
897
  const targetClass = target;
844
- _registerControllerClass(target, prefix);
898
+ _registerController(target, prefix);
845
899
  const router = (0, express.Router)();
846
900
  const routes = _getRoutes(target);
847
901
  const usedRoutes = /* @__PURE__ */ new Set();
@@ -866,15 +920,20 @@ Split these into separate @MiddlewareClass classes, or merge the logic into a si
866
920
  if (method === "USE" && fn.length >= 4) {
867
921
  const middlewareFn = async (err, request, response, next) => {
868
922
  try {
869
- const result = fn.bind(controllerInstance)(err, request, response, next);
870
- if (result instanceof ResponseEntity) {
871
- response.contentType("application/json").status(result.getStatusCode()).set(result.getHeaders()).send(Sapling.serialize(result.getBody()));
872
- return;
873
- }
874
- if (result instanceof RedirectView) {
875
- response.redirect(result.getUrl());
876
- return;
877
- }
923
+ await validate({
924
+ target,
925
+ fnName,
926
+ request
927
+ });
928
+ await handleResult({
929
+ result: fn.bind(controllerInstance)(err, request, response, next),
930
+ response,
931
+ target,
932
+ fnName,
933
+ method,
934
+ path: path instanceof RegExp ? path.source : fp,
935
+ isErrorMiddleware: true
936
+ });
878
937
  } catch (e) {
879
938
  console.error(e);
880
939
  next(e);
@@ -884,35 +943,52 @@ Split these into separate @MiddlewareClass classes, or merge the logic into a si
884
943
  return;
885
944
  }
886
945
  router[methodName](fp, async (request, response, next) => {
887
- const schemas = _getValidatorSchema(target, fnName);
888
- if (schemas) {
889
- if (schemas.requestBody) request.body = await _parseOrThrow(schemas.requestBody, request.body, "reqbody");
890
- if (schemas.requestParam) request.params = await _parseOrThrow(schemas.requestParam, request.params, "reqparams");
891
- if (schemas.requestQuery) {
892
- const parsedQuery = await _parseOrThrow(schemas.requestQuery, request.query, "reqquery");
893
- Object.defineProperty(request, "query", {
894
- value: parsedQuery,
895
- writable: true,
896
- configurable: true
897
- });
898
- }
899
- }
900
- const result = await fn.bind(controllerInstance)(request, response, next);
901
- if (result instanceof ResponseEntity) {
902
- const body = schemas && schemas.responseBody ? await _parseOrThrow(schemas.responseBody, result.getBody(), "resbody") : result.getBody();
903
- response.contentType("application/json").status(result.getStatusCode()).set(result.getHeaders()).send(Sapling.serialize(body));
904
- return;
905
- }
906
- if (result instanceof RedirectView) {
907
- response.redirect(result.getUrl());
908
- return;
909
- }
910
- if (method !== "USE" && !response.writableEnded) response.status(404).send(Html404ErrorPage(`Cannot ${methodName.toUpperCase()} ${path instanceof RegExp ? path.source : fp}`));
946
+ await validate({
947
+ target,
948
+ fnName,
949
+ request
950
+ });
951
+ await handleResult({
952
+ result: await fn.bind(controllerInstance)(request, response, next),
953
+ response,
954
+ target,
955
+ fnName,
956
+ method,
957
+ path: path instanceof RegExp ? path.source : fp
958
+ });
911
959
  });
912
960
  }
913
961
  _ControllerRegistry.set(targetClass, router);
914
962
  };
915
963
  }
964
+ async function handleResult({ result, target, fnName, response, method, path, isErrorMiddleware = false }) {
965
+ const schemas = _getValidatorSchema(target, fnName);
966
+ if (result instanceof ResponseEntity) {
967
+ const body = schemas && schemas.responseBody ? await _parseOrThrow(schemas.responseBody, result.getBody(), "resbody", fnName) : result.getBody();
968
+ response.contentType("application/json").status(result.getStatusCode()).set(result.getHeaders()).send(Sapling.serialize(body));
969
+ return;
970
+ }
971
+ if (result instanceof RedirectView) {
972
+ response.redirect(result.getUrl());
973
+ return;
974
+ }
975
+ if (!isErrorMiddleware && method !== "USE" && !response.writableEnded) response.status(404).send(Html404ErrorPage(`Cannot ${method} ${path}`));
976
+ }
977
+ async function validate({ target, fnName, request }) {
978
+ const schemas = _getValidatorSchema(target, fnName);
979
+ if (schemas) {
980
+ if (schemas.requestBody) request.body = await _parseOrThrow(schemas.requestBody, request.body, "reqbody", fnName);
981
+ if (schemas.requestParam) request.params = await _parseOrThrow(schemas.requestParam, request.params, "reqparams", fnName);
982
+ if (schemas.requestQuery) {
983
+ const parsedQuery = await _parseOrThrow(schemas.requestQuery, request.query, "reqquery", fnName);
984
+ Object.defineProperty(request, "query", {
985
+ value: parsedQuery,
986
+ writable: true,
987
+ configurable: true
988
+ });
989
+ }
990
+ }
991
+ }
916
992
  //#endregion
917
993
  //#region src/annotation/middleware.ts
918
994
  /**
@@ -947,7 +1023,10 @@ DefaultBaseErrorMiddleware = __decorate([MiddlewareClass()], DefaultBaseErrorMid
947
1023
  //#region src/middleware/default/error/parse.ts
948
1024
  let DefaultParserErrorMiddleware = class DefaultParserErrorMiddleware {
949
1025
  handle(err, _request, _response, next) {
950
- if (err instanceof ParserError) return ResponseEntity.status(err.status).body({ message: err.message });
1026
+ if (err instanceof ParserError) {
1027
+ console.warn(err);
1028
+ return ResponseEntity.status(err.status).body({ message: err.message });
1029
+ }
951
1030
  next(err);
952
1031
  }
953
1032
  };
@@ -974,17 +1053,48 @@ __decorate([GET(_settings.doc.openApiPath)], DefaultOpenApiMiddleware.prototype,
974
1053
  DefaultOpenApiMiddleware = __decorate([MiddlewareClass()], DefaultOpenApiMiddleware);
975
1054
  //#endregion
976
1055
  //#region src/middleware/default/swagger/index.ts
1056
+ /**
1057
+ * Enable the serving of the Swagger endpoint used to serve the OpenAPI spec generated by Sapling.
1058
+ *
1059
+ * Configure any middleware-specific settings with `Sapling.Extras.swaggerAndOpenApi`
1060
+ *
1061
+ * You must register `DefaultSwaggerMiddleware.Serve` & `DefaultSwaggerMiddleware.Setup` after `DefaultOpenApiMiddleware`
1062
+ *
1063
+ * ```ts
1064
+ * const middlewares = [
1065
+ * DefaultOpenApiMiddleware,
1066
+ * DefaultSwaggerMiddleware.Serve,
1067
+ * DefaultSwaggerMiddleware.Setup,
1068
+ * ];
1069
+ * middlewares.map(Sapling.resolve).forEach((r) => app.use(r));
1070
+ * ```
1071
+ */
977
1072
  let Serve = class Serve {
978
- constructor() {
979
- this.handlers = swagger_ui_express.default.serve;
980
- }
1073
+ handlers = swagger_ui_express.default.serve;
981
1074
  handle(request, response, next) {
982
1075
  return Sapling.chainHandlers(this.handlers, request, response, next);
983
1076
  }
984
1077
  };
985
1078
  __decorate([Middleware(_settings.doc.swaggerPath)], Serve.prototype, "handle", null);
986
1079
  Serve = __decorate([MiddlewareClass()], Serve);
1080
+ /**
1081
+ * Enable the serving of the Swagger endpoint used to serve the OpenAPI spec generated by Sapling.
1082
+ *
1083
+ * Configure any middleware-specific settings with `Sapling.Extras.swaggerAndOpenApi`
1084
+ *
1085
+ * You must register `DefaultSwaggerMiddleware.Serve` & `DefaultSwaggerMiddleware.Setup` after `DefaultOpenApiMiddleware`
1086
+ *
1087
+ * ```ts
1088
+ * const middlewares = [
1089
+ * DefaultOpenApiMiddleware,
1090
+ * DefaultSwaggerMiddleware.Serve,
1091
+ * DefaultSwaggerMiddleware.Setup,
1092
+ * ];
1093
+ * middlewares.map(Sapling.resolve).forEach((r) => app.use(r));
1094
+ * ```
1095
+ */
987
1096
  let Setup = class Setup {
1097
+ handler;
988
1098
  constructor() {
989
1099
  this.handler = swagger_ui_express.default.setup(null, { swaggerOptions: { url: _settings.doc.openApiPath } });
990
1100
  }
@@ -994,6 +1104,22 @@ let Setup = class Setup {
994
1104
  };
995
1105
  __decorate([Middleware(_settings.doc.swaggerPath)], Setup.prototype, "handle", null);
996
1106
  Setup = __decorate([MiddlewareClass()], Setup);
1107
+ /**
1108
+ * Enable the serving of the Swagger endpoint used to serve the OpenAPI spec generated by Sapling.
1109
+ *
1110
+ * Configure any middleware-specific settings with `Sapling.Extras.swaggerAndOpenApi`
1111
+ *
1112
+ * You must register `DefaultSwaggerMiddleware.Serve` & `DefaultSwaggerMiddleware.Setup` after `DefaultOpenApiMiddleware`
1113
+ *
1114
+ * ```ts
1115
+ * const middlewares = [
1116
+ * DefaultOpenApiMiddleware,
1117
+ * DefaultSwaggerMiddleware.Serve,
1118
+ * DefaultSwaggerMiddleware.Setup,
1119
+ * ];
1120
+ * middlewares.map(Sapling.resolve).forEach((r) => app.use(r));
1121
+ * ```
1122
+ */
997
1123
  const DefaultSwaggerMiddleware = {
998
1124
  Serve,
999
1125
  Setup
@@ -1059,13 +1185,12 @@ exports._getRouteSchema = _getRouteSchema;
1059
1185
  exports._getRoutes = _getRoutes;
1060
1186
  exports._getValidatorSchema = _getValidatorSchema;
1061
1187
  exports._parseOrThrow = _parseOrThrow;
1062
- exports._registerControllerClass = _registerControllerClass;
1188
+ exports._registerController = _registerController;
1063
1189
  exports._resolve = _resolve;
1190
+ exports._saveValidatorSchema = _saveValidatorSchema;
1064
1191
  exports._setControllerSchema = _setControllerSchema;
1065
- exports._setOnce = _setOnce;
1066
1192
  exports._setRouteSchema = _setRouteSchema;
1067
1193
  exports._settings = _settings;
1068
1194
  exports.generateOpenApiSpec = generateOpenApiSpec;
1069
1195
  exports.methodResolve = methodResolve;
1070
1196
  exports.openApiGenerator = openApiGenerator;
1071
- exports.setOpenApiConfig = setOpenApiConfig;