@sarj/eslint-plugin 15.14.0 → 15.16.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.js CHANGED
@@ -1223,8 +1223,8 @@ function testCallMatrixStems(comments) {
1223
1223
  const stems = /* @__PURE__ */ new Set();
1224
1224
  for (const comment of comments) {
1225
1225
  const body2 = stripCommentMarker(comment.value);
1226
- const stem3 = CALL_LABEL_RE.exec(body2)?.[1];
1227
- if (stem3 !== void 0 && MULTIPLIER_PSEUDOCODE_RE.test(body2)) stems.add(stem3);
1226
+ const stem4 = CALL_LABEL_RE.exec(body2)?.[1];
1227
+ if (stem4 !== void 0 && MULTIPLIER_PSEUDOCODE_RE.test(body2)) stems.add(stem4);
1228
1228
  }
1229
1229
  return stems;
1230
1230
  }
@@ -4010,8 +4010,8 @@ function privateMemberFixes(context, services, owner, members, removePrivateKeyw
4010
4010
  return;
4011
4011
  }
4012
4012
  if (node.type !== AST_NODE_TYPES14.MemberExpression) return;
4013
- const propertyName5 = node.property.type === AST_NODE_TYPES14.Identifier || node.property.type === AST_NODE_TYPES14.PrivateIdentifier ? node.property.name : node.property.type === AST_NODE_TYPES14.Literal && typeof node.property.value === "string" ? node.property.value : null;
4014
- if (propertyName5 !== name) return;
4013
+ const propertyName7 = node.property.type === AST_NODE_TYPES14.Identifier || node.property.type === AST_NODE_TYPES14.PrivateIdentifier ? node.property.name : node.property.type === AST_NODE_TYPES14.Literal && typeof node.property.value === "string" ? node.property.value : null;
4014
+ if (propertyName7 !== name) return;
4015
4015
  const propertySymbol = symbolAt(services, checker, node.property);
4016
4016
  if (node.computed || node.property.type !== AST_NODE_TYPES14.Identifier || node.object.type !== AST_NODE_TYPES14.ThisExpression || enclosingClass(node) !== owner || !symbols.some((symbol) => sameSymbol(symbol, propertySymbol))) {
4017
4017
  unsafe = true;
@@ -4883,8 +4883,8 @@ var CJS_OBJECT_EXPORT_METHODS = /* @__PURE__ */ new Set(["assign", "defineProper
4883
4883
  function fileParts(filename) {
4884
4884
  const base = filename.replaceAll("\\", "/").split("/").at(-1) ?? "";
4885
4885
  const extension = base.match(/(\.[cm]?[jt]sx?)$/u)?.[1] ?? ".ts";
4886
- const [stem3 = "", ...suffixes] = base.slice(0, -extension.length).split(".");
4887
- return { stem: stem3, suffixes: suffixes.map((suffix) => suffix.toLowerCase()) };
4886
+ const [stem4 = "", ...suffixes] = base.slice(0, -extension.length).split(".");
4887
+ return { stem: stem4, suffixes: suffixes.map((suffix) => suffix.toLowerCase()) };
4888
4888
  }
4889
4889
  function declaredNames(declaration) {
4890
4890
  if (declaration.declare === true) return [];
@@ -5008,8 +5008,8 @@ var no_generic_single_export_module_default = createRule({
5008
5008
  defaultOptions: [],
5009
5009
  create(context) {
5010
5010
  const file = fileParts(context.filename);
5011
- const { stem: stem3 } = file;
5012
- if (!GENERIC_STEMS.has(stem3) || isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
5011
+ const { stem: stem4 } = file;
5012
+ if (!GENERIC_STEMS.has(stem4) || isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
5013
5013
  let hasCommonJsExport = false;
5014
5014
  return {
5015
5015
  CallExpression(node) {
@@ -5029,12 +5029,12 @@ var no_generic_single_export_module_default = createRule({
5029
5029
  const { name: exported, node } = onlyExport;
5030
5030
  if (isConventionalFrameworkUtility(context.filename, exported)) return;
5031
5031
  const exportedRole = exported.replaceAll(/[^a-z0-9]/giu, "").toLowerCase();
5032
- const pathRole = [stem3, ...file.suffixes].join("").replaceAll(/[^a-z0-9]/giu, "");
5032
+ const pathRole = [stem4, ...file.suffixes].join("").replaceAll(/[^a-z0-9]/giu, "");
5033
5033
  if (exportedRole === pathRole && file.suffixes.length > 0) return;
5034
5034
  context.report({
5035
5035
  node,
5036
5036
  messageId: "genericSingleExport",
5037
- data: { stem: stem3, exported }
5037
+ data: { stem: stem4, exported }
5038
5038
  });
5039
5039
  }
5040
5040
  };
@@ -5351,7 +5351,7 @@ var no_positional_tuple_return_default = createRule({
5351
5351
  const aliases = typeAliases(context.sourceCode.ast);
5352
5352
  const reportedFunctions = /* @__PURE__ */ new WeakSet();
5353
5353
  const functionStack = [];
5354
- const report = (annotation, name) => {
5354
+ const report2 = (annotation, name) => {
5355
5355
  const tuple = tupleReturnType(annotation, aliases);
5356
5356
  if (tuple === null || tuple.elementTypes.length < MIN_ELEMENTS) return;
5357
5357
  context.report({
@@ -5385,7 +5385,7 @@ var no_positional_tuple_return_default = createRule({
5385
5385
  if (name === null) {
5386
5386
  return;
5387
5387
  }
5388
- report(annotation, name);
5388
+ report2(annotation, name);
5389
5389
  };
5390
5390
  const enterFunction = (node) => {
5391
5391
  functionStack.push(node);
@@ -5410,34 +5410,34 @@ var no_positional_tuple_return_default = createRule({
5410
5410
  },
5411
5411
  TSDeclareFunction(node) {
5412
5412
  if (node.id === null || node.returnType === void 0 || node.parent.type !== AST_NODE_TYPES21.ExportNamedDeclaration && node.parent.type !== AST_NODE_TYPES21.ExportDefaultDeclaration && !specifierExports.has(node.id.name)) return;
5413
- report(node.returnType.typeAnnotation, node.id.name);
5413
+ report2(node.returnType.typeAnnotation, node.id.name);
5414
5414
  },
5415
5415
  TSCallSignatureDeclaration(node) {
5416
5416
  const owner = owningInterface(node);
5417
5417
  if (owner === null || !isExportedInterface(owner, typeExports) || node.returnType === void 0) return;
5418
- report(node.returnType.typeAnnotation, `${owner.id.name}.call`);
5418
+ report2(node.returnType.typeAnnotation, `${owner.id.name}.call`);
5419
5419
  },
5420
5420
  TSMethodSignature(node) {
5421
5421
  const owner = owningInterface(node);
5422
5422
  const alias = owningTypeAlias(node);
5423
- const memberName3 = staticMemberName3(node.key);
5424
- if ((owner === null || !isExportedInterface(owner, typeExports)) && (alias === null || !typeExports.has(alias.id.name)) || node.returnType === void 0 || memberName3 === null) return;
5425
- report(node.returnType.typeAnnotation, `${owner?.id.name ?? alias?.id.name ?? "type"}.${memberName3}`);
5423
+ const memberName6 = staticMemberName3(node.key);
5424
+ if ((owner === null || !isExportedInterface(owner, typeExports)) && (alias === null || !typeExports.has(alias.id.name)) || node.returnType === void 0 || memberName6 === null) return;
5425
+ report2(node.returnType.typeAnnotation, `${owner?.id.name ?? alias?.id.name ?? "type"}.${memberName6}`);
5426
5426
  },
5427
5427
  TSTypeAliasDeclaration(node) {
5428
5428
  if (!typeExports.has(node.id.name)) return;
5429
5429
  const returnType = callableReturnType(node.typeAnnotation, aliases);
5430
- if (returnType !== null) report(returnType, node.id.name);
5430
+ if (returnType !== null) report2(returnType, node.id.name);
5431
5431
  },
5432
5432
  TSPropertySignature(node) {
5433
5433
  const owner = owningInterface(node);
5434
5434
  const alias = owningTypeAlias(node);
5435
5435
  const annotation = node.typeAnnotation?.typeAnnotation;
5436
- const memberName3 = staticMemberName3(node.key);
5437
- if ((owner === null || !isExportedInterface(owner, typeExports)) && (alias === null || !typeExports.has(alias.id.name)) || memberName3 === null || annotation === void 0) return;
5436
+ const memberName6 = staticMemberName3(node.key);
5437
+ if ((owner === null || !isExportedInterface(owner, typeExports)) && (alias === null || !typeExports.has(alias.id.name)) || memberName6 === null || annotation === void 0) return;
5438
5438
  const returnType = callableReturnType(annotation, aliases);
5439
5439
  if (returnType !== null) {
5440
- report(returnType, `${owner?.id.name ?? alias?.id.name ?? "type"}.${memberName3}`);
5440
+ report2(returnType, `${owner?.id.name ?? alias?.id.name ?? "type"}.${memberName6}`);
5441
5441
  }
5442
5442
  },
5443
5443
  PropertyDefinition(node) {
@@ -5448,7 +5448,7 @@ var no_positional_tuple_return_default = createRule({
5448
5448
  const returnType = callableReturnType(annotation, aliases);
5449
5449
  if (returnType !== null) {
5450
5450
  const name = node.key.type === AST_NODE_TYPES21.Identifier ? node.key.name : "property";
5451
- report(returnType, name);
5451
+ report2(returnType, name);
5452
5452
  }
5453
5453
  }
5454
5454
  };
@@ -5924,7 +5924,7 @@ var no_restricted_library_load_default = createRule({
5924
5924
  defaultOptions: [{ libraries: [] }],
5925
5925
  create(context, [options]) {
5926
5926
  const restrictions = options.libraries;
5927
- function report(node, source) {
5927
+ function report2(node, source) {
5928
5928
  const restriction = restrictions.find(
5929
5929
  (entry) => matchesModule(source, entry.module)
5930
5930
  );
@@ -5950,7 +5950,7 @@ var no_restricted_library_load_default = createRule({
5950
5950
  return {
5951
5951
  ImportExpression(node) {
5952
5952
  const source = literalModule(node.source);
5953
- if (source !== null) report(node.source, source);
5953
+ if (source !== null) report2(node.source, source);
5954
5954
  },
5955
5955
  CallExpression(node) {
5956
5956
  let requireIdentifier = null;
@@ -5961,12 +5961,12 @@ var no_restricted_library_load_default = createRule({
5961
5961
  }
5962
5962
  if (requireIdentifier === null || !isUnshadowedRequire(requireIdentifier)) return;
5963
5963
  const source = literalModule(node.arguments[0]);
5964
- if (source !== null) report(node.arguments[0], source);
5964
+ if (source !== null) report2(node.arguments[0], source);
5965
5965
  },
5966
5966
  TSImportEqualsDeclaration(node) {
5967
5967
  if (node.moduleReference.type !== AST_NODE_TYPES23.TSExternalModuleReference) return;
5968
5968
  const source = literalModule(node.moduleReference.expression);
5969
- if (source !== null) report(node.moduleReference.expression, source);
5969
+ if (source !== null) report2(node.moduleReference.expression, source);
5970
5970
  }
5971
5971
  };
5972
5972
  }
@@ -7782,7 +7782,7 @@ var no_sleep_in_test_body_default = createRule({
7782
7782
  if (!isTestFile(context.filename)) {
7783
7783
  return {};
7784
7784
  }
7785
- const report = (node) => {
7785
+ const report2 = (node) => {
7786
7786
  if (!isImmediatelyConsumedSleep(node)) {
7787
7787
  return;
7788
7788
  }
@@ -7795,12 +7795,12 @@ var no_sleep_in_test_body_default = createRule({
7795
7795
  return {
7796
7796
  NewExpression(node) {
7797
7797
  if (isPromiseSleep(node)) {
7798
- report(node);
7798
+ report2(node);
7799
7799
  }
7800
7800
  },
7801
7801
  CallExpression(node) {
7802
7802
  if (isHelperSleep(node)) {
7803
- report(node);
7803
+ report2(node);
7804
7804
  }
7805
7805
  }
7806
7806
  };
@@ -10251,7 +10251,7 @@ function reportClass2(context, services, owner) {
10251
10251
  }
10252
10252
  function isConvertible(member) {
10253
10253
  if (member.type !== AST_NODE_TYPES43.MethodDefinition && member.type !== AST_NODE_TYPES43.PropertyDefinition && member.type !== AST_NODE_TYPES43.AccessorProperty) return false;
10254
- return member.accessibility === "private" && !member.computed && member.key.type === AST_NODE_TYPES43.Identifier && member.decorators.length === 0 && !("declare" in member && member.declare) && !member.override && !(member.type === AST_NODE_TYPES43.MethodDefinition && member.value.body === null);
10254
+ return member.accessibility === "private" && !(member.type === AST_NODE_TYPES43.MethodDefinition && member.kind === "constructor") && !member.computed && member.key.type === AST_NODE_TYPES43.Identifier && member.decorators.length === 0 && !("declare" in member && member.declare) && !member.override && !(member.type === AST_NODE_TYPES43.MethodDefinition && member.value.body === null);
10255
10255
  }
10256
10256
  var prefer_ecmascript_private_members_default = createRule({
10257
10257
  name: "prefer-ecmascript-private-members",
@@ -10449,9 +10449,9 @@ var INPUT_MODULE = /(?:^|\/)components\/ui\/input$/u;
10449
10449
  var INPUT_GROUP_MODULE = /(?:^|\/)components\/ui\/input-group$/u;
10450
10450
  var MAX_JSX_DISTANCE = 2;
10451
10451
  var SEARCH_EXPORTS = ["Search", "SearchIcon", "LucideSearch"];
10452
- function localNamedImports(node, importedName6) {
10452
+ function localNamedImports(node, importedName7) {
10453
10453
  return node.specifiers.filter(
10454
- (specifier) => specifier.type === AST_NODE_TYPES45.ImportSpecifier && (specifier.imported.type === AST_NODE_TYPES45.Identifier ? specifier.imported.name : specifier.imported.value) === importedName6
10454
+ (specifier) => specifier.type === AST_NODE_TYPES45.ImportSpecifier && (specifier.imported.type === AST_NODE_TYPES45.Identifier ? specifier.imported.name : specifier.imported.value) === importedName7
10455
10455
  ).map((specifier) => specifier.local.name);
10456
10456
  }
10457
10457
  function elementName(node) {
@@ -11664,8 +11664,67 @@ var prefer_module_level_schema_default = createRule({
11664
11664
  }
11665
11665
  });
11666
11666
 
11667
+ // src/rules/prefer-named-complex-return-type.ts
11668
+ import { AST_NODE_TYPES as AST_NODE_TYPES50 } from "@typescript-eslint/utils";
11669
+ var PREFER_NAMED_COMPLEX_RETURN_TYPE_DOCUMENTATION = {
11670
+ summary: "Prefer a named contract for structurally complex function return types.",
11671
+ rationale: "A large inline return annotation hides a reusable domain concept and makes signatures difficult to scan.",
11672
+ remediation: "Extract the return annotation to a named type or interface and reference that contract from the signature.",
11673
+ category: "maintainability",
11674
+ limitations: [
11675
+ "Only explicit object types with at least three members and unions with at least three object variants are reported.",
11676
+ "Generic wrappers such as Promise and Readonly are unwrapped one level at a time; inferred return types are outside this rule."
11677
+ ],
11678
+ examples: [
11679
+ { 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 },
11680
+ { id: "inline-result", title: "Do not inline a multi-state result", outcome: "match", files: [{ path: "src/queue.ts", source: "export function claim(): { state: 'idle' } | { state: 'waiting'; retryAt: number } | { state: 'claimed'; id: string } { return { state: 'idle' }; }" }], focusPath: "src/queue.ts", expectedCount: 1, public: true }
11681
+ ]
11682
+ };
11683
+ function unwrap4(node) {
11684
+ if (node.type === AST_NODE_TYPES50.TSTypeReference && node.typeArguments?.params.length === 1) {
11685
+ const [inner] = node.typeArguments.params;
11686
+ if (inner !== void 0) return unwrap4(inner);
11687
+ }
11688
+ return node;
11689
+ }
11690
+ function report(context, node) {
11691
+ const annotation = node.returnType?.typeAnnotation;
11692
+ if (annotation !== void 0 && isComplex(annotation)) {
11693
+ context.report({ node: annotation, messageId: "nameComplexReturnType" });
11694
+ }
11695
+ }
11696
+ function isComplex(node) {
11697
+ const type = unwrap4(node);
11698
+ if (type.type === AST_NODE_TYPES50.TSTypeLiteral) return type.members.length >= 3;
11699
+ if (type.type !== AST_NODE_TYPES50.TSUnionType || type.types.length < 3) return false;
11700
+ return type.types.every((member) => unwrap4(member).type === AST_NODE_TYPES50.TSTypeLiteral);
11701
+ }
11702
+ var prefer_named_complex_return_type_default = createRule({
11703
+ name: "prefer-named-complex-return-type",
11704
+ documentation: PREFER_NAMED_COMPLEX_RETURN_TYPE_DOCUMENTATION,
11705
+ meta: {
11706
+ type: "suggestion",
11707
+ docs: { description: "Prefer a named contract for structurally complex function return types." },
11708
+ schema: [],
11709
+ messages: {
11710
+ nameComplexReturnType: "Extract this structurally complex return annotation to a named type or interface."
11711
+ }
11712
+ },
11713
+ defaultOptions: [],
11714
+ create(context) {
11715
+ if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
11716
+ return {
11717
+ ArrowFunctionExpression: (node) => report(context, node),
11718
+ FunctionDeclaration: (node) => report(context, node),
11719
+ FunctionExpression: (node) => report(context, node),
11720
+ TSDeclareFunction: (node) => report(context, node),
11721
+ TSMethodSignature: (node) => report(context, node)
11722
+ };
11723
+ }
11724
+ });
11725
+
11667
11726
  // src/rules/prefer-native-random-uuid.ts
11668
- import { AST_NODE_TYPES as AST_NODE_TYPES50, ASTUtils as ASTUtils14 } from "@typescript-eslint/utils";
11727
+ import { AST_NODE_TYPES as AST_NODE_TYPES51, ASTUtils as ASTUtils14 } from "@typescript-eslint/utils";
11669
11728
  var PREFER_NATIVE_RANDOM_UUID_DOCUMENTATION = {
11670
11729
  summary: "Prefer `globalThis.crypto.randomUUID()` over resolved zero-argument UUID v4 bindings from the `uuid` package.",
11671
11730
  rationale: "The platform implementation avoids an unnecessary dependency for standard random UUID generation.",
@@ -11679,7 +11738,7 @@ var PREFER_NATIVE_RANDOM_UUID_DOCUMENTATION = {
11679
11738
  ]
11680
11739
  };
11681
11740
  function requireUuid(node) {
11682
- return node?.type === AST_NODE_TYPES50.CallExpression && node.callee.type === AST_NODE_TYPES50.Identifier && node.callee.name === "require" && node.arguments.length === 1 && node.arguments[0]?.type === AST_NODE_TYPES50.Literal && node.arguments[0].value === "uuid";
11741
+ return node?.type === AST_NODE_TYPES51.CallExpression && node.callee.type === AST_NODE_TYPES51.Identifier && node.callee.name === "require" && node.arguments.length === 1 && node.arguments[0]?.type === AST_NODE_TYPES51.Literal && node.arguments[0].value === "uuid";
11683
11742
  }
11684
11743
  var prefer_native_random_uuid_default = createRule({
11685
11744
  name: "prefer-native-random-uuid",
@@ -11707,7 +11766,7 @@ var prefer_native_random_uuid_default = createRule({
11707
11766
  const variable = resolve(identifier);
11708
11767
  if (variable !== null) destination.add(variable);
11709
11768
  }
11710
- function report(node) {
11769
+ function report2(node) {
11711
11770
  context.report({
11712
11771
  node,
11713
11772
  messageId: "preferNative",
@@ -11723,48 +11782,291 @@ var prefer_native_random_uuid_default = createRule({
11723
11782
  ImportDeclaration(node) {
11724
11783
  if (node.source.value !== "uuid") return;
11725
11784
  for (const specifier of node.specifiers) {
11726
- if (specifier.type === AST_NODE_TYPES50.ImportSpecifier && (specifier.imported.type === AST_NODE_TYPES50.Identifier ? specifier.imported.name === "v4" : specifier.imported.value === "v4")) {
11785
+ if (specifier.type === AST_NODE_TYPES51.ImportSpecifier && (specifier.imported.type === AST_NODE_TYPES51.Identifier ? specifier.imported.name === "v4" : specifier.imported.value === "v4")) {
11727
11786
  record(specifier.local, directBindings);
11728
- } else if (specifier.type === AST_NODE_TYPES50.ImportNamespaceSpecifier) {
11787
+ } else if (specifier.type === AST_NODE_TYPES51.ImportNamespaceSpecifier) {
11729
11788
  record(specifier.local, namespaceBindings);
11730
11789
  }
11731
11790
  }
11732
11791
  },
11733
11792
  VariableDeclarator(node) {
11734
11793
  if (node.parent.kind !== "const" || !requireUuid(node.init)) return;
11735
- if (node.init?.type !== AST_NODE_TYPES50.CallExpression || node.init.callee.type !== AST_NODE_TYPES50.Identifier || (resolve(node.init.callee)?.defs.length ?? 0) > 0) {
11794
+ if (node.init?.type !== AST_NODE_TYPES51.CallExpression || node.init.callee.type !== AST_NODE_TYPES51.Identifier || (resolve(node.init.callee)?.defs.length ?? 0) > 0) {
11736
11795
  return;
11737
11796
  }
11738
- if (node.id.type === AST_NODE_TYPES50.Identifier) {
11797
+ if (node.id.type === AST_NODE_TYPES51.Identifier) {
11739
11798
  record(node.id, namespaceBindings);
11740
11799
  return;
11741
11800
  }
11742
- if (node.id.type !== AST_NODE_TYPES50.ObjectPattern) return;
11801
+ if (node.id.type !== AST_NODE_TYPES51.ObjectPattern) return;
11743
11802
  for (const property of node.id.properties) {
11744
- if (property.type === AST_NODE_TYPES50.Property && !property.computed && (property.key.type === AST_NODE_TYPES50.Identifier && property.key.name === "v4" || property.key.type === AST_NODE_TYPES50.Literal && property.key.value === "v4") && property.value.type === AST_NODE_TYPES50.Identifier) {
11803
+ if (property.type === AST_NODE_TYPES51.Property && !property.computed && (property.key.type === AST_NODE_TYPES51.Identifier && property.key.name === "v4" || property.key.type === AST_NODE_TYPES51.Literal && property.key.value === "v4") && property.value.type === AST_NODE_TYPES51.Identifier) {
11745
11804
  record(property.value, directBindings);
11746
11805
  }
11747
11806
  }
11748
11807
  },
11749
11808
  "CallExpression:exit"(node) {
11750
11809
  if (node.arguments.length !== 0) return;
11751
- if (node.callee.type === AST_NODE_TYPES50.Identifier) {
11810
+ if (node.callee.type === AST_NODE_TYPES51.Identifier) {
11752
11811
  const variable2 = resolve(node.callee);
11753
- if (variable2 !== null && directBindings.has(variable2)) report(node);
11812
+ if (variable2 !== null && directBindings.has(variable2)) report2(node);
11754
11813
  return;
11755
11814
  }
11756
- if (node.callee.type !== AST_NODE_TYPES50.MemberExpression || node.callee.computed || node.callee.object.type !== AST_NODE_TYPES50.Identifier || node.callee.property.type !== AST_NODE_TYPES50.Identifier || node.callee.property.name !== "v4") {
11815
+ if (node.callee.type !== AST_NODE_TYPES51.MemberExpression || node.callee.computed || node.callee.object.type !== AST_NODE_TYPES51.Identifier || node.callee.property.type !== AST_NODE_TYPES51.Identifier || node.callee.property.name !== "v4") {
11757
11816
  return;
11758
11817
  }
11759
11818
  const variable = resolve(node.callee.object);
11760
- if (variable !== null && namespaceBindings.has(variable)) report(node);
11819
+ if (variable !== null && namespaceBindings.has(variable)) report2(node);
11820
+ }
11821
+ };
11822
+ }
11823
+ });
11824
+
11825
+ // src/rules/prefer-node-crypto-hash.ts
11826
+ import { AST_NODE_TYPES as AST_NODE_TYPES52, ASTUtils as ASTUtils15 } from "@typescript-eslint/utils";
11827
+ var PREFER_NODE_CRYPTO_HASH_DOCUMENTATION = {
11828
+ summary: "Prefer the modern one-shot node:crypto hash API when streaming state is unnecessary.",
11829
+ rationale: "A createHash-update-digest chain allocates mutable streaming state for a single in-memory value; Node's built-in hash function expresses the one-shot operation directly and can use its optimized fast path.",
11830
+ remediation: "Import hash from node:crypto and replace a single-update chain with hash(algorithm, value, encoding). Keep createHash for streams or multiple incremental updates.",
11831
+ category: "performance",
11832
+ limitations: [
11833
+ "Only bindings and inline calls with statically proven provenance from crypto or node:crypto are analyzed; arbitrary assignments and dynamic module specifiers are excluded.",
11834
+ "Only a literal algorithm with exactly one update call is reported; streaming and incremental hashes remain valid."
11835
+ ],
11836
+ examples: [
11837
+ { id: "one-shot-hash", title: "Use Node's one-shot hash API", outcome: "no-match", files: [{ path: "case.ts", source: "import { hash } from 'node:crypto'; export const digest = hash('sha256', 'value', 'hex');" }], focusPath: "case.ts", expectedCount: 0, public: true },
11838
+ { id: "mutable-one-shot-chain", title: "Avoid mutable state for one value", outcome: "match", files: [{ path: "case.ts", source: "import { createHash } from 'node:crypto'; export const digest = createHash('sha256').update('value').digest('hex');" }], focusPath: "case.ts", expectedCount: 1, public: true }
11839
+ ]
11840
+ };
11841
+ function memberName3(node) {
11842
+ if (!node.computed && node.property.type === AST_NODE_TYPES52.Identifier) return node.property.name;
11843
+ if (node.computed && node.property.type === AST_NODE_TYPES52.Literal && typeof node.property.value === "string") {
11844
+ return node.property.value;
11845
+ }
11846
+ return null;
11847
+ }
11848
+ function isCryptoLoader(node, resolve) {
11849
+ if (node.type !== AST_NODE_TYPES52.CallExpression || node.arguments.length !== 1) return false;
11850
+ const [argument] = node.arguments;
11851
+ if (argument === void 0 || argument.type === AST_NODE_TYPES52.SpreadElement || !isCryptoSpecifier(argument)) {
11852
+ return false;
11853
+ }
11854
+ if (node.callee.type === AST_NODE_TYPES52.Identifier) {
11855
+ return node.callee.name === "require" && isUnshadowedBuiltinIdentifier(node.callee, resolve);
11856
+ }
11857
+ return node.callee.type === AST_NODE_TYPES52.MemberExpression && node.callee.object.type === AST_NODE_TYPES52.Identifier && node.callee.object.name === "process" && isUnshadowedBuiltinIdentifier(node.callee.object, resolve) && memberName3(node.callee) === "getBuiltinModule";
11858
+ }
11859
+ function isCryptoSpecifier(node) {
11860
+ return node.type === AST_NODE_TYPES52.Literal && (node.value === "crypto" || node.value === "node:crypto");
11861
+ }
11862
+ function isUnshadowedBuiltinIdentifier(identifier, resolve) {
11863
+ const variable = resolve(identifier);
11864
+ return variable === null || variable.defs.length === 0;
11865
+ }
11866
+ function propertyName3(node) {
11867
+ if (!node.computed && node.key.type === AST_NODE_TYPES52.Identifier) return node.key.name;
11868
+ if (node.key.type === AST_NODE_TYPES52.Literal && typeof node.key.value === "string") {
11869
+ return node.key.value;
11870
+ }
11871
+ return null;
11872
+ }
11873
+ var prefer_node_crypto_hash_default = createRule({
11874
+ name: "prefer-node-crypto-hash",
11875
+ documentation: PREFER_NODE_CRYPTO_HASH_DOCUMENTATION,
11876
+ meta: { type: "problem", docs: { description: PREFER_NODE_CRYPTO_HASH_DOCUMENTATION.summary }, schema: [], messages: { preferNodeCryptoHash: "Prefer the modern one-shot node:crypto hash API when streaming state is unnecessary." } },
11877
+ defaultOptions: [],
11878
+ create(context) {
11879
+ const directBindings = /* @__PURE__ */ new Set();
11880
+ const namespaceBindings = /* @__PURE__ */ new Set();
11881
+ function resolve(identifier) {
11882
+ return ASTUtils15.findVariable(
11883
+ context.sourceCode.getScope(identifier),
11884
+ identifier.name
11885
+ );
11886
+ }
11887
+ function record(identifier, destination) {
11888
+ const variable = resolve(identifier);
11889
+ if (variable !== null) destination.add(variable);
11890
+ }
11891
+ return {
11892
+ ImportDeclaration(node) {
11893
+ if (node.source.value !== "crypto" && node.source.value !== "node:crypto") return;
11894
+ for (const specifier of node.specifiers) {
11895
+ if (specifier.type === AST_NODE_TYPES52.ImportNamespaceSpecifier || specifier.type === AST_NODE_TYPES52.ImportDefaultSpecifier) {
11896
+ record(specifier.local, namespaceBindings);
11897
+ } else if (specifier.type === AST_NODE_TYPES52.ImportSpecifier && importedName5(specifier.imported) === "createHash") {
11898
+ record(specifier.local, directBindings);
11899
+ }
11900
+ }
11901
+ },
11902
+ VariableDeclarator(node) {
11903
+ if (node.parent.kind !== "const" || node.init === null || !isCryptoLoader(node.init, resolve)) {
11904
+ return;
11905
+ }
11906
+ if (node.id.type === AST_NODE_TYPES52.Identifier) {
11907
+ record(node.id, namespaceBindings);
11908
+ return;
11909
+ }
11910
+ if (node.id.type !== AST_NODE_TYPES52.ObjectPattern) return;
11911
+ for (const property of node.id.properties) {
11912
+ if (property.type === AST_NODE_TYPES52.Property && propertyName3(property) === "createHash" && property.value.type === AST_NODE_TYPES52.Identifier) {
11913
+ record(property.value, directBindings);
11914
+ }
11915
+ }
11916
+ },
11917
+ CallExpression(node) {
11918
+ if (!isMemberCall(node, "digest")) return;
11919
+ const update = node.callee.object;
11920
+ if (update.type !== AST_NODE_TYPES52.CallExpression || update.arguments.length !== 1 || !isMemberCall(update, "update"))
11921
+ return;
11922
+ const create = update.callee.object;
11923
+ if (create.type !== AST_NODE_TYPES52.CallExpression || create.arguments.length !== 1 || create.arguments[0]?.type !== AST_NODE_TYPES52.Literal || typeof create.arguments[0].value !== "string" || !isCreateHashCall(
11924
+ create,
11925
+ directBindings,
11926
+ namespaceBindings,
11927
+ resolve
11928
+ ))
11929
+ return;
11930
+ context.report({ node, messageId: "preferNodeCryptoHash" });
11931
+ }
11932
+ };
11933
+ }
11934
+ });
11935
+ function importedName5(node) {
11936
+ return node.type === AST_NODE_TYPES52.Identifier ? node.name : node.value;
11937
+ }
11938
+ function isMemberCall(node, name) {
11939
+ return node.callee.type === AST_NODE_TYPES52.MemberExpression && memberName3(node.callee) === name;
11940
+ }
11941
+ function isCreateHashCall(node, directBindings, namespaceBindings, resolve) {
11942
+ if (node.callee.type === AST_NODE_TYPES52.Identifier) {
11943
+ const variable2 = resolve(node.callee);
11944
+ return variable2 !== null && directBindings.has(variable2);
11945
+ }
11946
+ if (node.callee.type !== AST_NODE_TYPES52.MemberExpression || memberName3(node.callee) !== "createHash") {
11947
+ return false;
11948
+ }
11949
+ if (isCryptoLoader(node.callee.object, resolve)) return true;
11950
+ if (node.callee.object.type !== AST_NODE_TYPES52.Identifier) return false;
11951
+ const variable = resolve(node.callee.object);
11952
+ return variable !== null && namespaceBindings.has(variable);
11953
+ }
11954
+
11955
+ // src/rules/prefer-node-fs-promises.ts
11956
+ import { AST_NODE_TYPES as AST_NODE_TYPES53 } from "@typescript-eslint/utils";
11957
+ var PREFER_NODE_FS_PROMISES_DOCUMENTATION = {
11958
+ summary: "Prefer promise-based Node.js filesystem APIs over synchronous calls in production modules.",
11959
+ rationale: "Synchronous filesystem work blocks the event loop and can stall unrelated daemon, server, and worker tasks.",
11960
+ remediation: "Import the promise API from node:fs/promises and await it; use FileHandle.sync only where a documented durability boundary requires it.",
11961
+ category: "performance",
11962
+ limitations: [
11963
+ "Tests and generated files are excluded.",
11964
+ "ESLint rule implementations under src/rules are excluded because visitor creation and execution are synchronous by contract.",
11965
+ "Only statically identifiable node:fs loads are inspected; filesystem objects passed through arbitrary functions or assignments require type-aware analysis."
11966
+ ],
11967
+ examples: [
11968
+ { id: "async-read", title: "Use the promise API", outcome: "no-match", files: [{ path: "src/store.ts", source: "import { readFile } from 'node:fs/promises'; export async function load(path: string) { return readFile(path, 'utf8'); }" }], focusPath: "src/store.ts", expectedCount: 0, public: true },
11969
+ { id: "sync-read", title: "Do not block on a synchronous read", outcome: "match", files: [{ path: "src/store.ts", source: "import { readFileSync } from 'node:fs'; export function load(path: string) { return readFileSync(path, 'utf8'); }" }], focusPath: "src/store.ts", expectedCount: 1, public: true }
11970
+ ]
11971
+ };
11972
+ function memberName4(node) {
11973
+ if (!node.computed && node.property.type === AST_NODE_TYPES53.Identifier) return node.property.name;
11974
+ if (node.computed && node.property.type === AST_NODE_TYPES53.Literal && typeof node.property.value === "string") {
11975
+ return node.property.value;
11976
+ }
11977
+ return null;
11978
+ }
11979
+ function unwrapAwait2(node) {
11980
+ return node.type === AST_NODE_TYPES53.AwaitExpression ? node.argument : node;
11981
+ }
11982
+ function isFsLoader(node) {
11983
+ const expression = unwrapAwait2(node);
11984
+ if (expression.type === AST_NODE_TYPES53.ImportExpression) return isFsSpecifier(expression.source);
11985
+ if (expression.type !== AST_NODE_TYPES53.CallExpression || expression.arguments.length !== 1) return false;
11986
+ const [argument] = expression.arguments;
11987
+ if (argument === void 0 || argument.type === AST_NODE_TYPES53.SpreadElement || !isFsSpecifier(argument)) return false;
11988
+ if (expression.callee.type === AST_NODE_TYPES53.Identifier) return expression.callee.name === "require";
11989
+ return expression.callee.type === AST_NODE_TYPES53.MemberExpression && expression.callee.object.type === AST_NODE_TYPES53.Identifier && expression.callee.object.name === "process" && memberName4(expression.callee) === "getBuiltinModule";
11990
+ }
11991
+ function isFsSpecifier(node) {
11992
+ return node.type === AST_NODE_TYPES53.Literal && (node.value === "node:fs" || node.value === "fs");
11993
+ }
11994
+ function propertyName4(node) {
11995
+ if (!node.computed && node.key.type === AST_NODE_TYPES53.Identifier) return node.key.name;
11996
+ if (node.key.type === AST_NODE_TYPES53.Literal && typeof node.key.value === "string") return node.key.value;
11997
+ return null;
11998
+ }
11999
+ var prefer_node_fs_promises_default = createRule({
12000
+ name: "prefer-node-fs-promises",
12001
+ documentation: PREFER_NODE_FS_PROMISES_DOCUMENTATION,
12002
+ meta: {
12003
+ type: "suggestion",
12004
+ docs: { description: "Prefer promise-based Node.js filesystem APIs over synchronous calls in production modules." },
12005
+ schema: [],
12006
+ messages: {
12007
+ preferAsyncFs: "Node filesystem API `{{name}}` is synchronous; use the promise API and await it."
12008
+ }
12009
+ },
12010
+ defaultOptions: [],
12011
+ create(context) {
12012
+ const normalizedFilename = context.filename.replaceAll("\\", "/");
12013
+ if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text) || normalizedFilename.includes("src/rules/"))
12014
+ return {};
12015
+ const namespaces = /* @__PURE__ */ new Set();
12016
+ return {
12017
+ ImportDeclaration(node) {
12018
+ if (node.source.value !== "node:fs" && node.source.value !== "fs") return;
12019
+ const synchronousImports = [];
12020
+ for (const specifier of node.specifiers) {
12021
+ if (specifier.type === AST_NODE_TYPES53.ImportNamespaceSpecifier || specifier.type === AST_NODE_TYPES53.ImportDefaultSpecifier) {
12022
+ namespaces.add(specifier.local.name);
12023
+ continue;
12024
+ }
12025
+ if (specifier.type === AST_NODE_TYPES53.ImportSpecifier && specifier.imported.type === AST_NODE_TYPES53.Identifier && specifier.imported.name.endsWith("Sync")) synchronousImports.push(specifier.imported.name);
12026
+ }
12027
+ if (synchronousImports.length > 0) {
12028
+ context.report({
12029
+ node,
12030
+ messageId: "preferAsyncFs",
12031
+ data: { name: synchronousImports.join(", ") }
12032
+ });
12033
+ }
12034
+ },
12035
+ VariableDeclarator(node) {
12036
+ if (node.init === null || !isFsLoader(node.init) && (node.init.type !== AST_NODE_TYPES53.Identifier || !namespaces.has(node.init.name)))
12037
+ return;
12038
+ if (node.id.type === AST_NODE_TYPES53.Identifier) {
12039
+ namespaces.add(node.id.name);
12040
+ return;
12041
+ }
12042
+ if (node.id.type !== AST_NODE_TYPES53.ObjectPattern) return;
12043
+ const synchronousImports = node.id.properties.flatMap((property) => {
12044
+ if (property.type !== AST_NODE_TYPES53.Property) return [];
12045
+ const name = propertyName4(property);
12046
+ return name?.endsWith("Sync") === true ? [name] : [];
12047
+ });
12048
+ if (synchronousImports.length > 0) {
12049
+ context.report({
12050
+ node,
12051
+ messageId: "preferAsyncFs",
12052
+ data: { name: synchronousImports.join(", ") }
12053
+ });
12054
+ }
12055
+ },
12056
+ MemberExpression(node) {
12057
+ const name = memberName4(node);
12058
+ if (name?.endsWith("Sync") !== true) return;
12059
+ const object = unwrapAwait2(node.object);
12060
+ if (object.type === AST_NODE_TYPES53.Identifier && namespaces.has(object.name) || isFsLoader(object)) {
12061
+ context.report({ node, messageId: "preferAsyncFs", data: { name } });
12062
+ }
11761
12063
  }
11762
12064
  };
11763
12065
  }
11764
12066
  });
11765
12067
 
11766
12068
  // src/rules/prefer-non-nullable-collection.ts
11767
- import { AST_NODE_TYPES as AST_NODE_TYPES51, ASTUtils as ASTUtils15 } from "@typescript-eslint/utils";
12069
+ import { AST_NODE_TYPES as AST_NODE_TYPES54, ASTUtils as ASTUtils16 } from "@typescript-eslint/utils";
11768
12070
  var PREFER_NON_NULLABLE_COLLECTION_DOCUMENTATION = {
11769
12071
  summary: "Suggest non-null arrays only when local control flow proves the nullish state is equivalent to an empty collection.",
11770
12072
  rationale: "A redundant nullish collection state spreads defaults and guards through consumers without carrying information.",
@@ -11777,36 +12079,36 @@ var PREFER_NON_NULLABLE_COLLECTION_DOCUMENTATION = {
11777
12079
  ]
11778
12080
  };
11779
12081
  var ARRAY_TYPE_NAMES = /* @__PURE__ */ new Set(["Array", "ReadonlyArray"]);
11780
- function propertyName3(node) {
12082
+ function propertyName5(node) {
11781
12083
  const key = node.key;
11782
12084
  if (node.computed) return null;
11783
- if (key.type === AST_NODE_TYPES51.Identifier) return key.name;
11784
- if (key.type === AST_NODE_TYPES51.Literal && typeof key.value === "string") return key.value;
12085
+ if (key.type === AST_NODE_TYPES54.Identifier) return key.name;
12086
+ if (key.type === AST_NODE_TYPES54.Literal && typeof key.value === "string") return key.value;
11785
12087
  return null;
11786
12088
  }
11787
12089
  function isArrayType(node) {
11788
- if (node.type === AST_NODE_TYPES51.TSArrayType) return true;
11789
- return node.type === AST_NODE_TYPES51.TSTypeReference && node.typeName.type === AST_NODE_TYPES51.Identifier && ARRAY_TYPE_NAMES.has(node.typeName.name);
12090
+ if (node.type === AST_NODE_TYPES54.TSArrayType) return true;
12091
+ return node.type === AST_NODE_TYPES54.TSTypeReference && node.typeName.type === AST_NODE_TYPES54.Identifier && ARRAY_TYPE_NAMES.has(node.typeName.name);
11790
12092
  }
11791
12093
  function nullableProperty(node) {
11792
12094
  if (node.optional) return null;
11793
- const name = propertyName3(node);
12095
+ const name = propertyName5(node);
11794
12096
  const annotation = node.typeAnnotation?.typeAnnotation;
11795
- if (name === null || annotation?.type !== AST_NODE_TYPES51.TSUnionType) return null;
12097
+ if (name === null || annotation?.type !== AST_NODE_TYPES54.TSUnionType) return null;
11796
12098
  const concrete = annotation.types.filter(
11797
- (member) => member.type !== AST_NODE_TYPES51.TSNullKeyword && member.type !== AST_NODE_TYPES51.TSUndefinedKeyword
12099
+ (member) => member.type !== AST_NODE_TYPES54.TSNullKeyword && member.type !== AST_NODE_TYPES54.TSUndefinedKeyword
11798
12100
  );
11799
12101
  if (concrete.length === 0 || !concrete.every(isArrayType)) return null;
11800
- const acceptsNull = annotation.types.some((member) => member.type === AST_NODE_TYPES51.TSNullKeyword);
12102
+ const acceptsNull = annotation.types.some((member) => member.type === AST_NODE_TYPES54.TSNullKeyword);
11801
12103
  const acceptsUndefined = annotation.types.some(
11802
- (member) => member.type === AST_NODE_TYPES51.TSUndefinedKeyword
12104
+ (member) => member.type === AST_NODE_TYPES54.TSUndefinedKeyword
11803
12105
  );
11804
12106
  if (!acceptsNull && !acceptsUndefined) return null;
11805
12107
  return { name, node, acceptsNull, acceptsUndefined };
11806
12108
  }
11807
12109
  function shapeProperties(members) {
11808
12110
  return members.flatMap((member) => {
11809
- if (member.type !== AST_NODE_TYPES51.TSPropertySignature) return [];
12111
+ if (member.type !== AST_NODE_TYPES54.TSPropertySignature) return [];
11810
12112
  const property = nullableProperty(member);
11811
12113
  return property === null ? [] : [property];
11812
12114
  });
@@ -11814,14 +12116,14 @@ function shapeProperties(members) {
11814
12116
  function typeIndex(program) {
11815
12117
  const index = /* @__PURE__ */ new Map();
11816
12118
  for (const statement of program.body) {
11817
- const exported = statement.type === AST_NODE_TYPES51.ExportNamedDeclaration;
12119
+ const exported = statement.type === AST_NODE_TYPES54.ExportNamedDeclaration;
11818
12120
  const declaration = exported ? statement.declaration : statement;
11819
- if (declaration?.type === AST_NODE_TYPES51.TSInterfaceDeclaration) {
12121
+ if (declaration?.type === AST_NODE_TYPES54.TSInterfaceDeclaration) {
11820
12122
  index.set(declaration.id.name, {
11821
12123
  exported,
11822
12124
  properties: shapeProperties(declaration.body.body)
11823
12125
  });
11824
- } else if (declaration?.type === AST_NODE_TYPES51.TSTypeAliasDeclaration && declaration.typeAnnotation.type === AST_NODE_TYPES51.TSTypeLiteral) {
12126
+ } else if (declaration?.type === AST_NODE_TYPES54.TSTypeAliasDeclaration && declaration.typeAnnotation.type === AST_NODE_TYPES54.TSTypeLiteral) {
11825
12127
  index.set(declaration.id.name, {
11826
12128
  exported,
11827
12129
  properties: shapeProperties(declaration.typeAnnotation.members)
@@ -11831,42 +12133,42 @@ function typeIndex(program) {
11831
12133
  return index;
11832
12134
  }
11833
12135
  function emptyArray(node) {
11834
- return node.type === AST_NODE_TYPES51.ArrayExpression && node.elements.length === 0;
12136
+ return node.type === AST_NODE_TYPES54.ArrayExpression && node.elements.length === 0;
11835
12137
  }
11836
12138
  function sameAccess(node, access) {
11837
12139
  if (access.kind === "identifier") {
11838
- return node.type === AST_NODE_TYPES51.Identifier && node.name === access.name;
12140
+ return node.type === AST_NODE_TYPES54.Identifier && node.name === access.name;
11839
12141
  }
11840
- return node.type === AST_NODE_TYPES51.MemberExpression && !node.computed && node.object.type === AST_NODE_TYPES51.Identifier && node.object.name === access.object && node.property.type === AST_NODE_TYPES51.Identifier && node.property.name === access.property;
12142
+ return node.type === AST_NODE_TYPES54.MemberExpression && !node.computed && node.object.type === AST_NODE_TYPES54.Identifier && node.object.name === access.object && node.property.type === AST_NODE_TYPES54.Identifier && node.property.name === access.property;
11841
12143
  }
11842
12144
  function isNullGuard(node, access) {
11843
- if (node.type === AST_NODE_TYPES51.UnaryExpression && node.operator === "!" && (sameAccess(node.argument, access) || optionalMemberLengthOf(node.argument, access))) return true;
11844
- if (node.type !== AST_NODE_TYPES51.BinaryExpression || !["==", "==="].includes(node.operator)) {
12145
+ if (node.type === AST_NODE_TYPES54.UnaryExpression && node.operator === "!" && (sameAccess(node.argument, access) || optionalMemberLengthOf(node.argument, access))) return true;
12146
+ if (node.type !== AST_NODE_TYPES54.BinaryExpression || !["==", "==="].includes(node.operator)) {
11845
12147
  return false;
11846
12148
  }
11847
- const nullish = (value) => value.type === AST_NODE_TYPES51.Literal && value.value === null || value.type === AST_NODE_TYPES51.Identifier && value.name === "undefined";
12149
+ const nullish = (value) => value.type === AST_NODE_TYPES54.Literal && value.value === null || value.type === AST_NODE_TYPES54.Identifier && value.name === "undefined";
11848
12150
  return sameAccess(node.left, access) && nullish(node.right) || sameAccess(node.right, access) && nullish(node.left);
11849
12151
  }
11850
12152
  function isEmptyGuard(node, access) {
11851
- if (node.type === AST_NODE_TYPES51.UnaryExpression && node.operator === "!" && memberLengthOf(node.argument, access)) return true;
11852
- if (node.type !== AST_NODE_TYPES51.BinaryExpression || !["==", "===", "<="].includes(node.operator)) {
12153
+ if (node.type === AST_NODE_TYPES54.UnaryExpression && node.operator === "!" && memberLengthOf(node.argument, access)) return true;
12154
+ if (node.type !== AST_NODE_TYPES54.BinaryExpression || !["==", "===", "<="].includes(node.operator)) {
11853
12155
  return false;
11854
12156
  }
11855
- const zero = (value) => value.type === AST_NODE_TYPES51.Literal && value.value === 0;
12157
+ const zero = (value) => value.type === AST_NODE_TYPES54.Literal && value.value === 0;
11856
12158
  return memberLengthOf(node.left, access) && zero(node.right) || memberLengthOf(node.right, access) && zero(node.left);
11857
12159
  }
11858
12160
  function memberLengthOf(node, access) {
11859
- const target = node.type === AST_NODE_TYPES51.ChainExpression ? node.expression : node;
11860
- return target.type === AST_NODE_TYPES51.MemberExpression && !target.computed && target.property.type === AST_NODE_TYPES51.Identifier && target.property.name === "length" && sameAccess(target.object, access);
12161
+ const target = node.type === AST_NODE_TYPES54.ChainExpression ? node.expression : node;
12162
+ return target.type === AST_NODE_TYPES54.MemberExpression && !target.computed && target.property.type === AST_NODE_TYPES54.Identifier && target.property.name === "length" && sameAccess(target.object, access);
11861
12163
  }
11862
12164
  function optionalMemberLengthOf(node, access) {
11863
- return node.type === AST_NODE_TYPES51.ChainExpression && node.expression.type === AST_NODE_TYPES51.MemberExpression && node.expression.optional && memberLengthOf(node, access);
12165
+ return node.type === AST_NODE_TYPES54.ChainExpression && node.expression.type === AST_NODE_TYPES54.MemberExpression && node.expression.optional && memberLengthOf(node, access);
11864
12166
  }
11865
12167
  function hasEquivalentLeadingGuard(fn, access, visitorKeys) {
11866
- if (fn.body.type !== AST_NODE_TYPES51.BlockStatement) return false;
12168
+ if (fn.body.type !== AST_NODE_TYPES54.BlockStatement) return false;
11867
12169
  const first = fn.body.body[0];
11868
- if (first?.type !== AST_NODE_TYPES51.IfStatement) return false;
11869
- const terminating = first.consequent.type === AST_NODE_TYPES51.ReturnStatement || first.consequent.type === AST_NODE_TYPES51.ThrowStatement || first.consequent.type === AST_NODE_TYPES51.BlockStatement && first.consequent.body.length === 1 && (first.consequent.body[0]?.type === AST_NODE_TYPES51.ReturnStatement || first.consequent.body[0]?.type === AST_NODE_TYPES51.ThrowStatement);
12170
+ if (first?.type !== AST_NODE_TYPES54.IfStatement) return false;
12171
+ const terminating = first.consequent.type === AST_NODE_TYPES54.ReturnStatement || first.consequent.type === AST_NODE_TYPES54.ThrowStatement || first.consequent.type === AST_NODE_TYPES54.BlockStatement && first.consequent.body.length === 1 && (first.consequent.body[0]?.type === AST_NODE_TYPES54.ReturnStatement || first.consequent.body[0]?.type === AST_NODE_TYPES54.ThrowStatement);
11870
12172
  if (!terminating) return false;
11871
12173
  if (contains(first.consequent, visitorKeys, (node) => sameAccess(node, access))) return false;
11872
12174
  return contains(first.test, visitorKeys, (node) => isNullGuard(node, access)) && contains(first.test, visitorKeys, (node) => isEmptyGuard(node, access));
@@ -11884,29 +12186,29 @@ function contains(node, visitorKeys, predicate) {
11884
12186
  function belongsToFunction(node, fn) {
11885
12187
  let current = node;
11886
12188
  while (current !== void 0 && current !== fn) {
11887
- if (current !== node && (current.type === AST_NODE_TYPES51.ArrowFunctionExpression || current.type === AST_NODE_TYPES51.FunctionDeclaration || current.type === AST_NODE_TYPES51.FunctionExpression)) return false;
12189
+ if (current !== node && (current.type === AST_NODE_TYPES54.ArrowFunctionExpression || current.type === AST_NODE_TYPES54.FunctionDeclaration || current.type === AST_NODE_TYPES54.FunctionExpression)) return false;
11888
12190
  current = current.parent;
11889
12191
  }
11890
12192
  return current === fn;
11891
12193
  }
11892
12194
  function directlyCoalesced(node) {
11893
12195
  const parent = node.parent;
11894
- return parent?.type === AST_NODE_TYPES51.LogicalExpression && parent.left === node && (parent.operator === "??" || parent.operator === "||") && emptyArray(parent.right);
12196
+ return parent?.type === AST_NODE_TYPES54.LogicalExpression && parent.left === node && (parent.operator === "??" || parent.operator === "||") && emptyArray(parent.right);
11895
12197
  }
11896
12198
  function identifierIsOnlyCoalesced(context, binding, fn) {
11897
- const variable = ASTUtils15.findVariable(context.sourceCode.getScope(binding), binding.name);
12199
+ const variable = ASTUtils16.findVariable(context.sourceCode.getScope(binding), binding.name);
11898
12200
  if (variable === null || variable.references.length === 0) return false;
11899
12201
  return variable.references.every(
11900
12202
  (reference) => belongsToFunction(reference.identifier, fn) && directlyCoalesced(reference.identifier)
11901
12203
  );
11902
12204
  }
11903
12205
  function memberIsOnlyCoalesced(context, object, property, fn) {
11904
- const variable = ASTUtils15.findVariable(context.sourceCode.getScope(object), object.name);
12206
+ const variable = ASTUtils16.findVariable(context.sourceCode.getScope(object), object.name);
11905
12207
  if (variable === null) return false;
11906
12208
  const accesses = variable.references.flatMap((reference) => {
11907
12209
  if (!belongsToFunction(reference.identifier, fn)) return [null];
11908
12210
  const parent = reference.identifier.parent;
11909
- if (parent?.type === AST_NODE_TYPES51.MemberExpression && !parent.computed && parent.object === reference.identifier && parent.property.type === AST_NODE_TYPES51.Identifier && parent.property.name === property) return [parent];
12211
+ if (parent?.type === AST_NODE_TYPES54.MemberExpression && !parent.computed && parent.object === reference.identifier && parent.property.type === AST_NODE_TYPES54.Identifier && parent.property.name === property) return [parent];
11910
12212
  return [];
11911
12213
  });
11912
12214
  return accesses.length > 0 && accesses.every((access) => access !== null && directlyCoalesced(access));
@@ -11932,8 +12234,8 @@ var prefer_non_nullable_collection_default = createRule({
11932
12234
  let shapes = /* @__PURE__ */ new Map();
11933
12235
  const evidence = /* @__PURE__ */ new Map();
11934
12236
  function propertiesFor(annotation) {
11935
- if (annotation?.type === AST_NODE_TYPES51.TSTypeLiteral) return shapeProperties(annotation.members);
11936
- if (annotation?.type === AST_NODE_TYPES51.TSTypeReference && annotation.typeName.type === AST_NODE_TYPES51.Identifier) {
12237
+ if (annotation?.type === AST_NODE_TYPES54.TSTypeLiteral) return shapeProperties(annotation.members);
12238
+ if (annotation?.type === AST_NODE_TYPES54.TSTypeReference && annotation.typeName.type === AST_NODE_TYPES54.Identifier) {
11937
12239
  const shape = shapes.get(annotation.typeName.name);
11938
12240
  return shape?.exported === false ? shape.properties : [];
11939
12241
  }
@@ -11946,21 +12248,21 @@ var prefer_non_nullable_collection_default = createRule({
11946
12248
  }
11947
12249
  function checkFunction(fn) {
11948
12250
  for (const rawParameter of fn.params) {
11949
- const parameter = rawParameter.type === AST_NODE_TYPES51.AssignmentPattern ? rawParameter.left : rawParameter;
11950
- if (parameter.type === AST_NODE_TYPES51.ObjectPattern) {
12251
+ const parameter = rawParameter.type === AST_NODE_TYPES54.AssignmentPattern ? rawParameter.left : rawParameter;
12252
+ if (parameter.type === AST_NODE_TYPES54.ObjectPattern) {
11951
12253
  const properties2 = propertiesFor(parameter.typeAnnotation?.typeAnnotation);
11952
12254
  for (const property of properties2) {
11953
12255
  const bindingProperty = parameter.properties.find(
11954
- (entry) => entry.type === AST_NODE_TYPES51.Property && !entry.computed && entry.key.type === AST_NODE_TYPES51.Identifier && entry.key.name === property.name
12256
+ (entry) => entry.type === AST_NODE_TYPES54.Property && !entry.computed && entry.key.type === AST_NODE_TYPES54.Identifier && entry.key.name === property.name
11955
12257
  );
11956
12258
  if (bindingProperty === void 0) continue;
11957
12259
  const value = bindingProperty.value;
11958
- const binding = value.type === AST_NODE_TYPES51.AssignmentPattern ? value.left : value;
11959
- if (binding.type !== AST_NODE_TYPES51.Identifier) {
12260
+ const binding = value.type === AST_NODE_TYPES54.AssignmentPattern ? value.left : value;
12261
+ if (binding.type !== AST_NODE_TYPES54.Identifier) {
11960
12262
  record(property, false);
11961
12263
  continue;
11962
12264
  }
11963
- if (value.type === AST_NODE_TYPES51.AssignmentPattern && emptyArray(value.right) && property.acceptsUndefined && !property.acceptsNull) {
12265
+ if (value.type === AST_NODE_TYPES54.AssignmentPattern && emptyArray(value.right) && property.acceptsUndefined && !property.acceptsNull) {
11964
12266
  record(property, true);
11965
12267
  continue;
11966
12268
  }
@@ -11972,7 +12274,7 @@ var prefer_non_nullable_collection_default = createRule({
11972
12274
  }
11973
12275
  continue;
11974
12276
  }
11975
- if (parameter.type !== AST_NODE_TYPES51.Identifier) continue;
12277
+ if (parameter.type !== AST_NODE_TYPES54.Identifier) continue;
11976
12278
  const properties = propertiesFor(parameter.typeAnnotation?.typeAnnotation);
11977
12279
  for (const property of properties) {
11978
12280
  const access = {
@@ -12000,7 +12302,7 @@ var prefer_non_nullable_collection_default = createRule({
12000
12302
  context.report({
12001
12303
  node,
12002
12304
  messageId: "preferNonNullableCollection",
12003
- data: { name: propertyName3(node) ?? "collection" }
12305
+ data: { name: propertyName5(node) ?? "collection" }
12004
12306
  });
12005
12307
  }
12006
12308
  }
@@ -12010,8 +12312,8 @@ var prefer_non_nullable_collection_default = createRule({
12010
12312
 
12011
12313
  // src/rules/prefer-nullish-filter-predicate.ts
12012
12314
  import {
12013
- AST_NODE_TYPES as AST_NODE_TYPES52,
12014
- ASTUtils as ASTUtils16,
12315
+ AST_NODE_TYPES as AST_NODE_TYPES55,
12316
+ ASTUtils as ASTUtils17,
12015
12317
  ESLintUtils as ESLintUtils5
12016
12318
  } from "@typescript-eslint/utils";
12017
12319
  import ts3 from "typescript";
@@ -12057,7 +12359,7 @@ var PREFER_NULLISH_FILTER_PREDICATE_DOCUMENTATION = {
12057
12359
  ]
12058
12360
  };
12059
12361
  function isUnshadowedBoolean(node, context) {
12060
- const variable = ASTUtils16.findVariable(context.sourceCode.getScope(node), node.name);
12362
+ const variable = ASTUtils17.findVariable(context.sourceCode.getScope(node), node.name);
12061
12363
  return variable === null || variable.defs.length === 0;
12062
12364
  }
12063
12365
  function isBuiltinArrayFilter(node, services) {
@@ -12116,7 +12418,7 @@ function isProvablyTruthy(type, checker) {
12116
12418
  }
12117
12419
  function availableParameterName(node, context) {
12118
12420
  for (const name of ["value", "item", "element", "candidate"]) {
12119
- if (ASTUtils16.findVariable(context.sourceCode.getScope(node), name) === null) return name;
12421
+ if (ASTUtils17.findVariable(context.sourceCode.getScope(node), name) === null) return name;
12120
12422
  }
12121
12423
  return null;
12122
12424
  }
@@ -12147,7 +12449,7 @@ var prefer_nullish_filter_predicate_default = createRule({
12147
12449
  CallExpression(node) {
12148
12450
  const callee = node.callee;
12149
12451
  const callback = node.arguments[0];
12150
- if (node.arguments.length !== 1 || callback?.type !== AST_NODE_TYPES52.Identifier || callback.name !== "Boolean" || callee.type !== AST_NODE_TYPES52.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES52.Identifier || callee.property.name !== "filter" || !isUnshadowedBoolean(callback, context) || !isBuiltinArrayFilter(callee, services)) return;
12452
+ if (node.arguments.length !== 1 || callback?.type !== AST_NODE_TYPES55.Identifier || callback.name !== "Boolean" || callee.type !== AST_NODE_TYPES55.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES55.Identifier || callee.property.name !== "filter" || !isUnshadowedBoolean(callback, context) || !isBuiltinArrayFilter(callee, services)) return;
12151
12453
  const elementType = arrayElementType(callee.object, services);
12152
12454
  const checker = services.program.getTypeChecker();
12153
12455
  if (elementType === null || !isNullishPlusTruthy(elementType, checker)) return;
@@ -12170,9 +12472,9 @@ var prefer_nullish_filter_predicate_default = createRule({
12170
12472
 
12171
12473
  // src/rules/prefer-await-in-async-return.ts
12172
12474
  import {
12173
- ASTUtils as ASTUtils17,
12475
+ ASTUtils as ASTUtils18,
12174
12476
  ESLintUtils as ESLintUtils6,
12175
- AST_NODE_TYPES as AST_NODE_TYPES53
12477
+ AST_NODE_TYPES as AST_NODE_TYPES56
12176
12478
  } from "@typescript-eslint/utils";
12177
12479
  import * as ts4 from "typescript";
12178
12480
  var PREFER_AWAIT_IN_ASYNC_RETURN_DOCUMENTATION = {
@@ -12215,10 +12517,10 @@ var PREFER_AWAIT_IN_ASYNC_RETURN_DOCUMENTATION = {
12215
12517
  };
12216
12518
  function directAsyncReturnOwner(node) {
12217
12519
  const parent = node.parent;
12218
- if (parent.type === AST_NODE_TYPES53.ArrowFunctionExpression && parent.body === node) {
12520
+ if (parent.type === AST_NODE_TYPES56.ArrowFunctionExpression && parent.body === node) {
12219
12521
  return parent.async && !parent.generator ? parent : null;
12220
12522
  }
12221
- if (parent.type !== AST_NODE_TYPES53.ReturnStatement || parent.argument !== node) {
12523
+ if (parent.type !== AST_NODE_TYPES56.ReturnStatement || parent.argument !== node) {
12222
12524
  return null;
12223
12525
  }
12224
12526
  let owner = parent.parent;
@@ -12228,15 +12530,15 @@ function directAsyncReturnOwner(node) {
12228
12530
  return owner !== void 0 && owner.async && !owner.generator ? owner : null;
12229
12531
  }
12230
12532
  function isRuntimeFunction(node) {
12231
- return node.type === AST_NODE_TYPES53.ArrowFunctionExpression || node.type === AST_NODE_TYPES53.FunctionDeclaration || node.type === AST_NODE_TYPES53.FunctionExpression;
12533
+ return node.type === AST_NODE_TYPES56.ArrowFunctionExpression || node.type === AST_NODE_TYPES56.FunctionDeclaration || node.type === AST_NODE_TYPES56.FunctionExpression;
12232
12534
  }
12233
12535
  function promiseThenReceiver(node) {
12234
12536
  const callee = node.callee;
12235
- if (callee.type !== AST_NODE_TYPES53.MemberExpression || callee.computed || callee.optional || callee.property.type !== AST_NODE_TYPES53.Identifier || callee.property.name !== "then" || node.optional || node.arguments.length !== 1) {
12537
+ if (callee.type !== AST_NODE_TYPES56.MemberExpression || callee.computed || callee.optional || callee.property.type !== AST_NODE_TYPES56.Identifier || callee.property.name !== "then" || node.optional || node.arguments.length !== 1) {
12236
12538
  return null;
12237
12539
  }
12238
12540
  const callback = node.arguments[0];
12239
- if (callback === void 0 || callback.type !== AST_NODE_TYPES53.ArrowFunctionExpression && callback.type !== AST_NODE_TYPES53.FunctionExpression) {
12541
+ if (callback === void 0 || callback.type !== AST_NODE_TYPES56.ArrowFunctionExpression && callback.type !== AST_NODE_TYPES56.FunctionExpression) {
12240
12542
  return null;
12241
12543
  }
12242
12544
  return callee.object;
@@ -12284,25 +12586,25 @@ var prefer_await_in_async_return_default = createRule({
12284
12586
  if (services === null) return {};
12285
12587
  const frameworkLoaders = /* @__PURE__ */ new Set();
12286
12588
  const rememberFrameworkLoader = (identifier) => {
12287
- const variable = ASTUtils17.findVariable(context.sourceCode.getScope(identifier), identifier.name);
12589
+ const variable = ASTUtils18.findVariable(context.sourceCode.getScope(identifier), identifier.name);
12288
12590
  if (variable !== null) frameworkLoaders.add(variable);
12289
12591
  };
12290
12592
  const isFrameworkLoaderCallback = (owner) => {
12291
12593
  const parent = owner.parent;
12292
- if (parent.type !== AST_NODE_TYPES53.CallExpression || parent.arguments[0] !== owner || parent.callee.type !== AST_NODE_TYPES53.Identifier) return false;
12293
- const variable = ASTUtils17.findVariable(context.sourceCode.getScope(parent.callee), parent.callee.name);
12594
+ if (parent.type !== AST_NODE_TYPES56.CallExpression || parent.arguments[0] !== owner || parent.callee.type !== AST_NODE_TYPES56.Identifier) return false;
12595
+ const variable = ASTUtils18.findVariable(context.sourceCode.getScope(parent.callee), parent.callee.name);
12294
12596
  return variable !== null && frameworkLoaders.has(variable);
12295
12597
  };
12296
12598
  return {
12297
12599
  ImportDeclaration(node) {
12298
12600
  if (node.source.value === "react") {
12299
12601
  for (const specifier of node.specifiers) {
12300
- if (specifier.type === AST_NODE_TYPES53.ImportSpecifier && (specifier.imported.type === AST_NODE_TYPES53.Identifier ? specifier.imported.name : specifier.imported.value) === "lazy") rememberFrameworkLoader(specifier.local);
12602
+ if (specifier.type === AST_NODE_TYPES56.ImportSpecifier && (specifier.imported.type === AST_NODE_TYPES56.Identifier ? specifier.imported.name : specifier.imported.value) === "lazy") rememberFrameworkLoader(specifier.local);
12301
12603
  }
12302
12604
  }
12303
12605
  if (node.source.value === "next/dynamic") {
12304
12606
  for (const specifier of node.specifiers) {
12305
- if (specifier.type === AST_NODE_TYPES53.ImportDefaultSpecifier) rememberFrameworkLoader(specifier.local);
12607
+ if (specifier.type === AST_NODE_TYPES56.ImportDefaultSpecifier) rememberFrameworkLoader(specifier.local);
12306
12608
  }
12307
12609
  }
12308
12610
  },
@@ -12320,7 +12622,7 @@ var prefer_await_in_async_return_default = createRule({
12320
12622
  });
12321
12623
 
12322
12624
  // src/rules/prefer-schema-for-api-payload.ts
12323
- import { AST_NODE_TYPES as AST_NODE_TYPES54 } from "@typescript-eslint/utils";
12625
+ import { AST_NODE_TYPES as AST_NODE_TYPES57 } from "@typescript-eslint/utils";
12324
12626
  var PREFER_SCHEMA_FOR_API_PAYLOAD_DOCUMENTATION = {
12325
12627
  summary: "Require Zod (or similar) schema validation on `response.json()` / `JSON.parse()` results before property access.",
12326
12628
  rationale: "External JSON is untrusted at runtime even when its expected TypeScript shape is known statically.",
@@ -12332,12 +12634,12 @@ var PREFER_SCHEMA_FOR_API_PAYLOAD_DOCUMENTATION = {
12332
12634
  { id: "unvalidated-payload", title: "Do not trust response JSON directly", outcome: "match", files: [{ path: "src/client.ts", source: "async function load(response) { const body = await response.json(); return body.id; }" }], focusPath: "src/client.ts", expectedCount: 1, public: true }
12333
12635
  ]
12334
12636
  };
12335
- var unwrap4 = (node) => {
12637
+ var unwrap5 = (node) => {
12336
12638
  let current = node;
12337
12639
  while (current !== null && current !== void 0) {
12338
- if (current.type === AST_NODE_TYPES54.TSAsExpression || current.type === AST_NODE_TYPES54.TSTypeAssertion || current.type === AST_NODE_TYPES54.TSNonNullExpression || current.type === AST_NODE_TYPES54.TSSatisfiesExpression) {
12640
+ if (current.type === AST_NODE_TYPES57.TSAsExpression || current.type === AST_NODE_TYPES57.TSTypeAssertion || current.type === AST_NODE_TYPES57.TSNonNullExpression || current.type === AST_NODE_TYPES57.TSSatisfiesExpression) {
12339
12641
  current = current.expression;
12340
- } else if (current.type === AST_NODE_TYPES54.ChainExpression) {
12642
+ } else if (current.type === AST_NODE_TYPES57.ChainExpression) {
12341
12643
  current = current.expression;
12342
12644
  } else {
12343
12645
  break;
@@ -12351,24 +12653,24 @@ var PROMISE_CHAIN_METHODS = /* @__PURE__ */ new Set([
12351
12653
  "finally"
12352
12654
  ]);
12353
12655
  var isSchemaParseReference = (node) => {
12354
- const inner = unwrap4(node);
12355
- return inner !== null && inner.type === AST_NODE_TYPES54.MemberExpression && !inner.computed && inner.property.type === AST_NODE_TYPES54.Identifier && (inner.property.name === "parse" || inner.property.name === "safeParse");
12656
+ const inner = unwrap5(node);
12657
+ return inner !== null && inner.type === AST_NODE_TYPES57.MemberExpression && !inner.computed && inner.property.type === AST_NODE_TYPES57.Identifier && (inner.property.name === "parse" || inner.property.name === "safeParse");
12356
12658
  };
12357
12659
  var isRawPayloadSource = (node, isKnownLocalText) => {
12358
- let current = unwrap4(node);
12660
+ let current = unwrap5(node);
12359
12661
  if (current === null) return false;
12360
- if (current.type === AST_NODE_TYPES54.AwaitExpression) {
12361
- current = unwrap4(current.argument);
12662
+ if (current.type === AST_NODE_TYPES57.AwaitExpression) {
12663
+ current = unwrap5(current.argument);
12362
12664
  }
12363
- if (current === null || current.type !== AST_NODE_TYPES54.CallExpression) {
12665
+ if (current === null || current.type !== AST_NODE_TYPES57.CallExpression) {
12364
12666
  return false;
12365
12667
  }
12366
- const callee = unwrap4(current.callee);
12367
- if (callee === null || callee.type !== AST_NODE_TYPES54.MemberExpression) {
12668
+ const callee = unwrap5(current.callee);
12669
+ if (callee === null || callee.type !== AST_NODE_TYPES57.MemberExpression) {
12368
12670
  return false;
12369
12671
  }
12370
- const property = unwrap4(callee.property);
12371
- if (property === null || property.type !== AST_NODE_TYPES54.Identifier) {
12672
+ const property = unwrap5(callee.property);
12673
+ if (property === null || property.type !== AST_NODE_TYPES57.Identifier) {
12372
12674
  return false;
12373
12675
  }
12374
12676
  if (property.name === "json") {
@@ -12377,18 +12679,18 @@ var isRawPayloadSource = (node, isKnownLocalText) => {
12377
12679
  if (PROMISE_CHAIN_METHODS.has(property.name)) {
12378
12680
  return !current.arguments.some(isSchemaParseReference) && isRawPayloadSource(callee.object);
12379
12681
  }
12380
- const object = unwrap4(callee.object);
12381
- return property.name === "parse" && object !== null && object.type === AST_NODE_TYPES54.Identifier && object.name === "JSON" && !isLocalFileRead(current.arguments[0]) && isKnownLocalText?.(current.arguments[0]) !== true;
12682
+ const object = unwrap5(callee.object);
12683
+ return property.name === "parse" && object !== null && object.type === AST_NODE_TYPES57.Identifier && object.name === "JSON" && !isLocalFileRead(current.arguments[0]) && isKnownLocalText?.(current.arguments[0]) !== true;
12382
12684
  };
12383
12685
  var FILE_READ_RE = /^(readFile|readFileSync|readJson|readJsonSync|readJSON)$/;
12384
12686
  var isDirectLocalFileRead = (node) => {
12385
- let current = unwrap4(node);
12386
- if (current?.type === AST_NODE_TYPES54.AwaitExpression) {
12387
- current = unwrap4(current.argument);
12687
+ let current = unwrap5(node);
12688
+ if (current?.type === AST_NODE_TYPES57.AwaitExpression) {
12689
+ current = unwrap5(current.argument);
12388
12690
  }
12389
- if (current?.type !== AST_NODE_TYPES54.CallExpression) return false;
12390
- const callee = unwrap4(current.callee);
12391
- const name = callee?.type === AST_NODE_TYPES54.Identifier ? callee.name : callee?.type === AST_NODE_TYPES54.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES54.Identifier ? callee.property.name : null;
12691
+ if (current?.type !== AST_NODE_TYPES57.CallExpression) return false;
12692
+ const callee = unwrap5(current.callee);
12693
+ const name = callee?.type === AST_NODE_TYPES57.Identifier ? callee.name : callee?.type === AST_NODE_TYPES57.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES57.Identifier ? callee.property.name : null;
12392
12694
  return name !== null && FILE_READ_RE.test(name);
12393
12695
  };
12394
12696
  var isLocalFileRead = (node) => {
@@ -12415,15 +12717,15 @@ var isLocalFileRead = (node) => {
12415
12717
  var ASSERTION_CALLEE_RE = /^(expect|assert|should|invariant)$/;
12416
12718
  var isInsideAssertion = (node) => {
12417
12719
  for (let current = node.parent; current !== void 0 && current !== null; current = current.parent) {
12418
- if (current.type !== AST_NODE_TYPES54.CallExpression) continue;
12720
+ if (current.type !== AST_NODE_TYPES57.CallExpression) continue;
12419
12721
  let callee = current.callee;
12420
- while (callee.type === AST_NODE_TYPES54.MemberExpression) {
12722
+ while (callee.type === AST_NODE_TYPES57.MemberExpression) {
12421
12723
  callee = callee.object;
12422
12724
  }
12423
- if (callee.type === AST_NODE_TYPES54.CallExpression) {
12725
+ if (callee.type === AST_NODE_TYPES57.CallExpression) {
12424
12726
  callee = callee.callee;
12425
12727
  }
12426
- if (callee.type === AST_NODE_TYPES54.Identifier && ASSERTION_CALLEE_RE.test(callee.name)) {
12728
+ if (callee.type === AST_NODE_TYPES57.Identifier && ASSERTION_CALLEE_RE.test(callee.name)) {
12427
12729
  return true;
12428
12730
  }
12429
12731
  }
@@ -12442,22 +12744,22 @@ var GUARD_NAME_RE = /^(?:is|validate|parse|assert|decode|coerce)[A-Z]/;
12442
12744
  var isValidationRead = (node) => {
12443
12745
  let current = node;
12444
12746
  let parent = current.parent;
12445
- while (parent !== null && parent !== void 0 && (parent.type === AST_NODE_TYPES54.TSAsExpression || parent.type === AST_NODE_TYPES54.TSTypeAssertion || parent.type === AST_NODE_TYPES54.TSNonNullExpression || parent.type === AST_NODE_TYPES54.TSSatisfiesExpression || parent.type === AST_NODE_TYPES54.ChainExpression)) {
12747
+ while (parent !== null && parent !== void 0 && (parent.type === AST_NODE_TYPES57.TSAsExpression || parent.type === AST_NODE_TYPES57.TSTypeAssertion || parent.type === AST_NODE_TYPES57.TSNonNullExpression || parent.type === AST_NODE_TYPES57.TSSatisfiesExpression || parent.type === AST_NODE_TYPES57.ChainExpression)) {
12446
12748
  current = parent;
12447
12749
  parent = parent.parent;
12448
12750
  }
12449
12751
  if (parent === null || parent === void 0) return false;
12450
- if (parent.type === AST_NODE_TYPES54.UnaryExpression && parent.operator === "typeof" && parent.argument === current) {
12752
+ if (parent.type === AST_NODE_TYPES57.UnaryExpression && parent.operator === "typeof" && parent.argument === current) {
12451
12753
  return true;
12452
12754
  }
12453
- if (parent.type !== AST_NODE_TYPES54.CallExpression || !parent.arguments.some((arg) => arg === current)) {
12755
+ if (parent.type !== AST_NODE_TYPES57.CallExpression || !parent.arguments.some((arg) => arg === current)) {
12454
12756
  return false;
12455
12757
  }
12456
12758
  const callee = parent.callee;
12457
- if (callee.type === AST_NODE_TYPES54.MemberExpression && !callee.computed && callee.object.type === AST_NODE_TYPES54.Identifier && callee.object.name === "Array" && callee.property.type === AST_NODE_TYPES54.Identifier && callee.property.name === "isArray") {
12759
+ if (callee.type === AST_NODE_TYPES57.MemberExpression && !callee.computed && callee.object.type === AST_NODE_TYPES57.Identifier && callee.object.name === "Array" && callee.property.type === AST_NODE_TYPES57.Identifier && callee.property.name === "isArray") {
12458
12760
  return parent.arguments.length === 1;
12459
12761
  }
12460
- return callee.type === AST_NODE_TYPES54.Identifier && GUARD_NAME_RE.test(callee.name);
12762
+ return callee.type === AST_NODE_TYPES57.Identifier && GUARD_NAME_RE.test(callee.name);
12461
12763
  };
12462
12764
  var PRIMITIVE_TYPEOF_RESULTS = /* @__PURE__ */ new Set([
12463
12765
  "bigint",
@@ -12468,13 +12770,13 @@ var PRIMITIVE_TYPEOF_RESULTS = /* @__PURE__ */ new Set([
12468
12770
  "undefined"
12469
12771
  ]);
12470
12772
  var bindingValidationPolarity = (test, bindingName) => {
12471
- if (test.type === AST_NODE_TYPES54.UnaryExpression && test.operator === "!") {
12773
+ if (test.type === AST_NODE_TYPES57.UnaryExpression && test.operator === "!") {
12472
12774
  const inner = bindingValidationPolarity(test.argument, bindingName);
12473
12775
  return inner === "valid-when-true" ? "valid-when-false" : inner === "valid-when-false" ? "valid-when-true" : null;
12474
12776
  }
12475
- if (test.type === AST_NODE_TYPES54.BinaryExpression) {
12476
- const typeofName = (node) => node.type === AST_NODE_TYPES54.UnaryExpression && node.operator === "typeof" && node.argument.type === AST_NODE_TYPES54.Identifier ? node.argument.name : null;
12477
- const literalType = (node) => node.type === AST_NODE_TYPES54.Literal && typeof node.value === "string" && PRIMITIVE_TYPEOF_RESULTS.has(node.value) ? node.value : null;
12777
+ if (test.type === AST_NODE_TYPES57.BinaryExpression) {
12778
+ const typeofName = (node) => node.type === AST_NODE_TYPES57.UnaryExpression && node.operator === "typeof" && node.argument.type === AST_NODE_TYPES57.Identifier ? node.argument.name : null;
12779
+ const literalType = (node) => node.type === AST_NODE_TYPES57.Literal && typeof node.value === "string" && PRIMITIVE_TYPEOF_RESULTS.has(node.value) ? node.value : null;
12478
12780
  const matches = typeofName(test.left) === bindingName && literalType(test.right) !== null || typeofName(test.right) === bindingName && literalType(test.left) !== null;
12479
12781
  if (!matches) return null;
12480
12782
  if (test.operator === "===" || test.operator === "==") {
@@ -12482,9 +12784,9 @@ var bindingValidationPolarity = (test, bindingName) => {
12482
12784
  }
12483
12785
  return test.operator === "!==" || test.operator === "!=" ? "valid-when-false" : null;
12484
12786
  }
12485
- return test.type === AST_NODE_TYPES54.CallExpression && test.arguments.length === 1 && test.arguments[0]?.type === AST_NODE_TYPES54.Identifier && test.arguments[0].name === bindingName && test.callee.type === AST_NODE_TYPES54.MemberExpression && !test.callee.computed && test.callee.object.type === AST_NODE_TYPES54.Identifier && test.callee.object.name === "Array" && test.callee.property.type === AST_NODE_TYPES54.Identifier && test.callee.property.name === "isArray" ? "valid-when-true" : null;
12787
+ return test.type === AST_NODE_TYPES57.CallExpression && test.arguments.length === 1 && test.arguments[0]?.type === AST_NODE_TYPES57.Identifier && test.arguments[0].name === bindingName && test.callee.type === AST_NODE_TYPES57.MemberExpression && !test.callee.computed && test.callee.object.type === AST_NODE_TYPES57.Identifier && test.callee.object.name === "Array" && test.callee.property.type === AST_NODE_TYPES57.Identifier && test.callee.property.name === "isArray" ? "valid-when-true" : null;
12486
12788
  };
12487
- var plainMemberAccess = (node) => node.type === AST_NODE_TYPES54.MemberExpression && !node.computed && node.object.type === AST_NODE_TYPES54.Identifier && node.property.type === AST_NODE_TYPES54.Identifier ? { object: node.object.name, property: node.property.name } : null;
12789
+ var plainMemberAccess = (node) => node.type === AST_NODE_TYPES57.MemberExpression && !node.computed && node.object.type === AST_NODE_TYPES57.Identifier && node.property.type === AST_NODE_TYPES57.Identifier ? { object: node.object.name, property: node.property.name } : null;
12488
12790
  var isSamePlainMember = (node, access) => {
12489
12791
  const candidate2 = plainMemberAccess(node);
12490
12792
  return candidate2 !== null && candidate2.object === access.object && candidate2.property === access.property;
@@ -12492,19 +12794,19 @@ var isSamePlainMember = (node, access) => {
12492
12794
  var nodeWithin2 = (node, container) => node.range[0] >= container.range[0] && node.range[1] <= container.range[1];
12493
12795
  var isUseWithinValidatedBranch = (node, bindingName) => {
12494
12796
  for (let current = node.parent; current !== void 0 && current !== null; current = current.parent) {
12495
- if (current.type === AST_NODE_TYPES54.ConditionalExpression) {
12797
+ if (current.type === AST_NODE_TYPES57.ConditionalExpression) {
12496
12798
  const polarity = bindingValidationPolarity(current.test, bindingName);
12497
12799
  if (polarity === "valid-when-true" && nodeWithin2(node, current.consequent) || polarity === "valid-when-false" && nodeWithin2(node, current.alternate)) {
12498
12800
  return true;
12499
12801
  }
12500
12802
  }
12501
- if (current.type === AST_NODE_TYPES54.IfStatement) {
12803
+ if (current.type === AST_NODE_TYPES57.IfStatement) {
12502
12804
  const polarity = bindingValidationPolarity(current.test, bindingName);
12503
12805
  if (polarity === "valid-when-true" && nodeWithin2(node, current.consequent) || polarity === "valid-when-false" && current.alternate !== null && nodeWithin2(node, current.alternate)) {
12504
12806
  return true;
12505
12807
  }
12506
12808
  }
12507
- if (current.type === AST_NODE_TYPES54.FunctionDeclaration || current.type === AST_NODE_TYPES54.FunctionExpression || current.type === AST_NODE_TYPES54.ArrowFunctionExpression) {
12809
+ if (current.type === AST_NODE_TYPES57.FunctionDeclaration || current.type === AST_NODE_TYPES57.FunctionExpression || current.type === AST_NODE_TYPES57.ArrowFunctionExpression) {
12508
12810
  return false;
12509
12811
  }
12510
12812
  }
@@ -12512,32 +12814,32 @@ var isUseWithinValidatedBranch = (node, bindingName) => {
12512
12814
  };
12513
12815
  var isMemberUseWithinValidatedBranch = (node, access) => {
12514
12816
  for (let current = node.parent; current !== void 0 && current !== null; current = current.parent) {
12515
- if (current.type === AST_NODE_TYPES54.ConditionalExpression) {
12817
+ if (current.type === AST_NODE_TYPES57.ConditionalExpression) {
12516
12818
  const polarity = memberValidationPolarity(current.test, access);
12517
12819
  if (polarity === "valid-when-true" && nodeWithin2(node, current.consequent) || polarity === "valid-when-false" && nodeWithin2(node, current.alternate)) {
12518
12820
  return true;
12519
12821
  }
12520
12822
  }
12521
- if (current.type === AST_NODE_TYPES54.IfStatement) {
12823
+ if (current.type === AST_NODE_TYPES57.IfStatement) {
12522
12824
  const polarity = memberValidationPolarity(current.test, access);
12523
12825
  if (polarity === "valid-when-true" && nodeWithin2(node, current.consequent) || polarity === "valid-when-false" && current.alternate !== null && nodeWithin2(node, current.alternate)) {
12524
12826
  return true;
12525
12827
  }
12526
12828
  }
12527
- if (current.type === AST_NODE_TYPES54.FunctionDeclaration || current.type === AST_NODE_TYPES54.FunctionExpression || current.type === AST_NODE_TYPES54.ArrowFunctionExpression) {
12829
+ if (current.type === AST_NODE_TYPES57.FunctionDeclaration || current.type === AST_NODE_TYPES57.FunctionExpression || current.type === AST_NODE_TYPES57.ArrowFunctionExpression) {
12528
12830
  return false;
12529
12831
  }
12530
12832
  }
12531
12833
  return false;
12532
12834
  };
12533
12835
  var memberValidationPolarity = (test, access) => {
12534
- if (test.type === AST_NODE_TYPES54.UnaryExpression && test.operator === "!") {
12836
+ if (test.type === AST_NODE_TYPES57.UnaryExpression && test.operator === "!") {
12535
12837
  const inner = memberValidationPolarity(test.argument, access);
12536
12838
  return inner === "valid-when-true" ? "valid-when-false" : inner === "valid-when-false" ? "valid-when-true" : null;
12537
12839
  }
12538
- if (test.type === AST_NODE_TYPES54.BinaryExpression) {
12539
- const isMatchingTypeof = (node) => node.type === AST_NODE_TYPES54.UnaryExpression && node.operator === "typeof" && isSamePlainMember(node.argument, access);
12540
- const isPrimitiveType = (node) => node.type === AST_NODE_TYPES54.Literal && typeof node.value === "string" && PRIMITIVE_TYPEOF_RESULTS.has(node.value);
12840
+ if (test.type === AST_NODE_TYPES57.BinaryExpression) {
12841
+ const isMatchingTypeof = (node) => node.type === AST_NODE_TYPES57.UnaryExpression && node.operator === "typeof" && isSamePlainMember(node.argument, access);
12842
+ const isPrimitiveType = (node) => node.type === AST_NODE_TYPES57.Literal && typeof node.value === "string" && PRIMITIVE_TYPEOF_RESULTS.has(node.value);
12541
12843
  if (!(isMatchingTypeof(test.left) && isPrimitiveType(test.right) || isMatchingTypeof(test.right) && isPrimitiveType(test.left))) {
12542
12844
  return null;
12543
12845
  }
@@ -12546,15 +12848,15 @@ var memberValidationPolarity = (test, access) => {
12546
12848
  }
12547
12849
  return test.operator === "!==" || test.operator === "!=" ? "valid-when-false" : null;
12548
12850
  }
12549
- return test.type === AST_NODE_TYPES54.CallExpression && test.arguments.length === 1 && test.arguments[0] !== void 0 && test.arguments[0].type !== AST_NODE_TYPES54.SpreadElement && isSamePlainMember(test.arguments[0], access) && test.callee.type === AST_NODE_TYPES54.MemberExpression && !test.callee.computed && test.callee.object.type === AST_NODE_TYPES54.Identifier && test.callee.object.name === "Array" && test.callee.property.type === AST_NODE_TYPES54.Identifier && test.callee.property.name === "isArray" ? "valid-when-true" : null;
12851
+ return test.type === AST_NODE_TYPES57.CallExpression && test.arguments.length === 1 && test.arguments[0] !== void 0 && test.arguments[0].type !== AST_NODE_TYPES57.SpreadElement && isSamePlainMember(test.arguments[0], access) && test.callee.type === AST_NODE_TYPES57.MemberExpression && !test.callee.computed && test.callee.object.type === AST_NODE_TYPES57.Identifier && test.callee.object.name === "Array" && test.callee.property.type === AST_NODE_TYPES57.Identifier && test.callee.property.name === "isArray" ? "valid-when-true" : null;
12550
12852
  };
12551
12853
  var isFullyValidatedExtractedBinding = (member, source, context) => {
12552
12854
  const isValidationReference = (identifier) => {
12553
12855
  for (let current = identifier.parent; current !== void 0 && current !== null; current = current.parent) {
12554
- if ((current.type === AST_NODE_TYPES54.BinaryExpression || current.type === AST_NODE_TYPES54.CallExpression || current.type === AST_NODE_TYPES54.UnaryExpression) && bindingValidationPolarity(current, identifier.name) !== null) {
12856
+ if ((current.type === AST_NODE_TYPES57.BinaryExpression || current.type === AST_NODE_TYPES57.CallExpression || current.type === AST_NODE_TYPES57.UnaryExpression) && bindingValidationPolarity(current, identifier.name) !== null) {
12555
12857
  return true;
12556
12858
  }
12557
- if (current.type !== AST_NODE_TYPES54.UnaryExpression && current.type !== AST_NODE_TYPES54.MemberExpression && current.type !== AST_NODE_TYPES54.CallExpression) {
12859
+ if (current.type !== AST_NODE_TYPES57.UnaryExpression && current.type !== AST_NODE_TYPES57.MemberExpression && current.type !== AST_NODE_TYPES57.CallExpression) {
12558
12860
  return false;
12559
12861
  }
12560
12862
  }
@@ -12562,7 +12864,7 @@ var isFullyValidatedExtractedBinding = (member, source, context) => {
12562
12864
  };
12563
12865
  const isGuardedUse = (identifier) => {
12564
12866
  for (let current = identifier.parent; current !== void 0 && current !== null; current = current.parent) {
12565
- if (current.type === AST_NODE_TYPES54.ConditionalExpression) {
12867
+ if (current.type === AST_NODE_TYPES57.ConditionalExpression) {
12566
12868
  const polarity = bindingValidationPolarity(current.test, identifier.name);
12567
12869
  if (polarity === "valid-when-true" && nodeWithin2(identifier, current.consequent)) {
12568
12870
  return true;
@@ -12571,7 +12873,7 @@ var isFullyValidatedExtractedBinding = (member, source, context) => {
12571
12873
  return true;
12572
12874
  }
12573
12875
  }
12574
- if (current.type === AST_NODE_TYPES54.IfStatement) {
12876
+ if (current.type === AST_NODE_TYPES57.IfStatement) {
12575
12877
  const polarity = bindingValidationPolarity(current.test, identifier.name);
12576
12878
  if (polarity === "valid-when-true" && nodeWithin2(identifier, current.consequent)) {
12577
12879
  return true;
@@ -12580,14 +12882,14 @@ var isFullyValidatedExtractedBinding = (member, source, context) => {
12580
12882
  return true;
12581
12883
  }
12582
12884
  }
12583
- if (current.type === AST_NODE_TYPES54.FunctionDeclaration || current.type === AST_NODE_TYPES54.FunctionExpression || current.type === AST_NODE_TYPES54.ArrowFunctionExpression) {
12885
+ if (current.type === AST_NODE_TYPES57.FunctionDeclaration || current.type === AST_NODE_TYPES57.FunctionExpression || current.type === AST_NODE_TYPES57.ArrowFunctionExpression) {
12584
12886
  return false;
12585
12887
  }
12586
12888
  }
12587
12889
  return false;
12588
12890
  };
12589
12891
  const declarator = member.parent;
12590
- if (declarator.type !== AST_NODE_TYPES54.VariableDeclarator || declarator.init !== member || declarator.id.type !== AST_NODE_TYPES54.Identifier || declarator.parent.type !== AST_NODE_TYPES54.VariableDeclaration || declarator.parent.kind !== "const") {
12892
+ if (declarator.type !== AST_NODE_TYPES57.VariableDeclarator || declarator.init !== member || declarator.id.type !== AST_NODE_TYPES57.Identifier || declarator.parent.type !== AST_NODE_TYPES57.VariableDeclaration || declarator.parent.kind !== "const") {
12591
12893
  return false;
12592
12894
  }
12593
12895
  const extracted = context.sourceCode.getDeclaredVariables(declarator)[0];
@@ -12595,7 +12897,7 @@ var isFullyValidatedExtractedBinding = (member, source, context) => {
12595
12897
  let hasValueUse = false;
12596
12898
  for (const reference of extracted.references) {
12597
12899
  const identifier = reference.identifier;
12598
- if (identifier.type !== AST_NODE_TYPES54.Identifier) return false;
12900
+ if (identifier.type !== AST_NODE_TYPES57.Identifier) return false;
12599
12901
  if (nodeWithin2(identifier, declarator)) continue;
12600
12902
  if (isValidationReference(identifier)) continue;
12601
12903
  hasValueUse = true;
@@ -12608,17 +12910,17 @@ var isGuardTestPosition = (node) => {
12608
12910
  let parent = current.parent;
12609
12911
  while (parent !== void 0 && parent !== null) {
12610
12912
  switch (parent.type) {
12611
- case AST_NODE_TYPES54.UnaryExpression:
12612
- case AST_NODE_TYPES54.LogicalExpression:
12613
- case AST_NODE_TYPES54.ChainExpression:
12913
+ case AST_NODE_TYPES57.UnaryExpression:
12914
+ case AST_NODE_TYPES57.LogicalExpression:
12915
+ case AST_NODE_TYPES57.ChainExpression:
12614
12916
  current = parent;
12615
12917
  parent = parent.parent;
12616
12918
  continue;
12617
- case AST_NODE_TYPES54.IfStatement:
12618
- case AST_NODE_TYPES54.ConditionalExpression:
12619
- case AST_NODE_TYPES54.WhileStatement:
12620
- case AST_NODE_TYPES54.DoWhileStatement:
12621
- case AST_NODE_TYPES54.ForStatement:
12919
+ case AST_NODE_TYPES57.IfStatement:
12920
+ case AST_NODE_TYPES57.ConditionalExpression:
12921
+ case AST_NODE_TYPES57.WhileStatement:
12922
+ case AST_NODE_TYPES57.DoWhileStatement:
12923
+ case AST_NODE_TYPES57.ForStatement:
12622
12924
  return parent.test === current;
12623
12925
  default:
12624
12926
  return false;
@@ -12627,8 +12929,8 @@ var isGuardTestPosition = (node) => {
12627
12929
  return false;
12628
12930
  };
12629
12931
  var unvalidatedVariableRef = (node, scope, tracked) => {
12630
- const unwrapped = unwrap4(node);
12631
- if (unwrapped === null || unwrapped.type !== AST_NODE_TYPES54.Identifier) {
12932
+ const unwrapped = unwrap5(node);
12933
+ if (unwrapped === null || unwrapped.type !== AST_NODE_TYPES57.Identifier) {
12632
12934
  return null;
12633
12935
  }
12634
12936
  const variable = findVariable2(scope, unwrapped.name);
@@ -12656,8 +12958,8 @@ var prefer_schema_for_api_payload_default = createRule({
12656
12958
  const aliasGroups = /* @__PURE__ */ new Map();
12657
12959
  const localFileTextVariables = /* @__PURE__ */ new Set();
12658
12960
  const localFileTextRef = (node, scope) => {
12659
- const unwrapped = unwrap4(node);
12660
- if (unwrapped?.type !== AST_NODE_TYPES54.Identifier) return null;
12961
+ const unwrapped = unwrap5(node);
12962
+ if (unwrapped?.type !== AST_NODE_TYPES57.Identifier) return null;
12661
12963
  const variable = findVariable2(scope, unwrapped.name);
12662
12964
  return variable !== null && localFileTextVariables.has(variable) ? variable : null;
12663
12965
  };
@@ -12726,7 +13028,7 @@ var prefer_schema_for_api_payload_default = createRule({
12726
13028
  return {
12727
13029
  VariableDeclarator(node) {
12728
13030
  const scope = context.sourceCode.getScope(node);
12729
- if (node.id.type === AST_NODE_TYPES54.Identifier) {
13031
+ if (node.id.type === AST_NODE_TYPES57.Identifier) {
12730
13032
  const variable = context.sourceCode.getDeclaredVariables(node)[0];
12731
13033
  if (variable !== void 0) {
12732
13034
  updateLocalFileText(variable, node.init, scope);
@@ -12734,7 +13036,7 @@ var prefer_schema_for_api_payload_default = createRule({
12734
13036
  trackInitializer(node, scope);
12735
13037
  return;
12736
13038
  }
12737
- if (node.id.type === AST_NODE_TYPES54.ObjectPattern || node.id.type === AST_NODE_TYPES54.ArrayPattern) {
13039
+ if (node.id.type === AST_NODE_TYPES57.ObjectPattern || node.id.type === AST_NODE_TYPES57.ArrayPattern) {
12738
13040
  if (isRawPayloadSource(
12739
13041
  node.init,
12740
13042
  (candidate2) => localFileTextRef(candidate2, scope) !== null
@@ -12751,7 +13053,7 @@ var prefer_schema_for_api_payload_default = createRule({
12751
13053
  },
12752
13054
  AssignmentExpression(node) {
12753
13055
  const scope = context.sourceCode.getScope(node);
12754
- if (node.left.type === AST_NODE_TYPES54.Identifier) {
13056
+ if (node.left.type === AST_NODE_TYPES57.Identifier) {
12755
13057
  const variable = findVariable2(scope, node.left.name);
12756
13058
  if (variable === null) return;
12757
13059
  const isLocalText = (candidate2) => localFileTextRef(candidate2, scope) !== null;
@@ -12765,7 +13067,7 @@ var prefer_schema_for_api_payload_default = createRule({
12765
13067
  }
12766
13068
  return;
12767
13069
  }
12768
- if (node.left.type === AST_NODE_TYPES54.ObjectPattern || node.left.type === AST_NODE_TYPES54.ArrayPattern) {
13070
+ if (node.left.type === AST_NODE_TYPES57.ObjectPattern || node.left.type === AST_NODE_TYPES57.ArrayPattern) {
12769
13071
  if (isRawPayloadSource(
12770
13072
  node.right,
12771
13073
  (candidate2) => localFileTextRef(candidate2, scope) !== null
@@ -12785,15 +13087,15 @@ var prefer_schema_for_api_payload_default = createRule({
12785
13087
  }
12786
13088
  },
12787
13089
  CallExpression(node) {
12788
- if (node.callee.type !== AST_NODE_TYPES54.Identifier) return;
13090
+ if (node.callee.type !== AST_NODE_TYPES57.Identifier) return;
12789
13091
  if (!GUARD_NAME_RE.test(node.callee.name) && !isGuardTestPosition(node)) {
12790
13092
  return;
12791
13093
  }
12792
13094
  const scope = context.sourceCode.getScope(node);
12793
13095
  for (const arg of node.arguments) {
12794
- if (arg.type === AST_NODE_TYPES54.SpreadElement) continue;
12795
- const unwrapped = unwrap4(arg);
12796
- if (unwrapped === null || unwrapped.type !== AST_NODE_TYPES54.Identifier) {
13096
+ if (arg.type === AST_NODE_TYPES57.SpreadElement) continue;
13097
+ const unwrapped = unwrap5(arg);
13098
+ if (unwrapped === null || unwrapped.type !== AST_NODE_TYPES57.Identifier) {
12797
13099
  continue;
12798
13100
  }
12799
13101
  const variable = findVariable2(scope, unwrapped.name);
@@ -12804,20 +13106,20 @@ var prefer_schema_for_api_payload_default = createRule({
12804
13106
  if (isInsideAssertion(node)) return;
12805
13107
  if (isValidationRead(node)) return;
12806
13108
  const scope = context.sourceCode.getScope(node);
12807
- const obj = unwrap4(node.object);
13109
+ const obj = unwrap5(node.object);
12808
13110
  if (isRawPayloadSource(
12809
13111
  obj,
12810
13112
  (candidate2) => localFileTextRef(candidate2, scope) !== null
12811
13113
  )) {
12812
13114
  const parent = node.parent;
12813
- if (parent.type === AST_NODE_TYPES54.CallExpression && parent.callee === node && node.property.type === AST_NODE_TYPES54.Identifier && (node.property.name === "parse" || node.property.name === "safeParse" || PROMISE_CHAIN_METHODS.has(node.property.name))) {
13115
+ if (parent.type === AST_NODE_TYPES57.CallExpression && parent.callee === node && node.property.type === AST_NODE_TYPES57.Identifier && (node.property.name === "parse" || node.property.name === "safeParse" || PROMISE_CHAIN_METHODS.has(node.property.name))) {
12814
13116
  return;
12815
13117
  }
12816
13118
  context.report({ node, messageId: "unparsedJsonAccess" });
12817
13119
  return;
12818
13120
  }
12819
- const variable = obj?.type === AST_NODE_TYPES54.Identifier ? unvalidatedVariableRef(obj, scope, unvalidatedVariables) : null;
12820
- if (variable !== null && obj?.type === AST_NODE_TYPES54.Identifier) {
13121
+ const variable = obj?.type === AST_NODE_TYPES57.Identifier ? unvalidatedVariableRef(obj, scope, unvalidatedVariables) : null;
13122
+ if (variable !== null && obj?.type === AST_NODE_TYPES57.Identifier) {
12821
13123
  if (isUseWithinValidatedBranch(node, obj.name)) {
12822
13124
  return;
12823
13125
  }
@@ -12836,8 +13138,142 @@ var prefer_schema_for_api_payload_default = createRule({
12836
13138
  }
12837
13139
  });
12838
13140
 
13141
+ // src/rules/prefer-shared-zod-enum.ts
13142
+ import { AST_NODE_TYPES as AST_NODE_TYPES58 } from "@typescript-eslint/utils";
13143
+ var PREFER_SHARED_ZOD_ENUM_DOCUMENTATION = {
13144
+ summary: "Give literal Zod enum domains one reusable module-level schema.",
13145
+ rationale: "Inline or repeated literal domains hide a reusable contract and allow equivalent fields to drift independently.",
13146
+ remediation: "Declare a module-level named Zod enum schema and reuse it at each field or contract site.",
13147
+ category: "maintainability",
13148
+ limitations: ["Only direct z.enum calls with string-literal arrays are inspected; computed domains require review."],
13149
+ examples: [
13150
+ { id: "shared-provider", title: "Reuse a named enum schema", outcome: "no-match", files: [{ path: "src/provider.ts", source: "import { z } from 'zod'; const ProviderSchema = z.enum(['agy', 'claude', 'sol']); const JobSchema = z.object({ provider: ProviderSchema }); const StatusSchema = z.object({ provider: ProviderSchema.optional() });" }], focusPath: "src/provider.ts", expectedCount: 0, public: true },
13151
+ { id: "inline-provider", title: "Do not inline enum domains in object fields", outcome: "match", files: [{ path: "src/provider.ts", source: "import { z } from 'zod'; const JobSchema = z.object({ provider: z.enum(['agy', 'claude', 'sol']) });" }], focusPath: "src/provider.ts", expectedCount: 1, public: true }
13152
+ ]
13153
+ };
13154
+ function literalDomain(node) {
13155
+ const [argument] = node.arguments;
13156
+ if (argument?.type !== AST_NODE_TYPES58.ArrayExpression || argument.elements.length < 2) return null;
13157
+ const values = [];
13158
+ for (const element of argument.elements) {
13159
+ if (element?.type !== AST_NODE_TYPES58.Literal || typeof element.value !== "string") return null;
13160
+ values.push(element.value);
13161
+ }
13162
+ return values;
13163
+ }
13164
+ function isModuleLevelNamedSchema(node) {
13165
+ let current = node;
13166
+ while (current.parent?.type === AST_NODE_TYPES58.MemberExpression && current.parent.object === current) {
13167
+ current = current.parent;
13168
+ if (current.parent?.type === AST_NODE_TYPES58.CallExpression && current.parent.callee === current) current = current.parent;
13169
+ }
13170
+ const declarator = current.parent;
13171
+ if (declarator?.type !== AST_NODE_TYPES58.VariableDeclarator || declarator.init !== current || declarator.id.type !== AST_NODE_TYPES58.Identifier || declarator.parent.type !== AST_NODE_TYPES58.VariableDeclaration) return false;
13172
+ const declarationParent = declarator.parent.parent;
13173
+ return declarationParent.type === AST_NODE_TYPES58.Program || declarationParent.type === AST_NODE_TYPES58.ExportNamedDeclaration && declarationParent.parent.type === AST_NODE_TYPES58.Program;
13174
+ }
13175
+ var prefer_shared_zod_enum_default = createRule({
13176
+ name: "prefer-shared-zod-enum",
13177
+ documentation: PREFER_SHARED_ZOD_ENUM_DOCUMENTATION,
13178
+ meta: {
13179
+ type: "suggestion",
13180
+ docs: { description: "Give literal Zod enum domains one reusable module-level schema." },
13181
+ schema: [],
13182
+ messages: {
13183
+ shareEnumDomain: "Extract this literal Zod enum to one module-level named schema and reuse it."
13184
+ }
13185
+ },
13186
+ defaultOptions: [],
13187
+ create(context) {
13188
+ if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
13189
+ const zodBindings = /* @__PURE__ */ new Set();
13190
+ const seen = /* @__PURE__ */ new Set();
13191
+ return {
13192
+ ImportDeclaration(node) {
13193
+ if (!isZodModule(node.source.value)) return;
13194
+ for (const specifier of node.specifiers) {
13195
+ if (specifier.type === AST_NODE_TYPES58.ImportNamespaceSpecifier || specifier.type === AST_NODE_TYPES58.ImportDefaultSpecifier || specifier.type === AST_NODE_TYPES58.ImportSpecifier && specifier.imported.type === AST_NODE_TYPES58.Identifier && specifier.imported.name === "z") zodBindings.add(specifier.local.name);
13196
+ }
13197
+ },
13198
+ CallExpression(node) {
13199
+ if (node.callee.type !== AST_NODE_TYPES58.MemberExpression || node.callee.computed || node.callee.object.type !== AST_NODE_TYPES58.Identifier || !zodBindings.has(node.callee.object.name) || node.callee.property.type !== AST_NODE_TYPES58.Identifier || node.callee.property.name !== "enum") return;
13200
+ const domain = literalDomain(node);
13201
+ if (domain === null) return;
13202
+ const key = JSON.stringify(domain);
13203
+ const inline = !isModuleLevelNamedSchema(node);
13204
+ if (inline || seen.has(key))
13205
+ context.report({ node, messageId: "shareEnumDomain" });
13206
+ else seen.add(key);
13207
+ }
13208
+ };
13209
+ }
13210
+ });
13211
+
13212
+ // src/rules/prefer-switch-for-repeated-equality.ts
13213
+ import { AST_NODE_TYPES as AST_NODE_TYPES59 } from "@typescript-eslint/utils";
13214
+ var PREFER_SWITCH_FOR_REPEATED_EQUALITY_DOCUMENTATION = {
13215
+ summary: "Prefer switch over long if/else-if chains that compare one value for strict equality.",
13216
+ rationale: "A switch makes finite dispatch cases visually uniform and easier to extend without duplicating the discriminant.",
13217
+ remediation: "Replace three or more strict-equality branches over the same discriminant with a switch; keep if statements for ranges, guards, and heterogeneous predicates.",
13218
+ category: "maintainability",
13219
+ limitations: [
13220
+ "Only direct if/else-if chains with at least three strict-equality tests are reported.",
13221
+ "Case values may be literals, enum-like member references, or upper-case named constants; dynamic expressions are excluded.",
13222
+ "The rule deliberately ignores compound predicates, loose equality, ranges, and chains that compare different discriminants."
13223
+ ],
13224
+ examples: [
13225
+ { 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 },
13226
+ { 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 }
13227
+ ]
13228
+ };
13229
+ function discriminantText(sourceCode, test) {
13230
+ if (test.type !== AST_NODE_TYPES59.BinaryExpression || test.operator !== "===") return null;
13231
+ const leftIsCase = isCaseValue(test.left);
13232
+ const rightIsCase = isCaseValue(test.right);
13233
+ if (leftIsCase === rightIsCase) return null;
13234
+ return sourceCode.getText(leftIsCase ? test.right : test.left);
13235
+ }
13236
+ function isCaseValue(node) {
13237
+ if (node.type === AST_NODE_TYPES59.Literal) return true;
13238
+ if (node.type === AST_NODE_TYPES59.Identifier) return /^[A-Z][A-Z0-9_]*$/u.test(node.name);
13239
+ if (node.type !== AST_NODE_TYPES59.MemberExpression || node.computed) return false;
13240
+ return node.property.type === AST_NODE_TYPES59.Identifier && (node.object.type === AST_NODE_TYPES59.Identifier || isCaseValue(node.object));
13241
+ }
13242
+ var prefer_switch_for_repeated_equality_default = createRule({
13243
+ name: "prefer-switch-for-repeated-equality",
13244
+ documentation: PREFER_SWITCH_FOR_REPEATED_EQUALITY_DOCUMENTATION,
13245
+ meta: {
13246
+ type: "suggestion",
13247
+ docs: { description: "Prefer switch over long if/else-if chains that compare one value for strict equality." },
13248
+ schema: [],
13249
+ messages: {
13250
+ preferSwitch: "This if/else-if chain repeatedly compares `{{discriminant}}`; use a switch for the finite cases."
13251
+ }
13252
+ },
13253
+ defaultOptions: [],
13254
+ create(context) {
13255
+ return {
13256
+ IfStatement(node) {
13257
+ if (node.parent.type === AST_NODE_TYPES59.IfStatement && node.parent.alternate === node) return;
13258
+ const first = discriminantText(context.sourceCode, node.test);
13259
+ if (first === null) return;
13260
+ let count = 1;
13261
+ let current = node.alternate;
13262
+ while (current?.type === AST_NODE_TYPES59.IfStatement) {
13263
+ if (discriminantText(context.sourceCode, current.test) !== first) return;
13264
+ count += 1;
13265
+ current = current.alternate;
13266
+ }
13267
+ if (count >= 3) {
13268
+ context.report({ node, messageId: "preferSwitch", data: { discriminant: first } });
13269
+ }
13270
+ }
13271
+ };
13272
+ }
13273
+ });
13274
+
12839
13275
  // src/rules/prefer-semantic-colors.ts
12840
- import { AST_NODE_TYPES as AST_NODE_TYPES55 } from "@typescript-eslint/utils";
13276
+ import { AST_NODE_TYPES as AST_NODE_TYPES60 } from "@typescript-eslint/utils";
12841
13277
  import { existsSync, readdirSync, readFileSync } from "fs";
12842
13278
  import { dirname, join, parse } from "path";
12843
13279
 
@@ -12949,7 +13385,7 @@ var SVG_EXEMPT_COLOR_VALUES = /* @__PURE__ */ new Set([
12949
13385
  var isInsideSvg = (node) => {
12950
13386
  let current = node.parent;
12951
13387
  while (current !== void 0 && current !== null) {
12952
- if (current.type === AST_NODE_TYPES55.JSXElement) {
13388
+ if (current.type === AST_NODE_TYPES60.JSXElement) {
12953
13389
  const name = jsxElementName(current);
12954
13390
  if (name !== null && isSvgLikeElementName(name)) return true;
12955
13391
  }
@@ -12959,8 +13395,8 @@ var isInsideSvg = (node) => {
12959
13395
  };
12960
13396
  function jsxElementName(node) {
12961
13397
  const name = node.openingElement.name;
12962
- if (name.type === AST_NODE_TYPES55.JSXIdentifier) return name.name;
12963
- if (name.type === AST_NODE_TYPES55.JSXMemberExpression && name.property.type === AST_NODE_TYPES55.JSXIdentifier) {
13398
+ if (name.type === AST_NODE_TYPES60.JSXIdentifier) return name.name;
13399
+ if (name.type === AST_NODE_TYPES60.JSXMemberExpression && name.property.type === AST_NODE_TYPES60.JSXIdentifier) {
12964
13400
  return name.property.name;
12965
13401
  }
12966
13402
  return null;
@@ -12986,7 +13422,7 @@ function isSvgLikeElementName(name) {
12986
13422
  var isInsideIconFactoryPath = (node) => {
12987
13423
  let current = node.parent;
12988
13424
  while (current !== void 0 && current !== null) {
12989
- if (current.type === AST_NODE_TYPES55.Property && propName(current.key) === "path" && current.parent.type === AST_NODE_TYPES55.ObjectExpression && current.parent.parent.type === AST_NODE_TYPES55.CallExpression && current.parent.parent.callee.type === AST_NODE_TYPES55.Identifier && current.parent.parent.callee.name === "createIcon") {
13425
+ if (current.type === AST_NODE_TYPES60.Property && propName(current.key) === "path" && current.parent.type === AST_NODE_TYPES60.ObjectExpression && current.parent.parent.type === AST_NODE_TYPES60.CallExpression && current.parent.parent.callee.type === AST_NODE_TYPES60.Identifier && current.parent.parent.callee.name === "createIcon") {
12990
13426
  return true;
12991
13427
  }
12992
13428
  current = current.parent;
@@ -13120,12 +13556,12 @@ var expandWorkspaceGlob = (root, glob) => {
13120
13556
  return readdirSync(parent, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => join(parent, entry.name));
13121
13557
  };
13122
13558
  var propName = (key) => {
13123
- if (key.type === AST_NODE_TYPES55.Identifier) return key.name;
13124
- if (key.type === AST_NODE_TYPES55.Literal && typeof key.value === "string") return key.value;
13559
+ if (key.type === AST_NODE_TYPES60.Identifier) return key.name;
13560
+ if (key.type === AST_NODE_TYPES60.Literal && typeof key.value === "string") return key.value;
13125
13561
  return null;
13126
13562
  };
13127
13563
  var staticallyImportsEmailOrPdfRenderer = (program) => program.body.some((statement) => {
13128
- if (statement.type !== AST_NODE_TYPES55.ImportDeclaration && statement.type !== AST_NODE_TYPES55.ExportNamedDeclaration && statement.type !== AST_NODE_TYPES55.ExportAllDeclaration) {
13564
+ if (statement.type !== AST_NODE_TYPES60.ImportDeclaration && statement.type !== AST_NODE_TYPES60.ExportNamedDeclaration && statement.type !== AST_NODE_TYPES60.ExportAllDeclaration) {
13129
13565
  return false;
13130
13566
  }
13131
13567
  return statement.source !== null && typeof statement.source.value === "string" && EMAIL_OR_PDF_MODULE_RE.test(statement.source.value);
@@ -13162,43 +13598,43 @@ var prefer_semantic_colors_default = createRule({
13162
13598
  }
13163
13599
  let importsEmailOrPdfRenderer = false;
13164
13600
  const pendingReports = [];
13165
- const report = (node, messageId, data) => {
13601
+ const report2 = (node, messageId, data) => {
13166
13602
  pendingReports.push({ node, messageId, data });
13167
13603
  };
13168
13604
  const reportClasses = (value, node) => {
13169
13605
  for (const token of classTokens(value)) {
13170
13606
  const base = tailwindBase(token);
13171
13607
  if (RAW_PALETTE_RE.test(base)) {
13172
- report(node, "rawPalette", { class: token });
13608
+ report2(node, "rawPalette", { class: token });
13173
13609
  } else if (ARBITRARY_COLOR_RE.test(base) && !CSS_VAR_REFERENCE_RE.test(base)) {
13174
- report(node, "arbitraryColor", { class: token });
13610
+ report2(node, "arbitraryColor", { class: token });
13175
13611
  }
13176
13612
  }
13177
13613
  };
13178
13614
  const checkClassNode = (node) => {
13179
13615
  if (node === null) return;
13180
13616
  switch (node.type) {
13181
- case AST_NODE_TYPES55.Literal:
13617
+ case AST_NODE_TYPES60.Literal:
13182
13618
  if (typeof node.value === "string") reportClasses(node.value, node);
13183
13619
  break;
13184
- case AST_NODE_TYPES55.TemplateLiteral:
13620
+ case AST_NODE_TYPES60.TemplateLiteral:
13185
13621
  for (const quasi of node.quasis) reportClasses(quasi.value.cooked ?? "", quasi);
13186
13622
  break;
13187
- case AST_NODE_TYPES55.ArrayExpression:
13623
+ case AST_NODE_TYPES60.ArrayExpression:
13188
13624
  for (const element of node.elements) {
13189
- if (element !== null && element.type !== AST_NODE_TYPES55.SpreadElement) checkClassNode(element);
13625
+ if (element !== null && element.type !== AST_NODE_TYPES60.SpreadElement) checkClassNode(element);
13190
13626
  }
13191
13627
  break;
13192
- case AST_NODE_TYPES55.ObjectExpression:
13628
+ case AST_NODE_TYPES60.ObjectExpression:
13193
13629
  for (const property of node.properties) {
13194
- if (property.type === AST_NODE_TYPES55.Property) checkClassNode(property.value);
13630
+ if (property.type === AST_NODE_TYPES60.Property) checkClassNode(property.value);
13195
13631
  }
13196
13632
  break;
13197
- case AST_NODE_TYPES55.ConditionalExpression:
13633
+ case AST_NODE_TYPES60.ConditionalExpression:
13198
13634
  checkClassNode(node.consequent);
13199
13635
  checkClassNode(node.alternate);
13200
13636
  break;
13201
- case AST_NODE_TYPES55.LogicalExpression:
13637
+ case AST_NODE_TYPES60.LogicalExpression:
13202
13638
  checkClassNode(node.right);
13203
13639
  break;
13204
13640
  default:
@@ -13206,32 +13642,32 @@ var prefer_semantic_colors_default = createRule({
13206
13642
  }
13207
13643
  };
13208
13644
  const checkColorValueNode = (node) => {
13209
- if (node.type === AST_NODE_TYPES55.Literal && typeof node.value === "string" && RAW_COLOR_VALUE_RE.test(node.value) && !CSS_VAR_REFERENCE_RE.test(node.value)) {
13210
- report(node, "inlineColor", { value: node.value });
13645
+ if (node.type === AST_NODE_TYPES60.Literal && typeof node.value === "string" && RAW_COLOR_VALUE_RE.test(node.value) && !CSS_VAR_REFERENCE_RE.test(node.value)) {
13646
+ report2(node, "inlineColor", { value: node.value });
13211
13647
  }
13212
13648
  };
13213
13649
  return {
13214
13650
  "JSXAttribute[name.name='className']"(node) {
13215
13651
  if (node.value === null) return;
13216
- if (node.value.type === AST_NODE_TYPES55.Literal) checkClassNode(node.value);
13217
- else if (node.value.type === AST_NODE_TYPES55.JSXExpressionContainer) {
13218
- if (node.value.expression.type !== AST_NODE_TYPES55.JSXEmptyExpression) {
13652
+ if (node.value.type === AST_NODE_TYPES60.Literal) checkClassNode(node.value);
13653
+ else if (node.value.type === AST_NODE_TYPES60.JSXExpressionContainer) {
13654
+ if (node.value.expression.type !== AST_NODE_TYPES60.JSXEmptyExpression) {
13219
13655
  checkClassNode(node.value.expression);
13220
13656
  }
13221
13657
  }
13222
13658
  },
13223
13659
  CallExpression(node) {
13224
- if (node.callee.type === AST_NODE_TYPES55.Identifier && node.callee.name === "require" && node.arguments[0]?.type === AST_NODE_TYPES55.Literal && typeof node.arguments[0].value === "string" && EMAIL_OR_PDF_MODULE_RE.test(node.arguments[0].value)) {
13660
+ if (node.callee.type === AST_NODE_TYPES60.Identifier && node.callee.name === "require" && node.arguments[0]?.type === AST_NODE_TYPES60.Literal && typeof node.arguments[0].value === "string" && EMAIL_OR_PDF_MODULE_RE.test(node.arguments[0].value)) {
13225
13661
  importsEmailOrPdfRenderer = true;
13226
13662
  }
13227
- if (node.callee.type === AST_NODE_TYPES55.Identifier && CLASS_FNS.has(node.callee.name)) {
13663
+ if (node.callee.type === AST_NODE_TYPES60.Identifier && CLASS_FNS.has(node.callee.name)) {
13228
13664
  for (const arg of node.arguments) {
13229
- if (arg.type !== AST_NODE_TYPES55.SpreadElement) checkClassNode(arg);
13665
+ if (arg.type !== AST_NODE_TYPES60.SpreadElement) checkClassNode(arg);
13230
13666
  }
13231
13667
  }
13232
13668
  },
13233
13669
  VariableDeclarator(node) {
13234
- if (node.id.type === AST_NODE_TYPES55.Identifier && CLASS_NAME_RE.test(node.id.name)) {
13670
+ if (node.id.type === AST_NODE_TYPES60.Identifier && CLASS_NAME_RE.test(node.id.name)) {
13235
13671
  checkClassNode(node.init);
13236
13672
  }
13237
13673
  },
@@ -13241,9 +13677,9 @@ var prefer_semantic_colors_default = createRule({
13241
13677
  },
13242
13678
  // SVG artwork colors are exempt; component presentation colors still report.
13243
13679
  "JSXAttribute[name.name=/^(fill|stroke|color)$/]"(node) {
13244
- if (node.value?.type !== AST_NODE_TYPES55.Literal) return;
13680
+ if (node.value?.type !== AST_NODE_TYPES60.Literal) return;
13245
13681
  const owner = node.parent.name;
13246
- if (owner.type === AST_NODE_TYPES55.JSXIdentifier && SVG_SHAPE_PRIMITIVES.has(owner.name)) {
13682
+ if (owner.type === AST_NODE_TYPES60.JSXIdentifier && SVG_SHAPE_PRIMITIVES.has(owner.name)) {
13247
13683
  return;
13248
13684
  }
13249
13685
  if (typeof node.value.value === "string" && SVG_EXEMPT_COLOR_VALUES.has(node.value.value.toLowerCase())) {
@@ -13257,7 +13693,7 @@ var prefer_semantic_colors_default = createRule({
13257
13693
  if (name !== null && STYLE_COLOR_PROPS.has(name)) checkColorValueNode(node.value);
13258
13694
  },
13259
13695
  ImportExpression(node) {
13260
- if (node.source.type === AST_NODE_TYPES55.Literal && typeof node.source.value === "string" && EMAIL_OR_PDF_MODULE_RE.test(node.source.value)) {
13696
+ if (node.source.type === AST_NODE_TYPES60.Literal && typeof node.source.value === "string" && EMAIL_OR_PDF_MODULE_RE.test(node.source.value)) {
13261
13697
  importsEmailOrPdfRenderer = true;
13262
13698
  }
13263
13699
  },
@@ -13459,7 +13895,7 @@ var prefer_server_actions_default = createRule({
13459
13895
  });
13460
13896
 
13461
13897
  // src/rules/prefer-whole-object-assertion.ts
13462
- import { AST_NODE_TYPES as AST_NODE_TYPES56 } from "@typescript-eslint/utils";
13898
+ import { AST_NODE_TYPES as AST_NODE_TYPES61 } from "@typescript-eslint/utils";
13463
13899
  var MERGEABLE_MATCHERS = /* @__PURE__ */ new Set(["toBe", "toEqual", "toStrictEqual"]);
13464
13900
  var SYNTHETIC_LITERAL_MATCHERS = /* @__PURE__ */ new Map([
13465
13901
  ["toBeNull", "null"],
@@ -13484,11 +13920,11 @@ var PREFER_WHOLE_OBJECT_ASSERTION_DOCUMENTATION = {
13484
13920
  };
13485
13921
  function literalText(node, getText) {
13486
13922
  switch (node.type) {
13487
- case AST_NODE_TYPES56.Literal:
13923
+ case AST_NODE_TYPES61.Literal:
13488
13924
  return "regex" in node ? null : getText(node);
13489
- case AST_NODE_TYPES56.TemplateLiteral:
13925
+ case AST_NODE_TYPES61.TemplateLiteral:
13490
13926
  return node.expressions.length === 0 ? getText(node) : null;
13491
- case AST_NODE_TYPES56.UnaryExpression:
13927
+ case AST_NODE_TYPES61.UnaryExpression:
13492
13928
  return NUMERIC_SIGNS2.has(node.operator) && literalText(node.argument, getText) !== null ? getText(node) : null;
13493
13929
  default:
13494
13930
  return null;
@@ -13496,15 +13932,15 @@ function literalText(node, getText) {
13496
13932
  }
13497
13933
  function isPureReceiver(node) {
13498
13934
  switch (node.type) {
13499
- case AST_NODE_TYPES56.Identifier:
13500
- case AST_NODE_TYPES56.ThisExpression:
13935
+ case AST_NODE_TYPES61.Identifier:
13936
+ case AST_NODE_TYPES61.ThisExpression:
13501
13937
  return true;
13502
- case AST_NODE_TYPES56.MemberExpression:
13938
+ case AST_NODE_TYPES61.MemberExpression:
13503
13939
  if (node.optional) {
13504
13940
  return false;
13505
13941
  }
13506
13942
  if (node.computed) {
13507
- return node.property.type === AST_NODE_TYPES56.Literal && isPureReceiver(node.object);
13943
+ return node.property.type === AST_NODE_TYPES61.Literal && isPureReceiver(node.object);
13508
13944
  }
13509
13945
  return isPureReceiver(node.object);
13510
13946
  default:
@@ -13512,7 +13948,7 @@ function isPureReceiver(node) {
13512
13948
  }
13513
13949
  }
13514
13950
  function literalIndex(node) {
13515
- if (node.type !== AST_NODE_TYPES56.Literal || typeof node.value !== "number") {
13951
+ if (node.type !== AST_NODE_TYPES61.Literal || typeof node.value !== "number") {
13516
13952
  return null;
13517
13953
  }
13518
13954
  return Number.isInteger(node.value) && node.value >= 0 ? node.value : null;
@@ -13520,8 +13956,8 @@ function literalIndex(node) {
13520
13956
  function propertyAccess(node) {
13521
13957
  const path = [];
13522
13958
  let current = node;
13523
- while (current.type === AST_NODE_TYPES56.MemberExpression && !current.computed && !current.optional) {
13524
- if (current.property.type !== AST_NODE_TYPES56.Identifier || COLLECTION_PROPERTIES.has(current.property.name) || LITERAL_KEY_HAZARDS.has(current.property.name)) return null;
13959
+ while (current.type === AST_NODE_TYPES61.MemberExpression && !current.computed && !current.optional) {
13960
+ if (current.property.type !== AST_NODE_TYPES61.Identifier || COLLECTION_PROPERTIES.has(current.property.name) || LITERAL_KEY_HAZARDS.has(current.property.name)) return null;
13525
13961
  path.unshift(current.property.name);
13526
13962
  current = current.object;
13527
13963
  }
@@ -13549,24 +13985,24 @@ var prefer_whole_object_assertion_default = createRule({
13549
13985
  }
13550
13986
  const { sourceCode } = context;
13551
13987
  function parseAssertion(statement) {
13552
- if (statement.type !== AST_NODE_TYPES56.ExpressionStatement) {
13988
+ if (statement.type !== AST_NODE_TYPES61.ExpressionStatement) {
13553
13989
  return null;
13554
13990
  }
13555
13991
  const call = statement.expression;
13556
- if (call.type !== AST_NODE_TYPES56.CallExpression) {
13992
+ if (call.type !== AST_NODE_TYPES61.CallExpression) {
13557
13993
  return null;
13558
13994
  }
13559
13995
  const callee = call.callee;
13560
- if (callee.type !== AST_NODE_TYPES56.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES56.Identifier) {
13996
+ if (callee.type !== AST_NODE_TYPES61.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES61.Identifier) {
13561
13997
  return null;
13562
13998
  }
13563
13999
  const matcher = callee.property.name;
13564
14000
  const expectCall = callee.object;
13565
- if (expectCall.type !== AST_NODE_TYPES56.CallExpression || expectCall.callee.type !== AST_NODE_TYPES56.Identifier || expectCall.callee.name !== "expect" || expectCall.arguments.length !== 1) {
14001
+ if (expectCall.type !== AST_NODE_TYPES61.CallExpression || expectCall.callee.type !== AST_NODE_TYPES61.Identifier || expectCall.callee.name !== "expect" || expectCall.arguments.length !== 1) {
13566
14002
  return null;
13567
14003
  }
13568
14004
  const actual = expectCall.arguments[0];
13569
- if (actual === void 0 || actual.type !== AST_NODE_TYPES56.MemberExpression || actual.optional) {
14005
+ if (actual === void 0 || actual.type !== AST_NODE_TYPES61.MemberExpression || actual.optional) {
13570
14006
  return null;
13571
14007
  }
13572
14008
  if (!isPureReceiver(actual.object)) {
@@ -13595,7 +14031,7 @@ var prefer_whole_object_assertion_default = createRule({
13595
14031
  return null;
13596
14032
  }
13597
14033
  const expected = call.arguments[0];
13598
- if (call.arguments.length !== 1 || expected === void 0 || expected.type === AST_NODE_TYPES56.SpreadElement) {
14034
+ if (call.arguments.length !== 1 || expected === void 0 || expected.type === AST_NODE_TYPES61.SpreadElement) {
13599
14035
  return null;
13600
14036
  }
13601
14037
  const literal = literalText(expected, (node) => sourceCode.getText(node));
@@ -13736,7 +14172,7 @@ var prefer_whole_object_assertion_default = createRule({
13736
14172
  });
13737
14173
 
13738
14174
  // src/rules/repeated-static-call-cases.ts
13739
- import { AST_NODE_TYPES as AST_NODE_TYPES57, ASTUtils as ASTUtils18 } from "@typescript-eslint/utils";
14175
+ import { AST_NODE_TYPES as AST_NODE_TYPES62, ASTUtils as ASTUtils19 } from "@typescript-eslint/utils";
13740
14176
  var REPEATED_STATIC_CALL_CASES_DOCUMENTATION = {
13741
14177
  summary: "Report three or more consecutive literal call assertions that should be independently named test cases.",
13742
14178
  rationale: "Copy-pasted cases obscure the input table and stop later cases from being reported after the first failure.",
@@ -13757,67 +14193,67 @@ var EXPECT_MODIFIERS = /* @__PURE__ */ new Set(["not", "rejects", "resolves"]);
13757
14193
  var SNAPSHOT_MATCHERS = /snapshot/iu;
13758
14194
  var MIN_CASES2 = 3;
13759
14195
  function staticMemberName5(node) {
13760
- if (!node.computed && node.property.type === AST_NODE_TYPES57.Identifier) return node.property.name;
13761
- if (node.computed && node.property.type === AST_NODE_TYPES57.Literal && typeof node.property.value === "string") return node.property.value;
14196
+ if (!node.computed && node.property.type === AST_NODE_TYPES62.Identifier) return node.property.name;
14197
+ if (node.computed && node.property.type === AST_NODE_TYPES62.Literal && typeof node.property.value === "string") return node.property.value;
13762
14198
  return null;
13763
14199
  }
13764
- function importedName5(identifier, context, modules) {
13765
- const variable = ASTUtils18.findVariable(context.sourceCode.getScope(identifier), identifier.name);
14200
+ function importedName6(identifier, context, modules) {
14201
+ const variable = ASTUtils19.findVariable(context.sourceCode.getScope(identifier), identifier.name);
13766
14202
  if (variable === null || variable.defs.length === 0) return identifier.name;
13767
14203
  for (const definition of variable.defs) {
13768
- if (definition.node.type !== AST_NODE_TYPES57.ImportSpecifier) continue;
14204
+ if (definition.node.type !== AST_NODE_TYPES62.ImportSpecifier) continue;
13769
14205
  const declaration = definition.node.parent;
13770
- if (declaration.type !== AST_NODE_TYPES57.ImportDeclaration || typeof declaration.source.value !== "string" || !modules.has(declaration.source.value)) continue;
14206
+ if (declaration.type !== AST_NODE_TYPES62.ImportDeclaration || typeof declaration.source.value !== "string" || !modules.has(declaration.source.value)) continue;
13771
14207
  const imported = definition.node.imported;
13772
- return imported.type === AST_NODE_TYPES57.Identifier ? imported.name : String(imported.value);
14208
+ return imported.type === AST_NODE_TYPES62.Identifier ? imported.name : String(imported.value);
13773
14209
  }
13774
14210
  return null;
13775
14211
  }
13776
14212
  function isDirectTestCallback2(node, context) {
13777
- if (node.type !== AST_NODE_TYPES57.ArrowFunctionExpression && node.type !== AST_NODE_TYPES57.FunctionExpression) return false;
14213
+ if (node.type !== AST_NODE_TYPES62.ArrowFunctionExpression && node.type !== AST_NODE_TYPES62.FunctionExpression) return false;
13778
14214
  const call = node.parent;
13779
- if (call?.type !== AST_NODE_TYPES57.CallExpression || !call.arguments.includes(node)) return false;
14215
+ if (call?.type !== AST_NODE_TYPES62.CallExpression || !call.arguments.includes(node)) return false;
13780
14216
  const root = testRoot2(call.callee);
13781
- return root !== null && TEST_NAMES2.has(importedName5(root, context, TEST_MODULES4) ?? "");
14217
+ return root !== null && TEST_NAMES2.has(importedName6(root, context, TEST_MODULES4) ?? "");
13782
14218
  }
13783
14219
  function testRoot2(callee) {
13784
- if (callee.type === AST_NODE_TYPES57.Identifier) return callee;
13785
- if (callee.type !== AST_NODE_TYPES57.MemberExpression) return null;
14220
+ if (callee.type === AST_NODE_TYPES62.Identifier) return callee;
14221
+ if (callee.type !== AST_NODE_TYPES62.MemberExpression) return null;
13786
14222
  const modifier = staticMemberName5(callee);
13787
14223
  return modifier !== null && TEST_MODIFIERS4.has(modifier) ? testRoot2(callee.object) : null;
13788
14224
  }
13789
14225
  function isStatic(node) {
13790
- if (node.type === AST_NODE_TYPES57.TSAsExpression || node.type === AST_NODE_TYPES57.TSTypeAssertion || node.type === AST_NODE_TYPES57.TSSatisfiesExpression || node.type === AST_NODE_TYPES57.TSNonNullExpression) return isStatic(node.expression);
14226
+ if (node.type === AST_NODE_TYPES62.TSAsExpression || node.type === AST_NODE_TYPES62.TSTypeAssertion || node.type === AST_NODE_TYPES62.TSSatisfiesExpression || node.type === AST_NODE_TYPES62.TSNonNullExpression) return isStatic(node.expression);
13791
14227
  switch (node.type) {
13792
- case AST_NODE_TYPES57.Literal:
14228
+ case AST_NODE_TYPES62.Literal:
13793
14229
  return true;
13794
- case AST_NODE_TYPES57.TemplateLiteral:
14230
+ case AST_NODE_TYPES62.TemplateLiteral:
13795
14231
  return node.expressions.length === 0;
13796
- case AST_NODE_TYPES57.UnaryExpression:
14232
+ case AST_NODE_TYPES62.UnaryExpression:
13797
14233
  return (node.operator === "+" || node.operator === "-") && isStatic(node.argument);
13798
- case AST_NODE_TYPES57.ArrayExpression:
13799
- return node.elements.every((item) => item !== null && item.type !== AST_NODE_TYPES57.SpreadElement && isStatic(item));
13800
- case AST_NODE_TYPES57.ObjectExpression:
13801
- return node.properties.every((property) => property.type === AST_NODE_TYPES57.Property && !property.computed && property.kind === "init" && property.value.type !== AST_NODE_TYPES57.AssignmentPattern && isStatic(property.value));
14234
+ case AST_NODE_TYPES62.ArrayExpression:
14235
+ return node.elements.every((item) => item !== null && item.type !== AST_NODE_TYPES62.SpreadElement && isStatic(item));
14236
+ case AST_NODE_TYPES62.ObjectExpression:
14237
+ return node.properties.every((property) => property.type === AST_NODE_TYPES62.Property && !property.computed && property.kind === "init" && property.value.type !== AST_NODE_TYPES62.AssignmentPattern && isStatic(property.value));
13802
14238
  default:
13803
14239
  return false;
13804
14240
  }
13805
14241
  }
13806
14242
  function staticShape(node) {
13807
- if (node.type === AST_NODE_TYPES57.TSAsExpression || node.type === AST_NODE_TYPES57.TSTypeAssertion || node.type === AST_NODE_TYPES57.TSSatisfiesExpression || node.type === AST_NODE_TYPES57.TSNonNullExpression) return staticShape(node.expression);
14243
+ if (node.type === AST_NODE_TYPES62.TSAsExpression || node.type === AST_NODE_TYPES62.TSTypeAssertion || node.type === AST_NODE_TYPES62.TSSatisfiesExpression || node.type === AST_NODE_TYPES62.TSNonNullExpression) return staticShape(node.expression);
13808
14244
  switch (node.type) {
13809
- case AST_NODE_TYPES57.Literal:
14245
+ case AST_NODE_TYPES62.Literal:
13810
14246
  return `literal:${typeof node.value}`;
13811
- case AST_NODE_TYPES57.TemplateLiteral:
14247
+ case AST_NODE_TYPES62.TemplateLiteral:
13812
14248
  return "template";
13813
- case AST_NODE_TYPES57.UnaryExpression:
14249
+ case AST_NODE_TYPES62.UnaryExpression:
13814
14250
  return `unary:${node.operator}:${staticShape(node.argument)}`;
13815
- case AST_NODE_TYPES57.ArrayExpression:
13816
- return `array(${node.elements.map((item) => item === null || item.type === AST_NODE_TYPES57.SpreadElement ? "invalid" : staticShape(item)).join(",")})`;
13817
- case AST_NODE_TYPES57.ObjectExpression:
14251
+ case AST_NODE_TYPES62.ArrayExpression:
14252
+ return `array(${node.elements.map((item) => item === null || item.type === AST_NODE_TYPES62.SpreadElement ? "invalid" : staticShape(item)).join(",")})`;
14253
+ case AST_NODE_TYPES62.ObjectExpression:
13818
14254
  return `object(${node.properties.map((property) => {
13819
- if (property.type !== AST_NODE_TYPES57.Property || property.computed || property.value.type === AST_NODE_TYPES57.AssignmentPattern) return "invalid";
13820
- const key = property.key.type === AST_NODE_TYPES57.Identifier ? property.key.name : String(property.key.value);
14255
+ if (property.type !== AST_NODE_TYPES62.Property || property.computed || property.value.type === AST_NODE_TYPES62.AssignmentPattern) return "invalid";
14256
+ const key = property.key.type === AST_NODE_TYPES62.Identifier ? property.key.name : String(property.key.value);
13821
14257
  return `${key}:${staticShape(property.value)}`;
13822
14258
  }).join(",")})`;
13823
14259
  default:
@@ -13825,16 +14261,16 @@ function staticShape(node) {
13825
14261
  }
13826
14262
  }
13827
14263
  function assertionShape(statement, context) {
13828
- if (statement.type !== AST_NODE_TYPES57.ExpressionStatement || statement.expression.type !== AST_NODE_TYPES57.CallExpression) return null;
14264
+ if (statement.type !== AST_NODE_TYPES62.ExpressionStatement || statement.expression.type !== AST_NODE_TYPES62.CallExpression) return null;
13829
14265
  const matcherCall = statement.expression;
13830
- if (matcherCall.callee.type !== AST_NODE_TYPES57.MemberExpression || matcherCall.callee.computed || matcherCall.callee.property.type !== AST_NODE_TYPES57.Identifier || matcherCall.arguments.length !== 1) return null;
14266
+ if (matcherCall.callee.type !== AST_NODE_TYPES62.MemberExpression || matcherCall.callee.computed || matcherCall.callee.property.type !== AST_NODE_TYPES62.Identifier || matcherCall.arguments.length !== 1) return null;
13831
14267
  const matcher = matcherCall.callee.property.name;
13832
14268
  if (SNAPSHOT_MATCHERS.test(matcher)) return null;
13833
14269
  const chain = expectCallFromMatcher(matcherCall.callee);
13834
- if (chain === null || chain.call.callee.type !== AST_NODE_TYPES57.Identifier || importedName5(chain.call.callee, context, ASSERTION_MODULES3) !== "expect" || chain.call.arguments.length !== 1) return null;
14270
+ if (chain === null || chain.call.callee.type !== AST_NODE_TYPES62.Identifier || importedName6(chain.call.callee, context, ASSERTION_MODULES3) !== "expect" || chain.call.arguments.length !== 1) return null;
13835
14271
  const observed = chain.call.arguments[0];
13836
14272
  const expected = matcherCall.arguments[0];
13837
- if (observed?.type !== AST_NODE_TYPES57.CallExpression || observed.callee.type !== AST_NODE_TYPES57.Identifier || observed.arguments.length === 0 || observed.arguments.some((arg) => arg.type === AST_NODE_TYPES57.SpreadElement || !isStatic(arg)) || expected?.type === AST_NODE_TYPES57.SpreadElement || expected === void 0 || !isStatic(expected)) return null;
14273
+ if (observed?.type !== AST_NODE_TYPES62.CallExpression || observed.callee.type !== AST_NODE_TYPES62.Identifier || observed.arguments.length === 0 || observed.arguments.some((arg) => arg.type === AST_NODE_TYPES62.SpreadElement || !isStatic(arg)) || expected?.type === AST_NODE_TYPES62.SpreadElement || expected === void 0 || !isStatic(expected)) return null;
13838
14274
  const skeleton = `${observed.callee.name}/${observed.arguments.map((item) => staticShape(item)).join(",")}/${chain.modifiers.join(".")}/${matcher}/${staticShape(expected)}`;
13839
14275
  const values = [...observed.arguments, expected].map((item) => context.sourceCode.getText(item)).join("\0");
13840
14276
  return { statement, skeleton, values };
@@ -13842,13 +14278,13 @@ function assertionShape(statement, context) {
13842
14278
  function expectCallFromMatcher(node) {
13843
14279
  const modifiers = [];
13844
14280
  let receiver = node.object;
13845
- while (receiver.type === AST_NODE_TYPES57.MemberExpression) {
14281
+ while (receiver.type === AST_NODE_TYPES62.MemberExpression) {
13846
14282
  const modifier = staticMemberName5(receiver);
13847
14283
  if (modifier === null || !EXPECT_MODIFIERS.has(modifier)) return null;
13848
14284
  modifiers.unshift(modifier);
13849
14285
  receiver = receiver.object;
13850
14286
  }
13851
- return receiver.type === AST_NODE_TYPES57.CallExpression ? { call: receiver, modifiers } : null;
14287
+ return receiver.type === AST_NODE_TYPES62.CallExpression ? { call: receiver, modifiers } : null;
13852
14288
  }
13853
14289
  var repeated_static_call_cases_default = createRule({
13854
14290
  name: "repeated-static-call-cases",
@@ -13868,7 +14304,7 @@ var repeated_static_call_cases_default = createRule({
13868
14304
  return {
13869
14305
  "CallExpression > ArrowFunctionExpression, CallExpression > FunctionExpression"(node) {
13870
14306
  const call = node.parent;
13871
- if (call?.type === AST_NODE_TYPES57.CallExpression) {
14307
+ if (call?.type === AST_NODE_TYPES62.CallExpression) {
13872
14308
  const duplicate = duplicateTestBodyCandidate(call, sourceCode);
13873
14309
  if (duplicate !== null && duplicate.body === node) {
13874
14310
  const groups = duplicateGroups.get(duplicate.container) ?? /* @__PURE__ */ new Map();
@@ -13878,7 +14314,7 @@ var repeated_static_call_cases_default = createRule({
13878
14314
  duplicateGroups.set(duplicate.container, groups);
13879
14315
  }
13880
14316
  }
13881
- if (!isDirectTestCallback2(node, context) || node.body.type !== AST_NODE_TYPES57.BlockStatement) return;
14317
+ if (!isDirectTestCallback2(node, context) || node.body.type !== AST_NODE_TYPES62.BlockStatement) return;
13882
14318
  let run = [];
13883
14319
  const flush = () => {
13884
14320
  if (run.length >= MIN_CASES2 && new Set(run.map((item) => item.values)).size > 1) {
@@ -13919,7 +14355,7 @@ var repeated_static_call_cases_default = createRule({
13919
14355
  });
13920
14356
 
13921
14357
  // src/rules/prefer-zod-infer.ts
13922
- import { AST_NODE_TYPES as AST_NODE_TYPES58 } from "@typescript-eslint/utils";
14358
+ import { AST_NODE_TYPES as AST_NODE_TYPES63 } from "@typescript-eslint/utils";
13923
14359
  var PREFER_ZOD_INFER_DOCUMENTATION = {
13924
14360
  summary: "Derive a type from its Zod schema with `z.infer` instead of hand-writing a twin declaration beside it.",
13925
14361
  rationale: "A derived type stays synchronized when the runtime schema changes.",
@@ -13972,47 +14408,47 @@ var ZOD_TYPE_CONSTRAINTS = /* @__PURE__ */ new Set([
13972
14408
  "Schema"
13973
14409
  ]);
13974
14410
  var LEAF_NODE_TYPES = {
13975
- string: [AST_NODE_TYPES58.TSStringKeyword],
13976
- email: [AST_NODE_TYPES58.TSStringKeyword],
13977
- url: [AST_NODE_TYPES58.TSStringKeyword],
13978
- uuid: [AST_NODE_TYPES58.TSStringKeyword],
13979
- ulid: [AST_NODE_TYPES58.TSStringKeyword],
13980
- cuid: [AST_NODE_TYPES58.TSStringKeyword],
13981
- cuid2: [AST_NODE_TYPES58.TSStringKeyword],
13982
- nanoid: [AST_NODE_TYPES58.TSStringKeyword],
13983
- iso: [AST_NODE_TYPES58.TSStringKeyword],
13984
- number: [AST_NODE_TYPES58.TSNumberKeyword],
13985
- int: [AST_NODE_TYPES58.TSNumberKeyword],
13986
- float32: [AST_NODE_TYPES58.TSNumberKeyword],
13987
- float64: [AST_NODE_TYPES58.TSNumberKeyword],
13988
- boolean: [AST_NODE_TYPES58.TSBooleanKeyword],
13989
- bigint: [AST_NODE_TYPES58.TSBigIntKeyword],
13990
- symbol: [AST_NODE_TYPES58.TSSymbolKeyword],
13991
- any: [AST_NODE_TYPES58.TSAnyKeyword],
13992
- unknown: [AST_NODE_TYPES58.TSUnknownKeyword],
13993
- never: [AST_NODE_TYPES58.TSNeverKeyword],
13994
- void: [AST_NODE_TYPES58.TSVoidKeyword],
13995
- null: [AST_NODE_TYPES58.TSNullKeyword],
13996
- undefined: [AST_NODE_TYPES58.TSUndefinedKeyword],
13997
- literal: [AST_NODE_TYPES58.TSLiteralType],
13998
- date: [AST_NODE_TYPES58.TSTypeReference],
13999
- array: [AST_NODE_TYPES58.TSArrayType, AST_NODE_TYPES58.TSTypeReference],
14000
- tuple: [AST_NODE_TYPES58.TSTupleType],
14001
- object: [AST_NODE_TYPES58.TSTypeLiteral, AST_NODE_TYPES58.TSTypeReference],
14002
- strictObject: [AST_NODE_TYPES58.TSTypeLiteral, AST_NODE_TYPES58.TSTypeReference],
14003
- looseObject: [AST_NODE_TYPES58.TSTypeLiteral, AST_NODE_TYPES58.TSTypeReference],
14004
- record: [AST_NODE_TYPES58.TSTypeReference, AST_NODE_TYPES58.TSTypeLiteral],
14005
- map: [AST_NODE_TYPES58.TSTypeReference],
14006
- set: [AST_NODE_TYPES58.TSTypeReference],
14007
- promise: [AST_NODE_TYPES58.TSTypeReference],
14008
- enum: [AST_NODE_TYPES58.TSUnionType, AST_NODE_TYPES58.TSTypeReference, AST_NODE_TYPES58.TSLiteralType],
14009
- nativeEnum: [AST_NODE_TYPES58.TSUnionType, AST_NODE_TYPES58.TSTypeReference, AST_NODE_TYPES58.TSLiteralType],
14010
- union: [AST_NODE_TYPES58.TSUnionType, AST_NODE_TYPES58.TSTypeReference],
14011
- discriminatedUnion: [AST_NODE_TYPES58.TSUnionType, AST_NODE_TYPES58.TSTypeReference],
14012
- intersection: [AST_NODE_TYPES58.TSIntersectionType, AST_NODE_TYPES58.TSTypeReference]
14411
+ string: [AST_NODE_TYPES63.TSStringKeyword],
14412
+ email: [AST_NODE_TYPES63.TSStringKeyword],
14413
+ url: [AST_NODE_TYPES63.TSStringKeyword],
14414
+ uuid: [AST_NODE_TYPES63.TSStringKeyword],
14415
+ ulid: [AST_NODE_TYPES63.TSStringKeyword],
14416
+ cuid: [AST_NODE_TYPES63.TSStringKeyword],
14417
+ cuid2: [AST_NODE_TYPES63.TSStringKeyword],
14418
+ nanoid: [AST_NODE_TYPES63.TSStringKeyword],
14419
+ iso: [AST_NODE_TYPES63.TSStringKeyword],
14420
+ number: [AST_NODE_TYPES63.TSNumberKeyword],
14421
+ int: [AST_NODE_TYPES63.TSNumberKeyword],
14422
+ float32: [AST_NODE_TYPES63.TSNumberKeyword],
14423
+ float64: [AST_NODE_TYPES63.TSNumberKeyword],
14424
+ boolean: [AST_NODE_TYPES63.TSBooleanKeyword],
14425
+ bigint: [AST_NODE_TYPES63.TSBigIntKeyword],
14426
+ symbol: [AST_NODE_TYPES63.TSSymbolKeyword],
14427
+ any: [AST_NODE_TYPES63.TSAnyKeyword],
14428
+ unknown: [AST_NODE_TYPES63.TSUnknownKeyword],
14429
+ never: [AST_NODE_TYPES63.TSNeverKeyword],
14430
+ void: [AST_NODE_TYPES63.TSVoidKeyword],
14431
+ null: [AST_NODE_TYPES63.TSNullKeyword],
14432
+ undefined: [AST_NODE_TYPES63.TSUndefinedKeyword],
14433
+ literal: [AST_NODE_TYPES63.TSLiteralType],
14434
+ date: [AST_NODE_TYPES63.TSTypeReference],
14435
+ array: [AST_NODE_TYPES63.TSArrayType, AST_NODE_TYPES63.TSTypeReference],
14436
+ tuple: [AST_NODE_TYPES63.TSTupleType],
14437
+ object: [AST_NODE_TYPES63.TSTypeLiteral, AST_NODE_TYPES63.TSTypeReference],
14438
+ strictObject: [AST_NODE_TYPES63.TSTypeLiteral, AST_NODE_TYPES63.TSTypeReference],
14439
+ looseObject: [AST_NODE_TYPES63.TSTypeLiteral, AST_NODE_TYPES63.TSTypeReference],
14440
+ record: [AST_NODE_TYPES63.TSTypeReference, AST_NODE_TYPES63.TSTypeLiteral],
14441
+ map: [AST_NODE_TYPES63.TSTypeReference],
14442
+ set: [AST_NODE_TYPES63.TSTypeReference],
14443
+ promise: [AST_NODE_TYPES63.TSTypeReference],
14444
+ enum: [AST_NODE_TYPES63.TSUnionType, AST_NODE_TYPES63.TSTypeReference, AST_NODE_TYPES63.TSLiteralType],
14445
+ nativeEnum: [AST_NODE_TYPES63.TSUnionType, AST_NODE_TYPES63.TSTypeReference, AST_NODE_TYPES63.TSLiteralType],
14446
+ union: [AST_NODE_TYPES63.TSUnionType, AST_NODE_TYPES63.TSTypeReference],
14447
+ discriminatedUnion: [AST_NODE_TYPES63.TSUnionType, AST_NODE_TYPES63.TSTypeReference],
14448
+ intersection: [AST_NODE_TYPES63.TSIntersectionType, AST_NODE_TYPES63.TSTypeReference]
14013
14449
  };
14014
14450
  function primitiveLiteralKey(node) {
14015
- if (node.type !== AST_NODE_TYPES58.Literal) {
14451
+ if (node.type !== AST_NODE_TYPES63.Literal) {
14016
14452
  return null;
14017
14453
  }
14018
14454
  if (node.value === null) {
@@ -14044,13 +14480,13 @@ function staticZodDomain(leaf, call) {
14044
14480
  }
14045
14481
  if (leaf === "literal") {
14046
14482
  const [argument] = call.arguments;
14047
- if (argument === void 0 || argument.type === AST_NODE_TYPES58.SpreadElement) {
14483
+ if (argument === void 0 || argument.type === AST_NODE_TYPES63.SpreadElement) {
14048
14484
  return null;
14049
14485
  }
14050
- if (argument.type === AST_NODE_TYPES58.ArrayExpression) {
14486
+ if (argument.type === AST_NODE_TYPES63.ArrayExpression) {
14051
14487
  return exactDomain(
14052
14488
  argument.elements.map(
14053
- (element) => element === null || element.type === AST_NODE_TYPES58.SpreadElement ? null : primitiveLiteralKey(element)
14489
+ (element) => element === null || element.type === AST_NODE_TYPES63.SpreadElement ? null : primitiveLiteralKey(element)
14054
14490
  )
14055
14491
  );
14056
14492
  }
@@ -14058,13 +14494,13 @@ function staticZodDomain(leaf, call) {
14058
14494
  }
14059
14495
  if (leaf === "enum") {
14060
14496
  const [argument] = call.arguments;
14061
- if (argument === void 0 || argument.type === AST_NODE_TYPES58.SpreadElement) {
14497
+ if (argument === void 0 || argument.type === AST_NODE_TYPES63.SpreadElement) {
14062
14498
  return null;
14063
14499
  }
14064
- if (argument.type === AST_NODE_TYPES58.ArrayExpression) {
14500
+ if (argument.type === AST_NODE_TYPES63.ArrayExpression) {
14065
14501
  return exactDomain(
14066
14502
  argument.elements.map((element) => {
14067
- if (element === null || element.type === AST_NODE_TYPES58.SpreadElement) {
14503
+ if (element === null || element.type === AST_NODE_TYPES63.SpreadElement) {
14068
14504
  return null;
14069
14505
  }
14070
14506
  const key = primitiveLiteralKey(element);
@@ -14072,10 +14508,10 @@ function staticZodDomain(leaf, call) {
14072
14508
  })
14073
14509
  );
14074
14510
  }
14075
- if (argument.type === AST_NODE_TYPES58.ObjectExpression) {
14511
+ if (argument.type === AST_NODE_TYPES63.ObjectExpression) {
14076
14512
  return exactDomain(
14077
14513
  argument.properties.map((property) => {
14078
- if (property.type !== AST_NODE_TYPES58.Property || property.computed || property.kind !== "init" || property.method || property.shorthand) {
14514
+ if (property.type !== AST_NODE_TYPES63.Property || property.computed || property.kind !== "init" || property.method || property.shorthand) {
14079
14515
  return null;
14080
14516
  }
14081
14517
  const key = primitiveLiteralKey(property.value);
@@ -14102,15 +14538,15 @@ function sameDomain(left, right) {
14102
14538
  return true;
14103
14539
  }
14104
14540
  function isExportedDeclaration(node) {
14105
- return node.parent?.type === AST_NODE_TYPES58.ExportNamedDeclaration;
14541
+ return node.parent?.type === AST_NODE_TYPES63.ExportNamedDeclaration;
14106
14542
  }
14107
14543
  function isModuleLevelConst(node) {
14108
14544
  const declaration = node.parent;
14109
- if (declaration.type !== AST_NODE_TYPES58.VariableDeclaration || declaration.kind !== "const") {
14545
+ if (declaration.type !== AST_NODE_TYPES63.VariableDeclaration || declaration.kind !== "const") {
14110
14546
  return false;
14111
14547
  }
14112
14548
  const container = declaration.parent;
14113
- return container.type === AST_NODE_TYPES58.Program || container.type === AST_NODE_TYPES58.ExportNamedDeclaration && container.parent.type === AST_NODE_TYPES58.Program;
14549
+ return container.type === AST_NODE_TYPES63.Program || container.type === AST_NODE_TYPES63.ExportNamedDeclaration && container.parent.type === AST_NODE_TYPES63.Program;
14114
14550
  }
14115
14551
  function normalizeSchemaName(name) {
14116
14552
  return name.replace(/Schema$/i, "").replace(/^Z(?=[A-Z])/, "").toLowerCase();
@@ -14119,20 +14555,20 @@ function normalizeTypeName(name) {
14119
14555
  return name.replace(/Type$/, "").toLowerCase();
14120
14556
  }
14121
14557
  function unwrapNullish(annotation) {
14122
- if (annotation.type !== AST_NODE_TYPES58.TSUnionType) {
14558
+ if (annotation.type !== AST_NODE_TYPES63.TSUnionType) {
14123
14559
  return {
14124
14560
  core: annotation,
14125
- nullable: annotation.type === AST_NODE_TYPES58.TSNullKeyword
14561
+ nullable: annotation.type === AST_NODE_TYPES63.TSNullKeyword
14126
14562
  };
14127
14563
  }
14128
14564
  const rest = [];
14129
14565
  let nullable = false;
14130
14566
  for (const member of annotation.types) {
14131
- if (member.type === AST_NODE_TYPES58.TSNullKeyword) {
14567
+ if (member.type === AST_NODE_TYPES63.TSNullKeyword) {
14132
14568
  nullable = true;
14133
14569
  continue;
14134
14570
  }
14135
- if (member.type === AST_NODE_TYPES58.TSUndefinedKeyword) {
14571
+ if (member.type === AST_NODE_TYPES63.TSUndefinedKeyword) {
14136
14572
  continue;
14137
14573
  }
14138
14574
  rest.push(member);
@@ -14166,18 +14602,18 @@ function leafAgrees(field, annotation) {
14166
14602
  return null;
14167
14603
  }
14168
14604
  if (leaf === "date") {
14169
- return core.type === AST_NODE_TYPES58.TSTypeReference && core.typeName.type === AST_NODE_TYPES58.Identifier && core.typeName.name === "Date";
14605
+ return core.type === AST_NODE_TYPES63.TSTypeReference && core.typeName.type === AST_NODE_TYPES63.Identifier && core.typeName.name === "Date";
14170
14606
  }
14171
14607
  return expected.includes(core.type);
14172
14608
  }
14173
14609
  function typeLiteralDomain(annotation) {
14174
- const members = annotation.type === AST_NODE_TYPES58.TSUnionType ? annotation.types : [annotation];
14610
+ const members = annotation.type === AST_NODE_TYPES63.TSUnionType ? annotation.types : [annotation];
14175
14611
  const keys = [];
14176
14612
  for (const member of members) {
14177
- if (member.type === AST_NODE_TYPES58.TSNullKeyword) {
14613
+ if (member.type === AST_NODE_TYPES63.TSNullKeyword) {
14178
14614
  continue;
14179
14615
  }
14180
- if (member.type !== AST_NODE_TYPES58.TSLiteralType) {
14616
+ if (member.type !== AST_NODE_TYPES63.TSLiteralType) {
14181
14617
  return null;
14182
14618
  }
14183
14619
  keys.push(primitiveLiteralKey(member.literal));
@@ -14185,11 +14621,11 @@ function typeLiteralDomain(annotation) {
14185
14621
  return exactDomain(keys);
14186
14622
  }
14187
14623
  function staticStringUnionDomain(node) {
14188
- if (node.type !== AST_NODE_TYPES58.TSUnionType) {
14624
+ if (node.type !== AST_NODE_TYPES63.TSUnionType) {
14189
14625
  return null;
14190
14626
  }
14191
14627
  const keys = node.types.map((member) => {
14192
- if (member.type !== AST_NODE_TYPES58.TSLiteralType) {
14628
+ if (member.type !== AST_NODE_TYPES63.TSLiteralType) {
14193
14629
  return null;
14194
14630
  }
14195
14631
  const key = primitiveLiteralKey(member.literal);
@@ -14257,14 +14693,14 @@ var prefer_zod_infer_default = createRule({
14257
14693
  function zodCallChain(node) {
14258
14694
  const chain = [];
14259
14695
  let current = node;
14260
- while (current.type === AST_NODE_TYPES58.CallExpression) {
14696
+ while (current.type === AST_NODE_TYPES63.CallExpression) {
14261
14697
  const callee = current.callee;
14262
- if (callee.type !== AST_NODE_TYPES58.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES58.Identifier) {
14698
+ if (callee.type !== AST_NODE_TYPES63.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES63.Identifier) {
14263
14699
  return null;
14264
14700
  }
14265
14701
  chain.push(current);
14266
14702
  const receiver = callee.object;
14267
- if (receiver.type === AST_NODE_TYPES58.Identifier) {
14703
+ if (receiver.type === AST_NODE_TYPES63.Identifier) {
14268
14704
  return zodNamespaces.has(receiver.name) ? chain.reverse() : null;
14269
14705
  }
14270
14706
  current = receiver;
@@ -14273,14 +14709,14 @@ var prefer_zod_infer_default = createRule({
14273
14709
  }
14274
14710
  function methodName2(call) {
14275
14711
  const callee = call.callee;
14276
- return callee.type === AST_NODE_TYPES58.MemberExpression && callee.property.type === AST_NODE_TYPES58.Identifier ? callee.property.name : "";
14712
+ return callee.type === AST_NODE_TYPES63.MemberExpression && callee.property.type === AST_NODE_TYPES63.Identifier ? callee.property.name : "";
14277
14713
  }
14278
14714
  function recordZodImport(node) {
14279
14715
  if (!isZodModule(node.source.value)) {
14280
14716
  return;
14281
14717
  }
14282
14718
  for (const specifier of node.specifiers) {
14283
- if (specifier.type === AST_NODE_TYPES58.ImportNamespaceSpecifier || specifier.type === AST_NODE_TYPES58.ImportDefaultSpecifier || specifier.type === AST_NODE_TYPES58.ImportSpecifier && specifier.imported.type === AST_NODE_TYPES58.Identifier && specifier.imported.name === "z") {
14719
+ if (specifier.type === AST_NODE_TYPES63.ImportNamespaceSpecifier || specifier.type === AST_NODE_TYPES63.ImportDefaultSpecifier || specifier.type === AST_NODE_TYPES63.ImportSpecifier && specifier.imported.type === AST_NODE_TYPES63.Identifier && specifier.imported.name === "z") {
14284
14720
  zodNamespaces.add(specifier.local.name);
14285
14721
  }
14286
14722
  }
@@ -14290,13 +14726,13 @@ var prefer_zod_infer_default = createRule({
14290
14726
  let current = node;
14291
14727
  let leaf = null;
14292
14728
  let leafCall = null;
14293
- while (current.type === AST_NODE_TYPES58.CallExpression) {
14729
+ while (current.type === AST_NODE_TYPES63.CallExpression) {
14294
14730
  const callee = current.callee;
14295
- if (callee.type !== AST_NODE_TYPES58.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES58.Identifier) {
14731
+ if (callee.type !== AST_NODE_TYPES63.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES63.Identifier) {
14296
14732
  break;
14297
14733
  }
14298
14734
  const receiver = callee.object;
14299
- if (receiver.type === AST_NODE_TYPES58.Identifier && zodNamespaces.has(receiver.name)) {
14735
+ if (receiver.type === AST_NODE_TYPES63.Identifier && zodNamespaces.has(receiver.name)) {
14300
14736
  leaf = callee.property.name;
14301
14737
  leafCall = current;
14302
14738
  break;
@@ -14327,30 +14763,30 @@ var prefer_zod_infer_default = createRule({
14327
14763
  return domain instanceof Set && domain.size >= 2 ? domain : null;
14328
14764
  }
14329
14765
  function inferredSchemaName(node) {
14330
- if (node.type !== AST_NODE_TYPES58.TSTypeReference || node.typeName.type !== AST_NODE_TYPES58.TSQualifiedName || node.typeName.left.type !== AST_NODE_TYPES58.Identifier || !zodNamespaces.has(node.typeName.left.name) || node.typeName.right.name !== "infer") {
14766
+ if (node.type !== AST_NODE_TYPES63.TSTypeReference || node.typeName.type !== AST_NODE_TYPES63.TSQualifiedName || node.typeName.left.type !== AST_NODE_TYPES63.Identifier || !zodNamespaces.has(node.typeName.left.name) || node.typeName.right.name !== "infer") {
14331
14767
  return null;
14332
14768
  }
14333
14769
  const arguments_ = node.typeArguments?.params ?? [];
14334
14770
  const [argument] = arguments_;
14335
- return arguments_.length === 1 && argument?.type === AST_NODE_TYPES58.TSTypeQuery && argument.exprName.type === AST_NODE_TYPES58.Identifier ? argument.exprName.name : null;
14771
+ return arguments_.length === 1 && argument?.type === AST_NODE_TYPES63.TSTypeQuery && argument.exprName.type === AST_NODE_TYPES63.Identifier ? argument.exprName.name : null;
14336
14772
  }
14337
14773
  function recordLiteralUnions(members, owner, ownerName, exported) {
14338
14774
  for (const member of members) {
14339
- if (member.type !== AST_NODE_TYPES58.TSPropertySignature || member.computed || member.optional || member.readonly || member.typeAnnotation === void 0) {
14775
+ if (member.type !== AST_NODE_TYPES63.TSPropertySignature || member.computed || member.optional || member.readonly || member.typeAnnotation === void 0) {
14340
14776
  continue;
14341
14777
  }
14342
14778
  const key = member.key;
14343
- const propertyName5 = key.type === AST_NODE_TYPES58.Identifier ? key.name : key.type === AST_NODE_TYPES58.Literal && typeof key.value === "string" ? key.value : null;
14344
- if (propertyName5 === null) {
14779
+ const propertyName7 = key.type === AST_NODE_TYPES63.Identifier ? key.name : key.type === AST_NODE_TYPES63.Literal && typeof key.value === "string" ? key.value : null;
14780
+ if (propertyName7 === null) {
14345
14781
  continue;
14346
14782
  }
14347
- const propertyTokens = nameTokens(propertyName5);
14783
+ const propertyTokens = nameTokens(propertyName7);
14348
14784
  if (propertyTokens.length < 2) {
14349
14785
  continue;
14350
14786
  }
14351
14787
  const annotation = member.typeAnnotation.typeAnnotation;
14352
14788
  const domain = staticStringUnionDomain(annotation);
14353
- if (domain === null || annotation.type !== AST_NODE_TYPES58.TSUnionType) {
14789
+ if (domain === null || annotation.type !== AST_NODE_TYPES63.TSUnionType) {
14354
14790
  continue;
14355
14791
  }
14356
14792
  literalUnionOccurrences.push({
@@ -14359,7 +14795,7 @@ var prefer_zod_infer_default = createRule({
14359
14795
  node: annotation,
14360
14796
  owner,
14361
14797
  ownerName,
14362
- propertyName: propertyName5,
14798
+ propertyName: propertyName7,
14363
14799
  propertyTokens
14364
14800
  });
14365
14801
  }
@@ -14381,16 +14817,16 @@ var prefer_zod_infer_default = createRule({
14381
14817
  return null;
14382
14818
  }
14383
14819
  const shape = base.arguments[0];
14384
- if (shape === void 0 || shape.type !== AST_NODE_TYPES58.ObjectExpression) {
14820
+ if (shape === void 0 || shape.type !== AST_NODE_TYPES63.ObjectExpression) {
14385
14821
  return null;
14386
14822
  }
14387
14823
  const fields = /* @__PURE__ */ new Map();
14388
14824
  for (const property of shape.properties) {
14389
- if (property.type !== AST_NODE_TYPES58.Property || property.computed) {
14825
+ if (property.type !== AST_NODE_TYPES63.Property || property.computed) {
14390
14826
  return null;
14391
14827
  }
14392
14828
  const { key } = property;
14393
- const name = key.type === AST_NODE_TYPES58.Identifier ? key.name : key.type === AST_NODE_TYPES58.Literal && typeof key.value === "string" ? key.value : null;
14829
+ const name = key.type === AST_NODE_TYPES63.Identifier ? key.name : key.type === AST_NODE_TYPES63.Literal && typeof key.value === "string" ? key.value : null;
14394
14830
  if (name === null) {
14395
14831
  return null;
14396
14832
  }
@@ -14401,11 +14837,11 @@ var prefer_zod_infer_default = createRule({
14401
14837
  function typeMembers(members) {
14402
14838
  const result = /* @__PURE__ */ new Map();
14403
14839
  for (const member of members) {
14404
- if (member.type !== AST_NODE_TYPES58.TSPropertySignature || member.computed) {
14840
+ if (member.type !== AST_NODE_TYPES63.TSPropertySignature || member.computed) {
14405
14841
  return null;
14406
14842
  }
14407
14843
  const { key } = member;
14408
- const name = key.type === AST_NODE_TYPES58.Identifier ? key.name : key.type === AST_NODE_TYPES58.Literal && typeof key.value === "string" ? key.value : null;
14844
+ const name = key.type === AST_NODE_TYPES63.Identifier ? key.name : key.type === AST_NODE_TYPES63.Literal && typeof key.value === "string" ? key.value : null;
14409
14845
  if (name === null) {
14410
14846
  return null;
14411
14847
  }
@@ -14420,8 +14856,8 @@ var prefer_zod_infer_default = createRule({
14420
14856
  return result.size === 0 ? null : result;
14421
14857
  }
14422
14858
  function collectConstrainedNames(node) {
14423
- if (node.type === AST_NODE_TYPES58.TSTypeReference) {
14424
- if (node.typeName.type === AST_NODE_TYPES58.Identifier) {
14859
+ if (node.type === AST_NODE_TYPES63.TSTypeReference) {
14860
+ if (node.typeName.type === AST_NODE_TYPES63.Identifier) {
14425
14861
  constrainedTypeNames.add(node.typeName.name);
14426
14862
  }
14427
14863
  for (const argument of node.typeArguments?.params ?? []) {
@@ -14429,11 +14865,11 @@ var prefer_zod_infer_default = createRule({
14429
14865
  }
14430
14866
  return;
14431
14867
  }
14432
- if (node.type === AST_NODE_TYPES58.TSArrayType) {
14868
+ if (node.type === AST_NODE_TYPES63.TSArrayType) {
14433
14869
  collectConstrainedNames(node.elementType);
14434
14870
  return;
14435
14871
  }
14436
- if (node.type === AST_NODE_TYPES58.TSUnionType || node.type === AST_NODE_TYPES58.TSIntersectionType) {
14872
+ if (node.type === AST_NODE_TYPES63.TSUnionType || node.type === AST_NODE_TYPES63.TSIntersectionType) {
14437
14873
  for (const member of node.types) {
14438
14874
  collectConstrainedNames(member);
14439
14875
  }
@@ -14477,7 +14913,7 @@ var prefer_zod_infer_default = createRule({
14477
14913
  return {
14478
14914
  Program(node) {
14479
14915
  for (const statement of node.body) {
14480
- if (statement.type === AST_NODE_TYPES58.ImportDeclaration) {
14916
+ if (statement.type === AST_NODE_TYPES63.ImportDeclaration) {
14481
14917
  recordZodImport(statement);
14482
14918
  }
14483
14919
  }
@@ -14486,7 +14922,7 @@ var prefer_zod_infer_default = createRule({
14486
14922
  recordZodImport(node);
14487
14923
  },
14488
14924
  VariableDeclarator(node) {
14489
- if (node.id.type !== AST_NODE_TYPES58.Identifier || node.init == null) {
14925
+ if (node.id.type !== AST_NODE_TYPES63.Identifier || node.init == null) {
14490
14926
  return;
14491
14927
  }
14492
14928
  const fields = schemaFields(node.init);
@@ -14503,14 +14939,14 @@ var prefer_zod_infer_default = createRule({
14503
14939
  },
14504
14940
  /** Records `XSchema.transform(...)` and equivalent module-level reshaping. */
14505
14941
  "MemberExpression[computed=false]"(node) {
14506
- if (node.object.type === AST_NODE_TYPES58.Identifier && node.property.type === AST_NODE_TYPES58.Identifier && MODULE_LEVEL_RESHAPERS.has(node.property.name)) {
14942
+ if (node.object.type === AST_NODE_TYPES63.Identifier && node.property.type === AST_NODE_TYPES63.Identifier && MODULE_LEVEL_RESHAPERS.has(node.property.name)) {
14507
14943
  reshapedSchemaNames.add(node.object.name);
14508
14944
  }
14509
14945
  },
14510
14946
  /** Records every type argument carried by a Zod constraint. */
14511
14947
  TSTypeReference(node) {
14512
14948
  const { typeName } = node;
14513
- const referenced = typeName.type === AST_NODE_TYPES58.Identifier ? typeName.name : typeName.type === AST_NODE_TYPES58.TSQualifiedName && typeName.right.type === AST_NODE_TYPES58.Identifier ? typeName.right.name : null;
14949
+ const referenced = typeName.type === AST_NODE_TYPES63.Identifier ? typeName.name : typeName.type === AST_NODE_TYPES63.TSQualifiedName && typeName.right.type === AST_NODE_TYPES63.Identifier ? typeName.right.name : null;
14514
14950
  if (referenced === null || !ZOD_TYPE_CONSTRAINTS.has(referenced)) {
14515
14951
  return;
14516
14952
  }
@@ -14542,7 +14978,7 @@ var prefer_zod_infer_default = createRule({
14542
14978
  typeName: node.id.name
14543
14979
  });
14544
14980
  }
14545
- if (node.typeParameters !== void 0 || node.typeAnnotation.type !== AST_NODE_TYPES58.TSTypeLiteral) {
14981
+ if (node.typeParameters !== void 0 || node.typeAnnotation.type !== AST_NODE_TYPES63.TSTypeLiteral) {
14546
14982
  return;
14547
14983
  }
14548
14984
  const members = typeMembers(node.typeAnnotation.members);
@@ -14643,7 +15079,7 @@ var prefer_zod_infer_default = createRule({
14643
15079
  // src/rules/require-assert-never.ts
14644
15080
  import {
14645
15081
  ESLintUtils as ESLintUtils7,
14646
- AST_NODE_TYPES as AST_NODE_TYPES59
15082
+ AST_NODE_TYPES as AST_NODE_TYPES64
14647
15083
  } from "@typescript-eslint/utils";
14648
15084
  import ts5 from "typescript";
14649
15085
  var REQUIRE_ASSERT_NEVER_DOCUMENTATION = {
@@ -14657,14 +15093,14 @@ var REQUIRE_ASSERT_NEVER_DOCUMENTATION = {
14657
15093
  ]
14658
15094
  };
14659
15095
  var isRuntimeHandlingStatement = (statement) => {
14660
- if (statement.type === AST_NODE_TYPES59.EmptyStatement) return false;
14661
- if (statement.type === AST_NODE_TYPES59.BreakStatement) {
15096
+ if (statement.type === AST_NODE_TYPES64.EmptyStatement) return false;
15097
+ if (statement.type === AST_NODE_TYPES64.BreakStatement) {
14662
15098
  return statement.label !== null;
14663
15099
  }
14664
- if (statement.type === AST_NODE_TYPES59.TSTypeAliasDeclaration || statement.type === AST_NODE_TYPES59.TSInterfaceDeclaration) {
15100
+ if (statement.type === AST_NODE_TYPES64.TSTypeAliasDeclaration || statement.type === AST_NODE_TYPES64.TSInterfaceDeclaration) {
14665
15101
  return false;
14666
15102
  }
14667
- if (statement.type === AST_NODE_TYPES59.BlockStatement) {
15103
+ if (statement.type === AST_NODE_TYPES64.BlockStatement) {
14668
15104
  return statement.body.some(isRuntimeHandlingStatement);
14669
15105
  }
14670
15106
  return true;
@@ -14680,7 +15116,7 @@ var isCommentOnlyNoopDefault = (defaultCase, sourceCode) => {
14680
15116
  return colonToken !== null && sourceCode.getCommentsAfter(colonToken).length > 0;
14681
15117
  }
14682
15118
  const only = defaultCase.consequent[0];
14683
- if (only !== void 0 && defaultCase.consequent.length === 1 && only.type === AST_NODE_TYPES59.BlockStatement && !only.body.some(isRuntimeHandlingStatement)) {
15119
+ if (only !== void 0 && defaultCase.consequent.length === 1 && only.type === AST_NODE_TYPES64.BlockStatement && !only.body.some(isRuntimeHandlingStatement)) {
14684
15120
  return sourceCode.getCommentsInside(only).length > 0;
14685
15121
  }
14686
15122
  return false;
@@ -14763,7 +15199,7 @@ var require_assert_never_default = createRule({
14763
15199
  });
14764
15200
 
14765
15201
  // src/rules/require-fetch-timeout.ts
14766
- import { AST_NODE_TYPES as AST_NODE_TYPES60, ASTUtils as ASTUtils19 } from "@typescript-eslint/utils";
15202
+ import { AST_NODE_TYPES as AST_NODE_TYPES65, ASTUtils as ASTUtils20 } from "@typescript-eslint/utils";
14767
15203
  var REQUIRE_FETCH_TIMEOUT_DOCUMENTATION = {
14768
15204
  summary: "Require an abort `signal` (e.g. `AbortSignal.timeout(ms)`) on global `fetch()` calls so stalled upstreams cannot hang the caller forever.",
14769
15205
  rationale: "An unbounded request can occupy work indefinitely when an upstream stalls.",
@@ -14789,14 +15225,14 @@ function matchesAnyPattern3(filename, patterns) {
14789
15225
  return false;
14790
15226
  }
14791
15227
  function initProvablyLacksSignal(init) {
14792
- if (init.type !== AST_NODE_TYPES60.ObjectExpression) {
15228
+ if (init.type !== AST_NODE_TYPES65.ObjectExpression) {
14793
15229
  return false;
14794
15230
  }
14795
15231
  for (const prop of init.properties) {
14796
- if (prop.type === AST_NODE_TYPES60.SpreadElement) {
15232
+ if (prop.type === AST_NODE_TYPES65.SpreadElement) {
14797
15233
  return false;
14798
15234
  }
14799
- if (prop.key.type === AST_NODE_TYPES60.Identifier && prop.key.name === "signal" || prop.key.type === AST_NODE_TYPES60.Literal && prop.key.value === "signal") {
15235
+ if (prop.key.type === AST_NODE_TYPES65.Identifier && prop.key.name === "signal" || prop.key.type === AST_NODE_TYPES65.Literal && prop.key.value === "signal") {
14800
15236
  return false;
14801
15237
  }
14802
15238
  if (prop.computed) {
@@ -14806,7 +15242,7 @@ function initProvablyLacksSignal(init) {
14806
15242
  return true;
14807
15243
  }
14808
15244
  function isInlineUrl(node, resolvesToGlobal) {
14809
- return node.type === AST_NODE_TYPES60.Literal && typeof node.value === "string" || node.type === AST_NODE_TYPES60.TemplateLiteral || node.type === AST_NODE_TYPES60.NewExpression && node.callee.type === AST_NODE_TYPES60.Identifier && node.callee.name === "URL" && resolvesToGlobal(node.callee);
15245
+ return node.type === AST_NODE_TYPES65.Literal && typeof node.value === "string" || node.type === AST_NODE_TYPES65.TemplateLiteral || node.type === AST_NODE_TYPES65.NewExpression && node.callee.type === AST_NODE_TYPES65.Identifier && node.callee.name === "URL" && resolvesToGlobal(node.callee);
14810
15246
  }
14811
15247
  var require_fetch_timeout_default = createRule({
14812
15248
  name: "require-fetch-timeout",
@@ -14844,30 +15280,30 @@ var require_fetch_timeout_default = createRule({
14844
15280
  }
14845
15281
  function resolvesToGlobal(identifier) {
14846
15282
  const scope = context.sourceCode.getScope(identifier);
14847
- const variable = ASTUtils19.findVariable(scope, identifier.name);
15283
+ const variable = ASTUtils20.findVariable(scope, identifier.name);
14848
15284
  return variable === null || variable.defs.length === 0;
14849
15285
  }
14850
15286
  function isGlobalFetchCall2(callee) {
14851
- if (callee.type === AST_NODE_TYPES60.Identifier) {
15287
+ if (callee.type === AST_NODE_TYPES65.Identifier) {
14852
15288
  return callee.name === "fetch" && resolvesToGlobal(callee);
14853
15289
  }
14854
- return callee.type === AST_NODE_TYPES60.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES60.Identifier && callee.property.name === "fetch" && callee.object.type === AST_NODE_TYPES60.Identifier && GLOBAL_OBJECTS2.has(callee.object.name) && resolvesToGlobal(callee.object);
15290
+ return callee.type === AST_NODE_TYPES65.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES65.Identifier && callee.property.name === "fetch" && callee.object.type === AST_NODE_TYPES65.Identifier && GLOBAL_OBJECTS2.has(callee.object.name) && resolvesToGlobal(callee.object);
14855
15291
  }
14856
15292
  function localConstInitProvablyLacksSignal(identifier) {
14857
- const variable = ASTUtils19.findVariable(
15293
+ const variable = ASTUtils20.findVariable(
14858
15294
  context.sourceCode.getScope(identifier),
14859
15295
  identifier.name
14860
15296
  );
14861
15297
  if (variable?.defs.length !== 1) return false;
14862
15298
  const definition = variable.defs[0];
14863
- if (definition?.type !== "Variable" || definition.parent.kind !== "const" || definition.node.init?.type !== AST_NODE_TYPES60.ObjectExpression || !initProvablyLacksSignal(definition.node.init)) {
15299
+ if (definition?.type !== "Variable" || definition.parent.kind !== "const" || definition.node.init?.type !== AST_NODE_TYPES65.ObjectExpression || !initProvablyLacksSignal(definition.node.init)) {
14864
15300
  return false;
14865
15301
  }
14866
15302
  for (const reference of variable.references) {
14867
15303
  const ref = reference.identifier;
14868
15304
  if (ref === identifier || ref === definition.name) continue;
14869
15305
  const member = ref.parent;
14870
- if (member.type !== AST_NODE_TYPES60.MemberExpression || member.object !== ref || member.computed || member.property.type !== AST_NODE_TYPES60.Identifier || member.property.name === "signal" || member.parent.type !== AST_NODE_TYPES60.AssignmentExpression || member.parent.left !== member) {
15306
+ if (member.type !== AST_NODE_TYPES65.MemberExpression || member.object !== ref || member.computed || member.property.type !== AST_NODE_TYPES65.Identifier || member.property.name === "signal" || member.parent.type !== AST_NODE_TYPES65.AssignmentExpression || member.parent.left !== member) {
14871
15307
  return false;
14872
15308
  }
14873
15309
  }
@@ -14882,7 +15318,7 @@ var require_fetch_timeout_default = createRule({
14882
15318
  if (node.arguments.length === 1 && first !== void 0 && !isInlineUrl(first, resolvesToGlobal)) {
14883
15319
  return;
14884
15320
  }
14885
- if (init === void 0 || initProvablyLacksSignal(init) || init.type === AST_NODE_TYPES60.Identifier && localConstInitProvablyLacksSignal(init)) {
15321
+ if (init === void 0 || initProvablyLacksSignal(init) || init.type === AST_NODE_TYPES65.Identifier && localConstInitProvablyLacksSignal(init)) {
14886
15322
  context.report({ node, messageId: "missingSignal" });
14887
15323
  }
14888
15324
  }
@@ -14890,8 +15326,141 @@ var require_fetch_timeout_default = createRule({
14890
15326
  }
14891
15327
  });
14892
15328
 
15329
+ // src/rules/require-interface-for-exported-class.ts
15330
+ import { AST_NODE_TYPES as AST_NODE_TYPES66 } from "@typescript-eslint/utils";
15331
+ var REQUIRE_INTERFACE_FOR_EXPORTED_CLASS_DOCUMENTATION = {
15332
+ summary: "Require exported concrete classes with public behavior to declare a contract.",
15333
+ rationale: "Consumers coupled only to a concrete class cannot substitute implementations or state the supported public capability independently of implementation details.",
15334
+ remediation: "Declare a focused interface and add an implements clause, or inherit from an intentional base contract.",
15335
+ category: "architecture",
15336
+ limitations: [
15337
+ "The warning-stage rule checks module-level class declarations and direct class-expression values exported directly, through local export specifiers, or through a default identifier; re-exports and expressions wrapped in other calls require review.",
15338
+ "An extends clause satisfies the contract only when its target is a locally declared abstract class; imported base-class contracts require an explicit implements clause.",
15339
+ "Static factories and data-only classes without public instance methods are outside the contract requirement."
15340
+ ],
15341
+ examples: [
15342
+ {
15343
+ id: "implemented-store-contract",
15344
+ title: "Export behavior through a focused contract",
15345
+ outcome: "no-match",
15346
+ files: [
15347
+ {
15348
+ path: "src/artifact-store.ts",
15349
+ source: "export interface ArtifactStorage { read(id: string): Promise<Uint8Array>; } export class ArtifactStore implements ArtifactStorage { async read(id: string) { return new Uint8Array(); } }"
15350
+ }
15351
+ ],
15352
+ focusPath: "src/artifact-store.ts",
15353
+ expectedCount: 0,
15354
+ public: true
15355
+ },
15356
+ {
15357
+ id: "concrete-only-store",
15358
+ title: "Do not export behavior only through a concrete class",
15359
+ outcome: "match",
15360
+ files: [
15361
+ {
15362
+ path: "src/artifact-store.ts",
15363
+ source: "export class ArtifactStore { async read(id: string) { return new Uint8Array(); } }"
15364
+ }
15365
+ ],
15366
+ focusPath: "src/artifact-store.ts",
15367
+ expectedCount: 1,
15368
+ public: true
15369
+ }
15370
+ ]
15371
+ };
15372
+ function hasPublicInstanceBehavior(node) {
15373
+ return node.body.body.some((member) => {
15374
+ if (member.type === AST_NODE_TYPES66.MethodDefinition) {
15375
+ return member.kind !== "constructor" && !member.static && member.accessibility !== "private" && member.accessibility !== "protected" && member.key.type !== AST_NODE_TYPES66.PrivateIdentifier;
15376
+ }
15377
+ if (member.type !== AST_NODE_TYPES66.PropertyDefinition || member.static)
15378
+ return false;
15379
+ if (member.accessibility === "private" || member.accessibility === "protected" || member.key.type === AST_NODE_TYPES66.PrivateIdentifier) return false;
15380
+ return member.value?.type === AST_NODE_TYPES66.ArrowFunctionExpression || member.value?.type === AST_NODE_TYPES66.FunctionExpression || member.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES66.TSFunctionType;
15381
+ });
15382
+ }
15383
+ function classBindings(statement) {
15384
+ const declaration = statement.type === AST_NODE_TYPES66.ExportNamedDeclaration ? statement.declaration : statement;
15385
+ if (declaration?.type === AST_NODE_TYPES66.ClassDeclaration) {
15386
+ return declaration.id === null ? [] : [{ declaration, name: declaration.id.name }];
15387
+ }
15388
+ if (declaration?.type !== AST_NODE_TYPES66.VariableDeclaration) return [];
15389
+ return declaration.declarations.flatMap(
15390
+ (item) => item.id.type === AST_NODE_TYPES66.Identifier && item.init?.type === AST_NODE_TYPES66.ClassExpression ? [{ declaration: item.init, name: item.id.name }] : []
15391
+ );
15392
+ }
15393
+ var require_interface_for_exported_class_default = createRule({
15394
+ name: "require-interface-for-exported-class",
15395
+ documentation: REQUIRE_INTERFACE_FOR_EXPORTED_CLASS_DOCUMENTATION,
15396
+ meta: {
15397
+ type: "suggestion",
15398
+ docs: {
15399
+ description: "Require exported concrete classes with public behavior to declare a contract."
15400
+ },
15401
+ schema: [],
15402
+ messages: {
15403
+ requireContract: "Exported class `{{name}}` has public behavior but no declared interface or base contract; add a focused contract and implement it."
15404
+ }
15405
+ },
15406
+ defaultOptions: [],
15407
+ create(context) {
15408
+ if (isTestFile(context.filename) || isStoryFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
15409
+ return {
15410
+ "Program:exit"(program) {
15411
+ const classes = /* @__PURE__ */ new Map();
15412
+ const abstractBases = /* @__PURE__ */ new Set();
15413
+ for (const statement of program.body) {
15414
+ for (const binding of classBindings(statement)) {
15415
+ classes.set(binding.name, binding.declaration);
15416
+ if (binding.declaration.abstract) abstractBases.add(binding.name);
15417
+ }
15418
+ }
15419
+ const exported = /* @__PURE__ */ new Map();
15420
+ for (const statement of program.body) {
15421
+ if (statement.type === AST_NODE_TYPES66.ExportNamedDeclaration) {
15422
+ for (const binding of classBindings(statement)) {
15423
+ exported.set(binding.declaration, binding.name);
15424
+ }
15425
+ if (statement.source !== null || statement.exportKind === "type") continue;
15426
+ for (const specifier of statement.specifiers) {
15427
+ if (specifier.exportKind === "type") continue;
15428
+ const candidate2 = classes.get(specifier.local.name);
15429
+ if (candidate2 === void 0) continue;
15430
+ const exportedName = specifier.exported.type === AST_NODE_TYPES66.Identifier ? specifier.exported.name : specifier.exported.value;
15431
+ exported.set(candidate2, exportedName);
15432
+ }
15433
+ continue;
15434
+ }
15435
+ if (statement.type !== AST_NODE_TYPES66.ExportDefaultDeclaration) continue;
15436
+ if (statement.declaration.type === AST_NODE_TYPES66.ClassDeclaration || statement.declaration.type === AST_NODE_TYPES66.ClassExpression) {
15437
+ exported.set(
15438
+ statement.declaration,
15439
+ statement.declaration.id?.name ?? "default"
15440
+ );
15441
+ } else if (statement.declaration.type === AST_NODE_TYPES66.Identifier) {
15442
+ const candidate2 = classes.get(statement.declaration.name);
15443
+ if (candidate2 !== void 0) {
15444
+ exported.set(candidate2, statement.declaration.name);
15445
+ }
15446
+ }
15447
+ }
15448
+ for (const [declaration, exportedName] of exported) {
15449
+ const extendsLocalAbstractBase = declaration.superClass?.type === AST_NODE_TYPES66.Identifier && abstractBases.has(declaration.superClass.name);
15450
+ if (declaration.abstract || declaration.implements.length > 0 || extendsLocalAbstractBase || !hasPublicInstanceBehavior(declaration)) continue;
15451
+ context.report({
15452
+ node: declaration.id ?? declaration,
15453
+ messageId: "requireContract",
15454
+ data: { name: exportedName }
15455
+ });
15456
+ }
15457
+ }
15458
+ };
15459
+ }
15460
+ });
15461
+
14893
15462
  // src/rules/require-port-for-service.ts
14894
- import { AST_NODE_TYPES as AST_NODE_TYPES61 } from "@typescript-eslint/utils";
15463
+ import { AST_NODE_TYPES as AST_NODE_TYPES67 } from "@typescript-eslint/utils";
14895
15464
  var REQUIRE_PORT_FOR_SERVICE_DOCUMENTATION = {
14896
15465
  summary: "Advise when an exported service with injected collaborators has public methods not covered by its declared ports.",
14897
15466
  rationale: "A declared port keeps consumers coupled to the service capability instead of its concrete implementation.",
@@ -14916,45 +15485,45 @@ var ROUTER_FACTORY_NAME = "Router";
14916
15485
  var FRAMEWORK_HTTP_TYPES = /* @__PURE__ */ new Set(["Request", "Response", "NextFunction"]);
14917
15486
  var STORAGE_ASSIGNMENT_OPERATORS = /* @__PURE__ */ new Set(["=", "&&=", "??=", "||="]);
14918
15487
  var staticMemberName6 = (member) => {
14919
- if (member.property.type === AST_NODE_TYPES61.PrivateIdentifier) return `#${member.property.name}`;
14920
- if (!member.computed && member.property.type === AST_NODE_TYPES61.Identifier) return member.property.name;
14921
- return member.computed && member.property.type === AST_NODE_TYPES61.Literal && typeof member.property.value === "string" ? member.property.value : null;
15488
+ if (member.property.type === AST_NODE_TYPES67.PrivateIdentifier) return `#${member.property.name}`;
15489
+ if (!member.computed && member.property.type === AST_NODE_TYPES67.Identifier) return member.property.name;
15490
+ return member.computed && member.property.type === AST_NODE_TYPES67.Literal && typeof member.property.value === "string" ? member.property.value : null;
14922
15491
  };
14923
15492
  var detachedValueExports = (program) => {
14924
15493
  const names = /* @__PURE__ */ new Set();
14925
15494
  for (const statement of program.body) {
14926
- if (statement.type === AST_NODE_TYPES61.ExportNamedDeclaration && statement.declaration === null && statement.source === null && statement.exportKind !== "type") {
15495
+ if (statement.type === AST_NODE_TYPES67.ExportNamedDeclaration && statement.declaration === null && statement.source === null && statement.exportKind !== "type") {
14927
15496
  for (const specifier of statement.specifiers) {
14928
15497
  if (specifier.exportKind !== "type") names.add(specifier.local.name);
14929
15498
  }
14930
- } else if (statement.type === AST_NODE_TYPES61.ExportDefaultDeclaration && statement.declaration.type === AST_NODE_TYPES61.Identifier) {
15499
+ } else if (statement.type === AST_NODE_TYPES67.ExportDefaultDeclaration && statement.declaration.type === AST_NODE_TYPES67.Identifier) {
14931
15500
  names.add(statement.declaration.name);
14932
- } else if (statement.type === AST_NODE_TYPES61.TSExportAssignment && statement.expression.type === AST_NODE_TYPES61.Identifier) {
15501
+ } else if (statement.type === AST_NODE_TYPES67.TSExportAssignment && statement.expression.type === AST_NODE_TYPES67.Identifier) {
14933
15502
  names.add(statement.expression.name);
14934
15503
  }
14935
15504
  }
14936
15505
  return names;
14937
15506
  };
14938
- var isExportedClass2 = (node, detached) => node.parent.type === AST_NODE_TYPES61.ExportNamedDeclaration || node.parent.type === AST_NODE_TYPES61.ExportDefaultDeclaration || node.id !== null && detached.has(node.id.name);
15507
+ var isExportedClass2 = (node, detached) => node.parent.type === AST_NODE_TYPES67.ExportNamedDeclaration || node.parent.type === AST_NODE_TYPES67.ExportDefaultDeclaration || node.id !== null && detached.has(node.id.name);
14939
15508
  var readTypeReference = (annotation) => {
14940
- if (annotation?.type === AST_NODE_TYPES61.TSUnionType) {
15509
+ if (annotation?.type === AST_NODE_TYPES67.TSUnionType) {
14941
15510
  const members = annotation.types.filter(
14942
- (member) => member.type !== AST_NODE_TYPES61.TSUndefinedKeyword && member.type !== AST_NODE_TYPES61.TSNullKeyword
15511
+ (member) => member.type !== AST_NODE_TYPES67.TSUndefinedKeyword && member.type !== AST_NODE_TYPES67.TSNullKeyword
14943
15512
  );
14944
15513
  annotation = members.length === 1 ? members[0] : void 0;
14945
15514
  }
14946
- if (annotation === void 0 || annotation.type !== AST_NODE_TYPES61.TSTypeReference) return null;
15515
+ if (annotation === void 0 || annotation.type !== AST_NODE_TYPES67.TSTypeReference) return null;
14947
15516
  const { typeName } = annotation;
14948
- const rightmost = typeName.type === AST_NODE_TYPES61.Identifier ? typeName.name : typeName.type === AST_NODE_TYPES61.TSQualifiedName ? typeName.right.name : null;
15517
+ const rightmost = typeName.type === AST_NODE_TYPES67.Identifier ? typeName.name : typeName.type === AST_NODE_TYPES67.TSQualifiedName ? typeName.right.name : null;
14949
15518
  if (rightmost === null) return null;
14950
15519
  return { typeName: rightmost, display: qualifiedName(typeName) };
14951
15520
  };
14952
- var qualifiedName = (name) => name.type === AST_NODE_TYPES61.Identifier ? name.name : name.type === AST_NODE_TYPES61.TSQualifiedName ? `${qualifiedName(name.left)}.${name.right.name}` : "";
15521
+ var qualifiedName = (name) => name.type === AST_NODE_TYPES67.Identifier ? name.name : name.type === AST_NODE_TYPES67.TSQualifiedName ? `${qualifiedName(name.left)}.${name.right.name}` : "";
14953
15522
  var propertySignatureTypes = (members) => {
14954
15523
  const types = /* @__PURE__ */ new Map();
14955
15524
  for (const member of members) {
14956
- if (member.type !== AST_NODE_TYPES61.TSPropertySignature) continue;
14957
- if (member.computed || member.key.type !== AST_NODE_TYPES61.Identifier) continue;
15525
+ if (member.type !== AST_NODE_TYPES67.TSPropertySignature) continue;
15526
+ if (member.computed || member.key.type !== AST_NODE_TYPES67.Identifier) continue;
14958
15527
  const reference = readTypeReference(member.typeAnnotation?.typeAnnotation);
14959
15528
  if (reference === null) continue;
14960
15529
  types.set(member.key.name, reference);
@@ -14965,18 +15534,18 @@ var fileTypeIndex = (program) => {
14965
15534
  const objects = /* @__PURE__ */ new Map();
14966
15535
  const functionAliases = /* @__PURE__ */ new Set();
14967
15536
  for (const statement of program.body) {
14968
- const declaration = statement.type === AST_NODE_TYPES61.ExportNamedDeclaration ? statement.declaration : statement;
14969
- if (declaration?.type === AST_NODE_TYPES61.TSInterfaceDeclaration) {
15537
+ const declaration = statement.type === AST_NODE_TYPES67.ExportNamedDeclaration ? statement.declaration : statement;
15538
+ if (declaration?.type === AST_NODE_TYPES67.TSInterfaceDeclaration) {
14970
15539
  objects.set(declaration.id.name, propertySignatureTypes(declaration.body.body));
14971
15540
  continue;
14972
15541
  }
14973
- if (declaration?.type !== AST_NODE_TYPES61.TSTypeAliasDeclaration) continue;
15542
+ if (declaration?.type !== AST_NODE_TYPES67.TSTypeAliasDeclaration) continue;
14974
15543
  const aliased = declaration.typeAnnotation;
14975
- if (aliased.type === AST_NODE_TYPES61.TSFunctionType || aliased.type === AST_NODE_TYPES61.TSConstructorType) {
15544
+ if (aliased.type === AST_NODE_TYPES67.TSFunctionType || aliased.type === AST_NODE_TYPES67.TSConstructorType) {
14976
15545
  functionAliases.add(declaration.id.name);
14977
15546
  continue;
14978
15547
  }
14979
- const literals = aliased.type === AST_NODE_TYPES61.TSTypeLiteral ? [aliased] : aliased.type === AST_NODE_TYPES61.TSIntersectionType ? aliased.types.filter((part) => part.type === AST_NODE_TYPES61.TSTypeLiteral) : [];
15548
+ const literals = aliased.type === AST_NODE_TYPES67.TSTypeLiteral ? [aliased] : aliased.type === AST_NODE_TYPES67.TSIntersectionType ? aliased.types.filter((part) => part.type === AST_NODE_TYPES67.TSTypeLiteral) : [];
14980
15549
  if (literals.length === 0) continue;
14981
15550
  const merged = /* @__PURE__ */ new Map();
14982
15551
  for (const literal of literals) {
@@ -15005,10 +15574,10 @@ var readConstructor = (ctor, declared, typeParameters) => {
15005
15574
  while (pending.length > 0) {
15006
15575
  const current = pending.pop();
15007
15576
  if (current === void 0) break;
15008
- if (current.type === AST_NODE_TYPES61.ArrowFunctionExpression || current.type === AST_NODE_TYPES61.FunctionExpression || current.type === AST_NODE_TYPES61.FunctionDeclaration || current.type === AST_NODE_TYPES61.ClassExpression || current.type === AST_NODE_TYPES61.ClassDeclaration) continue;
15009
- const expression = current.type === AST_NODE_TYPES61.ExpressionStatement ? current.expression : null;
15010
- const storedField = expression?.type === AST_NODE_TYPES61.AssignmentExpression && expression.left.type === AST_NODE_TYPES61.MemberExpression && expression.left.object.type === AST_NODE_TYPES61.ThisExpression ? staticMemberName6(expression.left) : null;
15011
- if (expression?.type !== AST_NODE_TYPES61.AssignmentExpression || !STORAGE_ASSIGNMENT_OPERATORS.has(expression.operator) || expression.left.type !== AST_NODE_TYPES61.MemberExpression || expression.left.object.type !== AST_NODE_TYPES61.ThisExpression || storedField === null) {
15577
+ if (current.type === AST_NODE_TYPES67.ArrowFunctionExpression || current.type === AST_NODE_TYPES67.FunctionExpression || current.type === AST_NODE_TYPES67.FunctionDeclaration || current.type === AST_NODE_TYPES67.ClassExpression || current.type === AST_NODE_TYPES67.ClassDeclaration) continue;
15578
+ const expression = current.type === AST_NODE_TYPES67.ExpressionStatement ? current.expression : null;
15579
+ const storedField = expression?.type === AST_NODE_TYPES67.AssignmentExpression && expression.left.type === AST_NODE_TYPES67.MemberExpression && expression.left.object.type === AST_NODE_TYPES67.ThisExpression ? staticMemberName6(expression.left) : null;
15580
+ if (expression?.type !== AST_NODE_TYPES67.AssignmentExpression || !STORAGE_ASSIGNMENT_OPERATORS.has(expression.operator) || expression.left.type !== AST_NODE_TYPES67.MemberExpression || expression.left.object.type !== AST_NODE_TYPES67.ThisExpression || storedField === null) {
15012
15581
  for (const key of Object.keys(current)) {
15013
15582
  if (key === "parent") continue;
15014
15583
  const value = current[key];
@@ -15021,14 +15590,14 @@ var readConstructor = (ctor, declared, typeParameters) => {
15021
15590
  continue;
15022
15591
  }
15023
15592
  let source = expression.right;
15024
- while (source.type === AST_NODE_TYPES61.TSNonNullExpression || source.type === AST_NODE_TYPES61.TSAsExpression || source.type === AST_NODE_TYPES61.TSSatisfiesExpression || source.type === AST_NODE_TYPES61.TSTypeAssertion) source = source.expression;
15025
- if (source.type === AST_NODE_TYPES61.NewExpression) {
15593
+ while (source.type === AST_NODE_TYPES67.TSNonNullExpression || source.type === AST_NODE_TYPES67.TSAsExpression || source.type === AST_NODE_TYPES67.TSSatisfiesExpression || source.type === AST_NODE_TYPES67.TSTypeAssertion) source = source.expression;
15594
+ if (source.type === AST_NODE_TYPES67.NewExpression) {
15026
15595
  constructedFields += 1;
15027
- } else if (source.type === AST_NODE_TYPES61.Identifier) {
15596
+ } else if (source.type === AST_NODE_TYPES67.Identifier) {
15028
15597
  const fields = storedFieldsFrom.get(source.name) ?? /* @__PURE__ */ new Set();
15029
15598
  fields.add(storedField);
15030
15599
  storedFieldsFrom.set(source.name, fields);
15031
- } else if (source.type === AST_NODE_TYPES61.MemberExpression && source.object.type === AST_NODE_TYPES61.Identifier) {
15600
+ } else if (source.type === AST_NODE_TYPES67.MemberExpression && source.object.type === AST_NODE_TYPES67.Identifier) {
15032
15601
  const fields = storedFieldsFrom.get(source.object.name) ?? /* @__PURE__ */ new Set();
15033
15602
  fields.add(storedField);
15034
15603
  storedFieldsFrom.set(source.object.name, fields);
@@ -15046,7 +15615,7 @@ var readConstructor = (ctor, declared, typeParameters) => {
15046
15615
  const collaborators = [];
15047
15616
  for (const parameter of ctor.value.params) {
15048
15617
  for (const reference of parameterCollaborators(parameter, declared, storedMemberFieldsFrom)) {
15049
- const fields = parameter.type === AST_NODE_TYPES61.TSParameterProperty ? [reference.name] : reference.fields.length > 0 ? reference.fields : [...storedFieldsFrom.get(reference.name) ?? []];
15618
+ const fields = parameter.type === AST_NODE_TYPES67.TSParameterProperty ? [reference.name] : reference.fields.length > 0 ? reference.fields : [...storedFieldsFrom.get(reference.name) ?? []];
15050
15619
  if (fields.length === 0) continue;
15051
15620
  if (CONFIGISH_TYPE_RE.test(reference.typeName)) continue;
15052
15621
  if (CONFIGISH_NAME_RE.test(reference.name)) continue;
@@ -15061,8 +15630,8 @@ var readConstructor = (ctor, declared, typeParameters) => {
15061
15630
  };
15062
15631
  var parameterCollaborators = (parameter, declared, storedMemberFieldsFrom) => {
15063
15632
  let target = parameter;
15064
- if (target.type === AST_NODE_TYPES61.AssignmentPattern) target = target.left;
15065
- if (target.type === AST_NODE_TYPES61.ObjectPattern) {
15633
+ if (target.type === AST_NODE_TYPES67.AssignmentPattern) target = target.left;
15634
+ if (target.type === AST_NODE_TYPES67.ObjectPattern) {
15066
15635
  return objectPatternCollaborators(target, declared);
15067
15636
  }
15068
15637
  const named2 = namedParameterCollaborator(parameter);
@@ -15071,9 +15640,9 @@ var parameterCollaborators = (parameter, declared, storedMemberFieldsFrom) => {
15071
15640
  };
15072
15641
  var namedBagCollaborators = (annotated, declared, storedMemberFieldsFrom) => {
15073
15642
  let target = annotated;
15074
- if (target.type === AST_NODE_TYPES61.TSParameterProperty) target = target.parameter;
15075
- if (target.type === AST_NODE_TYPES61.AssignmentPattern) target = target.left;
15076
- if (target.type !== AST_NODE_TYPES61.Identifier) return [];
15643
+ if (target.type === AST_NODE_TYPES67.TSParameterProperty) target = target.parameter;
15644
+ if (target.type === AST_NODE_TYPES67.AssignmentPattern) target = target.left;
15645
+ if (target.type !== AST_NODE_TYPES67.Identifier) return [];
15077
15646
  const members = bagMemberTypes(target.typeAnnotation?.typeAnnotation, declared);
15078
15647
  if (members === null) return [];
15079
15648
  const storedMembers = storedMemberFieldsFrom.get(target.name);
@@ -15089,9 +15658,9 @@ var namedBagCollaborators = (annotated, declared, storedMemberFieldsFrom) => {
15089
15658
  };
15090
15659
  var namedParameterCollaborator = (annotated) => {
15091
15660
  let target = annotated;
15092
- if (target.type === AST_NODE_TYPES61.TSParameterProperty) target = target.parameter;
15093
- if (target.type === AST_NODE_TYPES61.AssignmentPattern) target = target.left;
15094
- if (target.type !== AST_NODE_TYPES61.Identifier) return null;
15661
+ if (target.type === AST_NODE_TYPES67.TSParameterProperty) target = target.parameter;
15662
+ if (target.type === AST_NODE_TYPES67.AssignmentPattern) target = target.left;
15663
+ if (target.type !== AST_NODE_TYPES67.Identifier) return null;
15095
15664
  const reference = readTypeReference(target.typeAnnotation?.typeAnnotation);
15096
15665
  if (reference === null) return null;
15097
15666
  return { name: target.name, ...reference, fields: [] };
@@ -15103,11 +15672,11 @@ var objectPatternCollaborators = (pattern, declared) => {
15103
15672
  if (members === null) return [];
15104
15673
  const collaborators = [];
15105
15674
  for (const property of pattern.properties) {
15106
- if (property.type !== AST_NODE_TYPES61.Property || property.computed) continue;
15107
- if (property.key.type !== AST_NODE_TYPES61.Identifier) continue;
15675
+ if (property.type !== AST_NODE_TYPES67.Property || property.computed) continue;
15676
+ if (property.key.type !== AST_NODE_TYPES67.Identifier) continue;
15108
15677
  const key = property.key.name;
15109
- const bound = property.value.type === AST_NODE_TYPES61.AssignmentPattern ? property.value.left : property.value;
15110
- if (bound.type !== AST_NODE_TYPES61.Identifier) continue;
15678
+ const bound = property.value.type === AST_NODE_TYPES67.AssignmentPattern ? property.value.left : property.value;
15679
+ if (bound.type !== AST_NODE_TYPES67.Identifier) continue;
15111
15680
  if (CONFIGISH_NAME_RE.test(key)) continue;
15112
15681
  const reference = members.get(key);
15113
15682
  if (reference === void 0) continue;
@@ -15117,21 +15686,21 @@ var objectPatternCollaborators = (pattern, declared) => {
15117
15686
  };
15118
15687
  var bagMemberTypes = (annotation, declared) => {
15119
15688
  if (annotation === void 0) return null;
15120
- if (annotation.type === AST_NODE_TYPES61.TSTypeLiteral) {
15689
+ if (annotation.type === AST_NODE_TYPES67.TSTypeLiteral) {
15121
15690
  return propertySignatureTypes(annotation.members);
15122
15691
  }
15123
- if (annotation.type !== AST_NODE_TYPES61.TSTypeReference || annotation.typeName.type !== AST_NODE_TYPES61.Identifier) {
15692
+ if (annotation.type !== AST_NODE_TYPES67.TSTypeReference || annotation.typeName.type !== AST_NODE_TYPES67.Identifier) {
15124
15693
  return null;
15125
15694
  }
15126
15695
  return declared().objects.get(annotation.typeName.name) ?? null;
15127
15696
  };
15128
15697
  var isFrameworkWiring = (body2) => subtreeHas(body2, (node) => {
15129
- if (node.type === AST_NODE_TYPES61.CallExpression) {
15698
+ if (node.type === AST_NODE_TYPES67.CallExpression) {
15130
15699
  const { callee } = node;
15131
- if (callee.type === AST_NODE_TYPES61.Identifier) return callee.name === ROUTER_FACTORY_NAME;
15132
- return callee.type === AST_NODE_TYPES61.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES61.Identifier && callee.property.name === ROUTER_FACTORY_NAME;
15700
+ if (callee.type === AST_NODE_TYPES67.Identifier) return callee.name === ROUTER_FACTORY_NAME;
15701
+ return callee.type === AST_NODE_TYPES67.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES67.Identifier && callee.property.name === ROUTER_FACTORY_NAME;
15133
15702
  }
15134
- return node.type === AST_NODE_TYPES61.TSTypeReference && node.typeName.type === AST_NODE_TYPES61.TSQualifiedName && FRAMEWORK_HTTP_TYPES.has(node.typeName.right.name);
15703
+ return node.type === AST_NODE_TYPES67.TSTypeReference && node.typeName.type === AST_NODE_TYPES67.TSQualifiedName && FRAMEWORK_HTTP_TYPES.has(node.typeName.right.name);
15135
15704
  });
15136
15705
  var subtreeHas = (root, found) => {
15137
15706
  let hit = false;
@@ -15158,19 +15727,19 @@ var invokedInstanceField = (call) => {
15158
15727
  const direct = instanceField(call.callee);
15159
15728
  if (direct !== null) return direct;
15160
15729
  let callee = call.callee;
15161
- while (callee.type === AST_NODE_TYPES61.ChainExpression || callee.type === AST_NODE_TYPES61.TSAsExpression || callee.type === AST_NODE_TYPES61.TSNonNullExpression || callee.type === AST_NODE_TYPES61.TSSatisfiesExpression || callee.type === AST_NODE_TYPES61.TSTypeAssertion) callee = callee.expression;
15162
- return callee.type === AST_NODE_TYPES61.MemberExpression ? instanceField(callee.object) : null;
15730
+ while (callee.type === AST_NODE_TYPES67.ChainExpression || callee.type === AST_NODE_TYPES67.TSAsExpression || callee.type === AST_NODE_TYPES67.TSNonNullExpression || callee.type === AST_NODE_TYPES67.TSSatisfiesExpression || callee.type === AST_NODE_TYPES67.TSTypeAssertion) callee = callee.expression;
15731
+ return callee.type === AST_NODE_TYPES67.MemberExpression ? instanceField(callee.object) : null;
15163
15732
  };
15164
15733
  var instanceField = (candidate2) => {
15165
15734
  let node = candidate2;
15166
- while (node.type === AST_NODE_TYPES61.ChainExpression || node.type === AST_NODE_TYPES61.TSAsExpression || node.type === AST_NODE_TYPES61.TSNonNullExpression || node.type === AST_NODE_TYPES61.TSSatisfiesExpression || node.type === AST_NODE_TYPES61.TSTypeAssertion) node = node.expression;
15167
- return node.type === AST_NODE_TYPES61.MemberExpression && node.object.type === AST_NODE_TYPES61.ThisExpression ? staticMemberName6(node) : null;
15735
+ while (node.type === AST_NODE_TYPES67.ChainExpression || node.type === AST_NODE_TYPES67.TSAsExpression || node.type === AST_NODE_TYPES67.TSNonNullExpression || node.type === AST_NODE_TYPES67.TSSatisfiesExpression || node.type === AST_NODE_TYPES67.TSTypeAssertion) node = node.expression;
15736
+ return node.type === AST_NODE_TYPES67.MemberExpression && node.object.type === AST_NODE_TYPES67.ThisExpression ? staticMemberName6(node) : null;
15168
15737
  };
15169
15738
  var behaviorallyInvokedFields = (body2) => {
15170
15739
  const invoked = /* @__PURE__ */ new Set();
15171
15740
  const visit = (current) => {
15172
- if (current.type === AST_NODE_TYPES61.ClassDeclaration || current.type === AST_NODE_TYPES61.ClassExpression || current.type === AST_NODE_TYPES61.FunctionDeclaration || current.type === AST_NODE_TYPES61.FunctionExpression) return;
15173
- if (current.type === AST_NODE_TYPES61.CallExpression) {
15741
+ if (current.type === AST_NODE_TYPES67.ClassDeclaration || current.type === AST_NODE_TYPES67.ClassExpression || current.type === AST_NODE_TYPES67.FunctionDeclaration || current.type === AST_NODE_TYPES67.FunctionExpression) return;
15742
+ if (current.type === AST_NODE_TYPES67.CallExpression) {
15174
15743
  const field = invokedInstanceField(current);
15175
15744
  if (field !== null) invoked.add(field);
15176
15745
  }
@@ -15183,14 +15752,14 @@ var behaviorallyInvokedFields = (body2) => {
15183
15752
  }
15184
15753
  };
15185
15754
  for (const member of body2.body) {
15186
- if (member.type === AST_NODE_TYPES61.StaticBlock || member.static) continue;
15187
- if (member.type === AST_NODE_TYPES61.MethodDefinition) {
15755
+ if (member.type === AST_NODE_TYPES67.StaticBlock || member.static) continue;
15756
+ if (member.type === AST_NODE_TYPES67.MethodDefinition) {
15188
15757
  if (member.value.body !== null && member.value.body !== void 0) visit(member.value.body);
15189
15758
  continue;
15190
15759
  }
15191
- if (member.type !== AST_NODE_TYPES61.PropertyDefinition || member.value === null) continue;
15760
+ if (member.type !== AST_NODE_TYPES67.PropertyDefinition || member.value === null) continue;
15192
15761
  visit(
15193
- member.value.type === AST_NODE_TYPES61.ArrowFunctionExpression ? member.value.body : member.value
15762
+ member.value.type === AST_NODE_TYPES67.ArrowFunctionExpression ? member.value.body : member.value
15194
15763
  );
15195
15764
  }
15196
15765
  return invoked;
@@ -15210,25 +15779,26 @@ var isTransportWrapper = (className, collaborators, program) => {
15210
15779
  var fileInterfaceNames = (program) => {
15211
15780
  const names = [];
15212
15781
  for (const statement of program.body) {
15213
- const declaration = statement.type === AST_NODE_TYPES61.ExportNamedDeclaration ? statement.declaration : statement;
15214
- if (declaration?.type === AST_NODE_TYPES61.TSInterfaceDeclaration) names.push(declaration.id.name);
15782
+ const declaration = statement.type === AST_NODE_TYPES67.ExportNamedDeclaration ? statement.declaration : statement;
15783
+ if (declaration?.type === AST_NODE_TYPES67.TSInterfaceDeclaration) names.push(declaration.id.name);
15215
15784
  }
15216
15785
  return names;
15217
15786
  };
15218
15787
  var publicMethodNames = (body2, functionAliases) => {
15219
15788
  const names = [];
15220
15789
  for (const member of body2.body) {
15221
- if (member.type === AST_NODE_TYPES61.PropertyDefinition) {
15790
+ if (member.type === AST_NODE_TYPES67.PropertyDefinition) {
15222
15791
  if (member.static || member.accessibility === "private" || member.accessibility === "protected") continue;
15223
- if (member.value?.type !== AST_NODE_TYPES61.ArrowFunctionExpression && member.value?.type !== AST_NODE_TYPES61.FunctionExpression && member.typeAnnotation?.typeAnnotation.type !== AST_NODE_TYPES61.TSFunctionType && !(member.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES61.TSTypeReference && member.typeAnnotation.typeAnnotation.typeName.type === AST_NODE_TYPES61.Identifier && functionAliases.has(member.typeAnnotation.typeAnnotation.typeName.name))) continue;
15224
- names.push(member.key.type === AST_NODE_TYPES61.Identifier ? member.key.name : "\u2026");
15792
+ if (member.key.type === AST_NODE_TYPES67.PrivateIdentifier) continue;
15793
+ if (member.value?.type !== AST_NODE_TYPES67.ArrowFunctionExpression && member.value?.type !== AST_NODE_TYPES67.FunctionExpression && member.typeAnnotation?.typeAnnotation.type !== AST_NODE_TYPES67.TSFunctionType && !(member.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES67.TSTypeReference && member.typeAnnotation.typeAnnotation.typeName.type === AST_NODE_TYPES67.Identifier && functionAliases.has(member.typeAnnotation.typeAnnotation.typeName.name))) continue;
15794
+ names.push(member.key.type === AST_NODE_TYPES67.Identifier ? member.key.name : "\u2026");
15225
15795
  continue;
15226
15796
  }
15227
- if (member.type !== AST_NODE_TYPES61.MethodDefinition) continue;
15797
+ if (member.type !== AST_NODE_TYPES67.MethodDefinition) continue;
15228
15798
  if (member.kind !== "method" || member.static) continue;
15229
15799
  if (member.accessibility === "private" || member.accessibility === "protected") continue;
15230
- if (member.key.type === AST_NODE_TYPES61.PrivateIdentifier) continue;
15231
- if (member.key.type === AST_NODE_TYPES61.Identifier) names.push(member.key.name);
15800
+ if (member.key.type === AST_NODE_TYPES67.PrivateIdentifier) continue;
15801
+ if (member.key.type === AST_NODE_TYPES67.Identifier) names.push(member.key.name);
15232
15802
  else names.push("\u2026");
15233
15803
  }
15234
15804
  return names;
@@ -15236,13 +15806,13 @@ var publicMethodNames = (body2, functionAliases) => {
15236
15806
  var isFluentConstructionObject = (node, getText) => {
15237
15807
  if (node.id === null) return false;
15238
15808
  const methods = node.body.body.filter(
15239
- (member) => member.type === AST_NODE_TYPES61.MethodDefinition && member.kind === "method" && !member.static && member.accessibility !== "private" && member.accessibility !== "protected" && member.value.body !== null
15809
+ (member) => member.type === AST_NODE_TYPES67.MethodDefinition && member.kind === "method" && !member.static && member.accessibility !== "private" && member.accessibility !== "protected" && member.value.body !== null
15240
15810
  );
15241
15811
  if (methods.length === 0) return false;
15242
15812
  return methods.every((member) => {
15243
15813
  const result = member.value.returnType?.typeAnnotation;
15244
15814
  if (result === void 0) return false;
15245
- const returnsOwnType = result.type === AST_NODE_TYPES61.TSTypeReference && result.typeName.type === AST_NODE_TYPES61.Identifier && result.typeName.name === node.id?.name;
15815
+ const returnsOwnType = result.type === AST_NODE_TYPES67.TSTypeReference && result.typeName.type === AST_NODE_TYPES67.Identifier && result.typeName.name === node.id?.name;
15246
15816
  return returnsOwnType || FLUENT_BUILDER_NAME_RE.test(node.id?.name ?? "") && FLUENT_RESULT_TYPE_RE.test(getText(result));
15247
15817
  });
15248
15818
  };
@@ -15250,10 +15820,10 @@ function localClassAbstractness(program) {
15250
15820
  const classes = /* @__PURE__ */ new Map();
15251
15821
  const parents = /* @__PURE__ */ new Map();
15252
15822
  for (const statement of program.body) {
15253
- const declaration = statement.type === AST_NODE_TYPES61.ExportNamedDeclaration || statement.type === AST_NODE_TYPES61.ExportDefaultDeclaration ? statement.declaration : statement;
15254
- if (declaration?.type === AST_NODE_TYPES61.ClassDeclaration && declaration.id !== null) {
15823
+ const declaration = statement.type === AST_NODE_TYPES67.ExportNamedDeclaration || statement.type === AST_NODE_TYPES67.ExportDefaultDeclaration ? statement.declaration : statement;
15824
+ if (declaration?.type === AST_NODE_TYPES67.ClassDeclaration && declaration.id !== null) {
15255
15825
  classes.set(declaration.id.name, declaration.abstract === true);
15256
- if (declaration.superClass?.type === AST_NODE_TYPES61.Identifier) {
15826
+ if (declaration.superClass?.type === AST_NODE_TYPES67.Identifier) {
15257
15827
  parents.set(declaration.id.name, declaration.superClass.name);
15258
15828
  }
15259
15829
  }
@@ -15275,43 +15845,43 @@ function localInterfaceSurfaces(program) {
15275
15845
  const parents = /* @__PURE__ */ new Map();
15276
15846
  const functionAliases = /* @__PURE__ */ new Set();
15277
15847
  for (const statement of program.body) {
15278
- const declaration = statement.type === AST_NODE_TYPES61.ExportNamedDeclaration ? statement.declaration : statement;
15279
- if (declaration?.type === AST_NODE_TYPES61.TSTypeAliasDeclaration && (declaration.typeAnnotation.type === AST_NODE_TYPES61.TSFunctionType || declaration.typeAnnotation.type === AST_NODE_TYPES61.TSConstructorType)) functionAliases.add(declaration.id.name);
15848
+ const declaration = statement.type === AST_NODE_TYPES67.ExportNamedDeclaration ? statement.declaration : statement;
15849
+ if (declaration?.type === AST_NODE_TYPES67.TSTypeAliasDeclaration && (declaration.typeAnnotation.type === AST_NODE_TYPES67.TSFunctionType || declaration.typeAnnotation.type === AST_NODE_TYPES67.TSConstructorType)) functionAliases.add(declaration.id.name);
15280
15850
  }
15281
15851
  for (const statement of program.body) {
15282
- const declaration = statement.type === AST_NODE_TYPES61.ExportNamedDeclaration ? statement.declaration : statement;
15283
- if (declaration?.type === AST_NODE_TYPES61.TSTypeAliasDeclaration) {
15852
+ const declaration = statement.type === AST_NODE_TYPES67.ExportNamedDeclaration ? statement.declaration : statement;
15853
+ if (declaration?.type === AST_NODE_TYPES67.TSTypeAliasDeclaration) {
15284
15854
  const callables2 = interfaces.get(declaration.id.name) ?? /* @__PURE__ */ new Set();
15285
- const parts = declaration.typeAnnotation.type === AST_NODE_TYPES61.TSIntersectionType ? declaration.typeAnnotation.types : [declaration.typeAnnotation];
15855
+ const parts = declaration.typeAnnotation.type === AST_NODE_TYPES67.TSIntersectionType ? declaration.typeAnnotation.types : [declaration.typeAnnotation];
15286
15856
  const inherited = parents.get(declaration.id.name) ?? [];
15287
15857
  for (const part of parts) {
15288
- if (part.type === AST_NODE_TYPES61.TSTypeReference && part.typeName.type === AST_NODE_TYPES61.Identifier) {
15858
+ if (part.type === AST_NODE_TYPES67.TSTypeReference && part.typeName.type === AST_NODE_TYPES67.Identifier) {
15289
15859
  inherited.push(part.typeName.name);
15290
15860
  continue;
15291
15861
  }
15292
- if (part.type !== AST_NODE_TYPES61.TSTypeLiteral) continue;
15862
+ if (part.type !== AST_NODE_TYPES67.TSTypeLiteral) continue;
15293
15863
  for (const member of part.members) {
15294
- if (member.type !== AST_NODE_TYPES61.TSMethodSignature && member.type !== AST_NODE_TYPES61.TSPropertySignature) continue;
15295
- if (member.computed || member.key.type !== AST_NODE_TYPES61.Identifier) continue;
15296
- if (member.type === AST_NODE_TYPES61.TSMethodSignature) {
15864
+ if (member.type !== AST_NODE_TYPES67.TSMethodSignature && member.type !== AST_NODE_TYPES67.TSPropertySignature) continue;
15865
+ if (member.computed || member.key.type !== AST_NODE_TYPES67.Identifier) continue;
15866
+ if (member.type === AST_NODE_TYPES67.TSMethodSignature) {
15297
15867
  callables2.add(member.key.name);
15298
15868
  continue;
15299
15869
  }
15300
- if (member.type !== AST_NODE_TYPES61.TSPropertySignature) continue;
15870
+ if (member.type !== AST_NODE_TYPES67.TSPropertySignature) continue;
15301
15871
  const annotation = member.typeAnnotation?.typeAnnotation;
15302
- if (annotation?.type === AST_NODE_TYPES61.TSFunctionType || annotation?.type === AST_NODE_TYPES61.TSTypeReference && annotation.typeName.type === AST_NODE_TYPES61.Identifier && functionAliases.has(annotation.typeName.name)) callables2.add(member.key.name);
15872
+ if (annotation?.type === AST_NODE_TYPES67.TSFunctionType || annotation?.type === AST_NODE_TYPES67.TSTypeReference && annotation.typeName.type === AST_NODE_TYPES67.Identifier && functionAliases.has(annotation.typeName.name)) callables2.add(member.key.name);
15303
15873
  }
15304
15874
  }
15305
15875
  interfaces.set(declaration.id.name, callables2);
15306
15876
  parents.set(declaration.id.name, inherited);
15307
15877
  continue;
15308
15878
  }
15309
- if (declaration?.type !== AST_NODE_TYPES61.TSInterfaceDeclaration) continue;
15879
+ if (declaration?.type !== AST_NODE_TYPES67.TSInterfaceDeclaration) continue;
15310
15880
  const callables = interfaces.get(declaration.id.name) ?? /* @__PURE__ */ new Set();
15311
15881
  for (const member of declaration.body.body) {
15312
- if (member.type !== AST_NODE_TYPES61.TSMethodSignature && member.type !== AST_NODE_TYPES61.TSPropertySignature) continue;
15313
- if (member.computed || member.key.type !== AST_NODE_TYPES61.Identifier) continue;
15314
- if (member.type === AST_NODE_TYPES61.TSMethodSignature || member.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES61.TSFunctionType || member.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES61.TSTypeReference && member.typeAnnotation.typeAnnotation.typeName.type === AST_NODE_TYPES61.Identifier && functionAliases.has(member.typeAnnotation.typeAnnotation.typeName.name)) callables.add(member.key.name);
15882
+ if (member.type !== AST_NODE_TYPES67.TSMethodSignature && member.type !== AST_NODE_TYPES67.TSPropertySignature) continue;
15883
+ if (member.computed || member.key.type !== AST_NODE_TYPES67.Identifier) continue;
15884
+ if (member.type === AST_NODE_TYPES67.TSMethodSignature || member.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES67.TSFunctionType || member.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES67.TSTypeReference && member.typeAnnotation.typeAnnotation.typeName.type === AST_NODE_TYPES67.Identifier && functionAliases.has(member.typeAnnotation.typeAnnotation.typeName.name)) callables.add(member.key.name);
15315
15885
  }
15316
15886
  interfaces.set(declaration.id.name, callables);
15317
15887
  parents.set(
@@ -15319,7 +15889,7 @@ function localInterfaceSurfaces(program) {
15319
15889
  [
15320
15890
  ...parents.get(declaration.id.name) ?? [],
15321
15891
  ...declaration.extends.flatMap(
15322
- (heritage) => heritage.expression.type === AST_NODE_TYPES61.Identifier ? [heritage.expression.name] : ["*"]
15892
+ (heritage) => heritage.expression.type === AST_NODE_TYPES67.Identifier ? [heritage.expression.name] : ["*"]
15323
15893
  )
15324
15894
  ]
15325
15895
  );
@@ -15346,7 +15916,7 @@ function localInterfaceSurfaces(program) {
15346
15916
  }
15347
15917
  function hasServicePort(node, methods, classes, interfaces) {
15348
15918
  if (node.superClass !== null) {
15349
- if (node.superClass.type !== AST_NODE_TYPES61.Identifier) return true;
15919
+ if (node.superClass.type !== AST_NODE_TYPES67.Identifier) return true;
15350
15920
  const localAbstract = classes.get(node.superClass.name);
15351
15921
  if (localAbstract === void 0 || localAbstract) return true;
15352
15922
  }
@@ -15358,7 +15928,7 @@ function hasServicePort(node, methods, classes, interfaces) {
15358
15928
  if (node.implements.length === 0) return false;
15359
15929
  const combined = /* @__PURE__ */ new Set();
15360
15930
  for (const implementation of node.implements) {
15361
- if (implementation.expression.type !== AST_NODE_TYPES61.Identifier) return true;
15931
+ if (implementation.expression.type !== AST_NODE_TYPES67.Identifier) return true;
15362
15932
  const name = implementation.expression.name;
15363
15933
  const localAbstract = classes.get(name);
15364
15934
  if (localAbstract === true) return true;
@@ -15401,7 +15971,7 @@ var require_port_for_service_default = createRule({
15401
15971
  if (node.abstract === true) return;
15402
15972
  if (node.decorators.length > 0) return;
15403
15973
  const ctor = node.body.body.find(
15404
- (member) => member.type === AST_NODE_TYPES61.MethodDefinition && member.kind === "constructor" && member.value.body !== null && member.value.body !== void 0
15974
+ (member) => member.type === AST_NODE_TYPES67.MethodDefinition && member.kind === "constructor" && member.value.body !== null && member.value.body !== void 0
15405
15975
  );
15406
15976
  if (ctor === void 0) return;
15407
15977
  const constructorFacts = readConstructor(
@@ -15435,8 +16005,292 @@ var require_port_for_service_default = createRule({
15435
16005
  }
15436
16006
  });
15437
16007
 
16008
+ // src/rules/require-sql-access-class.ts
16009
+ import { AST_NODE_TYPES as AST_NODE_TYPES68 } from "@typescript-eslint/utils";
16010
+ var DIRECT_EXECUTION_METHODS = /* @__PURE__ */ new Set([
16011
+ "all",
16012
+ "batch",
16013
+ "dump",
16014
+ "exec",
16015
+ "execute",
16016
+ "get",
16017
+ "pragma",
16018
+ "prepare",
16019
+ "query",
16020
+ "run",
16021
+ "transaction"
16022
+ ]);
16023
+ var BUILDER_TERMINAL_METHODS = /* @__PURE__ */ new Set([
16024
+ "execute",
16025
+ "executeQuery",
16026
+ "executeTakeFirst",
16027
+ "executeTakeFirstOrThrow",
16028
+ "stream"
16029
+ ]);
16030
+ var BUILDER_METHODS = /* @__PURE__ */ new Set([
16031
+ "delete",
16032
+ "insert",
16033
+ "select",
16034
+ "update"
16035
+ ]);
16036
+ var BUILDER_SHORT_TERMINALS = /* @__PURE__ */ new Set([
16037
+ "all",
16038
+ "get",
16039
+ "run"
16040
+ ]);
16041
+ var MODEL_EXECUTION_METHODS = /* @__PURE__ */ new Set([
16042
+ "aggregate",
16043
+ "count",
16044
+ "create",
16045
+ "createMany",
16046
+ "createManyAndReturn",
16047
+ "delete",
16048
+ "deleteMany",
16049
+ "findFirst",
16050
+ "findFirstOrThrow",
16051
+ "findMany",
16052
+ "findUnique",
16053
+ "findUniqueOrThrow",
16054
+ "groupBy",
16055
+ "update",
16056
+ "updateMany",
16057
+ "updateManyAndReturn",
16058
+ "upsert"
16059
+ ]);
16060
+ var DATABASE_NAMES = /^(?:db|database|connection|pool|prisma|query|transaction|tx)$/iu;
16061
+ var REQUIRE_SQL_ACCESS_CLASS_DOCUMENTATION = {
16062
+ summary: "Keep SQL reads and writes inside a class that receives its database dependency.",
16063
+ rationale: "Free-function database access hides connection ownership and makes transaction, retry, observability, and test boundaries inconsistent.",
16064
+ remediation: "Move the query into a repository or store class and inject the pool, connection, transaction, or typed database binding through its constructor.",
16065
+ category: "architecture",
16066
+ limitations: [
16067
+ "The rule recognizes conventional database receiver names, Cloudflare DB bindings, direct pool.query calls, explicit query-builder terminals, and Prisma-style model delegates; unusually named or heavily aliased clients require architectural review.",
16068
+ "Query construction without a recognized execution terminal is intentionally not reported.",
16069
+ "Constructor injection inherited from a base class or transformed through a wrapper is not inferred by this syntax-only rule."
16070
+ ],
16071
+ examples: [
16072
+ {
16073
+ id: "injected-repository",
16074
+ title: "Own queries in an injected repository",
16075
+ outcome: "no-match",
16076
+ files: [
16077
+ {
16078
+ path: "src/user-repository.ts",
16079
+ source: "export class UserRepository { constructor(private readonly db: Database.Database) {} find(id: string) { return this.db.prepare('SELECT id FROM user WHERE id = ?').get(id); } }"
16080
+ }
16081
+ ],
16082
+ focusPath: "src/user-repository.ts",
16083
+ expectedCount: 0,
16084
+ public: true
16085
+ },
16086
+ {
16087
+ id: "free-query",
16088
+ title: "Do not execute SQL in a free function",
16089
+ outcome: "match",
16090
+ files: [
16091
+ {
16092
+ path: "src/users.ts",
16093
+ source: "export function find(database: Database.Database, id: string) { return database.prepare('SELECT id FROM user WHERE id = ?').get(id); }"
16094
+ }
16095
+ ],
16096
+ focusPath: "src/users.ts",
16097
+ expectedCount: 1,
16098
+ public: true
16099
+ }
16100
+ ]
16101
+ };
16102
+ function memberName5(node) {
16103
+ if (!node.computed && node.property.type === AST_NODE_TYPES68.Identifier)
16104
+ return node.property.name;
16105
+ if (node.computed && node.property.type === AST_NODE_TYPES68.Literal && typeof node.property.value === "string")
16106
+ return node.property.value;
16107
+ return null;
16108
+ }
16109
+ function isDatabaseOperation(method, receiver) {
16110
+ if (DIRECT_EXECUTION_METHODS.has(method) && databaseReceiver(receiver))
16111
+ return true;
16112
+ if (!expressionHasDatabaseMarker(receiver)) return false;
16113
+ if (BUILDER_TERMINAL_METHODS.has(method) || MODEL_EXECUTION_METHODS.has(method)) return true;
16114
+ return BUILDER_SHORT_TERMINALS.has(method) && expressionCallsBuilder(receiver);
16115
+ }
16116
+ function databaseReceiver(node) {
16117
+ if (node.type === AST_NODE_TYPES68.Identifier)
16118
+ return DATABASE_NAMES.test(node.name);
16119
+ if (node.type !== AST_NODE_TYPES68.MemberExpression) return false;
16120
+ const name = memberName5(node);
16121
+ return name === "DB" || name !== null && DATABASE_NAMES.test(name);
16122
+ }
16123
+ function databaseRootMember(node) {
16124
+ let current = node;
16125
+ for (; ; ) {
16126
+ if (current.type === AST_NODE_TYPES68.ChainExpression) {
16127
+ current = current.expression;
16128
+ continue;
16129
+ }
16130
+ if (current.type === AST_NODE_TYPES68.TSAsExpression || current.type === AST_NODE_TYPES68.TSNonNullExpression || current.type === AST_NODE_TYPES68.TSTypeAssertion) {
16131
+ current = current.expression;
16132
+ continue;
16133
+ }
16134
+ if (current.type === AST_NODE_TYPES68.CallExpression) {
16135
+ if (current.callee.type !== AST_NODE_TYPES68.MemberExpression) return null;
16136
+ current = current.callee.object;
16137
+ continue;
16138
+ }
16139
+ if (current.type === AST_NODE_TYPES68.MemberExpression) {
16140
+ if (current.object.type === AST_NODE_TYPES68.ThisExpression)
16141
+ return memberName5(current);
16142
+ current = current.object;
16143
+ continue;
16144
+ }
16145
+ return current.type === AST_NODE_TYPES68.Identifier ? current.name : null;
16146
+ }
16147
+ }
16148
+ function expressionHasDatabaseMarker(node) {
16149
+ let current = node;
16150
+ for (; ; ) {
16151
+ if (current.type === AST_NODE_TYPES68.ChainExpression) {
16152
+ current = current.expression;
16153
+ continue;
16154
+ }
16155
+ if (current.type === AST_NODE_TYPES68.TSAsExpression || current.type === AST_NODE_TYPES68.TSNonNullExpression || current.type === AST_NODE_TYPES68.TSTypeAssertion) {
16156
+ current = current.expression;
16157
+ continue;
16158
+ }
16159
+ if (current.type === AST_NODE_TYPES68.CallExpression) {
16160
+ if (current.callee.type !== AST_NODE_TYPES68.MemberExpression) return false;
16161
+ current = current.callee.object;
16162
+ continue;
16163
+ }
16164
+ if (current.type === AST_NODE_TYPES68.MemberExpression) {
16165
+ const name = memberName5(current);
16166
+ if (name === "DB" || name !== null && DATABASE_NAMES.test(name))
16167
+ return true;
16168
+ current = current.object;
16169
+ continue;
16170
+ }
16171
+ return current.type === AST_NODE_TYPES68.Identifier && DATABASE_NAMES.test(current.name);
16172
+ }
16173
+ }
16174
+ function expressionCallsBuilder(node) {
16175
+ let current = node;
16176
+ for (; ; ) {
16177
+ if (current.type === AST_NODE_TYPES68.ChainExpression) {
16178
+ current = current.expression;
16179
+ continue;
16180
+ }
16181
+ if (current.type === AST_NODE_TYPES68.TSAsExpression || current.type === AST_NODE_TYPES68.TSNonNullExpression || current.type === AST_NODE_TYPES68.TSTypeAssertion) {
16182
+ current = current.expression;
16183
+ continue;
16184
+ }
16185
+ if (current.type === AST_NODE_TYPES68.CallExpression) {
16186
+ if (current.callee.type !== AST_NODE_TYPES68.MemberExpression) return false;
16187
+ const name = memberName5(current.callee);
16188
+ if (name !== null && BUILDER_METHODS.has(name)) return true;
16189
+ current = current.callee.object;
16190
+ continue;
16191
+ }
16192
+ if (current.type !== AST_NODE_TYPES68.MemberExpression) return false;
16193
+ current = current.object;
16194
+ }
16195
+ }
16196
+ function owningClass2(node) {
16197
+ let current = node.parent;
16198
+ while (current != null) {
16199
+ if (current.type === AST_NODE_TYPES68.ClassDeclaration || current.type === AST_NODE_TYPES68.ClassExpression)
16200
+ return current;
16201
+ current = current.parent;
16202
+ }
16203
+ return null;
16204
+ }
16205
+ function injectedMembers(owner) {
16206
+ const injected = /* @__PURE__ */ new Set();
16207
+ const constructor = owner.body.body.find(
16208
+ (member) => member.type === AST_NODE_TYPES68.MethodDefinition && member.kind === "constructor"
16209
+ );
16210
+ if (constructor === void 0) return injected;
16211
+ const parameters = /* @__PURE__ */ new Set();
16212
+ for (const parameter of constructor.value.params) {
16213
+ for (const name of parameterNames(parameter)) parameters.add(name);
16214
+ if (parameter.type !== AST_NODE_TYPES68.TSParameterProperty) continue;
16215
+ const value = parameter.parameter.type === AST_NODE_TYPES68.AssignmentPattern ? parameter.parameter.left : parameter.parameter;
16216
+ if (value.type === AST_NODE_TYPES68.Identifier) injected.add(value.name);
16217
+ }
16218
+ const body2 = constructor.value.body;
16219
+ if (body2 === null) return injected;
16220
+ for (const statement of body2.body) {
16221
+ if (statement.type !== AST_NODE_TYPES68.ExpressionStatement || statement.expression.type !== AST_NODE_TYPES68.AssignmentExpression || statement.expression.operator !== "=") continue;
16222
+ const { left, right } = statement.expression;
16223
+ if (left.type !== AST_NODE_TYPES68.MemberExpression) continue;
16224
+ const target = thisRootMember(left);
16225
+ if (target === null) continue;
16226
+ const source = right.type === AST_NODE_TYPES68.Identifier ? right.name : right.type === AST_NODE_TYPES68.MemberExpression && right.object.type === AST_NODE_TYPES68.Identifier ? right.object.name : null;
16227
+ if (source !== null && parameters.has(source)) injected.add(target);
16228
+ }
16229
+ return injected;
16230
+ }
16231
+ function thisRootMember(node) {
16232
+ let current = node;
16233
+ let root = null;
16234
+ while (current.type === AST_NODE_TYPES68.MemberExpression) {
16235
+ const name = memberName5(current);
16236
+ if (name === null) return null;
16237
+ root = name;
16238
+ current = current.object;
16239
+ }
16240
+ return current.type === AST_NODE_TYPES68.ThisExpression ? root : null;
16241
+ }
16242
+ function parameterNames(parameter) {
16243
+ let value = parameter;
16244
+ if (value.type === AST_NODE_TYPES68.TSParameterProperty) value = value.parameter;
16245
+ if (value.type === AST_NODE_TYPES68.AssignmentPattern) value = value.left;
16246
+ if (value.type === AST_NODE_TYPES68.Identifier) return /* @__PURE__ */ new Set([value.name]);
16247
+ if (value.type !== AST_NODE_TYPES68.ObjectPattern) return /* @__PURE__ */ new Set();
16248
+ return new Set(
16249
+ value.properties.flatMap((property) => {
16250
+ if (property.type === AST_NODE_TYPES68.RestElement)
16251
+ return property.argument.type === AST_NODE_TYPES68.Identifier ? [property.argument.name] : [];
16252
+ const target = property.value.type === AST_NODE_TYPES68.AssignmentPattern ? property.value.left : property.value;
16253
+ return target.type === AST_NODE_TYPES68.Identifier ? [target.name] : [];
16254
+ })
16255
+ );
16256
+ }
16257
+ var require_sql_access_class_default = createRule({
16258
+ name: "require-sql-access-class",
16259
+ documentation: REQUIRE_SQL_ACCESS_CLASS_DOCUMENTATION,
16260
+ meta: {
16261
+ type: "suggestion",
16262
+ docs: {
16263
+ description: "Keep SQL reads and writes inside a class that receives its database dependency."
16264
+ },
16265
+ schema: [],
16266
+ messages: {
16267
+ moveSqlIntoClass: "Move this database operation into a repository or store class with an injected connection or pool."
16268
+ }
16269
+ },
16270
+ defaultOptions: [],
16271
+ create(context) {
16272
+ if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text))
16273
+ return {};
16274
+ return {
16275
+ CallExpression(node) {
16276
+ if (node.callee.type !== AST_NODE_TYPES68.MemberExpression)
16277
+ return;
16278
+ const method = memberName5(node.callee);
16279
+ if (method === null || !isDatabaseOperation(method, node.callee.object))
16280
+ return;
16281
+ const owner = owningClass2(node);
16282
+ if (owner !== null) {
16283
+ const root = databaseRootMember(node.callee.object);
16284
+ if (root !== null && injectedMembers(owner).has(root)) return;
16285
+ }
16286
+ context.report({ node, messageId: "moveSqlIntoClass" });
16287
+ }
16288
+ };
16289
+ }
16290
+ });
16291
+
15438
16292
  // src/rules/require-static-next-matcher.ts
15439
- import { AST_NODE_TYPES as AST_NODE_TYPES62 } from "@typescript-eslint/utils";
16293
+ import { AST_NODE_TYPES as AST_NODE_TYPES69 } from "@typescript-eslint/utils";
15440
16294
  var REQUIRE_STATIC_NEXT_MATCHER_DOCUMENTATION = {
15441
16295
  summary: "Require Next.js middleware and proxy matcher configuration to contain only build-time literals.",
15442
16296
  rationale: "Next.js must statically analyze matcher values at build time; computed values are ignored.",
@@ -15449,34 +16303,34 @@ var REQUIRE_STATIC_NEXT_MATCHER_DOCUMENTATION = {
15449
16303
  };
15450
16304
  var NEXT_ENTRY_FILE = /(?:^|[/\\])(?:middleware|proxy)\.[cm]?[jt]sx?$/u;
15451
16305
  function unwrapExpression3(node) {
15452
- if (node.type === AST_NODE_TYPES62.TSAsExpression || node.type === AST_NODE_TYPES62.TSSatisfiesExpression || node.type === AST_NODE_TYPES62.TSNonNullExpression || node.type === AST_NODE_TYPES62.TSTypeAssertion) {
16306
+ if (node.type === AST_NODE_TYPES69.TSAsExpression || node.type === AST_NODE_TYPES69.TSSatisfiesExpression || node.type === AST_NODE_TYPES69.TSNonNullExpression || node.type === AST_NODE_TYPES69.TSTypeAssertion) {
15453
16307
  return unwrapExpression3(node.expression);
15454
16308
  }
15455
16309
  return node;
15456
16310
  }
15457
16311
  function isStaticValue(node) {
15458
16312
  const value = unwrapExpression3(node);
15459
- if (value.type === AST_NODE_TYPES62.Literal) {
16313
+ if (value.type === AST_NODE_TYPES69.Literal) {
15460
16314
  return true;
15461
16315
  }
15462
- if (value.type === AST_NODE_TYPES62.TemplateLiteral) {
16316
+ if (value.type === AST_NODE_TYPES69.TemplateLiteral) {
15463
16317
  return value.expressions.length === 0;
15464
16318
  }
15465
- if (value.type === AST_NODE_TYPES62.ArrayExpression) {
16319
+ if (value.type === AST_NODE_TYPES69.ArrayExpression) {
15466
16320
  return value.elements.every(
15467
- (element) => element !== null && element.type !== AST_NODE_TYPES62.SpreadElement && isStaticValue(element)
16321
+ (element) => element !== null && element.type !== AST_NODE_TYPES69.SpreadElement && isStaticValue(element)
15468
16322
  );
15469
16323
  }
15470
- if (value.type === AST_NODE_TYPES62.ObjectExpression) {
16324
+ if (value.type === AST_NODE_TYPES69.ObjectExpression) {
15471
16325
  return value.properties.every(
15472
- (property) => property.type === AST_NODE_TYPES62.Property && property.kind === "init" && !property.computed && property.value.type !== AST_NODE_TYPES62.AssignmentPattern && isStaticValue(property.value)
16326
+ (property) => property.type === AST_NODE_TYPES69.Property && property.kind === "init" && !property.computed && property.value.type !== AST_NODE_TYPES69.AssignmentPattern && isStaticValue(property.value)
15473
16327
  );
15474
16328
  }
15475
16329
  return false;
15476
16330
  }
15477
- function propertyName4(property) {
16331
+ function propertyName6(property) {
15478
16332
  if (property.computed) return null;
15479
- if (property.key.type === AST_NODE_TYPES62.Identifier) return property.key.name;
16333
+ if (property.key.type === AST_NODE_TYPES69.Identifier) return property.key.name;
15480
16334
  return typeof property.key.value === "string" ? property.key.value : null;
15481
16335
  }
15482
16336
  var require_static_next_matcher_default = createRule({
@@ -15499,19 +16353,19 @@ var require_static_next_matcher_default = createRule({
15499
16353
  }
15500
16354
  return {
15501
16355
  ExportNamedDeclaration(node) {
15502
- if (node.declaration?.type !== AST_NODE_TYPES62.VariableDeclaration) {
16356
+ if (node.declaration?.type !== AST_NODE_TYPES69.VariableDeclaration) {
15503
16357
  return;
15504
16358
  }
15505
16359
  for (const declaration of node.declaration.declarations) {
15506
- if (declaration.id.type !== AST_NODE_TYPES62.Identifier || declaration.id.name !== "config" || declaration.init === null) {
16360
+ if (declaration.id.type !== AST_NODE_TYPES69.Identifier || declaration.id.name !== "config" || declaration.init === null) {
15507
16361
  continue;
15508
16362
  }
15509
16363
  const config = unwrapExpression3(declaration.init);
15510
- if (config.type !== AST_NODE_TYPES62.ObjectExpression) {
16364
+ if (config.type !== AST_NODE_TYPES69.ObjectExpression) {
15511
16365
  continue;
15512
16366
  }
15513
16367
  for (const property of config.properties) {
15514
- if (property.type !== AST_NODE_TYPES62.Property || propertyName4(property) !== "matcher" || property.value.type === AST_NODE_TYPES62.AssignmentPattern) {
16368
+ if (property.type !== AST_NODE_TYPES69.Property || propertyName6(property) !== "matcher" || property.value.type === AST_NODE_TYPES69.AssignmentPattern) {
15515
16369
  continue;
15516
16370
  }
15517
16371
  if (!isStaticValue(property.value)) {
@@ -15525,7 +16379,7 @@ var require_static_next_matcher_default = createRule({
15525
16379
  });
15526
16380
 
15527
16381
  // src/rules/require-use-form-default-values.ts
15528
- import { ASTUtils as ASTUtils20 } from "@typescript-eslint/utils";
16382
+ import { ASTUtils as ASTUtils21 } from "@typescript-eslint/utils";
15529
16383
  var REQUIRE_USE_FORM_DEFAULT_VALUES_DOCUMENTATION = {
15530
16384
  summary: "react-hook-form useForm call without defaultValues",
15531
16385
  rationale: "Without an explicit initial value, fields can change from uncontrolled to controlled as data arrives, reset behavior becomes ambiguous, and the form's initial shape no longer documents the values users can edit.",
@@ -15579,13 +16433,13 @@ var require_use_form_default_values_default = createRule({
15579
16433
  if (node.source.value !== "react-hook-form") return;
15580
16434
  for (const specifier of node.specifiers) {
15581
16435
  if (specifier.type !== "ImportSpecifier" || (specifier.imported.type === "Identifier" ? specifier.imported.name : specifier.imported.value) !== "useForm") continue;
15582
- const variable = ASTUtils20.findVariable(context.sourceCode.getScope(specifier.local), specifier.local.name);
16436
+ const variable = ASTUtils21.findVariable(context.sourceCode.getScope(specifier.local), specifier.local.name);
15583
16437
  if (variable) importedHooks.add(variable);
15584
16438
  }
15585
16439
  },
15586
16440
  CallExpression(node) {
15587
16441
  if (node.callee.type !== "Identifier") return;
15588
- const variable = ASTUtils20.findVariable(context.sourceCode.getScope(node.callee), node.callee.name);
16442
+ const variable = ASTUtils21.findVariable(context.sourceCode.getScope(node.callee), node.callee.name);
15589
16443
  const options = node.arguments[0];
15590
16444
  if (!variable || !importedHooks.has(variable) || options !== void 0 && options.type !== "ObjectExpression" || hasDefaultValues(options)) return;
15591
16445
  context.report({ node, messageId: "requireUseFormDefaultValues" });
@@ -15662,8 +16516,8 @@ var require_use_server_in_actions_file_default = createRule({
15662
16516
 
15663
16517
  // src/rules/require-zod-form-validation.ts
15664
16518
  import {
15665
- AST_NODE_TYPES as AST_NODE_TYPES63,
15666
- ASTUtils as ASTUtils21
16519
+ AST_NODE_TYPES as AST_NODE_TYPES70,
16520
+ ASTUtils as ASTUtils22
15667
16521
  } from "@typescript-eslint/utils";
15668
16522
  var REQUIRE_ZOD_FORM_VALIDATION_DOCUMENTATION = {
15669
16523
  summary: "Require Zod validation (`Schema.parse(...)` / `Schema.safeParse(...)`) when reading values out of a `FormData` object.",
@@ -15689,14 +16543,14 @@ var FORM_VALUE_METHODS = /* @__PURE__ */ new Set(["get", "getAll"]);
15689
16543
  var zodReceiverRoot = (node) => {
15690
16544
  let current = node;
15691
16545
  while (true) {
15692
- if (current.type === AST_NODE_TYPES63.Identifier) {
16546
+ if (current.type === AST_NODE_TYPES70.Identifier) {
15693
16547
  return current;
15694
16548
  }
15695
- if (current.type === AST_NODE_TYPES63.CallExpression) {
16549
+ if (current.type === AST_NODE_TYPES70.CallExpression) {
15696
16550
  current = current.callee;
15697
16551
  continue;
15698
16552
  }
15699
- if (current.type === AST_NODE_TYPES63.MemberExpression) {
16553
+ if (current.type === AST_NODE_TYPES70.MemberExpression) {
15700
16554
  current = current.object;
15701
16555
  continue;
15702
16556
  }
@@ -15705,12 +16559,12 @@ var zodReceiverRoot = (node) => {
15705
16559
  };
15706
16560
  var isFormDataMethodCall = (node) => {
15707
16561
  let current = node;
15708
- if (current.type === AST_NODE_TYPES63.AwaitExpression) {
16562
+ if (current.type === AST_NODE_TYPES70.AwaitExpression) {
15709
16563
  current = current.argument;
15710
16564
  }
15711
- if (current.type !== AST_NODE_TYPES63.CallExpression) return false;
16565
+ if (current.type !== AST_NODE_TYPES70.CallExpression) return false;
15712
16566
  const callee = current.callee;
15713
- return callee.type === AST_NODE_TYPES63.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES63.Identifier && callee.property.name === "formData";
16567
+ return callee.type === AST_NODE_TYPES70.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES70.Identifier && callee.property.name === "formData";
15714
16568
  };
15715
16569
  var require_zod_form_validation_default = createRule({
15716
16570
  name: "require-zod-form-validation",
@@ -15731,7 +16585,7 @@ var require_zod_form_validation_default = createRule({
15731
16585
  return {};
15732
16586
  }
15733
16587
  const zodBindings = /* @__PURE__ */ new Set();
15734
- const resolvedBinding = (identifier) => ASTUtils21.findVariable(
16588
+ const resolvedBinding = (identifier) => ASTUtils22.findVariable(
15735
16589
  context.sourceCode.getScope(identifier),
15736
16590
  identifier.name
15737
16591
  );
@@ -15741,16 +16595,16 @@ var require_zod_form_validation_default = createRule({
15741
16595
  return false;
15742
16596
  }
15743
16597
  const definition = binding.defs[0];
15744
- if (definition?.type !== "Variable" || definition.node.type !== AST_NODE_TYPES63.VariableDeclarator) {
16598
+ if (definition?.type !== "Variable" || definition.node.type !== AST_NODE_TYPES70.VariableDeclarator) {
15745
16599
  return false;
15746
16600
  }
15747
16601
  const init = definition.node.init;
15748
- return init?.type === AST_NODE_TYPES63.ObjectExpression || init?.type === AST_NODE_TYPES63.ArrayExpression || init?.type === AST_NODE_TYPES63.Literal || init?.type === AST_NODE_TYPES63.ArrowFunctionExpression || init?.type === AST_NODE_TYPES63.FunctionExpression;
16602
+ return init?.type === AST_NODE_TYPES70.ObjectExpression || init?.type === AST_NODE_TYPES70.ArrayExpression || init?.type === AST_NODE_TYPES70.Literal || init?.type === AST_NODE_TYPES70.ArrowFunctionExpression || init?.type === AST_NODE_TYPES70.FunctionExpression;
15749
16603
  };
15750
16604
  const isZodParseCall = (node) => {
15751
- if (node.type !== AST_NODE_TYPES63.CallExpression) return false;
16605
+ if (node.type !== AST_NODE_TYPES70.CallExpression) return false;
15752
16606
  const callee = node.callee;
15753
- if (callee.type !== AST_NODE_TYPES63.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES63.Identifier || !ZOD_PARSE_METHODS.has(callee.property.name)) {
16607
+ if (callee.type !== AST_NODE_TYPES70.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES70.Identifier || !ZOD_PARSE_METHODS.has(callee.property.name)) {
15754
16608
  return false;
15755
16609
  }
15756
16610
  const root = zodReceiverRoot(callee.object);
@@ -15759,14 +16613,14 @@ var require_zod_form_validation_default = createRule({
15759
16613
  return binding !== null && zodBindings.has(binding) || (root.name === "z" || ZOD_SCHEMA_NAME_RE.test(root.name)) && !isProvablyNonZodLocal(root);
15760
16614
  };
15761
16615
  const isFormSourceIdentifier = (node) => {
15762
- if (node.type !== AST_NODE_TYPES63.Identifier) return false;
16616
+ if (node.type !== AST_NODE_TYPES70.Identifier) return false;
15763
16617
  const conventionalName = /formdata/i.test(node.name);
15764
16618
  let scope = context.sourceCode.getScope(node);
15765
16619
  while (scope !== null) {
15766
16620
  const variable = scope.set.get(node.name);
15767
16621
  if (variable !== void 0 && variable.defs.length === 1) {
15768
16622
  const def = variable.defs[0];
15769
- if (def !== void 0 && def.type === "Variable" && def.node.type === AST_NODE_TYPES63.VariableDeclarator && def.node.init !== null) {
16623
+ if (def !== void 0 && def.type === "Variable" && def.node.type === AST_NODE_TYPES70.VariableDeclarator && def.node.init !== null) {
15770
16624
  return isFormDataMethodCall(def.node.init);
15771
16625
  }
15772
16626
  return def?.type === "Parameter" && conventionalName;
@@ -15777,8 +16631,8 @@ var require_zod_form_validation_default = createRule({
15777
16631
  };
15778
16632
  const isFormDataGetCall = (node) => {
15779
16633
  const callee = node.callee;
15780
- if (callee.type !== AST_NODE_TYPES63.MemberExpression) return false;
15781
- if (callee.property.type !== AST_NODE_TYPES63.Identifier || !FORM_VALUE_METHODS.has(callee.property.name)) {
16634
+ if (callee.type !== AST_NODE_TYPES70.MemberExpression) return false;
16635
+ if (callee.property.type !== AST_NODE_TYPES70.Identifier || !FORM_VALUE_METHODS.has(callee.property.name)) {
15782
16636
  return false;
15783
16637
  }
15784
16638
  return isFormSourceIdentifier(callee.object);
@@ -15794,16 +16648,16 @@ var require_zod_form_validation_default = createRule({
15794
16648
  const hasZodParseAncestor = (node) => zodParseAncestor(node) !== null;
15795
16649
  const isInstanceofNarrowing = (node) => {
15796
16650
  const parent = node.parent;
15797
- return parent !== null && parent !== void 0 && parent.type === AST_NODE_TYPES63.BinaryExpression && parent.operator === "instanceof" && parent.left === node && parent.right.type === AST_NODE_TYPES63.Identifier && (parent.right.name === "File" || parent.right.name === "Blob");
16651
+ return parent !== null && parent !== void 0 && parent.type === AST_NODE_TYPES70.BinaryExpression && parent.operator === "instanceof" && parent.left === node && parent.right.type === AST_NODE_TYPES70.Identifier && (parent.right.name === "File" || parent.right.name === "Blob");
15798
16652
  };
15799
16653
  const boundDeclarator = (node) => {
15800
16654
  let current = node;
15801
16655
  let parent = current.parent;
15802
- while ((parent.type === AST_NODE_TYPES63.TSAsExpression || parent.type === AST_NODE_TYPES63.TSSatisfiesExpression || parent.type === AST_NODE_TYPES63.TSNonNullExpression || parent.type === AST_NODE_TYPES63.ChainExpression) && parent.expression === current) {
16656
+ while ((parent.type === AST_NODE_TYPES70.TSAsExpression || parent.type === AST_NODE_TYPES70.TSSatisfiesExpression || parent.type === AST_NODE_TYPES70.TSNonNullExpression || parent.type === AST_NODE_TYPES70.ChainExpression) && parent.expression === current) {
15803
16657
  current = parent;
15804
16658
  parent = current.parent;
15805
16659
  }
15806
- if (parent.type === AST_NODE_TYPES63.VariableDeclarator && parent.init === current && parent.id.type === AST_NODE_TYPES63.Identifier) {
16660
+ if (parent.type === AST_NODE_TYPES70.VariableDeclarator && parent.init === current && parent.id.type === AST_NODE_TYPES70.Identifier) {
15807
16661
  return parent;
15808
16662
  }
15809
16663
  return null;
@@ -15812,7 +16666,7 @@ var require_zod_form_validation_default = createRule({
15812
16666
  let current = node;
15813
16667
  while (current.parent !== void 0) {
15814
16668
  const parent = current.parent;
15815
- if (parent.type === AST_NODE_TYPES63.BlockStatement || parent.type === AST_NODE_TYPES63.Program) {
16669
+ if (parent.type === AST_NODE_TYPES70.BlockStatement || parent.type === AST_NODE_TYPES70.Program) {
15816
16670
  return current;
15817
16671
  }
15818
16672
  current = parent;
@@ -15821,12 +16675,12 @@ var require_zod_form_validation_default = createRule({
15821
16675
  };
15822
16676
  const zodParseMethod = (call) => {
15823
16677
  const callee = call.callee;
15824
- return callee.type === AST_NODE_TYPES63.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES63.Identifier ? callee.property.name : null;
16678
+ return callee.type === AST_NODE_TYPES70.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES70.Identifier ? callee.property.name : null;
15825
16679
  };
15826
16680
  const hasConditionalAncestorBeforeStatement = (node, statement) => {
15827
16681
  let current = node.parent;
15828
16682
  while (current !== void 0 && current !== statement) {
15829
- if (current.type === AST_NODE_TYPES63.LogicalExpression || current.type === AST_NODE_TYPES63.ConditionalExpression) {
16683
+ if (current.type === AST_NODE_TYPES70.LogicalExpression || current.type === AST_NODE_TYPES70.ConditionalExpression) {
15830
16684
  return true;
15831
16685
  }
15832
16686
  current = current.parent;
@@ -15836,7 +16690,7 @@ var require_zod_form_validation_default = createRule({
15836
16690
  const isAwaitedBeforeStatement = (node, statement) => {
15837
16691
  let current = node.parent;
15838
16692
  while (current !== void 0 && current !== statement) {
15839
- if (current.type === AST_NODE_TYPES63.AwaitExpression) return true;
16693
+ if (current.type === AST_NODE_TYPES70.AwaitExpression) return true;
15840
16694
  current = current.parent;
15841
16695
  }
15842
16696
  return false;
@@ -15849,7 +16703,7 @@ var require_zod_form_validation_default = createRule({
15849
16703
  if (declarationStatement === null || validationStatement === null || declarationStatement.parent !== validationStatement.parent || validationStatement.range[0] <= declarationStatement.range[1] || hasConditionalAncestorBeforeStatement(parse2, validationStatement)) {
15850
16704
  return null;
15851
16705
  }
15852
- if (validationStatement.type !== AST_NODE_TYPES63.VariableDeclaration && validationStatement.type !== AST_NODE_TYPES63.ExpressionStatement) {
16706
+ if (validationStatement.type !== AST_NODE_TYPES70.VariableDeclaration && validationStatement.type !== AST_NODE_TYPES70.ExpressionStatement) {
15853
16707
  return null;
15854
16708
  }
15855
16709
  const method = zodParseMethod(parse2);
@@ -15861,16 +16715,16 @@ var require_zod_form_validation_default = createRule({
15861
16715
  };
15862
16716
  const isSafePrevalidationInspection = (identifier) => {
15863
16717
  const parent = identifier.parent;
15864
- if (parent.type === AST_NODE_TYPES63.UnaryExpression && parent.operator === "typeof") {
16718
+ if (parent.type === AST_NODE_TYPES70.UnaryExpression && parent.operator === "typeof") {
15865
16719
  return true;
15866
16720
  }
15867
- if (parent.type !== AST_NODE_TYPES63.BinaryExpression || parent.left !== identifier) {
16721
+ if (parent.type !== AST_NODE_TYPES70.BinaryExpression || parent.left !== identifier) {
15868
16722
  return false;
15869
16723
  }
15870
16724
  if (parent.operator === "instanceof") {
15871
- return parent.right.type === AST_NODE_TYPES63.Identifier && (parent.right.name === "File" || parent.right.name === "Blob");
16725
+ return parent.right.type === AST_NODE_TYPES70.Identifier && (parent.right.name === "File" || parent.right.name === "Blob");
15872
16726
  }
15873
- return ["===", "!==", "==", "!="].includes(parent.operator) && (parent.right.type === AST_NODE_TYPES63.Literal && parent.right.value === null || parent.right.type === AST_NODE_TYPES63.Identifier && parent.right.name === "undefined");
16727
+ return ["===", "!==", "==", "!="].includes(parent.operator) && (parent.right.type === AST_NODE_TYPES70.Literal && parent.right.value === null || parent.right.type === AST_NODE_TYPES70.Identifier && parent.right.name === "undefined");
15874
16728
  };
15875
16729
  const isDescendantOf = (node, ancestor) => {
15876
16730
  let current = node;
@@ -15881,23 +16735,23 @@ var require_zod_form_validation_default = createRule({
15881
16735
  return false;
15882
16736
  };
15883
16737
  const blockTerminates = (node) => {
15884
- if (node.type === AST_NODE_TYPES63.ReturnStatement || node.type === AST_NODE_TYPES63.ThrowStatement) {
16738
+ if (node.type === AST_NODE_TYPES70.ReturnStatement || node.type === AST_NODE_TYPES70.ThrowStatement) {
15885
16739
  return true;
15886
16740
  }
15887
- if (node.type !== AST_NODE_TYPES63.BlockStatement || node.body.length === 0) return false;
16741
+ if (node.type !== AST_NODE_TYPES70.BlockStatement || node.body.length === 0) return false;
15888
16742
  const last = node.body.at(-1);
15889
16743
  return last !== void 0 && blockTerminates(last);
15890
16744
  };
15891
16745
  const narrowingIf = (identifier) => {
15892
16746
  const comparison = identifier.parent;
15893
- if (comparison?.type !== AST_NODE_TYPES63.BinaryExpression || comparison.operator !== "instanceof" || comparison.left !== identifier || comparison.right.type !== AST_NODE_TYPES63.Identifier || comparison.right.name !== "File" && comparison.right.name !== "Blob") {
16747
+ if (comparison?.type !== AST_NODE_TYPES70.BinaryExpression || comparison.operator !== "instanceof" || comparison.left !== identifier || comparison.right.type !== AST_NODE_TYPES70.Identifier || comparison.right.name !== "File" && comparison.right.name !== "Blob") {
15894
16748
  return null;
15895
16749
  }
15896
16750
  const maybeNegation = comparison.parent;
15897
- const negated = maybeNegation?.type === AST_NODE_TYPES63.UnaryExpression && maybeNegation.operator === "!";
16751
+ const negated = maybeNegation?.type === AST_NODE_TYPES70.UnaryExpression && maybeNegation.operator === "!";
15898
16752
  const test = negated ? maybeNegation : comparison;
15899
16753
  const branch = test.parent;
15900
- return branch?.type === AST_NODE_TYPES63.IfStatement && branch.test === test ? { branch, positive: !negated } : null;
16754
+ return branch?.type === AST_NODE_TYPES70.IfStatement && branch.test === test ? { branch, positive: !negated } : null;
15901
16755
  };
15902
16756
  const useDominatedByNarrowing = (use, narrowings) => narrowings.some(({ branch, positive }) => {
15903
16757
  if (positive) return isDescendantOf(use, branch.consequent);
@@ -15917,7 +16771,7 @@ var require_zod_form_validation_default = createRule({
15917
16771
  const variable = context.sourceCode.getDeclaredVariables(declarator)[0];
15918
16772
  if (variable === void 0) return false;
15919
16773
  const references = variable.references.filter((reference) => !reference.isWriteOnly()).map((reference) => reference.identifier).filter(
15920
- (identifier) => identifier.type === AST_NODE_TYPES63.Identifier
16774
+ (identifier) => identifier.type === AST_NODE_TYPES70.Identifier
15921
16775
  );
15922
16776
  if (references.length === 0) return false;
15923
16777
  const narrowings = references.map(narrowingIf).filter(
@@ -15943,7 +16797,7 @@ var require_zod_form_validation_default = createRule({
15943
16797
  ImportDeclaration(node) {
15944
16798
  if (!isZodModule(node.source.value)) return;
15945
16799
  for (const specifier of node.specifiers) {
15946
- if (specifier.type === AST_NODE_TYPES63.ImportNamespaceSpecifier || specifier.type === AST_NODE_TYPES63.ImportDefaultSpecifier || specifier.type === AST_NODE_TYPES63.ImportSpecifier && (specifier.imported.type === AST_NODE_TYPES63.Identifier ? specifier.imported.name === "z" : specifier.imported.value === "z")) {
16800
+ if (specifier.type === AST_NODE_TYPES70.ImportNamespaceSpecifier || specifier.type === AST_NODE_TYPES70.ImportDefaultSpecifier || specifier.type === AST_NODE_TYPES70.ImportSpecifier && (specifier.imported.type === AST_NODE_TYPES70.Identifier ? specifier.imported.name === "z" : specifier.imported.value === "z")) {
15947
16801
  const binding = resolvedBinding(specifier.local);
15948
16802
  if (binding !== null) zodBindings.add(binding);
15949
16803
  }
@@ -16028,7 +16882,7 @@ var store_insert_requires_on_conflict_default = createRule({
16028
16882
  });
16029
16883
 
16030
16884
  // src/rules/stepdown.ts
16031
- import { AST_NODE_TYPES as AST_NODE_TYPES64, ASTUtils as ASTUtils22 } from "@typescript-eslint/utils";
16885
+ import { AST_NODE_TYPES as AST_NODE_TYPES71, ASTUtils as ASTUtils23 } from "@typescript-eslint/utils";
16032
16886
  var STEPDOWN_DOCUMENTATION = {
16033
16887
  summary: "Place a private helper below its sole direct same-scope caller.",
16034
16888
  rationale: "Caller-first ordering lets a reader follow the main flow before descending into implementation details.",
@@ -16048,7 +16902,7 @@ var STEPDOWN_DOCUMENTATION = {
16048
16902
  ]
16049
16903
  };
16050
16904
  function isFunction(node) {
16051
- return node.type === AST_NODE_TYPES64.ArrowFunctionExpression || node.type === AST_NODE_TYPES64.FunctionDeclaration || node.type === AST_NODE_TYPES64.FunctionExpression;
16905
+ return node.type === AST_NODE_TYPES71.ArrowFunctionExpression || node.type === AST_NODE_TYPES71.FunctionDeclaration || node.type === AST_NODE_TYPES71.FunctionExpression;
16052
16906
  }
16053
16907
  function reportMisordered(context, candidates, scopeDefinitions, calls, pinned, canMove = () => true, makeFix) {
16054
16908
  const byName = new Map(scopeDefinitions.map((definition) => [definition.name, definition]));
@@ -16145,8 +16999,8 @@ function moduleScope(context, program) {
16145
16999
  for (const node of declarations) counts.set(node.name, (counts.get(node.name) ?? 0) + 1);
16146
17000
  const overloadNames = new Set(
16147
17001
  program.body.flatMap((statement) => {
16148
- const node = statement.type === AST_NODE_TYPES64.ExportNamedDeclaration ? statement.declaration : statement;
16149
- return node?.type === AST_NODE_TYPES64.TSDeclareFunction && node.id !== null ? [node.id.name] : [];
17002
+ const node = statement.type === AST_NODE_TYPES71.ExportNamedDeclaration ? statement.declaration : statement;
17003
+ return node?.type === AST_NODE_TYPES71.TSDeclareFunction && node.id !== null ? [node.id.name] : [];
16150
17004
  })
16151
17005
  );
16152
17006
  const exported = exportedNames(program);
@@ -16170,7 +17024,7 @@ function moduleScope(context, program) {
16170
17024
  const nearestFunction2 = [...ancestors].reverse().find(isFunction);
16171
17025
  const parent = identifier.parent;
16172
17026
  const callerDefinition = nearestFunction2 === void 0 ? void 0 : byFunction.get(nearestFunction2);
16173
- if (callerDefinition === void 0 || parent.type !== AST_NODE_TYPES64.CallExpression || parent.callee !== identifier) {
17027
+ if (callerDefinition === void 0 || parent.type !== AST_NODE_TYPES71.CallExpression || parent.callee !== identifier) {
16174
17028
  pinned.add(definition.name);
16175
17029
  continue;
16176
17030
  }
@@ -16185,38 +17039,38 @@ function moduleScope(context, program) {
16185
17039
  function exportedNames(program) {
16186
17040
  const names = /* @__PURE__ */ new Set();
16187
17041
  for (const statement of program.body) {
16188
- if (statement.type !== AST_NODE_TYPES64.ExportNamedDeclaration || statement.exportKind === "type" || statement.source !== null) continue;
16189
- if (statement.declaration?.type === AST_NODE_TYPES64.FunctionDeclaration && statement.declaration.id !== null) {
17042
+ if (statement.type !== AST_NODE_TYPES71.ExportNamedDeclaration || statement.exportKind === "type" || statement.source !== null) continue;
17043
+ if (statement.declaration?.type === AST_NODE_TYPES71.FunctionDeclaration && statement.declaration.id !== null) {
16190
17044
  names.add(statement.declaration.id.name);
16191
17045
  }
16192
- if (statement.declaration?.type === AST_NODE_TYPES64.VariableDeclaration) {
17046
+ if (statement.declaration?.type === AST_NODE_TYPES71.VariableDeclaration) {
16193
17047
  for (const declarator of statement.declaration.declarations) {
16194
- if (declarator.id.type === AST_NODE_TYPES64.Identifier) names.add(declarator.id.name);
17048
+ if (declarator.id.type === AST_NODE_TYPES71.Identifier) names.add(declarator.id.name);
16195
17049
  }
16196
17050
  }
16197
17051
  for (const specifier of statement.specifiers) {
16198
- if (specifier.exportKind !== "type" && specifier.local.type === AST_NODE_TYPES64.Identifier) {
17052
+ if (specifier.exportKind !== "type" && specifier.local.type === AST_NODE_TYPES71.Identifier) {
16199
17053
  names.add(specifier.local.name);
16200
17054
  }
16201
17055
  }
16202
17056
  }
16203
17057
  for (const statement of program.body) {
16204
- if (statement.type === AST_NODE_TYPES64.ExportDefaultDeclaration && statement.declaration.type === AST_NODE_TYPES64.Identifier) names.add(statement.declaration.name);
16205
- if (statement.type === AST_NODE_TYPES64.ExportDefaultDeclaration && statement.declaration.type === AST_NODE_TYPES64.FunctionDeclaration && statement.declaration.id !== null) names.add(statement.declaration.id.name);
17058
+ if (statement.type === AST_NODE_TYPES71.ExportDefaultDeclaration && statement.declaration.type === AST_NODE_TYPES71.Identifier) names.add(statement.declaration.name);
17059
+ if (statement.type === AST_NODE_TYPES71.ExportDefaultDeclaration && statement.declaration.type === AST_NODE_TYPES71.FunctionDeclaration && statement.declaration.id !== null) names.add(statement.declaration.id.name);
16206
17060
  }
16207
17061
  return names;
16208
17062
  }
16209
17063
  function moduleDefinitions(program) {
16210
17064
  const definitions = [];
16211
17065
  for (const statement of program.body) {
16212
- const node = statement.type === AST_NODE_TYPES64.ExportNamedDeclaration || statement.type === AST_NODE_TYPES64.ExportDefaultDeclaration ? statement.declaration : statement;
16213
- if (node?.type === AST_NODE_TYPES64.FunctionDeclaration && node.id !== null && node.body !== null) {
17066
+ const node = statement.type === AST_NODE_TYPES71.ExportNamedDeclaration || statement.type === AST_NODE_TYPES71.ExportDefaultDeclaration ? statement.declaration : statement;
17067
+ if (node?.type === AST_NODE_TYPES71.FunctionDeclaration && node.id !== null && node.body !== null) {
16214
17068
  definitions.push({ name: node.id.name, node, functionNode: node, bindingNode: node });
16215
17069
  continue;
16216
17070
  }
16217
- if (node?.type !== AST_NODE_TYPES64.VariableDeclaration || node.kind !== "const") continue;
17071
+ if (node?.type !== AST_NODE_TYPES71.VariableDeclaration || node.kind !== "const") continue;
16218
17072
  for (const declarator of node.declarations) {
16219
- if (declarator.id.type === AST_NODE_TYPES64.Identifier && declarator.init !== null && isFunction(declarator.init)) {
17073
+ if (declarator.id.type === AST_NODE_TYPES71.Identifier && declarator.init !== null && isFunction(declarator.init)) {
16220
17074
  definitions.push({
16221
17075
  name: declarator.id.name,
16222
17076
  node: declarator,
@@ -16229,21 +17083,21 @@ function moduleDefinitions(program) {
16229
17083
  return definitions;
16230
17084
  }
16231
17085
  function methodName(node) {
16232
- if (node.key.type === AST_NODE_TYPES64.PrivateIdentifier) return `#${node.key.name}`;
16233
- return !node.computed && node.key.type === AST_NODE_TYPES64.Identifier ? node.key.name : null;
17086
+ if (node.key.type === AST_NODE_TYPES71.PrivateIdentifier) return `#${node.key.name}`;
17087
+ return !node.computed && node.key.type === AST_NODE_TYPES71.Identifier ? node.key.name : null;
16234
17088
  }
16235
17089
  function referencedMethod(context, node, classVariables) {
16236
- const objectVariable = node.object.type === AST_NODE_TYPES64.Identifier ? ASTUtils22.findVariable(context.sourceCode.getScope(node.object), node.object.name) : null;
17090
+ const objectVariable = node.object.type === AST_NODE_TYPES71.Identifier ? ASTUtils23.findVariable(context.sourceCode.getScope(node.object), node.object.name) : null;
16237
17091
  const isClassReference = objectVariable !== null && classVariables.has(objectVariable);
16238
- if (node.object.type !== AST_NODE_TYPES64.ThisExpression && !isClassReference) return null;
16239
- if (node.property.type === AST_NODE_TYPES64.PrivateIdentifier) return `#${node.property.name}`;
16240
- if (!node.computed && node.property.type === AST_NODE_TYPES64.Identifier) return node.property.name;
16241
- return node.computed && node.property.type === AST_NODE_TYPES64.Literal && typeof node.property.value === "string" ? node.property.value : null;
17092
+ if (node.object.type !== AST_NODE_TYPES71.ThisExpression && !isClassReference) return null;
17093
+ if (node.property.type === AST_NODE_TYPES71.PrivateIdentifier) return `#${node.property.name}`;
17094
+ if (!node.computed && node.property.type === AST_NODE_TYPES71.Identifier) return node.property.name;
17095
+ return node.computed && node.property.type === AST_NODE_TYPES71.Literal && typeof node.property.value === "string" ? node.property.value : null;
16242
17096
  }
16243
17097
  function referencedPropertyName(node) {
16244
- if (node.property.type === AST_NODE_TYPES64.PrivateIdentifier) return `#${node.property.name}`;
16245
- if (!node.computed && node.property.type === AST_NODE_TYPES64.Identifier) return node.property.name;
16246
- return node.computed && node.property.type === AST_NODE_TYPES64.Literal && typeof node.property.value === "string" ? node.property.value : null;
17098
+ if (node.property.type === AST_NODE_TYPES71.PrivateIdentifier) return `#${node.property.name}`;
17099
+ if (!node.computed && node.property.type === AST_NODE_TYPES71.Identifier) return node.property.name;
17100
+ return node.computed && node.property.type === AST_NODE_TYPES71.Literal && typeof node.property.value === "string" ? node.property.value : null;
16247
17101
  }
16248
17102
  function walk2(node, visitorKeys, visit, nestedFunction = false) {
16249
17103
  visit(node, nestedFunction);
@@ -16259,7 +17113,7 @@ function walk2(node, visitorKeys, visit, nestedFunction = false) {
16259
17113
  }
16260
17114
  function classScope(context, node, computedReferenceNames) {
16261
17115
  const methods = node.body.body.filter(
16262
- (member) => member.type === AST_NODE_TYPES64.MethodDefinition
17116
+ (member) => member.type === AST_NODE_TYPES71.MethodDefinition
16263
17117
  );
16264
17118
  const counts = /* @__PURE__ */ new Map();
16265
17119
  for (const method of methods) {
@@ -16267,8 +17121,8 @@ function classScope(context, node, computedReferenceNames) {
16267
17121
  if (name !== null) counts.set(name, (counts.get(name) ?? 0) + 1);
16268
17122
  }
16269
17123
  for (const member of node.body.body) {
16270
- if (member.type !== AST_NODE_TYPES64.TSAbstractMethodDefinition) continue;
16271
- const name = !member.computed && member.key.type === AST_NODE_TYPES64.Identifier ? member.key.name : null;
17124
+ if (member.type !== AST_NODE_TYPES71.TSAbstractMethodDefinition) continue;
17125
+ const name = !member.computed && member.key.type === AST_NODE_TYPES71.Identifier ? member.key.name : null;
16272
17126
  if (name !== null) counts.set(name, (counts.get(name) ?? 0) + 1);
16273
17127
  }
16274
17128
  const scopeDefinitions = methods.flatMap((method) => {
@@ -16277,7 +17131,7 @@ function classScope(context, node, computedReferenceNames) {
16277
17131
  });
16278
17132
  const definitions = methods.flatMap((method) => {
16279
17133
  const name = methodName(method);
16280
- const isPrivate = method.accessibility === "private" || method.key.type === AST_NODE_TYPES64.PrivateIdentifier;
17134
+ const isPrivate = method.accessibility === "private" || method.key.type === AST_NODE_TYPES71.PrivateIdentifier;
16281
17135
  return name !== null && isPrivate && counts.get(name) === 1 && method.decorators.length === 0 ? [{ name, node: method }] : [];
16282
17136
  });
16283
17137
  if (definitions.length === 0) return;
@@ -16286,11 +17140,11 @@ function classScope(context, node, computedReferenceNames) {
16286
17140
  const pinned = /* @__PURE__ */ new Set();
16287
17141
  const classVariables = /* @__PURE__ */ new Set();
16288
17142
  if (node.id !== null) {
16289
- const internal = ASTUtils22.findVariable(context.sourceCode.getScope(node), node.id.name);
17143
+ const internal = ASTUtils23.findVariable(context.sourceCode.getScope(node), node.id.name);
16290
17144
  if (internal !== null) classVariables.add(internal);
16291
17145
  }
16292
- if (node.type === AST_NODE_TYPES64.ClassExpression && node.parent.type === AST_NODE_TYPES64.VariableDeclarator && node.parent.id.type === AST_NODE_TYPES64.Identifier) {
16293
- const outer = ASTUtils22.findVariable(context.sourceCode.getScope(node.parent), node.parent.id.name);
17146
+ if (node.type === AST_NODE_TYPES71.ClassExpression && node.parent.type === AST_NODE_TYPES71.VariableDeclarator && node.parent.id.type === AST_NODE_TYPES71.Identifier) {
17147
+ const outer = ASTUtils23.findVariable(context.sourceCode.getScope(node.parent), node.parent.id.name);
16294
17148
  if (outer !== null) classVariables.add(outer);
16295
17149
  }
16296
17150
  for (const method of methods) {
@@ -16306,27 +17160,27 @@ function classScope(context, node, computedReferenceNames) {
16306
17160
  }
16307
17161
  const thisValue = (value) => {
16308
17162
  let current = value;
16309
- while (current?.type === AST_NODE_TYPES64.TSAsExpression || current?.type === AST_NODE_TYPES64.TSSatisfiesExpression || current?.type === AST_NODE_TYPES64.TSNonNullExpression) current = current.expression;
16310
- return current?.type === AST_NODE_TYPES64.ThisExpression;
17163
+ while (current?.type === AST_NODE_TYPES71.TSAsExpression || current?.type === AST_NODE_TYPES71.TSSatisfiesExpression || current?.type === AST_NODE_TYPES71.TSNonNullExpression) current = current.expression;
17164
+ return current?.type === AST_NODE_TYPES71.ThisExpression;
16311
17165
  };
16312
17166
  const collectAlias = (current, nestedFunction) => {
16313
- if (nestedFunction || current.type !== AST_NODE_TYPES64.VariableDeclarator && current.type !== AST_NODE_TYPES64.AssignmentPattern) return;
16314
- if (current.type === AST_NODE_TYPES64.VariableDeclarator && (current.parent.type !== AST_NODE_TYPES64.VariableDeclaration || current.parent.kind !== "const")) return;
16315
- const binding = current.type === AST_NODE_TYPES64.VariableDeclarator ? current.id : current.left;
16316
- const value = current.type === AST_NODE_TYPES64.VariableDeclarator ? current.init : current.right;
17167
+ if (nestedFunction || current.type !== AST_NODE_TYPES71.VariableDeclarator && current.type !== AST_NODE_TYPES71.AssignmentPattern) return;
17168
+ if (current.type === AST_NODE_TYPES71.VariableDeclarator && (current.parent.type !== AST_NODE_TYPES71.VariableDeclaration || current.parent.kind !== "const")) return;
17169
+ const binding = current.type === AST_NODE_TYPES71.VariableDeclarator ? current.id : current.left;
17170
+ const value = current.type === AST_NODE_TYPES71.VariableDeclarator ? current.init : current.right;
16317
17171
  if (!thisValue(value)) return;
16318
- if (binding.type === AST_NODE_TYPES64.ObjectPattern) {
17172
+ if (binding.type === AST_NODE_TYPES71.ObjectPattern) {
16319
17173
  for (const property of binding.properties) {
16320
- if (property.type === AST_NODE_TYPES64.RestElement) {
17174
+ if (property.type === AST_NODE_TYPES71.RestElement) {
16321
17175
  for (const name of privateNames) pinned.add(name);
16322
- } else if (property.key.type === AST_NODE_TYPES64.Identifier && privateNames.has(property.key.name)) {
17176
+ } else if (property.key.type === AST_NODE_TYPES71.Identifier && privateNames.has(property.key.name)) {
16323
17177
  pinned.add(property.key.name);
16324
17178
  }
16325
17179
  }
16326
17180
  return;
16327
17181
  }
16328
- if (binding.type !== AST_NODE_TYPES64.Identifier) return;
16329
- const variable = ASTUtils22.findVariable(context.sourceCode.getScope(binding), binding.name);
17182
+ if (binding.type !== AST_NODE_TYPES71.Identifier) return;
17183
+ const variable = ASTUtils23.findVariable(context.sourceCode.getScope(binding), binding.name);
16330
17184
  if (variable !== null) {
16331
17185
  methodClassVariables.add(variable);
16332
17186
  methodAliases.add(variable);
@@ -16339,16 +17193,16 @@ function classScope(context, node, computedReferenceNames) {
16339
17193
  walk2(statement, context.sourceCode.visitorKeys, collectAlias);
16340
17194
  }
16341
17195
  const visitCall = (current, nestedFunction) => {
16342
- if (current.type === AST_NODE_TYPES64.VariableDeclarator && current.id.type === AST_NODE_TYPES64.ObjectPattern && thisValue(current.init)) {
17196
+ if (current.type === AST_NODE_TYPES71.VariableDeclarator && current.id.type === AST_NODE_TYPES71.ObjectPattern && thisValue(current.init)) {
16343
17197
  for (const property of current.id.properties) {
16344
- if (property.type === AST_NODE_TYPES64.RestElement) {
17198
+ if (property.type === AST_NODE_TYPES71.RestElement) {
16345
17199
  for (const name of privateNames) pinned.add(name);
16346
17200
  continue;
16347
17201
  }
16348
- if (property.type === AST_NODE_TYPES64.Property && property.key.type === AST_NODE_TYPES64.Identifier && privateNames.has(property.key.name)) pinned.add(property.key.name);
17202
+ if (property.type === AST_NODE_TYPES71.Property && property.key.type === AST_NODE_TYPES71.Identifier && privateNames.has(property.key.name)) pinned.add(property.key.name);
16349
17203
  }
16350
17204
  }
16351
- if (current.type !== AST_NODE_TYPES64.MemberExpression) return;
17205
+ if (current.type !== AST_NODE_TYPES71.MemberExpression) return;
16352
17206
  const target = referencedMethod(context, current, methodClassVariables);
16353
17207
  if (target === null) {
16354
17208
  const possibleTarget = referencedPropertyName(current);
@@ -16356,12 +17210,12 @@ function classScope(context, node, computedReferenceNames) {
16356
17210
  return;
16357
17211
  }
16358
17212
  if (!privateNames.has(target)) return;
16359
- const objectVariable = current.object.type === AST_NODE_TYPES64.Identifier ? ASTUtils22.findVariable(context.sourceCode.getScope(current.object), current.object.name) : null;
17213
+ const objectVariable = current.object.type === AST_NODE_TYPES71.Identifier ? ASTUtils23.findVariable(context.sourceCode.getScope(current.object), current.object.name) : null;
16360
17214
  if (objectVariable !== null && methodAliases.has(objectVariable)) {
16361
17215
  pinned.add(target);
16362
17216
  return;
16363
17217
  }
16364
- if (current.computed || nestedFunction || parameterDecoratorNodes.has(current) || current.parent.type !== AST_NODE_TYPES64.CallExpression || current.parent.callee !== current) {
17218
+ if (current.computed || nestedFunction || parameterDecoratorNodes.has(current) || current.parent.type !== AST_NODE_TYPES71.CallExpression || current.parent.callee !== current) {
16365
17219
  pinned.add(target);
16366
17220
  return;
16367
17221
  }
@@ -16381,9 +17235,9 @@ function classScope(context, node, computedReferenceNames) {
16381
17235
  }
16382
17236
  }
16383
17237
  for (const member of node.body.body) {
16384
- if (member.type === AST_NODE_TYPES64.MethodDefinition || member.type === AST_NODE_TYPES64.TSAbstractMethodDefinition) continue;
17238
+ if (member.type === AST_NODE_TYPES71.MethodDefinition || member.type === AST_NODE_TYPES71.TSAbstractMethodDefinition) continue;
16385
17239
  walk2(member, context.sourceCode.visitorKeys, (current) => {
16386
- if (current.type !== AST_NODE_TYPES64.MemberExpression) return;
17240
+ if (current.type !== AST_NODE_TYPES71.MemberExpression) return;
16387
17241
  const target = referencedMethod(context, current, classVariables);
16388
17242
  const possibleTarget = target ?? referencedPropertyName(current);
16389
17243
  if (possibleTarget !== null && privateNames.has(possibleTarget)) pinned.add(possibleTarget);
@@ -16435,12 +17289,12 @@ function classScope(context, node, computedReferenceNames) {
16435
17289
  }
16436
17290
  function isClassRuntimeBarrier(member) {
16437
17291
  switch (member.type) {
16438
- case AST_NODE_TYPES64.StaticBlock:
17292
+ case AST_NODE_TYPES71.StaticBlock:
16439
17293
  return true;
16440
- case AST_NODE_TYPES64.PropertyDefinition:
16441
- case AST_NODE_TYPES64.AccessorProperty:
17294
+ case AST_NODE_TYPES71.PropertyDefinition:
17295
+ case AST_NODE_TYPES71.AccessorProperty:
16442
17296
  return member.static || member.computed || member.decorators.length > 0 || member.value !== null;
16443
- case AST_NODE_TYPES64.MethodDefinition:
17297
+ case AST_NODE_TYPES71.MethodDefinition:
16444
17298
  return member.computed || member.decorators.length > 0;
16445
17299
  default:
16446
17300
  return false;
@@ -16473,7 +17327,7 @@ var stepdown_default = createRule({
16473
17327
  moduleScope(context, program);
16474
17328
  const computedReferenceNames = /* @__PURE__ */ new Set();
16475
17329
  walk2(program, context.sourceCode.visitorKeys, (node) => {
16476
- if (node.type === AST_NODE_TYPES64.MemberExpression && node.computed && node.property.type === AST_NODE_TYPES64.Literal && typeof node.property.value === "string") computedReferenceNames.add(node.property.value);
17330
+ if (node.type === AST_NODE_TYPES71.MemberExpression && node.computed && node.property.type === AST_NODE_TYPES71.Literal && typeof node.property.value === "string") computedReferenceNames.add(node.property.value);
16477
17331
  });
16478
17332
  for (const node of classes) classScope(context, node, computedReferenceNames);
16479
17333
  }
@@ -16482,7 +17336,7 @@ var stepdown_default = createRule({
16482
17336
  });
16483
17337
 
16484
17338
  // src/rules/source-coupled-test.ts
16485
- import { AST_NODE_TYPES as AST_NODE_TYPES65 } from "@typescript-eslint/utils";
17339
+ import { AST_NODE_TYPES as AST_NODE_TYPES72 } from "@typescript-eslint/utils";
16486
17340
  var GENERAL_SOURCE_SUFFIX_RE = /\.(?:bash|sh|ya?ml|jsonc|py|[cm]?[jt]s)$/iu;
16487
17341
  var FS_MODULES = /* @__PURE__ */ new Set(["fs", "node:fs", "fs/promises", "node:fs/promises"]);
16488
17342
  var FS_READERS = /* @__PURE__ */ new Set(["readFile", "readFileSync"]);
@@ -16551,28 +17405,28 @@ var SOURCE_COUPLED_TEST_DOCUMENTATION = {
16551
17405
  ]
16552
17406
  };
16553
17407
  function staticMemberName7(node) {
16554
- if (!node.computed && node.property.type === AST_NODE_TYPES65.Identifier) return node.property.name;
16555
- if (node.computed && node.property.type === AST_NODE_TYPES65.Literal && typeof node.property.value === "string") return node.property.value;
17408
+ if (!node.computed && node.property.type === AST_NODE_TYPES72.Identifier) return node.property.name;
17409
+ if (node.computed && node.property.type === AST_NODE_TYPES72.Literal && typeof node.property.value === "string") return node.property.value;
16556
17410
  return null;
16557
17411
  }
16558
- function unwrap5(node) {
16559
- if (node.type === AST_NODE_TYPES65.AwaitExpression) return unwrap5(node.argument);
16560
- if (node.type === AST_NODE_TYPES65.ChainExpression) return unwrap5(node.expression);
16561
- if (node.type === AST_NODE_TYPES65.TSAsExpression || node.type === AST_NODE_TYPES65.TSNonNullExpression || node.type === AST_NODE_TYPES65.TSTypeAssertion) return unwrap5(node.expression);
17412
+ function unwrap6(node) {
17413
+ if (node.type === AST_NODE_TYPES72.AwaitExpression) return unwrap6(node.argument);
17414
+ if (node.type === AST_NODE_TYPES72.ChainExpression) return unwrap6(node.expression);
17415
+ if (node.type === AST_NODE_TYPES72.TSAsExpression || node.type === AST_NODE_TYPES72.TSNonNullExpression || node.type === AST_NODE_TYPES72.TSTypeAssertion) return unwrap6(node.expression);
16562
17416
  return node;
16563
17417
  }
16564
17418
  function stringValue(node) {
16565
- const current = unwrap5(node);
16566
- if (current.type === AST_NODE_TYPES65.Literal && typeof current.value === "string") return current.value;
16567
- if (current.type === AST_NODE_TYPES65.TemplateLiteral && current.expressions.length === 0) return current.quasis[0]?.value.cooked ?? null;
17419
+ const current = unwrap6(node);
17420
+ if (current.type === AST_NODE_TYPES72.Literal && typeof current.value === "string") return current.value;
17421
+ if (current.type === AST_NODE_TYPES72.TemplateLiteral && current.expressions.length === 0) return current.quasis[0]?.value.cooked ?? null;
16568
17422
  return null;
16569
17423
  }
16570
17424
  function importSource(node) {
16571
17425
  return typeof node.source.value === "string" ? node.source.value : null;
16572
17426
  }
16573
17427
  function requireSource(node) {
16574
- const current = unwrap5(node);
16575
- if (current.type !== AST_NODE_TYPES65.CallExpression || current.callee.type !== AST_NODE_TYPES65.Identifier || current.callee.name !== "require" || current.arguments.length !== 1 || current.arguments[0]?.type === AST_NODE_TYPES65.SpreadElement) return null;
17428
+ const current = unwrap6(node);
17429
+ if (current.type !== AST_NODE_TYPES72.CallExpression || current.callee.type !== AST_NODE_TYPES72.Identifier || current.callee.name !== "require" || current.arguments.length !== 1 || current.arguments[0]?.type === AST_NODE_TYPES72.SpreadElement) return null;
16576
17430
  return stringValue(current.arguments[0]);
16577
17431
  }
16578
17432
  function newScope() {
@@ -16609,80 +17463,80 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
16609
17463
  return /* @__PURE__ */ new Set();
16610
17464
  };
16611
17465
  const sourcePath = (node) => {
16612
- const current = unwrap5(node);
17466
+ const current = unwrap6(node);
16613
17467
  const value = stringValue(current);
16614
17468
  if (value !== null) return sourceSuffixRe.test(value);
16615
- if (current.type === AST_NODE_TYPES65.Identifier) return visible("paths", current.name);
16616
- if (current.type === AST_NODE_TYPES65.BinaryExpression && current.operator === "+") {
17469
+ if (current.type === AST_NODE_TYPES72.Identifier) return visible("paths", current.name);
17470
+ if (current.type === AST_NODE_TYPES72.BinaryExpression && current.operator === "+") {
16617
17471
  return sourcePath(current.left) || sourcePath(current.right);
16618
17472
  }
16619
- if (current.type === AST_NODE_TYPES65.TemplateLiteral) return current.expressions.some(sourcePath);
16620
- if (current.type === AST_NODE_TYPES65.CallExpression || current.type === AST_NODE_TYPES65.NewExpression) {
16621
- return current.arguments.some((argument) => argument.type !== AST_NODE_TYPES65.SpreadElement && sourcePath(argument));
17473
+ if (current.type === AST_NODE_TYPES72.TemplateLiteral) return current.expressions.some(sourcePath);
17474
+ if (current.type === AST_NODE_TYPES72.CallExpression || current.type === AST_NODE_TYPES72.NewExpression) {
17475
+ return current.arguments.some((argument) => argument.type !== AST_NODE_TYPES72.SpreadElement && sourcePath(argument));
16622
17476
  }
16623
- if (current.type === AST_NODE_TYPES65.MemberExpression) return sourcePath(current.object);
17477
+ if (current.type === AST_NODE_TYPES72.MemberExpression) return sourcePath(current.object);
16624
17478
  return false;
16625
17479
  };
16626
17480
  const rawRead = (node) => {
16627
- const current = unwrap5(node);
16628
- if (current.type !== AST_NODE_TYPES65.CallExpression || current.arguments.length === 0) return false;
16629
- const callee = unwrap5(current.callee);
16630
- if (callee.type === AST_NODE_TYPES65.Identifier) {
17481
+ const current = unwrap6(node);
17482
+ if (current.type !== AST_NODE_TYPES72.CallExpression || current.arguments.length === 0) return false;
17483
+ const callee = unwrap6(current.callee);
17484
+ if (callee.type === AST_NODE_TYPES72.Identifier) {
16631
17485
  return visible("fsReaders", callee.name) && sourcePath(current.arguments[0]);
16632
17486
  }
16633
- if (callee.type !== AST_NODE_TYPES65.MemberExpression) return false;
17487
+ if (callee.type !== AST_NODE_TYPES72.MemberExpression) return false;
16634
17488
  const name2 = staticMemberName7(callee);
16635
- const object = unwrap5(callee.object);
16636
- return name2 !== null && FS_READERS.has(name2) && object.type === AST_NODE_TYPES65.Identifier && visible("fsObjects", object.name) && sourcePath(current.arguments[0]);
17489
+ const object = unwrap6(callee.object);
17490
+ return name2 !== null && FS_READERS.has(name2) && object.type === AST_NODE_TYPES72.Identifier && visible("fsObjects", object.name) && sourcePath(current.arguments[0]);
16637
17491
  };
16638
17492
  const rawOrigins = (node) => {
16639
- const current = unwrap5(node);
16640
- if (current.type === AST_NODE_TYPES65.Identifier) return visibleRawOrigins(current.name);
17493
+ const current = unwrap6(node);
17494
+ if (current.type === AST_NODE_TYPES72.Identifier) return visibleRawOrigins(current.name);
16641
17495
  if (rawRead(current)) return /* @__PURE__ */ new Set([`${current.range[0]}:${current.range[1]}`]);
16642
- if (current.type === AST_NODE_TYPES65.BinaryExpression && current.operator === "+") return /* @__PURE__ */ new Set([...rawOrigins(current.left), ...rawOrigins(current.right)]);
16643
- if (current.type === AST_NODE_TYPES65.MemberExpression && staticMemberName7(current) === "length") return rawOrigins(current.object);
16644
- if (current.type !== AST_NODE_TYPES65.CallExpression) return /* @__PURE__ */ new Set();
16645
- const callee = unwrap5(current.callee);
16646
- if (callee.type !== AST_NODE_TYPES65.MemberExpression) return /* @__PURE__ */ new Set();
17496
+ if (current.type === AST_NODE_TYPES72.BinaryExpression && current.operator === "+") return /* @__PURE__ */ new Set([...rawOrigins(current.left), ...rawOrigins(current.right)]);
17497
+ if (current.type === AST_NODE_TYPES72.MemberExpression && staticMemberName7(current) === "length") return rawOrigins(current.object);
17498
+ if (current.type !== AST_NODE_TYPES72.CallExpression) return /* @__PURE__ */ new Set();
17499
+ const callee = unwrap6(current.callee);
17500
+ if (callee.type !== AST_NODE_TYPES72.MemberExpression) return /* @__PURE__ */ new Set();
16647
17501
  const name2 = staticMemberName7(callee);
16648
17502
  return name2 !== null && TEXT_TRANSFORMS.has(name2) ? rawOrigins(callee.object) : /* @__PURE__ */ new Set();
16649
17503
  };
16650
17504
  const evidenceOrigins = (node) => {
16651
- const current = unwrap5(node);
17505
+ const current = unwrap6(node);
16652
17506
  const direct = rawOrigins(current);
16653
17507
  if (direct.size > 0) return direct;
16654
- if (current.type === AST_NODE_TYPES65.BinaryExpression || current.type === AST_NODE_TYPES65.LogicalExpression) return /* @__PURE__ */ new Set([...evidenceOrigins(current.left), ...evidenceOrigins(current.right)]);
16655
- if (current.type === AST_NODE_TYPES65.UnaryExpression) return evidenceOrigins(current.argument);
16656
- if (current.type !== AST_NODE_TYPES65.CallExpression) return /* @__PURE__ */ new Set();
16657
- const callee = unwrap5(current.callee);
16658
- if (callee.type !== AST_NODE_TYPES65.MemberExpression) return /* @__PURE__ */ new Set();
17508
+ if (current.type === AST_NODE_TYPES72.BinaryExpression || current.type === AST_NODE_TYPES72.LogicalExpression) return /* @__PURE__ */ new Set([...evidenceOrigins(current.left), ...evidenceOrigins(current.right)]);
17509
+ if (current.type === AST_NODE_TYPES72.UnaryExpression) return evidenceOrigins(current.argument);
17510
+ if (current.type !== AST_NODE_TYPES72.CallExpression) return /* @__PURE__ */ new Set();
17511
+ const callee = unwrap6(current.callee);
17512
+ if (callee.type !== AST_NODE_TYPES72.MemberExpression) return /* @__PURE__ */ new Set();
16659
17513
  const name2 = staticMemberName7(callee);
16660
17514
  if (name2 !== null && TEXT_PREDICATES.has(name2)) return rawOrigins(callee.object);
16661
- if (name2 !== null && REGEXP_PREDICATES.has(name2)) return new Set(current.arguments.flatMap((argument) => argument.type === AST_NODE_TYPES65.SpreadElement ? [] : [...rawOrigins(argument)]));
17515
+ if (name2 !== null && REGEXP_PREDICATES.has(name2)) return new Set(current.arguments.flatMap((argument) => argument.type === AST_NODE_TYPES72.SpreadElement ? [] : [...rawOrigins(argument)]));
16662
17516
  return /* @__PURE__ */ new Set();
16663
17517
  };
16664
17518
  const rawAssertionOrigins = (node) => {
16665
- const callee = unwrap5(node.callee);
16666
- if (callee.type === AST_NODE_TYPES65.Identifier && callee.name === "assert") {
16667
- return new Set(node.arguments.flatMap((argument) => argument.type === AST_NODE_TYPES65.SpreadElement ? [] : [...evidenceOrigins(argument)]));
17519
+ const callee = unwrap6(node.callee);
17520
+ if (callee.type === AST_NODE_TYPES72.Identifier && callee.name === "assert") {
17521
+ return new Set(node.arguments.flatMap((argument) => argument.type === AST_NODE_TYPES72.SpreadElement ? [] : [...evidenceOrigins(argument)]));
16668
17522
  }
16669
- if (callee.type !== AST_NODE_TYPES65.MemberExpression) return /* @__PURE__ */ new Set();
17523
+ if (callee.type !== AST_NODE_TYPES72.MemberExpression) return /* @__PURE__ */ new Set();
16670
17524
  const matcher = staticMemberName7(callee);
16671
17525
  if (matcher === null) return /* @__PURE__ */ new Set();
16672
- let receiver = unwrap5(callee.object);
16673
- while (receiver.type === AST_NODE_TYPES65.MemberExpression && EXPECT_MODIFIERS2.has(staticMemberName7(receiver) ?? "")) receiver = unwrap5(receiver.object);
16674
- if (receiver.type === AST_NODE_TYPES65.CallExpression && receiver.callee.type === AST_NODE_TYPES65.Identifier && receiver.callee.name === "expect") {
17526
+ let receiver = unwrap6(callee.object);
17527
+ while (receiver.type === AST_NODE_TYPES72.MemberExpression && EXPECT_MODIFIERS2.has(staticMemberName7(receiver) ?? "")) receiver = unwrap6(receiver.object);
17528
+ if (receiver.type === AST_NODE_TYPES72.CallExpression && receiver.callee.type === AST_NODE_TYPES72.Identifier && receiver.callee.name === "expect") {
16675
17529
  if (!EXPECT_MATCHERS.has(matcher)) return /* @__PURE__ */ new Set();
16676
- return new Set([...receiver.arguments, ...node.arguments].flatMap((argument) => argument.type === AST_NODE_TYPES65.SpreadElement ? [] : [...evidenceOrigins(argument)]));
17530
+ return new Set([...receiver.arguments, ...node.arguments].flatMap((argument) => argument.type === AST_NODE_TYPES72.SpreadElement ? [] : [...evidenceOrigins(argument)]));
16677
17531
  }
16678
- if (receiver.type !== AST_NODE_TYPES65.Identifier || receiver.name !== "assert" || !ASSERT_MATCHERS.has(matcher)) return /* @__PURE__ */ new Set();
16679
- return new Set(node.arguments.flatMap((argument) => argument.type === AST_NODE_TYPES65.SpreadElement ? [] : [...evidenceOrigins(argument)]));
17532
+ if (receiver.type !== AST_NODE_TYPES72.Identifier || receiver.name !== "assert" || !ASSERT_MATCHERS.has(matcher)) return /* @__PURE__ */ new Set();
17533
+ return new Set(node.arguments.flatMap((argument) => argument.type === AST_NODE_TYPES72.SpreadElement ? [] : [...evidenceOrigins(argument)]));
16680
17534
  };
16681
17535
  const rawRegexExtractionOrigins = (node) => {
16682
- const callee = unwrap5(node.callee);
16683
- if (callee.type !== AST_NODE_TYPES65.MemberExpression || staticMemberName7(callee) !== "matchAll" || node.arguments.length !== 1) return /* @__PURE__ */ new Set();
17536
+ const callee = unwrap6(node.callee);
17537
+ if (callee.type !== AST_NODE_TYPES72.MemberExpression || staticMemberName7(callee) !== "matchAll" || node.arguments.length !== 1) return /* @__PURE__ */ new Set();
16684
17538
  const argument = node.arguments[0];
16685
- if (argument?.type !== AST_NODE_TYPES65.Literal || !(argument.value instanceof RegExp)) return /* @__PURE__ */ new Set();
17539
+ if (argument?.type !== AST_NODE_TYPES72.Literal || !(argument.value instanceof RegExp)) return /* @__PURE__ */ new Set();
16686
17540
  return rawOrigins(callee.object);
16687
17541
  };
16688
17542
  const declare = (name2, state) => {
@@ -16702,16 +17556,16 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
16702
17556
  }
16703
17557
  };
16704
17558
  const sourceCollection = (node) => {
16705
- const current = unwrap5(node);
16706
- return current.type === AST_NODE_TYPES65.ArrayExpression && current.elements.length > 0 && current.elements.every((element) => element !== null && element.type !== AST_NODE_TYPES65.SpreadElement && sourcePath(element));
17559
+ const current = unwrap6(node);
17560
+ return current.type === AST_NODE_TYPES72.ArrayExpression && current.elements.length > 0 && current.elements.every((element) => element !== null && element.type !== AST_NODE_TYPES72.SpreadElement && sourcePath(element));
16707
17561
  };
16708
17562
  const declaredNames2 = (node) => {
16709
- const current = unwrap5(node);
16710
- if (current.type === AST_NODE_TYPES65.Identifier) return [current.name];
16711
- if (current.type === AST_NODE_TYPES65.AssignmentPattern) return declaredNames2(current.left);
16712
- if (current.type === AST_NODE_TYPES65.RestElement) return declaredNames2(current.argument);
16713
- if (current.type === AST_NODE_TYPES65.ArrayPattern) return current.elements.flatMap((element) => element === null ? [] : declaredNames2(element));
16714
- if (current.type === AST_NODE_TYPES65.ObjectPattern) return current.properties.flatMap((property) => property.type === AST_NODE_TYPES65.RestElement ? declaredNames2(property.argument) : declaredNames2(property.value));
17563
+ const current = unwrap6(node);
17564
+ if (current.type === AST_NODE_TYPES72.Identifier) return [current.name];
17565
+ if (current.type === AST_NODE_TYPES72.AssignmentPattern) return declaredNames2(current.left);
17566
+ if (current.type === AST_NODE_TYPES72.RestElement) return declaredNames2(current.argument);
17567
+ if (current.type === AST_NODE_TYPES72.ArrayPattern) return current.elements.flatMap((element) => element === null ? [] : declaredNames2(element));
17568
+ if (current.type === AST_NODE_TYPES72.ObjectPattern) return current.properties.flatMap((property) => property.type === AST_NODE_TYPES72.RestElement ? declaredNames2(property.argument) : declaredNames2(property.value));
16715
17569
  return [];
16716
17570
  };
16717
17571
  const enterFunction = (node) => {
@@ -16726,8 +17580,8 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
16726
17580
  const source = importSource(node);
16727
17581
  if (source === null || !FS_MODULES.has(source)) return;
16728
17582
  for (const specifier of node.specifiers) {
16729
- if (specifier.type === AST_NODE_TYPES65.ImportSpecifier) {
16730
- const imported = specifier.imported.type === AST_NODE_TYPES65.Identifier ? specifier.imported.name : String(specifier.imported.value);
17583
+ if (specifier.type === AST_NODE_TYPES72.ImportSpecifier) {
17584
+ const imported = specifier.imported.type === AST_NODE_TYPES72.Identifier ? specifier.imported.name : String(specifier.imported.value);
16731
17585
  if (FS_READERS.has(imported)) declare(specifier.local.name, { fsReader: true });
16732
17586
  } else {
16733
17587
  declare(specifier.local.name, { fsObject: true });
@@ -16739,29 +17593,29 @@ function createSourceCoupledRule(name, documentation, sourceSuffixRe) {
16739
17593
  VariableDeclarator(node) {
16740
17594
  if (node.init === null) return;
16741
17595
  const required = requireSource(node.init);
16742
- if (required !== null && FS_MODULES.has(required) && node.id.type === AST_NODE_TYPES65.Identifier) {
17596
+ if (required !== null && FS_MODULES.has(required) && node.id.type === AST_NODE_TYPES72.Identifier) {
16743
17597
  declare(node.id.name, { fsObject: true });
16744
17598
  return;
16745
17599
  }
16746
- if (node.id.type === AST_NODE_TYPES65.ObjectPattern && required !== null && FS_MODULES.has(required)) {
17600
+ if (node.id.type === AST_NODE_TYPES72.ObjectPattern && required !== null && FS_MODULES.has(required)) {
16747
17601
  for (const property of node.id.properties) {
16748
- if (property.type !== AST_NODE_TYPES65.Property || property.value.type !== AST_NODE_TYPES65.Identifier) continue;
16749
- const key = property.key.type === AST_NODE_TYPES65.Identifier ? property.key.name : property.key.type === AST_NODE_TYPES65.Literal ? String(property.key.value) : "";
17602
+ if (property.type !== AST_NODE_TYPES72.Property || property.value.type !== AST_NODE_TYPES72.Identifier) continue;
17603
+ const key = property.key.type === AST_NODE_TYPES72.Identifier ? property.key.name : property.key.type === AST_NODE_TYPES72.Literal ? String(property.key.value) : "";
16750
17604
  if (FS_READERS.has(key)) declare(property.value.name, { fsReader: true });
16751
17605
  }
16752
17606
  return;
16753
17607
  }
16754
- if (node.id.type !== AST_NODE_TYPES65.Identifier) return;
17608
+ if (node.id.type !== AST_NODE_TYPES72.Identifier) return;
16755
17609
  declare(node.id.name, { collection: sourceCollection(node.init), path: sourcePath(node.init), rawOrigins: rawOrigins(node.init) });
16756
17610
  },
16757
17611
  AssignmentExpression(node) {
16758
- if (node.left.type === AST_NODE_TYPES65.Identifier) declare(node.left.name, { path: sourcePath(node.right), rawOrigins: rawOrigins(node.right) });
17612
+ if (node.left.type === AST_NODE_TYPES72.Identifier) declare(node.left.name, { path: sourcePath(node.right), rawOrigins: rawOrigins(node.right) });
16759
17613
  },
16760
17614
  ForOfStatement(node) {
16761
- const right = unwrap5(node.right);
16762
- const collection = right.type === AST_NODE_TYPES65.Identifier && visible("collections", right.name);
16763
- const left = node.left.type === AST_NODE_TYPES65.VariableDeclaration ? node.left.declarations[0]?.id : node.left;
16764
- if (collection && left?.type === AST_NODE_TYPES65.Identifier) declare(left.name, { path: true });
17615
+ const right = unwrap6(node.right);
17616
+ const collection = right.type === AST_NODE_TYPES72.Identifier && visible("collections", right.name);
17617
+ const left = node.left.type === AST_NODE_TYPES72.VariableDeclaration ? node.left.declarations[0]?.id : node.left;
17618
+ if (collection && left?.type === AST_NODE_TYPES72.Identifier) declare(left.name, { path: true });
16765
17619
  },
16766
17620
  CallExpression(node) {
16767
17621
  const origins = /* @__PURE__ */ new Set([
@@ -16782,6 +17636,120 @@ var source_coupled_test_default = createSourceCoupledRule(
16782
17636
  GENERAL_SOURCE_SUFFIX_RE
16783
17637
  );
16784
17638
 
17639
+ // src/rules/sole-export-matches-filename.ts
17640
+ import { AST_NODE_TYPES as AST_NODE_TYPES73 } from "@typescript-eslint/utils";
17641
+ var SOLE_EXPORT_MATCHES_FILENAME_DOCUMENTATION = {
17642
+ summary: "Match a module filename to its sole named public runtime export.",
17643
+ rationale: "When a module owns one runtime responsibility, matching names make that responsibility directly discoverable.",
17644
+ remediation: "Rename the module stem to the kebab-case export name, or colocate genuinely related exports.",
17645
+ category: "maintainability",
17646
+ limitations: [
17647
+ "Framework entrypoints, generic stems covered by no-generic-single-export-module, tests, generated files, anonymous defaults, CommonJS, and re-exports are excluded.",
17648
+ "The rule compares the primary filename stem and preserves conventional suffixes such as .server or .worker."
17649
+ ],
17650
+ examples: [
17651
+ { id: "matching-class", title: "Match a class and module", outcome: "no-match", files: [{ path: "src/artifact-store.ts", source: "export class ArtifactStore {}" }], focusPath: "src/artifact-store.ts", expectedCount: 0, public: true },
17652
+ { id: "mismatched-class", title: "Do not hide a sole class behind another filename", outcome: "match", files: [{ path: "src/artifacts.ts", source: "export class ArtifactStore {}" }], focusPath: "src/artifacts.ts", expectedCount: 1, public: true }
17653
+ ]
17654
+ };
17655
+ var EXCLUDED_STEMS = /* @__PURE__ */ new Set([
17656
+ "common",
17657
+ "global",
17658
+ "helpers",
17659
+ "index",
17660
+ "layout",
17661
+ "loading",
17662
+ "middleware",
17663
+ "misc",
17664
+ "not-found",
17665
+ "page",
17666
+ "route",
17667
+ "shared",
17668
+ "template",
17669
+ "types",
17670
+ "util",
17671
+ "utils"
17672
+ ]);
17673
+ function stem3(filename) {
17674
+ const base = filename.replaceAll("\\", "/").split("/").at(-1) ?? "";
17675
+ return base.replace(/\.[cm]?[jt]sx?$/u, "").split(".")[0] ?? "";
17676
+ }
17677
+ function kebabCase(name) {
17678
+ return name.replace(/([A-Z]{2,})([A-Z][a-z])/gu, "$1-$2").replace(/([a-z0-9])([A-Z])/gu, "$1-$2").replaceAll(/[^a-z0-9]+/giu, "-").replaceAll(/^-+|-+$/gu, "").toLowerCase();
17679
+ }
17680
+ function declarationExport(statement) {
17681
+ const declaration = statement.declaration;
17682
+ if (declaration === null || declaration.declare === true) return [];
17683
+ if (declaration.type === AST_NODE_TYPES73.ClassDeclaration || declaration.type === AST_NODE_TYPES73.FunctionDeclaration || declaration.type === AST_NODE_TYPES73.TSEnumDeclaration) return declaration.id === null ? [] : [{ name: declaration.id.name, node: declaration }];
17684
+ if (declaration.type !== AST_NODE_TYPES73.VariableDeclaration) return [];
17685
+ return declaration.declarations.flatMap(
17686
+ (item) => item.id.type === AST_NODE_TYPES73.Identifier ? [{ name: item.id.name, node: item }] : []
17687
+ );
17688
+ }
17689
+ var sole_export_matches_filename_default = createRule({
17690
+ name: "sole-export-matches-filename",
17691
+ documentation: SOLE_EXPORT_MATCHES_FILENAME_DOCUMENTATION,
17692
+ meta: {
17693
+ type: "suggestion",
17694
+ docs: { description: "Match a module filename to its sole named public runtime export." },
17695
+ schema: [],
17696
+ messages: {
17697
+ matchSoleExport: "This module's sole runtime export is `{{exported}}`; rename the file stem to `{{expected}}`."
17698
+ }
17699
+ },
17700
+ defaultOptions: [],
17701
+ create(context) {
17702
+ const fileStem = stem3(context.filename);
17703
+ const normalizedFilename = context.filename.replaceAll("\\", "/");
17704
+ if (EXCLUDED_STEMS.has(fileStem) || normalizedFilename.includes("/pages/") || context.filename.endsWith(".d.ts") || isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
17705
+ return {
17706
+ "Program:exit"(program) {
17707
+ const exports = [];
17708
+ const publicExports = /* @__PURE__ */ new Set();
17709
+ for (const statement of program.body) {
17710
+ if (statement.type === AST_NODE_TYPES73.ExportAllDeclaration || statement.type === AST_NODE_TYPES73.ExportNamedDeclaration && statement.source !== null) return;
17711
+ if (statement.type === AST_NODE_TYPES73.ExportDefaultDeclaration) {
17712
+ publicExports.add("default");
17713
+ const declaration2 = statement.declaration;
17714
+ if ((declaration2.type === AST_NODE_TYPES73.ClassDeclaration || declaration2.type === AST_NODE_TYPES73.FunctionDeclaration) && declaration2.id !== null) exports.push({ name: declaration2.id.name, node: declaration2 });
17715
+ else return;
17716
+ }
17717
+ if (statement.type !== AST_NODE_TYPES73.ExportNamedDeclaration) continue;
17718
+ const declaration = statement.declaration;
17719
+ if (declaration !== null && "id" in declaration && declaration.id?.type === AST_NODE_TYPES73.Identifier) {
17720
+ publicExports.add(declaration.id.name);
17721
+ }
17722
+ if (declaration?.type === AST_NODE_TYPES73.VariableDeclaration) {
17723
+ for (const item of declaration.declarations) {
17724
+ if (item.id.type === AST_NODE_TYPES73.Identifier) publicExports.add(item.id.name);
17725
+ }
17726
+ }
17727
+ for (const specifier of statement.specifiers) {
17728
+ const exported = specifier.exported.type === AST_NODE_TYPES73.Identifier ? specifier.exported.name : specifier.exported.value;
17729
+ publicExports.add(String(exported));
17730
+ }
17731
+ if (statement.exportKind === "type") continue;
17732
+ exports.push(...declarationExport(statement));
17733
+ for (const specifier of statement.specifiers) {
17734
+ const exported = specifier.exported.type === AST_NODE_TYPES73.Identifier ? specifier.exported.name : specifier.exported.value;
17735
+ publicExports.add(String(exported));
17736
+ if (specifier.exportKind === "type") continue;
17737
+ if (exported === "default") exports.push({ name: specifier.local.name, node: specifier });
17738
+ else exports.push({ name: String(exported), node: specifier });
17739
+ }
17740
+ }
17741
+ const unique = new Map(exports.map((item) => [item.name, item]));
17742
+ if (unique.size !== 1 || publicExports.size !== 1) return;
17743
+ const only = [...unique.values()][0];
17744
+ if (only === void 0) return;
17745
+ const expected = kebabCase(only.name);
17746
+ if (expected === "" || expected === fileStem.toLowerCase()) return;
17747
+ context.report({ node: only.node, messageId: "matchSoleExport", data: { exported: only.name, expected } });
17748
+ }
17749
+ };
17750
+ }
17751
+ });
17752
+
16785
17753
  // src/rules/iac-source-coupled-test.ts
16786
17754
  var IAC_SOURCE_SUFFIX_RE = /(?:\.tf\.json|\.tftest\.(?:hcl|json)|\.(?:hcl|tf|tfvars))$/iu;
16787
17755
  var IAC_SOURCE_COUPLED_TEST_DOCUMENTATION = {
@@ -16822,8 +17790,8 @@ var iac_source_coupled_test_default = createSourceCoupledRule(
16822
17790
 
16823
17791
  // src/rules/require-pascal-case-zod-schema-name.ts
16824
17792
  import {
16825
- AST_NODE_TYPES as AST_NODE_TYPES66,
16826
- ASTUtils as ASTUtils23
17793
+ AST_NODE_TYPES as AST_NODE_TYPES74,
17794
+ ASTUtils as ASTUtils24
16827
17795
  } from "@typescript-eslint/utils";
16828
17796
  var REQUIRE_PASCAL_CASE_ZOD_SCHEMA_NAME_DOCUMENTATION = {
16829
17797
  summary: "Require confirmed module-level Zod schema contracts to use PascalCase with a `Schema` suffix.",
@@ -16956,18 +17924,18 @@ var SCHEMA_RETURNING_METHODS = /* @__PURE__ */ new Set([
16956
17924
  "superRefine",
16957
17925
  "transform"
16958
17926
  ]);
16959
- var terminalMethodName = (callee) => !callee.computed && callee.property.type === AST_NODE_TYPES66.Identifier ? callee.property.name : null;
17927
+ var terminalMethodName = (callee) => !callee.computed && callee.property.type === AST_NODE_TYPES74.Identifier ? callee.property.name : null;
16960
17928
  var calleeChainRoot = (node) => {
16961
17929
  let current = node;
16962
17930
  for (; ; ) {
16963
- if (current.type === AST_NODE_TYPES66.Identifier) {
17931
+ if (current.type === AST_NODE_TYPES74.Identifier) {
16964
17932
  return current;
16965
17933
  }
16966
- if (current.type === AST_NODE_TYPES66.MemberExpression) {
17934
+ if (current.type === AST_NODE_TYPES74.MemberExpression) {
16967
17935
  current = current.object;
16968
17936
  continue;
16969
17937
  }
16970
- if (current.type === AST_NODE_TYPES66.CallExpression) {
17938
+ if (current.type === AST_NODE_TYPES74.CallExpression) {
16971
17939
  current = current.callee;
16972
17940
  continue;
16973
17941
  }
@@ -16978,13 +17946,13 @@ var chainMemberNames = (node) => {
16978
17946
  const names = [];
16979
17947
  let current = node;
16980
17948
  for (; ; ) {
16981
- if (current.type === AST_NODE_TYPES66.MemberExpression) {
16982
- if (current.computed || current.property.type !== AST_NODE_TYPES66.Identifier) return [];
17949
+ if (current.type === AST_NODE_TYPES74.MemberExpression) {
17950
+ if (current.computed || current.property.type !== AST_NODE_TYPES74.Identifier) return [];
16983
17951
  names.push(current.property.name);
16984
17952
  current = current.object;
16985
17953
  continue;
16986
17954
  }
16987
- if (current.type === AST_NODE_TYPES66.CallExpression) {
17955
+ if (current.type === AST_NODE_TYPES74.CallExpression) {
16988
17956
  current = current.callee;
16989
17957
  continue;
16990
17958
  }
@@ -16995,16 +17963,16 @@ var chainMemberNames = (node) => {
16995
17963
  };
16996
17964
  var unwrapExpression4 = (node) => {
16997
17965
  let current = node;
16998
- while (current.type === AST_NODE_TYPES66.TSAsExpression || current.type === AST_NODE_TYPES66.TSSatisfiesExpression || current.type === AST_NODE_TYPES66.TSNonNullExpression || current.type === AST_NODE_TYPES66.TSTypeAssertion) {
17966
+ while (current.type === AST_NODE_TYPES74.TSAsExpression || current.type === AST_NODE_TYPES74.TSSatisfiesExpression || current.type === AST_NODE_TYPES74.TSNonNullExpression || current.type === AST_NODE_TYPES74.TSTypeAssertion) {
16999
17967
  current = current.expression;
17000
17968
  }
17001
17969
  return current;
17002
17970
  };
17003
17971
  var isModuleDeclarator = (node) => {
17004
17972
  const declaration = node.parent;
17005
- if (declaration.type !== AST_NODE_TYPES66.VariableDeclaration) return false;
17973
+ if (declaration.type !== AST_NODE_TYPES74.VariableDeclaration) return false;
17006
17974
  const owner = declaration.parent;
17007
- return owner.type === AST_NODE_TYPES66.Program || owner.type === AST_NODE_TYPES66.ExportNamedDeclaration && owner.parent.type === AST_NODE_TYPES66.Program;
17975
+ return owner.type === AST_NODE_TYPES74.Program || owner.type === AST_NODE_TYPES74.ExportNamedDeclaration && owner.parent.type === AST_NODE_TYPES74.Program;
17008
17976
  };
17009
17977
  var require_pascal_case_zod_schema_name_default = createRule({
17010
17978
  name: "require-pascal-case-zod-schema-name",
@@ -17024,7 +17992,7 @@ var require_pascal_case_zod_schema_name_default = createRule({
17024
17992
  const zodBindings = /* @__PURE__ */ new Set();
17025
17993
  const schemaBindings = /* @__PURE__ */ new Set();
17026
17994
  function resolvedBinding(identifier) {
17027
- return ASTUtils23.findVariable(
17995
+ return ASTUtils24.findVariable(
17028
17996
  context.sourceCode.getScope(identifier),
17029
17997
  identifier.name
17030
17998
  );
@@ -17045,8 +18013,8 @@ var require_pascal_case_zod_schema_name_default = createRule({
17045
18013
  }
17046
18014
  function isConfirmedSchema(expression) {
17047
18015
  const init = unwrapExpression4(expression);
17048
- if (init.type === AST_NODE_TYPES66.Identifier) return isSchemaBinding(init);
17049
- if (init.type !== AST_NODE_TYPES66.CallExpression || init.callee.type !== AST_NODE_TYPES66.MemberExpression) {
18016
+ if (init.type === AST_NODE_TYPES74.Identifier) return isSchemaBinding(init);
18017
+ if (init.type !== AST_NODE_TYPES74.CallExpression || init.callee.type !== AST_NODE_TYPES74.MemberExpression) {
17050
18018
  return false;
17051
18019
  }
17052
18020
  const terminal = terminalMethodName(init.callee);
@@ -17066,7 +18034,7 @@ var require_pascal_case_zod_schema_name_default = createRule({
17066
18034
  ImportDeclaration(node) {
17067
18035
  if (!isZodModule(node.source.value)) return;
17068
18036
  for (const specifier of node.specifiers) {
17069
- if (specifier.type === AST_NODE_TYPES66.ImportNamespaceSpecifier || specifier.type === AST_NODE_TYPES66.ImportDefaultSpecifier || specifier.type === AST_NODE_TYPES66.ImportSpecifier && (specifier.imported.type === AST_NODE_TYPES66.Identifier ? specifier.imported.name === "z" : specifier.imported.value === "z")) {
18037
+ if (specifier.type === AST_NODE_TYPES74.ImportNamespaceSpecifier || specifier.type === AST_NODE_TYPES74.ImportDefaultSpecifier || specifier.type === AST_NODE_TYPES74.ImportSpecifier && (specifier.imported.type === AST_NODE_TYPES74.Identifier ? specifier.imported.name === "z" : specifier.imported.value === "z")) {
17070
18038
  recordZodBinding(specifier.local);
17071
18039
  }
17072
18040
  }
@@ -17075,7 +18043,7 @@ var require_pascal_case_zod_schema_name_default = createRule({
17075
18043
  if (!isModuleDeclarator(node)) return;
17076
18044
  const init = node.init;
17077
18045
  if (init === null || init === void 0) return;
17078
- if (node.id.type !== AST_NODE_TYPES66.Identifier) return;
18046
+ if (node.id.type !== AST_NODE_TYPES74.Identifier) return;
17079
18047
  if (!isConfirmedSchema(init)) return;
17080
18048
  const binding = resolvedBinding(node.id);
17081
18049
  if (binding !== null) schemaBindings.add(binding);
@@ -17233,11 +18201,16 @@ var RULES = {
17233
18201
  "prefer-shadcn-primitives": prefer_shadcn_primitives_default,
17234
18202
  "prefer-module-level-constant": prefer_module_level_constant_default,
17235
18203
  "prefer-module-level-schema": prefer_module_level_schema_default,
18204
+ "prefer-named-complex-return-type": prefer_named_complex_return_type_default,
17236
18205
  "prefer-native-random-uuid": prefer_native_random_uuid_default,
18206
+ "prefer-node-crypto-hash": prefer_node_crypto_hash_default,
18207
+ "prefer-node-fs-promises": prefer_node_fs_promises_default,
17237
18208
  "prefer-non-nullable-collection": prefer_non_nullable_collection_default,
17238
18209
  "prefer-nullish-filter-predicate": prefer_nullish_filter_predicate_default,
17239
18210
  "prefer-await-in-async-return": prefer_await_in_async_return_default,
17240
18211
  "prefer-schema-for-api-payload": prefer_schema_for_api_payload_default,
18212
+ "prefer-shared-zod-enum": prefer_shared_zod_enum_default,
18213
+ "prefer-switch-for-repeated-equality": prefer_switch_for_repeated_equality_default,
17241
18214
  "prefer-semantic-colors": prefer_semantic_colors_default,
17242
18215
  "prefer-server-actions": prefer_server_actions_default,
17243
18216
  "prefer-whole-object-assertion": prefer_whole_object_assertion_default,
@@ -17245,24 +18218,37 @@ var RULES = {
17245
18218
  "prefer-zod-infer": prefer_zod_infer_default,
17246
18219
  "require-assert-never": require_assert_never_default,
17247
18220
  "require-fetch-timeout": require_fetch_timeout_default,
18221
+ "require-interface-for-exported-class": require_interface_for_exported_class_default,
17248
18222
  "require-port-for-service": require_port_for_service_default,
18223
+ "require-sql-access-class": require_sql_access_class_default,
17249
18224
  "require-static-next-matcher": require_static_next_matcher_default,
17250
18225
  "require-zod-form-validation": require_zod_form_validation_default,
17251
18226
  "store-insert-requires-on-conflict": store_insert_requires_on_conflict_default,
17252
18227
  "stepdown": stepdown_default,
17253
18228
  "source-coupled-test": source_coupled_test_default,
18229
+ "sole-export-matches-filename": sole_export_matches_filename_default,
17254
18230
  "require-pascal-case-zod-schema-name": require_pascal_case_zod_schema_name_default
17255
18231
  };
17256
18232
  var meta = {
17257
18233
  name: "@sarj/eslint-plugin",
17258
- version: "15.14.0"
18234
+ version: "15.16.0"
17259
18235
  };
17260
18236
  var APPLICATION_ONLY_RULES = [
17261
18237
  "no-restricted-library-load",
17262
18238
  "prefer-native-random-uuid",
17263
18239
  "prefer-shadcn-primitives"
17264
18240
  ];
17265
- var ADVISORY_RULES = ["@sarj/require-pascal-case-zod-schema-name"];
18241
+ var ADVISORY_RULES = [
18242
+ "@sarj/prefer-named-complex-return-type",
18243
+ "@sarj/prefer-node-crypto-hash",
18244
+ "@sarj/prefer-node-fs-promises",
18245
+ "@sarj/prefer-shared-zod-enum",
18246
+ "@sarj/prefer-switch-for-repeated-equality",
18247
+ "@sarj/require-interface-for-exported-class",
18248
+ "@sarj/require-pascal-case-zod-schema-name",
18249
+ "@sarj/require-sql-access-class",
18250
+ "@sarj/sole-export-matches-filename"
18251
+ ];
17266
18252
  var RECOMMENDED_RULES = {
17267
18253
  "@sarj/interface-contract-members-private": "error",
17268
18254
  "@sarj/iac-source-coupled-test": "error",
@@ -17316,10 +18302,15 @@ var RECOMMENDED_RULES = {
17316
18302
  "@sarj/prefer-immutable-module-constant": "error",
17317
18303
  "@sarj/prefer-module-level-constant": "error",
17318
18304
  "@sarj/prefer-module-level-schema": "error",
18305
+ "@sarj/prefer-named-complex-return-type": "warn",
18306
+ "@sarj/prefer-node-crypto-hash": "warn",
18307
+ "@sarj/prefer-node-fs-promises": "warn",
17319
18308
  "@sarj/prefer-non-nullable-collection": "error",
17320
18309
  "@sarj/prefer-nullish-filter-predicate": "error",
17321
18310
  "@sarj/prefer-await-in-async-return": "error",
17322
18311
  "@sarj/prefer-schema-for-api-payload": "error",
18312
+ "@sarj/prefer-shared-zod-enum": "warn",
18313
+ "@sarj/prefer-switch-for-repeated-equality": "warn",
17323
18314
  "@sarj/prefer-semantic-colors": ["error", { requireSemanticTokens: true }],
17324
18315
  "@sarj/prefer-server-actions": "error",
17325
18316
  "@sarj/prefer-whole-object-assertion": "error",
@@ -17327,7 +18318,9 @@ var RECOMMENDED_RULES = {
17327
18318
  "@sarj/prefer-zod-infer": "error",
17328
18319
  "@sarj/require-assert-never": "error",
17329
18320
  "@sarj/require-fetch-timeout": "error",
18321
+ "@sarj/require-interface-for-exported-class": "warn",
17330
18322
  "@sarj/require-port-for-service": "error",
18323
+ "@sarj/require-sql-access-class": "warn",
17331
18324
  "@sarj/require-static-next-matcher": "error",
17332
18325
  "@sarj/require-use-form-default-values": "error",
17333
18326
  "@sarj/require-use-server-in-actions-file": "error",
@@ -17335,6 +18328,7 @@ var RECOMMENDED_RULES = {
17335
18328
  "@sarj/store-insert-requires-on-conflict": "error",
17336
18329
  "@sarj/stepdown": "error",
17337
18330
  "@sarj/source-coupled-test": "error",
18331
+ "@sarj/sole-export-matches-filename": "warn",
17338
18332
  "@sarj/test-phase-label-comment": "error",
17339
18333
  "@sarj/require-pascal-case-zod-schema-name": "warn"
17340
18334
  };
@@ -17395,10 +18389,15 @@ var STRICT_RULES = {
17395
18389
  "@sarj/prefer-immutable-module-constant": "error",
17396
18390
  "@sarj/prefer-module-level-constant": "error",
17397
18391
  "@sarj/prefer-module-level-schema": "error",
18392
+ "@sarj/prefer-named-complex-return-type": "warn",
18393
+ "@sarj/prefer-node-crypto-hash": "warn",
18394
+ "@sarj/prefer-node-fs-promises": "warn",
17398
18395
  "@sarj/prefer-non-nullable-collection": "error",
17399
18396
  "@sarj/prefer-nullish-filter-predicate": "error",
17400
18397
  "@sarj/prefer-await-in-async-return": "error",
17401
18398
  "@sarj/prefer-schema-for-api-payload": "error",
18399
+ "@sarj/prefer-shared-zod-enum": "warn",
18400
+ "@sarj/prefer-switch-for-repeated-equality": "warn",
17402
18401
  "@sarj/prefer-semantic-colors": ["error", { requireSemanticTokens: true }],
17403
18402
  "@sarj/prefer-server-actions": "error",
17404
18403
  "@sarj/prefer-whole-object-assertion": "error",
@@ -17406,7 +18405,9 @@ var STRICT_RULES = {
17406
18405
  "@sarj/prefer-zod-infer": "error",
17407
18406
  "@sarj/require-assert-never": "error",
17408
18407
  "@sarj/require-fetch-timeout": "error",
18408
+ "@sarj/require-interface-for-exported-class": "warn",
17409
18409
  "@sarj/require-port-for-service": "error",
18410
+ "@sarj/require-sql-access-class": "warn",
17410
18411
  "@sarj/require-static-next-matcher": "error",
17411
18412
  "@sarj/require-use-form-default-values": "error",
17412
18413
  "@sarj/require-use-server-in-actions-file": "error",
@@ -17414,6 +18415,7 @@ var STRICT_RULES = {
17414
18415
  "@sarj/store-insert-requires-on-conflict": "error",
17415
18416
  "@sarj/stepdown": "error",
17416
18417
  "@sarj/source-coupled-test": "error",
18418
+ "@sarj/sole-export-matches-filename": "warn",
17417
18419
  "@sarj/test-phase-label-comment": "error",
17418
18420
  "@sarj/require-pascal-case-zod-schema-name": "warn"
17419
18421
  };