@baadal-sdk/dapi 0.31.3 → 0.31.5
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 +2 -1
- package/dist/cjs/index.js.LICENSE.txt +1 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/index.js.LICENSE.txt +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/types/aws/db.d.ts +23 -0
- 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 +49 -49
- package/src/aws/db.ts +43 -5
- package/src/common/const.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@baadal-sdk/dapi",
|
|
3
|
-
"version": "0.31.
|
|
3
|
+
"version": "0.31.5",
|
|
4
4
|
"description": "Dead-simple API wrappers",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -39,55 +39,9 @@
|
|
|
39
39
|
"ncu": "ncu",
|
|
40
40
|
"ncuu": "ncu -u"
|
|
41
41
|
},
|
|
42
|
-
"devDependencies": {
|
|
43
|
-
"@babel/core": "7.15.5",
|
|
44
|
-
"@babel/preset-env": "7.15.6",
|
|
45
|
-
"@babel/preset-react": "^7.14.5",
|
|
46
|
-
"@babel/preset-typescript": "7.15.0",
|
|
47
|
-
"@types/mime-types": "^2.1.1",
|
|
48
|
-
"@types/node": "16.9.6",
|
|
49
|
-
"@types/react": "^16.0.0",
|
|
50
|
-
"@types/react-dom": "^16.0.0",
|
|
51
|
-
"@types/rimraf": "3.0.2",
|
|
52
|
-
"@typescript-eslint/eslint-plugin": "4.31.2",
|
|
53
|
-
"@typescript-eslint/parser": "4.31.2",
|
|
54
|
-
"babel-loader": "8.2.2",
|
|
55
|
-
"eslint": "7.32.0",
|
|
56
|
-
"eslint-config-airbnb": "18.2.1",
|
|
57
|
-
"eslint-config-airbnb-typescript": "14.0.0",
|
|
58
|
-
"eslint-config-prettier": "8.3.0",
|
|
59
|
-
"eslint-plugin-import": "2.24.2",
|
|
60
|
-
"eslint-plugin-jsx-a11y": "6.4.1",
|
|
61
|
-
"eslint-plugin-prettier": "4.0.0",
|
|
62
|
-
"eslint-plugin-react": "7.26.0",
|
|
63
|
-
"eslint-plugin-react-hooks": "4.2.0",
|
|
64
|
-
"husky": "4.3.8",
|
|
65
|
-
"jsonlint": "1.6.3",
|
|
66
|
-
"lint-staged": "11.1.2",
|
|
67
|
-
"npm-run-all": "4.1.5",
|
|
68
|
-
"prettier": "2.4.1",
|
|
69
|
-
"shx": "0.3.3",
|
|
70
|
-
"ts-node": "10.2.1",
|
|
71
|
-
"typescript": "4.4.3",
|
|
72
|
-
"webpack": "5.53.0",
|
|
73
|
-
"webpack-cli": "4.8.0",
|
|
74
|
-
"webpack-node-externals": "3.0.0"
|
|
75
|
-
},
|
|
76
|
-
"dependencies": {
|
|
77
|
-
"@aws-sdk/client-dynamodb": "^3.34.0",
|
|
78
|
-
"@aws-sdk/client-s3": "^3.36.0",
|
|
79
|
-
"@aws-sdk/lib-dynamodb": "^3.34.0",
|
|
80
|
-
"@baadal-sdk/utils": "0.12.0",
|
|
81
|
-
"@octokit/core": "^3.5.1",
|
|
82
|
-
"chalk": "^2.4.2",
|
|
83
|
-
"core-js": "^3.18.0",
|
|
84
|
-
"mime-types": "^2.1.33",
|
|
85
|
-
"rimraf": "^3.0.2",
|
|
86
|
-
"short-uuid": "^4.2.0"
|
|
87
|
-
},
|
|
88
42
|
"peerDependencies": {
|
|
89
|
-
"react": ">=
|
|
90
|
-
"react-dom": ">=
|
|
43
|
+
"react": ">=18.2.0",
|
|
44
|
+
"react-dom": ">=18.2.0"
|
|
91
45
|
},
|
|
92
46
|
"peerDependenciesMeta": {
|
|
93
47
|
"react": {
|
|
@@ -97,6 +51,52 @@
|
|
|
97
51
|
"optional": true
|
|
98
52
|
}
|
|
99
53
|
},
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"@aws-sdk/client-dynamodb": "^3.264.0",
|
|
56
|
+
"@aws-sdk/client-s3": "^3.264.0",
|
|
57
|
+
"@aws-sdk/lib-dynamodb": "^3.264.0",
|
|
58
|
+
"@baadal-sdk/utils": "0.12.0",
|
|
59
|
+
"@octokit/core": "^4.2.0",
|
|
60
|
+
"chalk": "^5.2.0",
|
|
61
|
+
"core-js": "^3.27.2",
|
|
62
|
+
"mime-types": "^2.1.35",
|
|
63
|
+
"rimraf": "^4.1.2",
|
|
64
|
+
"short-uuid": "^4.2.2"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@babel/core": "7.20.12",
|
|
68
|
+
"@babel/preset-env": "7.20.2",
|
|
69
|
+
"@babel/preset-react": "^7.18.6",
|
|
70
|
+
"@babel/preset-typescript": "7.18.6",
|
|
71
|
+
"@types/mime-types": "2.1.1",
|
|
72
|
+
"@types/node": "18.11.19",
|
|
73
|
+
"@types/react": "18.0.27",
|
|
74
|
+
"@types/react-dom": "18.0.10",
|
|
75
|
+
"@types/rimraf": "3.0.2",
|
|
76
|
+
"@typescript-eslint/eslint-plugin": "5.50.0",
|
|
77
|
+
"@typescript-eslint/parser": "5.50.0",
|
|
78
|
+
"babel-loader": "9.1.2",
|
|
79
|
+
"eslint": "8.33.0",
|
|
80
|
+
"eslint-config-airbnb": "19.0.4",
|
|
81
|
+
"eslint-config-airbnb-typescript": "17.0.0",
|
|
82
|
+
"eslint-config-prettier": "8.6.0",
|
|
83
|
+
"eslint-plugin-import": "2.27.5",
|
|
84
|
+
"eslint-plugin-jsx-a11y": "6.7.1",
|
|
85
|
+
"eslint-plugin-prettier": "4.2.1",
|
|
86
|
+
"eslint-plugin-react": "7.32.2",
|
|
87
|
+
"eslint-plugin-react-hooks": "4.6.0",
|
|
88
|
+
"husky": "4.3.8",
|
|
89
|
+
"jsonlint": "1.6.3",
|
|
90
|
+
"lint-staged": "11.1.2",
|
|
91
|
+
"npm-run-all": "4.1.5",
|
|
92
|
+
"prettier": "2.8.3",
|
|
93
|
+
"shx": "0.3.4",
|
|
94
|
+
"ts-node": "10.9.1",
|
|
95
|
+
"typescript": "4.9.5",
|
|
96
|
+
"webpack": "5.75.0",
|
|
97
|
+
"webpack-cli": "5.0.1",
|
|
98
|
+
"webpack-node-externals": "3.0.0"
|
|
99
|
+
},
|
|
100
100
|
"browserslist": [
|
|
101
101
|
"chrome >= 23"
|
|
102
102
|
],
|
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;
|
package/src/common/const.ts
CHANGED