@cdxgen/cdxgen 0.0.1 → 13.0.1

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 (722) hide show
  1. package/README.md +921 -87
  2. package/bin/audit.js +239 -0
  3. package/bin/cdxgen.js +2335 -0
  4. package/bin/convert.js +220 -0
  5. package/bin/evinse.js +353 -0
  6. package/bin/hbom.js +504 -0
  7. package/bin/repl.js +2224 -0
  8. package/bin/sign.js +195 -0
  9. package/bin/tracebom.js +303 -0
  10. package/bin/validate.js +268 -0
  11. package/bin/verify.js +189 -0
  12. package/data/README.md +307 -0
  13. package/data/bom-1.4.schema.json +1605 -0
  14. package/data/bom-1.5.schema.json +3660 -0
  15. package/data/bom-1.6.schema.json +5511 -0
  16. package/data/bom-1.7.schema.json +6700 -0
  17. package/data/cbomosdb-queries.json +68 -0
  18. package/data/component-tags.json +339 -0
  19. package/data/container-knowledge-index.json +125 -0
  20. package/data/cosdb-queries.json +17 -0
  21. package/data/crypto-oid.json +1998 -0
  22. package/data/cryptography-defs.json +3793 -0
  23. package/data/cryptography-defs.schema.json +576 -0
  24. package/data/cyclonedx-2.0-bundled.schema.json +7182 -0
  25. package/data/frameworks-list.json +219 -0
  26. package/data/glibc-stdlib.json +117 -0
  27. package/data/gtfobins-index.json +6296 -0
  28. package/data/helpers/init.gradle +71 -0
  29. package/data/jsf-0.82.schema.json +211 -0
  30. package/data/known-licenses.json +82 -0
  31. package/data/lic-mapping.json +338 -0
  32. package/data/license-aliases.json +6624 -0
  33. package/data/license-db.json +39059 -0
  34. package/data/license-deprecations.json +302 -0
  35. package/data/lolbas-index.json +150 -0
  36. package/data/predictive-audit-allowlist.json +11 -0
  37. package/data/pypi-pkg-aliases.json +1199 -0
  38. package/data/python-stdlib.json +308 -0
  39. package/data/queries-darwin.json +193 -0
  40. package/data/queries-win.json +257 -0
  41. package/data/queries.json +268 -0
  42. package/data/ruby-known-modules.json +281 -0
  43. package/data/rules/ai-agent-governance.yaml +323 -0
  44. package/data/rules/ai-bom.yaml +268 -0
  45. package/data/rules/ai-oversight.yaml +186 -0
  46. package/data/rules/ai-provenance.yaml +92 -0
  47. package/data/rules/asar-archives.yaml +150 -0
  48. package/data/rules/cbom-security.yaml +165 -0
  49. package/data/rules/chrome-extensions.yaml +248 -0
  50. package/data/rules/ci-permissions.yaml +802 -0
  51. package/data/rules/container-risk.yaml +353 -0
  52. package/data/rules/dependency-sources.yaml +236 -0
  53. package/data/rules/golem-go.yaml +229 -0
  54. package/data/rules/hbom-compliance.yaml +325 -0
  55. package/data/rules/hbom-performance.yaml +307 -0
  56. package/data/rules/hbom-security.yaml +248 -0
  57. package/data/rules/host-topology.yaml +165 -0
  58. package/data/rules/mcp-servers.yaml +388 -0
  59. package/data/rules/obom-runtime.yaml +1776 -0
  60. package/data/rules/package-integrity.yaml +364 -0
  61. package/data/rules/rootfs-hardening.yaml +179 -0
  62. package/data/rules/vscode-extensions.yaml +237 -0
  63. package/data/spdx-export.schema.json +6794 -0
  64. package/data/spdx-license-list.json +7449 -0
  65. package/data/spdx-licenses.json +759 -0
  66. package/data/spdx.schema.json +819 -0
  67. package/data/templates/README.md +3 -0
  68. package/data/templates/asvs-4.0.3.cdx.json +2943 -0
  69. package/data/templates/asvs-5.0.cdx.json +3046 -0
  70. package/data/templates/bsimm-v13.cdx.json +1008 -0
  71. package/data/templates/masvs-2.0.0.cdx.json +225 -0
  72. package/data/templates/nist-ssdf-1.1.cdx.json +828 -0
  73. package/data/templates/pcissc-secure-slc-1.1.cdx.json +1027 -0
  74. package/data/templates/scvs-1.0.0.cdx.json +813 -0
  75. package/data/templates/ssaf-DRAFT-2023-11.cdx.json +127 -0
  76. package/data/vendor-alias.json +41967 -0
  77. package/data/wrapdb-releases.json +4227 -0
  78. package/index.cjs +15 -0
  79. package/lib/audit/index.js +2800 -0
  80. package/lib/audit/progress.js +114 -0
  81. package/lib/audit/reporters.js +937 -0
  82. package/lib/audit/scoring.js +560 -0
  83. package/lib/audit/targets.js +798 -0
  84. package/lib/cli/bomAssembly.js +1882 -0
  85. package/lib/cli/cliOptions.js +543 -0
  86. package/lib/cli/index.js +2759 -0
  87. package/lib/cli/jsBom.js +2087 -0
  88. package/lib/cli/jvmBom.js +1858 -0
  89. package/lib/cli/managedBom.js +2083 -0
  90. package/lib/cli/nativeBom.js +2125 -0
  91. package/lib/core/activity.js +1087 -0
  92. package/lib/core/env.js +719 -0
  93. package/lib/core/fs.js +1058 -0
  94. package/lib/core/httpClient.js +730 -0
  95. package/lib/core/logger.js +280 -0
  96. package/lib/core/parallel.js +323 -0
  97. package/lib/core/paths.js +70 -0
  98. package/lib/core/projectConfig.js +122 -0
  99. package/lib/core/propertySanitizer.js +174 -0
  100. package/lib/core/spdx.js +5 -0
  101. package/lib/core/state.js +59 -0
  102. package/lib/core/text.js +207 -0
  103. package/lib/core/ui.js +920 -0
  104. package/lib/core/urls.js +84 -0
  105. package/lib/ecosystems/asarutils.js +1636 -0
  106. package/lib/ecosystems/bunutils.js +402 -0
  107. package/lib/ecosystems/caxa.js +77 -0
  108. package/lib/ecosystems/chromextutils.js +1174 -0
  109. package/lib/ecosystems/cmakeResolver.js +587 -0
  110. package/lib/ecosystems/cppEvidence.js +305 -0
  111. package/lib/ecosystems/denoutils.js +1094 -0
  112. package/lib/ecosystems/dotnetutils.js +132 -0
  113. package/lib/ecosystems/ecosystems.js +2772 -0
  114. package/lib/ecosystems/golem.js +1807 -0
  115. package/lib/ecosystems/gradleutils.js +1048 -0
  116. package/lib/ecosystems/jsEvidence.js +317 -0
  117. package/lib/ecosystems/npmutils.js +586 -0
  118. package/lib/ecosystems/parsers-bazel.js +875 -0
  119. package/lib/ecosystems/parsers-dotnet.js +1430 -0
  120. package/lib/ecosystems/parsers-gleam.js +302 -0
  121. package/lib/ecosystems/parsers-go.js +818 -0
  122. package/lib/ecosystems/parsers-js.js +4222 -0
  123. package/lib/ecosystems/parsers-jvm.js +948 -0
  124. package/lib/ecosystems/parsers-misc.js +3191 -0
  125. package/lib/ecosystems/parsers-python.js +2070 -0
  126. package/lib/ecosystems/parsers-rust.js +1294 -0
  127. package/lib/ecosystems/parsers-zig.js +861 -0
  128. package/lib/ecosystems/pep770.js +341 -0
  129. package/lib/ecosystems/pylockutils.js +427 -0
  130. package/lib/ecosystems/pythonutils.js +1281 -0
  131. package/lib/ecosystems/registryProvenance.js +1003 -0
  132. package/lib/ecosystems/remote/huggingface.js +1343 -0
  133. package/lib/ecosystems/rubyutils.js +1629 -0
  134. package/lib/ecosystems/rusi.js +820 -0
  135. package/lib/ecosystems/sbtutils.js +972 -0
  136. package/lib/ecosystems/tea.js +607 -0
  137. package/lib/ecosystems/utils.js +583 -0
  138. package/lib/ecosystems/zigResolver.js +410 -0
  139. package/lib/evinser/db.js +145 -0
  140. package/lib/evinser/evinser.js +2362 -0
  141. package/lib/evinser/scalasem.js +65 -0
  142. package/lib/evinser/swiftsem.js +767 -0
  143. package/lib/helpers/annotationFormatter.js +84 -0
  144. package/lib/helpers/bomSigner.js +312 -0
  145. package/lib/helpers/exportUtils.js +160 -0
  146. package/lib/helpers/remote/dependency-track.js +117 -0
  147. package/lib/helpers/versutils.js +202 -0
  148. package/lib/helpers/vsixutils.js +1069 -0
  149. package/lib/inventory/agentFormulationParser.js +322 -0
  150. package/lib/inventory/aiCollector.js +2140 -0
  151. package/lib/inventory/aiInventory.js +414 -0
  152. package/lib/inventory/aiModelVariants.js +121 -0
  153. package/lib/inventory/aiOversightCollector.js +661 -0
  154. package/lib/inventory/aiProvenanceCollector.js +822 -0
  155. package/lib/inventory/analyzer.js +6089 -0
  156. package/lib/inventory/analyzerScope.js +807 -0
  157. package/lib/inventory/astWorker.js +20 -0
  158. package/lib/inventory/atomUtils.js +1092 -0
  159. package/lib/inventory/auditCategories.js +192 -0
  160. package/lib/inventory/bomUtils.js +369 -0
  161. package/lib/inventory/cacheCommands.js +182 -0
  162. package/lib/inventory/cacheDir.js +104 -0
  163. package/lib/inventory/cbomutils.js +590 -0
  164. package/lib/inventory/cdxrs.js +434 -0
  165. package/lib/inventory/ciParsers/azurePipelines.js +295 -0
  166. package/lib/inventory/ciParsers/circleCi.js +286 -0
  167. package/lib/inventory/ciParsers/common.js +24 -0
  168. package/lib/inventory/ciParsers/githubActions.js +2434 -0
  169. package/lib/inventory/ciParsers/gitlabCi.js +213 -0
  170. package/lib/inventory/ciParsers/jenkins.js +180 -0
  171. package/lib/inventory/citations.js +234 -0
  172. package/lib/inventory/communityAiConfigParser.js +756 -0
  173. package/lib/inventory/containerRisk.js +204 -0
  174. package/lib/inventory/cryptoAlgorithmFamily.js +258 -0
  175. package/lib/inventory/deps.js +807 -0
  176. package/lib/inventory/depsUtils.js +588 -0
  177. package/lib/inventory/display.js +2128 -0
  178. package/lib/inventory/dosai.js +601 -0
  179. package/lib/inventory/dosaiParsers.js +154 -0
  180. package/lib/inventory/dynamic.js +145 -0
  181. package/lib/inventory/envcontext.js +1793 -0
  182. package/lib/inventory/evidenceUtils.js +774 -0
  183. package/lib/inventory/fetchBatch.js +779 -0
  184. package/lib/inventory/fetchRate.js +255 -0
  185. package/lib/inventory/forgeEnricher.js +300 -0
  186. package/lib/inventory/formulationParsers.js +422 -0
  187. package/lib/inventory/gtfobins.js +339 -0
  188. package/lib/inventory/hbom.js +719 -0
  189. package/lib/inventory/hbomAnalysis.js +310 -0
  190. package/lib/inventory/hbomLoader.js +35 -0
  191. package/lib/inventory/hostTopology.js +835 -0
  192. package/lib/inventory/inventoryStats.js +100 -0
  193. package/lib/inventory/jsonLike.js +121 -0
  194. package/lib/inventory/licenseEnhancer.js +918 -0
  195. package/lib/inventory/lolbas.js +285 -0
  196. package/lib/inventory/mcp.js +253 -0
  197. package/lib/inventory/mcpConfigParser.js +683 -0
  198. package/lib/inventory/mcpDiscovery.js +112 -0
  199. package/lib/inventory/mcpPinning.js +209 -0
  200. package/lib/inventory/osPackageResolver.js +493 -0
  201. package/lib/inventory/osinfo.js +383 -0
  202. package/lib/inventory/osqueryTransform.js +274 -0
  203. package/lib/inventory/plugins.js +466 -0
  204. package/lib/inventory/protobom.js +231 -0
  205. package/lib/inventory/protobomLoader.js +43 -0
  206. package/lib/inventory/provenanceUtils.js +224 -0
  207. package/lib/inventory/purl.js +749 -0
  208. package/lib/inventory/rustFormulationParser.js +339 -0
  209. package/lib/inventory/sbomDocument.js +340 -0
  210. package/lib/inventory/source.js +1488 -0
  211. package/lib/inventory/spdx.js +361 -0
  212. package/lib/inventory/spdxExpression.js +512 -0
  213. package/lib/inventory/spdxUtils.js +107 -0
  214. package/lib/inventory/table.js +267 -0
  215. package/lib/inventory/traceRunner.js +439 -0
  216. package/lib/inventory/unicodeScan.js +147 -0
  217. package/lib/managers/binary.js +3459 -0
  218. package/lib/managers/containerutils.js +125 -0
  219. package/lib/managers/docker.js +2145 -0
  220. package/lib/managers/dockerConnection.js +162 -0
  221. package/lib/managers/oci.js +704 -0
  222. package/lib/managers/piptree.js +267 -0
  223. package/lib/parsers/cmakeCache.js +199 -0
  224. package/lib/parsers/gguf.js +492 -0
  225. package/lib/parsers/gitAiNotes.js +233 -0
  226. package/lib/parsers/gitmodules.js +239 -0
  227. package/lib/parsers/htmlExtract.js +610 -0
  228. package/lib/parsers/huggingfaceManifest.js +551 -0
  229. package/lib/parsers/huggingfaceUtils.js +506 -0
  230. package/lib/parsers/iri.js +618 -0
  231. package/lib/parsers/npmrc.js +99 -0
  232. package/lib/parsers/ollama.js +101 -0
  233. package/lib/parsers/xml.js +841 -0
  234. package/lib/server/openapi.yaml +433 -0
  235. package/lib/server/server.js +616 -0
  236. package/lib/stages/postgen/annotator.js +977 -0
  237. package/lib/stages/postgen/auditBom.js +468 -0
  238. package/lib/stages/postgen/postgen.js +1239 -0
  239. package/lib/stages/postgen/ruleEngine.js +731 -0
  240. package/lib/stages/postgen/sortBom.js +195 -0
  241. package/lib/stages/postgen/spdxConverter.js +796 -0
  242. package/lib/stages/postgen/specVersionCompat.js +703 -0
  243. package/lib/stages/pregen/envAudit.js +388 -0
  244. package/lib/stages/pregen/pregen.js +637 -0
  245. package/lib/third-party/README.md +9 -0
  246. package/lib/third-party/arborist/CHANGELOG.md +1109 -0
  247. package/lib/third-party/arborist/LICENSE.md +20 -0
  248. package/lib/third-party/arborist/README.md +315 -0
  249. package/lib/third-party/arborist/lib/arborist/index.js +258 -0
  250. package/lib/third-party/arborist/lib/arborist/load-actual.js +605 -0
  251. package/lib/third-party/arborist/lib/arborist/load-virtual.js +300 -0
  252. package/lib/third-party/arborist/lib/bin-links.js +120 -0
  253. package/lib/third-party/arborist/lib/calc-dep-flags.js +130 -0
  254. package/lib/third-party/arborist/lib/case-insensitive-map.js +51 -0
  255. package/lib/third-party/arborist/lib/consistent-resolve.js +42 -0
  256. package/lib/third-party/arborist/lib/debug.js +50 -0
  257. package/lib/third-party/arborist/lib/dep-valid.js +190 -0
  258. package/lib/third-party/arborist/lib/edge.js +417 -0
  259. package/lib/third-party/arborist/lib/from-path.js +36 -0
  260. package/lib/third-party/arborist/lib/gather-dep-set.js +43 -0
  261. package/lib/third-party/arborist/lib/index.js +22 -0
  262. package/lib/third-party/arborist/lib/inventory.js +138 -0
  263. package/lib/third-party/arborist/lib/link.js +169 -0
  264. package/lib/third-party/arborist/lib/node.js +1673 -0
  265. package/lib/third-party/arborist/lib/npm-extension.js +45 -0
  266. package/lib/third-party/arborist/lib/override-resolves.js +11 -0
  267. package/lib/third-party/arborist/lib/override-set.js +319 -0
  268. package/lib/third-party/arborist/lib/package-extensions.js +289 -0
  269. package/lib/third-party/arborist/lib/printable.js +210 -0
  270. package/lib/third-party/arborist/lib/proc-log.js +30 -0
  271. package/lib/third-party/arborist/lib/realpath.js +100 -0
  272. package/lib/third-party/arborist/lib/relpath.js +4 -0
  273. package/lib/third-party/arborist/lib/shrinkwrap.js +1291 -0
  274. package/lib/third-party/arborist/lib/spec-from-lock.js +34 -0
  275. package/lib/third-party/arborist/lib/tree-check.js +165 -0
  276. package/lib/third-party/arborist/lib/validate-npm-package-name.js +107 -0
  277. package/lib/third-party/arborist/lib/version-from-tgz.js +51 -0
  278. package/lib/third-party/arborist/lib/yarn-lock.js +397 -0
  279. package/lib/validator/bomValidator.js +985 -0
  280. package/lib/validator/complianceEngine.js +241 -0
  281. package/lib/validator/complianceRules.js +1680 -0
  282. package/lib/validator/generated/runtime.mjs +17 -0
  283. package/lib/validator/generated/validate-1.6.mjs +21258 -0
  284. package/lib/validator/generated/validate-1.7.mjs +24803 -0
  285. package/lib/validator/generated/validate-2.0.mjs +22931 -0
  286. package/lib/validator/index.js +246 -0
  287. package/lib/validator/reporters/annotations.js +142 -0
  288. package/lib/validator/reporters/console.js +160 -0
  289. package/lib/validator/reporters/index.js +41 -0
  290. package/lib/validator/reporters/json.js +37 -0
  291. package/lib/validator/reporters/sarif.js +184 -0
  292. package/package.json +209 -26
  293. package/types/bin/audit.d.ts +3 -0
  294. package/types/bin/audit.d.ts.map +1 -0
  295. package/types/bin/cdxgen.d.ts +3 -0
  296. package/types/bin/cdxgen.d.ts.map +1 -0
  297. package/types/bin/convert.d.ts +3 -0
  298. package/types/bin/convert.d.ts.map +1 -0
  299. package/types/bin/evinse.d.ts +3 -0
  300. package/types/bin/evinse.d.ts.map +1 -0
  301. package/types/bin/hbom.d.ts +3 -0
  302. package/types/bin/hbom.d.ts.map +1 -0
  303. package/types/bin/repl.d.ts +3 -0
  304. package/types/bin/repl.d.ts.map +1 -0
  305. package/types/bin/sign.d.ts +3 -0
  306. package/types/bin/sign.d.ts.map +1 -0
  307. package/types/bin/tracebom.d.ts +3 -0
  308. package/types/bin/tracebom.d.ts.map +1 -0
  309. package/types/bin/validate.d.ts +14 -0
  310. package/types/bin/validate.d.ts.map +1 -0
  311. package/types/bin/verify.d.ts +3 -0
  312. package/types/bin/verify.d.ts.map +1 -0
  313. package/types/lib/audit/index.d.ts +153 -0
  314. package/types/lib/audit/index.d.ts.map +1 -0
  315. package/types/lib/audit/progress.d.ts +31 -0
  316. package/types/lib/audit/progress.d.ts.map +1 -0
  317. package/types/lib/audit/reporters.d.ts +62 -0
  318. package/types/lib/audit/reporters.d.ts.map +1 -0
  319. package/types/lib/audit/scoring.d.ts +36 -0
  320. package/types/lib/audit/scoring.d.ts.map +1 -0
  321. package/types/lib/audit/targets.d.ts +77 -0
  322. package/types/lib/audit/targets.d.ts.map +1 -0
  323. package/types/lib/cli/bomAssembly.d.ts +329 -0
  324. package/types/lib/cli/bomAssembly.d.ts.map +1 -0
  325. package/types/lib/cli/cliOptions.d.ts +156 -0
  326. package/types/lib/cli/cliOptions.d.ts.map +1 -0
  327. package/types/lib/cli/index.d.ts +107 -0
  328. package/types/lib/cli/index.d.ts.map +1 -0
  329. package/types/lib/cli/jsBom.d.ts +94 -0
  330. package/types/lib/cli/jsBom.d.ts.map +1 -0
  331. package/types/lib/cli/jvmBom.d.ts +54 -0
  332. package/types/lib/cli/jvmBom.d.ts.map +1 -0
  333. package/types/lib/cli/managedBom.d.ts +105 -0
  334. package/types/lib/cli/managedBom.d.ts.map +1 -0
  335. package/types/lib/cli/nativeBom.d.ts +143 -0
  336. package/types/lib/cli/nativeBom.d.ts.map +1 -0
  337. package/types/lib/core/activity.d.ts +178 -0
  338. package/types/lib/core/activity.d.ts.map +1 -0
  339. package/types/lib/core/env.d.ts +192 -0
  340. package/types/lib/core/env.d.ts.map +1 -0
  341. package/types/lib/core/fs.d.ts +158 -0
  342. package/types/lib/core/fs.d.ts.map +1 -0
  343. package/types/lib/core/httpClient.d.ts +149 -0
  344. package/types/lib/core/httpClient.d.ts.map +1 -0
  345. package/types/lib/core/logger.d.ts +50 -0
  346. package/types/lib/core/logger.d.ts.map +1 -0
  347. package/types/lib/core/parallel.d.ts +95 -0
  348. package/types/lib/core/parallel.d.ts.map +1 -0
  349. package/types/lib/core/paths.d.ts +36 -0
  350. package/types/lib/core/paths.d.ts.map +1 -0
  351. package/types/lib/core/projectConfig.d.ts +23 -0
  352. package/types/lib/core/projectConfig.d.ts.map +1 -0
  353. package/types/lib/core/propertySanitizer.d.ts +23 -0
  354. package/types/lib/core/propertySanitizer.d.ts.map +1 -0
  355. package/types/lib/core/spdx.d.ts +5 -0
  356. package/types/lib/core/spdx.d.ts.map +1 -0
  357. package/types/lib/core/state.d.ts +20 -0
  358. package/types/lib/core/state.d.ts.map +1 -0
  359. package/types/lib/core/text.d.ts +78 -0
  360. package/types/lib/core/text.d.ts.map +1 -0
  361. package/types/lib/core/ui.d.ts +87 -0
  362. package/types/lib/core/ui.d.ts.map +1 -0
  363. package/types/lib/core/urls.d.ts +43 -0
  364. package/types/lib/core/urls.d.ts.map +1 -0
  365. package/types/lib/ecosystems/asarutils.d.ts +71 -0
  366. package/types/lib/ecosystems/asarutils.d.ts.map +1 -0
  367. package/types/lib/ecosystems/bunutils.d.ts +38 -0
  368. package/types/lib/ecosystems/bunutils.d.ts.map +1 -0
  369. package/types/lib/ecosystems/caxa.d.ts +8 -0
  370. package/types/lib/ecosystems/caxa.d.ts.map +1 -0
  371. package/types/lib/ecosystems/chromextutils.d.ts +97 -0
  372. package/types/lib/ecosystems/chromextutils.d.ts.map +1 -0
  373. package/types/lib/ecosystems/cmakeResolver.d.ts +176 -0
  374. package/types/lib/ecosystems/cmakeResolver.d.ts.map +1 -0
  375. package/types/lib/ecosystems/cppEvidence.d.ts +35 -0
  376. package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -0
  377. package/types/lib/ecosystems/denoutils.d.ts +76 -0
  378. package/types/lib/ecosystems/denoutils.d.ts.map +1 -0
  379. package/types/lib/ecosystems/dotnetutils.d.ts +45 -0
  380. package/types/lib/ecosystems/dotnetutils.d.ts.map +1 -0
  381. package/types/lib/ecosystems/ecosystems.d.ts +279 -0
  382. package/types/lib/ecosystems/ecosystems.d.ts.map +1 -0
  383. package/types/lib/ecosystems/golem.d.ts +60 -0
  384. package/types/lib/ecosystems/golem.d.ts.map +1 -0
  385. package/types/lib/ecosystems/gradleutils.d.ts +139 -0
  386. package/types/lib/ecosystems/gradleutils.d.ts.map +1 -0
  387. package/types/lib/ecosystems/jsEvidence.d.ts +17 -0
  388. package/types/lib/ecosystems/jsEvidence.d.ts.map +1 -0
  389. package/types/lib/ecosystems/npmutils.d.ts +183 -0
  390. package/types/lib/ecosystems/npmutils.d.ts.map +1 -0
  391. package/types/lib/ecosystems/parsers-bazel.d.ts +36 -0
  392. package/types/lib/ecosystems/parsers-bazel.d.ts.map +1 -0
  393. package/types/lib/ecosystems/parsers-dotnet.d.ts +116 -0
  394. package/types/lib/ecosystems/parsers-dotnet.d.ts.map +1 -0
  395. package/types/lib/ecosystems/parsers-gleam.d.ts +33 -0
  396. package/types/lib/ecosystems/parsers-gleam.d.ts.map +1 -0
  397. package/types/lib/ecosystems/parsers-go.d.ts +92 -0
  398. package/types/lib/ecosystems/parsers-go.d.ts.map +1 -0
  399. package/types/lib/ecosystems/parsers-js.d.ts +242 -0
  400. package/types/lib/ecosystems/parsers-js.d.ts.map +1 -0
  401. package/types/lib/ecosystems/parsers-jvm.d.ts +100 -0
  402. package/types/lib/ecosystems/parsers-jvm.d.ts.map +1 -0
  403. package/types/lib/ecosystems/parsers-misc.d.ts +450 -0
  404. package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -0
  405. package/types/lib/ecosystems/parsers-python.d.ts +145 -0
  406. package/types/lib/ecosystems/parsers-python.d.ts.map +1 -0
  407. package/types/lib/ecosystems/parsers-rust.d.ts +56 -0
  408. package/types/lib/ecosystems/parsers-rust.d.ts.map +1 -0
  409. package/types/lib/ecosystems/parsers-zig.d.ts +83 -0
  410. package/types/lib/ecosystems/parsers-zig.d.ts.map +1 -0
  411. package/types/lib/ecosystems/pep770.d.ts +38 -0
  412. package/types/lib/ecosystems/pep770.d.ts.map +1 -0
  413. package/types/lib/ecosystems/pylockutils.d.ts +68 -0
  414. package/types/lib/ecosystems/pylockutils.d.ts.map +1 -0
  415. package/types/lib/ecosystems/pythonutils.d.ts +70 -0
  416. package/types/lib/ecosystems/pythonutils.d.ts.map +1 -0
  417. package/types/lib/ecosystems/registryProvenance.d.ts +26 -0
  418. package/types/lib/ecosystems/registryProvenance.d.ts.map +1 -0
  419. package/types/lib/ecosystems/remote/huggingface.d.ts +31 -0
  420. package/types/lib/ecosystems/remote/huggingface.d.ts.map +1 -0
  421. package/types/lib/ecosystems/rubyutils.d.ts +182 -0
  422. package/types/lib/ecosystems/rubyutils.d.ts.map +1 -0
  423. package/types/lib/ecosystems/rusi.d.ts +40 -0
  424. package/types/lib/ecosystems/rusi.d.ts.map +1 -0
  425. package/types/lib/ecosystems/sbtutils.d.ts +179 -0
  426. package/types/lib/ecosystems/sbtutils.d.ts.map +1 -0
  427. package/types/lib/ecosystems/tea.d.ts +180 -0
  428. package/types/lib/ecosystems/tea.d.ts.map +1 -0
  429. package/types/lib/ecosystems/utils.d.ts +41 -0
  430. package/types/lib/ecosystems/utils.d.ts.map +1 -0
  431. package/types/lib/ecosystems/zigResolver.d.ts +70 -0
  432. package/types/lib/ecosystems/zigResolver.d.ts.map +1 -0
  433. package/types/lib/evinser/db.d.ts +17 -0
  434. package/types/lib/evinser/db.d.ts.map +1 -0
  435. package/types/lib/evinser/evinser.d.ts +354 -0
  436. package/types/lib/evinser/evinser.d.ts.map +1 -0
  437. package/types/lib/evinser/scalasem.d.ts +15 -0
  438. package/types/lib/evinser/scalasem.d.ts.map +1 -0
  439. package/types/lib/evinser/swiftsem.d.ts +103 -0
  440. package/types/lib/evinser/swiftsem.d.ts.map +1 -0
  441. package/types/lib/helpers/annotationFormatter.d.ts +23 -0
  442. package/types/lib/helpers/annotationFormatter.d.ts.map +1 -0
  443. package/types/lib/helpers/bomSigner.d.ts +28 -0
  444. package/types/lib/helpers/bomSigner.d.ts.map +1 -0
  445. package/types/lib/helpers/exportUtils.d.ts +52 -0
  446. package/types/lib/helpers/exportUtils.d.ts.map +1 -0
  447. package/types/lib/helpers/remote/dependency-track.d.ts +23 -0
  448. package/types/lib/helpers/remote/dependency-track.d.ts.map +1 -0
  449. package/types/lib/helpers/versutils.d.ts +8 -0
  450. package/types/lib/helpers/versutils.d.ts.map +1 -0
  451. package/types/lib/helpers/vsixutils.d.ts +130 -0
  452. package/types/lib/helpers/vsixutils.d.ts.map +1 -0
  453. package/types/lib/inventory/agentFormulationParser.d.ts +21 -0
  454. package/types/lib/inventory/agentFormulationParser.d.ts.map +1 -0
  455. package/types/lib/inventory/aiCollector.d.ts +61 -0
  456. package/types/lib/inventory/aiCollector.d.ts.map +1 -0
  457. package/types/lib/inventory/aiInventory.d.ts +103 -0
  458. package/types/lib/inventory/aiInventory.d.ts.map +1 -0
  459. package/types/lib/inventory/aiModelVariants.d.ts +31 -0
  460. package/types/lib/inventory/aiModelVariants.d.ts.map +1 -0
  461. package/types/lib/inventory/aiOversightCollector.d.ts +28 -0
  462. package/types/lib/inventory/aiOversightCollector.d.ts.map +1 -0
  463. package/types/lib/inventory/aiProvenanceCollector.d.ts +13 -0
  464. package/types/lib/inventory/aiProvenanceCollector.d.ts.map +1 -0
  465. package/types/lib/inventory/analyzer.d.ts +157 -0
  466. package/types/lib/inventory/analyzer.d.ts.map +1 -0
  467. package/types/lib/inventory/analyzerScope.d.ts +106 -0
  468. package/types/lib/inventory/analyzerScope.d.ts.map +1 -0
  469. package/types/lib/inventory/astWorker.d.ts +9 -0
  470. package/types/lib/inventory/astWorker.d.ts.map +1 -0
  471. package/types/lib/inventory/atomUtils.d.ts +159 -0
  472. package/types/lib/inventory/atomUtils.d.ts.map +1 -0
  473. package/types/lib/inventory/auditCategories.d.ts +80 -0
  474. package/types/lib/inventory/auditCategories.d.ts.map +1 -0
  475. package/types/lib/inventory/bomUtils.d.ts +145 -0
  476. package/types/lib/inventory/bomUtils.d.ts.map +1 -0
  477. package/types/lib/inventory/cacheCommands.d.ts +28 -0
  478. package/types/lib/inventory/cacheCommands.d.ts.map +1 -0
  479. package/types/lib/inventory/cacheDir.d.ts +55 -0
  480. package/types/lib/inventory/cacheDir.d.ts.map +1 -0
  481. package/types/lib/inventory/cbomutils.d.ts +37 -0
  482. package/types/lib/inventory/cbomutils.d.ts.map +1 -0
  483. package/types/lib/inventory/cdxrs.d.ts +90 -0
  484. package/types/lib/inventory/cdxrs.d.ts.map +1 -0
  485. package/types/lib/inventory/ciParsers/azurePipelines.d.ts +27 -0
  486. package/types/lib/inventory/ciParsers/azurePipelines.d.ts.map +1 -0
  487. package/types/lib/inventory/ciParsers/circleCi.d.ts +27 -0
  488. package/types/lib/inventory/ciParsers/circleCi.d.ts.map +1 -0
  489. package/types/lib/inventory/ciParsers/common.d.ts +11 -0
  490. package/types/lib/inventory/ciParsers/common.d.ts.map +1 -0
  491. package/types/lib/inventory/ciParsers/githubActions.d.ts +38 -0
  492. package/types/lib/inventory/ciParsers/githubActions.d.ts.map +1 -0
  493. package/types/lib/inventory/ciParsers/gitlabCi.d.ts +26 -0
  494. package/types/lib/inventory/ciParsers/gitlabCi.d.ts.map +1 -0
  495. package/types/lib/inventory/ciParsers/jenkins.d.ts +26 -0
  496. package/types/lib/inventory/ciParsers/jenkins.d.ts.map +1 -0
  497. package/types/lib/inventory/citations.d.ts +90 -0
  498. package/types/lib/inventory/citations.d.ts.map +1 -0
  499. package/types/lib/inventory/communityAiConfigParser.d.ts +14 -0
  500. package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -0
  501. package/types/lib/inventory/containerRisk.d.ts +20 -0
  502. package/types/lib/inventory/containerRisk.d.ts.map +1 -0
  503. package/types/lib/inventory/cryptoAlgorithmFamily.d.ts +37 -0
  504. package/types/lib/inventory/cryptoAlgorithmFamily.d.ts.map +1 -0
  505. package/types/lib/inventory/deps.d.ts +140 -0
  506. package/types/lib/inventory/deps.d.ts.map +1 -0
  507. package/types/lib/inventory/depsUtils.d.ts +74 -0
  508. package/types/lib/inventory/depsUtils.d.ts.map +1 -0
  509. package/types/lib/inventory/display.d.ts +227 -0
  510. package/types/lib/inventory/display.d.ts.map +1 -0
  511. package/types/lib/inventory/dosai.d.ts +130 -0
  512. package/types/lib/inventory/dosai.d.ts.map +1 -0
  513. package/types/lib/inventory/dosaiParsers.d.ts +59 -0
  514. package/types/lib/inventory/dosaiParsers.d.ts.map +1 -0
  515. package/types/lib/inventory/dynamic.d.ts +25 -0
  516. package/types/lib/inventory/dynamic.d.ts.map +1 -0
  517. package/types/lib/inventory/envcontext.d.ts +377 -0
  518. package/types/lib/inventory/envcontext.d.ts.map +1 -0
  519. package/types/lib/inventory/evidenceUtils.d.ts +74 -0
  520. package/types/lib/inventory/evidenceUtils.d.ts.map +1 -0
  521. package/types/lib/inventory/fetchBatch.d.ts +127 -0
  522. package/types/lib/inventory/fetchBatch.d.ts.map +1 -0
  523. package/types/lib/inventory/fetchRate.d.ts +118 -0
  524. package/types/lib/inventory/fetchRate.d.ts.map +1 -0
  525. package/types/lib/inventory/forgeEnricher.d.ts +31 -0
  526. package/types/lib/inventory/forgeEnricher.d.ts.map +1 -0
  527. package/types/lib/inventory/formulationParsers.d.ts +50 -0
  528. package/types/lib/inventory/formulationParsers.d.ts.map +1 -0
  529. package/types/lib/inventory/gtfobins.d.ts +27 -0
  530. package/types/lib/inventory/gtfobins.d.ts.map +1 -0
  531. package/types/lib/inventory/hbom.d.ts +58 -0
  532. package/types/lib/inventory/hbom.d.ts.map +1 -0
  533. package/types/lib/inventory/hbomAnalysis.d.ts +56 -0
  534. package/types/lib/inventory/hbomAnalysis.d.ts.map +1 -0
  535. package/types/lib/inventory/hbomLoader.d.ts +7 -0
  536. package/types/lib/inventory/hbomLoader.d.ts.map +1 -0
  537. package/types/lib/inventory/hostTopology.d.ts +47 -0
  538. package/types/lib/inventory/hostTopology.d.ts.map +1 -0
  539. package/types/lib/inventory/inventoryStats.d.ts +42 -0
  540. package/types/lib/inventory/inventoryStats.d.ts.map +1 -0
  541. package/types/lib/inventory/jsonLike.d.ts +23 -0
  542. package/types/lib/inventory/jsonLike.d.ts.map +1 -0
  543. package/types/lib/inventory/licenseEnhancer.d.ts +70 -0
  544. package/types/lib/inventory/licenseEnhancer.d.ts.map +1 -0
  545. package/types/lib/inventory/lolbas.d.ts +16 -0
  546. package/types/lib/inventory/lolbas.d.ts.map +1 -0
  547. package/types/lib/inventory/mcp.d.ts +29 -0
  548. package/types/lib/inventory/mcp.d.ts.map +1 -0
  549. package/types/lib/inventory/mcpConfigParser.d.ts +20 -0
  550. package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -0
  551. package/types/lib/inventory/mcpDiscovery.d.ts +33 -0
  552. package/types/lib/inventory/mcpDiscovery.d.ts.map +1 -0
  553. package/types/lib/inventory/mcpPinning.d.ts +11 -0
  554. package/types/lib/inventory/mcpPinning.d.ts.map +1 -0
  555. package/types/lib/inventory/osPackageResolver.d.ts +49 -0
  556. package/types/lib/inventory/osPackageResolver.d.ts.map +1 -0
  557. package/types/lib/inventory/osinfo.d.ts +201 -0
  558. package/types/lib/inventory/osinfo.d.ts.map +1 -0
  559. package/types/lib/inventory/osqueryTransform.d.ts +84 -0
  560. package/types/lib/inventory/osqueryTransform.d.ts.map +1 -0
  561. package/types/lib/inventory/plugins.d.ts +58 -0
  562. package/types/lib/inventory/plugins.d.ts.map +1 -0
  563. package/types/lib/inventory/protobom.d.ts +71 -0
  564. package/types/lib/inventory/protobom.d.ts.map +1 -0
  565. package/types/lib/inventory/protobomLoader.d.ts +17 -0
  566. package/types/lib/inventory/protobomLoader.d.ts.map +1 -0
  567. package/types/lib/inventory/provenanceUtils.d.ts +98 -0
  568. package/types/lib/inventory/provenanceUtils.d.ts.map +1 -0
  569. package/types/lib/inventory/purl.d.ts +313 -0
  570. package/types/lib/inventory/purl.d.ts.map +1 -0
  571. package/types/lib/inventory/rustFormulationParser.d.ts +17 -0
  572. package/types/lib/inventory/rustFormulationParser.d.ts.map +1 -0
  573. package/types/lib/inventory/sbomDocument.d.ts +59 -0
  574. package/types/lib/inventory/sbomDocument.d.ts.map +1 -0
  575. package/types/lib/inventory/source.d.ts +163 -0
  576. package/types/lib/inventory/source.d.ts.map +1 -0
  577. package/types/lib/inventory/spdx.d.ts +66 -0
  578. package/types/lib/inventory/spdx.d.ts.map +1 -0
  579. package/types/lib/inventory/spdxExpression.d.ts +58 -0
  580. package/types/lib/inventory/spdxExpression.d.ts.map +1 -0
  581. package/types/lib/inventory/spdxUtils.d.ts +12 -0
  582. package/types/lib/inventory/spdxUtils.d.ts.map +1 -0
  583. package/types/lib/inventory/table.d.ts +22 -0
  584. package/types/lib/inventory/table.d.ts.map +1 -0
  585. package/types/lib/inventory/traceRunner.d.ts +80 -0
  586. package/types/lib/inventory/traceRunner.d.ts.map +1 -0
  587. package/types/lib/inventory/unicodeScan.d.ts +46 -0
  588. package/types/lib/inventory/unicodeScan.d.ts.map +1 -0
  589. package/types/lib/managers/binary.d.ts +147 -0
  590. package/types/lib/managers/binary.d.ts.map +1 -0
  591. package/types/lib/managers/containerutils.d.ts +30 -0
  592. package/types/lib/managers/containerutils.d.ts.map +1 -0
  593. package/types/lib/managers/docker.d.ts +157 -0
  594. package/types/lib/managers/docker.d.ts.map +1 -0
  595. package/types/lib/managers/dockerConnection.d.ts +42 -0
  596. package/types/lib/managers/dockerConnection.d.ts.map +1 -0
  597. package/types/lib/managers/oci.d.ts +21 -0
  598. package/types/lib/managers/oci.d.ts.map +1 -0
  599. package/types/lib/managers/piptree.d.ts +13 -0
  600. package/types/lib/managers/piptree.d.ts.map +1 -0
  601. package/types/lib/parsers/cmakeCache.d.ts +70 -0
  602. package/types/lib/parsers/cmakeCache.d.ts.map +1 -0
  603. package/types/lib/parsers/gguf.d.ts +39 -0
  604. package/types/lib/parsers/gguf.d.ts.map +1 -0
  605. package/types/lib/parsers/gitAiNotes.d.ts +15 -0
  606. package/types/lib/parsers/gitAiNotes.d.ts.map +1 -0
  607. package/types/lib/parsers/gitmodules.d.ts +88 -0
  608. package/types/lib/parsers/gitmodules.d.ts.map +1 -0
  609. package/types/lib/parsers/htmlExtract.d.ts +34 -0
  610. package/types/lib/parsers/htmlExtract.d.ts.map +1 -0
  611. package/types/lib/parsers/huggingfaceManifest.d.ts +153 -0
  612. package/types/lib/parsers/huggingfaceManifest.d.ts.map +1 -0
  613. package/types/lib/parsers/huggingfaceUtils.d.ts +155 -0
  614. package/types/lib/parsers/huggingfaceUtils.d.ts.map +1 -0
  615. package/types/lib/parsers/iri.d.ts +68 -0
  616. package/types/lib/parsers/iri.d.ts.map +1 -0
  617. package/types/lib/parsers/npmrc.d.ts +33 -0
  618. package/types/lib/parsers/npmrc.d.ts.map +1 -0
  619. package/types/lib/parsers/ollama.d.ts +22 -0
  620. package/types/lib/parsers/ollama.d.ts.map +1 -0
  621. package/types/lib/parsers/xml.d.ts +47 -0
  622. package/types/lib/parsers/xml.d.ts.map +1 -0
  623. package/types/lib/server/server.d.ts +51 -0
  624. package/types/lib/server/server.d.ts.map +1 -0
  625. package/types/lib/stages/postgen/annotator.d.ts +36 -0
  626. package/types/lib/stages/postgen/annotator.d.ts.map +1 -0
  627. package/types/lib/stages/postgen/auditBom.d.ts +92 -0
  628. package/types/lib/stages/postgen/auditBom.d.ts.map +1 -0
  629. package/types/lib/stages/postgen/postgen.d.ts +59 -0
  630. package/types/lib/stages/postgen/postgen.d.ts.map +1 -0
  631. package/types/lib/stages/postgen/ruleEngine.d.ts +18 -0
  632. package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -0
  633. package/types/lib/stages/postgen/sortBom.d.ts +34 -0
  634. package/types/lib/stages/postgen/sortBom.d.ts.map +1 -0
  635. package/types/lib/stages/postgen/spdxConverter.d.ts +11 -0
  636. package/types/lib/stages/postgen/spdxConverter.d.ts.map +1 -0
  637. package/types/lib/stages/postgen/specVersionCompat.d.ts +71 -0
  638. package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -0
  639. package/types/lib/stages/pregen/envAudit.d.ts +14 -0
  640. package/types/lib/stages/pregen/envAudit.d.ts.map +1 -0
  641. package/types/lib/stages/pregen/pregen.d.ts +59 -0
  642. package/types/lib/stages/pregen/pregen.d.ts.map +1 -0
  643. package/types/lib/third-party/arborist/lib/arborist/index.d.ts +47 -0
  644. package/types/lib/third-party/arborist/lib/arborist/index.d.ts.map +1 -0
  645. package/types/lib/third-party/arborist/lib/arborist/load-actual.d.ts +4 -0
  646. package/types/lib/third-party/arborist/lib/arborist/load-actual.d.ts.map +1 -0
  647. package/types/lib/third-party/arborist/lib/arborist/load-virtual.d.ts +4 -0
  648. package/types/lib/third-party/arborist/lib/arborist/load-virtual.d.ts.map +1 -0
  649. package/types/lib/third-party/arborist/lib/bin-links.d.ts +18 -0
  650. package/types/lib/third-party/arborist/lib/bin-links.d.ts.map +1 -0
  651. package/types/lib/third-party/arborist/lib/calc-dep-flags.d.ts +3 -0
  652. package/types/lib/third-party/arborist/lib/calc-dep-flags.d.ts.map +1 -0
  653. package/types/lib/third-party/arborist/lib/case-insensitive-map.d.ts +9 -0
  654. package/types/lib/third-party/arborist/lib/case-insensitive-map.d.ts.map +1 -0
  655. package/types/lib/third-party/arborist/lib/consistent-resolve.d.ts +3 -0
  656. package/types/lib/third-party/arborist/lib/consistent-resolve.d.ts.map +1 -0
  657. package/types/lib/third-party/arborist/lib/debug.d.ts +3 -0
  658. package/types/lib/third-party/arborist/lib/debug.d.ts.map +1 -0
  659. package/types/lib/third-party/arborist/lib/dep-valid.d.ts +3 -0
  660. package/types/lib/third-party/arborist/lib/dep-valid.d.ts.map +1 -0
  661. package/types/lib/third-party/arborist/lib/edge.d.ts +46 -0
  662. package/types/lib/third-party/arborist/lib/edge.d.ts.map +1 -0
  663. package/types/lib/third-party/arborist/lib/from-path.d.ts +3 -0
  664. package/types/lib/third-party/arborist/lib/from-path.d.ts.map +1 -0
  665. package/types/lib/third-party/arborist/lib/gather-dep-set.d.ts +3 -0
  666. package/types/lib/third-party/arborist/lib/gather-dep-set.d.ts.map +1 -0
  667. package/types/lib/third-party/arborist/lib/index.d.ts +3 -0
  668. package/types/lib/third-party/arborist/lib/index.d.ts.map +1 -0
  669. package/types/lib/third-party/arborist/lib/inventory.d.ts +14 -0
  670. package/types/lib/third-party/arborist/lib/inventory.d.ts.map +1 -0
  671. package/types/lib/third-party/arborist/lib/link.d.ts +18 -0
  672. package/types/lib/third-party/arborist/lib/link.d.ts.map +1 -0
  673. package/types/lib/third-party/arborist/lib/node.d.ts +112 -0
  674. package/types/lib/third-party/arborist/lib/node.d.ts.map +1 -0
  675. package/types/lib/third-party/arborist/lib/npm-extension.d.ts +18 -0
  676. package/types/lib/third-party/arborist/lib/npm-extension.d.ts.map +1 -0
  677. package/types/lib/third-party/arborist/lib/override-resolves.d.ts +3 -0
  678. package/types/lib/third-party/arborist/lib/override-resolves.d.ts.map +1 -0
  679. package/types/lib/third-party/arborist/lib/override-set.d.ts +27 -0
  680. package/types/lib/third-party/arborist/lib/override-set.d.ts.map +1 -0
  681. package/types/lib/third-party/arborist/lib/package-extensions.d.ts +36 -0
  682. package/types/lib/third-party/arborist/lib/package-extensions.d.ts.map +1 -0
  683. package/types/lib/third-party/arborist/lib/printable.d.ts +3 -0
  684. package/types/lib/third-party/arborist/lib/printable.d.ts.map +1 -0
  685. package/types/lib/third-party/arborist/lib/proc-log.d.ts +20 -0
  686. package/types/lib/third-party/arborist/lib/proc-log.d.ts.map +1 -0
  687. package/types/lib/third-party/arborist/lib/realpath.d.ts +3 -0
  688. package/types/lib/third-party/arborist/lib/realpath.d.ts.map +1 -0
  689. package/types/lib/third-party/arborist/lib/relpath.d.ts +3 -0
  690. package/types/lib/third-party/arborist/lib/relpath.d.ts.map +1 -0
  691. package/types/lib/third-party/arborist/lib/shrinkwrap.d.ts +54 -0
  692. package/types/lib/third-party/arborist/lib/shrinkwrap.d.ts.map +1 -0
  693. package/types/lib/third-party/arborist/lib/spec-from-lock.d.ts +3 -0
  694. package/types/lib/third-party/arborist/lib/spec-from-lock.d.ts.map +1 -0
  695. package/types/lib/third-party/arborist/lib/tree-check.d.ts +3 -0
  696. package/types/lib/third-party/arborist/lib/tree-check.d.ts.map +1 -0
  697. package/types/lib/third-party/arborist/lib/validate-npm-package-name.d.ts +13 -0
  698. package/types/lib/third-party/arborist/lib/validate-npm-package-name.d.ts.map +1 -0
  699. package/types/lib/third-party/arborist/lib/version-from-tgz.d.ts +6 -0
  700. package/types/lib/third-party/arborist/lib/version-from-tgz.d.ts.map +1 -0
  701. package/types/lib/third-party/arborist/lib/yarn-lock.d.ts +35 -0
  702. package/types/lib/third-party/arborist/lib/yarn-lock.d.ts.map +1 -0
  703. package/types/lib/validator/bomValidator.d.ts +40 -0
  704. package/types/lib/validator/bomValidator.d.ts.map +1 -0
  705. package/types/lib/validator/complianceEngine.d.ts +72 -0
  706. package/types/lib/validator/complianceEngine.d.ts.map +1 -0
  707. package/types/lib/validator/complianceRules.d.ts +61 -0
  708. package/types/lib/validator/complianceRules.d.ts.map +1 -0
  709. package/types/lib/validator/index.d.ts +101 -0
  710. package/types/lib/validator/index.d.ts.map +1 -0
  711. package/types/lib/validator/reporters/annotations.d.ts +37 -0
  712. package/types/lib/validator/reporters/annotations.d.ts.map +1 -0
  713. package/types/lib/validator/reporters/console.d.ts +34 -0
  714. package/types/lib/validator/reporters/console.d.ts.map +1 -0
  715. package/types/lib/validator/reporters/index.d.ts +30 -0
  716. package/types/lib/validator/reporters/index.d.ts.map +1 -0
  717. package/types/lib/validator/reporters/json.d.ts +11 -0
  718. package/types/lib/validator/reporters/json.d.ts.map +1 -0
  719. package/types/lib/validator/reporters/sarif.d.ts +22 -0
  720. package/types/lib/validator/reporters/sarif.d.ts.map +1 -0
  721. package/mod.d.ts +0 -7
  722. package/mod.js +0 -22
@@ -0,0 +1,2125 @@
1
+ import { Buffer } from "node:buffer";
2
+ import { readFileSync, statSync } from "node:fs";
3
+ import { homedir } from "node:os";
4
+ import { basename, dirname, join, relative, resolve } from "node:path";
5
+ import process from "node:process";
6
+
7
+ import { build } from "@cdxgen/cdx-purl";
8
+ import { parse as loadYaml } from "yaml";
9
+
10
+ import { DEBUG_MODE, readEnvironmentVariable } from "../core/activity.js";
11
+ import {
12
+ CARGO_CMD,
13
+ CLJ_CMD,
14
+ hasAnyProjectType,
15
+ LEIN_CMD,
16
+ SWIFT_CMD,
17
+ shouldFetchLicense,
18
+ } from "../core/env.js";
19
+ import {
20
+ checksumFile,
21
+ getAllFiles,
22
+ safeExistsSync,
23
+ safeSpawnSync,
24
+ } from "../core/fs.js";
25
+ import { thoughtLog } from "../core/logger.js";
26
+ import { dirNameStr, isMac } from "../core/paths.js";
27
+ import {
28
+ buildDependentPurl,
29
+ collapseCmakeVersions,
30
+ resolveCmakeContext,
31
+ } from "../ecosystems/cmakeResolver.js";
32
+ import { getCppModules } from "../ecosystems/cppEvidence.js";
33
+ import {
34
+ getCratesMetadata,
35
+ getSwiftPackageMetadata,
36
+ } from "../ecosystems/ecosystems.js";
37
+ import { parseGleamProject } from "../ecosystems/parsers-gleam.js";
38
+ import {
39
+ parseGoListDep,
40
+ parseGoModData,
41
+ parseGoModGraph,
42
+ parseGoModulesTxt,
43
+ parseGoModWhy,
44
+ parseGopkgData,
45
+ parseGosumData,
46
+ } from "../ecosystems/parsers-go.js";
47
+ import {
48
+ parseCljDep,
49
+ parseEdnData,
50
+ parseLeinDep,
51
+ parseLeiningenData,
52
+ } from "../ecosystems/parsers-jvm.js";
53
+ import {
54
+ buildObjectForCocoaPod,
55
+ executeAlpmList,
56
+ executeApkList,
57
+ executeDpkgList,
58
+ executeEqueryList,
59
+ executePodCommand,
60
+ executeRpmList,
61
+ parseCabalData,
62
+ parseCmakeLikeFile,
63
+ parseCocoaDependency,
64
+ parseColliderLockData,
65
+ parseConanData,
66
+ parseConanLockData,
67
+ parseFlakeLock,
68
+ parseFlakeNix,
69
+ parseMakeDFile,
70
+ parseMixLockData,
71
+ parsePodfileLock,
72
+ parsePodfileTargets,
73
+ parsePubLockData,
74
+ parsePubYamlData,
75
+ parseSwiftJsonTree,
76
+ parseSwiftResolved,
77
+ prefetchCocoaPodspecs,
78
+ } from "../ecosystems/parsers-misc.js";
79
+ import {
80
+ parseCargoData,
81
+ parseCargoDependencyData,
82
+ parseCargoManifestDependencyData,
83
+ parseCargoTomlData,
84
+ } from "../ecosystems/parsers-rust.js";
85
+ import { resolveZigGraph } from "../ecosystems/zigResolver.js";
86
+ import { mergeDependencies, trimComponents } from "../inventory/depsUtils.js";
87
+ import { convertOSQueryResults } from "../inventory/evidenceUtils.js";
88
+ import { applyPurl, nixBomRef, tryBuildPurl } from "../inventory/purl.js";
89
+ import { executeOsQuery } from "../managers/binary.js";
90
+ import {
91
+ buildBomNSData,
92
+ createBinaryBom,
93
+ createDefaultParentComponent,
94
+ } from "./bomAssembly.js";
95
+
96
+ const isWin = process.platform === "win32";
97
+
98
+ const cosDbQueries = JSON.parse(
99
+ readFileSync(join(dirNameStr, "data", "cosdb-queries.json"), "utf-8"),
100
+ );
101
+
102
+ /**
103
+ * Strip an unresolved CMake/MSBuild variable from a component's version and purl.
104
+ *
105
+ * A variable defined in a parent `CMakeLists.txt` (`project(foo VERSION
106
+ * ${PARENT_VERSION})`) cannot be resolved from the file that references it, and
107
+ * percent-encoding one into a purl publishes the variable name as the version
108
+ * (`pkg:generic/foo@%24%7B...%7D`). The scrapers drop such versions at the
109
+ * point they are read; this is the final check over everything reaching the
110
+ * BOM, covering components contributed by `cppEvidence` and the CMake cache
111
+ * resolver as well.
112
+ *
113
+ * @param {object} component Component to sanitise in place
114
+ */
115
+ function sanitizeUnresolvedPurl(component) {
116
+ if (!component) {
117
+ return;
118
+ }
119
+ const hasUnresolvedVar =
120
+ component.version?.includes("${") ||
121
+ (component.purl &&
122
+ (component.purl.includes("%24%7B") || component.purl.includes("${")));
123
+ if (!hasUnresolvedVar) {
124
+ return;
125
+ }
126
+ if (component.version?.includes("${")) {
127
+ component.version = "";
128
+ }
129
+ applyPurl(
130
+ component,
131
+ tryBuildPurl({
132
+ type: "generic",
133
+ namespace: component.group || null,
134
+ name: component.name,
135
+ version: null,
136
+ }),
137
+ );
138
+ }
139
+
140
+ /**
141
+ * Resolves the local Cargo registry cache directory from the `CARGO_CACHE_DIR`
142
+ * or `CARGO_HOME` environment variables, falling back to `~/.cargo/registry/cache`.
143
+ *
144
+ * @returns {string|undefined} Absolute path to the Cargo cache directory
145
+ */
146
+ export function getCargoCacheDir() {
147
+ return readEnvironmentVariable("CARGO_CACHE_DIR")
148
+ ? resolve(readEnvironmentVariable("CARGO_CACHE_DIR"))
149
+ : resolve(
150
+ readEnvironmentVariable("CARGO_HOME") || join(homedir(), ".cargo"),
151
+ "registry",
152
+ "cache",
153
+ );
154
+ }
155
+
156
+ /**
157
+ * Function to create bom string for Go projects
158
+ *
159
+ * @param {string} path to the project
160
+ * @param {Object} options Parse options from the cli
161
+ * @returns {Promise<Object | undefined>} Promise resolving to a BOM object or `undefined`
162
+ */
163
+ export async function createGoBom(path, options) {
164
+ let pkgList = [];
165
+ let dependencies = [];
166
+ const allImports = {};
167
+ let parentComponent = createDefaultParentComponent(path, "golang", options);
168
+ // Is this a binary file
169
+ let maybeBinary;
170
+ try {
171
+ maybeBinary = statSync(path).isFile();
172
+ } catch (_err) {
173
+ maybeBinary = false;
174
+ }
175
+ if (maybeBinary || options?.lifecycle?.includes("post-build")) {
176
+ return createBinaryBom(path, options);
177
+ }
178
+
179
+ // Read in go.sum and merge all go.sum files.
180
+ const gosumFiles = getAllFiles(
181
+ path,
182
+ `${options.multiProject ? "**/" : ""}go.sum`,
183
+ options,
184
+ );
185
+
186
+ // If USE_GOSUM is true|1, generate BOM components only using go.sum.
187
+ const useGosum =
188
+ readEnvironmentVariable("USE_GOSUM") &&
189
+ ["true", "1"].includes(readEnvironmentVariable("USE_GOSUM"));
190
+ if (useGosum && gosumFiles.length) {
191
+ console.warn(
192
+ "Using go.sum to generate BOMs for go projects may return an inaccurate representation of transitive dependencies.\nSee: https://github.com/golang/go/wiki/Modules#is-gosum-a-lock-file-why-does-gosum-include-information-for-module-versions-i-am-no-longer-using\n",
193
+ "Set USE_GOSUM=false to generate BOMs using go.mod as the dependency source of truth.",
194
+ );
195
+ for (const f of gosumFiles) {
196
+ if (DEBUG_MODE) {
197
+ console.log(`Parsing ${f}`);
198
+ }
199
+ const gosumData = readFileSync(f, { encoding: "utf-8" });
200
+ const dlist = await parseGosumData(gosumData);
201
+ if (dlist?.length) {
202
+ pkgList = pkgList.concat(dlist);
203
+ }
204
+ }
205
+ const doneList = {};
206
+ let circuitBreak = false;
207
+ if (DEBUG_MODE) {
208
+ console.log(
209
+ `Attempting to detect required packages using "go mod why" command for ${pkgList.length} packages`,
210
+ );
211
+ }
212
+ // Using go mod why detect required packages
213
+ for (const apkg of pkgList) {
214
+ if (circuitBreak) {
215
+ break;
216
+ }
217
+ const pkgFullName = `${apkg.name}`;
218
+ if (apkg.scope === "required") {
219
+ allImports[pkgFullName] = true;
220
+ continue;
221
+ }
222
+ if (
223
+ apkg.scope === "optional" ||
224
+ allImports[pkgFullName] ||
225
+ doneList[pkgFullName]
226
+ ) {
227
+ continue;
228
+ }
229
+ if (DEBUG_MODE) {
230
+ console.log(`go mod why -m -vendor ${pkgFullName}`);
231
+ }
232
+ const mresult = safeSpawnSync(
233
+ "go",
234
+ ["mod", "why", "-m", "-vendor", pkgFullName],
235
+ {
236
+ cwd: path,
237
+ },
238
+ );
239
+ if (mresult.status !== 0 || mresult.error) {
240
+ if (DEBUG_MODE) {
241
+ if (mresult.stdout) {
242
+ console.log(mresult.stdout);
243
+ }
244
+ if (mresult.stderr) {
245
+ console.log(mresult.stderr);
246
+ }
247
+ }
248
+ circuitBreak = true;
249
+ } else {
250
+ const mstdout = mresult.stdout;
251
+ if (mstdout) {
252
+ const cmdOutput = Buffer.from(mstdout).toString();
253
+ const whyPkg = parseGoModWhy(cmdOutput);
254
+ // whyPkg would include this package string
255
+ // github.com/golang/protobuf/proto github.com/golang/protobuf
256
+ // golang.org/x/tools/cmd/goimports golang.org/x/tools
257
+ if (whyPkg?.includes(pkgFullName)) {
258
+ allImports[pkgFullName] = true;
259
+ }
260
+ doneList[pkgFullName] = true;
261
+ }
262
+ }
263
+ }
264
+ if (DEBUG_MODE) {
265
+ console.log(`Required packages: ${Object.keys(allImports).length}`);
266
+ }
267
+ return buildBomNSData(options, pkgList, "golang", {
268
+ src: path,
269
+ dependencies,
270
+ parentComponent,
271
+ filename: gosumFiles.join(", "),
272
+ });
273
+ }
274
+
275
+ // If USE_GOSUM is false, generate BOM components using go.mod.
276
+ const gosumMap = {};
277
+ if (gosumFiles.length) {
278
+ for (const f of gosumFiles) {
279
+ if (DEBUG_MODE) {
280
+ console.log(`Parsing ${f}`);
281
+ }
282
+ const gosumData = readFileSync(f, { encoding: "utf-8" });
283
+ const dlist = await parseGosumData(gosumData);
284
+ if (dlist?.length) {
285
+ dlist.forEach((pkg) => {
286
+ gosumMap[`${pkg.name}@${pkg.version}`] = pkg._integrity;
287
+ });
288
+ }
289
+ }
290
+ }
291
+
292
+ // Read in data from Gopkg.lock files if they exist
293
+ const gopkgLockFiles = getAllFiles(
294
+ path,
295
+ `${options.multiProject ? "**/" : ""}Gopkg.lock`,
296
+ options,
297
+ );
298
+
299
+ // Read in go.mod files and parse BOM components with checksums from gosumData
300
+ const gomodFiles = getAllFiles(
301
+ path,
302
+ `${options.multiProject ? "**/" : ""}go.mod`,
303
+ options,
304
+ );
305
+ // Collect any vendored dependencies
306
+ const modulesTxtFiles = getAllFiles(path, "vendor/**/modules.txt", options);
307
+ for (const f of modulesTxtFiles) {
308
+ const dlist = await parseGoModulesTxt(f, gosumMap);
309
+ pkgList = pkgList.concat(dlist);
310
+ }
311
+ if (gomodFiles.length) {
312
+ let shouldManuallyParse = false;
313
+ // Sort go.mod files by depth (shallowest first) to prioritize root modules
314
+ const sortedGomodFiles = gomodFiles.sort((a, b) => {
315
+ const relativePathA = relative(path, a);
316
+ const relativePathB = relative(path, b);
317
+ const depthA = relativePathA.split("/").length;
318
+ const depthB = relativePathB.split("/").length;
319
+ return depthA - depthB;
320
+ });
321
+
322
+ let rootParentComponent = null;
323
+ // Use the go list -deps and go mod why commands to generate a good quality BOM for non-docker invocations
324
+ if (
325
+ !hasAnyProjectType(["docker", "oci", "container", "os"], options, false)
326
+ ) {
327
+ for (const f of sortedGomodFiles) {
328
+ const basePath = dirname(f);
329
+ // Ignore vendor packages and test fixtures
330
+ if (
331
+ basePath.includes("/vendor/") ||
332
+ basePath.includes("/build/") ||
333
+ basePath.includes("/test-fixtures/")
334
+ ) {
335
+ continue;
336
+ }
337
+ // First we execute the go list -deps command which gives the correct list of dependencies
338
+ if (DEBUG_MODE) {
339
+ console.log("Executing go list -deps in", basePath);
340
+ }
341
+ // TODO: Replacing this with -json gives us more interesting data points such as GoFiles, Imports, and Deps
342
+ let result = safeSpawnSync(
343
+ "go",
344
+ [
345
+ "list",
346
+ "-deps",
347
+ "-f",
348
+ "'{{with .Module}}{{.Path}}|{{.Version}}|{{.Indirect}}|{{.GoMod}}|{{.GoVersion}}|{{.Main}}|{{.Time}}|{{.Deprecated}}|{{.GoModSum}}|{{.Dir}}{{end}}'",
349
+ "./...",
350
+ ],
351
+ {
352
+ cwd: basePath,
353
+ },
354
+ );
355
+ if (result.status !== 0 || result.error) {
356
+ // go list -deps command may not work when private packages are involved
357
+ // So we support a fallback to only operate with go mod graph command output in such instances
358
+ console.log("go list -deps command has failed for", basePath);
359
+ shouldManuallyParse = true;
360
+ if (DEBUG_MODE && result.stdout) {
361
+ console.log(result.stdout);
362
+ }
363
+ if (DEBUG_MODE && result.stderr) {
364
+ console.log(result.stderr);
365
+ }
366
+ options.failOnError && process.exit(1);
367
+ }
368
+ const stdout = result.stdout;
369
+ if (stdout) {
370
+ let cmdOutput = Buffer.from(stdout).toString();
371
+ const retMap = await parseGoListDep(cmdOutput, gosumMap);
372
+ if (retMap.pkgList?.length) {
373
+ pkgList = pkgList.concat(retMap.pkgList);
374
+ }
375
+ // Prioritize the shallowest module as the root component
376
+ if (
377
+ retMap.parentComponent &&
378
+ Object.keys(retMap.parentComponent).length
379
+ ) {
380
+ if (!rootParentComponent) {
381
+ // First (shallowest) module becomes the root
382
+ rootParentComponent = retMap.parentComponent;
383
+ rootParentComponent.type = "application";
384
+ parentComponent = rootParentComponent;
385
+ } else {
386
+ // Subsequent modules become subcomponents
387
+ if (!parentComponent.components) {
388
+ parentComponent.components = [];
389
+ }
390
+ parentComponent.components.push(retMap.parentComponent);
391
+ }
392
+ }
393
+ if (DEBUG_MODE) {
394
+ console.log("Executing go mod graph in", basePath);
395
+ }
396
+ // Next we use the go mod graph command to construct the dependency tree
397
+ result = safeSpawnSync("go", ["mod", "graph"], {
398
+ cwd: basePath,
399
+ });
400
+ // Check if got a mod graph successfully
401
+ if (result.status !== 0 || result.error) {
402
+ console.log("go mod graph command has failed.");
403
+ if (DEBUG_MODE && result.stdout) {
404
+ console.log(result.stdout);
405
+ if (result?.stdout.includes("unrecognized import path")) {
406
+ console.log(
407
+ "go couldn't download all the modules, including any private modules. Dependency tree would be missing.",
408
+ );
409
+ }
410
+ }
411
+ if (DEBUG_MODE && result.stderr) {
412
+ console.log(result.stderr);
413
+ }
414
+ options.failOnError && process.exit(1);
415
+ }
416
+ if (result.stdout) {
417
+ cmdOutput = Buffer.from(result.stdout).toString();
418
+ const retMap = await parseGoModGraph(
419
+ cmdOutput,
420
+ f,
421
+ gosumMap,
422
+ pkgList,
423
+ parentComponent,
424
+ );
425
+ if (retMap.pkgList?.length) {
426
+ pkgList = pkgList.concat(retMap.pkgList);
427
+ pkgList = trimComponents(pkgList);
428
+ }
429
+ if (retMap.dependenciesList?.length) {
430
+ dependencies = mergeDependencies(
431
+ dependencies,
432
+ retMap.dependenciesList,
433
+ parentComponent,
434
+ );
435
+ }
436
+ // Retain the parent component hierarchy
437
+ if (Object.keys(retMap.parentComponent).length) {
438
+ parentComponent.components = parentComponent.components || [];
439
+ parentComponent.components.push(retMap.parentComponent);
440
+ }
441
+ }
442
+ } else {
443
+ if (DEBUG_MODE) {
444
+ console.log("Executing go mod graph in", basePath);
445
+ }
446
+ // Next we use the go mod graph command to construct the dependency tree
447
+ result = safeSpawnSync("go", ["mod", "graph"], {
448
+ cwd: basePath,
449
+ shell: isWin,
450
+ });
451
+ if (result.stdout) {
452
+ const cmdOutput = Buffer.from(result.stdout).toString();
453
+ // The arguments to parseGoModGraph are slightly different to force inclusion of all packages
454
+ const retMap = await parseGoModGraph(
455
+ cmdOutput,
456
+ f,
457
+ gosumMap,
458
+ [],
459
+ {},
460
+ );
461
+ if (retMap.pkgList?.length) {
462
+ pkgList = pkgList.concat(retMap.pkgList);
463
+ pkgList = trimComponents(pkgList);
464
+ }
465
+ if (retMap.dependenciesList?.length) {
466
+ dependencies = mergeDependencies(
467
+ dependencies,
468
+ retMap.dependenciesList,
469
+ parentComponent,
470
+ );
471
+ }
472
+ // Retain the parent component hierarchy, prioritizing the shallowest module
473
+ if (Object.keys(retMap.parentComponent).length) {
474
+ if (!rootParentComponent) {
475
+ // First (shallowest) module becomes the root
476
+ rootParentComponent = retMap.parentComponent;
477
+ parentComponent = rootParentComponent;
478
+ } else {
479
+ // Subsequent modules become subcomponents
480
+ parentComponent.components = parentComponent.components || [];
481
+ parentComponent.components.push(retMap.parentComponent);
482
+ }
483
+ }
484
+ } else {
485
+ shouldManuallyParse = true;
486
+ console.log(
487
+ "1. Check if the correct version of golang is installed. Try building the application using go build or make command to troubleshoot.",
488
+ );
489
+ console.log(
490
+ "2. If the application uses private go modules, ensure the environment variable GOPRIVATE is set with the comma-separated repo names.\nEnsure $HOME/.netrc file contains a valid username and password for the private repos.",
491
+ );
492
+ console.log(
493
+ "3. Alternatively, consider generating a post-build SBOM from the built binary using blint. Use the official container image and invoke cdxgen with the arguments `-t binary --lifecycle post-build`.",
494
+ );
495
+ options.failOnError && process.exit(1);
496
+ }
497
+ }
498
+ }
499
+ if (pkgList.length && !shouldManuallyParse) {
500
+ return buildBomNSData(options, pkgList, "golang", {
501
+ allImports,
502
+ dependencies,
503
+ parentComponent,
504
+ src: path,
505
+ filename: sortedGomodFiles.join(", "),
506
+ });
507
+ }
508
+ }
509
+ // Parse the gomod files manually. The resultant BOM would be incomplete
510
+ if (
511
+ !hasAnyProjectType(["docker", "oci", "container", "os"], options, false)
512
+ ) {
513
+ console.log(
514
+ "Manually parsing go.mod files. The resultant BOM would be incomplete.",
515
+ );
516
+ }
517
+ for (const f of sortedGomodFiles) {
518
+ if (DEBUG_MODE) {
519
+ console.log(`Parsing ${f}`);
520
+ }
521
+ const gomodData = readFileSync(f, { encoding: "utf-8" });
522
+ const retMap = await parseGoModData(gomodData, gosumMap);
523
+ if (retMap?.pkgList?.length) {
524
+ pkgList = pkgList.concat(retMap.pkgList);
525
+ }
526
+ // Retain the parent component hierarchy, prioritizing the shallowest module
527
+ if (
528
+ retMap?.parentComponent &&
529
+ Object.keys(retMap.parentComponent).length
530
+ ) {
531
+ if (!rootParentComponent) {
532
+ // First (shallowest) module becomes the root
533
+ rootParentComponent = retMap.parentComponent;
534
+ parentComponent = rootParentComponent;
535
+ } else {
536
+ // Subsequent modules become subcomponents
537
+ parentComponent.components = parentComponent.components || [];
538
+ parentComponent.components.push(retMap.parentComponent);
539
+ }
540
+ if (retMap?.rootList?.length) {
541
+ const thisParentDependsOn = [
542
+ {
543
+ ref: retMap.parentComponent["bom-ref"],
544
+ dependsOn: [
545
+ ...new Set(retMap.rootList.map((c) => c["bom-ref"])),
546
+ ].sort(),
547
+ },
548
+ ];
549
+ dependencies = mergeDependencies(
550
+ dependencies,
551
+ thisParentDependsOn,
552
+ parentComponent,
553
+ );
554
+ }
555
+ }
556
+ }
557
+ return buildBomNSData(options, pkgList, "golang", {
558
+ src: path,
559
+ dependencies,
560
+ parentComponent,
561
+ filename: sortedGomodFiles.join(", "),
562
+ });
563
+ }
564
+ if (gopkgLockFiles.length) {
565
+ for (const f of gopkgLockFiles) {
566
+ if (DEBUG_MODE) {
567
+ console.log(`Parsing ${f}`);
568
+ }
569
+ const gopkgData = readFileSync(f, {
570
+ encoding: "utf-8",
571
+ });
572
+ const dlist = await parseGopkgData(gopkgData);
573
+ if (dlist?.length) {
574
+ pkgList = pkgList.concat(dlist);
575
+ }
576
+ }
577
+ return buildBomNSData(options, pkgList, "golang", {
578
+ src: path,
579
+ dependencies,
580
+ parentComponent,
581
+ filename: gopkgLockFiles.join(", "),
582
+ });
583
+ }
584
+ return {};
585
+ }
586
+
587
+ /**
588
+ * Function to create bom string for Rust projects
589
+ *
590
+ * @param {string} path to the project
591
+ * @param {Object} options Parse options from the cli
592
+ * @returns {Promise<Object|undefined>} Promise resolving to a BOM object or undefined
593
+ */
594
+ export async function createRustBom(path, options) {
595
+ let pkgList = [];
596
+ let parentComponent = {};
597
+ // Is this a binary file
598
+ let maybeBinary;
599
+ try {
600
+ maybeBinary = statSync(path).isFile();
601
+ } catch (_err) {
602
+ maybeBinary = false;
603
+ }
604
+ if (maybeBinary || options?.lifecycle?.includes("post-build")) {
605
+ return createBinaryBom(path, options);
606
+ }
607
+
608
+ // This function assumes that the given path is prioritized, i.e that the
609
+ // Cargo.toml-file directly inside the directory `path` (or the one in the
610
+ // shortest distance from the `path` directory) will be the first returned
611
+ // object. If that assumption is broken, the parent component may be
612
+ // inaccurate.
613
+ const cargoFiles = getAllFiles(
614
+ path,
615
+ `${options.multiProject ? "**/" : ""}Cargo.toml`,
616
+ options,
617
+ );
618
+ // Attempt to build or generate lock files automatically
619
+ for (const f of cargoFiles) {
620
+ // If there are no cargo.lock files, we can attempt a cargo install when
621
+ // options.deep is true or options.lifecycle == build or post-build with installDeps
622
+ // Why the need for installDeps? It currently defaults to true, so let's obey if someone wants no installs
623
+ if (
624
+ (options.deep && !hasAnyProjectType(["oci"], options, false)) ||
625
+ (options.installDeps &&
626
+ !safeExistsSync(f.replace(".toml", ".lock")) &&
627
+ ["build", "post-build"].includes(options.lifecycle))
628
+ ) {
629
+ const basePath = dirname(f);
630
+ const cargoArgs = options.deep
631
+ ? ["check", "--all-features", "--manifest-path", f]
632
+ : ["generate-lockfile", "--manifest-path", f];
633
+ if (!DEBUG_MODE) {
634
+ cargoArgs.push("--quiet");
635
+ }
636
+ if (DEBUG_MODE) {
637
+ console.log(
638
+ "Executing ",
639
+ CARGO_CMD,
640
+ cargoArgs.join(" "),
641
+ "in",
642
+ basePath,
643
+ );
644
+ }
645
+ const cargoInstallResult = safeSpawnSync(CARGO_CMD, cargoArgs, {
646
+ cwd: basePath,
647
+ shell: isWin,
648
+ });
649
+ if (cargoInstallResult.status !== 0 || cargoInstallResult.error) {
650
+ console.error("Error running the cargo command");
651
+ console.log(cargoInstallResult.error, cargoInstallResult.stderr);
652
+ options.failOnError && process.exit(1);
653
+ }
654
+ }
655
+ }
656
+ // After running cargo check, .d files would get created
657
+ let pkgFilesMap = {};
658
+ if (options.deep || ["build", "post-build"].includes(options.lifecycle)) {
659
+ const makeDFiles = getAllFiles(path, "target/**/*.d", options);
660
+ for (const dfile of makeDFiles) {
661
+ pkgFilesMap = { ...pkgFilesMap, ...parseMakeDFile(dfile) };
662
+ }
663
+ }
664
+ const cargoLockFiles = getAllFiles(
665
+ path,
666
+ `${options.multiProject ? "**/" : ""}Cargo.lock`,
667
+ options,
668
+ );
669
+ const cargoLockMode = cargoLockFiles.length;
670
+ for (const f of cargoFiles) {
671
+ if (DEBUG_MODE) {
672
+ console.log(`Parsing ${f}`);
673
+ }
674
+ const dlist = await parseCargoTomlData(f, cargoLockMode, pkgFilesMap, {
675
+ includeWorkspaceMembers: !options.multiProject,
676
+ });
677
+ if (dlist?.length) {
678
+ if (!cargoLockMode) {
679
+ pkgList = pkgList.concat(dlist);
680
+ } else {
681
+ if (!Object.keys(parentComponent).length) {
682
+ parentComponent = dlist[0];
683
+ parentComponent.type = "application";
684
+ parentComponent.components = [];
685
+ if (DEBUG_MODE) {
686
+ console.log(
687
+ `Assigning parent component "${parentComponent.name}" from ${f}`,
688
+ );
689
+ }
690
+ } else {
691
+ parentComponent.components.push(dlist[0]);
692
+ }
693
+ }
694
+ }
695
+ }
696
+ let dependencyTree = [];
697
+ if (cargoLockMode) {
698
+ for (const f of cargoLockFiles) {
699
+ if (DEBUG_MODE) {
700
+ console.log(`Parsing ${f}`);
701
+ }
702
+ const dlist = await parseCargoData(f, false, pkgFilesMap);
703
+ if (dlist?.length) {
704
+ pkgList = pkgList.concat(dlist);
705
+ }
706
+
707
+ if (DEBUG_MODE) {
708
+ console.log(`Constructing dependency tree from ${f}`);
709
+ }
710
+ const cargoLockData = readFileSync(f, { encoding: "utf-8" });
711
+ const fileDependencylist = parseCargoDependencyData(cargoLockData);
712
+ if (fileDependencylist?.length) {
713
+ dependencyTree = mergeDependencies(
714
+ dependencyTree,
715
+ fileDependencylist,
716
+ parentComponent,
717
+ );
718
+ }
719
+ }
720
+ }
721
+ for (const f of cargoFiles) {
722
+ const manifestDependencyList = parseCargoManifestDependencyData(f, {
723
+ includeWorkspaceMembers: !options.multiProject,
724
+ });
725
+ if (manifestDependencyList?.length) {
726
+ dependencyTree = mergeDependencies(
727
+ dependencyTree,
728
+ manifestDependencyList,
729
+ parentComponent,
730
+ );
731
+ }
732
+ }
733
+ return buildBomNSData(options, pkgList, "cargo", {
734
+ src: path,
735
+ filename: cargoLockFiles.join(", "),
736
+ dependencies: dependencyTree,
737
+ parentComponent,
738
+ });
739
+ }
740
+
741
+ /**
742
+ * Parses a `.crate` file name into a CycloneDX component (name, version, purl,
743
+ * bom-ref, and source/cache properties). Returns undefined when the file name
744
+ * does not match the `name-version` convention.
745
+ *
746
+ * @param {string} crateFile Absolute path to a `.crate` archive
747
+ * @returns {object|undefined} Component object or undefined
748
+ */
749
+ export function buildCargoCacheComponent(crateFile) {
750
+ const crateFileName = basename(crateFile, ".crate");
751
+ const nameVersionMatch = crateFileName.match(/^(.+)-([0-9][A-Za-z0-9.+-]*)$/);
752
+ if (!nameVersionMatch) {
753
+ return undefined;
754
+ }
755
+ const [, name, version] = nameVersionMatch;
756
+ const purl = build({
757
+ type: "cargo",
758
+ namespace: "" || null,
759
+ name: name,
760
+ version: version || null,
761
+ });
762
+ return {
763
+ "bom-ref": decodeURIComponent(purl),
764
+ group: "",
765
+ name,
766
+ properties: [
767
+ {
768
+ name: "internal:SrcFile",
769
+ value: crateFile,
770
+ },
771
+ {
772
+ name: "cdx:cargo:cacheSource",
773
+ value: "registry-cache",
774
+ },
775
+ ],
776
+ purl,
777
+ type: "library",
778
+ version,
779
+ };
780
+ }
781
+
782
+ /**
783
+ * Enriches a cargo cache component with a SHA-256 hash and filename-based
784
+ * identity evidence (confidence 0.5). Hash computation failures are ignored.
785
+ *
786
+ * @param {string} crateFile Absolute path to the `.crate` archive
787
+ * @param {object} [component] Component produced by `buildCargoCacheComponent`
788
+ * @returns {Promise<object|undefined>} The enriched component or undefined
789
+ */
790
+ export async function enrichCargoCacheComponent(crateFile, component) {
791
+ if (!component) {
792
+ return undefined;
793
+ }
794
+ try {
795
+ component.hashes = [
796
+ {
797
+ alg: "SHA-256",
798
+ content: await checksumFile("sha256", crateFile),
799
+ },
800
+ ];
801
+ } catch {
802
+ // continue without hashes
803
+ }
804
+ component.evidence = {
805
+ identity: {
806
+ field: "purl",
807
+ confidence: 0.5,
808
+ methods: [
809
+ {
810
+ technique: "filename",
811
+ confidence: 0.5,
812
+ value: crateFile,
813
+ },
814
+ ],
815
+ },
816
+ };
817
+ return component;
818
+ }
819
+
820
+ /**
821
+ * Builds a BOM from `.crate` files found in the Cargo registry cache (or from a
822
+ * single `.crate` path). Optionally fetches crates.io license metadata when
823
+ * license fetching is enabled.
824
+ *
825
+ * @param {string} path Directory or `.crate` file path
826
+ * @param {object} options CLI options
827
+ * @returns {Promise<object>} Promise resolving to a BOM namespace data object
828
+ */
829
+ export async function createCargoCacheBom(path, options) {
830
+ const parentComponent = createDefaultParentComponent(path, "cargo", options);
831
+ const crateFiles = path.endsWith(".crate")
832
+ ? [resolve(path)]
833
+ : getAllFiles(path, "**/*.crate", options);
834
+ let pkgList = [];
835
+ for (const crateFile of crateFiles) {
836
+ const component = await enrichCargoCacheComponent(
837
+ crateFile,
838
+ buildCargoCacheComponent(crateFile),
839
+ );
840
+ if (component) {
841
+ pkgList.push(component);
842
+ }
843
+ }
844
+ if (pkgList.length && shouldFetchLicense()) {
845
+ pkgList = await getCratesMetadata(pkgList);
846
+ }
847
+ return buildBomNSData(options, pkgList, "cargo", {
848
+ src: path,
849
+ parentComponent,
850
+ });
851
+ }
852
+
853
+ /**
854
+ * Function to create bom string for Dart projects
855
+ *
856
+ * @param {string} path to the project
857
+ * @param {Object} options Parse options from the cli
858
+ * @returns {Promise<Object>} Promise resolving to BOM object
859
+ */
860
+ export async function createDartBom(path, options) {
861
+ const pubFiles = getAllFiles(
862
+ path,
863
+ `${options.multiProject ? "**/" : ""}pubspec.lock`,
864
+ options,
865
+ );
866
+ const pubSpecYamlFiles = getAllFiles(
867
+ path,
868
+ `${options.multiProject ? "**/" : ""}pubspec.yaml`,
869
+ options,
870
+ );
871
+ let dependencies = [];
872
+ let pkgList = [];
873
+ let parentComponent;
874
+ if (pubSpecYamlFiles.length) {
875
+ for (const f of pubSpecYamlFiles) {
876
+ if (DEBUG_MODE) {
877
+ console.log(`Parsing ${f}`);
878
+ }
879
+ const pubYamlData = readFileSync(f, { encoding: "utf-8" });
880
+ const dlist = parsePubYamlData(pubYamlData);
881
+ if (dlist?.length) {
882
+ pkgList = pkgList.concat(dlist);
883
+ if (!parentComponent) {
884
+ parentComponent = pkgList[0];
885
+ parentComponent.type = "application";
886
+ }
887
+ }
888
+ }
889
+ }
890
+ if (pubFiles.length) {
891
+ for (const f of pubFiles) {
892
+ if (DEBUG_MODE) {
893
+ console.log(`Parsing ${f}`);
894
+ }
895
+ const pubLockData = readFileSync(f, { encoding: "utf-8" });
896
+ const retMap = await parsePubLockData(pubLockData, f);
897
+ if (retMap.pkgList?.length) {
898
+ pkgList = pkgList.concat(retMap.pkgList);
899
+ }
900
+ if (retMap?.rootList?.length) {
901
+ const thisParentDependsOn = [
902
+ {
903
+ ref: parentComponent["bom-ref"],
904
+ dependsOn: [
905
+ ...new Set(retMap.rootList.map((c) => c["bom-ref"])),
906
+ ].sort(),
907
+ },
908
+ ];
909
+ dependencies = mergeDependencies(
910
+ dependencies,
911
+ thisParentDependsOn,
912
+ parentComponent,
913
+ );
914
+ }
915
+ }
916
+ }
917
+ return buildBomNSData(options, pkgList, "pub", {
918
+ src: path,
919
+ dependencies,
920
+ parentComponent,
921
+ filename: pubFiles.join(", "),
922
+ });
923
+ }
924
+
925
+ /**
926
+ * Function to create bom string for cpp projects
927
+ *
928
+ * @param {string} path to the project
929
+ * @param {Object} options Parse options from the cli
930
+ * @returns {Object} BOM object
931
+ */
932
+ export function createCppBom(path, options) {
933
+ let parentComponent;
934
+ let dependencies = [];
935
+ const addedParentComponentsMap = {};
936
+ const colliderLockFiles = getAllFiles(
937
+ path,
938
+ `${options.multiProject ? "**/" : ""}collider.lock`,
939
+ options,
940
+ );
941
+ const conanLockFiles = getAllFiles(
942
+ path,
943
+ `${options.multiProject ? "**/" : ""}conan.lock`,
944
+ options,
945
+ );
946
+ const conanFiles = getAllFiles(
947
+ path,
948
+ `${options.multiProject ? "**/" : ""}conanfile.txt`,
949
+ options,
950
+ );
951
+ let cmakeLikeFiles = [];
952
+ const mesonBuildFiles = getAllFiles(
953
+ path,
954
+ `${options.multiProject ? "**/" : ""}meson.build`,
955
+ options,
956
+ );
957
+ if (mesonBuildFiles?.length) {
958
+ cmakeLikeFiles = cmakeLikeFiles.concat(mesonBuildFiles);
959
+ }
960
+ cmakeLikeFiles = cmakeLikeFiles.concat(
961
+ getAllFiles(
962
+ path,
963
+ `${options.multiProject ? "**/" : ""}CMakeLists.txt`,
964
+ options,
965
+ ),
966
+ );
967
+ const cmakeFiles = getAllFiles(
968
+ path,
969
+ `${options.multiProject ? "**/" : ""}*.cmake`,
970
+ options,
971
+ );
972
+ if (cmakeFiles?.length) {
973
+ cmakeLikeFiles = cmakeLikeFiles.concat(cmakeFiles);
974
+ }
975
+ let pkgList = [];
976
+ let parentComponentDependencies = [];
977
+ if (conanLockFiles.length) {
978
+ for (const f of conanLockFiles) {
979
+ if (DEBUG_MODE) {
980
+ console.log(`Parsing ${f}`);
981
+ }
982
+ const conanLockData = readFileSync(f, { encoding: "utf-8" });
983
+ const {
984
+ pkgList: conanPkgList,
985
+ dependencies: conanDependencies,
986
+ parentComponentDependencies: parentCompDeps,
987
+ } = parseConanLockData(conanLockData);
988
+
989
+ if (conanPkgList.length) {
990
+ pkgList = pkgList.concat(conanPkgList);
991
+ }
992
+
993
+ if (Object.keys(conanDependencies).length) {
994
+ dependencies = mergeDependencies(
995
+ dependencies,
996
+ Object.keys(conanDependencies).map((dependentBomRef) => ({
997
+ ref: dependentBomRef,
998
+ dependsOn: conanDependencies[dependentBomRef],
999
+ })),
1000
+ );
1001
+ }
1002
+
1003
+ parentComponentDependencies = parentCompDeps;
1004
+ }
1005
+ } else if (conanFiles.length) {
1006
+ for (const f of conanFiles) {
1007
+ if (DEBUG_MODE) {
1008
+ console.log(`Parsing ${f}`);
1009
+ }
1010
+ const conanData = readFileSync(f, { encoding: "utf-8" });
1011
+ const dlist = parseConanData(conanData);
1012
+ if (dlist?.length) {
1013
+ pkgList = pkgList.concat(dlist);
1014
+ }
1015
+ }
1016
+ }
1017
+ if (colliderLockFiles.length) {
1018
+ for (const f of colliderLockFiles) {
1019
+ if (DEBUG_MODE) {
1020
+ console.log(`Parsing ${f}`);
1021
+ }
1022
+ const colliderLockData = readFileSync(f, { encoding: "utf-8" });
1023
+ const {
1024
+ pkgList: colliderPkgList,
1025
+ dependencies: colliderDependencies,
1026
+ parentComponentDependencies: parentCompDeps,
1027
+ } = parseColliderLockData(colliderLockData, f);
1028
+
1029
+ if (colliderPkgList.length) {
1030
+ pkgList = pkgList.concat(colliderPkgList);
1031
+ }
1032
+
1033
+ if (Object.keys(colliderDependencies).length) {
1034
+ dependencies = mergeDependencies(
1035
+ dependencies,
1036
+ Object.keys(colliderDependencies).map((dependentBomRef) => ({
1037
+ ref: dependentBomRef,
1038
+ dependsOn: colliderDependencies[dependentBomRef],
1039
+ })),
1040
+ );
1041
+ }
1042
+
1043
+ if (parentCompDeps.length) {
1044
+ parentComponentDependencies = [
1045
+ ...new Set(parentComponentDependencies.concat(parentCompDeps)),
1046
+ ];
1047
+ }
1048
+ }
1049
+ }
1050
+ if (cmakeLikeFiles.length) {
1051
+ const beforeCmake = pkgList.length;
1052
+ for (const f of cmakeLikeFiles) {
1053
+ if (DEBUG_MODE) {
1054
+ console.log(`Parsing ${f}`);
1055
+ }
1056
+ const basePath = dirname(f);
1057
+ const retMap = parseCmakeLikeFile(f, "generic");
1058
+ if (retMap.pkgList?.length) {
1059
+ pkgList = pkgList.concat(retMap.pkgList);
1060
+ }
1061
+ if (
1062
+ basePath === path &&
1063
+ retMap.parentComponent &&
1064
+ Object.keys(retMap.parentComponent).length
1065
+ ) {
1066
+ if (!parentComponent) {
1067
+ parentComponent = retMap.parentComponent;
1068
+ } else {
1069
+ parentComponent.components = parentComponent.components || [];
1070
+ if (!addedParentComponentsMap[retMap.parentComponent.name]) {
1071
+ parentComponent.components.push(retMap.parentComponent);
1072
+ addedParentComponentsMap[retMap.parentComponent.name] = true;
1073
+ }
1074
+ }
1075
+ } else if (
1076
+ retMap.parentComponent &&
1077
+ Object.keys(retMap.parentComponent).length &&
1078
+ !addedParentComponentsMap[retMap.parentComponent.name]
1079
+ ) {
1080
+ retMap.parentComponent.type = "library";
1081
+ pkgList.push(retMap.parentComponent);
1082
+ }
1083
+ // Retain the dependency tree from cmake
1084
+ if (retMap.dependenciesList) {
1085
+ if (dependencies.length) {
1086
+ dependencies = mergeDependencies(
1087
+ dependencies,
1088
+ retMap.dependenciesList,
1089
+ parentComponent,
1090
+ );
1091
+ } else {
1092
+ dependencies = retMap.dependenciesList;
1093
+ }
1094
+ }
1095
+ }
1096
+ // Only the entries this loop appended state version *requirements* that
1097
+ // several files may repeat. The conan and collider entries above name
1098
+ // resolved versions and are left as they are.
1099
+ pkgList = pkgList
1100
+ .slice(0, beforeCmake)
1101
+ .concat(collapseCmakeVersions(pkgList.slice(beforeCmake)));
1102
+ }
1103
+ // CMake describes how a project is built from source. An image or an OS
1104
+ // installation carries build output, not a build tree, so resolving CMake
1105
+ // context over every directory of an exploded rootfs finds nothing and costs
1106
+ // a filesystem walk and a git invocation per directory.
1107
+ const cmakeContext = hasAnyProjectType(
1108
+ ["docker", "oci", "container", "os"],
1109
+ options,
1110
+ false,
1111
+ )
1112
+ ? {
1113
+ rootProject: undefined,
1114
+ findPackages: new Map(),
1115
+ submodules: [],
1116
+ fetchDeps: [],
1117
+ boundaries: new Map(),
1118
+ }
1119
+ : resolveCmakeContext(path, options);
1120
+ if (cmakeContext.rootProject?.version && parentComponent) {
1121
+ const resolvedVersion = cmakeContext.rootProject.version;
1122
+ const scrapedVersion = parentComponent.version;
1123
+ if (!scrapedVersion || scrapedVersion.includes("${")) {
1124
+ parentComponent.version = resolvedVersion;
1125
+ applyPurl(
1126
+ parentComponent,
1127
+ tryBuildPurl({
1128
+ type: "generic",
1129
+ namespace: parentComponent.group || null,
1130
+ name: parentComponent.name,
1131
+ version: resolvedVersion,
1132
+ }),
1133
+ );
1134
+ }
1135
+ }
1136
+ if (cmakeContext.findPackages.size) {
1137
+ for (const pkg of pkgList) {
1138
+ if (pkg.version) {
1139
+ continue;
1140
+ }
1141
+ const resolved =
1142
+ cmakeContext.findPackages.get(pkg.name) ||
1143
+ cmakeContext.findPackages.get(pkg.name.toUpperCase());
1144
+ if (resolved) {
1145
+ pkg.version = resolved;
1146
+ applyPurl(
1147
+ pkg,
1148
+ tryBuildPurl({
1149
+ type: "generic",
1150
+ name: pkg.name,
1151
+ version: resolved,
1152
+ }),
1153
+ );
1154
+ pkg.properties = pkg.properties || [];
1155
+ pkg.properties.push({
1156
+ name: "cdx:cmake:resolvedVia",
1157
+ value: "cmake-cache",
1158
+ });
1159
+ }
1160
+ }
1161
+ }
1162
+ for (const dep of cmakeContext.fetchDeps) {
1163
+ const depPurl = buildDependentPurl(dep.url, dep.version);
1164
+ const depRef = depPurl
1165
+ ? decodeURIComponent(depPurl)
1166
+ : `library:${dep.name}:${dep.version || ""}`;
1167
+ const depComponent = {
1168
+ name: dep.name,
1169
+ version: dep.version || "",
1170
+ type: "library",
1171
+ purl: depPurl,
1172
+ "bom-ref": depRef,
1173
+ evidence: {
1174
+ identity: {
1175
+ field: "purl",
1176
+ confidence: 0.6,
1177
+ methods: [
1178
+ {
1179
+ technique: "manifest-analysis",
1180
+ confidence: 0.6,
1181
+ value: "FetchContent gitclone script",
1182
+ },
1183
+ ],
1184
+ },
1185
+ },
1186
+ properties: [
1187
+ { name: "cdx:cmake:depKind", value: "fetch" },
1188
+ { name: "cdx:cmake:resolvedVia", value: "gitclone-script" },
1189
+ ],
1190
+ };
1191
+ if (dep.sourceDir) {
1192
+ depComponent.properties.push({
1193
+ name: "cdx:cmake:sourceDir",
1194
+ value: dep.sourceDir,
1195
+ });
1196
+ }
1197
+ pkgList.push(depComponent);
1198
+ }
1199
+ for (const sub of cmakeContext.submodules) {
1200
+ const subPurl = buildDependentPurl(sub.url, sub.version);
1201
+ const subRef = subPurl
1202
+ ? decodeURIComponent(subPurl)
1203
+ : `library:${sub.name}:${sub.version || ""}`;
1204
+ const props = [
1205
+ { name: "cdx:cmake:depKind", value: "submodule" },
1206
+ { name: "cdx:cmake:resolvedVia", value: "git-submodule" },
1207
+ ];
1208
+ if (sub.uninitialised) {
1209
+ props.push({ name: "cdx:cmake:uninitialised", value: "true" });
1210
+ }
1211
+ if (sub.path) {
1212
+ props.push({ name: "cdx:cmake:sourceDir", value: sub.path });
1213
+ }
1214
+ pkgList.push({
1215
+ name: sub.name,
1216
+ version: sub.version || "",
1217
+ type: "library",
1218
+ purl: subPurl,
1219
+ "bom-ref": subRef,
1220
+ evidence: {
1221
+ identity: {
1222
+ field: "purl",
1223
+ confidence: 0.6,
1224
+ methods: [
1225
+ {
1226
+ technique: "manifest-analysis",
1227
+ confidence: 0.6,
1228
+ value: "git submodule status",
1229
+ },
1230
+ ],
1231
+ },
1232
+ },
1233
+ properties: props,
1234
+ });
1235
+ }
1236
+ // The need for java >= 21 with atom is causing confusions since there could be C projects
1237
+ // inside of other project types. So we currently limit this analyis only when -t argument
1238
+ // is used.
1239
+ if (
1240
+ !hasAnyProjectType(["docker", "oci", "container", "os"], options, false) &&
1241
+ (!options.createMultiXBom || options.deep)
1242
+ ) {
1243
+ let osPkgsList = [];
1244
+ // Case 1: Development libraries installed in this OS environment might be used for build
1245
+ // We collect OS packages with the word dev in the name using osquery here
1246
+ // rpm, deb and ebuild are supported
1247
+ // TODO: For archlinux and alpine users we need a different mechanism to collect this information
1248
+ for (const queryCategory of Object.keys(cosDbQueries)) {
1249
+ const queryObj = cosDbQueries[queryCategory];
1250
+ const results = executeOsQuery(queryObj.query);
1251
+ const dlist = convertOSQueryResults(
1252
+ queryCategory,
1253
+ queryObj,
1254
+ results,
1255
+ true,
1256
+ {
1257
+ deb: executeDpkgList,
1258
+ rpm: executeRpmList,
1259
+ apk: executeApkList,
1260
+ ebuild: executeEqueryList,
1261
+ alpm: executeAlpmList,
1262
+ },
1263
+ );
1264
+ if (dlist?.length) {
1265
+ osPkgsList = osPkgsList.concat(dlist);
1266
+ }
1267
+ }
1268
+ // Now we check with atom and attempt to detect all external modules via usages
1269
+ // We pass the current list of packages so that we enhance the current list and replace
1270
+ // components inadvertently. For example, we might resolved a name, version and url information already via cmake
1271
+ const retMap = getCppModules(path, options, osPkgsList, pkgList);
1272
+ if (retMap.pkgList?.length) {
1273
+ pkgList = pkgList.concat(retMap.pkgList);
1274
+ }
1275
+ if (retMap.dependenciesList) {
1276
+ if (dependencies.length) {
1277
+ dependencies = mergeDependencies(
1278
+ dependencies,
1279
+ retMap.dependenciesList,
1280
+ parentComponent,
1281
+ );
1282
+ } else {
1283
+ dependencies = retMap.dependenciesList;
1284
+ }
1285
+ }
1286
+ if (!parentComponent) {
1287
+ parentComponent = retMap.parentComponent;
1288
+ } else {
1289
+ parentComponent.components = parentComponent.components || [];
1290
+ if (
1291
+ retMap?.parentComponent?.name &&
1292
+ !addedParentComponentsMap[retMap.parentComponent.name]
1293
+ ) {
1294
+ parentComponent.components.push(retMap.parentComponent);
1295
+ addedParentComponentsMap[retMap.parentComponent.name] = true;
1296
+ }
1297
+ }
1298
+ }
1299
+ if (!options.createMultiXBom) {
1300
+ if (!parentComponent) {
1301
+ parentComponent = createDefaultParentComponent(path, "generic", options);
1302
+ }
1303
+ options.parentComponent = parentComponent;
1304
+ }
1305
+
1306
+ if (parentComponent && parentComponentDependencies.length) {
1307
+ dependencies = mergeDependencies(dependencies, [
1308
+ {
1309
+ ref: parentComponent["bom-ref"],
1310
+ dependsOn: parentComponentDependencies,
1311
+ },
1312
+ ]);
1313
+ }
1314
+
1315
+ if (parentComponent) {
1316
+ sanitizeUnresolvedPurl(parentComponent);
1317
+ if (parentComponent.components) {
1318
+ for (const sub of parentComponent.components) {
1319
+ sanitizeUnresolvedPurl(sub);
1320
+ }
1321
+ }
1322
+ }
1323
+ for (const pkg of pkgList) {
1324
+ sanitizeUnresolvedPurl(pkg);
1325
+ }
1326
+
1327
+ return buildBomNSData(options, pkgList, "generic", {
1328
+ src: path,
1329
+ parentComponent,
1330
+ dependencies,
1331
+ });
1332
+ }
1333
+
1334
+ /**
1335
+ * Function to create bom string for clojure projects
1336
+ *
1337
+ * @param {string} path to the project
1338
+ * @param {Object} options Parse options from the cli
1339
+ * @returns {Object} BOM object
1340
+ */
1341
+ export function createClojureBom(path, options) {
1342
+ const ednFiles = getAllFiles(
1343
+ path,
1344
+ `${options.multiProject ? "**/" : ""}deps.edn`,
1345
+ options,
1346
+ );
1347
+ const leinFiles = getAllFiles(
1348
+ path,
1349
+ `${options.multiProject ? "**/" : ""}project.clj`,
1350
+ options,
1351
+ );
1352
+ let pkgList = [];
1353
+ if (leinFiles.length) {
1354
+ let LEIN_ARGS = ["deps", ":tree-data"];
1355
+ if (readEnvironmentVariable("LEIN_ARGS")) {
1356
+ LEIN_ARGS = readEnvironmentVariable("LEIN_ARGS").split(" ");
1357
+ }
1358
+ for (const f of leinFiles) {
1359
+ if (DEBUG_MODE) {
1360
+ console.log(`Parsing ${f}`);
1361
+ }
1362
+ const basePath = dirname(f);
1363
+ console.log("Executing", LEIN_CMD, "in", basePath);
1364
+ const result = safeSpawnSync(LEIN_CMD, LEIN_ARGS, {
1365
+ cwd: basePath,
1366
+ });
1367
+ if (result.status !== 0 || result.error) {
1368
+ if (result.stderr) {
1369
+ console.error(result.stdout, result.stderr);
1370
+ options.failOnError && process.exit(1);
1371
+ }
1372
+ console.log(
1373
+ "Check if the correct version of lein is installed and available in PATH. Falling back to manual parsing.",
1374
+ );
1375
+ if (DEBUG_MODE) {
1376
+ console.log(`Parsing ${f}`);
1377
+ }
1378
+ const leinData = readFileSync(f, { encoding: "utf-8" });
1379
+ const dlist = parseLeiningenData(leinData);
1380
+ if (dlist?.length) {
1381
+ pkgList = pkgList.concat(dlist);
1382
+ }
1383
+ } else {
1384
+ const stdout = result.stdout;
1385
+ if (stdout) {
1386
+ const cmdOutput = Buffer.from(stdout).toString();
1387
+ const dlist = parseLeinDep(cmdOutput);
1388
+ if (dlist?.length) {
1389
+ pkgList = pkgList.concat(dlist);
1390
+ }
1391
+ } else {
1392
+ console.error("lein unexpectedly didn't return any output");
1393
+ options.failOnError && process.exit(1);
1394
+ }
1395
+ }
1396
+ }
1397
+ return buildBomNSData(options, pkgList, "clojars", {
1398
+ src: path,
1399
+ filename: leinFiles.join(", "),
1400
+ });
1401
+ }
1402
+ if (ednFiles.length && !hasAnyProjectType(["oci"], options, false)) {
1403
+ let CLJ_ARGS = ["-Stree"];
1404
+ if (readEnvironmentVariable("CLJ_ARGS")) {
1405
+ CLJ_ARGS = readEnvironmentVariable("CLJ_ARGS").split(" ");
1406
+ }
1407
+ for (const f of ednFiles) {
1408
+ const basePath = dirname(f);
1409
+ console.log("Executing", CLJ_CMD, "in", basePath);
1410
+ const result = safeSpawnSync(CLJ_CMD, CLJ_ARGS, {
1411
+ cwd: basePath,
1412
+ });
1413
+ if (result.status !== 0 || result.error) {
1414
+ if (result.stderr) {
1415
+ console.error(result.stdout, result.stderr);
1416
+ options.failOnError && process.exit(1);
1417
+ }
1418
+ console.log(
1419
+ "Check if the correct version of clojure cli is installed and available in PATH. Falling back to manual parsing.",
1420
+ );
1421
+ if (DEBUG_MODE) {
1422
+ console.log(`Parsing ${f}`);
1423
+ }
1424
+ const ednData = readFileSync(f, { encoding: "utf-8" });
1425
+ const dlist = parseEdnData(ednData);
1426
+ if (dlist?.length) {
1427
+ pkgList = pkgList.concat(dlist);
1428
+ }
1429
+ } else {
1430
+ const stdout = result.stdout;
1431
+ if (stdout) {
1432
+ const cmdOutput = Buffer.from(stdout).toString();
1433
+ const dlist = parseCljDep(cmdOutput);
1434
+ if (dlist?.length) {
1435
+ pkgList = pkgList.concat(dlist);
1436
+ }
1437
+ } else {
1438
+ console.error("clj unexpectedly didn't return any output");
1439
+ options.failOnError && process.exit(1);
1440
+ }
1441
+ }
1442
+ }
1443
+ return buildBomNSData(options, pkgList, "clojars", {
1444
+ src: path,
1445
+ filename: ednFiles.join(", "),
1446
+ });
1447
+ }
1448
+
1449
+ return {};
1450
+ }
1451
+
1452
+ /**
1453
+ * Function to create bom string for Haskell projects
1454
+ *
1455
+ * @param {string} path to the project
1456
+ * @param {Object} options Parse options from the cli
1457
+ * @returns {Object} BOM object
1458
+ */
1459
+ export function createHaskellBom(path, options) {
1460
+ const cabalFiles = getAllFiles(
1461
+ path,
1462
+ `${options.multiProject ? "**/" : ""}cabal.project.freeze`,
1463
+ options,
1464
+ );
1465
+ let pkgList = [];
1466
+ if (cabalFiles.length) {
1467
+ for (const f of cabalFiles) {
1468
+ if (DEBUG_MODE) {
1469
+ console.log(`Parsing ${f}`);
1470
+ }
1471
+ const cabalData = readFileSync(f, { encoding: "utf-8" });
1472
+ const dlist = parseCabalData(cabalData);
1473
+ if (dlist?.length) {
1474
+ pkgList = pkgList.concat(dlist);
1475
+ }
1476
+ }
1477
+ return buildBomNSData(options, pkgList, "hackage", {
1478
+ src: path,
1479
+ filename: cabalFiles.join(", "),
1480
+ });
1481
+ }
1482
+ return {};
1483
+ }
1484
+
1485
+ /**
1486
+ * Function to create bom string for Elixir projects
1487
+ *
1488
+ * @param {string} path to the project
1489
+ * @param {Object} options Parse options from the cli
1490
+ * @returns {Object} BOM object
1491
+ */
1492
+ export function createElixirBom(path, options) {
1493
+ const mixFiles = getAllFiles(
1494
+ path,
1495
+ `${options.multiProject ? "**/" : ""}mix.lock`,
1496
+ options,
1497
+ );
1498
+ let pkgList = [];
1499
+ if (mixFiles.length) {
1500
+ for (const f of mixFiles) {
1501
+ if (DEBUG_MODE) {
1502
+ console.log(`Parsing ${f}`);
1503
+ }
1504
+ const mixData = readFileSync(f, { encoding: "utf-8" });
1505
+ const dlist = parseMixLockData(mixData);
1506
+ if (dlist?.length) {
1507
+ pkgList = pkgList.concat(dlist);
1508
+ }
1509
+ }
1510
+ return buildBomNSData(options, pkgList, "hex", {
1511
+ src: path,
1512
+ filename: mixFiles.join(", "),
1513
+ });
1514
+ }
1515
+ return {};
1516
+ }
1517
+
1518
+ /**
1519
+ * Function to create bom string for swift projects
1520
+ *
1521
+ * @param {string} path to the project
1522
+ * @param {Object} options Parse options from the cli
1523
+ * @returns {Promise<Object>} Promise resolving to BOM object
1524
+ */
1525
+ export async function createSwiftBom(path, options) {
1526
+ const swiftFiles = getAllFiles(
1527
+ path,
1528
+ `${options.multiProject ? "**/" : ""}Package*.swift`,
1529
+ options,
1530
+ );
1531
+ const pkgResolvedFiles = getAllFiles(
1532
+ path,
1533
+ `${options.multiProject ? "**/" : ""}Package.resolved`,
1534
+ options,
1535
+ );
1536
+ let pkgList = [];
1537
+ let dependencies = [];
1538
+ let parentComponent = {};
1539
+ const completedPath = [];
1540
+ let packageArgsMessageShown = false;
1541
+ if (pkgResolvedFiles.length) {
1542
+ for (const f of pkgResolvedFiles) {
1543
+ if (!parentComponent || !Object.keys(parentComponent).length) {
1544
+ parentComponent = createDefaultParentComponent(f, "swift", options);
1545
+ }
1546
+ if (DEBUG_MODE) {
1547
+ console.log("Parsing", f);
1548
+ }
1549
+ const dlist = parseSwiftResolved(f);
1550
+ if (dlist?.length) {
1551
+ pkgList = pkgList.concat(dlist);
1552
+ }
1553
+ }
1554
+ thoughtLog(
1555
+ `It looks like we have ${pkgResolvedFiles.length} Package.resolved files, which is good. To compute the dependency tree, let's try using the swift package command 📦.`,
1556
+ );
1557
+ }
1558
+ if (swiftFiles.length) {
1559
+ for (const f of swiftFiles) {
1560
+ const basePath = dirname(f);
1561
+ if (completedPath.includes(basePath)) {
1562
+ continue;
1563
+ }
1564
+ let treeData;
1565
+ let packageArgs = ["package"];
1566
+ // Additional arguments to pass to the swift package command.
1567
+ // Example: --swift-sdks-path <swift-sdks-path> --jobs <jobs>
1568
+ if (readEnvironmentVariable("SWIFT_PACKAGE_ARGS")) {
1569
+ packageArgs = packageArgs.concat(
1570
+ readEnvironmentVariable("SWIFT_PACKAGE_ARGS").split(" "),
1571
+ );
1572
+ if (!packageArgsMessageShown) {
1573
+ thoughtLog(
1574
+ `Wait, let's use the additional arguments '${readEnvironmentVariable("SWIFT_PACKAGE_ARGS")}' for the swift package command.`,
1575
+ );
1576
+ packageArgsMessageShown = true;
1577
+ }
1578
+ }
1579
+ packageArgs = packageArgs.concat([
1580
+ "show-dependencies",
1581
+ "--format",
1582
+ "json",
1583
+ ]);
1584
+ let swiftCommand = SWIFT_CMD;
1585
+ if (swiftCommand.startsWith("xcrun")) {
1586
+ swiftCommand = "xcrun";
1587
+ packageArgs = ["swift"].concat(packageArgs);
1588
+ }
1589
+ if (DEBUG_MODE) {
1590
+ console.log(
1591
+ `Executing '${swiftCommand} ${packageArgs.join(" ")}' in ${basePath}. Please wait ...`,
1592
+ );
1593
+ }
1594
+ const result = safeSpawnSync(swiftCommand, packageArgs, {
1595
+ cwd: basePath,
1596
+ });
1597
+ if (result.stdout) {
1598
+ completedPath.push(basePath);
1599
+ treeData = Buffer.from(result.stdout).toString();
1600
+ const retData = parseSwiftJsonTree(treeData, f);
1601
+ if (retData.rootList?.length) {
1602
+ if (!Object.keys(parentComponent).length) {
1603
+ parentComponent = retData.rootList[0];
1604
+ if (retData.rootList.length > 1) {
1605
+ if (!parentComponent.components) {
1606
+ parentComponent.components = [];
1607
+ }
1608
+ for (const p of retData.rootList.splice(0, 1)) {
1609
+ parentComponent.components.push(p);
1610
+ }
1611
+ }
1612
+ } else {
1613
+ if (!parentComponent.components) {
1614
+ parentComponent.components = [];
1615
+ }
1616
+ parentComponent.components.concat(retData.rootList);
1617
+ }
1618
+ }
1619
+ pkgList = pkgList.concat(retData.pkgList);
1620
+ if (retData.dependenciesList) {
1621
+ dependencies = mergeDependencies(
1622
+ dependencies,
1623
+ retData.dependenciesList,
1624
+ parentComponent,
1625
+ );
1626
+ }
1627
+ }
1628
+ if (result.status !== 0 || result.error) {
1629
+ if (result?.stderr?.includes("Source files for target")) {
1630
+ console.log(
1631
+ "The Sources directory is missing. Please run cdxgen from the directory that contains the complete source code.",
1632
+ );
1633
+ thoughtLog(
1634
+ `It looks like the 'Sources' directory is missing, so we are missing the components and dependencies for '${basename(basePath)}'.`,
1635
+ );
1636
+ } else if (readEnvironmentVariable("CDXGEN_IN_CONTAINER") !== "true") {
1637
+ console.log(
1638
+ "Consider using the cdxgen container image (`ghcr.io/cdxgen/cdxgen`), which includes Swift and additional build tools.",
1639
+ );
1640
+ if (!isMac) {
1641
+ console.log("Alternatively, try building this project from a Mac.");
1642
+ thoughtLog(
1643
+ "I'm wondering if the results might be better on a Mac 🤔.",
1644
+ );
1645
+ }
1646
+ }
1647
+ console.error(result.stderr);
1648
+ options.failOnError && process.exit(1);
1649
+ }
1650
+ }
1651
+ }
1652
+ if (shouldFetchLicense()) {
1653
+ pkgList = await getSwiftPackageMetadata(pkgList);
1654
+ }
1655
+ return buildBomNSData(options, pkgList, "swift", {
1656
+ src: path,
1657
+ filename: swiftFiles.join(", "),
1658
+ parentComponent,
1659
+ dependencies,
1660
+ });
1661
+ }
1662
+
1663
+ /**
1664
+ * Function to create bom string for cocoa projects
1665
+ *
1666
+ * @param {string} path to the project
1667
+ * @param {Object} options Parse options from the cli
1668
+ * @returns {Promise<Object | undefined>} Promise resolving to a BOM object, or `undefined` when no Podfiles are found
1669
+ */
1670
+ export async function createCocoaBom(path, options) {
1671
+ const cocoaFiles = getAllFiles(
1672
+ path,
1673
+ `${options.multiProject ? "**/" : ""}Podfile`,
1674
+ options,
1675
+ );
1676
+ if (cocoaFiles.length > 1) {
1677
+ thoughtLog(
1678
+ `There are ${cocoaFiles.length} pod files. I will carefully process each one.`,
1679
+ );
1680
+ }
1681
+ let excludeMessageShown = false;
1682
+ for (const podFile of cocoaFiles) {
1683
+ const projectPath = dirname(podFile);
1684
+ const lockFile = `${podFile}.lock`;
1685
+ let missingLockWarningShown = false;
1686
+ if (!safeExistsSync(lockFile)) {
1687
+ if (options.installDeps) {
1688
+ executePodCommand(["install"], projectPath, options);
1689
+ } else {
1690
+ console.log(
1691
+ "No 'Podfile.lock' found and '--no-install-deps' is set -- A Podfile.lock is needed to parse dependencies!",
1692
+ );
1693
+ missingLockWarningShown = true;
1694
+ options.failOnError && process.exit(1);
1695
+ }
1696
+ } else if (options.deep && options.installDeps) {
1697
+ executePodCommand(["install"], projectPath, options);
1698
+ }
1699
+ if (!safeExistsSync(lockFile)) {
1700
+ if (!missingLockWarningShown) {
1701
+ console.log(
1702
+ `No 'Podfile.lock' found for ${projectPath}. Skipping CocoaPods dependency parsing for this project.`,
1703
+ );
1704
+ }
1705
+ continue;
1706
+ }
1707
+ const parentComponent = await buildObjectForCocoaPod(
1708
+ {
1709
+ name: basename(projectPath),
1710
+ version: "latest",
1711
+ },
1712
+ undefined,
1713
+ "application",
1714
+ );
1715
+ const podfileLock = loadYaml(readFileSync(lockFile, "utf-8"));
1716
+ const pods = await parsePodfileLock(podfileLock, projectPath);
1717
+ const allObjects = new Map();
1718
+ if (options) {
1719
+ // Every remote podspec the scan below reads is known from the lockfile,
1720
+ // so they are fetched in batched rounds rather than one at a time inside
1721
+ // the loop.
1722
+ await prefetchCocoaPodspecs(
1723
+ [...pods.values()].map((pod) => pod.metadata),
1724
+ );
1725
+ }
1726
+ for (const [name, pod] of pods) {
1727
+ allObjects.set(name, await buildObjectForCocoaPod(pod.metadata, options));
1728
+ }
1729
+ const allDependencies = new Map();
1730
+ for (const [name, pod] of pods) {
1731
+ const podDependencies = new Set();
1732
+ if (pod.dependencies) {
1733
+ for (const podDependency of pod.dependencies) {
1734
+ podDependencies.add(podDependency.name);
1735
+ }
1736
+ }
1737
+ allDependencies.set(name, podDependencies);
1738
+ }
1739
+ const targetDependencies = new Map();
1740
+ if (
1741
+ !readEnvironmentVariable("COCOA_INCLUDED_TARGETS") &&
1742
+ !readEnvironmentVariable("COCOA_EXCLUDED_TARGETS")
1743
+ ) {
1744
+ targetDependencies.set("Pods", podfileLock["DEPENDENCIES"]);
1745
+ } else {
1746
+ const result = executePodCommand(
1747
+ ["ipc", "podfile-json", "--silent", podFile],
1748
+ projectPath,
1749
+ options,
1750
+ );
1751
+ const resolvedPodFile = JSON.parse(result.stdout);
1752
+ parsePodfileTargets(
1753
+ resolvedPodFile["target_definitions"][0],
1754
+ targetDependencies,
1755
+ );
1756
+ }
1757
+ const usedTargets = new Set(
1758
+ readEnvironmentVariable("COCOA_INCLUDED_TARGETS")
1759
+ ? readEnvironmentVariable("COCOA_INCLUDED_TARGETS").split(",")
1760
+ : targetDependencies.keys(),
1761
+ );
1762
+ if (readEnvironmentVariable("COCOA_EXCLUDED_TARGETS")) {
1763
+ readEnvironmentVariable("COCOA_EXCLUDED_TARGETS")
1764
+ .split(",")
1765
+ .forEach((excludedTarget) => {
1766
+ usedTargets.delete(excludedTarget);
1767
+ });
1768
+ if (!excludeMessageShown) {
1769
+ thoughtLog(
1770
+ "Wait, the user wants me to exclude certain targets from this CocoaPods project. Perhaps they don't want dev and test projects included in the SBOM 🤔?",
1771
+ );
1772
+ excludeMessageShown = true;
1773
+ }
1774
+ }
1775
+ let addedObjects = new Set();
1776
+ for (const target of usedTargets) {
1777
+ if (targetDependencies.has(target)) {
1778
+ for (const dependency of targetDependencies.get(target)) {
1779
+ let dependencyName = parseCocoaDependency(dependency, false).name;
1780
+ if (
1781
+ !["false", "0"].includes(
1782
+ readEnvironmentVariable("COCOA_MERGE_SUBSPECS"),
1783
+ )
1784
+ ) {
1785
+ dependencyName = dependencyName.split("/")[0];
1786
+ }
1787
+ addedObjects.add(dependencyName);
1788
+ }
1789
+ }
1790
+ }
1791
+ // A Podfile target can name a pod that the lockfile does not resolve (a
1792
+ // subspec collapsed by COCOA_MERGE_SUBSPECS, or a pod declared but never
1793
+ // locked). Those names have no entry in allObjects/allDependencies, so every
1794
+ // lookup here is filtered rather than dereferenced — the unguarded version
1795
+ // threw "allDependencies.get(...) is not iterable" and aborted the scan.
1796
+ const bomRefFor = (name) => allObjects.get(name)?.["bom-ref"];
1797
+ const dependenciesOf = (name) => allDependencies.get(name) ?? [];
1798
+ let includedDependencies = [
1799
+ {
1800
+ ref: parentComponent["bom-ref"],
1801
+ dependsOn: [
1802
+ ...new Set([...addedObjects].map(bomRefFor).filter(Boolean)),
1803
+ ],
1804
+ },
1805
+ ];
1806
+ const includedObjects = new Set(addedObjects);
1807
+ while (addedObjects.size !== 0) {
1808
+ const newlyAddedObjects = new Set();
1809
+ for (const addedObject of addedObjects) {
1810
+ for (const dependency of dependenciesOf(addedObject)) {
1811
+ if (!includedObjects.has(dependency)) {
1812
+ includedObjects.add(dependency);
1813
+ newlyAddedObjects.add(dependency);
1814
+ }
1815
+ }
1816
+ }
1817
+ addedObjects = newlyAddedObjects;
1818
+ }
1819
+ for (const object of includedObjects) {
1820
+ const ref = bomRefFor(object);
1821
+ if (!ref) {
1822
+ continue;
1823
+ }
1824
+ includedDependencies = mergeDependencies(includedDependencies, [
1825
+ {
1826
+ ref,
1827
+ dependsOn: [
1828
+ ...new Set(
1829
+ [...dependenciesOf(object)].map(bomRefFor).filter(Boolean),
1830
+ ),
1831
+ ],
1832
+ },
1833
+ ]);
1834
+ }
1835
+ return buildBomNSData(
1836
+ options,
1837
+ [...includedObjects].map((obj) => allObjects.get(obj)).filter(Boolean),
1838
+ "cocoapods",
1839
+ {
1840
+ src: path,
1841
+ filename: lockFile,
1842
+ dependencies: includedDependencies,
1843
+ parentComponent,
1844
+ },
1845
+ );
1846
+ }
1847
+ }
1848
+
1849
+ /**
1850
+ * Function to create bom string for Nix flakes
1851
+ *
1852
+ * @param {string} path to the project
1853
+ * @param {Object} options Parse options from the cli
1854
+ * @returns {Promise<Object>} Promise resolving to BOM object
1855
+ */
1856
+ export async function createNixBom(path, options) {
1857
+ let pkgList = [];
1858
+ let dependencies = [];
1859
+ let parentComponent = {};
1860
+
1861
+ const flakeNixFiles = getAllFiles(
1862
+ path,
1863
+ `${options.multiProject ? "**/" : ""}flake.nix`,
1864
+ options,
1865
+ );
1866
+ const flakeLockFiles = getAllFiles(
1867
+ path,
1868
+ `${options.multiProject ? "**/" : ""}flake.lock`,
1869
+ options,
1870
+ );
1871
+
1872
+ for (const flakeNixFile of flakeNixFiles) {
1873
+ if (DEBUG_MODE) {
1874
+ console.log(`Parsing ${flakeNixFile}`);
1875
+ }
1876
+ const { pkgList: nixPkgs, dependencies: nixDeps } =
1877
+ parseFlakeNix(flakeNixFile);
1878
+ if (nixPkgs?.length) {
1879
+ pkgList = pkgList.concat(nixPkgs);
1880
+ }
1881
+ if (nixDeps?.length) {
1882
+ dependencies = dependencies.concat(nixDeps);
1883
+ }
1884
+ }
1885
+
1886
+ for (const flakeLockFile of flakeLockFiles) {
1887
+ if (DEBUG_MODE) {
1888
+ console.log(`Parsing ${flakeLockFile}`);
1889
+ }
1890
+ const {
1891
+ pkgList: lockPkgs,
1892
+ dependencies: lockDeps,
1893
+ rootInputs,
1894
+ } = parseFlakeLock(flakeLockFile);
1895
+ if (lockPkgs?.length) {
1896
+ const mergedPkgs = [];
1897
+ const existingNames = new Set();
1898
+
1899
+ for (const lockPkg of lockPkgs) {
1900
+ mergedPkgs.push(lockPkg);
1901
+ existingNames.add(lockPkg.name);
1902
+ }
1903
+
1904
+ for (const nixPkg of pkgList) {
1905
+ if (!existingNames.has(nixPkg.name)) {
1906
+ mergedPkgs.push(nixPkg);
1907
+ }
1908
+ }
1909
+
1910
+ pkgList = mergedPkgs;
1911
+ }
1912
+ if (lockDeps?.length) {
1913
+ dependencies = dependencies.concat(lockDeps);
1914
+ }
1915
+
1916
+ // Create parent component from flake.lock if found
1917
+ if (!Object.keys(parentComponent).length) {
1918
+ const flakeDir = dirname(flakeLockFile);
1919
+ const projectName = basename(flakeDir);
1920
+ parentComponent = {
1921
+ type: "application",
1922
+ name: projectName,
1923
+ version: "latest",
1924
+ description: `Nix flake project: ${projectName}`,
1925
+ "bom-ref": nixBomRef(projectName),
1926
+ properties: [
1927
+ {
1928
+ name: "internal:SrcFile",
1929
+ value: flakeLockFile,
1930
+ },
1931
+ {
1932
+ name: "cdx:nix:flake_dir",
1933
+ value: flakeDir,
1934
+ },
1935
+ ],
1936
+ };
1937
+ }
1938
+
1939
+ // Build the root dependency edge here, where the parent component's real
1940
+ // bom-ref is known. parseFlakeLock returns the root's direct inputs as
1941
+ // bom-refs rather than synthesising an edge with a guessed (and dangling)
1942
+ // root ref.
1943
+ if (rootInputs?.length && parentComponent?.["bom-ref"]) {
1944
+ dependencies.push({
1945
+ ref: parentComponent["bom-ref"],
1946
+ dependsOn: [...new Set(rootInputs)],
1947
+ });
1948
+ }
1949
+ }
1950
+
1951
+ // If no parent component was created from flake.lock, create one from flake.nix
1952
+ if (!Object.keys(parentComponent).length && flakeNixFiles.length > 0) {
1953
+ const flakeDir = dirname(flakeNixFiles[0]);
1954
+ const projectName = basename(flakeDir);
1955
+ parentComponent = {
1956
+ type: "application",
1957
+ name: projectName,
1958
+ version: "latest",
1959
+ description: `Nix flake project: ${projectName}`,
1960
+ "bom-ref": nixBomRef(projectName),
1961
+ properties: [
1962
+ {
1963
+ name: "internal:SrcFile",
1964
+ value: flakeNixFiles[0],
1965
+ },
1966
+ {
1967
+ name: "cdx:nix:flake_dir",
1968
+ value: flakeDir,
1969
+ },
1970
+ ],
1971
+ };
1972
+ }
1973
+
1974
+ if (pkgList.length || Object.keys(parentComponent).length) {
1975
+ return buildBomNSData(options, pkgList, "nix", {
1976
+ src: path,
1977
+ filename: [...flakeNixFiles, ...flakeLockFiles].join(", "),
1978
+ dependencies,
1979
+ parentComponent,
1980
+ });
1981
+ }
1982
+
1983
+ return {};
1984
+ }
1985
+
1986
+ /**
1987
+ * Function to create bom string for Zig projects.
1988
+ *
1989
+ * Zig moved package management into the build system, so the dependency list
1990
+ * lives in `build.zig.zon` (ZON, not JSON). The resolver walks the full
1991
+ * dependency graph by locating each dependency's manifest through the in-tree
1992
+ * `zig-pkg/` directory or the global cache, producing both a flat component
1993
+ * list and a CycloneDX `dependencies[]` edge list.
1994
+ *
1995
+ * @param {string} path to the project
1996
+ * @param {Object} options Parse options from the cli
1997
+ * @returns {Promise<Object>} Promise resolving to BOM object
1998
+ */
1999
+ export async function createZigBom(path, options) {
2000
+ const pkgList = [];
2001
+ const seenRefs = new Set();
2002
+ let parentComponent = {};
2003
+ let dependencies = [];
2004
+
2005
+ const zonFiles = getAllFiles(
2006
+ path,
2007
+ `${options.multiProject ? "**/" : ""}build.zig.zon`,
2008
+ options,
2009
+ ).filter((f) => !/[\\/]zig-pkg[\\/]/.test(f));
2010
+
2011
+ // Vendored manifests under zig-pkg/ describe dependencies, not projects. The
2012
+ // resolver reaches them through their hash, so treating one as a root would
2013
+ // duplicate the component and invent a second parent component.
2014
+ for (const zonFile of zonFiles) {
2015
+ if (DEBUG_MODE) {
2016
+ console.log(`Parsing ${zonFile}`);
2017
+ }
2018
+ const {
2019
+ pkgList: resolvedPkgs,
2020
+ dependencies: resolvedDeps,
2021
+ parentComponent: zonParent,
2022
+ unresolvedCount,
2023
+ } = await resolveZigGraph(zonFile, path, options);
2024
+ // Each root manifest is resolved independently, so a dependency shared by
2025
+ // two workspace members arrives twice. Both the component and its edges
2026
+ // are keyed on bom-ref, so merging on that key is what keeps a
2027
+ // multi-project scan from emitting duplicates.
2028
+ for (const pkg of resolvedPkgs || []) {
2029
+ if (!seenRefs.has(pkg["bom-ref"])) {
2030
+ seenRefs.add(pkg["bom-ref"]);
2031
+ pkgList.push(pkg);
2032
+ }
2033
+ }
2034
+ if (resolvedDeps?.length) {
2035
+ dependencies = mergeDependencies(dependencies, resolvedDeps);
2036
+ }
2037
+ if (!Object.keys(parentComponent).length && Object.keys(zonParent).length) {
2038
+ parentComponent = zonParent;
2039
+ }
2040
+ if (unresolvedCount && DEBUG_MODE) {
2041
+ console.log(
2042
+ `${unresolvedCount} Zig package hash(es) could not be resolved — dependency graph may be partial.`,
2043
+ );
2044
+ }
2045
+ }
2046
+
2047
+ if (pkgList.length || Object.keys(parentComponent).length) {
2048
+ return buildBomNSData(options, pkgList, "zig", {
2049
+ src: path,
2050
+ filename: zonFiles.join(", "),
2051
+ parentComponent,
2052
+ dependencies,
2053
+ });
2054
+ }
2055
+
2056
+ return {};
2057
+ }
2058
+
2059
+ /**
2060
+ * Function to create bom string for Gleam projects.
2061
+ *
2062
+ * Gleam resolves through Hex, so packages carry `pkg:hex/...` purls and no new
2063
+ * purl type is introduced. The `manifest.toml` lock is the source of truth for
2064
+ * resolved versions and the direct/transitive distinction; `gleam.toml` is the
2065
+ * manifest.
2066
+ *
2067
+ * @param {string} path to the project
2068
+ * @param {Object} options Parse options from the cli
2069
+ * @returns {Promise<Object>} Promise resolving to BOM object
2070
+ */
2071
+ export async function createGleamBom(path, options) {
2072
+ let pkgList = [];
2073
+ let dependencies = [];
2074
+ let parentComponent = {};
2075
+
2076
+ const gleamTomlFiles = getAllFiles(
2077
+ path,
2078
+ `${options.multiProject ? "**/" : ""}gleam.toml`,
2079
+ options,
2080
+ );
2081
+
2082
+ for (const gleamTomlFile of gleamTomlFiles) {
2083
+ if (DEBUG_MODE) {
2084
+ console.log(`Parsing ${gleamTomlFile}`);
2085
+ }
2086
+ const baseDir = dirname(gleamTomlFile);
2087
+ const manifestTomlFile = join(baseDir, "manifest.toml");
2088
+ const lockPath = safeExistsSync(manifestTomlFile)
2089
+ ? manifestTomlFile
2090
+ : undefined;
2091
+ const result = parseGleamProject(gleamTomlFile, lockPath);
2092
+ if (result.pkgList?.length) {
2093
+ pkgList = pkgList.concat(result.pkgList);
2094
+ }
2095
+ if (result.dependencies?.length) {
2096
+ dependencies = dependencies.concat(result.dependencies);
2097
+ }
2098
+ if (
2099
+ !Object.keys(parentComponent).length &&
2100
+ Object.keys(result.parentComponent).length
2101
+ ) {
2102
+ parentComponent = result.parentComponent;
2103
+ // Attach the root dependency edge to the real parent bom-ref.
2104
+ if (result.rootInputs?.length && parentComponent.name) {
2105
+ const rootRef = `application:${parentComponent.name}:${parentComponent.version || "latest"}`;
2106
+ parentComponent["bom-ref"] = rootRef;
2107
+ dependencies.push({
2108
+ ref: rootRef,
2109
+ dependsOn: [...new Set(result.rootInputs)],
2110
+ });
2111
+ }
2112
+ }
2113
+ }
2114
+
2115
+ if (pkgList.length || Object.keys(parentComponent).length) {
2116
+ return buildBomNSData(options, pkgList, "gleam", {
2117
+ src: path,
2118
+ filename: gleamTomlFiles.join(", "),
2119
+ dependencies,
2120
+ parentComponent,
2121
+ });
2122
+ }
2123
+
2124
+ return {};
2125
+ }