eslint-plugin-svelte 3.8.0 → 3.8.2

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/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.8.0";
17
+ version: "3.8.2";
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.8.0";
2
+ export declare const version: "3.8.2";
package/lib/meta.js CHANGED
@@ -2,4 +2,4 @@
2
2
  // This file has been automatically generated,
3
3
  // in order to update its content execute "pnpm run update"
4
4
  export const name = 'eslint-plugin-svelte';
5
- export const version = '3.8.0';
5
+ export const version = '3.8.2';
@@ -1,6 +1,7 @@
1
1
  import { findClassesInAttribute } from '../utils/ast-utils.js';
2
2
  import { extractExpressionPrefixLiteral, extractExpressionSuffixLiteral } from '../utils/expression-affixes.js';
3
3
  import { createRule } from '../utils/index.js';
4
+ import { ElementOccurenceCount, elementOccurrenceCount } from '../utils/element-occurences.js';
4
5
  export default createRule('consistent-selector-style', {
5
6
  meta: {
6
7
  docs: {
@@ -108,7 +109,7 @@ export default createRule('consistent-selector-style', {
108
109
  if (styleValue === 'class') {
109
110
  return;
110
111
  }
111
- if (styleValue === 'id' && canUseIdSelector(selection)) {
112
+ if (styleValue === 'id' && canUseIdSelector(selection.map(([elem]) => elem))) {
112
113
  context.report({
113
114
  messageId: 'classShouldBeId',
114
115
  loc: styleSelectorNodeLoc(node)
@@ -243,10 +244,10 @@ function addToArrayMap(map, key, value) {
243
244
  * Finds all nodes in selections that could be matched by key
244
245
  */
245
246
  function matchSelection(selections, key) {
246
- const selection = selections.exact.get(key) ?? [];
247
+ const selection = (selections.exact.get(key) ?? []).map((elem) => [elem, true]);
247
248
  selections.affixes.forEach((nodes, [prefix, suffix]) => {
248
249
  if ((prefix === null || key.startsWith(prefix)) && (suffix === null || key.endsWith(suffix))) {
249
- selection.push(...nodes);
250
+ selection.push(...nodes.map((elem) => [elem, false]));
250
251
  }
251
252
  });
252
253
  return selection;
@@ -255,22 +256,28 @@ function matchSelection(selections, key) {
255
256
  * Checks whether a given selection could be obtained using an ID selector
256
257
  */
257
258
  function canUseIdSelector(selection) {
258
- return selection.length <= 1;
259
+ return (selection.length === 0 ||
260
+ (selection.length === 1 &&
261
+ elementOccurrenceCount(selection[0]) !== ElementOccurenceCount.ZeroToInf));
259
262
  }
260
263
  /**
261
264
  * Checks whether a given selection could be obtained using a type selector
262
265
  */
263
266
  function canUseTypeSelector(selection, typeSelections) {
264
- const types = new Set(selection.map((node) => node.name.name));
267
+ const types = new Set(selection.map(([node]) => node.name.name));
265
268
  if (types.size > 1) {
266
269
  return false;
267
270
  }
268
271
  if (types.size < 1) {
269
272
  return true;
270
273
  }
274
+ if (selection.some(([elem, exact]) => !exact && elementOccurrenceCount(elem) === ElementOccurenceCount.ZeroToInf)) {
275
+ return false;
276
+ }
271
277
  const type = [...types][0];
272
278
  const typeSelection = typeSelections.get(type);
273
- return typeSelection !== undefined && arrayEquals(typeSelection, selection);
279
+ return (typeSelection !== undefined &&
280
+ arrayEquals(typeSelection, selection.map(([elem]) => elem)));
274
281
  }
275
282
  /**
276
283
  * Compares two arrays for item equality
@@ -25,11 +25,17 @@ export default createRule('no-top-level-browser-globals', {
25
25
  });
26
26
  const maybeGuards = [];
27
27
  const functions = [];
28
+ const typeAnnotations = [];
28
29
  function enterFunction(node) {
29
30
  if (isTopLevelLocation(node)) {
30
31
  functions.push(node);
31
32
  }
32
33
  }
34
+ function enterTypeAnnotation(node) {
35
+ if (!isInTypeAnnotation(node)) {
36
+ typeAnnotations.push(node);
37
+ }
38
+ }
33
39
  function enterMetaProperty(node) {
34
40
  if (node.meta.name !== 'import' || node.property.name !== 'meta')
35
41
  return;
@@ -69,7 +75,7 @@ export default createRule('no-top-level-browser-globals', {
69
75
  const reportCandidates = [];
70
76
  // Collects references to global variables.
71
77
  for (const ref of iterateBrowserGlobalReferences()) {
72
- if (!isTopLevelLocation(ref.node))
78
+ if (!isTopLevelLocation(ref.node) || isInTypeAnnotation(ref.node))
73
79
  continue;
74
80
  const guardChecker = getGuardCheckerFromReference(ref.node);
75
81
  if (guardChecker) {
@@ -98,6 +104,7 @@ export default createRule('no-top-level-browser-globals', {
98
104
  }
99
105
  return {
100
106
  ':function': enterFunction,
107
+ '*.typeAnnotation': enterTypeAnnotation,
101
108
  MetaProperty: enterMetaProperty,
102
109
  'Program:exit': verifyGlobalReferences
103
110
  };
@@ -127,6 +134,18 @@ export default createRule('no-top-level-browser-globals', {
127
134
  }
128
135
  return true;
129
136
  }
137
+ /**
138
+ * Checks whether the node is in type annotation.
139
+ * @returns `true` if the node is in type annotation.
140
+ */
141
+ function isInTypeAnnotation(node) {
142
+ for (const typeAnnotation of typeAnnotations) {
143
+ if (typeAnnotation.range[0] <= node.range[0] && node.range[1] <= typeAnnotation.range[1]) {
144
+ return true;
145
+ }
146
+ }
147
+ return false;
148
+ }
130
149
  /**
131
150
  * Iterate over the references of modules that can check the browser environment.
132
151
  */
@@ -0,0 +1,7 @@
1
+ import type { AST } from 'svelte-eslint-parser';
2
+ export declare enum ElementOccurenceCount {
3
+ ZeroOrOne = 0,
4
+ One = 1,
5
+ ZeroToInf = 2
6
+ }
7
+ export declare function elementOccurrenceCount(element: AST.SvelteHTMLNode): ElementOccurenceCount;
@@ -0,0 +1,43 @@
1
+ export var ElementOccurenceCount;
2
+ (function (ElementOccurenceCount) {
3
+ ElementOccurenceCount[ElementOccurenceCount["ZeroOrOne"] = 0] = "ZeroOrOne";
4
+ ElementOccurenceCount[ElementOccurenceCount["One"] = 1] = "One";
5
+ ElementOccurenceCount[ElementOccurenceCount["ZeroToInf"] = 2] = "ZeroToInf";
6
+ })(ElementOccurenceCount || (ElementOccurenceCount = {}));
7
+ function multiplyCounts(left, right) {
8
+ if (left === ElementOccurenceCount.One) {
9
+ return right;
10
+ }
11
+ if (right === ElementOccurenceCount.One) {
12
+ return left;
13
+ }
14
+ if (left === right) {
15
+ return left;
16
+ }
17
+ return ElementOccurenceCount.ZeroToInf;
18
+ }
19
+ function childElementOccurenceCount(parent) {
20
+ if (parent === null) {
21
+ return ElementOccurenceCount.One;
22
+ }
23
+ if ([
24
+ 'SvelteIfBlock',
25
+ 'SvelteElseBlock',
26
+ 'SvelteAwaitBlock',
27
+ 'SvelteAwaitPendingBlock',
28
+ 'SvelteAwaitThenBlock',
29
+ 'SvelteAwaitCatchBlock'
30
+ ].includes(parent.type)) {
31
+ return ElementOccurenceCount.ZeroOrOne;
32
+ }
33
+ if (['SvelteEachBlock', 'SvelteSnippetBlock'].includes(parent.type) ||
34
+ (parent.type === 'SvelteElement' && parent.kind === 'component')) {
35
+ return ElementOccurenceCount.ZeroToInf;
36
+ }
37
+ return ElementOccurenceCount.One;
38
+ }
39
+ export function elementOccurrenceCount(element) {
40
+ const parentCount = element.parent !== null ? elementOccurrenceCount(element.parent) : ElementOccurenceCount.One;
41
+ const parentChildCount = childElementOccurenceCount(element.parent);
42
+ return multiplyCounts(parentCount, parentChildCount);
43
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-svelte",
3
- "version": "3.8.0",
3
+ "version": "3.8.2",
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",