dyno-table 2.3.3 → 2.5.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.
@@ -1,18 +1,9 @@
1
1
  'use strict';
2
2
 
3
+ var chunkELULXDSB_cjs = require('./chunk-ELULXDSB.cjs');
3
4
  var chunk7UJJ7JXM_cjs = require('./chunk-7UJJ7JXM.cjs');
4
5
 
5
6
  // src/builders/batch-builder.ts
6
- var BatchError = class extends Error {
7
- operation;
8
- cause;
9
- constructor(message, operation, cause) {
10
- super(message);
11
- this.name = "BatchError";
12
- this.operation = operation;
13
- this.cause = cause;
14
- }
15
- };
16
7
  var BatchBuilder = class {
17
8
  constructor(batchWriteExecutor, batchGetExecutor, config) {
18
9
  this.batchWriteExecutor = batchWriteExecutor;
@@ -47,10 +38,7 @@ var BatchBuilder = class {
47
38
  */
48
39
  validateNotEmpty() {
49
40
  if (this.isEmpty()) {
50
- throw new BatchError(
51
- "Cannot execute empty batch. Add operations using entity builders with .withBatch()",
52
- "write"
53
- );
41
+ throw chunkELULXDSB_cjs.BatchErrors.batchEmpty("write");
54
42
  }
55
43
  }
56
44
  /**
@@ -141,13 +129,14 @@ var BatchBuilder = class {
141
129
  key
142
130
  };
143
131
  }
144
- throw new BatchError(`Unsupported batch item type for write operation: ${item.type}`, "write");
132
+ throw chunkELULXDSB_cjs.BatchErrors.unsupportedType("write", item);
145
133
  });
146
134
  return await this.batchWriteExecutor(operations);
147
135
  } catch (error) {
148
- throw new BatchError(
149
- `Failed to execute batch write operations: ${error instanceof Error ? error.message : "Unknown error"}`,
150
- "write",
136
+ if (error instanceof chunkELULXDSB_cjs.BatchError) throw error;
137
+ throw chunkELULXDSB_cjs.BatchErrors.batchWriteFailed(
138
+ [],
139
+ { operationCount: this.writeItems.length },
151
140
  error instanceof Error ? error : void 0
152
141
  );
153
142
  }
@@ -174,13 +163,14 @@ var BatchBuilder = class {
174
163
  sk: this.config.sortKey ? tableKey[this.config.sortKey] : void 0
175
164
  };
176
165
  }
177
- throw new BatchError(`Unsupported batch item type for get operation: ${item.type}`, "read");
166
+ throw chunkELULXDSB_cjs.BatchErrors.unsupportedType("read", item);
178
167
  });
179
168
  return await this.batchGetExecutor(keys);
180
169
  } catch (error) {
181
- throw new BatchError(
182
- `Failed to execute batch get operations: ${error instanceof Error ? error.message : "Unknown error"}`,
183
- "read",
170
+ if (error instanceof chunkELULXDSB_cjs.BatchError) throw error;
171
+ throw chunkELULXDSB_cjs.BatchErrors.batchGetFailed(
172
+ [],
173
+ { operationCount: this.getItems.length },
184
174
  error instanceof Error ? error : void 0
185
175
  );
186
176
  }
@@ -226,13 +216,16 @@ var BatchBuilder = class {
226
216
  try {
227
217
  writeResults = await this.executeWrites();
228
218
  } catch (error) {
229
- if (error instanceof BatchError) {
219
+ if (error instanceof chunkELULXDSB_cjs.BatchError) {
230
220
  errors.push(error);
231
221
  } else {
232
222
  errors.push(
233
- new BatchError(
223
+ new chunkELULXDSB_cjs.BatchError(
234
224
  "Unexpected error during write operations",
225
+ chunkELULXDSB_cjs.ErrorCodes.BATCH_WRITE_FAILED,
235
226
  "write",
227
+ [],
228
+ {},
236
229
  error instanceof Error ? error : void 0
237
230
  )
238
231
  );
@@ -243,13 +236,16 @@ var BatchBuilder = class {
243
236
  try {
244
237
  getResults = await this.executeGets();
245
238
  } catch (error) {
246
- if (error instanceof BatchError) {
239
+ if (error instanceof chunkELULXDSB_cjs.BatchError) {
247
240
  errors.push(error);
248
241
  } else {
249
242
  errors.push(
250
- new BatchError(
243
+ new chunkELULXDSB_cjs.BatchError(
251
244
  "Unexpected error during read operations",
245
+ chunkELULXDSB_cjs.ErrorCodes.BATCH_GET_FAILED,
252
246
  "read",
247
+ [],
248
+ {},
253
249
  error instanceof Error ? error : void 0
254
250
  )
255
251
  );
@@ -316,16 +312,16 @@ var generateValueName = (params, value) => {
316
312
  };
317
313
  var validateCondition = (condition, requiresAttr = true, requiresValue = true) => {
318
314
  if (requiresAttr && !condition.attr) {
319
- throw new Error(`Attribute is required for ${condition.type} condition`);
315
+ throw chunkELULXDSB_cjs.ExpressionErrors.missingAttribute(condition.type, condition);
320
316
  }
321
317
  if (requiresValue && condition.value === void 0) {
322
- throw new Error(`Value is required for ${condition.type} condition`);
318
+ throw chunkELULXDSB_cjs.ExpressionErrors.missingValue(condition.type, condition);
323
319
  }
324
320
  };
325
321
  var buildComparisonExpression = (condition, operator, params) => {
326
322
  validateCondition(condition);
327
323
  if (!condition.attr) {
328
- throw new Error(`Attribute is required for ${condition.type} condition`);
324
+ throw chunkELULXDSB_cjs.ExpressionErrors.missingAttribute(condition.type, condition);
329
325
  }
330
326
  const attrName = generateAttributeName(params, condition.attr);
331
327
  const valueName = generateValueName(params, condition.value);
@@ -334,10 +330,14 @@ var buildComparisonExpression = (condition, operator, params) => {
334
330
  var buildBetweenExpression = (condition, params) => {
335
331
  validateCondition(condition);
336
332
  if (!condition.attr) {
337
- throw new Error(`Attribute is required for ${condition.type} condition`);
333
+ throw chunkELULXDSB_cjs.ExpressionErrors.missingAttribute(condition.type, condition);
338
334
  }
339
335
  if (!Array.isArray(condition.value) || condition.value.length !== 2) {
340
- throw new Error("Between condition requires an array of two values");
336
+ throw chunkELULXDSB_cjs.ExpressionErrors.invalidCondition(
337
+ condition.type,
338
+ condition,
339
+ "Provide an array with exactly two values: [lowerBound, upperBound]"
340
+ );
341
341
  }
342
342
  const attrName = generateAttributeName(params, condition.attr);
343
343
  const lowerName = generateValueName(params, condition.value[0]);
@@ -347,13 +347,17 @@ var buildBetweenExpression = (condition, params) => {
347
347
  var buildInExpression = (condition, params) => {
348
348
  validateCondition(condition);
349
349
  if (!condition.attr) {
350
- throw new Error(`Attribute is required for ${condition.type} condition`);
350
+ throw chunkELULXDSB_cjs.ExpressionErrors.missingAttribute(condition.type, condition);
351
351
  }
352
352
  if (!Array.isArray(condition.value) || condition.value.length === 0) {
353
- throw new Error("In condition requires a non-empty array of values");
353
+ throw chunkELULXDSB_cjs.ExpressionErrors.emptyArray(condition.type, condition.value);
354
354
  }
355
355
  if (condition.value.length > 100) {
356
- throw new Error("In condition supports a maximum of 100 values");
356
+ throw chunkELULXDSB_cjs.ExpressionErrors.invalidCondition(
357
+ condition.type,
358
+ condition,
359
+ "Split your query into multiple operations or use a different condition type"
360
+ );
357
361
  }
358
362
  const attrName = generateAttributeName(params, condition.attr);
359
363
  const valueNames = condition.value.map((value) => generateValueName(params, value));
@@ -362,7 +366,7 @@ var buildInExpression = (condition, params) => {
362
366
  var buildFunctionExpression = (functionName, condition, params) => {
363
367
  validateCondition(condition);
364
368
  if (!condition.attr) {
365
- throw new Error(`Attribute is required for ${condition.type} condition`);
369
+ throw chunkELULXDSB_cjs.ExpressionErrors.missingAttribute(condition.type, condition);
366
370
  }
367
371
  const attrName = generateAttributeName(params, condition.attr);
368
372
  const valueName = generateValueName(params, condition.value);
@@ -371,66 +375,65 @@ var buildFunctionExpression = (functionName, condition, params) => {
371
375
  var buildAttributeFunction = (functionName, condition, params) => {
372
376
  validateCondition(condition, true, false);
373
377
  if (!condition.attr) {
374
- throw new Error(`Attribute is required for ${condition.type} condition`);
378
+ throw chunkELULXDSB_cjs.ExpressionErrors.missingAttribute(condition.type, condition);
375
379
  }
376
380
  const attrName = generateAttributeName(params, condition.attr);
377
381
  return `${functionName}(${attrName})`;
378
382
  };
379
383
  var buildLogicalExpression = (operator, conditions, params) => {
380
384
  if (!conditions || conditions.length === 0) {
381
- throw new Error(`At least one condition is required for ${operator} expression`);
385
+ throw chunkELULXDSB_cjs.ExpressionErrors.emptyArray(operator, conditions);
382
386
  }
383
387
  const expressions = conditions.map((c) => buildExpression(c, params));
384
388
  return `(${expressions.join(` ${operator} `)})`;
385
389
  };
386
390
  var buildExpression = (condition, params) => {
387
391
  if (!condition) return "";
388
- try {
389
- const expressionBuilders = {
390
- eq: () => buildComparisonExpression(condition, "=", params),
391
- ne: () => buildComparisonExpression(condition, "<>", params),
392
- lt: () => buildComparisonExpression(condition, "<", params),
393
- lte: () => buildComparisonExpression(condition, "<=", params),
394
- gt: () => buildComparisonExpression(condition, ">", params),
395
- gte: () => buildComparisonExpression(condition, ">=", params),
396
- between: () => buildBetweenExpression(condition, params),
397
- in: () => buildInExpression(condition, params),
398
- beginsWith: () => buildFunctionExpression("begins_with", condition, params),
399
- contains: () => buildFunctionExpression("contains", condition, params),
400
- attributeExists: () => buildAttributeFunction("attribute_exists", condition, params),
401
- attributeNotExists: () => buildAttributeFunction("attribute_not_exists", condition, params),
402
- and: () => {
403
- if (!condition.conditions) {
404
- throw new Error("Conditions array is required for AND operator");
405
- }
406
- return buildLogicalExpression("AND", condition.conditions, params);
407
- },
408
- or: () => {
409
- if (!condition.conditions) {
410
- throw new Error("Conditions array is required for OR operator");
411
- }
412
- return buildLogicalExpression("OR", condition.conditions, params);
413
- },
414
- not: () => {
415
- if (!condition.condition) {
416
- throw new Error("Condition is required for NOT operator");
417
- }
418
- return `NOT (${buildExpression(condition.condition, params)})`;
392
+ const expressionBuilders = {
393
+ eq: () => buildComparisonExpression(condition, "=", params),
394
+ ne: () => buildComparisonExpression(condition, "<>", params),
395
+ lt: () => buildComparisonExpression(condition, "<", params),
396
+ lte: () => buildComparisonExpression(condition, "<=", params),
397
+ gt: () => buildComparisonExpression(condition, ">", params),
398
+ gte: () => buildComparisonExpression(condition, ">=", params),
399
+ between: () => buildBetweenExpression(condition, params),
400
+ in: () => buildInExpression(condition, params),
401
+ beginsWith: () => buildFunctionExpression("begins_with", condition, params),
402
+ contains: () => buildFunctionExpression("contains", condition, params),
403
+ attributeExists: () => buildAttributeFunction("attribute_exists", condition, params),
404
+ attributeNotExists: () => buildAttributeFunction("attribute_not_exists", condition, params),
405
+ and: () => {
406
+ if (!condition.conditions) {
407
+ throw chunkELULXDSB_cjs.ExpressionErrors.invalidCondition(
408
+ condition.type,
409
+ condition,
410
+ "Provide an array of conditions to combine with AND"
411
+ );
419
412
  }
420
- };
421
- const builder = expressionBuilders[condition.type];
422
- if (!builder) {
423
- throw new Error(`Unknown condition type: ${condition.type}`);
424
- }
425
- return builder();
426
- } catch (error) {
427
- if (error instanceof Error) {
428
- console.error(`Error building expression for condition type ${condition.type}:`, error.message);
429
- } else {
430
- console.error(`Error building expression for condition type ${condition.type}:`, error);
413
+ return buildLogicalExpression("AND", condition.conditions, params);
414
+ },
415
+ or: () => {
416
+ if (!condition.conditions) {
417
+ throw chunkELULXDSB_cjs.ExpressionErrors.invalidCondition(
418
+ condition.type,
419
+ condition,
420
+ "Provide an array of conditions to combine with OR"
421
+ );
422
+ }
423
+ return buildLogicalExpression("OR", condition.conditions, params);
424
+ },
425
+ not: () => {
426
+ if (!condition.condition) {
427
+ throw chunkELULXDSB_cjs.ExpressionErrors.invalidCondition(condition.type, condition, "Provide a condition to negate with NOT");
428
+ }
429
+ return `NOT (${buildExpression(condition.condition, params)})`;
431
430
  }
432
- throw error;
431
+ };
432
+ const builder = expressionBuilders[condition.type];
433
+ if (!builder) {
434
+ throw chunkELULXDSB_cjs.ExpressionErrors.unknownType(condition.type, condition);
433
435
  }
436
+ return builder();
434
437
  };
435
438
  var prepareExpressionParams = (condition) => {
436
439
  if (!condition) return {};
@@ -1464,6 +1467,32 @@ var FilterBuilder = class {
1464
1467
  this.options.lastEvaluatedKey = lastEvaluatedKey;
1465
1468
  return this;
1466
1469
  }
1470
+ /**
1471
+ * Executes the operation and returns the first matching item, if any.
1472
+ *
1473
+ * This helper:
1474
+ * - Applies an internal limit of 1
1475
+ * - Streams results until a match is found or there are no more pages
1476
+ * - Avoids mutating the current builder by using a clone
1477
+ *
1478
+ * @example
1479
+ * ```typescript
1480
+ * const latest = await table
1481
+ * .query(eq("moduleId", moduleId))
1482
+ * .useIndex("module-version-index")
1483
+ * .sortDescending()
1484
+ * .findOne();
1485
+ * ```
1486
+ *
1487
+ * @returns The first matching item, or undefined if none found
1488
+ */
1489
+ async findOne() {
1490
+ const iterator = await this.clone().limit(1).execute();
1491
+ for await (const item of iterator) {
1492
+ return item;
1493
+ }
1494
+ return void 0;
1495
+ }
1467
1496
  };
1468
1497
 
1469
1498
  // src/builders/result-iterator.ts
@@ -1537,10 +1566,13 @@ var QueryBuilder = class _QueryBuilder extends FilterBuilder {
1537
1566
  keyCondition;
1538
1567
  options = {};
1539
1568
  executor;
1540
- constructor(executor, keyCondition) {
1569
+ includeIndexAttributes = false;
1570
+ indexAttributeNames;
1571
+ constructor(executor, keyCondition, indexAttributeNames = []) {
1541
1572
  super();
1542
1573
  this.executor = executor;
1543
1574
  this.keyCondition = keyCondition;
1575
+ this.indexAttributeNames = indexAttributeNames;
1544
1576
  }
1545
1577
  /**
1546
1578
  * Sets the maximum number of items to return from the query.
@@ -1613,6 +1645,24 @@ var QueryBuilder = class _QueryBuilder extends FilterBuilder {
1613
1645
  this.options.scanIndexForward = false;
1614
1646
  return this;
1615
1647
  }
1648
+ /**
1649
+ * Ensures index attributes are included in the result.
1650
+ * By default, index attributes are removed from query responses.
1651
+ */
1652
+ includeIndexes() {
1653
+ this.includeIndexAttributes = true;
1654
+ if (this.selectedFields.size > 0) {
1655
+ this.addIndexAttributesToSelection();
1656
+ }
1657
+ return this;
1658
+ }
1659
+ select(fields) {
1660
+ super.select(fields);
1661
+ if (this.includeIndexAttributes) {
1662
+ this.addIndexAttributesToSelection();
1663
+ }
1664
+ return this;
1665
+ }
1616
1666
  /**
1617
1667
  * Creates a deep clone of this QueryBuilder instance.
1618
1668
  *
@@ -1647,12 +1697,13 @@ var QueryBuilder = class _QueryBuilder extends FilterBuilder {
1647
1697
  * @returns A new QueryBuilder instance with the same configuration
1648
1698
  */
1649
1699
  clone() {
1650
- const clone = new _QueryBuilder(this.executor, this.keyCondition);
1700
+ const clone = new _QueryBuilder(this.executor, this.keyCondition, this.indexAttributeNames);
1651
1701
  clone.options = {
1652
1702
  ...this.options,
1653
1703
  filter: this.deepCloneFilter(this.options.filter)
1654
1704
  };
1655
1705
  clone.selectedFields = new Set(this.selectedFields);
1706
+ clone.includeIndexAttributes = this.includeIndexAttributes;
1656
1707
  return clone;
1657
1708
  }
1658
1709
  deepCloneFilter(filter) {
@@ -1704,9 +1755,39 @@ var QueryBuilder = class _QueryBuilder extends FilterBuilder {
1704
1755
  * @returns A promise that resolves to a ResultGenerator that behaves like an array
1705
1756
  */
1706
1757
  async execute() {
1707
- const directExecutor = () => this.executor(this.keyCondition, this.options);
1758
+ const directExecutor = async () => {
1759
+ const result = await this.executor(this.keyCondition, this.options);
1760
+ if (this.includeIndexAttributes || this.indexAttributeNames.length === 0) {
1761
+ return result;
1762
+ }
1763
+ return {
1764
+ ...result,
1765
+ items: result.items.map((item) => this.omitIndexAttributes(item))
1766
+ };
1767
+ };
1708
1768
  return new ResultIterator(this, directExecutor);
1709
1769
  }
1770
+ addIndexAttributesToSelection() {
1771
+ if (this.indexAttributeNames.length === 0) return;
1772
+ for (const attributeName of this.indexAttributeNames) {
1773
+ this.selectedFields.add(attributeName);
1774
+ }
1775
+ this.options.projection = Array.from(this.selectedFields);
1776
+ }
1777
+ omitIndexAttributes(item) {
1778
+ if (this.indexAttributeNames.length === 0) {
1779
+ return item;
1780
+ }
1781
+ let didOmit = false;
1782
+ const cleaned = { ...item };
1783
+ for (const attributeName of this.indexAttributeNames) {
1784
+ if (attributeName in cleaned) {
1785
+ delete cleaned[attributeName];
1786
+ didOmit = true;
1787
+ }
1788
+ }
1789
+ return didOmit ? cleaned : item;
1790
+ }
1710
1791
  };
1711
1792
 
1712
1793
  // src/utils/debug-transaction.ts
@@ -1757,7 +1838,7 @@ var TransactionBuilder = class {
1757
1838
  const pkValue = newItem[pkName];
1758
1839
  const skValue = skName ? newItem[skName] : void 0;
1759
1840
  if (!pkValue) {
1760
- throw new Error(`Primary key value for '${pkName}' is missing`);
1841
+ throw chunkELULXDSB_cjs.ConfigurationErrors.primaryKeyMissing(tableName, pkName, newItem);
1761
1842
  }
1762
1843
  const duplicateItem = this.items.find((item) => {
1763
1844
  let itemKey;
@@ -1789,8 +1870,10 @@ var TransactionBuilder = class {
1789
1870
  return false;
1790
1871
  });
1791
1872
  if (duplicateItem) {
1792
- throw new Error(
1793
- `Duplicate item detected in transaction: Table=${tableName}, ${pkName}=${String(pkValue)}, ${skName}=${skValue !== void 0 ? String(skValue) : "undefined"}. DynamoDB transactions do not allow multiple operations on the same item.`
1873
+ throw chunkELULXDSB_cjs.TransactionErrors.duplicateItem(
1874
+ tableName,
1875
+ { name: pkName, value: pkValue },
1876
+ skName ? { name: skName, value: skValue } : void 0
1794
1877
  );
1795
1878
  }
1796
1879
  }
@@ -1800,7 +1883,7 @@ var TransactionBuilder = class {
1800
1883
  };
1801
1884
  if (this.indexConfig.sortKey) {
1802
1885
  if (key.sk === void 0) {
1803
- throw new Error("Sort key is required for delete operation");
1886
+ throw chunkELULXDSB_cjs.ConfigurationErrors.sortKeyRequired("", this.indexConfig.partitionKey, this.indexConfig.sortKey);
1804
1887
  }
1805
1888
  keyCondition[this.indexConfig.sortKey] = key.sk;
1806
1889
  }
@@ -2174,7 +2257,7 @@ var TransactionBuilder = class {
2174
2257
  this.checkForDuplicateItem(tableName, keyCondition);
2175
2258
  const { expression, names, values } = prepareExpressionParams(condition);
2176
2259
  if (!expression) {
2177
- throw new Error("Failed to generate condition expression");
2260
+ throw chunkELULXDSB_cjs.ConfigurationErrors.conditionGenerationFailed(condition);
2178
2261
  }
2179
2262
  const transactionItem = {
2180
2263
  type: "ConditionCheck",
@@ -2328,7 +2411,7 @@ var TransactionBuilder = class {
2328
2411
  */
2329
2412
  async execute() {
2330
2413
  if (this.items.length === 0) {
2331
- throw new Error("No transaction items specified");
2414
+ throw chunkELULXDSB_cjs.TransactionErrors.transactionEmpty();
2332
2415
  }
2333
2416
  const transactItems = this.items.map((item) => {
2334
2417
  switch (item.type) {
@@ -2375,7 +2458,7 @@ var TransactionBuilder = class {
2375
2458
  };
2376
2459
  default: {
2377
2460
  const exhaustiveCheck = item;
2378
- throw new Error(`Unsupported transaction item type: ${String(exhaustiveCheck)}`);
2461
+ throw chunkELULXDSB_cjs.TransactionErrors.unsupportedType(exhaustiveCheck);
2379
2462
  }
2380
2463
  }
2381
2464
  });
@@ -2388,9 +2471,7 @@ var TransactionBuilder = class {
2388
2471
  try {
2389
2472
  await this.executor(params);
2390
2473
  } catch (error) {
2391
- console.log(this.debug());
2392
- console.error("Error executing transaction:", error);
2393
- throw error;
2474
+ throw chunkELULXDSB_cjs.TransactionErrors.transactionFailed(this.items.length, {}, error instanceof Error ? error : void 0);
2394
2475
  }
2395
2476
  }
2396
2477
  };
@@ -2412,6 +2493,9 @@ var UpdateBuilder = class {
2412
2493
  set(valuesOrPath, value) {
2413
2494
  if (typeof valuesOrPath === "object") {
2414
2495
  for (const [key, value2] of Object.entries(valuesOrPath)) {
2496
+ if (value2 === void 0) {
2497
+ throw chunkELULXDSB_cjs.ValidationErrors.undefinedValue(key, this.tableName, this.key);
2498
+ }
2415
2499
  this.updates.push({
2416
2500
  type: "SET",
2417
2501
  path: key,
@@ -2419,6 +2503,9 @@ var UpdateBuilder = class {
2419
2503
  });
2420
2504
  }
2421
2505
  } else {
2506
+ if (value === void 0) {
2507
+ throw chunkELULXDSB_cjs.ValidationErrors.undefinedValue(valuesOrPath, this.tableName, this.key);
2508
+ }
2422
2509
  this.updates.push({
2423
2510
  type: "SET",
2424
2511
  path: valuesOrPath,
@@ -2474,6 +2561,9 @@ var UpdateBuilder = class {
2474
2561
  * @returns The builder instance for method chaining
2475
2562
  */
2476
2563
  add(path, value) {
2564
+ if (value === void 0) {
2565
+ throw chunkELULXDSB_cjs.ValidationErrors.undefinedValue(path, this.tableName, this.key);
2566
+ }
2477
2567
  this.updates.push({
2478
2568
  type: "ADD",
2479
2569
  path,
@@ -2510,6 +2600,9 @@ var UpdateBuilder = class {
2510
2600
  * @returns The builder instance for method chaining
2511
2601
  */
2512
2602
  deleteElementsFromSet(path, value) {
2603
+ if (value === void 0) {
2604
+ throw chunkELULXDSB_cjs.ValidationErrors.undefinedValue(path, this.tableName, this.key);
2605
+ }
2513
2606
  let valuesToDelete;
2514
2607
  if (Array.isArray(value)) {
2515
2608
  valuesToDelete = new Set(value);
@@ -2628,7 +2721,7 @@ var UpdateBuilder = class {
2628
2721
  */
2629
2722
  toDynamoCommand() {
2630
2723
  if (this.updates.length === 0) {
2631
- throw new Error("No update actions specified");
2724
+ throw chunkELULXDSB_cjs.ValidationErrors.noUpdateActions(this.tableName, this.key);
2632
2725
  }
2633
2726
  const expressionParams = {
2634
2727
  expressionAttributeNames: {},
@@ -2902,11 +2995,11 @@ var ConditionCheckBuilder = class {
2902
2995
  */
2903
2996
  toDynamoCommand() {
2904
2997
  if (!this.conditionExpression) {
2905
- throw new Error("Condition is required for condition check operations");
2998
+ throw chunkELULXDSB_cjs.ValidationErrors.conditionRequired(this.tableName, this.key);
2906
2999
  }
2907
3000
  const { expression, names, values } = prepareExpressionParams(this.conditionExpression);
2908
3001
  if (!expression) {
2909
- throw new Error("Failed to generate condition expression");
3002
+ throw chunkELULXDSB_cjs.ConfigurationErrors.conditionGenerationFailed(this.conditionExpression);
2910
3003
  }
2911
3004
  return {
2912
3005
  tableName: this.tableName,
@@ -2938,7 +3031,7 @@ var ConditionCheckBuilder = class {
2938
3031
  */
2939
3032
  withTransaction(transaction) {
2940
3033
  if (!this.conditionExpression) {
2941
- throw new Error("Condition is required for condition check operations");
3034
+ throw chunkELULXDSB_cjs.ValidationErrors.conditionRequired(this.tableName, this.key);
2942
3035
  }
2943
3036
  const command = this.toDynamoCommand();
2944
3037
  transaction.conditionCheckWithCommand(command);
@@ -2978,16 +3071,19 @@ var GetBuilder = class {
2978
3071
  * @param key - Primary key of the item to retrieve
2979
3072
  * @param tableName - Name of the DynamoDB table
2980
3073
  */
2981
- constructor(executor, key, tableName) {
3074
+ constructor(executor, key, tableName, indexAttributeNames = []) {
2982
3075
  this.executor = executor;
2983
3076
  this.params = {
2984
3077
  tableName,
2985
3078
  key
2986
3079
  };
3080
+ this.indexAttributeNames = indexAttributeNames;
2987
3081
  }
2988
3082
  params;
2989
3083
  options = {};
2990
3084
  selectedFields = /* @__PURE__ */ new Set();
3085
+ includeIndexAttributes = false;
3086
+ indexAttributeNames;
2991
3087
  /**
2992
3088
  * Specifies which attributes to return in the get results.
2993
3089
  *
@@ -3016,9 +3112,23 @@ var GetBuilder = class {
3016
3112
  this.selectedFields.add(field);
3017
3113
  }
3018
3114
  }
3115
+ if (this.includeIndexAttributes) {
3116
+ this.addIndexAttributesToSelection();
3117
+ }
3019
3118
  this.options.projection = Array.from(this.selectedFields);
3020
3119
  return this;
3021
3120
  }
3121
+ /**
3122
+ * Ensures index attributes are included in the result.
3123
+ * By default, index attributes are removed from get responses.
3124
+ */
3125
+ includeIndexes() {
3126
+ this.includeIndexAttributes = true;
3127
+ if (this.selectedFields.size > 0) {
3128
+ this.addIndexAttributesToSelection();
3129
+ }
3130
+ return this;
3131
+ }
3022
3132
  /**
3023
3133
  * Sets whether to use strongly consistent reads for the get operation.
3024
3134
  * Use this method when you need:
@@ -3097,6 +3207,27 @@ var GetBuilder = class {
3097
3207
  expressionAttributeNames: Object.keys(expressionAttributeNames).length > 0 ? expressionAttributeNames : void 0
3098
3208
  };
3099
3209
  }
3210
+ addIndexAttributesToSelection() {
3211
+ if (this.indexAttributeNames.length === 0) return;
3212
+ for (const attributeName of this.indexAttributeNames) {
3213
+ this.selectedFields.add(attributeName);
3214
+ }
3215
+ this.options.projection = Array.from(this.selectedFields);
3216
+ }
3217
+ omitIndexAttributes(item) {
3218
+ if (!item || this.includeIndexAttributes || this.indexAttributeNames.length === 0) {
3219
+ return item;
3220
+ }
3221
+ let didOmit = false;
3222
+ const cleaned = { ...item };
3223
+ for (const attributeName of this.indexAttributeNames) {
3224
+ if (attributeName in cleaned) {
3225
+ delete cleaned[attributeName];
3226
+ didOmit = true;
3227
+ }
3228
+ }
3229
+ return didOmit ? cleaned : item;
3230
+ }
3100
3231
  /**
3101
3232
  * Executes the get operation against DynamoDB.
3102
3233
  *
@@ -3123,7 +3254,10 @@ var GetBuilder = class {
3123
3254
  */
3124
3255
  async execute() {
3125
3256
  const command = this.toDynamoCommand();
3126
- return this.executor(command);
3257
+ const result = await this.executor(command);
3258
+ return {
3259
+ item: this.omitIndexAttributes(result.item)
3260
+ };
3127
3261
  }
3128
3262
  };
3129
3263
 
@@ -3200,7 +3334,6 @@ var ScanBuilder = class _ScanBuilder extends FilterBuilder {
3200
3334
  };
3201
3335
 
3202
3336
  exports.BatchBuilder = BatchBuilder;
3203
- exports.BatchError = BatchError;
3204
3337
  exports.ConditionCheckBuilder = ConditionCheckBuilder;
3205
3338
  exports.DeleteBuilder = DeleteBuilder;
3206
3339
  exports.FilterBuilder = FilterBuilder;
@@ -3213,5 +3346,4 @@ exports.ScanBuilder = ScanBuilder;
3213
3346
  exports.TransactionBuilder = TransactionBuilder;
3214
3347
  exports.UpdateBuilder = UpdateBuilder;
3215
3348
  exports.buildExpression = buildExpression;
3216
- exports.debugCommand = debugCommand;
3217
3349
  exports.generateAttributeName = generateAttributeName;