UNPKG

ng-packagr

Version:

Compile and package Angular libraries in Angular Package Format (APF)

185 lines • 7.33 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.analyseSourcesTransform = void 0; const node_fs_1 = require("node:fs"); const node_path_1 = require("node:path"); const rxjs_1 = require("rxjs"); const typescript_1 = __importDefault(require("typescript")); const node_1 = require("../../graph/node"); const log_1 = require("../../utils/log"); const path_1 = require("../../utils/path"); const nodes_1 = require("../nodes"); exports.analyseSourcesTransform = (0, rxjs_1.pipe)((0, rxjs_1.map)(graph => { const entryPoints = graph.filter(nodes_1.isEntryPoint); const entryPointsMapped = new Map(entryPoints.map(ep => [ep.data.entryPoint.moduleId, ep])); const packageNode = (0, nodes_1.findPackageNode)(graph); const primaryModuleId = packageNode.data.primary.moduleId; for (const entryPoint of entryPoints) { if (entryPoint.state !== node_1.STATE_DONE) { analyseEntryPoint(entryPoint, entryPointsMapped, primaryModuleId); } } return graph; })); const JS_TO_TS_EXTENSIONS = { '.js': ['.ts', '.tsx', '.d.ts'], '.mjs': ['.mts', '.d.mts'], '.cjs': ['.cts', '.d.cts'], }; const RESOLUTION_EXTENSIONS = [ '.ts', '.tsx', '.mts', '.cts', '.d.ts', '.d.mts', '.d.cts', '/index.ts', '/index.tsx', '/index.mts', '/index.cts', '/index.d.ts', '/index.d.mts', '/index.d.cts', '.js', '.mjs', '.cjs', '/index.js', '/index.mjs', '/index.cjs', ]; function checkFile(filePath, fileCache) { const entry = fileCache.getOrCreate(filePath); if (entry.exists === undefined) { const stat = (0, node_fs_1.statSync)(filePath, { throwIfNoEntry: false }); if (stat?.isFile()) { entry.exists = true; } else { return false; } } return entry.exists; } function resolveRelativeSourceFile(dir, moduleName, fileCache) { const target = (0, node_path_1.resolve)(dir, moduleName); if (target.includes('/node_modules/') || target.includes('\\node_modules\\')) { return undefined; } const ext = (0, node_path_1.extname)(target); const tsExtensions = JS_TO_TS_EXTENSIONS[ext]; if (tsExtensions) { const base = target.slice(0, -ext.length); for (const tsExt of tsExtensions) { const candidate = base + tsExt; if (checkFile(candidate, fileCache)) { return (0, path_1.ensureUnixPath)(candidate); } } } if (checkFile(target, fileCache)) { return (0, path_1.ensureUnixPath)(target); } for (const suffix of RESOLUTION_EXTENSIONS) { const candidate = target + suffix; if (checkFile(candidate, fileCache)) { return (0, path_1.ensureUnixPath)(candidate); } } return undefined; } /** * Analyses an entrypoint, searching for TypeScript dependencies and internal package imports. * * @param entryPoint Current entry point that should be analysed. * @param entryPointsMapped Map of all entry points by moduleId. * @param primaryModuleId The moduleId of the primary entry point. */ function analyseEntryPoint(entryPoint, entryPointsMapped, primaryModuleId) { const { analyseSourcesFileCache } = entryPoint.cache; const { moduleId, entryFilePath } = entryPoint.data.entryPoint; (0, log_1.debug)(`Analysing sources for ${moduleId}`); // Remove previously discovered entry point dependencies in watch mode for (const dep of entryPoint.dependents) { if ((0, nodes_1.isEntryPoint)(dep)) { dep.dependees.delete(entryPoint); entryPoint.dependents.delete(dep); } } const potentialDependencies = new Set(); const filesToScan = [...(entryPoint.data.tsConfig?.rootNames ?? [entryFilePath])]; const visited = new Set(); while (filesToScan.length > 0) { const file = filesToScan.pop(); if (!file) { continue; } const currentFile = (0, path_1.ensureUnixPath)(file); if (visited.has(currentFile)) { continue; } visited.add(currentFile); const fileEntry = analyseSourcesFileCache.getOrCreate(currentFile); if (fileEntry.content === undefined) { try { fileEntry.content = (0, node_fs_1.readFileSync)(currentFile, 'utf-8'); fileEntry.exists = true; } catch { continue; } } const { importedFiles, typeReferenceDirectives, referencedFiles } = typescript_1.default.preProcessFile(fileEntry.content, true, // readImportFiles true); for (const ref of referencedFiles) { const resolvedPath = resolveRelativeSourceFile((0, node_path_1.dirname)(currentFile), ref.fileName, analyseSourcesFileCache); if (resolvedPath && !visited.has(resolvedPath)) { filesToScan.push(resolvedPath); } } for (const ref of [...importedFiles, ...typeReferenceDirectives]) { const moduleName = ref.fileName; if (moduleName[0] !== '.') { if (moduleName === primaryModuleId || moduleName.startsWith(`${primaryModuleId}/`)) { potentialDependencies.add(moduleName); } } else { const resolvedPath = resolveRelativeSourceFile((0, node_path_1.dirname)(currentFile), moduleName, analyseSourcesFileCache); if (resolvedPath && !visited.has(resolvedPath)) { filesToScan.push(resolvedPath); } } } } // If an index file parallel to the entryFilePath is imported it is not valid as index should be reserved as an // entry file of an entry-point based on node resolution strategy. if ((0, node_path_1.basename)(entryFilePath) !== 'index.ts') { const potentialIndexPath = (0, node_path_1.join)((0, node_path_1.dirname)(entryFilePath), 'index.ts'); if (visited.has((0, path_1.ensureUnixPath)(potentialIndexPath))) { throw new Error(`Entry point '${moduleId}' has an 'index.ts' parallel to the 'entryFilePath'. ` + `The 'entryFilePath' should be updated to point to the 'index.ts' file.\n` + `Full path: ${potentialIndexPath}`); } } for (const moduleName of potentialDependencies) { const dep = entryPointsMapped.get(moduleName); if (dep) { (0, log_1.debug)(`Found entry point dependency: ${moduleId} -> ${moduleName}`); if (moduleId === moduleName) { throw new Error(`Entry point ${moduleName} has a circular dependency on itself.`); } if (dep.dependents.has(entryPoint)) { throw new Error(`Entry point ${moduleName} has a circular dependency on ${moduleId}.`); } entryPoint.dependsOn(dep); } else { throw new Error(`Entry point ${moduleName} which is required by ${moduleId} doesn't exist.`); } } } //# sourceMappingURL=analyse-sources.transform.js.map