UNPKG

node-controller

Version:

A lightweight, single-file Controller approach for node/express.

36 lines 4.73 kB
/*! * 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;