From af3e64e0562b98eda87ed54fc061a07d57a125b5 Mon Sep 17 00:00:00 2001 From: analog-nico Date: Fri, 18 Sep 2015 16:21:52 +0200 Subject: [PATCH] Refactoring for cleaner middleware integration, added beforeAll hook --- lib/index.js | 130 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 86 insertions(+), 44 deletions(-) diff --git a/lib/index.js b/lib/index.js index 5ae1ce0..f09e09c 100644 --- a/lib/index.js +++ b/lib/index.js @@ -77,6 +77,10 @@ module.exports = function initServeSpa(app, root, options) { throw new TypeError('The require option must be if type function.'); } + if (!_.isUndefined(options.beforeAll) && !_.isFunction(options.beforeAll)) { + throw new TypeError('The beforeAll option must be if type function.'); + } + // Cache HTML templates @@ -120,46 +124,14 @@ module.exports = function initServeSpa(app, root, options) { }); - // Create and apply the middleware - - function serveSpa(req, res, next) { - - function render() { - - if ((arguments.length === 1 && !_.isUndefined(arguments[0]) && !_.isNull(arguments[0])) || arguments.length > 1) { - // Error provided or route forward intended... - return next.apply(undefined, arguments); - } - - var data = { - require: options.require || require, - request: req, - req: req, - response: res, - res: res - }; - - try { - - var html = cache[cacheEntry].template(data); - - res.set({ - 'Cache-Control': 'no-cache, no-store, must-revalidate', - 'Pragma': 'no-cache', - 'Expires': '0' - }); - res.send(html); - - } catch(err) { - next(err); - } + // Create and apply the middlewares - } + function prepare(req, res, next) { - var url = parseurl(req); + parseurl(req); // Don't serve index.htmlt and compose.js directly - if (url.pathname.match(/\/(index.htmlt|compose.js)$/i) !== null) { + if (req._parsedUrl.pathname.match(/\/(index.htmlt|compose.js)$/i) !== null) { // Ignore files with same behavior as SendStream.prototype.error(404) in npm package 'send' var msg = statuses[404]; res._headers = null; @@ -171,26 +143,96 @@ module.exports = function initServeSpa(app, root, options) { return; } + // Configuration for downstream middlewares + req._serveSpa = { + before: false, + compose: false, + render: false + }; + // Serve static files as usual - if (!_.isUndefined(staticFiles[url.pathname])) { + if (!_.isUndefined(staticFiles[req._parsedUrl.pathname])) { return next(); } - var cacheEntry = findCacheEntry(cache, url.pathname); + // Configuration for before middleware + if (!_.isUndefined(options.beforeAll)) { + req._serveSpa.before = options.beforeAll; + } + + var cacheEntry = findCacheEntry(cache, req._parsedUrl.pathname); if (_.isUndefined(cacheEntry)) { - return next(); + return next(); // serve-static will send a 404. } - // Render template + // Configuration for compose middleware if (!_.isUndefined(cache[cacheEntry].compose)) { - cache[cacheEntry].compose(req, res, render); - } else { - render(); + req._serveSpa.compose = cache[cacheEntry].compose; + } + + // Configuration for render middleware + req._serveSpa.render = cache[cacheEntry].template; + + next(); + + } + + function before(req, res, next) { + + if (req._serveSpa.before === false) { + return next(); + } + + return req._serveSpa.before(req, res, next); + + } + + function compose(req, res, next) { + + if (req._serveSpa.compose === false) { + return next(); + } + + return req._serveSpa.compose(req, res, next); + + } + + function render(req, res, next) { + + if (req._serveSpa.render === false) { + return next(); + } + + var data = { + require: options.require || require, + request: req, + req: req, + response: res, + res: res + }; + + try { + + var html = req._serveSpa.render(data); + + res.set({ + 'Cache-Control': 'no-cache, no-store, must-revalidate', + 'Pragma': 'no-cache', + 'Expires': '0' + }); + res.send(html); + + } catch(err) { + next(err); } } - app.use(serveSpa); + app.use(prepare); + app.use(before); + app.use(compose); + app.use(render); + app.use(serveStatic(root, options.staticSettings));