mirror of
https://github.com/nuxt/nuxt.git
synced 2025-03-26 02:47:34 +00:00
fix(nuxt): prevent param duplication in typedPages
implementation (#31331)
This commit is contained in:
parent
f4182359f9
commit
0c5f40b57c
@ -202,9 +202,17 @@ export default defineNuxtModule({
|
|||||||
// Avoid duplicate keys in the generated RouteNamedMap type
|
// Avoid duplicate keys in the generated RouteNamedMap type
|
||||||
const absolutePagePath = joinURL(parent.path, page.path)
|
const absolutePagePath = joinURL(parent.path, page.path)
|
||||||
|
|
||||||
// @ts-expect-error TODO: either fix types upstream or figure out another
|
|
||||||
// way to add a route without a file, which must be possible
|
// way to add a route without a file, which must be possible
|
||||||
const route = addedPagePaths.has(absolutePagePath) ? parent : parent.insert(page.path, page.file)
|
const route = addedPagePaths.has(absolutePagePath)
|
||||||
|
? parent
|
||||||
|
: /^\//.test(page.path)
|
||||||
|
// @ts-expect-error TODO: either fix types upstream or figure out another
|
||||||
|
// way to add a route without a file, which must be possible
|
||||||
|
? rootPage.insert(page.path, page.file)
|
||||||
|
// @ts-expect-error TODO: either fix types upstream or figure out another
|
||||||
|
// way to add a route without a file, which must be possible
|
||||||
|
: parent.insert(page.path, page.file)
|
||||||
|
|
||||||
addedPagePaths.add(absolutePagePath)
|
addedPagePaths.add(absolutePagePath)
|
||||||
if (page.meta) {
|
if (page.meta) {
|
||||||
route.addToMeta(page.meta)
|
route.addToMeta(page.meta)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!-- -->
|
<NuxtPage />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
13
test/fixtures/basic-types/pages/param/[id]/view.vue
vendored
Normal file
13
test/fixtures/basic-types/pages/param/[id]/view.vue
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
definePageMeta({
|
||||||
|
name: 'param-id-view-custom',
|
||||||
|
// Deliberately passing absolute path here to test if params are not being duplicated in RouteNamedMap
|
||||||
|
path: '/param/:id()/view-custom',
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- -->
|
||||||
|
</div>
|
||||||
|
</template>
|
4
test/fixtures/basic-types/types.ts
vendored
4
test/fixtures/basic-types/types.ts
vendored
@ -206,6 +206,7 @@ describe('typed router integration', () => {
|
|||||||
it('correctly reads custom names typed in `definePageMeta`', () => {
|
it('correctly reads custom names typed in `definePageMeta`', () => {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
router.push({ name: 'some-custom-name' })
|
router.push({ name: 'some-custom-name' })
|
||||||
|
router.push({ name: 'param-id-view-custom', params: { id: 4 } })
|
||||||
})
|
})
|
||||||
|
|
||||||
it('allows typing useRoute', () => {
|
it('allows typing useRoute', () => {
|
||||||
@ -224,6 +225,9 @@ describe('typed router integration', () => {
|
|||||||
// @ts-expect-error this is an invalid param
|
// @ts-expect-error this is an invalid param
|
||||||
navigateTo({ name: 'param-id', params: { bob: 23 } })
|
navigateTo({ name: 'param-id', params: { bob: 23 } })
|
||||||
navigateTo({ name: 'param-id', params: { id: 4 } })
|
navigateTo({ name: 'param-id', params: { id: 4 } })
|
||||||
|
// @ts-expect-error this is an invalid param
|
||||||
|
navigateTo({ name: 'param-id-view-custom', params: { bob: 23 } })
|
||||||
|
navigateTo({ name: 'param-id-view-custom', params: { id: 4 } })
|
||||||
})
|
})
|
||||||
|
|
||||||
it('allows typing middleware', () => {
|
it('allows typing middleware', () => {
|
||||||
|
17
test/typed-router.test.ts
Normal file
17
test/typed-router.test.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { readFileSync } from 'node:fs'
|
||||||
|
import { resolve } from 'node:path'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
import { x } from 'tinyexec'
|
||||||
|
import { describe, expect, it } from 'vitest'
|
||||||
|
|
||||||
|
const rootDir = fileURLToPath(new URL('./fixtures/basic-types', import.meta.url))
|
||||||
|
|
||||||
|
describe('typed router integration', () => {
|
||||||
|
it('does not duplicate params in RouteNamedMap when a child route overrides the path with an absolute path', async () => {
|
||||||
|
await x('nuxi', ['prepare', rootDir])
|
||||||
|
const typedRouterDtsFile = resolve(rootDir, '.nuxt/types/typed-router.d.ts')
|
||||||
|
const typedRouterDts = readFileSync(typedRouterDtsFile, 'utf8')
|
||||||
|
expect(typedRouterDts).toContain(`'param-id-view-custom': RouteRecordInfo<'param-id-view-custom', '/param/:id()/view-custom', { id: ParamValue<true> }, { id: ParamValue<false> }>,`)
|
||||||
|
expect(typedRouterDts).not.toContain(`'param-id-view-custom': RouteRecordInfo<'param-id-view-custom', '/param/:id()/view-custom', { id: ParamValue<true>, id: ParamValue<true> }, { id: ParamValue<false>, id: ParamValue<false> }>,`)
|
||||||
|
})
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user