@moicky/dynamodb 1.0.1 → 1.1.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,3 +1,3 @@
1
1
  import { BatchWriteItemCommandInput, DeleteItemCommandInput, DeleteItemCommandOutput } from "@aws-sdk/client-dynamodb";
2
2
  export declare function deleteItem(key: any, args?: Partial<DeleteItemCommandInput>): Promise<DeleteItemCommandOutput>;
3
- export declare function deleteItems(keys: any[], args?: Partial<BatchWriteItemCommandInput>, retries?: number): Promise<void>;
3
+ export declare function deleteItems(keys: any[], args?: Partial<BatchWriteItemCommandInput>, retry?: number): Promise<void>;
@@ -1,4 +1,4 @@
1
1
  import { BatchGetItemCommandInput, GetItemCommandInput, ScanCommandInput } from "@aws-sdk/client-dynamodb";
2
2
  export declare function getItem(key: any, args?: Partial<GetItemCommandInput>): Promise<Record<string, any>>;
3
- export declare function getItems(keys: any[], args?: Partial<BatchGetItemCommandInput>, retry?: number): Promise<Record<string, any>[]>;
3
+ export declare function getItems(keys: any[], args?: Partial<BatchGetItemCommandInput>, retry?: number): Promise<Record<string, any> | Record<string, any>[]>;
4
4
  export declare function getAllItems(args?: Partial<ScanCommandInput>): Promise<Record<string, any>[]>;
@@ -1,4 +1,4 @@
1
1
  import { QueryCommandInput, QueryCommandOutput } from "@aws-sdk/client-dynamodb";
2
- export declare function query(keyCondition: string, keys: any[], args?: Partial<QueryCommandInput>): Promise<QueryCommandOutput>;
2
+ export declare function query(keyCondition: string, key: any, args?: Partial<QueryCommandInput>): Promise<QueryCommandOutput>;
3
3
  export declare function queryItems(keyCondition: string, key: any, args?: Partial<QueryCommandInput>): Promise<Record<string, any>[]>;
4
4
  export declare function queryAllItems(keyCondition: string, key: any, args?: Partial<QueryCommandInput>): Promise<Record<string, any>[]>;
package/package.json CHANGED
@@ -1,26 +1,28 @@
1
1
  {
2
2
  "name": "@moicky/dynamodb",
3
- "version": "1.0.1",
4
- "description": "",
3
+ "version": "1.1.0",
4
+ "description": "Contains a collection of convenience functions for working with AWS DynamoDB",
5
5
  "main": "dist/built/commonjs/index.js",
6
6
  "module": "dist/built/esnext/index.js",
7
7
  "types": "dist/index.d.ts",
8
- "private": false,
8
+ "homepage": "https://github.com/Moicky/dynamodb#readme",
9
+ "author": {
10
+ "name": "Moicky",
11
+ "url": "https://github.com/Moicky"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/Moicky/dynamodb/issues"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/Moicky/dynamodb.git"
19
+ },
20
+ "license": "ISC",
9
21
  "scripts": {
10
22
  "watch": "webpack --watch --mode=development",
11
23
  "build": "webpack --mode=production",
12
24
  "test": "jest --runInBand"
13
25
  },
14
- "keywords": [
15
- "dynamodb-helpers",
16
- "dynamodb",
17
- "aws-dynamodb"
18
- ],
19
- "files": [
20
- "dist"
21
- ],
22
- "author": "Moicky",
23
- "license": "ISC",
24
26
  "dependencies": {
25
27
  "@aws-sdk/client-dynamodb": "^3.338.0",
26
28
  "@aws-sdk/util-dynamodb": "^3.338.0",
@@ -33,5 +35,13 @@
33
35
  "dotenv": "^16.0.3",
34
36
  "ts-loader": "^9.4.3",
35
37
  "webpack-cli": "^5.1.1"
36
- }
38
+ },
39
+ "keywords": [
40
+ "dynamodb-helpers",
41
+ "dynamodb",
42
+ "aws-dynamodb"
43
+ ],
44
+ "files": [
45
+ "dist"
46
+ ]
37
47
  }
package/readme.md ADDED
@@ -0,0 +1,225 @@
1
+ # @moicky/dynamodb
2
+
3
+ ## Stats
4
+
5
+ ![](https://img.shields.io/github/languages/top/moicky/dynamodb)
6
+ ![](https://img.shields.io/github/actions/workflow/status/moicky/dynamodb/npm-publish.yml)
7
+ ![](https://img.shields.io/github/languages/code-size/moicky/dynamodb)
8
+ ![](https://img.shields.io/github/languages/count/moicky/dynamodb)
9
+
10
+ ## Description
11
+
12
+ Contains convenience functions for all major dynamodb operations. Requires very little code to interact with items from aws dynamodb. Uses **aws sdk v3** and fixes several issues:
13
+
14
+ - 🎁 Will **automatically marshall and unmarshall** items
15
+ - 📦 Will **group items into batches** to avoid aws limits and improve performance
16
+ - 🔄 Will **retry** some operations (getItems, deleteItems) **up to 3 times** on unprocessed items
17
+ - 🔒 When specifying an item using its keySchema, all additional attributes (apart from **PK** and **SK**) will be removed to avoid errors
18
+ - 👻 Will **use placeholders** to avoid colliding with [reserved words](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html) if applicable
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ npm i @moicky/dynamodb
24
+ ```
25
+
26
+ ## Setup
27
+
28
+ Add `DYNAMODB_TABLE` as an **environment variable** containing the name of the dynamodb table. Also make sure to setup the required permissions to access the dynamodb table on aws or on your local machine. Also make sure to use `PK` and `SK` as keySchema attribute names in the table.
29
+
30
+ _Support for different keySchemas will follow 😉_
31
+
32
+ ## Usage Examples
33
+
34
+ ### Put Items
35
+
36
+ ```ts
37
+ import { putItem, putItems } from "@moicky/dynamodb";
38
+
39
+ // Put single item into dynamodb
40
+ await putItem({
41
+ PK: "User/1",
42
+ SK: "Book/1",
43
+ title: "The Great Gatsby",
44
+ author: "F. Scott Fitzgerald",
45
+ released: 1925,
46
+ });
47
+
48
+ // Put multiple items into dynamodb
49
+ await putItems([
50
+ {
51
+ PK: "User/1",
52
+ SK: "Book/1",
53
+ title: "The Great Gatsby",
54
+ author: "F. Scott Fitzgerald",
55
+ released: 1925,
56
+ },
57
+ // ... infinite more items (will be grouped into batches of 25 due to aws limit)
58
+ ]);
59
+ ```
60
+
61
+ ### Get Items
62
+
63
+ ```ts
64
+ import { getItem, getItems, getAllItems } from "@moicky/dynamodb";
65
+
66
+ // Passing more than just the key is possible, but will be removed to avoid errors
67
+
68
+ // Get single item
69
+ await getItem({
70
+ PK: "User/1",
71
+ SK: "Book/1",
72
+ title: "The Great Gatsby", // additional fields will be removed before sending
73
+ author: "F. Scott Fitzgerald",
74
+ released: 1925,
75
+ });
76
+
77
+ // Get multiple items
78
+ // Items will be grouped into batches of 100 and will be retried up to 3 times if there are unprocessed items
79
+ // Will also only request each keySchema once, even if it is present multiple times in the array to improve performance
80
+ await getItems([
81
+ {
82
+ PK: "User/1",
83
+ SK: "Book/1",
84
+ title: "The Great Gatsby", // additional fields will be removed before sending
85
+ author: "F. Scott Fitzgerald",
86
+ released: 1925,
87
+ },
88
+ // ... infinite more items (will be grouped into batches of 100 due to aws limit) and retried up to 3 times
89
+ ]);
90
+
91
+ // Retrieve all items using ScanCommand
92
+ await getAllItems();
93
+ ```
94
+
95
+ ### Delete Items
96
+
97
+ ```ts
98
+ import { deleteItem, deleteItems } from "@moicky/dynamodb";
99
+
100
+ // Passing more than just the key is possible, but will be removed to avoid errors
101
+
102
+ // Delete single item
103
+ await deleteItem({
104
+ PK: "User/1",
105
+ SK: "Book/1",
106
+ title: "The Great Gatsby", // additional fields will be removed before sending
107
+ author: "F. Scott Fitzgerald",
108
+ released: 1925,
109
+ });
110
+
111
+ // Delete multiple items
112
+ // Keys will be grouped into batches of 25 and will be retried up to 3 times if there are unprocessed items
113
+ // Will also only delete each keySchema once, even if it is present multiple times in the array to improve performance
114
+ await deleteItems([
115
+ {
116
+ PK: "User/1",
117
+ SK: "Book/1",
118
+ title: "The Great Gatsby", // additional fields will be removed before sending
119
+ author: "F. Scott Fitzgerald",
120
+ released: 1925,
121
+ },
122
+ // ... infinite more items (will be grouped into batches of 25 due to aws limit) and retried up to 3 times
123
+ ]);
124
+ ```
125
+
126
+ ### Update Items
127
+
128
+ ```ts
129
+ import { updateItem, removeAttributes } from "@moicky/dynamodb";
130
+
131
+ // Passing more than just the key is possible, but will be removed to avoid errors
132
+
133
+ // Update the item and overwrite all supplied fields
134
+ await updateItem(
135
+ {
136
+ PK: "User/1",
137
+ SK: "Book/1",
138
+ title: "The Great Gatsby", // additional fields will be removed before sending
139
+ },
140
+ { description: "A book about a rich guy", author: "F. Scott Fitzgerald" }
141
+ );
142
+
143
+ // Completely remove fields from the item
144
+ await removeAttributes(
145
+ {
146
+ PK: "User/1",
147
+ SK: "Book/1",
148
+ title: "The Great Gatsby", // additional fields will be removed before sending
149
+ },
150
+ ["description"]
151
+ );
152
+ ```
153
+
154
+ ### Query Items
155
+
156
+ ```ts
157
+ import { query, queryItems, queryAllItems } from "@moicky/dynamodb";
158
+
159
+ // You have to use placeholders for the keyCondition & filterExpression:
160
+ // prefix the attributeNames with a hash (#) and the attributeValues with a colon (:)
161
+
162
+ // Query only using keyCondition and retrieve complete response
163
+ const booksResponse = await query("#PK = :PK and begins_with(#SK, :SK)", {
164
+ PK: "User/1",
165
+ SK: "Book/",
166
+ });
167
+
168
+ // Query and retrieve unmarshalled items array
169
+ const books = await queryItems("#PK = :PK and begins_with(#SK, :SK)", {
170
+ PK: "User/1",
171
+ SK: "Book/",
172
+ });
173
+
174
+ // Query and retry until all items are retrieved (due to aws limit of 1MB per query)
175
+ const allBooks = await queryAllItems("#PK = :PK and begins_with(#SK, :SK)", {
176
+ PK: "User/1",
177
+ SK: "Book/",
178
+ });
179
+
180
+ // Query with filterExpression (also specifiy attributes inside the key object)
181
+ const booksWithFilter = await queryAllItems(
182
+ "#PK = :PK and begins_with(#SK, :SK)", // keyCondition
183
+ {
184
+ // definition for all attributes
185
+ PK: "User/1",
186
+ SK: "Book/",
187
+ from: 1950,
188
+ to: 2000,
189
+ },
190
+ // additional args with filterExpression
191
+ { FilterExpression: "#released BETWEEN :from AND :to" }
192
+ );
193
+ ```
194
+
195
+ ### Miscellaneous
196
+
197
+ ```ts
198
+ import { itemExists, getNewId } from "@moicky/dynamodb";
199
+
200
+ // Check if an item exists using keySchema
201
+ const exists = await itemExists({ PK: "User/1", SK: "Book/1" });
202
+
203
+ // Generate ascending ID
204
+ // Example Structure 1: PK: "User/1", SK: "{{ ASCENDING_ID }}"
205
+ // Last item: { PK: "User/1", SK: "00000009" }
206
+
207
+ const id1 = await getNewId({ PK: "User/1" });
208
+ console.log(id1); // "00000010"
209
+
210
+ // Example Structure 2: PK: "User/1", SK: "Book/{{ ASCENDING_ID }}"
211
+ // Last item: { PK: "User/1", SK: "Book/00000009" }
212
+
213
+ const id2 = await getNewId({ PK: "User/1", SK: "Book" });
214
+ console.log(id2); // "00000010"
215
+
216
+ // Specify length of ID
217
+ const id3 = await getNewId({ PK: "User/1", SK: "Book", length: 4 });
218
+ console.log(id3); // "0010"
219
+ ```
220
+
221
+ ## Tests
222
+
223
+ ```bash
224
+ npm run test
225
+ ```