Skip to content

Commit 248ca37

Browse files
committed
fix(no-navigation-without-resolve): allowing undefined and null in link hrefs
1 parent 854f774 commit 248ca37

File tree

4 files changed

+89
-0
lines changed

4 files changed

+89
-0
lines changed

packages/eslint-plugin-svelte/src/rules/no-navigation-without-resolve.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,11 @@ export default createRule('no-navigation-without-resolve', {
9797
}
9898
if (
9999
(node.value[0].type === 'SvelteLiteral' &&
100+
!expressionIsNullish(new FindVariableContext(context), node.value[0]) &&
100101
!expressionIsAbsolute(new FindVariableContext(context), node.value[0]) &&
101102
!expressionIsFragment(new FindVariableContext(context), node.value[0])) ||
102103
(node.value[0].type === 'SvelteMustacheTag' &&
104+
!expressionIsNullish(new FindVariableContext(context), node.value[0].expression) &&
103105
!expressionIsAbsolute(new FindVariableContext(context), node.value[0].expression) &&
104106
!expressionIsFragment(new FindVariableContext(context), node.value[0].expression) &&
105107
!isResolveCall(
@@ -263,6 +265,45 @@ function expressionIsEmpty(url: TSESTree.CallExpressionArgument): boolean {
263265
);
264266
}
265267

268+
function expressionIsNullish(
269+
ctx: FindVariableContext,
270+
url: AST.SvelteLiteral | TSESTree.Expression
271+
): boolean {
272+
switch (url.type) {
273+
case 'Identifier':
274+
return identifierIsNullish(ctx, url);
275+
case 'Literal':
276+
return url.value === null; // Undefined is an Identifier in ESTree, null is a Literal
277+
case 'TemplateLiteral':
278+
return templateLiteralIsNullish(ctx, url);
279+
default:
280+
return false;
281+
}
282+
}
283+
284+
function identifierIsNullish(ctx: FindVariableContext, url: TSESTree.Identifier): boolean {
285+
if (url.name === 'undefined') {
286+
return true;
287+
}
288+
const variable = ctx.findVariable(url);
289+
if (
290+
variable === null ||
291+
variable.identifiers.length === 0 ||
292+
variable.identifiers[0].parent.type !== 'VariableDeclarator' ||
293+
variable.identifiers[0].parent.init === null
294+
) {
295+
return false;
296+
}
297+
return expressionIsNullish(ctx, variable.identifiers[0].parent.init);
298+
}
299+
300+
function templateLiteralIsNullish(
301+
ctx: FindVariableContext,
302+
url: TSESTree.TemplateLiteral
303+
): boolean {
304+
return url.expressions.length === 1 && expressionIsNullish(ctx, url.expressions[0]);
305+
}
306+
266307
function expressionIsAbsolute(
267308
ctx: FindVariableContext,
268309
url: AST.SvelteLiteral | TSESTree.Expression
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
- message: Unexpected href link without resolve().
2+
line: 6
3+
column: 10
4+
suggestions: null
5+
- message: Unexpected href link without resolve().
6+
line: 7
7+
column: 10
8+
suggestions: null
9+
- message: Unexpected href link without resolve().
10+
line: 8
11+
column: 9
12+
suggestions: null
13+
- message: Unexpected href link without resolve().
14+
line: 9
15+
column: 9
16+
suggestions: null
17+
- message: Unexpected href link without resolve().
18+
line: 10
19+
column: 9
20+
suggestions: null
21+
- message: Unexpected href link without resolve().
22+
line: 11
23+
column: 9
24+
suggestions: null
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<script>
2+
const one = "undefined";
3+
const two = "null";
4+
</script>
5+
6+
<a href="undefined">Click me!</a>
7+
<a href="null">Click me!</a>
8+
<a href={one}>Click me!</a>
9+
<a href={two}>Click me!</a>
10+
<a href={`undefined`}>Click me!</a>
11+
<a href={`null`}>Click me!</a>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script>
2+
const one = undefined;
3+
const two = null;
4+
</script>
5+
6+
<a href={undefined}>Click me!</a>
7+
<a href={null}>Click me!</a>
8+
<a href={one}>Click me!</a>
9+
<a href={two}>Click me!</a>
10+
<a href={`${undefined}`}>Click me!</a>
11+
<a href={`${null}`}>Click me!</a>
12+
<a href={`${one}`}>Click me!</a>
13+
<a href={`${two}`}>Click me!</a>

0 commit comments

Comments
 (0)