Generate type-safe Dart repositories and models from your Supabase database schema.
- 🚀 Automatically generate Dart models and repositories
- 🔄 Support for real-time subscriptions
- 🔌 Works with local or remote Supabase instances
- 🧩 Generates complete CRUD operations
- 📦 Includes repository provider for dependency injection
- 🎯 Follows Dart naming conventions (camelCase for fields)
- 🔒 Type-safe JSON serialization with json_annotation
- 📝 Comprehensive documentation in generated code
- 🔄 Supports all common PostgreSQL data types
- 🎯 Generates proper Dart types based on PostgreSQL column types
- 📝 Supports nullable fields
- 🎯 Generates JSON serialization code
- 🎯 Generates repository methods for CRUD operations
- 🎯 Supports real-time subscriptions with Supabase stream
- 🎯 Generates a repository provider for easy dependency injection
- 🎯 Supports PostgreSQL enum types with proper Dart enum generation
- 🔄 Includes database functions as callable methods
- 📝 Documents database triggers for context
# Install globally
npm install -g supabase-dart-repo-generator-fixed
# Or use npx
npx supabase-dart-repo-generator-fixed
# Using environment variables
supabase-dart-repo-generator-fixed
# Direct PostgreSQL connection (recommended for local development)
supabase-dart-repo-generator-fixed --database postgresql://postgres:postgres@127.0.0.1:54322/postgres
# Supabase API connection
supabase-dart-repo-generator-fixed --url https://your-project.supabase.co --key your-service-key
# Using a schema file (bypasses database connection)
supabase-dart-repo-generator-fixed --schema path/to/schema.json
# Clone the repository
git clone https://github.com/Albaraazain/supabase-dart-repo-generator.git
cd supabase-dart-repo-generator
# Install dependencies
npm install
# Run tests
npm test
# Clean up the project (removes test files and directories)
npm run cleanup
-
-u, --url <url>
: Supabase URL -
-k, --key <key>
: Supabase service key -
-d, --database <url>
: PostgreSQL connection URL -
-o, --output <dir>
: Output directory (default:lib/generated
) -
-v, --verbose
: Enable verbose logging
You can also set these in a .env
file:
# For Supabase API access
SUPABASE_URL=http://localhost:54321
SUPABASE_SERVICE_KEY=your-service-key
# For direct PostgreSQL connection
DATABASE_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres
lib/generated/
├── enums/
│ ├── status_enum.dart
│ └── index.dart
├── models/
│ ├── index.dart
│ ├── user_model.dart
│ ├── user_model.g.dart (generated by build_runner)
│ └── ...
├── repositories/
│ ├── index.dart
│ ├── user_repository.dart
│ └── ...
└── repository_provider.dart
The generator now includes support for PostgreSQL functions and triggers:
- 🔄 Automatically generates Dart wrappers for all database functions
- 🎯 Type-safe parameters and return values
- 📝 Includes documentation from database comments
- 🧩 Accessible through the repository provider
Example usage:
// Access a database function
final result = await repositoryProvider.databaseFunctions.calculateTotal(userId: 123);
- 📝 Generates documentation for all database triggers
- 🔍 Includes trigger definitions for reference
- 📚 Helps understand automatic database behaviors
This feature allows you to:
- Test database functions directly in PostgreSQL first
- Then use those tested functions from your Dart code
- Have documentation about triggers for context
- Reduce runtime errors by ensuring database functions work before using them in code
The generated models include:
- 🔄 JSON serialization with
json_annotation
- 🎯 Dart naming conventions (camelCase) with original database names preserved
- 📝 Documentation comments for all fields
- 🔄
copyWith()
method for immutability - 📝
toString()
method for debugging - 🔒 Type-safe field access
The generated repositories include:
- 🧩 Complete CRUD operations
- 🔄 Real-time subscriptions with Supabase
- 🔒 Type-safe query methods
- 📝 Documentation comments
- Add required dependencies to your
pubspec.yaml
:
dependencies:
supabase_flutter: ^1.10.0
json_annotation: ^4.8.1
dev_dependencies:
build_runner: ^2.4.0
json_serializable: ^6.7.1
- Run build_runner to generate JSON serialization code:
flutter pub run build_runner build --delete-conflicting-outputs
- Initialize the repository provider in your app:
final repositoryProvider = RepositoryProvider(Supabase.instance.client);
ISC
- Added support for database functions with automatic Dart wrapper generation
- Added documentation for database triggers
- Improved repository provider to include database functions
- Enhanced schema fetcher to detect and include database functions and triggers
- Added type-safe parameter and return type handling for database functions
- Organized database functions by related tables in repositories
- Fixed HTML entity encoding issues in generated code
- Fixed issue with PostgreSQL interval type conversion
- Ensured interval fields are properly mapped to String type in Dart models
- Added special conversion methods for interval fields to handle different Dart types (String, int, double)
- Improved interval parsing to handle various interval formats
- Added support for PostgreSQL interval type handling
- Fixed issue with interval type conversion in Dart models
- Added special conversion logic for interval fields to handle int, double, and String types
- Updated documentation with interval type mapping information
- Fixed nullable enum field declarations in model classes
- Fixed type errors in copyWith method parameters for nullable enum types
- Ensured consistent type handling for nullable and non-nullable enum fields
- Fixed "missing_default_value_for_parameter" errors for nullable enum fields
- Fixed JSON serialization in generated models to use _$ClassNameFromJson and _$ClassNameToJson
- Removed duplicate toStringValue() method in enum classes
- Improved compatibility with json_serializable package
- Fixed linter errors that would cause build_runner to fail
- Fixed nullable enum handling in generated models
- Fixed type compatibility issues in copyWith methods for enum parameters
- Improved enum fromString method to always return a non-null value for non-nullable fields
- Fixed double question mark issue in copyWith method for nullable enum types
- Updated toStringValue method in enum classes for better consistency
- Fixed duplicate enum imports in generated model files
- Fixed type compatibility issues in copyWith methods for non-nullable enum parameters
- Improved handling of enum types in generated code to prevent type errors
- Fixed unnecessary null-aware operators on non-nullable types
- Fixed undefined method errors for enum fromString methods
- Added static fromString method directly on enum classes
- Improved type safety for non-nullable enum fields
- Fixed null-aware operator usage on non-nullable types
- Added nullable enum extension methods for better type safety
- Fixed type compatibility issues between enum fields and their JSON conversion functions
- Ensured non-nullable enum fields have proper fallback values
- Improved handling of null values in enum conversions
- Fixed SQL script for enum type detection and conversion
- Improved error handling in enum type conversion
- Added support for handling enum values with spaces
- Enhanced get_enum_types function for better enum detection
- Fixed HTML entity encoding in generated enum files
- Improved enum support with proper PostgreSQL enum type detection
- Added SQL script for converting text columns to enum types
- Enhanced documentation for setting up and using enum types
- Fixed enum detection in text columns that should be enums
- Added enum support with automatic Dart enum generation
- Enhanced schema fetcher to detect enum types in PostgreSQL
- Updated models and repositories to utilize enum types
- Added documentation for enum support
- Added enum support with automatic Dart enum generation
- Enhanced schema fetcher to detect enum types
- Updated models and repositories to utilize enum types
- Fixed stream method in repository template to use primaryKey as a list of strings
- Updated to match the latest Supabase Dart SDK stream API requirements
- Fixed repository template to work with latest Supabase Dart SDK
- Removed references to deprecated response.error and response.data properties
- Updated response handling to match current SDK structure
- Fixed CLI version display to match package version
- Improved error handling for template path resolution
- Enhanced HTML entity handling in generated models
- Fixed template path resolution for global installations
- Updated CLI version number to match package version
- Added better error handling for missing templates
- Added support for generating code for all tables at once
- Improved PostgreSQL type mapping for better type safety
- Enhanced documentation comments for fields and methods
- Fixed issues with HTML entity encoding in generated models
- Optimized repository provider for lazy initialization
- Fixed issue with double question marks in copyWith method for nullable fields
- Improved type handling in generated models
- Fixed repository parameter naming to use camelCase instead of snake_case
- Improved consistency between model and repository naming conventions
- Fixed HTML entity encoding issues in generated models
- Ensured proper handling of nullable parameters in copyWith methods
- Improved toString method formatting
- Added support for camelCase field names in Dart models
- Improved JSON serialization with @JsonKey annotations
- Enhanced repository methods with better error handling
The generator supports PostgreSQL enum types and will automatically generate Dart enum classes for them. When a column in your database uses an enum type, the generator will create a corresponding Dart enum and use it in the generated models and repositories.
For the best experience with enum types, you should define them properly in your PostgreSQL database. Here's how:
-
Define the enum type:
CREATE TYPE user_role AS ENUM ('admin', 'user', 'guest');
-
Use the enum type in your table columns:
CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), name TEXT NOT NULL, role user_role NOT NULL DEFAULT 'user' );
-
Converting existing text columns to enum types: If you have existing text columns that should be enum types, you can convert them:
-- First, create the enum type CREATE TYPE user_role AS ENUM ('admin', 'user', 'guest'); -- Then, alter the column to use the enum type ALTER TABLE users ALTER COLUMN role TYPE user_role USING role::user_role;
We've provided a SQL script in sql/update_enum_columns.sql
that demonstrates how to define enum types and update columns to use them.
If you can't modify your database schema to use proper enum types (for example, in a shared database), you can use the get_enum_types()
function to tell the generator which text columns should be treated as enums:
CREATE OR REPLACE FUNCTION get_enum_types()
RETURNS TABLE(enum_name text, enum_value text) AS $$
BEGIN
RETURN QUERY
SELECT
t.typname::text as enum_name,
e.enumlabel::text as enum_value
FROM pg_type t
JOIN pg_enum e ON t.oid = e.enumtypid
JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
WHERE n.nspname = 'public'
ORDER BY t.typname, e.enumsortorder;
END;
$$ LANGUAGE plpgsql;
For each enum type, the generator will create a Dart enum class with methods for converting between string values and enum values. For example:
/// Represents the possible values for UserRole.
enum UserRole {
admin,
user,
guest;
/// Converts a string value from the database to the enum value
static UserRole fromString(String? value) {
if (value == null) return UserRole.admin;
return UserRole.values.firstWhere(
(e) => e.name == value,
orElse: () => UserRole.admin,
);
}
/// Converts the enum to a string for database storage
String toJson() => name;
}
The generated models will use these enum types and include conversion methods for JSON serialization:
@JsonSerializable()
class User {
@JsonKey(name: 'id')
final String id;
@JsonKey(name: 'name')
final String name;
@JsonKey(name: 'role', fromJson: _roleFromJson, toJson: _roleToJson)
final UserRole role;
// ... constructor, fromJson, toJson methods ...
// Enum conversion helpers
static UserRole _roleFromJson(dynamic value) =>
UserRole.fromString(value as String);
static String _roleToJson(UserRole value) =>
value.toJson();
}
The following PostgreSQL types are mapped to Dart types:
PostgreSQL Type | Dart Type |
---|---|
int, integer, serial, bigserial | int |
text, varchar, char, character varying | String |
boolean | bool |
real, double precision, float | double |
numeric, decimal | double |
json, jsonb | Map<String, dynamic> |
timestamp, timestamptz, timestamp with time zone, timestamp without time zone | DateTime |
date | DateTime |
time, timetz | String |
interval | String |
uuid | String |
bytea | List |
PostgreSQL's interval
type is mapped to String
by default. However, the generator includes special conversion logic to handle cases where you want to use int
or double
in your Dart model:
- If the field type in your model is
String
, the interval value is passed as-is. - If the field type is
int
, the interval is converted to seconds (hours * 3600 + minutes * 60 + seconds). - If the field type is
double
, the interval is converted to seconds with decimal precision.
Example of an interval field in a generated model:
@JsonKey(name: 'total_pause_duration', fromJson: _totalPauseDurationFromJson, toJson: _totalPauseDurationToJson)
final int? totalPauseDuration;
// Conversion methods
static int? _totalPauseDurationFromJson(dynamic value) {
if (value == null) return null;
// Convert PostgreSQL interval to seconds
if (value is String) {
try {
// Parse interval string like "00:17:02.998758"
final parts = value.split(':');
if (parts.length >= 3) {
final hours = int.parse(parts[0]);
final minutes = int.parse(parts[1]);
// Handle seconds with potential decimal part
final secondsPart = parts[2].split('.');
final seconds = int.parse(secondsPart[0]);
// Convert to total seconds
return hours * 3600 + minutes * 60 + seconds;
}
} catch (e) {
print('Error parsing interval: $value, $e');
}
}
return 0; // Default value if parsing fails
}
static dynamic _totalPauseDurationToJson(int? value) {
if (value == null) return null;
return value.toString();
}
- Fixed issue with PostgreSQL interval type conversion - now correctly maps to String? in Dart models
- Fixed issue with missing field types in generated Dart models
- Added special conversion methods for interval fields to handle different Dart types (String, int, double)
- Improved interval parsing to handle various formats
- Initial release