@cdxgen/cdxgen 13.3.0 → 13.5.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 +12 -9
- package/bin/cdxgen-secure.js +15 -0
- package/bin/cdxgen.js +115 -31
- package/bin/evinse.js +23 -1
- package/bin/hbom.js +15 -7
- package/bin/repl.js +115 -0
- package/bin/sign.js +45 -15
- package/bin/tracebom.js +5 -1
- package/bin/validate.js +84 -18
- package/bin/verify.js +155 -86
- package/data/cbomosdb-queries.json +13 -1
- package/data/component-tags.json +8 -0
- package/data/helpers/init.gradle +46 -21
- package/data/queries-darwin.json +25 -1
- package/data/queries-win.json +19 -1
- package/data/queries.json +41 -0
- package/data/remediations.json +344 -1
- package/data/rules/cbom-security.yaml +235 -4
- package/data/rules/dependency-sources.yaml +67 -0
- package/data/rules/go-binaries.yaml +46 -0
- package/data/rules/golem-go.yaml +80 -0
- package/data/rules/hbom-compliance.yaml +40 -22
- package/data/rules/hbom-performance.yaml +7 -1
- package/data/rules/host-topology.yaml +1 -1
- package/data/rules/obom-runtime.yaml +31 -2
- package/data/rules/php-runtime.yaml +143 -0
- package/data/rules/scala-evidence.yaml +115 -0
- package/lib/audit/index.js +52 -6
- package/lib/cli/bomAssembly.js +28 -3
- package/lib/cli/cliOptions.js +110 -3
- package/lib/cli/index.js +186 -58
- package/lib/cli/jsBom.js +50 -29
- package/lib/cli/jvmBom.js +779 -146
- package/lib/cli/managedBom.js +1021 -261
- package/lib/cli/nativeBom.js +364 -58
- package/lib/core/activity.js +12 -0
- package/lib/core/env.js +47 -17
- package/lib/core/fs.js +31 -21
- package/lib/core/httpClient.js +233 -69
- package/lib/core/pluginRun.js +184 -0
- package/lib/core/processTree.js +100 -0
- package/lib/core/projectConfig.js +1 -0
- package/lib/core/projectTooling.js +97 -0
- package/lib/core/propertySanitizer.js +72 -0
- package/lib/core/runState.js +39 -0
- package/lib/core/toml.js +72 -0
- package/lib/ecosystems/asarutils.js +4 -2
- package/lib/ecosystems/bunutils.js +5 -7
- package/lib/ecosystems/cargoCache.js +231 -8
- package/lib/ecosystems/cmakeResolver.js +10 -21
- package/lib/ecosystems/cppBuildContext.js +631 -0
- package/lib/ecosystems/cppEvidence.js +337 -22
- package/lib/ecosystems/cppIncludeResolver.js +294 -0
- package/lib/ecosystems/denoutils.js +93 -66
- package/lib/ecosystems/ecosystems.js +1967 -788
- package/lib/ecosystems/golem.js +578 -18
- package/lib/ecosystems/gradleutils.js +340 -46
- package/lib/ecosystems/jsEvidence.js +85 -24
- package/lib/ecosystems/kosi.js +21 -4
- package/lib/ecosystems/npmutils.js +64 -0
- package/lib/ecosystems/parsers-dotnet.js +668 -153
- package/lib/ecosystems/parsers-elm.js +46 -28
- package/lib/ecosystems/parsers-gleam.js +3 -4
- package/lib/ecosystems/parsers-go.js +1283 -297
- package/lib/ecosystems/parsers-js.js +92 -26
- package/lib/ecosystems/parsers-julia.js +2 -3
- package/lib/ecosystems/parsers-jvm.js +463 -29
- package/lib/ecosystems/parsers-misc.js +405 -93
- package/lib/ecosystems/parsers-python.js +152 -20
- package/lib/ecosystems/parsers-rust.js +4 -4
- package/lib/ecosystems/parsers-terraform.js +1573 -19
- package/lib/ecosystems/pythonutils.js +102 -6
- package/lib/ecosystems/remote/huggingface.js +3 -0
- package/lib/ecosystems/rubyutils.js +73 -20
- package/lib/ecosystems/rusi.js +32 -9
- package/lib/ecosystems/sbtutils.js +243 -187
- package/lib/ecosystems/scalacliutils.js +343 -0
- package/lib/ecosystems/scalasem.js +2620 -0
- package/lib/ecosystems/terraformRegistry.js +288 -0
- package/lib/ecosystems/utils.js +2 -0
- package/lib/ecosystems/vendoredCode.js +156 -0
- package/lib/evinser/evinser.js +695 -78
- package/lib/evinser/swiftsem.js +68 -5
- package/lib/helpers/agenticToolutils.js +2 -2
- package/lib/helpers/bomSigner.js +576 -128
- package/lib/inventory/agentSkillSpec.js +17 -0
- package/lib/inventory/aiCollector.js +4 -1
- package/lib/inventory/analyzer.js +110 -127
- package/lib/inventory/apkInstalledDb.js +243 -0
- package/lib/inventory/atomUtils.js +204 -48
- package/lib/inventory/auditCategories.js +10 -3
- package/lib/inventory/buildToolRateLimit.js +144 -0
- package/lib/inventory/cacheCommands.js +2 -1
- package/lib/inventory/cacheDir.js +52 -9
- package/lib/inventory/certificates.js +2371 -0
- package/lib/inventory/cmakeBuildDirs.js +254 -0
- package/lib/inventory/communityAiConfigParser.js +4 -9
- package/lib/inventory/deps.js +507 -128
- package/lib/inventory/display.js +200 -3
- package/lib/inventory/dosai.js +747 -101
- package/lib/inventory/dosaiParsers.js +310 -15
- package/lib/inventory/dynamic.js +96 -8
- package/lib/inventory/envcontext.js +168 -5
- package/lib/inventory/evidenceUtils.js +590 -132
- package/lib/inventory/fetchBatch.js +574 -38
- package/lib/inventory/fetchDiskCache.js +597 -0
- package/lib/inventory/forgeEnricher.js +14 -5
- package/lib/inventory/formulationParsers.js +3 -2
- package/lib/inventory/goBuildInfo.js +140 -0
- package/lib/inventory/hbom.js +67 -7
- package/lib/inventory/hbomAnalysis.js +16 -0
- package/lib/inventory/hostTopology.js +21 -0
- package/lib/inventory/jvmLocalRepos.js +917 -0
- package/lib/inventory/mcpConfigParser.js +2 -3
- package/lib/inventory/osPackagePurl.js +244 -0
- package/lib/inventory/osPackageResolver.js +89 -87
- package/lib/inventory/osinfo.js +79 -31
- package/lib/inventory/osqueryTransform.js +114 -5
- package/lib/inventory/parentSelection.js +146 -0
- package/lib/inventory/phpBuildInfo.js +487 -0
- package/lib/inventory/phpHostProbe.js +641 -0
- package/lib/inventory/rootfsCerts.js +426 -0
- package/lib/inventory/rustFormulationParser.js +3 -4
- package/lib/inventory/scalaCoords.js +153 -0
- package/lib/inventory/source.js +215 -11
- package/lib/inventory/spdx.js +245 -0
- package/lib/inventory/traceRunner.js +93 -8
- package/lib/inventory/tracedCrypto.js +423 -0
- package/lib/managers/binary.js +529 -183
- package/lib/managers/docker.js +199 -44
- package/lib/managers/oci.js +24 -2
- package/lib/parsers/cmakeCache.js +69 -0
- package/lib/parsers/cmakeLists.js +16 -2
- package/lib/parsers/cmakePresets.js +400 -0
- package/lib/parsers/compileCommands.js +557 -0
- package/lib/parsers/email.js +277 -0
- package/lib/parsers/largeJson.js +34 -2
- package/lib/parsers/strictJson.js +322 -0
- package/lib/parsers/terraformConfig.js +1073 -0
- package/lib/parsers/terraformSource.js +652 -0
- package/lib/server/server.js +209 -1
- package/lib/stages/postgen/annotator.js +17 -1
- package/lib/stages/postgen/introspection/markers.js +1 -1
- package/lib/stages/postgen/introspection/reflect.js +4 -1
- package/lib/stages/postgen/postgen.js +20 -6
- package/lib/stages/postgen/ruleEngine.js +58 -1
- package/lib/stages/postgen/specVersionCompat.js +62 -0
- package/lib/stages/pregen/pregen.js +117 -5
- package/lib/validator/bomValidator.js +26 -5
- package/lib/validator/generated/runtime.mjs +13 -0
- package/lib/validator/generated/validate-1.6.mjs +26 -7
- package/lib/validator/generated/validate-1.7.mjs +31 -12
- package/lib/validator/generated/validate-2.0.mjs +30 -11
- package/lib/validator/index.js +25 -10
- package/lib/validator/reporters/json.js +1 -0
- package/package.json +23 -23
- package/types/bin/cdxgen-secure.d.ts +3 -0
- package/types/bin/cdxgen-secure.d.ts.map +1 -0
- package/types/bin/repl.d.ts.map +1 -1
- package/types/lib/audit/index.d.ts.map +1 -1
- package/types/lib/cli/bomAssembly.d.ts +9 -2
- package/types/lib/cli/bomAssembly.d.ts.map +1 -1
- package/types/lib/cli/cliOptions.d.ts +43 -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.map +1 -1
- package/types/lib/cli/jvmBom.d.ts +44 -1
- package/types/lib/cli/jvmBom.d.ts.map +1 -1
- package/types/lib/cli/managedBom.d.ts +7 -4
- package/types/lib/cli/managedBom.d.ts.map +1 -1
- package/types/lib/cli/nativeBom.d.ts +3 -1
- package/types/lib/cli/nativeBom.d.ts.map +1 -1
- package/types/lib/core/activity.d.ts.map +1 -1
- package/types/lib/core/env.d.ts +27 -2
- package/types/lib/core/env.d.ts.map +1 -1
- package/types/lib/core/fs.d.ts.map +1 -1
- package/types/lib/core/httpClient.d.ts +13 -8
- package/types/lib/core/httpClient.d.ts.map +1 -1
- package/types/lib/core/pluginRun.d.ts +97 -0
- package/types/lib/core/pluginRun.d.ts.map +1 -0
- package/types/lib/core/processTree.d.ts +36 -0
- package/types/lib/core/processTree.d.ts.map +1 -0
- package/types/lib/core/projectConfig.d.ts.map +1 -1
- package/types/lib/core/projectTooling.d.ts +41 -0
- package/types/lib/core/projectTooling.d.ts.map +1 -0
- package/types/lib/core/propertySanitizer.d.ts +26 -0
- package/types/lib/core/propertySanitizer.d.ts.map +1 -1
- package/types/lib/core/runState.d.ts +29 -0
- package/types/lib/core/runState.d.ts.map +1 -0
- package/types/lib/core/toml.d.ts +20 -0
- package/types/lib/core/toml.d.ts.map +1 -0
- package/types/lib/ecosystems/asarutils.d.ts.map +1 -1
- package/types/lib/ecosystems/bunutils.d.ts.map +1 -1
- package/types/lib/ecosystems/cargoCache.d.ts +12 -0
- package/types/lib/ecosystems/cargoCache.d.ts.map +1 -1
- package/types/lib/ecosystems/cmakeResolver.d.ts +5 -3
- package/types/lib/ecosystems/cmakeResolver.d.ts.map +1 -1
- package/types/lib/ecosystems/cppBuildContext.d.ts +55 -0
- package/types/lib/ecosystems/cppBuildContext.d.ts.map +1 -0
- package/types/lib/ecosystems/cppEvidence.d.ts +19 -3
- package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/cppIncludeResolver.d.ts +92 -0
- package/types/lib/ecosystems/cppIncludeResolver.d.ts.map +1 -0
- package/types/lib/ecosystems/denoutils.d.ts +9 -3
- package/types/lib/ecosystems/denoutils.d.ts.map +1 -1
- package/types/lib/ecosystems/ecosystems.d.ts +62 -13
- package/types/lib/ecosystems/ecosystems.d.ts.map +1 -1
- package/types/lib/ecosystems/golem.d.ts +81 -1
- package/types/lib/ecosystems/golem.d.ts.map +1 -1
- package/types/lib/ecosystems/gradleutils.d.ts +59 -7
- package/types/lib/ecosystems/gradleutils.d.ts.map +1 -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/npmutils.d.ts +15 -0
- package/types/lib/ecosystems/npmutils.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-dotnet.d.ts +155 -5
- package/types/lib/ecosystems/parsers-dotnet.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-elm.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-gleam.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-go.d.ts +119 -5
- package/types/lib/ecosystems/parsers-go.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-js.d.ts +6 -1
- package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-julia.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-jvm.d.ts +74 -3
- package/types/lib/ecosystems/parsers-jvm.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-misc.d.ts +21 -59
- package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-python.d.ts +57 -6
- package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-terraform.d.ts +38 -21
- package/types/lib/ecosystems/parsers-terraform.d.ts.map +1 -1
- package/types/lib/ecosystems/pythonutils.d.ts +26 -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 +21 -1
- package/types/lib/ecosystems/rubyutils.d.ts.map +1 -1
- package/types/lib/ecosystems/rusi.d.ts.map +1 -1
- package/types/lib/ecosystems/sbtutils.d.ts +88 -2
- package/types/lib/ecosystems/sbtutils.d.ts.map +1 -1
- package/types/lib/ecosystems/scalacliutils.d.ts +56 -0
- package/types/lib/ecosystems/scalacliutils.d.ts.map +1 -0
- package/types/lib/ecosystems/scalasem.d.ts +311 -0
- package/types/lib/ecosystems/scalasem.d.ts.map +1 -0
- package/types/lib/ecosystems/terraformRegistry.d.ts +9 -0
- package/types/lib/ecosystems/terraformRegistry.d.ts.map +1 -0
- package/types/lib/ecosystems/utils.d.ts +2 -2
- package/types/lib/ecosystems/utils.d.ts.map +1 -1
- package/types/lib/ecosystems/vendoredCode.d.ts +32 -0
- package/types/lib/ecosystems/vendoredCode.d.ts.map +1 -0
- package/types/lib/evinser/evinser.d.ts +100 -8
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/evinser/swiftsem.d.ts +10 -0
- package/types/lib/evinser/swiftsem.d.ts.map +1 -1
- package/types/lib/helpers/bomSigner.d.ts +80 -4
- package/types/lib/helpers/bomSigner.d.ts.map +1 -1
- package/types/lib/inventory/agentSkillSpec.d.ts +13 -0
- package/types/lib/inventory/agentSkillSpec.d.ts.map +1 -0
- package/types/lib/inventory/aiCollector.d.ts.map +1 -1
- package/types/lib/inventory/analyzer.d.ts.map +1 -1
- package/types/lib/inventory/apkInstalledDb.d.ts +42 -0
- package/types/lib/inventory/apkInstalledDb.d.ts.map +1 -0
- package/types/lib/inventory/atomUtils.d.ts +96 -10
- package/types/lib/inventory/atomUtils.d.ts.map +1 -1
- package/types/lib/inventory/auditCategories.d.ts +3 -0
- package/types/lib/inventory/auditCategories.d.ts.map +1 -1
- package/types/lib/inventory/buildToolRateLimit.d.ts +38 -0
- package/types/lib/inventory/buildToolRateLimit.d.ts.map +1 -0
- package/types/lib/inventory/cacheCommands.d.ts +2 -1
- package/types/lib/inventory/cacheCommands.d.ts.map +1 -1
- package/types/lib/inventory/cacheDir.d.ts +12 -4
- package/types/lib/inventory/cacheDir.d.ts.map +1 -1
- package/types/lib/inventory/certificates.d.ts +205 -0
- package/types/lib/inventory/certificates.d.ts.map +1 -0
- package/types/lib/inventory/cmakeBuildDirs.d.ts +58 -0
- package/types/lib/inventory/cmakeBuildDirs.d.ts.map +1 -0
- package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/deps.d.ts +61 -2
- package/types/lib/inventory/deps.d.ts.map +1 -1
- package/types/lib/inventory/display.d.ts +18 -0
- package/types/lib/inventory/display.d.ts.map +1 -1
- package/types/lib/inventory/dosai.d.ts +202 -14
- package/types/lib/inventory/dosai.d.ts.map +1 -1
- package/types/lib/inventory/dosaiParsers.d.ts +53 -7
- package/types/lib/inventory/dosaiParsers.d.ts.map +1 -1
- package/types/lib/inventory/dynamic.d.ts +16 -1
- package/types/lib/inventory/dynamic.d.ts.map +1 -1
- package/types/lib/inventory/envcontext.d.ts +40 -2
- package/types/lib/inventory/envcontext.d.ts.map +1 -1
- package/types/lib/inventory/evidenceUtils.d.ts +48 -14
- package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
- package/types/lib/inventory/fetchBatch.d.ts +83 -14
- package/types/lib/inventory/fetchBatch.d.ts.map +1 -1
- package/types/lib/inventory/fetchDiskCache.d.ts +169 -0
- package/types/lib/inventory/fetchDiskCache.d.ts.map +1 -0
- package/types/lib/inventory/forgeEnricher.d.ts.map +1 -1
- package/types/lib/inventory/formulationParsers.d.ts.map +1 -1
- package/types/lib/inventory/goBuildInfo.d.ts +10 -0
- package/types/lib/inventory/goBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/hbom.d.ts.map +1 -1
- package/types/lib/inventory/hbomAnalysis.d.ts +10 -0
- package/types/lib/inventory/hbomAnalysis.d.ts.map +1 -1
- package/types/lib/inventory/hostTopology.d.ts.map +1 -1
- package/types/lib/inventory/jvmLocalRepos.d.ts +178 -0
- package/types/lib/inventory/jvmLocalRepos.d.ts.map +1 -0
- package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/osPackagePurl.d.ts +99 -0
- package/types/lib/inventory/osPackagePurl.d.ts.map +1 -0
- package/types/lib/inventory/osPackageResolver.d.ts +6 -2
- package/types/lib/inventory/osPackageResolver.d.ts.map +1 -1
- package/types/lib/inventory/osinfo.d.ts +31 -6
- package/types/lib/inventory/osinfo.d.ts.map +1 -1
- package/types/lib/inventory/osqueryTransform.d.ts +51 -0
- package/types/lib/inventory/osqueryTransform.d.ts.map +1 -1
- package/types/lib/inventory/parentSelection.d.ts +34 -0
- package/types/lib/inventory/parentSelection.d.ts.map +1 -0
- package/types/lib/inventory/phpBuildInfo.d.ts +142 -0
- package/types/lib/inventory/phpBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/phpHostProbe.d.ts +35 -0
- package/types/lib/inventory/phpHostProbe.d.ts.map +1 -0
- package/types/lib/inventory/rootfsCerts.d.ts +27 -0
- package/types/lib/inventory/rootfsCerts.d.ts.map +1 -0
- package/types/lib/inventory/rustFormulationParser.d.ts.map +1 -1
- package/types/lib/inventory/scalaCoords.d.ts +80 -0
- package/types/lib/inventory/scalaCoords.d.ts.map +1 -0
- package/types/lib/inventory/source.d.ts +28 -0
- package/types/lib/inventory/source.d.ts.map +1 -1
- package/types/lib/inventory/spdx.d.ts +24 -0
- package/types/lib/inventory/spdx.d.ts.map +1 -1
- package/types/lib/inventory/traceRunner.d.ts +16 -1
- package/types/lib/inventory/traceRunner.d.ts.map +1 -1
- package/types/lib/inventory/tracedCrypto.d.ts +64 -0
- package/types/lib/inventory/tracedCrypto.d.ts.map +1 -0
- package/types/lib/managers/binary.d.ts +10 -0
- 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/managers/oci.d.ts +3 -1
- package/types/lib/managers/oci.d.ts.map +1 -1
- package/types/lib/parsers/cmakeCache.d.ts +16 -0
- package/types/lib/parsers/cmakeCache.d.ts.map +1 -1
- package/types/lib/parsers/cmakeLists.d.ts +2 -1
- package/types/lib/parsers/cmakeLists.d.ts.map +1 -1
- package/types/lib/parsers/cmakePresets.d.ts +78 -0
- package/types/lib/parsers/cmakePresets.d.ts.map +1 -0
- package/types/lib/parsers/compileCommands.d.ts +115 -0
- package/types/lib/parsers/compileCommands.d.ts.map +1 -0
- package/types/lib/parsers/email.d.ts +19 -0
- package/types/lib/parsers/email.d.ts.map +1 -0
- package/types/lib/parsers/largeJson.d.ts +13 -0
- package/types/lib/parsers/largeJson.d.ts.map +1 -1
- package/types/lib/parsers/strictJson.d.ts +46 -0
- package/types/lib/parsers/strictJson.d.ts.map +1 -0
- package/types/lib/parsers/terraformConfig.d.ts +70 -0
- package/types/lib/parsers/terraformConfig.d.ts.map +1 -0
- package/types/lib/parsers/terraformSource.d.ts +66 -0
- package/types/lib/parsers/terraformSource.d.ts.map +1 -0
- package/types/lib/server/server.d.ts +8 -0
- package/types/lib/server/server.d.ts.map +1 -1
- package/types/lib/stages/postgen/annotator.d.ts.map +1 -1
- package/types/lib/stages/postgen/introspection/reflect.d.ts.map +1 -1
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
- package/types/lib/stages/postgen/ruleEngine.d.ts +7 -4
- package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
- package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -1
- package/types/lib/stages/pregen/pregen.d.ts +14 -1
- package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
- package/types/lib/validator/index.d.ts +8 -0
- package/types/lib/validator/index.d.ts.map +1 -1
- package/types/lib/validator/reporters/json.d.ts.map +1 -1
- package/lib/third-party/arborist/snapshots/calc-dep-flags.test.cjs +0 -462
package/lib/inventory/osinfo.js
CHANGED
|
@@ -49,14 +49,34 @@ export const OS_DISTRO_ALIAS = {
|
|
|
49
49
|
"ubuntu-24.10": "oracular",
|
|
50
50
|
"ubuntu-25.04": "plucky",
|
|
51
51
|
"ubuntu-25.10": "questing",
|
|
52
|
+
"ubuntu-26.04": "resolute",
|
|
53
|
+
"ubuntu-26.10": "stonking",
|
|
52
54
|
"debian-15": "duke",
|
|
53
55
|
"debian-14": "forky",
|
|
54
56
|
"debian-14.5": "forky",
|
|
55
57
|
"debian-13": "trixie",
|
|
58
|
+
"debian-13.7": "trixie",
|
|
59
|
+
"debian-13.6": "trixie",
|
|
56
60
|
"debian-13.5": "trixie",
|
|
61
|
+
"debian-13.4": "trixie",
|
|
62
|
+
"debian-13.3": "trixie",
|
|
63
|
+
"debian-13.2": "trixie",
|
|
64
|
+
"debian-13.1": "trixie",
|
|
57
65
|
"debian-12": "bookworm",
|
|
58
|
-
"debian-12.
|
|
66
|
+
"debian-12.15": "bookworm",
|
|
67
|
+
"debian-12.14": "bookworm",
|
|
68
|
+
"debian-12.13": "bookworm",
|
|
69
|
+
"debian-12.12": "bookworm",
|
|
70
|
+
"debian-12.11": "bookworm",
|
|
71
|
+
"debian-12.10": "bookworm",
|
|
72
|
+
"debian-12.9": "bookworm",
|
|
73
|
+
"debian-12.8": "bookworm",
|
|
74
|
+
"debian-12.7": "bookworm",
|
|
59
75
|
"debian-12.6": "bookworm",
|
|
76
|
+
"debian-12.5": "bookworm",
|
|
77
|
+
"debian-12.4": "bookworm",
|
|
78
|
+
"debian-12.2": "bookworm",
|
|
79
|
+
"debian-12.1": "bookworm",
|
|
60
80
|
"debian-11": "bullseye",
|
|
61
81
|
"debian-11.5": "bullseye",
|
|
62
82
|
"debian-10": "buster",
|
|
@@ -256,15 +276,20 @@ export function _resetOsReleaseCache() {
|
|
|
256
276
|
* Derive structured distro information from an os-release file.
|
|
257
277
|
*
|
|
258
278
|
* Returns an object with:
|
|
259
|
-
* - purlType {string} "deb" | "apk" | "rpm"
|
|
279
|
+
* - purlType {string} "deb" | "apk" | "rpm" | "alpm" (Arch and the
|
|
280
|
+
* distros built on it)
|
|
260
281
|
* - namespace {string} canonical purl namespace (e.g. "ubuntu", "alpine",
|
|
261
282
|
* "azure-linux" for both Azure Linux and CBL-Mariner)
|
|
262
283
|
* - distroId {string} ID + "-" + VERSION_ID with a canonical vendor
|
|
263
|
-
* prefix (e.g. "ubuntu-22.04", "azure-linux-3.0"
|
|
264
|
-
*
|
|
284
|
+
* prefix (e.g. "ubuntu-22.04", "azure-linux-3.0",
|
|
285
|
+
* "alpine-3.24.3")
|
|
286
|
+
* - distroName {string} release codename, or a token OS_DISTRO_ALIAS knows
|
|
287
|
+
* (e.g. "jammy", "rhel", "alpine-3.24"); empty when
|
|
288
|
+
* the distro has neither
|
|
265
289
|
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
290
|
+
* lib/managers/binary.js getOSPackages() reads its distro from here, so a
|
|
291
|
+
* container scan and an OBOM run on the same system give a package the same
|
|
292
|
+
* `distro` and `distro_name` qualifiers.
|
|
268
293
|
*
|
|
269
294
|
* @param {string} [root="/"] - Filesystem root to look for os-release.
|
|
270
295
|
* @returns {{ purlType: string, namespace: string, distroId: string, distroName: string }}
|
|
@@ -290,6 +315,8 @@ export function getDistroInfo(root = "/") {
|
|
|
290
315
|
case "alpine":
|
|
291
316
|
case "alpaquita":
|
|
292
317
|
case "openwrt":
|
|
318
|
+
case "wolfi":
|
|
319
|
+
case "chainguard":
|
|
293
320
|
purlType = "apk";
|
|
294
321
|
break;
|
|
295
322
|
case "sles":
|
|
@@ -312,11 +339,23 @@ export function getDistroInfo(root = "/") {
|
|
|
312
339
|
case "photon":
|
|
313
340
|
purlType = "rpm";
|
|
314
341
|
break;
|
|
342
|
+
case "arch":
|
|
343
|
+
case "archarm":
|
|
344
|
+
case "manjaro":
|
|
345
|
+
case "endeavouros":
|
|
346
|
+
case "cachyos":
|
|
347
|
+
case "steamos":
|
|
348
|
+
case "artix":
|
|
349
|
+
purlType = "alpm";
|
|
350
|
+
break;
|
|
315
351
|
default:
|
|
316
352
|
if (idLike.includes("debian") || idLike.includes("ubuntu")) {
|
|
317
353
|
purlType = "deb";
|
|
318
354
|
} else if (idLike.includes("alpine")) {
|
|
319
355
|
purlType = "apk";
|
|
356
|
+
} else if (idLike.split(/\s+/u).includes("arch")) {
|
|
357
|
+
// A token, not a substring: ID_LIKE is a space-separated list.
|
|
358
|
+
purlType = "alpm";
|
|
320
359
|
} else if (
|
|
321
360
|
idLike.includes("rhel") ||
|
|
322
361
|
idLike.includes("centos") ||
|
|
@@ -343,41 +382,50 @@ export function getDistroInfo(root = "/") {
|
|
|
343
382
|
namespace = "debian";
|
|
344
383
|
} else if (idLike.includes("ubuntu")) {
|
|
345
384
|
namespace = "ubuntu";
|
|
385
|
+
} else if (purlType === "alpm") {
|
|
386
|
+
namespace = "arch";
|
|
346
387
|
} else {
|
|
347
388
|
namespace = "linux";
|
|
348
389
|
}
|
|
349
390
|
}
|
|
350
391
|
|
|
351
|
-
// Build distroId = ID-VERSION_ID (e.g. "fedora-25",
|
|
352
|
-
// canonicalising the vendor prefix so one release has a
|
|
353
|
-
// value (e.g. "mariner-2.0" and "azurelinux-3.0" ->
|
|
354
|
-
// "azure-linux-3.0")
|
|
355
|
-
|
|
356
|
-
distroId = canonicalDistroQualifier(
|
|
392
|
+
// Build distroId = ID-VERSION_ID as os-release writes it (e.g. "fedora-25",
|
|
393
|
+
// "alpine-3.24.3"), canonicalising the vendor prefix so one release has a
|
|
394
|
+
// single qualifier value (e.g. "mariner-2.0" and "azurelinux-3.0" ->
|
|
395
|
+
// "azure-linux-2.0"/"azure-linux-3.0")
|
|
396
|
+
const releaseId = versionId ? `${rawId}-${versionId}` : rawId;
|
|
397
|
+
const distroId = canonicalDistroQualifier(releaseId);
|
|
357
398
|
|
|
358
|
-
//
|
|
359
|
-
|
|
399
|
+
// distro_name is a release codename or a token OS_DISTRO_ALIAS knows
|
|
400
|
+
// ("bookworm", "jammy", "rhel", "alpine-3.24"), never a product display
|
|
401
|
+
// name: "AlmaLinux" or "Rocky Linux 9" has no place in a purl, since RPM
|
|
402
|
+
// distros track packages flat and a display name there breaks vulnerability
|
|
403
|
+
// matching. A product name counts only when it resolves through the alias
|
|
404
|
+
// table, which holds the RHEL names.
|
|
405
|
+
let distroName = (info.VERSION_CODENAME || "").toLowerCase();
|
|
406
|
+
if (!distroName) {
|
|
407
|
+
const productName = (
|
|
408
|
+
info.CENTOS_MANTISBT_PROJECT ||
|
|
409
|
+
info.REDHAT_BUGZILLA_PRODUCT ||
|
|
410
|
+
info.REDHAT_SUPPORT_PRODUCT ||
|
|
411
|
+
""
|
|
412
|
+
).toLowerCase();
|
|
413
|
+
if (productName && Object.hasOwn(OS_DISTRO_ALIAS, productName)) {
|
|
414
|
+
distroName = OS_DISTRO_ALIAS[productName];
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
// Alpine names its release series: 3.24.3 belongs to alpine-3.24, the unit
|
|
418
|
+
// its security data is kept in.
|
|
419
|
+
if (rawId === "alpine" && versionId) {
|
|
360
420
|
const parts = versionId.split(".");
|
|
361
421
|
if (parts.length >= 2) {
|
|
362
|
-
|
|
422
|
+
distroName = `alpine-${parts[0]}.${parts[1]}`;
|
|
363
423
|
}
|
|
364
424
|
}
|
|
365
|
-
|
|
366
|
-
//
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
info.CENTOS_MANTISBT_PROJECT ||
|
|
370
|
-
info.REDHAT_BUGZILLA_PRODUCT ||
|
|
371
|
-
info.REDHAT_SUPPORT_PRODUCT ||
|
|
372
|
-
"";
|
|
373
|
-
distroName = distroName.toLowerCase();
|
|
374
|
-
|
|
375
|
-
// Resolve well-known display name aliases
|
|
376
|
-
if (distroName.includes(" ") && OS_DISTRO_ALIAS[distroName]) {
|
|
377
|
-
distroName = OS_DISTRO_ALIAS[distroName];
|
|
378
|
-
}
|
|
379
|
-
if (!distroName && OS_DISTRO_ALIAS[distroId]) {
|
|
380
|
-
distroName = OS_DISTRO_ALIAS[distroId];
|
|
425
|
+
// The alias of the release itself (ubuntu-24.04 -> noble) wins over the
|
|
426
|
+
// codename the file carries.
|
|
427
|
+
if (versionId && Object.hasOwn(OS_DISTRO_ALIAS, releaseId)) {
|
|
428
|
+
distroName = OS_DISTRO_ALIAS[releaseId];
|
|
381
429
|
}
|
|
382
430
|
|
|
383
431
|
return { purlType, namespace, distroId, distroName };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getDistroInfo } from "./osinfo.js";
|
|
2
|
+
import { buildOsPackagePurl, osPackageVersion } from "./osPackagePurl.js";
|
|
2
3
|
import { tryBuildPurl } from "./purl.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -62,6 +63,8 @@ export function deriveOsQueryPublisher(res) {
|
|
|
62
63
|
res.creator ||
|
|
63
64
|
res.manufacturer ||
|
|
64
65
|
res.provider ||
|
|
66
|
+
res.packager ||
|
|
67
|
+
res.developer_name ||
|
|
65
68
|
"";
|
|
66
69
|
return publisher === "null" ? "" : publisher;
|
|
67
70
|
}
|
|
@@ -174,7 +177,10 @@ export function shouldCreateOsQueryPurl(componentType) {
|
|
|
174
177
|
|
|
175
178
|
// Purl types whose type rules require a namespace. For OS package types the
|
|
176
179
|
// namespace is the distro vendor (`pkg:deb/debian/...`, `pkg:rpm/redhat/...`),
|
|
177
|
-
// which osquery does not report but /etc/os-release does.
|
|
180
|
+
// which osquery does not report but /etc/os-release does. deb, rpm and apk rows
|
|
181
|
+
// are named by createOsQueryPackageIdentity; this covers the other types that
|
|
182
|
+
// need a vendor (portage's ebuild) and a caller that asks for one of the three
|
|
183
|
+
// directly.
|
|
178
184
|
const NAMESPACE_REQUIRED_TYPES = new Set([
|
|
179
185
|
"deb",
|
|
180
186
|
"rpm",
|
|
@@ -216,10 +222,9 @@ export function createOsQueryPurl(
|
|
|
216
222
|
if (type === "swid" && !finalQualifiers.tag_id) {
|
|
217
223
|
finalQualifiers.tag_id = name;
|
|
218
224
|
}
|
|
219
|
-
//
|
|
220
|
-
//
|
|
221
|
-
//
|
|
222
|
-
// purl instead of losing one.
|
|
225
|
+
// Rows with no group whose purl type requires a namespace get the vendor from
|
|
226
|
+
// /etc/os-release, the way osPackageResolver does, so they keep a valid purl
|
|
227
|
+
// instead of losing one.
|
|
223
228
|
let namespace = group || null;
|
|
224
229
|
if (!namespace && NAMESPACE_REQUIRED_TYPES.has(type)) {
|
|
225
230
|
namespace = getDistroInfo().namespace || null;
|
|
@@ -237,6 +242,110 @@ export function createOsQueryPurl(
|
|
|
237
242
|
});
|
|
238
243
|
}
|
|
239
244
|
|
|
245
|
+
/**
|
|
246
|
+
* The version and purl of a row from an OS package table: `deb_packages`,
|
|
247
|
+
* `rpm_packages`, `pacman_packages`, `homebrew_packages`, `macports_packages`,
|
|
248
|
+
* `snap_packages`, `flatpak_packages` or the rows of the apk database.
|
|
249
|
+
*
|
|
250
|
+
* Such a row is named the way the package manager's own scan names it: deb,
|
|
251
|
+
* rpm and apk with the vendor and the `arch`, `distro`, `distro_name` and
|
|
252
|
+
* `epoch` qualifiers of the container scan, an rpm version joined to its
|
|
253
|
+
* release, a MacPorts version joined to its revision, a flatpak by its
|
|
254
|
+
* application ID with the `arch` and `branch` of its ref. A row's `path`,
|
|
255
|
+
* `admindir` or source file is not a path inside the package, so none of them
|
|
256
|
+
* becomes a subpath.
|
|
257
|
+
*
|
|
258
|
+
* @param {string} purlType One of OS_PACKAGE_PURL_TYPES
|
|
259
|
+
* @param {Object} res osquery row
|
|
260
|
+
* @param {string} name Component name derived from the row
|
|
261
|
+
* @param {Object} [distro] What getDistroInfo() reports; the host's by default
|
|
262
|
+
* @returns {{version: string, purl: string|null}} The component version and the purl, which is null when the row cannot be expressed as one
|
|
263
|
+
*/
|
|
264
|
+
export function createOsQueryPackageIdentity(purlType, res, name, distro) {
|
|
265
|
+
const pkg = {
|
|
266
|
+
type: purlType,
|
|
267
|
+
name,
|
|
268
|
+
version: res.version,
|
|
269
|
+
arch: res.arch,
|
|
270
|
+
};
|
|
271
|
+
if (purlType === "rpm") {
|
|
272
|
+
pkg.release = res.release;
|
|
273
|
+
pkg.epoch = res.epoch;
|
|
274
|
+
} else if (purlType === "macports") {
|
|
275
|
+
pkg.revision = res.revision;
|
|
276
|
+
} else if (purlType === "flatpak") {
|
|
277
|
+
pkg.branch = res.branch;
|
|
278
|
+
}
|
|
279
|
+
return {
|
|
280
|
+
version: osPackageVersion(pkg),
|
|
281
|
+
purl: buildOsPackagePurl(pkg, distro),
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Columns of an OS package table that are named or dropped on their way to a
|
|
286
|
+
// property. A bare `source` is the source package of a deb, the source rpm file
|
|
287
|
+
// of an rpm and the pkgbase of a pacman package, and `type` says whether a
|
|
288
|
+
// Homebrew entry is a formula or a cask, a snap an app or a base, a flatpak an
|
|
289
|
+
// app or a runtime, so each takes the name that says which. The dpkg
|
|
290
|
+
// administrative directory and the pacman database path are the same for every
|
|
291
|
+
// package and say nothing about one.
|
|
292
|
+
const OS_PACKAGE_PROPERTY_NAMES = {
|
|
293
|
+
deb: { source: "cdx:deb:source", admindir: undefined },
|
|
294
|
+
rpm: { source: "cdx:rpm:sourceRpm" },
|
|
295
|
+
apk: { origin: "cdx:apk:origin" },
|
|
296
|
+
alpm: { source: "cdx:alpm:pkgbase", dbpath: undefined },
|
|
297
|
+
brew: { type: "cdx:homebrew:type" },
|
|
298
|
+
macports: {
|
|
299
|
+
variants: "cdx:macports:variants",
|
|
300
|
+
requested: "cdx:macports:requested",
|
|
301
|
+
},
|
|
302
|
+
snap: {
|
|
303
|
+
type: "cdx:snap:type",
|
|
304
|
+
revision: "cdx:snap:revision",
|
|
305
|
+
channel: "cdx:snap:channel",
|
|
306
|
+
confinement: "cdx:snap:confinement",
|
|
307
|
+
},
|
|
308
|
+
flatpak: {
|
|
309
|
+
display_name: "cdx:flatpak:displayName",
|
|
310
|
+
commit_hash: "cdx:flatpak:commit",
|
|
311
|
+
origin: "cdx:flatpak:origin",
|
|
312
|
+
installation: "cdx:flatpak:installation",
|
|
313
|
+
type: "cdx:flatpak:type",
|
|
314
|
+
runtime: "cdx:flatpak:runtime",
|
|
315
|
+
},
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* The columns of an OS package row that give its licence and its home page.
|
|
320
|
+
* They become the component's `licenses` and a `website` reference rather than
|
|
321
|
+
* properties. `separator` splits a licence column that lists several: pacman
|
|
322
|
+
* keeps one licence per entry, which osquery joins with commas.
|
|
323
|
+
*/
|
|
324
|
+
export const OS_PACKAGE_LICENSE_COLUMNS = {
|
|
325
|
+
alpm: { license: "licenses", separator: ",", website: "url" },
|
|
326
|
+
snap: { license: "license" },
|
|
327
|
+
flatpak: { license: "license", website: "homepage" },
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* The property name an OS package table column is emitted under.
|
|
332
|
+
*
|
|
333
|
+
* @param {string|undefined} purlType Purl type of the table
|
|
334
|
+
* @param {string} column Column name
|
|
335
|
+
* @returns {string|undefined} The property name, or undefined when the column is not emitted
|
|
336
|
+
*/
|
|
337
|
+
export function osPackagePropertyName(purlType, column) {
|
|
338
|
+
const fields = OS_PACKAGE_LICENSE_COLUMNS[purlType];
|
|
339
|
+
if (fields && (column === fields.license || column === fields.website)) {
|
|
340
|
+
return undefined;
|
|
341
|
+
}
|
|
342
|
+
const names = OS_PACKAGE_PROPERTY_NAMES[purlType];
|
|
343
|
+
if (names && Object.hasOwn(names, column)) {
|
|
344
|
+
return names[column];
|
|
345
|
+
}
|
|
346
|
+
return column;
|
|
347
|
+
}
|
|
348
|
+
|
|
240
349
|
function _deriveCertificateFormat(certificateFileExtension) {
|
|
241
350
|
switch ((certificateFileExtension || "").toLowerCase()) {
|
|
242
351
|
case "pem":
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which detected project becomes the parent (`metadata.component`) when one
|
|
3
|
+
* scan covers several ecosystems and no parent was given.
|
|
4
|
+
*
|
|
5
|
+
* Each ecosystem detects its own project from its own manifest. The project
|
|
6
|
+
* whose manifest sits at the scan root describes the repository; one found
|
|
7
|
+
* deeper is a part of it (a web client in `tools/ui/`, a helper script's
|
|
8
|
+
* `pyproject.toml`). So candidates are ordered by how deep their ecosystem's
|
|
9
|
+
* manifests sit, the scan root first, and ties keep the ecosystem order the
|
|
10
|
+
* scan ran in.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { readdirSync } from "node:fs";
|
|
14
|
+
import { dirname, relative, resolve, sep } from "node:path";
|
|
15
|
+
|
|
16
|
+
import { getAllFiles } from "../core/fs.js";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Manifest file names (or `*.ext` suffixes) per purl type: the files a
|
|
20
|
+
* project of that ecosystem is described by.
|
|
21
|
+
*/
|
|
22
|
+
const MANIFESTS_BY_PURL_TYPE = {
|
|
23
|
+
npm: ["package.json"],
|
|
24
|
+
pypi: [
|
|
25
|
+
"pyproject.toml",
|
|
26
|
+
"setup.py",
|
|
27
|
+
"setup.cfg",
|
|
28
|
+
"Pipfile",
|
|
29
|
+
"requirements.txt",
|
|
30
|
+
"uv.lock",
|
|
31
|
+
"poetry.lock",
|
|
32
|
+
"pixi.toml",
|
|
33
|
+
],
|
|
34
|
+
generic: [
|
|
35
|
+
"CMakeLists.txt",
|
|
36
|
+
"meson.build",
|
|
37
|
+
"conanfile.txt",
|
|
38
|
+
"conanfile.py",
|
|
39
|
+
"vcpkg.json",
|
|
40
|
+
"xmake.lua",
|
|
41
|
+
],
|
|
42
|
+
maven: ["pom.xml", "build.gradle", "build.gradle.kts", "build.sbt"],
|
|
43
|
+
golang: ["go.mod"],
|
|
44
|
+
cargo: ["Cargo.toml"],
|
|
45
|
+
composer: ["composer.json"],
|
|
46
|
+
gem: ["Gemfile", "*.gemspec"],
|
|
47
|
+
nuget: ["*.csproj", "*.fsproj", "*.vbproj", "*.sln", "packages.config"],
|
|
48
|
+
pub: ["pubspec.yaml"],
|
|
49
|
+
hex: ["mix.exs"],
|
|
50
|
+
hackage: ["*.cabal", "stack.yaml"],
|
|
51
|
+
swift: ["Package.swift"],
|
|
52
|
+
cocoapods: ["Podfile"],
|
|
53
|
+
clojars: ["deps.edn", "project.clj"],
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/** The purl type of a component, or `undefined`. */
|
|
57
|
+
function purlTypeOf(component) {
|
|
58
|
+
const purl = `${component?.purl || ""}`;
|
|
59
|
+
if (!purl.startsWith("pkg:")) {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
const rest = purl.slice(4);
|
|
63
|
+
const end = rest.search(/[/@?#]/);
|
|
64
|
+
return (end < 0 ? rest : rest.slice(0, end)).toLowerCase();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function matchesManifest(name, patterns) {
|
|
68
|
+
return patterns.some((p) =>
|
|
69
|
+
p.startsWith("*.") ? name.endsWith(p.slice(1)) : name === p,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* How deep the shallowest manifest of an ecosystem sits under a scan root:
|
|
75
|
+
* 0 for one at the root itself, `Infinity` when there is none (or the
|
|
76
|
+
* ecosystem is not one this module knows).
|
|
77
|
+
*
|
|
78
|
+
* @param {string} root Scan root
|
|
79
|
+
* @param {string} purlType Purl type of the ecosystem
|
|
80
|
+
* @param {Object} options CLI options (exclusions)
|
|
81
|
+
* @returns {number}
|
|
82
|
+
*/
|
|
83
|
+
export function manifestDepth(root, purlType, options = {}) {
|
|
84
|
+
const patterns = MANIFESTS_BY_PURL_TYPE[purlType];
|
|
85
|
+
if (!patterns || !root) {
|
|
86
|
+
return Number.POSITIVE_INFINITY;
|
|
87
|
+
}
|
|
88
|
+
const absRoot = resolve(root);
|
|
89
|
+
try {
|
|
90
|
+
if (readdirSync(absRoot).some((name) => matchesManifest(name, patterns))) {
|
|
91
|
+
return 0;
|
|
92
|
+
}
|
|
93
|
+
} catch (_err) {
|
|
94
|
+
return Number.POSITIVE_INFINITY;
|
|
95
|
+
}
|
|
96
|
+
const glob =
|
|
97
|
+
patterns.length === 1 ? `**/${patterns[0]}` : `**/{${patterns.join(",")}}`;
|
|
98
|
+
const files = getAllFiles(absRoot, glob, options);
|
|
99
|
+
let depth = Number.POSITIVE_INFINITY;
|
|
100
|
+
for (const f of files) {
|
|
101
|
+
const rel = relative(absRoot, dirname(resolve(f)));
|
|
102
|
+
if (!rel || rel.startsWith("..")) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
depth = Math.min(depth, rel.split(sep).length);
|
|
106
|
+
}
|
|
107
|
+
return depth;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Order parent candidates by the depth of their ecosystem's manifests under
|
|
112
|
+
* the scan roots (the shallowest first). The sort is stable, so candidates of
|
|
113
|
+
* equal depth keep the order the ecosystems were scanned in.
|
|
114
|
+
*
|
|
115
|
+
* @param {Object[]} candidates Detected parent components, in scan order
|
|
116
|
+
* @param {string[]} roots Scan roots
|
|
117
|
+
* @param {Object} options CLI options
|
|
118
|
+
* @returns {Object[]} The candidates, reordered
|
|
119
|
+
*/
|
|
120
|
+
export function orderParentCandidates(candidates, roots, options = {}) {
|
|
121
|
+
const depthByType = new Map();
|
|
122
|
+
const depthOf = (component) => {
|
|
123
|
+
const type = purlTypeOf(component);
|
|
124
|
+
if (!type) {
|
|
125
|
+
return Number.POSITIVE_INFINITY;
|
|
126
|
+
}
|
|
127
|
+
if (!depthByType.has(type)) {
|
|
128
|
+
depthByType.set(
|
|
129
|
+
type,
|
|
130
|
+
Math.min(
|
|
131
|
+
Number.POSITIVE_INFINITY,
|
|
132
|
+
...(roots || []).map((r) => manifestDepth(r, type, options)),
|
|
133
|
+
),
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
return depthByType.get(type);
|
|
137
|
+
};
|
|
138
|
+
return candidates
|
|
139
|
+
.map((component, index) => ({
|
|
140
|
+
component,
|
|
141
|
+
index,
|
|
142
|
+
depth: depthOf(component),
|
|
143
|
+
}))
|
|
144
|
+
.sort((a, b) => a.depth - b.depth || a.index - b.index)
|
|
145
|
+
.map((c) => c.component);
|
|
146
|
+
}
|