All files / middlewares mvc.js

100% Statements 48/48
100% Branches 18/18
100% Functions 12/12
100% Lines 47/47
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89          1x 1x 1x 1x 1x   1x   7x 7x 7x         7x 6x 1x   5x 5x       7x       7x 6x   1x 1x 1x 1x 1x 2x 1x 1x 2x 2x 2x 2x 2x 2x     2x     2x 2x         6x 4x 4x   2x 1x 4x     2x       7x 6x   1x 1x       1x       1x    
/**
 * MVC middleware
 **/
'use strict';
 
const assert    = require('assert');
const path      = require('path');
const Directory = require('directoryfiles');
const LarkMVC   = require('lark-mvc');
const LarkViews = require('lark-views');
 
module.exports = (app) => {
 
    registerControllerProxy(app);
    registerModels(app);
    registerViews(app);
 
};
 
function registerControllerProxy(app) {
    const proxy = (controller) => {
        if (!(controller instanceof Function) || controller.MVC_TYPE !== 'Controller') {
            return controller;
        }
        return async (ctx) => {
            return await app.mvc.dispatch(controller, ctx);
        };
    };
 
    app.config.set('mvc/proxy/controller', proxy);
}
 
function registerModels(app) {
    if (!app.config.has('mvc/models/path')) {
        return;
    }
    const config = app.config.get('mvc/models');
    let directory = config.path;
    let extList = config.ext || ['js', 'node'];
    assert('string' === typeof directory, 'Models directory path must be a string');
    assert(Array.isArray(extList), 'Model files extname list must be an array');
    extList.forEach(ext => assert('string' === typeof ext, 'Model files extname must be a string'));
    directory = new Directory(directory);
    directory.map(filepath => {
        let extname = path.extname(filepath);
        let name = path.basename(filepath, extname);
        let dirname = path.relative(directory.path, path.dirname(filepath));
        name = path.join(dirname, name);
        extname = extname.slice(1);
        return { filepath, name, extname };
    })
    .filter((file) => {
        return (!file.name.startsWith('.')) && extList.includes(file.extname);
    })
    .each(file => {
        const module = require(file.filepath);
        registerModel(app, module, file.name);
    });
}
 
function registerModel(app, module, name) {
    if (module instanceof Function && module.MVC_TYPE === LarkMVC.Model.MVC_TYPE) {
        app.mvc.use(module, { name });
        return;
    }
    if (module instanceof Object) {
        for (const key in module) {
            registerModel(app, module[key], path.join(name, key));
        }
    }
    return;
}
 
function registerViews(app) {
    if (!app.config.has('mvc/views')) {
        return;
    }
    const config = app.config.get('mvc/views');
    const views = new LarkViews(config);
 
    class View extends LarkMVC.View {
        async render(...args) {
            return await views.render(...args);
        }
    }
 
    app.mvc.use(View);
}