@moicky/dynamodb 1.1.0 → 1.1.2

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/index.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./operations"), exports);
18
+ __exportStar(require("./lib/client"), exports);
19
+ __exportStar(require("./lib/helpers"), exports);
@@ -1,4 +1,3 @@
1
1
  import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
2
- import "dotenv/config";
3
2
  export declare const client: DynamoDBClient;
4
3
  export declare const TableName: string;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TableName = exports.client = void 0;
4
+ const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
5
+ exports.client = new client_dynamodb_1.DynamoDBClient({
6
+ region: process.env.AWS_REGION || "eu-central-1",
7
+ });
8
+ exports.TableName = process.env.DYNAMODB_TABLE;
9
+ if (!exports.TableName) {
10
+ throw new Error("Missing DYNAMODB_TABLE environment variable");
11
+ }
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAttributesFromExpression = exports.getAttributeNames = exports.getAttributeValues = exports.splitEvery = exports.stripKey = void 0;
4
+ const util_dynamodb_1 = require("@aws-sdk/util-dynamodb");
5
+ // ----- Configuration -----
6
+ // Since dynamo only accepts key atrtributes which are described in table schema
7
+ // we remove any other attributes from the item if they are present and passed as
8
+ // key parameter to any of the functions below (getItem, updateItem, deleteItem...)
9
+ function stripKey(key) {
10
+ return (0, util_dynamodb_1.marshall)({ PK: key.PK, SK: key.SK });
11
+ }
12
+ exports.stripKey = stripKey;
13
+ function splitEvery(items, limit = 25) {
14
+ const batches = [];
15
+ for (let i = 0; i < items.length; i += limit) {
16
+ batches.push(items.slice(i, i + limit));
17
+ }
18
+ return batches;
19
+ }
20
+ exports.splitEvery = splitEvery;
21
+ function getAttributeValues(key, attributesToGet) {
22
+ return (0, util_dynamodb_1.marshall)((attributesToGet || Object.keys(key)).reduce((acc, keyName) => {
23
+ acc[`:${keyName}`] = key[keyName];
24
+ return acc;
25
+ }, {}));
26
+ }
27
+ exports.getAttributeValues = getAttributeValues;
28
+ function getAttributeNames(key, attributesToGet) {
29
+ return (attributesToGet || Object.keys(key)).reduce((acc, keyName) => {
30
+ acc[`#${keyName}`] = keyName;
31
+ return acc;
32
+ }, {});
33
+ }
34
+ exports.getAttributeNames = getAttributeNames;
35
+ function getAttributesFromExpression(expression, prefix = "#") {
36
+ return (expression
37
+ .match(new RegExp(`${prefix}\\w+`, "g"))
38
+ ?.map((attr) => attr.slice(1)) || []);
39
+ }
40
+ exports.getAttributesFromExpression = getAttributesFromExpression;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deleteItems = exports.deleteItem = void 0;
4
+ const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
5
+ const client_1 = require("../lib/client");
6
+ const helpers_1 = require("../lib/helpers");
7
+ async function deleteItem(key, args = {}) {
8
+ return client_1.client.send(new client_dynamodb_1.DeleteItemCommand({
9
+ TableName: client_1.TableName,
10
+ Key: (0, helpers_1.stripKey)(key),
11
+ ...args,
12
+ }));
13
+ }
14
+ exports.deleteItem = deleteItem;
15
+ async function deleteItems(keys, args = {}, retry = 0) {
16
+ const uniqueKeys = Object.values(keys.reduce((acc, key) => {
17
+ const strippedKey = (0, helpers_1.stripKey)(key);
18
+ const keyString = JSON.stringify(strippedKey);
19
+ if (!acc[keyString]) {
20
+ acc[keyString] = strippedKey;
21
+ }
22
+ return acc;
23
+ }, {}));
24
+ return new Promise(async (resolve, reject) => {
25
+ const batches = (0, helpers_1.splitEvery)(uniqueKeys);
26
+ if (retry > 3)
27
+ return;
28
+ for (const batch of batches) {
29
+ await client_1.client
30
+ .send(new client_dynamodb_1.BatchWriteItemCommand({
31
+ RequestItems: {
32
+ [client_1.TableName]: batch.map((Key) => ({
33
+ DeleteRequest: {
34
+ Key,
35
+ },
36
+ })),
37
+ },
38
+ ...args,
39
+ }))
40
+ .then((res) => {
41
+ if (res?.UnprocessedItems?.[client_1.TableName]?.length) {
42
+ if (retry + 1 > 3)
43
+ return reject(res);
44
+ return deleteItems(res.UnprocessedItems[client_1.TableName], args, retry + 1);
45
+ }
46
+ })
47
+ .catch(reject);
48
+ }
49
+ resolve();
50
+ });
51
+ }
52
+ exports.deleteItems = deleteItems;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAllItems = exports.getItems = exports.getItem = void 0;
4
+ const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
5
+ const util_dynamodb_1 = require("@aws-sdk/util-dynamodb");
6
+ const client_1 = require("../lib/client");
7
+ const helpers_1 = require("../lib/helpers");
8
+ async function getItem(key, args = {}) {
9
+ return client_1.client
10
+ .send(new client_dynamodb_1.GetItemCommand({
11
+ TableName: client_1.TableName,
12
+ Key: (0, helpers_1.stripKey)(key),
13
+ ...args,
14
+ }))
15
+ .then((res) => res?.Item && (0, util_dynamodb_1.unmarshall)(res.Item));
16
+ }
17
+ exports.getItem = getItem;
18
+ async function getItems(keys, args = {}, retry = 0) {
19
+ // creates batches of 100 items each and performs batchGet on every batch.
20
+ // also retries up to 3 times if there are unprocessed items (due to size limit of 16MB)
21
+ // returns items in same order as keys (not sorted by default when using batchGet)
22
+ if (retry > 3)
23
+ return [];
24
+ const batchReadLimit = 100;
25
+ // duplicate key entries would cause an error, so we remove them
26
+ const uniqueKeys = Object.values(keys.reduce((acc, key) => {
27
+ const strippedKey = (0, helpers_1.stripKey)(key);
28
+ const keyString = JSON.stringify(strippedKey);
29
+ if (!acc[keyString]) {
30
+ acc[keyString] = strippedKey;
31
+ }
32
+ return acc;
33
+ }, {}));
34
+ const batches = (0, helpers_1.splitEvery)(uniqueKeys, batchReadLimit);
35
+ const results = [];
36
+ if (retry > 2) {
37
+ return results;
38
+ }
39
+ await Promise.all(batches.map(async (batch) => {
40
+ await client_1.client
41
+ .send(new client_dynamodb_1.BatchGetItemCommand({
42
+ RequestItems: {
43
+ [client_1.TableName]: {
44
+ Keys: batch,
45
+ ...args,
46
+ },
47
+ },
48
+ }))
49
+ .then((res) => {
50
+ const unprocessed = res?.UnprocessedKeys?.[client_1.TableName];
51
+ const allItemsFromBatch = res?.Responses?.[client_1.TableName] || [];
52
+ if (unprocessed) {
53
+ return getItems(unprocessed.Keys, args, retry + 1).then((items) => allItemsFromBatch.concat(items));
54
+ }
55
+ return allItemsFromBatch.map((item) => item && (0, util_dynamodb_1.unmarshall)(item));
56
+ })
57
+ .then((items) => results.push(...items));
58
+ }));
59
+ const resultItems = results
60
+ .filter((i) => i)
61
+ .reduce((acc, item) => {
62
+ const keyString = JSON.stringify((0, helpers_1.stripKey)(item));
63
+ acc[keyString] = item;
64
+ return acc;
65
+ }, {});
66
+ return keys.map((key) => resultItems[JSON.stringify((0, helpers_1.stripKey)(key))] || undefined);
67
+ }
68
+ exports.getItems = getItems;
69
+ async function getAllItems(args = {}) {
70
+ return client_1.client
71
+ .send(new client_dynamodb_1.ScanCommand({
72
+ TableName: client_1.TableName,
73
+ ...args,
74
+ }))
75
+ .then((res) => res.Items.map((item) => item && (0, util_dynamodb_1.unmarshall)(item)));
76
+ }
77
+ exports.getAllItems = getAllItems;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./delete"), exports);
18
+ __exportStar(require("./get"), exports);
19
+ __exportStar(require("./misc"), exports);
20
+ __exportStar(require("./put"), exports);
21
+ __exportStar(require("./query"), exports);
22
+ __exportStar(require("./update"), exports);
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getNewId = exports.itemExists = void 0;
4
+ const get_1 = require("./get");
5
+ const query_1 = require("./query");
6
+ async function itemExists(key, args = {}) {
7
+ const item = await (0, get_1.getItem)(key, args);
8
+ return item !== undefined && item !== null;
9
+ }
10
+ exports.itemExists = itemExists;
11
+ async function getNewId({ PK, SK, length = 8, }) {
12
+ // Assumes that you are using SK as the incrementing ID
13
+ if (!PK) {
14
+ throw new Error("Cannot generate new ID: PK");
15
+ }
16
+ let lastId = "0";
17
+ if (!SK) {
18
+ const lastItem = (await (0, query_1.queryItems)("#PK = :PK", { PK }, { Limit: 1, ScanIndexForward: false }))?.[0];
19
+ const parts = lastItem?.["SK"]?.split("/") || [];
20
+ lastId = parts?.[parts.length - 1] || "0";
21
+ }
22
+ else {
23
+ const formattedSK = SK + (!SK.endsWith("/") ? "/" : "");
24
+ const lastItem = (await (0, query_1.queryItems)("#PK = :PK and begins_with(#SK, :SK)", { PK, SK: formattedSK }, { Limit: 1, ScanIndexForward: false }))?.[0];
25
+ const parts = lastItem?.["SK"]?.split("/") || [];
26
+ lastId = parts?.[formattedSK.split("/").length - 1] || "0";
27
+ }
28
+ const newId = parseInt(lastId) + 1 + "";
29
+ const withPadding = newId.padStart(length || 0, "0");
30
+ return SK
31
+ ? `${SK}${!SK.endsWith("/") ? "/" : ""}${withPadding}`
32
+ : withPadding;
33
+ }
34
+ exports.getNewId = getNewId;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.putItems = exports.putItem = void 0;
4
+ const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
5
+ const util_dynamodb_1 = require("@aws-sdk/util-dynamodb");
6
+ const client_1 = require("../lib/client");
7
+ const helpers_1 = require("../lib/helpers");
8
+ async function putItem(data, args = {}) {
9
+ if (!Object.keys(data).includes("createdAt")) {
10
+ data.createdAt = Date.now();
11
+ }
12
+ return client_1.client.send(new client_dynamodb_1.PutItemCommand({
13
+ TableName: client_1.TableName,
14
+ Item: (0, util_dynamodb_1.marshall)(data),
15
+ ...args,
16
+ }));
17
+ }
18
+ exports.putItem = putItem;
19
+ async function putItems(items, args = {}) {
20
+ return new Promise(async (resolve, reject) => {
21
+ const batches = (0, helpers_1.splitEvery)(items);
22
+ const now = Date.now();
23
+ for (const batch of batches) {
24
+ batch.forEach((item) => {
25
+ if (!Object.keys(item).includes("createdAt")) {
26
+ item.createdAt = now;
27
+ }
28
+ });
29
+ await client_1.client
30
+ .send(new client_dynamodb_1.BatchWriteItemCommand({
31
+ RequestItems: {
32
+ [client_1.TableName]: batch.map((item) => ({
33
+ PutRequest: {
34
+ Item: (0, util_dynamodb_1.marshall)(item),
35
+ },
36
+ })),
37
+ },
38
+ ...args,
39
+ }))
40
+ .catch(reject);
41
+ }
42
+ resolve();
43
+ });
44
+ }
45
+ exports.putItems = putItems;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.queryAllItems = exports.queryItems = exports.query = void 0;
4
+ const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
5
+ const util_dynamodb_1 = require("@aws-sdk/util-dynamodb");
6
+ const client_1 = require("../lib/client");
7
+ const helpers_1 = require("../lib/helpers");
8
+ async function query(keyCondition, key, args = {}) {
9
+ return client_1.client.send(new client_dynamodb_1.QueryCommand({
10
+ TableName: client_1.TableName,
11
+ KeyConditionExpression: keyCondition,
12
+ ExpressionAttributeValues: (0, helpers_1.getAttributeValues)(key, [
13
+ ...(0, helpers_1.getAttributesFromExpression)(keyCondition, ":"),
14
+ ...(0, helpers_1.getAttributesFromExpression)(args?.FilterExpression || "", ":"),
15
+ ]),
16
+ ExpressionAttributeNames: (0, helpers_1.getAttributeNames)(key, [
17
+ ...(0, helpers_1.getAttributesFromExpression)(keyCondition),
18
+ ...(0, helpers_1.getAttributesFromExpression)(args?.FilterExpression || ""),
19
+ ]),
20
+ ...args,
21
+ }));
22
+ }
23
+ exports.query = query;
24
+ async function queryItems(keyCondition, key, args = {}) {
25
+ return query(keyCondition, key, args).then((res) => (res?.Items || []).map((item) => item && (0, util_dynamodb_1.unmarshall)(item)));
26
+ }
27
+ exports.queryItems = queryItems;
28
+ async function queryAllItems(keyCondition, key, args = {}) {
29
+ let data = await query(keyCondition, key, args);
30
+ while (data.LastEvaluatedKey) {
31
+ if (data.LastEvaluatedKey) {
32
+ let helper = await query(keyCondition, key, {
33
+ ...args,
34
+ ExclusiveStartKey: data.LastEvaluatedKey,
35
+ });
36
+ if (helper?.Items && data?.Items) {
37
+ data.Items.push(...helper.Items);
38
+ }
39
+ data && (data.LastEvaluatedKey = helper.LastEvaluatedKey);
40
+ }
41
+ }
42
+ return (data?.Items || []).map((item) => item && (0, util_dynamodb_1.unmarshall)(item));
43
+ }
44
+ exports.queryAllItems = queryAllItems;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.removeAttributes = exports.updateItem = void 0;
4
+ const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
5
+ const client_1 = require("../lib/client");
6
+ const helpers_1 = require("../lib/helpers");
7
+ async function updateItem(key, data, args = {}) {
8
+ if (!Object.keys(data).includes("updatedAt")) {
9
+ data.updatedAt = Date.now();
10
+ }
11
+ const UpdateExpression = "SET " +
12
+ Object.keys(data)
13
+ .map((key) => `#${key} = :${key}`)
14
+ .join(", ");
15
+ return client_1.client.send(new client_dynamodb_1.UpdateItemCommand({
16
+ TableName: client_1.TableName,
17
+ Key: (0, helpers_1.stripKey)(key),
18
+ UpdateExpression,
19
+ ExpressionAttributeValues: (0, helpers_1.getAttributeValues)(data),
20
+ ExpressionAttributeNames: (0, helpers_1.getAttributeNames)(data),
21
+ ...args,
22
+ }));
23
+ }
24
+ exports.updateItem = updateItem;
25
+ async function removeAttributes(key, attributes) {
26
+ const UpdateExpression = "REMOVE " + attributes.map((att) => `#${att}`).join(", ");
27
+ return client_1.client.send(new client_dynamodb_1.UpdateItemCommand({
28
+ TableName: client_1.TableName,
29
+ Key: (0, helpers_1.stripKey)(key),
30
+ UpdateExpression,
31
+ ExpressionAttributeNames: (0, helpers_1.getAttributeNames)(attributes.reduce((acc, att) => {
32
+ acc[att] = att;
33
+ return acc;
34
+ }, {})),
35
+ }));
36
+ }
37
+ exports.removeAttributes = removeAttributes;
package/package.json CHANGED
@@ -1,10 +1,9 @@
1
1
  {
2
2
  "name": "@moicky/dynamodb",
3
- "version": "1.1.0",
4
- "description": "Contains a collection of convenience functions for working with AWS DynamoDB",
5
- "main": "dist/built/commonjs/index.js",
6
- "module": "dist/built/esnext/index.js",
3
+ "version": "1.1.2",
4
+ "main": "dist/index.js",
7
5
  "types": "dist/index.d.ts",
6
+ "description": "Contains a collection of convenience functions for working with AWS DynamoDB",
8
7
  "homepage": "https://github.com/Moicky/dynamodb#readme",
9
8
  "author": {
10
9
  "name": "Moicky",
@@ -19,22 +18,20 @@
19
18
  },
20
19
  "license": "ISC",
21
20
  "scripts": {
22
- "watch": "webpack --watch --mode=development",
23
- "build": "webpack --mode=production",
21
+ "build": "tsc",
22
+ "watch": "tsc -w",
24
23
  "test": "jest --runInBand"
25
24
  },
26
25
  "dependencies": {
27
26
  "@aws-sdk/client-dynamodb": "^3.338.0",
28
- "@aws-sdk/util-dynamodb": "^3.338.0",
29
- "aws-crt": "^1.15.16"
27
+ "@aws-sdk/util-dynamodb": "^3.338.0"
30
28
  },
31
29
  "devDependencies": {
32
30
  "@types/jest": "^29.5.1",
33
- "jest": "^29.5.0",
34
- "aws-sdk": "^2.1383.0",
31
+ "@types/node": "^20.2.4",
35
32
  "dotenv": "^16.0.3",
36
- "ts-loader": "^9.4.3",
37
- "webpack-cli": "^5.1.1"
33
+ "typescript": "^5.0.4",
34
+ "jest": "^29.5.0"
38
35
  },
39
36
  "keywords": [
40
37
  "dynamodb-helpers",
package/readme.md CHANGED
@@ -1,11 +1,10 @@
1
1
  # @moicky/dynamodb
2
2
 
3
- ## Stats
4
-
5
3
  ![](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)
4
+ ![](https://img.shields.io/github/actions/workflow/status/moicky/dynamodb/npm-publish.yml?label=build)
5
+ ![](https://img.shields.io/github/actions/workflow/status/moicky/dynamodb/run-tests.yml?label=tests)
8
6
  ![](https://img.shields.io/github/languages/count/moicky/dynamodb)
7
+ ![](https://img.shields.io/bundlephobia/min/@moicky/dynamodb)
9
8
 
10
9
  ## Description
11
10
 
@@ -13,6 +12,7 @@ Contains convenience functions for all major dynamodb operations. Requires very
13
12
 
14
13
  - 🎁 Will **automatically marshall and unmarshall** items
15
14
  - 📦 Will **group items into batches** to avoid aws limits and improve performance
15
+ - ⏱ Will **automatically** add `createdAt` and `updatedAt` attributes on all items to track their most recent create/update operation timestamp. Example value: `Date.now() -> 1685138436000`
16
16
  - 🔄 Will **retry** some operations (getItems, deleteItems) **up to 3 times** on unprocessed items
17
17
  - 🔒 When specifying an item using its keySchema, all additional attributes (apart from **PK** and **SK**) will be removed to avoid errors
18
18
  - 👻 Will **use placeholders** to avoid colliding with [reserved words](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html) if applicable
@@ -97,28 +97,20 @@ await getAllItems();
97
97
  ```ts
98
98
  import { deleteItem, deleteItems } from "@moicky/dynamodb";
99
99
 
100
- // Passing more than just the key is possible, but will be removed to avoid errors
101
-
102
100
  // Delete single item
103
101
  await deleteItem({
104
102
  PK: "User/1",
105
103
  SK: "Book/1",
106
- title: "The Great Gatsby", // additional fields will be removed before sending
104
+ title: "The Great Gatsby", // additional fields will be removed before sending to avoid errors
107
105
  author: "F. Scott Fitzgerald",
108
106
  released: 1925,
109
107
  });
110
108
 
111
109
  // 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
110
+ // KeySchemas will be grouped into batches of 25 and will be retried up to 3 times if there are unprocessed items
111
+ // Will only delete each keySchema only once, even if it is present multiple times in the array to improve performance
114
112
  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
- },
113
+ { PK: "User/1", SK: "Book/1" },
122
114
  // ... infinite more items (will be grouped into batches of 25 due to aws limit) and retried up to 3 times
123
115
  ]);
124
116
  ```
@@ -128,27 +120,13 @@ await deleteItems([
128
120
  ```ts
129
121
  import { updateItem, removeAttributes } from "@moicky/dynamodb";
130
122
 
131
- // Passing more than just the key is possible, but will be removed to avoid errors
132
-
133
123
  // Update the item and overwrite all supplied fields
134
124
  await updateItem(
135
- {
136
- PK: "User/1",
137
- SK: "Book/1",
138
- title: "The Great Gatsby", // additional fields will be removed before sending
139
- },
125
+ { PK: "User/1", SK: "Book/1" },
140
126
  { description: "A book about a rich guy", author: "F. Scott Fitzgerald" }
141
127
  );
142
128
 
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
- );
129
+ await removeAttributes({ PK: "User/1", SK: "Book/1" }, ["description"]);
152
130
  ```
153
131
 
154
132
  ### Query Items
@@ -156,7 +134,7 @@ await removeAttributes(
156
134
  ```ts
157
135
  import { query, queryItems, queryAllItems } from "@moicky/dynamodb";
158
136
 
159
- // You have to use placeholders for the keyCondition & filterExpression:
137
+ // You HAVE TO use placeholders for the keyCondition & filterExpression:
160
138
  // prefix the attributeNames with a hash (#) and the attributeValues with a colon (:)
161
139
 
162
140
  // Query only using keyCondition and retrieve complete response
@@ -188,7 +166,7 @@ const booksWithFilter = await queryAllItems(
188
166
  to: 2000,
189
167
  },
190
168
  // additional args with filterExpression
191
- { FilterExpression: "#released BETWEEN :from AND :to" }
169
+ { FilterExpression: "#released BETWEEN :from AND :to" } // allows to override all args
192
170
  );
193
171
  ```
194
172
 
@@ -201,15 +179,14 @@ import { itemExists, getNewId } from "@moicky/dynamodb";
201
179
  const exists = await itemExists({ PK: "User/1", SK: "Book/1" });
202
180
 
203
181
  // Generate ascending ID
182
+
204
183
  // Example Structure 1: PK: "User/1", SK: "{{ ASCENDING_ID }}"
205
184
  // Last item: { PK: "User/1", SK: "00000009" }
206
-
207
185
  const id1 = await getNewId({ PK: "User/1" });
208
186
  console.log(id1); // "00000010"
209
187
 
210
188
  // Example Structure 2: PK: "User/1", SK: "Book/{{ ASCENDING_ID }}"
211
189
  // Last item: { PK: "User/1", SK: "Book/00000009" }
212
-
213
190
  const id2 = await getNewId({ PK: "User/1", SK: "Book" });
214
191
  console.log(id2); // "00000010"
215
192