diff --git a/CHANGELOG.md b/CHANGELOG.md index 16f47bd8..3a92a7b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## Unreleased +### Added option to allow output routes to be registered before provider routes; if true any conflicts will default to output routes + ## [3.17.3] - 2020-03-26 ### Fixed * Prevent overwriting cache and option assignments that occur in provider model constructors diff --git a/src/helpers/register-plugin-routes.js b/src/helpers/register-plugin-routes.js index e744ca42..c7443aa6 100644 --- a/src/helpers/register-plugin-routes.js +++ b/src/helpers/register-plugin-routes.js @@ -2,7 +2,7 @@ const _ = require('lodash') const validateHttpMethods = require('./validate-http-methods') const composeRouteString = require('./compose-route-string') -function registerProviderRoutes ({ provider, controller, server, pluginRoutes }, options = {}) { +function registerPluginRoutes ({ provider, controller, server, pluginRoutes }, options = {}) { const namespace = provider.namespace.replace(/\s/g, '').toLowerCase() const { hosts, disableIdParam } = provider const { routePrefix } = options @@ -58,4 +58,4 @@ function addMethodsToRouteMap (map, path, methods) { _.set(map, path, _.concat(existingMethods, methods)) } -module.exports = registerProviderRoutes +module.exports = registerPluginRoutes diff --git a/src/index.js b/src/index.js index 5e62637e..492bb422 100644 --- a/src/index.js +++ b/src/index.js @@ -35,7 +35,8 @@ const providerOptionsSchema = Joi.object({ routePrefix: Joi.string().optional(), before: Joi.function().arity(2).optional(), after: Joi.function().arity(3).optional(), - name: Joi.string().optional() + name: Joi.string().optional(), + defaultToOutputRoutes: Joi.boolean().optional() }).unknown(true) function Koop (config) { @@ -202,11 +203,21 @@ function extend (klass, extender) { * @param {object} controller - the initiated provider's controller * @param {object} server - the koop express server */ -function registerRoutes ({ provider, controller, server, pluginRoutes }, options) { - // Provider-routes are bound first; any routing conflicts will result in requests routed to provider - const providerRouteMap = registerProviderRoutes({ provider, controller, server }, options) +function registerRoutes ({ provider, controller, server, pluginRoutes }, options = {}) { + // Plugin and provider-routes may conflict; which ever is registered first gets precendence; default is provider route precedence + if (options.defaultToOutputRoutes) return registerPluginRoutesFirst({ provider, controller, server, pluginRoutes }, options) + return registerProviderRoutesFirst({ provider, controller, server, pluginRoutes }, options) +} + +function registerPluginRoutesFirst ({ provider, controller, server, pluginRoutes }, options = {}) { const pluginRouteMap = registerPluginRoutes({ provider, controller, server, pluginRoutes }, options) + const providerRouteMap = registerProviderRoutes({ provider, controller, server }, options) + return { providerRouteMap, pluginRouteMap } +} +function registerProviderRoutesFirst ({ provider, controller, server, pluginRoutes }, options = {}) { + const providerRouteMap = registerProviderRoutes({ provider, controller, server }, options) + const pluginRouteMap = registerPluginRoutes({ provider, controller, server, pluginRoutes }, options) return { providerRouteMap, pluginRouteMap } } diff --git a/test/index-test.js b/test/index-test.js index e9d06748..14e71cce 100644 --- a/test/index-test.js +++ b/test/index-test.js @@ -41,6 +41,18 @@ describe('Index tests for registering providers', function () { providerRouteIndex.should.be.below(pluginRouteIndex) }) + it('should register plugin-routes before provider-routes', function () { + const koop = new Koop() + koop.register(_.cloneDeep(provider), { defaultToOutputRoutes: true }) + // Check that the stack index of the plugin routes are prior to index of provider routes + const routePaths = koop.server._router.stack + .filter((layer) => { return _.has(layer, 'route.path') }) + .map(layer => { return _.get(layer, 'route.path') }) + const pluginRouteIndex = routePaths.findIndex(path => path.includes('/test-provider/:id/FeatureServer')) + const providerRouteIndex = routePaths.findIndex(path => path.includes('/fake/:id')) + pluginRouteIndex.should.be.below(providerRouteIndex) + }) + it('should register successfully and attach cache and options object to model', function () { const koop = new Koop() koop.register(_.cloneDeep(provider), { routePrefix: 'path-to-route' })