Skip to content

feat(cli): generate types natively with postgrest-typegen - #6404

Open
avallete wants to merge 9 commits into
developfrom
claude/postgrest-typegen-cli-wud64e
Open

feat(cli): generate types natively with postgrest-typegen#6404
avallete wants to merge 9 commits into
developfrom
claude/postgrest-typegen-cli-wud64e

Conversation

@avallete

@avallete avallete commented Aug 31, 2026

Copy link
Copy Markdown
Member

Summary

Replaces the pg-meta Docker container behind gen types with the new @supabase/postgrest-typegen package (0.2.0), running introspection and language generation in-process over a direct Postgres connection.

  • New LegacyGenTypesGenerator service seam: the production layer acquires a scoped pg.Pool via legacyAcquirePgPool (full driver parity: TLS mode, DoH resolver, connect-error mapping), feeds it to introspect(), sorts with sortGeneratorMetadata, and renders typescript/go/python/swift.
  • --local connects to the host-mapped db port instead of spawning the pg-meta image inside the stack network; the container inspect stack-running check and rest-version v9 forcing are unchanged. The obsolete .temp/pgmeta-version image override is removed.
  • --db-url now resolves through the shared LegacyDbConfigResolver (libpq keywords, options=reference pooler tenants, sslmode, PG* env fallbacks), matching every other --db-url command. When the DSN carries no explicit sslmode, the existing SSLRequest probe decides whether to connect with sslmode=disable, so plain-TCP servers (common when self-hosting) keep working as they did with pg-meta.
  • Project-ref non-TypeScript paths and the preview-branch fallback keep their Management API flow and IPv4 pooler retry, now classifying the native connect error instead of container stderr. The --linked/--project-id TypeScript path still uses the Management API unchanged.
  • --query-timeout maps to statement_timeout plus the connect timeout; --postgrest-v9-compat disables one-to-one detection in the TypeScript generator; output keeps the trailing newline pg-meta's console.log added.
  • oxfmt (the package's formatter since 0.2.0) resolves its napi binding through createRequire(import.meta.url), which bun build --compile cannot follow, so the CLI embeds the platform binding statically (the @parcel/watcher pattern) and injects it through the generator's format option — verified byte-equivalent to the package default. The never-installed optional prettier plugins oxfmt lazily imports are marked external in both build scripts.

Output parity against postgres-meta 0.98.0 on the same database: Swift byte-identical; Go and Python identical content in canonical sorted order (pg-meta emitted environment-dependent SQL row order); TypeScript identical content with oxfmt's union-wrapping style. Details in the command's SIDE_EFFECTS.md.

Linked issue

Resolves CLI-2279 (no GitHub issue).

  • The linked issue is open and carries the open-for-contribution label (or I'm a Supabase maintainer).

Checklist

  • The PR title follows Conventional Commits (e.g. fix(cli): …).
  • Tests added or updated for the change.
  • From the repository root, pnpm check:all passes; relevant package tests pass for every touched workspace, and pnpm types:check passes for each touched TypeScript workspace (or workspace declaring it).

https://claude.ai/code/session_01RpnbmgTzwdTMkWYF7uFR1V

claude added 2 commits August 31, 2026 11:48
Replace the pg-meta Docker container behind `gen types` with the new
@supabase/postgrest-typegen package, running introspection and language
generation in-process over a direct Postgres connection.

- New LegacyGenTypesGenerator service seam: the production layer acquires
  a scoped pg.Pool via legacyAcquirePgPool (full driver parity: TLS mode,
  DoH resolver, connect-error mapping), feeds it to introspect(), sorts
  with sortGeneratorMetadata, and renders typescript/go/python/swift.
- `--local` connects to the host-mapped db port instead of spawning the
  pg-meta image inside the stack network; the `container inspect`
  stack-running check and rest-version v9 forcing are unchanged. The
  obsolete `.temp/pgmeta-version` image override is removed.
- `--db-url` now resolves through the shared LegacyDbConfigResolver
  (libpq keywords, options=reference pooler tenants, sslmode, PG* env
  fallbacks), matching every other --db-url command.
- Project-ref non-TypeScript paths and the preview-branch fallback keep
  their Management API flow and IPv4 pooler retry, now classifying the
  native connect error instead of container stderr.
- `--query-timeout` maps to statement_timeout plus the connect timeout,
  mirroring the PG_QUERY_TIMEOUT_SECS/PG_CONN_TIMEOUT_SECS envs pg-meta
  received; `--postgrest-v9-compat` disables one-to-one detection in the
  TypeScript generator; output keeps the trailing newline console.log
  added in pg-meta.
- The pg-meta SSL probe, CA bundle templates, and --network-id container
  override are gone with the container; the linked TypeScript path still
  uses the Management API unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RpnbmgTzwdTMkWYF7uFR1V
Validated the native typegen end-to-end against a real Postgres 16 and
against postgres-meta 0.98.0 on the same schema, which surfaced two issues:

- The driver requires TLS for remote-looking targets, so `gen types
  --db-url` against a plain-TCP server (common when self-hosting) failed
  where the pg-meta path adapted via its SSL probe. Restore that
  adaptivity in the generator layer: when the DSN carries no explicit
  sslmode, the shared SSLRequest probe decides whether to connect with
  sslmode=disable; probe failures keep the TLS default so the real
  connect error still surfaces.
- prettier 3.5.3 (postgrest-typegen's pin) trips a Bun bundler renaming
  bug under `bun build --compile`, breaking TypeScript generation in the
  compiled binary only. Override it to the repo's prettier 3.9.6, which
  bundles cleanly; pg-meta itself floated ^3.3.3, so there is no
  output-parity concern.

Parity results against postgres-meta on the same database: TypeScript and
Swift byte-identical; Go and Python identical content with canonical
sorted entity ordering (sortGeneratorMetadata) instead of pg-meta's
environment-dependent row order. Documented in SIDE_EFFECTS.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RpnbmgTzwdTMkWYF7uFR1V
@avallete
avallete requested a review from a team as a code owner August 31, 2026 14:34
develop's SUPABASE_USE_SLIM_IMAGES change (de133cf) touched gen types only
through resolvePgmetaImage and its tests, all of which this branch deletes
with the pg-meta container path, so the branch side wins in all four files.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RpnbmgTzwdTMkWYF7uFR1V

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6d8c60d5cf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/cli/src/legacy/commands/gen/types/types.handler.ts
Comment thread apps/cli/src/legacy/commands/gen/types/types.generator.layer.ts Outdated
Comment thread apps/cli/src/legacy/commands/gen/types/types.generator.layer.ts Outdated
0.2.0 drops prettier for oxfmt, so the prettier bundling override goes
away. oxfmt's ESM dist resolves its napi binding through
createRequire(import.meta.url) and lazily imports optional prettier
plugins — neither survives `bun build --compile` — so the CLI:

- embeds the platform binding statically (the @parcel/watcher pattern:
  one @oxfmt/binding-* devDependency per shipped target, dispatched on
  platform/arch/SUPABASE_LIBC in types.oxfmt.ts) and injects it through
  the generator's new `format` option, verified byte-equivalent to the
  package's own default formatter;
- marks the never-installed optional prettier plugins external in both
  the dev and release build scripts (shared bundle-externals.ts).

Revalidated against a real Postgres 16 from the compiled binary:
Go/Swift/Python output is byte-identical to the 0.1.0 integration;
TypeScript content is identical with oxfmt's union-wrapping style
(three lines differ from the prettier-era output), and source-run vs
compiled-binary output is identical. SIDE_EFFECTS.md parity note
updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RpnbmgTzwdTMkWYF7uFR1V
@avallete avallete changed the title refactor(cli): migrate gen types to postgrest-typegen library feat(cli): generate types natively with postgrest-typegen Aug 31, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ebb449be92

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/cli/src/legacy/commands/gen/types/types.generator.layer.ts Outdated
Comment thread apps/cli/src/legacy/commands/gen/types/types.generator.layer.ts Outdated
Comment thread apps/cli/src/legacy/commands/gen/types/SIDE_EFFECTS.md Outdated
Comment thread apps/cli/src/legacy/commands/gen/types/types.errors.ts
avallete and others added 4 commits August 31, 2026 18:06
Keep native typegen SIDE_EFFECTS; drop the slim-image pg-meta notes
develop added, since this command no longer runs that container.

Co-authored-by: Cursor <cursoragent@cursor.com>
Pin the embedded Supabase CA when the SSL probe reports TLS, treat
--query-timeout 0 as disabled rather than an immediate connect
timeout, let the flag override a DSN statement_timeout, bound
introspect() on the client, and classify generator/formatter
failures as internal instead of database findings.

Co-authored-by: Cursor <cursoragent@cursor.com>
A probe error still leaves sslmode unset so the driver default and
IPv6 pooler classification stay intact.

Co-authored-by: Cursor <cursoragent@cursor.com>
Drop the duplicate TLS-probe comment, unused network-id test wiring,
and a leftover localNetworkId assertion. Clarify that a TLS probe
replaces sslrootcert when sslmode is omitted.

Co-authored-by: Cursor <cursoragent@cursor.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 39cb1577fe

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +91 to +93
? yield* introspectEffect.pipe(
Effect.timeoutOrElse({
duration: Duration.seconds(input.queryTimeoutSeconds),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Cancel the database operation when timing out

When an established connection stalls during introspection, this timeout interrupts only the Effect.tryPromise waiter; it does not cancel the underlying pool.query. The fresh evidence after the earlier review is that scope cleanup calls pool.end() through legacyAcquireProbedPool, but an active checked-out query prevents pool.end() from completing, and its one-second timeoutOption neither destroys the client nor closes its socket. Consequently the timeout error may be produced while the live socket still keeps the CLI process running indefinitely; make the foreign boundary cancellable by destroying/cancelling the owned query or pool when this timeout fires.

AGENTS.md reference: AGENTS.md:L92-L97

Useful? React with 👍 / 👎.

Comment on lines +61 to +64
if (typeof SUPABASE_LIBC !== "undefined" && SUPABASE_LIBC === "musl") {
return require("@oxfmt/binding-linux-x64-musl");
}
return require("@oxfmt/binding-linux-x64-gnu");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Detect musl outside release builds

When the CLI runs from source or is compiled with the standard build:legacy/build-binary.ts path on Alpine, SUPABASE_LIBC is never defined, so this condition is always false and the glibc binding is loaded on a musl system. The native addon then cannot load, causing TypeScript generation to fail; only the multi-target release build currently injects this define. Detect the current libc when the define is absent or pass the corresponding define from build-binary.ts.

Useful? React with 👍 / 👎.

The glibc and local compile paths already pass oxfmtExternalArgs; musl
release binaries were still resolving those never-installed prettier
plugins and would fail bun build --compile.

Co-authored-by: Cursor <cursoragent@cursor.com>
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