From f75c64589776f0592d605899820a546db2cd8bef Mon Sep 17 00:00:00 2001 From: Tim Shedor Date: Mon, 19 Aug 2024 00:11:58 -0700 Subject: [PATCH] remove abstract packages --- .../connect_offline_first_with_supabase.dart | 0 .../.gitignore | 1 - .../CHANGELOG.md | 5 - .../LICENSE | 21 -- .../README.md | 147 ------------- .../analysis_options.yaml | 1 - ..._offline_first_with_supabase_abstract.dart | 1 - .../pubspec.yaml | 19 -- .../brick_supabase/lib/brick_supabase.dart | 5 +- .../lib/src/annotations}/supabase.dart | 0 .../annotations}/supabase_serializable.dart | 0 .../lib/src/query_supabase_transformer.dart | 6 +- .../runtime_supabase_column_definition.dart | 0 .../lib/src/supabase_adapter.dart | 2 +- .../lib/src/supabase_model.dart | 0 .../lib/src/supabase_provider.dart | 16 +- packages/brick_supabase/pubspec.yaml | 4 +- packages/brick_supabase_abstract/CHANGELOG.md | 5 - packages/brick_supabase_abstract/LICENSE | 21 -- packages/brick_supabase_abstract/README.md | 202 ------------------ .../analysis_options.yaml | 1 - .../lib/brick_supabase_abstract.dart | 4 - packages/brick_supabase_abstract/pubspec.yaml | 17 -- 23 files changed, 19 insertions(+), 459 deletions(-) rename packages/{brick_offline_first_with_supabase_abstract/lib/src => brick_offline_first_with_supabase/lib/src/annotations}/connect_offline_first_with_supabase.dart (100%) delete mode 100644 packages/brick_offline_first_with_supabase_abstract/.gitignore delete mode 100644 packages/brick_offline_first_with_supabase_abstract/CHANGELOG.md delete mode 100644 packages/brick_offline_first_with_supabase_abstract/LICENSE delete mode 100644 packages/brick_offline_first_with_supabase_abstract/README.md delete mode 100644 packages/brick_offline_first_with_supabase_abstract/analysis_options.yaml delete mode 100644 packages/brick_offline_first_with_supabase_abstract/lib/brick_offline_first_with_supabase_abstract.dart delete mode 100644 packages/brick_offline_first_with_supabase_abstract/pubspec.yaml rename packages/{brick_supabase_abstract/lib/src => brick_supabase/lib/src/annotations}/supabase.dart (100%) rename packages/{brick_supabase_abstract/lib/src => brick_supabase/lib/src/annotations}/supabase_serializable.dart (100%) rename packages/{brick_supabase_abstract => brick_supabase}/lib/src/runtime_supabase_column_definition.dart (100%) rename packages/{brick_supabase_abstract => brick_supabase}/lib/src/supabase_model.dart (100%) delete mode 100644 packages/brick_supabase_abstract/CHANGELOG.md delete mode 100644 packages/brick_supabase_abstract/LICENSE delete mode 100644 packages/brick_supabase_abstract/README.md delete mode 100644 packages/brick_supabase_abstract/analysis_options.yaml delete mode 100644 packages/brick_supabase_abstract/lib/brick_supabase_abstract.dart delete mode 100644 packages/brick_supabase_abstract/pubspec.yaml diff --git a/packages/brick_offline_first_with_supabase_abstract/lib/src/connect_offline_first_with_supabase.dart b/packages/brick_offline_first_with_supabase/lib/src/annotations/connect_offline_first_with_supabase.dart similarity index 100% rename from packages/brick_offline_first_with_supabase_abstract/lib/src/connect_offline_first_with_supabase.dart rename to packages/brick_offline_first_with_supabase/lib/src/annotations/connect_offline_first_with_supabase.dart diff --git a/packages/brick_offline_first_with_supabase_abstract/.gitignore b/packages/brick_offline_first_with_supabase_abstract/.gitignore deleted file mode 100644 index 79dcd336..00000000 --- a/packages/brick_offline_first_with_supabase_abstract/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!example/**/*.g.dart diff --git a/packages/brick_offline_first_with_supabase_abstract/CHANGELOG.md b/packages/brick_offline_first_with_supabase_abstract/CHANGELOG.md deleted file mode 100644 index b5de7397..00000000 --- a/packages/brick_offline_first_with_supabase_abstract/CHANGELOG.md +++ /dev/null @@ -1,5 +0,0 @@ -## Unreleased - -### 0.0.1 - -Initial diff --git a/packages/brick_offline_first_with_supabase_abstract/LICENSE b/packages/brick_offline_first_with_supabase_abstract/LICENSE deleted file mode 100644 index f8548186..00000000 --- a/packages/brick_offline_first_with_supabase_abstract/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -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 restriction, 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. diff --git a/packages/brick_offline_first_with_supabase_abstract/README.md b/packages/brick_offline_first_with_supabase_abstract/README.md deleted file mode 100644 index 96e4711c..00000000 --- a/packages/brick_offline_first_with_supabase_abstract/README.md +++ /dev/null @@ -1,147 +0,0 @@ -![brick_offline_first_with_rest workflow](https://github.com/GetDutchie/brick/actions/workflows/brick_offline_first_with_rest.yaml/badge.svg) - -`OfflineFirstWithRestRepository` streamlines the REST integration with an `OfflineFirstRepository`. A serial queue is included to track REST requests in a separate SQLite database, only removing requests when a response is returned from the host (i.e. the device has lost internet connectivity). See `OfflineFirstWithRest#reattemptForStatusCodes`. - -The `OfflineFirstWithRest` domain uses all the same configurations and annotations as `OfflineFirst`. - -## Models - -### ConnectOfflineFirstWithRest - -`@ConnectOfflineFirstWithRest` 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 -@ConnectOfflineFirstWithRest( - restConfig: RestSerializable(), - sqliteConfig: SqliteSerializable(), -) -class MyModel extends OfflineFirstModel {} -``` - -## Generating Models from a REST Endpoint - -A utility class is provided to make model generation from a JSON API a snap. Given an endpoint, the converter will infer the type of a field and scaffold a class. For example, the following would be saved to the `lib` directory of your project and run `$ dart lib/converter_script.dart`: - -```dart -// lib/converter_script.dart -import 'package:brick_offline_first/rest_to_offline_first_converter.dart'; - -const BASE = "http://0.0.0.0:3000"; -const endpoint = "$BASE/users"; - -final converter = RestToOfflineFirstConverter(endpoint: endpoint); - -void main() { - converter.saveToFile(); -} - -// => dart lib/converter_script.dart -``` - -After the model is generated, double check for `List` and `null` types. While the converter is smart, it's not smarter than you. - -## Testing - -Responses can be stubbed to and from an `OfflineFirstWithRest` repository. For convenience, file data can be used to stub JSON responses from an API: - -```dart -// test/models/api/user.json -{ - "user": { "name" : "Thomas" } -} - -// test/models/user_test.dart -import 'package:brick_sqlite/testing.dart'; -import 'package:my_app/brick/repository.dart'; - -void main() { - group("MySqliteProvider", () { - late MyRepository repository; - setUpAll(() async { - repository = MyRepository( - restProvider: RestProvider( - client: StubOfflineFirstWithRest.fromFiles('http://0.0.0.0:3000', { - 'users': 'api/user.json' - }).client, - ) - ); - - await repository.initialize() - }); - }); -} -``` - -By default, the same response is returned for both `upsert` and `get` methods, with the only variation being in status code. However, responses can be configured for different methods: - -```dart -StubOfflineFirstWithRest( - baseEndpoint: 'http://0.0.0.0:3000', - responses: [ - StubOfflineFirstRestResponse.fromFile('users', 'api/user.json', StubHttpMethod.get), - StubOfflineFirstRestResponse.fromFile('users', 'api/user-post.json', StubHttpMethod.post), - ], -) -``` - -### Stubbing Without Files - -While storing the responses in a file can be convenient and reduce code clutter, responses can be defined inline: - -```dart -StubOfflineFirstWithRest( - baseEndpoint: 'http://0.0.0.0:3000', - responses: [ - StubOfflineFirstRestResponse('users', '{"name":"Bob"'), - StubOfflineFirstRestResponse('users', '{"name":"Alice"'), - ], -) -``` - -### Handling Endpoint Variations - -Variants in the endpoint must be explicitly declared. For example, `/user`, `/users`, `/users?by_first_name=Guy` are all different. When instantiating, specify any expected variants: - -```dart -StubOfflineFirstRestResponse( - endpoints: ["user", "users", "users?by_first_name=Guy"] -) -``` - -### Stubbing Multiple Models - -Rarely will only one model need to be stubbed. All classes in an app can be stubbed efficiently using `StubOfflineFirstWithRest`: - -```dart -setUpAll() async { - final config = { - User: ['user', 'users'], - // Even individual member endpoints must be declared for association fetching - // REST endpoints are manually configured, so the content may vary - Hat: ['hat/1', 'hat/2', 'hats'], - } - final responses = config.entries.map((modelConfig) { - return modelConfig.value.map((endpoint) { - return StubOfflineFirstRestResponse.fromFile( - 'api/${modelConfig.key.toString().toLowerCase()}.json', - endpoint: endpoint, - ); - }); - }).expand((e) => e); - final client = StubOfflineFirstWithRest( - baseEndpoint: 'http://0.0.0.0:3000', - responses: responses, - ).client; -} -``` - -### 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 `RestProvider`, or `SqliteProvider` -* Future iterables of future models (i.e. `Future>>`. diff --git a/packages/brick_offline_first_with_supabase_abstract/analysis_options.yaml b/packages/brick_offline_first_with_supabase_abstract/analysis_options.yaml deleted file mode 100644 index f04c6cf0..00000000 --- a/packages/brick_offline_first_with_supabase_abstract/analysis_options.yaml +++ /dev/null @@ -1 +0,0 @@ -include: ../../analysis_options.yaml diff --git a/packages/brick_offline_first_with_supabase_abstract/lib/brick_offline_first_with_supabase_abstract.dart b/packages/brick_offline_first_with_supabase_abstract/lib/brick_offline_first_with_supabase_abstract.dart deleted file mode 100644 index ac8637cd..00000000 --- a/packages/brick_offline_first_with_supabase_abstract/lib/brick_offline_first_with_supabase_abstract.dart +++ /dev/null @@ -1 +0,0 @@ -export 'package:brick_offline_first_with_supabase_abstract/src/connect_offline_first_with_supabase.dart'; diff --git a/packages/brick_offline_first_with_supabase_abstract/pubspec.yaml b/packages/brick_offline_first_with_supabase_abstract/pubspec.yaml deleted file mode 100644 index 6dca6be4..00000000 --- a/packages/brick_offline_first_with_supabase_abstract/pubspec.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: brick_offline_first_with_supabase_abstract -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_abstract -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_supabase_abstract: ">=0.0.1 <1.0.0" - brick_sqlite: ">=3.0.0 <4.0.0" - -dev_dependencies: - lints: ^2.0.1 - test: ^1.16.5 diff --git a/packages/brick_supabase/lib/brick_supabase.dart b/packages/brick_supabase/lib/brick_supabase.dart index 5747d516..b2becb5e 100644 --- a/packages/brick_supabase/lib/brick_supabase.dart +++ b/packages/brick_supabase/lib/brick_supabase.dart @@ -1,4 +1,7 @@ +export 'package:brick_supabase/src/annotations/supabase.dart'; +export 'package:brick_supabase/src/annotations/supabase_serializable.dart'; +export 'package:brick_supabase/src/runtime_supabase_column_definition.dart'; export 'package:brick_supabase/src/supabase_adapter.dart'; +export 'package:brick_supabase/src/supabase_model.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'; diff --git a/packages/brick_supabase_abstract/lib/src/supabase.dart b/packages/brick_supabase/lib/src/annotations/supabase.dart similarity index 100% rename from packages/brick_supabase_abstract/lib/src/supabase.dart rename to packages/brick_supabase/lib/src/annotations/supabase.dart diff --git a/packages/brick_supabase_abstract/lib/src/supabase_serializable.dart b/packages/brick_supabase/lib/src/annotations/supabase_serializable.dart similarity index 100% rename from packages/brick_supabase_abstract/lib/src/supabase_serializable.dart rename to packages/brick_supabase/lib/src/annotations/supabase_serializable.dart diff --git a/packages/brick_supabase/lib/src/query_supabase_transformer.dart b/packages/brick_supabase/lib/src/query_supabase_transformer.dart index d6475c27..bc4fe96d 100644 --- a/packages/brick_supabase/lib/src/query_supabase_transformer.dart +++ b/packages/brick_supabase/lib/src/query_supabase_transformer.dart @@ -2,7 +2,7 @@ import 'package:brick_core/core.dart'; import 'package:brick_supabase/src/supabase_adapter.dart'; import 'package:brick_supabase/src/supabase_model_dictionary.dart'; import 'package:brick_supabase_abstract/brick_supabase_abstract.dart' hide Supabase; -import 'package:supabase_flutter/supabase_flutter.dart'; +import 'package:supabase/supabase.dart'; /// Create a prepared SQLite statement for eventual execution. Only [statement] and [values] /// should be accessed. @@ -30,9 +30,7 @@ class QuerySupabaseTransformer<_Model extends SupabaseModel> { return _destructureAssociation(adapter.fieldsToSupabaseColumns.values).join(',\n '); } - PostgrestFilterBuilder>> select() { - final builder = Supabase.instance.client.from(adapter.tableName); - + PostgrestFilterBuilder>> select(SupabaseQueryBuilder builder) { return (query?.where ?? []).fold(builder.select(selectQuery), (acc, condition) { final whereStatement = _expandCondition(condition); for (final where in whereStatement) { diff --git a/packages/brick_supabase_abstract/lib/src/runtime_supabase_column_definition.dart b/packages/brick_supabase/lib/src/runtime_supabase_column_definition.dart similarity index 100% rename from packages/brick_supabase_abstract/lib/src/runtime_supabase_column_definition.dart rename to packages/brick_supabase/lib/src/runtime_supabase_column_definition.dart diff --git a/packages/brick_supabase/lib/src/supabase_adapter.dart b/packages/brick_supabase/lib/src/supabase_adapter.dart index c75dd7ab..b4c8bad0 100644 --- a/packages/brick_supabase/lib/src/supabase_adapter.dart +++ b/packages/brick_supabase/lib/src/supabase_adapter.dart @@ -3,7 +3,7 @@ import 'package:brick_supabase/src/supabase_provider.dart'; import 'package:brick_supabase_abstract/brick_supabase_abstract.dart'; /// Constructors that convert app models to and from Supabase -abstract class SupabaseAdapter implements Adapter { +abstract mixin class SupabaseAdapter implements Adapter { /// Used for upserts; forwards to Supabase's `defaultToNull` bool get defaultToNull; diff --git a/packages/brick_supabase_abstract/lib/src/supabase_model.dart b/packages/brick_supabase/lib/src/supabase_model.dart similarity index 100% rename from packages/brick_supabase_abstract/lib/src/supabase_model.dart rename to packages/brick_supabase/lib/src/supabase_model.dart diff --git a/packages/brick_supabase/lib/src/supabase_provider.dart b/packages/brick_supabase/lib/src/supabase_provider.dart index 5fe3fbae..9923191c 100644 --- a/packages/brick_supabase/lib/src/supabase_provider.dart +++ b/packages/brick_supabase/lib/src/supabase_provider.dart @@ -4,13 +4,15 @@ import 'package:brick_supabase/src/supabase_model_dictionary.dart'; import 'package:brick_supabase_abstract/brick_supabase_abstract.dart' hide Supabase; import 'package:logging/logging.dart'; import 'package:meta/meta.dart'; -import 'package:supabase_flutter/supabase_flutter.dart'; +import 'package:supabase/supabase.dart'; /// Retrieves from an HTTP endpoint class SupabaseProvider implements Provider { /// A fully-qualified URL final String baseEndpoint; + final SupabaseClient client; + /// The glue between app models and generated adapters. @override final SupabaseModelDictionary modelDictionary; @@ -20,6 +22,7 @@ class SupabaseProvider implements Provider { SupabaseProvider( this.baseEndpoint, { + required this.client, required this.modelDictionary, }) : logger = Logger('SupabaseProvider'); @@ -27,7 +30,7 @@ class SupabaseProvider implements Provider { @override Future delete(instance, {query, repository}) async { final adapter = modelDictionary.adapterFor[TModel]!; - final tableBuilder = Supabase.instance.client.from(adapter.tableName); + final tableBuilder = client.from(adapter.tableName); final output = await adapter.toSupabase(instance, provider: this, repository: repository); final queryTransformer = @@ -47,9 +50,10 @@ class SupabaseProvider implements Provider { @override Future exists({query, repository}) async { + final adapter = modelDictionary.adapterFor[TModel]!; final queryTransformer = QuerySupabaseTransformer(modelDictionary: modelDictionary, query: query); - final builder = queryTransformer.select(); + final builder = queryTransformer.select(client.from(adapter.tableName)); final resp = await builder.count(CountOption.exact); return resp.count > 0; @@ -60,7 +64,7 @@ class SupabaseProvider implements Provider { final adapter = modelDictionary.adapterFor[TModel]!; final queryTransformer = QuerySupabaseTransformer(modelDictionary: modelDictionary, query: query); - final builder = queryTransformer.select(); + final builder = queryTransformer.select(client.from(adapter.tableName)); final resp = await builder; @@ -73,13 +77,13 @@ class SupabaseProvider implements Provider { @override Future upsert(instance, {query, repository}) async { final adapter = modelDictionary.adapterFor[TModel]!; - final tableBuilder = Supabase.instance.client.from(adapter.tableName); final output = await adapter.toSupabase(instance, provider: this, repository: repository); final queryTransformer = QuerySupabaseTransformer(modelDictionary: modelDictionary, query: query); - final builder = adapter.uniqueFields.fold(tableBuilder.upsert(output), (acc, uniqueFieldName) { + final builder = adapter.uniqueFields.fold(client.from(adapter.tableName).upsert(output), + (acc, uniqueFieldName) { final columnName = adapter.fieldsToSupabaseColumns[uniqueFieldName]!.columnName; if (output.containsKey(columnName)) { return acc.eq(columnName, output[columnName]); diff --git a/packages/brick_supabase/pubspec.yaml b/packages/brick_supabase/pubspec.yaml index af88000a..77e15497 100644 --- a/packages/brick_supabase/pubspec.yaml +++ b/packages/brick_supabase/pubspec.yaml @@ -7,11 +7,11 @@ repository: https://github.com/GetDutchie/brick version: 0.0.1 environment: - sdk: ">=2.18.0 <4.0.0" + sdk: ">=3.0.0 <4.0.0" dependencies: brick_core: ^1.1.1 - supabase_flutter: ">=2.6.0 <3.0.0" + supabase: ">=2.3.0 <3.0.0" logging: ">=1.0.0 <2.0.0" meta: ">=1.3.0 <2.0.0" brick_supabase_abstract: ">=0.0.1 <2.0.0" diff --git a/packages/brick_supabase_abstract/CHANGELOG.md b/packages/brick_supabase_abstract/CHANGELOG.md deleted file mode 100644 index b5de7397..00000000 --- a/packages/brick_supabase_abstract/CHANGELOG.md +++ /dev/null @@ -1,5 +0,0 @@ -## Unreleased - -### 0.0.1 - -Initial diff --git a/packages/brick_supabase_abstract/LICENSE b/packages/brick_supabase_abstract/LICENSE deleted file mode 100644 index 3b662c6b..00000000 --- a/packages/brick_supabase_abstract/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -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. diff --git a/packages/brick_supabase_abstract/README.md b/packages/brick_supabase_abstract/README.md deleted file mode 100644 index 5e384beb..00000000 --- a/packages/brick_supabase_abstract/README.md +++ /dev/null @@ -1,202 +0,0 @@ -![brick_supabase workflow](https://github.com/GetDutchie/brick/actions/workflows/brick_supabase.yaml/badge.svg) - -# REST Provider - -Connecting [Brick](https://github.com/GetDutchie/brick) with a RESTful API. - -## Supported `Query` Configuration - -### `providerArgs:` - -- `'request'` (`SupabaseRequest`) Specifies configurable information about the request like HTTP method or top level key - -### `where:` - -`SupabaseProvider` does not support any `Query#where` arguments. These should be configured on a model-by-model base by the `SupabaseSerializable#endpoint` argument. - -## Models - -### `@SupabaseSerializable(requestTransformer:)` - -:bulb: `requestTransformer` was added in Brick 3. For upgrading to Brick v3 from v2, please see [the migration guide](https://github.com/GetDutchie/brick/blob/main/MIGRATING.md). - -Every REST API is built differently, and with a fair amount of technical debt. Brick provides flexibility for inconsistent endpoints within any system. Endpoints can also change based on the query. The model adapter will query `endpoint` for `upsert` or `get` or `delete`. - -Since Dart requires annotations to be constants, dynamic functions cannot be used. This is a headache. Instead, the a `const`antized [constructor tearoff](https://medium.com/dartlang/dart-2-15-7e7a598e508a) can be used. The transformers permit dynamically defining the request (method, top level key, url, etc.) at runtime based on query params or if a Dart instance is available (`upsert` and `delete` only) - -```dart -class UserRequestTransformer extends SupabaseRequestTransformer { - final get = const SupabaseRequest(url: '/users'); - const UserRequestTransformer(Query? query, SupabaseModel? instance) : super(query, instance); -} - -@ConnectOfflineFirstWithSupabase( - supabaseConfig: SupabaseSerializable( - requestTransformer: UserRequestTransformer.new; - ) -) -class User extends OfflineFirstModel {} -``` - -Different provider calls will use different transformer fields: - -```dart -class UserRequestTransformer extends SupabaseRequestTransformer { - final get = const SupabaseRequest(url: '/users'); - final delete = SupabaseRequest(url: '/users/${instance.id}'); - - const UserRequestTransformer(Query? query, Model? instance) : super(query, instance); -} - -@ConnectOfflineFirstWithSupabase( - supabaseConfig: SupabaseSerializable( - requestTransformer: UserRequestTransformer.new, - ) -) -class User extends OfflineFirstModel {} -``` - -:warning: If an `SupabaseRequestTransform`'s method field (`get`, `upsert`, `delete`) is `null` or it's `url` is `null`, the request is skipped by the provider. - -#### With Query#providerArgs - -```dart -class UserRequestTransformer extends SupabaseRequestTransformer { - SupabaseRequest? get get { - if (query?.providerArgs.isNotEmpty && query.providerArgs['limit'] != null) { - return SupabaseRequest(url: "/users?limit=${query.providerArgs['limit']}"); - } - const SupabaseRequest(url: '/users'); - } - - final delete = SupabaseRequest(url: '/users/${instance.id}'); - - const UserRequestTransformer(Query? query, SupabaseModel? instance) : super(query, instance); -} - -@ConnectOfflineFirstWithSupabase( - supabaseConfig: SupabaseSerializable( - requestTransformer: UserRequestTransformer.new, - ) -) -class User extends OfflineFirstModel {} -``` - -#### With Query#where - -```dart -class UserRequestTransformer extends SupabaseRequestTransformer { - SupabaseRequest? get get { - if (query?.where != null) { - final id = Where.firstByField('id', query.where)?.value; - if (id != null) return SupabaseRequest(url: "/users/$id"); - } - const SupabaseRequest(url: '/users'); - } - - final delete = SupabaseRequest(url: '/users/${instance.id}'); - - const UserRequestTransformer(Query? query, SupabaseModel? instance) : super(query, instance); -} - -@ConnectOfflineFirstWithSupabase( - supabaseConfig: SupabaseSerializable( - requestTransformer: UserRequestTransformer.new, - ) -) -class User extends OfflineFirstModel {} -``` - -:bulb: For ease of illustration, the code is provided as if the transformer and model logic live in the same file. It's strongly recommended to include the request transformer logic in its own, colocated file (such as `user.model.request.dart`). - -### `@SupabaseRequest(topLevelKey:)` - -Data will most often be nested beneath a top-level key in a JSON response. The key is determined by the following priority: - -1. A `topLevelKey` in `Query#providerArgs['request']` with a non-empty value -1. `topLevelKey` if defined in a `SupabaseRequest` -1. The first discovered key. As a map is effectively an unordered list, relying on this fall through is not recommended. - -```dart -class UserRequestTransformer extends SupabaseRequestTransformer { - final get = const SupabaseRequest(url: '/users', topLevelKey: 'users'); - final upsert = const SupabaseRequest(url: '/users', topLevelKey: 'user'); - const UserRequestTransformer(Query? query, SupabaseModel? instance) : super(query, instance); -} - -@ConnectOfflineFirstWithSupabase( - requestTransformer: UserRequestTransformer.new -) -class User extends OfflineFirstModel {} -``` - -:warning: If the response from REST **is not** a map, the full response is returned instead. - -### `@SupabaseSerializable(fieldRename:)` - -Brick reduces the need to map REST keys to model field names by assuming a standard naming convention. For example: - -```dart -SupabaseSerializable(fieldRename: FieldRename.snake_case) -// on from supabase (get) - "last_name" => final String lastName -// on to supabase (upsert) -final String lastName => "last_name" -``` - -## Fields - -### `@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 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. - -## GZipping Requests - -All requests to the API endpoint can be compressed with Dart's standard [GZip library](https://api.dart.dev/stable/2.10.4/dart-io/GZipCodec-class.html). All requests will (over)write the `Content-Encoding` header to `{'Content-Encoding': 'gzip'}`. - -```dart -import 'package:brick_supabase/gzip_http_client.dart'; - -final supabaseProvider = SupabaseProvider(client: GZipHttpClient(level: 9)); -``` - -:warning: Your API must be able to accept and decode GZipped requests. - -## 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. `>>` -- Many-to-many associations diff --git a/packages/brick_supabase_abstract/analysis_options.yaml b/packages/brick_supabase_abstract/analysis_options.yaml deleted file mode 100644 index f04c6cf0..00000000 --- a/packages/brick_supabase_abstract/analysis_options.yaml +++ /dev/null @@ -1 +0,0 @@ -include: ../../analysis_options.yaml diff --git a/packages/brick_supabase_abstract/lib/brick_supabase_abstract.dart b/packages/brick_supabase_abstract/lib/brick_supabase_abstract.dart deleted file mode 100644 index a29d8aa0..00000000 --- a/packages/brick_supabase_abstract/lib/brick_supabase_abstract.dart +++ /dev/null @@ -1,4 +0,0 @@ -export 'package:brick_supabase_abstract/src/runtime_supabase_column_definition.dart'; -export 'package:brick_supabase_abstract/src/supabase.dart'; -export 'package:brick_supabase_abstract/src/supabase_model.dart'; -export 'package:brick_supabase_abstract/src/supabase_serializable.dart'; diff --git a/packages/brick_supabase_abstract/pubspec.yaml b/packages/brick_supabase_abstract/pubspec.yaml deleted file mode 100644 index a3bcc432..00000000 --- a/packages/brick_supabase_abstract/pubspec.yaml +++ /dev/null @@ -1,17 +0,0 @@ -name: brick_supabase_abstract -description: Supabase annotations and model/adapter to remove the Flutter restriction on build packages -homepage: https://github.com/GetDutchie/brick/tree/main/packages/brick_supabase_abstract -issue_tracker: https://github.com/GetDutchie/brick/issues -repository: https://github.com/GetDutchie/brick - -version: 0.0.1 - -environment: - sdk: ">=3.0.0 <4.0.0" - -dependencies: - brick_core: ^1.1.1 - -dev_dependencies: - lints: ^2.0.1 - test: ^1.16.5