Skip to content

Commit e3a7e95

Browse files
committed
feat: add require-store-callbacks-use-set-param
1 parent b8e968e commit e3a7e95

File tree

11 files changed

+202
-0
lines changed

11 files changed

+202
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ These rules relate to possible syntax or logic errors in Svelte code:
271271
| [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: |
272272
| [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 | |
273273
| [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: |
274+
| [svelte/require-store-callbacks-use-set-param](https://ota-meshi.github.io/eslint-plugin-svelte/rules/require-store-callbacks-use-set-param/) | (no description) | |
274275
| [svelte/valid-compile](https://ota-meshi.github.io/eslint-plugin-svelte/rules/valid-compile/) | disallow warnings when compiling. | :star: |
275276

276277
## Security Vulnerability

docs/rules.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ These rules relate to possible syntax or logic errors in Svelte code:
2424
| [svelte/no-shorthand-style-property-overrides](./rules/no-shorthand-style-property-overrides.md) | disallow shorthand style properties that override related longhand properties | :star: |
2525
| [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 | |
2626
| [svelte/no-unknown-style-directive-property](./rules/no-unknown-style-directive-property.md) | disallow unknown `style:property` | :star: |
27+
| [svelte/require-store-callbacks-use-set-param](./rules/require-store-callbacks-use-set-param.md) | (no description) | |
2728
| [svelte/valid-compile](./rules/valid-compile.md) | disallow warnings when compiling. | :star: |
2829

2930
## Security Vulnerability
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
pageClass: "rule-details"
3+
sidebarDepth: 0
4+
title: "svelte/require-store-callbacks-use-set-param"
5+
description: ""
6+
---
7+
8+
# svelte/require-store-callbacks-use-set-param
9+
10+
> Store callbacks must use `set` param.
11+
12+
## :book: Rule Details
13+
14+
This rule disallows if readable / writable store's setter function doesn't use `set` parameter.
15+
16+
<ESLintCodeBlock>
17+
18+
<!--eslint-skip-->
19+
20+
```svelte
21+
<script>
22+
/* eslint svelte/require-store-callbacks-use-set-param: "error" */
23+
import { readable, writable, derived } from "svelte/store"
24+
25+
/** ✓ GOOD */
26+
readable(false, (set) => set(true))
27+
// `set` is unused but this rule doesn't report.
28+
// For that, please use `no-unused-vars` rule.
29+
// refer: https://eslint.org/docs/latest/rules/no-unused-vars
30+
readable(false, (set) => true)
31+
32+
writable(false, (set) => set(true))
33+
writable(false, (set) => true)
34+
35+
derived(a, ($a) => $a * 2)
36+
derived(
37+
a,
38+
($a, set) => {
39+
setTimeout(() => set($a), 1000)
40+
},
41+
"one moment...",
42+
)
43+
44+
/** ✗ BAD */
45+
readable(false, () => true)
46+
readable(false, (foo) => true)
47+
48+
writable(false, () => true)
49+
writable(false, (foo) => true)
50+
</script>
51+
```
52+
53+
</ESLintCodeBlock>
54+
55+
## :wrench: Options
56+
57+
Nothing.
58+
59+
## :books: Further Reading
60+
61+
- [Svelte - Docs > RUN TIME > svelte/store](https://svelte.dev/docs#run-time-svelte-store)
62+
63+
## :mag: Implementation
64+
65+
- [Rule source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/src/rules/require-store-callbacks-use-set-param.ts)
66+
- [Test source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/tests/src/rules/require-store-callbacks-use-set-param.ts)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// import { AST } from "svelte-eslint-parser"
2+
import { createRule } from "../utils"
3+
import { extractStoreReferences } from "./reference-helpers/svelte-store"
4+
5+
export default createRule("require-store-callbacks-use-set-param", {
6+
meta: {
7+
docs: {
8+
description: "",
9+
category: "Possible Errors",
10+
recommended: false,
11+
},
12+
schema: [],
13+
messages: {
14+
unexpected: "Store callbacks must use `set` param.",
15+
},
16+
type: "suggestion", // "problem", or "layout",
17+
},
18+
create(context) {
19+
return {
20+
Program() {
21+
for (const { node } of extractStoreReferences(context, [
22+
"readable",
23+
"writable",
24+
])) {
25+
const [_, fn] = node.arguments
26+
if (!fn || fn.type !== "ArrowFunctionExpression") {
27+
continue
28+
}
29+
const param = fn.params[0]
30+
if (!param || (param.type === "Identifier" && param.name !== "set")) {
31+
context.report({
32+
node: fn,
33+
loc: fn.loc!,
34+
messageId: "unexpected",
35+
})
36+
}
37+
}
38+
},
39+
}
40+
},
41+
})

src/utils/rules.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import preferClassDirective from "../rules/prefer-class-directive"
3333
import preferDestructuredStoreProps from "../rules/prefer-destructured-store-props"
3434
import preferStyleDirective from "../rules/prefer-style-directive"
3535
import requireOptimizedStyleAttribute from "../rules/require-optimized-style-attribute"
36+
import requireStoreCallbacksUseSetParam from "../rules/require-store-callbacks-use-set-param"
3637
import requireStoresInit from "../rules/require-stores-init"
3738
import shorthandAttribute from "../rules/shorthand-attribute"
3839
import shorthandDirective from "../rules/shorthand-directive"
@@ -76,6 +77,7 @@ export const rules = [
7677
preferDestructuredStoreProps,
7778
preferStyleDirective,
7879
requireOptimizedStyleAttribute,
80+
requireStoreCallbacksUseSetParam,
7981
requireStoresInit,
8082
shorthandAttribute,
8183
shorthandDirective,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
- message: Disallow self-closing on HTML elements.
2+
line: 3
3+
column: 3
4+
suggestions: null
5+
- message: Require self-closing on HTML void elements.
6+
line: 4
7+
column: 3
8+
suggestions: null
9+
- message: Disallow self-closing on Svelte custom components.
10+
line: 5
11+
column: 3
12+
suggestions: null
13+
- message: Require self-closing on Svelte special elements.
14+
line: 8
15+
column: 1
16+
suggestions: null
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
- message: Disallow self-closing on HTML elements.
2+
line: 3
3+
column: 3
4+
suggestions: null
5+
- message: Disallow self-closing on Svelte custom components.
6+
line: 4
7+
column: 3
8+
suggestions: null
9+
- message: Disallow self-closing on HTML void elements.
10+
line: 5
11+
column: 3
12+
suggestions: null
13+
- message: Disallow self-closing on Svelte special elements.
14+
line: 8
15+
column: 1
16+
suggestions: null
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
- message: Store callbacks must use `set` param.
2+
line: 4
3+
column: 19
4+
suggestions: null
5+
- message: Store callbacks must use `set` param.
6+
line: 5
7+
column: 19
8+
suggestions: null
9+
- message: Store callbacks must use `set` param.
10+
line: 7
11+
column: 19
12+
suggestions: null
13+
- message: Store callbacks must use `set` param.
14+
line: 8
15+
column: 19
16+
suggestions: null
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<script>
2+
import { readable, writable } from "svelte/store"
3+
4+
readable(false, () => true)
5+
readable(false, (foo) => true)
6+
7+
writable(false, () => true)
8+
writable(false, (foo) => true)
9+
</script>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<script>
2+
import { readable, writable, derived } from "svelte/store"
3+
4+
readable(false, (set) => set(true))
5+
readable(false, (set) => true)
6+
7+
writable(false, (set) => set(true))
8+
writable(false, (set) => true)
9+
10+
derived(a, ($a) => $a * 2)
11+
derived(
12+
a,
13+
($a, set) => {
14+
setTimeout(() => set($a), 1000)
15+
},
16+
"one moment...",
17+
)
18+
</script>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { RuleTester } from "eslint"
2+
import rule from "../../../src/rules/require-store-callbacks-use-set-param"
3+
import { loadTestCases } from "../../utils/utils"
4+
5+
const tester = new RuleTester({
6+
parserOptions: {
7+
ecmaVersion: 2020,
8+
sourceType: "module",
9+
},
10+
})
11+
12+
tester.run(
13+
"require-store-callbacks-use-set-param",
14+
rule as any,
15+
loadTestCases("require-store-callbacks-use-set-param"),
16+
)

0 commit comments

Comments
 (0)