UNPKG

eslint-plugin-esm

Version:
56 lines 8.06 kB
import path from "node:path"; import process from "node:process"; import { createRule, getRuleName, getSourceType } from "../common.js"; /** * Key is the source file, value is its imports. */ const store = new Map(); function isCircular(currentFile, visited = new Set()) { if (visited.has(currentFile)) { return [true, [...visited]]; } visited.add(currentFile); const dependencies = store.get(currentFile) ?? new Set(); for (const dependency of dependencies) { const [isCircularResult, circularPaths] = isCircular(path.resolve(path.dirname(currentFile), dependency), new Set(visited)); if (isCircularResult) { return [isCircularResult, circularPaths]; } } return [false, []]; } /** * Note: This rule do not support importing files without extensions and directory imports. */ export const noCircularImports = createRule({ name: getRuleName(import.meta.url), message: "Circular imports are not allowed.", create: (context) => { const filePath = context.filename; const imports = store.get(filePath) ?? new Set(); store.set(filePath, imports); return { ImportDeclaration: (node) => { if (typeof node.source.value !== "string" || getSourceType(node.source.value) !== "local") return; imports.add(node.source.value); }, "ImportDeclaration:exit": (node) => { if (typeof node.source.value !== "string" || getSourceType(node.source.value) !== "local") return; const [isCircularResult, circularPaths] = isCircular(path.resolve(path.dirname(filePath), node.source.value), new Set([filePath])); if (isCircularResult) { context.report({ node, message: `Circular import detected: ${circularPaths .map((p) => path.relative(process.cwd(), p)) .join(" -> ")}`, }); } }, }; }, }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tY2lyY3VsYXItaW1wb3J0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9uby1jaXJjdWxhci1pbXBvcnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sSUFBSSxNQUFNLFdBQVcsQ0FBQztBQUM3QixPQUFPLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDbkMsT0FBTyxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsYUFBYSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRXRFOztHQUVHO0FBQ0gsTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQXVCLENBQUM7QUFFN0MsU0FBUyxVQUFVLENBQ2pCLFdBQW1CLEVBQ25CLFVBQVUsSUFBSSxHQUFHLEVBQVU7SUFFM0IsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7UUFDN0IsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBQ0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUV6QixNQUFNLFlBQVksR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxJQUFJLElBQUksR0FBRyxFQUFVLENBQUM7SUFDakUsS0FBSyxNQUFNLFVBQVUsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUN0QyxNQUFNLENBQUMsZ0JBQWdCLEVBQUUsYUFBYSxDQUFDLEdBQUcsVUFBVSxDQUNsRCxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLEVBQUUsVUFBVSxDQUFDLEVBQ25ELElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUNqQixDQUFDO1FBQ0YsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3JCLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSxhQUFhLENBQUMsQ0FBQztRQUMzQyxDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDckIsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUcsVUFBVSxDQUFDO0lBQzFDLElBQUksRUFBRSxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7SUFDbEMsT0FBTyxFQUFFLG1DQUFtQztJQUM1QyxNQUFNLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRTtRQUNsQixNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDO1FBQ2xDLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksSUFBSSxHQUFHLEVBQVUsQ0FBQztRQUN6RCxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUU3QixPQUFPO1lBQ0wsaUJBQWlCLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRTtnQkFDMUIsSUFDRSxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxLQUFLLFFBQVE7b0JBQ3JDLGFBQWEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLE9BQU87b0JBRTVDLE9BQU87Z0JBQ1QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2pDLENBQUM7WUFFRCx3QkFBd0IsRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFO2dCQUNqQyxJQUNFLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEtBQUssUUFBUTtvQkFDckMsYUFBYSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssT0FBTztvQkFFNUMsT0FBTztnQkFFVCxNQUFNLENBQUMsZ0JBQWdCLEVBQUUsYUFBYSxDQUFDLEdBQUcsVUFBVSxDQUNsRCxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFDdkQsSUFBSSxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUNwQixDQUFDO2dCQUNGLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztvQkFDckIsT0FBTyxDQUFDLE1BQU0sQ0FBQzt3QkFDYixJQUFJO3dCQUNKLE9BQU8sRUFBRSw2QkFBNkIsYUFBYTs2QkFDaEQsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQzs2QkFDM0MsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFO3FCQUNsQixDQUFDLENBQUM7Z0JBQ0wsQ0FBQztZQUNILENBQUM7U0FDRixDQUFDO0lBQ0osQ0FBQztDQUNGLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCBwcm9jZXNzIGZyb20gXCJub2RlOnByb2Nlc3NcIjtcbmltcG9ydCB7IGNyZWF0ZVJ1bGUsIGdldFJ1bGVOYW1lLCBnZXRTb3VyY2VUeXBlIH0gZnJvbSBcIi4uL2NvbW1vbi50c1wiO1xuXG4vKipcbiAqIEtleSBpcyB0aGUgc291cmNlIGZpbGUsIHZhbHVlIGlzIGl0cyBpbXBvcnRzLlxuICovXG5jb25zdCBzdG9yZSA9IG5ldyBNYXA8c3RyaW5nLCBTZXQ8c3RyaW5nPj4oKTtcblxuZnVuY3Rpb24gaXNDaXJjdWxhcihcbiAgY3VycmVudEZpbGU6IHN0cmluZyxcbiAgdmlzaXRlZCA9IG5ldyBTZXQ8c3RyaW5nPigpLFxuKTogW2Jvb2xlYW4sIHN0cmluZ1tdXSB7XG4gIGlmICh2aXNpdGVkLmhhcyhjdXJyZW50RmlsZSkpIHtcbiAgICByZXR1cm4gW3RydWUsIFsuLi52aXNpdGVkXV07XG4gIH1cbiAgdmlzaXRlZC5hZGQoY3VycmVudEZpbGUpO1xuXG4gIGNvbnN0IGRlcGVuZGVuY2llcyA9IHN0b3JlLmdldChjdXJyZW50RmlsZSkgPz8gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGZvciAoY29uc3QgZGVwZW5kZW5jeSBvZiBkZXBlbmRlbmNpZXMpIHtcbiAgICBjb25zdCBbaXNDaXJjdWxhclJlc3VsdCwgY2lyY3VsYXJQYXRoc10gPSBpc0NpcmN1bGFyKFxuICAgICAgcGF0aC5yZXNvbHZlKHBhdGguZGlybmFtZShjdXJyZW50RmlsZSksIGRlcGVuZGVuY3kpLFxuICAgICAgbmV3IFNldCh2aXNpdGVkKSxcbiAgICApO1xuICAgIGlmIChpc0NpcmN1bGFyUmVzdWx0KSB7XG4gICAgICByZXR1cm4gW2lzQ2lyY3VsYXJSZXN1bHQsIGNpcmN1bGFyUGF0aHNdO1xuICAgIH1cbiAgfVxuICByZXR1cm4gW2ZhbHNlLCBbXV07XG59XG5cbi8qKlxuICogTm90ZTogVGhpcyBydWxlIGRvIG5vdCBzdXBwb3J0IGltcG9ydGluZyBmaWxlcyB3aXRob3V0IGV4dGVuc2lvbnMgYW5kIGRpcmVjdG9yeSBpbXBvcnRzLlxuICovXG5leHBvcnQgY29uc3Qgbm9DaXJjdWxhckltcG9ydHMgPSBjcmVhdGVSdWxlKHtcbiAgbmFtZTogZ2V0UnVsZU5hbWUoaW1wb3J0Lm1ldGEudXJsKSxcbiAgbWVzc2FnZTogXCJDaXJjdWxhciBpbXBvcnRzIGFyZSBub3QgYWxsb3dlZC5cIixcbiAgY3JlYXRlOiAoY29udGV4dCkgPT4ge1xuICAgIGNvbnN0IGZpbGVQYXRoID0gY29udGV4dC5maWxlbmFtZTtcbiAgICBjb25zdCBpbXBvcnRzID0gc3RvcmUuZ2V0KGZpbGVQYXRoKSA/PyBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBzdG9yZS5zZXQoZmlsZVBhdGgsIGltcG9ydHMpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIEltcG9ydERlY2xhcmF0aW9uOiAobm9kZSkgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgdHlwZW9mIG5vZGUuc291cmNlLnZhbHVlICE9PSBcInN0cmluZ1wiIHx8XG4gICAgICAgICAgZ2V0U291cmNlVHlwZShub2RlLnNvdXJjZS52YWx1ZSkgIT09IFwibG9jYWxcIlxuICAgICAgICApXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICBpbXBvcnRzLmFkZChub2RlLnNvdXJjZS52YWx1ZSk7XG4gICAgICB9LFxuXG4gICAgICBcIkltcG9ydERlY2xhcmF0aW9uOmV4aXRcIjogKG5vZGUpID0+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHR5cGVvZiBub2RlLnNvdXJjZS52YWx1ZSAhPT0gXCJzdHJpbmdcIiB8fFxuICAgICAgICAgIGdldFNvdXJjZVR5cGUobm9kZS5zb3VyY2UudmFsdWUpICE9PSBcImxvY2FsXCJcbiAgICAgICAgKVxuICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBjb25zdCBbaXNDaXJjdWxhclJlc3VsdCwgY2lyY3VsYXJQYXRoc10gPSBpc0NpcmN1bGFyKFxuICAgICAgICAgIHBhdGgucmVzb2x2ZShwYXRoLmRpcm5hbWUoZmlsZVBhdGgpLCBub2RlLnNvdXJjZS52YWx1ZSksXG4gICAgICAgICAgbmV3IFNldChbZmlsZVBhdGhdKSxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGlzQ2lyY3VsYXJSZXN1bHQpIHtcbiAgICAgICAgICBjb250ZXh0LnJlcG9ydCh7XG4gICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgbWVzc2FnZTogYENpcmN1bGFyIGltcG9ydCBkZXRlY3RlZDogJHtjaXJjdWxhclBhdGhzXG4gICAgICAgICAgICAgIC5tYXAoKHApID0+IHBhdGgucmVsYXRpdmUocHJvY2Vzcy5jd2QoKSwgcCkpXG4gICAgICAgICAgICAgIC5qb2luKFwiIC0+IFwiKX1gLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH07XG4gIH0sXG59KTtcbiJdfQ==