feat(gen): add dart and json output languages to gen types - #6230
Closed
spydon wants to merge 4 commits into
Closed
Conversation
This was referenced Aug 17, 2026
feat: add supabase_typegen package generating typed table definitions
supabase/supabase-flutter#1635
Merged
lvinist
added a commit
to lvinist/mine-flow-app
that referenced
this pull request
Aug 25, 2026
… harden guard - Remove lib/core/data/models/generated/database.dart (10-line hand-written stub of empty classes; Dart typegen was removed from the Supabase CLI — supabase/cli#6230 to restore it is still a draft) - Add supabase/types/database.ts: real 'supabase gen types --lang typescript' output against staging (714 lines, all 9 tables + enums), now the committed contract artifact per Option 1 decision - Harden tool/check_supabase_contracts.dart: reject artifacts missing the 'export type Database' / '__InternalSupabase' typegen markers or under a minimum size (stub class of phantom close); repoint all paths - Update guard tests: +stub-rejection case, artifact helpers; 4/4 pass Verification: dart run tool/check_supabase_contracts.dart exit 0; flutter test 435/435 (was 434); flutter analyze 0 issues.
Author
|
Superseded by the native typegen architecture in #6404: the CLI holds the sorted GeneratorMetadata in-process there, so |
spydon
added a commit
to supabase/supabase-flutter
that referenced
this pull request
Sep 1, 2026
…#1635) ## What kind of change does this PR introduce? Feature (draft, layer 2 of the typed table access work, stacked on #1634). Adds a new `supabase_typegen` package: a standalone code generator that turns a database schema into the typed table definitions introduced in #1634, so users get the fully typed surface without writing any of it by hand. Linear: SDK-1362 ## What is the new behavior? ```sh supabase gen types --lang dart --local > lib/supabase_schema.g.dart ``` The CLI runs postgrest-typegen's introspection in-process against the database and hands the language-neutral `GeneratorMetadata` document, the intermediate representation of [`@supabase/postgrest-typegen`](https://github.com/supabase/sdk/tree/main/packages/postgrest-typegen) that its TypeScript, Go, Swift, and Python generators also consume, to this tool over stdin. The tool emits one Dart file containing, per table: - a zero-cost row extension type over the decoded JSON map with typed getters (`DateTime` parsing, `double`/`num` coercion, `List` casts, Postgres enum mapping), - `Insert` and `Update` value extension types that implement `Map<String, dynamic>`, with required parameters derived from `NOT NULL`-without-default columns and null-aware omission for everything else; explicit SQL NULL writes go through generated `set…ToNull` copy methods that only exist for nullable, writable columns, - a `PostgrestTable` definition plus `TableColumn` tokens for compile-time checked filters, - Dart enums for Postgres enums with wire-name mapping (`toString` returns the wire name so enum values work directly in filters). See `packages/supabase_typegen/test/goldens/supabase_schema.dart` for what the output looks like for the fixture schema. Design choices worth reviewing: - **Introspection source**: the `GeneratorMetadata` contract of `@supabase/postgrest-typegen` (version 1, as shipped in the released 0.2.0 and embedded in postgres-meta v0.99.0). The CLI produces the document by running the package's `introspect()` in-process against the local database; there is no postgres-meta dependency. The document comes straight from the database catalog, so the output is exact where API-derived descriptions are lossy: `NOT NULL` columns with a database default read as non-nullable but stay optional on insert, identity columns are recognized, and `GENERATED ALWAYS` columns appear in the row type but are excluded from the insert and update types. Structural validation rejects non-matching documents. - **Relation and column writability**: tables and foreign tables emit the full surface; views gate `Insert` and `Update` independently on `is_insert_enabled` and `is_update_enabled` (falling back to `is_updatable` for documents predating the flags), so a view writable only through an INSTEAD OF INSERT trigger gets exactly an insert type; materialized views are read-only; non-updatable view columns read but are excluded from writes. This mirrors the TypeScript generator's semantics. - **Exact enum resolution**: a column's enum type resolves by its `type_schema` plus type name, so same-named enums in different schemas cannot be confused. - **Canonical ordering**: columns are emitted in the order `sortGeneratorMetadata` produces (name order within a table), matching every other postgrest-typegen generator and keeping output insensitive to column declaration order. - **Naming**: `books` emits `BooksRow`/`BooksInsert`/`BooksUpdate` plus a `Books` namespace class (no English singularization, so names stay predictable). Identifiers are sanitized against Dart reserved words and `Map` member names with a `$` suffix, and collisions are deduplicated. - **Lint-clean output**: the emitted code (checked in as a golden) passes `supabase_lints` and DCM with zero issues, including the strict extension type rules. ## Additional context - The metadata fixture is regenerated from a real introspection and stays reproducible: `test/fixtures/seed.sql` applied to a disposable Postgres container, introspected with the released `@supabase/postgrest-typegen@0.2.0` via `tool/regenerate_fixture.ts`. - CLI exposure as `supabase gen types --lang dart` is a small follow-up on supabase/cli#6404, which already runs postgrest-typegen's `introspect()` in-process: the CLI serializes the sorted document and pipes it to `dart run supabase_typegen` over stdin, the tool's only input channel. No pg-meta container, no metadata file on disk, and no user-facing json output language are involved (the earlier container-based supabase/cli#6230 is closed as superseded). - The package is excluded from the SDK compliance scan via `.sdk-parse-ignore` since it is a development-time tool, not SDK client surface; the symbol, drift and schema checks pass locally against the base branch. - `supabase_typegen` is added to the CI dart test matrix; tests are fully mocked/fixture-based (introspection unit tests over the checked-in metadata fixture, a whitespace-insensitive golden comparison with a `tool/regenerate_goldens.dart` refresh script, and behavior tests that run the generated golden code against a mock HTTP client to verify wire formats end to end). - `publish_to: none` until the API settles. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a Dart generator for strongly typed Supabase tables, rows, inserts, updates, columns, relationships, views, and Postgres enums. * Added the `supabase_typegen` command-line tool, accepting metadata through standard input and writing generated code to the terminal or a file. * Added safe handling for dates, timestamps, enums, arrays, comments, and reserved identifiers. * **Documentation** * Updated usage guidance, schema-target behavior, generated-code examples, options, and limitations. * **Tests** * Added comprehensive coverage for generation, parsing, serialization, views, relationships, enums, and typed data access. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds two
--langvalues tosupabase gen types, makingsupabase gen types --lang dartwork end to end:json: passes the language-neutralGeneratorMetadataintrospection document (the@supabase/postgrest-typegencontract) straight through (the same catalog introspection the typescript/go/swift/python generators consume, with exact nullability, defaults, and identity information). This gives third-party and community type generators a single high-fidelity source instead of parsing lossy API descriptions.dart: runs the pg-meta container with thejsongenerator, collects the metadata instead of printing it, and pipes it throughdart run supabase_typegen --input - --output -on the host. The generated Dart code arrives on stdout like every other language; the typegen's summary line goes to stderr. Requires the Dart SDK on PATH and thesupabase_typegenpackage as a dev dependency of the current project; a missing SDK or failing typegen produces an actionable error.Both languages work on every connection path (
--local,--db-url,--linked,--project-id, and the implicit linked fallback), since non-TypeScript languages already run pg-meta directly.Draft because of upstream dependencies:
GeneratorMetadatacontract, and feat: consume @supabase/postgrest-typegen for type generation postgres-meta#1084 makes postgres-meta consume that package; thejsonvalue forPG_META_GENERATE_TYPESis added on top of it in feat: add json output exposing the GeneratorMetadata contract postgres-meta#1110 (stacked on fix: bump edge-runtime to v1.2.19 #1084; It should be possible to run npx supabase init without human interaction #1106 was closed as a duplicate of that stack), and this PR needs a pg-meta image that ships it.supabase_typegenpackage (its--input -/--output -stdin/stdout contract is already in place there).Implementation notes:
docs/go-cli-divergences.md;SIDE_EFFECTS.mdcovers the newdartsubprocess and the json-collection behavior.dart run supabase_typegen --input - --output -) is pinned intypes.shared.tsso the handler and tests share one definition.jsonpassthrough env, the dart pipe (metadata collected rather than printed, dart argv, generated code on stdout), and the non-zero typegen exit error.Linked issue
Closes #
open-for-contributionlabel (or I'm a Supabase maintainer).Checklist
fix(cli): …).pnpm check:allandpnpm testpass for the workspace(s) I touched (check:allfully; unit and integration suites forgen typespass, the docker-dependent e2e suite was not run locally).