@lucaapp/service-utils 1.8.0 → 1.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/lib/kafka/kafkaClient.d.ts +1 -1
- package/dist/lib/kafka/kafkaClient.js +3 -1
- package/dist/lib/lifecycle/index.d.ts +17 -0
- package/dist/lib/lifecycle/index.js +54 -0
- package/dist/lib/lifecycle/sleep.d.ts +3 -0
- package/dist/lib/lifecycle/sleep.js +13 -0
- package/dist/lib/logger/index.d.ts +6 -0
- package/dist/lib/logger/index.js +89 -0
- package/dist/lib/logger/utils.d.ts +9 -0
- package/dist/lib/logger/utils.js +2 -0
- package/dist/lib/serviceIdentity/environment.d.ts +16 -16
- package/dist/lib/serviceIdentity/environment.js +16 -16
- package/dist/lib/serviceIdentity/service.d.ts +2 -0
- package/dist/lib/serviceIdentity/service.js +2 -0
- package/package.json +4 -2
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -18,3 +18,5 @@ __exportStar(require("./lib/kafka"), exports);
|
|
|
18
18
|
__exportStar(require("./lib/serviceIdentity"), exports);
|
|
19
19
|
__exportStar(require("./lib/metrics"), exports);
|
|
20
20
|
__exportStar(require("./lib/wsEvent"), exports);
|
|
21
|
+
__exportStar(require("./lib/lifecycle"), exports);
|
|
22
|
+
__exportStar(require("./lib/logger"), exports);
|
|
@@ -21,7 +21,7 @@ declare class KafkaClient {
|
|
|
21
21
|
private verifySignature;
|
|
22
22
|
private parseValue;
|
|
23
23
|
private ensureTopics;
|
|
24
|
-
consume: <T extends KafkaTopic>(
|
|
24
|
+
consume: <T extends KafkaTopic>(kafkaTopic: T, handler: EventPayloadHandler<T>, fromBeginning?: boolean) => Promise<Consumer>;
|
|
25
25
|
produce: <T extends KafkaTopic>(kafkaTopic: T, key: string, value: KafkaEvent<T>) => Promise<void>;
|
|
26
26
|
}
|
|
27
27
|
export { KafkaClient };
|
|
@@ -154,8 +154,9 @@ class KafkaClient {
|
|
|
154
154
|
});
|
|
155
155
|
this.logger.debug(`Topic=${topic} created.`);
|
|
156
156
|
};
|
|
157
|
-
this.consume = async (
|
|
157
|
+
this.consume = async (kafkaTopic, handler, fromBeginning = false) => {
|
|
158
158
|
const topic = await this.getTopic(kafkaTopic);
|
|
159
|
+
const groupId = `${this.environment.valueOf()}_${this.serviceIdentity.identityName}`;
|
|
159
160
|
try {
|
|
160
161
|
const consumer = this.kafkaClient.consumer({ groupId });
|
|
161
162
|
await consumer.connect();
|
|
@@ -180,6 +181,7 @@ class KafkaClient {
|
|
|
180
181
|
messageConsumedErrorCounter
|
|
181
182
|
.labels({ topic: kafkaTopic.valueOf(), groupId })
|
|
182
183
|
.inc();
|
|
184
|
+
throw error;
|
|
183
185
|
}
|
|
184
186
|
},
|
|
185
187
|
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Logger, LoggerOptions } from 'pino';
|
|
2
|
+
declare class Lifecycle {
|
|
3
|
+
state: {
|
|
4
|
+
isShuttingDown: boolean;
|
|
5
|
+
};
|
|
6
|
+
private readonly shutdownDelay;
|
|
7
|
+
private readonly logger;
|
|
8
|
+
constructor(shutdownDelay: number, logger: Logger<LoggerOptions>);
|
|
9
|
+
shutdownHandlers: Array<() => void>;
|
|
10
|
+
gracefulShutdown: (isImmediate?: boolean) => Promise<void>;
|
|
11
|
+
private sigtermHandler;
|
|
12
|
+
unhandledRejectionHandler: (error: unknown) => void;
|
|
13
|
+
uncaughtExceptionHandler: (error: unknown) => void;
|
|
14
|
+
registerShutdownHandler: (shutdownHandler: () => void) => void;
|
|
15
|
+
registerHooks: () => void;
|
|
16
|
+
}
|
|
17
|
+
export { Lifecycle };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Lifecycle = void 0;
|
|
7
|
+
const moment_1 = __importDefault(require("moment"));
|
|
8
|
+
const sleep_1 = require("./sleep");
|
|
9
|
+
class Lifecycle {
|
|
10
|
+
constructor(shutdownDelay, logger) {
|
|
11
|
+
this.state = {
|
|
12
|
+
isShuttingDown: false,
|
|
13
|
+
};
|
|
14
|
+
this.shutdownHandlers = [];
|
|
15
|
+
this.gracefulShutdown = async (isImmediate = false) => {
|
|
16
|
+
if (this.state.isShuttingDown)
|
|
17
|
+
return;
|
|
18
|
+
this.state.isShuttingDown = true;
|
|
19
|
+
if (!isImmediate) {
|
|
20
|
+
this.logger.info(`shutting down in ${this.shutdownDelay.as('seconds')}s.`);
|
|
21
|
+
await (0, sleep_1.sleep)(this.shutdownDelay.as('milliseconds'));
|
|
22
|
+
}
|
|
23
|
+
this.logger.info('starting shutdown');
|
|
24
|
+
for (const shutdownHandler of this.shutdownHandlers) {
|
|
25
|
+
shutdownHandler();
|
|
26
|
+
}
|
|
27
|
+
this.logger.info('shutdown complete');
|
|
28
|
+
};
|
|
29
|
+
this.sigtermHandler = async () => {
|
|
30
|
+
this.logger.info('SIGTERM received.');
|
|
31
|
+
await this.gracefulShutdown();
|
|
32
|
+
process.exit(0);
|
|
33
|
+
};
|
|
34
|
+
this.unhandledRejectionHandler = (error) => {
|
|
35
|
+
this.logger.error(error, 'unhandledRejection');
|
|
36
|
+
process.exit(1);
|
|
37
|
+
};
|
|
38
|
+
this.uncaughtExceptionHandler = (error) => {
|
|
39
|
+
this.logger.error(error, 'uncaughtException');
|
|
40
|
+
process.exit(1);
|
|
41
|
+
};
|
|
42
|
+
this.registerShutdownHandler = (shutdownHandler) => {
|
|
43
|
+
this.shutdownHandlers.push(shutdownHandler);
|
|
44
|
+
};
|
|
45
|
+
this.registerHooks = () => {
|
|
46
|
+
process.on('SIGTERM', this.sigtermHandler);
|
|
47
|
+
process.on('uncaughtException', this.uncaughtExceptionHandler);
|
|
48
|
+
process.on('unhandledRejection', this.unhandledRejectionHandler);
|
|
49
|
+
};
|
|
50
|
+
this.shutdownDelay = moment_1.default.duration(shutdownDelay, 'seconds');
|
|
51
|
+
this.logger = logger;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.Lifecycle = Lifecycle;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.randomSleep = exports.sleep = void 0;
|
|
7
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
8
|
+
const util_1 = require("util");
|
|
9
|
+
const setTimeoutPromise = (0, util_1.promisify)(setTimeout);
|
|
10
|
+
const sleep = (msToSleep) => setTimeoutPromise(msToSleep);
|
|
11
|
+
exports.sleep = sleep;
|
|
12
|
+
const randomSleep = () => setTimeoutPromise(crypto_1.default.randomInt(100, 500));
|
|
13
|
+
exports.randomSleep = randomSleep;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Logger, LoggerOptions } from 'pino';
|
|
2
|
+
import { HttpLoggerCreationOptions } from './utils';
|
|
3
|
+
export declare class LoggerFactory {
|
|
4
|
+
static getLogger(logLevel: string): Logger<LoggerOptions>;
|
|
5
|
+
static getHttpLogger(options: HttpLoggerCreationOptions): import("pino-http").HttpLogger;
|
|
6
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.LoggerFactory = void 0;
|
|
7
|
+
const pino_1 = __importDefault(require("pino"));
|
|
8
|
+
const pino_http_1 = __importDefault(require("pino-http"));
|
|
9
|
+
const pick_1 = __importDefault(require("lodash/pick"));
|
|
10
|
+
const uuid_1 = require("uuid");
|
|
11
|
+
class LoggerFactory {
|
|
12
|
+
static getLogger(logLevel) {
|
|
13
|
+
return (0, pino_1.default)({ level: logLevel });
|
|
14
|
+
}
|
|
15
|
+
static getHttpLogger(options) {
|
|
16
|
+
const { requestSerializer, responseSerializer, errorSerializer, defaultHttpLogLevel, customMessage, } = new HttpLoggerHelpers(options);
|
|
17
|
+
const logger = this.getLogger(options.logLevel);
|
|
18
|
+
return (0, pino_http_1.default)({
|
|
19
|
+
logger: logger,
|
|
20
|
+
serializers: {
|
|
21
|
+
req: requestSerializer,
|
|
22
|
+
res: responseSerializer,
|
|
23
|
+
err: errorSerializer,
|
|
24
|
+
},
|
|
25
|
+
customLogLevel: (response, error) => {
|
|
26
|
+
if (response.statusCode >= 400 && response.statusCode < 500)
|
|
27
|
+
return 'warn';
|
|
28
|
+
if (response.statusCode >= 500 || error)
|
|
29
|
+
return 'error';
|
|
30
|
+
return defaultHttpLogLevel;
|
|
31
|
+
},
|
|
32
|
+
customSuccessMessage: customMessage,
|
|
33
|
+
customErrorMessage: (_, response) => customMessage(response),
|
|
34
|
+
genReqId: () => (0, uuid_1.v4)(),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.LoggerFactory = LoggerFactory;
|
|
39
|
+
class HttpLoggerHelpers {
|
|
40
|
+
constructor({ debug, e2e, defaultHttpLogLevel }) {
|
|
41
|
+
this.requestSerializer = (request) => {
|
|
42
|
+
if (this.debug || this.e2e)
|
|
43
|
+
return request;
|
|
44
|
+
request.headers = (0, pick_1.default)(request.headers, [
|
|
45
|
+
'connection',
|
|
46
|
+
'host',
|
|
47
|
+
'origin',
|
|
48
|
+
'x-real-ip',
|
|
49
|
+
'x-forwarded-for',
|
|
50
|
+
'x-forwarded-proto',
|
|
51
|
+
'x-forwarded-host',
|
|
52
|
+
'x-forwarded-port',
|
|
53
|
+
'x-scheme',
|
|
54
|
+
'user-agent',
|
|
55
|
+
'content-type',
|
|
56
|
+
'accept',
|
|
57
|
+
'referer',
|
|
58
|
+
'accept-encoding',
|
|
59
|
+
'ssl-client-subject-dn',
|
|
60
|
+
]);
|
|
61
|
+
return request;
|
|
62
|
+
};
|
|
63
|
+
this.responseSerializer = (response) => {
|
|
64
|
+
if (this.debug)
|
|
65
|
+
return response;
|
|
66
|
+
response.headers = (0, pick_1.default)(response.headers, [
|
|
67
|
+
'content-type',
|
|
68
|
+
'content-length',
|
|
69
|
+
]);
|
|
70
|
+
return response;
|
|
71
|
+
};
|
|
72
|
+
this.errorSerializer = (error) => {
|
|
73
|
+
if (error?.parameters)
|
|
74
|
+
error.parameters = undefined;
|
|
75
|
+
if (error?.parent?.parameters)
|
|
76
|
+
error.parent.parameters = undefined;
|
|
77
|
+
if (error?.original?.parameters)
|
|
78
|
+
error.original.parameters = undefined;
|
|
79
|
+
return error;
|
|
80
|
+
};
|
|
81
|
+
this.customMessage = (response) => {
|
|
82
|
+
const { req: { method, originalUrl }, statusCode, } = response;
|
|
83
|
+
return `${statusCode} ${method} ${originalUrl}`;
|
|
84
|
+
};
|
|
85
|
+
this.debug = !!debug;
|
|
86
|
+
this.e2e = !!e2e;
|
|
87
|
+
this.defaultHttpLogLevel = defaultHttpLogLevel || 'info';
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
declare enum Environment {
|
|
2
|
-
LOCAL = "
|
|
3
|
-
DEV = "
|
|
4
|
-
QS = "
|
|
5
|
-
AQS = "
|
|
6
|
-
RELEASE = "
|
|
7
|
-
HOTFIX = "
|
|
8
|
-
PENTEST = "
|
|
9
|
-
P1 = "
|
|
10
|
-
P2 = "
|
|
11
|
-
P3 = "
|
|
12
|
-
P4 = "
|
|
13
|
-
P5 = "
|
|
14
|
-
P6 = "
|
|
15
|
-
DEMO = "
|
|
16
|
-
PREPROD = "
|
|
17
|
-
PROD = "
|
|
2
|
+
LOCAL = "local",
|
|
3
|
+
DEV = "dev",
|
|
4
|
+
QS = "qs",
|
|
5
|
+
AQS = "aqs",
|
|
6
|
+
RELEASE = "release",
|
|
7
|
+
HOTFIX = "hotfix",
|
|
8
|
+
PENTEST = "pentest",
|
|
9
|
+
P1 = "p1",
|
|
10
|
+
P2 = "p2",
|
|
11
|
+
P3 = "p3",
|
|
12
|
+
P4 = "p4",
|
|
13
|
+
P5 = "p5",
|
|
14
|
+
P6 = "p6",
|
|
15
|
+
DEMO = "demo",
|
|
16
|
+
PREPROD = "preprod",
|
|
17
|
+
PROD = "prod"
|
|
18
18
|
}
|
|
19
19
|
export { Environment };
|
|
@@ -3,21 +3,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Environment = void 0;
|
|
4
4
|
var Environment;
|
|
5
5
|
(function (Environment) {
|
|
6
|
-
Environment["LOCAL"] = "
|
|
7
|
-
Environment["DEV"] = "
|
|
8
|
-
Environment["QS"] = "
|
|
9
|
-
Environment["AQS"] = "
|
|
10
|
-
Environment["RELEASE"] = "
|
|
11
|
-
Environment["HOTFIX"] = "
|
|
12
|
-
Environment["PENTEST"] = "
|
|
13
|
-
Environment["P1"] = "
|
|
14
|
-
Environment["P2"] = "
|
|
15
|
-
Environment["P3"] = "
|
|
16
|
-
Environment["P4"] = "
|
|
17
|
-
Environment["P5"] = "
|
|
18
|
-
Environment["P6"] = "
|
|
19
|
-
Environment["DEMO"] = "
|
|
20
|
-
Environment["PREPROD"] = "
|
|
21
|
-
Environment["PROD"] = "
|
|
6
|
+
Environment["LOCAL"] = "local";
|
|
7
|
+
Environment["DEV"] = "dev";
|
|
8
|
+
Environment["QS"] = "qs";
|
|
9
|
+
Environment["AQS"] = "aqs";
|
|
10
|
+
Environment["RELEASE"] = "release";
|
|
11
|
+
Environment["HOTFIX"] = "hotfix";
|
|
12
|
+
Environment["PENTEST"] = "pentest";
|
|
13
|
+
Environment["P1"] = "p1";
|
|
14
|
+
Environment["P2"] = "p2";
|
|
15
|
+
Environment["P3"] = "p3";
|
|
16
|
+
Environment["P4"] = "p4";
|
|
17
|
+
Environment["P5"] = "p5";
|
|
18
|
+
Environment["P6"] = "p6";
|
|
19
|
+
Environment["DEMO"] = "demo";
|
|
20
|
+
Environment["PREPROD"] = "preprod";
|
|
21
|
+
Environment["PROD"] = "prod";
|
|
22
22
|
})(Environment || (Environment = {}));
|
|
23
23
|
exports.Environment = Environment;
|
|
@@ -6,6 +6,8 @@ var Service;
|
|
|
6
6
|
Service["BACKEND"] = "backend";
|
|
7
7
|
Service["BACKEND_PAY"] = "backend-pay";
|
|
8
8
|
Service["BACKEND_POS"] = "backend-pos";
|
|
9
|
+
Service["BACKEND_ID"] = "backend-id";
|
|
10
|
+
Service["BACKEND_ATTESTATION"] = "backend-attestation";
|
|
9
11
|
Service["BACKEND_PUBSUB"] = "backend-pubsub";
|
|
10
12
|
})(Service || (Service = {}));
|
|
11
13
|
exports.Service = Service;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lucaapp/service-utils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@types/express": "4.17.13",
|
|
22
22
|
"@types/jest": "^28.1.5",
|
|
23
|
+
"@types/lodash": "^4.14.187",
|
|
23
24
|
"@types/uuid": "^8.3.4",
|
|
24
25
|
"@typescript-eslint/eslint-plugin": "^5.30.6",
|
|
25
26
|
"@typescript-eslint/parser": "^5.30.6",
|
|
@@ -31,7 +32,6 @@
|
|
|
31
32
|
"semantic-release": "^19.0.3",
|
|
32
33
|
"semantic-release-monorepo": "^7.0.5",
|
|
33
34
|
"ts-jest": "^28.0.5",
|
|
34
|
-
"pino": "^8.6.1",
|
|
35
35
|
"typescript": "^4.7.4"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
@@ -40,7 +40,9 @@
|
|
|
40
40
|
"axios": "^0.27.2",
|
|
41
41
|
"jose": "4.9.2",
|
|
42
42
|
"kafkajs": "2.1.0",
|
|
43
|
+
"lodash": "^4.17.21",
|
|
43
44
|
"moment": "^2.29.4",
|
|
45
|
+
"pino-http": "6.6.0",
|
|
44
46
|
"prom-client": "14.1.0",
|
|
45
47
|
"uuid": "^9.0.0"
|
|
46
48
|
}
|