@sarj/eslint-plugin 16.5.3 → 16.7.0
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.cjs +174 -67
- package/dist/index.d.cts +9 -9
- package/dist/index.d.ts +9 -9
- package/dist/index.js +249 -142
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
3
|
name: "@sarj/eslint-plugin",
|
|
4
|
-
version: "16.
|
|
4
|
+
version: "16.7.0",
|
|
5
5
|
packageManager: "npm@12.1.0",
|
|
6
6
|
description: "Custom ESLint rules for hypermodern TypeScript / React / Next.js projects",
|
|
7
7
|
type: "module",
|
|
@@ -419,8 +419,9 @@ function commentLineEnd(sourceText, start) {
|
|
|
419
419
|
}
|
|
420
420
|
|
|
421
421
|
// src/rules/require-explicit-contract-implementation.ts
|
|
422
|
+
var ESCAPED_CLASSES = /* @__PURE__ */ new WeakMap();
|
|
422
423
|
var REQUIRE_EXPLICIT_CONTRACT_IMPLEMENTATION_DOCUMENTATION = {
|
|
423
|
-
defaultLevel: "
|
|
424
|
+
defaultLevel: "error",
|
|
424
425
|
summary: "Require nominal inheritance when an injected abstract class is rejected by an instanceof guard.",
|
|
425
426
|
rationale: "A structurally assignable fake can still fail a constructor's nominal runtime guard. Pure structural interfaces do not require an implements clause.",
|
|
426
427
|
remediation: "Use an implementation inheriting the existing abstract class, or remove the nominal guard if the boundary is intentionally structural.",
|
|
@@ -428,8 +429,8 @@ var REQUIRE_EXPLICIT_CONTRACT_IMPLEMENTATION_DOCUMENTATION = {
|
|
|
428
429
|
autofix: "none",
|
|
429
430
|
limitations: [
|
|
430
431
|
"Requires direct construction of both owned consumer and collaborator classes, with a first-statement consumer constructor guard rejecting the exact parameter with if (!(parameter instanceof Contract)) throw.",
|
|
431
|
-
"The contract must resolve to an abstract class without decorators, unresolved ancestors, or custom computed static members in its resolved hierarchy.",
|
|
432
|
-
"Structural interfaces, non-rejecting branches, reassignment before the guard, casts, unresolved heritage, dynamic factories, explicit implementation constructors or initializers, modules referencing prototype-mutator members or assigning prototypes, and third-party classes are excluded."
|
|
432
|
+
"The contract must resolve to an abstract class without decorators, static blocks, unresolved ancestors, or custom computed static members in its resolved hierarchy. Escaped class constructors are checked across every owned module in the typed program.",
|
|
433
|
+
"Structural interfaces, non-rejecting branches, reassignment before the guard, casts, unresolved heritage, dynamic factories, implementation static blocks, explicit implementation constructors or initializers, involved modules referencing prototype-mutator members or assigning prototypes, escaped class constructors, and third-party classes are excluded."
|
|
433
434
|
],
|
|
434
435
|
examples: [
|
|
435
436
|
{
|
|
@@ -452,6 +453,115 @@ var REQUIRE_EXPLICIT_CONTRACT_IMPLEMENTATION_DOCUMENTATION = {
|
|
|
452
453
|
}
|
|
453
454
|
]
|
|
454
455
|
};
|
|
456
|
+
function hasPrototypeMutation(source) {
|
|
457
|
+
function visit(node) {
|
|
458
|
+
const member = memberName(node);
|
|
459
|
+
if (member === "setPrototypeOf" || member === "__proto__" || member === "hasInstance") return true;
|
|
460
|
+
if (ts.isBinaryExpression(node) && node.operatorToken.kind >= ts.SyntaxKind.FirstAssignment && node.operatorToken.kind <= ts.SyntaxKind.LastAssignment && memberName(node.left) === "prototype") return true;
|
|
461
|
+
return ts.forEachChild(node, visit);
|
|
462
|
+
}
|
|
463
|
+
return visit(source) === true;
|
|
464
|
+
}
|
|
465
|
+
function memberName(node) {
|
|
466
|
+
if (ts.isPropertyAccessExpression(node)) return node.name.text;
|
|
467
|
+
if (ts.isElementAccessExpression(node) && ts.isStringLiteralLike(node.argumentExpression)) return node.argumentExpression.text;
|
|
468
|
+
return null;
|
|
469
|
+
}
|
|
470
|
+
function ownedSource(source) {
|
|
471
|
+
return !source.isDeclarationFile && !/(?:^|[/\\])(?:node_modules|vendor|vendored|generated|dist)(?:[/\\])/u.test(source.fileName) && !isGeneratedFile(source.fileName, source.text);
|
|
472
|
+
}
|
|
473
|
+
function escapedClasses(program, checker) {
|
|
474
|
+
const cached = ESCAPED_CLASSES.get(program);
|
|
475
|
+
if (cached !== void 0) return cached;
|
|
476
|
+
const escaped = /* @__PURE__ */ new Set();
|
|
477
|
+
const namespaceValues = /* @__PURE__ */ new Map();
|
|
478
|
+
function visit(node) {
|
|
479
|
+
if (ts.isTypeNode(node) || ts.isImportDeclaration(node)) return;
|
|
480
|
+
if (ts.isIdentifier(node) || ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node)) {
|
|
481
|
+
recordEscapedReference(checker, node, escaped, namespaceValues);
|
|
482
|
+
}
|
|
483
|
+
ts.forEachChild(node, visit);
|
|
484
|
+
}
|
|
485
|
+
for (const source of program.getSourceFiles()) if (ownedSource(source)) visit(source);
|
|
486
|
+
ESCAPED_CLASSES.set(program, escaped);
|
|
487
|
+
return escaped;
|
|
488
|
+
}
|
|
489
|
+
function recordEscapedReference(checker, node, escaped, namespaceValues) {
|
|
490
|
+
const symbol = canonicalSymbol(checker, node);
|
|
491
|
+
if (symbol !== void 0) {
|
|
492
|
+
let values = namespaceValues.get(symbol);
|
|
493
|
+
if (values === void 0) {
|
|
494
|
+
values = ownedClassValues(checker, symbol);
|
|
495
|
+
namespaceValues.set(symbol, values);
|
|
496
|
+
}
|
|
497
|
+
if (!namespacePrefix(symbol, node) && !safeClassReference(node)) for (const value of values) escaped.add(value);
|
|
498
|
+
}
|
|
499
|
+
if (ts.isElementAccessExpression(node) && !safeClassReference(node)) {
|
|
500
|
+
const receiver = canonicalSymbol(checker, node.expression) ?? checker.getTypeAtLocation(node.expression).getSymbol();
|
|
501
|
+
if (receiver !== void 0) for (const value of ownedClassValues(checker, receiver)) escaped.add(value);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
function ownedClassValues(checker, original, seen = /* @__PURE__ */ new Set()) {
|
|
505
|
+
const symbol = original.flags & ts.SymbolFlags.Alias ? checker.getAliasedSymbol(original) : original;
|
|
506
|
+
const values = /* @__PURE__ */ new Set();
|
|
507
|
+
if (seen.has(symbol)) return values;
|
|
508
|
+
seen.add(symbol);
|
|
509
|
+
if (symbol.declarations?.some((declaration) => ts.isClassDeclaration(declaration) && ownedSource(declaration.getSourceFile()))) values.add(symbol);
|
|
510
|
+
if (symbol.declarations?.some((declaration) => (ts.isSourceFile(declaration) || ts.isModuleDeclaration(declaration)) && ownedSource(declaration.getSourceFile()))) {
|
|
511
|
+
for (const exported of checker.getExportsOfModule(symbol)) {
|
|
512
|
+
for (const value of ownedClassValues(checker, exported, seen)) values.add(value);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return values;
|
|
516
|
+
}
|
|
517
|
+
function safeClassReference(node) {
|
|
518
|
+
let reference = ts.isPropertyAccessExpression(node.parent) && node.parent.name === node ? node.parent : node;
|
|
519
|
+
while (ts.isParenthesizedExpression(reference.parent)) reference = reference.parent;
|
|
520
|
+
const parent = reference.parent;
|
|
521
|
+
return ts.isClassDeclaration(parent) && parent.name === reference || ts.isNewExpression(parent) && parent.expression === reference || ts.isExpressionWithTypeArguments(parent) && parent.expression === reference || ts.isBinaryExpression(parent) && parent.operatorToken.kind === ts.SyntaxKind.InstanceOfKeyword && parent.right === reference;
|
|
522
|
+
}
|
|
523
|
+
function namespacePrefix(symbol, node) {
|
|
524
|
+
const parent = node.parent;
|
|
525
|
+
const memberCall = (ts.isPropertyAccessExpression(parent) || ts.isElementAccessExpression(parent)) && ts.isCallExpression(parent.parent) && parent.parent.expression === parent;
|
|
526
|
+
return !symbol.declarations?.some(ts.isClassDeclaration) && (ts.isPropertyAccessExpression(parent) || ts.isElementAccessExpression(parent)) && parent.expression === node && !memberCall;
|
|
527
|
+
}
|
|
528
|
+
function closedNominalBoundary(program, checker, call, consumer, missing) {
|
|
529
|
+
const { implementation, contractSymbol } = missing;
|
|
530
|
+
const implementationSymbol = implementation.name === void 0 ? void 0 : canonicalSymbol(checker, implementation.name);
|
|
531
|
+
const consumerSymbol = consumer.name === void 0 ? void 0 : canonicalSymbol(checker, consumer.name);
|
|
532
|
+
if (implementationSymbol === void 0 || consumerSymbol === void 0) return false;
|
|
533
|
+
const contract = contractSymbol.declarations?.find(ts.isClassDeclaration);
|
|
534
|
+
if (contract === void 0) return false;
|
|
535
|
+
const targets = /* @__PURE__ */ new Set([consumerSymbol, ...classHierarchySymbols(checker, contract), ...classHierarchySymbols(checker, implementation)]);
|
|
536
|
+
const sources = /* @__PURE__ */ new Set([call.getSourceFile(), consumer.getSourceFile(), implementation.getSourceFile(), ...contractSymbol.declarations?.map((item) => item.getSourceFile()) ?? []]);
|
|
537
|
+
return ![...sources].some(hasPrototypeMutation) && ![...targets].some((target) => escapedClasses(program, checker).has(target));
|
|
538
|
+
}
|
|
539
|
+
function classHierarchySymbols(checker, declaration, seen = /* @__PURE__ */ new Set()) {
|
|
540
|
+
const symbol = declaration.name === void 0 ? void 0 : canonicalSymbol(checker, declaration.name);
|
|
541
|
+
if (symbol === void 0 || seen.has(symbol)) return seen;
|
|
542
|
+
seen.add(symbol);
|
|
543
|
+
for (const clause of declaration.heritageClauses ?? []) {
|
|
544
|
+
if (clause.token !== ts.SyntaxKind.ExtendsKeyword) continue;
|
|
545
|
+
for (const parent of clause.types) {
|
|
546
|
+
const ancestor = canonicalSymbol(checker, parent.expression)?.declarations?.find(ts.isClassDeclaration);
|
|
547
|
+
if (ancestor !== void 0) classHierarchySymbols(checker, ancestor, seen);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
return seen;
|
|
551
|
+
}
|
|
552
|
+
function missingImplementation(checker, signature, parameter, call, argument) {
|
|
553
|
+
const parameterType = checker.getTypeOfSymbolAtLocation(parameter, call);
|
|
554
|
+
const contractType = behavioralContract(checker, parameterType);
|
|
555
|
+
if (contractType === null) return null;
|
|
556
|
+
const contractSymbol = contractType.getSymbol();
|
|
557
|
+
if (contractSymbol === void 0 || !hasNominalRejectionGuard(checker, signature, parameter, contractSymbol)) return null;
|
|
558
|
+
const actualType = checker.getTypeAtLocation(argument);
|
|
559
|
+
if (!checker.isTypeAssignableTo(actualType, contractType)) return null;
|
|
560
|
+
const implementation = ownedClass(checker, argument);
|
|
561
|
+
if (implementation === null) return null;
|
|
562
|
+
if (nominallyInherits(checker, implementation, contractSymbol, /* @__PURE__ */ new Set()) !== false) return null;
|
|
563
|
+
return { implementation, contractSymbol };
|
|
564
|
+
}
|
|
455
565
|
function behavioralContract(checker, type) {
|
|
456
566
|
if (type.isUnion()) {
|
|
457
567
|
const substantive = type.types.filter((member) => (member.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) === 0);
|
|
@@ -476,23 +586,9 @@ function ownedClass(checker, expression) {
|
|
|
476
586
|
if (declaration === void 0 || declaration !== constructed || declaration.getSourceFile().isDeclarationFile || /(?:^|[/\\])(?:node_modules|vendor|generated)(?:[/\\])/u.test(declaration.getSourceFile().fileName)) return null;
|
|
477
587
|
return declaration;
|
|
478
588
|
}
|
|
479
|
-
function memberName(node) {
|
|
480
|
-
if (ts.isPropertyAccessExpression(node)) return node.name.text;
|
|
481
|
-
if (ts.isElementAccessExpression(node) && ts.isStringLiteralLike(node.argumentExpression)) return node.argumentExpression.text;
|
|
482
|
-
return null;
|
|
483
|
-
}
|
|
484
|
-
function hasPrototypeMutation(source) {
|
|
485
|
-
function visit(node) {
|
|
486
|
-
const member = memberName(node);
|
|
487
|
-
if (member === "setPrototypeOf" || member === "__proto__" || member === "hasInstance") return true;
|
|
488
|
-
if (ts.isBinaryExpression(node) && node.operatorToken.kind >= ts.SyntaxKind.FirstAssignment && node.operatorToken.kind <= ts.SyntaxKind.LastAssignment && memberName(node.left) === "prototype") return true;
|
|
489
|
-
return ts.forEachChild(node, visit);
|
|
490
|
-
}
|
|
491
|
-
return visit(source) === true;
|
|
492
|
-
}
|
|
493
589
|
function nominallyInherits(checker, declaration, target, seen) {
|
|
494
590
|
if (ts.canHaveDecorators(declaration) && ts.getDecorators(declaration)?.length) return null;
|
|
495
|
-
if (hasPrototypeMutation(declaration.getSourceFile()) || declaration.members.some((member) => ts.isConstructorDeclaration(member) || ts.isPropertyDeclaration(member) && member.initializer !== void 0)) return null;
|
|
591
|
+
if (hasPrototypeMutation(declaration.getSourceFile()) || declaration.members.some((member) => ts.isConstructorDeclaration(member) || ts.isClassStaticBlockDeclaration(member) || ts.isPropertyDeclaration(member) && member.initializer !== void 0)) return null;
|
|
496
592
|
const symbol = declaration.name === void 0 ? void 0 : canonicalSymbol(checker, declaration.name);
|
|
497
593
|
if (symbol !== void 0) {
|
|
498
594
|
if (seen.has(symbol)) return null;
|
|
@@ -507,10 +603,6 @@ function nominallyInherits(checker, declaration, target, seen) {
|
|
|
507
603
|
const inherited = parentSymbol.declarations?.find(ts.isClassDeclaration);
|
|
508
604
|
return inherited === void 0 ? null : nominallyInherits(checker, inherited, target, new Set(seen));
|
|
509
605
|
}
|
|
510
|
-
function canonicalSymbol(checker, node) {
|
|
511
|
-
const symbol = checker.getSymbolAtLocation(node);
|
|
512
|
-
return symbol === void 0 ? void 0 : (symbol.flags & ts.SymbolFlags.Alias) !== 0 ? checker.getAliasedSymbol(symbol) : symbol;
|
|
513
|
-
}
|
|
514
606
|
function hasNominalRejectionGuard(checker, signature, parameter, contract) {
|
|
515
607
|
const declaration = signature.getDeclaration();
|
|
516
608
|
if (declaration === void 0 || !ts.isConstructorDeclaration(declaration)) return false;
|
|
@@ -535,7 +627,7 @@ function alwaysThrows(statement) {
|
|
|
535
627
|
return ts.isThrowStatement(statement) || ts.isBlock(statement) && statement.statements.length === 1 && ts.isThrowStatement(statement.statements[0]);
|
|
536
628
|
}
|
|
537
629
|
function hasOrdinaryInstanceCheck(checker, declaration, seen) {
|
|
538
|
-
if (seen.has(declaration) || ts.getDecorators(declaration)?.length || hasPrototypeMutation(declaration.getSourceFile())) return false;
|
|
630
|
+
if (seen.has(declaration) || ts.getDecorators(declaration)?.length || hasPrototypeMutation(declaration.getSourceFile()) || declaration.members.some(ts.isClassStaticBlockDeclaration)) return false;
|
|
539
631
|
seen.add(declaration);
|
|
540
632
|
if (declaration.members.some((member) => member.name !== void 0 && ts.isComputedPropertyName(member.name) && ts.canHaveModifiers(member) && ts.getModifiers(member)?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword))) return false;
|
|
541
633
|
for (const clause of declaration.heritageClauses ?? []) {
|
|
@@ -547,6 +639,10 @@ function hasOrdinaryInstanceCheck(checker, declaration, seen) {
|
|
|
547
639
|
}
|
|
548
640
|
return true;
|
|
549
641
|
}
|
|
642
|
+
function canonicalSymbol(checker, node) {
|
|
643
|
+
const symbol = checker.getSymbolAtLocation(node);
|
|
644
|
+
return symbol === void 0 ? void 0 : (symbol.flags & ts.SymbolFlags.Alias) !== 0 ? checker.getAliasedSymbol(symbol) : symbol;
|
|
645
|
+
}
|
|
550
646
|
var require_explicit_contract_implementation_default = createRule({
|
|
551
647
|
name: "require-explicit-contract-implementation",
|
|
552
648
|
documentation: REQUIRE_EXPLICIT_CONTRACT_IMPLEMENTATION_DOCUMENTATION,
|
|
@@ -576,22 +672,13 @@ var require_explicit_contract_implementation_default = createRule({
|
|
|
576
672
|
if (argument.type !== AST_NODE_TYPES.NewExpression) continue;
|
|
577
673
|
const parameter = parameters[index];
|
|
578
674
|
if (parameter === void 0) continue;
|
|
579
|
-
const parameterType = checker.getTypeOfSymbolAtLocation(parameter, tsNode);
|
|
580
|
-
const contractType = behavioralContract(checker, parameterType);
|
|
581
|
-
if (contractType === null) continue;
|
|
582
|
-
const contractSymbol = contractType.getSymbol();
|
|
583
|
-
if (contractSymbol === void 0 || !hasNominalRejectionGuard(checker, signature, parameter, contractSymbol)) continue;
|
|
584
675
|
const tsArgument = services.esTreeNodeToTSNodeMap.get(argument);
|
|
585
|
-
const
|
|
586
|
-
if (!
|
|
587
|
-
const implementation = ownedClass(checker, tsArgument);
|
|
588
|
-
if (implementation === null) continue;
|
|
589
|
-
const relationship = nominallyInherits(checker, implementation, contractSymbol, /* @__PURE__ */ new Set());
|
|
590
|
-
if (relationship !== false) continue;
|
|
676
|
+
const missing = missingImplementation(checker, signature, parameter, tsNode, tsArgument);
|
|
677
|
+
if (missing === null || !closedNominalBoundary(services.program, checker, tsNode, consumer, missing)) continue;
|
|
591
678
|
context.report({
|
|
592
679
|
node: argument,
|
|
593
680
|
messageId: "declareActualContract",
|
|
594
|
-
data: { implementation: implementation.name?.text ?? "class", contract: contractSymbol.getName() }
|
|
681
|
+
data: { implementation: missing.implementation.name?.text ?? "class", contract: missing.contractSymbol.getName() }
|
|
595
682
|
});
|
|
596
683
|
}
|
|
597
684
|
}
|
|
@@ -7592,7 +7679,8 @@ var NO_IMPOSSIBLE_ZOD_LITERAL_BOUNDS_DOCUMENTATION = {
|
|
|
7592
7679
|
remediation: "Choose compatible lower and upper bounds, or remove the constraint that does not express the intended domain.",
|
|
7593
7680
|
category: "correctness",
|
|
7594
7681
|
limitations: [
|
|
7595
|
-
"Only finite numeric literals in a single number, string, or array schema chain are compared.",
|
|
7682
|
+
"Only finite numeric literals in a single number, string, or array schema chain are compared; explicit int() chains also require an admitted integer.",
|
|
7683
|
+
"Integer-domain comparisons abstain near the JavaScript safe-integer boundary.",
|
|
7596
7684
|
"Chains with dynamic bounds, non-bound validators, transforms, pipes, or preprocessors are skipped.",
|
|
7597
7685
|
"Test and generated files are excluded."
|
|
7598
7686
|
],
|
|
@@ -7631,6 +7719,7 @@ var KINDS = /* @__PURE__ */ new Set(["array", "number", "string"]);
|
|
|
7631
7719
|
var NUMBER_METHODS = /* @__PURE__ */ new Set([
|
|
7632
7720
|
"gt",
|
|
7633
7721
|
"gte",
|
|
7722
|
+
"int",
|
|
7634
7723
|
"lt",
|
|
7635
7724
|
"lte",
|
|
7636
7725
|
"max",
|
|
@@ -7672,9 +7761,20 @@ function strongerUpper(current, candidate2) {
|
|
|
7672
7761
|
}
|
|
7673
7762
|
return current;
|
|
7674
7763
|
}
|
|
7675
|
-
function isEmpty(lower, upper) {
|
|
7764
|
+
function isEmpty(lower, upper, integer) {
|
|
7676
7765
|
if (lower === null || upper === null) return false;
|
|
7677
|
-
|
|
7766
|
+
const realEmpty = lower.value > upper.value || lower.value === upper.value && (lower.exclusive || upper.exclusive);
|
|
7767
|
+
if (integer) {
|
|
7768
|
+
if (realEmpty) return false;
|
|
7769
|
+
const safeMargin = Number.MAX_SAFE_INTEGER - 1;
|
|
7770
|
+
if (Math.abs(lower.value) >= safeMargin || Math.abs(upper.value) >= safeMargin) {
|
|
7771
|
+
return false;
|
|
7772
|
+
}
|
|
7773
|
+
const minimum = lower.exclusive ? Math.floor(lower.value) + 1 : Math.ceil(lower.value);
|
|
7774
|
+
const maximum = upper.exclusive ? Math.ceil(upper.value) - 1 : Math.floor(upper.value);
|
|
7775
|
+
return minimum > maximum;
|
|
7776
|
+
}
|
|
7777
|
+
return realEmpty;
|
|
7678
7778
|
}
|
|
7679
7779
|
function isOutermostCall(node) {
|
|
7680
7780
|
const parent = node.parent;
|
|
@@ -7768,6 +7868,7 @@ var no_impossible_zod_literal_bounds_default = createRule({
|
|
|
7768
7868
|
const allowed = chain.kind === "number" ? NUMBER_METHODS : LENGTH_METHODS;
|
|
7769
7869
|
let lower = null;
|
|
7770
7870
|
let upper = null;
|
|
7871
|
+
let integer = false;
|
|
7771
7872
|
function addBound(method, semantic, value) {
|
|
7772
7873
|
const label = `${method}(${String(value)})`;
|
|
7773
7874
|
if (semantic !== null) {
|
|
@@ -7803,6 +7904,11 @@ var no_impossible_zod_literal_bounds_default = createRule({
|
|
|
7803
7904
|
}
|
|
7804
7905
|
for (const { method, node } of chain.calls) {
|
|
7805
7906
|
if (!allowed.has(method)) return null;
|
|
7907
|
+
if (method === "int") {
|
|
7908
|
+
if (node.arguments.length !== 0) return null;
|
|
7909
|
+
integer = true;
|
|
7910
|
+
continue;
|
|
7911
|
+
}
|
|
7806
7912
|
const semantic = zeroBoundSemantic(method);
|
|
7807
7913
|
const value = semantic?.value ?? finiteNumber(node.arguments[0]);
|
|
7808
7914
|
if (value === null) return null;
|
|
@@ -7812,7 +7918,7 @@ var no_impossible_zod_literal_bounds_default = createRule({
|
|
|
7812
7918
|
if (semantic !== null && node.arguments.length !== 0) return null;
|
|
7813
7919
|
addBound(method, semantic, value);
|
|
7814
7920
|
}
|
|
7815
|
-
return isEmpty(lower, upper) && lower !== null && upper !== null ? { lower, upper } : null;
|
|
7921
|
+
return isEmpty(lower, upper, integer) && lower !== null && upper !== null ? { lower, upper } : null;
|
|
7816
7922
|
}
|
|
7817
7923
|
return {
|
|
7818
7924
|
ImportDeclaration(node) {
|
|
@@ -17698,14 +17804,14 @@ var prefer_named_callback_domain_default = createRule({
|
|
|
17698
17804
|
// src/rules/prefer-named-complex-return-type.ts
|
|
17699
17805
|
import { AST_NODE_TYPES as AST_NODE_TYPES86 } from "@typescript-eslint/utils";
|
|
17700
17806
|
var PREFER_NAMED_COMPLEX_RETURN_TYPE_DOCUMENTATION = {
|
|
17701
|
-
defaultLevel: "
|
|
17807
|
+
defaultLevel: "error",
|
|
17702
17808
|
summary: "Prefer a named contract for structurally complex function return types.",
|
|
17703
17809
|
rationale: "A large inline return annotation hides a reusable domain concept and makes signatures difficult to scan.",
|
|
17704
17810
|
remediation: "Name the complex nested shape while preserving its generic wrappers and type parameters; reference the named contract from the return annotation.",
|
|
17705
17811
|
category: "maintainability",
|
|
17706
17812
|
limitations: [
|
|
17707
17813
|
"Only explicit object types with at least three members and unions with at least three object variants are reported.",
|
|
17708
|
-
"Any single-argument generic wrapper is traversed to find nested shapes, not assumed semantically transparent. Inferred return types are outside this rule; extraction is manual and must preserve locally bound type parameters."
|
|
17814
|
+
"Any single-argument generic wrapper is traversed to find nested shapes, not assumed semantically transparent. Inferred return types are outside this rule; extraction is manual and must preserve locally bound type parameters with generic named contracts. Types depending on polymorphic this or a local value query are excluded."
|
|
17709
17815
|
],
|
|
17710
17816
|
examples: [
|
|
17711
17817
|
{ id: "named-result", title: "Name a multi-state result", outcome: "no-match", files: [{ path: "src/queue.ts", source: "type ClaimResult = { state: 'idle' } | { state: 'waiting'; retryAt: number } | { state: 'claimed'; id: string }; export function claim(): ClaimResult { return { state: 'idle' }; }" }], focusPath: "src/queue.ts", expectedCount: 0, public: true },
|
|
@@ -17721,10 +17827,13 @@ function unwrap4(node) {
|
|
|
17721
17827
|
}
|
|
17722
17828
|
function report(context, node) {
|
|
17723
17829
|
const annotation = node.returnType?.typeAnnotation;
|
|
17724
|
-
if (annotation !== void 0 && isComplex(annotation)) {
|
|
17830
|
+
if (annotation !== void 0 && isComplex(annotation) && !hasValueDependency(annotation)) {
|
|
17725
17831
|
context.report({ node: annotation, messageId: "nameComplexReturnType" });
|
|
17726
17832
|
}
|
|
17727
17833
|
}
|
|
17834
|
+
function hasValueDependency(node) {
|
|
17835
|
+
return node.type === AST_NODE_TYPES86.TSThisType || node.type === AST_NODE_TYPES86.TSTypeQuery || forEachOwnAstChild(node, hasValueDependency);
|
|
17836
|
+
}
|
|
17728
17837
|
function isComplex(node) {
|
|
17729
17838
|
const type = unwrap4(node);
|
|
17730
17839
|
if (type.type === AST_NODE_TYPES86.TSTypeLiteral) return type.members.length >= 3;
|
|
@@ -19378,22 +19487,22 @@ var prefer_shared_zod_enum_default = createRule({
|
|
|
19378
19487
|
});
|
|
19379
19488
|
|
|
19380
19489
|
// src/rules/prefer-switch-for-repeated-equality.ts
|
|
19381
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES95 } from "@typescript-eslint/utils";
|
|
19490
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES95, ASTUtils as ASTUtils57 } from "@typescript-eslint/utils";
|
|
19382
19491
|
var PREFER_SWITCH_FOR_REPEATED_EQUALITY_DOCUMENTATION = {
|
|
19383
|
-
defaultLevel: "
|
|
19492
|
+
defaultLevel: "error",
|
|
19384
19493
|
summary: "Prefer switch over long if/else-if chains that compare one value for strict equality.",
|
|
19385
19494
|
rationale: "A switch makes finite dispatch cases visually uniform and easier to extend without duplicating the discriminant.",
|
|
19386
19495
|
remediation: "Replace three or more strict-equality branches over the same discriminant with a switch; keep if statements for ranges, guards, and heterogeneous predicates.",
|
|
19387
19496
|
category: "maintainability",
|
|
19388
19497
|
limitations: [
|
|
19389
19498
|
"Only direct if/else-if chains with at least three strict-equality tests are reported.",
|
|
19390
|
-
"The discriminant must be a
|
|
19391
|
-
"Case values
|
|
19499
|
+
"The discriminant must be a resolved lexical variable or parameter; unresolved globals, calls, getters, and indexed reads are excluded. Preserve branch scopes and break/continue targets when converting manually; no autofix is offered.",
|
|
19500
|
+
"Case values must be primitive literals. Member references and named constants are excluded because evaluating them can observe getters or mutate the selector. Generated sources are excluded.",
|
|
19392
19501
|
"The rule deliberately ignores compound predicates, loose equality, ranges, and chains that compare different discriminants."
|
|
19393
19502
|
],
|
|
19394
19503
|
examples: [
|
|
19395
19504
|
{ id: "switch-dispatch", title: "Make finite dispatch explicit", outcome: "no-match", files: [{ path: "src/render.ts", source: "switch (kind) { case 'a': return a(); case 'b': return b(); case 'c': return c(); default: return fallback(); }" }], focusPath: "src/render.ts", expectedCount: 0, public: true },
|
|
19396
|
-
{ id: "repeated-equality", title: "Avoid repeating the discriminant", outcome: "match", files: [{ path: "src/render.ts", source: "if (kind === 'a') return a(); else if (kind === 'b') return b(); else if (kind === 'c') return c();" }], focusPath: "src/render.ts", expectedCount: 1, public: true },
|
|
19505
|
+
{ id: "repeated-equality", title: "Avoid repeating the discriminant", outcome: "match", files: [{ path: "src/render.ts", source: "function render(kind: string) { if (kind === 'a') return a(); else if (kind === 'b') return b(); else if (kind === 'c') return c(); }" }], focusPath: "src/render.ts", expectedCount: 1, public: true },
|
|
19397
19506
|
{ id: "escaped-middle", scenarioId: "native-discriminant", title: "Use native identifier identity", outcome: "match", files: [{ path: "src/dispatch.ts", source: `function probe(kind){if(kind==='a')return 1;else if(\\u006bind==='b')return 2;else if(kind==='c')return 3;return 0;}
|
|
19398
19507
|
console.log(JSON.stringify(["a","b","c","d"].map(probe)));` }], focusPath: "src/dispatch.ts", expectedCount: 1, public: true },
|
|
19399
19508
|
{ id: "different-discriminants", scenarioId: "native-discriminant", title: "Use native identifier identity", outcome: "no-match", files: [{ path: "src/dispatch.ts", source: `function probe(kind){const other="other";if(kind==='a')return 1;else if(other==='b')return 2;else if(kind==='c')return 3;return 0;}
|
|
@@ -19409,10 +19518,7 @@ function discriminantName(test) {
|
|
|
19409
19518
|
return discriminant.type === AST_NODE_TYPES95.Identifier ? discriminant.name : null;
|
|
19410
19519
|
}
|
|
19411
19520
|
function isCaseValue(node) {
|
|
19412
|
-
|
|
19413
|
-
if (node.type === AST_NODE_TYPES95.Identifier) return /^[A-Z][A-Z0-9_]*$/u.test(node.name);
|
|
19414
|
-
if (node.type !== AST_NODE_TYPES95.MemberExpression || node.computed) return false;
|
|
19415
|
-
return node.property.type === AST_NODE_TYPES95.Identifier && (node.object.type === AST_NODE_TYPES95.Identifier || isCaseValue(node.object));
|
|
19521
|
+
return node.type === AST_NODE_TYPES95.Literal && !("regex" in node);
|
|
19416
19522
|
}
|
|
19417
19523
|
var prefer_switch_for_repeated_equality_default = createRule({
|
|
19418
19524
|
name: "prefer-switch-for-repeated-equality",
|
|
@@ -19427,11 +19533,16 @@ var prefer_switch_for_repeated_equality_default = createRule({
|
|
|
19427
19533
|
},
|
|
19428
19534
|
defaultOptions: [],
|
|
19429
19535
|
create(context) {
|
|
19536
|
+
if (isGeneratedFile(context.filename, context.sourceCode.text)) return {};
|
|
19430
19537
|
return {
|
|
19431
19538
|
IfStatement(node) {
|
|
19432
19539
|
if (node.parent.type === AST_NODE_TYPES95.IfStatement && node.parent.alternate === node) return;
|
|
19433
19540
|
const first = discriminantName(node.test);
|
|
19434
19541
|
if (first === null) return;
|
|
19542
|
+
const binding = ASTUtils57.findVariable(context.sourceCode.getScope(node), first);
|
|
19543
|
+
if (binding === null || binding.defs.length !== 1 || binding.scope.type === "global") return;
|
|
19544
|
+
const [definition] = binding.defs;
|
|
19545
|
+
if (definition?.type !== "Parameter" && definition?.type !== "Variable") return;
|
|
19435
19546
|
let count = 1;
|
|
19436
19547
|
let current = node.alternate;
|
|
19437
19548
|
while (current?.type === AST_NODE_TYPES95.IfStatement) {
|
|
@@ -19975,7 +20086,7 @@ function packageWorkspaceGlobs(parsed) {
|
|
|
19975
20086
|
}
|
|
19976
20087
|
|
|
19977
20088
|
// src/rules/prefer-server-actions.ts
|
|
19978
|
-
import { ASTUtils as
|
|
20089
|
+
import { ASTUtils as ASTUtils58 } from "@typescript-eslint/utils";
|
|
19979
20090
|
var PREFER_SERVER_ACTIONS_DOCUMENTATION = {
|
|
19980
20091
|
summary: "Prefer Next.js Server Actions over same-origin API mutations.",
|
|
19981
20092
|
rationale: "Server Actions can remove a hand-written internal API wrapper while retaining typed application calls. Client invocations still cross a network and serialization boundary.",
|
|
@@ -20008,7 +20119,7 @@ function resolveNode(node, context) {
|
|
|
20008
20119
|
node = node == null ? node : unwrapExpression(node);
|
|
20009
20120
|
if (!node) return null;
|
|
20010
20121
|
if (node.type !== "Identifier") return node;
|
|
20011
|
-
const variable =
|
|
20122
|
+
const variable = ASTUtils58.findVariable(getScope(context, node), node.name);
|
|
20012
20123
|
const definition = variable?.defs.length === 1 ? variable.defs[0] : void 0;
|
|
20013
20124
|
if (definition?.type !== "Variable" || definition.parent.kind !== "const" || definition.node.init === null || variable?.references.some((reference) => reference.isWrite() && reference.init !== true)) return node;
|
|
20014
20125
|
if (definition.node.init.type === "ObjectExpression" && variable?.references.some((reference) => reference.identifier !== node && reference.init !== true)) return node;
|
|
@@ -20017,7 +20128,7 @@ function resolveNode(node, context) {
|
|
|
20017
20128
|
function isAxiosClient(node, context, seen = /* @__PURE__ */ new Set()) {
|
|
20018
20129
|
if (node.type !== "Identifier" || seen.has(node)) return false;
|
|
20019
20130
|
seen.add(node);
|
|
20020
|
-
const variable =
|
|
20131
|
+
const variable = ASTUtils58.findVariable(getScope(context, node), node.name);
|
|
20021
20132
|
const definition = variable?.defs.length === 1 ? variable.defs[0] : void 0;
|
|
20022
20133
|
if (definition === void 0 || variable?.references.some((reference) => reference.isWrite() && reference.init !== true)) return false;
|
|
20023
20134
|
if (variable?.references.some((reference) => {
|
|
@@ -20101,10 +20212,10 @@ function isFunctionArgument(node, context) {
|
|
|
20101
20212
|
}
|
|
20102
20213
|
function getPropertyNode(objNode, propName2) {
|
|
20103
20214
|
if (!objNode || objNode.type !== "ObjectExpression") return null;
|
|
20104
|
-
if (objNode.properties.some((property) => property.type === "SpreadElement" ||
|
|
20215
|
+
if (objNode.properties.some((property) => property.type === "SpreadElement" || ASTUtils58.getPropertyName(property) === null)) return null;
|
|
20105
20216
|
for (const prop of [...objNode.properties].reverse()) {
|
|
20106
20217
|
if (prop.type !== "Property") continue;
|
|
20107
|
-
const keyName =
|
|
20218
|
+
const keyName = ASTUtils58.getPropertyName(prop);
|
|
20108
20219
|
if (keyName === propName2) {
|
|
20109
20220
|
if (prop.value.type === "AssignmentPattern" || prop.value.type === "ArrayPattern" || prop.value.type === "ObjectPattern") {
|
|
20110
20221
|
return null;
|
|
@@ -20228,7 +20339,7 @@ var prefer_server_actions_default = createRule({
|
|
|
20228
20339
|
});
|
|
20229
20340
|
|
|
20230
20341
|
// src/rules/prefer-whole-object-assertion.ts
|
|
20231
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES97, ASTUtils as
|
|
20342
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES97, ASTUtils as ASTUtils59 } from "@typescript-eslint/utils";
|
|
20232
20343
|
var MERGEABLE_MATCHERS = /* @__PURE__ */ new Set(["toBe", "toEqual", "toStrictEqual"]);
|
|
20233
20344
|
var SYNTHETIC_LITERAL_MATCHERS = /* @__PURE__ */ new Map([
|
|
20234
20345
|
["toBeNull", "null"]
|
|
@@ -20293,7 +20404,7 @@ function propertyAccess(node) {
|
|
|
20293
20404
|
const path = [];
|
|
20294
20405
|
let current = node;
|
|
20295
20406
|
while (current.type === AST_NODE_TYPES97.MemberExpression && !current.optional) {
|
|
20296
|
-
const name =
|
|
20407
|
+
const name = ASTUtils59.getPropertyName(current);
|
|
20297
20408
|
if (name === null || COLLECTION_PROPERTIES.has(name) || LITERAL_KEY_HAZARDS.has(name)) return null;
|
|
20298
20409
|
path.unshift(name);
|
|
20299
20410
|
current = unwrapExpression(current.object);
|
|
@@ -20440,7 +20551,7 @@ var prefer_whole_object_assertion_default = createRule({
|
|
|
20440
20551
|
const callee = unwrapExpression(call.callee);
|
|
20441
20552
|
const calleeReceiver = callee.type === AST_NODE_TYPES97.MemberExpression ? unwrapExpression(callee.object) : callee;
|
|
20442
20553
|
if (callee.type !== AST_NODE_TYPES97.MemberExpression) return null;
|
|
20443
|
-
const matcher =
|
|
20554
|
+
const matcher = ASTUtils59.getPropertyName(callee);
|
|
20444
20555
|
if (matcher === null) return null;
|
|
20445
20556
|
const expectCall = calleeReceiver;
|
|
20446
20557
|
const expectCallee = expectCall.type === AST_NODE_TYPES97.CallExpression ? unwrapExpression(expectCall.callee) : null;
|
|
@@ -20470,7 +20581,7 @@ var prefer_whole_object_assertion_default = createRule({
|
|
|
20470
20581
|
return assertionExpectation(statement, call, receiver, key, matcher);
|
|
20471
20582
|
}
|
|
20472
20583
|
function isTestExpect(callee) {
|
|
20473
|
-
const variable =
|
|
20584
|
+
const variable = ASTUtils59.findVariable(sourceCode.getScope(callee), callee.name);
|
|
20474
20585
|
if (variable !== null && variable.defs.some((definition) => {
|
|
20475
20586
|
if (definition.node.type !== AST_NODE_TYPES97.ImportSpecifier) return true;
|
|
20476
20587
|
const declaration = definition.node.parent;
|
|
@@ -20513,7 +20624,7 @@ var prefer_whole_object_assertion_default = createRule({
|
|
|
20513
20624
|
});
|
|
20514
20625
|
|
|
20515
20626
|
// src/rules/repeated-static-call-cases.ts
|
|
20516
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES98, ASTUtils as
|
|
20627
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES98, ASTUtils as ASTUtils60 } from "@typescript-eslint/utils";
|
|
20517
20628
|
var REPEATED_STATIC_CALL_CASES_DOCUMENTATION = {
|
|
20518
20629
|
summary: "Review three or more consecutive static-input call assertions as potential named cases.",
|
|
20519
20630
|
rationale: "Copy-pasted cases obscure the input table, and a thrown assertion can stop later cases from being reported.",
|
|
@@ -20534,7 +20645,7 @@ var EXPECT_MODIFIERS = /* @__PURE__ */ new Set(["not", "rejects", "resolves"]);
|
|
|
20534
20645
|
var SNAPSHOT_MATCHERS = /snapshot/iu;
|
|
20535
20646
|
var MIN_CASES2 = 3;
|
|
20536
20647
|
function importedName6(identifier, context, modules) {
|
|
20537
|
-
const variable =
|
|
20648
|
+
const variable = ASTUtils60.findVariable(context.sourceCode.getScope(identifier), identifier.name);
|
|
20538
20649
|
if (variable === null || variable.defs.length === 0) return identifier.name;
|
|
20539
20650
|
for (const definition of variable.defs) {
|
|
20540
20651
|
if (definition.node.type !== AST_NODE_TYPES98.ImportSpecifier) continue;
|
|
@@ -20556,7 +20667,7 @@ function testRoot2(callee) {
|
|
|
20556
20667
|
callee = unwrapExpression(callee);
|
|
20557
20668
|
if (callee.type === AST_NODE_TYPES98.Identifier) return callee;
|
|
20558
20669
|
if (callee.type !== AST_NODE_TYPES98.MemberExpression) return null;
|
|
20559
|
-
const modifier =
|
|
20670
|
+
const modifier = ASTUtils60.getPropertyName(callee);
|
|
20560
20671
|
return modifier !== null && TEST_MODIFIERS5.has(modifier) ? testRoot2(callee.object) : null;
|
|
20561
20672
|
}
|
|
20562
20673
|
function isStatic(input) {
|
|
@@ -20602,8 +20713,8 @@ function assertionShape(statement, context, callback) {
|
|
|
20602
20713
|
const matcherCall = unwrapExpression(statement.expression);
|
|
20603
20714
|
if (matcherCall.type !== AST_NODE_TYPES98.CallExpression) return null;
|
|
20604
20715
|
const matcherCallee = unwrapExpression(matcherCall.callee);
|
|
20605
|
-
if (matcherCallee.type !== AST_NODE_TYPES98.MemberExpression ||
|
|
20606
|
-
const matcher =
|
|
20716
|
+
if (matcherCallee.type !== AST_NODE_TYPES98.MemberExpression || ASTUtils60.getPropertyName(matcherCallee) === null || matcherCall.arguments.length !== 1) return null;
|
|
20717
|
+
const matcher = ASTUtils60.getPropertyName(matcherCallee) ?? "";
|
|
20607
20718
|
if (SNAPSHOT_MATCHERS.test(matcher)) return null;
|
|
20608
20719
|
const chain = expectCallFromMatcher(matcherCallee);
|
|
20609
20720
|
const expectCallee = chain === null ? null : unwrapExpression(chain.call.callee);
|
|
@@ -20613,7 +20724,7 @@ function assertionShape(statement, context, callback) {
|
|
|
20613
20724
|
const observedCallee = observed?.type === AST_NODE_TYPES98.CallExpression ? unwrapExpression(observed.callee) : null;
|
|
20614
20725
|
if (observed?.type !== AST_NODE_TYPES98.CallExpression || observedCallee?.type !== AST_NODE_TYPES98.Identifier || observed.arguments.length === 0 || observed.arguments.some((arg) => arg.type === AST_NODE_TYPES98.SpreadElement || !isStatic(arg)) || expected?.type === AST_NODE_TYPES98.SpreadElement || expected === void 0 || !isStatic(expected)) return null;
|
|
20615
20726
|
const skeleton = `${observedCallee.name}/${observed.arguments.map((item) => staticShape(item)).join(",")}/${chain.modifiers.join(".")}/${matcher}/${staticShape(expected)}`;
|
|
20616
|
-
const binding =
|
|
20727
|
+
const binding = ASTUtils60.findVariable(context.sourceCode.getScope(observedCallee), observedCallee.name);
|
|
20617
20728
|
if (binding?.defs.some(
|
|
20618
20729
|
(definition) => definition.node.range[0] >= callback.range[0] && definition.node.range[1] <= callback.range[1]
|
|
20619
20730
|
)) return null;
|
|
@@ -20624,7 +20735,7 @@ function expectCallFromMatcher(node) {
|
|
|
20624
20735
|
const modifiers = [];
|
|
20625
20736
|
let receiver = node.object;
|
|
20626
20737
|
while (receiver.type === AST_NODE_TYPES98.MemberExpression) {
|
|
20627
|
-
const modifier =
|
|
20738
|
+
const modifier = ASTUtils60.getPropertyName(receiver);
|
|
20628
20739
|
if (modifier === null || !EXPECT_MODIFIERS.has(modifier)) return null;
|
|
20629
20740
|
modifiers.unshift(modifier);
|
|
20630
20741
|
receiver = receiver.object;
|
|
@@ -20700,7 +20811,7 @@ var repeated_static_call_cases_default = createRule({
|
|
|
20700
20811
|
});
|
|
20701
20812
|
|
|
20702
20813
|
// src/rules/prefer-zod-infer.ts
|
|
20703
|
-
import { ASTUtils as
|
|
20814
|
+
import { ASTUtils as ASTUtils61, AST_NODE_TYPES as AST_NODE_TYPES99 } from "@typescript-eslint/utils";
|
|
20704
20815
|
var PREFER_ZOD_INFER_DOCUMENTATION = {
|
|
20705
20816
|
summary: "Derive a type from its Zod schema with `z.infer` instead of hand-writing a twin declaration beside it.",
|
|
20706
20817
|
rationale: "A derived type stays synchronized when the runtime schema changes.",
|
|
@@ -21018,7 +21129,7 @@ function twinCallChain(node, zodNamespaces) {
|
|
|
21018
21129
|
while (current.type === AST_NODE_TYPES99.CallExpression) {
|
|
21019
21130
|
const callee = unwrapExpression(current.callee);
|
|
21020
21131
|
const calleeReceiver = callee.type === AST_NODE_TYPES99.MemberExpression ? unwrapExpression(callee.object) : callee;
|
|
21021
|
-
if (callee.type !== AST_NODE_TYPES99.MemberExpression ||
|
|
21132
|
+
if (callee.type !== AST_NODE_TYPES99.MemberExpression || ASTUtils61.getPropertyName(callee) === null) {
|
|
21022
21133
|
return null;
|
|
21023
21134
|
}
|
|
21024
21135
|
chain.push(current);
|
|
@@ -21031,7 +21142,7 @@ function twinCallChain(node, zodNamespaces) {
|
|
|
21031
21142
|
}
|
|
21032
21143
|
function twinMethodName(call) {
|
|
21033
21144
|
const callee = unwrapExpression(call.callee);
|
|
21034
|
-
return callee.type === AST_NODE_TYPES99.MemberExpression &&
|
|
21145
|
+
return callee.type === AST_NODE_TYPES99.MemberExpression && ASTUtils61.getPropertyName(callee) !== null ? ASTUtils61.getPropertyName(callee) ?? "" : "";
|
|
21035
21146
|
}
|
|
21036
21147
|
function twinSchemaFields(initializer, zodNamespaces) {
|
|
21037
21148
|
const chain = twinCallChain(initializer, zodNamespaces);
|
|
@@ -21046,7 +21157,7 @@ function twinSchemaFields(initializer, zodNamespaces) {
|
|
|
21046
21157
|
const fields = /* @__PURE__ */ new Map();
|
|
21047
21158
|
for (const property of shape.properties) {
|
|
21048
21159
|
if (property.type !== AST_NODE_TYPES99.Property) return null;
|
|
21049
|
-
const name =
|
|
21160
|
+
const name = ASTUtils61.getPropertyName(property);
|
|
21050
21161
|
if (name === null) return null;
|
|
21051
21162
|
fields.set(name, twinSchemaField(property.value, zodNamespaces));
|
|
21052
21163
|
}
|
|
@@ -21060,16 +21171,16 @@ function twinSchemaField(node, zodNamespaces) {
|
|
|
21060
21171
|
while (current.type === AST_NODE_TYPES99.CallExpression) {
|
|
21061
21172
|
const callee = unwrapExpression(current.callee);
|
|
21062
21173
|
const calleeReceiver = callee.type === AST_NODE_TYPES99.MemberExpression ? unwrapExpression(callee.object) : callee;
|
|
21063
|
-
if (callee.type !== AST_NODE_TYPES99.MemberExpression ||
|
|
21174
|
+
if (callee.type !== AST_NODE_TYPES99.MemberExpression || ASTUtils61.getPropertyName(callee) === null) {
|
|
21064
21175
|
break;
|
|
21065
21176
|
}
|
|
21066
21177
|
const receiver = calleeReceiver;
|
|
21067
21178
|
if (receiver.type === AST_NODE_TYPES99.Identifier && zodNamespaces.has(receiver.name)) {
|
|
21068
|
-
leaf =
|
|
21179
|
+
leaf = ASTUtils61.getPropertyName(callee) ?? "";
|
|
21069
21180
|
leafCall = current;
|
|
21070
21181
|
break;
|
|
21071
21182
|
}
|
|
21072
|
-
modifiers.push(
|
|
21183
|
+
modifiers.push(ASTUtils61.getPropertyName(callee) ?? "");
|
|
21073
21184
|
current = receiver;
|
|
21074
21185
|
}
|
|
21075
21186
|
return {
|
|
@@ -21272,7 +21383,7 @@ var prefer_zod_infer_default = createRule({
|
|
|
21272
21383
|
},
|
|
21273
21384
|
/** Records `XSchema.transform(...)` and equivalent module-level reshaping. */
|
|
21274
21385
|
"MemberExpression"(node) {
|
|
21275
|
-
if (node.object.type === AST_NODE_TYPES99.Identifier &&
|
|
21386
|
+
if (node.object.type === AST_NODE_TYPES99.Identifier && ASTUtils61.getPropertyName(node) !== null && isPreferZodInferModuleReshaper(ASTUtils61.getPropertyName(node) ?? "")) {
|
|
21276
21387
|
reshapedSchemaNames.add(node.object.name);
|
|
21277
21388
|
}
|
|
21278
21389
|
},
|
|
@@ -21429,7 +21540,7 @@ function staticFieldName(key) {
|
|
|
21429
21540
|
}
|
|
21430
21541
|
|
|
21431
21542
|
// src/rules/named-child-schema-type.ts
|
|
21432
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES100, ASTUtils as
|
|
21543
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES100, ASTUtils as ASTUtils62 } from "@typescript-eslint/utils";
|
|
21433
21544
|
var UNRESOLVED_TYPE_NODES = /* @__PURE__ */ new Set([
|
|
21434
21545
|
AST_NODE_TYPES100.TSTypeQuery,
|
|
21435
21546
|
AST_NODE_TYPES100.TSImportType,
|
|
@@ -21438,17 +21549,17 @@ var UNRESOLVED_TYPE_NODES = /* @__PURE__ */ new Set([
|
|
|
21438
21549
|
AST_NODE_TYPES100.TSUnknownKeyword
|
|
21439
21550
|
]);
|
|
21440
21551
|
var NAMED_CHILD_SCHEMA_TYPE_DOCUMENTATION = {
|
|
21441
|
-
defaultLevel: "
|
|
21552
|
+
defaultLevel: "error",
|
|
21442
21553
|
summary: "Reference a named Zod record child's complete schema type instead of repeating its explicit annotation.",
|
|
21443
21554
|
rationale: "Repeating a child schema's generic contract creates a second maintained declaration even though the record already uses that child at runtime.",
|
|
21444
|
-
remediation: "Replace only the matching record type argument with `typeof ChildSchema
|
|
21555
|
+
remediation: "Replace only the matching record type argument with `typeof ChildSchema`, or share one explicit named schema type alias between child and record to retain an independently named public contract. Keep the outer annotation required by isolatedDeclarations and every runtime schema operation.",
|
|
21445
21556
|
category: "maintainability",
|
|
21446
21557
|
autofix: "none",
|
|
21447
21558
|
limitations: [
|
|
21448
21559
|
"Only direct module-level const z.record calls with two arguments, a ZodRecord annotation, and an earlier local const child with a complete explicit Zod type are inspected.",
|
|
21449
21560
|
"The entire generic child annotation must match token for token; input/output, defaults, transforms, readonly modifiers and brands are never compared by output shape alone.",
|
|
21450
21561
|
"Bare leaf types, broad ZodType constraints, type queries, imported or unqualified type references, annotation cycles, comments on the repeated argument, mutable bindings and generated files are excluded.",
|
|
21451
|
-
"Import aliases and namespace imports resolve through scope bindings. Independent public contract pins
|
|
21562
|
+
"Import aliases and namespace imports resolve through scope bindings. Independent public contract pins can use one shared named type alias or an exact reasoned suppression; runtime validation and outer annotations are preserved."
|
|
21452
21563
|
],
|
|
21453
21564
|
examples: [
|
|
21454
21565
|
{ id: "named-child", title: "Reference the named child contract", outcome: "no-match", files: [{ path: "src/record.ts", source: 'import { z } from "zod"; const KeySchema: z.ZodEnum<{ a: "a"; b: "b" }> = z.enum(["a", "b"]); export const RecordSchema: z.ZodRecord<typeof KeySchema, z.ZodString> = z.record(KeySchema, z.string());' }], focusPath: "src/record.ts", expectedCount: 0, public: true },
|
|
@@ -21467,14 +21578,14 @@ var named_child_schema_type_default = createRule({
|
|
|
21467
21578
|
type: "suggestion",
|
|
21468
21579
|
docs: { description: NAMED_CHILD_SCHEMA_TYPE_DOCUMENTATION.summary },
|
|
21469
21580
|
schema: [],
|
|
21470
|
-
messages: { namedChildType: "Use `typeof {{name}}` for this exact child contract; keep the outer schema annotation and runtime operations." }
|
|
21581
|
+
messages: { namedChildType: "Use `typeof {{name}}` or one shared named type alias for this exact child contract; keep the outer schema annotation and runtime operations." }
|
|
21471
21582
|
},
|
|
21472
21583
|
defaultOptions: [],
|
|
21473
21584
|
create(context) {
|
|
21474
21585
|
const source = context.sourceCode;
|
|
21475
21586
|
if (isGeneratedFile(context.filename, source.text)) return {};
|
|
21476
21587
|
const namespaces = /* @__PURE__ */ new Set();
|
|
21477
|
-
const bindingOf = (node) =>
|
|
21588
|
+
const bindingOf = (node) => ASTUtils62.findVariable(source.getScope(node), node.name);
|
|
21478
21589
|
function namespaceOf(type) {
|
|
21479
21590
|
if (type.typeName.type !== AST_NODE_TYPES100.TSQualifiedName || type.typeName.left.type !== AST_NODE_TYPES100.Identifier) return null;
|
|
21480
21591
|
const binding = bindingOf(type.typeName.left);
|
|
@@ -21518,7 +21629,7 @@ var named_child_schema_type_default = createRule({
|
|
|
21518
21629
|
VariableDeclarator(node) {
|
|
21519
21630
|
if (!isModuleConst(node) || node.id.type !== AST_NODE_TYPES100.Identifier || node.init?.type !== AST_NODE_TYPES100.CallExpression) return;
|
|
21520
21631
|
const call = node.init;
|
|
21521
|
-
if (call.arguments.length !== 2 || call.callee.type !== AST_NODE_TYPES100.MemberExpression || call.callee.object.type !== AST_NODE_TYPES100.Identifier ||
|
|
21632
|
+
if (call.arguments.length !== 2 || call.callee.type !== AST_NODE_TYPES100.MemberExpression || call.callee.object.type !== AST_NODE_TYPES100.Identifier || ASTUtils62.getPropertyName(call.callee) !== "record") return;
|
|
21522
21633
|
const annotation = node.id.typeAnnotation?.typeAnnotation;
|
|
21523
21634
|
if (annotation?.type !== AST_NODE_TYPES100.TSTypeReference || annotation.typeName.type !== AST_NODE_TYPES100.TSQualifiedName || annotation.typeName.right.name !== "ZodRecord") return;
|
|
21524
21635
|
const namespace = namespaceOf(annotation);
|
|
@@ -21534,7 +21645,7 @@ var named_child_schema_type_default = createRule({
|
|
|
21534
21645
|
|
|
21535
21646
|
// src/rules/prefer-zod-parse-output-type.ts
|
|
21536
21647
|
import {
|
|
21537
|
-
ASTUtils as
|
|
21648
|
+
ASTUtils as ASTUtils63,
|
|
21538
21649
|
AST_NODE_TYPES as AST_NODE_TYPES101,
|
|
21539
21650
|
ESLintUtils as ESLintUtils14
|
|
21540
21651
|
} from "@typescript-eslint/utils";
|
|
@@ -21604,11 +21715,11 @@ function isLocalZodObjectSchema(node, namespaces) {
|
|
|
21604
21715
|
while (current.type === AST_NODE_TYPES101.CallExpression) {
|
|
21605
21716
|
const callee = unwrapExpression(current.callee);
|
|
21606
21717
|
const calleeReceiver = callee.type === AST_NODE_TYPES101.MemberExpression ? unwrapExpression(callee.object) : callee;
|
|
21607
|
-
if (callee.type !== AST_NODE_TYPES101.MemberExpression ||
|
|
21718
|
+
if (callee.type !== AST_NODE_TYPES101.MemberExpression || ASTUtils63.getPropertyName(callee) === null) {
|
|
21608
21719
|
return false;
|
|
21609
21720
|
}
|
|
21610
21721
|
if (calleeReceiver.type === AST_NODE_TYPES101.Identifier) {
|
|
21611
|
-
return namespaces.has(calleeReceiver.name) && ((
|
|
21722
|
+
return namespaces.has(calleeReceiver.name) && ((ASTUtils63.getPropertyName(callee) ?? "") === "object" || (ASTUtils63.getPropertyName(callee) ?? "") === "strictObject");
|
|
21612
21723
|
}
|
|
21613
21724
|
current = calleeReceiver;
|
|
21614
21725
|
}
|
|
@@ -21617,10 +21728,10 @@ function isLocalZodObjectSchema(node, namespaces) {
|
|
|
21617
21728
|
function zodParseCall(node) {
|
|
21618
21729
|
const callee = unwrapExpression(node.callee);
|
|
21619
21730
|
const calleeReceiver = callee.type === AST_NODE_TYPES101.MemberExpression ? unwrapExpression(callee.object) : callee;
|
|
21620
|
-
if (callee.type !== AST_NODE_TYPES101.MemberExpression || calleeReceiver.type !== AST_NODE_TYPES101.Identifier ||
|
|
21731
|
+
if (callee.type !== AST_NODE_TYPES101.MemberExpression || calleeReceiver.type !== AST_NODE_TYPES101.Identifier || ASTUtils63.getPropertyName(callee) === null) {
|
|
21621
21732
|
return null;
|
|
21622
21733
|
}
|
|
21623
|
-
const method =
|
|
21734
|
+
const method = ASTUtils63.getPropertyName(callee);
|
|
21624
21735
|
if (method !== "parse" && method !== "safeParse") return null;
|
|
21625
21736
|
return {
|
|
21626
21737
|
call: node,
|
|
@@ -21662,7 +21773,7 @@ function localParseReturnCandidates(node, sourceCode) {
|
|
|
21662
21773
|
for (const reference of variable.references) {
|
|
21663
21774
|
const identifier = reference.identifier;
|
|
21664
21775
|
const parent = identifier.parent;
|
|
21665
|
-
const output = parsed.method === "parse" ? identifier : parent.type === AST_NODE_TYPES101.MemberExpression && parent.object === identifier &&
|
|
21776
|
+
const output = parsed.method === "parse" ? identifier : parent.type === AST_NODE_TYPES101.MemberExpression && parent.object === identifier && ASTUtils63.getPropertyName(parent) !== null && (ASTUtils63.getPropertyName(parent) ?? "") === "data" ? parent : null;
|
|
21666
21777
|
if (output === null) continue;
|
|
21667
21778
|
const candidate2 = returnedOutputCandidate(parsed, output);
|
|
21668
21779
|
if (candidate2 !== null) candidates.push(candidate2);
|
|
@@ -22045,7 +22156,7 @@ var require_assert_never_default = createRule({
|
|
|
22045
22156
|
});
|
|
22046
22157
|
|
|
22047
22158
|
// src/rules/require-fetch-timeout.ts
|
|
22048
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES103, ASTUtils as
|
|
22159
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES103, ASTUtils as ASTUtils64 } from "@typescript-eslint/utils";
|
|
22049
22160
|
var REQUIRE_FETCH_TIMEOUT_DOCUMENTATION = {
|
|
22050
22161
|
summary: "Require an explicit abort signal on locally analyzable global fetch calls.",
|
|
22051
22162
|
rationale: "An unbounded request can occupy work indefinitely when an upstream stalls.",
|
|
@@ -22129,7 +22240,7 @@ var require_fetch_timeout_default = createRule({
|
|
|
22129
22240
|
}
|
|
22130
22241
|
function resolvesToGlobal(identifier) {
|
|
22131
22242
|
const scope = context.sourceCode.getScope(identifier);
|
|
22132
|
-
const variable =
|
|
22243
|
+
const variable = ASTUtils64.findVariable(scope, identifier.name);
|
|
22133
22244
|
return variable === null || variable.defs.length === 0;
|
|
22134
22245
|
}
|
|
22135
22246
|
function isGlobalFetchCall2(callee) {
|
|
@@ -22139,7 +22250,7 @@ var require_fetch_timeout_default = createRule({
|
|
|
22139
22250
|
return callee.type === AST_NODE_TYPES103.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES103.Identifier && callee.property.name === "fetch" && callee.object.type === AST_NODE_TYPES103.Identifier && GLOBAL_OBJECTS2.has(callee.object.name) && resolvesToGlobal(callee.object);
|
|
22140
22251
|
}
|
|
22141
22252
|
function localConstInitProvablyLacksSignal(identifier) {
|
|
22142
|
-
const variable =
|
|
22253
|
+
const variable = ASTUtils64.findVariable(
|
|
22143
22254
|
context.sourceCode.getScope(identifier),
|
|
22144
22255
|
identifier.name
|
|
22145
22256
|
);
|
|
@@ -22161,7 +22272,7 @@ var require_fetch_timeout_default = createRule({
|
|
|
22161
22272
|
function isForwardedRequest(argument) {
|
|
22162
22273
|
let value = argument;
|
|
22163
22274
|
if (value.type === AST_NODE_TYPES103.Identifier) {
|
|
22164
|
-
const binding =
|
|
22275
|
+
const binding = ASTUtils64.findVariable(context.sourceCode.getScope(value), value.name);
|
|
22165
22276
|
const definition = binding?.defs.length === 1 ? binding.defs[0] : void 0;
|
|
22166
22277
|
if (definition?.type !== "Variable" || definition.parent.kind !== "const" || definition.node.init === null || binding?.references.some((reference) => reference.isWrite() && reference.init !== true)) return false;
|
|
22167
22278
|
value = definition.node.init;
|
|
@@ -22336,7 +22447,7 @@ function exportedClasses(program, classes) {
|
|
|
22336
22447
|
}
|
|
22337
22448
|
|
|
22338
22449
|
// src/rules/require-sql-access-class.ts
|
|
22339
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES105, ASTUtils as
|
|
22450
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES105, ASTUtils as ASTUtils65 } from "@typescript-eslint/utils";
|
|
22340
22451
|
var DIRECT_EXECUTION_METHODS = /* @__PURE__ */ new Set([
|
|
22341
22452
|
"all",
|
|
22342
22453
|
"batch",
|
|
@@ -22443,7 +22554,7 @@ function databaseReceiver(node) {
|
|
|
22443
22554
|
if (node.type === AST_NODE_TYPES105.Identifier)
|
|
22444
22555
|
return DATABASE_NAMES.test(node.name);
|
|
22445
22556
|
if (node.type !== AST_NODE_TYPES105.MemberExpression) return false;
|
|
22446
|
-
const name =
|
|
22557
|
+
const name = ASTUtils65.getPropertyName(node);
|
|
22447
22558
|
return name === "DB" || name !== null && DATABASE_NAMES.test(name);
|
|
22448
22559
|
}
|
|
22449
22560
|
function databaseRootMember(node) {
|
|
@@ -22461,7 +22572,7 @@ function databaseRootMember(node) {
|
|
|
22461
22572
|
}
|
|
22462
22573
|
if (current.type === AST_NODE_TYPES105.MemberExpression) {
|
|
22463
22574
|
if (current.object.type === AST_NODE_TYPES105.ThisExpression)
|
|
22464
|
-
return
|
|
22575
|
+
return ASTUtils65.getPropertyName(current);
|
|
22465
22576
|
current = current.object;
|
|
22466
22577
|
continue;
|
|
22467
22578
|
}
|
|
@@ -22482,7 +22593,7 @@ function expressionHasDatabaseMarker(node) {
|
|
|
22482
22593
|
continue;
|
|
22483
22594
|
}
|
|
22484
22595
|
if (current.type === AST_NODE_TYPES105.MemberExpression) {
|
|
22485
|
-
const name =
|
|
22596
|
+
const name = ASTUtils65.getPropertyName(current);
|
|
22486
22597
|
if (name === "DB" || name !== null && DATABASE_NAMES.test(name))
|
|
22487
22598
|
return true;
|
|
22488
22599
|
current = current.object;
|
|
@@ -22501,7 +22612,7 @@ function expressionCallsBuilder(node) {
|
|
|
22501
22612
|
}
|
|
22502
22613
|
if (current.type === AST_NODE_TYPES105.CallExpression) {
|
|
22503
22614
|
if (current.callee.type !== AST_NODE_TYPES105.MemberExpression) return false;
|
|
22504
|
-
const name =
|
|
22615
|
+
const name = ASTUtils65.getPropertyName(current.callee);
|
|
22505
22616
|
if (name !== null && BUILDER_METHODS.has(name)) return true;
|
|
22506
22617
|
current = current.callee.object;
|
|
22507
22618
|
continue;
|
|
@@ -22552,7 +22663,7 @@ function thisRootMember(node) {
|
|
|
22552
22663
|
let current = node;
|
|
22553
22664
|
let root = null;
|
|
22554
22665
|
while (current.type === AST_NODE_TYPES105.MemberExpression) {
|
|
22555
|
-
const name =
|
|
22666
|
+
const name = ASTUtils65.getPropertyName(current);
|
|
22556
22667
|
if (name === null) return null;
|
|
22557
22668
|
root = name;
|
|
22558
22669
|
current = current.object;
|
|
@@ -22596,19 +22707,19 @@ var require_sql_access_class_default = createRule({
|
|
|
22596
22707
|
if (seen.has(node)) return false;
|
|
22597
22708
|
seen.add(node);
|
|
22598
22709
|
if (node.type === AST_NODE_TYPES105.Identifier) {
|
|
22599
|
-
const binding =
|
|
22710
|
+
const binding = ASTUtils65.findVariable(context.sourceCode.getScope(node), node.name);
|
|
22600
22711
|
if (binding?.defs.length !== 1 || binding.references.some((reference) => reference.isWrite() && reference.init !== true)) return false;
|
|
22601
22712
|
const definition = binding.defs[0];
|
|
22602
22713
|
return definition?.type === "Variable" && definition.node.init !== null && knownNonDatabase(definition.node.init, seen);
|
|
22603
22714
|
}
|
|
22604
|
-
return node.type === AST_NODE_TYPES105.NewExpression && unwrappedNodeCallee?.type === AST_NODE_TYPES105.Identifier && ["Map", "WeakMap", "URLSearchParams"].includes(unwrappedNodeCallee.name) && (
|
|
22715
|
+
return node.type === AST_NODE_TYPES105.NewExpression && unwrappedNodeCallee?.type === AST_NODE_TYPES105.Identifier && ["Map", "WeakMap", "URLSearchParams"].includes(unwrappedNodeCallee.name) && (ASTUtils65.findVariable(context.sourceCode.getScope(unwrappedNodeCallee), unwrappedNodeCallee.name)?.defs.length ?? 0) === 0;
|
|
22605
22716
|
}
|
|
22606
22717
|
return {
|
|
22607
22718
|
CallExpression(node) {
|
|
22608
22719
|
const unwrappedNodeCallee = unwrapExpression(node.callee);
|
|
22609
22720
|
if (unwrappedNodeCallee.type !== AST_NODE_TYPES105.MemberExpression)
|
|
22610
22721
|
return;
|
|
22611
|
-
const method =
|
|
22722
|
+
const method = ASTUtils65.getPropertyName(unwrappedNodeCallee);
|
|
22612
22723
|
if (knownNonDatabase(unwrappedNodeCallee.object)) return;
|
|
22613
22724
|
if (method === null || !isDatabaseOperation(method, unwrappedNodeCallee.object))
|
|
22614
22725
|
return;
|
|
@@ -22708,7 +22819,7 @@ var require_static_next_matcher_default = createRule({
|
|
|
22708
22819
|
});
|
|
22709
22820
|
|
|
22710
22821
|
// src/rules/require-use-form-default-values.ts
|
|
22711
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES107, ASTUtils as
|
|
22822
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES107, ASTUtils as ASTUtils66 } from "@typescript-eslint/utils";
|
|
22712
22823
|
var REQUIRE_USE_FORM_DEFAULT_VALUES_DOCUMENTATION = {
|
|
22713
22824
|
summary: "Require explicit form-level initialization or a field default for directly bound Controller fields.",
|
|
22714
22825
|
rationale: "React Hook Form exposes form-level defaultValues/values and field-level defaultValue as its explicit initialization mechanisms. A directly bound controlled field should not omit both mechanisms.",
|
|
@@ -22759,7 +22870,7 @@ var require_use_form_default_values_default = createRule({
|
|
|
22759
22870
|
const imported = /* @__PURE__ */ new Map();
|
|
22760
22871
|
const uninitializedForms = /* @__PURE__ */ new Set();
|
|
22761
22872
|
const uninitializedControls = /* @__PURE__ */ new Set();
|
|
22762
|
-
const bindingNamed = (node, name) =>
|
|
22873
|
+
const bindingNamed = (node, name) => ASTUtils66.findVariable(context.sourceCode.getScope(node), name);
|
|
22763
22874
|
const bindingOf = (node) => bindingNamed(node, node.name);
|
|
22764
22875
|
const stable = (variable) => !variable.references.some((reference) => reference.isWrite() && reference.init !== true);
|
|
22765
22876
|
const importedKind = (node) => {
|
|
@@ -22805,7 +22916,7 @@ var require_use_form_default_values_default = createRule({
|
|
|
22805
22916
|
const variable = bindingOf(node);
|
|
22806
22917
|
return variable !== null && stable(variable) && uninitializedControls.has(variable);
|
|
22807
22918
|
}
|
|
22808
|
-
return node.type === AST_NODE_TYPES107.MemberExpression &&
|
|
22919
|
+
return node.type === AST_NODE_TYPES107.MemberExpression && ASTUtils66.getPropertyName(node) !== null && (ASTUtils66.getPropertyName(node) ?? "") === "control" && isUninitializedForm(node.object);
|
|
22809
22920
|
};
|
|
22810
22921
|
const fieldOptionsNeedDefault = (node) => {
|
|
22811
22922
|
if (node?.type !== AST_NODE_TYPES107.ObjectExpression) return false;
|
|
@@ -22861,7 +22972,7 @@ var require_use_form_default_values_default = createRule({
|
|
|
22861
22972
|
trackDestructuredControl(node.id);
|
|
22862
22973
|
return;
|
|
22863
22974
|
}
|
|
22864
|
-
if (node.id.type === AST_NODE_TYPES107.Identifier && node.init.type === AST_NODE_TYPES107.MemberExpression &&
|
|
22975
|
+
if (node.id.type === AST_NODE_TYPES107.Identifier && node.init.type === AST_NODE_TYPES107.MemberExpression && ASTUtils66.getPropertyName(node.init) !== null && (ASTUtils66.getPropertyName(node.init) ?? "") === "control" && isUninitializedForm(node.init.object)) {
|
|
22865
22976
|
const variable = bindingOf(node.id);
|
|
22866
22977
|
if (variable !== null) uninitializedControls.add(variable);
|
|
22867
22978
|
}
|
|
@@ -22954,7 +23065,7 @@ var require_use_server_in_actions_file_default = createRule({
|
|
|
22954
23065
|
// src/rules/require-zod-form-validation.ts
|
|
22955
23066
|
import {
|
|
22956
23067
|
AST_NODE_TYPES as AST_NODE_TYPES108,
|
|
22957
|
-
ASTUtils as
|
|
23068
|
+
ASTUtils as ASTUtils67
|
|
22958
23069
|
} from "@typescript-eslint/utils";
|
|
22959
23070
|
var REQUIRE_ZOD_FORM_VALIDATION_DOCUMENTATION = {
|
|
22960
23071
|
summary: "Require Zod validation (`Schema.parse(...)` / `Schema.safeParse(...)`) when reading values out of a `FormData` object.",
|
|
@@ -23002,7 +23113,7 @@ var isFormDataMethodCall = (node) => {
|
|
|
23002
23113
|
}
|
|
23003
23114
|
if (current.type !== AST_NODE_TYPES108.CallExpression) return false;
|
|
23004
23115
|
const callee = unwrapExpression(current.callee);
|
|
23005
|
-
return callee.type === AST_NODE_TYPES108.MemberExpression &&
|
|
23116
|
+
return callee.type === AST_NODE_TYPES108.MemberExpression && ASTUtils67.getPropertyName(callee) === "formData";
|
|
23006
23117
|
};
|
|
23007
23118
|
var require_zod_form_validation_default = createRule({
|
|
23008
23119
|
name: "require-zod-form-validation",
|
|
@@ -23023,7 +23134,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
23023
23134
|
return {};
|
|
23024
23135
|
}
|
|
23025
23136
|
const zodBindings = /* @__PURE__ */ new Set();
|
|
23026
|
-
const resolvedBinding = (identifier) =>
|
|
23137
|
+
const resolvedBinding = (identifier) => ASTUtils67.findVariable(
|
|
23027
23138
|
context.sourceCode.getScope(identifier),
|
|
23028
23139
|
identifier.name
|
|
23029
23140
|
);
|
|
@@ -23031,7 +23142,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
23031
23142
|
const callee = unwrapExpression(node.callee);
|
|
23032
23143
|
const calleeReceiver = callee.type === AST_NODE_TYPES108.MemberExpression ? unwrapExpression(callee.object) : callee;
|
|
23033
23144
|
if (callee.type !== AST_NODE_TYPES108.MemberExpression) return false;
|
|
23034
|
-
if (
|
|
23145
|
+
if (ASTUtils67.getPropertyName(callee) === null || !FORM_VALUE_METHODS.has(ASTUtils67.getPropertyName(callee) ?? "")) {
|
|
23035
23146
|
return false;
|
|
23036
23147
|
}
|
|
23037
23148
|
return isFormSourceIdentifier(calleeReceiver);
|
|
@@ -23062,7 +23173,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
23062
23173
|
parent = parent.parent;
|
|
23063
23174
|
continue;
|
|
23064
23175
|
}
|
|
23065
|
-
if (parent.type === AST_NODE_TYPES108.CallExpression && parent.callee.type === AST_NODE_TYPES108.MemberExpression && parent.callee.object.type === AST_NODE_TYPES108.Identifier && parent.callee.object.name === "Object" &&
|
|
23176
|
+
if (parent.type === AST_NODE_TYPES108.CallExpression && parent.callee.type === AST_NODE_TYPES108.MemberExpression && parent.callee.object.type === AST_NODE_TYPES108.Identifier && parent.callee.object.name === "Object" && ASTUtils67.getPropertyName(parent.callee) === "fromEntries" && (resolvedBinding(parent.callee.object)?.defs.length ?? 0) === 0) {
|
|
23066
23177
|
parent = parent.parent;
|
|
23067
23178
|
continue;
|
|
23068
23179
|
}
|
|
@@ -23075,7 +23186,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
23075
23186
|
if (node.type !== AST_NODE_TYPES108.CallExpression) return false;
|
|
23076
23187
|
const callee = unwrapExpression(node.callee);
|
|
23077
23188
|
const calleeReceiver = callee.type === AST_NODE_TYPES108.MemberExpression ? unwrapExpression(callee.object) : callee;
|
|
23078
|
-
if (callee.type !== AST_NODE_TYPES108.MemberExpression ||
|
|
23189
|
+
if (callee.type !== AST_NODE_TYPES108.MemberExpression || ASTUtils67.getPropertyName(callee) === null || !ZOD_PARSE_METHODS.has(ASTUtils67.getPropertyName(callee) ?? "")) {
|
|
23079
23190
|
return false;
|
|
23080
23191
|
}
|
|
23081
23192
|
const root = zodReceiverRoot(calleeReceiver);
|
|
@@ -23161,7 +23272,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
23161
23272
|
};
|
|
23162
23273
|
const zodParseMethod = (call) => {
|
|
23163
23274
|
const callee = unwrapExpression(call.callee);
|
|
23164
|
-
return callee.type === AST_NODE_TYPES108.MemberExpression &&
|
|
23275
|
+
return callee.type === AST_NODE_TYPES108.MemberExpression && ASTUtils67.getPropertyName(callee) !== null ? ASTUtils67.getPropertyName(callee) ?? "" : null;
|
|
23165
23276
|
};
|
|
23166
23277
|
const isSafePrevalidationInspection = (identifier) => {
|
|
23167
23278
|
const parent = identifier.parent;
|
|
@@ -23337,7 +23448,7 @@ function expressionCallableName(current) {
|
|
|
23337
23448
|
}
|
|
23338
23449
|
|
|
23339
23450
|
// src/rules/stepdown.ts
|
|
23340
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES109, ASTUtils as
|
|
23451
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES109, ASTUtils as ASTUtils68 } from "@typescript-eslint/utils";
|
|
23341
23452
|
var STEPDOWN_DOCUMENTATION = {
|
|
23342
23453
|
summary: "Place a private helper below its sole direct same-scope caller.",
|
|
23343
23454
|
rationale: "Caller-first ordering lets a reader follow the main flow before descending into implementation details.",
|
|
@@ -23637,7 +23748,7 @@ function receiverOrigin(context, object, receivers) {
|
|
|
23637
23748
|
while (true) {
|
|
23638
23749
|
const unwrapped = unwrapExpression4(current);
|
|
23639
23750
|
if (unwrapped.type !== AST_NODE_TYPES109.Identifier) return unwrapped;
|
|
23640
|
-
const variable =
|
|
23751
|
+
const variable = ASTUtils68.findVariable(context.sourceCode.getScope(unwrapped), unwrapped.name);
|
|
23641
23752
|
if (variable === null) return null;
|
|
23642
23753
|
const known = receivers.get(variable);
|
|
23643
23754
|
if (known !== void 0) return known;
|
|
@@ -23818,11 +23929,11 @@ function classScope(context, node, computedReferences) {
|
|
|
23818
23929
|
function classReceiverBindings(context, node) {
|
|
23819
23930
|
const classReceivers = /* @__PURE__ */ new Map();
|
|
23820
23931
|
if (node.id !== null) {
|
|
23821
|
-
const internal =
|
|
23932
|
+
const internal = ASTUtils68.findVariable(context.sourceCode.getScope(node), node.id.name);
|
|
23822
23933
|
if (internal !== null && stableVariable(internal)) classReceivers.set(internal, true);
|
|
23823
23934
|
}
|
|
23824
23935
|
if (node.type === AST_NODE_TYPES109.ClassExpression && node.parent.type === AST_NODE_TYPES109.VariableDeclarator && node.parent.id.type === AST_NODE_TYPES109.Identifier && node.parent.parent.type === AST_NODE_TYPES109.VariableDeclaration && node.parent.parent.kind === "const") {
|
|
23825
|
-
const outer =
|
|
23936
|
+
const outer = ASTUtils68.findVariable(context.sourceCode.getScope(node.parent), node.parent.id.name);
|
|
23826
23937
|
if (outer !== null && stableVariable(outer)) classReceivers.set(outer, true);
|
|
23827
23938
|
}
|
|
23828
23939
|
return classReceivers;
|
|
@@ -23908,7 +24019,7 @@ function classMethodCounts(body2, methods) {
|
|
|
23908
24019
|
}
|
|
23909
24020
|
|
|
23910
24021
|
// src/rules/source-coupled-test.ts
|
|
23911
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES110, ASTUtils as
|
|
24022
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES110, ASTUtils as ASTUtils69 } from "@typescript-eslint/utils";
|
|
23912
24023
|
var GENERAL_SOURCE_SUFFIX_RE = /\.(?:bash|sh|ya?ml|jsonc?|toml|py|[cm]?[jt]s)$/iu;
|
|
23913
24024
|
var FS_MODULES = /* @__PURE__ */ new Set(["fs", "node:fs", "fs/promises", "node:fs/promises"]);
|
|
23914
24025
|
var FS_READERS = /* @__PURE__ */ new Set(["readFile", "readFileSync"]);
|
|
@@ -24025,7 +24136,7 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
|
|
|
24025
24136
|
const scopes = [newScope()];
|
|
24026
24137
|
const reportedOrigins = /* @__PURE__ */ new Set();
|
|
24027
24138
|
const currentScope = () => scopes.at(-1) ?? scopes[0];
|
|
24028
|
-
const bindingOf = (node) =>
|
|
24139
|
+
const bindingOf = (node) => ASTUtils69.findVariable(context.sourceCode.getScope(node), node.name);
|
|
24029
24140
|
const assertionKind = (node) => {
|
|
24030
24141
|
const binding = bindingOf(node);
|
|
24031
24142
|
if (binding === null || binding.defs.length === 0) {
|
|
@@ -24078,7 +24189,7 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
|
|
|
24078
24189
|
return visible("fsReaders", callee) && sourcePath(current.arguments[0]);
|
|
24079
24190
|
}
|
|
24080
24191
|
if (callee.type !== AST_NODE_TYPES110.MemberExpression) return false;
|
|
24081
|
-
const name2 =
|
|
24192
|
+
const name2 = ASTUtils69.getPropertyName(callee);
|
|
24082
24193
|
const object = unwrap6(calleeReceiver);
|
|
24083
24194
|
return name2 !== null && FS_READERS.has(name2) && object.type === AST_NODE_TYPES110.Identifier && visible("fsObjects", object) && sourcePath(current.arguments[0]);
|
|
24084
24195
|
};
|
|
@@ -24087,12 +24198,12 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
|
|
|
24087
24198
|
if (current.type === AST_NODE_TYPES110.Identifier) return visibleRawOrigins(current);
|
|
24088
24199
|
if (rawRead(current)) return /* @__PURE__ */ new Set([`${current.range[0]}:${current.range[1]}`]);
|
|
24089
24200
|
if (current.type === AST_NODE_TYPES110.BinaryExpression && current.operator === "+") return /* @__PURE__ */ new Set([...rawOrigins(current.left), ...rawOrigins(current.right)]);
|
|
24090
|
-
if (current.type === AST_NODE_TYPES110.MemberExpression &&
|
|
24201
|
+
if (current.type === AST_NODE_TYPES110.MemberExpression && ASTUtils69.getPropertyName(current) === "length") return rawOrigins(current.object);
|
|
24091
24202
|
if (current.type !== AST_NODE_TYPES110.CallExpression) return /* @__PURE__ */ new Set();
|
|
24092
24203
|
const callee = unwrap6(current.callee);
|
|
24093
24204
|
const calleeReceiver = callee.type === AST_NODE_TYPES110.MemberExpression ? unwrapExpression(callee.object) : callee;
|
|
24094
24205
|
if (callee.type !== AST_NODE_TYPES110.MemberExpression) return /* @__PURE__ */ new Set();
|
|
24095
|
-
const name2 =
|
|
24206
|
+
const name2 = ASTUtils69.getPropertyName(callee);
|
|
24096
24207
|
return name2 !== null && TEXT_TRANSFORMS.has(name2) ? rawOrigins(calleeReceiver) : /* @__PURE__ */ new Set();
|
|
24097
24208
|
};
|
|
24098
24209
|
const evidenceOrigins = (node) => {
|
|
@@ -24105,7 +24216,7 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
|
|
|
24105
24216
|
const callee = unwrap6(current.callee);
|
|
24106
24217
|
const calleeReceiver = callee.type === AST_NODE_TYPES110.MemberExpression ? unwrapExpression(callee.object) : callee;
|
|
24107
24218
|
if (callee.type !== AST_NODE_TYPES110.MemberExpression) return /* @__PURE__ */ new Set();
|
|
24108
|
-
const name2 =
|
|
24219
|
+
const name2 = ASTUtils69.getPropertyName(callee);
|
|
24109
24220
|
if (name2 !== null && TEXT_PREDICATES.has(name2)) return rawOrigins(calleeReceiver);
|
|
24110
24221
|
if (name2 !== null && REGEXP_PREDICATES.has(name2)) return new Set(current.arguments.flatMap((argument) => argument.type === AST_NODE_TYPES110.SpreadElement ? [] : [...rawOrigins(argument)]));
|
|
24111
24222
|
return /* @__PURE__ */ new Set();
|
|
@@ -24117,10 +24228,10 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
|
|
|
24117
24228
|
return new Set(node.arguments.flatMap((argument) => argument.type === AST_NODE_TYPES110.SpreadElement ? [] : [...evidenceOrigins(argument)]));
|
|
24118
24229
|
}
|
|
24119
24230
|
if (callee.type !== AST_NODE_TYPES110.MemberExpression) return /* @__PURE__ */ new Set();
|
|
24120
|
-
const matcher =
|
|
24231
|
+
const matcher = ASTUtils69.getPropertyName(callee);
|
|
24121
24232
|
if (matcher === null) return /* @__PURE__ */ new Set();
|
|
24122
24233
|
let receiver = unwrap6(calleeReceiver);
|
|
24123
|
-
while (receiver.type === AST_NODE_TYPES110.MemberExpression && EXPECT_MODIFIERS2.has(
|
|
24234
|
+
while (receiver.type === AST_NODE_TYPES110.MemberExpression && EXPECT_MODIFIERS2.has(ASTUtils69.getPropertyName(receiver) ?? "")) receiver = unwrap6(receiver.object);
|
|
24124
24235
|
const expectCallee = receiver.type === AST_NODE_TYPES110.CallExpression ? unwrapExpression(receiver.callee) : null;
|
|
24125
24236
|
if (receiver.type === AST_NODE_TYPES110.CallExpression && expectCallee?.type === AST_NODE_TYPES110.Identifier && assertionKind(expectCallee) === "expect") {
|
|
24126
24237
|
if (!EXPECT_MATCHERS.has(matcher)) return /* @__PURE__ */ new Set();
|
|
@@ -24403,7 +24514,7 @@ var iac_source_coupled_test_default = createSourceCoupledRule(
|
|
|
24403
24514
|
// src/rules/require-pascal-case-zod-schema-name.ts
|
|
24404
24515
|
import {
|
|
24405
24516
|
AST_NODE_TYPES as AST_NODE_TYPES112,
|
|
24406
|
-
ASTUtils as
|
|
24517
|
+
ASTUtils as ASTUtils70
|
|
24407
24518
|
} from "@typescript-eslint/utils";
|
|
24408
24519
|
var REQUIRE_PASCAL_CASE_ZOD_SCHEMA_NAME_DOCUMENTATION = {
|
|
24409
24520
|
summary: "Require confirmed module-level Zod schema contracts to use PascalCase with a `Schema` suffix.",
|
|
@@ -24536,7 +24647,7 @@ var SCHEMA_RETURNING_METHODS = /* @__PURE__ */ new Set([
|
|
|
24536
24647
|
"superRefine",
|
|
24537
24648
|
"transform"
|
|
24538
24649
|
]);
|
|
24539
|
-
var terminalMethodName = (callee) =>
|
|
24650
|
+
var terminalMethodName = (callee) => ASTUtils70.getPropertyName(callee) !== null ? ASTUtils70.getPropertyName(callee) ?? "" : null;
|
|
24540
24651
|
var calleeChainRoot2 = (node) => {
|
|
24541
24652
|
let current = node;
|
|
24542
24653
|
for (; ; ) {
|
|
@@ -24561,8 +24672,8 @@ var chainMemberNames2 = (node) => {
|
|
|
24561
24672
|
for (; ; ) {
|
|
24562
24673
|
current = unwrapExpression(current);
|
|
24563
24674
|
if (current.type === AST_NODE_TYPES112.MemberExpression) {
|
|
24564
|
-
if (
|
|
24565
|
-
names.push(
|
|
24675
|
+
if (ASTUtils70.getPropertyName(current) === null) return [];
|
|
24676
|
+
names.push(ASTUtils70.getPropertyName(current) ?? "");
|
|
24566
24677
|
current = current.object;
|
|
24567
24678
|
continue;
|
|
24568
24679
|
}
|
|
@@ -24599,7 +24710,7 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
24599
24710
|
const zodBindings = /* @__PURE__ */ new Set();
|
|
24600
24711
|
const schemaBindings = /* @__PURE__ */ new Set();
|
|
24601
24712
|
function resolvedBinding(identifier) {
|
|
24602
|
-
return
|
|
24713
|
+
return ASTUtils70.findVariable(
|
|
24603
24714
|
context.sourceCode.getScope(identifier),
|
|
24604
24715
|
identifier.name
|
|
24605
24716
|
);
|
|
@@ -24880,7 +24991,6 @@ var LIBRARY_IMPORT_POLICY = ["error", {
|
|
|
24880
24991
|
}];
|
|
24881
24992
|
var ADVISORY_RULES = [
|
|
24882
24993
|
"@sarj/excessive-commentary",
|
|
24883
|
-
"@sarj/named-child-schema-type",
|
|
24884
24994
|
"@sarj/no-bespoke-api-case-conversion",
|
|
24885
24995
|
"@sarj/no-duplicate-test-case",
|
|
24886
24996
|
"@sarj/no-json-stringify-object-equality",
|
|
@@ -24889,21 +24999,18 @@ var ADVISORY_RULES = [
|
|
|
24889
24999
|
"@sarj/prefer-millisecond-control-duration-schema",
|
|
24890
25000
|
"@sarj/prefer-module-level-refined-schema",
|
|
24891
25001
|
"@sarj/prefer-multi-value-zod-literal",
|
|
24892
|
-
"@sarj/prefer-named-complex-return-type",
|
|
24893
25002
|
"@sarj/prefer-node-crypto-hash",
|
|
24894
25003
|
"@sarj/prefer-node-fs-promises",
|
|
24895
25004
|
"@sarj/prefer-nominal-id-types",
|
|
24896
25005
|
"@sarj/prefer-shared-zod-enum",
|
|
24897
|
-
"@sarj/prefer-switch-for-repeated-equality",
|
|
24898
25006
|
"@sarj/prefer-whole-object-assertion",
|
|
24899
25007
|
"@sarj/require-camelcase-properties",
|
|
24900
|
-
"@sarj/require-explicit-contract-implementation",
|
|
24901
25008
|
"@sarj/require-explicit-service-contract",
|
|
24902
25009
|
"@sarj/require-interface-for-exported-class",
|
|
24903
25010
|
"@sarj/require-sql-access-class"
|
|
24904
25011
|
];
|
|
24905
25012
|
var RECOMMENDED_RULES = {
|
|
24906
|
-
"@sarj/named-child-schema-type": "
|
|
25013
|
+
"@sarj/named-child-schema-type": "error",
|
|
24907
25014
|
"@sarj/no-conditional-empty-object-spread": "error",
|
|
24908
25015
|
"@sarj/prefer-typed-reflection": "error",
|
|
24909
25016
|
"@sarj/no-broad-return-type": "error",
|
|
@@ -24987,7 +25094,7 @@ var RECOMMENDED_RULES = {
|
|
|
24987
25094
|
"@sarj/prefer-multi-value-zod-literal": ["warn", { zodMajorVersion: 4 }],
|
|
24988
25095
|
"@sarj/prefer-named-callback-domain": "error",
|
|
24989
25096
|
"@sarj/prefer-nominal-id-types": "warn",
|
|
24990
|
-
"@sarj/prefer-named-complex-return-type": "
|
|
25097
|
+
"@sarj/prefer-named-complex-return-type": "error",
|
|
24991
25098
|
"@sarj/prefer-node-crypto-hash": "warn",
|
|
24992
25099
|
"@sarj/prefer-node-fs-promises": "warn",
|
|
24993
25100
|
"@sarj/prefer-non-nullable-collection": "error",
|
|
@@ -24995,7 +25102,7 @@ var RECOMMENDED_RULES = {
|
|
|
24995
25102
|
"@sarj/prefer-await-in-async-return": "error",
|
|
24996
25103
|
"@sarj/prefer-schema-for-api-payload": "error",
|
|
24997
25104
|
"@sarj/prefer-shared-zod-enum": "warn",
|
|
24998
|
-
"@sarj/prefer-switch-for-repeated-equality": "
|
|
25105
|
+
"@sarj/prefer-switch-for-repeated-equality": "error",
|
|
24999
25106
|
"@sarj/prefer-semantic-colors": ["error", { requireSemanticTokens: true }],
|
|
25000
25107
|
"@sarj/prefer-server-actions": "error",
|
|
25001
25108
|
"@sarj/prefer-whole-object-assertion": "warn",
|
|
@@ -25004,7 +25111,7 @@ var RECOMMENDED_RULES = {
|
|
|
25004
25111
|
"@sarj/prefer-zod-parse-output-type": "error",
|
|
25005
25112
|
"@sarj/require-assert-never": "error",
|
|
25006
25113
|
"@sarj/require-fetch-timeout": "error",
|
|
25007
|
-
"@sarj/require-explicit-contract-implementation": "
|
|
25114
|
+
"@sarj/require-explicit-contract-implementation": "error",
|
|
25008
25115
|
"@sarj/require-explicit-service-contract": "warn",
|
|
25009
25116
|
"@sarj/require-interface-for-exported-class": "warn",
|
|
25010
25117
|
"@sarj/require-port-for-service": "error",
|
|
@@ -25021,7 +25128,7 @@ var RECOMMENDED_RULES = {
|
|
|
25021
25128
|
"@sarj/require-pascal-case-zod-schema-name": "error"
|
|
25022
25129
|
};
|
|
25023
25130
|
var STRICT_RULES = {
|
|
25024
|
-
"@sarj/named-child-schema-type": "
|
|
25131
|
+
"@sarj/named-child-schema-type": "error",
|
|
25025
25132
|
"@sarj/no-conditional-empty-object-spread": "error",
|
|
25026
25133
|
"@sarj/prefer-typed-reflection": "error",
|
|
25027
25134
|
"@sarj/no-broad-return-type": "error",
|
|
@@ -25109,7 +25216,7 @@ var STRICT_RULES = {
|
|
|
25109
25216
|
"@sarj/prefer-multi-value-zod-literal": ["warn", { zodMajorVersion: 4 }],
|
|
25110
25217
|
"@sarj/prefer-named-callback-domain": "error",
|
|
25111
25218
|
"@sarj/prefer-nominal-id-types": "warn",
|
|
25112
|
-
"@sarj/prefer-named-complex-return-type": "
|
|
25219
|
+
"@sarj/prefer-named-complex-return-type": "error",
|
|
25113
25220
|
"@sarj/prefer-node-crypto-hash": "warn",
|
|
25114
25221
|
"@sarj/prefer-node-fs-promises": "warn",
|
|
25115
25222
|
"@sarj/prefer-non-nullable-collection": "error",
|
|
@@ -25117,7 +25224,7 @@ var STRICT_RULES = {
|
|
|
25117
25224
|
"@sarj/prefer-await-in-async-return": "error",
|
|
25118
25225
|
"@sarj/prefer-schema-for-api-payload": "error",
|
|
25119
25226
|
"@sarj/prefer-shared-zod-enum": "warn",
|
|
25120
|
-
"@sarj/prefer-switch-for-repeated-equality": "
|
|
25227
|
+
"@sarj/prefer-switch-for-repeated-equality": "error",
|
|
25121
25228
|
"@sarj/prefer-semantic-colors": ["error", { requireSemanticTokens: true }],
|
|
25122
25229
|
"@sarj/prefer-server-actions": "error",
|
|
25123
25230
|
"@sarj/prefer-whole-object-assertion": "warn",
|
|
@@ -25126,7 +25233,7 @@ var STRICT_RULES = {
|
|
|
25126
25233
|
"@sarj/prefer-zod-parse-output-type": "error",
|
|
25127
25234
|
"@sarj/require-assert-never": "error",
|
|
25128
25235
|
"@sarj/require-fetch-timeout": "error",
|
|
25129
|
-
"@sarj/require-explicit-contract-implementation": "
|
|
25236
|
+
"@sarj/require-explicit-contract-implementation": "error",
|
|
25130
25237
|
"@sarj/require-explicit-service-contract": "warn",
|
|
25131
25238
|
"@sarj/require-interface-for-exported-class": "warn",
|
|
25132
25239
|
"@sarj/require-port-for-service": "error",
|