Note: this is an in-house item already being handled by the maintainer - not open for contribution. Filed for tracking only.
CycloneDX output carries no dependency relationships at all. src/output/cyclonedx.ts never calls resolveDependencyEdges and never emits a dependencies array.
Measured
examples/analog, 3368 packages, a project with a properly named package.json:
CycloneDX metadata.component: analogjs-platform
CycloneDX dependencies entries: 0
Same project, SPDX: every package has a parent edge except the root.
Verified structurally as well:
$ grep -c 'resolveDependencyEdges' src/output/cyclonedx.ts src/output/spdx.ts
src/output/cyclonedx.ts:0
src/output/spdx.ts:1
Why it matters
CycloneDX 1.6 defines a dependencies array precisely for this, and it is what Dependency-Track builds its graph from. website/docs/cyclonedx.md points users at Dependency-Track as the headline integration, so the format is being recommended for the tool that most depends on the field we do not emit.
Dependency relationships are also an NTIA minimum element. The SPDX output was brought to completeness across all four package managers in #1106, #1115, #1125 and #1132. CycloneDX was never part of that, and nothing said so.
Scope note, in fairness
cyclonedx.md does not claim to emit a dependency graph, so no documentation is wrong. But the SBOM work has been described in several PR bodies and tracker entries as completing "dependency graphs" without qualifying the format, which reads broader than it is. Worth correcting in the v1.35.0 release notes so nobody infers CycloneDX parity.
Fix direction
The hard part is already done. resolveDependencyEdges returns { child, parent } keyed by name@version and is format-agnostic. CycloneDX needs the same call, then a mapping from those pairs to dependencies[].ref and dependsOn, using the same purl bom-ref values the components already carry. The root component becomes the anchor for parent: null, mirroring SPDX.
Note #1134 applies here too: a project with no package.json name has no root component to anchor to.
CycloneDX output carries no dependency relationships at all.
src/output/cyclonedx.tsnever callsresolveDependencyEdgesand never emits adependenciesarray.Measured
examples/analog, 3368 packages, a project with a properly namedpackage.json:Same project, SPDX: every package has a parent edge except the root.
Verified structurally as well:
Why it matters
CycloneDX 1.6 defines a
dependenciesarray precisely for this, and it is what Dependency-Track builds its graph from.website/docs/cyclonedx.mdpoints users at Dependency-Track as the headline integration, so the format is being recommended for the tool that most depends on the field we do not emit.Dependency relationships are also an NTIA minimum element. The SPDX output was brought to completeness across all four package managers in #1106, #1115, #1125 and #1132. CycloneDX was never part of that, and nothing said so.
Scope note, in fairness
cyclonedx.mddoes not claim to emit a dependency graph, so no documentation is wrong. But the SBOM work has been described in several PR bodies and tracker entries as completing "dependency graphs" without qualifying the format, which reads broader than it is. Worth correcting in the v1.35.0 release notes so nobody infers CycloneDX parity.Fix direction
The hard part is already done.
resolveDependencyEdgesreturns{ child, parent }keyed byname@versionand is format-agnostic. CycloneDX needs the same call, then a mapping from those pairs todependencies[].refanddependsOn, using the same purlbom-refvalues the components already carry. The root component becomes the anchor forparent: null, mirroring SPDX.Note #1134 applies here too: a project with no
package.jsonname has no root component to anchor to.