@tsed/terminus 7.0.0-beta.2 → 7.0.0-beta.20

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.
Files changed (37) hide show
  1. package/jest.config.js +14 -0
  2. package/lib/cjs/TerminusModule.js +103 -41
  3. package/lib/cjs/TerminusModule.js.map +1 -1
  4. package/lib/cjs/decorators/health.js +4 -6
  5. package/lib/cjs/decorators/health.js.map +1 -1
  6. package/lib/cjs/decorators/shutdown.js +12 -10
  7. package/lib/cjs/decorators/shutdown.js.map +1 -1
  8. package/lib/cjs/index.js +8 -4
  9. package/lib/cjs/index.js.map +1 -1
  10. package/lib/cjs/interfaces/TerminusSettings.js.map +1 -1
  11. package/lib/cjs/interfaces/interfaces.js +3 -0
  12. package/lib/cjs/interfaces/interfaces.js.map +1 -0
  13. package/lib/cjs/package.json +3 -0
  14. package/lib/esm/TerminusModule.js +94 -32
  15. package/lib/esm/TerminusModule.js.map +1 -1
  16. package/lib/esm/decorators/health.js +4 -6
  17. package/lib/esm/decorators/health.js.map +1 -1
  18. package/lib/esm/decorators/shutdown.js +10 -9
  19. package/lib/esm/decorators/shutdown.js.map +1 -1
  20. package/lib/esm/index.js +8 -4
  21. package/lib/esm/index.js.map +1 -1
  22. package/lib/esm/interfaces/TerminusSettings.js.map +1 -1
  23. package/lib/esm/interfaces/interfaces.js +2 -0
  24. package/lib/esm/interfaces/interfaces.js.map +1 -0
  25. package/lib/esm/package.json +3 -0
  26. package/lib/types/TerminusModule.d.ts +24 -4
  27. package/lib/types/decorators/shutdown.d.ts +5 -0
  28. package/lib/types/index.d.ts +6 -2
  29. package/lib/types/interfaces/TerminusSettings.d.ts +3 -1
  30. package/lib/types/interfaces/{index.d.ts → interfaces.d.ts} +0 -1
  31. package/package.json +34 -15
  32. package/readme.md +96 -53
  33. package/tsconfig.compile.esm.json +1 -12
  34. package/lib/cjs/interfaces/index.js +0 -5
  35. package/lib/cjs/interfaces/index.js.map +0 -1
  36. package/lib/esm/interfaces/index.js +0 -2
  37. package/lib/esm/interfaces/index.js.map +0 -1
package/jest.config.js ADDED
@@ -0,0 +1,14 @@
1
+ // For a detailed explanation regarding each configuration property, visit:
2
+ // https://jestjs.io/docs/en/configuration.html
3
+
4
+ module.exports = {
5
+ ...require("@tsed/jest-config")(__dirname, "terminus"),
6
+ coverageThreshold: {
7
+ global: {
8
+ statements: 100,
9
+ branches: 100,
10
+ functions: 100,
11
+ lines: 100
12
+ }
13
+ }
14
+ };
@@ -4,23 +4,61 @@ exports.TerminusModule = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const terminus_1 = require("@godaddy/terminus");
6
6
  const di_1 = require("@tsed/di");
7
- const https_1 = (0, tslib_1.__importDefault)(require("https"));
8
- const http_1 = (0, tslib_1.__importDefault)(require("http"));
7
+ const schema_1 = require("@tsed/schema");
8
+ const http_1 = tslib_1.__importDefault(require("http"));
9
+ const https_1 = tslib_1.__importDefault(require("https"));
9
10
  let TerminusModule = class TerminusModule {
11
+ settings;
12
+ basePath;
13
+ injector;
14
+ httpServer;
15
+ httpsServer;
10
16
  $onInit() {
11
17
  this.mount();
12
18
  }
13
- mount() {
14
- const { terminus } = this.configuration;
15
- const terminusConfig = {
16
- logger: this.injector.logger,
19
+ getConfiguration() {
20
+ const { path, ...props } = this.settings;
21
+ return {
22
+ logger: (event, error) => this.injector.logger.info({
23
+ event: event.toUpperCase(),
24
+ error_message: error.message
25
+ }),
17
26
  healthChecks: this.getHealths(),
18
- onSignal: this.execShutdown("onSignal"),
19
- onShutdown: this.execShutdown("onShutdown"),
20
- beforeShutdown: this.execShutdown("beforeShutdown"),
21
- onSendFailureDuringShutdown: this.execShutdown("onSendFailureDuringShutdown"),
22
- ...terminus
27
+ onSignal: this.createEmitter("$onSignal"),
28
+ onShutdown: this.createEmitter("$onShutdown"),
29
+ beforeShutdown: this.createEmitter("$beforeShutdown"),
30
+ onSendFailureDuringShutdown: this.createEmitter("$onSendFailureDuringShutdown"),
31
+ ...props
23
32
  };
33
+ }
34
+ async $logRoutes(routes) {
35
+ return [
36
+ ...routes,
37
+ {
38
+ toJSON: () => {
39
+ return {
40
+ method: "GET",
41
+ name: `TerminusModule.dispatch`,
42
+ url: this.basePath
43
+ };
44
+ }
45
+ },
46
+ ...this.getAll("health").map(({ provider, propertyKey, options }) => {
47
+ const path = this.getPath(provider, options.name);
48
+ return {
49
+ toJSON() {
50
+ return {
51
+ method: "GET",
52
+ name: `${provider.className}.${propertyKey}`,
53
+ url: path
54
+ };
55
+ }
56
+ };
57
+ })
58
+ ];
59
+ }
60
+ mount() {
61
+ const terminusConfig = this.getConfiguration();
24
62
  if (this.httpServer) {
25
63
  (0, terminus_1.createTerminus)(this.httpServer, terminusConfig);
26
64
  }
@@ -28,50 +66,74 @@ let TerminusModule = class TerminusModule {
28
66
  (0, terminus_1.createTerminus)(this.httpsServer, terminusConfig);
29
67
  }
30
68
  }
31
- getProviders(name) {
32
- return this.injector.getProviders().filter((provider) => {
33
- return provider.store.get(name);
69
+ getAll(name) {
70
+ return this.injector.getProviders().flatMap((provider) => {
71
+ const metadata = provider.store.get(`terminus:${name}`);
72
+ if (metadata) {
73
+ return Object.entries(metadata).map(([propertyKey, options]) => {
74
+ return {
75
+ provider,
76
+ propertyKey,
77
+ options
78
+ };
79
+ });
80
+ }
81
+ return [];
34
82
  });
35
83
  }
36
- getStore(name) {
37
- return this.injector
38
- .getProviders()
39
- .map((provider) => provider.store.get(name))
40
- .filter((x) => !!x)
41
- .flat();
42
- }
43
84
  getHealths() {
44
- const healths = {};
45
- this.getProviders("terminus").forEach((provider) => {
46
- Object.keys(provider.store.get("terminus")).forEach((name) => {
47
- healths[`${provider.path}${name}`] = provider.store.get("terminus")[name];
48
- });
49
- });
85
+ const subHealths = this.getAll("health").reduce((healths, { provider, propertyKey, options: { name } }) => {
86
+ const instance = this.injector.get(provider.token);
87
+ const callback = async (...args) => {
88
+ const result = await instance[propertyKey](...args);
89
+ return { [name]: result };
90
+ };
91
+ let path = this.getPath(provider, name);
92
+ return {
93
+ ...healths,
94
+ [path]: callback
95
+ };
96
+ }, {});
97
+ const healths = {
98
+ ...subHealths,
99
+ [this.basePath]: (state) => {
100
+ const promises = Object.entries(subHealths).map(([path, callback]) => callback(state));
101
+ return Promise.all(promises);
102
+ }
103
+ };
50
104
  return healths;
51
105
  }
52
- execShutdown(name) {
53
- return async () => {
54
- this.getStore(name).forEach((func) => func());
106
+ getPath(provider, name) {
107
+ let path = (0, schema_1.concatPath)(provider.path, name);
108
+ return path.includes("health") ? path : (0, schema_1.concatPath)(path, this.basePath);
109
+ }
110
+ createEmitter(name) {
111
+ return async (...args) => {
112
+ return this.injector.emit(`$${name}`, ...args);
55
113
  };
56
114
  }
57
115
  };
58
- (0, tslib_1.__decorate)([
59
- (0, di_1.Configuration)(),
60
- (0, tslib_1.__metadata)("design:type", Object)
61
- ], TerminusModule.prototype, "configuration", void 0);
62
- (0, tslib_1.__decorate)([
116
+ tslib_1.__decorate([
117
+ (0, di_1.Constant)("terminus", {}),
118
+ tslib_1.__metadata("design:type", Object)
119
+ ], TerminusModule.prototype, "settings", void 0);
120
+ tslib_1.__decorate([
121
+ (0, di_1.Constant)("terminus.path", "/health"),
122
+ tslib_1.__metadata("design:type", String)
123
+ ], TerminusModule.prototype, "basePath", void 0);
124
+ tslib_1.__decorate([
63
125
  (0, di_1.Inject)(),
64
- (0, tslib_1.__metadata)("design:type", di_1.InjectorService)
126
+ tslib_1.__metadata("design:type", di_1.InjectorService)
65
127
  ], TerminusModule.prototype, "injector", void 0);
66
- (0, tslib_1.__decorate)([
128
+ tslib_1.__decorate([
67
129
  (0, di_1.Inject)(http_1.default.Server),
68
- (0, tslib_1.__metadata)("design:type", Object)
130
+ tslib_1.__metadata("design:type", Object)
69
131
  ], TerminusModule.prototype, "httpServer", void 0);
70
- (0, tslib_1.__decorate)([
132
+ tslib_1.__decorate([
71
133
  (0, di_1.Inject)(https_1.default.Server),
72
- (0, tslib_1.__metadata)("design:type", Object)
134
+ tslib_1.__metadata("design:type", Object)
73
135
  ], TerminusModule.prototype, "httpsServer", void 0);
74
- TerminusModule = (0, tslib_1.__decorate)([
136
+ TerminusModule = tslib_1.__decorate([
75
137
  (0, di_1.Module)()
76
138
  ], TerminusModule);
77
139
  exports.TerminusModule = TerminusModule;
@@ -1 +1 @@
1
- {"version":3,"file":"TerminusModule.js","sourceRoot":"","sources":["../../src/TerminusModule.ts"],"names":[],"mappings":";;;;AAAA,gDAAiD;AACjD,iCAAgF;AAChF,+DAA0B;AAC1B,6DAAwB;AAGxB,IAAa,cAAc,GAA3B,MAAa,cAAc;IAalB,OAAO;QACZ,IAAI,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;IAEO,KAAK;QACX,MAAM,EAAC,QAAQ,EAAC,GAAG,IAAI,CAAC,aAAa,CAAC;QACtC,MAAM,cAAc,GAAG;YACrB,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAa;YACnC,YAAY,EAAE,IAAI,CAAC,UAAU,EAAE;YAC/B,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC;YACvC,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC;YAC3C,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC;YACnD,2BAA2B,EAAE,IAAI,CAAC,YAAY,CAAC,6BAA6B,CAAC;YAC7E,GAAG,QAAQ;SACZ,CAAC;QAEF,IAAI,IAAI,CAAC,UAAU,EAAE;YACnB,IAAA,yBAAc,EAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;SACjD;QAED,IAAI,IAAI,CAAC,WAAW,EAAE;YACpB,IAAA,yBAAc,EAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;SAClD;IACH,CAAC;IAEO,YAAY,CAAC,IAAY;QAC/B,OAAO,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE;YACtD,OAAO,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,QAAQ,CAAC,IAAY;QAC3B,OAAO,IAAI,CAAC,QAAQ;aACjB,YAAY,EAAE;aACd,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;aAC3C,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;aAClB,IAAI,EAAE,CAAC;IACZ,CAAC;IAEO,UAAU;QAChB,MAAM,OAAO,GAAsC,EAAE,CAAC;QAEtD,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;YACjD,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;gBAC3D,OAAO,CAAC,GAAG,QAAQ,CAAC,IAAI,GAAG,IAAI,EAAE,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC;YAC5E,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,YAAY,CAAC,IAAY;QAC/B,OAAO,KAAK,IAAI,EAAE;YAChB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;QAChD,CAAC,CAAC;IACJ,CAAC;CACF,CAAA;AAnEC;IADC,IAAA,kBAAa,GAAE;;qDACqB;AAGrC;IADC,IAAA,WAAM,GAAE;2CACS,oBAAe;gDAAC;AAGlC;IADC,IAAA,WAAM,EAAC,cAAI,CAAC,MAAM,CAAC;;kDACmB;AAGvC;IADC,IAAA,WAAM,EAAC,eAAK,CAAC,MAAM,CAAC;;mDACoB;AAX9B,cAAc;IAD1B,IAAA,WAAM,GAAE;GACI,cAAc,CAqE1B;AArEY,wCAAc","sourcesContent":["import {createTerminus} from \"@godaddy/terminus\";\nimport {Configuration, Inject, InjectorService, Module, OnInit} from \"@tsed/di\";\nimport Https from \"https\";\nimport Http from \"http\";\n\n@Module()\nexport class TerminusModule implements OnInit {\n @Configuration()\n private configuration: Configuration;\n\n @Inject()\n private injector: InjectorService;\n\n @Inject(Http.Server)\n private httpServer: Http.Server | null;\n\n @Inject(Https.Server)\n private httpsServer: Https.Server | null;\n\n public $onInit() {\n this.mount();\n }\n\n private mount() {\n const {terminus} = this.configuration;\n const terminusConfig = {\n logger: this.injector.logger as any,\n healthChecks: this.getHealths(),\n onSignal: this.execShutdown(\"onSignal\"),\n onShutdown: this.execShutdown(\"onShutdown\"),\n beforeShutdown: this.execShutdown(\"beforeShutdown\"),\n onSendFailureDuringShutdown: this.execShutdown(\"onSendFailureDuringShutdown\"),\n ...terminus\n };\n\n if (this.httpServer) {\n createTerminus(this.httpServer, terminusConfig);\n }\n\n if (this.httpsServer) {\n createTerminus(this.httpsServer, terminusConfig);\n }\n }\n\n private getProviders(name: string) {\n return this.injector.getProviders().filter((provider) => {\n return provider.store.get(name);\n });\n }\n\n private getStore(name: string) {\n return this.injector\n .getProviders()\n .map((provider) => provider.store.get(name))\n .filter((x) => !!x)\n .flat();\n }\n\n private getHealths() {\n const healths: {[k: string]: () => Promise<any>} = {};\n\n this.getProviders(\"terminus\").forEach((provider) => {\n Object.keys(provider.store.get(\"terminus\")).forEach((name) => {\n healths[`${provider.path}${name}`] = provider.store.get(\"terminus\")[name];\n });\n });\n\n return healths;\n }\n\n private execShutdown(name: string) {\n return async () => {\n this.getStore(name).forEach((func) => func());\n };\n }\n}\n"]}
1
+ {"version":3,"file":"TerminusModule.js","sourceRoot":"","sources":["../../src/TerminusModule.ts"],"names":[],"mappings":"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","sourcesContent":["import {createTerminus} from \"@godaddy/terminus\";\nimport {Constant, Inject, InjectorService, Module, OnInit, Provider} from \"@tsed/di\";\nimport {concatPath} from \"@tsed/schema\";\nimport Http from \"http\";\nimport Https from \"https\";\nimport {TerminusSettings} from \"./interfaces/TerminusSettings\";\n\n@Module()\nexport class TerminusModule implements OnInit {\n @Constant(\"terminus\", {})\n private settings: TerminusSettings;\n\n @Constant(\"terminus.path\", \"/health\")\n private basePath: string;\n\n @Inject()\n private injector: InjectorService;\n\n @Inject(Http.Server)\n private httpServer: Http.Server | null;\n\n @Inject(Https.Server)\n private httpsServer: Https.Server | null;\n\n public $onInit() {\n this.mount();\n }\n\n getConfiguration() {\n const {path, ...props} = this.settings;\n\n return {\n logger: (event: string, error: any) =>\n this.injector.logger.info({\n event: event.toUpperCase(),\n error_message: error.message\n }),\n healthChecks: this.getHealths(),\n onSignal: this.createEmitter(\"$onSignal\"),\n onShutdown: this.createEmitter(\"$onShutdown\"),\n beforeShutdown: this.createEmitter(\"$beforeShutdown\"),\n onSendFailureDuringShutdown: this.createEmitter(\"$onSendFailureDuringShutdown\"),\n ...props\n };\n }\n\n async $logRoutes(routes: any[]): Promise<any[]> {\n return [\n ...routes,\n {\n toJSON: () => {\n return {\n method: \"GET\",\n name: `TerminusModule.dispatch`,\n url: this.basePath\n };\n }\n },\n ...this.getAll<{name: string}>(\"health\").map(({provider, propertyKey, options}) => {\n const path = this.getPath(provider, options.name);\n\n return {\n toJSON() {\n return {\n method: \"GET\",\n name: `${provider.className}.${propertyKey}`,\n url: path\n };\n }\n } as any;\n })\n ];\n }\n\n private mount() {\n const terminusConfig = this.getConfiguration();\n\n if (this.httpServer) {\n createTerminus(this.httpServer, terminusConfig);\n }\n\n if (this.httpsServer) {\n createTerminus(this.httpsServer, terminusConfig);\n }\n }\n\n private getAll<Opts = any>(\n name: string\n ): {\n provider: Provider;\n propertyKey: string;\n options: Opts;\n }[] {\n return this.injector.getProviders().flatMap((provider) => {\n const metadata = provider.store.get(`terminus:${name}`);\n\n if (metadata) {\n return Object.entries(metadata).map(([propertyKey, options]: [string, Opts]) => {\n return {\n provider,\n propertyKey,\n options\n };\n });\n }\n return [];\n });\n }\n\n private getHealths() {\n const subHealths = this.getAll<{name: string}>(\"health\").reduce((healths, {provider, propertyKey, options: {name}}) => {\n const instance = this.injector.get<any>(provider.token)!;\n const callback = async (...args: any[]) => {\n const result = await instance[propertyKey](...args);\n\n return {[name]: result};\n };\n\n let path = this.getPath(provider, name);\n\n return {\n ...healths,\n [path]: callback\n };\n }, {} as Record<string, (state: any) => Promise<any>>);\n\n const healths: Record<string, any> = {\n ...subHealths,\n [this.basePath]: (state: any) => {\n const promises = Object.entries(subHealths).map(([path, callback]) => callback(state));\n\n return Promise.all(promises);\n }\n };\n\n return healths;\n }\n\n private getPath(provider: Provider<any>, name: string) {\n let path = concatPath(provider.path, name);\n return path.includes(\"health\") ? path : concatPath(path, this.basePath);\n }\n\n private createEmitter(name: string) {\n return async (...args: any[]) => {\n return this.injector.emit(`$${name}`, ...args);\n };\n }\n}\n"]}
@@ -22,12 +22,10 @@ const core_1 = require("@tsed/core");
22
22
  * @terminus
23
23
  */
24
24
  function Health(name) {
25
- return (target, propertyKey, descriptor) => {
26
- if (descriptor.value) {
27
- core_1.Store.from(target).merge("terminus", {
28
- [name]: descriptor.value
29
- });
30
- }
25
+ return (target, propertyKey) => {
26
+ core_1.Store.from(target).merge(`terminus:health`, {
27
+ [propertyKey]: { name }
28
+ });
31
29
  };
32
30
  }
33
31
  exports.Health = Health;
@@ -1 +1 @@
1
- {"version":3,"file":"health.js","sourceRoot":"","sources":["../../../src/decorators/health.ts"],"names":[],"mappings":";;;AAAA,qCAAiC;AAEjC;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAgB,MAAM,CAAC,IAAY;IACjC,OAAO,CAAW,MAAc,EAAE,WAAmB,EAAE,UAA6C,EAAE,EAAE;QACtG,IAAI,UAAU,CAAC,KAAK,EAAE;YACpB,YAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,UAAU,EAAE;gBACnC,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,KAAK;aACzB,CAAC,CAAC;SACJ;IACH,CAAC,CAAC;AACJ,CAAC;AARD,wBAQC","sourcesContent":["import {Store} from \"@tsed/core\";\n\n/**\n * Create a readiness / liveness checks.\n *\n * ```ts\n * import { Health } from \"@tsed/terminus\";\n *\n * @Controller(\"/mongo\")\n * class MongoCtrl {\n * @Health(\"/health\")\n * health() {\n * // Here check the mongo health\n * return Promise.resolve();\n * }\n * }\n *\n * @param name\n * @decorator\n * @terminus\n */\nexport function Health(name: string): MethodDecorator {\n return <Function>(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<Function>) => {\n if (descriptor.value) {\n Store.from(target).merge(\"terminus\", {\n [name]: descriptor.value\n });\n }\n };\n}\n"]}
1
+ {"version":3,"file":"health.js","sourceRoot":"","sources":["../../../src/decorators/health.ts"],"names":[],"mappings":";;;AAAA,qCAAiC;AAEjC;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAgB,MAAM,CAAC,IAAY;IACjC,OAAO,CAAW,MAAc,EAAE,WAAmB,EAAE,EAAE;QACvD,YAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,iBAAiB,EAAE;YAC1C,CAAC,WAAW,CAAC,EAAE,EAAC,IAAI,EAAC;SACtB,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAND,wBAMC","sourcesContent":["import {Store} from \"@tsed/core\";\n\n/**\n * Create a readiness / liveness checks.\n *\n * ```ts\n * import { Health } from \"@tsed/terminus\";\n *\n * @Controller(\"/mongo\")\n * class MongoCtrl {\n * @Health(\"/health\")\n * health() {\n * // Here check the mongo health\n * return Promise.resolve();\n * }\n * }\n *\n * @param name\n * @decorator\n * @terminus\n */\nexport function Health(name: string): MethodDecorator {\n return <Function>(target: Object, propertyKey: string) => {\n Store.from(target).merge(`terminus:health`, {\n [propertyKey]: {name}\n });\n };\n}\n"]}
@@ -1,21 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.OnSendFailureDuringShutdown = exports.OnShutdown = exports.OnSignal = exports.BeforeShutdown = void 0;
4
- const core_1 = require("@tsed/core");
5
- function register(name) {
6
- return (target, propertyKey, descriptor) => {
7
- if (descriptor.value) {
8
- const store = core_1.Store.from(target);
9
- const values = store.get(name) || [];
10
- store.merge(name, [...values, descriptor.value]);
11
- }
3
+ exports.OnSendFailureDuringShutdown = exports.OnShutdown = exports.OnSignal = exports.BeforeShutdown = exports.register = void 0;
4
+ function register(event) {
5
+ return (target, propertyKey, description) => {
6
+ Object.defineProperty(target, `$${event}`, {
7
+ value: description.value
8
+ });
12
9
  };
13
10
  }
11
+ exports.register = register;
14
12
  /**
15
13
  * Listen the `beforeShutdown` terminus event.
16
14
  *
17
15
  * @decorator
18
16
  * @terminus
17
+ * @deprecated Use $BeforeShutdown hook
19
18
  */
20
19
  function BeforeShutdown() {
21
20
  return register("beforeShutdown");
@@ -26,6 +25,7 @@ exports.BeforeShutdown = BeforeShutdown;
26
25
  *
27
26
  * @decorator
28
27
  * @terminus
28
+ * @deprecated Use $onSignal hook
29
29
  */
30
30
  function OnSignal() {
31
31
  return register("onSignal");
@@ -36,6 +36,7 @@ exports.OnSignal = OnSignal;
36
36
  *
37
37
  * @decorator
38
38
  * @terminus
39
+ * @deprecated Use $onShutdown hook
39
40
  */
40
41
  function OnShutdown() {
41
42
  return register("onShutdown");
@@ -46,9 +47,10 @@ exports.OnShutdown = OnShutdown;
46
47
  *
47
48
  * @decorator
48
49
  * @terminus
50
+ * @deprecated Use $onSendFailureDuringShutdown hook
49
51
  */
50
52
  function OnSendFailureDuringShutdown() {
51
- return register("onSendFailureDuringShutdown");
53
+ return register("OnSendFailureDuringShutdown");
52
54
  }
53
55
  exports.OnSendFailureDuringShutdown = OnSendFailureDuringShutdown;
54
56
  //# sourceMappingURL=shutdown.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../../src/decorators/shutdown.ts"],"names":[],"mappings":";;;AAAA,qCAAiC;AAEjC,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,CAAW,MAAc,EAAE,WAAmB,EAAE,UAA6C,EAAE,EAAE;QACtG,IAAI,UAAU,CAAC,KAAK,EAAE;YACpB,MAAM,KAAK,GAAG,YAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACjC,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAErC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;SAClD;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,cAAc;IAC5B,OAAO,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AACpC,CAAC;AAFD,wCAEC;AAED;;;;;GAKG;AACH,SAAgB,QAAQ;IACtB,OAAO,QAAQ,CAAC,UAAU,CAAC,CAAC;AAC9B,CAAC;AAFD,4BAEC;AAED;;;;;GAKG;AACH,SAAgB,UAAU;IACxB,OAAO,QAAQ,CAAC,YAAY,CAAC,CAAC;AAChC,CAAC;AAFD,gCAEC;AAED;;;;;GAKG;AACH,SAAgB,2BAA2B;IACzC,OAAO,QAAQ,CAAC,6BAA6B,CAAC,CAAC;AACjD,CAAC;AAFD,kEAEC","sourcesContent":["import {Store} from \"@tsed/core\";\n\nfunction register(name: string) {\n return <Function>(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<Function>) => {\n if (descriptor.value) {\n const store = Store.from(target);\n const values = store.get(name) || [];\n\n store.merge(name, [...values, descriptor.value]);\n }\n };\n}\n\n/**\n * Listen the `beforeShutdown` terminus event.\n *\n * @decorator\n * @terminus\n */\nexport function BeforeShutdown(): MethodDecorator {\n return register(\"beforeShutdown\");\n}\n\n/**\n * Listen the `onSignal` terminus event.\n *\n * @decorator\n * @terminus\n */\nexport function OnSignal(): MethodDecorator {\n return register(\"onSignal\");\n}\n\n/**\n * Listen the `onShutdown` terminus event.\n *\n * @decorator\n * @terminus\n */\nexport function OnShutdown(): MethodDecorator {\n return register(\"onShutdown\");\n}\n\n/**\n * Listen the `onSendFailureDuringShutdown` terminus event.\n *\n * @decorator\n * @terminus\n */\nexport function OnSendFailureDuringShutdown(): MethodDecorator {\n return register(\"onSendFailureDuringShutdown\");\n}\n"]}
1
+ {"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../../src/decorators/shutdown.ts"],"names":[],"mappings":";;;AAAA,SAAgB,QAAQ,CAAC,KAAa;IACpC,OAAO,CAAW,MAAc,EAAE,WAAmB,EAAE,WAA+B,EAAE,EAAE;QACxF,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,KAAK,EAAE,EAAE;YACzC,KAAK,EAAE,WAAW,CAAC,KAAK;SACzB,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAND,4BAMC;AAED;;;;;;GAMG;AACH,SAAgB,cAAc;IAC5B,OAAO,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AACpC,CAAC;AAFD,wCAEC;AAED;;;;;;GAMG;AACH,SAAgB,QAAQ;IACtB,OAAO,QAAQ,CAAC,UAAU,CAAC,CAAC;AAC9B,CAAC;AAFD,4BAEC;AAED;;;;;;GAMG;AACH,SAAgB,UAAU;IACxB,OAAO,QAAQ,CAAC,YAAY,CAAC,CAAC;AAChC,CAAC;AAFD,gCAEC;AAED;;;;;;GAMG;AACH,SAAgB,2BAA2B;IACzC,OAAO,QAAQ,CAAC,6BAA6B,CAAC,CAAC;AACjD,CAAC;AAFD,kEAEC","sourcesContent":["export function register(event: string) {\n return <Function>(target: Object, propertyKey: string, description: PropertyDescriptor) => {\n Object.defineProperty(target, `$${event}`, {\n value: description.value\n });\n };\n}\n\n/**\n * Listen the `beforeShutdown` terminus event.\n *\n * @decorator\n * @terminus\n * @deprecated Use $BeforeShutdown hook\n */\nexport function BeforeShutdown(): MethodDecorator {\n return register(\"beforeShutdown\");\n}\n\n/**\n * Listen the `onSignal` terminus event.\n *\n * @decorator\n * @terminus\n * @deprecated Use $onSignal hook\n */\nexport function OnSignal(): MethodDecorator {\n return register(\"onSignal\");\n}\n\n/**\n * Listen the `onShutdown` terminus event.\n *\n * @decorator\n * @terminus\n * @deprecated Use $onShutdown hook\n */\nexport function OnShutdown(): MethodDecorator {\n return register(\"onShutdown\");\n}\n\n/**\n * Listen the `onSendFailureDuringShutdown` terminus event.\n *\n * @decorator\n * @terminus\n * @deprecated Use $onSendFailureDuringShutdown hook\n */\nexport function OnSendFailureDuringShutdown(): MethodDecorator {\n return register(\"OnSendFailureDuringShutdown\");\n}\n"]}
package/lib/cjs/index.js CHANGED
@@ -1,8 +1,12 @@
1
1
  "use strict";
2
+ /**
3
+ * @file Automatically generated by barrelsby.
4
+ */
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  const tslib_1 = require("tslib");
4
- (0, tslib_1.__exportStar)(require("./decorators/health"), exports);
5
- (0, tslib_1.__exportStar)(require("./decorators/shutdown"), exports);
6
- (0, tslib_1.__exportStar)(require("./interfaces"), exports);
7
- (0, tslib_1.__exportStar)(require("./TerminusModule"), exports);
7
+ tslib_1.__exportStar(require("./TerminusModule"), exports);
8
+ tslib_1.__exportStar(require("./decorators/health"), exports);
9
+ tslib_1.__exportStar(require("./decorators/shutdown"), exports);
10
+ tslib_1.__exportStar(require("./interfaces/TerminusSettings"), exports);
11
+ tslib_1.__exportStar(require("./interfaces/interfaces"), exports);
8
12
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,mEAAoC;AACpC,qEAAsC;AACtC,4DAA6B;AAC7B,gEAAiC","sourcesContent":["export * from \"./decorators/health\";\nexport * from \"./decorators/shutdown\";\nexport * from \"./interfaces\";\nexport * from \"./TerminusModule\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,2DAAiC;AACjC,8DAAoC;AACpC,gEAAsC;AACtC,wEAA8C;AAC9C,kEAAwC","sourcesContent":["/**\n * @file Automatically generated by barrelsby.\n */\n\nexport * from \"./TerminusModule\";\nexport * from \"./decorators/health\";\nexport * from \"./decorators/shutdown\";\nexport * from \"./interfaces/TerminusSettings\";\nexport * from \"./interfaces/interfaces\";\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"TerminusSettings.js","sourceRoot":"","sources":["../../../src/interfaces/TerminusSettings.ts"],"names":[],"mappings":"","sourcesContent":["import {TerminusOptions} from \"@godaddy/terminus\";\n\nexport type TerminusSettings = Omit<\n TerminusOptions,\n \"healthChecks\" | \"onSignal\" | \"onSendFailureDuringShutdown\" | \"onShutdown\" | \"beforeShutdown\" | \"onSigterm\"\n>;\n"]}
1
+ {"version":3,"file":"TerminusSettings.js","sourceRoot":"","sources":["../../../src/interfaces/TerminusSettings.ts"],"names":[],"mappings":"","sourcesContent":["import {TerminusOptions} from \"@godaddy/terminus\";\n\nexport type TerminusSettings = Omit<\n TerminusOptions,\n \"healthChecks\" | \"onSignal\" | \"onSendFailureDuringShutdown\" | \"onShutdown\" | \"beforeShutdown\" | \"onSigterm\"\n> & {path?: string};\n"]}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=interfaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../../src/interfaces/interfaces.ts"],"names":[],"mappings":"","sourcesContent":["import {TerminusSettings} from \"./TerminusSettings\";\n\ndeclare global {\n namespace TsED {\n interface Configuration {\n terminus: TerminusSettings;\n }\n }\n}\n"]}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -1,23 +1,61 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
2
  import { createTerminus } from "@godaddy/terminus";
3
- import { Configuration, Inject, InjectorService, Module } from "@tsed/di";
4
- import Https from "https";
3
+ import { Constant, Inject, InjectorService, Module } from "@tsed/di";
4
+ import { concatPath } from "@tsed/schema";
5
5
  import Http from "http";
6
+ import Https from "https";
6
7
  let TerminusModule = class TerminusModule {
8
+ settings;
9
+ basePath;
10
+ injector;
11
+ httpServer;
12
+ httpsServer;
7
13
  $onInit() {
8
14
  this.mount();
9
15
  }
10
- mount() {
11
- const { terminus } = this.configuration;
12
- const terminusConfig = {
13
- logger: this.injector.logger,
16
+ getConfiguration() {
17
+ const { path, ...props } = this.settings;
18
+ return {
19
+ logger: (event, error) => this.injector.logger.info({
20
+ event: event.toUpperCase(),
21
+ error_message: error.message
22
+ }),
14
23
  healthChecks: this.getHealths(),
15
- onSignal: this.execShutdown("onSignal"),
16
- onShutdown: this.execShutdown("onShutdown"),
17
- beforeShutdown: this.execShutdown("beforeShutdown"),
18
- onSendFailureDuringShutdown: this.execShutdown("onSendFailureDuringShutdown"),
19
- ...terminus
24
+ onSignal: this.createEmitter("$onSignal"),
25
+ onShutdown: this.createEmitter("$onShutdown"),
26
+ beforeShutdown: this.createEmitter("$beforeShutdown"),
27
+ onSendFailureDuringShutdown: this.createEmitter("$onSendFailureDuringShutdown"),
28
+ ...props
20
29
  };
30
+ }
31
+ async $logRoutes(routes) {
32
+ return [
33
+ ...routes,
34
+ {
35
+ toJSON: () => {
36
+ return {
37
+ method: "GET",
38
+ name: `TerminusModule.dispatch`,
39
+ url: this.basePath
40
+ };
41
+ }
42
+ },
43
+ ...this.getAll("health").map(({ provider, propertyKey, options }) => {
44
+ const path = this.getPath(provider, options.name);
45
+ return {
46
+ toJSON() {
47
+ return {
48
+ method: "GET",
49
+ name: `${provider.className}.${propertyKey}`,
50
+ url: path
51
+ };
52
+ }
53
+ };
54
+ })
55
+ ];
56
+ }
57
+ mount() {
58
+ const terminusConfig = this.getConfiguration();
21
59
  if (this.httpServer) {
22
60
  createTerminus(this.httpServer, terminusConfig);
23
61
  }
@@ -25,37 +63,61 @@ let TerminusModule = class TerminusModule {
25
63
  createTerminus(this.httpsServer, terminusConfig);
26
64
  }
27
65
  }
28
- getProviders(name) {
29
- return this.injector.getProviders().filter((provider) => {
30
- return provider.store.get(name);
66
+ getAll(name) {
67
+ return this.injector.getProviders().flatMap((provider) => {
68
+ const metadata = provider.store.get(`terminus:${name}`);
69
+ if (metadata) {
70
+ return Object.entries(metadata).map(([propertyKey, options]) => {
71
+ return {
72
+ provider,
73
+ propertyKey,
74
+ options
75
+ };
76
+ });
77
+ }
78
+ return [];
31
79
  });
32
80
  }
33
- getStore(name) {
34
- return this.injector
35
- .getProviders()
36
- .map((provider) => provider.store.get(name))
37
- .filter((x) => !!x)
38
- .flat();
39
- }
40
81
  getHealths() {
41
- const healths = {};
42
- this.getProviders("terminus").forEach((provider) => {
43
- Object.keys(provider.store.get("terminus")).forEach((name) => {
44
- healths[`${provider.path}${name}`] = provider.store.get("terminus")[name];
45
- });
46
- });
82
+ const subHealths = this.getAll("health").reduce((healths, { provider, propertyKey, options: { name } }) => {
83
+ const instance = this.injector.get(provider.token);
84
+ const callback = async (...args) => {
85
+ const result = await instance[propertyKey](...args);
86
+ return { [name]: result };
87
+ };
88
+ let path = this.getPath(provider, name);
89
+ return {
90
+ ...healths,
91
+ [path]: callback
92
+ };
93
+ }, {});
94
+ const healths = {
95
+ ...subHealths,
96
+ [this.basePath]: (state) => {
97
+ const promises = Object.entries(subHealths).map(([path, callback]) => callback(state));
98
+ return Promise.all(promises);
99
+ }
100
+ };
47
101
  return healths;
48
102
  }
49
- execShutdown(name) {
50
- return async () => {
51
- this.getStore(name).forEach((func) => func());
103
+ getPath(provider, name) {
104
+ let path = concatPath(provider.path, name);
105
+ return path.includes("health") ? path : concatPath(path, this.basePath);
106
+ }
107
+ createEmitter(name) {
108
+ return async (...args) => {
109
+ return this.injector.emit(`$${name}`, ...args);
52
110
  };
53
111
  }
54
112
  };
55
113
  __decorate([
56
- Configuration(),
114
+ Constant("terminus", {}),
57
115
  __metadata("design:type", Object)
58
- ], TerminusModule.prototype, "configuration", void 0);
116
+ ], TerminusModule.prototype, "settings", void 0);
117
+ __decorate([
118
+ Constant("terminus.path", "/health"),
119
+ __metadata("design:type", String)
120
+ ], TerminusModule.prototype, "basePath", void 0);
59
121
  __decorate([
60
122
  Inject(),
61
123
  __metadata("design:type", InjectorService)
@@ -1 +1 @@
1
- {"version":3,"file":"TerminusModule.js","sourceRoot":"","sources":["../../src/TerminusModule.ts"],"names":[],"mappings":"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","sourcesContent":["import {createTerminus} from \"@godaddy/terminus\";\nimport {Configuration, Inject, InjectorService, Module, OnInit} from \"@tsed/di\";\nimport Https from \"https\";\nimport Http from \"http\";\n\n@Module()\nexport class TerminusModule implements OnInit {\n @Configuration()\n private configuration: Configuration;\n\n @Inject()\n private injector: InjectorService;\n\n @Inject(Http.Server)\n private httpServer: Http.Server | null;\n\n @Inject(Https.Server)\n private httpsServer: Https.Server | null;\n\n public $onInit() {\n this.mount();\n }\n\n private mount() {\n const {terminus} = this.configuration;\n const terminusConfig = {\n logger: this.injector.logger as any,\n healthChecks: this.getHealths(),\n onSignal: this.execShutdown(\"onSignal\"),\n onShutdown: this.execShutdown(\"onShutdown\"),\n beforeShutdown: this.execShutdown(\"beforeShutdown\"),\n onSendFailureDuringShutdown: this.execShutdown(\"onSendFailureDuringShutdown\"),\n ...terminus\n };\n\n if (this.httpServer) {\n createTerminus(this.httpServer, terminusConfig);\n }\n\n if (this.httpsServer) {\n createTerminus(this.httpsServer, terminusConfig);\n }\n }\n\n private getProviders(name: string) {\n return this.injector.getProviders().filter((provider) => {\n return provider.store.get(name);\n });\n }\n\n private getStore(name: string) {\n return this.injector\n .getProviders()\n .map((provider) => provider.store.get(name))\n .filter((x) => !!x)\n .flat();\n }\n\n private getHealths() {\n const healths: {[k: string]: () => Promise<any>} = {};\n\n this.getProviders(\"terminus\").forEach((provider) => {\n Object.keys(provider.store.get(\"terminus\")).forEach((name) => {\n healths[`${provider.path}${name}`] = provider.store.get(\"terminus\")[name];\n });\n });\n\n return healths;\n }\n\n private execShutdown(name: string) {\n return async () => {\n this.getStore(name).forEach((func) => func());\n };\n }\n}\n"]}
1
+ {"version":3,"file":"TerminusModule.js","sourceRoot":"","sources":["../../src/TerminusModule.ts"],"names":[],"mappings":"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","sourcesContent":["import {createTerminus} from \"@godaddy/terminus\";\nimport {Constant, Inject, InjectorService, Module, OnInit, Provider} from \"@tsed/di\";\nimport {concatPath} from \"@tsed/schema\";\nimport Http from \"http\";\nimport Https from \"https\";\nimport {TerminusSettings} from \"./interfaces/TerminusSettings\";\n\n@Module()\nexport class TerminusModule implements OnInit {\n @Constant(\"terminus\", {})\n private settings: TerminusSettings;\n\n @Constant(\"terminus.path\", \"/health\")\n private basePath: string;\n\n @Inject()\n private injector: InjectorService;\n\n @Inject(Http.Server)\n private httpServer: Http.Server | null;\n\n @Inject(Https.Server)\n private httpsServer: Https.Server | null;\n\n public $onInit() {\n this.mount();\n }\n\n getConfiguration() {\n const {path, ...props} = this.settings;\n\n return {\n logger: (event: string, error: any) =>\n this.injector.logger.info({\n event: event.toUpperCase(),\n error_message: error.message\n }),\n healthChecks: this.getHealths(),\n onSignal: this.createEmitter(\"$onSignal\"),\n onShutdown: this.createEmitter(\"$onShutdown\"),\n beforeShutdown: this.createEmitter(\"$beforeShutdown\"),\n onSendFailureDuringShutdown: this.createEmitter(\"$onSendFailureDuringShutdown\"),\n ...props\n };\n }\n\n async $logRoutes(routes: any[]): Promise<any[]> {\n return [\n ...routes,\n {\n toJSON: () => {\n return {\n method: \"GET\",\n name: `TerminusModule.dispatch`,\n url: this.basePath\n };\n }\n },\n ...this.getAll<{name: string}>(\"health\").map(({provider, propertyKey, options}) => {\n const path = this.getPath(provider, options.name);\n\n return {\n toJSON() {\n return {\n method: \"GET\",\n name: `${provider.className}.${propertyKey}`,\n url: path\n };\n }\n } as any;\n })\n ];\n }\n\n private mount() {\n const terminusConfig = this.getConfiguration();\n\n if (this.httpServer) {\n createTerminus(this.httpServer, terminusConfig);\n }\n\n if (this.httpsServer) {\n createTerminus(this.httpsServer, terminusConfig);\n }\n }\n\n private getAll<Opts = any>(\n name: string\n ): {\n provider: Provider;\n propertyKey: string;\n options: Opts;\n }[] {\n return this.injector.getProviders().flatMap((provider) => {\n const metadata = provider.store.get(`terminus:${name}`);\n\n if (metadata) {\n return Object.entries(metadata).map(([propertyKey, options]: [string, Opts]) => {\n return {\n provider,\n propertyKey,\n options\n };\n });\n }\n return [];\n });\n }\n\n private getHealths() {\n const subHealths = this.getAll<{name: string}>(\"health\").reduce((healths, {provider, propertyKey, options: {name}}) => {\n const instance = this.injector.get<any>(provider.token)!;\n const callback = async (...args: any[]) => {\n const result = await instance[propertyKey](...args);\n\n return {[name]: result};\n };\n\n let path = this.getPath(provider, name);\n\n return {\n ...healths,\n [path]: callback\n };\n }, {} as Record<string, (state: any) => Promise<any>>);\n\n const healths: Record<string, any> = {\n ...subHealths,\n [this.basePath]: (state: any) => {\n const promises = Object.entries(subHealths).map(([path, callback]) => callback(state));\n\n return Promise.all(promises);\n }\n };\n\n return healths;\n }\n\n private getPath(provider: Provider<any>, name: string) {\n let path = concatPath(provider.path, name);\n return path.includes(\"health\") ? path : concatPath(path, this.basePath);\n }\n\n private createEmitter(name: string) {\n return async (...args: any[]) => {\n return this.injector.emit(`$${name}`, ...args);\n };\n }\n}\n"]}
@@ -19,12 +19,10 @@ import { Store } from "@tsed/core";
19
19
  * @terminus
20
20
  */
21
21
  export function Health(name) {
22
- return (target, propertyKey, descriptor) => {
23
- if (descriptor.value) {
24
- Store.from(target).merge("terminus", {
25
- [name]: descriptor.value
26
- });
27
- }
22
+ return (target, propertyKey) => {
23
+ Store.from(target).merge(`terminus:health`, {
24
+ [propertyKey]: { name }
25
+ });
28
26
  };
29
27
  }
30
28
  //# sourceMappingURL=health.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"health.js","sourceRoot":"","sources":["../../../src/decorators/health.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,YAAY,CAAC;AAEjC;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,OAAO,CAAW,MAAc,EAAE,WAAmB,EAAE,UAA6C,EAAE,EAAE;QACtG,IAAI,UAAU,CAAC,KAAK,EAAE;YACpB,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,UAAU,EAAE;gBACnC,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,KAAK;aACzB,CAAC,CAAC;SACJ;IACH,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import {Store} from \"@tsed/core\";\n\n/**\n * Create a readiness / liveness checks.\n *\n * ```ts\n * import { Health } from \"@tsed/terminus\";\n *\n * @Controller(\"/mongo\")\n * class MongoCtrl {\n * @Health(\"/health\")\n * health() {\n * // Here check the mongo health\n * return Promise.resolve();\n * }\n * }\n *\n * @param name\n * @decorator\n * @terminus\n */\nexport function Health(name: string): MethodDecorator {\n return <Function>(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<Function>) => {\n if (descriptor.value) {\n Store.from(target).merge(\"terminus\", {\n [name]: descriptor.value\n });\n }\n };\n}\n"]}
1
+ {"version":3,"file":"health.js","sourceRoot":"","sources":["../../../src/decorators/health.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,YAAY,CAAC;AAEjC;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,OAAO,CAAW,MAAc,EAAE,WAAmB,EAAE,EAAE;QACvD,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,iBAAiB,EAAE;YAC1C,CAAC,WAAW,CAAC,EAAE,EAAC,IAAI,EAAC;SACtB,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import {Store} from \"@tsed/core\";\n\n/**\n * Create a readiness / liveness checks.\n *\n * ```ts\n * import { Health } from \"@tsed/terminus\";\n *\n * @Controller(\"/mongo\")\n * class MongoCtrl {\n * @Health(\"/health\")\n * health() {\n * // Here check the mongo health\n * return Promise.resolve();\n * }\n * }\n *\n * @param name\n * @decorator\n * @terminus\n */\nexport function Health(name: string): MethodDecorator {\n return <Function>(target: Object, propertyKey: string) => {\n Store.from(target).merge(`terminus:health`, {\n [propertyKey]: {name}\n });\n };\n}\n"]}
@@ -1,11 +1,8 @@
1
- import { Store } from "@tsed/core";
2
- function register(name) {
3
- return (target, propertyKey, descriptor) => {
4
- if (descriptor.value) {
5
- const store = Store.from(target);
6
- const values = store.get(name) || [];
7
- store.merge(name, [...values, descriptor.value]);
8
- }
1
+ export function register(event) {
2
+ return (target, propertyKey, description) => {
3
+ Object.defineProperty(target, `$${event}`, {
4
+ value: description.value
5
+ });
9
6
  };
10
7
  }
11
8
  /**
@@ -13,6 +10,7 @@ function register(name) {
13
10
  *
14
11
  * @decorator
15
12
  * @terminus
13
+ * @deprecated Use $BeforeShutdown hook
16
14
  */
17
15
  export function BeforeShutdown() {
18
16
  return register("beforeShutdown");
@@ -22,6 +20,7 @@ export function BeforeShutdown() {
22
20
  *
23
21
  * @decorator
24
22
  * @terminus
23
+ * @deprecated Use $onSignal hook
25
24
  */
26
25
  export function OnSignal() {
27
26
  return register("onSignal");
@@ -31,6 +30,7 @@ export function OnSignal() {
31
30
  *
32
31
  * @decorator
33
32
  * @terminus
33
+ * @deprecated Use $onShutdown hook
34
34
  */
35
35
  export function OnShutdown() {
36
36
  return register("onShutdown");
@@ -40,8 +40,9 @@ export function OnShutdown() {
40
40
  *
41
41
  * @decorator
42
42
  * @terminus
43
+ * @deprecated Use $onSendFailureDuringShutdown hook
43
44
  */
44
45
  export function OnSendFailureDuringShutdown() {
45
- return register("onSendFailureDuringShutdown");
46
+ return register("OnSendFailureDuringShutdown");
46
47
  }
47
48
  //# sourceMappingURL=shutdown.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../../src/decorators/shutdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,YAAY,CAAC;AAEjC,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,CAAW,MAAc,EAAE,WAAmB,EAAE,UAA6C,EAAE,EAAE;QACtG,IAAI,UAAU,CAAC,KAAK,EAAE;YACpB,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACjC,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAErC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;SAClD;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ;IACtB,OAAO,QAAQ,CAAC,UAAU,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU;IACxB,OAAO,QAAQ,CAAC,YAAY,CAAC,CAAC;AAChC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,2BAA2B;IACzC,OAAO,QAAQ,CAAC,6BAA6B,CAAC,CAAC;AACjD,CAAC","sourcesContent":["import {Store} from \"@tsed/core\";\n\nfunction register(name: string) {\n return <Function>(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<Function>) => {\n if (descriptor.value) {\n const store = Store.from(target);\n const values = store.get(name) || [];\n\n store.merge(name, [...values, descriptor.value]);\n }\n };\n}\n\n/**\n * Listen the `beforeShutdown` terminus event.\n *\n * @decorator\n * @terminus\n */\nexport function BeforeShutdown(): MethodDecorator {\n return register(\"beforeShutdown\");\n}\n\n/**\n * Listen the `onSignal` terminus event.\n *\n * @decorator\n * @terminus\n */\nexport function OnSignal(): MethodDecorator {\n return register(\"onSignal\");\n}\n\n/**\n * Listen the `onShutdown` terminus event.\n *\n * @decorator\n * @terminus\n */\nexport function OnShutdown(): MethodDecorator {\n return register(\"onShutdown\");\n}\n\n/**\n * Listen the `onSendFailureDuringShutdown` terminus event.\n *\n * @decorator\n * @terminus\n */\nexport function OnSendFailureDuringShutdown(): MethodDecorator {\n return register(\"onSendFailureDuringShutdown\");\n}\n"]}
1
+ {"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../../src/decorators/shutdown.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,QAAQ,CAAC,KAAa;IACpC,OAAO,CAAW,MAAc,EAAE,WAAmB,EAAE,WAA+B,EAAE,EAAE;QACxF,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,KAAK,EAAE,EAAE;YACzC,KAAK,EAAE,WAAW,CAAC,KAAK;SACzB,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ;IACtB,OAAO,QAAQ,CAAC,UAAU,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU;IACxB,OAAO,QAAQ,CAAC,YAAY,CAAC,CAAC;AAChC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,2BAA2B;IACzC,OAAO,QAAQ,CAAC,6BAA6B,CAAC,CAAC;AACjD,CAAC","sourcesContent":["export function register(event: string) {\n return <Function>(target: Object, propertyKey: string, description: PropertyDescriptor) => {\n Object.defineProperty(target, `$${event}`, {\n value: description.value\n });\n };\n}\n\n/**\n * Listen the `beforeShutdown` terminus event.\n *\n * @decorator\n * @terminus\n * @deprecated Use $BeforeShutdown hook\n */\nexport function BeforeShutdown(): MethodDecorator {\n return register(\"beforeShutdown\");\n}\n\n/**\n * Listen the `onSignal` terminus event.\n *\n * @decorator\n * @terminus\n * @deprecated Use $onSignal hook\n */\nexport function OnSignal(): MethodDecorator {\n return register(\"onSignal\");\n}\n\n/**\n * Listen the `onShutdown` terminus event.\n *\n * @decorator\n * @terminus\n * @deprecated Use $onShutdown hook\n */\nexport function OnShutdown(): MethodDecorator {\n return register(\"onShutdown\");\n}\n\n/**\n * Listen the `onSendFailureDuringShutdown` terminus event.\n *\n * @decorator\n * @terminus\n * @deprecated Use $onSendFailureDuringShutdown hook\n */\nexport function OnSendFailureDuringShutdown(): MethodDecorator {\n return register(\"OnSendFailureDuringShutdown\");\n}\n"]}
package/lib/esm/index.js CHANGED
@@ -1,5 +1,9 @@
1
- export * from "./decorators/health";
2
- export * from "./decorators/shutdown";
3
- export * from "./interfaces";
4
- export * from "./TerminusModule";
1
+ /**
2
+ * @file Automatically generated by barrelsby.
3
+ */
4
+ export * from "./TerminusModule.js";
5
+ export * from "./decorators/health.js";
6
+ export * from "./decorators/shutdown.js";
7
+ export * from "./interfaces/TerminusSettings.js";
8
+ export * from "./interfaces/interfaces.js";
5
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC","sourcesContent":["export * from \"./decorators/health\";\nexport * from \"./decorators/shutdown\";\nexport * from \"./interfaces\";\nexport * from \"./TerminusModule\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yBAAyB,CAAC","sourcesContent":["/**\n * @file Automatically generated by barrelsby.\n */\n\nexport * from \"./TerminusModule\";\nexport * from \"./decorators/health\";\nexport * from \"./decorators/shutdown\";\nexport * from \"./interfaces/TerminusSettings\";\nexport * from \"./interfaces/interfaces\";\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"TerminusSettings.js","sourceRoot":"","sources":["../../../src/interfaces/TerminusSettings.ts"],"names":[],"mappings":"","sourcesContent":["import {TerminusOptions} from \"@godaddy/terminus\";\n\nexport type TerminusSettings = Omit<\n TerminusOptions,\n \"healthChecks\" | \"onSignal\" | \"onSendFailureDuringShutdown\" | \"onShutdown\" | \"beforeShutdown\" | \"onSigterm\"\n>;\n"]}
1
+ {"version":3,"file":"TerminusSettings.js","sourceRoot":"","sources":["../../../src/interfaces/TerminusSettings.ts"],"names":[],"mappings":"","sourcesContent":["import {TerminusOptions} from \"@godaddy/terminus\";\n\nexport type TerminusSettings = Omit<\n TerminusOptions,\n \"healthChecks\" | \"onSignal\" | \"onSendFailureDuringShutdown\" | \"onShutdown\" | \"beforeShutdown\" | \"onSigterm\"\n> & {path?: string};\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=interfaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../../src/interfaces/interfaces.ts"],"names":[],"mappings":"","sourcesContent":["import {TerminusSettings} from \"./TerminusSettings\";\n\ndeclare global {\n namespace TsED {\n interface Configuration {\n terminus: TerminusSettings;\n }\n }\n}\n"]}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
@@ -1,13 +1,33 @@
1
1
  import { OnInit } from "@tsed/di";
2
2
  export declare class TerminusModule implements OnInit {
3
- private configuration;
3
+ private settings;
4
+ private basePath;
4
5
  private injector;
5
6
  private httpServer;
6
7
  private httpsServer;
7
8
  $onInit(): void;
9
+ getConfiguration(): {
10
+ caseInsensitive?: boolean | undefined;
11
+ timeout?: number | undefined;
12
+ signal?: string | undefined;
13
+ signals?: string[] | undefined;
14
+ sendFailuresDuringShutdown?: boolean | undefined;
15
+ statusOk?: number | undefined;
16
+ statusError?: number | undefined;
17
+ logger: (event: string, error: any) => any;
18
+ headers?: {
19
+ [key: string]: string;
20
+ } | undefined;
21
+ healthChecks: Record<string, any>;
22
+ onSignal: (...args: any[]) => Promise<void>;
23
+ onShutdown: (...args: any[]) => Promise<void>;
24
+ beforeShutdown: (...args: any[]) => Promise<void>;
25
+ onSendFailureDuringShutdown: (...args: any[]) => Promise<void>;
26
+ };
27
+ $logRoutes(routes: any[]): Promise<any[]>;
8
28
  private mount;
9
- private getProviders;
10
- private getStore;
29
+ private getAll;
11
30
  private getHealths;
12
- private execShutdown;
31
+ private getPath;
32
+ private createEmitter;
13
33
  }
@@ -1,8 +1,10 @@
1
+ export declare function register(event: string): <Function_1>(target: Object, propertyKey: string, description: PropertyDescriptor) => void;
1
2
  /**
2
3
  * Listen the `beforeShutdown` terminus event.
3
4
  *
4
5
  * @decorator
5
6
  * @terminus
7
+ * @deprecated Use $BeforeShutdown hook
6
8
  */
7
9
  export declare function BeforeShutdown(): MethodDecorator;
8
10
  /**
@@ -10,6 +12,7 @@ export declare function BeforeShutdown(): MethodDecorator;
10
12
  *
11
13
  * @decorator
12
14
  * @terminus
15
+ * @deprecated Use $onSignal hook
13
16
  */
14
17
  export declare function OnSignal(): MethodDecorator;
15
18
  /**
@@ -17,6 +20,7 @@ export declare function OnSignal(): MethodDecorator;
17
20
  *
18
21
  * @decorator
19
22
  * @terminus
23
+ * @deprecated Use $onShutdown hook
20
24
  */
21
25
  export declare function OnShutdown(): MethodDecorator;
22
26
  /**
@@ -24,5 +28,6 @@ export declare function OnShutdown(): MethodDecorator;
24
28
  *
25
29
  * @decorator
26
30
  * @terminus
31
+ * @deprecated Use $onSendFailureDuringShutdown hook
27
32
  */
28
33
  export declare function OnSendFailureDuringShutdown(): MethodDecorator;
@@ -1,4 +1,8 @@
1
+ /**
2
+ * @file Automatically generated by barrelsby.
3
+ */
4
+ export * from "./TerminusModule";
1
5
  export * from "./decorators/health";
2
6
  export * from "./decorators/shutdown";
3
- export * from "./interfaces";
4
- export * from "./TerminusModule";
7
+ export * from "./interfaces/TerminusSettings";
8
+ export * from "./interfaces/interfaces";
@@ -1,2 +1,4 @@
1
1
  import { TerminusOptions } from "@godaddy/terminus";
2
- export declare type TerminusSettings = Omit<TerminusOptions, "healthChecks" | "onSignal" | "onSendFailureDuringShutdown" | "onShutdown" | "beforeShutdown" | "onSigterm">;
2
+ export declare type TerminusSettings = Omit<TerminusOptions, "healthChecks" | "onSignal" | "onSendFailureDuringShutdown" | "onShutdown" | "beforeShutdown" | "onSigterm"> & {
3
+ path?: string;
4
+ };
@@ -6,4 +6,3 @@ declare global {
6
6
  }
7
7
  }
8
8
  }
9
- export * from "./TerminusSettings";
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@tsed/terminus",
3
- "version": "7.0.0-beta.2",
3
+ "version": "7.0.0-beta.20",
4
4
  "description": "Adds graceful shutdown and Kubernetes readiness / liveness checks for any HTTP applications.",
5
5
  "author": "Romain Lenzotti",
6
6
  "private": false,
7
7
  "source": "./src/index.ts",
8
8
  "main": "./lib/cjs/index.js",
9
+ "module": "./lib/esm/index.js",
9
10
  "typings": "./lib/types/index.d.ts",
10
11
  "exports": {
11
12
  "types": "./lib/types/index.d.ts",
@@ -14,31 +15,49 @@
14
15
  "default": "./lib/esm/index.js"
15
16
  },
16
17
  "scripts": {
17
- "build": "yarn run build:esm && yarn run build:cjs",
18
+ "build": "yarn barrels && yarn run build:esm && yarn run build:cjs",
18
19
  "build:cjs": "tsc --build tsconfig.compile.json",
19
20
  "build:esm": "tsc --build tsconfig.compile.esm.json",
20
- "start": "ts-node -r tsconfig-paths/register test/app/index.ts"
21
+ "barrels": "yarn barrelsby --delete -d ./src -e \"\\.spec\\.ts\" -e \"__mock__\" -e \".benchmark.ts\"",
22
+ "start": "ts-node -r tsconfig-paths/register test/app/index.ts",
23
+ "test": "cross-env NODE_ENV=test yarn jest --max-workers=2"
21
24
  },
22
25
  "dependencies": {
23
- "@godaddy/terminus": "^4.7.1",
24
- "tslib": "2.2.0"
26
+ "tslib": "2.4.0"
25
27
  },
26
28
  "devDependencies": {
27
- "@tsed/core": "7.0.0-beta.2",
28
- "@tsed/di": "7.0.0-beta.2",
29
- "@tsed/openspec": "7.0.0-beta.2",
30
- "@tsed/schema": "7.0.0-beta.2"
29
+ "@godaddy/terminus": "^4.7.1",
30
+ "@tsed/core": "7.0.0-beta.20",
31
+ "@tsed/di": "7.0.0-beta.20",
32
+ "@tsed/schema": "7.0.0-beta.20"
31
33
  },
32
34
  "peerDependencies": {
33
- "@tsed/core": "^7.0.0-beta.2",
34
- "@tsed/di": "^7.0.0-beta.2",
35
- "@tsed/openspec": "^7.0.0-beta.2",
36
- "@tsed/schema": "^7.0.0-beta.2"
35
+ "@godaddy/terminus": "^4.7.1",
36
+ "@tsed/core": "^7.0.0-beta.20",
37
+ "@tsed/di": "^7.0.0-beta.20",
38
+ "@tsed/schema": "^7.0.0-beta.20"
39
+ },
40
+ "peerDependenciesMeta": {
41
+ "@godaddy/terminus": {
42
+ "optional": false
43
+ },
44
+ "@tsed/core": {
45
+ "optional": false
46
+ },
47
+ "@tsed/di": {
48
+ "optional": false
49
+ },
50
+ "@tsed/schema": {
51
+ "optional": false
52
+ }
37
53
  },
38
54
  "repository": "https://github.com/tsedio/tsed",
39
55
  "bugs": {
40
56
  "url": "https://github.com/tsedio/tsed/issues"
41
57
  },
42
- "homepage": "https://github.com/tsedio/tsed/tree/alpha/packages/third-parties/terminus",
43
- "license": "MIT"
58
+ "homepage": "https://github.com/tsedio/tsed/tree/beta/packages/third-parties/terminus",
59
+ "license": "MIT",
60
+ "publishConfig": {
61
+ "tag": "beta"
62
+ }
44
63
  }
package/readme.md CHANGED
@@ -11,7 +11,8 @@
11
11
  [![npm version](https://badge.fury.io/js/%40tsed%2Fcommon.svg)](https://badge.fury.io/js/%40tsed%2Fcommon)
12
12
  [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
13
13
  [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
14
- [![backers](https://opencollective.com/tsed/tiers/badge.svg)](https://opencollective.com/tsed)
14
+ [![github](https://img.shields.io/static/v1?label=Github%20sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86)](https://github.com/sponsors/romakita)
15
+ [![opencollective](https://img.shields.io/static/v1?label=OpenCollective%20sponsor&message=%E2%9D%A4&logo=OpenCollective&color=%23fe8e86)](https://opencollective.com/tsed)
15
16
 
16
17
  </div>
17
18
 
@@ -27,7 +28,7 @@
27
28
 
28
29
  <hr />
29
30
 
30
- Adds graceful shutdown and Kubernetes readiness / liveness checks for any HTTP applications.
31
+ Adds graceful shutdown and Kubernetes readiness / liveliness checks for any HTTP applications.
31
32
 
32
33
  ## Installation
33
34
 
@@ -43,10 +44,8 @@ Then import `@tsed/terminus` and add the following configuration in your `Server
43
44
  import {Configuration} from "@tsed/common";
44
45
  import "@tsed/terminus"; // import terminus Ts.ED module
45
46
  import {resolve} from "path";
46
- const rootDir = resolve(__dirname);
47
47
 
48
48
  @Configuration({
49
- rootDir,
50
49
  terminus: {
51
50
  // ... see Terminus configuration options on https://github.com/godaddy/terminus
52
51
  }
@@ -59,95 +58,140 @@ export class Server {}
59
58
  `terminus` configuration options waiting the same option description in the official Terminus documentation [here](https://github.com/godaddy/terminus).
60
59
  The following the options are managed by the `@tsed/terminus` package:
61
60
 
62
- - healthChecks
63
- - onSignal
64
- - onSendFailureDuringShutdown
65
- - onShutdown
66
- - beforeShutdown
67
- - onSigterm
61
+ - healthChecks
62
+ - onSignal
63
+ - onSendFailureDuringShutdown
64
+ - onShutdown
65
+ - beforeShutdown
66
+ - onSigterm
68
67
 
69
68
  ```typescript
70
69
  export type TerminusSettings = Omit<
71
- TerminusOptions,
72
- "healthChecks" | "onSignal" | "onSendFailureDuringShutdown" | "onShutdown" | "beforeShutdown" | "onSigterm"
70
+ TerminusOptions,
71
+ "healthChecks" | "onSignal" | "onSendFailureDuringShutdown" | "onShutdown" | "beforeShutdown" | "onSigterm"
73
72
  >;
74
73
  ```
75
74
 
76
75
  ## Usage
77
- ### Readiness / liveness checks
78
76
 
79
- To create a readiness / liveness checks use the `@Health` decorator.
77
+ ### Readiness / liveliness checks
78
+
79
+ To create a readiness / liveliness checks use the `@Health` decorator.
80
80
 
81
81
  ```ts
82
- import { Health } from "@tsed/terminus";
83
-
84
- @Controller("/mongo")
85
- class MongoCtrl {
86
- @Health("/health")
87
- health() {
88
- // Here check the mongo health
89
- return Promise.resolve();
82
+ import {Health} from "@tsed/terminus";
83
+ import {Injectable, Inject} from "@tsed/di";
84
+ import {HealthCheckError} from "@godaddy/terminus";
85
+ import {REDIS_CONNECTION} from "./RedisConnection";
86
+
87
+ @Injectable()
88
+ class RedisClient {
89
+ @Inject(REDIS_CONNECTION)
90
+ protected redisConnection: REDIS_CONNECTION;
91
+
92
+ @Health("redis")
93
+ async check() {
94
+ if (this.redisConnection.status === "ready") {
95
+ return "OK";
96
+ }
97
+
98
+ // Here check the redis health
99
+ throw new HealthCheckError("failed", {
100
+ redis: this.redisConnection.status
101
+ });
90
102
  }
91
103
  }
92
104
  ```
93
105
 
94
- You can also create an ``HealthCheckError`` when an error appear during your check.
106
+ You can also create an `HealthCheckError` when an error appear during your check.
95
107
 
96
108
  ```ts
97
- import { Health } from "@tsed/terminus";
98
- import { HealthCheckError } from "@godaddy/terminus";
109
+ import {Health} from "@tsed/terminus";
110
+ import {Injectable, Inject} from "@tsed/di";
111
+ import {HealthCheckError} from "@godaddy/terminus";
112
+ import {REDIS_CONNECTION} from "./RedisConnection";
113
+
114
+ @Injectable()
115
+ class RedisClient {
116
+ @Inject(REDIS_CONNECTION)
117
+ protected redisConnection: REDIS_CONNECTION;
118
+
119
+ @Health("redis")
120
+ async check() {
121
+ if (this.redisConnection.status === "ready") {
122
+ return "ok";
123
+ }
99
124
 
100
- @Controller("/redis")
101
- class Redis {
102
- @Health("/health")
103
- health() {
104
125
  // Here check the redis health
105
- return Promise.reject(new HealthCheckError('failed', {
106
- redis: 'down',
107
- }));
126
+ throw new HealthCheckError("failed", {
127
+ redis: this.redisConnection.status
128
+ });
108
129
  }
109
130
  }
110
131
  ```
111
132
 
133
+ Expected result when calling the "/health":
134
+
135
+ ```json
136
+ {
137
+ "status": "ok",
138
+ "info": [
139
+ {
140
+ "mongo": "ok"
141
+ },
142
+ {
143
+ "redis": "ok"
144
+ }
145
+ ],
146
+ "details": [
147
+ {
148
+ "mongo": "ok"
149
+ },
150
+ {
151
+ "redis": "ok"
152
+ }
153
+ ]
154
+ }
155
+ ```
156
+
112
157
  ### Graceful shutdown
113
158
 
114
- `@tsed/terminus` package give some decorators to handle Terminus hooks. These hooks allow you to adds graceful shutdown.
159
+ `@tsed/terminus` package give some decorators to handle Terminus hooks. These hooks allow you to adds graceful shutdown.
115
160
  Here is the list of decorators:
116
161
 
117
- - `BeforeShutdown`: Use this hook if you deploy your application with Kubernetes (see more details [here](https://github.com/godaddy/terminus#how-to-set-terminus-up-with-kubernetes)),
118
- - `OnSignal`: cleanup hook, returning a promise (used to be onSigterm),
119
- - `OnShutdown`: called right before exiting,
120
- - `OnSendFailureDuringShutdown`: called before sending each 503 during shutdowns.
162
+ - `$beforeShutdown`: Use this hook if you deploy your application with Kubernetes (see more
163
+ details [here](https://github.com/godaddy/terminus#how-to-set-terminus-up-with-kubernetes)),
164
+ - `$onSignal`: cleanup hook, returning a promise (used to be onSigterm),
165
+ - `$onShutdown`: called right before exiting,
166
+ - `$onSendFailureDuringShutdown`: called before sending each 503 during shutdowns.
121
167
 
122
168
  **Example:**
169
+
123
170
  ```typescript
124
- import { BeforeShutdown, OnSendFailureDuringShutdown, OnShutdown, OnSignal } from "@tsed/terminus";
171
+ import {Injectable} from "@tsed/di";
125
172
 
126
- @Controller("/redis")
173
+ @Injectable()
127
174
  class RedisCtrl {
128
- @BeforeShutdown()
129
- beforeShutdow() {
130
- console.log('called before shutdown');
175
+ $beforeShutdown() {
176
+ console.log("called before shutdown");
131
177
  }
132
178
 
133
- @OnSignal()
134
- OnSignal() {
135
- console.log('called on signal');
179
+ $onSignal() {
180
+ console.log("called on signal");
136
181
  }
137
182
 
138
- @OnShutdown()
139
- OnShutdown() {
140
- console.log('called on shutdown');
183
+ $onShutdown() {
184
+ console.log("called on shutdown");
141
185
  }
142
186
 
143
- @OnSendFailureDuringShutdown()
144
- OnSendFailureDuringShutdown() {
145
- console.log('on send failure during shutdown');
187
+ $onSendFailureDuringShutdown() {
188
+ console.log("on send failure during shutdown");
146
189
  }
147
190
  }
148
191
  ```
149
192
 
150
193
  ## Contributors
194
+
151
195
  Please read [contributing guidelines here](https://tsed.io/CONTRIBUTING.html).
152
196
 
153
197
  <a href="https://github.com/tsedio/ts-express-decorators/graphs/contributors"><img src="https://opencollective.com/tsed/contributors.svg?width=890" /></a>
@@ -158,7 +202,6 @@ Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com
158
202
 
159
203
  <a href="https://opencollective.com/tsed#backers" target="_blank"><img src="https://opencollective.com/tsed/tiers/backer.svg?width=890"></a>
160
204
 
161
-
162
205
  ## Sponsors
163
206
 
164
207
  Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/tsed#sponsor)]
@@ -167,7 +210,7 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
167
210
 
168
211
  The MIT License (MIT)
169
212
 
170
- Copyright (c) 2016 - 2018 Romain Lenzotti
213
+ Copyright (c) 2016 - 2022 Romain Lenzotti
171
214
 
172
215
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
173
216
 
@@ -8,16 +8,5 @@
8
8
  "declaration": true,
9
9
  "declarationDir": "./lib/types"
10
10
  },
11
- "exclude": [
12
- "node_modules",
13
- "test",
14
- "lib",
15
- "benchmark",
16
- "coverage",
17
- "spec",
18
- "**/*.benchmark.ts",
19
- "**/*.spec.ts",
20
- "keys",
21
- "jest.config.js"
22
- ]
11
+ "exclude": ["node_modules", "test", "lib", "benchmark", "coverage", "spec", "**/*.benchmark.ts", "**/*.spec.ts", "keys", "jest.config.js"]
23
12
  }
@@ -1,5 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- (0, tslib_1.__exportStar)(require("./TerminusSettings"), exports);
5
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/interfaces/index.ts"],"names":[],"mappings":";;;AAUA,kEAAmC","sourcesContent":["import {TerminusSettings} from \"./TerminusSettings\";\n\ndeclare global {\n namespace TsED {\n interface Configuration {\n terminus: TerminusSettings;\n }\n }\n}\n\nexport * from \"./TerminusSettings\";\n"]}
@@ -1,2 +0,0 @@
1
- export * from "./TerminusSettings";
2
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/interfaces/index.ts"],"names":[],"mappings":"AAUA,cAAc,oBAAoB,CAAC","sourcesContent":["import {TerminusSettings} from \"./TerminusSettings\";\n\ndeclare global {\n namespace TsED {\n interface Configuration {\n terminus: TerminusSettings;\n }\n }\n}\n\nexport * from \"./TerminusSettings\";\n"]}