Skip to content

Commit 915de64

Browse files
authored
refactor(router-core): more stable url decoding (#5663)
* add decode path segment util * ensure navigation and browsing to path has same encoding/decoding * add e2e tests * add test recommendations * nitpick * minor enhancements * build array once * add additional unit and e2e tests * remove react import from solid test * nitpicks * final nitpicks * use history.push
1 parent e06cfad commit 915de64

File tree

17 files changed

+700
-18
lines changed

17 files changed

+700
-18
lines changed

e2e/react-router/basic-file-based/src/routeTree.gen.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,10 @@ import { Route as RedirectTargetViaLoaderRouteImport } from './routes/redirect/$
5656
import { Route as RedirectTargetViaBeforeLoadRouteImport } from './routes/redirect/$target/via-beforeLoad'
5757
import { Route as PostsPostIdEditRouteImport } from './routes/posts_.$postId.edit'
5858
import { Route as ParamsSingleValueRouteImport } from './routes/params.single.$value'
59+
import { Route as ParamsPsWildcardChar123Char125suffixAtChar45824RouteImport } from './routes/params-ps/wildcard/{$}suffix@대'
5960
import { Route as ParamsPsWildcardChar123Char125suffixRouteImport } from './routes/params-ps/wildcard/{$}suffix'
6061
import { Route as ParamsPsWildcardPrefixChar123Char125RouteImport } from './routes/params-ps/wildcard/prefix{$}'
62+
import { Route as ParamsPsWildcardPrefixAtChar45824Char123Char125RouteImport } from './routes/params-ps/wildcard/prefix@대{$}'
6163
import { Route as ParamsPsWildcardSplatRouteImport } from './routes/params-ps/wildcard/$'
6264
import { Route as ParamsPsNamedChar123fooChar125suffixRouteImport } from './routes/params-ps/named/{$foo}suffix'
6365
import { Route as ParamsPsNamedPrefixChar123fooChar125RouteImport } from './routes/params-ps/named/prefix{$foo}'
@@ -340,6 +342,12 @@ const ParamsSingleValueRoute = ParamsSingleValueRouteImport.update({
340342
path: '/params/single/$value',
341343
getParentRoute: () => rootRouteImport,
342344
} as any)
345+
const ParamsPsWildcardChar123Char125suffixAtChar45824Route =
346+
ParamsPsWildcardChar123Char125suffixAtChar45824RouteImport.update({
347+
id: '/params-ps/wildcard/{$}suffix@대',
348+
path: '/params-ps/wildcard/{$}suffix@대',
349+
getParentRoute: () => rootRouteImport,
350+
} as any)
343351
const ParamsPsWildcardChar123Char125suffixRoute =
344352
ParamsPsWildcardChar123Char125suffixRouteImport.update({
345353
id: '/params-ps/wildcard/{$}suffix',
@@ -352,6 +360,12 @@ const ParamsPsWildcardPrefixChar123Char125Route =
352360
path: '/params-ps/wildcard/prefix{$}',
353361
getParentRoute: () => rootRouteImport,
354362
} as any)
363+
const ParamsPsWildcardPrefixAtChar45824Char123Char125Route =
364+
ParamsPsWildcardPrefixAtChar45824Char123Char125RouteImport.update({
365+
id: '/params-ps/wildcard/prefix@대{$}',
366+
path: '/params-ps/wildcard/prefix@대{$}',
367+
getParentRoute: () => rootRouteImport,
368+
} as any)
355369
const ParamsPsWildcardSplatRoute = ParamsPsWildcardSplatRouteImport.update({
356370
id: '/params-ps/wildcard/$',
357371
path: '/params-ps/wildcard/$',
@@ -607,8 +621,10 @@ export interface FileRoutesByFullPath {
607621
'/params-ps/named/prefix{$foo}': typeof ParamsPsNamedPrefixChar123fooChar125Route
608622
'/params-ps/named/{$foo}suffix': typeof ParamsPsNamedChar123fooChar125suffixRoute
609623
'/params-ps/wildcard/$': typeof ParamsPsWildcardSplatRoute
624+
'/params-ps/wildcard/prefix@대{$}': typeof ParamsPsWildcardPrefixAtChar45824Char123Char125Route
610625
'/params-ps/wildcard/prefix{$}': typeof ParamsPsWildcardPrefixChar123Char125Route
611626
'/params-ps/wildcard/{$}suffix': typeof ParamsPsWildcardChar123Char125suffixRoute
627+
'/params-ps/wildcard/{$}suffix@대': typeof ParamsPsWildcardChar123Char125suffixAtChar45824Route
612628
'/params/single/$value': typeof ParamsSingleValueRoute
613629
'/posts/$postId/edit': typeof PostsPostIdEditRoute
614630
'/redirect/$target/via-beforeLoad': typeof RedirectTargetViaBeforeLoadRoute
@@ -686,8 +702,10 @@ export interface FileRoutesByTo {
686702
'/params-ps/named/prefix{$foo}': typeof ParamsPsNamedPrefixChar123fooChar125Route
687703
'/params-ps/named/{$foo}suffix': typeof ParamsPsNamedChar123fooChar125suffixRoute
688704
'/params-ps/wildcard/$': typeof ParamsPsWildcardSplatRoute
705+
'/params-ps/wildcard/prefix@대{$}': typeof ParamsPsWildcardPrefixAtChar45824Char123Char125Route
689706
'/params-ps/wildcard/prefix{$}': typeof ParamsPsWildcardPrefixChar123Char125Route
690707
'/params-ps/wildcard/{$}suffix': typeof ParamsPsWildcardChar123Char125suffixRoute
708+
'/params-ps/wildcard/{$}suffix@대': typeof ParamsPsWildcardChar123Char125suffixAtChar45824Route
691709
'/params/single/$value': typeof ParamsSingleValueRoute
692710
'/posts/$postId/edit': typeof PostsPostIdEditRoute
693711
'/redirect/$target/via-beforeLoad': typeof RedirectTargetViaBeforeLoadRoute
@@ -776,8 +794,10 @@ export interface FileRoutesById {
776794
'/params-ps/named/prefix{$foo}': typeof ParamsPsNamedPrefixChar123fooChar125Route
777795
'/params-ps/named/{$foo}suffix': typeof ParamsPsNamedChar123fooChar125suffixRoute
778796
'/params-ps/wildcard/$': typeof ParamsPsWildcardSplatRoute
797+
'/params-ps/wildcard/prefix@대{$}': typeof ParamsPsWildcardPrefixAtChar45824Char123Char125Route
779798
'/params-ps/wildcard/prefix{$}': typeof ParamsPsWildcardPrefixChar123Char125Route
780799
'/params-ps/wildcard/{$}suffix': typeof ParamsPsWildcardChar123Char125suffixRoute
800+
'/params-ps/wildcard/{$}suffix@대': typeof ParamsPsWildcardChar123Char125suffixAtChar45824Route
781801
'/params/single/$value': typeof ParamsSingleValueRoute
782802
'/posts_/$postId/edit': typeof PostsPostIdEditRoute
783803
'/redirect/$target/via-beforeLoad': typeof RedirectTargetViaBeforeLoadRoute
@@ -864,8 +884,10 @@ export interface FileRouteTypes {
864884
| '/params-ps/named/prefix{$foo}'
865885
| '/params-ps/named/{$foo}suffix'
866886
| '/params-ps/wildcard/$'
887+
| '/params-ps/wildcard/prefix@대{$}'
867888
| '/params-ps/wildcard/prefix{$}'
868889
| '/params-ps/wildcard/{$}suffix'
890+
| '/params-ps/wildcard/{$}suffix@대'
869891
| '/params/single/$value'
870892
| '/posts/$postId/edit'
871893
| '/redirect/$target/via-beforeLoad'
@@ -943,8 +965,10 @@ export interface FileRouteTypes {
943965
| '/params-ps/named/prefix{$foo}'
944966
| '/params-ps/named/{$foo}suffix'
945967
| '/params-ps/wildcard/$'
968+
| '/params-ps/wildcard/prefix@대{$}'
946969
| '/params-ps/wildcard/prefix{$}'
947970
| '/params-ps/wildcard/{$}suffix'
971+
| '/params-ps/wildcard/{$}suffix@대'
948972
| '/params/single/$value'
949973
| '/posts/$postId/edit'
950974
| '/redirect/$target/via-beforeLoad'
@@ -1032,8 +1056,10 @@ export interface FileRouteTypes {
10321056
| '/params-ps/named/prefix{$foo}'
10331057
| '/params-ps/named/{$foo}suffix'
10341058
| '/params-ps/wildcard/$'
1059+
| '/params-ps/wildcard/prefix@대{$}'
10351060
| '/params-ps/wildcard/prefix{$}'
10361061
| '/params-ps/wildcard/{$}suffix'
1062+
| '/params-ps/wildcard/{$}suffix@대'
10371063
| '/params/single/$value'
10381064
| '/posts_/$postId/edit'
10391065
| '/redirect/$target/via-beforeLoad'
@@ -1105,8 +1131,10 @@ export interface RootRouteChildren {
11051131
ParamsPsNamedPrefixChar123fooChar125Route: typeof ParamsPsNamedPrefixChar123fooChar125Route
11061132
ParamsPsNamedChar123fooChar125suffixRoute: typeof ParamsPsNamedChar123fooChar125suffixRoute
11071133
ParamsPsWildcardSplatRoute: typeof ParamsPsWildcardSplatRoute
1134+
ParamsPsWildcardPrefixAtChar45824Char123Char125Route: typeof ParamsPsWildcardPrefixAtChar45824Char123Char125Route
11081135
ParamsPsWildcardPrefixChar123Char125Route: typeof ParamsPsWildcardPrefixChar123Char125Route
11091136
ParamsPsWildcardChar123Char125suffixRoute: typeof ParamsPsWildcardChar123Char125suffixRoute
1137+
ParamsPsWildcardChar123Char125suffixAtChar45824Route: typeof ParamsPsWildcardChar123Char125suffixAtChar45824Route
11101138
ParamsSingleValueRoute: typeof ParamsSingleValueRoute
11111139
PostsPostIdEditRoute: typeof PostsPostIdEditRoute
11121140
RedirectPreloadFirstRoute: typeof RedirectPreloadFirstRoute
@@ -1447,6 +1475,13 @@ declare module '@tanstack/react-router' {
14471475
preLoaderRoute: typeof ParamsSingleValueRouteImport
14481476
parentRoute: typeof rootRouteImport
14491477
}
1478+
'/params-ps/wildcard/{$}suffix@대': {
1479+
id: '/params-ps/wildcard/{$}suffix@대'
1480+
path: '/params-ps/wildcard/{$}suffix@대'
1481+
fullPath: '/params-ps/wildcard/{$}suffix@대'
1482+
preLoaderRoute: typeof ParamsPsWildcardChar123Char125suffixAtChar45824RouteImport
1483+
parentRoute: typeof rootRouteImport
1484+
}
14501485
'/params-ps/wildcard/{$}suffix': {
14511486
id: '/params-ps/wildcard/{$}suffix'
14521487
path: '/params-ps/wildcard/{$}suffix'
@@ -1461,6 +1496,13 @@ declare module '@tanstack/react-router' {
14611496
preLoaderRoute: typeof ParamsPsWildcardPrefixChar123Char125RouteImport
14621497
parentRoute: typeof rootRouteImport
14631498
}
1499+
'/params-ps/wildcard/prefix@대{$}': {
1500+
id: '/params-ps/wildcard/prefix@대{$}'
1501+
path: '/params-ps/wildcard/prefix@대{$}'
1502+
fullPath: '/params-ps/wildcard/prefix@대{$}'
1503+
preLoaderRoute: typeof ParamsPsWildcardPrefixAtChar45824Char123Char125RouteImport
1504+
parentRoute: typeof rootRouteImport
1505+
}
14641506
'/params-ps/wildcard/$': {
14651507
id: '/params-ps/wildcard/$'
14661508
path: '/params-ps/wildcard/$'
@@ -2091,10 +2133,14 @@ const rootRouteChildren: RootRouteChildren = {
20912133
ParamsPsNamedChar123fooChar125suffixRoute:
20922134
ParamsPsNamedChar123fooChar125suffixRoute,
20932135
ParamsPsWildcardSplatRoute: ParamsPsWildcardSplatRoute,
2136+
ParamsPsWildcardPrefixAtChar45824Char123Char125Route:
2137+
ParamsPsWildcardPrefixAtChar45824Char123Char125Route,
20942138
ParamsPsWildcardPrefixChar123Char125Route:
20952139
ParamsPsWildcardPrefixChar123Char125Route,
20962140
ParamsPsWildcardChar123Char125suffixRoute:
20972141
ParamsPsWildcardChar123Char125suffixRoute,
2142+
ParamsPsWildcardChar123Char125suffixAtChar45824Route:
2143+
ParamsPsWildcardChar123Char125suffixAtChar45824Route,
20982144
ParamsSingleValueRoute: ParamsSingleValueRoute,
20992145
PostsPostIdEditRoute: PostsPostIdEditRoute,
21002146
RedirectPreloadFirstRoute: RedirectPreloadFirstRoute,

e2e/react-router/basic-file-based/src/routes/params-ps/index.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@ function RouteComponent() {
4949
/params-ps/wildcard/$
5050
</Link>
5151
</li>
52+
<li>
53+
<Link
54+
data-testid="l-to-wildcard-escaped"
55+
to="/params-ps/wildcard/$"
56+
params={{ _splat: 'test[s\\/.\\/parameter%!🚀]' }}
57+
>
58+
/params-ps/wildcard/$ with escaped params
59+
</Link>
60+
</li>
5261
<li>
5362
<Link
5463
data-testid="l-to-wildcard-prefixfoo"
@@ -58,6 +67,15 @@ function RouteComponent() {
5867
/params-ps/wildcard/{'prefix{$}'}
5968
</Link>
6069
</li>
70+
<li>
71+
<Link
72+
data-testid="l-to-wildcard-prefix-escaped"
73+
to="/params-ps/wildcard/prefix@대{$}"
74+
params={{ _splat: 'test[s\\/.\\/parameter%!🚀]' }}
75+
>
76+
/params-ps/wildcard/{'prefix@대{$}'}
77+
</Link>
78+
</li>
6179
<li>
6280
<Link
6381
data-testid="l-to-wildcard-foosuffix"
@@ -67,6 +85,15 @@ function RouteComponent() {
6785
/params-ps/wildcard/{'{$}suffix'}
6886
</Link>
6987
</li>
88+
<li>
89+
<Link
90+
data-testid="l-to-wildcard-suffix-escaped"
91+
to="/params-ps/wildcard/{$}suffix@대"
92+
params={{ _splat: 'test[s\\/.\\/parameter%!🚀]' }}
93+
>
94+
/params-ps/wildcard/{'{$}suffix@대'}
95+
</Link>
96+
</li>
7097
</ul>
7198
<hr />
7299
<h3 className="pb-2">Non-nested path params</h3>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { createFileRoute } from '@tanstack/react-router'
2+
3+
export const Route = createFileRoute('/params-ps/wildcard/prefix@대{$}')({
4+
component: RouteComponent,
5+
})
6+
7+
function RouteComponent() {
8+
const p = Route.useParams()
9+
return (
10+
<div>
11+
<h3>ParamsWildcardSplatPrefix</h3>
12+
<div data-testid="params-output">{JSON.stringify(p)}</div>
13+
</div>
14+
)
15+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { createFileRoute } from '@tanstack/react-router'
2+
3+
export const Route = createFileRoute('/params-ps/wildcard/{$}suffix@대')({
4+
component: RouteComponent,
5+
})
6+
7+
function RouteComponent() {
8+
const p = Route.useParams()
9+
return (
10+
<div>
11+
<h3>ParamsWildcardSplatSuffix</h3>
12+
<div data-testid="params-output">{JSON.stringify(p)}</div>
13+
</div>
14+
)
15+
}

e2e/react-router/basic-file-based/tests/params.spec.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,33 @@ test.describe('params operations + prefix/suffix', () => {
290290
params: { '*': 'foo', _splat: 'foo' },
291291
destHeadingId: 'ParamsWildcardSplatSuffix',
292292
},
293+
{
294+
id: 'l-to-wildcard-escaped',
295+
pathname: `/params-ps/wildcard/test[s%5C/.%5C/parameter%25!%F0%9F%9A%80]`,
296+
params: {
297+
_splat: 'test[s\\/.\\/parameter%!🚀]',
298+
'*': 'test[s\\/.\\/parameter%!🚀]',
299+
},
300+
destHeadingId: 'ParamsWildcardSplat',
301+
},
302+
{
303+
id: 'l-to-wildcard-prefix-escaped',
304+
pathname: `/params-ps/wildcard/prefix@%EB%8C%80test[s%5C/.%5C/parameter%25!%F0%9F%9A%80]`,
305+
params: {
306+
_splat: 'test[s\\/.\\/parameter%!🚀]',
307+
'*': 'test[s\\/.\\/parameter%!🚀]',
308+
},
309+
destHeadingId: 'ParamsWildcardSplatPrefix',
310+
},
311+
{
312+
id: 'l-to-wildcard-suffix-escaped',
313+
pathname: `/params-ps/wildcard/test[s%5C/.%5C/parameter%25!%F0%9F%9A%80]suffix@%EB%8C%80`,
314+
params: {
315+
_splat: 'test[s\\/.\\/parameter%!🚀]',
316+
'*': 'test[s\\/.\\/parameter%!🚀]',
317+
},
318+
destHeadingId: 'ParamsWildcardSplatSuffix',
319+
},
293320
] satisfies Array<{
294321
id: string
295322
pathname: string

0 commit comments

Comments
 (0)