@moicky/dynamodb
Version:
Contains a collection of convenience functions for working with AWS DynamoDB
107 lines (106 loc) • 4.06 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getItemKey = exports.ExpressionAttributes = exports.getAttributesFromExpression = exports.getAttributeNames = exports.getAttributeValues = exports.splitEvery = exports.stripKey = void 0;
const fixes_1 = require("./fixes");
const schemas_1 = require("./schemas");
// Since dynamo only accepts key atrtributes which are described in table schema
// we remove any other attributes from the item if they are present and passed as
// key parameter to any of the functions below (getItem, updateItem, deleteItem...)
function stripKey(key, args) {
const { hash, range } = (0, schemas_1.getTableSchema)(args?.TableName);
return (0, fixes_1.marshallWithOptions)({
[hash]: key[hash],
...(range && { [range]: key[range] }),
});
}
exports.stripKey = stripKey;
function splitEvery(items, limit = 25) {
const batches = [];
for (let i = 0; i < items.length; i += limit) {
batches.push(items.slice(i, i + limit));
}
return batches;
}
exports.splitEvery = splitEvery;
function getAttributeValues(key, { attributesToGet, prefix = ":", } = {}) {
return (0, fixes_1.marshallWithOptions)((attributesToGet || Object.keys(key)).reduce((acc, keyName) => {
acc[`${prefix}${keyName}`] = key[keyName];
return acc;
}, {}));
}
exports.getAttributeValues = getAttributeValues;
function getAttributeNames(key, { attributesToGet, prefix = "#", } = {}) {
return (attributesToGet || Object.keys(key)).reduce((acc, keyName) => {
acc[`${prefix}${keyName}`] = keyName;
return acc;
}, {});
}
exports.getAttributeNames = getAttributeNames;
function getAttributesFromExpression(expression, prefix = "#") {
return (expression
.match(new RegExp(`${prefix}\\w+`, "g"))
?.map((attr) => attr.slice(1)) || []);
}
exports.getAttributesFromExpression = getAttributesFromExpression;
class ExpressionAttributes {
ExpressionAttributeValues;
ExpressionAttributeNames;
nameMapping = {};
valueMapping = {};
nameCounter = 0;
valueCounter = 0;
constructor(ExpressionAttributeValues = {}, ExpressionAttributeNames = {}) {
this.ExpressionAttributeValues = ExpressionAttributeValues;
this.ExpressionAttributeNames = ExpressionAttributeNames;
}
appendNames(names) {
names.forEach((name) => {
const parts = name.split(".");
parts.forEach((part) => {
if (!this.nameMapping[part]) {
const newName = `#${this.nameCounter++}`;
this.nameMapping[part] = newName;
this.ExpressionAttributeNames[newName] = part;
}
});
});
}
appendValues(values) {
Object.entries(values).forEach(([key, value]) => {
const newValueName = `:${this.valueCounter++}`;
this.valueMapping[key] = newValueName;
this.ExpressionAttributeValues[newValueName] = value;
});
}
appendBoth(values) {
this.appendNames(Object.keys(values));
this.appendValues(values);
}
getAttributes() {
const marshalled = (0, fixes_1.marshallWithOptions)(this.ExpressionAttributeValues);
return {
ExpressionAttributeNames: this.ExpressionAttributeNames,
...(Object.keys(marshalled).length > 0 && {
ExpressionAttributeValues: marshalled,
}),
};
}
getName(attributeName) {
return attributeName
.split(".")
.map((part) => this.nameMapping[part])
.join(".");
}
getValue(attributeName) {
return this.valueMapping[attributeName];
}
}
exports.ExpressionAttributes = ExpressionAttributes;
const getItemKey = (item, args) => {
const { hash, range } = (0, schemas_1.getTableSchema)(args?.TableName);
return JSON.stringify({
[hash]: item[hash],
...(range && { [range]: item[range] }),
});
};
exports.getItemKey = getItemKey;