@cdxgen/cdxgen 13.5.0 → 13.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (380) hide show
  1. package/README.md +17 -10
  2. package/bin/audit.js +7 -4
  3. package/bin/cdxgen.js +260 -37
  4. package/bin/convert.js +146 -22
  5. package/bin/evinse.js +28 -3
  6. package/bin/repl.js +47 -3
  7. package/bin/sign.js +211 -34
  8. package/bin/tracebom.js +18 -6
  9. package/bin/validate.js +24 -3
  10. package/bin/verify.js +113 -5
  11. package/data/behavior-taxonomy.schema.json +1491 -0
  12. package/data/cyclonedx-2.0-bundled.schema.json +18606 -5528
  13. package/data/cyclonedx-2.0-cryptography-defs.schema.json +857 -0
  14. package/data/license-aliases.json +24 -2
  15. package/data/pqc-migration.json +239 -0
  16. package/data/remediations.json +176 -0
  17. package/data/rules/ai-bom.yaml +1 -1
  18. package/data/rules/brotli-decoder.yaml +107 -0
  19. package/data/rules/cbom-security.yaml +4 -3
  20. package/data/rules/package-integrity.yaml +28 -0
  21. package/data/rules/vscode-extensions.yaml +75 -0
  22. package/data/spdx-license-list.json +121 -7
  23. package/data/spdx-licenses.json +69 -0
  24. package/data/spdx.schema.json +845 -2
  25. package/lib/audit/index.js +25 -3
  26. package/lib/cli/bomAssembly.js +172 -4
  27. package/lib/cli/cliOptions.js +121 -17
  28. package/lib/cli/index.js +720 -902
  29. package/lib/cli/jsBom.js +156 -64
  30. package/lib/cli/jvmBom.js +602 -86
  31. package/lib/cli/managedBom.js +161 -19
  32. package/lib/cli/nativeBom.js +52 -5
  33. package/lib/core/boundedFile.js +344 -0
  34. package/lib/core/brotliProbe.js +182 -0
  35. package/lib/core/env.js +34 -0
  36. package/lib/core/fs.js +138 -3
  37. package/lib/core/globPatterns.js +218 -0
  38. package/lib/core/httpClient.js +98 -1
  39. package/lib/core/lockPaths.js +38 -0
  40. package/lib/core/paths.js +24 -1
  41. package/lib/core/processTree.js +100 -8
  42. package/lib/core/projectConfig.js +332 -25
  43. package/lib/core/toolRegistry.js +184 -0
  44. package/lib/ecosystems/cppEvidence.js +263 -106
  45. package/lib/ecosystems/cppIncludeResolver.js +16 -5
  46. package/lib/ecosystems/denoutils.js +2 -2
  47. package/lib/ecosystems/ecosystems.js +25 -10
  48. package/lib/ecosystems/gemHostProbe.js +301 -0
  49. package/lib/ecosystems/golem.js +3 -8
  50. package/lib/ecosystems/gradleutils.js +1909 -229
  51. package/lib/ecosystems/jsEvidence.js +90 -38
  52. package/lib/ecosystems/kosi.js +3 -5
  53. package/lib/ecosystems/npmVersionResolution.js +376 -0
  54. package/lib/ecosystems/parsers-bazel.js +107 -6
  55. package/lib/ecosystems/parsers-js.js +505 -22
  56. package/lib/ecosystems/parsers-misc.js +209 -20
  57. package/lib/ecosystems/parsers-python.js +178 -30
  58. package/lib/ecosystems/parsers-rust.js +117 -15
  59. package/lib/ecosystems/pythonutils.js +128 -2
  60. package/lib/ecosystems/remote/huggingface.js +22 -0
  61. package/lib/ecosystems/rubyutils.js +538 -31
  62. package/lib/ecosystems/rusi.js +2 -4
  63. package/lib/ecosystems/scalacliutils.js +2 -0
  64. package/lib/ecosystems/scalasem.js +798 -152
  65. package/lib/ecosystems/vendoredCode.js +237 -3
  66. package/lib/ecosystems/venvProbe.js +360 -0
  67. package/lib/evinser/evinser.js +536 -71
  68. package/lib/evinser/scalasem.js +5 -1
  69. package/lib/helpers/agenticToolutils.js +525 -94
  70. package/lib/helpers/bomSigner.js +43 -9
  71. package/lib/helpers/jssSigner.js +1276 -0
  72. package/lib/helpers/vsixutils.js +1574 -315
  73. package/lib/inventory/agentBlueprint.js +193 -0
  74. package/lib/inventory/agentToolNames.js +145 -0
  75. package/lib/inventory/aiCollector.js +153 -7
  76. package/lib/inventory/aiInventory.js +44 -8
  77. package/lib/inventory/aiProviders.js +324 -0
  78. package/lib/inventory/atomUtils.js +77 -0
  79. package/lib/inventory/bomUtils.js +8 -1
  80. package/lib/inventory/brotliDecoder.js +142 -0
  81. package/lib/inventory/buildToolRateLimit.js +1 -1
  82. package/lib/inventory/cbomutils.js +56 -7
  83. package/lib/inventory/ciParsers/githubActionsLock.js +821 -0
  84. package/lib/inventory/citations.js +31 -2
  85. package/lib/inventory/communityAiConfigParser.js +978 -80
  86. package/lib/inventory/cyclonedx20.js +152 -0
  87. package/lib/inventory/cyclonedx20Common.js +286 -0
  88. package/lib/inventory/cyclonedx20Derived.js +159 -0
  89. package/lib/inventory/cyclonedx20Parties.js +552 -0
  90. package/lib/inventory/cyclonedx20Read.js +768 -0
  91. package/lib/inventory/cyclonedx20ReadCommon.js +374 -0
  92. package/lib/inventory/cyclonedx20ReadComponents.js +692 -0
  93. package/lib/inventory/cyclonedx20ReadContext.js +380 -0
  94. package/lib/inventory/cyclonedx20ReadEvidence.js +466 -0
  95. package/lib/inventory/cyclonedx20ReadSections.js +599 -0
  96. package/lib/inventory/cyclonedx20Render.js +766 -0
  97. package/lib/inventory/cyclonedx20RenderComponents.js +716 -0
  98. package/lib/inventory/cyclonedx20RenderDefinitions.js +405 -0
  99. package/lib/inventory/cyclonedx20RenderEvidence.js +726 -0
  100. package/lib/inventory/cyclonedx20RenderHardware.js +203 -0
  101. package/lib/inventory/cyclonedx20RenderPatents.js +174 -0
  102. package/lib/inventory/cyclonedx20RenderRefIds.js +314 -0
  103. package/lib/inventory/cyclonedx20RenderSections.js +499 -0
  104. package/lib/inventory/cyclonedx20Tables.js +594 -0
  105. package/lib/inventory/deps.js +141 -13
  106. package/lib/inventory/dosai.js +375 -6
  107. package/lib/inventory/dosaiParsers.js +3 -6
  108. package/lib/inventory/dotnetRuntime.js +367 -0
  109. package/lib/inventory/ecosystemFormulationParsers.js +979 -0
  110. package/lib/inventory/envcontext.js +436 -48
  111. package/lib/inventory/evidenceUtils.js +13 -1
  112. package/lib/inventory/fetchBatch.js +1 -1
  113. package/lib/inventory/formulationParsers.js +124 -14
  114. package/lib/inventory/gtfobins.js +13 -0
  115. package/lib/inventory/hbom.js +45 -6
  116. package/lib/inventory/hbomLoader.js +166 -0
  117. package/lib/inventory/hostRuntimeProbe.js +686 -0
  118. package/lib/inventory/jvmLocalRepos.js +9 -2
  119. package/lib/inventory/jvmToolEnv.js +29 -0
  120. package/lib/inventory/licenseEnhancer.js +12 -0
  121. package/lib/inventory/mavenCentralMirror.js +534 -0
  122. package/lib/inventory/mcpConfigParser.js +5 -0
  123. package/lib/inventory/nodeBuildInfo.js +218 -0
  124. package/lib/inventory/nodeHostProbe.js +202 -0
  125. package/lib/inventory/occurrenceKey.js +90 -0
  126. package/lib/inventory/osPackageResolver.js +182 -0
  127. package/lib/inventory/phpBuildInfo.js +10 -59
  128. package/lib/inventory/phpHostProbe.js +32 -488
  129. package/lib/inventory/pqcMigration.js +426 -0
  130. package/lib/inventory/rubyBuildInfo.js +972 -0
  131. package/lib/inventory/rubyHostProbe.js +218 -0
  132. package/lib/inventory/rustFormulationParser.js +21 -10
  133. package/lib/inventory/scalaCoords.js +4 -3
  134. package/lib/inventory/scalaDedupe.js +440 -0
  135. package/lib/inventory/source.js +114 -8
  136. package/lib/managers/binary.js +337 -3
  137. package/lib/managers/docker.js +79 -0
  138. package/lib/parsers/huggingfaceManifest.js +9 -1
  139. package/lib/parsers/huggingfaceUtils.js +18 -0
  140. package/lib/parsers/kiroPermissions.js +166 -0
  141. package/lib/parsers/largeJson.js +28 -11
  142. package/lib/parsers/vscodeExtensionId.js +183 -0
  143. package/lib/server/server.js +48 -35
  144. package/lib/stages/postgen/postgen.js +41 -1
  145. package/lib/stages/postgen/ruleEngine.js +13 -5
  146. package/lib/stages/postgen/specVersionCompat.js +76 -0
  147. package/lib/stages/pregen/envAudit.js +1 -0
  148. package/lib/stages/pregen/pregen.js +114 -57
  149. package/lib/validator/bomValidator.js +14 -2
  150. package/lib/validator/complianceEngine.js +30 -3
  151. package/lib/validator/complianceRules.js +1416 -4
  152. package/lib/validator/generated/validate-1.6.mjs +1 -1
  153. package/lib/validator/generated/validate-1.7.mjs +1 -1
  154. package/lib/validator/generated/validate-2.0.mjs +57554 -13851
  155. package/lib/validator/index.js +49 -8
  156. package/lib/validator/reporters/json.js +6 -0
  157. package/package.json +11 -10
  158. package/types/bin/repl.d.ts.map +1 -1
  159. package/types/lib/audit/index.d.ts +6 -2
  160. package/types/lib/audit/index.d.ts.map +1 -1
  161. package/types/lib/cli/bomAssembly.d.ts +29 -1
  162. package/types/lib/cli/bomAssembly.d.ts.map +1 -1
  163. package/types/lib/cli/cliOptions.d.ts +6 -0
  164. package/types/lib/cli/cliOptions.d.ts.map +1 -1
  165. package/types/lib/cli/index.d.ts.map +1 -1
  166. package/types/lib/cli/jsBom.d.ts +3 -18
  167. package/types/lib/cli/jsBom.d.ts.map +1 -1
  168. package/types/lib/cli/jvmBom.d.ts +15 -0
  169. package/types/lib/cli/jvmBom.d.ts.map +1 -1
  170. package/types/lib/cli/managedBom.d.ts.map +1 -1
  171. package/types/lib/cli/nativeBom.d.ts.map +1 -1
  172. package/types/lib/core/boundedFile.d.ts +100 -0
  173. package/types/lib/core/boundedFile.d.ts.map +1 -0
  174. package/types/lib/core/brotliProbe.d.ts +37 -0
  175. package/types/lib/core/brotliProbe.d.ts.map +1 -0
  176. package/types/lib/core/env.d.ts +14 -0
  177. package/types/lib/core/env.d.ts.map +1 -1
  178. package/types/lib/core/fs.d.ts +4 -0
  179. package/types/lib/core/fs.d.ts.map +1 -1
  180. package/types/lib/core/globPatterns.d.ts +70 -0
  181. package/types/lib/core/globPatterns.d.ts.map +1 -0
  182. package/types/lib/core/httpClient.d.ts +24 -0
  183. package/types/lib/core/httpClient.d.ts.map +1 -1
  184. package/types/lib/core/lockPaths.d.ts +19 -0
  185. package/types/lib/core/lockPaths.d.ts.map +1 -0
  186. package/types/lib/core/paths.d.ts +9 -0
  187. package/types/lib/core/paths.d.ts.map +1 -1
  188. package/types/lib/core/processTree.d.ts +17 -4
  189. package/types/lib/core/processTree.d.ts.map +1 -1
  190. package/types/lib/core/projectConfig.d.ts +47 -8
  191. package/types/lib/core/projectConfig.d.ts.map +1 -1
  192. package/types/lib/core/toolRegistry.d.ts +36 -0
  193. package/types/lib/core/toolRegistry.d.ts.map +1 -0
  194. package/types/lib/ecosystems/cppEvidence.d.ts +40 -13
  195. package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
  196. package/types/lib/ecosystems/cppIncludeResolver.d.ts +2 -1
  197. package/types/lib/ecosystems/cppIncludeResolver.d.ts.map +1 -1
  198. package/types/lib/ecosystems/ecosystems.d.ts.map +1 -1
  199. package/types/lib/ecosystems/gemHostProbe.d.ts +28 -0
  200. package/types/lib/ecosystems/gemHostProbe.d.ts.map +1 -0
  201. package/types/lib/ecosystems/golem.d.ts.map +1 -1
  202. package/types/lib/ecosystems/gradleutils.d.ts +294 -20
  203. package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
  204. package/types/lib/ecosystems/jsEvidence.d.ts +14 -1
  205. package/types/lib/ecosystems/jsEvidence.d.ts.map +1 -1
  206. package/types/lib/ecosystems/kosi.d.ts.map +1 -1
  207. package/types/lib/ecosystems/npmVersionResolution.d.ts +119 -0
  208. package/types/lib/ecosystems/npmVersionResolution.d.ts.map +1 -0
  209. package/types/lib/ecosystems/parsers-bazel.d.ts.map +1 -1
  210. package/types/lib/ecosystems/parsers-js.d.ts +17 -20
  211. package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
  212. package/types/lib/ecosystems/parsers-misc.d.ts +19 -0
  213. package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
  214. package/types/lib/ecosystems/parsers-python.d.ts +10 -0
  215. package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
  216. package/types/lib/ecosystems/parsers-rust.d.ts.map +1 -1
  217. package/types/lib/ecosystems/pythonutils.d.ts +19 -1
  218. package/types/lib/ecosystems/pythonutils.d.ts.map +1 -1
  219. package/types/lib/ecosystems/remote/huggingface.d.ts.map +1 -1
  220. package/types/lib/ecosystems/rubyutils.d.ts +144 -12
  221. package/types/lib/ecosystems/rubyutils.d.ts.map +1 -1
  222. package/types/lib/ecosystems/rusi.d.ts.map +1 -1
  223. package/types/lib/ecosystems/scalacliutils.d.ts.map +1 -1
  224. package/types/lib/ecosystems/scalasem.d.ts +58 -16
  225. package/types/lib/ecosystems/scalasem.d.ts.map +1 -1
  226. package/types/lib/ecosystems/vendoredCode.d.ts +26 -0
  227. package/types/lib/ecosystems/vendoredCode.d.ts.map +1 -1
  228. package/types/lib/ecosystems/venvProbe.d.ts +40 -0
  229. package/types/lib/ecosystems/venvProbe.d.ts.map +1 -0
  230. package/types/lib/evinser/evinser.d.ts +120 -13
  231. package/types/lib/evinser/evinser.d.ts.map +1 -1
  232. package/types/lib/evinser/scalasem.d.ts.map +1 -1
  233. package/types/lib/helpers/agenticToolutils.d.ts +53 -19
  234. package/types/lib/helpers/agenticToolutils.d.ts.map +1 -1
  235. package/types/lib/helpers/bomSigner.d.ts +20 -3
  236. package/types/lib/helpers/bomSigner.d.ts.map +1 -1
  237. package/types/lib/helpers/jssSigner.d.ts +288 -0
  238. package/types/lib/helpers/jssSigner.d.ts.map +1 -0
  239. package/types/lib/helpers/vsixutils.d.ts +303 -19
  240. package/types/lib/helpers/vsixutils.d.ts.map +1 -1
  241. package/types/lib/inventory/agentBlueprint.d.ts +70 -0
  242. package/types/lib/inventory/agentBlueprint.d.ts.map +1 -0
  243. package/types/lib/inventory/agentToolNames.d.ts +51 -0
  244. package/types/lib/inventory/agentToolNames.d.ts.map +1 -0
  245. package/types/lib/inventory/aiCollector.d.ts.map +1 -1
  246. package/types/lib/inventory/aiInventory.d.ts.map +1 -1
  247. package/types/lib/inventory/aiProviders.d.ts +85 -0
  248. package/types/lib/inventory/aiProviders.d.ts.map +1 -0
  249. package/types/lib/inventory/atomUtils.d.ts +19 -0
  250. package/types/lib/inventory/atomUtils.d.ts.map +1 -1
  251. package/types/lib/inventory/bomUtils.d.ts.map +1 -1
  252. package/types/lib/inventory/brotliDecoder.d.ts +58 -0
  253. package/types/lib/inventory/brotliDecoder.d.ts.map +1 -0
  254. package/types/lib/inventory/cbomutils.d.ts +17 -0
  255. package/types/lib/inventory/cbomutils.d.ts.map +1 -1
  256. package/types/lib/inventory/ciParsers/githubActionsLock.d.ts +101 -0
  257. package/types/lib/inventory/ciParsers/githubActionsLock.d.ts.map +1 -0
  258. package/types/lib/inventory/citations.d.ts +5 -0
  259. package/types/lib/inventory/citations.d.ts.map +1 -1
  260. package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
  261. package/types/lib/inventory/cyclonedx20.d.ts +99 -0
  262. package/types/lib/inventory/cyclonedx20.d.ts.map +1 -0
  263. package/types/lib/inventory/cyclonedx20Common.d.ts +102 -0
  264. package/types/lib/inventory/cyclonedx20Common.d.ts.map +1 -0
  265. package/types/lib/inventory/cyclonedx20Derived.d.ts +74 -0
  266. package/types/lib/inventory/cyclonedx20Derived.d.ts.map +1 -0
  267. package/types/lib/inventory/cyclonedx20Parties.d.ts +91 -0
  268. package/types/lib/inventory/cyclonedx20Parties.d.ts.map +1 -0
  269. package/types/lib/inventory/cyclonedx20Read.d.ts +51 -0
  270. package/types/lib/inventory/cyclonedx20Read.d.ts.map +1 -0
  271. package/types/lib/inventory/cyclonedx20ReadCommon.d.ts +69 -0
  272. package/types/lib/inventory/cyclonedx20ReadCommon.d.ts.map +1 -0
  273. package/types/lib/inventory/cyclonedx20ReadComponents.d.ts +77 -0
  274. package/types/lib/inventory/cyclonedx20ReadComponents.d.ts.map +1 -0
  275. package/types/lib/inventory/cyclonedx20ReadContext.d.ts +118 -0
  276. package/types/lib/inventory/cyclonedx20ReadContext.d.ts.map +1 -0
  277. package/types/lib/inventory/cyclonedx20ReadEvidence.d.ts +40 -0
  278. package/types/lib/inventory/cyclonedx20ReadEvidence.d.ts.map +1 -0
  279. package/types/lib/inventory/cyclonedx20ReadSections.d.ts +45 -0
  280. package/types/lib/inventory/cyclonedx20ReadSections.d.ts.map +1 -0
  281. package/types/lib/inventory/cyclonedx20Render.d.ts +53 -0
  282. package/types/lib/inventory/cyclonedx20Render.d.ts.map +1 -0
  283. package/types/lib/inventory/cyclonedx20RenderComponents.d.ts +73 -0
  284. package/types/lib/inventory/cyclonedx20RenderComponents.d.ts.map +1 -0
  285. package/types/lib/inventory/cyclonedx20RenderDefinitions.d.ts +29 -0
  286. package/types/lib/inventory/cyclonedx20RenderDefinitions.d.ts.map +1 -0
  287. package/types/lib/inventory/cyclonedx20RenderEvidence.d.ts +110 -0
  288. package/types/lib/inventory/cyclonedx20RenderEvidence.d.ts.map +1 -0
  289. package/types/lib/inventory/cyclonedx20RenderHardware.d.ts +42 -0
  290. package/types/lib/inventory/cyclonedx20RenderHardware.d.ts.map +1 -0
  291. package/types/lib/inventory/cyclonedx20RenderPatents.d.ts +26 -0
  292. package/types/lib/inventory/cyclonedx20RenderPatents.d.ts.map +1 -0
  293. package/types/lib/inventory/cyclonedx20RenderRefIds.d.ts +55 -0
  294. package/types/lib/inventory/cyclonedx20RenderRefIds.d.ts.map +1 -0
  295. package/types/lib/inventory/cyclonedx20RenderSections.d.ts +45 -0
  296. package/types/lib/inventory/cyclonedx20RenderSections.d.ts.map +1 -0
  297. package/types/lib/inventory/cyclonedx20Tables.d.ts +134 -0
  298. package/types/lib/inventory/cyclonedx20Tables.d.ts.map +1 -0
  299. package/types/lib/inventory/deps.d.ts +35 -2
  300. package/types/lib/inventory/deps.d.ts.map +1 -1
  301. package/types/lib/inventory/dosai.d.ts +36 -1
  302. package/types/lib/inventory/dosai.d.ts.map +1 -1
  303. package/types/lib/inventory/dosaiParsers.d.ts.map +1 -1
  304. package/types/lib/inventory/dotnetRuntime.d.ts +91 -0
  305. package/types/lib/inventory/dotnetRuntime.d.ts.map +1 -0
  306. package/types/lib/inventory/ecosystemFormulationParsers.d.ts +73 -0
  307. package/types/lib/inventory/ecosystemFormulationParsers.d.ts.map +1 -0
  308. package/types/lib/inventory/envcontext.d.ts +74 -12
  309. package/types/lib/inventory/envcontext.d.ts.map +1 -1
  310. package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
  311. package/types/lib/inventory/formulationParsers.d.ts.map +1 -1
  312. package/types/lib/inventory/gtfobins.d.ts.map +1 -1
  313. package/types/lib/inventory/hbom.d.ts +11 -0
  314. package/types/lib/inventory/hbom.d.ts.map +1 -1
  315. package/types/lib/inventory/hbomLoader.d.ts +54 -0
  316. package/types/lib/inventory/hbomLoader.d.ts.map +1 -1
  317. package/types/lib/inventory/hostRuntimeProbe.d.ts +44 -0
  318. package/types/lib/inventory/hostRuntimeProbe.d.ts.map +1 -0
  319. package/types/lib/inventory/jvmLocalRepos.d.ts +5 -1
  320. package/types/lib/inventory/jvmLocalRepos.d.ts.map +1 -1
  321. package/types/lib/inventory/jvmToolEnv.d.ts +12 -0
  322. package/types/lib/inventory/jvmToolEnv.d.ts.map +1 -1
  323. package/types/lib/inventory/licenseEnhancer.d.ts.map +1 -1
  324. package/types/lib/inventory/mavenCentralMirror.d.ts +170 -0
  325. package/types/lib/inventory/mavenCentralMirror.d.ts.map +1 -0
  326. package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -1
  327. package/types/lib/inventory/nodeBuildInfo.d.ts +95 -0
  328. package/types/lib/inventory/nodeBuildInfo.d.ts.map +1 -0
  329. package/types/lib/inventory/nodeHostProbe.d.ts +15 -0
  330. package/types/lib/inventory/nodeHostProbe.d.ts.map +1 -0
  331. package/types/lib/inventory/occurrenceKey.d.ts +52 -0
  332. package/types/lib/inventory/occurrenceKey.d.ts.map +1 -0
  333. package/types/lib/inventory/osPackageResolver.d.ts +38 -0
  334. package/types/lib/inventory/osPackageResolver.d.ts.map +1 -1
  335. package/types/lib/inventory/phpBuildInfo.d.ts.map +1 -1
  336. package/types/lib/inventory/phpHostProbe.d.ts.map +1 -1
  337. package/types/lib/inventory/pqcMigration.d.ts +84 -0
  338. package/types/lib/inventory/pqcMigration.d.ts.map +1 -0
  339. package/types/lib/inventory/rubyBuildInfo.d.ts +271 -0
  340. package/types/lib/inventory/rubyBuildInfo.d.ts.map +1 -0
  341. package/types/lib/inventory/rubyHostProbe.d.ts +47 -0
  342. package/types/lib/inventory/rubyHostProbe.d.ts.map +1 -0
  343. package/types/lib/inventory/rustFormulationParser.d.ts +7 -2
  344. package/types/lib/inventory/rustFormulationParser.d.ts.map +1 -1
  345. package/types/lib/inventory/scalaCoords.d.ts.map +1 -1
  346. package/types/lib/inventory/scalaDedupe.d.ts +43 -0
  347. package/types/lib/inventory/scalaDedupe.d.ts.map +1 -0
  348. package/types/lib/inventory/source.d.ts +25 -0
  349. package/types/lib/inventory/source.d.ts.map +1 -1
  350. package/types/lib/managers/binary.d.ts.map +1 -1
  351. package/types/lib/managers/docker.d.ts +12 -0
  352. package/types/lib/managers/docker.d.ts.map +1 -1
  353. package/types/lib/parsers/huggingfaceManifest.d.ts +10 -1
  354. package/types/lib/parsers/huggingfaceManifest.d.ts.map +1 -1
  355. package/types/lib/parsers/huggingfaceUtils.d.ts +12 -0
  356. package/types/lib/parsers/huggingfaceUtils.d.ts.map +1 -1
  357. package/types/lib/parsers/kiroPermissions.d.ts +62 -0
  358. package/types/lib/parsers/kiroPermissions.d.ts.map +1 -0
  359. package/types/lib/parsers/largeJson.d.ts +4 -3
  360. package/types/lib/parsers/largeJson.d.ts.map +1 -1
  361. package/types/lib/parsers/vscodeExtensionId.d.ts +48 -0
  362. package/types/lib/parsers/vscodeExtensionId.d.ts.map +1 -0
  363. package/types/lib/server/server.d.ts.map +1 -1
  364. package/types/lib/stages/postgen/postgen.d.ts +7 -0
  365. package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
  366. package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
  367. package/types/lib/stages/postgen/specVersionCompat.d.ts +25 -0
  368. package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -1
  369. package/types/lib/stages/pregen/envAudit.d.ts.map +1 -1
  370. package/types/lib/stages/pregen/pregen.d.ts +12 -8
  371. package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
  372. package/types/lib/validator/bomValidator.d.ts +5 -1
  373. package/types/lib/validator/bomValidator.d.ts.map +1 -1
  374. package/types/lib/validator/complianceEngine.d.ts +4 -4
  375. package/types/lib/validator/complianceEngine.d.ts.map +1 -1
  376. package/types/lib/validator/complianceRules.d.ts +14 -2
  377. package/types/lib/validator/complianceRules.d.ts.map +1 -1
  378. package/types/lib/validator/index.d.ts +10 -0
  379. package/types/lib/validator/index.d.ts.map +1 -1
  380. package/types/lib/validator/reporters/json.d.ts.map +1 -1
@@ -0,0 +1,152 @@
1
+ /**
2
+ * CycloneDX 2.0 rendering and reading.
3
+ *
4
+ * cdxgen assembles every BOM in the CycloneDX 1.x shape and converts to the
5
+ * requested spec version at the end of the pipeline (see
6
+ * lib/stages/postgen/specVersionCompat.js). The 2.0 draft is a structural
7
+ * rewrite rather than an additive change, so the conversion lives here, as two
8
+ * pure functions plus small helpers, instead of inside the compat walker:
9
+ *
10
+ * - `renderCycloneDx20(internalBom, context)` turns the 1.x-shaped internal
11
+ * model into a 2.0 document. It never mutates its input, and its output
12
+ * depends only on the model and the optional context (the cdx-hbom
13
+ * hardware mapper, see hbomLoader.js: hardwareRenderContext).
14
+ * `renderCycloneDx20WithReport(internalBom, context)` does the same and
15
+ * also returns the counts of everything the render could not carry.
16
+ * - `readCycloneDx20(bom20)` turns a 2.0 document into the internal 1.x-shaped
17
+ * model, reporting everything it could not carry in `losses`.
18
+ * - `loadBomForAnalysis(bomJson)` is the single entry point every BOM reader
19
+ * uses; it returns the document as is for 1.x and calls readCycloneDx20 for
20
+ * 2.0, so no reader learns the 2.0 shape.
21
+ * - `getInternalBom(bomNSData)` and `refreshRenderedBom(bomNSData, options)`
22
+ * are the generation-side half: postProcess keeps the 1.x model on
23
+ * `bomNSData.internalBomJson` at 2.0, and the writer re-renders once after
24
+ * the last mutation.
25
+ *
26
+ * Every field name below is quoted from the pinned draft schema
27
+ * (data/cyclonedx-2.0-bundled.schema.json, CycloneDX/specification 2.0-dev at
28
+ * ea8c3605829d1da13339a0790b6da73548e42a6b); citations give the `$defs` path.
29
+ */
30
+
31
+ import { thoughtLog } from "../core/logger.js";
32
+ import { isCycloneDx20SpecVersion } from "./bomUtils.js";
33
+ import { isObjectRecord } from "./cyclonedx20Common.js";
34
+ import { readCycloneDx20 } from "./cyclonedx20Read.js";
35
+ import { isMarkedInternalModel } from "./cyclonedx20ReadContext.js";
36
+ import { renderCycloneDx20 } from "./cyclonedx20Render.js";
37
+ import { CDX20_INTERNAL_SECTIONS_KEY } from "./cyclonedx20Tables.js";
38
+
39
+ export { readCycloneDx20 } from "./cyclonedx20Read.js";
40
+ export {
41
+ renderCycloneDx20,
42
+ renderCycloneDx20WithReport,
43
+ } from "./cyclonedx20Render.js";
44
+ export {
45
+ CDX20_INTERNAL_SECTIONS_KEY,
46
+ CDXGEN_PARTY_REF_ID,
47
+ DEPENDENCY_TRACK_CDX20_ERROR,
48
+ } from "./cyclonedx20Tables.js";
49
+
50
+ /**
51
+ * Load any CycloneDX BOM for analysis: the document as is for 1.x, the
52
+ * internal 1.x-shaped model for 2.0.
53
+ *
54
+ * A document whose specVersion is 2.0 or later, or which has a specFormat, is
55
+ * read as 2.0, and the reader reports stray 1.x members such as
56
+ * `components` as losses. A model the 2.0 reader or the 2.0 compatibility
57
+ * pass produced carries the internal model mark (markInternalModel) and is
58
+ * returned as is; cdxgen hands that model to the evidence analysis in memory
59
+ * (evinse's `inputBomJson`), because the mark does not survive JSON. The
60
+ * internal sections key is never trusted on a 1.x document: the returned
61
+ * copy leaves it out, so it cannot reach a 2.0 render.
62
+ *
63
+ * @param {object} bomJson Parsed CycloneDX BOM
64
+ * @returns {{internalBom: object, specVersion: string, losses: Array<{pointer: string, reason: string}>}}
65
+ * @throws {Error} With a short message when the 2.0 reader fails on the
66
+ * document
67
+ */
68
+ export function loadBomForAnalysis(bomJson) {
69
+ if (!isObjectRecord(bomJson)) {
70
+ return { internalBom: bomJson, specVersion: "1.5", losses: [] };
71
+ }
72
+ const specVersion = `${bomJson.specVersion ?? ""}`.trim() || "1.5";
73
+ if (isMarkedInternalModel(bomJson)) {
74
+ return { internalBom: bomJson, specVersion, losses: [] };
75
+ }
76
+ if (
77
+ isCycloneDx20SpecVersion(specVersion) ||
78
+ bomJson.specFormat !== undefined
79
+ ) {
80
+ let read;
81
+ try {
82
+ read = readCycloneDx20(bomJson);
83
+ } catch (err) {
84
+ throw new Error(
85
+ `Unable to read the CycloneDX 2.0 document: ${err?.message || err}`,
86
+ { cause: err },
87
+ );
88
+ }
89
+ return {
90
+ internalBom: read.internalBom,
91
+ specVersion: "2.0",
92
+ losses: read.losses,
93
+ };
94
+ }
95
+ if (Object.hasOwn(bomJson, CDX20_INTERNAL_SECTIONS_KEY)) {
96
+ thoughtLog(
97
+ `Ignoring the ${CDX20_INTERNAL_SECTIONS_KEY} member of a CycloneDX ${specVersion} document; only the 2.0 reader sets it.`,
98
+ );
99
+ const { [CDX20_INTERNAL_SECTIONS_KEY]: _ignored, ...internalBom } = bomJson;
100
+ return { internalBom, specVersion, losses: [] };
101
+ }
102
+ return { internalBom: bomJson, specVersion, losses: [] };
103
+ }
104
+
105
+ /**
106
+ * The one-line notice a reader prints when loading a 2.0 document lost
107
+ * data: the number of losses, with the details left to thoughtLog.
108
+ *
109
+ * @param {Array<{pointer: string, reason: string}>} losses Reader losses
110
+ * @returns {string} The notice
111
+ */
112
+ export function formatReadLossNotice(losses) {
113
+ const count = losses?.length || 0;
114
+ return `CycloneDX 2.0 input: reading it into the 1.x model reported ${count} loss${count === 1 ? "" : "es"}; those parts were not analysed. Set CDXGEN_THINK_MODE=true to list them.`;
115
+ }
116
+
117
+ /**
118
+ * Return the 1.x-shaped model of a generation run. At 1.x the rendered BOM is
119
+ * the internal model, so this always yields something readers can walk.
120
+ *
121
+ * @param {{bomJson?: object, internalBomJson?: object}} bomNSData
122
+ * @returns {object} The 1.x-shaped BOM
123
+ */
124
+ export function getInternalBom(bomNSData) {
125
+ return bomNSData?.internalBomJson ?? bomNSData?.bomJson;
126
+ }
127
+
128
+ /**
129
+ * Re-render the 2.0 document after a post-postProcess mutation of the
130
+ * internal model, with the render context postProcess used
131
+ * (`bomNSData.renderContext`). A no-op at 1.x, which keeps those versions
132
+ * byte-identical.
133
+ *
134
+ * @param {{bomJson?: object, internalBomJson?: object, renderContext?: object}} bomNSData
135
+ * @param {object} options CLI options carrying `specVersion`
136
+ * @returns {{bomJson?: object, internalBomJson?: object}} The same bomNSData
137
+ */
138
+ export function refreshRenderedBom(bomNSData, options) {
139
+ if (
140
+ !bomNSData?.internalBomJson ||
141
+ !isCycloneDx20SpecVersion(
142
+ options?.specVersion ?? bomNSData.bomJson?.specVersion,
143
+ )
144
+ ) {
145
+ return bomNSData;
146
+ }
147
+ bomNSData.bomJson = renderCycloneDx20(
148
+ bomNSData.internalBomJson,
149
+ bomNSData.renderContext,
150
+ );
151
+ return bomNSData;
152
+ }
@@ -0,0 +1,286 @@
1
+ /**
2
+ * Small shared helpers for the CycloneDX 2.0 renderer and reader: type
3
+ * guards, cloning, render counters and the environment-variable shape change.
4
+ */
5
+
6
+ import { createHash } from "node:crypto";
7
+
8
+ /** True for a plain object (not null, not an array). */
9
+ export const isObjectRecord = (value) =>
10
+ Boolean(value && typeof value === "object" && !Array.isArray(value));
11
+
12
+ /** True for a string with at least one character. */
13
+ export const isNonEmptyString = (value) =>
14
+ typeof value === "string" && value.length > 0;
15
+
16
+ /** structuredClone that passes `undefined` through. */
17
+ export const clone = (value) =>
18
+ value === undefined ? undefined : structuredClone(value);
19
+
20
+ // bomLinkElementType / bomLinkDocumentType values point into another document
21
+ // (#/$defs/cyclonedx-common-2.0/$defs/bomLink), so they never resolve here.
22
+ export const isBomLink = (value) =>
23
+ typeof value === "string" && value.startsWith("urn:cdx:");
24
+
25
+ /**
26
+ * A fresh, empty set of render counters.
27
+ *
28
+ * @param {object} [shadows] 2.0 originals kept by readCycloneDx20 (see
29
+ * takeShadow)
30
+ * @param {{toolRefId?: string, timestamp?: string}} [claims] What identity
31
+ * claims are attributed with (see identityClaimContext)
32
+ * @returns {object} Render counters
33
+ */
34
+ export function createRenderStats(shadows, claims) {
35
+ return {
36
+ claims: isObjectRecord(claims) ? claims : {},
37
+ customSchemes: new Set(),
38
+ droppedMethods: [],
39
+ drops: {},
40
+ rewrites: {},
41
+ formulaComponents: [],
42
+ formulaMembership: [],
43
+ shadows: isObjectRecord(shadows) ? shadows : {},
44
+ shadowUse: new Map(),
45
+ };
46
+ }
47
+
48
+ /**
49
+ * The key a 1.x value is shadowed under: the SHA-256 of its JSON. The
50
+ * reader and the renderer serialize the same object the same way, so an
51
+ * unchanged value finds its 2.0 original again.
52
+ *
53
+ * @param {*} value 1.x value
54
+ * @returns {string} Hex digest
55
+ */
56
+ export function shadowKey(value) {
57
+ return createHash("sha256").update(JSON.stringify(value)).digest("hex");
58
+ }
59
+
60
+ /**
61
+ * The 2.0 original readCycloneDx20 kept for this unchanged 1.x value, as a
62
+ * fresh clone, or undefined. Identical 1.x values kept for several originals
63
+ * get them back in document order. Never mutates the stored shadows.
64
+ *
65
+ * @param {object} stats Render counters from createRenderStats
66
+ * @param {string} kind Shadow namespace (component, metadata, …)
67
+ * @param {*} value 1.x value about to be rendered
68
+ * @returns {*} The 2.0 original or undefined
69
+ */
70
+ export function takeShadow(stats, kind, value) {
71
+ const byKind = stats.shadows[kind];
72
+ if (!isObjectRecord(byKind) || value === undefined) {
73
+ return undefined;
74
+ }
75
+ const key = shadowKey(value);
76
+ const originals = byKind[key];
77
+ if (!Array.isArray(originals)) {
78
+ return undefined;
79
+ }
80
+ const useKey = `${kind}:${key}`;
81
+ const used = stats.shadowUse.get(useKey) || 0;
82
+ if (used >= originals.length) {
83
+ return undefined;
84
+ }
85
+ stats.shadowUse.set(useKey, used + 1);
86
+ return clone(originals[used]);
87
+ }
88
+
89
+ /**
90
+ * The single 2.0 original readCycloneDx20 kept for this unchanged 1.x value,
91
+ * as a fresh clone, or undefined. Unlike takeShadow nothing is consumed: the
92
+ * reader registers a key here only when every entry it read under that key
93
+ * had the same original, so the lookup does not depend on render order.
94
+ *
95
+ * @param {object} stats Render counters from createRenderStats
96
+ * @param {string} kind Shadow namespace (identity)
97
+ * @param {*} value 1.x value about to be rendered
98
+ * @returns {*} The 2.0 original or undefined
99
+ */
100
+ export function peekShadow(stats, kind, value) {
101
+ const byKind = stats.shadows[kind];
102
+ if (!isObjectRecord(byKind) || value === undefined) {
103
+ return undefined;
104
+ }
105
+ const originals = byKind[shadowKey(value)];
106
+ return Array.isArray(originals) && originals.length === 1
107
+ ? clone(originals[0])
108
+ : undefined;
109
+ }
110
+
111
+ /** Count one dropped or rewritten value under a stable label. */
112
+ export function countDrop(stats, label, count = 1) {
113
+ stats.drops[label] = (stats.drops[label] || 0) + count;
114
+ }
115
+
116
+ /**
117
+ * Count one value the render rewrote without losing data (a duplicate refId
118
+ * turned into a reference, a retargeted annotation subject).
119
+ */
120
+ export function countRewrite(stats, label, count = 1) {
121
+ stats.rewrites[label] = (stats.rewrites[label] || 0) + count;
122
+ }
123
+
124
+ /**
125
+ * Count a 1.x JSF `signature` the render leaves out: it signs the 1.x
126
+ * serialization, so it cannot verify over the re-rendered 2.0 document, and
127
+ * 2.0 `signatures` hold JSS signatures
128
+ * (#/$defs/cyclonedx-common-2.0/$defs/signatures).
129
+ */
130
+ export function countSignatureDrop(stats, path) {
131
+ countDrop(
132
+ stats,
133
+ `${path} (1.x JSF signature: does not verify after re-rendering)`,
134
+ );
135
+ }
136
+
137
+ /** Count every defined key of `source` that `handled` does not list. */
138
+ export function countUnmapped(stats, prefix, source, handled) {
139
+ for (const [key, value] of Object.entries(source)) {
140
+ if (value !== undefined && !handled.has(key)) {
141
+ countDrop(stats, `${prefix}.${key}`);
142
+ }
143
+ }
144
+ }
145
+
146
+ /** Clone the listed fields of `source` that are defined onto `target`. */
147
+ export function copyDefined(target, source, fields) {
148
+ for (const field of fields) {
149
+ if (source[field] !== undefined) {
150
+ target[field] = clone(source[field]);
151
+ }
152
+ }
153
+ }
154
+
155
+ /** Remove duplicate entries (by JSON value) for `uniqueItems` arrays. */
156
+ export function uniqueByValue(values) {
157
+ const seen = new Set();
158
+ const unique = [];
159
+ for (const value of values) {
160
+ const key = JSON.stringify(value);
161
+ if (!seen.has(key)) {
162
+ seen.add(key);
163
+ unique.push(value);
164
+ }
165
+ }
166
+ return unique;
167
+ }
168
+
169
+ /** Split a 1.x `author` string the way specVersionCompat does. */
170
+ export function authorStringToNames(authorValue) {
171
+ if (typeof authorValue !== "string") {
172
+ return [];
173
+ }
174
+ return authorValue
175
+ .split(",")
176
+ .map((name) => name.trim())
177
+ .filter(Boolean);
178
+ }
179
+
180
+ /** A 1.x scalar-or-array identifier field as a list of strings. */
181
+ export function identifierValues(value) {
182
+ if (Array.isArray(value)) {
183
+ return value;
184
+ }
185
+ return typeof value === "string" ? [value] : [];
186
+ }
187
+
188
+ /** Assign `value` to `out[key]` unless it is undefined. */
189
+ export function setDefined(out, key, value) {
190
+ if (value !== undefined) {
191
+ out[key] = value;
192
+ }
193
+ }
194
+
195
+ /**
196
+ * Convert a 1.x `environmentVars` array of {name, value} entries into the 2.0
197
+ * map of names to values
198
+ * (#/$defs/cyclonedx-formulation-2.0/$defs/environmentVars). Reverse for read.
199
+ * Entries the map cannot hold are counted when `stats` is given.
200
+ */
201
+ export function convertEnvironmentVars(value, stats) {
202
+ if (Array.isArray(value)) {
203
+ const mapped = {};
204
+ for (const entry of value) {
205
+ // A 1.x string entry becomes a name with a null value, which the 2.0
206
+ // map allows.
207
+ const name = typeof entry === "string" ? entry : entry?.name;
208
+ if (!isObjectRecord(entry) && typeof entry !== "string") {
209
+ countDropIf(stats, "environmentVars (not a name or {name, value})");
210
+ } else if (typeof name !== "string") {
211
+ countDropIf(stats, "environmentVars (no name)");
212
+ } else if (Object.hasOwn(mapped, name)) {
213
+ countDropIf(stats, "environmentVars (repeated name)");
214
+ } else {
215
+ mapped[name] = typeof entry?.value === "string" ? entry.value : null;
216
+ }
217
+ }
218
+ return mapped;
219
+ }
220
+ return clone(value);
221
+ }
222
+
223
+ function countDropIf(stats, label) {
224
+ if (stats) {
225
+ countDrop(stats, label);
226
+ }
227
+ }
228
+
229
+ /** Turn a 2.0 environmentVars map back into the 1.x {name, value} array. */
230
+ export function reverseEnvironmentVars(value) {
231
+ if (!Array.isArray(value) && isObjectRecord(value)) {
232
+ return Object.entries(value).map(([name, val]) => ({
233
+ name,
234
+ value: val === null ? undefined : val,
235
+ }));
236
+ }
237
+ return value;
238
+ }
239
+
240
+ /** Every refId string declared anywhere under the given roots. */
241
+ export function collectDeclaredRefIds(roots) {
242
+ const declared = new Set();
243
+ const visit = (node) => {
244
+ if (Array.isArray(node)) {
245
+ node.forEach(visit);
246
+ return;
247
+ }
248
+ if (!isObjectRecord(node)) {
249
+ return;
250
+ }
251
+ if (typeof node.refId === "string") {
252
+ declared.add(node.refId);
253
+ }
254
+ for (const value of Object.values(node)) {
255
+ visit(value);
256
+ }
257
+ };
258
+ roots.forEach(visit);
259
+ return declared;
260
+ }
261
+
262
+ /**
263
+ * True when any `party` member (a refId string or a partyReference) or any
264
+ * `ref` member below `node` names `refId`. Restored 2.0 originals reference
265
+ * a derived party (see derivedPartyDeclarations) without passing through the
266
+ * converters, so its declaration follows the rendered document rather than a
267
+ * render flag.
268
+ */
269
+ export function referencesParty(node, refId) {
270
+ if (Array.isArray(node)) {
271
+ return node.some((child) => referencesParty(child, refId));
272
+ }
273
+ if (!isObjectRecord(node)) {
274
+ return false;
275
+ }
276
+ for (const [key, value] of Object.entries(node)) {
277
+ if (
278
+ (key === "party" && (value === refId || value?.ref === refId)) ||
279
+ (key === "ref" && value === refId) ||
280
+ referencesParty(value, refId)
281
+ ) {
282
+ return true;
283
+ }
284
+ }
285
+ return false;
286
+ }
@@ -0,0 +1,159 @@
1
+ /**
2
+ * The 2.0 sections the renderer derives from the 1.x-shaped internal model
3
+ * rather than converts: post-quantum migration risks (pqcMigration.js,
4
+ * #4592), and the coding-agent parties and behavioral blueprint
5
+ * (agentBlueprint.js, #4593).
6
+ *
7
+ * A model read from 2.0 carries its 2.0-only sections (risks, blueprints,
8
+ * parties) for 2.0 output. Derived entries in them are recognised by refId
9
+ * (`risk-pqc-*`, `blueprint-declared-agents`, agent parties `party-agent-*`
10
+ * of system kind `agent`). The renderer drops carried derived entries and
11
+ * derives them again from the model, so they follow edits to the model and
12
+ * are never declared twice. Every other carried entry is kept, first, and a
13
+ * derived entry never replaces a carried entry with the same refId.
14
+ *
15
+ * Only cdxgen's own analysis is derived: the sections are derived only when
16
+ * the model's `metadata.tools` lists cdxgen with a bom-ref, the rule
17
+ * identityClaimContext applies to cdxgen's identity claims. Another tool's
18
+ * BOM converted with `cdx-convert --to 2.0` gets no derived section.
19
+ */
20
+
21
+ import { isDeepStrictEqual } from "node:util";
22
+
23
+ import {
24
+ AGENT_BLUEPRINT_REF_ID,
25
+ AGENT_PARTY_REF_ID_PREFIX,
26
+ collectAgentBehaviour,
27
+ } from "./agentBlueprint.js";
28
+ import { clone, isObjectRecord } from "./cyclonedx20Common.js";
29
+ import { identityClaimContext } from "./cyclonedx20RenderEvidence.js";
30
+ import { collectPqcRisks, PQC_RISK_REF_ID_PREFIX } from "./pqcMigration.js";
31
+
32
+ const startsWith = (value, prefix) =>
33
+ typeof value === "string" && value.startsWith(prefix);
34
+
35
+ /** A risk entry renderCycloneDx20 derives (see collectPqcRisks). */
36
+ export const isDerivedRisk = (risk) =>
37
+ startsWith(risk?.refId, PQC_RISK_REF_ID_PREFIX);
38
+
39
+ /** The blueprint renderCycloneDx20 derives (see collectAgentBehaviour). */
40
+ export const isDerivedBlueprint = (blueprint) =>
41
+ blueprint?.refId === AGENT_BLUEPRINT_REF_ID;
42
+
43
+ /** An agent party renderCycloneDx20 derives (see collectAgentBehaviour). */
44
+ export const isDerivedAgentParty = (party) =>
45
+ startsWith(party?.refId, AGENT_PARTY_REF_ID_PREFIX) &&
46
+ party?.system?.kind === "agent";
47
+
48
+ /**
49
+ * Does the model's `metadata.tools` list cdxgen with a bom-ref? The same
50
+ * test decides whether cdxgen's identity claims are written.
51
+ *
52
+ * @param {object} internalBom The 1.x-shaped internal model
53
+ * @returns {boolean} True when cdxgen is a listed tool
54
+ */
55
+ export function isCdxgenListedTool(internalBom) {
56
+ return identityClaimContext(internalBom).toolRefId !== undefined;
57
+ }
58
+
59
+ /**
60
+ * Derive the 2.0 sections of an internal model; all empty unless cdxgen is a
61
+ * listed tool (isCdxgenListedTool).
62
+ *
63
+ * @param {object} internalBom The 1.x-shaped internal model
64
+ * @returns {{risks: object[], agentParties: object[], blueprints: object[]}}
65
+ */
66
+ export function deriveCycloneDx20Sections(internalBom) {
67
+ if (!isCdxgenListedTool(internalBom)) {
68
+ return { risks: [], agentParties: [], blueprints: [] };
69
+ }
70
+ const { parties, blueprint } = collectAgentBehaviour(internalBom);
71
+ return {
72
+ risks: collectPqcRisks(internalBom),
73
+ agentParties: parties,
74
+ blueprints: blueprint ? [blueprint] : [],
75
+ };
76
+ }
77
+
78
+ /** Carried entries that are not derived, then derived ones with new refIds. */
79
+ function mergeByRefId(carried, derived, isDerived) {
80
+ const kept = (Array.isArray(carried) ? carried : []).filter(
81
+ (entry) => !isDerived(entry),
82
+ );
83
+ const refIds = new Set(kept.map((entry) => entry?.refId));
84
+ return [...kept, ...derived.filter((entry) => !refIds.has(entry.refId))];
85
+ }
86
+
87
+ /**
88
+ * Add the derived risks and blueprint to a rendered document whose carried
89
+ * 2.0 sections are already in place, and return the parties to declare: the
90
+ * carried parties without derived agent parties, then the derived ones.
91
+ *
92
+ * @param {object} out The document being rendered
93
+ * @param {object[]} carriedParties Parties carried from a 2.0 read
94
+ * @param {object} internalBom The internal model the document renders
95
+ * @returns {object[]} The parties to declare before the cdxgen party
96
+ */
97
+ export function appendDerivedSections(out, carriedParties, internalBom) {
98
+ const derived = deriveCycloneDx20Sections(internalBom);
99
+ // For another tool's document cdxgen derives nothing, and entries that look
100
+ // derived are that tool's own, so they are kept.
101
+ const listed = isCdxgenListedTool(internalBom);
102
+ const derivedOnly = (isDerived) => (entry) => listed && isDerived(entry);
103
+ const risks = mergeByRefId(
104
+ (isObjectRecord(out.risks) ? out.risks : {}).risks,
105
+ derived.risks,
106
+ derivedOnly(isDerivedRisk),
107
+ );
108
+ const risksSection = isObjectRecord(out.risks) ? out.risks : {};
109
+ const { risks: _risks, ...riskMembers } = risksSection;
110
+ if (risks.length) {
111
+ out.risks = { ...riskMembers, risks };
112
+ } else if (Object.keys(riskMembers).length) {
113
+ out.risks = riskMembers;
114
+ } else {
115
+ delete out.risks;
116
+ }
117
+ const blueprints = mergeByRefId(
118
+ out.blueprints,
119
+ derived.blueprints,
120
+ derivedOnly(isDerivedBlueprint),
121
+ );
122
+ if (blueprints.length) {
123
+ out.blueprints = blueprints;
124
+ } else {
125
+ delete out.blueprints;
126
+ }
127
+ return mergeByRefId(
128
+ carriedParties,
129
+ derived.agentParties,
130
+ derivedOnly(isDerivedAgentParty),
131
+ );
132
+ }
133
+
134
+ /**
135
+ * Split the derived entries out of a list read from 2.0. An entry that is
136
+ * what the renderer derives again from the read model is dropped without a
137
+ * loss; a derived-looking entry that differs is dropped too (the renderer
138
+ * would replace it), and its index is returned so the reader reports the
139
+ * loss.
140
+ *
141
+ * @param {object[]} entries The 2.0 list (risks, blueprints, parties)
142
+ * @param {object[]} derived What the renderer derives from the read model
143
+ * @param {Function} isDerived Recogniser for derived entries
144
+ * @returns {{kept: object[], differing: number[]}} The entries to carry, and
145
+ * the indexes of dropped entries that differ from the derivation
146
+ */
147
+ export function splitDerivedEntries(entries, derived, isDerived) {
148
+ const byRefId = new Map(derived.map((entry) => [entry.refId, entry]));
149
+ const kept = [];
150
+ const differing = [];
151
+ (Array.isArray(entries) ? entries : []).forEach((entry, index) => {
152
+ if (!isDerived(entry)) {
153
+ kept.push(entry);
154
+ } else if (!isDeepStrictEqual(byRefId.get(entry.refId), entry)) {
155
+ differing.push(index);
156
+ }
157
+ });
158
+ return { kept: clone(kept), differing };
159
+ }