Skip to content

Instantly share code, notes, and snippets.

@andrewluetgers
Last active March 2, 2017 17:30
Show Gist options
  • Save andrewluetgers/a01e59973eff7e999b1f4395716f41c3 to your computer and use it in GitHub Desktop.
Save andrewluetgers/a01e59973eff7e999b1f4395716f41c3 to your computer and use it in GitHub Desktop.
DynamoDB Simple Change-Feed Lambda Trigger
/**
* @license
* Lodash (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
* Build: `lodash include="isObject,isEqual"`
*/
;(function(){function t(t,e){for(var r=-1,n=null==t?0:t.length,o=0,a=[];++r<n;){var i=t[r];e(i,r,t)&&(a[o++]=i)}return a}function e(t,e){for(var r=-1,n=null==t?0:t.length;++r<n;)if(e(t[r],r,t))return true;return false}function r(t){return function(e){return t(e)}}function n(t){var e=-1,r=Array(t.size);return t.forEach(function(t,n){r[++e]=[n,t]}),r}function o(t){var e=-1,r=Array(t.size);return t.forEach(function(t){r[++e]=t}),r}function a(){}function i(t){var e=-1,r=null==t?0:t.length;for(this.clear();++e<r;){
var n=t[e];this.set(n[0],n[1])}}function c(t){var e=-1,r=null==t?0:t.length;for(this.clear();++e<r;){var n=t[e];this.set(n[0],n[1])}}function s(t){var e=-1,r=null==t?0:t.length;for(this.clear();++e<r;){var n=t[e];this.set(n[0],n[1])}}function u(t){var e=-1,r=null==t?0:t.length;for(this.__data__=new s;++e<r;)this.add(t[e])}function f(t){this.size=(this.__data__=new c(t)).size}function l(t,e){for(var r=t.length;r--;)if(m(t[r][0],e))return r;return-1}function _(t,e,r){if(e=e(t),!pt(t)){t=r(t),r=-1;for(var n=t.length,o=e.length;++r<n;)e[o+r]=t[r];
}return e}function b(t){if(null==t)t=t===M?"[object Undefined]":"[object Null]";else if(Y&&Y in Object(t)){var e=q.call(t,Y),r=t[Y];try{t[Y]=M;var n=true}catch(t){}var o=G.call(t);n&&(e?t[Y]=r:delete t[Y]),t=o}else t=G.call(t);return t}function h(t){return S(t)&&"[object Arguments]"==b(t)}function p(t,e,r,n,o){if(t===e)e=true;else if(null==t||null==e||!S(t)&&!S(e))e=t!==t&&e!==e;else t:{var a=pt(t),i=pt(e),c=a?"[object Array]":bt(t),s=i?"[object Array]":bt(e),c="[object Arguments]"==c?"[object Object]":c,s="[object Arguments]"==s?"[object Object]":s,u="[object Object]"==c,i="[object Object]"==s;
if((s=c==s)&&yt(t)){if(!yt(e)){e=false;break t}a=true,u=false}if(s&&!u)o||(o=new f),e=a||jt(t)?j(t,e,r,n,p,o):d(t,e,c,r,n,p,o);else{if(!(1&r)&&(a=u&&q.call(t,"__wrapped__"),c=i&&q.call(e,"__wrapped__"),a||c)){t=a?t.value():t,e=c?e.value():e,o||(o=new f),e=p(t,e,r,n,o);break t}if(s)e:if(o||(o=new f),a=1&r,c=_(t,x,_t),i=c.length,s=_(e,x,_t).length,i==s||a){for(u=i;u--;){var l=c[u];if(!(a?l in e:q.call(e,l))){e=false;break e}}if((s=o.get(t))&&o.get(e))e=s==e;else{s=true,o.set(t,e),o.set(e,t);for(var b=a;++u<i;){
var l=c[u],h=t[l],y=e[l];if(n)var g=a?n(y,h,l,e,t,o):n(h,y,l,t,e,o);if(g===M?h!==y&&!p(h,y,r,n,o):!g){s=false;break}b||(b="constructor"==l)}s&&!b&&(r=t.constructor,n=e.constructor,r!=n&&"constructor"in t&&"constructor"in e&&!(typeof r=="function"&&r instanceof r&&typeof n=="function"&&n instanceof n)&&(s=false)),o.delete(t),o.delete(e),e=s}}else e=false;else e=false}}return e}function y(t){return S(t)&&z(t.length)&&!!P[b(t)]}function j(t,r,n,o,a,i){var c=1&n,s=t.length,f=r.length;if(s!=f&&!(c&&f>s))return false;if((f=i.get(t))&&i.get(r))return f==r;
var f=-1,l=true,_=2&n?new u:M;for(i.set(t,r),i.set(r,t);++f<s;){var b=t[f],h=r[f];if(o)var p=c?o(h,b,f,r,t,i):o(b,h,f,t,r,i);if(p!==M){if(p)continue;l=false;break}if(_){if(!e(r,function(t,e){if(!_.has(e)&&(b===t||a(b,t,n,o,i)))return _.push(e)})){l=false;break}}else if(b!==h&&!a(b,h,n,o,i)){l=false;break}}return i.delete(t),i.delete(r),l}function d(t,e,r,a,i,c,s){switch(r){case"[object DataView]":if(t.byteLength!=e.byteLength||t.byteOffset!=e.byteOffset)break;t=t.buffer,e=e.buffer;case"[object ArrayBuffer]":
if(t.byteLength!=e.byteLength||!c(new K(t),new K(e)))break;return true;case"[object Boolean]":case"[object Date]":case"[object Number]":return m(+t,+e);case"[object Error]":return t.name==e.name&&t.message==e.message;case"[object RegExp]":case"[object String]":return t==e+"";case"[object Map]":var u=n;case"[object Set]":if(u||(u=o),t.size!=e.size&&!(1&a))break;return(r=s.get(t))?r==e:(a|=2,s.set(t,e),e=j(u(t),u(e),a,i,c,s),s.delete(t),e);case"[object Symbol]":if(lt)return lt.call(t)==lt.call(e)}return false;
}function g(t,e){var r=t.__data__,n=typeof e;return("string"==n||"number"==n||"symbol"==n||"boolean"==n?"__proto__"!==e:null===e)?r[typeof e=="string"?"string":"hash"]:r.map}function v(t,e){var r=null==t?M:t[e];return(!k(r)||C&&C in r?0:(O(r)?H:B).test(A(r)))?r:M}function A(t){if(null!=t){try{return W.call(t)}catch(t){}return t+""}return""}function m(t,e){return t===e||t!==t&&e!==e}function w(t){return null!=t&&z(t.length)&&!O(t)}function O(t){return!!k(t)&&(t=b(t),"[object Function]"==t||"[object GeneratorFunction]"==t||"[object AsyncFunction]"==t||"[object Proxy]"==t);
}function z(t){return typeof t=="number"&&-1<t&&0==t%1&&9007199254740991>=t}function k(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}function S(t){return null!=t&&typeof t=="object"}function x(t){if(w(t)){var e=pt(t),r=!e&&ht(t),n=!e&&!r&&yt(t),o=!e&&!r&&!n&&jt(t);if(e=e||r||n||o){for(var r=t.length,a=String,i=-1,c=Array(r);++i<r;)c[i]=a(i);r=c}else r=[];var s,a=r.length;for(s in t)(i=!q.call(t,s))||!(i=e)||(i="length"==s||n&&("offset"==s||"parent"==s)||o&&("buffer"==s||"byteLength"==s||"byteOffset"==s))||(i=s,
c=a,c=null==c?9007199254740991:c,i=!!c&&(typeof i=="number"||L.test(i))&&-1<i&&0==i%1&&i<c),i||r.push(s);t=r}else if(s=t&&t.constructor,t===(typeof s=="function"&&s.prototype||R)){s=[];for(n in Object(t))q.call(t,n)&&"constructor"!=n&&s.push(n);t=s}else t=tt(t);return t}function E(){return[]}function F(){return false}var M,B=/^\[object .+?Constructor\]$/,L=/^(?:0|[1-9]\d*)$/,P={};P["[object Float32Array]"]=P["[object Float64Array]"]=P["[object Int8Array]"]=P["[object Int16Array]"]=P["[object Int32Array]"]=P["[object Uint8Array]"]=P["[object Uint8ClampedArray]"]=P["[object Uint16Array]"]=P["[object Uint32Array]"]=true,
P["[object Arguments]"]=P["[object Array]"]=P["[object ArrayBuffer]"]=P["[object Boolean]"]=P["[object DataView]"]=P["[object Date]"]=P["[object Error]"]=P["[object Function]"]=P["[object Map]"]=P["[object Number]"]=P["[object Object]"]=P["[object RegExp]"]=P["[object Set]"]=P["[object String]"]=P["[object WeakMap]"]=false;var D,$=typeof global=="object"&&global&&global.Object===Object&&global,I=typeof self=="object"&&self&&self.Object===Object&&self,I=$||I||Function("return this")(),T=typeof exports=="object"&&exports&&!exports.nodeType&&exports,U=T&&typeof module=="object"&&module&&!module.nodeType&&module,V=U&&U.exports===T,$=V&&$.process;
t:{try{D=$&&$.binding&&$.binding("util");break t}catch(t){}D=void 0}D=D&&D.isTypedArray;var $=Array.prototype,R=Object.prototype,N=I["__core-js_shared__"],W=Function.prototype.toString,q=R.hasOwnProperty,C=function(){var t=/[^.]+$/.exec(N&&N.keys&&N.keys.IE_PROTO||"");return t?"Symbol(src)_1."+t:""}(),G=R.toString,H=RegExp("^"+W.call(q).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),J=V?I.Buffer:M,V=I.Symbol,K=I.Uint8Array,Q=R.propertyIsEnumerable,X=$.splice,Y=V?V.toStringTag:M,Z=Object.getOwnPropertySymbols,$=J?J.isBuffer:M,tt=function(t,e){
return function(r){return t(e(r))}}(Object.keys,Object),J=v(I,"DataView"),et=v(I,"Map"),rt=v(I,"Promise"),nt=v(I,"Set"),ot=v(I,"WeakMap"),at=v(Object,"create"),it=A(J),ct=A(et),st=A(rt),ut=A(nt),ft=A(ot),lt=(V=V?V.prototype:M)?V.valueOf:M;i.prototype.clear=function(){this.__data__=at?at(null):{},this.size=0},i.prototype.delete=function(t){return t=this.has(t)&&delete this.__data__[t],this.size-=t?1:0,t},i.prototype.get=function(t){var e=this.__data__;return at?(t=e[t],"__lodash_hash_undefined__"===t?M:t):q.call(e,t)?e[t]:M;
},i.prototype.has=function(t){var e=this.__data__;return at?e[t]!==M:q.call(e,t)},i.prototype.set=function(t,e){var r=this.__data__;return this.size+=this.has(t)?0:1,r[t]=at&&e===M?"__lodash_hash_undefined__":e,this},c.prototype.clear=function(){this.__data__=[],this.size=0},c.prototype.delete=function(t){var e=this.__data__;return t=l(e,t),!(0>t)&&(t==e.length-1?e.pop():X.call(e,t,1),--this.size,true)},c.prototype.get=function(t){var e=this.__data__;return t=l(e,t),0>t?M:e[t][1]},c.prototype.has=function(t){
return-1<l(this.__data__,t)},c.prototype.set=function(t,e){var r=this.__data__,n=l(r,t);return 0>n?(++this.size,r.push([t,e])):r[n][1]=e,this},s.prototype.clear=function(){this.size=0,this.__data__={hash:new i,map:new(et||c),string:new i}},s.prototype.delete=function(t){return t=g(this,t).delete(t),this.size-=t?1:0,t},s.prototype.get=function(t){return g(this,t).get(t)},s.prototype.has=function(t){return g(this,t).has(t)},s.prototype.set=function(t,e){var r=g(this,t),n=r.size;return r.set(t,e),this.size+=r.size==n?0:1,
this},u.prototype.add=u.prototype.push=function(t){return this.__data__.set(t,"__lodash_hash_undefined__"),this},u.prototype.has=function(t){return this.__data__.has(t)},f.prototype.clear=function(){this.__data__=new c,this.size=0},f.prototype.delete=function(t){var e=this.__data__;return t=e.delete(t),this.size=e.size,t},f.prototype.get=function(t){return this.__data__.get(t)},f.prototype.has=function(t){return this.__data__.has(t)},f.prototype.set=function(t,e){var r=this.__data__;if(r instanceof c){
var n=r.__data__;if(!et||199>n.length)return n.push([t,e]),this.size=++r.size,this;r=this.__data__=new s(n)}return r.set(t,e),this.size=r.size,this};var _t=Z?function(e){return null==e?[]:(e=Object(e),t(Z(e),function(t){return Q.call(e,t)}))}:E,bt=b;(J&&"[object DataView]"!=bt(new J(new ArrayBuffer(1)))||et&&"[object Map]"!=bt(new et)||rt&&"[object Promise]"!=bt(rt.resolve())||nt&&"[object Set]"!=bt(new nt)||ot&&"[object WeakMap]"!=bt(new ot))&&(bt=function(t){var e=b(t);if(t=(t="[object Object]"==e?t.constructor:M)?A(t):"")switch(t){
case it:return"[object DataView]";case ct:return"[object Map]";case st:return"[object Promise]";case ut:return"[object Set]";case ft:return"[object WeakMap]"}return e});var ht=h(function(){return arguments}())?h:function(t){return S(t)&&q.call(t,"callee")&&!Q.call(t,"callee")},pt=Array.isArray,yt=$||F,jt=D?r(D):y;a.keys=x,a.eq=m,a.isArguments=ht,a.isArray=pt,a.isArrayLike=w,a.isBuffer=yt,a.isEqual=function(t,e){return p(t,e)},a.isFunction=O,a.isLength=z,a.isObject=k,a.isObjectLike=S,a.isTypedArray=jt,
a.stubArray=E,a.stubFalse=F,a.VERSION="4.17.4",I._=a}).call(this);
function unique(value, index, self) {
return self.indexOf(value) === index;
}
function isEmpty(obj) {
return !obj || !Object.keys(obj).length;
}
function isArray(obj) {
return !!(obj && obj.concat);
}
function isObject(value) {
var type = typeof value;
return value != null && (type == 'object' || type == 'function');
}
function diff(template, override) {
if (!isObject(override)) {
return undefined;
}
// handle arrays
if (!isObject(template) || (isArray(override) || isArray(template)) && !_.isEqual(template, override)) {
return override;
}
var ret = {},
hasDiff = false,
oVal, tVal,
keys = Object.keys(template).concat(Object.keys(override)).filter(unique);
keys.forEach(function(name) {
oVal = override[name];
tVal = template[name];
if (tVal && isObject(oVal) && !isArray(oVal)) {
var _diff = diff(tVal, oVal);
if (!isEmpty(_diff)) {
hasDiff = true;
ret[name] = _diff;
}
} else if (!_.isEqual(tVal, oVal)) {
hasDiff = true;
ret[name] = oVal;
}
});
return hasDiff ? ret : null;
}
function mapper(data, setType) {
var keys = Object.keys(data),
ret = data.concat ? [] : {};
console.log("keys", keys);
while (keys.length) {
var key = keys.shift(),
obj = data[key];
console.log("key", key, obj);
if (setType) {
switch(setType) {
case "BB":
case "SS": ret[key] = obj; break;
case "NN": ret[key] = parseFloat(obj); break;
}
} else if (typeof obj === "object" && obj !== null) {
var type = Object.keys(obj)[0];
switch(type) {
case "S":
case "B":
case "BOOL": ret[key] = obj[type]; break;
case "N": ret[key] = parseFloat(obj[type]); break;
case "NULL": ret[key] = null; break;
case "L":
case "M": ret[key] = mapper(obj[type]); break;
case "SS":
case "NN":
case "BB": ret[key] = mapper(obj[type], type); break;
}
}
}
return ret;
}
exports.handler = function(event, context, callback) {
var items = [];
if (event.Records) {
event.Records.forEach(function(r) {
var ddb = r.dynamodb,
o = ddb.OldImage,
n = ddb.NewImage,
rec = {
"eventName": r.eventName,
"ts": ddb && ddb.ApproximateCreationDateTime
};
if (o && n) {
rec.diff = diff(mapper(o), mapper(n));
} else {
o && (rec.old = mapper(o));
n && (rec.new = mapper(n));
}
items.push(rec);
});
}
callback(null, items);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment