@sarj/eslint-plugin 15.28.0 → 16.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -28,8 +28,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
 
30
30
  // src/index.ts
31
- var index_exports = {};
32
- __export(index_exports, {
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
33
  ADVISORY_RULES: () => ADVISORY_RULES,
34
34
  APPLICATION_ONLY_RULES: () => APPLICATION_ONLY_RULES,
35
35
  RECOMMENDED_RULES: () => RECOMMENDED_RULES,
@@ -39,7 +39,7 @@ __export(index_exports, {
39
39
  STRICT_RULES: () => STRICT_RULES,
40
40
  advisoryRules: () => ADVISORY_RULES,
41
41
  applicationOnlyRules: () => APPLICATION_ONLY_RULES,
42
- default: () => index_default,
42
+ default: () => src_default,
43
43
  publicDocumentation: () => publicDocumentation,
44
44
  recommendedRules: () => RECOMMENDED_RULES,
45
45
  renamedRules: () => RENAMED_RULES,
@@ -47,7 +47,7 @@ __export(index_exports, {
47
47
  rules: () => RULES,
48
48
  strictRules: () => STRICT_RULES
49
49
  });
50
- module.exports = __toCommonJS(index_exports);
50
+ module.exports = __toCommonJS(src_exports);
51
51
 
52
52
  // src/rules/no-conditional-empty-object-spread.ts
53
53
  var import_utils2 = require("@typescript-eslint/utils");
@@ -7521,20 +7521,9 @@ var no_vague_suppression_description_default = createRule({
7521
7521
  }
7522
7522
  });
7523
7523
 
7524
- // src/rules/no-generic-single-export-module.ts
7524
+ // src/rules/_runtime-exports.ts
7525
7525
  var import_utils47 = require("@typescript-eslint/utils");
7526
- var NO_GENERIC_SINGLE_EXPORT_MODULE_DOCUMENTATION = {
7527
- summary: "Disallow generic module stems when one runtime export already names the responsibility.",
7528
- rationale: "A generic filename hides the sole exported responsibility and makes navigation less descriptive.",
7529
- remediation: "Choose a responsibility-bearing module name or colocate the export with its domain.",
7530
- category: "maintainability",
7531
- limitations: ["Only the fixed generic-stem vocabulary with exactly one public runtime export is checked; exported destructuring patterns are excluded rather than undercounted."],
7532
- examples: [
7533
- { id: "responsibility-named-module", title: "Name the module after its export", outcome: "no-match", files: [{ path: "src/parse-order.ts", source: "export function parseOrder() { return {}; }" }], focusPath: "src/parse-order.ts", expectedCount: 0, public: true },
7534
- { id: "generic-module-name", title: "Do not hide one export in a generic module", outcome: "match", files: [{ path: "src/utils.ts", source: "export function parseOrder() { return {}; }" }], focusPath: "src/utils.ts", expectedCount: 1, public: true }
7535
- ]
7536
- };
7537
- var GENERIC_STEMS = /* @__PURE__ */ new Set([
7526
+ var GENERIC_MODULE_STEMS = /* @__PURE__ */ new Set([
7538
7527
  "common",
7539
7528
  "helper",
7540
7529
  "helpers",
@@ -7545,139 +7534,152 @@ var GENERIC_STEMS = /* @__PURE__ */ new Set([
7545
7534
  "utils"
7546
7535
  ]);
7547
7536
  var CJS_OBJECT_EXPORT_METHODS = /* @__PURE__ */ new Set(["assign", "defineProperties", "defineProperty"]);
7548
- function fileParts(filename) {
7549
- const base = filename.replaceAll("\\", "/").split("/").at(-1) ?? "";
7550
- const extension = base.match(/(\.[cm]?[jt]sx?)$/u)?.[1] ?? ".ts";
7551
- const [stem4 = "", ...suffixes] = base.slice(0, -extension.length).split(".");
7552
- return { stem: stem4, suffixes: suffixes.map((suffix) => suffix.toLowerCase()) };
7553
- }
7554
- function declaredNames(declaration) {
7555
- if (declaration.declare === true) return [];
7556
- if (declaration.type === import_utils47.AST_NODE_TYPES.FunctionDeclaration || declaration.type === import_utils47.AST_NODE_TYPES.ClassDeclaration || declaration.type === import_utils47.AST_NODE_TYPES.TSEnumDeclaration) {
7557
- if (declaration.type === import_utils47.AST_NODE_TYPES.TSEnumDeclaration && declaration.const) return [];
7558
- return declaration.id === null ? [] : [declaration.id.name];
7559
- }
7560
- if (declaration.type === import_utils47.AST_NODE_TYPES.TSModuleDeclaration && declaration.id.type === import_utils47.AST_NODE_TYPES.Identifier) {
7561
- return [declaration.id.name];
7562
- }
7563
- if (declaration.type !== import_utils47.AST_NODE_TYPES.VariableDeclaration) return [];
7564
- return declaration.declarations.flatMap(
7565
- (item) => item.id.type === import_utils47.AST_NODE_TYPES.Identifier ? [item.id.name] : []
7566
- );
7567
- }
7568
7537
  function runtimeExports(program) {
7569
- const exports2 = [];
7570
- const typeBindings = typeOnlyBindings(program);
7538
+ const bindings = localBindings(program);
7539
+ const exports2 = /* @__PURE__ */ new Map();
7571
7540
  let ambiguous = false;
7572
- function collectRuntimeExport(statement) {
7573
- if (statement.type === import_utils47.AST_NODE_TYPES.ExportAllDeclaration) {
7574
- if (statement.exportKind !== "type") ambiguous = true;
7575
- return;
7576
- }
7577
- if (statement.type === import_utils47.AST_NODE_TYPES.ExportDefaultDeclaration) {
7578
- collectDefaultExport(statement);
7579
- return;
7580
- }
7581
- if (statement.type !== import_utils47.AST_NODE_TYPES.ExportNamedDeclaration || statement.exportKind === "type") return;
7541
+ function add(key, name, node, emission) {
7542
+ if (emission === "unknown") ambiguous = true;
7543
+ if (emission === "runtime") exports2.set(key, { key, name, node });
7544
+ }
7545
+ function collectDefault(statement) {
7546
+ const declaration = statement.declaration;
7547
+ if (declaration.type === import_utils47.AST_NODE_TYPES.Identifier) {
7548
+ add("default", declaration.name, statement, bindings.get(declaration.name) ?? "unknown");
7549
+ } else if ("id" in declaration && declaration.id?.type === import_utils47.AST_NODE_TYPES.Identifier) {
7550
+ add("default", declaration.id.name, declaration, declarationEmission(declaration));
7551
+ } else ambiguous = true;
7552
+ }
7553
+ function collectNamed(statement) {
7554
+ if (statement.exportKind === "type") return;
7582
7555
  if (statement.source !== null) {
7583
7556
  if (statement.specifiers.some((specifier) => specifier.exportKind !== "type")) ambiguous = true;
7584
7557
  return;
7585
7558
  }
7586
- if (statement.declaration !== null) {
7587
- const declaration = statement.declaration;
7559
+ const declaration = statement.declaration;
7560
+ if (declaration !== null) {
7588
7561
  if (declaration.type === import_utils47.AST_NODE_TYPES.VariableDeclaration && declaration.declarations.some((item) => item.id.type !== import_utils47.AST_NODE_TYPES.Identifier)) ambiguous = true;
7589
- exports2.push(...declaredNames(declaration).map((name) => ({ key: name, name, node: declaration })));
7562
+ const names = declarationNames(declaration);
7563
+ if (names.length === 0 && declarationEmission(declaration) !== "erased") ambiguous = true;
7564
+ for (const name of names) add(name, name, declaration, bindings.get(name) ?? "unknown");
7590
7565
  }
7591
- collectExportSpecifiers(statement);
7592
- }
7593
- function collectExportSpecifiers(statement) {
7594
7566
  for (const specifier of statement.specifiers) {
7595
- if (specifier.exportKind === "type" || typeBindings.has(specifier.local.name)) continue;
7596
- const exported = specifier.exported.type === import_utils47.AST_NODE_TYPES.Identifier ? specifier.exported.name : specifier.exported.value;
7567
+ if (specifier.exportKind === "type") continue;
7568
+ const key = specifier.exported.type === import_utils47.AST_NODE_TYPES.Identifier ? specifier.exported.name : specifier.exported.value;
7597
7569
  const local = specifier.local.name;
7598
- exports2.push({ key: exported, name: exported === "default" ? local : exported, node: specifier });
7570
+ add(key, key === "default" ? local : key, specifier, bindings.get(local) ?? "unknown");
7599
7571
  }
7600
7572
  }
7601
- function collectDefaultExport(statement) {
7602
- const declaration = statement.declaration;
7603
- if (declaration.type === import_utils47.AST_NODE_TYPES.Identifier) {
7604
- if (!typeBindings.has(declaration.name)) {
7605
- exports2.push({ key: "default", name: declaration.name, node: statement });
7606
- }
7607
- } else if ((declaration.type === import_utils47.AST_NODE_TYPES.FunctionDeclaration || declaration.type === import_utils47.AST_NODE_TYPES.ClassDeclaration) && declaration.id !== null && declaration.declare !== true) exports2.push({ key: "default", name: declaration.id.name, node: declaration });
7608
- else if (declaration.type !== import_utils47.AST_NODE_TYPES.TSInterfaceDeclaration && declaration.type !== import_utils47.AST_NODE_TYPES.TSTypeAliasDeclaration) ambiguous = true;
7609
- }
7610
7573
  for (const statement of program.body) {
7611
- collectRuntimeExport(statement);
7574
+ if (statement.type === import_utils47.AST_NODE_TYPES.ExportAllDeclaration && statement.exportKind !== "type") ambiguous = true;
7575
+ if (statement.type === import_utils47.AST_NODE_TYPES.TSExportAssignment) ambiguous = true;
7576
+ if (statement.type === import_utils47.AST_NODE_TYPES.ExportDefaultDeclaration) collectDefault(statement);
7577
+ if (statement.type === import_utils47.AST_NODE_TYPES.ExportNamedDeclaration) collectNamed(statement);
7612
7578
  }
7613
- const unique = new Map(exports2.map((entry) => [entry.key, entry]));
7614
- return { exports: [...unique.values()], ambiguous };
7579
+ return { exports: [...exports2.values()], ambiguous };
7615
7580
  }
7616
- function typeOnlyBindings(program) {
7617
- const names = /* @__PURE__ */ new Set();
7618
- const runtimeNames = /* @__PURE__ */ new Set();
7619
- function collectTypeBinding(statement) {
7620
- const declaration = statement.type === import_utils47.AST_NODE_TYPES.ExportNamedDeclaration ? statement.declaration : statement;
7621
- if (declaration?.type === import_utils47.AST_NODE_TYPES.TSInterfaceDeclaration || declaration?.type === import_utils47.AST_NODE_TYPES.TSTypeAliasDeclaration) {
7622
- names.add(declaration.id.name);
7623
- return;
7624
- }
7625
- if (declaration?.type === import_utils47.AST_NODE_TYPES.TSEnumDeclaration && declaration.const) {
7626
- names.add(declaration.id.name);
7627
- return;
7628
- }
7629
- if (statement.type === import_utils47.AST_NODE_TYPES.ImportDeclaration) {
7630
- collectImportBindings(statement);
7631
- return;
7632
- }
7633
- if (declaration?.type === import_utils47.AST_NODE_TYPES.TSDeclareFunction && declaration.id !== null) {
7634
- names.add(declaration.id.name);
7635
- return;
7636
- }
7637
- if (declaration !== null && declaration.declare === true) {
7638
- collectDeclaredNames(declaration);
7639
- return;
7640
- }
7641
- if (declaration !== null && "type" in declaration) {
7642
- for (const name of declaredNames(declaration)) {
7643
- runtimeNames.add(name);
7644
- }
7645
- }
7581
+ function localBindings(program) {
7582
+ const bindings = /* @__PURE__ */ new Map();
7583
+ function register(name, emission) {
7584
+ const previous = bindings.get(name);
7585
+ if (previous === "runtime" || emission === "runtime") bindings.set(name, "runtime");
7586
+ else if (previous === "unknown" || emission === "unknown") bindings.set(name, "unknown");
7587
+ else bindings.set(name, "erased");
7646
7588
  }
7647
- function collectImportBindings(statement) {
7648
- for (const specifier of statement.specifiers) {
7649
- if (statement.importKind === "type" || specifier.type === import_utils47.AST_NODE_TYPES.ImportSpecifier && specifier.importKind === "type") {
7650
- names.add(specifier.local.name);
7651
- } else {
7652
- runtimeNames.add(specifier.local.name);
7589
+ for (const statement of program.body) {
7590
+ if (statement.type === import_utils47.AST_NODE_TYPES.ImportDeclaration) {
7591
+ for (const specifier of statement.specifiers) {
7592
+ const typeOnly = statement.importKind === "type" || specifier.type === import_utils47.AST_NODE_TYPES.ImportSpecifier && specifier.importKind === "type";
7593
+ register(specifier.local.name, typeOnly ? "erased" : "unknown");
7653
7594
  }
7595
+ continue;
7654
7596
  }
7597
+ const declaration = statement.type === import_utils47.AST_NODE_TYPES.ExportNamedDeclaration || statement.type === import_utils47.AST_NODE_TYPES.ExportDefaultDeclaration ? statement.declaration : statement;
7598
+ if (declaration === null) continue;
7599
+ for (const name of declarationNames(declaration)) register(name, declarationEmission(declaration));
7655
7600
  }
7656
- function collectDeclaredNames(declaration) {
7657
- if ((declaration.type === import_utils47.AST_NODE_TYPES.ClassDeclaration || declaration.type === import_utils47.AST_NODE_TYPES.FunctionDeclaration || declaration.type === import_utils47.AST_NODE_TYPES.TSEnumDeclaration || declaration.type === import_utils47.AST_NODE_TYPES.TSModuleDeclaration) && declaration.id !== null && declaration.id.type === import_utils47.AST_NODE_TYPES.Identifier) names.add(declaration.id.name);
7658
- if (declaration.type === import_utils47.AST_NODE_TYPES.VariableDeclaration) {
7659
- for (const item of declaration.declarations) {
7660
- if (item.id.type === import_utils47.AST_NODE_TYPES.Identifier) names.add(item.id.name);
7661
- }
7662
- }
7601
+ return bindings;
7602
+ }
7603
+ function declarationNames(declaration) {
7604
+ if ("id" in declaration && declaration.id !== null) {
7605
+ let id = declaration.id;
7606
+ while (id.type === import_utils47.AST_NODE_TYPES.TSQualifiedName) id = id.left;
7607
+ if (id.type === import_utils47.AST_NODE_TYPES.Identifier) return [id.name];
7663
7608
  }
7664
- for (const statement of program.body) {
7665
- collectTypeBinding(statement);
7609
+ if (declaration.type !== import_utils47.AST_NODE_TYPES.VariableDeclaration) return [];
7610
+ return declaration.declarations.flatMap((item) => item.id.type === import_utils47.AST_NODE_TYPES.Identifier ? [item.id.name] : []);
7611
+ }
7612
+ function declarationEmission(declaration) {
7613
+ if ("declare" in declaration && declaration.declare === true) return "erased";
7614
+ switch (declaration.type) {
7615
+ case import_utils47.AST_NODE_TYPES.TSInterfaceDeclaration:
7616
+ case import_utils47.AST_NODE_TYPES.TSTypeAliasDeclaration:
7617
+ case import_utils47.AST_NODE_TYPES.TSDeclareFunction:
7618
+ return "erased";
7619
+ case import_utils47.AST_NODE_TYPES.ClassDeclaration:
7620
+ case import_utils47.AST_NODE_TYPES.FunctionDeclaration:
7621
+ case import_utils47.AST_NODE_TYPES.VariableDeclaration:
7622
+ return "runtime";
7623
+ case import_utils47.AST_NODE_TYPES.TSEnumDeclaration:
7624
+ return declaration.const ? "unknown" : "runtime";
7625
+ case import_utils47.AST_NODE_TYPES.TSModuleDeclaration:
7626
+ return namespaceEmission(declaration);
7627
+ default:
7628
+ return "unknown";
7666
7629
  }
7667
- return new Set([...names].filter((name) => !runtimeNames.has(name)));
7668
7630
  }
7669
- function isGlobalIdentifier2(context, node) {
7670
- const variable = import_utils47.ASTUtils.findVariable(context.sourceCode.getScope(node), node.name);
7671
- return variable === null || variable.defs.length === 0;
7631
+ function namespaceEmission(declaration) {
7632
+ const { body: body2 } = declaration;
7633
+ if (body2 === void 0) return "unknown";
7634
+ if (body2.body.length === 0) return "unknown";
7635
+ let ambiguous = false;
7636
+ for (const statement of body2.body) {
7637
+ if (statement.type === import_utils47.AST_NODE_TYPES.ExportNamedDeclaration && statement.exportKind === "type") continue;
7638
+ const inner = statement.type === import_utils47.AST_NODE_TYPES.ExportNamedDeclaration ? statement.declaration : statement;
7639
+ const emission = inner === null ? "unknown" : declarationEmission(inner);
7640
+ if (emission === "runtime") return "runtime";
7641
+ if (emission === "unknown") ambiguous = true;
7642
+ }
7643
+ return ambiguous ? "unknown" : "erased";
7672
7644
  }
7673
- function isConventionalFrameworkUtility(filename, exported) {
7674
- const normalized = filename.replaceAll("\\", "/");
7675
- return exported === "cn" && /(?:^|\/)lib\/utils\.[cm]?[jt]sx?$/u.test(normalized);
7645
+ function isCommonJsExportReference(node, sourceCode) {
7646
+ function isGlobal(node2) {
7647
+ const variable = import_utils47.ASTUtils.findVariable(sourceCode.getScope(node2), node2.name);
7648
+ return variable === null || variable.defs.length === 0;
7649
+ }
7650
+ if (node.type === import_utils47.AST_NODE_TYPES.MemberExpression) {
7651
+ return node.object.type === import_utils47.AST_NODE_TYPES.Identifier && isGlobal(node.object) && (node.object.name === "exports" || node.object.name === "module" && memberPropertyName(node) === "exports");
7652
+ }
7653
+ const first = node.arguments[0];
7654
+ return first?.type === import_utils47.AST_NODE_TYPES.Identifier && first.name === "exports" && isGlobal(first) && node.callee.type === import_utils47.AST_NODE_TYPES.MemberExpression && node.callee.object.type === import_utils47.AST_NODE_TYPES.Identifier && node.callee.object.name === "Object" && isGlobal(node.callee.object) && CJS_OBJECT_EXPORT_METHODS.has(memberPropertyName(node.callee) ?? "");
7676
7655
  }
7677
7656
  function memberPropertyName(node) {
7678
7657
  if (!node.computed && node.property.type === import_utils47.AST_NODE_TYPES.Identifier) return node.property.name;
7679
7658
  return node.computed && node.property.type === import_utils47.AST_NODE_TYPES.Literal && typeof node.property.value === "string" ? node.property.value : null;
7680
7659
  }
7660
+
7661
+ // src/rules/no-generic-single-export-module.ts
7662
+ var NO_GENERIC_SINGLE_EXPORT_MODULE_DOCUMENTATION = {
7663
+ summary: "Disallow generic module stems when one runtime export already names the responsibility.",
7664
+ rationale: "A generic filename hides the sole exported responsibility and makes navigation less descriptive.",
7665
+ remediation: "Choose a responsibility-bearing module name or colocate the export with its domain.",
7666
+ category: "maintainability",
7667
+ limitations: ["Only the fixed generic-stem vocabulary with exactly one public runtime export is checked; exported destructuring patterns are excluded rather than undercounted."],
7668
+ examples: [
7669
+ { id: "responsibility-named-module", title: "Name the module after its export", outcome: "no-match", files: [{ path: "src/parse-order.ts", source: "export function parseOrder() { return {}; }" }], focusPath: "src/parse-order.ts", expectedCount: 0, public: true },
7670
+ { id: "generic-module-name", title: "Do not hide one export in a generic module", outcome: "match", files: [{ path: "src/utils.ts", source: "export function parseOrder() { return {}; }" }], focusPath: "src/utils.ts", expectedCount: 1, public: true }
7671
+ ]
7672
+ };
7673
+ function fileParts(filename) {
7674
+ const base = filename.replaceAll("\\", "/").split("/").at(-1) ?? "";
7675
+ const extension = base.match(/(\.[cm]?[jt]sx?)$/u)?.[1] ?? ".ts";
7676
+ const [stem4 = "", ...suffixes] = base.slice(0, -extension.length).split(".");
7677
+ return { stem: stem4, suffixes: suffixes.map((suffix) => suffix.toLowerCase()) };
7678
+ }
7679
+ function isConventionalFrameworkUtility(filename, exported) {
7680
+ const normalized = filename.replaceAll("\\", "/");
7681
+ return exported === "cn" && /(?:^|\/)lib\/utils\.[cm]?[jt]sx?$/u.test(normalized);
7682
+ }
7681
7683
  var no_generic_single_export_module_default = createRule({
7682
7684
  name: "no-generic-single-export-module",
7683
7685
  documentation: NO_GENERIC_SINGLE_EXPORT_MODULE_DOCUMENTATION,
@@ -7693,16 +7695,11 @@ var no_generic_single_export_module_default = createRule({
7693
7695
  create(context) {
7694
7696
  const file = fileParts(context.filename);
7695
7697
  const { stem: stem4 } = file;
7696
- if (!GENERIC_STEMS.has(stem4) || isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
7698
+ if (!GENERIC_MODULE_STEMS.has(stem4) || isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
7697
7699
  let hasCommonJsExport = false;
7698
7700
  return {
7699
- CallExpression(node) {
7700
- const first = node.arguments[0];
7701
- if (first?.type === import_utils47.AST_NODE_TYPES.Identifier && first.name === "exports" && isGlobalIdentifier2(context, first) && node.callee.type === import_utils47.AST_NODE_TYPES.MemberExpression && node.callee.object.type === import_utils47.AST_NODE_TYPES.Identifier && node.callee.object.name === "Object" && isGlobalIdentifier2(context, node.callee.object) && memberPropertyName(node.callee) !== null && CJS_OBJECT_EXPORT_METHODS.has(memberPropertyName(node.callee))) hasCommonJsExport = true;
7702
- },
7703
- MemberExpression(node) {
7704
- if (node.object.type === import_utils47.AST_NODE_TYPES.Identifier && node.object.name === "exports" && isGlobalIdentifier2(context, node.object)) hasCommonJsExport = true;
7705
- if (node.object.type === import_utils47.AST_NODE_TYPES.Identifier && node.object.name === "module" && isGlobalIdentifier2(context, node.object) && memberPropertyName(node) === "exports") hasCommonJsExport = true;
7701
+ "CallExpression, MemberExpression"(node) {
7702
+ if (isCommonJsExportReference(node, context.sourceCode)) hasCommonJsExport = true;
7706
7703
  },
7707
7704
  "Program:exit"(program) {
7708
7705
  if (hasCommonJsExport) return;
@@ -9243,19 +9240,19 @@ var no_restated_jsdoc_default = createRule({
9243
9240
  function enclosingDeclarationNames(node) {
9244
9241
  let declaration = null;
9245
9242
  while (node != null && node.type !== import_utils57.AST_NODE_TYPES.Program) {
9246
- declaration = declarationNames(node);
9243
+ declaration = declarationNames2(node);
9247
9244
  if (declaration !== null) break;
9248
9245
  node = node.parent ?? null;
9249
9246
  }
9250
9247
  return declaration;
9251
9248
  }
9252
- function declarationNames(node) {
9249
+ function declarationNames2(node) {
9253
9250
  switch (node.type) {
9254
9251
  // `export function f()` — the JSDoc sits above the `export`, so the token
9255
9252
  // after it resolves to the wrapper, not to the thing being documented.
9256
9253
  case import_utils57.AST_NODE_TYPES.ExportNamedDeclaration:
9257
9254
  case import_utils57.AST_NODE_TYPES.ExportDefaultDeclaration:
9258
- return node.declaration == null ? null : declarationNames(node.declaration);
9255
+ return node.declaration == null ? null : declarationNames2(node.declaration);
9259
9256
  case import_utils57.AST_NODE_TYPES.FunctionDeclaration:
9260
9257
  case import_utils57.AST_NODE_TYPES.TSDeclareFunction:
9261
9258
  return node.id === null ? null : { name: node.id.name, params: paramNames(node.params) };
@@ -20078,7 +20075,7 @@ var REQUIRE_FETCH_TIMEOUT_DOCUMENTATION = {
20078
20075
  rationale: "An unbounded request can occupy work indefinitely when an upstream stalls.",
20079
20076
  remediation: "Pass an abort signal, such as `AbortSignal.timeout(ms)`, in the fetch init.",
20080
20077
  category: "correctness",
20081
- limitations: ["Signal presence establishes an explicit cancellation path, not a guaranteed timeout. Forwarded Request objects can carry an existing signal."],
20078
+ limitations: ["Signal presence establishes an explicit cancellation path, not a guaranteed timeout. Literal null, global undefined, and void 0 do not provide a signal. Unknown spreads and dynamic values are not inferred. Forwarded Request objects can carry an existing signal."],
20082
20079
  examples: [
20083
20080
  { id: "bounded-fetch", title: "Bound the request", outcome: "no-match", files: [{ path: "src/client.ts", source: "await fetch(url, { signal: AbortSignal.timeout(5000) });" }], focusPath: "src/client.ts", expectedCount: 0, public: true },
20084
20081
  { id: "unbounded-fetch", title: "Do not leave fetch unbounded", outcome: "match", files: [{ path: "src/client.ts", source: "await fetch('https://api.example.com/items');" }], focusPath: "src/client.ts", expectedCount: 1, public: true }
@@ -20098,22 +20095,23 @@ function matchesAnyPattern3(filename, patterns) {
20098
20095
  }
20099
20096
  return false;
20100
20097
  }
20101
- function initProvablyLacksSignal(init) {
20102
- if (init.type !== import_utils110.AST_NODE_TYPES.ObjectExpression) {
20103
- return false;
20104
- }
20098
+ function initProvablyLacksSignal(init, resolvesToGlobal) {
20099
+ if (init.type !== import_utils110.AST_NODE_TYPES.ObjectExpression) return false;
20100
+ let lacksSignal = true;
20105
20101
  for (const prop of init.properties) {
20106
20102
  if (prop.type === import_utils110.AST_NODE_TYPES.SpreadElement) {
20107
- return false;
20108
- }
20109
- if (prop.key.type === import_utils110.AST_NODE_TYPES.Identifier && prop.key.name === "signal" || prop.key.type === import_utils110.AST_NODE_TYPES.Literal && prop.key.value === "signal") {
20110
- return false;
20103
+ lacksSignal = false;
20104
+ continue;
20111
20105
  }
20112
- if (prop.computed) {
20113
- return false;
20106
+ const isSignal = !prop.computed && prop.key.type === import_utils110.AST_NODE_TYPES.Identifier && prop.key.name === "signal" || prop.key.type === import_utils110.AST_NODE_TYPES.Literal && prop.key.value === "signal";
20107
+ if (isSignal) {
20108
+ const value = prop.value;
20109
+ lacksSignal = prop.kind === "init" && !prop.method && (value.type === import_utils110.AST_NODE_TYPES.Literal && value.value === null || value.type === import_utils110.AST_NODE_TYPES.Identifier && value.name === "undefined" && resolvesToGlobal(value) || value.type === import_utils110.AST_NODE_TYPES.UnaryExpression && value.operator === "void" && value.argument.type === import_utils110.AST_NODE_TYPES.Literal && value.argument.value === 0);
20110
+ } else if (prop.computed && prop.key.type !== import_utils110.AST_NODE_TYPES.Literal) {
20111
+ lacksSignal = false;
20114
20112
  }
20115
20113
  }
20116
- return true;
20114
+ return lacksSignal;
20117
20115
  }
20118
20116
  function isInlineUrl(node, resolvesToGlobal) {
20119
20117
  return node.type === import_utils110.AST_NODE_TYPES.Literal && typeof node.value === "string" || node.type === import_utils110.AST_NODE_TYPES.TemplateLiteral || node.type === import_utils110.AST_NODE_TYPES.NewExpression && node.callee.type === import_utils110.AST_NODE_TYPES.Identifier && node.callee.name === "URL" && resolvesToGlobal(node.callee);
@@ -20170,7 +20168,7 @@ var require_fetch_timeout_default = createRule({
20170
20168
  );
20171
20169
  if (variable?.defs.length !== 1) return false;
20172
20170
  const definition = variable.defs[0];
20173
- if (definition?.type !== "Variable" || definition.parent.kind !== "const" || definition.node.init?.type !== import_utils110.AST_NODE_TYPES.ObjectExpression || !initProvablyLacksSignal(definition.node.init)) {
20171
+ if (definition?.type !== "Variable" || definition.parent.kind !== "const" || definition.node.init?.type !== import_utils110.AST_NODE_TYPES.ObjectExpression || !initProvablyLacksSignal(definition.node.init, resolvesToGlobal)) {
20174
20172
  return false;
20175
20173
  }
20176
20174
  for (const reference of variable.references) {
@@ -20202,7 +20200,7 @@ var require_fetch_timeout_default = createRule({
20202
20200
  if (first !== void 0 && (node.arguments.length === 1 && !isInlineUrl(first, resolvesToGlobal) || isForwardedRequest(first))) {
20203
20201
  return;
20204
20202
  }
20205
- if (init === void 0 || initProvablyLacksSignal(init) || init.type === import_utils110.AST_NODE_TYPES.Identifier && localConstInitProvablyLacksSignal(init)) {
20203
+ if (init === void 0 || initProvablyLacksSignal(init, resolvesToGlobal) || init.type === import_utils110.AST_NODE_TYPES.Identifier && localConstInitProvablyLacksSignal(init)) {
20206
20204
  context.report({ node, messageId: "missingSignal" });
20207
20205
  }
20208
20206
  }
@@ -21942,9 +21940,9 @@ var STEPDOWN_DOCUMENTATION = {
21942
21940
  remediation: "Consider moving the private helper below its sole caller after reviewing initialization and reflection dependencies.",
21943
21941
  category: "maintainability",
21944
21942
  limitations: [
21945
- "Generated and test files, cycles, dynamic references, overload targets, and helpers with multiple callers are excluded.",
21943
+ "Generated and test files, cycles, dynamic or escaped references, overload targets, and helpers with multiple callers are excluded; immutable local callable aliases are followed only when every use stays in the caller.",
21946
21944
  "Class helpers must be private; their sole caller may be public, protected, or private.",
21947
- "Runtime class-field, static-block, computed-member, and decorator barriers are never crossed.",
21945
+ "Runtime class-field, static-block, computed-member, and decorator barriers are never crossed; non-hoisted module helpers also cannot cross eager execution or unrelated initialization.",
21948
21946
  "This rule is report-only: reordering methods can change reflective property order, and moving module declarations can change initialization behavior or introduce temporal-dead-zone failures. Review module cycles and eager callers manually."
21949
21947
  ],
21950
21948
  examples: [
@@ -21956,7 +21954,7 @@ function isFunction(node) {
21956
21954
  return node.type === import_utils119.AST_NODE_TYPES.ArrowFunctionExpression || node.type === import_utils119.AST_NODE_TYPES.FunctionDeclaration || node.type === import_utils119.AST_NODE_TYPES.FunctionExpression;
21957
21955
  }
21958
21956
  function reportMisordered(context, candidates, scopeDefinitions, calls, pinned, canMove = () => true) {
21959
- const byName = new Map(scopeDefinitions.map((definition) => [definition.name, definition]));
21957
+ const byName = new Map(scopeDefinitions.map((definition) => [definition.key, definition]));
21960
21958
  const cycles = cycleComponents(calls);
21961
21959
  const callers = /* @__PURE__ */ new Map();
21962
21960
  for (const [caller, callees] of calls) {
@@ -21968,16 +21966,16 @@ function reportMisordered(context, candidates, scopeDefinitions, calls, pinned,
21968
21966
  }
21969
21967
  }
21970
21968
  for (const helper of candidates) {
21971
- const helperCallers = [...callers.get(helper.name) ?? []];
21972
- if (pinned.has(helper.name) || helperCallers.length !== 1) continue;
21969
+ const helperCallers = [...callers.get(helper.key) ?? []];
21970
+ if (pinned.has(helper.key) || helperCallers.length !== 1) continue;
21973
21971
  const callerName2 = helperCallers[0];
21974
- if (callerName2 === void 0 || cycles.has(helper.name) && cycles.get(helper.name) === cycles.get(callerName2)) continue;
21972
+ if (callerName2 === void 0 || cycles.has(helper.key) && cycles.get(helper.key) === cycles.get(callerName2)) continue;
21975
21973
  const caller = byName.get(callerName2);
21976
21974
  if (caller === void 0 || helper.node.range[0] >= caller.node.range[0] || !canMove(helper, caller)) continue;
21977
21975
  context.report({
21978
21976
  node: helper.node,
21979
21977
  messageId: "helperAboveOnlyCaller",
21980
- data: { helper: helper.name, caller: callerName2 }
21978
+ data: { helper: helper.name, caller: caller.name }
21981
21979
  });
21982
21980
  }
21983
21981
  }
@@ -22048,6 +22046,43 @@ function cycleComponents(graph) {
22048
22046
  }
22049
22047
  return components;
22050
22048
  }
22049
+ function isErasedExpression(node) {
22050
+ return node.type === import_utils119.AST_NODE_TYPES.TSAsExpression || node.type === import_utils119.AST_NODE_TYPES.TSTypeAssertion || node.type === import_utils119.AST_NODE_TYPES.TSSatisfiesExpression || node.type === import_utils119.AST_NODE_TYPES.TSNonNullExpression || node.type === import_utils119.AST_NODE_TYPES.TSInstantiationExpression;
22051
+ }
22052
+ function unwrapExpression7(node) {
22053
+ let current = node;
22054
+ while (isErasedExpression(current)) current = current.expression;
22055
+ return current;
22056
+ }
22057
+ function wrappedExpression(node) {
22058
+ let current = node;
22059
+ while (current.parent !== void 0 && isErasedExpression(current.parent) && current.parent.expression === current) current = current.parent;
22060
+ return current;
22061
+ }
22062
+ function enclosingFunction5(context, node) {
22063
+ return [...context.sourceCode.getAncestors(node)].reverse().find(isFunction);
22064
+ }
22065
+ function localCallCount(context, node, owner) {
22066
+ const seen = /* @__PURE__ */ new Set();
22067
+ const pending = [node];
22068
+ let count = 0;
22069
+ while (pending.length > 0) {
22070
+ const current = pending.pop();
22071
+ if (current === void 0 || enclosingFunction5(context, current) !== owner) return null;
22072
+ const expression = wrappedExpression(current);
22073
+ const parent = expression.parent;
22074
+ if (parent?.type === import_utils119.AST_NODE_TYPES.CallExpression && parent.callee === expression) {
22075
+ count += 1;
22076
+ continue;
22077
+ }
22078
+ if (parent?.type !== import_utils119.AST_NODE_TYPES.VariableDeclarator || parent.init !== expression || parent.id.type !== import_utils119.AST_NODE_TYPES.Identifier || parent.parent.type !== import_utils119.AST_NODE_TYPES.VariableDeclaration || parent.parent.kind !== "const") return null;
22079
+ const variable = context.sourceCode.getDeclaredVariables(parent)[0];
22080
+ if (variable === void 0 || seen.has(variable) || !stableVariable(variable)) return null;
22081
+ seen.add(variable);
22082
+ pending.push(...variable.references.filter((reference) => reference.isRead()).map((reference) => reference.identifier));
22083
+ }
22084
+ return count;
22085
+ }
22051
22086
  function moduleScope(context, program) {
22052
22087
  const declarations = moduleDefinitions(program);
22053
22088
  const counts = /* @__PURE__ */ new Map();
@@ -22063,6 +22098,26 @@ function moduleScope(context, program) {
22063
22098
  const definitions = scopeDefinitions.filter(
22064
22099
  (definition) => !exported.has(definition.name) && !overloadNames.has(definition.name)
22065
22100
  );
22101
+ const { calls, pinned } = moduleCallGraph(context, scopeDefinitions);
22102
+ const statementIndexes = new Map(program.body.map((statement, index) => [statement, index]));
22103
+ const runtimeBarrierPrefix = [0];
22104
+ for (const statement of program.body) {
22105
+ runtimeBarrierPrefix.push((runtimeBarrierPrefix.at(-1) ?? 0) + (isDeferredModuleStatement(statement) ? 0 : 1));
22106
+ }
22107
+ const statementIndex = (definition) => {
22108
+ let current = definition.node;
22109
+ while (current.parent !== void 0 && current.parent.type !== import_utils119.AST_NODE_TYPES.Program) current = current.parent;
22110
+ return statementIndexes.get(current);
22111
+ };
22112
+ const canMove = (helper, caller) => {
22113
+ if (helper.node.type === import_utils119.AST_NODE_TYPES.FunctionDeclaration) return true;
22114
+ const helperIndex = statementIndex(helper);
22115
+ const callerIndex = statementIndex(caller);
22116
+ return helperIndex !== void 0 && callerIndex !== void 0 && runtimeBarrierPrefix[callerIndex + 1] === runtimeBarrierPrefix[helperIndex + 1];
22117
+ };
22118
+ reportMisordered(context, definitions, scopeDefinitions, calls, pinned, canMove);
22119
+ }
22120
+ function moduleCallGraph(context, scopeDefinitions) {
22066
22121
  const byFunction = new Map(scopeDefinitions.map((definition) => [definition.functionNode, definition]));
22067
22122
  const calls = /* @__PURE__ */ new Map();
22068
22123
  const pinned = /* @__PURE__ */ new Set();
@@ -22070,26 +22125,33 @@ function moduleScope(context, program) {
22070
22125
  const variable = context.sourceCode.getDeclaredVariables(definition.bindingNode)[0];
22071
22126
  for (const reference of variable?.references ?? []) {
22072
22127
  if (reference.isWrite() && reference.init !== true) {
22073
- pinned.add(definition.name);
22128
+ pinned.add(definition.key);
22074
22129
  continue;
22075
22130
  }
22076
22131
  if (!reference.isRead()) continue;
22077
- const identifier = reference.identifier;
22078
- const ancestors = context.sourceCode.getAncestors(identifier);
22079
- const nearestFunction2 = [...ancestors].reverse().find(isFunction);
22080
- const parent = identifier.parent;
22081
- const callerDefinition = nearestFunction2 === void 0 ? void 0 : byFunction.get(nearestFunction2);
22082
- if (callerDefinition === void 0 || parent.type !== import_utils119.AST_NODE_TYPES.CallExpression || parent.callee !== identifier) {
22083
- pinned.add(definition.name);
22132
+ const callerDefinition = byFunction.get(enclosingFunction5(context, reference.identifier));
22133
+ if (callerDefinition?.functionNode === void 0) {
22134
+ pinned.add(definition.key);
22084
22135
  continue;
22085
22136
  }
22086
- const caller = callerDefinition.name;
22087
- const callees = calls.get(caller) ?? /* @__PURE__ */ new Set();
22088
- callees.add(definition.name);
22089
- calls.set(caller, callees);
22137
+ const count = localCallCount(context, reference.identifier, callerDefinition.functionNode);
22138
+ if (count === null) {
22139
+ pinned.add(definition.key);
22140
+ } else if (count > 0) {
22141
+ const callees = calls.get(callerDefinition.key) ?? /* @__PURE__ */ new Set();
22142
+ callees.add(definition.key);
22143
+ calls.set(callerDefinition.key, callees);
22144
+ }
22090
22145
  }
22091
22146
  }
22092
- reportMisordered(context, definitions, scopeDefinitions, calls, pinned);
22147
+ return { calls, pinned };
22148
+ }
22149
+ function isDeferredModuleStatement(statement) {
22150
+ const node = statement.type === import_utils119.AST_NODE_TYPES.ExportNamedDeclaration || statement.type === import_utils119.AST_NODE_TYPES.ExportDefaultDeclaration ? statement.declaration : statement;
22151
+ if (node === null || node.type === import_utils119.AST_NODE_TYPES.FunctionDeclaration || node.type === import_utils119.AST_NODE_TYPES.TSDeclareFunction || node.type === import_utils119.AST_NODE_TYPES.TSInterfaceDeclaration || node.type === import_utils119.AST_NODE_TYPES.TSTypeAliasDeclaration || node.type === import_utils119.AST_NODE_TYPES.ImportDeclaration || node.type === import_utils119.AST_NODE_TYPES.ExportAllDeclaration || node.type === import_utils119.AST_NODE_TYPES.EmptyStatement) return true;
22152
+ return node.type === import_utils119.AST_NODE_TYPES.VariableDeclaration && node.declarations.every(
22153
+ (declaration) => declaration.id.type === import_utils119.AST_NODE_TYPES.Identifier && declaration.init !== null && isFunction(unwrapExpression7(declaration.init))
22154
+ );
22093
22155
  }
22094
22156
  function exportedNames(program) {
22095
22157
  const names = /* @__PURE__ */ new Set();
@@ -22123,16 +22185,18 @@ function moduleDefinitions(program) {
22123
22185
  for (const statement of program.body) {
22124
22186
  const node = statement.type === import_utils119.AST_NODE_TYPES.ExportNamedDeclaration || statement.type === import_utils119.AST_NODE_TYPES.ExportDefaultDeclaration ? statement.declaration : statement;
22125
22187
  if (node?.type === import_utils119.AST_NODE_TYPES.FunctionDeclaration && node.id !== null && node.body !== null) {
22126
- definitions.push({ name: node.id.name, node, functionNode: node, bindingNode: node });
22188
+ definitions.push({ key: node.id.name, name: node.id.name, node, functionNode: node, bindingNode: node });
22127
22189
  continue;
22128
22190
  }
22129
- if (node?.type !== import_utils119.AST_NODE_TYPES.VariableDeclaration || node.kind !== "const") continue;
22191
+ if (node?.type !== import_utils119.AST_NODE_TYPES.VariableDeclaration || node.kind !== "const" || node.declarations.length !== 1) continue;
22130
22192
  for (const declarator of node.declarations) {
22131
- if (declarator.id.type === import_utils119.AST_NODE_TYPES.Identifier && declarator.init !== null && isFunction(declarator.init)) {
22193
+ const initializer = declarator.init === null ? null : unwrapExpression7(declarator.init);
22194
+ if (declarator.id.type === import_utils119.AST_NODE_TYPES.Identifier && initializer !== null && isFunction(initializer)) {
22132
22195
  definitions.push({
22196
+ key: declarator.id.name,
22133
22197
  name: declarator.id.name,
22134
22198
  node: declarator,
22135
- functionNode: declarator.init,
22199
+ functionNode: initializer,
22136
22200
  bindingNode: declarator
22137
22201
  });
22138
22202
  }
@@ -22142,15 +22206,21 @@ function moduleDefinitions(program) {
22142
22206
  }
22143
22207
  function methodName2(node) {
22144
22208
  if (node.key.type === import_utils119.AST_NODE_TYPES.PrivateIdentifier) return `#${node.key.name}`;
22145
- return !node.computed && node.key.type === import_utils119.AST_NODE_TYPES.Identifier ? node.key.name : null;
22209
+ if (!node.computed && node.key.type === import_utils119.AST_NODE_TYPES.Identifier) return node.key.name;
22210
+ return node.key.type === import_utils119.AST_NODE_TYPES.Literal && typeof node.key.value === "string" ? node.key.value : null;
22146
22211
  }
22147
- function referencedMethod(context, node, classVariables) {
22148
- const objectVariable = node.object.type === import_utils119.AST_NODE_TYPES.Identifier ? import_utils119.ASTUtils.findVariable(context.sourceCode.getScope(node.object), node.object.name) : null;
22149
- const isClassReference = objectVariable !== null && classVariables.has(objectVariable);
22150
- if (node.object.type !== import_utils119.AST_NODE_TYPES.ThisExpression && !isClassReference) return null;
22151
- if (node.property.type === import_utils119.AST_NODE_TYPES.PrivateIdentifier) return `#${node.property.name}`;
22152
- if (!node.computed && node.property.type === import_utils119.AST_NODE_TYPES.Identifier) return node.property.name;
22153
- return node.computed && node.property.type === import_utils119.AST_NODE_TYPES.Literal && typeof node.property.value === "string" ? node.property.value : null;
22212
+ function methodKey(name, isStatic2) {
22213
+ return `${isStatic2 ? "static" : "instance"}:${name}`;
22214
+ }
22215
+ function receiverDomain(context, object, receivers, thisIsStatic) {
22216
+ const unwrapped = unwrapExpression7(object);
22217
+ if (unwrapped.type === import_utils119.AST_NODE_TYPES.ThisExpression) return thisIsStatic;
22218
+ if (unwrapped.type !== import_utils119.AST_NODE_TYPES.Identifier) return null;
22219
+ const variable = import_utils119.ASTUtils.findVariable(context.sourceCode.getScope(unwrapped), unwrapped.name);
22220
+ return variable === null ? null : receivers.get(variable) ?? null;
22221
+ }
22222
+ function stableVariable(variable) {
22223
+ return !variable.references.some((reference) => reference.isWrite() && reference.init !== true);
22154
22224
  }
22155
22225
  function referencedPropertyName(node) {
22156
22226
  if (node.property.type === import_utils119.AST_NODE_TYPES.PrivateIdentifier) return `#${node.property.name}`;
@@ -22159,7 +22229,7 @@ function referencedPropertyName(node) {
22159
22229
  }
22160
22230
  function walk(node, visitorKeys, visit, nestedFunction = false) {
22161
22231
  visit(node, nestedFunction);
22162
- const nested = nestedFunction || isFunction(node);
22232
+ const nested = nestedFunction || isFunction(node) || node.type === import_utils119.AST_NODE_TYPES.ClassDeclaration || node.type === import_utils119.AST_NODE_TYPES.ClassExpression;
22163
22233
  forEachAstChild(node, visitorKeys, (child) => walk(child, visitorKeys, visit, nested));
22164
22234
  }
22165
22235
  function classScope(context, node, computedReferenceNames) {
@@ -22167,123 +22237,127 @@ function classScope(context, node, computedReferenceNames) {
22167
22237
  (member) => member.type === import_utils119.AST_NODE_TYPES.MethodDefinition
22168
22238
  );
22169
22239
  const counts = classMethodCounts(node.body, methods);
22170
- const scopeDefinitions = methods.flatMap((method) => {
22240
+ const implementations = methods.filter((method) => isFunction(method.value));
22241
+ const implementationCounts = classMethodCounts(node.body, implementations);
22242
+ const scopeDefinitions = implementations.flatMap((method) => {
22171
22243
  const name = methodName2(method);
22172
- return name !== null && counts.get(name) === 1 ? [{ name, node: method }] : [];
22173
- });
22174
- const definitions = methods.flatMap((method) => {
22175
- const name = methodName2(method);
22176
- const isPrivate = method.accessibility === "private" || method.key.type === import_utils119.AST_NODE_TYPES.PrivateIdentifier;
22177
- return name !== null && isPrivate && counts.get(name) === 1 && method.decorators.length === 0 ? [{ name, node: method }] : [];
22244
+ const key = name === null ? null : methodKey(name, method.static);
22245
+ return name !== null && key !== null && implementationCounts.get(key) === 1 ? [{ key, name, node: method }] : [];
22178
22246
  });
22247
+ const definitions = scopeDefinitions.filter(
22248
+ ({ key, node: method }) => (method.accessibility === "private" || method.key.type === import_utils119.AST_NODE_TYPES.PrivateIdentifier) && counts.get(key) === 1 && method.decorators.length === 0 && !method.computed && method.kind === "method"
22249
+ );
22179
22250
  if (definitions.length === 0) return;
22180
- const privateNames = new Set(definitions.map((definition) => definition.name));
22251
+ const methodKeys = new Set(scopeDefinitions.map((definition) => definition.key));
22181
22252
  const calls = /* @__PURE__ */ new Map();
22182
22253
  const pinned = /* @__PURE__ */ new Set();
22183
- const classVariables = /* @__PURE__ */ new Set();
22184
- if (node.id !== null) {
22185
- const internal = import_utils119.ASTUtils.findVariable(context.sourceCode.getScope(node), node.id.name);
22186
- if (internal !== null) classVariables.add(internal);
22187
- }
22188
- if (node.type === import_utils119.AST_NODE_TYPES.ClassExpression && node.parent.type === import_utils119.AST_NODE_TYPES.VariableDeclarator && node.parent.id.type === import_utils119.AST_NODE_TYPES.Identifier) {
22189
- const outer = import_utils119.ASTUtils.findVariable(context.sourceCode.getScope(node.parent), node.parent.id.name);
22190
- if (outer !== null) classVariables.add(outer);
22254
+ const classReceivers = classReceiverBindings(context, node);
22255
+ const pinNames = (name, domain = null) => {
22256
+ for (const definition of definitions) {
22257
+ if ((name === null || definition.name === name) && (domain === null || definition.node.static === domain)) {
22258
+ pinned.add(definition.key);
22259
+ }
22260
+ }
22261
+ };
22262
+ function pinDestructuredMembers(binding, domain) {
22263
+ for (const property of binding.properties) {
22264
+ if (property.type === import_utils119.AST_NODE_TYPES.RestElement || property.computed) {
22265
+ pinNames(null, domain);
22266
+ } else if (property.key.type === import_utils119.AST_NODE_TYPES.Identifier) {
22267
+ pinNames(property.key.name, domain);
22268
+ } else if (property.key.type === import_utils119.AST_NODE_TYPES.Literal && typeof property.key.value === "string") {
22269
+ pinNames(property.key.value, domain);
22270
+ }
22271
+ }
22191
22272
  }
22192
22273
  function collectMethodCalls(method) {
22193
- const caller = methodName2(method);
22194
- if (caller === null || method.value.body === null) return;
22195
- const methodClassVariables = new Set(classVariables);
22196
- const methodAliases = /* @__PURE__ */ new Set();
22274
+ const name = methodName2(method);
22275
+ if (name === null) {
22276
+ pinNames(null);
22277
+ return;
22278
+ }
22279
+ if (!isFunction(method.value)) return;
22280
+ const methodFunction = method.value;
22281
+ const caller = methodKey(name, method.static);
22282
+ const receivers = new Map(classReceivers);
22197
22283
  const parameterDecoratorNodes = /* @__PURE__ */ new Set();
22198
22284
  for (const parameter of method.value.params) {
22199
22285
  for (const decorator of parameter.decorators) {
22200
22286
  walk(decorator, context.sourceCode.visitorKeys, (current) => parameterDecoratorNodes.add(current));
22201
22287
  }
22202
22288
  }
22203
- const thisValue = (value) => {
22204
- let current = value;
22205
- while (current?.type === import_utils119.AST_NODE_TYPES.TSAsExpression || current?.type === import_utils119.AST_NODE_TYPES.TSSatisfiesExpression || current?.type === import_utils119.AST_NODE_TYPES.TSNonNullExpression) current = current.expression;
22206
- return current?.type === import_utils119.AST_NODE_TYPES.ThisExpression;
22207
- };
22208
22289
  const collectAlias = (current, nestedFunction) => {
22209
- if (nestedFunction || current.type !== import_utils119.AST_NODE_TYPES.VariableDeclarator && current.type !== import_utils119.AST_NODE_TYPES.AssignmentPattern) return;
22210
- if (current.type === import_utils119.AST_NODE_TYPES.VariableDeclarator && (current.parent.type !== import_utils119.AST_NODE_TYPES.VariableDeclaration || current.parent.kind !== "const")) return;
22211
- const binding = current.type === import_utils119.AST_NODE_TYPES.VariableDeclarator ? current.id : current.left;
22212
- const value = current.type === import_utils119.AST_NODE_TYPES.VariableDeclarator ? current.init : current.right;
22213
- if (!thisValue(value)) return;
22214
- if (binding.type === import_utils119.AST_NODE_TYPES.ObjectPattern) {
22215
- pinDestructuredMembers(binding);
22290
+ if (nestedFunction || current.type !== import_utils119.AST_NODE_TYPES.VariableDeclarator || current.init === null) return;
22291
+ const domain = receiverDomain(context, current.init, receivers, method.static);
22292
+ if (domain === null) return;
22293
+ if (current.id.type === import_utils119.AST_NODE_TYPES.ObjectPattern) {
22294
+ pinDestructuredMembers(current.id, domain);
22216
22295
  return;
22217
22296
  }
22218
- if (binding.type !== import_utils119.AST_NODE_TYPES.Identifier) return;
22219
- const variable = import_utils119.ASTUtils.findVariable(context.sourceCode.getScope(binding), binding.name);
22220
- if (variable !== null) {
22221
- methodClassVariables.add(variable);
22222
- methodAliases.add(variable);
22297
+ if (current.id.type !== import_utils119.AST_NODE_TYPES.Identifier) return;
22298
+ if (current.parent.type !== import_utils119.AST_NODE_TYPES.VariableDeclaration || current.parent.kind !== "const") {
22299
+ pinNames(null, domain);
22300
+ return;
22223
22301
  }
22302
+ const variable = context.sourceCode.getDeclaredVariables(current)[0];
22303
+ if (variable === void 0 || !stableVariable(variable)) return;
22304
+ const local = variable.references.every((reference) => {
22305
+ if (!reference.isRead()) return true;
22306
+ const expression = wrappedExpression(reference.identifier);
22307
+ return enclosingFunction5(context, reference.identifier) === methodFunction && expression.parent?.type === import_utils119.AST_NODE_TYPES.MemberExpression && expression.parent.object === expression;
22308
+ });
22309
+ if (local) receivers.set(variable, domain);
22310
+ else pinNames(null, domain);
22224
22311
  };
22225
- for (const parameter of method.value.params) {
22226
- walk(parameter, context.sourceCode.visitorKeys, collectAlias);
22227
- }
22228
- for (const statement of method.value.body.body) {
22229
- walk(statement, context.sourceCode.visitorKeys, collectAlias);
22230
- }
22231
- function pinDestructuredMembers(binding) {
22232
- for (const property of binding.properties) {
22233
- if (property.type === import_utils119.AST_NODE_TYPES.RestElement) {
22234
- for (const name of privateNames) pinned.add(name);
22235
- } else if (property.key.type === import_utils119.AST_NODE_TYPES.Identifier && privateNames.has(property.key.name)) {
22236
- pinned.add(property.key.name);
22237
- }
22238
- }
22239
- }
22312
+ for (const statement of method.value.body.body) walk(statement, context.sourceCode.visitorKeys, collectAlias);
22240
22313
  const visitCall = (current, nestedFunction) => {
22241
- if (current.type === import_utils119.AST_NODE_TYPES.VariableDeclarator && current.id.type === import_utils119.AST_NODE_TYPES.ObjectPattern && thisValue(current.init)) {
22242
- pinDestructuredMembers(current.id);
22314
+ const destructuring = receiverDestructuring(current);
22315
+ if (destructuring !== null) {
22316
+ const domain2 = receiverDomain(context, destructuring.value, receivers, method.static);
22317
+ pinDestructuredMembers(destructuring.binding, domain2);
22243
22318
  }
22244
22319
  if (current.type !== import_utils119.AST_NODE_TYPES.MemberExpression) return;
22245
- const target = referencedMethod(context, current, methodClassVariables);
22246
- if (target === null) {
22247
- const possibleTarget = referencedPropertyName(current);
22248
- if (possibleTarget !== null && privateNames.has(possibleTarget)) pinned.add(possibleTarget);
22320
+ const domain = receiverDomain(context, current.object, receivers, method.static);
22321
+ const targetName = referencedPropertyName(current);
22322
+ if (domain === null) {
22323
+ pinNames(targetName);
22249
22324
  return;
22250
22325
  }
22251
- if (!privateNames.has(target)) return;
22252
- const objectVariable = current.object.type === import_utils119.AST_NODE_TYPES.Identifier ? import_utils119.ASTUtils.findVariable(context.sourceCode.getScope(current.object), current.object.name) : null;
22253
- if (objectVariable !== null && methodAliases.has(objectVariable)) {
22254
- pinned.add(target);
22326
+ if (targetName === null) {
22327
+ if (current.computed) pinNames(null, domain);
22255
22328
  return;
22256
22329
  }
22257
- if (current.computed || nestedFunction || parameterDecoratorNodes.has(current) || current.parent.type !== import_utils119.AST_NODE_TYPES.CallExpression || current.parent.callee !== current) {
22330
+ const target = methodKey(targetName, domain);
22331
+ if (!methodKeys.has(target)) return;
22332
+ if (current.computed || nestedFunction || parameterDecoratorNodes.has(current)) {
22258
22333
  pinned.add(target);
22259
22334
  return;
22260
22335
  }
22261
- const callees = calls.get(caller) ?? /* @__PURE__ */ new Set();
22262
- callees.add(target);
22263
- calls.set(caller, callees);
22336
+ const count = localCallCount(context, current, methodFunction);
22337
+ if (count === null) {
22338
+ pinned.add(target);
22339
+ } else if (count > 0) {
22340
+ const callees = calls.get(caller) ?? /* @__PURE__ */ new Set();
22341
+ callees.add(target);
22342
+ calls.set(caller, callees);
22343
+ }
22264
22344
  };
22265
- for (const decorator of method.decorators) {
22266
- walk(decorator, context.sourceCode.visitorKeys, visitCall, true);
22267
- }
22345
+ for (const decorator of method.decorators) walk(decorator, context.sourceCode.visitorKeys, visitCall, true);
22268
22346
  if (method.computed) walk(method.key, context.sourceCode.visitorKeys, visitCall, true);
22269
- for (const parameter of method.value.params) {
22270
- walk(parameter, context.sourceCode.visitorKeys, visitCall);
22271
- }
22272
- for (const statement of method.value.body.body) {
22273
- walk(statement, context.sourceCode.visitorKeys, visitCall);
22274
- }
22347
+ for (const parameter of method.value.params) walk(parameter, context.sourceCode.visitorKeys, visitCall);
22348
+ for (const statement of method.value.body.body) walk(statement, context.sourceCode.visitorKeys, visitCall);
22275
22349
  }
22276
22350
  for (const method of methods) collectMethodCalls(method);
22277
22351
  for (const member of node.body.body) {
22278
22352
  if (member.type === import_utils119.AST_NODE_TYPES.MethodDefinition || member.type === import_utils119.AST_NODE_TYPES.TSAbstractMethodDefinition) continue;
22279
22353
  walk(member, context.sourceCode.visitorKeys, (current) => {
22280
22354
  if (current.type !== import_utils119.AST_NODE_TYPES.MemberExpression) return;
22281
- const target = referencedMethod(context, current, classVariables);
22282
- const possibleTarget = target ?? referencedPropertyName(current);
22283
- if (possibleTarget !== null && privateNames.has(possibleTarget)) pinned.add(possibleTarget);
22355
+ pinNames(referencedPropertyName(current));
22284
22356
  });
22285
22357
  }
22286
- for (const name of privateNames) if (computedReferenceNames.has(name)) pinned.add(name);
22358
+ for (const definition of definitions) {
22359
+ if (computedReferenceNames.has(definition.name)) pinned.add(definition.key);
22360
+ }
22287
22361
  const memberIndexes = new Map(node.body.body.map((member, index) => [member, index]));
22288
22362
  const runtimeBarrierPrefix = [0];
22289
22363
  for (const member of node.body.body) {
@@ -22297,6 +22371,27 @@ function classScope(context, node, computedReferenceNames) {
22297
22371
  };
22298
22372
  reportMisordered(context, definitions, scopeDefinitions, calls, pinned, canMove);
22299
22373
  }
22374
+ function classReceiverBindings(context, node) {
22375
+ const classReceivers = /* @__PURE__ */ new Map();
22376
+ if (node.id !== null) {
22377
+ const internal = import_utils119.ASTUtils.findVariable(context.sourceCode.getScope(node), node.id.name);
22378
+ if (internal !== null && stableVariable(internal)) classReceivers.set(internal, true);
22379
+ }
22380
+ if (node.type === import_utils119.AST_NODE_TYPES.ClassExpression && node.parent.type === import_utils119.AST_NODE_TYPES.VariableDeclarator && node.parent.id.type === import_utils119.AST_NODE_TYPES.Identifier && node.parent.parent.type === import_utils119.AST_NODE_TYPES.VariableDeclaration && node.parent.parent.kind === "const") {
22381
+ const outer = import_utils119.ASTUtils.findVariable(context.sourceCode.getScope(node.parent), node.parent.id.name);
22382
+ if (outer !== null && stableVariable(outer)) classReceivers.set(outer, true);
22383
+ }
22384
+ return classReceivers;
22385
+ }
22386
+ function receiverDestructuring(node) {
22387
+ if (node.type === import_utils119.AST_NODE_TYPES.VariableDeclarator && node.id.type === import_utils119.AST_NODE_TYPES.ObjectPattern && node.init !== null) {
22388
+ return { binding: node.id, value: node.init };
22389
+ }
22390
+ if ((node.type === import_utils119.AST_NODE_TYPES.AssignmentPattern || node.type === import_utils119.AST_NODE_TYPES.AssignmentExpression) && node.left.type === import_utils119.AST_NODE_TYPES.ObjectPattern) {
22391
+ return { binding: node.left, value: node.right };
22392
+ }
22393
+ return null;
22394
+ }
22300
22395
  function isClassRuntimeBarrier(member) {
22301
22396
  switch (member.type) {
22302
22397
  case import_utils119.AST_NODE_TYPES.StaticBlock:
@@ -22347,12 +22442,18 @@ function classMethodCounts(body2, methods) {
22347
22442
  const counts = /* @__PURE__ */ new Map();
22348
22443
  for (const method of methods) {
22349
22444
  const name = methodName2(method);
22350
- if (name !== null) counts.set(name, (counts.get(name) ?? 0) + 1);
22445
+ if (name !== null) {
22446
+ const key = methodKey(name, method.static);
22447
+ counts.set(key, (counts.get(key) ?? 0) + 1);
22448
+ }
22351
22449
  }
22352
22450
  for (const member of body2.body) {
22353
22451
  if (member.type !== import_utils119.AST_NODE_TYPES.TSAbstractMethodDefinition) continue;
22354
22452
  const name = !member.computed && member.key.type === import_utils119.AST_NODE_TYPES.Identifier ? member.key.name : null;
22355
- if (name !== null) counts.set(name, (counts.get(name) ?? 0) + 1);
22453
+ if (name !== null) {
22454
+ const key = methodKey(name, member.static);
22455
+ counts.set(key, (counts.get(key) ?? 0) + 1);
22456
+ }
22356
22457
  }
22357
22458
  return counts;
22358
22459
  }
@@ -22685,14 +22786,14 @@ function importedAssertionKind(specifier) {
22685
22786
  // src/rules/sole-export-matches-filename.ts
22686
22787
  var import_utils121 = require("@typescript-eslint/utils");
22687
22788
  var SOLE_EXPORT_MATCHES_FILENAME_DOCUMENTATION = {
22688
- defaultLevel: "warning",
22789
+ defaultLevel: "error",
22689
22790
  summary: "Make a module filename reflect its sole named public runtime export.",
22690
22791
  rationale: "When a module owns one runtime responsibility, matching names make that responsibility directly discoverable.",
22691
- remediation: "Name the module for the exported responsibility, using either the full export name or a clear leading or trailing domain phrase; otherwise colocate genuinely related exports.",
22792
+ remediation: "Name the module for the exported responsibility, using the full kebab-case export name; otherwise colocate genuinely related exports.",
22692
22793
  category: "maintainability",
22693
22794
  limitations: [
22694
- "Framework entrypoints, generic stems covered by no-generic-single-export-module, tests, generated files, anonymous defaults, CommonJS, and re-exports are excluded.",
22695
- "The rule compares the primary filename stem and preserves a single private underscore prefix and conventional suffixes such as .server or .worker. A leading or trailing export-name phrase is accepted only at token boundaries; multi-token stems also tolerate established acronym spelling such as github versus GitHub.",
22795
+ "Framework entrypoints, generic stems covered by no-generic-single-export-module, tests, generated files, anonymous defaults, CommonJS, unresolved re-exports, and emission-dependent exports are excluded.",
22796
+ "The rule compares the primary filename stem and preserves a single private underscore prefix and conventional suffixes such as .server or .worker. Supporting types do not exempt a sole runtime export; public runtime aliases count as distinct exports.",
22696
22797
  "Exported destructuring patterns are excluded rather than undercounted as public exports."
22697
22798
  ],
22698
22799
  examples: [
@@ -22701,39 +22802,16 @@ var SOLE_EXPORT_MATCHES_FILENAME_DOCUMENTATION = {
22701
22802
  ]
22702
22803
  };
22703
22804
  var EXCLUDED_STEMS = /* @__PURE__ */ new Set([
22704
- "common",
22705
22805
  "global",
22706
- "helpers",
22707
22806
  "index",
22708
22807
  "layout",
22709
22808
  "loading",
22710
22809
  "middleware",
22711
- "misc",
22712
22810
  "not-found",
22713
22811
  "page",
22714
22812
  "route",
22715
- "shared",
22716
22813
  "template",
22717
- "types",
22718
- "util",
22719
- "utils"
22720
- ]);
22721
- var WEAK_DOMAIN_TOKENS = /* @__PURE__ */ new Set([
22722
- "adapter",
22723
- "client",
22724
- "config",
22725
- "controller",
22726
- "factory",
22727
- "handler",
22728
- "manager",
22729
- "provider",
22730
- "record",
22731
- "repository",
22732
- "router",
22733
- "schema",
22734
- "service",
22735
- "store",
22736
- "worker"
22814
+ "types"
22737
22815
  ]);
22738
22816
  function stem3(filename) {
22739
22817
  const base = filename.replaceAll("\\", "/").split("/").at(-1) ?? "";
@@ -22742,34 +22820,6 @@ function stem3(filename) {
22742
22820
  function kebabCase(name) {
22743
22821
  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();
22744
22822
  }
22745
- function reflectsExportName(fileStem, exportedStem) {
22746
- if (fileStem.startsWith("_")) return false;
22747
- const visibleFileStem = fileStem.toLowerCase();
22748
- const fileTokens = visibleFileStem.split("-").filter(Boolean);
22749
- const exportTokens = exportedStem.split("-").filter(Boolean);
22750
- if (fileTokens.length === 0 || exportTokens.length === 0) return false;
22751
- if (fileTokens.length === 1) {
22752
- const [token] = fileTokens;
22753
- return token !== void 0 && token.length >= 4 && !WEAK_DOMAIN_TOKENS.has(token) && (exportTokens[0] === token || exportTokens.at(-1) === token);
22754
- }
22755
- const compactFile = fileTokens.join("");
22756
- if (compactFile.length < 6) return false;
22757
- const boundaryPhrases = /* @__PURE__ */ new Set();
22758
- for (let index = 1; index <= exportTokens.length; index += 1) {
22759
- boundaryPhrases.add(exportTokens.slice(0, index).join(""));
22760
- boundaryPhrases.add(exportTokens.slice(-index).join(""));
22761
- }
22762
- return boundaryPhrases.has(compactFile);
22763
- }
22764
- function declarationExport(statement) {
22765
- const declaration = statement.declaration;
22766
- if (declaration === null || declaration.declare === true) return [];
22767
- if (declaration.type === import_utils121.AST_NODE_TYPES.ClassDeclaration || declaration.type === import_utils121.AST_NODE_TYPES.FunctionDeclaration || declaration.type === import_utils121.AST_NODE_TYPES.TSEnumDeclaration) return declaration.id === null ? [] : [{ name: declaration.id.name, node: declaration }];
22768
- if (declaration.type !== import_utils121.AST_NODE_TYPES.VariableDeclaration) return [];
22769
- return declaration.declarations.flatMap(
22770
- (item) => item.id.type === import_utils121.AST_NODE_TYPES.Identifier ? [{ name: item.id.name, node: item }] : []
22771
- );
22772
- }
22773
22823
  var sole_export_matches_filename_default = createRule({
22774
22824
  name: "sole-export-matches-filename",
22775
22825
  documentation: SOLE_EXPORT_MATCHES_FILENAME_DOCUMENTATION,
@@ -22785,64 +22835,24 @@ var sole_export_matches_filename_default = createRule({
22785
22835
  create(context) {
22786
22836
  const fileStem = stem3(context.filename);
22787
22837
  const normalizedFilename = context.filename.replaceAll("\\", "/");
22788
- if (EXCLUDED_STEMS.has(fileStem) || /(?:^|\/)app\/(?:.*\/)?(?:global-)?error\.[jt]sx?$/u.test(normalizedFilename) || normalizedFilename.includes("/pages/") || context.filename.endsWith(".d.ts") || isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
22838
+ if (EXCLUDED_STEMS.has(fileStem) || GENERIC_MODULE_STEMS.has(fileStem) || /(?:^|\/)app\/(?:.*\/)?(?:global-)?error\.[jt]sx?$/u.test(normalizedFilename) || normalizedFilename.includes("/pages/") || context.filename.endsWith(".d.ts") || isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
22839
+ let hasCommonJsExport = false;
22789
22840
  return {
22841
+ "CallExpression, MemberExpression"(node) {
22842
+ if (isCommonJsExportReference(node, context.sourceCode)) hasCommonJsExport = true;
22843
+ },
22790
22844
  "Program:exit"(program) {
22791
- const exports2 = [];
22792
- const publicExports = /* @__PURE__ */ new Set();
22793
- function collectPublicExport(statement) {
22794
- if (statement.type === import_utils121.AST_NODE_TYPES.ExportAllDeclaration || statement.type === import_utils121.AST_NODE_TYPES.ExportNamedDeclaration && statement.source !== null) return false;
22795
- if (statement.type === import_utils121.AST_NODE_TYPES.ExportDefaultDeclaration) {
22796
- publicExports.add("default");
22797
- const declaration = statement.declaration;
22798
- if ((declaration.type === import_utils121.AST_NODE_TYPES.ClassDeclaration || declaration.type === import_utils121.AST_NODE_TYPES.FunctionDeclaration) && declaration.id !== null) exports2.push({ name: declaration.id.name, node: declaration });
22799
- else return false;
22800
- }
22801
- if (statement.type !== import_utils121.AST_NODE_TYPES.ExportNamedDeclaration) return true;
22802
- return collectNamedExport(statement);
22803
- }
22804
- function collectNamedExport(statement) {
22805
- const declaration = statement.declaration;
22806
- if (declaration !== null && "id" in declaration && declaration.id?.type === import_utils121.AST_NODE_TYPES.Identifier) {
22807
- publicExports.add(declaration.id.name);
22808
- }
22809
- if (declaration?.type === import_utils121.AST_NODE_TYPES.VariableDeclaration) {
22810
- if (declaration.declarations.some((item) => item.id.type !== import_utils121.AST_NODE_TYPES.Identifier)) return false;
22811
- for (const item of declaration.declarations) {
22812
- if (item.id.type === import_utils121.AST_NODE_TYPES.Identifier) publicExports.add(item.id.name);
22813
- }
22814
- }
22815
- for (const specifier of statement.specifiers) {
22816
- const exported = specifier.exported.type === import_utils121.AST_NODE_TYPES.Identifier ? specifier.exported.name : specifier.exported.value;
22817
- publicExports.add(String(exported));
22818
- }
22819
- if (statement.exportKind === "type") return true;
22820
- exports2.push(...declarationExport(statement));
22821
- collectRuntimeSpecifiers(statement);
22822
- return true;
22823
- }
22824
- function collectRuntimeSpecifiers(statement) {
22825
- for (const specifier of statement.specifiers) {
22826
- const exported = specifier.exported.type === import_utils121.AST_NODE_TYPES.Identifier ? specifier.exported.name : specifier.exported.value;
22827
- publicExports.add(String(exported));
22828
- if (specifier.exportKind === "type") continue;
22829
- if (exported === "default") exports2.push({ name: specifier.local.name, node: specifier });
22830
- else exports2.push({ name: String(exported), node: specifier });
22831
- }
22832
- }
22833
- for (const statement of program.body) {
22834
- if (!collectPublicExport(statement)) return;
22835
- }
22836
- const unique = new Map(exports2.map((item) => [item.name, item]));
22837
- if (unique.size !== 1 || publicExports.size !== 1) return;
22838
- const only = [...unique.values()][0];
22845
+ if (hasCommonJsExport) return;
22846
+ const exports2 = runtimeExports(program);
22847
+ if (exports2.ambiguous || exports2.exports.length !== 1) return;
22848
+ const only = exports2.exports[0];
22839
22849
  if (only === void 0) return;
22840
22850
  if (only.name === "onRouterTransitionStart" && /(?:^|\/)instrumentation-client\.[jt]s$/u.test(normalizedFilename)) return;
22841
22851
  if (only.name === "collections" && /(?:^|\/)src\/content\.config\.(?:ts|js|mjs)$/u.test(normalizedFilename) && program.body.some((statement) => statement.type === import_utils121.AST_NODE_TYPES.ImportDeclaration && statement.source.value === "astro:content")) return;
22842
22852
  const exportedStem = kebabCase(only.name);
22843
22853
  if (exportedStem === "") return;
22844
22854
  const expected = `${fileStem.startsWith("_") ? "_" : ""}${exportedStem}`;
22845
- if (expected === fileStem.toLowerCase() || reflectsExportName(fileStem, exportedStem)) return;
22855
+ if (expected === fileStem.toLowerCase()) return;
22846
22856
  context.report({ node: only.node, messageId: "matchSoleExport", data: { exported: only.name, expected } });
22847
22857
  }
22848
22858
  };
@@ -23057,7 +23067,7 @@ var chainMemberNames2 = (node) => {
23057
23067
  names.reverse();
23058
23068
  return names;
23059
23069
  };
23060
- var unwrapExpression7 = (node) => {
23070
+ var unwrapExpression8 = (node) => {
23061
23071
  let current = node;
23062
23072
  while (current.type === import_utils122.AST_NODE_TYPES.TSAsExpression || current.type === import_utils122.AST_NODE_TYPES.TSSatisfiesExpression || current.type === import_utils122.AST_NODE_TYPES.TSNonNullExpression || current.type === import_utils122.AST_NODE_TYPES.TSTypeAssertion) {
23063
23073
  current = current.expression;
@@ -23108,7 +23118,7 @@ var require_pascal_case_zod_schema_name_default = createRule({
23108
23118
  return binding !== null && schemaBindings.has(binding);
23109
23119
  }
23110
23120
  function isConfirmedSchema(expression) {
23111
- const init = unwrapExpression7(expression);
23121
+ const init = unwrapExpression8(expression);
23112
23122
  if (init.type === import_utils122.AST_NODE_TYPES.Identifier) return isSchemaBinding(init);
23113
23123
  if (init.type !== import_utils122.AST_NODE_TYPES.CallExpression || init.callee.type !== import_utils122.AST_NODE_TYPES.MemberExpression) {
23114
23124
  return false;
@@ -23153,7 +23163,7 @@ var require_pascal_case_zod_schema_name_default = createRule({
23153
23163
  }
23154
23164
  });
23155
23165
 
23156
- // src/rules/_renames.ts
23166
+ // src/rules/_renamed-rules.ts
23157
23167
  var RENAMED_RULES = {
23158
23168
  "jsdoc-restates-signature": "no-restated-jsdoc",
23159
23169
  "zod-naming-convention": "require-pascal-case-zod-schema-name",
@@ -23162,7 +23172,7 @@ var RENAMED_RULES = {
23162
23172
  "trailing-value-narration": "no-trailing-value-narration"
23163
23173
  };
23164
23174
 
23165
- // src/rules/_retired.ts
23175
+ // src/rules/_retired-rules.ts
23166
23176
  var RETIRED_RULES = {
23167
23177
  "ban-loose-type-guards-in-tests": {
23168
23178
  removedIn: "5.0.0",
@@ -23354,7 +23364,7 @@ var RULES = {
23354
23364
  };
23355
23365
  var meta = {
23356
23366
  name: "@sarj/eslint-plugin",
23357
- version: "15.28.0"
23367
+ version: "16.0.0"
23358
23368
  };
23359
23369
  var APPLICATION_ONLY_RULES = [];
23360
23370
  var LIBRARY_IMPORT_POLICY = ["error", {
@@ -23379,8 +23389,7 @@ var ADVISORY_RULES = [
23379
23389
  "@sarj/prefer-whole-object-assertion",
23380
23390
  "@sarj/require-camelcase-properties",
23381
23391
  "@sarj/require-interface-for-exported-class",
23382
- "@sarj/require-sql-access-class",
23383
- "@sarj/sole-export-matches-filename"
23392
+ "@sarj/require-sql-access-class"
23384
23393
  ];
23385
23394
  var RECOMMENDED_RULES = {
23386
23395
  "@sarj/no-conditional-empty-object-spread": "error",
@@ -23492,7 +23501,7 @@ var RECOMMENDED_RULES = {
23492
23501
  "@sarj/store-insert-requires-on-conflict": "error",
23493
23502
  "@sarj/stepdown": "error",
23494
23503
  "@sarj/source-coupled-test": "error",
23495
- "@sarj/sole-export-matches-filename": "warn",
23504
+ "@sarj/sole-export-matches-filename": "error",
23496
23505
  "@sarj/test-phase-label-comment": "error",
23497
23506
  "@sarj/require-pascal-case-zod-schema-name": "error"
23498
23507
  };
@@ -23610,7 +23619,7 @@ var STRICT_RULES = {
23610
23619
  "@sarj/store-insert-requires-on-conflict": "error",
23611
23620
  "@sarj/stepdown": "error",
23612
23621
  "@sarj/source-coupled-test": "error",
23613
- "@sarj/sole-export-matches-filename": "warn",
23622
+ "@sarj/sole-export-matches-filename": "error",
23614
23623
  "@sarj/test-phase-label-comment": "error",
23615
23624
  "@sarj/require-pascal-case-zod-schema-name": "error"
23616
23625
  };
@@ -23633,7 +23642,7 @@ var PLUGIN = {
23633
23642
  };
23634
23643
  }
23635
23644
  };
23636
- var index_default = PLUGIN;
23645
+ var src_default = PLUGIN;
23637
23646
  // Annotate the CommonJS export names for ESM import in node:
23638
23647
  0 && (module.exports = {
23639
23648
  ADVISORY_RULES,