sm-utility 1.0.3 → 1.1.0
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/general/index.d.ts +1 -0
- package/general/index.js +24 -1
- package/logger/index.d.ts +6 -0
- package/logger/index.js +90 -0
- package/logger/types.d.ts +7 -0
- package/logger/types.js +2 -0
- package/package.json +8 -3
- package/request/index.d.ts +2 -0
- package/request/index.js +59 -0
- package/middleware/index.d.ts +0 -7
- package/middleware/index.js +0 -85
package/general/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export declare function pipe(...fns: Array<Function>): any;
|
|
2
2
|
export declare function randomSixDigitNumber(): number;
|
|
3
3
|
export declare function timeout(ms: number): Promise<any>;
|
|
4
|
+
export declare function mergeDeep(target: Record<string, any>, source: Record<string, any>): Record<string, any>;
|
package/general/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.timeout = exports.randomSixDigitNumber = exports.pipe = void 0;
|
|
3
|
+
exports.mergeDeep = exports.timeout = exports.randomSixDigitNumber = exports.pipe = void 0;
|
|
4
4
|
function pipe() {
|
|
5
5
|
var fns = [];
|
|
6
6
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
@@ -17,3 +17,26 @@ function timeout(ms) {
|
|
|
17
17
|
return new Promise(function (resolve) { return setTimeout(resolve, ms); });
|
|
18
18
|
}
|
|
19
19
|
exports.timeout = timeout;
|
|
20
|
+
function isObject(obj) {
|
|
21
|
+
return !!obj && obj.constructor === Object;
|
|
22
|
+
}
|
|
23
|
+
function mergeDeep(target, source) {
|
|
24
|
+
if (!isObject(target) || !isObject(source)) {
|
|
25
|
+
return source;
|
|
26
|
+
}
|
|
27
|
+
Object.keys(source).forEach(function (key) {
|
|
28
|
+
var targetValue = target[key];
|
|
29
|
+
var sourceValue = source[key];
|
|
30
|
+
if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {
|
|
31
|
+
target[key] = targetValue.concat(sourceValue);
|
|
32
|
+
}
|
|
33
|
+
else if (isObject(targetValue) && isObject(sourceValue)) {
|
|
34
|
+
target[key] = mergeDeep(Object.assign({}, targetValue), sourceValue);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
target[key] = sourceValue;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
return target;
|
|
41
|
+
}
|
|
42
|
+
exports.mergeDeep = mergeDeep;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/// <reference types="express" />
|
|
2
|
+
/// <reference types="qs" />
|
|
3
|
+
import winston from "winston";
|
|
4
|
+
export declare const loggerMiddleware: import("express").Handler;
|
|
5
|
+
export declare const logError: import("express").ErrorRequestHandler<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
|
|
6
|
+
export declare const logger: winston.Logger;
|
package/logger/index.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
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.logger = exports.logError = exports.loggerMiddleware = void 0;
|
|
7
|
+
var process_1 = require("process");
|
|
8
|
+
var winston_1 = __importDefault(require("winston"));
|
|
9
|
+
var express_winston_1 = __importDefault(require("express-winston"));
|
|
10
|
+
var configs;
|
|
11
|
+
try {
|
|
12
|
+
configs = require(process_1.cwd() + "/logger.config");
|
|
13
|
+
}
|
|
14
|
+
catch (_a) {
|
|
15
|
+
throw Error('Logger configs could not be found on app root\'s directory.');
|
|
16
|
+
}
|
|
17
|
+
function formatReqResLog(info) {
|
|
18
|
+
var level = info.level, _a = info.meta, req = _a.req, res = _a.res, responseTime = _a.responseTime;
|
|
19
|
+
var logData = Object.assign({}, { req: req, res: res, responseTime: responseTime + "ms" });
|
|
20
|
+
return level + " - [" + req.method + "] " + req.url + ": " + JSON.stringify(logData);
|
|
21
|
+
}
|
|
22
|
+
function filterRequestHeaders(confidentialHeaders) {
|
|
23
|
+
if (confidentialHeaders === void 0) { confidentialHeaders = []; }
|
|
24
|
+
return function (req, propName) {
|
|
25
|
+
if (propName !== "headers")
|
|
26
|
+
return req[propName];
|
|
27
|
+
var filteredHeaders = Object.keys(req.headers)
|
|
28
|
+
.filter(function (key) { return !confidentialHeaders.includes(key); })
|
|
29
|
+
.reduce(function (acc, key) {
|
|
30
|
+
acc[key] = req.headers[key];
|
|
31
|
+
return acc;
|
|
32
|
+
}, {});
|
|
33
|
+
return filteredHeaders;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
var routeFilter = function (req, res) {
|
|
37
|
+
var url = req.url;
|
|
38
|
+
var shouldRouteBeFiltered = shouldFilterRoute(url);
|
|
39
|
+
return shouldRouteBeFiltered;
|
|
40
|
+
};
|
|
41
|
+
function shouldFilterRoute(url) {
|
|
42
|
+
var routesToBeFiltered = configs.ignoredRoutes || [];
|
|
43
|
+
var shouldRouteBeFiltered = routesToBeFiltered.some(function (route) {
|
|
44
|
+
var splitedRouteParts = getSplitedRouteParts(route);
|
|
45
|
+
return splitedRouteParts.every(function (part) { return url.toLowerCase().indexOf(part) > -1; });
|
|
46
|
+
});
|
|
47
|
+
return shouldRouteBeFiltered;
|
|
48
|
+
}
|
|
49
|
+
function getSplitedRouteParts(route) {
|
|
50
|
+
var routeParts = route.split('/');
|
|
51
|
+
var filteredParts = routeParts.filter(function (part) {
|
|
52
|
+
var firstChar = part === null || part === void 0 ? void 0 : part.charAt(0);
|
|
53
|
+
return firstChar !== ":" && firstChar !== '';
|
|
54
|
+
});
|
|
55
|
+
return filteredParts;
|
|
56
|
+
}
|
|
57
|
+
function createLoggerMiddleware() {
|
|
58
|
+
express_winston_1.default.requestWhitelist.push("body");
|
|
59
|
+
express_winston_1.default.responseWhitelist.push("body");
|
|
60
|
+
return express_winston_1.default.logger({
|
|
61
|
+
statusLevels: true,
|
|
62
|
+
transports: [
|
|
63
|
+
new winston_1.default.transports.Console(configs.console),
|
|
64
|
+
],
|
|
65
|
+
requestFilter: filterRequestHeaders(configs.confidentialHeaders || []),
|
|
66
|
+
ignoreRoute: routeFilter,
|
|
67
|
+
format: winston_1.default.format.combine(winston_1.default.format.colorize(), winston_1.default.format.printf(formatReqResLog))
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
function createErrorLoggerMiddleware() {
|
|
71
|
+
return express_winston_1.default.errorLogger({
|
|
72
|
+
transports: [
|
|
73
|
+
new winston_1.default.transports.Console(configs.console)
|
|
74
|
+
],
|
|
75
|
+
requestFilter: filterRequestHeaders(configs.confidentialHeaders || []),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
exports.loggerMiddleware = createLoggerMiddleware();
|
|
79
|
+
exports.logError = createErrorLoggerMiddleware();
|
|
80
|
+
exports.logger = winston_1.default.createLogger({
|
|
81
|
+
transports: [
|
|
82
|
+
new winston_1.default.transports.Console(configs.console)
|
|
83
|
+
],
|
|
84
|
+
exitOnError: false,
|
|
85
|
+
});
|
|
86
|
+
exports.logger.stream = Object.assign(exports.logger.stream, {
|
|
87
|
+
write: function (message) {
|
|
88
|
+
exports.logger.info(JSON.parse(message));
|
|
89
|
+
},
|
|
90
|
+
});
|
package/logger/types.js
ADDED
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sm-utility",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "reusable utility codes for sm projects",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"clean": "rm -rf general/ date/ string/ array/
|
|
8
|
+
"clean": "rm -rf general/ date/ string/ array/ logger/ request/",
|
|
9
9
|
"build": "npm run clean && tsc",
|
|
10
10
|
"prepare": "npm run build",
|
|
11
11
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
@@ -17,15 +17,20 @@
|
|
|
17
17
|
"/date",
|
|
18
18
|
"/string",
|
|
19
19
|
"/array",
|
|
20
|
-
"/
|
|
20
|
+
"/logger",
|
|
21
|
+
"/request",
|
|
22
|
+
"/typings"
|
|
21
23
|
],
|
|
22
24
|
"devDependencies": {
|
|
23
25
|
"@types/express": "^4.17.11",
|
|
24
26
|
"@types/node": "^14.14.40",
|
|
27
|
+
"@types/uuid": "^8.3.1",
|
|
25
28
|
"typescript": "^4.2.4"
|
|
26
29
|
},
|
|
27
30
|
"dependencies": {
|
|
31
|
+
"axios": "^0.23.0",
|
|
28
32
|
"express-winston": "^4.1.0",
|
|
33
|
+
"uuid": "^8.3.2",
|
|
29
34
|
"winston": "^3.3.3"
|
|
30
35
|
}
|
|
31
36
|
}
|
package/request/index.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
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.createApi = void 0;
|
|
7
|
+
var axios_1 = __importDefault(require("axios"));
|
|
8
|
+
var uuid_1 = require("uuid");
|
|
9
|
+
function createApi(config) {
|
|
10
|
+
var axiosApi = axios_1.default.create(config);
|
|
11
|
+
axiosApi.interceptors.request.use(function (request) {
|
|
12
|
+
var url = request.url, data = request.data, params = request.params, method = request.method;
|
|
13
|
+
request.meta = request.meta || {};
|
|
14
|
+
request.meta.requestId = uuid_1.v4();
|
|
15
|
+
request.meta.requestStartedAt = new Date().getTime();
|
|
16
|
+
logApiInfo(request.meta.requestId, 'Request', method, url, {
|
|
17
|
+
data: data,
|
|
18
|
+
params: params,
|
|
19
|
+
});
|
|
20
|
+
return request;
|
|
21
|
+
});
|
|
22
|
+
axiosApi.interceptors.response.use(function (response) {
|
|
23
|
+
var status = response.status, data = response.data, config = response.config;
|
|
24
|
+
var method = config.method, url = config.url, meta = config.meta;
|
|
25
|
+
var responseTime = getResponseTimeFromConfig(config);
|
|
26
|
+
logApiInfo(meta === null || meta === void 0 ? void 0 : meta.requestId, 'Response', method, url, {
|
|
27
|
+
status: status,
|
|
28
|
+
data: data,
|
|
29
|
+
responseTime: responseTime,
|
|
30
|
+
});
|
|
31
|
+
return response;
|
|
32
|
+
}, function (error) {
|
|
33
|
+
var config = error.config, message = error.message, response = error.response;
|
|
34
|
+
var method = config.method, url = config.url, meta = config.meta;
|
|
35
|
+
var responseTime = getResponseTimeFromConfig(config);
|
|
36
|
+
logApiInfo(meta === null || meta === void 0 ? void 0 : meta.requestId, 'Error', method, url, {
|
|
37
|
+
status: response === null || response === void 0 ? void 0 : response.status,
|
|
38
|
+
message: message,
|
|
39
|
+
data: response === null || response === void 0 ? void 0 : response.data,
|
|
40
|
+
responseTime: responseTime,
|
|
41
|
+
});
|
|
42
|
+
return error;
|
|
43
|
+
});
|
|
44
|
+
return axiosApi;
|
|
45
|
+
}
|
|
46
|
+
exports.createApi = createApi;
|
|
47
|
+
function logApiInfo(id, title, method, url, content) {
|
|
48
|
+
var formattedLog = "(" + title + ") " + id + " - [" + (method === null || method === void 0 ? void 0 : method.toUpperCase()) + "] " + url + ": " + JSON.stringify(content);
|
|
49
|
+
console.log(formattedLog);
|
|
50
|
+
}
|
|
51
|
+
function getResponseTimeFromConfig(config) {
|
|
52
|
+
var _a;
|
|
53
|
+
var requestStart = (_a = config === null || config === void 0 ? void 0 : config.meta) === null || _a === void 0 ? void 0 : _a.requestStartedAt;
|
|
54
|
+
var responseTime = '-';
|
|
55
|
+
if (requestStart) {
|
|
56
|
+
responseTime = String(new Date().getTime() - requestStart);
|
|
57
|
+
}
|
|
58
|
+
return responseTime + ' ms';
|
|
59
|
+
}
|
package/middleware/index.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/// <reference types="express" />
|
|
2
|
-
/// <reference types="qs" />
|
|
3
|
-
import winston from "winston";
|
|
4
|
-
declare function createLoggerMiddleware(confidentialHeaders?: string[]): import("express").Handler;
|
|
5
|
-
declare function createErrorLoggerMiddleware(confidentialHeaders?: string[]): import("express").ErrorRequestHandler<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
|
|
6
|
-
declare const logger: winston.Logger;
|
|
7
|
-
export { logger, createLoggerMiddleware, createErrorLoggerMiddleware };
|
package/middleware/index.js
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
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.createErrorLoggerMiddleware = exports.createLoggerMiddleware = exports.logger = void 0;
|
|
7
|
-
var process_1 = require("process");
|
|
8
|
-
var winston_1 = __importDefault(require("winston"));
|
|
9
|
-
var express_winston_1 = __importDefault(require("express-winston"));
|
|
10
|
-
var configs = {
|
|
11
|
-
winston: {
|
|
12
|
-
file: {
|
|
13
|
-
level: "info",
|
|
14
|
-
filename: process_1.cwd() + "/logs/access." + process.env.NODE_ENV + ".log",
|
|
15
|
-
handleExceptions: true,
|
|
16
|
-
json: true,
|
|
17
|
-
maxsize: 5242880,
|
|
18
|
-
maxFiles: 5,
|
|
19
|
-
colorize: false,
|
|
20
|
-
},
|
|
21
|
-
console: {
|
|
22
|
-
level: "debug",
|
|
23
|
-
handleExceptions: true,
|
|
24
|
-
json: true,
|
|
25
|
-
colorize: true,
|
|
26
|
-
format: winston_1.default.format.combine(winston_1.default.format.colorize(), winston_1.default.format.printf(formatReqResLog)),
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
function formatReqResLog(info) {
|
|
31
|
-
var level = info.level, _a = info.meta, req = _a.req, res = _a.res, responseTime = _a.responseTime;
|
|
32
|
-
return level + " - [" + req.method + "] " + req.url + ": {\"req\": " + JSON.stringify(req) + ", \"res\": " + JSON.stringify(res) + ", \"responseTime\": \"" + responseTime + "ms\"}";
|
|
33
|
-
}
|
|
34
|
-
function filterRequestHeaders(confidentialHeaders) {
|
|
35
|
-
if (confidentialHeaders === void 0) { confidentialHeaders = []; }
|
|
36
|
-
return function (req, propName) {
|
|
37
|
-
if (propName !== "headers")
|
|
38
|
-
return req[propName];
|
|
39
|
-
var filteredHeaders = Object.keys(req.headers)
|
|
40
|
-
.filter(function (key) { return !confidentialHeaders.includes(key); })
|
|
41
|
-
.reduce(function (acc, key) {
|
|
42
|
-
acc[key] = req.headers[key];
|
|
43
|
-
return acc;
|
|
44
|
-
}, {});
|
|
45
|
-
return filteredHeaders;
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
function createLoggerMiddleware(confidentialHeaders) {
|
|
49
|
-
if (confidentialHeaders === void 0) { confidentialHeaders = []; }
|
|
50
|
-
express_winston_1.default.requestWhitelist.push("body");
|
|
51
|
-
express_winston_1.default.responseWhitelist.push("body");
|
|
52
|
-
return express_winston_1.default.logger({
|
|
53
|
-
statusLevels: true,
|
|
54
|
-
transports: [
|
|
55
|
-
new winston_1.default.transports.Console(configs.winston.console),
|
|
56
|
-
new winston_1.default.transports.File(configs.winston.file),
|
|
57
|
-
],
|
|
58
|
-
requestFilter: filterRequestHeaders(confidentialHeaders),
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
exports.createLoggerMiddleware = createLoggerMiddleware;
|
|
62
|
-
function createErrorLoggerMiddleware(confidentialHeaders) {
|
|
63
|
-
if (confidentialHeaders === void 0) { confidentialHeaders = []; }
|
|
64
|
-
return express_winston_1.default.errorLogger({
|
|
65
|
-
transports: [
|
|
66
|
-
new winston_1.default.transports.Console(configs.winston.console),
|
|
67
|
-
new winston_1.default.transports.File(configs.winston.file),
|
|
68
|
-
],
|
|
69
|
-
requestFilter: filterRequestHeaders(confidentialHeaders),
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
exports.createErrorLoggerMiddleware = createErrorLoggerMiddleware;
|
|
73
|
-
var logger = winston_1.default.createLogger({
|
|
74
|
-
transports: [
|
|
75
|
-
new winston_1.default.transports.Console(configs.winston.console),
|
|
76
|
-
new winston_1.default.transports.File(configs.winston.file),
|
|
77
|
-
],
|
|
78
|
-
exitOnError: false,
|
|
79
|
-
});
|
|
80
|
-
exports.logger = logger;
|
|
81
|
-
logger.stream = Object.assign(logger.stream, {
|
|
82
|
-
write: function (message) {
|
|
83
|
-
logger.info(JSON.parse(message));
|
|
84
|
-
},
|
|
85
|
-
});
|