Last active
March 2, 2017 17:30
-
-
Save andrewluetgers/a01e59973eff7e999b1f4395716f41c3 to your computer and use it in GitHub Desktop.
DynamoDB Simple Change-Feed Lambda Trigger
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @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