module.exports = function(app) {
return function(path, defaultMiddleware, moduleNames, includeNameInPath) {
moduleNames.forEach(function(name) {
let route = path;
if (includeNameInPath) {
route += name + "/";
}
console.log("Build routes for " + path + name);
let routeData = require("./routes" + path + name);
for (let endpointType in routeData) {
console.log("Build " + endpointType + " endpoints...");
let routes = routeData[endpointType];
traverse(routes, [], function(path, node) {
let fullPath = route + path.join("/");
app[endpointType](...processRoute(fullPath, defaultMiddleware, node));
});
console.log("done\n");
}
});
return app;
};
};
function traverse(obj, path, func) {
for (const key in obj) {
if (Array.isArray(obj[key]) || typeof(obj[key]) == "function") {
func.apply(this, [
[...path, key], obj[key]
]);
} else if (typeof(obj[key]) == "object") {
//going one step down in the object tree!!
traverse(obj[key], [...path, key], func);
}
}
}
function processRoute(path, middlewares, data) {
if (typeof data === "function") {
let final_middleware = [];
let names = "";
for (const [name, middleware] of middlewares) {
if (middleware.default) {
final_middleware.push(middleware.func);
names += name + " ";
}
}
console.log(names.padEnd(20), path);
return [path, ...final_middleware, data];
} else {
let final_middleware = new Map();
for (const [name, middleware] of middlewares) {
if (Object.prototype.hasOwnProperty.call(data[0], name)) {
final_middleware.set(name, {
func: middleware.func,
default: data[0][name]
});
} else {
final_middleware.set(name, middleware);
}
}
return processRoute(path, final_middleware, data[1]);
}
}