@blumintinc/eslint-plugin-blumint 1.19.6 → 1.19.7

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
@@ -222,7 +222,7 @@ function noFrontendImportsFromFunctionsPatterns(pattern) {
222
222
  module.exports = {
223
223
  meta: {
224
224
  name: '@blumintinc/eslint-plugin-blumint',
225
- version: '1.19.6',
225
+ version: '1.19.7',
226
226
  },
227
227
  parseOptions: {
228
228
  ecmaVersion: 2020,
@@ -77,6 +77,47 @@ exports.noRedundantThisParams = (0, createRule_1.createRule)({
77
77
  }
78
78
  return [];
79
79
  }
80
+ function isBindingExportedInScope(scopeBody, bindingName) {
81
+ // A class bound at module (or namespace) scope can be exported by a
82
+ // statement separate from its declaration — `export { Foo }`,
83
+ // `export { Foo as Bar }`, `export default Foo`, or `export = Foo`. Any of
84
+ // these exposes it to subclassing from another file just as an inline
85
+ // export does.
86
+ for (const statement of scopeBody) {
87
+ if (statement.type === utils_1.AST_NODE_TYPES.ExportNamedDeclaration &&
88
+ !statement.source) {
89
+ for (const specifier of statement.specifiers) {
90
+ if (specifier.local.type === utils_1.AST_NODE_TYPES.Identifier &&
91
+ specifier.local.name === bindingName) {
92
+ return true;
93
+ }
94
+ }
95
+ }
96
+ if (statement.type === utils_1.AST_NODE_TYPES.ExportDefaultDeclaration &&
97
+ statement.declaration.type === utils_1.AST_NODE_TYPES.Identifier &&
98
+ statement.declaration.name === bindingName) {
99
+ return true;
100
+ }
101
+ if (statement.type === utils_1.AST_NODE_TYPES.TSExportAssignment &&
102
+ statement.expression.type === utils_1.AST_NODE_TYPES.Identifier &&
103
+ statement.expression.name === bindingName) {
104
+ return true;
105
+ }
106
+ }
107
+ return false;
108
+ }
109
+ function getEnclosingScopeBody(node) {
110
+ if (!node) {
111
+ return null;
112
+ }
113
+ if (node.type === utils_1.AST_NODE_TYPES.Program) {
114
+ return node.body;
115
+ }
116
+ if (node.type === utils_1.AST_NODE_TYPES.TSModuleBlock) {
117
+ return node.body;
118
+ }
119
+ return null;
120
+ }
80
121
  function isExportedClass(node) {
81
122
  const parent = node.parent;
82
123
  if (!parent) {
@@ -86,14 +127,33 @@ exports.noRedundantThisParams = (0, createRule_1.createRule)({
86
127
  parent.type === utils_1.AST_NODE_TYPES.ExportDefaultDeclaration) {
87
128
  return true;
88
129
  }
89
- // `export const Foo = class { ... }` exposes the class expression to other
90
- // files just as an exported declaration does.
130
+ // A `class Foo {}` declaration exported by a later `export { Foo }` /
131
+ // `export default Foo` in the same scope is still reachable cross-file.
132
+ if (node.type === utils_1.AST_NODE_TYPES.ClassDeclaration &&
133
+ node.id &&
134
+ (parent.type === utils_1.AST_NODE_TYPES.Program ||
135
+ parent.type === utils_1.AST_NODE_TYPES.TSModuleBlock)) {
136
+ const scopeBody = getEnclosingScopeBody(parent);
137
+ if (scopeBody && isBindingExportedInScope(scopeBody, node.id.name)) {
138
+ return true;
139
+ }
140
+ }
141
+ // `export const Foo = class { ... }`, or `const Foo = class {}` exported by
142
+ // a later statement, both expose the class expression like an exported
143
+ // declaration does.
91
144
  if (node.type === utils_1.AST_NODE_TYPES.ClassExpression &&
92
- parent.type === utils_1.AST_NODE_TYPES.VariableDeclarator) {
145
+ parent.type === utils_1.AST_NODE_TYPES.VariableDeclarator &&
146
+ parent.id.type === utils_1.AST_NODE_TYPES.Identifier) {
93
147
  const declaration = parent.parent;
94
148
  const exportNode = declaration?.parent;
95
- return (exportNode?.type === utils_1.AST_NODE_TYPES.ExportNamedDeclaration ||
96
- exportNode?.type === utils_1.AST_NODE_TYPES.ExportDefaultDeclaration);
149
+ if (exportNode?.type === utils_1.AST_NODE_TYPES.ExportNamedDeclaration ||
150
+ exportNode?.type === utils_1.AST_NODE_TYPES.ExportDefaultDeclaration) {
151
+ return true;
152
+ }
153
+ const scopeBody = getEnclosingScopeBody(exportNode);
154
+ if (scopeBody && isBindingExportedInScope(scopeBody, parent.id.name)) {
155
+ return true;
156
+ }
97
157
  }
98
158
  return false;
99
159
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blumintinc/eslint-plugin-blumint",
3
- "version": "1.19.6",
3
+ "version": "1.19.7",
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.19.7",
4
+ "date": "2026-07-16T01:36:53.555Z",
5
+ "rules": [
6
+ {
7
+ "name": "no-redundant-this-params",
8
+ "changeType": "fix",
9
+ "issues": [
10
+ 1309
11
+ ],
12
+ "summary": "treat trailing-export classes as reachable"
13
+ }
14
+ ]
15
+ },
2
16
  {
3
17
  "version": "1.19.6",
4
18
  "date": "2026-07-16T01:27:07.130Z",