Skip to content

feat(gen): add dart and json output languages to gen types - #6230

Closed
spydon wants to merge 4 commits into
developfrom
feat/gen-types-json-dart
Closed

feat(gen): add dart and json output languages to gen types#6230
spydon wants to merge 4 commits into
developfrom
feat/gen-types-json-dart

Conversation

@spydon

@spydon spydon commented Aug 17, 2026

Copy link
Copy Markdown

Summary

Adds two --lang values to supabase gen types, making supabase gen types --lang dart work end to end:

  • json: passes the language-neutral GeneratorMetadata introspection document (the @supabase/postgrest-typegen contract) 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 the json generator, collects the metadata instead of printing it, and pipes it through dart 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 the supabase_typegen package 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:

Implementation notes:

  • The lang additions are TS-only and documented in docs/go-cli-divergences.md; SIDE_EFFECTS.md covers the new dart subprocess and the json-collection behavior.
  • The invocation contract (dart run supabase_typegen --input - --output -) is pinned in types.shared.ts so the handler and tests share one definition.
  • Integration tests cover the json passthrough 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 #

  • 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.
  • pnpm check:all and pnpm test pass for the workspace(s) I touched (check:all fully; unit and integration suites for gen types pass, the docker-dependent e2e suite was not run locally).

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.
@spydon

spydon commented Sep 1, 2026

Copy link
Copy Markdown
Author

Superseded by the native typegen architecture in #6404: the CLI holds the sorted GeneratorMetadata in-process there, so --lang dart can hand the document to the Dart generator directly and no pg-meta container or user-facing --lang json is needed. A small follow-up on top of #6404 will add the dart flag.

@spydon spydon closed this Sep 1, 2026
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 -->
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