Skip to content

feat: add attested and downloads fields to File/Package types#80

Merged
kmturley merged 2 commits into
mainfrom
feature/attested-downloads-fields
Jul 21, 2026
Merged

feat: add attested and downloads fields to File/Package types#80
kmturley merged 2 commits into
mainfrom
feature/attested-downloads-fields

Conversation

@kmturley

Copy link
Copy Markdown
Member

Summary

Adds two new optional signals to the shared types, ahead of the registry-side implementation that populates them (opening as a separate PR once this is merged and published):

  • attested?: boolean on FileInterface — whether a file has a GitHub Artifact Attestation linking it back to the CI run/commit/repo that built it. Computed once at import time (not on every build) since a published file's hash/url/release never change afterwards.
  • downloads?: number at three levels:
    • Per-file (FileInterface) — raw download count for that exact file, from the GitHub Releases API.
    • Per-version rollup (PackageBase) — sum of that version's files, via new packageDownloadsTotal() helper.
    • Per-package rollup across all versions (PackageInterface) — via new Package.getTotalDownloads(), wired into toJSON().

Both fields are omitted rather than written as false/0 — keeps generated registry JSON smaller, and neither "not fetched yet" nor "genuinely zero" is worth distinguishing for either signal. PackageFileValidator (Zod) extended so both are type-checked when present, without being required.

This PR is types/core-logic only — no network calls, no new dependencies. The registry-side pieces that actually populate these fields (fetch.ts checking attestations at import time, a new downloads.ts batching GitHub GraphQL calls to compute download counts at build time) are ready as a follow-up PR once this publishes.

Test plan

  • npm run build — type-checks clean
  • npm test — 170/170 passing (5 new tests directly exercising the rollup math with real non-zero numbers, not just zero-value fixtures)
  • npm run lint — clean
  • No behavior change for existing consumers — both fields are optional/additive

🤖 Generated with Claude Code

kmturley and others added 2 commits July 20, 2026 19:53
Supports two new registry signals discussed alongside the recent
security fixes:

- `attested?: boolean` on FileInterface - whether a file has a GitHub
  Artifact Attestation linking it back to the CI run/commit that built
  it. Computed once at import time (registry/fetch.ts, in a follow-up
  PR) since a published file's hash/url/release never change
  afterwards - unlike `downloads`, this isn't recomputed on every
  build.
- `downloads?: number` at three levels - per-file (FileInterface),
  per-version rollup (PackageBase, summed via the new
  packageDownloadsTotal() helper), and per-package rollup across all
  versions (PackageInterface, via the new Package.getTotalDownloads(),
  wired into toJSON()). Recomputed at registry build time from the
  GitHub Releases API (registry/downloads.ts, in a follow-up PR) since
  download counts change continuously.

Both fields are omitted rather than written as `false`/`0` - keeps
generated JSON smaller, and neither "not fetched" nor "genuinely zero"
is worth distinguishing for either signal. PackageFileValidator
extended to type-check them when present.

Verified packageDownloadsTotal/getTotalDownloads rollup math directly
with dedicated tests (not just zero-value fixtures), and separately
end-to-end against live GitHub API data for a real registry package
(aaronaanderson/Terrain) during development - see the registry-side
follow-up PR for that verification.

No behavior change for existing consumers: both fields are optional
and additive to the existing schema.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kmturley
kmturley merged commit 7baeafd into main Jul 21, 2026
6 checks passed
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.

1 participant