var specificity = require('route-order')(); var slash = require('express-slash'); function OKServer(options) { if (!(this instanceof OKServer)) return new OKServer(options); options = options || {}; if (!options.express) throw new Error('No Express provided to OKServer'); if (!options.app) throw new Error('No Express app provided to OKServer') if (!options.views) throw new Error('No views provided to OKServer'); if (!options.root) throw new Error('No app root directory provided to OKServer'); if (!options.adminRoot) throw new Error('No admin root directory provided to OKServer'); if (!options.adminPath) throw new Error('No admin path provided to OKServer'); if (!options.errorHandler) throw new Error('No error handler provided to OKServer'); var root = options.root; var adminRoot = options.adminRoot; var adminPath = options.adminPath; var views = options.views; var express = options.express; var app = this._app = options.app; var router = express.Router({ strict: app.get('strict routing') }); var error = options.errorHandler; var services = options.services || {}; Object.keys(views) // Sort such that more general routes are matched last .sort(specificity) // Add the views .forEach(function(route) { var view = views[route]; var mount = view.mount; if (!mount) throw Error('View doesn\'t specify a mount point'); var handler = view.middleware(); if (!handler) throw new Error('View doesn\'t provide middleware'); router[mount](route, handler); }); /** * Mount our middleware. * Order is important here! Requests go down the middleware * chain until they are handled with a response, which could * happen anywhere in the chain. Watch out for middleware shadowing * other middleware. */ // Disable silly express header app.disable('x-powered-by') // Serve user static files app.use(express.static(root)); // Serve admin interface static files app.use(adminPath, express.static(adminRoot)); // Application router app.use(router); // Add services if (services.s3) { app.use('/_services/s3', services.s3.middleware()); } if (services.twitter) { app.use('/_services/twitter', services.twitter.middleware()) } // Make sure this lady is last. Checks whether the desired // route has a trailing-slash counterpart and redirects there app.use(slash()); // Otherwise it's a 404 app.use(function(req, res) { error(req, res, 404)(new Error('No matching route')); }); } OKServer.prototype.listen = function listen(port) { this._app.listen(port || 1337); return this; }; module.exports = OKServer;