@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.
- package/README.md +17 -10
- package/bin/audit.js +7 -4
- package/bin/cdxgen.js +260 -37
- package/bin/convert.js +146 -22
- package/bin/evinse.js +28 -3
- package/bin/repl.js +47 -3
- package/bin/sign.js +211 -34
- package/bin/tracebom.js +18 -6
- package/bin/validate.js +24 -3
- package/bin/verify.js +113 -5
- package/data/behavior-taxonomy.schema.json +1491 -0
- package/data/cyclonedx-2.0-bundled.schema.json +18606 -5528
- package/data/cyclonedx-2.0-cryptography-defs.schema.json +857 -0
- package/data/license-aliases.json +24 -2
- package/data/pqc-migration.json +239 -0
- package/data/remediations.json +176 -0
- package/data/rules/ai-bom.yaml +1 -1
- package/data/rules/brotli-decoder.yaml +107 -0
- package/data/rules/cbom-security.yaml +4 -3
- package/data/rules/package-integrity.yaml +28 -0
- package/data/rules/vscode-extensions.yaml +75 -0
- package/data/spdx-license-list.json +121 -7
- package/data/spdx-licenses.json +69 -0
- package/data/spdx.schema.json +845 -2
- package/lib/audit/index.js +25 -3
- package/lib/cli/bomAssembly.js +172 -4
- package/lib/cli/cliOptions.js +121 -17
- package/lib/cli/index.js +720 -902
- package/lib/cli/jsBom.js +156 -64
- package/lib/cli/jvmBom.js +602 -86
- package/lib/cli/managedBom.js +161 -19
- package/lib/cli/nativeBom.js +52 -5
- package/lib/core/boundedFile.js +344 -0
- package/lib/core/brotliProbe.js +182 -0
- package/lib/core/env.js +34 -0
- package/lib/core/fs.js +138 -3
- package/lib/core/globPatterns.js +218 -0
- package/lib/core/httpClient.js +98 -1
- package/lib/core/lockPaths.js +38 -0
- package/lib/core/paths.js +24 -1
- package/lib/core/processTree.js +100 -8
- package/lib/core/projectConfig.js +332 -25
- package/lib/core/toolRegistry.js +184 -0
- package/lib/ecosystems/cppEvidence.js +263 -106
- package/lib/ecosystems/cppIncludeResolver.js +16 -5
- package/lib/ecosystems/denoutils.js +2 -2
- package/lib/ecosystems/ecosystems.js +25 -10
- package/lib/ecosystems/gemHostProbe.js +301 -0
- package/lib/ecosystems/golem.js +3 -8
- package/lib/ecosystems/gradleutils.js +1909 -229
- package/lib/ecosystems/jsEvidence.js +90 -38
- package/lib/ecosystems/kosi.js +3 -5
- package/lib/ecosystems/npmVersionResolution.js +376 -0
- package/lib/ecosystems/parsers-bazel.js +107 -6
- package/lib/ecosystems/parsers-js.js +505 -22
- package/lib/ecosystems/parsers-misc.js +209 -20
- package/lib/ecosystems/parsers-python.js +178 -30
- package/lib/ecosystems/parsers-rust.js +117 -15
- package/lib/ecosystems/pythonutils.js +128 -2
- package/lib/ecosystems/remote/huggingface.js +22 -0
- package/lib/ecosystems/rubyutils.js +538 -31
- package/lib/ecosystems/rusi.js +2 -4
- package/lib/ecosystems/scalacliutils.js +2 -0
- package/lib/ecosystems/scalasem.js +798 -152
- package/lib/ecosystems/vendoredCode.js +237 -3
- package/lib/ecosystems/venvProbe.js +360 -0
- package/lib/evinser/evinser.js +536 -71
- package/lib/evinser/scalasem.js +5 -1
- package/lib/helpers/agenticToolutils.js +525 -94
- package/lib/helpers/bomSigner.js +43 -9
- package/lib/helpers/jssSigner.js +1276 -0
- package/lib/helpers/vsixutils.js +1574 -315
- package/lib/inventory/agentBlueprint.js +193 -0
- package/lib/inventory/agentToolNames.js +145 -0
- package/lib/inventory/aiCollector.js +153 -7
- package/lib/inventory/aiInventory.js +44 -8
- package/lib/inventory/aiProviders.js +324 -0
- package/lib/inventory/atomUtils.js +77 -0
- package/lib/inventory/bomUtils.js +8 -1
- package/lib/inventory/brotliDecoder.js +142 -0
- package/lib/inventory/buildToolRateLimit.js +1 -1
- package/lib/inventory/cbomutils.js +56 -7
- package/lib/inventory/ciParsers/githubActionsLock.js +821 -0
- package/lib/inventory/citations.js +31 -2
- package/lib/inventory/communityAiConfigParser.js +978 -80
- package/lib/inventory/cyclonedx20.js +152 -0
- package/lib/inventory/cyclonedx20Common.js +286 -0
- package/lib/inventory/cyclonedx20Derived.js +159 -0
- package/lib/inventory/cyclonedx20Parties.js +552 -0
- package/lib/inventory/cyclonedx20Read.js +768 -0
- package/lib/inventory/cyclonedx20ReadCommon.js +374 -0
- package/lib/inventory/cyclonedx20ReadComponents.js +692 -0
- package/lib/inventory/cyclonedx20ReadContext.js +380 -0
- package/lib/inventory/cyclonedx20ReadEvidence.js +466 -0
- package/lib/inventory/cyclonedx20ReadSections.js +599 -0
- package/lib/inventory/cyclonedx20Render.js +766 -0
- package/lib/inventory/cyclonedx20RenderComponents.js +716 -0
- package/lib/inventory/cyclonedx20RenderDefinitions.js +405 -0
- package/lib/inventory/cyclonedx20RenderEvidence.js +726 -0
- package/lib/inventory/cyclonedx20RenderHardware.js +203 -0
- package/lib/inventory/cyclonedx20RenderPatents.js +174 -0
- package/lib/inventory/cyclonedx20RenderRefIds.js +314 -0
- package/lib/inventory/cyclonedx20RenderSections.js +499 -0
- package/lib/inventory/cyclonedx20Tables.js +594 -0
- package/lib/inventory/deps.js +141 -13
- package/lib/inventory/dosai.js +375 -6
- package/lib/inventory/dosaiParsers.js +3 -6
- package/lib/inventory/dotnetRuntime.js +367 -0
- package/lib/inventory/ecosystemFormulationParsers.js +979 -0
- package/lib/inventory/envcontext.js +436 -48
- package/lib/inventory/evidenceUtils.js +13 -1
- package/lib/inventory/fetchBatch.js +1 -1
- package/lib/inventory/formulationParsers.js +124 -14
- package/lib/inventory/gtfobins.js +13 -0
- package/lib/inventory/hbom.js +45 -6
- package/lib/inventory/hbomLoader.js +166 -0
- package/lib/inventory/hostRuntimeProbe.js +686 -0
- package/lib/inventory/jvmLocalRepos.js +9 -2
- package/lib/inventory/jvmToolEnv.js +29 -0
- package/lib/inventory/licenseEnhancer.js +12 -0
- package/lib/inventory/mavenCentralMirror.js +534 -0
- package/lib/inventory/mcpConfigParser.js +5 -0
- package/lib/inventory/nodeBuildInfo.js +218 -0
- package/lib/inventory/nodeHostProbe.js +202 -0
- package/lib/inventory/occurrenceKey.js +90 -0
- package/lib/inventory/osPackageResolver.js +182 -0
- package/lib/inventory/phpBuildInfo.js +10 -59
- package/lib/inventory/phpHostProbe.js +32 -488
- package/lib/inventory/pqcMigration.js +426 -0
- package/lib/inventory/rubyBuildInfo.js +972 -0
- package/lib/inventory/rubyHostProbe.js +218 -0
- package/lib/inventory/rustFormulationParser.js +21 -10
- package/lib/inventory/scalaCoords.js +4 -3
- package/lib/inventory/scalaDedupe.js +440 -0
- package/lib/inventory/source.js +114 -8
- package/lib/managers/binary.js +337 -3
- package/lib/managers/docker.js +79 -0
- package/lib/parsers/huggingfaceManifest.js +9 -1
- package/lib/parsers/huggingfaceUtils.js +18 -0
- package/lib/parsers/kiroPermissions.js +166 -0
- package/lib/parsers/largeJson.js +28 -11
- package/lib/parsers/vscodeExtensionId.js +183 -0
- package/lib/server/server.js +48 -35
- package/lib/stages/postgen/postgen.js +41 -1
- package/lib/stages/postgen/ruleEngine.js +13 -5
- package/lib/stages/postgen/specVersionCompat.js +76 -0
- package/lib/stages/pregen/envAudit.js +1 -0
- package/lib/stages/pregen/pregen.js +114 -57
- package/lib/validator/bomValidator.js +14 -2
- package/lib/validator/complianceEngine.js +30 -3
- package/lib/validator/complianceRules.js +1416 -4
- package/lib/validator/generated/validate-1.6.mjs +1 -1
- package/lib/validator/generated/validate-1.7.mjs +1 -1
- package/lib/validator/generated/validate-2.0.mjs +57554 -13851
- package/lib/validator/index.js +49 -8
- package/lib/validator/reporters/json.js +6 -0
- package/package.json +11 -10
- package/types/bin/repl.d.ts.map +1 -1
- package/types/lib/audit/index.d.ts +6 -2
- package/types/lib/audit/index.d.ts.map +1 -1
- package/types/lib/cli/bomAssembly.d.ts +29 -1
- package/types/lib/cli/bomAssembly.d.ts.map +1 -1
- package/types/lib/cli/cliOptions.d.ts +6 -0
- package/types/lib/cli/cliOptions.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/cli/jsBom.d.ts +3 -18
- package/types/lib/cli/jsBom.d.ts.map +1 -1
- package/types/lib/cli/jvmBom.d.ts +15 -0
- package/types/lib/cli/jvmBom.d.ts.map +1 -1
- package/types/lib/cli/managedBom.d.ts.map +1 -1
- package/types/lib/cli/nativeBom.d.ts.map +1 -1
- package/types/lib/core/boundedFile.d.ts +100 -0
- package/types/lib/core/boundedFile.d.ts.map +1 -0
- package/types/lib/core/brotliProbe.d.ts +37 -0
- package/types/lib/core/brotliProbe.d.ts.map +1 -0
- package/types/lib/core/env.d.ts +14 -0
- package/types/lib/core/env.d.ts.map +1 -1
- package/types/lib/core/fs.d.ts +4 -0
- package/types/lib/core/fs.d.ts.map +1 -1
- package/types/lib/core/globPatterns.d.ts +70 -0
- package/types/lib/core/globPatterns.d.ts.map +1 -0
- package/types/lib/core/httpClient.d.ts +24 -0
- package/types/lib/core/httpClient.d.ts.map +1 -1
- package/types/lib/core/lockPaths.d.ts +19 -0
- package/types/lib/core/lockPaths.d.ts.map +1 -0
- package/types/lib/core/paths.d.ts +9 -0
- package/types/lib/core/paths.d.ts.map +1 -1
- package/types/lib/core/processTree.d.ts +17 -4
- package/types/lib/core/processTree.d.ts.map +1 -1
- package/types/lib/core/projectConfig.d.ts +47 -8
- package/types/lib/core/projectConfig.d.ts.map +1 -1
- package/types/lib/core/toolRegistry.d.ts +36 -0
- package/types/lib/core/toolRegistry.d.ts.map +1 -0
- package/types/lib/ecosystems/cppEvidence.d.ts +40 -13
- package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/cppIncludeResolver.d.ts +2 -1
- package/types/lib/ecosystems/cppIncludeResolver.d.ts.map +1 -1
- package/types/lib/ecosystems/ecosystems.d.ts.map +1 -1
- package/types/lib/ecosystems/gemHostProbe.d.ts +28 -0
- package/types/lib/ecosystems/gemHostProbe.d.ts.map +1 -0
- package/types/lib/ecosystems/golem.d.ts.map +1 -1
- package/types/lib/ecosystems/gradleutils.d.ts +294 -20
- package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
- package/types/lib/ecosystems/jsEvidence.d.ts +14 -1
- package/types/lib/ecosystems/jsEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/kosi.d.ts.map +1 -1
- package/types/lib/ecosystems/npmVersionResolution.d.ts +119 -0
- package/types/lib/ecosystems/npmVersionResolution.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-bazel.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-js.d.ts +17 -20
- package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-misc.d.ts +19 -0
- package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-python.d.ts +10 -0
- package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-rust.d.ts.map +1 -1
- package/types/lib/ecosystems/pythonutils.d.ts +19 -1
- package/types/lib/ecosystems/pythonutils.d.ts.map +1 -1
- package/types/lib/ecosystems/remote/huggingface.d.ts.map +1 -1
- package/types/lib/ecosystems/rubyutils.d.ts +144 -12
- package/types/lib/ecosystems/rubyutils.d.ts.map +1 -1
- package/types/lib/ecosystems/rusi.d.ts.map +1 -1
- package/types/lib/ecosystems/scalacliutils.d.ts.map +1 -1
- package/types/lib/ecosystems/scalasem.d.ts +58 -16
- package/types/lib/ecosystems/scalasem.d.ts.map +1 -1
- package/types/lib/ecosystems/vendoredCode.d.ts +26 -0
- package/types/lib/ecosystems/vendoredCode.d.ts.map +1 -1
- package/types/lib/ecosystems/venvProbe.d.ts +40 -0
- package/types/lib/ecosystems/venvProbe.d.ts.map +1 -0
- package/types/lib/evinser/evinser.d.ts +120 -13
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/evinser/scalasem.d.ts.map +1 -1
- package/types/lib/helpers/agenticToolutils.d.ts +53 -19
- package/types/lib/helpers/agenticToolutils.d.ts.map +1 -1
- package/types/lib/helpers/bomSigner.d.ts +20 -3
- package/types/lib/helpers/bomSigner.d.ts.map +1 -1
- package/types/lib/helpers/jssSigner.d.ts +288 -0
- package/types/lib/helpers/jssSigner.d.ts.map +1 -0
- package/types/lib/helpers/vsixutils.d.ts +303 -19
- package/types/lib/helpers/vsixutils.d.ts.map +1 -1
- package/types/lib/inventory/agentBlueprint.d.ts +70 -0
- package/types/lib/inventory/agentBlueprint.d.ts.map +1 -0
- package/types/lib/inventory/agentToolNames.d.ts +51 -0
- package/types/lib/inventory/agentToolNames.d.ts.map +1 -0
- package/types/lib/inventory/aiCollector.d.ts.map +1 -1
- package/types/lib/inventory/aiInventory.d.ts.map +1 -1
- package/types/lib/inventory/aiProviders.d.ts +85 -0
- package/types/lib/inventory/aiProviders.d.ts.map +1 -0
- package/types/lib/inventory/atomUtils.d.ts +19 -0
- package/types/lib/inventory/atomUtils.d.ts.map +1 -1
- package/types/lib/inventory/bomUtils.d.ts.map +1 -1
- package/types/lib/inventory/brotliDecoder.d.ts +58 -0
- package/types/lib/inventory/brotliDecoder.d.ts.map +1 -0
- package/types/lib/inventory/cbomutils.d.ts +17 -0
- package/types/lib/inventory/cbomutils.d.ts.map +1 -1
- package/types/lib/inventory/ciParsers/githubActionsLock.d.ts +101 -0
- package/types/lib/inventory/ciParsers/githubActionsLock.d.ts.map +1 -0
- package/types/lib/inventory/citations.d.ts +5 -0
- package/types/lib/inventory/citations.d.ts.map +1 -1
- package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/cyclonedx20.d.ts +99 -0
- package/types/lib/inventory/cyclonedx20.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Common.d.ts +102 -0
- package/types/lib/inventory/cyclonedx20Common.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Derived.d.ts +74 -0
- package/types/lib/inventory/cyclonedx20Derived.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Parties.d.ts +91 -0
- package/types/lib/inventory/cyclonedx20Parties.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Read.d.ts +51 -0
- package/types/lib/inventory/cyclonedx20Read.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadCommon.d.ts +69 -0
- package/types/lib/inventory/cyclonedx20ReadCommon.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadComponents.d.ts +77 -0
- package/types/lib/inventory/cyclonedx20ReadComponents.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadContext.d.ts +118 -0
- package/types/lib/inventory/cyclonedx20ReadContext.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadEvidence.d.ts +40 -0
- package/types/lib/inventory/cyclonedx20ReadEvidence.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadSections.d.ts +45 -0
- package/types/lib/inventory/cyclonedx20ReadSections.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Render.d.ts +53 -0
- package/types/lib/inventory/cyclonedx20Render.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderComponents.d.ts +73 -0
- package/types/lib/inventory/cyclonedx20RenderComponents.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderDefinitions.d.ts +29 -0
- package/types/lib/inventory/cyclonedx20RenderDefinitions.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderEvidence.d.ts +110 -0
- package/types/lib/inventory/cyclonedx20RenderEvidence.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderHardware.d.ts +42 -0
- package/types/lib/inventory/cyclonedx20RenderHardware.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderPatents.d.ts +26 -0
- package/types/lib/inventory/cyclonedx20RenderPatents.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderRefIds.d.ts +55 -0
- package/types/lib/inventory/cyclonedx20RenderRefIds.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderSections.d.ts +45 -0
- package/types/lib/inventory/cyclonedx20RenderSections.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Tables.d.ts +134 -0
- package/types/lib/inventory/cyclonedx20Tables.d.ts.map +1 -0
- package/types/lib/inventory/deps.d.ts +35 -2
- package/types/lib/inventory/deps.d.ts.map +1 -1
- package/types/lib/inventory/dosai.d.ts +36 -1
- package/types/lib/inventory/dosai.d.ts.map +1 -1
- package/types/lib/inventory/dosaiParsers.d.ts.map +1 -1
- package/types/lib/inventory/dotnetRuntime.d.ts +91 -0
- package/types/lib/inventory/dotnetRuntime.d.ts.map +1 -0
- package/types/lib/inventory/ecosystemFormulationParsers.d.ts +73 -0
- package/types/lib/inventory/ecosystemFormulationParsers.d.ts.map +1 -0
- package/types/lib/inventory/envcontext.d.ts +74 -12
- package/types/lib/inventory/envcontext.d.ts.map +1 -1
- package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
- package/types/lib/inventory/formulationParsers.d.ts.map +1 -1
- package/types/lib/inventory/gtfobins.d.ts.map +1 -1
- package/types/lib/inventory/hbom.d.ts +11 -0
- package/types/lib/inventory/hbom.d.ts.map +1 -1
- package/types/lib/inventory/hbomLoader.d.ts +54 -0
- package/types/lib/inventory/hbomLoader.d.ts.map +1 -1
- package/types/lib/inventory/hostRuntimeProbe.d.ts +44 -0
- package/types/lib/inventory/hostRuntimeProbe.d.ts.map +1 -0
- package/types/lib/inventory/jvmLocalRepos.d.ts +5 -1
- package/types/lib/inventory/jvmLocalRepos.d.ts.map +1 -1
- package/types/lib/inventory/jvmToolEnv.d.ts +12 -0
- package/types/lib/inventory/jvmToolEnv.d.ts.map +1 -1
- package/types/lib/inventory/licenseEnhancer.d.ts.map +1 -1
- package/types/lib/inventory/mavenCentralMirror.d.ts +170 -0
- package/types/lib/inventory/mavenCentralMirror.d.ts.map +1 -0
- package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/nodeBuildInfo.d.ts +95 -0
- package/types/lib/inventory/nodeBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/nodeHostProbe.d.ts +15 -0
- package/types/lib/inventory/nodeHostProbe.d.ts.map +1 -0
- package/types/lib/inventory/occurrenceKey.d.ts +52 -0
- package/types/lib/inventory/occurrenceKey.d.ts.map +1 -0
- package/types/lib/inventory/osPackageResolver.d.ts +38 -0
- package/types/lib/inventory/osPackageResolver.d.ts.map +1 -1
- package/types/lib/inventory/phpBuildInfo.d.ts.map +1 -1
- package/types/lib/inventory/phpHostProbe.d.ts.map +1 -1
- package/types/lib/inventory/pqcMigration.d.ts +84 -0
- package/types/lib/inventory/pqcMigration.d.ts.map +1 -0
- package/types/lib/inventory/rubyBuildInfo.d.ts +271 -0
- package/types/lib/inventory/rubyBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/rubyHostProbe.d.ts +47 -0
- package/types/lib/inventory/rubyHostProbe.d.ts.map +1 -0
- package/types/lib/inventory/rustFormulationParser.d.ts +7 -2
- package/types/lib/inventory/rustFormulationParser.d.ts.map +1 -1
- package/types/lib/inventory/scalaCoords.d.ts.map +1 -1
- package/types/lib/inventory/scalaDedupe.d.ts +43 -0
- package/types/lib/inventory/scalaDedupe.d.ts.map +1 -0
- package/types/lib/inventory/source.d.ts +25 -0
- package/types/lib/inventory/source.d.ts.map +1 -1
- package/types/lib/managers/binary.d.ts.map +1 -1
- package/types/lib/managers/docker.d.ts +12 -0
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/parsers/huggingfaceManifest.d.ts +10 -1
- package/types/lib/parsers/huggingfaceManifest.d.ts.map +1 -1
- package/types/lib/parsers/huggingfaceUtils.d.ts +12 -0
- package/types/lib/parsers/huggingfaceUtils.d.ts.map +1 -1
- package/types/lib/parsers/kiroPermissions.d.ts +62 -0
- package/types/lib/parsers/kiroPermissions.d.ts.map +1 -0
- package/types/lib/parsers/largeJson.d.ts +4 -3
- package/types/lib/parsers/largeJson.d.ts.map +1 -1
- package/types/lib/parsers/vscodeExtensionId.d.ts +48 -0
- package/types/lib/parsers/vscodeExtensionId.d.ts.map +1 -0
- package/types/lib/server/server.d.ts.map +1 -1
- package/types/lib/stages/postgen/postgen.d.ts +7 -0
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
- package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
- package/types/lib/stages/postgen/specVersionCompat.d.ts +25 -0
- package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -1
- package/types/lib/stages/pregen/envAudit.d.ts.map +1 -1
- package/types/lib/stages/pregen/pregen.d.ts +12 -8
- package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
- package/types/lib/validator/bomValidator.d.ts +5 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
- package/types/lib/validator/complianceEngine.d.ts +4 -4
- package/types/lib/validator/complianceEngine.d.ts.map +1 -1
- package/types/lib/validator/complianceRules.d.ts +14 -2
- package/types/lib/validator/complianceRules.d.ts.map +1 -1
- package/types/lib/validator/index.d.ts +10 -0
- package/types/lib/validator/index.d.ts.map +1 -1
- package/types/lib/validator/reporters/json.d.ts.map +1 -1
|
@@ -43,6 +43,7 @@ const AI_INVENTORY_FILE_KINDS = new Set([
|
|
|
43
43
|
"agent-config",
|
|
44
44
|
"agent-definition",
|
|
45
45
|
"agent-instructions",
|
|
46
|
+
"agent-spec",
|
|
46
47
|
"ai-agent-file",
|
|
47
48
|
"copilot-instructions",
|
|
48
49
|
"copilot-setup-workflow",
|
|
@@ -52,6 +53,10 @@ const AI_INVENTORY_FILE_KINDS = new Set([
|
|
|
52
53
|
"custom-command",
|
|
53
54
|
"custom-tool",
|
|
54
55
|
"graph-definition",
|
|
56
|
+
"hook-file",
|
|
57
|
+
"permission-policy",
|
|
58
|
+
"settings",
|
|
59
|
+
"workflow-file",
|
|
55
60
|
AI_SKILL_FILE_KIND,
|
|
56
61
|
]);
|
|
57
62
|
|
|
@@ -80,6 +85,11 @@ const AI_INVENTORY_PARSERS = [
|
|
|
80
85
|
id: communityAiConfigParser.id,
|
|
81
86
|
parser: communityAiConfigParser,
|
|
82
87
|
types: ["ai-skill"],
|
|
88
|
+
// The community agent configurations (.kiro, .cursor/rules,
|
|
89
|
+
// .claude/agents, and similar) also belong in an AI-BOM next to the
|
|
90
|
+
// models and services, so `-t ai` runs this parser and keeps its
|
|
91
|
+
// ai-skill components.
|
|
92
|
+
aiOverlay: true,
|
|
83
93
|
},
|
|
84
94
|
];
|
|
85
95
|
|
|
@@ -301,8 +311,23 @@ export function collectAiInventory(discoveryPath, options, types) {
|
|
|
301
311
|
let components = [];
|
|
302
312
|
const dependencies = [];
|
|
303
313
|
let services = [];
|
|
314
|
+
// Output of an aiOverlay parser that runs only because `-t ai` was
|
|
315
|
+
// requested. It is filtered with ai-skill added to the requested types, and
|
|
316
|
+
// kept apart so the extra type never widens the filter for other parsers
|
|
317
|
+
// or the language collectors. `--exclude-type ai-skill` turns it off.
|
|
318
|
+
const overlayTypes = uniqueNonEmptyTypes([...requestedTypes, "ai-skill"]);
|
|
319
|
+
const overlayEnabled =
|
|
320
|
+
requestedTypes.includes("ai") &&
|
|
321
|
+
!requestedTypes.includes("ai-skill") &&
|
|
322
|
+
!optionIncludesAiInventoryProjectType(options?.excludeType, "ai-skill");
|
|
323
|
+
let overlayComponents = [];
|
|
324
|
+
let overlayServices = [];
|
|
304
325
|
for (const parserEntry of AI_INVENTORY_PARSERS) {
|
|
305
|
-
|
|
326
|
+
const requested = parserEntry.types.some((type) =>
|
|
327
|
+
requestedTypes.includes(type),
|
|
328
|
+
);
|
|
329
|
+
const isOverlay = !requested && overlayEnabled && parserEntry.aiOverlay;
|
|
330
|
+
if (!requested && !isOverlay) {
|
|
306
331
|
continue;
|
|
307
332
|
}
|
|
308
333
|
const matchedFiles = [];
|
|
@@ -326,11 +351,20 @@ export function collectAiInventory(discoveryPath, options, types) {
|
|
|
326
351
|
);
|
|
327
352
|
continue;
|
|
328
353
|
}
|
|
329
|
-
if (
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
354
|
+
if (isOverlay) {
|
|
355
|
+
overlayComponents = overlayComponents.concat(
|
|
356
|
+
filterInventorySubjectsByTypes(result?.components, overlayTypes),
|
|
357
|
+
);
|
|
358
|
+
overlayServices = overlayServices.concat(
|
|
359
|
+
filterInventorySubjectsByTypes(result?.services, overlayTypes),
|
|
360
|
+
);
|
|
361
|
+
} else {
|
|
362
|
+
if (result?.components?.length) {
|
|
363
|
+
components = components.concat(result.components);
|
|
364
|
+
}
|
|
365
|
+
if (result?.services?.length) {
|
|
366
|
+
services = mergeServices(services, result.services);
|
|
367
|
+
}
|
|
334
368
|
}
|
|
335
369
|
if (result?.dependencies?.length) {
|
|
336
370
|
dependencies.push(...result.dependencies);
|
|
@@ -365,11 +399,13 @@ export function collectAiInventory(discoveryPath, options, types) {
|
|
|
365
399
|
}
|
|
366
400
|
|
|
367
401
|
components = trimComponents(
|
|
368
|
-
filterInventorySubjectsByTypes(components, requestedTypes)
|
|
402
|
+
filterInventorySubjectsByTypes(components, requestedTypes).concat(
|
|
403
|
+
overlayComponents,
|
|
404
|
+
),
|
|
369
405
|
);
|
|
370
406
|
services = mergeServices(
|
|
371
|
-
[],
|
|
372
407
|
filterInventorySubjectsByTypes(services, requestedTypes),
|
|
408
|
+
overlayServices,
|
|
373
409
|
);
|
|
374
410
|
return {
|
|
375
411
|
components,
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Organisations that create AI models, keyed by the short creator id cdxgen
|
|
3
|
+
* uses internally. The value is the full organisation name written to the
|
|
4
|
+
* `manufacturer` of a model component, since the minimum elements guidance
|
|
5
|
+
* asks for full names rather than acronyms or product names.
|
|
6
|
+
*/
|
|
7
|
+
export const MODEL_CREATOR_NAMES = new Map([
|
|
8
|
+
["alibaba", "Alibaba Cloud"],
|
|
9
|
+
["anthropic", "Anthropic"],
|
|
10
|
+
["cohere", "Cohere"],
|
|
11
|
+
["deepseek", "DeepSeek"],
|
|
12
|
+
["google", "Google"],
|
|
13
|
+
["meta", "Meta"],
|
|
14
|
+
["mistral", "Mistral AI"],
|
|
15
|
+
["openai", "OpenAI"],
|
|
16
|
+
["xai", "xAI"],
|
|
17
|
+
["zhipu", "Zhipu AI"],
|
|
18
|
+
]);
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Providers that are a creator's own SDK or API, mapped to that creator.
|
|
22
|
+
* Hosting, routing and local providers such as groq, together, fireworks,
|
|
23
|
+
* openrouter, replicate, aws-bedrock, azure-openai, vertex-ai, huggingface
|
|
24
|
+
* and ollama serve models other organisations made, so they are absent.
|
|
25
|
+
*/
|
|
26
|
+
const CREATOR_OWN_PROVIDERS = new Map([
|
|
27
|
+
["anthropic", "anthropic"],
|
|
28
|
+
["cohere", "cohere"],
|
|
29
|
+
["dashscope", "alibaba"],
|
|
30
|
+
["deepseek", "deepseek"],
|
|
31
|
+
["gemini", "google"],
|
|
32
|
+
["google", "google"],
|
|
33
|
+
["meta", "meta"],
|
|
34
|
+
["mistral", "mistral"],
|
|
35
|
+
["openai", "openai"],
|
|
36
|
+
["xai", "xai"],
|
|
37
|
+
["zhipu", "zhipu"],
|
|
38
|
+
]);
|
|
39
|
+
|
|
40
|
+
// Creators whose own API serves only the models they made, so any model
|
|
41
|
+
// called through that API is theirs even when its name is not recognised.
|
|
42
|
+
// OpenAI-compatible clients, Google (Vertex Model Garden) and DashScope also
|
|
43
|
+
// serve models from other creators, so they are not in this set.
|
|
44
|
+
const SINGLE_CATALOGUE_CREATORS = new Set([
|
|
45
|
+
"anthropic",
|
|
46
|
+
"cohere",
|
|
47
|
+
"deepseek",
|
|
48
|
+
"mistral",
|
|
49
|
+
"xai",
|
|
50
|
+
"zhipu",
|
|
51
|
+
]);
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Local runtimes and inference servers. They serve whatever tag or served
|
|
55
|
+
* model name the user chose, so a model they run names no creator.
|
|
56
|
+
*/
|
|
57
|
+
export const LOCAL_MODEL_RUNTIMES = new Set([
|
|
58
|
+
"gpt4all",
|
|
59
|
+
"jan",
|
|
60
|
+
"llama.cpp",
|
|
61
|
+
"llamafile",
|
|
62
|
+
"lm-studio",
|
|
63
|
+
"local",
|
|
64
|
+
"local-inference",
|
|
65
|
+
"mlc",
|
|
66
|
+
"ollama",
|
|
67
|
+
"vllm",
|
|
68
|
+
"xinference",
|
|
69
|
+
]);
|
|
70
|
+
|
|
71
|
+
// Provider prefixes of model routes such as the litellm `groq/llama3-8b`
|
|
72
|
+
// form, mapped to the provider the route names. Matching is case-sensitive
|
|
73
|
+
// because the routes are lowercase while some Hugging Face organisations
|
|
74
|
+
// share the name in another case (Groq, Anthropic, Cohere). Prefixes that are
|
|
75
|
+
// also real lowercase Hub organisations (openai, google, databricks,
|
|
76
|
+
// cerebras, huggingface) are left out.
|
|
77
|
+
const MODEL_ROUTE_PROVIDERS = new Map([
|
|
78
|
+
["anthropic", "anthropic"],
|
|
79
|
+
["azure", "azure-openai"],
|
|
80
|
+
["azure_ai", "azure-ai"],
|
|
81
|
+
["bedrock", "aws-bedrock"],
|
|
82
|
+
["codestral", "mistral"],
|
|
83
|
+
["cohere", "cohere"],
|
|
84
|
+
["cohere_chat", "cohere"],
|
|
85
|
+
["dashscope", "dashscope"],
|
|
86
|
+
["deepseek", "deepseek"],
|
|
87
|
+
["fireworks_ai", "fireworks"],
|
|
88
|
+
["friendliai", "friendliai"],
|
|
89
|
+
["gemini", "gemini"],
|
|
90
|
+
["groq", "groq"],
|
|
91
|
+
["hosted_vllm", "vllm"],
|
|
92
|
+
["llamafile", "llamafile"],
|
|
93
|
+
["lm_studio", "lm-studio"],
|
|
94
|
+
["mistral", "mistral"],
|
|
95
|
+
["moonshot", "moonshot"],
|
|
96
|
+
["nvidia_nim", "nvidia-nim"],
|
|
97
|
+
["ollama", "ollama"],
|
|
98
|
+
["ollama_chat", "ollama"],
|
|
99
|
+
["openrouter", "openrouter"],
|
|
100
|
+
["perplexity", "perplexity"],
|
|
101
|
+
["replicate", "replicate"],
|
|
102
|
+
["sagemaker", "aws-sagemaker"],
|
|
103
|
+
["sambanova", "sambanova"],
|
|
104
|
+
["together_ai", "together"],
|
|
105
|
+
["vertex_ai", "vertex-ai"],
|
|
106
|
+
["watsonx", "watsonx"],
|
|
107
|
+
["xai", "xai"],
|
|
108
|
+
["xinference", "xinference"],
|
|
109
|
+
]);
|
|
110
|
+
|
|
111
|
+
// Google API resource collections that hold a model name, as in
|
|
112
|
+
// `models/gemini-1.5-flash` or `tunedModels/my-model`.
|
|
113
|
+
const GOOGLE_MODEL_COLLECTIONS = new Set(["models", "tunedModels"]);
|
|
114
|
+
|
|
115
|
+
// Model name prefixes that only one creator publishes under. A prefix, not a
|
|
116
|
+
// substring, so a community fine-tune such as openhermes-2.5-mistral-7b is
|
|
117
|
+
// not credited to Mistral AI. The OpenAI entries name its model lines,
|
|
118
|
+
// because a bare gpt prefix also covers open-weight families from other
|
|
119
|
+
// creators (gpt-j, gpt-neo, gpt-neox, gpt-sw3, gpt4all).
|
|
120
|
+
const MODEL_NAME_CREATOR_PREFIXES = [
|
|
121
|
+
["chatgpt", "openai"],
|
|
122
|
+
["claude", "anthropic"],
|
|
123
|
+
["codestral", "mistral"],
|
|
124
|
+
["command-r", "cohere"],
|
|
125
|
+
["dall-e", "openai"],
|
|
126
|
+
["deepseek", "deepseek"],
|
|
127
|
+
["gemini", "google"],
|
|
128
|
+
["gemma", "google"],
|
|
129
|
+
["glm", "zhipu"],
|
|
130
|
+
["gpt-3", "openai"],
|
|
131
|
+
["gpt-4", "openai"],
|
|
132
|
+
["gpt-5", "openai"],
|
|
133
|
+
["gpt-audio", "openai"],
|
|
134
|
+
["gpt-image", "openai"],
|
|
135
|
+
["gpt-oss", "openai"],
|
|
136
|
+
["gpt-realtime", "openai"],
|
|
137
|
+
["gpt2", "openai"],
|
|
138
|
+
["grok", "xai"],
|
|
139
|
+
["llama", "meta"],
|
|
140
|
+
["meta-llama", "meta"],
|
|
141
|
+
["mistral", "mistral"],
|
|
142
|
+
["mixtral", "mistral"],
|
|
143
|
+
["qwen", "alibaba"],
|
|
144
|
+
["text-embedding-3", "openai"],
|
|
145
|
+
["text-embedding-ada", "openai"],
|
|
146
|
+
];
|
|
147
|
+
|
|
148
|
+
// Spellings of a creator's name, compared after lowercasing and dropping
|
|
149
|
+
// everything but letters and digits. They cover the creator ids, the full
|
|
150
|
+
// names, the creators' own Hugging Face organisations and the way GGUF
|
|
151
|
+
// converters write general.organization ("Meta Llama", "Mistralai").
|
|
152
|
+
const MODEL_CREATOR_ALIASES = new Map([
|
|
153
|
+
["alibaba", "alibaba"],
|
|
154
|
+
["alibabacloud", "alibaba"],
|
|
155
|
+
["qwen", "alibaba"],
|
|
156
|
+
["anthropic", "anthropic"],
|
|
157
|
+
["cohere", "cohere"],
|
|
158
|
+
["cohereforai", "cohere"],
|
|
159
|
+
["coherelabs", "cohere"],
|
|
160
|
+
["deepseek", "deepseek"],
|
|
161
|
+
["deepseekai", "deepseek"],
|
|
162
|
+
["google", "google"],
|
|
163
|
+
["googledeepmind", "google"],
|
|
164
|
+
["facebook", "meta"],
|
|
165
|
+
["meta", "meta"],
|
|
166
|
+
["metallama", "meta"],
|
|
167
|
+
["mistral", "mistral"],
|
|
168
|
+
["mistralai", "mistral"],
|
|
169
|
+
["openai", "openai"],
|
|
170
|
+
["xai", "xai"],
|
|
171
|
+
["xaiorg", "xai"],
|
|
172
|
+
["thudm", "zhipu"],
|
|
173
|
+
["zaiorg", "zhipu"],
|
|
174
|
+
["zhipu", "zhipu"],
|
|
175
|
+
["zhipuai", "zhipu"],
|
|
176
|
+
]);
|
|
177
|
+
|
|
178
|
+
const normalizeProviderId = (provider) =>
|
|
179
|
+
typeof provider === "string" ? provider.trim().toLowerCase() : "";
|
|
180
|
+
|
|
181
|
+
const aliasKey = (value) =>
|
|
182
|
+
String(value || "")
|
|
183
|
+
.toLowerCase()
|
|
184
|
+
.replace(/[^a-z0-9]/gu, "");
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Split a model reference written in source code into the route provider it
|
|
188
|
+
* names, if any, and the model name a creator lookup should read.
|
|
189
|
+
*
|
|
190
|
+
* `groq/llama3-8b-8192` names the groq route and the model `llama3-8b-8192`.
|
|
191
|
+
* `models/gemini-1.5-flash`, `tunedModels/x` and
|
|
192
|
+
* `projects/p/locations/l/publishers/google/models/gemini-1.5-pro` are Google
|
|
193
|
+
* API resource names, and the model is the part after the last `models`
|
|
194
|
+
* segment. Neither form is a Hugging Face repository id.
|
|
195
|
+
*
|
|
196
|
+
* @param {string} modelId Model reference as written in the source
|
|
197
|
+
* @returns {{ name: string, nonHub: boolean, route?: string, routeProvider?: string }}
|
|
198
|
+
* The model name, whether the reference is not a Hub repository id, and the
|
|
199
|
+
* route and its provider when one is named
|
|
200
|
+
*/
|
|
201
|
+
export function splitModelReference(modelId) {
|
|
202
|
+
const value = String(modelId || "").trim();
|
|
203
|
+
const segments = value.split("/");
|
|
204
|
+
if (segments.length < 2 || segments.some((segment) => !segment)) {
|
|
205
|
+
return { name: value, nonHub: false };
|
|
206
|
+
}
|
|
207
|
+
if (GOOGLE_MODEL_COLLECTIONS.has(segments[0])) {
|
|
208
|
+
return { name: segments.slice(1).join("/"), nonHub: true };
|
|
209
|
+
}
|
|
210
|
+
const publishersIndex = segments.indexOf("publishers");
|
|
211
|
+
const modelsIndex = segments.lastIndexOf("models");
|
|
212
|
+
if (publishersIndex >= 0 && modelsIndex > publishersIndex) {
|
|
213
|
+
return { name: segments.slice(modelsIndex + 1).join("/"), nonHub: true };
|
|
214
|
+
}
|
|
215
|
+
const routeProvider = MODEL_ROUTE_PROVIDERS.get(segments[0]);
|
|
216
|
+
if (routeProvider) {
|
|
217
|
+
return {
|
|
218
|
+
name: segments.slice(1).join("/"),
|
|
219
|
+
nonHub: true,
|
|
220
|
+
route: segments[0],
|
|
221
|
+
routeProvider,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
return { name: value, nonHub: false };
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Name the creator of a model from its name alone, when only one creator
|
|
229
|
+
* publishes under that name.
|
|
230
|
+
*
|
|
231
|
+
* @param {string} modelName Model name without route or namespace
|
|
232
|
+
* @returns {string|undefined} Creator id
|
|
233
|
+
*/
|
|
234
|
+
export function modelCreatorFromName(modelName) {
|
|
235
|
+
const normalized = String(modelName || "")
|
|
236
|
+
.trim()
|
|
237
|
+
.toLowerCase();
|
|
238
|
+
for (const [prefix, creator] of MODEL_NAME_CREATOR_PREFIXES) {
|
|
239
|
+
if (normalized.startsWith(prefix)) {
|
|
240
|
+
return creator;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return /^o[134](?:$|[-:])/u.test(normalized) ? "openai" : undefined;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Resolve a creator spelling, such as a Hugging Face organisation or a
|
|
248
|
+
* GGUF general.organization value, to a known creator id.
|
|
249
|
+
*
|
|
250
|
+
* @param {string} name Organisation name or namespace
|
|
251
|
+
* @returns {string|undefined} Creator id, or undefined when unknown
|
|
252
|
+
*/
|
|
253
|
+
export function modelCreatorFromOrganization(name) {
|
|
254
|
+
return MODEL_CREATOR_ALIASES.get(aliasKey(name));
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Pick the creator of a model that source code calls by name.
|
|
259
|
+
*
|
|
260
|
+
* The provider of such a model is the SDK, AI host or route the code uses,
|
|
261
|
+
* which names the client rather than the model: the openai SDK is the usual
|
|
262
|
+
* client for self-hosted Llama or DeepSeek servers, and a file may use
|
|
263
|
+
* several SDKs. So the creator is the one the model name names, when the
|
|
264
|
+
* provider is that creator, is a hosting or routing service, or the file
|
|
265
|
+
* also uses the creator's own SDK or host. A different creator's SDK leaves
|
|
266
|
+
* it unset. A model name that names no creator is credited only to a
|
|
267
|
+
* provider whose own API serves nothing but its own models. A local runtime
|
|
268
|
+
* serves whatever tag the user created, so it names no creator, and neither
|
|
269
|
+
* does a file that only uses a local runtime.
|
|
270
|
+
*
|
|
271
|
+
* @param {string} modelId Model reference as written in the source
|
|
272
|
+
* @param {{ provider?: string, fileProviders?: Iterable<string>, runtimes?: Iterable<string> }} [context]
|
|
273
|
+
* The provider the code declares through an SDK import, AI host or dosai
|
|
274
|
+
* report (never a guess from the model name), every provider the file
|
|
275
|
+
* references, and the runtimes it uses
|
|
276
|
+
* @returns {string|undefined} Creator id
|
|
277
|
+
*/
|
|
278
|
+
export function resolveModelCreator(modelId, context = {}) {
|
|
279
|
+
const reference = splitModelReference(modelId);
|
|
280
|
+
const provider = normalizeProviderId(
|
|
281
|
+
reference.routeProvider || context.provider,
|
|
282
|
+
);
|
|
283
|
+
if (LOCAL_MODEL_RUNTIMES.has(provider)) {
|
|
284
|
+
return undefined;
|
|
285
|
+
}
|
|
286
|
+
if (
|
|
287
|
+
!provider &&
|
|
288
|
+
[...(context.runtimes || [])].some((runtime) =>
|
|
289
|
+
LOCAL_MODEL_RUNTIMES.has(normalizeProviderId(runtime)),
|
|
290
|
+
)
|
|
291
|
+
) {
|
|
292
|
+
return undefined;
|
|
293
|
+
}
|
|
294
|
+
const nameCreator = modelCreatorFromName(reference.name);
|
|
295
|
+
const providerCreator = CREATOR_OWN_PROVIDERS.get(provider);
|
|
296
|
+
if (!nameCreator) {
|
|
297
|
+
return SINGLE_CATALOGUE_CREATORS.has(providerCreator)
|
|
298
|
+
? providerCreator
|
|
299
|
+
: undefined;
|
|
300
|
+
}
|
|
301
|
+
if (!providerCreator || providerCreator === nameCreator) {
|
|
302
|
+
return nameCreator;
|
|
303
|
+
}
|
|
304
|
+
for (const fileProvider of context.fileProviders || []) {
|
|
305
|
+
if (
|
|
306
|
+
CREATOR_OWN_PROVIDERS.get(normalizeProviderId(fileProvider)) ===
|
|
307
|
+
nameCreator
|
|
308
|
+
) {
|
|
309
|
+
return nameCreator;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return undefined;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Build the CycloneDX organisational entity for a creator id.
|
|
317
|
+
*
|
|
318
|
+
* @param {string} creator Creator id
|
|
319
|
+
* @returns {{ name: string }|undefined} Manufacturer entity
|
|
320
|
+
*/
|
|
321
|
+
export function modelCreatorEntity(creator) {
|
|
322
|
+
const name = MODEL_CREATOR_NAMES.get(creator);
|
|
323
|
+
return name ? { name } : undefined;
|
|
324
|
+
}
|
|
@@ -183,6 +183,7 @@ export function findCompileCommands(src, options = {}) {
|
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
const atomFrontendArgKeysCache = new Map();
|
|
186
|
+
const atomOptionsCache = new Map();
|
|
186
187
|
|
|
187
188
|
/**
|
|
188
189
|
* Split an atom command that may carry a leading argument (`node
|
|
@@ -271,6 +272,43 @@ export function atomFrontendArgKeys(language) {
|
|
|
271
272
|
return keys;
|
|
272
273
|
}
|
|
273
274
|
|
|
275
|
+
/**
|
|
276
|
+
* The options the installed atom accepts, as `atom --help` lists them. Asked
|
|
277
|
+
* once per atom command. An atom that fails to start accepts none.
|
|
278
|
+
*
|
|
279
|
+
* @returns {Set<string>} Supported options, such as `--bom-file`
|
|
280
|
+
*/
|
|
281
|
+
export function atomOptions() {
|
|
282
|
+
const command = getAtomCommand();
|
|
283
|
+
if (atomOptionsCache.has(command)) {
|
|
284
|
+
return atomOptionsCache.get(command);
|
|
285
|
+
}
|
|
286
|
+
const [bin, leadingArg] = splitAtomCommand(command);
|
|
287
|
+
const args = ["--help"];
|
|
288
|
+
if (leadingArg !== undefined) {
|
|
289
|
+
args.unshift(leadingArg);
|
|
290
|
+
}
|
|
291
|
+
const env = { ...process.env };
|
|
292
|
+
if (readEnvironmentVariable("ATOM_JAVA_HOME")) {
|
|
293
|
+
env.JAVA_HOME = readEnvironmentVariable("ATOM_JAVA_HOME");
|
|
294
|
+
}
|
|
295
|
+
const options = new Set();
|
|
296
|
+
const result = safeSpawnSync(bin, args, {
|
|
297
|
+
shell: isWin,
|
|
298
|
+
env,
|
|
299
|
+
timeout: 120000,
|
|
300
|
+
});
|
|
301
|
+
if (result?.status === 0 && result.stdout) {
|
|
302
|
+
for (const match of `${result.stdout}`.matchAll(
|
|
303
|
+
/(?:^|\s)(--[a-z][a-z0-9-]*)/g,
|
|
304
|
+
)) {
|
|
305
|
+
options.add(match[1]);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
atomOptionsCache.set(command, options);
|
|
309
|
+
return options;
|
|
310
|
+
}
|
|
311
|
+
|
|
274
312
|
/**
|
|
275
313
|
* The `--frontend-args` atom takes for a C/C++ language: the project's
|
|
276
314
|
* compilation database, when there is one and the installed atom reads it
|
|
@@ -315,6 +353,45 @@ export function atomCompileCommandsArgs(src, language, options = {}) {
|
|
|
315
353
|
return ["--frontend-args", `compile-commands=${database}`];
|
|
316
354
|
}
|
|
317
355
|
|
|
356
|
+
/**
|
|
357
|
+
* The `--bom-file` a reachables slice takes package purls from: the BOM evinse
|
|
358
|
+
* annotates. atom would otherwise only find a BOM saved as `bom.json` inside
|
|
359
|
+
* the scanned directory, so a BOM written anywhere else gave every reachable
|
|
360
|
+
* flow no purl. An atom without `--bom-file` is given the arguments it has
|
|
361
|
+
* always been given, and still reads a `bom.json` in the scanned directory.
|
|
362
|
+
*
|
|
363
|
+
* @param {string} sliceType atom slice command
|
|
364
|
+
* @param {Object} options CLI options, for `input`
|
|
365
|
+
* @returns {string[]} Arguments to add to the atom command
|
|
366
|
+
*/
|
|
367
|
+
export function atomBomFileArgs(sliceType, options = {}) {
|
|
368
|
+
if (
|
|
369
|
+
sliceType !== "reachables" ||
|
|
370
|
+
!options?.input ||
|
|
371
|
+
!safeExistsSync(options.input)
|
|
372
|
+
) {
|
|
373
|
+
return [];
|
|
374
|
+
}
|
|
375
|
+
const bomFile = resolve(options.input);
|
|
376
|
+
// The argument reaches a Windows shell command line through `shell: isWin`
|
|
377
|
+
// in executeAtom, so a path a shell would interpret is never passed on.
|
|
378
|
+
if (UNSAFE_SHELL_CHARS_RE.test(bomFile)) {
|
|
379
|
+
console.warn(
|
|
380
|
+
`The BOM path ${bomFile} contains characters a shell would interpret. Reachable flows will carry purls only if a bom.json is in the scanned directory.`,
|
|
381
|
+
);
|
|
382
|
+
return [];
|
|
383
|
+
}
|
|
384
|
+
if (!atomOptions().has("--bom-file")) {
|
|
385
|
+
if (DEBUG_MODE) {
|
|
386
|
+
console.log(
|
|
387
|
+
"The installed atom does not take --bom-file. Reachable flows will carry purls only if a bom.json is in the scanned directory.",
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
return [];
|
|
391
|
+
}
|
|
392
|
+
return ["--bom-file", bomFile];
|
|
393
|
+
}
|
|
394
|
+
|
|
318
395
|
/**
|
|
319
396
|
* The arguments that stop atom's Java frontend from running the scanned
|
|
320
397
|
* project's build. In its default delombok mode, atom runs
|
|
@@ -43,6 +43,13 @@ const COMPONENT_TYPES_1_5 = [
|
|
|
43
43
|
"data",
|
|
44
44
|
];
|
|
45
45
|
const COMPONENT_TYPES_1_6 = [...COMPONENT_TYPES_1_5, "cryptographic-asset"];
|
|
46
|
+
// CycloneDX 2.0 keeps every 1.6 type and turns services into components of
|
|
47
|
+
// type `service` (`#/$defs/cyclonedx-component-2.0/$defs/component/properties/type`),
|
|
48
|
+
// next to the new physical type `material`. The draft's enum, quoted:
|
|
49
|
+
// application, framework, library, container, platform, operating-system,
|
|
50
|
+
// device, device-driver, firmware, file, machine-learning-model, data,
|
|
51
|
+
// cryptographic-asset, material, service.
|
|
52
|
+
const COMPONENT_TYPES_2_0 = [...COMPONENT_TYPES_1_6, "material", "service"];
|
|
46
53
|
|
|
47
54
|
/**
|
|
48
55
|
* Frozen map of CycloneDX spec versions (as "major.minor" strings) to the
|
|
@@ -53,7 +60,7 @@ export const CYCLONEDX_COMPONENT_TYPES_BY_SPEC_VERSION = Object.freeze({
|
|
|
53
60
|
1.5: Object.freeze(COMPONENT_TYPES_1_5),
|
|
54
61
|
1.6: Object.freeze(COMPONENT_TYPES_1_6),
|
|
55
62
|
1.7: Object.freeze(COMPONENT_TYPES_1_6),
|
|
56
|
-
"2.0": Object.freeze(
|
|
63
|
+
"2.0": Object.freeze(COMPONENT_TYPES_2_0),
|
|
57
64
|
});
|
|
58
65
|
|
|
59
66
|
/**
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// BOM components for the Brotli decoders compiled into native files. The
|
|
2
|
+
// detection itself, and why its markers can be trusted, is in
|
|
3
|
+
// lib/core/brotliProbe.js.
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
MAX_BROTLI_PROBE_BYTES,
|
|
7
|
+
MAX_BROTLI_PROBES,
|
|
8
|
+
readBrotliDecoder,
|
|
9
|
+
} from "../core/brotliProbe.js";
|
|
10
|
+
import { applyPurl, tryBuildPurl } from "./purl.js";
|
|
11
|
+
|
|
12
|
+
export { MAX_BROTLI_PROBE_BYTES, MAX_BROTLI_PROBES, readBrotliDecoder };
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The properties a file component carries once it has been probed: the fix
|
|
16
|
+
* state of each decoder found in it, or why it could not be read.
|
|
17
|
+
*
|
|
18
|
+
* @param {Object} decoder result of readBrotliDecoder
|
|
19
|
+
* @returns {{name: string, value: string}[]} properties to append
|
|
20
|
+
*/
|
|
21
|
+
export function brotliDecoderProperties(decoder) {
|
|
22
|
+
const properties = [];
|
|
23
|
+
if (decoder?.skipped) {
|
|
24
|
+
properties.push({ name: "cdx:brotli:probe", value: decoder.skipped });
|
|
25
|
+
}
|
|
26
|
+
if (decoder?.c) {
|
|
27
|
+
properties.push(
|
|
28
|
+
{ name: "cdx:brotli:c:blockSwitchFix", value: decoder.c.blockSwitchFix },
|
|
29
|
+
{ name: "cdx:brotli:c:evidence", value: decoder.c.evidence },
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
if (decoder?.go) {
|
|
33
|
+
properties.push({
|
|
34
|
+
name: "cdx:brotli:go:blockSwitchFix",
|
|
35
|
+
value: decoder.go.blockSwitchFix,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return properties;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The library component every embedded decoder links to. It has no version:
|
|
43
|
+
* no build records one, and only the per-file cdx:brotli:*:blockSwitchFix
|
|
44
|
+
* properties say whether a copy is vulnerable. The `vcs_url` qualifier names
|
|
45
|
+
* the project and keeps the identity apart from an unpackaged `brotli`
|
|
46
|
+
* executable, which is `pkg:generic/brotli`. The purl has no namespace: a
|
|
47
|
+
* `pkg:github` purl is typed as an application and `pkg:generic/google` as a
|
|
48
|
+
* framework when the BOM is assembled, and this is neither.
|
|
49
|
+
*
|
|
50
|
+
* @returns {Object} component with `purl` and `bom-ref`
|
|
51
|
+
*/
|
|
52
|
+
export function createBrotliComponent() {
|
|
53
|
+
return applyPurl(
|
|
54
|
+
{
|
|
55
|
+
type: "library",
|
|
56
|
+
name: "brotli",
|
|
57
|
+
description:
|
|
58
|
+
"Brotli decoder compiled into native files; see the cdx:brotli properties on each file",
|
|
59
|
+
properties: [],
|
|
60
|
+
},
|
|
61
|
+
tryBuildPurl({
|
|
62
|
+
type: "generic",
|
|
63
|
+
name: "brotli",
|
|
64
|
+
qualifiers: { vcs_url: "git+https://github.com/google/brotli" },
|
|
65
|
+
}),
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Start collecting the decoder copies of one scan.
|
|
71
|
+
*
|
|
72
|
+
* @returns {{component: Object|undefined, dependencies: Object[], copies: number, unpatched: number, unknown: number}}
|
|
73
|
+
*/
|
|
74
|
+
export function createBrotliInventory() {
|
|
75
|
+
return {
|
|
76
|
+
component: undefined,
|
|
77
|
+
dependencies: [],
|
|
78
|
+
copies: 0,
|
|
79
|
+
unpatched: 0,
|
|
80
|
+
unknown: 0,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Tag a probed file component and, when it holds a decoder, link it to the
|
|
86
|
+
* shared brotli component, creating that component on first use. Mutates the
|
|
87
|
+
* file component in place.
|
|
88
|
+
*
|
|
89
|
+
* @param {Object} inventory accumulator from createBrotliInventory
|
|
90
|
+
* @param {Object} fileComponent file component with a `properties` array
|
|
91
|
+
* @param {Object} decoder result of readBrotliDecoder
|
|
92
|
+
*/
|
|
93
|
+
export function attachBrotliDecoder(inventory, fileComponent, decoder) {
|
|
94
|
+
const properties = brotliDecoderProperties(decoder);
|
|
95
|
+
if (!properties.length) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
fileComponent.properties.push(...properties);
|
|
99
|
+
if (!decoder.c && !decoder.go) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (!inventory.component) {
|
|
103
|
+
inventory.component = createBrotliComponent();
|
|
104
|
+
}
|
|
105
|
+
const states = [decoder.c?.blockSwitchFix, decoder.go?.blockSwitchFix];
|
|
106
|
+
inventory.copies += 1;
|
|
107
|
+
if (states.includes("false")) {
|
|
108
|
+
inventory.unpatched += 1;
|
|
109
|
+
} else if (states.includes("unknown")) {
|
|
110
|
+
inventory.unknown += 1;
|
|
111
|
+
}
|
|
112
|
+
if (fileComponent["bom-ref"] && inventory.component["bom-ref"]) {
|
|
113
|
+
inventory.dependencies.push({
|
|
114
|
+
ref: fileComponent["bom-ref"],
|
|
115
|
+
dependsOn: [inventory.component["bom-ref"]],
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Finish an inventory: record the copy counts on the brotli component.
|
|
122
|
+
*
|
|
123
|
+
* @param {Object} inventory accumulator from createBrotliInventory
|
|
124
|
+
* @returns {{components: Object[], dependencies: Object[]}} what to add to the BOM
|
|
125
|
+
*/
|
|
126
|
+
export function finishBrotliInventory(inventory) {
|
|
127
|
+
if (!inventory?.component) {
|
|
128
|
+
return { components: [], dependencies: [] };
|
|
129
|
+
}
|
|
130
|
+
inventory.component.properties = [
|
|
131
|
+
{ name: "cdx:brotli:embeddedCopies", value: String(inventory.copies) },
|
|
132
|
+
{ name: "cdx:brotli:unpatchedCopies", value: String(inventory.unpatched) },
|
|
133
|
+
{ name: "cdx:brotli:unknownCopies", value: String(inventory.unknown) },
|
|
134
|
+
];
|
|
135
|
+
return {
|
|
136
|
+
components: [inventory.component],
|
|
137
|
+
dependencies: [
|
|
138
|
+
{ ref: inventory.component["bom-ref"], dependsOn: [] },
|
|
139
|
+
...inventory.dependencies,
|
|
140
|
+
],
|
|
141
|
+
};
|
|
142
|
+
}
|
|
@@ -129,7 +129,7 @@ export function noteBuildToolRateLimit(tool, output, context = {}) {
|
|
|
129
129
|
? `, so cdxgen runs no further ${tool} resolution in this scan and`
|
|
130
130
|
: ", so";
|
|
131
131
|
console.warn(
|
|
132
|
-
`The repository ${tool} downloads from is rate limiting this machine (HTTP 429)${stopped} its dependency tree is incomplete. ${MIRROR_SETTINGS[tool] || MIRROR_SETTINGS[TOOL_MATCHER[tool]]}
|
|
132
|
+
`The repository ${tool} downloads from is rate limiting this machine (HTTP 429)${stopped} its dependency tree is incomplete. ${MIRROR_SETTINGS[tool] || MIRROR_SETTINGS[TOOL_MATCHER[tool]]} Set MAVEN_CENTRAL_MIRROR=true to point every build tool at Google's Maven Central mirror, or MAVEN_CENTRAL_URL for cdxgen's own lookups.`,
|
|
133
133
|
);
|
|
134
134
|
recordDegradation("build.rate-limited", {
|
|
135
135
|
ecosystem: "java",
|