UNPKG

@moicky/dynamodb

Version:

Contains a collection of convenience functions for working with AWS DynamoDB

112 lines (111 loc) 4.17 kB
"use strict"; 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;