UNPKG

dotnode

Version:

.NET-like MVC framework for Node.js

191 lines (122 loc) 5.87 kB
var BaseController = require('../controllers/controller'), ControllerFactory = require('../controllers/controllerFactory'), Injector = require('../ioc/injector'), url = require('url'), extend = require('xtend'); var Router = function (expressApp, mvcAppContext) { this._app = expressApp; this._appContext = mvcAppContext; this._controllerFactory = new ControllerFactory(mvcAppContext); this._injector = new Injector(); this._controllersFolder = mvcAppContext.appConfig && mvcAppContext.appConfig.controllersFolder ? mvcAppContext.appConfig.controllersFolder : 'controllers'; }; Router.prototype._defaultRouteHandler = function (routeOptions, request, response, next) { var queryStringParams = url.parse(request.url, true).query, routeParams = request.params; var actionName = routeOptions.defaults ? routeOptions.defaults.action : null, controllerName = routeOptions.defaults ? routeOptions.defaults.controller : null, areaName = ''; if (typeof routeOptions.handler == 'function') { if (!routeOptions.methods || routeOptions.methods.indexOf(request.method) != -1) { return routeOptions.handler(request, response, next); } } if (typeof routeOptions.routeValues.controller == 'string') { var isVariable = this._paramIsVariable(routeOptions.routeValues.controller); var controllerProp = isVariable ? this._unwrapParam(routeOptions.routeValues.controller) : routeOptions.routeValues.controller; controllerName = isVariable ? routeParams[controllerProp] : routeOptions.routeValues.controller; } if (typeof routeOptions.routeValues.action == 'string') { var isVariable = this._paramIsVariable(routeOptions.routeValues.action); var actionProp = isVariable ? this._unwrapParam(routeOptions.routeValues.action) : routeOptions.routeValues.action; actionName = isVariable ? routeParams[actionProp] : routeOptions.routeValues.action; } if (typeof routeParams.area == 'string') { var areaProp = this._paramIsVariable(routeOptions.routeValues.area) ? this._unwrapParam(routeOptions.routeValues.area) : routeOptions.routeValues.area; areaName = routeParams[areaProp]; } var inferredParams = routeOptions.defaults && routeOptions.defaults.params ? routeOptions.defaults.params : {}; if (routeOptions.routeValues && routeOptions.routeValues.params) { for (var prop in routeOptions.routeValues.params) { if (routeOptions.routeValues.params.hasOwnProperty(prop)) { var param = routeOptions.routeValues.params[prop]; if (this._paramIsVariable(param)) { var paramProp = this._unwrapParam(param); inferredParams[prop] = routeParams[paramProp]; } else { inferredParams[prop] = param; } } } } if (!this._controllerFactory.controllerIsRegistered(controllerName)) { var areaPrefix = typeof areaName == 'string' && areaName !== '' ? 'areas/' + areaName + '/' : ''; var relativePath = areaPrefix + this._controllersFolder + '/' + controllerName; var controllerPath = '../../' + relativePath; var bindings = this._appContext.bindings.getBindings(); if (bindings) { this._injector.registerBindings(this._appContext.bindings); } if (bindings && bindings[relativePath]) { var AugmentedController = this._injector.create(relativePath); this._controllerFactory.registerController(controllerName, AugmentedController); } else { var Controller = require(controllerPath); this._controllerFactory.registerController(controllerName, Controller); } } var params = extend(inferredParams, queryStringParams); var requestMethod = request.method; var verbs = routeOptions.methods || this._controllerFactory.getVerbs(actionName, controllerName); if (verbs.indexOf(requestMethod) != -1) { var invokeOptions = { actionName: actionName, controllerName: controllerName, areaName: areaName, request: request, response: response, params: params }; return this._controllerFactory.invoke(invokeOptions); } else { response.writeHead(404, { 'Content-Type': 'text/html' }); response.end('not found :\'('); } }; Router.prototype._getRouteOptions = function (routeString) { }; Router.prototype._paramIsVariable = function (param) { return param.indexOf(':') === 0; }; Router.prototype._wrapParam = function (param) { return ':' + param; }; Router.prototype._unwrapParam = function (param) { return param.replace(':', ''); }; // #region public methods Router.prototype.registerRoutes = function (routeTable) { this._routeTable = routeTable; var routes = this._routeTable.getRoutes(); for (var i in routes) { var routeOptions = routes[i]; this._app.all(routeOptions.route, this._defaultRouteHandler.bind(this, routeOptions)); } }; Router.prototype.getRoutes = function () { this._routeTable.getRoutes(); }; // #endregion module.exports = Router;