Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/jakesmd/typesafe-supabase

A dart package that enables type-safe queries to a Supabase database.
https://github.com/jakesmd/typesafe-supabase

dart postgres supabase typesafety

Last synced: 3 months ago
JSON representation

A dart package that enables type-safe queries to a Supabase database.

Awesome Lists containing this project

README

        

# Type-safe supabase for dart
> 🚨 This is **NOT** an official *supabase* package and **NOT** developed by the *supabase* team!
- [x] ⚡️ Type-safe queries
- [x] ⚡️ Foolproof filters
- [x] ⚡️ Foolproof modifiers
- [x] ⚡️ Minimal setup
- [x] ⚡️ Minimal code generation

## 🎮 Basic Usage

> 🚧 **WIP!** This package is still under development. Use it with caution and [file any potential issues you see](https://github.com/JakesMD/typesafe-supabase/issues).

First, create your tables that replicate the ones in your Supabase project:
``` dart
// authors.dart

import 'package:typesafe_supabase/typesafe_supabase.dart';

part 'authors.g.dart';

/// Represents the `authors` table in the Supabase database.
@SupaTableHere()
class Authors extends SupaTable {
const Authors({required super.supabaseClient})
: super(AuthorsRecord.new, tableName: 'authors', primaryKey: const ['id']);

/// The unique identifier of the author.
@SupaColumnHere(hasDefault: true)
static const id = SupaColumn(name: 'id');

/// The author's name.
@SupaColumnHere()
static const name = SupaColumn(name: 'name');
}
```
``` dart
// books.dart

import 'package:typesafe_supabase/typesafe_supabase.dart';

part 'books.g.dart';

/// Represents the `books` table in the Supabase database.
@SupaTableHere()
class Books extends SupaTable {
const Books({required super.supabaseClient})
: super(BooksRecord.new, tableName: 'books', primaryKey: const ['id']);

/// The unique identifier of the book.
@SupaColumnHere(hasDefault: true)
static const id = SupaColumn(name: 'id');

/// The title of the book.
@SupaColumnHere()
static const title = SupaColumn(name: 'title');

/// The unique identifier of the author of the book.
@SupaColumnHere()
static const authorID = SupaColumn(name: 'author_id');

/// The number of pages in the book.
@SupaColumnHere()
static const pages = SupaColumn(name: 'pages');

/// References the `authors` table joined by the `author_id` column.
@SupaTableJoinHere('Authors', 'authors', SupaJoinType.oneToOne, isNullable: false)
static final author = SupaTableJoin(
tableName: 'authors',
joiningColumn: Books.authorID,
joinType: SupaJoinType.oneToOne,
record: AuthorsRecord.new,
);
}
```

Next, run the generator to generate a small piece of code:
```
dart run build_runner build
```

Now use it!
``` dart
// Create the books table.
final books = Books(supabaseClient: supabaseClient);

// Fetch a Paddington book.
final book = await books.fetch(
columns: {
Books.title,
Books.author({Authors.name}),
},
filter: books.textSearch(Books.title('Paddington')),
modifier: books.order(Books.title).limit(1).single(),
);

// Print the title of the book.
print(book.title);

// Print the author's name.
print(book.author.name);

// Insert a new Paddington book.
await books.insert(
records: [
BooksInsert(title: 'To be updated', authorID: BigInt.two, pages: 160),
],
modifier: books.none(),
);

// Update the title and author of the book with the ID 4.
await books.update(
values: {
Books.title('Paddington Here and Now'),
Books.authorID(BigInt.one),
},
filter: books.equal(Books.id(BigInt.from(4))),
modifier: books.none(),
);

// Delete all Paddington books that were not written by Michael Bond.
await books.delete(
filter: books
.textSearch(Books.title('Paddington'))
.notEqual(Books.authorID(BigInt.one)),
modifier: books.none(),
);
```

## 📋 TODO
- [ ] Query JSON data (`.select('address->city')`)
- [ ] Filter by JSON key (`.eq('address->postcode', 90210)`)
- [ ] Filter by joined table column (`.eq('countries.name', 'Indonesia')`)
- [ ] In-depth documentation