@tahminator/sapling 2.0.3 → 2.0.5-beta.18ab8bae

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.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  import e, { Router } from "express";
2
+ import swagger from "swagger-ui-express";
2
3
  //#region src/html/404.ts
3
4
  /**
4
5
  * Default Express.js 404 error page, as a string.
@@ -232,15 +233,20 @@ var ParserError = class ParserError extends ResponseStatusError {
232
233
  case "reqbody": return "request body";
233
234
  case "reqparams": return "request params";
234
235
  case "reqquery": return "request query";
236
+ case "resbody": return "response body";
235
237
  }
236
238
  })()}: ${formatted}`;
237
239
  }
238
240
  };
239
241
  //#endregion
240
242
  //#region src/helper/sapling.ts
241
- const settings = {
243
+ const _settings = {
242
244
  serialize: JSON.stringify,
243
- deserialize: JSON.parse
245
+ deserialize: JSON.parse,
246
+ doc: {
247
+ openApiPath: "/openapi.json",
248
+ swaggerPath: "/swagger.html"
249
+ }
244
250
  };
245
251
  /**
246
252
  * Collection of utility functions which are essential for Sapling to function.
@@ -319,13 +325,13 @@ var Sapling = class Sapling {
319
325
  * @defaultValue `JSON.stringify`
320
326
  */
321
327
  static serialize(value) {
322
- return settings.serialize(value);
328
+ return _settings.serialize(value);
323
329
  }
324
330
  /**
325
331
  * Replace the function used for `serialize`.
326
332
  */
327
333
  static setSerializeFn(fn) {
328
- settings.serialize = fn;
334
+ _settings.serialize = fn;
329
335
  }
330
336
  /**
331
337
  * De-serialize a JSON string back to a JavaScript object.
@@ -337,16 +343,265 @@ var Sapling = class Sapling {
337
343
  * @defaultValue `JSON.parse`
338
344
  */
339
345
  static deserialize(value) {
340
- return settings.deserialize(value);
346
+ return _settings.deserialize(value);
341
347
  }
342
348
  /**
343
349
  * Replace the function used for `deserialize`
344
350
  */
345
351
  static setDeserializeFn(fn) {
346
- settings.deserialize = fn;
352
+ _settings.deserialize = fn;
353
+ }
354
+ static setOpenApiPath(path) {
355
+ _settings.doc.openApiPath = path;
356
+ }
357
+ static setSwaggerPath(path) {
358
+ _settings.doc.swaggerPath = path;
359
+ }
360
+ static chainHandlers(handlers, request, response, next, index = 0) {
361
+ if (index >= handlers.length) {
362
+ next();
363
+ return;
364
+ }
365
+ handlers[index]?.(request, response, (err) => {
366
+ if (err) {
367
+ next(err);
368
+ return;
369
+ }
370
+ Sapling.chainHandlers(handlers, request, response, next, index + 1);
371
+ });
347
372
  }
348
373
  };
349
374
  //#endregion
375
+ //#region src/annotation/route.ts
376
+ const _routeStore = /* @__PURE__ */ new WeakMap();
377
+ /**
378
+ * Custom annotation that will store all routes inside of a map,
379
+ * which can then be used to initialize all the routes to the router.
380
+ */
381
+ function _Route({ method, path = "" }) {
382
+ return (target, propertyKey) => {
383
+ const ctor = target.constructor;
384
+ const list = _routeStore.get(ctor) ?? [];
385
+ list.push({
386
+ method,
387
+ path: path ?? "",
388
+ fnName: String(propertyKey)
389
+ });
390
+ _routeStore.set(ctor, list);
391
+ };
392
+ }
393
+ /**
394
+ * Register GET route on the given path (default "") for the given controller.
395
+ */
396
+ const GET = (path = "") => _Route({
397
+ method: "GET",
398
+ path
399
+ });
400
+ /**
401
+ * Register POST route on the given path (default "") for the given controller.
402
+ */
403
+ const POST = (path = "") => _Route({
404
+ method: "POST",
405
+ path
406
+ });
407
+ /**
408
+ * Register PUT route on the given path (default "") for the given controller.
409
+ */
410
+ const PUT = (path = "") => _Route({
411
+ method: "PUT",
412
+ path
413
+ });
414
+ /**
415
+ * Register DELETE route on the given path (default "") for the given controller.
416
+ */
417
+ const DELETE = (path = "") => _Route({
418
+ method: "DELETE",
419
+ path
420
+ });
421
+ /**
422
+ * Register OPTIONS route on the given path (default "") for the given controller.
423
+ */
424
+ const OPTIONS = (path = "") => _Route({
425
+ method: "OPTIONS",
426
+ path
427
+ });
428
+ /**
429
+ * Register PATCH route on the given path (default "") for the given controller.
430
+ */
431
+ const PATCH = (path = "") => _Route({
432
+ method: "PATCH",
433
+ path
434
+ });
435
+ /**
436
+ * Register HEAD route on the given path (default "") for the given controller.
437
+ */
438
+ const HEAD = (path = "") => _Route({
439
+ method: "HEAD",
440
+ path
441
+ });
442
+ /**
443
+ * Register a middleware route on the given path (default "") for the given controller.
444
+ */
445
+ const Middleware = (path = "") => _Route({
446
+ method: "USE",
447
+ path
448
+ });
449
+ /**
450
+ * Given a class constructor, fetch all the routes attached.
451
+ */
452
+ function _getRoutes(ctor) {
453
+ return _routeStore.get(ctor) ?? [];
454
+ }
455
+ //#endregion
456
+ //#region src/utils.ts
457
+ function _getOrCreateMap(store, ctor) {
458
+ const existing = store.get(ctor);
459
+ if (existing) return existing;
460
+ const created = /* @__PURE__ */ new Map();
461
+ store.set(ctor, created);
462
+ return created;
463
+ }
464
+ //#endregion
465
+ //#region src/annotation/schema.ts
466
+ const _routeSchemaStore = /* @__PURE__ */ new WeakMap();
467
+ const _controllerSchemaStore = /* @__PURE__ */ new WeakMap();
468
+ function ControllerSchema(options) {
469
+ return (target) => {
470
+ _setControllerSchema(target, options);
471
+ };
472
+ }
473
+ function RouteSchema(options) {
474
+ return (target, propertyKey) => {
475
+ const ctor = target.constructor;
476
+ _setRouteSchema(ctor, String(propertyKey), options);
477
+ };
478
+ }
479
+ function _setRouteSchema(ctor, fnName, options) {
480
+ _getOrCreateMap(_routeSchemaStore, ctor).set(fnName, options);
481
+ }
482
+ function _setControllerSchema(ctor, options) {
483
+ _controllerSchemaStore.set(ctor, options);
484
+ }
485
+ function _getRouteSchema(ctor, fnName) {
486
+ return _routeSchemaStore.get(ctor)?.get(fnName);
487
+ }
488
+ function _getControllerSchema(ctor) {
489
+ return _controllerSchemaStore.get(ctor);
490
+ }
491
+ //#endregion
492
+ //#region src/helper/openapi.ts
493
+ var OpenAPIGenerator = class {
494
+ constructor() {
495
+ this.controllers = /* @__PURE__ */ new Set();
496
+ this.config = {
497
+ title: "API",
498
+ version: "1.0.0"
499
+ };
500
+ }
501
+ setConfig(config) {
502
+ this.config = config;
503
+ }
504
+ registerController(controllerClass, prefix) {
505
+ this.controllers.add({
506
+ class: controllerClass,
507
+ prefix
508
+ });
509
+ }
510
+ generateSpec() {
511
+ const config = this.config;
512
+ const paths = {};
513
+ const tags = [];
514
+ for (const { class: controllerClass, prefix } of this.controllers) {
515
+ const routes = _getRoutes(controllerClass);
516
+ const controllerSchema = _getControllerSchema(controllerClass);
517
+ if (controllerSchema?.title) tags.push({
518
+ name: controllerSchema.title,
519
+ description: controllerSchema.description
520
+ });
521
+ for (const route of routes) {
522
+ if (route.method === "USE") continue;
523
+ const schemas = _getValidatorSchema(controllerClass, route.fnName);
524
+ const routeSchema = _getRouteSchema(controllerClass, route.fnName);
525
+ if (route.path instanceof RegExp) throw new Error(`You have a route with a regex path of ${route.path.source}. This is not compatible with OpenAPI.`);
526
+ const openApiPath = prefix + route.path;
527
+ if (!paths[openApiPath]) paths[openApiPath] = {};
528
+ const responses = {};
529
+ if (schemas?.responseBody) responses["200"] = {
530
+ description: "Successful response",
531
+ content: { "application/json": { schema: this.toJsonSchema(schemas.responseBody) } }
532
+ };
533
+ else responses["200"] = { description: "Successful response" };
534
+ if (routeSchema?.responses) for (const resp of routeSchema.responses) responses[String(resp.statusCode)] = {
535
+ description: `Response ${resp.statusCode}`,
536
+ content: { "application/json": { schema: this.toJsonSchema(resp.schema) } }
537
+ };
538
+ const operation = {
539
+ responses,
540
+ description: routeSchema?.description,
541
+ tags: controllerSchema?.title ? [controllerSchema.title] : void 0
542
+ };
543
+ const parameters = [];
544
+ if (schemas?.requestParam) {
545
+ const paramSchema = this.toJsonSchema(schemas.requestParam);
546
+ if (paramSchema.type === "object" && paramSchema.properties) for (const [name, schema] of Object.entries(paramSchema.properties)) parameters.push({
547
+ name,
548
+ in: "path",
549
+ required: true,
550
+ schema
551
+ });
552
+ }
553
+ if (schemas?.requestQuery) {
554
+ const querySchema = this.toJsonSchema(schemas.requestQuery);
555
+ if (querySchema.type === "object" && querySchema.properties) for (const [name, schema] of Object.entries(querySchema.properties)) {
556
+ const isRequired = Array.isArray(querySchema.required) && querySchema.required.includes(name);
557
+ parameters.push({
558
+ name,
559
+ in: "query",
560
+ required: isRequired,
561
+ schema
562
+ });
563
+ }
564
+ }
565
+ if (parameters.length > 0) operation.parameters = parameters;
566
+ if (schemas?.requestBody) operation.requestBody = {
567
+ required: true,
568
+ content: { "application/json": { schema: this.toJsonSchema(schemas.requestBody) } }
569
+ };
570
+ const method = route.method.toLowerCase();
571
+ paths[openApiPath][method] = operation;
572
+ }
573
+ }
574
+ return {
575
+ openapi: "3.0.0",
576
+ info: {
577
+ title: config.title,
578
+ version: config.version,
579
+ description: config.description
580
+ },
581
+ tags: tags.length > 0 ? tags : void 0,
582
+ paths
583
+ };
584
+ }
585
+ toJsonSchema(schema) {
586
+ try {
587
+ return schema["~standard"].jsonSchema.output({ target: "openapi-3.0" });
588
+ } catch (e) {
589
+ 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`);
590
+ throw e;
591
+ }
592
+ }
593
+ };
594
+ const openApiGenerator = new OpenAPIGenerator();
595
+ function _registerControllerClass(controllerClass, prefix) {
596
+ openApiGenerator.registerController(controllerClass, prefix);
597
+ }
598
+ function setOpenApiConfig(config) {
599
+ openApiGenerator.setConfig(config);
600
+ }
601
+ function generateOpenApiSpec() {
602
+ return openApiGenerator.generateSpec();
603
+ }
604
+ //#endregion
350
605
  //#region src/types.ts
351
606
  const methodResolve = {
352
607
  GET: "get",
@@ -479,49 +734,43 @@ function _resolve(ctor) {
479
734
  return _InjectableRegistry.get(ctor);
480
735
  }
481
736
  //#endregion
482
- //#region src/annotation/request.ts
483
- const _requestSchemaStore = /* @__PURE__ */ new WeakMap();
484
- function _getOrCreateRequestSchemaDefinition(ctor, fnName) {
485
- const byFn = (() => {
486
- const fn = _requestSchemaStore.get(ctor);
487
- if (fn) return fn;
488
- const newFn = /* @__PURE__ */ new Map();
489
- _requestSchemaStore.set(ctor, newFn);
490
- return newFn;
491
- })();
492
- const existing = byFn.get(fnName);
493
- if (existing) return existing;
494
- const created = {};
495
- byFn.set(fnName, created);
496
- return created;
497
- }
498
- function _setOnce(def, key, schema, fnName) {
499
- if (def[key]) throw new Error(`Duplicate request schema for "${String(key)}" on method "${fnName}"`);
500
- def[key] = schema;
737
+ //#region src/annotation/validator.ts
738
+ const _validatorSchemaStore = /* @__PURE__ */ new WeakMap();
739
+ function ResponseBody(schema) {
740
+ return (target, propertyKey) => {
741
+ const ctor = target.constructor;
742
+ const fnName = String(propertyKey);
743
+ _setOnce(_getOrCreateSchemaDefinition(ctor, fnName), "responseBody", schema, fnName);
744
+ };
501
745
  }
502
746
  function RequestBody(schema) {
503
747
  return (target, propertyKey) => {
504
748
  const ctor = target.constructor;
505
749
  const fnName = String(propertyKey);
506
- _setOnce(_getOrCreateRequestSchemaDefinition(ctor, fnName), "body", schema, fnName);
750
+ _setOnce(_getOrCreateSchemaDefinition(ctor, fnName), "requestBody", schema, fnName);
507
751
  };
508
752
  }
509
753
  function RequestParam(schema) {
510
754
  return (target, propertyKey) => {
511
755
  const ctor = target.constructor;
512
756
  const fnName = String(propertyKey);
513
- _setOnce(_getOrCreateRequestSchemaDefinition(ctor, fnName), "param", schema, fnName);
757
+ _setOnce(_getOrCreateSchemaDefinition(ctor, fnName), "requestParam", schema, fnName);
514
758
  };
515
759
  }
516
760
  function RequestQuery(schema) {
517
761
  return (target, propertyKey) => {
518
762
  const ctor = target.constructor;
519
763
  const fnName = String(propertyKey);
520
- _setOnce(_getOrCreateRequestSchemaDefinition(ctor, fnName), "query", schema, fnName);
764
+ _setOnce(_getOrCreateSchemaDefinition(ctor, fnName), "requestQuery", schema, fnName);
521
765
  };
522
766
  }
523
- function _getRequestSchemas(ctor, fnName) {
524
- return _requestSchemaStore.get(ctor)?.get(fnName);
767
+ function _getOrCreateSchemaDefinition(ctor, fnName) {
768
+ const byFn = _getOrCreateMap(_validatorSchemaStore, ctor);
769
+ const existing = byFn.get(fnName);
770
+ if (existing) return existing;
771
+ const created = {};
772
+ byFn.set(fnName, created);
773
+ return created;
525
774
  }
526
775
  async function _parseOrThrow(schema, input, kind) {
527
776
  const result = await schema["~standard"].validate(input);
@@ -531,86 +780,12 @@ async function _parseOrThrow(schema, input, kind) {
531
780
  }
532
781
  return result.value;
533
782
  }
534
- //#endregion
535
- //#region src/annotation/route.ts
536
- const _routeStore = /* @__PURE__ */ new WeakMap();
537
- /**
538
- * Custom annotation that will store all routes inside of a map,
539
- * which can then be used to initialize all the routes to the router.
540
- */
541
- function _Route({ method, path = "" }) {
542
- return (target, propertyKey) => {
543
- const ctor = target.constructor;
544
- const list = _routeStore.get(ctor) ?? [];
545
- list.push({
546
- method,
547
- path: path ?? "",
548
- fnName: String(propertyKey)
549
- });
550
- _routeStore.set(ctor, list);
551
- };
783
+ function _getValidatorSchema(ctor, fnName) {
784
+ return _validatorSchemaStore.get(ctor)?.get(fnName);
552
785
  }
553
- /**
554
- * Register GET route on the given path (default "") for the given controller.
555
- */
556
- const GET = (path = "") => _Route({
557
- method: "GET",
558
- path
559
- });
560
- /**
561
- * Register POST route on the given path (default "") for the given controller.
562
- */
563
- const POST = (path = "") => _Route({
564
- method: "POST",
565
- path
566
- });
567
- /**
568
- * Register PUT route on the given path (default "") for the given controller.
569
- */
570
- const PUT = (path = "") => _Route({
571
- method: "PUT",
572
- path
573
- });
574
- /**
575
- * Register DELETE route on the given path (default "") for the given controller.
576
- */
577
- const DELETE = (path = "") => _Route({
578
- method: "DELETE",
579
- path
580
- });
581
- /**
582
- * Register OPTIONS route on the given path (default "") for the given controller.
583
- */
584
- const OPTIONS = (path = "") => _Route({
585
- method: "OPTIONS",
586
- path
587
- });
588
- /**
589
- * Register PATCH route on the given path (default "") for the given controller.
590
- */
591
- const PATCH = (path = "") => _Route({
592
- method: "PATCH",
593
- path
594
- });
595
- /**
596
- * Register HEAD route on the given path (default "") for the given controller.
597
- */
598
- const HEAD = (path = "") => _Route({
599
- method: "HEAD",
600
- path
601
- });
602
- /**
603
- * Register a middleware route on the given path (default "") for the given controller.
604
- */
605
- const Middleware = (path = "") => _Route({
606
- method: "USE",
607
- path
608
- });
609
- /**
610
- * Given a class constructor, fetch all the routes attached.
611
- */
612
- function _getRoutes(ctor) {
613
- return _routeStore.get(ctor) ?? [];
786
+ function _setOnce(def, key, schema, fnName) {
787
+ if (def[key]) throw new Error(`Duplicate schema for "${String(key)}" on method "${fnName}"`);
788
+ def[key] = schema;
614
789
  }
615
790
  //#endregion
616
791
  //#region src/annotation/controller.ts
@@ -624,6 +799,7 @@ const _ControllerRegistry = /* @__PURE__ */ new WeakMap();
624
799
  function Controller({ prefix = "", deps = [] } = {}) {
625
800
  return (target) => {
626
801
  const targetClass = target;
802
+ _registerControllerClass(target, prefix);
627
803
  const router = Router();
628
804
  const routes = _getRoutes(target);
629
805
  const usedRoutes = /* @__PURE__ */ new Set();
@@ -666,12 +842,12 @@ Split these into separate @MiddlewareClass classes, or merge the logic into a si
666
842
  return;
667
843
  }
668
844
  router[methodName](fp, async (request, response, next) => {
669
- const schemas = _getRequestSchemas(target, fnName);
845
+ const schemas = _getValidatorSchema(target, fnName);
670
846
  if (schemas) {
671
- if (schemas.body) request.body = await _parseOrThrow(schemas.body, request.body, "reqbody");
672
- if (schemas.param) request.params = await _parseOrThrow(schemas.param, request.params, "reqparams");
673
- if (schemas.query) {
674
- const parsedQuery = await _parseOrThrow(schemas.query, request.query, "reqquery");
847
+ if (schemas.requestBody) request.body = await _parseOrThrow(schemas.requestBody, request.body, "reqbody");
848
+ if (schemas.requestParam) request.params = await _parseOrThrow(schemas.requestParam, request.params, "reqparams");
849
+ if (schemas.requestQuery) {
850
+ const parsedQuery = await _parseOrThrow(schemas.requestQuery, request.query, "reqquery");
675
851
  Object.defineProperty(request, "query", {
676
852
  value: parsedQuery,
677
853
  writable: true,
@@ -681,7 +857,8 @@ Split these into separate @MiddlewareClass classes, or merge the logic into a si
681
857
  }
682
858
  const result = await fn.bind(controllerInstance)(request, response, next);
683
859
  if (result instanceof ResponseEntity) {
684
- response.contentType("application/json").status(result.getStatusCode()).set(result.getHeaders()).send(Sapling.serialize(result.getBody()));
860
+ const body = schemas && schemas.responseBody ? await _parseOrThrow(schemas.responseBody, result.getBody(), "resbody") : result.getBody();
861
+ response.contentType("application/json").status(result.getStatusCode()).set(result.getHeaders()).send(Sapling.serialize(body));
685
862
  return;
686
863
  }
687
864
  if (result instanceof RedirectView) {
@@ -715,7 +892,7 @@ function __decorate(decorators, target, key, desc) {
715
892
  return c > 3 && r && Object.defineProperty(target, key, r), r;
716
893
  }
717
894
  //#endregion
718
- //#region src/middleware/default/base.ts
895
+ //#region src/middleware/default/error/base.ts
719
896
  let DefaultBaseErrorMiddleware = class DefaultBaseErrorMiddleware {
720
897
  handle(err, _request, _response, _next) {
721
898
  console.error("[Error]", err);
@@ -725,7 +902,17 @@ let DefaultBaseErrorMiddleware = class DefaultBaseErrorMiddleware {
725
902
  __decorate([Middleware()], DefaultBaseErrorMiddleware.prototype, "handle", null);
726
903
  DefaultBaseErrorMiddleware = __decorate([MiddlewareClass()], DefaultBaseErrorMiddleware);
727
904
  //#endregion
728
- //#region src/middleware/default/responsestatus.ts
905
+ //#region src/middleware/default/error/parse.ts
906
+ let DefaultParserErrorMiddleware = class DefaultParserErrorMiddleware {
907
+ handle(err, _request, _response, next) {
908
+ if (err instanceof ParserError) return ResponseEntity.status(err.status).body({ message: err.message });
909
+ next(err);
910
+ }
911
+ };
912
+ __decorate([Middleware()], DefaultParserErrorMiddleware.prototype, "handle", null);
913
+ DefaultParserErrorMiddleware = __decorate([MiddlewareClass()], DefaultParserErrorMiddleware);
914
+ //#endregion
915
+ //#region src/middleware/default/error/responsestatus.ts
729
916
  let DefaultResponseStatusErrorMiddleware = class DefaultResponseStatusErrorMiddleware {
730
917
  handle(err, _request, _response, next) {
731
918
  if (err instanceof ResponseStatusError) return ResponseEntity.status(err.status).body({ message: err.message });
@@ -735,4 +922,39 @@ let DefaultResponseStatusErrorMiddleware = class DefaultResponseStatusErrorMiddl
735
922
  __decorate([Middleware()], DefaultResponseStatusErrorMiddleware.prototype, "handle", null);
736
923
  DefaultResponseStatusErrorMiddleware = __decorate([MiddlewareClass()], DefaultResponseStatusErrorMiddleware);
737
924
  //#endregion
738
- export { Controller, DELETE, DefaultBaseErrorMiddleware, DefaultResponseStatusErrorMiddleware, GET, HEAD, Html404ErrorPage, HttpStatus, Injectable, Middleware, MiddlewareClass, OPTIONS, PATCH, POST, PUT, ParserError, RedirectView, RequestBody, RequestParam, RequestQuery, ResponseEntity, ResponseEntityBuilder, ResponseStatusError, Sapling, _ControllerRegistry, _InjectableDeps, _InjectableRegistry, _Route, _getRequestSchemas, _getRoutes, _parseOrThrow, _resolve, methodResolve };
925
+ //#region src/middleware/default/openapi/index.ts
926
+ let DefaultOpenApiMiddleware = class DefaultOpenApiMiddleware {
927
+ handle(_request, _response, _next) {
928
+ return ResponseEntity.ok().body(generateOpenApiSpec());
929
+ }
930
+ };
931
+ __decorate([GET(_settings.doc.openApiPath)], DefaultOpenApiMiddleware.prototype, "handle", null);
932
+ DefaultOpenApiMiddleware = __decorate([MiddlewareClass()], DefaultOpenApiMiddleware);
933
+ //#endregion
934
+ //#region src/middleware/default/swagger/index.ts
935
+ let Serve = class Serve {
936
+ constructor() {
937
+ this.handlers = swagger.serve;
938
+ }
939
+ handle(request, response, next) {
940
+ return Sapling.chainHandlers(this.handlers, request, response, next);
941
+ }
942
+ };
943
+ __decorate([Middleware(_settings.doc.swaggerPath)], Serve.prototype, "handle", null);
944
+ Serve = __decorate([MiddlewareClass()], Serve);
945
+ let Setup = class Setup {
946
+ constructor() {
947
+ this.handler = swagger.setup(null, { swaggerOptions: { url: _settings.doc.openApiPath } });
948
+ }
949
+ handle(request, response, next) {
950
+ return this.handler(request, response, next);
951
+ }
952
+ };
953
+ __decorate([Middleware(_settings.doc.swaggerPath)], Setup.prototype, "handle", null);
954
+ Setup = __decorate([MiddlewareClass()], Setup);
955
+ const DefaultSwaggerMiddleware = {
956
+ Serve,
957
+ Setup
958
+ };
959
+ //#endregion
960
+ export { Controller, ControllerSchema, DELETE, DefaultBaseErrorMiddleware, DefaultOpenApiMiddleware, DefaultParserErrorMiddleware, DefaultResponseStatusErrorMiddleware, DefaultSwaggerMiddleware, GET, HEAD, Html404ErrorPage, HttpStatus, Injectable, Middleware, MiddlewareClass, OPTIONS, PATCH, POST, PUT, ParserError, RedirectView, RequestBody, RequestParam, RequestQuery, ResponseBody, ResponseEntity, ResponseEntityBuilder, ResponseStatusError, RouteSchema, Sapling, _ControllerRegistry, _InjectableDeps, _InjectableRegistry, _Route, _getControllerSchema, _getOrCreateSchemaDefinition, _getRouteSchema, _getRoutes, _getValidatorSchema, _parseOrThrow, _registerControllerClass, _resolve, _setControllerSchema, _setOnce, _setRouteSchema, _settings, generateOpenApiSpec, methodResolve, openApiGenerator, setOpenApiConfig };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tahminator/sapling",
3
- "version": "2.0.3",
3
+ "version": "2.0.5-beta.18ab8bae",
4
4
  "author": "Tahmid Ahmed",
5
5
  "description": "A library to help you write cleaner Express.js code",
6
6
  "repository": {
@@ -44,12 +44,14 @@
44
44
  "@standard-schema/spec": "^1.1.0",
45
45
  "@types/express": "^5",
46
46
  "@types/supertest": "^7.2.0",
47
+ "@types/swagger-ui-express": "^4.1.8",
47
48
  "@vitest/coverage-istanbul": "^4.1.2",
48
49
  "eslint": "^10.1.0",
49
50
  "eslint-plugin-perfectionist": "^5.7.0",
50
51
  "globals": "^17.4.0",
51
52
  "jiti": "^2.6.1",
52
53
  "jsdom": "^29.0.1",
54
+ "openapi-types": "12.1.3",
53
55
  "prettier": "^3.8.1",
54
56
  "superjson": "^2.2.6",
55
57
  "supertest": "^7.2.2",
@@ -60,6 +62,10 @@
60
62
  "zod": "^4.4.3"
61
63
  },
62
64
  "inlinedDependencies": {
63
- "@standard-schema/spec": "1.1.0"
65
+ "@standard-schema/spec": "1.1.0",
66
+ "openapi-types": "12.1.3"
67
+ },
68
+ "dependencies": {
69
+ "swagger-ui-express": "^5.0.1"
64
70
  }
65
71
  }