Skip to content

Commit

Permalink
eng(supabase): add supabase and offline first with supabase packages
Browse files Browse the repository at this point in the history
  • Loading branch information
tshedor committed Aug 19, 2024
1 parent 5461db3 commit 234c5eb
Show file tree
Hide file tree
Showing 22 changed files with 603 additions and 0 deletions.
18 changes: 18 additions & 0 deletions .github/workflows/brick_offline_first_with_supabase.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Brick Offline First with Supabase
on:
push:
branches:
- main
pull_request:
paths:
- "packages/brick_offline_first_with_supabase/**"
- ".github/workflows/brick_offline_first_with_supabase.yaml"

env:
PUB_ENVIRONMENT: bot.github

jobs:
analyze_format_test:
uses: ./.github/workflows/reusable-flutter-analyze-format-test.yaml
with:
package: brick_offline_first_with_supabase
18 changes: 18 additions & 0 deletions .github/workflows/brick_supabase.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Brick Supabase
on:
push:
branches:
- main
pull_request:
paths:
- "packages/brick_supabase/**"
- ".github/workflows/brick_supabase.yaml"

env:
PUB_ENVIRONMENT: bot.github

jobs:
analyze_format_test:
uses: ./.github/workflows/reusable-dart-analyze-format-test.yaml
with:
package: brick_supabase
1 change: 1 addition & 0 deletions packages/brick_offline_first_with_supabase/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
!example/**/*.g.dart
5 changes: 5 additions & 0 deletions packages/brick_offline_first_with_supabase/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Unreleased

### 0.0.1

Initial
21 changes: 21 additions & 0 deletions packages/brick_offline_first_with_supabase/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) Green Bits, Inc. and its affiliates.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without supabaseriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
30 changes: 30 additions & 0 deletions packages/brick_offline_first_with_supabase/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
![brick_offline_first_with_supabase workflow](https://github.com/GetDutchie/brick/actions/workflows/brick_offline_first_with_supabase.yaml/badge.svg)

`OfflineFirstWithSupabaseRepository` streamlines the Supabase integration with an `OfflineFirstRepository`.

The `OfflineFirstWithSupabase` domain uses all the same configurations and annotations as `OfflineFirst`.

## Models

### ConnectOfflineFirstWithSupabase

`@ConnectOfflineFirstWithSupabase` decorates the model that can be serialized by one or more providers. Offline First does not have configuration at the class level and only extends configuration held by its providers:

```dart
@ConnectOfflineFirstWithSupabase(
supabaseConfig: SupabaseSerializable(),
sqliteConfig: SqliteSerializable(),
)
class MyModel extends OfflineFirstModel {}
```

### FAQ

#### Why can't I declare a model argument?

Due to [an open analyzer bug](https://github.com/dart-lang/sdk/issues/38309), a custom model cannot be passed to the repository as a type argument.

## Unsupported Field Types

- Any unsupported field types from `SupabaseProvider`, or `SqliteProvider`
- Future iterables of future models (i.e. `Future<List<Future<Model>>>`).
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include: ../../analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export 'package:brick_offline_first_with_supabase/src/offline_first_with_supabase_adapter.dart';
export 'package:brick_offline_first_with_supabase/src/offline_first_with_supabase_model.dart';
export 'package:brick_offline_first_with_supabase/src/offline_first_with_supabase_repository.dart';
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import 'package:brick_offline_first/brick_offline_first.dart';
import 'package:brick_offline_first_with_supabase/src/offline_first_with_supabase_model.dart';
import 'package:brick_supabase/brick_supabase.dart';

/// This adapter fetches first from [SqliteProvider] then hydrates with [SupabaseProvider].
abstract class OfflineFirstWithSupabaseAdapter<_Model extends OfflineFirstWithSupabaseModel>
extends OfflineFirstAdapter<_Model> with SupabaseAdapter<_Model> {
OfflineFirstWithSupabaseAdapter();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import 'package:brick_offline_first/brick_offline_first.dart';
import 'package:brick_supabase_abstract/brick_supabase_abstract.dart';

abstract class OfflineFirstWithSupabaseModel extends OfflineFirstModel with SupabaseModel {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import 'package:brick_offline_first/brick_offline_first.dart';
import 'package:brick_offline_first_with_supabase/src/offline_first_with_supabase_model.dart';
import 'package:brick_supabase/brick_supabase.dart' show SupabaseProvider;

/// Ensures the [remoteProvider] is a [SupabaseProvider].
///
/// OfflineFirstWithSupabaseRepository should accept a type argument such as
/// <_RepositoryModel extends OfflineFirstWithSupabaseModel>, however, this causes a type bound
/// error on runtime. The argument should be reintroduced with a future version of the
/// compiler/analyzer.
abstract class OfflineFirstWithSupabaseRepository
extends OfflineFirstRepository<OfflineFirstWithSupabaseModel> {
/// The type declaration is important here for the rare circumstances that
/// require interfacting with [SupabaseProvider]'s client directly.
@override
// ignore: overridden_fields
final SupabaseProvider remoteProvider;

OfflineFirstWithSupabaseRepository({
super.autoHydrate,
super.loggerName,
super.memoryCacheProvider,
required super.migrations,
required SupabaseProvider supabaseProvider,
required super.sqliteProvider,
}) : remoteProvider = supabaseProvider,
super(
remoteProvider: supabaseProvider,
);
}
27 changes: 27 additions & 0 deletions packages/brick_offline_first_with_supabase/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: brick_offline_first_with_supabase
description: A Brick domain that routes data fetching through local providers
before a Supabase provider.
homepage: https://github.com/GetDutchie/brick/tree/main/packages/brick_offline_first_with_supabase
issue_tracker: https://github.com/GetDutchie/brick/issues
repository: https://github.com/GetDutchie/brick

version: 0.0.1

environment:
sdk: ">=2.18.0 <4.0.0"

dependencies:
brick_core: ^1.1.1
brick_offline_first: ">=3.0.0 <4.0.0"
brick_supabase: ">=0.0.1 <2.0.0"
brick_supabase_abstract: ">=0.0.1 <2.0.0"
brick_sqlite: ">=3.0.0 <4.0.0"
logging: ">=1.0.0 <2.0.0"
meta: ">=1.3.0 <2.0.0"
sqflite_common: ">=2.0.0 <3.0.0"

dev_dependencies:
lints: ^2.0.1
mockito: ^5.0.0
test: ^1.16.5
sqflite_common_ffi: ^2.0.0
5 changes: 5 additions & 0 deletions packages/brick_supabase/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Unreleased

### 0.0.1

Initial
21 changes: 21 additions & 0 deletions packages/brick_supabase/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) Green Bits, Inc. and its affiliates.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without supabaseriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
90 changes: 90 additions & 0 deletions packages/brick_supabase/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
![brick_supabase workflow](https://github.com/GetDutchie/brick/actions/workflows/brick_supabase.yaml/badge.svg)

# Supabase Provider

Connecting [Brick](https://github.com/GetDutchie/brick) with Supabase.

## Models

### `@SupabaseSerializable(tableName:)`

The Supabase table name must be specified to connect `from`, `upsert` and `delete` invocations:

```dart
@SupabaseSerializable(tableName: 'users')
class User
```

## Fields

### `@Supabase(unique:)`

Connect Supabase's primary key (or any other index) to your application code. This is useful for `upsert` and `delete` logic when mutating instances.

```dart
@Supabase(unique: true, name: 'id')
final int supabaseId;
```

### `@Supabase(foreignKey:)`

Specify the foreign key to use on the table when fetching for a remote association.

For example, given the `orders` table has a `customer_id` column that associates
the `customers` table, an `Order` class in Dart may look like:

```dart
@SupabaseSerializeable(tableName: 'orders')
class Order {
@Supabase(foreignKey: 'customer_id')
final Customer customer;
}
@SupabaseSerializeable(tableName: 'customers')
class Customer {
final int id;
}
```

### `@Supabase(enumAsString:)`

Brick by default assumes enums from a REST API will be delivered as integers matching the index in the Flutter app. However, if your API delivers strings instead, the field can be easily annotated without writing a custom generator.

Given the API:

```json
{ "user": { "hats": ["bowler", "birthday"] } }
```

Simply convert `hats` into a Dart enum:

```dart
enum Hat { baseball, bowler, birthday }
...
@Supabase(enumAsString: true)
final List<Hat> hats;
```

### `@Supabase(name:)`

REST keys can be renamed per field. This will override the default set by `SupabaseSerializable#fieldRename`.

```dart
@Supabase(
name: "full_name" // "full_name" is used in from and to requests to REST instead of "last_name"
)
final String lastName;
```

### `@Supabase(ignoreFrom:)` and `@Supabase(ignoreTo:)`

When true, the field will be ignored by the (de)serializing function in the adapter.

## Unsupported Field Types

The following are not serialized to REST. However, unsupported types can still be accessed in the model as non-final fields.

- Nested `List<>` e.g. `<List<List<int>>>`
- Many-to-many associations
1 change: 1 addition & 0 deletions packages/brick_supabase/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include: ../../analysis_options.yaml
4 changes: 4 additions & 0 deletions packages/brick_supabase/lib/brick_supabase.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export 'package:brick_supabase/src/supabase_adapter.dart';
export 'package:brick_supabase/src/supabase_model_dictionary.dart';
export 'package:brick_supabase/src/supabase_provider.dart';
export 'package:brick_supabase_abstract/brick_supabase_abstract.dart';
Loading

0 comments on commit 234c5eb

Please sign in to comment.