mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 08:33:53 +00:00
fix(utils): respect patterns within paths when sorting routes (#20669)
This commit is contained in:
parent
10787e325b
commit
5e9942b007
@ -97,7 +97,7 @@ function cleanChildrenRoutes (routes, isChild = false, routeNameSplitter = '-',
|
||||
return routes
|
||||
}
|
||||
|
||||
const DYNAMIC_ROUTE_REGEX = /^\/([:*])/
|
||||
const DYNAMIC_ROUTE_REGEX = /[:*]/
|
||||
|
||||
export const sortRoutes = function sortRoutes (routes) {
|
||||
routes.sort((a, b) => {
|
||||
@ -126,13 +126,13 @@ export const sortRoutes = function sortRoutes (routes) {
|
||||
if (res !== 0) {
|
||||
break
|
||||
}
|
||||
y = _a[i] === '*' ? 2 : _a[i].includes(':') ? 1 : 0
|
||||
z = _b[i] === '*' ? 2 : _b[i].includes(':') ? 1 : 0
|
||||
y = _a[i] === '*' ? 3 : _a[i].includes(':') ? 2 : _a[i].includes('*') ? 1 : 0
|
||||
z = _b[i] === '*' ? 3 : _b[i].includes(':') ? 2 : _b[i].includes('*') ? 1 : 0
|
||||
res = y - z
|
||||
// If a.length >= b.length
|
||||
if (i === _b.length - 1 && res === 0) {
|
||||
// unless * found sort by level, then alphabetically
|
||||
res = _a[i] === '*'
|
||||
res = _a[i].includes('*')
|
||||
? -1
|
||||
: (
|
||||
_a.length === _b.length ? a.path.localeCompare(b.path) : (_a.length - _b.length)
|
||||
@ -142,7 +142,7 @@ export const sortRoutes = function sortRoutes (routes) {
|
||||
|
||||
if (res === 0) {
|
||||
// unless * found sort by level, then alphabetically
|
||||
res = _a[i - 1] === '*' && _b[i]
|
||||
res = _a[i - 1].includes('*') && _b[i]
|
||||
? 1
|
||||
: (
|
||||
_a.length === _b.length ? a.path.localeCompare(b.path) : (_a.length - _b.length)
|
||||
@ -248,7 +248,6 @@ const getRoutePathExtension = (key) => {
|
||||
if (key.startsWith('_')) {
|
||||
return `:${key.substr(1)}`
|
||||
}
|
||||
|
||||
return key
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,12 @@ exports[`util: route util: route create createRoutes should allow snake case rou
|
||||
"name": "parent-child-test",
|
||||
"path": "/parent/child/test",
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/index",
|
||||
"component": "/some/nuxt/app/pages/index.vue",
|
||||
"name": "index",
|
||||
"path": "/",
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/another_route/_id",
|
||||
"component": "/some/nuxt/app/pages/another_route/_id.vue",
|
||||
@ -44,12 +50,6 @@ exports[`util: route util: route create createRoutes should allow snake case rou
|
||||
"name": "parent-all",
|
||||
"path": "/parent/*",
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/index",
|
||||
"component": "/some/nuxt/app/pages/index.vue",
|
||||
"name": "index",
|
||||
"path": "/",
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/_param",
|
||||
"component": "/some/nuxt/app/pages/_param.vue",
|
||||
@ -85,6 +85,12 @@ exports[`util: route util: route create createRoutes should allow snake case rou
|
||||
"name": "parent-child-test",
|
||||
"path": "/parent/child/test",
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/index",
|
||||
"component": "\\\\\\\\some\\\\nuxt\\\\app\\\\pages\\\\index.vue",
|
||||
"name": "index",
|
||||
"path": "/",
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/another_route/_id",
|
||||
"component": "\\\\\\\\some\\\\nuxt\\\\app\\\\pages\\\\another_route\\\\_id.vue",
|
||||
@ -103,12 +109,6 @@ exports[`util: route util: route create createRoutes should allow snake case rou
|
||||
"name": "parent-all",
|
||||
"path": "/parent/*",
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/index",
|
||||
"component": "\\\\\\\\some\\\\nuxt\\\\app\\\\pages\\\\index.vue",
|
||||
"name": "index",
|
||||
"path": "/",
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/_param",
|
||||
"component": "\\\\\\\\some\\\\nuxt\\\\app\\\\pages\\\\_param.vue",
|
||||
@ -156,6 +156,15 @@ exports[`util: route util: route create createRoutes should enforce trailing sla
|
||||
"strict": true,
|
||||
},
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/index",
|
||||
"component": "/some/nuxt/app/pages/index.vue",
|
||||
"name": "index",
|
||||
"path": "/",
|
||||
"pathToRegexpOptions": {
|
||||
"strict": true,
|
||||
},
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/another_route/_id",
|
||||
"component": "/some/nuxt/app/pages/another_route/_id.vue",
|
||||
@ -183,15 +192,6 @@ exports[`util: route util: route create createRoutes should enforce trailing sla
|
||||
"strict": true,
|
||||
},
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/index",
|
||||
"component": "/some/nuxt/app/pages/index.vue",
|
||||
"name": "index",
|
||||
"path": "/",
|
||||
"pathToRegexpOptions": {
|
||||
"strict": true,
|
||||
},
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/_param",
|
||||
"component": "/some/nuxt/app/pages/_param.vue",
|
||||
@ -242,6 +242,15 @@ exports[`util: route util: route create createRoutes should remove trailing slas
|
||||
"strict": true,
|
||||
},
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/index",
|
||||
"component": "/some/nuxt/app/pages/index.vue",
|
||||
"name": "index",
|
||||
"path": "/",
|
||||
"pathToRegexpOptions": {
|
||||
"strict": true,
|
||||
},
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/another_route/_id",
|
||||
"component": "/some/nuxt/app/pages/another_route/_id.vue",
|
||||
@ -269,15 +278,6 @@ exports[`util: route util: route create createRoutes should remove trailing slas
|
||||
"strict": true,
|
||||
},
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/index",
|
||||
"component": "/some/nuxt/app/pages/index.vue",
|
||||
"name": "index",
|
||||
"path": "/",
|
||||
"pathToRegexpOptions": {
|
||||
"strict": true,
|
||||
},
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/_param",
|
||||
"component": "/some/nuxt/app/pages/_param.vue",
|
||||
@ -289,3 +289,93 @@ exports[`util: route util: route create createRoutes should remove trailing slas
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`util: route util: route sortRoutes sortRoutes should sort routes 1`] = `
|
||||
[
|
||||
{
|
||||
"chunkName": "pages/de/index",
|
||||
"component": "/some/nuxt/app/pages/de/index.vue",
|
||||
"name": "de",
|
||||
"path": "/de",
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/de_",
|
||||
"component": "/some/nuxt/app/pages/de_.vue",
|
||||
"name": "de_",
|
||||
"path": "/de_",
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/parent/index",
|
||||
"component": "/some/nuxt/app/pages/parent/index.vue",
|
||||
"name": "parent",
|
||||
"path": "/parent",
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/snake_case_route",
|
||||
"component": "/some/nuxt/app/pages/snake_case_route.vue",
|
||||
"name": "snake_case_route",
|
||||
"path": "/snake_case_route",
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"chunkName": "pages/another_route/rout_",
|
||||
"component": "/some/nuxt/app/pages/another_route/rout_.vue",
|
||||
"name": "another_route-rout_",
|
||||
"path": "",
|
||||
},
|
||||
],
|
||||
"chunkName": "pages/another_route/rout_",
|
||||
"component": "/some/nuxt/app/pages/another_route/rout_.vue",
|
||||
"path": "/another_route/rout_",
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/parent/child/index",
|
||||
"component": "/some/nuxt/app/pages/parent/child/index.vue",
|
||||
"name": "parent-child",
|
||||
"path": "/parent/child",
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/parent/child/test",
|
||||
"component": "/some/nuxt/app/pages/parent/child/test.vue",
|
||||
"name": "parent-child-test",
|
||||
"path": "/parent/child/test",
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/index",
|
||||
"component": "/some/nuxt/app/pages/index.vue",
|
||||
"name": "index",
|
||||
"path": "/",
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/another_route/_id",
|
||||
"component": "/some/nuxt/app/pages/another_route/_id.vue",
|
||||
"name": "another_route-id",
|
||||
"path": "/another_route/:id?",
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/subpage/_param",
|
||||
"component": "/some/nuxt/app/pages/subpage/_param.vue",
|
||||
"name": "subpage-param",
|
||||
"path": "/subpage/:param?",
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/parent/_",
|
||||
"component": "/some/nuxt/app/pages/parent/_.vue",
|
||||
"name": "parent-all",
|
||||
"path": "/parent/*",
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/_param",
|
||||
"component": "/some/nuxt/app/pages/_param.vue",
|
||||
"name": "param",
|
||||
"path": "/:param",
|
||||
},
|
||||
{
|
||||
"chunkName": "pages/_",
|
||||
"component": "/some/nuxt/app/pages/_.vue",
|
||||
"name": "all",
|
||||
"path": "/*",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { flatRoutes, createRoutes, guardDir, promisifyRoute } from '../src/route'
|
||||
import { flatRoutes, createRoutes, guardDir, promisifyRoute, sortRoutes } from '../src/route'
|
||||
|
||||
describe('util: route', () => {
|
||||
test('should flat route with path', () => {
|
||||
@ -238,4 +238,109 @@ describe('util: route', () => {
|
||||
expect(routesResult).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
|
||||
describe('util: route sortRoutes', () => {
|
||||
const files = [
|
||||
'pages/_param.vue',
|
||||
'pages/de/index.vue',
|
||||
'pages/index.vue',
|
||||
'pages/_.vue',
|
||||
'pages/another_route/rout_.vue',
|
||||
'pages/snake_case_route.vue',
|
||||
'pages/subpage/_param.vue',
|
||||
'pages/de_.vue',
|
||||
'pages/parent/index.vue',
|
||||
'pages/parent/_.vue',
|
||||
'pages/another_route/_id.vue',
|
||||
'pages/another_route/rout_.vue',
|
||||
'pages/parent/child/index.vue',
|
||||
'pages/parent/child/test.vue'
|
||||
]
|
||||
const srcDir = '/some/nuxt/app'
|
||||
const pagesDir = 'pages'
|
||||
|
||||
test.posix('sortRoutes should sort routes', () => {
|
||||
const routesResult = createRoutes({ files, srcDir, pagesDir })
|
||||
expect(routesResult).toMatchSnapshot()
|
||||
})
|
||||
test('Should sortRoutes with extendRoutes using *', () => {
|
||||
const routes = [
|
||||
{ path: '/poetry' },
|
||||
{ path: '/reports' },
|
||||
{ path: '*' },
|
||||
{ path: '/de/about' },
|
||||
{ path: '/' },
|
||||
{ path: '/about' },
|
||||
{ path: '/de' },
|
||||
{ path: '/tech' },
|
||||
{ path: '/de/tech' },
|
||||
{ path: '/de*' },
|
||||
{ path: '/:post' },
|
||||
{ path: '/de/:post' },
|
||||
{ path: '/de/reports' },
|
||||
{ path: '/de/poetry' }
|
||||
]
|
||||
|
||||
sortRoutes(routes)
|
||||
|
||||
expect(routes).toEqual(
|
||||
[
|
||||
{ path: '/about' },
|
||||
{ path: '/de' },
|
||||
{ path: '/poetry' },
|
||||
{ path: '/reports' },
|
||||
{ path: '/tech' },
|
||||
{ path: '/de/about' },
|
||||
{ path: '/de/poetry' },
|
||||
{ path: '/de/reports' },
|
||||
{ path: '/de/tech' },
|
||||
{ path: '/' },
|
||||
{ path: '/de/:post' },
|
||||
{ path: '/de*' },
|
||||
{ path: '/:post' },
|
||||
{ path: '*' }
|
||||
]
|
||||
)
|
||||
})
|
||||
|
||||
test('Should sortRoutes with extendRoutes using /*', () => {
|
||||
const routes = [
|
||||
{ path: '/poetry' },
|
||||
{ path: '/reports' },
|
||||
{ path: '/*' },
|
||||
{ path: '/de/about' },
|
||||
{ path: '/about' },
|
||||
{ path: '/de' },
|
||||
{ path: '/tech' },
|
||||
{ path: '/de/tech' },
|
||||
{ path: '/de/*' },
|
||||
{ path: '/' },
|
||||
{ path: '/:post' },
|
||||
{ path: '/de/:post' },
|
||||
{ path: '/de/reports' },
|
||||
{ path: '/de/poetry' }
|
||||
]
|
||||
|
||||
sortRoutes(routes)
|
||||
|
||||
expect(routes).toEqual(
|
||||
[
|
||||
{ path: '/about' },
|
||||
{ path: '/de' },
|
||||
{ path: '/poetry' },
|
||||
{ path: '/reports' },
|
||||
{ path: '/tech' },
|
||||
{ path: '/de/about' },
|
||||
{ path: '/de/poetry' },
|
||||
{ path: '/de/reports' },
|
||||
{ path: '/de/tech' },
|
||||
{ path: '/' },
|
||||
{ path: '/de/:post' },
|
||||
{ path: '/de/*' },
|
||||
{ path: '/:post' },
|
||||
{ path: '/*' }
|
||||
]
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -54,23 +54,23 @@ describe('dynamic routes', () => {
|
||||
// pages/test/songs/toto.vue
|
||||
expect(routes[5].path).toBe('/test/songs/toto')
|
||||
expect(routes[5].name).toBe('test-songs-toto')
|
||||
// pages/test/projects/_category.vue
|
||||
expect(routes[6].path).toBe('/test/projects/:category')
|
||||
expect(routes[6].name).toBe('test-projects-category')
|
||||
// pages/test/songs/_id.vue
|
||||
expect(routes[7].path).toBe('/test/songs/:id?')
|
||||
expect(routes[7].name).toBe('test-songs-id')
|
||||
// pages/users/_id.vue
|
||||
expect(routes[8].path).toBe('/users/:id?')
|
||||
expect(routes[8].name).toBe('users-id')
|
||||
// pages/test/_.vue
|
||||
expect(routes[9].path).toBe('/test/*')
|
||||
expect(routes[9].name).toBe('test-all')
|
||||
|
||||
// pages/index.vue
|
||||
expect(routes[10].path).toBe('/')
|
||||
expect(routes[10].name).toBe('index')
|
||||
expect(routes[6].path).toBe('/')
|
||||
expect(routes[6].name).toBe('index')
|
||||
|
||||
// pages/test/projects/_category.vue
|
||||
expect(routes[7].path).toBe('/test/projects/:category')
|
||||
expect(routes[7].name).toBe('test-projects-category')
|
||||
// pages/test/songs/_id.vue
|
||||
expect(routes[8].path).toBe('/test/songs/:id?')
|
||||
expect(routes[8].name).toBe('test-songs-id')
|
||||
// pages/users/_id.vue
|
||||
expect(routes[9].path).toBe('/users/:id?')
|
||||
expect(routes[9].name).toBe('users-id')
|
||||
// pages/test/_.vue
|
||||
expect(routes[10].path).toBe('/test/*')
|
||||
expect(routes[10].name).toBe('test-all')
|
||||
// pages/_slug.vue
|
||||
expect(routes[11].path).toBe('/:slug')
|
||||
expect(routes[11].name).toBe('slug')
|
||||
|
Loading…
Reference in New Issue
Block a user