Skip to content

Drop @atproto/api runtime dependency from bsky - #5422

Open
bigmoves wants to merge 2 commits into
bluesky-social:mainfrom
bigmoves:bigmoves/audit-api-refs
Open

Drop @atproto/api runtime dependency from bsky#5422
bigmoves wants to merge 2 commits into
bluesky-social:mainfrom
bigmoves:bigmoves/audit-api-refs

Conversation

@bigmoves

@bigmoves bigmoves commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

What & why

packages/bsky carried @atproto/api as a runtime dependency because of exactly two production files. Both imported the age assurance region/rule helpers — getAgeAssuranceRegionConfig, computeAgeAssuranceRegionAccess, AgeAssuranceRuleID — from @atproto/api:

  • src/api/age-assurance/util.ts
  • src/api/app/bsky/ageassurance/begin.ts

Those helpers live in packages/api/src/age-assurance.ts, which is hand-written logic that happens to sit alongside the legacy generated client. So two imports were pinning the whole legacy client stack into bsky's shipped artifact and into the services/bsky image.

Per review, this sources them from @bsky/sdk (@bsky/sdk/utils), which already ships getAgeAssuranceRegionConfig, computeAgeAssuranceRegionAccess, and AgeAssuranceRuleID typed against @atproto/lex — so no logic is duplicated into this repo.

src/api/age-assurance/util.ts keeps only the two bsky-specific wrappers (computeAgeAssuranceAccessOrThrow, createLocationString); begin.ts imports getAgeAssuranceRegionConfig straight from the SDK.

This works because the SDK declares @atproto/lex as a peer dependency, so it resolves to link:../lex/lex in this workspace. The branded types (l.UnknownString inside Access) therefore come from the same instance, and the SDK's Config / ConfigRegion are structurally compatible with this package's own generated app.bsky.ageassurance.defs tree — including AGE_ASSURANCE_CONFIG, which is still built from the local tree.

@atproto/api moves to devDependencies, and the ../api project reference moves from tsconfig.build.json to tsconfig.test.json — mirroring how packages/pds is already set up. pnpm why @atproto/api --filter @atproto/bsky --prod now returns nothing.

Also converts the age-assurance-v2 mocked config fixture to $build, so it is checked against the same schema the production code consumes rather than the structurally-compatible legacy type.

What this does not do

@atproto/api stays in devDependencies. All 58 bsky test files drive the services through AtpAgent, which dev-env hands them (packages/dev-env/src/bsky.ts:148, pds.ts:75), and pass legacy ids.* NSID constants to network.serviceHeaders(). That can't go away until dev-env itself migrates — a separate, much larger change that would also unblock pds and ozone shedding their test-side dep.

packages/api keeps its own copy of these helpers, since it is a published package and they are public API for external clients. That copy is now the redundant one and can go with the rest of @atproto/api.

Checklist

  • pnpm build --force && pnpm verify passes
  • Tests pass, and new behavior is covered by tests
  • A changeset is included for every package this touches
  • Written with the help of an LLM or coding agent? Say so here, and name the tooling.

Written with Claude Code (Claude Opus 5).

Test evidence

  • tests/views/age-assurance.test.ts + tests/views/age-assurance-v2.test.ts — 29 passed, 1 skipped

Two production files were pinning the legacy client stack into bsky's
shipped artifact: the age assurance region/rule helpers were imported
from @atproto/api, whose `age-assurance.ts` is hand-written logic that
happens to live alongside the legacy generated client.

Port those helpers into `api/age-assurance/util.ts`, typed against the
generated `app.bsky.ageassurance.defs` schemas. The legacy
`isConfigRegionRuleX()` guards become `$isTypeOf`, and `AgeAssuranceRuleID`
is derived from the schemas' `$type` constants rather than hand-built
NSID strings. Rule ordering and comparisons are unchanged.

@atproto/api moves to devDependencies — the 58 test files still drive the
services through AtpAgent, which dev-env hands them, so it can't go away
entirely until dev-env migrates. The `../api` project reference moves to
tsconfig.test.json accordingly, mirroring packages/pds.

Also converts the age-assurance-v2 config fixture to `$build` so it is
checked against the same schema the production code consumes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@bigmoves
bigmoves marked this pull request as ready for review August 17, 2026 21:41
* provided platform is included in that list. If no platform filter is
* provided, platform restrictions are ignored.
*/
export function getAgeAssuranceRegionConfig(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be able to use @bsky/sdk for this and other age assurance helpers.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -0,0 +1,267 @@
import { describe, expect, it } from 'vitest'

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can nix this once we move to @bsky/sdk for the age assurance utils.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per review feedback: rather than porting the age assurance region/rule
helpers into this repo, take them from @bsky/sdk, which already ships
`getAgeAssuranceRegionConfig`, `computeAgeAssuranceRegionAccess`, and
`AgeAssuranceRuleID` typed against @atproto/lex.

The SDK declares @atproto/lex as a peer dependency, so it resolves to the
workspace copy and its generated `app.bsky.ageassurance.defs` types are
compatible with this package's own tree — including AGE_ASSURANCE_CONFIG,
which is still built locally.

Drops the ported implementation and its unit tests; `util.ts` keeps only
the bsky-specific wrappers.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@bigmoves

Copy link
Copy Markdown
Contributor Author

@devinivy I updated to use bsky/sdk

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.

2 participants