@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,692 @@
1
+ /**
2
+ * Reader converters for CycloneDX 2.0 components
3
+ * (#/$defs/cyclonedx-component-2.0/$defs/component) back to 1.x components
4
+ * and, for `type: service`, 1.x services. Each frozen spec is the allowlist
5
+ * of the members 1.x carries; everything else is reported as a loss.
6
+ */
7
+
8
+ import { isDeepStrictEqual } from "node:util";
9
+
10
+ import {
11
+ createRenderStats,
12
+ isNonEmptyString,
13
+ isObjectRecord,
14
+ shadowKey,
15
+ } from "./cyclonedx20Common.js";
16
+ import { readParty, reverseParties } from "./cyclonedx20Parties.js";
17
+ import {
18
+ ATTACHMENT_RULE,
19
+ EXTERNAL_REFERENCES_RULE,
20
+ HASHES_RULE,
21
+ LICENSES_RULE,
22
+ PATENT_ASSERTIONS_RULE,
23
+ PROPERTIES_RULE,
24
+ RESOLVES_RULE,
25
+ reverseAttachment,
26
+ reverseProperty,
27
+ reverseReleaseNotes,
28
+ } from "./cyclonedx20ReadCommon.js";
29
+ import {
30
+ addLoss,
31
+ jsonPointer,
32
+ listOf,
33
+ objectOf,
34
+ registerShadowKey,
35
+ reportUnmapped,
36
+ reverseFields,
37
+ reverseList,
38
+ reverseObject,
39
+ } from "./cyclonedx20ReadContext.js";
40
+ import {
41
+ reverseCryptoProperties,
42
+ reverseEvidence,
43
+ } from "./cyclonedx20ReadEvidence.js";
44
+ import {
45
+ convertComponent,
46
+ convertService,
47
+ } from "./cyclonedx20RenderComponents.js";
48
+ import { identifierPartyRefId } from "./cyclonedx20RenderEvidence.js";
49
+ import {
50
+ CARRIED_SERVICE_PROPERTIES,
51
+ COMPONENT_TYPES_1X,
52
+ IDENTITY_SCHEME_FIELDS_1X,
53
+ } from "./cyclonedx20Tables.js";
54
+
55
+ const COMPONENT_ROLES = Object.freeze({
56
+ supplier: "supplier",
57
+ manufacturer: "manufacturer",
58
+ author: "authors",
59
+ publisher: "publisher",
60
+ });
61
+ const SERVICE_ROLES = Object.freeze({ provider: "provider" });
62
+
63
+ // The 1.x mime-type pattern (data/bom-1.7.schema.json component.mime-type).
64
+ const isMimeType1x = (value) => {
65
+ if (typeof value !== "string") {
66
+ return false;
67
+ }
68
+ const slash = value.indexOf("/");
69
+ const token = (part) =>
70
+ part.length > 0 &&
71
+ [...part].every(
72
+ (char) =>
73
+ (char >= "a" && char <= "z") ||
74
+ (char >= "0" && char <= "9") ||
75
+ char === "-" ||
76
+ char === "+" ||
77
+ char === ".",
78
+ );
79
+ return (
80
+ slash > 0 &&
81
+ value.indexOf("/", slash + 1) === -1 &&
82
+ token(value.slice(0, slash)) &&
83
+ token(value.slice(slash + 1))
84
+ );
85
+ };
86
+
87
+ /** One identity of an identifier group onto the 1.x fields. */
88
+ function reverseIdentity(ctx, fields, identity, pointer, componentName) {
89
+ if (!isObjectRecord(identity) || typeof identity.value !== "string") {
90
+ addLoss(ctx, pointer, "identity has no value");
91
+ return;
92
+ }
93
+ reportUnmapped(ctx, "identity", identity, pointer, IDENTITY_KEYS);
94
+ const scheme = identity.scheme;
95
+ const field =
96
+ typeof scheme === "string" &&
97
+ Object.hasOwn(IDENTITY_SCHEME_FIELDS_1X, scheme)
98
+ ? IDENTITY_SCHEME_FIELDS_1X[scheme]
99
+ : undefined;
100
+ if (!field) {
101
+ addLoss(
102
+ ctx,
103
+ jsonPointer(pointer, "scheme"),
104
+ "identity scheme has no 1.x field",
105
+ );
106
+ return;
107
+ }
108
+ if (field === "omniborId" || field === "swhid") {
109
+ (fields[field] ||= []).push(identity.value);
110
+ return;
111
+ }
112
+ if (fields[field] !== undefined) {
113
+ addLoss(ctx, pointer, `1.x holds one ${field}; only the first is kept`);
114
+ return;
115
+ }
116
+ if (field !== "swid") {
117
+ fields[field] = identity.value;
118
+ } else if (isNonEmptyString(componentName)) {
119
+ // 1.x swid requires tagId and name; the swid name is the software name.
120
+ fields.swid = { tagId: identity.value, name: componentName };
121
+ } else {
122
+ addLoss(ctx, pointer, "a 1.x swid needs the component name");
123
+ }
124
+ }
125
+ const IDENTITY_KEYS = Object.freeze(new Set(["scheme", "value"]));
126
+ const IDENTIFIER_KEYS = Object.freeze(new Set(["party", "identities"]));
127
+
128
+ /**
129
+ * component.identifiers → purl, cpe, swid, omniborId and swhid. 1.x has no
130
+ * attribution, so an identifier asserted by a party other than the one the
131
+ * renderer derives from the document's tools (identifierPartyRefId) is a
132
+ * loss, as is any scheme without a 1.x field.
133
+ */
134
+ function reverseIdentifiers(ctx, value, pointer, component) {
135
+ const fields = {};
136
+ reverseList(ctx, value, pointer, (_ctx, group, groupPointer) => {
137
+ if (!isObjectRecord(group)) {
138
+ addLoss(ctx, groupPointer, "identifier is not an object");
139
+ return undefined;
140
+ }
141
+ reportUnmapped(ctx, "identifier", group, groupPointer, IDENTIFIER_KEYS);
142
+ if (group.party !== identifierPartyRefId(ctx.claims)) {
143
+ addLoss(
144
+ ctx,
145
+ jsonPointer(groupPointer, "party"),
146
+ "1.x identifiers carry no asserting party",
147
+ );
148
+ }
149
+ (Array.isArray(group.identities) ? group.identities : []).forEach(
150
+ (identity, index) => {
151
+ reverseIdentity(
152
+ ctx,
153
+ fields,
154
+ identity,
155
+ jsonPointer(groupPointer, "identities", index),
156
+ component.name,
157
+ );
158
+ },
159
+ );
160
+ return undefined;
161
+ });
162
+ return fields;
163
+ }
164
+
165
+ /** data classification: a 2.0 enum value or custom `{name}` → 1.x string. */
166
+ function reverseClassification(ctx, value, pointer) {
167
+ if (typeof value === "string") {
168
+ return value;
169
+ }
170
+ if (isObjectRecord(value) && isNonEmptyString(value.name)) {
171
+ reportUnmapped(ctx, "classification", value, pointer, NAME_KEYS);
172
+ return value.name;
173
+ }
174
+ addLoss(ctx, pointer, "classification has no 1.x form");
175
+ return undefined;
176
+ }
177
+ const NAME_KEYS = Object.freeze(new Set(["name"]));
178
+ const CLASSIFICATION_RULE = Object.freeze({ convert: reverseClassification });
179
+
180
+ const GOVERNANCE_ROLE_FIELDS = Object.freeze({
181
+ custodian: "custodians",
182
+ steward: "stewards",
183
+ owner: "owners",
184
+ });
185
+
186
+ /**
187
+ * dataGovernance parties → the 1.x {custodians, stewards, owners} lists of
188
+ * `{organization}` or `{contact}` entries, the inverse of convertGovernance.
189
+ */
190
+ function reverseGovernance(ctx, value, pointer) {
191
+ const governance = {};
192
+ reverseList(ctx, value, pointer, (_ctx, entry, entryPointer) => {
193
+ const read = readParty(ctx, entry, entryPointer, GOVERNANCE_ROLE_FIELDS);
194
+ for (const role of read?.roles || []) {
195
+ const responsible =
196
+ read.identity.kind === "organization"
197
+ ? { organization: structuredClone(read.identity.identity) }
198
+ : { contact: structuredClone(read.identity.identity) };
199
+ (governance[GOVERNANCE_ROLE_FIELDS[role]] ||= []).push(responsible);
200
+ }
201
+ return undefined;
202
+ });
203
+ return Object.keys(governance).length ? governance : undefined;
204
+ }
205
+
206
+ const DATA_CONTENTS_SPEC = Object.freeze({
207
+ attachment: ATTACHMENT_RULE,
208
+ url: true,
209
+ properties: PROPERTIES_RULE,
210
+ });
211
+
212
+ /** graphics collection: graphic references have no 1.x form. */
213
+ function reverseGraphic(ctx, value, pointer) {
214
+ if (isObjectRecord(value) && typeof value.ref === "string") {
215
+ addLoss(ctx, pointer, "graphic reference has no 1.x form");
216
+ return undefined;
217
+ }
218
+ return reverseObject(ctx, "graphic", value, pointer, {
219
+ name: true,
220
+ image: Object.freeze({ convert: reverseAttachment }),
221
+ });
222
+ }
223
+
224
+ const GRAPHICS_SPEC = Object.freeze({
225
+ description: true,
226
+ collection: listOf(reverseGraphic),
227
+ });
228
+
229
+ const COMPONENT_DATA_SPEC = Object.freeze({
230
+ refId: "bom-ref",
231
+ type: true,
232
+ name: true,
233
+ contents: objectOf("data.contents", DATA_CONTENTS_SPEC),
234
+ classification: CLASSIFICATION_RULE,
235
+ sensitiveData: true,
236
+ graphics: objectOf("data.graphics", GRAPHICS_SPEC),
237
+ description: true,
238
+ governance: Object.freeze({ convert: reverseGovernance }),
239
+ });
240
+
241
+ /** componentData → 1.x componentData. */
242
+ function reverseComponentData(ctx, value, pointer) {
243
+ return reverseObject(
244
+ ctx,
245
+ "componentData",
246
+ value,
247
+ pointer,
248
+ COMPONENT_DATA_SPEC,
249
+ );
250
+ }
251
+
252
+ const SERVICE_DATA_SPEC = Object.freeze({
253
+ type: true,
254
+ name: true,
255
+ description: true,
256
+ classification: CLASSIFICATION_RULE,
257
+ governance: Object.freeze({ convert: reverseGovernance }),
258
+ });
259
+
260
+ /**
261
+ * Service componentData → 1.x serviceData, which requires `flow` and
262
+ * `classification`. 2.0 has no flow, so it reads as `unknown`; an entry with
263
+ * no classification cannot be 1.x service data.
264
+ */
265
+ function reverseServiceData(ctx, value, pointer) {
266
+ if (!isObjectRecord(value) || value.classification === undefined) {
267
+ addLoss(
268
+ ctx,
269
+ pointer,
270
+ "service data without a classification has no 1.x form",
271
+ );
272
+ return undefined;
273
+ }
274
+ const entry = reverseFields(
275
+ ctx,
276
+ "serviceData",
277
+ value,
278
+ pointer,
279
+ SERVICE_DATA_SPEC,
280
+ );
281
+ if (entry.type !== "other") {
282
+ addLoss(
283
+ ctx,
284
+ jsonPointer(pointer, "type"),
285
+ "service data type has no 1.x field",
286
+ );
287
+ }
288
+ delete entry.type;
289
+ if (entry.classification === undefined) {
290
+ return undefined;
291
+ }
292
+ return { flow: "unknown", ...entry };
293
+ }
294
+
295
+ /** A pedigree ancestor, descendant or variant entry → a 1.x component. */
296
+ function reversePedigreeEntry(ctx, value, pointer) {
297
+ const resolved = resolveComponentEntry(ctx, value, pointer);
298
+ if (!resolved) {
299
+ return undefined;
300
+ }
301
+ if (resolved.component.type === "service") {
302
+ addLoss(ctx, pointer, "a service has no 1.x pedigree form");
303
+ return undefined;
304
+ }
305
+ return reverseComponent(ctx, resolved.component, resolved.pointer);
306
+ }
307
+
308
+ const COMMIT_SPEC = Object.freeze({
309
+ uid: true,
310
+ url: true,
311
+ author: true,
312
+ committer: true,
313
+ message: true,
314
+ });
315
+
316
+ /** patch: a patch reference has no 1.x form, nor does the patch refId. */
317
+ function reversePatch(ctx, value, pointer) {
318
+ if (isObjectRecord(value) && typeof value.ref === "string") {
319
+ addLoss(ctx, pointer, "patch reference has no 1.x form");
320
+ return undefined;
321
+ }
322
+ return reverseObject(ctx, "patch", value, pointer, {
323
+ type: true,
324
+ diff: objectOf("diff", { text: ATTACHMENT_RULE, url: true }),
325
+ resolves: RESOLVES_RULE,
326
+ });
327
+ }
328
+
329
+ const PEDIGREE_SPEC = Object.freeze({
330
+ ancestors: listOf(reversePedigreeEntry),
331
+ descendants: listOf(reversePedigreeEntry),
332
+ variants: listOf(reversePedigreeEntry),
333
+ commits: listOf((ctx, value, pointer) =>
334
+ reverseObject(ctx, "commit", value, pointer, COMMIT_SPEC),
335
+ ),
336
+ patches: listOf(reversePatch),
337
+ notes: true,
338
+ });
339
+
340
+ /** Nested componentEntries → the 1.x `components` and `services`. */
341
+ function reverseNestedEntries(ctx, value, pointer) {
342
+ const components = [];
343
+ const services = [];
344
+ reverseList(ctx, value, pointer, (_ctx, entry, entryPointer) => {
345
+ const resolved = resolveComponentEntry(ctx, entry, entryPointer);
346
+ if (!resolved) {
347
+ return undefined;
348
+ }
349
+ if (resolved.component.type === "service") {
350
+ const service = reverseService(ctx, resolved.component, resolved.pointer);
351
+ if (service) {
352
+ services.push(service);
353
+ }
354
+ } else {
355
+ const component = reverseComponent(
356
+ ctx,
357
+ resolved.component,
358
+ resolved.pointer,
359
+ );
360
+ if (component) {
361
+ components.push(component);
362
+ }
363
+ }
364
+ return undefined;
365
+ });
366
+ const fields = {};
367
+ if (components.length) {
368
+ fields.components = components;
369
+ }
370
+ if (services.length) {
371
+ fields.services = services;
372
+ }
373
+ return fields;
374
+ }
375
+
376
+ /** modelProperties: only `properties` matches the 1.x modelCard. */
377
+ function reverseModelProperties(ctx, value, pointer) {
378
+ const modelCard = reverseObject(ctx, "modelProperties", value, pointer, {
379
+ properties: PROPERTIES_RULE,
380
+ });
381
+ return modelCard;
382
+ }
383
+
384
+ const COMPONENT_SPEC = Object.freeze({
385
+ type: true,
386
+ mediaType: Object.freeze({
387
+ to: "mime-type",
388
+ convert: (ctx, value, pointer) => {
389
+ if (isMimeType1x(value)) {
390
+ return value;
391
+ }
392
+ addLoss(
393
+ ctx,
394
+ pointer,
395
+ "mediaType does not match the 1.x mime-type pattern",
396
+ );
397
+ return undefined;
398
+ },
399
+ }),
400
+ refId: "bom-ref",
401
+ parties: Object.freeze({
402
+ spread: true,
403
+ convert: (ctx, value, pointer) =>
404
+ reverseParties(ctx, value, pointer, COMPONENT_ROLES),
405
+ }),
406
+ group: true,
407
+ name: true,
408
+ version: true,
409
+ versionRange: true,
410
+ isExternal: true,
411
+ description: true,
412
+ scope: true,
413
+ hashes: HASHES_RULE,
414
+ licenses: LICENSES_RULE,
415
+ copyright: true,
416
+ patentAssertions: PATENT_ASSERTIONS_RULE,
417
+ identifiers: Object.freeze({ spread: true, convert: reverseIdentifiers }),
418
+ pedigree: objectOf("pedigree", PEDIGREE_SPEC),
419
+ components: Object.freeze({ spread: true, convert: reverseNestedEntries }),
420
+ evidence: Object.freeze({ convert: reverseEvidence }),
421
+ releaseNotes: Object.freeze({ convert: reverseReleaseNotes }),
422
+ modelProperties: Object.freeze({
423
+ to: "modelCard",
424
+ convert: reverseModelProperties,
425
+ }),
426
+ data: listOf(reverseComponentData),
427
+ cryptoProperties: Object.freeze({ convert: reverseCryptoProperties }),
428
+ tags: true,
429
+ properties: PROPERTIES_RULE,
430
+ externalReferences: EXTERNAL_REFERENCES_RULE,
431
+ });
432
+
433
+ /**
434
+ * A 2.0 component (not a service) → a 1.x component, or undefined when its
435
+ * type has no 1.x equivalent (a loss).
436
+ *
437
+ * @param {object} ctx Reader context
438
+ * @param {object} component 2.0 component
439
+ * @param {string} pointer JSON pointer of `component`
440
+ * @returns {object|undefined} 1.x component
441
+ */
442
+ export function reverseComponent(ctx, component, pointer) {
443
+ if (!COMPONENT_TYPES_1X.has(component.type)) {
444
+ addLoss(
445
+ ctx,
446
+ jsonPointer(pointer, "type"),
447
+ `component type '${component.type}' has no 1.x equivalent; component dropped`,
448
+ );
449
+ return undefined;
450
+ }
451
+ return reverseFields(ctx, "component", component, pointer, COMPONENT_SPEC);
452
+ }
453
+
454
+ const SERVICE_SPEC = Object.freeze({
455
+ type: Object.freeze({ convert: () => undefined }),
456
+ refId: "bom-ref",
457
+ parties: Object.freeze({
458
+ spread: true,
459
+ convert: (ctx, value, pointer) =>
460
+ reverseParties(ctx, value, pointer, SERVICE_ROLES),
461
+ }),
462
+ group: true,
463
+ name: true,
464
+ version: true,
465
+ description: true,
466
+ endpoints: true,
467
+ licenses: LICENSES_RULE,
468
+ patentAssertions: PATENT_ASSERTIONS_RULE,
469
+ externalReferences: EXTERNAL_REFERENCES_RULE,
470
+ data: listOf(reverseServiceData),
471
+ components: Object.freeze({
472
+ to: "services",
473
+ convert: (ctx, value, pointer) => {
474
+ const nested = reverseNestedEntries(ctx, value, pointer);
475
+ if (nested.components) {
476
+ addLoss(ctx, pointer, "1.x services cannot nest components");
477
+ }
478
+ return nested.services;
479
+ },
480
+ }),
481
+ releaseNotes: Object.freeze({ convert: reverseReleaseNotes }),
482
+ tags: true,
483
+ properties: Object.freeze({
484
+ spread: true,
485
+ convert: reverseServiceProperties,
486
+ }),
487
+ });
488
+
489
+ /** CARRIED_SERVICE_PROPERTIES keyed by property name. */
490
+ const CARRIED_SERVICE_PROPERTY_BY_NAME = Object.freeze(
491
+ Object.fromEntries(
492
+ CARRIED_SERVICE_PROPERTIES.map(([field, name, kind]) => [
493
+ name,
494
+ Object.freeze({ field, kind }),
495
+ ]),
496
+ ),
497
+ );
498
+
499
+ /** A carried property value as its 1.x field value, or undefined. */
500
+ function parseCarriedServiceValue(kind, value) {
501
+ if (typeof value !== "string") {
502
+ return undefined;
503
+ }
504
+ if (kind === "boolean") {
505
+ return value === "true" ? true : value === "false" ? false : undefined;
506
+ }
507
+ return value;
508
+ }
509
+
510
+ /**
511
+ * Service properties: the cdx:service:* properties the renderer adds for the
512
+ * 1.x `authenticated`, `x-trust-boundary` and `trustZone` become those fields
513
+ * again (booleans for the first two) and leave the property list, so a
514
+ * render of the read model does not add them twice. A value that does not
515
+ * parse (or a repeat of a name already restored) stays a property.
516
+ */
517
+ function reverseServiceProperties(ctx, value, pointer) {
518
+ const properties = reverseList(ctx, value, pointer, reverseProperty);
519
+ if (!properties) {
520
+ return undefined;
521
+ }
522
+ const out = {};
523
+ const kept = [];
524
+ for (const property of properties) {
525
+ const carried = Object.hasOwn(
526
+ CARRIED_SERVICE_PROPERTY_BY_NAME,
527
+ property?.name ?? "",
528
+ )
529
+ ? CARRIED_SERVICE_PROPERTY_BY_NAME[property.name]
530
+ : undefined;
531
+ const parsed = carried
532
+ ? parseCarriedServiceValue(carried.kind, property.value)
533
+ : undefined;
534
+ if (parsed !== undefined && !Object.hasOwn(out, carried.field)) {
535
+ out[carried.field] = parsed;
536
+ } else {
537
+ kept.push(property);
538
+ }
539
+ }
540
+ if (kept.length) {
541
+ out.properties = kept;
542
+ }
543
+ return out;
544
+ }
545
+
546
+ /**
547
+ * A 2.0 component of type `service` → a 1.x service.
548
+ *
549
+ * @param {object} ctx Reader context
550
+ * @param {object} component 2.0 service component
551
+ * @param {string} pointer JSON pointer of `component`
552
+ * @returns {object} 1.x service
553
+ */
554
+ export function reverseService(ctx, component, pointer) {
555
+ return reverseFields(ctx, "service", component, pointer, SERVICE_SPEC);
556
+ }
557
+
558
+ /**
559
+ * Resolve a componentEntry (component, componentReference or
560
+ * component-choice) to a concrete component. A reference resolves against
561
+ * every declared component; a choice keeps its first resolvable member.
562
+ *
563
+ * @param {object} ctx Reader context (with `componentIndex`)
564
+ * @param {object} entry 2.0 componentEntry
565
+ * @param {string} pointer JSON pointer of `entry`
566
+ * @returns {{component: object, pointer: string}|undefined}
567
+ */
568
+ export function resolveComponentEntry(ctx, entry, pointer, depth = 0) {
569
+ if (!isObjectRecord(entry) || depth > 32) {
570
+ addLoss(ctx, pointer, "component entry is not an object");
571
+ return undefined;
572
+ }
573
+ if (typeof entry.ref === "string" && entry.name === undefined) {
574
+ const declared = ctx.componentIndex.get(entry.ref);
575
+ if (!declared) {
576
+ addLoss(
577
+ ctx,
578
+ jsonPointer(pointer, "ref"),
579
+ `component reference '${entry.ref}' could not be resolved`,
580
+ );
581
+ return undefined;
582
+ }
583
+ return resolveComponentEntry(
584
+ ctx,
585
+ declared.entry,
586
+ declared.pointer,
587
+ depth + 1,
588
+ );
589
+ }
590
+ if (entry.type === "component-choice") {
591
+ const members = Array.isArray(entry.components) ? entry.components : [];
592
+ for (let index = 0; index < members.length; index++) {
593
+ const memberPointer = jsonPointer(pointer, "components", index);
594
+ const resolved = resolveComponentEntry(
595
+ ctx,
596
+ members[index],
597
+ memberPointer,
598
+ depth + 1,
599
+ );
600
+ if (resolved) {
601
+ addLoss(
602
+ ctx,
603
+ pointer,
604
+ "component-choice has no 1.x form; its first member is kept",
605
+ );
606
+ return resolved;
607
+ }
608
+ }
609
+ addLoss(ctx, pointer, "component-choice has no resolvable member");
610
+ return undefined;
611
+ }
612
+ return { component: entry, pointer };
613
+ }
614
+
615
+ /**
616
+ * Read one top-level component entry (an inventory entry, subject, tool,
617
+ * definitions component, formula component or annotator) into 1.x, as a
618
+ * component or a service. `needsShadow` is set when the 1.x value does not
619
+ * render back to the same 2.0 entry; a caller that keeps the entry passes the
620
+ * result to keepComponentShadow.
621
+ *
622
+ * @param {object} ctx Reader context
623
+ * @param {object} entry 2.0 componentEntry
624
+ * @param {string} pointer JSON pointer of `entry`
625
+ * @returns {{internal: object, isService: boolean, refId?: string, entry: object, needsShadow: boolean}|undefined}
626
+ */
627
+ export function readComponentEntry(ctx, entry, pointer) {
628
+ const before = ctx.losses.length;
629
+ const resolved = resolveComponentEntry(ctx, entry, pointer);
630
+ if (!resolved) {
631
+ return undefined;
632
+ }
633
+ const isService = resolved.component.type === "service";
634
+ const internal = isService
635
+ ? reverseService(ctx, resolved.component, resolved.pointer)
636
+ : reverseComponent(ctx, resolved.component, resolved.pointer);
637
+ if (!internal) {
638
+ return undefined;
639
+ }
640
+ const stats = createRenderStats(undefined, ctx.claims);
641
+ const rendered = isService
642
+ ? convertService(internal, stats)
643
+ : convertComponent(internal, stats);
644
+ return {
645
+ internal,
646
+ isService,
647
+ refId: resolved.component.refId,
648
+ entry,
649
+ needsShadow:
650
+ ctx.losses.length > before || !isDeepStrictEqual(rendered, entry),
651
+ };
652
+ }
653
+
654
+ /**
655
+ * Note a kept component entry for the shadows. Entries read inside a section
656
+ * entry that is itself restored whole (annotations, vulnerabilities) are not
657
+ * noted, since the renderer never converts them.
658
+ *
659
+ * @param {object} ctx Reader context
660
+ * @param {object} read Result of readComponentEntry
661
+ */
662
+ export function keepComponentShadow(ctx, read) {
663
+ if (!read || ctx.shadowSuspended) {
664
+ return;
665
+ }
666
+ ctx.keptComponents.push({
667
+ key: shadowKey(read.internal),
668
+ original: read.entry,
669
+ needsShadow: read.needsShadow,
670
+ });
671
+ }
672
+
673
+ /**
674
+ * Register the component shadows. Kept entries whose 1.x values are
675
+ * identical share a key; when any of them needs a shadow, all of them are
676
+ * registered in document order, which is the order the renderer converts
677
+ * them in, so each gets its own original back.
678
+ *
679
+ * @param {object} ctx Reader context
680
+ */
681
+ export function flushComponentShadows(ctx) {
682
+ const needed = new Set(
683
+ ctx.keptComponents
684
+ .filter((kept) => kept.needsShadow)
685
+ .map((kept) => kept.key),
686
+ );
687
+ for (const kept of ctx.keptComponents) {
688
+ if (needed.has(kept.key)) {
689
+ registerShadowKey(ctx, "component", kept.key, kept.original);
690
+ }
691
+ }
692
+ }