@nxworker/workspace
Version:
Nx plugin providing generators for managing workspace files, including the move-file generator for safely moving files between projects while updating all imports
114 lines (113 loc) • 5.28 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "checkForUnexportedRelativeDependencies", {
enumerable: true,
get: function() {
return checkForUnexportedRelativeDependencies;
}
});
const _devkit = require("@nx/devkit");
const _nodepath = require("node:path");
const _removesourcefileextension = require("../path-utils/remove-source-file-extension");
const _isfileexported = require("../export-management/is-file-exported");
const _astcache = require("../ast-cache");
/**
* Collects all import specifiers from a file.
*
* @param tree - The virtual file system tree.
* @param filePath - Path to the file to analyze.
* @returns Array of import specifiers found in the file.
*/ function collectImportSpecifiers(tree, filePath) {
const specifiers = [];
// Get content from cache or read from tree
const content = _astcache.astCache.getContent(tree, filePath);
if (!content || content.trim().length === 0) {
return specifiers;
}
// Early exit: quick check if file contains any imports/requires at all
if (!(content.includes('import') || content.includes('require') || content.includes('export'))) {
return specifiers;
}
// Get parsed AST from cache or parse content
const root = _astcache.astCache.getAST(tree, filePath);
if (!root) {
return specifiers;
}
try {
// Filter to only relevant node types
const relevantNodes = root.find(_astcache.j.Node, (node)=>{
return _astcache.j.ImportDeclaration.check(node) || _astcache.j.ExportNamedDeclaration.check(node) || _astcache.j.ExportAllDeclaration.check(node) || _astcache.j.CallExpression.check(node);
});
relevantNodes.forEach((path)=>{
const node = path.node;
// Handle ImportDeclaration: import ... from 'specifier'
if (_astcache.j.ImportDeclaration.check(node)) {
const source = node.source.value;
if (typeof source === 'string') {
specifiers.push(source);
}
} else if (_astcache.j.ExportNamedDeclaration.check(node)) {
if (node.source && typeof node.source.value === 'string') {
specifiers.push(node.source.value);
}
} else if (_astcache.j.ExportAllDeclaration.check(node)) {
const source = node.source.value;
if (typeof source === 'string') {
specifiers.push(source);
}
} else if (_astcache.j.CallExpression.check(node)) {
const { callee, arguments: args } = node;
// Check if first argument is a string literal
if (args.length > 0 && _astcache.j.StringLiteral.check(args[0]) && typeof args[0].value === 'string') {
const specifier = args[0].value;
// Dynamic import: import('specifier') or require('specifier')
if (_astcache.j.Import.check(callee) || _astcache.j.Identifier.check(callee) && callee.name === 'require') {
specifiers.push(specifier);
}
}
}
});
} catch {
// If parsing fails, return empty array
return specifiers;
}
return specifiers;
}
function checkForUnexportedRelativeDependencies(tree, sourceFilePath, sourceProject, cachedTreeExists) {
const unexportedDeps = [];
const sourceRoot = sourceProject.sourceRoot || sourceProject.root;
const normalizedSourceWithoutExt = (0, _devkit.normalizePath)((0, _removesourcefileextension.removeSourceFileExtension)(sourceFilePath));
// Collect all import specifiers from the source file
const specifiers = collectImportSpecifiers(tree, sourceFilePath);
for (const specifier of specifiers){
// Only check relative imports
if (!specifier.startsWith('.')) {
continue;
}
// Resolve the import specifier to an absolute path
const sourceFileDir = _nodepath.posix.dirname(sourceFilePath);
const resolvedImport = _nodepath.posix.join(sourceFileDir, specifier);
// Normalize and compare (both without extension)
const normalizedResolvedImport = (0, _devkit.normalizePath)((0, _removesourcefileextension.removeSourceFileExtension)(resolvedImport));
// Skip self-references
if (normalizedResolvedImport === normalizedSourceWithoutExt) {
continue;
}
// Get the relative path within the source project
const relativePathInProject = _nodepath.posix.relative(sourceRoot, normalizedResolvedImport);
// Check if this dependency is exported from the source project
const isExported = (0, _isfileexported.isFileExported)(tree, sourceProject, relativePathInProject, cachedTreeExists);
// If not exported, add to the list
if (!isExported) {
unexportedDeps.push({
specifier,
resolvedPath: normalizedResolvedImport,
relativePathInProject
});
}
}
return unexportedDeps;
}
//# sourceMappingURL=check-for-unexported-relative-dependencies.js.map