99 fetchPackagePackument ,
1010 readPackageJson
1111} from '@socketsecurity/registry/lib/packages'
12+ import { naturalCompare } from '@socketsecurity/registry/lib/sorts'
1213
1314import {
1415 getBaseGitBranch ,
@@ -60,16 +61,16 @@ type InstallOptions = {
6061}
6162
6263async function install (
63- idealTree : SafeNode ,
64+ arb : SafeArborist ,
6465 options : InstallOptions
65- ) : Promise < void > {
66+ ) : Promise < SafeNode > {
6667 const { cwd = process . cwd ( ) } = {
6768 __proto__ : null ,
6869 ...options
6970 } as InstallOptions
70- const arb = new Arborist ( { path : cwd } )
71- arb . idealTree = idealTree
72- await arb . reify ( )
71+ const newArb = new Arborist ( { path : cwd } )
72+ newArb . idealTree = await arb . buildIdealTree ( )
73+ return await newArb . reify ( )
7374}
7475
7576export async function npmFix (
@@ -95,12 +96,14 @@ export async function npmFix(
9596 spinner ?. start ( )
9697
9798 const { pkgPath : rootPath } = pkgEnvDetails
99+
98100 const arb = new SafeArborist ( {
99101 path : rootPath ,
100102 ...SAFE_ARBORIST_REIFY_OPTIONS_OVERRIDES
101103 } )
102- // Calling arb.reify() creates the arb.diff object and nulls-out arb.idealTree.
103- await arb . reify ( )
104+ // Calling arb.reify() creates the arb.diff object, nulls-out arb.idealTree,
105+ // and populates arb.actualTree.
106+ let actualTree = await arb . reify ( )
104107
105108 const alertsMap = purls . length
106109 ? await getAlertsMapFromPurls ( purls , getAlertMapOptions ( { limit } ) )
@@ -129,7 +132,10 @@ export async function npmFix(
129132 spinner ?. stop ( )
130133
131134 let count = 0
132- infoByPkgNameLoop: for ( const { 0 : name , 1 : infos } of infoByPkgName ) {
135+ const sortedInfoEntries = [ ...infoByPkgName . entries ( ) ] . sort ( ( a , b ) =>
136+ naturalCompare ( a [ 0 ] , b [ 0 ] )
137+ )
138+ infoByPkgNameLoop: for ( const { 0 : name , 1 : infos } of sortedInfoEntries ) {
133139 logger . log ( `Processing vulnerable package: ${ name } ` )
134140 logger . indent ( )
135141 spinner ?. indent ( )
@@ -159,12 +165,11 @@ export async function npmFix(
159165
160166 logger . log ( `Checking workspace: ${ workspaceName } ` )
161167
162- arb . idealTree = null
163168 // eslint-disable-next-line no-await-in-loop
164- await arb . buildIdealTree ( )
169+ actualTree = await install ( arb , { cwd } )
165170
166171 const oldVersions = arrayUnique (
167- findPackageNodes ( arb . idealTree ! , name )
172+ findPackageNodes ( actualTree , name )
168173 . map ( n => n . target ?. version ?? n . version )
169174 . filter ( Boolean )
170175 )
@@ -174,7 +179,7 @@ export async function npmFix(
174179 `Unexpected condition: Lockfile entries not found for ${ name } .\n`
175180 )
176181 if ( isDebug ( ) ) {
177- console . dir ( arb . idealTree ! , { depth : 999 } )
182+ console . dir ( actualTree , { depth : 999 } )
178183 }
179184 continue
180185 }
@@ -190,7 +195,7 @@ export async function npmFix(
190195 const oldId = `${ name } @${ oldVersion } `
191196 const oldPurl = idToPurl ( oldId )
192197
193- const node = findPackageNode ( arb . idealTree ! , name , oldVersion )
198+ const node = findPackageNode ( actualTree , name , oldVersion )
194199 if ( ! node ) {
195200 logger . warn (
196201 `Unexpected condition: Arborist node not found, skipping ${ oldId } `
@@ -238,7 +243,8 @@ export async function npmFix(
238243 updateNode ( node , newVersion , newVersionPackument )
239244 updatePackageJsonFromNode (
240245 editablePkgJson ,
241- arb . idealTree ! ,
246+ // eslint-disable-next-line no-await-in-loop
247+ await arb . buildIdealTree ( ) ,
242248 node ,
243249 newVersion ,
244250 rangeStyle
@@ -261,7 +267,7 @@ export async function npmFix(
261267 let errored = false
262268 try {
263269 // eslint-disable-next-line no-await-in-loop
264- await install ( arb . idealTree ! , { cwd } )
270+ actualTree = await install ( arb , { cwd } )
265271 if ( test ) {
266272 spinner ?. info ( `Testing ${ newId } in ${ workspaceName } ` )
267273 // eslint-disable-next-line no-await-in-loop
@@ -358,8 +364,6 @@ export async function npmFix(
358364 if ( isCi ) {
359365 // eslint-disable-next-line no-await-in-loop
360366 await gitResetAndClean ( baseBranch , cwd )
361- // eslint-disable-next-line no-await-in-loop
362- await install ( arb . idealTree ! , { cwd } )
363367 }
364368 if ( errored ) {
365369 if ( ! isCi ) {
@@ -369,8 +373,6 @@ export async function npmFix(
369373 removeNodeModules ( cwd ) ,
370374 editablePkgJson . save ( { ignoreWhitespace : true } )
371375 ] )
372- // eslint-disable-next-line no-await-in-loop
373- await install ( arb . idealTree ! , { cwd } )
374376 }
375377 spinner ?. failAndStop (
376378 `Update failed for ${ oldId } in ${ workspaceName } ` ,
0 commit comments