Skip to content

Commit 92efba7

Browse files
committed
feat(experimental): handle redirect types
1 parent 4c9b69e commit 92efba7

File tree

2 files changed

+96
-23
lines changed

2 files changed

+96
-23
lines changed

packages/router/src/experimental/router.spec.ts

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,23 @@ const childRawRecord: EXPERIMENTAL_RouteRecord_Matchable = {
104104
parent: parentRecord,
105105
}
106106

107+
const parentWithRedirectRawRecord: EXPERIMENTAL_RouteRecord_Matchable = {
108+
name: 'parent-with-redirect',
109+
path: new MatcherPatternPathStatic('/parent-with-redirect'),
110+
redirect: { name: 'child-for-redirect' },
111+
}
112+
const parentWithRedirectRecord = normalizeRouteRecord(
113+
parentWithRedirectRawRecord
114+
)
115+
116+
const childDefaultRawRecord: EXPERIMENTAL_RouteRecord_Matchable = {
117+
name: 'child-for-redirect',
118+
path: new MatcherPatternPathStatic('/parent-with-redirect'),
119+
components: { default: components.Foo },
120+
meta: { fromParent: 'foo' },
121+
parent: parentWithRedirectRecord,
122+
}
123+
107124
// Create all route records
108125
const routeRecords: EXPERIMENTAL_RouteRecord_Matchable[] = [
109126
{
@@ -114,8 +131,6 @@ const routeRecords: EXPERIMENTAL_RouteRecord_Matchable[] = [
114131
{
115132
name: 'home-redirect',
116133
path: new MatcherPatternPathStatic('/home'),
117-
// TODO: this should not be needed in a redirect record
118-
components: { default: components.Home },
119134
redirect: { name: 'home' },
120135
},
121136
{
@@ -137,8 +152,6 @@ const routeRecords: EXPERIMENTAL_RouteRecord_Matchable[] = [
137152
{
138153
name: Symbol('to-foo'),
139154
path: new MatcherPatternPathStatic('/to-foo'),
140-
// TODO: this should not be needed in a redirect record
141-
components: { default: components.Home },
142155
redirect: to => ({
143156
path: '/foo',
144157
query: to.query,
@@ -148,15 +161,11 @@ const routeRecords: EXPERIMENTAL_RouteRecord_Matchable[] = [
148161
{
149162
name: Symbol('to-foo2'),
150163
path: new MatcherPatternPathStatic('/to-foo2'),
151-
// TODO: this should not be needed in a redirect record
152-
components: { default: components.Home },
153164
redirect: '/to-foo',
154165
},
155166
{
156167
path: new MatcherPatternPathStatic('/to-foo-query'),
157168
name: Symbol('to-foo-query'),
158-
// TODO: this should not be needed in a redirect record
159-
components: { default: components.Home },
160169
redirect: '/foo?a=2#b',
161170
},
162171

@@ -166,8 +175,6 @@ const routeRecords: EXPERIMENTAL_RouteRecord_Matchable[] = [
166175
'to-p',
167176
1,
168177
]),
169-
// TODO: this should not be needed in a redirect record
170-
components: { default: components.Home },
171178
redirect: to => ({
172179
name: 'Param',
173180
params: to.params,
@@ -201,8 +208,12 @@ const routeRecords: EXPERIMENTAL_RouteRecord_Matchable[] = [
201208
path: new MatcherPatternPathStatic('/before-leave'),
202209
components: { default: components.BeforeLeave },
203210
},
204-
parentRawRecord,
211+
205212
childRawRecord,
213+
parentRawRecord,
214+
215+
childDefaultRawRecord,
216+
parentWithRedirectRecord,
206217

207218
{
208219
name: 'param-with-slashes',
@@ -234,10 +245,18 @@ const routeRecords: EXPERIMENTAL_RouteRecord_Matchable[] = [
234245
{ p: [] },
235246
['redirect-with-param', 1]
236247
),
237-
// TODO: shouldn't be needed in a redirect record
238-
components: { default: components.Foo },
239248
redirect: () => `/`,
240249
},
250+
{
251+
name: Symbol('inc-query-hash'),
252+
// path: '/inc-query-hash',
253+
path: new MatcherPatternPathStatic('/inc-query-hash'),
254+
redirect: to => ({
255+
name: 'Foo',
256+
query: { n: to.query.n + '-2' },
257+
hash: to.hash + '-2',
258+
}),
259+
},
241260

242261
{
243262
name: 'catch-all',
@@ -991,16 +1010,46 @@ describe('Experimental Router', () => {
9911010
redirectedFrom: expect.objectContaining({ path: '/to-foo' }),
9921011
})
9931012

1013+
const navPromise = nextNavigation(router as any)
9941014
history.go(-1)
995-
await nextNavigation(router as any)
1015+
await navPromise
9961016
expect(router.currentRoute.value).not.toMatchObject({
9971017
path: '/search',
9981018
})
9991019
})
10001020

1001-
it.skip('can pass on query and hash when redirecting', async () => {})
1021+
it('can pass on query and hash when redirecting', async () => {
1022+
const { router } = await newRouter()
1023+
await router.push('/inc-query-hash?n=3#fa')
1024+
const loc = router.currentRoute.value
1025+
expect(loc).toMatchObject({
1026+
name: 'Foo',
1027+
query: {
1028+
n: '3-2',
1029+
},
1030+
hash: '#fa-2',
1031+
})
1032+
expect(loc.redirectedFrom).toMatchObject({
1033+
fullPath: '/inc-query-hash?n=3#fa',
1034+
query: { n: '3' },
1035+
hash: '#fa',
1036+
path: '/inc-query-hash',
1037+
})
1038+
})
10021039

1003-
it.skip('allows a redirect with children', async () => {})
1040+
it('allows a redirect with children', async () => {
1041+
const { router } = await newRouter()
1042+
await expect(
1043+
router.push({ name: 'parent-with-redirect' })
1044+
).resolves.toEqual(undefined)
1045+
const loc = router.currentRoute.value
1046+
expect(loc.path).toBe('/parent-with-redirect')
1047+
expect(loc.name).toBe('child-for-redirect')
1048+
expect(loc.redirectedFrom).toMatchObject({
1049+
name: 'parent-with-redirect',
1050+
path: '/parent-with-redirect',
1051+
})
1052+
})
10041053

10051054
it.skip('works with named routes', async () => {})
10061055
})

packages/router/src/experimental/router.ts

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,13 @@ export interface EXPERIMENTAL_RouteRecord_Base
234234
// props?: _RouteRecordProps | Record<string, _RouteRecordProps>
235235
}
236236

237-
export interface EXPERIMENTAL_RouteRecord_Matchable
237+
export interface EXPERIMENTAL_RouteRecord_Redirect
238238
// preserve the values from the type EXPERIMENTAL_ResolverRecord_Matchable
239239
extends Omit<EXPERIMENTAL_RouteRecord_Base, 'name' | 'path' | 'parent'>,
240240
EXPERIMENTAL_ResolverRecord_Matchable {
241-
components: Record<string, RawRouteComponent>
241+
components?: Record<string, RawRouteComponent>
242+
243+
redirect: RouteRecordRedirectOption // must be defined
242244

243245
parent?: EXPERIMENTAL_RouteRecordNormalized | null
244246
}
@@ -255,6 +257,21 @@ export interface EXPERIMENTAL_RouteRecord_Group
255257
parent?: EXPERIMENTAL_RouteRecordNormalized | null
256258
}
257259

260+
export interface EXPERIMENTAL_RouteRecord_Components
261+
// preserve the values from the type EXPERIMENTAL_ResolverRecord_Matchable
262+
extends Omit<EXPERIMENTAL_RouteRecord_Base, 'name' | 'path' | 'parent'>,
263+
EXPERIMENTAL_ResolverRecord_Matchable {
264+
components: Record<string, RawRouteComponent>
265+
266+
redirect?: never
267+
268+
parent?: EXPERIMENTAL_RouteRecordNormalized | null
269+
}
270+
271+
export type EXPERIMENTAL_RouteRecord_Matchable =
272+
| EXPERIMENTAL_RouteRecord_Components
273+
| EXPERIMENTAL_RouteRecord_Redirect
274+
258275
export type EXPERIMENTAL_RouteRecordRaw =
259276
| EXPERIMENTAL_RouteRecord_Matchable
260277
| EXPERIMENTAL_RouteRecord_Group
@@ -299,17 +316,24 @@ export interface EXPERIMENTAL_RouteRecordNormalized_Group
299316
parent: EXPERIMENTAL_RouteRecordNormalized | null
300317
}
301318

302-
// TODO: is it worth to have 2 types for the undefined values?
303-
export interface EXPERIMENTAL_RouteRecordNormalized_Matchable
319+
export interface EXPERIMENTAL_RouteRecordNormalized_Redirect
304320
extends EXPERIMENTAL_RouteRecordNormalized_Base,
305-
EXPERIMENTAL_RouteRecord_Matchable {
321+
EXPERIMENTAL_RouteRecord_Redirect {
306322
meta: RouteMeta
307-
308323
parent: EXPERIMENTAL_RouteRecordNormalized | null
324+
}
309325

310-
components: Record<string, RawRouteComponent>
326+
export interface EXPERIMENTAL_RouteRecordNormalized_Components
327+
extends EXPERIMENTAL_RouteRecordNormalized_Base,
328+
EXPERIMENTAL_RouteRecord_Components {
329+
meta: RouteMeta
330+
parent: EXPERIMENTAL_RouteRecordNormalized | null
311331
}
312332

333+
export type EXPERIMENTAL_RouteRecordNormalized_Matchable =
334+
| EXPERIMENTAL_RouteRecordNormalized_Components
335+
| EXPERIMENTAL_RouteRecordNormalized_Redirect
336+
313337
export type EXPERIMENTAL_RouteRecordNormalized =
314338
| EXPERIMENTAL_RouteRecordNormalized_Matchable
315339
| EXPERIMENTAL_RouteRecordNormalized_Group

0 commit comments

Comments
 (0)