UNPKG

mixdown-router

Version:
131 lines (95 loc) 3.63 kB
var _ = require('lodash'); var verbs = ['get', 'post', 'put', 'delete']; var non_manifest_properties = ['browser_handler', 'dir_path']; var manifest_properties = ['authenticate', 'authorize', 'name', 'path', 'timeout', 'description', 'params', 'browser', 'cache_buster', 'session', 'protocol', 'port', 'hostname']; var controller_properties = non_manifest_properties.concat(verbs.concat(manifest_properties)); var parse_params = require('./parse_params.js'); var Controller = function (rawController) { if (!(this instanceof Controller)) { return new Controller(rawController); } // apply properties from raw controller export. _.extend(this, _.pick(rawController, controller_properties)); this.path = this.path || '/'; this.timeout = this.timeout || 120000; // node.js default var self = this; // parse and attach urlformat restHash = {}; this.queryParams = {}; _.each(this.params, function (p, name) { p.name = name; //set this so it is accessible inside the param spec. if (p.kind === 'rest') { restHash[name] = p; } else if (p.kind === 'query') { p.regex = new RegExp(p.regex); self.queryParams[name] = p; } }); // ensure starts with slash. if (this.path[0] !== '/') { this.path = '/' + this.path; } var parsed_params = parse_params(this.path, restHash); this.urlformat = parsed_params.urlformat; this.restParams = parsed_params.restParams; }; Controller.prototype.evaluate = function (strUrl) { return this.urlformat.test(strUrl); }; Controller.prototype.parse_url = function (url_object) { var params = {}; // validate and attach blessed query params. Non-declared will still exist on url_object. _.each(this.queryParams, function (p, name) { if (typeof (url_object.query[name]) !== 'undefined' && p.regex.test(url_object.query[name])) { params[name] = url_object.query[name]; } else if (p['default']) { params[name] = p['default']; } }); var urlParams = url_object.pathname.split('/'); if (urlParams[0] === "") { urlParams.splice(0, 1); } // validate and attach rest params. _.each(this.restParams, function (pmap, i) { var param = urlParams[i]; if (param && pmap) { var m = pmap.regex.exec(param); if (m) { params[pmap.name] = decodeURIComponent(_.last(m)); } } }); // return context. return params; }; Controller.prototype.parse = function (httpContext) { // return context. httpContext.params = this.parse_url(httpContext.url); return httpContext; }; Controller.prototype.manifest = function () { var self = this; var manifest_entry = _.pick(this, manifest_properties); // return boolean noting whether this supports each verb. _.each(verbs, function (v) { manifest_entry[v] = self.hasOwnProperty(v); }); manifest_entry.browser = (typeof (this.browser_handler) === 'function'); return manifest_entry; }; Controller.prototype.handle = function (httpContext) { var method = httpContext.request.method.toLowerCase(); // if browser, then handle if (typeof (window) !== 'undefined' && this.browser) { this.browser_handler.call(httpContext.app, httpContext) } else if (typeof (window) !== 'undefined' && window.location.href !== httpContext.request.url) { window.location.href = httpContext.request.url; } else if (typeof (this[method]) === 'function') { this[method].call(httpContext.app, httpContext); } else { throw new Error(this.name + ' Controller does not support http verb ' + method.toUpperCase()); } return httpContext; }; module.exports = Controller;