@moicky/dynamodb 2.0.1 → 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.
@@ -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;
@@ -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)();
@@ -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
- export declare function putItems(items: any[], args?: Partial<BatchWriteItemCommandInput & {
21
+ type PutItemsArgs = Partial<BatchWriteItemCommandInput & {
4
22
  TableName?: string;
5
- }>): Promise<BatchWriteItemCommandOutput[]>;
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 {};
@@ -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>;
@@ -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.LastEvaluatedKey) {
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 && data?.Items) {
111
+ if (helper?.Items) {
43
112
  data.Items.push(...helper.Items);
44
113
  }
45
- data && (data.LastEvaluatedKey = helper.LastEvaluatedKey);
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((item) => item);
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>;
@@ -3,6 +3,38 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.removeAttributes = exports.updateItem = void 0;
4
4
  const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
5
5
  const lib_1 = require("../lib");
6
+ /**
7
+ * Updates an item in DynamoDB. All provided fields are overwritten.
8
+ *
9
+ * @param key - The primary key of the item to be updated
10
+ * @param data - An object containing the data to be updated
11
+ * @param args - Optional parameters for the {@link UpdateItemCommand}
12
+ * @returns Returns updated item if ReturnValues argument is set, otherwise undefined
13
+ *
14
+ * @example
15
+ * Update the item and overwrite all supplied fields
16
+ * ```javascript
17
+ * await updateItem(
18
+ * { PK: "User/1", SK: "Book/1" }, // reference to item
19
+ * { description: "A book about a rich guy", author: "F. Scott Fitzgerald" } // fields to update
20
+ * );
21
+ *
22
+ * // Conditionally update an item. 'maxReleased' will not be updated since it is referenced inside the ConditionExpression
23
+ * await updateItem(
24
+ * { PK: "User/1", SK: "Book/1" },
25
+ * { released: 2000, maxReleased: 1950 },
26
+ * { ConditionExpression: "#released < :maxReleased" }
27
+ * );
28
+ *
29
+ * // Return all attributes of the new item
30
+ * const newItem = await updateItem(
31
+ * { PK: "User/1", SK: "Book/1" },
32
+ * { released: 2000 },
33
+ * { ReturnValues: "ALL_NEW" }
34
+ * );
35
+ * console.log(newItem); // { "PK": "User/1", "SK": "Book/1", "released": 2000 }
36
+ * ```
37
+ */
6
38
  async function updateItem(key, data, args = {}) {
7
39
  args = (0, lib_1.withDefaults)(args, "updateItem");
8
40
  if (!Object.keys(data).includes("updatedAt")) {
@@ -30,6 +62,20 @@ async function updateItem(key, data, args = {}) {
30
62
  .then((res) => args?.ReturnValues ? (0, lib_1.unmarshallWithOptions)(res.Attributes) : undefined);
31
63
  }
32
64
  exports.updateItem = updateItem;
65
+ /**
66
+ * Removes specified attributes from an item in DynamoDB.
67
+ *
68
+ * @param key - The primary key of the item from which attributes should be removed
69
+ * @param {string[]} attributes - Array of attribute names to be removed
70
+ * @param args - Optional parameters for the {@link UpdateItemCommand}
71
+ * @returns Promise object representing the output of the DynamoDB UpdateItem command
72
+ *
73
+ * @example
74
+ * Remove a specific attribute from an item
75
+ * ```javascript
76
+ * await removeAttributes({ PK: "User/1", SK: "Book/1" }, ["description"]);
77
+ * ```
78
+ */
33
79
  async function removeAttributes(key, attributes, args = {}) {
34
80
  args = (0, lib_1.withDefaults)(args, "removeAttributes");
35
81
  const UpdateExpression = "REMOVE " + attributes.map((att) => `#${att}`).join(", ");