UNPKG

tslint-folders

Version:

Custom TSLint rules for checking imports between packages and their folders, and generating relevant diagrams.

206 lines (205 loc) 9.81 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ImportRuleUtils = exports.PathSource = void 0; var AbsoluteImportResolver_1 = require("./AbsoluteImportResolver"); var DirUtils_1 = require("./DirUtils"); var GeneralRuleUtils_1 = require("./GeneralRuleUtils"); var PackageConfigHelper_1 = require("./PackageConfigHelper"); var PathSource; (function (PathSource) { PathSource[PathSource["SourceFilePath"] = 0] = "SourceFilePath"; PathSource[PathSource["ImportText"] = 1] = "ImportText"; })(PathSource = exports.PathSource || (exports.PathSource = {})); var ImportRuleUtils; (function (ImportRuleUtils) { ImportRuleUtils.IS_DEBUG_ENABLED = false; function determinePackageLocationFromPath(filePath, ruleId, config, pathSource, tsConfig, thisPackageLocation) { if (ImportRuleUtils.IS_DEBUG_ENABLED) { console.log("\nchecking ".concat(PathSource[pathSource], " against path:"), filePath); } var _a = determinePackageName(config, filePath, pathSource, tsConfig), packageName = _a[0], dirs = _a[1]; if (packageName === null || (pathSource === PathSource.SourceFilePath && !PackageConfigHelper_1.PackageConfigHelper.hasPackage(config, packageName))) { return { packageName: filePath, }; } var packageFolderAndName = determinePackageFolderAndName(config, dirs, filePath, thisPackageLocation, packageName, pathSource, ruleId); packageName = packageFolderAndName.packageName; if (!packageFolderAndName.packageFolder) { return { packageName: packageName, }; } if (packageFolderAndName.packageFolder.subFolders.length === 0) { return { packageName: packageName, packageFolder: packageFolderAndName.packageFolder, }; } return determinePackageLocationWithSubFolder(dirs, packageName, packageFolderAndName.packageFolder, pathSource); } ImportRuleUtils.determinePackageLocationFromPath = determinePackageLocationFromPath; // TODO xxx review - too many params! function determinePackageFolderAndName(config, dirs, filePath, thisPackageLocation, packageName, pathSource, ruleId) { var activePackageName = packageName; var packageFolder; if (pathSource === PathSource.ImportText && isRelativeImport(dirs[0])) { if (!thisPackageLocation) { throw new Error("for path source = ImportText - expect thisPackageLocation to be set"); } // assumption: we are importing from 'this' package // (assuming is not ..'ing back into other package! - that would require 'virtual directories') packageFolder = thisPackageLocation.packageFolder; } else { try { packageFolder = PackageConfigHelper_1.PackageConfigHelper.getPackage(config, packageName); } catch (error) { GeneralRuleUtils_1.GeneralRuleUtils.buildFailureString("unexpected: import had a recognised package: [".concat(packageName, "] but could not find the PackageFolder in the config"), ruleId); packageFolder = undefined; activePackageName = filePath; } } return { packageFolder: packageFolder, packageName: activePackageName, }; } function determinePackageName(config, filePath, pathSource, tsConfig) { var packageName = null; var dirs = []; var clearedFilePath = DirUtils_1.DirUtils.cleanPath(filePath); switch (pathSource) { case PathSource.ImportText: { // take the biggest part known to be a package: var lastSlashIndex = Infinity; while (lastSlashIndex !== -1) { var head = clearedFilePath.substring(0, lastSlashIndex); if (PackageConfigHelper_1.PackageConfigHelper.hasPackage(config, head)) { dirs.unshift(head); break; } var slashIndex = clearedFilePath.lastIndexOf("/", lastSlashIndex - 1); var part = clearedFilePath.substring(slashIndex + 1, lastSlashIndex); dirs.unshift(part); lastSlashIndex = slashIndex; } // (ignore local directories that happen to have same name as a package) packageName = dirs[0]; } break; case PathSource.SourceFilePath: { dirs = clearedFilePath.split("/"); var pathName = AbsoluteImportResolver_1.AbsoluteImportResolver.resolvePathToPackageName(filePath, tsConfig, config); if (pathName && PackageConfigHelper_1.PackageConfigHelper.hasPackage(config, pathName)) { // take the 1st recognised folder: packageName = pathName; } break; } default: { throw new Error("unhandled PathSource ".concat(pathSource)); } } return [packageName, dirs]; } function determinePackageLocationWithSubFolder(dirs, packageName, packageFolder, pathSource) { var packageSubFolder; var activePackageName = packageName; switch (pathSource) { case PathSource.ImportText: { // take the 1st part of the path: // (ignore local directories that happen to have same name as a package) activePackageName = dirs[0]; var isImportingFromSubFolder = isRelativeImport(dirs[0]); if (isImportingFromSubFolder) { var _loop_1 = function (i) { var subFolder = packageFolder.subFolders.find(function (folder) { return folder.importPath === dirs[i]; }); if (subFolder) { packageSubFolder = subFolder; activePackageName = subFolder.importPath; return "break"; } }; for (var i = 1; i < dirs.length; i++) { var state_1 = _loop_1(i); if (state_1 === "break") break; } } } break; case PathSource.SourceFilePath: { var hasPackageDir_1 = false; dirs.forEach(function (dir) { if (packageSubFolder) { return; } if (packageFolder.importPath === dir) { hasPackageDir_1 = true; return; } { if (hasPackageDir_1) { var subFolder = packageFolder.subFolders.find(function (folder) { return folder.importPath === dir; }); if (subFolder) { packageSubFolder = subFolder; return; } } } }); break; } default: { throw new Error("unhandled PathSource ".concat(pathSource)); } } return { packageName: activePackageName, packageFolder: packageFolder, packageSubFolder: packageSubFolder, }; } function isRelativeImport(pathDir) { return pathDir === "." || pathDir === ".."; } ImportRuleUtils.isRelativeImport = isRelativeImport; function isThisPackageThirdParty(thisFolderLocation, node) { if (isPackageThirdParty(thisFolderLocation)) { if (ImportRuleUtils.IS_DEBUG_ENABLED) { console.log(node.getSourceFile().fileName, "- this package ThirdParty!", thisFolderLocation.packageName); } return true; } return false; } ImportRuleUtils.isThisPackageThirdParty = isThisPackageThirdParty; function isPackageThirdParty(folderLocation) { return !folderLocation.packageFolder && !folderLocation.packageSubFolder; } ImportRuleUtils.isPackageThirdParty = isPackageThirdParty; function logPackageAndImport(node, thisPackageLocation, importPackageLocation) { if (ImportRuleUtils.IS_DEBUG_ENABLED) { console.log(node.getSourceFile().fileName, "- this package:", thisPackageLocation.packageName, getPackageName(thisPackageLocation.packageFolder), "- import:", importPackageLocation.packageName, getPackageName(importPackageLocation.packageFolder)); } } ImportRuleUtils.logPackageAndImport = logPackageAndImport; function getPackageName(packageFolder) { return packageFolder ? packageFolder.importPath : "(unknown)"; } function shouldIgnoreFile(node, ignorePaths) { var filePath = node.getSourceFile().fileName; return shouldIgnorePath(filePath, ignorePaths); } ImportRuleUtils.shouldIgnoreFile = shouldIgnoreFile; function shouldIgnorePath(path, ignorePaths) { return ignorePaths.some(function (ignore) { return path.indexOf(ignore) >= 0; }); } ImportRuleUtils.shouldIgnorePath = shouldIgnorePath; })(ImportRuleUtils = exports.ImportRuleUtils || (exports.ImportRuleUtils = {}));