import { exec } from "child_process" ; import { readJson } from "fs-extra" ; import glob from "glob-promise" ; import { resolve } from "path" ; import { getMonoRepo } from "./mono-repo" ; import { MonoRepo , Package , VersionSpec } from "./types" ; param { string } currentDir returns { Promise < Object [ ] > } export const getPackages = async ( currentDir ) : Promise < Package [ ] > => { const monoRepo = await getMonoRepo ( currentDir ) ; if ( ! monoRepo ) { return [ ] ; } const packageGlobs = monoRepo . workspaces . map ( x => resolve ( monoRepo . __dir , x , "package.json" ) ) ; const globResults = await Promise . all ( packageGlobs . map ( g => glob ( g ) ) ) ; const workspaceFilePaths = globResults . reduce ( ( acc , next ) => [ ... acc , ... next ] , [ ] ) . filter ( x => ! x . includes ( "node_modules" ) ) ; const packages = await Promise . all ( workspaceFilePaths . map ( ( x ) : Promise < Package > => readJson ( x ) ) ) ; return packages . map ( ( x , i ) : Package => ( { ... x , __dir : workspaceFilePaths [ i ] . replace ( "/package.json" , "" ) } ) ) ; } ; param { Objectp [ ] } packages param { string } filter returns { Object [ ] } export const filterPackages = ( packages , filter ) : Package [ ] => { const filterParts = filter . split ( "," ) ; const packageNames = filterParts . filter ( f => ! f . includes ( "*" ) ) ; const packageWildcards = filterParts . filter ( f => f . includes ( "*" ) ) ; if ( packageWildcards . includes ( "*" ) ) { return packages ; } return Array . from ( new Set ( [ ... packages . filter ( p => packageNames . includes ( p . name ) ) , ... packages . filter ( p => packageWildcards . find ( w => p . name . startsWith ( w . substring ( 0 , w . length - 1 ) ) ) ) , ] ) ) ; } ; param { string } nameWithMaybeVersion returns { string } export const getPackageName = ( nameWithMaybeVersion ) : string => { const isScoped = nameWithMaybeVersion . startsWith ( "@" ) ; const strippedScopeNameWithMaybeVersion = isScoped ? nameWithMaybeVersion . substring ( 1 ) : nameWithMaybeVersion ; const [ name ] = strippedScopeNameWithMaybeVersion . split ( "@" ) ; return isScoped ? `@${ name }` : name ; } ; param { string } nameWithMaybeVersion param { Object [ ] } localPackages returns { Pbject } export const getPackageVersion = async ( nameWithMaybeVersion , localPackages ) : Promise < VersionSpec > => { const isScoped = nameWithMaybeVersion . startsWith ( "@" ) ; const strippedScopeNameWithMaybeVersion = isScoped ? nameWithMaybeVersion . substring ( 1 ) : nameWithMaybeVersion ; const [ , version ] = strippedScopeNameWithMaybeVersion . split ( "@" ) ; if ( ! version ) { const packageName = getPackageName ( nameWithMaybeVersion ) ; const localPackage = localPackages . find ( p => p . name === packageName ) ; if ( localPackage ) { return Promise . resolve ( { modifier : "^" , version : localPackage . version } ) ; } const runner = exec ( `npm show ${ packageName } version` ) ; return new Promise ( ( res , rej ) : void => { runner . stdout . on ( "data" , ( out ) => { res ( { modifier : "^" , version : out . trim ( ) } ) ; } ) ; runner . on ( "exit" , code => { if ( code !== 0 ) { rej ( new Error ( `NPM package '${ packageName }' does not exist` ) ) ; } } ) ; } ) ; } const match = /\d/ . exec ( version ) ; const hasNoModifier = match && match . index === 0 ; return { modifier : hasNoModifier ? "" : version . substring ( 0 , 1 ) , version : hasNoModifier ? version : version . substring ( 1 ) } ; } ;