eslint-plugin-svelte 2.44.1 → 2.45.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/configs/flat/all.d.ts +1 -1
- package/lib/configs/flat/prettier.js +1 -0
- package/lib/configs/prettier.js +1 -0
- package/lib/index.d.ts +1 -1
- package/lib/meta.d.ts +1 -1
- package/lib/meta.js +1 -1
- package/lib/rule-types.d.ts +20 -0
- package/lib/rules/html-closing-bracket-new-line.d.ts +2 -0
- package/lib/rules/html-closing-bracket-new-line.js +118 -0
- package/lib/rules/no-inspect.d.ts +2 -0
- package/lib/rules/no-inspect.js +29 -0
- package/lib/utils/rules.js +4 -0
- package/package.json +16 -16
package/README.md
CHANGED
|
@@ -419,6 +419,7 @@ These rules relate to better ways of doing things to help you avoid problems:
|
|
|
419
419
|
| [svelte/no-ignored-unsubscribe](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-ignored-unsubscribe/) | disallow ignoring the unsubscribe method returned by the `subscribe()` on Svelte stores. | |
|
|
420
420
|
| [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. | |
|
|
421
421
|
| [svelte/no-inline-styles](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-inline-styles/) | disallow attributes and directives that produce inline styles | |
|
|
422
|
+
| [svelte/no-inspect](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-inspect/) | Warns against the use of `$inspect` directive | |
|
|
422
423
|
| [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: |
|
|
423
424
|
| [svelte/no-reactive-literals](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-reactive-literals/) | don't assign literal values in reactive statements | :bulb: |
|
|
424
425
|
| [svelte/no-svelte-internal](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-svelte-internal/) | svelte/internal will be removed in Svelte 6. | |
|
|
@@ -440,6 +441,7 @@ These rules relate to style guidelines, and are therefore quite subjective:
|
|
|
440
441
|
|:--------|:------------|:---|
|
|
441
442
|
| [svelte/derived-has-same-inputs-outputs](https://sveltejs.github.io/eslint-plugin-svelte/rules/derived-has-same-inputs-outputs/) | derived store should use same variable names between values and callback | |
|
|
442
443
|
| [svelte/first-attribute-linebreak](https://sveltejs.github.io/eslint-plugin-svelte/rules/first-attribute-linebreak/) | enforce the location of first attribute | :wrench: |
|
|
444
|
+
| [svelte/html-closing-bracket-new-line](https://sveltejs.github.io/eslint-plugin-svelte/rules/html-closing-bracket-new-line/) | Require or disallow a line break before tag's closing brackets | :wrench: |
|
|
443
445
|
| [svelte/html-closing-bracket-spacing](https://sveltejs.github.io/eslint-plugin-svelte/rules/html-closing-bracket-spacing/) | require or disallow a space before tag's closing brackets | :wrench: |
|
|
444
446
|
| [svelte/html-quotes](https://sveltejs.github.io/eslint-plugin-svelte/rules/html-quotes/) | enforce quotes style of HTML attributes | :wrench: |
|
|
445
447
|
| [svelte/html-self-closing](https://sveltejs.github.io/eslint-plugin-svelte/rules/html-self-closing/) | enforce self-closing style | :wrench: |
|
|
@@ -11,6 +11,7 @@ const config = [
|
|
|
11
11
|
rules: {
|
|
12
12
|
// eslint-plugin-svelte rules
|
|
13
13
|
'svelte/first-attribute-linebreak': 'off',
|
|
14
|
+
'svelte/html-closing-bracket-new-line': 'off',
|
|
14
15
|
'svelte/html-closing-bracket-spacing': 'off',
|
|
15
16
|
'svelte/html-quotes': 'off',
|
|
16
17
|
'svelte/html-self-closing': 'off',
|
package/lib/configs/prettier.js
CHANGED
|
@@ -10,6 +10,7 @@ const config = {
|
|
|
10
10
|
rules: {
|
|
11
11
|
// eslint-plugin-svelte rules
|
|
12
12
|
'svelte/first-attribute-linebreak': 'off',
|
|
13
|
+
'svelte/html-closing-bracket-new-line': 'off',
|
|
13
14
|
'svelte/html-closing-bracket-spacing': 'off',
|
|
14
15
|
'svelte/html-quotes': 'off',
|
|
15
16
|
'svelte/html-self-closing': 'off',
|
package/lib/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ declare const _default: {
|
|
|
11
11
|
'flat/base': import("eslint").Linter.Config<import("eslint").Linter.RulesRecord>[];
|
|
12
12
|
'flat/recommended': import("eslint").Linter.Config<import("eslint").Linter.RulesRecord>[];
|
|
13
13
|
'flat/prettier': import("eslint").Linter.Config<import("eslint").Linter.RulesRecord>[];
|
|
14
|
-
'flat/all': import("eslint").Linter.
|
|
14
|
+
'flat/all': import("eslint").Linter.Config<import("eslint").Linter.RulesRecord>[];
|
|
15
15
|
};
|
|
16
16
|
rules: {
|
|
17
17
|
[key: string]: RuleModule;
|
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.45.0";
|
package/lib/meta.js
CHANGED
package/lib/rule-types.d.ts
CHANGED
|
@@ -47,6 +47,11 @@ export interface RuleOptions {
|
|
|
47
47
|
* @see https://sveltejs.github.io/eslint-plugin-svelte/rules/first-attribute-linebreak/
|
|
48
48
|
*/
|
|
49
49
|
'svelte/first-attribute-linebreak'?: Linter.RuleEntry<SvelteFirstAttributeLinebreak>;
|
|
50
|
+
/**
|
|
51
|
+
* Require or disallow a line break before tag's closing brackets
|
|
52
|
+
* @see https://sveltejs.github.io/eslint-plugin-svelte/rules/html-closing-bracket-new-line/
|
|
53
|
+
*/
|
|
54
|
+
'svelte/html-closing-bracket-new-line'?: Linter.RuleEntry<SvelteHtmlClosingBracketNewLine>;
|
|
50
55
|
/**
|
|
51
56
|
* require or disallow a space before tag's closing brackets
|
|
52
57
|
* @see https://sveltejs.github.io/eslint-plugin-svelte/rules/html-closing-bracket-spacing/
|
|
@@ -157,6 +162,11 @@ export interface RuleOptions {
|
|
|
157
162
|
* @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-inner-declarations/
|
|
158
163
|
*/
|
|
159
164
|
'svelte/no-inner-declarations'?: Linter.RuleEntry<SvelteNoInnerDeclarations>;
|
|
165
|
+
/**
|
|
166
|
+
* Warns against the use of `$inspect` directive
|
|
167
|
+
* @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-inspect/
|
|
168
|
+
*/
|
|
169
|
+
'svelte/no-inspect'?: Linter.RuleEntry<[]>;
|
|
160
170
|
/**
|
|
161
171
|
* disallow use of not function in event handler
|
|
162
172
|
* @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-not-function-handler/
|
|
@@ -355,6 +365,16 @@ type SvelteFirstAttributeLinebreak = [] | [
|
|
|
355
365
|
singleline?: ("below" | "beside");
|
|
356
366
|
}
|
|
357
367
|
];
|
|
368
|
+
type SvelteHtmlClosingBracketNewLine = [] | [
|
|
369
|
+
{
|
|
370
|
+
singleline?: ("always" | "never");
|
|
371
|
+
multiline?: ("always" | "never");
|
|
372
|
+
selfClosingTag?: {
|
|
373
|
+
singleline?: ("always" | "never");
|
|
374
|
+
multiline?: ("always" | "never");
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
];
|
|
358
378
|
type SvelteHtmlClosingBracketSpacing = [] | [
|
|
359
379
|
{
|
|
360
380
|
startTag?: ("always" | "never" | "ignore");
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("../utils");
|
|
4
|
+
const compat_1 = require("../utils/compat");
|
|
5
|
+
function getPhrase(lineBreaks) {
|
|
6
|
+
switch (lineBreaks) {
|
|
7
|
+
case 0: {
|
|
8
|
+
return 'no line breaks';
|
|
9
|
+
}
|
|
10
|
+
case 1: {
|
|
11
|
+
return '1 line break';
|
|
12
|
+
}
|
|
13
|
+
default: {
|
|
14
|
+
return `${lineBreaks} line breaks`;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function getExpectedLineBreaks(node, options, type) {
|
|
19
|
+
const isSelfClosingTag = node.type === 'SvelteStartTag' && node.selfClosing;
|
|
20
|
+
if (isSelfClosingTag && options.selfClosingTag && options.selfClosingTag[type]) {
|
|
21
|
+
return options.selfClosingTag[type] === 'always' ? 1 : 0;
|
|
22
|
+
}
|
|
23
|
+
return options[type] === 'always' ? 1 : 0;
|
|
24
|
+
}
|
|
25
|
+
function getSelfClosingData(sourceCode, node, options) {
|
|
26
|
+
const tokens = sourceCode.getTokens(node);
|
|
27
|
+
const closingToken = tokens[tokens.length - 2];
|
|
28
|
+
if (closingToken.value !== '/') {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
const prevToken = sourceCode.getTokenBefore(closingToken);
|
|
32
|
+
const type = node.loc.start.line === prevToken.loc.end.line ? 'singleline' : 'multiline';
|
|
33
|
+
const expectedLineBreaks = getExpectedLineBreaks(node, options, type);
|
|
34
|
+
const actualLineBreaks = closingToken.loc.start.line - prevToken.loc.end.line;
|
|
35
|
+
return { actualLineBreaks, expectedLineBreaks, startToken: prevToken, endToken: closingToken };
|
|
36
|
+
}
|
|
37
|
+
function getNodeData(sourceCode, node, options) {
|
|
38
|
+
const closingToken = sourceCode.getLastToken(node);
|
|
39
|
+
if (closingToken.value !== '>') {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const prevToken = sourceCode.getTokenBefore(closingToken);
|
|
43
|
+
const type = node.loc.start.line === prevToken.loc.end.line ? 'singleline' : 'multiline';
|
|
44
|
+
const expectedLineBreaks = getExpectedLineBreaks(node, options, type);
|
|
45
|
+
const actualLineBreaks = closingToken.loc.start.line - prevToken.loc.end.line;
|
|
46
|
+
return { actualLineBreaks, expectedLineBreaks, startToken: prevToken, endToken: closingToken };
|
|
47
|
+
}
|
|
48
|
+
exports.default = (0, utils_1.createRule)('html-closing-bracket-new-line', {
|
|
49
|
+
meta: {
|
|
50
|
+
docs: {
|
|
51
|
+
description: "Require or disallow a line break before tag's closing brackets",
|
|
52
|
+
category: 'Stylistic Issues',
|
|
53
|
+
recommended: false,
|
|
54
|
+
conflictWithPrettier: true
|
|
55
|
+
},
|
|
56
|
+
schema: [
|
|
57
|
+
{
|
|
58
|
+
type: 'object',
|
|
59
|
+
properties: {
|
|
60
|
+
singleline: { enum: ['always', 'never'] },
|
|
61
|
+
multiline: { enum: ['always', 'never'] },
|
|
62
|
+
selfClosingTag: {
|
|
63
|
+
type: 'object',
|
|
64
|
+
properties: {
|
|
65
|
+
singleline: { enum: ['always', 'never'] },
|
|
66
|
+
multiline: { enum: ['always', 'never'] }
|
|
67
|
+
},
|
|
68
|
+
additionalProperties: false,
|
|
69
|
+
minProperties: 1
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
additionalProperties: false
|
|
73
|
+
}
|
|
74
|
+
],
|
|
75
|
+
messages: {
|
|
76
|
+
expectedBeforeClosingBracket: 'Expected {{expected}} before closing bracket, but {{actual}} found.'
|
|
77
|
+
},
|
|
78
|
+
fixable: 'code',
|
|
79
|
+
type: 'suggestion'
|
|
80
|
+
},
|
|
81
|
+
create(context) {
|
|
82
|
+
const options = context.options[0] ?? {};
|
|
83
|
+
options.singleline ?? (options.singleline = 'never');
|
|
84
|
+
options.multiline ?? (options.multiline = 'always');
|
|
85
|
+
const sourceCode = (0, compat_1.getSourceCode)(context);
|
|
86
|
+
return {
|
|
87
|
+
'SvelteStartTag, SvelteEndTag'(node) {
|
|
88
|
+
const data = node.type === 'SvelteStartTag' && node.selfClosing
|
|
89
|
+
? getSelfClosingData(sourceCode, node, options)
|
|
90
|
+
: getNodeData(sourceCode, node, options);
|
|
91
|
+
if (!data) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const { actualLineBreaks, expectedLineBreaks, startToken, endToken } = data;
|
|
95
|
+
if (actualLineBreaks !== expectedLineBreaks) {
|
|
96
|
+
// For SvelteEndTag, does not make sense to add a line break, so we only fix if there are extra line breaks
|
|
97
|
+
if (node.type === 'SvelteEndTag' && expectedLineBreaks !== 0) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
context.report({
|
|
101
|
+
node,
|
|
102
|
+
loc: { start: startToken.loc.end, end: endToken.loc.start },
|
|
103
|
+
messageId: 'expectedBeforeClosingBracket',
|
|
104
|
+
data: {
|
|
105
|
+
expected: getPhrase(expectedLineBreaks),
|
|
106
|
+
actual: getPhrase(actualLineBreaks)
|
|
107
|
+
},
|
|
108
|
+
fix(fixer) {
|
|
109
|
+
const range = [startToken.range[1], endToken.range[0]];
|
|
110
|
+
const text = '\n'.repeat(expectedLineBreaks);
|
|
111
|
+
return fixer.replaceTextRange(range, text);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("../utils");
|
|
4
|
+
exports.default = (0, utils_1.createRule)('no-inspect', {
|
|
5
|
+
meta: {
|
|
6
|
+
docs: {
|
|
7
|
+
description: 'Warns against the use of `$inspect` directive',
|
|
8
|
+
category: 'Best Practices',
|
|
9
|
+
// TODO: Enable recommended in major version
|
|
10
|
+
recommended: false,
|
|
11
|
+
default: 'warn'
|
|
12
|
+
},
|
|
13
|
+
schema: [],
|
|
14
|
+
messages: {
|
|
15
|
+
unexpected: 'Do not use $inspect directive'
|
|
16
|
+
},
|
|
17
|
+
type: 'suggestion'
|
|
18
|
+
},
|
|
19
|
+
create(context) {
|
|
20
|
+
return {
|
|
21
|
+
Identifier(node) {
|
|
22
|
+
if (node.name !== '$inspect') {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
context.report({ messageId: 'unexpected', node });
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
});
|
package/lib/utils/rules.js
CHANGED
|
@@ -12,6 +12,7 @@ const derived_has_same_inputs_outputs_1 = __importDefault(require("../rules/deri
|
|
|
12
12
|
const experimental_require_slot_types_1 = __importDefault(require("../rules/experimental-require-slot-types"));
|
|
13
13
|
const experimental_require_strict_events_1 = __importDefault(require("../rules/experimental-require-strict-events"));
|
|
14
14
|
const first_attribute_linebreak_1 = __importDefault(require("../rules/first-attribute-linebreak"));
|
|
15
|
+
const html_closing_bracket_new_line_1 = __importDefault(require("../rules/html-closing-bracket-new-line"));
|
|
15
16
|
const html_closing_bracket_spacing_1 = __importDefault(require("../rules/html-closing-bracket-spacing"));
|
|
16
17
|
const html_quotes_1 = __importDefault(require("../rules/html-quotes"));
|
|
17
18
|
const html_self_closing_1 = __importDefault(require("../rules/html-self-closing"));
|
|
@@ -34,6 +35,7 @@ const no_ignored_unsubscribe_1 = __importDefault(require("../rules/no-ignored-un
|
|
|
34
35
|
const no_immutable_reactive_statements_1 = __importDefault(require("../rules/no-immutable-reactive-statements"));
|
|
35
36
|
const no_inline_styles_1 = __importDefault(require("../rules/no-inline-styles"));
|
|
36
37
|
const no_inner_declarations_1 = __importDefault(require("../rules/no-inner-declarations"));
|
|
38
|
+
const no_inspect_1 = __importDefault(require("../rules/no-inspect"));
|
|
37
39
|
const no_not_function_handler_1 = __importDefault(require("../rules/no-not-function-handler"));
|
|
38
40
|
const no_object_in_text_mustaches_1 = __importDefault(require("../rules/no-object-in-text-mustaches"));
|
|
39
41
|
const no_reactive_functions_1 = __importDefault(require("../rules/no-reactive-functions"));
|
|
@@ -76,6 +78,7 @@ exports.rules = [
|
|
|
76
78
|
experimental_require_slot_types_1.default,
|
|
77
79
|
experimental_require_strict_events_1.default,
|
|
78
80
|
first_attribute_linebreak_1.default,
|
|
81
|
+
html_closing_bracket_new_line_1.default,
|
|
79
82
|
html_closing_bracket_spacing_1.default,
|
|
80
83
|
html_quotes_1.default,
|
|
81
84
|
html_self_closing_1.default,
|
|
@@ -98,6 +101,7 @@ exports.rules = [
|
|
|
98
101
|
no_immutable_reactive_statements_1.default,
|
|
99
102
|
no_inline_styles_1.default,
|
|
100
103
|
no_inner_declarations_1.default,
|
|
104
|
+
no_inspect_1.default,
|
|
101
105
|
no_not_function_handler_1.default,
|
|
102
106
|
no_object_in_text_mustaches_1.default,
|
|
103
107
|
no_reactive_functions_1.default,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-svelte",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.45.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",
|
|
@@ -45,39 +45,39 @@
|
|
|
45
45
|
"svelte-eslint-parser": "^0.41.1"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@babel/core": "^7.25.
|
|
49
|
-
"@babel/eslint-parser": "^7.25.
|
|
50
|
-
"@babel/plugin-proposal-function-bind": "^7.
|
|
48
|
+
"@babel/core": "^7.25.8",
|
|
49
|
+
"@babel/eslint-parser": "^7.25.8",
|
|
50
|
+
"@babel/plugin-proposal-function-bind": "^7.25.8",
|
|
51
51
|
"@eslint-community/eslint-plugin-eslint-comments": "^4.4.0",
|
|
52
52
|
"@types/babel__core": "^7.20.5",
|
|
53
53
|
"@types/eslint-utils": "^3.0.5",
|
|
54
54
|
"@types/esutils": "^2.0.2",
|
|
55
55
|
"@types/json-schema": "^7.0.15",
|
|
56
56
|
"@types/less": "^3.0.6",
|
|
57
|
-
"@types/mocha": "^10.0.
|
|
58
|
-
"@types/node": "^20.16.
|
|
57
|
+
"@types/mocha": "^10.0.9",
|
|
58
|
+
"@types/node": "^20.16.11",
|
|
59
59
|
"@types/postcss-safe-parser": "^5.0.4",
|
|
60
60
|
"@types/semver": "^7.5.8",
|
|
61
|
-
"@types/stylus": "^0.48.
|
|
62
|
-
"acorn": "^8.
|
|
61
|
+
"@types/stylus": "^0.48.43",
|
|
62
|
+
"acorn": "^8.13.0",
|
|
63
63
|
"assert": "^2.1.0",
|
|
64
64
|
"esbuild": "^0.24.0",
|
|
65
65
|
"esbuild-register": "^3.6.0",
|
|
66
|
-
"eslint-scope": "^8.0
|
|
66
|
+
"eslint-scope": "^8.1.0",
|
|
67
67
|
"eslint-typegen": "^0.3.2",
|
|
68
|
-
"eslint-visitor-keys": "^4.
|
|
69
|
-
"espree": "^10.
|
|
68
|
+
"eslint-visitor-keys": "^4.1.0",
|
|
69
|
+
"espree": "^10.2.0",
|
|
70
70
|
"less": "^4.2.0",
|
|
71
71
|
"mocha": "^10.7.3",
|
|
72
|
-
"nyc": "^17.
|
|
72
|
+
"nyc": "^17.1.0",
|
|
73
73
|
"postcss-nested": "^6.2.0",
|
|
74
|
-
"sass": "^1.
|
|
74
|
+
"sass": "^1.79.5",
|
|
75
75
|
"source-map-js": "^1.2.1",
|
|
76
76
|
"stylus": "^0.63.0",
|
|
77
|
-
"svelte": "5.0.0-next.
|
|
77
|
+
"svelte": "^5.0.0-next.268",
|
|
78
78
|
"svelte-i18n": "^4.0.0",
|
|
79
|
-
"type-coverage": "^2.29.
|
|
80
|
-
"yaml": "^2.
|
|
79
|
+
"type-coverage": "^2.29.7",
|
|
80
|
+
"yaml": "^2.6.0"
|
|
81
81
|
},
|
|
82
82
|
"publishConfig": {
|
|
83
83
|
"access": "public"
|