@cdxgen/cdxgen 13.5.0 → 13.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (380) hide show
  1. package/README.md +17 -10
  2. package/bin/audit.js +7 -4
  3. package/bin/cdxgen.js +260 -37
  4. package/bin/convert.js +146 -22
  5. package/bin/evinse.js +28 -3
  6. package/bin/repl.js +47 -3
  7. package/bin/sign.js +211 -34
  8. package/bin/tracebom.js +18 -6
  9. package/bin/validate.js +24 -3
  10. package/bin/verify.js +113 -5
  11. package/data/behavior-taxonomy.schema.json +1491 -0
  12. package/data/cyclonedx-2.0-bundled.schema.json +18606 -5528
  13. package/data/cyclonedx-2.0-cryptography-defs.schema.json +857 -0
  14. package/data/license-aliases.json +24 -2
  15. package/data/pqc-migration.json +239 -0
  16. package/data/remediations.json +176 -0
  17. package/data/rules/ai-bom.yaml +1 -1
  18. package/data/rules/brotli-decoder.yaml +107 -0
  19. package/data/rules/cbom-security.yaml +4 -3
  20. package/data/rules/package-integrity.yaml +28 -0
  21. package/data/rules/vscode-extensions.yaml +75 -0
  22. package/data/spdx-license-list.json +121 -7
  23. package/data/spdx-licenses.json +69 -0
  24. package/data/spdx.schema.json +845 -2
  25. package/lib/audit/index.js +25 -3
  26. package/lib/cli/bomAssembly.js +172 -4
  27. package/lib/cli/cliOptions.js +121 -17
  28. package/lib/cli/index.js +720 -902
  29. package/lib/cli/jsBom.js +156 -64
  30. package/lib/cli/jvmBom.js +602 -86
  31. package/lib/cli/managedBom.js +161 -19
  32. package/lib/cli/nativeBom.js +52 -5
  33. package/lib/core/boundedFile.js +344 -0
  34. package/lib/core/brotliProbe.js +182 -0
  35. package/lib/core/env.js +34 -0
  36. package/lib/core/fs.js +138 -3
  37. package/lib/core/globPatterns.js +218 -0
  38. package/lib/core/httpClient.js +98 -1
  39. package/lib/core/lockPaths.js +38 -0
  40. package/lib/core/paths.js +24 -1
  41. package/lib/core/processTree.js +100 -8
  42. package/lib/core/projectConfig.js +332 -25
  43. package/lib/core/toolRegistry.js +184 -0
  44. package/lib/ecosystems/cppEvidence.js +263 -106
  45. package/lib/ecosystems/cppIncludeResolver.js +16 -5
  46. package/lib/ecosystems/denoutils.js +2 -2
  47. package/lib/ecosystems/ecosystems.js +25 -10
  48. package/lib/ecosystems/gemHostProbe.js +301 -0
  49. package/lib/ecosystems/golem.js +3 -8
  50. package/lib/ecosystems/gradleutils.js +1909 -229
  51. package/lib/ecosystems/jsEvidence.js +90 -38
  52. package/lib/ecosystems/kosi.js +3 -5
  53. package/lib/ecosystems/npmVersionResolution.js +376 -0
  54. package/lib/ecosystems/parsers-bazel.js +107 -6
  55. package/lib/ecosystems/parsers-js.js +505 -22
  56. package/lib/ecosystems/parsers-misc.js +209 -20
  57. package/lib/ecosystems/parsers-python.js +178 -30
  58. package/lib/ecosystems/parsers-rust.js +117 -15
  59. package/lib/ecosystems/pythonutils.js +128 -2
  60. package/lib/ecosystems/remote/huggingface.js +22 -0
  61. package/lib/ecosystems/rubyutils.js +538 -31
  62. package/lib/ecosystems/rusi.js +2 -4
  63. package/lib/ecosystems/scalacliutils.js +2 -0
  64. package/lib/ecosystems/scalasem.js +798 -152
  65. package/lib/ecosystems/vendoredCode.js +237 -3
  66. package/lib/ecosystems/venvProbe.js +360 -0
  67. package/lib/evinser/evinser.js +536 -71
  68. package/lib/evinser/scalasem.js +5 -1
  69. package/lib/helpers/agenticToolutils.js +525 -94
  70. package/lib/helpers/bomSigner.js +43 -9
  71. package/lib/helpers/jssSigner.js +1276 -0
  72. package/lib/helpers/vsixutils.js +1574 -315
  73. package/lib/inventory/agentBlueprint.js +193 -0
  74. package/lib/inventory/agentToolNames.js +145 -0
  75. package/lib/inventory/aiCollector.js +153 -7
  76. package/lib/inventory/aiInventory.js +44 -8
  77. package/lib/inventory/aiProviders.js +324 -0
  78. package/lib/inventory/atomUtils.js +77 -0
  79. package/lib/inventory/bomUtils.js +8 -1
  80. package/lib/inventory/brotliDecoder.js +142 -0
  81. package/lib/inventory/buildToolRateLimit.js +1 -1
  82. package/lib/inventory/cbomutils.js +56 -7
  83. package/lib/inventory/ciParsers/githubActionsLock.js +821 -0
  84. package/lib/inventory/citations.js +31 -2
  85. package/lib/inventory/communityAiConfigParser.js +978 -80
  86. package/lib/inventory/cyclonedx20.js +152 -0
  87. package/lib/inventory/cyclonedx20Common.js +286 -0
  88. package/lib/inventory/cyclonedx20Derived.js +159 -0
  89. package/lib/inventory/cyclonedx20Parties.js +552 -0
  90. package/lib/inventory/cyclonedx20Read.js +768 -0
  91. package/lib/inventory/cyclonedx20ReadCommon.js +374 -0
  92. package/lib/inventory/cyclonedx20ReadComponents.js +692 -0
  93. package/lib/inventory/cyclonedx20ReadContext.js +380 -0
  94. package/lib/inventory/cyclonedx20ReadEvidence.js +466 -0
  95. package/lib/inventory/cyclonedx20ReadSections.js +599 -0
  96. package/lib/inventory/cyclonedx20Render.js +766 -0
  97. package/lib/inventory/cyclonedx20RenderComponents.js +716 -0
  98. package/lib/inventory/cyclonedx20RenderDefinitions.js +405 -0
  99. package/lib/inventory/cyclonedx20RenderEvidence.js +726 -0
  100. package/lib/inventory/cyclonedx20RenderHardware.js +203 -0
  101. package/lib/inventory/cyclonedx20RenderPatents.js +174 -0
  102. package/lib/inventory/cyclonedx20RenderRefIds.js +314 -0
  103. package/lib/inventory/cyclonedx20RenderSections.js +499 -0
  104. package/lib/inventory/cyclonedx20Tables.js +594 -0
  105. package/lib/inventory/deps.js +141 -13
  106. package/lib/inventory/dosai.js +375 -6
  107. package/lib/inventory/dosaiParsers.js +3 -6
  108. package/lib/inventory/dotnetRuntime.js +367 -0
  109. package/lib/inventory/ecosystemFormulationParsers.js +979 -0
  110. package/lib/inventory/envcontext.js +436 -48
  111. package/lib/inventory/evidenceUtils.js +13 -1
  112. package/lib/inventory/fetchBatch.js +1 -1
  113. package/lib/inventory/formulationParsers.js +124 -14
  114. package/lib/inventory/gtfobins.js +13 -0
  115. package/lib/inventory/hbom.js +45 -6
  116. package/lib/inventory/hbomLoader.js +166 -0
  117. package/lib/inventory/hostRuntimeProbe.js +686 -0
  118. package/lib/inventory/jvmLocalRepos.js +9 -2
  119. package/lib/inventory/jvmToolEnv.js +29 -0
  120. package/lib/inventory/licenseEnhancer.js +12 -0
  121. package/lib/inventory/mavenCentralMirror.js +534 -0
  122. package/lib/inventory/mcpConfigParser.js +5 -0
  123. package/lib/inventory/nodeBuildInfo.js +218 -0
  124. package/lib/inventory/nodeHostProbe.js +202 -0
  125. package/lib/inventory/occurrenceKey.js +90 -0
  126. package/lib/inventory/osPackageResolver.js +182 -0
  127. package/lib/inventory/phpBuildInfo.js +10 -59
  128. package/lib/inventory/phpHostProbe.js +32 -488
  129. package/lib/inventory/pqcMigration.js +426 -0
  130. package/lib/inventory/rubyBuildInfo.js +972 -0
  131. package/lib/inventory/rubyHostProbe.js +218 -0
  132. package/lib/inventory/rustFormulationParser.js +21 -10
  133. package/lib/inventory/scalaCoords.js +4 -3
  134. package/lib/inventory/scalaDedupe.js +440 -0
  135. package/lib/inventory/source.js +114 -8
  136. package/lib/managers/binary.js +337 -3
  137. package/lib/managers/docker.js +79 -0
  138. package/lib/parsers/huggingfaceManifest.js +9 -1
  139. package/lib/parsers/huggingfaceUtils.js +18 -0
  140. package/lib/parsers/kiroPermissions.js +166 -0
  141. package/lib/parsers/largeJson.js +28 -11
  142. package/lib/parsers/vscodeExtensionId.js +183 -0
  143. package/lib/server/server.js +48 -35
  144. package/lib/stages/postgen/postgen.js +41 -1
  145. package/lib/stages/postgen/ruleEngine.js +13 -5
  146. package/lib/stages/postgen/specVersionCompat.js +76 -0
  147. package/lib/stages/pregen/envAudit.js +1 -0
  148. package/lib/stages/pregen/pregen.js +114 -57
  149. package/lib/validator/bomValidator.js +14 -2
  150. package/lib/validator/complianceEngine.js +30 -3
  151. package/lib/validator/complianceRules.js +1416 -4
  152. package/lib/validator/generated/validate-1.6.mjs +1 -1
  153. package/lib/validator/generated/validate-1.7.mjs +1 -1
  154. package/lib/validator/generated/validate-2.0.mjs +57554 -13851
  155. package/lib/validator/index.js +49 -8
  156. package/lib/validator/reporters/json.js +6 -0
  157. package/package.json +11 -10
  158. package/types/bin/repl.d.ts.map +1 -1
  159. package/types/lib/audit/index.d.ts +6 -2
  160. package/types/lib/audit/index.d.ts.map +1 -1
  161. package/types/lib/cli/bomAssembly.d.ts +29 -1
  162. package/types/lib/cli/bomAssembly.d.ts.map +1 -1
  163. package/types/lib/cli/cliOptions.d.ts +6 -0
  164. package/types/lib/cli/cliOptions.d.ts.map +1 -1
  165. package/types/lib/cli/index.d.ts.map +1 -1
  166. package/types/lib/cli/jsBom.d.ts +3 -18
  167. package/types/lib/cli/jsBom.d.ts.map +1 -1
  168. package/types/lib/cli/jvmBom.d.ts +15 -0
  169. package/types/lib/cli/jvmBom.d.ts.map +1 -1
  170. package/types/lib/cli/managedBom.d.ts.map +1 -1
  171. package/types/lib/cli/nativeBom.d.ts.map +1 -1
  172. package/types/lib/core/boundedFile.d.ts +100 -0
  173. package/types/lib/core/boundedFile.d.ts.map +1 -0
  174. package/types/lib/core/brotliProbe.d.ts +37 -0
  175. package/types/lib/core/brotliProbe.d.ts.map +1 -0
  176. package/types/lib/core/env.d.ts +14 -0
  177. package/types/lib/core/env.d.ts.map +1 -1
  178. package/types/lib/core/fs.d.ts +4 -0
  179. package/types/lib/core/fs.d.ts.map +1 -1
  180. package/types/lib/core/globPatterns.d.ts +70 -0
  181. package/types/lib/core/globPatterns.d.ts.map +1 -0
  182. package/types/lib/core/httpClient.d.ts +24 -0
  183. package/types/lib/core/httpClient.d.ts.map +1 -1
  184. package/types/lib/core/lockPaths.d.ts +19 -0
  185. package/types/lib/core/lockPaths.d.ts.map +1 -0
  186. package/types/lib/core/paths.d.ts +9 -0
  187. package/types/lib/core/paths.d.ts.map +1 -1
  188. package/types/lib/core/processTree.d.ts +17 -4
  189. package/types/lib/core/processTree.d.ts.map +1 -1
  190. package/types/lib/core/projectConfig.d.ts +47 -8
  191. package/types/lib/core/projectConfig.d.ts.map +1 -1
  192. package/types/lib/core/toolRegistry.d.ts +36 -0
  193. package/types/lib/core/toolRegistry.d.ts.map +1 -0
  194. package/types/lib/ecosystems/cppEvidence.d.ts +40 -13
  195. package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
  196. package/types/lib/ecosystems/cppIncludeResolver.d.ts +2 -1
  197. package/types/lib/ecosystems/cppIncludeResolver.d.ts.map +1 -1
  198. package/types/lib/ecosystems/ecosystems.d.ts.map +1 -1
  199. package/types/lib/ecosystems/gemHostProbe.d.ts +28 -0
  200. package/types/lib/ecosystems/gemHostProbe.d.ts.map +1 -0
  201. package/types/lib/ecosystems/golem.d.ts.map +1 -1
  202. package/types/lib/ecosystems/gradleutils.d.ts +294 -20
  203. package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
  204. package/types/lib/ecosystems/jsEvidence.d.ts +14 -1
  205. package/types/lib/ecosystems/jsEvidence.d.ts.map +1 -1
  206. package/types/lib/ecosystems/kosi.d.ts.map +1 -1
  207. package/types/lib/ecosystems/npmVersionResolution.d.ts +119 -0
  208. package/types/lib/ecosystems/npmVersionResolution.d.ts.map +1 -0
  209. package/types/lib/ecosystems/parsers-bazel.d.ts.map +1 -1
  210. package/types/lib/ecosystems/parsers-js.d.ts +17 -20
  211. package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
  212. package/types/lib/ecosystems/parsers-misc.d.ts +19 -0
  213. package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
  214. package/types/lib/ecosystems/parsers-python.d.ts +10 -0
  215. package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
  216. package/types/lib/ecosystems/parsers-rust.d.ts.map +1 -1
  217. package/types/lib/ecosystems/pythonutils.d.ts +19 -1
  218. package/types/lib/ecosystems/pythonutils.d.ts.map +1 -1
  219. package/types/lib/ecosystems/remote/huggingface.d.ts.map +1 -1
  220. package/types/lib/ecosystems/rubyutils.d.ts +144 -12
  221. package/types/lib/ecosystems/rubyutils.d.ts.map +1 -1
  222. package/types/lib/ecosystems/rusi.d.ts.map +1 -1
  223. package/types/lib/ecosystems/scalacliutils.d.ts.map +1 -1
  224. package/types/lib/ecosystems/scalasem.d.ts +58 -16
  225. package/types/lib/ecosystems/scalasem.d.ts.map +1 -1
  226. package/types/lib/ecosystems/vendoredCode.d.ts +26 -0
  227. package/types/lib/ecosystems/vendoredCode.d.ts.map +1 -1
  228. package/types/lib/ecosystems/venvProbe.d.ts +40 -0
  229. package/types/lib/ecosystems/venvProbe.d.ts.map +1 -0
  230. package/types/lib/evinser/evinser.d.ts +120 -13
  231. package/types/lib/evinser/evinser.d.ts.map +1 -1
  232. package/types/lib/evinser/scalasem.d.ts.map +1 -1
  233. package/types/lib/helpers/agenticToolutils.d.ts +53 -19
  234. package/types/lib/helpers/agenticToolutils.d.ts.map +1 -1
  235. package/types/lib/helpers/bomSigner.d.ts +20 -3
  236. package/types/lib/helpers/bomSigner.d.ts.map +1 -1
  237. package/types/lib/helpers/jssSigner.d.ts +288 -0
  238. package/types/lib/helpers/jssSigner.d.ts.map +1 -0
  239. package/types/lib/helpers/vsixutils.d.ts +303 -19
  240. package/types/lib/helpers/vsixutils.d.ts.map +1 -1
  241. package/types/lib/inventory/agentBlueprint.d.ts +70 -0
  242. package/types/lib/inventory/agentBlueprint.d.ts.map +1 -0
  243. package/types/lib/inventory/agentToolNames.d.ts +51 -0
  244. package/types/lib/inventory/agentToolNames.d.ts.map +1 -0
  245. package/types/lib/inventory/aiCollector.d.ts.map +1 -1
  246. package/types/lib/inventory/aiInventory.d.ts.map +1 -1
  247. package/types/lib/inventory/aiProviders.d.ts +85 -0
  248. package/types/lib/inventory/aiProviders.d.ts.map +1 -0
  249. package/types/lib/inventory/atomUtils.d.ts +19 -0
  250. package/types/lib/inventory/atomUtils.d.ts.map +1 -1
  251. package/types/lib/inventory/bomUtils.d.ts.map +1 -1
  252. package/types/lib/inventory/brotliDecoder.d.ts +58 -0
  253. package/types/lib/inventory/brotliDecoder.d.ts.map +1 -0
  254. package/types/lib/inventory/cbomutils.d.ts +17 -0
  255. package/types/lib/inventory/cbomutils.d.ts.map +1 -1
  256. package/types/lib/inventory/ciParsers/githubActionsLock.d.ts +101 -0
  257. package/types/lib/inventory/ciParsers/githubActionsLock.d.ts.map +1 -0
  258. package/types/lib/inventory/citations.d.ts +5 -0
  259. package/types/lib/inventory/citations.d.ts.map +1 -1
  260. package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
  261. package/types/lib/inventory/cyclonedx20.d.ts +99 -0
  262. package/types/lib/inventory/cyclonedx20.d.ts.map +1 -0
  263. package/types/lib/inventory/cyclonedx20Common.d.ts +102 -0
  264. package/types/lib/inventory/cyclonedx20Common.d.ts.map +1 -0
  265. package/types/lib/inventory/cyclonedx20Derived.d.ts +74 -0
  266. package/types/lib/inventory/cyclonedx20Derived.d.ts.map +1 -0
  267. package/types/lib/inventory/cyclonedx20Parties.d.ts +91 -0
  268. package/types/lib/inventory/cyclonedx20Parties.d.ts.map +1 -0
  269. package/types/lib/inventory/cyclonedx20Read.d.ts +51 -0
  270. package/types/lib/inventory/cyclonedx20Read.d.ts.map +1 -0
  271. package/types/lib/inventory/cyclonedx20ReadCommon.d.ts +69 -0
  272. package/types/lib/inventory/cyclonedx20ReadCommon.d.ts.map +1 -0
  273. package/types/lib/inventory/cyclonedx20ReadComponents.d.ts +77 -0
  274. package/types/lib/inventory/cyclonedx20ReadComponents.d.ts.map +1 -0
  275. package/types/lib/inventory/cyclonedx20ReadContext.d.ts +118 -0
  276. package/types/lib/inventory/cyclonedx20ReadContext.d.ts.map +1 -0
  277. package/types/lib/inventory/cyclonedx20ReadEvidence.d.ts +40 -0
  278. package/types/lib/inventory/cyclonedx20ReadEvidence.d.ts.map +1 -0
  279. package/types/lib/inventory/cyclonedx20ReadSections.d.ts +45 -0
  280. package/types/lib/inventory/cyclonedx20ReadSections.d.ts.map +1 -0
  281. package/types/lib/inventory/cyclonedx20Render.d.ts +53 -0
  282. package/types/lib/inventory/cyclonedx20Render.d.ts.map +1 -0
  283. package/types/lib/inventory/cyclonedx20RenderComponents.d.ts +73 -0
  284. package/types/lib/inventory/cyclonedx20RenderComponents.d.ts.map +1 -0
  285. package/types/lib/inventory/cyclonedx20RenderDefinitions.d.ts +29 -0
  286. package/types/lib/inventory/cyclonedx20RenderDefinitions.d.ts.map +1 -0
  287. package/types/lib/inventory/cyclonedx20RenderEvidence.d.ts +110 -0
  288. package/types/lib/inventory/cyclonedx20RenderEvidence.d.ts.map +1 -0
  289. package/types/lib/inventory/cyclonedx20RenderHardware.d.ts +42 -0
  290. package/types/lib/inventory/cyclonedx20RenderHardware.d.ts.map +1 -0
  291. package/types/lib/inventory/cyclonedx20RenderPatents.d.ts +26 -0
  292. package/types/lib/inventory/cyclonedx20RenderPatents.d.ts.map +1 -0
  293. package/types/lib/inventory/cyclonedx20RenderRefIds.d.ts +55 -0
  294. package/types/lib/inventory/cyclonedx20RenderRefIds.d.ts.map +1 -0
  295. package/types/lib/inventory/cyclonedx20RenderSections.d.ts +45 -0
  296. package/types/lib/inventory/cyclonedx20RenderSections.d.ts.map +1 -0
  297. package/types/lib/inventory/cyclonedx20Tables.d.ts +134 -0
  298. package/types/lib/inventory/cyclonedx20Tables.d.ts.map +1 -0
  299. package/types/lib/inventory/deps.d.ts +35 -2
  300. package/types/lib/inventory/deps.d.ts.map +1 -1
  301. package/types/lib/inventory/dosai.d.ts +36 -1
  302. package/types/lib/inventory/dosai.d.ts.map +1 -1
  303. package/types/lib/inventory/dosaiParsers.d.ts.map +1 -1
  304. package/types/lib/inventory/dotnetRuntime.d.ts +91 -0
  305. package/types/lib/inventory/dotnetRuntime.d.ts.map +1 -0
  306. package/types/lib/inventory/ecosystemFormulationParsers.d.ts +73 -0
  307. package/types/lib/inventory/ecosystemFormulationParsers.d.ts.map +1 -0
  308. package/types/lib/inventory/envcontext.d.ts +74 -12
  309. package/types/lib/inventory/envcontext.d.ts.map +1 -1
  310. package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
  311. package/types/lib/inventory/formulationParsers.d.ts.map +1 -1
  312. package/types/lib/inventory/gtfobins.d.ts.map +1 -1
  313. package/types/lib/inventory/hbom.d.ts +11 -0
  314. package/types/lib/inventory/hbom.d.ts.map +1 -1
  315. package/types/lib/inventory/hbomLoader.d.ts +54 -0
  316. package/types/lib/inventory/hbomLoader.d.ts.map +1 -1
  317. package/types/lib/inventory/hostRuntimeProbe.d.ts +44 -0
  318. package/types/lib/inventory/hostRuntimeProbe.d.ts.map +1 -0
  319. package/types/lib/inventory/jvmLocalRepos.d.ts +5 -1
  320. package/types/lib/inventory/jvmLocalRepos.d.ts.map +1 -1
  321. package/types/lib/inventory/jvmToolEnv.d.ts +12 -0
  322. package/types/lib/inventory/jvmToolEnv.d.ts.map +1 -1
  323. package/types/lib/inventory/licenseEnhancer.d.ts.map +1 -1
  324. package/types/lib/inventory/mavenCentralMirror.d.ts +170 -0
  325. package/types/lib/inventory/mavenCentralMirror.d.ts.map +1 -0
  326. package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -1
  327. package/types/lib/inventory/nodeBuildInfo.d.ts +95 -0
  328. package/types/lib/inventory/nodeBuildInfo.d.ts.map +1 -0
  329. package/types/lib/inventory/nodeHostProbe.d.ts +15 -0
  330. package/types/lib/inventory/nodeHostProbe.d.ts.map +1 -0
  331. package/types/lib/inventory/occurrenceKey.d.ts +52 -0
  332. package/types/lib/inventory/occurrenceKey.d.ts.map +1 -0
  333. package/types/lib/inventory/osPackageResolver.d.ts +38 -0
  334. package/types/lib/inventory/osPackageResolver.d.ts.map +1 -1
  335. package/types/lib/inventory/phpBuildInfo.d.ts.map +1 -1
  336. package/types/lib/inventory/phpHostProbe.d.ts.map +1 -1
  337. package/types/lib/inventory/pqcMigration.d.ts +84 -0
  338. package/types/lib/inventory/pqcMigration.d.ts.map +1 -0
  339. package/types/lib/inventory/rubyBuildInfo.d.ts +271 -0
  340. package/types/lib/inventory/rubyBuildInfo.d.ts.map +1 -0
  341. package/types/lib/inventory/rubyHostProbe.d.ts +47 -0
  342. package/types/lib/inventory/rubyHostProbe.d.ts.map +1 -0
  343. package/types/lib/inventory/rustFormulationParser.d.ts +7 -2
  344. package/types/lib/inventory/rustFormulationParser.d.ts.map +1 -1
  345. package/types/lib/inventory/scalaCoords.d.ts.map +1 -1
  346. package/types/lib/inventory/scalaDedupe.d.ts +43 -0
  347. package/types/lib/inventory/scalaDedupe.d.ts.map +1 -0
  348. package/types/lib/inventory/source.d.ts +25 -0
  349. package/types/lib/inventory/source.d.ts.map +1 -1
  350. package/types/lib/managers/binary.d.ts.map +1 -1
  351. package/types/lib/managers/docker.d.ts +12 -0
  352. package/types/lib/managers/docker.d.ts.map +1 -1
  353. package/types/lib/parsers/huggingfaceManifest.d.ts +10 -1
  354. package/types/lib/parsers/huggingfaceManifest.d.ts.map +1 -1
  355. package/types/lib/parsers/huggingfaceUtils.d.ts +12 -0
  356. package/types/lib/parsers/huggingfaceUtils.d.ts.map +1 -1
  357. package/types/lib/parsers/kiroPermissions.d.ts +62 -0
  358. package/types/lib/parsers/kiroPermissions.d.ts.map +1 -0
  359. package/types/lib/parsers/largeJson.d.ts +4 -3
  360. package/types/lib/parsers/largeJson.d.ts.map +1 -1
  361. package/types/lib/parsers/vscodeExtensionId.d.ts +48 -0
  362. package/types/lib/parsers/vscodeExtensionId.d.ts.map +1 -0
  363. package/types/lib/server/server.d.ts.map +1 -1
  364. package/types/lib/stages/postgen/postgen.d.ts +7 -0
  365. package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
  366. package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
  367. package/types/lib/stages/postgen/specVersionCompat.d.ts +25 -0
  368. package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -1
  369. package/types/lib/stages/pregen/envAudit.d.ts.map +1 -1
  370. package/types/lib/stages/pregen/pregen.d.ts +12 -8
  371. package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
  372. package/types/lib/validator/bomValidator.d.ts +5 -1
  373. package/types/lib/validator/bomValidator.d.ts.map +1 -1
  374. package/types/lib/validator/complianceEngine.d.ts +4 -4
  375. package/types/lib/validator/complianceEngine.d.ts.map +1 -1
  376. package/types/lib/validator/complianceRules.d.ts +14 -2
  377. package/types/lib/validator/complianceRules.d.ts.map +1 -1
  378. package/types/lib/validator/index.d.ts +10 -0
  379. package/types/lib/validator/index.d.ts.map +1 -1
  380. package/types/lib/validator/reporters/json.d.ts.map +1 -1
@@ -5,6 +5,8 @@
5
5
  * and the dosai runners (layer 2) can share it.
6
6
  */
7
7
 
8
+ import process from "node:process";
9
+
8
10
  import { DEBUG_MODE } from "./activity.js";
9
11
  import { safeSpawnSync } from "./fs.js";
10
12
  import { isWin } from "./paths.js";
@@ -24,6 +26,54 @@ export function formatDuration(ms) {
24
26
  return `${Math.round(ms / 100) / 10} seconds`;
25
27
  }
26
28
 
29
+ /**
30
+ * Longest the PowerShell process snapshot behind reapProcessTree may run.
31
+ */
32
+ const REAP_TIMEOUT_MS = 60000;
33
+
34
+ /**
35
+ * Longest reapProcessTree waits for the processes it stopped to exit.
36
+ */
37
+ const REAP_EXIT_WAIT_MS = 10000;
38
+
39
+ /**
40
+ * Block the calling thread for a number of milliseconds.
41
+ *
42
+ * @param {number} ms Milliseconds to wait
43
+ */
44
+ function sleepSync(ms) {
45
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
46
+ }
47
+
48
+ /**
49
+ * Whether a process with this pid is still running.
50
+ *
51
+ * @param {number} pid Process id
52
+ * @returns {boolean} true while the process exists
53
+ */
54
+ function isRunning(pid) {
55
+ try {
56
+ process.kill(pid, 0);
57
+ return true;
58
+ } catch (err) {
59
+ // EPERM means the process exists but belongs to someone else.
60
+ return err?.code === "EPERM";
61
+ }
62
+ }
63
+
64
+ /**
65
+ * A UTC instant as a DMTF datetime, the form WQL compares CIM_DATETIME
66
+ * properties such as Win32_Process.CreationDate against.
67
+ *
68
+ * @param {number} ms Epoch milliseconds
69
+ * @returns {string} The instant as `yyyymmddHHMMSS.mmmmmm+000`
70
+ */
71
+ export function toDmtfUtc(ms) {
72
+ const date = new Date(ms);
73
+ const pad = (value, width = 2) => `${value}`.padStart(width, "0");
74
+ return `${date.getUTCFullYear()}${pad(date.getUTCMonth() + 1)}${pad(date.getUTCDate())}${pad(date.getUTCHours())}${pad(date.getUTCMinutes())}${pad(date.getUTCSeconds())}.${pad(date.getUTCMilliseconds(), 3)}000+000`;
75
+ }
76
+
27
77
  /**
28
78
  * Stop the descendants a timed-out run left behind on Windows.
29
79
  *
@@ -32,11 +82,16 @@ export function formatDuration(ms) {
32
82
  * workers, or the build hosts a .NET analyzer starts keep running while still
33
83
  * pointing at the dead process's pid. `taskkill /T` on that pid finds nothing,
34
84
  * because the root is already gone. The live descendants are therefore found
35
- * by parent pid in a process snapshot and stopped, limited to processes
36
- * created after the run started. The root's own children must also predate
37
- * its end: once the root is gone its pid can be handed to an unrelated
38
- * process, whose children would otherwise look like the run's. Elsewhere this
85
+ * by parent pid in a PowerShell process snapshot, limited to processes
86
+ * created after the run started, and stopped from Node.js. The root's own
87
+ * children must also predate its end: once the root is gone its pid can be
88
+ * handed to an unrelated process, whose children would otherwise look like
89
+ * the run's. Elsewhere this
39
90
  * does nothing: an orphan is re-parented and can no longer be told apart.
91
+ * It returns once the stopped processes have exited, or after ten seconds,
92
+ * so the caller can remove files the run left half-written. When the
93
+ * snapshot itself fails or runs past its time limit it warns and returns an
94
+ * empty list, since processes may then still be running.
40
95
  *
41
96
  * @param {number|undefined} rootPid pid of the process cdxgen spawned
42
97
  * @param {number} startedAt Epoch milliseconds at which the run started
@@ -53,15 +108,24 @@ export function reapProcessTree(
53
108
  if (!isWin || !Number.isInteger(rootPid) || rootPid <= 0) {
54
109
  return [];
55
110
  }
56
- // All three values are integers, so interpolating them cannot inject anything.
111
+ // All three values are integers, and the DMTF string is built from digits
112
+ // only, so interpolating them cannot inject anything.
57
113
  const since = Math.max(0, Math.floor(startedAt) - 1000);
58
114
  const until = Math.max(since, Math.floor(endedAt) + 1000);
115
+ const snapshotProperties = "-Property ProcessId,ParentProcessId,CreationDate";
59
116
  const script = [
60
117
  `$root = ${rootPid}`,
61
118
  `$since = [DateTimeOffset]::FromUnixTimeMilliseconds(${since}).UtcDateTime`,
62
119
  `$until = [DateTimeOffset]::FromUnixTimeMilliseconds(${until}).UtcDateTime`,
120
+ // WMI drops the processes that predate the run before PowerShell sees
121
+ // them, which keeps the snapshot small on a busy host. The loop below
122
+ // applies the same bound, so a WMI that rejects the filter only costs the
123
+ // full snapshot.
124
+ "$procs = @()",
125
+ `try { $procs = @(Get-CimInstance Win32_Process -Filter "CreationDate >= '${toDmtfUtc(since)}'" ${snapshotProperties} -ErrorAction Stop) }`,
126
+ `catch { $procs = @(Get-CimInstance Win32_Process ${snapshotProperties}) }`,
63
127
  "$children = @{}",
64
- "foreach ($p in Get-CimInstance Win32_Process -Property ProcessId,ParentProcessId,CreationDate) {",
128
+ "foreach ($p in $procs) {",
65
129
  " if (-not $p.CreationDate) { continue }",
66
130
  " $created = $p.CreationDate.ToUniversalTime()",
67
131
  " if ($created -lt $since) { continue }",
@@ -76,19 +140,47 @@ export function reapProcessTree(
76
140
  " if ($child -and -not $found.Contains($child)) { $found.Add($child); $queue.Enqueue($child) }",
77
141
  " }",
78
142
  "}",
79
- "foreach ($child in $found) { Stop-Process -Id $child -Force -ErrorAction SilentlyContinue }",
80
143
  "$found -join ','",
81
144
  ].join("\n");
82
145
  const result = safeSpawnSync(
83
146
  "powershell",
84
147
  ["-NoProfile", "-NonInteractive", "-Command", script],
85
- { timeout: 60000 },
148
+ { timeout: REAP_TIMEOUT_MS },
86
149
  );
150
+ if (result?.error || result?.status !== 0) {
151
+ // An empty result here is not evidence that nothing was left running.
152
+ console.warn(
153
+ result?.error?.code === "ETIMEDOUT"
154
+ ? `Could not look for processes the timed-out ${toolName} run left behind: the process snapshot took longer than ${formatDuration(REAP_TIMEOUT_MS)}.`
155
+ : `Could not look for processes the timed-out ${toolName} run left behind: PowerShell ${result?.error ? `failed to start (${result.error.message})` : `exited with status ${result?.status}`}.`,
156
+ );
157
+ return [];
158
+ }
87
159
  const reaped = `${result?.stdout || ""}`
88
160
  .trim()
89
161
  .split(",")
90
162
  .map((pid) => Number.parseInt(pid, 10))
91
163
  .filter((pid) => pid > 0);
164
+ for (const pid of reaped) {
165
+ try {
166
+ process.kill(pid, "SIGKILL");
167
+ } catch {
168
+ // The process exited between the snapshot and the kill.
169
+ }
170
+ }
171
+ // A process that is still exiting keeps its files open, so wait for the
172
+ // exits, but never longer than REAP_EXIT_WAIT_MS.
173
+ const deadline = Date.now() + REAP_EXIT_WAIT_MS;
174
+ let running = reaped.filter(isRunning);
175
+ while (running.length && Date.now() < deadline) {
176
+ sleepSync(100);
177
+ running = running.filter(isRunning);
178
+ }
179
+ if (running.length) {
180
+ console.warn(
181
+ `${running.length} process(es) the timed-out ${toolName} run left behind were still exiting after ${formatDuration(REAP_EXIT_WAIT_MS)}: ${running.join(", ")}.`,
182
+ );
183
+ }
92
184
  if (DEBUG_MODE) {
93
185
  console.log(
94
186
  reaped.length
@@ -1,5 +1,8 @@
1
+ import { realpathSync } from "node:fs";
1
2
  import path from "node:path";
2
3
 
4
+ import { HOST_SCOPE_PROJECT_TYPES } from "./env.js";
5
+ import { boundUntrustedGlobPatterns } from "./globPatterns.js";
3
6
  import {
4
7
  isReservedMetadataPropertyName,
5
8
  METADATA_PROPERTY_CONFIG_KEYS,
@@ -17,10 +20,162 @@ export const PROJECT_CONFIG_FILENAMES = [
17
20
  ".cdxgen.yaml",
18
21
  ];
19
22
 
23
+ /**
24
+ * Options a config file may set, by their kebab-case name. A config file may
25
+ * also use the camelCase spelling of each, or one of the aliases in
26
+ * PROJECT_CONFIG_OPTION_ALIASES. Every other key is ignored: options that
27
+ * only library callers pass (such as `dosaiCommand` or `traceCmd`), yargs'
28
+ * own `extends`, and anything cdxgen does not know.
29
+ *
30
+ * Every option bin/cdxgen.js declares is either here or in
31
+ * OPERATOR_ONLY_OPTIONS, which projectConfig.poku.js checks.
32
+ */
33
+ export const PROJECT_CONFIG_OPTIONS = new Set([
34
+ "activity-report",
35
+ "api-key",
36
+ "author",
37
+ "auto-compositions",
38
+ "auto-create",
39
+ "bom-audit",
40
+ "bom-audit-categories",
41
+ "bom-audit-fail-severity",
42
+ "bom-audit-include-trusted",
43
+ "bom-audit-max-targets",
44
+ "bom-audit-min-severity",
45
+ "bom-audit-only-trusted",
46
+ "bom-audit-rules-dir",
47
+ "bom-audit-scope",
48
+ "cache",
49
+ "cache-ttl",
50
+ "callsites-slices-file",
51
+ "caxa-app-dir",
52
+ "cmake-cache",
53
+ "color",
54
+ "compile-commands",
55
+ "component-type",
56
+ "data-flow-slices-file",
57
+ "deep",
58
+ "deps-slices-file",
59
+ "dry-run",
60
+ "env-audit",
61
+ "evidence",
62
+ "evinse-output",
63
+ "exclude",
64
+ "exclude-type",
65
+ "experimental-mcp-pinning",
66
+ "export-proto",
67
+ "fail-on-error",
68
+ "filter",
69
+ "format",
70
+ "generate-key-and-sign",
71
+ "git-branch",
72
+ "include-crypto",
73
+ "include-formulation",
74
+ "include-regex",
75
+ "include-release-notes",
76
+ "include-runtime",
77
+ "install-deps",
78
+ "introspect",
79
+ "introspect-annotate",
80
+ "introspect-fail-below",
81
+ "introspect-json",
82
+ "introspect-report",
83
+ "is-latest",
84
+ "json-pretty",
85
+ "license-policy",
86
+ "license-ref",
87
+ "lifecycle",
88
+ "log-format",
89
+ "metadata-property",
90
+ "min-confidence",
91
+ "no-babel",
92
+ "no-banner",
93
+ "no-ignore",
94
+ "only",
95
+ "openapi-spec-file",
96
+ "output",
97
+ "package-extensions",
98
+ "parent-project-id",
99
+ "parent-project-name",
100
+ "parent-project-version",
101
+ "print",
102
+ "profile",
103
+ "progress",
104
+ "project-group",
105
+ "project-id",
106
+ "project-name",
107
+ "project-tag",
108
+ "project-version",
109
+ "proto-bin-file",
110
+ "quiet",
111
+ "reachables-slices-file",
112
+ "recurse",
113
+ "release-notes-current-tag",
114
+ "release-notes-previous-tag",
115
+ "required-only",
116
+ "resolve-class",
117
+ "rust",
118
+ "scalasem",
119
+ "scalasem-include-tests",
120
+ "semantics-slices-file",
121
+ "server-url",
122
+ "spec-version",
123
+ "standard",
124
+ "tea-artifact-url",
125
+ "tea-author-email",
126
+ "tea-author-name",
127
+ "tea-collection-name",
128
+ "tea-fetch",
129
+ "tea-leaf-identifier",
130
+ "tea-publish",
131
+ "tea-reason",
132
+ "tea-token",
133
+ "technique",
134
+ "tlp-classification",
135
+ "tui",
136
+ "type",
137
+ "usages-slices-file",
138
+ "validate",
139
+ "verbose",
140
+ ]);
141
+
142
+ /**
143
+ * Options only the operator may set, on the command line or through a
144
+ * CDXGEN_* environment variable. They choose an executable, start a listener,
145
+ * turn off certificate checks on the operator's own upload, opt into
146
+ * experimental tool installation, or end the run without a BOM. A config file
147
+ * that sets one is told so and ignored.
148
+ */
149
+ export const OPERATOR_ONLY_OPTIONS = new Set([
150
+ "feature-flags",
151
+ "help",
152
+ "scalasem-command",
153
+ "server",
154
+ "server-host",
155
+ "server-port",
156
+ "skip-dt-tls-check",
157
+ ]);
158
+
159
+ /**
160
+ * Alternate option names a config file may use, with the option each one
161
+ * stands for. yargs applies its aliases to config keys too, so each is
162
+ * checked as the option it names.
163
+ */
164
+ export const PROJECT_CONFIG_OPTION_ALIASES = new Map([
165
+ ["c", "resolve-class"],
166
+ ["exclude-regex", "exclude"],
167
+ ["h", "help"],
168
+ ["o", "output"],
169
+ ["p", "print"],
170
+ ["q", "quiet"],
171
+ ["r", "recurse"],
172
+ ["t", "type"],
173
+ ]);
174
+
20
175
  /**
21
176
  * Options whose values name a file or directory cdxgen writes to or reads
22
177
  * from. A config file may set these, but only to a location inside its own
23
- * directory.
178
+ * directory, after symbolic links are resolved.
24
179
  */
25
180
  const PATH_OPTIONS = new Set([
26
181
  "output",
@@ -28,14 +183,26 @@ const PATH_OPTIONS = new Set([
28
183
  "proto-bin-file",
29
184
  "deps-slices-file",
30
185
  "usages-slices-file",
186
+ "callsites-slices-file",
31
187
  "data-flow-slices-file",
32
188
  "reachables-slices-file",
33
189
  "semantics-slices-file",
34
190
  "openapi-spec-file",
35
191
  "license-policy",
36
192
  "bom-audit-rules-dir",
193
+ "introspect-report",
194
+ "introspect-json",
195
+ "cmake-cache",
196
+ "compile-commands",
197
+ "caxa-app-dir",
37
198
  ]);
38
199
 
200
+ /**
201
+ * Options whose values are glob patterns matched against every file a scan
202
+ * walks, in the order they draw on the shared expansion budget.
203
+ */
204
+ const PATTERN_OPTIONS = ["exclude", "include-regex"];
205
+
39
206
  /**
40
207
  * Options that change where cdxgen sends data or how much of the host it
41
208
  * touches. These stay usable, but never silently.
@@ -64,9 +231,53 @@ function optionSpellings(option) {
64
231
  return camel === option ? [option] : [option, camel];
65
232
  }
66
233
 
234
+ /**
235
+ * Find the option a config key names.
236
+ *
237
+ * @param {string} key config file key
238
+ * @returns {string|undefined} kebab-case option name, or undefined when the
239
+ * key is not the kebab-case spelling, the camelCase spelling or an alias of
240
+ * an option cdxgen declares
241
+ */
242
+ function configKeyOption(key) {
243
+ if (PROJECT_CONFIG_OPTION_ALIASES.has(key)) {
244
+ return PROJECT_CONFIG_OPTION_ALIASES.get(key);
245
+ }
246
+ const kebab = key.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
247
+ if (!PROJECT_CONFIG_OPTIONS.has(kebab) && !OPERATOR_ONLY_OPTIONS.has(kebab)) {
248
+ return undefined;
249
+ }
250
+ return optionSpellings(kebab).includes(key) ? kebab : undefined;
251
+ }
252
+
253
+ /**
254
+ * Resolve a path through the symbolic links of its longest existing prefix.
255
+ * The part that does not exist yet is appended unchanged.
256
+ *
257
+ * @param {string} absolutePath absolute path to resolve
258
+ * @returns {string} the path with every existing component resolved
259
+ */
260
+ function resolveExistingPrefix(absolutePath) {
261
+ const missing = [];
262
+ let current = absolutePath;
263
+ for (;;) {
264
+ try {
265
+ return path.join(realpathSync(current), ...missing.reverse());
266
+ } catch {
267
+ const parent = path.dirname(current);
268
+ if (parent === current) {
269
+ return absolutePath;
270
+ }
271
+ missing.push(path.basename(current));
272
+ current = parent;
273
+ }
274
+ }
275
+ }
276
+
67
277
  /**
68
278
  * Determine whether a config-supplied path stays inside the config's own
69
- * directory.
279
+ * directory once symbolic links are resolved, so a link committed to the
280
+ * scanned tree cannot carry a path option outside it.
70
281
  *
71
282
  * @param {string} configDir directory the config file was read from
72
283
  * @param {unknown} value config-supplied path value
@@ -76,40 +287,95 @@ function isContainedPath(configDir, value) {
76
287
  if (typeof value !== "string" || !value.length) {
77
288
  return false;
78
289
  }
79
- const relativePath = path.relative(
80
- path.resolve(configDir),
81
- path.resolve(configDir, value),
82
- );
290
+ const root = resolveExistingPrefix(path.resolve(configDir));
291
+ const target = resolveExistingPrefix(path.resolve(configDir, value));
292
+ const relativePath = path.relative(root, target);
83
293
  return (
84
294
  relativePath === "" ||
85
- (!relativePath.startsWith("..") && !path.isAbsolute(relativePath))
295
+ (relativePath !== ".." &&
296
+ !relativePath.startsWith(`..${path.sep}`) &&
297
+ !path.isAbsolute(relativePath))
86
298
  );
87
299
  }
88
300
 
301
+ /**
302
+ * Split a config-supplied project type value into the individual types.
303
+ *
304
+ * @param {unknown} value `type` value from a config file
305
+ * @returns {string[]} trimmed, non-empty project types
306
+ */
307
+ function projectTypeList(value) {
308
+ return (Array.isArray(value) ? value : [value])
309
+ .flatMap((entry) => `${entry ?? ""}`.split(","))
310
+ .map((entry) => entry.trim())
311
+ .filter(Boolean);
312
+ }
313
+
89
314
  /**
90
315
  * Apply the trust boundary between cdxgen and the directory it is scanning.
91
316
  *
92
317
  * A config file lives in the tree under analysis, so it is attacker-controlled
93
- * whenever that tree is. Path options are therefore confined to the config's
94
- * own directory - a scanned project may choose where in itself the BOM lands,
95
- * but not write outside it - and options that redirect data off the host or
96
- * widen what cdxgen executes are announced on the console. A project may
97
- * describe itself with custom metadata properties, but not in the namespaces
98
- * cdxgen reserves for the facts it establishes, so a scanned tree cannot pass
99
- * its own claims off as cdxgen's.
318
+ * whenever that tree is. It may therefore only set the options listed in
319
+ * PROJECT_CONFIG_OPTIONS: options that choose an executable, start a listener
320
+ * or weaken the operator's own checks, and every key cdxgen does not declare
321
+ * as an option, are dropped. Path options are confined to the config's own
322
+ * directory - a scanned project may choose where in itself the BOM lands, but
323
+ * not write outside it - and project types that inventory the host rather
324
+ * than the scan path are dropped. Exclude and include patterns are kept
325
+ * within the bounds of boundUntrustedGlobPatterns, so a project cannot make
326
+ * every file match against thousands of brace-expanded patterns. Options that
327
+ * redirect data off the host or widen what cdxgen does are announced on the
328
+ * console. A project may describe itself with custom metadata properties, but
329
+ * not in the namespaces cdxgen reserves for the facts it establishes, so a
330
+ * scanned tree cannot pass its own claims off as cdxgen's.
100
331
  *
101
332
  * @param {Object} config parsed config file contents
102
333
  * @param {string} configDir directory the config file was read from
103
- * @returns {{config: Object, rejected: string[], announced: string[], reservedProperties: string[]}} sanitized config and what it did
334
+ * @returns {{config: Object, rejected: string[], announced: string[], reservedProperties: string[], ignored: string[], operatorOnly: string[], hostScopeTypes: string[], refusedPatterns: {key: string, pattern: string, reason: string}[]}} sanitized config and what it did
104
335
  */
105
336
  export function sanitizeProjectConfig(config, configDir) {
106
- if (!config || typeof config !== "object") {
107
- return { announced: [], config: {}, rejected: [], reservedProperties: [] };
337
+ const result = {
338
+ announced: [],
339
+ config: {},
340
+ hostScopeTypes: [],
341
+ ignored: [],
342
+ operatorOnly: [],
343
+ refusedPatterns: [],
344
+ rejected: [],
345
+ reservedProperties: [],
346
+ };
347
+ if (!config || typeof config !== "object" || Array.isArray(config)) {
348
+ return result;
349
+ }
350
+ const sanitized = result.config;
351
+ const aliasEntries = [];
352
+ for (const [key, value] of Object.entries(config)) {
353
+ if (METADATA_PROPERTY_CONFIG_KEYS.includes(key)) {
354
+ sanitized[key] = value;
355
+ continue;
356
+ }
357
+ const option = configKeyOption(key);
358
+ if (!option) {
359
+ result.ignored.push(key);
360
+ continue;
361
+ }
362
+ if (OPERATOR_ONLY_OPTIONS.has(option)) {
363
+ result.operatorOnly.push(key);
364
+ continue;
365
+ }
366
+ if (PROJECT_CONFIG_OPTION_ALIASES.has(key)) {
367
+ aliasEntries.push([option, value]);
368
+ continue;
369
+ }
370
+ sanitized[key] = value;
371
+ }
372
+ // An alias is stored under the option it names, so the checks below see
373
+ // it. A spelled-out option in the same file takes precedence.
374
+ for (const [option, value] of aliasEntries) {
375
+ if (optionSpellings(option).every((key) => sanitized[key] === undefined)) {
376
+ sanitized[option] = value;
377
+ }
108
378
  }
109
- const sanitized = { ...config };
110
- const rejected = [];
111
- const announced = [];
112
- const reservedProperties = [];
113
379
  for (const key of METADATA_PROPERTY_CONFIG_KEYS) {
114
380
  if (sanitized[key] === undefined) {
115
381
  continue;
@@ -117,7 +383,7 @@ export function sanitizeProjectConfig(config, configDir) {
117
383
  const properties = [];
118
384
  for (const aprop of parseMetadataProperties(sanitized[key])) {
119
385
  if (isReservedMetadataPropertyName(aprop.name)) {
120
- reservedProperties.push(aprop.name);
386
+ result.reservedProperties.push(aprop.name);
121
387
  } else {
122
388
  properties.push(aprop);
123
389
  }
@@ -134,17 +400,58 @@ export function sanitizeProjectConfig(config, configDir) {
134
400
  continue;
135
401
  }
136
402
  if (!isContainedPath(configDir, sanitized[key])) {
137
- rejected.push(`${key}=${sanitized[key]}`);
403
+ result.rejected.push(`${key}=${sanitized[key]}`);
138
404
  delete sanitized[key];
139
405
  }
140
406
  }
141
407
  }
408
+ if (sanitized.type !== undefined) {
409
+ const types = projectTypeList(sanitized.type);
410
+ const projectTypes = types.filter(
411
+ (type) => !HOST_SCOPE_PROJECT_TYPES.has(type.toLowerCase()),
412
+ );
413
+ result.hostScopeTypes = types.filter(
414
+ (type) => !projectTypes.includes(type),
415
+ );
416
+ if (result.hostScopeTypes.length) {
417
+ if (projectTypes.length) {
418
+ sanitized.type = projectTypes;
419
+ } else {
420
+ delete sanitized.type;
421
+ }
422
+ }
423
+ }
424
+ // Exclude patterns, then include patterns, share one expansion budget.
425
+ let patternsUsed = 0;
426
+ for (const option of PATTERN_OPTIONS) {
427
+ for (const key of optionSpellings(option)) {
428
+ if (sanitized[key] === undefined) {
429
+ continue;
430
+ }
431
+ const { accepted, expansions, refused } = boundUntrustedGlobPatterns(
432
+ sanitized[key],
433
+ { used: patternsUsed },
434
+ );
435
+ patternsUsed += expansions;
436
+ for (const entry of refused) {
437
+ result.refusedPatterns.push({ key, ...entry });
438
+ }
439
+ if (!refused.length) {
440
+ continue;
441
+ }
442
+ if (!accepted.length) {
443
+ delete sanitized[key];
444
+ } else {
445
+ sanitized[key] = Array.isArray(sanitized[key]) ? accepted : accepted[0];
446
+ }
447
+ }
448
+ }
142
449
  for (const option of ANNOUNCED_OPTIONS) {
143
450
  for (const key of optionSpellings(option)) {
144
451
  if (sanitized[key] !== undefined) {
145
- announced.push(key);
452
+ result.announced.push(key);
146
453
  }
147
454
  }
148
455
  }
149
- return { announced, config: sanitized, rejected, reservedProperties };
456
+ return result;
150
457
  }