@eslint-react/core 1.28.0-beta.1 → 1.28.0-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +64 -67
- package/dist/index.d.ts +64 -67
- package/dist/index.js +664 -164
- package/dist/index.mjs +660 -165
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var AST8 = require('@eslint-react/ast');
|
|
4
4
|
var eff = require('@eslint-react/eff');
|
|
5
5
|
var JSX3 = require('@eslint-react/jsx');
|
|
6
6
|
var shared = require('@eslint-react/shared');
|
|
@@ -29,27 +29,489 @@ function _interopNamespace(e) {
|
|
|
29
29
|
return Object.freeze(n);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
var
|
|
32
|
+
var AST8__namespace = /*#__PURE__*/_interopNamespace(AST8);
|
|
33
33
|
var JSX3__namespace = /*#__PURE__*/_interopNamespace(JSX3);
|
|
34
34
|
var VAR__namespace = /*#__PURE__*/_interopNamespace(VAR);
|
|
35
35
|
var birecord__default = /*#__PURE__*/_interopDefault(birecord);
|
|
36
36
|
|
|
37
37
|
// src/component/component-collector.ts
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
38
|
+
|
|
39
|
+
// ../../node_modules/.pnpm/valibot@1.0.0-rc.2_typescript@5.8.1-rc/node_modules/valibot/dist/index.js
|
|
40
|
+
var store;
|
|
41
|
+
// @__NO_SIDE_EFFECTS__
|
|
42
|
+
function getGlobalConfig(config2) {
|
|
43
|
+
return {
|
|
44
|
+
lang: config2?.lang ?? store?.lang,
|
|
45
|
+
message: config2?.message,
|
|
46
|
+
abortEarly: config2?.abortEarly ?? store?.abortEarly,
|
|
47
|
+
abortPipeEarly: config2?.abortPipeEarly ?? store?.abortPipeEarly
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
var store2;
|
|
51
|
+
// @__NO_SIDE_EFFECTS__
|
|
52
|
+
function getGlobalMessage(lang) {
|
|
53
|
+
return store2?.get(lang);
|
|
54
|
+
}
|
|
55
|
+
var store3;
|
|
56
|
+
// @__NO_SIDE_EFFECTS__
|
|
57
|
+
function getSchemaMessage(lang) {
|
|
58
|
+
return store3?.get(lang);
|
|
59
|
+
}
|
|
60
|
+
var store4;
|
|
61
|
+
// @__NO_SIDE_EFFECTS__
|
|
62
|
+
function getSpecificMessage(reference, lang) {
|
|
63
|
+
return store4?.get(reference)?.get(lang);
|
|
64
|
+
}
|
|
65
|
+
// @__NO_SIDE_EFFECTS__
|
|
66
|
+
function _stringify(input) {
|
|
67
|
+
const type = typeof input;
|
|
68
|
+
if (type === "string") {
|
|
69
|
+
return `"${input}"`;
|
|
70
|
+
}
|
|
71
|
+
if (type === "number" || type === "bigint" || type === "boolean") {
|
|
72
|
+
return `${input}`;
|
|
73
|
+
}
|
|
74
|
+
if (type === "object" || type === "function") {
|
|
75
|
+
return (input && Object.getPrototypeOf(input)?.constructor?.name) ?? "null";
|
|
76
|
+
}
|
|
77
|
+
return type;
|
|
78
|
+
}
|
|
79
|
+
function _addIssue(context, label, dataset, config2, other) {
|
|
80
|
+
const input = other && "input" in other ? other.input : dataset.value;
|
|
81
|
+
const expected = other?.expected ?? context.expects ?? null;
|
|
82
|
+
const received = other?.received ?? /* @__PURE__ */ _stringify(input);
|
|
83
|
+
const issue = {
|
|
84
|
+
kind: context.kind,
|
|
85
|
+
type: context.type,
|
|
86
|
+
input,
|
|
87
|
+
expected,
|
|
88
|
+
received,
|
|
89
|
+
message: `Invalid ${label}: ${expected ? `Expected ${expected} but r` : "R"}eceived ${received}`,
|
|
90
|
+
requirement: context.requirement,
|
|
91
|
+
path: other?.path,
|
|
92
|
+
issues: other?.issues,
|
|
93
|
+
lang: config2.lang,
|
|
94
|
+
abortEarly: config2.abortEarly,
|
|
95
|
+
abortPipeEarly: config2.abortPipeEarly
|
|
96
|
+
};
|
|
97
|
+
const isSchema = context.kind === "schema";
|
|
98
|
+
const message = other?.message ?? context.message ?? /* @__PURE__ */ getSpecificMessage(context.reference, issue.lang) ?? (isSchema ? /* @__PURE__ */ getSchemaMessage(issue.lang) : null) ?? config2.message ?? /* @__PURE__ */ getGlobalMessage(issue.lang);
|
|
99
|
+
if (message) {
|
|
100
|
+
issue.message = typeof message === "function" ? (
|
|
101
|
+
// @ts-expect-error
|
|
102
|
+
message(issue)
|
|
103
|
+
) : message;
|
|
104
|
+
}
|
|
105
|
+
if (isSchema) {
|
|
106
|
+
dataset.typed = false;
|
|
107
|
+
}
|
|
108
|
+
if (dataset.issues) {
|
|
109
|
+
dataset.issues.push(issue);
|
|
110
|
+
} else {
|
|
111
|
+
dataset.issues = [issue];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// @__NO_SIDE_EFFECTS__
|
|
115
|
+
function _getStandardProps(context) {
|
|
116
|
+
return {
|
|
117
|
+
version: 1,
|
|
118
|
+
vendor: "valibot",
|
|
119
|
+
validate(value2) {
|
|
120
|
+
return context["~run"]({ value: value2 }, /* @__PURE__ */ getGlobalConfig());
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
var ValiError = class extends Error {
|
|
125
|
+
/**
|
|
126
|
+
* Creates a Valibot error with useful information.
|
|
127
|
+
*
|
|
128
|
+
* @param issues The error issues.
|
|
129
|
+
*/
|
|
130
|
+
constructor(issues) {
|
|
131
|
+
super(issues[0].message);
|
|
132
|
+
this.name = "ValiError";
|
|
133
|
+
this.issues = issues;
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
// @__NO_SIDE_EFFECTS__
|
|
137
|
+
function getFallback(schema, dataset, config2) {
|
|
138
|
+
return typeof schema.fallback === "function" ? (
|
|
139
|
+
// @ts-expect-error
|
|
140
|
+
schema.fallback(dataset, config2)
|
|
141
|
+
) : (
|
|
142
|
+
// @ts-expect-error
|
|
143
|
+
schema.fallback
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
// @__NO_SIDE_EFFECTS__
|
|
147
|
+
function getDefault(schema, dataset, config2) {
|
|
148
|
+
return typeof schema.default === "function" ? (
|
|
149
|
+
// @ts-expect-error
|
|
150
|
+
schema.default(dataset, config2)
|
|
151
|
+
) : (
|
|
152
|
+
// @ts-expect-error
|
|
153
|
+
schema.default
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
// @__NO_SIDE_EFFECTS__
|
|
157
|
+
function array(item, message) {
|
|
158
|
+
return {
|
|
159
|
+
kind: "schema",
|
|
160
|
+
type: "array",
|
|
161
|
+
reference: array,
|
|
162
|
+
expects: "Array",
|
|
163
|
+
async: false,
|
|
164
|
+
item,
|
|
165
|
+
message,
|
|
166
|
+
get "~standard"() {
|
|
167
|
+
return /* @__PURE__ */ _getStandardProps(this);
|
|
168
|
+
},
|
|
169
|
+
"~run"(dataset, config2) {
|
|
170
|
+
const input = dataset.value;
|
|
171
|
+
if (Array.isArray(input)) {
|
|
172
|
+
dataset.typed = true;
|
|
173
|
+
dataset.value = [];
|
|
174
|
+
for (let key = 0; key < input.length; key++) {
|
|
175
|
+
const value2 = input[key];
|
|
176
|
+
const itemDataset = this.item["~run"]({ value: value2 }, config2);
|
|
177
|
+
if (itemDataset.issues) {
|
|
178
|
+
const pathItem = {
|
|
179
|
+
type: "array",
|
|
180
|
+
origin: "value",
|
|
181
|
+
input,
|
|
182
|
+
key,
|
|
183
|
+
value: value2
|
|
184
|
+
};
|
|
185
|
+
for (const issue of itemDataset.issues) {
|
|
186
|
+
if (issue.path) {
|
|
187
|
+
issue.path.unshift(pathItem);
|
|
188
|
+
} else {
|
|
189
|
+
issue.path = [pathItem];
|
|
190
|
+
}
|
|
191
|
+
dataset.issues?.push(issue);
|
|
192
|
+
}
|
|
193
|
+
if (!dataset.issues) {
|
|
194
|
+
dataset.issues = itemDataset.issues;
|
|
195
|
+
}
|
|
196
|
+
if (config2.abortEarly) {
|
|
197
|
+
dataset.typed = false;
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (!itemDataset.typed) {
|
|
202
|
+
dataset.typed = false;
|
|
203
|
+
}
|
|
204
|
+
dataset.value.push(itemDataset.value);
|
|
205
|
+
}
|
|
206
|
+
} else {
|
|
207
|
+
_addIssue(this, "type", dataset, config2);
|
|
208
|
+
}
|
|
209
|
+
return dataset;
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
// @__NO_SIDE_EFFECTS__
|
|
214
|
+
function boolean(message) {
|
|
215
|
+
return {
|
|
216
|
+
kind: "schema",
|
|
217
|
+
type: "boolean",
|
|
218
|
+
reference: boolean,
|
|
219
|
+
expects: "boolean",
|
|
220
|
+
async: false,
|
|
221
|
+
message,
|
|
222
|
+
get "~standard"() {
|
|
223
|
+
return /* @__PURE__ */ _getStandardProps(this);
|
|
224
|
+
},
|
|
225
|
+
"~run"(dataset, config2) {
|
|
226
|
+
if (typeof dataset.value === "boolean") {
|
|
227
|
+
dataset.typed = true;
|
|
228
|
+
} else {
|
|
229
|
+
_addIssue(this, "type", dataset, config2);
|
|
230
|
+
}
|
|
231
|
+
return dataset;
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
// @__NO_SIDE_EFFECTS__
|
|
236
|
+
function object(entries, message) {
|
|
237
|
+
return {
|
|
238
|
+
kind: "schema",
|
|
239
|
+
type: "object",
|
|
240
|
+
reference: object,
|
|
241
|
+
expects: "Object",
|
|
242
|
+
async: false,
|
|
243
|
+
entries,
|
|
244
|
+
message,
|
|
245
|
+
get "~standard"() {
|
|
246
|
+
return /* @__PURE__ */ _getStandardProps(this);
|
|
247
|
+
},
|
|
248
|
+
"~run"(dataset, config2) {
|
|
249
|
+
const input = dataset.value;
|
|
250
|
+
if (input && typeof input === "object") {
|
|
251
|
+
dataset.typed = true;
|
|
252
|
+
dataset.value = {};
|
|
253
|
+
for (const key in this.entries) {
|
|
254
|
+
const valueSchema = this.entries[key];
|
|
255
|
+
if (key in input || (valueSchema.type === "exact_optional" || valueSchema.type === "optional" || valueSchema.type === "nullish") && // @ts-expect-error
|
|
256
|
+
valueSchema.default !== void 0) {
|
|
257
|
+
const value2 = key in input ? (
|
|
258
|
+
// @ts-expect-error
|
|
259
|
+
input[key]
|
|
260
|
+
) : /* @__PURE__ */ getDefault(valueSchema);
|
|
261
|
+
const valueDataset = valueSchema["~run"]({ value: value2 }, config2);
|
|
262
|
+
if (valueDataset.issues) {
|
|
263
|
+
const pathItem = {
|
|
264
|
+
type: "object",
|
|
265
|
+
origin: "value",
|
|
266
|
+
input,
|
|
267
|
+
key,
|
|
268
|
+
value: value2
|
|
269
|
+
};
|
|
270
|
+
for (const issue of valueDataset.issues) {
|
|
271
|
+
if (issue.path) {
|
|
272
|
+
issue.path.unshift(pathItem);
|
|
273
|
+
} else {
|
|
274
|
+
issue.path = [pathItem];
|
|
275
|
+
}
|
|
276
|
+
dataset.issues?.push(issue);
|
|
277
|
+
}
|
|
278
|
+
if (!dataset.issues) {
|
|
279
|
+
dataset.issues = valueDataset.issues;
|
|
280
|
+
}
|
|
281
|
+
if (config2.abortEarly) {
|
|
282
|
+
dataset.typed = false;
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (!valueDataset.typed) {
|
|
287
|
+
dataset.typed = false;
|
|
288
|
+
}
|
|
289
|
+
dataset.value[key] = valueDataset.value;
|
|
290
|
+
} else if (valueSchema.fallback !== void 0) {
|
|
291
|
+
dataset.value[key] = /* @__PURE__ */ getFallback(valueSchema);
|
|
292
|
+
} else if (valueSchema.type !== "exact_optional" && valueSchema.type !== "optional" && valueSchema.type !== "nullish") {
|
|
293
|
+
_addIssue(this, "key", dataset, config2, {
|
|
294
|
+
input: void 0,
|
|
295
|
+
expected: `"${key}"`,
|
|
296
|
+
path: [
|
|
297
|
+
{
|
|
298
|
+
type: "object",
|
|
299
|
+
origin: "key",
|
|
300
|
+
input,
|
|
301
|
+
key,
|
|
302
|
+
// @ts-expect-error
|
|
303
|
+
value: input[key]
|
|
304
|
+
}
|
|
305
|
+
]
|
|
306
|
+
});
|
|
307
|
+
if (config2.abortEarly) {
|
|
308
|
+
break;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
} else {
|
|
313
|
+
_addIssue(this, "type", dataset, config2);
|
|
314
|
+
}
|
|
315
|
+
return dataset;
|
|
316
|
+
}
|
|
317
|
+
};
|
|
48
318
|
}
|
|
319
|
+
// @__NO_SIDE_EFFECTS__
|
|
320
|
+
function optional(wrapped, default_) {
|
|
321
|
+
return {
|
|
322
|
+
kind: "schema",
|
|
323
|
+
type: "optional",
|
|
324
|
+
reference: optional,
|
|
325
|
+
expects: `(${wrapped.expects} | undefined)`,
|
|
326
|
+
async: false,
|
|
327
|
+
wrapped,
|
|
328
|
+
default: default_,
|
|
329
|
+
get "~standard"() {
|
|
330
|
+
return /* @__PURE__ */ _getStandardProps(this);
|
|
331
|
+
},
|
|
332
|
+
"~run"(dataset, config2) {
|
|
333
|
+
if (dataset.value === void 0) {
|
|
334
|
+
if (this.default !== void 0) {
|
|
335
|
+
dataset.value = /* @__PURE__ */ getDefault(this, dataset, config2);
|
|
336
|
+
}
|
|
337
|
+
if (dataset.value === void 0) {
|
|
338
|
+
dataset.typed = true;
|
|
339
|
+
return dataset;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return this.wrapped["~run"](dataset, config2);
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
// @__NO_SIDE_EFFECTS__
|
|
347
|
+
function string(message) {
|
|
348
|
+
return {
|
|
349
|
+
kind: "schema",
|
|
350
|
+
type: "string",
|
|
351
|
+
reference: string,
|
|
352
|
+
expects: "string",
|
|
353
|
+
async: false,
|
|
354
|
+
message,
|
|
355
|
+
get "~standard"() {
|
|
356
|
+
return /* @__PURE__ */ _getStandardProps(this);
|
|
357
|
+
},
|
|
358
|
+
"~run"(dataset, config2) {
|
|
359
|
+
if (typeof dataset.value === "string") {
|
|
360
|
+
dataset.typed = true;
|
|
361
|
+
} else {
|
|
362
|
+
_addIssue(this, "type", dataset, config2);
|
|
363
|
+
}
|
|
364
|
+
return dataset;
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
function parse(schema, input, config2) {
|
|
369
|
+
const dataset = schema["~run"]({ value: input }, /* @__PURE__ */ getGlobalConfig(config2));
|
|
370
|
+
if (dataset.issues) {
|
|
371
|
+
throw new ValiError(dataset.issues);
|
|
372
|
+
}
|
|
373
|
+
return dataset.value;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// ../shared/src/schemas.ts
|
|
377
|
+
var CustomComponentPropSchema = object({
|
|
378
|
+
/**
|
|
379
|
+
* The name of the prop in the user-defined component.
|
|
380
|
+
* @example
|
|
381
|
+
* "to"
|
|
382
|
+
*/
|
|
383
|
+
name: string(),
|
|
384
|
+
/**
|
|
385
|
+
* The name of the prop in the built-in component.
|
|
386
|
+
* @example
|
|
387
|
+
* "href"
|
|
388
|
+
*/
|
|
389
|
+
as: optional(string()),
|
|
390
|
+
/**
|
|
391
|
+
* Whether the prop is controlled or not in the user-defined component.
|
|
392
|
+
* @example
|
|
393
|
+
* `true`
|
|
394
|
+
*/
|
|
395
|
+
controlled: optional(boolean()),
|
|
396
|
+
/**
|
|
397
|
+
* The default value of the prop in the user-defined component.
|
|
398
|
+
* @example
|
|
399
|
+
* `"/"`
|
|
400
|
+
*/
|
|
401
|
+
defaultValue: optional(string())
|
|
402
|
+
});
|
|
403
|
+
var CustomComponentSchema = object({
|
|
404
|
+
/**
|
|
405
|
+
* The name of the user-defined component.
|
|
406
|
+
* @example
|
|
407
|
+
* "Link"
|
|
408
|
+
*/
|
|
409
|
+
name: string(),
|
|
410
|
+
/**
|
|
411
|
+
* The name of the built-in component that the user-defined component represents.
|
|
412
|
+
* @example
|
|
413
|
+
* "a"
|
|
414
|
+
*/
|
|
415
|
+
as: optional(string()),
|
|
416
|
+
/**
|
|
417
|
+
* Attributes mapping between the user-defined component and the built-in component.
|
|
418
|
+
* @example
|
|
419
|
+
* `Link` component has a `to` attribute that represents the `href` attribute in the built-in `a` element with a default value of `"/"`.
|
|
420
|
+
*/
|
|
421
|
+
attributes: optional(array(CustomComponentPropSchema)),
|
|
422
|
+
/**
|
|
423
|
+
* The ESQuery selector to select the component precisely.
|
|
424
|
+
* @internal
|
|
425
|
+
* @example
|
|
426
|
+
* `JSXElement:has(JSXAttribute[name.name='component'][value.value='a'])`
|
|
427
|
+
*/
|
|
428
|
+
selector: optional(string())
|
|
429
|
+
});
|
|
430
|
+
var CustomHooksSchema = object({
|
|
431
|
+
use: optional(array(string())),
|
|
432
|
+
useActionState: optional(array(string())),
|
|
433
|
+
useCallback: optional(array(string())),
|
|
434
|
+
useContext: optional(array(string())),
|
|
435
|
+
useDebugValue: optional(array(string())),
|
|
436
|
+
useDeferredValue: optional(array(string())),
|
|
437
|
+
useEffect: optional(array(string())),
|
|
438
|
+
useFormStatus: optional(array(string())),
|
|
439
|
+
useId: optional(array(string())),
|
|
440
|
+
useImperativeHandle: optional(array(string())),
|
|
441
|
+
useInsertionEffect: optional(array(string())),
|
|
442
|
+
useLayoutEffect: optional(array(string())),
|
|
443
|
+
useMemo: optional(array(string())),
|
|
444
|
+
useOptimistic: optional(array(string())),
|
|
445
|
+
useReducer: optional(array(string())),
|
|
446
|
+
useRef: optional(array(string())),
|
|
447
|
+
useState: optional(array(string())),
|
|
448
|
+
useSyncExternalStore: optional(array(string())),
|
|
449
|
+
useTransition: optional(array(string()))
|
|
450
|
+
});
|
|
451
|
+
var ESLintReactSettingsSchema = object({
|
|
452
|
+
/**
|
|
453
|
+
* The source where React is imported from.
|
|
454
|
+
* @description This allows to specify a custom import location for React when not using the official distribution.
|
|
455
|
+
* @default `"react"`
|
|
456
|
+
* @example `"@pika/react"`
|
|
457
|
+
*/
|
|
458
|
+
importSource: optional(string()),
|
|
459
|
+
/**
|
|
460
|
+
* The identifier that’s used for JSX Element creation.
|
|
461
|
+
* @default `"createElement"`
|
|
462
|
+
* @deprecated
|
|
463
|
+
*/
|
|
464
|
+
jsxPragma: optional(string()),
|
|
465
|
+
/**
|
|
466
|
+
* The identifier that’s used for JSX fragment elements.
|
|
467
|
+
* @description This should not be a member expression (i.e. use "Fragment" instead of "React.Fragment").
|
|
468
|
+
* @default `"Fragment"`
|
|
469
|
+
* @deprecated
|
|
470
|
+
*/
|
|
471
|
+
jsxPragmaFrag: optional(string()),
|
|
472
|
+
/**
|
|
473
|
+
* The name of the prop that is used for polymorphic components.
|
|
474
|
+
* @description This is used to determine the type of the component.
|
|
475
|
+
* @example `"as"`
|
|
476
|
+
*/
|
|
477
|
+
polymorphicPropName: optional(string()),
|
|
478
|
+
/**
|
|
479
|
+
* @internal
|
|
480
|
+
*/
|
|
481
|
+
strict: optional(boolean(), false),
|
|
482
|
+
/**
|
|
483
|
+
* Check both the shape and the import to determine if an API is from React.
|
|
484
|
+
* @description This can prevent false positives when using a irrelevant third-party library that has similar APIs to React.
|
|
485
|
+
* @default `true`
|
|
486
|
+
*/
|
|
487
|
+
skipImportCheck: optional(boolean(), true),
|
|
488
|
+
/**
|
|
489
|
+
* React version to use, "detect" means auto detect React version from the project’s dependencies.
|
|
490
|
+
* If `importSource` is specified, an equivalent version of React should be provided here.
|
|
491
|
+
* @example `"18.3.1"`
|
|
492
|
+
* @default `"detect"`
|
|
493
|
+
*/
|
|
494
|
+
version: optional(string()),
|
|
495
|
+
/**
|
|
496
|
+
* A object to define additional hooks that are equivalent to the built-in React Hooks.
|
|
497
|
+
* @description ESLint React will recognize these aliases as equivalent to the built-in hooks in all its rules.
|
|
498
|
+
* @example `{ useEffect: ["useIsomorphicLayoutEffect"] }`
|
|
499
|
+
*/
|
|
500
|
+
additionalHooks: optional(CustomHooksSchema),
|
|
501
|
+
/**
|
|
502
|
+
* An array of user-defined components
|
|
503
|
+
* @description This is used to inform the ESLint React plugins how to treat these components during checks.
|
|
504
|
+
* @example `[{ name: "Link", as: "a", attributes: [{ name: "to", as: "href" }, { name: "rel", defaultValue: "noopener noreferrer" }] }]`
|
|
505
|
+
*/
|
|
506
|
+
additionalComponents: optional(array(CustomComponentSchema))
|
|
507
|
+
});
|
|
508
|
+
var DEFAULT_ESLINT_REACT_SETTINGS = {
|
|
509
|
+
...parse(ESLintReactSettingsSchema, {}),
|
|
510
|
+
importSource: "react"};
|
|
49
511
|
function getRequireExpressionArguments(node) {
|
|
50
512
|
return tsPattern.match(node).with({ type: types.AST_NODE_TYPES.CallExpression, arguments: tsPattern.P.select(), callee: { type: types.AST_NODE_TYPES.Identifier, name: "require" } }, eff.identity).with({ type: types.AST_NODE_TYPES.MemberExpression, object: tsPattern.P.select() }, getRequireExpressionArguments).otherwise(() => eff._);
|
|
51
513
|
}
|
|
52
|
-
function isInitializedFromReact(name,
|
|
514
|
+
function isInitializedFromReact(name, importSource, initialScope) {
|
|
53
515
|
if (name.toLowerCase() === "react") return true;
|
|
54
516
|
const latestDef = VAR__namespace.findVariable(name, initialScope)?.defs.at(-1);
|
|
55
517
|
if (latestDef == null) return false;
|
|
@@ -57,81 +519,101 @@ function isInitializedFromReact(name, source, initialScope) {
|
|
|
57
519
|
if (node.type === types.AST_NODE_TYPES.VariableDeclarator && node.init != null) {
|
|
58
520
|
const { init } = node;
|
|
59
521
|
if (init.type === types.AST_NODE_TYPES.MemberExpression && init.object.type === types.AST_NODE_TYPES.Identifier) {
|
|
60
|
-
return isInitializedFromReact(init.object.name,
|
|
522
|
+
return isInitializedFromReact(init.object.name, importSource, initialScope);
|
|
61
523
|
}
|
|
62
524
|
if (init.type === types.AST_NODE_TYPES.Identifier) {
|
|
63
|
-
return isInitializedFromReact(init.name,
|
|
525
|
+
return isInitializedFromReact(init.name, importSource, initialScope);
|
|
64
526
|
}
|
|
65
527
|
const args = getRequireExpressionArguments(init);
|
|
66
528
|
const arg0 = args?.[0];
|
|
67
|
-
if (arg0 == null || !
|
|
529
|
+
if (arg0 == null || !AST8__namespace.isKindOfLiteral(arg0, "string")) {
|
|
68
530
|
return false;
|
|
69
531
|
}
|
|
70
|
-
return arg0.value ===
|
|
532
|
+
return arg0.value === importSource || arg0.value.startsWith(`${importSource}/`);
|
|
71
533
|
}
|
|
72
|
-
return parent?.type === types.AST_NODE_TYPES.ImportDeclaration && parent.source.value ===
|
|
534
|
+
return parent?.type === types.AST_NODE_TYPES.ImportDeclaration && parent.source.value === importSource;
|
|
73
535
|
}
|
|
74
536
|
|
|
75
537
|
// src/utils/is-from-react.ts
|
|
538
|
+
var defaultImportSource = shared.DEFAULT_ESLINT_REACT_SETTINGS.importSource;
|
|
539
|
+
function isFromReactLoose(node, name) {
|
|
540
|
+
if (node.type === types.AST_NODE_TYPES.MemberExpression) {
|
|
541
|
+
return node.object.type === types.AST_NODE_TYPES.Identifier && node.property.type === types.AST_NODE_TYPES.Identifier && node.property.name === name;
|
|
542
|
+
}
|
|
543
|
+
return node.name === name;
|
|
544
|
+
}
|
|
545
|
+
function isFromReactStrict(node, name, importSource, initialScope) {
|
|
546
|
+
if (node.type === types.AST_NODE_TYPES.MemberExpression) {
|
|
547
|
+
return node.object.type === types.AST_NODE_TYPES.Identifier && node.property.type === types.AST_NODE_TYPES.Identifier && node.property.name === name && isInitializedFromReact(node.object.name, importSource, initialScope);
|
|
548
|
+
}
|
|
549
|
+
if (node.name === name) {
|
|
550
|
+
return isInitializedFromReact(name, importSource, initialScope);
|
|
551
|
+
}
|
|
552
|
+
return false;
|
|
553
|
+
}
|
|
76
554
|
function isFromReact(name) {
|
|
77
|
-
return (
|
|
78
|
-
const
|
|
79
|
-
if (
|
|
80
|
-
|
|
81
|
-
return node.object.type === types.AST_NODE_TYPES.Identifier && node.property.type === types.AST_NODE_TYPES.Identifier && node.property.name === name;
|
|
82
|
-
}
|
|
83
|
-
return node.name === name;
|
|
84
|
-
}
|
|
85
|
-
const importSource = settings.importSource ?? shared.DEFAULT_ESLINT_REACT_SETTINGS.importSource;
|
|
86
|
-
const initialScope = context.sourceCode.getScope(node);
|
|
87
|
-
if (node.type === types.AST_NODE_TYPES.MemberExpression) {
|
|
88
|
-
return node.object.type === types.AST_NODE_TYPES.Identifier && node.property.type === types.AST_NODE_TYPES.Identifier && node.property.name === name && isInitializedFromReact(node.object.name, importSource, initialScope);
|
|
89
|
-
}
|
|
90
|
-
if (node.name === name) {
|
|
91
|
-
return isInitializedFromReact(name, importSource, initialScope);
|
|
92
|
-
}
|
|
93
|
-
return false;
|
|
555
|
+
return (context, node) => {
|
|
556
|
+
const { importSource = defaultImportSource, skipImportCheck = true } = shared.unsafeDecodeSettings(context.settings);
|
|
557
|
+
if (skipImportCheck) return isFromReactLoose(node, name);
|
|
558
|
+
return isFromReactStrict(node, name, importSource, context.sourceCode.getScope(node));
|
|
94
559
|
};
|
|
95
560
|
}
|
|
96
|
-
function
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const initialScope = context.sourceCode.getScope(node);
|
|
109
|
-
if (node.property.type !== types.AST_NODE_TYPES.Identifier || node.property.name !== name) {
|
|
110
|
-
return false;
|
|
111
|
-
}
|
|
112
|
-
if (node.object.type === types.AST_NODE_TYPES.Identifier && node.object.name === memberName) {
|
|
113
|
-
return isInitializedFromReact(node.object.name, importSource, initialScope);
|
|
114
|
-
}
|
|
115
|
-
if (node.object.type === types.AST_NODE_TYPES.MemberExpression && node.object.object.type === types.AST_NODE_TYPES.Identifier && isInitializedFromReact(node.object.object.name, importSource, initialScope) && node.object.property.type === types.AST_NODE_TYPES.Identifier) {
|
|
116
|
-
return node.object.property.name === memberName;
|
|
117
|
-
}
|
|
561
|
+
function isFromReactMemberLoose(node, memberName, name) {
|
|
562
|
+
const { object: object2, property } = node;
|
|
563
|
+
if (property.type !== types.AST_NODE_TYPES.Identifier || property.name !== name) return false;
|
|
564
|
+
if (object2.type === types.AST_NODE_TYPES.Identifier && object2.name === memberName) return true;
|
|
565
|
+
if (object2.type === types.AST_NODE_TYPES.MemberExpression && object2.object.type === types.AST_NODE_TYPES.Identifier && object2.property.type === types.AST_NODE_TYPES.Identifier) {
|
|
566
|
+
return object2.property.name === memberName;
|
|
567
|
+
}
|
|
568
|
+
return false;
|
|
569
|
+
}
|
|
570
|
+
function isFromReactMemberStrict(node, memberName, name, importSource, initialScope) {
|
|
571
|
+
const { object: object2, property } = node;
|
|
572
|
+
if (property.type !== types.AST_NODE_TYPES.Identifier || property.name !== name) {
|
|
118
573
|
return false;
|
|
574
|
+
}
|
|
575
|
+
if (object2.type === types.AST_NODE_TYPES.Identifier && object2.name === memberName) {
|
|
576
|
+
return isInitializedFromReact(object2.name, importSource, initialScope);
|
|
577
|
+
}
|
|
578
|
+
if (object2.type === types.AST_NODE_TYPES.MemberExpression && object2.object.type === types.AST_NODE_TYPES.Identifier && isInitializedFromReact(object2.object.name, importSource, initialScope) && object2.property.type === types.AST_NODE_TYPES.Identifier) {
|
|
579
|
+
return object2.property.name === memberName;
|
|
580
|
+
}
|
|
581
|
+
return false;
|
|
582
|
+
}
|
|
583
|
+
function isFromReactMember(memberName, name) {
|
|
584
|
+
return (context, node) => {
|
|
585
|
+
const { importSource = defaultImportSource, skipImportCheck = true } = shared.unsafeDecodeSettings(context.settings);
|
|
586
|
+
if (skipImportCheck) return isFromReactMemberLoose(node, memberName, name);
|
|
587
|
+
return isFromReactMemberStrict(node, memberName, name, importSource, context.sourceCode.getScope(node));
|
|
119
588
|
};
|
|
120
589
|
}
|
|
590
|
+
|
|
591
|
+
// src/utils/is-call-from-react.ts
|
|
121
592
|
function isCallFromReact(name) {
|
|
122
|
-
return eff.dual(2, (
|
|
593
|
+
return eff.dual(2, (context, node) => {
|
|
123
594
|
if (node.type !== types.AST_NODE_TYPES.CallExpression) return false;
|
|
124
|
-
if (!
|
|
125
|
-
return isFromReact(name)(node.callee
|
|
595
|
+
if (!AST8__namespace.isOneOf([types.AST_NODE_TYPES.Identifier, types.AST_NODE_TYPES.MemberExpression])(node.callee)) return false;
|
|
596
|
+
return isFromReact(name)(context, node.callee);
|
|
126
597
|
});
|
|
127
598
|
}
|
|
128
599
|
function isCallFromReactMember(pragmaMemberName, name) {
|
|
129
|
-
return eff.dual(2, (
|
|
600
|
+
return eff.dual(2, (context, node) => {
|
|
130
601
|
if (node.type !== types.AST_NODE_TYPES.CallExpression) return false;
|
|
131
|
-
if (!
|
|
132
|
-
return isFromReactMember(pragmaMemberName, name)(node.callee
|
|
602
|
+
if (!AST8__namespace.is(types.AST_NODE_TYPES.MemberExpression)(node.callee)) return false;
|
|
603
|
+
return isFromReactMember(pragmaMemberName, name)(context, node.callee);
|
|
133
604
|
});
|
|
134
605
|
}
|
|
606
|
+
var DISPLAY_NAME_ASSIGNMENT_SELECTOR = [
|
|
607
|
+
"AssignmentExpression",
|
|
608
|
+
"[type]",
|
|
609
|
+
"[operator='=']",
|
|
610
|
+
"[left.type='MemberExpression']",
|
|
611
|
+
"[left.property.name='displayName']"
|
|
612
|
+
].join("");
|
|
613
|
+
function isDisplayNameAssignment(node) {
|
|
614
|
+
if (node == null) return false;
|
|
615
|
+
return node.type === types.AST_NODE_TYPES.AssignmentExpression && node.operator === "=" && node.left.type === types.AST_NODE_TYPES.MemberExpression && node.left.property.type === types.AST_NODE_TYPES.Identifier && node.left.property.name === "displayName";
|
|
616
|
+
}
|
|
135
617
|
|
|
136
618
|
// src/utils/is-react-api.ts
|
|
137
619
|
function isReactAPIWithName(name, member) {
|
|
@@ -163,21 +645,6 @@ var isCreateRefCall = isReactAPICallWithName("createRef");
|
|
|
163
645
|
var isForwardRefCall = isReactAPICallWithName("forwardRef");
|
|
164
646
|
var isMemoCall = isReactAPICallWithName("memo");
|
|
165
647
|
|
|
166
|
-
// src/element/hierarchy.ts
|
|
167
|
-
function isInsideCreateElementProps(node, context) {
|
|
168
|
-
const call = AST9__namespace.findParentNode(node, isCreateElementCall(context));
|
|
169
|
-
if (call == null) return false;
|
|
170
|
-
const prop = AST9__namespace.findParentNode(node, AST9__namespace.is(types.AST_NODE_TYPES.ObjectExpression));
|
|
171
|
-
if (prop == null) return false;
|
|
172
|
-
return prop === call.arguments[1];
|
|
173
|
-
}
|
|
174
|
-
function isChildrenOfCreateElement(node, context) {
|
|
175
|
-
const parent = node.parent;
|
|
176
|
-
if (parent == null || parent.type !== types.AST_NODE_TYPES.CallExpression) return false;
|
|
177
|
-
if (!isCreateElementCall(parent, context)) return false;
|
|
178
|
-
return parent.arguments.slice(2).some((arg) => arg === node);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
648
|
// src/hook/hook-name.ts
|
|
182
649
|
var RE_HOOK_NAME = /^use[A-Z\d]/u;
|
|
183
650
|
function isReactHookName(name) {
|
|
@@ -187,7 +654,7 @@ function isReactHookName(name) {
|
|
|
187
654
|
// src/hook/is.ts
|
|
188
655
|
function isReactHook(node) {
|
|
189
656
|
if (node == null) return eff._;
|
|
190
|
-
const id =
|
|
657
|
+
const id = AST8__namespace.getFunctionIdentifier(node);
|
|
191
658
|
return id?.name != null && isReactHookName(id.name);
|
|
192
659
|
}
|
|
193
660
|
function isReactHookCall(node) {
|
|
@@ -203,17 +670,19 @@ function isReactHookCall(node) {
|
|
|
203
670
|
}
|
|
204
671
|
return false;
|
|
205
672
|
}
|
|
206
|
-
function isReactHookCallWithName(
|
|
673
|
+
function isReactHookCallWithName(context, node) {
|
|
207
674
|
if (node == null) return eff.constFalse;
|
|
208
|
-
const
|
|
209
|
-
|
|
675
|
+
const {
|
|
676
|
+
importSource = DEFAULT_ESLINT_REACT_SETTINGS.importSource,
|
|
677
|
+
skipImportCheck = true
|
|
678
|
+
} = shared.unsafeDecodeSettings(context.settings);
|
|
210
679
|
const initialScope = context.sourceCode.getScope(node);
|
|
211
680
|
return (name) => {
|
|
212
681
|
switch (true) {
|
|
213
682
|
case (node.callee.type === types.AST_NODE_TYPES.Identifier && node.callee.name === name):
|
|
214
|
-
return
|
|
683
|
+
return skipImportCheck || isInitializedFromReact(name, importSource, initialScope);
|
|
215
684
|
case (node.callee.type === types.AST_NODE_TYPES.MemberExpression && node.callee.property.type === types.AST_NODE_TYPES.Identifier && node.callee.property.name === name && "name" in node.callee.object):
|
|
216
|
-
return
|
|
685
|
+
return skipImportCheck || isInitializedFromReact(node.callee.object.name, importSource, initialScope);
|
|
217
686
|
default:
|
|
218
687
|
return false;
|
|
219
688
|
}
|
|
@@ -232,16 +701,18 @@ function isReactHookCallWithNameLoose(node) {
|
|
|
232
701
|
}
|
|
233
702
|
};
|
|
234
703
|
}
|
|
235
|
-
function isReactHookCallWithNameAlias(
|
|
236
|
-
const
|
|
237
|
-
|
|
704
|
+
function isReactHookCallWithNameAlias(context, name, alias) {
|
|
705
|
+
const {
|
|
706
|
+
importSource = DEFAULT_ESLINT_REACT_SETTINGS.importSource,
|
|
707
|
+
skipImportCheck = true
|
|
708
|
+
} = shared.unsafeDecodeSettings(context.settings);
|
|
238
709
|
return (node) => {
|
|
239
710
|
const initialScope = context.sourceCode.getScope(node);
|
|
240
711
|
switch (true) {
|
|
241
712
|
case (node.callee.type === types.AST_NODE_TYPES.Identifier && node.callee.name === name):
|
|
242
|
-
return
|
|
713
|
+
return skipImportCheck || isInitializedFromReact(name, importSource, initialScope);
|
|
243
714
|
case (node.callee.type === types.AST_NODE_TYPES.MemberExpression && node.callee.property.type === types.AST_NODE_TYPES.Identifier && node.callee.property.name === name && "name" in node.callee.object):
|
|
244
|
-
return
|
|
715
|
+
return skipImportCheck || isInitializedFromReact(node.callee.object.name, importSource, initialScope);
|
|
245
716
|
default:
|
|
246
717
|
return alias.some(isReactHookCallWithNameLoose(node));
|
|
247
718
|
}
|
|
@@ -279,13 +750,13 @@ var isUseTransitionCall = eff.flip(isReactHookCallWithName)("useTransition");
|
|
|
279
750
|
|
|
280
751
|
// src/hook/hierarchy.ts
|
|
281
752
|
function isInsideReactHook(node) {
|
|
282
|
-
return isReactHook(
|
|
753
|
+
return isReactHook(AST8__namespace.findParentNode(node, AST8__namespace.isFunction));
|
|
283
754
|
}
|
|
284
755
|
function useHookCollector() {
|
|
285
756
|
const hooks = /* @__PURE__ */ new Map();
|
|
286
757
|
const functionEntries = [];
|
|
287
758
|
const onFunctionEnter = (node) => {
|
|
288
|
-
const id =
|
|
759
|
+
const id = AST8__namespace.getFunctionIdentifier(node);
|
|
289
760
|
const key = shared.getId();
|
|
290
761
|
const name = id?.name;
|
|
291
762
|
if (name != null && isReactHookName(name)) {
|
|
@@ -374,26 +845,53 @@ var ERComponentFlag = {
|
|
|
374
845
|
ForwardRef: 1n << 3n,
|
|
375
846
|
Async: 1n << 4n
|
|
376
847
|
};
|
|
377
|
-
function isComponentWrapperCall(
|
|
848
|
+
function isComponentWrapperCall(context, node) {
|
|
378
849
|
if (node.type !== types.AST_NODE_TYPES.CallExpression) {
|
|
379
850
|
return false;
|
|
380
851
|
}
|
|
381
|
-
return isMemoCall(
|
|
852
|
+
return isMemoCall(context, node) || isForwardRefCall(context, node) || isReactHookCallWithNameLoose(node)("useCallback");
|
|
382
853
|
}
|
|
383
|
-
function getFunctionComponentIdentifier(
|
|
384
|
-
const functionId =
|
|
854
|
+
function getFunctionComponentIdentifier(context, node) {
|
|
855
|
+
const functionId = AST8__namespace.getFunctionIdentifier(node);
|
|
385
856
|
if (functionId != null) {
|
|
386
857
|
return functionId;
|
|
387
858
|
}
|
|
388
859
|
const { parent } = node;
|
|
389
|
-
if (parent.type === types.AST_NODE_TYPES.CallExpression && isComponentWrapperCall(
|
|
860
|
+
if (parent.type === types.AST_NODE_TYPES.CallExpression && isComponentWrapperCall(context, parent) && parent.parent.type === types.AST_NODE_TYPES.VariableDeclarator && parent.parent.id.type === types.AST_NODE_TYPES.Identifier) {
|
|
390
861
|
return parent.parent.id;
|
|
391
862
|
}
|
|
392
|
-
if (parent.type === types.AST_NODE_TYPES.CallExpression && isComponentWrapperCall(
|
|
863
|
+
if (parent.type === types.AST_NODE_TYPES.CallExpression && isComponentWrapperCall(context, parent) && parent.parent.type === types.AST_NODE_TYPES.CallExpression && isComponentWrapperCall(context, parent.parent) && parent.parent.parent.type === types.AST_NODE_TYPES.VariableDeclarator && parent.parent.parent.id.type === types.AST_NODE_TYPES.Identifier) {
|
|
393
864
|
return parent.parent.parent.id;
|
|
394
865
|
}
|
|
395
866
|
return eff._;
|
|
396
867
|
}
|
|
868
|
+
var RE_COMPONENT_NAME = /^_?[A-Z]/u;
|
|
869
|
+
function getComponentNameFromIdentifier(node) {
|
|
870
|
+
if (node == null) return eff._;
|
|
871
|
+
return Array.isArray(node) ? node.map((n) => n.name).join(".") : node.name;
|
|
872
|
+
}
|
|
873
|
+
function isComponentName(name) {
|
|
874
|
+
return RE_COMPONENT_NAME.test(name);
|
|
875
|
+
}
|
|
876
|
+
function hasNoneOrValidComponentName(context, node) {
|
|
877
|
+
const id = getFunctionComponentIdentifier(context, node);
|
|
878
|
+
if (id == null) return true;
|
|
879
|
+
const name = Array.isArray(id) ? id.at(-1)?.name : id.name;
|
|
880
|
+
return name != null && isComponentName(name);
|
|
881
|
+
}
|
|
882
|
+
function isInsideCreateElementProps(context, node) {
|
|
883
|
+
const call = AST8__namespace.findParentNode(node, isCreateElementCall(context));
|
|
884
|
+
if (call == null) return false;
|
|
885
|
+
const prop = AST8__namespace.findParentNode(node, AST8__namespace.is(types.AST_NODE_TYPES.ObjectExpression));
|
|
886
|
+
if (prop == null) return false;
|
|
887
|
+
return prop === call.arguments[1];
|
|
888
|
+
}
|
|
889
|
+
function isChildrenOfCreateElement(context, node) {
|
|
890
|
+
const parent = node.parent;
|
|
891
|
+
if (parent == null || parent.type !== types.AST_NODE_TYPES.CallExpression) return false;
|
|
892
|
+
if (!isCreateElementCall(context, parent)) return false;
|
|
893
|
+
return parent.arguments.slice(2).some((arg) => arg === node);
|
|
894
|
+
}
|
|
397
895
|
function isClassComponent(node) {
|
|
398
896
|
if ("superClass" in node && node.superClass != null) {
|
|
399
897
|
const re = /^(?:Pure)?Component$/u;
|
|
@@ -421,28 +919,28 @@ function isPureComponent(node) {
|
|
|
421
919
|
|
|
422
920
|
// src/component/component-lifecycle.ts
|
|
423
921
|
function isComponentDidMount(node) {
|
|
424
|
-
return
|
|
922
|
+
return AST8__namespace.isMethodOrProperty(node) && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "componentDidMount";
|
|
425
923
|
}
|
|
426
924
|
function isComponentWillUnmount(node) {
|
|
427
|
-
return
|
|
925
|
+
return AST8__namespace.isMethodOrProperty(node) && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "componentWillUnmount";
|
|
428
926
|
}
|
|
429
927
|
function isComponentDidCatch(node) {
|
|
430
|
-
return
|
|
928
|
+
return AST8__namespace.isMethodOrProperty(node) && !node.static && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "componentDidCatch";
|
|
431
929
|
}
|
|
432
930
|
function isGetDerivedStateFromError(node) {
|
|
433
|
-
return
|
|
931
|
+
return AST8__namespace.isMethodOrProperty(node) && node.static && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromError";
|
|
434
932
|
}
|
|
435
933
|
function isGetDerivedStateFromProps(node) {
|
|
436
|
-
return
|
|
934
|
+
return AST8__namespace.isMethodOrProperty(node) && node.static && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromProps";
|
|
437
935
|
}
|
|
438
936
|
function isFunctionOfComponentDidMount(node) {
|
|
439
|
-
return
|
|
937
|
+
return AST8__namespace.isFunction(node) && isComponentDidMount(node.parent) && node.parent.value === node;
|
|
440
938
|
}
|
|
441
939
|
function isFunctionOfComponentWillUnmount(node) {
|
|
442
|
-
return
|
|
940
|
+
return AST8__namespace.isFunction(node) && isComponentWillUnmount(node.parent) && node.parent.value === node;
|
|
443
941
|
}
|
|
444
942
|
function isRenderMethodLike(node) {
|
|
445
|
-
return
|
|
943
|
+
return AST8__namespace.isMethodOrProperty(node) && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "render" && node.parent.parent.type === types.AST_NODE_TYPES.ClassDeclaration;
|
|
446
944
|
}
|
|
447
945
|
function isFunctionOfRenderMethod(node) {
|
|
448
946
|
if (!isRenderMethodLike(node.parent)) {
|
|
@@ -451,21 +949,46 @@ function isFunctionOfRenderMethod(node) {
|
|
|
451
949
|
return isClassComponent(node.parent.parent.parent);
|
|
452
950
|
}
|
|
453
951
|
function isInsideRenderMethod(node) {
|
|
454
|
-
return
|
|
952
|
+
return AST8__namespace.findParentNode(node, (node2) => isRenderMethodLike(node2) && isClassComponent(node2.parent.parent)) != null;
|
|
455
953
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
954
|
+
|
|
955
|
+
// src/component/hierarchy.ts
|
|
956
|
+
function hasValidHierarchy(context, node, hint) {
|
|
957
|
+
if (isChildrenOfCreateElement(context, node) || isFunctionOfRenderMethod(node)) {
|
|
958
|
+
return false;
|
|
959
|
+
}
|
|
960
|
+
if (hint & ERComponentHint.SkipMapCallback && AST8__namespace.isMapCallLoose(node.parent)) {
|
|
961
|
+
return false;
|
|
962
|
+
}
|
|
963
|
+
if (hint & ERComponentHint.SkipObjectMethod && isFunctionOfObjectMethod(node.parent)) {
|
|
964
|
+
return false;
|
|
965
|
+
}
|
|
966
|
+
if (hint & ERComponentHint.SkipClassMethod && isFunctionOfClassMethod(node.parent)) {
|
|
967
|
+
return false;
|
|
968
|
+
}
|
|
969
|
+
if (hint & ERComponentHint.SkipClassProperty && isFunctionOfClassProperty(node.parent)) {
|
|
970
|
+
return false;
|
|
971
|
+
}
|
|
972
|
+
const boundaryNode = AST8__namespace.findParentNode(
|
|
973
|
+
node,
|
|
974
|
+
AST8__namespace.isOneOf([
|
|
975
|
+
types.AST_NODE_TYPES.JSXExpressionContainer,
|
|
976
|
+
types.AST_NODE_TYPES.ArrowFunctionExpression,
|
|
977
|
+
types.AST_NODE_TYPES.FunctionExpression,
|
|
978
|
+
types.AST_NODE_TYPES.Property,
|
|
979
|
+
types.AST_NODE_TYPES.ClassBody
|
|
980
|
+
])
|
|
981
|
+
);
|
|
982
|
+
return boundaryNode == null || boundaryNode.type !== types.AST_NODE_TYPES.JSXExpressionContainer;
|
|
460
983
|
}
|
|
461
|
-
function
|
|
462
|
-
return
|
|
984
|
+
function isFunctionOfClassMethod(node) {
|
|
985
|
+
return (node.type === types.AST_NODE_TYPES.FunctionExpression || node.type === types.AST_NODE_TYPES.ArrowFunctionExpression) && node.parent.type === types.AST_NODE_TYPES.MethodDefinition;
|
|
463
986
|
}
|
|
464
|
-
function
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
return
|
|
987
|
+
function isFunctionOfClassProperty(node) {
|
|
988
|
+
return (node.type === types.AST_NODE_TYPES.FunctionExpression || node.type === types.AST_NODE_TYPES.ArrowFunctionExpression) && node.parent.type === types.AST_NODE_TYPES.Property;
|
|
989
|
+
}
|
|
990
|
+
function isFunctionOfObjectMethod(node) {
|
|
991
|
+
return (node.type === types.AST_NODE_TYPES.FunctionExpression || node.type === types.AST_NODE_TYPES.ArrowFunctionExpression) && node.parent.type === types.AST_NODE_TYPES.Property && node.parent.parent.type === types.AST_NODE_TYPES.ObjectExpression;
|
|
469
992
|
}
|
|
470
993
|
|
|
471
994
|
// src/component/component-collector.ts
|
|
@@ -483,7 +1006,7 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
|
|
|
483
1006
|
const entry = functionEntries.at(-1);
|
|
484
1007
|
if (entry == null) return;
|
|
485
1008
|
if (!entry.isComponent) return functionEntries.pop();
|
|
486
|
-
const shouldDrop =
|
|
1009
|
+
const shouldDrop = AST8__namespace.getNestedReturnStatements(entry.node.body).slice().reverse().some((r) => {
|
|
487
1010
|
return context.sourceCode.getScope(r).block === entry.node && r.argument != null && !JSX3__namespace.isJSXValue(r.argument, jsxCtx, hint);
|
|
488
1011
|
});
|
|
489
1012
|
if (shouldDrop) {
|
|
@@ -508,10 +1031,10 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
|
|
|
508
1031
|
const entry = getCurrentEntry();
|
|
509
1032
|
if (entry == null) return;
|
|
510
1033
|
const { body } = entry.node;
|
|
511
|
-
const isComponent = hasNoneOrValidComponentName(entry.node
|
|
1034
|
+
const isComponent = hasNoneOrValidComponentName(context, entry.node) && JSX3__namespace.isJSXValue(body, jsxCtx, hint) && hasValidHierarchy(context, entry.node, hint);
|
|
512
1035
|
if (!isComponent) return;
|
|
513
|
-
const initPath =
|
|
514
|
-
const id = getFunctionComponentIdentifier(entry.node
|
|
1036
|
+
const initPath = AST8__namespace.getFunctionInitPath(entry.node);
|
|
1037
|
+
const id = getFunctionComponentIdentifier(context, entry.node);
|
|
515
1038
|
const name = getComponentNameFromIdentifier(id);
|
|
516
1039
|
const key = shared.getId();
|
|
517
1040
|
components.set(key, {
|
|
@@ -548,11 +1071,11 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
|
|
|
548
1071
|
"ReturnStatement[type]"(node) {
|
|
549
1072
|
const entry = getCurrentEntry();
|
|
550
1073
|
if (entry == null) return;
|
|
551
|
-
const isComponent = hasNoneOrValidComponentName(entry.node
|
|
1074
|
+
const isComponent = hasNoneOrValidComponentName(context, entry.node) && JSX3__namespace.isJSXValue(node.argument, jsxCtx, hint) && hasValidHierarchy(context, entry.node, hint);
|
|
552
1075
|
if (!isComponent) return;
|
|
553
1076
|
entry.isComponent = true;
|
|
554
|
-
const initPath =
|
|
555
|
-
const id = getFunctionComponentIdentifier(entry.node
|
|
1077
|
+
const initPath = AST8__namespace.getFunctionInitPath(entry.node);
|
|
1078
|
+
const id = getFunctionComponentIdentifier(context, entry.node);
|
|
556
1079
|
const name = getComponentNameFromIdentifier(id);
|
|
557
1080
|
components.set(entry.key, {
|
|
558
1081
|
id,
|
|
@@ -570,40 +1093,12 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
|
|
|
570
1093
|
};
|
|
571
1094
|
return { ctx, listeners };
|
|
572
1095
|
}
|
|
573
|
-
function hasValidHierarchy(node, context, hint) {
|
|
574
|
-
if (isChildrenOfCreateElement(node, context) || isFunctionOfRenderMethod(node)) {
|
|
575
|
-
return false;
|
|
576
|
-
}
|
|
577
|
-
if (hint & ERComponentHint.SkipMapCallback && AST9__namespace.isMapCallLoose(node.parent)) {
|
|
578
|
-
return false;
|
|
579
|
-
}
|
|
580
|
-
if (hint & ERComponentHint.SkipObjectMethod && AST9__namespace.isFunctionOfObjectMethod(node.parent)) {
|
|
581
|
-
return false;
|
|
582
|
-
}
|
|
583
|
-
if (hint & ERComponentHint.SkipClassMethod && AST9__namespace.isFunctionOfClassMethod(node.parent)) {
|
|
584
|
-
return false;
|
|
585
|
-
}
|
|
586
|
-
if (hint & ERComponentHint.SkipClassProperty && AST9__namespace.isFunctionOfClassProperty(node.parent)) {
|
|
587
|
-
return false;
|
|
588
|
-
}
|
|
589
|
-
const boundaryNode = AST9__namespace.findParentNode(
|
|
590
|
-
node,
|
|
591
|
-
AST9__namespace.isOneOf([
|
|
592
|
-
types.AST_NODE_TYPES.JSXExpressionContainer,
|
|
593
|
-
types.AST_NODE_TYPES.ArrowFunctionExpression,
|
|
594
|
-
types.AST_NODE_TYPES.FunctionExpression,
|
|
595
|
-
types.AST_NODE_TYPES.Property,
|
|
596
|
-
types.AST_NODE_TYPES.ClassBody
|
|
597
|
-
])
|
|
598
|
-
);
|
|
599
|
-
return boundaryNode == null || boundaryNode.type !== types.AST_NODE_TYPES.JSXExpressionContainer;
|
|
600
|
-
}
|
|
601
1096
|
function getComponentFlag(initPath) {
|
|
602
1097
|
let flag = ERComponentFlag.None;
|
|
603
|
-
if (initPath != null &&
|
|
1098
|
+
if (initPath != null && AST8__namespace.hasCallInFunctionInitPath("memo", initPath)) {
|
|
604
1099
|
flag |= ERComponentFlag.Memo;
|
|
605
1100
|
}
|
|
606
|
-
if (initPath != null &&
|
|
1101
|
+
if (initPath != null && AST8__namespace.hasCallInFunctionInitPath("forwardRef", initPath)) {
|
|
607
1102
|
flag |= ERComponentFlag.ForwardRef;
|
|
608
1103
|
}
|
|
609
1104
|
return flag;
|
|
@@ -620,7 +1115,7 @@ function useComponentCollectorLegacy() {
|
|
|
620
1115
|
if (!isClassComponent(node)) {
|
|
621
1116
|
return;
|
|
622
1117
|
}
|
|
623
|
-
const id =
|
|
1118
|
+
const id = AST8__namespace.getClassIdentifier(node);
|
|
624
1119
|
const key = shared.getId();
|
|
625
1120
|
const flag = isPureComponent(node) ? ERComponentFlag.PureComponent : ERComponentFlag.None;
|
|
626
1121
|
components.set(
|
|
@@ -651,9 +1146,9 @@ var ERPhaseRelevance = birecord__default.default({
|
|
|
651
1146
|
setup: "cleanup"
|
|
652
1147
|
});
|
|
653
1148
|
var isInversePhase = eff.dual(2, (a, b) => ERPhaseRelevance.get(a) === b);
|
|
654
|
-
function isRenderFunctionLoose(
|
|
1149
|
+
function isRenderFunctionLoose(context, node) {
|
|
655
1150
|
const { body, parent } = node;
|
|
656
|
-
if (
|
|
1151
|
+
if (AST8__namespace.getFunctionIdentifier(node)?.name.startsWith("render")) {
|
|
657
1152
|
return parent.type === types.AST_NODE_TYPES.JSXExpressionContainer && parent.parent.type === types.AST_NODE_TYPES.JSXAttribute && parent.parent.name.type === types.AST_NODE_TYPES.JSXIdentifier && parent.parent.name.name.startsWith("render");
|
|
658
1153
|
}
|
|
659
1154
|
return JSX3__namespace.isJSXValue(
|
|
@@ -664,11 +1159,11 @@ function isRenderFunctionLoose(node, context) {
|
|
|
664
1159
|
JSX3__namespace.JSXValueHint.SkipNullLiteral | JSX3__namespace.JSXValueHint.SkipUndefined | JSX3__namespace.JSXValueHint.StrictLogical | JSX3__namespace.JSXValueHint.StrictConditional
|
|
665
1160
|
);
|
|
666
1161
|
}
|
|
667
|
-
function isRenderPropLoose(
|
|
1162
|
+
function isRenderPropLoose(context, node) {
|
|
668
1163
|
if (node.name.type !== types.AST_NODE_TYPES.JSXIdentifier) {
|
|
669
1164
|
return false;
|
|
670
1165
|
}
|
|
671
|
-
return node.name.name.startsWith("render") && node.value?.type === types.AST_NODE_TYPES.JSXExpressionContainer &&
|
|
1166
|
+
return node.name.name.startsWith("render") && node.value?.type === types.AST_NODE_TYPES.JSXExpressionContainer && AST8__namespace.isFunction(node.value.expression) && isRenderFunctionLoose(context, node.value.expression);
|
|
672
1167
|
}
|
|
673
1168
|
function isDirectValueOfRenderPropertyLoose(node) {
|
|
674
1169
|
const matching = (node2) => {
|
|
@@ -680,7 +1175,7 @@ function isDeclaredInRenderPropLoose(node) {
|
|
|
680
1175
|
if (isDirectValueOfRenderPropertyLoose(node)) {
|
|
681
1176
|
return true;
|
|
682
1177
|
}
|
|
683
|
-
const parent =
|
|
1178
|
+
const parent = AST8__namespace.findParentNode(node, AST8__namespace.is(types.AST_NODE_TYPES.JSXExpressionContainer))?.parent;
|
|
684
1179
|
if (parent?.type !== types.AST_NODE_TYPES.JSXAttribute) {
|
|
685
1180
|
return false;
|
|
686
1181
|
}
|
|
@@ -688,16 +1183,16 @@ function isDeclaredInRenderPropLoose(node) {
|
|
|
688
1183
|
}
|
|
689
1184
|
function isThisSetState(node) {
|
|
690
1185
|
const { callee } = node;
|
|
691
|
-
return callee.type === types.AST_NODE_TYPES.MemberExpression &&
|
|
1186
|
+
return callee.type === types.AST_NODE_TYPES.MemberExpression && AST8__namespace.isThisExpression(callee.object) && callee.property.type === types.AST_NODE_TYPES.Identifier && callee.property.name === "setState";
|
|
692
1187
|
}
|
|
693
1188
|
function isFunctionOfUseEffectSetup(node) {
|
|
694
1189
|
if (node == null) return eff._;
|
|
695
1190
|
return node.parent?.type === types.AST_NODE_TYPES.CallExpression && node.parent.callee !== node && node.parent.callee.type === types.AST_NODE_TYPES.Identifier && node.parent.arguments.at(0) === node && isUseEffectCallLoose(node.parent);
|
|
696
1191
|
}
|
|
697
1192
|
function isFunctionOfUseEffectCleanup(node) {
|
|
698
|
-
const nearReturn =
|
|
699
|
-
const nearFunction =
|
|
700
|
-
const nearFunctionOfReturn =
|
|
1193
|
+
const nearReturn = AST8__namespace.findParentNode(node, AST8__namespace.is(types.AST_NODE_TYPES.ReturnStatement));
|
|
1194
|
+
const nearFunction = AST8__namespace.findParentNode(node, AST8__namespace.isFunction);
|
|
1195
|
+
const nearFunctionOfReturn = AST8__namespace.findParentNode(nearReturn, AST8__namespace.isFunction);
|
|
701
1196
|
return nearFunction === nearFunctionOfReturn && isFunctionOfUseEffectSetup(nearFunction);
|
|
702
1197
|
}
|
|
703
1198
|
|
|
@@ -711,6 +1206,7 @@ exports.RE_HOOK_NAME = RE_HOOK_NAME;
|
|
|
711
1206
|
exports.getComponentNameFromIdentifier = getComponentNameFromIdentifier;
|
|
712
1207
|
exports.getFunctionComponentIdentifier = getFunctionComponentIdentifier;
|
|
713
1208
|
exports.hasNoneOrValidComponentName = hasNoneOrValidComponentName;
|
|
1209
|
+
exports.hasValidHierarchy = hasValidHierarchy;
|
|
714
1210
|
exports.isCallFromReact = isCallFromReact;
|
|
715
1211
|
exports.isCallFromReactMember = isCallFromReactMember;
|
|
716
1212
|
exports.isChildrenCount = isChildrenCount;
|
|
@@ -743,7 +1239,11 @@ exports.isDisplayNameAssignment = isDisplayNameAssignment;
|
|
|
743
1239
|
exports.isForwardRef = isForwardRef;
|
|
744
1240
|
exports.isForwardRefCall = isForwardRefCall;
|
|
745
1241
|
exports.isFromReact = isFromReact;
|
|
1242
|
+
exports.isFromReactLoose = isFromReactLoose;
|
|
746
1243
|
exports.isFromReactMember = isFromReactMember;
|
|
1244
|
+
exports.isFromReactMemberLoose = isFromReactMemberLoose;
|
|
1245
|
+
exports.isFromReactMemberStrict = isFromReactMemberStrict;
|
|
1246
|
+
exports.isFromReactStrict = isFromReactStrict;
|
|
747
1247
|
exports.isFunctionOfComponentDidMount = isFunctionOfComponentDidMount;
|
|
748
1248
|
exports.isFunctionOfComponentWillUnmount = isFunctionOfComponentWillUnmount;
|
|
749
1249
|
exports.isFunctionOfRenderMethod = isFunctionOfRenderMethod;
|