@moicky/dynamodb
Version:
Contains a collection of convenience functions for working with AWS DynamoDB
112 lines (111 loc) • 4.17 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getResolvedDependencies = exports.getDependencies = exports.resolveReferences = exports.createCustomReference = exports.createReference = void 0;
const crypto_1 = require("crypto");
const operations_1 = require("../../operations");
const createReference = (ref, transaction) => {
const { item, references, onAttribute } = ref;
const referenceKey = {
PK: references.PK,
...(references.SK !== undefined && { SK: references.SK }),
};
const referenceItem = {
PK: "dynamodb:reference",
SK: (0, crypto_1.randomUUID)(),
item: {
PK: item.PK,
...(item.SK !== undefined && { SK: item.SK }),
},
references: referenceKey,
onAttribute,
};
transaction.create(referenceItem);
return {
_type: "dynamodb:reference",
_target: referenceKey,
_refId: referenceItem.SK,
};
};
exports.createReference = createReference;
const itemToStringKey = (item) => `${item.PK}#|#${item.SK}`;
const getRefsToResolve = (item) => {
const refs = [];
if (!item)
return refs;
if (typeof item !== "object")
return refs;
if (item?._type === "dynamodb:reference")
return [item?._target];
for (const value of Object.values(item)) {
if (typeof value === "object") {
if (value instanceof Set || Array.isArray(value)) {
refs.push(...[...value].map((v) => getRefsToResolve(v)).flat());
}
else if (value?._type === "dynamodb:reference") {
refs.push(value?._target);
}
else {
refs.push(...getRefsToResolve(value));
}
}
}
return refs;
};
const injectRefs = (item, refs) => {
if (!item)
return item;
if (typeof item !== "object")
return item;
if (item?._type === "dynamodb:reference") {
return refs[itemToStringKey(item._target)];
}
for (const [key, value] of Object.entries(item)) {
if (typeof value === "object") {
if (value instanceof Set || Array.isArray(value)) {
item[key] = new Set([...value].map((v) => injectRefs(v, refs)));
}
else if (value?._type === "dynamodb:reference") {
item[key] = refs[itemToStringKey(value._target)];
}
else {
item[key] = injectRefs(value, refs);
}
}
}
return item;
};
const createCustomReference = async (baseItem, references, onAttribute) => (0, operations_1.putItem)({
PK: "dynamodb:reference",
SK: (0, crypto_1.randomUUID)(),
item: {
PK: baseItem.PK,
...(baseItem.SK !== undefined && { SK: baseItem.SK }),
},
references: {
PK: references.PK,
...(references.SK !== undefined && { SK: references.SK }),
},
onAttribute: onAttribute || "",
}, { ReturnValues: "ALL_NEW" });
exports.createCustomReference = createCustomReference;
const resolveReferences = async (item) => {
const resolvedItem = structuredClone(item);
let refs = getRefsToResolve(item);
if (!refs.length)
return item;
const fetchedRefs = await (0, operations_1.getItems)(refs).then((items) => items.reduce((acc, item) => ({ ...acc, [itemToStringKey(item)]: item }), {}));
return injectRefs(resolvedItem, fetchedRefs);
};
exports.resolveReferences = resolveReferences;
const getDependencies = async (item) => (0, operations_1.queryAllItems)("#PK = :PK", {
PK: "dynamodb:reference",
references: {
PK: item.PK,
...(item.SK !== undefined && { SK: item.SK }),
},
}, { FilterExpression: "#references = :references" });
exports.getDependencies = getDependencies;
const getResolvedDependencies = async (item) => (0, exports.getDependencies)(item).then((refs) => (0, operations_1.getItems)(refs
.map(({ item }) => item)
.filter((item, index, array) => array.findIndex((i) => i.SK === item.SK) === index)).then((items) => items.filter(Boolean)));
exports.getResolvedDependencies = getResolvedDependencies;