vgno/roc-web

View on GitHub
src/app/server/index.js

Summary

Maintainability
B
4 hrs
Test Coverage
/* global USE_DEFAULT_KOA_MIDDLEWARES HAS_KOA_MIDDLEWARES KOA_MIDDLEWARES ROC_PATH  */

import debug from 'debug';
import koa from 'koa';
import serve from 'koa-static';
import mount from 'koa-mount';

import addTrailingSlash from 'koa-add-trailing-slashes';
import normalizePath from 'koa-normalize-path';
import lowercasePath from 'koa-lowercase-path';
import removeTrailingSlash from 'koa-remove-trailing-slashes';

import { merge, getSettings } from 'roc';

/**
 * Creates a server instance.
 *
 * @example
 * import { createServer } from 'roc-web/app';
 *
 * const server = createServer({
 *    serve: 'static',
 *    favicon: 'static/favicon.png'
 * });
 *
 * server.start();
 *
 * @param {rocServerOptions} options - Options for the server. Will override configuration in roc.config.js.
 * @param {Function[]} beforeUserMiddlewares - Middlewares that should be added before the user middlewares.
 * @returns {rocServer} server - Roc server instace.
 */
export default function createServer(options = {}, beforeUserMiddlewares = []) {
    const server = koa();
    const settings = merge(getSettings('runtime'), options);

    if (USE_DEFAULT_KOA_MIDDLEWARES) {
        const middlewares = require('./middlewares').default(settings);
        middlewares.forEach((middleware) => server.use(middleware));
    }

    if (beforeUserMiddlewares.length) {
        beforeUserMiddlewares.forEach((middleware) => server.use(middleware));
    }

    if (HAS_KOA_MIDDLEWARES) {
        const middlewares = require(KOA_MIDDLEWARES).default(settings);
        middlewares.forEach((middleware) => server.use(middleware));
    }

    const makeServe = (toServe = []) => {
        toServe = [].concat(toServe);
        for (const path of toServe) {
            // We use defer here to no try to fetch a file if we have set something on body, something that is done in
            // redirect. This because https://github.com/koajs/send/issues/51
            server.use(serve(path, { defer: true }));
        }
    };

    if (settings.koa.normalize.enabled) {
        server.use(normalizePath({ defer: settings.koa.normalize.defer }));
    }

    if (settings.koa.lowercase.enabled) {
        server.use(lowercasePath({ defer: settings.koa.lowercase.defer }));
    }

    if (settings.koa.trailingSlashes.enabled === true) {
        server.use(addTrailingSlash({ defer: settings.koa.trailingSlashes.defer }));
    } else if (settings.koa.trailingSlashes.enabled === false) {
        server.use(removeTrailingSlash());
    }

    // Serve folders
    makeServe(settings.serve);

    function start(port) {
        port = port || process.env.PORT || settings.port;

        const app = koa();
        app.use(mount(ROC_PATH, server));
        app.listen(port);

        if (process.send) {
            process.send('online');
        }

        debug('roc:server')('Server started on port ' + port + ' and served from ' + ROC_PATH);
    }

    return {
        server,
        start
    };
}