@ftschopp/dynatable-core 1.0.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/CHANGELOG.md +62 -0
- package/README.md +17 -0
- package/dist/builders/batch-get/create-batch-get-builder.d.ts +18 -0
- package/dist/builders/batch-get/create-batch-get-builder.d.ts.map +1 -0
- package/dist/builders/batch-get/create-batch-get-builder.js +71 -0
- package/dist/builders/batch-get/index.d.ts +3 -0
- package/dist/builders/batch-get/index.d.ts.map +1 -0
- package/dist/builders/batch-get/index.js +18 -0
- package/dist/builders/batch-get/types.d.ts +25 -0
- package/dist/builders/batch-get/types.d.ts.map +1 -0
- package/dist/builders/batch-get/types.js +2 -0
- package/dist/builders/batch-write/create-batch-write-builder.d.ts +12 -0
- package/dist/builders/batch-write/create-batch-write-builder.d.ts.map +1 -0
- package/dist/builders/batch-write/create-batch-write-builder.js +35 -0
- package/dist/builders/batch-write/index.d.ts +3 -0
- package/dist/builders/batch-write/index.d.ts.map +1 -0
- package/dist/builders/batch-write/index.js +18 -0
- package/dist/builders/batch-write/types.d.ts +30 -0
- package/dist/builders/batch-write/types.d.ts.map +1 -0
- package/dist/builders/batch-write/types.js +2 -0
- package/dist/builders/delete/create-delete-builder.d.ts +9 -0
- package/dist/builders/delete/create-delete-builder.d.ts.map +1 -0
- package/dist/builders/delete/create-delete-builder.js +72 -0
- package/dist/builders/delete/index.d.ts +3 -0
- package/dist/builders/delete/index.d.ts.map +1 -0
- package/dist/builders/delete/index.js +18 -0
- package/dist/builders/delete/types.d.ts +11 -0
- package/dist/builders/delete/types.d.ts.map +1 -0
- package/dist/builders/delete/types.js +2 -0
- package/dist/builders/get/create-get-builder.d.ts +12 -0
- package/dist/builders/get/create-get-builder.d.ts.map +1 -0
- package/dist/builders/get/create-get-builder.js +95 -0
- package/dist/builders/get/index.d.ts +3 -0
- package/dist/builders/get/index.d.ts.map +1 -0
- package/dist/builders/get/index.js +18 -0
- package/dist/builders/get/types.d.ts +28 -0
- package/dist/builders/get/types.d.ts.map +1 -0
- package/dist/builders/get/types.js +2 -0
- package/dist/builders/index.d.ts +12 -0
- package/dist/builders/index.d.ts.map +1 -0
- package/dist/builders/index.js +29 -0
- package/dist/builders/put/create-put-builder.d.ts +9 -0
- package/dist/builders/put/create-put-builder.d.ts.map +1 -0
- package/dist/builders/put/create-put-builder.js +104 -0
- package/dist/builders/put/index.d.ts +3 -0
- package/dist/builders/put/index.d.ts.map +1 -0
- package/dist/builders/put/index.js +18 -0
- package/dist/builders/put/types.d.ts +17 -0
- package/dist/builders/put/types.d.ts.map +1 -0
- package/dist/builders/put/types.js +2 -0
- package/dist/builders/query/create-query-builder.d.ts +9 -0
- package/dist/builders/query/create-query-builder.d.ts.map +1 -0
- package/dist/builders/query/create-query-builder.js +283 -0
- package/dist/builders/query/index.d.ts +3 -0
- package/dist/builders/query/index.d.ts.map +1 -0
- package/dist/builders/query/index.js +18 -0
- package/dist/builders/query/types.d.ts +79 -0
- package/dist/builders/query/types.d.ts.map +1 -0
- package/dist/builders/query/types.js +2 -0
- package/dist/builders/scan/create-scan-builder.d.ts +12 -0
- package/dist/builders/scan/create-scan-builder.d.ts.map +1 -0
- package/dist/builders/scan/create-scan-builder.js +103 -0
- package/dist/builders/scan/index.d.ts +3 -0
- package/dist/builders/scan/index.d.ts.map +1 -0
- package/dist/builders/scan/index.js +18 -0
- package/dist/builders/scan/types.d.ts +43 -0
- package/dist/builders/scan/types.d.ts.map +1 -0
- package/dist/builders/scan/types.js +2 -0
- package/dist/builders/shared/conditions.d.ts +18 -0
- package/dist/builders/shared/conditions.d.ts.map +1 -0
- package/dist/builders/shared/conditions.js +48 -0
- package/dist/builders/shared/index.d.ts +4 -0
- package/dist/builders/shared/index.d.ts.map +1 -0
- package/dist/builders/shared/index.js +19 -0
- package/dist/builders/shared/operators.d.ts +12 -0
- package/dist/builders/shared/operators.d.ts.map +1 -0
- package/dist/builders/shared/operators.js +197 -0
- package/dist/builders/shared/types.d.ts +77 -0
- package/dist/builders/shared/types.d.ts.map +1 -0
- package/dist/builders/shared/types.js +6 -0
- package/dist/builders/transact-get/create-transact-get-builder.d.ts +18 -0
- package/dist/builders/transact-get/create-transact-get-builder.d.ts.map +1 -0
- package/dist/builders/transact-get/create-transact-get-builder.js +60 -0
- package/dist/builders/transact-get/index.d.ts +3 -0
- package/dist/builders/transact-get/index.d.ts.map +1 -0
- package/dist/builders/transact-get/index.js +18 -0
- package/dist/builders/transact-get/types.d.ts +28 -0
- package/dist/builders/transact-get/types.d.ts.map +1 -0
- package/dist/builders/transact-get/types.js +2 -0
- package/dist/builders/transact-write/create-transact-write-builder.d.ts +18 -0
- package/dist/builders/transact-write/create-transact-write-builder.d.ts.map +1 -0
- package/dist/builders/transact-write/create-transact-write-builder.js +97 -0
- package/dist/builders/transact-write/index.d.ts +3 -0
- package/dist/builders/transact-write/index.d.ts.map +1 -0
- package/dist/builders/transact-write/index.js +18 -0
- package/dist/builders/transact-write/types.d.ts +34 -0
- package/dist/builders/transact-write/types.d.ts.map +1 -0
- package/dist/builders/transact-write/types.js +2 -0
- package/dist/builders/update/create-update-builder.d.ts +14 -0
- package/dist/builders/update/create-update-builder.d.ts.map +1 -0
- package/dist/builders/update/create-update-builder.js +180 -0
- package/dist/builders/update/index.d.ts +3 -0
- package/dist/builders/update/index.d.ts.map +1 -0
- package/dist/builders/update/index.js +18 -0
- package/dist/builders/update/types.d.ts +35 -0
- package/dist/builders/update/types.d.ts.map +1 -0
- package/dist/builders/update/types.js +2 -0
- package/dist/core/types.d.ts +224 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +3 -0
- package/dist/entity.d.ts +73 -0
- package/dist/entity.d.ts.map +1 -0
- package/dist/entity.js +161 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/table.d.ts +70 -0
- package/dist/table.d.ts.map +1 -0
- package/dist/table.js +69 -0
- package/dist/utils/dynamodb-logger.d.ts +118 -0
- package/dist/utils/dynamodb-logger.d.ts.map +1 -0
- package/dist/utils/dynamodb-logger.js +125 -0
- package/dist/utils/model-utils.d.ts +24 -0
- package/dist/utils/model-utils.d.ts.map +1 -0
- package/dist/utils/model-utils.js +88 -0
- package/dist/utils/zod-utils.d.ts +13 -0
- package/dist/utils/zod-utils.d.ts.map +1 -0
- package/dist/utils/zod-utils.js +35 -0
- package/eslint.config.mjs +4 -0
- package/jest.config.js +11 -0
- package/package.json +36 -0
- package/src/builders/README.md +272 -0
- package/src/builders/batch-get/README.md +98 -0
- package/src/builders/batch-get/create-batch-get-builder.test.ts +165 -0
- package/src/builders/batch-get/create-batch-get-builder.ts +106 -0
- package/src/builders/batch-get/index.ts +2 -0
- package/src/builders/batch-get/types.ts +29 -0
- package/src/builders/batch-write/README.md +204 -0
- package/src/builders/batch-write/create-batch-write-builder.test.ts +173 -0
- package/src/builders/batch-write/create-batch-write-builder.ts +49 -0
- package/src/builders/batch-write/index.ts +2 -0
- package/src/builders/batch-write/types.ts +33 -0
- package/src/builders/delete/create-delete-builder.test.ts +294 -0
- package/src/builders/delete/create-delete-builder.ts +100 -0
- package/src/builders/delete/index.ts +2 -0
- package/src/builders/delete/types.ts +11 -0
- package/src/builders/get/create-get-builder.test.ts +272 -0
- package/src/builders/get/create-get-builder.ts +140 -0
- package/src/builders/get/index.ts +2 -0
- package/src/builders/get/types.ts +30 -0
- package/src/builders/index.ts +14 -0
- package/src/builders/put/create-put-builder.test.ts +213 -0
- package/src/builders/put/create-put-builder.ts +151 -0
- package/src/builders/put/index.ts +2 -0
- package/src/builders/put/types.ts +18 -0
- package/src/builders/query/create-query-builder.test.ts +230 -0
- package/src/builders/query/create-query-builder.ts +353 -0
- package/src/builders/query/index.ts +2 -0
- package/src/builders/query/types.ts +95 -0
- package/src/builders/scan/create-scan-builder.test.ts +260 -0
- package/src/builders/scan/create-scan-builder.ts +217 -0
- package/src/builders/scan/index.ts +2 -0
- package/src/builders/scan/types.ts +49 -0
- package/src/builders/shared/conditions.ts +58 -0
- package/src/builders/shared/index.ts +3 -0
- package/src/builders/shared/operators.test.ts +270 -0
- package/src/builders/shared/operators.ts +200 -0
- package/src/builders/shared/types.ts +100 -0
- package/src/builders/transact-get/README.md +167 -0
- package/src/builders/transact-get/create-transact-get-builder.test.ts +239 -0
- package/src/builders/transact-get/create-transact-get-builder.ts +67 -0
- package/src/builders/transact-get/index.ts +2 -0
- package/src/builders/transact-get/types.ts +31 -0
- package/src/builders/transact-write/README.md +166 -0
- package/src/builders/transact-write/create-transact-write-builder.test.ts +288 -0
- package/src/builders/transact-write/create-transact-write-builder.ts +118 -0
- package/src/builders/transact-write/index.ts +2 -0
- package/src/builders/transact-write/types.ts +33 -0
- package/src/builders/update/create-update-builder.test.ts +333 -0
- package/src/builders/update/create-update-builder.ts +284 -0
- package/src/builders/update/index.ts +2 -0
- package/src/builders/update/types.ts +42 -0
- package/src/core/types.test.ts +506 -0
- package/src/core/types.ts +290 -0
- package/src/entity.ts +337 -0
- package/src/index.ts +22 -0
- package/src/table.ts +109 -0
- package/src/utils/dynamodb-logger.test.ts +246 -0
- package/src/utils/dynamodb-logger.ts +175 -0
- package/src/utils/model-utils.test.ts +232 -0
- package/src/utils/model-utils.ts +101 -0
- package/src/utils/zod-utils.test.ts +272 -0
- package/src/utils/zod-utils.ts +36 -0
- package/tests/integration/instagram-clone.integration.test.ts +966 -0
- package/tests/integration/pagination-timestamps.integration.test.ts +375 -0
- package/tests/integration/transactions.integration.test.ts +529 -0
- package/tsconfig.json +12 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# BatchWrite Builder
|
|
2
|
+
|
|
3
|
+
The `BatchWriteBuilder` allows writing (put) or deleting (delete) multiple items from one or more tables in a single request to DynamoDB.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Create multiple items (PutRequest)
|
|
8
|
+
- Delete multiple items (DeleteRequest)
|
|
9
|
+
- Mix Put and Delete operations in a single request
|
|
10
|
+
- Supports multiple tables in a single request
|
|
11
|
+
- Handles unprocessed items (UnprocessedItems)
|
|
12
|
+
|
|
13
|
+
## Basic Usage - Create Items
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { createBatchWriteBuilder } from './builders/batch-write';
|
|
17
|
+
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
|
|
18
|
+
|
|
19
|
+
const client = new DynamoDBClient({});
|
|
20
|
+
|
|
21
|
+
// Create multiple users
|
|
22
|
+
const result = await createBatchWriteBuilder(
|
|
23
|
+
{
|
|
24
|
+
Users: [
|
|
25
|
+
{
|
|
26
|
+
PutRequest: {
|
|
27
|
+
Item: {
|
|
28
|
+
pk: 'USER#alice',
|
|
29
|
+
sk: 'USER#alice',
|
|
30
|
+
username: 'alice',
|
|
31
|
+
name: 'Alice Smith',
|
|
32
|
+
followerCount: 0,
|
|
33
|
+
followingCount: 0,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
PutRequest: {
|
|
39
|
+
Item: {
|
|
40
|
+
pk: 'USER#bob',
|
|
41
|
+
sk: 'USER#bob',
|
|
42
|
+
username: 'bob',
|
|
43
|
+
name: 'Bob Jones',
|
|
44
|
+
followerCount: 0,
|
|
45
|
+
followingCount: 0,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
client
|
|
52
|
+
).execute();
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Delete Items
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
const result = await createBatchWriteBuilder(
|
|
59
|
+
{
|
|
60
|
+
Users: [
|
|
61
|
+
{
|
|
62
|
+
DeleteRequest: {
|
|
63
|
+
Key: {
|
|
64
|
+
pk: 'USER#alice',
|
|
65
|
+
sk: 'USER#alice',
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
DeleteRequest: {
|
|
71
|
+
Key: {
|
|
72
|
+
pk: 'USER#bob',
|
|
73
|
+
sk: 'USER#bob',
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
client
|
|
80
|
+
).execute();
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Mix Put and Delete
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
const result = await createBatchWriteBuilder(
|
|
87
|
+
{
|
|
88
|
+
Users: [
|
|
89
|
+
{
|
|
90
|
+
PutRequest: {
|
|
91
|
+
Item: {
|
|
92
|
+
pk: 'USER#alice',
|
|
93
|
+
sk: 'USER#alice',
|
|
94
|
+
username: 'alice',
|
|
95
|
+
name: 'Alice Smith Updated',
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
DeleteRequest: {
|
|
101
|
+
Key: {
|
|
102
|
+
pk: 'USER#bob',
|
|
103
|
+
sk: 'USER#bob',
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
client
|
|
110
|
+
).execute();
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Using the Table Class
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
// Create multiple items using the Table class
|
|
117
|
+
const result = await table
|
|
118
|
+
.batchWrite({
|
|
119
|
+
InstagramClone: [
|
|
120
|
+
{
|
|
121
|
+
PutRequest: {
|
|
122
|
+
Item: {
|
|
123
|
+
pk: 'USER#alice',
|
|
124
|
+
sk: 'USER#alice',
|
|
125
|
+
username: 'alice',
|
|
126
|
+
name: 'Alice Smith',
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
DeleteRequest: {
|
|
132
|
+
Key: {
|
|
133
|
+
pk: 'USER#bob',
|
|
134
|
+
sk: 'USER#bob',
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
})
|
|
140
|
+
.execute();
|
|
141
|
+
|
|
142
|
+
// Handle unprocessed items
|
|
143
|
+
if (result.unprocessedItems) {
|
|
144
|
+
console.log('Unprocessed items:', result.unprocessedItems);
|
|
145
|
+
// Retry unprocessed items
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Bulk Operations
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
// Create multiple photos and likes in a single request
|
|
153
|
+
await table
|
|
154
|
+
.batchWrite({
|
|
155
|
+
InstagramClone: [
|
|
156
|
+
{
|
|
157
|
+
PutRequest: {
|
|
158
|
+
Item: {
|
|
159
|
+
pk: 'UP#alice',
|
|
160
|
+
sk: 'PHOTO#photo1',
|
|
161
|
+
username: 'alice',
|
|
162
|
+
photoId: 'photo1',
|
|
163
|
+
url: 'https://example.com/photo1.jpg',
|
|
164
|
+
likesCount: 0,
|
|
165
|
+
commentCount: 0,
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
PutRequest: {
|
|
171
|
+
Item: {
|
|
172
|
+
pk: 'UP#alice',
|
|
173
|
+
sk: 'PHOTO#photo2',
|
|
174
|
+
username: 'alice',
|
|
175
|
+
photoId: 'photo2',
|
|
176
|
+
url: 'https://example.com/photo2.jpg',
|
|
177
|
+
likesCount: 0,
|
|
178
|
+
commentCount: 0,
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
PutRequest: {
|
|
184
|
+
Item: {
|
|
185
|
+
pk: 'PL#photo1',
|
|
186
|
+
sk: 'LIKE#bob',
|
|
187
|
+
photoId: 'photo1',
|
|
188
|
+
likingUsername: 'bob',
|
|
189
|
+
likeId: 'like123',
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
})
|
|
195
|
+
.execute();
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## DynamoDB Limitations
|
|
199
|
+
|
|
200
|
+
- Maximum 25 items per request
|
|
201
|
+
- Maximum 16 MB of data per request
|
|
202
|
+
- Does not support conditions (ConditionExpression)
|
|
203
|
+
- Unprocessed items are returned in `UnprocessedItems` and must be retried
|
|
204
|
+
- Put operations completely overwrite the existing item
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
|
|
3
|
+
import { createBatchWriteBuilder } from './create-batch-write-builder';
|
|
4
|
+
|
|
5
|
+
describe('BatchWriteBuilder', () => {
|
|
6
|
+
const client = new DynamoDBClient({});
|
|
7
|
+
|
|
8
|
+
describe('dbParams', () => {
|
|
9
|
+
test('should build basic BatchWriteItem params with PutRequests', () => {
|
|
10
|
+
const requestItems = {
|
|
11
|
+
Users: [
|
|
12
|
+
{
|
|
13
|
+
PutRequest: {
|
|
14
|
+
Item: {
|
|
15
|
+
pk: 'USER#alice',
|
|
16
|
+
sk: 'USER#alice',
|
|
17
|
+
username: 'alice',
|
|
18
|
+
name: 'Alice Smith',
|
|
19
|
+
followerCount: 0,
|
|
20
|
+
followingCount: 0,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
PutRequest: {
|
|
26
|
+
Item: {
|
|
27
|
+
pk: 'USER#bob',
|
|
28
|
+
sk: 'USER#bob',
|
|
29
|
+
username: 'bob',
|
|
30
|
+
name: 'Bob Jones',
|
|
31
|
+
followerCount: 0,
|
|
32
|
+
followingCount: 0,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const builder = createBatchWriteBuilder(requestItems, client);
|
|
40
|
+
const params = builder.dbParams();
|
|
41
|
+
|
|
42
|
+
expect(params).toEqual({
|
|
43
|
+
RequestItems: requestItems,
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('should build BatchWriteItem params with DeleteRequests', () => {
|
|
48
|
+
const requestItems = {
|
|
49
|
+
Users: [
|
|
50
|
+
{
|
|
51
|
+
DeleteRequest: {
|
|
52
|
+
Key: {
|
|
53
|
+
pk: 'USER#alice',
|
|
54
|
+
sk: 'USER#alice',
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
DeleteRequest: {
|
|
60
|
+
Key: {
|
|
61
|
+
pk: 'USER#bob',
|
|
62
|
+
sk: 'USER#bob',
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const builder = createBatchWriteBuilder(requestItems, client);
|
|
70
|
+
const params = builder.dbParams();
|
|
71
|
+
|
|
72
|
+
expect(params).toEqual({
|
|
73
|
+
RequestItems: requestItems,
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test('should build BatchWriteItem params with mixed Put and Delete requests', () => {
|
|
78
|
+
const requestItems = {
|
|
79
|
+
Users: [
|
|
80
|
+
{
|
|
81
|
+
PutRequest: {
|
|
82
|
+
Item: {
|
|
83
|
+
pk: 'USER#alice',
|
|
84
|
+
sk: 'USER#alice',
|
|
85
|
+
username: 'alice',
|
|
86
|
+
name: 'Alice Smith',
|
|
87
|
+
followerCount: 0,
|
|
88
|
+
followingCount: 0,
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
DeleteRequest: {
|
|
94
|
+
Key: {
|
|
95
|
+
pk: 'USER#bob',
|
|
96
|
+
sk: 'USER#bob',
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const builder = createBatchWriteBuilder(requestItems, client);
|
|
104
|
+
const params = builder.dbParams();
|
|
105
|
+
|
|
106
|
+
expect(params).toEqual({
|
|
107
|
+
RequestItems: requestItems,
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test('should build BatchWriteItem params with multiple tables', () => {
|
|
112
|
+
const requestItems = {
|
|
113
|
+
Users: [
|
|
114
|
+
{
|
|
115
|
+
PutRequest: {
|
|
116
|
+
Item: {
|
|
117
|
+
pk: 'USER#alice',
|
|
118
|
+
sk: 'USER#alice',
|
|
119
|
+
username: 'alice',
|
|
120
|
+
name: 'Alice Smith',
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
Photos: [
|
|
126
|
+
{
|
|
127
|
+
PutRequest: {
|
|
128
|
+
Item: {
|
|
129
|
+
pk: 'UP#alice',
|
|
130
|
+
sk: 'PHOTO#photo1',
|
|
131
|
+
username: 'alice',
|
|
132
|
+
photoId: 'photo1',
|
|
133
|
+
url: 'https://example.com/photo1.jpg',
|
|
134
|
+
likesCount: 0,
|
|
135
|
+
commentCount: 0,
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
DeleteRequest: {
|
|
141
|
+
Key: {
|
|
142
|
+
pk: 'UP#alice',
|
|
143
|
+
sk: 'PHOTO#photo2',
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const builder = createBatchWriteBuilder(requestItems, client);
|
|
151
|
+
const params = builder.dbParams();
|
|
152
|
+
|
|
153
|
+
expect(params).toEqual({
|
|
154
|
+
RequestItems: requestItems,
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
test('should handle empty request items', () => {
|
|
159
|
+
const requestItems = {
|
|
160
|
+
Users: [],
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
const builder = createBatchWriteBuilder(requestItems, client);
|
|
164
|
+
const params = builder.dbParams();
|
|
165
|
+
|
|
166
|
+
expect(params).toEqual({
|
|
167
|
+
RequestItems: {
|
|
168
|
+
Users: [],
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
|
|
3
|
+
import {
|
|
4
|
+
BatchWriteCommand,
|
|
5
|
+
BatchWriteCommandInput,
|
|
6
|
+
BatchWriteCommandOutput,
|
|
7
|
+
} from '@aws-sdk/lib-dynamodb';
|
|
8
|
+
import { BatchWriteBuilder, WriteRequest } from './types';
|
|
9
|
+
import { DynamoDBLogger } from '../../utils/dynamodb-logger';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Creates a BatchWriteBuilder to put or delete multiple items.
|
|
13
|
+
*
|
|
14
|
+
* @param requestItems - An object where keys are table names and values are arrays of WriteRequest
|
|
15
|
+
* @param client - DynamoDB client instance
|
|
16
|
+
* @param logger - Optional logger instance
|
|
17
|
+
*/
|
|
18
|
+
export function createBatchWriteBuilder(
|
|
19
|
+
requestItems: Record<string, WriteRequest[]>,
|
|
20
|
+
client: DynamoDBClient,
|
|
21
|
+
logger?: DynamoDBLogger
|
|
22
|
+
): BatchWriteBuilder {
|
|
23
|
+
return {
|
|
24
|
+
/**
|
|
25
|
+
* Build the underlying DynamoDB input parameters.
|
|
26
|
+
*/
|
|
27
|
+
dbParams(): BatchWriteCommandInput {
|
|
28
|
+
return {
|
|
29
|
+
RequestItems: requestItems,
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Execute the BatchWriteItem command.
|
|
35
|
+
*/
|
|
36
|
+
async execute(): Promise<{
|
|
37
|
+
unprocessedItems?: Record<string, WriteRequest[]>;
|
|
38
|
+
}> {
|
|
39
|
+
const params = this.dbParams();
|
|
40
|
+
const result: BatchWriteCommandOutput = await client.send(new BatchWriteCommand(params));
|
|
41
|
+
logger?.log('BatchWriteCommand', params, result);
|
|
42
|
+
|
|
43
|
+
// Return unprocessed items if any
|
|
44
|
+
return {
|
|
45
|
+
unprocessedItems: result.UnprocessedItems as Record<string, WriteRequest[]> | undefined,
|
|
46
|
+
};
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { BatchWriteItemCommandInput } from '@aws-sdk/client-dynamodb';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A single write request that can be either a PutRequest or DeleteRequest
|
|
6
|
+
*/
|
|
7
|
+
export type WriteRequest = {
|
|
8
|
+
PutRequest?: {
|
|
9
|
+
Item: any;
|
|
10
|
+
};
|
|
11
|
+
DeleteRequest?: {
|
|
12
|
+
Key: any;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* BatchWriteBuilder allows you to put or delete multiple items from one or more tables
|
|
18
|
+
* in a single request.
|
|
19
|
+
*/
|
|
20
|
+
export type BatchWriteBuilder = {
|
|
21
|
+
/**
|
|
22
|
+
* Build the underlying DynamoDB BatchWriteItem input parameters.
|
|
23
|
+
*/
|
|
24
|
+
dbParams(): BatchWriteItemCommandInput;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Execute the BatchWriteItem command.
|
|
28
|
+
* Returns unprocessed items if any requests failed.
|
|
29
|
+
*/
|
|
30
|
+
execute(): Promise<{
|
|
31
|
+
unprocessedItems?: Record<string, WriteRequest[]>;
|
|
32
|
+
}>;
|
|
33
|
+
};
|