eslint-plugin-react-x 5.14.2 → 5.14.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.js +181 -170
- package/package.json +10 -10
package/dist/index.js
CHANGED
|
@@ -144,7 +144,7 @@ const rules$6 = {
|
|
|
144
144
|
//#endregion
|
|
145
145
|
//#region package.json
|
|
146
146
|
var name$6 = "eslint-plugin-react-x";
|
|
147
|
-
var version = "5.14.
|
|
147
|
+
var version = "5.14.6";
|
|
148
148
|
|
|
149
149
|
//#endregion
|
|
150
150
|
//#region src/utils/create-rule.ts
|
|
@@ -1344,81 +1344,176 @@ const MUTATING_METHODS = /* @__PURE__ */ new Set([
|
|
|
1344
1344
|
"splice",
|
|
1345
1345
|
"unshift"
|
|
1346
1346
|
]);
|
|
1347
|
-
|
|
1348
|
-
* Check if `inner` is fully contained within `outer`'s source range.
|
|
1349
|
-
* @param inner The node that may be contained.
|
|
1350
|
-
* @param outer The node that may contain it.
|
|
1351
|
-
*/
|
|
1352
|
-
function isNodeWithin(inner, outer) {
|
|
1353
|
-
return inner.range[0] >= outer.range[0] && inner.range[1] <= outer.range[1];
|
|
1354
|
-
}
|
|
1355
|
-
/**
|
|
1356
|
-
* Resolve an expression to the function it ultimately refers to, following
|
|
1357
|
-
* simple local aliasing (`const fn2 = fn;`) via scope resolution.
|
|
1358
|
-
* @param context The ESLint rule context.
|
|
1359
|
-
* @param node The expression to resolve.
|
|
1360
|
-
* @param seen Identifiers already visited, to guard against cycles.
|
|
1361
|
-
*/
|
|
1347
|
+
const isUseRouterCall = core.isAPICall("useRouter");
|
|
1362
1348
|
function resolveToFunctionNode(context, node, seen = /* @__PURE__ */ new Set()) {
|
|
1363
1349
|
const expr = Extract.unwrap(node);
|
|
1364
1350
|
if (Check.isFunction(expr)) return expr;
|
|
1365
|
-
if (expr.type !== AST_NODE_TYPES.Identifier) return null;
|
|
1366
|
-
if (seen.has(expr)) return null;
|
|
1351
|
+
if (expr.type !== AST_NODE_TYPES.Identifier || seen.has(expr)) return null;
|
|
1367
1352
|
seen.add(expr);
|
|
1368
1353
|
const resolved = resolve(context, expr);
|
|
1369
|
-
|
|
1370
|
-
|
|
1354
|
+
return resolved == null ? null : resolveToFunctionNode(context, resolved, seen);
|
|
1355
|
+
}
|
|
1356
|
+
function resolveVariableOrigin(context, variable, seen = /* @__PURE__ */ new Set()) {
|
|
1357
|
+
if (seen.has(variable)) return variable;
|
|
1358
|
+
seen.add(variable);
|
|
1359
|
+
const def = variable.defs.length === 1 ? variable.defs[0] : null;
|
|
1360
|
+
if (def?.type !== DefinitionType.Variable || def.node.init == null) return variable;
|
|
1361
|
+
const init = Extract.unwrap(def.node.init);
|
|
1362
|
+
if (init.type !== AST_NODE_TYPES.Identifier) return variable;
|
|
1363
|
+
const source = findVariable(context.sourceCode.getScope(init), init);
|
|
1364
|
+
return source == null ? variable : resolveVariableOrigin(context, source, seen);
|
|
1371
1365
|
}
|
|
1372
|
-
/**
|
|
1373
|
-
* Check if a name is ref-like ("ref" or ends with "Ref").
|
|
1374
|
-
* Refs are mutable by design and exempted from immutability checks.
|
|
1375
|
-
* @param name The identifier name to check.
|
|
1376
|
-
*/
|
|
1377
1366
|
function isRefLikeName$1(name) {
|
|
1378
1367
|
return name === "ref" || name.endsWith("Ref");
|
|
1379
1368
|
}
|
|
1380
|
-
/**
|
|
1381
|
-
* Check if any identifier or property name in a member-expression chain
|
|
1382
|
-
* is ref-like.
|
|
1383
|
-
* @param node The AST node to inspect.
|
|
1384
|
-
*/
|
|
1385
1369
|
function hasRefLikeNameInChain(node) {
|
|
1386
1370
|
if (node.type === AST_NODE_TYPES.Identifier) return isRefLikeName$1(node.name);
|
|
1387
|
-
if (node.type
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1371
|
+
if (node.type !== AST_NODE_TYPES.MemberExpression) return false;
|
|
1372
|
+
const propertyName = Extract.getPropertyName(node.property);
|
|
1373
|
+
return propertyName != null ? isRefLikeName$1(propertyName) || hasRefLikeNameInChain(node.object) : hasRefLikeNameInChain(node.object);
|
|
1374
|
+
}
|
|
1375
|
+
function isInitializedFromCall(context, node, isCall) {
|
|
1376
|
+
const root = node.type === AST_NODE_TYPES.Identifier ? node : Extract.getRootIdentifier(node);
|
|
1377
|
+
if (root == null) return false;
|
|
1378
|
+
const variable = findVariable(context.sourceCode.getScope(root), root);
|
|
1379
|
+
if (variable == null) return false;
|
|
1380
|
+
const origin = resolveVariableOrigin(context, variable);
|
|
1381
|
+
const def = origin.defs.length === 1 ? origin.defs[0] : null;
|
|
1382
|
+
if (def?.type !== DefinitionType.Variable || def.node.init == null) return false;
|
|
1383
|
+
const init = Extract.unwrap(def.node.init);
|
|
1384
|
+
return init.type === AST_NODE_TYPES.CallExpression && isCall(init);
|
|
1393
1385
|
}
|
|
1394
|
-
/**
|
|
1395
|
-
* Check if the root identifier of a member-expression chain (or the
|
|
1396
|
-
* identifier itself) is initialized directly from a `useRef()` call, e.g.
|
|
1397
|
-
* `const mounted = useRef(false); mounted.current = true;`.
|
|
1398
|
-
*
|
|
1399
|
-
* This catches refs regardless of naming convention, complementing
|
|
1400
|
-
* {@link hasRefLikeNameInChain}.
|
|
1401
|
-
* @param context The ESLint rule context.
|
|
1402
|
-
* @param node The AST node to inspect (an identifier or member-expression chain).
|
|
1403
|
-
*/
|
|
1404
1386
|
function isInitializedFromUseRef(context, node) {
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
return
|
|
1387
|
+
return isInitializedFromCall(context, node, (init) => core.isUseRefCall(context, init));
|
|
1388
|
+
}
|
|
1389
|
+
function isInitializedFromUseRouter(context, node) {
|
|
1390
|
+
return isInitializedFromCall(context, node, (init) => isUseRouterCall(context, init));
|
|
1391
|
+
}
|
|
1392
|
+
function isKnownNonMutatingMethodCall(context, node) {
|
|
1393
|
+
const callee = Extract.unwrap(node.callee);
|
|
1394
|
+
return Check.isExpression(callee) && isInitializedFromUseRouter(context, callee);
|
|
1409
1395
|
}
|
|
1410
|
-
/**
|
|
1411
|
-
* Check if a mutated expression chain should be exempt from immutability
|
|
1412
|
-
* checks because it is rooted at a ref: either by naming convention
|
|
1413
|
-
* ({@link hasRefLikeNameInChain}) or because it is initialized from a
|
|
1414
|
-
* `useRef()` call ({@link isInitializedFromUseRef}).
|
|
1415
|
-
* @param context The ESLint rule context.
|
|
1416
|
-
* @param node The AST node to inspect (an identifier or member-expression chain).
|
|
1417
|
-
*/
|
|
1418
1396
|
function isRefLikeChain(context, node) {
|
|
1419
1397
|
return hasRefLikeNameInChain(node) || isInitializedFromUseRef(context, node);
|
|
1420
1398
|
}
|
|
1421
1399
|
|
|
1400
|
+
//#endregion
|
|
1401
|
+
//#region src/rules/immutability/collect.ts
|
|
1402
|
+
function createImmutabilityCollector() {
|
|
1403
|
+
const facts = {
|
|
1404
|
+
mutations: [],
|
|
1405
|
+
sinks: []
|
|
1406
|
+
};
|
|
1407
|
+
function pushMutation(kind, node, target, root) {
|
|
1408
|
+
const enclosingFunction = Traverse.findParent(node, Check.isFunction);
|
|
1409
|
+
if (enclosingFunction == null) return;
|
|
1410
|
+
facts.mutations.push({
|
|
1411
|
+
kind,
|
|
1412
|
+
enclosingFunction,
|
|
1413
|
+
node,
|
|
1414
|
+
root,
|
|
1415
|
+
target
|
|
1416
|
+
});
|
|
1417
|
+
}
|
|
1418
|
+
return {
|
|
1419
|
+
facts,
|
|
1420
|
+
visitor: {
|
|
1421
|
+
AssignmentExpression(node) {
|
|
1422
|
+
const target = Extract.unwrap(node.left);
|
|
1423
|
+
switch (target.type) {
|
|
1424
|
+
case AST_NODE_TYPES.Identifier:
|
|
1425
|
+
pushMutation("binding", node, target, target);
|
|
1426
|
+
return;
|
|
1427
|
+
case AST_NODE_TYPES.MemberExpression: {
|
|
1428
|
+
const root = Extract.getRootIdentifier(target);
|
|
1429
|
+
if (root != null) pushMutation("value", node, target, root);
|
|
1430
|
+
return;
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
},
|
|
1434
|
+
CallExpression(node) {
|
|
1435
|
+
const callee = Extract.unwrap(node.callee);
|
|
1436
|
+
if (callee.type === AST_NODE_TYPES.MemberExpression) {
|
|
1437
|
+
const property = Extract.getPropertyName(callee.property);
|
|
1438
|
+
if (property != null && MUTATING_METHODS.has(property)) {
|
|
1439
|
+
const root = Extract.getRootIdentifier(callee.object);
|
|
1440
|
+
if (root != null) pushMutation("value", node, callee.object, root);
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
if (!core.isHookCall(node)) return;
|
|
1444
|
+
for (const argument of node.arguments) {
|
|
1445
|
+
if (argument.type === AST_NODE_TYPES.SpreadElement) continue;
|
|
1446
|
+
facts.sinks.push({
|
|
1447
|
+
kind: "hook-argument",
|
|
1448
|
+
expression: argument
|
|
1449
|
+
});
|
|
1450
|
+
}
|
|
1451
|
+
},
|
|
1452
|
+
JSXAttribute(node) {
|
|
1453
|
+
if (node.value?.type !== AST_NODE_TYPES.JSXExpressionContainer) return;
|
|
1454
|
+
const expression = node.value.expression;
|
|
1455
|
+
if (expression.type === AST_NODE_TYPES.JSXEmptyExpression) return;
|
|
1456
|
+
facts.sinks.push({
|
|
1457
|
+
kind: "jsx-prop",
|
|
1458
|
+
expression
|
|
1459
|
+
});
|
|
1460
|
+
},
|
|
1461
|
+
UnaryExpression(node) {
|
|
1462
|
+
if (node.operator !== "delete") return;
|
|
1463
|
+
const target = Extract.unwrap(node.argument);
|
|
1464
|
+
if (target.type !== AST_NODE_TYPES.MemberExpression) return;
|
|
1465
|
+
const root = Extract.getRootIdentifier(target);
|
|
1466
|
+
if (root != null) pushMutation("value", node, target, root);
|
|
1467
|
+
},
|
|
1468
|
+
UpdateExpression(node) {
|
|
1469
|
+
const target = Extract.unwrap(node.argument);
|
|
1470
|
+
switch (target.type) {
|
|
1471
|
+
case AST_NODE_TYPES.Identifier:
|
|
1472
|
+
pushMutation("binding", node, target, target);
|
|
1473
|
+
return;
|
|
1474
|
+
case AST_NODE_TYPES.MemberExpression: {
|
|
1475
|
+
const root = Extract.getRootIdentifier(target);
|
|
1476
|
+
if (root != null) pushMutation("value", node, target, root);
|
|
1477
|
+
return;
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
};
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1485
|
+
//#endregion
|
|
1486
|
+
//#region src/rules/immutability/effects.ts
|
|
1487
|
+
function isGlobalOrModuleVariable(variable) {
|
|
1488
|
+
return variable.defs.length === 0 || variable.scope.type === ScopeType.global || variable.scope.type === ScopeType.module;
|
|
1489
|
+
}
|
|
1490
|
+
function isRefMutation(context, mutation) {
|
|
1491
|
+
if (mutation.target.type === AST_NODE_TYPES.Identifier) return isRefLikeName$1(mutation.target.name);
|
|
1492
|
+
return isRefLikeChain(context, mutation.target);
|
|
1493
|
+
}
|
|
1494
|
+
function inferMutableFunctions(context, mutations) {
|
|
1495
|
+
const mutableFunctions = /* @__PURE__ */ new Map();
|
|
1496
|
+
for (const mutation of mutations) {
|
|
1497
|
+
if (mutation.node.type === AST_NODE_TYPES.CallExpression && isKnownNonMutatingMethodCall(context, mutation.node)) continue;
|
|
1498
|
+
if (isRefMutation(context, mutation)) continue;
|
|
1499
|
+
const variable = findVariable(context.sourceCode.getScope(mutation.root), mutation.root);
|
|
1500
|
+
if (variable == null) continue;
|
|
1501
|
+
const origin = mutation.kind === "binding" ? variable : resolveVariableOrigin(context, variable);
|
|
1502
|
+
if (isGlobalOrModuleVariable(origin)) continue;
|
|
1503
|
+
const declaration = origin.identifiers.at(0) ?? null;
|
|
1504
|
+
let current = mutation.enclosingFunction;
|
|
1505
|
+
while (current != null) {
|
|
1506
|
+
if (declaration != null && Traverse.findParent(declaration, Check.isFunction) === current) break;
|
|
1507
|
+
if (!mutableFunctions.has(current)) mutableFunctions.set(current, {
|
|
1508
|
+
name: origin.name,
|
|
1509
|
+
node: mutation.node
|
|
1510
|
+
});
|
|
1511
|
+
current = Traverse.findParent(current, Check.isFunction);
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
return mutableFunctions;
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1422
1517
|
//#endregion
|
|
1423
1518
|
//#region src/rules/immutability/immutability.ts
|
|
1424
1519
|
const RULE_NAME$48 = "immutability";
|
|
@@ -1437,120 +1532,36 @@ var immutability_default = createRule({
|
|
|
1437
1532
|
defaultOptions: []
|
|
1438
1533
|
});
|
|
1439
1534
|
function create$48(context) {
|
|
1440
|
-
const
|
|
1441
|
-
const
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
mutationSites.push({
|
|
1447
|
-
enclosing,
|
|
1448
|
-
node,
|
|
1449
|
-
root
|
|
1535
|
+
const hooks = core.getHookCollector(context);
|
|
1536
|
+
const collector = createImmutabilityCollector();
|
|
1537
|
+
return merge(hooks.visitor, collector.visitor, { "Program:exit"(program) {
|
|
1538
|
+
for (const hook of hooks.api.getAllHooks(program)) for (const expression of hook.rets) if (expression != null) collector.facts.sinks.push({
|
|
1539
|
+
kind: "hook-return",
|
|
1540
|
+
expression
|
|
1450
1541
|
});
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
const propName = Extract.getPropertyName(callee.property);
|
|
1473
|
-
if (propName != null && MUTATING_METHODS.has(propName) && !isRefLikeChain(context, callee.object)) {
|
|
1474
|
-
const rootId = Extract.getRootIdentifier(callee.object);
|
|
1475
|
-
if (rootId != null) pushMutationSite(node, rootId);
|
|
1476
|
-
}
|
|
1477
|
-
}
|
|
1478
|
-
if (core.isHookCall(node)) for (const arg of node.arguments) {
|
|
1479
|
-
if (arg.type === AST_NODE_TYPES.SpreadElement) continue;
|
|
1480
|
-
sinkCandidates.push(arg);
|
|
1481
|
-
}
|
|
1482
|
-
},
|
|
1483
|
-
JSXAttribute(node) {
|
|
1484
|
-
if (node.value?.type !== AST_NODE_TYPES.JSXExpressionContainer) return;
|
|
1485
|
-
const expr = node.value.expression;
|
|
1486
|
-
if (expr.type === AST_NODE_TYPES.JSXEmptyExpression) return;
|
|
1487
|
-
sinkCandidates.push(expr);
|
|
1488
|
-
},
|
|
1489
|
-
"Program:exit"(program) {
|
|
1490
|
-
const mutableFunctions = /* @__PURE__ */ new Map();
|
|
1491
|
-
for (const { enclosing, node, root } of mutationSites) {
|
|
1492
|
-
const variable = findVariable(context.sourceCode.getScope(root), root);
|
|
1493
|
-
if (variable == null) continue;
|
|
1494
|
-
const declId = variable.identifiers.at(0) ?? null;
|
|
1495
|
-
let current = enclosing;
|
|
1496
|
-
while (current != null) {
|
|
1497
|
-
if (declId != null && isNodeWithin(declId, current)) break;
|
|
1498
|
-
if (!mutableFunctions.has(current)) mutableFunctions.set(current, {
|
|
1499
|
-
name: variable.name,
|
|
1500
|
-
node
|
|
1501
|
-
});
|
|
1502
|
-
current = Traverse.findParent(current, Check.isFunction);
|
|
1503
|
-
}
|
|
1504
|
-
}
|
|
1505
|
-
if (mutableFunctions.size === 0) return;
|
|
1506
|
-
const reported = /* @__PURE__ */ new Set();
|
|
1507
|
-
function checkSink(expr) {
|
|
1508
|
-
if (expr == null || reported.has(expr)) return;
|
|
1509
|
-
const fn = resolveToFunctionNode(context, expr);
|
|
1510
|
-
if (fn == null) return;
|
|
1511
|
-
const mutation = mutableFunctions.get(fn);
|
|
1512
|
-
if (mutation == null) return;
|
|
1513
|
-
reported.add(expr);
|
|
1514
|
-
context.report({
|
|
1515
|
-
data: { name: mutation.name },
|
|
1516
|
-
messageId: "default",
|
|
1517
|
-
node: expr
|
|
1518
|
-
});
|
|
1519
|
-
context.report({
|
|
1520
|
-
data: { name: mutation.name },
|
|
1521
|
-
messageId: "mutates",
|
|
1522
|
-
node: mutation.node
|
|
1523
|
-
});
|
|
1524
|
-
}
|
|
1525
|
-
for (const candidate of sinkCandidates) checkSink(candidate);
|
|
1526
|
-
for (const hook of hc.api.getAllHooks(program)) for (const ret of hook.rets) checkSink(ret);
|
|
1527
|
-
},
|
|
1528
|
-
UnaryExpression(node) {
|
|
1529
|
-
if (node.operator !== "delete") return;
|
|
1530
|
-
const arg = Extract.unwrap(node.argument);
|
|
1531
|
-
if (arg.type !== AST_NODE_TYPES.MemberExpression) return;
|
|
1532
|
-
if (isRefLikeChain(context, arg)) return;
|
|
1533
|
-
const rootId = Extract.getRootIdentifier(arg);
|
|
1534
|
-
if (rootId == null) return;
|
|
1535
|
-
pushMutationSite(node, rootId);
|
|
1536
|
-
},
|
|
1537
|
-
UpdateExpression(node) {
|
|
1538
|
-
const arg = Extract.unwrap(node.argument);
|
|
1539
|
-
switch (arg.type) {
|
|
1540
|
-
case AST_NODE_TYPES.Identifier:
|
|
1541
|
-
if (isRefLikeName$1(arg.name)) return;
|
|
1542
|
-
pushMutationSite(node, arg);
|
|
1543
|
-
return;
|
|
1544
|
-
case AST_NODE_TYPES.MemberExpression: {
|
|
1545
|
-
if (isRefLikeChain(context, arg)) return;
|
|
1546
|
-
const rootId = Extract.getRootIdentifier(arg);
|
|
1547
|
-
if (rootId == null) return;
|
|
1548
|
-
pushMutationSite(node, rootId);
|
|
1549
|
-
return;
|
|
1550
|
-
}
|
|
1551
|
-
}
|
|
1542
|
+
const mutableFunctions = inferMutableFunctions(context, collector.facts.mutations);
|
|
1543
|
+
if (mutableFunctions.size === 0) return;
|
|
1544
|
+
const reported = /* @__PURE__ */ new Set();
|
|
1545
|
+
for (const sink of collector.facts.sinks) {
|
|
1546
|
+
const expression = sink.expression;
|
|
1547
|
+
if (reported.has(expression)) continue;
|
|
1548
|
+
const fn = resolveToFunctionNode(context, expression);
|
|
1549
|
+
if (fn == null) continue;
|
|
1550
|
+
const mutation = mutableFunctions.get(fn);
|
|
1551
|
+
if (mutation == null) continue;
|
|
1552
|
+
reported.add(expression);
|
|
1553
|
+
context.report({
|
|
1554
|
+
data: { name: mutation.name },
|
|
1555
|
+
messageId: "default",
|
|
1556
|
+
node: expression
|
|
1557
|
+
});
|
|
1558
|
+
context.report({
|
|
1559
|
+
data: { name: mutation.name },
|
|
1560
|
+
messageId: "mutates",
|
|
1561
|
+
node: mutation.node
|
|
1562
|
+
});
|
|
1552
1563
|
}
|
|
1553
|
-
});
|
|
1564
|
+
} });
|
|
1554
1565
|
}
|
|
1555
1566
|
|
|
1556
1567
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-x",
|
|
3
|
-
"version": "5.14.
|
|
3
|
+
"version": "5.14.6",
|
|
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.14.
|
|
49
|
-
"@eslint-react/core": "5.14.
|
|
50
|
-
"@eslint-react/
|
|
51
|
-
"@eslint-react/eslint": "5.14.
|
|
52
|
-
"@eslint-react/
|
|
53
|
-
"@eslint-react/var": "5.14.
|
|
48
|
+
"@eslint-react/ast": "5.14.6",
|
|
49
|
+
"@eslint-react/core": "5.14.6",
|
|
50
|
+
"@eslint-react/jsx": "5.14.6",
|
|
51
|
+
"@eslint-react/eslint": "5.14.6",
|
|
52
|
+
"@eslint-react/shared": "5.14.6",
|
|
53
|
+
"@eslint-react/var": "5.14.6"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@types/react": "^19.2.17",
|
|
57
57
|
"@types/react-dom": "^19.2.3",
|
|
58
58
|
"dedent": "^1.7.2",
|
|
59
|
-
"eslint": "^10.
|
|
59
|
+
"eslint": "^10.7.0",
|
|
60
60
|
"react": "^19.2.7",
|
|
61
61
|
"react-dom": "^19.2.7",
|
|
62
62
|
"tsdown": "^0.22.4",
|
|
63
63
|
"tsl": "^1.0.30",
|
|
64
64
|
"tsl-dx": "^0.13.2",
|
|
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": "*",
|