@kitmi/jacaranda
Version:
JavaScript application framework
125 lines (124 loc) • 5.03 kB
JavaScript
/**
* Enable routing web requests to a child app.
* @module Feature_AppRouting
*
* @example
*
* 'appRouting': {
* '<mounting point>': {
* name: 'app name',
* npmModule: false, // whether is a npm module
* options: { // module options
* },
* settings: { // can override module defined settings
* },
* middlewares: { // can override middlewares
* }
* }
* }
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return _default;
}
});
const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
const _utils = require("@kitmi/utils");
const _types = require("@kitmi/types");
const _algo = require("@kitmi/algo");
const _Feature = /*#__PURE__*/ _interop_require_default(require("../Feature"));
const _WebModule = /*#__PURE__*/ _interop_require_default(require("../WebModule"));
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
const _default = {
/**
* This feature is loaded at plugin stage.
* @member {string}
*/ stage: _Feature.default.PLUGIN,
/**
* Load the feature.
* @param {WebServer} server - The web server module object.
* @param {object} routes - Routes and configuration.
* @returns {Promise.<*>}
*/ load_: async (server, routes)=>{
const topoSort = new _algo.TopoSort();
const modules = {};
await (0, _utils.batchAsync_)(routes, async (config, baseRoute)=>{
if (!config.name) {
throw new _types.InvalidConfiguration('Missing app name.', app, `appRouting.${baseRoute}.name`);
}
let options = {
configType: server.options.configType,
logLevel: server.options.logLevel,
traceMiddlewares: server.options.traceMiddlewares,
logMiddlewareRegistry: server.options.logMiddlewareRegistry,
sourcePath: server.options.sourcePath,
...config.options
};
let { appPath, moduleMeta } = await server.tryLoadModule_(config, config.name, server.appModulesPath, `appRouting.[${baseRoute}]`);
if (!moduleMeta) {
moduleMeta = {};
}
let app = new _WebModule.default(server, config.name, baseRoute, appPath, {
...options,
...moduleMeta.options,
registry: moduleMeta.registry
});
app.once('configLoaded', ()=>{
if (!_utils._.isEmpty(config.overrides)) {
Object.assign(app.config, config.overrides);
server.log('verbose', 'App config is overrided.');
}
if (!_utils._.isEmpty(config.settings)) {
app.config.settings = Object.assign({}, app.config.settings, config.settings);
server.log('verbose', `App settings of [${app.name}] is overrided.`);
}
if (!_utils._.isEmpty(config.middlewares)) {
let middlewaresToAppend = app.config.middlewares;
app.config.middlewares = {
...config.middlewares
};
_utils._.defaults(app.config.middlewares, middlewaresToAppend);
}
});
(0, _utils.pushIntoBucket)(modules, config.name, {
appPath,
app
});
if (config.depends) {
topoSort.depends(config.name, config.depends);
} else if (moduleMeta.depends) {
topoSort.depends(config.name, moduleMeta.depends);
} else {
topoSort.add(config.name);
}
});
const sorted = topoSort.sort();
server.once('after:' + _Feature.default.PLUGIN, async ()=>{
await (0, _utils.eachAsync_)(sorted, async (name)=>{
const bucket = modules[name];
if (bucket == null) {
throw new _types.ServerError(`App [${name}] not exist.`);
}
return (0, _utils.batchAsync_)(bucket, async ({ appPath, app })=>{
let relativePath = _nodepath.default.relative(server.workingPath, appPath);
server.log('verbose', `Loading app [${app.name}] from "${relativePath}" ...`);
await app.start_();
server.log('verbose', `App [${app.name}] is loaded.`);
//delayed the app routes mounting after all plugins of the server are loaded
server.on('before:' + _Feature.default.FINAL, ()=>{
server.mountApp(app);
});
});
});
});
}
};
//# sourceMappingURL=appRouting.js.map