diff --git a/helpers.js b/helpers.js index 5cf4d59..67e25ea 100644 --- a/helpers.js +++ b/helpers.js @@ -13,14 +13,14 @@ function replace(text, marker, getReplacement, once) { matches = [matches[0]]; } var match_promises = []; - _.forEach(matches, function (result) { + _.forEach(matches, function handleMatch(result) { var deferred2 = when.defer(); match_promises.push(deferred2.promise); - getReplacement(result, function (err, replacement) { + getReplacement(result, function resolveReplacement(err, replacement) { if (err) { deferred2.reject(err); } else { - var replace_result ={ + var replace_result = { regExp: replacement.regExp || regExp, replacement: replacement.value }; @@ -47,9 +47,9 @@ function handTextManipulation(text, promises, handler, callback) { when.all( promises, function onSuccess(all_results) { - _.forEach(all_results, function (results) { - _.forEach(results, function (result) { - text = handler( text, result); + _.forEach(all_results, function loopResults(results) { + _.forEach(results, function handleResult(result) { + text = handler(text, result); }); }); return callback(null, text); diff --git a/importer.js b/importer.js index 6716a27..bcec5b7 100644 --- a/importer.js +++ b/importer.js @@ -5,7 +5,7 @@ var path = require('path'); var fs = require('fs'); -module.exports = function (config, mongoInstance, sharemodel) { +module.exports = function (config, mongoInstance, shareModel) { var import_leftovers_tag = 'import_leftovers__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)'; var import_leftovers_regexp = new RegExp(helpers.marker_prefix + import_leftovers_tag + helpers.marker_postfix); @@ -34,7 +34,7 @@ module.exports = function (config, mongoInstance, sharemodel) { return cb(err); } if (leftover) { - mongoInstance.ensureContent(leftover.replacement, function parent(err, parent_result) { + return mongoInstance.ensureContent(leftover.replacement, function parent(err, parent_result) { if (err) { config.errors && console.log('ERR importer.importer ensureContent', err); return cb(err); @@ -42,17 +42,17 @@ module.exports = function (config, mongoInstance, sharemodel) { leftover.replacement.query = { _id: parent_result._id }; remainder = remainder.replace(leftover.regExp, ""); - mongoInstance.setMongoAttribute(remainder, leftover.replacement, function (err, attribute_result) { + return mongoInstance.setMongoAttribute(remainder, leftover.replacement, function savedAttribute(err) { if (err) { config.errors && console.log('ERR importer.importer setMongoAttribute', err); return cb(err); } - var documentId = 'text:'+leftover.replacement.collection + ':' + parent_result._id+ ':' + leftover.replacement.attribute; - console.log('1 removing documentID',documentId); + var documentId = 'text:' + leftover.replacement.collection + ':' + parent_result._id + ':' + leftover.replacement.attribute; + console.log('1 removing documentID', documentId); - sharemodel.delete(documentId, function (err, result) { + return shareModel.delete(documentId, function deletedDocument(err) { if (err) { - config.errors && console.log('ERR importer.importer sharemodel.delete', documentId, err); + config.errors && console.log('ERR importer.importer shareModel.delete', documentId, err); //return cb(err); } @@ -79,6 +79,7 @@ module.exports = function (config, mongoInstance, sharemodel) { function handler(text, result) { var new_text = text.replace(result.regExp, result.replacement); + config.debug && console.log('handleImportMarker.handler new_text', new_text); return new_text; } @@ -96,7 +97,7 @@ module.exports = function (config, mongoInstance, sharemodel) { var import_strip_regexp = new RegExp(helpers.marker_postfix + '([\\w\\W]*)' + helpers.marker_prefix); promises.push( - helpers.replace(doc, import_tag, function (result, callback) { + helpers.replace(doc, import_tag, function handleImportMarker(result, callback) { var parts = import_regexp.exec(result); var context = { collection: parts[1], @@ -112,7 +113,7 @@ module.exports = function (config, mongoInstance, sharemodel) { config.errors && console.log('ERR importer.replaceMarkers ensureContent', err); return callback(err); } - function handleResult(err, db_result) { + function handleResult(err) { var replacement = { regExp: result, value: "" @@ -123,7 +124,7 @@ module.exports = function (config, mongoInstance, sharemodel) { if (context.attribute == "json") { var data = null; try { - data = JSON.parse(remainder); + data = JSON.parse(remainder); } catch (err) { config.errors && console.log('ERR importer.replaceMarkers JSON.parse(remainder)', remainder, err); return callback(err); @@ -132,22 +133,22 @@ module.exports = function (config, mongoInstance, sharemodel) { delete data._id; } _.extend(parent_result, data); - mongoInstance.setMongoContent(parent_result, context, handleResult); + return mongoInstance.setMongoContent(parent_result, context, handleResult); } else { context.query = { _id: parent_result._id }; - mongoInstance.setMongoAttribute(remainder, context, function (err, attribute_result) { + return mongoInstance.setMongoAttribute(remainder, context, function savedAttribute(err) { if (err) { config.errors && console.log('ERR importer.importer setMongoAttribute', err); return callback(err); } - var documentId = 'text:'+context.collection + ':' + parent_result._id+ ':' + context.attribute; - console.log('2 removing documentID',documentId); - sharemodel.delete(documentId, function (err, result) { + var documentId = 'text:' + context.collection + ':' + parent_result._id + ':' + context.attribute; + console.log('2 removing documentID', documentId); + return shareModel.delete(documentId, function deletedDocument(err) { if (err) { - config.errors && console.log('ERR importer.importer sharemodel.delete', documentId, err); + config.errors && console.log('ERR importer.importer shareModel.delete', documentId, err); } - handleResult(null, attribute_result); + handleResult(null); }) }); @@ -162,43 +163,43 @@ module.exports = function (config, mongoInstance, sharemodel) { var import_file_regexp = new RegExp(helpers.marker_prefix + import_file_tag + helpers.marker_postfix); promises.push( - helpers.replace(doc, import_file_tag, function (result, callback) { + helpers.replace(doc, import_file_tag, function handleImportFileMarker(result, callback) { var parts = import_file_regexp.exec(result); - var filename = path.resolve(config.importer_path, parts[1]); + var filename = path.resolve(config.statics.importer_path, parts[1]); var context = { collection: parts[2], name: parts[3], attribute: parts[4] }; - fs.readFile(filename, 'utf-8', function (err, sub_doc) { + fs.readFile(filename, 'utf-8', function handleFileContent(err, sub_doc) { if (err) { config.errors && console.log('ERR importer.replaceMarkers readFile', err); return callback(err); } // process with leftover marker support - importer(sub_doc, context, function handleLeftover(err, remainder) { + return importer(sub_doc, context, function handleLeftover(err, remainder) { if (err) { config.errors && console.log('ERR importer.replaceMarkers importer', err); return callback(err); } - mongoInstance.ensureContent(context, function parent(err, parent_result) { + return mongoInstance.ensureContent(context, function parent(err, parent_result) { if (err) { config.errors && console.log('ERR importer.importer ensureContent', err); return callback(err); } context.query = { _id: parent_result._id }; - mongoInstance.setMongoAttribute(remainder, context, function (err, attribute_result) { + return mongoInstance.setMongoAttribute(remainder, context, function savedAttribute(err) { if (err) { config.errors && console.log('ERR importer.importer setMongoAttribute', err); return callback(err); } - var documentId = 'text:'+context.collection + ':' + parent_result._id+ ':' + context.attribute; - console.log('3 removing documentID',documentId); + var documentId = 'text:' + context.collection + ':' + parent_result._id + ':' + context.attribute; + console.log('3 removing documentID', documentId); - sharemodel.delete(documentId, function (err, result) { + return shareModel.delete(documentId, function deletedDocument(err, result) { if (err) { - config.errors && console.log('ERR importer.importer sharemodel.delete', documentId, err); + config.errors && console.log('ERR importer.importer shareModel.delete', documentId, err); } // remove import_file marker from source var replacement = { diff --git a/preview.js b/preview.js index 0505d21..87319a3 100644 --- a/preview.js +++ b/preview.js @@ -5,16 +5,7 @@ var less = require('less'); var when = require('when'); var helpers = require('./helpers.js'); -module.exports = function (config, mongodataInstance) { - - var sourceHead = - '\n' + - '{{#if debug}}' + - '\n' + - '\n' + - '{{else}}' + - '\n' + - '{{/if}}'; +module.exports = function (config, mongoDataInstance) { var getPreviewHTML = function (content, options, callback) { config.debug && console.log('getPreviewHTML', content); @@ -38,7 +29,7 @@ module.exports = function (config, mongodataInstance) { var script_tag = 'script__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)'; var script_regexp = new RegExp(helpers.marker_prefix + script_tag + helpers.marker_postfix); promises.push( - helpers.replace(html, script_tag, function (result, callback) { + helpers.replace(html, script_tag, function handleScriptMarker(result, callback) { var parts = script_regexp.exec(result); var context = { collection: parts[1], @@ -47,14 +38,14 @@ module.exports = function (config, mongodataInstance) { }; return callback(null, { regExp: new RegExp(result, 'gmi'), - value: '' + value: '' }); })); var style_tag = 'style__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)'; var style_regexp = new RegExp(helpers.marker_prefix + style_tag + helpers.marker_postfix); promises.push( - helpers.replace(html, style_tag, function (result, callback) { + helpers.replace(html, style_tag, function handleStyleMarker(result, callback) { var parts = style_regexp.exec(result); var context = { collection: parts[1], @@ -63,14 +54,14 @@ module.exports = function (config, mongodataInstance) { }; return callback(null, { regExp: new RegExp(result, 'gmi'), - value: '' + value: '' }); })); var template_tag = 'template__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)__context__([A-Za-z0-9]+)_([A-Za-z0-9]+)'; var template_regexp = new RegExp(helpers.marker_prefix + template_tag + helpers.marker_postfix); promises.push( - helpers.replace(html, template_tag, function (result, callback) { + helpers.replace(html, template_tag, function handleTemplateMarker(result, callback) { var parts = template_regexp.exec(result); var template = { collection: parts[1], @@ -84,12 +75,12 @@ module.exports = function (config, mongodataInstance) { query: { name: parts[5]}, req: options.req }; - mongodataInstance.getMongoContent(context, function (err, context_result) { + return mongoDataInstance.getMongoContent(context, function handleContext(err, context_result) { if (err) { config.errors && console.log('ERR template_tag getMongoContent', context); return callback(err); } - mongodataInstance.getMongoAttribute(template, function (err, attribute_result) { + return mongoDataInstance.getMongoAttribute(template, function handleTemplate(err, template_result) { if (err) { config.errors && console.log('ERR template_tag getMongoAttribute', template, err); return callback(err); @@ -99,7 +90,7 @@ module.exports = function (config, mongodataInstance) { // Handlebars is synchronous ouch !! var handlebars = Handlebars.create(); _.forEach(_.keys(context_result), function (key) { - handlebars.registerHelper(key, function (key_context, key_options) { + handlebars.registerHelper(key, function () { if (context_result[key].guid) { if (keys_to_collect.hasOwnProperty(key)) { return keys_to_collect[key]; @@ -112,19 +103,19 @@ module.exports = function (config, mongodataInstance) { }); }); try { - compiled_template = handlebars.compile(attribute_result[template.attribute]); + compiled_template = handlebars.compile(template_result[template.attribute]); } catch (err) { config.errors && console.log('ERR template_tag Handlebars.compile', template, err); return callback(err); } try { - var tmp_rendered = compiled_template(context_result); + compiled_template(context_result); } catch (err) { config.errors && console.log('ERR template_tag Handlebars.render', template, context, err); return callback(err); } var promises = []; - _.forEach(_.keys(keys_to_collect), function (key) { + _.forEach(_.keys(keys_to_collect), function gatherKeyValues(key) { var deferred = when.defer(); var promise = deferred.promise; promises.push(promise); @@ -133,19 +124,19 @@ module.exports = function (config, mongodataInstance) { attribute: key, query: { _id: context_result._id} }; - mongodataInstance.getMongoAttribute(attribute_context, function (err, template_attribute_result) { + return mongoDataInstance.getMongoAttribute(attribute_context, function cacheTemplateKey(err, template_key_result) { if (err) { config.errors && console.log('ERR handlebar.registerHelper getMongoAttribute', err); deferred.reject(err); } - var value = template_attribute_result[key]; + var value = template_key_result[key]; keys_to_collect[key] = value; deferred.resolve(value); }); }); - when.all( + return when.all( promises, - function onSuccess(values) { + function onSuccess() { var rendered = null; try { rendered = compiled_template(context_result); @@ -153,9 +144,9 @@ module.exports = function (config, mongodataInstance) { config.errors && console.log('ERR template_tag Handlebars.render', template, context, err); return callback(err); } - config.debug && console.log('// recurse markers on rendered template'); + config.debug && console.log('// handle markers on rendered template'); context.query = {_id: context_result._id}; - getPreviewHTML(rendered, context, function (err, preview_html) { + return getPreviewHTML(rendered, context, function handlePreviewResult(err, preview_html) { if (err) { config.errors && console.log('ERR template_tag getPreviewHTML', err); return callback(err); @@ -178,18 +169,18 @@ module.exports = function (config, mongodataInstance) { var markdown_tag = 'markdown__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)'; var markdown_regexp = new RegExp(helpers.marker_prefix + markdown_tag + helpers.marker_postfix); promises.push( - helpers.replace(html, markdown_tag, function (result, callback) { + helpers.replace(html, markdown_tag, function handleMarkDownMarker(result, callback) { var parts = markdown_regexp.exec(result); var attribute = { collection: parts[1], name: parts[2], attribute: parts[3] }; - mongodataInstance.getMongoAttribute(attribute, function (err, attribute_result) { + return mongoDataInstance.getMongoAttribute(attribute, function handleMarkdownContent(err, markdown_result) { if (err) { return callback(err); } - var html = markdown.toHTML(attribute_result[options.attribute]); + var html = markdown.toHTML(markdown_result[options.attribute]); return callback(null, { regExp: new RegExp(result, 'gmi'), value: html @@ -200,7 +191,7 @@ module.exports = function (config, mongodataInstance) { var remove_tag = 'remove_([\\w\\W]*?)_end_remove'; //var remove_regexp = new RegExp(remove_tag); promises.push( - helpers.replace(html, remove_tag, function (result, callback) { + helpers.replace(html, remove_tag, function handleRemoveMarker(result, callback) { return callback(null, { regExp: null, value: "" diff --git a/responder.js b/responder.js index c9a79cb..6e6dedd 100644 --- a/responder.js +++ b/responder.js @@ -15,9 +15,9 @@ var getMimeType = function (ext) { }; module.exports = function (options, res, next) { - var responder = function (err, result) { + return function responder(err, result) { if (err) { - console.log('ERR responder', options, err) ; + console.log('ERR responder', options, err); if (/Data not found*/.test(err.message)) { res.status(404); } @@ -29,7 +29,6 @@ module.exports = function (options, res, next) { if (options.attribute) { content = result[options.attribute]; } - res.send(content); + return res.send(content); }; - return responder; }; diff --git a/routes.js b/routes.js index d9b3ab1..e029dd4 100644 --- a/routes.js +++ b/routes.js @@ -1,5 +1,5 @@ -var sharejs = require('share'); -var mongodata = require('./mongodata.js'); +var ShareJS = require('share'); +var mongoData = require('./mongodata.js'); var responder = require('./responder.js'); var preview = require('./preview.js'); var importer = require('./importer.js'); @@ -10,12 +10,13 @@ var fs = require('fs'); module.exports = function (app, config) { // share wraps express app with http.Server - var server = sharejs.server.attach(app, config.share); + var server = ShareJS.server.attach(app, config.share); var model = app.model; - var mongodataInstance = mongodata(config); - - app.get('/data/:collection/:guid/:attribute.:ext(css|less|js|html)', + var mongoDataInstance = mongoData(config); + var route; + route = config.api.data + '/:collection/:guid/:attribute.:ext(css|less|js|html)'; + app.get(route, function getMongoAttribute(req, res, next) { config.debug && console.log('/data/:collection/:guid/:attribute.:ext(less|js|html)'); var options = { @@ -24,13 +25,14 @@ module.exports = function (app, config) { ext: req.params.ext, query: {_id: req.params.guid} }; - mongodataInstance.getMongoAttribute(options, + mongoDataInstance.getMongoAttribute(options, responder(options, res, next) ); } ); - app.get('/data/:collection/:guid.:ext(json)', + route = config.api.data + '/:collection/:guid.:ext(json)'; + app.get(route, function getMongoContent(req, res, next) { config.debug && console.log('/data/:collection/:guid.:ext(json)'); var options = { @@ -38,13 +40,14 @@ module.exports = function (app, config) { ext: req.params.ext, query: {_id: req.params.guid} }; - mongodataInstance.getMongoContent(options, + mongoDataInstance.getMongoContent(options, responder(options, res, next) ); } ); - app.get('/content/:collection/:name/:attribute.:ext(css|less|js|html)', + route = config.api.content + '/:collection/:name/:attribute.:ext(css|less|js|html)'; + app.get(route, function getMongoAttribute(req, res, next) { config.debug && console.log('/content/:collection/:name/:attribute.:ext(less|js|html)'); var options = { @@ -53,13 +56,14 @@ module.exports = function (app, config) { ext: req.params.ext, query: {name: req.params.name} }; - mongodataInstance.getMongoAttribute(options, + mongoDataInstance.getMongoAttribute(options, responder(options, res, next) ); } ); - app.get('/content/:collection/:name.:ext(json)', + route = config.api.content + '/content/:collection/:name.:ext(json)'; + app.get(route, function getMongoContent(req, res, next) { config.debug && console.log('/content/:collection/:name.:ext(json)'); var options = { @@ -67,7 +71,7 @@ module.exports = function (app, config) { ext: req.params.ext, query: {name: req.params.name} }; - mongodataInstance.getMongoContent(options, + mongoDataInstance.getMongoContent(options, responder(options, res, next) ); } @@ -129,10 +133,10 @@ module.exports = function (app, config) { if (splitId.length == 4) { options.query = {_id: splitId[2]}; options.attribute = splitId[3]; - mongodataInstance.getMongoAttribute(options, handleMongoGetResult(options)); + mongoDataInstance.getMongoAttribute(options, handleMongoGetResult(options)); } else { options.query = {name: splitId[2]}; - mongodataInstance.getMongoContent(options, handleMongoGetResult(options)); + mongoDataInstance.getMongoContent(options, handleMongoGetResult(options)); } }); @@ -148,7 +152,7 @@ module.exports = function (app, config) { var operation = { op: [ { p: ['name'], oi: result.name, od: null } ], v: options.operation.v }; - model.applyOp(options.documentId, operation, function appliedOp(error, version) { + return model.applyOp(options.documentId, operation, function appliedOp(error, version) { config.debug && console.log('setResult applyOp version', version); if (error) { config.error && console.log('ERR2 handleMongoSetResult', error); @@ -156,6 +160,8 @@ module.exports = function (app, config) { } return callback && callback(null, version); }); + } else { + return callback(null, null); } } @@ -166,7 +172,7 @@ module.exports = function (app, config) { function handleResult(err, result) { if (err) { config.errors && console.log('ERR1 handleMongoAttributeSetResult Error while saving document ', options.collection, JSON.stringify(options.query), options.attribute || "", err); - return callback && callback(err); + return callback(err); } options.debug && console.log('current', current, 'result', result); if (result.hasOwnProperty('_id')) { @@ -177,14 +183,16 @@ module.exports = function (app, config) { { p: [options.attribute], oi: { guid: result._id }, od: null } ], v: options.operation.v }; - model.applyOp(parentDocId, operation, function appliedOp(error, version) { + return model.applyOp(parentDocId, operation, function appliedOp(error, version) { config.debug && console.log('setResult applyOp parent version', version); if (error) { config.error && console.log('ERR2 handleMongoAttributeSetResult', error); - return callback && callback(error); + return callback(error); } - return callback && callback(null, version); + return callback(null, version); }) + } else { + return callback(null, null); } } @@ -194,22 +202,22 @@ module.exports = function (app, config) { var timers = {}; function handleSetTimeout(documentId) { - return function () { + return function saveContent() { var args = timers[documentId]; delete timers[documentId]; config.debug && console.log('running timer', documentId); - mongodataInstance.setMongoContent(args.current, args.options, + mongoDataInstance.setMongoContent(args.current, args.options, handleMongoSetResult(args.options, args.current, - function (err, result) { + function handleApplyOpResult(err, version) { if (err) { - config.errors && console.log('ERR2 applyOp', err); + config.errors && console.log('ERR2 applyOp', version, err); } })); }; } function handleSetAttributeTimeout(documentId) { - return function () { + return function saveAttribute() { var args = timers[documentId]; delete timers[documentId]; config.debug && console.log('running timer', documentId); @@ -217,11 +225,11 @@ module.exports = function (app, config) { if (args.options.type == 'json') { data = JSON.parse(args.current); } - mongodataInstance.setMongoAttribute(data, args.options, + mongoDataInstance.setMongoAttribute(data, args.options, handleMongoAttributeSetResult(args.options, data, - function (err, result) { + function handleApplyOpResult(err, version) { if (err) { - config.errors && console.log('ERR1 applyOp', err); + config.errors && console.log('ERR1 applyOp', version, err); } })); }; @@ -229,7 +237,7 @@ module.exports = function (app, config) { // 'applyOp' event is fired when an operational transform is applied to to a shareDoc // a shareDoc has changed and needs to be saved to mongo - model.on('applyOp', function persistDocument(documentId, operation, current, previous) { + model.on('applyOp', function persistDocument(documentId, operation, current) { config.debug && console.log('applyOp', documentId, operation, current); if (operation.v == 0) return; @@ -272,9 +280,10 @@ module.exports = function (app, config) { } }); - var previewInstance = preview(config, mongodataInstance); + var previewInstance = preview(config, mongoDataInstance); - app.get('/page/:collection/:name.:ext(html)', + route = config.api.preview + '/:collection/:name.:ext(html)'; + app.get(route, function getPreviewContent(req, res, next) { config.debug && console.log('/page/:collection/:name.:ext(html)'); var options = { @@ -284,11 +293,10 @@ module.exports = function (app, config) { req: { query: req.query || {}, headers: req.headers } -// debug: req.query && req.query.hasOwnProperty('debug') }; - mongodataInstance.getMongoContent(options, function (err, result) { + mongoDataInstance.getMongoContent(options, function handleResult(err, result) { if (err) { - responder(options, res, next)(err, result); + return responder(options, res, next)(err, result); } if (result) { var attribute_parts = options.query.name.split('.'); @@ -305,23 +313,26 @@ module.exports = function (app, config) { }; config.debug && console.log('getPreviewContent content', attribute_value); - previewInstance.getPreviewHTML(attribute_value, preview_options, + return previewInstance.getPreviewHTML(attribute_value, preview_options, responder(options, res, next) ); } else { return next(); } + } else { + return next(); } }); } ); - var importerInstance = importer(config, mongodataInstance, model); + var importerInstance = importer(config, mongoDataInstance, model); - app.get('/importer/:filename', function importFile(req, res, next) { - var filename = path.resolve(config.importer_path, req.params.filename); + route = config.api.importer + '/:filename'; + app.get(route, function importFile(req, res, next) { + var filename = path.resolve(config.statics.importer_path, req.params.filename); config.debug && console.log('/importer/:filename', filename); - fs.readFile(filename, 'utf-8', function (err, sub_doc) { + fs.readFile(filename, 'utf-8', function handleFileContent(err, sub_doc) { if (err) { config.errors && console.log('ERR readFile', filename, err); next(err); diff --git a/server.js b/server.js index 864f772..cb91161 100644 --- a/server.js +++ b/server.js @@ -27,22 +27,35 @@ var config = { staticpath: '/lib/share', db: {type: 'none'} }, - importer_path: __dirname + '/public', - public_path: __dirname + '/public', - markdown_client: __dirname + '/node_modules/markdown/lib', - ace_client: __dirname + '/node_modules/share/examples/lib/ace' + api: { + content: '/content', + data: '/data', + preview: '/page', + importer: '/importer' + }, + statics: { + importer_path: __dirname + '/public', + public_path: __dirname + '/public', + markdown_client: __dirname + '/node_modules/markdown/lib', + ace_client: __dirname + '/node_modules/share/examples/lib/ace' + } }; var app = express(); config.debug && app.use(connect.logger()); -app.use(express.static(config.public_path)); -app.use('/lib/markdown', express.static(config.markdown_client)); -app.use('/lib/ace', express.static(config.ace_client)); +app.use(express.static(config.statics.public_path)); +app.use('/lib/markdown', express.static(config.statics.markdown_client)); +app.use('/lib/ace', express.static(config.statics.ace_client)); var server = instance(app, config); -server.listen(config.port, function (err) { +server.listen(config.port, function handleServerResult(err) { + if (err) { + app.stop(); + console.log('Server error', err); + return process.exit(1); + } config.debug && console.log('routes', app.routes); - console.log('Server running at http://127.0.0.1:', config.port); + return console.log('Server running at http://127.0.0.1:', config.port); });