@tahminator/sapling 2.0.5-beta.e0403942 → 2.1.0-beta.0e8a97e8

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
@@ -270,10 +270,160 @@ var ParserError = class ParserError extends ResponseStatusError {
270
270
  }
271
271
  };
272
272
  //#endregion
273
+ //#region lib/weakmap.ts
274
+ /**
275
+ * WeakMap that is iterable.
276
+ */
277
+ var IterableWeakMap = class IterableWeakMap {
278
+ #weakMap = /* @__PURE__ */ new WeakMap();
279
+ #refSet = /* @__PURE__ */ new Set();
280
+ #finalizationGroup = new FinalizationRegistry(IterableWeakMap.#cleanup);
281
+ static #cleanup(heldValue) {
282
+ heldValue.set.delete(heldValue.ref);
283
+ }
284
+ constructor(iterable) {
285
+ if (iterable) for (const [key, value] of iterable) this.set(key, value);
286
+ }
287
+ set(key, value) {
288
+ const ref = new WeakRef(key);
289
+ this.#weakMap.set(key, {
290
+ value,
291
+ ref
292
+ });
293
+ this.#refSet.add(ref);
294
+ this.#finalizationGroup.register(key, {
295
+ set: this.#refSet,
296
+ ref
297
+ }, ref);
298
+ return this;
299
+ }
300
+ get(key) {
301
+ return this.#weakMap.get(key)?.value;
302
+ }
303
+ delete(key) {
304
+ const entry = this.#weakMap.get(key);
305
+ if (!entry) return false;
306
+ this.#weakMap.delete(key);
307
+ this.#refSet.delete(entry.ref);
308
+ this.#finalizationGroup.unregister(entry.ref);
309
+ return true;
310
+ }
311
+ *[Symbol.iterator]() {
312
+ for (const ref of this.#refSet) {
313
+ const key = ref.deref();
314
+ if (!key) continue;
315
+ const entry = this.#weakMap.get(key);
316
+ if (entry) yield [key, entry.value];
317
+ }
318
+ }
319
+ entries() {
320
+ return this[Symbol.iterator]();
321
+ }
322
+ *keys() {
323
+ for (const [key] of this) yield key;
324
+ }
325
+ *values() {
326
+ for (const [, value] of this) yield value;
327
+ }
328
+ forEach(callback, thisArg) {
329
+ for (const [key, value] of this) callback.call(thisArg, value, key, this);
330
+ }
331
+ };
332
+ //#endregion
333
+ //#region src/annotation/injectable.ts
334
+ const _InjectableRegistry = /* @__PURE__ */ new WeakMap();
335
+ const _InjectableDeps = new IterableWeakMap();
336
+ /**
337
+ * Mark the class as an injectable to be handled by Sapling. The class can now be
338
+ * be injected into other classes, as well as allow the class to inject other `@Injectable` classes.
339
+ *
340
+ * @argument deps - An optional array to define any dependencies that this class may require.
341
+ */
342
+ function Injectable(deps = []) {
343
+ return function(target) {
344
+ _InjectableRegistry.set(target, null);
345
+ _InjectableDeps.set(target, deps);
346
+ };
347
+ }
348
+ /**
349
+ * Resolves and instantiates a class along with all of it's transitive dependencies.
350
+ *
351
+ * Uses topological sort (Kahn's algorithm) to ensure that the dependency graph is created
352
+ * in a correct order.
353
+ *
354
+ * When `resolve` is first called (usually during controller registration),
355
+ * it will compute the dependency graph of all `@Injectable` classes and instantiates
356
+ * them in the correct order.
357
+ *
358
+ * Subsequent calls to dependencies that have already been resolved are cached, so they will
359
+ * re-use the created singletons instead of re-instantiation.
360
+ */
361
+ function _resolve(ctor) {
362
+ const inDegree = /* @__PURE__ */ new Map();
363
+ const graph = /* @__PURE__ */ new Map();
364
+ _InjectableDeps.forEach((deps, node) => {
365
+ inDegree.set(node, inDegree.get(node) || 0);
366
+ deps.forEach((dep) => {
367
+ if (dep === void 0) throw new Error(`There is an @Injectable (${node.name}) which has a dependency that cannot be found. This is likely caused by a circular dependency.`);
368
+ inDegree.set(dep, inDegree.get(dep) || 0);
369
+ inDegree.set(node, inDegree.get(node) + 1);
370
+ if (!graph.has(dep)) graph.set(dep, []);
371
+ graph.get(dep).push(node);
372
+ });
373
+ });
374
+ const queue = [];
375
+ inDegree.forEach((deg, node) => {
376
+ if (deg === 0) queue.push(node);
377
+ });
378
+ while (queue.length) {
379
+ const current = queue.shift();
380
+ if (!_InjectableRegistry.get(current)) {
381
+ const instance = new current(...(_InjectableDeps.get(current) || []).map((dep) => _InjectableRegistry.get(dep)));
382
+ _InjectableRegistry.set(current, instance);
383
+ }
384
+ (graph.get(current) || []).forEach((neighbor) => {
385
+ inDegree.set(neighbor, (inDegree.get(neighbor) ?? 0) - 1);
386
+ if (inDegree.get(neighbor) === 0) queue.push(neighbor);
387
+ });
388
+ }
389
+ if (!_InjectableRegistry.get(ctor)) throw new Error("Circular dependency detected or injectable not registered");
390
+ return _InjectableRegistry.get(ctor);
391
+ }
392
+ //#endregion
393
+ //#region \0@oxc-project+runtime@0.127.0/helpers/decorate.js
394
+ function __decorate(decorators, target, key, desc) {
395
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
396
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
397
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
398
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
399
+ }
400
+ //#endregion
401
+ //#region src/middleware/health/registrar.ts
402
+ let HealthRegistrar = class HealthRegistrar {
403
+ _checks;
404
+ _sealed;
405
+ constructor() {
406
+ this._checks = [];
407
+ this._sealed = false;
408
+ }
409
+ add(healthCheck) {
410
+ this._checks.push(healthCheck);
411
+ }
412
+ seal() {
413
+ this._sealed = true;
414
+ }
415
+ async check() {
416
+ if (!this._sealed) return false;
417
+ return (await Promise.all(this._checks.map((c) => c()))).every((c) => c === true);
418
+ }
419
+ };
420
+ HealthRegistrar = __decorate([Injectable()], HealthRegistrar);
421
+ //#endregion
273
422
  //#region src/helper/sapling.ts
274
423
  const _settings = {
275
424
  serialize: JSON.stringify,
276
425
  deserialize: JSON.parse,
426
+ health: { path: "/up" },
277
427
  doc: {
278
428
  openApiPath: "/openapi.json",
279
429
  swaggerPath: "/swagger.html",
@@ -349,6 +499,7 @@ var Sapling = class Sapling {
349
499
  static registerApp(app) {
350
500
  app.use(express.default.text({ type: "application/json" }));
351
501
  app.use(Sapling.json());
502
+ _InjectableRegistry.get(HealthRegistrar)?.seal();
352
503
  }
353
504
  /**
354
505
  * Serialize a value into a JSON string.
@@ -629,6 +780,7 @@ function _getValidatorSchema(ctor, fnName) {
629
780
  //#endregion
630
781
  //#region src/helper/openapi.ts
631
782
  var OpenAPIGenerator = class {
783
+ OPENAPI_VERSION = "3.0.0";
632
784
  controllers = /* @__PURE__ */ new Set();
633
785
  registerController(controllerClass, prefix) {
634
786
  this.controllers.add({
@@ -636,6 +788,12 @@ var OpenAPIGenerator = class {
636
788
  prefix
637
789
  });
638
790
  }
791
+ /**
792
+ * visible for testing
793
+ */
794
+ _clearControllers() {
795
+ this.controllers.clear();
796
+ }
639
797
  get metadata() {
640
798
  return _settings.doc.metadata;
641
799
  }
@@ -724,7 +882,7 @@ var OpenAPIGenerator = class {
724
882
  }
725
883
  }
726
884
  return {
727
- openapi: "3.0.0",
885
+ openapi: this.OPENAPI_VERSION,
728
886
  info: {
729
887
  title: metadata.title,
730
888
  version: metadata.version,
@@ -751,6 +909,9 @@ function _registerController(controllerClass, prefix) {
751
909
  function generateOpenApiSpec() {
752
910
  return openApiGenerator.generateSpec();
753
911
  }
912
+ function _clearOpenApiRegistry() {
913
+ openApiGenerator._clearControllers();
914
+ }
754
915
  //#endregion
755
916
  //#region src/types.ts
756
917
  const methodResolve = {
@@ -764,126 +925,6 @@ const methodResolve = {
764
925
  USE: "use"
765
926
  };
766
927
  //#endregion
767
- //#region lib/weakmap.ts
768
- /**
769
- * WeakMap that is iterable.
770
- */
771
- var IterableWeakMap = class IterableWeakMap {
772
- #weakMap = /* @__PURE__ */ new WeakMap();
773
- #refSet = /* @__PURE__ */ new Set();
774
- #finalizationGroup = new FinalizationRegistry(IterableWeakMap.#cleanup);
775
- static #cleanup(heldValue) {
776
- heldValue.set.delete(heldValue.ref);
777
- }
778
- constructor(iterable) {
779
- if (iterable) for (const [key, value] of iterable) this.set(key, value);
780
- }
781
- set(key, value) {
782
- const ref = new WeakRef(key);
783
- this.#weakMap.set(key, {
784
- value,
785
- ref
786
- });
787
- this.#refSet.add(ref);
788
- this.#finalizationGroup.register(key, {
789
- set: this.#refSet,
790
- ref
791
- }, ref);
792
- return this;
793
- }
794
- get(key) {
795
- return this.#weakMap.get(key)?.value;
796
- }
797
- delete(key) {
798
- const entry = this.#weakMap.get(key);
799
- if (!entry) return false;
800
- this.#weakMap.delete(key);
801
- this.#refSet.delete(entry.ref);
802
- this.#finalizationGroup.unregister(entry.ref);
803
- return true;
804
- }
805
- *[Symbol.iterator]() {
806
- for (const ref of this.#refSet) {
807
- const key = ref.deref();
808
- if (!key) continue;
809
- const entry = this.#weakMap.get(key);
810
- if (entry) yield [key, entry.value];
811
- }
812
- }
813
- entries() {
814
- return this[Symbol.iterator]();
815
- }
816
- *keys() {
817
- for (const [key] of this) yield key;
818
- }
819
- *values() {
820
- for (const [, value] of this) yield value;
821
- }
822
- forEach(callback, thisArg) {
823
- for (const [key, value] of this) callback.call(thisArg, value, key, this);
824
- }
825
- };
826
- //#endregion
827
- //#region src/annotation/injectable.ts
828
- const _InjectableRegistry = /* @__PURE__ */ new WeakMap();
829
- const _InjectableDeps = new IterableWeakMap();
830
- /**
831
- * Mark the class as an injectable to be handled by Sapling. The class can now be
832
- * be injected into other classes, as well as allow the class to inject other `@Injectable` classes.
833
- *
834
- * @argument deps - An optional array to define any dependencies that this class may require.
835
- */
836
- function Injectable(deps = []) {
837
- return function(target) {
838
- _InjectableRegistry.set(target, null);
839
- _InjectableDeps.set(target, deps);
840
- };
841
- }
842
- /**
843
- * Resolves and instantiates a class along with all of it's transitive dependencies.
844
- *
845
- * Uses topological sort (Kahn's algorithm) to ensure that the dependency graph is created
846
- * in a correct order.
847
- *
848
- * When `resolve` is first called (usually during controller registration),
849
- * it will compute the dependency graph of all `@Injectable` classes and instantiates
850
- * them in the correct order.
851
- *
852
- * Subsequent calls to dependencies that have already been resolved are cached, so they will
853
- * re-use the created singletons instead of re-instantiation.
854
- */
855
- function _resolve(ctor) {
856
- const inDegree = /* @__PURE__ */ new Map();
857
- const graph = /* @__PURE__ */ new Map();
858
- _InjectableDeps.forEach((deps, node) => {
859
- inDegree.set(node, inDegree.get(node) || 0);
860
- deps.forEach((dep) => {
861
- if (dep === void 0) throw new Error(`There is an @Injectable (${node.name}) which has a dependency that cannot be found. This is likely caused by a circular dependency.`);
862
- inDegree.set(dep, inDegree.get(dep) || 0);
863
- inDegree.set(node, inDegree.get(node) + 1);
864
- if (!graph.has(dep)) graph.set(dep, []);
865
- graph.get(dep).push(node);
866
- });
867
- });
868
- const queue = [];
869
- inDegree.forEach((deg, node) => {
870
- if (deg === 0) queue.push(node);
871
- });
872
- while (queue.length) {
873
- const current = queue.shift();
874
- if (!_InjectableRegistry.get(current)) {
875
- const instance = new current(...(_InjectableDeps.get(current) || []).map((dep) => _InjectableRegistry.get(dep)));
876
- _InjectableRegistry.set(current, instance);
877
- }
878
- (graph.get(current) || []).forEach((neighbor) => {
879
- inDegree.set(neighbor, (inDegree.get(neighbor) ?? 0) - 1);
880
- if (inDegree.get(neighbor) === 0) queue.push(neighbor);
881
- });
882
- }
883
- if (!_InjectableRegistry.get(ctor)) throw new Error("Circular dependency detected or injectable not registered");
884
- return _InjectableRegistry.get(ctor);
885
- }
886
- //#endregion
887
928
  //#region src/annotation/controller.ts
888
929
  const _ControllerRegistry = /* @__PURE__ */ new WeakMap();
889
930
  /**
@@ -1002,14 +1043,6 @@ function MiddlewareClass(...args) {
1002
1043
  return Controller(...args);
1003
1044
  }
1004
1045
  //#endregion
1005
- //#region \0@oxc-project+runtime@0.127.0/helpers/decorate.js
1006
- function __decorate(decorators, target, key, desc) {
1007
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1008
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1009
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1010
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1011
- }
1012
- //#endregion
1013
1046
  //#region src/middleware/default/error/base.ts
1014
1047
  let DefaultBaseErrorMiddleware = class DefaultBaseErrorMiddleware {
1015
1048
  handle(err, _request, _response, _next) {
@@ -1125,6 +1158,19 @@ const DefaultSwaggerMiddleware = {
1125
1158
  Setup
1126
1159
  };
1127
1160
  //#endregion
1161
+ //#region src/middleware/default/health/index.ts
1162
+ let DefaultHealthMiddleware = class DefaultHealthMiddleware {
1163
+ constructor(healthRegistrar) {
1164
+ this.healthRegistrar = healthRegistrar;
1165
+ }
1166
+ async serve(_request, _response, _next) {
1167
+ const up = await this.healthRegistrar.check();
1168
+ return ResponseEntity.ok().body({ up });
1169
+ }
1170
+ };
1171
+ __decorate([GET(_settings.health.path)], DefaultHealthMiddleware.prototype, "serve", null);
1172
+ DefaultHealthMiddleware = __decorate([MiddlewareClass({ deps: [HealthRegistrar] })], DefaultHealthMiddleware);
1173
+ //#endregion
1128
1174
  exports.Controller = Controller;
1129
1175
  exports.ControllerSchema = ControllerSchema;
1130
1176
  exports.DELETE = DELETE;
@@ -1134,6 +1180,12 @@ Object.defineProperty(exports, "DefaultBaseErrorMiddleware", {
1134
1180
  return DefaultBaseErrorMiddleware;
1135
1181
  }
1136
1182
  });
1183
+ Object.defineProperty(exports, "DefaultHealthMiddleware", {
1184
+ enumerable: true,
1185
+ get: function() {
1186
+ return DefaultHealthMiddleware;
1187
+ }
1188
+ });
1137
1189
  Object.defineProperty(exports, "DefaultOpenApiMiddleware", {
1138
1190
  enumerable: true,
1139
1191
  get: function() {
@@ -1155,6 +1207,12 @@ Object.defineProperty(exports, "DefaultResponseStatusErrorMiddleware", {
1155
1207
  exports.DefaultSwaggerMiddleware = DefaultSwaggerMiddleware;
1156
1208
  exports.GET = GET;
1157
1209
  exports.HEAD = HEAD;
1210
+ Object.defineProperty(exports, "HealthRegistrar", {
1211
+ enumerable: true,
1212
+ get: function() {
1213
+ return HealthRegistrar;
1214
+ }
1215
+ });
1158
1216
  exports.Html404ErrorPage = Html404ErrorPage;
1159
1217
  exports.HttpStatus = HttpStatus;
1160
1218
  exports.Injectable = Injectable;
@@ -1179,6 +1237,7 @@ exports._ControllerRegistry = _ControllerRegistry;
1179
1237
  exports._InjectableDeps = _InjectableDeps;
1180
1238
  exports._InjectableRegistry = _InjectableRegistry;
1181
1239
  exports._Route = _Route;
1240
+ exports._clearOpenApiRegistry = _clearOpenApiRegistry;
1182
1241
  exports._getControllerSchema = _getControllerSchema;
1183
1242
  exports._getOrCreateSchemaDefinition = _getOrCreateSchemaDefinition;
1184
1243
  exports._getRouteSchema = _getRouteSchema;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import e, { ErrorRequestHandler, NextFunction, Request, RequestHandler, Response as Response$1, Router } from "express";
1
+ import e, { ErrorRequestHandler, NextFunction, Request as Request$1, RequestHandler, Response as Response$1, Router } from "express";
2
2
 
3
3
  //#region src/html/404.d.ts
4
4
  /**
@@ -26,7 +26,7 @@ type RouteDefinition = {
26
26
  };
27
27
  type Class<T> = new (...args: any[]) => T;
28
28
  type HttpHeaders = Record<string, string>;
29
- type ExpressMiddlewareFn = ($1: Request, $2: Response$1, $3: NextFunction) => void;
29
+ type ExpressMiddlewareFn = ($1: Request$1, $2: Response$1, $3: NextFunction) => void;
30
30
  //#endregion
31
31
  //#region src/annotation/controller.d.ts
32
32
  declare const _ControllerRegistry: WeakMap<Function, Router | ErrorRequestHandler>;
@@ -774,8 +774,13 @@ type OpenAPIMetadata = {
774
774
  description?: string;
775
775
  };
776
776
  declare class OpenAPIGenerator {
777
+ private OPENAPI_VERSION;
777
778
  private controllers;
778
779
  registerController(controllerClass: Function, prefix: string): void;
780
+ /**
781
+ * visible for testing
782
+ */
783
+ _clearControllers(): void;
779
784
  private get metadata();
780
785
  generateSpec(): OpenAPIV3.Document;
781
786
  private toJsonSchema;
@@ -783,11 +788,15 @@ declare class OpenAPIGenerator {
783
788
  declare const openApiGenerator: OpenAPIGenerator;
784
789
  declare function _registerController(controllerClass: Function, prefix: string): void;
785
790
  declare function generateOpenApiSpec(): OpenAPIV3.Document;
791
+ declare function _clearOpenApiRegistry(): void;
786
792
  //#endregion
787
793
  //#region src/helper/sapling.d.ts
788
794
  type Settings = {
789
795
  serialize: (value: any) => string;
790
796
  deserialize: (value: string) => any;
797
+ health: {
798
+ path: string;
799
+ };
791
800
  doc: {
792
801
  openApiPath: string;
793
802
  swaggerPath: string;
@@ -916,7 +925,7 @@ declare class Sapling {
916
925
  * }
917
926
  * ```
918
927
  */
919
- static chainHandlers(this: void, handlers: RequestHandler[], request: Request, response: Response$1, next: NextFunction, index?: number): void;
928
+ static chainHandlers(this: void, handlers: RequestHandler[], request: Request$1, response: Response$1, next: NextFunction, index?: number): void;
920
929
  }
921
930
  //#endregion
922
931
  //#region src/annotation/validator.d.ts
@@ -972,7 +981,7 @@ declare function _getControllerSchema(ctor: Function): ControllerSchemaDefinitio
972
981
  * If the default is not suitable, you may also easily write your own.
973
982
  */
974
983
  declare class DefaultBaseErrorMiddleware {
975
- handle(err: unknown, _request: Request, _response: Response$1, _next: NextFunction): ResponseEntity<{
984
+ handle(err: unknown, _request: Request$1, _response: Response$1, _next: NextFunction): ResponseEntity<{
976
985
  message: string;
977
986
  }>;
978
987
  }
@@ -983,7 +992,7 @@ declare class DefaultBaseErrorMiddleware {
983
992
  * If the default is not suitable, you may also easily write your own.
984
993
  */
985
994
  declare class DefaultParserErrorMiddleware {
986
- handle(err: unknown, _request: Request, _response: Response$1, next: NextFunction): ResponseEntity<{
995
+ handle(err: unknown, _request: Request$1, _response: Response$1, next: NextFunction): ResponseEntity<{
987
996
  message: string;
988
997
  }> | undefined;
989
998
  }
@@ -994,7 +1003,7 @@ declare class DefaultParserErrorMiddleware {
994
1003
  * If the default is not suitable, you may also easily write your own.
995
1004
  */
996
1005
  declare class DefaultResponseStatusErrorMiddleware {
997
- handle(err: unknown, _request: Request, _response: Response$1, next: NextFunction): ResponseEntity<{
1006
+ handle(err: unknown, _request: Request$1, _response: Response$1, next: NextFunction): ResponseEntity<{
998
1007
  message: string;
999
1008
  }> | undefined;
1000
1009
  }
@@ -1017,7 +1026,7 @@ declare class DefaultResponseStatusErrorMiddleware {
1017
1026
  * ```
1018
1027
  */
1019
1028
  declare class DefaultOpenApiMiddleware {
1020
- handle(_request: Request, _response: Response$1, _next: NextFunction): ResponseEntity<OpenAPIV3.Document<{}>>;
1029
+ handle(_request: Request$1, _response: Response$1, _next: NextFunction): ResponseEntity<OpenAPIV3.Document<{}>>;
1021
1030
  }
1022
1031
  //#endregion
1023
1032
  //#region src/middleware/default/swagger/index.d.ts
@@ -1039,7 +1048,7 @@ declare class DefaultOpenApiMiddleware {
1039
1048
  */
1040
1049
  declare class Serve {
1041
1050
  private readonly handlers;
1042
- handle(request: Request, response: Response$1, next: NextFunction): void;
1051
+ handle(request: Request$1, response: Response$1, next: NextFunction): void;
1043
1052
  }
1044
1053
  /**
1045
1054
  * Enable the serving of the Swagger endpoint used to serve the OpenAPI spec generated by Sapling.
@@ -1060,7 +1069,7 @@ declare class Serve {
1060
1069
  declare class Setup {
1061
1070
  private readonly handler;
1062
1071
  constructor();
1063
- handle(request: Request, response: Response$1, next: NextFunction): unknown;
1072
+ handle(request: Request$1, response: Response$1, next: NextFunction): unknown;
1064
1073
  }
1065
1074
  /**
1066
1075
  * Enable the serving of the Swagger endpoint used to serve the OpenAPI spec generated by Sapling.
@@ -1083,4 +1092,24 @@ declare const DefaultSwaggerMiddleware: {
1083
1092
  Setup: typeof Setup;
1084
1093
  };
1085
1094
  //#endregion
1086
- export { Class, Controller, ControllerSchema, ControllerSchemaDefinition, DELETE, DefaultBaseErrorMiddleware, DefaultOpenApiMiddleware, DefaultParserErrorMiddleware, DefaultResponseStatusErrorMiddleware, DefaultSwaggerMiddleware, ExpressMiddlewareFn, ExpressRouterMethodKey, ExpressRouterMethods, GET, HEAD, Html404ErrorPage, HttpHeaders, HttpStatus, Injectable, Middleware, MiddlewareClass, OPTIONS, OpenAPIMetadata, PATCH, POST, PUT, ParserError, ParserErrorLocation, RedirectView, RequestBody, RequestParam, RequestQuery, ResponseBody, ResponseEntity, ResponseEntityBuilder, ResponseSchema, ResponseStatusError, RouteDefinition, RouteSchema, RouteSchemaDefinition, Sapling, ValidatorSchema, _ControllerRegistry, _InjectableDeps, _InjectableRegistry, _Route, _getControllerSchema, _getOrCreateSchemaDefinition, _getRouteSchema, _getRoutes, _getValidatorSchema, _parseOrThrow, _registerController, _resolve, _saveValidatorSchema, _setControllerSchema, _setRouteSchema, _settings, generateOpenApiSpec, methodResolve, openApiGenerator };
1095
+ //#region src/middleware/health/registrar.d.ts
1096
+ type HealthCheck = () => boolean | Promise<boolean>;
1097
+ declare class HealthRegistrar {
1098
+ private _checks;
1099
+ private _sealed;
1100
+ constructor();
1101
+ add(healthCheck: HealthCheck): void;
1102
+ seal(): void;
1103
+ check(): Promise<boolean>;
1104
+ }
1105
+ //#endregion
1106
+ //#region src/middleware/default/health/index.d.ts
1107
+ declare class DefaultHealthMiddleware {
1108
+ private readonly healthRegistrar;
1109
+ constructor(healthRegistrar: HealthRegistrar);
1110
+ serve(_request: Request, _response: Response, _next: NextFunction): Promise<ResponseEntity<{
1111
+ up: boolean;
1112
+ }>>;
1113
+ }
1114
+ //#endregion
1115
+ export { Class, Controller, ControllerSchema, ControllerSchemaDefinition, DELETE, DefaultBaseErrorMiddleware, DefaultHealthMiddleware, DefaultOpenApiMiddleware, DefaultParserErrorMiddleware, DefaultResponseStatusErrorMiddleware, DefaultSwaggerMiddleware, ExpressMiddlewareFn, ExpressRouterMethodKey, ExpressRouterMethods, GET, HEAD, HealthCheck, HealthRegistrar, Html404ErrorPage, HttpHeaders, HttpStatus, Injectable, Middleware, MiddlewareClass, OPTIONS, OpenAPIMetadata, PATCH, POST, PUT, ParserError, ParserErrorLocation, RedirectView, RequestBody, RequestParam, RequestQuery, ResponseBody, ResponseEntity, ResponseEntityBuilder, ResponseSchema, ResponseStatusError, RouteDefinition, RouteSchema, RouteSchemaDefinition, Sapling, ValidatorSchema, _ControllerRegistry, _InjectableDeps, _InjectableRegistry, _Route, _clearOpenApiRegistry, _getControllerSchema, _getOrCreateSchemaDefinition, _getRouteSchema, _getRoutes, _getValidatorSchema, _parseOrThrow, _registerController, _resolve, _saveValidatorSchema, _setControllerSchema, _setRouteSchema, _settings, generateOpenApiSpec, methodResolve, openApiGenerator };
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import e, { ErrorRequestHandler, NextFunction, Request, RequestHandler, Response as Response$1, Router } from "express";
1
+ import e, { ErrorRequestHandler, NextFunction, Request as Request$1, RequestHandler, Response as Response$1, Router } from "express";
2
2
 
3
3
  //#region src/html/404.d.ts
4
4
  /**
@@ -26,7 +26,7 @@ type RouteDefinition = {
26
26
  };
27
27
  type Class<T> = new (...args: any[]) => T;
28
28
  type HttpHeaders = Record<string, string>;
29
- type ExpressMiddlewareFn = ($1: Request, $2: Response$1, $3: NextFunction) => void;
29
+ type ExpressMiddlewareFn = ($1: Request$1, $2: Response$1, $3: NextFunction) => void;
30
30
  //#endregion
31
31
  //#region src/annotation/controller.d.ts
32
32
  declare const _ControllerRegistry: WeakMap<Function, Router | ErrorRequestHandler>;
@@ -774,8 +774,13 @@ type OpenAPIMetadata = {
774
774
  description?: string;
775
775
  };
776
776
  declare class OpenAPIGenerator {
777
+ private OPENAPI_VERSION;
777
778
  private controllers;
778
779
  registerController(controllerClass: Function, prefix: string): void;
780
+ /**
781
+ * visible for testing
782
+ */
783
+ _clearControllers(): void;
779
784
  private get metadata();
780
785
  generateSpec(): OpenAPIV3.Document;
781
786
  private toJsonSchema;
@@ -783,11 +788,15 @@ declare class OpenAPIGenerator {
783
788
  declare const openApiGenerator: OpenAPIGenerator;
784
789
  declare function _registerController(controllerClass: Function, prefix: string): void;
785
790
  declare function generateOpenApiSpec(): OpenAPIV3.Document;
791
+ declare function _clearOpenApiRegistry(): void;
786
792
  //#endregion
787
793
  //#region src/helper/sapling.d.ts
788
794
  type Settings = {
789
795
  serialize: (value: any) => string;
790
796
  deserialize: (value: string) => any;
797
+ health: {
798
+ path: string;
799
+ };
791
800
  doc: {
792
801
  openApiPath: string;
793
802
  swaggerPath: string;
@@ -916,7 +925,7 @@ declare class Sapling {
916
925
  * }
917
926
  * ```
918
927
  */
919
- static chainHandlers(this: void, handlers: RequestHandler[], request: Request, response: Response$1, next: NextFunction, index?: number): void;
928
+ static chainHandlers(this: void, handlers: RequestHandler[], request: Request$1, response: Response$1, next: NextFunction, index?: number): void;
920
929
  }
921
930
  //#endregion
922
931
  //#region src/annotation/validator.d.ts
@@ -972,7 +981,7 @@ declare function _getControllerSchema(ctor: Function): ControllerSchemaDefinitio
972
981
  * If the default is not suitable, you may also easily write your own.
973
982
  */
974
983
  declare class DefaultBaseErrorMiddleware {
975
- handle(err: unknown, _request: Request, _response: Response$1, _next: NextFunction): ResponseEntity<{
984
+ handle(err: unknown, _request: Request$1, _response: Response$1, _next: NextFunction): ResponseEntity<{
976
985
  message: string;
977
986
  }>;
978
987
  }
@@ -983,7 +992,7 @@ declare class DefaultBaseErrorMiddleware {
983
992
  * If the default is not suitable, you may also easily write your own.
984
993
  */
985
994
  declare class DefaultParserErrorMiddleware {
986
- handle(err: unknown, _request: Request, _response: Response$1, next: NextFunction): ResponseEntity<{
995
+ handle(err: unknown, _request: Request$1, _response: Response$1, next: NextFunction): ResponseEntity<{
987
996
  message: string;
988
997
  }> | undefined;
989
998
  }
@@ -994,7 +1003,7 @@ declare class DefaultParserErrorMiddleware {
994
1003
  * If the default is not suitable, you may also easily write your own.
995
1004
  */
996
1005
  declare class DefaultResponseStatusErrorMiddleware {
997
- handle(err: unknown, _request: Request, _response: Response$1, next: NextFunction): ResponseEntity<{
1006
+ handle(err: unknown, _request: Request$1, _response: Response$1, next: NextFunction): ResponseEntity<{
998
1007
  message: string;
999
1008
  }> | undefined;
1000
1009
  }
@@ -1017,7 +1026,7 @@ declare class DefaultResponseStatusErrorMiddleware {
1017
1026
  * ```
1018
1027
  */
1019
1028
  declare class DefaultOpenApiMiddleware {
1020
- handle(_request: Request, _response: Response$1, _next: NextFunction): ResponseEntity<OpenAPIV3.Document<{}>>;
1029
+ handle(_request: Request$1, _response: Response$1, _next: NextFunction): ResponseEntity<OpenAPIV3.Document<{}>>;
1021
1030
  }
1022
1031
  //#endregion
1023
1032
  //#region src/middleware/default/swagger/index.d.ts
@@ -1039,7 +1048,7 @@ declare class DefaultOpenApiMiddleware {
1039
1048
  */
1040
1049
  declare class Serve {
1041
1050
  private readonly handlers;
1042
- handle(request: Request, response: Response$1, next: NextFunction): void;
1051
+ handle(request: Request$1, response: Response$1, next: NextFunction): void;
1043
1052
  }
1044
1053
  /**
1045
1054
  * Enable the serving of the Swagger endpoint used to serve the OpenAPI spec generated by Sapling.
@@ -1060,7 +1069,7 @@ declare class Serve {
1060
1069
  declare class Setup {
1061
1070
  private readonly handler;
1062
1071
  constructor();
1063
- handle(request: Request, response: Response$1, next: NextFunction): unknown;
1072
+ handle(request: Request$1, response: Response$1, next: NextFunction): unknown;
1064
1073
  }
1065
1074
  /**
1066
1075
  * Enable the serving of the Swagger endpoint used to serve the OpenAPI spec generated by Sapling.
@@ -1083,4 +1092,24 @@ declare const DefaultSwaggerMiddleware: {
1083
1092
  Setup: typeof Setup;
1084
1093
  };
1085
1094
  //#endregion
1086
- export { Class, Controller, ControllerSchema, ControllerSchemaDefinition, DELETE, DefaultBaseErrorMiddleware, DefaultOpenApiMiddleware, DefaultParserErrorMiddleware, DefaultResponseStatusErrorMiddleware, DefaultSwaggerMiddleware, ExpressMiddlewareFn, ExpressRouterMethodKey, ExpressRouterMethods, GET, HEAD, Html404ErrorPage, HttpHeaders, HttpStatus, Injectable, Middleware, MiddlewareClass, OPTIONS, OpenAPIMetadata, PATCH, POST, PUT, ParserError, ParserErrorLocation, RedirectView, RequestBody, RequestParam, RequestQuery, ResponseBody, ResponseEntity, ResponseEntityBuilder, ResponseSchema, ResponseStatusError, RouteDefinition, RouteSchema, RouteSchemaDefinition, Sapling, ValidatorSchema, _ControllerRegistry, _InjectableDeps, _InjectableRegistry, _Route, _getControllerSchema, _getOrCreateSchemaDefinition, _getRouteSchema, _getRoutes, _getValidatorSchema, _parseOrThrow, _registerController, _resolve, _saveValidatorSchema, _setControllerSchema, _setRouteSchema, _settings, generateOpenApiSpec, methodResolve, openApiGenerator };
1095
+ //#region src/middleware/health/registrar.d.ts
1096
+ type HealthCheck = () => boolean | Promise<boolean>;
1097
+ declare class HealthRegistrar {
1098
+ private _checks;
1099
+ private _sealed;
1100
+ constructor();
1101
+ add(healthCheck: HealthCheck): void;
1102
+ seal(): void;
1103
+ check(): Promise<boolean>;
1104
+ }
1105
+ //#endregion
1106
+ //#region src/middleware/default/health/index.d.ts
1107
+ declare class DefaultHealthMiddleware {
1108
+ private readonly healthRegistrar;
1109
+ constructor(healthRegistrar: HealthRegistrar);
1110
+ serve(_request: Request, _response: Response, _next: NextFunction): Promise<ResponseEntity<{
1111
+ up: boolean;
1112
+ }>>;
1113
+ }
1114
+ //#endregion
1115
+ export { Class, Controller, ControllerSchema, ControllerSchemaDefinition, DELETE, DefaultBaseErrorMiddleware, DefaultHealthMiddleware, DefaultOpenApiMiddleware, DefaultParserErrorMiddleware, DefaultResponseStatusErrorMiddleware, DefaultSwaggerMiddleware, ExpressMiddlewareFn, ExpressRouterMethodKey, ExpressRouterMethods, GET, HEAD, HealthCheck, HealthRegistrar, Html404ErrorPage, HttpHeaders, HttpStatus, Injectable, Middleware, MiddlewareClass, OPTIONS, OpenAPIMetadata, PATCH, POST, PUT, ParserError, ParserErrorLocation, RedirectView, RequestBody, RequestParam, RequestQuery, ResponseBody, ResponseEntity, ResponseEntityBuilder, ResponseSchema, ResponseStatusError, RouteDefinition, RouteSchema, RouteSchemaDefinition, Sapling, ValidatorSchema, _ControllerRegistry, _InjectableDeps, _InjectableRegistry, _Route, _clearOpenApiRegistry, _getControllerSchema, _getOrCreateSchemaDefinition, _getRouteSchema, _getRoutes, _getValidatorSchema, _parseOrThrow, _registerController, _resolve, _saveValidatorSchema, _setControllerSchema, _setRouteSchema, _settings, generateOpenApiSpec, methodResolve, openApiGenerator };
package/dist/index.mjs CHANGED
@@ -245,10 +245,160 @@ var ParserError = class ParserError extends ResponseStatusError {
245
245
  }
246
246
  };
247
247
  //#endregion
248
+ //#region lib/weakmap.ts
249
+ /**
250
+ * WeakMap that is iterable.
251
+ */
252
+ var IterableWeakMap = class IterableWeakMap {
253
+ #weakMap = /* @__PURE__ */ new WeakMap();
254
+ #refSet = /* @__PURE__ */ new Set();
255
+ #finalizationGroup = new FinalizationRegistry(IterableWeakMap.#cleanup);
256
+ static #cleanup(heldValue) {
257
+ heldValue.set.delete(heldValue.ref);
258
+ }
259
+ constructor(iterable) {
260
+ if (iterable) for (const [key, value] of iterable) this.set(key, value);
261
+ }
262
+ set(key, value) {
263
+ const ref = new WeakRef(key);
264
+ this.#weakMap.set(key, {
265
+ value,
266
+ ref
267
+ });
268
+ this.#refSet.add(ref);
269
+ this.#finalizationGroup.register(key, {
270
+ set: this.#refSet,
271
+ ref
272
+ }, ref);
273
+ return this;
274
+ }
275
+ get(key) {
276
+ return this.#weakMap.get(key)?.value;
277
+ }
278
+ delete(key) {
279
+ const entry = this.#weakMap.get(key);
280
+ if (!entry) return false;
281
+ this.#weakMap.delete(key);
282
+ this.#refSet.delete(entry.ref);
283
+ this.#finalizationGroup.unregister(entry.ref);
284
+ return true;
285
+ }
286
+ *[Symbol.iterator]() {
287
+ for (const ref of this.#refSet) {
288
+ const key = ref.deref();
289
+ if (!key) continue;
290
+ const entry = this.#weakMap.get(key);
291
+ if (entry) yield [key, entry.value];
292
+ }
293
+ }
294
+ entries() {
295
+ return this[Symbol.iterator]();
296
+ }
297
+ *keys() {
298
+ for (const [key] of this) yield key;
299
+ }
300
+ *values() {
301
+ for (const [, value] of this) yield value;
302
+ }
303
+ forEach(callback, thisArg) {
304
+ for (const [key, value] of this) callback.call(thisArg, value, key, this);
305
+ }
306
+ };
307
+ //#endregion
308
+ //#region src/annotation/injectable.ts
309
+ const _InjectableRegistry = /* @__PURE__ */ new WeakMap();
310
+ const _InjectableDeps = new IterableWeakMap();
311
+ /**
312
+ * Mark the class as an injectable to be handled by Sapling. The class can now be
313
+ * be injected into other classes, as well as allow the class to inject other `@Injectable` classes.
314
+ *
315
+ * @argument deps - An optional array to define any dependencies that this class may require.
316
+ */
317
+ function Injectable(deps = []) {
318
+ return function(target) {
319
+ _InjectableRegistry.set(target, null);
320
+ _InjectableDeps.set(target, deps);
321
+ };
322
+ }
323
+ /**
324
+ * Resolves and instantiates a class along with all of it's transitive dependencies.
325
+ *
326
+ * Uses topological sort (Kahn's algorithm) to ensure that the dependency graph is created
327
+ * in a correct order.
328
+ *
329
+ * When `resolve` is first called (usually during controller registration),
330
+ * it will compute the dependency graph of all `@Injectable` classes and instantiates
331
+ * them in the correct order.
332
+ *
333
+ * Subsequent calls to dependencies that have already been resolved are cached, so they will
334
+ * re-use the created singletons instead of re-instantiation.
335
+ */
336
+ function _resolve(ctor) {
337
+ const inDegree = /* @__PURE__ */ new Map();
338
+ const graph = /* @__PURE__ */ new Map();
339
+ _InjectableDeps.forEach((deps, node) => {
340
+ inDegree.set(node, inDegree.get(node) || 0);
341
+ deps.forEach((dep) => {
342
+ if (dep === void 0) throw new Error(`There is an @Injectable (${node.name}) which has a dependency that cannot be found. This is likely caused by a circular dependency.`);
343
+ inDegree.set(dep, inDegree.get(dep) || 0);
344
+ inDegree.set(node, inDegree.get(node) + 1);
345
+ if (!graph.has(dep)) graph.set(dep, []);
346
+ graph.get(dep).push(node);
347
+ });
348
+ });
349
+ const queue = [];
350
+ inDegree.forEach((deg, node) => {
351
+ if (deg === 0) queue.push(node);
352
+ });
353
+ while (queue.length) {
354
+ const current = queue.shift();
355
+ if (!_InjectableRegistry.get(current)) {
356
+ const instance = new current(...(_InjectableDeps.get(current) || []).map((dep) => _InjectableRegistry.get(dep)));
357
+ _InjectableRegistry.set(current, instance);
358
+ }
359
+ (graph.get(current) || []).forEach((neighbor) => {
360
+ inDegree.set(neighbor, (inDegree.get(neighbor) ?? 0) - 1);
361
+ if (inDegree.get(neighbor) === 0) queue.push(neighbor);
362
+ });
363
+ }
364
+ if (!_InjectableRegistry.get(ctor)) throw new Error("Circular dependency detected or injectable not registered");
365
+ return _InjectableRegistry.get(ctor);
366
+ }
367
+ //#endregion
368
+ //#region \0@oxc-project+runtime@0.127.0/helpers/decorate.js
369
+ function __decorate(decorators, target, key, desc) {
370
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
371
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
372
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
373
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
374
+ }
375
+ //#endregion
376
+ //#region src/middleware/health/registrar.ts
377
+ let HealthRegistrar = class HealthRegistrar {
378
+ _checks;
379
+ _sealed;
380
+ constructor() {
381
+ this._checks = [];
382
+ this._sealed = false;
383
+ }
384
+ add(healthCheck) {
385
+ this._checks.push(healthCheck);
386
+ }
387
+ seal() {
388
+ this._sealed = true;
389
+ }
390
+ async check() {
391
+ if (!this._sealed) return false;
392
+ return (await Promise.all(this._checks.map((c) => c()))).every((c) => c === true);
393
+ }
394
+ };
395
+ HealthRegistrar = __decorate([Injectable()], HealthRegistrar);
396
+ //#endregion
248
397
  //#region src/helper/sapling.ts
249
398
  const _settings = {
250
399
  serialize: JSON.stringify,
251
400
  deserialize: JSON.parse,
401
+ health: { path: "/up" },
252
402
  doc: {
253
403
  openApiPath: "/openapi.json",
254
404
  swaggerPath: "/swagger.html",
@@ -324,6 +474,7 @@ var Sapling = class Sapling {
324
474
  static registerApp(app) {
325
475
  app.use(e.text({ type: "application/json" }));
326
476
  app.use(Sapling.json());
477
+ _InjectableRegistry.get(HealthRegistrar)?.seal();
327
478
  }
328
479
  /**
329
480
  * Serialize a value into a JSON string.
@@ -604,6 +755,7 @@ function _getValidatorSchema(ctor, fnName) {
604
755
  //#endregion
605
756
  //#region src/helper/openapi.ts
606
757
  var OpenAPIGenerator = class {
758
+ OPENAPI_VERSION = "3.0.0";
607
759
  controllers = /* @__PURE__ */ new Set();
608
760
  registerController(controllerClass, prefix) {
609
761
  this.controllers.add({
@@ -611,6 +763,12 @@ var OpenAPIGenerator = class {
611
763
  prefix
612
764
  });
613
765
  }
766
+ /**
767
+ * visible for testing
768
+ */
769
+ _clearControllers() {
770
+ this.controllers.clear();
771
+ }
614
772
  get metadata() {
615
773
  return _settings.doc.metadata;
616
774
  }
@@ -699,7 +857,7 @@ var OpenAPIGenerator = class {
699
857
  }
700
858
  }
701
859
  return {
702
- openapi: "3.0.0",
860
+ openapi: this.OPENAPI_VERSION,
703
861
  info: {
704
862
  title: metadata.title,
705
863
  version: metadata.version,
@@ -726,6 +884,9 @@ function _registerController(controllerClass, prefix) {
726
884
  function generateOpenApiSpec() {
727
885
  return openApiGenerator.generateSpec();
728
886
  }
887
+ function _clearOpenApiRegistry() {
888
+ openApiGenerator._clearControllers();
889
+ }
729
890
  //#endregion
730
891
  //#region src/types.ts
731
892
  const methodResolve = {
@@ -739,126 +900,6 @@ const methodResolve = {
739
900
  USE: "use"
740
901
  };
741
902
  //#endregion
742
- //#region lib/weakmap.ts
743
- /**
744
- * WeakMap that is iterable.
745
- */
746
- var IterableWeakMap = class IterableWeakMap {
747
- #weakMap = /* @__PURE__ */ new WeakMap();
748
- #refSet = /* @__PURE__ */ new Set();
749
- #finalizationGroup = new FinalizationRegistry(IterableWeakMap.#cleanup);
750
- static #cleanup(heldValue) {
751
- heldValue.set.delete(heldValue.ref);
752
- }
753
- constructor(iterable) {
754
- if (iterable) for (const [key, value] of iterable) this.set(key, value);
755
- }
756
- set(key, value) {
757
- const ref = new WeakRef(key);
758
- this.#weakMap.set(key, {
759
- value,
760
- ref
761
- });
762
- this.#refSet.add(ref);
763
- this.#finalizationGroup.register(key, {
764
- set: this.#refSet,
765
- ref
766
- }, ref);
767
- return this;
768
- }
769
- get(key) {
770
- return this.#weakMap.get(key)?.value;
771
- }
772
- delete(key) {
773
- const entry = this.#weakMap.get(key);
774
- if (!entry) return false;
775
- this.#weakMap.delete(key);
776
- this.#refSet.delete(entry.ref);
777
- this.#finalizationGroup.unregister(entry.ref);
778
- return true;
779
- }
780
- *[Symbol.iterator]() {
781
- for (const ref of this.#refSet) {
782
- const key = ref.deref();
783
- if (!key) continue;
784
- const entry = this.#weakMap.get(key);
785
- if (entry) yield [key, entry.value];
786
- }
787
- }
788
- entries() {
789
- return this[Symbol.iterator]();
790
- }
791
- *keys() {
792
- for (const [key] of this) yield key;
793
- }
794
- *values() {
795
- for (const [, value] of this) yield value;
796
- }
797
- forEach(callback, thisArg) {
798
- for (const [key, value] of this) callback.call(thisArg, value, key, this);
799
- }
800
- };
801
- //#endregion
802
- //#region src/annotation/injectable.ts
803
- const _InjectableRegistry = /* @__PURE__ */ new WeakMap();
804
- const _InjectableDeps = new IterableWeakMap();
805
- /**
806
- * Mark the class as an injectable to be handled by Sapling. The class can now be
807
- * be injected into other classes, as well as allow the class to inject other `@Injectable` classes.
808
- *
809
- * @argument deps - An optional array to define any dependencies that this class may require.
810
- */
811
- function Injectable(deps = []) {
812
- return function(target) {
813
- _InjectableRegistry.set(target, null);
814
- _InjectableDeps.set(target, deps);
815
- };
816
- }
817
- /**
818
- * Resolves and instantiates a class along with all of it's transitive dependencies.
819
- *
820
- * Uses topological sort (Kahn's algorithm) to ensure that the dependency graph is created
821
- * in a correct order.
822
- *
823
- * When `resolve` is first called (usually during controller registration),
824
- * it will compute the dependency graph of all `@Injectable` classes and instantiates
825
- * them in the correct order.
826
- *
827
- * Subsequent calls to dependencies that have already been resolved are cached, so they will
828
- * re-use the created singletons instead of re-instantiation.
829
- */
830
- function _resolve(ctor) {
831
- const inDegree = /* @__PURE__ */ new Map();
832
- const graph = /* @__PURE__ */ new Map();
833
- _InjectableDeps.forEach((deps, node) => {
834
- inDegree.set(node, inDegree.get(node) || 0);
835
- deps.forEach((dep) => {
836
- if (dep === void 0) throw new Error(`There is an @Injectable (${node.name}) which has a dependency that cannot be found. This is likely caused by a circular dependency.`);
837
- inDegree.set(dep, inDegree.get(dep) || 0);
838
- inDegree.set(node, inDegree.get(node) + 1);
839
- if (!graph.has(dep)) graph.set(dep, []);
840
- graph.get(dep).push(node);
841
- });
842
- });
843
- const queue = [];
844
- inDegree.forEach((deg, node) => {
845
- if (deg === 0) queue.push(node);
846
- });
847
- while (queue.length) {
848
- const current = queue.shift();
849
- if (!_InjectableRegistry.get(current)) {
850
- const instance = new current(...(_InjectableDeps.get(current) || []).map((dep) => _InjectableRegistry.get(dep)));
851
- _InjectableRegistry.set(current, instance);
852
- }
853
- (graph.get(current) || []).forEach((neighbor) => {
854
- inDegree.set(neighbor, (inDegree.get(neighbor) ?? 0) - 1);
855
- if (inDegree.get(neighbor) === 0) queue.push(neighbor);
856
- });
857
- }
858
- if (!_InjectableRegistry.get(ctor)) throw new Error("Circular dependency detected or injectable not registered");
859
- return _InjectableRegistry.get(ctor);
860
- }
861
- //#endregion
862
903
  //#region src/annotation/controller.ts
863
904
  const _ControllerRegistry = /* @__PURE__ */ new WeakMap();
864
905
  /**
@@ -977,14 +1018,6 @@ function MiddlewareClass(...args) {
977
1018
  return Controller(...args);
978
1019
  }
979
1020
  //#endregion
980
- //#region \0@oxc-project+runtime@0.127.0/helpers/decorate.js
981
- function __decorate(decorators, target, key, desc) {
982
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
983
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
984
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
985
- return c > 3 && r && Object.defineProperty(target, key, r), r;
986
- }
987
- //#endregion
988
1021
  //#region src/middleware/default/error/base.ts
989
1022
  let DefaultBaseErrorMiddleware = class DefaultBaseErrorMiddleware {
990
1023
  handle(err, _request, _response, _next) {
@@ -1100,4 +1133,17 @@ const DefaultSwaggerMiddleware = {
1100
1133
  Setup
1101
1134
  };
1102
1135
  //#endregion
1103
- 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, _registerController, _resolve, _saveValidatorSchema, _setControllerSchema, _setRouteSchema, _settings, generateOpenApiSpec, methodResolve, openApiGenerator };
1136
+ //#region src/middleware/default/health/index.ts
1137
+ let DefaultHealthMiddleware = class DefaultHealthMiddleware {
1138
+ constructor(healthRegistrar) {
1139
+ this.healthRegistrar = healthRegistrar;
1140
+ }
1141
+ async serve(_request, _response, _next) {
1142
+ const up = await this.healthRegistrar.check();
1143
+ return ResponseEntity.ok().body({ up });
1144
+ }
1145
+ };
1146
+ __decorate([GET(_settings.health.path)], DefaultHealthMiddleware.prototype, "serve", null);
1147
+ DefaultHealthMiddleware = __decorate([MiddlewareClass({ deps: [HealthRegistrar] })], DefaultHealthMiddleware);
1148
+ //#endregion
1149
+ export { Controller, ControllerSchema, DELETE, DefaultBaseErrorMiddleware, DefaultHealthMiddleware, DefaultOpenApiMiddleware, DefaultParserErrorMiddleware, DefaultResponseStatusErrorMiddleware, DefaultSwaggerMiddleware, GET, HEAD, HealthRegistrar, Html404ErrorPage, HttpStatus, Injectable, Middleware, MiddlewareClass, OPTIONS, PATCH, POST, PUT, ParserError, RedirectView, RequestBody, RequestParam, RequestQuery, ResponseBody, ResponseEntity, ResponseEntityBuilder, ResponseStatusError, RouteSchema, Sapling, _ControllerRegistry, _InjectableDeps, _InjectableRegistry, _Route, _clearOpenApiRegistry, _getControllerSchema, _getOrCreateSchemaDefinition, _getRouteSchema, _getRoutes, _getValidatorSchema, _parseOrThrow, _registerController, _resolve, _saveValidatorSchema, _setControllerSchema, _setRouteSchema, _settings, generateOpenApiSpec, methodResolve, openApiGenerator };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tahminator/sapling",
3
- "version": "2.0.5-beta.e0403942",
3
+ "version": "2.1.0-beta.0e8a97e8",
4
4
  "author": "Tahmid Ahmed",
5
5
  "description": "A library to help you write cleaner Express.js code",
6
6
  "repository": {