eslint-plugin-react-hooks 6.1.0 → 6.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# `eslint-plugin-react-hooks`
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
It is a part of the [Hooks API](https://react.dev/reference/react/hooks) for React.
|
|
3
|
+
The official ESLint plugin for [React](https://react.dev) which enforces the [Rules of React](https://react.dev/reference/eslint-plugin-react-hooks) and other best practices.
|
|
6
4
|
|
|
7
5
|
## Installation
|
|
8
6
|
|
|
@@ -89,7 +87,7 @@ If you're using a version earlier than 5.2.0, the legacy config was simply `reco
|
|
|
89
87
|
|
|
90
88
|
### Custom Configuration
|
|
91
89
|
|
|
92
|
-
If you want more fine-grained configuration, you can instead
|
|
90
|
+
If you want more fine-grained configuration, you can instead choose to enable specific rules. However, we strongly encourage using the recommended presets — see above — so that you will automatically receive new recommended rules as we add them in future versions of the plugin.
|
|
93
91
|
|
|
94
92
|
#### Flat Config (eslint.config.js|ts)
|
|
95
93
|
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import * as estree from 'estree';
|
|
2
|
-
import { Rule } from 'eslint';
|
|
2
|
+
import { Rule, Linter } from 'eslint';
|
|
3
3
|
|
|
4
4
|
declare const plugin: {
|
|
5
5
|
meta: {
|
|
6
6
|
name: string;
|
|
7
7
|
};
|
|
8
|
-
configs: {};
|
|
9
8
|
rules: {
|
|
10
9
|
'exhaustive-deps': {
|
|
11
10
|
meta: {
|
|
@@ -73,6 +72,19 @@ declare const plugin: {
|
|
|
73
72
|
};
|
|
74
73
|
};
|
|
75
74
|
};
|
|
75
|
+
configs: {
|
|
76
|
+
"recommended-legacy": {
|
|
77
|
+
plugins: Array<string>;
|
|
78
|
+
rules: Linter.RulesRecord;
|
|
79
|
+
};
|
|
80
|
+
"recommended-latest-legacy": {
|
|
81
|
+
plugins: Array<string>;
|
|
82
|
+
rules: Linter.RulesRecord;
|
|
83
|
+
};
|
|
84
|
+
"flat/recommended": Array<Linter.Config>;
|
|
85
|
+
"recommended-latest": Array<Linter.Config>;
|
|
86
|
+
recommended: Array<Linter.Config>;
|
|
87
|
+
};
|
|
76
88
|
};
|
|
77
89
|
|
|
78
90
|
export { plugin as default };
|
|
@@ -19,8 +19,6 @@ var BabelParser = require('@babel/parser');
|
|
|
19
19
|
var zod = require('zod');
|
|
20
20
|
var zodValidationError = require('zod-validation-error');
|
|
21
21
|
var crypto = require('crypto');
|
|
22
|
-
var PluginProposalPrivateMethods = require('@babel/plugin-proposal-private-methods');
|
|
23
|
-
var HermesParser = require('hermes-parser');
|
|
24
22
|
var util = require('util');
|
|
25
23
|
|
|
26
24
|
const SETTINGS_KEY = 'react-hooks';
|
|
@@ -32072,15 +32070,15 @@ const HookSchema = zod.z.object({
|
|
|
32072
32070
|
});
|
|
32073
32071
|
const EnvironmentConfigSchema = zod.z.object({
|
|
32074
32072
|
customHooks: zod.z.map(zod.z.string(), HookSchema).default(new Map()),
|
|
32075
|
-
moduleTypeProvider: zod.z.nullable(zod.z.
|
|
32073
|
+
moduleTypeProvider: zod.z.nullable(zod.z.any()).default(null),
|
|
32076
32074
|
customMacros: zod.z.nullable(zod.z.array(MacroSchema)).default(null),
|
|
32077
32075
|
enableResetCacheOnSourceFileChanges: zod.z.nullable(zod.z.boolean()).default(null),
|
|
32078
|
-
enablePreserveExistingMemoizationGuarantees: zod.z.boolean().default(
|
|
32076
|
+
enablePreserveExistingMemoizationGuarantees: zod.z.boolean().default(true),
|
|
32079
32077
|
validatePreserveExistingMemoizationGuarantees: zod.z.boolean().default(true),
|
|
32080
32078
|
enablePreserveExistingManualUseMemo: zod.z.boolean().default(false),
|
|
32081
32079
|
enableForest: zod.z.boolean().default(false),
|
|
32082
32080
|
enableUseTypeAnnotations: zod.z.boolean().default(false),
|
|
32083
|
-
flowTypeProvider: zod.z.nullable(zod.z.
|
|
32081
|
+
flowTypeProvider: zod.z.nullable(zod.z.any()).default(null),
|
|
32084
32082
|
enableOptionalDependencies: zod.z.boolean().default(true),
|
|
32085
32083
|
enableFire: zod.z.boolean().default(false),
|
|
32086
32084
|
enableNameAnonymousFunctions: zod.z.boolean().default(false),
|
|
@@ -32445,6 +32443,12 @@ _Environment_globals = new WeakMap(), _Environment_shapes = new WeakMap(), _Envi
|
|
|
32445
32443
|
if (moduleTypeProvider == null) {
|
|
32446
32444
|
return null;
|
|
32447
32445
|
}
|
|
32446
|
+
if (typeof moduleTypeProvider !== 'function') {
|
|
32447
|
+
CompilerError.throwInvalidConfig({
|
|
32448
|
+
reason: `Expected a function for \`moduleTypeProvider\``,
|
|
32449
|
+
loc,
|
|
32450
|
+
});
|
|
32451
|
+
}
|
|
32448
32452
|
const unparsedModuleConfig = moduleTypeProvider(moduleName);
|
|
32449
32453
|
if (unparsedModuleConfig != null) {
|
|
32450
32454
|
const parsedModuleConfig = TypeSchema.safeParse(unparsedModuleConfig);
|
|
@@ -45315,6 +45319,29 @@ function collectNonNullsInBlocks(fn, context) {
|
|
|
45315
45319
|
}
|
|
45316
45320
|
}
|
|
45317
45321
|
}
|
|
45322
|
+
else if (fn.env.config.enablePreserveExistingMemoizationGuarantees &&
|
|
45323
|
+
instr.value.kind === 'StartMemoize' &&
|
|
45324
|
+
instr.value.deps != null) {
|
|
45325
|
+
for (const dep of instr.value.deps) {
|
|
45326
|
+
if (dep.root.kind === 'NamedLocal') {
|
|
45327
|
+
if (!isImmutableAtInstr(dep.root.value.identifier, instr.id, context)) {
|
|
45328
|
+
continue;
|
|
45329
|
+
}
|
|
45330
|
+
for (let i = 0; i < dep.path.length; i++) {
|
|
45331
|
+
const pathEntry = dep.path[i];
|
|
45332
|
+
if (pathEntry.optional) {
|
|
45333
|
+
break;
|
|
45334
|
+
}
|
|
45335
|
+
const depNode = context.registry.getOrCreateProperty({
|
|
45336
|
+
identifier: dep.root.value.identifier,
|
|
45337
|
+
path: dep.path.slice(0, i),
|
|
45338
|
+
reactive: dep.root.value.reactive,
|
|
45339
|
+
});
|
|
45340
|
+
assumedNonNullObjects.add(depNode);
|
|
45341
|
+
}
|
|
45342
|
+
}
|
|
45343
|
+
}
|
|
45344
|
+
}
|
|
45318
45345
|
}
|
|
45319
45346
|
nodes.set(block.id, {
|
|
45320
45347
|
block,
|
|
@@ -54127,20 +54154,6 @@ function getFlowSuppressions(sourceCode) {
|
|
|
54127
54154
|
}
|
|
54128
54155
|
return results;
|
|
54129
54156
|
}
|
|
54130
|
-
function filterUnusedOptOutDirectives(directives) {
|
|
54131
|
-
const results = [];
|
|
54132
|
-
for (const directive of directives) {
|
|
54133
|
-
if (OPT_OUT_DIRECTIVES.has(directive.value.value) &&
|
|
54134
|
-
directive.loc != null) {
|
|
54135
|
-
results.push({
|
|
54136
|
-
loc: directive.loc,
|
|
54137
|
-
directive: directive.value.value,
|
|
54138
|
-
range: [directive.start, directive.end],
|
|
54139
|
-
});
|
|
54140
|
-
}
|
|
54141
|
-
}
|
|
54142
|
-
return results;
|
|
54143
|
-
}
|
|
54144
54157
|
function runReactCompilerImpl({ sourceCode, filename, userOpts, }) {
|
|
54145
54158
|
var _a, _b;
|
|
54146
54159
|
const options = parsePluginOptions(Object.assign(Object.assign(Object.assign({}, COMPILER_OPTIONS), userOpts), { environment: Object.assign(Object.assign({}, COMPILER_OPTIONS.environment), userOpts.environment) }));
|
|
@@ -54149,7 +54162,6 @@ function runReactCompilerImpl({ sourceCode, filename, userOpts, }) {
|
|
|
54149
54162
|
filename,
|
|
54150
54163
|
userOpts,
|
|
54151
54164
|
flowSuppressions: [],
|
|
54152
|
-
unusedOptOutDirectives: [],
|
|
54153
54165
|
events: [],
|
|
54154
54166
|
};
|
|
54155
54167
|
const userLogger = options.logger;
|
|
@@ -54166,28 +54178,14 @@ function runReactCompilerImpl({ sourceCode, filename, userOpts, }) {
|
|
|
54166
54178
|
(_b = options.logger) === null || _b === void 0 ? void 0 : _b.logEvent(filename, err);
|
|
54167
54179
|
}
|
|
54168
54180
|
let babelAST = null;
|
|
54169
|
-
|
|
54170
|
-
|
|
54171
|
-
|
|
54172
|
-
|
|
54173
|
-
|
|
54174
|
-
|
|
54175
|
-
});
|
|
54176
|
-
}
|
|
54177
|
-
catch (_c) {
|
|
54178
|
-
}
|
|
54181
|
+
try {
|
|
54182
|
+
babelAST = BabelParser.parse(sourceCode.text, {
|
|
54183
|
+
sourceFilename: filename,
|
|
54184
|
+
sourceType: 'unambiguous',
|
|
54185
|
+
plugins: ['typescript', 'jsx'],
|
|
54186
|
+
});
|
|
54179
54187
|
}
|
|
54180
|
-
|
|
54181
|
-
try {
|
|
54182
|
-
babelAST = HermesParser.parse(sourceCode.text, {
|
|
54183
|
-
babel: true,
|
|
54184
|
-
enableExperimentalComponentSyntax: true,
|
|
54185
|
-
sourceFilename: filename,
|
|
54186
|
-
sourceType: 'module',
|
|
54187
|
-
});
|
|
54188
|
-
}
|
|
54189
|
-
catch (_d) {
|
|
54190
|
-
}
|
|
54188
|
+
catch (err) {
|
|
54191
54189
|
}
|
|
54192
54190
|
if (babelAST != null) {
|
|
54193
54191
|
results.flowSuppressions = getFlowSuppressions(sourceCode);
|
|
@@ -54196,29 +54194,11 @@ function runReactCompilerImpl({ sourceCode, filename, userOpts, }) {
|
|
|
54196
54194
|
filename,
|
|
54197
54195
|
highlightCode: false,
|
|
54198
54196
|
retainLines: true,
|
|
54199
|
-
plugins: [
|
|
54200
|
-
[PluginProposalPrivateMethods.default, { loose: true }],
|
|
54201
|
-
[BabelPluginReactCompiler, options],
|
|
54202
|
-
],
|
|
54197
|
+
plugins: [[BabelPluginReactCompiler, options]],
|
|
54203
54198
|
sourceType: 'module',
|
|
54204
54199
|
configFile: false,
|
|
54205
54200
|
babelrc: false,
|
|
54206
54201
|
});
|
|
54207
|
-
if (results.events.filter(e => e.kind === 'CompileError').length === 0) {
|
|
54208
|
-
core$1.traverse(babelAST, {
|
|
54209
|
-
FunctionDeclaration(path) {
|
|
54210
|
-
results.unusedOptOutDirectives.push(...filterUnusedOptOutDirectives(path.node.body.directives));
|
|
54211
|
-
},
|
|
54212
|
-
ArrowFunctionExpression(path) {
|
|
54213
|
-
if (path.node.body.type === 'BlockStatement') {
|
|
54214
|
-
results.unusedOptOutDirectives.push(...filterUnusedOptOutDirectives(path.node.body.directives));
|
|
54215
|
-
}
|
|
54216
|
-
},
|
|
54217
|
-
FunctionExpression(path) {
|
|
54218
|
-
results.unusedOptOutDirectives.push(...filterUnusedOptOutDirectives(path.node.body.directives));
|
|
54219
|
-
},
|
|
54220
|
-
});
|
|
54221
|
-
}
|
|
54222
54202
|
}
|
|
54223
54203
|
catch (err) {
|
|
54224
54204
|
}
|
|
@@ -54388,53 +54368,31 @@ function makeRule(rule) {
|
|
|
54388
54368
|
create,
|
|
54389
54369
|
};
|
|
54390
54370
|
}
|
|
54391
|
-
const NoUnusedDirectivesRule = {
|
|
54392
|
-
meta: {
|
|
54393
|
-
type: 'suggestion',
|
|
54394
|
-
docs: {
|
|
54395
|
-
recommended: true,
|
|
54396
|
-
},
|
|
54397
|
-
fixable: 'code',
|
|
54398
|
-
hasSuggestions: true,
|
|
54399
|
-
schema: [{ type: 'object', additionalProperties: true }],
|
|
54400
|
-
},
|
|
54401
|
-
create(context) {
|
|
54402
|
-
const results = getReactCompilerResult(context);
|
|
54403
|
-
for (const directive of results.unusedOptOutDirectives) {
|
|
54404
|
-
context.report({
|
|
54405
|
-
message: `Unused '${directive.directive}' directive`,
|
|
54406
|
-
loc: directive.loc,
|
|
54407
|
-
suggest: [
|
|
54408
|
-
{
|
|
54409
|
-
desc: 'Remove the directive',
|
|
54410
|
-
fix(fixer) {
|
|
54411
|
-
return fixer.removeRange(directive.range);
|
|
54412
|
-
},
|
|
54413
|
-
},
|
|
54414
|
-
],
|
|
54415
|
-
});
|
|
54416
|
-
}
|
|
54417
|
-
return {};
|
|
54418
|
-
},
|
|
54419
|
-
};
|
|
54420
54371
|
const allRules = LintRules.reduce((acc, rule) => {
|
|
54421
54372
|
acc[rule.name] = { rule: makeRule(rule), severity: rule.severity };
|
|
54422
54373
|
return acc;
|
|
54423
|
-
}, {
|
|
54424
|
-
|
|
54425
|
-
rule: NoUnusedDirectivesRule,
|
|
54426
|
-
severity: ErrorSeverity.Error,
|
|
54427
|
-
},
|
|
54428
|
-
});
|
|
54429
|
-
LintRules.filter(rule => rule.recommended).reduce((acc, rule) => {
|
|
54374
|
+
}, {});
|
|
54375
|
+
const recommendedRules = LintRules.filter(rule => rule.recommended).reduce((acc, rule) => {
|
|
54430
54376
|
acc[rule.name] = { rule: makeRule(rule), severity: rule.severity };
|
|
54431
54377
|
return acc;
|
|
54432
|
-
}, {
|
|
54433
|
-
|
|
54434
|
-
|
|
54435
|
-
|
|
54436
|
-
|
|
54437
|
-
}
|
|
54378
|
+
}, {});
|
|
54379
|
+
function mapErrorSeverityToESlint(severity) {
|
|
54380
|
+
switch (severity) {
|
|
54381
|
+
case ErrorSeverity.Error: {
|
|
54382
|
+
return 'error';
|
|
54383
|
+
}
|
|
54384
|
+
case ErrorSeverity.Warning: {
|
|
54385
|
+
return 'warn';
|
|
54386
|
+
}
|
|
54387
|
+
case ErrorSeverity.Hint:
|
|
54388
|
+
case ErrorSeverity.Off: {
|
|
54389
|
+
return 'off';
|
|
54390
|
+
}
|
|
54391
|
+
default: {
|
|
54392
|
+
assertExhaustive(severity, `Unhandled severity: ${severity}`);
|
|
54393
|
+
}
|
|
54394
|
+
}
|
|
54395
|
+
}
|
|
54438
54396
|
|
|
54439
54397
|
var assert_1;
|
|
54440
54398
|
var hasRequiredAssert;
|
|
@@ -57722,28 +57680,39 @@ function last(array) {
|
|
|
57722
57680
|
}
|
|
57723
57681
|
|
|
57724
57682
|
const rules = Object.assign({ 'exhaustive-deps': rule$1, 'rules-of-hooks': rule }, Object.fromEntries(Object.entries(allRules).map(([name, config]) => [name, config.rule])));
|
|
57725
|
-
const
|
|
57683
|
+
const basicRuleConfigs = {
|
|
57726
57684
|
'react-hooks/rules-of-hooks': 'error',
|
|
57727
57685
|
'react-hooks/exhaustive-deps': 'warn',
|
|
57728
57686
|
};
|
|
57687
|
+
const compilerRuleConfigs = Object.fromEntries(Object.entries(recommendedRules).map(([name, ruleConfig]) => {
|
|
57688
|
+
return [
|
|
57689
|
+
`react-hooks/${name}`,
|
|
57690
|
+
mapErrorSeverityToESlint(ruleConfig.severity),
|
|
57691
|
+
];
|
|
57692
|
+
}));
|
|
57693
|
+
const allRuleConfigs = Object.assign(Object.assign({}, basicRuleConfigs), compilerRuleConfigs);
|
|
57729
57694
|
const plugin = {
|
|
57730
57695
|
meta: {
|
|
57731
57696
|
name: 'eslint-plugin-react-hooks',
|
|
57732
57697
|
},
|
|
57733
|
-
configs: {},
|
|
57734
57698
|
rules,
|
|
57699
|
+
configs: {},
|
|
57735
57700
|
};
|
|
57736
57701
|
Object.assign(plugin.configs, {
|
|
57737
57702
|
'recommended-legacy': {
|
|
57738
57703
|
plugins: ['react-hooks'],
|
|
57739
|
-
rules:
|
|
57704
|
+
rules: basicRuleConfigs,
|
|
57705
|
+
},
|
|
57706
|
+
'recommended-latest-legacy': {
|
|
57707
|
+
plugins: ['react-hooks'],
|
|
57708
|
+
rules: allRuleConfigs,
|
|
57740
57709
|
},
|
|
57741
57710
|
'flat/recommended': [
|
|
57742
57711
|
{
|
|
57743
57712
|
plugins: {
|
|
57744
57713
|
'react-hooks': plugin,
|
|
57745
57714
|
},
|
|
57746
|
-
rules:
|
|
57715
|
+
rules: basicRuleConfigs,
|
|
57747
57716
|
},
|
|
57748
57717
|
],
|
|
57749
57718
|
'recommended-latest': [
|
|
@@ -57751,13 +57720,17 @@ Object.assign(plugin.configs, {
|
|
|
57751
57720
|
plugins: {
|
|
57752
57721
|
'react-hooks': plugin,
|
|
57753
57722
|
},
|
|
57754
|
-
rules:
|
|
57723
|
+
rules: allRuleConfigs,
|
|
57724
|
+
},
|
|
57725
|
+
],
|
|
57726
|
+
recommended: [
|
|
57727
|
+
{
|
|
57728
|
+
plugins: {
|
|
57729
|
+
'react-hooks': plugin,
|
|
57730
|
+
},
|
|
57731
|
+
rules: basicRuleConfigs,
|
|
57755
57732
|
},
|
|
57756
57733
|
],
|
|
57757
|
-
recommended: {
|
|
57758
|
-
plugins: ['react-hooks'],
|
|
57759
|
-
rules: ruleConfigs,
|
|
57760
|
-
},
|
|
57761
57734
|
});
|
|
57762
57735
|
|
|
57763
57736
|
module.exports = plugin;
|
|
@@ -15,8 +15,6 @@ var BabelParser = require('@babel/parser');
|
|
|
15
15
|
var zod = require('zod');
|
|
16
16
|
var zodValidationError = require('zod-validation-error');
|
|
17
17
|
var crypto = require('crypto');
|
|
18
|
-
var PluginProposalPrivateMethods = require('@babel/plugin-proposal-private-methods');
|
|
19
|
-
var HermesParser = require('hermes-parser');
|
|
20
18
|
var util = require('util');
|
|
21
19
|
|
|
22
20
|
const SETTINGS_KEY = 'react-hooks';
|
|
@@ -31899,15 +31897,15 @@ const HookSchema = zod.z.object({
|
|
|
31899
31897
|
});
|
|
31900
31898
|
const EnvironmentConfigSchema = zod.z.object({
|
|
31901
31899
|
customHooks: zod.z.map(zod.z.string(), HookSchema).default(new Map()),
|
|
31902
|
-
moduleTypeProvider: zod.z.nullable(zod.z.
|
|
31900
|
+
moduleTypeProvider: zod.z.nullable(zod.z.any()).default(null),
|
|
31903
31901
|
customMacros: zod.z.nullable(zod.z.array(MacroSchema)).default(null),
|
|
31904
31902
|
enableResetCacheOnSourceFileChanges: zod.z.nullable(zod.z.boolean()).default(null),
|
|
31905
|
-
enablePreserveExistingMemoizationGuarantees: zod.z.boolean().default(
|
|
31903
|
+
enablePreserveExistingMemoizationGuarantees: zod.z.boolean().default(true),
|
|
31906
31904
|
validatePreserveExistingMemoizationGuarantees: zod.z.boolean().default(true),
|
|
31907
31905
|
enablePreserveExistingManualUseMemo: zod.z.boolean().default(false),
|
|
31908
31906
|
enableForest: zod.z.boolean().default(false),
|
|
31909
31907
|
enableUseTypeAnnotations: zod.z.boolean().default(false),
|
|
31910
|
-
flowTypeProvider: zod.z.nullable(zod.z.
|
|
31908
|
+
flowTypeProvider: zod.z.nullable(zod.z.any()).default(null),
|
|
31911
31909
|
enableOptionalDependencies: zod.z.boolean().default(true),
|
|
31912
31910
|
enableFire: zod.z.boolean().default(false),
|
|
31913
31911
|
enableNameAnonymousFunctions: zod.z.boolean().default(false),
|
|
@@ -32272,6 +32270,12 @@ _Environment_globals = new WeakMap(), _Environment_shapes = new WeakMap(), _Envi
|
|
|
32272
32270
|
if (moduleTypeProvider == null) {
|
|
32273
32271
|
return null;
|
|
32274
32272
|
}
|
|
32273
|
+
if (typeof moduleTypeProvider !== 'function') {
|
|
32274
|
+
CompilerError.throwInvalidConfig({
|
|
32275
|
+
reason: `Expected a function for \`moduleTypeProvider\``,
|
|
32276
|
+
loc,
|
|
32277
|
+
});
|
|
32278
|
+
}
|
|
32275
32279
|
const unparsedModuleConfig = moduleTypeProvider(moduleName);
|
|
32276
32280
|
if (unparsedModuleConfig != null) {
|
|
32277
32281
|
const parsedModuleConfig = TypeSchema.safeParse(unparsedModuleConfig);
|
|
@@ -45142,6 +45146,29 @@ function collectNonNullsInBlocks(fn, context) {
|
|
|
45142
45146
|
}
|
|
45143
45147
|
}
|
|
45144
45148
|
}
|
|
45149
|
+
else if (fn.env.config.enablePreserveExistingMemoizationGuarantees &&
|
|
45150
|
+
instr.value.kind === 'StartMemoize' &&
|
|
45151
|
+
instr.value.deps != null) {
|
|
45152
|
+
for (const dep of instr.value.deps) {
|
|
45153
|
+
if (dep.root.kind === 'NamedLocal') {
|
|
45154
|
+
if (!isImmutableAtInstr(dep.root.value.identifier, instr.id, context)) {
|
|
45155
|
+
continue;
|
|
45156
|
+
}
|
|
45157
|
+
for (let i = 0; i < dep.path.length; i++) {
|
|
45158
|
+
const pathEntry = dep.path[i];
|
|
45159
|
+
if (pathEntry.optional) {
|
|
45160
|
+
break;
|
|
45161
|
+
}
|
|
45162
|
+
const depNode = context.registry.getOrCreateProperty({
|
|
45163
|
+
identifier: dep.root.value.identifier,
|
|
45164
|
+
path: dep.path.slice(0, i),
|
|
45165
|
+
reactive: dep.root.value.reactive,
|
|
45166
|
+
});
|
|
45167
|
+
assumedNonNullObjects.add(depNode);
|
|
45168
|
+
}
|
|
45169
|
+
}
|
|
45170
|
+
}
|
|
45171
|
+
}
|
|
45145
45172
|
}
|
|
45146
45173
|
nodes.set(block.id, {
|
|
45147
45174
|
block,
|
|
@@ -53954,20 +53981,6 @@ function getFlowSuppressions(sourceCode) {
|
|
|
53954
53981
|
}
|
|
53955
53982
|
return results;
|
|
53956
53983
|
}
|
|
53957
|
-
function filterUnusedOptOutDirectives(directives) {
|
|
53958
|
-
const results = [];
|
|
53959
|
-
for (const directive of directives) {
|
|
53960
|
-
if (OPT_OUT_DIRECTIVES.has(directive.value.value) &&
|
|
53961
|
-
directive.loc != null) {
|
|
53962
|
-
results.push({
|
|
53963
|
-
loc: directive.loc,
|
|
53964
|
-
directive: directive.value.value,
|
|
53965
|
-
range: [directive.start, directive.end],
|
|
53966
|
-
});
|
|
53967
|
-
}
|
|
53968
|
-
}
|
|
53969
|
-
return results;
|
|
53970
|
-
}
|
|
53971
53984
|
function runReactCompilerImpl({ sourceCode, filename, userOpts, }) {
|
|
53972
53985
|
var _a, _b;
|
|
53973
53986
|
const options = parsePluginOptions(Object.assign(Object.assign(Object.assign({}, COMPILER_OPTIONS), userOpts), { environment: Object.assign(Object.assign({}, COMPILER_OPTIONS.environment), userOpts.environment) }));
|
|
@@ -53976,7 +53989,6 @@ function runReactCompilerImpl({ sourceCode, filename, userOpts, }) {
|
|
|
53976
53989
|
filename,
|
|
53977
53990
|
userOpts,
|
|
53978
53991
|
flowSuppressions: [],
|
|
53979
|
-
unusedOptOutDirectives: [],
|
|
53980
53992
|
events: [],
|
|
53981
53993
|
};
|
|
53982
53994
|
const userLogger = options.logger;
|
|
@@ -53993,28 +54005,14 @@ function runReactCompilerImpl({ sourceCode, filename, userOpts, }) {
|
|
|
53993
54005
|
(_b = options.logger) === null || _b === void 0 ? void 0 : _b.logEvent(filename, err);
|
|
53994
54006
|
}
|
|
53995
54007
|
let babelAST = null;
|
|
53996
|
-
|
|
53997
|
-
|
|
53998
|
-
|
|
53999
|
-
|
|
54000
|
-
|
|
54001
|
-
|
|
54002
|
-
});
|
|
54003
|
-
}
|
|
54004
|
-
catch (_c) {
|
|
54005
|
-
}
|
|
54008
|
+
try {
|
|
54009
|
+
babelAST = BabelParser.parse(sourceCode.text, {
|
|
54010
|
+
sourceFilename: filename,
|
|
54011
|
+
sourceType: 'unambiguous',
|
|
54012
|
+
plugins: ['typescript', 'jsx'],
|
|
54013
|
+
});
|
|
54006
54014
|
}
|
|
54007
|
-
|
|
54008
|
-
try {
|
|
54009
|
-
babelAST = HermesParser.parse(sourceCode.text, {
|
|
54010
|
-
babel: true,
|
|
54011
|
-
enableExperimentalComponentSyntax: true,
|
|
54012
|
-
sourceFilename: filename,
|
|
54013
|
-
sourceType: 'module',
|
|
54014
|
-
});
|
|
54015
|
-
}
|
|
54016
|
-
catch (_d) {
|
|
54017
|
-
}
|
|
54015
|
+
catch (err) {
|
|
54018
54016
|
}
|
|
54019
54017
|
if (babelAST != null) {
|
|
54020
54018
|
results.flowSuppressions = getFlowSuppressions(sourceCode);
|
|
@@ -54023,29 +54021,11 @@ function runReactCompilerImpl({ sourceCode, filename, userOpts, }) {
|
|
|
54023
54021
|
filename,
|
|
54024
54022
|
highlightCode: false,
|
|
54025
54023
|
retainLines: true,
|
|
54026
|
-
plugins: [
|
|
54027
|
-
[PluginProposalPrivateMethods.default, { loose: true }],
|
|
54028
|
-
[BabelPluginReactCompiler, options],
|
|
54029
|
-
],
|
|
54024
|
+
plugins: [[BabelPluginReactCompiler, options]],
|
|
54030
54025
|
sourceType: 'module',
|
|
54031
54026
|
configFile: false,
|
|
54032
54027
|
babelrc: false,
|
|
54033
54028
|
});
|
|
54034
|
-
if (results.events.filter(e => e.kind === 'CompileError').length === 0) {
|
|
54035
|
-
core$1.traverse(babelAST, {
|
|
54036
|
-
FunctionDeclaration(path) {
|
|
54037
|
-
results.unusedOptOutDirectives.push(...filterUnusedOptOutDirectives(path.node.body.directives));
|
|
54038
|
-
},
|
|
54039
|
-
ArrowFunctionExpression(path) {
|
|
54040
|
-
if (path.node.body.type === 'BlockStatement') {
|
|
54041
|
-
results.unusedOptOutDirectives.push(...filterUnusedOptOutDirectives(path.node.body.directives));
|
|
54042
|
-
}
|
|
54043
|
-
},
|
|
54044
|
-
FunctionExpression(path) {
|
|
54045
|
-
results.unusedOptOutDirectives.push(...filterUnusedOptOutDirectives(path.node.body.directives));
|
|
54046
|
-
},
|
|
54047
|
-
});
|
|
54048
|
-
}
|
|
54049
54029
|
}
|
|
54050
54030
|
catch (err) {
|
|
54051
54031
|
}
|
|
@@ -54215,53 +54195,31 @@ function makeRule(rule) {
|
|
|
54215
54195
|
create,
|
|
54216
54196
|
};
|
|
54217
54197
|
}
|
|
54218
|
-
const NoUnusedDirectivesRule = {
|
|
54219
|
-
meta: {
|
|
54220
|
-
type: 'suggestion',
|
|
54221
|
-
docs: {
|
|
54222
|
-
recommended: true,
|
|
54223
|
-
},
|
|
54224
|
-
fixable: 'code',
|
|
54225
|
-
hasSuggestions: true,
|
|
54226
|
-
schema: [{ type: 'object', additionalProperties: true }],
|
|
54227
|
-
},
|
|
54228
|
-
create(context) {
|
|
54229
|
-
const results = getReactCompilerResult(context);
|
|
54230
|
-
for (const directive of results.unusedOptOutDirectives) {
|
|
54231
|
-
context.report({
|
|
54232
|
-
message: `Unused '${directive.directive}' directive`,
|
|
54233
|
-
loc: directive.loc,
|
|
54234
|
-
suggest: [
|
|
54235
|
-
{
|
|
54236
|
-
desc: 'Remove the directive',
|
|
54237
|
-
fix(fixer) {
|
|
54238
|
-
return fixer.removeRange(directive.range);
|
|
54239
|
-
},
|
|
54240
|
-
},
|
|
54241
|
-
],
|
|
54242
|
-
});
|
|
54243
|
-
}
|
|
54244
|
-
return {};
|
|
54245
|
-
},
|
|
54246
|
-
};
|
|
54247
54198
|
const allRules = LintRules.reduce((acc, rule) => {
|
|
54248
54199
|
acc[rule.name] = { rule: makeRule(rule), severity: rule.severity };
|
|
54249
54200
|
return acc;
|
|
54250
|
-
}, {
|
|
54251
|
-
|
|
54252
|
-
rule: NoUnusedDirectivesRule,
|
|
54253
|
-
severity: ErrorSeverity.Error,
|
|
54254
|
-
},
|
|
54255
|
-
});
|
|
54256
|
-
LintRules.filter(rule => rule.recommended).reduce((acc, rule) => {
|
|
54201
|
+
}, {});
|
|
54202
|
+
const recommendedRules = LintRules.filter(rule => rule.recommended).reduce((acc, rule) => {
|
|
54257
54203
|
acc[rule.name] = { rule: makeRule(rule), severity: rule.severity };
|
|
54258
54204
|
return acc;
|
|
54259
|
-
}, {
|
|
54260
|
-
|
|
54261
|
-
|
|
54262
|
-
|
|
54263
|
-
|
|
54264
|
-
}
|
|
54205
|
+
}, {});
|
|
54206
|
+
function mapErrorSeverityToESlint(severity) {
|
|
54207
|
+
switch (severity) {
|
|
54208
|
+
case ErrorSeverity.Error: {
|
|
54209
|
+
return 'error';
|
|
54210
|
+
}
|
|
54211
|
+
case ErrorSeverity.Warning: {
|
|
54212
|
+
return 'warn';
|
|
54213
|
+
}
|
|
54214
|
+
case ErrorSeverity.Hint:
|
|
54215
|
+
case ErrorSeverity.Off: {
|
|
54216
|
+
return 'off';
|
|
54217
|
+
}
|
|
54218
|
+
default: {
|
|
54219
|
+
assertExhaustive(severity, `Unhandled severity: ${severity}`);
|
|
54220
|
+
}
|
|
54221
|
+
}
|
|
54222
|
+
}
|
|
54265
54223
|
|
|
54266
54224
|
var assert_1;
|
|
54267
54225
|
var hasRequiredAssert;
|
|
@@ -57549,28 +57507,39 @@ function last(array) {
|
|
|
57549
57507
|
}
|
|
57550
57508
|
|
|
57551
57509
|
const rules = Object.assign({ 'exhaustive-deps': rule$1, 'rules-of-hooks': rule }, Object.fromEntries(Object.entries(allRules).map(([name, config]) => [name, config.rule])));
|
|
57552
|
-
const
|
|
57510
|
+
const basicRuleConfigs = {
|
|
57553
57511
|
'react-hooks/rules-of-hooks': 'error',
|
|
57554
57512
|
'react-hooks/exhaustive-deps': 'warn',
|
|
57555
57513
|
};
|
|
57514
|
+
const compilerRuleConfigs = Object.fromEntries(Object.entries(recommendedRules).map(([name, ruleConfig]) => {
|
|
57515
|
+
return [
|
|
57516
|
+
`react-hooks/${name}`,
|
|
57517
|
+
mapErrorSeverityToESlint(ruleConfig.severity),
|
|
57518
|
+
];
|
|
57519
|
+
}));
|
|
57520
|
+
const allRuleConfigs = Object.assign(Object.assign({}, basicRuleConfigs), compilerRuleConfigs);
|
|
57556
57521
|
const plugin = {
|
|
57557
57522
|
meta: {
|
|
57558
57523
|
name: 'eslint-plugin-react-hooks',
|
|
57559
57524
|
},
|
|
57560
|
-
configs: {},
|
|
57561
57525
|
rules,
|
|
57526
|
+
configs: {},
|
|
57562
57527
|
};
|
|
57563
57528
|
Object.assign(plugin.configs, {
|
|
57564
57529
|
'recommended-legacy': {
|
|
57565
57530
|
plugins: ['react-hooks'],
|
|
57566
|
-
rules:
|
|
57531
|
+
rules: basicRuleConfigs,
|
|
57532
|
+
},
|
|
57533
|
+
'recommended-latest-legacy': {
|
|
57534
|
+
plugins: ['react-hooks'],
|
|
57535
|
+
rules: allRuleConfigs,
|
|
57567
57536
|
},
|
|
57568
57537
|
'flat/recommended': [
|
|
57569
57538
|
{
|
|
57570
57539
|
plugins: {
|
|
57571
57540
|
'react-hooks': plugin,
|
|
57572
57541
|
},
|
|
57573
|
-
rules:
|
|
57542
|
+
rules: basicRuleConfigs,
|
|
57574
57543
|
},
|
|
57575
57544
|
],
|
|
57576
57545
|
'recommended-latest': [
|
|
@@ -57578,13 +57547,17 @@ Object.assign(plugin.configs, {
|
|
|
57578
57547
|
plugins: {
|
|
57579
57548
|
'react-hooks': plugin,
|
|
57580
57549
|
},
|
|
57581
|
-
rules:
|
|
57550
|
+
rules: allRuleConfigs,
|
|
57551
|
+
},
|
|
57552
|
+
],
|
|
57553
|
+
recommended: [
|
|
57554
|
+
{
|
|
57555
|
+
plugins: {
|
|
57556
|
+
'react-hooks': plugin,
|
|
57557
|
+
},
|
|
57558
|
+
rules: basicRuleConfigs,
|
|
57582
57559
|
},
|
|
57583
57560
|
],
|
|
57584
|
-
recommended: {
|
|
57585
|
-
plugins: ['react-hooks'],
|
|
57586
|
-
rules: ruleConfigs,
|
|
57587
|
-
},
|
|
57588
57561
|
});
|
|
57589
57562
|
|
|
57590
57563
|
module.exports = plugin;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-hooks",
|
|
3
3
|
"description": "ESLint rules for React Hooks",
|
|
4
|
-
"version": "6.1.
|
|
4
|
+
"version": "6.1.1",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/facebook/react.git",
|
|
@@ -41,24 +41,22 @@
|
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@babel/core": "^7.24.4",
|
|
43
43
|
"@babel/parser": "^7.24.4",
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"zod": "^3.22.4",
|
|
47
|
-
"zod-validation-error": "^3.0.3"
|
|
44
|
+
"zod": "^3.22.4 || ^4.0.0",
|
|
45
|
+
"zod-validation-error": "^3.0.3 || ^4.0.0"
|
|
48
46
|
},
|
|
49
47
|
"devDependencies": {
|
|
50
48
|
"@babel/eslint-parser": "^7.11.4",
|
|
51
49
|
"@babel/preset-typescript": "^7.26.0",
|
|
52
50
|
"@babel/types": "^7.19.0",
|
|
53
51
|
"@tsconfig/strictest": "^2.0.5",
|
|
54
|
-
"@typescript-eslint/parser-v2": "npm:@typescript-eslint/parser@^2.26.0",
|
|
55
|
-
"@typescript-eslint/parser-v3": "npm:@typescript-eslint/parser@^3.10.0",
|
|
56
|
-
"@typescript-eslint/parser-v4": "npm:@typescript-eslint/parser@^4.1.0",
|
|
57
|
-
"@typescript-eslint/parser-v5": "npm:@typescript-eslint/parser@^5.62.0",
|
|
58
52
|
"@types/eslint": "^8.56.12",
|
|
59
53
|
"@types/estree": "^1.0.6",
|
|
60
54
|
"@types/estree-jsx": "^1.0.5",
|
|
61
55
|
"@types/node": "^20.2.5",
|
|
56
|
+
"@typescript-eslint/parser-v2": "npm:@typescript-eslint/parser@^2.26.0",
|
|
57
|
+
"@typescript-eslint/parser-v3": "npm:@typescript-eslint/parser@^3.10.0",
|
|
58
|
+
"@typescript-eslint/parser-v4": "npm:@typescript-eslint/parser@^4.1.0",
|
|
59
|
+
"@typescript-eslint/parser-v5": "npm:@typescript-eslint/parser@^5.62.0",
|
|
62
60
|
"babel-eslint": "^10.0.3",
|
|
63
61
|
"eslint-v7": "npm:eslint@^7.7.0",
|
|
64
62
|
"eslint-v8": "npm:eslint@^8.57.1",
|
|
@@ -66,4 +64,4 @@
|
|
|
66
64
|
"jest": "^29.5.0",
|
|
67
65
|
"typescript": "^5.4.3"
|
|
68
66
|
}
|
|
69
|
-
}
|
|
67
|
+
}
|