@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 +386 -377
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +383 -374
- package/dist/rule-examples.cjs +4 -4
- package/dist/rule-examples.js +1 -1
- package/package.json +1 -1
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
|
|
32
|
-
__export(
|
|
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: () =>
|
|
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(
|
|
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/
|
|
7524
|
+
// src/rules/_runtime-exports.ts
|
|
7525
7525
|
var import_utils47 = require("@typescript-eslint/utils");
|
|
7526
|
-
var
|
|
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
|
|
7570
|
-
const
|
|
7538
|
+
const bindings = localBindings(program);
|
|
7539
|
+
const exports2 = /* @__PURE__ */ new Map();
|
|
7571
7540
|
let ambiguous = false;
|
|
7572
|
-
function
|
|
7573
|
-
if (
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
|
|
7580
|
-
}
|
|
7581
|
-
|
|
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
|
-
|
|
7587
|
-
|
|
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
|
-
|
|
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"
|
|
7596
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
7614
|
-
return { exports: [...unique.values()], ambiguous };
|
|
7579
|
+
return { exports: [...exports2.values()], ambiguous };
|
|
7615
7580
|
}
|
|
7616
|
-
function
|
|
7617
|
-
const
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
if (
|
|
7622
|
-
|
|
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
|
-
|
|
7648
|
-
|
|
7649
|
-
|
|
7650
|
-
|
|
7651
|
-
|
|
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
|
-
|
|
7657
|
-
|
|
7658
|
-
|
|
7659
|
-
|
|
7660
|
-
|
|
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
|
-
|
|
7665
|
-
|
|
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
|
|
7670
|
-
const
|
|
7671
|
-
|
|
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
|
|
7674
|
-
|
|
7675
|
-
|
|
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 (!
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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 :
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
20113
|
-
|
|
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
|
|
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.
|
|
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.
|
|
21972
|
-
if (pinned.has(helper.
|
|
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.
|
|
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:
|
|
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.
|
|
22128
|
+
pinned.add(definition.key);
|
|
22074
22129
|
continue;
|
|
22075
22130
|
}
|
|
22076
22131
|
if (!reference.isRead()) continue;
|
|
22077
|
-
const
|
|
22078
|
-
|
|
22079
|
-
|
|
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
|
|
22087
|
-
|
|
22088
|
-
|
|
22089
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
|
22148
|
-
|
|
22149
|
-
|
|
22150
|
-
|
|
22151
|
-
|
|
22152
|
-
if (
|
|
22153
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
22184
|
-
|
|
22185
|
-
const
|
|
22186
|
-
|
|
22187
|
-
|
|
22188
|
-
|
|
22189
|
-
|
|
22190
|
-
|
|
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
|
|
22194
|
-
if (
|
|
22195
|
-
|
|
22196
|
-
|
|
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
|
|
22210
|
-
|
|
22211
|
-
|
|
22212
|
-
|
|
22213
|
-
|
|
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 (
|
|
22219
|
-
|
|
22220
|
-
|
|
22221
|
-
|
|
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
|
|
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
|
-
|
|
22242
|
-
|
|
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
|
|
22246
|
-
|
|
22247
|
-
|
|
22248
|
-
|
|
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 (
|
|
22252
|
-
|
|
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
|
-
|
|
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
|
|
22262
|
-
|
|
22263
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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)
|
|
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)
|
|
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: "
|
|
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
|
|
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,
|
|
22695
|
-
"The rule compares the primary filename stem and preserves a single private underscore prefix and conventional suffixes such as .server or .worker.
|
|
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
|
-
|
|
22792
|
-
const
|
|
22793
|
-
|
|
22794
|
-
|
|
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()
|
|
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
|
|
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 =
|
|
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/
|
|
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: "
|
|
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": "
|
|
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": "
|
|
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
|
|
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,
|