Skip to content

Commit bace812

Browse files
committed
[feat] Routes as Map
Keeps Sorted Order in Place.
1 parent 324ea45 commit bace812

File tree

7 files changed

+155
-22
lines changed

7 files changed

+155
-22
lines changed

lib/RouterSpool.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import * as pkg from '../package.json'
1818
* @see https://github.com/fabrix-app/spool-hapi
1919
*/
2020
export class RouterSpool extends SystemSpool {
21-
private _routes = {}
21+
private _routes: Map<string, {[key: string]: any}> // = new Map
2222

2323
constructor (app) {
2424
super(app, {
@@ -63,7 +63,7 @@ export class RouterSpool extends SystemSpool {
6363
/**
6464
* Get's the routes from spool-router
6565
*/
66-
get routes(): {[key: string]: any} {
66+
get routes(): Map<string, {[key: string]: any}> {
6767
return this._routes
6868
}
6969

lib/config/router.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export const router = {
22
prefix: null,
3-
sortOrder: 'asc'
3+
sortOrder: 'asc',
4+
debug: false
45
}

lib/schemas/router.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ import * as joi from 'joi'
22

33
export const routerSchema = joi.object().keys({
44
sortOrder: joi.string().allow('asc', 'desc').required(),
5-
prefix: joi.string().allow('', null).required()
5+
prefix: joi.string().allow('', null).required(),
6+
debug: joi.any()
67
})

lib/utils.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,19 @@ export const Utils = {
2121
*/
2222
buildRoute (app: FabrixApp, path: string, rawRoute: IRoute) {
2323
const orgRoute = Object.assign({ }, rawRoute)
24-
orgRoute._orgPath = path
2524
orgRoute.config = orgRoute.config || (orgRoute.config = { })
2625
orgRoute.config.pre = orgRoute.config.pre || (orgRoute.config.pre = [ ])
2726

27+
if (app.config.get('router.debug')) {
28+
orgRoute._orgPath = path
29+
}
30+
2831
path = Utils.getPathFromRoute(app, path, orgRoute)
32+
33+
if (app.config.get('router.debug')) {
34+
orgRoute._newPath = path
35+
}
36+
2937
Utils.getHandlerFromString(app, orgRoute)
3038

3139
orgRoute.config.pre = orgRoute.config.pre
@@ -183,10 +191,10 @@ export const Utils = {
183191
* Sort a route collection by object key
184192
*/
185193
sortRoutes(routes, order) {
186-
const toReturn = {}
194+
const toReturn = new Map
187195
const sorted = Object.keys(routes).sort(Utils.createSpecificityComparator({ order: order }))
188196
sorted.forEach((r, i) => {
189-
toReturn[r] = routes[r]
197+
toReturn.set(r, routes[r])
190198
})
191199
return toReturn
192200
},
@@ -215,19 +223,19 @@ export const Utils = {
215223
|| routeA === catchAllRoute
216224
) {
217225
return asc ? 1 : -1
218-
// Also push index route down to end, but not past the default
219226
}
227+
// Also push index route down to end, but not past the default
220228
else if (
221229
routeB === defaultRoute
222230
|| routeB === catchAllRoute
223231
) {
224232
return asc ? -1 : 1
225-
// Also push index route down to end, but not past the default
226233
}
234+
// Also push index route down to end, but not past the default
227235
else if (/^\/$/.test(routeA) && (routeB !== defaultRoute && routeB !== catchAllRoute)) {
228236
return asc ? 1 : -1
229-
// Otherwise, sort based on either depth or free variable priority
230237
}
238+
// Otherwise, sort based on either depth or free variable priority
231239
else {
232240
const slicedA = routeA.split('/') // .normalize('/' + routeA + '/').split('/').join('/')
233241
const slicedB = routeB.split('/') // .normalize('/' + routeB + '/').split('/').join('/')

test/fixtures/app.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ module.exports = {
3434
customPrefixer: {
3535
prefix: '/prefix'
3636
},
37+
router: {
38+
debug: true
39+
},
3740
routes: {
3841
'/test/foo': {
3942
'GET': 'TestController.foo'

test/integration/spool.test.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,19 @@ describe('Router Spool', () => {
1515
// assert(_.isFunction(routes[2].handler))
1616
// assert(_.isPlainObject(routes[3].handler))
1717

18-
assert(global.app.routes['/test/foo1'])
19-
assert(global.app.routes['/test/foo2'])
20-
assert(global.app.routes['/prefix/test/custom/prefix'])
18+
assert(global.app.routes.get('/test/foo1'))
19+
assert(global.app.routes.get('/test/foo2'))
20+
assert(global.app.routes.get('/prefix/test/custom/prefix'))
2121

22-
assert.equal(Object.keys(global.app.routes).length, 9)
22+
assert.equal(global.app.routes.size, 9)
2323
})
2424
})
2525

2626
describe('route #config', () => {
2727

2828
it('tags could be an array', () => {
2929
const routes = global.app.routes
30-
const route = routes['/test/foo/tags']
30+
const route = routes.get('/test/foo/tags')
3131
assert(_.isObject(route.GET.config))
3232
assert(_.isArray(route.GET.config.tags))
3333
assert(_.includes(route.GET.config.tags, 'test', 'other'))

test/unit/lib/routeSortOrder.test.js

Lines changed: 127 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ const sort = require('../../../dist/utils').Utils.sortRoutes
77
describe('Utils Route Sort Order', () => {
88
it('should exist', () => {
99
assert(routeOrder)
10+
assert(sort)
1011
})
11-
it('should sort the routes for free variables', () => {
12+
it('should sort the routes for free variables (express style)', () => {
1213
let routes = {
1314
'/a': {},
1415
'/a/:id': {},
@@ -24,9 +25,11 @@ describe('Utils Route Sort Order', () => {
2425
'/b/*': {}
2526
}
2627

27-
routes = sort(routes, {order: 'asc'})
28-
29-
assert.deepEqual(routes, {
28+
routes = sort(routes, 'asc')
29+
assert(routes)
30+
console.log(routes)
31+
const ordered = new Map()
32+
const order = {
3033
'/a': {},
3134
'/a/:id': {},
3235
'/a/*': {},
@@ -38,11 +41,15 @@ describe('Utils Route Sort Order', () => {
3841
'/b/:id/:world': {},
3942
'/b/:id/*': {},
4043
'/': {},
41-
'*': {}
44+
'*': {},
45+
}
46+
Object.keys(order).forEach(k => {
47+
ordered.set(k, order[k])
4248
})
49+
assert.deepEqual(routes, ordered)
4350
})
4451

45-
it('should sort the routes for free variables', () => {
52+
it('should sort the routes for free variables (hapi style)', () => {
4653
let routes = {
4754
'/a': {},
4855
'/a/{id}': {},
@@ -59,8 +66,49 @@ describe('Utils Route Sort Order', () => {
5966
}
6067

6168
routes = sort(routes, 'asc')
69+
assert(routes)
70+
71+
const ordered = new Map()
72+
const order = {
73+
'/a': {},
74+
'/a/{id}': {},
75+
'/a/*': {},
76+
'/a/{id}/{world}': {},
77+
'/a/{id}/*': {},
78+
'/b': {},
79+
'/b/{id}': {},
80+
'/b/*': {},
81+
'/b/{id}/{world}': {},
82+
'/b/{id}/*': {},
83+
'/': {},
84+
'*': {},
85+
}
86+
Object.keys(order).forEach(k => {
87+
ordered.set(k, order[k])
88+
})
89+
assert.deepEqual(routes, ordered)
90+
})
91+
92+
it('should sort the routes for free variables desc', () => {
93+
let routes = {
94+
'/a': {},
95+
'/a/{id}': {},
96+
'/a/*': {},
97+
'/b': {},
98+
'/a/{id}/{world}': {},
99+
'/a/{id}/*': {},
100+
'*': {},
101+
'/b/{id}/{world}': {},
102+
'/': {},
103+
'/b/{id}/*': {},
104+
'/b/{id}': {},
105+
'/b/*': {},
106+
}
62107

63-
assert.deepEqual(routes, {
108+
routes = sort(routes, 'desc')
109+
assert(routes)
110+
const ordered = new Map()
111+
const order = {
64112
'/a': {},
65113
'/a/{id}': {},
66114
'/a/*': {},
@@ -73,6 +121,78 @@ describe('Utils Route Sort Order', () => {
73121
'/b/{id}/*': {},
74122
'/': {},
75123
'*': {},
124+
}
125+
Object.keys(order).forEach(k => {
126+
ordered.set(k, order[k])
76127
})
128+
assert.deepEqual(routes, ordered)
129+
})
130+
131+
it('should sort the routes for free variables asc', () => {
132+
let routes = {
133+
'/a': {},
134+
'/a/{id}': {},
135+
'/a/*': {},
136+
'/b': {},
137+
'/a/{id}/{world}': {},
138+
'/a/{id}/*': {},
139+
'*': {},
140+
'/b/{id}/{world}': {},
141+
'/': {},
142+
'/b/{id}/*': {},
143+
'/b/{id}': {},
144+
'/b/*': {},
145+
}
146+
147+
const order = Object.keys(routes).sort(routeOrder({order: 'asc'}))
148+
assert.deepEqual(order, [
149+
'/a',
150+
'/a/{id}',
151+
'/a/*',
152+
'/a/{id}/{world}',
153+
'/a/{id}/*',
154+
'/b',
155+
'/b/{id}',
156+
'/b/*',
157+
'/b/{id}/{world}',
158+
'/b/{id}/*',
159+
'/',
160+
'*',
161+
])
162+
})
163+
164+
// TODO
165+
it.skip('should sort the routes for free variables desc', () => {
166+
let routes = {
167+
'/a': {},
168+
'/a/{id}': {},
169+
'/a/*': {},
170+
'/b': {},
171+
'/a/{id}/{world}': {},
172+
'/a/{id}/*': {},
173+
'*': {},
174+
'/b/{id}/{world}': {},
175+
'/': {},
176+
'/b/{id}/*': {},
177+
'/b/{id}': {},
178+
'/b/*': {},
179+
}
180+
181+
const order = Object.keys(routes).sort(routeOrder({order: 'desc'}))
182+
console.log('BROKE', order)
183+
assert.deepEqual(order, [
184+
'*',
185+
'/',
186+
'/b/{id}/*',
187+
'/b/{id}/{world}',
188+
'/b/*',
189+
'/b/{id}',
190+
'/b',
191+
'/a/{id}/*',
192+
'/a/{id}/{world}',
193+
'/a/*',
194+
'/a/{id}',
195+
'/a'
196+
])
77197
})
78198
})

0 commit comments

Comments
 (0)