From f22ae796a08b22210d3ae12294813799a9c0348b Mon Sep 17 00:00:00 2001 From: Jesse Ditson Date: Fri, 10 Feb 2017 14:20:18 -0800 Subject: [PATCH] Add support for routing to an index file inside of a named folder --- index.js | 16 ++++++++++-- test/fixtures/index/conflict.js | 1 + test/fixtures/index/conflict/index.js | 1 + test/fixtures/index/index.js | 1 + test/fixtures/index/test/:param/index.js | 1 + test/fixtures/index/thing/index.js | 1 + test/index-test.js | 32 ++++++++++++++++++++++++ 7 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 test/fixtures/index/conflict.js create mode 100644 test/fixtures/index/conflict/index.js create mode 100644 test/fixtures/index/index.js create mode 100644 test/fixtures/index/test/:param/index.js create mode 100644 test/fixtures/index/thing/index.js create mode 100644 test/index-test.js diff --git a/index.js b/index.js index 2fc5645..12b2823 100644 --- a/index.js +++ b/index.js @@ -13,8 +13,14 @@ function addMatch(route) { routePath = routePath.replace(paramPattern, '([^\?\/]+)') paramNames.push(matched[1]) } + // if a route ends with `index`, allow matching that route without matching the `index` part + if (path.basename(routePath) === 'index') { + route.isIndex = true + routePath = routePath.replace(/\/index$/, '\/?(:?index)?') + } // create a regex with our path - let pattern = new RegExp(`^${routePath}\\??(.*)`, 'i') + let pattern = new RegExp(`^${routePath}(\\?(.*)|$)`, 'i') + route.pattern = pattern route.match = url => { let m = url.match(pattern) if (m) { @@ -51,9 +57,15 @@ module.exports = function router(routesDir) { } return route }) + // add a match function + .map(addMatch) + // sort named files ahead of subfolder index files + .map(route => { + if (!route.priority && route.isIndex) route.priority = -1 + return route + }) // if a route exposes a `priority` property, sort the route on it. .sort((a, b) => val(a.priority) < val(b.priority) ? 1 : -1) - .map(addMatch) // generated match method - call with a req object to get a route. return function match(req) { diff --git a/test/fixtures/index/conflict.js b/test/fixtures/index/conflict.js new file mode 100644 index 0000000..4bbcfd2 --- /dev/null +++ b/test/fixtures/index/conflict.js @@ -0,0 +1 @@ +module.exports = () => 'conflict' diff --git a/test/fixtures/index/conflict/index.js b/test/fixtures/index/conflict/index.js new file mode 100644 index 0000000..9f71342 --- /dev/null +++ b/test/fixtures/index/conflict/index.js @@ -0,0 +1 @@ +module.exports = () => 'conflict/index' diff --git a/test/fixtures/index/index.js b/test/fixtures/index/index.js new file mode 100644 index 0000000..4fe53dc --- /dev/null +++ b/test/fixtures/index/index.js @@ -0,0 +1 @@ +module.exports = () => 'index' diff --git a/test/fixtures/index/test/:param/index.js b/test/fixtures/index/test/:param/index.js new file mode 100644 index 0000000..1d2f853 --- /dev/null +++ b/test/fixtures/index/test/:param/index.js @@ -0,0 +1 @@ +module.exports = () => 'test/:param' diff --git a/test/fixtures/index/thing/index.js b/test/fixtures/index/thing/index.js new file mode 100644 index 0000000..0d2c4e5 --- /dev/null +++ b/test/fixtures/index/thing/index.js @@ -0,0 +1 @@ +module.exports = () => 'thing' diff --git a/test/index-test.js b/test/index-test.js new file mode 100644 index 0000000..799c72c --- /dev/null +++ b/test/index-test.js @@ -0,0 +1,32 @@ +const test = require('tape') +const router = require('..') + +let match = router(__dirname + '/fixtures/index') + +test('uses index.js when the root is requested', t => { + t.plan(2) + let req = { url: '/', method: 'GET' } + t.equal(typeof match(req), 'function', 'finds a route') + t.equal(match(req)(), 'index', 'finds the index route') +}) + +test('uses index.js of a subfolder', t => { + t.plan(2) + let req = { url: '/thing', method: 'GET' } + t.equal(typeof match(req), 'function', 'finds a route') + t.equal(match(req)(), 'thing', 'finds the right route') +}) + +test('uses index.js of a parameter', t => { + t.plan(2) + let req = { url: '/test/foo', method: 'GET' } + t.equal(typeof match(req), 'function', 'finds a route') + t.equal(match(req)(), 'test/:param', 'finds the right route') +}) + +test('prefers a .js file to a nested index file when there is a conflict', t => { + t.plan(2) + let req = { url: '/conflict', method: 'GET' } + t.equal(typeof match(req), 'function', 'finds a route') + t.equal(match(req)(), 'conflict', 'finds the right route') +})