@blumintinc/eslint-plugin-blumint 1.20.114 → 1.20.115

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/index.js CHANGED
@@ -223,7 +223,7 @@ function noFrontendImportsFromFunctionsPatterns(pattern) {
223
223
  module.exports = {
224
224
  meta: {
225
225
  name: '@blumintinc/eslint-plugin-blumint',
226
- version: '1.20.114',
226
+ version: '1.20.115',
227
227
  },
228
228
  parseOptions: {
229
229
  ecmaVersion: 2020,
@@ -13,20 +13,47 @@ const isJsxElement = (node) => {
13
13
  node.type === utils_1.AST_NODE_TYPES.JSXFragment ||
14
14
  node.type === utils_1.AST_NODE_TYPES.JSXExpressionContainer);
15
15
  };
16
+ /**
17
+ * A type reference's name as dotted segments.
18
+ *
19
+ * A qualified name nests to the LEFT, so `React.JSX.Element` is a
20
+ * TSQualifiedName whose own `left` is another TSQualifiedName. Matching one
21
+ * nesting level at a time therefore recognizes `JSX.Element` but not the
22
+ * React-namespaced spelling of the same type; comparing whole paths recognizes
23
+ * both.
24
+ */
25
+ const qualifiedSegments = (typeName) => {
26
+ if (typeName.type === utils_1.AST_NODE_TYPES.Identifier) {
27
+ return [typeName.name];
28
+ }
29
+ if (typeName.type === utils_1.AST_NODE_TYPES.TSQualifiedName) {
30
+ const left = qualifiedSegments(typeName.left);
31
+ return left && [...left, typeName.right.name];
32
+ }
33
+ return null;
34
+ };
35
+ /** JSX-producing type paths, written without the optional `React` qualifier. */
36
+ const JSX_TYPE_PATHS = new Set([
37
+ 'JSX',
38
+ 'JSX.Element',
39
+ 'ReactNode',
40
+ 'ReactElement',
41
+ ]);
16
42
  const isJsxReturnType = (node) => {
17
- if (node.typeAnnotation.type === utils_1.AST_NODE_TYPES.TSTypeReference) {
18
- const typeName = node.typeAnnotation.typeName;
19
- if (typeName.type === utils_1.AST_NODE_TYPES.Identifier) {
20
- return ['JSX', 'ReactNode', 'ReactElement'].includes(typeName.name);
21
- }
22
- if (typeName.type === utils_1.AST_NODE_TYPES.TSQualifiedName) {
23
- return (typeName.left.type === utils_1.AST_NODE_TYPES.Identifier &&
24
- typeName.left.name === 'JSX' &&
25
- typeName.right.type === utils_1.AST_NODE_TYPES.Identifier &&
26
- typeName.right.name === 'Element');
27
- }
43
+ if (node.typeAnnotation.type !== utils_1.AST_NODE_TYPES.TSTypeReference) {
44
+ return false;
28
45
  }
29
- return false;
46
+ const segments = qualifiedSegments(node.typeAnnotation.typeName);
47
+ if (!segments) {
48
+ return false;
49
+ }
50
+ /**
51
+ * `React.` re-exports the same declarations, so it carries no meaning for
52
+ * this question. Every other qualifier names a type from a different module
53
+ * and must not match — `Foo.ReactNode` is not React's.
54
+ */
55
+ const path = segments[0] === 'React' ? segments.slice(1) : segments;
56
+ return path.length > 0 && JSX_TYPE_PATHS.has(path.join('.'));
30
57
  };
31
58
  const containsJsxInBlockStatement = (node) => {
32
59
  const variablesWithJsx = new Set();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blumintinc/eslint-plugin-blumint",
3
- "version": "1.20.114",
3
+ "version": "1.20.115",
4
4
  "description": "Custom eslint rules for use within BluMint",
5
5
  "author": {
6
6
  "name": "Brodie McGuire",
@@ -1,4 +1,18 @@
1
1
  [
2
+ {
3
+ "version": "1.20.115",
4
+ "date": "2026-08-05T18:41:41.153Z",
5
+ "rules": [
6
+ {
7
+ "name": "no-jsx-in-hooks",
8
+ "changeType": "fix",
9
+ "issues": [
10
+ 1753
11
+ ],
12
+ "summary": "detect React-qualified JSX return types (closes #1753)"
13
+ }
14
+ ]
15
+ },
2
16
  {
3
17
  "version": "1.20.114",
4
18
  "date": "2026-08-05T18:16:40.596Z",