@cspell/eslint-plugin 5.19.0 → 5.19.1

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
@@ -21,30 +21,36 @@ This plugin is still in active development. Due to the nature of how files are p
21
21
 
22
22
  ## Options
23
23
 
24
- ```ts
24
+ ````ts
25
25
  interface Options {
26
26
  /**
27
27
  * Number of spelling suggestions to make.
28
28
  * @default 8
29
29
  */
30
30
  numSuggestions: number;
31
-
32
31
  /**
33
32
  * Generate suggestions
34
33
  * @default true
35
34
  */
36
35
  generateSuggestions: boolean;
37
-
38
- /**
39
- * Output debug logs
40
- * @default false
41
- */
42
- debugMode?: boolean;
43
36
  /**
44
37
  * Ignore import and require names
45
38
  * @default true
46
39
  */
47
40
  ignoreImports?: boolean;
41
+ /**
42
+ * Ignore the properties of imported variables, structures, and types.
43
+ *
44
+ * Example:
45
+ * ```
46
+ * import { example } from 'third-party';
47
+ *
48
+ * const msg = example.property; // `property` is not spell checked.
49
+ * ```
50
+ *
51
+ * @default true
52
+ */
53
+ ignoreImportProperties?: boolean;
48
54
  /**
49
55
  * Spell check identifiers (variables names, function names, and class names)
50
56
  * @default true
@@ -65,8 +71,13 @@ interface Options {
65
71
  * @default true
66
72
  */
67
73
  checkComments?: boolean;
74
+ /**
75
+ * Output debug logs
76
+ * @default false
77
+ */
78
+ debugMode?: boolean;
68
79
  }
69
- ```
80
+ ````
70
81
 
71
82
  Example:
72
83
 
package/dist/index.d.ts CHANGED
@@ -45,7 +45,20 @@ interface Check {
45
45
  */
46
46
  ignoreImports?: boolean;
47
47
  /**
48
- * Spell check identifiers (variables names, function names, and class names)
48
+ * Ignore the properties of imported variables, structures, and types.
49
+ *
50
+ * Example:
51
+ * ```
52
+ * import { example } from 'third-party';
53
+ *
54
+ * const msg = example.property; // `property` is not spell checked.
55
+ * ```
56
+ *
57
+ * @default true
58
+ */
59
+ ignoreImportProperties?: boolean;
60
+ /**
61
+ * Spell check identifiers (variables names, function names, class names, etc.)
49
62
  * @default true
50
63
  */
51
64
  checkIdentifiers?: boolean;
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @cspell/eslint-plugin v5.18.5
2
+ * @cspell/eslint-plugin v5.19.0
3
3
  * Copyright 2022 Jason Dent <jason@streetsidesoftware.nl>
4
4
  * Released under the MIT License
5
5
  * https://github.com/streetsidesoftware/cspell/tree/main/packages/cspell-eslint-plugin#readme
@@ -23,6 +23,7 @@ const defaultCheckOptions = {
23
23
  checkStrings: true,
24
24
  checkStringTemplates: true,
25
25
  ignoreImports: true,
26
+ ignoreImportProperties: true,
26
27
  };
27
28
  const defaultOptions = {
28
29
  ...defaultCheckOptions,
@@ -47,7 +48,7 @@ var properties = {
47
48
  },
48
49
  checkIdentifiers: {
49
50
  "default": true,
50
- description: "Spell check identifiers (variables names, function names, and class names)",
51
+ description: "Spell check identifiers (variables names, function names, class names, etc.)",
51
52
  type: "boolean"
52
53
  },
53
54
  checkStringTemplates: {
@@ -70,6 +71,11 @@ var properties = {
70
71
  description: "Generate suggestions",
71
72
  type: "boolean"
72
73
  },
74
+ ignoreImportProperties: {
75
+ "default": true,
76
+ description: "Ignore the properties of imported variables, structures, and types.\n\nExample: ``` import { example } from 'third-party';\n\nconst msg = example.property; // `property` is not spell checked. ```",
77
+ type: "boolean"
78
+ },
73
79
  ignoreImports: {
74
80
  "default": true,
75
81
  description: "Ignore import and require names",
@@ -129,6 +135,7 @@ function log(...args) {
129
135
  }
130
136
  function create(context) {
131
137
  const options = normalizeOptions(context.options[0]);
138
+ const toIgnore = new Set();
132
139
  const importedIdentifiers = new Set();
133
140
  isDebugMode = options.debugMode || false;
134
141
  isDebugMode && logContext(context);
@@ -139,9 +146,11 @@ function create(context) {
139
146
  if (!options.checkStrings)
140
147
  return;
141
148
  if (typeof node.value === 'string') {
149
+ debugNode(node, node.value);
142
150
  if (options.ignoreImports && isImportOrRequired(node))
143
151
  return;
144
- debugNode(node, node.value);
152
+ if (options.ignoreImportProperties && isImportedProperty(node))
153
+ return;
145
154
  checkNodeText(node, node.value);
146
155
  }
147
156
  }
@@ -153,15 +162,29 @@ function create(context) {
153
162
  checkNodeText(node, node.value.cooked || node.value.raw);
154
163
  }
155
164
  function checkIdentifier(node) {
156
- if (options.ignoreImports && isImportIdentifier(node)) {
157
- importedIdentifiers.add(node.name);
158
- return;
165
+ debugNode(node, node.name);
166
+ if (options.ignoreImports) {
167
+ if (isRawImportIdentifier(node)) {
168
+ toIgnore.add(node.name);
169
+ return;
170
+ }
171
+ if (isImportIdentifier(node)) {
172
+ importedIdentifiers.add(node.name);
173
+ if (isLocalImportIdentifierUnique(node)) {
174
+ checkNodeText(node, node.name);
175
+ }
176
+ return;
177
+ }
178
+ else if (options.ignoreImportProperties && isImportedProperty(node)) {
179
+ return;
180
+ }
159
181
  }
160
182
  if (!options.checkIdentifiers)
161
183
  return;
162
- if (importedIdentifiers.has(node.name))
184
+ if (toIgnore.has(node.name) && !isObjectProperty(node))
185
+ return;
186
+ if (skipCheckForRawImportIdentifiers(node))
163
187
  return;
164
- debugNode(node, node.name);
165
188
  checkNodeText(node, node.name);
166
189
  }
167
190
  function checkComment(node) {
@@ -184,12 +207,49 @@ function create(context) {
184
207
  return [];
185
208
  }
186
209
  function isImportIdentifier(node) {
210
+ const parent = node.parent;
211
+ if (node.type !== 'Identifier' || !parent)
212
+ return false;
213
+ return ((parent.type === 'ImportSpecifier' ||
214
+ parent.type === 'ImportNamespaceSpecifier' ||
215
+ parent.type === 'ImportDefaultSpecifier') &&
216
+ parent.local === node);
217
+ }
218
+ function isRawImportIdentifier(node) {
187
219
  const parent = node.parent;
188
220
  if (node.type !== 'Identifier' || !parent)
189
221
  return false;
190
222
  return ((parent.type === 'ImportSpecifier' && parent.imported === node) ||
191
223
  (parent.type === 'ExportSpecifier' && parent.local === node));
192
224
  }
225
+ function isLocalImportIdentifierUnique(node) {
226
+ var _a, _b, _c, _d;
227
+ const parent = getImportParent(node);
228
+ if (!parent)
229
+ return true;
230
+ const { imported, local } = parent;
231
+ if (imported.name !== local.name)
232
+ return true;
233
+ return ((_a = imported.range) === null || _a === void 0 ? void 0 : _a[0]) !== ((_b = local.range) === null || _b === void 0 ? void 0 : _b[0]) && ((_c = imported.range) === null || _c === void 0 ? void 0 : _c[1]) !== ((_d = local.range) === null || _d === void 0 ? void 0 : _d[1]);
234
+ }
235
+ function getImportParent(node) {
236
+ const parent = node.parent;
237
+ return (parent === null || parent === void 0 ? void 0 : parent.type) === 'ImportSpecifier' ? parent : undefined;
238
+ }
239
+ function skipCheckForRawImportIdentifiers(node) {
240
+ if (options.ignoreImports)
241
+ return false;
242
+ const parent = getImportParent(node);
243
+ return !!parent && parent.imported === node && !isLocalImportIdentifierUnique(node);
244
+ }
245
+ function isImportedProperty(node) {
246
+ const obj = findOriginObject(node);
247
+ return !!obj && obj.type === 'Identifier' && importedIdentifiers.has(obj.name);
248
+ }
249
+ function isObjectProperty(node) {
250
+ var _a;
251
+ return ((_a = node.parent) === null || _a === void 0 ? void 0 : _a.type) === 'MemberExpression';
252
+ }
193
253
  function reportIssue(issue) {
194
254
  var _a;
195
255
  const messageId = issue.isFlagged ? 'wordForbidden' : 'wordUnknown';
@@ -295,6 +355,19 @@ function create(context) {
295
355
  function inheritanceSummary(node) {
296
356
  return inheritance(node).join(' ');
297
357
  }
358
+ /**
359
+ * find the origin of a member expression
360
+ */
361
+ function findOriginObject(node) {
362
+ const parent = node.parent;
363
+ if ((parent === null || parent === void 0 ? void 0 : parent.type) !== 'MemberExpression' || parent.property !== node)
364
+ return undefined;
365
+ let obj = parent.object;
366
+ while (obj.type === 'MemberExpression') {
367
+ obj = obj.object;
368
+ }
369
+ return obj;
370
+ }
298
371
  function isFunctionCall(node, name) {
299
372
  return (node === null || node === void 0 ? void 0 : node.type) === 'CallExpression' && node.callee.type === 'Identifier' && node.callee.name === name;
300
373
  }
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @cspell/eslint-plugin v5.18.5
2
+ * @cspell/eslint-plugin v5.19.0
3
3
  * Copyright 2022 Jason Dent <jason@streetsidesoftware.nl>
4
4
  * Released under the MIT License
5
5
  * https://github.com/streetsidesoftware/cspell/tree/main/packages/cspell-eslint-plugin#readme
@@ -15,6 +15,7 @@ const defaultCheckOptions = {
15
15
  checkStrings: true,
16
16
  checkStringTemplates: true,
17
17
  ignoreImports: true,
18
+ ignoreImportProperties: true,
18
19
  };
19
20
  const defaultOptions = {
20
21
  ...defaultCheckOptions,
@@ -39,7 +40,7 @@ var properties = {
39
40
  },
40
41
  checkIdentifiers: {
41
42
  "default": true,
42
- description: "Spell check identifiers (variables names, function names, and class names)",
43
+ description: "Spell check identifiers (variables names, function names, class names, etc.)",
43
44
  type: "boolean"
44
45
  },
45
46
  checkStringTemplates: {
@@ -62,6 +63,11 @@ var properties = {
62
63
  description: "Generate suggestions",
63
64
  type: "boolean"
64
65
  },
66
+ ignoreImportProperties: {
67
+ "default": true,
68
+ description: "Ignore the properties of imported variables, structures, and types.\n\nExample: ``` import { example } from 'third-party';\n\nconst msg = example.property; // `property` is not spell checked. ```",
69
+ type: "boolean"
70
+ },
65
71
  ignoreImports: {
66
72
  "default": true,
67
73
  description: "Ignore import and require names",
@@ -121,6 +127,7 @@ function log(...args) {
121
127
  }
122
128
  function create(context) {
123
129
  const options = normalizeOptions(context.options[0]);
130
+ const toIgnore = new Set();
124
131
  const importedIdentifiers = new Set();
125
132
  isDebugMode = options.debugMode || false;
126
133
  isDebugMode && logContext(context);
@@ -131,9 +138,11 @@ function create(context) {
131
138
  if (!options.checkStrings)
132
139
  return;
133
140
  if (typeof node.value === 'string') {
141
+ debugNode(node, node.value);
134
142
  if (options.ignoreImports && isImportOrRequired(node))
135
143
  return;
136
- debugNode(node, node.value);
144
+ if (options.ignoreImportProperties && isImportedProperty(node))
145
+ return;
137
146
  checkNodeText(node, node.value);
138
147
  }
139
148
  }
@@ -145,15 +154,29 @@ function create(context) {
145
154
  checkNodeText(node, node.value.cooked || node.value.raw);
146
155
  }
147
156
  function checkIdentifier(node) {
148
- if (options.ignoreImports && isImportIdentifier(node)) {
149
- importedIdentifiers.add(node.name);
150
- return;
157
+ debugNode(node, node.name);
158
+ if (options.ignoreImports) {
159
+ if (isRawImportIdentifier(node)) {
160
+ toIgnore.add(node.name);
161
+ return;
162
+ }
163
+ if (isImportIdentifier(node)) {
164
+ importedIdentifiers.add(node.name);
165
+ if (isLocalImportIdentifierUnique(node)) {
166
+ checkNodeText(node, node.name);
167
+ }
168
+ return;
169
+ }
170
+ else if (options.ignoreImportProperties && isImportedProperty(node)) {
171
+ return;
172
+ }
151
173
  }
152
174
  if (!options.checkIdentifiers)
153
175
  return;
154
- if (importedIdentifiers.has(node.name))
176
+ if (toIgnore.has(node.name) && !isObjectProperty(node))
177
+ return;
178
+ if (skipCheckForRawImportIdentifiers(node))
155
179
  return;
156
- debugNode(node, node.name);
157
180
  checkNodeText(node, node.name);
158
181
  }
159
182
  function checkComment(node) {
@@ -176,12 +199,49 @@ function create(context) {
176
199
  return [];
177
200
  }
178
201
  function isImportIdentifier(node) {
202
+ const parent = node.parent;
203
+ if (node.type !== 'Identifier' || !parent)
204
+ return false;
205
+ return ((parent.type === 'ImportSpecifier' ||
206
+ parent.type === 'ImportNamespaceSpecifier' ||
207
+ parent.type === 'ImportDefaultSpecifier') &&
208
+ parent.local === node);
209
+ }
210
+ function isRawImportIdentifier(node) {
179
211
  const parent = node.parent;
180
212
  if (node.type !== 'Identifier' || !parent)
181
213
  return false;
182
214
  return ((parent.type === 'ImportSpecifier' && parent.imported === node) ||
183
215
  (parent.type === 'ExportSpecifier' && parent.local === node));
184
216
  }
217
+ function isLocalImportIdentifierUnique(node) {
218
+ var _a, _b, _c, _d;
219
+ const parent = getImportParent(node);
220
+ if (!parent)
221
+ return true;
222
+ const { imported, local } = parent;
223
+ if (imported.name !== local.name)
224
+ return true;
225
+ return ((_a = imported.range) === null || _a === void 0 ? void 0 : _a[0]) !== ((_b = local.range) === null || _b === void 0 ? void 0 : _b[0]) && ((_c = imported.range) === null || _c === void 0 ? void 0 : _c[1]) !== ((_d = local.range) === null || _d === void 0 ? void 0 : _d[1]);
226
+ }
227
+ function getImportParent(node) {
228
+ const parent = node.parent;
229
+ return (parent === null || parent === void 0 ? void 0 : parent.type) === 'ImportSpecifier' ? parent : undefined;
230
+ }
231
+ function skipCheckForRawImportIdentifiers(node) {
232
+ if (options.ignoreImports)
233
+ return false;
234
+ const parent = getImportParent(node);
235
+ return !!parent && parent.imported === node && !isLocalImportIdentifierUnique(node);
236
+ }
237
+ function isImportedProperty(node) {
238
+ const obj = findOriginObject(node);
239
+ return !!obj && obj.type === 'Identifier' && importedIdentifiers.has(obj.name);
240
+ }
241
+ function isObjectProperty(node) {
242
+ var _a;
243
+ return ((_a = node.parent) === null || _a === void 0 ? void 0 : _a.type) === 'MemberExpression';
244
+ }
185
245
  function reportIssue(issue) {
186
246
  var _a;
187
247
  const messageId = issue.isFlagged ? 'wordForbidden' : 'wordUnknown';
@@ -287,6 +347,19 @@ function create(context) {
287
347
  function inheritanceSummary(node) {
288
348
  return inheritance(node).join(' ');
289
349
  }
350
+ /**
351
+ * find the origin of a member expression
352
+ */
353
+ function findOriginObject(node) {
354
+ const parent = node.parent;
355
+ if ((parent === null || parent === void 0 ? void 0 : parent.type) !== 'MemberExpression' || parent.property !== node)
356
+ return undefined;
357
+ let obj = parent.object;
358
+ while (obj.type === 'MemberExpression') {
359
+ obj = obj.object;
360
+ }
361
+ return obj;
362
+ }
290
363
  function isFunctionCall(node, name) {
291
364
  return (node === null || node === void 0 ? void 0 : node.type) === 'CallExpression' && node.callee.type === 'Identifier' && node.callee.name === name;
292
365
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "5.19.0",
6
+ "version": "5.19.1",
7
7
  "description": "[WIP] CSpell ESLint plugin",
8
8
  "keywords": [
9
9
  "cspell",
@@ -72,7 +72,7 @@
72
72
  "ts-json-schema-generator": "^0.98.0"
73
73
  },
74
74
  "dependencies": {
75
- "cspell-lib": "^5.19.0"
75
+ "cspell-lib": "^5.19.1"
76
76
  },
77
- "gitHead": "7873efe40a3287d3e025f705e1712c12d3cb392e"
77
+ "gitHead": "622cd59a44bf1f76d538e3cf37983f387c5423e8"
78
78
  }