eslint-plugin-react-hooks-extra 1.23.3-next.8 → 1.24.0-beta.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/dist/index.js +144 -146
- package/dist/index.mjs +144 -146
- package/package.json +13 -13
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var AST = require('@eslint-react/ast');
|
|
4
4
|
var core = require('@eslint-react/core');
|
|
5
5
|
var eff = require('@eslint-react/eff');
|
|
6
6
|
var shared = require('@eslint-react/shared');
|
|
@@ -26,22 +26,23 @@ function _interopNamespace(e) {
|
|
|
26
26
|
return Object.freeze(n);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
var
|
|
29
|
+
var AST__namespace = /*#__PURE__*/_interopNamespace(AST);
|
|
30
30
|
var VAR5__namespace = /*#__PURE__*/_interopNamespace(VAR5);
|
|
31
31
|
|
|
32
32
|
// package.json
|
|
33
33
|
var name = "eslint-plugin-react-hooks-extra";
|
|
34
|
-
var version = "1.
|
|
34
|
+
var version = "1.24.0-beta.1";
|
|
35
35
|
var createRule = shared.createRuleForPlugin("hooks-extra");
|
|
36
|
-
function isFromHookCall(name2, context, settings, predicate = eff.
|
|
36
|
+
function isFromHookCall(name2, context, settings, predicate = eff.returnTrue) {
|
|
37
37
|
const hookAlias = settings.additionalHooks?.[name2] ?? [];
|
|
38
|
-
return (topLevelId) =>
|
|
39
|
-
VAR5__namespace.findVariable(topLevelId, context.sourceCode.getScope(topLevelId))
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
38
|
+
return (topLevelId) => {
|
|
39
|
+
const variable = VAR5__namespace.findVariable(topLevelId, context.sourceCode.getScope(topLevelId));
|
|
40
|
+
const variableNode = VAR5__namespace.getVariableNode(variable, 0);
|
|
41
|
+
if (variableNode == null) return false;
|
|
42
|
+
if (variableNode.type !== types.AST_NODE_TYPES.CallExpression) return false;
|
|
43
|
+
if (!core.isReactHookCallWithNameAlias(name2, context, hookAlias)(variableNode)) return false;
|
|
44
|
+
return predicate(topLevelId, variableNode);
|
|
45
|
+
};
|
|
45
46
|
}
|
|
46
47
|
function isFromUseStateCall(context, settings) {
|
|
47
48
|
const predicate = (topLevelId, call) => {
|
|
@@ -72,8 +73,13 @@ function isSetFunctionCall(context, settings) {
|
|
|
72
73
|
if (!isAt || index == null) {
|
|
73
74
|
return false;
|
|
74
75
|
}
|
|
75
|
-
const
|
|
76
|
-
|
|
76
|
+
const indexScope = context.sourceCode.getScope(node);
|
|
77
|
+
const indexValue = VAR5__namespace.toResolved({
|
|
78
|
+
kind: "lazy",
|
|
79
|
+
node: index,
|
|
80
|
+
initialScope: indexScope
|
|
81
|
+
}).value;
|
|
82
|
+
return indexValue === 1 && isIdFromUseStateCall(callee.object);
|
|
77
83
|
}
|
|
78
84
|
// const [data, setData] = useState();
|
|
79
85
|
// setData();
|
|
@@ -86,8 +92,14 @@ function isSetFunctionCall(context, settings) {
|
|
|
86
92
|
if (!("name" in node.callee.object)) {
|
|
87
93
|
return false;
|
|
88
94
|
}
|
|
89
|
-
const
|
|
90
|
-
|
|
95
|
+
const property = node.callee.property;
|
|
96
|
+
const propertyScope = context.sourceCode.getScope(node);
|
|
97
|
+
const propertyValue = VAR5__namespace.toResolved({
|
|
98
|
+
kind: "lazy",
|
|
99
|
+
node: property,
|
|
100
|
+
initialScope: propertyScope
|
|
101
|
+
}).value;
|
|
102
|
+
return propertyValue === 1 && isIdFromUseStateCall(node.callee.object);
|
|
91
103
|
}
|
|
92
104
|
default: {
|
|
93
105
|
return false;
|
|
@@ -148,8 +160,8 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
148
160
|
const isUseCallbackCall2 = core.isReactHookCallWithNameAlias("useCallback", context, additionalHooks.useCallback ?? []);
|
|
149
161
|
const isSetStateCall = isSetFunctionCall(context, settings);
|
|
150
162
|
const isIdFromUseStateCall = isFromUseStateCall(context, settings);
|
|
151
|
-
const
|
|
152
|
-
const setupFunctionRef = { current:
|
|
163
|
+
const functionEntries = [];
|
|
164
|
+
const setupFunctionRef = { current: null };
|
|
153
165
|
const setupFunctionIdentifiers = [];
|
|
154
166
|
const indFunctionCalls = [];
|
|
155
167
|
const indSetStateCalls = /* @__PURE__ */ new WeakMap();
|
|
@@ -157,10 +169,12 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
157
169
|
const indSetStateCallsInUseEffectSetup = /* @__PURE__ */ new Map();
|
|
158
170
|
const indSetStateCallsInUseMemoOrCallback = /* @__PURE__ */ new WeakMap();
|
|
159
171
|
const onSetupFunctionEnter = (node) => {
|
|
160
|
-
setupFunctionRef.current =
|
|
172
|
+
setupFunctionRef.current = node;
|
|
161
173
|
};
|
|
162
174
|
const onSetupFunctionExit = (node) => {
|
|
163
|
-
|
|
175
|
+
if (setupFunctionRef.current === node) {
|
|
176
|
+
setupFunctionRef.current = null;
|
|
177
|
+
}
|
|
164
178
|
};
|
|
165
179
|
function isSetupFunction(node) {
|
|
166
180
|
return node.parent?.type === types.AST_NODE_TYPES.CallExpression && node.parent.callee !== node && isUseEffectLikeCall(node.parent);
|
|
@@ -169,33 +183,30 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
169
183
|
return tsPattern.match(node).when(isUseStateCall2, () => "useState").when(isUseEffectLikeCall, () => "useEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
|
|
170
184
|
}
|
|
171
185
|
function getFunctionKind(node) {
|
|
172
|
-
return tsPattern.match(node).when(isSetupFunction, () => "setup").when(
|
|
186
|
+
return tsPattern.match(node).when(isSetupFunction, () => "setup").when(AST__namespace.isFunctionOfImmediatelyInvoked, () => "immediate").otherwise(() => "other");
|
|
173
187
|
}
|
|
174
188
|
return {
|
|
175
189
|
":function"(node) {
|
|
176
190
|
const kind = getFunctionKind(node);
|
|
177
|
-
|
|
191
|
+
functionEntries.push({ kind, node });
|
|
178
192
|
if (kind === "setup") {
|
|
179
193
|
onSetupFunctionEnter(node);
|
|
180
194
|
}
|
|
181
195
|
},
|
|
182
196
|
":function:exit"(node) {
|
|
183
|
-
const { kind } =
|
|
197
|
+
const { kind } = functionEntries.at(-1) ?? {};
|
|
184
198
|
if (kind === "setup") {
|
|
185
199
|
onSetupFunctionExit(node);
|
|
186
200
|
}
|
|
187
|
-
|
|
201
|
+
functionEntries.pop();
|
|
188
202
|
},
|
|
189
203
|
CallExpression(node) {
|
|
190
|
-
const setupFunction =
|
|
191
|
-
const pEntry =
|
|
192
|
-
if (pEntry
|
|
204
|
+
const setupFunction = setupFunctionRef.current;
|
|
205
|
+
const pEntry = functionEntries.at(-1);
|
|
206
|
+
if (pEntry == null || pEntry.node.async) {
|
|
193
207
|
return;
|
|
194
208
|
}
|
|
195
209
|
tsPattern.match(getCallKind(node)).with("setState", () => {
|
|
196
|
-
if (pEntry == null) {
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
210
|
switch (true) {
|
|
200
211
|
case (pEntry.node === setupFunction || pEntry.kind === "immediate"): {
|
|
201
212
|
context.report({
|
|
@@ -208,28 +219,28 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
208
219
|
return;
|
|
209
220
|
}
|
|
210
221
|
default: {
|
|
211
|
-
const
|
|
212
|
-
if (
|
|
222
|
+
const variableDeclarator = AST__namespace.findParentNodeGuard(node, isVariableDeclaratorFromHookCall);
|
|
223
|
+
if (variableDeclarator == null) {
|
|
213
224
|
const calls = indSetStateCalls.get(pEntry.node) ?? [];
|
|
214
225
|
indSetStateCalls.set(pEntry.node, [...calls, node]);
|
|
215
226
|
return;
|
|
216
227
|
}
|
|
217
|
-
const
|
|
218
|
-
const prevs = indSetStateCallsInUseMemoOrCallback.get(
|
|
219
|
-
indSetStateCallsInUseMemoOrCallback.set(
|
|
228
|
+
const init = variableDeclarator.init;
|
|
229
|
+
const prevs = indSetStateCallsInUseMemoOrCallback.get(init) ?? [];
|
|
230
|
+
indSetStateCallsInUseMemoOrCallback.set(init, [...prevs, node]);
|
|
220
231
|
}
|
|
221
232
|
}
|
|
222
233
|
}).with("useEffect", () => {
|
|
223
|
-
if (
|
|
234
|
+
if (AST__namespace.isFunction(node.arguments.at(0))) {
|
|
224
235
|
return;
|
|
225
236
|
}
|
|
226
|
-
setupFunctionIdentifiers.push(...
|
|
237
|
+
setupFunctionIdentifiers.push(...AST__namespace.getNestedIdentifiers(node));
|
|
227
238
|
}).with("other", () => {
|
|
228
|
-
if (pEntry
|
|
239
|
+
if (pEntry.node !== setupFunction) {
|
|
229
240
|
return;
|
|
230
241
|
}
|
|
231
242
|
indFunctionCalls.push(node);
|
|
232
|
-
}).otherwise(eff.
|
|
243
|
+
}).otherwise(() => eff._);
|
|
233
244
|
},
|
|
234
245
|
Identifier(node) {
|
|
235
246
|
if (node.parent.type === types.AST_NODE_TYPES.CallExpression && node.parent.callee === node) {
|
|
@@ -247,11 +258,10 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
247
258
|
if (!isUseMemoCall2(parent)) {
|
|
248
259
|
break;
|
|
249
260
|
}
|
|
250
|
-
const
|
|
251
|
-
if (
|
|
261
|
+
const variableDeclarator = AST__namespace.findParentNodeGuard(parent, isVariableDeclaratorFromHookCall);
|
|
262
|
+
if (variableDeclarator == null) {
|
|
252
263
|
break;
|
|
253
264
|
}
|
|
254
|
-
const variableDeclarator = mbVariableDeclarator.value;
|
|
255
265
|
const calls = indSetStateCallsInUseEffectArg0.get(variableDeclarator.init) ?? [];
|
|
256
266
|
indSetStateCallsInUseEffectArg0.set(variableDeclarator.init, [...calls, node]);
|
|
257
267
|
break;
|
|
@@ -261,11 +271,10 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
261
271
|
break;
|
|
262
272
|
}
|
|
263
273
|
if (isUseCallbackCall2(node.parent)) {
|
|
264
|
-
const
|
|
265
|
-
if (
|
|
274
|
+
const variableDeclarator = AST__namespace.findParentNodeGuard(node.parent, isVariableDeclaratorFromHookCall);
|
|
275
|
+
if (variableDeclarator == null) {
|
|
266
276
|
break;
|
|
267
277
|
}
|
|
268
|
-
const variableDeclarator = mbVariableDeclarator.value;
|
|
269
278
|
const prevs = indSetStateCallsInUseEffectArg0.get(variableDeclarator.init) ?? [];
|
|
270
279
|
indSetStateCallsInUseEffectArg0.set(variableDeclarator.init, [...prevs, node]);
|
|
271
280
|
}
|
|
@@ -279,7 +288,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
279
288
|
},
|
|
280
289
|
"Program:exit"() {
|
|
281
290
|
const getSetStateCalls = (id, initialScope) => {
|
|
282
|
-
const node =
|
|
291
|
+
const node = VAR5__namespace.getVariableNode(VAR5__namespace.findVariable(id, initialScope), 0);
|
|
283
292
|
switch (node?.type) {
|
|
284
293
|
case types.AST_NODE_TYPES.ArrowFunctionExpression:
|
|
285
294
|
case types.AST_NODE_TYPES.FunctionDeclaration:
|
|
@@ -290,7 +299,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
290
299
|
}
|
|
291
300
|
return [];
|
|
292
301
|
};
|
|
293
|
-
for (const [
|
|
302
|
+
for (const [, calls] of indSetStateCallsInUseEffectSetup) {
|
|
294
303
|
for (const call of calls) {
|
|
295
304
|
context.report({
|
|
296
305
|
messageId: "noDirectSetStateInUseEffect",
|
|
@@ -310,7 +319,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
310
319
|
messageId: "noDirectSetStateInUseEffect",
|
|
311
320
|
node: setStateCall,
|
|
312
321
|
data: {
|
|
313
|
-
name:
|
|
322
|
+
name: AST__namespace.toReadableNodeName(setStateCall, (n) => context.sourceCode.getText(n))
|
|
314
323
|
}
|
|
315
324
|
});
|
|
316
325
|
}
|
|
@@ -322,7 +331,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
322
331
|
messageId: "noDirectSetStateInUseEffect",
|
|
323
332
|
node: setStateCall,
|
|
324
333
|
data: {
|
|
325
|
-
name:
|
|
334
|
+
name: AST__namespace.toReadableNodeName(setStateCall, (n) => context.sourceCode.getText(n))
|
|
326
335
|
}
|
|
327
336
|
});
|
|
328
337
|
}
|
|
@@ -365,8 +374,8 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
365
374
|
const isUseCallbackCall2 = core.isReactHookCallWithNameAlias("useCallback", context, additionalHooks.useCallback ?? []);
|
|
366
375
|
const isSetStateCall = isSetFunctionCall(context, settings);
|
|
367
376
|
const isIdFromUseStateCall = isFromUseStateCall(context, settings);
|
|
368
|
-
const
|
|
369
|
-
const setupFunctionRef = { current:
|
|
377
|
+
const functionEntries = [];
|
|
378
|
+
const setupFunctionRef = { current: null };
|
|
370
379
|
const setupFunctionIdentifiers = [];
|
|
371
380
|
const indFunctionCalls = [];
|
|
372
381
|
const indSetStateCalls = /* @__PURE__ */ new WeakMap();
|
|
@@ -374,10 +383,12 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
374
383
|
const indSetStateCallsInUseLayoutEffectSetup = /* @__PURE__ */ new Map();
|
|
375
384
|
const indSetStateCallsInUseMemoOrCallback = /* @__PURE__ */ new WeakMap();
|
|
376
385
|
const onSetupFunctionEnter = (node) => {
|
|
377
|
-
setupFunctionRef.current =
|
|
386
|
+
setupFunctionRef.current = node;
|
|
378
387
|
};
|
|
379
388
|
const onSetupFunctionExit = (node) => {
|
|
380
|
-
|
|
389
|
+
if (setupFunctionRef.current === node) {
|
|
390
|
+
setupFunctionRef.current = null;
|
|
391
|
+
}
|
|
381
392
|
};
|
|
382
393
|
function isSetupFunction(node) {
|
|
383
394
|
return node.parent?.type === types.AST_NODE_TYPES.CallExpression && node.parent.callee !== node && isUseLayoutEffectLikeCall(node.parent);
|
|
@@ -386,33 +397,30 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
386
397
|
return tsPattern.match(node).when(isUseStateCall2, () => "useState").when(isUseLayoutEffectLikeCall, () => "useLayoutEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
|
|
387
398
|
}
|
|
388
399
|
function getFunctionKind(node) {
|
|
389
|
-
return tsPattern.match(node).when(isSetupFunction, () => "setup").when(
|
|
400
|
+
return tsPattern.match(node).when(isSetupFunction, () => "setup").when(AST__namespace.isFunctionOfImmediatelyInvoked, () => "immediate").otherwise(() => "other");
|
|
390
401
|
}
|
|
391
402
|
return {
|
|
392
403
|
":function"(node) {
|
|
393
404
|
const kind = getFunctionKind(node);
|
|
394
|
-
|
|
405
|
+
functionEntries.push({ kind, node });
|
|
395
406
|
if (kind === "setup") {
|
|
396
407
|
onSetupFunctionEnter(node);
|
|
397
408
|
}
|
|
398
409
|
},
|
|
399
410
|
":function:exit"(node) {
|
|
400
|
-
const { kind } =
|
|
411
|
+
const { kind } = functionEntries.at(-1) ?? {};
|
|
401
412
|
if (kind === "setup") {
|
|
402
413
|
onSetupFunctionExit(node);
|
|
403
414
|
}
|
|
404
|
-
|
|
415
|
+
functionEntries.pop();
|
|
405
416
|
},
|
|
406
417
|
CallExpression(node) {
|
|
407
|
-
const setupFunction =
|
|
408
|
-
const pEntry =
|
|
409
|
-
if (pEntry
|
|
418
|
+
const setupFunction = setupFunctionRef.current;
|
|
419
|
+
const pEntry = functionEntries.at(-1);
|
|
420
|
+
if (pEntry == null || pEntry.node.async) {
|
|
410
421
|
return;
|
|
411
422
|
}
|
|
412
423
|
tsPattern.match(getCallKind(node)).with("setState", () => {
|
|
413
|
-
if (pEntry == null) {
|
|
414
|
-
return;
|
|
415
|
-
}
|
|
416
424
|
switch (true) {
|
|
417
425
|
case (pEntry.node === setupFunction || pEntry.kind === "immediate"): {
|
|
418
426
|
context.report({
|
|
@@ -425,28 +433,28 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
425
433
|
return;
|
|
426
434
|
}
|
|
427
435
|
default: {
|
|
428
|
-
const
|
|
429
|
-
if (
|
|
436
|
+
const variableDeclarator = AST__namespace.findParentNodeGuard(node, isVariableDeclaratorFromHookCall);
|
|
437
|
+
if (variableDeclarator == null) {
|
|
430
438
|
const calls = indSetStateCalls.get(pEntry.node) ?? [];
|
|
431
439
|
indSetStateCalls.set(pEntry.node, [...calls, node]);
|
|
432
440
|
return;
|
|
433
441
|
}
|
|
434
|
-
const
|
|
435
|
-
const prevs = indSetStateCallsInUseMemoOrCallback.get(
|
|
436
|
-
indSetStateCallsInUseMemoOrCallback.set(
|
|
442
|
+
const init = variableDeclarator.init;
|
|
443
|
+
const prevs = indSetStateCallsInUseMemoOrCallback.get(init) ?? [];
|
|
444
|
+
indSetStateCallsInUseMemoOrCallback.set(init, [...prevs, node]);
|
|
437
445
|
}
|
|
438
446
|
}
|
|
439
447
|
}).with("useLayoutEffect", () => {
|
|
440
|
-
if (
|
|
448
|
+
if (AST__namespace.isFunction(node.arguments.at(0))) {
|
|
441
449
|
return;
|
|
442
450
|
}
|
|
443
|
-
setupFunctionIdentifiers.push(...
|
|
451
|
+
setupFunctionIdentifiers.push(...AST__namespace.getNestedIdentifiers(node));
|
|
444
452
|
}).with("other", () => {
|
|
445
|
-
if (pEntry
|
|
453
|
+
if (pEntry.node !== setupFunction) {
|
|
446
454
|
return;
|
|
447
455
|
}
|
|
448
456
|
indFunctionCalls.push(node);
|
|
449
|
-
}).otherwise(eff.
|
|
457
|
+
}).otherwise(() => eff._);
|
|
450
458
|
},
|
|
451
459
|
Identifier(node) {
|
|
452
460
|
if (node.parent.type === types.AST_NODE_TYPES.CallExpression && node.parent.callee === node) {
|
|
@@ -464,11 +472,10 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
464
472
|
if (!isUseMemoCall2(parent)) {
|
|
465
473
|
break;
|
|
466
474
|
}
|
|
467
|
-
const
|
|
468
|
-
if (
|
|
475
|
+
const variableDeclarator = AST__namespace.findParentNodeGuard(parent, isVariableDeclaratorFromHookCall);
|
|
476
|
+
if (variableDeclarator == null) {
|
|
469
477
|
break;
|
|
470
478
|
}
|
|
471
|
-
const variableDeclarator = mbVariableDeclarator.value;
|
|
472
479
|
const calls = indSetStateCallsInUseLayoutEffectArg0.get(variableDeclarator.init) ?? [];
|
|
473
480
|
indSetStateCallsInUseLayoutEffectArg0.set(variableDeclarator.init, [...calls, node]);
|
|
474
481
|
break;
|
|
@@ -478,11 +485,10 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
478
485
|
break;
|
|
479
486
|
}
|
|
480
487
|
if (isUseCallbackCall2(node.parent)) {
|
|
481
|
-
const
|
|
482
|
-
if (
|
|
488
|
+
const variableDeclarator = AST__namespace.findParentNodeGuard(node.parent, isVariableDeclaratorFromHookCall);
|
|
489
|
+
if (variableDeclarator == null) {
|
|
483
490
|
break;
|
|
484
491
|
}
|
|
485
|
-
const variableDeclarator = mbVariableDeclarator.value;
|
|
486
492
|
const prevs = indSetStateCallsInUseLayoutEffectArg0.get(variableDeclarator.init) ?? [];
|
|
487
493
|
indSetStateCallsInUseLayoutEffectArg0.set(variableDeclarator.init, [...prevs, node]);
|
|
488
494
|
}
|
|
@@ -496,7 +502,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
496
502
|
},
|
|
497
503
|
"Program:exit"() {
|
|
498
504
|
const getSetStateCalls = (id, initialScope) => {
|
|
499
|
-
const node =
|
|
505
|
+
const node = VAR5__namespace.getVariableNode(VAR5__namespace.findVariable(id, initialScope), 0);
|
|
500
506
|
switch (node?.type) {
|
|
501
507
|
case types.AST_NODE_TYPES.ArrowFunctionExpression:
|
|
502
508
|
case types.AST_NODE_TYPES.FunctionDeclaration:
|
|
@@ -507,7 +513,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
507
513
|
}
|
|
508
514
|
return [];
|
|
509
515
|
};
|
|
510
|
-
for (const [
|
|
516
|
+
for (const [, calls] of indSetStateCallsInUseLayoutEffectSetup) {
|
|
511
517
|
for (const call of calls) {
|
|
512
518
|
context.report({
|
|
513
519
|
messageId: "noDirectSetStateInUseLayoutEffect",
|
|
@@ -527,7 +533,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
527
533
|
messageId: "noDirectSetStateInUseLayoutEffect",
|
|
528
534
|
node: setStateCall,
|
|
529
535
|
data: {
|
|
530
|
-
name:
|
|
536
|
+
name: AST__namespace.toReadableNodeName(setStateCall, (n) => context.sourceCode.getText(n))
|
|
531
537
|
}
|
|
532
538
|
});
|
|
533
539
|
}
|
|
@@ -539,7 +545,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
539
545
|
messageId: "noDirectSetStateInUseLayoutEffect",
|
|
540
546
|
node: setStateCall,
|
|
541
547
|
data: {
|
|
542
|
-
name:
|
|
548
|
+
name: AST__namespace.toReadableNodeName(setStateCall, (n) => context.sourceCode.getText(n))
|
|
543
549
|
}
|
|
544
550
|
});
|
|
545
551
|
}
|
|
@@ -582,43 +588,41 @@ var no_unnecessary_use_callback_default = createRule({
|
|
|
582
588
|
}
|
|
583
589
|
const scope = context.sourceCode.getScope(node);
|
|
584
590
|
const component = scope.block;
|
|
585
|
-
if (!
|
|
591
|
+
if (!AST__namespace.isFunction(component)) {
|
|
586
592
|
return;
|
|
587
593
|
}
|
|
588
594
|
const [arg0, arg1] = node.arguments;
|
|
589
595
|
if (arg0 == null || arg1 == null) {
|
|
590
596
|
return;
|
|
591
597
|
}
|
|
592
|
-
const hasEmptyDeps =
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
eff.O.exists((x) => x.elements.length === 0)
|
|
601
|
-
);
|
|
598
|
+
const hasEmptyDeps = tsPattern.match(arg1).with({ type: types.AST_NODE_TYPES.ArrayExpression }, (n) => n.elements.length === 0).with({ type: types.AST_NODE_TYPES.Identifier }, (n) => {
|
|
599
|
+
const variable = VAR5__namespace.findVariable(n.name, initialScope);
|
|
600
|
+
const variableNode = VAR5__namespace.getVariableNode(variable, 0);
|
|
601
|
+
if (variableNode?.type !== types.AST_NODE_TYPES.ArrayExpression) {
|
|
602
|
+
return false;
|
|
603
|
+
}
|
|
604
|
+
return variableNode.elements.length === 0;
|
|
605
|
+
}).otherwise(() => false);
|
|
602
606
|
if (!hasEmptyDeps) {
|
|
603
607
|
return;
|
|
604
608
|
}
|
|
605
|
-
const
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
);
|
|
609
|
+
const arg0Node = tsPattern.match(arg0).with({ type: types.AST_NODE_TYPES.ArrowFunctionExpression }, (n) => {
|
|
610
|
+
if (n.body.type === types.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
611
|
+
return n.body;
|
|
612
|
+
}
|
|
613
|
+
return n;
|
|
614
|
+
}).with({ type: types.AST_NODE_TYPES.FunctionExpression }, eff.identity).with({ type: types.AST_NODE_TYPES.Identifier }, (n) => {
|
|
615
|
+
const variable = VAR5__namespace.findVariable(n.name, initialScope);
|
|
616
|
+
const variableNode = VAR5__namespace.getVariableNode(variable, 0);
|
|
617
|
+
if (variableNode?.type !== types.AST_NODE_TYPES.ArrowFunctionExpression && variableNode?.type !== types.AST_NODE_TYPES.FunctionExpression) {
|
|
618
|
+
return eff._;
|
|
619
|
+
}
|
|
620
|
+
return variableNode;
|
|
621
|
+
}).otherwise(() => eff._);
|
|
622
|
+
if (arg0Node == null) return;
|
|
623
|
+
const arg0NodeScope = context.sourceCode.getScope(arg0Node);
|
|
624
|
+
const arg0NodeReferences = VAR5__namespace.getChidScopes(arg0NodeScope).flatMap((x) => x.references);
|
|
625
|
+
const isReferencedToComponentScope = arg0NodeReferences.some((x) => x.resolved?.scope.block === component);
|
|
622
626
|
if (!isReferencedToComponentScope) {
|
|
623
627
|
context.report({
|
|
624
628
|
messageId: "noUnnecessaryUseCallback",
|
|
@@ -663,51 +667,45 @@ var no_unnecessary_use_memo_default = createRule({
|
|
|
663
667
|
}
|
|
664
668
|
const scope = context.sourceCode.getScope(node);
|
|
665
669
|
const component = scope.block;
|
|
666
|
-
if (!
|
|
670
|
+
if (!AST__namespace.isFunction(component)) {
|
|
667
671
|
return;
|
|
668
672
|
}
|
|
669
673
|
const [arg0, arg1] = node.arguments;
|
|
670
674
|
if (arg0 == null || arg1 == null) {
|
|
671
675
|
return;
|
|
672
676
|
}
|
|
673
|
-
const hasCallInArg0 =
|
|
674
|
-
eff.O.some(arg0),
|
|
675
|
-
eff.O.filter((n) => AST2__namespace.isFunction(n)),
|
|
676
|
-
eff.O.exists((n) => [...AST2__namespace.getNestedCallExpressions(n.body), ...AST2__namespace.getNestedNewExpressions(n.body)].length > 0)
|
|
677
|
-
);
|
|
677
|
+
const hasCallInArg0 = AST__namespace.isFunction(arg0) && [...AST__namespace.getNestedCallExpressions(arg0.body), ...AST__namespace.getNestedNewExpressions(arg0.body)].length > 0;
|
|
678
678
|
if (hasCallInArg0) {
|
|
679
679
|
return;
|
|
680
680
|
}
|
|
681
|
-
const hasEmptyDeps =
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
eff.O.exists((x) => x.elements.length === 0)
|
|
690
|
-
);
|
|
681
|
+
const hasEmptyDeps = tsPattern.match(arg1).with({ type: types.AST_NODE_TYPES.ArrayExpression }, (n) => n.elements.length === 0).with({ type: types.AST_NODE_TYPES.Identifier }, (n) => {
|
|
682
|
+
const variable = VAR5__namespace.findVariable(n.name, initialScope);
|
|
683
|
+
const variableNode = VAR5__namespace.getVariableNode(variable, 0);
|
|
684
|
+
if (variableNode?.type !== types.AST_NODE_TYPES.ArrayExpression) {
|
|
685
|
+
return false;
|
|
686
|
+
}
|
|
687
|
+
return variableNode.elements.length === 0;
|
|
688
|
+
}).otherwise(() => false);
|
|
691
689
|
if (!hasEmptyDeps) {
|
|
692
690
|
return;
|
|
693
691
|
}
|
|
694
|
-
const
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
);
|
|
692
|
+
const arg0Node = tsPattern.match(arg0).with({ type: types.AST_NODE_TYPES.ArrowFunctionExpression }, (n) => {
|
|
693
|
+
if (n.body.type === types.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
694
|
+
return n.body;
|
|
695
|
+
}
|
|
696
|
+
return n;
|
|
697
|
+
}).with({ type: types.AST_NODE_TYPES.FunctionExpression }, eff.identity).with({ type: types.AST_NODE_TYPES.Identifier }, (n) => {
|
|
698
|
+
const variable = VAR5__namespace.findVariable(n.name, initialScope);
|
|
699
|
+
const variableNode = VAR5__namespace.getVariableNode(variable, 0);
|
|
700
|
+
if (variableNode?.type !== types.AST_NODE_TYPES.ArrowFunctionExpression && variableNode?.type !== types.AST_NODE_TYPES.FunctionExpression) {
|
|
701
|
+
return eff._;
|
|
702
|
+
}
|
|
703
|
+
return variableNode;
|
|
704
|
+
}).otherwise(() => eff._);
|
|
705
|
+
if (arg0Node == null) return;
|
|
706
|
+
const arg0NodeScope = context.sourceCode.getScope(arg0Node);
|
|
707
|
+
const arg0NodeReferences = VAR5__namespace.getChidScopes(arg0NodeScope).flatMap((x) => x.references);
|
|
708
|
+
const isReferencedToComponentScope = arg0NodeReferences.some((x) => x.resolved?.scope.block === component);
|
|
711
709
|
if (!isReferencedToComponentScope) {
|
|
712
710
|
context.report({
|
|
713
711
|
messageId: "noUnnecessaryUseMemo",
|
|
@@ -746,7 +744,7 @@ var no_useless_custom_hooks_default = createRule({
|
|
|
746
744
|
"Program:exit"(node) {
|
|
747
745
|
const allHooks = ctx.getAllHooks(node);
|
|
748
746
|
for (const { name: name2, node: node2, hookCalls } of allHooks.values()) {
|
|
749
|
-
if (
|
|
747
|
+
if (AST__namespace.isEmptyFunction(node2)) {
|
|
750
748
|
continue;
|
|
751
749
|
}
|
|
752
750
|
if (hookCalls.length > 0) {
|
|
@@ -759,7 +757,7 @@ var no_useless_custom_hooks_default = createRule({
|
|
|
759
757
|
messageId: "noUselessCustomHooks",
|
|
760
758
|
node: node2,
|
|
761
759
|
data: {
|
|
762
|
-
name: name2
|
|
760
|
+
name: name2
|
|
763
761
|
}
|
|
764
762
|
});
|
|
765
763
|
}
|
|
@@ -803,11 +801,11 @@ var prefer_use_state_lazy_initialization_default = createRule({
|
|
|
803
801
|
if (useStateInput == null) {
|
|
804
802
|
return;
|
|
805
803
|
}
|
|
806
|
-
const nestedCallExpressions =
|
|
804
|
+
const nestedCallExpressions = AST__namespace.getNestedCallExpressions(useStateInput);
|
|
807
805
|
const hasFunctionCall = nestedCallExpressions.some((n) => {
|
|
808
806
|
return "name" in n.callee && !ALLOW_LIST.includes(n.callee.name);
|
|
809
807
|
});
|
|
810
|
-
const hasNewCall =
|
|
808
|
+
const hasNewCall = AST__namespace.getNestedNewExpressions(useStateInput).some((n) => {
|
|
811
809
|
return "name" in n.callee && !ALLOW_LIST.includes(n.callee.name);
|
|
812
810
|
});
|
|
813
811
|
if (!hasFunctionCall && !hasNewCall) {
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as AST from '@eslint-react/ast';
|
|
2
2
|
import { isReactHookCallWithNameAlias, isReactHookCall, isUseCallbackCall, isReactHookCallWithNameLoose, isUseMemoCall, useHookCollector, isUseStateCall, isReactHookName } from '@eslint-react/core';
|
|
3
|
-
import {
|
|
3
|
+
import { _, identity, returnTrue } from '@eslint-react/eff';
|
|
4
4
|
import { createRuleForPlugin, getSettingsFromContext } from '@eslint-react/shared';
|
|
5
5
|
import * as VAR5 from '@eslint-react/var';
|
|
6
6
|
import { AST_NODE_TYPES } from '@typescript-eslint/types';
|
|
@@ -8,17 +8,18 @@ import { match } from 'ts-pattern';
|
|
|
8
8
|
|
|
9
9
|
// package.json
|
|
10
10
|
var name = "eslint-plugin-react-hooks-extra";
|
|
11
|
-
var version = "1.
|
|
11
|
+
var version = "1.24.0-beta.1";
|
|
12
12
|
var createRule = createRuleForPlugin("hooks-extra");
|
|
13
|
-
function isFromHookCall(name2, context, settings, predicate =
|
|
13
|
+
function isFromHookCall(name2, context, settings, predicate = returnTrue) {
|
|
14
14
|
const hookAlias = settings.additionalHooks?.[name2] ?? [];
|
|
15
|
-
return (topLevelId) =>
|
|
16
|
-
VAR5.findVariable(topLevelId, context.sourceCode.getScope(topLevelId))
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
return (topLevelId) => {
|
|
16
|
+
const variable = VAR5.findVariable(topLevelId, context.sourceCode.getScope(topLevelId));
|
|
17
|
+
const variableNode = VAR5.getVariableNode(variable, 0);
|
|
18
|
+
if (variableNode == null) return false;
|
|
19
|
+
if (variableNode.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
20
|
+
if (!isReactHookCallWithNameAlias(name2, context, hookAlias)(variableNode)) return false;
|
|
21
|
+
return predicate(topLevelId, variableNode);
|
|
22
|
+
};
|
|
22
23
|
}
|
|
23
24
|
function isFromUseStateCall(context, settings) {
|
|
24
25
|
const predicate = (topLevelId, call) => {
|
|
@@ -49,8 +50,13 @@ function isSetFunctionCall(context, settings) {
|
|
|
49
50
|
if (!isAt || index == null) {
|
|
50
51
|
return false;
|
|
51
52
|
}
|
|
52
|
-
const
|
|
53
|
-
|
|
53
|
+
const indexScope = context.sourceCode.getScope(node);
|
|
54
|
+
const indexValue = VAR5.toResolved({
|
|
55
|
+
kind: "lazy",
|
|
56
|
+
node: index,
|
|
57
|
+
initialScope: indexScope
|
|
58
|
+
}).value;
|
|
59
|
+
return indexValue === 1 && isIdFromUseStateCall(callee.object);
|
|
54
60
|
}
|
|
55
61
|
// const [data, setData] = useState();
|
|
56
62
|
// setData();
|
|
@@ -63,8 +69,14 @@ function isSetFunctionCall(context, settings) {
|
|
|
63
69
|
if (!("name" in node.callee.object)) {
|
|
64
70
|
return false;
|
|
65
71
|
}
|
|
66
|
-
const
|
|
67
|
-
|
|
72
|
+
const property = node.callee.property;
|
|
73
|
+
const propertyScope = context.sourceCode.getScope(node);
|
|
74
|
+
const propertyValue = VAR5.toResolved({
|
|
75
|
+
kind: "lazy",
|
|
76
|
+
node: property,
|
|
77
|
+
initialScope: propertyScope
|
|
78
|
+
}).value;
|
|
79
|
+
return propertyValue === 1 && isIdFromUseStateCall(node.callee.object);
|
|
68
80
|
}
|
|
69
81
|
default: {
|
|
70
82
|
return false;
|
|
@@ -125,8 +137,8 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
125
137
|
const isUseCallbackCall2 = isReactHookCallWithNameAlias("useCallback", context, additionalHooks.useCallback ?? []);
|
|
126
138
|
const isSetStateCall = isSetFunctionCall(context, settings);
|
|
127
139
|
const isIdFromUseStateCall = isFromUseStateCall(context, settings);
|
|
128
|
-
const
|
|
129
|
-
const setupFunctionRef = { current:
|
|
140
|
+
const functionEntries = [];
|
|
141
|
+
const setupFunctionRef = { current: null };
|
|
130
142
|
const setupFunctionIdentifiers = [];
|
|
131
143
|
const indFunctionCalls = [];
|
|
132
144
|
const indSetStateCalls = /* @__PURE__ */ new WeakMap();
|
|
@@ -134,10 +146,12 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
134
146
|
const indSetStateCallsInUseEffectSetup = /* @__PURE__ */ new Map();
|
|
135
147
|
const indSetStateCallsInUseMemoOrCallback = /* @__PURE__ */ new WeakMap();
|
|
136
148
|
const onSetupFunctionEnter = (node) => {
|
|
137
|
-
setupFunctionRef.current =
|
|
149
|
+
setupFunctionRef.current = node;
|
|
138
150
|
};
|
|
139
151
|
const onSetupFunctionExit = (node) => {
|
|
140
|
-
|
|
152
|
+
if (setupFunctionRef.current === node) {
|
|
153
|
+
setupFunctionRef.current = null;
|
|
154
|
+
}
|
|
141
155
|
};
|
|
142
156
|
function isSetupFunction(node) {
|
|
143
157
|
return node.parent?.type === AST_NODE_TYPES.CallExpression && node.parent.callee !== node && isUseEffectLikeCall(node.parent);
|
|
@@ -146,33 +160,30 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
146
160
|
return match(node).when(isUseStateCall2, () => "useState").when(isUseEffectLikeCall, () => "useEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
|
|
147
161
|
}
|
|
148
162
|
function getFunctionKind(node) {
|
|
149
|
-
return match(node).when(isSetupFunction, () => "setup").when(
|
|
163
|
+
return match(node).when(isSetupFunction, () => "setup").when(AST.isFunctionOfImmediatelyInvoked, () => "immediate").otherwise(() => "other");
|
|
150
164
|
}
|
|
151
165
|
return {
|
|
152
166
|
":function"(node) {
|
|
153
167
|
const kind = getFunctionKind(node);
|
|
154
|
-
|
|
168
|
+
functionEntries.push({ kind, node });
|
|
155
169
|
if (kind === "setup") {
|
|
156
170
|
onSetupFunctionEnter(node);
|
|
157
171
|
}
|
|
158
172
|
},
|
|
159
173
|
":function:exit"(node) {
|
|
160
|
-
const { kind } =
|
|
174
|
+
const { kind } = functionEntries.at(-1) ?? {};
|
|
161
175
|
if (kind === "setup") {
|
|
162
176
|
onSetupFunctionExit(node);
|
|
163
177
|
}
|
|
164
|
-
|
|
178
|
+
functionEntries.pop();
|
|
165
179
|
},
|
|
166
180
|
CallExpression(node) {
|
|
167
|
-
const setupFunction =
|
|
168
|
-
const pEntry =
|
|
169
|
-
if (pEntry
|
|
181
|
+
const setupFunction = setupFunctionRef.current;
|
|
182
|
+
const pEntry = functionEntries.at(-1);
|
|
183
|
+
if (pEntry == null || pEntry.node.async) {
|
|
170
184
|
return;
|
|
171
185
|
}
|
|
172
186
|
match(getCallKind(node)).with("setState", () => {
|
|
173
|
-
if (pEntry == null) {
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
187
|
switch (true) {
|
|
177
188
|
case (pEntry.node === setupFunction || pEntry.kind === "immediate"): {
|
|
178
189
|
context.report({
|
|
@@ -185,28 +196,28 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
185
196
|
return;
|
|
186
197
|
}
|
|
187
198
|
default: {
|
|
188
|
-
const
|
|
189
|
-
if (
|
|
199
|
+
const variableDeclarator = AST.findParentNodeGuard(node, isVariableDeclaratorFromHookCall);
|
|
200
|
+
if (variableDeclarator == null) {
|
|
190
201
|
const calls = indSetStateCalls.get(pEntry.node) ?? [];
|
|
191
202
|
indSetStateCalls.set(pEntry.node, [...calls, node]);
|
|
192
203
|
return;
|
|
193
204
|
}
|
|
194
|
-
const
|
|
195
|
-
const prevs = indSetStateCallsInUseMemoOrCallback.get(
|
|
196
|
-
indSetStateCallsInUseMemoOrCallback.set(
|
|
205
|
+
const init = variableDeclarator.init;
|
|
206
|
+
const prevs = indSetStateCallsInUseMemoOrCallback.get(init) ?? [];
|
|
207
|
+
indSetStateCallsInUseMemoOrCallback.set(init, [...prevs, node]);
|
|
197
208
|
}
|
|
198
209
|
}
|
|
199
210
|
}).with("useEffect", () => {
|
|
200
|
-
if (
|
|
211
|
+
if (AST.isFunction(node.arguments.at(0))) {
|
|
201
212
|
return;
|
|
202
213
|
}
|
|
203
|
-
setupFunctionIdentifiers.push(...
|
|
214
|
+
setupFunctionIdentifiers.push(...AST.getNestedIdentifiers(node));
|
|
204
215
|
}).with("other", () => {
|
|
205
|
-
if (pEntry
|
|
216
|
+
if (pEntry.node !== setupFunction) {
|
|
206
217
|
return;
|
|
207
218
|
}
|
|
208
219
|
indFunctionCalls.push(node);
|
|
209
|
-
}).otherwise(
|
|
220
|
+
}).otherwise(() => _);
|
|
210
221
|
},
|
|
211
222
|
Identifier(node) {
|
|
212
223
|
if (node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node) {
|
|
@@ -224,11 +235,10 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
224
235
|
if (!isUseMemoCall2(parent)) {
|
|
225
236
|
break;
|
|
226
237
|
}
|
|
227
|
-
const
|
|
228
|
-
if (
|
|
238
|
+
const variableDeclarator = AST.findParentNodeGuard(parent, isVariableDeclaratorFromHookCall);
|
|
239
|
+
if (variableDeclarator == null) {
|
|
229
240
|
break;
|
|
230
241
|
}
|
|
231
|
-
const variableDeclarator = mbVariableDeclarator.value;
|
|
232
242
|
const calls = indSetStateCallsInUseEffectArg0.get(variableDeclarator.init) ?? [];
|
|
233
243
|
indSetStateCallsInUseEffectArg0.set(variableDeclarator.init, [...calls, node]);
|
|
234
244
|
break;
|
|
@@ -238,11 +248,10 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
238
248
|
break;
|
|
239
249
|
}
|
|
240
250
|
if (isUseCallbackCall2(node.parent)) {
|
|
241
|
-
const
|
|
242
|
-
if (
|
|
251
|
+
const variableDeclarator = AST.findParentNodeGuard(node.parent, isVariableDeclaratorFromHookCall);
|
|
252
|
+
if (variableDeclarator == null) {
|
|
243
253
|
break;
|
|
244
254
|
}
|
|
245
|
-
const variableDeclarator = mbVariableDeclarator.value;
|
|
246
255
|
const prevs = indSetStateCallsInUseEffectArg0.get(variableDeclarator.init) ?? [];
|
|
247
256
|
indSetStateCallsInUseEffectArg0.set(variableDeclarator.init, [...prevs, node]);
|
|
248
257
|
}
|
|
@@ -256,7 +265,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
256
265
|
},
|
|
257
266
|
"Program:exit"() {
|
|
258
267
|
const getSetStateCalls = (id, initialScope) => {
|
|
259
|
-
const node =
|
|
268
|
+
const node = VAR5.getVariableNode(VAR5.findVariable(id, initialScope), 0);
|
|
260
269
|
switch (node?.type) {
|
|
261
270
|
case AST_NODE_TYPES.ArrowFunctionExpression:
|
|
262
271
|
case AST_NODE_TYPES.FunctionDeclaration:
|
|
@@ -267,7 +276,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
267
276
|
}
|
|
268
277
|
return [];
|
|
269
278
|
};
|
|
270
|
-
for (const [
|
|
279
|
+
for (const [, calls] of indSetStateCallsInUseEffectSetup) {
|
|
271
280
|
for (const call of calls) {
|
|
272
281
|
context.report({
|
|
273
282
|
messageId: "noDirectSetStateInUseEffect",
|
|
@@ -287,7 +296,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
287
296
|
messageId: "noDirectSetStateInUseEffect",
|
|
288
297
|
node: setStateCall,
|
|
289
298
|
data: {
|
|
290
|
-
name:
|
|
299
|
+
name: AST.toReadableNodeName(setStateCall, (n) => context.sourceCode.getText(n))
|
|
291
300
|
}
|
|
292
301
|
});
|
|
293
302
|
}
|
|
@@ -299,7 +308,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
299
308
|
messageId: "noDirectSetStateInUseEffect",
|
|
300
309
|
node: setStateCall,
|
|
301
310
|
data: {
|
|
302
|
-
name:
|
|
311
|
+
name: AST.toReadableNodeName(setStateCall, (n) => context.sourceCode.getText(n))
|
|
303
312
|
}
|
|
304
313
|
});
|
|
305
314
|
}
|
|
@@ -342,8 +351,8 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
342
351
|
const isUseCallbackCall2 = isReactHookCallWithNameAlias("useCallback", context, additionalHooks.useCallback ?? []);
|
|
343
352
|
const isSetStateCall = isSetFunctionCall(context, settings);
|
|
344
353
|
const isIdFromUseStateCall = isFromUseStateCall(context, settings);
|
|
345
|
-
const
|
|
346
|
-
const setupFunctionRef = { current:
|
|
354
|
+
const functionEntries = [];
|
|
355
|
+
const setupFunctionRef = { current: null };
|
|
347
356
|
const setupFunctionIdentifiers = [];
|
|
348
357
|
const indFunctionCalls = [];
|
|
349
358
|
const indSetStateCalls = /* @__PURE__ */ new WeakMap();
|
|
@@ -351,10 +360,12 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
351
360
|
const indSetStateCallsInUseLayoutEffectSetup = /* @__PURE__ */ new Map();
|
|
352
361
|
const indSetStateCallsInUseMemoOrCallback = /* @__PURE__ */ new WeakMap();
|
|
353
362
|
const onSetupFunctionEnter = (node) => {
|
|
354
|
-
setupFunctionRef.current =
|
|
363
|
+
setupFunctionRef.current = node;
|
|
355
364
|
};
|
|
356
365
|
const onSetupFunctionExit = (node) => {
|
|
357
|
-
|
|
366
|
+
if (setupFunctionRef.current === node) {
|
|
367
|
+
setupFunctionRef.current = null;
|
|
368
|
+
}
|
|
358
369
|
};
|
|
359
370
|
function isSetupFunction(node) {
|
|
360
371
|
return node.parent?.type === AST_NODE_TYPES.CallExpression && node.parent.callee !== node && isUseLayoutEffectLikeCall(node.parent);
|
|
@@ -363,33 +374,30 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
363
374
|
return match(node).when(isUseStateCall2, () => "useState").when(isUseLayoutEffectLikeCall, () => "useLayoutEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
|
|
364
375
|
}
|
|
365
376
|
function getFunctionKind(node) {
|
|
366
|
-
return match(node).when(isSetupFunction, () => "setup").when(
|
|
377
|
+
return match(node).when(isSetupFunction, () => "setup").when(AST.isFunctionOfImmediatelyInvoked, () => "immediate").otherwise(() => "other");
|
|
367
378
|
}
|
|
368
379
|
return {
|
|
369
380
|
":function"(node) {
|
|
370
381
|
const kind = getFunctionKind(node);
|
|
371
|
-
|
|
382
|
+
functionEntries.push({ kind, node });
|
|
372
383
|
if (kind === "setup") {
|
|
373
384
|
onSetupFunctionEnter(node);
|
|
374
385
|
}
|
|
375
386
|
},
|
|
376
387
|
":function:exit"(node) {
|
|
377
|
-
const { kind } =
|
|
388
|
+
const { kind } = functionEntries.at(-1) ?? {};
|
|
378
389
|
if (kind === "setup") {
|
|
379
390
|
onSetupFunctionExit(node);
|
|
380
391
|
}
|
|
381
|
-
|
|
392
|
+
functionEntries.pop();
|
|
382
393
|
},
|
|
383
394
|
CallExpression(node) {
|
|
384
|
-
const setupFunction =
|
|
385
|
-
const pEntry =
|
|
386
|
-
if (pEntry
|
|
395
|
+
const setupFunction = setupFunctionRef.current;
|
|
396
|
+
const pEntry = functionEntries.at(-1);
|
|
397
|
+
if (pEntry == null || pEntry.node.async) {
|
|
387
398
|
return;
|
|
388
399
|
}
|
|
389
400
|
match(getCallKind(node)).with("setState", () => {
|
|
390
|
-
if (pEntry == null) {
|
|
391
|
-
return;
|
|
392
|
-
}
|
|
393
401
|
switch (true) {
|
|
394
402
|
case (pEntry.node === setupFunction || pEntry.kind === "immediate"): {
|
|
395
403
|
context.report({
|
|
@@ -402,28 +410,28 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
402
410
|
return;
|
|
403
411
|
}
|
|
404
412
|
default: {
|
|
405
|
-
const
|
|
406
|
-
if (
|
|
413
|
+
const variableDeclarator = AST.findParentNodeGuard(node, isVariableDeclaratorFromHookCall);
|
|
414
|
+
if (variableDeclarator == null) {
|
|
407
415
|
const calls = indSetStateCalls.get(pEntry.node) ?? [];
|
|
408
416
|
indSetStateCalls.set(pEntry.node, [...calls, node]);
|
|
409
417
|
return;
|
|
410
418
|
}
|
|
411
|
-
const
|
|
412
|
-
const prevs = indSetStateCallsInUseMemoOrCallback.get(
|
|
413
|
-
indSetStateCallsInUseMemoOrCallback.set(
|
|
419
|
+
const init = variableDeclarator.init;
|
|
420
|
+
const prevs = indSetStateCallsInUseMemoOrCallback.get(init) ?? [];
|
|
421
|
+
indSetStateCallsInUseMemoOrCallback.set(init, [...prevs, node]);
|
|
414
422
|
}
|
|
415
423
|
}
|
|
416
424
|
}).with("useLayoutEffect", () => {
|
|
417
|
-
if (
|
|
425
|
+
if (AST.isFunction(node.arguments.at(0))) {
|
|
418
426
|
return;
|
|
419
427
|
}
|
|
420
|
-
setupFunctionIdentifiers.push(...
|
|
428
|
+
setupFunctionIdentifiers.push(...AST.getNestedIdentifiers(node));
|
|
421
429
|
}).with("other", () => {
|
|
422
|
-
if (pEntry
|
|
430
|
+
if (pEntry.node !== setupFunction) {
|
|
423
431
|
return;
|
|
424
432
|
}
|
|
425
433
|
indFunctionCalls.push(node);
|
|
426
|
-
}).otherwise(
|
|
434
|
+
}).otherwise(() => _);
|
|
427
435
|
},
|
|
428
436
|
Identifier(node) {
|
|
429
437
|
if (node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node) {
|
|
@@ -441,11 +449,10 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
441
449
|
if (!isUseMemoCall2(parent)) {
|
|
442
450
|
break;
|
|
443
451
|
}
|
|
444
|
-
const
|
|
445
|
-
if (
|
|
452
|
+
const variableDeclarator = AST.findParentNodeGuard(parent, isVariableDeclaratorFromHookCall);
|
|
453
|
+
if (variableDeclarator == null) {
|
|
446
454
|
break;
|
|
447
455
|
}
|
|
448
|
-
const variableDeclarator = mbVariableDeclarator.value;
|
|
449
456
|
const calls = indSetStateCallsInUseLayoutEffectArg0.get(variableDeclarator.init) ?? [];
|
|
450
457
|
indSetStateCallsInUseLayoutEffectArg0.set(variableDeclarator.init, [...calls, node]);
|
|
451
458
|
break;
|
|
@@ -455,11 +462,10 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
455
462
|
break;
|
|
456
463
|
}
|
|
457
464
|
if (isUseCallbackCall2(node.parent)) {
|
|
458
|
-
const
|
|
459
|
-
if (
|
|
465
|
+
const variableDeclarator = AST.findParentNodeGuard(node.parent, isVariableDeclaratorFromHookCall);
|
|
466
|
+
if (variableDeclarator == null) {
|
|
460
467
|
break;
|
|
461
468
|
}
|
|
462
|
-
const variableDeclarator = mbVariableDeclarator.value;
|
|
463
469
|
const prevs = indSetStateCallsInUseLayoutEffectArg0.get(variableDeclarator.init) ?? [];
|
|
464
470
|
indSetStateCallsInUseLayoutEffectArg0.set(variableDeclarator.init, [...prevs, node]);
|
|
465
471
|
}
|
|
@@ -473,7 +479,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
473
479
|
},
|
|
474
480
|
"Program:exit"() {
|
|
475
481
|
const getSetStateCalls = (id, initialScope) => {
|
|
476
|
-
const node =
|
|
482
|
+
const node = VAR5.getVariableNode(VAR5.findVariable(id, initialScope), 0);
|
|
477
483
|
switch (node?.type) {
|
|
478
484
|
case AST_NODE_TYPES.ArrowFunctionExpression:
|
|
479
485
|
case AST_NODE_TYPES.FunctionDeclaration:
|
|
@@ -484,7 +490,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
484
490
|
}
|
|
485
491
|
return [];
|
|
486
492
|
};
|
|
487
|
-
for (const [
|
|
493
|
+
for (const [, calls] of indSetStateCallsInUseLayoutEffectSetup) {
|
|
488
494
|
for (const call of calls) {
|
|
489
495
|
context.report({
|
|
490
496
|
messageId: "noDirectSetStateInUseLayoutEffect",
|
|
@@ -504,7 +510,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
504
510
|
messageId: "noDirectSetStateInUseLayoutEffect",
|
|
505
511
|
node: setStateCall,
|
|
506
512
|
data: {
|
|
507
|
-
name:
|
|
513
|
+
name: AST.toReadableNodeName(setStateCall, (n) => context.sourceCode.getText(n))
|
|
508
514
|
}
|
|
509
515
|
});
|
|
510
516
|
}
|
|
@@ -516,7 +522,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
516
522
|
messageId: "noDirectSetStateInUseLayoutEffect",
|
|
517
523
|
node: setStateCall,
|
|
518
524
|
data: {
|
|
519
|
-
name:
|
|
525
|
+
name: AST.toReadableNodeName(setStateCall, (n) => context.sourceCode.getText(n))
|
|
520
526
|
}
|
|
521
527
|
});
|
|
522
528
|
}
|
|
@@ -559,43 +565,41 @@ var no_unnecessary_use_callback_default = createRule({
|
|
|
559
565
|
}
|
|
560
566
|
const scope = context.sourceCode.getScope(node);
|
|
561
567
|
const component = scope.block;
|
|
562
|
-
if (!
|
|
568
|
+
if (!AST.isFunction(component)) {
|
|
563
569
|
return;
|
|
564
570
|
}
|
|
565
571
|
const [arg0, arg1] = node.arguments;
|
|
566
572
|
if (arg0 == null || arg1 == null) {
|
|
567
573
|
return;
|
|
568
574
|
}
|
|
569
|
-
const hasEmptyDeps =
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
O.exists((x) => x.elements.length === 0)
|
|
578
|
-
);
|
|
575
|
+
const hasEmptyDeps = match(arg1).with({ type: AST_NODE_TYPES.ArrayExpression }, (n) => n.elements.length === 0).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
576
|
+
const variable = VAR5.findVariable(n.name, initialScope);
|
|
577
|
+
const variableNode = VAR5.getVariableNode(variable, 0);
|
|
578
|
+
if (variableNode?.type !== AST_NODE_TYPES.ArrayExpression) {
|
|
579
|
+
return false;
|
|
580
|
+
}
|
|
581
|
+
return variableNode.elements.length === 0;
|
|
582
|
+
}).otherwise(() => false);
|
|
579
583
|
if (!hasEmptyDeps) {
|
|
580
584
|
return;
|
|
581
585
|
}
|
|
582
|
-
const
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
);
|
|
586
|
+
const arg0Node = match(arg0).with({ type: AST_NODE_TYPES.ArrowFunctionExpression }, (n) => {
|
|
587
|
+
if (n.body.type === AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
588
|
+
return n.body;
|
|
589
|
+
}
|
|
590
|
+
return n;
|
|
591
|
+
}).with({ type: AST_NODE_TYPES.FunctionExpression }, identity).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
592
|
+
const variable = VAR5.findVariable(n.name, initialScope);
|
|
593
|
+
const variableNode = VAR5.getVariableNode(variable, 0);
|
|
594
|
+
if (variableNode?.type !== AST_NODE_TYPES.ArrowFunctionExpression && variableNode?.type !== AST_NODE_TYPES.FunctionExpression) {
|
|
595
|
+
return _;
|
|
596
|
+
}
|
|
597
|
+
return variableNode;
|
|
598
|
+
}).otherwise(() => _);
|
|
599
|
+
if (arg0Node == null) return;
|
|
600
|
+
const arg0NodeScope = context.sourceCode.getScope(arg0Node);
|
|
601
|
+
const arg0NodeReferences = VAR5.getChidScopes(arg0NodeScope).flatMap((x) => x.references);
|
|
602
|
+
const isReferencedToComponentScope = arg0NodeReferences.some((x) => x.resolved?.scope.block === component);
|
|
599
603
|
if (!isReferencedToComponentScope) {
|
|
600
604
|
context.report({
|
|
601
605
|
messageId: "noUnnecessaryUseCallback",
|
|
@@ -640,51 +644,45 @@ var no_unnecessary_use_memo_default = createRule({
|
|
|
640
644
|
}
|
|
641
645
|
const scope = context.sourceCode.getScope(node);
|
|
642
646
|
const component = scope.block;
|
|
643
|
-
if (!
|
|
647
|
+
if (!AST.isFunction(component)) {
|
|
644
648
|
return;
|
|
645
649
|
}
|
|
646
650
|
const [arg0, arg1] = node.arguments;
|
|
647
651
|
if (arg0 == null || arg1 == null) {
|
|
648
652
|
return;
|
|
649
653
|
}
|
|
650
|
-
const hasCallInArg0 =
|
|
651
|
-
O.some(arg0),
|
|
652
|
-
O.filter((n) => AST2.isFunction(n)),
|
|
653
|
-
O.exists((n) => [...AST2.getNestedCallExpressions(n.body), ...AST2.getNestedNewExpressions(n.body)].length > 0)
|
|
654
|
-
);
|
|
654
|
+
const hasCallInArg0 = AST.isFunction(arg0) && [...AST.getNestedCallExpressions(arg0.body), ...AST.getNestedNewExpressions(arg0.body)].length > 0;
|
|
655
655
|
if (hasCallInArg0) {
|
|
656
656
|
return;
|
|
657
657
|
}
|
|
658
|
-
const hasEmptyDeps =
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
O.exists((x) => x.elements.length === 0)
|
|
667
|
-
);
|
|
658
|
+
const hasEmptyDeps = match(arg1).with({ type: AST_NODE_TYPES.ArrayExpression }, (n) => n.elements.length === 0).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
659
|
+
const variable = VAR5.findVariable(n.name, initialScope);
|
|
660
|
+
const variableNode = VAR5.getVariableNode(variable, 0);
|
|
661
|
+
if (variableNode?.type !== AST_NODE_TYPES.ArrayExpression) {
|
|
662
|
+
return false;
|
|
663
|
+
}
|
|
664
|
+
return variableNode.elements.length === 0;
|
|
665
|
+
}).otherwise(() => false);
|
|
668
666
|
if (!hasEmptyDeps) {
|
|
669
667
|
return;
|
|
670
668
|
}
|
|
671
|
-
const
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
);
|
|
669
|
+
const arg0Node = match(arg0).with({ type: AST_NODE_TYPES.ArrowFunctionExpression }, (n) => {
|
|
670
|
+
if (n.body.type === AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
671
|
+
return n.body;
|
|
672
|
+
}
|
|
673
|
+
return n;
|
|
674
|
+
}).with({ type: AST_NODE_TYPES.FunctionExpression }, identity).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
675
|
+
const variable = VAR5.findVariable(n.name, initialScope);
|
|
676
|
+
const variableNode = VAR5.getVariableNode(variable, 0);
|
|
677
|
+
if (variableNode?.type !== AST_NODE_TYPES.ArrowFunctionExpression && variableNode?.type !== AST_NODE_TYPES.FunctionExpression) {
|
|
678
|
+
return _;
|
|
679
|
+
}
|
|
680
|
+
return variableNode;
|
|
681
|
+
}).otherwise(() => _);
|
|
682
|
+
if (arg0Node == null) return;
|
|
683
|
+
const arg0NodeScope = context.sourceCode.getScope(arg0Node);
|
|
684
|
+
const arg0NodeReferences = VAR5.getChidScopes(arg0NodeScope).flatMap((x) => x.references);
|
|
685
|
+
const isReferencedToComponentScope = arg0NodeReferences.some((x) => x.resolved?.scope.block === component);
|
|
688
686
|
if (!isReferencedToComponentScope) {
|
|
689
687
|
context.report({
|
|
690
688
|
messageId: "noUnnecessaryUseMemo",
|
|
@@ -723,7 +721,7 @@ var no_useless_custom_hooks_default = createRule({
|
|
|
723
721
|
"Program:exit"(node) {
|
|
724
722
|
const allHooks = ctx.getAllHooks(node);
|
|
725
723
|
for (const { name: name2, node: node2, hookCalls } of allHooks.values()) {
|
|
726
|
-
if (
|
|
724
|
+
if (AST.isEmptyFunction(node2)) {
|
|
727
725
|
continue;
|
|
728
726
|
}
|
|
729
727
|
if (hookCalls.length > 0) {
|
|
@@ -736,7 +734,7 @@ var no_useless_custom_hooks_default = createRule({
|
|
|
736
734
|
messageId: "noUselessCustomHooks",
|
|
737
735
|
node: node2,
|
|
738
736
|
data: {
|
|
739
|
-
name: name2
|
|
737
|
+
name: name2
|
|
740
738
|
}
|
|
741
739
|
});
|
|
742
740
|
}
|
|
@@ -780,11 +778,11 @@ var prefer_use_state_lazy_initialization_default = createRule({
|
|
|
780
778
|
if (useStateInput == null) {
|
|
781
779
|
return;
|
|
782
780
|
}
|
|
783
|
-
const nestedCallExpressions =
|
|
781
|
+
const nestedCallExpressions = AST.getNestedCallExpressions(useStateInput);
|
|
784
782
|
const hasFunctionCall = nestedCallExpressions.some((n) => {
|
|
785
783
|
return "name" in n.callee && !ALLOW_LIST.includes(n.callee.name);
|
|
786
784
|
});
|
|
787
|
-
const hasNewCall =
|
|
785
|
+
const hasNewCall = AST.getNestedNewExpressions(useStateInput).some((n) => {
|
|
788
786
|
return "name" in n.callee && !ALLOW_LIST.includes(n.callee.name);
|
|
789
787
|
});
|
|
790
788
|
if (!hasFunctionCall && !hasNewCall) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-hooks-extra",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.24.0-beta.1",
|
|
4
4
|
"description": "ESLint React's ESLint plugin for React Hooks related rules.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
"eslint-plugin",
|
|
12
12
|
"eslint-plugin-react-hooks-extra"
|
|
13
13
|
],
|
|
14
|
-
"homepage": "https://github.com/
|
|
14
|
+
"homepage": "https://github.com/Rel1cx/eslint-react",
|
|
15
15
|
"bugs": {
|
|
16
|
-
"url": "https://github.com/
|
|
16
|
+
"url": "https://github.com/Rel1cx/eslint-react/issues"
|
|
17
17
|
},
|
|
18
18
|
"repository": {
|
|
19
19
|
"type": "git",
|
|
20
|
-
"url": "git+https://github.com/
|
|
20
|
+
"url": "git+https://github.com/Rel1cx/eslint-react.git",
|
|
21
21
|
"directory": "packages/plugins/eslint-plugin-react-hooks-extra"
|
|
22
22
|
},
|
|
23
23
|
"license": "MIT",
|
|
@@ -48,17 +48,17 @@
|
|
|
48
48
|
"@typescript-eslint/utils": "^8.19.1",
|
|
49
49
|
"string-ts": "^2.2.0",
|
|
50
50
|
"ts-pattern": "^5.6.0",
|
|
51
|
-
"@eslint-react/ast": "1.
|
|
52
|
-
"@eslint-react/
|
|
53
|
-
"@eslint-react/
|
|
54
|
-
"@eslint-react/shared": "1.
|
|
55
|
-
"@eslint-react/
|
|
56
|
-
"@eslint-react/
|
|
57
|
-
"@eslint-react/
|
|
51
|
+
"@eslint-react/ast": "1.24.0-beta.1",
|
|
52
|
+
"@eslint-react/eff": "1.24.0-beta.1",
|
|
53
|
+
"@eslint-react/jsx": "1.24.0-beta.1",
|
|
54
|
+
"@eslint-react/shared": "1.24.0-beta.1",
|
|
55
|
+
"@eslint-react/var": "1.24.0-beta.1",
|
|
56
|
+
"@eslint-react/core": "1.24.0-beta.1",
|
|
57
|
+
"@eslint-react/types": "1.24.0-beta.1"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@types/react": "^19.0.
|
|
61
|
-
"@types/react-dom": "^19.0.
|
|
60
|
+
"@types/react": "^19.0.5",
|
|
61
|
+
"@types/react-dom": "^19.0.3",
|
|
62
62
|
"tsup": "^8.3.5",
|
|
63
63
|
"@workspace/configs": "0.0.0"
|
|
64
64
|
},
|