diff --git a/packages/strapi/lib/configuration/hooks/core/router/index.js b/packages/strapi/lib/configuration/hooks/core/router/index.js index 5bacb2ff31..83cae444f1 100644 --- a/packages/strapi/lib/configuration/hooks/core/router/index.js +++ b/packages/strapi/lib/configuration/hooks/core/router/index.js @@ -1,4 +1,4 @@ -'use strict'; + 'use strict'; /** * Module dependencies @@ -53,12 +53,46 @@ module.exports = strapi => { }; } - if (((cluster.isWorker && strapi.config.reload.workers > 0) || (cluster.isMaster && strapi.config.reload.workers < 1)) || (!strapi.config.reload && cluster.isMaster)) { - let route; - let controller; + function routerChecker(value, endpoint, plugin) { let action; - let policies = []; + const route = regex.detectRoute(endpoint); + // Check if the controller is a function. + if (typeof value.controller === 'function') { + action = value.controller; + } else { + const controller = strapi.controllers[value.controller.toLowerCase()] || strapi.plugins[plugin].controllers[value.controller.toLowerCase()]; + action = controller[value.action]; + } + + // Init policies array. + const policies = []; + + // Add the `globalPolicy`. + policies.push(globalPolicy(endpoint, value, route)); + + // Add the `responsesPolicy`. + policies.push(responsesPolicy); + + if (_.isArray(value.policies) && !_.isEmpty(value.policies)) { + _.forEach(value.policies, policy => { + if (strapi.policies[policy]) { + policies.push(strapi.policies[policy]); + } else { + strapi.log.error('Ignored attempt to bind route `' + endpoint + '` with unknown policy `' + policy + '`.'); + process.exit(1); + } + }); + } + + return { + route: route, + policies: policies, + action: action + }; + } + + if (((cluster.isWorker && strapi.config.reload.workers > 0) || (cluster.isMaster && strapi.config.reload.workers < 1)) || (!strapi.config.reload && cluster.isMaster)) { // Initialize the router. if (!strapi.router) { strapi.router = strapi.middlewares.router({ @@ -66,43 +100,50 @@ module.exports = strapi => { }); } - // Add response policy to the global variable + // Add response policy to the global variable. _.set(strapi.policies, 'responsesPolicy', responsesPolicy); // Parse each route from the user config, load policies if any // and match the controller and action to the desired endpoint. - _.forEach(strapi.config.routes, (value, endpoint) => { + _.forEach(_.omit(strapi.config.routes, 'plugins'), (value, endpoint) => { try { - route = regex.detectRoute(endpoint); + const { route, policies, action } = routerChecker(value, endpoint); - // Check if the controller is a function. - if (typeof value.controller === 'function') { - action = value.controller; - } else { - controller = strapi.controllers[value.controller.toLowerCase()]; - action = controller[value.action]; - } + strapi.router[route.verb.toLowerCase()](route.endpoint, strapi.middlewares.compose(policies), action); + } catch (err) { + strapi.log.warn('Ignored attempt to bind route `' + endpoint + '` to unknown controller/action.'); + } + }); - // Init policies array. - policies = []; + // Parse each plugin's routes. + _.forEach(strapi.config.routes.plugins, (value, plugin) => { + try { + // Create router for each plugin. + // Prefix router with the plugin's name. + const router = strapi.middlewares.router({ + prefix: plugin + }); - // Add the `globalPolicy`. - policies.push(globalPolicy(endpoint, value, route)); + // Exclude routes with prefix. + const excludedRoutes = _.omitBy(value, o => !o.hasOwnProperty('prefix')); - // Add the `responsesPolicy`. - policies.push(responsesPolicy); + // Add others routes to the plugin's router. + _.forEach(_.omit(value, _.keys(excludedRoutes)), (value, endpoint) => { + const { route, policies, action } = routerChecker(value, endpoint, plugin); - if (_.isArray(value.policies) && !_.isEmpty(value.policies)) { - _.forEach(value.policies, policy => { - if (strapi.policies[policy]) { - policies.push(strapi.policies[policy]); - } else { - strapi.log.error('Ignored attempt to bind route `' + endpoint + '` with unknown policy `' + policy + '`.'); - process.exit(1); - } + router[route.verb.toLowerCase()](route.endpoint, strapi.middlewares.compose(policies), action); + }); + + // /!\ Could override main router's routes. + if (!_.isEmpty(excludedRoutes)) { + _.forEach(excludedRoutes, (value, endpoint) => { + const { route, policies, action } = routerChecker(value, endpoint, plugin); + + strapi.router[route.verb.toLowerCase()](route.endpoint, strapi.middlewares.compose(policies), action); }); } - strapi.router[route.verb.toLowerCase()](route.endpoint, strapi.middlewares.compose(policies), action); + + strapi.router.use(router.routes(), router.allowedMethods()); } catch (err) { strapi.log.warn('Ignored attempt to bind route `' + endpoint + '` to unknown controller/action.'); } diff --git a/packages/strapi/lib/configuration/hooks/dictionary/_plugins/index.js b/packages/strapi/lib/configuration/hooks/dictionary/_plugins/index.js index 434d64232b..6d3e3dfa02 100644 --- a/packages/strapi/lib/configuration/hooks/dictionary/_plugins/index.js +++ b/packages/strapi/lib/configuration/hooks/dictionary/_plugins/index.js @@ -133,7 +133,10 @@ module.exports = strapi => { }; // Delete the definition if it's empty. - strapi.plugins[plugin.name] = _.omitBy(strapi.plugins[plugin.name], _.isEmpty); + strapi.plugins[plugin.name] = _.omitBy(_.get(strapi.plugins, plugin.name), _.isEmpty); + + // Merge API routes with the main ones. + _.set(strapi.config.routes, 'plugins.' + plugin.name, _.get(strapi.plugins, plugin.name + '.config.routes')); // If the module doesn't have a definition at all // just remove it completely from the dictionary.