@cdxgen/cdxgen 0.0.1 → 13.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (722) hide show
  1. package/README.md +921 -87
  2. package/bin/audit.js +239 -0
  3. package/bin/cdxgen.js +2324 -0
  4. package/bin/convert.js +213 -0
  5. package/bin/evinse.js +353 -0
  6. package/bin/hbom.js +495 -0
  7. package/bin/repl.js +2224 -0
  8. package/bin/sign.js +195 -0
  9. package/bin/tracebom.js +295 -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 +1833 -0
  85. package/lib/cli/cliOptions.js +513 -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 +142 -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 +876 -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 +575 -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 +1789 -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 +277 -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 +263 -0
  215. package/lib/inventory/traceRunner.js +439 -0
  216. package/lib/inventory/unicodeScan.js +147 -0
  217. package/lib/managers/binary.js +3307 -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 +315 -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 +28 -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 +120 -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 +19 -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 +76 -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,1833 @@
1
+ import { Buffer } from "node:buffer";
2
+ import { randomUUID as uuidv4 } from "node:crypto";
3
+ import { lstatSync, readFileSync } from "node:fs";
4
+ import { basename, dirname, join, relative, resolve, sep } from "node:path";
5
+
6
+ import { build, Purl } from "@cdxgen/cdx-purl";
7
+ import { parse } from "ssri";
8
+
9
+ import {
10
+ DEBUG_MODE,
11
+ recordActivity,
12
+ resetActivityContext,
13
+ setActivityContext,
14
+ } from "../core/activity.js";
15
+ import { PROJECT_TYPE_ALIASES } from "../core/env.js";
16
+ import {
17
+ getTimestamp,
18
+ getTmpDir,
19
+ safeExistsSync,
20
+ safeMkdtempSync,
21
+ } from "../core/fs.js";
22
+ import {
23
+ CDXGEN_TOOL_GROUP,
24
+ CDXGEN_TOOL_NAME,
25
+ CDXGEN_VERSION,
26
+ frameworksList,
27
+ } from "../core/state.js";
28
+ import { isPkgTypeOnlyImport } from "../ecosystems/npmutils.js";
29
+ import { parsePackageJsonName } from "../ecosystems/parsers-js.js";
30
+ import {
31
+ AI_INSTRUCTION_FILE_KINDS,
32
+ AI_INVENTORY_PROJECT_TYPES,
33
+ AI_SKILL_FILE_KIND,
34
+ inventoryPropertyValue,
35
+ MCP_CONFIG_FILE_KIND,
36
+ optionIncludesAiInventoryProjectType,
37
+ summarizeAiInventory,
38
+ } from "../inventory/aiInventory.js";
39
+ import { expandBomAuditCategories } from "../inventory/auditCategories.js";
40
+ import {
41
+ DEFAULT_CDX_SPEC_VERSION,
42
+ setCycloneDxFormat,
43
+ toCycloneDxSpecVersionString,
44
+ } from "../inventory/bomUtils.js";
45
+ import { mergeServices, trimComponents } from "../inventory/depsUtils.js";
46
+ import {
47
+ attachIdentityTools,
48
+ extractToolRefs,
49
+ } from "../inventory/evidenceUtils.js";
50
+ import { enrichComponentWithMcpMetadata } from "../inventory/mcp.js";
51
+ import {
52
+ applyPurl,
53
+ encodeForPurl,
54
+ isValidPurl,
55
+ npmPurl,
56
+ tryBuildPurl,
57
+ } from "../inventory/purl.js";
58
+ import { repairPurl } from "../inventory/sbomDocument.js";
59
+ import { getLicenses } from "../inventory/spdx.js";
60
+ import { getBinaryBom } from "../managers/binary.js";
61
+ import { isValidIriReference } from "../parsers/iri.js";
62
+
63
+ /**
64
+ * Determines whether the `node_modules` directory should be scanned for the
65
+ * current run. Scanning is always performed in deep mode or when no project
66
+ * type is selected; otherwise the selected types must include at least one of
67
+ * the requested base project types.
68
+ *
69
+ * @param {object} options CLI options
70
+ * @param {string[]} baseProjectTypes Base project types that require the scan
71
+ * @returns {boolean} True when `node_modules` should be included in the scan
72
+ */
73
+ export const shouldIncludeNodeModulesDir = (
74
+ options = {},
75
+ baseProjectTypes = [],
76
+ ) => {
77
+ if (options.deep) {
78
+ return true;
79
+ }
80
+ const projectTypes = Array.isArray(options.projectType)
81
+ ? options.projectType
82
+ : options.projectType
83
+ ? [options.projectType]
84
+ : [];
85
+ if (!projectTypes.length) {
86
+ return true;
87
+ }
88
+ return baseProjectTypes.some((projectType) =>
89
+ projectTypes.every((selectedProjectType) =>
90
+ PROJECT_TYPE_ALIASES[projectType]?.includes(selectedProjectType),
91
+ ),
92
+ );
93
+ };
94
+
95
+ /**
96
+ * Regex source string that matches hex digests of common lengths
97
+ * (32, 40, 64, 96, or 128 characters) used for integrity validation.
98
+ *
99
+ * @type {string}
100
+ */
101
+ export const HASH_PATTERN =
102
+ "^([a-fA-F0-9]{32}|[a-fA-F0-9]{40}|[a-fA-F0-9]{64}|[a-fA-F0-9]{96}|[a-fA-F0-9]{128})$";
103
+
104
+ /**
105
+ * Creates a default parent component based on the directory name.
106
+ *
107
+ * @param {String} path Directory or file name
108
+ * @param {String} type Package type
109
+ * @param {Object} options CLI options
110
+ * @returns component object
111
+ */
112
+ export const createDefaultParentComponent = (
113
+ path,
114
+ type = "application",
115
+ options = {},
116
+ ) => {
117
+ // Expands any relative path such as dot
118
+ path = resolve(path);
119
+ // Create a parent component based on the directory name
120
+ let dirNameStr =
121
+ safeExistsSync(path) && lstatSync(path).isDirectory()
122
+ ? basename(path)
123
+ : dirname(path);
124
+ const tmpA = dirNameStr.split(sep);
125
+ dirNameStr = tmpA[tmpA.length - 1];
126
+ const compName = "project-name" in options ? options.projectName : dirNameStr;
127
+ const parentComponent = {
128
+ group: options.projectGroup || "",
129
+ name: compName,
130
+ version: `${options.projectVersion || "latest"}`,
131
+ type:
132
+ type === "container" || compName.endsWith(".tar")
133
+ ? "container"
134
+ : "application",
135
+ };
136
+ // Strict purl validation (swift requires a namespace, maven a groupId)
137
+ // rejects root application components that have no group. applyPurl then
138
+ // omits the purl rather than inventing one, and derives a unique bom-ref.
139
+ applyPurl(
140
+ parentComponent,
141
+ tryBuildPurl({
142
+ type: type,
143
+ namespace: parentComponent.group || null,
144
+ name: parentComponent.name,
145
+ version: parentComponent.version || null,
146
+ }),
147
+ );
148
+ return parentComponent;
149
+ };
150
+
151
+ /**
152
+ * Builds the parent (metadata.component) for the BOM from the
153
+ * `--project-name`/`--project-version`/`--project-group` CLI options,
154
+ * constructing a purl and bom-ref. Returns the caller-supplied
155
+ * `options.parentComponent` unchanged when present.
156
+ *
157
+ * @param {object} options CLI options
158
+ * @returns {object|undefined} Parent component object, or undefined when no
159
+ * project name/version is available
160
+ */
161
+ export const determineParentComponent = (options) => {
162
+ let parentComponent;
163
+ if (options.parentComponent && Object.keys(options.parentComponent).length) {
164
+ return options.parentComponent;
165
+ }
166
+ if (options.projectName && options.projectVersion) {
167
+ parentComponent = {
168
+ group: options.projectGroup || "",
169
+ name: options.projectName,
170
+ version: `${options.projectVersion}` || "",
171
+ type: "application",
172
+ };
173
+ const ppurl = build({
174
+ type: parentComponent.type,
175
+ namespace: parentComponent.group || null,
176
+ name: parentComponent.name,
177
+ version: parentComponent.version || null,
178
+ });
179
+ parentComponent["bom-ref"] = decodeURIComponent(ppurl);
180
+ parentComponent["purl"] = ppurl;
181
+ }
182
+ return parentComponent;
183
+ };
184
+
185
+ /**
186
+ * Re-anchor a dependency graph onto a caller-supplied parent component.
187
+ *
188
+ * A generator builds its `dependencies[]` around the parent it detected from
189
+ * the manifest it read. `--project-name`/`--project-version` and an explicit
190
+ * `parentComponent` replace that parent in `metadata.component`, which leaves
191
+ * the graph rooted at a `bom-ref` that appears nowhere in the document — every
192
+ * edge the generator produced hangs off a dangling ref.
193
+ *
194
+ * The detected parent is real: it is the project the manifest describes, and
195
+ * the supplied parent is the larger thing that contains it. So it is kept as a
196
+ * component and an edge is drawn from the supplied parent to it, which is the
197
+ * CycloneDX way to express a subproject and preserves every edge below it.
198
+ *
199
+ * @param {object|undefined} overrideParent Parent supplied through the options
200
+ * @param {object|undefined} detectedParent Parent the generator derived
201
+ * @param {object[]} components The component list, appended to in place
202
+ * @param {object[]} dependencies Edges the generator produced
203
+ * @returns {object[]} Edges to emit, re-anchored when an override applies
204
+ */
205
+ function anchorDetectedParent(
206
+ overrideParent,
207
+ detectedParent,
208
+ components,
209
+ dependencies,
210
+ ) {
211
+ const detectedRef = detectedParent?.["bom-ref"];
212
+ const overrideRef = overrideParent?.["bom-ref"];
213
+ if (!detectedRef || !overrideRef || detectedRef === overrideRef) {
214
+ return dependencies;
215
+ }
216
+ if (!dependencies.some((dep) => dep.ref === detectedRef)) {
217
+ return dependencies;
218
+ }
219
+ if (
220
+ Array.isArray(components) &&
221
+ !components.some((comp) => comp["bom-ref"] === detectedRef)
222
+ ) {
223
+ components.push({ ...detectedParent });
224
+ }
225
+ // The caller owns the array it passed, and postProcess merges these edges
226
+ // across generators, so the re-anchoring is returned rather than spliced in.
227
+ const anchored = [];
228
+ let linked = false;
229
+ for (const dep of dependencies) {
230
+ if (dep.ref !== overrideRef) {
231
+ anchored.push(dep);
232
+ continue;
233
+ }
234
+ linked = true;
235
+ anchored.push({
236
+ ...dep,
237
+ dependsOn: Array.from(new Set([...(dep.dependsOn || []), detectedRef])),
238
+ });
239
+ }
240
+ if (!linked) {
241
+ anchored.unshift({ ref: overrideRef, dependsOn: [detectedRef] });
242
+ }
243
+ return anchored;
244
+ }
245
+
246
+ /**
247
+ * Assembles the `metadata.tools` block, including the cdxgen tool entry and,
248
+ * for spec versions prior to 1.5, the legacy tools array. For spec version
249
+ * 1.6+ the author field is converted to the authors array.
250
+ *
251
+ * @param {object} options CLI options
252
+ * @param {object} [context={}] Additional context carrying existing components
253
+ * @returns {{ components?: object[], tools?: object[] }} Object containing the
254
+ * tools array (1.4) or a components array with tool components (1.5+)
255
+ */
256
+ export const addToolsSection = (options, context = {}) => {
257
+ if (options.specVersion === 1.4) {
258
+ return [
259
+ {
260
+ vendor: "cyclonedx",
261
+ name: "cdxgen",
262
+ version: CDXGEN_VERSION,
263
+ },
264
+ ];
265
+ }
266
+ let components = [];
267
+ const tools = options.tools || context.tools || [];
268
+ // tools can be an object or array
269
+ if (Array.isArray(tools) && tools.length) {
270
+ // cyclonedx-maven-plugin has the legacy tools metadata which needs to be patched
271
+ for (const tool of tools) {
272
+ if (!tool.type) {
273
+ tool.type = "application";
274
+ if (tool.vendor) {
275
+ tool.publisher = tool.vendor;
276
+ delete tool.vendor;
277
+ }
278
+ }
279
+ }
280
+ components = components.concat(tools);
281
+ } else if (tools && Object.keys(tools).length && tools.components) {
282
+ components = components.concat(tools.components);
283
+ }
284
+ const cdxToolComponent = {
285
+ group: CDXGEN_TOOL_GROUP,
286
+ name: CDXGEN_TOOL_NAME,
287
+ version: CDXGEN_VERSION,
288
+ purl: npmPurl(`${CDXGEN_TOOL_GROUP}/${CDXGEN_TOOL_NAME}`, CDXGEN_VERSION),
289
+ type: "application",
290
+ "bom-ref": `pkg:npm/${CDXGEN_TOOL_GROUP}/${CDXGEN_TOOL_NAME}@${CDXGEN_VERSION}`,
291
+ author: "OWASP Foundation",
292
+ publisher: "OWASP Foundation",
293
+ };
294
+ if (options.specVersion >= 1.6) {
295
+ cdxToolComponent.authors = [{ name: "OWASP Foundation" }];
296
+ delete cdxToolComponent.author;
297
+ }
298
+ components.push(cdxToolComponent);
299
+ return { components };
300
+ };
301
+
302
+ /**
303
+ * Renders a component's group/name@version as a simple display string.
304
+ *
305
+ * @param {object} comp Component object
306
+ * @returns {string} `group/name@version`, `name@version`, or `name`
307
+ */
308
+ export const componentToSimpleFullName = (comp) => {
309
+ let fullName = comp.group?.length ? `${comp.group}/${comp.name}` : comp.name;
310
+ if (comp.version?.length) {
311
+ fullName = `${fullName}@${comp.version}`;
312
+ }
313
+ return fullName;
314
+ };
315
+
316
+ /**
317
+ * Strips transient keys (`evidence`, `_integrity`, `license`, `qualifiers`,
318
+ * `repository`, `homepage`) from a parent component while preserving licenses
319
+ * and external references (bug #1519).
320
+ *
321
+ * @param {object} comp Parent component to clean in place
322
+ * @returns {object} The cleaned parent component
323
+ */
324
+ // Remove unwanted properties from parent component
325
+ // Bug #1519 - Retain licenses and external references
326
+ export const cleanParentComponent = (comp) => {
327
+ delete comp.evidence;
328
+ delete comp._integrity;
329
+ if (comp.license) {
330
+ const licenses = getLicenses(comp);
331
+ if (licenses?.length) {
332
+ comp.licenses = licenses;
333
+ }
334
+ }
335
+ delete comp.license;
336
+ delete comp.qualifiers;
337
+ if (comp.repository || comp.homepage) {
338
+ const externalReferences = addExternalReferences(comp);
339
+ if (externalReferences?.length) {
340
+ comp.externalReferences = externalReferences;
341
+ }
342
+ }
343
+ delete comp.repository;
344
+ delete comp.homepage;
345
+ return comp;
346
+ };
347
+
348
+ /**
349
+ * Builds the `metadata.authors` array from `options.author`, which may be a
350
+ * single string or an array of author strings. Entries shorter than two
351
+ * characters are ignored.
352
+ *
353
+ * @param {object} options CLI options
354
+ * @returns {object[]} Author objects of the form `{ name }`
355
+ */
356
+ export const addAuthorsSection = (options) => {
357
+ const authors = [];
358
+ if (options.author) {
359
+ const oauthors = Array.isArray(options.author)
360
+ ? options.author
361
+ : [options.author];
362
+ for (const aauthor of oauthors) {
363
+ if (aauthor.trim().length < 2) {
364
+ continue;
365
+ }
366
+ authors.push({ name: aauthor });
367
+ }
368
+ }
369
+ return authors;
370
+ };
371
+
372
+ /**
373
+ * Method to generate metadata.lifecycles section. We assume that we operate during "build"
374
+ * most of the time and under "post-build" for containers.
375
+ *
376
+ * @param {Object} options
377
+ * @returns {Array} Lifecycles array
378
+ */
379
+ export const addLifecyclesSection = (options) => {
380
+ // If lifecycle was set via CLI arguments, reuse the value
381
+ if (options.lifecycle) {
382
+ return [{ phase: options.lifecycle }];
383
+ }
384
+ const lifecycles = [{ phase: options.installDeps ? "build" : "pre-build" }];
385
+ if (options.exportData) {
386
+ const inspectData = options.exportData.inspectData;
387
+ if (inspectData) {
388
+ lifecycles.push({ phase: "post-build" });
389
+ }
390
+ } else if (
391
+ options?.projectType?.length &&
392
+ options?.projectType?.includes("binary")
393
+ ) {
394
+ lifecycles.push({ phase: "post-build" });
395
+ }
396
+ if (options.projectType?.includes("os")) {
397
+ lifecycles.push({ phase: "operations" });
398
+ }
399
+ return lifecycles;
400
+ };
401
+
402
+ /**
403
+ * Function to create metadata block
404
+ *
405
+ */
406
+ export function addMetadata(parentComponent = {}, options = {}, context = {}) {
407
+ // DO NOT fork this project to just change the vendor or author's name
408
+ // Try to contribute to this project by sending PR or filing issues
409
+ const tools = addToolsSection(options, context);
410
+ const authors = addAuthorsSection(options);
411
+ const lifecycles =
412
+ options.specVersion >= 1.5 ? addLifecyclesSection(options) : undefined;
413
+ const metadata = {
414
+ timestamp: getTimestamp(),
415
+ tools,
416
+ authors,
417
+ supplier: undefined,
418
+ };
419
+ if (lifecycles) {
420
+ metadata.lifecycles = lifecycles;
421
+ }
422
+ // TLP classification
423
+ if (options.specVersion >= 1.7 && options?.tlpClassification) {
424
+ metadata.distributionConstraints = { tlp: options.tlpClassification };
425
+ }
426
+ if (parentComponent && Object.keys(parentComponent).length) {
427
+ if (parentComponent) {
428
+ cleanParentComponent(parentComponent);
429
+ // Recover a purl from the bom-ref only when the bom-ref genuinely is
430
+ // one. Parsers that cannot build a valid purl (a swift package with no
431
+ // remote URL, a maven module with no groupId) deliberately fall back to a
432
+ // name-based bom-ref, and blindly copying that here manufactured invalid
433
+ // purls such as `"purl": "swift-smoke"`. CycloneDX requires `purl` to be
434
+ // a valid Package URL when present, so absent is the only correct answer.
435
+ if (!parentComponent["purl"] && parentComponent["bom-ref"]) {
436
+ const candidate = encodeForPurl(parentComponent["bom-ref"]);
437
+ if (isValidPurl(candidate)) {
438
+ parentComponent["purl"] = candidate;
439
+ }
440
+ }
441
+ }
442
+ if (parentComponent?.components) {
443
+ parentComponent.components = listComponents(
444
+ options,
445
+ {},
446
+ parentComponent.components,
447
+ );
448
+ const parentFullName = componentToSimpleFullName(parentComponent);
449
+ const subComponents = [];
450
+ const addedSubComponents = {};
451
+ for (const comp of parentComponent.components) {
452
+ cleanParentComponent(comp);
453
+ if (comp.name && comp.type) {
454
+ const fullName = componentToSimpleFullName(comp);
455
+ // Fixes #479
456
+ // Prevent the parent component from also appearing as a sub-component
457
+ // We cannot use purl or bom-ref here since they would not match
458
+ // purl - could have application on one side and a different type
459
+ // bom-ref could have qualifiers on one side
460
+ if (fullName !== parentFullName) {
461
+ if (!comp["bom-ref"]) {
462
+ comp["bom-ref"] = `pkg:${comp.type}/${decodeURIComponent(
463
+ fullName,
464
+ )}`;
465
+ }
466
+ if (!addedSubComponents[comp["bom-ref"]]) {
467
+ subComponents.push(comp);
468
+ addedSubComponents[comp["bom-ref"]] = true;
469
+ }
470
+ }
471
+ }
472
+ } // for
473
+ // Avoid creating empty component.components attribute
474
+ if (subComponents.length) {
475
+ parentComponent.components = subComponents;
476
+ } else {
477
+ parentComponent.components = undefined;
478
+ }
479
+ }
480
+ // Convert authors to author for specVersion < 1.6
481
+ const parentComponentCopy = { ...parentComponent };
482
+
483
+ if (options.specVersion < 1.6 && parentComponent?.authors) {
484
+ parentComponentCopy.author = parentComponentCopy.authors
485
+ .map((a) => (a.email ? `${a.name} <${a.email}>` : a.name))
486
+ .join(",");
487
+ delete parentComponentCopy.authors;
488
+ }
489
+
490
+ metadata.component = parentComponent;
491
+ }
492
+ // Have we already captured the oci properties
493
+ if (metadata?.properties?.some((prop) => prop.name === "oci:image:Id")) {
494
+ return metadata;
495
+ }
496
+ if (options) {
497
+ const mproperties = [];
498
+ if (options.exportData) {
499
+ const inspectData = options.exportData.inspectData;
500
+ if (inspectData) {
501
+ if (inspectData.Id) {
502
+ mproperties.push({
503
+ name: "oci:image:Id",
504
+ value: inspectData.Id,
505
+ });
506
+ }
507
+ if (
508
+ inspectData.RepoTags &&
509
+ Array.isArray(inspectData.RepoTags) &&
510
+ inspectData.RepoTags.length
511
+ ) {
512
+ mproperties.push({
513
+ name: "oci:image:RepoTag",
514
+ value: inspectData.RepoTags[0],
515
+ });
516
+ }
517
+ if (
518
+ inspectData.RepoDigests &&
519
+ Array.isArray(inspectData.RepoDigests) &&
520
+ inspectData.RepoDigests.length
521
+ ) {
522
+ mproperties.push({
523
+ name: "oci:image:RepoDigest",
524
+ value: inspectData.RepoDigests[0],
525
+ });
526
+ }
527
+ if (inspectData.Created) {
528
+ mproperties.push({
529
+ name: "oci:image:Created",
530
+ value: inspectData.Created,
531
+ });
532
+ }
533
+ if (inspectData.Architecture) {
534
+ mproperties.push({
535
+ name: "oci:image:Architecture",
536
+ value: inspectData.Architecture,
537
+ });
538
+ }
539
+ if (inspectData.Os) {
540
+ mproperties.push({
541
+ name: "oci:image:Os",
542
+ value: inspectData.Os,
543
+ });
544
+ }
545
+ }
546
+ const manifestList = options.exportData.manifest;
547
+ if (manifestList && Array.isArray(manifestList) && manifestList.length) {
548
+ const manifest = manifestList[0] || {};
549
+ if (manifest.Config) {
550
+ mproperties.push({
551
+ name: "oci:image:manifest:Config",
552
+ value: manifest.Config,
553
+ });
554
+ }
555
+ if (
556
+ manifest.Layers &&
557
+ Array.isArray(manifest.Layers) &&
558
+ manifest.Layers.length
559
+ ) {
560
+ mproperties.push({
561
+ name: "oci:image:manifest:Layers",
562
+ value: manifest.Layers.join("\\n"),
563
+ });
564
+ }
565
+ }
566
+ const lastLayerConfig = options.exportData.lastLayerConfig;
567
+ if (lastLayerConfig) {
568
+ if (lastLayerConfig.id) {
569
+ mproperties.push({
570
+ name: "oci:image:lastLayer:Id",
571
+ value: lastLayerConfig.id,
572
+ });
573
+ }
574
+ if (lastLayerConfig.parent) {
575
+ mproperties.push({
576
+ name: "oci:image:lastLayer:ParentId",
577
+ value: lastLayerConfig.parent,
578
+ });
579
+ }
580
+ if (lastLayerConfig.created) {
581
+ mproperties.push({
582
+ name: "oci:image:lastLayer:Created",
583
+ value: lastLayerConfig.created,
584
+ });
585
+ }
586
+ }
587
+ const layerConfig =
588
+ lastLayerConfig?.config || options.exportData?.inspectData;
589
+ if (layerConfig) {
590
+ const env = layerConfig?.config?.Env || layerConfig?.Config?.Env;
591
+ if (env && Array.isArray(env) && env.length) {
592
+ mproperties.push({
593
+ name: "oci:image:lastLayer:Env",
594
+ value: env.join("\\n"),
595
+ });
596
+ // Does the image have any special packages that cdxgen cannot detect such as android-sdk and sdkman
597
+ const evalue = env.join(":");
598
+ if (
599
+ evalue.includes("android-sdk") ||
600
+ evalue.includes("commandlinetools")
601
+ ) {
602
+ mproperties.push({
603
+ name: "oci:image:bundles:AndroidSdk",
604
+ value: "true",
605
+ });
606
+ }
607
+ // Track the use of special environment variables that could influence the search paths for libraries
608
+ // This list was generated by repeatedly prompting ChatGPT with examples.
609
+ // FIXME: Move these to a config file
610
+ for (const senvValue of [
611
+ "LD_LIBRARY_PATH",
612
+ "DYLD_LIBRARY_PATH",
613
+ "LD_PRELOAD",
614
+ "PYTHONPATH",
615
+ "CLASSPATH",
616
+ "PERL5LIB",
617
+ "PERLLIB",
618
+ "RUBYLIB",
619
+ "NODE_PATH",
620
+ "LUA_PATH",
621
+ "JULIA_LOAD_PATH",
622
+ "R_LIBS",
623
+ "R_LIBS_USER",
624
+ "GEM_PATH",
625
+ "DOTNET_ROOT",
626
+ "DOTNET_ADDITIONAL_DEPS",
627
+ "DOTNET_SHARED_STORE",
628
+ "DOTNET_STARTUP_HOOKS",
629
+ "DOTNET_BUNDLE_EXTRACT_BASE_DIR",
630
+ "JAVA_OPTIONS",
631
+ "JAVA_TOOL_OPTIONS",
632
+ "NODE_OPTIONS",
633
+ "PYTHONSTARTUP",
634
+ "RUBYOPT",
635
+ "WGETRC",
636
+ "APT_CONFIG",
637
+ "NPM_CONFIG_PREFIX",
638
+ "NPM_CONFIG_REGISTRY",
639
+ "YARN_CACHE_FOLDER",
640
+ "PNPM_STORE_PATH",
641
+ "PNPM_HOME",
642
+ "PNPM_CONFIG_",
643
+ "GIO_MODULE_DIR",
644
+ "GST_PLUGIN_PATH",
645
+ "GST_PLUGIN_SYSTEM_PATH",
646
+ "APPDIR_LIBRARY_PATH", // appimage specific which gets prepended to LD_LIBRARY_PATH
647
+ ]) {
648
+ if (evalue.includes(senvValue)) {
649
+ mproperties.push({
650
+ name: `oci:image:env:${senvValue}`,
651
+ value: "true",
652
+ });
653
+ }
654
+ }
655
+ // This value represents a filtered and expanded path
656
+ if (options?.binPaths?.length) {
657
+ mproperties.push({
658
+ name: "oci:image:env:PATH",
659
+ value: options.binPaths.join(":"),
660
+ });
661
+ }
662
+ if (evalue.includes(".sdkman")) {
663
+ mproperties.push({
664
+ name: "oci:image:bundles:Sdkman",
665
+ value: "true",
666
+ });
667
+ }
668
+ if (evalue.includes(".nvm")) {
669
+ mproperties.push({
670
+ name: "oci:image:bundles:Nvm",
671
+ value: "true",
672
+ });
673
+ }
674
+ if (evalue.includes(".rbenv")) {
675
+ mproperties.push({
676
+ name: "oci:image:bundles:Rbenv",
677
+ value: "true",
678
+ });
679
+ }
680
+ }
681
+ const ccmd =
682
+ layerConfig?.config?.Cmd ||
683
+ layerConfig?.Config?.Cmd ||
684
+ layerConfig?.Config?.EntryPoint;
685
+ if (ccmd) {
686
+ if (Array.isArray(ccmd) && ccmd.length) {
687
+ const fullCommand = ccmd.join(" ");
688
+ mproperties.push({
689
+ name: "oci:image:lastLayer:Cmd",
690
+ value: fullCommand,
691
+ });
692
+ let appLanguage;
693
+ // TODO: Move these lists to a config file.
694
+ for (const lang in [
695
+ "java",
696
+ "node",
697
+ "dotnet",
698
+ "python",
699
+ "python3",
700
+ "ruby",
701
+ "php",
702
+ "php7",
703
+ "php8",
704
+ "perl",
705
+ ]) {
706
+ if (fullCommand.includes(`${lang} `)) {
707
+ appLanguage = lang;
708
+ break;
709
+ }
710
+ }
711
+ if (appLanguage) {
712
+ mproperties.push({
713
+ name: "oci:image:appLanguage",
714
+ value: appLanguage,
715
+ });
716
+ }
717
+ } else {
718
+ mproperties.push({
719
+ name: "oci:image:lastLayer:Cmd",
720
+ value: ccmd.toString(),
721
+ });
722
+ }
723
+ }
724
+ }
725
+ }
726
+ if (options.allOSComponentTypes?.length) {
727
+ mproperties.push({
728
+ name: "oci:image:componentTypes",
729
+ value: options.allOSComponentTypes.sort().join("\\n"),
730
+ });
731
+ }
732
+ if (Number.isInteger(options?.unpackagedExecutableCount)) {
733
+ mproperties.push({
734
+ name: "cdx:container:unpackagedExecutableCount",
735
+ value: String(options.unpackagedExecutableCount),
736
+ });
737
+ }
738
+ if (Number.isInteger(options?.unpackagedSharedLibraryCount)) {
739
+ mproperties.push({
740
+ name: "cdx:container:unpackagedSharedLibraryCount",
741
+ value: String(options.unpackagedSharedLibraryCount),
742
+ });
743
+ }
744
+ // Should we move these to formulation?
745
+ if (options?.bundledSdks?.length) {
746
+ for (const sdk of options.bundledSdks) {
747
+ try {
748
+ const purlObj = Purl.parse(sdk);
749
+ const sdkName = purlObj.name.split("-")[0].toLowerCase();
750
+ mproperties.push({
751
+ name: `oci:image:bundles:${sdkName}Sdk`,
752
+ value: "true",
753
+ });
754
+ } catch (_e) {
755
+ // ignore
756
+ }
757
+ }
758
+ }
759
+ if (options?.bundledRuntimes?.length) {
760
+ for (const runt of options.bundledRuntimes) {
761
+ mproperties.push({
762
+ name: `oci:image:bundles:${runt}Runtime`,
763
+ value: "true",
764
+ });
765
+ }
766
+ }
767
+ // AI provenance/oversight detection (`-t ai-provenance`) is injected into the
768
+ // BOM document root (bomJson.properties) after post-processing, not into
769
+ // metadata.properties. See ensureAiProvenanceProperties/ensureAiOversightProperties.
770
+ if (mproperties.length) {
771
+ metadata.properties = mproperties;
772
+ }
773
+ }
774
+ return metadata;
775
+ }
776
+
777
+ /**
778
+ * Method to create external references
779
+ *
780
+ * @param {Array | Object} opkg
781
+ * @returns {Array}
782
+ */
783
+ export function addExternalReferences(opkg) {
784
+ let externalReferences = [];
785
+ let pkgList;
786
+ if (Array.isArray(opkg)) {
787
+ pkgList = opkg;
788
+ } else {
789
+ pkgList = [opkg];
790
+ }
791
+ for (const pkg of pkgList) {
792
+ if (pkg.externalReferences) {
793
+ externalReferences = externalReferences.concat(pkg.externalReferences);
794
+ } else {
795
+ if (pkg.homepage?.url) {
796
+ externalReferences.push({
797
+ type: pkg.homepage.url.includes("git") ? "vcs" : "website",
798
+ url: pkg.homepage.url,
799
+ });
800
+ }
801
+ if (pkg.bugs?.url) {
802
+ externalReferences.push({
803
+ type: "issue-tracker",
804
+ url: pkg.bugs.url,
805
+ });
806
+ }
807
+ if (pkg.repository?.url) {
808
+ externalReferences.push({
809
+ type: "vcs",
810
+ url: pkg.repository.url,
811
+ });
812
+ }
813
+ if (pkg.distribution?.url) {
814
+ externalReferences.push({
815
+ type: "distribution",
816
+ url: pkg.distribution.url,
817
+ });
818
+ }
819
+ }
820
+ }
821
+ return externalReferences
822
+ .map((reference) => ({ ...reference, url: reference.url.trim() }))
823
+ .filter((reference) => isValidIriReference(reference.url));
824
+ }
825
+
826
+ /**
827
+ * For all modules in the specified package, creates a list of
828
+ * component objects from each one.
829
+ *
830
+ * @param {Object} options CLI options
831
+ * @param {Object} allImports All imports
832
+ * @param {Object} pkg Package object
833
+ * @param {string} ptype Package type
834
+ * @returns {Object[]} Array of component objects
835
+ */
836
+ export function listComponents(options, allImports, pkg, ptype = "npm") {
837
+ const compMap = {};
838
+ const isRootPkg = ptype === "npm";
839
+ if (Array.isArray(pkg)) {
840
+ pkg.forEach((p) => {
841
+ addComponent(options, allImports, p, ptype, compMap, false);
842
+ });
843
+ } else {
844
+ addComponent(options, allImports, pkg, ptype, compMap, isRootPkg);
845
+ }
846
+
847
+ return Object.keys(compMap).map((k) => compMap[k]);
848
+ }
849
+
850
+ /**
851
+ * Component types that never receive an ecosystem purl.
852
+ *
853
+ * @type {string[]}
854
+ */
855
+ // These component types do not have PURLs
856
+ export const NON_PURL_TYPES = ["cryptographic-asset", "file", "data"];
857
+
858
+ /**
859
+ * Property-name prefix used to key npm bin-command import evidence
860
+ * (`cdx:npm:bin/`).
861
+ *
862
+ * @type {string}
863
+ */
864
+ export const NPM_BIN_IMPORT_PREFIX = "cdx:npm:bin/";
865
+
866
+ /**
867
+ * Returns all non-empty property values for a given property name on a package.
868
+ *
869
+ * @param {object} pkg Package/component object with an optional `properties` array
870
+ * @param {string} propertyName Property name to match
871
+ * @returns {string[]} Matching property values as strings
872
+ */
873
+ export function getPackagePropertyValues(pkg, propertyName) {
874
+ if (!Array.isArray(pkg?.properties)) {
875
+ return [];
876
+ }
877
+ return pkg.properties
878
+ .filter((property) => property.name === propertyName && property.value)
879
+ .map((property) => String(property.value));
880
+ }
881
+
882
+ /**
883
+ * Splits a comma-separated property value into a trimmed, non-empty string array.
884
+ *
885
+ * @param {string} value Comma-separated value
886
+ * @returns {string[]} Trimmed list entries
887
+ */
888
+ export function splitPackagePropertyList(value) {
889
+ return String(value || "")
890
+ .split(",")
891
+ .map((item) => item.trim())
892
+ .filter(Boolean);
893
+ }
894
+
895
+ /**
896
+ * Collects the set of bin command names an npm package exposes, derived from
897
+ * the `bin` field and the `cdx:npm:bin` / `cdx:npm:binPaths` properties.
898
+ *
899
+ * @param {object} pkg Package object
900
+ * @returns {Set<string>} Bin command names
901
+ */
902
+ export function getPackageBinCommandNames(pkg) {
903
+ const binNames = new Set();
904
+ if (pkg?.bin && typeof pkg.bin === "object") {
905
+ for (const binName of Object.keys(pkg.bin)) {
906
+ binNames.add(binName);
907
+ }
908
+ } else if (typeof pkg?.bin === "string") {
909
+ binNames.add(pkg.name);
910
+ }
911
+ for (const binValue of getPackagePropertyValues(pkg, "cdx:npm:bin")) {
912
+ for (const binName of splitPackagePropertyList(binValue)) {
913
+ binNames.add(binName);
914
+ }
915
+ }
916
+ for (const binPathValue of getPackagePropertyValues(
917
+ pkg,
918
+ "cdx:npm:binPaths",
919
+ )) {
920
+ for (const binPath of splitPackagePropertyList(binPathValue)) {
921
+ const normalizedBinPath = binPath.replaceAll("\\", "/");
922
+ const binName = normalizedBinPath.split("/").filter(Boolean).pop();
923
+ if (binName) {
924
+ binNames.add(binName);
925
+ }
926
+ }
927
+ }
928
+ return binNames;
929
+ }
930
+
931
+ /**
932
+ * Checks whether any bin command of a package appears in the analyzer import
933
+ * evidence (keyed under `cdx:npm:bin/`).
934
+ *
935
+ * @param {object} allImports Map of import names to usage counts
936
+ * @param {object} pkg Package object
937
+ * @returns {boolean} True when at least one bin command is imported
938
+ */
939
+ export function hasNpmBinCommandEvidence(allImports, pkg) {
940
+ const binCommandNames = getPackageBinCommandNames(pkg);
941
+ if (!binCommandNames.size) {
942
+ return false;
943
+ }
944
+ for (const importName of Object.keys(allImports || {})) {
945
+ if (!importName.startsWith(NPM_BIN_IMPORT_PREFIX)) {
946
+ continue;
947
+ }
948
+ const commandName = importName.slice(NPM_BIN_IMPORT_PREFIX.length);
949
+ if (binCommandNames.has(commandName)) {
950
+ return true;
951
+ }
952
+ }
953
+ return false;
954
+ }
955
+
956
+ /**
957
+ * Given the specified package, create a CycloneDX component and add it to the list.
958
+ */
959
+ export function addComponent(
960
+ options,
961
+ allImports,
962
+ pkg,
963
+ ptype,
964
+ compMap,
965
+ isRootPkg = false,
966
+ ) {
967
+ if (!pkg || pkg.extraneous) {
968
+ return;
969
+ }
970
+ if (!isRootPkg) {
971
+ const pkgIdentifier = parsePackageJsonName(pkg.name);
972
+ const author = pkg.author || undefined;
973
+ const authors = pkg.authors || undefined;
974
+ const publisher = pkg.publisher || undefined;
975
+ let group = pkg.group || pkgIdentifier.scope;
976
+ // Create empty group
977
+ group = group || "";
978
+ const name = pkgIdentifier.fullName || pkg.name || "";
979
+ // name is mandatory
980
+ if (!name) {
981
+ return;
982
+ }
983
+ // Do we need this still?
984
+ if (
985
+ !ptype &&
986
+ ["jar", "war", "ear", "pom"].includes(pkg?.qualifiers?.type)
987
+ ) {
988
+ ptype = "maven";
989
+ }
990
+ const version = pkg.version || "";
991
+ const licenses = pkg.licenses || getLicenses(pkg);
992
+ let purl = pkg.purl;
993
+ if (!purl && ptype) {
994
+ try {
995
+ purl = new Purl({
996
+ type: ptype,
997
+ namespace: encodeForPurl(group) || null,
998
+ name: encodeForPurl(name),
999
+ version: version || null,
1000
+ qualifiers: pkg.qualifiers || null,
1001
+ subpath: encodeForPurl(pkg.subpath) || null,
1002
+ });
1003
+ } catch {
1004
+ // purl construction may fail for types requiring a namespace (maven,
1005
+ // swift) when the component has no group; fall through without a purl.
1006
+ }
1007
+ }
1008
+ let purlString = purl?.toString();
1009
+ // These types get no purl derived from the ecosystem being scanned, since a
1010
+ // file or a crypto asset is not a package of that ecosystem. A collector
1011
+ // that set a purl itself — file components carry `pkg:generic/...` — is
1012
+ // taken at its word.
1013
+ if (
1014
+ !pkg.purl &&
1015
+ (NON_PURL_TYPES.includes(ptype) || NON_PURL_TYPES.includes(pkg.type))
1016
+ ) {
1017
+ purl = undefined;
1018
+ purlString = undefined;
1019
+ }
1020
+ // Some applications like github workflow steps and commands do not have purl
1021
+ if (
1022
+ pkg.purl === undefined &&
1023
+ !pkg?.["bom-ref"]?.startsWith("pkg:") &&
1024
+ pkg?.type === "application"
1025
+ ) {
1026
+ purl = undefined;
1027
+ purlString = undefined;
1028
+ }
1029
+ const description = pkg.description || undefined;
1030
+ let compScope = pkg.scope;
1031
+ let isTypeOnlyPkg = false;
1032
+ if (allImports) {
1033
+ const impPkgs = Object.keys(allImports);
1034
+ const hasBinCommandEvidence = hasNpmBinCommandEvidence(allImports, pkg);
1035
+ if (
1036
+ impPkgs.includes(name) ||
1037
+ impPkgs.includes(`${group}/${name}`) ||
1038
+ impPkgs.includes(`@${group}/${name}`) ||
1039
+ (group.length > 0 && impPkgs.includes(group)) ||
1040
+ (group.length > 0 && impPkgs.includes(`@${group}`)) ||
1041
+ hasBinCommandEvidence
1042
+ ) {
1043
+ if (
1044
+ !hasBinCommandEvidence &&
1045
+ isPkgTypeOnlyImport(allImports, group, name)
1046
+ ) {
1047
+ compScope = "excluded";
1048
+ isTypeOnlyPkg = true;
1049
+ } else {
1050
+ compScope = "required";
1051
+ }
1052
+ } else if (impPkgs.length && compScope !== "excluded") {
1053
+ compScope = "optional";
1054
+ }
1055
+ }
1056
+ let component = {
1057
+ author,
1058
+ authors,
1059
+ publisher,
1060
+ group,
1061
+ name,
1062
+ version,
1063
+ description,
1064
+ scope: compScope,
1065
+ hashes: [],
1066
+ licenses,
1067
+ purl: purlString,
1068
+ externalReferences: addExternalReferences(pkg),
1069
+ };
1070
+ if (options.specVersion >= 1.5) {
1071
+ component.pedigree = pkg.pedigree || undefined;
1072
+ }
1073
+ if (options.specVersion >= 1.6) {
1074
+ component.releaseNotes = pkg.releaseNotes || undefined;
1075
+ component.modelCard = pkg.modelCard || undefined;
1076
+ component.data = pkg.data || undefined;
1077
+ }
1078
+ component["type"] = determinePackageType(pkg);
1079
+ if (pkg["bom-ref"]) {
1080
+ component["bom-ref"] = pkg["bom-ref"];
1081
+ } else if (purlString) {
1082
+ component["bom-ref"] = decodeURIComponent(purlString);
1083
+ }
1084
+
1085
+ if (
1086
+ component.externalReferences === undefined ||
1087
+ component.externalReferences.length === 0
1088
+ ) {
1089
+ delete component.externalReferences;
1090
+ }
1091
+ if (options.specVersion < 1.6) {
1092
+ delete component.omniborId;
1093
+ delete component.swhid;
1094
+ }
1095
+ processHashes(pkg, component);
1096
+ // Upgrade authors section
1097
+ if (options.specVersion >= 1.6 && component.author) {
1098
+ const authorsList = [];
1099
+ for (const aauthor of component.author.split(",")) {
1100
+ authorsList.push({ name: aauthor });
1101
+ }
1102
+ component.authors = authorsList;
1103
+ delete component.author;
1104
+ }
1105
+ // Downgrade authors section for < 1.5 :(
1106
+ if (options.specVersion < 1.6) {
1107
+ if (component?.authors?.length) {
1108
+ component.author = component.authors
1109
+ .map((a) => (a.email ? `${a.name} <${a.email}>` : a.name))
1110
+ .join(",");
1111
+ }
1112
+ delete component.authors;
1113
+ }
1114
+ // Downgrade from 1.7
1115
+ if (options.specVersion < 1.7) {
1116
+ if (component.isExternal) {
1117
+ delete component.isExternal;
1118
+ }
1119
+ if (component.versionRange) {
1120
+ console.warn(
1121
+ `Version Range is not supported in ${options.specVersion} specifications. Please run cdxgen with --spec-version 1.7`,
1122
+ );
1123
+ delete component.versionRange;
1124
+ }
1125
+ }
1126
+ // Retain any tags
1127
+ if (
1128
+ options.specVersion >= 1.6 &&
1129
+ pkg.tags &&
1130
+ Object.keys(pkg.tags).length
1131
+ ) {
1132
+ component.tags = pkg.tags;
1133
+ }
1134
+ // Retain any component properties and crypto properties
1135
+ if (pkg.properties?.length) {
1136
+ component.properties = pkg.properties;
1137
+ }
1138
+ if (isTypeOnlyPkg) {
1139
+ component.properties = component.properties || [];
1140
+ if (
1141
+ !component.properties.some(
1142
+ (p) => p.name === "cdx:npm:package:type-only",
1143
+ )
1144
+ ) {
1145
+ component.properties.push({
1146
+ name: "cdx:npm:package:type-only",
1147
+ value: "true",
1148
+ });
1149
+ }
1150
+ }
1151
+ if (pkg.cryptoProperties && typeof pkg.cryptoProperties === "object") {
1152
+ component.cryptoProperties = pkg.cryptoProperties;
1153
+ }
1154
+ // Retain nested components
1155
+ if (pkg.components) {
1156
+ component.components = pkg.components;
1157
+ }
1158
+ component = enrichComponentWithMcpMetadata(component);
1159
+ const compMapKey = component.purl || component["bom-ref"];
1160
+ // Issue: 1353. We need to keep merging the properties
1161
+ if (compMap[compMapKey]) {
1162
+ const mergedComponents = trimComponents([compMap[compMapKey], component]);
1163
+ if (mergedComponents?.length === 1) {
1164
+ component = mergedComponents[0];
1165
+ }
1166
+ }
1167
+ // Retain evidence
1168
+ if (
1169
+ options.specVersion >= 1.5 &&
1170
+ pkg.evidence &&
1171
+ Object.keys(pkg.evidence).length
1172
+ ) {
1173
+ component.evidence = pkg.evidence;
1174
+ // Convert evidence.identity section to an array for 1.6 and above
1175
+ if (
1176
+ options.specVersion >= 1.6 &&
1177
+ pkg.evidence &&
1178
+ pkg.evidence.identity &&
1179
+ !Array.isArray(pkg.evidence.identity)
1180
+ ) {
1181
+ // Automatically add concludedValue
1182
+ if (pkg.evidence.identity?.methods?.length === 1) {
1183
+ pkg.evidence.identity.concludedValue =
1184
+ pkg.evidence.identity.methods[0].value;
1185
+ }
1186
+ component.evidence.identity = [pkg.evidence.identity];
1187
+ }
1188
+ // Convert evidence.identity section to an object for 1.5
1189
+ if (
1190
+ options.specVersion === 1.5 &&
1191
+ pkg.evidence &&
1192
+ pkg.evidence.identity &&
1193
+ Array.isArray(pkg.evidence.identity)
1194
+ ) {
1195
+ component.evidence.identity = pkg.evidence.identity[0];
1196
+ }
1197
+ }
1198
+ compMap[compMapKey] = component;
1199
+ }
1200
+ if (pkg.dependencies) {
1201
+ Object.keys(pkg.dependencies)
1202
+ .map((x) => pkg.dependencies[x])
1203
+ .filter((x) => typeof x !== "string") //remove cycles
1204
+ .map((x) => addComponent(options, allImports, x, ptype, compMap, false));
1205
+ }
1206
+ }
1207
+
1208
+ /**
1209
+ * If the author has described the module as a 'framework', the take their
1210
+ * word for it, otherwise, identify the module as a 'library'.
1211
+ */
1212
+ export function determinePackageType(pkg) {
1213
+ // Retain the exact component type in certain cases.
1214
+ if (
1215
+ [
1216
+ "container",
1217
+ "platform",
1218
+ "operating-system",
1219
+ "device",
1220
+ "device-driver",
1221
+ "firmware",
1222
+ "file",
1223
+ "machine-learning-model",
1224
+ "data",
1225
+ "cryptographic-asset",
1226
+ ].includes(pkg.type)
1227
+ ) {
1228
+ return pkg.type;
1229
+ }
1230
+ if (pkg.type === "application") {
1231
+ if (pkg?.name?.endsWith(".tar")) {
1232
+ return "container";
1233
+ }
1234
+ return pkg.type;
1235
+ }
1236
+ if (pkg.purl) {
1237
+ try {
1238
+ const purl = Purl.parse(pkg.purl);
1239
+ if (purl.type) {
1240
+ if (["docker", "oci", "container"].includes(purl.type)) {
1241
+ return "container";
1242
+ }
1243
+ if (["github"].includes(purl.type)) {
1244
+ return "application";
1245
+ }
1246
+ }
1247
+ // See #1760
1248
+ if (
1249
+ purl.namespace?.startsWith("@types") ||
1250
+ (purl.namespace?.includes("-types") && pkg?.type === "npm")
1251
+ ) {
1252
+ return "library";
1253
+ }
1254
+ for (const cf of frameworksList.all) {
1255
+ if (
1256
+ pkg.purl.startsWith(cf) ||
1257
+ purl.namespace?.includes(cf) ||
1258
+ purl.name.toLowerCase().startsWith(cf)
1259
+ ) {
1260
+ return "framework";
1261
+ }
1262
+ }
1263
+ } catch (_e) {
1264
+ // continue regardless of error
1265
+ }
1266
+ } else if (pkg.group) {
1267
+ if (["actions"].includes(pkg.group)) {
1268
+ return "application";
1269
+ }
1270
+ }
1271
+ if (Object.hasOwn(pkg, "description")) {
1272
+ if (pkg.description?.toLowerCase().includes("framework")) {
1273
+ return "framework";
1274
+ }
1275
+ }
1276
+ if (Object.hasOwn(pkg, "keywords")) {
1277
+ for (const keyword of pkg.keywords) {
1278
+ if (keyword && keyword.toLowerCase() === "framework") {
1279
+ return "framework";
1280
+ }
1281
+ }
1282
+ }
1283
+ if (Object.hasOwn(pkg, "tags")) {
1284
+ for (const tag of pkg.tags) {
1285
+ if (tag && tag.toLowerCase() === "framework") {
1286
+ return "framework";
1287
+ }
1288
+ }
1289
+ }
1290
+ return "library";
1291
+ }
1292
+
1293
+ /**
1294
+ * Uses the SHA1 shasum (if present) otherwise utilizes Subresource Integrity
1295
+ * of the package with support for multiple hashing algorithms.
1296
+ */
1297
+ export function processHashes(pkg, component) {
1298
+ if (pkg.hashes) {
1299
+ // This attribute would be available when we read a bom json directly
1300
+ // Eg: cyclonedx-maven-plugin. See: Bugs: #172, #175
1301
+ for (const ahash of pkg.hashes) {
1302
+ addComponentHash(ahash.alg, ahash.content, component);
1303
+ }
1304
+ } else if (pkg._shasum) {
1305
+ const ahash = { alg: "SHA-1", content: pkg._shasum };
1306
+ component.hashes.push(ahash);
1307
+ } else if (pkg._integrity) {
1308
+ const integrity = parse(pkg._integrity) || {};
1309
+ // Components may have multiple hashes with various lengths. Check each one
1310
+ // that is supported by the CycloneDX specification.
1311
+ if (Object.hasOwn(integrity, "sha512")) {
1312
+ addComponentHash("SHA-512", integrity.sha512[0].digest, component);
1313
+ }
1314
+ if (Object.hasOwn(integrity, "sha384")) {
1315
+ addComponentHash("SHA-384", integrity.sha384[0].digest, component);
1316
+ }
1317
+ if (Object.hasOwn(integrity, "sha256")) {
1318
+ addComponentHash("SHA-256", integrity.sha256[0].digest, component);
1319
+ }
1320
+ if (Object.hasOwn(integrity, "sha1")) {
1321
+ addComponentHash("SHA-1", integrity.sha1[0].digest, component);
1322
+ }
1323
+ }
1324
+ if (component.hashes.length === 0) {
1325
+ delete component.hashes; // If no hashes exist, delete the hashes node (it's optional)
1326
+ }
1327
+ }
1328
+
1329
+ /**
1330
+ * Adds a hash to component.
1331
+ */
1332
+ export function addComponentHash(alg, digest, component) {
1333
+ let hash;
1334
+ // If it is a valid hash simply use it
1335
+ if (new RegExp(HASH_PATTERN).test(digest)) {
1336
+ hash = digest;
1337
+ } else {
1338
+ // Check if base64 encoded
1339
+ const isBase64Encoded =
1340
+ Buffer.from(digest, "base64").toString("base64") === digest;
1341
+ hash = isBase64Encoded
1342
+ ? Buffer.from(digest, "base64").toString("hex")
1343
+ : digest;
1344
+ }
1345
+ const ahash = { alg: alg, content: hash };
1346
+ component.hashes.push(ahash);
1347
+ }
1348
+
1349
+ /**
1350
+ * Return the BOM in json format including any namespace mapping
1351
+ *
1352
+ * @param {Object} options Options
1353
+ * @param {Object} pkgInfo Package information
1354
+ * @param {string} ptype Package type
1355
+ * @param {Object} context Context
1356
+ *
1357
+ * @returns {Object} BOM with namespace mapping
1358
+ */
1359
+ export const buildBomNSData = (options, pkgInfo, ptype, context) => {
1360
+ // Many create*Bom call sites provide only a source directory (`src`) when
1361
+ // there is no single manifest/lock file to report, so activity records must
1362
+ // fall back to that directory to keep the target populated.
1363
+ const sourcePath =
1364
+ context?.srcDir || context?.src || options.path || options.filePath;
1365
+ const activityProjectType =
1366
+ context?.projectType ||
1367
+ (Array.isArray(options.projectType)
1368
+ ? options.projectType.length === 1
1369
+ ? options.projectType[0]
1370
+ : undefined
1371
+ : options.projectType);
1372
+ setActivityContext({
1373
+ packageType: ptype,
1374
+ sourcePath,
1375
+ ...(activityProjectType ? { projectType: activityProjectType } : {}),
1376
+ });
1377
+ const bomNSData = {
1378
+ bomJson: undefined,
1379
+ bomJsonFiles: undefined,
1380
+ nsMapping: undefined,
1381
+ dependencies: undefined,
1382
+ parentComponent: undefined,
1383
+ };
1384
+ const serialNum = `urn:uuid:${uuidv4()}`;
1385
+ let allImports = {};
1386
+ if (context?.allImports) {
1387
+ allImports = context.allImports;
1388
+ }
1389
+ const nsMapping = context.nsMapping || {};
1390
+ const services = context.services || [];
1391
+ const overrideParent = determineParentComponent(options);
1392
+ const parentComponent = overrideParent || context.parentComponent;
1393
+ const metadata = addMetadata(parentComponent, options, context);
1394
+ const components = listComponents(options, allImports, pkgInfo, ptype);
1395
+ const dependencies = anchorDetectedParent(
1396
+ overrideParent,
1397
+ context.parentComponent,
1398
+ components,
1399
+ context.dependencies || [],
1400
+ );
1401
+ if (
1402
+ components &&
1403
+ (components.length ||
1404
+ parentComponent ||
1405
+ options.projectType?.includes("dynamic") ||
1406
+ options.projectType?.includes("ai-provenance"))
1407
+ ) {
1408
+ // CycloneDX Json Template
1409
+ const jsonTpl = {
1410
+ bomFormat: "CycloneDX",
1411
+ specVersion: toCycloneDxSpecVersionString(
1412
+ options.specVersion || DEFAULT_CDX_SPEC_VERSION,
1413
+ ),
1414
+ serialNumber: serialNum,
1415
+ version: 1,
1416
+ metadata: metadata,
1417
+ components,
1418
+ dependencies,
1419
+ };
1420
+ setCycloneDxFormat(jsonTpl, jsonTpl.specVersion, {
1421
+ preserveLegacyBomFormat: true,
1422
+ });
1423
+ if (services.length) {
1424
+ jsonTpl.services = mergeServices([], services);
1425
+ }
1426
+ bomNSData.bomJson = jsonTpl;
1427
+ bomNSData.nsMapping = nsMapping;
1428
+ bomNSData.dependencies = dependencies;
1429
+ bomNSData.parentComponent = parentComponent;
1430
+ // Carry language-specific formulation data (e.g. Pixi) so that
1431
+ // postProcess can merge it when building the final formulation section.
1432
+ if (context?.formulationList?.length) {
1433
+ bomNSData.formulationList = context.formulationList;
1434
+ }
1435
+ // Carry language-specific provenance citations (e.g. PEP 770 embedded
1436
+ // SBOMs) so postProcess can attach them in the single root-level citations
1437
+ // section it builds.
1438
+ if (Array.isArray(context?.citations) && context.citations.length) {
1439
+ bomNSData.citations = context.citations;
1440
+ }
1441
+ }
1442
+ recordActivity({
1443
+ kind: "read",
1444
+ reason: `Collected ${ptype || "generic"} component metadata.`,
1445
+ status: components?.length || parentComponent ? "completed" : "failed",
1446
+ target: context?.filename || sourcePath,
1447
+ });
1448
+ resetActivityContext();
1449
+ return bomNSData;
1450
+ };
1451
+
1452
+ /**
1453
+ * Function to create bom string for Android apps using blint
1454
+ *
1455
+ * @param {string} path to the project
1456
+ * @param {Object} options Parse options from the cli
1457
+ * @returns {Object|undefined} BOM object
1458
+ */
1459
+ export function createAndroidBom(path, options) {
1460
+ return createBinaryBom(path, options);
1461
+ }
1462
+
1463
+ /**
1464
+ * Escape the purls of a blint BOM and carry the change through its graph.
1465
+ *
1466
+ * blint composes purls by string interpolation, so a name holding a character
1467
+ * a purl reserves — `libstdc++.so.6` and its kin — arrives unescaped. blint
1468
+ * also uses the purl as the bom-ref, so every ref that quoted the old string,
1469
+ * in `dependencies` and in the parent component alike, moves with it.
1470
+ *
1471
+ * @param {Object} binaryBom BOM read from blint, rewritten in place
1472
+ */
1473
+ function repairBinaryBomPurls(binaryBom) {
1474
+ const renamed = new Map();
1475
+ const repair = (component) => {
1476
+ const before = component?.purl;
1477
+ if (!before) {
1478
+ return;
1479
+ }
1480
+ repairPurl(component);
1481
+ if (component.purl === before) {
1482
+ return;
1483
+ }
1484
+ renamed.set(before, component.purl);
1485
+ if (component["bom-ref"] === before) {
1486
+ component["bom-ref"] = component.purl;
1487
+ }
1488
+ };
1489
+ for (const component of binaryBom?.components || []) {
1490
+ repair(component);
1491
+ }
1492
+ repair(binaryBom?.parentComponent);
1493
+ repair(binaryBom?.metadata?.component);
1494
+ if (!renamed.size) {
1495
+ return;
1496
+ }
1497
+ const rename = (ref) => renamed.get(ref) || ref;
1498
+ for (const dependency of binaryBom?.dependencies || []) {
1499
+ if (dependency?.ref) {
1500
+ dependency.ref = rename(dependency.ref);
1501
+ }
1502
+ for (const key of ["dependsOn", "provides"]) {
1503
+ if (Array.isArray(dependency?.[key])) {
1504
+ dependency[key] = dependency[key].map(rename);
1505
+ }
1506
+ }
1507
+ }
1508
+ }
1509
+
1510
+ /**
1511
+ * Function to create bom string for binaries using blint
1512
+ *
1513
+ * @param {string} path to the project
1514
+ * @param {Object} options Parse options from the cli
1515
+ * @returns {Object|undefined} BOM object
1516
+ */
1517
+ export function createBinaryBom(path, options) {
1518
+ const tempDir = safeMkdtempSync(join(getTmpDir(), "blint-tmp-"));
1519
+ const binaryBomFile = join(tempDir, "bom.json");
1520
+ getBinaryBom(path, binaryBomFile, options.deep);
1521
+ if (safeExistsSync(binaryBomFile)) {
1522
+ const binaryBom = JSON.parse(
1523
+ readFileSync(binaryBomFile, { encoding: "utf-8" }),
1524
+ );
1525
+ repairBinaryBomPurls(binaryBom);
1526
+ attachIdentityTools(
1527
+ binaryBom?.components,
1528
+ extractToolRefs(
1529
+ binaryBom?.metadata?.tools,
1530
+ (tool) => tool?.name !== "cdxgen",
1531
+ ),
1532
+ );
1533
+ return {
1534
+ bomJson: binaryBom,
1535
+ dependencies: binaryBom.dependencies,
1536
+ parentComponent: binaryBom.parentComponent,
1537
+ };
1538
+ }
1539
+ return undefined;
1540
+ }
1541
+
1542
+ /**
1543
+ * Identify the requested AI inventory project types.
1544
+ *
1545
+ * @param {Object} options Parse options from the cli
1546
+ * @returns {string[]} Requested AI inventory types
1547
+ */
1548
+ export function getRequestedAiInventoryTypes(options) {
1549
+ return AI_INVENTORY_PROJECT_TYPES.filter((type) =>
1550
+ optionIncludesAiInventoryProjectType(options?.projectType, type),
1551
+ );
1552
+ }
1553
+
1554
+ /**
1555
+ * Returns the AI inventory types excluded via `--exclude-type`.
1556
+ *
1557
+ * @param {object} options CLI options
1558
+ * @returns {string[]} Excluded AI inventory types
1559
+ */
1560
+ export function getExcludedAiInventoryTypes(options) {
1561
+ return AI_INVENTORY_PROJECT_TYPES.filter((type) =>
1562
+ optionIncludesAiInventoryProjectType(options?.excludeType, type),
1563
+ );
1564
+ }
1565
+
1566
+ /**
1567
+ * Removes the excluded AI inventory types from the included list.
1568
+ *
1569
+ * @param {string[]} includedAiInventoryTypes Types selected for collection
1570
+ * @param {string[]} excludedAiInventoryTypes Types excluded by the user
1571
+ * @returns {string[]} Filtered list of AI inventory types
1572
+ */
1573
+ export function filterIncludedAiInventoryTypes(
1574
+ includedAiInventoryTypes,
1575
+ excludedAiInventoryTypes,
1576
+ ) {
1577
+ return [...new Set(includedAiInventoryTypes)].filter(
1578
+ (type) => !excludedAiInventoryTypes.includes(type),
1579
+ );
1580
+ }
1581
+
1582
+ /**
1583
+ * Determine which AI inventory types should be collected for a scan.
1584
+ *
1585
+ * This combines explicit project-type opt-ins with BOM audit category-driven
1586
+ * opt-ins, then removes any explicitly excluded inventory types.
1587
+ *
1588
+ * @param {Object} options Parse options from the CLI
1589
+ * @returns {string[]} AI inventory types to collect
1590
+ */
1591
+ export function getIncludedAiInventoryTypes(options) {
1592
+ const requestedAiInventoryTypes = getRequestedAiInventoryTypes(options);
1593
+ const excludedAiInventoryTypes = getExcludedAiInventoryTypes(options);
1594
+ const exactAiInventoryType = getExactAiInventoryType(options);
1595
+ if (exactAiInventoryType) {
1596
+ return filterIncludedAiInventoryTypes(
1597
+ requestedAiInventoryTypes,
1598
+ excludedAiInventoryTypes,
1599
+ );
1600
+ }
1601
+ const auditCategories = expandBomAuditCategories(options?.bomAuditCategories);
1602
+ const includedAiInventoryTypes = [...requestedAiInventoryTypes];
1603
+ if (auditCategories.includes("ai-agent")) {
1604
+ includedAiInventoryTypes.push("ai-skill");
1605
+ includedAiInventoryTypes.push("ai");
1606
+ }
1607
+ if (auditCategories.includes("mcp-server")) {
1608
+ includedAiInventoryTypes.push("mcp");
1609
+ }
1610
+ return filterIncludedAiInventoryTypes(
1611
+ includedAiInventoryTypes,
1612
+ excludedAiInventoryTypes,
1613
+ );
1614
+ }
1615
+
1616
+ /**
1617
+ * Returns the single AI inventory type when exactly one project type alias is
1618
+ * selected, otherwise undefined.
1619
+ *
1620
+ * @param {object} options CLI options
1621
+ * @returns {string|undefined} The exact AI inventory type or undefined
1622
+ */
1623
+ export function getExactAiInventoryType(options) {
1624
+ const requestedAiInventoryTypes = getRequestedAiInventoryTypes(options);
1625
+ return requestedAiInventoryTypes.length === 1 &&
1626
+ Array.isArray(options?.projectType) &&
1627
+ options.projectType.length === 1
1628
+ ? requestedAiInventoryTypes[0]
1629
+ : undefined;
1630
+ }
1631
+
1632
+ /**
1633
+ * Determine whether MCP source-code analysis should run for the current scan.
1634
+ *
1635
+ * @param {string[]} includedAiInventoryTypes AI inventory types selected for collection
1636
+ * @returns {boolean} True when MCP inventory collection is enabled
1637
+ */
1638
+ export function shouldDetectMcpInventory(includedAiInventoryTypes) {
1639
+ return includedAiInventoryTypes.includes("mcp");
1640
+ }
1641
+
1642
+ /**
1643
+ * Collects sorted, unique relative file names for AI inventory subjects whose
1644
+ * `cdx:file:kind` property matches one of the given kinds.
1645
+ *
1646
+ * @param {object[]} subjects Component or service subjects to inspect
1647
+ * @param {string} discoveryPath Base path used to compute relative file names
1648
+ * @param {Set<string>} kindSet Accepted kind values
1649
+ * @returns {string[]} Sorted unique relative file names
1650
+ */
1651
+ export function summarizeAiInventoryNames(subjects, discoveryPath, kindSet) {
1652
+ return [
1653
+ ...new Set(
1654
+ (subjects || [])
1655
+ .filter((subject) =>
1656
+ kindSet.has(inventoryPropertyValue(subject, "cdx:file:kind")),
1657
+ )
1658
+ .map((subject) => inventoryPropertyValue(subject, "internal:SrcFile"))
1659
+ .filter(Boolean)
1660
+ .map(
1661
+ (filePath) => relative(discoveryPath, filePath) || basename(filePath),
1662
+ ),
1663
+ ),
1664
+ ].sort();
1665
+ }
1666
+
1667
+ /**
1668
+ * Collects sorted unique service names from an AI inventory services list.
1669
+ *
1670
+ * @param {object[]} services Services with a `name` property
1671
+ * @returns {string[]} Sorted unique service names
1672
+ */
1673
+ export function summarizeAiInventoryServiceNames(services) {
1674
+ return [
1675
+ ...new Set(
1676
+ (services || []).map((service) => service?.name).filter(Boolean),
1677
+ ),
1678
+ ].sort();
1679
+ }
1680
+
1681
+ /**
1682
+ * Formats one padded summary line for the AI inventory console output.
1683
+ *
1684
+ * @param {string} label Left-aligned label (padded to 20 chars)
1685
+ * @param {number} count Item count
1686
+ * @param {string[]} nameList Optional list of names to append in parentheses
1687
+ * @returns {string} The formatted summary line
1688
+ */
1689
+ export function formatAiInventorySummaryLine(label, count, nameList) {
1690
+ return ` ${label.padEnd(20)} ${count}${nameList.length ? ` (${nameList.join(", ")})` : ""}`;
1691
+ }
1692
+
1693
+ /**
1694
+ * Prints a human-readable AI inventory summary to stderr, including counts and
1695
+ * names for instruction files, skill files, MCP configs, and MCP services.
1696
+ * Returns without printing when the inventory is empty.
1697
+ *
1698
+ * @param {object} aiInventory AI inventory object with components and services
1699
+ * @param {string} discoveryPath Base path used to compute relative file names
1700
+ * @returns {void}
1701
+ */
1702
+ export function emitAiInventorySummary(aiInventory, discoveryPath) {
1703
+ const summary = summarizeAiInventory(aiInventory);
1704
+ const totalInventory =
1705
+ summary.instructionCount +
1706
+ summary.skillCount +
1707
+ summary.mcpConfigCount +
1708
+ summary.mcpServiceCount;
1709
+ if (!totalInventory) {
1710
+ return;
1711
+ }
1712
+ const instructionNames = summarizeAiInventoryNames(
1713
+ aiInventory.components,
1714
+ discoveryPath,
1715
+ AI_INSTRUCTION_FILE_KINDS,
1716
+ );
1717
+ const skillNames = summarizeAiInventoryNames(
1718
+ aiInventory.components,
1719
+ discoveryPath,
1720
+ new Set([AI_SKILL_FILE_KIND]),
1721
+ );
1722
+ const mcpConfigNames = summarizeAiInventoryNames(
1723
+ aiInventory.components,
1724
+ discoveryPath,
1725
+ new Set([MCP_CONFIG_FILE_KIND]),
1726
+ );
1727
+ const mcpServiceNames = summarizeAiInventoryServiceNames(
1728
+ aiInventory.services,
1729
+ );
1730
+ console.warn(
1731
+ [
1732
+ "AI Inventory Summary:",
1733
+ formatAiInventorySummaryLine(
1734
+ "AI instruction files:",
1735
+ summary.instructionCount,
1736
+ instructionNames,
1737
+ ),
1738
+ formatAiInventorySummaryLine(
1739
+ "Skill files:",
1740
+ summary.skillCount,
1741
+ skillNames,
1742
+ ),
1743
+ formatAiInventorySummaryLine(
1744
+ "MCP configs:",
1745
+ summary.mcpConfigCount,
1746
+ mcpConfigNames,
1747
+ ),
1748
+ formatAiInventorySummaryLine(
1749
+ "MCP services:",
1750
+ summary.mcpServiceCount,
1751
+ mcpServiceNames,
1752
+ ),
1753
+ "",
1754
+ "Run --bom-audit --bom-audit-categories ai-inventory to audit these surfaces.",
1755
+ ].join("\n"),
1756
+ );
1757
+ }
1758
+
1759
+ /**
1760
+ * Dedupe components
1761
+ *
1762
+ * @param {Object} options Options
1763
+ * @param {Array} components Components
1764
+ * @param {Object} parentComponent Parent component
1765
+ * @param {Array} dependencies Dependencies
1766
+ *
1767
+ * @returns {Object} Object including BOM Json
1768
+ */
1769
+ export function dedupeBom(options, components, parentComponent, dependencies) {
1770
+ if (!components) {
1771
+ return {};
1772
+ }
1773
+ if (!dependencies) {
1774
+ dependencies = [];
1775
+ }
1776
+ components = trimComponents(components);
1777
+ // Let's apply some common tweaks
1778
+ // Convert evidence.identity section to an object for 1.5
1779
+ if (options.specVersion === 1.5) {
1780
+ for (const comp of components) {
1781
+ if (comp?.evidence?.identity && Array.isArray(comp.evidence.identity)) {
1782
+ comp.evidence.identity = comp.evidence.identity[0];
1783
+ delete comp.evidence.identity.concludedValue;
1784
+ }
1785
+ }
1786
+ }
1787
+ if (DEBUG_MODE) {
1788
+ console.log(
1789
+ `Obtained ${components.length} components and ${dependencies.length} dependencies after dedupe.`,
1790
+ );
1791
+ }
1792
+ const serialNum = `urn:uuid:${uuidv4()}`;
1793
+ return {
1794
+ options,
1795
+ parentComponent,
1796
+ components,
1797
+ bomJson: setCycloneDxFormat(
1798
+ {
1799
+ specVersion: toCycloneDxSpecVersionString(
1800
+ options.specVersion || DEFAULT_CDX_SPEC_VERSION,
1801
+ ),
1802
+ serialNumber: serialNum,
1803
+ version: 1,
1804
+ metadata: addMetadata(parentComponent, options, {}),
1805
+ components,
1806
+ services: options.services || [],
1807
+ dependencies,
1808
+ },
1809
+ options.specVersion || DEFAULT_CDX_SPEC_VERSION,
1810
+ { preserveLegacyBomFormat: true },
1811
+ ),
1812
+ };
1813
+ }
1814
+
1815
+ /**
1816
+ * Checks whether the user explicitly selected a project type alias that
1817
+ * belongs to the given base project type.
1818
+ *
1819
+ * @param {object} options CLI options
1820
+ * @param {string} baseProjectType Base project type to check against
1821
+ * @returns {boolean} True when an explicit alias selection matches
1822
+ */
1823
+ export const hasExplicitProjectTypeSelection = (options, baseProjectType) => {
1824
+ options = options || {};
1825
+ const projectTypes = Array.isArray(options.projectType)
1826
+ ? options.projectType
1827
+ : options.projectType
1828
+ ? [options.projectType]
1829
+ : [];
1830
+ return projectTypes.some((selectedProjectType) =>
1831
+ PROJECT_TYPE_ALIASES[baseProjectType]?.includes(selectedProjectType),
1832
+ );
1833
+ };