dyno-table 2.4.0 → 2.5.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.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkAHF4H42Q_cjs = require('./chunk-AHF4H42Q.cjs');
3
+ var chunk3DR6VOFW_cjs = require('./chunk-3DR6VOFW.cjs');
4
4
  require('./chunk-ELULXDSB.cjs');
5
5
  require('./chunk-7UJJ7JXM.cjs');
6
6
 
@@ -8,49 +8,49 @@ require('./chunk-7UJJ7JXM.cjs');
8
8
 
9
9
  Object.defineProperty(exports, "BatchBuilder", {
10
10
  enumerable: true,
11
- get: function () { return chunkAHF4H42Q_cjs.BatchBuilder; }
11
+ get: function () { return chunk3DR6VOFW_cjs.BatchBuilder; }
12
12
  });
13
13
  Object.defineProperty(exports, "ConditionCheckBuilder", {
14
14
  enumerable: true,
15
- get: function () { return chunkAHF4H42Q_cjs.ConditionCheckBuilder; }
15
+ get: function () { return chunk3DR6VOFW_cjs.ConditionCheckBuilder; }
16
16
  });
17
17
  Object.defineProperty(exports, "DeleteBuilder", {
18
18
  enumerable: true,
19
- get: function () { return chunkAHF4H42Q_cjs.DeleteBuilder; }
19
+ get: function () { return chunk3DR6VOFW_cjs.DeleteBuilder; }
20
20
  });
21
21
  Object.defineProperty(exports, "FilterBuilder", {
22
22
  enumerable: true,
23
- get: function () { return chunkAHF4H42Q_cjs.FilterBuilder; }
23
+ get: function () { return chunk3DR6VOFW_cjs.FilterBuilder; }
24
24
  });
25
25
  Object.defineProperty(exports, "GetBuilder", {
26
26
  enumerable: true,
27
- get: function () { return chunkAHF4H42Q_cjs.GetBuilder; }
27
+ get: function () { return chunk3DR6VOFW_cjs.GetBuilder; }
28
28
  });
29
29
  Object.defineProperty(exports, "Paginator", {
30
30
  enumerable: true,
31
- get: function () { return chunkAHF4H42Q_cjs.Paginator; }
31
+ get: function () { return chunk3DR6VOFW_cjs.Paginator; }
32
32
  });
33
33
  Object.defineProperty(exports, "PutBuilder", {
34
34
  enumerable: true,
35
- get: function () { return chunkAHF4H42Q_cjs.PutBuilder; }
35
+ get: function () { return chunk3DR6VOFW_cjs.PutBuilder; }
36
36
  });
37
37
  Object.defineProperty(exports, "QueryBuilder", {
38
38
  enumerable: true,
39
- get: function () { return chunkAHF4H42Q_cjs.QueryBuilder; }
39
+ get: function () { return chunk3DR6VOFW_cjs.QueryBuilder; }
40
40
  });
41
41
  Object.defineProperty(exports, "ResultIterator", {
42
42
  enumerable: true,
43
- get: function () { return chunkAHF4H42Q_cjs.ResultIterator; }
43
+ get: function () { return chunk3DR6VOFW_cjs.ResultIterator; }
44
44
  });
45
45
  Object.defineProperty(exports, "ScanBuilder", {
46
46
  enumerable: true,
47
- get: function () { return chunkAHF4H42Q_cjs.ScanBuilder; }
47
+ get: function () { return chunk3DR6VOFW_cjs.ScanBuilder; }
48
48
  });
49
49
  Object.defineProperty(exports, "TransactionBuilder", {
50
50
  enumerable: true,
51
- get: function () { return chunkAHF4H42Q_cjs.TransactionBuilder; }
51
+ get: function () { return chunk3DR6VOFW_cjs.TransactionBuilder; }
52
52
  });
53
53
  Object.defineProperty(exports, "UpdateBuilder", {
54
54
  enumerable: true,
55
- get: function () { return chunkAHF4H42Q_cjs.UpdateBuilder; }
55
+ get: function () { return chunk3DR6VOFW_cjs.UpdateBuilder; }
56
56
  });
@@ -1,4 +1,4 @@
1
- export { u as BaseBuilderInterface, B as BatchBuilder, C as ConditionCheckBuilder, t as ConditionCheckCommandParams, D as DeleteBuilder, r as DeleteCommandParams, F as FilterBuilder, x as FilterBuilderInterface, G as GetBuilder, y as PaginationResult, q as Paginator, P as PutBuilder, s as PutCommandParams, Q as QueryBuilder, v as QueryBuilderInterface, R as ResultIterator, S as ScanBuilder, w as ScanBuilderInterface, T as TransactionBuilder, z as TransactionItem, U as UpdateBuilder, p as UpdateCommandParams } from './index-BX-MSZHj.cjs';
1
+ export { q as BaseBuilderInterface, B as BatchBuilder, C as ConditionCheckBuilder, r as ConditionCheckCommandParams, D as DeleteBuilder, s as DeleteCommandParams, F as FilterBuilder, t as FilterBuilderInterface, G as GetBuilder, u as PaginationResult, v as Paginator, P as PutBuilder, w as PutCommandParams, Q as QueryBuilder, x as QueryBuilderInterface, R as ResultIterator, S as ScanBuilder, y as ScanBuilderInterface, T as TransactionBuilder, z as TransactionItem, U as UpdateBuilder, p as UpdateCommandParams } from './index-CPCmWsEv.cjs';
2
2
  export { s as Path, t as PathType } from './conditions-C8bM__Pn.cjs';
3
3
  import './types.cjs';
4
4
  import '@aws-sdk/lib-dynamodb';
@@ -1,4 +1,4 @@
1
- export { u as BaseBuilderInterface, B as BatchBuilder, C as ConditionCheckBuilder, t as ConditionCheckCommandParams, D as DeleteBuilder, r as DeleteCommandParams, F as FilterBuilder, x as FilterBuilderInterface, G as GetBuilder, y as PaginationResult, q as Paginator, P as PutBuilder, s as PutCommandParams, Q as QueryBuilder, v as QueryBuilderInterface, R as ResultIterator, S as ScanBuilder, w as ScanBuilderInterface, T as TransactionBuilder, z as TransactionItem, U as UpdateBuilder, p as UpdateCommandParams } from './index-DdTolMJW.js';
1
+ export { q as BaseBuilderInterface, B as BatchBuilder, C as ConditionCheckBuilder, r as ConditionCheckCommandParams, D as DeleteBuilder, s as DeleteCommandParams, F as FilterBuilder, t as FilterBuilderInterface, G as GetBuilder, u as PaginationResult, v as Paginator, P as PutBuilder, w as PutCommandParams, Q as QueryBuilder, x as QueryBuilderInterface, R as ResultIterator, S as ScanBuilder, y as ScanBuilderInterface, T as TransactionBuilder, z as TransactionItem, U as UpdateBuilder, p as UpdateCommandParams } from './index-Bc-ra0im.js';
2
2
  export { s as Path, t as PathType } from './conditions-BSAcZswY.js';
3
3
  import './types.js';
4
4
  import '@aws-sdk/lib-dynamodb';
package/dist/builders.js CHANGED
@@ -1,3 +1,3 @@
1
- export { BatchBuilder, ConditionCheckBuilder, DeleteBuilder, FilterBuilder, GetBuilder, Paginator, PutBuilder, QueryBuilder, ResultIterator, ScanBuilder, TransactionBuilder, UpdateBuilder } from './chunk-GWHGUKAL.js';
1
+ export { BatchBuilder, ConditionCheckBuilder, DeleteBuilder, FilterBuilder, GetBuilder, Paginator, PutBuilder, QueryBuilder, ResultIterator, ScanBuilder, TransactionBuilder, UpdateBuilder } from './chunk-NYJGW3XH.js';
2
2
  import './chunk-FF7FYGDH.js';
3
3
  import './chunk-2WIBY7PZ.js';
@@ -1467,6 +1467,32 @@ var FilterBuilder = class {
1467
1467
  this.options.lastEvaluatedKey = lastEvaluatedKey;
1468
1468
  return this;
1469
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
+ }
1470
1496
  };
1471
1497
 
1472
1498
  // src/builders/result-iterator.ts
@@ -1540,10 +1566,13 @@ var QueryBuilder = class _QueryBuilder extends FilterBuilder {
1540
1566
  keyCondition;
1541
1567
  options = {};
1542
1568
  executor;
1543
- constructor(executor, keyCondition) {
1569
+ includeIndexAttributes = false;
1570
+ indexAttributeNames;
1571
+ constructor(executor, keyCondition, indexAttributeNames = []) {
1544
1572
  super();
1545
1573
  this.executor = executor;
1546
1574
  this.keyCondition = keyCondition;
1575
+ this.indexAttributeNames = indexAttributeNames;
1547
1576
  }
1548
1577
  /**
1549
1578
  * Sets the maximum number of items to return from the query.
@@ -1616,6 +1645,24 @@ var QueryBuilder = class _QueryBuilder extends FilterBuilder {
1616
1645
  this.options.scanIndexForward = false;
1617
1646
  return this;
1618
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
+ }
1619
1666
  /**
1620
1667
  * Creates a deep clone of this QueryBuilder instance.
1621
1668
  *
@@ -1650,12 +1697,13 @@ var QueryBuilder = class _QueryBuilder extends FilterBuilder {
1650
1697
  * @returns A new QueryBuilder instance with the same configuration
1651
1698
  */
1652
1699
  clone() {
1653
- const clone = new _QueryBuilder(this.executor, this.keyCondition);
1700
+ const clone = new _QueryBuilder(this.executor, this.keyCondition, this.indexAttributeNames);
1654
1701
  clone.options = {
1655
1702
  ...this.options,
1656
1703
  filter: this.deepCloneFilter(this.options.filter)
1657
1704
  };
1658
1705
  clone.selectedFields = new Set(this.selectedFields);
1706
+ clone.includeIndexAttributes = this.includeIndexAttributes;
1659
1707
  return clone;
1660
1708
  }
1661
1709
  deepCloneFilter(filter) {
@@ -1707,9 +1755,39 @@ var QueryBuilder = class _QueryBuilder extends FilterBuilder {
1707
1755
  * @returns A promise that resolves to a ResultGenerator that behaves like an array
1708
1756
  */
1709
1757
  async execute() {
1710
- 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
+ };
1711
1768
  return new ResultIterator(this, directExecutor);
1712
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
+ }
1713
1791
  };
1714
1792
 
1715
1793
  // src/utils/debug-transaction.ts
@@ -2993,16 +3071,19 @@ var GetBuilder = class {
2993
3071
  * @param key - Primary key of the item to retrieve
2994
3072
  * @param tableName - Name of the DynamoDB table
2995
3073
  */
2996
- constructor(executor, key, tableName) {
3074
+ constructor(executor, key, tableName, indexAttributeNames = []) {
2997
3075
  this.executor = executor;
2998
3076
  this.params = {
2999
3077
  tableName,
3000
3078
  key
3001
3079
  };
3080
+ this.indexAttributeNames = indexAttributeNames;
3002
3081
  }
3003
3082
  params;
3004
3083
  options = {};
3005
3084
  selectedFields = /* @__PURE__ */ new Set();
3085
+ includeIndexAttributes = false;
3086
+ indexAttributeNames;
3006
3087
  /**
3007
3088
  * Specifies which attributes to return in the get results.
3008
3089
  *
@@ -3031,9 +3112,23 @@ var GetBuilder = class {
3031
3112
  this.selectedFields.add(field);
3032
3113
  }
3033
3114
  }
3115
+ if (this.includeIndexAttributes) {
3116
+ this.addIndexAttributesToSelection();
3117
+ }
3034
3118
  this.options.projection = Array.from(this.selectedFields);
3035
3119
  return this;
3036
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
+ }
3037
3132
  /**
3038
3133
  * Sets whether to use strongly consistent reads for the get operation.
3039
3134
  * Use this method when you need:
@@ -3112,6 +3207,27 @@ var GetBuilder = class {
3112
3207
  expressionAttributeNames: Object.keys(expressionAttributeNames).length > 0 ? expressionAttributeNames : void 0
3113
3208
  };
3114
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
+ }
3115
3231
  /**
3116
3232
  * Executes the get operation against DynamoDB.
3117
3233
  *
@@ -3138,7 +3254,10 @@ var GetBuilder = class {
3138
3254
  */
3139
3255
  async execute() {
3140
3256
  const command = this.toDynamoCommand();
3141
- return this.executor(command);
3257
+ const result = await this.executor(command);
3258
+ return {
3259
+ item: this.omitIndexAttributes(result.item)
3260
+ };
3142
3261
  }
3143
3262
  };
3144
3263
 
@@ -1,4 +1,4 @@
1
- import { GetBuilder, PutBuilder, QueryBuilder, ScanBuilder, DeleteBuilder, UpdateBuilder, TransactionBuilder, BatchBuilder, ConditionCheckBuilder, buildExpression, generateAttributeName } from './chunk-GWHGUKAL.js';
1
+ import { GetBuilder, PutBuilder, QueryBuilder, ScanBuilder, DeleteBuilder, UpdateBuilder, TransactionBuilder, BatchBuilder, ConditionCheckBuilder, buildExpression, generateAttributeName } from './chunk-NYJGW3XH.js';
2
2
  import { ConfigurationErrors, OperationErrors } from './chunk-FF7FYGDH.js';
3
3
  import { eq, and, beginsWith, between, gte, gt, lte, lt } from './chunk-2WIBY7PZ.js';
4
4
 
@@ -37,6 +37,16 @@ var Table = class {
37
37
  this.sortKey = config.indexes.sortKey;
38
38
  this.gsis = config.indexes.gsis || {};
39
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
+ }
40
50
  createKeyForPrimaryIndex(keyCondition) {
41
51
  const primaryCondition = { [this.partitionKey]: keyCondition.pk };
42
52
  if (this.sortKey) {
@@ -82,6 +92,7 @@ var Table = class {
82
92
  return this.put(item).condition((op) => op.attributeNotExists(this.partitionKey)).returnValues("INPUT");
83
93
  }
84
94
  get(keyCondition) {
95
+ const indexAttributeNames = this.getIndexAttributeNames();
85
96
  const executor = async (params) => {
86
97
  try {
87
98
  const result = await this.dynamoClient.get({
@@ -98,7 +109,7 @@ var Table = class {
98
109
  throw OperationErrors.getFailed(params.tableName, keyCondition, error instanceof Error ? error : void 0);
99
110
  }
100
111
  };
101
- return new GetBuilder(executor, keyCondition, this.tableName);
112
+ return new GetBuilder(executor, keyCondition, this.tableName, indexAttributeNames);
102
113
  }
103
114
  /**
104
115
  * Updates an item in the table
@@ -145,6 +156,7 @@ var Table = class {
145
156
  * If useIndex is called on the returned QueryBuilder, it will use the GSI configuration
146
157
  */
147
158
  query(keyCondition) {
159
+ const indexAttributeNames = this.getIndexAttributeNames();
148
160
  const pkAttributeName = this.partitionKey;
149
161
  const skAttributeName = this.sortKey;
150
162
  let keyConditionExpression = eq(pkAttributeName, keyCondition.pk);
@@ -258,7 +270,7 @@ var Table = class {
258
270
  );
259
271
  }
260
272
  };
261
- return new QueryBuilder(executor, keyConditionExpression);
273
+ return new QueryBuilder(executor, keyConditionExpression, indexAttributeNames);
262
274
  }
263
275
  /**
264
276
  * Creates a scan builder for scanning the entire table
@@ -1465,6 +1465,32 @@ var FilterBuilder = class {
1465
1465
  this.options.lastEvaluatedKey = lastEvaluatedKey;
1466
1466
  return this;
1467
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
+ }
1468
1494
  };
1469
1495
 
1470
1496
  // src/builders/result-iterator.ts
@@ -1538,10 +1564,13 @@ var QueryBuilder = class _QueryBuilder extends FilterBuilder {
1538
1564
  keyCondition;
1539
1565
  options = {};
1540
1566
  executor;
1541
- constructor(executor, keyCondition) {
1567
+ includeIndexAttributes = false;
1568
+ indexAttributeNames;
1569
+ constructor(executor, keyCondition, indexAttributeNames = []) {
1542
1570
  super();
1543
1571
  this.executor = executor;
1544
1572
  this.keyCondition = keyCondition;
1573
+ this.indexAttributeNames = indexAttributeNames;
1545
1574
  }
1546
1575
  /**
1547
1576
  * Sets the maximum number of items to return from the query.
@@ -1614,6 +1643,24 @@ var QueryBuilder = class _QueryBuilder extends FilterBuilder {
1614
1643
  this.options.scanIndexForward = false;
1615
1644
  return this;
1616
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
+ }
1617
1664
  /**
1618
1665
  * Creates a deep clone of this QueryBuilder instance.
1619
1666
  *
@@ -1648,12 +1695,13 @@ var QueryBuilder = class _QueryBuilder extends FilterBuilder {
1648
1695
  * @returns A new QueryBuilder instance with the same configuration
1649
1696
  */
1650
1697
  clone() {
1651
- const clone = new _QueryBuilder(this.executor, this.keyCondition);
1698
+ const clone = new _QueryBuilder(this.executor, this.keyCondition, this.indexAttributeNames);
1652
1699
  clone.options = {
1653
1700
  ...this.options,
1654
1701
  filter: this.deepCloneFilter(this.options.filter)
1655
1702
  };
1656
1703
  clone.selectedFields = new Set(this.selectedFields);
1704
+ clone.includeIndexAttributes = this.includeIndexAttributes;
1657
1705
  return clone;
1658
1706
  }
1659
1707
  deepCloneFilter(filter) {
@@ -1705,9 +1753,39 @@ var QueryBuilder = class _QueryBuilder extends FilterBuilder {
1705
1753
  * @returns A promise that resolves to a ResultGenerator that behaves like an array
1706
1754
  */
1707
1755
  async execute() {
1708
- 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
+ };
1709
1766
  return new ResultIterator(this, directExecutor);
1710
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
+ }
1711
1789
  };
1712
1790
 
1713
1791
  // src/utils/debug-transaction.ts
@@ -2991,16 +3069,19 @@ var GetBuilder = class {
2991
3069
  * @param key - Primary key of the item to retrieve
2992
3070
  * @param tableName - Name of the DynamoDB table
2993
3071
  */
2994
- constructor(executor, key, tableName) {
3072
+ constructor(executor, key, tableName, indexAttributeNames = []) {
2995
3073
  this.executor = executor;
2996
3074
  this.params = {
2997
3075
  tableName,
2998
3076
  key
2999
3077
  };
3078
+ this.indexAttributeNames = indexAttributeNames;
3000
3079
  }
3001
3080
  params;
3002
3081
  options = {};
3003
3082
  selectedFields = /* @__PURE__ */ new Set();
3083
+ includeIndexAttributes = false;
3084
+ indexAttributeNames;
3004
3085
  /**
3005
3086
  * Specifies which attributes to return in the get results.
3006
3087
  *
@@ -3029,9 +3110,23 @@ var GetBuilder = class {
3029
3110
  this.selectedFields.add(field);
3030
3111
  }
3031
3112
  }
3113
+ if (this.includeIndexAttributes) {
3114
+ this.addIndexAttributesToSelection();
3115
+ }
3032
3116
  this.options.projection = Array.from(this.selectedFields);
3033
3117
  return this;
3034
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
+ }
3035
3130
  /**
3036
3131
  * Sets whether to use strongly consistent reads for the get operation.
3037
3132
  * Use this method when you need:
@@ -3110,6 +3205,27 @@ var GetBuilder = class {
3110
3205
  expressionAttributeNames: Object.keys(expressionAttributeNames).length > 0 ? expressionAttributeNames : void 0
3111
3206
  };
3112
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
+ }
3113
3229
  /**
3114
3230
  * Executes the get operation against DynamoDB.
3115
3231
  *
@@ -3136,7 +3252,10 @@ var GetBuilder = class {
3136
3252
  */
3137
3253
  async execute() {
3138
3254
  const command = this.toDynamoCommand();
3139
- return this.executor(command);
3255
+ const result = await this.executor(command);
3256
+ return {
3257
+ item: this.omitIndexAttributes(result.item)
3258
+ };
3140
3259
  }
3141
3260
  };
3142
3261
 
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkAHF4H42Q_cjs = require('./chunk-AHF4H42Q.cjs');
3
+ var chunk3DR6VOFW_cjs = require('./chunk-3DR6VOFW.cjs');
4
4
  var chunkELULXDSB_cjs = require('./chunk-ELULXDSB.cjs');
5
5
  var chunk7UJJ7JXM_cjs = require('./chunk-7UJJ7JXM.cjs');
6
6
 
@@ -39,6 +39,16 @@ var Table = class {
39
39
  this.sortKey = config.indexes.sortKey;
40
40
  this.gsis = config.indexes.gsis || {};
41
41
  }
42
+ getIndexAttributeNames() {
43
+ const names = /* @__PURE__ */ new Set();
44
+ for (const gsi of Object.values(this.gsis)) {
45
+ names.add(gsi.partitionKey);
46
+ if (gsi.sortKey) {
47
+ names.add(gsi.sortKey);
48
+ }
49
+ }
50
+ return Array.from(names);
51
+ }
42
52
  createKeyForPrimaryIndex(keyCondition) {
43
53
  const primaryCondition = { [this.partitionKey]: keyCondition.pk };
44
54
  if (this.sortKey) {
@@ -84,6 +94,7 @@ var Table = class {
84
94
  return this.put(item).condition((op) => op.attributeNotExists(this.partitionKey)).returnValues("INPUT");
85
95
  }
86
96
  get(keyCondition) {
97
+ const indexAttributeNames = this.getIndexAttributeNames();
87
98
  const executor = async (params) => {
88
99
  try {
89
100
  const result = await this.dynamoClient.get({
@@ -100,7 +111,7 @@ var Table = class {
100
111
  throw chunkELULXDSB_cjs.OperationErrors.getFailed(params.tableName, keyCondition, error instanceof Error ? error : void 0);
101
112
  }
102
113
  };
103
- return new chunkAHF4H42Q_cjs.GetBuilder(executor, keyCondition, this.tableName);
114
+ return new chunk3DR6VOFW_cjs.GetBuilder(executor, keyCondition, this.tableName, indexAttributeNames);
104
115
  }
105
116
  /**
106
117
  * Updates an item in the table
@@ -140,13 +151,14 @@ var Table = class {
140
151
  throw chunkELULXDSB_cjs.OperationErrors.putFailed(params.tableName, params.item, error instanceof Error ? error : void 0);
141
152
  }
142
153
  };
143
- return new chunkAHF4H42Q_cjs.PutBuilder(executor, item, this.tableName);
154
+ return new chunk3DR6VOFW_cjs.PutBuilder(executor, item, this.tableName);
144
155
  }
145
156
  /**
146
157
  * Creates a query builder for complex queries
147
158
  * If useIndex is called on the returned QueryBuilder, it will use the GSI configuration
148
159
  */
149
160
  query(keyCondition) {
161
+ const indexAttributeNames = this.getIndexAttributeNames();
150
162
  const pkAttributeName = this.partitionKey;
151
163
  const skAttributeName = this.sortKey;
152
164
  let keyConditionExpression = chunk7UJJ7JXM_cjs.eq(pkAttributeName, keyCondition.pk);
@@ -225,12 +237,12 @@ var Table = class {
225
237
  expressionAttributeValues: {},
226
238
  valueCounter: { count: 0 }
227
239
  };
228
- const keyConditionExpression2 = chunkAHF4H42Q_cjs.buildExpression(finalKeyCondition, expressionParams);
240
+ const keyConditionExpression2 = chunk3DR6VOFW_cjs.buildExpression(finalKeyCondition, expressionParams);
229
241
  let filterExpression;
230
242
  if (options.filter) {
231
- filterExpression = chunkAHF4H42Q_cjs.buildExpression(options.filter, expressionParams);
243
+ filterExpression = chunk3DR6VOFW_cjs.buildExpression(options.filter, expressionParams);
232
244
  }
233
- const projectionExpression = options.projection?.map((p) => chunkAHF4H42Q_cjs.generateAttributeName(expressionParams, p)).join(", ");
245
+ const projectionExpression = options.projection?.map((p) => chunk3DR6VOFW_cjs.generateAttributeName(expressionParams, p)).join(", ");
234
246
  const { expressionAttributeNames, expressionAttributeValues } = expressionParams;
235
247
  const { indexName, limit, consistentRead, scanIndexForward, lastEvaluatedKey } = options;
236
248
  const params = {
@@ -260,7 +272,7 @@ var Table = class {
260
272
  );
261
273
  }
262
274
  };
263
- return new chunkAHF4H42Q_cjs.QueryBuilder(executor, keyConditionExpression);
275
+ return new chunk3DR6VOFW_cjs.QueryBuilder(executor, keyConditionExpression, indexAttributeNames);
264
276
  }
265
277
  /**
266
278
  * Creates a scan builder for scanning the entire table
@@ -280,9 +292,9 @@ var Table = class {
280
292
  };
281
293
  let filterExpression;
282
294
  if (options.filter) {
283
- filterExpression = chunkAHF4H42Q_cjs.buildExpression(options.filter, expressionParams);
295
+ filterExpression = chunk3DR6VOFW_cjs.buildExpression(options.filter, expressionParams);
284
296
  }
285
- const projectionExpression = options.projection?.map((p) => chunkAHF4H42Q_cjs.generateAttributeName(expressionParams, p)).join(", ");
297
+ const projectionExpression = options.projection?.map((p) => chunk3DR6VOFW_cjs.generateAttributeName(expressionParams, p)).join(", ");
286
298
  const { expressionAttributeNames, expressionAttributeValues } = expressionParams;
287
299
  const { indexName, limit, consistentRead, lastEvaluatedKey } = options;
288
300
  const params = {
@@ -310,7 +322,7 @@ var Table = class {
310
322
  );
311
323
  }
312
324
  };
313
- return new chunkAHF4H42Q_cjs.ScanBuilder(executor);
325
+ return new chunk3DR6VOFW_cjs.ScanBuilder(executor);
314
326
  }
315
327
  delete(keyCondition) {
316
328
  const executor = async (params) => {
@@ -330,7 +342,7 @@ var Table = class {
330
342
  throw chunkELULXDSB_cjs.OperationErrors.deleteFailed(params.tableName, keyCondition, error instanceof Error ? error : void 0);
331
343
  }
332
344
  };
333
- return new chunkAHF4H42Q_cjs.DeleteBuilder(executor, this.tableName, keyCondition);
345
+ return new chunk3DR6VOFW_cjs.DeleteBuilder(executor, this.tableName, keyCondition);
334
346
  }
335
347
  /**
336
348
  * Updates an item in the table
@@ -357,7 +369,7 @@ var Table = class {
357
369
  throw chunkELULXDSB_cjs.OperationErrors.updateFailed(params.tableName, keyCondition, error instanceof Error ? error : void 0);
358
370
  }
359
371
  };
360
- return new chunkAHF4H42Q_cjs.UpdateBuilder(executor, this.tableName, keyCondition);
372
+ return new chunk3DR6VOFW_cjs.UpdateBuilder(executor, this.tableName, keyCondition);
361
373
  }
362
374
  /**
363
375
  * Creates a transaction builder for performing multiple operations atomically
@@ -366,7 +378,7 @@ var Table = class {
366
378
  const executor = async (params) => {
367
379
  await this.dynamoClient.transactWrite(params);
368
380
  };
369
- return new chunkAHF4H42Q_cjs.TransactionBuilder(executor, {
381
+ return new chunk3DR6VOFW_cjs.TransactionBuilder(executor, {
370
382
  partitionKey: this.partitionKey,
371
383
  sortKey: this.sortKey
372
384
  });
@@ -413,7 +425,7 @@ var Table = class {
413
425
  const batchGetExecutor = async (keys) => {
414
426
  return this.batchGet(keys);
415
427
  };
416
- return new chunkAHF4H42Q_cjs.BatchBuilder(batchWriteExecutor, batchGetExecutor, {
428
+ return new chunk3DR6VOFW_cjs.BatchBuilder(batchWriteExecutor, batchGetExecutor, {
417
429
  partitionKey: this.partitionKey,
418
430
  sortKey: this.sortKey
419
431
  });
@@ -429,7 +441,7 @@ var Table = class {
429
441
  const transactionExecutor = async (params) => {
430
442
  await this.dynamoClient.transactWrite(params);
431
443
  };
432
- const transaction = new chunkAHF4H42Q_cjs.TransactionBuilder(transactionExecutor, {
444
+ const transaction = new chunk3DR6VOFW_cjs.TransactionBuilder(transactionExecutor, {
433
445
  partitionKey: this.partitionKey,
434
446
  sortKey: this.sortKey
435
447
  });
@@ -449,7 +461,7 @@ var Table = class {
449
461
  * For example, you are updating a record and you want to ensure that another record exists and/or has a specific value before proceeding.
450
462
  */
451
463
  conditionCheck(keyCondition) {
452
- return new chunkAHF4H42Q_cjs.ConditionCheckBuilder(this.tableName, keyCondition);
464
+ return new chunk3DR6VOFW_cjs.ConditionCheckBuilder(this.tableName, keyCondition);
453
465
  }
454
466
  /**
455
467
  * Performs a batch get operation to retrieve multiple items at once
package/dist/entity.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { s as Path, t as PathType, b as Condition, c as ConditionOperator, P as PrimaryKeyWithoutExpression, a as PrimaryKey } from './conditions-C8bM__Pn.cjs';
2
- import { P as PutBuilder, G as GetBuilder, U as UpdateBuilder, p as UpdateCommandParams, T as TransactionBuilder, D as DeleteBuilder, S as ScanBuilder, Q as QueryBuilder } from './index-BX-MSZHj.cjs';
2
+ import { P as PutBuilder, G as GetBuilder, U as UpdateBuilder, p as UpdateCommandParams, T as TransactionBuilder, D as DeleteBuilder, S as ScanBuilder, Q as QueryBuilder } from './index-CPCmWsEv.cjs';
3
3
  import { StandardSchemaV1 } from './standard-schema.cjs';
4
4
  import { Table } from './table.cjs';
5
5
  import { DynamoItem, Index, TableConfig } from './types.cjs';
package/dist/entity.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { s as Path, t as PathType, b as Condition, c as ConditionOperator, P as PrimaryKeyWithoutExpression, a as PrimaryKey } from './conditions-BSAcZswY.js';
2
- import { P as PutBuilder, G as GetBuilder, U as UpdateBuilder, p as UpdateCommandParams, T as TransactionBuilder, D as DeleteBuilder, S as ScanBuilder, Q as QueryBuilder } from './index-DdTolMJW.js';
2
+ import { P as PutBuilder, G as GetBuilder, U as UpdateBuilder, p as UpdateCommandParams, T as TransactionBuilder, D as DeleteBuilder, S as ScanBuilder, Q as QueryBuilder } from './index-Bc-ra0im.js';
3
3
  import { StandardSchemaV1 } from './standard-schema.js';
4
4
  import { Table } from './table.js';
5
5
  import { DynamoItem, Index, TableConfig } from './types.js';
@@ -354,6 +354,7 @@ interface BaseBuilderInterface<T extends DynamoItem, TConfig extends TableConfig
354
354
  getLimit(): number | undefined;
355
355
  startFrom(lastEvaluatedKey: DynamoItem): B;
356
356
  execute(): Promise<ResultIterator<T, TConfig>>;
357
+ findOne(): Promise<T | undefined>;
357
358
  }
358
359
  /**
359
360
  * Interface for the QueryBuilder class to be used by Paginator
@@ -459,6 +460,8 @@ declare class GetBuilder<T extends DynamoItem> {
459
460
  private readonly params;
460
461
  private options;
461
462
  private selectedFields;
463
+ private includeIndexAttributes;
464
+ private readonly indexAttributeNames;
462
465
  /**
463
466
  * Creates a new GetBuilder instance.
464
467
  *
@@ -466,7 +469,7 @@ declare class GetBuilder<T extends DynamoItem> {
466
469
  * @param key - Primary key of the item to retrieve
467
470
  * @param tableName - Name of the DynamoDB table
468
471
  */
469
- constructor(executor: GetExecutor<T>, key: PrimaryKeyWithoutExpression, tableName: string);
472
+ constructor(executor: GetExecutor<T>, key: PrimaryKeyWithoutExpression, tableName: string, indexAttributeNames?: string[]);
470
473
  /**
471
474
  * Specifies which attributes to return in the get results.
472
475
  *
@@ -488,6 +491,11 @@ declare class GetBuilder<T extends DynamoItem> {
488
491
  * @returns The builder instance for method chaining
489
492
  */
490
493
  select<K extends Path<T>>(fields: K | K[]): GetBuilder<T>;
494
+ /**
495
+ * Ensures index attributes are included in the result.
496
+ * By default, index attributes are removed from get responses.
497
+ */
498
+ includeIndexes(): GetBuilder<T>;
491
499
  /**
492
500
  * Sets whether to use strongly consistent reads for the get operation.
493
501
  * Use this method when you need:
@@ -550,6 +558,8 @@ declare class GetBuilder<T extends DynamoItem> {
550
558
  * Converts the builder configuration to a DynamoDB command
551
559
  */
552
560
  private toDynamoCommand;
561
+ private addIndexAttributesToSelection;
562
+ private omitIndexAttributes;
553
563
  /**
554
564
  * Executes the get operation against DynamoDB.
555
565
  *
@@ -2176,6 +2186,26 @@ declare abstract class FilterBuilder<T extends DynamoItem, TConfig extends Table
2176
2186
  * their specific execution logic.
2177
2187
  */
2178
2188
  abstract execute(): Promise<ResultIterator<T, TConfig>>;
2189
+ /**
2190
+ * Executes the operation and returns the first matching item, if any.
2191
+ *
2192
+ * This helper:
2193
+ * - Applies an internal limit of 1
2194
+ * - Streams results until a match is found or there are no more pages
2195
+ * - Avoids mutating the current builder by using a clone
2196
+ *
2197
+ * @example
2198
+ * ```typescript
2199
+ * const latest = await table
2200
+ * .query(eq("moduleId", moduleId))
2201
+ * .useIndex("module-version-index")
2202
+ * .sortDescending()
2203
+ * .findOne();
2204
+ * ```
2205
+ *
2206
+ * @returns The first matching item, or undefined if none found
2207
+ */
2208
+ findOne(): Promise<T | undefined>;
2179
2209
  }
2180
2210
 
2181
2211
  /**
@@ -2238,7 +2268,9 @@ declare class QueryBuilder<T extends DynamoItem, TConfig extends TableConfig = T
2238
2268
  private readonly keyCondition;
2239
2269
  protected options: QueryOptions;
2240
2270
  protected readonly executor: QueryExecutor<T>;
2241
- constructor(executor: QueryExecutor<T>, keyCondition: Condition);
2271
+ private includeIndexAttributes;
2272
+ private readonly indexAttributeNames;
2273
+ constructor(executor: QueryExecutor<T>, keyCondition: Condition, indexAttributeNames?: string[]);
2242
2274
  /**
2243
2275
  * Sets the maximum number of items to return from the query.
2244
2276
  *
@@ -2304,6 +2336,12 @@ declare class QueryBuilder<T extends DynamoItem, TConfig extends TableConfig = T
2304
2336
  * @returns The builder instance for method chaining
2305
2337
  */
2306
2338
  sortDescending(): this;
2339
+ /**
2340
+ * Ensures index attributes are included in the result.
2341
+ * By default, index attributes are removed from query responses.
2342
+ */
2343
+ includeIndexes(): this;
2344
+ select<K extends Path<T>>(fields: K | K[]): this;
2307
2345
  /**
2308
2346
  * Creates a deep clone of this QueryBuilder instance.
2309
2347
  *
@@ -2378,6 +2416,8 @@ declare class QueryBuilder<T extends DynamoItem, TConfig extends TableConfig = T
2378
2416
  * @returns A promise that resolves to a ResultGenerator that behaves like an array
2379
2417
  */
2380
2418
  execute(): Promise<ResultIterator<T, TConfig>>;
2419
+ private addIndexAttributesToSelection;
2420
+ private omitIndexAttributes;
2381
2421
  }
2382
2422
 
2383
2423
  /**
@@ -2999,4 +3039,4 @@ declare class ScanBuilder<T extends DynamoItem, TConfig extends TableConfig = Ta
2999
3039
  execute(): Promise<ResultIterator<T, TConfig>>;
3000
3040
  }
3001
3041
 
3002
- export { BatchBuilder as B, ConditionCheckBuilder as C, DeleteBuilder as D, ExpressionError as E, FilterBuilder as F, GetBuilder as G, IndexGenerationError as I, KeyGenerationError as K, OperationError as O, PutBuilder as P, QueryBuilder as Q, ResultIterator as R, ScanBuilder as S, TransactionBuilder as T, UpdateBuilder as U, ValidationError as V, type TransactionOptions as a, type BatchWriteOperation as b, BatchError as c, ConfigurationError as d, EntityValidationError as e, TransactionError as f, DynoTableError as g, EntityError as h, type BatchResult as i, type DeleteOptions as j, type PutOptions as k, type QueryOptions as l, type UpdateOptions as m, ErrorCodes as n, type ErrorCode as o, type UpdateCommandParams as p, Paginator as q, type DeleteCommandParams as r, type PutCommandParams as s, type ConditionCheckCommandParams as t, type BaseBuilderInterface as u, type QueryBuilderInterface as v, type ScanBuilderInterface as w, type FilterBuilderInterface as x, type PaginationResult as y, type TransactionItem as z };
3042
+ export { BatchBuilder as B, ConditionCheckBuilder as C, DeleteBuilder as D, ExpressionError as E, FilterBuilder as F, GetBuilder as G, IndexGenerationError as I, KeyGenerationError as K, OperationError as O, PutBuilder as P, QueryBuilder as Q, ResultIterator as R, ScanBuilder as S, TransactionBuilder as T, UpdateBuilder as U, ValidationError as V, type TransactionOptions as a, type BatchWriteOperation as b, BatchError as c, ConfigurationError as d, EntityValidationError as e, TransactionError as f, DynoTableError as g, EntityError as h, type BatchResult as i, type DeleteOptions as j, type ErrorCode as k, ErrorCodes as l, type PutOptions as m, type QueryOptions as n, type UpdateOptions as o, type UpdateCommandParams as p, type BaseBuilderInterface as q, type ConditionCheckCommandParams as r, type DeleteCommandParams as s, type FilterBuilderInterface as t, type PaginationResult as u, Paginator as v, type PutCommandParams as w, type QueryBuilderInterface as x, type ScanBuilderInterface as y, type TransactionItem as z };
@@ -354,6 +354,7 @@ interface BaseBuilderInterface<T extends DynamoItem, TConfig extends TableConfig
354
354
  getLimit(): number | undefined;
355
355
  startFrom(lastEvaluatedKey: DynamoItem): B;
356
356
  execute(): Promise<ResultIterator<T, TConfig>>;
357
+ findOne(): Promise<T | undefined>;
357
358
  }
358
359
  /**
359
360
  * Interface for the QueryBuilder class to be used by Paginator
@@ -459,6 +460,8 @@ declare class GetBuilder<T extends DynamoItem> {
459
460
  private readonly params;
460
461
  private options;
461
462
  private selectedFields;
463
+ private includeIndexAttributes;
464
+ private readonly indexAttributeNames;
462
465
  /**
463
466
  * Creates a new GetBuilder instance.
464
467
  *
@@ -466,7 +469,7 @@ declare class GetBuilder<T extends DynamoItem> {
466
469
  * @param key - Primary key of the item to retrieve
467
470
  * @param tableName - Name of the DynamoDB table
468
471
  */
469
- constructor(executor: GetExecutor<T>, key: PrimaryKeyWithoutExpression, tableName: string);
472
+ constructor(executor: GetExecutor<T>, key: PrimaryKeyWithoutExpression, tableName: string, indexAttributeNames?: string[]);
470
473
  /**
471
474
  * Specifies which attributes to return in the get results.
472
475
  *
@@ -488,6 +491,11 @@ declare class GetBuilder<T extends DynamoItem> {
488
491
  * @returns The builder instance for method chaining
489
492
  */
490
493
  select<K extends Path<T>>(fields: K | K[]): GetBuilder<T>;
494
+ /**
495
+ * Ensures index attributes are included in the result.
496
+ * By default, index attributes are removed from get responses.
497
+ */
498
+ includeIndexes(): GetBuilder<T>;
491
499
  /**
492
500
  * Sets whether to use strongly consistent reads for the get operation.
493
501
  * Use this method when you need:
@@ -550,6 +558,8 @@ declare class GetBuilder<T extends DynamoItem> {
550
558
  * Converts the builder configuration to a DynamoDB command
551
559
  */
552
560
  private toDynamoCommand;
561
+ private addIndexAttributesToSelection;
562
+ private omitIndexAttributes;
553
563
  /**
554
564
  * Executes the get operation against DynamoDB.
555
565
  *
@@ -2176,6 +2186,26 @@ declare abstract class FilterBuilder<T extends DynamoItem, TConfig extends Table
2176
2186
  * their specific execution logic.
2177
2187
  */
2178
2188
  abstract execute(): Promise<ResultIterator<T, TConfig>>;
2189
+ /**
2190
+ * Executes the operation and returns the first matching item, if any.
2191
+ *
2192
+ * This helper:
2193
+ * - Applies an internal limit of 1
2194
+ * - Streams results until a match is found or there are no more pages
2195
+ * - Avoids mutating the current builder by using a clone
2196
+ *
2197
+ * @example
2198
+ * ```typescript
2199
+ * const latest = await table
2200
+ * .query(eq("moduleId", moduleId))
2201
+ * .useIndex("module-version-index")
2202
+ * .sortDescending()
2203
+ * .findOne();
2204
+ * ```
2205
+ *
2206
+ * @returns The first matching item, or undefined if none found
2207
+ */
2208
+ findOne(): Promise<T | undefined>;
2179
2209
  }
2180
2210
 
2181
2211
  /**
@@ -2238,7 +2268,9 @@ declare class QueryBuilder<T extends DynamoItem, TConfig extends TableConfig = T
2238
2268
  private readonly keyCondition;
2239
2269
  protected options: QueryOptions;
2240
2270
  protected readonly executor: QueryExecutor<T>;
2241
- constructor(executor: QueryExecutor<T>, keyCondition: Condition);
2271
+ private includeIndexAttributes;
2272
+ private readonly indexAttributeNames;
2273
+ constructor(executor: QueryExecutor<T>, keyCondition: Condition, indexAttributeNames?: string[]);
2242
2274
  /**
2243
2275
  * Sets the maximum number of items to return from the query.
2244
2276
  *
@@ -2304,6 +2336,12 @@ declare class QueryBuilder<T extends DynamoItem, TConfig extends TableConfig = T
2304
2336
  * @returns The builder instance for method chaining
2305
2337
  */
2306
2338
  sortDescending(): this;
2339
+ /**
2340
+ * Ensures index attributes are included in the result.
2341
+ * By default, index attributes are removed from query responses.
2342
+ */
2343
+ includeIndexes(): this;
2344
+ select<K extends Path<T>>(fields: K | K[]): this;
2307
2345
  /**
2308
2346
  * Creates a deep clone of this QueryBuilder instance.
2309
2347
  *
@@ -2378,6 +2416,8 @@ declare class QueryBuilder<T extends DynamoItem, TConfig extends TableConfig = T
2378
2416
  * @returns A promise that resolves to a ResultGenerator that behaves like an array
2379
2417
  */
2380
2418
  execute(): Promise<ResultIterator<T, TConfig>>;
2419
+ private addIndexAttributesToSelection;
2420
+ private omitIndexAttributes;
2381
2421
  }
2382
2422
 
2383
2423
  /**
@@ -2999,4 +3039,4 @@ declare class ScanBuilder<T extends DynamoItem, TConfig extends TableConfig = Ta
2999
3039
  execute(): Promise<ResultIterator<T, TConfig>>;
3000
3040
  }
3001
3041
 
3002
- export { BatchBuilder as B, ConditionCheckBuilder as C, DeleteBuilder as D, ExpressionError as E, FilterBuilder as F, GetBuilder as G, IndexGenerationError as I, KeyGenerationError as K, OperationError as O, PutBuilder as P, QueryBuilder as Q, ResultIterator as R, ScanBuilder as S, TransactionBuilder as T, UpdateBuilder as U, ValidationError as V, type TransactionOptions as a, type BatchWriteOperation as b, BatchError as c, ConfigurationError as d, EntityValidationError as e, TransactionError as f, DynoTableError as g, EntityError as h, type BatchResult as i, type DeleteOptions as j, type PutOptions as k, type QueryOptions as l, type UpdateOptions as m, ErrorCodes as n, type ErrorCode as o, type UpdateCommandParams as p, Paginator as q, type DeleteCommandParams as r, type PutCommandParams as s, type ConditionCheckCommandParams as t, type BaseBuilderInterface as u, type QueryBuilderInterface as v, type ScanBuilderInterface as w, type FilterBuilderInterface as x, type PaginationResult as y, type TransactionItem as z };
3042
+ export { BatchBuilder as B, ConditionCheckBuilder as C, DeleteBuilder as D, ExpressionError as E, FilterBuilder as F, GetBuilder as G, IndexGenerationError as I, KeyGenerationError as K, OperationError as O, PutBuilder as P, QueryBuilder as Q, ResultIterator as R, ScanBuilder as S, TransactionBuilder as T, UpdateBuilder as U, ValidationError as V, type TransactionOptions as a, type BatchWriteOperation as b, BatchError as c, ConfigurationError as d, EntityValidationError as e, TransactionError as f, DynoTableError as g, EntityError as h, type BatchResult as i, type DeleteOptions as j, type ErrorCode as k, ErrorCodes as l, type PutOptions as m, type QueryOptions as n, type UpdateOptions as o, type UpdateCommandParams as p, type BaseBuilderInterface as q, type ConditionCheckCommandParams as r, type DeleteCommandParams as s, type FilterBuilderInterface as t, type PaginationResult as u, Paginator as v, type PutCommandParams as w, type QueryBuilderInterface as x, type ScanBuilderInterface as y, type TransactionItem as z };
package/dist/index.cjs CHANGED
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
- var chunkOLURZQ7R_cjs = require('./chunk-OLURZQ7R.cjs');
3
+ var chunkZUBCW3LA_cjs = require('./chunk-ZUBCW3LA.cjs');
4
4
  var chunkZXM6LPRV_cjs = require('./chunk-ZXM6LPRV.cjs');
5
5
  var chunkPB7BBCZO_cjs = require('./chunk-PB7BBCZO.cjs');
6
- var chunkAHF4H42Q_cjs = require('./chunk-AHF4H42Q.cjs');
6
+ var chunk3DR6VOFW_cjs = require('./chunk-3DR6VOFW.cjs');
7
7
  var chunkELULXDSB_cjs = require('./chunk-ELULXDSB.cjs');
8
8
  var chunk7UJJ7JXM_cjs = require('./chunk-7UJJ7JXM.cjs');
9
9
 
@@ -11,7 +11,7 @@ var chunk7UJJ7JXM_cjs = require('./chunk-7UJJ7JXM.cjs');
11
11
 
12
12
  Object.defineProperty(exports, "Table", {
13
13
  enumerable: true,
14
- get: function () { return chunkOLURZQ7R_cjs.Table; }
14
+ get: function () { return chunkZUBCW3LA_cjs.Table; }
15
15
  });
16
16
  Object.defineProperty(exports, "createIndex", {
17
17
  enumerable: true,
@@ -119,27 +119,27 @@ Object.defineProperty(exports, "sortKey", {
119
119
  });
120
120
  Object.defineProperty(exports, "BatchBuilder", {
121
121
  enumerable: true,
122
- get: function () { return chunkAHF4H42Q_cjs.BatchBuilder; }
122
+ get: function () { return chunk3DR6VOFW_cjs.BatchBuilder; }
123
123
  });
124
124
  Object.defineProperty(exports, "DeleteBuilder", {
125
125
  enumerable: true,
126
- get: function () { return chunkAHF4H42Q_cjs.DeleteBuilder; }
126
+ get: function () { return chunk3DR6VOFW_cjs.DeleteBuilder; }
127
127
  });
128
128
  Object.defineProperty(exports, "PutBuilder", {
129
129
  enumerable: true,
130
- get: function () { return chunkAHF4H42Q_cjs.PutBuilder; }
130
+ get: function () { return chunk3DR6VOFW_cjs.PutBuilder; }
131
131
  });
132
132
  Object.defineProperty(exports, "QueryBuilder", {
133
133
  enumerable: true,
134
- get: function () { return chunkAHF4H42Q_cjs.QueryBuilder; }
134
+ get: function () { return chunk3DR6VOFW_cjs.QueryBuilder; }
135
135
  });
136
136
  Object.defineProperty(exports, "TransactionBuilder", {
137
137
  enumerable: true,
138
- get: function () { return chunkAHF4H42Q_cjs.TransactionBuilder; }
138
+ get: function () { return chunk3DR6VOFW_cjs.TransactionBuilder; }
139
139
  });
140
140
  Object.defineProperty(exports, "UpdateBuilder", {
141
141
  enumerable: true,
142
- get: function () { return chunkAHF4H42Q_cjs.UpdateBuilder; }
142
+ get: function () { return chunk3DR6VOFW_cjs.UpdateBuilder; }
143
143
  });
144
144
  Object.defineProperty(exports, "BatchError", {
145
145
  enumerable: true,
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { c as BatchError, d as ConfigurationError, E as ExpressionError, e as EntityValidationError, K as KeyGenerationError, I as IndexGenerationError, O as OperationError, f as TransactionError, V as ValidationError, g as DynoTableError, h as EntityError } from './index-BX-MSZHj.cjs';
2
- export { B as BatchBuilder, i as BatchResult, D as DeleteBuilder, j as DeleteOptions, o as ErrorCode, n as ErrorCodes, P as PutBuilder, k as PutOptions, Q as QueryBuilder, l as QueryOptions, T as TransactionBuilder, a as TransactionOptions, U as UpdateBuilder, m as UpdateOptions } from './index-BX-MSZHj.cjs';
1
+ import { c as BatchError, d as ConfigurationError, E as ExpressionError, e as EntityValidationError, K as KeyGenerationError, I as IndexGenerationError, O as OperationError, f as TransactionError, V as ValidationError, g as DynoTableError, h as EntityError } from './index-CPCmWsEv.cjs';
2
+ export { B as BatchBuilder, i as BatchResult, D as DeleteBuilder, j as DeleteOptions, k as ErrorCode, l as ErrorCodes, P as PutBuilder, m as PutOptions, Q as QueryBuilder, n as QueryOptions, T as TransactionBuilder, a as TransactionOptions, U as UpdateBuilder, o as UpdateOptions } from './index-CPCmWsEv.cjs';
3
3
  export { C as ComparisonOperator, b as Condition, c as ConditionOperator, E as ExpressionParams, K as KeyConditionOperator, L as LogicalOperator, a as PrimaryKey, P as PrimaryKeyWithoutExpression, d as and, e as attributeExists, f as attributeNotExists, g as beginsWith, h as between, i as contains, j as eq, k as gt, l as gte, m as inArray, n as lt, o as lte, p as ne, q as not, r as or } from './conditions-C8bM__Pn.cjs';
4
4
  export { EntityConfig, EntityRepository, IndexDefinition, QueryEntity, QueryRecord, createIndex, createQueries, defineEntity } from './entity.cjs';
5
5
  export { Table } from './table.cjs';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { c as BatchError, d as ConfigurationError, E as ExpressionError, e as EntityValidationError, K as KeyGenerationError, I as IndexGenerationError, O as OperationError, f as TransactionError, V as ValidationError, g as DynoTableError, h as EntityError } from './index-DdTolMJW.js';
2
- export { B as BatchBuilder, i as BatchResult, D as DeleteBuilder, j as DeleteOptions, o as ErrorCode, n as ErrorCodes, P as PutBuilder, k as PutOptions, Q as QueryBuilder, l as QueryOptions, T as TransactionBuilder, a as TransactionOptions, U as UpdateBuilder, m as UpdateOptions } from './index-DdTolMJW.js';
1
+ import { c as BatchError, d as ConfigurationError, E as ExpressionError, e as EntityValidationError, K as KeyGenerationError, I as IndexGenerationError, O as OperationError, f as TransactionError, V as ValidationError, g as DynoTableError, h as EntityError } from './index-Bc-ra0im.js';
2
+ export { B as BatchBuilder, i as BatchResult, D as DeleteBuilder, j as DeleteOptions, k as ErrorCode, l as ErrorCodes, P as PutBuilder, m as PutOptions, Q as QueryBuilder, n as QueryOptions, T as TransactionBuilder, a as TransactionOptions, U as UpdateBuilder, o as UpdateOptions } from './index-Bc-ra0im.js';
3
3
  export { C as ComparisonOperator, b as Condition, c as ConditionOperator, E as ExpressionParams, K as KeyConditionOperator, L as LogicalOperator, a as PrimaryKey, P as PrimaryKeyWithoutExpression, d as and, e as attributeExists, f as attributeNotExists, g as beginsWith, h as between, i as contains, j as eq, k as gt, l as gte, m as inArray, n as lt, o as lte, p as ne, q as not, r as or } from './conditions-BSAcZswY.js';
4
4
  export { EntityConfig, EntityRepository, IndexDefinition, QueryEntity, QueryRecord, createIndex, createQueries, defineEntity } from './entity.js';
5
5
  export { Table } from './table.js';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- export { Table } from './chunk-64DG2EEI.js';
1
+ export { Table } from './chunk-42LH2UEM.js';
2
2
  export { createIndex, createQueries, defineEntity, extractRequiredAttributes, formatErrorContext, getAwsErrorCode, getAwsErrorMessage, getErrorSummary, isBatchError, isConditionalCheckFailed, isConfigurationError, isDynoTableError, isEntityError, isEntityValidationError, isExpressionError, isIndexGenerationError, isKeyGenerationError, isOperationError, isProvisionedThroughputExceeded, isRetryableError, isTransactionCanceled, isTransactionError, isValidationError, isValidationException } from './chunk-U6MQGB6Y.js';
3
3
  export { partitionKey, sortKey } from './chunk-QVRMYGC4.js';
4
- export { BatchBuilder, DeleteBuilder, PutBuilder, QueryBuilder, TransactionBuilder, UpdateBuilder } from './chunk-GWHGUKAL.js';
4
+ export { BatchBuilder, DeleteBuilder, PutBuilder, QueryBuilder, TransactionBuilder, UpdateBuilder } from './chunk-NYJGW3XH.js';
5
5
  export { BatchError, BatchErrors, ConfigurationError, ConfigurationErrors, DynoTableError, EntityError, EntityErrors, EntityValidationError, ErrorCodes, ExpressionError, ExpressionErrors, IndexErrors, IndexGenerationError, KeyGenerationError, OperationError, OperationErrors, TransactionError, TransactionErrors, ValidationError, ValidationErrors } from './chunk-FF7FYGDH.js';
6
6
  export { and, attributeExists, attributeNotExists, beginsWith, between, contains, eq, gt, gte, inArray, lt, lte, ne, not, or } from './chunk-2WIBY7PZ.js';
package/dist/table.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkOLURZQ7R_cjs = require('./chunk-OLURZQ7R.cjs');
4
- require('./chunk-AHF4H42Q.cjs');
3
+ var chunkZUBCW3LA_cjs = require('./chunk-ZUBCW3LA.cjs');
4
+ require('./chunk-3DR6VOFW.cjs');
5
5
  require('./chunk-ELULXDSB.cjs');
6
6
  require('./chunk-7UJJ7JXM.cjs');
7
7
 
@@ -9,5 +9,5 @@ require('./chunk-7UJJ7JXM.cjs');
9
9
 
10
10
  Object.defineProperty(exports, "Table", {
11
11
  enumerable: true,
12
- get: function () { return chunkOLURZQ7R_cjs.Table; }
12
+ get: function () { return chunkZUBCW3LA_cjs.Table; }
13
13
  });
package/dist/table.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { P as PutBuilder, G as GetBuilder, Q as QueryBuilder, S as ScanBuilder, D as DeleteBuilder, U as UpdateBuilder, T as TransactionBuilder, B as BatchBuilder, a as TransactionOptions, C as ConditionCheckBuilder, b as BatchWriteOperation } from './index-BX-MSZHj.cjs';
1
+ import { P as PutBuilder, G as GetBuilder, Q as QueryBuilder, S as ScanBuilder, D as DeleteBuilder, U as UpdateBuilder, T as TransactionBuilder, B as BatchBuilder, a as TransactionOptions, C as ConditionCheckBuilder, b as BatchWriteOperation } from './index-CPCmWsEv.cjs';
2
2
  import { P as PrimaryKeyWithoutExpression, a as PrimaryKey } from './conditions-C8bM__Pn.cjs';
3
3
  import { TableConfig, Index, DynamoItem } from './types.cjs';
4
4
  import '@aws-sdk/lib-dynamodb';
@@ -19,6 +19,7 @@ declare class Table<TConfig extends TableConfig = TableConfig> {
19
19
  */
20
20
  readonly gsis: Record<string, Index>;
21
21
  constructor(config: TConfig);
22
+ private getIndexAttributeNames;
22
23
  protected createKeyForPrimaryIndex(keyCondition: PrimaryKeyWithoutExpression): Record<string, unknown>;
23
24
  /**
24
25
  * Creates a new item in the table, it will fail if the item already exists.
package/dist/table.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { P as PutBuilder, G as GetBuilder, Q as QueryBuilder, S as ScanBuilder, D as DeleteBuilder, U as UpdateBuilder, T as TransactionBuilder, B as BatchBuilder, a as TransactionOptions, C as ConditionCheckBuilder, b as BatchWriteOperation } from './index-DdTolMJW.js';
1
+ import { P as PutBuilder, G as GetBuilder, Q as QueryBuilder, S as ScanBuilder, D as DeleteBuilder, U as UpdateBuilder, T as TransactionBuilder, B as BatchBuilder, a as TransactionOptions, C as ConditionCheckBuilder, b as BatchWriteOperation } from './index-Bc-ra0im.js';
2
2
  import { P as PrimaryKeyWithoutExpression, a as PrimaryKey } from './conditions-BSAcZswY.js';
3
3
  import { TableConfig, Index, DynamoItem } from './types.js';
4
4
  import '@aws-sdk/lib-dynamodb';
@@ -19,6 +19,7 @@ declare class Table<TConfig extends TableConfig = TableConfig> {
19
19
  */
20
20
  readonly gsis: Record<string, Index>;
21
21
  constructor(config: TConfig);
22
+ private getIndexAttributeNames;
22
23
  protected createKeyForPrimaryIndex(keyCondition: PrimaryKeyWithoutExpression): Record<string, unknown>;
23
24
  /**
24
25
  * Creates a new item in the table, it will fail if the item already exists.
package/dist/table.js CHANGED
@@ -1,4 +1,4 @@
1
- export { Table } from './chunk-64DG2EEI.js';
2
- import './chunk-GWHGUKAL.js';
1
+ export { Table } from './chunk-42LH2UEM.js';
2
+ import './chunk-NYJGW3XH.js';
3
3
  import './chunk-FF7FYGDH.js';
4
4
  import './chunk-2WIBY7PZ.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dyno-table",
3
- "version": "2.4.0",
3
+ "version": "2.5.1",
4
4
  "description": "A TypeScript library to simplify working with DynamoDB",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -118,16 +118,16 @@
118
118
  "url": "git+https://github.com/Kysumi/dyno-table.git"
119
119
  },
120
120
  "devDependencies": {
121
- "@babel/preset-typescript": "^7.26.0",
121
+ "@babel/preset-typescript": "^7.28.5",
122
122
  "@biomejs/biome": "2.2.2",
123
123
  "@semantic-release/changelog": "^6.0.3",
124
124
  "@semantic-release/git": "^10.0.1",
125
- "@types/node": "^20.17.11",
125
+ "@types/node": "^20.19.31",
126
126
  "husky": "^9.1.7",
127
127
  "rimraf": "^5.0.10",
128
128
  "semantic-release": "24.2.3",
129
- "tsup": "^8.3.5",
130
- "typescript": "^5.7.2",
129
+ "tsup": "^8.5.1",
130
+ "typescript": "^5.9.3",
131
131
  "vitest": "3.0.5"
132
132
  },
133
133
  "peerDependencies": {