lemon-core 4.1.14 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/common/test-helper.d.ts +2 -2
- package/dist/common/test-helper.js +24 -26
- package/dist/common/test-helper.js.map +1 -1
- package/dist/controllers/dummy-controller.js +39 -46
- package/dist/controllers/dummy-controller.js.map +1 -1
- package/dist/controllers/general-api-controller.js +95 -100
- package/dist/controllers/general-api-controller.js.map +1 -1
- package/dist/controllers/general-controller.js +81 -82
- package/dist/controllers/general-controller.js.map +1 -1
- package/dist/cores/api/api-service.d.ts +1 -1
- package/dist/cores/api/api-service.js +228 -269
- package/dist/cores/api/api-service.js.map +1 -1
- package/dist/cores/aws/aws-kms-service.d.ts +1 -2
- package/dist/cores/aws/aws-kms-service.js +143 -153
- package/dist/cores/aws/aws-kms-service.js.map +1 -1
- package/dist/cores/aws/aws-s3-service.d.ts +2 -4
- package/dist/cores/aws/aws-s3-service.js +306 -330
- package/dist/cores/aws/aws-s3-service.js.map +1 -1
- package/dist/cores/aws/aws-sns-service.js +147 -153
- package/dist/cores/aws/aws-sns-service.js.map +1 -1
- package/dist/cores/aws/aws-sqs-service.js +149 -170
- package/dist/cores/aws/aws-sqs-service.js.map +1 -1
- package/dist/cores/aws/index.js +10 -20
- package/dist/cores/aws/index.js.map +1 -1
- package/dist/cores/cache/cache-service.d.ts +2 -2
- package/dist/cores/cache/cache-service.js +435 -499
- package/dist/cores/cache/cache-service.js.map +1 -1
- package/dist/cores/config/config-service.d.ts +1 -1
- package/dist/cores/config/config-service.js +56 -63
- package/dist/cores/config/config-service.js.map +1 -1
- package/dist/cores/config/index.js +14 -24
- package/dist/cores/config/index.js.map +1 -1
- package/dist/cores/core-services.d.ts +1 -1
- package/dist/cores/dynamo/dynamo-query-service.js +37 -51
- package/dist/cores/dynamo/dynamo-query-service.js.map +1 -1
- package/dist/cores/dynamo/dynamo-scan-service.d.ts +2 -2
- package/dist/cores/dynamo/dynamo-scan-service.js +29 -40
- package/dist/cores/dynamo/dynamo-scan-service.js.map +1 -1
- package/dist/cores/dynamo/dynamo-service.d.ts +2 -2
- package/dist/cores/dynamo/dynamo-service.js +528 -601
- package/dist/cores/dynamo/dynamo-service.js.map +1 -1
- package/dist/cores/dynamo/tools/expressions.js +17 -7
- package/dist/cores/dynamo/tools/expressions.js.map +1 -1
- package/dist/cores/dynamo/tools/query.js +142 -127
- package/dist/cores/dynamo/tools/query.js.map +1 -1
- package/dist/cores/dynamo/tools/scan.js +111 -97
- package/dist/cores/dynamo/tools/scan.js.map +1 -1
- package/dist/cores/dynamo/tools/serializer.js +17 -7
- package/dist/cores/dynamo/tools/serializer.js.map +1 -1
- package/dist/cores/dynamo/tools/utils.d.ts +0 -2
- package/dist/cores/dynamo/tools/utils.js.map +1 -1
- package/dist/cores/elastic/elastic6-query-service.js +307 -324
- package/dist/cores/elastic/elastic6-query-service.js.map +1 -1
- package/dist/cores/elastic/elastic6-service.d.ts +3 -3
- package/dist/cores/elastic/elastic6-service.js +568 -647
- package/dist/cores/elastic/elastic6-service.js.map +1 -1
- package/dist/cores/elastic/hangul-service.js +52 -54
- package/dist/cores/elastic/hangul-service.js.map +1 -1
- package/dist/cores/lambda/index.js +42 -36
- package/dist/cores/lambda/index.js.map +1 -1
- package/dist/cores/lambda/lambda-alb-handler.d.ts +2 -2
- package/dist/cores/lambda/lambda-alb-handler.js +59 -72
- package/dist/cores/lambda/lambda-alb-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-cognito-handler.js +10 -19
- package/dist/cores/lambda/lambda-cognito-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-cron-handler.d.ts +1 -1
- package/dist/cores/lambda/lambda-cron-handler.js +14 -23
- package/dist/cores/lambda/lambda-cron-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-dynamo-stream-handler.d.ts +2 -2
- package/dist/cores/lambda/lambda-dynamo-stream-handler.js +57 -67
- package/dist/cores/lambda/lambda-dynamo-stream-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-handler.d.ts +22 -22
- package/dist/cores/lambda/lambda-handler.js +93 -106
- package/dist/cores/lambda/lambda-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-notification-handler.d.ts +1 -1
- package/dist/cores/lambda/lambda-notification-handler.js +39 -50
- package/dist/cores/lambda/lambda-notification-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-sns-handler.js +79 -88
- package/dist/cores/lambda/lambda-sns-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-sqs-handler.js +79 -88
- package/dist/cores/lambda/lambda-sqs-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-web-handler.d.ts +21 -43
- package/dist/cores/lambda/lambda-web-handler.js +392 -482
- package/dist/cores/lambda/lambda-web-handler.js.map +1 -1
- package/dist/cores/lambda/lambda-wss-handler.js +23 -32
- package/dist/cores/lambda/lambda-wss-handler.js.map +1 -1
- package/dist/cores/protocol/index.js +10 -20
- package/dist/cores/protocol/index.js.map +1 -1
- package/dist/cores/protocol/protocol-service.d.ts +3 -3
- package/dist/cores/protocol/protocol-service.js +235 -227
- package/dist/cores/protocol/protocol-service.js.map +1 -1
- package/dist/cores/storage/http-storage-service.js +65 -85
- package/dist/cores/storage/http-storage-service.js.map +1 -1
- package/dist/cores/storage/model-manager.js +66 -85
- package/dist/cores/storage/model-manager.js.map +1 -1
- package/dist/cores/storage/proxy-storage-service.d.ts +2 -2
- package/dist/cores/storage/proxy-storage-service.js +562 -599
- package/dist/cores/storage/proxy-storage-service.js.map +1 -1
- package/dist/cores/storage/redis-storage-service.js +163 -177
- package/dist/cores/storage/redis-storage-service.js.map +1 -1
- package/dist/cores/storage/storage-service.js +281 -322
- package/dist/cores/storage/storage-service.js.map +1 -1
- package/dist/engine/builder.d.ts +1 -1
- package/dist/engine/builder.js +59 -63
- package/dist/engine/builder.js.map +1 -1
- package/dist/engine/engine.d.ts +4 -4
- package/dist/engine/engine.js +9 -18
- package/dist/engine/engine.js.map +1 -1
- package/dist/engine/types.d.ts +1 -1
- package/dist/engine/utilities.d.ts +14 -10
- package/dist/engine/utilities.js +301 -280
- package/dist/engine/utilities.js.map +1 -1
- package/dist/environ.js +4 -6
- package/dist/environ.js.map +1 -1
- package/dist/extended/abstract-service.js +595 -645
- package/dist/extended/abstract-service.js.map +1 -1
- package/dist/extended/libs/sig-v4.js.map +1 -1
- package/dist/generated/field-registry.d.ts +10 -0
- package/dist/generated/field-registry.js +17 -0
- package/dist/generated/field-registry.js.map +1 -0
- package/dist/helpers/helpers.d.ts +17 -9
- package/dist/helpers/helpers.js +88 -78
- package/dist/helpers/helpers.js.map +1 -1
- package/dist/index.js +17 -7
- package/dist/index.js.map +1 -1
- package/dist/lib/dynamodb-value.js +2 -3
- package/dist/lib/dynamodb-value.js.map +1 -1
- package/dist/tools/express.js +4 -5
- package/dist/tools/express.js.map +1 -1
- package/dist/tools/tools.d.ts +3 -1
- package/dist/tools/tools.js +14 -21
- package/dist/tools/tools.js.map +1 -1
- package/package.json +19 -18
- package/dist/exec-cli.d.ts +0 -2
- package/dist/exec-cli.js +0 -211
- package/dist/exec-cli.js.map +0 -1
- package/dist/lib/dynamo/expressions.d.ts +0 -14
- package/dist/lib/dynamo/expressions.js +0 -212
- package/dist/lib/dynamo/expressions.js.map +0 -1
- package/dist/lib/dynamo/query.d.ts +0 -43
- package/dist/lib/dynamo/query.js +0 -246
- package/dist/lib/dynamo/query.js.map +0 -1
- package/dist/lib/dynamo/scan.d.ts +0 -33
- package/dist/lib/dynamo/scan.js +0 -172
- package/dist/lib/dynamo/scan.js.map +0 -1
- package/dist/lib/dynamo/serializer.d.ts +0 -12
- package/dist/lib/dynamo/serializer.js +0 -243
- package/dist/lib/dynamo/serializer.js.map +0 -1
- package/dist/lib/dynamo/utils.d.ts +0 -15
- package/dist/lib/dynamo/utils.js +0 -129
- package/dist/lib/dynamo/utils.js.map +0 -1
- package/dist/tools/shared.d.ts +0 -37
- package/dist/tools/shared.js +0 -130
- package/dist/tools/shared.js.map +0 -1
|
@@ -15,33 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
var t = {};
|
|
36
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
37
|
-
t[p] = s[p];
|
|
38
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
39
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
40
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
41
|
-
t[p[i]] = s[p[i]];
|
|
42
|
-
}
|
|
43
|
-
return t;
|
|
44
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
45
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
36
|
exports.DummyDynamoService = exports.DynamoService = void 0;
|
|
47
37
|
/**
|
|
@@ -95,11 +85,8 @@ const normalize = (data) => {
|
|
|
95
85
|
* - basic CRUD service for AWS DynamoDB.
|
|
96
86
|
*/
|
|
97
87
|
class DynamoService {
|
|
88
|
+
options;
|
|
98
89
|
constructor(options) {
|
|
99
|
-
/**
|
|
100
|
-
* say hello of identity.
|
|
101
|
-
*/
|
|
102
|
-
this.hello = () => `dynamo-service:${this.options.tableName}`;
|
|
103
90
|
// eslint-disable-next-line prettier/prettier
|
|
104
91
|
(0, engine_1._inf)(NS, `DynamoService(${options.tableName}/${options.idName}${options.sortName ? '/' : ''}${options.sortName || ''})...`);
|
|
105
92
|
if (!options.tableName)
|
|
@@ -108,32 +95,43 @@ class DynamoService {
|
|
|
108
95
|
throw new Error('.idName is required');
|
|
109
96
|
this.options = options;
|
|
110
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* say hello of identity.
|
|
100
|
+
*/
|
|
101
|
+
hello = () => `dynamo-service:${this.options.tableName}`;
|
|
102
|
+
static _dynamo = {};
|
|
103
|
+
static _dynamostr = {};
|
|
104
|
+
//TODO [Steve] why to use promise here to make DynamoDBDocumentClient? @251212
|
|
105
|
+
static _dynamodoc = {};
|
|
111
106
|
/**
|
|
112
107
|
* simple instance maker.
|
|
113
108
|
* @param region (default as `ap-northeast-2`)
|
|
114
109
|
*/
|
|
115
110
|
static instance(region) {
|
|
116
|
-
var _a, _b;
|
|
117
111
|
region = `${region || 'ap-northeast-2'}`;
|
|
118
112
|
const $cfg = (0, tools_1.awsConfig)(engine_1.default, region);
|
|
119
|
-
const dynamo =
|
|
120
|
-
const dynamostr =
|
|
113
|
+
const dynamo = DynamoService._dynamo[region] ?? new client_dynamodb_2.DynamoDBClient($cfg); // Low-level DynamoDB client
|
|
114
|
+
const dynamostr = DynamoService._dynamostr[region] ?? new client_dynamodb_streams_1.DynamoDBStreamsClient($cfg); // DynamoDB Streams client
|
|
121
115
|
// Create memoized function for dynamodoc
|
|
122
116
|
if (!DynamoService._dynamodoc[region]) {
|
|
123
117
|
const cache = { client: null };
|
|
124
|
-
DynamoService._dynamodoc[region] = () =>
|
|
118
|
+
DynamoService._dynamodoc[region] = async () => {
|
|
125
119
|
if (!cache.client) {
|
|
126
120
|
(0, engine_1._log)(NS, `! creating NEW DynamoDBDocumentClient for region[${region}]`);
|
|
127
121
|
const credentials = $cfg.credentials;
|
|
128
|
-
const dynamo = new client_dynamodb_2.DynamoDBClient(
|
|
122
|
+
const dynamo = new client_dynamodb_2.DynamoDBClient({ ...$cfg, credentials });
|
|
129
123
|
cache.client = lib_dynamodb_1.DynamoDBDocumentClient.from(dynamo);
|
|
130
124
|
}
|
|
131
125
|
return cache.client;
|
|
132
|
-
}
|
|
126
|
+
};
|
|
133
127
|
}
|
|
134
128
|
const dynamodoc = DynamoService._dynamodoc[region]; // High-level Document client
|
|
135
129
|
return { dynamo, dynamostr, dynamodoc };
|
|
136
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* export to test..
|
|
133
|
+
*/
|
|
134
|
+
static normalize = normalize;
|
|
137
135
|
/**
|
|
138
136
|
* prepare `CreateTable` payload.
|
|
139
137
|
*
|
|
@@ -301,7 +299,7 @@ class DynamoService {
|
|
|
301
299
|
UpdateExpression: { SET: [], REMOVE: [], ADD: [], DELETE: [] },
|
|
302
300
|
ExpressionAttributeNames: {},
|
|
303
301
|
ExpressionAttributeValues: {},
|
|
304
|
-
ConditionExpression: null,
|
|
302
|
+
ConditionExpression: null, // "size(a) > :num "
|
|
305
303
|
ReturnValues: 'UPDATED_NEW',
|
|
306
304
|
});
|
|
307
305
|
//* prepare increment update.
|
|
@@ -342,32 +340,28 @@ class DynamoService {
|
|
|
342
340
|
* @param ReadCapacityUnits
|
|
343
341
|
* @param WriteCapacityUnits
|
|
344
342
|
*/
|
|
345
|
-
createTable(ReadCapacityUnits = 1, WriteCapacityUnits = 1) {
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
return res;
|
|
354
|
-
});
|
|
343
|
+
async createTable(ReadCapacityUnits = 1, WriteCapacityUnits = 1) {
|
|
344
|
+
(0, engine_1._log)(NS, `createTable(${ReadCapacityUnits}, ${WriteCapacityUnits})...`);
|
|
345
|
+
const payload = this.prepareCreateTable(ReadCapacityUnits, WriteCapacityUnits);
|
|
346
|
+
return instance()
|
|
347
|
+
.dynamo.send(new client_dynamodb_2.CreateTableCommand(payload))
|
|
348
|
+
.then(res => {
|
|
349
|
+
(0, engine_1._log)(NS, '> createTable.res =', res);
|
|
350
|
+
return res;
|
|
355
351
|
});
|
|
356
352
|
}
|
|
357
353
|
/**
|
|
358
354
|
* delete-table
|
|
359
355
|
*
|
|
360
356
|
*/
|
|
361
|
-
deleteTable() {
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
return res;
|
|
370
|
-
});
|
|
357
|
+
async deleteTable() {
|
|
358
|
+
(0, engine_1._log)(NS, `deleteTable()...`);
|
|
359
|
+
const payload = this.prepareDeleteTable();
|
|
360
|
+
return instance()
|
|
361
|
+
.dynamo.send(new client_dynamodb_2.DeleteTableCommand(payload))
|
|
362
|
+
.then(res => {
|
|
363
|
+
(0, engine_1._log)(NS, '> deleteTable.res =', res);
|
|
364
|
+
return res;
|
|
371
365
|
});
|
|
372
366
|
}
|
|
373
367
|
/**
|
|
@@ -377,26 +371,24 @@ class DynamoService {
|
|
|
377
371
|
* @param id
|
|
378
372
|
* @param sort
|
|
379
373
|
*/
|
|
380
|
-
readItem(id, sort) {
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
throw e;
|
|
399
|
-
});
|
|
374
|
+
async readItem(id, sort) {
|
|
375
|
+
const { tableName, idName, sortName } = this.options;
|
|
376
|
+
// _log(NS, `readItem(${id})...`);
|
|
377
|
+
const itemKey = this.prepareItemKey(id, sort);
|
|
378
|
+
// _log(NS, `> pkey[${id}${sort ? '/' : ''}${sort || ''}] =`, $U.json(itemKey));
|
|
379
|
+
const dynamodoc = await instance().dynamodoc();
|
|
380
|
+
return dynamodoc
|
|
381
|
+
.send(new lib_dynamodb_1.GetCommand(itemKey))
|
|
382
|
+
.then(res => {
|
|
383
|
+
// _log(NS, '> readItem.res =', $U.json(res));
|
|
384
|
+
if (!res.Item)
|
|
385
|
+
throw new Error(`404 NOT FOUND - ${idName}:${id}${sort ? '/' : ''}${sort || ''}`);
|
|
386
|
+
return res.Item;
|
|
387
|
+
})
|
|
388
|
+
.catch((e) => {
|
|
389
|
+
if (`${e.message}` == 'Requested resource not found')
|
|
390
|
+
throw new Error(`404 NOT FOUND - ${idName}:${id}`);
|
|
391
|
+
throw e;
|
|
400
392
|
});
|
|
401
393
|
}
|
|
402
394
|
/**
|
|
@@ -406,127 +398,120 @@ class DynamoService {
|
|
|
406
398
|
* @param list array of items with { id, sort? }
|
|
407
399
|
* @returns BatchResult with success/failed items
|
|
408
400
|
*/
|
|
409
|
-
mreadItem(list) {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
const
|
|
418
|
-
const
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
const
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
const
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
const
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
if (`${e.message}`.includes('ResourceNotFoundException'))
|
|
447
|
-
throw new Error(`404 NOT FOUND - table:${tableName}`);
|
|
448
|
-
throw e;
|
|
449
|
-
});
|
|
450
|
-
const items = ((_d = (_c = response.Responses) === null || _c === void 0 ? void 0 : _c[tableName]) !== null && _d !== void 0 ? _d : []);
|
|
451
|
-
if (items.length > 0)
|
|
452
|
-
acc.push(...items);
|
|
453
|
-
const unprocessed = ((_g = (_f = (_e = response.UnprocessedKeys) === null || _e === void 0 ? void 0 : _e[tableName]) === null || _f === void 0 ? void 0 : _f.Keys) !== null && _g !== void 0 ? _g : []);
|
|
454
|
-
if (unprocessed.length > 0) {
|
|
455
|
-
if (attempt >= MAX_RETRIES)
|
|
456
|
-
return { items: acc, unprocessed };
|
|
457
|
-
//* exponential backoff
|
|
458
|
-
yield new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 100));
|
|
459
|
-
return _doBatchGet(unprocessed, attempt + 1, acc);
|
|
460
|
-
}
|
|
461
|
-
return { items: acc, unprocessed: [] };
|
|
401
|
+
async mreadItem(list) {
|
|
402
|
+
const { tableName, idName, sortName } = this.options;
|
|
403
|
+
const total = list?.length ?? 0;
|
|
404
|
+
const result = { success: [], failed: [], total };
|
|
405
|
+
if (!list || total === 0)
|
|
406
|
+
return result;
|
|
407
|
+
const dynamodoc = await DynamoService.instance().dynamodoc();
|
|
408
|
+
const _convertKeyToSig = (key) => {
|
|
409
|
+
const id = key[idName];
|
|
410
|
+
const sort = sortName ? key[sortName] : undefined;
|
|
411
|
+
return `${id}${sortName ? '/' + sort : ''}`;
|
|
412
|
+
};
|
|
413
|
+
const _convertItemToSig = (item) => {
|
|
414
|
+
const id = item[idName];
|
|
415
|
+
const sort = sortName ? item[sortName] : undefined;
|
|
416
|
+
return `${id}${sortName ? '/' + sort : ''}`;
|
|
417
|
+
};
|
|
418
|
+
//* Maps to preserve original order
|
|
419
|
+
const successMap = new Map();
|
|
420
|
+
const failedMap = new Map();
|
|
421
|
+
for (let i = 0; i < total; i += BATCH_GET_CHUNK) {
|
|
422
|
+
const chunk = list?.slice(i, i + BATCH_GET_CHUNK) ?? [];
|
|
423
|
+
const chunkKeyMap = new Map();
|
|
424
|
+
const chunkKeys = chunk.map(item => {
|
|
425
|
+
const key = this.prepareItemKey(item.id, item.sort).Key;
|
|
426
|
+
const sig = _convertKeyToSig(key);
|
|
427
|
+
if (!chunkKeyMap.has(sig))
|
|
428
|
+
chunkKeyMap.set(sig, key);
|
|
429
|
+
return key;
|
|
430
|
+
});
|
|
431
|
+
const _doBatchGet = async (keys, attempt, acc) => {
|
|
432
|
+
const response = await dynamodoc
|
|
433
|
+
.send(new lib_dynamodb_1.BatchGetCommand({ RequestItems: { [tableName]: { Keys: keys } } }))
|
|
434
|
+
.catch((e) => {
|
|
435
|
+
if (`${e.message}`.includes('ResourceNotFoundException'))
|
|
436
|
+
throw new Error(`404 NOT FOUND - table:${tableName}`);
|
|
437
|
+
throw e;
|
|
462
438
|
});
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
unprocessed.forEach(key => {
|
|
474
|
-
const sig = _convertKeyToSig(key);
|
|
475
|
-
const failedItem = Object.assign(Object.assign({}, key), { error });
|
|
476
|
-
failedMap.set(sig, failedItem);
|
|
477
|
-
});
|
|
478
|
-
}
|
|
479
|
-
//* Identify items not found (404)
|
|
480
|
-
const received = new Set(items.map(item => _convertItemToSig(item)));
|
|
481
|
-
const unprocessedSigs = new Set(unprocessed.map(key => _convertKeyToSig(key)));
|
|
482
|
-
Array.from(chunkKeyMap.entries())
|
|
483
|
-
.filter(([sig]) => !received.has(sig) && !unprocessedSigs.has(sig))
|
|
484
|
-
.forEach(([sig, key]) => {
|
|
485
|
-
const failedItem = Object.assign(Object.assign({}, key), { error: `404 NOT FOUND - ${idName}:${key[idName]}` });
|
|
486
|
-
failedMap.set(sig, failedItem);
|
|
487
|
-
});
|
|
439
|
+
const items = (response.Responses?.[tableName] ?? []);
|
|
440
|
+
if (items.length > 0)
|
|
441
|
+
acc.push(...items);
|
|
442
|
+
const unprocessed = (response.UnprocessedKeys?.[tableName]?.Keys ?? []);
|
|
443
|
+
if (unprocessed.length > 0) {
|
|
444
|
+
if (attempt >= MAX_RETRIES)
|
|
445
|
+
return { items: acc, unprocessed };
|
|
446
|
+
//* exponential backoff
|
|
447
|
+
await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 100));
|
|
448
|
+
return _doBatchGet(unprocessed, attempt + 1, acc);
|
|
488
449
|
}
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
450
|
+
return { items: acc, unprocessed: [] };
|
|
451
|
+
};
|
|
452
|
+
try {
|
|
453
|
+
const { items, unprocessed } = await _doBatchGet(chunkKeys, 1, []);
|
|
454
|
+
items.forEach(item => {
|
|
455
|
+
const sig = _convertItemToSig(item);
|
|
456
|
+
successMap.set(sig, item);
|
|
457
|
+
});
|
|
458
|
+
//* Handle unprocessed items (failed after retries)
|
|
459
|
+
if (unprocessed.length > 0) {
|
|
460
|
+
const error = `UNPROCESSED after ${MAX_RETRIES} retries`;
|
|
461
|
+
(0, engine_1._err)(NS, `! mreadItem unprocessed:`, { count: unprocessed.length, error });
|
|
462
|
+
unprocessed.forEach(key => {
|
|
463
|
+
const sig = _convertKeyToSig(key);
|
|
464
|
+
const failedItem = { ...key, error };
|
|
494
465
|
failedMap.set(sig, failedItem);
|
|
495
466
|
});
|
|
496
467
|
}
|
|
468
|
+
//* Identify items not found (404)
|
|
469
|
+
const received = new Set(items.map(item => _convertItemToSig(item)));
|
|
470
|
+
const unprocessedSigs = new Set(unprocessed.map(key => _convertKeyToSig(key)));
|
|
471
|
+
Array.from(chunkKeyMap.entries())
|
|
472
|
+
.filter(([sig]) => !received.has(sig) && !unprocessedSigs.has(sig))
|
|
473
|
+
.forEach(([sig, key]) => {
|
|
474
|
+
const failedItem = { ...key, error: `404 NOT FOUND - ${idName}:${key[idName]}` };
|
|
475
|
+
failedMap.set(sig, failedItem);
|
|
476
|
+
});
|
|
497
477
|
}
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
if (successItem) {
|
|
505
|
-
result.success.push(successItem);
|
|
506
|
-
}
|
|
507
|
-
else if (failedItem) {
|
|
508
|
-
result.failed.push(failedItem);
|
|
509
|
-
}
|
|
510
|
-
});
|
|
511
|
-
if (result.failed.length > 0) {
|
|
512
|
-
(0, engine_1._err)(NS, `! mreadItem.failed =`, {
|
|
513
|
-
failed: result.failed.length,
|
|
514
|
-
sample_failed: result.failed.slice(0, 3).map((item) => {
|
|
515
|
-
var _a;
|
|
516
|
-
return ({
|
|
517
|
-
id: (_a = item === null || item === void 0 ? void 0 : item._id) !== null && _a !== void 0 ? _a : item === null || item === void 0 ? void 0 : item.id,
|
|
518
|
-
error: item === null || item === void 0 ? void 0 : item.error,
|
|
519
|
-
});
|
|
520
|
-
}),
|
|
478
|
+
catch (e) {
|
|
479
|
+
const error = e instanceof Error ? e.message : `${e}`;
|
|
480
|
+
(0, engine_1._err)(NS, `! mreadItem batch failed:`, error);
|
|
481
|
+
Array.from(chunkKeyMap.entries()).forEach(([sig, key]) => {
|
|
482
|
+
const failedItem = { ...key, error };
|
|
483
|
+
failedMap.set(sig, failedItem);
|
|
521
484
|
});
|
|
522
485
|
}
|
|
523
|
-
|
|
524
|
-
|
|
486
|
+
}
|
|
487
|
+
//* Preserve original order
|
|
488
|
+
list.forEach(item => {
|
|
489
|
+
const key = this.prepareItemKey(item.id, item.sort).Key;
|
|
490
|
+
const sig = _convertKeyToSig(key);
|
|
491
|
+
const successItem = successMap.get(sig);
|
|
492
|
+
const failedItem = failedMap.get(sig);
|
|
493
|
+
if (successItem) {
|
|
494
|
+
result.success.push(successItem);
|
|
495
|
+
}
|
|
496
|
+
else if (failedItem) {
|
|
497
|
+
result.failed.push(failedItem);
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
if (result.failed.length > 0) {
|
|
501
|
+
(0, engine_1._err)(NS, `! mreadItem.failed =`, {
|
|
525
502
|
failed: result.failed.length,
|
|
526
|
-
|
|
503
|
+
sample_failed: result.failed.slice(0, 3).map((item) => ({
|
|
504
|
+
id: item?._id ?? item?.id,
|
|
505
|
+
error: item?.error,
|
|
506
|
+
})),
|
|
527
507
|
});
|
|
528
|
-
|
|
508
|
+
}
|
|
509
|
+
(0, engine_1._log)(NS, `> mreadItem.res =`, {
|
|
510
|
+
success: result.success.length,
|
|
511
|
+
failed: result.failed.length,
|
|
512
|
+
total: result.total,
|
|
529
513
|
});
|
|
514
|
+
return result;
|
|
530
515
|
}
|
|
531
516
|
/**
|
|
532
517
|
* save-item
|
|
@@ -537,24 +522,22 @@ class DynamoService {
|
|
|
537
522
|
* @param id
|
|
538
523
|
* @param item
|
|
539
524
|
*/
|
|
540
|
-
saveItem(id, item) {
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
throw e;
|
|
557
|
-
});
|
|
525
|
+
async saveItem(id, item) {
|
|
526
|
+
const { tableName, idName, sortName } = this.options;
|
|
527
|
+
// _log(NS, `saveItem(${id})...`);
|
|
528
|
+
const payload = this.prepareSaveItem(id, item);
|
|
529
|
+
// _log(NS, '> payload :=', payload);
|
|
530
|
+
const dynamodoc = await DynamoService.instance().dynamodoc();
|
|
531
|
+
return dynamodoc
|
|
532
|
+
.send(new lib_dynamodb_1.PutCommand(payload))
|
|
533
|
+
.then(res => {
|
|
534
|
+
(0, engine_1._log)(NS, '> saveItem.res =', engine_1.$U.json(res));
|
|
535
|
+
return payload.Item;
|
|
536
|
+
})
|
|
537
|
+
.catch((e) => {
|
|
538
|
+
if (`${e.message}` == 'Requested resource not found')
|
|
539
|
+
throw new Error(`404 NOT FOUND - ${idName}:${id}`);
|
|
540
|
+
throw e;
|
|
558
541
|
});
|
|
559
542
|
}
|
|
560
543
|
/**
|
|
@@ -565,112 +548,104 @@ class DynamoService {
|
|
|
565
548
|
* @param list array of items with { id, sort?, ...model }
|
|
566
549
|
* @returns BatchResult with success/failed items
|
|
567
550
|
*/
|
|
568
|
-
msaveItem(list) {
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
const
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
const
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
551
|
+
async msaveItem(list) {
|
|
552
|
+
const { tableName } = this.options;
|
|
553
|
+
const total = list?.length ?? 0;
|
|
554
|
+
const result = { success: [], failed: [], total };
|
|
555
|
+
if (!list || total === 0)
|
|
556
|
+
return result;
|
|
557
|
+
const dynamodoc = await DynamoService.instance().dynamodoc();
|
|
558
|
+
for (let i = 0; i < total; i += BATCH_WRITE_CHUNK) {
|
|
559
|
+
const chunk = list?.slice(i, i + BATCH_WRITE_CHUNK) ?? [];
|
|
560
|
+
const chunkItems = [];
|
|
561
|
+
//* prepare batch write requests
|
|
562
|
+
const putRequests = chunk.map(item => {
|
|
563
|
+
const { id, ...rest } = item;
|
|
564
|
+
const payload = this.prepareSaveItem(id, rest);
|
|
565
|
+
chunkItems.push(payload.Item);
|
|
566
|
+
return {
|
|
567
|
+
PutRequest: {
|
|
568
|
+
Item: payload.Item,
|
|
569
|
+
},
|
|
570
|
+
};
|
|
571
|
+
});
|
|
572
|
+
//* execute batch write with retry for unprocessed items
|
|
573
|
+
const _doBatchWrite = async (requests, attempt) => {
|
|
574
|
+
const response = await dynamodoc
|
|
575
|
+
.send(new lib_dynamodb_1.BatchWriteCommand({ RequestItems: { [tableName]: requests } }))
|
|
576
|
+
.catch((e) => {
|
|
577
|
+
if (`${e.message}`.includes('ResourceNotFoundException'))
|
|
578
|
+
throw new Error(`404 NOT FOUND - table:${tableName}`);
|
|
579
|
+
throw e;
|
|
590
580
|
});
|
|
591
|
-
//*
|
|
592
|
-
const
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
.catch((e) => {
|
|
597
|
-
if (`${e.message}`.includes('ResourceNotFoundException'))
|
|
598
|
-
throw new Error(`404 NOT FOUND - table:${tableName}`);
|
|
599
|
-
throw e;
|
|
600
|
-
});
|
|
601
|
-
//* check for unprocessed items
|
|
602
|
-
const unprocessed = (_c = response.UnprocessedItems) === null || _c === void 0 ? void 0 : _c[tableName];
|
|
603
|
-
if (unprocessed && (unprocessed === null || unprocessed === void 0 ? void 0 : unprocessed.length) > 0) {
|
|
604
|
-
if (attempt >= MAX_RETRIES) {
|
|
605
|
-
return unprocessed;
|
|
606
|
-
}
|
|
607
|
-
//* exponential backoff
|
|
608
|
-
yield new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 100));
|
|
609
|
-
return _doBatchWrite(unprocessed, attempt + 1);
|
|
581
|
+
//* check for unprocessed items
|
|
582
|
+
const unprocessed = response.UnprocessedItems?.[tableName];
|
|
583
|
+
if (unprocessed && unprocessed?.length > 0) {
|
|
584
|
+
if (attempt >= MAX_RETRIES) {
|
|
585
|
+
return unprocessed;
|
|
610
586
|
}
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
587
|
+
//* exponential backoff
|
|
588
|
+
await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 100));
|
|
589
|
+
return _doBatchWrite(unprocessed, attempt + 1);
|
|
590
|
+
}
|
|
591
|
+
return [];
|
|
592
|
+
};
|
|
593
|
+
try {
|
|
594
|
+
const unprocessed = await _doBatchWrite(putRequests, 1);
|
|
595
|
+
//* Handle unprocessed items (failed after retries)
|
|
596
|
+
const unprocessedIds = new Set();
|
|
597
|
+
if (unprocessed?.length > 0) {
|
|
598
|
+
const error = `UNPROCESSED after ${MAX_RETRIES} retries`;
|
|
599
|
+
(0, engine_1._err)(NS, `! msaveItem unprocessed:`, { count: unprocessed.length, error });
|
|
600
|
+
unprocessed.forEach(req => {
|
|
601
|
+
const item = req.PutRequest?.Item;
|
|
602
|
+
if (item) {
|
|
603
|
+
const itemId = String(item[this.options.idName] || item.id);
|
|
604
|
+
unprocessedIds.add(itemId);
|
|
605
|
+
const chunkItem = chunkItems.find(ci => {
|
|
606
|
+
const chunkItemId = String(ci[this.options.idName] || ci.id);
|
|
607
|
+
return chunkItemId === itemId;
|
|
608
|
+
});
|
|
609
|
+
if (chunkItem) {
|
|
610
|
+
const failedItem = { ...chunkItem, error };
|
|
611
|
+
result.failed.push(failedItem);
|
|
634
612
|
}
|
|
635
|
-
});
|
|
636
|
-
}
|
|
637
|
-
//* Add successfully written items
|
|
638
|
-
chunkItems.forEach(item => {
|
|
639
|
-
const itemId = String(item[this.options.idName] || item.id);
|
|
640
|
-
if (!unprocessedIds.has(itemId)) {
|
|
641
|
-
result.success.push(item);
|
|
642
613
|
}
|
|
643
614
|
});
|
|
644
615
|
}
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
const
|
|
648
|
-
(
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
});
|
|
653
|
-
}
|
|
616
|
+
//* Add successfully written items
|
|
617
|
+
chunkItems.forEach(item => {
|
|
618
|
+
const itemId = String(item[this.options.idName] || item.id);
|
|
619
|
+
if (!unprocessedIds.has(itemId)) {
|
|
620
|
+
result.success.push(item);
|
|
621
|
+
}
|
|
622
|
+
});
|
|
654
623
|
}
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
error: item === null || item === void 0 ? void 0 : item.error,
|
|
663
|
-
});
|
|
664
|
-
}),
|
|
624
|
+
catch (e) {
|
|
625
|
+
//* Handle complete batch failure
|
|
626
|
+
const error = e instanceof Error ? e.message : `${e}`;
|
|
627
|
+
(0, engine_1._err)(NS, `! msaveItem batch failed:`, error);
|
|
628
|
+
chunkItems.forEach(item => {
|
|
629
|
+
const failedItem = { ...item, error };
|
|
630
|
+
result.failed.push(failedItem);
|
|
665
631
|
});
|
|
666
632
|
}
|
|
667
|
-
|
|
668
|
-
|
|
633
|
+
}
|
|
634
|
+
if (result.failed.length > 0) {
|
|
635
|
+
(0, engine_1._err)(NS, `! msaveItem.failed =`, {
|
|
669
636
|
failed: result.failed.length,
|
|
670
|
-
|
|
637
|
+
sample_failed: result.failed.slice(0, 3).map((item) => ({
|
|
638
|
+
id: item?._id ?? item?.id,
|
|
639
|
+
error: item?.error,
|
|
640
|
+
})),
|
|
671
641
|
});
|
|
672
|
-
|
|
642
|
+
}
|
|
643
|
+
(0, engine_1._log)(NS, `> msaveItem.res =`, {
|
|
644
|
+
success: result.success.length,
|
|
645
|
+
failed: result.failed.length,
|
|
646
|
+
total: result.total,
|
|
673
647
|
});
|
|
648
|
+
return result;
|
|
674
649
|
}
|
|
675
650
|
/**
|
|
676
651
|
* delete-item
|
|
@@ -679,22 +654,20 @@ class DynamoService {
|
|
|
679
654
|
* @param id
|
|
680
655
|
* @param sort
|
|
681
656
|
*/
|
|
682
|
-
deleteItem(id, sort) {
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
throw e;
|
|
697
|
-
});
|
|
657
|
+
async deleteItem(id, sort) {
|
|
658
|
+
// _log(NS, `deleteItem(${id})...`);
|
|
659
|
+
const payload = this.prepareItemKey(id, sort);
|
|
660
|
+
const dynamodoc = await DynamoService.instance().dynamodoc();
|
|
661
|
+
return dynamodoc
|
|
662
|
+
.send(new lib_dynamodb_1.DeleteCommand(payload))
|
|
663
|
+
.then(res => {
|
|
664
|
+
(0, engine_1._log)(NS, '> deleteItem.res =', engine_1.$U.json(res));
|
|
665
|
+
return null;
|
|
666
|
+
})
|
|
667
|
+
.catch((e) => {
|
|
668
|
+
if (`${e.message}` == 'Requested resource not found')
|
|
669
|
+
return {};
|
|
670
|
+
throw e;
|
|
698
671
|
});
|
|
699
672
|
}
|
|
700
673
|
/**
|
|
@@ -706,25 +679,23 @@ class DynamoService {
|
|
|
706
679
|
* @param updates
|
|
707
680
|
* @param increments
|
|
708
681
|
*/
|
|
709
|
-
updateItem(id, sort, updates, increments) {
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
throw e;
|
|
727
|
-
});
|
|
682
|
+
async updateItem(id, sort, updates, increments) {
|
|
683
|
+
const { idName } = this.options;
|
|
684
|
+
// _log(NS, `updateItem(${id})...`);
|
|
685
|
+
const payload = this.prepareUpdateItem(id, sort, updates, increments);
|
|
686
|
+
const dynamodoc = await DynamoService.instance().dynamodoc();
|
|
687
|
+
return dynamodoc
|
|
688
|
+
.send(new lib_dynamodb_1.UpdateCommand(payload))
|
|
689
|
+
.then(res => {
|
|
690
|
+
(0, engine_1._log)(NS, `> updateItem[${id}].res =`, engine_1.$U.json(res));
|
|
691
|
+
const attr = res.Attributes;
|
|
692
|
+
const $key = Object.assign({}, payload.Key);
|
|
693
|
+
return Object.assign(attr, $key);
|
|
694
|
+
})
|
|
695
|
+
.catch((e) => {
|
|
696
|
+
if (`${e.message}` == 'Requested resource not found')
|
|
697
|
+
throw new Error(`404 NOT FOUND - ${idName}:${id}`);
|
|
698
|
+
throw e;
|
|
728
699
|
});
|
|
729
700
|
}
|
|
730
701
|
/**
|
|
@@ -735,139 +706,123 @@ class DynamoService {
|
|
|
735
706
|
* @param list array of items with { id, sort?, ...model }
|
|
736
707
|
* @returns BatchResult with success/failed items
|
|
737
708
|
*/
|
|
738
|
-
mupdateItem(list) {
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
const
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
709
|
+
async mupdateItem(list) {
|
|
710
|
+
const { tableName, idName } = this.options;
|
|
711
|
+
const total = list?.length ?? 0;
|
|
712
|
+
const result = { success: [], failed: [], total };
|
|
713
|
+
if (!list || total === 0)
|
|
714
|
+
return result;
|
|
715
|
+
const dynamodoc = await DynamoService.instance().dynamodoc();
|
|
716
|
+
//* Maps to preserve original order
|
|
717
|
+
const successMap = new Map();
|
|
718
|
+
const failedMap = new Map();
|
|
719
|
+
for (let i = 0; i < total; i += BATCH_WRITE_CHUNK) {
|
|
720
|
+
const chunk = list?.slice(i, i + BATCH_WRITE_CHUNK) ?? [];
|
|
721
|
+
const chunkItemMap = new Map();
|
|
722
|
+
//* prepare batch write requests
|
|
723
|
+
const putRequests = chunk.map(item => {
|
|
724
|
+
const { id, ...rest } = item;
|
|
725
|
+
//* Use partition key field if available, otherwise use id
|
|
726
|
+
const actualId = rest[this.options.idName] || id;
|
|
727
|
+
const payload = this.prepareSaveItem(actualId, rest);
|
|
728
|
+
chunkItemMap.set(id, payload.Item);
|
|
729
|
+
return {
|
|
730
|
+
PutRequest: {
|
|
731
|
+
Item: payload.Item,
|
|
732
|
+
},
|
|
733
|
+
};
|
|
734
|
+
});
|
|
735
|
+
//* execute batch write with retry for unprocessed items
|
|
736
|
+
const _doBatchWrite = async (requests, attempt) => {
|
|
737
|
+
const response = await dynamodoc
|
|
738
|
+
.send(new lib_dynamodb_1.BatchWriteCommand({ RequestItems: { [tableName]: requests } }))
|
|
739
|
+
.catch((e) => {
|
|
740
|
+
if (`${e.message}`.includes('ResourceNotFoundException'))
|
|
741
|
+
throw new Error(`404 NOT FOUND - table:${tableName}`);
|
|
742
|
+
throw e;
|
|
765
743
|
});
|
|
766
|
-
//*
|
|
767
|
-
const
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
.catch((e) => {
|
|
772
|
-
if (`${e.message}`.includes('ResourceNotFoundException'))
|
|
773
|
-
throw new Error(`404 NOT FOUND - table:${tableName}`);
|
|
774
|
-
throw e;
|
|
775
|
-
});
|
|
776
|
-
//* check for unprocessed items
|
|
777
|
-
const unprocessed = (_c = response.UnprocessedItems) === null || _c === void 0 ? void 0 : _c[tableName];
|
|
778
|
-
if (unprocessed && (unprocessed === null || unprocessed === void 0 ? void 0 : unprocessed.length) > 0) {
|
|
779
|
-
if (attempt >= MAX_RETRIES) {
|
|
780
|
-
return unprocessed;
|
|
781
|
-
}
|
|
782
|
-
//* exponential backoff
|
|
783
|
-
yield new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 100));
|
|
784
|
-
return _doBatchWrite(unprocessed, attempt + 1);
|
|
744
|
+
//* check for unprocessed items
|
|
745
|
+
const unprocessed = response.UnprocessedItems?.[tableName];
|
|
746
|
+
if (unprocessed && unprocessed?.length > 0) {
|
|
747
|
+
if (attempt >= MAX_RETRIES) {
|
|
748
|
+
return unprocessed;
|
|
785
749
|
}
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
}
|
|
750
|
+
//* exponential backoff
|
|
751
|
+
await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 100));
|
|
752
|
+
return _doBatchWrite(unprocessed, attempt + 1);
|
|
753
|
+
}
|
|
754
|
+
return [];
|
|
755
|
+
};
|
|
756
|
+
try {
|
|
757
|
+
const unprocessed = await _doBatchWrite(putRequests, 1);
|
|
758
|
+
//* Handle unprocessed items (failed after retries)
|
|
759
|
+
const unprocessedIds = new Set();
|
|
760
|
+
if (unprocessed?.length > 0) {
|
|
761
|
+
const error = `UNPROCESSED after ${MAX_RETRIES} retries`;
|
|
762
|
+
(0, engine_1._err)(NS, `! mupdateItem unprocessed:`, { count: unprocessed.length, error });
|
|
763
|
+
unprocessed.forEach(req => {
|
|
764
|
+
const item = req.PutRequest?.Item;
|
|
765
|
+
if (item) {
|
|
766
|
+
const itemId = String(item[this.options.idName] || item.id);
|
|
767
|
+
for (const [id, chunkItem] of chunkItemMap.entries()) {
|
|
768
|
+
const chunkItemId = String(chunkItem[this.options.idName] || chunkItem.id);
|
|
769
|
+
if (chunkItemId === itemId) {
|
|
770
|
+
unprocessedIds.add(id);
|
|
771
|
+
const failedItem = { ...chunkItem, error };
|
|
772
|
+
failedMap.set(id, failedItem);
|
|
773
|
+
break;
|
|
808
774
|
}
|
|
809
775
|
}
|
|
810
|
-
});
|
|
811
|
-
}
|
|
812
|
-
//* Add successfully written items
|
|
813
|
-
chunkItemMap.forEach((item, id) => {
|
|
814
|
-
if (!unprocessedIds.has(id)) {
|
|
815
|
-
successMap.set(id, item);
|
|
816
776
|
}
|
|
817
777
|
});
|
|
818
778
|
}
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
failedMap.set(id, failedItem);
|
|
826
|
-
});
|
|
827
|
-
}
|
|
779
|
+
//* Add successfully written items
|
|
780
|
+
chunkItemMap.forEach((item, id) => {
|
|
781
|
+
if (!unprocessedIds.has(id)) {
|
|
782
|
+
successMap.set(id, item);
|
|
783
|
+
}
|
|
784
|
+
});
|
|
828
785
|
}
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
const
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
}
|
|
837
|
-
else if (failedItem) {
|
|
838
|
-
result.failed.push(failedItem);
|
|
839
|
-
}
|
|
840
|
-
});
|
|
841
|
-
if (result.failed.length > 0) {
|
|
842
|
-
(0, engine_1._err)(NS, `! mupdateItem.failed =`, {
|
|
843
|
-
failed: result.failed.length,
|
|
844
|
-
sample_failed: result.failed.slice(0, 3).map((item) => {
|
|
845
|
-
var _a;
|
|
846
|
-
return ({
|
|
847
|
-
id: (_a = item === null || item === void 0 ? void 0 : item._id) !== null && _a !== void 0 ? _a : item === null || item === void 0 ? void 0 : item.id,
|
|
848
|
-
error: item === null || item === void 0 ? void 0 : item.error,
|
|
849
|
-
});
|
|
850
|
-
}),
|
|
786
|
+
catch (e) {
|
|
787
|
+
//* Handle complete batch failure
|
|
788
|
+
const error = e instanceof Error ? e.message : `${e}`;
|
|
789
|
+
(0, engine_1._err)(NS, `! mupdateItem batch failed:`, error);
|
|
790
|
+
chunkItemMap.forEach((item, id) => {
|
|
791
|
+
const failedItem = { ...item, error };
|
|
792
|
+
failedMap.set(id, failedItem);
|
|
851
793
|
});
|
|
852
794
|
}
|
|
853
|
-
|
|
854
|
-
|
|
795
|
+
}
|
|
796
|
+
//* Preserve original order
|
|
797
|
+
list.forEach(item => {
|
|
798
|
+
const id = item.id;
|
|
799
|
+
const successItem = successMap.get(id);
|
|
800
|
+
const failedItem = failedMap.get(id);
|
|
801
|
+
if (successItem) {
|
|
802
|
+
result.success.push(successItem);
|
|
803
|
+
}
|
|
804
|
+
else if (failedItem) {
|
|
805
|
+
result.failed.push(failedItem);
|
|
806
|
+
}
|
|
807
|
+
});
|
|
808
|
+
if (result.failed.length > 0) {
|
|
809
|
+
(0, engine_1._err)(NS, `! mupdateItem.failed =`, {
|
|
855
810
|
failed: result.failed.length,
|
|
856
|
-
|
|
811
|
+
sample_failed: result.failed.slice(0, 3).map((item) => ({
|
|
812
|
+
id: item?._id ?? item?.id,
|
|
813
|
+
error: item?.error,
|
|
814
|
+
})),
|
|
857
815
|
});
|
|
858
|
-
|
|
816
|
+
}
|
|
817
|
+
(0, engine_1._log)(NS, `> mupdateItem.res =`, {
|
|
818
|
+
success: result.success.length,
|
|
819
|
+
failed: result.failed.length,
|
|
820
|
+
total: result.total,
|
|
859
821
|
});
|
|
822
|
+
return result;
|
|
860
823
|
}
|
|
861
824
|
}
|
|
862
825
|
exports.DynamoService = DynamoService;
|
|
863
|
-
DynamoService._dynamo = {};
|
|
864
|
-
DynamoService._dynamostr = {};
|
|
865
|
-
//TODO [Steve] why to use promise here to make DynamoDBDocumentClient? @251212
|
|
866
|
-
DynamoService._dynamodoc = {};
|
|
867
|
-
/**
|
|
868
|
-
* export to test..
|
|
869
|
-
*/
|
|
870
|
-
DynamoService.normalize = normalize;
|
|
871
826
|
/** ****************************************************************************************************************
|
|
872
827
|
* Dummy Dynamo Service
|
|
873
828
|
** ****************************************************************************************************************/
|
|
@@ -878,17 +833,13 @@ DynamoService.normalize = normalize;
|
|
|
878
833
|
class DummyDynamoService extends DynamoService {
|
|
879
834
|
constructor(dataFile, options) {
|
|
880
835
|
super(options);
|
|
881
|
-
this.buffer = {};
|
|
882
|
-
/**
|
|
883
|
-
* say hello()
|
|
884
|
-
*/
|
|
885
|
-
this.hello = () => `dummy-dynamo-service:${this.options.tableName}`;
|
|
886
836
|
(0, engine_1._log)(NS, `DummyDynamoService(${dataFile || ''})...`);
|
|
887
837
|
if (!dataFile)
|
|
888
838
|
throw new Error('@dataFile(string) is required!');
|
|
889
839
|
const dummy = (0, tools_1.loadDataYml)(dataFile);
|
|
890
840
|
this.load(dummy.data);
|
|
891
841
|
}
|
|
842
|
+
buffer = {};
|
|
892
843
|
load(data) {
|
|
893
844
|
const { idName } = this.options;
|
|
894
845
|
if (!data || !Array.isArray(data))
|
|
@@ -898,6 +849,10 @@ class DummyDynamoService extends DynamoService {
|
|
|
898
849
|
this.buffer[id] = item;
|
|
899
850
|
});
|
|
900
851
|
}
|
|
852
|
+
/**
|
|
853
|
+
* say hello()
|
|
854
|
+
*/
|
|
855
|
+
hello = () => `dummy-dynamo-service:${this.options.tableName}`;
|
|
901
856
|
/**
|
|
902
857
|
* ONLY FOR DUMMY
|
|
903
858
|
* - send list of data.
|
|
@@ -905,171 +860,143 @@ class DummyDynamoService extends DynamoService {
|
|
|
905
860
|
* @param page page number starts from 1
|
|
906
861
|
* @param limit limit of count.
|
|
907
862
|
*/
|
|
908
|
-
listItems(page, limit) {
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
return { page, limit, total, list };
|
|
916
|
-
});
|
|
863
|
+
async listItems(page, limit) {
|
|
864
|
+
page = engine_1.$U.N(page, 1);
|
|
865
|
+
limit = engine_1.$U.N(limit, 2);
|
|
866
|
+
const keys = Object.keys(this.buffer);
|
|
867
|
+
const total = keys.length;
|
|
868
|
+
const list = keys.slice((page - 1) * limit, page * limit).map(_ => this.buffer[_]);
|
|
869
|
+
return { page, limit, total, list };
|
|
917
870
|
}
|
|
918
|
-
readItem(id, sort) {
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
return Object.assign({ [idName]: id }, item);
|
|
925
|
-
});
|
|
871
|
+
async readItem(id, sort) {
|
|
872
|
+
const { idName } = this.options;
|
|
873
|
+
const item = this.buffer[id];
|
|
874
|
+
if (item === undefined)
|
|
875
|
+
throw new Error(`404 NOT FOUND - ${idName}:${id}`);
|
|
876
|
+
return { [idName]: id, ...item };
|
|
926
877
|
}
|
|
927
|
-
mreadItem(list) {
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
const
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
result.failed.push(failedItem);
|
|
942
|
-
continue;
|
|
943
|
-
}
|
|
944
|
-
result.success.push(Object.assign({ [idName]: item.id }, data));
|
|
945
|
-
}
|
|
946
|
-
if (result.failed.length > 0) {
|
|
947
|
-
(0, engine_1._err)(NS, `! mreadItem.failed =`, {
|
|
948
|
-
failed: result.failed.length,
|
|
949
|
-
sample_failed: result.failed.slice(0, 3).map((item) => {
|
|
950
|
-
var _a, _b;
|
|
951
|
-
return ({
|
|
952
|
-
id: (_b = (_a = item === null || item === void 0 ? void 0 : item._id) !== null && _a !== void 0 ? _a : item === null || item === void 0 ? void 0 : item.id) !== null && _b !== void 0 ? _b : item === null || item === void 0 ? void 0 : item[idName],
|
|
953
|
-
error: item === null || item === void 0 ? void 0 : item.error,
|
|
954
|
-
});
|
|
955
|
-
}),
|
|
956
|
-
});
|
|
878
|
+
async mreadItem(list) {
|
|
879
|
+
const { idName, sortName } = this.options;
|
|
880
|
+
const total = list?.length ?? 0;
|
|
881
|
+
const result = { success: [], failed: [], total };
|
|
882
|
+
if (!list || total === 0)
|
|
883
|
+
return result;
|
|
884
|
+
for (const item of list) {
|
|
885
|
+
const data = this.buffer[item.id];
|
|
886
|
+
if (data === undefined) {
|
|
887
|
+
const failedItem = (sortName
|
|
888
|
+
? { [idName]: item.id, [sortName]: item.sort, error: '404 NOT FOUND' }
|
|
889
|
+
: { [idName]: item.id, error: '404 NOT FOUND' });
|
|
890
|
+
result.failed.push(failedItem);
|
|
891
|
+
continue;
|
|
957
892
|
}
|
|
958
|
-
|
|
959
|
-
|
|
893
|
+
result.success.push({ [idName]: item.id, ...data });
|
|
894
|
+
}
|
|
895
|
+
if (result.failed.length > 0) {
|
|
896
|
+
(0, engine_1._err)(NS, `! mreadItem.failed =`, {
|
|
960
897
|
failed: result.failed.length,
|
|
961
|
-
|
|
898
|
+
sample_failed: result.failed.slice(0, 3).map((item) => ({
|
|
899
|
+
id: item?._id ?? item?.id ?? item?.[idName],
|
|
900
|
+
error: item?.error,
|
|
901
|
+
})),
|
|
962
902
|
});
|
|
963
|
-
|
|
903
|
+
}
|
|
904
|
+
(0, engine_1._log)(NS, `> mreadItem.res =`, {
|
|
905
|
+
success: result.success.length,
|
|
906
|
+
failed: result.failed.length,
|
|
907
|
+
total: result.total,
|
|
964
908
|
});
|
|
909
|
+
return result;
|
|
965
910
|
}
|
|
966
|
-
saveItem(id, item) {
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
return Object.assign({ [idName]: id }, this.buffer[id]);
|
|
971
|
-
});
|
|
911
|
+
async saveItem(id, item) {
|
|
912
|
+
const { idName } = this.options;
|
|
913
|
+
this.buffer[id] = normalize(item);
|
|
914
|
+
return { [idName]: id, ...this.buffer[id] };
|
|
972
915
|
}
|
|
973
|
-
msaveItem(list) {
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
this.buffer[id] = normalize(rest);
|
|
986
|
-
result.success.push(Object.assign({ [idName]: id }, this.buffer[id]));
|
|
987
|
-
}
|
|
988
|
-
catch (e) {
|
|
989
|
-
const error = e instanceof Error ? e.message : `${e}`;
|
|
990
|
-
(0, engine_1._err)(NS, `! msaveItem failed for id=${item === null || item === void 0 ? void 0 : item.id}:`, error);
|
|
991
|
-
const failedItem = Object.assign(Object.assign({}, item), { error });
|
|
992
|
-
result.failed.push(failedItem);
|
|
993
|
-
}
|
|
916
|
+
async msaveItem(list) {
|
|
917
|
+
const { idName } = this.options;
|
|
918
|
+
const total = list?.length ?? 0;
|
|
919
|
+
const result = { success: [], failed: [], total };
|
|
920
|
+
if (!list || total === 0)
|
|
921
|
+
return result;
|
|
922
|
+
//* process all saves using the in-memory buffer (overwrites entire items)
|
|
923
|
+
for (const item of list) {
|
|
924
|
+
try {
|
|
925
|
+
const { id, ...rest } = item;
|
|
926
|
+
this.buffer[id] = normalize(rest);
|
|
927
|
+
result.success.push({ [idName]: id, ...this.buffer[id] });
|
|
994
928
|
}
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
return ({
|
|
1001
|
-
id: (_b = (_a = item === null || item === void 0 ? void 0 : item._id) !== null && _a !== void 0 ? _a : item === null || item === void 0 ? void 0 : item.id) !== null && _b !== void 0 ? _b : item === null || item === void 0 ? void 0 : item[idName],
|
|
1002
|
-
error: item === null || item === void 0 ? void 0 : item.error,
|
|
1003
|
-
});
|
|
1004
|
-
}),
|
|
1005
|
-
});
|
|
929
|
+
catch (e) {
|
|
930
|
+
const error = e instanceof Error ? e.message : `${e}`;
|
|
931
|
+
(0, engine_1._err)(NS, `! msaveItem failed for id=${item?.id}:`, error);
|
|
932
|
+
const failedItem = { ...item, error };
|
|
933
|
+
result.failed.push(failedItem);
|
|
1006
934
|
}
|
|
1007
|
-
|
|
1008
|
-
|
|
935
|
+
}
|
|
936
|
+
if (result.failed.length > 0) {
|
|
937
|
+
(0, engine_1._err)(NS, `! msaveItem.failed =`, {
|
|
1009
938
|
failed: result.failed.length,
|
|
1010
|
-
|
|
939
|
+
sample_failed: result.failed.slice(0, 3).map((item) => ({
|
|
940
|
+
id: item?._id ?? item?.id ?? item?.[idName],
|
|
941
|
+
error: item?.error,
|
|
942
|
+
})),
|
|
1011
943
|
});
|
|
1012
|
-
|
|
944
|
+
}
|
|
945
|
+
(0, engine_1._log)(NS, `> msaveItem.res =`, {
|
|
946
|
+
success: result.success.length,
|
|
947
|
+
failed: result.failed.length,
|
|
948
|
+
total: result.total,
|
|
1013
949
|
});
|
|
950
|
+
return result;
|
|
1014
951
|
}
|
|
1015
|
-
deleteItem(id, sort) {
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
return null;
|
|
1019
|
-
});
|
|
952
|
+
async deleteItem(id, sort) {
|
|
953
|
+
delete this.buffer[id];
|
|
954
|
+
return null;
|
|
1020
955
|
}
|
|
1021
|
-
updateItem(id, sort, updates, increments) {
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
return Object.assign({ [idName]: id }, this.buffer[id]);
|
|
1029
|
-
});
|
|
956
|
+
async updateItem(id, sort, updates, increments) {
|
|
957
|
+
const { idName } = this.options;
|
|
958
|
+
const item = this.buffer[id];
|
|
959
|
+
if (item === undefined)
|
|
960
|
+
throw new Error(`404 NOT FOUND - ${idName}:${id}`);
|
|
961
|
+
this.buffer[id] = { ...item, ...normalize(updates) };
|
|
962
|
+
return { [idName]: id, ...this.buffer[id] };
|
|
1030
963
|
}
|
|
1031
|
-
mupdateItem(list) {
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
this.buffer[id] = normalize(rest);
|
|
1045
|
-
result.success.push(Object.assign({ [idName]: id }, this.buffer[id]));
|
|
1046
|
-
}
|
|
1047
|
-
catch (e) {
|
|
1048
|
-
const error = e instanceof Error ? e.message : `${e}`;
|
|
1049
|
-
(0, engine_1._err)(NS, `! mupdateItem failed for id=${item === null || item === void 0 ? void 0 : item.id}:`, error);
|
|
1050
|
-
const failedItem = { [idName]: item.id, error };
|
|
1051
|
-
result.failed.push(failedItem);
|
|
1052
|
-
}
|
|
964
|
+
async mupdateItem(list) {
|
|
965
|
+
const { idName } = this.options;
|
|
966
|
+
const total = list?.length ?? 0;
|
|
967
|
+
const result = { success: [], failed: [], total };
|
|
968
|
+
if (!list || total === 0)
|
|
969
|
+
return result;
|
|
970
|
+
//* process all updates using the in-memory buffer (overwrites entire items)
|
|
971
|
+
for (const item of list) {
|
|
972
|
+
try {
|
|
973
|
+
const { id, ...rest } = item;
|
|
974
|
+
//* overwrite entire item (same as PutItem behavior)
|
|
975
|
+
this.buffer[id] = normalize(rest);
|
|
976
|
+
result.success.push({ [idName]: id, ...this.buffer[id] });
|
|
1053
977
|
}
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
return ({
|
|
1060
|
-
id: (_b = (_a = item === null || item === void 0 ? void 0 : item._id) !== null && _a !== void 0 ? _a : item === null || item === void 0 ? void 0 : item.id) !== null && _b !== void 0 ? _b : item === null || item === void 0 ? void 0 : item[idName],
|
|
1061
|
-
error: item === null || item === void 0 ? void 0 : item.error,
|
|
1062
|
-
});
|
|
1063
|
-
}),
|
|
1064
|
-
});
|
|
978
|
+
catch (e) {
|
|
979
|
+
const error = e instanceof Error ? e.message : `${e}`;
|
|
980
|
+
(0, engine_1._err)(NS, `! mupdateItem failed for id=${item?.id}:`, error);
|
|
981
|
+
const failedItem = { [idName]: item.id, error };
|
|
982
|
+
result.failed.push(failedItem);
|
|
1065
983
|
}
|
|
1066
|
-
|
|
1067
|
-
|
|
984
|
+
}
|
|
985
|
+
if (result.failed.length > 0) {
|
|
986
|
+
(0, engine_1._err)(NS, `! mupdateItem.failed =`, {
|
|
1068
987
|
failed: result.failed.length,
|
|
1069
|
-
|
|
988
|
+
sample_failed: result.failed.slice(0, 3).map((item) => ({
|
|
989
|
+
id: item?._id ?? item?.id ?? item?.[idName],
|
|
990
|
+
error: item?.error,
|
|
991
|
+
})),
|
|
1070
992
|
});
|
|
1071
|
-
|
|
993
|
+
}
|
|
994
|
+
(0, engine_1._log)(NS, `> mupdateItem.res =`, {
|
|
995
|
+
success: result.success.length,
|
|
996
|
+
failed: result.failed.length,
|
|
997
|
+
total: result.total,
|
|
1072
998
|
});
|
|
999
|
+
return result;
|
|
1073
1000
|
}
|
|
1074
1001
|
}
|
|
1075
1002
|
exports.DummyDynamoService = DummyDynamoService;
|