# sbom _(no submodules)_ ## Purpose Generates CycloneDX 1.5 compatible Software Bill of Materials documents for packages in Suaveplan. An SBOM lists every component a package depends on, keyed by `purl`, enabling downstream vulnerability scanners, license audits, and provenance correlation. Alongside generation, this module exports canonical serialisation, SHA-256 digesting, and `purl` construction so other packages (notably the publish pipeline) can reproduce the same output bytes. ## Features - CycloneDX 1.5 schema adherence, validated by the sibling Zod schema. - Scoped-package `purl` construction (`pkg:npm/%40scope/name@ver`). - Workspace/catalog placeholder resolution (`workspace:*` → `*`, `catalog:key` → `catalog-key`). - Deterministic sort-key serialisation via `canonicalize`. - Injectable `clock` and `serial` factories for deterministic tests. ## Usage: Basic Example ```ts import { generateSbom } from "@suaveplan/slsa"; const sbom = generateSbom({ packageName: "@suaveplan/utils", packageVersion: "1.2.3", dependencies: { lodash: "4.17.21" }, }); ``` ## Usage: Advanced Example ```ts import { generateSbom, hashSbom, serializeSbom } from "@suaveplan/slsa"; const sbom = generateSbom( { packageName: "@suaveplan/app", packageVersion: "2.0.0", packageLicense: "MIT", componentType: "application", dependencies: { "@suaveplan/crypto": "workspace:*", vitest: "catalog:testing", }, }, { clock: () => 0, serial: () => "urn:uuid:deadbeef-dead-beef-dead-beefdeadbeef", } ); console.log(hashSbom(sbom)); // stable across runs await fs.writeFile("sbom.json", serializeSbom(sbom)); ``` ## API Reference - `generateSbom(input, opts?): Sbom` — constructs the SBOM. Throws `InvalidSbomError` when `packageName`, `packageVersion`, or `dependencies` is missing. - `GenerateSbomOptions { clock?, serial? }` — deterministic seam. - `serializeSbom(sbom): string` — canonical JSON encoding. - `hashSbom(sbom): string` — SHA-256 hex digest of the canonical encoding. - `buildPurl(name, version): string` — constructs a `purl` for either a scoped or unscoped npm package. ## Implementation Notes `crypto.randomUUID` is the default serial source; the fallback construction using `Math.random` is retained only to keep the module universally importable — runtimes that land in the fallback should be considered a configuration bug and should inject `serial` explicitly. `resolveVersion` maps catalog references to a stable `catalog-` form rather than the resolved pin because catalog resolution happens at publish time, not at SBOM generation time; the downstream publisher can post-process the document if stricter pins are required.