Skip to content

Commit 1b2016b

Browse files
committed
matchPath options object
1 parent 3f64c75 commit 1b2016b

5 files changed

Lines changed: 203 additions & 75 deletions

File tree

packages/router/src/__tests__/util.test.ts

Lines changed: 114 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -29,65 +29,91 @@ describe('matchPath', () => {
2929
['/blog/{year}/{month}/{day}', '/blog/2019/07'],
3030
['/posts/{id}/edit', '/posts//edit'],
3131
['/about', '/'],
32-
])('does not match route "%s" with path "%s"', (route, pathname) => {
33-
expect(matchPath(route, pathname)).toEqual({ match: false })
32+
])('does not match route "%s" with path "%s"', (path, pathname) => {
33+
expect(matchPath({ path, pathname })).toEqual({ match: false })
3434
})
3535

3636
it('matches valid paths and extracts params correctly', () => {
37-
expect(matchPath('/blog/{year}/{month}/{day}', '/blog/2019/12/07')).toEqual(
38-
{ match: true, params: { day: '07', month: '12', year: '2019' } }
39-
)
37+
expect(
38+
matchPath({
39+
path: '/blog/{year}/{month}/{day}',
40+
pathname: '/blog/2019/12/07',
41+
})
42+
).toEqual({ match: true, params: { day: '07', month: '12', year: '2019' } })
4043
})
4144

4245
it('transforms a param for Int', () => {
43-
expect(matchPath('/post/{id}', '/post/1337')).toEqual({
46+
expect(matchPath({ path: '/post/{id}', pathname: '/post/1337' })).toEqual({
4447
match: true,
4548
params: { id: '1337' },
4649
})
4750

48-
expect(matchPath('/post/{id:Int}', '/post/1337')).toEqual({
51+
expect(
52+
matchPath({ path: '/post/{id:Int}', pathname: '/post/1337' })
53+
).toEqual({
4954
match: true,
5055
params: { id: 1337 },
5156
})
5257

53-
expect(matchPath('/post/id-{id:Int}', '/post/id-37')).toEqual({
58+
expect(
59+
matchPath({ path: '/post/id-{id:Int}', pathname: '/post/id-37' })
60+
).toEqual({
5461
match: true,
5562
params: { id: 37 },
5663
})
5764

58-
expect(matchPath('/post/{id:Int}-id', '/post/78-id')).toEqual({
65+
expect(
66+
matchPath({ path: '/post/{id:Int}-id', pathname: '/post/78-id' })
67+
).toEqual({
5968
match: true,
6069
params: { id: 78 },
6170
})
6271

63-
expect(matchPath('/post/id-{id:Int}-id', '/post/id-789-id')).toEqual({
72+
expect(
73+
matchPath({ path: '/post/id-{id:Int}-id', pathname: '/post/id-789-id' })
74+
).toEqual({
6475
match: true,
6576
params: { id: 789 },
6677
})
6778

68-
expect(matchPath('/{id:Int}/bazinga', '/89/bazinga')).toEqual({
79+
expect(
80+
matchPath({ path: '/{id:Int}/bazinga', pathname: '/89/bazinga' })
81+
).toEqual({
6982
match: true,
7083
params: { id: 89 },
7184
})
7285
})
7386

7487
it('transforms a param for Boolean', () => {
75-
expect(matchPath('/signedUp/{status:Boolean}', '/signedUp/true')).toEqual({
88+
expect(
89+
matchPath({
90+
path: '/signedUp/{status:Boolean}',
91+
pathname: '/signedUp/true',
92+
})
93+
).toEqual({
7694
match: true,
7795
params: {
7896
status: true,
7997
},
8098
})
8199

82-
expect(matchPath('/signedUp/{status:Boolean}', '/signedUp/false')).toEqual({
100+
expect(
101+
matchPath({
102+
path: '/signedUp/{status:Boolean}',
103+
pathname: '/signedUp/false',
104+
})
105+
).toEqual({
83106
match: true,
84107
params: {
85108
status: false,
86109
},
87110
})
88111

89112
expect(
90-
matchPath('/signedUp/x-{status:Boolean}', '/signedUp/x-false')
113+
matchPath({
114+
path: '/signedUp/x-{status:Boolean}',
115+
pathname: '/signedUp/x-false',
116+
})
91117
).toEqual({
92118
match: true,
93119
params: {
@@ -96,7 +122,10 @@ describe('matchPath', () => {
96122
})
97123

98124
expect(
99-
matchPath('/signedUp/{status:Boolean}y', '/signedUp/falsey')
125+
matchPath({
126+
path: '/signedUp/{status:Boolean}y',
127+
pathname: '/signedUp/falsey',
128+
})
100129
).toEqual({
101130
match: true,
102131
params: {
@@ -105,7 +134,10 @@ describe('matchPath', () => {
105134
})
106135

107136
expect(
108-
matchPath('/signedUp/e{status:Boolean}y', '/signedUp/efalsey')
137+
matchPath({
138+
path: '/signedUp/e{status:Boolean}y',
139+
pathname: '/signedUp/efalsey',
140+
})
109141
).toEqual({
110142
match: true,
111143
params: {
@@ -114,33 +146,45 @@ describe('matchPath', () => {
114146
})
115147

116148
expect(
117-
matchPath('/signedUp/{status:Boolean}', '/signedUp/somethingElse')
149+
matchPath({
150+
path: '/signedUp/{status:Boolean}',
151+
pathname: '/signedUp/somethingElse',
152+
})
118153
).toEqual({
119154
match: false,
120155
})
121156
})
122157

123158
it('transforms a param for Floats', () => {
124159
expect(
125-
matchPath('/version/{floatyMcFloat:Float}', '/version/1.58')
160+
matchPath({
161+
path: '/version/{floatyMcFloat:Float}',
162+
pathname: '/version/1.58',
163+
})
126164
).toEqual({
127165
match: true,
128166
params: {
129167
floatyMcFloat: 1.58,
130168
},
131169
})
132170

133-
expect(matchPath('/version/{floatyMcFloat:Float}', '/version/626')).toEqual(
134-
{
135-
match: true,
136-
params: {
137-
floatyMcFloat: 626,
138-
},
139-
}
140-
)
171+
expect(
172+
matchPath({
173+
path: '/version/{floatyMcFloat:Float}',
174+
pathname: '/version/626',
175+
})
176+
).toEqual({
177+
match: true,
178+
params: {
179+
floatyMcFloat: 626,
180+
},
181+
})
141182

142183
expect(
143-
matchPath('/version/{floatyMcFloat:Float}', '/version/+0.92')
184+
matchPath({
185+
path: '/version/{floatyMcFloat:Float}',
186+
pathname: '/version/+0.92',
187+
})
144188
).toEqual({
145189
match: true,
146190
params: {
@@ -149,41 +193,57 @@ describe('matchPath', () => {
149193
})
150194

151195
expect(
152-
matchPath('/version/{floatyMcFloat:Float}', '/version/-5.5')
196+
matchPath({
197+
path: '/version/{floatyMcFloat:Float}',
198+
pathname: '/version/-5.5',
199+
})
153200
).toEqual({
154201
match: true,
155202
params: {
156203
floatyMcFloat: -5.5,
157204
},
158205
})
159206

160-
expect(matchPath('/version/{floatyMcFloat:Float}', '/version/4e8')).toEqual(
161-
{
162-
match: true,
163-
params: {
164-
floatyMcFloat: 4e8,
165-
},
166-
}
167-
)
207+
expect(
208+
matchPath({
209+
path: '/version/{floatyMcFloat:Float}',
210+
pathname: '/version/4e8',
211+
})
212+
).toEqual({
213+
match: true,
214+
params: {
215+
floatyMcFloat: 4e8,
216+
},
217+
})
168218

169219
expect(
170-
matchPath('/version/{floatyMcFloat:Float}', '/version/noMatchMe')
220+
matchPath({
221+
path: '/version/{floatyMcFloat:Float}',
222+
pathname: '/version/noMatchMe',
223+
})
171224
).toEqual({
172225
match: false,
173226
})
174227
})
175228

176229
it('transforms a param for Globs', () => {
177230
//single
178-
expect(matchPath('/version/{path...}', '/version/path/to/file')).toEqual({
231+
expect(
232+
matchPath({
233+
path: '/version/{path...}',
234+
pathname: '/version/path/to/file',
235+
})
236+
).toEqual({
179237
match: true,
180238
params: {
181239
path: 'path/to/file',
182240
},
183241
})
184242

185243
// multiple
186-
expect(matchPath('/a/{a...}/b/{b...}/c', '/a/1/2/b/3/4/c')).toEqual({
244+
expect(
245+
matchPath({ path: '/a/{a...}/b/{b...}/c', pathname: '/a/1/2/b/3/4/c' })
246+
).toEqual({
187247
match: true,
188248
params: {
189249
a: '1/2',
@@ -192,7 +252,9 @@ describe('matchPath', () => {
192252
})
193253

194254
// adjacent
195-
expect(matchPath('/a/{a...}{b...}/c', '/a/1/2/3/4/c')).toEqual({
255+
expect(
256+
matchPath({ path: '/a/{a...}{b...}/c', pathname: '/a/1/2/3/4/c' })
257+
).toEqual({
196258
match: true,
197259
params: {
198260
a: '1/2/3/4',
@@ -201,7 +263,9 @@ describe('matchPath', () => {
201263
})
202264

203265
// adjacent with a slash
204-
expect(matchPath('/a/{a...}/{b...}/c', '/a/1/2/3/4/c')).toEqual({
266+
expect(
267+
matchPath({ path: '/a/{a...}/{b...}/c', pathname: '/a/1/2/3/4/c' })
268+
).toEqual({
205269
match: true,
206270
params: {
207271
a: '1/2/3',
@@ -210,15 +274,17 @@ describe('matchPath', () => {
210274
})
211275

212276
// prefixed
213-
expect(matchPath('/a-{a...}', '/a-1/2')).toEqual({
277+
expect(matchPath({ path: '/a-{a...}', pathname: '/a-1/2' })).toEqual({
214278
match: true,
215279
params: {
216280
a: '1/2',
217281
},
218282
})
219283

220284
// suffixed
221-
expect(matchPath('/{a...}-a/kittens', '/1/2-a/kittens')).toEqual({
285+
expect(
286+
matchPath({ path: '/{a...}-a/kittens', pathname: '/1/2-a/kittens' })
287+
).toEqual({
222288
match: true,
223289
params: {
224290
a: '1/2',
@@ -228,10 +294,11 @@ describe('matchPath', () => {
228294

229295
it('handles multiple typed params', () => {
230296
expect(
231-
matchPath(
232-
'/dashboard/document/{id:Int}/{version:Float}/edit/{edit:Boolean}/{path...}/terminate',
233-
'/dashboard/document/44/1.8/edit/false/path/to/file/terminate'
234-
)
297+
matchPath({
298+
path: '/dashboard/document/{id:Int}/{version:Float}/edit/{edit:Boolean}/{path...}/terminate',
299+
pathname:
300+
'/dashboard/document/44/1.8/edit/false/path/to/file/terminate',
301+
})
235302
).toEqual({
236303
match: true,
237304
params: { id: 44, version: 1.8, edit: false, path: 'path/to/file' },

packages/router/src/links.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,11 @@ const useMatch = (pathname: string, options?: UseMatchOptions) => {
5858
}
5959
}
6060

61-
return matchPath(
62-
pathname,
63-
location.pathname,
64-
undefined,
65-
options?.matchChildRoutes
66-
)
61+
return matchPath({
62+
path: pathname,
63+
pathname: location.pathname,
64+
matchChildRoutes: options?.matchChildRoutes,
65+
})
6766
}
6867

6968
interface LinkProps {

packages/router/src/params.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ export const ParamsProvider: React.FC<Props> = ({
2929
const searchParams = parseSearch(internalLocation.search)
3030

3131
if (path) {
32-
const { match, params } = matchPath(
32+
const { match, params } = matchPath({
3333
path,
34-
internalLocation.pathname,
35-
paramTypes
36-
)
34+
pathname: internalLocation.pathname,
35+
paramTypes,
36+
})
3737

3838
if (match && typeof params !== 'undefined') {
3939
pathParams = params

packages/router/src/router.tsx

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@ const InternalRoute = ({
9090
throw new Error(`No location for route "${name}"`)
9191
}
9292

93-
const { params: pathParams } = matchPath(
93+
const { params: pathParams } = matchPath({
9494
path,
95-
location.pathname,
96-
routerState.paramTypes
97-
)
95+
pathname: location.pathname,
96+
paramTypes: routerState.paramTypes,
97+
})
9898

9999
const searchParams = parseSearch(location.search)
100100
const allParams: Record<string, string> = { ...searchParams, ...pathParams }
@@ -242,7 +242,11 @@ const LocationAwareRouter: React.FC<RouterProps> = ({
242242
// Check for issues with the path.
243243
validatePath(path)
244244

245-
const { params: pathParams } = matchPath(path, location.pathname, paramTypes)
245+
const { params: pathParams } = matchPath({
246+
path,
247+
pathname: location.pathname,
248+
paramTypes,
249+
})
246250

247251
const searchParams = parseSearch(location.search)
248252
const allParams = { ...searchParams, ...pathParams }
@@ -291,7 +295,11 @@ function analyzeRouterTree(
291295

292296
function isActiveRoute(route: React.ReactElement<InternalRouteProps>) {
293297
if (route.props.path) {
294-
const { match } = matchPath(route.props.path, pathname, paramTypes)
298+
const { match } = matchPath({
299+
path: route.props.path,
300+
pathname,
301+
paramTypes,
302+
})
295303

296304
if (match) {
297305
return true

0 commit comments

Comments
 (0)