@moicky/dynamodb 2.0.1 → 2.2.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/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 +50 -0
- package/dist/lib/fixes.js +33 -0
- 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 +60 -1
- 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 +52 -2
- 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
|
@@ -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, retry?: number): 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,7 +35,30 @@ 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;
|
|
20
|
-
|
|
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
|
+
*/
|
|
59
|
+
async function putItems(items, args = {}, retry = 0) {
|
|
60
|
+
if (retry > 3)
|
|
61
|
+
return;
|
|
21
62
|
args = (0, lib_1.withDefaults)(args, "putItems");
|
|
22
63
|
return new Promise(async (resolve, reject) => {
|
|
23
64
|
const now = Date.now();
|
|
@@ -39,7 +80,16 @@ async function putItems(items, args = {}) {
|
|
|
39
80
|
},
|
|
40
81
|
...args,
|
|
41
82
|
}))
|
|
42
|
-
.then((res) =>
|
|
83
|
+
.then((res) => {
|
|
84
|
+
results.push(res);
|
|
85
|
+
if (res?.UnprocessedItems?.[table]?.length) {
|
|
86
|
+
if (retry + 1 < 3) {
|
|
87
|
+
reject(res);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
return putItems(res.UnprocessedItems[table].map((item) => (0, lib_1.unmarshallWithOptions)(item.PutRequest.Item)), { ...args, TableName: table }, retry + 1);
|
|
91
|
+
}
|
|
92
|
+
})
|
|
43
93
|
.catch(reject);
|
|
44
94
|
}
|
|
45
95
|
resolve(results);
|
|
@@ -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;
|
|
@@ -1,3 +1,49 @@
|
|
|
1
1
|
import { UpdateItemCommandInput, UpdateItemCommandOutput } from "@aws-sdk/client-dynamodb";
|
|
2
|
+
/**
|
|
3
|
+
* Updates an item in DynamoDB. All provided fields are overwritten.
|
|
4
|
+
*
|
|
5
|
+
* @param key - The primary key of the item to be updated
|
|
6
|
+
* @param data - An object containing the data to be updated
|
|
7
|
+
* @param args - Optional parameters for the {@link UpdateItemCommand}
|
|
8
|
+
* @returns Returns updated item if ReturnValues argument is set, otherwise undefined
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* Update the item and overwrite all supplied fields
|
|
12
|
+
* ```javascript
|
|
13
|
+
* await updateItem(
|
|
14
|
+
* { PK: "User/1", SK: "Book/1" }, // reference to item
|
|
15
|
+
* { description: "A book about a rich guy", author: "F. Scott Fitzgerald" } // fields to update
|
|
16
|
+
* );
|
|
17
|
+
*
|
|
18
|
+
* // Conditionally update an item. 'maxReleased' will not be updated since it is referenced inside the ConditionExpression
|
|
19
|
+
* await updateItem(
|
|
20
|
+
* { PK: "User/1", SK: "Book/1" },
|
|
21
|
+
* { released: 2000, maxReleased: 1950 },
|
|
22
|
+
* { ConditionExpression: "#released < :maxReleased" }
|
|
23
|
+
* );
|
|
24
|
+
*
|
|
25
|
+
* // Return all attributes of the new item
|
|
26
|
+
* const newItem = await updateItem(
|
|
27
|
+
* { PK: "User/1", SK: "Book/1" },
|
|
28
|
+
* { released: 2000 },
|
|
29
|
+
* { ReturnValues: "ALL_NEW" }
|
|
30
|
+
* );
|
|
31
|
+
* console.log(newItem); // { "PK": "User/1", "SK": "Book/1", "released": 2000 }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
2
34
|
export declare function updateItem(key: any, data: any, args?: Partial<UpdateItemCommandInput>): Promise<undefined | Record<string, any>>;
|
|
35
|
+
/**
|
|
36
|
+
* Removes specified attributes from an item in DynamoDB.
|
|
37
|
+
*
|
|
38
|
+
* @param key - The primary key of the item from which attributes should be removed
|
|
39
|
+
* @param {string[]} attributes - Array of attribute names to be removed
|
|
40
|
+
* @param args - Optional parameters for the {@link UpdateItemCommand}
|
|
41
|
+
* @returns Promise object representing the output of the DynamoDB UpdateItem command
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* Remove a specific attribute from an item
|
|
45
|
+
* ```javascript
|
|
46
|
+
* await removeAttributes({ PK: "User/1", SK: "Book/1" }, ["description"]);
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
3
49
|
export declare function removeAttributes(key: any, attributes: string[], args?: Partial<UpdateItemCommandInput>): Promise<UpdateItemCommandOutput>;
|