From a34494d6f5cbc5ef220baf3fd5723075f92aa704 Mon Sep 17 00:00:00 2001 From: Tim Shedor Date: Mon, 7 Oct 2024 17:22:54 -0700 Subject: [PATCH] doc(supabase): improve legibility (#453) --- docs/data/fields.md | 54 +++++++++++++++---------------- docs/graphql/fields.md | 5 ++- docs/index.html | 20 +++++++++++- docs/offline_first/policies.md | 18 +++++------ docs/rest/fields.md | 11 +++---- docs/supabase/fields.md | 5 ++- docs/supabase/query.md | 2 +- packages/brick_rest/README.md | 19 ++++++----- packages/brick_supabase/README.md | 7 ++-- 9 files changed, 77 insertions(+), 64 deletions(-) diff --git a/docs/data/fields.md b/docs/data/fields.md index 302dd110..db52fd30 100644 --- a/docs/data/fields.md +++ b/docs/data/fields.md @@ -10,14 +10,14 @@ All `final` fields of a model, unless specified, will be (de)serialized by the p As providers are ultimately responsible for converting raw data into model data, a description of fields on models is overly generic. Field-level annotations always override class-level annotations/configuration. However, providers should adhere to some standards of annotations: -| Named Arg | Description | Example | -|---|---|---| -| `ignore:` | Do not deserialize (from) or serialize (to) this field to a provider | `@Rest(ignore: true)` | -| `name:` | Stored key for this field according to the provider. In SQLite, for example, this would be the column name. | `@Sqlite(name: "address_2")` | -| `defaultValue:` | Value to use in absence or `null` of the instance. It does not dictate what the Dart model will hold on empty instantiation. **Recommended to use Dart's default constructor assignment instead**. | `@Rest(defaultValue: '[]')` | -| `nullable:` | `null` fields are handled gracefully when serializing and deserializing. | `@Rest(nullable: true)` | +| Named Arg | Description | Example | +| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| `ignore:` | Do not deserialize (from) or serialize (to) this field to a provider | `@Rest(ignore: true)` | +| `name:` | Stored key for this field according to the provider. In SQLite, for example, this would be the column name. | `@Sqlite(name: "address_2")` | +| `defaultValue:` | Value to use in absence or `null` of the instance. It does not dictate what the Dart model will hold on empty instantiation. **Recommended to use Dart's default constructor assignment instead**. | `@Rest(defaultValue: '[]')` | +| `nullable:` | `null` fields are handled gracefully when serializing and deserializing. | `@Rest(nullable: true)` | | `fromGenerator` | A stringified function with access to [placeholders](#placeholders); replaces adapter's generated deserialize code for the field. Do not include trailing semicolons or function body wrapping symbols (`{}` or `=>`) in the definition. | `@Rest(fromGenerator: "int.tryParse(%DATA_PROPERTY%.toString())")` | -| `toGenerator` | A stringified function with access to [placeholders](#placeholders); replaces adapter's generated serialize code for the field. Do not include trailing semicolons or function body wrapping symbols (`{}` or `=>`) in the definition. | `@Sqlite(toGenerator: "%INSTANCE_PROPERTY% > 1 ? 1 : 0")` | +| `toGenerator` | A stringified function with access to [placeholders](#placeholders); replaces adapter's generated serialize code for the field. Do not include trailing semicolons or function body wrapping symbols (`{}` or `=>`) in the definition. | `@Sqlite(toGenerator: "%INSTANCE_PROPERTY% > 1 ? 1 : 0")` | ## Custom Generators @@ -48,7 +48,7 @@ final data = { To replace a few parts and DRY up code in custom, field-level generators, placeholders can be employed and replaced with values at build time. -All custom generators passed through field annotations (such as `@Rest(fromGenerator:)` or `@Sqlite(toGenerator:)`) have access to predefined placeholders and custom placeholders. +All custom generators passed through field annotations (such as `@Rest(fromGenerator:)` or `@Sqlite(toGenerator:)`) have access to predefined placeholders and custom placeholders. To declare your own variables, wrap the variable name like a tag using `@`: `@VARIABLE_NAME@value@/VARIABLE_NAME@`. Placeholders and their values **must** conform to the RegEx `[\w\d]+`. @@ -69,27 +69,27 @@ final customGenerator = """(%DATA_PROPERTY% as Map).map((key, v There are several globally-defined placeholders: -* `%ANNOTATED_NAME%` - key name. - ```dart - @Rest(name: 'my_field') - final String myField - // => 'my_field' - ``` -* `%DATA_PROPERTY%` - deserializing key name (`@Rest(name:)` or `@Sqlite(name:)` or the default) wrapped in the deserialized map. **Only use in `fromGenerator`**. - ```dart - @Rest(name: 'my_field') - final String myField - // => data['my_field'] - ``` -* `%INSTANCE_PROPERTY%` - serializing property. **Only use in `toGenerator`**. - ```dart - @Rest(name: 'my_field') - final String myField - // => instance.myField - ``` +- `%ANNOTATED_NAME%` - key name. + ```dart + @Rest(name: 'my_field') + final String myField + // => 'my_field' + ``` +- `%DATA_PROPERTY%` - deserializing key name (`@Rest(name:)` or `@Sqlite(name:)` or the default) wrapped in the deserialized map. **Only use in `fromGenerator`**. + ```dart + @Rest(name: 'my_field') + final String myField + // => data['my_field'] + ``` +- `%INSTANCE_PROPERTY%` - serializing property. **Only use in `toGenerator`**. + ```dart + @Rest(name: 'my_field') + final String myField + // => instance.myField + ``` ## FAQ -### Why are annotations AND extensions required? +### Why are annotations AND `extends` required? The annotation is required to build the generated files (adapters, migrations, etc.). The type extension (e.g. `OfflineFirstModel`) is used by the repository's type system. diff --git a/docs/graphql/fields.md b/docs/graphql/fields.md index 59c3ed19..1240b2f5 100644 --- a/docs/graphql/fields.md +++ b/docs/graphql/fields.md @@ -28,9 +28,8 @@ final List hats; GraphQL keys can be renamed per field. This will override the default set by `GraphqlSerializable#fieldRename`. ```dart -@Graphql( - name: "full_name" // "full_name" is used in ***fromGraphql*** and ***toGraphql*** requests instead of "last_name" -) +// "full_name" is used in ***fromGraphql*** and ***toGraphql*** requests instead of "last_name" +@Graphql(name: "full_name") final String lastName; ``` diff --git a/docs/index.html b/docs/index.html index d12afde2..8603e7d9 100644 --- a/docs/index.html +++ b/docs/index.html @@ -14,6 +14,10 @@ diff --git a/docs/offline_first/policies.md b/docs/offline_first/policies.md index cb729d65..2de63d27 100644 --- a/docs/offline_first/policies.md +++ b/docs/offline_first/policies.md @@ -1,16 +1,16 @@ # Offline First Policies -Repository methods can be invoked with policies to prioritize data sources. For example, a request may need to skip the offline queue or the response must come from a remote source. It is strongly encouraged to use a policy (e.g. `Repository().get(policy: .requireRemote))`) instead of directly accessing a provider (e.g. `Repository().restPovider.get()`) +Repository methods can be invoked with policies to prioritize data sources. For example, a request may need to skip the offline queue or the response must come from a remote source. It is strongly encouraged to use a policy (e.g. `Repository().get(policy: .requireRemote))`) instead of directly accessing a provider (e.g. `Repository().restPovider.get()`). ## OfflineFirstDeletePolicy -### `optimisticLocal` +### `optimisticLocal` (default) -Delete local results before waiting for the remote provider to respond +Delete local results before waiting for the remote provider to respond. ### `requireRemote` -Delete local results after remote responds; local results are not deleted if remote responds with any exception +Delete local results after remote responds; local results are not deleted if remote responds with any exception. ## OfflineFirstGetPolicy @@ -22,20 +22,20 @@ Ensures data is fetched from the remote provider(s) at each invocation. This hyd Ensures results must be updated from the remote proivder(s) before returning if the app is online. An empty array will be returned if the app is offline. -### `awaitRemoteWhenNoneExist` +### `awaitRemoteWhenNoneExist` (default) Retrieves from the remote provider(s) if the query returns no results from the local provider(s). ### `localOnly` -Do not request from the remote provider(s) +Do not request from the remote provider(s). ## OfflineFirstUpsertPolicy -### `optimisticLocal` +### `optimisticLocal` (default) -Save results to local before waiting for the remote provider to respond +Save results to local before waiting for the remote provider to respond. ### `requireRemote` -Save results to local after remote responds; local results are not saved if remote responds with any exception +Save results to local after remote responds; local results are not saved if remote responds with any exception. diff --git a/docs/rest/fields.md b/docs/rest/fields.md index 530a5cfc..0679f19f 100644 --- a/docs/rest/fields.md +++ b/docs/rest/fields.md @@ -9,7 +9,7 @@ Brick by default assumes enums from a REST API will be delivered as integers mat Given the API: ```json -{ "user": { "hats": [ "bowler", "birthday" ] } } +{ "user": { "hats": ["bowler", "birthday"] } } ``` Simply convert `hats` into a Dart enum: @@ -28,9 +28,8 @@ final List hats; REST keys can be renamed per field. This will override the default set by `RestSerializable#fieldRename`. ```dart -@Rest( - name: "full_name" // "full_name" is used in from and to requests to REST instead of "last_name" -) +// "full_name" is used in from and to requests to REST instead of "last_name" +@Rest(name: "full_name") final String lastName; ``` @@ -42,5 +41,5 @@ When true, the field will be ignored by the (de)serializing function in the adap 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 +- Nested `List<>` e.g. `>>` +- Many-to-many associations diff --git a/docs/supabase/fields.md b/docs/supabase/fields.md index 343028f6..f77d698d 100644 --- a/docs/supabase/fields.md +++ b/docs/supabase/fields.md @@ -23,9 +23,8 @@ Supabase.instance.client.from('users') Supabase 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 Supabase instead of "last_name" -) +// "full_name" is used in from and to requests to Supabase instead of "last_name" +@Supabase(name: "full_name") final String lastName; ``` diff --git a/docs/supabase/query.md b/docs/supabase/query.md index 7df9d582..98897796 100644 --- a/docs/supabase/query.md +++ b/docs/supabase/query.md @@ -9,7 +9,7 @@ | `'orderBy'` | `String` | Use field names not column names and always specify direction.For example, given a `final DateTime createdAt;` field: `{'orderBy': 'createdAt ASC'}`. | | `'orderByReferencedTable'` | `String?` | Forwards to Supabase's `referencedTable` [property](https://supabase.com/docs/reference/dart/order) | -?> The `ReferencedTable` params are awkward but necessary to not collide with other providers (like `SqliteProvider`) that also use `orderBy` and `limit`. While a `foreign_table.foreign_column` syntax is more Supabase-like, it is not supported in `orderBy` and `limit`. +?> The `ReferencedTable` naming convention is awkward but necessary to not collide with other providers (like `SqliteProvider`) that also use `orderBy` and `limit`. While a `foreign_table.foreign_column` syntax is more Supabase-like, it is not supported in `orderBy` and `limit`. ## `where:` diff --git a/packages/brick_rest/README.md b/packages/brick_rest/README.md index 4ed86b9b..68cfee0c 100644 --- a/packages/brick_rest/README.md +++ b/packages/brick_rest/README.md @@ -8,7 +8,7 @@ Connecting [Brick](https://github.com/GetDutchie/brick) with a RESTful API. ### `providerArgs:` -* `'request'` (`RestRequest`) Specifies configurable information about the request like HTTP method or top level key +- `'request'` (`RestRequest`) Specifies configurable information about the request like HTTP method or top level key ### `where:` @@ -113,9 +113,9 @@ class User extends OfflineFirstModel {} 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 `RestRequest` -1) The first discovered key. As a map is effectively an unordered list, relying on this fall through is not recommended. +1. A `topLevelKey` in `Query#providerArgs['request']` with a non-empty value +1. `topLevelKey` if defined in a `RestRequest` +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 RestRequestTransformer { @@ -153,7 +153,7 @@ Brick by default assumes enums from a REST API will be delivered as integers mat Given the API: ```json -{ "user": { "hats": [ "bowler", "birthday" ] } } +{ "user": { "hats": ["bowler", "birthday"] } } ``` Simply convert `hats` into a Dart enum: @@ -172,9 +172,8 @@ final List hats; REST keys can be renamed per field. This will override the default set by `RestSerializable#fieldRename`. ```dart -@Rest( - name: "full_name" // "full_name" is used in from and to requests to REST instead of "last_name" -) +// "full_name" is used in from and to requests to REST instead of "last_name" +@Rest(name: "full_name") final String lastName; ``` @@ -198,5 +197,5 @@ final restProvider = RestProvider(client: GZipHttpClient(level: 9)); 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 +- Nested `List<>` e.g. `>>` +- Many-to-many associations diff --git a/packages/brick_supabase/README.md b/packages/brick_supabase/README.md index c04e009b..b52f631a 100644 --- a/packages/brick_supabase/README.md +++ b/packages/brick_supabase/README.md @@ -15,7 +15,7 @@ Connecting [Brick](https://github.com/GetDutchie/brick) with Supabase. | `'orderBy'` | `String` | Use field names not column names and always specify direction.For example, given a `final DateTime createdAt;` field: `{'orderBy': 'createdAt ASC'}`. | | `'orderByReferencedTable'` | `String?` | Forwards to Supabase's `referencedTable` [property](https://supabase.com/docs/reference/dart/order) | -:bulb: The `ReferencedTable` params are awkward but necessary to not collide with other providers (like `SqliteProvider`) that also use `orderBy` and `limit`. While a `foreign_table.foreign_column` syntax is more Supabase-like, it is not supported in `orderBy` and `limit`. +:bulb: The `ReferencedTable` naming convention is awkward but necessary to not collide with other providers (like `SqliteProvider`) that also use `orderBy` and `limit`. While a `foreign_table.foreign_column` syntax is more Supabase-like, it is not supported in `orderBy` and `limit`. ### `where:` @@ -104,9 +104,8 @@ final List hats; Supabase 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 Supabase instead of "last_name" -) +// "full_name" is used in from and to requests to Supabase instead of "last_name" +@Supabase(name: "full_name") final String lastName; ```