From 8a5da38b90d256e7eb16b722c398b08536ac70ea Mon Sep 17 00:00:00 2001 From: Blake West Date: Fri, 23 Jan 2015 18:19:12 -0800 Subject: [PATCH] Added "PATCH" route creation, cuz it should be there. --- bower.json | 2 +- dist/facade.js | 19 ++++++++++++++++++- dist/facade.min.js | 4 ++-- src/facade.js | 19 ++++++++++++++++++- 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/bower.json b/bower.json index a590c08..8791bf9 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "facade", - "version": "0.4.5", + "version": "0.4.6", "authors": [ "Blake West " ], diff --git a/dist/facade.js b/dist/facade.js index 58fc858..a438013 100644 --- a/dist/facade.js +++ b/dist/facade.js @@ -221,6 +221,23 @@ var Y=s();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(G. }); } + function createPatchRoute(opts) { + var headers = {}; + Facade.backend.whenPATCH(opts.resource.url + '/' + opts.item.id) + .respond(function(method, url, data, headers) { + data = data || {}; + var route = Facade.findRoute(method, url); + var response = route.getSpecialResponseOr(function() { + var item = getOneItem(opts.resource, opts.item.id); + // Perform the patch on the db object + _.assign(item, JSON.parse(data)); + return [200, JSON.stringify(item), headers, 'OK'] + }) + + return response; + }); + } + function createDeleteRoute(opts) { var headers = {}; @@ -278,6 +295,7 @@ var Y=s();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(G. return [ {createWith: createItemIdRoute, method: 'GET'}, {createWith: createPutRoute, method: 'PUT'}, + {createWith: createPatchRoute, method: 'PATCH'}, {createWith: createDeleteRoute, method: 'DELETE'} ]; } @@ -325,7 +343,6 @@ var Y=s();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(G. function createExpectationFor(opts) { var fullUrl = opts.resource.url + opts.route; - console.log('creating expecation'); Facade.backend.expect(opts.method, fullUrl, withJSON(opts.expected)) .respond(function(method, url, requestData, headers) { requestData = JSON.parse(requestData || "{}"); diff --git a/dist/facade.min.js b/dist/facade.min.js index f16c63e..a1f9932 100644 --- a/dist/facade.min.js +++ b/dist/facade.min.js @@ -1,2 +1,2 @@ -(function(){function n(n,e,t){t=(t||0)-1;for(var r=n?n.length:0;++ta||"undefined"==typeof i)return 1;if(a>i||"undefined"==typeof a)return-1}}return n.n-e.n}function o(n){var e=-1,r=n.length,u=n[0],o=n[r/2|0],i=n[r-1];if(u&&"object"==typeof u&&o&&"object"==typeof o&&i&&"object"==typeof i)return!1;for(u=c(),u["false"]=u["null"]=u["true"]=u.undefined=!1,o=c(),o.k=n,o.l=u,o.push=t;++et?0:t);++r3&&"function"==typeof i[c-2])var f=ee(i[--c-1],i[c--],2);else c>2&&"function"==typeof i[c-1]&&(f=i[--c]);for(;++a=y&&i===n,f=[];if(c){var s=o(r);s?(i=e,r=s):c=!1}for(;++ui(r,s)&&f.push(s);return c&&l(r),f}function ue(n,e,t,r){r=(r||0)-1;for(var u=n?n.length:0,o=[];++r=y&&c===n,d=u||h?a():p;for(h&&(d=o(d),c=e);++ic(d,v))&&((u||h)&&d.push(v),p.push(g))}return h?(f(d.k),l(d)):u&&f(d),p}function fe(n){return function(e,t,r){var u={};t=M.createCallback(t,r,3),r=-1;var o=e?e.length:0;if("number"==typeof o)for(;++rt?jt(0,o+t):t)||0,Dt(n)?i=-1o&&(o=a)}}else e=null==e&&Ee(n)?r:M.createCallback(e,t,3),Re(n,function(n,t,r){t=e(n,t,r),t>u&&(u=t,o=n)});return o}function Ae(n,e,t,r){if(!n)return t;var u=3>arguments.length;e=M.createCallback(e,r,4);var o=-1,i=n.length;if("number"==typeof i)for(u&&(t=n[++o]);++oarguments.length;return e=M.createCallback(e,r,4),Ne(n,function(n,r,o){t=u?(u=!1,n):e(t,n,r,o)}),t}function De(n){var e=-1,t=n?n.length:0,r=Qe("number"==typeof t?t:0);return Re(n,function(n){var t=ae(0,++e);r[e]=r[t],r[t]=n}),r}function Je(n,e,t){var r;e=M.createCallback(e,t,3),t=-1;var u=n?n.length:0;if("number"==typeof u)for(;++tr?jt(0,u+r):r||0}else if(r)return r=Be(e,t),e[r]===t?r:-1;return n(e,t,r)}function $e(n,e,t){if("number"!=typeof e&&null!=e){var r=0,u=-1,o=n?n.length:0;for(e=M.createCallback(e,t,3);++uu;)r=u+o>>>1,t(n[r])t?0:t);++e0?l=bt(u,t):(i&&ht(i),t=s,i=l=s=h,t&&(p=Ut(),a=n.apply(f,o),l||i||(o=f=null)))}var o,i,a,c,f,l,s,p=0,d=!1,g=!0;if(!_e(n))throw new it;if(e=jt(0,e)||0,!0===t)var v=!0,g=!1;else we(t)&&(v=t.leading,d="maxWait"in t&&(jt(e,t.maxWait)||0),g="trailing"in t?t.trailing:g);return function(){if(o=arguments,c=Ut(),f=this,s=g&&(l||!v),!1===d)var t=v&&!l;else{i||v||(p=c);var h=d-(c-p),m=0>=h;m?(i&&(i=ht(i)),p=c,a=n.apply(f,o)):i||(i=bt(r,h))}return m&&l?l=ht(l):l||e===d||(l=bt(u,e)),t&&(m=!0,a=n.apply(f,o)),!m||l||i||(o=f=null),a}}function Ue(n){return n}function Ye(n,e,t){var r=!0,u=e&&ye(e);e&&(t||u.length)||(null==t&&(t=e),o=V,e=n,n=M,u=ye(e)),!1===t?r=!1:we(t)&&"chain"in t&&(r=t.chain);var o=n,i=_e(o);Re(u,function(t){var u=n[t]=e[t];i&&(o.prototype[t]=function(){var e=this.__chain__,t=this.__wrapped__,i=[t];if(yt.apply(i,arguments),i=u.apply(n,i),r||e){if(t===i&&we(i))return this;i=new o(i),i.__chain__=e}return i})})}function He(){}function Me(n){return function(e){return e[n]}}function Ve(){return this.__wrapped__}t=t?X.defaults(Y.Object(),t,X.pick(Y,C)):Y;var Qe=t.Array,Xe=t.Boolean,Ze=t.Date,nt=t.Function,et=t.Math,tt=t.Number,rt=t.Object,ut=t.RegExp,ot=t.String,it=t.TypeError,at=[],ct=rt.prototype,ft=t._,lt=ct.toString,st=ut("^"+ot(lt).replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/toString| for [^\]]+/g,".*?")+"$"),pt=et.ceil,ht=t.clearTimeout,dt=et.floor,gt=nt.prototype.toString,vt=he(vt=rt.getPrototypeOf)&&vt,mt=ct.hasOwnProperty,yt=at.push,bt=t.setTimeout,_t=at.splice,wt=at.unshift,kt=function(){try{var n={},e=he(e=rt.defineProperty)&&e,t=e(n,n,n)&&e}catch(r){}return t}(),Et=he(Et=rt.create)&&Et,xt=he(xt=Qe.isArray)&&xt,Ot=t.isFinite,Ft=t.isNaN,St=he(St=rt.keys)&&St,jt=et.max,Rt=et.min,Nt=t.parseInt,Tt=et.random,Ct={};Ct[I]=Qe,Ct[D]=Xe,Ct[J]=Ze,Ct[P]=nt,Ct[$]=rt,Ct[W]=tt,Ct[B]=ut,Ct[K]=ot,V.prototype=M.prototype;var At=M.support={};At.funcDecomp=!he(t.a)&&N.test(p),At.funcNames="string"==typeof nt.name,M.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:S,variable:"",imports:{_:M}},Et||(ne=function(){function n(){}return function(e){if(we(e)){n.prototype=e;var r=new n;n.prototype=null}return r||t.Object()}}());var It=kt?function(n,e){G.value=e,kt(n,"__bindData__",G)}:He,Dt=xt||function(n){return n&&"object"==typeof n&&"number"==typeof n.length&<.call(n)==I||!1},Jt=St?function(n){return we(n)?St(n):[]}:H,Pt={"&":"&","<":"<",">":">",'"':""","'":"'"},Wt=be(Pt),$t=ut("("+Jt(Wt).join("|")+")","g"),Bt=ut("["+Jt(Pt).join("")+"]","g"),Kt=vt?function(n){if(!n||lt.call(n)!=$)return!1;var e=n.valueOf,t=he(e)&&(t=vt(e))&&vt(t);return t?n==t||vt(n)==t:de(n)}:de,zt=fe(function(n,e,t){mt.call(n,t)?n[t]++:n[t]=1}),qt=fe(function(n,e,t){(mt.call(n,t)?n[t]:n[t]=[]).push(e)}),Gt=fe(function(n,e,t){n[t]=e}),Lt=Te,Ut=he(Ut=Ze.now)&&Ut||function(){return(new Ze).getTime()},Yt=8==Nt(_+"08")?Nt:function(n,e){return Nt(Ee(n)?n.replace(j,""):n,e||0)};return M.after=function(n,e){if(!_e(e))throw new it;return function(){return 1>--n?e.apply(this,arguments):void 0}},M.assign=U,M.at=function(n){for(var e=arguments,t=-1,r=ue(e,!0,!1,1),e=e[2]&&e[2][e[1]]===n?1:r.length,u=Qe(e);++t=y&&o(r?t[r]:p)))}var s=t[0],d=-1,g=s?s.length:0,v=[];n:for(;++d(m?e(m,h):c(p,h))){for(r=u,(m||p).push(h);--r;)if(m=i[r],0>(m?e(m,h):c(t[r],h)))continue n;v.push(h)}}for(;u--;)(m=i[u])&&l(m);return f(i),f(p),v},M.invert=be,M.invoke=function(n,e){var t=s(arguments,2),r=-1,u="function"==typeof e,o=n?n.length:0,i=Qe("number"==typeof o?o:0);return Re(n,function(n){i[++r]=(u?e:n[e]).apply(n,t)}),i},M.keys=Jt,M.map=Te,M.mapValues=function(n,e,t){var r={};return e=M.createCallback(e,t,3),d(n,function(n,t,u){r[t]=e(n,t,u)}),r},M.max=Ce,M.memoize=function(n,e){function t(){var r=t.cache,u=e?e.apply(this,arguments):m+arguments[0];return mt.call(r,u)?r[u]:r[u]=n.apply(this,arguments)}if(!_e(n))throw new it;return t.cache={},t},M.merge=function(n){var e=arguments,t=2;if(!we(n))return n;if("number"!=typeof e[2]&&(t=e.length),t>3&&"function"==typeof e[t-2])var r=ee(e[--t-1],e[t--],2);else t>2&&"function"==typeof e[t-1]&&(r=e[--t]);for(var e=s(arguments,1,t),u=-1,o=a(),i=a();++ua&&(o=a)}}else e=null==e&&Ee(n)?r:M.createCallback(e,t,3),Re(n,function(n,t,r){t=e(n,t,r),u>t&&(u=t,o=n)});return o},M.omit=function(n,e,t){var r={};if("function"!=typeof e){var u=[];g(n,function(n,e){u.push(e)});for(var u=re(u,ue(arguments,!0,!1,1)),o=-1,i=u.length;++ot?jt(0,r+t):Rt(t,r-1))+1);r--;)if(n[r]===e)return r;return-1},M.mixin=Ye,M.noConflict=function(){return t._=ft,this},M.noop=He,M.now=Ut,M.parseInt=Yt,M.random=function(n,e,t){var r=null==n,u=null==e;return null==t&&("boolean"==typeof n&&u?(t=n,n=1):u||"boolean"!=typeof e||(t=e,u=!0)),r&&u&&(e=1),n=+n||0,u?(e=n,n=0):e=+e||0,t||n%1||e%1?(t=Tt(),Rt(n+t*(e-n+parseFloat("1e-"+((t+"").length-1))),e)):ae(n,e)},M.reduce=Ae,M.reduceRight=Ie,M.result=function(n,e){if(n){var t=n[e];return _e(t)?n[e]():t}},M.runInContext=p,M.size=function(n){var e=n?n.length:0;return"number"==typeof e?e:Jt(n).length},M.some=Je,M.sortedIndex=Be,M.template=function(n,e,t){var r=M.templateSettings;n=ot(n||""),t=b({},t,r);var u,o=b({},t.imports,r.imports),r=Jt(o),o=xe(o),a=0,c=t.interpolate||R,f="__p+='",c=ut((t.escape||R).source+"|"+c.source+"|"+(c===S?x:R).source+"|"+(t.evaluate||R).source+"|$","g");n.replace(c,function(e,t,r,o,c,l){return r||(r=o),f+=n.slice(a,l).replace(T,i),t&&(f+="'+__e("+t+")+'"),c&&(u=!0,f+="';"+c+";\n__p+='"),r&&(f+="'+((__t=("+r+"))==null?'':__t)+'"),a=l+e.length,e}),f+="';",c=t=t.variable,c||(t="obj",f="with("+t+"){"+f+"}"),f=(u?f.replace(w,""):f).replace(k,"$1").replace(E,"$1;"),f="function("+t+"){"+(c?"":t+"||("+t+"={});")+"var __t,__p='',__e=_.escape"+(u?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+f+"return __p}";try{var l=nt(r,"return "+f).apply(h,o)}catch(s){throw s.source=f,s}return e?l(e):(l.source=f,l)},M.unescape=function(n){return null==n?"":ot(n).replace($t,ge)},M.uniqueId=function(n){var e=++v;return ot(null==n?"":n)+e},M.all=Fe,M.any=Je,M.detect=je,M.findWhere=je,M.foldl=Ae,M.foldr=Ie,M.include=Oe,M.inject=Ae,Ye(function(){var n={};return d(M,function(e,t){M.prototype[t]||(n[t]=e)}),n}(),!1),M.first=Pe,M.last=function(n,e,t){var r=0,u=n?n.length:0;if("number"!=typeof e&&null!=e){var o=u;for(e=M.createCallback(e,t,3);o--&&e(n[o],o,n);)r++}else if(r=e,null==r||t)return n?n[u-1]:h;return s(n,jt(0,u-r))},M.sample=function(n,e,t){return n&&"number"!=typeof n.length&&(n=xe(n)),null==e||t?n?n[ae(0,n.length-1)]:h:(n=De(n),n.length=Rt(jt(0,e),n.length),n)},M.take=Pe,M.head=Pe,d(M,function(n,e){var t="sample"!==e;M.prototype[e]||(M.prototype[e]=function(e,r){var u=this.__chain__,o=n(this.__wrapped__,e,r);return u||null!=e&&(!r||t&&"function"==typeof e)?new V(o,u):o})}),M.VERSION="2.4.1",M.prototype.chain=function(){return this.__chain__=!0,this},M.prototype.toString=function(){return ot(this.__wrapped__)},M.prototype.value=Ve,M.prototype.valueOf=Ve,Re(["join","pop","shift"],function(n){var e=at[n];M.prototype[n]=function(){var n=this.__chain__,t=e.apply(this.__wrapped__,arguments);return n?new V(t,n):t}}),Re(["push","reverse","sort","unshift"],function(n){var e=at[n];M.prototype[n]=function(){return e.apply(this.__wrapped__,arguments),this}}),Re(["concat","slice","splice"],function(n){var e=at[n];M.prototype[n]=function(){return new V(e.apply(this.__wrapped__,arguments),this.__chain__)}}),M}var h,d=[],g=[],v=0,m=+new Date+"",y=75,b=40,_=" \f \n\r\u2028\u2029 ᠎              ",w=/\b__p\+='';/g,k=/\b(__p\+=)''\+/g,E=/(__e\(.*?\)|\b__t\))\+'';/g,x=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,O=/\w*$/,F=/^\s*function[ \n\r\t]+\w/,S=/<%=([\s\S]+?)%>/g,j=RegExp("^["+_+"]*0+(?=.$)"),R=/($^)/,N=/\bthis\b/,T=/['\n\r\t\u2028\u2029\\]/g,C="Array Boolean Date Function Math Number Object RegExp String _ attachEvent clearTimeout isFinite isNaN parseInt setTimeout".split(" "),A="[object Arguments]",I="[object Array]",D="[object Boolean]",J="[object Date]",P="[object Function]",W="[object Number]",$="[object Object]",B="[object RegExp]",K="[object String]",z={};z[P]=!1,z[A]=z[I]=z[D]=z[J]=z[W]=z[$]=z[B]=z[K]=!0;var q={leading:!1,maxWait:0,trailing:!1},G={configurable:!1,enumerable:!1,value:null,writable:!1},L={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},U={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"},Y=L[typeof window]&&window||this,H=L[typeof exports]&&exports&&!exports.nodeType&&exports,M=L[typeof module]&&module&&!module.nodeType&&module,V=M&&M.exports===H&&H,Q=L[typeof global]&&global;!Q||Q.global!==Q&&Q.window!==Q||(Y=Q);var X=p();"function"==typeof define&&"object"==typeof define.amd&&define.amd?(Y._=X,define(function(){return X})):H&&M?V?(M.exports=X)._=X:H._=X:Y._=X}).call(this),function(){"use strict";function n(){$=_.clone(Facade.resources,!0),B=_.clone(Facade.db,!0),K=_.clone(W,!0)}function e(n){t(n),r(n)}function t(n){_.each(s(),function(e){var t={resource:n,method:e.method};e.createWith(t),g(t)})}function r(n){var e=E(n);_.each(e,function(e){u(n,e)})}function u(n,e){_.each(l(),function(t){var r={resource:n,item:e,method:t.method};t.createWith(r),g(r)}),_.each(z,function(n){n.onItem&&(n.item=e,p(n),g(n))})}function o(n){Facade.backend.whenGET(n.resource.url+"/"+n.item.id).respond(function(e,t){var r=Facade.findRoute(e,t),u=r.getSpecialResponseOr(function(){var e=x(n.resource,n.item.id);return[200,JSON.stringify(e),{},"OK"]});return u})}function i(n){Facade.backend.whenPUT(n.resource.url+"/"+n.item.id).respond(function(e,t,r,u){r=r||{};var o=Facade.findRoute(e,t),i=o.getSpecialResponseOr(function(){var e=x(n.resource,n.item.id);return _.assign(e,JSON.parse(r)),[200,JSON.stringify(e),u,"OK"]});return i})}function a(n){Facade.backend.whenDELETE(n.resource.url+"/"+n.item.id).respond(function(e,t,r){r=r||{};var u=Facade.findRoute(e,t),o=u.getSpecialResponseOr(function(){var e=k(n.resource).delete(n.item.id);return[200,JSON.stringify(e),{},"OK"]});return o})}function c(n){Facade.backend.whenPOST(n.resource.url).respond(function(e,t,r){r=r||{},r=JSON.parse(r);var u=Facade.findRoute(e,t),o=u.getSpecialResponseOr(function(){var e=_.isFunction(n.resource.createDefault)&&n.resource.createDefault(r);return e=e||r,n.resource.addItem(e),[200,JSON.stringify(e),{},"OK"]});return o})}function f(n){Facade.backend.whenGET(n.resource.url).respond(function(e,t){var r=Facade.findRoute(e,t),u=r.getSpecialResponseOr(function(){return[200,E(n.resource),{},"OK"]});return u})}function l(){return[{createWith:o,method:"GET"},{createWith:i,method:"PUT"},{createWith:a,method:"DELETE"}]}function s(){return[{createWith:c,method:"POST"},{createWith:f,method:"GET"}]}function p(n){A(n.route);var e=n.resource.url+"/"+n.item.id+n.route;Facade.backend.when(n.method,e).respond(function(e,t,r,u){r=JSON.parse(r||"{}");var o=Facade.findRoute(e,t),i=k(n.resource).find(n.item.id),a=o.getSpecialResponseOr(function(){return n.callback(r,i,u)});return D(a),a})}function h(n){var e=_.isRegExp(n.route)?n.route:n.resource.url+n.route;Facade.backend.when(n.method,e).respond(function(e,t,r){r=JSON.parse(r||"{}");var u=k(n.resource).getAll(),o=Facade.findRoute(e,t),i=o.getSpecialResponseOr(function(){return n.callback(r,u)});return D(i),i})}function d(n){var e=n.resource.url+n.route;console.log("creating expecation"),Facade.backend.expect(n.method,e,m(n.expected)).respond(function(e,t,r){r=JSON.parse(r||"{}");var u=k(n.resource).getAll(),o=Facade.findRoute(e,t);o.hasSpecialResponse()||_.isFunction(n.callback)&&n.callback(r,u);var i=o.getSpecialResponseOr(function(){return[200,JSON.stringify(u),{},"OK"]});return i})}function g(n){if(n.route=n.route||"",_.isRegExp(n.route))n.regExp=n.route;else{var e=n.resource.url,t=n.item?e+"/"+n.item.id+n.route:e+n.route,r=[n.method,t].join(" ");n.fullRoute=r}W[n.resource.name][n.regExp||n.fullRoute]=b(n)}function v(n){z.push(n)}function m(n){function e(t,r,u){if(t[u])return t[u]===r?!0:(console.log("Expected",u,"to equal",r,"in",t,"but it was",t[u]),!1);var o=_.filter(t,function(n){return _.isObject(n)}),i=t[u]===r;return o||i?_.any(o,function(n){return e(n,r,u)}):(console.log("Missing expectedKey",u,"in",nestedData,"should include",n),!1)}return function(t){var r=JSON.parse(t);return r?_.all(n,function(n,t){return e(r,n,t)}):(console.log("Unable to parse to JSON:",t),!1)}}function y(n){return n=n||{},{url:n.url,name:n.name,addItem:function(n){return j(n),k(this).create(n),P&&u(this,n),n},addItems:function(n){N(n),_.each(n,function(n){this.addItem(n)},this)},resource:function(n){return n.url=this.url+n.url,Facade.resource(n)},addRoute:function(n){if(n=n||{},I(n),n.resource=this,v(n),n.onItem){var e=k(this).getAll();_.each(e,function(e){n.item=e,p(n),g(n)})}else h(n),g(n)},expect:function(e,t){T(e),t=t||"";var r=this;return{"with":function(u){n={method:e,route:t,expected:u,resource:r},d(n)}}}}}function b(n){var e=[];return{fullRoute:n.fullRoute,regExp:n.regExp,method:n.method,nextResponse:function(n,t){e.push({status:n,data:t})},getSpecialResponse:function(){return e.shift()},hasSpecialResponse:function(){return Boolean(e.length)},getSpecialResponseOr:function(n){if(this.hasSpecialResponse()){var e=this.getSpecialResponse();return[e.status,JSON.stringify(e.data),{},"OK"] -}return _.isFunction(n)&&n()}}}function w(n){var e={};return{getAll:function(){return _.map(e)},create:function(n){j(n);var t=n.id;e[JSON.stringify(t)]=n},find:function(t,r){R(t),r=r||{};var u=e[JSON.stringify(t)];if(!u)throw new Error("No item found in "+n+" table with id of "+t);return r.wrap?O(u,F(n)):u},"delete":function(t){R(t);var t=JSON.stringify(t),r=e[t];if(!r)throw new Error("No item found in "+n+" table with id of "+t+". So can't delete it.");return e[t]=null,r}}}function k(n){var e=Facade.db[n.name];if(!e)throw new Error("There doesnt appear to be a table called "+n.name);return e}function E(n){return k(n).getAll()}function x(n,e,t){return t=t||{},k(n).find(e,t)}function O(n,e){return n=_.extend({},n),n.showUrl=function(){return e.url+"/"+n.id},n}function F(n){var e=Facade.resources[n];if(!e)throw new Error("There doesnt appear to be a resource called "+n);return e}function S(n){if(!_.isString(n.name))throw new Error("You must provide a name for the resource");if(Facade.resources[n.name])throw new Error("A resource named "+n.name+" already exists. Please choose a different name.");if(!_.isString(n.url))throw new Error("You must provide a url for the "+n.name+" resource");var e=_.pluck(Facade.resources,"url");if(_.find(e,function(e){return e===n.url}))throw new Error("The url "+n.url+" is already taken. Please change one")}function j(n){if(!n.id)throw new Error("The resource must have an id property.")}function R(n){if(!n)throw new Error("You must pass in an id to find a record")}function N(n){if(!_.isArray(n))throw new Error("addItems must take an array")}function T(n){if(!_.isString(n))throw new Error("No HTTP method was provided");var e=["GET","POST","PATCH","PUT","HEAD","DELETE"];if(!_.contains(e,n))throw new Error(n+" is not a valid HTTP method.")}function C(n){if(n=n||{},Facade.backend=Facade.backend||n.backend||{},!_.isFunction(Facade.backend.whenGET))throw new Error("$httpBackend not detected. Either add it as an option when initializing, or set the attribute directly on Facade via Facade.backend = $httpBackend")}function A(n){if(_.isRegExp(n))throw new Error("Regex routes can't be used for item routes. Either make 'onItem' false or make the route a string")}function I(n){if(T(n.method),!_.isString(n.route)&&!_.isRegExp(n.route))throw new Error("You must supply a route (eg: '/my_route') as either a string or regex");if(!n.callback)throw new Error("You must supply a response callback for custom routes.")}function D(n){if(!_.isArray(n))throw new Error("Response must be an array");if(4!==n.length)throw new Error("Response does not appear to be in the form of [status, data, headers, status_text]")}window.Facade={};var J,P=!1;Facade.resources={},Facade.db={};var W={},$={},B={},K={},z=[];Facade.resource=function(n){return n=n||{},S(n),this.db[n.name]=w(n.name),W[n.name]={},this.resources[n.name]=y(n)},Facade.initialize=function(t){C(t),P=!0,_.isFunction(J)&&J(),_.each(this.resources,function(n){e(n)}),n()},Facade.reset=function(){Facade.resources=_.clone($,!0),Facade.db=_.clone(B,!0),W=_.clone(K,!0),P=!1},Facade.define=function(n){J=n},Facade.undefine=function(){J=void 0},Facade.clear=function(){this.resources={},this.db={},W={},z=[],this.backend=void 0,P=!1},Facade.findRoute=function(n,e){var t,r=[n,e].join(" "),u=_.any(W,function(u){return t=u[r],t?t:t=_.chain(u).filter("regExp").where({method:n}).find(function(n){return n.regExp.test(e)}).value()});if(!u)throw new Error("The route "+r+" does not exist");return t}}.call(this); \ No newline at end of file +(function(){function n(n,e,t){t=(t||0)-1;for(var r=n?n.length:0;++ta||"undefined"==typeof i)return 1;if(a>i||"undefined"==typeof a)return-1}}return n.n-e.n}function o(n){var e=-1,r=n.length,u=n[0],o=n[r/2|0],i=n[r-1];if(u&&"object"==typeof u&&o&&"object"==typeof o&&i&&"object"==typeof i)return!1;for(u=c(),u["false"]=u["null"]=u["true"]=u.undefined=!1,o=c(),o.k=n,o.l=u,o.push=t;++et?0:t);++r3&&"function"==typeof i[c-2])var f=ee(i[--c-1],i[c--],2);else c>2&&"function"==typeof i[c-1]&&(f=i[--c]);for(;++a=y&&i===n,f=[];if(c){var s=o(r);s?(i=e,r=s):c=!1}for(;++ui(r,s)&&f.push(s);return c&&l(r),f}function ue(n,e,t,r){r=(r||0)-1;for(var u=n?n.length:0,o=[];++r=y&&c===n,d=u||h?a():p;for(h&&(d=o(d),c=e);++ic(d,v))&&((u||h)&&d.push(v),p.push(g))}return h?(f(d.k),l(d)):u&&f(d),p}function fe(n){return function(e,t,r){var u={};t=M.createCallback(t,r,3),r=-1;var o=e?e.length:0;if("number"==typeof o)for(;++rt?jt(0,o+t):t)||0,Dt(n)?i=-1o&&(o=a)}}else e=null==e&&Ee(n)?r:M.createCallback(e,t,3),Re(n,function(n,t,r){t=e(n,t,r),t>u&&(u=t,o=n)});return o}function Ae(n,e,t,r){if(!n)return t;var u=3>arguments.length;e=M.createCallback(e,r,4);var o=-1,i=n.length;if("number"==typeof i)for(u&&(t=n[++o]);++oarguments.length;return e=M.createCallback(e,r,4),Ne(n,function(n,r,o){t=u?(u=!1,n):e(t,n,r,o)}),t}function De(n){var e=-1,t=n?n.length:0,r=Qe("number"==typeof t?t:0);return Re(n,function(n){var t=ae(0,++e);r[e]=r[t],r[t]=n}),r}function Je(n,e,t){var r;e=M.createCallback(e,t,3),t=-1;var u=n?n.length:0;if("number"==typeof u)for(;++tr?jt(0,u+r):r||0}else if(r)return r=$e(e,t),e[r]===t?r:-1;return n(e,t,r)}function Ke(n,e,t){if("number"!=typeof e&&null!=e){var r=0,u=-1,o=n?n.length:0;for(e=M.createCallback(e,t,3);++uu;)r=u+o>>>1,t(n[r])t?0:t);++e0?l=bt(u,t):(i&&ht(i),t=s,i=l=s=h,t&&(p=Lt(),a=n.apply(f,o),l||i||(o=f=null)))}var o,i,a,c,f,l,s,p=0,d=!1,g=!0;if(!_e(n))throw new it;if(e=jt(0,e)||0,!0===t)var v=!0,g=!1;else we(t)&&(v=t.leading,d="maxWait"in t&&(jt(e,t.maxWait)||0),g="trailing"in t?t.trailing:g);return function(){if(o=arguments,c=Lt(),f=this,s=g&&(l||!v),!1===d)var t=v&&!l;else{i||v||(p=c);var h=d-(c-p),m=0>=h;m?(i&&(i=ht(i)),p=c,a=n.apply(f,o)):i||(i=bt(r,h))}return m&&l?l=ht(l):l||e===d||(l=bt(u,e)),t&&(m=!0,a=n.apply(f,o)),!m||l||i||(o=f=null),a}}function Le(n){return n}function Ue(n,e,t){var r=!0,u=e&&ye(e);e&&(t||u.length)||(null==t&&(t=e),o=V,e=n,n=M,u=ye(e)),!1===t?r=!1:we(t)&&"chain"in t&&(r=t.chain);var o=n,i=_e(o);Re(u,function(t){var u=n[t]=e[t];i&&(o.prototype[t]=function(){var e=this.__chain__,t=this.__wrapped__,i=[t];if(yt.apply(i,arguments),i=u.apply(n,i),r||e){if(t===i&&we(i))return this;i=new o(i),i.__chain__=e}return i})})}function Ye(){}function Me(n){return function(e){return e[n]}}function Ve(){return this.__wrapped__}t=t?X.defaults(U.Object(),t,X.pick(U,C)):U;var Qe=t.Array,Xe=t.Boolean,Ze=t.Date,nt=t.Function,et=t.Math,tt=t.Number,rt=t.Object,ut=t.RegExp,ot=t.String,it=t.TypeError,at=[],ct=rt.prototype,ft=t._,lt=ct.toString,st=ut("^"+ot(lt).replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/toString| for [^\]]+/g,".*?")+"$"),pt=et.ceil,ht=t.clearTimeout,dt=et.floor,gt=nt.prototype.toString,vt=he(vt=rt.getPrototypeOf)&&vt,mt=ct.hasOwnProperty,yt=at.push,bt=t.setTimeout,_t=at.splice,wt=at.unshift,kt=function(){try{var n={},e=he(e=rt.defineProperty)&&e,t=e(n,n,n)&&e}catch(r){}return t}(),Et=he(Et=rt.create)&&Et,Ot=he(Ot=Qe.isArray)&&Ot,xt=t.isFinite,Ft=t.isNaN,St=he(St=rt.keys)&&St,jt=et.max,Rt=et.min,Nt=t.parseInt,Tt=et.random,Ct={};Ct[I]=Qe,Ct[D]=Xe,Ct[J]=Ze,Ct[P]=nt,Ct[K]=rt,Ct[W]=tt,Ct[$]=ut,Ct[B]=ot,V.prototype=M.prototype;var At=M.support={};At.funcDecomp=!he(t.a)&&N.test(p),At.funcNames="string"==typeof nt.name,M.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:S,variable:"",imports:{_:M}},Et||(ne=function(){function n(){}return function(e){if(we(e)){n.prototype=e;var r=new n;n.prototype=null}return r||t.Object()}}());var It=kt?function(n,e){G.value=e,kt(n,"__bindData__",G)}:Ye,Dt=Ot||function(n){return n&&"object"==typeof n&&"number"==typeof n.length&<.call(n)==I||!1},Jt=St?function(n){return we(n)?St(n):[]}:Y,Pt={"&":"&","<":"<",">":">",'"':""","'":"'"},Wt=be(Pt),Kt=ut("("+Jt(Wt).join("|")+")","g"),$t=ut("["+Jt(Pt).join("")+"]","g"),Bt=vt?function(n){if(!n||lt.call(n)!=K)return!1;var e=n.valueOf,t=he(e)&&(t=vt(e))&&vt(t);return t?n==t||vt(n)==t:de(n)}:de,zt=fe(function(n,e,t){mt.call(n,t)?n[t]++:n[t]=1}),qt=fe(function(n,e,t){(mt.call(n,t)?n[t]:n[t]=[]).push(e)}),Gt=fe(function(n,e,t){n[t]=e}),Ht=Te,Lt=he(Lt=Ze.now)&&Lt||function(){return(new Ze).getTime()},Ut=8==Nt(_+"08")?Nt:function(n,e){return Nt(Ee(n)?n.replace(j,""):n,e||0)};return M.after=function(n,e){if(!_e(e))throw new it;return function(){return 1>--n?e.apply(this,arguments):void 0}},M.assign=L,M.at=function(n){for(var e=arguments,t=-1,r=ue(e,!0,!1,1),e=e[2]&&e[2][e[1]]===n?1:r.length,u=Qe(e);++t=y&&o(r?t[r]:p)))}var s=t[0],d=-1,g=s?s.length:0,v=[];n:for(;++d(m?e(m,h):c(p,h))){for(r=u,(m||p).push(h);--r;)if(m=i[r],0>(m?e(m,h):c(t[r],h)))continue n;v.push(h)}}for(;u--;)(m=i[u])&&l(m);return f(i),f(p),v},M.invert=be,M.invoke=function(n,e){var t=s(arguments,2),r=-1,u="function"==typeof e,o=n?n.length:0,i=Qe("number"==typeof o?o:0);return Re(n,function(n){i[++r]=(u?e:n[e]).apply(n,t)}),i},M.keys=Jt,M.map=Te,M.mapValues=function(n,e,t){var r={};return e=M.createCallback(e,t,3),d(n,function(n,t,u){r[t]=e(n,t,u)}),r},M.max=Ce,M.memoize=function(n,e){function t(){var r=t.cache,u=e?e.apply(this,arguments):m+arguments[0];return mt.call(r,u)?r[u]:r[u]=n.apply(this,arguments)}if(!_e(n))throw new it;return t.cache={},t},M.merge=function(n){var e=arguments,t=2;if(!we(n))return n;if("number"!=typeof e[2]&&(t=e.length),t>3&&"function"==typeof e[t-2])var r=ee(e[--t-1],e[t--],2);else t>2&&"function"==typeof e[t-1]&&(r=e[--t]);for(var e=s(arguments,1,t),u=-1,o=a(),i=a();++ua&&(o=a)}}else e=null==e&&Ee(n)?r:M.createCallback(e,t,3),Re(n,function(n,t,r){t=e(n,t,r),u>t&&(u=t,o=n)});return o},M.omit=function(n,e,t){var r={};if("function"!=typeof e){var u=[];g(n,function(n,e){u.push(e)});for(var u=re(u,ue(arguments,!0,!1,1)),o=-1,i=u.length;++ot?jt(0,r+t):Rt(t,r-1))+1);r--;)if(n[r]===e)return r;return-1},M.mixin=Ue,M.noConflict=function(){return t._=ft,this},M.noop=Ye,M.now=Lt,M.parseInt=Ut,M.random=function(n,e,t){var r=null==n,u=null==e;return null==t&&("boolean"==typeof n&&u?(t=n,n=1):u||"boolean"!=typeof e||(t=e,u=!0)),r&&u&&(e=1),n=+n||0,u?(e=n,n=0):e=+e||0,t||n%1||e%1?(t=Tt(),Rt(n+t*(e-n+parseFloat("1e-"+((t+"").length-1))),e)):ae(n,e)},M.reduce=Ae,M.reduceRight=Ie,M.result=function(n,e){if(n){var t=n[e];return _e(t)?n[e]():t}},M.runInContext=p,M.size=function(n){var e=n?n.length:0;return"number"==typeof e?e:Jt(n).length},M.some=Je,M.sortedIndex=$e,M.template=function(n,e,t){var r=M.templateSettings;n=ot(n||""),t=b({},t,r);var u,o=b({},t.imports,r.imports),r=Jt(o),o=Oe(o),a=0,c=t.interpolate||R,f="__p+='",c=ut((t.escape||R).source+"|"+c.source+"|"+(c===S?O:R).source+"|"+(t.evaluate||R).source+"|$","g");n.replace(c,function(e,t,r,o,c,l){return r||(r=o),f+=n.slice(a,l).replace(T,i),t&&(f+="'+__e("+t+")+'"),c&&(u=!0,f+="';"+c+";\n__p+='"),r&&(f+="'+((__t=("+r+"))==null?'':__t)+'"),a=l+e.length,e}),f+="';",c=t=t.variable,c||(t="obj",f="with("+t+"){"+f+"}"),f=(u?f.replace(w,""):f).replace(k,"$1").replace(E,"$1;"),f="function("+t+"){"+(c?"":t+"||("+t+"={});")+"var __t,__p='',__e=_.escape"+(u?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+f+"return __p}";try{var l=nt(r,"return "+f).apply(h,o)}catch(s){throw s.source=f,s}return e?l(e):(l.source=f,l)},M.unescape=function(n){return null==n?"":ot(n).replace(Kt,ge)},M.uniqueId=function(n){var e=++v;return ot(null==n?"":n)+e},M.all=Fe,M.any=Je,M.detect=je,M.findWhere=je,M.foldl=Ae,M.foldr=Ie,M.include=xe,M.inject=Ae,Ue(function(){var n={};return d(M,function(e,t){M.prototype[t]||(n[t]=e)}),n}(),!1),M.first=Pe,M.last=function(n,e,t){var r=0,u=n?n.length:0;if("number"!=typeof e&&null!=e){var o=u;for(e=M.createCallback(e,t,3);o--&&e(n[o],o,n);)r++}else if(r=e,null==r||t)return n?n[u-1]:h;return s(n,jt(0,u-r))},M.sample=function(n,e,t){return n&&"number"!=typeof n.length&&(n=Oe(n)),null==e||t?n?n[ae(0,n.length-1)]:h:(n=De(n),n.length=Rt(jt(0,e),n.length),n)},M.take=Pe,M.head=Pe,d(M,function(n,e){var t="sample"!==e;M.prototype[e]||(M.prototype[e]=function(e,r){var u=this.__chain__,o=n(this.__wrapped__,e,r);return u||null!=e&&(!r||t&&"function"==typeof e)?new V(o,u):o})}),M.VERSION="2.4.1",M.prototype.chain=function(){return this.__chain__=!0,this},M.prototype.toString=function(){return ot(this.__wrapped__)},M.prototype.value=Ve,M.prototype.valueOf=Ve,Re(["join","pop","shift"],function(n){var e=at[n];M.prototype[n]=function(){var n=this.__chain__,t=e.apply(this.__wrapped__,arguments);return n?new V(t,n):t}}),Re(["push","reverse","sort","unshift"],function(n){var e=at[n];M.prototype[n]=function(){return e.apply(this.__wrapped__,arguments),this}}),Re(["concat","slice","splice"],function(n){var e=at[n];M.prototype[n]=function(){return new V(e.apply(this.__wrapped__,arguments),this.__chain__)}}),M}var h,d=[],g=[],v=0,m=+new Date+"",y=75,b=40,_=" \f \n\r\u2028\u2029 ᠎              ",w=/\b__p\+='';/g,k=/\b(__p\+=)''\+/g,E=/(__e\(.*?\)|\b__t\))\+'';/g,O=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,x=/\w*$/,F=/^\s*function[ \n\r\t]+\w/,S=/<%=([\s\S]+?)%>/g,j=RegExp("^["+_+"]*0+(?=.$)"),R=/($^)/,N=/\bthis\b/,T=/['\n\r\t\u2028\u2029\\]/g,C="Array Boolean Date Function Math Number Object RegExp String _ attachEvent clearTimeout isFinite isNaN parseInt setTimeout".split(" "),A="[object Arguments]",I="[object Array]",D="[object Boolean]",J="[object Date]",P="[object Function]",W="[object Number]",K="[object Object]",$="[object RegExp]",B="[object String]",z={};z[P]=!1,z[A]=z[I]=z[D]=z[J]=z[W]=z[K]=z[$]=z[B]=!0;var q={leading:!1,maxWait:0,trailing:!1},G={configurable:!1,enumerable:!1,value:null,writable:!1},H={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},L={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"},U=H[typeof window]&&window||this,Y=H[typeof exports]&&exports&&!exports.nodeType&&exports,M=H[typeof module]&&module&&!module.nodeType&&module,V=M&&M.exports===Y&&Y,Q=H[typeof global]&&global;!Q||Q.global!==Q&&Q.window!==Q||(U=Q);var X=p();"function"==typeof define&&"object"==typeof define.amd&&define.amd?(U._=X,define(function(){return X})):Y&&M?V?(M.exports=X)._=X:Y._=X:U._=X}).call(this),function(){"use strict";function n(){$=_.clone(Facade.resources,!0),B=_.clone(Facade.db,!0),z=_.clone(K,!0)}function e(n){t(n),r(n)}function t(n){_.each(p(),function(e){var t={resource:n,method:e.method};e.createWith(t),v(t)})}function r(n){var e=O(n);_.each(e,function(e){u(n,e)})}function u(n,e){_.each(s(),function(t){var r={resource:n,item:e,method:t.method};t.createWith(r),v(r)}),_.each(q,function(n){n.onItem&&(n.item=e,h(n),v(n))})}function o(n){Facade.backend.whenGET(n.resource.url+"/"+n.item.id).respond(function(e,t){var r=Facade.findRoute(e,t),u=r.getSpecialResponseOr(function(){var e=x(n.resource,n.item.id);return[200,JSON.stringify(e),{},"OK"]});return u})}function i(n){Facade.backend.whenPUT(n.resource.url+"/"+n.item.id).respond(function(e,t,r,u){r=r||{};var o=Facade.findRoute(e,t),i=o.getSpecialResponseOr(function(){var e=x(n.resource,n.item.id);return _.assign(e,JSON.parse(r)),[200,JSON.stringify(e),u,"OK"]});return i})}function a(n){Facade.backend.whenPATCH(n.resource.url+"/"+n.item.id).respond(function(e,t,r,u){r=r||{};var o=Facade.findRoute(e,t),i=o.getSpecialResponseOr(function(){var e=x(n.resource,n.item.id);return _.assign(e,JSON.parse(r)),[200,JSON.stringify(e),u,"OK"]});return i})}function c(n){Facade.backend.whenDELETE(n.resource.url+"/"+n.item.id).respond(function(e,t,r){r=r||{};var u=Facade.findRoute(e,t),o=u.getSpecialResponseOr(function(){var e=E(n.resource).delete(n.item.id);return[200,JSON.stringify(e),{},"OK"]});return o})}function f(n){Facade.backend.whenPOST(n.resource.url).respond(function(e,t,r){r=r||{},r=JSON.parse(r);var u=Facade.findRoute(e,t),o=u.getSpecialResponseOr(function(){var e=_.isFunction(n.resource.createDefault)&&n.resource.createDefault(r);return e=e||r,n.resource.addItem(e),[200,JSON.stringify(e),{},"OK"]});return o})}function l(n){Facade.backend.whenGET(n.resource.url).respond(function(e,t){var r=Facade.findRoute(e,t),u=r.getSpecialResponseOr(function(){return[200,O(n.resource),{},"OK"]});return u})}function s(){return[{createWith:o,method:"GET"},{createWith:i,method:"PUT"},{createWith:a,method:"PATCH"},{createWith:c,method:"DELETE"}]}function p(){return[{createWith:f,method:"POST"},{createWith:l,method:"GET"}]}function h(n){I(n.route);var e=n.resource.url+"/"+n.item.id+n.route;Facade.backend.when(n.method,e).respond(function(e,t,r,u){r=JSON.parse(r||"{}");var o=Facade.findRoute(e,t),i=E(n.resource).find(n.item.id),a=o.getSpecialResponseOr(function(){return n.callback(r,i,u)});return J(a),a})}function d(n){var e=_.isRegExp(n.route)?n.route:n.resource.url+n.route;Facade.backend.when(n.method,e).respond(function(e,t,r){r=JSON.parse(r||"{}");var u=E(n.resource).getAll(),o=Facade.findRoute(e,t),i=o.getSpecialResponseOr(function(){return n.callback(r,u)});return J(i),i})}function g(n){var e=n.resource.url+n.route;Facade.backend.expect(n.method,e,y(n.expected)).respond(function(e,t,r){r=JSON.parse(r||"{}");var u=E(n.resource).getAll(),o=Facade.findRoute(e,t);o.hasSpecialResponse()||_.isFunction(n.callback)&&n.callback(r,u);var i=o.getSpecialResponseOr(function(){return[200,JSON.stringify(u),{},"OK"]});return i})}function v(n){if(n.route=n.route||"",_.isRegExp(n.route))n.regExp=n.route;else{var e=n.resource.url,t=n.item?e+"/"+n.item.id+n.route:e+n.route,r=[n.method,t].join(" ");n.fullRoute=r}K[n.resource.name][n.regExp||n.fullRoute]=w(n)}function m(n){q.push(n)}function y(n){function e(t,r,u){if(t[u])return t[u]===r?!0:(console.log("Expected",u,"to equal",r,"in",t,"but it was",t[u]),!1);var o=_.filter(t,function(n){return _.isObject(n)}),i=t[u]===r;return o||i?_.any(o,function(n){return e(n,r,u)}):(console.log("Missing expectedKey",u,"in",nestedData,"should include",n),!1)}return function(t){var r=JSON.parse(t);return r?_.all(n,function(n,t){return e(r,n,t)}):(console.log("Unable to parse to JSON:",t),!1)}}function b(n){return n=n||{},{url:n.url,name:n.name,addItem:function(n){return R(n),E(this).create(n),W&&u(this,n),n},addItems:function(n){T(n),_.each(n,function(n){this.addItem(n)},this)},resource:function(n){return n.url=this.url+n.url,Facade.resource(n)},addRoute:function(n){if(n=n||{},D(n),n.resource=this,m(n),n.onItem){var e=E(this).getAll();_.each(e,function(e){n.item=e,h(n),v(n)})}else d(n),v(n)},expect:function(e,t){C(e),t=t||"";var r=this;return{"with":function(u){n={method:e,route:t,expected:u,resource:r},g(n)}}}}}function w(n){var e=[];return{fullRoute:n.fullRoute,regExp:n.regExp,method:n.method,nextResponse:function(n,t){e.push({status:n,data:t}) +},getSpecialResponse:function(){return e.shift()},hasSpecialResponse:function(){return Boolean(e.length)},getSpecialResponseOr:function(n){if(this.hasSpecialResponse()){var e=this.getSpecialResponse();return[e.status,JSON.stringify(e.data),{},"OK"]}return _.isFunction(n)&&n()}}}function k(n){var e={};return{getAll:function(){return _.map(e)},create:function(n){R(n);var t=n.id;e[JSON.stringify(t)]=n},find:function(t,r){N(t),r=r||{};var u=e[JSON.stringify(t)];if(!u)throw new Error("No item found in "+n+" table with id of "+t);return r.wrap?F(u,S(n)):u},"delete":function(t){N(t);var t=JSON.stringify(t),r=e[t];if(!r)throw new Error("No item found in "+n+" table with id of "+t+". So can't delete it.");return e[t]=null,r}}}function E(n){var e=Facade.db[n.name];if(!e)throw new Error("There doesnt appear to be a table called "+n.name);return e}function O(n){return E(n).getAll()}function x(n,e,t){return t=t||{},E(n).find(e,t)}function F(n,e){return n=_.extend({},n),n.showUrl=function(){return e.url+"/"+n.id},n}function S(n){var e=Facade.resources[n];if(!e)throw new Error("There doesnt appear to be a resource called "+n);return e}function j(n){if(!_.isString(n.name))throw new Error("You must provide a name for the resource");if(Facade.resources[n.name])throw new Error("A resource named "+n.name+" already exists. Please choose a different name.");if(!_.isString(n.url))throw new Error("You must provide a url for the "+n.name+" resource");var e=_.pluck(Facade.resources,"url");if(_.find(e,function(e){return e===n.url}))throw new Error("The url "+n.url+" is already taken. Please change one")}function R(n){if(!n.id)throw new Error("The resource must have an id property.")}function N(n){if(!n)throw new Error("You must pass in an id to find a record")}function T(n){if(!_.isArray(n))throw new Error("addItems must take an array")}function C(n){if(!_.isString(n))throw new Error("No HTTP method was provided");var e=["GET","POST","PATCH","PUT","HEAD","DELETE"];if(!_.contains(e,n))throw new Error(n+" is not a valid HTTP method.")}function A(n){if(n=n||{},Facade.backend=Facade.backend||n.backend||{},!_.isFunction(Facade.backend.whenGET))throw new Error("$httpBackend not detected. Either add it as an option when initializing, or set the attribute directly on Facade via Facade.backend = $httpBackend")}function I(n){if(_.isRegExp(n))throw new Error("Regex routes can't be used for item routes. Either make 'onItem' false or make the route a string")}function D(n){if(C(n.method),!_.isString(n.route)&&!_.isRegExp(n.route))throw new Error("You must supply a route (eg: '/my_route') as either a string or regex");if(!n.callback)throw new Error("You must supply a response callback for custom routes.")}function J(n){if(!_.isArray(n))throw new Error("Response must be an array");if(4!==n.length)throw new Error("Response does not appear to be in the form of [status, data, headers, status_text]")}window.Facade={};var P,W=!1;Facade.resources={},Facade.db={};var K={},$={},B={},z={},q=[];Facade.resource=function(n){return n=n||{},j(n),this.db[n.name]=k(n.name),K[n.name]={},this.resources[n.name]=b(n)},Facade.initialize=function(t){A(t),W=!0,_.isFunction(P)&&P(),_.each(this.resources,function(n){e(n)}),n()},Facade.reset=function(){Facade.resources=_.clone($,!0),Facade.db=_.clone(B,!0),K=_.clone(z,!0),W=!1},Facade.define=function(n){P=n},Facade.undefine=function(){P=void 0},Facade.clear=function(){this.resources={},this.db={},K={},q=[],this.backend=void 0,W=!1},Facade.findRoute=function(n,e){var t,r=[n,e].join(" "),u=_.any(K,function(u){return t=u[r],t?t:t=_.chain(u).filter("regExp").where({method:n}).find(function(n){return n.regExp.test(e)}).value()});if(!u)throw new Error("The route "+r+" does not exist");return t}}.call(this); \ No newline at end of file diff --git a/src/facade.js b/src/facade.js index e746c40..4f7f52e 100644 --- a/src/facade.js +++ b/src/facade.js @@ -165,6 +165,23 @@ }); } + function createPatchRoute(opts) { + var headers = {}; + Facade.backend.whenPATCH(opts.resource.url + '/' + opts.item.id) + .respond(function(method, url, data, headers) { + data = data || {}; + var route = Facade.findRoute(method, url); + var response = route.getSpecialResponseOr(function() { + var item = getOneItem(opts.resource, opts.item.id); + // Perform the patch on the db object + _.assign(item, JSON.parse(data)); + return [200, JSON.stringify(item), headers, 'OK'] + }) + + return response; + }); + } + function createDeleteRoute(opts) { var headers = {}; @@ -222,6 +239,7 @@ return [ {createWith: createItemIdRoute, method: 'GET'}, {createWith: createPutRoute, method: 'PUT'}, + {createWith: createPatchRoute, method: 'PATCH'}, {createWith: createDeleteRoute, method: 'DELETE'} ]; } @@ -269,7 +287,6 @@ function createExpectationFor(opts) { var fullUrl = opts.resource.url + opts.route; - console.log('creating expecation'); Facade.backend.expect(opts.method, fullUrl, withJSON(opts.expected)) .respond(function(method, url, requestData, headers) { requestData = JSON.parse(requestData || "{}");