Skip to content

feat(api): support v2 namespace endpoints in @supabase/api - #6142

Draft
Coly010 wants to merge 4 commits into
developfrom
columferry/cli-2157-support-v2-namespace-endpoints-in-supabaseapi
Draft

feat(api): support v2 namespace endpoints in @supabase/api#6142
Coly010 wants to merge 4 commits into
developfrom
columferry/cli-2157-support-v2-namespace-endpoints-in-supabaseapi

Conversation

@Coly010

@Coly010 Coly010 commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

What changed

`@supabase/api` previously modeled only the Management API v1 namespace. The upstream API now publishes two OpenAPI documents (`/api/v1-json` and `/api/v2-json`), and the config endpoint needed by CLI-2156/CLI-2064 lives on v2. This PR makes v2 a first-class namespace:

  • `scripts/download-openapi.ts` fetches both documents from the same base URL, merges them (paths + `components.schemas` unioned with collision asserts; `info.title` normalized), applies overrides to the merged document, and validates operationId uniqueness and version/path agreement. A missing v2 document is a hard failure — tolerating it would silently delete the namespace and the hourly sync would auto-merge the deletion.
  • `scripts/generate.ts` derives the client namespace from the path's leading segment (`/v2/...` → `api.v2.*`) instead of the operationId prefix, with a hard error on duplicate `(version, method)` pairs. Adding a v3 later requires no generator changes. All 170 existing v1 operations produce byte-identical output — the regenerated `contracts.ts`/`effect-client.ts` diff is additions-only (verified: zero removed lines).
  • `scripts/openapi-overrides.json` gains a tolerant `remove` op (remove-if-present, a documented RFC 6902 deviation) and 13 entries removing the v2 webhook paths + `APIErrorObject`. Upstream spec bug: all 10 project-webhook operations share one operationId (`allV2ProjectsByRefWebhooks`), the 10 org-webhook ones share another — duplicated and not version-prefixed, which breaks codegen. Removing them is also what makes staging's v2 document deterministic (staging currently serves two variants that differ by exactly these paths).
  • `scripts/openapi-source.json` (new, committed) pins the spec source base URL so `pnpm generate` reproduces the snapshot with no env var, and makes provenance visible in diffs. `SUPABASE_API_URL` still overrides it.
  • Drift detection: `src/generated-contract-sync.unit.test.ts` asserts a full bijection between the committed snapshot and the generated modules in ordinary PR CI (this is what catches a hand-edited snapshot or client — the failure mode from the feat(cli): add config pull command #6111 POC). `pnpm generate:check` mirrors the hourly sync's regenerate→format→diff sequence for live verification.
  • `api-package-sync.yml` is pinned to `https://api.supabase.com\` so develop's hourly sync always regenerates from prod regardless of the sidecar.

⚠️ Merge gate — snapshot is generated from staging

`GET /v2/projects/{ref}/config` (`api.v2.getProjectConfig`, the proving case from CLI-2137/CLI-2157) has not shipped to prod yet, so the committed snapshot is generated from `api.supabase.green`. After the webhook removals, that endpoint is the entire prod↔staging delta. Do not merge until either:

  1. the endpoint ships to prod (the hourly sync will then keep it), or
  2. the snapshot is regenerated from prod at merge time (re-point `scripts/openapi-source.json`, delete the one staging-only test in `client.unit.test.ts`) — which un-blocks this PR but re-blocks the stacked CLI-2156/CLI-2064 branches.

Otherwise develop's first hourly sync after merge will auto-merge a PR deleting the endpoint from the client. Fallback if a staging-sourced snapshot is unacceptable: switch the sidecar to prod and inject the config endpoint via `add` overrides (~10KB) — the `add` hard-fails the day prod ships it, a self-removing reminder.

Known limitation

Three v2 operations (`v2-list-organization-members`, `v2-list-organization-projects`, `v2-list-organization-github-connections`) declare `style: deepObject` object query params, which the client currently serializes as JSON strings rather than `page[size]=...`. Documented in the README; the typed surface is correct, the wire format for those params is not.

Part of CLI-2157 (unblocks CLI-2156 and CLI-2064).

Fetch and merge both Management API OpenAPI documents (/api/v1-json and
/api/v2-json), derive client namespaces from the path, and regenerate the
snapshot so v2 operations are callable as api.v2.<operation>.

- download-openapi.ts: two-document fetch (hard-fail on a missing doc),
  structural merge with collision asserts, tolerant remove override op,
  committed source pin in scripts/openapi-source.json (staging for now:
  GET /v2/projects/{ref}/config has not shipped to prod yet)
- generate.ts: version namespace derived from the leading path segment,
  duplicate-operation hard error; v1 output is byte-identical
- openapi-overrides.json: remove the v2 webhook paths (upstream spec bug:
  duplicated, non-version-prefixed operationIds) and APIErrorObject
- api-package-sync.yml: pin hourly sync to prod, diff the source pin
- generate:check script + README spec-pipeline/override/merge-gate docs
- generated-contract-sync.unit.test.ts: bijection between the committed
  openapi.json snapshot and the generated contracts/effect client, so a
  hand-edited snapshot or client fails CI
- client.unit.test.ts: 404 on a v2 operation surfaces as a StatusCodeError
  with the response status; v2 requests carry identical auth/base-url
  wiring; nested V2ProjectConfigResponse payload decodes strictly
- effect.unit.test.ts: same-named v1/v2 operations are separately
  addressable per namespace
- export OpenApiDocument/OpenApiOperation types from generate.ts for
  typed test fixtures
ApiClient now carries a v2 namespace, so the v1-only mock object no
longer overlaps the ApiClient type. The legacy shell only calls v1
operations; v2 calls die loudly as wiring bugs.
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