eslint-plugin-react-hooks-extra 1.48.3 → 2.0.0-next.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.d.ts CHANGED
@@ -17,11 +17,6 @@ declare const _default: {
17
17
  readonly "no-unnecessary-use-memo": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnnecessaryUseMemo", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
18
18
  readonly "no-unnecessary-use-prefix": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnnecessaryUsePrefix", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
19
19
  readonly "prefer-use-state-lazy-initialization": _typescript_eslint_utils_ts_eslint.RuleModule<"preferUseStateLazyInitialization", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
20
- readonly "ensure-custom-hooks-using-other-hooks": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnnecessaryUsePrefix", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
21
- readonly "ensure-use-callback-has-non-empty-deps": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnnecessaryUseCallback", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
22
- readonly "ensure-use-memo-has-non-empty-deps": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnnecessaryUseMemo", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
23
- readonly "no-redundant-custom-hook": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnnecessaryUsePrefix", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
24
- readonly "no-useless-custom-hooks": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnnecessaryUsePrefix", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
25
20
  };
26
21
  };
27
22
  };
@@ -44,11 +39,6 @@ declare const _default: {
44
39
  readonly "no-unnecessary-use-memo": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnnecessaryUseMemo", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
45
40
  readonly "no-unnecessary-use-prefix": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnnecessaryUsePrefix", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
46
41
  readonly "prefer-use-state-lazy-initialization": _typescript_eslint_utils_ts_eslint.RuleModule<"preferUseStateLazyInitialization", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
47
- readonly "ensure-custom-hooks-using-other-hooks": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnnecessaryUsePrefix", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
48
- readonly "ensure-use-callback-has-non-empty-deps": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnnecessaryUseCallback", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
49
- readonly "ensure-use-memo-has-non-empty-deps": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnnecessaryUseMemo", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
50
- readonly "no-redundant-custom-hook": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnnecessaryUsePrefix", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
51
- readonly "no-useless-custom-hooks": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnnecessaryUsePrefix", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
52
42
  };
53
43
  };
54
44
 
package/dist/index.js CHANGED
@@ -1,35 +1,11 @@
1
- 'use strict';
2
-
3
- var AST = require('@eslint-react/ast');
4
- var ER7 = require('@eslint-react/core');
5
- var eff = require('@eslint-react/eff');
6
- var shared = require('@eslint-react/shared');
7
- var VAR4 = require('@eslint-react/var');
8
- var types = require('@typescript-eslint/types');
9
- var tsPattern = require('ts-pattern');
10
- var utils = require('@typescript-eslint/utils');
11
-
12
- function _interopNamespace(e) {
13
- if (e && e.__esModule) return e;
14
- var n = Object.create(null);
15
- if (e) {
16
- Object.keys(e).forEach(function (k) {
17
- if (k !== 'default') {
18
- var d = Object.getOwnPropertyDescriptor(e, k);
19
- Object.defineProperty(n, k, d.get ? d : {
20
- enumerable: true,
21
- get: function () { return e[k]; }
22
- });
23
- }
24
- });
25
- }
26
- n.default = e;
27
- return Object.freeze(n);
28
- }
29
-
30
- var AST__namespace = /*#__PURE__*/_interopNamespace(AST);
31
- var ER7__namespace = /*#__PURE__*/_interopNamespace(ER7);
32
- var VAR4__namespace = /*#__PURE__*/_interopNamespace(VAR4);
1
+ import * as AST from '@eslint-react/ast';
2
+ import * as ER7 from '@eslint-react/core';
3
+ import { identity, getOrElseUpdate, constVoid, constTrue } from '@eslint-react/eff';
4
+ import { getDocsUrl, getSettingsFromContext } from '@eslint-react/shared';
5
+ import * as VAR4 from '@eslint-react/var';
6
+ import { AST_NODE_TYPES } from '@typescript-eslint/types';
7
+ import { match } from 'ts-pattern';
8
+ import { ESLintUtils } from '@typescript-eslint/utils';
33
9
 
34
10
  var __defProp = Object.defineProperty;
35
11
  var __export = (target, all) => {
@@ -52,31 +28,31 @@ var rules = {
52
28
 
53
29
  // package.json
54
30
  var name2 = "eslint-plugin-react-hooks-extra";
55
- var version = "1.48.3";
56
- var createRule = utils.ESLintUtils.RuleCreator(shared.getDocsUrl("hooks-extra"));
57
- function isFromHookCall(context, name3, settings, predicate = eff.constTrue) {
31
+ var version = "2.0.0-next.1";
32
+ var createRule = ESLintUtils.RuleCreator(getDocsUrl("hooks-extra"));
33
+ function isFromHookCall(context, name3, settings, predicate = constTrue) {
58
34
  const hookAlias = settings.additionalHooks[name3] ?? [];
59
35
  return (topLevelId) => {
60
- const variable = VAR4__namespace.findVariable(topLevelId, context.sourceCode.getScope(topLevelId));
61
- const variableNode = VAR4__namespace.getVariableInitNode(variable, 0);
36
+ const variable = VAR4.findVariable(topLevelId, context.sourceCode.getScope(topLevelId));
37
+ const variableNode = VAR4.getVariableInitNode(variable, 0);
62
38
  if (variableNode == null) return false;
63
- if (variableNode.type !== types.AST_NODE_TYPES.CallExpression) return false;
64
- if (!ER7__namespace.isReactHookCallWithNameAlias(context, name3, hookAlias)(variableNode)) return false;
39
+ if (variableNode.type !== AST_NODE_TYPES.CallExpression) return false;
40
+ if (!ER7.isReactHookCallWithNameAlias(context, name3, hookAlias)(variableNode)) return false;
65
41
  return predicate(topLevelId, variableNode);
66
42
  };
67
43
  }
68
44
  function isFromUseStateCall(context, settings) {
69
45
  const predicate = (topLevelId, call) => {
70
46
  const { parent } = call;
71
- if (!("id" in parent) || parent.id?.type !== types.AST_NODE_TYPES.ArrayPattern) {
47
+ if (!("id" in parent) || parent.id?.type !== AST_NODE_TYPES.ArrayPattern) {
72
48
  return true;
73
49
  }
74
- return parent.id.elements.findIndex((e) => e?.type === types.AST_NODE_TYPES.Identifier && e.name === topLevelId.name) === 1;
50
+ return parent.id.elements.findIndex((e) => e?.type === AST_NODE_TYPES.Identifier && e.name === topLevelId.name) === 1;
75
51
  };
76
52
  return isFromHookCall(context, "useState", settings, predicate);
77
53
  }
78
54
  function isFunctionOfImmediatelyInvoked(node) {
79
- return node.type !== types.AST_NODE_TYPES.FunctionDeclaration && node.parent.type === types.AST_NODE_TYPES.CallExpression && node.parent.callee === node;
55
+ return node.type !== AST_NODE_TYPES.FunctionDeclaration && node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node;
80
56
  }
81
57
  function isSetFunctionCall(context, settings) {
82
58
  const isIdFromUseStateCall = isFromUseStateCall(context, settings);
@@ -84,21 +60,21 @@ function isSetFunctionCall(context, settings) {
84
60
  switch (node.callee.type) {
85
61
  // const data = useState();
86
62
  // data.at(1)();
87
- case types.AST_NODE_TYPES.CallExpression: {
63
+ case AST_NODE_TYPES.CallExpression: {
88
64
  const { callee } = node.callee;
89
- if (callee.type !== types.AST_NODE_TYPES.MemberExpression) {
65
+ if (callee.type !== AST_NODE_TYPES.MemberExpression) {
90
66
  return false;
91
67
  }
92
68
  if (!("name" in callee.object)) {
93
69
  return false;
94
70
  }
95
- const isAt = callee.property.type === types.AST_NODE_TYPES.Identifier && callee.property.name === "at";
71
+ const isAt = callee.property.type === AST_NODE_TYPES.Identifier && callee.property.name === "at";
96
72
  const [index] = node.callee.arguments;
97
73
  if (!isAt || index == null) {
98
74
  return false;
99
75
  }
100
76
  const indexScope = context.sourceCode.getScope(node);
101
- const indexValue = VAR4__namespace.toStaticValue({
77
+ const indexValue = VAR4.toStaticValue({
102
78
  kind: "lazy",
103
79
  node: index,
104
80
  initialScope: indexScope
@@ -107,18 +83,18 @@ function isSetFunctionCall(context, settings) {
107
83
  }
108
84
  // const [data, setData] = useState();
109
85
  // setData();
110
- case types.AST_NODE_TYPES.Identifier: {
86
+ case AST_NODE_TYPES.Identifier: {
111
87
  return isIdFromUseStateCall(node.callee);
112
88
  }
113
89
  // const data = useState();
114
90
  // data[1]();
115
- case types.AST_NODE_TYPES.MemberExpression: {
91
+ case AST_NODE_TYPES.MemberExpression: {
116
92
  if (!("name" in node.callee.object)) {
117
93
  return false;
118
94
  }
119
95
  const property = node.callee.property;
120
96
  const propertyScope = context.sourceCode.getScope(node);
121
- const propertyValue = VAR4__namespace.toStaticValue({
97
+ const propertyValue = VAR4.toStaticValue({
122
98
  kind: "lazy",
123
99
  node: property,
124
100
  initialScope: propertyScope
@@ -132,23 +108,23 @@ function isSetFunctionCall(context, settings) {
132
108
  };
133
109
  }
134
110
  function isThenCall(node) {
135
- return node.callee.type === types.AST_NODE_TYPES.MemberExpression && node.callee.property.type === types.AST_NODE_TYPES.Identifier && node.callee.property.name === "then";
111
+ return node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.property.type === AST_NODE_TYPES.Identifier && node.callee.property.name === "then";
136
112
  }
137
113
  function isVariableDeclaratorFromHookCall(node) {
138
- if (node.type !== types.AST_NODE_TYPES.VariableDeclarator) {
114
+ if (node.type !== AST_NODE_TYPES.VariableDeclarator) {
139
115
  return false;
140
116
  }
141
- if (node.id.type !== types.AST_NODE_TYPES.Identifier) {
117
+ if (node.id.type !== AST_NODE_TYPES.Identifier) {
142
118
  return false;
143
119
  }
144
- if (node.init?.type !== types.AST_NODE_TYPES.CallExpression) {
120
+ if (node.init?.type !== AST_NODE_TYPES.CallExpression) {
145
121
  return false;
146
122
  }
147
123
  switch (node.init.callee.type) {
148
- case types.AST_NODE_TYPES.Identifier:
149
- return ER7__namespace.isReactHookName(node.init.callee.name);
150
- case types.AST_NODE_TYPES.MemberExpression:
151
- return node.init.callee.property.type === types.AST_NODE_TYPES.Identifier && ER7__namespace.isReactHookName(node.init.callee.property.name);
124
+ case AST_NODE_TYPES.Identifier:
125
+ return ER7.isReactHookName(node.init.callee.name);
126
+ case AST_NODE_TYPES.MemberExpression:
127
+ return node.init.callee.property.type === AST_NODE_TYPES.Identifier && ER7.isReactHookName(node.init.callee.property.name);
152
128
  default:
153
129
  return false;
154
130
  }
@@ -157,13 +133,13 @@ function isVariableDeclaratorFromHookCall(node) {
157
133
  // src/hooks/use-no-direct-set-state-in-use-effect.ts
158
134
  function useNoDirectSetStateInUseEffect(context, options) {
159
135
  const { onViolation, useEffectKind } = options;
160
- const settings = shared.getSettingsFromContext(context);
136
+ const settings = getSettingsFromContext(context);
161
137
  const hooks = settings.additionalHooks;
162
138
  const getText = (n) => context.sourceCode.getText(n);
163
- const isUseEffectLikeCall = ER7__namespace.isReactHookCallWithNameAlias(context, useEffectKind, hooks[useEffectKind]);
164
- const isUseStateCall = ER7__namespace.isReactHookCallWithNameAlias(context, "useState", hooks.useState);
165
- const isUseMemoCall = ER7__namespace.isReactHookCallWithNameAlias(context, "useMemo", hooks.useMemo);
166
- const isUseCallbackCall = ER7__namespace.isReactHookCallWithNameAlias(context, "useCallback", hooks.useCallback);
139
+ const isUseEffectLikeCall = ER7.isReactHookCallWithNameAlias(context, useEffectKind, hooks[useEffectKind]);
140
+ const isUseStateCall = ER7.isReactHookCallWithNameAlias(context, "useState", hooks.useState);
141
+ const isUseMemoCall = ER7.isReactHookCallWithNameAlias(context, "useMemo", hooks.useMemo);
142
+ const isUseCallbackCall = ER7.isReactHookCallWithNameAlias(context, "useCallback", hooks.useCallback);
167
143
  const isSetStateCall = isSetFunctionCall(context, settings);
168
144
  const isIdFromUseStateCall = isFromUseStateCall(context, settings);
169
145
  const functionEntries = [];
@@ -183,19 +159,19 @@ function useNoDirectSetStateInUseEffect(context, options) {
183
159
  }
184
160
  };
185
161
  function isFunctionOfUseEffectSetup(node) {
186
- return node.parent?.type === types.AST_NODE_TYPES.CallExpression && node.parent.callee !== node && isUseEffectLikeCall(node.parent);
162
+ return node.parent?.type === AST_NODE_TYPES.CallExpression && node.parent.callee !== node && isUseEffectLikeCall(node.parent);
187
163
  }
188
164
  function getCallName(node) {
189
- if (node.type === types.AST_NODE_TYPES.CallExpression) {
190
- return AST__namespace.toString(node.callee, getText);
165
+ if (node.type === AST_NODE_TYPES.CallExpression) {
166
+ return AST.toString(node.callee, getText);
191
167
  }
192
- return AST__namespace.toString(node, getText);
168
+ return AST.toString(node, getText);
193
169
  }
194
170
  function getCallKind(node) {
195
- return tsPattern.match(node).when(isUseStateCall, () => "useState").when(isUseEffectLikeCall, () => useEffectKind).when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
171
+ return match(node).when(isUseStateCall, () => "useState").when(isUseEffectLikeCall, () => useEffectKind).when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
196
172
  }
197
173
  function getFunctionKind(node) {
198
- return tsPattern.match(node).when(isFunctionOfUseEffectSetup, () => "setup").when(isFunctionOfImmediatelyInvoked, () => "immediate").otherwise(() => "other");
174
+ return match(node).when(isFunctionOfUseEffectSetup, () => "setup").when(isFunctionOfImmediatelyInvoked, () => "immediate").otherwise(() => "other");
199
175
  }
200
176
  return {
201
177
  ":function"(node) {
@@ -218,77 +194,77 @@ function useNoDirectSetStateInUseEffect(context, options) {
218
194
  if (pEntry == null || pEntry.node.async) {
219
195
  return;
220
196
  }
221
- tsPattern.match(getCallKind(node)).with("setState", () => {
197
+ match(getCallKind(node)).with("setState", () => {
222
198
  switch (true) {
223
199
  case pEntry.node === setupFunction:
224
- case (pEntry.kind === "immediate" && AST__namespace.findParentNode(pEntry.node, AST__namespace.isFunction) === setupFunction): {
200
+ case (pEntry.kind === "immediate" && AST.findParentNode(pEntry.node, AST.isFunction) === setupFunction): {
225
201
  onViolation(context, node, {
226
202
  name: context.sourceCode.getText(node.callee)
227
203
  });
228
204
  return;
229
205
  }
230
206
  default: {
231
- const vd = AST__namespace.findParentNode(node, isVariableDeclaratorFromHookCall);
232
- if (vd == null) eff.getOrElseUpdate(indSetStateCalls, pEntry.node, () => []).push(node);
233
- else eff.getOrElseUpdate(indSetStateCallsInUseMemoOrCallback, vd.init, () => []).push(node);
207
+ const vd = AST.findParentNode(node, isVariableDeclaratorFromHookCall);
208
+ if (vd == null) getOrElseUpdate(indSetStateCalls, pEntry.node, () => []).push(node);
209
+ else getOrElseUpdate(indSetStateCallsInUseMemoOrCallback, vd.init, () => []).push(node);
234
210
  }
235
211
  }
236
212
  }).with(useEffectKind, () => {
237
- if (AST__namespace.isFunction(node.arguments.at(0))) return;
238
- setupFunctionIdentifiers.push(...AST__namespace.getNestedIdentifiers(node));
213
+ if (AST.isFunction(node.arguments.at(0))) return;
214
+ setupFunctionIdentifiers.push(...AST.getNestedIdentifiers(node));
239
215
  }).with("other", () => {
240
216
  if (pEntry.node !== setupFunction) return;
241
217
  indFunctionCalls.push(node);
242
- }).otherwise(eff.constVoid);
218
+ }).otherwise(constVoid);
243
219
  },
244
220
  Identifier(node) {
245
- if (node.parent.type === types.AST_NODE_TYPES.CallExpression && node.parent.callee === node) {
221
+ if (node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node) {
246
222
  return;
247
223
  }
248
224
  if (!isIdFromUseStateCall(node)) {
249
225
  return;
250
226
  }
251
227
  switch (node.parent.type) {
252
- case types.AST_NODE_TYPES.ArrowFunctionExpression: {
228
+ case AST_NODE_TYPES.ArrowFunctionExpression: {
253
229
  const parent = node.parent.parent;
254
- if (parent.type !== types.AST_NODE_TYPES.CallExpression) {
230
+ if (parent.type !== AST_NODE_TYPES.CallExpression) {
255
231
  break;
256
232
  }
257
233
  if (!isUseMemoCall(parent)) {
258
234
  break;
259
235
  }
260
- const vd = AST__namespace.findParentNode(parent, isVariableDeclaratorFromHookCall);
236
+ const vd = AST.findParentNode(parent, isVariableDeclaratorFromHookCall);
261
237
  if (vd != null) {
262
- eff.getOrElseUpdate(indSetStateCallsInUseEffectArg0, vd.init, () => []).push(node);
238
+ getOrElseUpdate(indSetStateCallsInUseEffectArg0, vd.init, () => []).push(node);
263
239
  }
264
240
  break;
265
241
  }
266
- case types.AST_NODE_TYPES.CallExpression: {
242
+ case AST_NODE_TYPES.CallExpression: {
267
243
  if (node !== node.parent.arguments.at(0)) {
268
244
  break;
269
245
  }
270
246
  if (isUseCallbackCall(node.parent)) {
271
- const vd = AST__namespace.findParentNode(node.parent, isVariableDeclaratorFromHookCall);
247
+ const vd = AST.findParentNode(node.parent, isVariableDeclaratorFromHookCall);
272
248
  if (vd != null) {
273
- eff.getOrElseUpdate(indSetStateCallsInUseEffectArg0, vd.init, () => []).push(node);
249
+ getOrElseUpdate(indSetStateCallsInUseEffectArg0, vd.init, () => []).push(node);
274
250
  }
275
251
  break;
276
252
  }
277
253
  if (isUseEffectLikeCall(node.parent)) {
278
- eff.getOrElseUpdate(indSetStateCallsInUseEffectSetup, node.parent, () => []).push(node);
254
+ getOrElseUpdate(indSetStateCallsInUseEffectSetup, node.parent, () => []).push(node);
279
255
  }
280
256
  }
281
257
  }
282
258
  },
283
259
  "Program:exit"() {
284
260
  const getSetStateCalls = (id, initialScope) => {
285
- const node = VAR4__namespace.getVariableInitNode(VAR4__namespace.findVariable(id, initialScope), 0);
261
+ const node = VAR4.getVariableInitNode(VAR4.findVariable(id, initialScope), 0);
286
262
  switch (node?.type) {
287
- case types.AST_NODE_TYPES.ArrowFunctionExpression:
288
- case types.AST_NODE_TYPES.FunctionDeclaration:
289
- case types.AST_NODE_TYPES.FunctionExpression:
263
+ case AST_NODE_TYPES.ArrowFunctionExpression:
264
+ case AST_NODE_TYPES.FunctionDeclaration:
265
+ case AST_NODE_TYPES.FunctionExpression:
290
266
  return indSetStateCalls.get(node) ?? [];
291
- case types.AST_NODE_TYPES.CallExpression:
267
+ case AST_NODE_TYPES.CallExpression:
292
268
  return indSetStateCallsInUseMemoOrCallback.get(node) ?? indSetStateCallsInUseEffectArg0.get(node) ?? [];
293
269
  }
294
270
  return [];
@@ -405,11 +381,11 @@ var no_unnecessary_use_callback_default = createRule({
405
381
  });
406
382
  function create3(context) {
407
383
  if (!context.sourceCode.text.includes("use")) return {};
408
- const alias = shared.getSettingsFromContext(context).additionalHooks.useCallback ?? [];
409
- const isUseCallbackCall = ER7__namespace.isReactHookCallWithNameAlias(context, "useCallback", alias);
384
+ const alias = getSettingsFromContext(context).additionalHooks.useCallback ?? [];
385
+ const isUseCallbackCall = ER7.isReactHookCallWithNameAlias(context, "useCallback", alias);
410
386
  return {
411
387
  CallExpression(node) {
412
- if (!ER7__namespace.isReactHookCall(node)) {
388
+ if (!ER7.isReactHookCall(node)) {
413
389
  return;
414
390
  }
415
391
  const initialScope = context.sourceCode.getScope(node);
@@ -418,17 +394,17 @@ function create3(context) {
418
394
  }
419
395
  const scope = context.sourceCode.getScope(node);
420
396
  const component = scope.block;
421
- if (!AST__namespace.isFunction(component)) {
397
+ if (!AST.isFunction(component)) {
422
398
  return;
423
399
  }
424
400
  const [arg0, arg1] = node.arguments;
425
401
  if (arg0 == null || arg1 == null) {
426
402
  return;
427
403
  }
428
- 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) => {
429
- const variable = VAR4__namespace.findVariable(n.name, initialScope);
430
- const variableNode = VAR4__namespace.getVariableInitNode(variable, 0);
431
- if (variableNode?.type !== types.AST_NODE_TYPES.ArrayExpression) {
404
+ const hasEmptyDeps = match(arg1).with({ type: AST_NODE_TYPES.ArrayExpression }, (n) => n.elements.length === 0).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
405
+ const variable = VAR4.findVariable(n.name, initialScope);
406
+ const variableNode = VAR4.getVariableInitNode(variable, 0);
407
+ if (variableNode?.type !== AST_NODE_TYPES.ArrayExpression) {
432
408
  return false;
433
409
  }
434
410
  return variableNode.elements.length === 0;
@@ -436,22 +412,22 @@ function create3(context) {
436
412
  if (!hasEmptyDeps) {
437
413
  return;
438
414
  }
439
- const arg0Node = tsPattern.match(arg0).with({ type: types.AST_NODE_TYPES.ArrowFunctionExpression }, (n) => {
440
- if (n.body.type === types.AST_NODE_TYPES.ArrowFunctionExpression) {
415
+ const arg0Node = match(arg0).with({ type: AST_NODE_TYPES.ArrowFunctionExpression }, (n) => {
416
+ if (n.body.type === AST_NODE_TYPES.ArrowFunctionExpression) {
441
417
  return n.body;
442
418
  }
443
419
  return n;
444
- }).with({ type: types.AST_NODE_TYPES.FunctionExpression }, eff.identity).with({ type: types.AST_NODE_TYPES.Identifier }, (n) => {
445
- const variable = VAR4__namespace.findVariable(n.name, initialScope);
446
- const variableNode = VAR4__namespace.getVariableInitNode(variable, 0);
447
- if (variableNode?.type !== types.AST_NODE_TYPES.ArrowFunctionExpression && variableNode?.type !== types.AST_NODE_TYPES.FunctionExpression) {
420
+ }).with({ type: AST_NODE_TYPES.FunctionExpression }, identity).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
421
+ const variable = VAR4.findVariable(n.name, initialScope);
422
+ const variableNode = VAR4.getVariableInitNode(variable, 0);
423
+ if (variableNode?.type !== AST_NODE_TYPES.ArrowFunctionExpression && variableNode?.type !== AST_NODE_TYPES.FunctionExpression) {
448
424
  return null;
449
425
  }
450
426
  return variableNode;
451
427
  }).otherwise(() => null);
452
428
  if (arg0Node == null) return;
453
429
  const arg0NodeScope = context.sourceCode.getScope(arg0Node);
454
- const arg0NodeReferences = VAR4__namespace.getChidScopes(arg0NodeScope).flatMap((x) => x.references);
430
+ const arg0NodeReferences = VAR4.getChidScopes(arg0NodeScope).flatMap((x) => x.references);
455
431
  const isReferencedToComponentScope = arg0NodeReferences.some((x) => x.resolved?.scope.block === component);
456
432
  if (!isReferencedToComponentScope) {
457
433
  context.report({
@@ -484,11 +460,11 @@ var no_unnecessary_use_memo_default = createRule({
484
460
  });
485
461
  function create4(context) {
486
462
  if (!context.sourceCode.text.includes("use")) return {};
487
- const alias = shared.getSettingsFromContext(context).additionalHooks.useMemo ?? [];
488
- const isUseMemoCall = ER7__namespace.isReactHookCallWithNameAlias(context, "useMemo", alias);
463
+ const alias = getSettingsFromContext(context).additionalHooks.useMemo ?? [];
464
+ const isUseMemoCall = ER7.isReactHookCallWithNameAlias(context, "useMemo", alias);
489
465
  return {
490
466
  CallExpression(node) {
491
- if (!ER7__namespace.isReactHookCall(node)) {
467
+ if (!ER7.isReactHookCall(node)) {
492
468
  return;
493
469
  }
494
470
  const initialScope = context.sourceCode.getScope(node);
@@ -497,21 +473,21 @@ function create4(context) {
497
473
  }
498
474
  const scope = context.sourceCode.getScope(node);
499
475
  const component = scope.block;
500
- if (!AST__namespace.isFunction(component)) {
476
+ if (!AST.isFunction(component)) {
501
477
  return;
502
478
  }
503
479
  const [arg0, arg1] = node.arguments;
504
480
  if (arg0 == null || arg1 == null) {
505
481
  return;
506
482
  }
507
- const hasCallInArg0 = AST__namespace.isFunction(arg0) && [...AST__namespace.getNestedCallExpressions(arg0.body), ...AST__namespace.getNestedNewExpressions(arg0.body)].length > 0;
483
+ const hasCallInArg0 = AST.isFunction(arg0) && [...AST.getNestedCallExpressions(arg0.body), ...AST.getNestedNewExpressions(arg0.body)].length > 0;
508
484
  if (hasCallInArg0) {
509
485
  return;
510
486
  }
511
- 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) => {
512
- const variable = VAR4__namespace.findVariable(n.name, initialScope);
513
- const variableNode = VAR4__namespace.getVariableInitNode(variable, 0);
514
- if (variableNode?.type !== types.AST_NODE_TYPES.ArrayExpression) {
487
+ const hasEmptyDeps = match(arg1).with({ type: AST_NODE_TYPES.ArrayExpression }, (n) => n.elements.length === 0).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
488
+ const variable = VAR4.findVariable(n.name, initialScope);
489
+ const variableNode = VAR4.getVariableInitNode(variable, 0);
490
+ if (variableNode?.type !== AST_NODE_TYPES.ArrayExpression) {
515
491
  return false;
516
492
  }
517
493
  return variableNode.elements.length === 0;
@@ -519,22 +495,22 @@ function create4(context) {
519
495
  if (!hasEmptyDeps) {
520
496
  return;
521
497
  }
522
- const arg0Node = tsPattern.match(arg0).with({ type: types.AST_NODE_TYPES.ArrowFunctionExpression }, (n) => {
523
- if (n.body.type === types.AST_NODE_TYPES.ArrowFunctionExpression) {
498
+ const arg0Node = match(arg0).with({ type: AST_NODE_TYPES.ArrowFunctionExpression }, (n) => {
499
+ if (n.body.type === AST_NODE_TYPES.ArrowFunctionExpression) {
524
500
  return n.body;
525
501
  }
526
502
  return n;
527
- }).with({ type: types.AST_NODE_TYPES.FunctionExpression }, eff.identity).with({ type: types.AST_NODE_TYPES.Identifier }, (n) => {
528
- const variable = VAR4__namespace.findVariable(n.name, initialScope);
529
- const variableNode = VAR4__namespace.getVariableInitNode(variable, 0);
530
- if (variableNode?.type !== types.AST_NODE_TYPES.ArrowFunctionExpression && variableNode?.type !== types.AST_NODE_TYPES.FunctionExpression) {
503
+ }).with({ type: AST_NODE_TYPES.FunctionExpression }, identity).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
504
+ const variable = VAR4.findVariable(n.name, initialScope);
505
+ const variableNode = VAR4.getVariableInitNode(variable, 0);
506
+ if (variableNode?.type !== AST_NODE_TYPES.ArrowFunctionExpression && variableNode?.type !== AST_NODE_TYPES.FunctionExpression) {
531
507
  return null;
532
508
  }
533
509
  return variableNode;
534
510
  }).otherwise(() => null);
535
511
  if (arg0Node == null) return;
536
512
  const arg0NodeScope = context.sourceCode.getScope(arg0Node);
537
- const arg0NodeReferences = VAR4__namespace.getChidScopes(arg0NodeScope).flatMap((x) => x.references);
513
+ const arg0NodeReferences = VAR4.getChidScopes(arg0NodeScope).flatMap((x) => x.references);
538
514
  const isReferencedToComponentScope = arg0NodeReferences.some((x) => x.resolved?.scope.block === component);
539
515
  if (!isReferencedToComponentScope) {
540
516
  context.report({
@@ -570,7 +546,7 @@ var no_unnecessary_use_prefix_default = createRule({
570
546
  defaultOptions: []
571
547
  });
572
548
  function create5(context) {
573
- const { ctx, listeners } = ER7__namespace.useHookCollector();
549
+ const { ctx, listeners } = ER7.useHookCollector();
574
550
  return {
575
551
  ...listeners,
576
552
  "Program:exit"(program) {
@@ -579,7 +555,7 @@ function create5(context) {
579
555
  if (WELL_KNOWN_HOOKS.includes(name3)) {
580
556
  continue;
581
557
  }
582
- if (AST__namespace.isEmptyFunction(node)) {
558
+ if (AST.isEmptyFunction(node)) {
583
559
  continue;
584
560
  }
585
561
  if (hookCalls.length > 0) {
@@ -610,7 +586,7 @@ function create5(context) {
610
586
  };
611
587
  }
612
588
  function getPreferredLoc(context, id) {
613
- if (AST__namespace.isMultiLine(id)) return id.loc;
589
+ if (AST.isMultiLine(id)) return id.loc;
614
590
  if (!context.sourceCode.getText(id).startsWith("use")) return id.loc;
615
591
  return {
616
592
  end: {
@@ -649,11 +625,11 @@ var prefer_use_state_lazy_initialization_default = createRule({
649
625
  defaultOptions: []
650
626
  });
651
627
  function create6(context) {
652
- const alias = shared.getSettingsFromContext(context).additionalHooks.useState ?? [];
653
- const isUseStateCall = ER7__namespace.isReactHookCallWithNameAlias(context, "useState", alias);
628
+ const alias = getSettingsFromContext(context).additionalHooks.useState ?? [];
629
+ const isUseStateCall = ER7.isReactHookCallWithNameAlias(context, "useState", alias);
654
630
  return {
655
631
  CallExpression(node) {
656
- if (!ER7__namespace.isReactHookCall(node)) {
632
+ if (!ER7.isReactHookCall(node)) {
657
633
  return;
658
634
  }
659
635
  if (!isUseStateCall(node)) {
@@ -663,20 +639,20 @@ function create6(context) {
663
639
  if (useStateInput == null) {
664
640
  return;
665
641
  }
666
- for (const expr of AST__namespace.getNestedNewExpressions(useStateInput)) {
642
+ for (const expr of AST.getNestedNewExpressions(useStateInput)) {
667
643
  if (!("name" in expr.callee)) continue;
668
644
  if (ALLOW_LIST.includes(expr.callee.name)) continue;
669
- if (AST__namespace.findParentNode(expr, (n) => ER7__namespace.isUseCall(context, n)) != null) continue;
645
+ if (AST.findParentNode(expr, (n) => ER7.isUseCall(context, n)) != null) continue;
670
646
  context.report({
671
647
  messageId: "preferUseStateLazyInitialization",
672
648
  node: expr
673
649
  });
674
650
  }
675
- for (const expr of AST__namespace.getNestedCallExpressions(useStateInput)) {
651
+ for (const expr of AST.getNestedCallExpressions(useStateInput)) {
676
652
  if (!("name" in expr.callee)) continue;
677
- if (ER7__namespace.isReactHookName(expr.callee.name)) continue;
653
+ if (ER7.isReactHookName(expr.callee.name)) continue;
678
654
  if (ALLOW_LIST.includes(expr.callee.name)) continue;
679
- if (AST__namespace.findParentNode(expr, (n) => ER7__namespace.isUseCall(context, n)) != null) continue;
655
+ if (AST.findParentNode(expr, (n) => ER7.isUseCall(context, n)) != null) continue;
680
656
  context.report({
681
657
  messageId: "preferUseStateLazyInitialization",
682
658
  node: expr
@@ -698,18 +674,7 @@ var plugin = {
698
674
  "no-unnecessary-use-callback": no_unnecessary_use_callback_default,
699
675
  "no-unnecessary-use-memo": no_unnecessary_use_memo_default,
700
676
  "no-unnecessary-use-prefix": no_unnecessary_use_prefix_default,
701
- "prefer-use-state-lazy-initialization": prefer_use_state_lazy_initialization_default,
702
- // Part: deprecated rules
703
- /** @deprecated Use `no-unnecessary-use-prefix` instead */
704
- "ensure-custom-hooks-using-other-hooks": no_unnecessary_use_prefix_default,
705
- /** @deprecated Use `no-unnecessary-use-callback` instead */
706
- "ensure-use-callback-has-non-empty-deps": no_unnecessary_use_callback_default,
707
- /** @deprecated Use `no-unnecessary-use-memo` instead */
708
- "ensure-use-memo-has-non-empty-deps": no_unnecessary_use_memo_default,
709
- /** @deprecated Use `no-unnecessary-use-prefix` instead */
710
- "no-redundant-custom-hook": no_unnecessary_use_prefix_default,
711
- /** @deprecated Use `no-unnecessary-use-prefix` instead */
712
- "no-useless-custom-hooks": no_unnecessary_use_prefix_default
677
+ "prefer-use-state-lazy-initialization": prefer_use_state_lazy_initialization_default
713
678
  }
714
679
  };
715
680
 
@@ -736,4 +701,4 @@ var index_default = {
736
701
  }
737
702
  };
738
703
 
739
- module.exports = index_default;
704
+ export { index_default as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-react-hooks-extra",
3
- "version": "1.48.3",
3
+ "version": "2.0.0-next.1",
4
4
  "description": "ESLint React's ESLint plugin for React Hooks related rules.",
5
5
  "keywords": [
6
6
  "react",
@@ -23,22 +23,14 @@
23
23
  "license": "MIT",
24
24
  "author": "Rel1cx<rel1cx@proton.me>",
25
25
  "sideEffects": false,
26
+ "type": "module",
26
27
  "exports": {
27
28
  ".": {
28
- "import": {
29
- "types": "./dist/index.d.mts",
30
- "default": "./dist/index.mjs"
31
- },
32
- "require": {
33
- "types": "./dist/index.d.ts",
34
- "default": "./dist/index.js"
35
- }
29
+ "types": "./dist/index.d.ts",
30
+ "import": "./dist/index.js"
36
31
  },
37
32
  "./package.json": "./package.json"
38
33
  },
39
- "main": "dist/index.js",
40
- "module": "dist/index.mjs",
41
- "types": "dist/index.d.ts",
42
34
  "files": [
43
35
  "dist",
44
36
  "./package.json"
@@ -50,12 +42,12 @@
50
42
  "@typescript-eslint/utils": "^8.30.1",
51
43
  "string-ts": "^2.2.1",
52
44
  "ts-pattern": "^5.7.0",
53
- "@eslint-react/core": "1.48.3",
54
- "@eslint-react/ast": "1.48.3",
55
- "@eslint-react/kit": "1.48.3",
56
- "@eslint-react/eff": "1.48.3",
57
- "@eslint-react/shared": "1.48.3",
58
- "@eslint-react/var": "1.48.3"
45
+ "@eslint-react/ast": "2.0.0-next.1",
46
+ "@eslint-react/core": "2.0.0-next.1",
47
+ "@eslint-react/eff": "2.0.0-next.1",
48
+ "@eslint-react/kit": "2.0.0-next.1",
49
+ "@eslint-react/shared": "2.0.0-next.1",
50
+ "@eslint-react/var": "2.0.0-next.1"
59
51
  },
60
52
  "devDependencies": {
61
53
  "@types/react": "^19.1.2",
@@ -64,8 +56,8 @@
64
56
  "@local/configs": "0.0.0"
65
57
  },
66
58
  "peerDependencies": {
67
- "eslint": "^8.57.0 || ^9.0.0",
68
- "typescript": "^4.9.5 || ^5.3.3"
59
+ "eslint": "^9.24.0",
60
+ "typescript": "^4.9.5 || ^5.4.5"
69
61
  },
70
62
  "peerDependenciesMeta": {
71
63
  "eslint": {
@@ -77,7 +69,7 @@
77
69
  },
78
70
  "engines": {
79
71
  "bun": ">=1.0.15",
80
- "node": ">=18.18.0"
72
+ "node": ">=20.19.0"
81
73
  },
82
74
  "publishConfig": {
83
75
  "access": "public"