@ftschopp/dynatable-core 1.5.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/builders/delete/create-delete-builder.d.ts +1 -1
- package/dist/builders/delete/create-delete-builder.d.ts.map +1 -1
- package/dist/builders/delete/create-delete-builder.js +7 -3
- package/dist/builders/delete/types.d.ts +9 -0
- package/dist/builders/delete/types.d.ts.map +1 -1
- package/dist/builders/put/create-put-builder.d.ts +1 -1
- package/dist/builders/put/create-put-builder.d.ts.map +1 -1
- package/dist/builders/put/create-put-builder.js +8 -4
- package/dist/builders/put/types.d.ts +10 -0
- package/dist/builders/put/types.d.ts.map +1 -1
- package/dist/builders/query/create-query-builder.d.ts.map +1 -1
- package/dist/builders/query/create-query-builder.js +25 -1
- package/dist/builders/query/types.d.ts +10 -0
- package/dist/builders/query/types.d.ts.map +1 -1
- package/dist/builders/scan/create-scan-builder.d.ts +1 -1
- package/dist/builders/scan/create-scan-builder.d.ts.map +1 -1
- package/dist/builders/scan/create-scan-builder.js +14 -8
- package/dist/builders/scan/types.d.ts +10 -0
- package/dist/builders/scan/types.d.ts.map +1 -1
- package/dist/builders/update/create-update-builder.d.ts +1 -1
- package/dist/builders/update/create-update-builder.d.ts.map +1 -1
- package/dist/builders/update/create-update-builder.js +86 -8
- package/dist/builders/update/types.d.ts +10 -0
- package/dist/builders/update/types.d.ts.map +1 -1
- package/dist/entity/create-entity-api.d.ts.map +1 -1
- package/dist/entity/create-entity-api.js +15 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# @ftschopp/dynatable-core [1.6.0](https://github.com/ftschopp/dynatable/compare/@ftschopp/dynatable-core@1.5.2...@ftschopp/dynatable-core@1.6.0) (2026-05-10)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **core:** expose ReturnConsumedCapacity on query/scan/update/put/delete ([#44](https://github.com/ftschopp/dynatable/issues/44)) ([048e52f](https://github.com/ftschopp/dynatable/commit/048e52f8172cd13a0ad1720e8c701af8bf20603d))
|
|
7
|
+
|
|
8
|
+
## @ftschopp/dynatable-core [1.5.2](https://github.com/ftschopp/dynatable/compare/@ftschopp/dynatable-core@1.5.1...@ftschopp/dynatable-core@1.5.2) (2026-05-10)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **core:** guard primary-key template fields and non-set ops on GSI templates in update builder ([#42](https://github.com/ftschopp/dynatable/issues/42)) ([4487ff2](https://github.com/ftschopp/dynatable/commit/4487ff22ad507b37aa0e2e279a602a4813afddba))
|
|
14
|
+
|
|
1
15
|
## @ftschopp/dynatable-core [1.5.1](https://github.com/ftschopp/dynatable/compare/@ftschopp/dynatable-core@1.5.0...@ftschopp/dynatable-core@1.5.1) (2026-05-10)
|
|
2
16
|
|
|
3
17
|
|
|
@@ -5,5 +5,5 @@ import { DynamoDBLogger } from '../../utils/dynamodb-logger';
|
|
|
5
5
|
/**
|
|
6
6
|
* Creates a DeleteBuilder for an item key and table.
|
|
7
7
|
*/
|
|
8
|
-
export declare function createDeleteBuilder<Model>(tableName: string, key: Partial<Model>, client: DynamoDBClient, prevConditions?: Condition[], returnMode?: 'NONE' | 'ALL_OLD', logger?: DynamoDBLogger): DeleteBuilder<Model>;
|
|
8
|
+
export declare function createDeleteBuilder<Model>(tableName: string, key: Partial<Model>, client: DynamoDBClient, prevConditions?: Condition[], returnMode?: 'NONE' | 'ALL_OLD', logger?: DynamoDBLogger, consumedCapacity?: 'INDEXES' | 'TOTAL' | 'NONE'): DeleteBuilder<Model>;
|
|
9
9
|
//# sourceMappingURL=create-delete-builder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-delete-builder.d.ts","sourceRoot":"","sources":["../../../src/builders/delete/create-delete-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAgC,SAAS,EAAmB,MAAM,WAAW,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EACvC,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,EACnB,MAAM,EAAE,cAAc,EACtB,cAAc,GAAE,SAAS,EAAO,EAChC,UAAU,GAAE,MAAM,GAAG,SAAkB,EACvC,MAAM,CAAC,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"create-delete-builder.d.ts","sourceRoot":"","sources":["../../../src/builders/delete/create-delete-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAgC,SAAS,EAAmB,MAAM,WAAW,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EACvC,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,EACnB,MAAM,EAAE,cAAc,EACtB,cAAc,GAAE,SAAS,EAAO,EAChC,UAAU,GAAE,MAAM,GAAG,SAAkB,EACvC,MAAM,CAAC,EAAE,cAAc,EACvB,gBAAgB,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,GAC9C,aAAa,CAAC,KAAK,CAAC,CAwGtB"}
|
|
@@ -6,7 +6,7 @@ const shared_1 = require("../shared");
|
|
|
6
6
|
/**
|
|
7
7
|
* Creates a DeleteBuilder for an item key and table.
|
|
8
8
|
*/
|
|
9
|
-
function createDeleteBuilder(tableName, key, client, prevConditions = [], returnMode = 'NONE', logger) {
|
|
9
|
+
function createDeleteBuilder(tableName, key, client, prevConditions = [], returnMode = 'NONE', logger, consumedCapacity) {
|
|
10
10
|
const conditions = [...prevConditions];
|
|
11
11
|
const build = () => ({
|
|
12
12
|
where(fn) {
|
|
@@ -17,10 +17,13 @@ function createDeleteBuilder(tableName, key, client, prevConditions = [], return
|
|
|
17
17
|
});
|
|
18
18
|
const opBuilder = (0, shared_1.createOpBuilder)();
|
|
19
19
|
const condition = fn(attrs, opBuilder);
|
|
20
|
-
return createDeleteBuilder(tableName, key, client, [...conditions, condition], returnMode, logger);
|
|
20
|
+
return createDeleteBuilder(tableName, key, client, [...conditions, condition], returnMode, logger, consumedCapacity);
|
|
21
21
|
},
|
|
22
22
|
returning(mode) {
|
|
23
|
-
return createDeleteBuilder(tableName, key, client, conditions, mode, logger);
|
|
23
|
+
return createDeleteBuilder(tableName, key, client, conditions, mode, logger, consumedCapacity);
|
|
24
|
+
},
|
|
25
|
+
returnConsumedCapacity(mode) {
|
|
26
|
+
return createDeleteBuilder(tableName, key, client, conditions, returnMode, logger, mode);
|
|
24
27
|
},
|
|
25
28
|
dbParams() {
|
|
26
29
|
// Build ConditionExpression from condition tree
|
|
@@ -53,6 +56,7 @@ function createDeleteBuilder(tableName, key, client, prevConditions = [], return
|
|
|
53
56
|
...(Object.keys(expressionAttributeValues).length && {
|
|
54
57
|
ExpressionAttributeValues: expressionAttributeValues,
|
|
55
58
|
}),
|
|
59
|
+
...(consumedCapacity && { ReturnConsumedCapacity: consumedCapacity }),
|
|
56
60
|
...extra,
|
|
57
61
|
};
|
|
58
62
|
},
|
|
@@ -8,6 +8,15 @@ export interface DeleteBuilder<Model> extends Omit<OperationBuilder<Model>, 'dbP
|
|
|
8
8
|
* Configures what values should be returned after the delete operation
|
|
9
9
|
*/
|
|
10
10
|
returning(mode: 'NONE' | 'ALL_OLD'): DeleteBuilder<Model>;
|
|
11
|
+
/**
|
|
12
|
+
* Configures the ReturnConsumedCapacity parameter so DynamoDB reports
|
|
13
|
+
* how many WCUs the delete consumed. Useful for diagnosing throttling.
|
|
14
|
+
*
|
|
15
|
+
* - INDEXES: Returns consumed capacity for table and indexes
|
|
16
|
+
* - TOTAL: Returns total consumed capacity
|
|
17
|
+
* - NONE: No consumed capacity data returned (default)
|
|
18
|
+
*/
|
|
19
|
+
returnConsumedCapacity(mode: 'INDEXES' | 'TOTAL' | 'NONE'): DeleteBuilder<Model>;
|
|
11
20
|
/**
|
|
12
21
|
* Converts the builder state to DynamoDB DeleteItem parameters
|
|
13
22
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/builders/delete/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,KAAK,CAAE,SAAQ,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACrF;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAE1D;;OAEG;IACH,QAAQ,IAAI,kBAAkB,CAAC;CAChC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/builders/delete/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,KAAK,CAAE,SAAQ,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACrF;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAE1D;;;;;;;OAOG;IACH,sBAAsB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAEjF;;OAEG;IACH,QAAQ,IAAI,kBAAkB,CAAC;CAChC"}
|
|
@@ -5,5 +5,5 @@ import { DynamoDBLogger } from '../../utils/dynamodb-logger';
|
|
|
5
5
|
/**
|
|
6
6
|
* Creates a PutBuilder for an item and table.
|
|
7
7
|
*/
|
|
8
|
-
export declare function createPutBuilder<Model>(tableName: string, item: Model, client: DynamoDBClient, prevConditions?: Condition[], shouldCheckNotExists?: boolean, returnMode?: 'NONE' | 'ALL_OLD', enableTimestamps?: boolean, logger?: DynamoDBLogger): PutBuilder<Model>;
|
|
8
|
+
export declare function createPutBuilder<Model>(tableName: string, item: Model, client: DynamoDBClient, prevConditions?: Condition[], shouldCheckNotExists?: boolean, returnMode?: 'NONE' | 'ALL_OLD', enableTimestamps?: boolean, logger?: DynamoDBLogger, consumedCapacity?: 'INDEXES' | 'TOTAL' | 'NONE'): PutBuilder<Model>;
|
|
9
9
|
//# sourceMappingURL=create-put-builder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-put-builder.d.ts","sourceRoot":"","sources":["../../../src/builders/put/create-put-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAgC,SAAS,EAAmB,MAAM,WAAW,CAAC;AACrF,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAgB7D;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EACpC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,KAAK,EACX,MAAM,EAAE,cAAc,EACtB,cAAc,GAAE,SAAS,EAAO,EAChC,oBAAoB,UAAQ,EAC5B,UAAU,GAAE,MAAM,GAAG,SAAkB,EACvC,gBAAgB,UAAQ,EACxB,MAAM,CAAC,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"create-put-builder.d.ts","sourceRoot":"","sources":["../../../src/builders/put/create-put-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAgC,SAAS,EAAmB,MAAM,WAAW,CAAC;AACrF,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAgB7D;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EACpC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,KAAK,EACX,MAAM,EAAE,cAAc,EACtB,cAAc,GAAE,SAAS,EAAO,EAChC,oBAAoB,UAAQ,EAC5B,UAAU,GAAE,MAAM,GAAG,SAAkB,EACvC,gBAAgB,UAAQ,EACxB,MAAM,CAAC,EAAE,cAAc,EACvB,gBAAgB,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,GAC9C,UAAU,CAAC,KAAK,CAAC,CAgJnB"}
|
|
@@ -18,7 +18,7 @@ function buildNotExistsConditions(item) {
|
|
|
18
18
|
/**
|
|
19
19
|
* Creates a PutBuilder for an item and table.
|
|
20
20
|
*/
|
|
21
|
-
function createPutBuilder(tableName, item, client, prevConditions = [], shouldCheckNotExists = false, returnMode = 'NONE', enableTimestamps = false, logger) {
|
|
21
|
+
function createPutBuilder(tableName, item, client, prevConditions = [], shouldCheckNotExists = false, returnMode = 'NONE', enableTimestamps = false, logger, consumedCapacity) {
|
|
22
22
|
const conditions = [...prevConditions];
|
|
23
23
|
const build = () => ({
|
|
24
24
|
where(fn) {
|
|
@@ -30,13 +30,16 @@ function createPutBuilder(tableName, item, client, prevConditions = [], shouldCh
|
|
|
30
30
|
// Create a scoped opBuilder for this operation to avoid global state
|
|
31
31
|
const opBuilder = (0, shared_1.createOpBuilder)();
|
|
32
32
|
const condition = fn(attrs, opBuilder);
|
|
33
|
-
return createPutBuilder(tableName, item, client, [...conditions, condition], shouldCheckNotExists, returnMode, enableTimestamps, logger);
|
|
33
|
+
return createPutBuilder(tableName, item, client, [...conditions, condition], shouldCheckNotExists, returnMode, enableTimestamps, logger, consumedCapacity);
|
|
34
34
|
},
|
|
35
35
|
ifNotExists() {
|
|
36
|
-
return createPutBuilder(tableName, item, client, conditions, true, returnMode, enableTimestamps, logger);
|
|
36
|
+
return createPutBuilder(tableName, item, client, conditions, true, returnMode, enableTimestamps, logger, consumedCapacity);
|
|
37
37
|
},
|
|
38
38
|
returning(mode) {
|
|
39
|
-
return createPutBuilder(tableName, item, client, conditions, shouldCheckNotExists, mode, enableTimestamps, logger);
|
|
39
|
+
return createPutBuilder(tableName, item, client, conditions, shouldCheckNotExists, mode, enableTimestamps, logger, consumedCapacity);
|
|
40
|
+
},
|
|
41
|
+
returnConsumedCapacity(mode) {
|
|
42
|
+
return createPutBuilder(tableName, item, client, conditions, shouldCheckNotExists, returnMode, enableTimestamps, logger, mode);
|
|
40
43
|
},
|
|
41
44
|
dbParams() {
|
|
42
45
|
let finalConditions = [...conditions];
|
|
@@ -85,6 +88,7 @@ function createPutBuilder(tableName, item, client, prevConditions = [], shouldCh
|
|
|
85
88
|
...(Object.keys(expressionAttributeValues).length && {
|
|
86
89
|
ExpressionAttributeValues: expressionAttributeValues,
|
|
87
90
|
}),
|
|
91
|
+
...(consumedCapacity && { ReturnConsumedCapacity: consumedCapacity }),
|
|
88
92
|
...extra,
|
|
89
93
|
};
|
|
90
94
|
},
|
|
@@ -14,6 +14,16 @@ export interface PutBuilder<Model> extends Omit<OperationBuilder<Model>, 'dbPara
|
|
|
14
14
|
* - ALL_OLD: Returns the item as it was before being replaced (if it existed)
|
|
15
15
|
*/
|
|
16
16
|
returning(mode: 'NONE' | 'ALL_OLD'): PutBuilder<Model>;
|
|
17
|
+
/**
|
|
18
|
+
* Configures the ReturnConsumedCapacity parameter so DynamoDB reports
|
|
19
|
+
* how many WCUs the put consumed. Useful for diagnosing throttling and
|
|
20
|
+
* accounting for index amplification on tables with multiple GSIs.
|
|
21
|
+
*
|
|
22
|
+
* - INDEXES: Returns consumed capacity for table and indexes
|
|
23
|
+
* - TOTAL: Returns total consumed capacity
|
|
24
|
+
* - NONE: No consumed capacity data returned (default)
|
|
25
|
+
*/
|
|
26
|
+
returnConsumedCapacity(mode: 'INDEXES' | 'TOTAL' | 'NONE'): PutBuilder<Model>;
|
|
17
27
|
/**
|
|
18
28
|
* Converts the builder state to DynamoDB PutItem parameters
|
|
19
29
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/builders/put/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,UAAU,CAAC,KAAK,CAAE,SAAQ,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IAClF;;OAEG;IACH,WAAW,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IAEjC;;;;OAIG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IAEvD;;OAEG;IACH,QAAQ,IAAI,eAAe,CAAC;CAC7B"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/builders/put/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,UAAU,CAAC,KAAK,CAAE,SAAQ,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IAClF;;OAEG;IACH,WAAW,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IAEjC;;;;OAIG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IAEvD;;;;;;;;OAQG;IACH,sBAAsB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IAE9E;;OAEG;IACH,QAAQ,IAAI,eAAe,CAAC;CAC7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-query-builder.d.ts","sourceRoot":"","sources":["../../../src/builders/query/create-query-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAM1D,OAAO,EAAE,YAAY,EAA8B,MAAM,SAAS,CAAC;AACnE,OAAO,EAAiB,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAElE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"create-query-builder.d.ts","sourceRoot":"","sources":["../../../src/builders/query/create-query-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAM1D,OAAO,EAAE,YAAY,EAA8B,MAAM,SAAS,CAAC;AACnE,OAAO,EAAiB,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAElE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAkd7D;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EACtC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,cAAc,EACtB,KAAK,CAAC,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,cAAc,EACvB,UAAU,CAAC,EAAE,MAAM,GAClB,YAAY,CAAC,KAAK,CAAC,CA6BrB"}
|
|
@@ -23,6 +23,21 @@ function keyBelongsToIndex(keyName, keyDef, indexName) {
|
|
|
23
23
|
}
|
|
24
24
|
return keyName === `${indexName}PK` || keyName === `${indexName}SK`;
|
|
25
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Cache of compiled `#<fieldName>\b` regexes used to rewrite a leaf
|
|
28
|
+
* condition's expression when its field maps onto a key. Without this,
|
|
29
|
+
* `separateConditions` allocates a fresh `RegExp` per AND-leaf per query —
|
|
30
|
+
* cheap individually, noisy under load on multi-condition queries.
|
|
31
|
+
*/
|
|
32
|
+
const fieldPlaceholderRegexCache = new Map();
|
|
33
|
+
function fieldPlaceholderRegex(fieldName) {
|
|
34
|
+
let re = fieldPlaceholderRegexCache.get(fieldName);
|
|
35
|
+
if (!re) {
|
|
36
|
+
re = new RegExp(`#${fieldName}\\b`, 'g');
|
|
37
|
+
fieldPlaceholderRegexCache.set(fieldName, re);
|
|
38
|
+
}
|
|
39
|
+
return re;
|
|
40
|
+
}
|
|
26
41
|
/**
|
|
27
42
|
* Maps a model attribute name to its corresponding DynamoDB key name (PK/SK)
|
|
28
43
|
* Also returns the key template for value transformation
|
|
@@ -127,7 +142,7 @@ function separateConditions(condition, model, indexName) {
|
|
|
127
142
|
}
|
|
128
143
|
const rewrittenCond = {
|
|
129
144
|
...cond,
|
|
130
|
-
expression: cond.expression.replace(
|
|
145
|
+
expression: cond.expression.replace(fieldPlaceholderRegex(fieldName), `#${keyInfo.keyName}`),
|
|
131
146
|
names: {
|
|
132
147
|
[`#${keyInfo.keyName}`]: keyInfo.keyName,
|
|
133
148
|
},
|
|
@@ -209,6 +224,12 @@ function createQueryExecutor(state) {
|
|
|
209
224
|
exclusiveStartKey: key,
|
|
210
225
|
});
|
|
211
226
|
},
|
|
227
|
+
returnConsumedCapacity(mode) {
|
|
228
|
+
return createQueryExecutor({
|
|
229
|
+
...state,
|
|
230
|
+
returnConsumedCapacity: mode,
|
|
231
|
+
});
|
|
232
|
+
},
|
|
212
233
|
dbParams() {
|
|
213
234
|
if (!state.condition) {
|
|
214
235
|
throw new Error('No where condition specified');
|
|
@@ -307,6 +328,9 @@ function createQueryExecutor(state) {
|
|
|
307
328
|
...(state.exclusiveStartKey && {
|
|
308
329
|
ExclusiveStartKey: state.exclusiveStartKey,
|
|
309
330
|
}),
|
|
331
|
+
...(state.returnConsumedCapacity && {
|
|
332
|
+
ReturnConsumedCapacity: state.returnConsumedCapacity,
|
|
333
|
+
}),
|
|
310
334
|
};
|
|
311
335
|
},
|
|
312
336
|
/**
|
|
@@ -48,6 +48,16 @@ export interface QueryExecutor<Model> extends ExecutableBuilder<Model[]> {
|
|
|
48
48
|
* Start query from a specific key (for pagination)
|
|
49
49
|
*/
|
|
50
50
|
startFrom(key: Record<string, any>): QueryExecutor<Model>;
|
|
51
|
+
/**
|
|
52
|
+
* Configures the ReturnConsumedCapacity parameter so DynamoDB reports
|
|
53
|
+
* how many RCUs the query consumed. Useful for diagnosing throttling
|
|
54
|
+
* and confirming a query hit the expected (G)SI.
|
|
55
|
+
*
|
|
56
|
+
* - INDEXES: Returns consumed capacity for table and indexes
|
|
57
|
+
* - TOTAL: Returns total consumed capacity
|
|
58
|
+
* - NONE: No consumed capacity data returned (default)
|
|
59
|
+
*/
|
|
60
|
+
returnConsumedCapacity(mode: 'INDEXES' | 'TOTAL' | 'NONE'): QueryExecutor<Model>;
|
|
51
61
|
/**
|
|
52
62
|
* Returns the raw DynamoDB query parameters
|
|
53
63
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/builders/query/types.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEjF;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,KAAK;IAChC;;OAEG;IACH,KAAK,EAAE,KAAK,EAAE,CAAC;IAEf;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAEvC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,KAAK,CAAE,SAAQ,iBAAiB,CAAC,KAAK,EAAE,CAAC;IACtE;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAE3C;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAEzD;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAElD;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAErD;;OAEG;IACH,cAAc,IAAI,aAAa,CAAC,KAAK,CAAC,CAAC;IAEvC;;OAEG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAE1D;;OAEG;IACH,QAAQ,IAAI,GAAG,CAAC;IAEhB;;OAEG;IACH,OAAO,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAE5B;;OAEG;IACH,qBAAqB,IAAI,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IAErD;;;;;;;;;;;;;;OAcG;IACH,OAAO,IAAI,qBAAqB,CAAC,KAAK,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,KAAK;IACjC;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,SAAS,KAAK,SAAS,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;CACzF"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/builders/query/types.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEjF;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,KAAK;IAChC;;OAEG;IACH,KAAK,EAAE,KAAK,EAAE,CAAC;IAEf;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAEvC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,KAAK,CAAE,SAAQ,iBAAiB,CAAC,KAAK,EAAE,CAAC;IACtE;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAE3C;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAEzD;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAElD;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAErD;;OAEG;IACH,cAAc,IAAI,aAAa,CAAC,KAAK,CAAC,CAAC;IAEvC;;OAEG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAE1D;;;;;;;;OAQG;IACH,sBAAsB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAEjF;;OAEG;IACH,QAAQ,IAAI,GAAG,CAAC;IAEhB;;OAEG;IACH,OAAO,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAE5B;;OAEG;IACH,qBAAqB,IAAI,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IAErD;;;;;;;;;;;;;;OAcG;IACH,OAAO,IAAI,qBAAqB,CAAC,KAAK,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,KAAK;IACjC;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,SAAS,KAAK,SAAS,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;CACzF"}
|
|
@@ -8,5 +8,5 @@ import { DynamoDBLogger } from '../../utils/dynamodb-logger';
|
|
|
8
8
|
export declare function createScanBuilder<Model>(tableName: string, client: DynamoDBClient, filters?: Condition[], projectionAttrs?: (keyof Model)[], limitValue?: number, isConsistentRead?: boolean, indexName?: string, exclusiveStartKey?: Record<string, any>, segmentConfig?: {
|
|
9
9
|
segment: number;
|
|
10
10
|
totalSegments: number;
|
|
11
|
-
}, logger?: DynamoDBLogger): ScanBuilder<Model>;
|
|
11
|
+
}, logger?: DynamoDBLogger, consumedCapacity?: 'INDEXES' | 'TOTAL' | 'NONE'): ScanBuilder<Model>;
|
|
12
12
|
//# sourceMappingURL=create-scan-builder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-scan-builder.d.ts","sourceRoot":"","sources":["../../../src/builders/scan/create-scan-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAGL,SAAS,EAGV,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,WAAW,EAAc,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,cAAc,EACtB,OAAO,GAAE,SAAS,EAAO,EACzB,eAAe,GAAE,CAAC,MAAM,KAAK,CAAC,EAAO,EACrC,UAAU,CAAC,EAAE,MAAM,EACnB,gBAAgB,UAAQ,EACxB,SAAS,CAAC,EAAE,MAAM,EAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACvC,aAAa,CAAC,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,EAC1D,MAAM,CAAC,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"create-scan-builder.d.ts","sourceRoot":"","sources":["../../../src/builders/scan/create-scan-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAGL,SAAS,EAGV,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,WAAW,EAAc,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,cAAc,EACtB,OAAO,GAAE,SAAS,EAAO,EACzB,eAAe,GAAE,CAAC,MAAM,KAAK,CAAC,EAAO,EACrC,UAAU,CAAC,EAAE,MAAM,EACnB,gBAAgB,UAAQ,EACxB,SAAS,CAAC,EAAE,MAAM,EAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACvC,aAAa,CAAC,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,EAC1D,MAAM,CAAC,EAAE,cAAc,EACvB,gBAAgB,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,GAC9C,WAAW,CAAC,KAAK,CAAC,CAwQpB"}
|
|
@@ -6,7 +6,7 @@ const shared_1 = require("../shared");
|
|
|
6
6
|
/**
|
|
7
7
|
* Creates a ScanBuilder for scanning a table or index.
|
|
8
8
|
*/
|
|
9
|
-
function createScanBuilder(tableName, client, filters = [], projectionAttrs = [], limitValue, isConsistentRead = false, indexName, exclusiveStartKey, segmentConfig, logger) {
|
|
9
|
+
function createScanBuilder(tableName, client, filters = [], projectionAttrs = [], limitValue, isConsistentRead = false, indexName, exclusiveStartKey, segmentConfig, logger, consumedCapacity) {
|
|
10
10
|
const build = () => ({
|
|
11
11
|
filter(fn) {
|
|
12
12
|
const attrs = new Proxy({}, {
|
|
@@ -16,25 +16,28 @@ function createScanBuilder(tableName, client, filters = [], projectionAttrs = []
|
|
|
16
16
|
});
|
|
17
17
|
const opBuilder = (0, shared_1.createOpBuilder)();
|
|
18
18
|
const condition = fn(attrs, opBuilder);
|
|
19
|
-
return createScanBuilder(tableName, client, [...filters, condition], projectionAttrs, limitValue, isConsistentRead, indexName, exclusiveStartKey, segmentConfig, logger);
|
|
19
|
+
return createScanBuilder(tableName, client, [...filters, condition], projectionAttrs, limitValue, isConsistentRead, indexName, exclusiveStartKey, segmentConfig, logger, consumedCapacity);
|
|
20
20
|
},
|
|
21
21
|
select(attrs) {
|
|
22
|
-
return createScanBuilder(tableName, client, filters, attrs, limitValue, isConsistentRead, indexName, exclusiveStartKey, segmentConfig, logger);
|
|
22
|
+
return createScanBuilder(tableName, client, filters, attrs, limitValue, isConsistentRead, indexName, exclusiveStartKey, segmentConfig, logger, consumedCapacity);
|
|
23
23
|
},
|
|
24
24
|
limit(count) {
|
|
25
|
-
return createScanBuilder(tableName, client, filters, projectionAttrs, count, isConsistentRead, indexName, exclusiveStartKey, segmentConfig, logger);
|
|
25
|
+
return createScanBuilder(tableName, client, filters, projectionAttrs, count, isConsistentRead, indexName, exclusiveStartKey, segmentConfig, logger, consumedCapacity);
|
|
26
26
|
},
|
|
27
27
|
consistentRead() {
|
|
28
|
-
return createScanBuilder(tableName, client, filters, projectionAttrs, limitValue, true, indexName, exclusiveStartKey, segmentConfig, logger);
|
|
28
|
+
return createScanBuilder(tableName, client, filters, projectionAttrs, limitValue, true, indexName, exclusiveStartKey, segmentConfig, logger, consumedCapacity);
|
|
29
29
|
},
|
|
30
30
|
usingIndex(index) {
|
|
31
|
-
return createScanBuilder(tableName, client, filters, projectionAttrs, limitValue, isConsistentRead, index, exclusiveStartKey, segmentConfig, logger);
|
|
31
|
+
return createScanBuilder(tableName, client, filters, projectionAttrs, limitValue, isConsistentRead, index, exclusiveStartKey, segmentConfig, logger, consumedCapacity);
|
|
32
32
|
},
|
|
33
33
|
startFrom(key) {
|
|
34
|
-
return createScanBuilder(tableName, client, filters, projectionAttrs, limitValue, isConsistentRead, indexName, key, segmentConfig, logger);
|
|
34
|
+
return createScanBuilder(tableName, client, filters, projectionAttrs, limitValue, isConsistentRead, indexName, key, segmentConfig, logger, consumedCapacity);
|
|
35
35
|
},
|
|
36
36
|
segment(segmentNumber, totalSegments) {
|
|
37
|
-
return createScanBuilder(tableName, client, filters, projectionAttrs, limitValue, isConsistentRead, indexName, exclusiveStartKey, { segment: segmentNumber, totalSegments }, logger);
|
|
37
|
+
return createScanBuilder(tableName, client, filters, projectionAttrs, limitValue, isConsistentRead, indexName, exclusiveStartKey, { segment: segmentNumber, totalSegments }, logger, consumedCapacity);
|
|
38
|
+
},
|
|
39
|
+
returnConsumedCapacity(mode) {
|
|
40
|
+
return createScanBuilder(tableName, client, filters, projectionAttrs, limitValue, isConsistentRead, indexName, exclusiveStartKey, segmentConfig, logger, mode);
|
|
38
41
|
},
|
|
39
42
|
dbParams() {
|
|
40
43
|
let filterExpression = '';
|
|
@@ -98,6 +101,9 @@ function createScanBuilder(tableName, client, filters = [], projectionAttrs = []
|
|
|
98
101
|
params.Segment = segmentConfig.segment;
|
|
99
102
|
params.TotalSegments = segmentConfig.totalSegments;
|
|
100
103
|
}
|
|
104
|
+
if (consumedCapacity) {
|
|
105
|
+
params.ReturnConsumedCapacity = consumedCapacity;
|
|
106
|
+
}
|
|
101
107
|
return params;
|
|
102
108
|
},
|
|
103
109
|
/**
|
|
@@ -52,6 +52,16 @@ export interface ScanBuilder<Model> extends ExecutableBuilder<Model[]> {
|
|
|
52
52
|
* Returns a new immutable builder.
|
|
53
53
|
*/
|
|
54
54
|
segment(segmentNumber: number, totalSegments: number): ScanBuilder<Model>;
|
|
55
|
+
/**
|
|
56
|
+
* Configures the ReturnConsumedCapacity parameter so DynamoDB reports
|
|
57
|
+
* how many RCUs the scan consumed. Useful for diagnosing throttling
|
|
58
|
+
* and confirming filter selectivity.
|
|
59
|
+
*
|
|
60
|
+
* - INDEXES: Returns consumed capacity for table and indexes
|
|
61
|
+
* - TOTAL: Returns total consumed capacity
|
|
62
|
+
* - NONE: No consumed capacity data returned (default)
|
|
63
|
+
*/
|
|
64
|
+
returnConsumedCapacity(mode: 'INDEXES' | 'TOTAL' | 'NONE'): ScanBuilder<Model>;
|
|
55
65
|
/**
|
|
56
66
|
* Executes a single Scan request and returns the page along with the
|
|
57
67
|
* `lastEvaluatedKey` cursor and counts. Use this when you want to drive
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/builders/scan/types.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEjF;;GAEG;AACH,MAAM,WAAW,UAAU,CAAC,KAAK;IAC/B,mCAAmC;IACnC,KAAK,EAAE,KAAK,EAAE,CAAC;IACf,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACvC,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW,CAAC,KAAK,CAAE,SAAQ,iBAAiB,CAAC,KAAK,EAAE,CAAC;IACpE;;;OAGG;IACH,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,SAAS,KAAK,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAEvF;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAEnD;;;OAGG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAEzC;;;OAGG;IACH,cAAc,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC;IAErC;;;OAGG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAElD;;;OAGG;IACH,SAAS,CAAC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAEtE;;;OAGG;IACH,OAAO,CAAC,aAAa,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAE1E;;;;OAIG;IACH,qBAAqB,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IAEpD;;;;;;;;;;;;;;OAcG;IACH,OAAO,IAAI,qBAAqB,CAAC,KAAK,CAAC,CAAC;CACzC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/builders/scan/types.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEjF;;GAEG;AACH,MAAM,WAAW,UAAU,CAAC,KAAK;IAC/B,mCAAmC;IACnC,KAAK,EAAE,KAAK,EAAE,CAAC;IACf,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACvC,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW,CAAC,KAAK,CAAE,SAAQ,iBAAiB,CAAC,KAAK,EAAE,CAAC;IACpE;;;OAGG;IACH,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,SAAS,KAAK,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAEvF;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAEnD;;;OAGG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAEzC;;;OAGG;IACH,cAAc,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC;IAErC;;;OAGG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAElD;;;OAGG;IACH,SAAS,CAAC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAEtE;;;OAGG;IACH,OAAO,CAAC,aAAa,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAE1E;;;;;;;;OAQG;IACH,sBAAsB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAE/E;;;;OAIG;IACH,qBAAqB,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IAEpD;;;;;;;;;;;;;;OAcG;IACH,OAAO,IAAI,qBAAqB,CAAC,KAAK,CAAC,CAAC;CACzC"}
|
|
@@ -16,5 +16,5 @@ export declare function createUpdateBuilder<Model>(tableName: string, key: Parti
|
|
|
16
16
|
remove: UpdateAction[];
|
|
17
17
|
add: UpdateAction[];
|
|
18
18
|
delete: UpdateAction[];
|
|
19
|
-
}, returnMode?: 'NONE' | 'ALL_OLD' | 'ALL_NEW' | 'UPDATED_OLD' | 'UPDATED_NEW', valueCounter?: number, enableTimestamps?: boolean, logger?: DynamoDBLogger, indexContext?: IndexContext, setInputs?: Record<string, any
|
|
19
|
+
}, returnMode?: 'NONE' | 'ALL_OLD' | 'ALL_NEW' | 'UPDATED_OLD' | 'UPDATED_NEW', valueCounter?: number, enableTimestamps?: boolean, logger?: DynamoDBLogger, indexContext?: IndexContext, setInputs?: Record<string, any>, consumedCapacity?: 'INDEXES' | 'TOTAL' | 'NONE'): UpdateBuilder<Model>;
|
|
20
20
|
//# sourceMappingURL=create-update-builder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-update-builder.d.ts","sourceRoot":"","sources":["../../../src/builders/update/create-update-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAgC,SAAS,EAA4B,MAAM,WAAW,CAAC;AAC9F,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"create-update-builder.d.ts","sourceRoot":"","sources":["../../../src/builders/update/create-update-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAgC,SAAS,EAA4B,MAAM,WAAW,CAAC;AAC9F,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAyB7D;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EACvC,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,EACnB,MAAM,EAAE,cAAc,EACtB,cAAc,GAAE,SAAS,EAAO,EAChC,aAAa,GAAE;IACb,GAAG,EAAE,YAAY,EAAE,CAAC;IACpB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,GAAG,EAAE,YAAY,EAAE,CAAC;IACpB,MAAM,EAAE,YAAY,EAAE,CAAC;CACuB,EAChD,UAAU,GAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,GAAG,aAAsB,EACnF,YAAY,SAAI,EAChB,gBAAgB,UAAQ,EACxB,MAAM,CAAC,EAAE,cAAc,EACvB,YAAY,CAAC,EAAE,YAAY,EAC3B,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,EACnC,gBAAgB,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,GAC9C,aAAa,CAAC,KAAK,CAAC,CAidtB"}
|
|
@@ -13,6 +13,18 @@ function extractAttrName(action) {
|
|
|
13
13
|
const m = action.expression.match(/^\s*#([A-Za-z0-9_]+)\s*=/);
|
|
14
14
|
return m?.[1];
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Pull the attribute name from any update action (set / remove / add / delete).
|
|
18
|
+
* Each action emitted by this builder carries exactly one entry in `names`
|
|
19
|
+
* mapping `#<attr>` → `<attr>`, so the value side of that map is the source
|
|
20
|
+
* of truth regardless of the surrounding expression syntax.
|
|
21
|
+
*/
|
|
22
|
+
function actionAttrName(action) {
|
|
23
|
+
if (!action.names)
|
|
24
|
+
return undefined;
|
|
25
|
+
const values = Object.values(action.names);
|
|
26
|
+
return values[0];
|
|
27
|
+
}
|
|
16
28
|
/**
|
|
17
29
|
* Creates an UpdateBuilder for an item key and table.
|
|
18
30
|
*
|
|
@@ -22,7 +34,7 @@ function extractAttrName(action) {
|
|
|
22
34
|
* cannot be fully resolved from the primary-key vars plus the updates, building
|
|
23
35
|
* the params throws — the caller must include the missing fields in `.set()`.
|
|
24
36
|
*/
|
|
25
|
-
function createUpdateBuilder(tableName, key, client, prevConditions = [], updateActions = { set: [], remove: [], add: [], delete: [] }, returnMode = 'NONE', valueCounter = 0, enableTimestamps = false, logger, indexContext, setInputs = {}) {
|
|
37
|
+
function createUpdateBuilder(tableName, key, client, prevConditions = [], updateActions = { set: [], remove: [], add: [], delete: [] }, returnMode = 'NONE', valueCounter = 0, enableTimestamps = false, logger, indexContext, setInputs = {}, consumedCapacity) {
|
|
26
38
|
const conditions = [...prevConditions];
|
|
27
39
|
const getUniqueValueName = (baseName) => {
|
|
28
40
|
return `${baseName}_${valueCounter++}`;
|
|
@@ -42,7 +54,7 @@ function createUpdateBuilder(tableName, key, client, prevConditions = [], update
|
|
|
42
54
|
});
|
|
43
55
|
const opBuilder = (0, shared_1.createOpBuilder)();
|
|
44
56
|
const condition = fn(attrs, opBuilder);
|
|
45
|
-
return createUpdateBuilder(tableName, key, client, [...conditions, condition], updateActions, returnMode, valueCounter, enableTimestamps, logger, indexContext, setInputs);
|
|
57
|
+
return createUpdateBuilder(tableName, key, client, [...conditions, condition], updateActions, returnMode, valueCounter, enableTimestamps, logger, indexContext, setInputs, consumedCapacity);
|
|
46
58
|
},
|
|
47
59
|
set(attrOrUpdates, value) {
|
|
48
60
|
// When no value is provided and the first arg is a plain object,
|
|
@@ -65,7 +77,7 @@ function createUpdateBuilder(tableName, key, client, prevConditions = [], update
|
|
|
65
77
|
});
|
|
66
78
|
newSetInputs[attrName] = val;
|
|
67
79
|
}
|
|
68
|
-
return createUpdateBuilder(tableName, key, client, conditions, { ...updateActions, set: [...updateActions.set, ...newActions] }, returnMode, valueCounter, enableTimestamps, logger, indexContext, newSetInputs);
|
|
80
|
+
return createUpdateBuilder(tableName, key, client, conditions, { ...updateActions, set: [...updateActions.set, ...newActions] }, returnMode, valueCounter, enableTimestamps, logger, indexContext, newSetInputs, consumedCapacity);
|
|
69
81
|
}
|
|
70
82
|
// Single update case
|
|
71
83
|
const attrName = normalizeAttr(attrOrUpdates);
|
|
@@ -75,7 +87,7 @@ function createUpdateBuilder(tableName, key, client, prevConditions = [], update
|
|
|
75
87
|
names: { [`#${attrName}`]: attrName },
|
|
76
88
|
values: { [`:${valueName}`]: value },
|
|
77
89
|
};
|
|
78
|
-
return createUpdateBuilder(tableName, key, client, conditions, { ...updateActions, set: [...updateActions.set, action] }, returnMode, valueCounter, enableTimestamps, logger, indexContext, { ...setInputs, [attrName]: value });
|
|
90
|
+
return createUpdateBuilder(tableName, key, client, conditions, { ...updateActions, set: [...updateActions.set, action] }, returnMode, valueCounter, enableTimestamps, logger, indexContext, { ...setInputs, [attrName]: value }, consumedCapacity);
|
|
79
91
|
},
|
|
80
92
|
remove(attr) {
|
|
81
93
|
const attrName = normalizeAttr(attr);
|
|
@@ -83,7 +95,7 @@ function createUpdateBuilder(tableName, key, client, prevConditions = [], update
|
|
|
83
95
|
expression: `#${attrName}`,
|
|
84
96
|
names: { [`#${attrName}`]: attrName },
|
|
85
97
|
};
|
|
86
|
-
return createUpdateBuilder(tableName, key, client, conditions, { ...updateActions, remove: [...updateActions.remove, action] }, returnMode, valueCounter, enableTimestamps, logger, indexContext, setInputs);
|
|
98
|
+
return createUpdateBuilder(tableName, key, client, conditions, { ...updateActions, remove: [...updateActions.remove, action] }, returnMode, valueCounter, enableTimestamps, logger, indexContext, setInputs, consumedCapacity);
|
|
87
99
|
},
|
|
88
100
|
add(attr, value) {
|
|
89
101
|
const attrName = normalizeAttr(attr);
|
|
@@ -93,7 +105,7 @@ function createUpdateBuilder(tableName, key, client, prevConditions = [], update
|
|
|
93
105
|
names: { [`#${attrName}`]: attrName },
|
|
94
106
|
values: { [`:${valueName}`]: value },
|
|
95
107
|
};
|
|
96
|
-
return createUpdateBuilder(tableName, key, client, conditions, { ...updateActions, add: [...updateActions.add, action] }, returnMode, valueCounter, enableTimestamps, logger, indexContext, setInputs);
|
|
108
|
+
return createUpdateBuilder(tableName, key, client, conditions, { ...updateActions, add: [...updateActions.add, action] }, returnMode, valueCounter, enableTimestamps, logger, indexContext, setInputs, consumedCapacity);
|
|
97
109
|
},
|
|
98
110
|
delete(attr, value) {
|
|
99
111
|
const attrName = normalizeAttr(attr);
|
|
@@ -103,10 +115,13 @@ function createUpdateBuilder(tableName, key, client, prevConditions = [], update
|
|
|
103
115
|
names: { [`#${attrName}`]: attrName },
|
|
104
116
|
values: { [`:${valueName}`]: value },
|
|
105
117
|
};
|
|
106
|
-
return createUpdateBuilder(tableName, key, client, conditions, { ...updateActions, delete: [...updateActions.delete, action] }, returnMode, valueCounter, enableTimestamps, logger, indexContext, setInputs);
|
|
118
|
+
return createUpdateBuilder(tableName, key, client, conditions, { ...updateActions, delete: [...updateActions.delete, action] }, returnMode, valueCounter, enableTimestamps, logger, indexContext, setInputs, consumedCapacity);
|
|
107
119
|
},
|
|
108
120
|
returning(mode) {
|
|
109
|
-
return createUpdateBuilder(tableName, key, client, conditions, updateActions, mode, valueCounter, enableTimestamps, logger, indexContext, setInputs);
|
|
121
|
+
return createUpdateBuilder(tableName, key, client, conditions, updateActions, mode, valueCounter, enableTimestamps, logger, indexContext, setInputs, consumedCapacity);
|
|
122
|
+
},
|
|
123
|
+
returnConsumedCapacity(mode) {
|
|
124
|
+
return createUpdateBuilder(tableName, key, client, conditions, updateActions, returnMode, valueCounter, enableTimestamps, logger, indexContext, setInputs, mode);
|
|
110
125
|
},
|
|
111
126
|
dbParams() {
|
|
112
127
|
// Build UpdateExpression from actions
|
|
@@ -120,6 +135,68 @@ function createUpdateBuilder(tableName, key, client, prevConditions = [], update
|
|
|
120
135
|
// key vars + the .set() payload, we throw — recomputing from the
|
|
121
136
|
// existing item would require an extra read the builder won't do.
|
|
122
137
|
if (indexContext) {
|
|
138
|
+
// Collect the attribute name targeted by every update action,
|
|
139
|
+
// grouped by op. `setInputs` carries the .set() payload (already
|
|
140
|
+
// structured) — for remove/add/delete we read from the action's
|
|
141
|
+
// attribute-name map.
|
|
142
|
+
const setFields = Object.keys(setInputs);
|
|
143
|
+
const removeFields = updateActions.remove
|
|
144
|
+
.map(actionAttrName)
|
|
145
|
+
.filter((n) => !!n);
|
|
146
|
+
const addFields = updateActions.add
|
|
147
|
+
.map(actionAttrName)
|
|
148
|
+
.filter((n) => !!n);
|
|
149
|
+
const deleteFields = updateActions.delete
|
|
150
|
+
.map(actionAttrName)
|
|
151
|
+
.filter((n) => !!n);
|
|
152
|
+
// Guard 1: primary-key template fields are immutable in DynamoDB.
|
|
153
|
+
// The Key on the UpdateItem request fixes the row to operate on; if
|
|
154
|
+
// the user changes a field that participates in the PK/SK template,
|
|
155
|
+
// the row's PK doesn't move (DynamoDB doesn't allow that) but the
|
|
156
|
+
// attribute does — leaving an inconsistent row whose PK encodes the
|
|
157
|
+
// old value. Catch this on every op (.set / .remove / .add / .delete)
|
|
158
|
+
// before it leaves the process.
|
|
159
|
+
const primaryKeyTemplateVars = new Set();
|
|
160
|
+
for (const keyDef of Object.values(indexContext.model.key)) {
|
|
161
|
+
for (const v of (0, model_utils_1.extractTemplateVars)(keyDef.value)) {
|
|
162
|
+
primaryKeyTemplateVars.add(v);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const allTouched = [...setFields, ...removeFields, ...addFields, ...deleteFields];
|
|
166
|
+
const pkConflicts = [
|
|
167
|
+
...new Set(allTouched.filter((f) => primaryKeyTemplateVars.has(f))),
|
|
168
|
+
];
|
|
169
|
+
if (pkConflicts.length > 0) {
|
|
170
|
+
throw new Error(`Cannot update field(s) [${pkConflicts.join(', ')}] — they participate ` +
|
|
171
|
+
`in the primary key template, which is immutable in DynamoDB. To ` +
|
|
172
|
+
`"rename" a primary-key value, delete the old item and put a new one ` +
|
|
173
|
+
`(ideally inside a transactWrite for atomicity).`);
|
|
174
|
+
}
|
|
175
|
+
// Guard 2: .add() / .remove() / .delete() against a field used in a
|
|
176
|
+
// SECONDARY-index template. The recompute path needs an explicit new
|
|
177
|
+
// value to resolve the template — ADD increments without exposing
|
|
178
|
+
// the new value, REMOVE strips the field entirely, and DELETE
|
|
179
|
+
// mutates a Set without naming a scalar. Switching to .set(field,
|
|
180
|
+
// newValue) lets the recompute path handle it correctly.
|
|
181
|
+
if (indexContext.model.index) {
|
|
182
|
+
const indexTemplateVars = new Set();
|
|
183
|
+
for (const indexDef of Object.values(indexContext.model.index)) {
|
|
184
|
+
for (const v of (0, model_utils_1.extractTemplateVars)(indexDef.value)) {
|
|
185
|
+
indexTemplateVars.add(v);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const nonSetTouches = [...removeFields, ...addFields, ...deleteFields];
|
|
189
|
+
const gsiConflicts = [
|
|
190
|
+
...new Set(nonSetTouches.filter((f) => indexTemplateVars.has(f))),
|
|
191
|
+
];
|
|
192
|
+
if (gsiConflicts.length > 0) {
|
|
193
|
+
throw new Error(`Cannot use .add() / .remove() / .delete() on field(s) ` +
|
|
194
|
+
`[${gsiConflicts.join(', ')}] — they participate in a ` +
|
|
195
|
+
`secondary-index template, and the affected index key cannot be ` +
|
|
196
|
+
`recomputed without an explicit new value. Use .set(field, ` +
|
|
197
|
+
`newValue) instead so the index key is recomputed atomically.`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
123
200
|
const { actions: idxActions, missing } = (0, model_utils_1.computeIndexUpdates)(indexContext.model, indexContext.keyVars, setInputs);
|
|
124
201
|
if (missing.length > 0) {
|
|
125
202
|
const details = missing
|
|
@@ -246,6 +323,7 @@ function createUpdateBuilder(tableName, key, client, prevConditions = [], update
|
|
|
246
323
|
...(Object.keys(expressionAttributeValues).length && {
|
|
247
324
|
ExpressionAttributeValues: expressionAttributeValues,
|
|
248
325
|
}),
|
|
326
|
+
...(consumedCapacity && { ReturnConsumedCapacity: consumedCapacity }),
|
|
249
327
|
...extra,
|
|
250
328
|
};
|
|
251
329
|
},
|
|
@@ -46,6 +46,16 @@ export interface UpdateBuilder<Model> extends Omit<OperationBuilder<Model>, 'dbP
|
|
|
46
46
|
* Configures what values should be returned after the update operation
|
|
47
47
|
*/
|
|
48
48
|
returning(mode: 'NONE' | 'ALL_OLD' | 'ALL_NEW' | 'UPDATED_OLD' | 'UPDATED_NEW'): UpdateBuilder<Model>;
|
|
49
|
+
/**
|
|
50
|
+
* Configures the ReturnConsumedCapacity parameter so DynamoDB reports
|
|
51
|
+
* how many WCUs the update consumed. Useful for diagnosing throttling
|
|
52
|
+
* and validating cost when index keys are auto-recomputed.
|
|
53
|
+
*
|
|
54
|
+
* - INDEXES: Returns consumed capacity for table and indexes
|
|
55
|
+
* - TOTAL: Returns total consumed capacity
|
|
56
|
+
* - NONE: No consumed capacity data returned (default)
|
|
57
|
+
*/
|
|
58
|
+
returnConsumedCapacity(mode: 'INDEXES' | 'TOTAL' | 'NONE'): UpdateBuilder<Model>;
|
|
49
59
|
/**
|
|
50
60
|
* Converts the builder state to DynamoDB UpdateItem parameters
|
|
51
61
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/builders/update/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEtD;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,eAAe,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,KAAK,CAAE,SAAQ,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACrF;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,EAAE,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACnE,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAEnD;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,KAAK,GAAG,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAE1D;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,EAAE,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAEnE;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,EAAE,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAEtE;;OAEG;IACH,SAAS,CACP,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,GAAG,aAAa,GACnE,aAAa,CAAC,KAAK,CAAC,CAAC;IAExB;;OAEG;IACH,QAAQ,IAAI,kBAAkB,CAAC;CAChC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/builders/update/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEtD;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,eAAe,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,KAAK,CAAE,SAAQ,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACrF;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,EAAE,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACnE,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAEnD;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,KAAK,GAAG,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAE1D;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,EAAE,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAEnE;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,EAAE,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAEtE;;OAEG;IACH,SAAS,CACP,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,GAAG,aAAa,GACnE,aAAa,CAAC,KAAK,CAAC,CAAC;IAExB;;;;;;;;OAQG;IACH,sBAAsB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAEjF;;OAEG;IACH,QAAQ,IAAI,kBAAkB,CAAC;CAChC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-entity-api.d.ts","sourceRoot":"","sources":["../../src/entity/create-entity-api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AActF,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAMtD;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,GAAI,KAAK,SAAS,eAAe,EAC3D,WAAW,MAAM,EACjB,WAAW,MAAM,EACjB,OAAO,KAAK,EACZ,QAAQ,cAAc,EACtB,UAAS,gBAAqB,KAC7B,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"create-entity-api.d.ts","sourceRoot":"","sources":["../../src/entity/create-entity-api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AActF,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAMtD;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,GAAI,KAAK,SAAS,eAAe,EAC3D,WAAW,MAAM,EACjB,WAAW,MAAM,EACjB,OAAO,KAAK,EACZ,QAAQ,cAAc,EACtB,UAAS,gBAAqB,KAC7B,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,CA0OtE,CAAC"}
|
|
@@ -54,6 +54,14 @@ const createEntityAPI = (tableName, modelName, model, client, options = {}) => {
|
|
|
54
54
|
// Auto-filter by entity type so query() only returns items for this
|
|
55
55
|
// entity. Without this, queries on shared GSIs return items from other
|
|
56
56
|
// entities that share the same partition key.
|
|
57
|
+
//
|
|
58
|
+
// GOTCHA: this is implemented as a `FilterExpression` (`_type = …`),
|
|
59
|
+
// and DynamoDB applies `Limit` BEFORE filtering. On a single-table
|
|
60
|
+
// design where many entities share PKs, a `.limit(10)` query can
|
|
61
|
+
// return 0 items and a non-empty `LastEvaluatedKey` if none of the
|
|
62
|
+
// first 10 scanned items happen to belong to this entity. Either
|
|
63
|
+
// ignore Limit when type-mixing is heavy, or paginate via
|
|
64
|
+
// `iterate()` / `executeWithPagination()` and accumulate yourself.
|
|
57
65
|
const builder = (0, builders_1.createQueryBuilder)(tableName, client, model, logger, modelName);
|
|
58
66
|
// QueryBuilder exposes only `where()` — the executable surface lives
|
|
59
67
|
// on the QueryExecutor it returns. Wrap that executor's `execute()`
|
|
@@ -72,7 +80,13 @@ const createEntityAPI = (tableName, modelName, model, client, options = {}) => {
|
|
|
72
80
|
};
|
|
73
81
|
},
|
|
74
82
|
scan() {
|
|
75
|
-
// Auto-filter by entity type so scan only returns items for this entity
|
|
83
|
+
// Auto-filter by entity type so scan only returns items for this entity.
|
|
84
|
+
//
|
|
85
|
+
// Same Limit-vs-Filter gotcha as `query()`: DynamoDB applies `Limit`
|
|
86
|
+
// before the FilterExpression, so on a multi-entity table a
|
|
87
|
+
// `.limit(N)` scan may return fewer than N items of THIS entity even
|
|
88
|
+
// when more exist deeper in the table. Use `iterate()` for "give me
|
|
89
|
+
// every item of this entity" semantics.
|
|
76
90
|
const typeFilter = {
|
|
77
91
|
expression: '#_type = :_type',
|
|
78
92
|
names: { '#_type': '_type' },
|