Skip to content

Commit

Permalink
feat: add custom serialize and deserialize for StringSet and NumberSet
Browse files Browse the repository at this point in the history
  • Loading branch information
kritish-dhaubanjar committed May 12, 2024
1 parent d401f2d commit b222c4d
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 46 deletions.
1 change: 1 addition & 0 deletions server/package.json
Expand Up @@ -45,6 +45,7 @@
"dotenv": "^16.0.1",
"express": "^4.18.1",
"joi": "^17.6.0",
"lodash": "^4.17.21",
"morgan": "^1.10.0",
"open": "^8.4.0"
},
Expand Down
22 changes: 18 additions & 4 deletions server/src/services/item.service.js
@@ -1,5 +1,6 @@
import AWS from "../config/aws";
import { chunk, pick } from "../utils/object";
import { chunk, pick } from "lodash";
import { deserialize, serialize } from "../utils/dynamodb";

export default class ItemServiceProvider {
constructor(_AWS_ = AWS) {
Expand Down Expand Up @@ -59,7 +60,7 @@ export default class ItemServiceProvider {
}

return {
Items: slice,
Items: slice.map((item) => serialize(item)),
Count: slice.length,
ScannedCount: scannedCount,
LastEvaluatedKey: params.ExclusiveStartKey,
Expand All @@ -80,6 +81,8 @@ export default class ItemServiceProvider {

const response = await this.AWS.document.get(params);

response.Item = serialize(response.Item);

return response;
}

Expand Down Expand Up @@ -131,14 +134,20 @@ export default class ItemServiceProvider {
* @returns
*/
async update(tableName, schema, { ref, body }) {
const { Item } = await this.AWS.document.get({
Key: ref,
TableName: tableName,
});

const params = {
Key: ref,
Item: body,
TableName: tableName,
Item: deserialize(Item, body),
ConditionExpression: schema.map((key) => `attribute_exists(${key})`).join(" AND "),
};

const response = await this.AWS.document.put(params);

return response;
}

Expand All @@ -149,6 +158,11 @@ export default class ItemServiceProvider {
* @returns
*/
async transactUpdate(tableName, schema, { ref, body }) {
const { Item } = await this.AWS.document.get({
TableName: tableName,
Key: ref
});

const response = this.AWS.document.transactWrite({
TransactItems: [
{
Expand All @@ -159,7 +173,7 @@ export default class ItemServiceProvider {
},
{
Put: {
Item: body,
Item: deserialize(Item, body),
TableName: tableName,
Key: pick(body, schema),
ConditionExpression: schema.map((key) => `attribute_not_exists(${key})`).join(" AND "),
Expand Down
59 changes: 58 additions & 1 deletion server/src/utils/dynamodb.js
@@ -1,4 +1,4 @@
import { pick } from "./object";
import { get, set, pick } from "lodash";
import { create as TableSchema } from "../schemas/table.joi";
import { ProvisionedThroughput } from "../constants/dynamodb";

Expand All @@ -17,3 +17,60 @@ export function constructSchema(Table) {

return schema;
}

export function serialize(Item, path = '', callback = () => { }) {
if (["string", "number", "boolean"].includes(typeof Item)) {
return Item;
}

if (Item instanceof Set) {
callback(path)
return Array.from(Item);
}

if (Item instanceof Array) {
return Item.map((value, index) => serialize(value, `${path}[${index}]`, callback));
}

const output = {}

for (const [key, value] of Object.entries(Item)) {
const currentPath = path ? `${path}.${key}` : key;

if (value instanceof Set) {
callback(currentPath)
output[key] = Array.from(value);
continue;
}

if (value instanceof Array) {
output[key] = value.map((value, index) => serialize(value, `${currentPath}[${index}]`, callback));
continue;
}

if (value instanceof Object) {
output[key] = serialize(value, currentPath, callback);
continue;
}

output[key] = value;
}

return output;
}

export function deserialize(source = {}, object = {}) {
const paths = []

serialize(source, '', (path) => paths.push(path))

for (const path of paths) {
const value = get(object, path)

if (value instanceof Array) {
set(object, path, new Set(value))
}
}

return object
}
23 changes: 0 additions & 23 deletions server/src/utils/object.js
@@ -1,16 +1,3 @@
export function pick(object = {}, keys = []) {
const result = {};
const filteredKeys = Object.keys(object).filter((key) => keys.includes(key));

filteredKeys.forEach((key) => {
if (!object[key]) return;

result[key] = object[key];
});

return result;
}

export function isPartialMatchWith(object = {}, source = {}, keys = []) {
let match = true;

Expand All @@ -22,13 +9,3 @@ export function isPartialMatchWith(object = {}, source = {}, keys = []) {

return match;
}

export function chunk(array = [], size) {
const chunks = [];

for (let i = 0; i < array.length; i += size) {
chunks.push(array.slice(i, i + size));
}

return chunks;
}
25 changes: 7 additions & 18 deletions server/yarn.lock
Expand Up @@ -3622,6 +3622,11 @@ lodash.merge@^4.6.2:
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==

lodash@^4.17.21:
version "4.17.21"
resolved "http://verdaccio.khadasvim1s.box/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==

lru-cache@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
Expand Down Expand Up @@ -4335,16 +4340,7 @@ statuses@2.0.1:
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==

"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"

string-width@^4.1.0:
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
Expand Down Expand Up @@ -4389,14 +4385,7 @@ string.prototype.trimstart@^1.0.7:
define-properties "^1.2.0"
es-abstract "^1.22.1"

"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"

strip-ansi@^6.0.0, strip-ansi@^6.0.1:
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
Expand Down

0 comments on commit b222c4d

Please sign in to comment.