UNPKG

@argodigital/qq-shared

Version:
123 lines (122 loc) 6.17 kB
"use strict"; 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; }