eslint-plugin-svelte 2.33.1 → 2.34.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 CHANGED
@@ -340,6 +340,7 @@ These rules relate to better ways of doing things to help you avoid problems:
340
340
  | [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. | |
341
341
  | [svelte/button-has-type](https://sveltejs.github.io/eslint-plugin-svelte/rules/button-has-type/) | disallow usage of button without an explicit type attribute | |
342
342
  | [svelte/no-at-debug-tags](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-at-debug-tags/) | disallow the use of `{@debug}` | :star: |
343
+ | [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. | |
343
344
  | [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
345
  | [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
346
  | [svelte/no-reactive-literals](https://sveltejs.github.io/eslint-plugin-svelte/rules/no-reactive-literals/) | don't assign literal values in reactive statements | :bulb: |
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.33.1";
2
+ export declare const version: "2.34.0";
package/lib/meta.js CHANGED
@@ -2,4 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.version = exports.name = void 0;
4
4
  exports.name = 'eslint-plugin-svelte';
5
- exports.version = '2.33.1';
5
+ exports.version = '2.34.0';
@@ -0,0 +1,2 @@
1
+ declare const _default: import("../types").RuleModule;
2
+ export default _default;
@@ -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-ignored-unsubscribe', {
5
+ meta: {
6
+ docs: {
7
+ description: 'disallow ignoring the unsubscribe method returned by the `subscribe()` on Svelte stores.',
8
+ category: 'Best Practices',
9
+ recommended: false
10
+ },
11
+ fixable: undefined,
12
+ hasSuggestions: false,
13
+ messages: {
14
+ forbidden: 'Ignoring returned value of the subscribe method is forbidden.'
15
+ },
16
+ schema: [],
17
+ type: 'problem'
18
+ },
19
+ create: (context) => {
20
+ return {
21
+ "ExpressionStatement > CallExpression > MemberExpression.callee[property.name='subscribe']": (node) => {
22
+ context.report({
23
+ messageId: 'forbidden',
24
+ node: node.property
25
+ });
26
+ }
27
+ };
28
+ }
29
+ });
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const utils_1 = require("../utils");
4
+ const ast_utils_1 = require("../utils/ast-utils");
4
5
  exports.default = (0, utils_1.createRule)('no-immutable-reactive-statements', {
5
6
  meta: {
6
7
  docs: {
@@ -77,29 +78,43 @@ exports.default = (0, utils_1.createRule)('no-immutable-reactive-statements', {
77
78
  reference.identifier.range[1] <= defId.range[1])) {
78
79
  return true;
79
80
  }
80
- if (isMutableMember(reference.identifier)) {
81
+ if (hasWriteMember(reference.identifier)) {
81
82
  return true;
82
83
  }
83
84
  }
84
85
  return false;
85
- function isMutableMember(expr) {
86
- if (expr.type === 'JSXIdentifier')
87
- return false;
88
- const parent = expr.parent;
89
- if (parent.type === 'AssignmentExpression') {
90
- return parent.left === expr;
91
- }
92
- if (parent.type === 'UpdateExpression') {
93
- return parent.argument === expr;
94
- }
95
- if (parent.type === 'UnaryExpression') {
96
- return parent.operator === 'delete' && parent.argument === expr;
97
- }
98
- if (parent.type === 'MemberExpression') {
99
- return parent.object === expr && isMutableMember(parent);
100
- }
86
+ }
87
+ function hasWriteMember(expr) {
88
+ if (expr.type === 'JSXIdentifier')
101
89
  return false;
90
+ const parent = expr.parent;
91
+ if (parent.type === 'AssignmentExpression') {
92
+ return parent.left === expr;
93
+ }
94
+ if (parent.type === 'UpdateExpression') {
95
+ return parent.argument === expr;
96
+ }
97
+ if (parent.type === 'UnaryExpression') {
98
+ return parent.operator === 'delete' && parent.argument === expr;
102
99
  }
100
+ if (parent.type === 'MemberExpression') {
101
+ return parent.object === expr && hasWriteMember(parent);
102
+ }
103
+ if (parent.type === 'SvelteDirective') {
104
+ return parent.kind === 'Binding' && parent.expression === expr;
105
+ }
106
+ if (parent.type === 'SvelteEachBlock') {
107
+ return parent.expression === expr && hasWriteReference(parent.context);
108
+ }
109
+ return false;
110
+ }
111
+ function hasWriteReference(pattern) {
112
+ for (const id of (0, ast_utils_1.iterateIdentifiers)(pattern)) {
113
+ const variable = (0, ast_utils_1.findVariable)(context, id);
114
+ if (variable && hasWrite(variable))
115
+ return true;
116
+ }
117
+ return false;
103
118
  }
104
119
  function* iterateRangeReferences(scope, range) {
105
120
  for (const variable of scope.variables) {
@@ -30,6 +30,7 @@ export declare function findBindDirective<N extends string>(node: SvAST.SvelteEl
30
30
  export declare function getStaticAttributeValue(node: SvAST.SvelteAttribute): string | null;
31
31
  export declare function getLangValue(node: SvAST.SvelteScriptElement | SvAST.SvelteStyleElement): string | null;
32
32
  export declare function findVariable(context: RuleContext, node: TSESTree.Identifier): Variable | null;
33
+ export declare function iterateIdentifiers(node: TSESTree.DestructuringPattern): Iterable<TSESTree.Identifier>;
33
34
  export declare function getScope(context: RuleContext, currentNode: TSESTree.Node): Scope;
34
35
  export declare function getParent(node: TSESTree.Node): TSESTree.Node | null;
35
36
  export type QuoteAndRange = {
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.isExpressionIdentifier = exports.isVoidHtmlElement = exports.getNodeName = exports.getDirectiveName = exports.getAttributeKeyText = exports.getMustacheTokens = exports.getAttributeValueQuoteAndRange = exports.getParent = 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.isExpressionIdentifier = exports.isVoidHtmlElement = exports.getNodeName = exports.getDirectiveName = exports.getAttributeKeyText = exports.getMustacheTokens = exports.getAttributeValueQuoteAndRange = exports.getParent = exports.getScope = exports.iterateIdentifiers = exports.findVariable = exports.getLangValue = exports.getStaticAttributeValue = exports.findBindDirective = exports.findShorthandAttribute = exports.findAttribute = exports.isHTMLElementLike = exports.needParentheses = exports.getStringIfConstant = exports.equalTokens = void 0;
30
30
  const eslintUtils = __importStar(require("@eslint-community/eslint-utils"));
31
31
  const void_elements_1 = __importDefault(require("./void-elements"));
32
32
  function equalTokens(left, right, sourceCode) {
@@ -178,6 +178,41 @@ function findVariable(context, node) {
178
178
  return eslintUtils.findVariable(initialScope, node.name.slice(1));
179
179
  }
180
180
  exports.findVariable = findVariable;
181
+ function* iterateIdentifiers(node) {
182
+ const buffer = [node];
183
+ let pattern;
184
+ while ((pattern = buffer.shift())) {
185
+ if (pattern.type === 'Identifier') {
186
+ yield pattern;
187
+ }
188
+ else if (pattern.type === 'ArrayPattern') {
189
+ for (const element of pattern.elements) {
190
+ if (element) {
191
+ buffer.push(element);
192
+ }
193
+ }
194
+ }
195
+ else if (pattern.type === 'ObjectPattern') {
196
+ for (const property of pattern.properties) {
197
+ if (property.type === 'Property') {
198
+ buffer.push(property.value);
199
+ }
200
+ else if (property.type === 'RestElement') {
201
+ buffer.push(property);
202
+ }
203
+ }
204
+ }
205
+ else if (pattern.type === 'AssignmentPattern') {
206
+ buffer.push(pattern.left);
207
+ }
208
+ else if (pattern.type === 'RestElement') {
209
+ buffer.push(pattern.argument);
210
+ }
211
+ else if (pattern.type === 'MemberExpression') {
212
+ }
213
+ }
214
+ }
215
+ exports.iterateIdentifiers = iterateIdentifiers;
181
216
  function getScope(context, currentNode) {
182
217
  const scopeManager = context.getSourceCode().scopeManager;
183
218
  let node = currentNode;
@@ -29,6 +29,7 @@ const no_dupe_use_directives_1 = __importDefault(require("../rules/no-dupe-use-d
29
29
  const no_dynamic_slot_name_1 = __importDefault(require("../rules/no-dynamic-slot-name"));
30
30
  const no_export_load_in_svelte_module_in_kit_pages_1 = __importDefault(require("../rules/no-export-load-in-svelte-module-in-kit-pages"));
31
31
  const no_extra_reactive_curlies_1 = __importDefault(require("../rules/no-extra-reactive-curlies"));
32
+ const no_ignored_unsubscribe_1 = __importDefault(require("../rules/no-ignored-unsubscribe"));
32
33
  const no_immutable_reactive_statements_1 = __importDefault(require("../rules/no-immutable-reactive-statements"));
33
34
  const no_inner_declarations_1 = __importDefault(require("../rules/no-inner-declarations"));
34
35
  const no_not_function_handler_1 = __importDefault(require("../rules/no-not-function-handler"));
@@ -89,6 +90,7 @@ exports.rules = [
89
90
  no_dynamic_slot_name_1.default,
90
91
  no_export_load_in_svelte_module_in_kit_pages_1.default,
91
92
  no_extra_reactive_curlies_1.default,
93
+ no_ignored_unsubscribe_1.default,
92
94
  no_immutable_reactive_statements_1.default,
93
95
  no_inner_declarations_1.default,
94
96
  no_not_function_handler_1.default,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-svelte",
3
- "version": "2.33.1",
3
+ "version": "2.34.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",