Skip to content

docs: generate the stack-supabase reference, and stop overstating the API gate - #80

Merged
coderdan merged 1 commit into
v2from
docs/api-validation
Jul 28, 2026
Merged

docs: generate the stack-supabase reference, and stop overstating the API gate#80
coderdan merged 1 commit into
v2from
docs/api-validation

Conversation

@coderdan

Copy link
Copy Markdown
Contributor

Three changes, all about the docs telling the truth about the SDK.

1. @cipherstash/stack-supabase is now in the TypeDoc entry points

Stack 1.0 split the Supabase adapter into its own package and the entry points were never updated, so nothing in it reached the generated reference — encryptedSupabaseV3, the query builder, and its EQL-version constraints were all absent. 19 pages now generate (763 total, up from 706).

The payoff is that constraints stop depending on someone reading the source. This is now published automatically:

contains() on encrypted column "x" is unavailable with EQL 3.0.2+: the SQL operator requires an eql_v3.query_* cast that PostgREST cannot express. Use the Drizzle or Prisma Next adapter, or a scoped SQL/RPC function.

2. Workspace subpath imports resolve to source

Adding the entry point alone produced 42 × TS2307. stack-supabase imports its sibling by package name (@cipherstash/stack, /schema, /adapter-kit, …), which resolves through that package's exports map to ./dist — and the clone is never built. Every cross-package type would have documented as any, the same failure #77 fixed for protect-ffi.

Fixed by deriving the tsconfig paths from the sibling's own exports map (./dist/x.js./packages/<pkg>/src/x.ts) rather than hardcoding twelve subpaths. Two aren't guessable — /typestypes-public.ts, /v3encryption/v3.ts — which is the argument for deriving rather than transcribing, and it won't rot when Stack adds a subpath.

3. The content API gate no longer overstates itself

It printed ✓ no deprecated or non-existent API found in documentation while the Supabase page taught .contains() for encrypted free-text, which raises. It's a denylist of 7 patterns, not verification. Now:

✓ content API gate: no occurrences of 7 known-retired API pattern(s) in 132 file(s) (143 generated/pinned file(s) skipped).
  Denylist only: it does not verify that the APIs the docs DO name still exist.

On the version-diff denylist — I did not build it, and I think that's right

We agreed on deriving the denylist from removed/renamed symbols between Stack versions. Checking before building, it would not have caught the bug that motivated it:

contains matches
@cipherstash/stack@1.0.0-rc.3 3 2
@cipherstash/stack@1.0.0-rc.4 3 2

contains() was repurposed, not removed — it's present in every tag, so no symbol-presence diff fires. A signature diff would in principle catch the changed type constraint, but the rename landed in 1.0.0-rc.0, whose predecessor is 0.18.0 — a different major where Supabase lived inside packages/stack. The signal would have been buried in the noise of the entire 1.0 restructure.

Building it anyway would have added a second check that reports confidence it can't back — the exact problem this PR is fixing. The file header now records the finding and points at what would actually work: typechecking the documented examples against the installed SDK, the way Rust compiles doctests. That catches contains()-on-a-text-column as a type error, and it's the only approach here that generalises. Happy to scope it as a follow-up — my suggestion is to start with the reference pages, where examples are most nearly complete, and opt pages in rather than boiling the ocean.

Also: CLAUDE.md's "Required Skills" section removed

All six skills it mandated — encryption, secrets, drizzle, supabase, dynamodb, update-docs — do not exist, so an instruction to "always use" them for API accuracy was unenforceable. Its validation checklist was stale too: switcher appears in 0 files and the "Good to know" callout in 1, versus <Callout> in 37. The accurate items are already covered by the Frontmatter, Code Blocks, and Formatting sections above it.

Verified

bun run build green: 0 TypeDoc errors (from 42), 763 pages, EQL drift clean, no broken links, all validators pass. biome check clean.

https://claude.ai/code/session_01NkuQNMvw9BpB4BWWeKtfV8

… API gate

Three changes, all about the docs telling the truth about the SDK.

1. Add @cipherstash/stack-supabase to the TypeDoc entry points.

Stack 1.0 split the Supabase adapter into its own package, and the entry points
were never updated, so NOTHING in it reached the generated reference —
encryptedSupabaseV3, the query builder, and the EQL-version constraints on its
encrypted operators were all absent. 19 pages now generate (763 total, up from
706), including the constraint that free-text and JSON operators are
"unavailable with EQL 3.0.2+" because PostgREST cannot express the required
eql_v3.query_* cast. That is now published automatically instead of relying on
someone reading the source.

2. Resolve a workspace package's subpath imports to source.

stack-supabase imports its sibling by package name (@cipherstash/stack,
/schema, /adapter-kit, ...), which resolves through that package's exports map
to ./dist — and the clone is never built, so all 42 imports were TS2307 and
every cross-package type would have documented as `any`. Derive the tsconfig
`paths` from the sibling's own exports map, rewriting ./dist/x.js to
./packages/<pkg>/src/x.ts, rather than hardcoding twelve subpaths that would
rot the next time Stack adds one. Two of them are not guessable
(`/types` -> types-public.ts, `/v3` -> encryption/v3.ts), which is the argument
for deriving rather than transcribing.

3. Say what the content API gate actually checks.

It printed "no deprecated or non-existent API found in documentation" while the
Supabase page taught `.contains()` for encrypted free-text, which raises. It is
a denylist of 7 patterns, not verification, so it now reports the rule count and
files scanned and states the limitation outright.

Deliberately NOT adding the version-diff denylist discussed: `contains()` was
repurposed rather than removed, so it is present in every tag and no
symbol-presence or signature diff fires on it. Catching that class needs the
examples typechecked against the SDK; the header now records that.

Also removes CLAUDE.md's "Required Skills" section. All six skills it mandated
(encryption, secrets, drizzle, supabase, dynamodb, update-docs) do not exist,
and its validation checklist was stale too — `switcher` appears in 0 files and
the "Good to know" callout in 1, versus <Callout> in 37. Its accurate items are
already covered by the Frontmatter, Code Blocks, and Formatting sections above.

Claude-Session: https://claude.ai/code/session_01NkuQNMvw9BpB4BWWeKtfV8
@vercel

vercel Bot commented Jul 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
public-docs Ready Ready Preview, Comment Jul 28, 2026 9:08am

Request Review

@coderdan
coderdan merged commit 57dd44f into v2 Jul 28, 2026
2 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