suparepo 1.0.0
suparepo: ^1.0.0 copied to clipboard
Generate repository/data access layer code from Supabase database schema. Automatically creates CRUD operations, queries, and type-safe API clients.
suparepo #
Generate repository/data access layer code from Supabase database schema automatically.
Features #
- Automatic CRUD operation generation (getAll, getById, create, update, delete)
- Type-safe when used with supafreeze models
- Pagination support
- Count queries
- Relation handling with embedded queries
Installation #
dependencies:
suparepo: ^1.0.0
Usage #
1. Create Configuration #
Create suparepo.yaml in your project root:
url: ${SUPABASE_DATA_API_URL}
secret_key: ${SUPABASE_SECRET_KEY}
output: lib/repositories
# Optional: Link to your model classes (generated by supafreeze)
model_import_path: package:myapp/models/models.dart
# Optional: Generate barrel file
generate_barrel: true
# Optional: Filter tables
include:
- users
- posts
# Or exclude tables
exclude:
- _migrations
2. Set Environment Variables #
Create .env file:
SUPABASE_DATA_API_URL=https://your-project.supabase.co
SUPABASE_SECRET_KEY=your-service-role-key
3. Run Generator #
dart run suparepo
Generated Code Example #
For a users table with columns id, email, name, the generated code looks like:
class UsersRepository {
final SupabaseClient _client;
UsersRepository(this._client);
Future<List<User>> getAll() async {
final response = await _client.from('users').select();
return response.map((e) => User.fromJson(e)).toList();
}
Future<User?> getById(String id) async {
final response = await _client
.from('users')
.select()
.eq('id', id)
.maybeSingle();
return response != null ? User.fromJson(response) : null;
}
Future<User> create(User data) async {
final response = await _client
.from('users')
.insert(data.toJson())
.select()
.single();
return User.fromJson(response);
}
Future<User> update(String id, User data) async {
final response = await _client
.from('users')
.update(data.toJson())
.eq('id', id)
.select()
.single();
return User.fromJson(response);
}
Future<void> delete(String id) async {
await _client.from('users').delete().eq('id', id);
}
Future<int> count() async {
final response = await _client
.from('users')
.select('*', const FetchOptions(count: CountOption.exact, head: true));
return response.count ?? 0;
}
Future<List<User>> paginate({int page = 1, int perPage = 20}) async {
final from = (page - 1) * perPage;
final to = from + perPage - 1;
final response = await _client
.from('users')
.select()
.range(from, to);
return response.map((e) => User.fromJson(e)).toList();
}
}
Using with supafreeze #
For the best experience, use suparepo together with supafreeze:
- Generate models with supafreeze
- Set
model_import_pathin suparepo.yaml to point to your models - Generate repositories with suparepo
This gives you fully type-safe repositories with Freezed models.
License #
MIT