From 7e16960bcce26900aa01ba61f7f563068c8ed88a Mon Sep 17 00:00:00 2001 From: robertmoura <17804984+robertmoura@users.noreply.github.com> Date: Tue, 25 Jun 2024 15:36:46 +1000 Subject: [PATCH 01/15] fix(extendRoutes): override child with relative paths --- src/core/extendRoutes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/extendRoutes.ts b/src/core/extendRoutes.ts index ae03acd79..cab3d5692 100644 --- a/src/core/extendRoutes.ts +++ b/src/core/extendRoutes.ts @@ -142,7 +142,7 @@ export class EditableTreeNode { * Override the path of the route. You must ensure `params` match with the existing path. */ set path(path: string) { - if (!path.startsWith('/')) { + if (!this.node.parent && !path.startsWith('/')) { warn( `Only absolute paths are supported. Make sure that "${path}" starts with a slash "/".` ) From 87f4855bccd9dd762d50e5fe938d9af5f70a2462 Mon Sep 17 00:00:00 2001 From: robertmoura <17804984+robertmoura@users.noreply.github.com> Date: Tue, 25 Jun 2024 15:39:36 +1000 Subject: [PATCH 02/15] fix(extendRoutes): flip parent check --- src/core/extendRoutes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/extendRoutes.ts b/src/core/extendRoutes.ts index cab3d5692..b74a6081a 100644 --- a/src/core/extendRoutes.ts +++ b/src/core/extendRoutes.ts @@ -142,7 +142,7 @@ export class EditableTreeNode { * Override the path of the route. You must ensure `params` match with the existing path. */ set path(path: string) { - if (!this.node.parent && !path.startsWith('/')) { + if (this.node.parent && !path.startsWith('/')) { warn( `Only absolute paths are supported. Make sure that "${path}" starts with a slash "/".` ) From 1c77a15ed091364c4c84ae2431bd0ce11e1de7d8 Mon Sep 17 00:00:00 2001 From: robertmoura <17804984+robertmoura@users.noreply.github.com> Date: Wed, 26 Jun 2024 09:05:29 +1000 Subject: [PATCH 03/15] test(extendRoutes): add tests and fix set path --- src/core/extendRoutes.spec.ts | 18 ++++++++++++++++++ src/core/extendRoutes.ts | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/core/extendRoutes.spec.ts b/src/core/extendRoutes.spec.ts index 730a0e647..4a561c203 100644 --- a/src/core/extendRoutes.spec.ts +++ b/src/core/extendRoutes.spec.ts @@ -251,4 +251,22 @@ describe('EditableTreeNode', () => { }, ]) }) + + it('can override the path', () => { + const tree = new PrefixTree(RESOLVED_OPTIONS) + const editable = new EditableTreeNode(tree) + + const node = editable.insert('foo', 'file.vue') + const childNode = node.insert('bar/nested', 'file.vue') + + node.path = 'baz' + childNode.path = 'baz' + expect(node.path).toBe('/foo') + expect(childNode.path).toBe('baz') + + node.path = '/baz' + childNode.path = '/baz' + expect(node.path).toBe('/baz') + expect(node.path).toBe('/baz') + }) }) diff --git a/src/core/extendRoutes.ts b/src/core/extendRoutes.ts index b74a6081a..7e6600961 100644 --- a/src/core/extendRoutes.ts +++ b/src/core/extendRoutes.ts @@ -142,7 +142,7 @@ export class EditableTreeNode { * Override the path of the route. You must ensure `params` match with the existing path. */ set path(path: string) { - if (this.node.parent && !path.startsWith('/')) { + if (this.node.parent?.isRoot() && !path.startsWith('/')) { warn( `Only absolute paths are supported. Make sure that "${path}" starts with a slash "/".` ) From b940c15e43353c9c0159dbbc0c3796b9da9e92ae Mon Sep 17 00:00:00 2001 From: robertmoura <17804984+robertmoura@users.noreply.github.com> Date: Wed, 26 Jun 2024 09:17:26 +1000 Subject: [PATCH 04/15] test(extendRoutes): improve set path tests --- src/core/extendRoutes.spec.ts | 14 +++++++++----- src/core/extendRoutes.ts | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/core/extendRoutes.spec.ts b/src/core/extendRoutes.spec.ts index 4a561c203..275894476 100644 --- a/src/core/extendRoutes.spec.ts +++ b/src/core/extendRoutes.spec.ts @@ -255,18 +255,22 @@ describe('EditableTreeNode', () => { it('can override the path', () => { const tree = new PrefixTree(RESOLVED_OPTIONS) const editable = new EditableTreeNode(tree) - const node = editable.insert('foo', 'file.vue') - const childNode = node.insert('bar/nested', 'file.vue') + const childNode = node.insert('bar', 'file.vue') - node.path = 'baz' childNode.path = 'baz' + node.path = 'baz' + editable.path = 'baz' + expect(editable.path).toBe(''); expect(node.path).toBe('/foo') expect(childNode.path).toBe('baz') - - node.path = '/baz' childNode.path = '/baz' + node.path = '/baz' expect(node.path).toBe('/baz') expect(node.path).toBe('/baz') + editable.path = '/baz' + node.path = 'baz' + expect(editable.path).toBe('/baz'); + expect(node.path).toBe('baz') }) }) diff --git a/src/core/extendRoutes.ts b/src/core/extendRoutes.ts index 7e6600961..361d5c228 100644 --- a/src/core/extendRoutes.ts +++ b/src/core/extendRoutes.ts @@ -142,7 +142,7 @@ export class EditableTreeNode { * Override the path of the route. You must ensure `params` match with the existing path. */ set path(path: string) { - if (this.node.parent?.isRoot() && !path.startsWith('/')) { + if ((!this.node.parent || this.node.parent.isRoot()) && !path.startsWith('/')) { warn( `Only absolute paths are supported. Make sure that "${path}" starts with a slash "/".` ) From 4a82dc49ab18c4a1f7376eb55d82fb181b1f6991 Mon Sep 17 00:00:00 2001 From: robertmoura <17804984+robertmoura@users.noreply.github.com> Date: Wed, 26 Jun 2024 09:18:07 +1000 Subject: [PATCH 05/15] chore: lint extend routes --- src/core/extendRoutes.spec.ts | 4 ++-- src/core/extendRoutes.ts | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/core/extendRoutes.spec.ts b/src/core/extendRoutes.spec.ts index 275894476..b6f5b07b9 100644 --- a/src/core/extendRoutes.spec.ts +++ b/src/core/extendRoutes.spec.ts @@ -261,7 +261,7 @@ describe('EditableTreeNode', () => { childNode.path = 'baz' node.path = 'baz' editable.path = 'baz' - expect(editable.path).toBe(''); + expect(editable.path).toBe('') expect(node.path).toBe('/foo') expect(childNode.path).toBe('baz') childNode.path = '/baz' @@ -270,7 +270,7 @@ describe('EditableTreeNode', () => { expect(node.path).toBe('/baz') editable.path = '/baz' node.path = 'baz' - expect(editable.path).toBe('/baz'); + expect(editable.path).toBe('/baz') expect(node.path).toBe('baz') }) }) diff --git a/src/core/extendRoutes.ts b/src/core/extendRoutes.ts index 361d5c228..908d77bf5 100644 --- a/src/core/extendRoutes.ts +++ b/src/core/extendRoutes.ts @@ -142,7 +142,10 @@ export class EditableTreeNode { * Override the path of the route. You must ensure `params` match with the existing path. */ set path(path: string) { - if ((!this.node.parent || this.node.parent.isRoot()) && !path.startsWith('/')) { + if ( + (!this.node.parent || this.node.parent.isRoot()) && + !path.startsWith('/') + ) { warn( `Only absolute paths are supported. Make sure that "${path}" starts with a slash "/".` ) From b811c721a361e53d88fad17667c1c914d56f305b Mon Sep 17 00:00:00 2001 From: robertmoura <17804984+robertmoura@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:46:12 +1000 Subject: [PATCH 06/15] refactor(tree): update full path override --- src/core/tree.spec.ts | 2 +- src/core/tree.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/tree.spec.ts b/src/core/tree.spec.ts index 266a0962f..7df7aa7c9 100644 --- a/src/core/tree.spec.ts +++ b/src/core/tree.spec.ts @@ -413,7 +413,7 @@ describe('Tree', () => { path: '/custom-child', }) expect(node.path).toBe('/custom-child') - expect(node.fullPath).toBe('/custom-child') + expect(node.fullPath).toBe('/auth/custom-child') }) it('removes trailing slash from path but not from name', () => { diff --git a/src/core/tree.ts b/src/core/tree.ts index 1dcfbe6d3..26799408d 100644 --- a/src/core/tree.ts +++ b/src/core/tree.ts @@ -195,7 +195,7 @@ export class TreeNode { * Returns the route path of the node including parent paths. */ get fullPath() { - return this.value.overrides.path ?? this.value.path + return this.value.path } /** From 98bfe7626e08a7e3e548bf208a30604c1fe5c599 Mon Sep 17 00:00:00 2001 From: robertmoura <17804984+robertmoura@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:53:35 +1000 Subject: [PATCH 07/15] chore(extendRoutes): update warning message --- src/core/extendRoutes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/extendRoutes.ts b/src/core/extendRoutes.ts index 908d77bf5..f2f6bc954 100644 --- a/src/core/extendRoutes.ts +++ b/src/core/extendRoutes.ts @@ -147,7 +147,7 @@ export class EditableTreeNode { !path.startsWith('/') ) { warn( - `Only absolute paths are supported. Make sure that "${path}" starts with a slash "/".` + `Only absolute paths are supported at the root route. Make sure that "${path}" starts with a slash "/".` ) return } From a8c529a488462c664c510fc55669197e45b0887d Mon Sep 17 00:00:00 2001 From: robertmoura <17804984+robertmoura@users.noreply.github.com> Date: Fri, 28 Jun 2024 15:30:03 +1000 Subject: [PATCH 08/15] test(extendRoutes): remove set root node path --- src/core/extendRoutes.spec.ts | 26 ++++++++++---------------- src/core/extendRoutes.ts | 2 +- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/src/core/extendRoutes.spec.ts b/src/core/extendRoutes.spec.ts index b6f5b07b9..09e489e23 100644 --- a/src/core/extendRoutes.spec.ts +++ b/src/core/extendRoutes.spec.ts @@ -255,22 +255,16 @@ describe('EditableTreeNode', () => { it('can override the path', () => { const tree = new PrefixTree(RESOLVED_OPTIONS) const editable = new EditableTreeNode(tree) - const node = editable.insert('foo', 'file.vue') - const childNode = node.insert('bar', 'file.vue') + const parent = editable.insert('foo', 'file.vue') + const child = parent.insert('bar', 'file.vue') - childNode.path = 'baz' - node.path = 'baz' - editable.path = 'baz' - expect(editable.path).toBe('') - expect(node.path).toBe('/foo') - expect(childNode.path).toBe('baz') - childNode.path = '/baz' - node.path = '/baz' - expect(node.path).toBe('/baz') - expect(node.path).toBe('/baz') - editable.path = '/baz' - node.path = 'baz' - expect(editable.path).toBe('/baz') - expect(node.path).toBe('baz') + child.path = 'baz' + parent.path = 'baz' + expect(parent.path).toBe('/foo') + expect(child.path).toBe('baz') + child.path = '/baz' + parent.path = '/baz' + expect(parent.path).toBe('/baz') + expect(parent.path).toBe('/baz') }) }) diff --git a/src/core/extendRoutes.ts b/src/core/extendRoutes.ts index f2f6bc954..69462f318 100644 --- a/src/core/extendRoutes.ts +++ b/src/core/extendRoutes.ts @@ -147,7 +147,7 @@ export class EditableTreeNode { !path.startsWith('/') ) { warn( - `Only absolute paths are supported at the root route. Make sure that "${path}" starts with a slash "/".` + `Only absolute paths are supported at the root of the route tree. Make sure that "${path}" starts with a slash "/".` ) return } From 964e9cd4a6118690d8671f889c62df920b6645fc Mon Sep 17 00:00:00 2001 From: robertmoura <17804984+robertmoura@users.noreply.github.com> Date: Fri, 28 Jun 2024 16:05:44 +1000 Subject: [PATCH 09/15] refactor(tree): remove fullPath --- src/codegen/generateRouteMap.spec.ts | 2 +- src/codegen/generateRouteMap.ts | 2 +- src/core/extendRoutes.spec.ts | 20 ++++++++++---------- src/core/extendRoutes.ts | 2 +- src/core/tree.spec.ts | 10 +++++----- src/core/tree.ts | 7 ------- 6 files changed, 18 insertions(+), 25 deletions(-) diff --git a/src/codegen/generateRouteMap.spec.ts b/src/codegen/generateRouteMap.spec.ts index 6afb60977..75c7209bf 100644 --- a/src/codegen/generateRouteMap.spec.ts +++ b/src/codegen/generateRouteMap.spec.ts @@ -153,7 +153,7 @@ describe('generateRouteNamedMap', () => { const parent = tree.insert('parent', 'parent.vue') const child = tree.insert('parent/child', 'parent/child.vue') parent.value.setOverride('parent', { path: '/' }) - expect(child.fullPath).toBe('/child') + expect(child.value.path).toBe('/child') expect(formatExports(generateRouteNamedMap(tree))).toMatchInlineSnapshot(` "export interface RouteNamedMap { '/parent': RouteRecordInfo<'/parent', '/', Record, Record>, diff --git a/src/codegen/generateRouteMap.ts b/src/codegen/generateRouteMap.ts index 6a2a2bd77..62638ae0d 100644 --- a/src/codegen/generateRouteMap.ts +++ b/src/codegen/generateRouteMap.ts @@ -22,6 +22,6 @@ ${node.getSortedChildren().map(generateRouteNamedMap).join('')}}` export function generateRouteRecordInfo(node: TreeNode) { return `RouteRecordInfo<'${node.name}', '${ - node.fullPath + node.value.path }', ${generateRouteParams(node, true)}, ${generateRouteParams(node, false)}>` } diff --git a/src/core/extendRoutes.spec.ts b/src/core/extendRoutes.spec.ts index 09e489e23..ace2d408e 100644 --- a/src/core/extendRoutes.spec.ts +++ b/src/core/extendRoutes.spec.ts @@ -37,7 +37,7 @@ describe('EditableTreeNode', () => { editable.insert('foo/bar', 'file.vue') expect(tree.children.size).toBe(1) expect(tree.children.get('foo/bar')?.children.size).toBe(0) - expect(tree.children.get('foo/bar')?.fullPath).toBe('/foo/bar') + expect(tree.children.get('foo/bar')?.value.path).toBe('/foo/bar') expect(tree.children.get('foo/bar')?.path).toBe('/foo/bar') }) @@ -62,7 +62,7 @@ describe('EditableTreeNode', () => { editable.insert(':id', 'file.vue') expect(tree.children.size).toBe(1) const child = tree.children.get(':id')! - expect(child.fullPath).toBe('/:id') + expect(child.value.path).toBe('/:id') expect(child.path).toBe('/:id') expect(child.params).toEqual([ { @@ -82,7 +82,7 @@ describe('EditableTreeNode', () => { editable.insert(':id+', 'file.vue') expect(tree.children.size).toBe(1) const child = tree.children.get(':id+')! - expect(child.fullPath).toBe('/:id+') + expect(child.value.path).toBe('/:id+') expect(child.path).toBe('/:id+') expect(child.params).toEqual([ { @@ -102,7 +102,7 @@ describe('EditableTreeNode', () => { editable.insert(':foo/:bar', 'file.vue') expect(tree.children.size).toBe(1) const node = tree.children.get(':foo/:bar')! - expect(node.fullPath).toBe('/:foo/:bar') + expect(node.value.path).toBe('/:foo/:bar') expect(node.path).toBe('/:foo/:bar') expect(node.params).toEqual([ { @@ -129,7 +129,7 @@ describe('EditableTreeNode', () => { editable.insert(':foo/:bar+_:o(\\d+)', 'file.vue') expect(tree.children.size).toBe(1) const node = tree.children.get(':foo/:bar+_:o(\\d+)')! - expect(node.fullPath).toBe('/:foo/:bar+_:o(\\d+)') + expect(node.value.path).toBe('/:foo/:bar+_:o(\\d+)') expect(node.path).toBe('/:foo/:bar+_:o(\\d+)') expect(node.params).toEqual([ { @@ -162,7 +162,7 @@ describe('EditableTreeNode', () => { editable.insert(':id(\\d+)', 'file.vue') const node = tree.children.get(':id(\\d+)')! - expect(node.fullPath).toBe('/:id(\\d+)') + expect(node.value.path).toBe('/:id(\\d+)') expect(node.path).toBe('/:id(\\d+)') expect(node.params).toEqual([ { @@ -181,7 +181,7 @@ describe('EditableTreeNode', () => { editable.insert(':id()', 'file.vue') const node = tree.children.get(':id()')! - expect(node.fullPath).toBe('/:id()') + expect(node.value.path).toBe('/:id()') expect(node.path).toBe('/:id()') expect(node.params).toEqual([ { @@ -200,7 +200,7 @@ describe('EditableTreeNode', () => { editable.insert(':id(\\d+)+', 'file.vue') const node = tree.children.get(':id(\\d+)+')! - expect(node.fullPath).toBe('/:id(\\d+)+') + expect(node.value.path).toBe('/:id(\\d+)+') expect(node.path).toBe('/:id(\\d+)+') expect(node.params).toEqual([ { @@ -219,7 +219,7 @@ describe('EditableTreeNode', () => { editable.insert(':id()+', 'file.vue') const node = tree.children.get(':id()+')! - expect(node.fullPath).toBe('/:id()+') + expect(node.value.path).toBe('/:id()+') expect(node.path).toBe('/:id()+') expect(node.params).toEqual([ { @@ -239,7 +239,7 @@ describe('EditableTreeNode', () => { editable.insert('/:path(.*)', 'file.vue') expect(tree.children.size).toBe(1) const child = tree.children.get(':path(.*)')! - expect(child.fullPath).toBe('/:path(.*)') + expect(child.value.path).toBe('/:path(.*)') expect(child.path).toBe('/:path(.*)') expect(child.params).toEqual([ { diff --git a/src/core/extendRoutes.ts b/src/core/extendRoutes.ts index 69462f318..7844de930 100644 --- a/src/core/extendRoutes.ts +++ b/src/core/extendRoutes.ts @@ -181,7 +181,7 @@ export class EditableTreeNode { * Path of the route including parent paths. */ get fullPath() { - return this.node.fullPath + return this.node.value.path; } /** diff --git a/src/core/tree.spec.ts b/src/core/tree.spec.ts index 7df7aa7c9..be9b73f31 100644 --- a/src/core/tree.spec.ts +++ b/src/core/tree.spec.ts @@ -406,14 +406,14 @@ describe('Tree', () => { path: '/custom', }) expect(node.path).toBe('/custom') - expect(node.fullPath).toBe('/custom') + expect(node.value.path).toBe('/custom') node = tree.insert('auth/login', 'auth/login.vue') node.value.setOverride('', { path: '/custom-child', }) expect(node.path).toBe('/custom-child') - expect(node.fullPath).toBe('/auth/custom-child') + expect(node.value.path).toBe('/auth/custom-child') }) it('removes trailing slash from path but not from name', () => { @@ -422,19 +422,19 @@ describe('Tree', () => { tree.insert('a/a', 'a/a.vue') let child = tree.children.get('a')! expect(child).toBeDefined() - expect(child.fullPath).toBe('/a') + expect(child.value.path).toBe('/a') child = tree.children.get('a')!.children.get('index')! expect(child).toBeDefined() expect(child.name).toBe('/a/') - expect(child.fullPath).toBe('/a') + expect(child.value.path).toBe('/a') // it stays the same with a parent component in the parent route record tree.insert('a', 'a.vue') child = tree.children.get('a')!.children.get('index')! expect(child).toBeDefined() expect(child.name).toBe('/a/') - expect(child.fullPath).toBe('/a') + expect(child.value.path).toBe('/a') }) describe('dot nesting', () => { diff --git a/src/core/tree.ts b/src/core/tree.ts index 26799408d..a3f919901 100644 --- a/src/core/tree.ts +++ b/src/core/tree.ts @@ -191,13 +191,6 @@ export class TreeNode { ) } - /** - * Returns the route path of the node including parent paths. - */ - get fullPath() { - return this.value.path - } - /** * Returns the route name of the node. If the name was overridden, it returns the override. */ From 3135bb53754e014a9d8ceda9296eff33004f47eb Mon Sep 17 00:00:00 2001 From: robertmoura <17804984+robertmoura@users.noreply.github.com> Date: Fri, 28 Jun 2024 16:40:08 +1000 Subject: [PATCH 10/15] fix: reintroduce absolute paths --- src/codegen/generateRouteMap.spec.ts | 2 +- src/codegen/generateRouteMap.ts | 2 +- src/core/extendRoutes.spec.ts | 20 ++++++++++---------- src/core/extendRoutes.ts | 2 +- src/core/tree.spec.ts | 10 +++++----- src/core/tree.ts | 7 +++++++ 6 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/codegen/generateRouteMap.spec.ts b/src/codegen/generateRouteMap.spec.ts index 75c7209bf..6afb60977 100644 --- a/src/codegen/generateRouteMap.spec.ts +++ b/src/codegen/generateRouteMap.spec.ts @@ -153,7 +153,7 @@ describe('generateRouteNamedMap', () => { const parent = tree.insert('parent', 'parent.vue') const child = tree.insert('parent/child', 'parent/child.vue') parent.value.setOverride('parent', { path: '/' }) - expect(child.value.path).toBe('/child') + expect(child.fullPath).toBe('/child') expect(formatExports(generateRouteNamedMap(tree))).toMatchInlineSnapshot(` "export interface RouteNamedMap { '/parent': RouteRecordInfo<'/parent', '/', Record, Record>, diff --git a/src/codegen/generateRouteMap.ts b/src/codegen/generateRouteMap.ts index 62638ae0d..6a2a2bd77 100644 --- a/src/codegen/generateRouteMap.ts +++ b/src/codegen/generateRouteMap.ts @@ -22,6 +22,6 @@ ${node.getSortedChildren().map(generateRouteNamedMap).join('')}}` export function generateRouteRecordInfo(node: TreeNode) { return `RouteRecordInfo<'${node.name}', '${ - node.value.path + node.fullPath }', ${generateRouteParams(node, true)}, ${generateRouteParams(node, false)}>` } diff --git a/src/core/extendRoutes.spec.ts b/src/core/extendRoutes.spec.ts index ace2d408e..09e489e23 100644 --- a/src/core/extendRoutes.spec.ts +++ b/src/core/extendRoutes.spec.ts @@ -37,7 +37,7 @@ describe('EditableTreeNode', () => { editable.insert('foo/bar', 'file.vue') expect(tree.children.size).toBe(1) expect(tree.children.get('foo/bar')?.children.size).toBe(0) - expect(tree.children.get('foo/bar')?.value.path).toBe('/foo/bar') + expect(tree.children.get('foo/bar')?.fullPath).toBe('/foo/bar') expect(tree.children.get('foo/bar')?.path).toBe('/foo/bar') }) @@ -62,7 +62,7 @@ describe('EditableTreeNode', () => { editable.insert(':id', 'file.vue') expect(tree.children.size).toBe(1) const child = tree.children.get(':id')! - expect(child.value.path).toBe('/:id') + expect(child.fullPath).toBe('/:id') expect(child.path).toBe('/:id') expect(child.params).toEqual([ { @@ -82,7 +82,7 @@ describe('EditableTreeNode', () => { editable.insert(':id+', 'file.vue') expect(tree.children.size).toBe(1) const child = tree.children.get(':id+')! - expect(child.value.path).toBe('/:id+') + expect(child.fullPath).toBe('/:id+') expect(child.path).toBe('/:id+') expect(child.params).toEqual([ { @@ -102,7 +102,7 @@ describe('EditableTreeNode', () => { editable.insert(':foo/:bar', 'file.vue') expect(tree.children.size).toBe(1) const node = tree.children.get(':foo/:bar')! - expect(node.value.path).toBe('/:foo/:bar') + expect(node.fullPath).toBe('/:foo/:bar') expect(node.path).toBe('/:foo/:bar') expect(node.params).toEqual([ { @@ -129,7 +129,7 @@ describe('EditableTreeNode', () => { editable.insert(':foo/:bar+_:o(\\d+)', 'file.vue') expect(tree.children.size).toBe(1) const node = tree.children.get(':foo/:bar+_:o(\\d+)')! - expect(node.value.path).toBe('/:foo/:bar+_:o(\\d+)') + expect(node.fullPath).toBe('/:foo/:bar+_:o(\\d+)') expect(node.path).toBe('/:foo/:bar+_:o(\\d+)') expect(node.params).toEqual([ { @@ -162,7 +162,7 @@ describe('EditableTreeNode', () => { editable.insert(':id(\\d+)', 'file.vue') const node = tree.children.get(':id(\\d+)')! - expect(node.value.path).toBe('/:id(\\d+)') + expect(node.fullPath).toBe('/:id(\\d+)') expect(node.path).toBe('/:id(\\d+)') expect(node.params).toEqual([ { @@ -181,7 +181,7 @@ describe('EditableTreeNode', () => { editable.insert(':id()', 'file.vue') const node = tree.children.get(':id()')! - expect(node.value.path).toBe('/:id()') + expect(node.fullPath).toBe('/:id()') expect(node.path).toBe('/:id()') expect(node.params).toEqual([ { @@ -200,7 +200,7 @@ describe('EditableTreeNode', () => { editable.insert(':id(\\d+)+', 'file.vue') const node = tree.children.get(':id(\\d+)+')! - expect(node.value.path).toBe('/:id(\\d+)+') + expect(node.fullPath).toBe('/:id(\\d+)+') expect(node.path).toBe('/:id(\\d+)+') expect(node.params).toEqual([ { @@ -219,7 +219,7 @@ describe('EditableTreeNode', () => { editable.insert(':id()+', 'file.vue') const node = tree.children.get(':id()+')! - expect(node.value.path).toBe('/:id()+') + expect(node.fullPath).toBe('/:id()+') expect(node.path).toBe('/:id()+') expect(node.params).toEqual([ { @@ -239,7 +239,7 @@ describe('EditableTreeNode', () => { editable.insert('/:path(.*)', 'file.vue') expect(tree.children.size).toBe(1) const child = tree.children.get(':path(.*)')! - expect(child.value.path).toBe('/:path(.*)') + expect(child.fullPath).toBe('/:path(.*)') expect(child.path).toBe('/:path(.*)') expect(child.params).toEqual([ { diff --git a/src/core/extendRoutes.ts b/src/core/extendRoutes.ts index 7844de930..b0a992a5e 100644 --- a/src/core/extendRoutes.ts +++ b/src/core/extendRoutes.ts @@ -181,7 +181,7 @@ export class EditableTreeNode { * Path of the route including parent paths. */ get fullPath() { - return this.node.value.path; + return this.node.fullPath; } /** diff --git a/src/core/tree.spec.ts b/src/core/tree.spec.ts index be9b73f31..266a0962f 100644 --- a/src/core/tree.spec.ts +++ b/src/core/tree.spec.ts @@ -406,14 +406,14 @@ describe('Tree', () => { path: '/custom', }) expect(node.path).toBe('/custom') - expect(node.value.path).toBe('/custom') + expect(node.fullPath).toBe('/custom') node = tree.insert('auth/login', 'auth/login.vue') node.value.setOverride('', { path: '/custom-child', }) expect(node.path).toBe('/custom-child') - expect(node.value.path).toBe('/auth/custom-child') + expect(node.fullPath).toBe('/custom-child') }) it('removes trailing slash from path but not from name', () => { @@ -422,19 +422,19 @@ describe('Tree', () => { tree.insert('a/a', 'a/a.vue') let child = tree.children.get('a')! expect(child).toBeDefined() - expect(child.value.path).toBe('/a') + expect(child.fullPath).toBe('/a') child = tree.children.get('a')!.children.get('index')! expect(child).toBeDefined() expect(child.name).toBe('/a/') - expect(child.value.path).toBe('/a') + expect(child.fullPath).toBe('/a') // it stays the same with a parent component in the parent route record tree.insert('a', 'a.vue') child = tree.children.get('a')!.children.get('index')! expect(child).toBeDefined() expect(child.name).toBe('/a/') - expect(child.value.path).toBe('/a') + expect(child.fullPath).toBe('/a') }) describe('dot nesting', () => { diff --git a/src/core/tree.ts b/src/core/tree.ts index a3f919901..3f8e29082 100644 --- a/src/core/tree.ts +++ b/src/core/tree.ts @@ -191,6 +191,13 @@ export class TreeNode { ) } + /** + * Returns the route path of the node including parent paths. + */ + get fullPath() { + return this.value.overrides.path?.startsWith('/') ? this.value.overrides.path : this.value.path + } + /** * Returns the route name of the node. If the name was overridden, it returns the override. */ From b260d9b96a2e2a1c7cbced3bf8584283af15da2c Mon Sep 17 00:00:00 2001 From: robertmoura <17804984+robertmoura@users.noreply.github.com> Date: Fri, 28 Jun 2024 16:41:03 +1000 Subject: [PATCH 11/15] chore: lint code --- src/core/extendRoutes.ts | 2 +- src/core/tree.ts | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/core/extendRoutes.ts b/src/core/extendRoutes.ts index b0a992a5e..69462f318 100644 --- a/src/core/extendRoutes.ts +++ b/src/core/extendRoutes.ts @@ -181,7 +181,7 @@ export class EditableTreeNode { * Path of the route including parent paths. */ get fullPath() { - return this.node.fullPath; + return this.node.fullPath } /** diff --git a/src/core/tree.ts b/src/core/tree.ts index 3f8e29082..f23eeab9c 100644 --- a/src/core/tree.ts +++ b/src/core/tree.ts @@ -192,11 +192,13 @@ export class TreeNode { } /** - * Returns the route path of the node including parent paths. - */ - get fullPath() { - return this.value.overrides.path?.startsWith('/') ? this.value.overrides.path : this.value.path - } + * Returns the route path of the node including parent paths. + */ + get fullPath() { + return this.value.overrides.path?.startsWith('/') + ? this.value.overrides.path + : this.value.path + } /** * Returns the route name of the node. If the name was overridden, it returns the override. From 43ed75f49165278fd57e415cacf728655cba0634 Mon Sep 17 00:00:00 2001 From: robertmoura <17804984+robertmoura@users.noreply.github.com> Date: Fri, 28 Jun 2024 16:45:16 +1000 Subject: [PATCH 12/15] test(extendRoutes): improve tests --- src/core/extendRoutes.spec.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/core/extendRoutes.spec.ts b/src/core/extendRoutes.spec.ts index 09e489e23..2cfcd0e26 100644 --- a/src/core/extendRoutes.spec.ts +++ b/src/core/extendRoutes.spec.ts @@ -255,16 +255,16 @@ describe('EditableTreeNode', () => { it('can override the path', () => { const tree = new PrefixTree(RESOLVED_OPTIONS) const editable = new EditableTreeNode(tree) - const parent = editable.insert('foo', 'file.vue') - const child = parent.insert('bar', 'file.vue') + const parent = editable.insert('parent', 'file.vue') + const child = parent.insert('child', 'file.vue') - child.path = 'baz' - parent.path = 'baz' - expect(parent.path).toBe('/foo') - expect(child.path).toBe('baz') - child.path = '/baz' - parent.path = '/baz' - expect(parent.path).toBe('/baz') - expect(parent.path).toBe('/baz') + child.path = 'relative' + parent.path = 'relative' + expect(parent.path).toBe('/parent') + expect(child.path).toBe('relative') + expect(child.fullPath).toBe('/parent/relative') + child.path = '/absolute' + expect(child.path).toBe('/absolute') + expect(child.fullPath).toBe('/absolute') }) }) From 652507ac1c06a46dab3b89ec82718d4a4ff08356 Mon Sep 17 00:00:00 2001 From: robertmoura <17804984+robertmoura@users.noreply.github.com> Date: Fri, 28 Jun 2024 19:51:49 +1000 Subject: [PATCH 13/15] fix(tree): relative child of absolute route --- src/core/extendRoutes.spec.ts | 3 +++ src/core/tree.ts | 4 +--- src/core/treeNodeValue.ts | 7 ++++++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/core/extendRoutes.spec.ts b/src/core/extendRoutes.spec.ts index 2cfcd0e26..33f6447c8 100644 --- a/src/core/extendRoutes.spec.ts +++ b/src/core/extendRoutes.spec.ts @@ -257,14 +257,17 @@ describe('EditableTreeNode', () => { const editable = new EditableTreeNode(tree) const parent = editable.insert('parent', 'file.vue') const child = parent.insert('child', 'file.vue') + const grandChild = child.insert('grandchild', 'file.vue') child.path = 'relative' parent.path = 'relative' expect(parent.path).toBe('/parent') expect(child.path).toBe('relative') expect(child.fullPath).toBe('/parent/relative') + expect(grandChild.fullPath).toBe('/parent/relative/grandchild') child.path = '/absolute' expect(child.path).toBe('/absolute') expect(child.fullPath).toBe('/absolute') + expect(grandChild.fullPath).toBe('/absolute/grandchild') }) }) diff --git a/src/core/tree.ts b/src/core/tree.ts index f23eeab9c..26799408d 100644 --- a/src/core/tree.ts +++ b/src/core/tree.ts @@ -195,9 +195,7 @@ export class TreeNode { * Returns the route path of the node including parent paths. */ get fullPath() { - return this.value.overrides.path?.startsWith('/') - ? this.value.overrides.path - : this.value.path + return this.value.path } /** diff --git a/src/core/treeNodeValue.ts b/src/core/treeNodeValue.ts index 4d06fefb5..3e323ee46 100644 --- a/src/core/treeNodeValue.ts +++ b/src/core/treeNodeValue.ts @@ -70,9 +70,14 @@ class _TreeNodeValueBase { * fullPath of the node based on parent nodes */ get path(): string { - const parentPath = this.parent?.path + if (this.overrides.path?.startsWith('/')) { + return this.overrides.path + } + // both the root record and the index record have a path of / const pathSegment = this.overrides.path ?? this.pathSegment + const parentPath = this.parent?.path + return (!parentPath || parentPath === '/') && pathSegment === '' ? '/' : joinPath(parentPath || '', pathSegment) From 3ec0b22a5ff96e986d16db2d8bb412edf98164ea Mon Sep 17 00:00:00 2001 From: robertmoura <17804984+robertmoura@users.noreply.github.com> Date: Mon, 1 Jul 2024 14:14:10 +1000 Subject: [PATCH 14/15] feat(routeBlock): improve relative path overrides --- src/core/context.ts | 22 +++++++++++++++++++--- src/core/customBlock.ts | 13 +------------ 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/core/context.ts b/src/core/context.ts index 73813da87..cc1fd037a 100644 --- a/src/core/context.ts +++ b/src/core/context.ts @@ -1,7 +1,7 @@ import { ResolvedOptions } from '../options' import { TreeNode, PrefixTree } from './tree' import { promises as fs } from 'fs' -import { asRoutePath, ImportsMap, logTree, throttle } from './utils' +import { asRoutePath, ImportsMap, joinPath, logTree, throttle } from './utils' import { generateRouteNamedMap } from '../codegen/generateRouteMap' import { MODULE_ROUTES_PATH, MODULE_VUE_ROUTER_AUTO } from './moduleConstants' import { generateRouteRecord } from '../codegen/generateRouteRecords' @@ -114,10 +114,26 @@ export function createRoutesContext(options: ResolvedOptions) { const routeBlock = getRouteBlock(filePath, content, options) // TODO: should warn if hasDefinePage and customRouteBlock // if (routeBlock) logger.log(routeBlock) - node.setCustomRouteBlock(filePath, { + + const routeOverrides = { ...routeBlock, ...definedPageNameAndPath, - }) + } + + if (routeOverrides.path && !routeOverrides.path.startsWith('/')) { + let parent = node.parent + + while (parent && !parent.value.components.size) { + parent = parent.parent + } + + routeOverrides.path = joinPath( + parent?.value.path || '', + routeOverrides.path + ) + } + + node.setCustomRouteBlock(filePath, routeOverrides) } async function addPage( diff --git a/src/core/customBlock.ts b/src/core/customBlock.ts index b8c8f5da4..fd0ce5ffc 100644 --- a/src/core/customBlock.ts +++ b/src/core/customBlock.ts @@ -13,18 +13,7 @@ export function getRouteBlock( const parsedSFC = parse(content, { pad: 'space' }).descriptor const blockStr = parsedSFC?.customBlocks.find((b) => b.type === 'route') - if (!blockStr) return - - let result = parseCustomBlock(blockStr, path, options) - - // validation - if (result) { - if (result.path != null && !result.path.startsWith('/')) { - warn(`Overridden path must start with "/". Found in "${path}".`) - } - } - - return result + if (blockStr) return parseCustomBlock(blockStr, path, options) } export interface CustomRouteBlock From a930a2d61e62276f7140ee7d50c56bd7e60e6948 Mon Sep 17 00:00:00 2001 From: robertmoura <17804984+robertmoura@users.noreply.github.com> Date: Fri, 4 Oct 2024 15:22:17 +1000 Subject: [PATCH 15/15] fix: handle empty string --- src/core/context.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/context.ts b/src/core/context.ts index cc1fd037a..17724455c 100644 --- a/src/core/context.ts +++ b/src/core/context.ts @@ -120,7 +120,7 @@ export function createRoutesContext(options: ResolvedOptions) { ...definedPageNameAndPath, } - if (routeOverrides.path && !routeOverrides.path.startsWith('/')) { + if (routeOverrides.path != null && !routeOverrides.path.startsWith('/')) { let parent = node.parent while (parent && !parent.value.components.size) {