eslint-plugin-svelte 3.19.0 → 3.20.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 -1
- package/lib/main.d.ts +1 -1
- package/lib/meta.d.ts +1 -1
- package/lib/meta.js +1 -1
- package/lib/rule-types.d.ts +6 -1
- package/lib/rules/no-at-const-tags.d.ts +2 -0
- package/lib/rules/no-at-const-tags.js +67 -0
- package/lib/rules/valid-prop-names-in-kit-pages.js +21 -9
- package/lib/utils/rules.js +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -334,6 +334,7 @@ These rules relate to better ways of doing things to help you avoid problems:
|
|
|
334
334
|
| [svelte/block-lang](https://sveltejs.github.io/eslint-plugin-svelte/rules/block-lang/) | disallows the use of languages other than those specified in the configuration for the lang attribute of `<script>` and `<style>` blocks. | :bulb: |
|
|
335
335
|
| [svelte/button-has-type](https://sveltejs.github.io/eslint-plugin-svelte/rules/button-has-type/) | disallow usage of button without an explicit type attribute | |
|
|
336
336
|
| [svelte/no-add-event-listener](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-add-event-listener/) | Warns against the use of `addEventListener` | :bulb: |
|
|
337
|
+
| [svelte/no-at-const-tags](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-at-const-tags/) | disallow the use of `{@const}` in favor of `{const ...}` declaration tags | :wrench: |
|
|
337
338
|
| [svelte/no-at-debug-tags](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-at-debug-tags/) | disallow the use of `{@debug}` | :star::bulb: |
|
|
338
339
|
| [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. | |
|
|
339
340
|
| [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. | :star: |
|
|
@@ -403,7 +404,7 @@ These rules relate to SvelteKit and its best Practices.
|
|
|
403
404
|
|:--------|:------------|:---|
|
|
404
405
|
| [svelte/no-export-load-in-svelte-module-in-kit-pages](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-export-load-in-svelte-module-in-kit-pages/) | disallow exporting load functions in `*.svelte` module in SvelteKit page components. | :star: |
|
|
405
406
|
| [svelte/no-navigation-without-resolve](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-navigation-without-resolve/) | disallow internal navigation (links, `goto()`, `pushState()`, `replaceState()`) without a `resolve()` | :star: |
|
|
406
|
-
| [svelte/valid-prop-names-in-kit-pages](https://sveltejs.github.io/eslint-plugin-svelte/rules/valid-prop-names-in-kit-pages/) | disallow props
|
|
407
|
+
| [svelte/valid-prop-names-in-kit-pages](https://sveltejs.github.io/eslint-plugin-svelte/rules/valid-prop-names-in-kit-pages/) | disallow invalid props in SvelteKit route components. | :star: |
|
|
407
408
|
|
|
408
409
|
## Experimental
|
|
409
410
|
|
package/lib/main.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export declare const configs: {
|
|
|
14
14
|
export declare const rules: Record<string, Rule.RuleModule>;
|
|
15
15
|
export declare const meta: {
|
|
16
16
|
name: "eslint-plugin-svelte";
|
|
17
|
-
version: "3.
|
|
17
|
+
version: "3.20.0";
|
|
18
18
|
};
|
|
19
19
|
export declare const processors: {
|
|
20
20
|
'.svelte': typeof processor;
|
package/lib/meta.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare const name: "eslint-plugin-svelte";
|
|
2
|
-
export declare const version: "3.
|
|
2
|
+
export declare const version: "3.20.0";
|
package/lib/meta.js
CHANGED
package/lib/rule-types.d.ts
CHANGED
|
@@ -100,6 +100,11 @@ export interface RuleOptions {
|
|
|
100
100
|
* @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-add-event-listener/
|
|
101
101
|
*/
|
|
102
102
|
'svelte/no-add-event-listener'?: Linter.RuleEntry<[]>;
|
|
103
|
+
/**
|
|
104
|
+
* disallow the use of `{@const}` in favor of `{const ...}` declaration tags
|
|
105
|
+
* @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-at-const-tags/
|
|
106
|
+
*/
|
|
107
|
+
'svelte/no-at-const-tags'?: Linter.RuleEntry<[]>;
|
|
103
108
|
/**
|
|
104
109
|
* disallow the use of `{@debug}`
|
|
105
110
|
* @see https://sveltejs.github.io/eslint-plugin-svelte/rules/no-at-debug-tags/
|
|
@@ -409,7 +414,7 @@ export interface RuleOptions {
|
|
|
409
414
|
*/
|
|
410
415
|
'svelte/valid-each-key'?: Linter.RuleEntry<[]>;
|
|
411
416
|
/**
|
|
412
|
-
* disallow props
|
|
417
|
+
* disallow invalid props in SvelteKit route components.
|
|
413
418
|
* @see https://sveltejs.github.io/eslint-plugin-svelte/rules/valid-prop-names-in-kit-pages/
|
|
414
419
|
*/
|
|
415
420
|
'svelte/valid-prop-names-in-kit-pages'?: Linter.RuleEntry<[]>;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { createRule } from '../utils/index.js';
|
|
2
|
+
import { getSvelteContext } from '../utils/svelte-context.js';
|
|
3
|
+
import { VERSION as SVELTE_VERSION } from 'svelte/compiler';
|
|
4
|
+
import semver from 'semver';
|
|
5
|
+
const shouldRun = semver.satisfies(SVELTE_VERSION, '>=5.56.0');
|
|
6
|
+
export default createRule('no-at-const-tags', {
|
|
7
|
+
meta: {
|
|
8
|
+
docs: {
|
|
9
|
+
description: 'disallow the use of `{@const}` in favor of `{const ...}` declaration tags',
|
|
10
|
+
category: 'Best Practices',
|
|
11
|
+
recommended: false
|
|
12
|
+
},
|
|
13
|
+
fixable: 'code',
|
|
14
|
+
schema: [],
|
|
15
|
+
messages: {
|
|
16
|
+
unexpected: 'Use `{const ...}` declaration tag instead of legacy `{@const ...}`.'
|
|
17
|
+
},
|
|
18
|
+
type: 'suggestion',
|
|
19
|
+
conditions: [
|
|
20
|
+
{
|
|
21
|
+
svelteVersions: ['5']
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
create(context) {
|
|
26
|
+
if (!shouldRun) {
|
|
27
|
+
return {};
|
|
28
|
+
}
|
|
29
|
+
const sourceCode = context.sourceCode;
|
|
30
|
+
const runes = getSvelteContext(context)?.runes;
|
|
31
|
+
// Only report and fix in runes mode, since preserving reactivity requires
|
|
32
|
+
// `$derived(...)`, which is unavailable outside runes mode.
|
|
33
|
+
if (runes !== true) {
|
|
34
|
+
return {};
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
SvelteConstTag(node) {
|
|
38
|
+
context.report({
|
|
39
|
+
node,
|
|
40
|
+
messageId: 'unexpected',
|
|
41
|
+
*fix(fixer) {
|
|
42
|
+
const text = sourceCode.getText(node);
|
|
43
|
+
const match = /^\{(\s*)@const\b/u.exec(text);
|
|
44
|
+
if (!match) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const atOffset = node.range[0] + 1 + match[1].length;
|
|
48
|
+
yield fixer.removeRange([atOffset, atOffset + 1]);
|
|
49
|
+
const init = node.declarations[0].init;
|
|
50
|
+
if (init == null) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
// Preserve the reactivity of legacy `{@const}` by wrapping the
|
|
54
|
+
// initializer in `$derived(...)`. Skip when already wrapped.
|
|
55
|
+
if (init.type === 'CallExpression' &&
|
|
56
|
+
init.callee.type === 'Identifier' &&
|
|
57
|
+
init.callee.name === '$derived') {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
yield fixer.insertTextBefore(init, '$derived(');
|
|
61
|
+
yield fixer.insertTextAfter(init, ')');
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
});
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { createRule } from '../utils/index.js';
|
|
2
|
-
import { getSvelteVersion } from '../utils/svelte-context.js';
|
|
3
|
-
const
|
|
4
|
-
const
|
|
2
|
+
import { getSvelteContext, getSvelteVersion } from '../utils/svelte-context.js';
|
|
3
|
+
const PAGE_PROP_NAMES = ['data', 'form', 'params', 'snapshot'];
|
|
4
|
+
const LEGACY_PAGE_PROP_NAMES = [...PAGE_PROP_NAMES, 'errors'];
|
|
5
|
+
const LAYOUT_PROP_NAMES = [...PAGE_PROP_NAMES, 'children'];
|
|
6
|
+
const ERROR_PROP_NAMES = ['error'];
|
|
5
7
|
function checkProp(node, context, expectedPropNames) {
|
|
6
8
|
if (node.id.type !== 'ObjectPattern')
|
|
7
9
|
return;
|
|
@@ -32,25 +34,35 @@ function isModuleScript(node) {
|
|
|
32
34
|
export default createRule('valid-prop-names-in-kit-pages', {
|
|
33
35
|
meta: {
|
|
34
36
|
docs: {
|
|
35
|
-
description: 'disallow props
|
|
37
|
+
description: 'disallow invalid props in SvelteKit route components.',
|
|
36
38
|
category: 'SvelteKit',
|
|
37
39
|
recommended: true
|
|
38
40
|
},
|
|
39
41
|
schema: [],
|
|
40
42
|
messages: {
|
|
41
|
-
unexpected: 'disallow props
|
|
43
|
+
unexpected: 'disallow invalid props in SvelteKit route components.'
|
|
42
44
|
},
|
|
43
45
|
type: 'problem',
|
|
44
46
|
conditions: [
|
|
45
47
|
{
|
|
46
|
-
svelteKitFileTypes: ['+page.svelte', '+
|
|
48
|
+
svelteKitFileTypes: ['+page.svelte', '+layout.svelte', '+error.svelte']
|
|
47
49
|
}
|
|
48
50
|
]
|
|
49
51
|
},
|
|
50
52
|
create(context) {
|
|
51
53
|
let isScript = false;
|
|
52
54
|
const isSvelte5 = getSvelteVersion() === '5';
|
|
53
|
-
const
|
|
55
|
+
const svelteContext = getSvelteContext(context);
|
|
56
|
+
const fileType = svelteContext?.svelteKitFileType;
|
|
57
|
+
let expectedPropNames = PAGE_PROP_NAMES;
|
|
58
|
+
if (isSvelte5) {
|
|
59
|
+
if (fileType === '+layout.svelte') {
|
|
60
|
+
expectedPropNames = LAYOUT_PROP_NAMES;
|
|
61
|
+
}
|
|
62
|
+
else if (fileType === '+error.svelte') {
|
|
63
|
+
expectedPropNames = ERROR_PROP_NAMES;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
54
66
|
return {
|
|
55
67
|
// <script>
|
|
56
68
|
'Program > SvelteScriptElement > SvelteStartTag': (node) => {
|
|
@@ -67,7 +79,7 @@ export default createRule('valid-prop-names-in-kit-pages', {
|
|
|
67
79
|
return;
|
|
68
80
|
// export let foo
|
|
69
81
|
if (node.id.type === 'Identifier') {
|
|
70
|
-
if (!
|
|
82
|
+
if (!LEGACY_PAGE_PROP_NAMES.includes(node.id.name)) {
|
|
71
83
|
context.report({
|
|
72
84
|
node,
|
|
73
85
|
loc: node.loc,
|
|
@@ -77,7 +89,7 @@ export default createRule('valid-prop-names-in-kit-pages', {
|
|
|
77
89
|
return;
|
|
78
90
|
}
|
|
79
91
|
// export let { xxx, yyy } = zzz
|
|
80
|
-
checkProp(node, context,
|
|
92
|
+
checkProp(node, context, LEGACY_PAGE_PROP_NAMES);
|
|
81
93
|
},
|
|
82
94
|
// Svelte5
|
|
83
95
|
// let { foo, bar } = $props();
|
package/lib/utils/rules.js
CHANGED
|
@@ -17,6 +17,7 @@ import maxAttributesPerLine from '../rules/max-attributes-per-line.js';
|
|
|
17
17
|
import maxLinesPerBlock from '../rules/max-lines-per-block.js';
|
|
18
18
|
import mustacheSpacing from '../rules/mustache-spacing.js';
|
|
19
19
|
import noAddEventListener from '../rules/no-add-event-listener.js';
|
|
20
|
+
import noAtConstTags from '../rules/no-at-const-tags.js';
|
|
20
21
|
import noAtDebugTags from '../rules/no-at-debug-tags.js';
|
|
21
22
|
import noAtHtmlTags from '../rules/no-at-html-tags.js';
|
|
22
23
|
import noDomManipulating from '../rules/no-dom-manipulating.js';
|
|
@@ -100,6 +101,7 @@ export const rules = [
|
|
|
100
101
|
maxLinesPerBlock,
|
|
101
102
|
mustacheSpacing,
|
|
102
103
|
noAddEventListener,
|
|
104
|
+
noAtConstTags,
|
|
103
105
|
noAtDebugTags,
|
|
104
106
|
noAtHtmlTags,
|
|
105
107
|
noDomManipulating,
|