Skip to content

refactor(api): extend #206 type-safety to sbom (#359 batch 5)#381

Merged
brandonrc merged 1 commit intomainfrom
harden/359-type-safety-sbom
May 9, 2026
Merged

refactor(api): extend #206 type-safety to sbom (#359 batch 5)#381
brandonrc merged 1 commit intomainfrom
harden/359-type-safety-sbom

Conversation

@brandonrc
Copy link
Copy Markdown
Contributor

Summary

Closes #359 (partial — batch 5). Same playbook as batches 1-4 (PRs #376/#377/#379/#380) for src/lib/api/sbom.ts. 21 as never removed; zero retained casts (SDK type leaks documented in inline comments).

Notable shape mismatches surfaced + documented

  • LicenseCheckResult: SDK has violations: string[] and no action. Adapter synthesizes {license, reason: ""} rows and derives action from compliant. No app consumer today; best-effort synthesis is documented.
  • getByArtifact dropped its dead format?: string parameter — the SDK has no query for this endpoint and the cast was sending an ignored query.

Acceptance criteria

  • No uncommented as unknown as / as never in changed files
  • All tests pass (2070/2070)
  • New code coverage on changed lines ≥ 80%

Test plan

  • npm test — 2070/2070
  • npm run lint — 0 errors
  • npm run build — succeeds (TypeScript + Next prerender clean)

Remaining

dependency-track / promotion (medium); security / sso (large).

🤖 Generated with Claude Code

Apply the #206 playbook to sbom.ts. 21 `as never` casts removed.

src/lib/api/sbom.ts:
  + 9 read adapters: adaptSbom / adaptSbomContent / adaptComponent /
    adaptCveHistory / adaptCveTimelineEntry / adaptCveTrends /
    adaptLicensePolicy / adaptLicenseCheckResult — each normalizes
    SDK's `?: T | null` to local type's `: T | null`
  + 5 write adapters: adaptGenerateRequest / adaptConvertRequest /
    adaptUpdateCveStatusRequest / adaptUpsertPolicyRequest /
    adaptCheckRequest — explicit field forwarding so a future local-
    type addition surfaces at typecheck
  + narrowCveStatus / narrowPolicyAction — exported helpers for callers
    that want a typed enum from the string fields the SDK exposes
  + assertData on every successful read

SDK shape mismatches (now explicit + documented):
  - LicenseCheckResult: SDK returns `violations: string[]` with no
    `action`; adapter coerces to `{license, reason: ""}` and derives
    `action: compliant ? "allow" : "block"`. No app consumer calls
    this endpoint today, so the synthesis is best-effort.
  - getByArtifact dropped `format?: string` query param: SDK has no
    query for that endpoint (the pre-#359 cast bypassed types and sent
    an unsupported query the backend ignored). No consumer was passing
    format, so end-to-end no-op.

Tests rewritten with realistic SDK fixtures (typed as Sdk* for compile-
time drift detection). New regression tests:
  - undefined → null nullable normalization for SbomResponse
  - getByArtifact does not pass query
  - checkCompliance synthesizes action + violation rows
  - checkCompliance allow path

CHANGELOG entry under [Unreleased] / Changed.

Closes #359 (partial — batch 5 of N). Remaining: dependency-track,
promotion (medium), security, sso (large).
@brandonrc brandonrc requested a review from a team as a code owner May 9, 2026 19:36
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 9, 2026

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@brandonrc brandonrc merged commit 8ba9e04 into main May 9, 2026
18 checks passed
@brandonrc brandonrc deleted the harden/359-type-safety-sbom branch May 9, 2026 19:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extend #206 type-safety hardening to remaining lib/api modules

1 participant