import type { Capability , KitType } from "@rnx-kit/config" ; import type { PackageManifest } from "@rnx-kit/tools-node/package" ; import omit from "lodash/omit" ; import semver from "semver" ; import { resolveCapabilities } from "./capabilities" ; import type { DependencyType , Package , Profile } from "./types" ; export function devOnlyPackages ( packages ) { return Object . keys ( packages ) . reduce < Record < string , Package [ ] > > ( ( result , name ) => { const versions = packages [ name ] ; if ( versions . some ( ( pkg ) => Boolean ( pkg . devOnly ) ) ) { result [ name ] = versions ; } return result ; } , { } ) ; } export function removeKeys ( obj , keys ) { if ( ! obj ) { return obj ; } return omit ( obj , ... keys ) ; } export function updateDependencies ( dependencies = { } , packages , dependencyType , nodeVersion = process . versions . node ) { const packageNames = Object . keys ( packages ) ; if ( packageNames . length === 0 ) { return dependencies ; } const makeVersionRange = ( ( ) => { switch ( dependencyType ) { case "direct" : return ( versions ) => versions [ versions . length - 1 ] . version ; case "development" : return ( versions ) => versions [ 0 ] . version ; case "peer" : return ( versions ) => versions . map ( ( pkg ) => pkg . version ) . join ( " || " ) ; } } ) ( ) ; const shouldBeAdded = ( pkg ) => ! pkg . devOnly || dependencyType === "development" ; if ( semver . satisfies ( nodeVersion , ">=11" ) ) { const entries = packageNames . reduce ( ( result , dependency ) => { const packageRange = packages [ dependency ] ; if ( shouldBeAdded ( packageRange [ 0 ] ) ) { result . push ( [ dependency , makeVersionRange ( packageRange ) ] ) ; } return result ; } , Object . entries ( dependencies ) ) ; return Object . fromEntries ( entries . sort ( ( [ a ] , [ b ] ) => a . localeCompare ( b ) ) ) ; } else { const copy = packageNames . reduce ( ( result , dependency ) => { const packageRange = packages [ dependency ] ; if ( shouldBeAdded ( packageRange [ 0 ] ) ) { result [ dependency ] = makeVersionRange ( packageRange ) ; } return result ; } , { ... dependencies } ) ; return Object . keys ( copy ) . sort ( ) . reduce < Record < string , string > > ( ( result , dependency ) => { result [ dependency ] = copy [ dependency ] ; return result ; } , { } ) ; } } param manifest param capabilities param profiles param devProfiles param packageType returns export function updatePackageManifest ( manifest , capabilities , profiles , devProfiles , packageType ) { const { dependencies , peerDependencies , devDependencies } = manifest ; const packages = resolveCapabilities ( capabilities , profiles ) ; const names = Object . keys ( packages ) ; switch ( packageType ) { case "app" : return { ... manifest , dependencies : updateDependencies ( dependencies , packages , "direct" ) , peerDependencies : removeKeys ( peerDependencies , names ) , devDependencies : updateDependencies ( removeKeys ( devDependencies , names ) , devOnlyPackages ( packages ) , "development" ) } ; case "library" : return { ... manifest , dependencies : removeKeys ( dependencies , names ) , peerDependencies : updateDependencies ( peerDependencies , packages , "peer" ) , devDependencies : updateDependencies ( devDependencies , resolveCapabilities ( capabilities , devProfiles ) , "development" ) } ; } }