@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.
- package/jest.config.js +14 -0
- package/lib/cjs/TerminusModule.js +103 -41
- package/lib/cjs/TerminusModule.js.map +1 -1
- package/lib/cjs/decorators/health.js +4 -6
- package/lib/cjs/decorators/health.js.map +1 -1
- package/lib/cjs/decorators/shutdown.js +12 -10
- package/lib/cjs/decorators/shutdown.js.map +1 -1
- package/lib/cjs/index.js +8 -4
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/interfaces/TerminusSettings.js.map +1 -1
- package/lib/cjs/interfaces/interfaces.js +3 -0
- package/lib/cjs/interfaces/interfaces.js.map +1 -0
- package/lib/cjs/package.json +3 -0
- package/lib/esm/TerminusModule.js +94 -32
- package/lib/esm/TerminusModule.js.map +1 -1
- package/lib/esm/decorators/health.js +4 -6
- package/lib/esm/decorators/health.js.map +1 -1
- package/lib/esm/decorators/shutdown.js +10 -9
- package/lib/esm/decorators/shutdown.js.map +1 -1
- package/lib/esm/index.js +8 -4
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/interfaces/TerminusSettings.js.map +1 -1
- package/lib/esm/interfaces/interfaces.js +2 -0
- package/lib/esm/interfaces/interfaces.js.map +1 -0
- package/lib/esm/package.json +3 -0
- package/lib/types/TerminusModule.d.ts +24 -4
- package/lib/types/decorators/shutdown.d.ts +5 -0
- package/lib/types/index.d.ts +6 -2
- package/lib/types/interfaces/TerminusSettings.d.ts +3 -1
- package/lib/types/interfaces/{index.d.ts → interfaces.d.ts} +0 -1
- package/package.json +34 -15
- package/readme.md +96 -53
- package/tsconfig.compile.esm.json +1 -12
- package/lib/cjs/interfaces/index.js +0 -5
- package/lib/cjs/interfaces/index.js.map +0 -1
- package/lib/esm/interfaces/index.js +0 -2
- 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
|
|
8
|
-
const http_1 =
|
|
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
|
-
|
|
14
|
-
const {
|
|
15
|
-
|
|
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.
|
|
19
|
-
onShutdown: this.
|
|
20
|
-
beforeShutdown: this.
|
|
21
|
-
onSendFailureDuringShutdown: this.
|
|
22
|
-
...
|
|
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
|
-
|
|
32
|
-
return this.injector.getProviders().
|
|
33
|
-
|
|
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
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
59
|
-
(0, di_1.
|
|
60
|
-
|
|
61
|
-
], TerminusModule.prototype, "
|
|
62
|
-
|
|
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
|
-
|
|
126
|
+
tslib_1.__metadata("design:type", di_1.InjectorService)
|
|
65
127
|
], TerminusModule.prototype, "injector", void 0);
|
|
66
|
-
|
|
128
|
+
tslib_1.__decorate([
|
|
67
129
|
(0, di_1.Inject)(http_1.default.Server),
|
|
68
|
-
|
|
130
|
+
tslib_1.__metadata("design:type", Object)
|
|
69
131
|
], TerminusModule.prototype, "httpServer", void 0);
|
|
70
|
-
|
|
132
|
+
tslib_1.__decorate([
|
|
71
133
|
(0, di_1.Inject)(https_1.default.Server),
|
|
72
|
-
|
|
134
|
+
tslib_1.__metadata("design:type", Object)
|
|
73
135
|
], TerminusModule.prototype, "httpsServer", void 0);
|
|
74
|
-
TerminusModule =
|
|
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,
|
|
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
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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,
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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("
|
|
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,
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
package/lib/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;
|
|
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
|
|
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 @@
|
|
|
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"]}
|
|
@@ -1,23 +1,61 @@
|
|
|
1
1
|
import { __decorate, __metadata } from "tslib";
|
|
2
2
|
import { createTerminus } from "@godaddy/terminus";
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
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
|
-
|
|
11
|
-
const {
|
|
12
|
-
|
|
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.
|
|
16
|
-
onShutdown: this.
|
|
17
|
-
beforeShutdown: this.
|
|
18
|
-
onSendFailureDuringShutdown: this.
|
|
19
|
-
...
|
|
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
|
-
|
|
29
|
-
return this.injector.getProviders().
|
|
30
|
-
|
|
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
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
114
|
+
Constant("terminus", {}),
|
|
57
115
|
__metadata("design:type", Object)
|
|
58
|
-
], TerminusModule.prototype, "
|
|
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":";AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAC,
|
|
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
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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,
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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("
|
|
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,
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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
|
package/lib/esm/index.js.map
CHANGED
|
@@ -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,
|
|
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
|
|
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 @@
|
|
|
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"]}
|
|
@@ -1,13 +1,33 @@
|
|
|
1
1
|
import { OnInit } from "@tsed/di";
|
|
2
2
|
export declare class TerminusModule implements OnInit {
|
|
3
|
-
private
|
|
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
|
|
10
|
-
private getStore;
|
|
29
|
+
private getAll;
|
|
11
30
|
private getHealths;
|
|
12
|
-
private
|
|
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;
|
package/lib/types/index.d.ts
CHANGED
|
@@ -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 "./
|
|
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
|
+
};
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsed/terminus",
|
|
3
|
-
"version": "7.0.0-beta.
|
|
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
|
-
"
|
|
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
|
-
"
|
|
24
|
-
"tslib": "2.2.0"
|
|
26
|
+
"tslib": "2.4.0"
|
|
25
27
|
},
|
|
26
28
|
"devDependencies": {
|
|
27
|
-
"@
|
|
28
|
-
"@tsed/
|
|
29
|
-
"@tsed/
|
|
30
|
-
"@tsed/schema": "7.0.0-beta.
|
|
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
|
-
"@
|
|
34
|
-
"@tsed/
|
|
35
|
-
"@tsed/
|
|
36
|
-
"@tsed/schema": "^7.0.0-beta.
|
|
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/
|
|
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
|
[](https://badge.fury.io/js/%40tsed%2Fcommon)
|
|
12
12
|
[](https://github.com/semantic-release/semantic-release)
|
|
13
13
|
[](https://github.com/prettier/prettier)
|
|
14
|
-
[](https://github.com/sponsors/romakita)
|
|
15
|
+
[](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 /
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|
-
|
|
77
|
+
### Readiness / liveliness checks
|
|
78
|
+
|
|
79
|
+
To create a readiness / liveliness checks use the `@Health` decorator.
|
|
80
80
|
|
|
81
81
|
```ts
|
|
82
|
-
import {
|
|
83
|
-
|
|
84
|
-
@
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
|
106
|
+
You can also create an `HealthCheckError` when an error appear during your check.
|
|
95
107
|
|
|
96
108
|
```ts
|
|
97
|
-
import {
|
|
98
|
-
import {
|
|
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
|
-
|
|
106
|
-
redis:
|
|
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
|
-
-
|
|
118
|
-
|
|
119
|
-
-
|
|
120
|
-
-
|
|
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 {
|
|
171
|
+
import {Injectable} from "@tsed/di";
|
|
125
172
|
|
|
126
|
-
@
|
|
173
|
+
@Injectable()
|
|
127
174
|
class RedisCtrl {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
console.log('called before shutdown');
|
|
175
|
+
$beforeShutdown() {
|
|
176
|
+
console.log("called before shutdown");
|
|
131
177
|
}
|
|
132
178
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
console.log('called on signal');
|
|
179
|
+
$onSignal() {
|
|
180
|
+
console.log("called on signal");
|
|
136
181
|
}
|
|
137
182
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
console.log('called on shutdown');
|
|
183
|
+
$onShutdown() {
|
|
184
|
+
console.log("called on shutdown");
|
|
141
185
|
}
|
|
142
186
|
|
|
143
|
-
|
|
144
|
-
|
|
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 -
|
|
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 +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 +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"]}
|