UNPKG

eslint-plugin-export-scope

Version:

Don't leak LOCAL utils, states, components into the global scope

106 lines 5.18 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.checkIsImportable = exports.SCOPE_JS_FILE_NAME = exports.SCOPE_TS_FILE_NAME = void 0; const path_1 = __importDefault(require("path")); const typescript_1 = require("typescript"); const utils_1 = require("./utils"); const tsUtils_1 = require("./tsPlugin/tsUtils"); exports.SCOPE_TS_FILE_NAME = ".scope.ts"; exports.SCOPE_JS_FILE_NAME = ".scope.js"; const checkIsImportable = ({ tsProgram, importPath, exportPath, exportName, }) => { if (!importPath || !exportPath || exportPath.includes("node_modules")) return true; const exportFile = tsProgram.getSourceFile(exportPath); const exportDir = path_1.default.dirname(exportPath); let scope; if (!exportFile) return true; const isIndexFile = path_1.default.parse(exportFile.fileName).name === "index"; getLocalScope: { if (!exportName) break getLocalScope; const typeChecker = tsProgram.getTypeChecker(); const fileSymbol = typeChecker.getSymbolAtLocation(exportFile); const exports = fileSymbol && typeChecker.getExportsOfModule(fileSymbol); let exportSymbol = exports?.find((x) => x.name === exportName); if (!exportSymbol) break getLocalScope; if (exportName !== "default" && exportSymbol.flags & typescript_1.SymbolFlags.Alias) { exportSymbol = typeChecker.getImmediateAliasedSymbol(exportSymbol); } const jsDocTags = exportSymbol?.getJsDocTags(); if (!jsDocTags) break getLocalScope; for (const tag of jsDocTags) { if (tag.name === "scopeException") { const exception = tag.text?.at(0)?.text; if (!exception) continue; const exceptionFullPath = (0, utils_1.getFullScopePath)(exportDir, exception); if (exceptionFullPath && (0, utils_1.isSubPath)(exceptionFullPath, importPath)) { return true; } } if (tag.name === "scope") { scope = tag.text?.at(0)?.text; } } } getFileScope: { if (scope) break getFileScope; const firstStatementEndIndex = exportFile.statements[0]?.getEnd() ?? -1; const fileComments = exportFile.getFullText().slice(0, firstStatementEndIndex); [, scope] = fileComments.match(/@scopeDefault\s+([^\s]+)/) ?? []; } getFolderScope: { if (scope) break getFolderScope; let scopeFile = tsProgram.getSourceFile(path_1.default.join(exportDir, exports.SCOPE_TS_FILE_NAME)); scopeFile ?? (scopeFile = tsProgram.getSourceFile(path_1.default.join(exportDir, exports.SCOPE_JS_FILE_NAME))); if (isIndexFile) { const parentDir = path_1.default.dirname(exportDir); scopeFile ?? (scopeFile = tsProgram.getSourceFile(path_1.default.join(parentDir, exports.SCOPE_TS_FILE_NAME))); scopeFile ?? (scopeFile = tsProgram.getSourceFile(path_1.default.join(parentDir, exports.SCOPE_JS_FILE_NAME))); } if (!scopeFile) { const rootDir = (0, utils_1.getRootDir)(exportDir); if (rootDir) { scopeFile ?? (scopeFile = tsProgram.getSourceFile(path_1.default.join(rootDir, exports.SCOPE_TS_FILE_NAME))); scopeFile ?? (scopeFile = tsProgram.getSourceFile(path_1.default.join(rootDir, exports.SCOPE_JS_FILE_NAME))); } } if (!scopeFile) break getFolderScope; const symbols = tsProgram.getTypeChecker().getSymbolAtLocation(scopeFile); const defaultExportValDecl = symbols?.exports?.get("default")?.valueDeclaration; const exceptionsValDecl = symbols?.exports?.get("exceptions")?.valueDeclaration; if ((0, tsUtils_1.isExportAssignment)(defaultExportValDecl)) { scope = defaultExportValDecl.expression.getText().slice(1, -1); } if ((0, tsUtils_1.isVariableDeclaration)(exceptionsValDecl) && (0, tsUtils_1.isArrayLiteralExpression)(exceptionsValDecl.initializer)) { const exceptions = exceptionsValDecl.initializer.elements.map((x) => x.getText()); for (const exception of exceptions) { const exceptionFullPath = (0, utils_1.getFullScopePath)(exportDir, exception.slice(1, -1)); if (!exceptionFullPath) continue; if ((0, utils_1.isSubPath)(exceptionFullPath, importPath)) { return true; } } } } // handles index files scope ?? (scope = isIndexFile ? ".." : "."); if (scope === "*") return true; const fullScopePath = (0, utils_1.getFullScopePath)(exportDir, scope); if (!fullScopePath) return true; return (0, utils_1.isSubPath)(fullScopePath, importPath); }; exports.checkIsImportable = checkIsImportable; //# sourceMappingURL=checkIsImportable.js.map