UNPKG

dependency-cruiser-fork

Version:

Validate and visualize dependencies. With your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.

173 lines (159 loc) 4.37 kB
/* eslint-disable complexity */ /* eslint-disable max-lines-per-function */ const _uniqBy = require("lodash/uniqBy"); const _spread = require("lodash/spread"); const _concat = require("lodash/concat"); const pathToPosix = require("../utl/path-to-posix"); const getDependencies = require("./get-dependencies"); const gatherInitialSources = require("./gather-initial-sources"); const clearCaches = require("./clear-caches"); /* eslint max-params:0 */ function extractRecursive( pFileName, pCruiseOptions, pVisited, pDepth, pResolveOptions, pTranspileOptions ) { pVisited.add(pFileName); const extractDeps = getDependencies( pFileName, pCruiseOptions, pResolveOptions, pTranspileOptions ); const lDependencies = pCruiseOptions.maxDepth <= 0 || pDepth < pCruiseOptions.maxDepth ? extractDeps.dependencies : []; const lFunctionDeclarations = pCruiseOptions.maxDepth <= 0 || pDepth < pCruiseOptions.maxDepth ? extractDeps.functionDeclarations : []; const lCallExpressions = pCruiseOptions.maxDepth <= 0 || pDepth < pCruiseOptions.maxDepth ? extractDeps.callExpressions : []; return lDependencies .filter( (pDependency) => pDependency.followable && !pDependency.matchesDoNotFollow ) .reduce( (pAll, pDependency) => { if (!pVisited.has(pDependency.resolved)) { return pAll.concat( extractRecursive( pDependency.resolved, pCruiseOptions, pVisited, pDepth + 1, pResolveOptions, pTranspileOptions ) ); } return pAll; }, [ { source: pathToPosix(pFileName), dependencies: lDependencies, functionDeclarations: lFunctionDeclarations, callExpressions: lCallExpressions, }, ] ); } function extractFileDirectoryArray( pFileDirectoryArray, pCruiseOptions, pResolveOptions, pTranspileOptions ) { let lVisited = new Set(); return _spread(_concat)( gatherInitialSources(pFileDirectoryArray, pCruiseOptions).reduce( (pDependencies, pFilename) => { if (!lVisited.has(pFilename)) { lVisited.add(pFilename); return pDependencies.concat( extractRecursive( pFilename, pCruiseOptions, lVisited, 0, pResolveOptions, pTranspileOptions ) ); } return pDependencies; }, [] ) ); } function isNotFollowable(pToDependency) { return !pToDependency.followable; } function notInFromListAlready(pFromList) { return (pToListItem) => !pFromList.some( (pFromListItem) => pFromListItem.source === pToListItem.resolved ); } function toDependencyToSource(pToListItem) { return { source: pToListItem.resolved, followable: pToListItem.followable, coreModule: pToListItem.coreModule, couldNotResolve: pToListItem.couldNotResolve, matchesDoNotFollow: pToListItem.matchesDoNotFollow, dependencyTypes: pToListItem.dependencyTypes, dependencies: [], }; } function complete(pAll, pFromListItem) { return pAll .concat(pFromListItem) .concat( pFromListItem.dependencies .filter(isNotFollowable) .filter(notInFromListAlready(pAll)) .map(toDependencyToSource) ); } function filterExcludedDynamicDependencies(pModule, pExclude) { // no need to do the 'path' thing as that was addressed in extractFileDirectoryArray already return { ...pModule, dependencies: pModule.dependencies.filter( (pDependency) => !Object.prototype.hasOwnProperty.call(pExclude, "dynamic") || pExclude.dynamic !== pDependency.dynamic ), }; } module.exports = ( pFileDirectoryArray, pCruiseOptions, pResolveOptions, pTranspileOptions ) => { clearCaches(); const lReturnValue = _uniqBy( extractFileDirectoryArray( pFileDirectoryArray, pCruiseOptions, pResolveOptions, pTranspileOptions ).reduce(complete, []), (pModule) => pModule.source ).map((pModule) => filterExcludedDynamicDependencies(pModule, pCruiseOptions.exclude) ); pResolveOptions.fileSystem.purge(); clearCaches(); return lReturnValue; };