node-controller
Version:
A lightweight, single-file Controller approach for node/express.
36 lines • 4.73 kB
JavaScript
/*!
* node-controller module v0.2.13
* https://github.com/riga/node-controller
*
* Marcel Rieger, 2014
* Dual licensed under the MIT or GPL Version 3 licenses.
* http://www.opensource.org/licenses/mit-license
* http://www.opensource.org/licenses/GPL-3.0
*
* A lightweight, single-file Controller approach for node/express.
*/
var util=require("util"),domain=require("domain"),events=require("events");
var Class=require("node-oo");var defaultConfig={base:"/",index:"index",scheme:"_%s_",caseSensitive:true,exactParameters:true};var multiRe=/\/{2,}/g;var Emitter=Class._convert(events.EventEmitter,"__emitter");
var Controller=Emitter._extend({init:function(b,a){this._super();this.parent=b||"root";this.config=util._extend(util._extend({},defaultConfig),a);this.config.base="/"+this._class.cutSlashes(this.config.base)+"/";
this.config.base=this.config.base.replace(multiRe,"/");this.__parMap={};},findRoot:function(){var a=this.parent;while(a instanceof Controller){a=a.parent;
}return a;},isRoot:function(){return this.findRoot()==this.parent;},bind:function(a){a.use(this.middleware());return this;},middleware:function(){var a=this;
base=this.config.base;var b=new RegExp("^"+this._class.cutTrainlingSlash(base)+"(|/|/.+)$");return function(e,c,d){if(!a.config.caseSensitive){e.url=e._parsedUrl.pathname.toLowerCase()+(e._parsedUrl.search||"");
}if(b.test(e.url)){e.url=a._class.shiftUrl(e.url,base);a.__dispatch(e,c,d);}else{d();}};},__dispatch:function(g,c,f){var b=this;var a=this._class.firstRoute(g.url)||this.config.index;
var e=this.__handler(a);if(this[a] instanceof Controller){g.url=this._class.shiftUrl(g.url);this[a].__dispatch(g,c,f);}else{if(this[e] instanceof Function&&this.__parse(g,c,a,e)){var h=domain.create();
h.on("error",function(d){if(c.finished){return;}if(typeof(d)=="number"){c.send(d);}else{if(!(d instanceof Error)&&d instanceof Object&&d.status&&d.err){c.send(d.status,d.err);
}else{c.send(500);throw d;}}});h.add(g);h.add(c);this.removeAllListeners("error");this.once("error",h.emit.bind(h,"error"));h.run(function(){try{b[e](g,c);
}catch(d){h.emit("error",d);}});}else{f();}}return this;},__handler:function(a){return util.format(this.config.scheme,a);},__parse:function(f,d,b,e){var c=this._class.cutQuery(this._class.cutSlashes(f.url));
f.params=f.params||{};var a=this.__parMap[b];if(c!=b&&a){var g=this._class.cutSlashes(this._class.shiftUrl(c,b)).split("/");if(this.config.exactParameters&&g.length!=a.length){return false;
}g.forEach(function(j,h){f.params[a[h]||h]=j;});}return this;},setParameters:function(b,c){var a=this;if(b instanceof Object&&c==null){Object.keys(b).forEach(function(d){a.setParameters(d,b[d]);
});return this;}if(!this[this.__handler(b)]||!c){return this;}if(!(c instanceof Array)){c=[c];}this.__parMap[b]=c;return this;},join:function(){var b=Array.prototype.slice.call(arguments);
b.unshift(this.config.base);var a=b.join("/").replace(multiRe,"/");return"/"+this._class.cutSlashes(a);},restrictMethod:function(c,b,a,d){if(!(a instanceof Array)){a=[a];
}if(~a.indexOf(c.method)){if(d instanceof Function){d(c,b,a);}throw 405;}return this;},requireMethod:function(c,b,a,d){if(!(a instanceof Array)){a=[a];
}if(!~a.indexOf(c.method)){if(d instanceof Function){d(c,b,a);}throw 405;}return this;},requireOPTIONS:function(b,a,c){return this.requireMethod(b,a,["OPTIONS"],c);
},requireGET:function(b,a,c){return this.requireMethod(b,a,["GET"],c);},requireHEAD:function(b,a,c){return this.requireMethod(b,a,["HEAD"],c);},requirePOST:function(b,a,c){return this.requireMethod(b,a,["POST"],c);
},requirePUT:function(b,a,c){return this.requireMethod(b,a,["PUT"],c);},requireDELETE:function(b,a,c){return this.requireMethod(b,a,["DELETE"],c);},requireTRACE:function(b,a,c){return this.requireMethod(b,a,["TRACE"],c);
},requireCONNECT:function(b,a,c){return this.requireMethod(b,a,["CONNECT"],c);},requireParam:function(d,b,a,c){c=c||400;var e=d.param(b);if(e==null&&a===undefined){throw c;
}else{return e!=null?e:a;}},requireParams:function(d,c,e,b){b=b||400;var a={};c.forEach(function(f){var g=d.param(f);if(g==null&&!(f in e)){throw b;}else{a[f]=g!=null?g:e[f];
}});return a;}},{firstRoute:function(a){a=this.cutQuery(a);return this.cutLeadingSlash(a).split("/")[0];},shiftUrl:function(b,a){a=a==null?this.firstRoute(b):this.cutSlashes(a);
if(a){b=this.cutLeadingSlash(b);if(b.substr(0,a.length)==a){b=b.slice(a.length);}}return"/"+this.cutLeadingSlash(b);},cutTrainlingSlash:function(a){if(a[a.length-1]=="/"){a=a.slice(0,-1);
}return a;},cutLeadingSlash:function(a){if(a[0]=="/"){a=a.slice(1);}return a;},cutSlashes:function(a){return this.cutTrainlingSlash(this.cutLeadingSlash(a));
},cutQuery:function(a){return a.split("?")[0];}});module.exports=Controller;