mirror of
https://github.com/nuxt/nuxt.git
synced 2025-02-17 06:01:34 +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
|
return routes
|
||||||
}
|
}
|
||||||
|
|
||||||
const DYNAMIC_ROUTE_REGEX = /^\/([:*])/
|
const DYNAMIC_ROUTE_REGEX = /[:*]/
|
||||||
|
|
||||||
export const sortRoutes = function sortRoutes (routes) {
|
export const sortRoutes = function sortRoutes (routes) {
|
||||||
routes.sort((a, b) => {
|
routes.sort((a, b) => {
|
||||||
@ -126,13 +126,13 @@ export const sortRoutes = function sortRoutes (routes) {
|
|||||||
if (res !== 0) {
|
if (res !== 0) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
y = _a[i] === '*' ? 2 : _a[i].includes(':') ? 1 : 0
|
y = _a[i] === '*' ? 3 : _a[i].includes(':') ? 2 : _a[i].includes('*') ? 1 : 0
|
||||||
z = _b[i] === '*' ? 2 : _b[i].includes(':') ? 1 : 0
|
z = _b[i] === '*' ? 3 : _b[i].includes(':') ? 2 : _b[i].includes('*') ? 1 : 0
|
||||||
res = y - z
|
res = y - z
|
||||||
// If a.length >= b.length
|
// If a.length >= b.length
|
||||||
if (i === _b.length - 1 && res === 0) {
|
if (i === _b.length - 1 && res === 0) {
|
||||||
// unless * found sort by level, then alphabetically
|
// unless * found sort by level, then alphabetically
|
||||||
res = _a[i] === '*'
|
res = _a[i].includes('*')
|
||||||
? -1
|
? -1
|
||||||
: (
|
: (
|
||||||
_a.length === _b.length ? a.path.localeCompare(b.path) : (_a.length - _b.length)
|
_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) {
|
if (res === 0) {
|
||||||
// unless * found sort by level, then alphabetically
|
// unless * found sort by level, then alphabetically
|
||||||
res = _a[i - 1] === '*' && _b[i]
|
res = _a[i - 1].includes('*') && _b[i]
|
||||||
? 1
|
? 1
|
||||||
: (
|
: (
|
||||||
_a.length === _b.length ? a.path.localeCompare(b.path) : (_a.length - _b.length)
|
_a.length === _b.length ? a.path.localeCompare(b.path) : (_a.length - _b.length)
|
||||||
@ -248,7 +248,6 @@ const getRoutePathExtension = (key) => {
|
|||||||
if (key.startsWith('_')) {
|
if (key.startsWith('_')) {
|
||||||
return `:${key.substr(1)}`
|
return `:${key.substr(1)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
return key
|
return key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,12 @@ exports[`util: route util: route create createRoutes should allow snake case rou
|
|||||||
"name": "parent-child-test",
|
"name": "parent-child-test",
|
||||||
"path": "/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",
|
"chunkName": "pages/another_route/_id",
|
||||||
"component": "/some/nuxt/app/pages/another_route/_id.vue",
|
"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",
|
"name": "parent-all",
|
||||||
"path": "/parent/*",
|
"path": "/parent/*",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"chunkName": "pages/index",
|
|
||||||
"component": "/some/nuxt/app/pages/index.vue",
|
|
||||||
"name": "index",
|
|
||||||
"path": "/",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"chunkName": "pages/_param",
|
"chunkName": "pages/_param",
|
||||||
"component": "/some/nuxt/app/pages/_param.vue",
|
"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",
|
"name": "parent-child-test",
|
||||||
"path": "/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",
|
"chunkName": "pages/another_route/_id",
|
||||||
"component": "\\\\\\\\some\\\\nuxt\\\\app\\\\pages\\\\another_route\\\\_id.vue",
|
"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",
|
"name": "parent-all",
|
||||||
"path": "/parent/*",
|
"path": "/parent/*",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"chunkName": "pages/index",
|
|
||||||
"component": "\\\\\\\\some\\\\nuxt\\\\app\\\\pages\\\\index.vue",
|
|
||||||
"name": "index",
|
|
||||||
"path": "/",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"chunkName": "pages/_param",
|
"chunkName": "pages/_param",
|
||||||
"component": "\\\\\\\\some\\\\nuxt\\\\app\\\\pages\\\\_param.vue",
|
"component": "\\\\\\\\some\\\\nuxt\\\\app\\\\pages\\\\_param.vue",
|
||||||
@ -156,6 +156,15 @@ exports[`util: route util: route create createRoutes should enforce trailing sla
|
|||||||
"strict": true,
|
"strict": true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"chunkName": "pages/index",
|
||||||
|
"component": "/some/nuxt/app/pages/index.vue",
|
||||||
|
"name": "index",
|
||||||
|
"path": "/",
|
||||||
|
"pathToRegexpOptions": {
|
||||||
|
"strict": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"chunkName": "pages/another_route/_id",
|
"chunkName": "pages/another_route/_id",
|
||||||
"component": "/some/nuxt/app/pages/another_route/_id.vue",
|
"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,
|
"strict": true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"chunkName": "pages/index",
|
|
||||||
"component": "/some/nuxt/app/pages/index.vue",
|
|
||||||
"name": "index",
|
|
||||||
"path": "/",
|
|
||||||
"pathToRegexpOptions": {
|
|
||||||
"strict": true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"chunkName": "pages/_param",
|
"chunkName": "pages/_param",
|
||||||
"component": "/some/nuxt/app/pages/_param.vue",
|
"component": "/some/nuxt/app/pages/_param.vue",
|
||||||
@ -242,6 +242,15 @@ exports[`util: route util: route create createRoutes should remove trailing slas
|
|||||||
"strict": true,
|
"strict": true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"chunkName": "pages/index",
|
||||||
|
"component": "/some/nuxt/app/pages/index.vue",
|
||||||
|
"name": "index",
|
||||||
|
"path": "/",
|
||||||
|
"pathToRegexpOptions": {
|
||||||
|
"strict": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"chunkName": "pages/another_route/_id",
|
"chunkName": "pages/another_route/_id",
|
||||||
"component": "/some/nuxt/app/pages/another_route/_id.vue",
|
"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,
|
"strict": true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"chunkName": "pages/index",
|
|
||||||
"component": "/some/nuxt/app/pages/index.vue",
|
|
||||||
"name": "index",
|
|
||||||
"path": "/",
|
|
||||||
"pathToRegexpOptions": {
|
|
||||||
"strict": true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"chunkName": "pages/_param",
|
"chunkName": "pages/_param",
|
||||||
"component": "/some/nuxt/app/pages/_param.vue",
|
"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', () => {
|
describe('util: route', () => {
|
||||||
test('should flat route with path', () => {
|
test('should flat route with path', () => {
|
||||||
@ -238,4 +238,109 @@ describe('util: route', () => {
|
|||||||
expect(routesResult).toMatchSnapshot()
|
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
|
// pages/test/songs/toto.vue
|
||||||
expect(routes[5].path).toBe('/test/songs/toto')
|
expect(routes[5].path).toBe('/test/songs/toto')
|
||||||
expect(routes[5].name).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
|
// pages/index.vue
|
||||||
expect(routes[10].path).toBe('/')
|
expect(routes[6].path).toBe('/')
|
||||||
expect(routes[10].name).toBe('index')
|
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
|
// pages/_slug.vue
|
||||||
expect(routes[11].path).toBe('/:slug')
|
expect(routes[11].path).toBe('/:slug')
|
||||||
expect(routes[11].name).toBe('slug')
|
expect(routes[11].name).toBe('slug')
|
||||||
|
Loading…
Reference in New Issue
Block a user