@platform-x/hep-notification-client 1.3.0 → 1.3.2
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/README.md +7 -7
- package/dist/jest-setup.js +28 -0
- package/dist/jest-setup.js.map +1 -0
- package/dist/src/common/controllers/common_controller.js +72 -0
- package/dist/src/common/controllers/common_controller.js.map +1 -0
- package/dist/src/common/controllers/index.js +29 -0
- package/dist/src/common/controllers/index.js.map +1 -0
- package/dist/src/common/middleware/commonMiddleware.js +141 -0
- package/dist/src/common/middleware/commonMiddleware.js.map +1 -0
- package/dist/src/common/service/requestService.js +79 -1
- package/dist/src/common/service/requestService.js.map +1 -0
- package/dist/src/common/service/twilioService.js +3 -11
- package/dist/src/common/service/twilioService.js.map +1 -0
- package/dist/src/common/util/commonUtil.js +119 -1
- package/dist/src/common/util/commonUtil.js.map +1 -0
- package/dist/src/common/util/constants.js +18 -0
- package/dist/src/common/util/constants.js.map +1 -0
- package/dist/src/common/util/errorHandler.js +4 -6
- package/dist/src/common/util/errorHandler.js.map +1 -0
- package/dist/src/common/util/httpCodes.js +26 -0
- package/dist/src/common/util/httpCodes.js.map +1 -0
- package/dist/src/common/util/logger.js +1 -1
- package/dist/src/common/util/logger.js.map +1 -0
- package/dist/src/common/util/requestTracer.js +18 -1
- package/dist/src/common/util/requestTracer.js.map +1 -0
- package/dist/src/common/util/solrConnector.js.map +1 -0
- package/dist/src/config/index.js +49 -4
- package/dist/src/config/index.js.map +1 -0
- package/dist/src/platform-x/app.js +35 -0
- package/dist/src/platform-x/app.js.map +1 -0
- package/dist/src/platform-x/constants/index.js +2 -14
- package/dist/src/platform-x/constants/index.js.map +1 -0
- package/dist/src/platform-x/constants/style.js +98 -98
- package/dist/src/platform-x/constants/style.js.map +1 -0
- package/dist/src/platform-x/controllers/cronController.js +399 -0
- package/dist/src/platform-x/controllers/cronController.js.map +1 -0
- package/dist/src/platform-x/controllers/fileUploadController.js +76 -0
- package/dist/src/platform-x/controllers/fileUploadController.js.map +1 -0
- package/dist/src/platform-x/controllers/graphRESTControllers.js +183 -0
- package/dist/src/platform-x/controllers/graphRESTControllers.js.map +1 -0
- package/dist/src/platform-x/controllers/index.js +30 -0
- package/dist/src/platform-x/controllers/index.js.map +1 -0
- package/dist/src/platform-x/controllers/siteDomainController.js +74 -0
- package/dist/src/platform-x/controllers/siteDomainController.js.map +1 -0
- package/dist/src/platform-x/dataSource/emailDataSource.js.map +1 -0
- package/dist/src/platform-x/database/connection.js +3 -6
- package/dist/src/platform-x/database/connection.js.map +1 -0
- package/dist/src/platform-x/database/dao/formBuilder.dao.js +1 -1
- package/dist/src/platform-x/database/dao/formBuilder.dao.js.map +1 -0
- package/dist/src/platform-x/database/dao/siteDomain.dao.js +73 -0
- package/dist/src/platform-x/database/dao/siteDomain.dao.js.map +1 -0
- package/dist/src/platform-x/database/index.js.map +1 -0
- package/dist/src/platform-x/{interface/interface.js → database/interfaces/site_domain.interface.js} +1 -1
- package/dist/src/platform-x/database/interfaces/site_domain.interface.js.map +1 -0
- package/dist/src/platform-x/database/models/formBuilder.model.js.map +1 -0
- package/dist/src/platform-x/database/models/site_domains.model.js +51 -0
- package/dist/src/platform-x/database/models/site_domains.model.js.map +1 -0
- package/dist/src/platform-x/routes/index.js +19 -0
- package/dist/src/platform-x/routes/index.js.map +1 -0
- package/dist/src/platform-x/services/cron.services.js +117 -0
- package/dist/src/platform-x/services/cron.services.js.map +1 -0
- package/dist/src/platform-x/util/emailHandler.js +53 -137
- package/dist/src/platform-x/util/emailHandler.js.map +1 -0
- package/dist/src/platform-x/util/emailTemplate.js +63 -60
- package/dist/src/platform-x/util/emailTemplate.js.map +1 -0
- package/dist/src/platform-x/util/solr-data-source/SolrHttpDataSource.js +2 -0
- package/dist/src/platform-x/util/solr-data-source/SolrHttpDataSource.js.map +1 -0
- package/dist/src/server.js +38 -0
- package/dist/src/server.js.map +1 -0
- package/dist/swagger.json +247 -0
- package/dist/test/controllers/common_controller.spec.js +79 -0
- package/dist/test/controllers/common_controller.spec.js.map +1 -0
- package/dist/test/middleware/commonMiddleware.spec.js +88 -0
- package/dist/test/middleware/commonMiddleware.spec.js.map +1 -0
- package/dist/test/platform-x/controllers/graphRESTControllers.spec.js +195 -0
- package/dist/test/platform-x/controllers/graphRESTControllers.spec.js.map +1 -0
- package/dist/test/platform-x/datasource/emailDataSource.spec.js +81 -0
- package/dist/test/platform-x/datasource/emailDataSource.spec.js.map +1 -0
- package/dist/test/platform-x/util/emailHandler.spec.js +474 -0
- package/dist/test/platform-x/util/emailHandler.spec.js.map +1 -0
- package/dist/test/platform-x/util/solr-data-source/SolrHttpDataSource.spec.js +80 -0
- package/dist/test/platform-x/util/solr-data-source/SolrHttpDataSource.spec.js.map +1 -0
- package/dist/test/services/requestService.spec.js +108 -0
- package/dist/test/services/requestService.spec.js.map +1 -0
- package/dist/test/services/requestServiceGet.spec.js +43 -0
- package/dist/test/services/requestServiceGet.spec.js.map +1 -0
- package/dist/test/src/common/service/twilioService.spec.js +65 -0
- package/dist/test/src/common/service/twilioService.spec.js.map +1 -0
- package/dist/test/util/commonUtil.spec.js +110 -0
- package/dist/test/util/commonUtil.spec.js.map +1 -0
- package/dist/test/util/logger.spec.js +51 -0
- package/dist/test/util/logger.spec.js.map +1 -0
- package/dist/test/util/requestTracer.spec.js +64 -0
- package/dist/test/util/requestTracer.spec.js.map +1 -0
- package/dist/test/util/solrconnector.spec.js +145 -0
- package/dist/test/util/solrconnector.spec.js.map +1 -0
- package/package.json +66 -62
- package/postman_collection/HEP_Environment.postman_environment.json +44 -44
- package/postman_collection/hep-notification.postman_collection.json +55 -55
- package/reports/output.jtl +1 -1
- package/reports/scripts/jmeter_sendgrid.js +34 -34
- package/reports/scripts/newman_sendgrid.js +40 -40
- package/reports/scripts/sendgrid.js +40 -40
- package/reports/scripts/trivy_sendgrid.js +40 -40
- package/src/common/service/requestService.ts +87 -0
- package/{dist/src/common/service/secretKeyManager.services.js → src/common/service/secretKeyManager.services.ts} +1 -2
- package/src/common/service/twilioService.ts +58 -0
- package/src/common/util/commonUtil.ts +39 -0
- package/src/common/util/errorHandler.ts +120 -0
- package/src/common/util/logger.ts +215 -0
- package/src/common/util/requestTracer.ts +10 -0
- package/src/common/util/solrConnector.ts +319 -0
- package/src/config/index.ts +35 -0
- package/src/index.ts +34 -0
- package/src/platform-x/constants/index.ts +20 -0
- package/src/platform-x/constants/style.ts +99 -0
- package/src/platform-x/dataSource/emailDataSource.ts +34 -0
- package/src/platform-x/database/connection.ts +47 -0
- package/src/platform-x/database/dao/formBuilder.dao.ts +33 -0
- package/src/platform-x/database/index.ts +7 -0
- package/src/platform-x/database/models/formBuilder.model.ts +23 -0
- package/src/platform-x/util/emailHandler.ts +580 -0
- package/src/platform-x/util/emailTemplate.ts +66 -0
- package/src/platform-x/util/solr-data-source/SolrHttpDataSource.ts +97 -0
- package/{dist → src}/templates/orderPlaced.ejs +172 -172
- package/{dist → src}/templates/orderPlaced.html +189 -189
- package/tsconfig.json +73 -0
- package/dist/src/common/service/requestService.d.ts +0 -26
- package/dist/src/common/service/secretKeyManager.services.d.ts +0 -0
- package/dist/src/common/service/twilioService.d.ts +0 -19
- package/dist/src/common/util/commonUtil.d.ts +0 -22
- package/dist/src/common/util/errorHandler.d.ts +0 -44
- package/dist/src/common/util/logger.d.ts +0 -68
- package/dist/src/common/util/requestTracer.d.ts +0 -2
- package/dist/src/common/util/secretKeyManager.d.ts +0 -7
- package/dist/src/common/util/secretKeyManager.js +0 -58
- package/dist/src/common/util/solrConnector.d.ts +0 -35
- package/dist/src/config/index.d.ts +0 -30
- package/dist/src/index.d.ts +0 -5
- package/dist/src/index.js +0 -20
- package/dist/src/platform-x/constants/index.d.ts +0 -18
- package/dist/src/platform-x/constants/style.d.ts +0 -1
- package/dist/src/platform-x/dataSource/emailDataSource.d.ts +0 -5
- package/dist/src/platform-x/database/connection.d.ts +0 -8
- package/dist/src/platform-x/database/dao/formBuilder.dao.d.ts +0 -9
- package/dist/src/platform-x/database/index.d.ts +0 -7
- package/dist/src/platform-x/database/models/formBuilder.model.d.ts +0 -34
- package/dist/src/platform-x/interface/interface.d.ts +0 -4
- package/dist/src/platform-x/util/emailHandler.d.ts +0 -62
- package/dist/src/platform-x/util/emailTemplate.d.ts +0 -4
- package/dist/src/platform-x/util/solr-data-source/SolrHttpDataSource.d.ts +0 -26
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { Logger } from '../util/logger';
|
|
3
|
+
import https from 'https';
|
|
4
|
+
import { ApiError } from '../util/errorHandler';
|
|
5
|
+
import { HTTP_CONTENT_TYPE_JSON } from '../../platform-x/constants';
|
|
6
|
+
|
|
7
|
+
interface RequestHandlerPostOptions {
|
|
8
|
+
url: string;
|
|
9
|
+
body: any;
|
|
10
|
+
options?: any;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface RequestHandlerGetOptions {
|
|
14
|
+
url: string;
|
|
15
|
+
options?: any;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class HttpRequestHandler {
|
|
19
|
+
private requestTimeout = 1000 * 30;
|
|
20
|
+
// NOSONAR-NEXT-LINE
|
|
21
|
+
constructor() {} // NOSONAR
|
|
22
|
+
/**
|
|
23
|
+
* post - handler to do post api calls
|
|
24
|
+
* @param requestConfig
|
|
25
|
+
* @returns
|
|
26
|
+
*/
|
|
27
|
+
public async post(requestConfig: RequestHandlerPostOptions) {
|
|
28
|
+
Logger.info(
|
|
29
|
+
'HttpRequestHandler: Reached post method',
|
|
30
|
+
'post'
|
|
31
|
+
);
|
|
32
|
+
const { url, body } = requestConfig;
|
|
33
|
+
const defaultOptions = {
|
|
34
|
+
headers: {
|
|
35
|
+
'Content-Type': HTTP_CONTENT_TYPE_JSON,
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
let options = requestConfig.options || defaultOptions;
|
|
39
|
+
options.httpsAgent = new https.Agent({
|
|
40
|
+
rejectUnauthorized: true,
|
|
41
|
+
});
|
|
42
|
+
if (!options.headers) {
|
|
43
|
+
options.headers = {};
|
|
44
|
+
}
|
|
45
|
+
options.timeout = this.requestTimeout;
|
|
46
|
+
return axios
|
|
47
|
+
.post(url, body, options)
|
|
48
|
+
.then((res: any) => {
|
|
49
|
+
Logger.info('HttpRequestHandler: Successfull Response', 'post');
|
|
50
|
+
return res.data;
|
|
51
|
+
})
|
|
52
|
+
.catch((err: any) => {
|
|
53
|
+
let apiError = new ApiError(err.message, err.response?.status);
|
|
54
|
+
Logger.error('HttpRequestHandler: Error in post', 'post', err);
|
|
55
|
+
throw apiError;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* get - handler to do get api calls
|
|
60
|
+
* @param requestConfig
|
|
61
|
+
* @returns
|
|
62
|
+
*/
|
|
63
|
+
public async get(requestConfig: RequestHandlerGetOptions) {
|
|
64
|
+
Logger.info('HttpRequestHandler: Reached get method', 'get');
|
|
65
|
+
const { url } = requestConfig;
|
|
66
|
+
const defaultOptions = {};
|
|
67
|
+
let options = requestConfig.options || defaultOptions;
|
|
68
|
+
options.httpsAgent = new https.Agent({
|
|
69
|
+
rejectUnauthorized: true,
|
|
70
|
+
});
|
|
71
|
+
if (!options.headers) {
|
|
72
|
+
options.headers = {};
|
|
73
|
+
}
|
|
74
|
+
options.timeout = this.requestTimeout;
|
|
75
|
+
return axios
|
|
76
|
+
.get(url, options)
|
|
77
|
+
.then((res: any) => {
|
|
78
|
+
Logger.info('HttpRequestHandler: Successfull Response', 'get');
|
|
79
|
+
return res.data;
|
|
80
|
+
})
|
|
81
|
+
.catch((err: any) => {
|
|
82
|
+
let apiError = new ApiError(err.message, err.response?.status);
|
|
83
|
+
Logger.error('HttpRequestHandler: Error in get', 'get', err);
|
|
84
|
+
throw apiError;
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
// import { secretManager } from 'hep-secret-access';
|
|
3
2
|
// import config from '../../config';
|
|
4
3
|
// import { DynamicValues } from '../../platform-x/constants';
|
|
4
|
+
|
|
5
5
|
// export class SecretKeyServices {
|
|
6
6
|
// private ruleCache = new Map<string, any | null>();
|
|
7
7
|
// /**
|
|
@@ -35,4 +35,3 @@
|
|
|
35
35
|
// }
|
|
36
36
|
// }
|
|
37
37
|
// }
|
|
38
|
-
//# sourceMappingURL=secretKeyManager.services.js.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import twilio from 'twilio';
|
|
2
|
+
import { Logger } from '../util/logger';
|
|
3
|
+
import { DynamicValues } from '../../platform-x/constants';
|
|
4
|
+
import { getIAMSecrets } from '../..';
|
|
5
|
+
|
|
6
|
+
export class TwilioService {
|
|
7
|
+
private client: twilio.Twilio;
|
|
8
|
+
private senderNumber: string;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Constructor to initialize Twilio client and sender number
|
|
12
|
+
* @param accountSid - Twilio Account SID
|
|
13
|
+
* @param authToken - Twilio Auth Token
|
|
14
|
+
* @param senderNumber - Twilio Sender Phone Number
|
|
15
|
+
*/
|
|
16
|
+
private constructor(twilioConfig: any) {
|
|
17
|
+
this.client = twilio(twilioConfig?.[DynamicValues?.TWILIO_ACCOUNT_SID], twilioConfig?.[DynamicValues?.TWILIO_AUTH_TOKEN]);
|
|
18
|
+
this.senderNumber = twilioConfig?.[DynamicValues?.TWILIO_SENDER_NUMBER];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
static async TwilioClassObject() {
|
|
22
|
+
const secrets = await getIAMSecrets();
|
|
23
|
+
return new TwilioService(secrets);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Send an SMS using Twilio
|
|
28
|
+
* @param to - Recipient's phone number
|
|
29
|
+
* @param message - Message content
|
|
30
|
+
* @returns Promise resolving with the Twilio response
|
|
31
|
+
*/
|
|
32
|
+
async sendSMS(to: string, message: string) {
|
|
33
|
+
Logger.info(
|
|
34
|
+
'twilioService: Reached sendSMS',
|
|
35
|
+
'sendSMS'
|
|
36
|
+
);
|
|
37
|
+
Logger.debug(
|
|
38
|
+
'twilioService: check message and recipient number',
|
|
39
|
+
'sendSMS',
|
|
40
|
+
{to, message}
|
|
41
|
+
);
|
|
42
|
+
try {
|
|
43
|
+
const response = await this.client.messages.create({
|
|
44
|
+
body: message,
|
|
45
|
+
from: this.senderNumber,
|
|
46
|
+
to,
|
|
47
|
+
});
|
|
48
|
+
return response;
|
|
49
|
+
} catch (error) {
|
|
50
|
+
Logger.error(
|
|
51
|
+
'twilioService: error in send SMS by twilio',
|
|
52
|
+
'sendSMS',
|
|
53
|
+
error
|
|
54
|
+
);
|
|
55
|
+
throw new Error('Failed to send SMS');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { throwError } from "./errorHandler";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Validate a phone number for format and length
|
|
5
|
+
* @param phoneNumber
|
|
6
|
+
* @returns
|
|
7
|
+
*/
|
|
8
|
+
export const validatePhoneNumber = (phoneNumber: string): boolean => {
|
|
9
|
+
// Regular expression for validating international phone numbers
|
|
10
|
+
const phoneRegex = /^\+?[1-9]\d{1,14}$/; // E.164 format
|
|
11
|
+
return phoneRegex?.test(phoneNumber);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Validate a message for length and content
|
|
16
|
+
* @param message
|
|
17
|
+
* @returns
|
|
18
|
+
*/
|
|
19
|
+
export const validateMessage = (message: string): boolean => {
|
|
20
|
+
const maxLength:number = 250; // Standard SMS max length
|
|
21
|
+
return message?.trim()?.length > 0 && message?.length <= maxLength;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Validate both phone number and message
|
|
26
|
+
* @param phoneNumber
|
|
27
|
+
* @param message
|
|
28
|
+
* @returns
|
|
29
|
+
*/
|
|
30
|
+
export const validate = (phoneNumber: string, message: string): { valid: boolean; errors: any } => {
|
|
31
|
+
const errors: any = [];
|
|
32
|
+
if (!validatePhoneNumber(phoneNumber)) {
|
|
33
|
+
throwError('Invalid phone number format. Ensure it follows +915647374757 like this.');
|
|
34
|
+
}
|
|
35
|
+
if (!validateMessage(message)) {
|
|
36
|
+
throwError('Message must be between 1 and 250 characters.');
|
|
37
|
+
}
|
|
38
|
+
return {valid:true, errors:''};
|
|
39
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
export const enum HTTP_STATUS_CODE {
|
|
2
|
+
INTERNAL_SERVER_ERROR=500
|
|
3
|
+
}
|
|
4
|
+
export const HTTP_STATUS_MAP = new Map([
|
|
5
|
+
[500, 'Internal Server Error']
|
|
6
|
+
]);
|
|
7
|
+
export const enum HTTP_STATUS_TYPE {
|
|
8
|
+
INTERNAL_SERVER_ERROR='Internal Server Error'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class CommonErrorTemplate extends Error {
|
|
12
|
+
public code: number;
|
|
13
|
+
public type: string;
|
|
14
|
+
|
|
15
|
+
constructor(msg: string, code?: number) {
|
|
16
|
+
super(msg);
|
|
17
|
+
this.code = code || HTTP_STATUS_CODE.INTERNAL_SERVER_ERROR;
|
|
18
|
+
this.type =
|
|
19
|
+
HTTP_STATUS_MAP.get(this.code) || HTTP_STATUS_TYPE.INTERNAL_SERVER_ERROR;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public toJSON() {
|
|
23
|
+
return {
|
|
24
|
+
code: this.code,
|
|
25
|
+
type: this.type,
|
|
26
|
+
message: this.message,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export class ApiError extends CommonErrorTemplate {
|
|
32
|
+
constructor(msg: string, code?: number) {
|
|
33
|
+
super(msg, code);
|
|
34
|
+
this.name = 'ApiError';
|
|
35
|
+
Error.captureStackTrace(this, ApiError);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export class SolrError extends CommonErrorTemplate {
|
|
40
|
+
constructor(msg: string, code?: number) {
|
|
41
|
+
super(msg, code);
|
|
42
|
+
this.name = 'SolrError';
|
|
43
|
+
Error.captureStackTrace(this, SolrError);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export class CustomError {
|
|
48
|
+
public code!: number | undefined;
|
|
49
|
+
public type!: string | undefined;
|
|
50
|
+
public message!: string | undefined;
|
|
51
|
+
public stack!: string | undefined;
|
|
52
|
+
public errorObj: Error | undefined | null;
|
|
53
|
+
|
|
54
|
+
constructor(
|
|
55
|
+
errObj?: any,
|
|
56
|
+
code?: number,
|
|
57
|
+
type?: string,
|
|
58
|
+
message?: string,
|
|
59
|
+
stack?: string
|
|
60
|
+
) {
|
|
61
|
+
this.code = code;
|
|
62
|
+
this.type = type;
|
|
63
|
+
this.message = message;
|
|
64
|
+
this.stack = stack;
|
|
65
|
+
this.errorObj = errObj;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public toJSON() {
|
|
69
|
+
// NOSONAR
|
|
70
|
+
return {
|
|
71
|
+
code: this.code,
|
|
72
|
+
type: this.type,
|
|
73
|
+
message: this.message,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* errorMapper - to map error object to custom error
|
|
79
|
+
*/
|
|
80
|
+
export const errorMapper = (err: any, statusCode?: number, type?: string) => {
|
|
81
|
+
let error!: any;
|
|
82
|
+
let customError: CustomError;
|
|
83
|
+
let code: number = statusCode || HTTP_STATUS_CODE.INTERNAL_SERVER_ERROR;
|
|
84
|
+
let errorType: string =
|
|
85
|
+
type || HTTP_STATUS_MAP.get(code) || HTTP_STATUS_TYPE.INTERNAL_SERVER_ERROR;
|
|
86
|
+
|
|
87
|
+
if (typeof err === 'string') {
|
|
88
|
+
error = new Error(err);
|
|
89
|
+
customError = new CustomError(
|
|
90
|
+
null,
|
|
91
|
+
code,
|
|
92
|
+
errorType,
|
|
93
|
+
error.message,
|
|
94
|
+
error.stack
|
|
95
|
+
);
|
|
96
|
+
return customError;
|
|
97
|
+
} else if (
|
|
98
|
+
err.stack &&
|
|
99
|
+
err.message &&
|
|
100
|
+
!(err instanceof CustomError) &&
|
|
101
|
+
!err.toJSON
|
|
102
|
+
) {
|
|
103
|
+
customError = new CustomError(
|
|
104
|
+
null,
|
|
105
|
+
code,
|
|
106
|
+
errorType,
|
|
107
|
+
err.message,
|
|
108
|
+
err.stack
|
|
109
|
+
);
|
|
110
|
+
return customError;
|
|
111
|
+
} else {
|
|
112
|
+
return err;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* throwError - to throw custome error
|
|
117
|
+
*/
|
|
118
|
+
export const throwError = (err: any, statusCode?: number, type?: string) => {
|
|
119
|
+
throw errorMapper(err, statusCode, type);
|
|
120
|
+
};
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import bunyan from 'bunyan';
|
|
2
|
+
import config from '../../config/index';
|
|
3
|
+
import bformat from 'bunyan-format';
|
|
4
|
+
import { getTraceId, getSpanId } from './requestTracer';
|
|
5
|
+
import _ from 'lodash';
|
|
6
|
+
export interface payLoadInterface {
|
|
7
|
+
statusCode?: number;
|
|
8
|
+
data?: any;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface LoggerInterface {
|
|
12
|
+
info(message: string, method: string): void;
|
|
13
|
+
warn(message: string, method: string, payload?: object): void;
|
|
14
|
+
error(message: string, method: string, payload?: object): void;
|
|
15
|
+
debug(message: string, method: string, payload?: object): void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class LoggerClass implements LoggerInterface {
|
|
19
|
+
private logger: bunyan;
|
|
20
|
+
private infoLevel: boolean = false;
|
|
21
|
+
private debugLevel: boolean = false;
|
|
22
|
+
private errorLevel: boolean = false;
|
|
23
|
+
private warnLevel: boolean = false;
|
|
24
|
+
private blockedKeywords = ['currentPassword', 'clientSecret', 'newPassword'];
|
|
25
|
+
|
|
26
|
+
constructor() {
|
|
27
|
+
this.mapLogLevels();
|
|
28
|
+
this.logger = bunyan.createLogger({
|
|
29
|
+
name: config.APP_NAME,
|
|
30
|
+
level: 'trace', // by default enabling all levels, controlled through env separately
|
|
31
|
+
stream: bformat({
|
|
32
|
+
outputMode: config.NODE_ENV === 'development' ? 'short' : 'bunyan',
|
|
33
|
+
levelInString: true,
|
|
34
|
+
color: true,
|
|
35
|
+
}),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* It's written to handle JSON.circular error
|
|
40
|
+
* @param obj
|
|
41
|
+
* @returns
|
|
42
|
+
*/
|
|
43
|
+
public customstringify(obj: any) {
|
|
44
|
+
let cache: any = [];
|
|
45
|
+
let str = JSON.stringify(obj, (key, value) => {
|
|
46
|
+
{
|
|
47
|
+
if (typeof value === 'object' && value !== null) {
|
|
48
|
+
if (cache.indexOf(value) !== -1) {
|
|
49
|
+
// Circular reference found, discard key
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
// Store value in our collection
|
|
53
|
+
cache.push(value);
|
|
54
|
+
}
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
cache = null; // reset the cache
|
|
59
|
+
return str;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* for info log
|
|
63
|
+
* @param message
|
|
64
|
+
* @param payload
|
|
65
|
+
* @param method
|
|
66
|
+
* @returns
|
|
67
|
+
*/
|
|
68
|
+
public info(message: string, method: string) {
|
|
69
|
+
if (!this.infoLevel) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
let loggerParams = {
|
|
73
|
+
message,
|
|
74
|
+
method,
|
|
75
|
+
traceId: getTraceId(),
|
|
76
|
+
};
|
|
77
|
+
this.logger.info(` start ${JSON.stringify(loggerParams)} ==end`);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* for warn log
|
|
81
|
+
* @param message
|
|
82
|
+
* @param payload
|
|
83
|
+
* @param method
|
|
84
|
+
* @returns
|
|
85
|
+
*/
|
|
86
|
+
public warn(message: string, method: string, payload?: any) {
|
|
87
|
+
if (!this.warnLevel) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
let loggerParams = {
|
|
91
|
+
message,
|
|
92
|
+
method,
|
|
93
|
+
traceId: getTraceId(),
|
|
94
|
+
statusCode: payload?.statusCode,
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
let finalPayload = payload !== undefined ? payload : {};
|
|
98
|
+
this.logger.warn(
|
|
99
|
+
` start ${JSON.stringify(loggerParams)} payload: ${this.customstringify(
|
|
100
|
+
this.sanitizeLog(finalPayload)
|
|
101
|
+
)}==end`
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* for error log
|
|
106
|
+
* @param message
|
|
107
|
+
* @param payload
|
|
108
|
+
* @param method
|
|
109
|
+
* @returns
|
|
110
|
+
*/
|
|
111
|
+
public error(message: string, method: string, payload?: any) {
|
|
112
|
+
if (!this.errorLevel) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (payload instanceof Error) {
|
|
117
|
+
payload = {
|
|
118
|
+
message,
|
|
119
|
+
method,
|
|
120
|
+
traceId: getTraceId(),
|
|
121
|
+
stack: payload?.stack,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
let loggerParams = {
|
|
125
|
+
message,
|
|
126
|
+
method,
|
|
127
|
+
traceId: getTraceId(),
|
|
128
|
+
spanId: getSpanId(),
|
|
129
|
+
statusCode: payload?.statusCode,
|
|
130
|
+
};
|
|
131
|
+
let finalPayload = payload !== undefined ? payload : {};
|
|
132
|
+
this.logger.error(
|
|
133
|
+
` start ${JSON.stringify(loggerParams)} payload: ${this.customstringify(
|
|
134
|
+
this.sanitizeLog(finalPayload)
|
|
135
|
+
)}==end`
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* for debug log
|
|
140
|
+
* @param message
|
|
141
|
+
* @param payload
|
|
142
|
+
* @param method
|
|
143
|
+
* @returns
|
|
144
|
+
*/
|
|
145
|
+
public debug(message: string, method: string, payload?: any) {
|
|
146
|
+
if (!this.debugLevel) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
let loggerParams = {
|
|
151
|
+
message,
|
|
152
|
+
method,
|
|
153
|
+
traceId: getTraceId(),
|
|
154
|
+
statusCode: payload?.statusCode,
|
|
155
|
+
};
|
|
156
|
+
let finalPayload = payload !== undefined ? payload : {};
|
|
157
|
+
this.logger.debug(
|
|
158
|
+
` start ${JSON.stringify(loggerParams)} payload: ${this.customstringify(
|
|
159
|
+
this.sanitizeLog(finalPayload)
|
|
160
|
+
)}==end`
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* to map log levels and handle from config
|
|
165
|
+
*/
|
|
166
|
+
private mapLogLevels() {
|
|
167
|
+
if (config.LOG_LEVELS.length) {
|
|
168
|
+
config.LOG_LEVELS.forEach((element: string) => {
|
|
169
|
+
const logLevel = element.trim();
|
|
170
|
+
if (logLevel === 'info') {
|
|
171
|
+
this.infoLevel = true;
|
|
172
|
+
} else if (logLevel === 'debug') {
|
|
173
|
+
this.debugLevel = true;
|
|
174
|
+
} else if (logLevel === 'error') {
|
|
175
|
+
this.errorLevel = true;
|
|
176
|
+
} else if (logLevel === 'warn') {
|
|
177
|
+
this.warnLevel = true;
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* to sanitize logs from unwanted fields to be shown
|
|
184
|
+
* @param request
|
|
185
|
+
* @returns
|
|
186
|
+
*/
|
|
187
|
+
private sanitizeLog(request: any) {
|
|
188
|
+
try {
|
|
189
|
+
if (request) {
|
|
190
|
+
Object.keys(request).forEach((key) => {
|
|
191
|
+
let value = request[key];
|
|
192
|
+
if (request[key] === 'options') {
|
|
193
|
+
delete request.options;
|
|
194
|
+
} else {
|
|
195
|
+
if (
|
|
196
|
+
this.blockedKeywords.find(
|
|
197
|
+
(blockedKey: any) =>
|
|
198
|
+
key.toLowerCase() === blockedKey.toLowerCase()
|
|
199
|
+
)
|
|
200
|
+
) {
|
|
201
|
+
request[key] = 'XXXXXXXXXX';
|
|
202
|
+
} else {
|
|
203
|
+
request[key] = value;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
return request;
|
|
208
|
+
}
|
|
209
|
+
} catch (err: any) {
|
|
210
|
+
this.error('Logger sanitize error', err);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export const Logger = new LoggerClass();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import cls from 'cls-hooked';
|
|
2
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
+
|
|
4
|
+
const nsid = `rtracer:${uuidv4()}`;
|
|
5
|
+
const ns = cls.createNamespace(nsid);
|
|
6
|
+
const traceIdKey = 'traceId';
|
|
7
|
+
const spanIdKey = 'spanId';
|
|
8
|
+
|
|
9
|
+
export const getTraceId = () => ns.get(traceIdKey);
|
|
10
|
+
export const getSpanId = () => ns.get(spanIdKey);
|