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
JavaScript
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 = {}));
;