@moicky/dynamodb 2.0.0 → 2.2.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/dist/lib/client.d.ts +8 -0
- package/dist/lib/client.js +8 -0
- package/dist/lib/defaultArguments.d.ts +33 -1
- package/dist/lib/defaultArguments.js +31 -0
- package/dist/lib/fixes.d.ts +51 -8
- package/dist/lib/fixes.js +36 -6
- package/dist/lib/schemas.d.ts +31 -0
- package/dist/lib/schemas.js +24 -0
- package/dist/operations/delete.d.ts +63 -2
- package/dist/operations/delete.js +59 -0
- package/dist/operations/get.d.ts +77 -2
- package/dist/operations/get.js +73 -0
- package/dist/operations/misc.d.ts +44 -0
- package/dist/operations/misc.js +44 -0
- package/dist/operations/put.d.ts +43 -2
- package/dist/operations/put.js +39 -0
- package/dist/operations/query.d.ts +124 -0
- package/dist/operations/query.js +188 -5
- package/dist/operations/update.d.ts +46 -0
- package/dist/operations/update.js +46 -0
- package/package.json +1 -1
- package/readme.md +19 -0
package/dist/operations/get.js
CHANGED
|
@@ -3,6 +3,32 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getAllItems = exports.getItems = exports.getItem = void 0;
|
|
4
4
|
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
5
5
|
const lib_1 = require("../lib");
|
|
6
|
+
/**
|
|
7
|
+
* Retrieves an item from the DynamoDB table using its key schema.
|
|
8
|
+
* @param key - The item with at least the partition key and the sort key (if applicable) of the item to get.
|
|
9
|
+
* @param args - The additional arguments to override or specify for {@link GetItemCommandInput}
|
|
10
|
+
* @returns A promise that resolves to the unmarshalled item
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* Get a single item
|
|
14
|
+
* ```javascript
|
|
15
|
+
* await getItem({
|
|
16
|
+
* PK: "User/1",
|
|
17
|
+
* SK: "Book/1",
|
|
18
|
+
* title: "The Great Gatsby",
|
|
19
|
+
* author: "F. Scott Fitzgerald",
|
|
20
|
+
* released: 1925,
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
* @example
|
|
24
|
+
* Get a single item in a different table
|
|
25
|
+
* ```javascript
|
|
26
|
+
* await getItem(
|
|
27
|
+
* { PK: "User/1", SK: "Book/1" },
|
|
28
|
+
* { TableName: "AnotherTable" }
|
|
29
|
+
* );
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
6
32
|
async function getItem(key, args = {}) {
|
|
7
33
|
args = (0, lib_1.withDefaults)(args, "getItem");
|
|
8
34
|
return (0, lib_1.getClient)()
|
|
@@ -14,6 +40,35 @@ async function getItem(key, args = {}) {
|
|
|
14
40
|
.then((res) => res?.Item && (0, lib_1.unmarshallWithOptions)(res.Item));
|
|
15
41
|
}
|
|
16
42
|
exports.getItem = getItem;
|
|
43
|
+
/**
|
|
44
|
+
* Retrieves multiple items from the DynamoDB table using their key schema.
|
|
45
|
+
* @param keys - The items with at least the partition key and the sort key (if applicable) of the items to get.
|
|
46
|
+
* @param args - The additional arguments to override or specify for {@link GetItemsArgs}
|
|
47
|
+
* @returns A promise that resolves to an array of unmarshalled items
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* Get items in default table
|
|
51
|
+
* ```javascript
|
|
52
|
+
* await getItems([
|
|
53
|
+
* { PK: "User/1", SK: "Book/1", title: "The Great Gatsby", released: 1925 },
|
|
54
|
+
* { PK: "User/1", SK: "Book/2" },
|
|
55
|
+
* { PK: "User/1", SK: "Book/3" },
|
|
56
|
+
* // ... infinite more items (will be grouped into batches of 100 due to aws limit) and retried up to 3 times
|
|
57
|
+
* ]);
|
|
58
|
+
* ```
|
|
59
|
+
* @example
|
|
60
|
+
* Get items in a different table
|
|
61
|
+
* ```javascript
|
|
62
|
+
* await getItems(
|
|
63
|
+
* [
|
|
64
|
+
* { PK: "User/1", SK: "Book/1", title: "The Great Gatsby", released: 1925 },
|
|
65
|
+
* { PK: "User/1", SK: "Book/2" },
|
|
66
|
+
* { PK: "User/1", SK: "Book/3" },
|
|
67
|
+
* ],
|
|
68
|
+
* { TableName: "AnotherTable" }
|
|
69
|
+
* );
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
17
72
|
async function getItems(keys, args = {}, retry = 0) {
|
|
18
73
|
args = (0, lib_1.withDefaults)(args, "getItems");
|
|
19
74
|
// creates batches of 100 items each and performs batchGet on every batch.
|
|
@@ -68,6 +123,24 @@ async function getItems(keys, args = {}, retry = 0) {
|
|
|
68
123
|
return keys.map((key) => resultItems[JSON.stringify((0, lib_1.stripKey)(key, { TableName }))] || undefined);
|
|
69
124
|
}
|
|
70
125
|
exports.getItems = getItems;
|
|
126
|
+
/**
|
|
127
|
+
* Retrieves all items from the DynamoDB table.
|
|
128
|
+
* @param args - The additional arguments to override or specify for {@link ScanCommandInput}
|
|
129
|
+
* @returns A promise that resolves to an array of unmarshalled items
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* Retrieve all items in default table
|
|
133
|
+
* ```javascript
|
|
134
|
+
* await getAllItems();
|
|
135
|
+
* ```
|
|
136
|
+
* @example
|
|
137
|
+
* Retrieve all items in a different table
|
|
138
|
+
* ```javascript
|
|
139
|
+
* await getAllItems(
|
|
140
|
+
* { TableName: "AnotherTable" }
|
|
141
|
+
* );
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
71
144
|
async function getAllItems(args = {}) {
|
|
72
145
|
args = (0, lib_1.withFixes)((0, lib_1.withDefaults)(args, "getAllItems"));
|
|
73
146
|
return (0, lib_1.getClient)()
|
|
@@ -1,5 +1,49 @@
|
|
|
1
1
|
import { GetItemCommandInput } from "@aws-sdk/client-dynamodb";
|
|
2
|
+
/**
|
|
3
|
+
* Check if an item exists in the DynamoDB table using its key schema.
|
|
4
|
+
* @param key - The item with at least the partition key and the sort key (if applicable) of the item to check.
|
|
5
|
+
* @param args - The additional arguments to override or specify for {@link GetItemCommandInput}
|
|
6
|
+
* @returns A promise that resolves to a boolean indicating whether the item exists or not.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* Check if an item exists
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const exists = await itemExists({ PK: "User/1", SK: "Book/1" });
|
|
12
|
+
* console.log(exists); // true / false
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
2
15
|
export declare function itemExists(key: any, args?: Partial<GetItemCommandInput>): Promise<boolean>;
|
|
16
|
+
/**
|
|
17
|
+
* Generate an ascending ID for an item in the DynamoDB table using the key schema.
|
|
18
|
+
* @param params - An object containing key schema information and optional ID length and TableName
|
|
19
|
+
* @returns A promise that resolves to a string representing the new ascending ID.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* Generate ascending ID
|
|
23
|
+
* ```typescript
|
|
24
|
+
* // Example Structure 1: PK: "User/1", SK: "{{ ASCENDING_ID }}"
|
|
25
|
+
* // Last item: { PK: "User/1", SK: "00000009" }
|
|
26
|
+
* const id1 = await getAscendingId({ PK: "User/1" });
|
|
27
|
+
* console.log(id1); // "00000010"
|
|
28
|
+
*
|
|
29
|
+
* // Example Structure 2: PK: "User/1", SK: "Book/{{ ASCENDING_ID }}"
|
|
30
|
+
* // Last item: { PK: "User/1", SK: "Book/00000009" }
|
|
31
|
+
* const id2 = await getAscendingId({ PK: "User/1", SK: "Book" });
|
|
32
|
+
* console.log(id2); // "00000010"
|
|
33
|
+
*
|
|
34
|
+
* // Specify length of ID
|
|
35
|
+
* const id3 = await getAscendingId({ PK: "User/1", SK: "Book", length: 4 });
|
|
36
|
+
* console.log(id3); // "0010"
|
|
37
|
+
*
|
|
38
|
+
* // Example Structure 3: someKeySchemaHash: "User/1", SK: "Book/{{ ASCENDING_ID }}"
|
|
39
|
+
* // Last item: { someKeySchemaHash: "User/1", SK: "Book/00000009" }
|
|
40
|
+
* const id4 = await getAscendingId({
|
|
41
|
+
* someKeySchemaHash: "User/1",
|
|
42
|
+
* SK: "Book",
|
|
43
|
+
* });
|
|
44
|
+
* console.log(id4); // "00000010"
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
3
47
|
export declare function getAscendingId({ length, TableName, ...keySchema }: {
|
|
4
48
|
length?: number;
|
|
5
49
|
TableName?: string;
|
package/dist/operations/misc.js
CHANGED
|
@@ -4,6 +4,19 @@ exports.getAscendingId = exports.itemExists = void 0;
|
|
|
4
4
|
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
5
5
|
const lib_1 = require("../lib");
|
|
6
6
|
const query_1 = require("./query");
|
|
7
|
+
/**
|
|
8
|
+
* Check if an item exists in the DynamoDB table using its key schema.
|
|
9
|
+
* @param key - The item with at least the partition key and the sort key (if applicable) of the item to check.
|
|
10
|
+
* @param args - The additional arguments to override or specify for {@link GetItemCommandInput}
|
|
11
|
+
* @returns A promise that resolves to a boolean indicating whether the item exists or not.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* Check if an item exists
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const exists = await itemExists({ PK: "User/1", SK: "Book/1" });
|
|
17
|
+
* console.log(exists); // true / false
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
7
20
|
async function itemExists(key, args = {}) {
|
|
8
21
|
args = (0, lib_1.withDefaults)(args, "itemExists");
|
|
9
22
|
return (0, lib_1.getClient)()
|
|
@@ -15,6 +28,37 @@ async function itemExists(key, args = {}) {
|
|
|
15
28
|
.then((res) => !!res?.Item);
|
|
16
29
|
}
|
|
17
30
|
exports.itemExists = itemExists;
|
|
31
|
+
/**
|
|
32
|
+
* Generate an ascending ID for an item in the DynamoDB table using the key schema.
|
|
33
|
+
* @param params - An object containing key schema information and optional ID length and TableName
|
|
34
|
+
* @returns A promise that resolves to a string representing the new ascending ID.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* Generate ascending ID
|
|
38
|
+
* ```typescript
|
|
39
|
+
* // Example Structure 1: PK: "User/1", SK: "{{ ASCENDING_ID }}"
|
|
40
|
+
* // Last item: { PK: "User/1", SK: "00000009" }
|
|
41
|
+
* const id1 = await getAscendingId({ PK: "User/1" });
|
|
42
|
+
* console.log(id1); // "00000010"
|
|
43
|
+
*
|
|
44
|
+
* // Example Structure 2: PK: "User/1", SK: "Book/{{ ASCENDING_ID }}"
|
|
45
|
+
* // Last item: { PK: "User/1", SK: "Book/00000009" }
|
|
46
|
+
* const id2 = await getAscendingId({ PK: "User/1", SK: "Book" });
|
|
47
|
+
* console.log(id2); // "00000010"
|
|
48
|
+
*
|
|
49
|
+
* // Specify length of ID
|
|
50
|
+
* const id3 = await getAscendingId({ PK: "User/1", SK: "Book", length: 4 });
|
|
51
|
+
* console.log(id3); // "0010"
|
|
52
|
+
*
|
|
53
|
+
* // Example Structure 3: someKeySchemaHash: "User/1", SK: "Book/{{ ASCENDING_ID }}"
|
|
54
|
+
* // Last item: { someKeySchemaHash: "User/1", SK: "Book/00000009" }
|
|
55
|
+
* const id4 = await getAscendingId({
|
|
56
|
+
* someKeySchemaHash: "User/1",
|
|
57
|
+
* SK: "Book",
|
|
58
|
+
* });
|
|
59
|
+
* console.log(id4); // "00000010"
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
18
62
|
async function getAscendingId({ length = 8, TableName, ...keySchema }) {
|
|
19
63
|
// Assumes that you are the incrementing ID inside or as the keySchema range key
|
|
20
64
|
const table = TableName || (0, lib_1.getDefaultTable)();
|
package/dist/operations/put.d.ts
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
import { BatchWriteItemCommandInput, BatchWriteItemCommandOutput, PutItemCommandInput, PutItemCommandOutput } from "@aws-sdk/client-dynamodb";
|
|
2
|
+
/**
|
|
3
|
+
* Inserts an item into the DynamoDB table.
|
|
4
|
+
* @param data - The item to insert into the table.
|
|
5
|
+
* @param args - The additional arguments to override or specify for {@link PutItemCommandInput}
|
|
6
|
+
* @returns A promise that resolves to the output of {@link PutItemCommandOutput} or the unmarshalled attributes if 'ReturnValues' is specified in 'args'.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* Put a single item into DynamoDB
|
|
10
|
+
* ```javascript
|
|
11
|
+
* await putItem({
|
|
12
|
+
* PK: "User/1",
|
|
13
|
+
* SK: "Book/1",
|
|
14
|
+
* title: "The Great Gatsby",
|
|
15
|
+
* author: "F. Scott Fitzgerald",
|
|
16
|
+
* released: 1925,
|
|
17
|
+
* });
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
2
20
|
export declare function putItem(data: any, args?: Partial<PutItemCommandInput>): Promise<PutItemCommandOutput | Record<string, any>>;
|
|
3
|
-
|
|
21
|
+
type PutItemsArgs = Partial<BatchWriteItemCommandInput & {
|
|
4
22
|
TableName?: string;
|
|
5
|
-
}
|
|
23
|
+
}>;
|
|
24
|
+
/**
|
|
25
|
+
* Inserts multiple items into the DynamoDB table.
|
|
26
|
+
* @param items - The items to insert into the table.
|
|
27
|
+
* @param args - The additional arguments to override or specify for {@link PutItemsArgs}
|
|
28
|
+
* @returns A promise that resolves to an array of {@link BatchWriteItemCommandOutput}
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* Put multiple items into DynamoDB
|
|
32
|
+
* ```javascript
|
|
33
|
+
* await putItems([
|
|
34
|
+
* {
|
|
35
|
+
* PK: "User/1",
|
|
36
|
+
* SK: "Book/1",
|
|
37
|
+
* title: "The Great Gatsby",
|
|
38
|
+
* author: "F. Scott Fitzgerald",
|
|
39
|
+
* released: 1925,
|
|
40
|
+
* },
|
|
41
|
+
* // ... infinite more items (will be grouped into batches of 25 due to aws limit)
|
|
42
|
+
* ]);
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare function putItems(items: any[], args?: PutItemsArgs): Promise<BatchWriteItemCommandOutput[]>;
|
|
46
|
+
export {};
|
package/dist/operations/put.js
CHANGED
|
@@ -3,6 +3,24 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.putItems = exports.putItem = void 0;
|
|
4
4
|
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
5
5
|
const lib_1 = require("../lib");
|
|
6
|
+
/**
|
|
7
|
+
* Inserts an item into the DynamoDB table.
|
|
8
|
+
* @param data - The item to insert into the table.
|
|
9
|
+
* @param args - The additional arguments to override or specify for {@link PutItemCommandInput}
|
|
10
|
+
* @returns A promise that resolves to the output of {@link PutItemCommandOutput} or the unmarshalled attributes if 'ReturnValues' is specified in 'args'.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* Put a single item into DynamoDB
|
|
14
|
+
* ```javascript
|
|
15
|
+
* await putItem({
|
|
16
|
+
* PK: "User/1",
|
|
17
|
+
* SK: "Book/1",
|
|
18
|
+
* title: "The Great Gatsby",
|
|
19
|
+
* author: "F. Scott Fitzgerald",
|
|
20
|
+
* released: 1925,
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
6
24
|
async function putItem(data, args = {}) {
|
|
7
25
|
args = (0, lib_1.withDefaults)(args, "putItem");
|
|
8
26
|
if (!Object.keys(data).includes("createdAt")) {
|
|
@@ -17,6 +35,27 @@ async function putItem(data, args = {}) {
|
|
|
17
35
|
.then((res) => args?.ReturnValues ? (0, lib_1.unmarshallWithOptions)(res?.Attributes) : res);
|
|
18
36
|
}
|
|
19
37
|
exports.putItem = putItem;
|
|
38
|
+
/**
|
|
39
|
+
* Inserts multiple items into the DynamoDB table.
|
|
40
|
+
* @param items - The items to insert into the table.
|
|
41
|
+
* @param args - The additional arguments to override or specify for {@link PutItemsArgs}
|
|
42
|
+
* @returns A promise that resolves to an array of {@link BatchWriteItemCommandOutput}
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* Put multiple items into DynamoDB
|
|
46
|
+
* ```javascript
|
|
47
|
+
* await putItems([
|
|
48
|
+
* {
|
|
49
|
+
* PK: "User/1",
|
|
50
|
+
* SK: "Book/1",
|
|
51
|
+
* title: "The Great Gatsby",
|
|
52
|
+
* author: "F. Scott Fitzgerald",
|
|
53
|
+
* released: 1925,
|
|
54
|
+
* },
|
|
55
|
+
* // ... infinite more items (will be grouped into batches of 25 due to aws limit)
|
|
56
|
+
* ]);
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
20
59
|
async function putItems(items, args = {}) {
|
|
21
60
|
args = (0, lib_1.withDefaults)(args, "putItems");
|
|
22
61
|
return new Promise(async (resolve, reject) => {
|
|
@@ -1,4 +1,128 @@
|
|
|
1
1
|
import { QueryCommandInput, QueryCommandOutput } from "@aws-sdk/client-dynamodb";
|
|
2
|
+
/**
|
|
3
|
+
* Query a single item in a DynamoDB table using a key condition.
|
|
4
|
+
* @param keyCondition - The condition for the key in DynamoDB QueryCommand.
|
|
5
|
+
* @param key - Definitions for the attributes used in keyCondition and FilterExpression
|
|
6
|
+
* @param args - The additional arguments to override or specify for {@link QueryCommandInput}
|
|
7
|
+
* @returns A promise that resolves to the output of {@link QueryCommandOutput}
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* Query a single item using a key condition
|
|
11
|
+
* ```javascript
|
|
12
|
+
* const booksResponse = await query("#PK = :PK and begins_with(#SK, :SK)", {
|
|
13
|
+
* PK: "User/1",
|
|
14
|
+
* SK: "Book/",
|
|
15
|
+
* });
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
2
18
|
export declare function query(keyCondition: string, key: any, args?: Partial<QueryCommandInput>): Promise<QueryCommandOutput>;
|
|
19
|
+
/**
|
|
20
|
+
* Query multiple items from the DynamoDB table using a key condition and unmarshalls the result.
|
|
21
|
+
* @param keyCondition - The condition for the key in DynamoDB QueryCommand.
|
|
22
|
+
* @param key - Definitions for the attributes used in keyCondition and FilterExpression
|
|
23
|
+
* @param args - The additional arguments to override or specify for {@link QueryCommandInput}
|
|
24
|
+
* @returns A promise that resolves to an array of unmarshalled items.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* Query multiple items using a key condition
|
|
28
|
+
* ```javascript
|
|
29
|
+
* const books = await queryItems("#PK = :PK and begins_with(#SK, :SK)", {
|
|
30
|
+
* PK: "User/1",
|
|
31
|
+
* SK: "Book/",
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
3
35
|
export declare function queryItems(keyCondition: string, key: any, args?: Partial<QueryCommandInput>): Promise<Record<string, any>[]>;
|
|
36
|
+
/**
|
|
37
|
+
* Query all items from the DynamoDB table using a key condition and unmarshalls the result.
|
|
38
|
+
* This function retries until all items are retrieved due to the AWS limit of 1MB per query.
|
|
39
|
+
* @param keyCondition - The condition for the key in DynamoDB QueryCommand.
|
|
40
|
+
* @param key - Definitions for the attributes used in keyCondition and FilterExpression
|
|
41
|
+
* @param args - The additional arguments to override or specify for {@link QueryCommandInput}
|
|
42
|
+
* @returns A promise that resolves to an array of unmarshalled items.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* Query all items using a key condition
|
|
46
|
+
* ```javascript
|
|
47
|
+
* const allBooks = await queryAllItems("#PK = :PK and begins_with(#SK, :SK)", {
|
|
48
|
+
* PK: "User/1",
|
|
49
|
+
* SK: "Book/",
|
|
50
|
+
* });
|
|
51
|
+
* const booksWithFilter = await queryAllItems(
|
|
52
|
+
* "#PK = :PK and begins_with(#SK, :SK)", // keyCondition
|
|
53
|
+
* {
|
|
54
|
+
* // definition for all attributes
|
|
55
|
+
* PK: "User/1",
|
|
56
|
+
* SK: "Book/",
|
|
57
|
+
* from: 1950,
|
|
58
|
+
* to: 2000,
|
|
59
|
+
* },
|
|
60
|
+
* // additional args with FilterExpression for example
|
|
61
|
+
* { FilterExpression: "#released BETWEEN :from AND :to" }
|
|
62
|
+
* );
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
4
65
|
export declare function queryAllItems(keyCondition: string, key: any, args?: Partial<QueryCommandInput>): Promise<Record<string, any>[]>;
|
|
66
|
+
/**
|
|
67
|
+
* The structure for the PaginationPage type.
|
|
68
|
+
* @property number - The page number. Cannot be set manually.
|
|
69
|
+
* @property firstKey - The key for the first item on the page.
|
|
70
|
+
* @property lastKey - The key for the last item on the page.
|
|
71
|
+
*/
|
|
72
|
+
export type PaginationPage = {
|
|
73
|
+
number?: number;
|
|
74
|
+
firstKey: Record<string, any>;
|
|
75
|
+
lastKey: Record<string, any>;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* The structure for the PaginationResult type.
|
|
79
|
+
* @property items - The items on the current page.
|
|
80
|
+
* @property hasPreviousPage - Whether there is a previous page.
|
|
81
|
+
* @property hasNextPage - Whether there is a next page.
|
|
82
|
+
* @property currentPage - The current page.
|
|
83
|
+
*/
|
|
84
|
+
export type PaginationResult = {
|
|
85
|
+
items: Record<string, any>[];
|
|
86
|
+
hasPreviousPage: boolean;
|
|
87
|
+
hasNextPage: boolean;
|
|
88
|
+
currentPage: PaginationPage;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* The arguments for the queryPaginatedItems function.
|
|
92
|
+
* @property pageSize - The size of each page.
|
|
93
|
+
* @property direction - The direction of pagination, 'next' or 'previous'. Default is 'next'.
|
|
94
|
+
* @property currentPage - The current page.
|
|
95
|
+
*/
|
|
96
|
+
export interface PaginationArgs extends Partial<Omit<QueryCommandInput, "Limit">> {
|
|
97
|
+
pageSize: number;
|
|
98
|
+
direction?: "next" | "previous";
|
|
99
|
+
currentPage?: PaginationPage;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Query items from the DynamoDB table using a key condition in a paginated manner.
|
|
103
|
+
* @param keyCondition - The condition for the key in DynamoDB QueryCommand.
|
|
104
|
+
* @param key - Definitions for the attributes used in keyCondition and FilterExpression
|
|
105
|
+
* @param args- The pagination arguments, including pageSize and direction. {@link PaginationArgs}
|
|
106
|
+
* @returns A promise that resolves to a {@link PaginationResult}.
|
|
107
|
+
* @example
|
|
108
|
+
* Query the first page of items using a key condition
|
|
109
|
+
* ```javascript
|
|
110
|
+
* const { items, hasNextPage, hasPreviousPage, currentPage } =
|
|
111
|
+
* await queryPaginatedItems(
|
|
112
|
+
* "#PK = :PK and begins_with(#SK, :SK)",
|
|
113
|
+
* { PK: "User/1", SK: "Book/" },
|
|
114
|
+
* { pageSize: 100 }
|
|
115
|
+
* );
|
|
116
|
+
* // items: The items on the current page.
|
|
117
|
+
* // currentPage: { number: 1, firstKey: { ... }, lastKey: { ... } }
|
|
118
|
+
*
|
|
119
|
+
* const { items: nextItems, currentPage: nextPage } = await queryPaginatedItems(
|
|
120
|
+
* "#PK = :PK and begins_with(#SK, :SK)",
|
|
121
|
+
* { PK: "User/1", SK: "Book/" },
|
|
122
|
+
* { pageSize: 100, currentPage }
|
|
123
|
+
* );
|
|
124
|
+
* // items: The items on the second page.
|
|
125
|
+
* // currentPage: { number: 2, firstKey: { ... }, lastKey: { ... } }
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
export declare function queryPaginatedItems(keyCondition: string, key: any, args: PaginationArgs): Promise<PaginationResult>;
|
package/dist/operations/query.js
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.queryAllItems = exports.queryItems = exports.query = void 0;
|
|
3
|
+
exports.queryPaginatedItems = exports.queryAllItems = exports.queryItems = exports.query = void 0;
|
|
4
4
|
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
5
5
|
const lib_1 = require("../lib");
|
|
6
|
+
/**
|
|
7
|
+
* The internal _query function that executes the QueryCommand with given conditions and arguments.
|
|
8
|
+
* @param keyCondition - The condition for the key in DynamoDB QueryCommand.
|
|
9
|
+
* @param key - Definitions for the attributes used in keyCondition and FilterExpression
|
|
10
|
+
* @param args - The additional arguments to override or specify for {@link QueryCommandInput}
|
|
11
|
+
* @returns A promise that resolves to the output of {@link QueryCommandOutput}
|
|
12
|
+
* @private
|
|
13
|
+
*/
|
|
6
14
|
async function _query(keyCondition, key, args = {}) {
|
|
7
15
|
args = (0, lib_1.withFixes)(args);
|
|
8
16
|
return (0, lib_1.getClient)().send(new client_dynamodb_1.QueryCommand({
|
|
@@ -19,10 +27,42 @@ async function _query(keyCondition, key, args = {}) {
|
|
|
19
27
|
TableName: args?.TableName || (0, lib_1.getDefaultTable)(),
|
|
20
28
|
}));
|
|
21
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Query a single item in a DynamoDB table using a key condition.
|
|
32
|
+
* @param keyCondition - The condition for the key in DynamoDB QueryCommand.
|
|
33
|
+
* @param key - Definitions for the attributes used in keyCondition and FilterExpression
|
|
34
|
+
* @param args - The additional arguments to override or specify for {@link QueryCommandInput}
|
|
35
|
+
* @returns A promise that resolves to the output of {@link QueryCommandOutput}
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* Query a single item using a key condition
|
|
39
|
+
* ```javascript
|
|
40
|
+
* const booksResponse = await query("#PK = :PK and begins_with(#SK, :SK)", {
|
|
41
|
+
* PK: "User/1",
|
|
42
|
+
* SK: "Book/",
|
|
43
|
+
* });
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
22
46
|
async function query(keyCondition, key, args) {
|
|
23
47
|
return _query(keyCondition, key, (0, lib_1.withDefaults)(args, "query"));
|
|
24
48
|
}
|
|
25
49
|
exports.query = query;
|
|
50
|
+
/**
|
|
51
|
+
* Query multiple items from the DynamoDB table using a key condition and unmarshalls the result.
|
|
52
|
+
* @param keyCondition - The condition for the key in DynamoDB QueryCommand.
|
|
53
|
+
* @param key - Definitions for the attributes used in keyCondition and FilterExpression
|
|
54
|
+
* @param args - The additional arguments to override or specify for {@link QueryCommandInput}
|
|
55
|
+
* @returns A promise that resolves to an array of unmarshalled items.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* Query multiple items using a key condition
|
|
59
|
+
* ```javascript
|
|
60
|
+
* const books = await queryItems("#PK = :PK and begins_with(#SK, :SK)", {
|
|
61
|
+
* PK: "User/1",
|
|
62
|
+
* SK: "Book/",
|
|
63
|
+
* });
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
26
66
|
async function queryItems(keyCondition, key, args = {}) {
|
|
27
67
|
args = (0, lib_1.withDefaults)(args, "queryItems");
|
|
28
68
|
return _query(keyCondition, key, args).then((res) => (res?.Items || [])
|
|
@@ -30,23 +70,166 @@ async function queryItems(keyCondition, key, args = {}) {
|
|
|
30
70
|
.filter((item) => item));
|
|
31
71
|
}
|
|
32
72
|
exports.queryItems = queryItems;
|
|
73
|
+
/**
|
|
74
|
+
* Query all items from the DynamoDB table using a key condition and unmarshalls the result.
|
|
75
|
+
* This function retries until all items are retrieved due to the AWS limit of 1MB per query.
|
|
76
|
+
* @param keyCondition - The condition for the key in DynamoDB QueryCommand.
|
|
77
|
+
* @param key - Definitions for the attributes used in keyCondition and FilterExpression
|
|
78
|
+
* @param args - The additional arguments to override or specify for {@link QueryCommandInput}
|
|
79
|
+
* @returns A promise that resolves to an array of unmarshalled items.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* Query all items using a key condition
|
|
83
|
+
* ```javascript
|
|
84
|
+
* const allBooks = await queryAllItems("#PK = :PK and begins_with(#SK, :SK)", {
|
|
85
|
+
* PK: "User/1",
|
|
86
|
+
* SK: "Book/",
|
|
87
|
+
* });
|
|
88
|
+
* const booksWithFilter = await queryAllItems(
|
|
89
|
+
* "#PK = :PK and begins_with(#SK, :SK)", // keyCondition
|
|
90
|
+
* {
|
|
91
|
+
* // definition for all attributes
|
|
92
|
+
* PK: "User/1",
|
|
93
|
+
* SK: "Book/",
|
|
94
|
+
* from: 1950,
|
|
95
|
+
* to: 2000,
|
|
96
|
+
* },
|
|
97
|
+
* // additional args with FilterExpression for example
|
|
98
|
+
* { FilterExpression: "#released BETWEEN :from AND :to" }
|
|
99
|
+
* );
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
33
102
|
async function queryAllItems(keyCondition, key, args = {}) {
|
|
34
103
|
args = (0, lib_1.withDefaults)(args, "queryAllItems");
|
|
35
104
|
let data = await _query(keyCondition, key, args);
|
|
36
105
|
while (data.LastEvaluatedKey) {
|
|
37
|
-
if (data.
|
|
106
|
+
if (!Object.hasOwn(args, "Limit") || data.Items.length < args?.Limit) {
|
|
38
107
|
let helper = await _query(keyCondition, key, {
|
|
39
108
|
...args,
|
|
40
109
|
ExclusiveStartKey: data.LastEvaluatedKey,
|
|
41
110
|
});
|
|
42
|
-
if (helper?.Items
|
|
111
|
+
if (helper?.Items) {
|
|
43
112
|
data.Items.push(...helper.Items);
|
|
44
113
|
}
|
|
45
|
-
|
|
114
|
+
else {
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
data.LastEvaluatedKey = helper.LastEvaluatedKey;
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
break;
|
|
46
121
|
}
|
|
47
122
|
}
|
|
48
123
|
return (data?.Items || [])
|
|
49
124
|
.map((item) => item && (0, lib_1.unmarshallWithOptions)(item))
|
|
50
|
-
.filter(
|
|
125
|
+
.filter(Boolean);
|
|
51
126
|
}
|
|
52
127
|
exports.queryAllItems = queryAllItems;
|
|
128
|
+
/**
|
|
129
|
+
* Query items from the DynamoDB table using a key condition in a paginated manner.
|
|
130
|
+
* @param keyCondition - The condition for the key in DynamoDB QueryCommand.
|
|
131
|
+
* @param key - Definitions for the attributes used in keyCondition and FilterExpression
|
|
132
|
+
* @param args- The pagination arguments, including pageSize and direction. {@link PaginationArgs}
|
|
133
|
+
* @returns A promise that resolves to a {@link PaginationResult}.
|
|
134
|
+
* @example
|
|
135
|
+
* Query the first page of items using a key condition
|
|
136
|
+
* ```javascript
|
|
137
|
+
* const { items, hasNextPage, hasPreviousPage, currentPage } =
|
|
138
|
+
* await queryPaginatedItems(
|
|
139
|
+
* "#PK = :PK and begins_with(#SK, :SK)",
|
|
140
|
+
* { PK: "User/1", SK: "Book/" },
|
|
141
|
+
* { pageSize: 100 }
|
|
142
|
+
* );
|
|
143
|
+
* // items: The items on the current page.
|
|
144
|
+
* // currentPage: { number: 1, firstKey: { ... }, lastKey: { ... } }
|
|
145
|
+
*
|
|
146
|
+
* const { items: nextItems, currentPage: nextPage } = await queryPaginatedItems(
|
|
147
|
+
* "#PK = :PK and begins_with(#SK, :SK)",
|
|
148
|
+
* { PK: "User/1", SK: "Book/" },
|
|
149
|
+
* { pageSize: 100, currentPage }
|
|
150
|
+
* );
|
|
151
|
+
* // items: The items on the second page.
|
|
152
|
+
* // currentPage: { number: 2, firstKey: { ... }, lastKey: { ... } }
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
async function queryPaginatedItems(keyCondition, key, args) {
|
|
156
|
+
args = (0, lib_1.withDefaults)(args, "queryPaginatedItems");
|
|
157
|
+
const pageSize = args.pageSize;
|
|
158
|
+
const direction = args.direction || "next";
|
|
159
|
+
const currentPage = args.currentPage;
|
|
160
|
+
delete args.pageSize;
|
|
161
|
+
delete args.direction;
|
|
162
|
+
delete args.currentPage;
|
|
163
|
+
const queryArgs = {
|
|
164
|
+
...args,
|
|
165
|
+
Limit: pageSize,
|
|
166
|
+
ScanIndexForward: direction === "next",
|
|
167
|
+
};
|
|
168
|
+
let newPageNumber;
|
|
169
|
+
switch (direction) {
|
|
170
|
+
case "next":
|
|
171
|
+
if (currentPage?.lastKey) {
|
|
172
|
+
queryArgs.ExclusiveStartKey = (0, lib_1.marshallWithOptions)(currentPage.lastKey);
|
|
173
|
+
}
|
|
174
|
+
newPageNumber = (currentPage?.number || 0) + 1;
|
|
175
|
+
break;
|
|
176
|
+
case "previous":
|
|
177
|
+
if (currentPage?.firstKey) {
|
|
178
|
+
queryArgs.ExclusiveStartKey = (0, lib_1.marshallWithOptions)(currentPage.firstKey);
|
|
179
|
+
}
|
|
180
|
+
newPageNumber = (currentPage?.number || 2) - 1;
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
let data = await _query(keyCondition, key, queryArgs);
|
|
184
|
+
// Assume schema for either given index or the table's schema
|
|
185
|
+
const keyAttributes = Object.keys(data.LastEvaluatedKey || queryArgs.ExclusiveStartKey || {});
|
|
186
|
+
while (data.LastEvaluatedKey) {
|
|
187
|
+
if (data.Items.length < pageSize) {
|
|
188
|
+
let helper = await _query(keyCondition, key, {
|
|
189
|
+
...queryArgs,
|
|
190
|
+
ExclusiveStartKey: data.LastEvaluatedKey,
|
|
191
|
+
});
|
|
192
|
+
if (helper?.Items) {
|
|
193
|
+
data.Items.push(...helper.Items);
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
data.LastEvaluatedKey = helper.LastEvaluatedKey;
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
let hasNextPage = direction === "previous" ||
|
|
205
|
+
// If pagination matches exactly with total items, dynamodb still returns a LastEvaluatedKey even tho next page is empty
|
|
206
|
+
// Therefore we check if the next page actually has items
|
|
207
|
+
(!!data.LastEvaluatedKey &&
|
|
208
|
+
(await _query(keyCondition, key, {
|
|
209
|
+
...queryArgs,
|
|
210
|
+
Limit: 1,
|
|
211
|
+
ExclusiveStartKey: data.LastEvaluatedKey,
|
|
212
|
+
}).then(({ Count }) => Count > 0)));
|
|
213
|
+
let hasPreviousPage = newPageNumber > 1;
|
|
214
|
+
data.Items = data.Items || [];
|
|
215
|
+
direction === "previous" && data.Items.reverse();
|
|
216
|
+
const applySchema = (item) => {
|
|
217
|
+
return keyAttributes.reduce((acc, key) => ({ ...acc, [key]: item[key] }), {});
|
|
218
|
+
};
|
|
219
|
+
const firstItem = data.Items?.[0];
|
|
220
|
+
const lastItem = data.Items?.[data.Items?.length - 1];
|
|
221
|
+
const firstKey = firstItem && (0, lib_1.unmarshallWithOptions)(applySchema(firstItem));
|
|
222
|
+
const lastKey = lastItem && (0, lib_1.unmarshallWithOptions)(applySchema(lastItem));
|
|
223
|
+
const items = data.Items.map((item) => item && (0, lib_1.unmarshallWithOptions)(item)).filter(Boolean);
|
|
224
|
+
return {
|
|
225
|
+
items,
|
|
226
|
+
hasPreviousPage,
|
|
227
|
+
hasNextPage,
|
|
228
|
+
currentPage: {
|
|
229
|
+
number: newPageNumber,
|
|
230
|
+
firstKey,
|
|
231
|
+
lastKey,
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
exports.queryPaginatedItems = queryPaginatedItems;
|