eslint-plugin-svelte 2.30.0 → 2.31.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 +2 -0
- package/lib/meta.d.ts +1 -1
- package/lib/meta.js +1 -1
- package/lib/rules/no-restricted-html-elements.d.ts +2 -0
- package/lib/rules/no-restricted-html-elements.js +65 -0
- package/lib/rules/no-unused-class-name.d.ts +2 -0
- package/lib/rules/no-unused-class-name.js +82 -0
- package/lib/utils/rules.js +4 -0
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -343,6 +343,7 @@ These rules relate to better ways of doing things to help you avoid problems:
|
|
|
343
343
|
| [svelte/no-immutable-reactive-statements](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-immutable-reactive-statements/) | disallow reactive statements that don't reference reactive values. | |
|
|
344
344
|
| [svelte/no-reactive-functions](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-reactive-functions/) | it's not necessary to define functions in reactive statements | :bulb: |
|
|
345
345
|
| [svelte/no-reactive-literals](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-reactive-literals/) | don't assign literal values in reactive statements | :bulb: |
|
|
346
|
+
| [svelte/no-unused-class-name](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-unused-class-name/) | disallow the use of a class in the template without a corresponding style | |
|
|
346
347
|
| [svelte/no-unused-svelte-ignore](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-unused-svelte-ignore/) | disallow unused svelte-ignore comments | :star: |
|
|
347
348
|
| [svelte/no-useless-mustaches](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-useless-mustaches/) | disallow unnecessary mustache interpolations | :wrench: |
|
|
348
349
|
| [svelte/prefer-destructured-store-props](https://sveltejs.github.io/eslint-plugin-svelte/rules/prefer-destructured-store-props/) | destructure values from object stores for better change tracking & fewer redraws | :bulb: |
|
|
@@ -367,6 +368,7 @@ These rules relate to style guidelines, and are therefore quite subjective:
|
|
|
367
368
|
| [svelte/max-attributes-per-line](https://sveltejs.github.io/eslint-plugin-svelte/rules/max-attributes-per-line/) | enforce the maximum number of attributes per line | :wrench: |
|
|
368
369
|
| [svelte/mustache-spacing](https://sveltejs.github.io/eslint-plugin-svelte/rules/mustache-spacing/) | enforce unified spacing in mustache | :wrench: |
|
|
369
370
|
| [svelte/no-extra-reactive-curlies](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-extra-reactive-curlies/) | disallow wrapping single reactive statements in curly braces | :bulb: |
|
|
371
|
+
| [svelte/no-restricted-html-elements](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-restricted-html-elements/) | disallow specific HTML elements | |
|
|
370
372
|
| [svelte/no-spaces-around-equal-signs-in-attribute](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-spaces-around-equal-signs-in-attribute/) | disallow spaces around equal signs in attribute | :wrench: |
|
|
371
373
|
| [svelte/prefer-class-directive](https://sveltejs.github.io/eslint-plugin-svelte/rules/prefer-class-directive/) | require class directives instead of ternary expressions | :wrench: |
|
|
372
374
|
| [svelte/prefer-style-directive](https://sveltejs.github.io/eslint-plugin-svelte/rules/prefer-style-directive/) | require style directives instead of style attribute | :wrench: |
|
package/lib/meta.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare const name: "eslint-plugin-svelte";
|
|
2
|
-
export declare const version: "2.
|
|
2
|
+
export declare const version: "2.31.0";
|
package/lib/meta.js
CHANGED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("../utils");
|
|
4
|
+
exports.default = (0, utils_1.createRule)("no-restricted-html-elements", {
|
|
5
|
+
meta: {
|
|
6
|
+
docs: {
|
|
7
|
+
description: "disallow specific HTML elements",
|
|
8
|
+
category: "Stylistic Issues",
|
|
9
|
+
recommended: false,
|
|
10
|
+
conflictWithPrettier: false,
|
|
11
|
+
},
|
|
12
|
+
schema: {
|
|
13
|
+
type: "array",
|
|
14
|
+
items: {
|
|
15
|
+
oneOf: [
|
|
16
|
+
{ type: "string" },
|
|
17
|
+
{
|
|
18
|
+
type: "object",
|
|
19
|
+
properties: {
|
|
20
|
+
elements: {
|
|
21
|
+
type: "array",
|
|
22
|
+
items: {
|
|
23
|
+
type: ["string"],
|
|
24
|
+
},
|
|
25
|
+
uniqueItems: true,
|
|
26
|
+
minItems: 1,
|
|
27
|
+
},
|
|
28
|
+
message: { type: "string", minLength: 1 },
|
|
29
|
+
},
|
|
30
|
+
additionalProperties: false,
|
|
31
|
+
minItems: 1,
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
uniqueItems: true,
|
|
36
|
+
minItems: 1,
|
|
37
|
+
},
|
|
38
|
+
messages: {},
|
|
39
|
+
type: "suggestion",
|
|
40
|
+
},
|
|
41
|
+
create(context) {
|
|
42
|
+
return {
|
|
43
|
+
SvelteElement(node) {
|
|
44
|
+
if (node.kind !== "html")
|
|
45
|
+
return;
|
|
46
|
+
const { name } = node;
|
|
47
|
+
if (name.type !== "SvelteName")
|
|
48
|
+
return;
|
|
49
|
+
for (const option of context.options) {
|
|
50
|
+
const message = option.message ||
|
|
51
|
+
`Unexpected use of forbidden HTML element ${name.name}.`;
|
|
52
|
+
const elements = option.elements || [option];
|
|
53
|
+
for (const element of elements) {
|
|
54
|
+
if (element === name.name) {
|
|
55
|
+
context.report({
|
|
56
|
+
message,
|
|
57
|
+
node: node.startTag,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const utils_1 = require("../utils");
|
|
7
|
+
const postcss_selector_parser_1 = __importDefault(require("postcss-selector-parser"));
|
|
8
|
+
exports.default = (0, utils_1.createRule)("no-unused-class-name", {
|
|
9
|
+
meta: {
|
|
10
|
+
docs: {
|
|
11
|
+
description: "disallow the use of a class in the template without a corresponding style",
|
|
12
|
+
category: "Best Practices",
|
|
13
|
+
recommended: false,
|
|
14
|
+
},
|
|
15
|
+
schema: [],
|
|
16
|
+
messages: {},
|
|
17
|
+
type: "suggestion",
|
|
18
|
+
},
|
|
19
|
+
create(context) {
|
|
20
|
+
const classesUsedInTemplate = {};
|
|
21
|
+
return {
|
|
22
|
+
SvelteElement(node) {
|
|
23
|
+
if (node.kind !== "html") {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const classes = node.startTag.attributes.flatMap(findClassesInAttribute);
|
|
27
|
+
for (const className of classes) {
|
|
28
|
+
classesUsedInTemplate[className] = node.startTag.loc;
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"Program:exit"() {
|
|
32
|
+
const styleContext = context.parserServices.getStyleContext();
|
|
33
|
+
if (["parse-error", "unknown-lang"].includes(styleContext.status)) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const classesUsedInStyle = styleContext.sourceAst != null
|
|
37
|
+
? findClassesInPostCSSNode(styleContext.sourceAst)
|
|
38
|
+
: [];
|
|
39
|
+
for (const className in classesUsedInTemplate) {
|
|
40
|
+
if (!classesUsedInStyle.includes(className)) {
|
|
41
|
+
context.report({
|
|
42
|
+
loc: classesUsedInTemplate[className],
|
|
43
|
+
message: `Unused class "${className}".`,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
function findClassesInAttribute(attribute) {
|
|
52
|
+
if (attribute.type === "SvelteAttribute" && attribute.key.name === "class") {
|
|
53
|
+
return attribute.value.flatMap((value) => value.type === "SvelteLiteral" ? value.value.trim().split(/\s+/u) : []);
|
|
54
|
+
}
|
|
55
|
+
if (attribute.type === "SvelteDirective" && attribute.kind === "Class") {
|
|
56
|
+
return [attribute.key.name.name];
|
|
57
|
+
}
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
function findClassesInPostCSSNode(node) {
|
|
61
|
+
if (node.type === "rule") {
|
|
62
|
+
let classes = node.nodes.flatMap(findClassesInPostCSSNode);
|
|
63
|
+
const processor = (0, postcss_selector_parser_1.default)();
|
|
64
|
+
classes = classes.concat(findClassesInSelector(processor.astSync(node.selector)));
|
|
65
|
+
return classes;
|
|
66
|
+
}
|
|
67
|
+
if (node.type === "root" || node.type === "atrule") {
|
|
68
|
+
return node.nodes.flatMap(findClassesInPostCSSNode);
|
|
69
|
+
}
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
function findClassesInSelector(node) {
|
|
73
|
+
if (node.type === "class") {
|
|
74
|
+
return [node.value];
|
|
75
|
+
}
|
|
76
|
+
if (node.type === "pseudo" ||
|
|
77
|
+
node.type === "root" ||
|
|
78
|
+
node.type === "selector") {
|
|
79
|
+
return node.nodes.flatMap(findClassesInSelector);
|
|
80
|
+
}
|
|
81
|
+
return [];
|
|
82
|
+
}
|
package/lib/utils/rules.js
CHANGED
|
@@ -36,12 +36,14 @@ const no_object_in_text_mustaches_1 = __importDefault(require("../rules/no-objec
|
|
|
36
36
|
const no_reactive_functions_1 = __importDefault(require("../rules/no-reactive-functions"));
|
|
37
37
|
const no_reactive_literals_1 = __importDefault(require("../rules/no-reactive-literals"));
|
|
38
38
|
const no_reactive_reassign_1 = __importDefault(require("../rules/no-reactive-reassign"));
|
|
39
|
+
const no_restricted_html_elements_1 = __importDefault(require("../rules/no-restricted-html-elements"));
|
|
39
40
|
const no_shorthand_style_property_overrides_1 = __importDefault(require("../rules/no-shorthand-style-property-overrides"));
|
|
40
41
|
const no_spaces_around_equal_signs_in_attribute_1 = __importDefault(require("../rules/no-spaces-around-equal-signs-in-attribute"));
|
|
41
42
|
const no_store_async_1 = __importDefault(require("../rules/no-store-async"));
|
|
42
43
|
const no_target_blank_1 = __importDefault(require("../rules/no-target-blank"));
|
|
43
44
|
const no_trailing_spaces_1 = __importDefault(require("../rules/no-trailing-spaces"));
|
|
44
45
|
const no_unknown_style_directive_property_1 = __importDefault(require("../rules/no-unknown-style-directive-property"));
|
|
46
|
+
const no_unused_class_name_1 = __importDefault(require("../rules/no-unused-class-name"));
|
|
45
47
|
const no_unused_svelte_ignore_1 = __importDefault(require("../rules/no-unused-svelte-ignore"));
|
|
46
48
|
const no_useless_mustaches_1 = __importDefault(require("../rules/no-useless-mustaches"));
|
|
47
49
|
const prefer_class_directive_1 = __importDefault(require("../rules/prefer-class-directive"));
|
|
@@ -94,12 +96,14 @@ exports.rules = [
|
|
|
94
96
|
no_reactive_functions_1.default,
|
|
95
97
|
no_reactive_literals_1.default,
|
|
96
98
|
no_reactive_reassign_1.default,
|
|
99
|
+
no_restricted_html_elements_1.default,
|
|
97
100
|
no_shorthand_style_property_overrides_1.default,
|
|
98
101
|
no_spaces_around_equal_signs_in_attribute_1.default,
|
|
99
102
|
no_store_async_1.default,
|
|
100
103
|
no_target_blank_1.default,
|
|
101
104
|
no_trailing_spaces_1.default,
|
|
102
105
|
no_unknown_style_directive_property_1.default,
|
|
106
|
+
no_unused_class_name_1.default,
|
|
103
107
|
no_unused_svelte_ignore_1.default,
|
|
104
108
|
no_useless_mustaches_1.default,
|
|
105
109
|
prefer_class_directive_1.default,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-svelte",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.31.0",
|
|
4
4
|
"description": "ESLint plugin for Svelte using AST",
|
|
5
5
|
"repository": "git+https://github.com/sveltejs/eslint-plugin-svelte.git",
|
|
6
6
|
"homepage": "https://sveltejs.github.io/eslint-plugin-svelte",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
],
|
|
11
11
|
"funding": "https://github.com/sponsors/ota-meshi",
|
|
12
12
|
"license": "MIT",
|
|
13
|
-
"packageManager": "pnpm@7.
|
|
13
|
+
"packageManager": "pnpm@7.33.1",
|
|
14
14
|
"engines": {
|
|
15
15
|
"node": "^14.17.0 || >=16.0.0"
|
|
16
16
|
},
|
|
@@ -43,7 +43,8 @@
|
|
|
43
43
|
"postcss": "^8.4.5",
|
|
44
44
|
"postcss-load-config": "^3.1.4",
|
|
45
45
|
"postcss-safe-parser": "^6.0.0",
|
|
46
|
-
"
|
|
46
|
+
"postcss-selector-parser": "^6.0.11",
|
|
47
|
+
"svelte-eslint-parser": "^0.31.0"
|
|
47
48
|
},
|
|
48
49
|
"devDependencies": {
|
|
49
50
|
"@1stg/browserslist-config": "^1.2.3",
|
|
@@ -85,7 +86,7 @@
|
|
|
85
86
|
"assert": "^2.0.0",
|
|
86
87
|
"cross-spawn": "^7.0.3",
|
|
87
88
|
"env-cmd": "^10.1.0",
|
|
88
|
-
"esbuild": "^0.
|
|
89
|
+
"esbuild": "^0.18.0",
|
|
89
90
|
"esbuild-register": "^3.2.0",
|
|
90
91
|
"escape-html": "^1.0.3",
|
|
91
92
|
"eslint": "^8.40.0",
|
|
@@ -108,7 +109,7 @@
|
|
|
108
109
|
"espree": "^9.5.2",
|
|
109
110
|
"estree-walker": "^3.0.0",
|
|
110
111
|
"less": "^4.1.2",
|
|
111
|
-
"locate-character": "^
|
|
112
|
+
"locate-character": "^3.0.0",
|
|
112
113
|
"magic-string": "^0.30.0",
|
|
113
114
|
"markdown-it-anchor": "^8.4.1",
|
|
114
115
|
"markdown-it-container": "^3.0.0",
|