From 9bea4525680ad5de7ccca7b1ce6da1220f0763aa Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Tue, 2 May 2023 14:56:42 +0200 Subject: [PATCH] fix: handle empty regexp in raw routes --- src/core/extendRoutes.spec.ts | 104 +++++++++++++++++++++++++++++----- src/core/treeNodeValue.ts | 6 +- 2 files changed, 95 insertions(+), 15 deletions(-) diff --git a/src/core/extendRoutes.spec.ts b/src/core/extendRoutes.spec.ts index 877dbdc04..1d0f53f0e 100644 --- a/src/core/extendRoutes.spec.ts +++ b/src/core/extendRoutes.spec.ts @@ -54,6 +54,46 @@ describe('EditableTreeNode', () => { expect(node.children.at(0)?.fullPath).toBe('/foo/bar/nested') }) + it('adds params', () => { + const tree = createPrefixTree(DEFAULT_OPTIONS) + const editable = new EditableTreeNode(tree) + + editable.insert(':id', 'file.vue') + expect(tree.children.size).toBe(1) + const child = tree.children.get(':id')! + expect(child.fullPath).toBe('/:id') + expect(child.path).toBe('/:id') + expect(child.params).toEqual([ + { + paramName: 'id', + modifier: '', + optional: false, + repeatable: false, + isSplat: false, + }, + ]) + }) + + it('adds params with modifiers', () => { + const tree = createPrefixTree(DEFAULT_OPTIONS) + const editable = new EditableTreeNode(tree) + + editable.insert(':id+', 'file.vue') + expect(tree.children.size).toBe(1) + const child = tree.children.get(':id+')! + expect(child.fullPath).toBe('/:id+') + expect(child.path).toBe('/:id+') + expect(child.params).toEqual([ + { + paramName: 'id', + modifier: '+', + optional: false, + repeatable: true, + isSplat: false, + }, + ]) + }) + it('can have multiple params', () => { const tree = createPrefixTree(DEFAULT_OPTIONS) const editable = new EditableTreeNode(tree) @@ -115,16 +155,15 @@ describe('EditableTreeNode', () => { ]) }) - it('adds params', () => { + it('adds params with custom regex', () => { const tree = createPrefixTree(DEFAULT_OPTIONS) const editable = new EditableTreeNode(tree) - editable.insert(':id', 'file.vue') - expect(tree.children.size).toBe(1) - const child = tree.children.get(':id')! - expect(child.fullPath).toBe('/:id') - expect(child.path).toBe('/:id') - expect(child.params).toEqual([ + editable.insert(':id(\\d+)', 'file.vue') + const node = tree.children.get(':id(\\d+)')! + expect(node.fullPath).toBe('/:id(\\d+)') + expect(node.path).toBe('/:id(\\d+)') + expect(node.params).toEqual([ { paramName: 'id', modifier: '', @@ -135,16 +174,53 @@ describe('EditableTreeNode', () => { ]) }) - it('add params with modifiers', () => { + it('adds a param with empty regex', () => { const tree = createPrefixTree(DEFAULT_OPTIONS) const editable = new EditableTreeNode(tree) - editable.insert(':id+', 'file.vue') - expect(tree.children.size).toBe(1) - const child = tree.children.get(':id+')! - expect(child.fullPath).toBe('/:id+') - expect(child.path).toBe('/:id+') - expect(child.params).toEqual([ + editable.insert(':id()', 'file.vue') + const node = tree.children.get(':id()')! + expect(node.fullPath).toBe('/:id()') + expect(node.path).toBe('/:id()') + expect(node.params).toEqual([ + { + paramName: 'id', + modifier: '', + optional: false, + repeatable: false, + isSplat: false, + }, + ]) + }) + + it('adds a param with a modifier and custom regex', () => { + const tree = createPrefixTree(DEFAULT_OPTIONS) + const editable = new EditableTreeNode(tree) + + editable.insert(':id(\\d+)+', 'file.vue') + const node = tree.children.get(':id(\\d+)+')! + expect(node.fullPath).toBe('/:id(\\d+)+') + expect(node.path).toBe('/:id(\\d+)+') + expect(node.params).toEqual([ + { + paramName: 'id', + modifier: '+', + optional: false, + repeatable: true, + isSplat: false, + }, + ]) + }) + + it('adds a param with a modifier and empty regex', () => { + const tree = createPrefixTree(DEFAULT_OPTIONS) + const editable = new EditableTreeNode(tree) + + editable.insert(':id()+', 'file.vue') + const node = tree.children.get(':id()+')! + expect(node.fullPath).toBe('/:id()+') + expect(node.path).toBe('/:id()+') + expect(node.params).toEqual([ { paramName: 'id', modifier: '+', diff --git a/src/core/treeNodeValue.ts b/src/core/treeNodeValue.ts index 27d0a49d4..03ad9fb9b 100644 --- a/src/core/treeNodeValue.ts +++ b/src/core/treeNodeValue.ts @@ -489,7 +489,11 @@ function parseRawPathSegment( throw new Error(`Invalid segment: "${segment}"`) } - if (buffer) { + if ( + buffer || + // an empty finished regexp enters this state but must also be consumed + state === ParseRawPathSegmentState.modifier + ) { consumeBuffer() }