eslint-plugin-svelte 2.5.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -39
- package/lib/configs/prettier.d.ts +1 -0
- package/lib/configs/prettier.js +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/rules/derived-has-same-inputs-outputs.d.ts +2 -0
- package/lib/rules/derived-has-same-inputs-outputs.js +80 -0
- package/lib/rules/html-self-closing.js +48 -16
- package/lib/rules/no-store-async.d.ts +2 -0
- package/lib/rules/no-store-async.js +46 -0
- package/lib/rules/no-trailing-spaces.d.ts +2 -0
- package/lib/rules/no-trailing-spaces.js +91 -0
- package/lib/rules/reference-helpers/svelte-store.d.ts +8 -0
- package/lib/rules/reference-helpers/svelte-store.js +27 -0
- package/lib/rules/require-stores-init.js +2 -24
- package/lib/utils/rules.js +6 -0
- package/package.json +48 -15
package/README.md
CHANGED
|
@@ -13,6 +13,12 @@ You can check on the [Online DEMO](https://ota-meshi.github.io/eslint-plugin-sve
|
|
|
13
13
|
[](http://www.npmtrends.com/eslint-plugin-svelte)
|
|
14
14
|
[](https://github.com/ota-meshi/eslint-plugin-svelte/actions?query=workflow%3ACI)
|
|
15
15
|
|
|
16
|
+
[](https://lgtm.com/projects/g/ota-meshi/eslint-plugin-svelte/context:javascript)
|
|
17
|
+
[](https://github.com/plantain-00/type-coverage)
|
|
18
|
+
[](https://conventionalcommits.org)
|
|
19
|
+
[](https://github.com/prettier/prettier)
|
|
20
|
+
[](https://github.com/atlassian/changesets)
|
|
21
|
+
|
|
16
22
|
## :name_badge: What is this plugin?
|
|
17
23
|
|
|
18
24
|
[ESLint] plugin for [Svelte].
|
|
@@ -61,7 +67,7 @@ npm install --save-dev eslint eslint-plugin-svelte svelte
|
|
|
61
67
|
|
|
62
68
|
### Configuration
|
|
63
69
|
|
|
64
|
-
Use `.eslintrc.*` file to configure rules. See also:
|
|
70
|
+
Use `.eslintrc.*` file to configure rules. See also: <https://eslint.org/docs/user-guide/configuring>.
|
|
65
71
|
|
|
66
72
|
Example **.eslintrc.js**:
|
|
67
73
|
|
|
@@ -176,7 +182,7 @@ module.exports = {
|
|
|
176
182
|
}
|
|
177
183
|
```
|
|
178
184
|
|
|
179
|
-
See also
|
|
185
|
+
See also <https://github.com/ota-meshi/svelte-eslint-parser#readme>.
|
|
180
186
|
|
|
181
187
|
#### settings.svelte
|
|
182
188
|
|
|
@@ -242,6 +248,7 @@ Example **.vscode/settings.json**:
|
|
|
242
248
|
|
|
243
249
|
## :white_check_mark: Rules
|
|
244
250
|
|
|
251
|
+
<!-- prettier-ignore-start -->
|
|
245
252
|
<!--RULES_SECTION_START-->
|
|
246
253
|
|
|
247
254
|
:wrench: Indicates that the rule is fixable, and using `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the reported problems.
|
|
@@ -262,6 +269,7 @@ These rules relate to possible syntax or logic errors in Svelte code:
|
|
|
262
269
|
| [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: |
|
|
263
270
|
| [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: |
|
|
264
271
|
| [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: |
|
|
272
|
+
| [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 | |
|
|
265
273
|
| [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: |
|
|
266
274
|
| [svelte/valid-compile](https://ota-meshi.github.io/eslint-plugin-svelte/rules/valid-compile/) | disallow warnings when compiling. | :star: |
|
|
267
275
|
|
|
@@ -295,6 +303,7 @@ These rules relate to style guidelines, and are therefore quite subjective:
|
|
|
295
303
|
|
|
296
304
|
| Rule ID | Description | |
|
|
297
305
|
|:--------|:------------|:---|
|
|
306
|
+
| [svelte/derived-has-same-inputs-outputs](https://ota-meshi.github.io/eslint-plugin-svelte/rules/derived-has-same-inputs-outputs/) | derived store should use same variable names between values and callback | |
|
|
298
307
|
| [svelte/first-attribute-linebreak](https://ota-meshi.github.io/eslint-plugin-svelte/rules/first-attribute-linebreak/) | enforce the location of first attribute | :wrench: |
|
|
299
308
|
| [svelte/html-closing-bracket-spacing](https://ota-meshi.github.io/eslint-plugin-svelte/rules/html-closing-bracket-spacing/) | require or disallow a space before tag's closing brackets | :wrench: |
|
|
300
309
|
| [svelte/html-quotes](https://ota-meshi.github.io/eslint-plugin-svelte/rules/html-quotes/) | enforce quotes style of HTML attributes | :wrench: |
|
|
@@ -318,6 +327,7 @@ These rules extend the rules provided by ESLint itself to work well in Svelte:
|
|
|
318
327
|
| Rule ID | Description | |
|
|
319
328
|
|:--------|:------------|:---|
|
|
320
329
|
| [svelte/no-inner-declarations](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-inner-declarations/) | disallow variable or `function` declarations in nested blocks | :star: |
|
|
330
|
+
| [svelte/no-trailing-spaces](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-trailing-spaces/) | disallow trailing whitespace at the end of lines | :wrench: |
|
|
321
331
|
|
|
322
332
|
## System
|
|
323
333
|
|
|
@@ -330,6 +340,7 @@ These rules relate to this plugin works:
|
|
|
330
340
|
|
|
331
341
|
<!--RULES_TABLE_END-->
|
|
332
342
|
<!--RULES_SECTION_END-->
|
|
343
|
+
<!-- prettier-ignore-end -->
|
|
333
344
|
|
|
334
345
|
<!--DOCS_IGNORE_START-->
|
|
335
346
|
|
|
@@ -339,43 +350,7 @@ Welcome contributing!
|
|
|
339
350
|
|
|
340
351
|
Please use GitHub's Issues/PRs.
|
|
341
352
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
- `yarn test` runs tests.
|
|
345
|
-
- `yarn cover` runs tests and measures coverage.
|
|
346
|
-
- `yarn new [new-rule-name]` generate the files needed to implement the new rule.
|
|
347
|
-
- `yarn update` runs in order to update readme and recommended configuration.
|
|
348
|
-
- `yarn docs:watch` launch the document site in development mode.
|
|
349
|
-
|
|
350
|
-
### Test the Rule
|
|
351
|
-
|
|
352
|
-
Rule testing almost always uses fixtures.
|
|
353
|
-
For example, for an `indent` rule, the `.ts` file that runs the test is `tests/src/rules/indent.ts` and the fixture is in `tests/fixtures/rules/indent`.
|
|
354
|
-
The fixture directory has an `invalid` directory and a `valid` directory.
|
|
355
|
-
|
|
356
|
-
- The `invalid` directory contains test cases where the rule reports problems.
|
|
357
|
-
- The `valid` directory contains test cases where the rule does not report a problem.
|
|
358
|
-
|
|
359
|
-
The fixture input file should be named `*-input.svelte`. It is automatically collected and tested.
|
|
360
|
-
If your test requires configuration, you need to add a json file with the configuration.
|
|
361
|
-
|
|
362
|
-
- If you want to apply a configuration to `my-test-input.svelte`, add `my-test-config.json`.
|
|
363
|
-
- If you want to apply the same configuration to all the fixtures in that directory, add `_config.json`.
|
|
364
|
-
|
|
365
|
-
To verify the output of invalid test cases requires `*-errors.json`, and `*-output.svelte` (for auto-fix). However, you don't have to add them yourself. If they do not exist, they will be automatically generated when you run the test. In other words, delete them manually when you want to recreate them.
|
|
366
|
-
|
|
367
|
-
**Tips**:
|
|
368
|
-
|
|
369
|
-
If you want to test only one rule, run the following command (for `indent` rule):
|
|
370
|
-
|
|
371
|
-
```sh
|
|
372
|
-
yarn test -g indent
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
Take <https://stackoverflow.com/questions/10832031/how-to-run-a-single-test-with-mocha> as reference for details.
|
|
376
|
-
|
|
377
|
-
If you want to test only `my-test-input.svelte`, add `my-test-config.json` and save `{"only": true}`.
|
|
378
|
-
(Note that `{"only": true}` must be removed before making a pull request.)
|
|
353
|
+
See also [CONTRIBUTING.md](./CONTRIBUTING.md)
|
|
379
354
|
|
|
380
355
|
### Working With Rules
|
|
381
356
|
|
|
@@ -9,6 +9,7 @@ declare const _default: {
|
|
|
9
9
|
"svelte/max-attributes-per-line": string;
|
|
10
10
|
"svelte/mustache-spacing": string;
|
|
11
11
|
"svelte/no-spaces-around-equal-signs-in-attribute": string;
|
|
12
|
+
"svelte/no-trailing-spaces": string;
|
|
12
13
|
"svelte/shorthand-attribute": string;
|
|
13
14
|
"svelte/shorthand-directive": string;
|
|
14
15
|
};
|
package/lib/configs/prettier.js
CHANGED
|
@@ -16,6 +16,7 @@ module.exports = {
|
|
|
16
16
|
"svelte/max-attributes-per-line": "off",
|
|
17
17
|
"svelte/mustache-spacing": "off",
|
|
18
18
|
"svelte/no-spaces-around-equal-signs-in-attribute": "off",
|
|
19
|
+
"svelte/no-trailing-spaces": "off",
|
|
19
20
|
"svelte/shorthand-attribute": "off",
|
|
20
21
|
"svelte/shorthand-directive": "off",
|
|
21
22
|
},
|
package/lib/index.d.ts
CHANGED
|
@@ -44,6 +44,7 @@ declare const _default: {
|
|
|
44
44
|
"svelte/max-attributes-per-line": string;
|
|
45
45
|
"svelte/mustache-spacing": string;
|
|
46
46
|
"svelte/no-spaces-around-equal-signs-in-attribute": string;
|
|
47
|
+
"svelte/no-trailing-spaces": string;
|
|
47
48
|
"svelte/shorthand-attribute": string;
|
|
48
49
|
"svelte/shorthand-directive": string;
|
|
49
50
|
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("../utils");
|
|
4
|
+
const svelte_store_1 = require("./reference-helpers/svelte-store");
|
|
5
|
+
exports.default = (0, utils_1.createRule)("derived-has-same-inputs-outputs", {
|
|
6
|
+
meta: {
|
|
7
|
+
docs: {
|
|
8
|
+
description: "derived store should use same variable names between values and callback",
|
|
9
|
+
category: "Stylistic Issues",
|
|
10
|
+
recommended: false,
|
|
11
|
+
conflictWithPrettier: false,
|
|
12
|
+
},
|
|
13
|
+
schema: [],
|
|
14
|
+
messages: {
|
|
15
|
+
unexpected: "The argument name should be '{{name}}'.",
|
|
16
|
+
},
|
|
17
|
+
type: "suggestion",
|
|
18
|
+
},
|
|
19
|
+
create(context) {
|
|
20
|
+
function isIdentifierOrArrayExpression(node) {
|
|
21
|
+
return ["Identifier", "ArrayExpression"].includes(node.type);
|
|
22
|
+
}
|
|
23
|
+
function isFunctionExpression(node) {
|
|
24
|
+
return ["ArrowFunctionExpression", "FunctionExpression"].includes(node.type);
|
|
25
|
+
}
|
|
26
|
+
function checkIdentifier(context, args, fn) {
|
|
27
|
+
const fnParam = fn.params[0];
|
|
28
|
+
if (fnParam.type !== "Identifier")
|
|
29
|
+
return;
|
|
30
|
+
const expectedName = `$${args.name}`;
|
|
31
|
+
if (expectedName !== fnParam.name) {
|
|
32
|
+
context.report({
|
|
33
|
+
node: fn,
|
|
34
|
+
loc: fnParam.loc,
|
|
35
|
+
messageId: "unexpected",
|
|
36
|
+
data: { name: expectedName },
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function checkArrayExpression(context, args, fn) {
|
|
41
|
+
const fnParam = fn.params[0];
|
|
42
|
+
if (fnParam.type !== "ArrayPattern")
|
|
43
|
+
return;
|
|
44
|
+
const argNames = args.elements.map((element) => {
|
|
45
|
+
return element && element.type === "Identifier" ? element.name : null;
|
|
46
|
+
});
|
|
47
|
+
fnParam.elements.forEach((element, index) => {
|
|
48
|
+
const argName = argNames[index];
|
|
49
|
+
if (element && element.type === "Identifier" && argName) {
|
|
50
|
+
const expectedName = `$${argName}`;
|
|
51
|
+
if (expectedName !== element.name) {
|
|
52
|
+
context.report({
|
|
53
|
+
node: fn,
|
|
54
|
+
loc: element.loc,
|
|
55
|
+
messageId: "unexpected",
|
|
56
|
+
data: { name: expectedName },
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
Program() {
|
|
64
|
+
for (const { node } of (0, svelte_store_1.extractStoreReferences)(context, ["derived"])) {
|
|
65
|
+
const [args, fn] = node.arguments;
|
|
66
|
+
if (!args || !isIdentifierOrArrayExpression(args))
|
|
67
|
+
continue;
|
|
68
|
+
if (!fn || !isFunctionExpression(fn))
|
|
69
|
+
continue;
|
|
70
|
+
if (!fn.params || fn.params.length === 0)
|
|
71
|
+
continue;
|
|
72
|
+
if (args.type === "Identifier")
|
|
73
|
+
checkIdentifier(context, args, fn);
|
|
74
|
+
else
|
|
75
|
+
checkArrayExpression(context, args, fn);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
},
|
|
80
|
+
});
|
|
@@ -24,33 +24,65 @@ exports.default = (0, utils_1.createRule)("html-self-closing", {
|
|
|
24
24
|
},
|
|
25
25
|
schema: [
|
|
26
26
|
{
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
anyOf: [
|
|
28
|
+
{
|
|
29
|
+
properties: {
|
|
30
|
+
void: {
|
|
31
|
+
enum: ["never", "always", "ignore"],
|
|
32
|
+
},
|
|
33
|
+
normal: {
|
|
34
|
+
enum: ["never", "always", "ignore"],
|
|
35
|
+
},
|
|
36
|
+
component: {
|
|
37
|
+
enum: ["never", "always", "ignore"],
|
|
38
|
+
},
|
|
39
|
+
svelte: {
|
|
40
|
+
enum: ["never", "always", "ignore"],
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
additionalProperties: false,
|
|
31
44
|
},
|
|
32
|
-
|
|
33
|
-
enum: ["
|
|
45
|
+
{
|
|
46
|
+
enum: ["all", "html", "none"],
|
|
34
47
|
},
|
|
35
|
-
|
|
36
|
-
enum: ["never", "always", "ignore"],
|
|
37
|
-
},
|
|
38
|
-
svelte: {
|
|
39
|
-
enum: ["never", "always", "ignore"],
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
additionalProperties: false,
|
|
48
|
+
],
|
|
43
49
|
},
|
|
44
50
|
],
|
|
45
51
|
},
|
|
46
52
|
create(ctx) {
|
|
47
|
-
|
|
53
|
+
let options = {
|
|
48
54
|
void: "always",
|
|
49
55
|
normal: "always",
|
|
50
56
|
component: "always",
|
|
51
57
|
svelte: "always",
|
|
52
|
-
...ctx.options?.[0],
|
|
53
58
|
};
|
|
59
|
+
const option = ctx.options?.[0];
|
|
60
|
+
switch (option) {
|
|
61
|
+
case "none":
|
|
62
|
+
options = {
|
|
63
|
+
void: "never",
|
|
64
|
+
normal: "never",
|
|
65
|
+
component: "never",
|
|
66
|
+
svelte: "never",
|
|
67
|
+
};
|
|
68
|
+
break;
|
|
69
|
+
case "html":
|
|
70
|
+
options = {
|
|
71
|
+
void: "always",
|
|
72
|
+
normal: "never",
|
|
73
|
+
component: "never",
|
|
74
|
+
svelte: "always",
|
|
75
|
+
};
|
|
76
|
+
break;
|
|
77
|
+
default:
|
|
78
|
+
if (typeof option !== "object" || option === null)
|
|
79
|
+
break;
|
|
80
|
+
options = {
|
|
81
|
+
...options,
|
|
82
|
+
...option,
|
|
83
|
+
};
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
54
86
|
function getElementType(node) {
|
|
55
87
|
if (node.kind === "component")
|
|
56
88
|
return "component";
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("../utils");
|
|
4
|
+
const svelte_store_1 = require("./reference-helpers/svelte-store");
|
|
5
|
+
exports.default = (0, utils_1.createRule)("no-store-async", {
|
|
6
|
+
meta: {
|
|
7
|
+
docs: {
|
|
8
|
+
description: "disallow using async/await inside svelte stores because it causes issues with the auto-unsubscribing features",
|
|
9
|
+
category: "Possible Errors",
|
|
10
|
+
recommended: false,
|
|
11
|
+
default: "error",
|
|
12
|
+
},
|
|
13
|
+
schema: [],
|
|
14
|
+
messages: {
|
|
15
|
+
unexpected: "Do not pass async functions to svelte stores.",
|
|
16
|
+
},
|
|
17
|
+
type: "problem",
|
|
18
|
+
},
|
|
19
|
+
create(context) {
|
|
20
|
+
return {
|
|
21
|
+
Program() {
|
|
22
|
+
for (const { node } of (0, svelte_store_1.extractStoreReferences)(context)) {
|
|
23
|
+
const [, fn] = node.arguments;
|
|
24
|
+
if (!fn ||
|
|
25
|
+
(fn.type !== "ArrowFunctionExpression" &&
|
|
26
|
+
fn.type !== "FunctionExpression") ||
|
|
27
|
+
!fn.async) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const start = fn.loc.start;
|
|
31
|
+
context.report({
|
|
32
|
+
node: fn,
|
|
33
|
+
loc: {
|
|
34
|
+
start,
|
|
35
|
+
end: {
|
|
36
|
+
line: start.line,
|
|
37
|
+
column: start.column + 5,
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
messageId: "unexpected",
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
});
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("../utils");
|
|
4
|
+
exports.default = (0, utils_1.createRule)("no-trailing-spaces", {
|
|
5
|
+
meta: {
|
|
6
|
+
type: "layout",
|
|
7
|
+
docs: {
|
|
8
|
+
description: "disallow trailing whitespace at the end of lines",
|
|
9
|
+
category: "Extension Rules",
|
|
10
|
+
recommended: false,
|
|
11
|
+
extensionRule: "no-trailing-spaces",
|
|
12
|
+
conflictWithPrettier: true,
|
|
13
|
+
},
|
|
14
|
+
fixable: "whitespace",
|
|
15
|
+
schema: [
|
|
16
|
+
{
|
|
17
|
+
type: "object",
|
|
18
|
+
properties: {
|
|
19
|
+
skipBlankLines: { type: "boolean" },
|
|
20
|
+
ignoreComments: { type: "boolean" },
|
|
21
|
+
},
|
|
22
|
+
additionalProperties: false,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
messages: {
|
|
26
|
+
trailingSpace: "Trailing spaces not allowed.",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
create(context) {
|
|
30
|
+
const options = context.options[0];
|
|
31
|
+
const skipBlankLines = options?.skipBlankLines || false;
|
|
32
|
+
const ignoreComments = options?.ignoreComments || false;
|
|
33
|
+
const sourceCode = context.getSourceCode();
|
|
34
|
+
const ignoreLineNumbers = new Set();
|
|
35
|
+
if (ignoreComments) {
|
|
36
|
+
for (const { type, loc } of sourceCode.getAllComments()) {
|
|
37
|
+
const endLine = type === "Block" ? loc.end.line - 1 : loc.end.line;
|
|
38
|
+
for (let i = loc.start.line; i <= endLine; i++) {
|
|
39
|
+
ignoreLineNumbers.add(i);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function report(loc) {
|
|
44
|
+
context.report({
|
|
45
|
+
loc,
|
|
46
|
+
messageId: "trailingSpace",
|
|
47
|
+
fix(fixer) {
|
|
48
|
+
return fixer.removeRange([
|
|
49
|
+
sourceCode.getIndexFromLoc(loc.start),
|
|
50
|
+
sourceCode.getIndexFromLoc(loc.end),
|
|
51
|
+
]);
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function collectIgnoreLineNumbers({ loc }) {
|
|
56
|
+
const endLine = loc.end.line - 1;
|
|
57
|
+
for (let i = loc.start.line; i <= endLine; i++) {
|
|
58
|
+
ignoreLineNumbers.add(i);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
TemplateElement: collectIgnoreLineNumbers,
|
|
63
|
+
...(ignoreComments
|
|
64
|
+
? {
|
|
65
|
+
SvelteHTMLComment: collectIgnoreLineNumbers,
|
|
66
|
+
}
|
|
67
|
+
: {}),
|
|
68
|
+
"Program:exit"() {
|
|
69
|
+
const lines = sourceCode.lines;
|
|
70
|
+
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
|
|
71
|
+
const line = lines[lineIndex];
|
|
72
|
+
if (skipBlankLines && !line.trim()) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const lineNumber = lineIndex + 1;
|
|
76
|
+
if (ignoreLineNumbers.has(lineNumber)) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const trimmed = line.trimEnd();
|
|
80
|
+
if (trimmed === line) {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
report({
|
|
84
|
+
start: { line: lineNumber, column: trimmed.length },
|
|
85
|
+
end: { line: lineNumber, column: line.length },
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
},
|
|
91
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type * as ESTree from "estree";
|
|
2
|
+
import type { RuleContext } from "../../types";
|
|
3
|
+
declare type StoreName = "writable" | "readable" | "derived";
|
|
4
|
+
export declare function extractStoreReferences(context: RuleContext, storeNames?: StoreName[]): Generator<{
|
|
5
|
+
node: ESTree.CallExpression;
|
|
6
|
+
name: string;
|
|
7
|
+
}, void>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractStoreReferences = void 0;
|
|
4
|
+
const eslint_utils_1 = require("eslint-utils");
|
|
5
|
+
function* extractStoreReferences(context, storeNames = ["writable", "readable", "derived"]) {
|
|
6
|
+
const referenceTracker = new eslint_utils_1.ReferenceTracker(context.getScope());
|
|
7
|
+
for (const { node, path } of referenceTracker.iterateEsmReferences({
|
|
8
|
+
"svelte/store": {
|
|
9
|
+
[eslint_utils_1.ReferenceTracker.ESM]: true,
|
|
10
|
+
writable: {
|
|
11
|
+
[eslint_utils_1.ReferenceTracker.CALL]: storeNames.includes("writable"),
|
|
12
|
+
},
|
|
13
|
+
readable: {
|
|
14
|
+
[eslint_utils_1.ReferenceTracker.CALL]: storeNames.includes("readable"),
|
|
15
|
+
},
|
|
16
|
+
derived: {
|
|
17
|
+
[eslint_utils_1.ReferenceTracker.CALL]: storeNames.includes("derived"),
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
})) {
|
|
21
|
+
yield {
|
|
22
|
+
node: node,
|
|
23
|
+
name: path[path.length - 1],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.extractStoreReferences = extractStoreReferences;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const utils_1 = require("../utils");
|
|
4
|
-
const
|
|
4
|
+
const svelte_store_1 = require("./reference-helpers/svelte-store");
|
|
5
5
|
exports.default = (0, utils_1.createRule)("require-stores-init", {
|
|
6
6
|
meta: {
|
|
7
7
|
docs: {
|
|
@@ -16,31 +16,9 @@ exports.default = (0, utils_1.createRule)("require-stores-init", {
|
|
|
16
16
|
type: "suggestion",
|
|
17
17
|
},
|
|
18
18
|
create(context) {
|
|
19
|
-
function* extractStoreReferences() {
|
|
20
|
-
const referenceTracker = new eslint_utils_1.ReferenceTracker(context.getScope());
|
|
21
|
-
for (const { node, path } of referenceTracker.iterateEsmReferences({
|
|
22
|
-
"svelte/store": {
|
|
23
|
-
[eslint_utils_1.ReferenceTracker.ESM]: true,
|
|
24
|
-
writable: {
|
|
25
|
-
[eslint_utils_1.ReferenceTracker.CALL]: true,
|
|
26
|
-
},
|
|
27
|
-
readable: {
|
|
28
|
-
[eslint_utils_1.ReferenceTracker.CALL]: true,
|
|
29
|
-
},
|
|
30
|
-
derived: {
|
|
31
|
-
[eslint_utils_1.ReferenceTracker.CALL]: true,
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
})) {
|
|
35
|
-
yield {
|
|
36
|
-
node: node,
|
|
37
|
-
name: path[path.length - 1],
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
19
|
return {
|
|
42
20
|
Program() {
|
|
43
|
-
for (const { node, name } of extractStoreReferences()) {
|
|
21
|
+
for (const { node, name } of (0, svelte_store_1.extractStoreReferences)(context)) {
|
|
44
22
|
const minArgs = name === "writable" || name === "readable"
|
|
45
23
|
? 1
|
|
46
24
|
: name === "derived"
|
package/lib/utils/rules.js
CHANGED
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.rules = void 0;
|
|
7
7
|
const button_has_type_1 = __importDefault(require("../rules/button-has-type"));
|
|
8
8
|
const comment_directive_1 = __importDefault(require("../rules/comment-directive"));
|
|
9
|
+
const derived_has_same_inputs_outputs_1 = __importDefault(require("../rules/derived-has-same-inputs-outputs"));
|
|
9
10
|
const first_attribute_linebreak_1 = __importDefault(require("../rules/first-attribute-linebreak"));
|
|
10
11
|
const html_closing_bracket_spacing_1 = __importDefault(require("../rules/html-closing-bracket-spacing"));
|
|
11
12
|
const html_quotes_1 = __importDefault(require("../rules/html-quotes"));
|
|
@@ -26,7 +27,9 @@ const no_reactive_functions_1 = __importDefault(require("../rules/no-reactive-fu
|
|
|
26
27
|
const no_reactive_literals_1 = __importDefault(require("../rules/no-reactive-literals"));
|
|
27
28
|
const no_shorthand_style_property_overrides_1 = __importDefault(require("../rules/no-shorthand-style-property-overrides"));
|
|
28
29
|
const no_spaces_around_equal_signs_in_attribute_1 = __importDefault(require("../rules/no-spaces-around-equal-signs-in-attribute"));
|
|
30
|
+
const no_store_async_1 = __importDefault(require("../rules/no-store-async"));
|
|
29
31
|
const no_target_blank_1 = __importDefault(require("../rules/no-target-blank"));
|
|
32
|
+
const no_trailing_spaces_1 = __importDefault(require("../rules/no-trailing-spaces"));
|
|
30
33
|
const no_unknown_style_directive_property_1 = __importDefault(require("../rules/no-unknown-style-directive-property"));
|
|
31
34
|
const no_unused_svelte_ignore_1 = __importDefault(require("../rules/no-unused-svelte-ignore"));
|
|
32
35
|
const no_useless_mustaches_1 = __importDefault(require("../rules/no-useless-mustaches"));
|
|
@@ -43,6 +46,7 @@ const valid_compile_1 = __importDefault(require("../rules/valid-compile"));
|
|
|
43
46
|
exports.rules = [
|
|
44
47
|
button_has_type_1.default,
|
|
45
48
|
comment_directive_1.default,
|
|
49
|
+
derived_has_same_inputs_outputs_1.default,
|
|
46
50
|
first_attribute_linebreak_1.default,
|
|
47
51
|
html_closing_bracket_spacing_1.default,
|
|
48
52
|
html_quotes_1.default,
|
|
@@ -63,7 +67,9 @@ exports.rules = [
|
|
|
63
67
|
no_reactive_literals_1.default,
|
|
64
68
|
no_shorthand_style_property_overrides_1.default,
|
|
65
69
|
no_spaces_around_equal_signs_in_attribute_1.default,
|
|
70
|
+
no_store_async_1.default,
|
|
66
71
|
no_target_blank_1.default,
|
|
72
|
+
no_trailing_spaces_1.default,
|
|
67
73
|
no_unknown_style_directive_property_1.default,
|
|
68
74
|
no_unused_svelte_ignore_1.default,
|
|
69
75
|
no_useless_mustaches_1.default,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-svelte",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
4
4
|
"description": "ESLint plugin for Svelte using AST",
|
|
5
5
|
"repository": "git+https://github.com/ota-meshi/eslint-plugin-svelte.git",
|
|
6
6
|
"homepage": "https://ota-meshi.github.io/eslint-plugin-svelte",
|
|
@@ -34,20 +34,26 @@
|
|
|
34
34
|
"docs:build": "yarn svelte-kit build",
|
|
35
35
|
"docs:preview": "yarn svelte-kit preview",
|
|
36
36
|
"docs:watch": "yarn svelte-kit dev",
|
|
37
|
-
"eslint-fix": "eslint . --fix",
|
|
38
37
|
"format-for-gen-file": "eslint src/types-for-node.ts src/utils/rules.ts src/configs --fix",
|
|
39
|
-
"
|
|
38
|
+
"install-with-ignore-engines": "yarn --ignore-engines",
|
|
39
|
+
"lint": "run-p lint:*",
|
|
40
|
+
"lint-fix": "yarn lint:es --fix && yarn lint:style --fix",
|
|
41
|
+
"lint:es": "eslint --cache -f friendly .",
|
|
42
|
+
"lint:style": "stylelint --cache .",
|
|
40
43
|
"mocha": "yarn ts ./node_modules/mocha/bin/mocha.js",
|
|
41
44
|
"new": "yarn ts ./tools/new-rule.ts",
|
|
42
45
|
"prebuild": "yarn clean",
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
+
"prepare": "simple-git-hooks && yarn-deduplicate --strategy fewer || exit 0",
|
|
47
|
+
"prerelease": "yarn clean && yarn build",
|
|
48
|
+
"release": "changeset publish",
|
|
46
49
|
"svelte-kit": "node --experimental-loader ./svelte-kit-import-hook.mjs node_modules/vite/bin/vite.js",
|
|
47
50
|
"test": "yarn mocha \"tests/src/**/*.ts\" --reporter dot --timeout 60000",
|
|
51
|
+
"test:debug": "env-cmd -e debug yarn test",
|
|
48
52
|
"ts": "node -r esbuild-register",
|
|
53
|
+
"typecov": "type-coverage",
|
|
49
54
|
"update": "yarn ts ./tools/update.ts && yarn format-for-gen-file",
|
|
50
|
-
"version": "env-cmd -e version yarn update
|
|
55
|
+
"version": "env-cmd -e version yarn update",
|
|
56
|
+
"version:ci": "env-cmd -e version-ci yarn update && changeset version"
|
|
51
57
|
},
|
|
52
58
|
"peerDependencies": {
|
|
53
59
|
"eslint": "^7.0.0 || ^8.0.0-0",
|
|
@@ -69,15 +75,23 @@
|
|
|
69
75
|
"svelte-eslint-parser": "^0.18.0"
|
|
70
76
|
},
|
|
71
77
|
"devDependencies": {
|
|
78
|
+
"@1stg/browserslist-config": "^1.2.3",
|
|
79
|
+
"@1stg/commitlint-config": "^3.1.4",
|
|
80
|
+
"@1stg/lint-staged": "^3.3.0",
|
|
81
|
+
"@1stg/remark-config": "^4.0.3",
|
|
82
|
+
"@1stg/simple-git-hooks": "^0.2.1",
|
|
83
|
+
"@1stg/stylelint-config": "^4.6.1",
|
|
72
84
|
"@babel/core": "^7.16.0",
|
|
73
85
|
"@babel/eslint-parser": "^7.17.0",
|
|
74
86
|
"@babel/plugin-proposal-function-bind": "^7.16.7",
|
|
75
87
|
"@babel/types": "^7.16.0",
|
|
88
|
+
"@changesets/changelog-github": "^0.4.6",
|
|
89
|
+
"@changesets/cli": "^2.24.2",
|
|
76
90
|
"@fontsource/fira-mono": "^4.5.0",
|
|
77
|
-
"@ota-meshi/eslint-plugin": "^0.
|
|
91
|
+
"@ota-meshi/eslint-plugin": "^0.12.0",
|
|
78
92
|
"@sindresorhus/slugify": "^2.1.0",
|
|
79
|
-
"@sveltejs/adapter-static": "^1.0.0-next.
|
|
80
|
-
"@sveltejs/kit": "^1.0.0-next.
|
|
93
|
+
"@sveltejs/adapter-static": "^1.0.0-next.40",
|
|
94
|
+
"@sveltejs/kit": "^1.0.0-next.456",
|
|
81
95
|
"@types/babel__core": "^7.1.19",
|
|
82
96
|
"@types/cross-spawn": "^6.0.2",
|
|
83
97
|
"@types/escape-html": "^1.0.2",
|
|
@@ -99,17 +113,20 @@
|
|
|
99
113
|
"@typescript-eslint/parser": "^5.4.1-0",
|
|
100
114
|
"@typescript-eslint/parser-v4": "npm:@typescript-eslint/parser@4",
|
|
101
115
|
"assert": "^2.0.0",
|
|
116
|
+
"commitlint": "^17.0.3",
|
|
102
117
|
"env-cmd": "^10.1.0",
|
|
103
118
|
"esbuild": "^0.15.0",
|
|
104
119
|
"esbuild-register": "^3.2.0",
|
|
105
120
|
"escape-html": "^1.0.3",
|
|
106
121
|
"eslint": "^8.0.0",
|
|
107
122
|
"eslint-config-prettier": "^8.3.0",
|
|
123
|
+
"eslint-formatter-friendly": "^7.0.0",
|
|
108
124
|
"eslint-plugin-eslint-comments": "^3.2.0",
|
|
109
125
|
"eslint-plugin-eslint-plugin": "^5.0.0",
|
|
110
126
|
"eslint-plugin-json-schema-validator": "^4.0.0",
|
|
111
127
|
"eslint-plugin-jsonc": "^2.0.0",
|
|
112
128
|
"eslint-plugin-markdown": "^3.0.0",
|
|
129
|
+
"eslint-plugin-mdx": "^2.0.2",
|
|
113
130
|
"eslint-plugin-node": "^11.1.0",
|
|
114
131
|
"eslint-plugin-node-dependencies": "^0.9.0",
|
|
115
132
|
"eslint-plugin-prettier": "^4.0.0",
|
|
@@ -119,33 +136,49 @@
|
|
|
119
136
|
"eslint-scope": "^7.1.1",
|
|
120
137
|
"estree-walker": "^3.0.0",
|
|
121
138
|
"less": "^4.1.2",
|
|
139
|
+
"lint-staged": "^13.0.3",
|
|
122
140
|
"locate-character": "^2.0.5",
|
|
123
141
|
"magic-string": "^0.26.0",
|
|
124
142
|
"markdown-it-anchor": "^8.4.1",
|
|
125
143
|
"markdown-it-container": "^3.0.0",
|
|
126
144
|
"markdown-it-emoji": "^2.0.0",
|
|
127
145
|
"mocha": "^10.0.0",
|
|
146
|
+
"npm-run-all": "^4.1.5",
|
|
128
147
|
"nyc": "^15.1.0",
|
|
129
148
|
"pako": "^2.0.3",
|
|
130
149
|
"postcss-nested": "^5.0.6",
|
|
131
150
|
"prettier": "^2.2.1",
|
|
132
|
-
"prettier-plugin-pkg": "^0.
|
|
151
|
+
"prettier-plugin-pkg": "^0.17.0",
|
|
133
152
|
"prettier-plugin-svelte": "^2.6.0",
|
|
134
153
|
"prism-svelte": "^0.5.0",
|
|
135
154
|
"prismjs": "^1.25.0",
|
|
136
155
|
"sass": "^1.51.0",
|
|
137
156
|
"semver": "^7.3.5",
|
|
157
|
+
"simple-git-hooks": "^2.8.0",
|
|
138
158
|
"stylelint": "^14.0.0",
|
|
139
|
-
"stylelint-config-standard": "^
|
|
140
|
-
"stylus": "^0.
|
|
159
|
+
"stylelint-config-standard": "^28.0.0",
|
|
160
|
+
"stylus": "^0.59.0",
|
|
141
161
|
"svelte": "^3.46.1",
|
|
142
162
|
"svelte-adapter-ghpages": "0.0.2",
|
|
163
|
+
"type-coverage": "^2.22.0",
|
|
143
164
|
"typescript": "^4.5.2",
|
|
144
|
-
"vite": "^3.
|
|
165
|
+
"vite": "^3.1.0-0",
|
|
145
166
|
"vite-plugin-svelte-md": "^0.1.5",
|
|
146
|
-
"yaml": "^2.1.1"
|
|
167
|
+
"yaml": "^2.1.1",
|
|
168
|
+
"yarn-deduplicate": "^6.0.0"
|
|
147
169
|
},
|
|
148
170
|
"publishConfig": {
|
|
149
171
|
"access": "public"
|
|
172
|
+
},
|
|
173
|
+
"typeCoverage": {
|
|
174
|
+
"atLeast": 98.64,
|
|
175
|
+
"cache": true,
|
|
176
|
+
"detail": true,
|
|
177
|
+
"ignoreAsAssertion": true,
|
|
178
|
+
"ignoreNested": true,
|
|
179
|
+
"ignoreNonNullAssertion": true,
|
|
180
|
+
"showRelativePath": true,
|
|
181
|
+
"strict": true,
|
|
182
|
+
"update": true
|
|
150
183
|
}
|
|
151
184
|
}
|