@blumintinc/eslint-plugin-blumint 1.18.15 → 1.18.16
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
|
@@ -92,11 +92,39 @@ const isHookCall = (callee) => {
|
|
|
92
92
|
}
|
|
93
93
|
return null;
|
|
94
94
|
};
|
|
95
|
+
/**
|
|
96
|
+
* Recognizes a callee named exactly `name`, whether a bare identifier (`memo`)
|
|
97
|
+
* or a non-computed member access (`X.memo`), regardless of import source.
|
|
98
|
+
*
|
|
99
|
+
* memo/forwardRef are commonly re-exported from project-local wrapper modules
|
|
100
|
+
* (e.g. `import { memo } from 'src/util/memo'`, which the sibling
|
|
101
|
+
* `use-custom-memo` rule actively enforces). Resolving these purely against
|
|
102
|
+
* react's import table would miss the wrapper form and misclassify an HOC
|
|
103
|
+
* factory as a render body. By-name recognition is safe here because callers
|
|
104
|
+
* are already gated by PascalCase naming and the surrounding factory analysis.
|
|
105
|
+
*
|
|
106
|
+
* Note: this deliberately does NOT apply to `createElement`, which must stay
|
|
107
|
+
* bound to a react import so unrelated factories (e.g. `Factory.createElement`)
|
|
108
|
+
* are not misread as element creation.
|
|
109
|
+
*/
|
|
110
|
+
const calleeMatchesName = (callee, name) => {
|
|
111
|
+
if (callee.type === utils_1.AST_NODE_TYPES.Identifier) {
|
|
112
|
+
return callee.name === name;
|
|
113
|
+
}
|
|
114
|
+
if (callee.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
|
115
|
+
!callee.computed &&
|
|
116
|
+
callee.property.type === utils_1.AST_NODE_TYPES.Identifier) {
|
|
117
|
+
return callee.property.name === name;
|
|
118
|
+
}
|
|
119
|
+
return false;
|
|
120
|
+
};
|
|
95
121
|
const isForwardRefCall = (node, reactImports) => {
|
|
96
|
-
return calleeMatchesReactMember(node.callee, reactImports, 'forwardRef')
|
|
122
|
+
return (calleeMatchesReactMember(node.callee, reactImports, 'forwardRef') ||
|
|
123
|
+
calleeMatchesName(node.callee, 'forwardRef'));
|
|
97
124
|
};
|
|
98
125
|
const isMemoCall = (node, reactImports) => {
|
|
99
|
-
return calleeMatchesReactMember(node.callee, reactImports, 'memo')
|
|
126
|
+
return (calleeMatchesReactMember(node.callee, reactImports, 'memo') ||
|
|
127
|
+
calleeMatchesName(node.callee, 'memo'));
|
|
100
128
|
};
|
|
101
129
|
const filterPresentResults = (results) => {
|
|
102
130
|
return results.filter((result) => Boolean(result));
|
|
@@ -298,6 +298,15 @@ function isDomainNumberCompound(name) {
|
|
|
298
298
|
const lastSegment = segments[segments.length - 1];
|
|
299
299
|
return (!!lastSegment && DOMAIN_NUMBER_HEAD_NOUNS.has(lastSegment.toLowerCase()));
|
|
300
300
|
}
|
|
301
|
+
// Rebuild a SCREAMING_SNAKE_CASE identifier's segments into a PascalCase compound
|
|
302
|
+
// (["MATCH","NUMBER"] -> "MatchNumber") so the snake-case branch can reuse the
|
|
303
|
+
// camelCase isDomainNumberCompound / DOMAIN_NUMBER_HEAD_NOUNS exemption verbatim,
|
|
304
|
+
// keeping MATCH_NUMBER and matchNumber on a single code path (#1294).
|
|
305
|
+
function screamingSnakePartsToPascalCase(parts) {
|
|
306
|
+
return parts
|
|
307
|
+
.map((part) => part.charAt(0) + part.slice(1).toLowerCase())
|
|
308
|
+
.join('');
|
|
309
|
+
}
|
|
301
310
|
exports.noHungarian = (0, createRule_1.createRule)({
|
|
302
311
|
name: 'no-hungarian',
|
|
303
312
|
meta: {
|
|
@@ -387,12 +396,31 @@ exports.noHungarian = (0, createRule_1.createRule)({
|
|
|
387
396
|
if (isAbbreviation) {
|
|
388
397
|
return true;
|
|
389
398
|
}
|
|
390
|
-
// A FULL type word tags the entity's type only
|
|
391
|
-
//
|
|
392
|
-
//
|
|
393
|
-
//
|
|
394
|
-
//
|
|
395
|
-
|
|
399
|
+
// A FULL type word tags the entity's runtime type only as a genuine
|
|
400
|
+
// leading prefix (index 0) or trailing head-noun (last segment).
|
|
401
|
+
// Mirror the camelCase/PascalCase branch, which never flags a
|
|
402
|
+
// full-type-word in a MIDDLE segment: an interior NUMBER/STRING is a
|
|
403
|
+
// domain modifier describing a variant (CADENCE_NUMBER_EDITORS —
|
|
404
|
+
// "editors of a numeric cadence"), not a redundant type tag. The
|
|
405
|
+
// previous `index === lastIndex - 1` allowance produced a casing
|
|
406
|
+
// asymmetry — CadenceNumberEditor was exempt (#1250) but
|
|
407
|
+
// CADENCE_NUMBER_EDITORS fired (#1294).
|
|
408
|
+
if (index !== 0 && index !== lastIndex) {
|
|
409
|
+
return false;
|
|
410
|
+
}
|
|
411
|
+
// A trailing "..._NUMBER" whose preceding head noun is a domain
|
|
412
|
+
// entity (MATCH_NUMBER, ISSUE_NUMBER, CURRENT_LINE_NUMBER) is a
|
|
413
|
+
// domain compound, not a Hungarian type tag — route through the same
|
|
414
|
+
// isDomainNumberCompound carve-out used for camelCase matchNumber
|
|
415
|
+
// (#1277), so numeric-quantity heads (COUNT_NUMBER, MAX_RETRY_NUMBER)
|
|
416
|
+
// still fire because those heads are absent from
|
|
417
|
+
// DOMAIN_NUMBER_HEAD_NOUNS.
|
|
418
|
+
if (normalizedMarker === 'number' &&
|
|
419
|
+
index === lastIndex &&
|
|
420
|
+
isDomainNumberCompound(screamingSnakePartsToPascalCase(parts))) {
|
|
421
|
+
return false;
|
|
422
|
+
}
|
|
423
|
+
return true;
|
|
396
424
|
});
|
|
397
425
|
});
|
|
398
426
|
}
|
package/package.json
CHANGED
package/release-manifest.json
CHANGED
|
@@ -1,4 +1,26 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "1.18.16",
|
|
4
|
+
"date": "2026-07-13T17:31:09.661Z",
|
|
5
|
+
"rules": [
|
|
6
|
+
{
|
|
7
|
+
"name": "memo-nested-react-components",
|
|
8
|
+
"changeType": "fix",
|
|
9
|
+
"issues": [
|
|
10
|
+
1293
|
|
11
|
+
],
|
|
12
|
+
"summary": "recognize project-local memo/forwardRef re-exports in HOC-factory escape hatch (closes #1293)"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"name": "no-hungarian",
|
|
16
|
+
"changeType": "fix",
|
|
17
|
+
"issues": [
|
|
18
|
+
1294
|
|
19
|
+
],
|
|
20
|
+
"summary": "exempt interior type-word segments in SCREAMING_SNAKE_CASE constants (closes #1294)"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
},
|
|
2
24
|
{
|
|
3
25
|
"version": "1.18.15",
|
|
4
26
|
"date": "2026-07-13T15:25:03.959Z",
|