eslint-plugin-react-hooks-extra 1.9.2-next.3 → 1.9.2-next.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +56 -240
- package/dist/index.mjs +56 -240
- package/package.json +9 -8
package/dist/index.js
CHANGED
|
@@ -7,10 +7,11 @@ var tools = require('@eslint-react/tools');
|
|
|
7
7
|
var _var = require('@eslint-react/var');
|
|
8
8
|
var types = require('@typescript-eslint/types');
|
|
9
9
|
var astUtils = require('@typescript-eslint/utils/ast-utils');
|
|
10
|
+
var tsPattern = require('ts-pattern');
|
|
10
11
|
|
|
11
12
|
// package.json
|
|
12
13
|
var name = "eslint-plugin-react-hooks-extra";
|
|
13
|
-
var version = "1.9.2-next.
|
|
14
|
+
var version = "1.9.2-next.5";
|
|
14
15
|
var createRule = shared.createRuleForPlugin("hooks-extra");
|
|
15
16
|
function isFromHookCall(name2, context, settings, predicate = tools.F.constTrue) {
|
|
16
17
|
const hookAlias = settings.additionalHooks?.[name2] ?? [];
|
|
@@ -26,195 +27,10 @@ function isFromUseStateCall(context, settings) {
|
|
|
26
27
|
const predicate = (topLevelId, call) => {
|
|
27
28
|
const { parent } = call;
|
|
28
29
|
if (!("id" in parent && parent.id?.type === types.AST_NODE_TYPES.ArrayPattern)) return true;
|
|
29
|
-
return parent.id.elements.findIndex((
|
|
30
|
+
return parent.id.elements.findIndex((e) => e?.type === types.AST_NODE_TYPES.Identifier && e.name === topLevelId.name) === 1;
|
|
30
31
|
};
|
|
31
32
|
return isFromHookCall("useState", context, settings, predicate);
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
-
// ../../../node_modules/.pnpm/ts-pattern@5.2.0/node_modules/ts-pattern/dist/index.js
|
|
35
|
-
var t = Symbol.for("@ts-pattern/matcher");
|
|
36
|
-
var e = Symbol.for("@ts-pattern/isVariadic");
|
|
37
|
-
var n = "@ts-pattern/anonymous-select-key";
|
|
38
|
-
var r = (t2) => Boolean(t2 && "object" == typeof t2);
|
|
39
|
-
var i = (e2) => e2 && !!e2[t];
|
|
40
|
-
var o = (n2, s2, c2) => {
|
|
41
|
-
if (i(n2)) {
|
|
42
|
-
const e2 = n2[t](), { matched: r2, selections: i2 } = e2.match(s2);
|
|
43
|
-
return r2 && i2 && Object.keys(i2).forEach((t2) => c2(t2, i2[t2])), r2;
|
|
44
|
-
}
|
|
45
|
-
if (r(n2)) {
|
|
46
|
-
if (!r(s2)) return false;
|
|
47
|
-
if (Array.isArray(n2)) {
|
|
48
|
-
if (!Array.isArray(s2)) return false;
|
|
49
|
-
let t2 = [], r2 = [], a2 = [];
|
|
50
|
-
for (const o2 of n2.keys()) {
|
|
51
|
-
const s3 = n2[o2];
|
|
52
|
-
i(s3) && s3[e] ? a2.push(s3) : a2.length ? r2.push(s3) : t2.push(s3);
|
|
53
|
-
}
|
|
54
|
-
if (a2.length) {
|
|
55
|
-
if (a2.length > 1) throw new Error("Pattern error: Using `...P.array(...)` several times in a single pattern is not allowed.");
|
|
56
|
-
if (s2.length < t2.length + r2.length) return false;
|
|
57
|
-
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);
|
|
58
|
-
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));
|
|
59
|
-
}
|
|
60
|
-
return n2.length === s2.length && n2.every((t3, e2) => o(t3, s2[e2], c2));
|
|
61
|
-
}
|
|
62
|
-
return Object.keys(n2).every((e2) => {
|
|
63
|
-
const r2 = n2[e2];
|
|
64
|
-
return (e2 in s2 || i(a2 = r2) && "optional" === a2[t]().matcherType) && o(r2, s2[e2], c2);
|
|
65
|
-
var a2;
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
return Object.is(s2, n2);
|
|
69
|
-
};
|
|
70
|
-
var s = (e2) => {
|
|
71
|
-
var n2, o2, a2;
|
|
72
|
-
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) : [];
|
|
73
|
-
};
|
|
74
|
-
var c = (t2, e2) => t2.reduce((t3, n2) => t3.concat(e2(n2)), []);
|
|
75
|
-
function a(...t2) {
|
|
76
|
-
if (1 === t2.length) {
|
|
77
|
-
const [e2] = t2;
|
|
78
|
-
return (t3) => o(e2, t3, () => {
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
if (2 === t2.length) {
|
|
82
|
-
const [e2, n2] = t2;
|
|
83
|
-
return o(e2, n2, () => {
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
throw new Error(`isMatching wasn't given the right number of arguments: expected 1 or 2, received ${t2.length}.`);
|
|
87
|
-
}
|
|
88
|
-
function u(t2) {
|
|
89
|
-
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) });
|
|
90
|
-
}
|
|
91
|
-
function l(e2) {
|
|
92
|
-
return u({ [t]: () => ({ match: (t2) => {
|
|
93
|
-
let n2 = {};
|
|
94
|
-
const r2 = (t3, e3) => {
|
|
95
|
-
n2[t3] = e3;
|
|
96
|
-
};
|
|
97
|
-
return void 0 === t2 ? (s(e2).forEach((t3) => r2(t3, void 0)), { matched: true, selections: n2 }) : { matched: o(e2, t2, r2), selections: n2 };
|
|
98
|
-
}, getSelectionKeys: () => s(e2), matcherType: "optional" }) });
|
|
99
|
-
}
|
|
100
|
-
function m(...e2) {
|
|
101
|
-
return u({ [t]: () => ({ match: (t2) => {
|
|
102
|
-
let n2 = {};
|
|
103
|
-
const r2 = (t3, e3) => {
|
|
104
|
-
n2[t3] = e3;
|
|
105
|
-
};
|
|
106
|
-
return { matched: e2.every((e3) => o(e3, t2, r2)), selections: n2 };
|
|
107
|
-
}, getSelectionKeys: () => c(e2, s), matcherType: "and" }) });
|
|
108
|
-
}
|
|
109
|
-
function d(...e2) {
|
|
110
|
-
return u({ [t]: () => ({ match: (t2) => {
|
|
111
|
-
let n2 = {};
|
|
112
|
-
const r2 = (t3, e3) => {
|
|
113
|
-
n2[t3] = e3;
|
|
114
|
-
};
|
|
115
|
-
return c(e2, s).forEach((t3) => r2(t3, void 0)), { matched: e2.some((e3) => o(e3, t2, r2)), selections: n2 };
|
|
116
|
-
}, getSelectionKeys: () => c(e2, s), matcherType: "or" }) });
|
|
117
|
-
}
|
|
118
|
-
function y(e2) {
|
|
119
|
-
return { [t]: () => ({ match: (t2) => ({ matched: Boolean(e2(t2)) }) }) };
|
|
120
|
-
}
|
|
121
|
-
function p(...e2) {
|
|
122
|
-
const r2 = "string" == typeof e2[0] ? e2[0] : void 0, i2 = 2 === e2.length ? e2[1] : "string" == typeof e2[0] ? void 0 : e2[0];
|
|
123
|
-
return u({ [t]: () => ({ match: (t2) => {
|
|
124
|
-
let e3 = { [null != r2 ? r2 : n]: t2 };
|
|
125
|
-
return { matched: void 0 === i2 || o(i2, t2, (t3, n2) => {
|
|
126
|
-
e3[t3] = n2;
|
|
127
|
-
}), selections: e3 };
|
|
128
|
-
}, getSelectionKeys: () => [null != r2 ? r2 : n].concat(void 0 === i2 ? [] : s(i2)) }) });
|
|
129
|
-
}
|
|
130
|
-
function v(t2) {
|
|
131
|
-
return "number" == typeof t2;
|
|
132
|
-
}
|
|
133
|
-
function b(t2) {
|
|
134
|
-
return "string" == typeof t2;
|
|
135
|
-
}
|
|
136
|
-
function w(t2) {
|
|
137
|
-
return "bigint" == typeof t2;
|
|
138
|
-
}
|
|
139
|
-
u(y(function(t2) {
|
|
140
|
-
return true;
|
|
141
|
-
}));
|
|
142
|
-
var j = (t2) => Object.assign(u(t2), { startsWith: (e2) => {
|
|
143
|
-
return j(m(t2, (n2 = e2, y((t3) => b(t3) && t3.startsWith(n2)))));
|
|
144
|
-
var n2;
|
|
145
|
-
}, endsWith: (e2) => {
|
|
146
|
-
return j(m(t2, (n2 = e2, y((t3) => b(t3) && t3.endsWith(n2)))));
|
|
147
|
-
var n2;
|
|
148
|
-
}, 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) => {
|
|
149
|
-
return j(m(t2, (n2 = e2, y((t3) => b(t3) && t3.includes(n2)))));
|
|
150
|
-
var n2;
|
|
151
|
-
}, regex: (e2) => {
|
|
152
|
-
return j(m(t2, (n2 = e2, y((t3) => b(t3) && Boolean(t3.match(n2))))));
|
|
153
|
-
var n2;
|
|
154
|
-
} });
|
|
155
|
-
j(y(b));
|
|
156
|
-
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))) });
|
|
157
|
-
K(y(v));
|
|
158
|
-
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))) });
|
|
159
|
-
A(y(w));
|
|
160
|
-
u(y(function(t2) {
|
|
161
|
-
return "boolean" == typeof t2;
|
|
162
|
-
}));
|
|
163
|
-
u(y(function(t2) {
|
|
164
|
-
return "symbol" == typeof t2;
|
|
165
|
-
}));
|
|
166
|
-
u(y(function(t2) {
|
|
167
|
-
return null == t2;
|
|
168
|
-
}));
|
|
169
|
-
u(y(function(t2) {
|
|
170
|
-
return null != t2;
|
|
171
|
-
}));
|
|
172
|
-
var W = { matched: false, value: void 0 };
|
|
173
|
-
function $(t2) {
|
|
174
|
-
return new z(t2, W);
|
|
175
|
-
}
|
|
176
|
-
var z = class _z {
|
|
177
|
-
constructor(t2, e2) {
|
|
178
|
-
this.input = void 0, this.state = void 0, this.input = t2, this.state = e2;
|
|
179
|
-
}
|
|
180
|
-
with(...t2) {
|
|
181
|
-
if (this.state.matched) return this;
|
|
182
|
-
const e2 = t2[t2.length - 1], r2 = [t2[0]];
|
|
183
|
-
let i2;
|
|
184
|
-
3 === t2.length && "function" == typeof t2[1] ? i2 = t2[1] : t2.length > 2 && r2.push(...t2.slice(1, t2.length - 1));
|
|
185
|
-
let s2 = false, c2 = {};
|
|
186
|
-
const a2 = (t3, e3) => {
|
|
187
|
-
s2 = true, c2[t3] = e3;
|
|
188
|
-
}, 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) };
|
|
189
|
-
return new _z(this.input, u2);
|
|
190
|
-
}
|
|
191
|
-
when(t2, e2) {
|
|
192
|
-
if (this.state.matched) return this;
|
|
193
|
-
const n2 = Boolean(t2(this.input));
|
|
194
|
-
return new _z(this.input, n2 ? { matched: true, value: e2(this.input, this.input) } : W);
|
|
195
|
-
}
|
|
196
|
-
otherwise(t2) {
|
|
197
|
-
return this.state.matched ? this.state.value : t2(this.input);
|
|
198
|
-
}
|
|
199
|
-
exhaustive() {
|
|
200
|
-
if (this.state.matched) return this.state.value;
|
|
201
|
-
let t2;
|
|
202
|
-
try {
|
|
203
|
-
t2 = JSON.stringify(this.input);
|
|
204
|
-
} catch (e2) {
|
|
205
|
-
t2 = this.input;
|
|
206
|
-
}
|
|
207
|
-
throw new Error(`Pattern matching error: no pattern matches value ${t2}`);
|
|
208
|
-
}
|
|
209
|
-
run() {
|
|
210
|
-
return this.exhaustive();
|
|
211
|
-
}
|
|
212
|
-
returnType() {
|
|
213
|
-
return this;
|
|
214
|
-
}
|
|
215
|
-
};
|
|
216
|
-
|
|
217
|
-
// src/utils/is-set-function-call.ts
|
|
218
34
|
function isSetFunctionCall(context, settings) {
|
|
219
35
|
const isIdFromUseStateCall = isFromUseStateCall(context, settings);
|
|
220
36
|
return (node) => {
|
|
@@ -233,7 +49,7 @@ function isSetFunctionCall(context, settings) {
|
|
|
233
49
|
const callee = node.callee.callee;
|
|
234
50
|
if (callee.type !== types.AST_NODE_TYPES.MemberExpression) return false;
|
|
235
51
|
if (!("name" in callee.object)) return false;
|
|
236
|
-
const isAt =
|
|
52
|
+
const isAt = tsPattern.isMatching({
|
|
237
53
|
type: types.AST_NODE_TYPES.MemberExpression,
|
|
238
54
|
property: {
|
|
239
55
|
type: types.AST_NODE_TYPES.Identifier,
|
|
@@ -290,14 +106,14 @@ var ensure_custom_hooks_using_other_hooks_default = createRule({
|
|
|
290
106
|
...listeners,
|
|
291
107
|
"Program:exit"(node) {
|
|
292
108
|
const allHooks = ctx.getAllHooks(node);
|
|
293
|
-
for (const { name: name2,
|
|
109
|
+
for (const { name: name2, node: node2, hookCalls } of allHooks.values()) {
|
|
294
110
|
if (hookCalls.length > 0) continue;
|
|
295
111
|
context.report({
|
|
112
|
+
messageId: "ensureCustomHooksUsingOtherHooks",
|
|
113
|
+
node: node2,
|
|
296
114
|
data: {
|
|
297
115
|
name: name2.value
|
|
298
|
-
}
|
|
299
|
-
messageId: "ensureCustomHooksUsingOtherHooks",
|
|
300
|
-
node: node2
|
|
116
|
+
}
|
|
301
117
|
});
|
|
302
118
|
}
|
|
303
119
|
}
|
|
@@ -339,14 +155,14 @@ var ensure_use_callback_has_non_empty_deps_default = createRule({
|
|
|
339
155
|
return;
|
|
340
156
|
}
|
|
341
157
|
const hasEmptyDeps = tools.F.pipe(
|
|
342
|
-
|
|
158
|
+
tsPattern.match(deps).with({ type: types.AST_NODE_TYPES.ArrayExpression }, tools.O.some).with({ type: types.AST_NODE_TYPES.Identifier }, (n) => {
|
|
343
159
|
return tools.F.pipe(
|
|
344
|
-
_var.findVariable(
|
|
160
|
+
_var.findVariable(n.name, initialScope),
|
|
345
161
|
tools.O.flatMap(_var.getVariableNode(0)),
|
|
346
162
|
tools.O.filter(ast.is(types.AST_NODE_TYPES.ArrayExpression))
|
|
347
163
|
);
|
|
348
164
|
}).otherwise(tools.O.none),
|
|
349
|
-
tools.O.exists((
|
|
165
|
+
tools.O.exists((x) => x.elements.length === 0)
|
|
350
166
|
);
|
|
351
167
|
if (!hasEmptyDeps) return;
|
|
352
168
|
if (!cb) {
|
|
@@ -357,21 +173,21 @@ var ensure_use_callback_has_non_empty_deps_default = createRule({
|
|
|
357
173
|
return;
|
|
358
174
|
}
|
|
359
175
|
const isReferencedToComponentScope = tools.F.pipe(
|
|
360
|
-
|
|
361
|
-
if (
|
|
362
|
-
return tools.O.some(
|
|
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);
|
|
363
179
|
}
|
|
364
|
-
return tools.O.some(
|
|
365
|
-
}).with({ type: types.AST_NODE_TYPES.FunctionExpression }, tools.O.some).with({ type: types.AST_NODE_TYPES.Identifier }, (
|
|
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) => {
|
|
366
182
|
return tools.F.pipe(
|
|
367
|
-
_var.findVariable(
|
|
183
|
+
_var.findVariable(n.name, initialScope),
|
|
368
184
|
tools.O.flatMap(_var.getVariableNode(0)),
|
|
369
185
|
tools.O.filter(ast.isFunction)
|
|
370
186
|
);
|
|
371
187
|
}).otherwise(tools.O.none),
|
|
372
|
-
tools.O.map((
|
|
373
|
-
tools.O.map((
|
|
374
|
-
tools.O.exists((refs) => refs.some((
|
|
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))
|
|
375
191
|
);
|
|
376
192
|
if (isReferencedToComponentScope) return;
|
|
377
193
|
context.report({
|
|
@@ -417,14 +233,14 @@ var ensure_use_memo_has_non_empty_deps_default = createRule({
|
|
|
417
233
|
return;
|
|
418
234
|
}
|
|
419
235
|
const hasEmptyDeps = tools.F.pipe(
|
|
420
|
-
|
|
236
|
+
tsPattern.match(deps).with({ type: types.AST_NODE_TYPES.ArrayExpression }, tools.O.some).with({ type: types.AST_NODE_TYPES.Identifier }, (n) => {
|
|
421
237
|
return tools.F.pipe(
|
|
422
|
-
_var.findVariable(
|
|
238
|
+
_var.findVariable(n.name, initialScope),
|
|
423
239
|
tools.O.flatMap(_var.getVariableNode(0)),
|
|
424
240
|
tools.O.filter(ast.is(types.AST_NODE_TYPES.ArrayExpression))
|
|
425
241
|
);
|
|
426
242
|
}).otherwise(tools.O.none),
|
|
427
|
-
tools.O.exists((
|
|
243
|
+
tools.O.exists((x) => x.elements.length === 0)
|
|
428
244
|
);
|
|
429
245
|
if (!hasEmptyDeps) return;
|
|
430
246
|
if (!cb) {
|
|
@@ -435,21 +251,21 @@ var ensure_use_memo_has_non_empty_deps_default = createRule({
|
|
|
435
251
|
return;
|
|
436
252
|
}
|
|
437
253
|
const isReferencedToComponentScope = tools.F.pipe(
|
|
438
|
-
|
|
439
|
-
if (
|
|
440
|
-
return tools.O.some(
|
|
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);
|
|
441
257
|
}
|
|
442
|
-
return tools.O.some(
|
|
443
|
-
}).with({ type: types.AST_NODE_TYPES.FunctionExpression }, tools.O.some).with({ type: types.AST_NODE_TYPES.Identifier }, (
|
|
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) => {
|
|
444
260
|
return tools.F.pipe(
|
|
445
|
-
_var.findVariable(
|
|
261
|
+
_var.findVariable(n.name, initialScope),
|
|
446
262
|
tools.O.flatMap(_var.getVariableNode(0)),
|
|
447
263
|
tools.O.filter(ast.isFunction)
|
|
448
264
|
);
|
|
449
265
|
}).otherwise(tools.O.none),
|
|
450
|
-
tools.O.map((
|
|
451
|
-
tools.O.map((
|
|
452
|
-
tools.O.exists((refs) => refs.some((
|
|
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))
|
|
453
269
|
);
|
|
454
270
|
if (isReferencedToComponentScope) return;
|
|
455
271
|
context.report({
|
|
@@ -501,10 +317,10 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
501
317
|
return node.parent?.type === types.AST_NODE_TYPES.CallExpression && node.parent.callee !== node && isUseEffectCall(node.parent);
|
|
502
318
|
}
|
|
503
319
|
function getCallKind(node) {
|
|
504
|
-
return
|
|
320
|
+
return tsPattern.match(node).when(isUseStateCall2, () => "useState").when(isUseEffectCall, () => "useEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
|
|
505
321
|
}
|
|
506
322
|
function getFunctionKind(node) {
|
|
507
|
-
return
|
|
323
|
+
return tsPattern.match(node).when(isEffectFunction, () => "effect").when(ast.isFunctionOfImmediatelyInvoked, () => "immediate").otherwise(() => "other");
|
|
508
324
|
}
|
|
509
325
|
return {
|
|
510
326
|
":function"(node) {
|
|
@@ -513,7 +329,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
513
329
|
if (functionKind === "effect") onEffectFunctionEnter(node);
|
|
514
330
|
},
|
|
515
331
|
":function:exit"(node) {
|
|
516
|
-
const [
|
|
332
|
+
const [_, functionKind] = functionStack.at(-1) ?? [];
|
|
517
333
|
functionStack.pop();
|
|
518
334
|
if (functionKind === "effect") onEffectFunctionExit(node);
|
|
519
335
|
},
|
|
@@ -521,7 +337,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
521
337
|
const effectFn = tools.MutRef.get(effectFunctionRef);
|
|
522
338
|
const [parentFn, parentFnKind] = functionStack.at(-1) ?? [];
|
|
523
339
|
if (parentFn?.async) return;
|
|
524
|
-
|
|
340
|
+
tsPattern.match(getCallKind(node)).with("setState", () => {
|
|
525
341
|
if (!parentFn) return;
|
|
526
342
|
if (parentFn !== effectFn && parentFnKind !== "immediate") {
|
|
527
343
|
const maybeVd = ast.traverseUpGuard(node, isVariableDeclaratorFromHookCall);
|
|
@@ -595,12 +411,12 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
595
411
|
}
|
|
596
412
|
return [];
|
|
597
413
|
};
|
|
598
|
-
for (const [
|
|
414
|
+
for (const [_, calls] of indirectSetStateCallsAsEFs) {
|
|
599
415
|
for (const call of calls) {
|
|
600
416
|
context.report({
|
|
601
|
-
data: { name: call.name },
|
|
602
417
|
messageId: "noDirectSetStateInUseEffect",
|
|
603
|
-
node: call
|
|
418
|
+
node: call,
|
|
419
|
+
data: { name: call.name }
|
|
604
420
|
});
|
|
605
421
|
}
|
|
606
422
|
}
|
|
@@ -610,9 +426,9 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
610
426
|
const setStateCalls = getSetStateCalls(name2, context.sourceCode.getScope(callee));
|
|
611
427
|
for (const setStateCall of setStateCalls) {
|
|
612
428
|
context.report({
|
|
613
|
-
data: { name: name2 },
|
|
614
429
|
messageId: "noDirectSetStateInUseEffect",
|
|
615
|
-
node: setStateCall
|
|
430
|
+
node: setStateCall,
|
|
431
|
+
data: { name: name2 }
|
|
616
432
|
});
|
|
617
433
|
}
|
|
618
434
|
}
|
|
@@ -620,9 +436,9 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
620
436
|
const setStateCalls = getSetStateCalls(id.name, context.sourceCode.getScope(id));
|
|
621
437
|
for (const setStateCall of setStateCalls) {
|
|
622
438
|
context.report({
|
|
623
|
-
data: { name: id.name },
|
|
624
439
|
messageId: "noDirectSetStateInUseEffect",
|
|
625
|
-
node: setStateCall
|
|
440
|
+
node: setStateCall,
|
|
441
|
+
data: { name: id.name }
|
|
626
442
|
});
|
|
627
443
|
}
|
|
628
444
|
}
|
|
@@ -675,10 +491,10 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
675
491
|
return node.parent?.type === types.AST_NODE_TYPES.CallExpression && node.parent.callee !== node && isUseEffectCall(node.parent);
|
|
676
492
|
}
|
|
677
493
|
function getCallKind(node) {
|
|
678
|
-
return
|
|
494
|
+
return tsPattern.match(node).when(isUseStateCall2, () => "useState").when(isUseEffectCall, () => "useLayoutEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
|
|
679
495
|
}
|
|
680
496
|
function getFunctionKind(node) {
|
|
681
|
-
return
|
|
497
|
+
return tsPattern.match(node).when(isEffectFunction, () => "effect").when(ast.isFunctionOfImmediatelyInvoked, () => "immediate").otherwise(() => "other");
|
|
682
498
|
}
|
|
683
499
|
return {
|
|
684
500
|
":function"(node) {
|
|
@@ -687,7 +503,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
687
503
|
if (functionKind === "effect") onEffectFunctionEnter(node);
|
|
688
504
|
},
|
|
689
505
|
":function:exit"(node) {
|
|
690
|
-
const [
|
|
506
|
+
const [_, functionKind] = functionStack.at(-1) ?? [];
|
|
691
507
|
functionStack.pop();
|
|
692
508
|
if (functionKind === "effect") onEffectFunctionExit(node);
|
|
693
509
|
},
|
|
@@ -695,7 +511,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
695
511
|
const effectFn = tools.MutRef.get(effectFunctionRef);
|
|
696
512
|
const [parentFn, parentFnKind] = functionStack.at(-1) ?? [];
|
|
697
513
|
if (parentFn?.async) return;
|
|
698
|
-
|
|
514
|
+
tsPattern.match(getCallKind(node)).with("setState", () => {
|
|
699
515
|
if (!parentFn) return;
|
|
700
516
|
if (parentFn !== effectFn && parentFnKind !== "immediate") {
|
|
701
517
|
const maybeVd = ast.traverseUpGuard(node, isVariableDeclaratorFromHookCall);
|
|
@@ -769,12 +585,12 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
769
585
|
}
|
|
770
586
|
return [];
|
|
771
587
|
};
|
|
772
|
-
for (const [
|
|
588
|
+
for (const [_, calls] of indirectSetStateCallsAsEFs) {
|
|
773
589
|
for (const call of calls) {
|
|
774
590
|
context.report({
|
|
775
|
-
data: { name: call.name },
|
|
776
591
|
messageId: "noDirectSetStateInUseLayoutEffect",
|
|
777
|
-
node: call
|
|
592
|
+
node: call,
|
|
593
|
+
data: { name: call.name }
|
|
778
594
|
});
|
|
779
595
|
}
|
|
780
596
|
}
|
|
@@ -784,9 +600,9 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
784
600
|
const setStateCalls = getSetStateCalls(name2, context.sourceCode.getScope(callee));
|
|
785
601
|
for (const setStateCall of setStateCalls) {
|
|
786
602
|
context.report({
|
|
787
|
-
data: { name: name2 },
|
|
788
603
|
messageId: "noDirectSetStateInUseLayoutEffect",
|
|
789
|
-
node: setStateCall
|
|
604
|
+
node: setStateCall,
|
|
605
|
+
data: { name: name2 }
|
|
790
606
|
});
|
|
791
607
|
}
|
|
792
608
|
}
|
|
@@ -794,9 +610,9 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
794
610
|
const setStateCalls = getSetStateCalls(id.name, context.sourceCode.getScope(id));
|
|
795
611
|
for (const setStateCall of setStateCalls) {
|
|
796
612
|
context.report({
|
|
797
|
-
data: { name: id.name },
|
|
798
613
|
messageId: "noDirectSetStateInUseLayoutEffect",
|
|
799
|
-
node: setStateCall
|
|
614
|
+
node: setStateCall,
|
|
615
|
+
data: { name: id.name }
|
|
800
616
|
});
|
|
801
617
|
}
|
|
802
618
|
}
|
|
@@ -828,8 +644,8 @@ var prefer_use_state_lazy_initialization_default = createRule({
|
|
|
828
644
|
const [useStateInput] = node.arguments;
|
|
829
645
|
if (!useStateInput) return;
|
|
830
646
|
const nestedCallExpressions = ast.getNestedCallExpressions(useStateInput);
|
|
831
|
-
const hasFunctionCall = nestedCallExpressions.some((
|
|
832
|
-
return "name" in
|
|
647
|
+
const hasFunctionCall = nestedCallExpressions.some((n) => {
|
|
648
|
+
return "name" in n.callee && !ALLOW_LIST.includes(n.callee.name);
|
|
833
649
|
});
|
|
834
650
|
if (!hasFunctionCall) return;
|
|
835
651
|
context.report({
|
package/dist/index.mjs
CHANGED
|
@@ -5,10 +5,11 @@ import { F, O, MutRef } from '@eslint-react/tools';
|
|
|
5
5
|
import { findVariable, getVariableNode } from '@eslint-react/var';
|
|
6
6
|
import { AST_NODE_TYPES } from '@typescript-eslint/types';
|
|
7
7
|
import { getStaticValue } from '@typescript-eslint/utils/ast-utils';
|
|
8
|
+
import { match, isMatching } from 'ts-pattern';
|
|
8
9
|
|
|
9
10
|
// package.json
|
|
10
11
|
var name = "eslint-plugin-react-hooks-extra";
|
|
11
|
-
var version = "1.9.2-next.
|
|
12
|
+
var version = "1.9.2-next.5";
|
|
12
13
|
var createRule = createRuleForPlugin("hooks-extra");
|
|
13
14
|
function isFromHookCall(name2, context, settings, predicate = F.constTrue) {
|
|
14
15
|
const hookAlias = settings.additionalHooks?.[name2] ?? [];
|
|
@@ -24,195 +25,10 @@ function isFromUseStateCall(context, settings) {
|
|
|
24
25
|
const predicate = (topLevelId, call) => {
|
|
25
26
|
const { parent } = call;
|
|
26
27
|
if (!("id" in parent && parent.id?.type === AST_NODE_TYPES.ArrayPattern)) return true;
|
|
27
|
-
return parent.id.elements.findIndex((
|
|
28
|
+
return parent.id.elements.findIndex((e) => e?.type === AST_NODE_TYPES.Identifier && e.name === topLevelId.name) === 1;
|
|
28
29
|
};
|
|
29
30
|
return isFromHookCall("useState", context, settings, predicate);
|
|
30
31
|
}
|
|
31
|
-
|
|
32
|
-
// ../../../node_modules/.pnpm/ts-pattern@5.2.0/node_modules/ts-pattern/dist/index.js
|
|
33
|
-
var t = Symbol.for("@ts-pattern/matcher");
|
|
34
|
-
var e = Symbol.for("@ts-pattern/isVariadic");
|
|
35
|
-
var n = "@ts-pattern/anonymous-select-key";
|
|
36
|
-
var r = (t2) => Boolean(t2 && "object" == typeof t2);
|
|
37
|
-
var i = (e2) => e2 && !!e2[t];
|
|
38
|
-
var o = (n2, s2, c2) => {
|
|
39
|
-
if (i(n2)) {
|
|
40
|
-
const e2 = n2[t](), { matched: r2, selections: i2 } = e2.match(s2);
|
|
41
|
-
return r2 && i2 && Object.keys(i2).forEach((t2) => c2(t2, i2[t2])), r2;
|
|
42
|
-
}
|
|
43
|
-
if (r(n2)) {
|
|
44
|
-
if (!r(s2)) return false;
|
|
45
|
-
if (Array.isArray(n2)) {
|
|
46
|
-
if (!Array.isArray(s2)) return false;
|
|
47
|
-
let t2 = [], r2 = [], a2 = [];
|
|
48
|
-
for (const o2 of n2.keys()) {
|
|
49
|
-
const s3 = n2[o2];
|
|
50
|
-
i(s3) && s3[e] ? a2.push(s3) : a2.length ? r2.push(s3) : t2.push(s3);
|
|
51
|
-
}
|
|
52
|
-
if (a2.length) {
|
|
53
|
-
if (a2.length > 1) throw new Error("Pattern error: Using `...P.array(...)` several times in a single pattern is not allowed.");
|
|
54
|
-
if (s2.length < t2.length + r2.length) return false;
|
|
55
|
-
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);
|
|
56
|
-
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));
|
|
57
|
-
}
|
|
58
|
-
return n2.length === s2.length && n2.every((t3, e2) => o(t3, s2[e2], c2));
|
|
59
|
-
}
|
|
60
|
-
return Object.keys(n2).every((e2) => {
|
|
61
|
-
const r2 = n2[e2];
|
|
62
|
-
return (e2 in s2 || i(a2 = r2) && "optional" === a2[t]().matcherType) && o(r2, s2[e2], c2);
|
|
63
|
-
var a2;
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
return Object.is(s2, n2);
|
|
67
|
-
};
|
|
68
|
-
var s = (e2) => {
|
|
69
|
-
var n2, o2, a2;
|
|
70
|
-
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) : [];
|
|
71
|
-
};
|
|
72
|
-
var c = (t2, e2) => t2.reduce((t3, n2) => t3.concat(e2(n2)), []);
|
|
73
|
-
function a(...t2) {
|
|
74
|
-
if (1 === t2.length) {
|
|
75
|
-
const [e2] = t2;
|
|
76
|
-
return (t3) => o(e2, t3, () => {
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
if (2 === t2.length) {
|
|
80
|
-
const [e2, n2] = t2;
|
|
81
|
-
return o(e2, n2, () => {
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
throw new Error(`isMatching wasn't given the right number of arguments: expected 1 or 2, received ${t2.length}.`);
|
|
85
|
-
}
|
|
86
|
-
function u(t2) {
|
|
87
|
-
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) });
|
|
88
|
-
}
|
|
89
|
-
function l(e2) {
|
|
90
|
-
return u({ [t]: () => ({ match: (t2) => {
|
|
91
|
-
let n2 = {};
|
|
92
|
-
const r2 = (t3, e3) => {
|
|
93
|
-
n2[t3] = e3;
|
|
94
|
-
};
|
|
95
|
-
return void 0 === t2 ? (s(e2).forEach((t3) => r2(t3, void 0)), { matched: true, selections: n2 }) : { matched: o(e2, t2, r2), selections: n2 };
|
|
96
|
-
}, getSelectionKeys: () => s(e2), matcherType: "optional" }) });
|
|
97
|
-
}
|
|
98
|
-
function m(...e2) {
|
|
99
|
-
return u({ [t]: () => ({ match: (t2) => {
|
|
100
|
-
let n2 = {};
|
|
101
|
-
const r2 = (t3, e3) => {
|
|
102
|
-
n2[t3] = e3;
|
|
103
|
-
};
|
|
104
|
-
return { matched: e2.every((e3) => o(e3, t2, r2)), selections: n2 };
|
|
105
|
-
}, getSelectionKeys: () => c(e2, s), matcherType: "and" }) });
|
|
106
|
-
}
|
|
107
|
-
function d(...e2) {
|
|
108
|
-
return u({ [t]: () => ({ match: (t2) => {
|
|
109
|
-
let n2 = {};
|
|
110
|
-
const r2 = (t3, e3) => {
|
|
111
|
-
n2[t3] = e3;
|
|
112
|
-
};
|
|
113
|
-
return c(e2, s).forEach((t3) => r2(t3, void 0)), { matched: e2.some((e3) => o(e3, t2, r2)), selections: n2 };
|
|
114
|
-
}, getSelectionKeys: () => c(e2, s), matcherType: "or" }) });
|
|
115
|
-
}
|
|
116
|
-
function y(e2) {
|
|
117
|
-
return { [t]: () => ({ match: (t2) => ({ matched: Boolean(e2(t2)) }) }) };
|
|
118
|
-
}
|
|
119
|
-
function p(...e2) {
|
|
120
|
-
const r2 = "string" == typeof e2[0] ? e2[0] : void 0, i2 = 2 === e2.length ? e2[1] : "string" == typeof e2[0] ? void 0 : e2[0];
|
|
121
|
-
return u({ [t]: () => ({ match: (t2) => {
|
|
122
|
-
let e3 = { [null != r2 ? r2 : n]: t2 };
|
|
123
|
-
return { matched: void 0 === i2 || o(i2, t2, (t3, n2) => {
|
|
124
|
-
e3[t3] = n2;
|
|
125
|
-
}), selections: e3 };
|
|
126
|
-
}, getSelectionKeys: () => [null != r2 ? r2 : n].concat(void 0 === i2 ? [] : s(i2)) }) });
|
|
127
|
-
}
|
|
128
|
-
function v(t2) {
|
|
129
|
-
return "number" == typeof t2;
|
|
130
|
-
}
|
|
131
|
-
function b(t2) {
|
|
132
|
-
return "string" == typeof t2;
|
|
133
|
-
}
|
|
134
|
-
function w(t2) {
|
|
135
|
-
return "bigint" == typeof t2;
|
|
136
|
-
}
|
|
137
|
-
u(y(function(t2) {
|
|
138
|
-
return true;
|
|
139
|
-
}));
|
|
140
|
-
var j = (t2) => Object.assign(u(t2), { startsWith: (e2) => {
|
|
141
|
-
return j(m(t2, (n2 = e2, y((t3) => b(t3) && t3.startsWith(n2)))));
|
|
142
|
-
var n2;
|
|
143
|
-
}, endsWith: (e2) => {
|
|
144
|
-
return j(m(t2, (n2 = e2, y((t3) => b(t3) && t3.endsWith(n2)))));
|
|
145
|
-
var n2;
|
|
146
|
-
}, 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) => {
|
|
147
|
-
return j(m(t2, (n2 = e2, y((t3) => b(t3) && t3.includes(n2)))));
|
|
148
|
-
var n2;
|
|
149
|
-
}, regex: (e2) => {
|
|
150
|
-
return j(m(t2, (n2 = e2, y((t3) => b(t3) && Boolean(t3.match(n2))))));
|
|
151
|
-
var n2;
|
|
152
|
-
} });
|
|
153
|
-
j(y(b));
|
|
154
|
-
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))) });
|
|
155
|
-
K(y(v));
|
|
156
|
-
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))) });
|
|
157
|
-
A(y(w));
|
|
158
|
-
u(y(function(t2) {
|
|
159
|
-
return "boolean" == typeof t2;
|
|
160
|
-
}));
|
|
161
|
-
u(y(function(t2) {
|
|
162
|
-
return "symbol" == typeof t2;
|
|
163
|
-
}));
|
|
164
|
-
u(y(function(t2) {
|
|
165
|
-
return null == t2;
|
|
166
|
-
}));
|
|
167
|
-
u(y(function(t2) {
|
|
168
|
-
return null != t2;
|
|
169
|
-
}));
|
|
170
|
-
var W = { matched: false, value: void 0 };
|
|
171
|
-
function $(t2) {
|
|
172
|
-
return new z(t2, W);
|
|
173
|
-
}
|
|
174
|
-
var z = class _z {
|
|
175
|
-
constructor(t2, e2) {
|
|
176
|
-
this.input = void 0, this.state = void 0, this.input = t2, this.state = e2;
|
|
177
|
-
}
|
|
178
|
-
with(...t2) {
|
|
179
|
-
if (this.state.matched) return this;
|
|
180
|
-
const e2 = t2[t2.length - 1], r2 = [t2[0]];
|
|
181
|
-
let i2;
|
|
182
|
-
3 === t2.length && "function" == typeof t2[1] ? i2 = t2[1] : t2.length > 2 && r2.push(...t2.slice(1, t2.length - 1));
|
|
183
|
-
let s2 = false, c2 = {};
|
|
184
|
-
const a2 = (t3, e3) => {
|
|
185
|
-
s2 = true, c2[t3] = e3;
|
|
186
|
-
}, 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) };
|
|
187
|
-
return new _z(this.input, u2);
|
|
188
|
-
}
|
|
189
|
-
when(t2, e2) {
|
|
190
|
-
if (this.state.matched) return this;
|
|
191
|
-
const n2 = Boolean(t2(this.input));
|
|
192
|
-
return new _z(this.input, n2 ? { matched: true, value: e2(this.input, this.input) } : W);
|
|
193
|
-
}
|
|
194
|
-
otherwise(t2) {
|
|
195
|
-
return this.state.matched ? this.state.value : t2(this.input);
|
|
196
|
-
}
|
|
197
|
-
exhaustive() {
|
|
198
|
-
if (this.state.matched) return this.state.value;
|
|
199
|
-
let t2;
|
|
200
|
-
try {
|
|
201
|
-
t2 = JSON.stringify(this.input);
|
|
202
|
-
} catch (e2) {
|
|
203
|
-
t2 = this.input;
|
|
204
|
-
}
|
|
205
|
-
throw new Error(`Pattern matching error: no pattern matches value ${t2}`);
|
|
206
|
-
}
|
|
207
|
-
run() {
|
|
208
|
-
return this.exhaustive();
|
|
209
|
-
}
|
|
210
|
-
returnType() {
|
|
211
|
-
return this;
|
|
212
|
-
}
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
// src/utils/is-set-function-call.ts
|
|
216
32
|
function isSetFunctionCall(context, settings) {
|
|
217
33
|
const isIdFromUseStateCall = isFromUseStateCall(context, settings);
|
|
218
34
|
return (node) => {
|
|
@@ -231,7 +47,7 @@ function isSetFunctionCall(context, settings) {
|
|
|
231
47
|
const callee = node.callee.callee;
|
|
232
48
|
if (callee.type !== AST_NODE_TYPES.MemberExpression) return false;
|
|
233
49
|
if (!("name" in callee.object)) return false;
|
|
234
|
-
const isAt =
|
|
50
|
+
const isAt = isMatching({
|
|
235
51
|
type: AST_NODE_TYPES.MemberExpression,
|
|
236
52
|
property: {
|
|
237
53
|
type: AST_NODE_TYPES.Identifier,
|
|
@@ -288,14 +104,14 @@ var ensure_custom_hooks_using_other_hooks_default = createRule({
|
|
|
288
104
|
...listeners,
|
|
289
105
|
"Program:exit"(node) {
|
|
290
106
|
const allHooks = ctx.getAllHooks(node);
|
|
291
|
-
for (const { name: name2,
|
|
107
|
+
for (const { name: name2, node: node2, hookCalls } of allHooks.values()) {
|
|
292
108
|
if (hookCalls.length > 0) continue;
|
|
293
109
|
context.report({
|
|
110
|
+
messageId: "ensureCustomHooksUsingOtherHooks",
|
|
111
|
+
node: node2,
|
|
294
112
|
data: {
|
|
295
113
|
name: name2.value
|
|
296
|
-
}
|
|
297
|
-
messageId: "ensureCustomHooksUsingOtherHooks",
|
|
298
|
-
node: node2
|
|
114
|
+
}
|
|
299
115
|
});
|
|
300
116
|
}
|
|
301
117
|
}
|
|
@@ -337,14 +153,14 @@ var ensure_use_callback_has_non_empty_deps_default = createRule({
|
|
|
337
153
|
return;
|
|
338
154
|
}
|
|
339
155
|
const hasEmptyDeps = F.pipe(
|
|
340
|
-
|
|
156
|
+
match(deps).with({ type: AST_NODE_TYPES.ArrayExpression }, O.some).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
341
157
|
return F.pipe(
|
|
342
|
-
findVariable(
|
|
158
|
+
findVariable(n.name, initialScope),
|
|
343
159
|
O.flatMap(getVariableNode(0)),
|
|
344
160
|
O.filter(is(AST_NODE_TYPES.ArrayExpression))
|
|
345
161
|
);
|
|
346
162
|
}).otherwise(O.none),
|
|
347
|
-
O.exists((
|
|
163
|
+
O.exists((x) => x.elements.length === 0)
|
|
348
164
|
);
|
|
349
165
|
if (!hasEmptyDeps) return;
|
|
350
166
|
if (!cb) {
|
|
@@ -355,21 +171,21 @@ var ensure_use_callback_has_non_empty_deps_default = createRule({
|
|
|
355
171
|
return;
|
|
356
172
|
}
|
|
357
173
|
const isReferencedToComponentScope = F.pipe(
|
|
358
|
-
|
|
359
|
-
if (
|
|
360
|
-
return O.some(
|
|
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);
|
|
361
177
|
}
|
|
362
|
-
return O.some(
|
|
363
|
-
}).with({ type: AST_NODE_TYPES.FunctionExpression }, O.some).with({ type: AST_NODE_TYPES.Identifier }, (
|
|
178
|
+
return O.some(n);
|
|
179
|
+
}).with({ type: AST_NODE_TYPES.FunctionExpression }, O.some).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
364
180
|
return F.pipe(
|
|
365
|
-
findVariable(
|
|
181
|
+
findVariable(n.name, initialScope),
|
|
366
182
|
O.flatMap(getVariableNode(0)),
|
|
367
183
|
O.filter(isFunction)
|
|
368
184
|
);
|
|
369
185
|
}).otherwise(O.none),
|
|
370
|
-
O.map((
|
|
371
|
-
O.map((
|
|
372
|
-
O.exists((refs) => refs.some((
|
|
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))
|
|
373
189
|
);
|
|
374
190
|
if (isReferencedToComponentScope) return;
|
|
375
191
|
context.report({
|
|
@@ -415,14 +231,14 @@ var ensure_use_memo_has_non_empty_deps_default = createRule({
|
|
|
415
231
|
return;
|
|
416
232
|
}
|
|
417
233
|
const hasEmptyDeps = F.pipe(
|
|
418
|
-
|
|
234
|
+
match(deps).with({ type: AST_NODE_TYPES.ArrayExpression }, O.some).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
419
235
|
return F.pipe(
|
|
420
|
-
findVariable(
|
|
236
|
+
findVariable(n.name, initialScope),
|
|
421
237
|
O.flatMap(getVariableNode(0)),
|
|
422
238
|
O.filter(is(AST_NODE_TYPES.ArrayExpression))
|
|
423
239
|
);
|
|
424
240
|
}).otherwise(O.none),
|
|
425
|
-
O.exists((
|
|
241
|
+
O.exists((x) => x.elements.length === 0)
|
|
426
242
|
);
|
|
427
243
|
if (!hasEmptyDeps) return;
|
|
428
244
|
if (!cb) {
|
|
@@ -433,21 +249,21 @@ var ensure_use_memo_has_non_empty_deps_default = createRule({
|
|
|
433
249
|
return;
|
|
434
250
|
}
|
|
435
251
|
const isReferencedToComponentScope = F.pipe(
|
|
436
|
-
|
|
437
|
-
if (
|
|
438
|
-
return O.some(
|
|
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);
|
|
439
255
|
}
|
|
440
|
-
return O.some(
|
|
441
|
-
}).with({ type: AST_NODE_TYPES.FunctionExpression }, O.some).with({ type: AST_NODE_TYPES.Identifier }, (
|
|
256
|
+
return O.some(n);
|
|
257
|
+
}).with({ type: AST_NODE_TYPES.FunctionExpression }, O.some).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
442
258
|
return F.pipe(
|
|
443
|
-
findVariable(
|
|
259
|
+
findVariable(n.name, initialScope),
|
|
444
260
|
O.flatMap(getVariableNode(0)),
|
|
445
261
|
O.filter(isFunction)
|
|
446
262
|
);
|
|
447
263
|
}).otherwise(O.none),
|
|
448
|
-
O.map((
|
|
449
|
-
O.map((
|
|
450
|
-
O.exists((refs) => refs.some((
|
|
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))
|
|
451
267
|
);
|
|
452
268
|
if (isReferencedToComponentScope) return;
|
|
453
269
|
context.report({
|
|
@@ -499,10 +315,10 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
499
315
|
return node.parent?.type === AST_NODE_TYPES.CallExpression && node.parent.callee !== node && isUseEffectCall(node.parent);
|
|
500
316
|
}
|
|
501
317
|
function getCallKind(node) {
|
|
502
|
-
return
|
|
318
|
+
return match(node).when(isUseStateCall2, () => "useState").when(isUseEffectCall, () => "useEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
|
|
503
319
|
}
|
|
504
320
|
function getFunctionKind(node) {
|
|
505
|
-
return
|
|
321
|
+
return match(node).when(isEffectFunction, () => "effect").when(isFunctionOfImmediatelyInvoked, () => "immediate").otherwise(() => "other");
|
|
506
322
|
}
|
|
507
323
|
return {
|
|
508
324
|
":function"(node) {
|
|
@@ -511,7 +327,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
511
327
|
if (functionKind === "effect") onEffectFunctionEnter(node);
|
|
512
328
|
},
|
|
513
329
|
":function:exit"(node) {
|
|
514
|
-
const [
|
|
330
|
+
const [_, functionKind] = functionStack.at(-1) ?? [];
|
|
515
331
|
functionStack.pop();
|
|
516
332
|
if (functionKind === "effect") onEffectFunctionExit(node);
|
|
517
333
|
},
|
|
@@ -519,7 +335,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
519
335
|
const effectFn = MutRef.get(effectFunctionRef);
|
|
520
336
|
const [parentFn, parentFnKind] = functionStack.at(-1) ?? [];
|
|
521
337
|
if (parentFn?.async) return;
|
|
522
|
-
|
|
338
|
+
match(getCallKind(node)).with("setState", () => {
|
|
523
339
|
if (!parentFn) return;
|
|
524
340
|
if (parentFn !== effectFn && parentFnKind !== "immediate") {
|
|
525
341
|
const maybeVd = traverseUpGuard(node, isVariableDeclaratorFromHookCall);
|
|
@@ -593,12 +409,12 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
593
409
|
}
|
|
594
410
|
return [];
|
|
595
411
|
};
|
|
596
|
-
for (const [
|
|
412
|
+
for (const [_, calls] of indirectSetStateCallsAsEFs) {
|
|
597
413
|
for (const call of calls) {
|
|
598
414
|
context.report({
|
|
599
|
-
data: { name: call.name },
|
|
600
415
|
messageId: "noDirectSetStateInUseEffect",
|
|
601
|
-
node: call
|
|
416
|
+
node: call,
|
|
417
|
+
data: { name: call.name }
|
|
602
418
|
});
|
|
603
419
|
}
|
|
604
420
|
}
|
|
@@ -608,9 +424,9 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
608
424
|
const setStateCalls = getSetStateCalls(name2, context.sourceCode.getScope(callee));
|
|
609
425
|
for (const setStateCall of setStateCalls) {
|
|
610
426
|
context.report({
|
|
611
|
-
data: { name: name2 },
|
|
612
427
|
messageId: "noDirectSetStateInUseEffect",
|
|
613
|
-
node: setStateCall
|
|
428
|
+
node: setStateCall,
|
|
429
|
+
data: { name: name2 }
|
|
614
430
|
});
|
|
615
431
|
}
|
|
616
432
|
}
|
|
@@ -618,9 +434,9 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
618
434
|
const setStateCalls = getSetStateCalls(id.name, context.sourceCode.getScope(id));
|
|
619
435
|
for (const setStateCall of setStateCalls) {
|
|
620
436
|
context.report({
|
|
621
|
-
data: { name: id.name },
|
|
622
437
|
messageId: "noDirectSetStateInUseEffect",
|
|
623
|
-
node: setStateCall
|
|
438
|
+
node: setStateCall,
|
|
439
|
+
data: { name: id.name }
|
|
624
440
|
});
|
|
625
441
|
}
|
|
626
442
|
}
|
|
@@ -673,10 +489,10 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
673
489
|
return node.parent?.type === AST_NODE_TYPES.CallExpression && node.parent.callee !== node && isUseEffectCall(node.parent);
|
|
674
490
|
}
|
|
675
491
|
function getCallKind(node) {
|
|
676
|
-
return
|
|
492
|
+
return match(node).when(isUseStateCall2, () => "useState").when(isUseEffectCall, () => "useLayoutEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
|
|
677
493
|
}
|
|
678
494
|
function getFunctionKind(node) {
|
|
679
|
-
return
|
|
495
|
+
return match(node).when(isEffectFunction, () => "effect").when(isFunctionOfImmediatelyInvoked, () => "immediate").otherwise(() => "other");
|
|
680
496
|
}
|
|
681
497
|
return {
|
|
682
498
|
":function"(node) {
|
|
@@ -685,7 +501,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
685
501
|
if (functionKind === "effect") onEffectFunctionEnter(node);
|
|
686
502
|
},
|
|
687
503
|
":function:exit"(node) {
|
|
688
|
-
const [
|
|
504
|
+
const [_, functionKind] = functionStack.at(-1) ?? [];
|
|
689
505
|
functionStack.pop();
|
|
690
506
|
if (functionKind === "effect") onEffectFunctionExit(node);
|
|
691
507
|
},
|
|
@@ -693,7 +509,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
693
509
|
const effectFn = MutRef.get(effectFunctionRef);
|
|
694
510
|
const [parentFn, parentFnKind] = functionStack.at(-1) ?? [];
|
|
695
511
|
if (parentFn?.async) return;
|
|
696
|
-
|
|
512
|
+
match(getCallKind(node)).with("setState", () => {
|
|
697
513
|
if (!parentFn) return;
|
|
698
514
|
if (parentFn !== effectFn && parentFnKind !== "immediate") {
|
|
699
515
|
const maybeVd = traverseUpGuard(node, isVariableDeclaratorFromHookCall);
|
|
@@ -767,12 +583,12 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
767
583
|
}
|
|
768
584
|
return [];
|
|
769
585
|
};
|
|
770
|
-
for (const [
|
|
586
|
+
for (const [_, calls] of indirectSetStateCallsAsEFs) {
|
|
771
587
|
for (const call of calls) {
|
|
772
588
|
context.report({
|
|
773
|
-
data: { name: call.name },
|
|
774
589
|
messageId: "noDirectSetStateInUseLayoutEffect",
|
|
775
|
-
node: call
|
|
590
|
+
node: call,
|
|
591
|
+
data: { name: call.name }
|
|
776
592
|
});
|
|
777
593
|
}
|
|
778
594
|
}
|
|
@@ -782,9 +598,9 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
782
598
|
const setStateCalls = getSetStateCalls(name2, context.sourceCode.getScope(callee));
|
|
783
599
|
for (const setStateCall of setStateCalls) {
|
|
784
600
|
context.report({
|
|
785
|
-
data: { name: name2 },
|
|
786
601
|
messageId: "noDirectSetStateInUseLayoutEffect",
|
|
787
|
-
node: setStateCall
|
|
602
|
+
node: setStateCall,
|
|
603
|
+
data: { name: name2 }
|
|
788
604
|
});
|
|
789
605
|
}
|
|
790
606
|
}
|
|
@@ -792,9 +608,9 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
792
608
|
const setStateCalls = getSetStateCalls(id.name, context.sourceCode.getScope(id));
|
|
793
609
|
for (const setStateCall of setStateCalls) {
|
|
794
610
|
context.report({
|
|
795
|
-
data: { name: id.name },
|
|
796
611
|
messageId: "noDirectSetStateInUseLayoutEffect",
|
|
797
|
-
node: setStateCall
|
|
612
|
+
node: setStateCall,
|
|
613
|
+
data: { name: id.name }
|
|
798
614
|
});
|
|
799
615
|
}
|
|
800
616
|
}
|
|
@@ -826,8 +642,8 @@ var prefer_use_state_lazy_initialization_default = createRule({
|
|
|
826
642
|
const [useStateInput] = node.arguments;
|
|
827
643
|
if (!useStateInput) return;
|
|
828
644
|
const nestedCallExpressions = getNestedCallExpressions(useStateInput);
|
|
829
|
-
const hasFunctionCall = nestedCallExpressions.some((
|
|
830
|
-
return "name" in
|
|
645
|
+
const hasFunctionCall = nestedCallExpressions.some((n) => {
|
|
646
|
+
return "name" in n.callee && !ALLOW_LIST.includes(n.callee.name);
|
|
831
647
|
});
|
|
832
648
|
if (!hasFunctionCall) return;
|
|
833
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.2-next.
|
|
3
|
+
"version": "1.9.2-next.5",
|
|
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
|
-
"
|
|
49
|
-
"@eslint-react/core": "1.9.2-next.
|
|
50
|
-
"@eslint-react/
|
|
51
|
-
"@eslint-react/
|
|
52
|
-
"@eslint-react/
|
|
53
|
-
"@eslint-react/
|
|
54
|
-
"@eslint-react/types": "1.9.2-next.
|
|
48
|
+
"ts-pattern": "^5.2.0",
|
|
49
|
+
"@eslint-react/core": "1.9.2-next.5",
|
|
50
|
+
"@eslint-react/ast": "1.9.2-next.5",
|
|
51
|
+
"@eslint-react/jsx": "1.9.2-next.5",
|
|
52
|
+
"@eslint-react/shared": "1.9.2-next.5",
|
|
53
|
+
"@eslint-react/tools": "1.9.2-next.5",
|
|
54
|
+
"@eslint-react/types": "1.9.2-next.5",
|
|
55
|
+
"@eslint-react/var": "1.9.2-next.5"
|
|
55
56
|
},
|
|
56
57
|
"devDependencies": {
|
|
57
58
|
"@types/react": "^18.3.3",
|