Fix accidental relative imports from non namespace barrels (#59544)

This commit is contained in:
Jake Bailey
2024-08-08 09:38:10 -07:00
committed by GitHub
parent 1f54d0a935
commit 5e9e6ad295
6 changed files with 113 additions and 26 deletions

View File

@@ -0,0 +1,81 @@
const { createRule } = require("./utils.cjs");
const path = require("path");
/** @import { TSESTree } from "@typescript-eslint/utils" */
void 0;
module.exports = createRule({
name: "no-direct-import",
meta: {
docs: {
description: ``,
},
messages: {
noDirectImport: `This import relatively references another project; did you mean to import from a local _namespace module?`,
},
schema: [],
type: "problem",
},
defaultOptions: [],
create(context) {
const containingFileName = context.filename;
const containingDirectory = path.dirname(containingFileName);
/** @type {(node: TSESTree.ImportDeclaration | TSESTree.TSImportEqualsDeclaration) => void} */
const check = node => {
let source;
if (node.type === "TSImportEqualsDeclaration") {
const moduleReference = node.moduleReference;
if (
moduleReference.type === "TSExternalModuleReference"
&& moduleReference.expression.type === "Literal"
&& typeof moduleReference.expression.value === "string"
) {
source = moduleReference.expression;
}
}
else {
source = node.source;
}
if (!source) return;
const p = source.value;
// These appear in place of public API imports.
if (p.endsWith("../typescript/typescript.js")) return;
// The below is similar to https://github.com/microsoft/DefinitelyTyped-tools/blob/main/packages/eslint-plugin/src/rules/no-bad-reference.ts
// Any relative path that goes to the wrong place will contain "..".
if (!p.includes("..")) return;
const parts = p.split("/");
let cwd = containingDirectory;
for (const part of parts) {
if (part === "" || part === ".") {
continue;
}
if (part === "..") {
cwd = path.dirname(cwd);
}
else {
cwd = path.join(cwd, part);
}
if (path.basename(cwd) === "src") {
context.report({
messageId: "noDirectImport",
node: source,
});
}
}
};
return {
ImportDeclaration: check,
TSImportEqualsDeclaration: check,
};
},
});