Skip to content

Commit a91e5b3

Browse files
committed
Merge remote-tracking branch 'origin/main' into require-store-reactive-access
2 parents a8a5054 + 8da870f commit a91e5b3

Some content is hidden

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

45 files changed

+766
-1
lines changed

.changeset/fluffy-chicken-happen.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: add `require-store-callbacks-use-set-param` rule

.changeset/orange-months-sparkle.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: add `no-export-load-in-svelte-module-in-kit-pages` rule

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,28 @@ module.exports = {
216216
}
217217
```
218218

219+
#### settings.kit
220+
221+
If you use SvelteKit with not default configuration, you need to set below configurations.
222+
The schema is subset of SvelteKit's configuration.
223+
Therefore please check [SvelteKit docs](https://kit.svelte.dev/docs/configuration) for more details.
224+
225+
e.g.
226+
227+
```js
228+
module.exports = {
229+
// ...
230+
settings: {
231+
kit: {
232+
files: {
233+
routes: "src/routes",
234+
},
235+
},
236+
},
237+
// ...
238+
}
239+
```
240+
219241
### Running ESLint from the command line
220242

221243
If you want to run `eslint` from the command line, make sure you include the `.svelte` extension using [the `--ext` option](https://eslint.org/docs/user-guide/configuring#specifying-file-extensions-to-lint) or a glob pattern, because ESLint targets only `.js` files by default.
@@ -266,11 +288,13 @@ These rules relate to possible syntax or logic errors in Svelte code:
266288
| [svelte/no-dupe-else-if-blocks](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-dupe-else-if-blocks/) | disallow duplicate conditions in `{#if}` / `{:else if}` chains | :star: |
267289
| [svelte/no-dupe-style-properties](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-dupe-style-properties/) | disallow duplicate style properties | :star: |
268290
| [svelte/no-dynamic-slot-name](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-dynamic-slot-name/) | disallow dynamic slot name | :star::wrench: |
291+
| [svelte/no-export-load-in-svelte-module-in-kit-pages](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-export-load-in-svelte-module-in-kit-pages/) | disallow exporting load functions in `*.svelte` module in Svelte Kit page components. | |
269292
| [svelte/no-not-function-handler](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-not-function-handler/) | disallow use of not function in event handler | :star: |
270293
| [svelte/no-object-in-text-mustaches](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-object-in-text-mustaches/) | disallow objects in text mustache interpolation | :star: |
271294
| [svelte/no-shorthand-style-property-overrides](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-shorthand-style-property-overrides/) | disallow shorthand style properties that override related longhand properties | :star: |
272295
| [svelte/no-store-async](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-store-async/) | disallow using async/await inside svelte stores because it causes issues with the auto-unsubscribing features | |
273296
| [svelte/no-unknown-style-directive-property](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-unknown-style-directive-property/) | disallow unknown `style:property` | :star: |
297+
| [svelte/require-store-callbacks-use-set-param](https://ota-meshi.github.io/eslint-plugin-svelte/rules/require-store-callbacks-use-set-param/) | store callbacks must use `set` param | |
274298
| [svelte/require-store-reactive-access](https://ota-meshi.github.io/eslint-plugin-svelte/rules/require-store-reactive-access/) | disallow to render store itself. Need to use $ prefix or get function. | :wrench: |
275299
| [svelte/valid-compile](https://ota-meshi.github.io/eslint-plugin-svelte/rules/valid-compile/) | disallow warnings when compiling. | :star: |
276300

docs-svelte-kit/src/lib/components/ESLintCodeBlock.svelte

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
let tsParser = null
1616
1717
let code = ""
18+
export let config = {}
1819
export let rules = {}
1920
export let fix = false
2021
export let language = "svelte"
@@ -75,6 +76,7 @@
7576
browser: true,
7677
es2021: true,
7778
},
79+
...config,
7880
}}
7981
{language}
8082
{options}

docs/rules.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ These rules relate to possible syntax or logic errors in Svelte code:
1919
| [svelte/no-dupe-else-if-blocks](./rules/no-dupe-else-if-blocks.md) | disallow duplicate conditions in `{#if}` / `{:else if}` chains | :star: |
2020
| [svelte/no-dupe-style-properties](./rules/no-dupe-style-properties.md) | disallow duplicate style properties | :star: |
2121
| [svelte/no-dynamic-slot-name](./rules/no-dynamic-slot-name.md) | disallow dynamic slot name | :star::wrench: |
22+
| [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 Svelte Kit page components. | |
2223
| [svelte/no-not-function-handler](./rules/no-not-function-handler.md) | disallow use of not function in event handler | :star: |
2324
| [svelte/no-object-in-text-mustaches](./rules/no-object-in-text-mustaches.md) | disallow objects in text mustache interpolation | :star: |
2425
| [svelte/no-shorthand-style-property-overrides](./rules/no-shorthand-style-property-overrides.md) | disallow shorthand style properties that override related longhand properties | :star: |
2526
| [svelte/no-store-async](./rules/no-store-async.md) | disallow using async/await inside svelte stores because it causes issues with the auto-unsubscribing features | |
2627
| [svelte/no-unknown-style-directive-property](./rules/no-unknown-style-directive-property.md) | disallow unknown `style:property` | :star: |
28+
| [svelte/require-store-callbacks-use-set-param](./rules/require-store-callbacks-use-set-param.md) | store callbacks must use `set` param | |
2729
| [svelte/require-store-reactive-access](./rules/require-store-reactive-access.md) | disallow to render store itself. Need to use $ prefix or get function. | :wrench: |
2830
| [svelte/valid-compile](./rules/valid-compile.md) | disallow warnings when compiling. | :star: |
2931

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
pageClass: "rule-details"
3+
sidebarDepth: 0
4+
title: "svelte/no-export-load-in-svelte-module-in-kit-pages"
5+
description: "disallow exporting load functions in `*.svelte` module in Svelte Kit page components."
6+
---
7+
8+
# svelte/no-export-load-in-svelte-module-in-kit-pages
9+
10+
> disallow exporting load functions in `*.svelte` module in Svelte Kit page components.
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 unexpected exported `load` function at `<script context="module">`.
17+
At SvelteKit v1.0.0-next.405, `load` function has been moved into a separate file — `+page.js` for pages, `+layout.js` for layouts.
18+
And the API has changed.
19+
20+
<script>
21+
const config = {
22+
settings: {
23+
kit: {
24+
files: {
25+
routes: "",
26+
},
27+
},
28+
},
29+
}
30+
</script>
31+
32+
<ESLintCodeBlock config="{config}">
33+
34+
<!--eslint-skip-->
35+
36+
```svelte
37+
<script context="module">
38+
/* eslint svelte/no-export-load-in-svelte-module-in-kit-pages: "error" */
39+
/* ✓ GOOD */
40+
export function foo() {}
41+
export function bar() {}
42+
/* ✗ BAD */
43+
export function load() {}
44+
// export const load = () => {}
45+
</script>
46+
```
47+
48+
</ESLintCodeBlock>
49+
50+
## :wrench: Options
51+
52+
Nothing. But if use are using not default routes folder, please set configuration according to the [user guide](../user-guide.md#settings-kit).
53+
54+
## :books: Further Reading
55+
56+
- [SvelteKit Migration Guide (v1.0.0-next.405)](https://github.com/sveltejs/kit/discussions/5774#discussioncomment-3292693)
57+
58+
## :mag: Implementation
59+
60+
- [Rule source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts)
61+
- [Test source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/tests/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts)
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
pageClass: "rule-details"
3+
sidebarDepth: 0
4+
title: "svelte/require-store-callbacks-use-set-param"
5+
description: "store callbacks must use `set` param"
6+
---
7+
8+
# svelte/require-store-callbacks-use-set-param
9+
10+
> store callbacks must use `set` param
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 disallows if `readable` / `writable` store's setter function doesn't use `set` parameter.<br>
17+
This rule doesn't check `derived` store. Therefore if you set a updated value asynchronously, please don't forget to use `set` function.
18+
19+
<ESLintCodeBlock>
20+
21+
<!--eslint-skip-->
22+
23+
```svelte
24+
<script>
25+
/* eslint svelte/require-store-callbacks-use-set-param: "error" */
26+
import { readable, writable, derived } from "svelte/store"
27+
28+
/** ✓ GOOD */
29+
readable(null, (set) => {
30+
set(new Date())
31+
const interval = setInterval(() => set(new Date()), 1000)
32+
return () => clearInterval(interval)
33+
})
34+
35+
// `set` is unused but this rule doesn't report.
36+
// For that, please use `no-unused-vars` rule.
37+
// refer: https://eslint.org/docs/latest/rules/no-unused-vars
38+
readable(false, (set) => true)
39+
40+
writable(null, (set) => {
41+
set(1)
42+
return () => { /* no more subscribers */ }
43+
})
44+
45+
writable(false, (set) => true)
46+
47+
derived(a, ($a) => $a * 2)
48+
derived(
49+
a,
50+
($a, set) => {
51+
setTimeout(() => set($a), 1000)
52+
},
53+
"one moment...",
54+
)
55+
56+
/** ✗ BAD */
57+
readable(false, () => true)
58+
readable(false, (foo) => true)
59+
60+
writable(false, () => true)
61+
writable(false, (foo) => true)
62+
</script>
63+
```
64+
65+
</ESLintCodeBlock>
66+
67+
## :wrench: Options
68+
69+
Nothing.
70+
71+
## :books: Further Reading
72+
73+
- [Svelte - Docs > RUN TIME > svelte/store](https://svelte.dev/docs#run-time-svelte-store)
74+
75+
## :mag: Implementation
76+
77+
- [Rule source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/src/rules/require-store-callbacks-use-set-param.ts)
78+
- [Test source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/tests/src/rules/require-store-callbacks-use-set-param.ts)

docs/user-guide.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,28 @@ module.exports = {
168168
}
169169
```
170170

171+
#### settings.kit
172+
173+
If you use SvelteKit with not default configuration, you need to set below configurations.
174+
The schema is subset of SvelteKit's configuration.
175+
Therefore please check [SvelteKit docs](https://kit.svelte.dev/docs/configuration) for more details.
176+
177+
e.g.
178+
179+
```js
180+
module.exports = {
181+
// ...
182+
settings: {
183+
kit: {
184+
files: {
185+
routes: "src/routes",
186+
},
187+
},
188+
},
189+
// ...
190+
}
191+
```
192+
171193
### Running ESLint from the command line
172194

173195
If you want to run `eslint` from the command line, make sure you include the `.svelte` extension using [the `--ext` option](https://eslint.org/docs/user-guide/configuring#specifying-file-extensions-to-lint) or a glob pattern, because ESLint targets only `.js` files by default.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@
174174
"access": "public"
175175
},
176176
"typeCoverage": {
177-
"atLeast": 98.71,
177+
"atLeast": 98.7,
178178
"cache": true,
179179
"detail": true,
180180
"ignoreAsAssertion": true,
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import type * as ESTree from "estree"
2+
import { createRule } from "../utils"
3+
import { isKitPageComponent } from "../utils/svelte-kit"
4+
5+
export default createRule("no-export-load-in-svelte-module-in-kit-pages", {
6+
meta: {
7+
docs: {
8+
description:
9+
"disallow exporting load functions in `*.svelte` module in Svelte Kit page components.",
10+
category: "Possible Errors",
11+
// TODO Switch to recommended in the major version.
12+
recommended: false,
13+
},
14+
schema: [],
15+
messages: {
16+
unexpected:
17+
"disallow exporting load functions in `*.svelte` module in Svelte Kit page components.",
18+
},
19+
type: "problem",
20+
},
21+
create(context) {
22+
if (!isKitPageComponent(context)) {
23+
return {}
24+
}
25+
let isModule = false
26+
return {
27+
// <script context="module">
28+
[`Program > SvelteScriptElement > SvelteStartTag > SvelteAttribute[key.name="context"] > SvelteLiteral[value="module"]`]:
29+
() => {
30+
isModule = true
31+
},
32+
33+
// </script>
34+
"Program > SvelteScriptElement:exit": () => {
35+
isModule = false
36+
},
37+
38+
// export function load() {}
39+
// export const load = () => {}
40+
[`:matches(ExportNamedDeclaration > FunctionDeclaration, ExportNamedDeclaration > VariableDeclaration > VariableDeclarator) > Identifier.id[name="load"]`]:
41+
(node: ESTree.Identifier) => {
42+
if (!isModule) return {}
43+
return context.report({
44+
node,
45+
loc: node.loc!,
46+
messageId: "unexpected",
47+
})
48+
},
49+
}
50+
},
51+
})
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { createRule } from "../utils"
2+
import { extractStoreReferences } from "./reference-helpers/svelte-store"
3+
4+
export default createRule("require-store-callbacks-use-set-param", {
5+
meta: {
6+
docs: {
7+
description: "store callbacks must use `set` param",
8+
category: "Possible Errors",
9+
recommended: false,
10+
},
11+
schema: [],
12+
messages: {
13+
unexpected: "Store callbacks must use `set` param.",
14+
},
15+
type: "suggestion",
16+
},
17+
create(context) {
18+
return {
19+
Program() {
20+
for (const { node } of extractStoreReferences(context, [
21+
"readable",
22+
"writable",
23+
])) {
24+
const [_, fn] = node.arguments
25+
if (
26+
!fn ||
27+
(fn.type !== "ArrowFunctionExpression" &&
28+
fn.type !== "FunctionExpression")
29+
) {
30+
continue
31+
}
32+
const param = fn.params[0]
33+
if (!param || (param.type === "Identifier" && param.name !== "set")) {
34+
context.report({
35+
node: fn,
36+
loc: fn.loc!,
37+
messageId: "unexpected",
38+
})
39+
}
40+
}
41+
},
42+
}
43+
},
44+
})

src/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ export type RuleContext = {
128128
postcss?: false | { configFilePath?: unknown }
129129
}
130130
}
131+
["kit"]?: {
132+
files?: {
133+
routes?: string
134+
}
135+
}
131136
}
132137
parserPath: string
133138
parserOptions: Linter.ParserOptions

0 commit comments

Comments
 (0)