Skip to content

Release v2.3.0

Latest

Choose a tag to compare

@prabhu prabhu released this 19 Sep 23:29
· 2 commits to main since this release
v2.3.0
cbcc277

2.3.0 - 2026-09-20

A consumer-driven release. Everything here came from reading how cdxgen actually
uses this library and pulling the parts it had to reimplement back into the
package, plus a protobuf-es upgrade that turned out to be worth roughly 2x
across the board.

Fixed

  • convertBom no longer throws across the 1.5/1.6 boundary. Two fields
    changed cardinality in CycloneDX 1.6: metadata.licenses and
    evidence.identity were single objects in 1.5 and became arrays in 1.6.
    protobuf-es rejects an array where the schema wants one message and vice
    versa, so converting any BOM that used either field failed outright —
    cannot decode message cyclonedx.v1_5.EvidenceIdentity from JSON: Array(2).

    convertBom now reshapes both before decoding: wrap on the way up, keep the
    first entry on the way down. What gets dropped in a collapse is reported in
    warnings ($.components[].evidence.identity[1]) rather than vanishing, so
    downgrades stay lossy-but-visible. The evidence.identity reshape walks the
    whole document, so it covers components wherever they live — nested
    components[].components[], metadata.component and its subtree,
    metadata.tools.components[], formulation[].components[]. That matters
    more than it sounds: almost every real BOM has a metadata.component, so a
    reshape that only handled top-level components[] would still have thrown on
    nearly everything.

    A descriptor walk across all three schemas confirms these are the only two
    cardinality boundaries; nothing changes between 1.6 and 1.7.

Added

  • toBomMessage(value, specVersion?, options?) — one entry point for BOM
    input of any shape: an already-decoded message passes through, a JSON string
    is parsed, a JSON object with specVersion picks its own schema, one without
    falls back to the version you pass (latest by default), and anything else
    yields an empty BOM. Replaces the input-dispatch function every consumer ends
    up writing. isBomMessage(value) is the matching type guard, checking
    $typeName against the known Bom types rather than duck-typing.

  • normalizeSpecVersion() and isSupportedSpecVersion() are now exported.
    Both accept the spellings that turn up in the wild — "1.6", "v1.6", 1.6,
    "1.6.0" — the first throwing, the second not. Consumers gating protobuf work
    on version support no longer have to match against supportedSpecVersions by
    hand.

  • @cdxgen/cdx-proto/node subpath with readBomFile, writeBomFile and
    isProtoBomFile. Format is chosen from the extension: .json for canonical
    JSON, .b64/.base64 for base64, everything else as protobuf binary. The
    list of extensions that mean "protobuf BOM" (.cdx, .cdx.bin, .proto)
    lives here as protoBomFileExtensions so it stops being copied around. These
    are in a separate subpath deliberately — the main entry still has no node:
    imports and runs unchanged in browsers and edge runtimes.

  • Base64 codecs: encodeBomBase64, decodeBomBase64, parseBomBase64.
    Same bytes as the binary encoding, in a form that survives OCI labels,
    in-toto predicates, JSON documents and environment variables. Uses
    protobuf-es' own base64 rather than Buffer, so it stays runtime-neutral.
    The CLI reads and writes .b64/.base64 files too.

Changed

  • @bufbuild/protobuf and protoc-gen-es 2.13.0 → 2.15.0, buf → 1.73.0.
    2.14.0 was protobuf-es' performance release (growable writer buffers, native
    base64, compiled create()) and the effect is large. Same machine, same Node
    24.18.0, 10 000 components:

    operation 2.13.0 2.15.0
    parseBomJson 47.3 ms 24.6 ms
    encodeBomJson 28.6 ms 17.7 ms
    encodeBomBinary 66.0 ms 14.3 ms
    parseBomBinary 45.2 ms 16.4 ms

    Full tables in bench/BASELINE.md. Generated code changed only in its
    generator-version comment.

  • engines.node is now >=22. Node 20 reached end of life in April 2026.
    CI runs 22.x, 24.x and 26.x.

  • The CLI now builds on the new /node helpers instead of its own file
    plumbing.

Compatibility

No wire-format or schema changes — the vendored protos are untouched apart from
the generator comment, so binaries written by 2.2.0 read back identically. Every
addition is additive; nothing in the 2.2.0 API changed shape. The one behavioural
difference is that convertBom now succeeds where it used to throw, and may
return warnings on downgrades that previously produced no result at all.

Full Changelog: v2.2.0...v2.3.0