@blumintinc/eslint-plugin-blumint 1.20.53 → 1.20.55

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.53',
226
+ version: '1.20.55',
227
227
  },
228
228
  parseOptions: {
229
229
  ecmaVersion: 2020,
@@ -1219,40 +1219,12 @@ exports.enforceBooleanNamingPrefixes = (0, createRule_1.createRule)({
1219
1219
  }
1220
1220
  }
1221
1221
  /**
1222
- * Check class property definitions for boolean values
1223
- */
1224
- function checkClassProperty(node) {
1225
- if (node.key.type !== utils_1.AST_NODE_TYPES.Identifier)
1226
- return;
1227
- const propertyName = node.key.name;
1228
- // Check if it's a boolean property
1229
- let isBooleanProperty = false;
1230
- // Check if it has a boolean type annotation
1231
- if (node.typeAnnotation?.typeAnnotation &&
1232
- node.typeAnnotation.typeAnnotation.type ===
1233
- utils_1.AST_NODE_TYPES.TSBooleanKeyword) {
1234
- isBooleanProperty = true;
1235
- }
1236
- // Check if it's initialized with a boolean value
1237
- if (node.value?.type === utils_1.AST_NODE_TYPES.Literal &&
1238
- typeof node.value.value === 'boolean') {
1239
- isBooleanProperty = true;
1240
- }
1241
- if (isBooleanProperty && !hasApprovedPrefix(propertyName)) {
1242
- context.report({
1243
- node: node.key,
1244
- messageId: 'missingBooleanPrefix',
1245
- data: {
1246
- type: 'property',
1247
- name: propertyName,
1248
- capitalizedName: capitalizeFirst(propertyName),
1249
- prefixes: formatPrefixes(),
1250
- },
1251
- });
1252
- }
1253
- }
1254
- /**
1255
- * Check class property declarations for boolean values
1222
+ * Check class property declarations for boolean values.
1223
+ *
1224
+ * Handles both concrete (`PropertyDefinition`) and abstract
1225
+ * (`TSAbstractPropertyDefinition`) fields: an abstract field is a
1226
+ * declaration the author owns and every implementer inherits the name from,
1227
+ * so it carries the same naming obligation as a concrete one.
1256
1228
  */
1257
1229
  function checkClassPropertyDeclaration(node) {
1258
1230
  if (node.key.type !== utils_1.AST_NODE_TYPES.Identifier)
@@ -1383,6 +1355,43 @@ exports.enforceBooleanNamingPrefixes = (0, createRule_1.createRule)({
1383
1355
  }
1384
1356
  }
1385
1357
  }
1358
+ /**
1359
+ * Check constructor parameter properties (`constructor(private enabled: boolean) {}`)
1360
+ * for boolean values.
1361
+ *
1362
+ * An access modifier turns a constructor parameter into a declared class
1363
+ * field, so it is reported as a `property` rather than a `parameter`. The
1364
+ * generic parameter visitor never sees these names — `TSParameterProperty`
1365
+ * wraps the identifier — so this is the single report site for them.
1366
+ */
1367
+ function checkParameterProperty(node) {
1368
+ // A default value wraps the identifier again: `private enabled = true`
1369
+ // parses as an AssignmentPattern whose left holds the name and annotation.
1370
+ const { parameter } = node;
1371
+ const isDefaulted = parameter.type === utils_1.AST_NODE_TYPES.AssignmentPattern;
1372
+ const target = isDefaulted ? parameter.left : parameter;
1373
+ if (target.type !== utils_1.AST_NODE_TYPES.Identifier)
1374
+ return;
1375
+ const propertyName = target.name;
1376
+ const hasBooleanAnnotation = target.typeAnnotation?.typeAnnotation.type ===
1377
+ utils_1.AST_NODE_TYPES.TSBooleanKeyword;
1378
+ const initializer = isDefaulted ? parameter.right : undefined;
1379
+ const hasBooleanInitializer = initializer?.type === utils_1.AST_NODE_TYPES.Literal &&
1380
+ typeof initializer.value === 'boolean';
1381
+ if ((hasBooleanAnnotation || hasBooleanInitializer) &&
1382
+ !hasApprovedPrefix(propertyName)) {
1383
+ context.report({
1384
+ node: target,
1385
+ messageId: 'missingBooleanPrefix',
1386
+ data: {
1387
+ type: 'property',
1388
+ name: propertyName,
1389
+ capitalizedName: capitalizeFirst(propertyName),
1390
+ prefixes: formatPrefixes(),
1391
+ },
1392
+ });
1393
+ }
1394
+ }
1386
1395
  return {
1387
1396
  VariableDeclarator: checkVariableDeclaration,
1388
1397
  FunctionDeclaration: checkFunctionDeclaration,
@@ -1398,8 +1407,9 @@ exports.enforceBooleanNamingPrefixes = (0, createRule_1.createRule)({
1398
1407
  },
1399
1408
  MethodDefinition: checkMethodDefinition,
1400
1409
  TSAbstractMethodDefinition: checkMethodDefinition,
1401
- ClassProperty: checkClassProperty,
1402
1410
  PropertyDefinition: checkClassPropertyDeclaration,
1411
+ TSAbstractPropertyDefinition: checkClassPropertyDeclaration,
1412
+ TSParameterProperty: checkParameterProperty,
1403
1413
  TSPropertySignature: checkPropertySignature,
1404
1414
  Identifier(node) {
1405
1415
  // Check parameter names in function declarations
@@ -78,11 +78,16 @@ exports.exportIfInDoubt = (0, createRule_1.createRule)({
78
78
  !exportedIdentifiers.includes(node.id.name)) {
79
79
  const name = node.id.name;
80
80
  const kind = getDeclarationKind(node);
81
+ // The only remedy is prepending `export` to the declaration that
82
+ // is already there, so everything past the name is elided with
83
+ // `…`. A concrete-looking stand-in (`= undefined`, `() {}`,
84
+ // `= unknown`) reads as code to paste over the declaration and
85
+ // silently destroys its initializer, parameters, body, or type.
81
86
  const exportExample = node.type === 'VariableDeclarator'
82
- ? `export ${kind} ${name} = undefined;`
87
+ ? `export ${kind} ${name} = …;`
83
88
  : node.type === 'FunctionDeclaration'
84
- ? `export function ${name}() {}`
85
- : `export type ${name} = unknown;`;
89
+ ? `export function ${name}() {}`
90
+ : `export type ${name} = …;`;
86
91
  context.report({
87
92
  node,
88
93
  messageId: 'exportIfInDoubt',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blumintinc/eslint-plugin-blumint",
3
- "version": "1.20.53",
3
+ "version": "1.20.55",
4
4
  "description": "Custom eslint rules for use within BluMint",
5
5
  "author": {
6
6
  "name": "Brodie McGuire",
@@ -1,4 +1,32 @@
1
1
  [
2
+ {
3
+ "version": "1.20.55",
4
+ "date": "2026-08-01T02:47:13.295Z",
5
+ "rules": [
6
+ {
7
+ "name": "enforce-boolean-naming-prefixes",
8
+ "changeType": "fix",
9
+ "issues": [
10
+ 1545
11
+ ],
12
+ "summary": "check abstract properties and constructor parameter properties (closes #1545)"
13
+ }
14
+ ]
15
+ },
16
+ {
17
+ "version": "1.20.54",
18
+ "date": "2026-08-01T01:37:34.774Z",
19
+ "rules": [
20
+ {
21
+ "name": "export-if-in-doubt",
22
+ "changeType": "fix",
23
+ "issues": [
24
+ 1543
25
+ ],
26
+ "summary": "elide the remedy example instead of fabricating a destructive value (closes #1543)"
27
+ }
28
+ ]
29
+ },
2
30
  {
3
31
  "version": "1.20.53",
4
32
  "date": "2026-08-01T00:55:57.763Z",