sm-utility 2.4.21 → 2.4.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/logger/config/index.d.ts +3 -0
  2. package/logger/config/index.js +12 -0
  3. package/logger/formatters/blacklist.d.ts +2 -0
  4. package/logger/formatters/blacklist.js +36 -0
  5. package/logger/formatters/error.d.ts +2 -0
  6. package/logger/formatters/error.js +45 -0
  7. package/logger/index.d.ts +1 -1
  8. package/logger/index.js +35 -110
  9. package/logger/transports/index.d.ts +3 -0
  10. package/logger/transports/index.js +46 -0
  11. package/logger/utils/request.d.ts +3 -0
  12. package/logger/utils/request.js +22 -0
  13. package/logger/utils/route.d.ts +6 -0
  14. package/logger/utils/route.js +29 -0
  15. package/package.json +4 -2
  16. package/request/axios-custom-client.d.ts +2 -2
  17. package/request/axios-custom-client.js +5 -83
  18. package/request/index.d.ts +1 -0
  19. package/request/index.js +1 -0
  20. package/request/interceptors/error.interceptor.d.ts +2 -0
  21. package/request/interceptors/error.interceptor.js +15 -0
  22. package/request/interceptors/request.interceptor.d.ts +2 -0
  23. package/request/interceptors/request.interceptor.js +20 -0
  24. package/request/interceptors/response.interceptor.d.ts +2 -0
  25. package/request/interceptors/response.interceptor.js +19 -0
  26. package/request/loggers/error.logger.d.ts +1 -0
  27. package/request/loggers/error.logger.js +16 -0
  28. package/request/loggers/index.d.ts +3 -0
  29. package/request/loggers/index.js +19 -0
  30. package/request/loggers/request.logger.d.ts +1 -0
  31. package/request/loggers/request.logger.js +15 -0
  32. package/request/loggers/response.logger.d.ts +1 -0
  33. package/request/loggers/response.logger.js +16 -0
  34. package/request/requestExtractor.d.ts +25 -0
  35. package/request/requestExtractor.js +49 -0
  36. package/request/utils.d.ts +3 -0
  37. package/request/utils.js +19 -0
@@ -0,0 +1,3 @@
1
+ import { ILoggerConfigs } from "../types";
2
+ declare let configs: ILoggerConfigs;
3
+ export { configs };
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configs = void 0;
4
+ const process_1 = require("process");
5
+ let configs;
6
+ exports.configs = configs;
7
+ try {
8
+ exports.configs = configs = require((0, process_1.cwd)() + "/logger.config");
9
+ }
10
+ catch {
11
+ throw Error("Logger configs could not be found on app root's directory.");
12
+ }
@@ -0,0 +1,2 @@
1
+ import winston from "winston";
2
+ export declare function formatBlacklistedBody(): winston.Logform.Format;
@@ -0,0 +1,36 @@
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.formatBlacklistedBody = void 0;
7
+ const winston_1 = __importDefault(require("winston"));
8
+ const request_1 = require("../utils/request");
9
+ const route_1 = require("../utils/route");
10
+ const config_1 = require("../config");
11
+ function filterBlacklistedBodysByRoute(info) {
12
+ var _a, _b;
13
+ const blacklistedResponseRoutes = config_1.configs.responseBlacklistBodyRoutes || [];
14
+ const blacklistedRequestRoutes = config_1.configs.requestBlacklistBodyRoutes || [];
15
+ const request = info.meta.req;
16
+ const shouldResponseBeFiltered = (0, route_1.shouldRouteBeFiltered)(request, blacklistedResponseRoutes);
17
+ const shouldRequestBeFiltered = (0, route_1.shouldRouteBeFiltered)(request, blacklistedRequestRoutes);
18
+ if (shouldResponseBeFiltered) {
19
+ (_a = info.meta.res) === null || _a === void 0 ? true : delete _a.body;
20
+ }
21
+ if (shouldRequestBeFiltered) {
22
+ (_b = info.meta.req) === null || _b === void 0 ? true : delete _b.body;
23
+ }
24
+ return info;
25
+ }
26
+ function formatBlacklistedBody() {
27
+ return winston_1.default.format((info) => {
28
+ const isRequest = (0, request_1.isRequestInfo)(info);
29
+ if (isRequest) {
30
+ const filteredInfo = filterBlacklistedBodysByRoute(info);
31
+ return filteredInfo;
32
+ }
33
+ return info;
34
+ })();
35
+ }
36
+ exports.formatBlacklistedBody = formatBlacklistedBody;
@@ -0,0 +1,2 @@
1
+ import winston from "winston";
2
+ export declare const errorFormatter: winston.Logform.Format;
@@ -0,0 +1,45 @@
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.errorFormatter = void 0;
7
+ const winston_1 = __importDefault(require("winston"));
8
+ exports.errorFormatter = winston_1.default.format((info) => {
9
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
10
+ if (info.rejection) {
11
+ const error = info.error;
12
+ if (error === null || error === void 0 ? void 0 : error.isAxiosError) {
13
+ delete info.rejection;
14
+ info.error = {
15
+ message: error.message,
16
+ code: error.code,
17
+ status: (_a = error.response) === null || _a === void 0 ? void 0 : _a.status,
18
+ statusText: (_b = error.response) === null || _b === void 0 ? void 0 : _b.statusText,
19
+ url: (_c = error.config) === null || _c === void 0 ? void 0 : _c.url,
20
+ method: (_d = error.config) === null || _d === void 0 ? void 0 : _d.method,
21
+ baseURL: (_e = error.config) === null || _e === void 0 ? void 0 : _e.baseURL,
22
+ timeout: (_f = error.config) === null || _f === void 0 ? void 0 : _f.timeout,
23
+ responseData: (_g = error.response) === null || _g === void 0 ? void 0 : _g.data,
24
+ requestId: (_j = (_h = error.config) === null || _h === void 0 ? void 0 : _h.headers) === null || _j === void 0 ? void 0 : _j["x-request-id"],
25
+ };
26
+ }
27
+ return info;
28
+ }
29
+ const error = info.err || info.exception || info.error;
30
+ if (error === null || error === void 0 ? void 0 : error.isAxiosError) {
31
+ info.err = {
32
+ message: error.message,
33
+ code: error.code,
34
+ status: (_k = error.response) === null || _k === void 0 ? void 0 : _k.status,
35
+ statusText: (_l = error.response) === null || _l === void 0 ? void 0 : _l.statusText,
36
+ url: (_m = error.config) === null || _m === void 0 ? void 0 : _m.url,
37
+ method: (_o = error.config) === null || _o === void 0 ? void 0 : _o.method,
38
+ baseURL: (_p = error.config) === null || _p === void 0 ? void 0 : _p.baseURL,
39
+ timeout: (_q = error.config) === null || _q === void 0 ? void 0 : _q.timeout,
40
+ responseData: (_r = error.response) === null || _r === void 0 ? void 0 : _r.data,
41
+ requestId: (_t = (_s = error.config) === null || _s === void 0 ? void 0 : _s.headers) === null || _t === void 0 ? void 0 : _t["x-request-id"],
42
+ };
43
+ }
44
+ return info;
45
+ })();
package/logger/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /// <reference types="express" />
2
2
  /// <reference types="qs" />
3
- import winston from 'winston';
3
+ import winston from "winston";
4
4
  export declare const loggerMiddleware: import("express").Handler;
5
5
  export declare const logError: import("express").ErrorRequestHandler<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
6
6
  export declare const logger: winston.Logger;
package/logger/index.js CHANGED
@@ -4,127 +4,52 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.logger = exports.logError = exports.loggerMiddleware = void 0;
7
- const process_1 = require("process");
8
7
  const winston_1 = __importDefault(require("winston"));
9
8
  const express_winston_1 = __importDefault(require("express-winston"));
10
9
  const ecs_winston_format_1 = __importDefault(require("@elastic/ecs-winston-format"));
11
- let configs;
12
- try {
13
- configs = require((0, process_1.cwd)() + '/logger.config');
14
- }
15
- catch {
16
- throw Error("Logger configs could not be found on app root's directory.");
17
- }
18
- function filterRequestHeaders(confidentialHeaders = []) {
19
- return (req, propName) => {
20
- if (propName !== 'headers')
21
- return req[propName];
22
- const filteredHeaders = Object.keys(req.headers)
23
- .filter(key => !confidentialHeaders.includes(key))
24
- .reduce((acc, key) => {
25
- acc[key] = req.headers[key];
26
- return acc;
27
- }, {});
28
- return filteredHeaders;
29
- };
30
- }
31
- const routeFilter = (req, res) => {
32
- const { url } = req;
33
- const routesToBeFiltered = configs.ignoredRoutes || [];
34
- const shouldRouteBeFiltered = shouldFilterRoute(url, routesToBeFiltered);
35
- return shouldRouteBeFiltered;
36
- };
37
- function shouldFilterRoute(url, routesToBeFiltered) {
38
- const shouldRouteBeFiltered = routesToBeFiltered.some(route => {
39
- const regExp = generateRouteRegex(route);
40
- const matches = new String(url).match(regExp);
41
- return !!(matches === null || matches === void 0 ? void 0 : matches.length);
42
- });
43
- return shouldRouteBeFiltered;
44
- }
45
- function getTransports() {
46
- const transports = [];
47
- if (configs.console) {
48
- transports.push(new winston_1.default.transports.Console(configs.console));
49
- }
50
- if (configs.file) {
51
- transports.push(new winston_1.default.transports.File(configs.file));
52
- }
53
- return transports;
54
- }
55
- function isRequestInfo(info) {
56
- const metadata = info.meta;
57
- return (metadata === null || metadata === void 0 ? void 0 : metadata.req) && (metadata === null || metadata === void 0 ? void 0 : metadata.res) ? true : false;
58
- }
59
- function generateRouteRegex(route) {
60
- const splitedRoute = route.split('/').filter(i => i !== '');
61
- const regexString = splitedRoute
62
- .map(i => {
63
- return (i === null || i === void 0 ? void 0 : i.charAt(0)) === ':' ? '(.)+' : i;
64
- })
65
- .join('/');
66
- const regExp = new RegExp('^/' + regexString + '$', 'g');
67
- return regExp;
68
- }
69
- function shouldRouteBeFiltered(request, blacklistedRoutes) {
70
- return blacklistedRoutes.some(({ route, method }) => {
71
- const regExp = generateRouteRegex(route);
72
- const matches = new String(request.url).match(regExp);
73
- return ((matches === null || matches === void 0 ? void 0 : matches.length) && request.method.toLowerCase() === method.toLowerCase());
74
- });
75
- }
76
- function filterBlacklistedBodysByRoute(info) {
77
- var _a, _b;
78
- const blacklistedResponseRoutes = configs.responseBlacklistBodyRoutes || [];
79
- const blacklistedRequestRoutes = configs.requestBlacklistBodyRoutes || [];
80
- const request = info.meta.req;
81
- const shouldResponseBeFiltered = shouldRouteBeFiltered(request, blacklistedResponseRoutes);
82
- const shouldRequestBeFiltered = shouldRouteBeFiltered(request, blacklistedRequestRoutes);
83
- if (shouldResponseBeFiltered) {
84
- (_a = info.meta.res) === null || _a === void 0 ? true : delete _a.body;
85
- }
86
- if (shouldRequestBeFiltered) {
87
- (_b = info.meta.req) === null || _b === void 0 ? true : delete _b.body;
88
- }
89
- return info;
90
- }
91
- function formatBlacklistedBody() {
92
- return winston_1.default.format(info => {
93
- const isRequest = isRequestInfo(info);
94
- if (isRequest) {
95
- const filteredInfo = filterBlacklistedBodysByRoute(info);
96
- return filteredInfo;
97
- }
98
- return info;
99
- })();
100
- }
10
+ const config_1 = require("./config");
11
+ const error_1 = require("./formatters/error");
12
+ const blacklist_1 = require("./formatters/blacklist");
13
+ const request_1 = require("./utils/request");
14
+ const route_1 = require("./utils/route");
15
+ const transports_1 = require("./transports");
16
+ let loggerInstance = null;
101
17
  function createLoggerMiddleware() {
102
- express_winston_1.default.requestWhitelist.push('body', ...(configs.requestWhitelist || []));
103
- express_winston_1.default.responseWhitelist.push('body', ...(configs.responseWhitelist || []));
18
+ express_winston_1.default.requestWhitelist.push("body", ...(config_1.configs.requestWhitelist || []));
19
+ express_winston_1.default.responseWhitelist.push("body", ...(config_1.configs.responseWhitelist || []));
104
20
  return express_winston_1.default.logger({
105
21
  statusLevels: true,
106
- transports: getTransports(),
107
- requestFilter: filterRequestHeaders(configs.confidentialHeaders || []),
108
- ignoreRoute: routeFilter,
109
- format: winston_1.default.format.combine(formatBlacklistedBody(), (0, ecs_winston_format_1.default)({ convertReqRes: true })),
22
+ transports: (0, transports_1.getMiddlewareTransports)(),
23
+ requestFilter: (0, request_1.filterRequestHeaders)(config_1.configs.confidentialHeaders || []),
24
+ ignoreRoute: (req) => (0, route_1.shouldFilterRoute)(req.url, config_1.configs.ignoredRoutes || []),
25
+ format: winston_1.default.format.combine((0, blacklist_1.formatBlacklistedBody)(), error_1.errorFormatter, (0, ecs_winston_format_1.default)({ convertReqRes: true })),
110
26
  });
111
27
  }
112
28
  function createErrorLoggerMiddleware() {
113
29
  return express_winston_1.default.errorLogger({
114
- format: (0, ecs_winston_format_1.default)({ convertReqRes: true }),
115
- transports: getTransports(),
116
- requestFilter: filterRequestHeaders(configs.confidentialHeaders || []),
30
+ format: winston_1.default.format.combine(error_1.errorFormatter, (0, ecs_winston_format_1.default)({ convertReqRes: true })),
31
+ transports: (0, transports_1.getMiddlewareTransports)(),
32
+ requestFilter: (0, request_1.filterRequestHeaders)(config_1.configs.confidentialHeaders || []),
33
+ });
34
+ }
35
+ function createLogger() {
36
+ if (loggerInstance) {
37
+ return loggerInstance;
38
+ }
39
+ const logger = winston_1.default.createLogger({
40
+ exitOnError: false,
41
+ format: winston_1.default.format.combine(error_1.errorFormatter, (0, ecs_winston_format_1.default)({ convertReqRes: true })),
42
+ transports: (0, transports_1.getLoggerTransports)(),
43
+ });
44
+ logger.stream = Object.assign(logger.stream, {
45
+ write(message) {
46
+ logger.info(JSON.parse(message));
47
+ },
117
48
  });
49
+ loggerInstance = logger;
50
+ return logger;
118
51
  }
52
+ // Criar as instâncias uma única vez
119
53
  exports.loggerMiddleware = createLoggerMiddleware();
120
54
  exports.logError = createErrorLoggerMiddleware();
121
- exports.logger = winston_1.default.createLogger({
122
- format: (0, ecs_winston_format_1.default)({ convertReqRes: true }),
123
- transports: getTransports(),
124
- exitOnError: false,
125
- });
126
- exports.logger.stream = Object.assign(exports.logger.stream, {
127
- write(message) {
128
- exports.logger.info(JSON.parse(message));
129
- },
130
- });
55
+ exports.logger = createLogger();
@@ -0,0 +1,3 @@
1
+ import winston from "winston";
2
+ export declare function getMiddlewareTransports(): winston.transport[];
3
+ export declare function getLoggerTransports(): winston.transport[];
@@ -0,0 +1,46 @@
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.getLoggerTransports = exports.getMiddlewareTransports = void 0;
7
+ const winston_1 = __importDefault(require("winston"));
8
+ const config_1 = require("../config");
9
+ function getMiddlewareTransports() {
10
+ const transports = [];
11
+ if (config_1.configs.console) {
12
+ transports.push(new winston_1.default.transports.Console({
13
+ ...config_1.configs.console,
14
+ handleExceptions: false,
15
+ handleRejections: false,
16
+ }));
17
+ }
18
+ if (config_1.configs.file) {
19
+ transports.push(new winston_1.default.transports.File({
20
+ ...config_1.configs.file,
21
+ handleExceptions: false,
22
+ handleRejections: false,
23
+ }));
24
+ }
25
+ return transports;
26
+ }
27
+ exports.getMiddlewareTransports = getMiddlewareTransports;
28
+ function getLoggerTransports() {
29
+ const transports = [];
30
+ if (config_1.configs.console) {
31
+ transports.push(new winston_1.default.transports.Console({
32
+ handleExceptions: true,
33
+ handleRejections: true,
34
+ ...config_1.configs.console,
35
+ }));
36
+ }
37
+ if (config_1.configs.file) {
38
+ transports.push(new winston_1.default.transports.File({
39
+ handleExceptions: true,
40
+ handleRejections: true,
41
+ ...config_1.configs.file,
42
+ }));
43
+ }
44
+ return transports;
45
+ }
46
+ exports.getLoggerTransports = getLoggerTransports;
@@ -0,0 +1,3 @@
1
+ import { FilterRequest } from "express-winston";
2
+ export declare function filterRequestHeaders(confidentialHeaders?: string[]): (req: FilterRequest, propName: string) => any;
3
+ export declare function isRequestInfo(info: any): boolean;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isRequestInfo = exports.filterRequestHeaders = void 0;
4
+ function filterRequestHeaders(confidentialHeaders = []) {
5
+ return (req, propName) => {
6
+ if (propName !== "headers")
7
+ return req[propName];
8
+ const filteredHeaders = Object.keys(req.headers)
9
+ .filter((key) => !confidentialHeaders.includes(key))
10
+ .reduce((acc, key) => {
11
+ acc[key] = req.headers[key];
12
+ return acc;
13
+ }, {});
14
+ return filteredHeaders;
15
+ };
16
+ }
17
+ exports.filterRequestHeaders = filterRequestHeaders;
18
+ function isRequestInfo(info) {
19
+ const metadata = info.meta;
20
+ return (metadata === null || metadata === void 0 ? void 0 : metadata.req) && (metadata === null || metadata === void 0 ? void 0 : metadata.res) ? true : false;
21
+ }
22
+ exports.isRequestInfo = isRequestInfo;
@@ -0,0 +1,6 @@
1
+ export declare function generateRouteRegex(route: string): RegExp;
2
+ export declare function shouldFilterRoute(url: string, routesToBeFiltered: string[]): boolean;
3
+ export declare function shouldRouteBeFiltered(request: any, blacklistedRoutes: {
4
+ route: string;
5
+ method: string;
6
+ }[]): boolean;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.shouldRouteBeFiltered = exports.shouldFilterRoute = exports.generateRouteRegex = void 0;
4
+ function generateRouteRegex(route) {
5
+ const splitedRoute = route.split("/").filter((i) => i !== "");
6
+ const regexString = splitedRoute
7
+ .map((i) => {
8
+ return (i === null || i === void 0 ? void 0 : i.charAt(0)) === ":" ? "(.)+" : i;
9
+ })
10
+ .join("/");
11
+ return new RegExp("^/" + regexString + "$", "g");
12
+ }
13
+ exports.generateRouteRegex = generateRouteRegex;
14
+ function shouldFilterRoute(url, routesToBeFiltered) {
15
+ return routesToBeFiltered.some((route) => {
16
+ const regExp = generateRouteRegex(route);
17
+ const matches = new String(url).match(regExp);
18
+ return !!(matches === null || matches === void 0 ? void 0 : matches.length);
19
+ });
20
+ }
21
+ exports.shouldFilterRoute = shouldFilterRoute;
22
+ function shouldRouteBeFiltered(request, blacklistedRoutes) {
23
+ return blacklistedRoutes.some(({ route, method }) => {
24
+ const regExp = generateRouteRegex(route);
25
+ const matches = new String(request.url).match(regExp);
26
+ return ((matches === null || matches === void 0 ? void 0 : matches.length) && request.method.toLowerCase() === method.toLowerCase());
27
+ });
28
+ }
29
+ exports.shouldRouteBeFiltered = shouldRouteBeFiltered;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sm-utility",
3
- "version": "2.4.21",
3
+ "version": "2.4.23",
4
4
  "description": "reusable utility codes for sm projects",
5
5
  "main": "index.js",
6
6
  "types": "./index.d.ts",
@@ -21,6 +21,7 @@
21
21
  "devDependencies": {
22
22
  "@types/express": "^4.17.11",
23
23
  "@types/node": "^14.14.40",
24
+ "@types/request-ip": "0.0.41",
24
25
  "@types/uuid": "^8.3.1",
25
26
  "copyfiles": "^2.4.1",
26
27
  "typescript": "^4.2.4"
@@ -36,11 +37,12 @@
36
37
  "@opentelemetry/resources": "1.30.1",
37
38
  "@opentelemetry/sdk-node": "0.57.1",
38
39
  "@opentelemetry/sdk-trace-base": "1.30.1",
39
- "axios": "1.7.8",
40
+ "axios": "1.9.0",
40
41
  "express-winston": "^4.1.0",
41
42
  "nanoid": "^3.3.6",
42
43
  "node-xlsx": "^0.24.0",
43
44
  "redis": "^4.1.0",
45
+ "request-ip": "3.3.0",
44
46
  "ts-node": "^10.9.1",
45
47
  "uuid": "^8.3.2",
46
48
  "winston": "^3.3.3"
@@ -1,3 +1,3 @@
1
- import { AxiosInstance } from 'axios';
2
- import { CustomClientCreateApiParams } from './types';
1
+ import { AxiosInstance } from "axios";
2
+ import { CustomClientCreateApiParams } from "./types";
3
3
  export declare function createApi(axiosConfig?: CustomClientCreateApiParams): AxiosInstance;
@@ -5,91 +5,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.createApi = void 0;
7
7
  const axios_1 = __importDefault(require("axios"));
8
- const uuid_1 = require("uuid");
9
- const logger_1 = require("../logger");
8
+ const request_interceptor_1 = require("./interceptors/request.interceptor");
9
+ const response_interceptor_1 = require("./interceptors/response.interceptor");
10
+ const error_interceptor_1 = require("./interceptors/error.interceptor");
10
11
  function createApi(axiosConfig) {
11
12
  const axiosApi = axios_1.default.create(axiosConfig);
12
- axiosApi.interceptors.request.use();
13
- axiosApi.interceptors.request.use((request) => {
14
- if (request === null || request === void 0 ? void 0 : request.logRequest) {
15
- const { data, params, method } = request;
16
- const fullUrl = getFullUrlFromConfig(request);
17
- request.meta = request.meta || {};
18
- request.meta.requestId = (0, uuid_1.v4)();
19
- request.meta.requestStartedAt = new Date().getTime();
20
- logRequest(request.meta.requestId, method, fullUrl, data, params);
21
- }
22
- return request;
23
- }, (error) => {
24
- const { config, message, response } = error;
25
- const { method, meta } = config || {};
26
- const fullUrl = getFullUrlFromConfig(config);
27
- logError(meta === null || meta === void 0 ? void 0 : meta.requestId, method, fullUrl, response === null || response === void 0 ? void 0 : response.data, response === null || response === void 0 ? void 0 : response.status, message);
28
- throw error;
29
- });
30
- axiosApi.interceptors.response.use((response) => {
31
- var _a;
32
- if ((_a = response.config) === null || _a === void 0 ? void 0 : _a.logResponse) {
33
- const { status, data, config } = response;
34
- const { method, meta } = config;
35
- const fullUrl = getFullUrlFromConfig(config);
36
- const responseTime = getResponseTimeFromConfig(config);
37
- logResponse(meta === null || meta === void 0 ? void 0 : meta.requestId, method, fullUrl, data, status, responseTime);
38
- }
39
- return response;
40
- }, (error) => {
41
- const { config, message, response } = error;
42
- const { method, meta } = config || {};
43
- const fullUrl = getFullUrlFromConfig(config);
44
- logError(meta === null || meta === void 0 ? void 0 : meta.requestId, method, fullUrl, response === null || response === void 0 ? void 0 : response.data, response === null || response === void 0 ? void 0 : response.status, message);
45
- throw error;
46
- });
13
+ axiosApi.interceptors.request.use((0, request_interceptor_1.createRequestInterceptor)(), (0, error_interceptor_1.createErrorInterceptor)());
14
+ axiosApi.interceptors.response.use((0, response_interceptor_1.createResponseInterceptor)(), (0, error_interceptor_1.createErrorInterceptor)());
47
15
  return axiosApi;
48
16
  }
49
17
  exports.createApi = createApi;
50
- function logRequest(id, method, url, body, params) {
51
- const request = {
52
- ['context-id']: id,
53
- url,
54
- method: method === null || method === void 0 ? void 0 : method.toUpperCase(),
55
- params,
56
- body
57
- };
58
- logger_1.logger.info('sm-utility/api-request', { request });
59
- }
60
- function logResponse(id, method, url, body, status, responseTime) {
61
- const response = {
62
- ['context-id']: id,
63
- url,
64
- method: method === null || method === void 0 ? void 0 : method.toUpperCase(),
65
- body,
66
- status,
67
- responseTime
68
- };
69
- logger_1.logger.info('sm-utility/api-response', { response });
70
- }
71
- function logError(id, method, url, data, status, message) {
72
- const err = {
73
- ['context-id']: id,
74
- url,
75
- method: method === null || method === void 0 ? void 0 : method.toUpperCase(),
76
- data,
77
- status,
78
- message
79
- };
80
- logger_1.logger.error('sm-utility/api-error', { err });
81
- }
82
- function getResponseTimeFromConfig(config) {
83
- var _a;
84
- const requestStart = (_a = config === null || config === void 0 ? void 0 : config.meta) === null || _a === void 0 ? void 0 : _a.requestStartedAt;
85
- let responseTime = '-';
86
- if (requestStart) {
87
- responseTime = String(new Date().getTime() - requestStart);
88
- }
89
- return responseTime + ' ms';
90
- }
91
- function getFullUrlFromConfig(config) {
92
- const { baseURL, url } = config || {};
93
- const fullUrl = baseURL && url ? new String().concat(baseURL, url) : '';
94
- return fullUrl;
95
- }
@@ -1,3 +1,4 @@
1
1
  export * from './axios-custom-client';
2
2
  export * from './axios';
3
3
  export * from './types';
4
+ export * from './requestExtractor';
package/request/index.js CHANGED
@@ -17,3 +17,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./axios-custom-client"), exports);
18
18
  __exportStar(require("./axios"), exports);
19
19
  __exportStar(require("./types"), exports);
20
+ __exportStar(require("./requestExtractor"), exports);
@@ -0,0 +1,2 @@
1
+ import { AxiosError } from "axios";
2
+ export declare function createErrorInterceptor(): (error: AxiosError) => never;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createErrorInterceptor = void 0;
4
+ const loggers_1 = require("../loggers");
5
+ const utils_1 = require("../utils");
6
+ function createErrorInterceptor() {
7
+ return (error) => {
8
+ const { config, message, response } = error;
9
+ const { method, meta } = config || {};
10
+ const fullUrl = (0, utils_1.getFullUrlFromConfig)(config);
11
+ (0, loggers_1.logError)(meta === null || meta === void 0 ? void 0 : meta.requestId, method, fullUrl, response === null || response === void 0 ? void 0 : response.data, response === null || response === void 0 ? void 0 : response.status, message);
12
+ throw error;
13
+ };
14
+ }
15
+ exports.createErrorInterceptor = createErrorInterceptor;
@@ -0,0 +1,2 @@
1
+ import { InternalAxiosRequestConfig } from "axios";
2
+ export declare function createRequestInterceptor(): (request: InternalAxiosRequestConfig) => InternalAxiosRequestConfig<any>;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createRequestInterceptor = void 0;
4
+ const uuid_1 = require("uuid");
5
+ const utils_1 = require("../utils");
6
+ const loggers_1 = require("../loggers");
7
+ function createRequestInterceptor() {
8
+ return (request) => {
9
+ if (request === null || request === void 0 ? void 0 : request.logRequest) {
10
+ const { data, params, method } = request;
11
+ const fullUrl = (0, utils_1.getFullUrlFromConfig)(request);
12
+ request.meta = request.meta || {};
13
+ request.meta.requestId = (0, uuid_1.v4)();
14
+ request.meta.requestStartedAt = new Date().getTime();
15
+ (0, loggers_1.logRequest)(request.meta.requestId, method, fullUrl, data, params);
16
+ }
17
+ return request;
18
+ };
19
+ }
20
+ exports.createRequestInterceptor = createRequestInterceptor;
@@ -0,0 +1,2 @@
1
+ import { AxiosResponse } from "axios";
2
+ export declare function createResponseInterceptor(): (response: AxiosResponse) => AxiosResponse<any, any>;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createResponseInterceptor = void 0;
4
+ const loggers_1 = require("../loggers");
5
+ const utils_1 = require("../utils");
6
+ function createResponseInterceptor() {
7
+ return (response) => {
8
+ var _a;
9
+ if ((_a = response.config) === null || _a === void 0 ? void 0 : _a.logResponse) {
10
+ const { status, data, config } = response;
11
+ const { method, meta } = config;
12
+ const fullUrl = (0, utils_1.getFullUrlFromConfig)(config);
13
+ const responseTime = (0, utils_1.getResponseTimeFromConfig)(config);
14
+ (0, loggers_1.logResponse)(meta === null || meta === void 0 ? void 0 : meta.requestId, method, fullUrl, data, status, responseTime);
15
+ }
16
+ return response;
17
+ };
18
+ }
19
+ exports.createResponseInterceptor = createResponseInterceptor;
@@ -0,0 +1 @@
1
+ export declare function logError(id: string, method: string | undefined, url: string | undefined, data: unknown, status: any, message: any): void;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.logError = void 0;
4
+ const logger_1 = require("../../logger");
5
+ function logError(id, method, url, data, status, message) {
6
+ const err = {
7
+ ["context-id"]: id,
8
+ url,
9
+ method: method === null || method === void 0 ? void 0 : method.toUpperCase(),
10
+ data,
11
+ status,
12
+ message,
13
+ };
14
+ logger_1.logger.error("sm-utility/api-error", { err });
15
+ }
16
+ exports.logError = logError;
@@ -0,0 +1,3 @@
1
+ export * from "./error.logger";
2
+ export * from "./request.logger";
3
+ export * from "./response.logger";
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./error.logger"), exports);
18
+ __exportStar(require("./request.logger"), exports);
19
+ __exportStar(require("./response.logger"), exports);
@@ -0,0 +1 @@
1
+ export declare function logRequest(id: string, method: string | undefined, url: string | undefined, body: unknown, params: string): void;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.logRequest = void 0;
4
+ const logger_1 = require("../../logger");
5
+ function logRequest(id, method, url, body, params) {
6
+ const request = {
7
+ ["context-id"]: id,
8
+ url,
9
+ method: method === null || method === void 0 ? void 0 : method.toUpperCase(),
10
+ params,
11
+ body,
12
+ };
13
+ logger_1.logger.info("sm-utility/api-request", { request });
14
+ }
15
+ exports.logRequest = logRequest;
@@ -0,0 +1 @@
1
+ export declare function logResponse(id: string, method: string | undefined, url: string | undefined, body: unknown, status: any, responseTime: string): void;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.logResponse = void 0;
4
+ const logger_1 = require("../../logger");
5
+ function logResponse(id, method, url, body, status, responseTime) {
6
+ const response = {
7
+ ["context-id"]: id,
8
+ url,
9
+ method: method === null || method === void 0 ? void 0 : method.toUpperCase(),
10
+ body,
11
+ status,
12
+ responseTime,
13
+ };
14
+ logger_1.logger.info("sm-utility/api-response", { response });
15
+ }
16
+ exports.logResponse = logResponse;
@@ -0,0 +1,25 @@
1
+ import { Request } from 'express';
2
+ export declare class IpAddress {
3
+ private readonly ip;
4
+ constructor(ip: string | null);
5
+ raw(): string;
6
+ sanitized(): string;
7
+ }
8
+ export declare class RequestExtractor {
9
+ private readonly req;
10
+ constructor(req: Request);
11
+ /**
12
+ * Extracts the ip address from the request headers.
13
+ *
14
+ * If the ip address is not in the cf-connecting-ip header (Cloudflare - HML and PROD), it will be extracted from the x-forwarded-for header (local development)
15
+ */
16
+ extractIp(): IpAddress;
17
+ /**
18
+ * Extracts the trace id (x-ray trace id) from the request headers
19
+ */
20
+ extractTraceId(): string | undefined;
21
+ /**
22
+ * Extracts the user agent from the request headers
23
+ */
24
+ extractUserAgent(): string | undefined;
25
+ }
@@ -0,0 +1,49 @@
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.RequestExtractor = exports.IpAddress = void 0;
7
+ const request_ip_1 = __importDefault(require("request-ip"));
8
+ class IpAddress {
9
+ constructor(ip) {
10
+ this.ip = ip;
11
+ }
12
+ raw() {
13
+ return this.ip || 'unknown';
14
+ }
15
+ sanitized() {
16
+ var _a;
17
+ return ((_a = this.ip) === null || _a === void 0 ? void 0 : _a.replace(/^::ffff:/, '')) || 'unknown';
18
+ }
19
+ }
20
+ exports.IpAddress = IpAddress;
21
+ class RequestExtractor {
22
+ constructor(req) {
23
+ this.req = req;
24
+ }
25
+ /**
26
+ * Extracts the ip address from the request headers.
27
+ *
28
+ * If the ip address is not in the cf-connecting-ip header (Cloudflare - HML and PROD), it will be extracted from the x-forwarded-for header (local development)
29
+ */
30
+ extractIp() {
31
+ const cloudflareIp = this.req.headers['cf-connecting-ip'];
32
+ const ip = cloudflareIp || request_ip_1.default.getClientIp(this.req);
33
+ return new IpAddress(ip);
34
+ }
35
+ /**
36
+ * Extracts the trace id (x-ray trace id) from the request headers
37
+ */
38
+ extractTraceId() {
39
+ return this.req.headers['x-amzn-trace-id'];
40
+ }
41
+ /**
42
+ * Extracts the user agent from the request headers
43
+ */
44
+ extractUserAgent() {
45
+ var _a;
46
+ return (_a = this.req) === null || _a === void 0 ? void 0 : _a.headers['user-agent'];
47
+ }
48
+ }
49
+ exports.RequestExtractor = RequestExtractor;
@@ -0,0 +1,3 @@
1
+ import { AxiosRequestConfig, InternalAxiosRequestConfig } from "axios";
2
+ export declare function getFullUrlFromConfig(config: InternalAxiosRequestConfig | undefined): string;
3
+ export declare function getResponseTimeFromConfig(config: AxiosRequestConfig): string;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getResponseTimeFromConfig = exports.getFullUrlFromConfig = void 0;
4
+ function getFullUrlFromConfig(config) {
5
+ const { baseURL, url } = config || {};
6
+ const fullUrl = baseURL && url ? new String().concat(baseURL, url) : "";
7
+ return fullUrl;
8
+ }
9
+ exports.getFullUrlFromConfig = getFullUrlFromConfig;
10
+ function getResponseTimeFromConfig(config) {
11
+ var _a;
12
+ const requestStart = (_a = config === null || config === void 0 ? void 0 : config.meta) === null || _a === void 0 ? void 0 : _a.requestStartedAt;
13
+ let responseTime = "-";
14
+ if (requestStart) {
15
+ responseTime = String(new Date().getTime() - requestStart);
16
+ }
17
+ return responseTime + " ms";
18
+ }
19
+ exports.getResponseTimeFromConfig = getResponseTimeFromConfig;