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