@blumintinc/eslint-plugin-blumint 1.19.0 → 1.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/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.0',
225
+ version: '1.19.1',
226
226
  },
227
227
  parseOptions: {
228
228
  ecmaVersion: 2020,
@@ -26,6 +26,19 @@ var __importStar = (this && this.__importStar) || function (mod) {
26
26
  const createRule_1 = require("../utils/createRule");
27
27
  const utils_1 = require("@typescript-eslint/utils");
28
28
  const ts = __importStar(require("typescript"));
29
+ // The "handle" prefix the rule targets is the verb-phrase pattern
30
+ // `handle<Something>` — six letters immediately followed by a capitalized word
31
+ // (handleClick, handleSubmit, handleFormSubmit). When "handle" is followed by a
32
+ // lowercase letter the six letters are part of an ordinary word, not the prefix:
33
+ // the past participle "handled" (and derived names like "handledFingerprints"),
34
+ // the noun "handler(s)", "handles", "handling", the adjective "handleable". Those
35
+ // are plain identifiers, so flagging them — and worse, autofix-stripping the
36
+ // leading "handle" to leave nonsense like `d`/`dFingerprints` — silently corrupts
37
+ // unrelated code (Bug #1301). A bare "handle" is likewise a whole word, not a
38
+ // prefix.
39
+ function hasHandlePrefix(name) {
40
+ return /^handle[A-Z]/.test(name);
41
+ }
29
42
  module.exports = (0, createRule_1.createRule)({
30
43
  name: 'consistent-callback-naming',
31
44
  meta: {
@@ -48,9 +61,15 @@ module.exports = (0, createRule_1.createRule)({
48
61
  defaultOptions: [],
49
62
  create(context) {
50
63
  const parserServices = context.parserServices;
51
- // Check if we have access to TypeScript services
64
+ // This rule is type-aware, but a single eslint invocation routinely mixes
65
+ // in-project files with out-of-project ones (plain-Node `.mjs` scripts,
66
+ // config files, etc.) that the TS `project` never parses. Throwing here
67
+ // aborts rule loading for the ENTIRE run — one out-of-project file in argv
68
+ // kills diagnostics for every file (Bug #1302). Degrade gracefully instead:
69
+ // skip files without type information with a no-op visitor, matching how
70
+ // @typescript-eslint rules tolerate missing parser services per file.
52
71
  if (!parserServices?.program || !parserServices?.esTreeNodeToTSNodeMap) {
53
- throw new Error('You have to enable the `project` setting in parser options to use this rule');
72
+ return {};
54
73
  }
55
74
  const checker = parserServices.program.getTypeChecker();
56
75
  function isReactComponentType(node) {
@@ -251,16 +270,7 @@ module.exports = (0, createRule_1.createRule)({
251
270
  // Check function declarations and variable declarations for callback functions
252
271
  'FunctionDeclaration, VariableDeclarator'(node) {
253
272
  const functionName = node.id?.type === 'Identifier' ? node.id.name : undefined;
254
- if (functionName && functionName.startsWith('handle') && node.id) {
255
- // Skip autofixing for "handler" and "handlers"
256
- if (functionName === 'handler' || functionName === 'handlers') {
257
- context.report({
258
- node,
259
- messageId: 'callbackFunctionPrefix',
260
- data: { functionName },
261
- });
262
- return;
263
- }
273
+ if (functionName && hasHandlePrefix(functionName) && node.id) {
264
274
  // Skip autofixing for class parameters and getters
265
275
  const parent = node.parent;
266
276
  if (parent?.type === utils_1.AST_NODE_TYPES.PropertyDefinition ||
@@ -342,17 +352,8 @@ module.exports = (0, createRule_1.createRule)({
342
352
  'MethodDefinition, Property'(node) {
343
353
  if (node.key.type === 'Identifier' &&
344
354
  node.key.name &&
345
- node.key.name.startsWith('handle')) {
355
+ hasHandlePrefix(node.key.name)) {
346
356
  const name = node.key.name;
347
- // Skip autofixing for "handler" and "handlers"
348
- if (name === 'handler' || name === 'handlers') {
349
- context.report({
350
- node: node.key,
351
- messageId: 'callbackFunctionPrefix',
352
- data: { functionName: name },
353
- });
354
- return;
355
- }
356
357
  // Skip autofixing for class parameters and getters
357
358
  if (node.type === 'MethodDefinition' && node.kind === 'get') {
358
359
  context.report({
@@ -377,7 +378,7 @@ module.exports = (0, createRule_1.createRule)({
377
378
  // Check constructor parameters
378
379
  TSParameterProperty(node) {
379
380
  if (node.parameter.type === 'Identifier' &&
380
- node.parameter.name.startsWith('handle')) {
381
+ hasHandlePrefix(node.parameter.name)) {
381
382
  context.report({
382
383
  node,
383
384
  messageId: 'callbackFunctionPrefix',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blumintinc/eslint-plugin-blumint",
3
- "version": "1.19.0",
3
+ "version": "1.19.1",
4
4
  "description": "Custom eslint rules for use within BluMint",
5
5
  "author": {
6
6
  "name": "Brodie McGuire",
@@ -1,4 +1,19 @@
1
1
  [
2
+ {
3
+ "version": "1.19.1",
4
+ "date": "2026-07-14T01:28:36.352Z",
5
+ "rules": [
6
+ {
7
+ "name": "consistent-callback-naming",
8
+ "changeType": "fix",
9
+ "issues": [
10
+ 1301,
11
+ 1302
12
+ ],
13
+ "summary": "skip files without TS project services instead of aborting the run (closes #1302); require uppercase after \"handle\" so past-participle identifiers aren't stripped (closes #1301)"
14
+ }
15
+ ]
16
+ },
2
17
  {
3
18
  "version": "1.19.0",
4
19
  "date": "2026-07-13T23:57:00.324Z",