@@ -24,11 +24,13 @@ import * as CDX from '@cyclonedx/cyclonedx-library'
2424import  {  Compilation ,  type  Compiler ,  sources ,  version  as  WEBPACK_VERSION  }  from  'webpack' 
2525
2626import  { 
27+   doComponentsMatch , 
2728  getPackageDescription , 
2829  iterableSome , 
2930  loadJsonFile , 
3031  normalizePackageManifest , 
31-   type  PackageDescription 
32+   type  PackageDescription , 
33+   type  RootComponentCreationResult 
3234}  from  './_helpers' 
3335import  {  Extractor  }  from  './extractor' 
3436
@@ -214,7 +216,8 @@ export class CycloneDxWebpackPlugin {
214216
215217    const  bom  =  new  CDX . Models . Bom ( ) 
216218    bom . metadata . lifecycles . add ( CDX . Enums . LifecyclePhase . Build ) 
217-     bom . metadata . component  =  this . #makeRootComponent( compilation . compiler . context ,  cdxComponentBuilder ,  logger . getChildLogger ( 'RootComponentBuilder' ) ) 
219+     const  rootComponents  =  this . #makeRootComponent( compilation . compiler . context ,  cdxComponentBuilder ,  logger . getChildLogger ( 'RootComponentBuilder' ) ) 
220+     bom . metadata . component  =  rootComponents ?. rootComponent 
218221
219222    const  serializeOptions : CDX . Serialize . Types . SerializerOptions  &  CDX . Serialize . Types . NormalizerOptions  =  { 
220223      sortLists : this . reproducibleResults , 
@@ -267,11 +270,9 @@ export class CycloneDxWebpackPlugin {
267270        ) 
268271
269272        thisLogger . log ( 'generating components...' ) 
270-         for  ( const  component  of  extractor . generateComponents ( modules ,  this . collectEvidence ,  thisLogger . getChildLogger ( 'Extractor' ) ) )  { 
273+         for  ( const  component  of  extractor . generateComponents ( modules ,  this . collectEvidence ,  rootComponents ,   thisLogger . getChildLogger ( 'Extractor' ) ) )  { 
271274          if  ( bom . metadata . component  !==  undefined  && 
272-             bom . metadata . component . group  ===  component . group  && 
273-             bom . metadata . component . name  ===  component . name  && 
274-             bom . metadata . component . version  ===  component . version 
275+             doComponentsMatch ( bom . metadata . component ,  component ) 
275276          )  { 
276277            // metadata matches this exact component. 
277278            // -> so the component is actually treated as the root component. 
@@ -380,19 +381,33 @@ export class CycloneDxWebpackPlugin {
380381    path : string , 
381382    builder : CDX . Builders . FromNodePackageJson . ComponentBuilder , 
382383    logger : WebpackLogger 
383-   ) : CDX . Models . Component  |  undefined  { 
384+   ) : RootComponentCreationResult  |  undefined  { 
384385    /* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- expected */ 
385-     const  thisPackageJson  =  this . rootComponentAutodetect 
386-       ? getPackageDescription ( path ) ?. packageJson 
387-       : {  name : this . rootComponentName ,  version : this . rootComponentVersion  } 
388-     if  ( thisPackageJson  ===  undefined )  {  return  undefined  } 
386+     const  detectedRootPackageJson  =  getPackageDescription ( path ) ?. packageJson 
387+     /* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- expected */ 
388+     const  rootPackageJson  =  this . rootComponentAutodetect  ? detectedRootPackageJson 
389+                               : {  name : this . rootComponentName ,  version : this . rootComponentVersion  } 
390+ 
391+     if  ( rootPackageJson  ===  undefined )  {  return  undefined  } 
389392    normalizePackageManifest ( 
390-        
391-       thisPackageJson , 
393+       rootPackageJson , 
392394      w  =>  {  logger . debug ( 'normalizePackageJson from PkgPath' ,  path ,  'caused:' ,  w )  } 
393395    ) 
394-      
395-     return  builder . makeComponent ( thisPackageJson ) 
396+ 
397+     if  ( detectedRootPackageJson  !==  rootPackageJson )  { 
398+       normalizePackageManifest ( 
399+         detectedRootPackageJson , 
400+         w  =>  {  logger . debug ( 'normalizePackageJson from PkgPath' ,  path ,  'caused:' ,  w )  } 
401+       ) 
402+     } 
403+ 
404+     const  rootComponent  =  builder . makeComponent ( rootPackageJson ) 
405+     if ( rootComponent  ===  undefined )  {  return  undefined  } 
406+ 
407+     const  detectedRootComponent  =  detectedRootPackageJson  ===  rootPackageJson  ? rootComponent 
408+                                 /* eslint-disable-next-line @typescript-eslint/no-unsafe-argument -- expected */ 
409+                                 : builder . makeComponent ( detectedRootPackageJson ) 
410+     return  {  rootComponent,  detectedRootComponent } 
396411  } 
397412
398413  #finalizeBom ( 
0 commit comments