@blumintinc/eslint-plugin-blumint 1.18.4 → 1.18.5

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
@@ -218,7 +218,7 @@ function noFrontendImportsFromFunctionsPatterns(pattern) {
218
218
  module.exports = {
219
219
  meta: {
220
220
  name: '@blumintinc/eslint-plugin-blumint',
221
- version: '1.18.4',
221
+ version: '1.18.5',
222
222
  },
223
223
  parseOptions: {
224
224
  ecmaVersion: 2020,
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.enforcePropsArgumentName = void 0;
4
4
  const utils_1 = require("@typescript-eslint/utils");
5
5
  const createRule_1 = require("../utils/createRule");
6
+ const ASTHelpers_1 = require("../utils/ASTHelpers");
6
7
  exports.enforcePropsArgumentName = (0, createRule_1.createRule)({
7
8
  name: 'enforce-props-argument-name',
8
9
  meta: {
@@ -195,15 +196,89 @@ exports.enforcePropsArgumentName = (0, createRule_1.createRule)({
195
196
  }
196
197
  });
197
198
  }
199
+ // Determine whether renaming a constructor parameter property is unsafe to
200
+ // autofix. A parameter property (`private readonly foo: T`) creates BOTH a
201
+ // constructor-local binding and a `this.foo` class field, so a
202
+ // declaration-only rename would leave dangling references: plain `foo`
203
+ // usages inside the constructor (e.g. `super(foo)`) and `this.foo` accesses
204
+ // anywhere in the class. Mirrors #1123 — when a rename cannot be applied
205
+ // everywhere syntactically, emit no fix rather than corrupt the code.
206
+ function parameterPropertyRenameIsUnsafe(classNode, name, declarationId) {
207
+ let unsafe = false;
208
+ const visit = (node) => {
209
+ if (unsafe) {
210
+ return;
211
+ }
212
+ if (node.type === utils_1.AST_NODE_TYPES.MemberExpression &&
213
+ node.object.type === utils_1.AST_NODE_TYPES.ThisExpression &&
214
+ node.property.type === utils_1.AST_NODE_TYPES.Identifier &&
215
+ node.property.name === name) {
216
+ unsafe = true;
217
+ return;
218
+ }
219
+ if (node.type === utils_1.AST_NODE_TYPES.Identifier &&
220
+ node.name === name &&
221
+ node !== declarationId) {
222
+ unsafe = true;
223
+ return;
224
+ }
225
+ for (const key of Object.keys(node)) {
226
+ if (key === 'parent') {
227
+ continue;
228
+ }
229
+ const value = node[key];
230
+ if (Array.isArray(value)) {
231
+ for (const child of value) {
232
+ if (ASTHelpers_1.ASTHelpers.isNode(child)) {
233
+ visit(child);
234
+ }
235
+ }
236
+ }
237
+ else if (ASTHelpers_1.ASTHelpers.isNode(value)) {
238
+ visit(value);
239
+ }
240
+ }
241
+ };
242
+ visit(classNode);
243
+ return unsafe;
244
+ }
245
+ // Find the class (declaration or expression) that owns a method definition.
246
+ function getEnclosingClass(node) {
247
+ const classBody = node.parent;
248
+ if (classBody && classBody.type === utils_1.AST_NODE_TYPES.ClassBody) {
249
+ const classNode = classBody.parent;
250
+ if (classNode &&
251
+ (classNode.type === utils_1.AST_NODE_TYPES.ClassDeclaration ||
252
+ classNode.type === utils_1.AST_NODE_TYPES.ClassExpression)) {
253
+ return classNode;
254
+ }
255
+ }
256
+ return null;
257
+ }
198
258
  // Check class method parameters (including constructors)
199
259
  function checkClassMethod(node) {
200
260
  const method = node.value;
201
261
  const sourceCode = context.sourceCode;
202
262
  const propsParams = getPropsParams(method.params);
263
+ // When the enclosing class extends a base class, a constructor parameter
264
+ // property (e.g. `private readonly fullProps: SubProps`) cannot be safely
265
+ // renamed to `props`: the base class may already declare a private `props`
266
+ // field/parameter-property, so the rename would create a TS2415 private-
267
+ // field collision, and it would also leave `super(fullProps)` / `this.
268
+ // fullProps` references dangling. The rule is purely syntactic and cannot
269
+ // inspect the base class, so it defers to TypeScript correctness here and
270
+ // does not report on parameter properties in subclasses (this repo prefers
271
+ // false negatives over false positives).
272
+ const enclosingClass = getEnclosingClass(node);
273
+ const classExtendsBase = !!enclosingClass?.superClass;
203
274
  method.params.forEach((param) => {
204
275
  if (isDestructuredParameter(param)) {
205
276
  return;
206
277
  }
278
+ if (classExtendsBase &&
279
+ param.type === utils_1.AST_NODE_TYPES.TSParameterProperty) {
280
+ return;
281
+ }
207
282
  const id = getIdFromParam(param);
208
283
  if (id && id.typeAnnotation && id.typeAnnotation.typeAnnotation) {
209
284
  const typeName = getTypeName(id.typeAnnotation.typeAnnotation);
@@ -221,6 +296,15 @@ exports.enforcePropsArgumentName = (0, createRule_1.createRule)({
221
296
  suggestedName,
222
297
  },
223
298
  fix: (fixer) => {
299
+ // A parameter-property rename touches both the parameter and
300
+ // the `this.<name>` field; refuse to autofix when the name is
301
+ // referenced elsewhere, since a declaration-only rename would
302
+ // leave dangling references.
303
+ if (param.type === utils_1.AST_NODE_TYPES.TSParameterProperty &&
304
+ enclosingClass &&
305
+ parameterPropertyRenameIsUnsafe(enclosingClass, id.name, id)) {
306
+ return null;
307
+ }
224
308
  const token = sourceCode.getFirstToken(id);
225
309
  if (!token)
226
310
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blumintinc/eslint-plugin-blumint",
3
- "version": "1.18.4",
3
+ "version": "1.18.5",
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.18.5",
4
+ "date": "2026-07-09T03:26:45.486Z",
5
+ "rules": [
6
+ {
7
+ "name": "enforce-props-argument-name",
8
+ "changeType": "fix",
9
+ "issues": [
10
+ 1276
11
+ ],
12
+ "summary": "exempt subclass parameter properties to avoid TS2415/TS2304 (closes #1276)"
13
+ }
14
+ ]
15
+ },
2
16
  {
3
17
  "version": "1.18.4",
4
18
  "date": "2026-07-08T07:14:09.487Z",