Skip to content

Commit e5f59f4

Browse files
feat(eslint-plugin-router): route param name rule (#6473)
* feat(eslint-plugin-router): route param name rule * ci: apply automated fixes * remove support for magic pathless file routes * ci: apply automated fixes * coderabbit said so --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent 20d830e commit e5f59f4

7 files changed

Lines changed: 734 additions & 0 deletions

File tree

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
import { RuleTester } from '@typescript-eslint/rule-tester'
2+
3+
import { name, rule } from '../rules/route-param-names/route-param-names.rule'
4+
5+
const ruleTester = new RuleTester()
6+
7+
ruleTester.run(name, rule, {
8+
valid: [
9+
// Valid param names - simple $param format
10+
{
11+
name: 'valid simple param: $userId',
12+
code: `
13+
import { createFileRoute } from '@tanstack/react-router'
14+
const Route = createFileRoute('/users/$userId')({})
15+
`,
16+
},
17+
{
18+
name: 'valid simple param: $id',
19+
code: `
20+
import { createFileRoute } from '@tanstack/react-router'
21+
const Route = createFileRoute('/posts/$id')({})
22+
`,
23+
},
24+
{
25+
name: 'valid simple param: $_id (underscore prefix)',
26+
code: `
27+
import { createFileRoute } from '@tanstack/react-router'
28+
const Route = createFileRoute('/items/$_id')({})
29+
`,
30+
},
31+
{
32+
name: 'valid simple param: $$var (dollar prefix)',
33+
code: `
34+
import { createFileRoute } from '@tanstack/react-router'
35+
const Route = createFileRoute('/data/$$var')({})
36+
`,
37+
},
38+
{
39+
name: 'valid param with numbers: $user123',
40+
code: `
41+
import { createFileRoute } from '@tanstack/react-router'
42+
const Route = createFileRoute('/users/$user123')({})
43+
`,
44+
},
45+
46+
// Valid param names - braces format {$param}
47+
{
48+
name: 'valid braces param: {$userName}',
49+
code: `
50+
import { createFileRoute } from '@tanstack/react-router'
51+
const Route = createFileRoute('/users/{$userName}')({})
52+
`,
53+
},
54+
{
55+
name: 'valid braces param with prefix/suffix: prefix{$id}suffix',
56+
code: `
57+
import { createFileRoute } from '@tanstack/react-router'
58+
const Route = createFileRoute('/items/item-{$id}-details')({})
59+
`,
60+
},
61+
62+
// Valid optional params - {-$param}
63+
{
64+
name: 'valid optional param: {-$optional}',
65+
code: `
66+
import { createFileRoute } from '@tanstack/react-router'
67+
const Route = createFileRoute('/search/{-$query}')({})
68+
`,
69+
},
70+
{
71+
name: 'valid optional param with prefix/suffix: prefix{-$opt}suffix',
72+
code: `
73+
import { createFileRoute } from '@tanstack/react-router'
74+
const Route = createFileRoute('/filter/by-{-$category}-items')({})
75+
`,
76+
},
77+
78+
// Wildcards - should be skipped (no validation)
79+
{
80+
name: 'wildcard: $ alone',
81+
code: `
82+
import { createFileRoute } from '@tanstack/react-router'
83+
const Route = createFileRoute('/files/$')({})
84+
`,
85+
},
86+
{
87+
name: 'wildcard: {$}',
88+
code: `
89+
import { createFileRoute } from '@tanstack/react-router'
90+
const Route = createFileRoute('/catch/{$}')({})
91+
`,
92+
},
93+
94+
// Multiple valid params
95+
{
96+
name: 'multiple valid params in path',
97+
code: `
98+
import { createFileRoute } from '@tanstack/react-router'
99+
const Route = createFileRoute('/users/$userId/posts/$postId')({})
100+
`,
101+
},
102+
103+
// createRoute with path property
104+
{
105+
name: 'createRoute with valid param in path property',
106+
code: `
107+
import { createRoute } from '@tanstack/react-router'
108+
const Route = createRoute({ path: '/users/$userId' })
109+
`,
110+
},
111+
112+
// createLazyFileRoute
113+
{
114+
name: 'createLazyFileRoute with valid param',
115+
code: `
116+
import { createLazyFileRoute } from '@tanstack/react-router'
117+
const Route = createLazyFileRoute('/users/$userId')({})
118+
`,
119+
},
120+
121+
// createLazyRoute
122+
{
123+
name: 'createLazyRoute with valid param',
124+
code: `
125+
import { createLazyRoute } from '@tanstack/react-router'
126+
const Route = createLazyRoute('/users/$userId')({})
127+
`,
128+
},
129+
130+
// No params - should pass
131+
{
132+
name: 'no params in path',
133+
code: `
134+
import { createFileRoute } from '@tanstack/react-router'
135+
const Route = createFileRoute('/users/list')({})
136+
`,
137+
},
138+
139+
// Not from tanstack router - should be ignored
140+
{
141+
name: 'non-tanstack import should be ignored',
142+
code: `
143+
import { createFileRoute } from 'other-router'
144+
const Route = createFileRoute('/users/$123invalid')({})
145+
`,
146+
},
147+
],
148+
149+
invalid: [
150+
// Invalid param names - starts with number
151+
{
152+
name: 'invalid param starting with number: $123',
153+
code: `
154+
import { createFileRoute } from '@tanstack/react-router'
155+
const Route = createFileRoute('/users/$123')({})
156+
`,
157+
errors: [{ messageId: 'invalidParamName', data: { paramName: '123' } }],
158+
},
159+
{
160+
name: 'invalid param starting with number: $1user',
161+
code: `
162+
import { createFileRoute } from '@tanstack/react-router'
163+
const Route = createFileRoute('/users/$1user')({})
164+
`,
165+
errors: [{ messageId: 'invalidParamName', data: { paramName: '1user' } }],
166+
},
167+
168+
// Invalid param names - contains hyphen
169+
{
170+
name: 'invalid param with hyphen: $user-name',
171+
code: `
172+
import { createFileRoute } from '@tanstack/react-router'
173+
const Route = createFileRoute('/users/$user-name')({})
174+
`,
175+
errors: [
176+
{ messageId: 'invalidParamName', data: { paramName: 'user-name' } },
177+
],
178+
},
179+
180+
// Invalid param names - contains dot
181+
{
182+
name: 'invalid param with dot: {$my.param}',
183+
code: `
184+
import { createFileRoute } from '@tanstack/react-router'
185+
const Route = createFileRoute('/users/{$my.param}')({})
186+
`,
187+
errors: [
188+
{ messageId: 'invalidParamName', data: { paramName: 'my.param' } },
189+
],
190+
},
191+
192+
// Invalid param names - contains space
193+
{
194+
name: 'invalid param with space: {$param name}',
195+
code: `
196+
import { createFileRoute } from '@tanstack/react-router'
197+
const Route = createFileRoute('/users/{$param name}')({})
198+
`,
199+
errors: [
200+
{ messageId: 'invalidParamName', data: { paramName: 'param name' } },
201+
],
202+
},
203+
204+
// Invalid optional param
205+
{
206+
name: 'invalid optional param: {-$123invalid}',
207+
code: `
208+
import { createFileRoute } from '@tanstack/react-router'
209+
const Route = createFileRoute('/search/{-$123invalid}')({})
210+
`,
211+
errors: [
212+
{ messageId: 'invalidParamName', data: { paramName: '123invalid' } },
213+
],
214+
},
215+
216+
// Multiple invalid params
217+
{
218+
name: 'multiple invalid params in path',
219+
code: `
220+
import { createFileRoute } from '@tanstack/react-router'
221+
const Route = createFileRoute('/users/$1id/posts/$post-id')({})
222+
`,
223+
errors: [
224+
{ messageId: 'invalidParamName', data: { paramName: '1id' } },
225+
{ messageId: 'invalidParamName', data: { paramName: 'post-id' } },
226+
],
227+
},
228+
229+
// createRoute with invalid path property
230+
{
231+
name: 'createRoute with invalid param in path property',
232+
code: `
233+
import { createRoute } from '@tanstack/react-router'
234+
const Route = createRoute({ path: '/users/$123' })
235+
`,
236+
errors: [{ messageId: 'invalidParamName', data: { paramName: '123' } }],
237+
},
238+
239+
// createLazyFileRoute with invalid param
240+
{
241+
name: 'createLazyFileRoute with invalid param',
242+
code: `
243+
import { createLazyFileRoute } from '@tanstack/react-router'
244+
const Route = createLazyFileRoute('/users/$user-id')({})
245+
`,
246+
errors: [
247+
{ messageId: 'invalidParamName', data: { paramName: 'user-id' } },
248+
],
249+
},
250+
251+
// createLazyRoute with invalid param
252+
{
253+
name: 'createLazyRoute with invalid param',
254+
code: `
255+
import { createLazyRoute } from '@tanstack/react-router'
256+
const Route = createLazyRoute('/users/$1abc')({})
257+
`,
258+
errors: [{ messageId: 'invalidParamName', data: { paramName: '1abc' } }],
259+
},
260+
261+
// Invalid braces param with prefix/suffix
262+
{
263+
name: 'invalid braces param with prefix/suffix',
264+
code: `
265+
import { createFileRoute } from '@tanstack/react-router'
266+
const Route = createFileRoute('/items/item-{$123}-details')({})
267+
`,
268+
errors: [{ messageId: 'invalidParamName', data: { paramName: '123' } }],
269+
},
270+
],
271+
})

0 commit comments

Comments
 (0)