idea-aws 3.6.2 → 3.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,974 +1,4 @@
1
- (function webpackUniversalModuleDefinition(root, factory) {
2
- if(typeof exports === 'object' && typeof module === 'object')
3
- module.exports = factory();
4
- else if(typeof define === 'function' && define.amd)
5
- define([], factory);
6
- else {
7
- var a = factory();
8
- for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
9
- }
10
- })(global, function() {
11
- return /******/ (() => { // webpackBootstrap
12
- /******/ "use strict";
13
- /******/ var __webpack_modules__ = ({
14
-
15
- /***/ 490:
16
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
17
-
18
-
19
- Object.defineProperty(exports, "__esModule", ({ value: true }));
20
- exports.Attachments = void 0;
21
- const dynamoDB_1 = __webpack_require__(823);
22
- const s3_1 = __webpack_require__(216);
23
- /**
24
- * A custom class that takes advantage of DynamoDB and S3 to easily manage attachments.
25
- */
26
- class Attachments {
27
- constructor() {
28
- /**
29
- * The bucket where from to retrieve the attachments. Fallback to IDEA's default one.
30
- */
31
- this.S3_ATTACHMENTS_BUCKET = process.env['S3_ATTACHMENTS_BUCKET'] || 'idea-attachments';
32
- this.IUID_ATTACHMENTS_PREFIX = process.env['IUID_ATTACHMENTS_PREFIX'] || 'ATT';
33
- this.dynamo = new dynamoDB_1.DynamoDB();
34
- this.s3 = new s3_1.S3();
35
- }
36
- /**
37
- * Get a signedURL to put an attachment.
38
- */
39
- put(project, teamId) {
40
- return new Promise((resolve, reject) => {
41
- this.dynamo
42
- .IUID(this.IUID_ATTACHMENTS_PREFIX.concat('_').concat(project).concat('_').concat(teamId))
43
- .then(attachmentId => {
44
- const signedURL = this.s3.signedURLPut(this.S3_ATTACHMENTS_BUCKET, attachmentId);
45
- signedURL.id = attachmentId;
46
- resolve(signedURL);
47
- })
48
- .catch(err => reject(err));
49
- });
50
- }
51
- /**
52
- * Get a signedURL to retrieve an attachment.
53
- */
54
- get(attachmentId) {
55
- const signedURL = this.s3.signedURLGet(this.S3_ATTACHMENTS_BUCKET, attachmentId);
56
- signedURL.id = attachmentId;
57
- return signedURL;
58
- }
59
- }
60
- exports.Attachments = Attachments;
61
-
62
-
63
- /***/ }),
64
-
65
- /***/ 920:
66
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
67
-
68
-
69
- Object.defineProperty(exports, "__esModule", ({ value: true }));
70
- exports.Cognito = void 0;
71
- const aws_sdk_1 = __webpack_require__(480);
72
- const idea_toolbox_1 = __webpack_require__(81);
73
- /**
74
- * A wrapper for AWS Cognito.
75
- */
76
- class Cognito {
77
- constructor() {
78
- this.cognito = new aws_sdk_1.CognitoIdentityServiceProvider({ apiVersion: '2016-04-18' });
79
- }
80
- /**
81
- * Change the region in which to find the user pool.
82
- * Default: the runner's (e.g. Lambda function) region.
83
- */
84
- setRegion(region) {
85
- // there is no quick way to change the region without re-creating the object
86
- this.cognito = new aws_sdk_1.CognitoIdentityServiceProvider({ apiVersion: this.cognito.config.apiVersion, region });
87
- }
88
- /**
89
- * Get the attributes of the user, from the authorizer claims.
90
- * @param claims authorizer claims
91
- * @return user's data
92
- */
93
- getUserByClaims(claims) {
94
- if (!claims)
95
- return null;
96
- const user = {};
97
- // add any additional cognito attribute available in cognito
98
- for (const p in claims)
99
- if (p.startsWith('cognito:'))
100
- user[p.slice(8)] = claims[p];
101
- // map the important attributes with reserved names
102
- user.userId = claims.sub;
103
- user.email = claims.email;
104
- return user;
105
- }
106
- /**
107
- * Identify a user by its email address, returning its attributes.
108
- */
109
- getUserByEmail(email, cognitoUserPoolId) {
110
- return new Promise((resolve, reject) => {
111
- // find the user by the email
112
- this.cognito.adminGetUser({ UserPoolId: cognitoUserPoolId, Username: email }, (err, data) => {
113
- if (err || !data)
114
- reject(err);
115
- else {
116
- // convert and return the attributes
117
- const userAttributes = {};
118
- data.UserAttributes.forEach((a) => (userAttributes[a.Name] = a.Value));
119
- resolve(userAttributes);
120
- }
121
- });
122
- });
123
- }
124
- /**
125
- * Identify a user by its userId (sub), returning its attributes.
126
- */
127
- getUserBySub(sub, cognitoUserPoolId) {
128
- return new Promise((resolve, reject) => {
129
- // find the user by the sub
130
- this.cognito.listUsers({ UserPoolId: cognitoUserPoolId, Filter: `sub = "${sub}"`, Limit: 1 }, (err, data) => {
131
- if (err || !data || !data.Users || !data.Users[0])
132
- reject(err);
133
- else {
134
- // convert and return the attributes
135
- const userAttributes = {};
136
- data.Users[0].Attributes.forEach((a) => (userAttributes[a.Name] = a.Value));
137
- resolve(userAttributes);
138
- }
139
- });
140
- });
141
- }
142
- /**
143
- * Create a new user (by its email) in the pool specified.
144
- * @return userId of the new user
145
- */
146
- createUser(email, cognitoUserPoolId, options) {
147
- return new Promise((resolve, reject) => {
148
- options = options || {};
149
- if (idea_toolbox_1.isEmpty(email, 'email'))
150
- return reject(new Error('INVALID_EMAIL'));
151
- const attributes = [
152
- { Name: 'email', Value: email },
153
- { Name: 'email_verified', Value: 'true' }
154
- ];
155
- const params = {
156
- UserPoolId: cognitoUserPoolId,
157
- Username: email,
158
- UserAttributes: attributes
159
- };
160
- if (options.skipNotification)
161
- params.MessageAction = 'SUPPRESS';
162
- if (options.temporaryPassword)
163
- params.TemporaryPassword = options.temporaryPassword;
164
- this.cognito.adminCreateUser(params, (err, data) => {
165
- idea_toolbox_1.logger('COGNITO CREATE USER', err);
166
- if (err)
167
- switch (err.name) {
168
- case 'UsernameExistsException':
169
- return reject(new Error('USERNAME_ALREADY_EXISTS'));
170
- case 'InvalidPasswordException':
171
- return reject(new Error('INVALID_PASSWORD'));
172
- default:
173
- return reject(err);
174
- }
175
- const userId = data.User.Attributes.find((attr) => attr.Name === 'sub').Value || null;
176
- if (userId)
177
- resolve(userId);
178
- else
179
- reject(new Error('CREATION_FAILED'));
180
- });
181
- });
182
- }
183
- /**
184
- * Resend the password to a user who never logged in.
185
- */
186
- resendPassword(email, cognitoUserPoolId, options) {
187
- return new Promise((resolve, reject) => {
188
- options = options || {};
189
- if (idea_toolbox_1.isEmpty(email, 'email'))
190
- return reject(new Error('INVALID_EMAIL'));
191
- const params = {
192
- UserPoolId: cognitoUserPoolId,
193
- Username: email,
194
- MessageAction: 'RESEND'
195
- };
196
- if (options.temporaryPassword)
197
- params.TemporaryPassword = options.temporaryPassword;
198
- this.cognito.adminCreateUser(params, (err) => {
199
- idea_toolbox_1.logger('COGNITO RESEND PASSWORD', err);
200
- if (err)
201
- switch (err.name) {
202
- case 'UnsupportedUserStateException':
203
- return reject(new Error('USER_ALREADY_CONFIRMED_PASSWORD'));
204
- default:
205
- return reject(err);
206
- }
207
- else
208
- resolve();
209
- });
210
- });
211
- }
212
- /**
213
- * Delete a user by its email (username), in the pool specified.
214
- */
215
- deleteUser(email, cognitoUserPoolId) {
216
- return new Promise((resolve, reject) => {
217
- if (idea_toolbox_1.isEmpty(email, 'email'))
218
- return reject(new Error('INVALID_EMAIL'));
219
- this.cognito.adminDeleteUser({ UserPoolId: cognitoUserPoolId, Username: email }, (err) => {
220
- idea_toolbox_1.logger('COGNITO DELETE USER', err);
221
- if (err)
222
- reject(new Error('DELETION_FAILED'));
223
- else
224
- resolve();
225
- });
226
- });
227
- }
228
- /**
229
- * Sign in a user of a specific pool through username and password.
230
- */
231
- signIn(email, password, cognitoUserPoolId, cognitoUserPoolClientId) {
232
- return new Promise((resolve, reject) => {
233
- this.cognito.adminInitiateAuth({
234
- UserPoolId: cognitoUserPoolId,
235
- ClientId: cognitoUserPoolClientId,
236
- AuthFlow: 'ADMIN_NO_SRP_AUTH',
237
- AuthParameters: { USERNAME: email, PASSWORD: password }
238
- }, (err, data) => {
239
- idea_toolbox_1.logger('COGNITO SIGN IN', err);
240
- if (err || !data.AuthenticationResult)
241
- reject(err);
242
- else
243
- resolve(data.AuthenticationResult);
244
- });
245
- });
246
- }
247
- /**
248
- * Given a username and a refresh token (and pool data), refresh the session and return the new tokens.
249
- */
250
- refreshSession(email, refreshToken, cognitoUserPoolId, cognitoUserPoolClientId) {
251
- return new Promise((resolve, reject) => {
252
- this.cognito.adminInitiateAuth({
253
- UserPoolId: cognitoUserPoolId,
254
- ClientId: cognitoUserPoolClientId,
255
- AuthFlow: 'REFRESH_TOKEN_AUTH',
256
- AuthParameters: { USERNAME: email, REFRESH_TOKEN: refreshToken }
257
- }, (err, data) => {
258
- idea_toolbox_1.logger('COGNITO REFRESH TOKEN', err);
259
- if (err || !data.AuthenticationResult)
260
- reject(err);
261
- else
262
- resolve(data.AuthenticationResult);
263
- });
264
- });
265
- }
266
- /**
267
- * Change the email address (== username) associated to a user.
268
- */
269
- updateEmail(email, newEmail, cognitoUserPoolId) {
270
- return new Promise((resolve, reject) => {
271
- if (idea_toolbox_1.isEmpty(newEmail, 'email'))
272
- return reject(new Error('INVALID_NEW_EMAIL'));
273
- this.cognito.adminUpdateUserAttributes({
274
- UserPoolId: cognitoUserPoolId,
275
- Username: email,
276
- UserAttributes: [
277
- { Name: 'email', Value: newEmail },
278
- { Name: 'email_verified', Value: 'true' }
279
- ]
280
- }, (err) => {
281
- idea_toolbox_1.logger('COGNITO UPDATE EMAIL', err);
282
- if (err)
283
- reject(err);
284
- // sign out the user from all its devices and resolve
285
- else
286
- this.globalSignOut(newEmail, cognitoUserPoolId)
287
- .then(() => resolve())
288
- .catch(e => reject(e));
289
- });
290
- });
291
- }
292
- /**
293
- * Change the password to sign in for a user.
294
- */
295
- updatePassword(email, oldPassword, newPassword, cognitoUserPoolId, cognitoUserPoolClientId) {
296
- return new Promise((resolve, reject) => {
297
- if (newPassword.length < 8)
298
- return reject(new Error('INVALID_NEW_PASSWORD'));
299
- // get a token to run the password change
300
- this.signIn(email, oldPassword, cognitoUserPoolId, cognitoUserPoolClientId)
301
- .then((data) => {
302
- // request the password change
303
- this.cognito.changePassword({
304
- AccessToken: data.AccessToken,
305
- PreviousPassword: oldPassword,
306
- ProposedPassword: newPassword
307
- }, (err) => {
308
- idea_toolbox_1.logger('COGNITO UPDATE PASSWORD', err);
309
- if (err)
310
- reject(err);
311
- else
312
- resolve();
313
- });
314
- })
315
- .catch(err => reject(err));
316
- });
317
- }
318
- /**
319
- * Sign out the user from all devices.
320
- */
321
- globalSignOut(email, cognitoUserPoolId) {
322
- return new Promise((resolve, reject) => {
323
- this.cognito.adminUserGlobalSignOut({ Username: email, UserPoolId: cognitoUserPoolId }, (err) => {
324
- idea_toolbox_1.logger('COGNITO GLOBAL SIGN OUT', err);
325
- if (err)
326
- reject(err);
327
- else
328
- resolve();
329
- });
330
- });
331
- }
332
- /**
333
- * Confirm and conclude a registration, usign a confirmation code.
334
- */
335
- confirmSignUp(email, confirmationCode, cognitoUserPoolClientId) {
336
- return new Promise((resolve, reject) => {
337
- if (!email)
338
- return reject(new Error('INVALID_EMAIL'));
339
- if (!confirmationCode)
340
- return reject(new Error('INVALID_CONFIRMATION_CODE'));
341
- if (!cognitoUserPoolClientId)
342
- return reject(new Error('INVALID_CLIENT_ID'));
343
- // conclude the registration (sign-up) flow, using a provided confirmation code
344
- this.cognito.confirmSignUp({ Username: email, ConfirmationCode: confirmationCode, ClientId: cognitoUserPoolClientId }, (err) => {
345
- idea_toolbox_1.logger('COGNITO CONFIRM SIGN UP', err);
346
- if (err)
347
- reject(err);
348
- else
349
- resolve();
350
- });
351
- });
352
- }
353
- /**
354
- * List the groups of the user pool.
355
- */
356
- listGroups(cognitoUserPoolId) {
357
- return new Promise((resolve, reject) => {
358
- this.cognito.listGroups({ UserPoolId: cognitoUserPoolId }, (err, data) => {
359
- idea_toolbox_1.logger('COGNITO LIST GROUPS', err);
360
- if (err)
361
- return reject(err);
362
- const groups = data.Groups.map(g => ({ name: g.GroupName, description: g.Description }));
363
- resolve(groups);
364
- });
365
- });
366
- }
367
- /**
368
- * List the users part of a group in the user pool.
369
- */
370
- listUsersInGroup(group, cognitoUserPoolId) {
371
- return new Promise((resolve, reject) => {
372
- this.cognito.listUsersInGroup({ UserPoolId: cognitoUserPoolId, GroupName: group }, (err, data) => {
373
- idea_toolbox_1.logger('COGNITO LIST USERS IN GROUP', err);
374
- if (err)
375
- return reject(err);
376
- // convert the Cognito Users into the IDEA Users format
377
- const users = data.Users.map(u => {
378
- const userAttributes = {};
379
- u.Attributes.forEach((a) => (userAttributes[a.Name] = a.Value));
380
- return new idea_toolbox_1.User({ userId: userAttributes.sub, email: userAttributes.email, createdAt: u.UserCreateDate });
381
- });
382
- resolve(users);
383
- });
384
- });
385
- }
386
- /**
387
- * Add a user (by email) to a group in the user pool.
388
- */
389
- addUserToGroup(email, group, cognitoUserPoolId) {
390
- return new Promise((resolve, reject) => {
391
- this.getUserByEmail(email, cognitoUserPoolId).then(userData => {
392
- const user = new idea_toolbox_1.User({ userId: userData.sub, email: userData.email });
393
- this.cognito.adminAddUserToGroup({ UserPoolId: cognitoUserPoolId, GroupName: group, Username: user.userId }, err => {
394
- idea_toolbox_1.logger('COGNITO ADD USER TO GROUP', err);
395
- if (err)
396
- reject(err);
397
- else
398
- resolve(user);
399
- });
400
- });
401
- });
402
- }
403
- /**
404
- * Remove a user (by email) from a group in the user pool.
405
- */
406
- removeUserFromGroup(email, group, cognitoUserPoolId) {
407
- return new Promise((resolve, reject) => {
408
- this.getUserByEmail(email, cognitoUserPoolId).then(userData => {
409
- const user = new idea_toolbox_1.User({ userId: userData.sub, email: userData.email });
410
- this.cognito.adminRemoveUserFromGroup({ UserPoolId: cognitoUserPoolId, GroupName: group, Username: user.userId }, err => {
411
- idea_toolbox_1.logger('COGNITO REMOVE USER FROM GROUP', err);
412
- if (err)
413
- reject(err);
414
- else
415
- resolve(user);
416
- });
417
- });
418
- });
419
- }
420
- }
421
- exports.Cognito = Cognito;
422
-
423
-
424
- /***/ }),
425
-
426
- /***/ 132:
427
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
428
-
429
-
430
- Object.defineProperty(exports, "__esModule", ({ value: true }));
431
- exports.Comprehend = void 0;
432
- const aws_sdk_1 = __webpack_require__(480);
433
- /**
434
- * A wrapper for Amazon Comprehend.
435
- */
436
- class Comprehend {
437
- constructor() {
438
- this.comprehend = new aws_sdk_1.Comprehend({ apiVersion: '2017-11-27' });
439
- }
440
- /**
441
- * Inspects text and returns an inference of the prevailing sentiment (POSITIVE, NEUTRAL, MIXED, or NEGATIVE).
442
- */
443
- detectSentiment(params) {
444
- return new Promise((resolve, reject) => {
445
- // check for obligatory params
446
- if (!params.language || !params.text)
447
- return reject(new Error('MISSING_PARAMETERS'));
448
- // execute the sentiment detection
449
- this.comprehend.detectSentiment({ LanguageCode: params.language, Text: params.text }, (err, data) => {
450
- if (err)
451
- reject(err);
452
- else
453
- resolve(data.Sentiment);
454
- });
455
- });
456
- }
457
- }
458
- exports.Comprehend = Comprehend;
459
-
460
-
461
- /***/ }),
462
-
463
- /***/ 823:
464
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
465
-
466
-
467
- Object.defineProperty(exports, "__esModule", ({ value: true }));
468
- exports.DynamoDB = void 0;
469
- const UUIDV4 = __webpack_require__(180);
470
- const nanoid_1 = __webpack_require__(324);
471
- const aws_sdk_1 = __webpack_require__(480);
472
- const shortid_1 = __webpack_require__(942);
473
- const idea_toolbox_1 = __webpack_require__(81);
474
- /**
475
- * A wrapper for AWS DynamoDB.
476
- */
477
- class DynamoDB {
478
- /**
479
- * Initialize a new DynamoDB helper object.
480
- */
481
- constructor() {
482
- this.dynamo = new aws_sdk_1.DynamoDB.DocumentClient();
483
- }
484
- /**
485
- * Convert a JSON object from dynamoDB format to simple JSON.
486
- */
487
- unmarshall(data, options) {
488
- return aws_sdk_1.DynamoDB.Converter.unmarshall(data, options);
489
- }
490
- /**
491
- * Returns an IUID: IDEA's Unique IDentifier, which is an id unique through all IDEA's projects.
492
- * Note: there's no need of an authorization check for extrernal uses: the permissions depend
493
- * from the context in which it's executed.
494
- * @deprecated use IUNID instead (nano version)
495
- * @param project project code
496
- * @return the IUID
497
- */
498
- IUID(project) {
499
- const MAX_ATTEMPTS = 3;
500
- return new Promise((resolve, reject) => {
501
- if (!project)
502
- reject();
503
- else
504
- this.iuidHelper(project, 0, MAX_ATTEMPTS, resolve, reject);
505
- });
506
- }
507
- iuidHelper(project, attempt, maxAttempts, resolve, reject) {
508
- if (attempt > maxAttempts)
509
- reject();
510
- else {
511
- const id = UUIDV4();
512
- this.put({
513
- TableName: 'idea_IUID',
514
- Item: { project, id },
515
- ConditionExpression: 'NOT (#p = :project AND #id = :id)',
516
- ExpressionAttributeNames: { '#p': 'project', '#id': 'id' },
517
- ExpressionAttributeValues: { ':project': project, ':id': id }
518
- })
519
- .then(() => resolve(`${project}_${id}`))
520
- .catch(() =>
521
- // ID exists, try again
522
- this.iuidHelper(project, attempt + 1, maxAttempts, resolve, reject));
523
- }
524
- }
525
- /**
526
- * Returns an IUNID: IDEA's Unique Nano IDentifier, which is an id unique through all IDEA's projects.
527
- * Note: no need of an auth check for external uses: the permissions depend from the context in which it's executed.
528
- * @param project project code
529
- * @return the IUNID
530
- */
531
- IUNID(project) {
532
- const MAX_ATTEMPTS = 3;
533
- return new Promise((resolve, reject) => {
534
- if (!project)
535
- reject();
536
- else
537
- this.iunidHelper(project, 0, MAX_ATTEMPTS, resolve, reject);
538
- });
539
- }
540
- iunidHelper(project, attempt, maxAttempts, resolve, reject) {
541
- if (attempt > maxAttempts)
542
- reject();
543
- else {
544
- const id = nanoid_1.nanoid();
545
- this.put({
546
- TableName: 'idea_IUNID',
547
- Item: { project, id },
548
- ConditionExpression: 'NOT (#p = :project AND #id = :id)',
549
- ExpressionAttributeNames: { '#p': 'project', '#id': 'id' },
550
- ExpressionAttributeValues: { ':project': project, ':id': id }
551
- })
552
- .then(() => resolve(`${project}#${id}`))
553
- .catch(() =>
554
- // ID exists, try again
555
- this.iunidHelper(project, attempt + 1, maxAttempts, resolve, reject));
556
- }
557
- }
558
- /**
559
- * Returns an ISID: IDEA's Short IDentifier, which is a short, unique id through a single project.
560
- * Note: there's no need of an authorization check for extrernal uses: the permissions depend
561
- * from the context in which it's executed.
562
- * @param project project code
563
- * @return the ISID
564
- */
565
- ISID(project) {
566
- const MAX_ATTEMPTS = 3;
567
- // avoid _ characters (to avoid concatenation problems with ids) -- it must be anyway 64 chars-long
568
- shortid_1.characters('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-@');
569
- return new Promise((resolve, reject) => {
570
- if (!project)
571
- reject();
572
- else
573
- this.isidHelper(project, 0, MAX_ATTEMPTS, resolve, reject);
574
- });
575
- }
576
- isidHelper(project, attempt, maxAttempts, resolve, reject) {
577
- if (attempt > maxAttempts)
578
- reject();
579
- else {
580
- const id = shortid_1.generate();
581
- this.put({
582
- TableName: 'idea_ISID',
583
- Item: { project, id },
584
- ConditionExpression: 'NOT (#p = :project AND #id = :id)',
585
- ExpressionAttributeNames: { '#p': 'project', '#id': 'id' },
586
- ExpressionAttributeValues: { ':project': project, ':id': id }
587
- })
588
- .then(() => resolve(id))
589
- .catch(() =>
590
- // ID exists, try again
591
- this.isidHelper(project, attempt + 1, maxAttempts, resolve, reject));
592
- }
593
- }
594
- /**
595
- * Manage atomic counters (atomic autoincrement values) in IDEA's projects.
596
- * They key of an atomic counter should be composed as the following: `DynamoDBTableName_uniqueKey`.
597
- * @param key the key of the counter
598
- */
599
- getAtomicCounterByKey(key) {
600
- return new Promise((resolve, reject) => {
601
- idea_toolbox_1.logger('GET ATOMIC COUNTER');
602
- this.update({
603
- TableName: 'idea_atomicCounters',
604
- Key: { key },
605
- UpdateExpression: 'ADD atomicCounter :increment',
606
- ExpressionAttributeValues: { ':increment': 1 },
607
- ReturnValues: 'UPDATED_NEW'
608
- })
609
- .then((data) => resolve(data.Attributes.atomicCounter))
610
- .catch(err => reject(err));
611
- });
612
- }
613
- /**
614
- * Get an item of a DynamoDB table.
615
- */
616
- get(params) {
617
- return new Promise((resolve, reject) => {
618
- this.dynamo.get(params, (err, data) => {
619
- idea_toolbox_1.logger(`GET ${params.TableName}`, err);
620
- if (err || !data.Item)
621
- reject(err);
622
- else
623
- resolve(data.Item);
624
- });
625
- });
626
- }
627
- /**
628
- * Put an item in a DynamoDB table.
629
- */
630
- put(params) {
631
- return new Promise((resolve, reject) => {
632
- this.dynamo.put(params, (err, data) => {
633
- idea_toolbox_1.logger(`PUT ${params.TableName}`, err);
634
- if (err)
635
- reject(err);
636
- else
637
- resolve(data);
638
- });
639
- });
640
- }
641
- /**
642
- * Update an item of a DynamoDB table.
643
- */
644
- update(params) {
645
- return new Promise((resolve, reject) => {
646
- this.dynamo.update(params, (err, data) => {
647
- idea_toolbox_1.logger(`UPDATE ${params.TableName}`, err);
648
- if (err)
649
- reject(err);
650
- else
651
- resolve(data);
652
- });
653
- });
654
- }
655
- /**
656
- * Delete an item of a DynamoDB table.
657
- */
658
- delete(params) {
659
- return new Promise((resolve, reject) => {
660
- this.dynamo.delete(params, (err, data) => {
661
- idea_toolbox_1.logger(`DELETE ${params.TableName}`, err);
662
- if (err)
663
- reject(err);
664
- else
665
- resolve(data);
666
- });
667
- });
668
- }
669
- /**
670
- * Get group of items based on their keys from DynamoDb table, avoiding the limits of DynamoDB's BatchGetItem.
671
- * @param ignoreErr if set, ignore the errors and continue the bulk op.
672
- */
673
- batchGet(table, keys, ignoreErr) {
674
- return new Promise((resolve, reject) => {
675
- if (!keys.length) {
676
- idea_toolbox_1.logger(`BATCH GET ${table}`, null, 'No elements to get');
677
- resolve([]);
678
- }
679
- else
680
- this.batchGetHelper(table, keys, [], Boolean(ignoreErr), 0, 100, resolve, reject);
681
- });
682
- }
683
- batchGetHelper(t, keys, elements, iErr, curr, size, resolve, reject) {
684
- // prepare the structure for the bulk operation
685
- const batch = { RequestItems: {} };
686
- batch.RequestItems[t] = { Keys: [] };
687
- batch.RequestItems[t].Keys = keys.slice(curr, curr + size);
688
- // execute the bulk operation
689
- this.dynamo.batchGet(batch, (err, data) => {
690
- idea_toolbox_1.logger(`BATCH GET ${t}`, err, `${curr} of ${keys.length}`);
691
- if (err && !iErr)
692
- return reject(err);
693
- // concat the results
694
- elements = elements.concat(data.Responses[t]);
695
- // if there are still chunks to manage, go on recursively
696
- if (curr + size < keys.length)
697
- this.batchGetHelper(t, keys, elements, iErr, curr + size, size, resolve, reject);
698
- // no more chunks to manage: we're done
699
- else
700
- resolve(elements);
701
- });
702
- }
703
- /**
704
- * Put an array of items in a DynamoDb table, avoiding the limits of DynamoDB's BatchWriteItem.
705
- * @param ignoreErr if true, ignore the errors and continue the bulk op
706
- */
707
- batchPut(table, items, ignoreErr) {
708
- return new Promise((resolve, reject) => {
709
- if (!items.length) {
710
- idea_toolbox_1.logger(`BATCH WRITE (PUT) ${table}`, null, 'No elements to write');
711
- resolve();
712
- }
713
- else
714
- this.batchWriteHelper(table, items, true, Boolean(ignoreErr), 0, 25, resolve, reject);
715
- });
716
- }
717
- /**
718
- * Delete an array of items from a DynamoDb table, avoiding the limits of DynamoDB's BatchWriteItem.
719
- * @param ignoreErr if true, ignore the errors and continue the bulk op.
720
- */
721
- batchDelete(table, keys, ignoreErr) {
722
- return new Promise((resolve, reject) => {
723
- if (keys.length === 0) {
724
- idea_toolbox_1.logger(`BATCH WRITE (DELETE) ${table}`, null, 'No elements to write');
725
- resolve();
726
- }
727
- else
728
- this.batchWriteHelper(table, keys, false, Boolean(ignoreErr), 0, 25, resolve, reject);
729
- });
730
- }
731
- batchWriteHelper(t, items, isPut, iErr, curr, size, resolve, reject) {
732
- // prepare the structure for the bulk operation
733
- const batch = { RequestItems: {} };
734
- if (isPut) {
735
- batch.RequestItems[t] = items.slice(curr, curr + size).map(i => ({ PutRequest: { Item: i } }));
736
- }
737
- else {
738
- // isDelete
739
- batch.RequestItems[t] = items.slice(curr, curr + size).map(k => ({ DeleteRequest: { Key: k } }));
740
- }
741
- // execute the bulk operation
742
- this.dynamo.batchWrite(batch, (err) => {
743
- idea_toolbox_1.logger(`BATCH WRITE (${isPut ? 'PUT' : 'DELETE'}) ${t}`, err, `${curr} of ${items.length}`);
744
- if (err && !iErr)
745
- reject(err);
746
- // if there are still chunks to manage, go on recursively
747
- else if (curr + size < items.length)
748
- this.batchWriteHelper(t, items, isPut, iErr, curr + size, size, resolve, reject);
749
- // no more chunks to manage: we're done
750
- else
751
- resolve();
752
- });
753
- }
754
- /**
755
- * Query a DynamoDb table, avoiding the limits of DynamoDB's Query.
756
- * @param params the params to apply to DynamoDB's function
757
- */
758
- query(params) {
759
- return new Promise((resolve, reject) => {
760
- this.queryScanHelper(params, [], true, resolve, reject);
761
- });
762
- }
763
- /**
764
- * Scan a DynamoDb table, avoiding the limits of DynamoDB's Query.
765
- * @param params the params to apply to DynamoDB's function
766
- */
767
- scan(params) {
768
- return new Promise((resolve, reject) => {
769
- this.queryScanHelper(params, [], false, resolve, reject);
770
- });
771
- }
772
- queryScanHelper(params, items, isQuery, resolve, reject) {
773
- const f = isQuery ? 'query' : 'scan';
774
- this.dynamo[f](params, (err, data) => {
775
- if (err || !data || !data.Items) {
776
- idea_toolbox_1.logger(`${f.toUpperCase()} ${params.TableName}`, err);
777
- return reject(err);
778
- }
779
- items = items.concat(data.Items);
780
- if (data.LastEvaluatedKey) {
781
- params.ExclusiveStartKey = data.LastEvaluatedKey;
782
- this.queryScanHelper(params, items, isQuery, resolve, reject);
783
- }
784
- else {
785
- idea_toolbox_1.logger(`${f.toUpperCase()} ${params.TableName}`, null, items.length);
786
- resolve(items);
787
- }
788
- });
789
- }
790
- /**
791
- * Query a DynamoDb table in the traditional way (no pagination or data mapping).
792
- * @param params the params to apply to DynamoDB's function
793
- */
794
- queryClassic(params) {
795
- return new Promise((resolve, reject) => {
796
- this.queryScanClassicHelper(params, true, resolve, reject);
797
- });
798
- }
799
- /**
800
- * Scan a DynamoDb table in the traditional way (no pagination or data mapping).
801
- * @param params the params to apply to DynamoDB's function
802
- */
803
- scanClassic(params) {
804
- return new Promise((resolve, reject) => {
805
- this.queryScanClassicHelper(params, false, resolve, reject);
806
- });
807
- }
808
- queryScanClassicHelper(params, isQuery, resolve, reject) {
809
- const f = isQuery ? 'query' : 'scan';
810
- this.dynamo[f](params, (err, data) => {
811
- idea_toolbox_1.logger(`${f.toUpperCase()} classic ${params.TableName}`, err, data && data.Items ? data.Items.length : 0);
812
- if (err || !data)
813
- reject(err);
814
- else
815
- resolve(data);
816
- });
817
- }
818
- /**
819
- * Execute a series of max 10 write operations in a single transaction.
820
- * @param ops the operations to execute in the transaction
821
- */
822
- transactWrites(ops) {
823
- return new Promise((resolve, reject) => {
824
- if (!ops.length) {
825
- idea_toolbox_1.logger('TRANSACTION WRITES', null, 'No elements to write');
826
- resolve();
827
- }
828
- else
829
- this.dynamo.transactWrite({ TransactItems: ops.slice(0, 10) }, (err) => {
830
- idea_toolbox_1.logger('TRANSACTION WRITES', err);
831
- if (err)
832
- reject(err);
833
- else
834
- resolve();
835
- });
836
- });
837
- }
838
- /**
839
- * Creates a set of elements (DynamoDB format) inferring the type of set from the type of the first element.
840
- */
841
- createSet(array, options) {
842
- return this.dynamo.createSet(array, options);
843
- }
844
- }
845
- exports.DynamoDB = DynamoDB;
846
-
847
-
848
- /***/ }),
849
-
850
- /***/ 838:
851
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
852
-
853
-
854
- Object.defineProperty(exports, "__esModule", ({ value: true }));
855
- exports.GenericController = void 0;
856
- const idea_toolbox_1 = __webpack_require__(81);
857
- const dynamoDB_1 = __webpack_require__(823);
858
- const cognito_1 = __webpack_require__(920);
859
- const s3_1 = __webpack_require__(216);
860
- const ses_1 = __webpack_require__(887);
861
- const sns_1 = __webpack_require__(187);
862
- const translate_1 = __webpack_require__(580);
863
- const comprehend_1 = __webpack_require__(132);
864
- const attachments_1 = __webpack_require__(490);
865
- /**
866
- * An abstract class to inherit to manage some resources with an AWS Lambda function.
867
- */
868
- class GenericController {
869
- /**
870
- * Initialize a new GenericController helper object.
871
- * @param event the event that invoked the AWS lambda function
872
- * @param callback the callback to resolve or reject the execution
873
- */
874
- constructor(event, callback, options) {
875
- options = options || {};
876
- this.event = event;
877
- this.callback = callback;
878
- this.tables = options.tables || {};
879
- // set the logs to print objects deeper
880
- __webpack_require__(669).inspect.defaultOptions.depth = null;
881
- }
882
- /**
883
- * Default callback for the Lambda.
884
- */
885
- done(err, res) {
886
- idea_toolbox_1.logger(err ? 'DONE WITH ERRORS' : 'DONE', err, res, true);
887
- this.callback(err, res);
888
- }
889
- ///
890
- /// AWS SERVICES
891
- ///
892
- get dynamoDB() {
893
- if (!this._dynamoDB)
894
- this._dynamoDB = new dynamoDB_1.DynamoDB();
895
- return this._dynamoDB;
896
- }
897
- set dynamoDB(dynamoDB) {
898
- this._dynamoDB = dynamoDB;
899
- }
900
- get cognito() {
901
- if (!this._cognito)
902
- this._cognito = new cognito_1.Cognito();
903
- return this._cognito;
904
- }
905
- set cognito(cognito) {
906
- this._cognito = cognito;
907
- }
908
- get s3() {
909
- if (!this._s3)
910
- this._s3 = new s3_1.S3();
911
- return this._s3;
912
- }
913
- set s3(s3) {
914
- this._s3 = s3;
915
- }
916
- get ses() {
917
- if (!this._ses)
918
- this._ses = new ses_1.SES();
919
- return this._ses;
920
- }
921
- set ses(ses) {
922
- this._ses = ses;
923
- }
924
- get sns() {
925
- if (!this._sns)
926
- this._sns = new sns_1.SNS();
927
- return this._sns;
928
- }
929
- set sns(sns) {
930
- this._sns = sns;
931
- }
932
- get translate() {
933
- if (!this._translate)
934
- this._translate = new translate_1.Translate();
935
- return this._translate;
936
- }
937
- set translate(translate) {
938
- this._translate = translate;
939
- }
940
- get comprehend() {
941
- if (!this._comprehend)
942
- this._comprehend = new comprehend_1.Comprehend();
943
- return this._comprehend;
944
- }
945
- set comprehend(comprehend) {
946
- this._comprehend = comprehend;
947
- }
948
- ///
949
- /// HELPERS
950
- ///
951
- /**
952
- * Manage attachments (through SignedURLs).
953
- */
954
- get attachments() {
955
- if (!this._attachments)
956
- this._attachments = new attachments_1.Attachments();
957
- return this._attachments;
958
- }
959
- set attachments(attachments) {
960
- this._attachments = attachments;
961
- }
962
- }
963
- exports.GenericController = GenericController;
964
-
965
-
966
- /***/ }),
967
-
968
- /***/ 341:
969
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
970
-
971
-
1
+ "use strict";
972
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
973
3
  if (k2 === undefined) k2 = k;
974
4
  Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
@@ -977,1051 +7,17 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
977
7
  o[k2] = m[k];
978
8
  }));
979
9
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
980
- for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
981
11
  };
982
- Object.defineProperty(exports, "__esModule", ({ value: true }));
983
- __exportStar(__webpack_require__(629), exports);
984
- __exportStar(__webpack_require__(296), exports);
985
- __exportStar(__webpack_require__(823), exports);
986
- __exportStar(__webpack_require__(920), exports);
987
- __exportStar(__webpack_require__(132), exports);
988
- __exportStar(__webpack_require__(216), exports);
989
- __exportStar(__webpack_require__(887), exports);
990
- __exportStar(__webpack_require__(187), exports);
991
- __exportStar(__webpack_require__(580), exports);
992
- __exportStar(__webpack_require__(490), exports);
993
-
994
-
995
- /***/ }),
996
-
997
- /***/ 629:
998
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
999
-
1000
-
1001
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1002
- exports.ResourceController = void 0;
1003
- /* eslint-disable no-invalid-this */
1004
- const fs_1 = __webpack_require__(747);
1005
- const aws_sdk_1 = __webpack_require__(480);
1006
- const idea_toolbox_1 = __webpack_require__(81);
1007
- const genericController_1 = __webpack_require__(838);
1008
- /**
1009
- * An abstract class to inherit to manage API requests (AWS API Gateway) in an AWS Lambda function.
1010
- */
1011
- class ResourceController extends genericController_1.GenericController {
1012
- constructor(event, callback, options) {
1013
- var _a, _b, _c, _d, _e;
1014
- super(event, callback, options);
1015
- this.templateMatcher = /{{\s?([^{}\s]*)\s?}}/g;
1016
- ///
1017
- /// REQUEST HANDLERS
1018
- ///
1019
- this.handleRequest = () => {
1020
- // check the authorizations and prepare the API request
1021
- this.checkAuthBeforeRequest()
1022
- .then(() => {
1023
- let request;
1024
- if (this.resourceId)
1025
- switch (this.httpMethod) {
1026
- // resource/{resourceId}
1027
- case 'GET':
1028
- request = this.getResource();
1029
- break;
1030
- case 'POST':
1031
- request = this.postResource();
1032
- break;
1033
- case 'PUT':
1034
- request = this.putResource();
1035
- break;
1036
- case 'DELETE':
1037
- request = this.deleteResource();
1038
- break;
1039
- case 'PATCH':
1040
- request = this.patchResource();
1041
- break;
1042
- case 'HEAD':
1043
- request = this.headResource();
1044
- break;
1045
- default: /* nope */
1046
- }
1047
- else
1048
- switch (this.httpMethod) {
1049
- // resource
1050
- case 'GET':
1051
- request = this.getResources();
1052
- break;
1053
- case 'POST':
1054
- request = this.postResources();
1055
- break;
1056
- case 'PUT':
1057
- request = this.putResources();
1058
- break;
1059
- case 'DELETE':
1060
- request = this.deleteResources();
1061
- break;
1062
- case 'PATCH':
1063
- request = this.patchResources();
1064
- break;
1065
- case 'HEAD':
1066
- request = this.headResources();
1067
- break;
1068
- default: /* nope */
1069
- }
1070
- // execute the API request
1071
- if (!request)
1072
- this.done(new Error('UNSUPPORTED_METHOD'));
1073
- else {
1074
- request.then((res) => this.done(null, res)).catch((err) => this.done(err));
1075
- }
1076
- })
1077
- .catch(err => this.done(new Error(err && err.message ? err.message : 'FORBIDDEN')));
1078
- };
1079
- this.authorization = (_a = event.headers) === null || _a === void 0 ? void 0 : _a.Authorization;
1080
- this.claims = (_c = (_b = event.requestContext) === null || _b === void 0 ? void 0 : _b.authorizer) === null || _c === void 0 ? void 0 : _c.claims;
1081
- this.principalId = (_d = this.claims) === null || _d === void 0 ? void 0 : _d.sub;
1082
- this.stage = (_e = event.requestContext) === null || _e === void 0 ? void 0 : _e.stage;
1083
- this.httpMethod = event.httpMethod;
1084
- this.resource = (event.resource || '').replace('+', ''); // {proxy+} -> {proxy}
1085
- this.path = event.path || '';
1086
- this.resourceId =
1087
- event.pathParameters && event.pathParameters[options.resourceId || 'proxy']
1088
- ? decodeURIComponent(event.pathParameters[options.resourceId || 'proxy'])
1089
- : '';
1090
- this.queryParams = event.queryStringParameters || {};
1091
- this.body = (event.body ? JSON.parse(event.body) : {}) || {};
1092
- this.logRequestsWithKey = options.logRequestsWithKey;
1093
- // acquire some info about the client, if available
1094
- let version = '?', platform = '?';
1095
- if (this.queryParams['_v']) {
1096
- version = this.queryParams['_v'];
1097
- delete this.queryParams['_v'];
1098
- }
1099
- if (this.queryParams['_p']) {
1100
- platform = this.queryParams['_p'];
1101
- delete this.queryParams['_p'];
1102
- }
1103
- // print the initial log
1104
- const info = { principalId: this.principalId, queryParams: this.queryParams, body: this.body, version, platform };
1105
- idea_toolbox_1.logger(`START: ${this.httpMethod} ${this.stage} ${this.path}`, null, info, true);
1106
- }
1107
- done(err, res) {
1108
- idea_toolbox_1.logger(err ? 'DONE WITH ERRORS' : 'DONE', err, res, true);
1109
- // if configured, store the log of the request
1110
- if (this.logRequestsWithKey)
1111
- this.storeLog(!err);
1112
- // send the response
1113
- this.callback(null, {
1114
- statusCode: err ? '400' : '200',
1115
- body: err ? JSON.stringify({ message: err.message }) : JSON.stringify(res || {}),
1116
- headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' }
1117
- });
1118
- }
1119
- /**
1120
- * To @override
1121
- */
1122
- checkAuthBeforeRequest() {
1123
- return new Promise(resolve => resolve());
1124
- }
1125
- /**
1126
- * To @override
1127
- */
1128
- getResource() {
1129
- return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
1130
- }
1131
- /**
1132
- * To @override
1133
- */
1134
- postResource() {
1135
- return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
1136
- }
1137
- /**
1138
- * To @override
1139
- */
1140
- putResource() {
1141
- return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
1142
- }
1143
- /**
1144
- * To @override
1145
- */
1146
- deleteResource() {
1147
- return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
1148
- }
1149
- /**
1150
- * To @override
1151
- */
1152
- headResource() {
1153
- return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
1154
- }
1155
- /**
1156
- * To @override
1157
- */
1158
- getResources() {
1159
- return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
1160
- }
1161
- /**
1162
- * To @override
1163
- */
1164
- postResources() {
1165
- return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
1166
- }
1167
- /**
1168
- * To @override
1169
- */
1170
- putResources() {
1171
- return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
1172
- }
1173
- /**
1174
- * To @override
1175
- */
1176
- patchResource() {
1177
- return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
1178
- }
1179
- /**
1180
- * To @override
1181
- */
1182
- patchResources() {
1183
- return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
1184
- }
1185
- /**
1186
- * To @override
1187
- */
1188
- deleteResources() {
1189
- return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
1190
- }
1191
- /**
1192
- * To @override
1193
- */
1194
- headResources() {
1195
- return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
1196
- }
1197
- ///
1198
- /// HELPERS
1199
- ///
1200
- /**
1201
- * Store the log associated to the request (no response/error handling).
1202
- */
1203
- storeLog(succeeded) {
1204
- // create the log
1205
- const log = new idea_toolbox_1.APIRequestLog({
1206
- logId: this.logRequestsWithKey,
1207
- userId: this.principalId,
1208
- resource: this.resource,
1209
- path: this.path,
1210
- resourceId: this.resourceId,
1211
- method: this.httpMethod,
1212
- succeeded
1213
- });
1214
- // optionally add a track of the action
1215
- if (this.httpMethod === 'PATCH' && this.body && this.body.action)
1216
- log.action = this.body.action;
1217
- // insert the log and don't wait for response or errors
1218
- this.dynamoDB.put({ TableName: 'idea_logs', Item: log }).catch(() => { });
1219
- }
1220
- /**
1221
- * Check whether shared resource exists in the back-end (translation, template, etc.).
1222
- */
1223
- sharedResourceExists(path) {
1224
- return fs_1.existsSync(`assets/${path}`);
1225
- }
1226
- /**
1227
- * Load a shared resource in the back-end (translation, template, etc.).
1228
- * @param encoding default: `utf-8`
1229
- */
1230
- loadSharedResource(path, encoding) {
1231
- encoding = encoding || 'utf-8';
1232
- return fs_1.readFileSync(`assets/${path}`, { encoding });
1233
- }
1234
- ///
1235
- /// MANAGE INTERNAL API REQUESTS (lambda invokes masked as API requests)
1236
- ///
1237
- /**
1238
- * Simulate an internal API request, invoking directly the lambda and therefore saving resources.
1239
- * @return the body of the response
1240
- */
1241
- invokeInternalAPIRequest(params) {
1242
- return new Promise((resolve, reject) => {
1243
- // create a copy of the event
1244
- const event = JSON.parse(JSON.stringify(this.event));
1245
- // change only the event attributes we need; e.g. the authorization is unchanged
1246
- event.stage = params.stage || this.stage;
1247
- event.httpMethod = params.httpMethod;
1248
- event.resource = params.resource;
1249
- event.pathParameters = params.pathParams || {};
1250
- event.queryStringParameters = params.queryParams || {};
1251
- event.body = JSON.stringify(params.body || {});
1252
- // parse the path
1253
- event.path = event.resource;
1254
- for (const p in event.pathParameters)
1255
- if (event.pathParameters[p])
1256
- event.resource = event.resource.replace(`{${p}}`, event.pathParameters[p]);
1257
- // set a flag to make the invoked to recognise that is an internal request
1258
- event.internalAPIRequest = true;
1259
- // invoke the lambda with the event prepaired, simulating an API request
1260
- new aws_sdk_1.Lambda().invoke({
1261
- FunctionName: params.lambda,
1262
- Qualifier: event.stage,
1263
- InvocationType: 'RequestResponse',
1264
- Payload: JSON.stringify(event)
1265
- }, (err, res) => {
1266
- // reject in case of internal error
1267
- if (err)
1268
- reject(err);
1269
- else {
1270
- // parse the payload and the body
1271
- const payload = JSON.parse(res.Payload);
1272
- const body = JSON.parse(payload.body);
1273
- // if the response is successfull, return the body
1274
- if (Number(payload.statusCode) === 200)
1275
- resolve(body);
1276
- // otherwise, reject the controlled error
1277
- else
1278
- reject(new Error(body.message));
1279
- }
1280
- });
1281
- });
1282
- }
1283
- /**
1284
- * Whether the current request comes from an internal API request, i.e. it was invoked by another controller.
1285
- */
1286
- comesFromInternalRequest() {
1287
- return Boolean(this.event.internalAPIRequest);
1288
- }
1289
- //
1290
- // TRANSLATIONS
1291
- //
1292
- /**
1293
- * Load the translations from the shared resources and set them with a fallback language.
1294
- */
1295
- loadTranslations(lang, defLang) {
1296
- // check for the existance of the mandatory source file
1297
- if (!this.sharedResourceExists(`i18n/${lang}.json`))
1298
- return;
1299
- // set the languages
1300
- this.currentLang = lang;
1301
- this.defaultLang = defLang || lang;
1302
- this.translations = {};
1303
- // load the translations in the chosen language
1304
- this.translations[this.currentLang] = JSON.parse(this.loadSharedResource(`i18n/${this.currentLang}.json`).toString());
1305
- // load the translations in the default language, if set and differ from the current
1306
- if (this.defaultLang !== this.currentLang && this.sharedResourceExists(`i18n/${this.defaultLang}.json`))
1307
- this.translations[this.defaultLang] = JSON.parse(this.loadSharedResource(`i18n/${this.defaultLang}.json`).toString());
1308
- }
1309
- /**
1310
- * Get a translated term by key, optionally interpolating variables (e.g. `{{user}}`).
1311
- * If the term doesn't exist in the current language, it is searched in the default language.
1312
- */
1313
- t(key, interpolateParams) {
1314
- if (!this.translations || !this.currentLang)
1315
- return;
1316
- if (!this.isDefined(key) || !key.length)
1317
- return;
1318
- let res = this.interpolate(this.getValue(this.translations[this.currentLang], key), interpolateParams);
1319
- if (res === undefined && this.defaultLang !== null && this.defaultLang !== this.currentLang)
1320
- res = this.interpolate(this.getValue(this.translations[this.defaultLang], key), interpolateParams);
1321
- return res;
1322
- }
1323
- /**
1324
- * Interpolates a string to replace parameters.
1325
- * "This is a {{ key }}" ==> "This is a value", with params = { key: "value" }
1326
- */
1327
- interpolate(expr, params) {
1328
- if (!params || !expr)
1329
- return expr;
1330
- return expr.replace(this.templateMatcher, (substring, b) => {
1331
- const r = this.getValue(params, b);
1332
- return this.isDefined(r) ? r : substring;
1333
- });
1334
- }
1335
- /**
1336
- * Gets a value from an object by composed key.
1337
- * getValue({ key1: { keyA: 'valueI' }}, 'key1.keyA') ==> 'valueI'
1338
- */
1339
- getValue(target, key) {
1340
- const keys = typeof key === 'string' ? key.split('.') : [key];
1341
- key = '';
1342
- do {
1343
- key += keys.shift();
1344
- if (this.isDefined(target) && this.isDefined(target[key]) && (typeof target[key] === 'object' || !keys.length)) {
1345
- target = target[key];
1346
- key = '';
1347
- }
1348
- else if (!keys.length)
1349
- target = undefined;
1350
- else
1351
- key += '.';
1352
- } while (keys.length);
1353
- return target;
1354
- }
1355
- /**
1356
- * Helper to quicly check if the value is defined.
1357
- */
1358
- isDefined(value) {
1359
- return value !== undefined && value !== null;
1360
- }
1361
- }
1362
- exports.ResourceController = ResourceController;
1363
-
1364
-
1365
- /***/ }),
1366
-
1367
- /***/ 216:
1368
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
1369
-
1370
-
1371
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1372
- exports.GetObjectTypes = exports.S3 = void 0;
1373
- const aws_sdk_1 = __webpack_require__(480);
1374
- const idea_toolbox_1 = __webpack_require__(81);
1375
- /**
1376
- * A wrapper for AWS Simple Storage Service.
1377
- */
1378
- class S3 {
1379
- /**
1380
- * Initialize a new S3 helper object.
1381
- */
1382
- constructor() {
1383
- this.DEFAULT_DOWNLOAD_BUCKET_PREFIX = 'common';
1384
- this.DEFAULT_DOWNLOAD_BUCKET = 'idea-downloads';
1385
- this.DEFAULT_DOWNLOAD_BUCKET_SEC_TO_EXP = 180;
1386
- this.DEFAULT_UPLOAD_BUCKET_SEC_TO_EXP = 300;
1387
- this.s3 = new aws_sdk_1.S3({ apiVersion: '2006-03-01', signatureVersion: 'v4' });
1388
- }
1389
- /**
1390
- * Create a download link of a piece of data (through S3).
1391
- * *Pratically*, it uploads the file on an S3 bucket, generating and returning a url to it.
1392
- */
1393
- createDownloadURLFromData(data, options) {
1394
- return new Promise((resolve, reject) => {
1395
- // if needed, randomly generates the key
1396
- if (!options.key)
1397
- options.key = new Date().getTime().toString().concat(Math.random().toString(36).slice(2));
1398
- // add the prefix to the key
1399
- options.key = `${options.prefix || this.DEFAULT_DOWNLOAD_BUCKET_PREFIX}/${options.key}`;
1400
- // set the other parameters
1401
- options.bucket = options.bucket || this.DEFAULT_DOWNLOAD_BUCKET;
1402
- options.secToExp = options.secToExp || this.DEFAULT_DOWNLOAD_BUCKET_SEC_TO_EXP;
1403
- // upload the file to the downloads bucket
1404
- this.s3.upload({
1405
- Bucket: options.bucket,
1406
- Key: options.key,
1407
- Body: data,
1408
- ContentType: options.contentType
1409
- }, (err) => {
1410
- idea_toolbox_1.logger('S3 UPLOAD', err);
1411
- if (err)
1412
- reject(err);
1413
- else
1414
- resolve(this.signedURLGet(options.bucket, options.key, options.secToExp));
1415
- });
1416
- });
1417
- }
1418
- /**
1419
- * Get a signed URL to put a file on a S3 bucket.
1420
- * @param expires seconds after which the signed URL expires
1421
- */
1422
- signedURLPut(bucket, key, expires) {
1423
- return new idea_toolbox_1.SignedURL({
1424
- url: this.s3.getSignedUrl('putObject', {
1425
- Bucket: bucket,
1426
- Key: key,
1427
- Expires: expires || this.DEFAULT_UPLOAD_BUCKET_SEC_TO_EXP
1428
- })
1429
- });
1430
- }
1431
- /**
1432
- * Get a signed URL to get a file on a S3 bucket.
1433
- * @param expires seconds after which the signed URL expires
1434
- */
1435
- signedURLGet(bucket, key, expires) {
1436
- return new idea_toolbox_1.SignedURL({
1437
- url: this.s3.getSignedUrl('getObject', {
1438
- Bucket: bucket,
1439
- Key: key,
1440
- Expires: expires || this.DEFAULT_DOWNLOAD_BUCKET_SEC_TO_EXP
1441
- })
1442
- });
1443
- }
1444
- /**
1445
- * Make a copy of an object of the bucket.
1446
- */
1447
- copyObject(options) {
1448
- return new Promise((resolve, reject) => {
1449
- this.s3.copyObject({ CopySource: options.copySource, Bucket: options.bucket, Key: options.key }, (err) => {
1450
- idea_toolbox_1.logger('S3 COPY OBJECT', err, options.key);
1451
- if (err)
1452
- reject(err);
1453
- else
1454
- resolve();
1455
- });
1456
- });
1457
- }
1458
- /**
1459
- * Get an object from a S3 bucket.
1460
- */
1461
- getObject(options) {
1462
- return new Promise((resolve, reject) => {
1463
- this.s3.getObject({ Bucket: options.bucket, Key: options.key }, (err, d) => {
1464
- idea_toolbox_1.logger('S3 GET OBJECT', err, options.type);
1465
- if (err)
1466
- reject(err);
1467
- else
1468
- switch (options.type) {
1469
- case GetObjectTypes.JSON:
1470
- resolve(JSON.parse(d.Body.toString('utf-8')));
1471
- break;
1472
- case GetObjectTypes.TEXT:
1473
- resolve(d.Body.toString('utf-8'));
1474
- break;
1475
- default:
1476
- resolve(d);
1477
- }
1478
- });
1479
- });
1480
- }
1481
- /**
1482
- * Put an object in a S3 bucket.
1483
- */
1484
- putObject(options) {
1485
- return new Promise((resolve, reject) => {
1486
- const params = { Bucket: options.bucket, Key: options.key, Body: options.body };
1487
- if (options.contentType)
1488
- params.ContentType = options.contentType;
1489
- if (options.acl)
1490
- params.ACL = options.acl;
1491
- if (options.metadata)
1492
- params.Metadata = options.metadata;
1493
- this.s3.putObject(params, (err, d) => {
1494
- idea_toolbox_1.logger('S3 PUT OBJECT', err, options.key);
1495
- if (err)
1496
- reject(err);
1497
- else
1498
- resolve(d);
1499
- });
1500
- });
1501
- }
1502
- /**
1503
- * Delete an object from an S3 bucket.
1504
- */
1505
- deleteObject(options) {
1506
- return new Promise((resolve, reject) => {
1507
- this.s3.deleteObject({ Bucket: options.bucket, Key: options.key }, (err, o) => {
1508
- idea_toolbox_1.logger('S3 DELETE OBJECT', err, options.key);
1509
- if (err)
1510
- reject(err);
1511
- else
1512
- resolve(o);
1513
- });
1514
- });
1515
- }
1516
- /**
1517
- * List the objects of an S3 bucket.
1518
- */
1519
- listObjects(options) {
1520
- return new Promise((resolve, reject) => {
1521
- this.s3.listObjects({ Bucket: options.bucket, Prefix: options.prefix }, (err, o) => {
1522
- idea_toolbox_1.logger('S3 LIST OBJECTS', err, options.prefix);
1523
- if (err)
1524
- reject(err);
1525
- else
1526
- resolve(o);
1527
- });
1528
- });
1529
- }
1530
- /**
1531
- * List the objects keys of an S3 bucket.
1532
- */
1533
- listObjectsKeys(options) {
1534
- return new Promise((resolve, reject) => {
1535
- this.listObjects(options)
1536
- .then(list => resolve(list.Contents.map(obj => obj.Key)))
1537
- .catch(err => reject(err));
1538
- });
1539
- }
1540
- /**
1541
- * Check whether an object on an S3 bucket exists.
1542
- */
1543
- doesObjectExist(options) {
1544
- return new Promise(resolve => {
1545
- this.s3.headObject({ Bucket: options.bucket, Key: options.key }, (err) => {
1546
- idea_toolbox_1.logger('S3 HEAD OBJECT', err, options.key);
1547
- if (err)
1548
- resolve(false);
1549
- else
1550
- resolve(true);
1551
- });
1552
- });
1553
- }
1554
- }
1555
- exports.S3 = S3;
1556
- /**
1557
- * The managed types to convert objects coming from an S3 bucket.
1558
- */
1559
- var GetObjectTypes;
1560
- (function (GetObjectTypes) {
1561
- GetObjectTypes["JSON"] = "JSON";
1562
- GetObjectTypes["TEXT"] = "TEXT";
1563
- })(GetObjectTypes = exports.GetObjectTypes || (exports.GetObjectTypes = {}));
1564
-
1565
-
1566
- /***/ }),
1567
-
1568
- /***/ 887:
1569
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
1570
-
1571
-
1572
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1573
- exports.SES = void 0;
1574
- const aws_sdk_1 = __webpack_require__(480);
1575
- const nodemailer_1 = __webpack_require__(123);
1576
- const idea_toolbox_1 = __webpack_require__(81);
1577
- const dynamoDB_1 = __webpack_require__(823);
1578
- /**
1579
- * A wrapper for AWS Simple Email Service.
1580
- */
1581
- class SES {
1582
- /**
1583
- * Send an email through AWS Simple Email Service.
1584
- */
1585
- sendEmail(emailData, sesParams) {
1586
- return new Promise((resolve, reject) => {
1587
- // if requested, check whether there is a custom SES configuration to apply for the team
1588
- this.searchForCustomSESConfigByTeamId(sesParams.teamId).then(customSESConfig => {
1589
- var _a;
1590
- let promise;
1591
- // if the email includes attachments, send with Nodemailer (to avoid size limitations)
1592
- if ((_a = emailData.attachments) === null || _a === void 0 ? void 0 : _a.length)
1593
- promise = this.sendEmailWithNodemailer(emailData, customSESConfig || sesParams);
1594
- // otherwise, send with SES (more secure)
1595
- else
1596
- promise = this.sendEmailWithSES(emailData, customSESConfig || sesParams);
1597
- promise.then(res => resolve(res)).catch(err => reject(err));
1598
- });
1599
- });
1600
- }
1601
- searchForCustomSESConfigByTeamId(teamId) {
1602
- return new Promise(resolve => {
1603
- if (!teamId)
1604
- return resolve(null);
1605
- new dynamoDB_1.DynamoDB()
1606
- .get({ TableName: 'idea_teamsSES', Key: { teamId } })
1607
- .then((customConfig) => resolve(customConfig))
1608
- .catch(() => resolve(null));
1609
- });
1610
- }
1611
- sendEmailWithSES(emailData, sesParams) {
1612
- return new Promise((resolve, reject) => {
1613
- // prepare SES email data
1614
- const sesData = {};
1615
- sesData.Destination = {};
1616
- if (emailData.toAddresses)
1617
- sesData.Destination.ToAddresses = emailData.toAddresses;
1618
- if (emailData.ccAddresses)
1619
- sesData.Destination.CcAddresses = emailData.ccAddresses;
1620
- if (emailData.bccAddresses)
1621
- sesData.Destination.BccAddresses = emailData.bccAddresses;
1622
- if (emailData.replyToAddresses)
1623
- sesData.ReplyToAddresses = emailData.replyToAddresses;
1624
- sesData.Message = {};
1625
- if (emailData.subject)
1626
- sesData.Message.Subject = { Charset: 'UTF-8', Data: emailData.subject };
1627
- sesData.Message.Body = {};
1628
- if (emailData.html)
1629
- sesData.Message.Body.Html = { Charset: 'UTF-8', Data: emailData.html };
1630
- if (emailData.text)
1631
- sesData.Message.Body.Text = { Charset: 'UTF-8', Data: emailData.text };
1632
- if (!emailData.html && !emailData.text)
1633
- sesData.Message.Body.Text = { Charset: 'UTF-8', Data: '' };
1634
- sesData.Source = `${sesParams.sourceName} <${sesParams.source}>`;
1635
- sesData.SourceArn = sesParams.sourceArn;
1636
- // send email
1637
- new aws_sdk_1.SES({ region: sesParams.region }).sendEmail(sesData, (err) => {
1638
- idea_toolbox_1.logger('SES SEND EMAIL', err);
1639
- if (err)
1640
- reject(err);
1641
- else
1642
- resolve();
1643
- });
1644
- });
1645
- }
1646
- sendEmailWithNodemailer(emailData, sesParams) {
1647
- return new Promise((resolve, reject) => {
1648
- // set the mail options in Nodemailer's format
1649
- const mailOptions = {};
1650
- mailOptions.from = `${sesParams.sourceName} <${sesParams.source}>`;
1651
- mailOptions.to = emailData.toAddresses.join(',');
1652
- if (emailData.ccAddresses)
1653
- mailOptions.cc = emailData.ccAddresses.join(',');
1654
- if (emailData.bccAddresses)
1655
- mailOptions.bcc = emailData.bccAddresses.join(',');
1656
- if (emailData.replyToAddresses)
1657
- mailOptions.replyTo = emailData.replyToAddresses.join(',');
1658
- mailOptions.subject = emailData.subject;
1659
- if (emailData.html)
1660
- mailOptions.html = emailData.html;
1661
- if (emailData.text)
1662
- mailOptions.text = emailData.text;
1663
- mailOptions.attachments = emailData.attachments;
1664
- // create Nodemailer SES transporter and send the email
1665
- nodemailer_1.createTransport({ SES: new aws_sdk_1.SES({ region: sesParams.region }) }).sendMail(mailOptions, (err) => {
1666
- idea_toolbox_1.logger('SES SEND EMAIL (NODEMAILER)', err);
1667
- if (err)
1668
- reject(err);
1669
- else
1670
- resolve();
1671
- });
1672
- });
1673
- }
1674
- }
1675
- exports.SES = SES;
1676
-
1677
-
1678
- /***/ }),
1679
-
1680
- /***/ 187:
1681
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
1682
-
1683
-
1684
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1685
- exports.SNS = void 0;
1686
- const aws_sdk_1 = __webpack_require__(480);
1687
- const idea_toolbox_1 = __webpack_require__(81);
1688
- /**
1689
- * A wrapper for AWS Simple Notification Service.
1690
- */
1691
- class SNS {
1692
- /**
1693
- * Create a new endpoint in the SNS platform specified.
1694
- * @return platform endpoint ARN
1695
- */
1696
- createPushPlatormEndpoint(platform, token, snsParams) {
1697
- return new Promise((resolve, reject) => {
1698
- let platformARN;
1699
- // identify the platform ARN
1700
- switch (platform) {
1701
- case idea_toolbox_1.PushNotificationsPlatforms.APNS:
1702
- platformARN = snsParams.appleArn;
1703
- break;
1704
- case idea_toolbox_1.PushNotificationsPlatforms.APNS_SANDBOX:
1705
- platformARN = snsParams.appleDevArn;
1706
- break;
1707
- case idea_toolbox_1.PushNotificationsPlatforms.FCM:
1708
- platformARN = snsParams.androidArn;
1709
- break;
1710
- default:
1711
- return reject(new Error('UNSUPPORTED_PLATFORM'));
1712
- }
1713
- // create a new endpoint in the platform
1714
- new aws_sdk_1.SNS({ apiVersion: '2010-03-31', region: snsParams.region }).createPlatformEndpoint({ PlatformApplicationArn: platformARN, Token: token }, (err, data) => {
1715
- idea_toolbox_1.logger('SNS ADD PLATFORM ENDPOINT', err);
1716
- if (err || !data.EndpointArn)
1717
- reject(err);
1718
- else
1719
- resolve(data.EndpointArn);
1720
- });
1721
- });
1722
- }
1723
- /**
1724
- * Publish a message to a SNS endpoint.
1725
- */
1726
- publish(params) {
1727
- return new Promise((resolve, reject) => {
1728
- let structuredMessage;
1729
- if (params.json)
1730
- structuredMessage = { default: JSON.stringify(params.json) };
1731
- else
1732
- switch (params.platform) {
1733
- case idea_toolbox_1.PushNotificationsPlatforms.APNS:
1734
- structuredMessage = { APNS: JSON.stringify({ aps: { alert: params.message } }) };
1735
- break;
1736
- case idea_toolbox_1.PushNotificationsPlatforms.APNS_SANDBOX:
1737
- structuredMessage = { APNS_SANDBOX: JSON.stringify({ aps: { alert: params.message } }) };
1738
- break;
1739
- case idea_toolbox_1.PushNotificationsPlatforms.FCM:
1740
- structuredMessage = {
1741
- GCM: JSON.stringify({ notification: { body: params.message, title: params.message } })
1742
- };
1743
- break;
1744
- default:
1745
- return reject(new Error('UNSUPPORTED_PLATFORM'));
1746
- }
1747
- new aws_sdk_1.SNS({ apiVersion: '2010-03-31', region: params.region }).publish({
1748
- MessageStructure: 'json',
1749
- Message: JSON.stringify(structuredMessage),
1750
- TargetArn: params.endpoint
1751
- }, (err, data) => {
1752
- idea_toolbox_1.logger('SNS PUBLISH IN TOPIC', err);
1753
- if (err)
1754
- reject(err);
1755
- else
1756
- resolve(data);
1757
- });
1758
- });
1759
- }
1760
- }
1761
- exports.SNS = SNS;
1762
-
1763
-
1764
- /***/ }),
1765
-
1766
- /***/ 296:
1767
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
1768
-
1769
-
1770
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1771
- exports.StreamController = void 0;
1772
- const idea_toolbox_1 = __webpack_require__(81);
1773
- const genericController_1 = __webpack_require__(838);
1774
- /**
1775
- * An abstract class to inherit to manage AWS DDB streams in an AWS Lambda function.
1776
- */
1777
- class StreamController extends genericController_1.GenericController {
1778
- constructor(event, callback, options) {
1779
- super(event, callback, options);
1780
- this.records = event.Records || [];
1781
- idea_toolbox_1.logger(`START STREAM: ${this.records.length || 0} records`, null, null, true);
1782
- }
1783
- }
1784
- exports.StreamController = StreamController;
1785
-
1786
-
1787
- /***/ }),
1788
-
1789
- /***/ 580:
1790
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1791
-
1792
-
1793
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
1794
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
1795
- return new (P || (P = Promise))(function (resolve, reject) {
1796
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
1797
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
1798
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
1799
- step((generator = generator.apply(thisArg, _arguments || [])).next());
1800
- });
1801
- };
1802
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1803
- exports.Translate = void 0;
1804
- const aws_sdk_1 = __webpack_require__(480);
1805
- const idea_toolbox_1 = __webpack_require__(81);
1806
- /**
1807
- * A wrapper for Amazon Translate.
1808
- */
1809
- class Translate {
1810
- /**
1811
- * Initialize a new Translate helper object.
1812
- */
1813
- constructor() {
1814
- this.translate = new aws_sdk_1.Translate({ apiVersion: '2017-07-01' });
1815
- this.sourceLanguageCode = 'en';
1816
- this.targetLanguageCode = 'en';
1817
- this.terminologyNames = new Array();
1818
- }
1819
- /**
1820
- * Translates input text from the source language to the target language.
1821
- * @param params the parameters for translateText
1822
- */
1823
- text(params) {
1824
- return new Promise((resolve, reject) => {
1825
- // load source and target languages codes
1826
- if (params.sourceLanguageCode)
1827
- this.sourceLanguageCode = params.sourceLanguageCode;
1828
- if (params.targetLanguageCode)
1829
- this.targetLanguageCode = params.targetLanguageCode;
1830
- if (params.terminologyNames)
1831
- this.terminologyNames = params.terminologyNames;
1832
- // check for obligatory params
1833
- if (!this.sourceLanguageCode || !this.targetLanguageCode || !params.text)
1834
- return reject();
1835
- // execute the translation
1836
- this.translate.translateText({
1837
- Text: params.text,
1838
- SourceLanguageCode: this.sourceLanguageCode,
1839
- TargetLanguageCode: this.targetLanguageCode,
1840
- TerminologyNames: this.terminologyNames
1841
- }, (err, data) => {
1842
- if (err)
1843
- reject(err);
1844
- else
1845
- resolve(data.TranslatedText);
1846
- });
1847
- });
1848
- }
1849
- /**
1850
- * Get the contents of a PDF template (against a PDFEntity) translated in the desired language,
1851
- * if the latter isn't between the ones already available.
1852
- * @return an object that maps original texts with their translations (or nothing).
1853
- */
1854
- pdfTemplate(entity, template, language, languages) {
1855
- return new Promise(resolve => {
1856
- // if the language is included in the ones supported by the team, skip
1857
- if (languages.available.some(l => l === language))
1858
- return resolve(null);
1859
- // analyse the template to extract terms to translate based on the entity (using a sourceLanguage as reference)
1860
- this.analysePDFTemplateForTermsToTranslate(template, entity, languages.default).then(termsToTranslate => {
1861
- const translations = {};
1862
- Array.from(termsToTranslate).forEach((original) => __awaiter(this, void 0, void 0, function* () {
1863
- const translated = yield this.text({
1864
- sourceLanguageCode: languages.default,
1865
- targetLanguageCode: language,
1866
- text: original
1867
- });
1868
- translations[original] = translated
1869
- // fix markdown issue (the translations add a space before and after asterisks)
1870
- .replace(/\*\* /gm, '**')
1871
- .replace(/ \*\*/gm, '**');
1872
- }));
1873
- resolve(translations);
1874
- });
1875
- });
1876
- }
1877
- /**
1878
- * Analyse a PDFTemplate to extract terms to translate based on a PDFEntity (using a sourceLanguage as reference).
1879
- */
1880
- analysePDFTemplateForTermsToTranslate(template, entity, sourceLanguage) {
1881
- return new Promise(resolve => {
1882
- const toTranslate = new Set();
1883
- // gather the terms to translate from contents available on this level
1884
- template
1885
- .filter(s => s.isEither(idea_toolbox_1.PDFTemplateSectionTypes.ROW, idea_toolbox_1.PDFTemplateSectionTypes.HEADER))
1886
- .forEach(s => {
1887
- switch (s.type) {
1888
- case idea_toolbox_1.PDFTemplateSectionTypes.ROW:
1889
- s.columns
1890
- .filter((_, index) => s.doesColumnContainAField(index))
1891
- .forEach(field => {
1892
- field = field;
1893
- if (field.isComplex()) {
1894
- const complex = field;
1895
- toTranslate.add(complex.content[sourceLanguage]);
1896
- }
1897
- else {
1898
- const simple = field;
1899
- toTranslate.add(simple.label[sourceLanguage]);
1900
- // try to consider only notes (long fields)
1901
- if (typeof entity[simple.code] === 'string' && entity[simple.code].length > 50)
1902
- toTranslate.add(entity[simple.code]);
1903
- }
1904
- });
1905
- break;
1906
- case idea_toolbox_1.PDFTemplateSectionTypes.HEADER:
1907
- toTranslate.add(s.title[sourceLanguage]);
1908
- break;
1909
- }
1910
- });
1911
- // gather inner sections in a flat structure for further elaboraton
1912
- const innerSections = new Array();
1913
- template
1914
- .filter(s => s.isEither(idea_toolbox_1.PDFTemplateSectionTypes.INNER_SECTION, idea_toolbox_1.PDFTemplateSectionTypes.REPEATED_INNER_SECTION))
1915
- .forEach(s => {
1916
- switch (s.type) {
1917
- case idea_toolbox_1.PDFTemplateSectionTypes.INNER_SECTION:
1918
- innerSections.push({ data: entity[s.context], template: s.innerTemplate });
1919
- break;
1920
- case idea_toolbox_1.PDFTemplateSectionTypes.REPEATED_INNER_SECTION:
1921
- entity[s.context].forEach((element) => innerSections.push({ data: element, template: s.innerTemplate }));
1922
- break;
1923
- }
1924
- });
1925
- // run (inception) the inner sections to gather terms to translate from inner levels
1926
- innerSections.forEach((s) => __awaiter(this, void 0, void 0, function* () {
1927
- const res = yield this.analysePDFTemplateForTermsToTranslate(s.template, s.data, sourceLanguage);
1928
- res.forEach(x => toTranslate.add(x));
1929
- }));
1930
- resolve(toTranslate);
1931
- });
1932
- }
1933
- }
1934
- exports.Translate = Translate;
1935
-
1936
-
1937
- /***/ }),
1938
-
1939
- /***/ 480:
1940
- /***/ ((module) => {
1941
-
1942
- module.exports = require("aws-sdk");;
1943
-
1944
- /***/ }),
1945
-
1946
- /***/ 747:
1947
- /***/ ((module) => {
1948
-
1949
- module.exports = require("fs");;
1950
-
1951
- /***/ }),
1952
-
1953
- /***/ 81:
1954
- /***/ ((module) => {
1955
-
1956
- module.exports = require("idea-toolbox");;
1957
-
1958
- /***/ }),
1959
-
1960
- /***/ 324:
1961
- /***/ ((module) => {
1962
-
1963
- module.exports = require("nanoid");;
1964
-
1965
- /***/ }),
1966
-
1967
- /***/ 123:
1968
- /***/ ((module) => {
1969
-
1970
- module.exports = require("nodemailer");;
1971
-
1972
- /***/ }),
1973
-
1974
- /***/ 942:
1975
- /***/ ((module) => {
1976
-
1977
- module.exports = require("shortid");;
1978
-
1979
- /***/ }),
1980
-
1981
- /***/ 669:
1982
- /***/ ((module) => {
1983
-
1984
- module.exports = require("util");;
1985
-
1986
- /***/ }),
1987
-
1988
- /***/ 180:
1989
- /***/ ((module) => {
1990
-
1991
- module.exports = require("uuid/v4");;
1992
-
1993
- /***/ })
1994
-
1995
- /******/ });
1996
- /************************************************************************/
1997
- /******/ // The module cache
1998
- /******/ var __webpack_module_cache__ = {};
1999
- /******/
2000
- /******/ // The require function
2001
- /******/ function __webpack_require__(moduleId) {
2002
- /******/ // Check if module is in cache
2003
- /******/ if(__webpack_module_cache__[moduleId]) {
2004
- /******/ return __webpack_module_cache__[moduleId].exports;
2005
- /******/ }
2006
- /******/ // Create a new module (and put it into the cache)
2007
- /******/ var module = __webpack_module_cache__[moduleId] = {
2008
- /******/ // no module.id needed
2009
- /******/ // no module.loaded needed
2010
- /******/ exports: {}
2011
- /******/ };
2012
- /******/
2013
- /******/ // Execute the module function
2014
- /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
2015
- /******/
2016
- /******/ // Return the exports of the module
2017
- /******/ return module.exports;
2018
- /******/ }
2019
- /******/
2020
- /************************************************************************/
2021
- /******/ // module exports must be returned from runtime so entry inlining is disabled
2022
- /******/ // startup
2023
- /******/ // Load entry module and return exports
2024
- /******/ return __webpack_require__(341);
2025
- /******/ })()
2026
- ;
2027
- });
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ __exportStar(require("./src/genericController"), exports);
14
+ __exportStar(require("./src/resourceController"), exports);
15
+ __exportStar(require("./src/streamController"), exports);
16
+ __exportStar(require("./src/dynamoDB"), exports);
17
+ __exportStar(require("./src/cognito"), exports);
18
+ __exportStar(require("./src/comprehend"), exports);
19
+ __exportStar(require("./src/s3"), exports);
20
+ __exportStar(require("./src/ses"), exports);
21
+ __exportStar(require("./src/sns"), exports);
22
+ __exportStar(require("./src/translate"), exports);
23
+ __exportStar(require("./src/attachments"), exports);