@baadal-sdk/dapi 0.31.1 → 0.31.4
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/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/types/aws/db.d.ts +27 -3
- package/dist/types/aws/db.d.ts.map +1 -1
- package/dist/types/aws/s3.d.ts +4 -4
- package/dist/types/aws/s3.d.ts.map +1 -1
- package/dist/types/common/const.d.ts +1 -0
- package/dist/types/common/const.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/aws/db.ts +54 -12
- package/src/aws/s3.ts +5 -5
- package/src/common/const.ts +1 -0
package/package.json
CHANGED
package/src/aws/db.ts
CHANGED
|
@@ -33,7 +33,7 @@ import { dbClient } from './client';
|
|
|
33
33
|
import { StringIndexable } from '../common/common.model';
|
|
34
34
|
import { CustomError } from '../common/error';
|
|
35
35
|
import { warn, error } from '../common/logger';
|
|
36
|
-
import { BATCH_SIZE, CHUNK_SIZE } from '../common/const';
|
|
36
|
+
import { BATCH_SIZE, CHUNK_SIZE, MAX_RETRY_ATTEMPTS } from '../common/const';
|
|
37
37
|
|
|
38
38
|
const DynamoDBError = (msg: string) => new CustomError(msg, { name: 'DynamoDBError' });
|
|
39
39
|
|
|
@@ -70,7 +70,13 @@ const tryInit = (silent = false) => {
|
|
|
70
70
|
// auto-initialize on load
|
|
71
71
|
tryInit(true);
|
|
72
72
|
|
|
73
|
-
const writeItemForceHelper = async <T = any>(
|
|
73
|
+
const writeItemForceHelper = async <T = any>(
|
|
74
|
+
table: string,
|
|
75
|
+
item: T,
|
|
76
|
+
key: string,
|
|
77
|
+
i: number,
|
|
78
|
+
imax?: number
|
|
79
|
+
): Promise<T | null> => {
|
|
74
80
|
if (!dbClient.client) tryInit();
|
|
75
81
|
if (!dbClient.client) return null;
|
|
76
82
|
if (!table || !item) return null;
|
|
@@ -80,7 +86,7 @@ const writeItemForceHelper = async <T = any>(table: string, item: T, key: string
|
|
|
80
86
|
}
|
|
81
87
|
const cmdParams: PutCommandInput = { TableName: table, Item: item, ConditionExpression: `attribute_not_exists(${key})` };
|
|
82
88
|
const command = new PutCommand(cmdParams);
|
|
83
|
-
const numberOfAttempts =
|
|
89
|
+
const numberOfAttempts = imax ?? MAX_RETRY_ATTEMPTS;
|
|
84
90
|
|
|
85
91
|
try {
|
|
86
92
|
await dbClient.client.send(command);
|
|
@@ -88,11 +94,15 @@ const writeItemForceHelper = async <T = any>(table: string, item: T, key: string
|
|
|
88
94
|
if (err.name === 'ConditionalCheckFailedException') {
|
|
89
95
|
if (i < numberOfAttempts - 1) {
|
|
90
96
|
(item as any)[key] = short.uuid(); // new primary key
|
|
91
|
-
const ret: T | null = await writeItemForceHelper(table, item, key, i + 1);
|
|
97
|
+
const ret: T | null = await writeItemForceHelper(table, item, key, i + 1, imax);
|
|
92
98
|
return ret;
|
|
93
99
|
}
|
|
94
100
|
console.error('PutCommandInput:', cmdParams);
|
|
95
|
-
|
|
101
|
+
if (numberOfAttempts === 1) {
|
|
102
|
+
error(`[ERROR] An item with the same key(${(item as any)[key]}) already exists!`);
|
|
103
|
+
} else {
|
|
104
|
+
error('[ERROR] Maximum attempts overflow!');
|
|
105
|
+
}
|
|
96
106
|
}
|
|
97
107
|
return null;
|
|
98
108
|
}
|
|
@@ -106,6 +116,8 @@ export interface WriteItemForceInput<T = any> {
|
|
|
106
116
|
key?: string;
|
|
107
117
|
}
|
|
108
118
|
|
|
119
|
+
export type WriteItemUniqueInput<T = any> = WriteItemForceInput<T>;
|
|
120
|
+
|
|
109
121
|
/**
|
|
110
122
|
* Write an item to a DynamoDB table, retry in case of key conflict
|
|
111
123
|
* @param input input command object
|
|
@@ -130,6 +142,32 @@ export const writeItemForce = async <T = any>(input: WriteItemForceInput<T>): Pr
|
|
|
130
142
|
return writeItemForceHelper<T>(input.table, input.item, key, 0);
|
|
131
143
|
};
|
|
132
144
|
|
|
145
|
+
/**
|
|
146
|
+
* Write an item (uniquely) to a DynamoDB table.
|
|
147
|
+
* Unlike `writeItemForce`, it does not retry in case of key conflict
|
|
148
|
+
* Unlike `writeItem`, it does not overwrite an item with the same key (if it exists)
|
|
149
|
+
* @param input input command object
|
|
150
|
+
* @returns the created item, null in case of error or key conflict (i.e., if item with same key already exists)
|
|
151
|
+
*
|
|
152
|
+
* ```js
|
|
153
|
+
* writeItemUnique({
|
|
154
|
+
* table: 'lesson_list',
|
|
155
|
+
* item: { id: 'id_001', title: 'My Lesson' },
|
|
156
|
+
* key: 'id',
|
|
157
|
+
* });
|
|
158
|
+
*
|
|
159
|
+
* interface WriteItemUniqueInput<T = any> {
|
|
160
|
+
* table: string;
|
|
161
|
+
* item: T;
|
|
162
|
+
* key?: string; // default: `id`
|
|
163
|
+
* }
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
export const writeItemUnique = async <T = any>(input: WriteItemUniqueInput<T>): Promise<T | null> => {
|
|
167
|
+
const key = input.key || 'id';
|
|
168
|
+
return writeItemForceHelper<T>(input.table, input.item, key, 0, 1);
|
|
169
|
+
};
|
|
170
|
+
|
|
133
171
|
export interface WriteItemInput {
|
|
134
172
|
table: string;
|
|
135
173
|
item: StringIndexable;
|
|
@@ -177,7 +215,7 @@ const batchWriteItems = async (table: string, items: StringIndexable[]) => {
|
|
|
177
215
|
if (!dbClient.client) tryInit();
|
|
178
216
|
if (!dbClient.client) return null;
|
|
179
217
|
if (!table || !items || !Array.isArray(items)) return null;
|
|
180
|
-
if (!items.length) return
|
|
218
|
+
if (!items.length) return true;
|
|
181
219
|
|
|
182
220
|
const reqList = items.map(item => ({ PutRequest: { Item: item } }));
|
|
183
221
|
const cmdParams: BatchWriteCommandInput = {
|
|
@@ -206,7 +244,7 @@ export interface WriteItemsAllInput {
|
|
|
206
244
|
}
|
|
207
245
|
|
|
208
246
|
/**
|
|
209
|
-
* Write
|
|
247
|
+
* Write a list of items to a DynamoDB table
|
|
210
248
|
* @param input input command object
|
|
211
249
|
* @returns true if successful, null in case of error
|
|
212
250
|
*
|
|
@@ -226,7 +264,7 @@ export const writeItemsAll = async (input: WriteItemsAllInput) => {
|
|
|
226
264
|
if (!dbClient.client) tryInit();
|
|
227
265
|
if (!dbClient.client) return null;
|
|
228
266
|
if (!input.table || !input.items || !Array.isArray(input.items)) return null;
|
|
229
|
-
if (!input.items.length) return
|
|
267
|
+
if (!input.items.length) return true;
|
|
230
268
|
|
|
231
269
|
let errFlag = false;
|
|
232
270
|
|
|
@@ -308,6 +346,7 @@ export interface ReadItemInput {
|
|
|
308
346
|
key: StringIndexable;
|
|
309
347
|
projection?: string;
|
|
310
348
|
attrNames?: StringIndexable;
|
|
349
|
+
loud?: boolean;
|
|
311
350
|
}
|
|
312
351
|
|
|
313
352
|
/**
|
|
@@ -354,8 +393,11 @@ export const readItem = async <T = any>(input: ReadItemInput) => {
|
|
|
354
393
|
} catch (err) {
|
|
355
394
|
console.error('GetCommandInput:', cmdParams);
|
|
356
395
|
console.error(err);
|
|
357
|
-
|
|
358
|
-
|
|
396
|
+
if (input.loud) {
|
|
397
|
+
throw err;
|
|
398
|
+
} else {
|
|
399
|
+
return null;
|
|
400
|
+
}
|
|
359
401
|
}
|
|
360
402
|
|
|
361
403
|
return contents;
|
|
@@ -652,7 +694,7 @@ const batchDeleteItems = async (table: string, keys: StringIndexable[]) => {
|
|
|
652
694
|
if (!dbClient.client) tryInit();
|
|
653
695
|
if (!dbClient.client) return null;
|
|
654
696
|
if (!table || !keys || !Array.isArray(keys)) return null;
|
|
655
|
-
if (!keys.length) return
|
|
697
|
+
if (!keys.length) return true;
|
|
656
698
|
|
|
657
699
|
const reqList = keys.map(key => ({ DeleteRequest: { Key: key } }));
|
|
658
700
|
const cmdParams: BatchWriteCommandInput = {
|
|
@@ -701,7 +743,7 @@ export const deleteItemsAll = async (input: DeleteItemsAllInput) => {
|
|
|
701
743
|
if (!dbClient.client) tryInit();
|
|
702
744
|
if (!dbClient.client) return null;
|
|
703
745
|
if (!input.table || !input.keys || !Array.isArray(input.keys)) return null;
|
|
704
|
-
if (!input.keys.length) return
|
|
746
|
+
if (!input.keys.length) return true;
|
|
705
747
|
|
|
706
748
|
let errFlag = false;
|
|
707
749
|
|
package/src/aws/s3.ts
CHANGED
|
@@ -170,13 +170,13 @@ export const uploadFile = async (bucket: string, file: string, s3path?: string)
|
|
|
170
170
|
* @param bucket S3 bucket name
|
|
171
171
|
* @param files (local) list of file paths to upload
|
|
172
172
|
* @param s3paths [optional] S3 path to be created, if not provided then derived from `file` path
|
|
173
|
-
* @returns true if
|
|
173
|
+
* @returns true if all uploads are successful, null in case of error
|
|
174
174
|
*/
|
|
175
175
|
export const uploadFilesAll = async (bucket: string, files: string[], s3paths?: string[]) => {
|
|
176
176
|
if (!s3Client.client) tryInit();
|
|
177
177
|
if (!s3Client.client) return null;
|
|
178
178
|
if (!bucket || !files || !Array.isArray(files)) return null;
|
|
179
|
-
if (!files.length) return
|
|
179
|
+
if (!files.length) return true;
|
|
180
180
|
if (s3paths && (!Array.isArray(s3paths) || !s3paths.length || files.length !== s3paths.length)) return null;
|
|
181
181
|
|
|
182
182
|
let errFlag = false;
|
|
@@ -383,7 +383,7 @@ export const getObjectHeadsAll = async (bucket: string, s3paths: string[]) => {
|
|
|
383
383
|
contents = contents.filter(e => !!e);
|
|
384
384
|
}
|
|
385
385
|
|
|
386
|
-
return contents;
|
|
386
|
+
return contents as HeadObject[];
|
|
387
387
|
};
|
|
388
388
|
|
|
389
389
|
/**
|
|
@@ -416,7 +416,7 @@ const batchDeleteObjects = async (bucket: string, s3paths: string[]) => {
|
|
|
416
416
|
if (!s3Client.client) tryInit();
|
|
417
417
|
if (!s3Client.client) return null;
|
|
418
418
|
if (!bucket || !s3paths || !Array.isArray(s3paths)) return null;
|
|
419
|
-
if (!s3paths.length) return
|
|
419
|
+
if (!s3paths.length) return true;
|
|
420
420
|
|
|
421
421
|
const keys = s3paths.map(key => ({ Key: key }));
|
|
422
422
|
const cmdParams: DeleteObjectsCommandInput = { Bucket: bucket, Delete: { Objects: keys } };
|
|
@@ -444,7 +444,7 @@ export const deleteObjectsAll = async (bucket: string, s3paths: string[]) => {
|
|
|
444
444
|
if (!s3Client.client) tryInit();
|
|
445
445
|
if (!s3Client.client) return null;
|
|
446
446
|
if (!bucket || !s3paths || !Array.isArray(s3paths)) return null;
|
|
447
|
-
if (!s3paths.length) return
|
|
447
|
+
if (!s3paths.length) return true;
|
|
448
448
|
|
|
449
449
|
let errFlag = false;
|
|
450
450
|
|
package/src/common/const.ts
CHANGED