eslint-plugin-react-hooks-extra 1.9.1 → 1.9.2-beta.4

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2023 Eva1ent
3
+ Copyright (c) 2024 Eva1ent
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/dist/index.js CHANGED
@@ -5,18 +5,20 @@ var shared = require('@eslint-react/shared');
5
5
  var ast = require('@eslint-react/ast');
6
6
  var tools = require('@eslint-react/tools');
7
7
  var _var = require('@eslint-react/var');
8
+ var types = require('@typescript-eslint/types');
8
9
  var astUtils = require('@typescript-eslint/utils/ast-utils');
10
+ var tsPattern = require('ts-pattern');
9
11
 
10
12
  // package.json
11
13
  var name = "eslint-plugin-react-hooks-extra";
12
- var version = "1.9.1";
14
+ var version = "1.9.2-beta.4";
13
15
  var createRule = shared.createRuleForPlugin("hooks-extra");
14
16
  function isFromHookCall(name2, context, settings, predicate = tools.F.constTrue) {
15
17
  const hookAlias = settings.additionalHooks?.[name2] ?? [];
16
18
  return (topLevelId) => tools.F.pipe(
17
19
  _var.findVariable(topLevelId, context.sourceCode.getScope(topLevelId)),
18
20
  tools.O.flatMap(_var.getVariableNode(0)),
19
- tools.O.filter(ast.is(ast.NodeType.CallExpression)),
21
+ tools.O.filter(ast.is(types.AST_NODE_TYPES.CallExpression)),
20
22
  tools.O.filter(core.isReactHookCallWithNameAlias(name2, context, hookAlias)),
21
23
  tools.O.exists((call) => predicate(topLevelId, call))
22
24
  );
@@ -24,218 +26,33 @@ function isFromHookCall(name2, context, settings, predicate = tools.F.constTrue)
24
26
  function isFromUseStateCall(context, settings) {
25
27
  const predicate = (topLevelId, call) => {
26
28
  const { parent } = call;
27
- if (!("id" in parent && parent.id?.type === ast.NodeType.ArrayPattern)) return true;
28
- return parent.id.elements.findIndex((e2) => e2?.type === ast.NodeType.Identifier && e2.name === topLevelId.name) === 1;
29
+ if (!("id" in parent && parent.id?.type === types.AST_NODE_TYPES.ArrayPattern)) return true;
30
+ return parent.id.elements.findIndex((e) => e?.type === types.AST_NODE_TYPES.Identifier && e.name === topLevelId.name) === 1;
29
31
  };
30
32
  return isFromHookCall("useState", context, settings, predicate);
31
33
  }
32
-
33
- // ../../../node_modules/.pnpm/ts-pattern@5.2.0/node_modules/ts-pattern/dist/index.js
34
- var t = Symbol.for("@ts-pattern/matcher");
35
- var e = Symbol.for("@ts-pattern/isVariadic");
36
- var n = "@ts-pattern/anonymous-select-key";
37
- var r = (t2) => Boolean(t2 && "object" == typeof t2);
38
- var i = (e2) => e2 && !!e2[t];
39
- var o = (n2, s2, c2) => {
40
- if (i(n2)) {
41
- const e2 = n2[t](), { matched: r2, selections: i2 } = e2.match(s2);
42
- return r2 && i2 && Object.keys(i2).forEach((t2) => c2(t2, i2[t2])), r2;
43
- }
44
- if (r(n2)) {
45
- if (!r(s2)) return false;
46
- if (Array.isArray(n2)) {
47
- if (!Array.isArray(s2)) return false;
48
- let t2 = [], r2 = [], a2 = [];
49
- for (const o2 of n2.keys()) {
50
- const s3 = n2[o2];
51
- i(s3) && s3[e] ? a2.push(s3) : a2.length ? r2.push(s3) : t2.push(s3);
52
- }
53
- if (a2.length) {
54
- if (a2.length > 1) throw new Error("Pattern error: Using `...P.array(...)` several times in a single pattern is not allowed.");
55
- if (s2.length < t2.length + r2.length) return false;
56
- const e2 = s2.slice(0, t2.length), n3 = 0 === r2.length ? [] : s2.slice(-r2.length), i2 = s2.slice(t2.length, 0 === r2.length ? Infinity : -r2.length);
57
- return t2.every((t3, n4) => o(t3, e2[n4], c2)) && r2.every((t3, e3) => o(t3, n3[e3], c2)) && (0 === a2.length || o(a2[0], i2, c2));
58
- }
59
- return n2.length === s2.length && n2.every((t3, e2) => o(t3, s2[e2], c2));
60
- }
61
- return Object.keys(n2).every((e2) => {
62
- const r2 = n2[e2];
63
- return (e2 in s2 || i(a2 = r2) && "optional" === a2[t]().matcherType) && o(r2, s2[e2], c2);
64
- var a2;
65
- });
66
- }
67
- return Object.is(s2, n2);
68
- };
69
- var s = (e2) => {
70
- var n2, o2, a2;
71
- return r(e2) ? i(e2) ? null != (n2 = null == (o2 = (a2 = e2[t]()).getSelectionKeys) ? void 0 : o2.call(a2)) ? n2 : [] : Array.isArray(e2) ? c(e2, s) : c(Object.values(e2), s) : [];
72
- };
73
- var c = (t2, e2) => t2.reduce((t3, n2) => t3.concat(e2(n2)), []);
74
- function a(...t2) {
75
- if (1 === t2.length) {
76
- const [e2] = t2;
77
- return (t3) => o(e2, t3, () => {
78
- });
79
- }
80
- if (2 === t2.length) {
81
- const [e2, n2] = t2;
82
- return o(e2, n2, () => {
83
- });
84
- }
85
- throw new Error(`isMatching wasn't given the right number of arguments: expected 1 or 2, received ${t2.length}.`);
86
- }
87
- function u(t2) {
88
- return Object.assign(t2, { optional: () => l(t2), and: (e2) => m(t2, e2), or: (e2) => d(t2, e2), select: (e2) => void 0 === e2 ? p(t2) : p(e2, t2) });
89
- }
90
- function l(e2) {
91
- return u({ [t]: () => ({ match: (t2) => {
92
- let n2 = {};
93
- const r2 = (t3, e3) => {
94
- n2[t3] = e3;
95
- };
96
- return void 0 === t2 ? (s(e2).forEach((t3) => r2(t3, void 0)), { matched: true, selections: n2 }) : { matched: o(e2, t2, r2), selections: n2 };
97
- }, getSelectionKeys: () => s(e2), matcherType: "optional" }) });
98
- }
99
- function m(...e2) {
100
- return u({ [t]: () => ({ match: (t2) => {
101
- let n2 = {};
102
- const r2 = (t3, e3) => {
103
- n2[t3] = e3;
104
- };
105
- return { matched: e2.every((e3) => o(e3, t2, r2)), selections: n2 };
106
- }, getSelectionKeys: () => c(e2, s), matcherType: "and" }) });
107
- }
108
- function d(...e2) {
109
- return u({ [t]: () => ({ match: (t2) => {
110
- let n2 = {};
111
- const r2 = (t3, e3) => {
112
- n2[t3] = e3;
113
- };
114
- return c(e2, s).forEach((t3) => r2(t3, void 0)), { matched: e2.some((e3) => o(e3, t2, r2)), selections: n2 };
115
- }, getSelectionKeys: () => c(e2, s), matcherType: "or" }) });
116
- }
117
- function y(e2) {
118
- return { [t]: () => ({ match: (t2) => ({ matched: Boolean(e2(t2)) }) }) };
119
- }
120
- function p(...e2) {
121
- const r2 = "string" == typeof e2[0] ? e2[0] : void 0, i2 = 2 === e2.length ? e2[1] : "string" == typeof e2[0] ? void 0 : e2[0];
122
- return u({ [t]: () => ({ match: (t2) => {
123
- let e3 = { [null != r2 ? r2 : n]: t2 };
124
- return { matched: void 0 === i2 || o(i2, t2, (t3, n2) => {
125
- e3[t3] = n2;
126
- }), selections: e3 };
127
- }, getSelectionKeys: () => [null != r2 ? r2 : n].concat(void 0 === i2 ? [] : s(i2)) }) });
128
- }
129
- function v(t2) {
130
- return "number" == typeof t2;
131
- }
132
- function b(t2) {
133
- return "string" == typeof t2;
134
- }
135
- function w(t2) {
136
- return "bigint" == typeof t2;
137
- }
138
- u(y(function(t2) {
139
- return true;
140
- }));
141
- var j = (t2) => Object.assign(u(t2), { startsWith: (e2) => {
142
- return j(m(t2, (n2 = e2, y((t3) => b(t3) && t3.startsWith(n2)))));
143
- var n2;
144
- }, endsWith: (e2) => {
145
- return j(m(t2, (n2 = e2, y((t3) => b(t3) && t3.endsWith(n2)))));
146
- var n2;
147
- }, minLength: (e2) => j(m(t2, ((t3) => y((e3) => b(e3) && e3.length >= t3))(e2))), length: (e2) => j(m(t2, ((t3) => y((e3) => b(e3) && e3.length === t3))(e2))), maxLength: (e2) => j(m(t2, ((t3) => y((e3) => b(e3) && e3.length <= t3))(e2))), includes: (e2) => {
148
- return j(m(t2, (n2 = e2, y((t3) => b(t3) && t3.includes(n2)))));
149
- var n2;
150
- }, regex: (e2) => {
151
- return j(m(t2, (n2 = e2, y((t3) => b(t3) && Boolean(t3.match(n2))))));
152
- var n2;
153
- } });
154
- j(y(b));
155
- var K = (t2) => Object.assign(u(t2), { between: (e2, n2) => K(m(t2, ((t3, e3) => y((n3) => v(n3) && t3 <= n3 && e3 >= n3))(e2, n2))), lt: (e2) => K(m(t2, ((t3) => y((e3) => v(e3) && e3 < t3))(e2))), gt: (e2) => K(m(t2, ((t3) => y((e3) => v(e3) && e3 > t3))(e2))), lte: (e2) => K(m(t2, ((t3) => y((e3) => v(e3) && e3 <= t3))(e2))), gte: (e2) => K(m(t2, ((t3) => y((e3) => v(e3) && e3 >= t3))(e2))), int: () => K(m(t2, y((t3) => v(t3) && Number.isInteger(t3)))), finite: () => K(m(t2, y((t3) => v(t3) && Number.isFinite(t3)))), positive: () => K(m(t2, y((t3) => v(t3) && t3 > 0))), negative: () => K(m(t2, y((t3) => v(t3) && t3 < 0))) });
156
- K(y(v));
157
- var A = (t2) => Object.assign(u(t2), { between: (e2, n2) => A(m(t2, ((t3, e3) => y((n3) => w(n3) && t3 <= n3 && e3 >= n3))(e2, n2))), lt: (e2) => A(m(t2, ((t3) => y((e3) => w(e3) && e3 < t3))(e2))), gt: (e2) => A(m(t2, ((t3) => y((e3) => w(e3) && e3 > t3))(e2))), lte: (e2) => A(m(t2, ((t3) => y((e3) => w(e3) && e3 <= t3))(e2))), gte: (e2) => A(m(t2, ((t3) => y((e3) => w(e3) && e3 >= t3))(e2))), positive: () => A(m(t2, y((t3) => w(t3) && t3 > 0))), negative: () => A(m(t2, y((t3) => w(t3) && t3 < 0))) });
158
- A(y(w));
159
- u(y(function(t2) {
160
- return "boolean" == typeof t2;
161
- }));
162
- u(y(function(t2) {
163
- return "symbol" == typeof t2;
164
- }));
165
- u(y(function(t2) {
166
- return null == t2;
167
- }));
168
- u(y(function(t2) {
169
- return null != t2;
170
- }));
171
- var W = { matched: false, value: void 0 };
172
- function $(t2) {
173
- return new z(t2, W);
174
- }
175
- var z = class _z {
176
- constructor(t2, e2) {
177
- this.input = void 0, this.state = void 0, this.input = t2, this.state = e2;
178
- }
179
- with(...t2) {
180
- if (this.state.matched) return this;
181
- const e2 = t2[t2.length - 1], r2 = [t2[0]];
182
- let i2;
183
- 3 === t2.length && "function" == typeof t2[1] ? i2 = t2[1] : t2.length > 2 && r2.push(...t2.slice(1, t2.length - 1));
184
- let s2 = false, c2 = {};
185
- const a2 = (t3, e3) => {
186
- s2 = true, c2[t3] = e3;
187
- }, u2 = !r2.some((t3) => o(t3, this.input, a2)) || i2 && !Boolean(i2(this.input)) ? W : { matched: true, value: e2(s2 ? n in c2 ? c2[n] : c2 : this.input, this.input) };
188
- return new _z(this.input, u2);
189
- }
190
- when(t2, e2) {
191
- if (this.state.matched) return this;
192
- const n2 = Boolean(t2(this.input));
193
- return new _z(this.input, n2 ? { matched: true, value: e2(this.input, this.input) } : W);
194
- }
195
- otherwise(t2) {
196
- return this.state.matched ? this.state.value : t2(this.input);
197
- }
198
- exhaustive() {
199
- if (this.state.matched) return this.state.value;
200
- let t2;
201
- try {
202
- t2 = JSON.stringify(this.input);
203
- } catch (e2) {
204
- t2 = this.input;
205
- }
206
- throw new Error(`Pattern matching error: no pattern matches value ${t2}`);
207
- }
208
- run() {
209
- return this.exhaustive();
210
- }
211
- returnType() {
212
- return this;
213
- }
214
- };
215
-
216
- // src/utils/is-set-function-call.ts
217
34
  function isSetFunctionCall(context, settings) {
218
35
  const isIdFromUseStateCall = isFromUseStateCall(context, settings);
219
36
  return (node) => {
220
37
  switch (node.callee.type) {
221
- case ast.NodeType.Identifier: {
38
+ case types.AST_NODE_TYPES.Identifier: {
222
39
  return isIdFromUseStateCall(node.callee);
223
40
  }
224
- case ast.NodeType.MemberExpression: {
41
+ case types.AST_NODE_TYPES.MemberExpression: {
225
42
  if (!("name" in node.callee.object)) return false;
226
43
  const initialScope = context.sourceCode.getScope(node);
227
44
  const property = astUtils.getStaticValue(node.callee.property, initialScope);
228
45
  if (property?.value === 1) return isIdFromUseStateCall(node.callee.object);
229
46
  return false;
230
47
  }
231
- case ast.NodeType.CallExpression: {
48
+ case types.AST_NODE_TYPES.CallExpression: {
232
49
  const callee = node.callee.callee;
233
- if (callee.type !== ast.NodeType.MemberExpression) return false;
50
+ if (callee.type !== types.AST_NODE_TYPES.MemberExpression) return false;
234
51
  if (!("name" in callee.object)) return false;
235
- const isAt = a({
236
- type: ast.NodeType.MemberExpression,
52
+ const isAt = tsPattern.isMatching({
53
+ type: types.AST_NODE_TYPES.MemberExpression,
237
54
  property: {
238
- type: ast.NodeType.Identifier,
55
+ type: types.AST_NODE_TYPES.Identifier,
239
56
  name: "at"
240
57
  }
241
58
  }, callee);
@@ -253,17 +70,17 @@ function isSetFunctionCall(context, settings) {
253
70
  };
254
71
  }
255
72
  function isThenCall(node) {
256
- return node.callee.type === ast.NodeType.MemberExpression && node.callee.property.type === ast.NodeType.Identifier && node.callee.property.name === "then";
73
+ return node.callee.type === types.AST_NODE_TYPES.MemberExpression && node.callee.property.type === types.AST_NODE_TYPES.Identifier && node.callee.property.name === "then";
257
74
  }
258
75
  function isVariableDeclaratorFromHookCall(node) {
259
- if (node.type !== ast.NodeType.VariableDeclarator) return false;
260
- if (node.id.type !== ast.NodeType.Identifier) return false;
261
- if (node.init?.type !== ast.NodeType.CallExpression) return false;
76
+ if (node.type !== types.AST_NODE_TYPES.VariableDeclarator) return false;
77
+ if (node.id.type !== types.AST_NODE_TYPES.Identifier) return false;
78
+ if (node.init?.type !== types.AST_NODE_TYPES.CallExpression) return false;
262
79
  switch (node.init.callee.type) {
263
- case ast.NodeType.Identifier:
80
+ case types.AST_NODE_TYPES.Identifier:
264
81
  return core.isReactHookName(node.init.callee.name);
265
- case ast.NodeType.MemberExpression:
266
- return node.init.callee.property.type === ast.NodeType.Identifier && core.isReactHookName(node.init.callee.property.name);
82
+ case types.AST_NODE_TYPES.MemberExpression:
83
+ return node.init.callee.property.type === types.AST_NODE_TYPES.Identifier && core.isReactHookName(node.init.callee.property.name);
267
84
  default:
268
85
  return false;
269
86
  }
@@ -338,14 +155,14 @@ var ensure_use_callback_has_non_empty_deps_default = createRule({
338
155
  return;
339
156
  }
340
157
  const hasEmptyDeps = tools.F.pipe(
341
- $(deps).with({ type: ast.NodeType.ArrayExpression }, tools.O.some).with({ type: ast.NodeType.Identifier }, (n2) => {
158
+ tsPattern.match(deps).with({ type: types.AST_NODE_TYPES.ArrayExpression }, tools.O.some).with({ type: types.AST_NODE_TYPES.Identifier }, (n) => {
342
159
  return tools.F.pipe(
343
- _var.findVariable(n2.name, initialScope),
160
+ _var.findVariable(n.name, initialScope),
344
161
  tools.O.flatMap(_var.getVariableNode(0)),
345
- tools.O.filter(ast.is(ast.NodeType.ArrayExpression))
162
+ tools.O.filter(ast.is(types.AST_NODE_TYPES.ArrayExpression))
346
163
  );
347
164
  }).otherwise(tools.O.none),
348
- tools.O.exists((x2) => x2.elements.length === 0)
165
+ tools.O.exists((x) => x.elements.length === 0)
349
166
  );
350
167
  if (!hasEmptyDeps) return;
351
168
  if (!cb) {
@@ -356,21 +173,21 @@ var ensure_use_callback_has_non_empty_deps_default = createRule({
356
173
  return;
357
174
  }
358
175
  const isReferencedToComponentScope = tools.F.pipe(
359
- $(cb).with({ type: ast.NodeType.ArrowFunctionExpression }, (n2) => {
360
- if (n2.body.type === ast.NodeType.ArrowFunctionExpression) {
361
- return tools.O.some(n2.body);
176
+ tsPattern.match(cb).with({ type: types.AST_NODE_TYPES.ArrowFunctionExpression }, (n) => {
177
+ if (n.body.type === types.AST_NODE_TYPES.ArrowFunctionExpression) {
178
+ return tools.O.some(n.body);
362
179
  }
363
- return tools.O.some(n2);
364
- }).with({ type: ast.NodeType.FunctionExpression }, tools.O.some).with({ type: ast.NodeType.Identifier }, (n2) => {
180
+ return tools.O.some(n);
181
+ }).with({ type: types.AST_NODE_TYPES.FunctionExpression }, tools.O.some).with({ type: types.AST_NODE_TYPES.Identifier }, (n) => {
365
182
  return tools.F.pipe(
366
- _var.findVariable(n2.name, initialScope),
183
+ _var.findVariable(n.name, initialScope),
367
184
  tools.O.flatMap(_var.getVariableNode(0)),
368
185
  tools.O.filter(ast.isFunction)
369
186
  );
370
187
  }).otherwise(tools.O.none),
371
- tools.O.map((n2) => context.sourceCode.getScope(n2)),
372
- tools.O.map((s2) => [...s2.childScopes, s2].flatMap((x2) => x2.references)),
373
- tools.O.exists((refs) => refs.some((x2) => x2.resolved?.scope.block === component))
188
+ tools.O.map((n) => context.sourceCode.getScope(n)),
189
+ tools.O.map((s) => [...s.childScopes, s].flatMap((x) => x.references)),
190
+ tools.O.exists((refs) => refs.some((x) => x.resolved?.scope.block === component))
374
191
  );
375
192
  if (isReferencedToComponentScope) return;
376
193
  context.report({
@@ -416,14 +233,14 @@ var ensure_use_memo_has_non_empty_deps_default = createRule({
416
233
  return;
417
234
  }
418
235
  const hasEmptyDeps = tools.F.pipe(
419
- $(deps).with({ type: ast.NodeType.ArrayExpression }, tools.O.some).with({ type: ast.NodeType.Identifier }, (n2) => {
236
+ tsPattern.match(deps).with({ type: types.AST_NODE_TYPES.ArrayExpression }, tools.O.some).with({ type: types.AST_NODE_TYPES.Identifier }, (n) => {
420
237
  return tools.F.pipe(
421
- _var.findVariable(n2.name, initialScope),
238
+ _var.findVariable(n.name, initialScope),
422
239
  tools.O.flatMap(_var.getVariableNode(0)),
423
- tools.O.filter(ast.is(ast.NodeType.ArrayExpression))
240
+ tools.O.filter(ast.is(types.AST_NODE_TYPES.ArrayExpression))
424
241
  );
425
242
  }).otherwise(tools.O.none),
426
- tools.O.exists((x2) => x2.elements.length === 0)
243
+ tools.O.exists((x) => x.elements.length === 0)
427
244
  );
428
245
  if (!hasEmptyDeps) return;
429
246
  if (!cb) {
@@ -434,21 +251,21 @@ var ensure_use_memo_has_non_empty_deps_default = createRule({
434
251
  return;
435
252
  }
436
253
  const isReferencedToComponentScope = tools.F.pipe(
437
- $(cb).with({ type: ast.NodeType.ArrowFunctionExpression }, (n2) => {
438
- if (n2.body.type === ast.NodeType.ArrowFunctionExpression) {
439
- return tools.O.some(n2.body);
254
+ tsPattern.match(cb).with({ type: types.AST_NODE_TYPES.ArrowFunctionExpression }, (n) => {
255
+ if (n.body.type === types.AST_NODE_TYPES.ArrowFunctionExpression) {
256
+ return tools.O.some(n.body);
440
257
  }
441
- return tools.O.some(n2);
442
- }).with({ type: ast.NodeType.FunctionExpression }, tools.O.some).with({ type: ast.NodeType.Identifier }, (n2) => {
258
+ return tools.O.some(n);
259
+ }).with({ type: types.AST_NODE_TYPES.FunctionExpression }, tools.O.some).with({ type: types.AST_NODE_TYPES.Identifier }, (n) => {
443
260
  return tools.F.pipe(
444
- _var.findVariable(n2.name, initialScope),
261
+ _var.findVariable(n.name, initialScope),
445
262
  tools.O.flatMap(_var.getVariableNode(0)),
446
263
  tools.O.filter(ast.isFunction)
447
264
  );
448
265
  }).otherwise(tools.O.none),
449
- tools.O.map((n2) => context.sourceCode.getScope(n2)),
450
- tools.O.map((s2) => [...s2.childScopes, s2].flatMap((x2) => x2.references)),
451
- tools.O.exists((refs) => refs.some((x2) => x2.resolved?.scope.block === component))
266
+ tools.O.map((n) => context.sourceCode.getScope(n)),
267
+ tools.O.map((s) => [...s.childScopes, s].flatMap((x) => x.references)),
268
+ tools.O.exists((refs) => refs.some((x) => x.resolved?.scope.block === component))
452
269
  );
453
270
  if (isReferencedToComponentScope) return;
454
271
  context.report({
@@ -497,13 +314,13 @@ var no_direct_set_state_in_use_effect_default = createRule({
497
314
  tools.MutRef.update(effectFunctionRef, (current) => current === node ? null : current);
498
315
  };
499
316
  function isEffectFunction(node) {
500
- return node.parent?.type === ast.NodeType.CallExpression && node.parent.callee !== node && isUseEffectCall(node.parent);
317
+ return node.parent?.type === types.AST_NODE_TYPES.CallExpression && node.parent.callee !== node && isUseEffectCall(node.parent);
501
318
  }
502
319
  function getCallKind(node) {
503
- return $(node).when(isUseStateCall2, () => "useState").when(isUseEffectCall, () => "useEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
320
+ return tsPattern.match(node).when(isUseStateCall2, () => "useState").when(isUseEffectCall, () => "useEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
504
321
  }
505
322
  function getFunctionKind(node) {
506
- return $(node).when(isEffectFunction, () => "effect").when(ast.isIIFE, () => "immediate").otherwise(() => "other");
323
+ return tsPattern.match(node).when(isEffectFunction, () => "effect").when(ast.isFunctionOfImmediatelyInvoked, () => "immediate").otherwise(() => "other");
507
324
  }
508
325
  return {
509
326
  ":function"(node) {
@@ -512,7 +329,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
512
329
  if (functionKind === "effect") onEffectFunctionEnter(node);
513
330
  },
514
331
  ":function:exit"(node) {
515
- const [_2, functionKind] = functionStack.at(-1) ?? [];
332
+ const [_, functionKind] = functionStack.at(-1) ?? [];
516
333
  functionStack.pop();
517
334
  if (functionKind === "effect") onEffectFunctionExit(node);
518
335
  },
@@ -520,7 +337,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
520
337
  const effectFn = tools.MutRef.get(effectFunctionRef);
521
338
  const [parentFn, parentFnKind] = functionStack.at(-1) ?? [];
522
339
  if (parentFn?.async) return;
523
- $(getCallKind(node)).with("setState", () => {
340
+ tsPattern.match(getCallKind(node)).with("setState", () => {
524
341
  if (!parentFn) return;
525
342
  if (parentFn !== effectFn && parentFnKind !== "immediate") {
526
343
  const maybeVd = ast.traverseUpGuard(node, isVariableDeclaratorFromHookCall);
@@ -550,10 +367,10 @@ var no_direct_set_state_in_use_effect_default = createRule({
550
367
  }).otherwise(tools.F.constVoid);
551
368
  },
552
369
  Identifier(node) {
553
- if (node.parent.type === ast.NodeType.CallExpression && node.parent.callee === node) return;
370
+ if (node.parent.type === types.AST_NODE_TYPES.CallExpression && node.parent.callee === node) return;
554
371
  if (!isIdFromUseStateCall(node)) return;
555
372
  switch (node.parent.type) {
556
- case ast.NodeType.CallExpression: {
373
+ case types.AST_NODE_TYPES.CallExpression: {
557
374
  const [firstArg] = node.parent.arguments;
558
375
  if (node !== firstArg) break;
559
376
  if (isUseCallbackCall2(node.parent)) {
@@ -569,9 +386,9 @@ var no_direct_set_state_in_use_effect_default = createRule({
569
386
  }
570
387
  break;
571
388
  }
572
- case ast.NodeType.ArrowFunctionExpression: {
389
+ case types.AST_NODE_TYPES.ArrowFunctionExpression: {
573
390
  const parent = node.parent.parent;
574
- if (parent.type !== ast.NodeType.CallExpression) break;
391
+ if (parent.type !== types.AST_NODE_TYPES.CallExpression) break;
575
392
  if (!isUseMemoCall2(parent)) break;
576
393
  const maybeVd = ast.traverseUpGuard(parent, isVariableDeclaratorFromHookCall);
577
394
  if (tools.O.isNone(maybeVd)) break;
@@ -585,16 +402,16 @@ var no_direct_set_state_in_use_effect_default = createRule({
585
402
  const getSetStateCalls = (id, initialScope) => {
586
403
  const node = tools.O.flatMap(_var.findVariable(id, initialScope), _var.getVariableNode(0)).pipe(tools.O.getOrNull);
587
404
  switch (node?.type) {
588
- case ast.NodeType.FunctionDeclaration:
589
- case ast.NodeType.FunctionExpression:
590
- case ast.NodeType.ArrowFunctionExpression:
405
+ case types.AST_NODE_TYPES.FunctionDeclaration:
406
+ case types.AST_NODE_TYPES.FunctionExpression:
407
+ case types.AST_NODE_TYPES.ArrowFunctionExpression:
591
408
  return indirectSetStateCalls.get(node) ?? [];
592
- case ast.NodeType.CallExpression:
409
+ case types.AST_NODE_TYPES.CallExpression:
593
410
  return indirectSetStateCallsInHooks.get(node) ?? indirectSetStateCallsAsArgs.get(node) ?? [];
594
411
  }
595
412
  return [];
596
413
  };
597
- for (const [_2, calls] of indirectSetStateCallsAsEFs) {
414
+ for (const [_, calls] of indirectSetStateCallsAsEFs) {
598
415
  for (const call of calls) {
599
416
  context.report({
600
417
  data: { name: call.name },
@@ -671,13 +488,13 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
671
488
  tools.MutRef.update(effectFunctionRef, (current) => current === node ? null : current);
672
489
  };
673
490
  function isEffectFunction(node) {
674
- return node.parent?.type === ast.NodeType.CallExpression && node.parent.callee !== node && isUseEffectCall(node.parent);
491
+ return node.parent?.type === types.AST_NODE_TYPES.CallExpression && node.parent.callee !== node && isUseEffectCall(node.parent);
675
492
  }
676
493
  function getCallKind(node) {
677
- return $(node).when(isUseStateCall2, () => "useState").when(isUseEffectCall, () => "useLayoutEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
494
+ return tsPattern.match(node).when(isUseStateCall2, () => "useState").when(isUseEffectCall, () => "useLayoutEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
678
495
  }
679
496
  function getFunctionKind(node) {
680
- return $(node).when(isEffectFunction, () => "effect").when(ast.isIIFE, () => "immediate").otherwise(() => "other");
497
+ return tsPattern.match(node).when(isEffectFunction, () => "effect").when(ast.isFunctionOfImmediatelyInvoked, () => "immediate").otherwise(() => "other");
681
498
  }
682
499
  return {
683
500
  ":function"(node) {
@@ -686,7 +503,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
686
503
  if (functionKind === "effect") onEffectFunctionEnter(node);
687
504
  },
688
505
  ":function:exit"(node) {
689
- const [_2, functionKind] = functionStack.at(-1) ?? [];
506
+ const [_, functionKind] = functionStack.at(-1) ?? [];
690
507
  functionStack.pop();
691
508
  if (functionKind === "effect") onEffectFunctionExit(node);
692
509
  },
@@ -694,7 +511,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
694
511
  const effectFn = tools.MutRef.get(effectFunctionRef);
695
512
  const [parentFn, parentFnKind] = functionStack.at(-1) ?? [];
696
513
  if (parentFn?.async) return;
697
- $(getCallKind(node)).with("setState", () => {
514
+ tsPattern.match(getCallKind(node)).with("setState", () => {
698
515
  if (!parentFn) return;
699
516
  if (parentFn !== effectFn && parentFnKind !== "immediate") {
700
517
  const maybeVd = ast.traverseUpGuard(node, isVariableDeclaratorFromHookCall);
@@ -724,10 +541,10 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
724
541
  }).otherwise(tools.F.constVoid);
725
542
  },
726
543
  Identifier(node) {
727
- if (node.parent.type === ast.NodeType.CallExpression && node.parent.callee === node) return;
544
+ if (node.parent.type === types.AST_NODE_TYPES.CallExpression && node.parent.callee === node) return;
728
545
  if (!isIdFromUseStateCall(node)) return;
729
546
  switch (node.parent.type) {
730
- case ast.NodeType.CallExpression: {
547
+ case types.AST_NODE_TYPES.CallExpression: {
731
548
  const [firstArg] = node.parent.arguments;
732
549
  if (node !== firstArg) break;
733
550
  if (isUseCallbackCall2(node.parent)) {
@@ -743,9 +560,9 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
743
560
  }
744
561
  break;
745
562
  }
746
- case ast.NodeType.ArrowFunctionExpression: {
563
+ case types.AST_NODE_TYPES.ArrowFunctionExpression: {
747
564
  const parent = node.parent.parent;
748
- if (parent.type !== ast.NodeType.CallExpression) break;
565
+ if (parent.type !== types.AST_NODE_TYPES.CallExpression) break;
749
566
  if (!isUseMemoCall2(parent)) break;
750
567
  const maybeVd = ast.traverseUpGuard(parent, isVariableDeclaratorFromHookCall);
751
568
  if (tools.O.isNone(maybeVd)) break;
@@ -759,16 +576,16 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
759
576
  const getSetStateCalls = (id, initialScope) => {
760
577
  const node = tools.O.flatMap(_var.findVariable(id, initialScope), _var.getVariableNode(0)).pipe(tools.O.getOrNull);
761
578
  switch (node?.type) {
762
- case ast.NodeType.FunctionDeclaration:
763
- case ast.NodeType.FunctionExpression:
764
- case ast.NodeType.ArrowFunctionExpression:
579
+ case types.AST_NODE_TYPES.FunctionDeclaration:
580
+ case types.AST_NODE_TYPES.FunctionExpression:
581
+ case types.AST_NODE_TYPES.ArrowFunctionExpression:
765
582
  return indirectSetStateCalls.get(node) ?? [];
766
- case ast.NodeType.CallExpression:
583
+ case types.AST_NODE_TYPES.CallExpression:
767
584
  return indirectSetStateCallsInHooks.get(node) ?? indirectSetStateCallsAsArgs.get(node) ?? [];
768
585
  }
769
586
  return [];
770
587
  };
771
- for (const [_2, calls] of indirectSetStateCallsAsEFs) {
588
+ for (const [_, calls] of indirectSetStateCallsAsEFs) {
772
589
  for (const call of calls) {
773
590
  context.report({
774
591
  data: { name: call.name },
@@ -827,8 +644,8 @@ var prefer_use_state_lazy_initialization_default = createRule({
827
644
  const [useStateInput] = node.arguments;
828
645
  if (!useStateInput) return;
829
646
  const nestedCallExpressions = ast.getNestedCallExpressions(useStateInput);
830
- const hasFunctionCall = nestedCallExpressions.some((n2) => {
831
- return "name" in n2.callee && !ALLOW_LIST.includes(n2.callee.name);
647
+ const hasFunctionCall = nestedCallExpressions.some((n) => {
648
+ return "name" in n.callee && !ALLOW_LIST.includes(n.callee.name);
832
649
  });
833
650
  if (!hasFunctionCall) return;
834
651
  context.report({
package/dist/index.mjs CHANGED
@@ -1,20 +1,22 @@
1
1
  import { useHookCollector, isReactHookCall, isUseCallbackCall, isReactHookCallWithNameLoose, isUseMemoCall, isReactHookCallWithNameAlias, isUseStateCall, isReactHookName } from '@eslint-react/core';
2
2
  import { createRuleForPlugin, decodeSettings } from '@eslint-react/shared';
3
- import { isFunction, NodeType, is, traverseUpGuard, getNestedIdentifiers, getNestedCallExpressions, isIIFE } from '@eslint-react/ast';
3
+ import { isFunction, is, traverseUpGuard, getNestedIdentifiers, getNestedCallExpressions, isFunctionOfImmediatelyInvoked } from '@eslint-react/ast';
4
4
  import { F, O, MutRef } from '@eslint-react/tools';
5
5
  import { findVariable, getVariableNode } from '@eslint-react/var';
6
+ import { AST_NODE_TYPES } from '@typescript-eslint/types';
6
7
  import { getStaticValue } from '@typescript-eslint/utils/ast-utils';
8
+ import { match, isMatching } from 'ts-pattern';
7
9
 
8
10
  // package.json
9
11
  var name = "eslint-plugin-react-hooks-extra";
10
- var version = "1.9.1";
12
+ var version = "1.9.2-beta.4";
11
13
  var createRule = createRuleForPlugin("hooks-extra");
12
14
  function isFromHookCall(name2, context, settings, predicate = F.constTrue) {
13
15
  const hookAlias = settings.additionalHooks?.[name2] ?? [];
14
16
  return (topLevelId) => F.pipe(
15
17
  findVariable(topLevelId, context.sourceCode.getScope(topLevelId)),
16
18
  O.flatMap(getVariableNode(0)),
17
- O.filter(is(NodeType.CallExpression)),
19
+ O.filter(is(AST_NODE_TYPES.CallExpression)),
18
20
  O.filter(isReactHookCallWithNameAlias(name2, context, hookAlias)),
19
21
  O.exists((call) => predicate(topLevelId, call))
20
22
  );
@@ -22,218 +24,33 @@ function isFromHookCall(name2, context, settings, predicate = F.constTrue) {
22
24
  function isFromUseStateCall(context, settings) {
23
25
  const predicate = (topLevelId, call) => {
24
26
  const { parent } = call;
25
- if (!("id" in parent && parent.id?.type === NodeType.ArrayPattern)) return true;
26
- return parent.id.elements.findIndex((e2) => e2?.type === NodeType.Identifier && e2.name === topLevelId.name) === 1;
27
+ if (!("id" in parent && parent.id?.type === AST_NODE_TYPES.ArrayPattern)) return true;
28
+ return parent.id.elements.findIndex((e) => e?.type === AST_NODE_TYPES.Identifier && e.name === topLevelId.name) === 1;
27
29
  };
28
30
  return isFromHookCall("useState", context, settings, predicate);
29
31
  }
30
-
31
- // ../../../node_modules/.pnpm/ts-pattern@5.2.0/node_modules/ts-pattern/dist/index.js
32
- var t = Symbol.for("@ts-pattern/matcher");
33
- var e = Symbol.for("@ts-pattern/isVariadic");
34
- var n = "@ts-pattern/anonymous-select-key";
35
- var r = (t2) => Boolean(t2 && "object" == typeof t2);
36
- var i = (e2) => e2 && !!e2[t];
37
- var o = (n2, s2, c2) => {
38
- if (i(n2)) {
39
- const e2 = n2[t](), { matched: r2, selections: i2 } = e2.match(s2);
40
- return r2 && i2 && Object.keys(i2).forEach((t2) => c2(t2, i2[t2])), r2;
41
- }
42
- if (r(n2)) {
43
- if (!r(s2)) return false;
44
- if (Array.isArray(n2)) {
45
- if (!Array.isArray(s2)) return false;
46
- let t2 = [], r2 = [], a2 = [];
47
- for (const o2 of n2.keys()) {
48
- const s3 = n2[o2];
49
- i(s3) && s3[e] ? a2.push(s3) : a2.length ? r2.push(s3) : t2.push(s3);
50
- }
51
- if (a2.length) {
52
- if (a2.length > 1) throw new Error("Pattern error: Using `...P.array(...)` several times in a single pattern is not allowed.");
53
- if (s2.length < t2.length + r2.length) return false;
54
- const e2 = s2.slice(0, t2.length), n3 = 0 === r2.length ? [] : s2.slice(-r2.length), i2 = s2.slice(t2.length, 0 === r2.length ? Infinity : -r2.length);
55
- return t2.every((t3, n4) => o(t3, e2[n4], c2)) && r2.every((t3, e3) => o(t3, n3[e3], c2)) && (0 === a2.length || o(a2[0], i2, c2));
56
- }
57
- return n2.length === s2.length && n2.every((t3, e2) => o(t3, s2[e2], c2));
58
- }
59
- return Object.keys(n2).every((e2) => {
60
- const r2 = n2[e2];
61
- return (e2 in s2 || i(a2 = r2) && "optional" === a2[t]().matcherType) && o(r2, s2[e2], c2);
62
- var a2;
63
- });
64
- }
65
- return Object.is(s2, n2);
66
- };
67
- var s = (e2) => {
68
- var n2, o2, a2;
69
- return r(e2) ? i(e2) ? null != (n2 = null == (o2 = (a2 = e2[t]()).getSelectionKeys) ? void 0 : o2.call(a2)) ? n2 : [] : Array.isArray(e2) ? c(e2, s) : c(Object.values(e2), s) : [];
70
- };
71
- var c = (t2, e2) => t2.reduce((t3, n2) => t3.concat(e2(n2)), []);
72
- function a(...t2) {
73
- if (1 === t2.length) {
74
- const [e2] = t2;
75
- return (t3) => o(e2, t3, () => {
76
- });
77
- }
78
- if (2 === t2.length) {
79
- const [e2, n2] = t2;
80
- return o(e2, n2, () => {
81
- });
82
- }
83
- throw new Error(`isMatching wasn't given the right number of arguments: expected 1 or 2, received ${t2.length}.`);
84
- }
85
- function u(t2) {
86
- return Object.assign(t2, { optional: () => l(t2), and: (e2) => m(t2, e2), or: (e2) => d(t2, e2), select: (e2) => void 0 === e2 ? p(t2) : p(e2, t2) });
87
- }
88
- function l(e2) {
89
- return u({ [t]: () => ({ match: (t2) => {
90
- let n2 = {};
91
- const r2 = (t3, e3) => {
92
- n2[t3] = e3;
93
- };
94
- return void 0 === t2 ? (s(e2).forEach((t3) => r2(t3, void 0)), { matched: true, selections: n2 }) : { matched: o(e2, t2, r2), selections: n2 };
95
- }, getSelectionKeys: () => s(e2), matcherType: "optional" }) });
96
- }
97
- function m(...e2) {
98
- return u({ [t]: () => ({ match: (t2) => {
99
- let n2 = {};
100
- const r2 = (t3, e3) => {
101
- n2[t3] = e3;
102
- };
103
- return { matched: e2.every((e3) => o(e3, t2, r2)), selections: n2 };
104
- }, getSelectionKeys: () => c(e2, s), matcherType: "and" }) });
105
- }
106
- function d(...e2) {
107
- return u({ [t]: () => ({ match: (t2) => {
108
- let n2 = {};
109
- const r2 = (t3, e3) => {
110
- n2[t3] = e3;
111
- };
112
- return c(e2, s).forEach((t3) => r2(t3, void 0)), { matched: e2.some((e3) => o(e3, t2, r2)), selections: n2 };
113
- }, getSelectionKeys: () => c(e2, s), matcherType: "or" }) });
114
- }
115
- function y(e2) {
116
- return { [t]: () => ({ match: (t2) => ({ matched: Boolean(e2(t2)) }) }) };
117
- }
118
- function p(...e2) {
119
- const r2 = "string" == typeof e2[0] ? e2[0] : void 0, i2 = 2 === e2.length ? e2[1] : "string" == typeof e2[0] ? void 0 : e2[0];
120
- return u({ [t]: () => ({ match: (t2) => {
121
- let e3 = { [null != r2 ? r2 : n]: t2 };
122
- return { matched: void 0 === i2 || o(i2, t2, (t3, n2) => {
123
- e3[t3] = n2;
124
- }), selections: e3 };
125
- }, getSelectionKeys: () => [null != r2 ? r2 : n].concat(void 0 === i2 ? [] : s(i2)) }) });
126
- }
127
- function v(t2) {
128
- return "number" == typeof t2;
129
- }
130
- function b(t2) {
131
- return "string" == typeof t2;
132
- }
133
- function w(t2) {
134
- return "bigint" == typeof t2;
135
- }
136
- u(y(function(t2) {
137
- return true;
138
- }));
139
- var j = (t2) => Object.assign(u(t2), { startsWith: (e2) => {
140
- return j(m(t2, (n2 = e2, y((t3) => b(t3) && t3.startsWith(n2)))));
141
- var n2;
142
- }, endsWith: (e2) => {
143
- return j(m(t2, (n2 = e2, y((t3) => b(t3) && t3.endsWith(n2)))));
144
- var n2;
145
- }, minLength: (e2) => j(m(t2, ((t3) => y((e3) => b(e3) && e3.length >= t3))(e2))), length: (e2) => j(m(t2, ((t3) => y((e3) => b(e3) && e3.length === t3))(e2))), maxLength: (e2) => j(m(t2, ((t3) => y((e3) => b(e3) && e3.length <= t3))(e2))), includes: (e2) => {
146
- return j(m(t2, (n2 = e2, y((t3) => b(t3) && t3.includes(n2)))));
147
- var n2;
148
- }, regex: (e2) => {
149
- return j(m(t2, (n2 = e2, y((t3) => b(t3) && Boolean(t3.match(n2))))));
150
- var n2;
151
- } });
152
- j(y(b));
153
- var K = (t2) => Object.assign(u(t2), { between: (e2, n2) => K(m(t2, ((t3, e3) => y((n3) => v(n3) && t3 <= n3 && e3 >= n3))(e2, n2))), lt: (e2) => K(m(t2, ((t3) => y((e3) => v(e3) && e3 < t3))(e2))), gt: (e2) => K(m(t2, ((t3) => y((e3) => v(e3) && e3 > t3))(e2))), lte: (e2) => K(m(t2, ((t3) => y((e3) => v(e3) && e3 <= t3))(e2))), gte: (e2) => K(m(t2, ((t3) => y((e3) => v(e3) && e3 >= t3))(e2))), int: () => K(m(t2, y((t3) => v(t3) && Number.isInteger(t3)))), finite: () => K(m(t2, y((t3) => v(t3) && Number.isFinite(t3)))), positive: () => K(m(t2, y((t3) => v(t3) && t3 > 0))), negative: () => K(m(t2, y((t3) => v(t3) && t3 < 0))) });
154
- K(y(v));
155
- var A = (t2) => Object.assign(u(t2), { between: (e2, n2) => A(m(t2, ((t3, e3) => y((n3) => w(n3) && t3 <= n3 && e3 >= n3))(e2, n2))), lt: (e2) => A(m(t2, ((t3) => y((e3) => w(e3) && e3 < t3))(e2))), gt: (e2) => A(m(t2, ((t3) => y((e3) => w(e3) && e3 > t3))(e2))), lte: (e2) => A(m(t2, ((t3) => y((e3) => w(e3) && e3 <= t3))(e2))), gte: (e2) => A(m(t2, ((t3) => y((e3) => w(e3) && e3 >= t3))(e2))), positive: () => A(m(t2, y((t3) => w(t3) && t3 > 0))), negative: () => A(m(t2, y((t3) => w(t3) && t3 < 0))) });
156
- A(y(w));
157
- u(y(function(t2) {
158
- return "boolean" == typeof t2;
159
- }));
160
- u(y(function(t2) {
161
- return "symbol" == typeof t2;
162
- }));
163
- u(y(function(t2) {
164
- return null == t2;
165
- }));
166
- u(y(function(t2) {
167
- return null != t2;
168
- }));
169
- var W = { matched: false, value: void 0 };
170
- function $(t2) {
171
- return new z(t2, W);
172
- }
173
- var z = class _z {
174
- constructor(t2, e2) {
175
- this.input = void 0, this.state = void 0, this.input = t2, this.state = e2;
176
- }
177
- with(...t2) {
178
- if (this.state.matched) return this;
179
- const e2 = t2[t2.length - 1], r2 = [t2[0]];
180
- let i2;
181
- 3 === t2.length && "function" == typeof t2[1] ? i2 = t2[1] : t2.length > 2 && r2.push(...t2.slice(1, t2.length - 1));
182
- let s2 = false, c2 = {};
183
- const a2 = (t3, e3) => {
184
- s2 = true, c2[t3] = e3;
185
- }, u2 = !r2.some((t3) => o(t3, this.input, a2)) || i2 && !Boolean(i2(this.input)) ? W : { matched: true, value: e2(s2 ? n in c2 ? c2[n] : c2 : this.input, this.input) };
186
- return new _z(this.input, u2);
187
- }
188
- when(t2, e2) {
189
- if (this.state.matched) return this;
190
- const n2 = Boolean(t2(this.input));
191
- return new _z(this.input, n2 ? { matched: true, value: e2(this.input, this.input) } : W);
192
- }
193
- otherwise(t2) {
194
- return this.state.matched ? this.state.value : t2(this.input);
195
- }
196
- exhaustive() {
197
- if (this.state.matched) return this.state.value;
198
- let t2;
199
- try {
200
- t2 = JSON.stringify(this.input);
201
- } catch (e2) {
202
- t2 = this.input;
203
- }
204
- throw new Error(`Pattern matching error: no pattern matches value ${t2}`);
205
- }
206
- run() {
207
- return this.exhaustive();
208
- }
209
- returnType() {
210
- return this;
211
- }
212
- };
213
-
214
- // src/utils/is-set-function-call.ts
215
32
  function isSetFunctionCall(context, settings) {
216
33
  const isIdFromUseStateCall = isFromUseStateCall(context, settings);
217
34
  return (node) => {
218
35
  switch (node.callee.type) {
219
- case NodeType.Identifier: {
36
+ case AST_NODE_TYPES.Identifier: {
220
37
  return isIdFromUseStateCall(node.callee);
221
38
  }
222
- case NodeType.MemberExpression: {
39
+ case AST_NODE_TYPES.MemberExpression: {
223
40
  if (!("name" in node.callee.object)) return false;
224
41
  const initialScope = context.sourceCode.getScope(node);
225
42
  const property = getStaticValue(node.callee.property, initialScope);
226
43
  if (property?.value === 1) return isIdFromUseStateCall(node.callee.object);
227
44
  return false;
228
45
  }
229
- case NodeType.CallExpression: {
46
+ case AST_NODE_TYPES.CallExpression: {
230
47
  const callee = node.callee.callee;
231
- if (callee.type !== NodeType.MemberExpression) return false;
48
+ if (callee.type !== AST_NODE_TYPES.MemberExpression) return false;
232
49
  if (!("name" in callee.object)) return false;
233
- const isAt = a({
234
- type: NodeType.MemberExpression,
50
+ const isAt = isMatching({
51
+ type: AST_NODE_TYPES.MemberExpression,
235
52
  property: {
236
- type: NodeType.Identifier,
53
+ type: AST_NODE_TYPES.Identifier,
237
54
  name: "at"
238
55
  }
239
56
  }, callee);
@@ -251,17 +68,17 @@ function isSetFunctionCall(context, settings) {
251
68
  };
252
69
  }
253
70
  function isThenCall(node) {
254
- return node.callee.type === NodeType.MemberExpression && node.callee.property.type === NodeType.Identifier && node.callee.property.name === "then";
71
+ return node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.property.type === AST_NODE_TYPES.Identifier && node.callee.property.name === "then";
255
72
  }
256
73
  function isVariableDeclaratorFromHookCall(node) {
257
- if (node.type !== NodeType.VariableDeclarator) return false;
258
- if (node.id.type !== NodeType.Identifier) return false;
259
- if (node.init?.type !== NodeType.CallExpression) return false;
74
+ if (node.type !== AST_NODE_TYPES.VariableDeclarator) return false;
75
+ if (node.id.type !== AST_NODE_TYPES.Identifier) return false;
76
+ if (node.init?.type !== AST_NODE_TYPES.CallExpression) return false;
260
77
  switch (node.init.callee.type) {
261
- case NodeType.Identifier:
78
+ case AST_NODE_TYPES.Identifier:
262
79
  return isReactHookName(node.init.callee.name);
263
- case NodeType.MemberExpression:
264
- return node.init.callee.property.type === NodeType.Identifier && isReactHookName(node.init.callee.property.name);
80
+ case AST_NODE_TYPES.MemberExpression:
81
+ return node.init.callee.property.type === AST_NODE_TYPES.Identifier && isReactHookName(node.init.callee.property.name);
265
82
  default:
266
83
  return false;
267
84
  }
@@ -336,14 +153,14 @@ var ensure_use_callback_has_non_empty_deps_default = createRule({
336
153
  return;
337
154
  }
338
155
  const hasEmptyDeps = F.pipe(
339
- $(deps).with({ type: NodeType.ArrayExpression }, O.some).with({ type: NodeType.Identifier }, (n2) => {
156
+ match(deps).with({ type: AST_NODE_TYPES.ArrayExpression }, O.some).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
340
157
  return F.pipe(
341
- findVariable(n2.name, initialScope),
158
+ findVariable(n.name, initialScope),
342
159
  O.flatMap(getVariableNode(0)),
343
- O.filter(is(NodeType.ArrayExpression))
160
+ O.filter(is(AST_NODE_TYPES.ArrayExpression))
344
161
  );
345
162
  }).otherwise(O.none),
346
- O.exists((x2) => x2.elements.length === 0)
163
+ O.exists((x) => x.elements.length === 0)
347
164
  );
348
165
  if (!hasEmptyDeps) return;
349
166
  if (!cb) {
@@ -354,21 +171,21 @@ var ensure_use_callback_has_non_empty_deps_default = createRule({
354
171
  return;
355
172
  }
356
173
  const isReferencedToComponentScope = F.pipe(
357
- $(cb).with({ type: NodeType.ArrowFunctionExpression }, (n2) => {
358
- if (n2.body.type === NodeType.ArrowFunctionExpression) {
359
- return O.some(n2.body);
174
+ match(cb).with({ type: AST_NODE_TYPES.ArrowFunctionExpression }, (n) => {
175
+ if (n.body.type === AST_NODE_TYPES.ArrowFunctionExpression) {
176
+ return O.some(n.body);
360
177
  }
361
- return O.some(n2);
362
- }).with({ type: NodeType.FunctionExpression }, O.some).with({ type: NodeType.Identifier }, (n2) => {
178
+ return O.some(n);
179
+ }).with({ type: AST_NODE_TYPES.FunctionExpression }, O.some).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
363
180
  return F.pipe(
364
- findVariable(n2.name, initialScope),
181
+ findVariable(n.name, initialScope),
365
182
  O.flatMap(getVariableNode(0)),
366
183
  O.filter(isFunction)
367
184
  );
368
185
  }).otherwise(O.none),
369
- O.map((n2) => context.sourceCode.getScope(n2)),
370
- O.map((s2) => [...s2.childScopes, s2].flatMap((x2) => x2.references)),
371
- O.exists((refs) => refs.some((x2) => x2.resolved?.scope.block === component))
186
+ O.map((n) => context.sourceCode.getScope(n)),
187
+ O.map((s) => [...s.childScopes, s].flatMap((x) => x.references)),
188
+ O.exists((refs) => refs.some((x) => x.resolved?.scope.block === component))
372
189
  );
373
190
  if (isReferencedToComponentScope) return;
374
191
  context.report({
@@ -414,14 +231,14 @@ var ensure_use_memo_has_non_empty_deps_default = createRule({
414
231
  return;
415
232
  }
416
233
  const hasEmptyDeps = F.pipe(
417
- $(deps).with({ type: NodeType.ArrayExpression }, O.some).with({ type: NodeType.Identifier }, (n2) => {
234
+ match(deps).with({ type: AST_NODE_TYPES.ArrayExpression }, O.some).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
418
235
  return F.pipe(
419
- findVariable(n2.name, initialScope),
236
+ findVariable(n.name, initialScope),
420
237
  O.flatMap(getVariableNode(0)),
421
- O.filter(is(NodeType.ArrayExpression))
238
+ O.filter(is(AST_NODE_TYPES.ArrayExpression))
422
239
  );
423
240
  }).otherwise(O.none),
424
- O.exists((x2) => x2.elements.length === 0)
241
+ O.exists((x) => x.elements.length === 0)
425
242
  );
426
243
  if (!hasEmptyDeps) return;
427
244
  if (!cb) {
@@ -432,21 +249,21 @@ var ensure_use_memo_has_non_empty_deps_default = createRule({
432
249
  return;
433
250
  }
434
251
  const isReferencedToComponentScope = F.pipe(
435
- $(cb).with({ type: NodeType.ArrowFunctionExpression }, (n2) => {
436
- if (n2.body.type === NodeType.ArrowFunctionExpression) {
437
- return O.some(n2.body);
252
+ match(cb).with({ type: AST_NODE_TYPES.ArrowFunctionExpression }, (n) => {
253
+ if (n.body.type === AST_NODE_TYPES.ArrowFunctionExpression) {
254
+ return O.some(n.body);
438
255
  }
439
- return O.some(n2);
440
- }).with({ type: NodeType.FunctionExpression }, O.some).with({ type: NodeType.Identifier }, (n2) => {
256
+ return O.some(n);
257
+ }).with({ type: AST_NODE_TYPES.FunctionExpression }, O.some).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
441
258
  return F.pipe(
442
- findVariable(n2.name, initialScope),
259
+ findVariable(n.name, initialScope),
443
260
  O.flatMap(getVariableNode(0)),
444
261
  O.filter(isFunction)
445
262
  );
446
263
  }).otherwise(O.none),
447
- O.map((n2) => context.sourceCode.getScope(n2)),
448
- O.map((s2) => [...s2.childScopes, s2].flatMap((x2) => x2.references)),
449
- O.exists((refs) => refs.some((x2) => x2.resolved?.scope.block === component))
264
+ O.map((n) => context.sourceCode.getScope(n)),
265
+ O.map((s) => [...s.childScopes, s].flatMap((x) => x.references)),
266
+ O.exists((refs) => refs.some((x) => x.resolved?.scope.block === component))
450
267
  );
451
268
  if (isReferencedToComponentScope) return;
452
269
  context.report({
@@ -495,13 +312,13 @@ var no_direct_set_state_in_use_effect_default = createRule({
495
312
  MutRef.update(effectFunctionRef, (current) => current === node ? null : current);
496
313
  };
497
314
  function isEffectFunction(node) {
498
- return node.parent?.type === NodeType.CallExpression && node.parent.callee !== node && isUseEffectCall(node.parent);
315
+ return node.parent?.type === AST_NODE_TYPES.CallExpression && node.parent.callee !== node && isUseEffectCall(node.parent);
499
316
  }
500
317
  function getCallKind(node) {
501
- return $(node).when(isUseStateCall2, () => "useState").when(isUseEffectCall, () => "useEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
318
+ return match(node).when(isUseStateCall2, () => "useState").when(isUseEffectCall, () => "useEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
502
319
  }
503
320
  function getFunctionKind(node) {
504
- return $(node).when(isEffectFunction, () => "effect").when(isIIFE, () => "immediate").otherwise(() => "other");
321
+ return match(node).when(isEffectFunction, () => "effect").when(isFunctionOfImmediatelyInvoked, () => "immediate").otherwise(() => "other");
505
322
  }
506
323
  return {
507
324
  ":function"(node) {
@@ -510,7 +327,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
510
327
  if (functionKind === "effect") onEffectFunctionEnter(node);
511
328
  },
512
329
  ":function:exit"(node) {
513
- const [_2, functionKind] = functionStack.at(-1) ?? [];
330
+ const [_, functionKind] = functionStack.at(-1) ?? [];
514
331
  functionStack.pop();
515
332
  if (functionKind === "effect") onEffectFunctionExit(node);
516
333
  },
@@ -518,7 +335,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
518
335
  const effectFn = MutRef.get(effectFunctionRef);
519
336
  const [parentFn, parentFnKind] = functionStack.at(-1) ?? [];
520
337
  if (parentFn?.async) return;
521
- $(getCallKind(node)).with("setState", () => {
338
+ match(getCallKind(node)).with("setState", () => {
522
339
  if (!parentFn) return;
523
340
  if (parentFn !== effectFn && parentFnKind !== "immediate") {
524
341
  const maybeVd = traverseUpGuard(node, isVariableDeclaratorFromHookCall);
@@ -548,10 +365,10 @@ var no_direct_set_state_in_use_effect_default = createRule({
548
365
  }).otherwise(F.constVoid);
549
366
  },
550
367
  Identifier(node) {
551
- if (node.parent.type === NodeType.CallExpression && node.parent.callee === node) return;
368
+ if (node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node) return;
552
369
  if (!isIdFromUseStateCall(node)) return;
553
370
  switch (node.parent.type) {
554
- case NodeType.CallExpression: {
371
+ case AST_NODE_TYPES.CallExpression: {
555
372
  const [firstArg] = node.parent.arguments;
556
373
  if (node !== firstArg) break;
557
374
  if (isUseCallbackCall2(node.parent)) {
@@ -567,9 +384,9 @@ var no_direct_set_state_in_use_effect_default = createRule({
567
384
  }
568
385
  break;
569
386
  }
570
- case NodeType.ArrowFunctionExpression: {
387
+ case AST_NODE_TYPES.ArrowFunctionExpression: {
571
388
  const parent = node.parent.parent;
572
- if (parent.type !== NodeType.CallExpression) break;
389
+ if (parent.type !== AST_NODE_TYPES.CallExpression) break;
573
390
  if (!isUseMemoCall2(parent)) break;
574
391
  const maybeVd = traverseUpGuard(parent, isVariableDeclaratorFromHookCall);
575
392
  if (O.isNone(maybeVd)) break;
@@ -583,16 +400,16 @@ var no_direct_set_state_in_use_effect_default = createRule({
583
400
  const getSetStateCalls = (id, initialScope) => {
584
401
  const node = O.flatMap(findVariable(id, initialScope), getVariableNode(0)).pipe(O.getOrNull);
585
402
  switch (node?.type) {
586
- case NodeType.FunctionDeclaration:
587
- case NodeType.FunctionExpression:
588
- case NodeType.ArrowFunctionExpression:
403
+ case AST_NODE_TYPES.FunctionDeclaration:
404
+ case AST_NODE_TYPES.FunctionExpression:
405
+ case AST_NODE_TYPES.ArrowFunctionExpression:
589
406
  return indirectSetStateCalls.get(node) ?? [];
590
- case NodeType.CallExpression:
407
+ case AST_NODE_TYPES.CallExpression:
591
408
  return indirectSetStateCallsInHooks.get(node) ?? indirectSetStateCallsAsArgs.get(node) ?? [];
592
409
  }
593
410
  return [];
594
411
  };
595
- for (const [_2, calls] of indirectSetStateCallsAsEFs) {
412
+ for (const [_, calls] of indirectSetStateCallsAsEFs) {
596
413
  for (const call of calls) {
597
414
  context.report({
598
415
  data: { name: call.name },
@@ -669,13 +486,13 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
669
486
  MutRef.update(effectFunctionRef, (current) => current === node ? null : current);
670
487
  };
671
488
  function isEffectFunction(node) {
672
- return node.parent?.type === NodeType.CallExpression && node.parent.callee !== node && isUseEffectCall(node.parent);
489
+ return node.parent?.type === AST_NODE_TYPES.CallExpression && node.parent.callee !== node && isUseEffectCall(node.parent);
673
490
  }
674
491
  function getCallKind(node) {
675
- return $(node).when(isUseStateCall2, () => "useState").when(isUseEffectCall, () => "useLayoutEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
492
+ return match(node).when(isUseStateCall2, () => "useState").when(isUseEffectCall, () => "useLayoutEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
676
493
  }
677
494
  function getFunctionKind(node) {
678
- return $(node).when(isEffectFunction, () => "effect").when(isIIFE, () => "immediate").otherwise(() => "other");
495
+ return match(node).when(isEffectFunction, () => "effect").when(isFunctionOfImmediatelyInvoked, () => "immediate").otherwise(() => "other");
679
496
  }
680
497
  return {
681
498
  ":function"(node) {
@@ -684,7 +501,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
684
501
  if (functionKind === "effect") onEffectFunctionEnter(node);
685
502
  },
686
503
  ":function:exit"(node) {
687
- const [_2, functionKind] = functionStack.at(-1) ?? [];
504
+ const [_, functionKind] = functionStack.at(-1) ?? [];
688
505
  functionStack.pop();
689
506
  if (functionKind === "effect") onEffectFunctionExit(node);
690
507
  },
@@ -692,7 +509,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
692
509
  const effectFn = MutRef.get(effectFunctionRef);
693
510
  const [parentFn, parentFnKind] = functionStack.at(-1) ?? [];
694
511
  if (parentFn?.async) return;
695
- $(getCallKind(node)).with("setState", () => {
512
+ match(getCallKind(node)).with("setState", () => {
696
513
  if (!parentFn) return;
697
514
  if (parentFn !== effectFn && parentFnKind !== "immediate") {
698
515
  const maybeVd = traverseUpGuard(node, isVariableDeclaratorFromHookCall);
@@ -722,10 +539,10 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
722
539
  }).otherwise(F.constVoid);
723
540
  },
724
541
  Identifier(node) {
725
- if (node.parent.type === NodeType.CallExpression && node.parent.callee === node) return;
542
+ if (node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node) return;
726
543
  if (!isIdFromUseStateCall(node)) return;
727
544
  switch (node.parent.type) {
728
- case NodeType.CallExpression: {
545
+ case AST_NODE_TYPES.CallExpression: {
729
546
  const [firstArg] = node.parent.arguments;
730
547
  if (node !== firstArg) break;
731
548
  if (isUseCallbackCall2(node.parent)) {
@@ -741,9 +558,9 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
741
558
  }
742
559
  break;
743
560
  }
744
- case NodeType.ArrowFunctionExpression: {
561
+ case AST_NODE_TYPES.ArrowFunctionExpression: {
745
562
  const parent = node.parent.parent;
746
- if (parent.type !== NodeType.CallExpression) break;
563
+ if (parent.type !== AST_NODE_TYPES.CallExpression) break;
747
564
  if (!isUseMemoCall2(parent)) break;
748
565
  const maybeVd = traverseUpGuard(parent, isVariableDeclaratorFromHookCall);
749
566
  if (O.isNone(maybeVd)) break;
@@ -757,16 +574,16 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
757
574
  const getSetStateCalls = (id, initialScope) => {
758
575
  const node = O.flatMap(findVariable(id, initialScope), getVariableNode(0)).pipe(O.getOrNull);
759
576
  switch (node?.type) {
760
- case NodeType.FunctionDeclaration:
761
- case NodeType.FunctionExpression:
762
- case NodeType.ArrowFunctionExpression:
577
+ case AST_NODE_TYPES.FunctionDeclaration:
578
+ case AST_NODE_TYPES.FunctionExpression:
579
+ case AST_NODE_TYPES.ArrowFunctionExpression:
763
580
  return indirectSetStateCalls.get(node) ?? [];
764
- case NodeType.CallExpression:
581
+ case AST_NODE_TYPES.CallExpression:
765
582
  return indirectSetStateCallsInHooks.get(node) ?? indirectSetStateCallsAsArgs.get(node) ?? [];
766
583
  }
767
584
  return [];
768
585
  };
769
- for (const [_2, calls] of indirectSetStateCallsAsEFs) {
586
+ for (const [_, calls] of indirectSetStateCallsAsEFs) {
770
587
  for (const call of calls) {
771
588
  context.report({
772
589
  data: { name: call.name },
@@ -825,8 +642,8 @@ var prefer_use_state_lazy_initialization_default = createRule({
825
642
  const [useStateInput] = node.arguments;
826
643
  if (!useStateInput) return;
827
644
  const nestedCallExpressions = getNestedCallExpressions(useStateInput);
828
- const hasFunctionCall = nestedCallExpressions.some((n2) => {
829
- return "name" in n2.callee && !ALLOW_LIST.includes(n2.callee.name);
645
+ const hasFunctionCall = nestedCallExpressions.some((n) => {
646
+ return "name" in n.callee && !ALLOW_LIST.includes(n.callee.name);
830
647
  });
831
648
  if (!hasFunctionCall) return;
832
649
  context.report({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-react-hooks-extra",
3
- "version": "1.9.1",
3
+ "version": "1.9.2-beta.4",
4
4
  "description": "ESLint React's ESLint plugin for React Hooks related rules.",
5
5
  "keywords": [
6
6
  "eslint",
@@ -45,13 +45,14 @@
45
45
  "@typescript-eslint/type-utils": "^8.0.1",
46
46
  "@typescript-eslint/types": "^8.0.1",
47
47
  "@typescript-eslint/utils": "^8.0.1",
48
- "@eslint-react/jsx": "1.9.1",
49
- "@eslint-react/tools": "1.9.1",
50
- "@eslint-react/shared": "1.9.1",
51
- "@eslint-react/core": "1.9.1",
52
- "@eslint-react/ast": "1.9.1",
53
- "@eslint-react/types": "1.9.1",
54
- "@eslint-react/var": "1.9.1"
48
+ "ts-pattern": "^5.2.0",
49
+ "@eslint-react/ast": "1.9.2-beta.4",
50
+ "@eslint-react/jsx": "1.9.2-beta.4",
51
+ "@eslint-react/core": "1.9.2-beta.4",
52
+ "@eslint-react/shared": "1.9.2-beta.4",
53
+ "@eslint-react/tools": "1.9.2-beta.4",
54
+ "@eslint-react/var": "1.9.2-beta.4",
55
+ "@eslint-react/types": "1.9.2-beta.4"
55
56
  },
56
57
  "devDependencies": {
57
58
  "@types/react": "^18.3.3",