@blumintinc/eslint-plugin-blumint 1.20.197 → 1.20.198
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 +1 -1
- package/lib/rules/no-entire-object-hook-deps.js +55 -13
- package/package.json +1 -1
- package/release-manifest.json +14 -0
package/lib/index.js
CHANGED
|
@@ -109,6 +109,51 @@ function readExhaustiveDepsDisable(comment) {
|
|
|
109
109
|
}
|
|
110
110
|
return comment.type === utils_1.AST_TOKEN_TYPES.Block ? 'file' : null;
|
|
111
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Whether a dependency's type is a primitive, so that narrowing it into member
|
|
114
|
+
* paths is meaningless and an unread entry is a deliberate recompute trigger
|
|
115
|
+
* rather than a stale object.
|
|
116
|
+
*
|
|
117
|
+
* why the `*Like` flags, never the bare ones: each `*Like` is the union of a
|
|
118
|
+
* primitive and its LITERAL form, and a literal type is what this repo's own
|
|
119
|
+
* fixers produce. `global-const-style` appends `as const`, which turns `0` into
|
|
120
|
+
* the numeric literal type `0`. The list used to name `StringLiteral`
|
|
121
|
+
* explicitly but `Number` and `Boolean` bare, so a string literal was primitive
|
|
122
|
+
* while `0 as const` and `true as const` were not — the same value lost its
|
|
123
|
+
* exemption the moment a sibling fixer froze it, which made this an exemption
|
|
124
|
+
* destroyed by COMPOSITION rather than a latent gap (#2238).
|
|
125
|
+
*
|
|
126
|
+
* why unions are walked: a union carries `TypeFlags.Union` and none of the
|
|
127
|
+
* flags above, so a bitmask test on the union ITSELF answers no for
|
|
128
|
+
* `'compact' | 'full'` — a string at runtime, and the shape
|
|
129
|
+
* `prefer-union-from-const-array` leaves behind. A union is primitive exactly
|
|
130
|
+
* when every constituent is, which also keeps `string | { a: number }` an
|
|
131
|
+
* object.
|
|
132
|
+
*/
|
|
133
|
+
function isPrimitiveType(type) {
|
|
134
|
+
// why the mask is built HERE and not hoisted to module scope: this module is
|
|
135
|
+
// imported by `src/index.ts`, so a module-scope `TypeFlags.X` is read the
|
|
136
|
+
// moment the plugin loads. Against a compiler that does not root-export the
|
|
137
|
+
// API, `TypeFlags` is `undefined` and the read throws — taking down every
|
|
138
|
+
// rule in the plugin, not just this one. `plugin-load-without-compiler-api`
|
|
139
|
+
// is the guard that says so.
|
|
140
|
+
const primitiveFlags = typescript_1.TypeFlags.StringLike |
|
|
141
|
+
typescript_1.TypeFlags.NumberLike |
|
|
142
|
+
typescript_1.TypeFlags.BooleanLike |
|
|
143
|
+
typescript_1.TypeFlags.BigIntLike |
|
|
144
|
+
typescript_1.TypeFlags.ESSymbolLike |
|
|
145
|
+
typescript_1.TypeFlags.Null |
|
|
146
|
+
typescript_1.TypeFlags.Undefined |
|
|
147
|
+
typescript_1.TypeFlags.Void |
|
|
148
|
+
typescript_1.TypeFlags.Never;
|
|
149
|
+
if (type.flags & primitiveFlags)
|
|
150
|
+
return true;
|
|
151
|
+
if (type.flags & typescript_1.TypeFlags.Union) {
|
|
152
|
+
const constituents = type.types;
|
|
153
|
+
return constituents.length > 0 && constituents.every(isPrimitiveType);
|
|
154
|
+
}
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
112
157
|
/** `channelGroupActive` -> `setChannelGroupActive`, `a` -> `setA`. */
|
|
113
158
|
function toSetterName(dependencyName) {
|
|
114
159
|
return `set${dependencyName.charAt(0).toUpperCase()}${dependencyName.slice(1)}`;
|
|
@@ -119,19 +164,16 @@ function isArrayOrPrimitive(checker, esTreeNode, nodeMap) {
|
|
|
119
164
|
if (!tsNode)
|
|
120
165
|
return false;
|
|
121
166
|
const type = checker.getTypeAtLocation(tsNode);
|
|
122
|
-
//
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
typescript_1.TypeFlags.Never |
|
|
133
|
-
typescript_1.TypeFlags.BigInt |
|
|
134
|
-
typescript_1.TypeFlags.ESSymbol)) {
|
|
167
|
+
// why: the `*Like` flags, never the bare ones. Each `*Like` is the union of
|
|
168
|
+
// a primitive and its LITERAL form, and a literal type is what this repo's
|
|
169
|
+
// own `global-const-style` produces — it appends `as const`, which turns
|
|
170
|
+
// `0` into the numeric literal type `0`. The list used to name
|
|
171
|
+
// `StringLiteral` explicitly but `Number` and `Boolean` bare, so a string
|
|
172
|
+
// literal was primitive while `0 as const` and `true as const` were not:
|
|
173
|
+
// the same value lost the exemption the moment a sibling fixer froze it
|
|
174
|
+
// (#2238). Enum members come in through `NumberLike`/`StringLike` for the
|
|
175
|
+
// same reason — an enum member is a primitive at runtime.
|
|
176
|
+
if (isPrimitiveType(type)) {
|
|
135
177
|
return true;
|
|
136
178
|
}
|
|
137
179
|
// Check if it's an array type
|
package/package.json
CHANGED
package/release-manifest.json
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "1.20.198",
|
|
4
|
+
"date": "2026-08-31T11:06:34.784Z",
|
|
5
|
+
"rules": [
|
|
6
|
+
{
|
|
7
|
+
"name": "no-entire-object-hook-deps",
|
|
8
|
+
"changeType": "fix",
|
|
9
|
+
"issues": [
|
|
10
|
+
2238
|
|
11
|
+
],
|
|
12
|
+
"summary": "treat a literal type as the primitive it is (closes #2238)"
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
},
|
|
2
16
|
{
|
|
3
17
|
"version": "1.20.197",
|
|
4
18
|
"date": "2026-08-31T08:50:13.198Z",
|