@aspan-corporation/ac-shared 1.2.19 → 1.2.21
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/lib/index.js +3 -1581
- package/lib/lambda/index.d.ts +16 -16
- package/lib/lambda/index.js +56 -0
- package/lib/services/cloudWatch.js +30 -0
- package/lib/services/dynamoDB.js +45 -0
- package/lib/services/index.js +7 -0
- package/lib/services/location.js +23 -0
- package/lib/services/s3.js +92 -0
- package/lib/services/sqs.js +32 -0
- package/lib/services/ssm.js +26 -0
- package/lib/services/sts.js +33 -0
- package/lib/utils/helpers.js +10 -0
- package/lib/utils/index.js +9 -0
- package/lib/utils/normalizeErrorMessage.js +14 -0
- package/lib/utils/processMeta.js +135 -0
- package/lib/utils/thumbsKey.d.ts +12 -8
- package/lib/utils/thumbsKey.js +42 -0
- package/package.json +25 -10
- package/lib/index.js.map +0 -7
package/lib/index.js
CHANGED
|
@@ -1,1581 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
DeleteObjectsCommand,
|
|
5
|
-
GetObjectCommand,
|
|
6
|
-
HeadObjectCommand,
|
|
7
|
-
ListObjectsV2Command,
|
|
8
|
-
PutObjectCommand,
|
|
9
|
-
S3Client
|
|
10
|
-
} from "@aws-sdk/client-s3";
|
|
11
|
-
import { Upload } from "@aws-sdk/lib-storage";
|
|
12
|
-
import assert3 from "node:assert/strict";
|
|
13
|
-
import { PassThrough } from "node:stream";
|
|
14
|
-
|
|
15
|
-
// src/utils/index.ts
|
|
16
|
-
import assert2 from "node:assert/strict";
|
|
17
|
-
|
|
18
|
-
// src/utils/normalizeErrorMessage.ts
|
|
19
|
-
var normalizeErrorMessage = (error) => {
|
|
20
|
-
if (error instanceof Error) {
|
|
21
|
-
return error.message;
|
|
22
|
-
} else if (typeof error === "string") {
|
|
23
|
-
return error;
|
|
24
|
-
} else if (typeof error === "object" && error !== null) {
|
|
25
|
-
return JSON.stringify(error);
|
|
26
|
-
} else {
|
|
27
|
-
return String(error);
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
// src/utils/thumbsKey.ts
|
|
32
|
-
import { extname } from "node:path";
|
|
33
|
-
var JPEG_EXTENSION = "jpeg";
|
|
34
|
-
var JPG_EXTENSION = "jpg";
|
|
35
|
-
var HEIC_EXTENSION = "heic";
|
|
36
|
-
var MOV_EXTENSION = "mov";
|
|
37
|
-
var THUMBS_EXTENSION = JPG_EXTENSION;
|
|
38
|
-
var ENCODED_VIDEO_EXTENSION = "mp4";
|
|
39
|
-
var ALLOWED_EXTENSIONS = [
|
|
40
|
-
JPEG_EXTENSION,
|
|
41
|
-
JPG_EXTENSION,
|
|
42
|
-
HEIC_EXTENSION
|
|
43
|
-
];
|
|
44
|
-
var ALLOWED_VIDEO_EXTENSIONS = [MOV_EXTENSION];
|
|
45
|
-
var THUMBNAIL_RESOLUTIONS = [
|
|
46
|
-
[200, 200],
|
|
47
|
-
[1180, 820]
|
|
48
|
-
];
|
|
49
|
-
var getThumbsKey = ({
|
|
50
|
-
key,
|
|
51
|
-
width,
|
|
52
|
-
height
|
|
53
|
-
}) => {
|
|
54
|
-
return `${key.split(".").slice(0, -1).join(".")}.${width}x${height}.${THUMBS_EXTENSION}`;
|
|
55
|
-
};
|
|
56
|
-
var getEncodedVideoKey = ({ key }) => {
|
|
57
|
-
return `${key.split(".").slice(0, -1).join(".")}.${ENCODED_VIDEO_EXTENSION}`;
|
|
58
|
-
};
|
|
59
|
-
var getKeyExtension = (key) => extname(key).slice(1).toLowerCase();
|
|
60
|
-
var isAllowedExtension = (key) => {
|
|
61
|
-
const ext = getKeyExtension(key);
|
|
62
|
-
return ALLOWED_EXTENSIONS.includes(ext);
|
|
63
|
-
};
|
|
64
|
-
var isAllowedVideoExtension = (key) => {
|
|
65
|
-
const ext = getKeyExtension(key);
|
|
66
|
-
return ALLOWED_VIDEO_EXTENSIONS.includes(ext);
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
// src/utils/helpers.ts
|
|
70
|
-
var getObjectWithAssumeRoleCommandOutputAttribute = (assumeRoleCommandOutput) => assumeRoleCommandOutput ? {
|
|
71
|
-
credentials: {
|
|
72
|
-
accessKeyId: assumeRoleCommandOutput?.Credentials?.AccessKeyId,
|
|
73
|
-
secretAccessKey: assumeRoleCommandOutput?.Credentials?.SecretAccessKey,
|
|
74
|
-
sessionToken: assumeRoleCommandOutput?.Credentials?.SessionToken
|
|
75
|
-
}
|
|
76
|
-
} : {};
|
|
77
|
-
var getObjectWithStackAttribute = (error) => error && error instanceof Error ? { stack: error.stack } : {};
|
|
78
|
-
|
|
79
|
-
// src/utils/processMeta.ts
|
|
80
|
-
import assert from "node:assert/strict";
|
|
81
|
-
var processMeta = async ({
|
|
82
|
-
id,
|
|
83
|
-
meta,
|
|
84
|
-
metaTableName,
|
|
85
|
-
size,
|
|
86
|
-
logger: logger2,
|
|
87
|
-
locationService,
|
|
88
|
-
dynamoDBService
|
|
89
|
-
}) => {
|
|
90
|
-
const latitude = Number(meta.find((tag) => tag.key === "latitude")?.value);
|
|
91
|
-
const longitude = Number(meta.find((tag) => tag.key === "longitude")?.value);
|
|
92
|
-
let geoPositionResult;
|
|
93
|
-
if (!Number.isNaN(longitude) && !Number.isNaN(latitude)) {
|
|
94
|
-
try {
|
|
95
|
-
const res = await locationService.searchPlaceIndexForPositionCommand({
|
|
96
|
-
IndexName: "TauPlaceIndex",
|
|
97
|
-
Position: [longitude, latitude]
|
|
98
|
-
});
|
|
99
|
-
if (res?.Results && res?.Results?.length > 0) {
|
|
100
|
-
geoPositionResult = res?.Results[0];
|
|
101
|
-
} else {
|
|
102
|
-
throw Error("Can not resolve geo data");
|
|
103
|
-
}
|
|
104
|
-
} catch (error) {
|
|
105
|
-
logger2.error("Error fetching geo data", {
|
|
106
|
-
message: error instanceof Error ? error.message : ""
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
const newTags = [
|
|
111
|
-
...meta,
|
|
112
|
-
...meta.find((tag) => tag.key === "dateCreated") ? [] : extractMetaFromKey(id),
|
|
113
|
-
{ key: "extension", value: getKeyExtension(id) },
|
|
114
|
-
{ key: "size", value: String(size) },
|
|
115
|
-
{ key: "sizeMb", value: String(Math.round(size / 1024 ** 2)) },
|
|
116
|
-
...geoPositionResult?.Place?.Label ? [{ key: "label", value: geoPositionResult?.Place?.Label }] : [],
|
|
117
|
-
...geoPositionResult?.Place?.Country ? [{ key: "country", value: geoPositionResult?.Place?.Country }] : [],
|
|
118
|
-
...geoPositionResult?.Place?.Region ? [{ key: "region", value: geoPositionResult?.Place?.Region }] : [],
|
|
119
|
-
...geoPositionResult?.Place?.SubRegion ? [{ key: "subRegion", value: geoPositionResult?.Place?.SubRegion }] : [],
|
|
120
|
-
...geoPositionResult?.Place?.Municipality ? [{ key: "municipality", value: geoPositionResult?.Place?.Municipality }] : [],
|
|
121
|
-
...geoPositionResult?.Place?.Neighborhood ? [{ key: "neighborhood", value: geoPositionResult?.Place?.Neighborhood }] : [],
|
|
122
|
-
...geoPositionResult?.Place?.PostalCode ? [{ key: "postalCode", value: geoPositionResult?.Place?.PostalCode }] : []
|
|
123
|
-
].map((tag) => ({
|
|
124
|
-
key: "ac:tau:" + tag.key,
|
|
125
|
-
value: tag.value
|
|
126
|
-
}));
|
|
127
|
-
logger2.debug("metaData", { newTags });
|
|
128
|
-
logger2.debug("trying to read existing metadata");
|
|
129
|
-
const getResponse = await dynamoDBService.getCommand({
|
|
130
|
-
TableName: metaTableName,
|
|
131
|
-
Key: {
|
|
132
|
-
id
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
const oldTags = getResponse.Item?.tags;
|
|
136
|
-
logger2.debug("existing tags", { getResponse });
|
|
137
|
-
const reconciledTags = reconcileTags({ newTags, oldTags }, logger2);
|
|
138
|
-
logger2.debug("result", { reconciledTags });
|
|
139
|
-
const updateResponse = await dynamoDBService.updateCommand({
|
|
140
|
-
TableName: metaTableName,
|
|
141
|
-
Key: {
|
|
142
|
-
id
|
|
143
|
-
},
|
|
144
|
-
UpdateExpression: "set tags = :tags",
|
|
145
|
-
ExpressionAttributeValues: {
|
|
146
|
-
":tags": reconciledTags
|
|
147
|
-
},
|
|
148
|
-
ReturnValues: "ALL_NEW"
|
|
149
|
-
});
|
|
150
|
-
logger2.debug("sent UpdateCommand", { updateResponse });
|
|
151
|
-
};
|
|
152
|
-
var reconcileTags = ({ oldTags = [], newTags = [] }, logger2) => oldTags.reduce((acc, cur) => {
|
|
153
|
-
if (acc.find((element) => element.key === cur.key)) {
|
|
154
|
-
return acc;
|
|
155
|
-
} else {
|
|
156
|
-
logger2.debug("added", cur);
|
|
157
|
-
return [...acc, cur];
|
|
158
|
-
}
|
|
159
|
-
}, newTags);
|
|
160
|
-
var SUBSTRING_ANSI_DATES_BEGIN_WITH = "20";
|
|
161
|
-
var extractMetaFromKey = (key) => {
|
|
162
|
-
if (!key)
|
|
163
|
-
return [];
|
|
164
|
-
let firstToken = void 0;
|
|
165
|
-
try {
|
|
166
|
-
const folder = key.split("/").at(-2);
|
|
167
|
-
assert(typeof folder === "string");
|
|
168
|
-
firstToken = folder.split(".")[0];
|
|
169
|
-
} catch (error) {
|
|
170
|
-
}
|
|
171
|
-
if (firstToken === void 0 || firstToken.length !== 8 || !firstToken.startsWith(SUBSTRING_ANSI_DATES_BEGIN_WITH))
|
|
172
|
-
return [];
|
|
173
|
-
const year = Number(firstToken.substring(0, 4));
|
|
174
|
-
const month = Number(firstToken.substring(4, 6)) - 1;
|
|
175
|
-
const day = Number(firstToken.substring(6));
|
|
176
|
-
if (isNaN(year) || isNaN(month) || isNaN(day))
|
|
177
|
-
return [];
|
|
178
|
-
if (year < 2e3 || month < 1 || month > 11 || day < 1 || day > 31)
|
|
179
|
-
return [];
|
|
180
|
-
const dateCreatedBin = new Date(year, month, day);
|
|
181
|
-
return [
|
|
182
|
-
{ key: "dateCreated", value: dateCreatedBin.toISOString() },
|
|
183
|
-
{ key: "yearCreated", value: dateCreatedBin.getFullYear().toString() },
|
|
184
|
-
{ key: "dayCreated", value: dateCreatedBin.getDate().toString() },
|
|
185
|
-
{
|
|
186
|
-
key: "monthCreated",
|
|
187
|
-
value: (dateCreatedBin.getMonth() + 1).toString()
|
|
188
|
-
}
|
|
189
|
-
];
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
// src/utils/index.ts
|
|
193
|
-
var assertEnvVar = (envVar) => {
|
|
194
|
-
assert2(process.env[envVar], `${envVar} is not set`);
|
|
195
|
-
return process.env[envVar];
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
// src/services/s3.ts
|
|
199
|
-
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
|
200
|
-
var S3Service = class {
|
|
201
|
-
logger;
|
|
202
|
-
client;
|
|
203
|
-
constructor({
|
|
204
|
-
logger: logger2,
|
|
205
|
-
client,
|
|
206
|
-
assumeRoleCommandOutput,
|
|
207
|
-
region
|
|
208
|
-
}) {
|
|
209
|
-
this.logger = logger2;
|
|
210
|
-
if (client) {
|
|
211
|
-
this.client = client;
|
|
212
|
-
} else {
|
|
213
|
-
assert3(region, "Region must be provided if client is not passed");
|
|
214
|
-
this.client = new S3Client({
|
|
215
|
-
region,
|
|
216
|
-
...getObjectWithAssumeRoleCommandOutputAttribute(
|
|
217
|
-
assumeRoleCommandOutput
|
|
218
|
-
)
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
createS3UploadStream(putObjectCommandInput) {
|
|
223
|
-
this.logger.debug("upload stream started", { putObjectCommandInput });
|
|
224
|
-
const pass = new PassThrough();
|
|
225
|
-
const parallelUploads = new Upload({
|
|
226
|
-
client: this.client,
|
|
227
|
-
params: {
|
|
228
|
-
...putObjectCommandInput,
|
|
229
|
-
Body: pass
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
const donePromise = parallelUploads.done().then(() => this.logger.debug("upload stream finished")).catch((err) => {
|
|
233
|
-
this.logger.error("upload stream error", err);
|
|
234
|
-
pass.destroy(err);
|
|
235
|
-
});
|
|
236
|
-
return { stream: pass, done: donePromise };
|
|
237
|
-
}
|
|
238
|
-
async createS3DownloadStream(getObjectCommandInput) {
|
|
239
|
-
this.logger.debug("download stream started", { getObjectCommandInput });
|
|
240
|
-
const item = await this.client.send(
|
|
241
|
-
new GetObjectCommand(getObjectCommandInput)
|
|
242
|
-
);
|
|
243
|
-
this.logger.debug("download stream finished");
|
|
244
|
-
return item.Body;
|
|
245
|
-
}
|
|
246
|
-
async listObjectsV2(listObjectsV2CommandInput) {
|
|
247
|
-
this.logger.debug("listObjectsV2", { listObjectsV2CommandInput });
|
|
248
|
-
return await this.client.send(
|
|
249
|
-
new ListObjectsV2Command(listObjectsV2CommandInput)
|
|
250
|
-
);
|
|
251
|
-
}
|
|
252
|
-
async getObject(getObjectCommandInput) {
|
|
253
|
-
this.logger.debug("getObject", { getObjectCommandInput });
|
|
254
|
-
const stream = await this.createS3DownloadStream(getObjectCommandInput);
|
|
255
|
-
return Buffer.from(await stream.transformToByteArray());
|
|
256
|
-
}
|
|
257
|
-
async getSignedUrl(getObjectCommandInput) {
|
|
258
|
-
this.logger.debug("getSignedUrl", { getObjectCommandInput });
|
|
259
|
-
const signedUrl = await getSignedUrl(
|
|
260
|
-
this.client,
|
|
261
|
-
new GetObjectCommand(getObjectCommandInput),
|
|
262
|
-
{ expiresIn: 3600 }
|
|
263
|
-
);
|
|
264
|
-
return signedUrl;
|
|
265
|
-
}
|
|
266
|
-
async putObject(putObjectCommandInput) {
|
|
267
|
-
this.logger.debug("putObject", { putObjectCommandInput });
|
|
268
|
-
return await this.client.send(new PutObjectCommand(putObjectCommandInput));
|
|
269
|
-
}
|
|
270
|
-
async headObject(headObjectCommandInput) {
|
|
271
|
-
this.logger.debug("headObject", { headObjectCommandInput });
|
|
272
|
-
return await this.client.send(
|
|
273
|
-
new HeadObjectCommand(headObjectCommandInput)
|
|
274
|
-
);
|
|
275
|
-
}
|
|
276
|
-
async checkIfObjectExists(headObjectCommandInput) {
|
|
277
|
-
this.logger.debug("checkIfObjectExists", { headObjectCommandInput });
|
|
278
|
-
try {
|
|
279
|
-
await this.headObject(headObjectCommandInput);
|
|
280
|
-
return true;
|
|
281
|
-
} catch (error) {
|
|
282
|
-
if (error.name === "NotFound") {
|
|
283
|
-
return false;
|
|
284
|
-
}
|
|
285
|
-
throw error;
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
async deleteObject(deleteObjectCommandInput) {
|
|
289
|
-
this.logger.debug("deleteObject", { deleteObjectCommandInput });
|
|
290
|
-
return await this.client.send(
|
|
291
|
-
new DeleteObjectCommand(deleteObjectCommandInput)
|
|
292
|
-
);
|
|
293
|
-
}
|
|
294
|
-
async deleteObjects(deleteObjectsCommandInput) {
|
|
295
|
-
this.logger.debug("deleteObjects", { deleteObjectsCommandInput });
|
|
296
|
-
return await this.client.send(
|
|
297
|
-
new DeleteObjectsCommand(deleteObjectsCommandInput)
|
|
298
|
-
);
|
|
299
|
-
}
|
|
300
|
-
};
|
|
301
|
-
|
|
302
|
-
// src/services/dynamoDB.ts
|
|
303
|
-
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
|
|
304
|
-
import {
|
|
305
|
-
DynamoDBDocumentClient,
|
|
306
|
-
GetCommand,
|
|
307
|
-
PutCommand,
|
|
308
|
-
QueryCommand,
|
|
309
|
-
UpdateCommand,
|
|
310
|
-
ScanCommand,
|
|
311
|
-
BatchWriteCommand
|
|
312
|
-
} from "@aws-sdk/lib-dynamodb";
|
|
313
|
-
import assert4 from "node:assert/strict";
|
|
314
|
-
var DynamoDBService = class {
|
|
315
|
-
logger;
|
|
316
|
-
client;
|
|
317
|
-
documentClient;
|
|
318
|
-
constructor({
|
|
319
|
-
logger: logger2,
|
|
320
|
-
client,
|
|
321
|
-
assumeRoleCommandOutput,
|
|
322
|
-
region
|
|
323
|
-
}) {
|
|
324
|
-
this.logger = logger2;
|
|
325
|
-
if (client) {
|
|
326
|
-
this.client = client;
|
|
327
|
-
} else {
|
|
328
|
-
assert4(region, "Region must be provided if client is not passed");
|
|
329
|
-
this.client = new DynamoDBClient({
|
|
330
|
-
region,
|
|
331
|
-
...getObjectWithAssumeRoleCommandOutputAttribute(
|
|
332
|
-
assumeRoleCommandOutput
|
|
333
|
-
)
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
this.documentClient = DynamoDBDocumentClient.from(this.client);
|
|
337
|
-
}
|
|
338
|
-
async getCommand(getCommandInput) {
|
|
339
|
-
return await this.documentClient.send(new GetCommand(getCommandInput));
|
|
340
|
-
}
|
|
341
|
-
async updateCommand(updateCommandInput) {
|
|
342
|
-
return await this.documentClient.send(
|
|
343
|
-
new UpdateCommand(updateCommandInput)
|
|
344
|
-
);
|
|
345
|
-
}
|
|
346
|
-
async queryCommand(queryCommandInput) {
|
|
347
|
-
return await this.documentClient.send(new QueryCommand(queryCommandInput));
|
|
348
|
-
}
|
|
349
|
-
async putCommand(putCommandInput) {
|
|
350
|
-
return await this.documentClient.send(new PutCommand(putCommandInput));
|
|
351
|
-
}
|
|
352
|
-
async checkIfItemExists(checkInput) {
|
|
353
|
-
const result = await this.getCommand(checkInput);
|
|
354
|
-
return !!result.Item;
|
|
355
|
-
}
|
|
356
|
-
async scanCommand(scanCommandInput) {
|
|
357
|
-
return await this.client.send(new ScanCommand(scanCommandInput));
|
|
358
|
-
}
|
|
359
|
-
async batchWriteCommand(batchWriteCommandInput) {
|
|
360
|
-
return await this.client.send(
|
|
361
|
-
new BatchWriteCommand(batchWriteCommandInput)
|
|
362
|
-
);
|
|
363
|
-
}
|
|
364
|
-
};
|
|
365
|
-
|
|
366
|
-
// src/services/ssm.ts
|
|
367
|
-
import {
|
|
368
|
-
GetParameterCommand,
|
|
369
|
-
PutParameterCommand,
|
|
370
|
-
SSMClient
|
|
371
|
-
} from "@aws-sdk/client-ssm";
|
|
372
|
-
import assert5 from "node:assert/strict";
|
|
373
|
-
var SSMService = class {
|
|
374
|
-
logger;
|
|
375
|
-
client;
|
|
376
|
-
constructor({
|
|
377
|
-
logger: logger2,
|
|
378
|
-
client,
|
|
379
|
-
assumeRoleCommandOutput,
|
|
380
|
-
region
|
|
381
|
-
}) {
|
|
382
|
-
this.logger = logger2;
|
|
383
|
-
if (client) {
|
|
384
|
-
this.client = client;
|
|
385
|
-
} else {
|
|
386
|
-
assert5(region, "Region must be provided if client is not passed");
|
|
387
|
-
this.client = new SSMClient({
|
|
388
|
-
region,
|
|
389
|
-
...getObjectWithAssumeRoleCommandOutputAttribute(
|
|
390
|
-
assumeRoleCommandOutput
|
|
391
|
-
)
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
async getParameter(params) {
|
|
396
|
-
return await this.client.send(new GetParameterCommand(params));
|
|
397
|
-
}
|
|
398
|
-
async putParameter(params) {
|
|
399
|
-
return await this.client.send(new PutParameterCommand(params));
|
|
400
|
-
}
|
|
401
|
-
};
|
|
402
|
-
|
|
403
|
-
// src/services/sqs.ts
|
|
404
|
-
import {
|
|
405
|
-
DeleteMessageCommand,
|
|
406
|
-
ReceiveMessageCommand,
|
|
407
|
-
SQSClient,
|
|
408
|
-
SendMessageBatchCommand,
|
|
409
|
-
SendMessageCommand
|
|
410
|
-
} from "@aws-sdk/client-sqs";
|
|
411
|
-
import assert6 from "node:assert/strict";
|
|
412
|
-
var SQSService = class {
|
|
413
|
-
logger;
|
|
414
|
-
client;
|
|
415
|
-
constructor({
|
|
416
|
-
logger: logger2,
|
|
417
|
-
client,
|
|
418
|
-
assumeRoleCommandOutput,
|
|
419
|
-
region
|
|
420
|
-
}) {
|
|
421
|
-
this.logger = logger2;
|
|
422
|
-
if (client) {
|
|
423
|
-
this.client = client;
|
|
424
|
-
} else {
|
|
425
|
-
assert6(region, "Region must be provided if client is not passed");
|
|
426
|
-
this.client = new SQSClient({
|
|
427
|
-
region,
|
|
428
|
-
...getObjectWithAssumeRoleCommandOutputAttribute(
|
|
429
|
-
assumeRoleCommandOutput
|
|
430
|
-
)
|
|
431
|
-
});
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
async sendMessage(params) {
|
|
435
|
-
return await this.client.send(new SendMessageCommand(params));
|
|
436
|
-
}
|
|
437
|
-
async sendMessageBatch(params) {
|
|
438
|
-
return await this.client.send(new SendMessageBatchCommand(params));
|
|
439
|
-
}
|
|
440
|
-
async receiveMessage(params) {
|
|
441
|
-
return await this.client.send(new ReceiveMessageCommand(params));
|
|
442
|
-
}
|
|
443
|
-
async deleteMessage(params) {
|
|
444
|
-
return await this.client.send(new DeleteMessageCommand(params));
|
|
445
|
-
}
|
|
446
|
-
};
|
|
447
|
-
|
|
448
|
-
// src/services/sts.ts
|
|
449
|
-
import { Logger } from "@aws-lambda-powertools/logger";
|
|
450
|
-
import {
|
|
451
|
-
AssumeRoleCommand,
|
|
452
|
-
GetCallerIdentityCommand,
|
|
453
|
-
STSClient
|
|
454
|
-
} from "@aws-sdk/client-sts";
|
|
455
|
-
import assert7 from "node:assert/strict";
|
|
456
|
-
var STSService = class {
|
|
457
|
-
logger;
|
|
458
|
-
client;
|
|
459
|
-
constructor({
|
|
460
|
-
logger: logger2,
|
|
461
|
-
region,
|
|
462
|
-
client
|
|
463
|
-
}) {
|
|
464
|
-
if (logger2) {
|
|
465
|
-
this.logger = logger2;
|
|
466
|
-
} else {
|
|
467
|
-
this.logger = new Logger();
|
|
468
|
-
this.logger.appendKeys({ scope: "STSService" });
|
|
469
|
-
}
|
|
470
|
-
if (client) {
|
|
471
|
-
this.client = client;
|
|
472
|
-
} else {
|
|
473
|
-
assert7(region, "Region must be provided if client is not passed");
|
|
474
|
-
this.client = new STSClient({
|
|
475
|
-
region
|
|
476
|
-
});
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
async getCallerIdentity() {
|
|
480
|
-
this.logger.debug("getCallerIdentity");
|
|
481
|
-
return await this.client.send(new GetCallerIdentityCommand({}));
|
|
482
|
-
}
|
|
483
|
-
async assumeRole(assumeRoleCommandInput) {
|
|
484
|
-
this.logger.debug("assumeRole", { assumeRoleCommandInput });
|
|
485
|
-
return await this.client.send(
|
|
486
|
-
new AssumeRoleCommand(assumeRoleCommandInput)
|
|
487
|
-
);
|
|
488
|
-
}
|
|
489
|
-
};
|
|
490
|
-
|
|
491
|
-
// src/services/location.ts
|
|
492
|
-
import {
|
|
493
|
-
LocationClient,
|
|
494
|
-
SearchPlaceIndexForPositionCommand
|
|
495
|
-
} from "@aws-sdk/client-location";
|
|
496
|
-
import assert8 from "node:assert/strict";
|
|
497
|
-
var LocationService = class {
|
|
498
|
-
logger;
|
|
499
|
-
client;
|
|
500
|
-
constructor({
|
|
501
|
-
logger: logger2,
|
|
502
|
-
client,
|
|
503
|
-
assumeRoleCommandOutput,
|
|
504
|
-
region
|
|
505
|
-
}) {
|
|
506
|
-
this.logger = logger2;
|
|
507
|
-
if (client) {
|
|
508
|
-
this.client = client;
|
|
509
|
-
} else {
|
|
510
|
-
assert8(region, "Region must be provided if client is not passed");
|
|
511
|
-
this.client = new LocationClient({
|
|
512
|
-
region,
|
|
513
|
-
...getObjectWithAssumeRoleCommandOutputAttribute(
|
|
514
|
-
assumeRoleCommandOutput
|
|
515
|
-
)
|
|
516
|
-
});
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
async searchPlaceIndexForPositionCommand(searchPlaceIndexForPositionCommandInput) {
|
|
520
|
-
return await this.client.send(
|
|
521
|
-
new SearchPlaceIndexForPositionCommand(
|
|
522
|
-
searchPlaceIndexForPositionCommandInput
|
|
523
|
-
)
|
|
524
|
-
);
|
|
525
|
-
}
|
|
526
|
-
};
|
|
527
|
-
|
|
528
|
-
// src/services/cloudWatch.ts
|
|
529
|
-
import {
|
|
530
|
-
CloudWatchLogsClient,
|
|
531
|
-
DescribeLogStreamsCommand,
|
|
532
|
-
PutLogEventsCommand
|
|
533
|
-
} from "@aws-sdk/client-cloudwatch-logs";
|
|
534
|
-
import assert9 from "node:assert/strict";
|
|
535
|
-
var CloudWatchService = class {
|
|
536
|
-
logger;
|
|
537
|
-
client;
|
|
538
|
-
constructor({
|
|
539
|
-
logger: logger2,
|
|
540
|
-
client,
|
|
541
|
-
assumeRoleCommandOutput,
|
|
542
|
-
region
|
|
543
|
-
}) {
|
|
544
|
-
this.logger = logger2;
|
|
545
|
-
if (client) {
|
|
546
|
-
this.client = client;
|
|
547
|
-
} else {
|
|
548
|
-
assert9(region, "Region must be provided if client is not passed");
|
|
549
|
-
this.client = new CloudWatchLogsClient({
|
|
550
|
-
region,
|
|
551
|
-
...getObjectWithAssumeRoleCommandOutputAttribute(
|
|
552
|
-
assumeRoleCommandOutput
|
|
553
|
-
)
|
|
554
|
-
});
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
async describeLogStreamsCommand(describeLogStreamsCommandInput) {
|
|
558
|
-
this.logger.debug("describeLogStreamsCommand", {
|
|
559
|
-
describeLogStreamsCommandInput
|
|
560
|
-
});
|
|
561
|
-
return await this.client.send(
|
|
562
|
-
new DescribeLogStreamsCommand(describeLogStreamsCommandInput)
|
|
563
|
-
);
|
|
564
|
-
}
|
|
565
|
-
async putLogEventsCommand(putLogEventsCommandInput) {
|
|
566
|
-
this.logger.debug("putLogEventsCommand", { putLogEventsCommandInput });
|
|
567
|
-
return await this.client.send(
|
|
568
|
-
new PutLogEventsCommand(putLogEventsCommandInput)
|
|
569
|
-
);
|
|
570
|
-
}
|
|
571
|
-
};
|
|
572
|
-
|
|
573
|
-
// node_modules/@aws-lambda-powertools/batch/node_modules/@aws/lambda-invoke-store/dist-es/invoke-store.js
|
|
574
|
-
var PROTECTED_KEYS = {
|
|
575
|
-
REQUEST_ID: Symbol.for("_AWS_LAMBDA_REQUEST_ID"),
|
|
576
|
-
X_RAY_TRACE_ID: Symbol.for("_AWS_LAMBDA_X_RAY_TRACE_ID"),
|
|
577
|
-
TENANT_ID: Symbol.for("_AWS_LAMBDA_TENANT_ID")
|
|
578
|
-
};
|
|
579
|
-
var NO_GLOBAL_AWS_LAMBDA = ["true", "1"].includes(process.env?.AWS_LAMBDA_NODEJS_NO_GLOBAL_AWSLAMBDA ?? "");
|
|
580
|
-
if (!NO_GLOBAL_AWS_LAMBDA) {
|
|
581
|
-
globalThis.awslambda = globalThis.awslambda || {};
|
|
582
|
-
}
|
|
583
|
-
var InvokeStoreBase = class {
|
|
584
|
-
static PROTECTED_KEYS = PROTECTED_KEYS;
|
|
585
|
-
isProtectedKey(key) {
|
|
586
|
-
return Object.values(PROTECTED_KEYS).includes(key);
|
|
587
|
-
}
|
|
588
|
-
getRequestId() {
|
|
589
|
-
return this.get(PROTECTED_KEYS.REQUEST_ID) ?? "-";
|
|
590
|
-
}
|
|
591
|
-
getXRayTraceId() {
|
|
592
|
-
return this.get(PROTECTED_KEYS.X_RAY_TRACE_ID);
|
|
593
|
-
}
|
|
594
|
-
getTenantId() {
|
|
595
|
-
return this.get(PROTECTED_KEYS.TENANT_ID);
|
|
596
|
-
}
|
|
597
|
-
};
|
|
598
|
-
var InvokeStoreSingle = class extends InvokeStoreBase {
|
|
599
|
-
currentContext;
|
|
600
|
-
getContext() {
|
|
601
|
-
return this.currentContext;
|
|
602
|
-
}
|
|
603
|
-
hasContext() {
|
|
604
|
-
return this.currentContext !== void 0;
|
|
605
|
-
}
|
|
606
|
-
get(key) {
|
|
607
|
-
return this.currentContext?.[key];
|
|
608
|
-
}
|
|
609
|
-
set(key, value) {
|
|
610
|
-
if (this.isProtectedKey(key)) {
|
|
611
|
-
throw new Error(`Cannot modify protected Lambda context field: ${String(key)}`);
|
|
612
|
-
}
|
|
613
|
-
this.currentContext = this.currentContext || {};
|
|
614
|
-
this.currentContext[key] = value;
|
|
615
|
-
}
|
|
616
|
-
run(context, fn) {
|
|
617
|
-
this.currentContext = context;
|
|
618
|
-
return fn();
|
|
619
|
-
}
|
|
620
|
-
};
|
|
621
|
-
var InvokeStoreMulti = class _InvokeStoreMulti extends InvokeStoreBase {
|
|
622
|
-
als;
|
|
623
|
-
static async create() {
|
|
624
|
-
const instance = new _InvokeStoreMulti();
|
|
625
|
-
const asyncHooks = await import("node:async_hooks");
|
|
626
|
-
instance.als = new asyncHooks.AsyncLocalStorage();
|
|
627
|
-
return instance;
|
|
628
|
-
}
|
|
629
|
-
getContext() {
|
|
630
|
-
return this.als.getStore();
|
|
631
|
-
}
|
|
632
|
-
hasContext() {
|
|
633
|
-
return this.als.getStore() !== void 0;
|
|
634
|
-
}
|
|
635
|
-
get(key) {
|
|
636
|
-
return this.als.getStore()?.[key];
|
|
637
|
-
}
|
|
638
|
-
set(key, value) {
|
|
639
|
-
if (this.isProtectedKey(key)) {
|
|
640
|
-
throw new Error(`Cannot modify protected Lambda context field: ${String(key)}`);
|
|
641
|
-
}
|
|
642
|
-
const store = this.als.getStore();
|
|
643
|
-
if (!store) {
|
|
644
|
-
throw new Error("No context available");
|
|
645
|
-
}
|
|
646
|
-
store[key] = value;
|
|
647
|
-
}
|
|
648
|
-
run(context, fn) {
|
|
649
|
-
return this.als.run(context, fn);
|
|
650
|
-
}
|
|
651
|
-
};
|
|
652
|
-
var InvokeStore;
|
|
653
|
-
(function(InvokeStore2) {
|
|
654
|
-
let instance = null;
|
|
655
|
-
async function getInstanceAsync() {
|
|
656
|
-
if (!instance) {
|
|
657
|
-
instance = (async () => {
|
|
658
|
-
const isMulti = "AWS_LAMBDA_MAX_CONCURRENCY" in process.env;
|
|
659
|
-
const newInstance = isMulti ? await InvokeStoreMulti.create() : new InvokeStoreSingle();
|
|
660
|
-
if (!NO_GLOBAL_AWS_LAMBDA && globalThis.awslambda?.InvokeStore) {
|
|
661
|
-
return globalThis.awslambda.InvokeStore;
|
|
662
|
-
} else if (!NO_GLOBAL_AWS_LAMBDA && globalThis.awslambda) {
|
|
663
|
-
globalThis.awslambda.InvokeStore = newInstance;
|
|
664
|
-
return newInstance;
|
|
665
|
-
} else {
|
|
666
|
-
return newInstance;
|
|
667
|
-
}
|
|
668
|
-
})();
|
|
669
|
-
}
|
|
670
|
-
return instance;
|
|
671
|
-
}
|
|
672
|
-
InvokeStore2.getInstanceAsync = getInstanceAsync;
|
|
673
|
-
InvokeStore2._testing = process.env.AWS_LAMBDA_BENCHMARK_MODE === "1" ? {
|
|
674
|
-
reset: () => {
|
|
675
|
-
instance = null;
|
|
676
|
-
if (globalThis.awslambda?.InvokeStore) {
|
|
677
|
-
delete globalThis.awslambda.InvokeStore;
|
|
678
|
-
}
|
|
679
|
-
globalThis.awslambda = {};
|
|
680
|
-
}
|
|
681
|
-
} : void 0;
|
|
682
|
-
})(InvokeStore || (InvokeStore = {}));
|
|
683
|
-
|
|
684
|
-
// node_modules/@aws-lambda-powertools/batch/node_modules/@aws-lambda-powertools/commons/lib/esm/constants.js
|
|
685
|
-
var AWS_LAMBDA_MAX_CONCURRENCY = "AWS_LAMBDA_MAX_CONCURRENCY";
|
|
686
|
-
|
|
687
|
-
// node_modules/@aws-lambda-powertools/batch/node_modules/@aws-lambda-powertools/commons/lib/esm/envUtils.js
|
|
688
|
-
var getStringFromEnv = ({ key, defaultValue, errorMessage }) => {
|
|
689
|
-
const value = process.env[key];
|
|
690
|
-
if (value === void 0) {
|
|
691
|
-
if (defaultValue !== void 0) {
|
|
692
|
-
return defaultValue;
|
|
693
|
-
}
|
|
694
|
-
if (errorMessage) {
|
|
695
|
-
throw new Error(errorMessage);
|
|
696
|
-
}
|
|
697
|
-
throw new Error(`Environment variable ${key} is required`);
|
|
698
|
-
}
|
|
699
|
-
return value.trim();
|
|
700
|
-
};
|
|
701
|
-
var shouldUseInvokeStore = () => {
|
|
702
|
-
const res = getStringFromEnv({
|
|
703
|
-
key: AWS_LAMBDA_MAX_CONCURRENCY,
|
|
704
|
-
defaultValue: ""
|
|
705
|
-
});
|
|
706
|
-
return res !== "";
|
|
707
|
-
};
|
|
708
|
-
|
|
709
|
-
// node_modules/@aws-lambda-powertools/batch/lib/esm/BatchProcessingStore.js
|
|
710
|
-
var BatchProcessingStore = class {
|
|
711
|
-
#recordsKey = Symbol("powertools.batch.records");
|
|
712
|
-
#handlerKey = Symbol("powertools.batch.handler");
|
|
713
|
-
#optionsKey = Symbol("powertools.batch.options");
|
|
714
|
-
#failureMessagesKey = Symbol("powertools.batch.failureMessages");
|
|
715
|
-
#successMessagesKey = Symbol("powertools.batch.successMessages");
|
|
716
|
-
#batchResponseKey = Symbol("powertools.batch.batchResponse");
|
|
717
|
-
#errorsKey = Symbol("powertools.batch.errors");
|
|
718
|
-
#fallbackRecords = [];
|
|
719
|
-
#fallbackHandler = () => {
|
|
720
|
-
};
|
|
721
|
-
#fallbackOptions;
|
|
722
|
-
#fallbackFailureMessages = [];
|
|
723
|
-
#fallbackSuccessMessages = [];
|
|
724
|
-
#fallbackBatchResponse = {
|
|
725
|
-
batchItemFailures: []
|
|
726
|
-
};
|
|
727
|
-
#fallbackErrors = [];
|
|
728
|
-
getRecords() {
|
|
729
|
-
if (!shouldUseInvokeStore()) {
|
|
730
|
-
return this.#fallbackRecords;
|
|
731
|
-
}
|
|
732
|
-
if (globalThis.awslambda?.InvokeStore === void 0) {
|
|
733
|
-
throw new Error("InvokeStore is not available");
|
|
734
|
-
}
|
|
735
|
-
const store = globalThis.awslambda.InvokeStore;
|
|
736
|
-
return store.get(this.#recordsKey) ?? [];
|
|
737
|
-
}
|
|
738
|
-
setRecords(records) {
|
|
739
|
-
if (!shouldUseInvokeStore()) {
|
|
740
|
-
this.#fallbackRecords = records;
|
|
741
|
-
return;
|
|
742
|
-
}
|
|
743
|
-
if (globalThis.awslambda?.InvokeStore === void 0) {
|
|
744
|
-
throw new Error("InvokeStore is not available");
|
|
745
|
-
}
|
|
746
|
-
const store = globalThis.awslambda.InvokeStore;
|
|
747
|
-
store.set(this.#recordsKey, records);
|
|
748
|
-
}
|
|
749
|
-
getHandler() {
|
|
750
|
-
if (!shouldUseInvokeStore()) {
|
|
751
|
-
return this.#fallbackHandler;
|
|
752
|
-
}
|
|
753
|
-
return globalThis.awslambda?.InvokeStore?.get(this.#handlerKey) ?? (() => {
|
|
754
|
-
});
|
|
755
|
-
}
|
|
756
|
-
setHandler(handler) {
|
|
757
|
-
if (!shouldUseInvokeStore()) {
|
|
758
|
-
this.#fallbackHandler = handler;
|
|
759
|
-
return;
|
|
760
|
-
}
|
|
761
|
-
globalThis.awslambda?.InvokeStore?.set(this.#handlerKey, handler);
|
|
762
|
-
}
|
|
763
|
-
getOptions() {
|
|
764
|
-
if (!shouldUseInvokeStore()) {
|
|
765
|
-
return this.#fallbackOptions;
|
|
766
|
-
}
|
|
767
|
-
return globalThis.awslambda?.InvokeStore?.get(this.#optionsKey);
|
|
768
|
-
}
|
|
769
|
-
setOptions(options) {
|
|
770
|
-
if (!shouldUseInvokeStore()) {
|
|
771
|
-
this.#fallbackOptions = options;
|
|
772
|
-
return;
|
|
773
|
-
}
|
|
774
|
-
globalThis.awslambda?.InvokeStore?.set(this.#optionsKey, options);
|
|
775
|
-
}
|
|
776
|
-
getFailureMessages() {
|
|
777
|
-
if (!shouldUseInvokeStore()) {
|
|
778
|
-
return this.#fallbackFailureMessages;
|
|
779
|
-
}
|
|
780
|
-
return globalThis.awslambda?.InvokeStore?.get(this.#failureMessagesKey) ?? [];
|
|
781
|
-
}
|
|
782
|
-
setFailureMessages(messages) {
|
|
783
|
-
if (!shouldUseInvokeStore()) {
|
|
784
|
-
this.#fallbackFailureMessages = messages;
|
|
785
|
-
return;
|
|
786
|
-
}
|
|
787
|
-
globalThis.awslambda?.InvokeStore?.set(this.#failureMessagesKey, messages);
|
|
788
|
-
}
|
|
789
|
-
getSuccessMessages() {
|
|
790
|
-
if (!shouldUseInvokeStore()) {
|
|
791
|
-
return this.#fallbackSuccessMessages;
|
|
792
|
-
}
|
|
793
|
-
return globalThis.awslambda?.InvokeStore?.get(this.#successMessagesKey) ?? [];
|
|
794
|
-
}
|
|
795
|
-
setSuccessMessages(messages) {
|
|
796
|
-
if (!shouldUseInvokeStore()) {
|
|
797
|
-
this.#fallbackSuccessMessages = messages;
|
|
798
|
-
return;
|
|
799
|
-
}
|
|
800
|
-
globalThis.awslambda?.InvokeStore?.set(this.#successMessagesKey, messages);
|
|
801
|
-
}
|
|
802
|
-
getBatchResponse() {
|
|
803
|
-
if (!shouldUseInvokeStore()) {
|
|
804
|
-
return this.#fallbackBatchResponse;
|
|
805
|
-
}
|
|
806
|
-
return globalThis.awslambda?.InvokeStore?.get(this.#batchResponseKey) ?? { batchItemFailures: [] };
|
|
807
|
-
}
|
|
808
|
-
setBatchResponse(response) {
|
|
809
|
-
if (!shouldUseInvokeStore()) {
|
|
810
|
-
this.#fallbackBatchResponse = response;
|
|
811
|
-
return;
|
|
812
|
-
}
|
|
813
|
-
globalThis.awslambda?.InvokeStore?.set(this.#batchResponseKey, response);
|
|
814
|
-
}
|
|
815
|
-
getErrors() {
|
|
816
|
-
if (!shouldUseInvokeStore()) {
|
|
817
|
-
return this.#fallbackErrors;
|
|
818
|
-
}
|
|
819
|
-
return globalThis.awslambda?.InvokeStore?.get(this.#errorsKey) ?? [];
|
|
820
|
-
}
|
|
821
|
-
setErrors(errors) {
|
|
822
|
-
if (!shouldUseInvokeStore()) {
|
|
823
|
-
this.#fallbackErrors = errors;
|
|
824
|
-
return;
|
|
825
|
-
}
|
|
826
|
-
globalThis.awslambda?.InvokeStore?.set(this.#errorsKey, errors);
|
|
827
|
-
}
|
|
828
|
-
};
|
|
829
|
-
|
|
830
|
-
// node_modules/@aws-lambda-powertools/batch/lib/esm/BasePartialProcessor.js
|
|
831
|
-
var BasePartialProcessor = class {
|
|
832
|
-
/**
|
|
833
|
-
* Store for managing invocation-specific state
|
|
834
|
-
*/
|
|
835
|
-
#store = new BatchProcessingStore();
|
|
836
|
-
get errors() {
|
|
837
|
-
return this.#store.getErrors();
|
|
838
|
-
}
|
|
839
|
-
set errors(errors) {
|
|
840
|
-
this.#store.setErrors(errors);
|
|
841
|
-
}
|
|
842
|
-
get failureMessages() {
|
|
843
|
-
return this.#store.getFailureMessages();
|
|
844
|
-
}
|
|
845
|
-
set failureMessages(messages) {
|
|
846
|
-
this.#store.setFailureMessages(messages);
|
|
847
|
-
}
|
|
848
|
-
get handler() {
|
|
849
|
-
return this.#store.getHandler();
|
|
850
|
-
}
|
|
851
|
-
set handler(handler) {
|
|
852
|
-
this.#store.setHandler(handler);
|
|
853
|
-
}
|
|
854
|
-
get options() {
|
|
855
|
-
return this.#store.getOptions();
|
|
856
|
-
}
|
|
857
|
-
set options(options) {
|
|
858
|
-
this.#store.setOptions(options);
|
|
859
|
-
}
|
|
860
|
-
get records() {
|
|
861
|
-
return this.#store.getRecords();
|
|
862
|
-
}
|
|
863
|
-
set records(records) {
|
|
864
|
-
this.#store.setRecords(records);
|
|
865
|
-
}
|
|
866
|
-
get successMessages() {
|
|
867
|
-
return this.#store.getSuccessMessages();
|
|
868
|
-
}
|
|
869
|
-
set successMessages(messages) {
|
|
870
|
-
this.#store.setSuccessMessages(messages);
|
|
871
|
-
}
|
|
872
|
-
get batchResponse() {
|
|
873
|
-
return this.#store.getBatchResponse();
|
|
874
|
-
}
|
|
875
|
-
set batchResponse(response) {
|
|
876
|
-
this.#store.setBatchResponse(response);
|
|
877
|
-
}
|
|
878
|
-
/**
|
|
879
|
-
* Method to handle a record that failed processing
|
|
880
|
-
*
|
|
881
|
-
* This method should be called when a record fails processing so that
|
|
882
|
-
* the processor can keep track of the error and the record that failed.
|
|
883
|
-
*
|
|
884
|
-
* @param record - Record that failed processing
|
|
885
|
-
* @param error - Error that was thrown
|
|
886
|
-
*/
|
|
887
|
-
failureHandler(record, error) {
|
|
888
|
-
const entry = ["fail", error.message, record];
|
|
889
|
-
this.errors.push(error);
|
|
890
|
-
this.failureMessages.push(record);
|
|
891
|
-
return entry;
|
|
892
|
-
}
|
|
893
|
-
/**
|
|
894
|
-
* Process all records with an asynchronous handler
|
|
895
|
-
*
|
|
896
|
-
* Once called, the processor will create an array of promises to process each record
|
|
897
|
-
* and wait for all of them to settle before returning the results.
|
|
898
|
-
*
|
|
899
|
-
* Before and after processing, the processor will call the prepare and clean methods respectively.
|
|
900
|
-
*/
|
|
901
|
-
async process() {
|
|
902
|
-
this.prepare();
|
|
903
|
-
const processInParallel = this.options?.processInParallel ?? true;
|
|
904
|
-
const processedRecords = processInParallel ? await this.#processRecordsInParallel() : await this.#processRecordsSequentially();
|
|
905
|
-
this.clean();
|
|
906
|
-
return processedRecords;
|
|
907
|
-
}
|
|
908
|
-
/**
|
|
909
|
-
* Orchestrate the processing of a batch of records synchronously
|
|
910
|
-
* and sequentially.
|
|
911
|
-
*
|
|
912
|
-
* The method is responsible for calling the prepare method before
|
|
913
|
-
* processing the records and the clean method after processing the records.
|
|
914
|
-
*
|
|
915
|
-
* In the middle, the method will iterate over the records and call the
|
|
916
|
-
* processRecordSync method for each record.
|
|
917
|
-
*
|
|
918
|
-
* @returns List of processed records
|
|
919
|
-
*/
|
|
920
|
-
processSync() {
|
|
921
|
-
if (this.constructor.name === "BatchProcessor") {
|
|
922
|
-
this.processRecordSync(this.records[0]);
|
|
923
|
-
}
|
|
924
|
-
this.prepare();
|
|
925
|
-
const processedRecords = [];
|
|
926
|
-
for (const record of this.records) {
|
|
927
|
-
processedRecords.push(this.processRecordSync(record));
|
|
928
|
-
}
|
|
929
|
-
this.clean();
|
|
930
|
-
return processedRecords;
|
|
931
|
-
}
|
|
932
|
-
/**
|
|
933
|
-
* Set up the processor with the records and the handler
|
|
934
|
-
*
|
|
935
|
-
* This method should be called before processing the records to
|
|
936
|
-
* bind the records and the handler for a specific invocation to
|
|
937
|
-
* the processor.
|
|
938
|
-
*
|
|
939
|
-
* We use a separate method to do this rather than the constructor
|
|
940
|
-
* to allow for reusing the processor instance across multiple invocations
|
|
941
|
-
* by instantiating the processor outside the Lambda function handler.
|
|
942
|
-
*
|
|
943
|
-
* @param records - Array of records to be processed
|
|
944
|
-
* @param handler - CallableFunction to process each record from the batch
|
|
945
|
-
* @param options - Options to be used during processing (optional)
|
|
946
|
-
*/
|
|
947
|
-
register(records, handler, options) {
|
|
948
|
-
this.records = records;
|
|
949
|
-
this.handler = handler;
|
|
950
|
-
if (options) {
|
|
951
|
-
this.options = options;
|
|
952
|
-
}
|
|
953
|
-
return this;
|
|
954
|
-
}
|
|
955
|
-
/**
|
|
956
|
-
* Method to handle a record that succeeded processing
|
|
957
|
-
*
|
|
958
|
-
* This method should be called when a record succeeds processing so that
|
|
959
|
-
* the processor can keep track of the result and the record that succeeded.
|
|
960
|
-
*
|
|
961
|
-
* @param record - Record that succeeded processing
|
|
962
|
-
* @param result - Result from record handler
|
|
963
|
-
*/
|
|
964
|
-
successHandler(record, result) {
|
|
965
|
-
const entry = ["success", result, record];
|
|
966
|
-
this.successMessages.push(record);
|
|
967
|
-
return entry;
|
|
968
|
-
}
|
|
969
|
-
/**
|
|
970
|
-
* Processes records in parallel using `Promise.all`.
|
|
971
|
-
*/
|
|
972
|
-
#processRecordsInParallel() {
|
|
973
|
-
return Promise.all(this.records.map((record) => this.processRecord(record)));
|
|
974
|
-
}
|
|
975
|
-
/**
|
|
976
|
-
* Processes records sequentially, ensuring that each record is processed one after the other.
|
|
977
|
-
*/
|
|
978
|
-
async #processRecordsSequentially() {
|
|
979
|
-
const processedRecords = [];
|
|
980
|
-
for (const record of this.records) {
|
|
981
|
-
processedRecords.push(await this.processRecord(record));
|
|
982
|
-
}
|
|
983
|
-
return processedRecords;
|
|
984
|
-
}
|
|
985
|
-
};
|
|
986
|
-
|
|
987
|
-
// node_modules/@aws-lambda-powertools/batch/lib/esm/constants.js
|
|
988
|
-
var EventType = {
|
|
989
|
-
SQS: "SQS",
|
|
990
|
-
KinesisDataStreams: "KinesisDataStreams",
|
|
991
|
-
DynamoDBStreams: "DynamoDBStreams"
|
|
992
|
-
};
|
|
993
|
-
var DEFAULT_RESPONSE = {
|
|
994
|
-
batchItemFailures: []
|
|
995
|
-
};
|
|
996
|
-
var DATA_CLASS_MAPPING = {
|
|
997
|
-
[EventType.SQS]: (record) => record,
|
|
998
|
-
[EventType.KinesisDataStreams]: (record) => record,
|
|
999
|
-
[EventType.DynamoDBStreams]: (record) => record
|
|
1000
|
-
};
|
|
1001
|
-
|
|
1002
|
-
// node_modules/@aws-lambda-powertools/batch/lib/esm/errors.js
|
|
1003
|
-
var BatchProcessingError = class extends Error {
|
|
1004
|
-
constructor(message) {
|
|
1005
|
-
super(message);
|
|
1006
|
-
this.name = "BatchProcessingError";
|
|
1007
|
-
}
|
|
1008
|
-
};
|
|
1009
|
-
var FullBatchFailureError = class extends BatchProcessingError {
|
|
1010
|
-
recordErrors;
|
|
1011
|
-
constructor(childErrors) {
|
|
1012
|
-
super("All records failed processing. See individual errors below.");
|
|
1013
|
-
this.recordErrors = childErrors;
|
|
1014
|
-
this.name = "FullBatchFailureError";
|
|
1015
|
-
}
|
|
1016
|
-
};
|
|
1017
|
-
var UnexpectedBatchTypeError = class extends BatchProcessingError {
|
|
1018
|
-
constructor() {
|
|
1019
|
-
super(`Unexpected batch type. Possible values are: ${Object.values(EventType).join(", ")}`);
|
|
1020
|
-
this.name = "UnexpectedBatchTypeError";
|
|
1021
|
-
}
|
|
1022
|
-
};
|
|
1023
|
-
|
|
1024
|
-
// node_modules/@aws-lambda-powertools/batch/lib/esm/BasePartialBatchProcessor.js
|
|
1025
|
-
var BasePartialBatchProcessor = class extends BasePartialProcessor {
|
|
1026
|
-
/**
|
|
1027
|
-
* Mapping of event types to their respective failure collectors
|
|
1028
|
-
*
|
|
1029
|
-
* Each service expects a different format for partial failure reporting,
|
|
1030
|
-
* this mapping ensures that the correct format is used for each event type.
|
|
1031
|
-
*/
|
|
1032
|
-
COLLECTOR_MAPPING;
|
|
1033
|
-
/**
|
|
1034
|
-
* Type of event that the processor is handling
|
|
1035
|
-
*/
|
|
1036
|
-
eventType;
|
|
1037
|
-
/**
|
|
1038
|
-
* A logger instance to be used for logging debug, warning, and error messages.
|
|
1039
|
-
*
|
|
1040
|
-
* When no logger is provided, we'll only log warnings and errors using the global `console` object.
|
|
1041
|
-
*/
|
|
1042
|
-
logger;
|
|
1043
|
-
/**
|
|
1044
|
-
* The configuration options for the parser integration
|
|
1045
|
-
*/
|
|
1046
|
-
parserConfig;
|
|
1047
|
-
/**
|
|
1048
|
-
* Initializes base batch processing class
|
|
1049
|
-
*
|
|
1050
|
-
* @param eventType The type of event to process (SQS, Kinesis, DynamoDB)
|
|
1051
|
-
*/
|
|
1052
|
-
constructor(eventType, parserConfig) {
|
|
1053
|
-
super();
|
|
1054
|
-
this.eventType = eventType;
|
|
1055
|
-
this.batchResponse = DEFAULT_RESPONSE;
|
|
1056
|
-
this.COLLECTOR_MAPPING = {
|
|
1057
|
-
[EventType.SQS]: () => this.collectSqsFailures(),
|
|
1058
|
-
[EventType.KinesisDataStreams]: () => this.collectKinesisFailures(),
|
|
1059
|
-
[EventType.DynamoDBStreams]: () => this.collectDynamoDBFailures()
|
|
1060
|
-
};
|
|
1061
|
-
this.parserConfig = parserConfig;
|
|
1062
|
-
const alcLogLevel = getStringFromEnv({
|
|
1063
|
-
key: "AWS_LAMBDA_LOG_LEVEL",
|
|
1064
|
-
defaultValue: ""
|
|
1065
|
-
});
|
|
1066
|
-
this.logger = parserConfig?.logger ?? {
|
|
1067
|
-
debug: alcLogLevel === "DEBUG" ? console.debug : () => void 0,
|
|
1068
|
-
error: console.error,
|
|
1069
|
-
warn: console.warn
|
|
1070
|
-
};
|
|
1071
|
-
}
|
|
1072
|
-
/**
|
|
1073
|
-
* Clean up logic to be run after processing a batch
|
|
1074
|
-
*
|
|
1075
|
-
* If the entire batch failed this method will throw a {@link FullBatchFailureError | `FullBatchFailureError`} with the list of
|
|
1076
|
-
* errors that occurred during processing, unless the `throwOnFullBatchFailure` option is set to `false`.
|
|
1077
|
-
*
|
|
1078
|
-
* Otherwise, it will build the partial failure response based on the event type.
|
|
1079
|
-
*/
|
|
1080
|
-
clean() {
|
|
1081
|
-
if (!this.hasMessagesToReport()) {
|
|
1082
|
-
return;
|
|
1083
|
-
}
|
|
1084
|
-
if (this.options?.throwOnFullBatchFailure !== false && this.entireBatchFailed()) {
|
|
1085
|
-
throw new FullBatchFailureError(this.errors);
|
|
1086
|
-
}
|
|
1087
|
-
const messages = this.getMessagesToReport();
|
|
1088
|
-
this.batchResponse = { batchItemFailures: messages };
|
|
1089
|
-
}
|
|
1090
|
-
/**
|
|
1091
|
-
* Collect the identifiers of failed items for a DynamoDB stream
|
|
1092
|
-
*
|
|
1093
|
-
* The failures are collected based on the sequence number of the record
|
|
1094
|
-
* and formatted as a list of objects with the key `itemIdentifier` as
|
|
1095
|
-
* expected by the service.
|
|
1096
|
-
*/
|
|
1097
|
-
collectDynamoDBFailures() {
|
|
1098
|
-
const failures = [];
|
|
1099
|
-
for (const msg of this.failureMessages) {
|
|
1100
|
-
const msgId = msg.dynamodb?.SequenceNumber;
|
|
1101
|
-
if (msgId) {
|
|
1102
|
-
failures.push({ itemIdentifier: msgId });
|
|
1103
|
-
}
|
|
1104
|
-
}
|
|
1105
|
-
return failures;
|
|
1106
|
-
}
|
|
1107
|
-
/**
|
|
1108
|
-
* Collect identifiers of failed items for a Kinesis batch
|
|
1109
|
-
*
|
|
1110
|
-
* The failures are collected based on the sequence number of the record
|
|
1111
|
-
* and formatted as a list of objects with the key `itemIdentifier` as
|
|
1112
|
-
* expected by the service.
|
|
1113
|
-
*/
|
|
1114
|
-
collectKinesisFailures() {
|
|
1115
|
-
const failures = [];
|
|
1116
|
-
for (const msg of this.failureMessages) {
|
|
1117
|
-
const msgId = msg.kinesis.sequenceNumber;
|
|
1118
|
-
failures.push({ itemIdentifier: msgId });
|
|
1119
|
-
}
|
|
1120
|
-
return failures;
|
|
1121
|
-
}
|
|
1122
|
-
/**
|
|
1123
|
-
* Collect identifiers of failed items for an SQS batch
|
|
1124
|
-
*
|
|
1125
|
-
* The failures are collected based on the message ID of the record
|
|
1126
|
-
* and formatted as a list of objects with the key `itemIdentifier` as
|
|
1127
|
-
* expected by the service.
|
|
1128
|
-
*/
|
|
1129
|
-
collectSqsFailures() {
|
|
1130
|
-
const failures = [];
|
|
1131
|
-
for (const msg of this.failureMessages) {
|
|
1132
|
-
const msgId = msg.messageId;
|
|
1133
|
-
failures.push({ itemIdentifier: msgId });
|
|
1134
|
-
}
|
|
1135
|
-
return failures;
|
|
1136
|
-
}
|
|
1137
|
-
/**
|
|
1138
|
-
* Determine if the entire batch failed
|
|
1139
|
-
*
|
|
1140
|
-
* If the number of errors is equal to the number of records, then the
|
|
1141
|
-
* entire batch failed and this method will return `true`.
|
|
1142
|
-
*/
|
|
1143
|
-
entireBatchFailed() {
|
|
1144
|
-
return this.errors.length === this.records.length;
|
|
1145
|
-
}
|
|
1146
|
-
/**
|
|
1147
|
-
* Collect identifiers for failed batch items
|
|
1148
|
-
*
|
|
1149
|
-
* The method will call the appropriate collector based on the event type
|
|
1150
|
-
* and return the list of failed items.
|
|
1151
|
-
*/
|
|
1152
|
-
getMessagesToReport() {
|
|
1153
|
-
return this.COLLECTOR_MAPPING[this.eventType]();
|
|
1154
|
-
}
|
|
1155
|
-
/**
|
|
1156
|
-
* Determine if there are any failed records to report
|
|
1157
|
-
*
|
|
1158
|
-
* If there are no failed records, then the batch was successful
|
|
1159
|
-
* and this method will return `false`.
|
|
1160
|
-
*/
|
|
1161
|
-
hasMessagesToReport() {
|
|
1162
|
-
return this.failureMessages.length !== 0;
|
|
1163
|
-
}
|
|
1164
|
-
/**
|
|
1165
|
-
* Set up the processor with the initial state ready for processing
|
|
1166
|
-
*/
|
|
1167
|
-
prepare() {
|
|
1168
|
-
this.successMessages = [];
|
|
1169
|
-
this.failureMessages = [];
|
|
1170
|
-
this.errors = [];
|
|
1171
|
-
this.batchResponse = DEFAULT_RESPONSE;
|
|
1172
|
-
}
|
|
1173
|
-
/**
|
|
1174
|
-
* Get the response from the batch processing
|
|
1175
|
-
*/
|
|
1176
|
-
response() {
|
|
1177
|
-
return this.batchResponse;
|
|
1178
|
-
}
|
|
1179
|
-
/**
|
|
1180
|
-
* Forward a record to the appropriate batch type
|
|
1181
|
-
*
|
|
1182
|
-
* Based on the event type that the processor was initialized with, this method
|
|
1183
|
-
* will cast the record to the appropriate batch type handler.
|
|
1184
|
-
*
|
|
1185
|
-
* @param record The record to be processed
|
|
1186
|
-
* @param eventType The type of event to process
|
|
1187
|
-
*/
|
|
1188
|
-
toBatchType(record, eventType) {
|
|
1189
|
-
return DATA_CLASS_MAPPING[eventType](record);
|
|
1190
|
-
}
|
|
1191
|
-
};
|
|
1192
|
-
|
|
1193
|
-
// node_modules/@aws-lambda-powertools/batch/lib/esm/BatchProcessor.js
|
|
1194
|
-
var BatchProcessor = class extends BasePartialBatchProcessor {
|
|
1195
|
-
/**
|
|
1196
|
-
* Handle a record asynchronously with the instance handler provided.
|
|
1197
|
-
*
|
|
1198
|
-
* This method implements the abstract method from the parent class,
|
|
1199
|
-
* and orchestrates the processing of a single record.
|
|
1200
|
-
*
|
|
1201
|
-
* First, it converts the record to the appropriate type for the batch processor.
|
|
1202
|
-
* Then, it calls the handler function with the record data and context.
|
|
1203
|
-
*
|
|
1204
|
-
* If the handler function completes successfully, the method returns a success response.
|
|
1205
|
-
* Otherwise, it returns a failure response with the error that occurred during processing.
|
|
1206
|
-
*
|
|
1207
|
-
* @param record - The record to be processed
|
|
1208
|
-
*/
|
|
1209
|
-
async processRecord(record) {
|
|
1210
|
-
try {
|
|
1211
|
-
const recordToProcess = this.parserConfig?.parser ? await this.parserConfig.parser(record, this.eventType, this.logger, this.parserConfig) : record;
|
|
1212
|
-
const data = this.toBatchType(recordToProcess, this.eventType);
|
|
1213
|
-
const result = await this.handler(data, this.options?.context);
|
|
1214
|
-
return this.successHandler(record, result);
|
|
1215
|
-
} catch (error) {
|
|
1216
|
-
return this.failureHandler(record, error);
|
|
1217
|
-
}
|
|
1218
|
-
}
|
|
1219
|
-
/**
|
|
1220
|
-
* @throws {BatchProcessingError} This method is not implemented for synchronous processing.
|
|
1221
|
-
*
|
|
1222
|
-
* @param _record - The record to be processed
|
|
1223
|
-
*/
|
|
1224
|
-
processRecordSync(_record) {
|
|
1225
|
-
throw new BatchProcessingError("Not implemented. Use asyncProcess() instead.");
|
|
1226
|
-
}
|
|
1227
|
-
};
|
|
1228
|
-
|
|
1229
|
-
// node_modules/@aws-lambda-powertools/batch/lib/esm/processPartialResponse.js
|
|
1230
|
-
var processPartialResponse = async (event, recordHandler, processor, options) => {
|
|
1231
|
-
if (!event.Records || !Array.isArray(event.Records)) {
|
|
1232
|
-
throw new UnexpectedBatchTypeError();
|
|
1233
|
-
}
|
|
1234
|
-
processor.register(event.Records, recordHandler, options);
|
|
1235
|
-
await processor.process();
|
|
1236
|
-
return processor.response();
|
|
1237
|
-
};
|
|
1238
|
-
|
|
1239
|
-
// src/lambda/index.ts
|
|
1240
|
-
import { IdempotencyConfig } from "@aws-lambda-powertools/idempotency";
|
|
1241
|
-
import { DynamoDBPersistenceLayer } from "@aws-lambda-powertools/idempotency/dynamodb";
|
|
1242
|
-
import { Logger as Logger2 } from "@aws-lambda-powertools/logger";
|
|
1243
|
-
import { injectLambdaContext } from "@aws-lambda-powertools/logger/middleware";
|
|
1244
|
-
import { Metrics, MetricUnit } from "@aws-lambda-powertools/metrics";
|
|
1245
|
-
import { logMetrics } from "@aws-lambda-powertools/metrics/middleware";
|
|
1246
|
-
import { Tracer } from "@aws-lambda-powertools/tracer";
|
|
1247
|
-
import { captureLambdaHandler } from "@aws-lambda-powertools/tracer/middleware";
|
|
1248
|
-
|
|
1249
|
-
// node_modules/@middy/core/index.js
|
|
1250
|
-
import { Readable } from "node:stream";
|
|
1251
|
-
import { pipeline } from "node:stream/promises";
|
|
1252
|
-
import { setTimeout as setTimeout2 } from "node:timers/promises";
|
|
1253
|
-
var defaultLambdaHandler = () => {
|
|
1254
|
-
};
|
|
1255
|
-
var defaultPlugin = {
|
|
1256
|
-
timeoutEarlyInMillis: 5,
|
|
1257
|
-
timeoutEarlyResponse: () => {
|
|
1258
|
-
throw new Error("Timeout");
|
|
1259
|
-
},
|
|
1260
|
-
streamifyResponse: false
|
|
1261
|
-
// Deprecate need for this when AWS provides a flag for when it's looking for it
|
|
1262
|
-
};
|
|
1263
|
-
var middy = (lambdaHandler = defaultLambdaHandler, plugin = {}) => {
|
|
1264
|
-
if (typeof lambdaHandler !== "function") {
|
|
1265
|
-
plugin = lambdaHandler;
|
|
1266
|
-
lambdaHandler = defaultLambdaHandler;
|
|
1267
|
-
}
|
|
1268
|
-
plugin = {
|
|
1269
|
-
...defaultPlugin,
|
|
1270
|
-
...plugin
|
|
1271
|
-
};
|
|
1272
|
-
plugin.timeoutEarly = plugin.timeoutEarlyInMillis > 0;
|
|
1273
|
-
plugin.beforePrefetch?.();
|
|
1274
|
-
const beforeMiddlewares = [];
|
|
1275
|
-
const afterMiddlewares = [];
|
|
1276
|
-
const onErrorMiddlewares = [];
|
|
1277
|
-
const middyHandler = (event = {}, context = {}) => {
|
|
1278
|
-
plugin.requestStart?.();
|
|
1279
|
-
const request = {
|
|
1280
|
-
event,
|
|
1281
|
-
context,
|
|
1282
|
-
response: void 0,
|
|
1283
|
-
error: void 0,
|
|
1284
|
-
internal: plugin.internal ?? {}
|
|
1285
|
-
};
|
|
1286
|
-
return runRequest(request, [
|
|
1287
|
-
...beforeMiddlewares
|
|
1288
|
-
], lambdaHandler, [
|
|
1289
|
-
...afterMiddlewares
|
|
1290
|
-
], [
|
|
1291
|
-
...onErrorMiddlewares
|
|
1292
|
-
], plugin);
|
|
1293
|
-
};
|
|
1294
|
-
const middy2 = plugin.streamifyResponse ? awslambda.streamifyResponse(async (event, responseStream, context) => {
|
|
1295
|
-
const handlerResponse = await middyHandler(event, context);
|
|
1296
|
-
let handlerBody = handlerResponse;
|
|
1297
|
-
if (handlerResponse.statusCode) {
|
|
1298
|
-
handlerBody = handlerResponse.body ?? "";
|
|
1299
|
-
responseStream = awslambda.HttpResponseStream.from(responseStream, handlerResponse);
|
|
1300
|
-
}
|
|
1301
|
-
let handlerStream;
|
|
1302
|
-
if (handlerBody._readableState) {
|
|
1303
|
-
handlerStream = handlerBody;
|
|
1304
|
-
} else if (typeof handlerBody === "string") {
|
|
1305
|
-
function* iterator(input) {
|
|
1306
|
-
const size = 16384;
|
|
1307
|
-
let position = 0;
|
|
1308
|
-
const length = input.length;
|
|
1309
|
-
while (position < length) {
|
|
1310
|
-
yield input.substring(position, position + size);
|
|
1311
|
-
position += size;
|
|
1312
|
-
}
|
|
1313
|
-
}
|
|
1314
|
-
handlerStream = Readable.from(iterator(handlerBody));
|
|
1315
|
-
}
|
|
1316
|
-
if (!handlerStream) {
|
|
1317
|
-
throw new Error("handler response not a ReadableStream");
|
|
1318
|
-
}
|
|
1319
|
-
await pipeline(handlerStream, responseStream);
|
|
1320
|
-
}) : middyHandler;
|
|
1321
|
-
middy2.use = (middlewares) => {
|
|
1322
|
-
if (!Array.isArray(middlewares)) {
|
|
1323
|
-
middlewares = [
|
|
1324
|
-
middlewares
|
|
1325
|
-
];
|
|
1326
|
-
}
|
|
1327
|
-
for (const middleware of middlewares) {
|
|
1328
|
-
const { before, after, onError } = middleware;
|
|
1329
|
-
if (!before && !after && !onError) {
|
|
1330
|
-
throw new Error('Middleware must be an object containing at least one key among "before", "after", "onError"');
|
|
1331
|
-
}
|
|
1332
|
-
if (before)
|
|
1333
|
-
middy2.before(before);
|
|
1334
|
-
if (after)
|
|
1335
|
-
middy2.after(after);
|
|
1336
|
-
if (onError)
|
|
1337
|
-
middy2.onError(onError);
|
|
1338
|
-
}
|
|
1339
|
-
return middy2;
|
|
1340
|
-
};
|
|
1341
|
-
middy2.before = (beforeMiddleware) => {
|
|
1342
|
-
beforeMiddlewares.push(beforeMiddleware);
|
|
1343
|
-
return middy2;
|
|
1344
|
-
};
|
|
1345
|
-
middy2.after = (afterMiddleware) => {
|
|
1346
|
-
afterMiddlewares.unshift(afterMiddleware);
|
|
1347
|
-
return middy2;
|
|
1348
|
-
};
|
|
1349
|
-
middy2.onError = (onErrorMiddleware) => {
|
|
1350
|
-
onErrorMiddlewares.unshift(onErrorMiddleware);
|
|
1351
|
-
return middy2;
|
|
1352
|
-
};
|
|
1353
|
-
middy2.handler = (replaceLambdaHandler) => {
|
|
1354
|
-
lambdaHandler = replaceLambdaHandler;
|
|
1355
|
-
return middy2;
|
|
1356
|
-
};
|
|
1357
|
-
return middy2;
|
|
1358
|
-
};
|
|
1359
|
-
var runRequest = async (request, beforeMiddlewares, lambdaHandler, afterMiddlewares, onErrorMiddlewares, plugin) => {
|
|
1360
|
-
let timeoutAbort;
|
|
1361
|
-
const timeoutEarly = plugin.timeoutEarly && request.context.getRemainingTimeInMillis;
|
|
1362
|
-
try {
|
|
1363
|
-
await runMiddlewares(request, beforeMiddlewares, plugin);
|
|
1364
|
-
if (typeof request.response === "undefined") {
|
|
1365
|
-
plugin.beforeHandler?.();
|
|
1366
|
-
const handlerAbort = new AbortController();
|
|
1367
|
-
if (timeoutEarly)
|
|
1368
|
-
timeoutAbort = new AbortController();
|
|
1369
|
-
request.response = await Promise.race([
|
|
1370
|
-
lambdaHandler(request.event, request.context, {
|
|
1371
|
-
signal: handlerAbort.signal
|
|
1372
|
-
}),
|
|
1373
|
-
timeoutEarly ? setTimeout2(request.context.getRemainingTimeInMillis() - plugin.timeoutEarlyInMillis, void 0, {
|
|
1374
|
-
signal: timeoutAbort.signal
|
|
1375
|
-
}).then(() => {
|
|
1376
|
-
handlerAbort.abort();
|
|
1377
|
-
return plugin.timeoutEarlyResponse();
|
|
1378
|
-
}) : Promise.race([])
|
|
1379
|
-
]);
|
|
1380
|
-
timeoutAbort?.abort();
|
|
1381
|
-
plugin.afterHandler?.();
|
|
1382
|
-
await runMiddlewares(request, afterMiddlewares, plugin);
|
|
1383
|
-
}
|
|
1384
|
-
} catch (e) {
|
|
1385
|
-
timeoutAbort?.abort();
|
|
1386
|
-
request.response = void 0;
|
|
1387
|
-
request.error = e;
|
|
1388
|
-
try {
|
|
1389
|
-
await runMiddlewares(request, onErrorMiddlewares, plugin);
|
|
1390
|
-
} catch (e2) {
|
|
1391
|
-
e2.originalError = request.error;
|
|
1392
|
-
request.error = e2;
|
|
1393
|
-
throw request.error;
|
|
1394
|
-
}
|
|
1395
|
-
if (typeof request.response === "undefined")
|
|
1396
|
-
throw request.error;
|
|
1397
|
-
} finally {
|
|
1398
|
-
await plugin.requestEnd?.(request);
|
|
1399
|
-
}
|
|
1400
|
-
return request.response;
|
|
1401
|
-
};
|
|
1402
|
-
var runMiddlewares = async (request, middlewares, plugin) => {
|
|
1403
|
-
for (const nextMiddleware of middlewares) {
|
|
1404
|
-
plugin.beforeMiddleware?.(nextMiddleware.name);
|
|
1405
|
-
const res = await nextMiddleware(request);
|
|
1406
|
-
plugin.afterMiddleware?.(nextMiddleware.name);
|
|
1407
|
-
if (typeof res !== "undefined") {
|
|
1408
|
-
request.response = res;
|
|
1409
|
-
return;
|
|
1410
|
-
}
|
|
1411
|
-
}
|
|
1412
|
-
};
|
|
1413
|
-
var core_default = middy;
|
|
1414
|
-
|
|
1415
|
-
// node_modules/@middy/util/index.js
|
|
1416
|
-
var jsonSafeParse = (text, reviver) => {
|
|
1417
|
-
if (typeof text !== "string")
|
|
1418
|
-
return text;
|
|
1419
|
-
const firstChar = text[0];
|
|
1420
|
-
if (firstChar !== "{" && firstChar !== "[" && firstChar !== '"')
|
|
1421
|
-
return text;
|
|
1422
|
-
try {
|
|
1423
|
-
return JSON.parse(text, reviver);
|
|
1424
|
-
} catch (_e) {
|
|
1425
|
-
}
|
|
1426
|
-
return text;
|
|
1427
|
-
};
|
|
1428
|
-
var normalizeHttpResponse = (request) => {
|
|
1429
|
-
let { response } = request;
|
|
1430
|
-
if (typeof response === "undefined") {
|
|
1431
|
-
response = {};
|
|
1432
|
-
} else if (typeof response?.statusCode === "undefined" && typeof response?.body === "undefined" && typeof response?.headers === "undefined") {
|
|
1433
|
-
response = { statusCode: 200, body: response };
|
|
1434
|
-
}
|
|
1435
|
-
response.statusCode ??= 500;
|
|
1436
|
-
response.headers ??= {};
|
|
1437
|
-
request.response = response;
|
|
1438
|
-
return response;
|
|
1439
|
-
};
|
|
1440
|
-
|
|
1441
|
-
// node_modules/@middy/http-error-handler/index.js
|
|
1442
|
-
var defaults = {
|
|
1443
|
-
logger: console.error,
|
|
1444
|
-
// TODO v7 change to pass in request
|
|
1445
|
-
fallbackMessage: void 0
|
|
1446
|
-
};
|
|
1447
|
-
var httpErrorHandlerMiddleware = (opts = {}) => {
|
|
1448
|
-
const options = { ...defaults, ...opts };
|
|
1449
|
-
const httpErrorHandlerMiddlewareOnError = async (request) => {
|
|
1450
|
-
if (request.response !== void 0)
|
|
1451
|
-
return;
|
|
1452
|
-
if (typeof options.logger === "function") {
|
|
1453
|
-
options.logger(request.error);
|
|
1454
|
-
}
|
|
1455
|
-
if (request.error.statusCode && request.error.expose === void 0) {
|
|
1456
|
-
request.error.expose = request.error.statusCode < 500;
|
|
1457
|
-
}
|
|
1458
|
-
if (!request.error.expose || !request.error.statusCode) {
|
|
1459
|
-
request.error = {
|
|
1460
|
-
statusCode: 500,
|
|
1461
|
-
message: options.fallbackMessage,
|
|
1462
|
-
expose: true
|
|
1463
|
-
};
|
|
1464
|
-
}
|
|
1465
|
-
if (request.error.expose) {
|
|
1466
|
-
normalizeHttpResponse(request);
|
|
1467
|
-
const { statusCode, message, headers } = request.error;
|
|
1468
|
-
request.response = {
|
|
1469
|
-
...request.response,
|
|
1470
|
-
statusCode,
|
|
1471
|
-
headers: {
|
|
1472
|
-
...request.response.headers,
|
|
1473
|
-
...headers
|
|
1474
|
-
}
|
|
1475
|
-
};
|
|
1476
|
-
if (message) {
|
|
1477
|
-
const headerContentType = typeof jsonSafeParse(message) === "string" ? "text/plain" : "application/json";
|
|
1478
|
-
request.response.body = message;
|
|
1479
|
-
request.response.headers["Content-Type"] = headerContentType;
|
|
1480
|
-
}
|
|
1481
|
-
}
|
|
1482
|
-
};
|
|
1483
|
-
return {
|
|
1484
|
-
onError: httpErrorHandlerMiddlewareOnError
|
|
1485
|
-
};
|
|
1486
|
-
};
|
|
1487
|
-
var http_error_handler_default = httpErrorHandlerMiddleware;
|
|
1488
|
-
|
|
1489
|
-
// src/lambda/index.ts
|
|
1490
|
-
import { randomUUID } from "node:crypto";
|
|
1491
|
-
import { MetricUnit as MetricUnit2 } from "@aws-lambda-powertools/metrics";
|
|
1492
|
-
var logger = new Logger2();
|
|
1493
|
-
var tracer = new Tracer();
|
|
1494
|
-
var metrics = new Metrics({ namespace: "aspan-corporation" });
|
|
1495
|
-
var withMiddlewares = (handler) => core_default(handler).use(injectLambdaContext(logger)).use(captureLambdaHandler(tracer)).use(logMetrics(metrics, { captureColdStartMetric: true })).use({
|
|
1496
|
-
before: async (request) => {
|
|
1497
|
-
if (!logger.getCorrelationId()) {
|
|
1498
|
-
logger.setCorrelationId(request.context.awsRequestId || randomUUID());
|
|
1499
|
-
}
|
|
1500
|
-
logger.logEventIfEnabled(request.event);
|
|
1501
|
-
request.context.logger = logger;
|
|
1502
|
-
request.context.tracer = tracer;
|
|
1503
|
-
request.context.metrics = metrics;
|
|
1504
|
-
}
|
|
1505
|
-
}).use({
|
|
1506
|
-
onError: async ({ error, context: { logger: logger2, metrics: metrics2 } }) => {
|
|
1507
|
-
logger2.error("Error handled by middleware", {
|
|
1508
|
-
error
|
|
1509
|
-
});
|
|
1510
|
-
metrics2.addMetric("ErrorHandled", MetricUnit.Count, 1);
|
|
1511
|
-
}
|
|
1512
|
-
}).use(http_error_handler_default());
|
|
1513
|
-
var getPersistenceStore = (tableName) => {
|
|
1514
|
-
return new DynamoDBPersistenceLayer({
|
|
1515
|
-
tableName
|
|
1516
|
-
});
|
|
1517
|
-
};
|
|
1518
|
-
var getIdempotencyConfig = (eventKeyJmesPath) => {
|
|
1519
|
-
return new IdempotencyConfig({
|
|
1520
|
-
eventKeyJmesPath
|
|
1521
|
-
});
|
|
1522
|
-
};
|
|
1523
|
-
var getIdempotencyOptions = (tableName, path) => ({
|
|
1524
|
-
persistenceStore: getPersistenceStore(tableName),
|
|
1525
|
-
config: getIdempotencyConfig(path)
|
|
1526
|
-
});
|
|
1527
|
-
var getPartialResponseHandler = (handler) => {
|
|
1528
|
-
const processor = new BatchProcessor(EventType.SQS);
|
|
1529
|
-
return async (event, context) => processPartialResponse(event, handler, processor, {
|
|
1530
|
-
context
|
|
1531
|
-
});
|
|
1532
|
-
};
|
|
1533
|
-
export {
|
|
1534
|
-
ALLOWED_EXTENSIONS,
|
|
1535
|
-
ALLOWED_VIDEO_EXTENSIONS,
|
|
1536
|
-
CloudWatchService,
|
|
1537
|
-
DynamoDBService,
|
|
1538
|
-
ENCODED_VIDEO_EXTENSION,
|
|
1539
|
-
HEIC_EXTENSION,
|
|
1540
|
-
JPEG_EXTENSION,
|
|
1541
|
-
JPG_EXTENSION,
|
|
1542
|
-
LocationService,
|
|
1543
|
-
MOV_EXTENSION,
|
|
1544
|
-
MetricUnit2 as MetricUnit,
|
|
1545
|
-
S3Service,
|
|
1546
|
-
SQSService,
|
|
1547
|
-
SSMService,
|
|
1548
|
-
STSService,
|
|
1549
|
-
THUMBNAIL_RESOLUTIONS,
|
|
1550
|
-
THUMBS_EXTENSION,
|
|
1551
|
-
assertEnvVar,
|
|
1552
|
-
getEncodedVideoKey,
|
|
1553
|
-
getIdempotencyConfig,
|
|
1554
|
-
getIdempotencyOptions,
|
|
1555
|
-
getKeyExtension,
|
|
1556
|
-
getObjectWithAssumeRoleCommandOutputAttribute,
|
|
1557
|
-
getObjectWithStackAttribute,
|
|
1558
|
-
getPartialResponseHandler,
|
|
1559
|
-
getPersistenceStore,
|
|
1560
|
-
getThumbsKey,
|
|
1561
|
-
isAllowedExtension,
|
|
1562
|
-
isAllowedVideoExtension,
|
|
1563
|
-
logger,
|
|
1564
|
-
metrics,
|
|
1565
|
-
normalizeErrorMessage,
|
|
1566
|
-
processMeta,
|
|
1567
|
-
tracer,
|
|
1568
|
-
withMiddlewares
|
|
1569
|
-
};
|
|
1570
|
-
/*! Bundled license information:
|
|
1571
|
-
|
|
1572
|
-
@aws-lambda-powertools/batch/lib/esm/BasePartialBatchProcessor.js:
|
|
1573
|
-
(* v8 ignore else -- @preserve *)
|
|
1574
|
-
|
|
1575
|
-
@aws-lambda-powertools/batch/lib/esm/BatchProcessorSync.js:
|
|
1576
|
-
(* v8 ignore next -- @preserve *)
|
|
1577
|
-
|
|
1578
|
-
@aws-lambda-powertools/batch/lib/esm/processPartialResponseSync.js:
|
|
1579
|
-
(* v8 ignore next -- @preserve *)
|
|
1580
|
-
*/
|
|
1581
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
export * from "./services/index.js";
|
|
2
|
+
export * from "./lambda/index.js";
|
|
3
|
+
export * from "./utils/index.js";
|