idea-aws 4.3.5 → 4.4.1
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/package.json +2 -1
- package/dist/src/attachments.d.ts +0 -27
- package/dist/src/attachments.js +0 -39
- package/dist/src/cognito.d.ts +0 -177
- package/dist/src/cognito.js +0 -412
- package/dist/src/comprehend.d.ts +0 -34
- package/dist/src/comprehend.js +0 -58
- package/dist/src/dynamoDB.d.ts +0 -108
- package/dist/src/dynamoDB.js +0 -296
- package/dist/src/genericController.d.ts +0 -60
- package/dist/src/genericController.js +0 -89
- package/dist/src/lambdaLogger.d.ts +0 -13
- package/dist/src/lambdaLogger.js +0 -43
- package/dist/src/logger.d.ts +0 -10
- package/dist/src/logger.js +0 -16
- package/dist/src/metrics.d.ts +0 -31
- package/dist/src/metrics.js +0 -45
- package/dist/src/resourceController.d.ts +0 -226
- package/dist/src/resourceController.js +0 -535
- package/dist/src/s3.d.ts +0 -225
- package/dist/src/s3.js +0 -180
- package/dist/src/secretsManager.d.ts +0 -15
- package/dist/src/secretsManager.js +0 -48
- package/dist/src/ses.d.ts +0 -161
- package/dist/src/ses.js +0 -196
- package/dist/src/sns.d.ts +0 -60
- package/dist/src/sns.js +0 -94
- package/dist/src/ssm.d.ts +0 -22
- package/dist/src/ssm.js +0 -54
- package/dist/src/streamController.d.ts +0 -11
- package/dist/src/streamController.js +0 -20
- package/dist/src/translate.d.ts +0 -61
- package/dist/src/translate.js +0 -155
package/dist/src/comprehend.d.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import * as AmazonComprehend from '@aws-sdk/client-comprehend';
|
|
2
|
-
import { Sentiment } from 'idea-toolbox';
|
|
3
|
-
/**
|
|
4
|
-
* A wrapper for Amazon Comprehend.
|
|
5
|
-
*/
|
|
6
|
-
export declare class Comprehend {
|
|
7
|
-
protected comprehend: AmazonComprehend.ComprehendClient;
|
|
8
|
-
constructor(options?: {
|
|
9
|
-
region?: string;
|
|
10
|
-
});
|
|
11
|
-
/**
|
|
12
|
-
* Inspects text and returns an inference of the prevailing sentiment (POSITIVE, NEUTRAL, MIXED, or NEGATIVE).
|
|
13
|
-
*/
|
|
14
|
-
detectSentiment(params: DetectSentimentParameters): Promise<Sentiment>;
|
|
15
|
-
/**
|
|
16
|
-
* Determines the dominant language of the input text.
|
|
17
|
-
*/
|
|
18
|
-
detectDominantLanguage(params: {
|
|
19
|
-
text: string;
|
|
20
|
-
}): Promise<string>;
|
|
21
|
-
}
|
|
22
|
-
export interface DetectSentimentParameters {
|
|
23
|
-
/**
|
|
24
|
-
* The language of the input contents. You can specify any of the primary languages supported by Amazon Comprehend.
|
|
25
|
-
* All contents must be in the same language. Required.
|
|
26
|
-
* Valid Values: en | es | fr | de | it | pt | ar | hi | ja | ko | zh | zh-TW
|
|
27
|
-
*/
|
|
28
|
-
language: string;
|
|
29
|
-
/**
|
|
30
|
-
* The text to analyze. Required.
|
|
31
|
-
* A UTF-8 text string. Each string must contain fewer that 5,000 bytes of UTF-8 encoded characters.
|
|
32
|
-
*/
|
|
33
|
-
text: string;
|
|
34
|
-
}
|
package/dist/src/comprehend.js
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.Comprehend = void 0;
|
|
27
|
-
const AmazonComprehend = __importStar(require("@aws-sdk/client-comprehend"));
|
|
28
|
-
/**
|
|
29
|
-
* A wrapper for Amazon Comprehend.
|
|
30
|
-
*/
|
|
31
|
-
class Comprehend {
|
|
32
|
-
constructor(options = {}) {
|
|
33
|
-
this.comprehend = new AmazonComprehend.ComprehendClient({ region: options.region });
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Inspects text and returns an inference of the prevailing sentiment (POSITIVE, NEUTRAL, MIXED, or NEGATIVE).
|
|
37
|
-
*/
|
|
38
|
-
async detectSentiment(params) {
|
|
39
|
-
if (!params.language || !params.text)
|
|
40
|
-
throw new Error('Missing some parameters');
|
|
41
|
-
const command = new AmazonComprehend.DetectSentimentCommand({ LanguageCode: params.language, Text: params.text });
|
|
42
|
-
const { Sentiment } = await this.comprehend.send(command);
|
|
43
|
-
return Sentiment;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Determines the dominant language of the input text.
|
|
47
|
-
*/
|
|
48
|
-
async detectDominantLanguage(params) {
|
|
49
|
-
if (!params.text)
|
|
50
|
-
throw new Error('Missing text');
|
|
51
|
-
const command = new AmazonComprehend.DetectDominantLanguageCommand({ Text: params.text });
|
|
52
|
-
const { Languages } = await this.comprehend.send(command);
|
|
53
|
-
if (!Languages.length)
|
|
54
|
-
throw new Error('Not found');
|
|
55
|
-
return Languages[0].LanguageCode;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
exports.Comprehend = Comprehend;
|
package/dist/src/dynamoDB.d.ts
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import * as DDB from '@aws-sdk/lib-dynamodb';
|
|
2
|
-
import * as DDBUtils from '@aws-sdk/util-dynamodb';
|
|
3
|
-
import { LambdaLogger } from './lambdaLogger';
|
|
4
|
-
/**
|
|
5
|
-
* A wrapper for AWS DynamoDB.
|
|
6
|
-
*/
|
|
7
|
-
export declare class DynamoDB {
|
|
8
|
-
protected dynamo: DDB.DynamoDBDocument;
|
|
9
|
-
protected logger: LambdaLogger;
|
|
10
|
-
constructor();
|
|
11
|
-
/**
|
|
12
|
-
* Convert a JSON object from DynamoDB format to simple JSON.
|
|
13
|
-
* @data the data in DynamoDB's original format to convert in plain objects
|
|
14
|
-
* @options the options to use to convert the data
|
|
15
|
-
*/
|
|
16
|
-
unmarshall(data: Record<string, any>, options?: DDBUtils.unmarshallOptions): Record<string, any>;
|
|
17
|
-
/**
|
|
18
|
-
* Returns an IUNID: IDEA's Unique Nano IDentifier, which is an id unique through an IDEA's AWS account and region.
|
|
19
|
-
* Note: no need of an auth check for external uses: the permissions depend from the context in which it's executed.
|
|
20
|
-
* @param project project code
|
|
21
|
-
* @return the IUNID
|
|
22
|
-
*/
|
|
23
|
-
IUNID(project: string): Promise<string>;
|
|
24
|
-
protected IUNIDHelper(project: string, attempt: number, maxAttempts: number): Promise<string>;
|
|
25
|
-
/**
|
|
26
|
-
* Manage atomic counters (atomic autoincrement values) in IDEA's projects.
|
|
27
|
-
* They key of an atomic counter should be composed as the following: `DynamoDBTableName_uniqueKey`.
|
|
28
|
-
* @param key the key of the counter
|
|
29
|
-
*/
|
|
30
|
-
getAtomicCounterByKey(key: string): Promise<number>;
|
|
31
|
-
/**
|
|
32
|
-
* Get an item of a DynamoDB table.
|
|
33
|
-
* @param params the params to apply to DynamoDB's function
|
|
34
|
-
*/
|
|
35
|
-
get(params: DDB.GetCommandInput): Promise<any>;
|
|
36
|
-
/**
|
|
37
|
-
* Put an item in a DynamoDB table.
|
|
38
|
-
* @param params the params to apply to DynamoDB's function
|
|
39
|
-
*/
|
|
40
|
-
put(params: DDB.PutCommandInput): Promise<DDB.PutCommandOutput>;
|
|
41
|
-
/**
|
|
42
|
-
* Update an item of a DynamoDB table.
|
|
43
|
-
* @param params the params to apply to DynamoDB's function
|
|
44
|
-
*/
|
|
45
|
-
update(params: DDB.UpdateCommandInput): Promise<DDB.UpdateCommandOutput>;
|
|
46
|
-
/**
|
|
47
|
-
* Delete an item of a DynamoDB table.
|
|
48
|
-
* @param params the params to apply to DynamoDB's function
|
|
49
|
-
*/
|
|
50
|
-
delete(params: DDB.DeleteCommandInput): Promise<DDB.DeleteCommandOutput>;
|
|
51
|
-
/**
|
|
52
|
-
* Get group of items based on their keys from DynamoDB table, avoiding the limits of DynamoDB's BatchGetItem.
|
|
53
|
-
* @param table the target DynamoDB table
|
|
54
|
-
* @param keys the keys of the objects to retrieve
|
|
55
|
-
* @param ignoreErr if set, ignore the errors and continue the bulk op.
|
|
56
|
-
*/
|
|
57
|
-
batchGet(table: string, keys: Record<string, any>[], ignoreErr?: boolean): Promise<any[]>;
|
|
58
|
-
protected batchGetHelper(table: string, keys: Record<string, any>[], resultElements: Record<string, any>[], ignoreErr: boolean, currentChunk?: number, chunkSize?: number): Promise<Record<string, any>[]>;
|
|
59
|
-
/**
|
|
60
|
-
* Put an array of items in a DynamoDB table, avoiding the limits of DynamoDB's BatchWriteItem.
|
|
61
|
-
* In case of errors, it will retry with a random back-off mechanism until the timeout.
|
|
62
|
-
* Therefore, in case of timeout, there may be some elements written and some not.
|
|
63
|
-
* @param table the target DynamoDB table
|
|
64
|
-
* @param items the objects to insert
|
|
65
|
-
*/
|
|
66
|
-
batchPut(table: string, items: Record<string, any>[]): Promise<void>;
|
|
67
|
-
/**
|
|
68
|
-
* Delete an array of items from a DynamoDB table, avoiding the limits of DynamoDB's BatchWriteItem.
|
|
69
|
-
* In case of errors, it will retry with a random back-off mechanism until the timeout.
|
|
70
|
-
* Therefore, in case of timeout, there may be some elements deleted and some not.
|
|
71
|
-
* @param table the target DynamoDB table
|
|
72
|
-
* @param keys the keys to delete
|
|
73
|
-
*/
|
|
74
|
-
batchDelete(table: string, keys: Record<string, any>[]): Promise<void>;
|
|
75
|
-
protected batchWriteHelper(table: string, itemsOrKeys: Record<string, any>[], isPut: boolean, currentChunk?: number, chunkSize?: number): Promise<void>;
|
|
76
|
-
protected batchWriteChunkWithRetries(table: string, params: DDB.BatchWriteCommandInput): Promise<void>;
|
|
77
|
-
/**
|
|
78
|
-
* Query a DynamoDB table, avoiding the limits of DynamoDB's Query.
|
|
79
|
-
* @param params the params to apply to DynamoDB's function
|
|
80
|
-
*/
|
|
81
|
-
query(params: DDB.QueryCommandInput): Promise<any[]>;
|
|
82
|
-
/**
|
|
83
|
-
* Scan a DynamoDB table, avoiding the limits of DynamoDB's Query.
|
|
84
|
-
* @param params the params to apply to DynamoDB's function
|
|
85
|
-
*/
|
|
86
|
-
scan(params: DDB.ScanCommandInput): Promise<any[]>;
|
|
87
|
-
protected queryScanHelper(params: DDB.QueryCommandInput | DDB.ScanCommandInput, items: Record<string, any>[], isQuery: boolean): Promise<Record<string, any>[]>;
|
|
88
|
-
/**
|
|
89
|
-
* Query a DynamoDB table in the traditional way (no pagination or data mapping).
|
|
90
|
-
* @param params the params to apply to DynamoDB's function
|
|
91
|
-
*/
|
|
92
|
-
queryClassic(params: DDB.QueryCommandInput): Promise<DDB.QueryCommandOutput>;
|
|
93
|
-
/**
|
|
94
|
-
* Scan a DynamoDB table in the traditional way (no pagination or data mapping).
|
|
95
|
-
* @param params the params to apply to DynamoDB's function
|
|
96
|
-
*/
|
|
97
|
-
scanClassic(params: DDB.ScanCommandInput): Promise<DDB.ScanCommandOutput>;
|
|
98
|
-
/**
|
|
99
|
-
* Execute a series of write operations in a single transaction.
|
|
100
|
-
* @param ops the operations to execute in the transaction
|
|
101
|
-
*/
|
|
102
|
-
transactWrites(ops: {
|
|
103
|
-
ConditionCheck?: any;
|
|
104
|
-
Put?: any;
|
|
105
|
-
Delete?: any;
|
|
106
|
-
Update?: any;
|
|
107
|
-
}[]): Promise<void>;
|
|
108
|
-
}
|
package/dist/src/dynamoDB.js
DELETED
|
@@ -1,296 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.DynamoDB = void 0;
|
|
27
|
-
const DDB = __importStar(require("@aws-sdk/lib-dynamodb"));
|
|
28
|
-
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
29
|
-
const DDBUtils = __importStar(require("@aws-sdk/util-dynamodb"));
|
|
30
|
-
const nanoid_1 = require("nanoid");
|
|
31
|
-
const NanoID = (0, nanoid_1.customAlphabet)('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 25);
|
|
32
|
-
const lambdaLogger_1 = require("./lambdaLogger");
|
|
33
|
-
/**
|
|
34
|
-
* A wrapper for AWS DynamoDB.
|
|
35
|
-
*/
|
|
36
|
-
class DynamoDB {
|
|
37
|
-
constructor() {
|
|
38
|
-
this.logger = new lambdaLogger_1.LambdaLogger();
|
|
39
|
-
this.dynamo = DDB.DynamoDBDocument.from(new client_dynamodb_1.DynamoDB(), {
|
|
40
|
-
marshallOptions: { convertEmptyValues: true, removeUndefinedValues: true, convertClassInstanceToMap: true }
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Convert a JSON object from DynamoDB format to simple JSON.
|
|
45
|
-
* @data the data in DynamoDB's original format to convert in plain objects
|
|
46
|
-
* @options the options to use to convert the data
|
|
47
|
-
*/
|
|
48
|
-
unmarshall(data, options) {
|
|
49
|
-
return DDBUtils.unmarshall(data, options);
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Returns an IUNID: IDEA's Unique Nano IDentifier, which is an id unique through an IDEA's AWS account and region.
|
|
53
|
-
* Note: no need of an auth check for external uses: the permissions depend from the context in which it's executed.
|
|
54
|
-
* @param project project code
|
|
55
|
-
* @return the IUNID
|
|
56
|
-
*/
|
|
57
|
-
async IUNID(project) {
|
|
58
|
-
const MAX_ATTEMPTS = 3;
|
|
59
|
-
if (!project)
|
|
60
|
-
throw new Error('Missing project');
|
|
61
|
-
return await this.IUNIDHelper(project, 0, MAX_ATTEMPTS);
|
|
62
|
-
}
|
|
63
|
-
async IUNIDHelper(project, attempt, maxAttempts) {
|
|
64
|
-
if (attempt > maxAttempts)
|
|
65
|
-
throw new Error('Operation failed');
|
|
66
|
-
const id = NanoID();
|
|
67
|
-
const result = `${project}_${id}`;
|
|
68
|
-
try {
|
|
69
|
-
await this.put({
|
|
70
|
-
TableName: 'idea_IUNID',
|
|
71
|
-
Item: { project, id },
|
|
72
|
-
ConditionExpression: 'NOT (#p = :project AND #id = :id)',
|
|
73
|
-
ExpressionAttributeNames: { '#p': 'project', '#id': 'id' },
|
|
74
|
-
ExpressionAttributeValues: { ':project': project, ':id': id }
|
|
75
|
-
});
|
|
76
|
-
return result;
|
|
77
|
-
}
|
|
78
|
-
catch (err) {
|
|
79
|
-
// ID exists, try again
|
|
80
|
-
await this.IUNIDHelper(project, attempt + 1, maxAttempts);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Manage atomic counters (atomic autoincrement values) in IDEA's projects.
|
|
85
|
-
* They key of an atomic counter should be composed as the following: `DynamoDBTableName_uniqueKey`.
|
|
86
|
-
* @param key the key of the counter
|
|
87
|
-
*/
|
|
88
|
-
async getAtomicCounterByKey(key) {
|
|
89
|
-
this.logger.trace(`Get atomic counter for ${key}`);
|
|
90
|
-
const { Attributes } = await this.update({
|
|
91
|
-
TableName: 'idea_atomicCounters',
|
|
92
|
-
Key: { key },
|
|
93
|
-
UpdateExpression: 'ADD atomicCounter :increment',
|
|
94
|
-
ExpressionAttributeValues: { ':increment': 1 },
|
|
95
|
-
ReturnValues: 'UPDATED_NEW'
|
|
96
|
-
});
|
|
97
|
-
if (!Attributes.atomicCounter)
|
|
98
|
-
throw new Error('Operation failed');
|
|
99
|
-
return Attributes.atomicCounter;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Get an item of a DynamoDB table.
|
|
103
|
-
* @param params the params to apply to DynamoDB's function
|
|
104
|
-
*/
|
|
105
|
-
async get(params) {
|
|
106
|
-
this.logger.trace(`Get ${params.TableName}`);
|
|
107
|
-
const { Item } = await this.dynamo.get(params);
|
|
108
|
-
if (!Item)
|
|
109
|
-
throw new Error('Not found');
|
|
110
|
-
return Item;
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Put an item in a DynamoDB table.
|
|
114
|
-
* @param params the params to apply to DynamoDB's function
|
|
115
|
-
*/
|
|
116
|
-
async put(params) {
|
|
117
|
-
this.logger.trace(`Put ${params.TableName}`);
|
|
118
|
-
return await this.dynamo.put(params);
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Update an item of a DynamoDB table.
|
|
122
|
-
* @param params the params to apply to DynamoDB's function
|
|
123
|
-
*/
|
|
124
|
-
async update(params) {
|
|
125
|
-
this.logger.trace(`Update ${params.TableName}`);
|
|
126
|
-
return await this.dynamo.update(params);
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Delete an item of a DynamoDB table.
|
|
130
|
-
* @param params the params to apply to DynamoDB's function
|
|
131
|
-
*/
|
|
132
|
-
async delete(params) {
|
|
133
|
-
this.logger.trace(`Delete ${params.TableName}`);
|
|
134
|
-
return await this.dynamo.delete(params);
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Get group of items based on their keys from DynamoDB table, avoiding the limits of DynamoDB's BatchGetItem.
|
|
138
|
-
* @param table the target DynamoDB table
|
|
139
|
-
* @param keys the keys of the objects to retrieve
|
|
140
|
-
* @param ignoreErr if set, ignore the errors and continue the bulk op.
|
|
141
|
-
*/
|
|
142
|
-
async batchGet(table, keys, ignoreErr) {
|
|
143
|
-
if (!keys.length) {
|
|
144
|
-
this.logger.trace(`Batch get ${table}: no elements to get`);
|
|
145
|
-
return [];
|
|
146
|
-
}
|
|
147
|
-
return await this.batchGetHelper(table, keys, [], Boolean(ignoreErr));
|
|
148
|
-
}
|
|
149
|
-
async batchGetHelper(table, keys, resultElements, ignoreErr, currentChunk = 0, chunkSize = 100) {
|
|
150
|
-
const batch = {
|
|
151
|
-
RequestItems: {
|
|
152
|
-
[table]: { Keys: keys.slice(currentChunk, currentChunk + chunkSize) }
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
this.logger.trace(`Batch get ${table}: ${currentChunk} of ${keys.length}`);
|
|
156
|
-
let result;
|
|
157
|
-
try {
|
|
158
|
-
result = await this.dynamo.batchGet(batch);
|
|
159
|
-
}
|
|
160
|
-
catch (err) {
|
|
161
|
-
if (!ignoreErr)
|
|
162
|
-
throw err;
|
|
163
|
-
}
|
|
164
|
-
if (result)
|
|
165
|
-
resultElements = resultElements.concat(result.Responses[table]);
|
|
166
|
-
// if there are still chunks to manage, go on recursively
|
|
167
|
-
if (currentChunk + chunkSize < keys.length)
|
|
168
|
-
return await this.batchGetHelper(table, keys, resultElements, ignoreErr, currentChunk + chunkSize, chunkSize);
|
|
169
|
-
// no more chunks to manage: we're done
|
|
170
|
-
else
|
|
171
|
-
return resultElements;
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Put an array of items in a DynamoDB table, avoiding the limits of DynamoDB's BatchWriteItem.
|
|
175
|
-
* In case of errors, it will retry with a random back-off mechanism until the timeout.
|
|
176
|
-
* Therefore, in case of timeout, there may be some elements written and some not.
|
|
177
|
-
* @param table the target DynamoDB table
|
|
178
|
-
* @param items the objects to insert
|
|
179
|
-
*/
|
|
180
|
-
async batchPut(table, items) {
|
|
181
|
-
if (!items.length)
|
|
182
|
-
return this.logger.trace(`Batch write (put) ${table}: no elements to write`);
|
|
183
|
-
await this.batchWriteHelper(table, items, true);
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* Delete an array of items from a DynamoDB table, avoiding the limits of DynamoDB's BatchWriteItem.
|
|
187
|
-
* In case of errors, it will retry with a random back-off mechanism until the timeout.
|
|
188
|
-
* Therefore, in case of timeout, there may be some elements deleted and some not.
|
|
189
|
-
* @param table the target DynamoDB table
|
|
190
|
-
* @param keys the keys to delete
|
|
191
|
-
*/
|
|
192
|
-
async batchDelete(table, keys) {
|
|
193
|
-
if (!keys.length)
|
|
194
|
-
return this.logger.trace(`Batch write (delete) ${table}: no elements to write`);
|
|
195
|
-
await this.batchWriteHelper(table, keys, false);
|
|
196
|
-
}
|
|
197
|
-
async batchWriteHelper(table, itemsOrKeys, isPut, currentChunk = 0, chunkSize = 25) {
|
|
198
|
-
this.logger.trace(`Batch write (${isPut ? 'put' : 'delete'}) ${table}: ${currentChunk} of ${itemsOrKeys.length}`);
|
|
199
|
-
let requests;
|
|
200
|
-
if (isPut)
|
|
201
|
-
requests = itemsOrKeys.slice(currentChunk, currentChunk + chunkSize).map(i => ({ PutRequest: { Item: i } }));
|
|
202
|
-
// isDelete
|
|
203
|
-
else
|
|
204
|
-
requests = itemsOrKeys.slice(currentChunk, currentChunk + chunkSize).map(k => ({ DeleteRequest: { Key: k } }));
|
|
205
|
-
const batch = { RequestItems: { [table]: requests } };
|
|
206
|
-
await this.batchWriteChunkWithRetries(table, batch);
|
|
207
|
-
// if there are still chunks to manage, go on recursively
|
|
208
|
-
if (currentChunk + chunkSize < itemsOrKeys.length)
|
|
209
|
-
await this.batchWriteHelper(table, itemsOrKeys, isPut, currentChunk + chunkSize, chunkSize);
|
|
210
|
-
}
|
|
211
|
-
async batchWriteChunkWithRetries(table, params) {
|
|
212
|
-
const getRandomInt = (max) => Math.floor(Math.random() * max);
|
|
213
|
-
const wait = (seconds) => new Promise(x => setTimeout(() => x(), seconds * 1000));
|
|
214
|
-
let attempts = 0;
|
|
215
|
-
do {
|
|
216
|
-
const response = await this.dynamo.batchWrite(params);
|
|
217
|
-
if (response.UnprocessedItems &&
|
|
218
|
-
response.UnprocessedItems[table] &&
|
|
219
|
-
response.UnprocessedItems[table].length > 0) {
|
|
220
|
-
params.RequestItems = response.UnprocessedItems;
|
|
221
|
-
attempts++;
|
|
222
|
-
const waitSeconds = getRandomInt(attempts * 5);
|
|
223
|
-
this.logger.trace(`Batch write throttled: waiting ${waitSeconds} seconds to retry`);
|
|
224
|
-
await wait(waitSeconds);
|
|
225
|
-
}
|
|
226
|
-
else {
|
|
227
|
-
params.RequestItems = null;
|
|
228
|
-
}
|
|
229
|
-
} while (params.RequestItems);
|
|
230
|
-
}
|
|
231
|
-
/**
|
|
232
|
-
* Query a DynamoDB table, avoiding the limits of DynamoDB's Query.
|
|
233
|
-
* @param params the params to apply to DynamoDB's function
|
|
234
|
-
*/
|
|
235
|
-
async query(params) {
|
|
236
|
-
this.logger.trace(`Query ${params.TableName}`);
|
|
237
|
-
const result = await this.queryScanHelper(params, [], true);
|
|
238
|
-
this.logger.trace(`Results query ${params.TableName}: ${result.length ?? 0}`);
|
|
239
|
-
return result;
|
|
240
|
-
}
|
|
241
|
-
/**
|
|
242
|
-
* Scan a DynamoDB table, avoiding the limits of DynamoDB's Query.
|
|
243
|
-
* @param params the params to apply to DynamoDB's function
|
|
244
|
-
*/
|
|
245
|
-
async scan(params) {
|
|
246
|
-
this.logger.trace(`Scan ${params.TableName}`);
|
|
247
|
-
const result = await this.queryScanHelper(params, [], false);
|
|
248
|
-
this.logger.trace(`Results scan ${params.TableName}: ${result.length ?? 0}`);
|
|
249
|
-
return result;
|
|
250
|
-
}
|
|
251
|
-
async queryScanHelper(params, items, isQuery) {
|
|
252
|
-
let result;
|
|
253
|
-
if (isQuery)
|
|
254
|
-
result = await this.dynamo.query(params);
|
|
255
|
-
else
|
|
256
|
-
result = await this.dynamo.scan(params);
|
|
257
|
-
items = items.concat(result.Items);
|
|
258
|
-
if (result.LastEvaluatedKey) {
|
|
259
|
-
params.ExclusiveStartKey = result.LastEvaluatedKey;
|
|
260
|
-
return await this.queryScanHelper(params, items, isQuery);
|
|
261
|
-
}
|
|
262
|
-
else
|
|
263
|
-
return items;
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* Query a DynamoDB table in the traditional way (no pagination or data mapping).
|
|
267
|
-
* @param params the params to apply to DynamoDB's function
|
|
268
|
-
*/
|
|
269
|
-
async queryClassic(params) {
|
|
270
|
-
this.logger.trace(`Query classic ${params.TableName}`);
|
|
271
|
-
const result = await this.dynamo.query(params);
|
|
272
|
-
this.logger.trace(`Results query classic ${params.TableName}: ${result.Items.length ?? 0}`);
|
|
273
|
-
return result;
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* Scan a DynamoDB table in the traditional way (no pagination or data mapping).
|
|
277
|
-
* @param params the params to apply to DynamoDB's function
|
|
278
|
-
*/
|
|
279
|
-
async scanClassic(params) {
|
|
280
|
-
this.logger.trace(`Scan classic ${params.TableName}`);
|
|
281
|
-
const result = await this.dynamo.scan(params);
|
|
282
|
-
this.logger.trace(`Results scan classic ${params.TableName}: ${result.Items.length ?? 0}`);
|
|
283
|
-
return result;
|
|
284
|
-
}
|
|
285
|
-
/**
|
|
286
|
-
* Execute a series of write operations in a single transaction.
|
|
287
|
-
* @param ops the operations to execute in the transaction
|
|
288
|
-
*/
|
|
289
|
-
async transactWrites(ops) {
|
|
290
|
-
if (!ops.length)
|
|
291
|
-
return this.logger.trace('Transaction writes: no elements to write');
|
|
292
|
-
this.logger.trace('Transaction writes');
|
|
293
|
-
await this.dynamo.transactWrite({ TransactItems: ops });
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
exports.DynamoDB = DynamoDB;
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import 'source-map-support/register';
|
|
2
|
-
import { LambdaLogger } from './lambdaLogger';
|
|
3
|
-
/**
|
|
4
|
-
* An abstract class to inherit to manage some resources with an AWS Lambda function.
|
|
5
|
-
*/
|
|
6
|
-
export declare abstract class GenericController {
|
|
7
|
-
protected event: any;
|
|
8
|
-
protected callback: any;
|
|
9
|
-
protected logger: LambdaLogger;
|
|
10
|
-
/**
|
|
11
|
-
* Initialize a new GenericController helper object.
|
|
12
|
-
* @param event the event that invoked the AWS lambda function
|
|
13
|
-
* @param callback the callback to resolve or reject the execution
|
|
14
|
-
*/
|
|
15
|
-
constructor(event: any, callback: any);
|
|
16
|
-
/**
|
|
17
|
-
* The main function (to override), that handles the request and must terminate invoking the method `done`.
|
|
18
|
-
*/
|
|
19
|
-
handleRequest(): Promise<void>;
|
|
20
|
-
/**
|
|
21
|
-
* Default callback for the Lambda.
|
|
22
|
-
*/
|
|
23
|
-
protected done(error?: Error | any, res?: any): void;
|
|
24
|
-
/**
|
|
25
|
-
* Remap an error to manage the logging and make sure no unhandled error is returned to the requester.
|
|
26
|
-
*/
|
|
27
|
-
protected handleControllerError(err: Error | HandledError | any, interceptedInContext: string, replaceWithMessage: string): HandledError | UnhandledError;
|
|
28
|
-
/**
|
|
29
|
-
* Get the current log level for the current Lambda function's `logger`.
|
|
30
|
-
* Note: "FATAL" means that no log will be printed.
|
|
31
|
-
*/
|
|
32
|
-
getLambdaLogLevel(): 'TRACE' | 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'FATAL';
|
|
33
|
-
/**
|
|
34
|
-
* Set the log level for the current Lambda function's `logger`.
|
|
35
|
-
*/
|
|
36
|
-
setLambdaLogLevel(logLevel: 'TRACE' | 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'FATAL'): void;
|
|
37
|
-
/**
|
|
38
|
-
* Raise the log level of the current Lambda function's `logger` to "FATAL", hence avoiding printing any log.
|
|
39
|
-
*/
|
|
40
|
-
silentLambdaLogs(): void;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* A specific type of error in the context of the Controller, to distinguish from "unhandled" errors.
|
|
44
|
-
*/
|
|
45
|
-
export declare class HandledError extends Error {
|
|
46
|
-
constructor(message: string);
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* An unhandled error thrown inside the controller (i.e. `!(error instanceof HandledError)`) .
|
|
50
|
-
*/
|
|
51
|
-
export declare class UnhandledError extends Error {
|
|
52
|
-
/**
|
|
53
|
-
* The context where the unhandled error was intercepted.
|
|
54
|
-
*/
|
|
55
|
-
unhandled: string;
|
|
56
|
-
/**
|
|
57
|
-
* The original error message before it was replaced by a public-facing message.
|
|
58
|
-
*/
|
|
59
|
-
internalMessage: string;
|
|
60
|
-
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.UnhandledError = exports.HandledError = exports.GenericController = void 0;
|
|
4
|
-
require("source-map-support/register");
|
|
5
|
-
const lambdaLogger_1 = require("./lambdaLogger");
|
|
6
|
-
/**
|
|
7
|
-
* An abstract class to inherit to manage some resources with an AWS Lambda function.
|
|
8
|
-
*/
|
|
9
|
-
class GenericController {
|
|
10
|
-
/**
|
|
11
|
-
* Initialize a new GenericController helper object.
|
|
12
|
-
* @param event the event that invoked the AWS lambda function
|
|
13
|
-
* @param callback the callback to resolve or reject the execution
|
|
14
|
-
*/
|
|
15
|
-
constructor(event, callback) {
|
|
16
|
-
this.logger = new lambdaLogger_1.LambdaLogger();
|
|
17
|
-
this.event = event;
|
|
18
|
-
this.callback = callback;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* The main function (to override), that handles the request and must terminate invoking the method `done`.
|
|
22
|
-
*/
|
|
23
|
-
async handleRequest() {
|
|
24
|
-
this.logger.info('START');
|
|
25
|
-
this.done();
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Default callback for the Lambda.
|
|
29
|
-
*/
|
|
30
|
-
done(error = null, res) {
|
|
31
|
-
if (error) {
|
|
32
|
-
if (error.unhandled)
|
|
33
|
-
this.logger.error('END-FAILED', error);
|
|
34
|
-
else
|
|
35
|
-
this.logger.warn('END-FAILED', error);
|
|
36
|
-
}
|
|
37
|
-
else
|
|
38
|
-
this.logger.info('END-SUCCESS');
|
|
39
|
-
this.callback(error, res);
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Remap an error to manage the logging and make sure no unhandled error is returned to the requester.
|
|
43
|
-
*/
|
|
44
|
-
handleControllerError(err, interceptedInContext, replaceWithMessage) {
|
|
45
|
-
if (err instanceof HandledError)
|
|
46
|
-
return err;
|
|
47
|
-
const error = err;
|
|
48
|
-
error.unhandled = interceptedInContext;
|
|
49
|
-
error.internalMessage = error.message;
|
|
50
|
-
error.message = replaceWithMessage;
|
|
51
|
-
return error;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Get the current log level for the current Lambda function's `logger`.
|
|
55
|
-
* Note: "FATAL" means that no log will be printed.
|
|
56
|
-
*/
|
|
57
|
-
getLambdaLogLevel() {
|
|
58
|
-
return process.env.AWS_LAMBDA_LOG_LEVEL;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Set the log level for the current Lambda function's `logger`.
|
|
62
|
-
*/
|
|
63
|
-
setLambdaLogLevel(logLevel) {
|
|
64
|
-
process.env.AWS_LAMBDA_LOG_LEVEL = logLevel;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Raise the log level of the current Lambda function's `logger` to "FATAL", hence avoiding printing any log.
|
|
68
|
-
*/
|
|
69
|
-
silentLambdaLogs() {
|
|
70
|
-
process.env.AWS_LAMBDA_LOG_LEVEL = 'FATAL';
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
exports.GenericController = GenericController;
|
|
74
|
-
/**
|
|
75
|
-
* A specific type of error in the context of the Controller, to distinguish from "unhandled" errors.
|
|
76
|
-
*/
|
|
77
|
-
class HandledError extends Error {
|
|
78
|
-
constructor(message) {
|
|
79
|
-
super(message);
|
|
80
|
-
Object.setPrototypeOf(this, HandledError.prototype);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
exports.HandledError = HandledError;
|
|
84
|
-
/**
|
|
85
|
-
* An unhandled error thrown inside the controller (i.e. `!(error instanceof HandledError)`) .
|
|
86
|
-
*/
|
|
87
|
-
class UnhandledError extends Error {
|
|
88
|
-
}
|
|
89
|
-
exports.UnhandledError = UnhandledError;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Manage structured logging in the context of a Lambda function.
|
|
3
|
-
* Note: the log level is controlled by each Lambda function's configuration.
|
|
4
|
-
*/
|
|
5
|
-
export declare class LambdaLogger {
|
|
6
|
-
shouldLog: (logLevel: 'TRACE' | 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'FATAL') => boolean;
|
|
7
|
-
trace: (summary: string, content?: object) => void;
|
|
8
|
-
debug: (summary: string, content?: object) => void;
|
|
9
|
-
info: (summary: string, content?: object) => void;
|
|
10
|
-
warn: (summary: string, error: Error | any, content?: object) => void;
|
|
11
|
-
error: (summary: string, error: Error | any, content?: object) => void;
|
|
12
|
-
}
|
|
13
|
-
export declare const LOG_LEVELS_PRIORITY: Record<string, number>;
|