supabase_typegen 0.1.3
supabase_typegen: ^0.1.3 copied to clipboard
Command-line code generator that turns a Supabase database schema into typed Dart table definitions.
supabase_typegen #
Generates typed Supabase table definitions from your database schema, so
query results never expose raw Map<String, dynamic> data.
For every table the generator emits:
- a zero-cost row extension type over the decoded JSON map with typed getters,
InsertandUpdatevalue types that enforce required columns at the construction site,- a
PostgrestTabledefinition andPostgrestColumntokens for compile-time checked filters and orderings, with nullable columns asPostgrestNullableColumnsoisNull()only exists where it can match, and range columns typedPostgrestRange<int>,PostgrestRange<num>orPostgrestRange<DateTime>so the range operators only exist on them, PostgrestToOneRelationandPostgrestToManyRelationmembers for every foreign key between two generated tables of the selected schema, named after the table on the other side and carrying the constraint hint when two keys point at the same table. Keys into another schema and self-referential keys get no member, the latter because PostgREST needs a computed relationship to embed a table into itself,- Dart enums for Postgres enums, with wire-name mapping.
Usage #
The easiest way is through the Supabase CLI, which handles the database
connection and runs this package for you. Add supabase_typegen as a dev
dependency of your project (until the package is published to
pub.flutter-io.cn, depend on it with a git source pointing at
packages/supabase_typegen in this repository), then:
supabase gen types --lang dart --local > lib/supabase_schema.g.dart
Any of the CLI's connection flags work (--local, --linked, --db-url,
--project-id).
Under the hood the CLI runs the introspection of
@supabase/postgrest-typegen
in-process against the database (the same GeneratorMetadata intermediate
representation its TypeScript, Go, Swift, and Python generators consume,
ordered with sortGeneratorMetadata) and hands the document to this tool
over stdin. The types reflect the current state of the selected database:
with --local the SQL in your supabase/ directory stays the single source
of truth, since the CLI applies your migrations to the local database and
generates from the result, while --linked, --project-id, and --db-url
generate from whatever that database currently contains.
Use --schema to generate for a schema other than public, and --import
to change which library the generated file imports PostgrestTable and
PostgrestColumn from.
The metadata comes from the database catalog, so nullability, database
defaults, and identity columns are exact: a NOT NULL column with a default
reads as non-nullable but stays optional on insert, and GENERATED ALWAYS
columns appear in the row type but not in the insert and update types.
Generated code in action #
final books = await client.table(Books.table)
.select()
.where(Books.mood.eq(Mood.happy) & Books.publishedOn.isNull().not())
.order(Books.createdAt.desc()); // List<BooksRow>
await client.table(Books.table).insert(
BooksInsert(title: 'A typed row', tags: ['dart']),
);
Known limitations #
- Passing
nullto anInsert/Updateparameter omits the column. To write SQL NULL explicitly, use the generatedset…ToNullmethods, for exampleBooksUpdate(inPrint: false).setPriceToNull(); they only exist for nullable columns, so nulling aNOT NULLcolumn is a compile error. - Array elements are assumed non-null (
text[]maps toList<String>), matching the supabase-js type generator; arrays containing SQL NULL elements throw when the element is read. Enum, date, timestamp, and range array elements stay in their wire representation (List<String>); the Dart enum for enum array elements is still generated for manual conversion. timestamptzvalues are written back in UTC, naivetimestampvalues as local wall time, anddatevalues date-only, so calendar dates never shift with the client timezone.- Foreign keys into another schema get no relation member, since the row type on the other side is not generated. Typed functions (rpc) are not generated yet.