import util from 'util' ; import fs from 'fs' ; import jscodeshift from 'jscodeshift' ; import { debugConsole } from '@codemods/utils' ; import { getInternalImports } from '@codemods/get-internal-imports' ; import { getFullPath } from './getFullPath' ; import { getRelativePath } from './getRelativePath' ; import { getFilename } from './getFilename' ; const readFile = util . promisify ( fs . readFile ) ; const parser = 'tsx' ; const j = jscodeshift . withParser ( parser ) ; const empty = ( ) => { } ; const stats = ( name , quantity ) => { quantity = typeof quantity !== 'number' ? 1 : quantity ; console . log ( 'update: ' , { name , quantity } ) ; } ; const report = ( ) => { } ; const getImportsFromFile = async ( filename ) => { const content = await readFile ( filename ) ; const source = content . toString ( ) ; const options = { } ; const internalImports = getInternalImports ( { path : filename , source } , { j , jscodeshift : j , stats : options . dry ? stats : empty , report : ( msg ) => report ( file , msg ) } , options ) ; return internalImports . map ( ( i ) => getRelativePath ( filename , i . source . value ) ) ; } ; export const getSubgraph = async ( initialFile , calculateSmallestSubgraph = false ) => { const visited = { } ; visited [ initialFile ] = false ; let graph = [ initialFile ] ; let nodesToVisit = [ initialFile ] ; while ( true ) { const [ nextFile , ... rest ] = nodesToVisit ; if ( visited [ nextFile ] ) { nodesToVisit = [ ... rest ] ; } else { visited [ nextFile ] = true ; const fullpath = getFullPath ( nextFile ) ; const filename = getFilename ( fullpath ) ; if ( filename ) { const dependenciesImports = await getImportsFromFile ( filename ) ; graph = [ ... graph , ... dependenciesImports ] ; nodesToVisit = [ ... rest , ... dependenciesImports ] ; } else { nodesToVisit = [ ... rest ] ; } } if ( nodesToVisit . length === 0 ) { break ; } } if ( calculateSmallestSubgraph ) { debugConsole ( { subGraphSize : graph . length , graph } ) ; } if ( calculateSmallestSubgraph ) { if ( graph . length <= 1 ) { console . log ( 'graph is to small' ) ; return ; } const [ initial , ... relatedFiles ] = graph ; const graphs = { } ; for ( const f of relatedFiles ) { console . log ( 'processing: ' , f ) ; const subgraphForFile = await getSubgraph ( f ) ; console . log ( 'graph for f: ' , subgraphForFile . length ) ; graphs [ f ] = subgraphForFile ; } let minimalFile = relatedFiles [ 0 ] ; let min = graphs [ minimalFile ] . length ; for ( const f of relatedFiles ) { if ( graphs [ f ] . length < min ) { min = graphs [ f ] . length ; minimalFile = f ; } } debugConsole ( { minimalFile , graph : graphs [ minimalFile ] } ) ; } return graph ; } ;