eslint-plugin-react-x 5.18.3 → 5.18.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +78 -75
- package/package.json +10 -10
package/dist/index.js
CHANGED
|
@@ -145,7 +145,7 @@ const rules$6 = {
|
|
|
145
145
|
//#endregion
|
|
146
146
|
//#region package.json
|
|
147
147
|
var name$6 = "eslint-plugin-react-x";
|
|
148
|
-
var version = "5.18.
|
|
148
|
+
var version = "5.18.4";
|
|
149
149
|
|
|
150
150
|
//#endregion
|
|
151
151
|
//#region src/utils/create-rule.ts
|
|
@@ -531,15 +531,16 @@ const rule$1 = {
|
|
|
531
531
|
declaredDependency = analyzePropertyChain(declaredDependencyNode, null);
|
|
532
532
|
} catch (error) {
|
|
533
533
|
if (error instanceof Error && /Unsupported node type/.test(error.message)) {
|
|
534
|
-
if (declaredDependencyNode.type === "Literal")
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
534
|
+
if (declaredDependencyNode.type === "Literal") {
|
|
535
|
+
if (declaredDependencyNode.value && dependencies.has(declaredDependencyNode.value)) reportProblem({
|
|
536
|
+
node: declaredDependencyNode,
|
|
537
|
+
message: `The ${declaredDependencyNode.raw} literal is not a valid dependency because it never changes. Did you mean to include ${declaredDependencyNode.value} in the array instead?`
|
|
538
|
+
});
|
|
539
|
+
else reportProblem({
|
|
540
|
+
node: declaredDependencyNode,
|
|
541
|
+
message: `The ${declaredDependencyNode.raw} literal is not a valid dependency because it never changes. You can safely remove it.`
|
|
542
|
+
});
|
|
543
|
+
} else reportProblem({
|
|
543
544
|
node: declaredDependencyNode,
|
|
544
545
|
message: `React Hook ${getSourceCode().getText(reactiveHook)} has a complex expression in the dependency array. Extract it to a separate variable so it can be statically checked.`
|
|
545
546
|
});
|
|
@@ -813,7 +814,6 @@ const rule$1 = {
|
|
|
813
814
|
visitFunctionWithDependencies(init, declaredDependenciesNode, reactiveHook, reactiveHookName, isEffect, isAutoDepsHook);
|
|
814
815
|
return;
|
|
815
816
|
}
|
|
816
|
-
break;
|
|
817
817
|
}
|
|
818
818
|
break;
|
|
819
819
|
default:
|
|
@@ -906,9 +906,10 @@ function collectRecommendations({ dependencies, declaredDependencies, stableDepe
|
|
|
906
906
|
const unnecessaryDependencies = /* @__PURE__ */ new Set();
|
|
907
907
|
const duplicateDependencies = /* @__PURE__ */ new Set();
|
|
908
908
|
declaredDependencies.forEach(({ key }) => {
|
|
909
|
-
if (satisfyingDependencies.has(key))
|
|
910
|
-
|
|
911
|
-
|
|
909
|
+
if (satisfyingDependencies.has(key)) {
|
|
910
|
+
if (suggestedDependencies.indexOf(key) === -1) suggestedDependencies.push(key);
|
|
911
|
+
else duplicateDependencies.add(key);
|
|
912
|
+
} else if (isEffect && !key.endsWith(".current") && !externalDependencies.has(key)) {
|
|
912
913
|
if (suggestedDependencies.indexOf(key) === -1) suggestedDependencies.push(key);
|
|
913
914
|
} else unnecessaryDependencies.add(key);
|
|
914
915
|
});
|
|
@@ -967,10 +968,12 @@ function scanForConstructions({ declaredDependencies, declaredDependenciesNode,
|
|
|
967
968
|
function isUsedOutsideOfHook(ref) {
|
|
968
969
|
let foundWriteExpr = false;
|
|
969
970
|
for (const reference of ref.references) {
|
|
970
|
-
if (reference.writeExpr)
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
971
|
+
if (reference.writeExpr) {
|
|
972
|
+
if (foundWriteExpr) return true;
|
|
973
|
+
else {
|
|
974
|
+
foundWriteExpr = true;
|
|
975
|
+
continue;
|
|
976
|
+
}
|
|
974
977
|
}
|
|
975
978
|
let currentScope = reference.from;
|
|
976
979
|
while (currentScope !== scope && currentScope != null) currentScope = currentScope.upper;
|
|
@@ -1005,9 +1008,11 @@ function getDependency(node) {
|
|
|
1005
1008
|
* This particular node might still represent a required member, so check .optional field.
|
|
1006
1009
|
*/
|
|
1007
1010
|
function markNode(node, optionalChains, result) {
|
|
1008
|
-
if (optionalChains)
|
|
1009
|
-
if (
|
|
1010
|
-
|
|
1011
|
+
if (optionalChains) {
|
|
1012
|
+
if ("optional" in node && node.optional) {
|
|
1013
|
+
if (!optionalChains.has(result)) optionalChains.set(result, true);
|
|
1014
|
+
} else optionalChains.set(result, false);
|
|
1015
|
+
}
|
|
1011
1016
|
}
|
|
1012
1017
|
/**
|
|
1013
1018
|
* Assuming () means the passed node.
|
|
@@ -1916,10 +1921,12 @@ function create$40(context) {
|
|
|
1916
1921
|
if (!context.sourceCode.text.includes("Component")) return {};
|
|
1917
1922
|
const { api, visitor } = core.getClassComponentCollector(context);
|
|
1918
1923
|
return merge(visitor, { "Program:exit"(program) {
|
|
1919
|
-
for (const { name = "anonymous", node: component } of api.getAllComponents(program)) {
|
|
1924
|
+
for (const { id, name = "anonymous", node: component } of api.getAllComponents(program)) {
|
|
1920
1925
|
if (component.body.body.some((m) => core.isComponentDidCatch(m) || core.isGetDerivedStateFromError(m))) continue;
|
|
1926
|
+
const classToken = context.sourceCode.getFirstToken(component, { filter: (token) => token.value === "class" });
|
|
1921
1927
|
context.report({
|
|
1922
1928
|
data: { name },
|
|
1929
|
+
loc: (id ?? classToken ?? component).loc,
|
|
1923
1930
|
messageId: "default",
|
|
1924
1931
|
node: component
|
|
1925
1932
|
});
|
|
@@ -4084,7 +4091,9 @@ function create$11(context) {
|
|
|
4084
4091
|
for (const def of defs) {
|
|
4085
4092
|
const methodName = def.name;
|
|
4086
4093
|
if (usages?.has(methodName) ?? false) continue;
|
|
4087
|
-
if (LIFECYCLE_METHODS.has(methodName))
|
|
4094
|
+
if (LIFECYCLE_METHODS.has(methodName)) {
|
|
4095
|
+
if (methodName === "shouldComponentUpdate" && core.isPureComponent(currentClass)) {} else continue;
|
|
4096
|
+
}
|
|
4088
4097
|
context.report({
|
|
4089
4098
|
data: {
|
|
4090
4099
|
className: id != null ? context.sourceCode.getText(id) : "Component",
|
|
@@ -4155,9 +4164,7 @@ function collectUsedPropKeysOfObjectPattern(context, usedPropKeys, objectPattern
|
|
|
4155
4164
|
usedPropKeys.add(key);
|
|
4156
4165
|
break;
|
|
4157
4166
|
}
|
|
4158
|
-
case AST_NODE_TYPES.RestElement:
|
|
4159
|
-
if (!collectUsedPropsOfRestElement(context, usedPropKeys, property)) return false;
|
|
4160
|
-
break;
|
|
4167
|
+
case AST_NODE_TYPES.RestElement: if (!collectUsedPropsOfRestElement(context, usedPropKeys, property)) return false;
|
|
4161
4168
|
}
|
|
4162
4169
|
return true;
|
|
4163
4170
|
}
|
|
@@ -4189,18 +4196,14 @@ function collectUsedPropKeysOfReference(context, usedPropKeys, ref) {
|
|
|
4189
4196
|
return true;
|
|
4190
4197
|
}
|
|
4191
4198
|
break;
|
|
4192
|
-
case AST_NODE_TYPES.VariableDeclarator:
|
|
4193
|
-
if (parent.id.type === AST_NODE_TYPES.ObjectPattern && parent.init === valueNode) return collectUsedPropKeysOfObjectPattern(context, usedPropKeys, parent.id);
|
|
4194
|
-
break;
|
|
4199
|
+
case AST_NODE_TYPES.VariableDeclarator: if (parent.id.type === AST_NODE_TYPES.ObjectPattern && parent.init === valueNode) return collectUsedPropKeysOfObjectPattern(context, usedPropKeys, parent.id);
|
|
4195
4200
|
}
|
|
4196
4201
|
return false;
|
|
4197
4202
|
}
|
|
4198
4203
|
function getKeyOfExpression(expr) {
|
|
4199
4204
|
switch (expr.type) {
|
|
4200
4205
|
case AST_NODE_TYPES.Identifier: return expr.name;
|
|
4201
|
-
case AST_NODE_TYPES.Literal:
|
|
4202
|
-
if (typeof expr.value === "string") return expr.value;
|
|
4203
|
-
break;
|
|
4206
|
+
case AST_NODE_TYPES.Literal: if (typeof expr.value === "string") return expr.value;
|
|
4204
4207
|
}
|
|
4205
4208
|
return null;
|
|
4206
4209
|
}
|
|
@@ -4287,7 +4290,8 @@ function create$9(context) {
|
|
|
4287
4290
|
},
|
|
4288
4291
|
"Program:exit"() {
|
|
4289
4292
|
for (const { name, node } of stateEntries) {
|
|
4290
|
-
const
|
|
4293
|
+
const scope = context.sourceCode.getScope(node);
|
|
4294
|
+
const variable = findVariable(scope, name);
|
|
4291
4295
|
if (variable == null) continue;
|
|
4292
4296
|
let hasRead = false;
|
|
4293
4297
|
for (const ref of variable.references) {
|
|
@@ -4643,7 +4647,8 @@ const IMPURE_CTORS = /* @__PURE__ */ new Set([
|
|
|
4643
4647
|
function resolveBuiltinObjectName(context, node, seen = /* @__PURE__ */ new Set()) {
|
|
4644
4648
|
if (seen.has(node.name)) return null;
|
|
4645
4649
|
seen.add(node.name);
|
|
4646
|
-
const
|
|
4650
|
+
const scope = context.sourceCode.getScope(node);
|
|
4651
|
+
const variable = findVariable(scope, node);
|
|
4647
4652
|
if (variable == null) return node.name;
|
|
4648
4653
|
const def = variable.defs[0];
|
|
4649
4654
|
if (def == null) return node.name;
|
|
@@ -5860,10 +5865,12 @@ var CodePathState = class {
|
|
|
5860
5865
|
this.forkBypassPath();
|
|
5861
5866
|
const lastCaseSegments = forkContext.head;
|
|
5862
5867
|
brokenForkContext.add(lastSegments);
|
|
5863
|
-
if (!context.lastIsDefault)
|
|
5864
|
-
|
|
5865
|
-
|
|
5866
|
-
|
|
5868
|
+
if (!context.lastIsDefault) {
|
|
5869
|
+
if (context.defaultBodySegments) {
|
|
5870
|
+
removeConnection(context.defaultSegments, context.defaultBodySegments);
|
|
5871
|
+
makeLooped(this, lastCaseSegments, context.defaultBodySegments);
|
|
5872
|
+
} else brokenForkContext.add(lastCaseSegments);
|
|
5873
|
+
}
|
|
5867
5874
|
for (let i = 0; i < context.countForks; ++i) this.forkContext = this.forkContext.upper;
|
|
5868
5875
|
this.forkContext.replaceHead(brokenForkContext.makeNext(0, -1));
|
|
5869
5876
|
}
|
|
@@ -6265,10 +6272,12 @@ var CodePathState = class {
|
|
|
6265
6272
|
const forkContext = this.forkContext;
|
|
6266
6273
|
if (!forkContext.reachable) return;
|
|
6267
6274
|
const context = getContinueContext(this, label);
|
|
6268
|
-
if (context)
|
|
6269
|
-
|
|
6270
|
-
|
|
6271
|
-
|
|
6275
|
+
if (context) {
|
|
6276
|
+
if (context.continueDestSegments != null) {
|
|
6277
|
+
makeLooped(this, forkContext.head, context.continueDestSegments);
|
|
6278
|
+
if (context.type === "ForInStatement" || context.type === "ForOfStatement") context.brokenForkContext.add(forkContext.head);
|
|
6279
|
+
} else context.continueForkContext.add(forkContext.head);
|
|
6280
|
+
}
|
|
6272
6281
|
forkContext.replaceHead(forkContext.makeUnreachable(-1, -1));
|
|
6273
6282
|
}
|
|
6274
6283
|
/**
|
|
@@ -6663,14 +6672,11 @@ function preprocess(analyzer, node) {
|
|
|
6663
6672
|
state.makeForInOfBody();
|
|
6664
6673
|
}
|
|
6665
6674
|
break;
|
|
6666
|
-
case "AssignmentPattern":
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
|
|
6670
|
-
|
|
6671
|
-
}
|
|
6672
|
-
break;
|
|
6673
|
-
default: break;
|
|
6675
|
+
case "AssignmentPattern": if (parent.right === node) {
|
|
6676
|
+
state.pushForkContext();
|
|
6677
|
+
state.forkBypassPath();
|
|
6678
|
+
state.forkPath();
|
|
6679
|
+
}
|
|
6674
6680
|
}
|
|
6675
6681
|
}
|
|
6676
6682
|
/**
|
|
@@ -6745,10 +6751,7 @@ function processCodePathToEnter(analyzer, node) {
|
|
|
6745
6751
|
case "ForOfStatement":
|
|
6746
6752
|
state.pushLoopContext(node.type, getLabel(node));
|
|
6747
6753
|
break;
|
|
6748
|
-
case "LabeledStatement":
|
|
6749
|
-
if (!breakableTypePattern.test(node.body.type)) state.pushBreakContext(false, node.label.name);
|
|
6750
|
-
break;
|
|
6751
|
-
default: break;
|
|
6754
|
+
case "LabeledStatement": if (!breakableTypePattern.test(node.body.type)) state.pushBreakContext(false, node.label.name);
|
|
6752
6755
|
}
|
|
6753
6756
|
forwardCurrentToHead(analyzer, node);
|
|
6754
6757
|
}
|
|
@@ -6826,10 +6829,7 @@ function processCodePathToExit(analyzer, node) {
|
|
|
6826
6829
|
case "AssignmentPattern":
|
|
6827
6830
|
state.popForkContext();
|
|
6828
6831
|
break;
|
|
6829
|
-
case "LabeledStatement":
|
|
6830
|
-
if (!breakableTypePattern.test(node.body.type)) state.popBreakContext();
|
|
6831
|
-
break;
|
|
6832
|
-
default: break;
|
|
6832
|
+
case "LabeledStatement": if (!breakableTypePattern.test(node.body.type)) state.popBreakContext();
|
|
6833
6833
|
}
|
|
6834
6834
|
if (!dontForward) forwardCurrentToHead(analyzer, node);
|
|
6835
6835
|
}
|
|
@@ -6854,10 +6854,7 @@ function postprocess(analyzer, node) {
|
|
|
6854
6854
|
case "StaticBlock":
|
|
6855
6855
|
endCodePath();
|
|
6856
6856
|
break;
|
|
6857
|
-
case "CallExpression":
|
|
6858
|
-
if (node.optional === true && node.arguments.length === 0) CodePath.getState(analyzer.codePath).makeOptionalRight();
|
|
6859
|
-
break;
|
|
6860
|
-
default: break;
|
|
6857
|
+
case "CallExpression": if (node.optional === true && node.arguments.length === 0) CodePath.getState(analyzer.codePath).makeOptionalRight();
|
|
6861
6858
|
}
|
|
6862
6859
|
if (isPropertyDefinitionValue(node)) endCodePath();
|
|
6863
6860
|
}
|
|
@@ -7317,12 +7314,13 @@ const rule = {
|
|
|
7317
7314
|
*/
|
|
7318
7315
|
function getFunctionName(node) {
|
|
7319
7316
|
if (node.type === "ComponentDeclaration" || node.type === "HookDeclaration" || node.type === "FunctionDeclaration" || node.type === "FunctionExpression" && node.id) return node.id;
|
|
7320
|
-
else if (node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression")
|
|
7321
|
-
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
|
|
7317
|
+
else if (node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression") {
|
|
7318
|
+
if (node.parent?.type === "VariableDeclarator" && node.parent.init === node) return node.parent.id;
|
|
7319
|
+
else if (node.parent?.type === "AssignmentExpression" && node.parent.right === node && node.parent.operator === "=") return node.parent.left;
|
|
7320
|
+
else if (node.parent?.type === "Property" && node.parent.value === node && !node.parent.computed) return node.parent.key;
|
|
7321
|
+
else if (node.parent?.type === "AssignmentPattern" && node.parent.right === node && !node.parent.computed) return node.parent.left;
|
|
7322
|
+
else return;
|
|
7323
|
+
} else return;
|
|
7326
7324
|
}
|
|
7327
7325
|
/**
|
|
7328
7326
|
* Convenience function for peeking the last item in a stack.
|
|
@@ -7554,13 +7552,15 @@ function create$5(context) {
|
|
|
7554
7552
|
const isAt = Extract.getCalleeName(callee) === "at";
|
|
7555
7553
|
const [index] = callee.arguments;
|
|
7556
7554
|
if (!isAt || index == null) return false;
|
|
7557
|
-
|
|
7555
|
+
const indexScope = context.sourceCode.getScope(node);
|
|
7556
|
+
return getStaticValue(index, indexScope)?.value === 1 && isIdFromUseStateCall(innerCallee.object);
|
|
7558
7557
|
}
|
|
7559
7558
|
case AST_NODE_TYPES.Identifier: return isIdFromUseStateCall(callee, 1);
|
|
7560
7559
|
case AST_NODE_TYPES.MemberExpression: {
|
|
7561
7560
|
if (!("name" in callee.object)) return false;
|
|
7562
7561
|
const property = callee.property;
|
|
7563
|
-
|
|
7562
|
+
const propertyScope = context.sourceCode.getScope(node);
|
|
7563
|
+
return getStaticValue(property, propertyScope)?.value === 1 && isIdFromUseStateCall(callee.object, 1);
|
|
7564
7564
|
}
|
|
7565
7565
|
default: return false;
|
|
7566
7566
|
}
|
|
@@ -7713,7 +7713,6 @@ function isInsideConditional(node, stopAt) {
|
|
|
7713
7713
|
case AST_NODE_TYPES.LogicalExpression:
|
|
7714
7714
|
case AST_NODE_TYPES.SwitchStatement:
|
|
7715
7715
|
case AST_NODE_TYPES.SwitchCase: return true;
|
|
7716
|
-
default: break;
|
|
7717
7716
|
}
|
|
7718
7717
|
current = current.parent;
|
|
7719
7718
|
}
|
|
@@ -7776,13 +7775,15 @@ function create$4(context) {
|
|
|
7776
7775
|
const isAt = Extract.getCalleeName(callee) === "at";
|
|
7777
7776
|
const [index] = callee.arguments;
|
|
7778
7777
|
if (!isAt || index == null) return false;
|
|
7779
|
-
|
|
7778
|
+
const indexScope = context.sourceCode.getScope(node);
|
|
7779
|
+
return getStaticValue(index, indexScope)?.value === 1 && isIdFromUseStateCall(innerCallee.object);
|
|
7780
7780
|
}
|
|
7781
7781
|
case AST_NODE_TYPES.Identifier: return isIdFromUseStateCall(callee, 1);
|
|
7782
7782
|
case AST_NODE_TYPES.MemberExpression: {
|
|
7783
7783
|
if (!("name" in callee.object)) return false;
|
|
7784
7784
|
const property = callee.property;
|
|
7785
|
-
|
|
7785
|
+
const propertyScope = context.sourceCode.getScope(node);
|
|
7786
|
+
return getStaticValue(property, propertyScope)?.value === 1 && isIdFromUseStateCall(callee.object, 1);
|
|
7786
7787
|
}
|
|
7787
7788
|
default: return false;
|
|
7788
7789
|
}
|
|
@@ -7857,7 +7858,8 @@ const DYNAMIC_EXPRESSION_TYPES = /* @__PURE__ */ new Set([
|
|
|
7857
7858
|
AST_NODE_TYPES.NewExpression
|
|
7858
7859
|
]);
|
|
7859
7860
|
function findVariableForIdentifier(context, identifier) {
|
|
7860
|
-
|
|
7861
|
+
const scope = context.sourceCode.getScope(identifier);
|
|
7862
|
+
return findVariable(scope, identifier.name);
|
|
7861
7863
|
}
|
|
7862
7864
|
/**
|
|
7863
7865
|
* Resolves an expression down to the node that dynamically created its value, if any.
|
|
@@ -8121,7 +8123,8 @@ function create$1(context) {
|
|
|
8121
8123
|
const left = Extract.unwrap(node.left);
|
|
8122
8124
|
if (left.type !== AST_NODE_TYPES.Identifier) return;
|
|
8123
8125
|
if (Traverse.findParent(node, Check.isFunction, (n) => n === callback) != null) return;
|
|
8124
|
-
const
|
|
8126
|
+
const scope = context.sourceCode.getScope(left);
|
|
8127
|
+
const variable = findVariable(scope, left);
|
|
8125
8128
|
if (variable != null && variable.defs.length > 0 && isDeclaredInsideCallback(variable, callback)) return;
|
|
8126
8129
|
violations.push({
|
|
8127
8130
|
messageId: "noReassigningOuterVariables",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-x",
|
|
3
|
-
"version": "5.18.
|
|
3
|
+
"version": "5.18.4",
|
|
4
4
|
"description": "A set of composable ESLint rules for libraries and frameworks that use React as a UI runtime.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -45,26 +45,26 @@
|
|
|
45
45
|
"string-ts": "^2.3.1",
|
|
46
46
|
"ts-api-utils": "^2.5.0",
|
|
47
47
|
"ts-pattern": "^5.9.0",
|
|
48
|
-
"@eslint-react/ast": "5.18.
|
|
49
|
-
"@eslint-react/core": "5.18.
|
|
50
|
-
"@eslint-react/eslint": "5.18.
|
|
51
|
-
"@eslint-react/
|
|
52
|
-
"@eslint-react/var": "5.18.
|
|
53
|
-
"@eslint-react/
|
|
48
|
+
"@eslint-react/ast": "5.18.4",
|
|
49
|
+
"@eslint-react/core": "5.18.4",
|
|
50
|
+
"@eslint-react/eslint": "5.18.4",
|
|
51
|
+
"@eslint-react/jsx": "5.18.4",
|
|
52
|
+
"@eslint-react/var": "5.18.4",
|
|
53
|
+
"@eslint-react/shared": "5.18.4"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@types/react": "^19.2.18",
|
|
57
57
|
"@types/react-dom": "^19.2.4",
|
|
58
58
|
"dedent": "^1.7.2",
|
|
59
|
-
"eslint": "^10.8.
|
|
59
|
+
"eslint": "^10.8.1",
|
|
60
60
|
"react": "^19.2.8",
|
|
61
61
|
"react-dom": "^19.2.8",
|
|
62
62
|
"tsdown": "^0.22.14",
|
|
63
63
|
"tsl": "^1.0.30",
|
|
64
64
|
"tsl-dx": "^0.13.3",
|
|
65
65
|
"typescript": "6.0.3",
|
|
66
|
-
"@local/
|
|
67
|
-
"@local/
|
|
66
|
+
"@local/configs": "0.0.0",
|
|
67
|
+
"@local/eff": "0.0.0"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
70
70
|
"eslint": "*",
|