lambda-essentials-ts 5.0.0 → 5.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/CHANGELOG.md +6 -0
- package/lib/exceptions/exception.js +1 -1
- package/lib/httpClient/httpClient.js +36 -28
- package/lib/index.js +6 -2
- package/lib/logger/logger.js +9 -5
- package/lib/openApi/openApiWrapper.js +11 -5
- package/lib/util.js +1 -1
- package/package.json +20 -20
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
6
6
|
|
|
7
|
+
## [5.1.0] - 2022-09-05
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
Dependencies aren't pinned to a fixed version to allow users of the library to independently upgrade minor (devDependencies) and patch (dependencies) versions. This will simplify fixing security alerts faster than in this library, for example by applying `npm audit fix`.
|
|
12
|
+
|
|
7
13
|
## [5.0.0] - 2022-02-22
|
|
8
14
|
|
|
9
15
|
### Changed
|
|
@@ -6,7 +6,7 @@ class Exception extends Error {
|
|
|
6
6
|
constructor(message, statusCode, details) {
|
|
7
7
|
super(message);
|
|
8
8
|
this.statusCode = statusCode;
|
|
9
|
-
this.details = details ? util_1.serializeObject(details) : details;
|
|
9
|
+
this.details = details ? (0, util_1.serializeObject)(details) : details;
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
exports.Exception = Exception;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
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);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -14,7 +18,7 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
14
18
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
19
|
if (mod && mod.__esModule) return mod;
|
|
16
20
|
var result = {};
|
|
17
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
22
|
__setModuleDefault(result, mod);
|
|
19
23
|
return result;
|
|
20
24
|
};
|
|
@@ -47,6 +51,7 @@ class HttpClient {
|
|
|
47
51
|
/**
|
|
48
52
|
* Create a new Instance of the HttpClient
|
|
49
53
|
*/
|
|
54
|
+
// eslint-disable-next-line complexity
|
|
50
55
|
constructor(options) {
|
|
51
56
|
var _a, _b, _c, _d, _e;
|
|
52
57
|
// eslint-disable-next-line no-console
|
|
@@ -56,26 +61,27 @@ class HttpClient {
|
|
|
56
61
|
this.correlationIdResolverFunction = options === null || options === void 0 ? void 0 : options.correlationIdResolver;
|
|
57
62
|
this.enableCache = (_c = options === null || options === void 0 ? void 0 : options.enableCache) !== null && _c !== void 0 ? _c : false;
|
|
58
63
|
this.enableRetry = (_d = options === null || options === void 0 ? void 0 : options.enableRetry) !== null && _d !== void 0 ? _d : false;
|
|
59
|
-
this.client =
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
64
|
+
this.client =
|
|
65
|
+
(_e = options === null || options === void 0 ? void 0 : options.client) !== null && _e !== void 0 ? _e : axios_1.default.create({
|
|
66
|
+
adapter: (() => {
|
|
67
|
+
let adapters = axios_1.default.defaults.adapter;
|
|
68
|
+
if (this.enableCache) {
|
|
69
|
+
const cache = (0, axios_cache_adapter_1.setupCache)({
|
|
70
|
+
maxAge: 5 * 60 * 1000,
|
|
71
|
+
readHeaders: false,
|
|
72
|
+
readOnError: true,
|
|
73
|
+
exclude: {
|
|
74
|
+
query: false, // also cache requests with query parameters
|
|
75
|
+
},
|
|
76
|
+
...options === null || options === void 0 ? void 0 : options.cacheOptions,
|
|
77
|
+
key: (req) => HttpClient.generateCacheKey(req),
|
|
78
|
+
});
|
|
79
|
+
// debounce concurrent calls with the same cacheKey so that only one HTTP request is made
|
|
80
|
+
adapters = (0, deduplicateRequestAdapter_1.createDebounceRequestAdapter)(cache.adapter, HttpClient.generateCacheKey);
|
|
81
|
+
}
|
|
82
|
+
return adapters;
|
|
83
|
+
})(),
|
|
84
|
+
});
|
|
79
85
|
if (this.enableRetry) {
|
|
80
86
|
this.client.defaults.raxConfig = {
|
|
81
87
|
...options === null || options === void 0 ? void 0 : options.retryOptions,
|
|
@@ -88,7 +94,7 @@ class HttpClient {
|
|
|
88
94
|
level: 'INFO',
|
|
89
95
|
retryAttempt: (_b = (_a = err.config) === null || _a === void 0 ? void 0 : _a.raxConfig) === null || _b === void 0 ? void 0 : _b.currentRetryAttempt,
|
|
90
96
|
...HttpClient.extractRequestLogData(err.config),
|
|
91
|
-
error: util_1.serializeAxiosError(err),
|
|
97
|
+
error: (0, util_1.serializeAxiosError)(err),
|
|
92
98
|
});
|
|
93
99
|
},
|
|
94
100
|
};
|
|
@@ -109,7 +115,7 @@ class HttpClient {
|
|
|
109
115
|
return config;
|
|
110
116
|
}, (error) => {
|
|
111
117
|
var _a;
|
|
112
|
-
const serializedAxiosError = util_1.serializeAxiosError(error);
|
|
118
|
+
const serializedAxiosError = (0, util_1.serializeAxiosError)(error);
|
|
113
119
|
this.logFunction({
|
|
114
120
|
title: 'HTTP Request Error',
|
|
115
121
|
level: 'WARN',
|
|
@@ -136,7 +142,7 @@ class HttpClient {
|
|
|
136
142
|
if (error instanceof clientException_1.ClientException) {
|
|
137
143
|
throw error;
|
|
138
144
|
}
|
|
139
|
-
const serializedAxiosError = util_1.serializeAxiosError(error);
|
|
145
|
+
const serializedAxiosError = (0, util_1.serializeAxiosError)(error);
|
|
140
146
|
if (error.message === invalidToken) {
|
|
141
147
|
this.logFunction({
|
|
142
148
|
title: 'HTTP call skipped due to a token error',
|
|
@@ -166,18 +172,20 @@ class HttpClient {
|
|
|
166
172
|
method: requestConfig.method,
|
|
167
173
|
url: requestConfig.url,
|
|
168
174
|
query: requestConfig.params,
|
|
169
|
-
request: util_1.safeJsonParse(requestConfig.data, requestConfig.data),
|
|
175
|
+
request: (0, util_1.safeJsonParse)(requestConfig.data, requestConfig.data),
|
|
170
176
|
correlationId: (_a = requestConfig.headers) === null || _a === void 0 ? void 0 : _a[shared_1.orionCorrelationIdRoot],
|
|
171
177
|
};
|
|
172
178
|
}
|
|
173
179
|
// implemented based on https://github.com/RasCarlito/axios-cache-adapter/blob/master/src/cache.js#L77
|
|
174
180
|
static generateCacheKey(req) {
|
|
175
181
|
var _a, _b;
|
|
176
|
-
const prefix = ((_a = req.headers) === null || _a === void 0 ? void 0 : _a.Authorization)
|
|
182
|
+
const prefix = ((_a = req.headers) === null || _a === void 0 ? void 0 : _a.Authorization)
|
|
183
|
+
? (_b = (0, util_1.safeJwtCanonicalIdParse)(req.headers.Authorization.replace('Bearer ', ''))) !== null && _b !== void 0 ? _b : uuid.v4()
|
|
184
|
+
: 'shared';
|
|
177
185
|
const url = `${req.baseURL ? req.baseURL : ''}${req.url}`;
|
|
178
186
|
const query = req.params ? JSON.stringify(req.params) : ''; // possible improvement: optimize cache-hit ratio by sorting the query params
|
|
179
187
|
const key = `${prefix}/${url}${query}`;
|
|
180
|
-
return `${key}${req.data ? md5_1.default(req.data) : ''}`;
|
|
188
|
+
return `${key}${req.data ? (0, md5_1.default)(req.data) : ''}`;
|
|
181
189
|
}
|
|
182
190
|
/**
|
|
183
191
|
* Resolves the token with the token provider and adds it to the headers
|
package/lib/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
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);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -14,7 +18,7 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
14
18
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
19
|
if (mod && mod.__esModule) return mod;
|
|
16
20
|
var result = {};
|
|
17
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
22
|
__setModuleDefault(result, mod);
|
|
19
23
|
return result;
|
|
20
24
|
};
|
package/lib/logger/logger.js
CHANGED
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
/* eslint-disable no-console */
|
|
3
3
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
4
|
if (k2 === undefined) k2 = k;
|
|
5
|
-
Object.
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
6
10
|
}) : (function(o, m, k, k2) {
|
|
7
11
|
if (k2 === undefined) k2 = k;
|
|
8
12
|
o[k2] = m[k];
|
|
@@ -15,7 +19,7 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
19
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
16
20
|
if (mod && mod.__esModule) return mod;
|
|
17
21
|
var result = {};
|
|
18
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
19
23
|
__setModuleDefault(result, mod);
|
|
20
24
|
return result;
|
|
21
25
|
};
|
|
@@ -70,8 +74,8 @@ class Logger {
|
|
|
70
74
|
const truncateToken = (innerPayload) => {
|
|
71
75
|
return innerPayload.replace(/(eyJ[a-zA-Z0-9_-]{5,}\.eyJ[a-zA-Z0-9_-]{5,})\.[a-zA-Z0-9_-]*/gi, (m, p1) => `${p1}.<sig>`);
|
|
72
76
|
};
|
|
73
|
-
const replacer = (key, value) => (is_error_1.default(value) ? Logger.errorToObject(value) : value);
|
|
74
|
-
let stringifiedPayload = truncateToken(fast_safe_stringify_1.default(payload, replacer, this.jsonSpace));
|
|
77
|
+
const replacer = (key, value) => ((0, is_error_1.default)(value) ? Logger.errorToObject(value) : value);
|
|
78
|
+
let stringifiedPayload = truncateToken((0, fast_safe_stringify_1.default)(payload, replacer, this.jsonSpace));
|
|
75
79
|
// https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/cloudwatch_limits_cwl.html 256KB => 32768 characters
|
|
76
80
|
if (stringifiedPayload.length >= 32768) {
|
|
77
81
|
const replacementPayload = {
|
|
@@ -82,7 +86,7 @@ class Logger {
|
|
|
82
86
|
truncatedPayload: stringifiedPayload.substring(0, 10000),
|
|
83
87
|
},
|
|
84
88
|
};
|
|
85
|
-
stringifiedPayload = fast_safe_stringify_1.default(replacementPayload, replacer, this.jsonSpace);
|
|
89
|
+
stringifiedPayload = (0, fast_safe_stringify_1.default)(replacementPayload, replacer, this.jsonSpace);
|
|
86
90
|
}
|
|
87
91
|
this.logFunction(stringifiedPayload);
|
|
88
92
|
}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
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);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -14,7 +18,7 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
14
18
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
19
|
if (mod && mod.__esModule) return mod;
|
|
16
20
|
var result = {};
|
|
17
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
22
|
__setModuleDefault(result, mod);
|
|
19
23
|
return result;
|
|
20
24
|
};
|
|
@@ -43,8 +47,10 @@ class OpenApiWrapper {
|
|
|
43
47
|
const correlationId = this.generateCorrelationId(request.headers);
|
|
44
48
|
requestLogger.startInvocation(null, correlationId);
|
|
45
49
|
// TODO: restrict the alternative way of resolving token and principal only for localhost
|
|
46
|
-
this.userToken =
|
|
47
|
-
|
|
50
|
+
this.userToken =
|
|
51
|
+
(_b = (_a = request.requestContext.authorizer) === null || _a === void 0 ? void 0 : _a.jwt) !== null && _b !== void 0 ? _b : (_c = request.headers.Authorization) === null || _c === void 0 ? void 0 : _c.split(' ')[1];
|
|
52
|
+
this.userPrincipal =
|
|
53
|
+
(_f = (_e = (_d = request.requestContext.authorizer) === null || _d === void 0 ? void 0 : _d.canonicalId) !== null && _e !== void 0 ? _e : (0, util_1.safeJwtCanonicalIdParse)(this.userToken)) !== null && _f !== void 0 ? _f : 'unknown';
|
|
48
54
|
this.requestId = request.requestContext.requestId;
|
|
49
55
|
requestLogger.log({
|
|
50
56
|
title: 'RequestLogger',
|
|
@@ -71,7 +77,7 @@ class OpenApiWrapper {
|
|
|
71
77
|
errorMiddleware: (request, error) => {
|
|
72
78
|
const { correlationId } = this;
|
|
73
79
|
this.clearContext();
|
|
74
|
-
const serializedError = util_1.serializeObject(error);
|
|
80
|
+
const serializedError = (0, util_1.serializeObject)(error);
|
|
75
81
|
if (error instanceof exception_1.Exception) {
|
|
76
82
|
if (error.statusCode === 500) {
|
|
77
83
|
requestLogger.log({ title: 'ErrorLogger', level: 'ERROR', ...serializedError });
|
package/lib/util.js
CHANGED
|
@@ -43,7 +43,7 @@ function serializeAxiosError(error) {
|
|
|
43
43
|
const { status, data } = error.response;
|
|
44
44
|
return {
|
|
45
45
|
status: (_a = data.originalStatusCode) !== null && _a !== void 0 ? _a : status,
|
|
46
|
-
details: data.details ? data.details : data,
|
|
46
|
+
details: data.details ? data.details : data, // Prevent wrapping of Exception
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
49
|
exports.serializeAxiosError = serializeAxiosError;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lambda-essentials-ts",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"description": "A selection of the finest modules supporting authorization, API routing, error handling, logging and sending HTTP requests.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"private": false,
|
|
@@ -26,28 +26,28 @@
|
|
|
26
26
|
},
|
|
27
27
|
"homepage": "https://github.com/Cimpress-MCP/lambda-essentials-ts#readme",
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"aws-sdk": "2.1078.0",
|
|
30
|
-
"axios": "0.21.
|
|
31
|
-
"axios-cache-adapter": "2.7.3",
|
|
32
|
-
"fast-safe-stringify": "2.0.7",
|
|
33
|
-
"is-error": "2.2.2",
|
|
34
|
-
"jsonwebtoken": "8.5.1",
|
|
35
|
-
"md5": "2.3.0",
|
|
29
|
+
"aws-sdk": "^2.1078.0",
|
|
30
|
+
"axios": "~0.21.3",
|
|
31
|
+
"axios-cache-adapter": "~2.7.3",
|
|
32
|
+
"fast-safe-stringify": "~2.0.7",
|
|
33
|
+
"is-error": "~2.2.2",
|
|
34
|
+
"jsonwebtoken": "~8.5.1",
|
|
35
|
+
"md5": "~2.3.0",
|
|
36
36
|
"openapi-factory": "5.2.17",
|
|
37
|
-
"retry-axios": "2.6.0",
|
|
38
|
-
"uuid": "8.3.2"
|
|
37
|
+
"retry-axios": "~2.6.0",
|
|
38
|
+
"uuid": "~8.3.2"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@types/jest": "26.0.20",
|
|
42
|
-
"eslint": "7.18.0",
|
|
43
|
-
"eslint-config-cimpress-atsquad": "2.1.2",
|
|
44
|
-
"husky": "4.2.5",
|
|
45
|
-
"jest": "26.2.2",
|
|
46
|
-
"lint-staged": "10.2.13",
|
|
47
|
-
"prettier": "2.
|
|
48
|
-
"ts-jest": "26.1.4",
|
|
49
|
-
"ts-node": "
|
|
50
|
-
"typescript": "
|
|
41
|
+
"@types/jest": "^26.0.20",
|
|
42
|
+
"eslint": "^7.18.0",
|
|
43
|
+
"eslint-config-cimpress-atsquad": "^2.1.2",
|
|
44
|
+
"husky": "^4.2.5",
|
|
45
|
+
"jest": "^26.2.2",
|
|
46
|
+
"lint-staged": "^10.2.13",
|
|
47
|
+
"prettier": "^2.7.1",
|
|
48
|
+
"ts-jest": "^26.1.4",
|
|
49
|
+
"ts-node": "^10.9.1",
|
|
50
|
+
"typescript": "^4.8.2"
|
|
51
51
|
},
|
|
52
52
|
"eslintConfig": {
|
|
53
53
|
"extends": "cimpress-atsquad"
|