dyno-table 2.5.2 → 2.6.1
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/builders/batch-builder.d.ts +249 -0
- package/dist/builders/builder-types.d.ts +123 -0
- package/dist/builders/condition-check-builder.d.ts +149 -0
- package/dist/builders/delete-builder.d.ts +208 -0
- package/dist/builders/entity-aware-builders.d.ts +127 -0
- package/dist/builders/filter-builder.d.ts +294 -0
- package/dist/builders/get-builder.d.ts +191 -0
- package/dist/builders/index.d.ts +14 -0
- package/dist/builders/paginator.d.ts +151 -0
- package/dist/builders/put-builder.d.ts +317 -0
- package/dist/builders/query-builder.d.ts +218 -0
- package/dist/builders/result-iterator.d.ts +55 -0
- package/dist/builders/scan-builder.d.ts +109 -0
- package/dist/builders/transaction-builder.d.ts +462 -0
- package/dist/builders/types.d.ts +25 -0
- package/dist/builders/update-builder.d.ts +372 -0
- package/dist/builders.cjs +3648 -43
- package/dist/builders.d.ts +1 -4
- package/dist/builders.js +3648 -3
- package/dist/conditions.cjs +60 -67
- package/dist/conditions.d.ts +705 -3
- package/dist/conditions.js +46 -1
- package/dist/entity/ddb-indexing.d.ts +45 -0
- package/dist/entity/entity.d.ts +188 -0
- package/dist/entity/index-utils.d.ts +24 -0
- package/dist/entity.cjs +1126 -15
- package/dist/entity.d.ts +1 -261
- package/dist/entity.js +1127 -3
- package/dist/errors.d.ts +212 -0
- package/dist/expression.d.ts +9 -0
- package/dist/index-definition.d.ts +10 -0
- package/dist/index.cjs +5388 -270
- package/dist/index.d.ts +16 -273
- package/dist/index.js +5332 -6
- package/dist/operation-types.d.ts +8 -0
- package/dist/standard-schema.d.ts +2 -4
- package/dist/table.cjs +4311 -7
- package/dist/table.d.ts +13 -8
- package/dist/table.js +4315 -4
- package/dist/types.d.ts +6 -9
- package/dist/utils/chunk-array.d.ts +9 -0
- package/dist/utils/debug-expression.d.ts +32 -0
- package/dist/utils/debug-transaction.d.ts +17 -0
- package/dist/utils/error-factory.d.ts +162 -0
- package/dist/utils/error-utils.d.ts +170 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/partition-key-template.d.ts +30 -0
- package/dist/utils/sort-key-template.d.ts +33 -0
- package/dist/utils.cjs +28 -10
- package/dist/utils.d.ts +1 -66
- package/dist/utils.js +29 -1
- package/package.json +53 -66
- package/dist/builders.d.cts +0 -4
- package/dist/chunk-2WIBY7PZ.js +0 -46
- package/dist/chunk-3DR6VOFW.cjs +0 -3349
- package/dist/chunk-42LH2UEM.js +0 -577
- package/dist/chunk-7UJJ7JXM.cjs +0 -63
- package/dist/chunk-ELULXDSB.cjs +0 -564
- package/dist/chunk-FF7FYGDH.js +0 -543
- package/dist/chunk-G5ERTQFX.cjs +0 -843
- package/dist/chunk-NYJGW3XH.js +0 -3334
- package/dist/chunk-PB7BBCZO.cjs +0 -32
- package/dist/chunk-QVRMYGC4.js +0 -29
- package/dist/chunk-RNX2DAHA.js +0 -818
- package/dist/chunk-ZUBCW3LA.cjs +0 -579
- package/dist/conditions-BSAcZswY.d.ts +0 -731
- package/dist/conditions-C8bM__Pn.d.cts +0 -731
- package/dist/conditions.d.cts +0 -3
- package/dist/entity.d.cts +0 -261
- package/dist/index-Bc-ra0im.d.ts +0 -3042
- package/dist/index-CPCmWsEv.d.cts +0 -3042
- package/dist/index.d.cts +0 -273
- package/dist/standard-schema.d.cts +0 -57
- package/dist/table.d.cts +0 -165
- package/dist/types.d.cts +0 -29
- package/dist/utils.d.cts +0 -66
package/dist/chunk-42LH2UEM.js
DELETED
|
@@ -1,577 +0,0 @@
|
|
|
1
|
-
import { GetBuilder, PutBuilder, QueryBuilder, ScanBuilder, DeleteBuilder, UpdateBuilder, TransactionBuilder, BatchBuilder, ConditionCheckBuilder, buildExpression, generateAttributeName } from './chunk-NYJGW3XH.js';
|
|
2
|
-
import { ConfigurationErrors, OperationErrors } from './chunk-FF7FYGDH.js';
|
|
3
|
-
import { eq, and, beginsWith, between, gte, gt, lte, lt } from './chunk-2WIBY7PZ.js';
|
|
4
|
-
|
|
5
|
-
// src/utils/chunk-array.ts
|
|
6
|
-
function* chunkArray(array, size) {
|
|
7
|
-
if (size <= 0) {
|
|
8
|
-
throw ConfigurationErrors.invalidChunkSize(size);
|
|
9
|
-
}
|
|
10
|
-
for (let i = 0; i < array.length; i += size) {
|
|
11
|
-
yield array.slice(i, i + size);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// src/table.ts
|
|
16
|
-
var DDB_BATCH_WRITE_LIMIT = 25;
|
|
17
|
-
var DDB_BATCH_GET_LIMIT = 100;
|
|
18
|
-
var Table = class {
|
|
19
|
-
dynamoClient;
|
|
20
|
-
tableName;
|
|
21
|
-
/**
|
|
22
|
-
* The column name of the partitionKey for the Table
|
|
23
|
-
*/
|
|
24
|
-
partitionKey;
|
|
25
|
-
/**
|
|
26
|
-
* The column name of the sortKey for the Table
|
|
27
|
-
*/
|
|
28
|
-
sortKey;
|
|
29
|
-
/**
|
|
30
|
-
* The Global Secondary Indexes that are configured on this table
|
|
31
|
-
*/
|
|
32
|
-
gsis;
|
|
33
|
-
constructor(config) {
|
|
34
|
-
this.dynamoClient = config.client;
|
|
35
|
-
this.tableName = config.tableName;
|
|
36
|
-
this.partitionKey = config.indexes.partitionKey;
|
|
37
|
-
this.sortKey = config.indexes.sortKey;
|
|
38
|
-
this.gsis = config.indexes.gsis || {};
|
|
39
|
-
}
|
|
40
|
-
getIndexAttributeNames() {
|
|
41
|
-
const names = /* @__PURE__ */ new Set();
|
|
42
|
-
for (const gsi of Object.values(this.gsis)) {
|
|
43
|
-
names.add(gsi.partitionKey);
|
|
44
|
-
if (gsi.sortKey) {
|
|
45
|
-
names.add(gsi.sortKey);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return Array.from(names);
|
|
49
|
-
}
|
|
50
|
-
createKeyForPrimaryIndex(keyCondition) {
|
|
51
|
-
const primaryCondition = { [this.partitionKey]: keyCondition.pk };
|
|
52
|
-
if (this.sortKey) {
|
|
53
|
-
if (!keyCondition.sk) {
|
|
54
|
-
throw ConfigurationErrors.sortKeyRequired(this.tableName, this.partitionKey, this.sortKey);
|
|
55
|
-
}
|
|
56
|
-
primaryCondition[this.sortKey] = keyCondition.sk;
|
|
57
|
-
}
|
|
58
|
-
return primaryCondition;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Creates a new item in the table, it will fail if the item already exists.
|
|
62
|
-
*
|
|
63
|
-
* By default, this method returns the input values passed to the create operation
|
|
64
|
-
* upon successful creation.
|
|
65
|
-
*
|
|
66
|
-
* You can customise the return behaviour by chaining the `.returnValues()` method:
|
|
67
|
-
*
|
|
68
|
-
* @param item The item to create
|
|
69
|
-
* @returns A PutBuilder instance for chaining additional conditions and executing the create operation
|
|
70
|
-
*
|
|
71
|
-
* @example
|
|
72
|
-
* ```ts
|
|
73
|
-
* // Create with default behavior (returns input values)
|
|
74
|
-
* const result = await table.create({
|
|
75
|
-
* id: 'user-123',
|
|
76
|
-
* name: 'John Doe',
|
|
77
|
-
* email: 'john@example.com'
|
|
78
|
-
* }).execute();
|
|
79
|
-
* console.log(result); // Returns the input object
|
|
80
|
-
*
|
|
81
|
-
* // Create with no return value for better performance
|
|
82
|
-
* await table.create(userData).returnValues('NONE').execute();
|
|
83
|
-
*
|
|
84
|
-
* // Create and get fresh data from dynamodb using a strongly consistent read
|
|
85
|
-
* const freshData = await table.create(userData).returnValues('CONSISTENT').execute();
|
|
86
|
-
*
|
|
87
|
-
* // Create and get previous values (if the item was overwritten)
|
|
88
|
-
* const oldData = await table.create(userData).returnValues('ALL_OLD').execute();
|
|
89
|
-
* ```
|
|
90
|
-
*/
|
|
91
|
-
create(item) {
|
|
92
|
-
return this.put(item).condition((op) => op.attributeNotExists(this.partitionKey)).returnValues("INPUT");
|
|
93
|
-
}
|
|
94
|
-
get(keyCondition) {
|
|
95
|
-
const indexAttributeNames = this.getIndexAttributeNames();
|
|
96
|
-
const executor = async (params) => {
|
|
97
|
-
try {
|
|
98
|
-
const result = await this.dynamoClient.get({
|
|
99
|
-
TableName: params.tableName,
|
|
100
|
-
Key: this.createKeyForPrimaryIndex(keyCondition),
|
|
101
|
-
ProjectionExpression: params.projectionExpression,
|
|
102
|
-
ExpressionAttributeNames: params.expressionAttributeNames,
|
|
103
|
-
ConsistentRead: params.consistentRead
|
|
104
|
-
});
|
|
105
|
-
return {
|
|
106
|
-
item: result.Item ? result.Item : void 0
|
|
107
|
-
};
|
|
108
|
-
} catch (error) {
|
|
109
|
-
throw OperationErrors.getFailed(params.tableName, keyCondition, error instanceof Error ? error : void 0);
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
return new GetBuilder(executor, keyCondition, this.tableName, indexAttributeNames);
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Updates an item in the table
|
|
116
|
-
*
|
|
117
|
-
* @param item The item to update
|
|
118
|
-
* @returns A PutBuilder instance for chaining conditions and executing the put operation
|
|
119
|
-
*/
|
|
120
|
-
put(item) {
|
|
121
|
-
const executor = async (params) => {
|
|
122
|
-
try {
|
|
123
|
-
const result = await this.dynamoClient.put({
|
|
124
|
-
TableName: params.tableName,
|
|
125
|
-
Item: params.item,
|
|
126
|
-
ConditionExpression: params.conditionExpression,
|
|
127
|
-
ExpressionAttributeNames: params.expressionAttributeNames,
|
|
128
|
-
ExpressionAttributeValues: params.expressionAttributeValues,
|
|
129
|
-
// CONSISTENT and INPUT are not valid ReturnValues for DDB, so we set NONE as we are not interested in its
|
|
130
|
-
// response and will be handling these cases separately
|
|
131
|
-
ReturnValues: params.returnValues === "CONSISTENT" || params.returnValues === "INPUT" ? "NONE" : params.returnValues
|
|
132
|
-
});
|
|
133
|
-
if (params.returnValues === "INPUT") {
|
|
134
|
-
return params.item;
|
|
135
|
-
}
|
|
136
|
-
if (params.returnValues === "CONSISTENT") {
|
|
137
|
-
const getResult = await this.dynamoClient.get({
|
|
138
|
-
TableName: params.tableName,
|
|
139
|
-
Key: this.createKeyForPrimaryIndex({
|
|
140
|
-
pk: params.item[this.partitionKey],
|
|
141
|
-
...this.sortKey && { sk: params.item[this.sortKey] }
|
|
142
|
-
}),
|
|
143
|
-
ConsistentRead: true
|
|
144
|
-
});
|
|
145
|
-
return getResult.Item;
|
|
146
|
-
}
|
|
147
|
-
return result.Attributes;
|
|
148
|
-
} catch (error) {
|
|
149
|
-
throw OperationErrors.putFailed(params.tableName, params.item, error instanceof Error ? error : void 0);
|
|
150
|
-
}
|
|
151
|
-
};
|
|
152
|
-
return new PutBuilder(executor, item, this.tableName);
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Creates a query builder for complex queries
|
|
156
|
-
* If useIndex is called on the returned QueryBuilder, it will use the GSI configuration
|
|
157
|
-
*/
|
|
158
|
-
query(keyCondition) {
|
|
159
|
-
const indexAttributeNames = this.getIndexAttributeNames();
|
|
160
|
-
const pkAttributeName = this.partitionKey;
|
|
161
|
-
const skAttributeName = this.sortKey;
|
|
162
|
-
let keyConditionExpression = eq(pkAttributeName, keyCondition.pk);
|
|
163
|
-
if (keyCondition.sk) {
|
|
164
|
-
if (!skAttributeName) {
|
|
165
|
-
throw ConfigurationErrors.sortKeyNotDefined(this.tableName, pkAttributeName);
|
|
166
|
-
}
|
|
167
|
-
const keyConditionOperator = {
|
|
168
|
-
eq: (value) => eq(skAttributeName, value),
|
|
169
|
-
lt: (value) => lt(skAttributeName, value),
|
|
170
|
-
lte: (value) => lte(skAttributeName, value),
|
|
171
|
-
gt: (value) => gt(skAttributeName, value),
|
|
172
|
-
gte: (value) => gte(skAttributeName, value),
|
|
173
|
-
between: (lower, upper) => between(skAttributeName, lower, upper),
|
|
174
|
-
beginsWith: (value) => beginsWith(skAttributeName, value),
|
|
175
|
-
and: (...conditions) => and(...conditions)
|
|
176
|
-
};
|
|
177
|
-
const skCondition = keyCondition.sk(keyConditionOperator);
|
|
178
|
-
keyConditionExpression = and(eq(pkAttributeName, keyCondition.pk), skCondition);
|
|
179
|
-
}
|
|
180
|
-
const executor = async (originalKeyCondition, options) => {
|
|
181
|
-
let finalKeyCondition = originalKeyCondition;
|
|
182
|
-
if (options.indexName) {
|
|
183
|
-
const gsiName = String(options.indexName);
|
|
184
|
-
const gsi = this.gsis[gsiName];
|
|
185
|
-
if (!gsi) {
|
|
186
|
-
throw ConfigurationErrors.gsiNotFound(gsiName, this.tableName, Object.keys(this.gsis));
|
|
187
|
-
}
|
|
188
|
-
const gsiPkAttributeName = gsi.partitionKey;
|
|
189
|
-
const gsiSkAttributeName = gsi.sortKey;
|
|
190
|
-
let pkValue;
|
|
191
|
-
let skValue;
|
|
192
|
-
let extractedSkCondition;
|
|
193
|
-
if (originalKeyCondition.type === "eq") {
|
|
194
|
-
pkValue = originalKeyCondition.value;
|
|
195
|
-
} else if (originalKeyCondition.type === "and" && originalKeyCondition.conditions) {
|
|
196
|
-
const pkCondition = originalKeyCondition.conditions.find(
|
|
197
|
-
(c) => c.type === "eq" && c.attr === pkAttributeName
|
|
198
|
-
);
|
|
199
|
-
if (pkCondition && pkCondition.type === "eq") {
|
|
200
|
-
pkValue = pkCondition.value;
|
|
201
|
-
}
|
|
202
|
-
const skConditions = originalKeyCondition.conditions.filter((c) => c.attr === skAttributeName);
|
|
203
|
-
if (skConditions.length > 0) {
|
|
204
|
-
if (skConditions.length === 1) {
|
|
205
|
-
extractedSkCondition = skConditions[0];
|
|
206
|
-
if (extractedSkCondition && extractedSkCondition.type === "eq") {
|
|
207
|
-
skValue = extractedSkCondition.value;
|
|
208
|
-
}
|
|
209
|
-
} else if (skConditions.length > 1) {
|
|
210
|
-
extractedSkCondition = and(...skConditions);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
if (!pkValue) {
|
|
215
|
-
throw ConfigurationErrors.pkExtractionFailed(this.tableName, options.indexName, originalKeyCondition);
|
|
216
|
-
}
|
|
217
|
-
let gsiKeyCondition = eq(gsiPkAttributeName, pkValue);
|
|
218
|
-
if (skValue && gsiSkAttributeName) {
|
|
219
|
-
gsiKeyCondition = and(gsiKeyCondition, eq(gsiSkAttributeName, skValue));
|
|
220
|
-
} else if (extractedSkCondition && gsiSkAttributeName) {
|
|
221
|
-
if (extractedSkCondition.attr === skAttributeName) {
|
|
222
|
-
const updatedSkCondition = {
|
|
223
|
-
...extractedSkCondition,
|
|
224
|
-
attr: gsiSkAttributeName
|
|
225
|
-
};
|
|
226
|
-
gsiKeyCondition = and(gsiKeyCondition, updatedSkCondition);
|
|
227
|
-
} else {
|
|
228
|
-
gsiKeyCondition = and(gsiKeyCondition, extractedSkCondition);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
finalKeyCondition = gsiKeyCondition;
|
|
232
|
-
}
|
|
233
|
-
const expressionParams = {
|
|
234
|
-
expressionAttributeNames: {},
|
|
235
|
-
expressionAttributeValues: {},
|
|
236
|
-
valueCounter: { count: 0 }
|
|
237
|
-
};
|
|
238
|
-
const keyConditionExpression2 = buildExpression(finalKeyCondition, expressionParams);
|
|
239
|
-
let filterExpression;
|
|
240
|
-
if (options.filter) {
|
|
241
|
-
filterExpression = buildExpression(options.filter, expressionParams);
|
|
242
|
-
}
|
|
243
|
-
const projectionExpression = options.projection?.map((p) => generateAttributeName(expressionParams, p)).join(", ");
|
|
244
|
-
const { expressionAttributeNames, expressionAttributeValues } = expressionParams;
|
|
245
|
-
const { indexName, limit, consistentRead, scanIndexForward, lastEvaluatedKey } = options;
|
|
246
|
-
const params = {
|
|
247
|
-
TableName: this.tableName,
|
|
248
|
-
KeyConditionExpression: keyConditionExpression2,
|
|
249
|
-
FilterExpression: filterExpression,
|
|
250
|
-
ExpressionAttributeNames: expressionAttributeNames,
|
|
251
|
-
ExpressionAttributeValues: expressionAttributeValues,
|
|
252
|
-
IndexName: indexName,
|
|
253
|
-
Limit: limit,
|
|
254
|
-
ConsistentRead: consistentRead,
|
|
255
|
-
ScanIndexForward: scanIndexForward,
|
|
256
|
-
ProjectionExpression: projectionExpression,
|
|
257
|
-
ExclusiveStartKey: lastEvaluatedKey
|
|
258
|
-
};
|
|
259
|
-
try {
|
|
260
|
-
const result = await this.dynamoClient.query(params);
|
|
261
|
-
return {
|
|
262
|
-
items: result.Items,
|
|
263
|
-
lastEvaluatedKey: result.LastEvaluatedKey
|
|
264
|
-
};
|
|
265
|
-
} catch (error) {
|
|
266
|
-
throw OperationErrors.queryFailed(
|
|
267
|
-
this.tableName,
|
|
268
|
-
{ indexName, keyConditionExpression: keyConditionExpression2, filterExpression },
|
|
269
|
-
error instanceof Error ? error : void 0
|
|
270
|
-
);
|
|
271
|
-
}
|
|
272
|
-
};
|
|
273
|
-
return new QueryBuilder(executor, keyConditionExpression, indexAttributeNames);
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* Creates a scan builder for scanning the entire table
|
|
277
|
-
* Use this when you need to:
|
|
278
|
-
* - Process all items in a table
|
|
279
|
-
* - Apply filters to a large dataset
|
|
280
|
-
* - Use a GSI for scanning
|
|
281
|
-
*
|
|
282
|
-
* @returns A ScanBuilder instance for chaining operations
|
|
283
|
-
*/
|
|
284
|
-
scan() {
|
|
285
|
-
const executor = async (options) => {
|
|
286
|
-
const expressionParams = {
|
|
287
|
-
expressionAttributeNames: {},
|
|
288
|
-
expressionAttributeValues: {},
|
|
289
|
-
valueCounter: { count: 0 }
|
|
290
|
-
};
|
|
291
|
-
let filterExpression;
|
|
292
|
-
if (options.filter) {
|
|
293
|
-
filterExpression = buildExpression(options.filter, expressionParams);
|
|
294
|
-
}
|
|
295
|
-
const projectionExpression = options.projection?.map((p) => generateAttributeName(expressionParams, p)).join(", ");
|
|
296
|
-
const { expressionAttributeNames, expressionAttributeValues } = expressionParams;
|
|
297
|
-
const { indexName, limit, consistentRead, lastEvaluatedKey } = options;
|
|
298
|
-
const params = {
|
|
299
|
-
TableName: this.tableName,
|
|
300
|
-
FilterExpression: filterExpression,
|
|
301
|
-
ExpressionAttributeNames: Object.keys(expressionAttributeNames).length > 0 ? expressionAttributeNames : void 0,
|
|
302
|
-
ExpressionAttributeValues: Object.keys(expressionAttributeValues).length > 0 ? expressionAttributeValues : void 0,
|
|
303
|
-
IndexName: indexName,
|
|
304
|
-
Limit: limit,
|
|
305
|
-
ConsistentRead: consistentRead,
|
|
306
|
-
ProjectionExpression: projectionExpression,
|
|
307
|
-
ExclusiveStartKey: lastEvaluatedKey
|
|
308
|
-
};
|
|
309
|
-
try {
|
|
310
|
-
const result = await this.dynamoClient.scan(params);
|
|
311
|
-
return {
|
|
312
|
-
items: result.Items,
|
|
313
|
-
lastEvaluatedKey: result.LastEvaluatedKey
|
|
314
|
-
};
|
|
315
|
-
} catch (error) {
|
|
316
|
-
throw OperationErrors.scanFailed(
|
|
317
|
-
this.tableName,
|
|
318
|
-
{ indexName: options.indexName, filterExpression },
|
|
319
|
-
error instanceof Error ? error : void 0
|
|
320
|
-
);
|
|
321
|
-
}
|
|
322
|
-
};
|
|
323
|
-
return new ScanBuilder(executor);
|
|
324
|
-
}
|
|
325
|
-
delete(keyCondition) {
|
|
326
|
-
const executor = async (params) => {
|
|
327
|
-
try {
|
|
328
|
-
const result = await this.dynamoClient.delete({
|
|
329
|
-
TableName: params.tableName,
|
|
330
|
-
Key: this.createKeyForPrimaryIndex(keyCondition),
|
|
331
|
-
ConditionExpression: params.conditionExpression,
|
|
332
|
-
ExpressionAttributeNames: params.expressionAttributeNames,
|
|
333
|
-
ExpressionAttributeValues: params.expressionAttributeValues,
|
|
334
|
-
ReturnValues: params.returnValues
|
|
335
|
-
});
|
|
336
|
-
return {
|
|
337
|
-
item: result.Attributes
|
|
338
|
-
};
|
|
339
|
-
} catch (error) {
|
|
340
|
-
throw OperationErrors.deleteFailed(params.tableName, keyCondition, error instanceof Error ? error : void 0);
|
|
341
|
-
}
|
|
342
|
-
};
|
|
343
|
-
return new DeleteBuilder(executor, this.tableName, keyCondition);
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* Updates an item in the table
|
|
347
|
-
*
|
|
348
|
-
* @param keyCondition The primary key of the item to update
|
|
349
|
-
* @returns An UpdateBuilder instance for chaining update operations and conditions
|
|
350
|
-
*/
|
|
351
|
-
update(keyCondition) {
|
|
352
|
-
const executor = async (params) => {
|
|
353
|
-
try {
|
|
354
|
-
const result = await this.dynamoClient.update({
|
|
355
|
-
TableName: params.tableName,
|
|
356
|
-
Key: this.createKeyForPrimaryIndex(keyCondition),
|
|
357
|
-
UpdateExpression: params.updateExpression,
|
|
358
|
-
ConditionExpression: params.conditionExpression,
|
|
359
|
-
ExpressionAttributeNames: params.expressionAttributeNames,
|
|
360
|
-
ExpressionAttributeValues: params.expressionAttributeValues,
|
|
361
|
-
ReturnValues: params.returnValues
|
|
362
|
-
});
|
|
363
|
-
return {
|
|
364
|
-
item: result.Attributes
|
|
365
|
-
};
|
|
366
|
-
} catch (error) {
|
|
367
|
-
throw OperationErrors.updateFailed(params.tableName, keyCondition, error instanceof Error ? error : void 0);
|
|
368
|
-
}
|
|
369
|
-
};
|
|
370
|
-
return new UpdateBuilder(executor, this.tableName, keyCondition);
|
|
371
|
-
}
|
|
372
|
-
/**
|
|
373
|
-
* Creates a transaction builder for performing multiple operations atomically
|
|
374
|
-
*/
|
|
375
|
-
transactionBuilder() {
|
|
376
|
-
const executor = async (params) => {
|
|
377
|
-
await this.dynamoClient.transactWrite(params);
|
|
378
|
-
};
|
|
379
|
-
return new TransactionBuilder(executor, {
|
|
380
|
-
partitionKey: this.partitionKey,
|
|
381
|
-
sortKey: this.sortKey
|
|
382
|
-
});
|
|
383
|
-
}
|
|
384
|
-
/**
|
|
385
|
-
* Creates a batch builder for performing multiple operations efficiently with optional type inference
|
|
386
|
-
*
|
|
387
|
-
* @example Basic Usage
|
|
388
|
-
* ```typescript
|
|
389
|
-
* const batch = table.batchBuilder();
|
|
390
|
-
*
|
|
391
|
-
* // Add operations
|
|
392
|
-
* userRepo.create(newUser).withBatch(batch);
|
|
393
|
-
* orderRepo.get({ id: 'order-1' }).withBatch(batch);
|
|
394
|
-
*
|
|
395
|
-
* // Execute operations
|
|
396
|
-
* const result = await batch.execute();
|
|
397
|
-
* ```
|
|
398
|
-
*
|
|
399
|
-
* @example Typed Usage
|
|
400
|
-
* ```typescript
|
|
401
|
-
* // Define entity types for the batch
|
|
402
|
-
* const batch = table.batchBuilder<{
|
|
403
|
-
* User: UserEntity;
|
|
404
|
-
* Order: OrderEntity;
|
|
405
|
-
* Product: ProductEntity;
|
|
406
|
-
* }>();
|
|
407
|
-
*
|
|
408
|
-
* // Add operations with type information
|
|
409
|
-
* userRepo.create(newUser).withBatch(batch, 'User');
|
|
410
|
-
* orderRepo.get({ id: 'order-1' }).withBatch(batch, 'Order');
|
|
411
|
-
* productRepo.delete({ id: 'old-product' }).withBatch(batch, 'Product');
|
|
412
|
-
*
|
|
413
|
-
* // Execute and get typed results
|
|
414
|
-
* const result = await batch.execute();
|
|
415
|
-
* const users: UserEntity[] = result.reads.itemsByType.User;
|
|
416
|
-
* const orders: OrderEntity[] = result.reads.itemsByType.Order;
|
|
417
|
-
* ```
|
|
418
|
-
*/
|
|
419
|
-
batchBuilder() {
|
|
420
|
-
const batchWriteExecutor = async (operations) => {
|
|
421
|
-
return this.batchWrite(operations);
|
|
422
|
-
};
|
|
423
|
-
const batchGetExecutor = async (keys) => {
|
|
424
|
-
return this.batchGet(keys);
|
|
425
|
-
};
|
|
426
|
-
return new BatchBuilder(batchWriteExecutor, batchGetExecutor, {
|
|
427
|
-
partitionKey: this.partitionKey,
|
|
428
|
-
sortKey: this.sortKey
|
|
429
|
-
});
|
|
430
|
-
}
|
|
431
|
-
/**
|
|
432
|
-
* Executes a transaction using a callback function
|
|
433
|
-
*
|
|
434
|
-
* @param callback A function that receives a transaction context and performs operations on it
|
|
435
|
-
* @param options Optional transaction options
|
|
436
|
-
* @returns A promise that resolves when the transaction is complete
|
|
437
|
-
*/
|
|
438
|
-
async transaction(callback, options) {
|
|
439
|
-
const transactionExecutor = async (params) => {
|
|
440
|
-
await this.dynamoClient.transactWrite(params);
|
|
441
|
-
};
|
|
442
|
-
const transaction = new TransactionBuilder(transactionExecutor, {
|
|
443
|
-
partitionKey: this.partitionKey,
|
|
444
|
-
sortKey: this.sortKey
|
|
445
|
-
});
|
|
446
|
-
if (options) {
|
|
447
|
-
transaction.withOptions(options);
|
|
448
|
-
}
|
|
449
|
-
const result = await callback(transaction);
|
|
450
|
-
await transaction.execute();
|
|
451
|
-
return result;
|
|
452
|
-
}
|
|
453
|
-
/**
|
|
454
|
-
* Creates a condition check operation for use in transactions
|
|
455
|
-
*
|
|
456
|
-
* This is useful for when you require a transaction to succeed only when a specific condition is met on a
|
|
457
|
-
* a record within the database that you are not directly updating.
|
|
458
|
-
*
|
|
459
|
-
* For example, you are updating a record and you want to ensure that another record exists and/or has a specific value before proceeding.
|
|
460
|
-
*/
|
|
461
|
-
conditionCheck(keyCondition) {
|
|
462
|
-
return new ConditionCheckBuilder(this.tableName, keyCondition);
|
|
463
|
-
}
|
|
464
|
-
/**
|
|
465
|
-
* Performs a batch get operation to retrieve multiple items at once
|
|
466
|
-
*
|
|
467
|
-
* @param keys Array of primary keys to retrieve
|
|
468
|
-
* @returns A promise that resolves to the retrieved items
|
|
469
|
-
*/
|
|
470
|
-
async batchGet(keys) {
|
|
471
|
-
const allItems = [];
|
|
472
|
-
const allUnprocessedKeys = [];
|
|
473
|
-
for (const chunk of chunkArray(keys, DDB_BATCH_GET_LIMIT)) {
|
|
474
|
-
const formattedKeys = chunk.map((key) => ({
|
|
475
|
-
[this.partitionKey]: key.pk,
|
|
476
|
-
...this.sortKey ? { [this.sortKey]: key.sk } : {}
|
|
477
|
-
}));
|
|
478
|
-
const params = {
|
|
479
|
-
RequestItems: {
|
|
480
|
-
[this.tableName]: {
|
|
481
|
-
Keys: formattedKeys
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
};
|
|
485
|
-
try {
|
|
486
|
-
const result = await this.dynamoClient.batchGet(params);
|
|
487
|
-
if (result.Responses?.[this.tableName]) {
|
|
488
|
-
allItems.push(...result.Responses[this.tableName]);
|
|
489
|
-
}
|
|
490
|
-
const unprocessedKeysArray = result.UnprocessedKeys?.[this.tableName]?.Keys || [];
|
|
491
|
-
const unprocessedKeys = unprocessedKeysArray.map((key) => ({
|
|
492
|
-
pk: key[this.partitionKey],
|
|
493
|
-
sk: this.sortKey ? key[this.sortKey] : void 0
|
|
494
|
-
}));
|
|
495
|
-
if (unprocessedKeys.length > 0) {
|
|
496
|
-
allUnprocessedKeys.push(...unprocessedKeys);
|
|
497
|
-
}
|
|
498
|
-
} catch (error) {
|
|
499
|
-
throw OperationErrors.batchGetFailed(
|
|
500
|
-
this.tableName,
|
|
501
|
-
{ requestedKeys: keys.length },
|
|
502
|
-
error instanceof Error ? error : void 0
|
|
503
|
-
);
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
return {
|
|
507
|
-
items: allItems,
|
|
508
|
-
unprocessedKeys: allUnprocessedKeys
|
|
509
|
-
};
|
|
510
|
-
}
|
|
511
|
-
/**
|
|
512
|
-
* Performs a batch write operation to put or delete multiple items at once
|
|
513
|
-
*
|
|
514
|
-
* @param operations Array of put or delete operations
|
|
515
|
-
* @returns A promise that resolves to any unprocessed operations
|
|
516
|
-
*/
|
|
517
|
-
async batchWrite(operations) {
|
|
518
|
-
const allUnprocessedItems = [];
|
|
519
|
-
for (const chunk of chunkArray(operations, DDB_BATCH_WRITE_LIMIT)) {
|
|
520
|
-
const writeRequests = chunk.map((operation) => {
|
|
521
|
-
if (operation.type === "put") {
|
|
522
|
-
return {
|
|
523
|
-
PutRequest: {
|
|
524
|
-
Item: operation.item
|
|
525
|
-
}
|
|
526
|
-
};
|
|
527
|
-
}
|
|
528
|
-
return {
|
|
529
|
-
DeleteRequest: {
|
|
530
|
-
Key: this.createKeyForPrimaryIndex(operation.key)
|
|
531
|
-
}
|
|
532
|
-
};
|
|
533
|
-
});
|
|
534
|
-
const params = {
|
|
535
|
-
RequestItems: {
|
|
536
|
-
[this.tableName]: writeRequests
|
|
537
|
-
}
|
|
538
|
-
};
|
|
539
|
-
try {
|
|
540
|
-
const result = await this.dynamoClient.batchWrite(params);
|
|
541
|
-
const unprocessedRequestsArray = result.UnprocessedItems?.[this.tableName] || [];
|
|
542
|
-
if (unprocessedRequestsArray.length > 0) {
|
|
543
|
-
const unprocessedItems = unprocessedRequestsArray.map((request) => {
|
|
544
|
-
if (request?.PutRequest?.Item) {
|
|
545
|
-
return {
|
|
546
|
-
type: "put",
|
|
547
|
-
item: request.PutRequest.Item
|
|
548
|
-
};
|
|
549
|
-
}
|
|
550
|
-
if (request?.DeleteRequest?.Key) {
|
|
551
|
-
return {
|
|
552
|
-
type: "delete",
|
|
553
|
-
key: {
|
|
554
|
-
pk: request.DeleteRequest.Key[this.partitionKey],
|
|
555
|
-
sk: this.sortKey ? request.DeleteRequest.Key[this.sortKey] : void 0
|
|
556
|
-
}
|
|
557
|
-
};
|
|
558
|
-
}
|
|
559
|
-
throw new Error("Invalid unprocessed item format returned from DynamoDB");
|
|
560
|
-
});
|
|
561
|
-
allUnprocessedItems.push(...unprocessedItems);
|
|
562
|
-
}
|
|
563
|
-
} catch (error) {
|
|
564
|
-
throw OperationErrors.batchWriteFailed(
|
|
565
|
-
this.tableName,
|
|
566
|
-
{ requestedOperations: operations.length },
|
|
567
|
-
error instanceof Error ? error : void 0
|
|
568
|
-
);
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
return {
|
|
572
|
-
unprocessedItems: allUnprocessedItems
|
|
573
|
-
};
|
|
574
|
-
}
|
|
575
|
-
};
|
|
576
|
-
|
|
577
|
-
export { Table };
|
package/dist/chunk-7UJJ7JXM.cjs
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// src/conditions.ts
|
|
4
|
-
var createComparisonCondition = (type) => (attr, value) => ({
|
|
5
|
-
type,
|
|
6
|
-
attr,
|
|
7
|
-
value
|
|
8
|
-
});
|
|
9
|
-
var eq = createComparisonCondition("eq");
|
|
10
|
-
var ne = createComparisonCondition("ne");
|
|
11
|
-
var lt = createComparisonCondition("lt");
|
|
12
|
-
var lte = createComparisonCondition("lte");
|
|
13
|
-
var gt = createComparisonCondition("gt");
|
|
14
|
-
var gte = createComparisonCondition("gte");
|
|
15
|
-
var between = (attr, lower, upper) => ({
|
|
16
|
-
type: "between",
|
|
17
|
-
attr,
|
|
18
|
-
value: [lower, upper]
|
|
19
|
-
});
|
|
20
|
-
var inArray = (attr, values) => ({
|
|
21
|
-
type: "in",
|
|
22
|
-
attr,
|
|
23
|
-
value: values
|
|
24
|
-
});
|
|
25
|
-
var beginsWith = createComparisonCondition("beginsWith");
|
|
26
|
-
var contains = createComparisonCondition("contains");
|
|
27
|
-
var attributeExists = (attr) => ({
|
|
28
|
-
type: "attributeExists",
|
|
29
|
-
attr
|
|
30
|
-
});
|
|
31
|
-
var attributeNotExists = (attr) => ({
|
|
32
|
-
type: "attributeNotExists",
|
|
33
|
-
attr
|
|
34
|
-
});
|
|
35
|
-
var and = (...conditions) => ({
|
|
36
|
-
type: "and",
|
|
37
|
-
conditions
|
|
38
|
-
});
|
|
39
|
-
var or = (...conditions) => ({
|
|
40
|
-
type: "or",
|
|
41
|
-
conditions
|
|
42
|
-
});
|
|
43
|
-
var not = (condition) => ({
|
|
44
|
-
type: "not",
|
|
45
|
-
condition
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
exports.and = and;
|
|
49
|
-
exports.attributeExists = attributeExists;
|
|
50
|
-
exports.attributeNotExists = attributeNotExists;
|
|
51
|
-
exports.beginsWith = beginsWith;
|
|
52
|
-
exports.between = between;
|
|
53
|
-
exports.contains = contains;
|
|
54
|
-
exports.createComparisonCondition = createComparisonCondition;
|
|
55
|
-
exports.eq = eq;
|
|
56
|
-
exports.gt = gt;
|
|
57
|
-
exports.gte = gte;
|
|
58
|
-
exports.inArray = inArray;
|
|
59
|
-
exports.lt = lt;
|
|
60
|
-
exports.lte = lte;
|
|
61
|
-
exports.ne = ne;
|
|
62
|
-
exports.not = not;
|
|
63
|
-
exports.or = or;
|