import * as path from 'path' ; import { PackageJsonLookup } from '@rushstack/node-core-library' ; import globby from 'globby' ; import type { GlobbyOptions } from 'globby' ; import pMap from 'p-map' ; import { errorLog } from '../log/error' ; import { Package } from '../package' ; const normalize = ( results ) => results . map ( ( fp ) => path . normalize ( fp ) ) ; const getGlobOpts = ( rootPath , packageConfigs , ignore = [ ] ) : GlobbyOptions => { const globOpts = { cwd : rootPath , absolute : true , expandDirectories : false , followSymbolicLinks : false , } ; if ( packageConfigs . some ( ( cfg ) => cfg . includes ( '**' ) ) ) { if ( packageConfigs . some ( ( cfg ) => cfg . includes ( 'node_modules' ) ) ) { errorLog ( 'An explicit node_modules package path does not allow globstars (**)' ) ; } globOpts . ignore = [ '**/dist/**' , '**/node_modules/**' , ... ( ignore || [ ] ) , ] ; } return globOpts ; } ; const makeFileFinder = ( rootPath , packageConfigs , ignoreConfigs = [ ] ) => { const globOpts = getGlobOpts ( rootPath , packageConfigs , ignoreConfigs ) ; return async < FileMapperType > ( fileName , fileMapper , customGlobOpts = { } ) => { const options = { ... customGlobOpts , ... globOpts } ; const promise = pMap ( Array . from ( packageConfigs ) . sort ( ) , async ( globPath ) => { let result = await globby ( path . posix . join ( globPath , fileName ) , options ) ; result = result . sort ( ) ; result = normalize ( result ) ; return fileMapper ( result ) ; } , { concurrency : packageConfigs . length || Infinity } ) ; const results = await promise ; return results . reduce ( ( acc , result ) => acc . concat ( result ) , [ ] ) ; } ; } ; export const getProjetsByPackageConfig = async ( rootPath , packagesConfig , ignoreConfigs ) => { const finder = makeFileFinder ( rootPath , packagesConfig , ignoreConfigs ) ; const fileName = 'package.json' ; const mapper = ( packageConfigPath ) => { const packageJsonLookup = new PackageJsonLookup ( { loadExtraFields : true } ) ; const packageJson = packageJsonLookup . loadNodePackageJson ( packageConfigPath ) ; return new Package ( packageJson , path . dirname ( packageConfigPath ) , rootPath ) ; } ; const projects = await finder ( fileName , filePaths => pMap ( filePaths , mapper , { concurrency : filePaths . length || Infinity } ) , { } ) ; return projects ; } ; const makeSyncFileFinder = ( rootPath , packageConfigs , ignoreConfigs = [ ] ) => { const globOpts = getGlobOpts ( rootPath , packageConfigs , ignoreConfigs ) ; return < FileMapperType > ( fileName , fileMapper , customGlobOpts = { } ) => { const results = [ ] ; const options = { ... customGlobOpts , ... globOpts } ; for ( const globPath of Array . from ( packageConfigs ) . sort ( ) ) { let result = globby . sync ( path . posix . join ( globPath , fileName ) , options ) ; result = result . sort ( ) ; result = normalize ( result ) ; results . push ( fileMapper ( result ) ) ; } return results . reduce ( ( acc , result ) => acc . concat ( result ) , [ ] ) ; } ; } ; export const syncGetProjetsByPackageConfig = ( rootPath , packagesConfig , ignoreConfigs ) => { const finder = makeSyncFileFinder ( rootPath , packagesConfig , ignoreConfigs ) ; const fileName = 'package.json' ; const mapper = ( packageConfigPath ) => { const packageJsonLookup = new PackageJsonLookup ( { loadExtraFields : true } ) ; const packageJson = packageJsonLookup . loadNodePackageJson ( packageConfigPath ) ; return new Package ( packageJson , path . dirname ( packageConfigPath ) , rootPath ) ; } ; const projects = finder ( fileName , filePaths => filePaths . map ( filePath => mapper ( filePath ) ) , { } ) ; return projects ; } ;