Skip to content

Commit e2e791f

Browse files
feat: replaced no-navigation-without-base with no-navigation-without-resolve (#1289)
Co-authored-by: Yosuke Ota <[email protected]>
1 parent a1e90aa commit e2e791f

File tree

67 files changed

+832
-14
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+832
-14
lines changed

.changeset/huge-taxis-jog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'eslint-plugin-svelte': minor
3+
---
4+
5+
feat: added the no-navigation-without-resolve rule

.changeset/loud-rockets-lay.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'eslint-plugin-svelte': minor
3+
---
4+
5+
chore: deprecated the no-navigation-without-base rule

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ These rules relate to SvelteKit and its best Practices.
363363
| Rule ID | Description | |
364364
|:--------|:------------|:---|
365365
| [svelte/no-export-load-in-svelte-module-in-kit-pages](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-export-load-in-svelte-module-in-kit-pages/) | disallow exporting load functions in `*.svelte` module in SvelteKit page components. | :star: |
366-
| [svelte/no-navigation-without-base](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-navigation-without-base/) | disallow using navigation (links, goto, pushState, replaceState) without the base path | |
366+
| [svelte/no-navigation-without-resolve](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-navigation-without-resolve/) | disallow using navigation (links, goto, pushState, replaceState) without a resolve() | |
367367
| [svelte/valid-prop-names-in-kit-pages](https://sveltejs.github.io/eslint-plugin-svelte/rules/valid-prop-names-in-kit-pages/) | disallow props other than data or errors in SvelteKit page components. | :star: |
368368

369369
## Experimental
@@ -393,7 +393,8 @@ These rules relate to this plugin works:
393393
|:--------|:------------|
394394
| [svelte/@typescript-eslint/no-unnecessary-condition](https://sveltejs.github.io/eslint-plugin-svelte/rules/@typescript-eslint/no-unnecessary-condition/) | This rule is no longer needed when using svelte-eslint-parser>=v0.19.0. |
395395
| [svelte/no-dynamic-slot-name](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-dynamic-slot-name/) | Now Svelte compiler itself throws an compile error. |
396-
| [svelte/no-goto-without-base](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-goto-without-base/) | [svelte/no-navigation-without-base](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-navigation-without-base/) |
396+
| [svelte/no-goto-without-base](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-goto-without-base/) | [svelte/no-navigation-without-resolve](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-navigation-without-resolve/) |
397+
| [svelte/no-navigation-without-base](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-navigation-without-base/) | [svelte/no-navigation-without-resolve](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-navigation-without-resolve/) |
397398

398399
<!--RULES_TABLE_END-->
399400
<!--RULES_SECTION_END-->

docs/rules.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,11 @@ These rules extend the rules provided by ESLint itself, or other plugins to work
117117

118118
These rules relate to SvelteKit and its best Practices.
119119

120-
| Rule ID | Description | |
121-
| :------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------- | :----- |
122-
| [svelte/no-export-load-in-svelte-module-in-kit-pages](./rules/no-export-load-in-svelte-module-in-kit-pages.md) | disallow exporting load functions in `*.svelte` module in SvelteKit page components. | :star: |
123-
| [svelte/no-navigation-without-base](./rules/no-navigation-without-base.md) | disallow using navigation (links, goto, pushState, replaceState) without the base path | |
124-
| [svelte/valid-prop-names-in-kit-pages](./rules/valid-prop-names-in-kit-pages.md) | disallow props other than data or errors in SvelteKit page components. | :star: |
120+
| Rule ID | Description | |
121+
| :------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------- | :----- |
122+
| [svelte/no-export-load-in-svelte-module-in-kit-pages](./rules/no-export-load-in-svelte-module-in-kit-pages.md) | disallow exporting load functions in `*.svelte` module in SvelteKit page components. | :star: |
123+
| [svelte/no-navigation-without-resolve](./rules/no-navigation-without-resolve.md) | disallow using navigation (links, goto, pushState, replaceState) without a resolve() | |
124+
| [svelte/valid-prop-names-in-kit-pages](./rules/valid-prop-names-in-kit-pages.md) | disallow props other than data or errors in SvelteKit page components. | :star: |
125125

126126
## Experimental
127127

@@ -146,8 +146,9 @@ These rules relate to this plugin works:
146146
- :warning: We're going to remove deprecated rules in the next major release. Please migrate to successor/new rules.
147147
- :innocent: We don't fix bugs which are in deprecated rules since we don't have enough resources.
148148

149-
| Rule ID | Replaced by |
150-
| :----------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------- |
151-
| [svelte/@typescript-eslint/no-unnecessary-condition](./rules/@typescript-eslint/no-unnecessary-condition.md) | This rule is no longer needed when using svelte-eslint-parser>=v0.19.0. |
152-
| [svelte/no-dynamic-slot-name](./rules/no-dynamic-slot-name.md) | Now Svelte compiler itself throws an compile error. |
153-
| [svelte/no-goto-without-base](./rules/no-goto-without-base.md) | [svelte/no-navigation-without-base](./rules/no-navigation-without-base.md) |
149+
| Rule ID | Replaced by |
150+
| :----------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------- |
151+
| [svelte/@typescript-eslint/no-unnecessary-condition](./rules/@typescript-eslint/no-unnecessary-condition.md) | This rule is no longer needed when using svelte-eslint-parser>=v0.19.0. |
152+
| [svelte/no-dynamic-slot-name](./rules/no-dynamic-slot-name.md) | Now Svelte compiler itself throws an compile error. |
153+
| [svelte/no-goto-without-base](./rules/no-goto-without-base.md) | [svelte/no-navigation-without-resolve](./rules/no-navigation-without-resolve.md) |
154+
| [svelte/no-navigation-without-base](./rules/no-navigation-without-base.md) | [svelte/no-navigation-without-resolve](./rules/no-navigation-without-resolve.md) |

docs/rules/no-goto-without-base.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ since: 'v2.36.0-next.9'
1010

1111
> disallow using goto() without the base path
1212
13-
- :warning: This rule was **deprecated** and replaced by [svelte/no-navigation-without-base](no-navigation-without-base.md) rule.
13+
- :warning: This rule was **deprecated** and replaced by [svelte/no-navigation-without-resolve](no-navigation-without-resolve.md) rule.
1414

1515
## :book: Rule Details
1616

docs/rules/no-navigation-without-base.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ since: 'v2.36.0-next.9'
1010

1111
> disallow using navigation (links, goto, pushState, replaceState) without the base path
1212
13+
- :warning: This rule was **deprecated** and replaced by [svelte/no-navigation-without-resolve](no-navigation-without-resolve.md) rule.
14+
1315
## :book: Rule Details
1416

1517
This rule reports navigation using HTML `<a>` tags, SvelteKit's `goto()`, `pushState()` and `replaceState()` functions without prefixing a relative URL with the base path. All four of these may be used for navigation, with `goto()`, `pushState()` and `replaceState()` being intended solely for iternal navigation (i.e. not leaving the site), while `<a>` tags may be used for both internal and external navigation. When using any way of internal navigation, the base path must be prepended, otherwise the site may break. For programmatic navigation to external URLs, using `window.location` is advised.
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
---
2+
pageClass: 'rule-details'
3+
sidebarDepth: 0
4+
title: 'svelte/no-navigation-without-resolve'
5+
description: 'disallow using navigation (links, goto, pushState, replaceState) without a resolve()'
6+
---
7+
8+
# svelte/no-navigation-without-resolve
9+
10+
> disallow using navigation (links, goto, pushState, replaceState) without a resolve()
11+
12+
- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> **_This rule has not been released yet._** </badge>
13+
14+
## :book: Rule Details
15+
16+
This rule reports navigation using HTML `<a>` tags, SvelteKit's `goto()`, `pushState()` and `replaceState()` functions without resolving a relative URL. All four of these may be used for navigation, with `goto()`, `pushState()` and `replaceState()` being intended solely for iternal navigation (i.e. not leaving the site), while `<a>` tags may be used for both internal and external navigation. When using any way of internal navigation, the URL must be resolved using SvelteKit's `resolve()`, otherwise the site may break. For programmatic navigation to external URLs, using `window.location` is advised.
17+
18+
This rule checks all 4 navigation options for the presence of the `resolve()` fucntion call, with an exception for `<a>` links to absolute URLs (and fragment URLs), which are assumed to be used for external navigation and so do not require the `resolve()` function, and for shallow outing functions with an empty string as the path, which keeps the current URL.
19+
20+
<!--eslint-skip-->
21+
22+
```svelte
23+
<script>
24+
/* eslint svelte/no-navigation-without-resolve: "error" */
25+
26+
import { goto, pushState, replaceState } from '$app/navigation';
27+
import { resolve } from '$app/paths';
28+
29+
// ✓ GOOD
30+
goto(resolve('/foo/'));
31+
32+
pushState(resolve('/foo/'), {});
33+
pushState('', {});
34+
35+
replaceState(resolve('/foo/'), {});
36+
replaceState('', {});
37+
38+
// ✗ BAD
39+
goto('/foo');
40+
goto('/foo' + resolve('/bar'));
41+
goto(resolve('/foo') + '/bar');
42+
43+
pushState('/foo', {});
44+
replaceState('/foo', {});
45+
</script>
46+
47+
<!-- ✓ GOOD -->
48+
<a href={resolve('/foo/')}>Click me!</a>
49+
<a href="https://svelte.dev">Click me!</a>
50+
51+
<!-- ✗ BAD -->
52+
<a href="/foo">Click me!</a>
53+
<a href={'/foo'}>Click me!</a>
54+
```
55+
56+
## :wrench: Options
57+
58+
```json
59+
{
60+
"svelte/no-navigation-without-resolve": [
61+
"error",
62+
{
63+
"ignoreGoto": false,
64+
"ignoreLinks": false,
65+
"ignorePushState": false,
66+
"ignoreReplaceState": false
67+
}
68+
]
69+
}
70+
```
71+
72+
- `ignoreGoto` ... Whether to ignore all `goto()` calls. Default `false`.
73+
- `ignoreLinks` ... Whether to ignore all `<a>` tags. Default `false`.
74+
- `ignorePushState` ... Whether to ignore all `pushState()` calls. Default `false`.
75+
- `ignoreReplaceState` ... Whether to ignore all `replaceState()` calls. Default `false`.
76+
77+
## :books: Further Reading
78+
79+
- [`resolve()` documentation](https://svelte.dev/docs/kit/$app-paths#resolve)
80+
- [Shallow routing](https://svelte.dev/docs/kit/shallow-routing)
81+
- [`goto()` documentation](https://svelte.dev/docs/kit/$app-navigation#goto)
82+
- [`pushState()` documentation](https://svelte.dev/docs/kit/$app-navigation#pushState)
83+
- [`replaceState()` documentation](https://svelte.dev/docs/kit/$app-navigation#replaceState)
84+
85+
## :mag: Implementation
86+
87+
- [Rule source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/packages/eslint-plugin-svelte/src/rules/no-navigation-without-resolve.ts)
88+
- [Test source](https://github.com/sveltejs/eslint-plugin-svelte/blob/main/packages/eslint-plugin-svelte/tests/src/rules/no-navigation-without-resolve.ts)

packages/eslint-plugin-svelte/src/rule-types.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,14 @@ export interface RuleOptions {
189189
/**
190190
* disallow using navigation (links, goto, pushState, replaceState) without the base path
191191
* @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-navigation-without-base/
192+
* @deprecated
192193
*/
193194
'svelte/no-navigation-without-base'?: Linter.RuleEntry<SvelteNoNavigationWithoutBase>
195+
/**
196+
* disallow using navigation (links, goto, pushState, replaceState) without a resolve()
197+
* @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-navigation-without-resolve/
198+
*/
199+
'svelte/no-navigation-without-resolve'?: Linter.RuleEntry<SvelteNoNavigationWithoutResolve>
194200
/**
195201
* disallow use of not function in event handler
196202
* @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-not-function-handler/
@@ -518,6 +524,13 @@ type SvelteNoNavigationWithoutBase = []|[{
518524
ignorePushState?: boolean
519525
ignoreReplaceState?: boolean
520526
}]
527+
// ----- svelte/no-navigation-without-resolve -----
528+
type SvelteNoNavigationWithoutResolve = []|[{
529+
ignoreGoto?: boolean
530+
ignoreLinks?: boolean
531+
ignorePushState?: boolean
532+
ignoreReplaceState?: boolean
533+
}]
521534
// ----- svelte/no-reactive-reassign -----
522535
type SvelteNoReactiveReassign = []|[{
523536
props?: boolean

packages/eslint-plugin-svelte/src/rules/no-goto-without-base.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { RuleContext } from '../types.js';
77
export default createRule('no-goto-without-base', {
88
meta: {
99
deprecated: true,
10-
replacedBy: ['no-navigation-without-base'],
10+
replacedBy: ['no-navigation-without-resolve'],
1111
docs: {
1212
description: 'disallow using goto() without the base path',
1313
category: 'SvelteKit',

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import type { AST } from 'svelte-eslint-parser';
88

99
export default createRule('no-navigation-without-base', {
1010
meta: {
11+
deprecated: true,
12+
replacedBy: ['no-navigation-without-resolve'],
1113
docs: {
1214
description:
1315
'disallow using navigation (links, goto, pushState, replaceState) without the base path',

0 commit comments

Comments
 (0)