eslint-plugin-svelte 2.3.1 → 2.5.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 +9 -2
- 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/html-self-closing.d.ts +2 -0
- package/lib/rules/html-self-closing.js +120 -0
- package/lib/rules/no-extra-reactive-curlies.d.ts +2 -0
- package/lib/rules/no-extra-reactive-curlies.js +47 -0
- package/lib/rules/no-reactive-functions.d.ts +2 -0
- package/lib/rules/no-reactive-functions.js +48 -0
- package/lib/rules/no-reactive-literals.d.ts +2 -0
- package/lib/rules/no-reactive-literals.js +50 -0
- package/lib/rules/require-stores-init.d.ts +2 -0
- package/lib/rules/require-stores-init.js +61 -0
- package/lib/rules/sort-attributes.d.ts +2 -0
- package/lib/rules/sort-attributes.js +260 -0
- package/lib/types.d.ts +2 -0
- package/lib/utils/ast-utils.d.ts +4 -0
- package/lib/utils/ast-utils.js +66 -1
- package/lib/utils/regexp.d.ts +3 -1
- package/lib/utils/regexp.js +1 -8
- package/lib/utils/rules.js +12 -0
- package/lib/utils/void-elements.d.ts +2 -0
- package/lib/utils/void-elements.js +21 -0
- package/package.json +7 -5
package/README.md
CHANGED
|
@@ -244,8 +244,9 @@ Example **.vscode/settings.json**:
|
|
|
244
244
|
|
|
245
245
|
<!--RULES_SECTION_START-->
|
|
246
246
|
|
|
247
|
-
|
|
248
|
-
|
|
247
|
+
: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.
|
|
248
|
+
:bulb: Indicates that some problems reported by the rule are manually fixable by editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions).
|
|
249
|
+
:star: Indicates that the rule is included in the `plugin:svelte/recommended` config.
|
|
249
250
|
|
|
250
251
|
<!--RULES_TABLE_START-->
|
|
251
252
|
|
|
@@ -281,9 +282,12 @@ These rules relate to better ways of doing things to help you avoid problems:
|
|
|
281
282
|
|:--------|:------------|:---|
|
|
282
283
|
| [svelte/button-has-type](https://ota-meshi.github.io/eslint-plugin-svelte/rules/button-has-type/) | disallow usage of button without an explicit type attribute | |
|
|
283
284
|
| [svelte/no-at-debug-tags](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-at-debug-tags/) | disallow the use of `{@debug}` | :star: |
|
|
285
|
+
| [svelte/no-reactive-functions](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-reactive-functions/) | it's not necessary to define functions in reactive statements | :bulb: |
|
|
286
|
+
| [svelte/no-reactive-literals](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-reactive-literals/) | don't assign literal values in reactive statements | :bulb: |
|
|
284
287
|
| [svelte/no-unused-svelte-ignore](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-unused-svelte-ignore/) | disallow unused svelte-ignore comments | :star: |
|
|
285
288
|
| [svelte/no-useless-mustaches](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-useless-mustaches/) | disallow unnecessary mustache interpolations | :wrench: |
|
|
286
289
|
| [svelte/require-optimized-style-attribute](https://ota-meshi.github.io/eslint-plugin-svelte/rules/require-optimized-style-attribute/) | require style attributes that can be optimized | |
|
|
290
|
+
| [svelte/require-stores-init](https://ota-meshi.github.io/eslint-plugin-svelte/rules/require-stores-init/) | require initial value in store | |
|
|
287
291
|
|
|
288
292
|
## Stylistic Issues
|
|
289
293
|
|
|
@@ -294,14 +298,17 @@ These rules relate to style guidelines, and are therefore quite subjective:
|
|
|
294
298
|
| [svelte/first-attribute-linebreak](https://ota-meshi.github.io/eslint-plugin-svelte/rules/first-attribute-linebreak/) | enforce the location of first attribute | :wrench: |
|
|
295
299
|
| [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: |
|
|
296
300
|
| [svelte/html-quotes](https://ota-meshi.github.io/eslint-plugin-svelte/rules/html-quotes/) | enforce quotes style of HTML attributes | :wrench: |
|
|
301
|
+
| [svelte/html-self-closing](https://ota-meshi.github.io/eslint-plugin-svelte/rules/html-self-closing/) | enforce self-closing style | :wrench: |
|
|
297
302
|
| [svelte/indent](https://ota-meshi.github.io/eslint-plugin-svelte/rules/indent/) | enforce consistent indentation | :wrench: |
|
|
298
303
|
| [svelte/max-attributes-per-line](https://ota-meshi.github.io/eslint-plugin-svelte/rules/max-attributes-per-line/) | enforce the maximum number of attributes per line | :wrench: |
|
|
299
304
|
| [svelte/mustache-spacing](https://ota-meshi.github.io/eslint-plugin-svelte/rules/mustache-spacing/) | enforce unified spacing in mustache | :wrench: |
|
|
305
|
+
| [svelte/no-extra-reactive-curlies](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-extra-reactive-curlies/) | disallow wrapping single reactive statements in curly braces | :bulb: |
|
|
300
306
|
| [svelte/no-spaces-around-equal-signs-in-attribute](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-spaces-around-equal-signs-in-attribute/) | disallow spaces around equal signs in attribute | :wrench: |
|
|
301
307
|
| [svelte/prefer-class-directive](https://ota-meshi.github.io/eslint-plugin-svelte/rules/prefer-class-directive/) | require class directives instead of ternary expressions | :wrench: |
|
|
302
308
|
| [svelte/prefer-style-directive](https://ota-meshi.github.io/eslint-plugin-svelte/rules/prefer-style-directive/) | require style directives instead of style attribute | :wrench: |
|
|
303
309
|
| [svelte/shorthand-attribute](https://ota-meshi.github.io/eslint-plugin-svelte/rules/shorthand-attribute/) | enforce use of shorthand syntax in attribute | :wrench: |
|
|
304
310
|
| [svelte/shorthand-directive](https://ota-meshi.github.io/eslint-plugin-svelte/rules/shorthand-directive/) | enforce use of shorthand syntax in directives | :wrench: |
|
|
311
|
+
| [svelte/sort-attributes](https://ota-meshi.github.io/eslint-plugin-svelte/rules/sort-attributes/) | enforce order of attributes | :wrench: |
|
|
305
312
|
| [svelte/spaced-html-comment](https://ota-meshi.github.io/eslint-plugin-svelte/rules/spaced-html-comment/) | enforce consistent spacing after the `<!--` and before the `-->` in a HTML comment | :wrench: |
|
|
306
313
|
|
|
307
314
|
## Extension Rules
|
|
@@ -4,6 +4,7 @@ declare const _default: {
|
|
|
4
4
|
"svelte/first-attribute-linebreak": string;
|
|
5
5
|
"svelte/html-closing-bracket-spacing": string;
|
|
6
6
|
"svelte/html-quotes": string;
|
|
7
|
+
"svelte/html-self-closing": string;
|
|
7
8
|
"svelte/indent": string;
|
|
8
9
|
"svelte/max-attributes-per-line": string;
|
|
9
10
|
"svelte/mustache-spacing": string;
|
package/lib/configs/prettier.js
CHANGED
|
@@ -11,6 +11,7 @@ module.exports = {
|
|
|
11
11
|
"svelte/first-attribute-linebreak": "off",
|
|
12
12
|
"svelte/html-closing-bracket-spacing": "off",
|
|
13
13
|
"svelte/html-quotes": "off",
|
|
14
|
+
"svelte/html-self-closing": "off",
|
|
14
15
|
"svelte/indent": "off",
|
|
15
16
|
"svelte/max-attributes-per-line": "off",
|
|
16
17
|
"svelte/mustache-spacing": "off",
|
package/lib/index.d.ts
CHANGED
|
@@ -39,6 +39,7 @@ declare const _default: {
|
|
|
39
39
|
"svelte/first-attribute-linebreak": string;
|
|
40
40
|
"svelte/html-closing-bracket-spacing": string;
|
|
41
41
|
"svelte/html-quotes": string;
|
|
42
|
+
"svelte/html-self-closing": string;
|
|
42
43
|
"svelte/indent": string;
|
|
43
44
|
"svelte/max-attributes-per-line": string;
|
|
44
45
|
"svelte/mustache-spacing": string;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("../utils");
|
|
4
|
+
const ast_utils_1 = require("../utils/ast-utils");
|
|
5
|
+
const TYPE_MESSAGES = {
|
|
6
|
+
normal: "HTML elements",
|
|
7
|
+
void: "HTML void elements",
|
|
8
|
+
component: "Svelte custom components",
|
|
9
|
+
svelte: "Svelte special elements",
|
|
10
|
+
};
|
|
11
|
+
exports.default = (0, utils_1.createRule)("html-self-closing", {
|
|
12
|
+
meta: {
|
|
13
|
+
docs: {
|
|
14
|
+
description: "enforce self-closing style",
|
|
15
|
+
category: "Stylistic Issues",
|
|
16
|
+
recommended: false,
|
|
17
|
+
conflictWithPrettier: true,
|
|
18
|
+
},
|
|
19
|
+
type: "layout",
|
|
20
|
+
fixable: "code",
|
|
21
|
+
messages: {
|
|
22
|
+
requireClosing: "Require self-closing on {{type}}.",
|
|
23
|
+
disallowClosing: "Disallow self-closing on {{type}}.",
|
|
24
|
+
},
|
|
25
|
+
schema: [
|
|
26
|
+
{
|
|
27
|
+
type: "object",
|
|
28
|
+
properties: {
|
|
29
|
+
void: {
|
|
30
|
+
enum: ["never", "always", "ignore"],
|
|
31
|
+
},
|
|
32
|
+
normal: {
|
|
33
|
+
enum: ["never", "always", "ignore"],
|
|
34
|
+
},
|
|
35
|
+
component: {
|
|
36
|
+
enum: ["never", "always", "ignore"],
|
|
37
|
+
},
|
|
38
|
+
svelte: {
|
|
39
|
+
enum: ["never", "always", "ignore"],
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
additionalProperties: false,
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
create(ctx) {
|
|
47
|
+
const options = {
|
|
48
|
+
void: "always",
|
|
49
|
+
normal: "always",
|
|
50
|
+
component: "always",
|
|
51
|
+
svelte: "always",
|
|
52
|
+
...ctx.options?.[0],
|
|
53
|
+
};
|
|
54
|
+
function getElementType(node) {
|
|
55
|
+
if (node.kind === "component")
|
|
56
|
+
return "component";
|
|
57
|
+
if (node.kind === "special")
|
|
58
|
+
return "svelte";
|
|
59
|
+
if ((0, ast_utils_1.isVoidHtmlElement)(node))
|
|
60
|
+
return "void";
|
|
61
|
+
return "normal";
|
|
62
|
+
}
|
|
63
|
+
function isElementEmpty(node) {
|
|
64
|
+
if (node.children.length <= 0)
|
|
65
|
+
return true;
|
|
66
|
+
for (const child of node.children) {
|
|
67
|
+
if (child.type !== "SvelteText")
|
|
68
|
+
return false;
|
|
69
|
+
if (!/^\s*$/.test(child.value))
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
function report(node, close) {
|
|
75
|
+
const elementType = getElementType(node);
|
|
76
|
+
ctx.report({
|
|
77
|
+
node,
|
|
78
|
+
messageId: close ? "requireClosing" : "disallowClosing",
|
|
79
|
+
data: {
|
|
80
|
+
type: TYPE_MESSAGES[elementType],
|
|
81
|
+
},
|
|
82
|
+
*fix(fixer) {
|
|
83
|
+
if (close) {
|
|
84
|
+
for (const child of node.children) {
|
|
85
|
+
yield fixer.removeRange(child.range);
|
|
86
|
+
}
|
|
87
|
+
yield fixer.insertTextBeforeRange([node.startTag.range[1] - 1, node.startTag.range[1]], "/");
|
|
88
|
+
if (node.endTag)
|
|
89
|
+
yield fixer.removeRange(node.endTag.range);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
yield fixer.removeRange([
|
|
93
|
+
node.startTag.range[1] - 2,
|
|
94
|
+
node.startTag.range[1] - 1,
|
|
95
|
+
]);
|
|
96
|
+
if (!(0, ast_utils_1.isVoidHtmlElement)(node))
|
|
97
|
+
yield fixer.insertTextAfter(node, `</${(0, ast_utils_1.getNodeName)(node)}>`);
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
SvelteElement(node) {
|
|
104
|
+
if (!isElementEmpty(node))
|
|
105
|
+
return;
|
|
106
|
+
const elementType = getElementType(node);
|
|
107
|
+
const elementTypeOptions = options[elementType];
|
|
108
|
+
if (elementTypeOptions === "ignore")
|
|
109
|
+
return;
|
|
110
|
+
const shouldBeClosed = elementTypeOptions === "always";
|
|
111
|
+
if (shouldBeClosed && !node.startTag.selfClosing) {
|
|
112
|
+
report(node, true);
|
|
113
|
+
}
|
|
114
|
+
else if (!shouldBeClosed && node.startTag.selfClosing) {
|
|
115
|
+
report(node, false);
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
},
|
|
120
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("../utils");
|
|
4
|
+
exports.default = (0, utils_1.createRule)("no-extra-reactive-curlies", {
|
|
5
|
+
meta: {
|
|
6
|
+
docs: {
|
|
7
|
+
description: "disallow wrapping single reactive statements in curly braces",
|
|
8
|
+
category: "Stylistic Issues",
|
|
9
|
+
recommended: false,
|
|
10
|
+
conflictWithPrettier: false,
|
|
11
|
+
},
|
|
12
|
+
hasSuggestions: true,
|
|
13
|
+
schema: [],
|
|
14
|
+
messages: {
|
|
15
|
+
extraCurlies: `Do not wrap reactive statements in curly braces unless necessary.`,
|
|
16
|
+
removeExtraCurlies: `Remove the unnecessary curly braces.`,
|
|
17
|
+
},
|
|
18
|
+
type: "suggestion",
|
|
19
|
+
},
|
|
20
|
+
create(context) {
|
|
21
|
+
return {
|
|
22
|
+
[`SvelteReactiveStatement > BlockStatement[body.length=1]`]: (node) => {
|
|
23
|
+
const source = context.getSourceCode();
|
|
24
|
+
return context.report({
|
|
25
|
+
node,
|
|
26
|
+
loc: node.loc,
|
|
27
|
+
messageId: "extraCurlies",
|
|
28
|
+
suggest: [
|
|
29
|
+
{
|
|
30
|
+
messageId: "removeExtraCurlies",
|
|
31
|
+
fix(fixer) {
|
|
32
|
+
const tokens = source.getTokens(node, { includeComments: true });
|
|
33
|
+
return [
|
|
34
|
+
fixer.removeRange([tokens[0].range[0], tokens[1].range[0]]),
|
|
35
|
+
fixer.removeRange([
|
|
36
|
+
tokens[tokens.length - 2].range[1],
|
|
37
|
+
tokens[tokens.length - 1].range[1],
|
|
38
|
+
]),
|
|
39
|
+
];
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("../utils");
|
|
4
|
+
exports.default = (0, utils_1.createRule)("no-reactive-functions", {
|
|
5
|
+
meta: {
|
|
6
|
+
docs: {
|
|
7
|
+
description: "it's not necessary to define functions in reactive statements",
|
|
8
|
+
category: "Best Practices",
|
|
9
|
+
recommended: false,
|
|
10
|
+
},
|
|
11
|
+
hasSuggestions: true,
|
|
12
|
+
schema: [],
|
|
13
|
+
messages: {
|
|
14
|
+
noReactiveFns: `Do not create functions inside reactive statements unless absolutely necessary.`,
|
|
15
|
+
fixReactiveFns: `Move the function out of the reactive statement`,
|
|
16
|
+
},
|
|
17
|
+
type: "suggestion",
|
|
18
|
+
},
|
|
19
|
+
create(context) {
|
|
20
|
+
return {
|
|
21
|
+
[`SvelteReactiveStatement > ExpressionStatement > AssignmentExpression > :function`](node) {
|
|
22
|
+
const parent = node.parent?.parent?.parent;
|
|
23
|
+
if (!parent) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
const source = context.getSourceCode();
|
|
27
|
+
return context.report({
|
|
28
|
+
node: parent,
|
|
29
|
+
loc: parent.loc,
|
|
30
|
+
messageId: "noReactiveFns",
|
|
31
|
+
suggest: [
|
|
32
|
+
{
|
|
33
|
+
messageId: "fixReactiveFns",
|
|
34
|
+
fix(fixer) {
|
|
35
|
+
const tokens = source.getFirstTokens(parent, {
|
|
36
|
+
includeComments: false,
|
|
37
|
+
count: 3,
|
|
38
|
+
});
|
|
39
|
+
const noExtraSpace = source.isSpaceBetweenTokens(tokens[1], tokens[2]);
|
|
40
|
+
return fixer.replaceTextRange([tokens[0].range[0], tokens[1].range[1]], noExtraSpace ? "const" : "const ");
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
},
|
|
48
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("../utils");
|
|
4
|
+
exports.default = (0, utils_1.createRule)("no-reactive-literals", {
|
|
5
|
+
meta: {
|
|
6
|
+
docs: {
|
|
7
|
+
description: "don't assign literal values in reactive statements",
|
|
8
|
+
category: "Best Practices",
|
|
9
|
+
recommended: false,
|
|
10
|
+
},
|
|
11
|
+
hasSuggestions: true,
|
|
12
|
+
schema: [],
|
|
13
|
+
messages: {
|
|
14
|
+
noReactiveLiterals: `Do not assign literal values inside reactive statements unless absolutely necessary.`,
|
|
15
|
+
fixReactiveLiteral: `Move the literal out of the reactive statement into an assignment`,
|
|
16
|
+
},
|
|
17
|
+
type: "suggestion",
|
|
18
|
+
},
|
|
19
|
+
create(context) {
|
|
20
|
+
return {
|
|
21
|
+
[`SvelteReactiveStatement > ExpressionStatement > AssignmentExpression:matches(${[
|
|
22
|
+
`[right.type="Literal"]`,
|
|
23
|
+
`[right.type="ArrayExpression"][right.elements.length=0]`,
|
|
24
|
+
`[right.type="ObjectExpression"][right.properties.length=0]`,
|
|
25
|
+
].join(",")})`](node) {
|
|
26
|
+
const parent = node.parent?.parent;
|
|
27
|
+
if (!parent) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
const source = context.getSourceCode();
|
|
31
|
+
return context.report({
|
|
32
|
+
node: parent,
|
|
33
|
+
loc: parent.loc,
|
|
34
|
+
messageId: "noReactiveLiterals",
|
|
35
|
+
suggest: [
|
|
36
|
+
{
|
|
37
|
+
messageId: "fixReactiveLiteral",
|
|
38
|
+
fix(fixer) {
|
|
39
|
+
return [
|
|
40
|
+
fixer.insertTextBefore(parent, `let ${source.getText(node)}`),
|
|
41
|
+
fixer.remove(parent),
|
|
42
|
+
];
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
});
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("../utils");
|
|
4
|
+
const eslint_utils_1 = require("eslint-utils");
|
|
5
|
+
exports.default = (0, utils_1.createRule)("require-stores-init", {
|
|
6
|
+
meta: {
|
|
7
|
+
docs: {
|
|
8
|
+
description: "require initial value in store",
|
|
9
|
+
category: "Best Practices",
|
|
10
|
+
recommended: false,
|
|
11
|
+
},
|
|
12
|
+
schema: [],
|
|
13
|
+
messages: {
|
|
14
|
+
storeDefaultValue: `Always set a default value for svelte stores.`,
|
|
15
|
+
},
|
|
16
|
+
type: "suggestion",
|
|
17
|
+
},
|
|
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
|
+
return {
|
|
42
|
+
Program() {
|
|
43
|
+
for (const { node, name } of extractStoreReferences()) {
|
|
44
|
+
const minArgs = name === "writable" || name === "readable"
|
|
45
|
+
? 1
|
|
46
|
+
: name === "derived"
|
|
47
|
+
? 3
|
|
48
|
+
: 0;
|
|
49
|
+
if (node.arguments.length >= minArgs ||
|
|
50
|
+
node.arguments.some((arg) => arg.type === "SpreadElement")) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
context.report({
|
|
54
|
+
node,
|
|
55
|
+
messageId: "storeDefaultValue",
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
});
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("../utils");
|
|
4
|
+
const ast_utils_1 = require("../utils/ast-utils");
|
|
5
|
+
const regexp_1 = require("../utils/regexp");
|
|
6
|
+
const DEFAULT_ORDER = [
|
|
7
|
+
"this",
|
|
8
|
+
"bind:this",
|
|
9
|
+
"id",
|
|
10
|
+
"name",
|
|
11
|
+
"slot",
|
|
12
|
+
{ match: "/^--/u", sort: "alphabetical" },
|
|
13
|
+
["style", "/^style:/u"],
|
|
14
|
+
"class",
|
|
15
|
+
{ match: "/^class:/u", sort: "alphabetical" },
|
|
16
|
+
{
|
|
17
|
+
match: ["!/:/u", "!/^(?:this|id|name|style|class)$/u", "!/^--/u"],
|
|
18
|
+
sort: "alphabetical",
|
|
19
|
+
},
|
|
20
|
+
["/^bind:/u", "!bind:this", "/^on:/u"],
|
|
21
|
+
{ match: "/^use:/u", sort: "alphabetical" },
|
|
22
|
+
{ match: "/^transition:/u", sort: "alphabetical" },
|
|
23
|
+
{ match: "/^in:/u", sort: "alphabetical" },
|
|
24
|
+
{ match: "/^out:/u", sort: "alphabetical" },
|
|
25
|
+
{ match: "/^animate:/u", sort: "alphabetical" },
|
|
26
|
+
{ match: "/^let:/u", sort: "alphabetical" },
|
|
27
|
+
];
|
|
28
|
+
function parseOption(option) {
|
|
29
|
+
const order = option?.order ?? DEFAULT_ORDER;
|
|
30
|
+
const compiled = order.map(compileOption);
|
|
31
|
+
return {
|
|
32
|
+
ignore: (key) => {
|
|
33
|
+
return !compiled.some((c) => c.match(key));
|
|
34
|
+
},
|
|
35
|
+
compare: (a, b) => {
|
|
36
|
+
for (const c of compiled) {
|
|
37
|
+
const matchA = c.match(a);
|
|
38
|
+
const matchB = c.match(b);
|
|
39
|
+
if (matchA && matchB) {
|
|
40
|
+
if (c.sort === "alphabetical") {
|
|
41
|
+
return a === b ? 0 : a < b ? -1 : 1;
|
|
42
|
+
}
|
|
43
|
+
return 0;
|
|
44
|
+
}
|
|
45
|
+
if (matchA) {
|
|
46
|
+
return -1;
|
|
47
|
+
}
|
|
48
|
+
if (matchB) {
|
|
49
|
+
return 1;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
throw new Error("Illegal state");
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function compileOption(option) {
|
|
57
|
+
const cache = {};
|
|
58
|
+
const compiled = compileOptionWithoutCache(option);
|
|
59
|
+
return {
|
|
60
|
+
match: (str) => {
|
|
61
|
+
if (cache[str] != null)
|
|
62
|
+
return cache[str];
|
|
63
|
+
return (cache[str] = compiled.match(str));
|
|
64
|
+
},
|
|
65
|
+
sort: compiled.sort,
|
|
66
|
+
};
|
|
67
|
+
function compileOptionWithoutCache(option) {
|
|
68
|
+
if (typeof option === "string") {
|
|
69
|
+
const match = compileMatcher([option]);
|
|
70
|
+
return { match, sort: "ignore" };
|
|
71
|
+
}
|
|
72
|
+
if (Array.isArray(option)) {
|
|
73
|
+
const match = compileMatcher(option);
|
|
74
|
+
return { match, sort: "ignore" };
|
|
75
|
+
}
|
|
76
|
+
const { match } = compileOptionWithoutCache(option.match);
|
|
77
|
+
return { match, sort: option.sort || "ignore" };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function compileMatcher(pattern) {
|
|
81
|
+
const rules = [];
|
|
82
|
+
for (const p of pattern) {
|
|
83
|
+
let negative, patternStr;
|
|
84
|
+
if (p.startsWith("!")) {
|
|
85
|
+
negative = true;
|
|
86
|
+
patternStr = p.substring(1);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
negative = false;
|
|
90
|
+
patternStr = p;
|
|
91
|
+
}
|
|
92
|
+
const regex = (0, regexp_1.toRegExp)(patternStr);
|
|
93
|
+
rules.push({ negative, match: (str) => regex.test(str) });
|
|
94
|
+
}
|
|
95
|
+
return (str) => {
|
|
96
|
+
let result = Boolean(rules[0]?.negative);
|
|
97
|
+
for (const { negative, match } of rules) {
|
|
98
|
+
if (result === !negative) {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (match(str)) {
|
|
102
|
+
result = !negative;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return result;
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
exports.default = (0, utils_1.createRule)("sort-attributes", {
|
|
109
|
+
meta: {
|
|
110
|
+
docs: {
|
|
111
|
+
description: "enforce order of attributes",
|
|
112
|
+
category: "Stylistic Issues",
|
|
113
|
+
recommended: false,
|
|
114
|
+
conflictWithPrettier: false,
|
|
115
|
+
},
|
|
116
|
+
schema: [
|
|
117
|
+
{
|
|
118
|
+
type: "object",
|
|
119
|
+
properties: {
|
|
120
|
+
order: {
|
|
121
|
+
type: "array",
|
|
122
|
+
items: {
|
|
123
|
+
anyOf: [
|
|
124
|
+
{ type: "string" },
|
|
125
|
+
{
|
|
126
|
+
type: "array",
|
|
127
|
+
items: {
|
|
128
|
+
type: "string",
|
|
129
|
+
},
|
|
130
|
+
uniqueItems: true,
|
|
131
|
+
minItems: 1,
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
type: "object",
|
|
135
|
+
properties: {
|
|
136
|
+
match: {
|
|
137
|
+
anyOf: [
|
|
138
|
+
{ type: "string" },
|
|
139
|
+
{
|
|
140
|
+
type: "array",
|
|
141
|
+
items: {
|
|
142
|
+
type: "string",
|
|
143
|
+
},
|
|
144
|
+
uniqueItems: true,
|
|
145
|
+
minItems: 1,
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
},
|
|
149
|
+
sort: {
|
|
150
|
+
enum: ["alphabetical", "ignore"],
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
required: ["match", "sort"],
|
|
154
|
+
additionalProperties: false,
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
},
|
|
158
|
+
uniqueItems: true,
|
|
159
|
+
additionalItems: false,
|
|
160
|
+
},
|
|
161
|
+
alphabetical: { type: "boolean" },
|
|
162
|
+
},
|
|
163
|
+
additionalProperties: false,
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
messages: {
|
|
167
|
+
shouldBefore: "Attribute '{{currentKey}}' should go before '{{prevKey}}'.",
|
|
168
|
+
},
|
|
169
|
+
type: "layout",
|
|
170
|
+
fixable: "code",
|
|
171
|
+
},
|
|
172
|
+
create(context) {
|
|
173
|
+
const option = parseOption(context.options[0]);
|
|
174
|
+
const cacheKeyText = new Map();
|
|
175
|
+
function getKeyText(node) {
|
|
176
|
+
const k = cacheKeyText.get(node);
|
|
177
|
+
if (k != null)
|
|
178
|
+
return k;
|
|
179
|
+
const result = (0, ast_utils_1.getAttributeKeyText)(node);
|
|
180
|
+
cacheKeyText.set(node, result);
|
|
181
|
+
return result;
|
|
182
|
+
}
|
|
183
|
+
function report(node, previousNode) {
|
|
184
|
+
const currentKey = getKeyText(node);
|
|
185
|
+
const prevKey = getKeyText(previousNode);
|
|
186
|
+
context.report({
|
|
187
|
+
node,
|
|
188
|
+
messageId: "shouldBefore",
|
|
189
|
+
data: {
|
|
190
|
+
currentKey,
|
|
191
|
+
prevKey,
|
|
192
|
+
},
|
|
193
|
+
fix(fixer) {
|
|
194
|
+
const attributes = node.parent.attributes;
|
|
195
|
+
const previousNodes = attributes.slice(attributes.indexOf(previousNode), attributes.indexOf(node));
|
|
196
|
+
const moveNodes = [node, ...previousNodes];
|
|
197
|
+
const sourceCode = context.getSourceCode();
|
|
198
|
+
return moveNodes.map((moveNode, index) => {
|
|
199
|
+
const text = sourceCode.getText(moveNode);
|
|
200
|
+
return fixer.replaceText(previousNodes[index] || node, text);
|
|
201
|
+
});
|
|
202
|
+
},
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
function hasSpreadAttribute(node, previousNode) {
|
|
206
|
+
const attributes = node.parent.attributes;
|
|
207
|
+
const previousNodes = attributes.slice(attributes.indexOf(previousNode), attributes.indexOf(node));
|
|
208
|
+
return previousNodes.some((a) => a.type === "SvelteSpreadAttribute");
|
|
209
|
+
}
|
|
210
|
+
function verifyForSpreadAttributeExist(node) {
|
|
211
|
+
const previousNodes = [];
|
|
212
|
+
const attributes = node.parent.attributes;
|
|
213
|
+
for (const previousNode of attributes
|
|
214
|
+
.slice(0, attributes.indexOf(node))
|
|
215
|
+
.reverse()) {
|
|
216
|
+
if (previousNode.type === "SvelteSpreadAttribute") {
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
previousNodes.unshift(previousNode);
|
|
220
|
+
}
|
|
221
|
+
const key = getKeyText(node);
|
|
222
|
+
const invalidPreviousNode = previousNodes.find((previousNode) => {
|
|
223
|
+
const prevKey = getKeyText(previousNode);
|
|
224
|
+
if (option.ignore(prevKey)) {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
return option.compare(prevKey, key) > 0;
|
|
228
|
+
});
|
|
229
|
+
if (invalidPreviousNode) {
|
|
230
|
+
report(node, invalidPreviousNode);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return {
|
|
234
|
+
SvelteStartTag(node) {
|
|
235
|
+
const validPreviousNodes = [];
|
|
236
|
+
for (const attr of node.attributes) {
|
|
237
|
+
if (attr.type === "SvelteSpreadAttribute") {
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
const key = getKeyText(attr);
|
|
241
|
+
if (option.ignore(key)) {
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
const invalidPreviousNode = validPreviousNodes.find((previousNode) => option.compare(getKeyText(previousNode), key) > 0);
|
|
245
|
+
if (invalidPreviousNode) {
|
|
246
|
+
if (attr.type !== "SvelteAttribute" ||
|
|
247
|
+
!hasSpreadAttribute(attr, invalidPreviousNode)) {
|
|
248
|
+
report(attr, invalidPreviousNode);
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
verifyForSpreadAttributeExist(attr);
|
|
252
|
+
}
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
validPreviousNodes.push(attr);
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
};
|
|
259
|
+
},
|
|
260
|
+
});
|
package/lib/types.d.ts
CHANGED
|
@@ -33,6 +33,7 @@ export interface RuleMetaData {
|
|
|
33
33
|
[messageId: string]: string;
|
|
34
34
|
};
|
|
35
35
|
fixable?: "code" | "whitespace";
|
|
36
|
+
hasSuggestions?: boolean;
|
|
36
37
|
schema: JSONSchema4 | JSONSchema4[];
|
|
37
38
|
deprecated?: boolean;
|
|
38
39
|
replacedBy?: string[];
|
|
@@ -59,6 +60,7 @@ export interface PartialRuleMetaData {
|
|
|
59
60
|
[messageId: string]: string;
|
|
60
61
|
};
|
|
61
62
|
fixable?: "code" | "whitespace";
|
|
63
|
+
hasSuggestions?: boolean;
|
|
62
64
|
schema: JSONSchema4 | JSONSchema4[];
|
|
63
65
|
deprecated?: boolean;
|
|
64
66
|
replacedBy?: string[];
|
package/lib/utils/ast-utils.d.ts
CHANGED
|
@@ -46,3 +46,7 @@ export declare function getMustacheTokens(node: SvAST.SvelteDirective | SvAST.Sv
|
|
|
46
46
|
openToken: SvAST.Token;
|
|
47
47
|
closeToken: SvAST.Token;
|
|
48
48
|
} | null;
|
|
49
|
+
export declare function getAttributeKeyText(node: SvAST.SvelteAttribute | SvAST.SvelteShorthandAttribute | SvAST.SvelteStyleDirective | SvAST.SvelteDirective | SvAST.SvelteSpecialDirective): string;
|
|
50
|
+
export declare function getDirectiveName(node: SvAST.SvelteDirective): string;
|
|
51
|
+
export declare function getNodeName(node: SvAST.SvelteElement): string;
|
|
52
|
+
export declare function isVoidHtmlElement(node: SvAST.SvelteElement): boolean;
|
package/lib/utils/ast-utils.js
CHANGED
|
@@ -22,9 +22,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
25
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.getMustacheTokens = exports.getAttributeValueQuoteAndRange = exports.getScope = exports.findVariable = exports.getLangValue = exports.getStaticAttributeValue = exports.findBindDirective = exports.findShorthandAttribute = exports.findAttribute = exports.isHTMLElementLike = exports.needParentheses = exports.getStringIfConstant = exports.equalTokens = void 0;
|
|
29
|
+
exports.isVoidHtmlElement = exports.getNodeName = exports.getDirectiveName = exports.getAttributeKeyText = exports.getMustacheTokens = exports.getAttributeValueQuoteAndRange = exports.getScope = exports.findVariable = exports.getLangValue = exports.getStaticAttributeValue = exports.findBindDirective = exports.findShorthandAttribute = exports.findAttribute = exports.isHTMLElementLike = exports.needParentheses = exports.getStringIfConstant = exports.equalTokens = void 0;
|
|
27
30
|
const eslintUtils = __importStar(require("eslint-utils"));
|
|
31
|
+
const void_elements_1 = __importDefault(require("./void-elements"));
|
|
28
32
|
function equalTokens(left, right, sourceCode) {
|
|
29
33
|
const tokensL = sourceCode.getTokens(left);
|
|
30
34
|
const tokensR = sourceCode.getTokens(right);
|
|
@@ -260,6 +264,47 @@ function getMustacheTokens(node, sourceCode) {
|
|
|
260
264
|
};
|
|
261
265
|
}
|
|
262
266
|
exports.getMustacheTokens = getMustacheTokens;
|
|
267
|
+
function getAttributeKeyText(node) {
|
|
268
|
+
switch (node.type) {
|
|
269
|
+
case "SvelteAttribute":
|
|
270
|
+
case "SvelteShorthandAttribute":
|
|
271
|
+
return node.key.name;
|
|
272
|
+
case "SvelteStyleDirective":
|
|
273
|
+
return `style:${node.key.name.name}`;
|
|
274
|
+
case "SvelteSpecialDirective":
|
|
275
|
+
return node.kind;
|
|
276
|
+
case "SvelteDirective": {
|
|
277
|
+
const dir = getDirectiveName(node);
|
|
278
|
+
return `${dir}:${node.key.name.name}${node.key.modifiers.length ? `|${node.key.modifiers.join("|")}` : ""}`;
|
|
279
|
+
}
|
|
280
|
+
default:
|
|
281
|
+
throw new Error(`Unknown node type: ${node.type}`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
exports.getAttributeKeyText = getAttributeKeyText;
|
|
285
|
+
function getDirectiveName(node) {
|
|
286
|
+
switch (node.kind) {
|
|
287
|
+
case "Action":
|
|
288
|
+
return "use";
|
|
289
|
+
case "Animation":
|
|
290
|
+
return "animate";
|
|
291
|
+
case "Binding":
|
|
292
|
+
return "bind";
|
|
293
|
+
case "Class":
|
|
294
|
+
return "class";
|
|
295
|
+
case "EventHandler":
|
|
296
|
+
return "on";
|
|
297
|
+
case "Let":
|
|
298
|
+
return "let";
|
|
299
|
+
case "Transition":
|
|
300
|
+
return node.intro && node.outro ? "transition" : node.intro ? "in" : "out";
|
|
301
|
+
case "Ref":
|
|
302
|
+
return "ref";
|
|
303
|
+
default:
|
|
304
|
+
throw new Error("Unknown directive kind");
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
exports.getDirectiveName = getDirectiveName;
|
|
263
308
|
function getAttributeValueRangeTokens(attr, sourceCode) {
|
|
264
309
|
if (attr.type === "SvelteAttribute" || attr.type === "SvelteStyleDirective") {
|
|
265
310
|
if (!attr.value.length) {
|
|
@@ -281,3 +326,23 @@ function getAttributeValueRangeTokens(attr, sourceCode) {
|
|
|
281
326
|
lastToken: tokens.closeToken,
|
|
282
327
|
};
|
|
283
328
|
}
|
|
329
|
+
function getNodeName(node) {
|
|
330
|
+
if ("name" in node.name) {
|
|
331
|
+
return node.name.name;
|
|
332
|
+
}
|
|
333
|
+
let object = "";
|
|
334
|
+
let currentObject = node.name.object;
|
|
335
|
+
while ("object" in currentObject) {
|
|
336
|
+
object = `${currentObject.property.name}.${object}`;
|
|
337
|
+
currentObject = currentObject.object;
|
|
338
|
+
}
|
|
339
|
+
if ("name" in currentObject) {
|
|
340
|
+
object = `${currentObject.name}.${object}`;
|
|
341
|
+
}
|
|
342
|
+
return object + node.name.property.name;
|
|
343
|
+
}
|
|
344
|
+
exports.getNodeName = getNodeName;
|
|
345
|
+
function isVoidHtmlElement(node) {
|
|
346
|
+
return void_elements_1.default.includes(getNodeName(node));
|
|
347
|
+
}
|
|
348
|
+
exports.isVoidHtmlElement = isVoidHtmlElement;
|
package/lib/utils/regexp.d.ts
CHANGED
package/lib/utils/regexp.js
CHANGED
|
@@ -1,20 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.isRegExp = exports.toRegExp = void 0;
|
|
4
|
-
const RE_REGEXP_CHAR = /[$()*+.?[\\\]^{|}]/gu;
|
|
5
|
-
const RE_HAS_REGEXP_CHAR = new RegExp(RE_REGEXP_CHAR.source);
|
|
6
4
|
const RE_REGEXP_STR = /^\/(.+)\/([A-Za-z]*)$/u;
|
|
7
|
-
function escape(string) {
|
|
8
|
-
return string && RE_HAS_REGEXP_CHAR.test(string)
|
|
9
|
-
? string.replace(RE_REGEXP_CHAR, "\\$&")
|
|
10
|
-
: string;
|
|
11
|
-
}
|
|
12
5
|
function toRegExp(string) {
|
|
13
6
|
const parts = RE_REGEXP_STR.exec(string);
|
|
14
7
|
if (parts) {
|
|
15
8
|
return new RegExp(parts[1], parts[2]);
|
|
16
9
|
}
|
|
17
|
-
return
|
|
10
|
+
return { test: (s) => s === string };
|
|
18
11
|
}
|
|
19
12
|
exports.toRegExp = toRegExp;
|
|
20
13
|
function isRegExp(string) {
|
package/lib/utils/rules.js
CHANGED
|
@@ -9,6 +9,7 @@ const comment_directive_1 = __importDefault(require("../rules/comment-directive"
|
|
|
9
9
|
const first_attribute_linebreak_1 = __importDefault(require("../rules/first-attribute-linebreak"));
|
|
10
10
|
const html_closing_bracket_spacing_1 = __importDefault(require("../rules/html-closing-bracket-spacing"));
|
|
11
11
|
const html_quotes_1 = __importDefault(require("../rules/html-quotes"));
|
|
12
|
+
const html_self_closing_1 = __importDefault(require("../rules/html-self-closing"));
|
|
12
13
|
const indent_1 = __importDefault(require("../rules/indent"));
|
|
13
14
|
const max_attributes_per_line_1 = __importDefault(require("../rules/max-attributes-per-line"));
|
|
14
15
|
const mustache_spacing_1 = __importDefault(require("../rules/mustache-spacing"));
|
|
@@ -17,9 +18,12 @@ const no_at_html_tags_1 = __importDefault(require("../rules/no-at-html-tags"));
|
|
|
17
18
|
const no_dupe_else_if_blocks_1 = __importDefault(require("../rules/no-dupe-else-if-blocks"));
|
|
18
19
|
const no_dupe_style_properties_1 = __importDefault(require("../rules/no-dupe-style-properties"));
|
|
19
20
|
const no_dynamic_slot_name_1 = __importDefault(require("../rules/no-dynamic-slot-name"));
|
|
21
|
+
const no_extra_reactive_curlies_1 = __importDefault(require("../rules/no-extra-reactive-curlies"));
|
|
20
22
|
const no_inner_declarations_1 = __importDefault(require("../rules/no-inner-declarations"));
|
|
21
23
|
const no_not_function_handler_1 = __importDefault(require("../rules/no-not-function-handler"));
|
|
22
24
|
const no_object_in_text_mustaches_1 = __importDefault(require("../rules/no-object-in-text-mustaches"));
|
|
25
|
+
const no_reactive_functions_1 = __importDefault(require("../rules/no-reactive-functions"));
|
|
26
|
+
const no_reactive_literals_1 = __importDefault(require("../rules/no-reactive-literals"));
|
|
23
27
|
const no_shorthand_style_property_overrides_1 = __importDefault(require("../rules/no-shorthand-style-property-overrides"));
|
|
24
28
|
const no_spaces_around_equal_signs_in_attribute_1 = __importDefault(require("../rules/no-spaces-around-equal-signs-in-attribute"));
|
|
25
29
|
const no_target_blank_1 = __importDefault(require("../rules/no-target-blank"));
|
|
@@ -29,8 +33,10 @@ const no_useless_mustaches_1 = __importDefault(require("../rules/no-useless-must
|
|
|
29
33
|
const prefer_class_directive_1 = __importDefault(require("../rules/prefer-class-directive"));
|
|
30
34
|
const prefer_style_directive_1 = __importDefault(require("../rules/prefer-style-directive"));
|
|
31
35
|
const require_optimized_style_attribute_1 = __importDefault(require("../rules/require-optimized-style-attribute"));
|
|
36
|
+
const require_stores_init_1 = __importDefault(require("../rules/require-stores-init"));
|
|
32
37
|
const shorthand_attribute_1 = __importDefault(require("../rules/shorthand-attribute"));
|
|
33
38
|
const shorthand_directive_1 = __importDefault(require("../rules/shorthand-directive"));
|
|
39
|
+
const sort_attributes_1 = __importDefault(require("../rules/sort-attributes"));
|
|
34
40
|
const spaced_html_comment_1 = __importDefault(require("../rules/spaced-html-comment"));
|
|
35
41
|
const system_1 = __importDefault(require("../rules/system"));
|
|
36
42
|
const valid_compile_1 = __importDefault(require("../rules/valid-compile"));
|
|
@@ -40,6 +46,7 @@ exports.rules = [
|
|
|
40
46
|
first_attribute_linebreak_1.default,
|
|
41
47
|
html_closing_bracket_spacing_1.default,
|
|
42
48
|
html_quotes_1.default,
|
|
49
|
+
html_self_closing_1.default,
|
|
43
50
|
indent_1.default,
|
|
44
51
|
max_attributes_per_line_1.default,
|
|
45
52
|
mustache_spacing_1.default,
|
|
@@ -48,9 +55,12 @@ exports.rules = [
|
|
|
48
55
|
no_dupe_else_if_blocks_1.default,
|
|
49
56
|
no_dupe_style_properties_1.default,
|
|
50
57
|
no_dynamic_slot_name_1.default,
|
|
58
|
+
no_extra_reactive_curlies_1.default,
|
|
51
59
|
no_inner_declarations_1.default,
|
|
52
60
|
no_not_function_handler_1.default,
|
|
53
61
|
no_object_in_text_mustaches_1.default,
|
|
62
|
+
no_reactive_functions_1.default,
|
|
63
|
+
no_reactive_literals_1.default,
|
|
54
64
|
no_shorthand_style_property_overrides_1.default,
|
|
55
65
|
no_spaces_around_equal_signs_in_attribute_1.default,
|
|
56
66
|
no_target_blank_1.default,
|
|
@@ -60,8 +70,10 @@ exports.rules = [
|
|
|
60
70
|
prefer_class_directive_1.default,
|
|
61
71
|
prefer_style_directive_1.default,
|
|
62
72
|
require_optimized_style_attribute_1.default,
|
|
73
|
+
require_stores_init_1.default,
|
|
63
74
|
shorthand_attribute_1.default,
|
|
64
75
|
shorthand_directive_1.default,
|
|
76
|
+
sort_attributes_1.default,
|
|
65
77
|
spaced_html_comment_1.default,
|
|
66
78
|
system_1.default,
|
|
67
79
|
valid_compile_1.default,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const voidElements = [
|
|
4
|
+
"area",
|
|
5
|
+
"base",
|
|
6
|
+
"br",
|
|
7
|
+
"col",
|
|
8
|
+
"embed",
|
|
9
|
+
"hr",
|
|
10
|
+
"img",
|
|
11
|
+
"input",
|
|
12
|
+
"keygen",
|
|
13
|
+
"link",
|
|
14
|
+
"menuitem",
|
|
15
|
+
"meta",
|
|
16
|
+
"param",
|
|
17
|
+
"source",
|
|
18
|
+
"track",
|
|
19
|
+
"wbr",
|
|
20
|
+
];
|
|
21
|
+
exports.default = voidElements;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-svelte",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.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",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"postcss-load-config": "^3.1.4",
|
|
67
67
|
"postcss-safe-parser": "^6.0.0",
|
|
68
68
|
"sourcemap-codec": "^1.4.8",
|
|
69
|
-
"svelte-eslint-parser": "^0.
|
|
69
|
+
"svelte-eslint-parser": "^0.18.0"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@babel/core": "^7.16.0",
|
|
@@ -83,6 +83,7 @@
|
|
|
83
83
|
"@types/escape-html": "^1.0.2",
|
|
84
84
|
"@types/eslint": "^8.0.0",
|
|
85
85
|
"@types/eslint-scope": "^3.7.0",
|
|
86
|
+
"@types/eslint-utils": "^3.0.1",
|
|
86
87
|
"@types/eslint-visitor-keys": "^1.0.0",
|
|
87
88
|
"@types/estree": "^1.0.0",
|
|
88
89
|
"@types/less": "^3.0.3",
|
|
@@ -99,7 +100,7 @@
|
|
|
99
100
|
"@typescript-eslint/parser-v4": "npm:@typescript-eslint/parser@4",
|
|
100
101
|
"assert": "^2.0.0",
|
|
101
102
|
"env-cmd": "^10.1.0",
|
|
102
|
-
"esbuild": "^0.
|
|
103
|
+
"esbuild": "^0.15.0",
|
|
103
104
|
"esbuild-register": "^3.2.0",
|
|
104
105
|
"escape-html": "^1.0.3",
|
|
105
106
|
"eslint": "^8.0.0",
|
|
@@ -135,13 +136,14 @@
|
|
|
135
136
|
"sass": "^1.51.0",
|
|
136
137
|
"semver": "^7.3.5",
|
|
137
138
|
"stylelint": "^14.0.0",
|
|
138
|
-
"stylelint-config-standard": "^
|
|
139
|
+
"stylelint-config-standard": "^27.0.0",
|
|
139
140
|
"stylus": "^0.58.0",
|
|
140
141
|
"svelte": "^3.46.1",
|
|
141
142
|
"svelte-adapter-ghpages": "0.0.2",
|
|
142
143
|
"typescript": "^4.5.2",
|
|
143
144
|
"vite": "^3.0.0-0",
|
|
144
|
-
"vite-plugin-svelte-md": "^0.1.5"
|
|
145
|
+
"vite-plugin-svelte-md": "^0.1.5",
|
|
146
|
+
"yaml": "^2.1.1"
|
|
145
147
|
},
|
|
146
148
|
"publishConfig": {
|
|
147
149
|
"access": "public"
|