From f420e045be827fad6345f0f190d687938f47c959 Mon Sep 17 00:00:00 2001 From: Misha Wolfson Date: Thu, 15 Dec 2016 17:55:59 -0500 Subject: [PATCH] Refactor setting resolution from command line and config file --- lib/spserver.js | 97 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 32 deletions(-) diff --git a/lib/spserver.js b/lib/spserver.js index b7cb21c..b9f7e55 100644 --- a/lib/spserver.js +++ b/lib/spserver.js @@ -10,9 +10,15 @@ var nStatic = require('node-static'); var config = require('./config'); var logger = require('./logger'); -var env = config.get('NODE_ENV'); -var spserver = function (settings) { +// The different config sources sometimes manipulate different setting names. +// E.g. command line flags maniuplate root settings, but config files can +// manipulate settings at the prod/debug level. Resolve all of these into a +// final object of settings. +function _resolveFinalSettings(settings) { + var finalSettings = {}; + var env = config.get('NODE_ENV'); + if (!settings) { settings = config.get(); } @@ -20,9 +26,55 @@ var spserver = function (settings) { settings[env] = {}; } - var fileServer = new nStatic.Server(path.resolve(settings.serve || settings[env].server)); + // For 'name', 'file', 'serve', and 'port', default to the global setting rather than an + // individual environment's setting, because it might have been set via command-line flags + _(['name', 'file', 'serve', 'port']).forEach(function (field) { + finalSettings[field] = settings[field] || settings[env][field]; + }); - var base = generateBase(path.resolve(settings.file || settings[env].file), settings); + // For 'staticOptions', there are no command-line flags, so individual configuration options + // override global defaults where set + finalSettings.staticOptions = _.defaultsDeep(settings.staticOptions, settings[env].staticOptions); + + // Make a template function so we can just pass that in downstream + finalSettings.template = (settings.template || settings[env].template) ? + function (contents) { + // Note: template is run with _original_, non-resolved settings + return _.template(contents)(settings); + } : null; + + return finalSettings; +} + +function generateBase(file, finalSettings) { + if (!file) { + return null; + } + + if (_.endsWith(file, 'js')) { + return require(file); + } + + var contents = fs.readFileSync(file); + if (finalSettings.template) { + contents = finalSettings.template(contents); + } + + return function(req, res) { + res.writeHead(200, {'Content-Type': 'text/html'}); + res.end(contents); + }; +} + +var spserver = function (settings) { + var finalSettings = _resolveFinalSettings(settings); + + var fileServer = new nStatic.Server( + path.resolve(finalSettings.serve), + finalSettings.staticOptions + ); + + var base = generateBase(path.resolve(finalSettings.file), finalSettings); var server = http.createServer(function (req, res) { logger.debug('[REQ] GET:', req.url); @@ -52,37 +104,18 @@ var spserver = function (settings) { }).resume(); }); - server.listen(settings.port || settings[env].port); + server.listen(finalSettings.port); - logger.info('Static server', - settings.name, - 'is listening on port', - settings.port || settings[env].port, - 'with public folder', - settings.serve || settings[env].serve); + logger.info( + 'Started single-page server: ' + finalSettings.name + + ', base file: ' + finalSettings.file + + ', static folder: ' + finalSettings.serve + + ', port: ' + finalSettings.port + ); + + return server; }; spserver.generateBase = generateBase; -function generateBase(file, settings) { - if (!file) { - return null; - } - - if (_.endsWith(file, 'js')) { - return require(file); - } - - var contents = fs.readFileSync(file); - - if (settings.template || settings[env] && settings[env].template) { - contents = _.template(contents)(settings); - } - - return function(req, res) { - res.writeHead(200, {'Content-Type': 'text/html'}); - res.end(contents); - }; -} - module.exports = spserver;