@comicrelief/lambda-wrapper 1.10.1 → 2.0.0-beta.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.
Files changed (89) hide show
  1. package/README.md +172 -47
  2. package/dist/core/DependencyAwareClass.d.ts +15 -0
  3. package/dist/core/DependencyAwareClass.d.ts.map +1 -0
  4. package/dist/core/DependencyAwareClass.js +20 -0
  5. package/dist/core/DependencyAwareClass.js.map +1 -0
  6. package/dist/core/DependencyInjection.d.ts +62 -0
  7. package/dist/core/DependencyInjection.d.ts.map +1 -0
  8. package/dist/core/DependencyInjection.js +83 -0
  9. package/dist/core/DependencyInjection.js.map +1 -0
  10. package/dist/core/LambdaWrapper.d.ts +61 -0
  11. package/dist/core/LambdaWrapper.d.ts.map +1 -0
  12. package/dist/core/LambdaWrapper.js +126 -0
  13. package/dist/core/LambdaWrapper.js.map +1 -0
  14. package/dist/core/config.d.ts +20 -0
  15. package/dist/core/config.d.ts.map +1 -0
  16. package/dist/core/config.js +21 -0
  17. package/dist/core/config.js.map +1 -0
  18. package/dist/index.d.ts +28 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +59 -162
  21. package/dist/index.js.map +1 -0
  22. package/dist/models/ResponseModel.d.ts +91 -0
  23. package/dist/models/ResponseModel.d.ts.map +1 -0
  24. package/dist/models/ResponseModel.js +100 -0
  25. package/dist/models/ResponseModel.js.map +1 -0
  26. package/dist/models/SQSMessageModel.d.ts +46 -0
  27. package/dist/models/SQSMessageModel.d.ts.map +1 -0
  28. package/dist/models/SQSMessageModel.js +65 -0
  29. package/dist/models/SQSMessageModel.js.map +1 -0
  30. package/dist/models/StatusModel.d.ts +40 -0
  31. package/dist/models/StatusModel.d.ts.map +1 -0
  32. package/dist/models/StatusModel.js +50 -0
  33. package/dist/models/StatusModel.js.map +1 -0
  34. package/dist/services/BaseConfigService.d.ts +101 -0
  35. package/dist/services/BaseConfigService.d.ts.map +1 -0
  36. package/dist/services/BaseConfigService.js +180 -0
  37. package/dist/services/BaseConfigService.js.map +1 -0
  38. package/dist/services/HTTPService.d.ts +29 -0
  39. package/dist/services/HTTPService.d.ts.map +1 -0
  40. package/dist/services/HTTPService.js +55 -0
  41. package/dist/services/HTTPService.js.map +1 -0
  42. package/dist/services/LoggerService.d.ts +102 -0
  43. package/dist/services/LoggerService.d.ts.map +1 -0
  44. package/dist/services/LoggerService.js +258 -0
  45. package/dist/services/LoggerService.js.map +1 -0
  46. package/dist/services/RequestService.d.ts +119 -0
  47. package/dist/services/RequestService.d.ts.map +1 -0
  48. package/dist/services/RequestService.js +293 -0
  49. package/dist/services/RequestService.js.map +1 -0
  50. package/dist/services/SQSService.d.ts +181 -0
  51. package/dist/services/SQSService.d.ts.map +1 -0
  52. package/dist/services/SQSService.js +366 -0
  53. package/dist/services/SQSService.js.map +1 -0
  54. package/dist/services/TimerService.d.ts +22 -0
  55. package/dist/services/TimerService.d.ts.map +1 -0
  56. package/dist/services/TimerService.js +40 -0
  57. package/dist/services/TimerService.js.map +1 -0
  58. package/dist/utils/LambdaTermination.d.ts +14 -0
  59. package/dist/utils/LambdaTermination.d.ts.map +1 -0
  60. package/dist/utils/LambdaTermination.js +23 -0
  61. package/dist/utils/LambdaTermination.js.map +1 -0
  62. package/dist/utils/PromisifiedDelay.d.ts +17 -0
  63. package/dist/utils/PromisifiedDelay.d.ts.map +1 -0
  64. package/dist/utils/PromisifiedDelay.js +48 -0
  65. package/dist/utils/PromisifiedDelay.js.map +1 -0
  66. package/package.json +29 -19
  67. package/.eslintrc.yml +0 -16
  68. package/.github/dependabot.yml +0 -11
  69. package/.github/workflows/main.yml +0 -74
  70. package/babel.config.js +0 -13
  71. package/dist/Config/Dependencies.js +0 -40
  72. package/dist/DependencyInjection/DependencyAware.class.js +0 -47
  73. package/dist/DependencyInjection/DependencyInjection.class.js +0 -131
  74. package/dist/Model/CloudEvent.model.js +0 -156
  75. package/dist/Model/Model.model.js +0 -45
  76. package/dist/Model/Response.model.js +0 -150
  77. package/dist/Model/SQS/MarketingPreference.constraints.json +0 -28
  78. package/dist/Model/SQS/MarketingPreference.model.js +0 -641
  79. package/dist/Model/SQS/Message.model.js +0 -104
  80. package/dist/Model/Status.model.js +0 -82
  81. package/dist/Service/BaseConfig.service.js +0 -225
  82. package/dist/Service/HTTP.service.js +0 -70
  83. package/dist/Service/Logger.service.js +0 -293
  84. package/dist/Service/Request.service.js +0 -341
  85. package/dist/Service/SQS.service.js +0 -420
  86. package/dist/Service/Timer.service.js +0 -55
  87. package/dist/Wrapper/LambdaTermination.js +0 -39
  88. package/dist/Wrapper/LambdaWrapper.js +0 -164
  89. package/dist/Wrapper/PromisifiedDelay.js +0 -59
@@ -1,420 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = exports.SQS_PUBLISH_FAILURE_MODES = exports.SQS_OFFLINE_MODES = void 0;
7
-
8
- var _alai = _interopRequireDefault(require("alai"));
9
-
10
- var _each = _interopRequireDefault(require("async/each"));
11
-
12
- var _awsSdk = _interopRequireDefault(require("aws-sdk"));
13
-
14
- var _uuid = require("uuid");
15
-
16
- var _Dependencies = require("../Config/Dependencies");
17
-
18
- var _DependencyAware = _interopRequireDefault(require("../DependencyInjection/DependencyAware.class"));
19
-
20
- var _DependencyInjection = _interopRequireDefault(require("../DependencyInjection/DependencyInjection.class"));
21
-
22
- var _Message = _interopRequireDefault(require("../Model/SQS/Message.model"));
23
-
24
- var _Status = _interopRequireWildcard(require("../Model/Status.model"));
25
-
26
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
27
-
28
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
29
-
30
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
31
-
32
- /**
33
- * Allowed values for `process.env.LAMBDA_WRAPPER_OFFLINE_SQS_MODE`.
34
- */
35
- const SQS_OFFLINE_MODES = {
36
- /**
37
- * When running offline, messages will trigger the consumer function directly
38
- * via a Lambda endpoint, set using `process.env.SERVICE_LAMBDA_URL`. This is
39
- * the default.
40
- */
41
- DIRECT: 'direct',
42
-
43
- /**
44
- * When running offline, send messages to an offline SQS service defined by
45
- * `process.env.LAMBDA_WRAPPER_OFFLINE_SQS_HOST`.
46
- */
47
- LOCAL: 'local',
48
-
49
- /**
50
- * When running offline, send messages to AWS as normal.
51
- */
52
- AWS: 'aws'
53
- };
54
- /**
55
- * Defines the preferred behaviour
56
- * for SQSService.prototype.publish
57
- * should AWS SQS fail.
58
- */
59
-
60
- exports.SQS_OFFLINE_MODES = SQS_OFFLINE_MODES;
61
- const SQS_PUBLISH_FAILURE_MODES = {
62
- /**
63
- * Catches the exception and logs it.
64
- * This is the default behaviour
65
- * for LambdaWrapper 1.8.0 and below
66
- * and for LambdaWrapper 1.8.2 and above
67
- */
68
- CATCH: 'catch',
69
-
70
- /**
71
- * Throws the exception so that the caller
72
- * can handle it directly.
73
- */
74
- THROW: 'throw'
75
- };
76
- /**
77
- * SQSService class
78
- */
79
-
80
- exports.SQS_PUBLISH_FAILURE_MODES = SQS_PUBLISH_FAILURE_MODES;
81
-
82
- class SQSService extends _DependencyAware.default {
83
- /**
84
- * SQSService constructor
85
- *
86
- * @param di DependencyInjection
87
- */
88
- constructor(di) {
89
- super(di);
90
- const {
91
- LAMBDA_WRAPPER_OFFLINE_SQS_HOST: offlineHost = 'localhost',
92
- LAMBDA_WRAPPER_OFFLINE_SQS_PORT: offlinePort = '4576',
93
- LAMBDA_WRAPPER_OFFLINE_SQS_MODE: offlineMode = SQS_OFFLINE_MODES.DIRECT,
94
- AWS_ACCOUNT_ID,
95
- REGION
96
- } = process.env;
97
- const container = this.getContainer();
98
- const context = container.getContext();
99
- const queues = container.getConfiguration('QUEUES');
100
- const accountId = context && context.invokedFunctionArn && _alai.default.parse(context) || AWS_ACCOUNT_ID;
101
- this.queues = {};
102
- this.$lambda = null;
103
- this.$sqs = null;
104
-
105
- if (container.isOffline && !Object.values(SQS_OFFLINE_MODES).includes(offlineMode)) {
106
- throw new Error(`Invalid LAMBDA_WRAPPER_OFFLINE_SQS_MODE: ${offlineMode}\n` + `Please use one of: ${Object.values(SQS_OFFLINE_MODES).join(', ')}`);
107
- } // Add the queues from configuration
108
-
109
-
110
- if (queues !== null && Object.keys(queues).length > 0) {
111
- Object.keys(queues).forEach(queueDefinition => {
112
- if (container.isOffline && offlineMode === SQS_OFFLINE_MODES.LOCAL) {
113
- // custom URL when using an offline SQS service such as Localstack
114
- this.queues[queueDefinition] = `http://${offlineHost}:${offlinePort}/queue/${queues[queueDefinition]}`;
115
- } else {
116
- // default AWS queue URL
117
- this.queues[queueDefinition] = `https://sqs.${REGION}.amazonaws.com/${accountId}/${queues[queueDefinition]}`;
118
- }
119
- });
120
- }
121
- }
122
- /**
123
- * Returns an SQS client instance
124
- */
125
-
126
-
127
- get sqs() {
128
- if (!this.$sqs) {
129
- this.$sqs = new _awsSdk.default.SQS({
130
- region: process.env.REGION,
131
- httpOptions: {
132
- // longest publish on NOTV took 5 seconds
133
- connectTimeout: 8 * 1000,
134
- timeout: 8 * 1000
135
- },
136
- maxRetries: 3 // default is 3, we can change that
137
-
138
- });
139
- }
140
-
141
- return this.$sqs;
142
- }
143
- /**
144
- * Returns a Lambda client instance
145
- */
146
-
147
-
148
- get lambda() {
149
- if (!this.$lambda) {
150
- const endpoint = process.env.SERVICE_LAMBDA_URL;
151
-
152
- if (!endpoint) {
153
- throw new Error('process.env.SERVICE_LAMBDA_URL must be defined.');
154
- } // move to subprocess
155
-
156
-
157
- this.$lambda = new _awsSdk.default.Lambda({
158
- region: process.env.AWS_REGION,
159
- endpoint
160
- });
161
- }
162
-
163
- return this.$lambda;
164
- }
165
- /**
166
- * Returns the mode to use for offline SQS.
167
- *
168
- * This is configured by `process.env.LAMBDA_WRAPPER_OFFLINE_SQS_MODE`. The
169
- * default is `SQS_OFFLINE_MODES.LAMBDA`.
170
- */
171
-
172
-
173
- static get offlineMode() {
174
- return process.env.LAMBDA_WRAPPER_OFFLINE_SQS_MODE || SQS_OFFLINE_MODES.DIRECT;
175
- }
176
- /**
177
- * Batch delete messages
178
- *
179
- * @param queue strung
180
- * @param messageModels [SQSMessageModel]
181
- * @returns {Promise<any>}
182
- */
183
-
184
-
185
- batchDelete(queue, messageModels) {
186
- const container = this.getContainer();
187
- const queueUrl = this.queues[queue];
188
- const Logger = container.get(_Dependencies.DEFINITIONS.LOGGER);
189
- const Timer = container.get(_Dependencies.DEFINITIONS.TIMER);
190
- const timerId = `sqs-batch-delete-${(0, _uuid.v4)()} - Queue: '${queueUrl}'`;
191
- return new Promise(resolve => {
192
- const messagesForDeletion = [];
193
- Timer.start(timerId); // assuming openFiles is an array of file names
194
-
195
- (0, _each.default)(messageModels, (messageModel, callback) => {
196
- if (messageModel instanceof _Message.default && messageModel.isForDeletion() === true) {
197
- messagesForDeletion.push({
198
- Id: messageModel.getMessageId(),
199
- ReceiptHandle: messageModel.getReceiptHandle()
200
- });
201
- }
202
-
203
- callback();
204
- }, loopError => {
205
- if (loopError) {
206
- Logger.error(loopError);
207
- resolve();
208
- }
209
-
210
- this.sqs.deleteMessageBatch({
211
- Entries: messagesForDeletion,
212
- QueueUrl: queueUrl
213
- }, error => {
214
- Timer.stop(timerId);
215
-
216
- if (error) {
217
- Logger.error(error);
218
- }
219
-
220
- resolve();
221
- });
222
- });
223
- });
224
- }
225
- /**
226
- * Check SQS status
227
- *
228
- * @returns {Promise<any>}
229
- */
230
-
231
-
232
- checkStatus() {
233
- const container = this.getContainer();
234
- const Logger = container.get(_Dependencies.DEFINITIONS.LOGGER);
235
- const Timer = container.get(_Dependencies.DEFINITIONS.TIMER);
236
- const timerId = `sqs-list-queues-${(0, _uuid.v4)()}`;
237
- return new Promise(resolve => {
238
- Timer.start(timerId);
239
- this.sqs.listQueues({}, (error, data) => {
240
- Timer.stop(timerId);
241
- const statusModel = new _Status.default('SQS', _Status.STATUS_TYPES.OK);
242
-
243
- if (error) {
244
- Logger.error(error);
245
- statusModel.setStatus(_Status.STATUS_TYPES.APPLICATION_FAILURE);
246
- }
247
-
248
- if (typeof data.QueueUrls === 'undefined' || data.QueueUrls.length === 0) {
249
- statusModel.setStatus(_Status.STATUS_TYPES.APPLICATION_FAILURE);
250
- }
251
-
252
- resolve(statusModel);
253
- });
254
- });
255
- }
256
- /**
257
- * Get number of messages in a queue
258
- *
259
- * @param queue
260
- * @returns {Promise<any>}
261
- */
262
-
263
-
264
- getMessageCount(queue) {
265
- const container = this.getContainer();
266
- const queueUrl = this.queues[queue];
267
- const Logger = container.get(_Dependencies.DEFINITIONS.LOGGER);
268
- const Timer = container.get(_Dependencies.DEFINITIONS.TIMER);
269
- const timerId = `sqs-get-queue-attributes-${(0, _uuid.v4)()} - Queue: '${queueUrl}'`;
270
- return new Promise(resolve => {
271
- Timer.start(timerId);
272
- this.sqs.getQueueAttributes({
273
- AttributeNames: ['ApproximateNumberOfMessages'],
274
- QueueUrl: queueUrl
275
- }, (error, data) => {
276
- Timer.stop(timerId);
277
-
278
- if (error) {
279
- Logger.error(error);
280
- resolve(0);
281
- }
282
-
283
- resolve(Number.parseInt(data.Attributes.ApproximateNumberOfMessages, 10));
284
- });
285
- });
286
- }
287
- /**
288
- * Publish to message queue
289
- *
290
- * When running within serverless-offline, messages can be published to a
291
- * local Lambda or SQS service instead of to AWS, depending on the offline
292
- * mode specified by `process.env.LAMBDA_WRAPPER_OFFLINE_SQS_MODE`.
293
- *
294
- * @param queue string
295
- * @param messageObject object
296
- * @param messageGroupId string
297
- * @param {'catch' | 'throw'} failureMode Choose how failures are handled:
298
- * - `catch`: errors will be caught and logged. This is the default.
299
- * - `throw`: errors will be thrown, causing promise to reject.
300
- * @returns {Promise<any>}
301
- */
302
-
303
-
304
- async publish(queue, messageObject, messageGroupId = null, failureMode = SQS_PUBLISH_FAILURE_MODES.CATCH) {
305
- if (!Object.values(SQS_PUBLISH_FAILURE_MODES).includes(failureMode)) {
306
- throw new Error(`Invalid value for 'failureMode': ${failureMode}`);
307
- }
308
-
309
- const container = this.getContainer();
310
- const queueUrl = this.queues[queue];
311
- const Timer = container.get(_Dependencies.DEFINITIONS.TIMER);
312
- const timerId = `sqs-send-message-${(0, _uuid.v4)()} - Queue: '${queueUrl}'`;
313
- Timer.start(timerId);
314
- const messageParameters = {
315
- MessageBody: JSON.stringify(messageObject),
316
- QueueUrl: queueUrl
317
- };
318
-
319
- if (queueUrl.includes('.fifo')) {
320
- messageParameters.MessageDeduplicationId = (0, _uuid.v4)();
321
- messageParameters.MessageGroupId = messageGroupId !== null ? messageGroupId : (0, _uuid.v4)();
322
- }
323
-
324
- try {
325
- if (container.isOffline && this.constructor.offlineMode === SQS_OFFLINE_MODES.DIRECT) {
326
- await this.publishOffline(queue, messageParameters);
327
- } else {
328
- await this.sqs.sendMessage(messageParameters).promise();
329
- }
330
- } catch (error) {
331
- if (failureMode === SQS_PUBLISH_FAILURE_MODES.CATCH) {
332
- container.get(_Dependencies.DEFINITIONS.LOGGER).error(error);
333
- return null;
334
- }
335
-
336
- throw error;
337
- }
338
-
339
- return queue;
340
- }
341
- /**
342
- * Sends a message to a queue consumer running in serverless-offline.
343
- *
344
- * This method invokes the consumer function directly instead of sending the
345
- * message to SQS, which requires a real or emulated SQS service not provided
346
- * by serverless-offline. This works very well for local testing.
347
- *
348
- * @param queue
349
- * @param messageParameters
350
- */
351
-
352
-
353
- async publishOffline(queue, messageParameters) {
354
- const container = this.getContainer();
355
-
356
- if (!container.isOffline) {
357
- throw new Error('Can only publishOffline while running serverless offline.');
358
- }
359
-
360
- const consumers = container.getConfiguration('QUEUE_CONSUMERS') || {};
361
- const FunctionName = consumers[queue];
362
-
363
- if (!FunctionName) {
364
- throw new Error(`Queue consumer for queue ${queue} was not found. Please configure your application's QUEUE_CONSUMERS.`);
365
- }
366
-
367
- const InvocationType = 'RequestResponse';
368
- const Payload = JSON.stringify({
369
- Records: [{
370
- body: messageParameters.MessageBody
371
- }]
372
- });
373
- const parameters = {
374
- FunctionName,
375
- InvocationType,
376
- Payload
377
- };
378
- await this.lambda.invoke(parameters).promise();
379
- }
380
- /**
381
- * Receive from message queue
382
- *
383
- * @param queue string
384
- * @param timeout number
385
- * @returns {Promise<any>}
386
- */
387
-
388
-
389
- receive(queue, timeout = 15) {
390
- const container = this.getContainer();
391
- const queueUrl = this.queues[queue];
392
- const Logger = container.get(_Dependencies.DEFINITIONS.LOGGER);
393
- const Timer = container.get(_Dependencies.DEFINITIONS.TIMER);
394
- const timerId = `sqs-receive-message-${(0, _uuid.v4)()} - Queue: '${queueUrl}'`;
395
- return new Promise((resolve, reject) => {
396
- Timer.start(timerId);
397
- this.sqs.receiveMessage({
398
- QueueUrl: queueUrl,
399
- VisibilityTimeout: timeout,
400
- MaxNumberOfMessages: 10
401
- }, (error, data) => {
402
- Timer.stop(timerId);
403
-
404
- if (error) {
405
- Logger.error(error);
406
- return reject(error);
407
- }
408
-
409
- if (typeof data.Messages === 'undefined') {
410
- return resolve([]);
411
- }
412
-
413
- return resolve(data.Messages.map(message => new _Message.default(message)));
414
- });
415
- });
416
- }
417
-
418
- }
419
-
420
- exports.default = SQSService;
@@ -1,55 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- var _Dependencies = require("../Config/Dependencies");
9
-
10
- var _DependencyAware = _interopRequireDefault(require("../DependencyInjection/DependencyAware.class"));
11
-
12
- var _DependencyInjection = _interopRequireDefault(require("../DependencyInjection/DependencyInjection.class"));
13
-
14
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
-
16
- /**
17
- * TimerService class
18
- */
19
- class TimerService extends _DependencyAware.default {
20
- /**
21
- * TimerService constructor
22
- *
23
- * @param di
24
- */
25
- constructor(di) {
26
- super(di);
27
- this.timers = {};
28
- }
29
- /**
30
- * Start timer
31
- *
32
- * @param identifier
33
- */
34
-
35
-
36
- start(identifier) {
37
- this.timers[identifier] = Date.now();
38
- }
39
- /**
40
- * Stop timer
41
- *
42
- * @param identifier
43
- */
44
-
45
-
46
- stop(identifier) {
47
- if (typeof this.timers[identifier] !== 'undefined') {
48
- const duration = Date.now() - this.timers[identifier];
49
- this.getContainer().get(_Dependencies.DEFINITIONS.LOGGER).info(`Timing - ${identifier} took ${duration}ms to complete`);
50
- }
51
- }
52
-
53
- }
54
-
55
- exports.default = TimerService;
@@ -1,39 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- /**
9
- *
10
- */
11
- class LambdaTermination extends Error {
12
- /**
13
- * Triggers a Lambda Termination.
14
- * Offers developer details (that are logged)
15
- * an code for the Lambda and a front facing
16
- * consumer message.
17
- *
18
- * @param {object|string} internal
19
- * @param {number?} code
20
- * @param {object|string?} body
21
- * @param details
22
- */
23
- constructor(internal, code = 500, body = null, details = 'unknown error') {
24
- let stringified = internal;
25
-
26
- if (typeof internal !== 'string') {
27
- stringified = JSON.stringify(internal);
28
- }
29
-
30
- super(stringified);
31
- this.internal = internal;
32
- this.code = code;
33
- this.body = body || 'unknown error';
34
- this.details = details;
35
- }
36
-
37
- }
38
-
39
- exports.default = LambdaTermination;
@@ -1,164 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.handleSuccess = exports.handleError = exports.default = void 0;
7
-
8
- var _epsagon = _interopRequireDefault(require("epsagon"));
9
-
10
- var _Dependencies = require("../Config/Dependencies");
11
-
12
- var _DependencyInjection = _interopRequireDefault(require("../DependencyInjection/DependencyInjection.class"));
13
-
14
- var _Response = _interopRequireDefault(require("../Model/Response.model"));
15
-
16
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
-
18
- /* eslint-disable sonarjs/cognitive-complexity */
19
-
20
- /**
21
- * Processes the outcome once we have one
22
- *
23
- * @param di
24
- * @param outcome
25
- */
26
- const handleSuccess = (di, outcome) => {
27
- const logger = di.get(_Dependencies.DEFINITIONS.LOGGER); // Outcome may be undefined as not all lambdas have a return value.
28
-
29
- logger.metric('lambda.statusCode', outcome && outcome.statusCode || 200);
30
- return outcome;
31
- };
32
- /**
33
- * Gracefully handles an error
34
- * logging in Epsagon and generating
35
- * a response reflecting the `code`
36
- * of the error, if defined.
37
- *
38
- * Note about Epsagon:
39
- * Epsagon generates alerts for logs on level ERROR.
40
- * This means that logger.error will produce an alert.
41
- * To avoid not meaningful notifications, most likely
42
- * coming from tests, we log INFO unless either:
43
- *
44
- * 1. `error.raiseOnEpsagon` is defined & truthy
45
- * 2. `error.code` is defined and `error.code >= 500`.
46
- *
47
- * @param {DependencyInjection} di
48
- * @param {Error} error
49
- * @param {boolean} [throwError=false]
50
- */
51
-
52
-
53
- exports.handleSuccess = handleSuccess;
54
-
55
- const handleError = (di, error, throwError = false) => {
56
- const logger = di.get(_Dependencies.DEFINITIONS.LOGGER);
57
- logger.metric('lambda.statusCode', error.code || 500);
58
-
59
- if (error.raiseOnEpsagon || !error.code || error.code >= 500) {
60
- logger.error(error);
61
- } else {
62
- logger.info(error);
63
- }
64
-
65
- if (throwError) {
66
- if (error instanceof Error) {
67
- return error;
68
- } // We want to be absolutely sure
69
- // that we are returning an error
70
- // as Lambda sync handlers will only fail
71
- // if the object is instanceof Error
72
-
73
-
74
- return new Error(error);
75
- }
76
-
77
- const responseDetails = {
78
- body: error.body || {},
79
- code: error.code || 500,
80
- details: error.details || 'unknown error'
81
- };
82
- return _Response.default.generate(responseDetails.body, responseDetails.code, responseDetails.details);
83
- };
84
- /**
85
- * Lambda Wrapper.
86
- *
87
- * Wraps a lambda handler, generating a new function
88
- * that has access to the dependency injection
89
- * for the service and handles logging and exceptions.
90
- *
91
- * @param configuration
92
- * @param handler
93
- * @param throwError
94
- */
95
-
96
-
97
- exports.handleError = handleError;
98
-
99
- var _default = (configuration, handler, throwError = false) => {
100
- let instance = (event, context, callback) => {
101
- const di = new _DependencyInjection.default(configuration, event, context);
102
- const request = di.get(_Dependencies.DEFINITIONS.REQUEST);
103
- const logger = di.get(_Dependencies.DEFINITIONS.LOGGER);
104
- context.callbackWaitsForEmptyEventLoop = false; // If the event is to trigger a warm up, then don't bother returning the function.
105
-
106
- if (di.getEvent().source === 'serverless-plugin-warmup') {
107
- return callback(null, 'Lambda is warm!');
108
- } // Log the users ip address silently for use in error tracing
109
-
110
-
111
- if (request.getIp() !== null) {
112
- logger.metric('ipAddress', request.getIp(), true);
113
- } // Add metrics with user browser information for rapid debugging
114
-
115
-
116
- const userBrowserAndDevice = request.getUserBrowserAndDevice();
117
-
118
- if (userBrowserAndDevice !== null && typeof userBrowserAndDevice === 'object') {
119
- Object.keys(userBrowserAndDevice).forEach(metricKey => {
120
- logger.metric(metricKey, userBrowserAndDevice[metricKey], true);
121
- });
122
- }
123
-
124
- let outcome;
125
-
126
- try {
127
- outcome = handler.call(instance, di, request, callback);
128
-
129
- if (outcome instanceof Promise) {
130
- outcome = outcome.then(value => handleSuccess(di, value)).catch(error => {
131
- const handled = handleError(di, error, throwError);
132
-
133
- if (throwError) {
134
- // AWS Lambda with async handler is looking for a rejection
135
- // and not an error object directly
136
- // and will treat resolved errors as successful
137
- // as it will cast the error to JSON, i.e. `{}`
138
- throw handled;
139
- }
140
-
141
- return handled;
142
- });
143
- }
144
- } catch (error) {
145
- outcome = handleError(di, error, throwError);
146
- }
147
-
148
- return outcome;
149
- }; // If the Epsagon token is enabled, then wrap the instance in the Epsagon wrapper
150
-
151
-
152
- if (typeof process.env.EPSAGON_TOKEN === 'string' && process.env.EPSAGON_TOKEN !== 'undefined' && typeof process.env.EPSAGON_SERVICE_NAME === 'string' && process.env.EPSAGON_SERVICE_NAME !== 'undefined') {
153
- _epsagon.default.init({
154
- token: process.env.EPSAGON_TOKEN,
155
- appName: process.env.EPSAGON_SERVICE_NAME
156
- });
157
-
158
- instance = _epsagon.default.lambdaWrapper(instance);
159
- }
160
-
161
- return instance;
162
- };
163
-
164
- exports.default = _default;