@argodigital/qq-shared
Version:
Shared code for QQ projects
123 lines (122 loc) • 6.17 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var aws_sdk_1 = require("aws-sdk");
var deep_diff_1 = require("deep-diff");
var logger_1 = require("../logger");
var iopipe_1 = require("@iopipe/iopipe");
var ioPipeEnabled = 'true' !== process.env.DISABLE_IOPIPE;
function ddbswrapper(fn) {
return function (event, context, callback) {
var _a = getImages(event), newVersions = _a.newVersions, oldVersions = _a.oldVersions, versionsToUpdate = _a.versionsToUpdate;
var log = logger_1.logger(context);
if (ioPipeEnabled) {
iopipe_1.metric('region', process.env.AWS_REGION);
iopipe_1.metric('revision', process.env.REVISION);
iopipe_1.metric('stage', process.env.STAGE);
}
function success(message) {
if (ioPipeEnabled) {
iopipe_1.label('valid');
}
return callback(null, message);
}
function error(error) {
log.error('Error', error, event);
if (ioPipeEnabled) {
iopipe_1.label('error');
iopipe_1.metric('error', error);
}
return callback(error);
}
var props = { newVersions: newVersions, oldVersions: oldVersions, versionsToUpdate: versionsToUpdate, event: event, success: success, error: error, log: log, context: context };
return fn(props);
};
}
exports.ddbswrapper = ddbswrapper;
function getImages(event) {
var newVersions = [];
var oldVersions = [];
var versionsToUpdate = [];
event.Records.forEach(function (record) {
var _a = getVersionsAndUpdates(record), newVersion = _a.newVersion, oldVersion = _a.oldVersion, versionToUpdate = _a.versionToUpdate;
if (newVersion) {
newVersions.push(newVersion);
}
if (oldVersion) {
oldVersions.push(oldVersion);
}
if (versionToUpdate) {
versionsToUpdate.push(versionToUpdate);
}
});
return { newVersions: newVersions, oldVersions: oldVersions, versionsToUpdate: versionsToUpdate };
}
function getVersionsAndUpdates(record) {
var _a = getPropsFromRecord(record), newVersion = _a.newVersion, oldVersion = _a.oldVersion, StreamViewType = _a.StreamViewType, TableName = _a.TableName, keys = _a.keys, eventName = _a.eventName;
var _b = getVersionUpdateStatus(newVersion, oldVersion, StreamViewType, eventName), needToUpdateVersion = _b.needToUpdateVersion, onlyVersionChanged = _b.onlyVersionChanged;
return {
// objects shouldn't be considered new or old if the only change was version number being incremented
newVersion: onlyVersionChanged ? undefined : newVersion,
oldVersion: onlyVersionChanged ? undefined : oldVersion,
// only update the version number if it needs to be updated (ie more than the version number was changed between old and new object)
versionToUpdate: needToUpdateVersion ? getUpdatedVersion(newVersion, oldVersion, TableName, keys) : undefined
};
}
function getUpdatedVersion(_newVersion, oldVersion, TableName, keys) {
if (oldVersion) {
oldVersion.keys = getConcatenatedKeys(keys);
oldVersion.version = oldVersion.version ? oldVersion.version : 0;
}
return {
updated: {
TableName: TableName,
Keys: keys,
version: oldVersion && oldVersion.version ? oldVersion.version + 1 : 1
},
old: oldVersion
? {
TableName: process.env.VERSIONS_TABLE,
Item: oldVersion
}
: undefined
};
}
function getPropsFromRecord(record) {
var eventName = record.eventName;
var _a = record.dynamodb, NewImage = _a.NewImage, OldImage = _a.OldImage, StreamViewType = _a.StreamViewType, Keys = _a.Keys;
var newVersion = NewImage ? aws_sdk_1.DynamoDB.Converter.unmarshall(NewImage) : undefined;
var oldVersion = OldImage ? aws_sdk_1.DynamoDB.Converter.unmarshall(OldImage) : undefined;
var keys = aws_sdk_1.DynamoDB.Converter.unmarshall(Keys);
var TableName = getTableNameFromRecord(record);
return { newVersion: newVersion, oldVersion: oldVersion, StreamViewType: StreamViewType, TableName: TableName, keys: keys, eventName: eventName };
}
function getConcatenatedKeys(keys) {
return Object.keys(keys).reduce(function (concatenated, key) { return (concatenated += key + ":" + keys[key]); }, '');
}
function getTableNameFromRecord(record) {
var streamArn = record['eventSourceARN'];
var tableArn = streamArn.split('/stream/')[0];
return tableArn.split("arn:aws:dynamodb:" + process.env.AWS_REGION + ":" + process.env.AWS_ACCOUNT_ID + ":table/")[1];
}
function getVersionUpdateStatus(newVersion, oldVersion, streamType, eventName) {
var isDelete = eventName === 'REMOVE';
var isNewObject = streamType === 'NEW_AND_OLD_IMAGES' && newVersion && !oldVersion;
var newObjectMissingVersion = newVersion && !newVersion.version;
logger_1.log.trace(newVersion);
logger_1.log.trace(oldVersion);
logger_1.log.trace("Is new object: " + isNewObject);
logger_1.log.trace("Is new object missing version: " + newObjectMissingVersion);
logger_1.log.trace("Was object deleted: " + isDelete);
var onlyVersionChanged = isVersionOnlyDifference(newVersion, oldVersion);
var needToUpdateVersion = !isDelete && (isNewObject || newObjectMissingVersion || !onlyVersionChanged);
logger_1.log.trace("Is only version changed: " + onlyVersionChanged);
logger_1.log.trace("Need to update version: " + needToUpdateVersion);
return { needToUpdateVersion: needToUpdateVersion, onlyVersionChanged: onlyVersionChanged };
}
function isVersionOnlyDifference(newVersion, oldVersion) {
var differences = deep_diff_1.diff(newVersion, oldVersion);
logger_1.log.trace(differences);
var nonVersionDifferences = differences.filter(function (difference) { return !difference.path || (difference.path.indexOf('version') < 0 && difference.path.indexOf('keys') < 0); });
logger_1.log.trace(nonVersionDifferences);
return nonVersionDifferences.length === 0;
}