From 5e5cf5dd13284ca4904a742a0097e7c2d3dc0a7f Mon Sep 17 00:00:00 2001 From: Tim Shedor Date: Mon, 16 Dec 2024 12:40:02 -0800 Subject: [PATCH] eng: update remaining analysis options for all packages --- analysis_options.yaml | 197 ++++++++++- .../brick/db/20240920063917.migration.dart | 4 +- .../lib/brick/models/customer.model.dart | 2 + .../lib/brick/models/pizza.model.dart | 4 +- example_supabase/lib/brick/repository.dart | 6 +- example_supabase/lib/main.dart | 20 +- example_supabase/pubspec.yaml | 26 +- packages/brick_build/analysis_options.yaml | 325 ------------------ .../lib/src/adapter_generator.dart | 1 + .../lib/src/builders/aggregate_builder.dart | 12 + .../brick_build/lib/src/builders/base.dart | 4 + .../builders/model_dictionary_builder.dart | 4 + .../lib/src/model_dictionary_generator.dart | 3 + .../brick_build/lib/src/serdes_generator.dart | 2 +- .../lib/src/utils/string_helpers.dart | 5 +- .../lib/brick_build_test.dart | 2 + packages/brick_core/analysis_options.yaml | 325 ------------------ packages/brick_graphql/analysis_options.yaml | 325 ------------------ .../lib/graphql_model_serdes_generator.dart | 4 +- .../lib/src/graphql_deserialize.dart | 1 + .../lib/src/graphql_fields.dart | 11 +- .../lib/src/graphql_serdes_generator.dart | 2 + ...rializable_query_transformer_extended.dart | 9 + .../lib/src/graphql_serialize.dart | 4 +- .../brick_graphql_generators/pubspec.yaml | 4 +- .../test_annotation_subfields.dart | 2 +- ...est_constructor_member_field_mismatch.dart | 2 +- .../test_enum_as_string.dart | 2 +- .../test_from_json_to_json.dart | 2 +- .../test_ignore_from_to.dart | 2 +- .../test_runtime_association_definition.dart | 2 +- ...t_unserializable_field_with_generator.dart | 2 +- .../graphql_model_serdes_generator_test.dart | 2 +- .../analysis_options.yaml | 325 ------------------ .../annotations/offline_first_annotation.dart | 7 +- ...tructive_local_sync_from_remote_mixin.dart | 6 +- .../lib/src/models/offline_first_serdes.dart | 2 + .../lib/src/offline_first_adapter.dart | 6 +- .../lib/src/offline_first_exception.dart | 10 +- .../lib/src/offline_first_policy.dart | 2 + .../lib/src/offline_first_repository.dart | 29 +- .../offline_queue/offline_request_queue.dart | 6 +- .../offline_queue/request_sqlite_cache.dart | 20 +- .../request_sqlite_cache_manager.dart | 16 +- .../src/runtime_offline_first_definition.dart | 2 + packages/brick_offline_first/pubspec.yaml | 8 +- .../test/offline_first/helpers/__mocks__.dart | 11 +- .../offline_first/helpers/horse_adapter.dart | 18 +- .../offline_first/helpers/mounty_adapter.dart | 12 +- .../offline_first/helpers/test_domain.dart | 5 +- .../offline_first_repository_test.dart | 2 +- .../lib/src/offline_first_checker.dart | 2 + .../lib/src/offline_first_fields.dart | 5 +- .../lib/src/offline_first_generator.dart | 1 + .../src/offline_first_json_generators.dart | 25 +- ...line_first_model_dictionary_generator.dart | 1 + .../src/offline_first_sqlite_builders.dart | 7 +- .../src/offline_first_sqlite_generators.dart | 35 +- .../brick_offline_first_build/pubspec.yaml | 10 +- .../test/__helpers__.dart | 9 +- .../test_constructor_arguments.dart | 4 +- .../test_custom_offline_first_serdes.dart | 2 +- .../test_default_value.dart | 2 +- .../test_enum_factory_serialize.dart | 2 +- .../offline_first_generator/test_futures.dart | 2 +- .../test_ignore_field.dart | 2 +- .../test_no_final_no_const.dart | 6 +- .../test_nullable_field.dart | 4 +- ...first_apply_to_remote_deserialization.dart | 2 +- ...fline_first_serdes_with_type_argument.dart | 2 +- .../test_offline_first_where.dart | 2 +- .../test_one_to_many_association.dart | 2 +- .../test_one_to_one_association.dart | 2 +- .../test_only_static_members.dart | 6 +- .../test_primitive_fields.dart | 2 +- .../test_unique_offline_first_serdes.dart | 2 +- .../test_unrelated_association.dart | 2 +- .../test/offline_first_generator_test.dart | 4 +- ...first_model_dictionary_generator_test.dart | 4 +- .../test_with_association.dart | 2 +- .../test_with_associations.dart | 2 +- .../test_with_serdes.dart | 2 +- .../offline_first_schema_generator_test.dart | 2 +- .../lib/src/graphql_offline_queue_link.dart | 2 + .../src/graphql_offline_request_queue.dart | 2 + .../lib/src/graphql_request_sqlite_cache.dart | 3 +- .../graphql_request_sqlite_cache_manager.dart | 4 +- .../offline_first_with_graphql_model.dart | 2 + .../lib/src/offline_first_graphql_policy.dart | 9 + .../offline_first_with_graphql_adapter.dart | 5 +- ...offline_first_with_graphql_repository.dart | 9 +- .../pubspec.yaml | 8 +- .../test/__helpers__.dart | 2 +- .../graphql_offline_request_queue_test.dart | 6 +- ...hql_offline_sqlite_cache_manager_test.dart | 10 +- .../test/test_domain/__mocks__.dart | 4 +- .../test/test_domain/horse_adapter.dart | 26 +- .../test/test_domain/mounty_adapter.dart | 18 +- .../analysis_options.yaml | 325 ------------------ .../lib/rest_to_offline_first_converter.dart | 16 +- .../models/offline_first_with_rest_model.dart | 4 +- .../lib/src/offline_first_exception.dart | 26 -- .../src/offline_first_with_rest_adapter.dart | 8 +- .../offline_first_with_rest_exception.dart | 7 +- .../offline_first_with_rest_repository.dart | 23 +- .../rest_offline_queue_client.dart | 4 +- .../rest_offline_request_queue.dart | 2 + .../rest_request_sqlite_cache.dart | 3 + .../rest_request_sqlite_cache_manager.dart | 3 + .../lib/testing.dart | 12 +- .../pubspec.yaml | 8 +- .../test/helpers/__mocks__.dart | 8 +- .../test/helpers/horse_adapter.dart | 18 +- .../test/helpers/mounty.dart | 2 + .../test/helpers/mounty_adapter.dart | 12 +- .../rest_offline_queue_client_test.dart | 8 +- .../rest_offline_requeust_queue_test.dart | 6 +- ...est_request_sqlite_cache_manager_test.dart | 8 +- .../rest_to_offline_first_converter_test.dart | 18 +- .../lib/builder.dart | 23 +- .../src/offline_first_rest_generators.dart | 2 + .../offline_first_with_rest_generator.dart | 7 +- .../pubspec.yaml | 8 +- .../test_custom_serdes.dart | 2 +- .../test_rest_config_endpoint.dart | 2 +- .../test_rest_config_field_rename.dart | 4 +- .../test_specify_field_name.dart | 2 +- .../test/offline_first_generator_test.dart | 4 +- .../offline_first_with_supabase_adapter.dart | 4 +- .../offline_first_with_supabase_model.dart | 1 + ...ffline_first_with_supabase_repository.dart | 8 +- .../pubspec.yaml | 10 +- .../test/__mocks__.dart | 55 +-- ...e_first_with_supabase_repository_test.dart | 68 ++-- ...ick_offline_first_with_supabase_build.dart | 21 +- .../offline_first_supabase_generators.dart | 2 + ...offline_first_with_supabase_generator.dart | 7 +- .../pubspec.yaml | 12 +- .../test_default_to_null.dart | 2 +- .../test_field_name.dart | 2 +- .../test_field_rename.dart | 6 +- .../test_ignore_duplicates.dart | 2 +- .../test_offline_first_where.dart | 2 +- .../test_on_conflict.dart | 2 +- .../test_table_name_defined.dart | 2 +- .../test_table_name_undefined.dart | 4 +- .../test/offline_first_generator_test.dart | 4 +- packages/brick_rest/analysis_options.yaml | 325 ------------------ .../lib/src/rest_provider_query.dart | 8 + packages/brick_rest/lib/src/rest_request.dart | 16 + .../analysis_options.yaml | 325 ------------------ packages/brick_sqlite/analysis_options.yaml | 325 ------------------ .../lib/sqlite_model_serdes_generator.dart | 2 + .../src/builders/new_migration_builder.dart | 9 +- .../lib/src/builders/sqlite_base_builder.dart | 4 + .../src/builders/sqlite_schema_builder.dart | 5 +- .../lib/src/sqlite_deserialize.dart | 29 +- .../lib/src/sqlite_fields.dart | 9 +- .../sqlite_schema/migration_generator.dart | 5 +- .../sqlite_schema_generator.dart | 35 +- .../lib/src/sqlite_serdes_generator.dart | 7 +- .../lib/src/sqlite_serialize.dart | 14 +- packages/brick_sqlite_generators/pubspec.yaml | 4 +- .../test_from_identical_schema.dart | 1 - .../test_from_new_schema.dart | 3 +- .../test_after_save_with_association.dart | 2 +- .../test_all_field_types.dart | 2 +- .../test_boolean_fields.dart | 2 +- .../test_field_with_type_argument.dart | 2 +- .../test_sqlite_column_type.dart | 2 +- .../test_sqlite_enum_as_string.dart | 2 +- .../test_sqlite_unique.dart | 2 +- .../test_to_json_from_json.dart | 2 +- .../sqlite_model_serdes_generator_test.dart | 8 +- .../sqlite_schema/test_all_field_types.dart | 2 +- .../test/sqlite_schema/test_from_to_json.dart | 2 +- .../sqlite_schema/test_index_annotation.dart | 2 +- .../test/sqlite_schema/test_nullable.dart | 2 +- .../test_one_to_many_association.dart | 2 +- .../test_one_to_one_association.dart | 2 +- .../test/sqlite_schema/test_simple.dart | 4 +- .../test_sqlite_column_type.dart | 2 +- .../test/sqlite_schema_generator_test.dart | 2 +- packages/brick_supabase/analysis_options.yaml | 325 ------------------ .../lib/src/query_supabase_transformer.dart | 1 + .../test/__mocks_generated__.dart | 2 + .../lib/src/supabase_deserialize.dart | 3 +- .../lib/src/supabase_fields.dart | 6 +- .../lib/src/supabase_serdes_generator.dart | 2 + .../lib/src/supabase_serialize.dart | 1 + .../lib/supabase_model_serdes_generator.dart | 2 + .../brick_supabase_generators/pubspec.yaml | 4 +- ...est_constructor_member_field_mismatch.dart | 2 +- .../test_enum_as_string.dart | 2 +- .../test_ignore_from_to.dart | 2 +- ...st_runtime_supabase_column_definition.dart | 2 +- .../test_unique.dart | 2 +- ...t_unserializable_field_with_generator.dart | 2 +- 198 files changed, 961 insertions(+), 3428 deletions(-) delete mode 100644 packages/brick_offline_first_with_rest/lib/src/offline_first_exception.dart diff --git a/analysis_options.yaml b/analysis_options.yaml index 31d83698..1995b681 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,51 +1,234 @@ -include: package:lints/recommended.yaml - -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options +include: ../../analysis_options.yaml linter: rules: + # This list is derived from the list of all available lints located at + # https://github.com/dart-lang/linter/blob/master/example/all.yaml - always_declare_return_types + # - always_put_control_body_on_new_line + # - always_put_required_named_parameters_first + # - always_specify_types - always_use_package_imports + - annotate_overrides + # - avoid_annotating_with_dynamic - avoid_bool_literals_in_conditional_expressions + # - avoid_catches_without_on_clauses + # - avoid_catching_errors + - avoid_classes_with_only_static_members + - avoid_double_and_int_checks + # - avoid_dynamic_calls + - avoid_empty_else + # - avoid_equals_and_hash_code_on_mutable_classes - avoid_escaping_inner_quotes + - avoid_field_initializers_in_const_classes + # - avoid_final_parameters + - avoid_function_literals_in_foreach_calls + - avoid_implementing_value_types + - avoid_init_to_null + - avoid_js_rounded_ints + - avoid_multiple_declarations_per_line + - avoid_null_checks_in_equality_operators + # - avoid_positional_boolean_parameters + - avoid_print + - avoid_private_typedef_functions + - avoid_redundant_argument_values + - avoid_relative_lib_imports + - avoid_renaming_method_parameters + - avoid_return_types_on_setters + - avoid_returning_null_for_void + - avoid_returning_this + - avoid_setters_without_getters + - avoid_shadowing_type_parameters + - avoid_single_cascade_in_expression_statements + - avoid_slow_async_io + - avoid_type_to_string + - avoid_types_as_parameter_names + # - avoid_types_on_closure_parameters + - avoid_unnecessary_containers + - avoid_unused_constructor_parameters - avoid_void_async + - avoid_web_libraries_in_flutter + - await_only_futures - camel_case_extensions - camel_case_types + - cancel_subscriptions + - cascade_invocations + - cast_nullable_to_non_nullable + # - close_sinks + - collection_methods_unrelated_type + - combinators_ordering + - comment_references + - conditional_uri_does_not_exist + - constant_identifier_names + - control_flow_in_finally - curly_braces_in_flow_control_structures + - dangling_library_doc_comments + - depend_on_referenced_packages + - deprecated_consistency + - deprecated_member_use_from_same_package + # - diagnostic_describe_all_properties - directives_ordering - discarded_futures + - do_not_use_environment + - empty_catches + - empty_constructor_bodies + - empty_statements - eol_at_end_of_file + - exhaustive_cases - file_names + - flutter_style_todos + - hash_and_equals + - implementation_imports + - implicit_call_tearoffs + - implicit_reopen - invalid_case_patterns + - join_return_with_assignment + # - leading_newlines_in_multiline_strings + - library_annotations + - library_names + - library_prefixes + - library_private_types_in_public_api + # - lines_longer_than_80_chars + - literal_only_boolean_expressions - matching_super_parameters + - missing_whitespace_between_adjacent_strings + - no_adjacent_strings_in_list + - no_default_cases + - no_duplicate_case_values + - no_leading_underscores_for_library_prefixes + - no_leading_underscores_for_local_identifiers - no_literal_bool_comparisons + - no_logic_in_create_state + - no_runtimeType_toString + - no_self_assignments + - no_wildcard_variable_uses + - non_constant_identifier_names + - noop_primitive_operations + - null_check_on_nullable_type_parameter + - null_closures + - omit_local_variable_types + - one_member_abstracts + - only_throw_errors + - overridden_fields + - package_api_docs + - package_names + - package_prefixed_library_names + - parameter_assignments + - prefer_adjacent_string_concatenation + - prefer_asserts_in_initializer_lists + - prefer_asserts_with_message + - prefer_collection_literals + - prefer_conditional_assignment + - prefer_const_constructors + - prefer_const_constructors_in_immutables + - prefer_const_declarations + - prefer_const_literals_to_create_immutables + - prefer_constructors_over_static_methods + - prefer_contains + # - prefer_double_quotes + # - prefer_expression_function_bodies + - prefer_final_fields + - prefer_final_in_for_each - prefer_final_locals + # - prefer_final_parameters + - prefer_for_elements_to_map_fromIterable + - prefer_foreach + - prefer_function_declarations_over_variables + - prefer_generic_function_type_aliases + - prefer_if_elements_to_conditional_expressions + - prefer_if_null_operators + - prefer_initializing_formals + - prefer_inlined_adds + - prefer_int_literals + - prefer_interpolation_to_compose_strings - prefer_is_empty - prefer_is_not_empty + - prefer_is_not_operator + - prefer_iterable_whereType + - prefer_mixin + - prefer_null_aware_method_calls + - prefer_null_aware_operators + # - prefer_relative_imports - prefer_single_quotes + - prefer_spread_collections + - prefer_typing_uninitialized_variables + - prefer_void_to_null + - provide_deprecation_message + - public_member_api_docs + - recursive_getters - require_trailing_commas + - secure_pubspec_urls + - sized_box_for_whitespace + - sized_box_shrink_expand + - slash_for_doc_comments + - sort_child_properties_last + # - sort_constructors_first + - sort_pub_dependencies + - sort_unnamed_constructors_first + - test_types_in_equals + - throw_in_finally + - tighten_type_of_initializing_formals + - type_annotate_public_apis + - type_init_formals - type_literal_in_constant_pattern - unawaited_futures + # - unnecessary_await_in_return + - unnecessary_brace_in_string_interps + - unnecessary_breaks + - unnecessary_const + - unnecessary_constructor_name + # - unnecessary_final + - unnecessary_getters_setters - unnecessary_lambdas + - unnecessary_late + - unnecessary_library_directive + - unnecessary_new + - unnecessary_null_aware_assignments + - unnecessary_null_aware_operator_on_extension_on_nullable + - unnecessary_null_checks + - unnecessary_null_in_if_null_operators + - unnecessary_nullable_for_final_variable_declarations + - unnecessary_overrides - unnecessary_parenthesis - unnecessary_raw_strings - unnecessary_statements + - unnecessary_string_escapes + - unnecessary_string_interpolations + - unnecessary_this - unnecessary_to_list_in_spreads + # - unreachable_from_main + - unrelated_type_equality_checks + - unsafe_html + - use_build_context_synchronously + - use_colored_box + - use_decorated_box + - use_enums + - use_full_hex_values_for_flutter_colors + - use_function_type_syntax_for_parameters - use_if_null_to_convert_nulls_to_bools + - use_is_even_rather_than_modulo + - use_key_in_widget_constructors + - use_late_for_private_fields_and_variables + - use_named_constants - use_raw_strings + - use_rethrow_when_possible + - use_setters_to_change_properties + - use_string_buffers + - use_string_in_part_of_directives - use_super_parameters + - use_test_throws_matchers - use_to_and_as_if_applicable - - unnecessary_breaks + - valid_regexps + - void_checks analyzer: - exclude: + exclude: - example/ - "**/example/" - example_rest - example_graphql - "**/*.g.dart" - + errors: # override custom always_use_package_imports: error diff --git a/example_supabase/lib/brick/db/20240920063917.migration.dart b/example_supabase/lib/brick/db/20240920063917.migration.dart index 6e2aef80..a5493fb8 100644 --- a/example_supabase/lib/brick/db/20240920063917.migration.dart +++ b/example_supabase/lib/brick/db/20240920063917.migration.dart @@ -1,6 +1,8 @@ // GENERATED CODE EDIT WITH CAUTION // THIS FILE **WILL NOT** BE REGENERATED // This file should be version controlled and can be manually edited. +// ignore_for_file: public_member_api_docs, constant_identifier_names + part of 'schema.g.dart'; // While migrations are intelligently created, the difference between some commands, such as @@ -21,8 +23,6 @@ const List _migration_20240920063917_up = [ 'Pizza', 'Customer', foreignKeyColumn: 'customer_Customer_brick_id', - onDeleteCascade: false, - onDeleteSetDefault: false, ), ]; diff --git a/example_supabase/lib/brick/models/customer.model.dart b/example_supabase/lib/brick/models/customer.model.dart index 433d28bc..fd017717 100644 --- a/example_supabase/lib/brick/models/customer.model.dart +++ b/example_supabase/lib/brick/models/customer.model.dart @@ -1,3 +1,5 @@ +// ignore_for_file: public_member_api_docs + import 'package:brick_offline_first_with_supabase/brick_offline_first_with_supabase.dart'; import 'package:brick_sqlite/brick_sqlite.dart'; diff --git a/example_supabase/lib/brick/models/pizza.model.dart b/example_supabase/lib/brick/models/pizza.model.dart index 4bae5382..cd090e2c 100644 --- a/example_supabase/lib/brick/models/pizza.model.dart +++ b/example_supabase/lib/brick/models/pizza.model.dart @@ -1,10 +1,12 @@ +// ignore_for_file: public_member_api_docs + import 'package:brick_offline_first_with_supabase/brick_offline_first_with_supabase.dart'; import 'package:brick_sqlite/brick_sqlite.dart'; import 'package:brick_supabase/brick_supabase.dart'; import 'package:pizza_shoppe/brick/models/customer.model.dart'; @ConnectOfflineFirstWithSupabase( - supabaseConfig: SupabaseSerializable(), + supabaseConfig: SupabaseSerializable.defaults, ) class Pizza extends OfflineFirstWithSupabaseModel { /// Read more about `@Sqlite`: https://github.com/GetDutchie/brick/tree/main/packages/brick_sqlite#fields diff --git a/example_supabase/lib/brick/repository.dart b/example_supabase/lib/brick/repository.dart index d039db73..5d4b093c 100644 --- a/example_supabase/lib/brick/repository.dart +++ b/example_supabase/lib/brick/repository.dart @@ -1,3 +1,5 @@ +// ignore_for_file: public_member_api_docs + import 'package:brick_offline_first_with_supabase/brick_offline_first_with_supabase.dart'; import 'package:brick_sqlite/brick_sqlite.dart'; import 'package:brick_sqlite/memory_cache_provider.dart'; @@ -10,6 +12,8 @@ import 'package:supabase_flutter/supabase_flutter.dart'; class Repository extends OfflineFirstWithSupabaseRepository { static late Repository? _singleton; + factory Repository() => _singleton!; + Repository._({ required super.supabaseProvider, required super.sqliteProvider, @@ -18,8 +22,6 @@ class Repository extends OfflineFirstWithSupabaseRepository { super.memoryCacheProvider, }); - factory Repository() => _singleton!; - static Future initializeSupabaseAndConfigure({ required String supabaseUrl, required String supabaseAnonKey, diff --git a/example_supabase/lib/main.dart b/example_supabase/lib/main.dart index 5083a00a..02ef2c03 100644 --- a/example_supabase/lib/main.dart +++ b/example_supabase/lib/main.dart @@ -1,3 +1,5 @@ +// ignore_for_file: public_member_api_docs + import 'package:flutter/material.dart'; import 'package:pizza_shoppe/brick/models/pizza.model.dart'; import 'package:pizza_shoppe/brick/repository.dart'; @@ -11,21 +13,23 @@ Future main() async { supabaseAnonKey: supabaseAnonKey, ); await Repository().initialize(); - runApp(MyApp()); + runApp(const MyApp()); } class MyApp extends StatelessWidget { + const MyApp({super.key}); + @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, - textTheme: TextTheme( - bodyMedium: TextStyle(fontSize: 20.0), + textTheme: const TextTheme( + bodyMedium: TextStyle(fontSize: 20), ), ), - home: MyHomePage(title: 'Flutter Demo Home Page'), + home: const MyHomePage(title: 'Flutter Demo Home Page'), ); } } @@ -33,7 +37,7 @@ class MyApp extends StatelessWidget { class MyHomePage extends StatelessWidget { final String title; - MyHomePage({super.key, required this.title}); + const MyHomePage({super.key, required this.title}); @override Widget build(BuildContext context) { @@ -42,8 +46,9 @@ class MyHomePage extends StatelessWidget { title: Text(title), ), body: Container( - padding: const EdgeInsets.all(20.0), + padding: const EdgeInsets.all(20), child: FutureBuilder( + // ignore: discarded_futures future: Repository().get(), builder: (context, AsyncSnapshot> pizzaList) { final pizzas = pizzaList.data; @@ -63,12 +68,11 @@ class MyHomePage extends StatelessWidget { class PizzaTile extends StatelessWidget { final Pizza pizza; - PizzaTile(this.pizza); + const PizzaTile(this.pizza, {super.key}); @override Widget build(BuildContext context) { return Column( - mainAxisAlignment: MainAxisAlignment.start, children: [ Text('id: ${pizza.id}'), Text('frozen: ${pizza.frozen}'), diff --git a/example_supabase/pubspec.yaml b/example_supabase/pubspec.yaml index d6bf9775..1af16380 100644 --- a/example_supabase/pubspec.yaml +++ b/example_supabase/pubspec.yaml @@ -10,32 +10,32 @@ environment: flutter: ">=3.0.0" dependencies: + brick_offline_first_with_supabase: cupertino_icons: ^1.0.2 flutter: sdk: flutter - brick_offline_first_with_supabase: sqflite: supabase_flutter: dependency_overrides: - brick_offline_first_with_supabase: - path: ../packages/brick_offline_first_with_supabase - brick_supabase: - path: ../packages/brick_supabase - brick_sqlite_generators: - path: ../packages/brick_sqlite_generators - brick_offline_first_with_supabase_build: - path: ../packages/brick_offline_first_with_supabase_build brick_build: path: ../packages/brick_build - brick_supabase_generators: - path: ../packages/brick_supabase_generators + brick_json_generators: + path: ../packages/brick_json_generators brick_offline_first_build: path: ../packages/brick_offline_first_build brick_offline_first_with_rest: path: ../packages/brick_offline_first_with_rest - brick_json_generators: - path: ../packages/brick_json_generators + brick_offline_first_with_supabase: + path: ../packages/brick_offline_first_with_supabase + brick_offline_first_with_supabase_build: + path: ../packages/brick_offline_first_with_supabase_build + brick_sqlite_generators: + path: ../packages/brick_sqlite_generators + brick_supabase: + path: ../packages/brick_supabase + brick_supabase_generators: + path: ../packages/brick_supabase_generators dev_dependencies: brick_offline_first_with_supabase_build: diff --git a/packages/brick_build/analysis_options.yaml b/packages/brick_build/analysis_options.yaml index 5008bf6c..f04c6cf0 100644 --- a/packages/brick_build/analysis_options.yaml +++ b/packages/brick_build/analysis_options.yaml @@ -1,326 +1 @@ include: ../../analysis_options.yaml - -linter: - rules: - # This list is derived from the list of all available lints located at - # https://github.com/dart-lang/linter/blob/master/example/all.yaml - - always_declare_return_types - # - always_put_control_body_on_new_line - # - always_put_required_named_parameters_first - # - always_specify_types - - always_use_package_imports - - annotate_overrides - # - avoid_annotating_with_dynamic - - avoid_bool_literals_in_conditional_expressions - # - avoid_catches_without_on_clauses - # - avoid_catching_errors - - avoid_classes_with_only_static_members - - avoid_double_and_int_checks - # - avoid_dynamic_calls - - avoid_empty_else - # - avoid_equals_and_hash_code_on_mutable_classes - - avoid_escaping_inner_quotes - - avoid_field_initializers_in_const_classes - # - avoid_final_parameters - - avoid_function_literals_in_foreach_calls - - avoid_implementing_value_types - - avoid_init_to_null - - avoid_js_rounded_ints - - avoid_multiple_declarations_per_line - - avoid_null_checks_in_equality_operators - # - avoid_positional_boolean_parameters - - avoid_print - - avoid_private_typedef_functions - - avoid_redundant_argument_values - - avoid_relative_lib_imports - - avoid_renaming_method_parameters - - avoid_return_types_on_setters - - avoid_returning_null_for_void - - avoid_returning_this - - avoid_setters_without_getters - - avoid_shadowing_type_parameters - - avoid_single_cascade_in_expression_statements - - avoid_slow_async_io - - avoid_type_to_string - - avoid_types_as_parameter_names - # - avoid_types_on_closure_parameters - - avoid_unnecessary_containers - - avoid_unused_constructor_parameters - - avoid_void_async - - avoid_web_libraries_in_flutter - - await_only_futures - - camel_case_extensions - - camel_case_types - - cancel_subscriptions - - cascade_invocations - - cast_nullable_to_non_nullable - # - close_sinks - - collection_methods_unrelated_type - - combinators_ordering - - comment_references - - conditional_uri_does_not_exist - - constant_identifier_names - - control_flow_in_finally - - curly_braces_in_flow_control_structures - - dangling_library_doc_comments - - depend_on_referenced_packages - - deprecated_consistency - - deprecated_member_use_from_same_package - # - diagnostic_describe_all_properties - - directives_ordering - - discarded_futures - - do_not_use_environment - - empty_catches - - empty_constructor_bodies - - empty_statements - - eol_at_end_of_file - - exhaustive_cases - - file_names - - flutter_style_todos - - hash_and_equals - - implementation_imports - - implicit_call_tearoffs - - implicit_reopen - - invalid_case_patterns - - join_return_with_assignment - # - leading_newlines_in_multiline_strings - - library_annotations - - library_names - - library_prefixes - - library_private_types_in_public_api - # - lines_longer_than_80_chars - - literal_only_boolean_expressions - - matching_super_parameters - - missing_whitespace_between_adjacent_strings - - no_adjacent_strings_in_list - - no_default_cases - - no_duplicate_case_values - - no_leading_underscores_for_library_prefixes - - no_leading_underscores_for_local_identifiers - - no_literal_bool_comparisons - - no_logic_in_create_state - - no_runtimeType_toString - - no_self_assignments - - no_wildcard_variable_uses - - non_constant_identifier_names - - noop_primitive_operations - - null_check_on_nullable_type_parameter - - null_closures - - omit_local_variable_types - - one_member_abstracts - - only_throw_errors - - overridden_fields - - package_api_docs - - package_names - - package_prefixed_library_names - - parameter_assignments - - prefer_adjacent_string_concatenation - - prefer_asserts_in_initializer_lists - - prefer_asserts_with_message - - prefer_collection_literals - - prefer_conditional_assignment - - prefer_const_constructors - - prefer_const_constructors_in_immutables - - prefer_const_declarations - - prefer_const_literals_to_create_immutables - - prefer_constructors_over_static_methods - - prefer_contains - # - prefer_double_quotes - - prefer_expression_function_bodies - - prefer_final_fields - - prefer_final_in_for_each - - prefer_final_locals - # - prefer_final_parameters - - prefer_for_elements_to_map_fromIterable - - prefer_foreach - - prefer_function_declarations_over_variables - - prefer_generic_function_type_aliases - - prefer_if_elements_to_conditional_expressions - - prefer_if_null_operators - - prefer_initializing_formals - - prefer_inlined_adds - - prefer_int_literals - - prefer_interpolation_to_compose_strings - - prefer_is_empty - - prefer_is_not_empty - - prefer_is_not_operator - - prefer_iterable_whereType - - prefer_mixin - - prefer_null_aware_method_calls - - prefer_null_aware_operators - # - prefer_relative_imports - - prefer_single_quotes - - prefer_spread_collections - - prefer_typing_uninitialized_variables - - prefer_void_to_null - - provide_deprecation_message - - public_member_api_docs - - recursive_getters - - require_trailing_commas - - secure_pubspec_urls - - sized_box_for_whitespace - - sized_box_shrink_expand - - slash_for_doc_comments - - sort_child_properties_last - # - sort_constructors_first - - sort_pub_dependencies - - sort_unnamed_constructors_first - - test_types_in_equals - - throw_in_finally - - tighten_type_of_initializing_formals - - type_annotate_public_apis - - type_init_formals - - type_literal_in_constant_pattern - - unawaited_futures - # - unnecessary_await_in_return - - unnecessary_brace_in_string_interps - - unnecessary_breaks - - unnecessary_const - - unnecessary_constructor_name - # - unnecessary_final - - unnecessary_getters_setters - - unnecessary_lambdas - - unnecessary_late - - unnecessary_library_directive - - unnecessary_new - - unnecessary_null_aware_assignments - - unnecessary_null_aware_operator_on_extension_on_nullable - - unnecessary_null_checks - - unnecessary_null_in_if_null_operators - - unnecessary_nullable_for_final_variable_declarations - - unnecessary_overrides - - unnecessary_parenthesis - - unnecessary_raw_strings - - unnecessary_statements - - unnecessary_string_escapes - - unnecessary_string_interpolations - - unnecessary_this - - unnecessary_to_list_in_spreads - # - unreachable_from_main - - unrelated_type_equality_checks - - unsafe_html - - use_build_context_synchronously - - use_colored_box - - use_decorated_box - - use_enums - - use_full_hex_values_for_flutter_colors - - use_function_type_syntax_for_parameters - - use_if_null_to_convert_nulls_to_bools - - use_is_even_rather_than_modulo - - use_key_in_widget_constructors - - use_late_for_private_fields_and_variables - - use_named_constants - - use_raw_strings - - use_rethrow_when_possible - - use_setters_to_change_properties - - use_string_buffers - - use_string_in_part_of_directives - - use_super_parameters - - use_test_throws_matchers - - use_to_and_as_if_applicable - - valid_regexps - - void_checks - -analyzer: - exclude: - - example/ - - "**/example/" - - example_rest - - example_graphql - - "**/*.g.dart" - - errors: - # override custom - always_use_package_imports: error - camel_case_extensions: error - camel_case_types: error - curly_braces_in_flow_control_structures: error - directives_ordering: error - file_names: error - prefer_single_quotes: error - prefer_is_empty: error - prefer_is_not_empty: error - require_trailing_commas: error - sort_pub_dependencies: error - unnecessary_statements: error - - # override flutter_lints - avoid_print: error - avoid_unnecessary_containers: error - avoid_web_libraries_in_flutter: error - no_logic_in_create_state: error - prefer_const_constructors: error - prefer_const_constructors_in_immutables: error - prefer_const_declarations: error - prefer_const_literals_to_create_immutables: error - sized_box_for_whitespace: error - sort_child_properties_last: error - use_build_context_synchronously: error - use_full_hex_values_for_flutter_colors: error - use_key_in_widget_constructors: error - - # override recommended lints - always_require_non_null_named_parameters: error - annotate_overrides: error - avoid_function_literals_in_foreach_calls: error - avoid_init_to_null: error - avoid_null_checks_in_equality_operators: error - avoid_renaming_method_parameters: error - avoid_return_types_on_setters: error - avoid_returning_null_for_void: error - avoid_single_cascade_in_expression_statements: error - await_only_futures: error - constant_identifier_names: error - control_flow_in_finally: error - depend_on_referenced_packages: ignore - empty_constructor_bodies: error - empty_statements: error - exhaustive_cases: error - implementation_imports: ignore - invalid_case_patterns: error - library_names: error - library_prefixes: error - library_private_types_in_public_api: error - matching_super_parameters: error - no_leading_underscores_for_library_prefixes: error - no_leading_underscores_for_local_identifiers: error - no_literal_bool_comparisons: error - null_check_on_nullable_type_parameter: error - null_closures: error - overridden_fields: error - package_names: error - prefer_adjacent_string_concatenation: error - prefer_collection_literals: error - prefer_conditional_assignment: error - prefer_contains: error - prefer_equal_for_default_values: error - prefer_final_fields: error - prefer_for_elements_to_map_fromIterable: error - prefer_function_declarations_over_variables: error - prefer_if_null_operators: error - prefer_initializing_formals: error - prefer_inlined_adds: error - prefer_interpolation_to_compose_strings: error - prefer_is_not_operator: error - prefer_null_aware_operators: error - prefer_spread_collections: error - prefer_void_to_null: error - recursive_getters: error - slash_for_doc_comments: error - type_init_formals: error - type_literal_in_constant_pattern: error - unnecessary_brace_in_string_interps: error - unnecessary_breaks: error - unnecessary_const: error - unnecessary_constructor_name: error - unnecessary_getters_setters: error - unnecessary_late: error - unnecessary_new: error - unnecessary_null_aware_assignments: error - unnecessary_null_in_if_null_operators: error - unnecessary_nullable_for_final_variable_declarations: error - unnecessary_string_escapes: error - unnecessary_string_interpolations: error - unnecessary_this: error - use_function_type_syntax_for_parameters: error - use_rethrow_when_possible: error diff --git a/packages/brick_build/lib/src/adapter_generator.dart b/packages/brick_build/lib/src/adapter_generator.dart index eb14469f..49935311 100644 --- a/packages/brick_build/lib/src/adapter_generator.dart +++ b/packages/brick_build/lib/src/adapter_generator.dart @@ -51,6 +51,7 @@ class AdapterGenerator { return acc; }).join('\n'); + /// Given a model, outputs generated code to use as a Brick adapter. const AdapterGenerator({ required this.superAdapterName, required this.className, diff --git a/packages/brick_build/lib/src/builders/aggregate_builder.dart b/packages/brick_build/lib/src/builders/aggregate_builder.dart index ff770982..c8a8eb64 100644 --- a/packages/brick_build/lib/src/builders/aggregate_builder.dart +++ b/packages/brick_build/lib/src/builders/aggregate_builder.dart @@ -37,6 +37,18 @@ class AggregateBuilder implements Builder { /// static const outputFileName = 'models_and_migrations${BaseBuilder.aggregateExtension}.dart'; + /// Combine all `@ConnectOfflineFirstWithRest` and `@Migratable` classes and annotations + /// + /// Since [LibraryElement] only reads from one file and not an entire directory, all relevant + /// classes and annotation are inserted into copies of all input files. If there is ever a + /// performance concern with build times, start here. Only one file is needed, but it is impossible + /// to access [LibraryReader]s outside the build step of the created asset, and this was the only + /// successful way amongst dozens. + /// This does **not** output a file used by Brick in the app implementation. + /// + /// See the + /// [`build` docs](https://github.com/dart-lang/build/blob/master/docs/writing_an_aggregate_builder.md#defining-your-builder) + /// example for more. const AggregateBuilder({this.requiredImports = const []}); @override diff --git a/packages/brick_build/lib/src/builders/base.dart b/packages/brick_build/lib/src/builders/base.dart index d21c3da9..0798bcde 100644 --- a/packages/brick_build/lib/src/builders/base.dart +++ b/packages/brick_build/lib/src/builders/base.dart @@ -7,9 +7,11 @@ import 'package:source_gen/source_gen.dart'; export 'package:brick_build/src/annotation_super_generator.dart'; +/// final brickLogger = Logger('Brick'); abstract class BaseBuilder<_ClassAnnotation> implements Builder { + /// Logger get logger => brickLogger; @override @@ -20,8 +22,10 @@ abstract class BaseBuilder<_ClassAnnotation> implements Builder { /// The cached file this will produce String get outputExtension; + /// final typeChecker = TypeChecker.fromRuntime(_ClassAnnotation); + /// static const aggregateExtension = '.brick_aggregate'; /// Classes with the class-level annotation. For example, `ConnectOfflineFirstWithRest`. diff --git a/packages/brick_build/lib/src/builders/model_dictionary_builder.dart b/packages/brick_build/lib/src/builders/model_dictionary_builder.dart index 4572ddb7..532a74b1 100644 --- a/packages/brick_build/lib/src/builders/model_dictionary_builder.dart +++ b/packages/brick_build/lib/src/builders/model_dictionary_builder.dart @@ -15,13 +15,16 @@ class ModelDictionaryBuilder<_ClassAnnotation> extends BaseBuilder<_ClassAnnotat /// Include both single and double strings around package imports for safety. Regex is not supported. final List expectedImportRemovals; + /// final ModelDictionaryGenerator modelDictionaryGenerator; @override final outputExtension = '.model_dictionary_builder.dart'; + /// static final modelFiles = Glob('lib/**/*.model.dart'); + /// Writes [ModelDictionary] code to connect model and adapters. Outputs to brick/brick.g.dart ModelDictionaryBuilder( this.modelDictionaryGenerator, { this.expectedImportRemovals = const [], @@ -53,6 +56,7 @@ class ModelDictionaryBuilder<_ClassAnnotation> extends BaseBuilder<_ClassAnnotat logStopwatch('Generated brick.g.dart', stopwatch); } + /// static Map classFilePathsFromAnnotations( Iterable annotations, Map filesToContents, diff --git a/packages/brick_build/lib/src/model_dictionary_generator.dart b/packages/brick_build/lib/src/model_dictionary_generator.dart index cf6dda0d..810de4ab 100644 --- a/packages/brick_build/lib/src/model_dictionary_generator.dart +++ b/packages/brick_build/lib/src/model_dictionary_generator.dart @@ -8,9 +8,11 @@ abstract class ModelDictionaryGenerator { /// Consider adding analyzer ignores to disable 'unused_import' warnings. final requiredImports = ''; + /// // ignore: constant_identifier_names static const HEADER = '// GENERATED CODE DO NOT EDIT'; + /// Given a list of models, output generated code to use as `brick.g.dart` file const ModelDictionaryGenerator(); /// Adapter part imports @@ -18,6 +20,7 @@ abstract class ModelDictionaryGenerator { .map((k) => "part 'adapters/${StringHelpers.snakeCase(k)}_adapter.g.dart';") .join('\n'); + /// String dictionaryFromFiles(Map classNamesToFileNames) => classNamesToFileNames.keys.map((k) => '$k: ${k}Adapter()').join(',\n '); diff --git a/packages/brick_build/lib/src/serdes_generator.dart b/packages/brick_build/lib/src/serdes_generator.dart index 328a4f27..d71a85d8 100644 --- a/packages/brick_build/lib/src/serdes_generator.dart +++ b/packages/brick_build/lib/src/serdes_generator.dart @@ -364,7 +364,7 @@ abstract class SerdesGenerator fieldAnnotation.defaultValue != null ? ' ?? ${fieldAnnotation.defaultValue}' : ''; diff --git a/packages/brick_build/lib/src/utils/string_helpers.dart b/packages/brick_build/lib/src/utils/string_helpers.dart index b5a08ecf..b7b148d1 100644 --- a/packages/brick_build/lib/src/utils/string_helpers.dart +++ b/packages/brick_build/lib/src/utils/string_helpers.dart @@ -1,4 +1,7 @@ +// ignore: avoid_classes_with_only_static_members +/// class StringHelpers { + /// See [_EscapedDartString]. static String escape(String contents) => _EscapedDartString(contents).toString(); /// Convert a camelized string to snake_case @@ -17,7 +20,7 @@ class StringHelpers { // Borrowed from [JsonSerializable](https://github.com/dart-lang/json_serializable/blob/9fcee71528f17f8e9e80e90003264e84d048977b/json_serializable/lib/src/utils.dart) -/// Returns a quoted String literal for [value] that can be used in generated +/// Returns a quoted String literal for [contents] that can be used in generated /// Dart code. class _EscapedDartString { final String contents; diff --git a/packages/brick_build_test/lib/brick_build_test.dart b/packages/brick_build_test/lib/brick_build_test.dart index 42bef80e..2e84cd56 100644 --- a/packages/brick_build_test/lib/brick_build_test.dart +++ b/packages/brick_build_test/lib/brick_build_test.dart @@ -11,6 +11,7 @@ Future _libraryForFolder(String folder, String filename) async { ); } +/// typedef LibraryGenerator = Future Function(String filename); /// Thunks a reader generator that assumes the filename is prefixed `test_` @@ -31,6 +32,7 @@ Future annotationForFile<_Annotation>(String folder, String fi } // ignore: subtype_of_sealed_class +/// class MockBuildStep extends BuildStep { @override dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); diff --git a/packages/brick_core/analysis_options.yaml b/packages/brick_core/analysis_options.yaml index 5008bf6c..f04c6cf0 100644 --- a/packages/brick_core/analysis_options.yaml +++ b/packages/brick_core/analysis_options.yaml @@ -1,326 +1 @@ include: ../../analysis_options.yaml - -linter: - rules: - # This list is derived from the list of all available lints located at - # https://github.com/dart-lang/linter/blob/master/example/all.yaml - - always_declare_return_types - # - always_put_control_body_on_new_line - # - always_put_required_named_parameters_first - # - always_specify_types - - always_use_package_imports - - annotate_overrides - # - avoid_annotating_with_dynamic - - avoid_bool_literals_in_conditional_expressions - # - avoid_catches_without_on_clauses - # - avoid_catching_errors - - avoid_classes_with_only_static_members - - avoid_double_and_int_checks - # - avoid_dynamic_calls - - avoid_empty_else - # - avoid_equals_and_hash_code_on_mutable_classes - - avoid_escaping_inner_quotes - - avoid_field_initializers_in_const_classes - # - avoid_final_parameters - - avoid_function_literals_in_foreach_calls - - avoid_implementing_value_types - - avoid_init_to_null - - avoid_js_rounded_ints - - avoid_multiple_declarations_per_line - - avoid_null_checks_in_equality_operators - # - avoid_positional_boolean_parameters - - avoid_print - - avoid_private_typedef_functions - - avoid_redundant_argument_values - - avoid_relative_lib_imports - - avoid_renaming_method_parameters - - avoid_return_types_on_setters - - avoid_returning_null_for_void - - avoid_returning_this - - avoid_setters_without_getters - - avoid_shadowing_type_parameters - - avoid_single_cascade_in_expression_statements - - avoid_slow_async_io - - avoid_type_to_string - - avoid_types_as_parameter_names - # - avoid_types_on_closure_parameters - - avoid_unnecessary_containers - - avoid_unused_constructor_parameters - - avoid_void_async - - avoid_web_libraries_in_flutter - - await_only_futures - - camel_case_extensions - - camel_case_types - - cancel_subscriptions - - cascade_invocations - - cast_nullable_to_non_nullable - # - close_sinks - - collection_methods_unrelated_type - - combinators_ordering - - comment_references - - conditional_uri_does_not_exist - - constant_identifier_names - - control_flow_in_finally - - curly_braces_in_flow_control_structures - - dangling_library_doc_comments - - depend_on_referenced_packages - - deprecated_consistency - - deprecated_member_use_from_same_package - # - diagnostic_describe_all_properties - - directives_ordering - - discarded_futures - - do_not_use_environment - - empty_catches - - empty_constructor_bodies - - empty_statements - - eol_at_end_of_file - - exhaustive_cases - - file_names - - flutter_style_todos - - hash_and_equals - - implementation_imports - - implicit_call_tearoffs - - implicit_reopen - - invalid_case_patterns - - join_return_with_assignment - # - leading_newlines_in_multiline_strings - - library_annotations - - library_names - - library_prefixes - - library_private_types_in_public_api - # - lines_longer_than_80_chars - - literal_only_boolean_expressions - - matching_super_parameters - - missing_whitespace_between_adjacent_strings - - no_adjacent_strings_in_list - - no_default_cases - - no_duplicate_case_values - - no_leading_underscores_for_library_prefixes - - no_leading_underscores_for_local_identifiers - - no_literal_bool_comparisons - - no_logic_in_create_state - - no_runtimeType_toString - - no_self_assignments - - no_wildcard_variable_uses - - non_constant_identifier_names - - noop_primitive_operations - - null_check_on_nullable_type_parameter - - null_closures - - omit_local_variable_types - - one_member_abstracts - - only_throw_errors - - overridden_fields - - package_api_docs - - package_names - - package_prefixed_library_names - - parameter_assignments - - prefer_adjacent_string_concatenation - - prefer_asserts_in_initializer_lists - - prefer_asserts_with_message - - prefer_collection_literals - - prefer_conditional_assignment - - prefer_const_constructors - - prefer_const_constructors_in_immutables - - prefer_const_declarations - - prefer_const_literals_to_create_immutables - - prefer_constructors_over_static_methods - - prefer_contains - # - prefer_double_quotes - - prefer_expression_function_bodies - - prefer_final_fields - - prefer_final_in_for_each - - prefer_final_locals - # - prefer_final_parameters - - prefer_for_elements_to_map_fromIterable - - prefer_foreach - - prefer_function_declarations_over_variables - - prefer_generic_function_type_aliases - - prefer_if_elements_to_conditional_expressions - - prefer_if_null_operators - - prefer_initializing_formals - - prefer_inlined_adds - - prefer_int_literals - - prefer_interpolation_to_compose_strings - - prefer_is_empty - - prefer_is_not_empty - - prefer_is_not_operator - - prefer_iterable_whereType - - prefer_mixin - - prefer_null_aware_method_calls - - prefer_null_aware_operators - # - prefer_relative_imports - - prefer_single_quotes - - prefer_spread_collections - - prefer_typing_uninitialized_variables - - prefer_void_to_null - - provide_deprecation_message - - public_member_api_docs - - recursive_getters - - require_trailing_commas - - secure_pubspec_urls - - sized_box_for_whitespace - - sized_box_shrink_expand - - slash_for_doc_comments - - sort_child_properties_last - # - sort_constructors_first - - sort_pub_dependencies - - sort_unnamed_constructors_first - - test_types_in_equals - - throw_in_finally - - tighten_type_of_initializing_formals - - type_annotate_public_apis - - type_init_formals - - type_literal_in_constant_pattern - - unawaited_futures - # - unnecessary_await_in_return - - unnecessary_brace_in_string_interps - - unnecessary_breaks - - unnecessary_const - - unnecessary_constructor_name - # - unnecessary_final - - unnecessary_getters_setters - - unnecessary_lambdas - - unnecessary_late - - unnecessary_library_directive - - unnecessary_new - - unnecessary_null_aware_assignments - - unnecessary_null_aware_operator_on_extension_on_nullable - - unnecessary_null_checks - - unnecessary_null_in_if_null_operators - - unnecessary_nullable_for_final_variable_declarations - - unnecessary_overrides - - unnecessary_parenthesis - - unnecessary_raw_strings - - unnecessary_statements - - unnecessary_string_escapes - - unnecessary_string_interpolations - - unnecessary_this - - unnecessary_to_list_in_spreads - # - unreachable_from_main - - unrelated_type_equality_checks - - unsafe_html - - use_build_context_synchronously - - use_colored_box - - use_decorated_box - - use_enums - - use_full_hex_values_for_flutter_colors - - use_function_type_syntax_for_parameters - - use_if_null_to_convert_nulls_to_bools - - use_is_even_rather_than_modulo - - use_key_in_widget_constructors - - use_late_for_private_fields_and_variables - - use_named_constants - - use_raw_strings - - use_rethrow_when_possible - - use_setters_to_change_properties - - use_string_buffers - - use_string_in_part_of_directives - - use_super_parameters - - use_test_throws_matchers - - use_to_and_as_if_applicable - - valid_regexps - - void_checks - -analyzer: - exclude: - - example/ - - "**/example/" - - example_rest - - example_graphql - - "**/*.g.dart" - - errors: - # override custom - always_use_package_imports: error - camel_case_extensions: error - camel_case_types: error - curly_braces_in_flow_control_structures: error - directives_ordering: error - file_names: error - prefer_single_quotes: error - prefer_is_empty: error - prefer_is_not_empty: error - require_trailing_commas: error - sort_pub_dependencies: error - unnecessary_statements: error - - # override flutter_lints - avoid_print: error - avoid_unnecessary_containers: error - avoid_web_libraries_in_flutter: error - no_logic_in_create_state: error - prefer_const_constructors: error - prefer_const_constructors_in_immutables: error - prefer_const_declarations: error - prefer_const_literals_to_create_immutables: error - sized_box_for_whitespace: error - sort_child_properties_last: error - use_build_context_synchronously: error - use_full_hex_values_for_flutter_colors: error - use_key_in_widget_constructors: error - - # override recommended lints - always_require_non_null_named_parameters: error - annotate_overrides: error - avoid_function_literals_in_foreach_calls: error - avoid_init_to_null: error - avoid_null_checks_in_equality_operators: error - avoid_renaming_method_parameters: error - avoid_return_types_on_setters: error - avoid_returning_null_for_void: error - avoid_single_cascade_in_expression_statements: error - await_only_futures: error - constant_identifier_names: error - control_flow_in_finally: error - depend_on_referenced_packages: ignore - empty_constructor_bodies: error - empty_statements: error - exhaustive_cases: error - implementation_imports: ignore - invalid_case_patterns: error - library_names: error - library_prefixes: error - library_private_types_in_public_api: error - matching_super_parameters: error - no_leading_underscores_for_library_prefixes: error - no_leading_underscores_for_local_identifiers: error - no_literal_bool_comparisons: error - null_check_on_nullable_type_parameter: error - null_closures: error - overridden_fields: error - package_names: error - prefer_adjacent_string_concatenation: error - prefer_collection_literals: error - prefer_conditional_assignment: error - prefer_contains: error - prefer_equal_for_default_values: error - prefer_final_fields: error - prefer_for_elements_to_map_fromIterable: error - prefer_function_declarations_over_variables: error - prefer_if_null_operators: error - prefer_initializing_formals: error - prefer_inlined_adds: error - prefer_interpolation_to_compose_strings: error - prefer_is_not_operator: error - prefer_null_aware_operators: error - prefer_spread_collections: error - prefer_void_to_null: error - recursive_getters: error - slash_for_doc_comments: error - type_init_formals: error - type_literal_in_constant_pattern: error - unnecessary_brace_in_string_interps: error - unnecessary_breaks: error - unnecessary_const: error - unnecessary_constructor_name: error - unnecessary_getters_setters: error - unnecessary_late: error - unnecessary_new: error - unnecessary_null_aware_assignments: error - unnecessary_null_in_if_null_operators: error - unnecessary_nullable_for_final_variable_declarations: error - unnecessary_string_escapes: error - unnecessary_string_interpolations: error - unnecessary_this: error - use_function_type_syntax_for_parameters: error - use_rethrow_when_possible: error diff --git a/packages/brick_graphql/analysis_options.yaml b/packages/brick_graphql/analysis_options.yaml index 5008bf6c..f04c6cf0 100644 --- a/packages/brick_graphql/analysis_options.yaml +++ b/packages/brick_graphql/analysis_options.yaml @@ -1,326 +1 @@ include: ../../analysis_options.yaml - -linter: - rules: - # This list is derived from the list of all available lints located at - # https://github.com/dart-lang/linter/blob/master/example/all.yaml - - always_declare_return_types - # - always_put_control_body_on_new_line - # - always_put_required_named_parameters_first - # - always_specify_types - - always_use_package_imports - - annotate_overrides - # - avoid_annotating_with_dynamic - - avoid_bool_literals_in_conditional_expressions - # - avoid_catches_without_on_clauses - # - avoid_catching_errors - - avoid_classes_with_only_static_members - - avoid_double_and_int_checks - # - avoid_dynamic_calls - - avoid_empty_else - # - avoid_equals_and_hash_code_on_mutable_classes - - avoid_escaping_inner_quotes - - avoid_field_initializers_in_const_classes - # - avoid_final_parameters - - avoid_function_literals_in_foreach_calls - - avoid_implementing_value_types - - avoid_init_to_null - - avoid_js_rounded_ints - - avoid_multiple_declarations_per_line - - avoid_null_checks_in_equality_operators - # - avoid_positional_boolean_parameters - - avoid_print - - avoid_private_typedef_functions - - avoid_redundant_argument_values - - avoid_relative_lib_imports - - avoid_renaming_method_parameters - - avoid_return_types_on_setters - - avoid_returning_null_for_void - - avoid_returning_this - - avoid_setters_without_getters - - avoid_shadowing_type_parameters - - avoid_single_cascade_in_expression_statements - - avoid_slow_async_io - - avoid_type_to_string - - avoid_types_as_parameter_names - # - avoid_types_on_closure_parameters - - avoid_unnecessary_containers - - avoid_unused_constructor_parameters - - avoid_void_async - - avoid_web_libraries_in_flutter - - await_only_futures - - camel_case_extensions - - camel_case_types - - cancel_subscriptions - - cascade_invocations - - cast_nullable_to_non_nullable - # - close_sinks - - collection_methods_unrelated_type - - combinators_ordering - - comment_references - - conditional_uri_does_not_exist - - constant_identifier_names - - control_flow_in_finally - - curly_braces_in_flow_control_structures - - dangling_library_doc_comments - - depend_on_referenced_packages - - deprecated_consistency - - deprecated_member_use_from_same_package - # - diagnostic_describe_all_properties - - directives_ordering - - discarded_futures - - do_not_use_environment - - empty_catches - - empty_constructor_bodies - - empty_statements - - eol_at_end_of_file - - exhaustive_cases - - file_names - - flutter_style_todos - - hash_and_equals - - implementation_imports - - implicit_call_tearoffs - - implicit_reopen - - invalid_case_patterns - - join_return_with_assignment - # - leading_newlines_in_multiline_strings - - library_annotations - - library_names - - library_prefixes - - library_private_types_in_public_api - # - lines_longer_than_80_chars - - literal_only_boolean_expressions - - matching_super_parameters - - missing_whitespace_between_adjacent_strings - - no_adjacent_strings_in_list - - no_default_cases - - no_duplicate_case_values - - no_leading_underscores_for_library_prefixes - - no_leading_underscores_for_local_identifiers - - no_literal_bool_comparisons - - no_logic_in_create_state - - no_runtimeType_toString - - no_self_assignments - - no_wildcard_variable_uses - - non_constant_identifier_names - - noop_primitive_operations - - null_check_on_nullable_type_parameter - - null_closures - - omit_local_variable_types - - one_member_abstracts - - only_throw_errors - - overridden_fields - - package_api_docs - - package_names - - package_prefixed_library_names - - parameter_assignments - - prefer_adjacent_string_concatenation - - prefer_asserts_in_initializer_lists - - prefer_asserts_with_message - - prefer_collection_literals - - prefer_conditional_assignment - - prefer_const_constructors - - prefer_const_constructors_in_immutables - - prefer_const_declarations - - prefer_const_literals_to_create_immutables - - prefer_constructors_over_static_methods - - prefer_contains - # - prefer_double_quotes - - prefer_expression_function_bodies - - prefer_final_fields - - prefer_final_in_for_each - - prefer_final_locals - # - prefer_final_parameters - - prefer_for_elements_to_map_fromIterable - - prefer_foreach - - prefer_function_declarations_over_variables - - prefer_generic_function_type_aliases - - prefer_if_elements_to_conditional_expressions - - prefer_if_null_operators - - prefer_initializing_formals - - prefer_inlined_adds - - prefer_int_literals - - prefer_interpolation_to_compose_strings - - prefer_is_empty - - prefer_is_not_empty - - prefer_is_not_operator - - prefer_iterable_whereType - - prefer_mixin - - prefer_null_aware_method_calls - - prefer_null_aware_operators - # - prefer_relative_imports - - prefer_single_quotes - - prefer_spread_collections - - prefer_typing_uninitialized_variables - - prefer_void_to_null - - provide_deprecation_message - - public_member_api_docs - - recursive_getters - - require_trailing_commas - - secure_pubspec_urls - - sized_box_for_whitespace - - sized_box_shrink_expand - - slash_for_doc_comments - - sort_child_properties_last - # - sort_constructors_first - - sort_pub_dependencies - - sort_unnamed_constructors_first - - test_types_in_equals - - throw_in_finally - - tighten_type_of_initializing_formals - - type_annotate_public_apis - - type_init_formals - - type_literal_in_constant_pattern - - unawaited_futures - # - unnecessary_await_in_return - - unnecessary_brace_in_string_interps - - unnecessary_breaks - - unnecessary_const - - unnecessary_constructor_name - # - unnecessary_final - - unnecessary_getters_setters - - unnecessary_lambdas - - unnecessary_late - - unnecessary_library_directive - - unnecessary_new - - unnecessary_null_aware_assignments - - unnecessary_null_aware_operator_on_extension_on_nullable - - unnecessary_null_checks - - unnecessary_null_in_if_null_operators - - unnecessary_nullable_for_final_variable_declarations - - unnecessary_overrides - - unnecessary_parenthesis - - unnecessary_raw_strings - - unnecessary_statements - - unnecessary_string_escapes - - unnecessary_string_interpolations - - unnecessary_this - - unnecessary_to_list_in_spreads - # - unreachable_from_main - - unrelated_type_equality_checks - - unsafe_html - - use_build_context_synchronously - - use_colored_box - - use_decorated_box - - use_enums - - use_full_hex_values_for_flutter_colors - - use_function_type_syntax_for_parameters - - use_if_null_to_convert_nulls_to_bools - - use_is_even_rather_than_modulo - - use_key_in_widget_constructors - - use_late_for_private_fields_and_variables - - use_named_constants - - use_raw_strings - - use_rethrow_when_possible - - use_setters_to_change_properties - - use_string_buffers - - use_string_in_part_of_directives - - use_super_parameters - - use_test_throws_matchers - - use_to_and_as_if_applicable - - valid_regexps - - void_checks - -analyzer: - exclude: - - example/ - - "**/example/" - - example_rest - - example_graphql - - "**/*.g.dart" - - errors: - # override custom - always_use_package_imports: error - camel_case_extensions: error - camel_case_types: error - curly_braces_in_flow_control_structures: error - directives_ordering: error - file_names: error - prefer_single_quotes: error - prefer_is_empty: error - prefer_is_not_empty: error - require_trailing_commas: error - sort_pub_dependencies: error - unnecessary_statements: error - - # override flutter_lints - avoid_print: error - avoid_unnecessary_containers: error - avoid_web_libraries_in_flutter: error - no_logic_in_create_state: error - prefer_const_constructors: error - prefer_const_constructors_in_immutables: error - prefer_const_declarations: error - prefer_const_literals_to_create_immutables: error - sized_box_for_whitespace: error - sort_child_properties_last: error - use_build_context_synchronously: error - use_full_hex_values_for_flutter_colors: error - use_key_in_widget_constructors: error - - # override recommended lints - always_require_non_null_named_parameters: error - annotate_overrides: error - avoid_function_literals_in_foreach_calls: error - avoid_init_to_null: error - avoid_null_checks_in_equality_operators: error - avoid_renaming_method_parameters: error - avoid_return_types_on_setters: error - avoid_returning_null_for_void: error - avoid_single_cascade_in_expression_statements: error - await_only_futures: error - constant_identifier_names: error - control_flow_in_finally: error - depend_on_referenced_packages: ignore - empty_constructor_bodies: error - empty_statements: error - exhaustive_cases: error - implementation_imports: ignore - invalid_case_patterns: error - library_names: error - library_prefixes: error - library_private_types_in_public_api: error - matching_super_parameters: error - no_leading_underscores_for_library_prefixes: error - no_leading_underscores_for_local_identifiers: error - no_literal_bool_comparisons: error - null_check_on_nullable_type_parameter: error - null_closures: error - overridden_fields: error - package_names: error - prefer_adjacent_string_concatenation: error - prefer_collection_literals: error - prefer_conditional_assignment: error - prefer_contains: error - prefer_equal_for_default_values: error - prefer_final_fields: error - prefer_for_elements_to_map_fromIterable: error - prefer_function_declarations_over_variables: error - prefer_if_null_operators: error - prefer_initializing_formals: error - prefer_inlined_adds: error - prefer_interpolation_to_compose_strings: error - prefer_is_not_operator: error - prefer_null_aware_operators: error - prefer_spread_collections: error - prefer_void_to_null: error - recursive_getters: error - slash_for_doc_comments: error - type_init_formals: error - type_literal_in_constant_pattern: error - unnecessary_brace_in_string_interps: error - unnecessary_breaks: error - unnecessary_const: error - unnecessary_constructor_name: error - unnecessary_getters_setters: error - unnecessary_late: error - unnecessary_new: error - unnecessary_null_aware_assignments: error - unnecessary_null_in_if_null_operators: error - unnecessary_nullable_for_final_variable_declarations: error - unnecessary_string_escapes: error - unnecessary_string_interpolations: error - unnecessary_this: error - use_function_type_syntax_for_parameters: error - use_rethrow_when_possible: error diff --git a/packages/brick_graphql_generators/lib/graphql_model_serdes_generator.dart b/packages/brick_graphql_generators/lib/graphql_model_serdes_generator.dart index 44c2dd43..b7105844 100644 --- a/packages/brick_graphql_generators/lib/graphql_model_serdes_generator.dart +++ b/packages/brick_graphql_generators/lib/graphql_model_serdes_generator.dart @@ -15,6 +15,8 @@ class GraphqlModelSerdesGenerator /// should not be included. final String repositoryName; + /// Digest a `graphqlConfig` (`@ConnectOfflineFirstWithGraphQL`) from [reader] and manage serdes generators + /// to and from a `GraphqlProvider`. GraphqlModelSerdesGenerator( super.element, super.reader, { @@ -24,7 +26,7 @@ class GraphqlModelSerdesGenerator @override GraphqlSerializableExtended get config { if (reader.peek(configKey) == null) { - return GraphqlSerializableExtended(); + return const GraphqlSerializableExtended(); } final fieldRenameIndex = diff --git a/packages/brick_graphql_generators/lib/src/graphql_deserialize.dart b/packages/brick_graphql_generators/lib/src/graphql_deserialize.dart index 997588e3..b023a9c6 100644 --- a/packages/brick_graphql_generators/lib/src/graphql_deserialize.dart +++ b/packages/brick_graphql_generators/lib/src/graphql_deserialize.dart @@ -19,6 +19,7 @@ class GraphqlDeserialize extends GraphqlSerdesGenerator ]; } + /// Generate a function to produce a [ClassElement] from GraphQL data GraphqlDeserialize( super.element, super.fields, { diff --git a/packages/brick_graphql_generators/lib/src/graphql_fields.dart b/packages/brick_graphql_generators/lib/src/graphql_fields.dart index f4b52afd..61102aed 100644 --- a/packages/brick_graphql_generators/lib/src/graphql_fields.dart +++ b/packages/brick_graphql_generators/lib/src/graphql_fields.dart @@ -9,12 +9,14 @@ import 'package:brick_graphql_generators/src/graphql_serializable_query_transfor /// Find `@Graphql` given a field class GraphqlAnnotationFinder extends AnnotationFinder with AnnotationFinderWithFieldRename { + /// final GraphqlSerializable? config; + /// Find `@Graphql` given a field GraphqlAnnotationFinder([this.config]); @override - Graphql from(element) { + Graphql from(FieldElement element) { final obj = objectForField(element); if (obj == null) { @@ -53,20 +55,21 @@ class GraphqlAnnotationFinder extends AnnotationFinder if (unconvertedMap == null) return {}; return { for (final entry in unconvertedMap.entries) - entry.key!.toStringValue()!: entry.value?.toStringValue() == null - ? _convertMapToMap(entry.value!.toMapValue()!) - : {}, + entry.key!.toStringValue()!: + entry.value?.toStringValue() == null ? _convertMapToMap(entry.value!.toMapValue()) : {}, }; } } /// Converts all fields to [Graphql]s for later consumption class GraphqlFields extends FieldsForClass { + /// final GraphqlSerializableExtended? config; @override final GraphqlAnnotationFinder finder; + /// Converts all fields to [Graphql]s for later consumption GraphqlFields(ClassElement element, [this.config]) : finder = GraphqlAnnotationFinder(config), super(element: element); diff --git a/packages/brick_graphql_generators/lib/src/graphql_serdes_generator.dart b/packages/brick_graphql_generators/lib/src/graphql_serdes_generator.dart index 94d99584..8b01a27c 100644 --- a/packages/brick_graphql_generators/lib/src/graphql_serdes_generator.dart +++ b/packages/brick_graphql_generators/lib/src/graphql_serdes_generator.dart @@ -2,7 +2,9 @@ import 'package:brick_graphql/brick_graphql.dart'; import 'package:brick_graphql_generators/src/graphql_fields.dart'; import 'package:brick_json_generators/json_serdes_generator.dart'; +/// abstract class GraphqlSerdesGenerator extends JsonSerdesGenerator { + /// GraphqlSerdesGenerator( super.element, GraphqlFields super.fields, { diff --git a/packages/brick_graphql_generators/lib/src/graphql_serializable_query_transformer_extended.dart b/packages/brick_graphql_generators/lib/src/graphql_serializable_query_transformer_extended.dart index 1a7fbf11..458faed5 100644 --- a/packages/brick_graphql_generators/lib/src/graphql_serializable_query_transformer_extended.dart +++ b/packages/brick_graphql_generators/lib/src/graphql_serializable_query_transformer_extended.dart @@ -4,8 +4,17 @@ import 'package:brick_graphql/brick_graphql.dart'; /// however, the function can't be re-interpreted by ConstantReader. /// So the name is grabbed to be used in a later generator. class GraphqlSerializableExtended extends GraphqlSerializable { + /// The interface used to determine the document to send GraphQL. This class + /// will be accessed for all provider and repository operations. + /// + /// Implementing classes of [GraphqlQueryOperationTransformer] must be a `const` + /// constructor. For simplicity, the default constructor tearoff can be provided + /// as a value (`queryOperationTransformer: MyTransformer.new`). final String? queryOperationTransformerName; + /// [GraphqlSerializable] has `queryOperationTransformer`, + /// however, the function can't be re-interpreted by ConstantReader. + /// So the name is grabbed to be used in a later generator. const GraphqlSerializableExtended({ super.fieldRename, this.queryOperationTransformerName, diff --git a/packages/brick_graphql_generators/lib/src/graphql_serialize.dart b/packages/brick_graphql_generators/lib/src/graphql_serialize.dart index 7856d49a..8e0998ae 100644 --- a/packages/brick_graphql_generators/lib/src/graphql_serialize.dart +++ b/packages/brick_graphql_generators/lib/src/graphql_serialize.dart @@ -18,6 +18,7 @@ class GraphqlSerialize extends GraphqlSerdesGenerator with JsonSerialize=1.2.2 <2.0.0" dev_dependencies: - test: ^1.20.1 - lints: ^2.0.1 brick_build_test: path: ../brick_build_test + lints: + test: diff --git a/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_annotation_subfields.dart b/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_annotation_subfields.dart index 6ebb66b6..c97b31d9 100644 --- a/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_annotation_subfields.dart +++ b/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_annotation_subfields.dart @@ -1,6 +1,6 @@ import 'package:brick_graphql/brick_graphql.dart'; -final output = r''' +const output = r''' // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_constructor_member_field_mismatch.dart b/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_constructor_member_field_mismatch.dart index 89324198..2f63c497 100644 --- a/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_constructor_member_field_mismatch.dart +++ b/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_constructor_member_field_mismatch.dart @@ -1,6 +1,6 @@ import 'package:brick_graphql/brick_graphql.dart'; -final output = r''' +const output = r''' Future _$GraphqlConstructorMemberFieldMismatchFromGraphql( Map data, diff --git a/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_enum_as_string.dart b/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_enum_as_string.dart index 6b2f7ac9..9bf9a45f 100644 --- a/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_enum_as_string.dart +++ b/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_enum_as_string.dart @@ -1,6 +1,6 @@ import 'package:brick_graphql/brick_graphql.dart'; -final output = r''' +const output = r''' Future _$EnumAsStringFromGraphql(Map data, {required GraphqlProvider provider, GraphqlFirstRepository? repository}) async { diff --git a/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_from_json_to_json.dart b/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_from_json_to_json.dart index 1c18e954..59d94aa9 100644 --- a/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_from_json_to_json.dart +++ b/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_from_json_to_json.dart @@ -1,6 +1,6 @@ import 'package:brick_graphql/brick_graphql.dart'; -final output = r''' +const output = r''' // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_ignore_from_to.dart b/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_ignore_from_to.dart index 051c7feb..11dc7d93 100644 --- a/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_ignore_from_to.dart +++ b/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_ignore_from_to.dart @@ -1,6 +1,6 @@ import 'package:brick_graphql/brick_graphql.dart'; -final output = r''' +const output = r''' Future _$GraphqlIgnoreFromToFromGraphql( Map data, {required GraphqlProvider provider, diff --git a/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_runtime_association_definition.dart b/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_runtime_association_definition.dart index 721981ea..f8988286 100644 --- a/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_runtime_association_definition.dart +++ b/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_runtime_association_definition.dart @@ -1,6 +1,6 @@ import 'package:brick_graphql/brick_graphql.dart'; -final output = r''' +const output = r''' // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_unserializable_field_with_generator.dart b/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_unserializable_field_with_generator.dart index fcee516d..0630d53d 100644 --- a/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_unserializable_field_with_generator.dart +++ b/packages/brick_graphql_generators/test/graphql_model_serdes_generator/test_unserializable_field_with_generator.dart @@ -3,7 +3,7 @@ import 'dart:typed_data'; import 'package:brick_graphql/brick_graphql.dart'; -final output = r''' +const output = r''' Future _$GraphqlUnserializableFieldWithGeneratorFromGraphql( Map data, diff --git a/packages/brick_graphql_generators/test/graphql_model_serdes_generator_test.dart b/packages/brick_graphql_generators/test/graphql_model_serdes_generator_test.dart index 0b986b2a..ad249f85 100644 --- a/packages/brick_graphql_generators/test/graphql_model_serdes_generator_test.dart +++ b/packages/brick_graphql_generators/test/graphql_model_serdes_generator_test.dart @@ -18,7 +18,7 @@ import 'graphql_model_serdes_generator/test_unserializable_field_with_generator. as unserializable_field_with_generator; final _generator = TestGenerator(); -final folder = 'graphql_model_serdes_generator'; +const folder = 'graphql_model_serdes_generator'; final generateReader = generateLibraryForFolder(folder); void main() { diff --git a/packages/brick_json_generators/analysis_options.yaml b/packages/brick_json_generators/analysis_options.yaml index 5008bf6c..f04c6cf0 100644 --- a/packages/brick_json_generators/analysis_options.yaml +++ b/packages/brick_json_generators/analysis_options.yaml @@ -1,326 +1 @@ include: ../../analysis_options.yaml - -linter: - rules: - # This list is derived from the list of all available lints located at - # https://github.com/dart-lang/linter/blob/master/example/all.yaml - - always_declare_return_types - # - always_put_control_body_on_new_line - # - always_put_required_named_parameters_first - # - always_specify_types - - always_use_package_imports - - annotate_overrides - # - avoid_annotating_with_dynamic - - avoid_bool_literals_in_conditional_expressions - # - avoid_catches_without_on_clauses - # - avoid_catching_errors - - avoid_classes_with_only_static_members - - avoid_double_and_int_checks - # - avoid_dynamic_calls - - avoid_empty_else - # - avoid_equals_and_hash_code_on_mutable_classes - - avoid_escaping_inner_quotes - - avoid_field_initializers_in_const_classes - # - avoid_final_parameters - - avoid_function_literals_in_foreach_calls - - avoid_implementing_value_types - - avoid_init_to_null - - avoid_js_rounded_ints - - avoid_multiple_declarations_per_line - - avoid_null_checks_in_equality_operators - # - avoid_positional_boolean_parameters - - avoid_print - - avoid_private_typedef_functions - - avoid_redundant_argument_values - - avoid_relative_lib_imports - - avoid_renaming_method_parameters - - avoid_return_types_on_setters - - avoid_returning_null_for_void - - avoid_returning_this - - avoid_setters_without_getters - - avoid_shadowing_type_parameters - - avoid_single_cascade_in_expression_statements - - avoid_slow_async_io - - avoid_type_to_string - - avoid_types_as_parameter_names - # - avoid_types_on_closure_parameters - - avoid_unnecessary_containers - - avoid_unused_constructor_parameters - - avoid_void_async - - avoid_web_libraries_in_flutter - - await_only_futures - - camel_case_extensions - - camel_case_types - - cancel_subscriptions - - cascade_invocations - - cast_nullable_to_non_nullable - # - close_sinks - - collection_methods_unrelated_type - - combinators_ordering - - comment_references - - conditional_uri_does_not_exist - - constant_identifier_names - - control_flow_in_finally - - curly_braces_in_flow_control_structures - - dangling_library_doc_comments - - depend_on_referenced_packages - - deprecated_consistency - - deprecated_member_use_from_same_package - # - diagnostic_describe_all_properties - - directives_ordering - - discarded_futures - - do_not_use_environment - - empty_catches - - empty_constructor_bodies - - empty_statements - - eol_at_end_of_file - - exhaustive_cases - - file_names - - flutter_style_todos - - hash_and_equals - - implementation_imports - - implicit_call_tearoffs - - implicit_reopen - - invalid_case_patterns - - join_return_with_assignment - # - leading_newlines_in_multiline_strings - - library_annotations - - library_names - - library_prefixes - - library_private_types_in_public_api - # - lines_longer_than_80_chars - - literal_only_boolean_expressions - - matching_super_parameters - - missing_whitespace_between_adjacent_strings - - no_adjacent_strings_in_list - - no_default_cases - - no_duplicate_case_values - - no_leading_underscores_for_library_prefixes - - no_leading_underscores_for_local_identifiers - - no_literal_bool_comparisons - - no_logic_in_create_state - - no_runtimeType_toString - - no_self_assignments - - no_wildcard_variable_uses - - non_constant_identifier_names - - noop_primitive_operations - - null_check_on_nullable_type_parameter - - null_closures - - omit_local_variable_types - - one_member_abstracts - - only_throw_errors - - overridden_fields - - package_api_docs - - package_names - - package_prefixed_library_names - - parameter_assignments - - prefer_adjacent_string_concatenation - - prefer_asserts_in_initializer_lists - - prefer_asserts_with_message - - prefer_collection_literals - - prefer_conditional_assignment - - prefer_const_constructors - - prefer_const_constructors_in_immutables - - prefer_const_declarations - - prefer_const_literals_to_create_immutables - - prefer_constructors_over_static_methods - - prefer_contains - # - prefer_double_quotes - - prefer_expression_function_bodies - - prefer_final_fields - - prefer_final_in_for_each - - prefer_final_locals - # - prefer_final_parameters - - prefer_for_elements_to_map_fromIterable - - prefer_foreach - - prefer_function_declarations_over_variables - - prefer_generic_function_type_aliases - - prefer_if_elements_to_conditional_expressions - - prefer_if_null_operators - - prefer_initializing_formals - - prefer_inlined_adds - - prefer_int_literals - - prefer_interpolation_to_compose_strings - - prefer_is_empty - - prefer_is_not_empty - - prefer_is_not_operator - - prefer_iterable_whereType - - prefer_mixin - - prefer_null_aware_method_calls - - prefer_null_aware_operators - # - prefer_relative_imports - - prefer_single_quotes - - prefer_spread_collections - - prefer_typing_uninitialized_variables - - prefer_void_to_null - - provide_deprecation_message - - public_member_api_docs - - recursive_getters - - require_trailing_commas - - secure_pubspec_urls - - sized_box_for_whitespace - - sized_box_shrink_expand - - slash_for_doc_comments - - sort_child_properties_last - # - sort_constructors_first - - sort_pub_dependencies - - sort_unnamed_constructors_first - - test_types_in_equals - - throw_in_finally - - tighten_type_of_initializing_formals - - type_annotate_public_apis - - type_init_formals - - type_literal_in_constant_pattern - - unawaited_futures - # - unnecessary_await_in_return - - unnecessary_brace_in_string_interps - - unnecessary_breaks - - unnecessary_const - - unnecessary_constructor_name - # - unnecessary_final - - unnecessary_getters_setters - - unnecessary_lambdas - - unnecessary_late - - unnecessary_library_directive - - unnecessary_new - - unnecessary_null_aware_assignments - - unnecessary_null_aware_operator_on_extension_on_nullable - - unnecessary_null_checks - - unnecessary_null_in_if_null_operators - - unnecessary_nullable_for_final_variable_declarations - - unnecessary_overrides - - unnecessary_parenthesis - - unnecessary_raw_strings - - unnecessary_statements - - unnecessary_string_escapes - - unnecessary_string_interpolations - - unnecessary_this - - unnecessary_to_list_in_spreads - # - unreachable_from_main - - unrelated_type_equality_checks - - unsafe_html - - use_build_context_synchronously - - use_colored_box - - use_decorated_box - - use_enums - - use_full_hex_values_for_flutter_colors - - use_function_type_syntax_for_parameters - - use_if_null_to_convert_nulls_to_bools - - use_is_even_rather_than_modulo - - use_key_in_widget_constructors - - use_late_for_private_fields_and_variables - - use_named_constants - - use_raw_strings - - use_rethrow_when_possible - - use_setters_to_change_properties - - use_string_buffers - - use_string_in_part_of_directives - - use_super_parameters - - use_test_throws_matchers - - use_to_and_as_if_applicable - - valid_regexps - - void_checks - -analyzer: - exclude: - - example/ - - "**/example/" - - example_rest - - example_graphql - - "**/*.g.dart" - - errors: - # override custom - always_use_package_imports: error - camel_case_extensions: error - camel_case_types: error - curly_braces_in_flow_control_structures: error - directives_ordering: error - file_names: error - prefer_single_quotes: error - prefer_is_empty: error - prefer_is_not_empty: error - require_trailing_commas: error - sort_pub_dependencies: error - unnecessary_statements: error - - # override flutter_lints - avoid_print: error - avoid_unnecessary_containers: error - avoid_web_libraries_in_flutter: error - no_logic_in_create_state: error - prefer_const_constructors: error - prefer_const_constructors_in_immutables: error - prefer_const_declarations: error - prefer_const_literals_to_create_immutables: error - sized_box_for_whitespace: error - sort_child_properties_last: error - use_build_context_synchronously: error - use_full_hex_values_for_flutter_colors: error - use_key_in_widget_constructors: error - - # override recommended lints - always_require_non_null_named_parameters: error - annotate_overrides: error - avoid_function_literals_in_foreach_calls: error - avoid_init_to_null: error - avoid_null_checks_in_equality_operators: error - avoid_renaming_method_parameters: error - avoid_return_types_on_setters: error - avoid_returning_null_for_void: error - avoid_single_cascade_in_expression_statements: error - await_only_futures: error - constant_identifier_names: error - control_flow_in_finally: error - depend_on_referenced_packages: ignore - empty_constructor_bodies: error - empty_statements: error - exhaustive_cases: error - implementation_imports: ignore - invalid_case_patterns: error - library_names: error - library_prefixes: error - library_private_types_in_public_api: error - matching_super_parameters: error - no_leading_underscores_for_library_prefixes: error - no_leading_underscores_for_local_identifiers: error - no_literal_bool_comparisons: error - null_check_on_nullable_type_parameter: error - null_closures: error - overridden_fields: error - package_names: error - prefer_adjacent_string_concatenation: error - prefer_collection_literals: error - prefer_conditional_assignment: error - prefer_contains: error - prefer_equal_for_default_values: error - prefer_final_fields: error - prefer_for_elements_to_map_fromIterable: error - prefer_function_declarations_over_variables: error - prefer_if_null_operators: error - prefer_initializing_formals: error - prefer_inlined_adds: error - prefer_interpolation_to_compose_strings: error - prefer_is_not_operator: error - prefer_null_aware_operators: error - prefer_spread_collections: error - prefer_void_to_null: error - recursive_getters: error - slash_for_doc_comments: error - type_init_formals: error - type_literal_in_constant_pattern: error - unnecessary_brace_in_string_interps: error - unnecessary_breaks: error - unnecessary_const: error - unnecessary_constructor_name: error - unnecessary_getters_setters: error - unnecessary_late: error - unnecessary_new: error - unnecessary_null_aware_assignments: error - unnecessary_null_in_if_null_operators: error - unnecessary_nullable_for_final_variable_declarations: error - unnecessary_string_escapes: error - unnecessary_string_interpolations: error - unnecessary_this: error - use_function_type_syntax_for_parameters: error - use_rethrow_when_possible: error diff --git a/packages/brick_offline_first/lib/src/annotations/offline_first_annotation.dart b/packages/brick_offline_first/lib/src/annotations/offline_first_annotation.dart index a6672ffa..859f119f 100644 --- a/packages/brick_offline_first/lib/src/annotations/offline_first_annotation.dart +++ b/packages/brick_offline_first/lib/src/annotations/offline_first_annotation.dart @@ -1,3 +1,5 @@ +import 'package:brick_core/field_serializable.dart'; + /// Low-level field config for the `OfflineFirst` domain. class OfflineFirst { /// When `true` (the default), [where] will be used to fetch associations by their defined keys. @@ -38,7 +40,7 @@ class OfflineFirst { /// /// If [where] is not defined for an association, Brick will attempt to instantiate the /// association from the data in the payload. When [where] is included, the field will - /// not be generated for the serializer of the remote provider unless [toGenerator] is defined **or** only one pair is defined. + /// not be generated for the serializer of the remote provider unless [FieldSerializable.toGenerator] is defined **or** only one pair is defined. final Map? where; /// Annotates classes that require extra manipulation to map to the expected field type @@ -47,5 +49,6 @@ class OfflineFirst { this.where, }); - static const defaults = OfflineFirst(applyToRemoteDeserialization: true); + /// + static const defaults = OfflineFirst(); } diff --git a/packages/brick_offline_first/lib/src/mixins/destructive_local_sync_from_remote_mixin.dart b/packages/brick_offline_first/lib/src/mixins/destructive_local_sync_from_remote_mixin.dart index 1da4fd4e..313f654e 100644 --- a/packages/brick_offline_first/lib/src/mixins/destructive_local_sync_from_remote_mixin.dart +++ b/packages/brick_offline_first/lib/src/mixins/destructive_local_sync_from_remote_mixin.dart @@ -12,10 +12,10 @@ import 'package:brick_offline_first/src/offline_first_repository.dart'; /// should not be paginated and complete from a single request. mixin DestructiveLocalSyncFromRemoteMixin on OfflineFirstRepository { + /// When [forceLocalSyncFromRemote] is `true`, local instances that do not exist in the [remoteProvider] + /// are destroyed. Further, when `true`, all values from other parameters except [query] are ignored. @override Future> get({ - /// When [forceLocalSyncFromRemote] is `true`, local instances that do not exist in the [remoteProvider] - /// are destroyed. Further, when `true`, all values from other parameters except [query] are ignored. bool forceLocalSyncFromRemote = false, OfflineFirstGetPolicy policy = OfflineFirstGetPolicy.awaitRemoteWhenNoneExist, Query? query, @@ -36,7 +36,7 @@ mixin DestructiveLocalSyncFromRemoteMixin /// do not exist in the [remoteProvider] are destroyed. The data from the [remoteProvider] /// should not be paginated and must be complete from a single request. Future> destructiveLocalSyncFromRemote({Query? query}) async { - query = (query ?? Query()).copyWith(action: QueryAction.get); + query = (query ?? const Query()).copyWith(action: QueryAction.get); logger.finest('#get: $TModel $query'); final remoteResults = await remoteProvider.get(query: query, repository: this); diff --git a/packages/brick_offline_first/lib/src/models/offline_first_serdes.dart b/packages/brick_offline_first/lib/src/models/offline_first_serdes.dart index 6e6dca17..3cfe3a3e 100644 --- a/packages/brick_offline_first/lib/src/models/offline_first_serdes.dart +++ b/packages/brick_offline_first/lib/src/models/offline_first_serdes.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + /// A class that isn't connected to the `OfflineFirstRepository` but is still used /// by `OfflineFirstModels` (such as a `Cash` class that declares `amount` and `currency`). /// [OfflineFirstSerdes] **must** extend the class in end implementation. diff --git a/packages/brick_offline_first/lib/src/offline_first_adapter.dart b/packages/brick_offline_first/lib/src/offline_first_adapter.dart index b0eab9fb..039fa0a2 100644 --- a/packages/brick_offline_first/lib/src/offline_first_adapter.dart +++ b/packages/brick_offline_first/lib/src/offline_first_adapter.dart @@ -1,10 +1,12 @@ import 'package:brick_offline_first/src/models/offline_first_model.dart'; import 'package:brick_offline_first/src/runtime_offline_first_definition.dart'; -import 'package:brick_sqlite/brick_sqlite.dart' show SqliteAdapter; +import 'package:brick_sqlite/brick_sqlite.dart'; -/// This adapter fetches first from [SqliteProvider] then hydrates with from a remote provider.. +/// This adapter fetches first from [SqliteProvider] then hydrates with from a remote provider. abstract class OfflineFirstAdapter<_Model extends OfflineFirstModel> extends SqliteAdapter<_Model> { + /// Keyed by Dart field name. See [RuntimeOfflineFirstDefinition] Map get fieldsToOfflineFirstRuntimeDefinition => {}; + /// This adapter fetches first from [SqliteProvider] then hydrates with from a remote provider.. OfflineFirstAdapter(); } diff --git a/packages/brick_offline_first/lib/src/offline_first_exception.dart b/packages/brick_offline_first/lib/src/offline_first_exception.dart index 9e1d75a2..d1cbc79a 100644 --- a/packages/brick_offline_first/lib/src/offline_first_exception.dart +++ b/packages/brick_offline_first/lib/src/offline_first_exception.dart @@ -1,7 +1,15 @@ +import 'package:brick_sqlite/brick_sqlite.dart'; + +/// An exception thrown by the remote provider or the [SqliteProvider]. +/// An implementation may choose to ignore this error if the remote exception +/// is not important to the requested behavior. class OfflineFirstException implements Exception { - /// The producing error from either [RestProvider] or [SqliteProvider]. + /// The producing error from the remote provider or [SqliteProvider]. final Exception originalError; + /// An exception thrown by the remote provider or the [SqliteProvider]. + /// An implementation may choose to ignore this error if the remote exception + /// is not important to the requested behavior. OfflineFirstException(this.originalError); String get message => originalError.toString(); diff --git a/packages/brick_offline_first/lib/src/offline_first_policy.dart b/packages/brick_offline_first/lib/src/offline_first_policy.dart index 7328e95c..e1699705 100644 --- a/packages/brick_offline_first/lib/src/offline_first_policy.dart +++ b/packages/brick_offline_first/lib/src/offline_first_policy.dart @@ -1,3 +1,4 @@ +/// Behaviors for how the repository should handle delete requests enum OfflineFirstDeletePolicy { /// Delete local results before waiting for the remote provider to respond optimisticLocal, @@ -26,6 +27,7 @@ enum OfflineFirstGetPolicy { localOnly, } +/// Behaviors for how the repository should handle upsert requests enum OfflineFirstUpsertPolicy { /// Save results to local before waiting for the remote provider to respond optimisticLocal, diff --git a/packages/brick_offline_first/lib/src/offline_first_repository.dart b/packages/brick_offline_first/lib/src/offline_first_repository.dart index 2d5bf2d6..8d7aa331 100644 --- a/packages/brick_offline_first/lib/src/offline_first_repository.dart +++ b/packages/brick_offline_first/lib/src/offline_first_repository.dart @@ -1,9 +1,8 @@ import 'dart:async'; import 'dart:io'; -import 'package:brick_core/core.dart' show Query, ModelRepository, QueryAction, Provider; -import 'package:brick_offline_first/src/models/offline_first_model.dart'; -import 'package:brick_offline_first/src/offline_first_policy.dart'; +import 'package:brick_core/core.dart' show ModelRepository, Provider, Query, QueryAction; +import 'package:brick_offline_first/brick_offline_first.dart'; import 'package:brick_sqlite/brick_sqlite.dart'; import 'package:brick_sqlite/db.dart'; import 'package:brick_sqlite/memory_cache_provider.dart'; @@ -15,7 +14,7 @@ import 'package:meta/meta.dart'; /// A [ModelRepository] that interacts with a [SqliteProvider] first before using a [Provider] from a remote source. /// /// The `OfflineFirstRepository` should be extended by an implementation in the end class. -/// The implementation can then be accessed via singleton or [InheritedWidget]. +/// The implementation can then be accessed via singleton or `InheritedWidget`. /// For example: /// ```dart /// class MyRepository extends OfflineFirstRepository { @@ -44,7 +43,7 @@ import 'package:meta/meta.dart'; abstract class OfflineFirstRepository implements ModelRepository { /// Refetch results in the background from remote source when any request is made. - /// Defaults to [false]. + /// Defaults to `false`. final bool autoHydrate; /// Required to maintain the same policy for [getAssociation] requests. @@ -57,6 +56,7 @@ abstract class OfflineFirstRepository>>> subscriptions = {}; @@ -74,6 +75,7 @@ abstract class OfflineFirstRepository(instance, query: query); - await notifySubscriptionsWithLocalData(notifyWhenEmpty: true); + await notifySubscriptionsWithLocalData(); } try { await remoteProvider.delete(instance, query: query, repository: this); if (requireRemote) { rowsDeleted = await _deleteLocal(instance, query: query); - await notifySubscriptionsWithLocalData(notifyWhenEmpty: true); + await notifySubscriptionsWithLocalData(); } } on ClientException catch (e) { logger.warning('#delete client failure: $e'); @@ -179,7 +181,7 @@ abstract class OfflineFirstRepository>; } @@ -405,7 +407,7 @@ abstract class OfflineFirstRepository(modelIds, eagerError: true); MapEntry modelWithPrimaryKey(index, id) { - final model = models[index]; - model.primaryKey = id; + final model = models[index]..primaryKey = id; return MapEntry(index, model); } diff --git a/packages/brick_offline_first/lib/src/offline_queue/offline_request_queue.dart b/packages/brick_offline_first/lib/src/offline_queue/offline_request_queue.dart index f471eca4..19a44ef6 100644 --- a/packages/brick_offline_first/lib/src/offline_queue/offline_request_queue.dart +++ b/packages/brick_offline_first/lib/src/offline_queue/offline_request_queue.dart @@ -9,6 +9,7 @@ abstract class OfflineRequestQueue { /// If the queue is processing bool get isRunning => _timer?.isActive ?? false; + /// @protected final Logger logger; @@ -16,12 +17,15 @@ abstract class OfflineRequestQueue { /// not occur as the Timer runs in sub routines or isolates bool _processingInBackground = false; + /// How often requests are reattempted final Duration processingInterval; + /// final RequestSqliteCacheManager requestManager; Timer? _timer; + /// Repeatedly reattempts requests in an interval OfflineRequestQueue({ required this.processingInterval, required this.requestManager, @@ -45,7 +49,7 @@ abstract class OfflineRequestQueue { } } - /// Start the processing queue, resending requests every [interval]. + /// Start the processing queue, resending requests every [processingInterval]. /// Stops the existing timer if it was already running. void start() { stop(); diff --git a/packages/brick_offline_first/lib/src/offline_queue/request_sqlite_cache.dart b/packages/brick_offline_first/lib/src/offline_queue/request_sqlite_cache.dart index 66298cee..33b93afd 100644 --- a/packages/brick_offline_first/lib/src/offline_queue/request_sqlite_cache.dart +++ b/packages/brick_offline_first/lib/src/offline_queue/request_sqlite_cache.dart @@ -2,17 +2,30 @@ import 'package:logging/logging.dart'; import 'package:meta/meta.dart'; import 'package:sqflite_common/sqlite_api.dart' show Database, DatabaseExecutor; -/// Serialize and Deserialize a [Request] from SQLite. +/// Serialize and Deserialize a [TRequest] from SQLite. abstract class RequestSqliteCache { + /// Column that tracks the number of attempts final String attemptColumn; + + /// final String createdAtColumn; + + /// Column that tracks if the request is locked final String lockedColumn; + + /// Column that tracks the primary key final String primaryKeyColumn; + + /// final TRequest request; /// Columns used to uniquely identify the request (e.g. body, headers, url, method). final List requestColumns; + + /// final String tableName; + + /// final String updateAtColumn; /// Matches any HTTP requests that send data (or 'push'). 'Pull' requests most often have an @@ -51,6 +64,7 @@ abstract class RequestSqliteCache { return 0; } + /// @protected Future?> findRequestInDatabase(DatabaseExecutor db) async { final whereStatement = requestColumns.join(' = ? AND '); @@ -101,7 +115,7 @@ abstract class RequestSqliteCache { TRequest sqliteToRequest(Map data); /// Builds request into a new SQLite-insertable row - /// Only available if [request] was initialized from [fromRequest] + /// Only available if [request] was initialized from [sqliteToRequest] /// /// This is a function to ensure `DateTime.now()` is invoked predictably. Map toSqlite(); @@ -121,6 +135,7 @@ abstract class RequestSqliteCache { }); } + /// static Future lockRequest({ required DatabaseExecutor db, required Map data, @@ -130,6 +145,7 @@ abstract class RequestSqliteCache { }) async => await _updateLock(true, data, db, tableName, lockedColumn, primaryKeyColumn); + /// static Future unlockRequest({ required DatabaseExecutor db, required Map data, diff --git a/packages/brick_offline_first/lib/src/offline_queue/request_sqlite_cache_manager.dart b/packages/brick_offline_first/lib/src/offline_queue/request_sqlite_cache_manager.dart index 279cc4e4..215a8abf 100644 --- a/packages/brick_offline_first/lib/src/offline_queue/request_sqlite_cache_manager.dart +++ b/packages/brick_offline_first/lib/src/offline_queue/request_sqlite_cache_manager.dart @@ -1,6 +1,6 @@ import 'package:brick_offline_first/src/offline_queue/request_sqlite_cache.dart'; import 'package:meta/meta.dart'; -import 'package:sqflite_common/sqlite_api.dart' show Database, DatabaseFactory, DatabaseExecutor; +import 'package:sqflite_common/sqlite_api.dart' show Database, DatabaseExecutor, DatabaseFactory; /// Fetch and delete [RequestSqliteCache]s. abstract class RequestSqliteCacheManager { @@ -15,15 +15,25 @@ abstract class RequestSqliteCacheManager { /// With [databaseFactory], this is most commonly the /// `sqlite_common` constant `inMemoryDatabasePath`. final String createdAtColumn; + + /// Database file path final String databaseName; + + /// Column that tracks if the request is locked final String lockedColumn; + + /// Column that tracks the primary key final String primaryKeyColumn; + + /// final String updateAtColumn; Future? _db; + /// final String tableName; + /// String get orderByStatement { if (!serialProcessing) { return '$updateAtColumn ASC'; @@ -39,6 +49,7 @@ abstract class RequestSqliteCacheManager { /// Defaults `true`. final bool serialProcessing; + /// Fetch and delete [RequestSqliteCache]s. RequestSqliteCacheManager( this.databaseName, { required this.createdAtColumn, @@ -68,6 +79,7 @@ abstract class RequestSqliteCacheManager { return result > 0; } + /// Future getDb() { _db ??= databaseFactory.openDatabase(databaseName); @@ -138,7 +150,7 @@ abstract class RequestSqliteCacheManager { tableName, distinct: true, where: '$lockedColumn = ? AND $createdAtColumn <= ?', - whereArgs: [whereLocked ? 1 : 0, nowMinusNextPoll], + whereArgs: [if (whereLocked) 1 else 0, nowMinusNextPoll], orderBy: orderByStatement, limit: 1, ); diff --git a/packages/brick_offline_first/lib/src/runtime_offline_first_definition.dart b/packages/brick_offline_first/lib/src/runtime_offline_first_definition.dart index c4cc9940..2c40c241 100644 --- a/packages/brick_offline_first/lib/src/runtime_offline_first_definition.dart +++ b/packages/brick_offline_first/lib/src/runtime_offline_first_definition.dart @@ -5,6 +5,8 @@ class RuntimeOfflineFirstDefinition { /// `OfflineFirst` annotation final Map where; + /// Used to define types in [OfflineFirstAdapter#fieldsToOfflineFirstRuntimeDefinition]. The build runner package + /// extracts types and associations that would've been otherwise inaccessible at runtime. const RuntimeOfflineFirstDefinition({ required this.where, }); diff --git a/packages/brick_offline_first/pubspec.yaml b/packages/brick_offline_first/pubspec.yaml index bf93246d..69906f92 100644 --- a/packages/brick_offline_first/pubspec.yaml +++ b/packages/brick_offline_first/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: 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 + lints: + mockito: + sqflite_common_ffi: + test: diff --git a/packages/brick_offline_first/test/offline_first/helpers/__mocks__.dart b/packages/brick_offline_first/test/offline_first/helpers/__mocks__.dart index 84986512..7fd5fdd0 100644 --- a/packages/brick_offline_first/test/offline_first/helpers/__mocks__.dart +++ b/packages/brick_offline_first/test/offline_first/helpers/__mocks__.dart @@ -1,3 +1,4 @@ +import 'package:brick_core/src/model_repository.dart'; import 'package:brick_offline_first/brick_offline_first.dart'; import 'package:brick_sqlite/brick_sqlite.dart'; import 'package:brick_sqlite/db.dart'; @@ -11,8 +12,8 @@ part 'horse_adapter.dart'; part 'mounty.dart'; part 'mounty_adapter.dart'; -/// The exact same as [DemoModel], except this class is tracked by the Memory Cache Provider -/// while [DemoModel] is not. +/// The exact same as [Mounty], except this class is tracked by the Memory Cache Provider +/// while [Mounty] is not. class MemoryDemoModel extends Mounty { MemoryDemoModel(String name) : super(name: name); } @@ -45,11 +46,13 @@ class DemoModelMigration extends Migration { } class TestRepository extends OfflineFirstWithTestRepository { - static TestRepository? _singleton; + static late TestRepository? _singleton; /// A hack to similuate a failure in the remote provider static bool throwOnNextRemoteMutation = false; + factory TestRepository() => _singleton!; + TestRepository._( TestProvider testProvider, SqliteProvider sqliteProvider, @@ -60,8 +63,6 @@ class TestRepository extends OfflineFirstWithTestRepository { migrations: {const DemoModelMigration()}, ); - factory TestRepository() => _singleton!; - factory TestRepository.withProviders(TestProvider testProvider, SqliteProvider sqliteProvider) => TestRepository._(testProvider, sqliteProvider); diff --git a/packages/brick_offline_first/test/offline_first/helpers/horse_adapter.dart b/packages/brick_offline_first/test/offline_first/helpers/horse_adapter.dart index b1613bff..cb5f7fc5 100644 --- a/packages/brick_offline_first/test/offline_first/helpers/horse_adapter.dart +++ b/packages/brick_offline_first/test/offline_first/helpers/horse_adapter.dart @@ -72,15 +72,11 @@ class HorseAdapter extends OfflineFirstWithTestAdapter { @override final Map fieldsToSqliteColumns = { 'primaryKey': const RuntimeSqliteColumnDefinition( - association: false, columnName: '_brick_id', - iterable: false, type: int, ), 'name': const RuntimeSqliteColumnDefinition( - association: false, columnName: 'name', - iterable: false, type: String, ), 'mounties': const RuntimeSqliteColumnDefinition( @@ -96,7 +92,11 @@ class HorseAdapter extends OfflineFirstWithTestAdapter { @override final String tableName = 'Horse'; @override - Future afterSave(instance, {required provider, repository}) async { + Future afterSave( + Horse instance, { + required SqliteProvider provider, + ModelRepository? repository, + }) async { if (instance.primaryKey != null) { await Future.wait( instance.mounties.map((s) async { @@ -113,28 +113,28 @@ class HorseAdapter extends OfflineFirstWithTestAdapter { @override Future fromTest( Map input, { - required provider, + required TestProvider provider, covariant OfflineFirstWithTestRepository? repository, }) async => await _$HorseFromTest(input, provider: provider, repository: repository); @override Future> toTest( Horse input, { - required provider, + required TestProvider provider, covariant OfflineFirstWithTestRepository? repository, }) async => await _$HorseToTest(input, provider: provider, repository: repository); @override Future fromSqlite( Map input, { - required provider, + required SqliteProvider provider, covariant OfflineFirstWithTestRepository? repository, }) async => await _$HorseFromSqlite(input, provider: provider, repository: repository); @override Future> toSqlite( Horse input, { - required provider, + required SqliteProvider provider, covariant OfflineFirstWithTestRepository? repository, }) async => await _$HorseToSqlite(input, provider: provider, repository: repository); diff --git a/packages/brick_offline_first/test/offline_first/helpers/mounty_adapter.dart b/packages/brick_offline_first/test/offline_first/helpers/mounty_adapter.dart index d598d460..fba30032 100644 --- a/packages/brick_offline_first/test/offline_first/helpers/mounty_adapter.dart +++ b/packages/brick_offline_first/test/offline_first/helpers/mounty_adapter.dart @@ -40,15 +40,11 @@ class MountyAdapter extends OfflineFirstWithTestAdapter { @override final Map fieldsToSqliteColumns = { 'primaryKey': const RuntimeSqliteColumnDefinition( - association: false, columnName: '_brick_id', - iterable: false, type: int, ), 'name': const RuntimeSqliteColumnDefinition( - association: false, columnName: 'name', - iterable: false, type: String, ), }; @@ -61,28 +57,28 @@ class MountyAdapter extends OfflineFirstWithTestAdapter { @override Future fromTest( Map input, { - required provider, + required TestProvider provider, covariant OfflineFirstWithTestRepository? repository, }) async => await _$MountyFromTest(input, provider: provider, repository: repository); @override Future> toTest( Mounty input, { - required provider, + required TestProvider provider, covariant OfflineFirstWithTestRepository? repository, }) async => await _$MountyToTest(input, provider: provider, repository: repository); @override Future fromSqlite( Map input, { - required provider, + required SqliteProvider provider, covariant OfflineFirstWithTestRepository? repository, }) async => await _$MountyFromSqlite(input, provider: provider, repository: repository); @override Future> toSqlite( Mounty input, { - required provider, + required SqliteProvider provider, covariant OfflineFirstWithTestRepository? repository, }) async => await _$MountyToSqlite(input, provider: provider, repository: repository); diff --git a/packages/brick_offline_first/test/offline_first/helpers/test_domain.dart b/packages/brick_offline_first/test/offline_first/helpers/test_domain.dart index b078d7f4..75e3989e 100644 --- a/packages/brick_offline_first/test/offline_first/helpers/test_domain.dart +++ b/packages/brick_offline_first/test/offline_first/helpers/test_domain.dart @@ -1,3 +1,5 @@ +// ignore_for_file: prefer_mixin + import 'dart:io'; import 'package:brick_core/core.dart'; @@ -9,7 +11,7 @@ import 'package:brick_sqlite/memory_cache_provider.dart'; import '__mocks__.dart'; class TestProvider extends Provider { - var methodsCalled = []; + List methodsCalled = []; @override final TestModelDictionary modelDictionary; @@ -72,6 +74,7 @@ abstract class TestAdapter implements Adapter /// Associates app models with their [TestAdapter] class TestModelDictionary extends ModelDictionary> { + // ignore: use_super_parameters const TestModelDictionary(Map> mappings) : super(mappings); } diff --git a/packages/brick_offline_first/test/offline_first/offline_first_repository_test.dart b/packages/brick_offline_first/test/offline_first/offline_first_repository_test.dart index ddb9a183..ddc24358 100644 --- a/packages/brick_offline_first/test/offline_first/offline_first_repository_test.dart +++ b/packages/brick_offline_first/test/offline_first/offline_first_repository_test.dart @@ -26,7 +26,7 @@ void main() { test('#applyPolicyToQuery', () async { const policy = OfflineFirstGetPolicy.localOnly; - final query = TestRepository().applyPolicyToQuery(Query(), get: policy); + final query = TestRepository().applyPolicyToQuery(const Query(), get: policy); expect(query?.providerArgs, {'policy': policy.index}); }); diff --git a/packages/brick_offline_first_build/lib/src/offline_first_checker.dart b/packages/brick_offline_first_build/lib/src/offline_first_checker.dart index 3cc9d464..a9250d53 100644 --- a/packages/brick_offline_first_build/lib/src/offline_first_checker.dart +++ b/packages/brick_offline_first_build/lib/src/offline_first_checker.dart @@ -4,7 +4,9 @@ import 'package:source_gen/source_gen.dart' show TypeChecker; const _serdesClassChecker = TypeChecker.fromRuntime(OfflineFirstSerdes); +/// class OfflineFirstChecker extends SharedChecker { + /// OfflineFirstChecker(super.targetType); @override diff --git a/packages/brick_offline_first_build/lib/src/offline_first_fields.dart b/packages/brick_offline_first_build/lib/src/offline_first_fields.dart index 65d63116..adbb5c6b 100644 --- a/packages/brick_offline_first_build/lib/src/offline_first_fields.dart +++ b/packages/brick_offline_first_build/lib/src/offline_first_fields.dart @@ -7,10 +7,10 @@ class _OfflineFirstSerdesFinder extends AnnotationFinder { _OfflineFirstSerdesFinder(); @override - OfflineFirst from(element) { + OfflineFirst from(FieldElement element) { final obj = objectForField(element); - if (obj == null) return const OfflineFirst(); + if (obj == null) return OfflineFirst.defaults; final where = obj .getField('where') @@ -30,5 +30,6 @@ class OfflineFirstFields extends FieldsForClass { @override final finder = _OfflineFirstSerdesFinder(); + /// Discover all fields with `@OfflineFirst` OfflineFirstFields(ClassElement element) : super(element: element); } diff --git a/packages/brick_offline_first_build/lib/src/offline_first_generator.dart b/packages/brick_offline_first_build/lib/src/offline_first_generator.dart index 749c42ae..6216a6af 100644 --- a/packages/brick_offline_first_build/lib/src/offline_first_generator.dart +++ b/packages/brick_offline_first_build/lib/src/offline_first_generator.dart @@ -13,6 +13,7 @@ abstract class OfflineFirstGenerator<_ClassAnnotation> @override final String superAdapterName; + /// Output serializing code for all models with the @[_ClassAnnotation] annotation const OfflineFirstGenerator({ String? superAdapterName, String? repositoryName, diff --git a/packages/brick_offline_first_build/lib/src/offline_first_json_generators.dart b/packages/brick_offline_first_build/lib/src/offline_first_json_generators.dart index ae7684ee..50156faa 100644 --- a/packages/brick_offline_first_build/lib/src/offline_first_json_generators.dart +++ b/packages/brick_offline_first_build/lib/src/offline_first_json_generators.dart @@ -1,4 +1,6 @@ +import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/nullability_suffix.dart'; +import 'package:analyzer/dart/element/type.dart'; import 'package:brick_build/generators.dart'; import 'package:brick_core/core.dart'; import 'package:brick_core/field_serializable.dart'; @@ -11,10 +13,11 @@ import 'package:brick_offline_first_build/brick_offline_first_build.dart'; /// (e.g. `class OfflineFirstRestSerialize extends RestSerialize with OfflineFirstJsonSerialize`) mixin OfflineFirstJsonSerialize on JsonSerialize { + /// OfflineFirstFields get offlineFirstFields; @override - OfflineFirstChecker checkerForType(type) => OfflineFirstChecker(type); + OfflineFirstChecker checkerForType(DartType type) => OfflineFirstChecker(type); @override List get instanceFieldsAndMethods { @@ -49,7 +52,12 @@ mixin OfflineFirstJsonSerialize checker, { + required bool wrappedInFuture, + required Annotation fieldAnnotation, + }) { final offlineFirstAnnotation = offlineFirstFields.annotationForField(field); if (offlineFirstAnnotation.where != null && offlineFirstAnnotation.where!.length > 1) { @@ -122,13 +130,19 @@ mixin OfflineFirstJsonSerialize on JsonDeserialize { + /// OfflineFirstFields get offlineFirstFields; @override - OfflineFirstChecker checkerForType(type) => OfflineFirstChecker(type); + OfflineFirstChecker checkerForType(DartType type) => OfflineFirstChecker(type); @override - String? coderForField(field, checker, {required wrappedInFuture, required fieldAnnotation}) { + String? coderForField( + FieldElement field, + SharedChecker checker, { + required bool wrappedInFuture, + required Annotation fieldAnnotation, + }) { final offlineFirstAnnotation = offlineFirstFields.annotationForField(field); final fieldValue = serdesValueForField(field, fieldAnnotation.name!, checker: checker); final defaultValue = SerdesGenerator.defaultValueSuffix(fieldAnnotation); @@ -198,8 +212,7 @@ mixin OfflineFirstJsonDeserialize ${SharedChecker.withoutNullability(checker.argType)}.$constructorName(c as $serializableType))$castIterable$defaultValue'; } diff --git a/packages/brick_offline_first_build/lib/src/offline_first_model_dictionary_generator.dart b/packages/brick_offline_first_build/lib/src/offline_first_model_dictionary_generator.dart index d3a8d12a..fba224c6 100644 --- a/packages/brick_offline_first_build/lib/src/offline_first_model_dictionary_generator.dart +++ b/packages/brick_offline_first_build/lib/src/offline_first_model_dictionary_generator.dart @@ -1,5 +1,6 @@ import 'package:brick_build/generators.dart' show ModelDictionaryGenerator; +/// class OfflineFirstModelDictionaryGenerator extends ModelDictionaryGenerator { /// The capitalized domain, e.g. `Rest`. final String remoteProviderName; diff --git a/packages/brick_offline_first_build/lib/src/offline_first_sqlite_builders.dart b/packages/brick_offline_first_build/lib/src/offline_first_sqlite_builders.dart index 3d90cc04..d5ad3ff1 100644 --- a/packages/brick_offline_first_build/lib/src/offline_first_sqlite_builders.dart +++ b/packages/brick_offline_first_build/lib/src/offline_first_sqlite_builders.dart @@ -1,16 +1,19 @@ +import 'package:analyzer/dart/element/type.dart'; import 'package:brick_offline_first_build/src/offline_first_checker.dart'; import 'package:brick_sqlite/db.dart'; +import 'package:brick_sqlite/src/annotations/sqlite.dart'; import 'package:brick_sqlite_generators/generators.dart'; import 'package:meta/meta.dart'; +/// @visibleForTesting @protected class OfflineFirstSchemaGenerator extends SqliteSchemaGenerator { @override - OfflineFirstChecker checkerForType(type) => OfflineFirstChecker(type); + OfflineFirstChecker checkerForType(DartType type) => OfflineFirstChecker(type); @override - SchemaColumn? schemaColumn(column, {required covariant OfflineFirstChecker checker}) { + SchemaColumn? schemaColumn(Sqlite column, {required covariant OfflineFirstChecker checker}) { if (checker.hasSerdes) { final sqliteSerializerType = checker.superClassTypeArgs[1]; final sqliteChecker = checkerForType(sqliteSerializerType); diff --git a/packages/brick_offline_first_build/lib/src/offline_first_sqlite_generators.dart b/packages/brick_offline_first_build/lib/src/offline_first_sqlite_generators.dart index a3b7528c..f493ca5c 100644 --- a/packages/brick_offline_first_build/lib/src/offline_first_sqlite_generators.dart +++ b/packages/brick_offline_first_build/lib/src/offline_first_sqlite_generators.dart @@ -1,10 +1,15 @@ import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/type.dart'; import 'package:brick_build/generators.dart'; +import 'package:brick_core/src/model.dart'; import 'package:brick_offline_first_build/src/offline_first_checker.dart'; +import 'package:brick_sqlite/src/annotations/sqlite.dart'; import 'package:brick_sqlite_generators/generators.dart'; import 'package:brick_sqlite_generators/sqlite_model_serdes_generator.dart'; +/// class OfflineFirstSqliteSerialize extends SqliteSerialize { + /// OfflineFirstSqliteSerialize( super.element, super.fields, { @@ -12,10 +17,15 @@ class OfflineFirstSqliteSerialize extends SqliteSerialize { }); @override - OfflineFirstChecker checkerForType(type) => OfflineFirstChecker(type); + OfflineFirstChecker checkerForType(DartType type) => OfflineFirstChecker(type); @override - String? coderForField(field, checker, {required wrappedInFuture, required fieldAnnotation}) { + String? coderForField( + FieldElement field, + SharedChecker checker, { + required bool wrappedInFuture, + required Sqlite fieldAnnotation, + }) { final fieldValue = serdesValueForField(field, fieldAnnotation.name!, checker: checker); if (checker.isIterable) { @@ -52,7 +62,7 @@ class OfflineFirstSqliteSerialize extends SqliteSerialize { } @override - String uniqueValueForField(fieldName, {required checker}) { + String uniqueValueForField(String? fieldName, {required SharedChecker checker}) { if ((checker as OfflineFirstChecker).hasSerdes) { return '$fieldName.toSqlite()'; } @@ -61,7 +71,9 @@ class OfflineFirstSqliteSerialize extends SqliteSerialize { } } +/// class OfflineFirstSqliteDeserialize extends SqliteDeserialize { + /// OfflineFirstSqliteDeserialize( super.element, super.fields, { @@ -69,10 +81,15 @@ class OfflineFirstSqliteDeserialize extends SqliteDeserialize { }); @override - OfflineFirstChecker checkerForType(type) => OfflineFirstChecker(type); + OfflineFirstChecker checkerForType(DartType type) => OfflineFirstChecker(type); @override - String? coderForField(field, checker, {required wrappedInFuture, required fieldAnnotation}) { + String? coderForField( + FieldElement field, + SharedChecker checker, { + required bool wrappedInFuture, + required Sqlite fieldAnnotation, + }) { final fieldValue = serdesValueForField(field, fieldAnnotation.name!, checker: checker); // Iterable @@ -91,8 +108,7 @@ class OfflineFirstSqliteDeserialize extends SqliteDeserialize { if (argTypeChecker.hasSerdes) { final doesHaveConstructor = hasConstructor(checker.argType); if (doesHaveConstructor) { - final serializableType = - argTypeChecker.superClassTypeArgs.last.getDisplayString(withNullability: true); + final serializableType = argTypeChecker.superClassTypeArgs.last.getDisplayString(); return ''' jsonDecode($fieldValue).map( (c) => $argType.$constructorName(c as $serializableType) @@ -106,8 +122,7 @@ class OfflineFirstSqliteDeserialize extends SqliteDeserialize { if ((checker as OfflineFirstChecker).hasSerdes) { final doesHaveConstructor = hasConstructor(field.type); if (doesHaveConstructor) { - final serializableType = - checker.superClassTypeArgs.last.getDisplayString(withNullability: true); + final serializableType = checker.superClassTypeArgs.last.getDisplayString(); return '${SharedChecker.withoutNullability(field.type)}.$constructorName($fieldValue as $serializableType)'; } } @@ -121,7 +136,9 @@ class OfflineFirstSqliteDeserialize extends SqliteDeserialize { } } +/// class OfflineFirstSqliteModelSerdesGenerator extends SqliteModelSerdesGenerator { + /// OfflineFirstSqliteModelSerdesGenerator( super.element, super.reader, { diff --git a/packages/brick_offline_first_build/pubspec.yaml b/packages/brick_offline_first_build/pubspec.yaml index dfbe4e40..66a0a1ad 100644 --- a/packages/brick_offline_first_build/pubspec.yaml +++ b/packages/brick_offline_first_build/pubspec.yaml @@ -29,10 +29,10 @@ dev_dependencies: path: ../brick_build_test brick_offline_first_with_rest: path: ../brick_offline_first_with_rest - brick_rest: any + brick_rest: brick_rest_generators: path: ../brick_rest_generators - build_verify: ^2.0.0 - source_gen_test: ^1.0.0 - test: ^1.20.1 - lints: ^2.0.1 + build_verify: + lints: + source_gen_test: + test: diff --git a/packages/brick_offline_first_build/test/__helpers__.dart b/packages/brick_offline_first_build/test/__helpers__.dart index 32ec958f..b770890f 100644 --- a/packages/brick_offline_first_build/test/__helpers__.dart +++ b/packages/brick_offline_first_build/test/__helpers__.dart @@ -9,8 +9,8 @@ import 'package:brick_rest_generators/rest_model_serdes_generator.dart'; import 'package:source_gen/source_gen.dart'; import 'package:test/test.dart'; -final _generator = OfflineFirstWithTestGenerator(); -final folder = 'offline_first_generator'; +const _generator = OfflineFirstWithTestGenerator(); +const folder = 'offline_first_generator'; final generateReader = generateLibraryForFolder(folder); Future generateExpectation( @@ -100,9 +100,6 @@ class OfflineFirstWithTestGenerator extends OfflineFirstGenerator[]; - generators.addAll(rest.generators); - generators.addAll(sqlite.generators); - return generators; + return [...rest.generators, ...sqlite.generators]; } } diff --git a/packages/brick_offline_first_build/test/offline_first_generator/test_constructor_arguments.dart b/packages/brick_offline_first_build/test/offline_first_generator/test_constructor_arguments.dart index e04c12c3..eeb7daf2 100644 --- a/packages/brick_offline_first_build/test/offline_first_generator/test_constructor_arguments.dart +++ b/packages/brick_offline_first_build/test/offline_first_generator/test_constructor_arguments.dart @@ -4,7 +4,7 @@ import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart @ConnectOfflineFirstWithRest() class OfflineFirstGeneratorArguments extends OfflineFirstModel {} -final repositoryNameAdapterExpectation = r''' +const repositoryNameAdapterExpectation = r''' // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; @@ -86,7 +86,7 @@ class OfflineFirstGeneratorArgumentsAdapter } '''; -final superAdapterNameAdapterExpectation = r''' +const superAdapterNameAdapterExpectation = r''' // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_offline_first_build/test/offline_first_generator/test_custom_offline_first_serdes.dart b/packages/brick_offline_first_build/test/offline_first_generator/test_custom_offline_first_serdes.dart index cf79418c..337435a4 100644 --- a/packages/brick_offline_first_build/test/offline_first_generator/test_custom_offline_first_serdes.dart +++ b/packages/brick_offline_first_build/test/offline_first_generator/test_custom_offline_first_serdes.dart @@ -1,7 +1,7 @@ import 'package:brick_offline_first/brick_offline_first.dart' show OfflineFirstSerdes; import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart'; -final output = r''' +const output = r''' Future _$CustomOfflineFirstSerdesFromTest( Map data, {required TestProvider provider, diff --git a/packages/brick_offline_first_build/test/offline_first_generator/test_default_value.dart b/packages/brick_offline_first_build/test/offline_first_generator/test_default_value.dart index 69a7e5ad..21f6674b 100644 --- a/packages/brick_offline_first_build/test/offline_first_generator/test_default_value.dart +++ b/packages/brick_offline_first_build/test/offline_first_generator/test_default_value.dart @@ -2,7 +2,7 @@ import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart import 'package:brick_rest/brick_rest.dart' show Rest; import 'package:brick_sqlite/brick_sqlite.dart'; -final output = r''' +const output = r''' Future _$DefaultValueFromTest(Map data, {required TestProvider provider, OfflineFirstRepository? repository}) async { diff --git a/packages/brick_offline_first_build/test/offline_first_generator/test_enum_factory_serialize.dart b/packages/brick_offline_first_build/test/offline_first_generator/test_enum_factory_serialize.dart index 34b699b1..df09f6d4 100644 --- a/packages/brick_offline_first_build/test/offline_first_generator/test_enum_factory_serialize.dart +++ b/packages/brick_offline_first_build/test/offline_first_generator/test_enum_factory_serialize.dart @@ -1,6 +1,6 @@ import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart'; -final output = r''' +const output = r''' Future _$EnumFactorySerializeFromTest( Map data, {required TestProvider provider, diff --git a/packages/brick_offline_first_build/test/offline_first_generator/test_futures.dart b/packages/brick_offline_first_build/test/offline_first_generator/test_futures.dart index 6d931c35..2d6a41cb 100644 --- a/packages/brick_offline_first_build/test/offline_first_generator/test_futures.dart +++ b/packages/brick_offline_first_build/test/offline_first_generator/test_futures.dart @@ -1,7 +1,7 @@ import 'package:brick_offline_first/brick_offline_first.dart' show OfflineFirstModel; import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart'; -final output = r''' +const output = r''' // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_offline_first_build/test/offline_first_generator/test_ignore_field.dart b/packages/brick_offline_first_build/test/offline_first_generator/test_ignore_field.dart index 25d1cf5b..5796be53 100644 --- a/packages/brick_offline_first_build/test/offline_first_generator/test_ignore_field.dart +++ b/packages/brick_offline_first_build/test/offline_first_generator/test_ignore_field.dart @@ -2,7 +2,7 @@ import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart import 'package:brick_rest/brick_rest.dart'; import 'package:brick_sqlite/brick_sqlite.dart'; -final output = r''' +const output = r''' Future _$IgnoreFieldFromTest(Map data, {required TestProvider provider, OfflineFirstRepository? repository}) async { diff --git a/packages/brick_offline_first_build/test/offline_first_generator/test_no_final_no_const.dart b/packages/brick_offline_first_build/test/offline_first_generator/test_no_final_no_const.dart index 530b9e50..50582e32 100644 --- a/packages/brick_offline_first_build/test/offline_first_generator/test_no_final_no_const.dart +++ b/packages/brick_offline_first_build/test/offline_first_generator/test_no_final_no_const.dart @@ -1,6 +1,6 @@ import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart'; -final output = r''' +const output = r''' Future _$NoFinalNoConstFromTest(Map data, {required TestProvider provider, OfflineFirstRepository? repository}) async { @@ -42,9 +42,9 @@ Future> _$NoFinalNoConstToSqlite(NoFinalNoConst instance, @ConnectOfflineFirstWithRest() class NoFinalNoConst { int declaredVar = 5; - var regularVar = true; + bool regularVar = true; int get computedField => _privateVarField; int _privateVarField = 0; - set computedField(value) => _privateVarField = value; + set computedField(dynamic value) => _privateVarField = value; } diff --git a/packages/brick_offline_first_build/test/offline_first_generator/test_nullable_field.dart b/packages/brick_offline_first_build/test/offline_first_generator/test_nullable_field.dart index bffa712e..4dac8108 100644 --- a/packages/brick_offline_first_build/test/offline_first_generator/test_nullable_field.dart +++ b/packages/brick_offline_first_build/test/offline_first_generator/test_nullable_field.dart @@ -2,7 +2,7 @@ import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart import 'package:brick_rest/brick_rest.dart'; import 'package:brick_sqlite/brick_sqlite.dart'; -final output = r''' +const output = r''' Future _$NullableFieldFromTest(Map data, {required TestProvider provider, OfflineFirstRepository? repository}) async { @@ -66,7 +66,7 @@ Future> _$NullableFieldToSqlite(NullableField instance, '''; @ConnectOfflineFirstWithRest( - restConfig: RestSerializable(nullable: false), + restConfig: RestSerializable.defaults, sqliteConfig: SqliteSerializable(nullable: false), ) class NullableField { diff --git a/packages/brick_offline_first_build/test/offline_first_generator/test_offline_first_apply_to_remote_deserialization.dart b/packages/brick_offline_first_build/test/offline_first_generator/test_offline_first_apply_to_remote_deserialization.dart index 43a1e278..02749d52 100644 --- a/packages/brick_offline_first_build/test/offline_first_generator/test_offline_first_apply_to_remote_deserialization.dart +++ b/packages/brick_offline_first_build/test/offline_first_generator/test_offline_first_apply_to_remote_deserialization.dart @@ -2,7 +2,7 @@ import 'package:brick_offline_first/brick_offline_first.dart'; import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart'; import 'package:brick_rest/brick_rest.dart'; -final output = r''' +const output = r''' // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_offline_first_build/test/offline_first_generator/test_offline_first_serdes_with_type_argument.dart b/packages/brick_offline_first_build/test/offline_first_generator/test_offline_first_serdes_with_type_argument.dart index ffa499a7..2429b74a 100644 --- a/packages/brick_offline_first_build/test/offline_first_generator/test_offline_first_serdes_with_type_argument.dart +++ b/packages/brick_offline_first_build/test/offline_first_generator/test_offline_first_serdes_with_type_argument.dart @@ -1,7 +1,7 @@ import 'package:brick_offline_first/brick_offline_first.dart'; import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart'; -final output = r""" +const output = r""" // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_offline_first_build/test/offline_first_generator/test_offline_first_where.dart b/packages/brick_offline_first_build/test/offline_first_generator/test_offline_first_where.dart index 2bfc2c22..e9d5b72d 100644 --- a/packages/brick_offline_first_build/test/offline_first_generator/test_offline_first_where.dart +++ b/packages/brick_offline_first_build/test/offline_first_generator/test_offline_first_where.dart @@ -2,7 +2,7 @@ import 'package:brick_offline_first/brick_offline_first.dart'; import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart'; import 'package:brick_rest/brick_rest.dart'; -final output = r''' +const output = r''' // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_offline_first_build/test/offline_first_generator/test_one_to_many_association.dart b/packages/brick_offline_first_build/test/offline_first_generator/test_one_to_many_association.dart index b2cad810..f7edbf99 100644 --- a/packages/brick_offline_first_build/test/offline_first_generator/test_one_to_many_association.dart +++ b/packages/brick_offline_first_build/test/offline_first_generator/test_one_to_many_association.dart @@ -22,7 +22,7 @@ class SqliteAssoc extends OfflineFirstModel { int key = -1; } -final output = r''' +const output = r''' // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_offline_first_build/test/offline_first_generator/test_one_to_one_association.dart b/packages/brick_offline_first_build/test/offline_first_generator/test_one_to_one_association.dart index 8acce3c2..f92f437d 100644 --- a/packages/brick_offline_first_build/test/offline_first_generator/test_one_to_one_association.dart +++ b/packages/brick_offline_first_build/test/offline_first_generator/test_one_to_one_association.dart @@ -10,7 +10,7 @@ class SqliteAssoc extends OfflineFirstModel { int key = -1; } -final output = r''' +const output = r''' Future _$SqliteAssocFromTest(Map data, {required TestProvider provider, OfflineFirstRepository? repository}) async { diff --git a/packages/brick_offline_first_build/test/offline_first_generator/test_only_static_members.dart b/packages/brick_offline_first_build/test/offline_first_generator/test_only_static_members.dart index 736a37e9..240d6e8f 100644 --- a/packages/brick_offline_first_build/test/offline_first_generator/test_only_static_members.dart +++ b/packages/brick_offline_first_build/test/offline_first_generator/test_only_static_members.dart @@ -1,6 +1,8 @@ +// ignore_for_file: avoid_classes_with_only_static_members + import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart'; -final output = r''' +const output = r''' Future _$OnlyStaticMembersFromTest(Map data, {required TestProvider provider, OfflineFirstRepository? repository}) async { @@ -33,7 +35,7 @@ Future> _$OnlyStaticMembersToSqlite( class OnlyStaticMembers { // To ensure static members are not considered for serialization. static const answer = 42; - static final reason = 42; + static const reason = 42; static int get understand => 42; } diff --git a/packages/brick_offline_first_build/test/offline_first_generator/test_primitive_fields.dart b/packages/brick_offline_first_build/test/offline_first_generator/test_primitive_fields.dart index 0fe7667e..402fe712 100644 --- a/packages/brick_offline_first_build/test/offline_first_generator/test_primitive_fields.dart +++ b/packages/brick_offline_first_build/test/offline_first_generator/test_primitive_fields.dart @@ -2,7 +2,7 @@ import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart enum Casing { snake, camel } -final output = r''' +const output = r''' Future _$PrimitiveFieldsFromTest(Map data, {required TestProvider provider, OfflineFirstRepository? repository}) async { diff --git a/packages/brick_offline_first_build/test/offline_first_generator/test_unique_offline_first_serdes.dart b/packages/brick_offline_first_build/test/offline_first_generator/test_unique_offline_first_serdes.dart index 1631144c..8ce7def5 100644 --- a/packages/brick_offline_first_build/test/offline_first_generator/test_unique_offline_first_serdes.dart +++ b/packages/brick_offline_first_build/test/offline_first_generator/test_unique_offline_first_serdes.dart @@ -2,7 +2,7 @@ import 'package:brick_offline_first/brick_offline_first.dart' show OfflineFirstS import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart'; import 'package:brick_sqlite/brick_sqlite.dart'; -final output = r""" +const output = r""" // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_offline_first_build/test/offline_first_generator/test_unrelated_association.dart b/packages/brick_offline_first_build/test/offline_first_generator/test_unrelated_association.dart index c96ee07e..b336f507 100644 --- a/packages/brick_offline_first_build/test/offline_first_generator/test_unrelated_association.dart +++ b/packages/brick_offline_first_build/test/offline_first_generator/test_unrelated_association.dart @@ -2,7 +2,7 @@ import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart class NonSqliteAssoc {} -final output = r''' +const output = r''' Future _$UnreleatedAssociationFromTest( Map data, {required TestProvider provider, diff --git a/packages/brick_offline_first_build/test/offline_first_generator_test.dart b/packages/brick_offline_first_build/test/offline_first_generator_test.dart index be42eca6..c0a626c7 100644 --- a/packages/brick_offline_first_build/test/offline_first_generator_test.dart +++ b/packages/brick_offline_first_build/test/offline_first_generator_test.dart @@ -27,7 +27,7 @@ void main() { group('OfflineFirstJsonGenerators', () { group('constructor arguments', () { test('repositoryName', () async { - final generator = OfflineFirstWithTestGenerator(repositoryName: 'MyCustom'); + const generator = OfflineFirstWithTestGenerator(repositoryName: 'MyCustom'); await generateAdapterExpectation( 'constructor_arguments', constructor_arguments.repositoryNameAdapterExpectation, @@ -36,7 +36,7 @@ void main() { }); test('superAdapterName', () async { - final generator = OfflineFirstWithTestGenerator(superAdapterName: 'SuperDuper'); + const generator = OfflineFirstWithTestGenerator(superAdapterName: 'SuperDuper'); await generateAdapterExpectation( 'constructor_arguments', constructor_arguments.superAdapterNameAdapterExpectation, diff --git a/packages/brick_offline_first_build/test/offline_first_model_dictionary_generator_test.dart b/packages/brick_offline_first_build/test/offline_first_model_dictionary_generator_test.dart index 3a6b6612..4cf56ba8 100644 --- a/packages/brick_offline_first_build/test/offline_first_model_dictionary_generator_test.dart +++ b/packages/brick_offline_first_build/test/offline_first_model_dictionary_generator_test.dart @@ -5,9 +5,9 @@ void main() { group('OfflineFirstModelDictionaryGenerator', () { group('#generate', () { test('basic', () { - final generated = OfflineFirstModelDictionaryGenerator('Rest') + final generated = const OfflineFirstModelDictionaryGenerator('Rest') .generate({'Person': 'person.dart', 'User': 'path/user.dart'}); - final output = ''' + const output = ''' // GENERATED CODE DO NOT EDIT // ignore: unused_import import 'dart:convert'; diff --git a/packages/brick_offline_first_build/test/offline_first_schema_generator/test_with_association.dart b/packages/brick_offline_first_build/test/offline_first_schema_generator/test_with_association.dart index 3c3fa036..3050dc0b 100644 --- a/packages/brick_offline_first_build/test/offline_first_schema_generator/test_with_association.dart +++ b/packages/brick_offline_first_build/test/offline_first_schema_generator/test_with_association.dart @@ -7,7 +7,7 @@ class SqliteAssoc extends OfflineFirstWithRestModel { final int key = -1; } -final output = ''' +const output = ''' // GENERATED CODE DO NOT EDIT // This file should be version controlled import 'package:brick_sqlite/db.dart'; diff --git a/packages/brick_offline_first_build/test/offline_first_schema_generator/test_with_associations.dart b/packages/brick_offline_first_build/test/offline_first_schema_generator/test_with_associations.dart index d02ae279..43d7c11e 100644 --- a/packages/brick_offline_first_build/test/offline_first_schema_generator/test_with_associations.dart +++ b/packages/brick_offline_first_build/test/offline_first_schema_generator/test_with_associations.dart @@ -7,7 +7,7 @@ class SqliteAssoc extends OfflineFirstWithRestModel { final int key = -1; } -final output = ''' +const output = ''' // GENERATED CODE DO NOT EDIT // This file should be version controlled import 'package:brick_sqlite/db.dart'; diff --git a/packages/brick_offline_first_build/test/offline_first_schema_generator/test_with_serdes.dart b/packages/brick_offline_first_build/test/offline_first_schema_generator/test_with_serdes.dart index f1bd6039..ae7f472a 100644 --- a/packages/brick_offline_first_build/test/offline_first_schema_generator/test_with_serdes.dart +++ b/packages/brick_offline_first_build/test/offline_first_schema_generator/test_with_serdes.dart @@ -60,7 +60,7 @@ class WithSerdes extends OfflineFirstWithRestModel { }); } -final output = ''' +const output = ''' // GENERATED CODE EDIT WITH CAUTION // THIS FILE **WILL NOT** BE REGENERATED // This file should be version controlled and can be manually edited. diff --git a/packages/brick_offline_first_build/test/offline_first_schema_generator_test.dart b/packages/brick_offline_first_build/test/offline_first_schema_generator_test.dart index 897232c8..f1bf0e5b 100644 --- a/packages/brick_offline_first_build/test/offline_first_schema_generator_test.dart +++ b/packages/brick_offline_first_build/test/offline_first_schema_generator_test.dart @@ -12,7 +12,7 @@ import 'offline_first_schema_generator/test_with_serdes.dart' as with_serdes; final generator = OfflineFirstSchemaGenerator(); final generateLibrary = generateLibraryForFolder('offline_first_schema_generator'); -final annotationChecker = TypeChecker.fromRuntime(ConnectOfflineFirstWithRest); +const annotationChecker = TypeChecker.fromRuntime(ConnectOfflineFirstWithRest); Future generateOutputForFile(String fileName) async { final reader = await generateLibrary(fileName); diff --git a/packages/brick_offline_first_with_graphql/lib/src/graphql_offline_queue_link.dart b/packages/brick_offline_first_with_graphql/lib/src/graphql_offline_queue_link.dart index f113e40e..1dae72d7 100644 --- a/packages/brick_offline_first_with_graphql/lib/src/graphql_offline_queue_link.dart +++ b/packages/brick_offline_first_with_graphql/lib/src/graphql_offline_queue_link.dart @@ -13,6 +13,7 @@ import 'package:logging/logging.dart'; class GraphqlOfflineQueueLink extends Link { final Logger _logger; + /// final GraphqlRequestSqliteCacheManager requestManager; /// A callback triggered when a request failed, but will be reattempted. @@ -21,6 +22,7 @@ class GraphqlOfflineQueueLink extends Link { /// A callback triggered when a request throws an exception during execution. final void Function(Request request, Object error)? onRequestException; + /// Stores all mutation requests in a SQLite database GraphqlOfflineQueueLink( this.requestManager, { this.onReattempt, diff --git a/packages/brick_offline_first_with_graphql/lib/src/graphql_offline_request_queue.dart b/packages/brick_offline_first_with_graphql/lib/src/graphql_offline_request_queue.dart index 07d9c5c2..5a208fdc 100644 --- a/packages/brick_offline_first_with_graphql/lib/src/graphql_offline_request_queue.dart +++ b/packages/brick_offline_first_with_graphql/lib/src/graphql_offline_request_queue.dart @@ -5,10 +5,12 @@ import 'package:brick_offline_first_with_graphql/brick_offline_first_with_graphq import 'package:gql_exec/gql_exec.dart'; import 'package:gql_link/gql_link.dart'; +/// GraphQL implementation of [OfflineRequestQueue] class GraphqlOfflineRequestQueue extends OfflineRequestQueue { /// The client responsible for resending requests final Link link; + /// GraphQL implementation of [OfflineRequestQueue] GraphqlOfflineRequestQueue({ required this.link, required GraphqlRequestSqliteCacheManager requestManager, diff --git a/packages/brick_offline_first_with_graphql/lib/src/graphql_request_sqlite_cache.dart b/packages/brick_offline_first_with_graphql/lib/src/graphql_request_sqlite_cache.dart index f1adf726..64f541bd 100644 --- a/packages/brick_offline_first_with_graphql/lib/src/graphql_request_sqlite_cache.dart +++ b/packages/brick_offline_first_with_graphql/lib/src/graphql_request_sqlite_cache.dart @@ -7,6 +7,7 @@ import 'package:gql_exec/gql_exec.dart'; /// Serialize and Deserialize a [Request] from SQLite. class GraphqlRequestSqliteCache extends RequestSqliteCache { + /// Serialize and Deserialize a [Request] from SQLite. GraphqlRequestSqliteCache(request) : super( attemptColumn: GRAPHQL_JOBS_ATTEMPTS_COLUMN, @@ -41,7 +42,7 @@ class GraphqlRequestSqliteCache extends RequestSqliteCache { } /// Builds request into a new SQLite-insertable row - /// Only available if [request] was initialized from [fromRequest] + /// Only available if [request] was initialized from [sqliteToRequest] /// /// This is a function to ensure `DateTime.now()` is invoked predictably. @override diff --git a/packages/brick_offline_first_with_graphql/lib/src/graphql_request_sqlite_cache_manager.dart b/packages/brick_offline_first_with_graphql/lib/src/graphql_request_sqlite_cache_manager.dart index 4f51f6be..e2fbdbc5 100644 --- a/packages/brick_offline_first_with_graphql/lib/src/graphql_request_sqlite_cache_manager.dart +++ b/packages/brick_offline_first_with_graphql/lib/src/graphql_request_sqlite_cache_manager.dart @@ -6,7 +6,9 @@ import 'package:brick_offline_first/offline_queue.dart'; import 'package:gql/language.dart' as lang; import 'package:gql_exec/gql_exec.dart'; +/// GraphQL implementation of [RequestSqliteCacheManager] class GraphqlRequestSqliteCacheManager extends RequestSqliteCacheManager { + /// GraphQL implementation of [RequestSqliteCacheManager] GraphqlRequestSqliteCacheManager( super.databaseName, { required super.databaseFactory, @@ -72,7 +74,7 @@ const GRAPHQL_JOBS_PRIMARY_KEY_COLUMN = 'id'; /// json-encoded String const GRAPHQL_JOBS_VARIABLES_COLUMN = 'variables'; -// String +/// String const GRAPHQL_JOBS_TABLE_NAME = 'GraphqlJobs'; /// int; millisecondsSinceEpoch diff --git a/packages/brick_offline_first_with_graphql/lib/src/models/offline_first_with_graphql_model.dart b/packages/brick_offline_first_with_graphql/lib/src/models/offline_first_with_graphql_model.dart index 06411709..002574f7 100644 --- a/packages/brick_offline_first_with_graphql/lib/src/models/offline_first_with_graphql_model.dart +++ b/packages/brick_offline_first_with_graphql/lib/src/models/offline_first_with_graphql_model.dart @@ -1,4 +1,6 @@ import 'package:brick_graphql/brick_graphql.dart' show GraphqlModel; import 'package:brick_offline_first/brick_offline_first.dart'; +/// GraphQL-enabled [OfflineFirstModel] +// ignore: prefer_mixin abstract class OfflineFirstWithGraphqlModel extends OfflineFirstModel with GraphqlModel {} diff --git a/packages/brick_offline_first_with_graphql/lib/src/offline_first_graphql_policy.dart b/packages/brick_offline_first_with_graphql/lib/src/offline_first_graphql_policy.dart index 383da2f6..973cdf43 100644 --- a/packages/brick_offline_first_with_graphql/lib/src/offline_first_graphql_policy.dart +++ b/packages/brick_offline_first_with_graphql/lib/src/offline_first_graphql_policy.dart @@ -1,22 +1,31 @@ import 'package:brick_offline_first/brick_offline_first.dart'; +import 'package:brick_offline_first_with_graphql/src/offline_first_with_graphql_repository.dart'; import 'package:gql_exec/gql_exec.dart'; +/// Converts an `OfflineFirstPolicy` to a context object for later use in the request manager. +/// The request manager may choose to ignore the policy if the request is not a mutation. class OfflineFirstGraphqlPolicy extends ContextEntry { + /// [OfflineFirstWithGraphqlRepository.delete] invocations final OfflineFirstDeletePolicy? delete; @override List get fieldsForEquality => [delete, get, upsert]; + /// [OfflineFirstWithGraphqlRepository.get] invocations final OfflineFirstGetPolicy? get; + /// [OfflineFirstWithGraphqlRepository.upsert] invocations final OfflineFirstUpsertPolicy? upsert; + /// Converts an `OfflineFirstPolicy` to a context object for later use in the request manager. + /// The request manager may choose to ignore the policy if the request is not a mutation. const OfflineFirstGraphqlPolicy({ this.delete, this.get, this.upsert, }); + /// Serialize Map toJson() => { if (delete != null) 'delete': delete?.index, if (get != null) 'get': get?.index, diff --git a/packages/brick_offline_first_with_graphql/lib/src/offline_first_with_graphql_adapter.dart b/packages/brick_offline_first_with_graphql/lib/src/offline_first_with_graphql_adapter.dart index fcc95682..2d30c3bc 100644 --- a/packages/brick_offline_first_with_graphql/lib/src/offline_first_with_graphql_adapter.dart +++ b/packages/brick_offline_first_with_graphql/lib/src/offline_first_with_graphql_adapter.dart @@ -1,11 +1,14 @@ -import 'package:brick_graphql/brick_graphql.dart' show GraphqlProvider, GraphqlAdapter; +import 'package:brick_graphql/brick_graphql.dart' show GraphqlAdapter, GraphqlProvider; import 'package:brick_offline_first/brick_offline_first.dart'; import 'package:brick_offline_first_with_graphql/src/models/offline_first_with_graphql_model.dart'; +import 'package:brick_sqlite/brick_sqlite.dart'; export 'package:brick_graphql/src/runtime_graphql_definition.dart'; /// This adapter fetches first from [SqliteProvider] then hydrates with [GraphqlProvider]. abstract class OfflineFirstWithGraphqlAdapter<_Model extends OfflineFirstWithGraphqlModel> + // ignore: prefer_mixin extends OfflineFirstAdapter<_Model> with GraphqlAdapter<_Model> { + /// This adapter fetches first from [SqliteProvider] then hydrates with [GraphqlProvider]. OfflineFirstWithGraphqlAdapter(); } diff --git a/packages/brick_offline_first_with_graphql/lib/src/offline_first_with_graphql_repository.dart b/packages/brick_offline_first_with_graphql/lib/src/offline_first_with_graphql_repository.dart index b3bd9e0a..36b2d164 100644 --- a/packages/brick_offline_first_with_graphql/lib/src/offline_first_with_graphql_repository.dart +++ b/packages/brick_offline_first_with_graphql/lib/src/offline_first_with_graphql_repository.dart @@ -22,9 +22,14 @@ abstract class OfflineFirstWithGraphqlRepository< // ignore: overridden_fields final GraphqlProvider remoteProvider; + /// @protected late final GraphqlOfflineRequestQueue offlineRequestQueue; + /// Ensures the [remoteProvider] is a [GraphqlProvider]. All requests to and + /// from the [remoteProvider] pass through a seperate SQLite queue. If the app + /// is unable to make contact with the [remoteProvider], the queue automatically retries in + /// sequence until it receives a response. OfflineFirstWithGraphqlRepository({ super.autoHydrate, required GraphqlProvider graphqlProvider, @@ -60,7 +65,7 @@ abstract class OfflineFirstWithGraphqlRepository< .map((key, value) => MapEntry(value.runtimeType, value)), ) : null; - final context = (queryContext ?? argContext ?? Context()).withEntry( + final context = (queryContext ?? argContext ?? const Context()).withEntry( OfflineFirstGraphqlPolicy( delete: delete, get: get, @@ -169,7 +174,7 @@ abstract class OfflineFirstWithGraphqlRepository< OfflineFirstGetPolicy policy = OfflineFirstGetPolicy.awaitRemoteWhenNoneExist, Query? query, }) { - query ??= Query(); + query ??= const Query(); if (subscriptions[TModel]?[query] != null) { return subscriptions[TModel]![query]!.stream as Stream>; } diff --git a/packages/brick_offline_first_with_graphql/pubspec.yaml b/packages/brick_offline_first_with_graphql/pubspec.yaml index d027fa3a..bbf5d0bb 100644 --- a/packages/brick_offline_first_with_graphql/pubspec.yaml +++ b/packages/brick_offline_first_with_graphql/pubspec.yaml @@ -23,7 +23,7 @@ dependencies: 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 + lints: + mockito: + sqflite_common_ffi: + test: diff --git a/packages/brick_offline_first_with_graphql/test/__helpers__.dart b/packages/brick_offline_first_with_graphql/test/__helpers__.dart index c7ec7b0a..d2815685 100644 --- a/packages/brick_offline_first_with_graphql/test/__helpers__.dart +++ b/packages/brick_offline_first_with_graphql/test/__helpers__.dart @@ -15,6 +15,7 @@ Link stubGraphqlLink( final link = MockLink(); if (wrapInTopLevelKeyAndArray) { + // ignore: parameter_assignments response = { 'result': [response], }; @@ -28,7 +29,6 @@ Link stubGraphqlLink( data: response, response: {'body': jsonEncode(response)}, errors: errors?.map((e) => GraphQLError(message: e)).toList().cast(), - context: const Context(), ), ]), ); diff --git a/packages/brick_offline_first_with_graphql/test/graphql_offline_request_queue_test.dart b/packages/brick_offline_first_with_graphql/test/graphql_offline_request_queue_test.dart index 1d871ade..36eca764 100644 --- a/packages/brick_offline_first_with_graphql/test/graphql_offline_request_queue_test.dart +++ b/packages/brick_offline_first_with_graphql/test/graphql_offline_request_queue_test.dart @@ -19,8 +19,7 @@ void main() { final queue = GraphqlOfflineRequestQueue( link: offlineClient, requestManager: requestManager, - ); - queue.start(); + )..start(); expect(queue.isRunning, isTrue); queue.stop(); }); @@ -29,8 +28,7 @@ void main() { final queue = GraphqlOfflineRequestQueue( link: offlineClient, requestManager: requestManager, - ); - queue.start(); + )..start(); expect(queue.isRunning, isTrue); queue.stop(); expect(queue.isRunning, isFalse); diff --git a/packages/brick_offline_first_with_graphql/test/graphql_offline_sqlite_cache_manager_test.dart b/packages/brick_offline_first_with_graphql/test/graphql_offline_sqlite_cache_manager_test.dart index d4cb92fe..55807b15 100644 --- a/packages/brick_offline_first_with_graphql/test/graphql_offline_sqlite_cache_manager_test.dart +++ b/packages/brick_offline_first_with_graphql/test/graphql_offline_sqlite_cache_manager_test.dart @@ -37,7 +37,7 @@ void main() { final requestManager = GraphqlRequestSqliteCacheManager( inMemoryDatabasePath, databaseFactory: databaseFactoryFfi, - processingInterval: const Duration(seconds: 0), + processingInterval: Duration.zero, ); setUpAll(() async { @@ -58,7 +58,7 @@ void main() { inMemoryDatabasePath, databaseFactory: databaseFactoryFfi, serialProcessing: false, - processingInterval: const Duration(seconds: 0), + processingInterval: Duration.zero, ); final client = GraphqlOfflineQueueLink(requestManager) .concat(stubGraphqlLink({}, errors: ['Unable to connect'])); @@ -100,7 +100,7 @@ void main() { final request = await requestManager.prepareNextRequestToProcess(); expect(request?.operation.operationName, 'UpsertPerson'); - final asCacheItem = GraphqlRequestSqliteCache(request!); + final asCacheItem = GraphqlRequestSqliteCache(request); await asCacheItem.insertOrUpdate(await requestManager.getDb()); // Do not retry request if the row is locked and serial processing is active final req = await requestManager.prepareNextRequestToProcess(); @@ -143,7 +143,7 @@ void main() { await asCacheItem.insertOrUpdate(await requestManager.getDb()); await asCacheItem.unlock(await requestManager.getDb()); - final requests = await requestManager.unprocessedRequests(onlyLocked: false); + final requests = await requestManager.unprocessedRequests(); expect(requests, hasLength(1)); final lockedRequests = await requestManager.unprocessedRequests(onlyLocked: true); @@ -184,7 +184,7 @@ void main() { ); expect(await requestManager.unprocessedRequests(onlyLocked: true), hasLength(1)); - expect(await requestManager.unprocessedRequests(onlyLocked: false), hasLength(1)); + expect(await requestManager.unprocessedRequests(), hasLength(1)); expect(await requestManager.prepareNextRequestToProcess(), isNull); diff --git a/packages/brick_offline_first_with_graphql/test/test_domain/__mocks__.dart b/packages/brick_offline_first_with_graphql/test/test_domain/__mocks__.dart index 6a207f88..ee8d689f 100644 --- a/packages/brick_offline_first_with_graphql/test/test_domain/__mocks__.dart +++ b/packages/brick_offline_first_with_graphql/test/test_domain/__mocks__.dart @@ -12,8 +12,8 @@ part 'horse_adapter.dart'; part 'mounty.dart'; part 'mounty_adapter.dart'; -/// The exact same as [DemoModel], except this class is tracked by the Memory Cache Provider -/// while [DemoModel] is not. +/// The exact same as [Mounty], except this class is tracked by the Memory Cache Provider +/// while [Mounty] is not. class MemoryDemoModel extends Mounty { MemoryDemoModel(String name) : super(name: name); } diff --git a/packages/brick_offline_first_with_graphql/test/test_domain/horse_adapter.dart b/packages/brick_offline_first_with_graphql/test/test_domain/horse_adapter.dart index 619536d5..31a127cc 100644 --- a/packages/brick_offline_first_with_graphql/test/test_domain/horse_adapter.dart +++ b/packages/brick_offline_first_with_graphql/test/test_domain/horse_adapter.dart @@ -69,7 +69,7 @@ Future> _$HorseToSqlite( class HorseOperationTransformer extends GraphqlQueryOperationTransformer { @override - GraphqlOperation get delete => GraphqlOperation( + GraphqlOperation get delete => const GraphqlOperation( document: r'''mutation DeleteDemoModel($input: DemoModelInput!) { deleteDemoModel(input: $input) {} }''', @@ -104,7 +104,7 @@ class HorseOperationTransformer extends GraphqlQueryOperationTransformer { } @override - GraphqlOperation get upsert => GraphqlOperation( + GraphqlOperation get upsert => const GraphqlOperation( document: r'''mutation UpsertDemoModels($input: DemoModelInput) { upsertDemoModel(input: $input) {} }''', @@ -123,15 +123,11 @@ class HorseAdapter extends OfflineFirstWithGraphqlAdapter { @override final Map fieldsToGraphqlRuntimeDefinition = { 'primaryKey': const RuntimeGraphqlDefinition( - association: false, documentNodeName: '_brick_id', - iterable: false, type: int, ), 'name': const RuntimeGraphqlDefinition( - association: false, documentNodeName: 'name', - iterable: false, type: String, ), 'mounties': const RuntimeGraphqlDefinition( @@ -145,15 +141,11 @@ class HorseAdapter extends OfflineFirstWithGraphqlAdapter { @override final Map fieldsToSqliteColumns = { 'primaryKey': const RuntimeSqliteColumnDefinition( - association: false, columnName: '_brick_id', - iterable: false, type: int, ), 'name': const RuntimeSqliteColumnDefinition( - association: false, columnName: 'name', - iterable: false, type: String, ), 'mounties': const RuntimeSqliteColumnDefinition( @@ -169,7 +161,11 @@ class HorseAdapter extends OfflineFirstWithGraphqlAdapter { @override final String tableName = 'Horse'; @override - Future afterSave(instance, {required provider, repository}) async { + Future afterSave( + Horse instance, { + required SqliteProvider provider, + ModelRepository? repository, + }) async { if (instance.primaryKey != null) { await Future.wait( instance.mounties.map((s) async { @@ -186,28 +182,28 @@ class HorseAdapter extends OfflineFirstWithGraphqlAdapter { @override Future fromGraphql( Map input, { - required provider, + required GraphqlProvider provider, covariant OfflineFirstWithGraphqlRepository? repository, }) async => await _$HorseFromGraphql(input, provider: provider, repository: repository); @override Future> toGraphql( Horse input, { - required provider, + required GraphqlProvider provider, covariant OfflineFirstWithGraphqlRepository? repository, }) async => await _$HorseToGraphql(input, provider: provider, repository: repository); @override Future fromSqlite( Map input, { - required provider, + required SqliteProvider provider, covariant OfflineFirstWithGraphqlRepository? repository, }) async => await _$HorseFromSqlite(input, provider: provider, repository: repository); @override Future> toSqlite( Horse input, { - required provider, + required SqliteProvider provider, covariant OfflineFirstWithGraphqlRepository? repository, }) async => await _$HorseToSqlite(input, provider: provider, repository: repository); diff --git a/packages/brick_offline_first_with_graphql/test/test_domain/mounty_adapter.dart b/packages/brick_offline_first_with_graphql/test/test_domain/mounty_adapter.dart index fa0e68e6..dec9ac82 100644 --- a/packages/brick_offline_first_with_graphql/test/test_domain/mounty_adapter.dart +++ b/packages/brick_offline_first_with_graphql/test/test_domain/mounty_adapter.dart @@ -35,7 +35,7 @@ Future> _$MountyToSqlite( class MountyOperationTransformer extends GraphqlQueryOperationTransformer { @override - GraphqlOperation get delete => GraphqlOperation( + GraphqlOperation get delete => const GraphqlOperation( document: r'''mutation DeleteDemoModel($input: DemoModelInput!) { deleteDemoModel(input: $input) {} }''', @@ -70,7 +70,7 @@ class MountyOperationTransformer extends GraphqlQueryOperationTransformer { } @override - GraphqlOperation get upsert => GraphqlOperation( + GraphqlOperation get upsert => const GraphqlOperation( document: r'''mutation UpsertDemoModels($input: DemoModelInput) { upsertDemoModel(input: $input) {} }''', @@ -89,15 +89,11 @@ class MountyAdapter extends OfflineFirstWithGraphqlAdapter { @override final Map fieldsToSqliteColumns = { 'primaryKey': const RuntimeSqliteColumnDefinition( - association: false, columnName: '_brick_id', - iterable: false, type: int, ), 'name': const RuntimeSqliteColumnDefinition( - association: false, columnName: 'name', - iterable: false, type: String, ), }; @@ -105,9 +101,7 @@ class MountyAdapter extends OfflineFirstWithGraphqlAdapter { @override final Map fieldsToGraphqlRuntimeDefinition = { 'name': const RuntimeGraphqlDefinition( - association: false, documentNodeName: 'name', - iterable: false, type: String, ), }; @@ -120,28 +114,28 @@ class MountyAdapter extends OfflineFirstWithGraphqlAdapter { @override Future fromGraphql( Map input, { - required provider, + required GraphqlProvider provider, covariant OfflineFirstWithGraphqlRepository? repository, }) async => await _$MountyFromGraphql(input, provider: provider, repository: repository); @override Future> toGraphql( Mounty input, { - required provider, + required GraphqlProvider provider, covariant OfflineFirstWithGraphqlRepository? repository, }) async => await _$MountyToGraphql(input, provider: provider, repository: repository); @override Future fromSqlite( Map input, { - required provider, + required SqliteProvider provider, covariant OfflineFirstWithGraphqlRepository? repository, }) async => await _$MountyFromSqlite(input, provider: provider, repository: repository); @override Future> toSqlite( Mounty input, { - required provider, + required SqliteProvider provider, covariant OfflineFirstWithGraphqlRepository? repository, }) async => await _$MountyToSqlite(input, provider: provider, repository: repository); diff --git a/packages/brick_offline_first_with_graphql_build/analysis_options.yaml b/packages/brick_offline_first_with_graphql_build/analysis_options.yaml index 5008bf6c..f04c6cf0 100644 --- a/packages/brick_offline_first_with_graphql_build/analysis_options.yaml +++ b/packages/brick_offline_first_with_graphql_build/analysis_options.yaml @@ -1,326 +1 @@ include: ../../analysis_options.yaml - -linter: - rules: - # This list is derived from the list of all available lints located at - # https://github.com/dart-lang/linter/blob/master/example/all.yaml - - always_declare_return_types - # - always_put_control_body_on_new_line - # - always_put_required_named_parameters_first - # - always_specify_types - - always_use_package_imports - - annotate_overrides - # - avoid_annotating_with_dynamic - - avoid_bool_literals_in_conditional_expressions - # - avoid_catches_without_on_clauses - # - avoid_catching_errors - - avoid_classes_with_only_static_members - - avoid_double_and_int_checks - # - avoid_dynamic_calls - - avoid_empty_else - # - avoid_equals_and_hash_code_on_mutable_classes - - avoid_escaping_inner_quotes - - avoid_field_initializers_in_const_classes - # - avoid_final_parameters - - avoid_function_literals_in_foreach_calls - - avoid_implementing_value_types - - avoid_init_to_null - - avoid_js_rounded_ints - - avoid_multiple_declarations_per_line - - avoid_null_checks_in_equality_operators - # - avoid_positional_boolean_parameters - - avoid_print - - avoid_private_typedef_functions - - avoid_redundant_argument_values - - avoid_relative_lib_imports - - avoid_renaming_method_parameters - - avoid_return_types_on_setters - - avoid_returning_null_for_void - - avoid_returning_this - - avoid_setters_without_getters - - avoid_shadowing_type_parameters - - avoid_single_cascade_in_expression_statements - - avoid_slow_async_io - - avoid_type_to_string - - avoid_types_as_parameter_names - # - avoid_types_on_closure_parameters - - avoid_unnecessary_containers - - avoid_unused_constructor_parameters - - avoid_void_async - - avoid_web_libraries_in_flutter - - await_only_futures - - camel_case_extensions - - camel_case_types - - cancel_subscriptions - - cascade_invocations - - cast_nullable_to_non_nullable - # - close_sinks - - collection_methods_unrelated_type - - combinators_ordering - - comment_references - - conditional_uri_does_not_exist - - constant_identifier_names - - control_flow_in_finally - - curly_braces_in_flow_control_structures - - dangling_library_doc_comments - - depend_on_referenced_packages - - deprecated_consistency - - deprecated_member_use_from_same_package - # - diagnostic_describe_all_properties - - directives_ordering - - discarded_futures - - do_not_use_environment - - empty_catches - - empty_constructor_bodies - - empty_statements - - eol_at_end_of_file - - exhaustive_cases - - file_names - - flutter_style_todos - - hash_and_equals - - implementation_imports - - implicit_call_tearoffs - - implicit_reopen - - invalid_case_patterns - - join_return_with_assignment - # - leading_newlines_in_multiline_strings - - library_annotations - - library_names - - library_prefixes - - library_private_types_in_public_api - # - lines_longer_than_80_chars - - literal_only_boolean_expressions - - matching_super_parameters - - missing_whitespace_between_adjacent_strings - - no_adjacent_strings_in_list - - no_default_cases - - no_duplicate_case_values - - no_leading_underscores_for_library_prefixes - - no_leading_underscores_for_local_identifiers - - no_literal_bool_comparisons - - no_logic_in_create_state - - no_runtimeType_toString - - no_self_assignments - - no_wildcard_variable_uses - - non_constant_identifier_names - - noop_primitive_operations - - null_check_on_nullable_type_parameter - - null_closures - - omit_local_variable_types - - one_member_abstracts - - only_throw_errors - - overridden_fields - - package_api_docs - - package_names - - package_prefixed_library_names - - parameter_assignments - - prefer_adjacent_string_concatenation - - prefer_asserts_in_initializer_lists - - prefer_asserts_with_message - - prefer_collection_literals - - prefer_conditional_assignment - - prefer_const_constructors - - prefer_const_constructors_in_immutables - - prefer_const_declarations - - prefer_const_literals_to_create_immutables - - prefer_constructors_over_static_methods - - prefer_contains - # - prefer_double_quotes - - prefer_expression_function_bodies - - prefer_final_fields - - prefer_final_in_for_each - - prefer_final_locals - # - prefer_final_parameters - - prefer_for_elements_to_map_fromIterable - - prefer_foreach - - prefer_function_declarations_over_variables - - prefer_generic_function_type_aliases - - prefer_if_elements_to_conditional_expressions - - prefer_if_null_operators - - prefer_initializing_formals - - prefer_inlined_adds - - prefer_int_literals - - prefer_interpolation_to_compose_strings - - prefer_is_empty - - prefer_is_not_empty - - prefer_is_not_operator - - prefer_iterable_whereType - - prefer_mixin - - prefer_null_aware_method_calls - - prefer_null_aware_operators - # - prefer_relative_imports - - prefer_single_quotes - - prefer_spread_collections - - prefer_typing_uninitialized_variables - - prefer_void_to_null - - provide_deprecation_message - - public_member_api_docs - - recursive_getters - - require_trailing_commas - - secure_pubspec_urls - - sized_box_for_whitespace - - sized_box_shrink_expand - - slash_for_doc_comments - - sort_child_properties_last - # - sort_constructors_first - - sort_pub_dependencies - - sort_unnamed_constructors_first - - test_types_in_equals - - throw_in_finally - - tighten_type_of_initializing_formals - - type_annotate_public_apis - - type_init_formals - - type_literal_in_constant_pattern - - unawaited_futures - # - unnecessary_await_in_return - - unnecessary_brace_in_string_interps - - unnecessary_breaks - - unnecessary_const - - unnecessary_constructor_name - # - unnecessary_final - - unnecessary_getters_setters - - unnecessary_lambdas - - unnecessary_late - - unnecessary_library_directive - - unnecessary_new - - unnecessary_null_aware_assignments - - unnecessary_null_aware_operator_on_extension_on_nullable - - unnecessary_null_checks - - unnecessary_null_in_if_null_operators - - unnecessary_nullable_for_final_variable_declarations - - unnecessary_overrides - - unnecessary_parenthesis - - unnecessary_raw_strings - - unnecessary_statements - - unnecessary_string_escapes - - unnecessary_string_interpolations - - unnecessary_this - - unnecessary_to_list_in_spreads - # - unreachable_from_main - - unrelated_type_equality_checks - - unsafe_html - - use_build_context_synchronously - - use_colored_box - - use_decorated_box - - use_enums - - use_full_hex_values_for_flutter_colors - - use_function_type_syntax_for_parameters - - use_if_null_to_convert_nulls_to_bools - - use_is_even_rather_than_modulo - - use_key_in_widget_constructors - - use_late_for_private_fields_and_variables - - use_named_constants - - use_raw_strings - - use_rethrow_when_possible - - use_setters_to_change_properties - - use_string_buffers - - use_string_in_part_of_directives - - use_super_parameters - - use_test_throws_matchers - - use_to_and_as_if_applicable - - valid_regexps - - void_checks - -analyzer: - exclude: - - example/ - - "**/example/" - - example_rest - - example_graphql - - "**/*.g.dart" - - errors: - # override custom - always_use_package_imports: error - camel_case_extensions: error - camel_case_types: error - curly_braces_in_flow_control_structures: error - directives_ordering: error - file_names: error - prefer_single_quotes: error - prefer_is_empty: error - prefer_is_not_empty: error - require_trailing_commas: error - sort_pub_dependencies: error - unnecessary_statements: error - - # override flutter_lints - avoid_print: error - avoid_unnecessary_containers: error - avoid_web_libraries_in_flutter: error - no_logic_in_create_state: error - prefer_const_constructors: error - prefer_const_constructors_in_immutables: error - prefer_const_declarations: error - prefer_const_literals_to_create_immutables: error - sized_box_for_whitespace: error - sort_child_properties_last: error - use_build_context_synchronously: error - use_full_hex_values_for_flutter_colors: error - use_key_in_widget_constructors: error - - # override recommended lints - always_require_non_null_named_parameters: error - annotate_overrides: error - avoid_function_literals_in_foreach_calls: error - avoid_init_to_null: error - avoid_null_checks_in_equality_operators: error - avoid_renaming_method_parameters: error - avoid_return_types_on_setters: error - avoid_returning_null_for_void: error - avoid_single_cascade_in_expression_statements: error - await_only_futures: error - constant_identifier_names: error - control_flow_in_finally: error - depend_on_referenced_packages: ignore - empty_constructor_bodies: error - empty_statements: error - exhaustive_cases: error - implementation_imports: ignore - invalid_case_patterns: error - library_names: error - library_prefixes: error - library_private_types_in_public_api: error - matching_super_parameters: error - no_leading_underscores_for_library_prefixes: error - no_leading_underscores_for_local_identifiers: error - no_literal_bool_comparisons: error - null_check_on_nullable_type_parameter: error - null_closures: error - overridden_fields: error - package_names: error - prefer_adjacent_string_concatenation: error - prefer_collection_literals: error - prefer_conditional_assignment: error - prefer_contains: error - prefer_equal_for_default_values: error - prefer_final_fields: error - prefer_for_elements_to_map_fromIterable: error - prefer_function_declarations_over_variables: error - prefer_if_null_operators: error - prefer_initializing_formals: error - prefer_inlined_adds: error - prefer_interpolation_to_compose_strings: error - prefer_is_not_operator: error - prefer_null_aware_operators: error - prefer_spread_collections: error - prefer_void_to_null: error - recursive_getters: error - slash_for_doc_comments: error - type_init_formals: error - type_literal_in_constant_pattern: error - unnecessary_brace_in_string_interps: error - unnecessary_breaks: error - unnecessary_const: error - unnecessary_constructor_name: error - unnecessary_getters_setters: error - unnecessary_late: error - unnecessary_new: error - unnecessary_null_aware_assignments: error - unnecessary_null_in_if_null_operators: error - unnecessary_nullable_for_final_variable_declarations: error - unnecessary_string_escapes: error - unnecessary_string_interpolations: error - unnecessary_this: error - use_function_type_syntax_for_parameters: error - use_rethrow_when_possible: error diff --git a/packages/brick_offline_first_with_rest/lib/rest_to_offline_first_converter.dart b/packages/brick_offline_first_with_rest/lib/rest_to_offline_first_converter.dart index 046bb805..3560ca7c 100644 --- a/packages/brick_offline_first_with_rest/lib/rest_to_offline_first_converter.dart +++ b/packages/brick_offline_first_with_rest/lib/rest_to_offline_first_converter.dart @@ -1,8 +1,10 @@ import 'dart:convert'; import 'dart:io'; +import 'package:brick_offline_first/brick_offline_first.dart'; import 'package:dart_style/dart_style.dart' as dart_style; import 'package:http/http.dart'; +import 'package:meta/meta.dart'; final _formatter = dart_style.DartFormatter(); @@ -26,9 +28,15 @@ class RestToOfflineFirstConverter { late Client _client; /// Only set client when testing - set client(value) => _client = value; + @visibleForTesting + set client(Client value) => _client = value; + + /// Client get client => _client; + /// Convert a JSON API payload into an [OfflineFirstModel], output via [generate] or [saveToFile]. + /// + /// This will not map associations or non-primitive types. RestToOfflineFirstConverter({ required this.endpoint, this.headers, @@ -67,8 +75,7 @@ class RestToOfflineFirstConverter { /// Produce instance fields String generateFields(Map fields) { - final keys = fields.keys.toList(); - keys.sort(); + final keys = fields.keys.toList()..sort(); return keys.fold>([], (acc, key) { final valueType = fields[key].runtimeType.toString(); return acc..add(' final $valueType ${toCamelCase(key)};'); @@ -77,8 +84,7 @@ class RestToOfflineFirstConverter { /// Produce fields to be invoked in the default constructor String generateConstructorFields(Map fields) { - final keys = fields.keys.toList(); - keys.sort(); + final keys = fields.keys.toList()..sort(); return keys.fold>([], (acc, key) { return acc..add(' this.${toCamelCase(key)}'); }).join(',\n'); diff --git a/packages/brick_offline_first_with_rest/lib/src/models/offline_first_with_rest_model.dart b/packages/brick_offline_first_with_rest/lib/src/models/offline_first_with_rest_model.dart index c8aff4a1..6985a6c3 100644 --- a/packages/brick_offline_first_with_rest/lib/src/models/offline_first_with_rest_model.dart +++ b/packages/brick_offline_first_with_rest/lib/src/models/offline_first_with_rest_model.dart @@ -1,4 +1,6 @@ import 'package:brick_offline_first/brick_offline_first.dart' show OfflineFirstModel; -import 'package:brick_rest/brick_rest.dart' show RestModel; +import 'package:brick_rest/brick_rest.dart'; +/// An offline-first enabled model for use with the [RestProvider] +// ignore: prefer_mixin abstract class OfflineFirstWithRestModel extends OfflineFirstModel with RestModel {} diff --git a/packages/brick_offline_first_with_rest/lib/src/offline_first_exception.dart b/packages/brick_offline_first_with_rest/lib/src/offline_first_exception.dart deleted file mode 100644 index e252087c..00000000 --- a/packages/brick_offline_first_with_rest/lib/src/offline_first_exception.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:brick_rest/brick_rest.dart' show RestException; - -class OfflineFirstException implements Exception { - /// The producing error from either [RestProvider] or [SqliteProvider]. - final Exception originalError; - - OfflineFirstException(this.originalError); - - /// If [originalError] was produced by [RestProvider]. - bool get fromRest => originalError is RestException; - - String get message => originalError.toString(); - - int? get restErrorCode => fromRest ? (originalError as RestException).response.statusCode : null; - - /// Forward errors from a [RestException] response. `null` is returned - /// if [originalError] was not [fromRest]. - Map? get restErrors { - if (!fromRest) return null; - - return (originalError as RestException).errors; - } - - @override - String toString() => message; -} diff --git a/packages/brick_offline_first_with_rest/lib/src/offline_first_with_rest_adapter.dart b/packages/brick_offline_first_with_rest/lib/src/offline_first_with_rest_adapter.dart index 161395de..115c89c8 100644 --- a/packages/brick_offline_first_with_rest/lib/src/offline_first_with_rest_adapter.dart +++ b/packages/brick_offline_first_with_rest/lib/src/offline_first_with_rest_adapter.dart @@ -1,10 +1,12 @@ import 'package:brick_offline_first/brick_offline_first.dart'; import 'package:brick_offline_first_with_rest/src/models/offline_first_with_rest_model.dart'; +import 'package:brick_rest/brick_rest.dart' show RestAdapter, RestProvider; +import 'package:brick_sqlite/brick_sqlite.dart'; -import 'package:brick_rest/brick_rest.dart' show RestProvider, RestAdapter; - -/// This adapter fetches first from [SqliteProvider] then hydrates with [RestProvider]. +/// This adapter holds logic necessary to work with [SqliteProvider] and [RestProvider]. abstract class OfflineFirstWithRestAdapter<_Model extends OfflineFirstWithRestModel> + // ignore: prefer_mixin extends OfflineFirstAdapter<_Model> with RestAdapter<_Model> { + /// This adapter holds logic necessary to work with [SqliteProvider] and [RestProvider]. OfflineFirstWithRestAdapter(); } diff --git a/packages/brick_offline_first_with_rest/lib/src/offline_first_with_rest_exception.dart b/packages/brick_offline_first_with_rest/lib/src/offline_first_with_rest_exception.dart index f0be99ce..510f4ec6 100644 --- a/packages/brick_offline_first_with_rest/lib/src/offline_first_with_rest_exception.dart +++ b/packages/brick_offline_first_with_rest/lib/src/offline_first_with_rest_exception.dart @@ -1,12 +1,17 @@ import 'package:brick_offline_first/brick_offline_first.dart'; -import 'package:brick_rest/brick_rest.dart' show RestException; +import 'package:brick_rest/brick_rest.dart' show RestException, RestProvider; +/// Forwarded exception thrown from a [RestException]. The implementation may choose +/// to ignore this exception if the latest REST data is not important. class OfflineFirstWithRestException extends OfflineFirstException { + /// Forwarded exception thrown from a [RestException]. The implementation may choose + /// to ignore this exception if the latest REST data is not important. OfflineFirstWithRestException(super.originalError); /// If [originalError] was produced by [RestProvider]. bool get fromRest => originalError is RestException; + /// int? get restErrorCode => fromRest ? (originalError as RestException).response.statusCode : null; /// Forward errors from a [RestException] response. `null` is returned diff --git a/packages/brick_offline_first_with_rest/lib/src/offline_first_with_rest_repository.dart b/packages/brick_offline_first_with_rest/lib/src/offline_first_with_rest_repository.dart index 78fd672c..f82746f2 100644 --- a/packages/brick_offline_first_with_rest/lib/src/offline_first_with_rest_repository.dart +++ b/packages/brick_offline_first_with_rest/lib/src/offline_first_with_rest_repository.dart @@ -5,7 +5,7 @@ import 'package:brick_offline_first/offline_queue.dart'; import 'package:brick_offline_first_with_rest/src/models/offline_first_with_rest_model.dart'; import 'package:brick_offline_first_with_rest/src/offline_queue/rest_offline_queue_client.dart'; import 'package:brick_offline_first_with_rest/src/offline_queue/rest_offline_request_queue.dart'; -import 'package:brick_rest/brick_rest.dart' show RestProvider, RestException; +import 'package:brick_rest/brick_rest.dart'; import 'package:http/http.dart' as http; import 'package:meta/meta.dart'; @@ -22,9 +22,14 @@ abstract class OfflineFirstWithRestRepository requestManager; /// If the response returned from the client is one of these error codes, the request @@ -39,10 +40,11 @@ class RestOfflineQueueClient extends http.BaseClient { final Logger _logger; /// Describes the type of policy that came from the request, stringified - /// from the [OfflineFirstPolicy] enum. The property will be removed before + /// from the `OfflineFirstPolicy` enum. The property will be removed before /// forwarding the request to [_inner]. static const policyHeader = 'X-Brick-OfflineFirstPolicy'; + /// Stores all requests in a SQLite database RestOfflineQueueClient( this._inner, this.requestManager, { diff --git a/packages/brick_offline_first_with_rest/lib/src/offline_queue/rest_offline_request_queue.dart b/packages/brick_offline_first_with_rest/lib/src/offline_queue/rest_offline_request_queue.dart index d7643f30..45f16e54 100644 --- a/packages/brick_offline_first_with_rest/lib/src/offline_queue/rest_offline_request_queue.dart +++ b/packages/brick_offline_first_with_rest/lib/src/offline_queue/rest_offline_request_queue.dart @@ -4,10 +4,12 @@ import 'package:brick_offline_first/offline_queue.dart'; import 'package:brick_offline_first_with_rest/src/offline_queue/rest_offline_queue_client.dart'; import 'package:http/http.dart' as http; +/// REST implementation of [OfflineRequestQueue] class RestOfflineRequestQueue extends OfflineRequestQueue { /// The client responsible for resending requests final RestOfflineQueueClient client; + /// REST implementation of [OfflineRequestQueue] RestOfflineRequestQueue({ required this.client, }) : super( diff --git a/packages/brick_offline_first_with_rest/lib/src/offline_queue/rest_request_sqlite_cache.dart b/packages/brick_offline_first_with_rest/lib/src/offline_queue/rest_request_sqlite_cache.dart index 8cd1ad30..06eb4497 100644 --- a/packages/brick_offline_first_with_rest/lib/src/offline_queue/rest_request_sqlite_cache.dart +++ b/packages/brick_offline_first_with_rest/lib/src/offline_queue/rest_request_sqlite_cache.dart @@ -4,9 +4,12 @@ import 'package:brick_offline_first/offline_queue.dart'; import 'package:brick_offline_first_with_rest/src/offline_queue/rest_request_sqlite_cache_manager.dart'; import 'package:http/http.dart' as http; +/// REST implementation of [RequestSqliteCache] class RestRequestSqliteCache extends RequestSqliteCache { + /// bool get requestIsPush => ['POST', 'PUT', 'DELETE', 'PATCH'].contains(request.method); + /// REST implementation of [RequestSqliteCache] RestRequestSqliteCache(http.Request request) : super( attemptColumn: HTTP_JOBS_ATTEMPTS_COLUMN, diff --git a/packages/brick_offline_first_with_rest/lib/src/offline_queue/rest_request_sqlite_cache_manager.dart b/packages/brick_offline_first_with_rest/lib/src/offline_queue/rest_request_sqlite_cache_manager.dart index 72c99433..15589882 100644 --- a/packages/brick_offline_first_with_rest/lib/src/offline_queue/rest_request_sqlite_cache_manager.dart +++ b/packages/brick_offline_first_with_rest/lib/src/offline_queue/rest_request_sqlite_cache_manager.dart @@ -5,7 +5,9 @@ import 'dart:convert'; import 'package:brick_offline_first/offline_queue.dart'; import 'package:http/http.dart' as http; +/// REST implementation of [RequestSqliteCacheManager] class RestRequestSqliteCacheManager extends RequestSqliteCacheManager { + /// REST implementation of [RequestSqliteCacheManager] RestRequestSqliteCacheManager( super.databaseName, { required super.databaseFactory, @@ -96,6 +98,7 @@ const HTTP_JOBS_PRIMARY_KEY_COLUMN = 'id'; /// String const HTTP_JOBS_REQUEST_METHOD_COLUMN = 'request_method'; +/// String const HTTP_JOBS_TABLE_NAME = 'HttpJobs'; /// int; millisecondsSinceEpoch diff --git a/packages/brick_offline_first_with_rest/lib/testing.dart b/packages/brick_offline_first_with_rest/lib/testing.dart index e641be05..e4f5972a 100644 --- a/packages/brick_offline_first_with_rest/lib/testing.dart +++ b/packages/brick_offline_first_with_rest/lib/testing.dart @@ -1,13 +1,16 @@ import 'dart:io'; import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart'; +import 'package:brick_rest/brick_rest.dart'; import 'package:collection/collection.dart'; import 'package:http/http.dart' as http; import 'package:http/testing.dart'; import 'package:path/path.dart' as p; +// ignore: public_member_api_docs enum StubHttpMethod { get, post, put, delete, any } +/// The expected response from a request. class StubOfflineFirstRestResponse { /// The path where the [response] should be returned. Avoid leading slashes. /// @@ -23,6 +26,7 @@ class StubOfflineFirstRestResponse { /// The text returned from the HTTP request. final String response; + /// static String get currentDirectory { // `flutter test` and `dart test` resolve with different values // https://github.com/flutter/flutter/issues/20907 @@ -38,12 +42,14 @@ class StubOfflineFirstRestResponse { return p.join(directory, 'test'); } + /// The expected response from a request. StubOfflineFirstRestResponse( this.response, { required this.endpoint, StubHttpMethod? method, }) : method = method ?? StubHttpMethod.any; + /// factory StubOfflineFirstRestResponse.fromFile( String filePath, { required String endpoint, @@ -108,6 +114,10 @@ class StubOfflineFirstWithRest { return http.Response('endpoint ${req.method} ${req.url} is not stubbed', 422); }); + /// Generate mocks for an [OfflineFirstWithRestModel]. Instantiation automatically stubs REST responses. + /// + /// For convenience, your data structure only needs to be defined once. Include a sample API + /// response in a sibling `/api/` directory (`api` can be changed by overwriting `apiResponse`). StubOfflineFirstWithRest({ required this.baseEndpoint, required this.responses, @@ -120,7 +130,7 @@ class StubOfflineFirstWithRest { /// } /// ``` /// - /// Responses will be returned on all HTTP methods. The [filePath] is + /// Responses will be returned on all HTTP methods. The [endpointsAndFilePaths] is /// **relative to the top-level /test directory**. factory StubOfflineFirstWithRest.fromFiles( String baseEndpoint, diff --git a/packages/brick_offline_first_with_rest/pubspec.yaml b/packages/brick_offline_first_with_rest/pubspec.yaml index d4ae3b24..8b022c40 100644 --- a/packages/brick_offline_first_with_rest/pubspec.yaml +++ b/packages/brick_offline_first_with_rest/pubspec.yaml @@ -24,7 +24,7 @@ dependencies: 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 + lints: + mockito: + sqflite_common_ffi: + test: diff --git a/packages/brick_offline_first_with_rest/test/helpers/__mocks__.dart b/packages/brick_offline_first_with_rest/test/helpers/__mocks__.dart index b721f833..10176dd7 100644 --- a/packages/brick_offline_first_with_rest/test/helpers/__mocks__.dart +++ b/packages/brick_offline_first_with_rest/test/helpers/__mocks__.dart @@ -12,8 +12,8 @@ part 'horse_adapter.dart'; part 'mounty.dart'; part 'mounty_adapter.dart'; -/// The exact same as [DemoModel], except this class is tracked by the Memory Cache Provider -/// while [DemoModel] is not. +/// The exact same as [Mounty], except this class is tracked by the Memory Cache Provider +/// while [Mounty] is not. class MemoryDemoModel extends Mounty { MemoryDemoModel(String name) : super(name: name); } @@ -46,7 +46,8 @@ class DemoModelMigration extends Migration { } class TestRepository extends OfflineFirstWithRestRepository { - static TestRepository? _singleton; + static late TestRepository? _singleton; + factory TestRepository() => _singleton!; TestRepository._( RestProvider restProvider, @@ -61,7 +62,6 @@ class TestRepository extends OfflineFirstWithRestRepository { databaseFactory: databaseFactoryFfi, ), ); - factory TestRepository() => _singleton!; factory TestRepository.withProviders(RestProvider restProvider, SqliteProvider sqliteProvider) => TestRepository._(restProvider, sqliteProvider); diff --git a/packages/brick_offline_first_with_rest/test/helpers/horse_adapter.dart b/packages/brick_offline_first_with_rest/test/helpers/horse_adapter.dart index d8c19e80..b94b112e 100644 --- a/packages/brick_offline_first_with_rest/test/helpers/horse_adapter.dart +++ b/packages/brick_offline_first_with_rest/test/helpers/horse_adapter.dart @@ -72,15 +72,11 @@ class HorseAdapter extends OfflineFirstWithRestAdapter { @override final Map fieldsToSqliteColumns = { 'primaryKey': const RuntimeSqliteColumnDefinition( - association: false, columnName: '_brick_id', - iterable: false, type: int, ), 'name': const RuntimeSqliteColumnDefinition( - association: false, columnName: 'name', - iterable: false, type: String, ), 'mounties': const RuntimeSqliteColumnDefinition( @@ -96,7 +92,11 @@ class HorseAdapter extends OfflineFirstWithRestAdapter { @override final String tableName = 'Horse'; @override - Future afterSave(instance, {required provider, repository}) async { + Future afterSave( + Horse instance, { + required SqliteProvider provider, + ModelRepository? repository, + }) async { if (instance.primaryKey != null) { await Future.wait( instance.mounties.map((s) async { @@ -113,28 +113,28 @@ class HorseAdapter extends OfflineFirstWithRestAdapter { @override Future fromRest( Map input, { - required provider, + required RestProvider provider, covariant OfflineFirstWithRestRepository? repository, }) async => await _$HorseFromRest(input, provider: provider, repository: repository); @override Future> toRest( Horse input, { - required provider, + required RestProvider provider, covariant OfflineFirstWithRestRepository? repository, }) async => await _$HorseToRest(input, provider: provider, repository: repository); @override Future fromSqlite( Map input, { - required provider, + required SqliteProvider provider, covariant OfflineFirstWithRestRepository? repository, }) async => await _$HorseFromSqlite(input, provider: provider, repository: repository); @override Future> toSqlite( Horse input, { - required provider, + required SqliteProvider provider, covariant OfflineFirstWithRestRepository? repository, }) async => await _$HorseToSqlite(input, provider: provider, repository: repository); diff --git a/packages/brick_offline_first_with_rest/test/helpers/mounty.dart b/packages/brick_offline_first_with_rest/test/helpers/mounty.dart index c34c6022..ea4dc796 100644 --- a/packages/brick_offline_first_with_rest/test/helpers/mounty.dart +++ b/packages/brick_offline_first_with_rest/test/helpers/mounty.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_field_initializers_in_const_classes + part of '__mocks__.dart'; class MountyRequestTransformer extends RestRequestTransformer { diff --git a/packages/brick_offline_first_with_rest/test/helpers/mounty_adapter.dart b/packages/brick_offline_first_with_rest/test/helpers/mounty_adapter.dart index acdecfee..57d6f611 100644 --- a/packages/brick_offline_first_with_rest/test/helpers/mounty_adapter.dart +++ b/packages/brick_offline_first_with_rest/test/helpers/mounty_adapter.dart @@ -43,15 +43,11 @@ class MountyAdapter extends OfflineFirstWithRestAdapter { @override final Map fieldsToSqliteColumns = { 'primaryKey': const RuntimeSqliteColumnDefinition( - association: false, columnName: '_brick_id', - iterable: false, type: int, ), 'name': const RuntimeSqliteColumnDefinition( - association: false, columnName: 'name', - iterable: false, type: String, ), }; @@ -64,28 +60,28 @@ class MountyAdapter extends OfflineFirstWithRestAdapter { @override Future fromRest( Map input, { - required provider, + required RestProvider provider, covariant OfflineFirstWithRestRepository? repository, }) async => await _$MountyFromRest(input, provider: provider, repository: repository); @override Future> toRest( Mounty input, { - required provider, + required RestProvider provider, covariant OfflineFirstWithRestRepository? repository, }) async => await _$MountyToRest(input, provider: provider, repository: repository); @override Future fromSqlite( Map input, { - required provider, + required SqliteProvider provider, covariant OfflineFirstWithRestRepository? repository, }) async => await _$MountyFromSqlite(input, provider: provider, repository: repository); @override Future> toSqlite( Mounty input, { - required provider, + required SqliteProvider provider, covariant OfflineFirstWithRestRepository? repository, }) async => await _$MountyToSqlite(input, provider: provider, repository: repository); diff --git a/packages/brick_offline_first_with_rest/test/offline_queue/rest_offline_queue_client_test.dart b/packages/brick_offline_first_with_rest/test/offline_queue/rest_offline_queue_client_test.dart index 1c99791d..bca42c40 100644 --- a/packages/brick_offline_first_with_rest/test/offline_queue/rest_offline_queue_client_test.dart +++ b/packages/brick_offline_first_with_rest/test/offline_queue/rest_offline_queue_client_test.dart @@ -216,7 +216,7 @@ void main() { }); test('onReattempt is not triggered for non-reattemptable status code', () async { - bool callbackTriggered = false; + var callbackTriggered = false; final inner = stubResult(statusCode: 404); final client = RestOfflineQueueClient( @@ -238,7 +238,7 @@ void main() { Object? capturedException; final inner = MockClient((req) async { - throw SocketException('test error'); + throw const SocketException('test error'); }); final client = RestOfflineQueueClient( @@ -257,11 +257,11 @@ void main() { expect(capturedRequest?.method, equals('POST')); expect(capturedRequest?.url, equals(uri)); expect(capturedException, isA()); - expect((capturedException as SocketException).message, equals('test error')); + expect((capturedException! as SocketException).message, equals('test error')); }); test('onRequestException is not triggered for successful request', () async { - bool callbackTriggered = false; + var callbackTriggered = false; final inner = stubResult(statusCode: 200); final client = RestOfflineQueueClient( diff --git a/packages/brick_offline_first_with_rest/test/offline_queue/rest_offline_requeust_queue_test.dart b/packages/brick_offline_first_with_rest/test/offline_queue/rest_offline_requeust_queue_test.dart index d43f582b..a939ea88 100644 --- a/packages/brick_offline_first_with_rest/test/offline_queue/rest_offline_requeust_queue_test.dart +++ b/packages/brick_offline_first_with_rest/test/offline_queue/rest_offline_requeust_queue_test.dart @@ -17,15 +17,13 @@ void main() { group('RestOfflineRequestQueue', () { test('#start', () { - final queue = RestOfflineRequestQueue(client: offlineClient); - queue.start(); + final queue = RestOfflineRequestQueue(client: offlineClient)..start(); expect(queue.isRunning, isTrue); queue.stop(); }); test('#stop', () { - final queue = RestOfflineRequestQueue(client: offlineClient); - queue.start(); + final queue = RestOfflineRequestQueue(client: offlineClient)..start(); expect(queue.isRunning, isTrue); queue.stop(); expect(queue.isRunning, isFalse); diff --git a/packages/brick_offline_first_with_rest/test/offline_queue/rest_request_sqlite_cache_manager_test.dart b/packages/brick_offline_first_with_rest/test/offline_queue/rest_request_sqlite_cache_manager_test.dart index 99a8e0ab..268485d4 100644 --- a/packages/brick_offline_first_with_rest/test/offline_queue/rest_request_sqlite_cache_manager_test.dart +++ b/packages/brick_offline_first_with_rest/test/offline_queue/rest_request_sqlite_cache_manager_test.dart @@ -14,7 +14,7 @@ void main() { final requestManager = RestRequestSqliteCacheManager( inMemoryDatabasePath, databaseFactory: databaseFactoryFfi, - processingInterval: const Duration(seconds: 0), + processingInterval: Duration.zero, ); setUpAll(() async { @@ -36,7 +36,7 @@ void main() { inMemoryDatabasePath, databaseFactory: databaseFactoryFfi, serialProcessing: false, - processingInterval: const Duration(seconds: 0), + processingInterval: Duration.zero, ); final client = RestOfflineQueueClient(inner, requestManager); @@ -106,7 +106,7 @@ void main() { await asCacheItem.insertOrUpdate(await requestManager.getDb()); await asCacheItem.unlock(await requestManager.getDb()); - final requests = await requestManager.unprocessedRequests(onlyLocked: false); + final requests = await requestManager.unprocessedRequests(); expect(requests, hasLength(1)); final lockedRequests = await requestManager.unprocessedRequests(onlyLocked: true); @@ -140,7 +140,7 @@ void main() { ); expect(await requestManager.unprocessedRequests(onlyLocked: true), hasLength(1)); - expect(await requestManager.unprocessedRequests(onlyLocked: false), hasLength(1)); + expect(await requestManager.unprocessedRequests(), hasLength(1)); expect(await requestManager.prepareNextRequestToProcess(), isNull); diff --git a/packages/brick_offline_first_with_rest/test/rest_to_offline_first_converter_test.dart b/packages/brick_offline_first_with_rest/test/rest_to_offline_first_converter_test.dart index 3efaa2c3..913bba69 100644 --- a/packages/brick_offline_first_with_rest/test/rest_to_offline_first_converter_test.dart +++ b/packages/brick_offline_first_with_rest/test/rest_to_offline_first_converter_test.dart @@ -13,16 +13,16 @@ void main() { group('RestToOfflineFirstConverter', () { group('#getRestPayload', () { test('with top-level array', () async { - final converter = RestToOfflineFirstConverter(endpoint: 'http://0.0.0.0:3000/people'); - converter.client = _generateResponse('[{"name": "Thomas"}]'); + final converter = RestToOfflineFirstConverter(endpoint: 'http://0.0.0.0:3000/people') + ..client = _generateResponse('[{"name": "Thomas"}]'); final result = await converter.getRestPayload(); expect(result, {'name': 'Thomas'}); }); test('with top-level map', () async { - final converter = RestToOfflineFirstConverter(endpoint: 'http://0.0.0.0:3000/person'); - converter.client = _generateResponse('[{"name": "Thomas"}]'); + final converter = RestToOfflineFirstConverter(endpoint: 'http://0.0.0.0:3000/person') + ..client = _generateResponse('[{"name": "Thomas"}]'); final result = await converter.getRestPayload(); expect(result, {'name': 'Thomas'}); @@ -32,8 +32,7 @@ void main() { final converter = RestToOfflineFirstConverter( endpoint: 'http://0.0.0.0:3000/person', topLevelKey: 'person', - ); - converter.client = _generateResponse('{ "person": { "name": "Thomas"} }'); + )..client = _generateResponse('{ "person": { "name": "Thomas"} }'); final result = await converter.getRestPayload(); expect(result, {'name': 'Thomas'}); @@ -97,8 +96,8 @@ class People extends OfflineFirstModel { }); test('from rest', () async { - final converter = RestToOfflineFirstConverter(endpoint: 'http://0.0.0.0:3000/people'); - converter.client = _generateResponse('[{"name": "Thomas"}]'); + final converter = RestToOfflineFirstConverter(endpoint: 'http://0.0.0.0:3000/people') + ..client = _generateResponse('[{"name": "Thomas"}]'); final output = await converter.generate(); expect(output, expectedOutput); @@ -108,8 +107,7 @@ class People extends OfflineFirstModel { final converter = RestToOfflineFirstConverter( endpoint: 'http://0.0.0.0:3000/people', topLevelKey: 'people', - ); - converter.client = _generateResponse('{"people": [{"name": "Thomas"}]}'); + )..client = _generateResponse('{"people": [{"name": "Thomas"}]}'); final output = await converter.generate(); expect(output, contains("topLevelKey: 'people',")); diff --git a/packages/brick_offline_first_with_rest_build/lib/builder.dart b/packages/brick_offline_first_with_rest_build/lib/builder.dart index 90dbf9c2..d187fcee 100644 --- a/packages/brick_offline_first_with_rest_build/lib/builder.dart +++ b/packages/brick_offline_first_with_rest_build/lib/builder.dart @@ -7,23 +7,26 @@ import 'package:build/build.dart'; final _schemaGenerator = OfflineFirstSchemaGenerator(); +/// class OfflineFirstMigrationBuilder extends NewMigrationBuilder { @override final schemaGenerator = _schemaGenerator; } +/// class OfflineFirstSchemaBuilder extends SchemaBuilder { @override final schemaGenerator = _schemaGenerator; } -final offlineFirstGenerator = const OfflineFirstWithRestGenerator( +/// +const offlineFirstGenerator = OfflineFirstWithRestGenerator( superAdapterName: 'OfflineFirstWithRest', repositoryName: 'OfflineFirstWithRest', ); /// These functions act as builder factories used by `build.yaml` -Builder offlineFirstAggregateBuilder(options) => AggregateBuilder( +Builder offlineFirstAggregateBuilder(_) => const AggregateBuilder( requiredImports: [ "import 'package:brick_offline_first_abstract/annotations.dart';", "import 'package:brick_offline_first/brick_offline_first.dart';", @@ -31,9 +34,13 @@ Builder offlineFirstAggregateBuilder(options) => AggregateBuilder( "import 'package:brick_sqlite/db.dart';", ], ); -Builder offlineFirstAdaptersBuilder(options) => + +/// +Builder offlineFirstAdaptersBuilder(_) => AdapterBuilder(offlineFirstGenerator); -Builder offlineFirstModelDictionaryBuilder(options) => + +/// +Builder offlineFirstModelDictionaryBuilder(_) => ModelDictionaryBuilder( const OfflineFirstModelDictionaryGenerator('Rest'), expectedImportRemovals: [ @@ -43,5 +50,9 @@ Builder offlineFirstModelDictionaryBuilder(options) => 'import "package:brick_offline_first/brick_offline_first.dart";', ], ); -Builder offlineFirstNewMigrationBuilder(options) => OfflineFirstMigrationBuilder(); -Builder offlineFirstSchemaBuilder(options) => OfflineFirstSchemaBuilder(); + +/// +Builder offlineFirstNewMigrationBuilder(_) => OfflineFirstMigrationBuilder(); + +/// +Builder offlineFirstSchemaBuilder(_) => OfflineFirstSchemaBuilder(); diff --git a/packages/brick_offline_first_with_rest_build/lib/src/offline_first_rest_generators.dart b/packages/brick_offline_first_with_rest_build/lib/src/offline_first_rest_generators.dart index 7fc054eb..4df1fb6c 100644 --- a/packages/brick_offline_first_with_rest_build/lib/src/offline_first_rest_generators.dart +++ b/packages/brick_offline_first_with_rest_build/lib/src/offline_first_rest_generators.dart @@ -29,7 +29,9 @@ class _OfflineFirstRestDeserialize extends RestDeserialize }) : offlineFirstFields = OfflineFirstFields(element); } +/// class OfflineFirstRestModelSerdesGenerator extends RestModelSerdesGenerator { + /// OfflineFirstRestModelSerdesGenerator( super.element, super.reader, { diff --git a/packages/brick_offline_first_with_rest_build/lib/src/offline_first_with_rest_generator.dart b/packages/brick_offline_first_with_rest_build/lib/src/offline_first_with_rest_generator.dart index 4a7c87fc..1a654077 100644 --- a/packages/brick_offline_first_with_rest_build/lib/src/offline_first_with_rest_generator.dart +++ b/packages/brick_offline_first_with_rest_build/lib/src/offline_first_with_rest_generator.dart @@ -5,7 +5,9 @@ import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart import 'package:brick_offline_first_with_rest_build/src/offline_first_rest_generators.dart'; import 'package:source_gen/source_gen.dart'; +/// class OfflineFirstWithRestGenerator extends OfflineFirstGenerator { + /// const OfflineFirstWithRestGenerator({ super.repositoryName, super.superAdapterName, @@ -18,9 +20,6 @@ class OfflineFirstWithRestGenerator extends OfflineFirstGenerator[]; - generators.addAll(rest.generators); - generators.addAll(sqlite.generators); - return generators; + return [...rest.generators, ...sqlite.generators]; } } diff --git a/packages/brick_offline_first_with_rest_build/pubspec.yaml b/packages/brick_offline_first_with_rest_build/pubspec.yaml index 786bd8f9..5abab96e 100644 --- a/packages/brick_offline_first_with_rest_build/pubspec.yaml +++ b/packages/brick_offline_first_with_rest_build/pubspec.yaml @@ -27,9 +27,9 @@ dependencies: source_gen: ">=1.2.2 <2.0.0" dev_dependencies: - build_verify: ^2.0.0 - source_gen_test: ^1.0.0 - test: ^1.20.1 - lints: ^2.0.1 brick_build_test: path: ../brick_build_test + build_verify: + lints: + source_gen_test: + test: diff --git a/packages/brick_offline_first_with_rest_build/test/offline_first_generator/test_custom_serdes.dart b/packages/brick_offline_first_with_rest_build/test/offline_first_generator/test_custom_serdes.dart index 753cbe87..cce47b4f 100644 --- a/packages/brick_offline_first_with_rest_build/test/offline_first_generator/test_custom_serdes.dart +++ b/packages/brick_offline_first_with_rest_build/test/offline_first_generator/test_custom_serdes.dart @@ -2,7 +2,7 @@ import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart import 'package:brick_rest/brick_rest.dart' show Rest; import 'package:brick_sqlite/brick_sqlite.dart'; -final output = r''' +const output = r''' Future _$CustomSerdesFromRest(Map data, {required RestProvider provider, OfflineFirstRepository? repository}) async { diff --git a/packages/brick_offline_first_with_rest_build/test/offline_first_generator/test_rest_config_endpoint.dart b/packages/brick_offline_first_with_rest_build/test/offline_first_generator/test_rest_config_endpoint.dart index 501e9ed8..830f928b 100644 --- a/packages/brick_offline_first_with_rest_build/test/offline_first_generator/test_rest_config_endpoint.dart +++ b/packages/brick_offline_first_with_rest_build/test/offline_first_generator/test_rest_config_endpoint.dart @@ -2,7 +2,7 @@ import 'package:brick_offline_first/brick_offline_first.dart'; import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart'; import 'package:brick_rest/brick_rest.dart' show RestRequestTransformer, RestSerializable; -final output = r''' +const output = r''' // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_offline_first_with_rest_build/test/offline_first_generator/test_rest_config_field_rename.dart b/packages/brick_offline_first_with_rest_build/test/offline_first_generator/test_rest_config_field_rename.dart index 22c2ee43..2e0a0379 100644 --- a/packages/brick_offline_first_with_rest_build/test/offline_first_generator/test_rest_config_field_rename.dart +++ b/packages/brick_offline_first_with_rest_build/test/offline_first_generator/test_rest_config_field_rename.dart @@ -3,7 +3,7 @@ import 'package:brick_offline_first/brick_offline_first.dart'; import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart'; import 'package:brick_rest/brick_rest.dart' show RestSerializable; -final output = r''' +const output = r''' Future _$RestConfigNoRenameFromRest( Map data, {required RestProvider provider, @@ -131,7 +131,7 @@ class RestConfigNoRename extends OfflineFirstModel { } @ConnectOfflineFirstWithRest( - restConfig: RestSerializable(fieldRename: FieldRename.snake), + restConfig: RestSerializable.defaults, ) class RestConfigSnakeRename extends OfflineFirstModel { final int someLongField; diff --git a/packages/brick_offline_first_with_rest_build/test/offline_first_generator/test_specify_field_name.dart b/packages/brick_offline_first_with_rest_build/test/offline_first_generator/test_specify_field_name.dart index e5bb3ca5..d7ec7c57 100644 --- a/packages/brick_offline_first_with_rest_build/test/offline_first_generator/test_specify_field_name.dart +++ b/packages/brick_offline_first_with_rest_build/test/offline_first_generator/test_specify_field_name.dart @@ -2,7 +2,7 @@ import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart import 'package:brick_rest/brick_rest.dart' show Rest; import 'package:brick_sqlite/brick_sqlite.dart'; -final output = r''' +const output = r''' Future _$SpecifyFieldNameFromRest(Map data, {required RestProvider provider, OfflineFirstRepository? repository}) async { diff --git a/packages/brick_offline_first_with_rest_build/test/offline_first_generator_test.dart b/packages/brick_offline_first_with_rest_build/test/offline_first_generator_test.dart index 623a07d4..9f70fbaf 100644 --- a/packages/brick_offline_first_with_rest_build/test/offline_first_generator_test.dart +++ b/packages/brick_offline_first_with_rest_build/test/offline_first_generator_test.dart @@ -8,8 +8,8 @@ import 'offline_first_generator/test_rest_config_endpoint.dart' as rest_config_e import 'offline_first_generator/test_rest_config_field_rename.dart' as rest_config_field_rename; import 'offline_first_generator/test_specify_field_name.dart' as specify_field_name; -final _generator = OfflineFirstWithRestGenerator(); -final folder = 'offline_first_generator'; +const _generator = OfflineFirstWithRestGenerator(); +const folder = 'offline_first_generator'; final generateReader = generateLibraryForFolder(folder); void main() { diff --git a/packages/brick_offline_first_with_supabase/lib/src/offline_first_with_supabase_adapter.dart b/packages/brick_offline_first_with_supabase/lib/src/offline_first_with_supabase_adapter.dart index 5bc8ab0f..19a32637 100644 --- a/packages/brick_offline_first_with_supabase/lib/src/offline_first_with_supabase_adapter.dart +++ b/packages/brick_offline_first_with_supabase/lib/src/offline_first_with_supabase_adapter.dart @@ -1,9 +1,11 @@ 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_sqlite/brick_sqlite.dart'; import 'package:brick_supabase/brick_supabase.dart'; -/// This adapter fetches first from [SqliteProvider] then hydrates with [SupabaseProvider]. +/// This adapter combines logic from [SqliteProvider] and [SupabaseProvider]. abstract class OfflineFirstWithSupabaseAdapter<_Model extends OfflineFirstWithSupabaseModel> extends OfflineFirstAdapter<_Model> with SupabaseAdapter<_Model> { + /// This adapter combines logic from [SqliteProvider] and [SupabaseProvider]. OfflineFirstWithSupabaseAdapter(); } diff --git a/packages/brick_offline_first_with_supabase/lib/src/offline_first_with_supabase_model.dart b/packages/brick_offline_first_with_supabase/lib/src/offline_first_with_supabase_model.dart index 64cef86d..e4c705a1 100644 --- a/packages/brick_offline_first_with_supabase/lib/src/offline_first_with_supabase_model.dart +++ b/packages/brick_offline_first_with_supabase/lib/src/offline_first_with_supabase_model.dart @@ -1,4 +1,5 @@ import 'package:brick_offline_first/brick_offline_first.dart'; import 'package:brick_supabase/brick_supabase.dart'; +/// Supabase-enabled [OfflineFirstModel] abstract class OfflineFirstWithSupabaseModel extends OfflineFirstModel with SupabaseModel {} diff --git a/packages/brick_offline_first_with_supabase/lib/src/offline_first_with_supabase_repository.dart b/packages/brick_offline_first_with_supabase/lib/src/offline_first_with_supabase_repository.dart index bdc39762..860417b2 100644 --- a/packages/brick_offline_first_with_supabase/lib/src/offline_first_with_supabase_repository.dart +++ b/packages/brick_offline_first_with_supabase/lib/src/offline_first_with_supabase_repository.dart @@ -49,11 +49,16 @@ abstract class OfflineFirstWithSupabaseRepository< @protected final RestOfflineRequestQueue offlineRequestQueue; + /// Tracks the realtime stream controllers @protected @visibleForTesting final Map>>>> supabaseRealtimeSubscriptions = {}; + /// Ensures the [remoteProvider] is a [SupabaseProvider]. + /// + /// Care should be given to attach an offline queue to the provider using the static convenience + /// method [clientQueue]. OfflineFirstWithSupabaseRepository({ super.autoHydrate, super.loggerName, @@ -189,6 +194,7 @@ abstract class OfflineFirstWithSupabaseRepository< ); } + /// Convert a query to a [PostgresChangeFilter] for use with [subscribeToRealtime]. @protected @visibleForTesting @visibleForOverriding @@ -256,7 +262,7 @@ abstract class OfflineFirstWithSupabaseRepository< Query? query, String schema = 'public', }) { - query ??= Query(); + query ??= const Query(); if (supabaseRealtimeSubscriptions[TModel]?[eventType]?[query] != null) { return supabaseRealtimeSubscriptions[TModel]![eventType]![query]!.stream diff --git a/packages/brick_offline_first_with_supabase/pubspec.yaml b/packages/brick_offline_first_with_supabase/pubspec.yaml index 8ab938c4..cc4cb577 100644 --- a/packages/brick_offline_first_with_supabase/pubspec.yaml +++ b/packages/brick_offline_first_with_supabase/pubspec.yaml @@ -13,9 +13,9 @@ environment: dependencies: brick_core: ">=1.2.0 <2.0.0" brick_offline_first: ">=3.0.0 <4.0.0" + brick_offline_first_with_rest: ">=3.1.0 <4.0.0" brick_sqlite: ">=3.0.0 <4.0.0" brick_supabase: ">=1.0.0 <2.0.0" - brick_offline_first_with_rest: ">=3.1.0 <4.0.0" http: ">=1.0.0 <2.0.0" logging: ">=1.0.0 <2.0.0" meta: ">=1.3.0 <2.0.0" @@ -23,7 +23,7 @@ dependencies: supabase: ">=2.3.0 <3.0.0" dev_dependencies: - lints: ^2.0.1 - mockito: ^5.0.0 - sqflite_common_ffi: ^2.0.0 - test: ^1.16.5 + lints: + mockito: + sqflite_common_ffi: + test: diff --git a/packages/brick_offline_first_with_supabase/test/__mocks__.dart b/packages/brick_offline_first_with_supabase/test/__mocks__.dart index dd72d9cd..9f055904 100644 --- a/packages/brick_offline_first_with_supabase/test/__mocks__.dart +++ b/packages/brick_offline_first_with_supabase/test/__mocks__.dart @@ -5,6 +5,7 @@ import 'dart:convert'; // ignore: unused_import, unused_shown_name, unnecessary_import import 'package:brick_core/query.dart'; +import 'package:brick_core/src/model_repository.dart'; // ignore: unused_import, unused_shown_name import 'package:brick_offline_first/brick_offline_first.dart' show RuntimeOfflineFirstDefinition; // ignore: unused_import, unused_shown_name, unnecessary_import @@ -19,7 +20,7 @@ import 'package:brick_supabase/brick_supabase.dart'; import 'package:sqflite_common/sqlite_api.dart' show DatabaseExecutor; @ConnectOfflineFirstWithSupabase( - supabaseConfig: SupabaseSerializable(), + supabaseConfig: SupabaseSerializable.defaults, ) class Customer extends OfflineFirstWithSupabaseModel { @Sqlite(unique: true) @@ -55,7 +56,7 @@ class Customer extends OfflineFirstWithSupabaseModel { } @ConnectOfflineFirstWithSupabase( - supabaseConfig: SupabaseSerializable(), + supabaseConfig: SupabaseSerializable.defaults, ) class Pizza extends OfflineFirstWithSupabaseModel { /// Read more about `@Sqlite`: https://github.com/GetDutchie/brick/tree/main/packages/brick_sqlite#fields @@ -155,15 +156,12 @@ class PizzaAdapter extends OfflineFirstWithSupabaseAdapter { @override final fieldsToSupabaseColumns = { 'id': const RuntimeSupabaseColumnDefinition( - association: false, columnName: 'id', ), 'toppings': const RuntimeSupabaseColumnDefinition( - association: false, columnName: 'toppings', ), 'frozen': const RuntimeSupabaseColumnDefinition( - association: false, columnName: 'frozen', ), }; @@ -174,27 +172,20 @@ class PizzaAdapter extends OfflineFirstWithSupabaseAdapter { @override final Map fieldsToSqliteColumns = { 'primaryKey': const RuntimeSqliteColumnDefinition( - association: false, columnName: '_brick_id', - iterable: false, type: int, ), 'id': const RuntimeSqliteColumnDefinition( - association: false, columnName: 'id', - iterable: false, type: int, ), 'toppings': const RuntimeSqliteColumnDefinition( - association: false, columnName: 'toppings', iterable: true, type: Topping, ), 'frozen': const RuntimeSqliteColumnDefinition( - association: false, columnName: 'frozen', - iterable: false, type: bool, ), }; @@ -211,7 +202,7 @@ class PizzaAdapter extends OfflineFirstWithSupabaseAdapter { return null; } - return results.first['_brick_id'] as int; + return results.first['_brick_id']! as int; } @override @@ -220,28 +211,28 @@ class PizzaAdapter extends OfflineFirstWithSupabaseAdapter { @override Future fromSupabase( Map input, { - required provider, + required SupabaseProvider provider, covariant OfflineFirstWithSupabaseRepository? repository, }) async => await _$PizzaFromSupabase(input, provider: provider, repository: repository); @override Future> toSupabase( Pizza input, { - required provider, + required SupabaseProvider provider, covariant OfflineFirstWithSupabaseRepository? repository, }) async => await _$PizzaToSupabase(input, provider: provider, repository: repository); @override Future fromSqlite( Map input, { - required provider, + required SqliteProvider provider, covariant OfflineFirstWithSupabaseRepository? repository, }) async => await _$PizzaFromSqlite(input, provider: provider, repository: repository); @override Future> toSqlite( Pizza input, { - required provider, + required SqliteProvider provider, covariant OfflineFirstWithSupabaseRepository? repository, }) async => await _$PizzaToSqlite(input, provider: provider, repository: repository); @@ -333,22 +324,18 @@ class CustomerAdapter extends OfflineFirstWithSupabaseAdapter { @override final fieldsToSupabaseColumns = { 'id': const RuntimeSupabaseColumnDefinition( - association: false, columnName: 'id', ), 'firstName': const RuntimeSupabaseColumnDefinition( - association: false, columnName: 'first_name', ), 'lastName': const RuntimeSupabaseColumnDefinition( - association: false, columnName: 'last_name', ), 'pizzas': const RuntimeSupabaseColumnDefinition( association: true, columnName: 'pizzas', associationType: Pizza, - associationIsNullable: false, ), }; @override @@ -358,27 +345,19 @@ class CustomerAdapter extends OfflineFirstWithSupabaseAdapter { @override final Map fieldsToSqliteColumns = { 'primaryKey': const RuntimeSqliteColumnDefinition( - association: false, columnName: '_brick_id', - iterable: false, type: int, ), 'id': const RuntimeSqliteColumnDefinition( - association: false, columnName: 'id', - iterable: false, type: int, ), 'firstName': const RuntimeSqliteColumnDefinition( - association: false, columnName: 'first_name', - iterable: false, type: String, ), 'lastName': const RuntimeSqliteColumnDefinition( - association: false, columnName: 'last_name', - iterable: false, type: String, ), 'pizzas': const RuntimeSqliteColumnDefinition( @@ -401,13 +380,17 @@ class CustomerAdapter extends OfflineFirstWithSupabaseAdapter { return null; } - return results.first['_brick_id'] as int; + return results.first['_brick_id']! as int; } @override final String tableName = 'Customer'; @override - Future afterSave(instance, {required provider, repository}) async { + Future afterSave( + Customer instance, { + required SqliteProvider provider, + ModelRepository? repository, + }) async { if (instance.primaryKey != null) { final pizzasOldColumns = await provider.rawQuery( 'SELECT `f_Pizza_brick_id` FROM `_brick_Customer_pizzas` WHERE `l_Customer_brick_id` = ?', @@ -441,28 +424,28 @@ class CustomerAdapter extends OfflineFirstWithSupabaseAdapter { @override Future fromSupabase( Map input, { - required provider, + required SupabaseProvider provider, covariant OfflineFirstWithSupabaseRepository? repository, }) async => await _$CustomerFromSupabase(input, provider: provider, repository: repository); @override Future> toSupabase( Customer input, { - required provider, + required SupabaseProvider provider, covariant OfflineFirstWithSupabaseRepository? repository, }) async => await _$CustomerToSupabase(input, provider: provider, repository: repository); @override Future fromSqlite( Map input, { - required provider, + required SqliteProvider provider, covariant OfflineFirstWithSupabaseRepository? repository, }) async => await _$CustomerFromSqlite(input, provider: provider, repository: repository); @override Future> toSqlite( Customer input, { - required provider, + required SqliteProvider provider, covariant OfflineFirstWithSupabaseRepository? repository, }) async => await _$CustomerToSqlite(input, provider: provider, repository: repository); @@ -477,14 +460,12 @@ const List _migration_20240906052847_up = [ 'Customer', foreignKeyColumn: 'l_Customer_brick_id', onDeleteCascade: true, - onDeleteSetDefault: false, ), InsertForeignKey( '_brick_Customer_pizzas', 'Pizza', foreignKeyColumn: 'f_Pizza_brick_id', onDeleteCascade: true, - onDeleteSetDefault: false, ), InsertColumn('id', Column.integer, onTable: 'Customer', unique: true), InsertColumn('first_name', Column.varchar, onTable: 'Customer'), diff --git a/packages/brick_offline_first_with_supabase/test/offline_first_with_supabase_repository_test.dart b/packages/brick_offline_first_with_supabase/test/offline_first_with_supabase_repository_test.dart index a5c0f750..7e68c58a 100644 --- a/packages/brick_offline_first_with_supabase/test/offline_first_with_supabase_repository_test.dart +++ b/packages/brick_offline_first_with_supabase/test/offline_first_with_supabase_repository_test.dart @@ -24,7 +24,7 @@ class TestRepository extends OfflineFirstWithSupabaseRepository { }, ); - static TestRepository configure(SupabaseMockServer mock) { + factory TestRepository.configure(SupabaseMockServer mock) { final (client, queue) = OfflineFirstWithSupabaseRepository.clientQueue( databaseFactory: databaseFactoryFfi, reattemptForStatusCodes: [], @@ -69,7 +69,7 @@ void main() async { group('#get', () { test('stores locally', () async { - final req = SupabaseRequest(); + const req = SupabaseRequest(); final resp = SupabaseResponse([ await mock.serialize( Customer( @@ -98,8 +98,8 @@ void main() async { }; final supabaseDefinitions = { - 'id': RuntimeSupabaseColumnDefinition(columnName: 'id'), - 'name': RuntimeSupabaseColumnDefinition(columnName: 'name'), + 'id': const RuntimeSupabaseColumnDefinition(columnName: 'id'), + 'name': const RuntimeSupabaseColumnDefinition(columnName: 'name'), }; final query = repository.queryFromSupabaseDeletePayload( @@ -120,8 +120,8 @@ void main() async { }; final supabaseDefinitions = { - 'id': RuntimeSupabaseColumnDefinition(columnName: 'id'), - 'name': RuntimeSupabaseColumnDefinition(columnName: 'name'), + 'id': const RuntimeSupabaseColumnDefinition(columnName: 'id'), + 'name': const RuntimeSupabaseColumnDefinition(columnName: 'name'), }; final query = repository.queryFromSupabaseDeletePayload( @@ -138,7 +138,7 @@ void main() async { test('empty payload', () { final payload = {}; final supabaseDefinitions = { - 'id': RuntimeSupabaseColumnDefinition(columnName: 'id'), + 'id': const RuntimeSupabaseColumnDefinition(columnName: 'id'), }; final query = repository.queryFromSupabaseDeletePayload( @@ -154,7 +154,7 @@ void main() async { 'unknown_field': 'some value', }; final supabaseDefinitions = { - 'id': RuntimeSupabaseColumnDefinition(columnName: 'id'), + 'id': const RuntimeSupabaseColumnDefinition(columnName: 'id'), }; final query = repository.queryFromSupabaseDeletePayload( @@ -171,8 +171,8 @@ void main() async { }; final supabaseDefinitions = { - 'id': RuntimeSupabaseColumnDefinition(columnName: 'user_id'), - 'name': RuntimeSupabaseColumnDefinition(columnName: 'full_name'), + 'id': const RuntimeSupabaseColumnDefinition(columnName: 'user_id'), + 'name': const RuntimeSupabaseColumnDefinition(columnName: 'full_name'), }; final query = repository.queryFromSupabaseDeletePayload( @@ -193,8 +193,8 @@ void main() async { }; final supabaseDefinitions = { - 'id': RuntimeSupabaseColumnDefinition(columnName: 'user_id'), - 'name': RuntimeSupabaseColumnDefinition(columnName: 'full_name'), + 'id': const RuntimeSupabaseColumnDefinition(columnName: 'user_id'), + 'name': const RuntimeSupabaseColumnDefinition(columnName: 'full_name'), }; final query = repository.queryFromSupabaseDeletePayload( @@ -219,7 +219,7 @@ void main() async { }); test('for empty queries', () { - final query = Query(); + const query = Query(); expect(repository.queryToPostgresChangeFilter(query), isNull); }); @@ -231,13 +231,13 @@ void main() async { group('Compare', () { test('.between', () { - final query = Query(where: [Where('firstName').isBetween(1, 2)]); + final query = Query(where: [const Where('firstName').isBetween(1, 2)]); final filter = repository.queryToPostgresChangeFilter(query); expect(filter, isNull); }); test('.doesNotContain', () { - final query = Query(where: [Where('firstName').doesNotContain('Thomas')]); + final query = Query(where: [const Where('firstName').doesNotContain('Thomas')]); final filter = repository.queryToPostgresChangeFilter(query); expect(filter, isNull); }); @@ -252,7 +252,7 @@ void main() async { }); test('.greaterThan', () { - final query = Query(where: [Where('firstName').isGreaterThan('Thomas')]); + final query = Query(where: [const Where('firstName').isGreaterThan('Thomas')]); final filter = repository.queryToPostgresChangeFilter(query); expect(filter!.type, PostgresChangeFilterType.gt); @@ -262,7 +262,7 @@ void main() async { test('.greaterThanOrEqualTo', () { final query = Query( - where: [Where('firstName').isGreaterThanOrEqualTo('Thomas')], + where: [const Where('firstName').isGreaterThanOrEqualTo('Thomas')], ); final filter = repository.queryToPostgresChangeFilter(query); @@ -272,7 +272,7 @@ void main() async { }); test('.lessThan', () { - final query = Query(where: [Where('firstName').isLessThan('Thomas')]); + final query = Query(where: [const Where('firstName').isLessThan('Thomas')]); final filter = repository.queryToPostgresChangeFilter(query); expect(filter!.type, PostgresChangeFilterType.lt); @@ -282,7 +282,7 @@ void main() async { test('.lessThanOrEqualTo', () { final query = Query( - where: [Where('firstName').isLessThanOrEqualTo('Thomas')], + where: [const Where('firstName').isLessThanOrEqualTo('Thomas')], ); final filter = repository.queryToPostgresChangeFilter(query); @@ -292,7 +292,7 @@ void main() async { }); test('.notEqual', () { - final query = Query(where: [Where('firstName').isNot('Thomas')]); + final query = Query(where: [const Where('firstName').isNot('Thomas')]); final filter = repository.queryToPostgresChangeFilter(query); expect(filter!.type, PostgresChangeFilterType.neq); @@ -301,7 +301,7 @@ void main() async { }); test('.contains', () { - final query = Query(where: [Where('firstName').contains('Thomas')]); + final query = Query(where: [const Where('firstName').contains('Thomas')]); final filter = repository.queryToPostgresChangeFilter(query); expect(filter!.type, PostgresChangeFilterType.inFilter); @@ -329,7 +329,7 @@ void main() async { isNotNull, ); await subscription.cancel(); - await Future.delayed(Duration(milliseconds: 10)); + await Future.delayed(const Duration(milliseconds: 10)); }); test('subscription succeeds when policy is non-default .alwaysHydrate', () async { @@ -343,11 +343,11 @@ void main() async { .listen((_) {}); expect(repository.supabaseRealtimeSubscriptions, hasLength(1)); expect( - repository.supabaseRealtimeSubscriptions[Customer]![PostgresChangeEvent.all]!, + repository.supabaseRealtimeSubscriptions[Customer]![PostgresChangeEvent.all], hasLength(1), ); await subscription.cancel(); - await Future.delayed(Duration(milliseconds: 10)); + await Future.delayed(const Duration(milliseconds: 10)); }); test('adds controller and null query to #supabaseRealtimeSubscriptions', () async { @@ -366,7 +366,7 @@ void main() async { isNotNull, ); await subscription.cancel(); - await Future.delayed(Duration(milliseconds: 10)); + await Future.delayed(const Duration(milliseconds: 10)); }); test('cancelling removes from #supabaseRealtimeSubscriptions', () async { @@ -375,7 +375,7 @@ void main() async { expect(repository.supabaseRealtimeSubscriptions[Customer], hasLength(1)); await subscription.cancel(); expect(repository.supabaseRealtimeSubscriptions, hasLength(0)); - await Future.delayed(Duration(milliseconds: 10)); + await Future.delayed(const Duration(milliseconds: 10)); }); test('pausing does not remove from #supabaseRealtimeSubscriptions', () async { @@ -390,7 +390,7 @@ void main() async { isTrue, ); await subscription.cancel(); - await Future.delayed(Duration(milliseconds: 10)); + await Future.delayed(const Duration(milliseconds: 10)); }); }); @@ -438,7 +438,7 @@ void main() async { ]), ); - final req = SupabaseRequest(); + const req = SupabaseRequest(); final resp = SupabaseResponse( await mock.serialize( customer, @@ -480,7 +480,7 @@ void main() async { ]), ); - final req = SupabaseRequest(); + const req = SupabaseRequest(); final resp = SupabaseResponse( await mock.serialize( customer, @@ -530,7 +530,7 @@ void main() async { ]), ); - final req = SupabaseRequest(); + const req = SupabaseRequest(); final resp = SupabaseResponse( await mock.serialize( customer2, @@ -566,7 +566,7 @@ void main() async { ]), ); - final req = SupabaseRequest(); + const req = SupabaseRequest(); final resp = SupabaseResponse( await mock.serialize( customer, @@ -607,7 +607,7 @@ void main() async { ]), ); - final req = SupabaseRequest(); + const req = SupabaseRequest(); final resp = SupabaseResponse( await mock.serialize( customer, @@ -656,7 +656,7 @@ void main() async { ]), ); - final req = SupabaseRequest(); + const req = SupabaseRequest(); final resp = SupabaseResponse( await mock.serialize( customer2, @@ -696,7 +696,7 @@ void main() async { ]), ); - final req = SupabaseRequest(); + const req = SupabaseRequest(); final resp = SupabaseResponse( await mock.serialize( customer1, diff --git a/packages/brick_offline_first_with_supabase_build/lib/brick_offline_first_with_supabase_build.dart b/packages/brick_offline_first_with_supabase_build/lib/brick_offline_first_with_supabase_build.dart index 554c763b..85601d5a 100644 --- a/packages/brick_offline_first_with_supabase_build/lib/brick_offline_first_with_supabase_build.dart +++ b/packages/brick_offline_first_with_supabase_build/lib/brick_offline_first_with_supabase_build.dart @@ -19,22 +19,27 @@ class OfflineFirstSchemaBuilder extends SchemaBuilder AggregateBuilder( +Builder offlineFirstAggregateBuilder(_) => const AggregateBuilder( requiredImports: [ "import 'package:brick_offline_first/brick_offline_first.dart';", "import 'package:brick_core/query.dart';", "import 'package:brick_sqlite/db.dart';", ], ); -Builder offlineFirstAdaptersBuilder(options) => + +/// +Builder offlineFirstAdaptersBuilder(_) => AdapterBuilder(offlineFirstGenerator); -Builder offlineFirstModelDictionaryBuilder(options) => + +/// +Builder offlineFirstModelDictionaryBuilder(_) => ModelDictionaryBuilder( const OfflineFirstModelDictionaryGenerator('Supabase'), expectedImportRemovals: [ @@ -42,5 +47,9 @@ Builder offlineFirstModelDictionaryBuilder(options) => 'import "package:brick_offline_first/brick_offline_first.dart";', ], ); -Builder offlineFirstNewMigrationBuilder(options) => OfflineFirstMigrationBuilder(); -Builder offlineFirstSchemaBuilder(options) => OfflineFirstSchemaBuilder(); + +/// +Builder offlineFirstNewMigrationBuilder(_) => OfflineFirstMigrationBuilder(); + +/// +Builder offlineFirstSchemaBuilder(_) => OfflineFirstSchemaBuilder(); diff --git a/packages/brick_offline_first_with_supabase_build/lib/src/offline_first_supabase_generators.dart b/packages/brick_offline_first_with_supabase_build/lib/src/offline_first_supabase_generators.dart index 24d9a447..974835c2 100644 --- a/packages/brick_offline_first_with_supabase_build/lib/src/offline_first_supabase_generators.dart +++ b/packages/brick_offline_first_with_supabase_build/lib/src/offline_first_supabase_generators.dart @@ -29,7 +29,9 @@ class _OfflineFirstSupabaseDeserialize extends SupabaseDeserialize }) : offlineFirstFields = OfflineFirstFields(element); } +/// class OfflineFirstSupabaseModelSerdesGenerator extends SupabaseModelSerdesGenerator { + /// OfflineFirstSupabaseModelSerdesGenerator( super.element, super.reader, { diff --git a/packages/brick_offline_first_with_supabase_build/lib/src/offline_first_with_supabase_generator.dart b/packages/brick_offline_first_with_supabase_build/lib/src/offline_first_with_supabase_generator.dart index 2c28f043..b6a1426a 100644 --- a/packages/brick_offline_first_with_supabase_build/lib/src/offline_first_with_supabase_generator.dart +++ b/packages/brick_offline_first_with_supabase_build/lib/src/offline_first_with_supabase_generator.dart @@ -5,8 +5,10 @@ import 'package:brick_offline_first_with_supabase/brick_offline_first_with_supab import 'package:brick_offline_first_with_supabase_build/src/offline_first_supabase_generators.dart'; import 'package:source_gen/source_gen.dart'; +/// class OfflineFirstWithSupabaseGenerator extends OfflineFirstGenerator { + /// const OfflineFirstWithSupabaseGenerator({ super.repositoryName, super.superAdapterName, @@ -22,9 +24,6 @@ class OfflineFirstWithSupabaseGenerator ); final sqlite = OfflineFirstSqliteModelSerdesGenerator(element, annotation, repositoryName: repositoryName); - final generators = []; - generators.addAll(supabase.generators); - generators.addAll(sqlite.generators); - return generators; + return [...supabase.generators, ...sqlite.generators]; } } diff --git a/packages/brick_offline_first_with_supabase_build/pubspec.yaml b/packages/brick_offline_first_with_supabase_build/pubspec.yaml index 024a91bb..36973292 100644 --- a/packages/brick_offline_first_with_supabase_build/pubspec.yaml +++ b/packages/brick_offline_first_with_supabase_build/pubspec.yaml @@ -15,10 +15,10 @@ dependencies: brick_offline_first: ">=3.0.0 <4.0.0" brick_offline_first_build: ">=3.2.0 <4.0.0" brick_offline_first_with_supabase: ">=1.0.0 <2.0.0" - brick_supabase: ">=1.0.0 <2.0.0" - brick_supabase_generators: ">=1.0.0 <2.0.0" brick_sqlite: ">=3.0.0 <4.0.0" brick_sqlite_generators: ">=3.0.0 <4.0.0" + brick_supabase: ">=1.0.0 <2.0.0" + brick_supabase_generators: ">=1.0.0 <2.0.0" build: ">=2.0.0 <3.0.0" dart_style: ">=2.0.0 <3.0.0" logging: ">=1.0.0 <2.0.0" @@ -27,9 +27,9 @@ dependencies: source_gen: ">=1.2.2 <2.0.0" dev_dependencies: - build_verify: ^2.0.0 - source_gen_test: ^1.0.0 - test: ^1.20.1 - lints: ^2.0.1 brick_build_test: path: ../brick_build_test + build_verify: + lints: + source_gen_test: + test: diff --git a/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_default_to_null.dart b/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_default_to_null.dart index 9b66ed47..2186e490 100644 --- a/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_default_to_null.dart +++ b/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_default_to_null.dart @@ -2,7 +2,7 @@ import 'package:brick_offline_first/brick_offline_first.dart'; import 'package:brick_offline_first_with_supabase/brick_offline_first_with_supabase.dart'; import 'package:brick_supabase/brick_supabase.dart'; -final output = r''' +const output = r''' // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_field_name.dart b/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_field_name.dart index 61d91e53..329a3d0a 100644 --- a/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_field_name.dart +++ b/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_field_name.dart @@ -2,7 +2,7 @@ import 'package:brick_offline_first_with_supabase/brick_offline_first_with_supab import 'package:brick_sqlite/brick_sqlite.dart'; import 'package:brick_supabase/brick_supabase.dart'; -final output = r''' +const output = r''' Future _$SpecifyFieldNameFromSupabase( Map data, {required SupabaseProvider provider, diff --git a/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_field_rename.dart b/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_field_rename.dart index a8b23e3a..a1242560 100644 --- a/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_field_rename.dart +++ b/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_field_rename.dart @@ -2,7 +2,7 @@ import 'package:brick_offline_first/brick_offline_first.dart'; import 'package:brick_offline_first_with_supabase/brick_offline_first_with_supabase.dart'; import 'package:brick_supabase/brick_supabase.dart'; -final output = r''' +const output = r''' Future _$SupabaseDefaultFromSupabase(Map data, {required SupabaseProvider provider, OfflineFirstRepository? repository}) async { @@ -176,7 +176,7 @@ Future> _$SupabaseRenameWithOverrideToSqlite( '''; @ConnectOfflineFirstWithSupabase( - supabaseConfig: SupabaseSerializable(), + supabaseConfig: SupabaseSerializable.defaults, ) class SupabaseDefault extends OfflineFirstModel { final int someLongField; @@ -194,7 +194,7 @@ class SupabaseNoRename extends OfflineFirstModel { } @ConnectOfflineFirstWithSupabase( - supabaseConfig: SupabaseSerializable(fieldRename: FieldRename.snake), + supabaseConfig: SupabaseSerializable.defaults, ) class SupabaseSnakeRename extends OfflineFirstModel { final int someLongField; diff --git a/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_ignore_duplicates.dart b/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_ignore_duplicates.dart index fdb79efc..85e56b16 100644 --- a/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_ignore_duplicates.dart +++ b/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_ignore_duplicates.dart @@ -2,7 +2,7 @@ import 'package:brick_offline_first/brick_offline_first.dart'; import 'package:brick_offline_first_with_supabase/brick_offline_first_with_supabase.dart'; import 'package:brick_supabase/brick_supabase.dart'; -final output = r''' +const output = r''' // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_offline_first_where.dart b/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_offline_first_where.dart index 20f0e33d..a712e746 100644 --- a/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_offline_first_where.dart +++ b/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_offline_first_where.dart @@ -2,7 +2,7 @@ import 'package:brick_offline_first/brick_offline_first.dart'; import 'package:brick_offline_first_with_supabase/brick_offline_first_with_supabase.dart'; import 'package:brick_supabase/brick_supabase.dart'; -final output = r''' +const output = r''' // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_on_conflict.dart b/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_on_conflict.dart index 50374685..dd3d5150 100644 --- a/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_on_conflict.dart +++ b/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_on_conflict.dart @@ -2,7 +2,7 @@ import 'package:brick_offline_first/brick_offline_first.dart'; import 'package:brick_offline_first_with_supabase/brick_offline_first_with_supabase.dart'; import 'package:brick_supabase/brick_supabase.dart'; -final output = r''' +const output = r''' // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_table_name_defined.dart b/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_table_name_defined.dart index 9e8f9143..2dc618a3 100644 --- a/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_table_name_defined.dart +++ b/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_table_name_defined.dart @@ -2,7 +2,7 @@ import 'package:brick_offline_first/brick_offline_first.dart'; import 'package:brick_offline_first_with_supabase/brick_offline_first_with_supabase.dart'; import 'package:brick_supabase/brick_supabase.dart'; -final output = r''' +const output = r''' // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_table_name_undefined.dart b/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_table_name_undefined.dart index 530620b2..183fca3b 100644 --- a/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_table_name_undefined.dart +++ b/packages/brick_offline_first_with_supabase_build/test/offline_first_generator/test_table_name_undefined.dart @@ -2,7 +2,7 @@ import 'package:brick_offline_first/brick_offline_first.dart'; import 'package:brick_offline_first_with_supabase/brick_offline_first_with_supabase.dart'; import 'package:brick_supabase/brick_supabase.dart'; -final output = r''' +const output = r''' // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; @@ -105,7 +105,7 @@ class UndefinedCamelizedNameAdapter '''; @ConnectOfflineFirstWithSupabase( - supabaseConfig: SupabaseSerializable(), + supabaseConfig: SupabaseSerializable.defaults, ) class UndefinedCamelizedName extends OfflineFirstModel { final int someLongField; diff --git a/packages/brick_offline_first_with_supabase_build/test/offline_first_generator_test.dart b/packages/brick_offline_first_with_supabase_build/test/offline_first_generator_test.dart index a1946473..bd93bcf1 100644 --- a/packages/brick_offline_first_with_supabase_build/test/offline_first_generator_test.dart +++ b/packages/brick_offline_first_with_supabase_build/test/offline_first_generator_test.dart @@ -12,8 +12,8 @@ import 'offline_first_generator/test_on_conflict.dart' as on_conflict; import 'offline_first_generator/test_table_name_defined.dart' as table_name_defined; import 'offline_first_generator/test_table_name_undefined.dart' as table_name_undefined; -final _generator = OfflineFirstWithSupabaseGenerator(); -final folder = 'offline_first_generator'; +const _generator = OfflineFirstWithSupabaseGenerator(); +const folder = 'offline_first_generator'; final generateReader = generateLibraryForFolder(folder); void main() { diff --git a/packages/brick_rest/analysis_options.yaml b/packages/brick_rest/analysis_options.yaml index 5008bf6c..f04c6cf0 100644 --- a/packages/brick_rest/analysis_options.yaml +++ b/packages/brick_rest/analysis_options.yaml @@ -1,326 +1 @@ include: ../../analysis_options.yaml - -linter: - rules: - # This list is derived from the list of all available lints located at - # https://github.com/dart-lang/linter/blob/master/example/all.yaml - - always_declare_return_types - # - always_put_control_body_on_new_line - # - always_put_required_named_parameters_first - # - always_specify_types - - always_use_package_imports - - annotate_overrides - # - avoid_annotating_with_dynamic - - avoid_bool_literals_in_conditional_expressions - # - avoid_catches_without_on_clauses - # - avoid_catching_errors - - avoid_classes_with_only_static_members - - avoid_double_and_int_checks - # - avoid_dynamic_calls - - avoid_empty_else - # - avoid_equals_and_hash_code_on_mutable_classes - - avoid_escaping_inner_quotes - - avoid_field_initializers_in_const_classes - # - avoid_final_parameters - - avoid_function_literals_in_foreach_calls - - avoid_implementing_value_types - - avoid_init_to_null - - avoid_js_rounded_ints - - avoid_multiple_declarations_per_line - - avoid_null_checks_in_equality_operators - # - avoid_positional_boolean_parameters - - avoid_print - - avoid_private_typedef_functions - - avoid_redundant_argument_values - - avoid_relative_lib_imports - - avoid_renaming_method_parameters - - avoid_return_types_on_setters - - avoid_returning_null_for_void - - avoid_returning_this - - avoid_setters_without_getters - - avoid_shadowing_type_parameters - - avoid_single_cascade_in_expression_statements - - avoid_slow_async_io - - avoid_type_to_string - - avoid_types_as_parameter_names - # - avoid_types_on_closure_parameters - - avoid_unnecessary_containers - - avoid_unused_constructor_parameters - - avoid_void_async - - avoid_web_libraries_in_flutter - - await_only_futures - - camel_case_extensions - - camel_case_types - - cancel_subscriptions - - cascade_invocations - - cast_nullable_to_non_nullable - # - close_sinks - - collection_methods_unrelated_type - - combinators_ordering - - comment_references - - conditional_uri_does_not_exist - - constant_identifier_names - - control_flow_in_finally - - curly_braces_in_flow_control_structures - - dangling_library_doc_comments - - depend_on_referenced_packages - - deprecated_consistency - - deprecated_member_use_from_same_package - # - diagnostic_describe_all_properties - - directives_ordering - - discarded_futures - - do_not_use_environment - - empty_catches - - empty_constructor_bodies - - empty_statements - - eol_at_end_of_file - - exhaustive_cases - - file_names - - flutter_style_todos - - hash_and_equals - - implementation_imports - - implicit_call_tearoffs - - implicit_reopen - - invalid_case_patterns - - join_return_with_assignment - # - leading_newlines_in_multiline_strings - - library_annotations - - library_names - - library_prefixes - - library_private_types_in_public_api - # - lines_longer_than_80_chars - - literal_only_boolean_expressions - - matching_super_parameters - - missing_whitespace_between_adjacent_strings - - no_adjacent_strings_in_list - - no_default_cases - - no_duplicate_case_values - - no_leading_underscores_for_library_prefixes - - no_leading_underscores_for_local_identifiers - - no_literal_bool_comparisons - - no_logic_in_create_state - - no_runtimeType_toString - - no_self_assignments - - no_wildcard_variable_uses - - non_constant_identifier_names - - noop_primitive_operations - - null_check_on_nullable_type_parameter - - null_closures - - omit_local_variable_types - - one_member_abstracts - - only_throw_errors - - overridden_fields - - package_api_docs - - package_names - - package_prefixed_library_names - - parameter_assignments - - prefer_adjacent_string_concatenation - - prefer_asserts_in_initializer_lists - - prefer_asserts_with_message - - prefer_collection_literals - - prefer_conditional_assignment - - prefer_const_constructors - - prefer_const_constructors_in_immutables - - prefer_const_declarations - - prefer_const_literals_to_create_immutables - - prefer_constructors_over_static_methods - - prefer_contains - # - prefer_double_quotes - - prefer_expression_function_bodies - - prefer_final_fields - - prefer_final_in_for_each - - prefer_final_locals - # - prefer_final_parameters - - prefer_for_elements_to_map_fromIterable - - prefer_foreach - - prefer_function_declarations_over_variables - - prefer_generic_function_type_aliases - - prefer_if_elements_to_conditional_expressions - - prefer_if_null_operators - - prefer_initializing_formals - - prefer_inlined_adds - - prefer_int_literals - - prefer_interpolation_to_compose_strings - - prefer_is_empty - - prefer_is_not_empty - - prefer_is_not_operator - - prefer_iterable_whereType - - prefer_mixin - - prefer_null_aware_method_calls - - prefer_null_aware_operators - # - prefer_relative_imports - - prefer_single_quotes - - prefer_spread_collections - - prefer_typing_uninitialized_variables - - prefer_void_to_null - - provide_deprecation_message - - public_member_api_docs - - recursive_getters - - require_trailing_commas - - secure_pubspec_urls - - sized_box_for_whitespace - - sized_box_shrink_expand - - slash_for_doc_comments - - sort_child_properties_last - # - sort_constructors_first - - sort_pub_dependencies - - sort_unnamed_constructors_first - - test_types_in_equals - - throw_in_finally - - tighten_type_of_initializing_formals - - type_annotate_public_apis - - type_init_formals - - type_literal_in_constant_pattern - - unawaited_futures - # - unnecessary_await_in_return - - unnecessary_brace_in_string_interps - - unnecessary_breaks - - unnecessary_const - - unnecessary_constructor_name - # - unnecessary_final - - unnecessary_getters_setters - - unnecessary_lambdas - - unnecessary_late - - unnecessary_library_directive - - unnecessary_new - - unnecessary_null_aware_assignments - - unnecessary_null_aware_operator_on_extension_on_nullable - - unnecessary_null_checks - - unnecessary_null_in_if_null_operators - - unnecessary_nullable_for_final_variable_declarations - - unnecessary_overrides - - unnecessary_parenthesis - - unnecessary_raw_strings - - unnecessary_statements - - unnecessary_string_escapes - - unnecessary_string_interpolations - - unnecessary_this - - unnecessary_to_list_in_spreads - # - unreachable_from_main - - unrelated_type_equality_checks - - unsafe_html - - use_build_context_synchronously - - use_colored_box - - use_decorated_box - - use_enums - - use_full_hex_values_for_flutter_colors - - use_function_type_syntax_for_parameters - - use_if_null_to_convert_nulls_to_bools - - use_is_even_rather_than_modulo - - use_key_in_widget_constructors - - use_late_for_private_fields_and_variables - - use_named_constants - - use_raw_strings - - use_rethrow_when_possible - - use_setters_to_change_properties - - use_string_buffers - - use_string_in_part_of_directives - - use_super_parameters - - use_test_throws_matchers - - use_to_and_as_if_applicable - - valid_regexps - - void_checks - -analyzer: - exclude: - - example/ - - "**/example/" - - example_rest - - example_graphql - - "**/*.g.dart" - - errors: - # override custom - always_use_package_imports: error - camel_case_extensions: error - camel_case_types: error - curly_braces_in_flow_control_structures: error - directives_ordering: error - file_names: error - prefer_single_quotes: error - prefer_is_empty: error - prefer_is_not_empty: error - require_trailing_commas: error - sort_pub_dependencies: error - unnecessary_statements: error - - # override flutter_lints - avoid_print: error - avoid_unnecessary_containers: error - avoid_web_libraries_in_flutter: error - no_logic_in_create_state: error - prefer_const_constructors: error - prefer_const_constructors_in_immutables: error - prefer_const_declarations: error - prefer_const_literals_to_create_immutables: error - sized_box_for_whitespace: error - sort_child_properties_last: error - use_build_context_synchronously: error - use_full_hex_values_for_flutter_colors: error - use_key_in_widget_constructors: error - - # override recommended lints - always_require_non_null_named_parameters: error - annotate_overrides: error - avoid_function_literals_in_foreach_calls: error - avoid_init_to_null: error - avoid_null_checks_in_equality_operators: error - avoid_renaming_method_parameters: error - avoid_return_types_on_setters: error - avoid_returning_null_for_void: error - avoid_single_cascade_in_expression_statements: error - await_only_futures: error - constant_identifier_names: error - control_flow_in_finally: error - depend_on_referenced_packages: ignore - empty_constructor_bodies: error - empty_statements: error - exhaustive_cases: error - implementation_imports: ignore - invalid_case_patterns: error - library_names: error - library_prefixes: error - library_private_types_in_public_api: error - matching_super_parameters: error - no_leading_underscores_for_library_prefixes: error - no_leading_underscores_for_local_identifiers: error - no_literal_bool_comparisons: error - null_check_on_nullable_type_parameter: error - null_closures: error - overridden_fields: error - package_names: error - prefer_adjacent_string_concatenation: error - prefer_collection_literals: error - prefer_conditional_assignment: error - prefer_contains: error - prefer_equal_for_default_values: error - prefer_final_fields: error - prefer_for_elements_to_map_fromIterable: error - prefer_function_declarations_over_variables: error - prefer_if_null_operators: error - prefer_initializing_formals: error - prefer_inlined_adds: error - prefer_interpolation_to_compose_strings: error - prefer_is_not_operator: error - prefer_null_aware_operators: error - prefer_spread_collections: error - prefer_void_to_null: error - recursive_getters: error - slash_for_doc_comments: error - type_init_formals: error - type_literal_in_constant_pattern: error - unnecessary_brace_in_string_interps: error - unnecessary_breaks: error - unnecessary_const: error - unnecessary_constructor_name: error - unnecessary_getters_setters: error - unnecessary_late: error - unnecessary_new: error - unnecessary_null_aware_assignments: error - unnecessary_null_in_if_null_operators: error - unnecessary_nullable_for_final_variable_declarations: error - unnecessary_string_escapes: error - unnecessary_string_interpolations: error - unnecessary_this: error - use_function_type_syntax_for_parameters: error - use_rethrow_when_possible: error diff --git a/packages/brick_rest/lib/src/rest_provider_query.dart b/packages/brick_rest/lib/src/rest_provider_query.dart index 428e5706..0b837801 100644 --- a/packages/brick_rest/lib/src/rest_provider_query.dart +++ b/packages/brick_rest/lib/src/rest_provider_query.dart @@ -12,6 +12,14 @@ class RestProviderQuery extends ProviderQuery { this.request, }); + /// Creates a copy of this [RestProviderQuery] with the given fields replaced. + RestProviderQuery copyWith({ + RestRequest? request, + }) => + RestProviderQuery( + request: request ?? this.request, + ); + @override Map toJson() => { if (request != null) 'request': request?.toJson(), diff --git a/packages/brick_rest/lib/src/rest_request.dart b/packages/brick_rest/lib/src/rest_request.dart index 2f098b64..0921210a 100644 --- a/packages/brick_rest/lib/src/rest_request.dart +++ b/packages/brick_rest/lib/src/rest_request.dart @@ -56,6 +56,22 @@ class RestRequest { url: data['url'], ); + /// Copy a request with overriden parameters + RestRequest copyWith({ + Map? headers, + String? method, + Map? supplementalTopLevelData, + String? topLevelKey, + String? url, + }) => + RestRequest( + headers: headers ?? this.headers, + method: method ?? this.method, + supplementalTopLevelData: supplementalTopLevelData ?? this.supplementalTopLevelData, + topLevelKey: topLevelKey ?? this.topLevelKey, + url: url ?? this.url, + ); + /// Serialize a request to JSON Map toJson() => { 'headers': headers, diff --git a/packages/brick_rest_generators/analysis_options.yaml b/packages/brick_rest_generators/analysis_options.yaml index 5008bf6c..f04c6cf0 100644 --- a/packages/brick_rest_generators/analysis_options.yaml +++ b/packages/brick_rest_generators/analysis_options.yaml @@ -1,326 +1 @@ include: ../../analysis_options.yaml - -linter: - rules: - # This list is derived from the list of all available lints located at - # https://github.com/dart-lang/linter/blob/master/example/all.yaml - - always_declare_return_types - # - always_put_control_body_on_new_line - # - always_put_required_named_parameters_first - # - always_specify_types - - always_use_package_imports - - annotate_overrides - # - avoid_annotating_with_dynamic - - avoid_bool_literals_in_conditional_expressions - # - avoid_catches_without_on_clauses - # - avoid_catching_errors - - avoid_classes_with_only_static_members - - avoid_double_and_int_checks - # - avoid_dynamic_calls - - avoid_empty_else - # - avoid_equals_and_hash_code_on_mutable_classes - - avoid_escaping_inner_quotes - - avoid_field_initializers_in_const_classes - # - avoid_final_parameters - - avoid_function_literals_in_foreach_calls - - avoid_implementing_value_types - - avoid_init_to_null - - avoid_js_rounded_ints - - avoid_multiple_declarations_per_line - - avoid_null_checks_in_equality_operators - # - avoid_positional_boolean_parameters - - avoid_print - - avoid_private_typedef_functions - - avoid_redundant_argument_values - - avoid_relative_lib_imports - - avoid_renaming_method_parameters - - avoid_return_types_on_setters - - avoid_returning_null_for_void - - avoid_returning_this - - avoid_setters_without_getters - - avoid_shadowing_type_parameters - - avoid_single_cascade_in_expression_statements - - avoid_slow_async_io - - avoid_type_to_string - - avoid_types_as_parameter_names - # - avoid_types_on_closure_parameters - - avoid_unnecessary_containers - - avoid_unused_constructor_parameters - - avoid_void_async - - avoid_web_libraries_in_flutter - - await_only_futures - - camel_case_extensions - - camel_case_types - - cancel_subscriptions - - cascade_invocations - - cast_nullable_to_non_nullable - # - close_sinks - - collection_methods_unrelated_type - - combinators_ordering - - comment_references - - conditional_uri_does_not_exist - - constant_identifier_names - - control_flow_in_finally - - curly_braces_in_flow_control_structures - - dangling_library_doc_comments - - depend_on_referenced_packages - - deprecated_consistency - - deprecated_member_use_from_same_package - # - diagnostic_describe_all_properties - - directives_ordering - - discarded_futures - - do_not_use_environment - - empty_catches - - empty_constructor_bodies - - empty_statements - - eol_at_end_of_file - - exhaustive_cases - - file_names - - flutter_style_todos - - hash_and_equals - - implementation_imports - - implicit_call_tearoffs - - implicit_reopen - - invalid_case_patterns - - join_return_with_assignment - # - leading_newlines_in_multiline_strings - - library_annotations - - library_names - - library_prefixes - - library_private_types_in_public_api - # - lines_longer_than_80_chars - - literal_only_boolean_expressions - - matching_super_parameters - - missing_whitespace_between_adjacent_strings - - no_adjacent_strings_in_list - - no_default_cases - - no_duplicate_case_values - - no_leading_underscores_for_library_prefixes - - no_leading_underscores_for_local_identifiers - - no_literal_bool_comparisons - - no_logic_in_create_state - - no_runtimeType_toString - - no_self_assignments - - no_wildcard_variable_uses - - non_constant_identifier_names - - noop_primitive_operations - - null_check_on_nullable_type_parameter - - null_closures - - omit_local_variable_types - - one_member_abstracts - - only_throw_errors - - overridden_fields - - package_api_docs - - package_names - - package_prefixed_library_names - - parameter_assignments - - prefer_adjacent_string_concatenation - - prefer_asserts_in_initializer_lists - - prefer_asserts_with_message - - prefer_collection_literals - - prefer_conditional_assignment - - prefer_const_constructors - - prefer_const_constructors_in_immutables - - prefer_const_declarations - - prefer_const_literals_to_create_immutables - - prefer_constructors_over_static_methods - - prefer_contains - # - prefer_double_quotes - - prefer_expression_function_bodies - - prefer_final_fields - - prefer_final_in_for_each - - prefer_final_locals - # - prefer_final_parameters - - prefer_for_elements_to_map_fromIterable - - prefer_foreach - - prefer_function_declarations_over_variables - - prefer_generic_function_type_aliases - - prefer_if_elements_to_conditional_expressions - - prefer_if_null_operators - - prefer_initializing_formals - - prefer_inlined_adds - - prefer_int_literals - - prefer_interpolation_to_compose_strings - - prefer_is_empty - - prefer_is_not_empty - - prefer_is_not_operator - - prefer_iterable_whereType - - prefer_mixin - - prefer_null_aware_method_calls - - prefer_null_aware_operators - # - prefer_relative_imports - - prefer_single_quotes - - prefer_spread_collections - - prefer_typing_uninitialized_variables - - prefer_void_to_null - - provide_deprecation_message - - public_member_api_docs - - recursive_getters - - require_trailing_commas - - secure_pubspec_urls - - sized_box_for_whitespace - - sized_box_shrink_expand - - slash_for_doc_comments - - sort_child_properties_last - # - sort_constructors_first - - sort_pub_dependencies - - sort_unnamed_constructors_first - - test_types_in_equals - - throw_in_finally - - tighten_type_of_initializing_formals - - type_annotate_public_apis - - type_init_formals - - type_literal_in_constant_pattern - - unawaited_futures - # - unnecessary_await_in_return - - unnecessary_brace_in_string_interps - - unnecessary_breaks - - unnecessary_const - - unnecessary_constructor_name - # - unnecessary_final - - unnecessary_getters_setters - - unnecessary_lambdas - - unnecessary_late - - unnecessary_library_directive - - unnecessary_new - - unnecessary_null_aware_assignments - - unnecessary_null_aware_operator_on_extension_on_nullable - - unnecessary_null_checks - - unnecessary_null_in_if_null_operators - - unnecessary_nullable_for_final_variable_declarations - - unnecessary_overrides - - unnecessary_parenthesis - - unnecessary_raw_strings - - unnecessary_statements - - unnecessary_string_escapes - - unnecessary_string_interpolations - - unnecessary_this - - unnecessary_to_list_in_spreads - # - unreachable_from_main - - unrelated_type_equality_checks - - unsafe_html - - use_build_context_synchronously - - use_colored_box - - use_decorated_box - - use_enums - - use_full_hex_values_for_flutter_colors - - use_function_type_syntax_for_parameters - - use_if_null_to_convert_nulls_to_bools - - use_is_even_rather_than_modulo - - use_key_in_widget_constructors - - use_late_for_private_fields_and_variables - - use_named_constants - - use_raw_strings - - use_rethrow_when_possible - - use_setters_to_change_properties - - use_string_buffers - - use_string_in_part_of_directives - - use_super_parameters - - use_test_throws_matchers - - use_to_and_as_if_applicable - - valid_regexps - - void_checks - -analyzer: - exclude: - - example/ - - "**/example/" - - example_rest - - example_graphql - - "**/*.g.dart" - - errors: - # override custom - always_use_package_imports: error - camel_case_extensions: error - camel_case_types: error - curly_braces_in_flow_control_structures: error - directives_ordering: error - file_names: error - prefer_single_quotes: error - prefer_is_empty: error - prefer_is_not_empty: error - require_trailing_commas: error - sort_pub_dependencies: error - unnecessary_statements: error - - # override flutter_lints - avoid_print: error - avoid_unnecessary_containers: error - avoid_web_libraries_in_flutter: error - no_logic_in_create_state: error - prefer_const_constructors: error - prefer_const_constructors_in_immutables: error - prefer_const_declarations: error - prefer_const_literals_to_create_immutables: error - sized_box_for_whitespace: error - sort_child_properties_last: error - use_build_context_synchronously: error - use_full_hex_values_for_flutter_colors: error - use_key_in_widget_constructors: error - - # override recommended lints - always_require_non_null_named_parameters: error - annotate_overrides: error - avoid_function_literals_in_foreach_calls: error - avoid_init_to_null: error - avoid_null_checks_in_equality_operators: error - avoid_renaming_method_parameters: error - avoid_return_types_on_setters: error - avoid_returning_null_for_void: error - avoid_single_cascade_in_expression_statements: error - await_only_futures: error - constant_identifier_names: error - control_flow_in_finally: error - depend_on_referenced_packages: ignore - empty_constructor_bodies: error - empty_statements: error - exhaustive_cases: error - implementation_imports: ignore - invalid_case_patterns: error - library_names: error - library_prefixes: error - library_private_types_in_public_api: error - matching_super_parameters: error - no_leading_underscores_for_library_prefixes: error - no_leading_underscores_for_local_identifiers: error - no_literal_bool_comparisons: error - null_check_on_nullable_type_parameter: error - null_closures: error - overridden_fields: error - package_names: error - prefer_adjacent_string_concatenation: error - prefer_collection_literals: error - prefer_conditional_assignment: error - prefer_contains: error - prefer_equal_for_default_values: error - prefer_final_fields: error - prefer_for_elements_to_map_fromIterable: error - prefer_function_declarations_over_variables: error - prefer_if_null_operators: error - prefer_initializing_formals: error - prefer_inlined_adds: error - prefer_interpolation_to_compose_strings: error - prefer_is_not_operator: error - prefer_null_aware_operators: error - prefer_spread_collections: error - prefer_void_to_null: error - recursive_getters: error - slash_for_doc_comments: error - type_init_formals: error - type_literal_in_constant_pattern: error - unnecessary_brace_in_string_interps: error - unnecessary_breaks: error - unnecessary_const: error - unnecessary_constructor_name: error - unnecessary_getters_setters: error - unnecessary_late: error - unnecessary_new: error - unnecessary_null_aware_assignments: error - unnecessary_null_in_if_null_operators: error - unnecessary_nullable_for_final_variable_declarations: error - unnecessary_string_escapes: error - unnecessary_string_interpolations: error - unnecessary_this: error - use_function_type_syntax_for_parameters: error - use_rethrow_when_possible: error diff --git a/packages/brick_sqlite/analysis_options.yaml b/packages/brick_sqlite/analysis_options.yaml index 5008bf6c..f04c6cf0 100644 --- a/packages/brick_sqlite/analysis_options.yaml +++ b/packages/brick_sqlite/analysis_options.yaml @@ -1,326 +1 @@ include: ../../analysis_options.yaml - -linter: - rules: - # This list is derived from the list of all available lints located at - # https://github.com/dart-lang/linter/blob/master/example/all.yaml - - always_declare_return_types - # - always_put_control_body_on_new_line - # - always_put_required_named_parameters_first - # - always_specify_types - - always_use_package_imports - - annotate_overrides - # - avoid_annotating_with_dynamic - - avoid_bool_literals_in_conditional_expressions - # - avoid_catches_without_on_clauses - # - avoid_catching_errors - - avoid_classes_with_only_static_members - - avoid_double_and_int_checks - # - avoid_dynamic_calls - - avoid_empty_else - # - avoid_equals_and_hash_code_on_mutable_classes - - avoid_escaping_inner_quotes - - avoid_field_initializers_in_const_classes - # - avoid_final_parameters - - avoid_function_literals_in_foreach_calls - - avoid_implementing_value_types - - avoid_init_to_null - - avoid_js_rounded_ints - - avoid_multiple_declarations_per_line - - avoid_null_checks_in_equality_operators - # - avoid_positional_boolean_parameters - - avoid_print - - avoid_private_typedef_functions - - avoid_redundant_argument_values - - avoid_relative_lib_imports - - avoid_renaming_method_parameters - - avoid_return_types_on_setters - - avoid_returning_null_for_void - - avoid_returning_this - - avoid_setters_without_getters - - avoid_shadowing_type_parameters - - avoid_single_cascade_in_expression_statements - - avoid_slow_async_io - - avoid_type_to_string - - avoid_types_as_parameter_names - # - avoid_types_on_closure_parameters - - avoid_unnecessary_containers - - avoid_unused_constructor_parameters - - avoid_void_async - - avoid_web_libraries_in_flutter - - await_only_futures - - camel_case_extensions - - camel_case_types - - cancel_subscriptions - - cascade_invocations - - cast_nullable_to_non_nullable - # - close_sinks - - collection_methods_unrelated_type - - combinators_ordering - - comment_references - - conditional_uri_does_not_exist - - constant_identifier_names - - control_flow_in_finally - - curly_braces_in_flow_control_structures - - dangling_library_doc_comments - - depend_on_referenced_packages - - deprecated_consistency - - deprecated_member_use_from_same_package - # - diagnostic_describe_all_properties - - directives_ordering - - discarded_futures - - do_not_use_environment - - empty_catches - - empty_constructor_bodies - - empty_statements - - eol_at_end_of_file - - exhaustive_cases - - file_names - - flutter_style_todos - - hash_and_equals - - implementation_imports - - implicit_call_tearoffs - - implicit_reopen - - invalid_case_patterns - - join_return_with_assignment - # - leading_newlines_in_multiline_strings - - library_annotations - - library_names - - library_prefixes - - library_private_types_in_public_api - # - lines_longer_than_80_chars - - literal_only_boolean_expressions - - matching_super_parameters - - missing_whitespace_between_adjacent_strings - - no_adjacent_strings_in_list - - no_default_cases - - no_duplicate_case_values - - no_leading_underscores_for_library_prefixes - - no_leading_underscores_for_local_identifiers - - no_literal_bool_comparisons - - no_logic_in_create_state - - no_runtimeType_toString - - no_self_assignments - - no_wildcard_variable_uses - - non_constant_identifier_names - - noop_primitive_operations - - null_check_on_nullable_type_parameter - - null_closures - - omit_local_variable_types - - one_member_abstracts - - only_throw_errors - - overridden_fields - - package_api_docs - - package_names - - package_prefixed_library_names - - parameter_assignments - - prefer_adjacent_string_concatenation - - prefer_asserts_in_initializer_lists - - prefer_asserts_with_message - - prefer_collection_literals - - prefer_conditional_assignment - - prefer_const_constructors - - prefer_const_constructors_in_immutables - - prefer_const_declarations - - prefer_const_literals_to_create_immutables - - prefer_constructors_over_static_methods - - prefer_contains - # - prefer_double_quotes - - prefer_expression_function_bodies - - prefer_final_fields - - prefer_final_in_for_each - - prefer_final_locals - # - prefer_final_parameters - - prefer_for_elements_to_map_fromIterable - - prefer_foreach - - prefer_function_declarations_over_variables - - prefer_generic_function_type_aliases - - prefer_if_elements_to_conditional_expressions - - prefer_if_null_operators - - prefer_initializing_formals - - prefer_inlined_adds - - prefer_int_literals - - prefer_interpolation_to_compose_strings - - prefer_is_empty - - prefer_is_not_empty - - prefer_is_not_operator - - prefer_iterable_whereType - - prefer_mixin - - prefer_null_aware_method_calls - - prefer_null_aware_operators - # - prefer_relative_imports - - prefer_single_quotes - - prefer_spread_collections - - prefer_typing_uninitialized_variables - - prefer_void_to_null - - provide_deprecation_message - - public_member_api_docs - - recursive_getters - - require_trailing_commas - - secure_pubspec_urls - - sized_box_for_whitespace - - sized_box_shrink_expand - - slash_for_doc_comments - - sort_child_properties_last - # - sort_constructors_first - - sort_pub_dependencies - - sort_unnamed_constructors_first - - test_types_in_equals - - throw_in_finally - - tighten_type_of_initializing_formals - - type_annotate_public_apis - - type_init_formals - - type_literal_in_constant_pattern - - unawaited_futures - # - unnecessary_await_in_return - - unnecessary_brace_in_string_interps - - unnecessary_breaks - - unnecessary_const - - unnecessary_constructor_name - # - unnecessary_final - - unnecessary_getters_setters - - unnecessary_lambdas - - unnecessary_late - - unnecessary_library_directive - - unnecessary_new - - unnecessary_null_aware_assignments - - unnecessary_null_aware_operator_on_extension_on_nullable - - unnecessary_null_checks - - unnecessary_null_in_if_null_operators - - unnecessary_nullable_for_final_variable_declarations - - unnecessary_overrides - - unnecessary_parenthesis - - unnecessary_raw_strings - - unnecessary_statements - - unnecessary_string_escapes - - unnecessary_string_interpolations - - unnecessary_this - - unnecessary_to_list_in_spreads - # - unreachable_from_main - - unrelated_type_equality_checks - - unsafe_html - - use_build_context_synchronously - - use_colored_box - - use_decorated_box - - use_enums - - use_full_hex_values_for_flutter_colors - - use_function_type_syntax_for_parameters - - use_if_null_to_convert_nulls_to_bools - - use_is_even_rather_than_modulo - - use_key_in_widget_constructors - - use_late_for_private_fields_and_variables - - use_named_constants - - use_raw_strings - - use_rethrow_when_possible - - use_setters_to_change_properties - - use_string_buffers - - use_string_in_part_of_directives - - use_super_parameters - - use_test_throws_matchers - - use_to_and_as_if_applicable - - valid_regexps - - void_checks - -analyzer: - exclude: - - example/ - - "**/example/" - - example_rest - - example_graphql - - "**/*.g.dart" - - errors: - # override custom - always_use_package_imports: error - camel_case_extensions: error - camel_case_types: error - curly_braces_in_flow_control_structures: error - directives_ordering: error - file_names: error - prefer_single_quotes: error - prefer_is_empty: error - prefer_is_not_empty: error - require_trailing_commas: error - sort_pub_dependencies: error - unnecessary_statements: error - - # override flutter_lints - avoid_print: error - avoid_unnecessary_containers: error - avoid_web_libraries_in_flutter: error - no_logic_in_create_state: error - prefer_const_constructors: error - prefer_const_constructors_in_immutables: error - prefer_const_declarations: error - prefer_const_literals_to_create_immutables: error - sized_box_for_whitespace: error - sort_child_properties_last: error - use_build_context_synchronously: error - use_full_hex_values_for_flutter_colors: error - use_key_in_widget_constructors: error - - # override recommended lints - always_require_non_null_named_parameters: error - annotate_overrides: error - avoid_function_literals_in_foreach_calls: error - avoid_init_to_null: error - avoid_null_checks_in_equality_operators: error - avoid_renaming_method_parameters: error - avoid_return_types_on_setters: error - avoid_returning_null_for_void: error - avoid_single_cascade_in_expression_statements: error - await_only_futures: error - constant_identifier_names: error - control_flow_in_finally: error - depend_on_referenced_packages: ignore - empty_constructor_bodies: error - empty_statements: error - exhaustive_cases: error - implementation_imports: ignore - invalid_case_patterns: error - library_names: error - library_prefixes: error - library_private_types_in_public_api: error - matching_super_parameters: error - no_leading_underscores_for_library_prefixes: error - no_leading_underscores_for_local_identifiers: error - no_literal_bool_comparisons: error - null_check_on_nullable_type_parameter: error - null_closures: error - overridden_fields: error - package_names: error - prefer_adjacent_string_concatenation: error - prefer_collection_literals: error - prefer_conditional_assignment: error - prefer_contains: error - prefer_equal_for_default_values: error - prefer_final_fields: error - prefer_for_elements_to_map_fromIterable: error - prefer_function_declarations_over_variables: error - prefer_if_null_operators: error - prefer_initializing_formals: error - prefer_inlined_adds: error - prefer_interpolation_to_compose_strings: error - prefer_is_not_operator: error - prefer_null_aware_operators: error - prefer_spread_collections: error - prefer_void_to_null: error - recursive_getters: error - slash_for_doc_comments: error - type_init_formals: error - type_literal_in_constant_pattern: error - unnecessary_brace_in_string_interps: error - unnecessary_breaks: error - unnecessary_const: error - unnecessary_constructor_name: error - unnecessary_getters_setters: error - unnecessary_late: error - unnecessary_new: error - unnecessary_null_aware_assignments: error - unnecessary_null_in_if_null_operators: error - unnecessary_nullable_for_final_variable_declarations: error - unnecessary_string_escapes: error - unnecessary_string_interpolations: error - unnecessary_this: error - use_function_type_syntax_for_parameters: error - use_rethrow_when_possible: error diff --git a/packages/brick_sqlite_generators/lib/sqlite_model_serdes_generator.dart b/packages/brick_sqlite_generators/lib/sqlite_model_serdes_generator.dart index 2ddc37c4..08c8ca43 100644 --- a/packages/brick_sqlite_generators/lib/sqlite_model_serdes_generator.dart +++ b/packages/brick_sqlite_generators/lib/sqlite_model_serdes_generator.dart @@ -12,6 +12,8 @@ class SqliteModelSerdesGenerator extends ProviderSerializableGenerator extends SqliteBaseBuilder<_ClassAnnotation> { @override final outputExtension = '.migration_builder.dart'; + /// Create a new [Migration] from the contents of all `ConnectOfflineFirstWith` models NewMigrationBuilder(); @override @@ -15,14 +17,13 @@ class NewMigrationBuilder<_ClassAnnotation> extends SqliteBaseBuilder<_ClassAnno final fieldses = await sqliteFieldsFromBuildStep(buildStep); final now = DateTime.now().toUtc(); final timestamp = - [now.month, now.day, now.hour, now.minute, now.second].map(_padToTwo).toList().join(''); + [now.month, now.day, now.hour, now.minute, now.second].map(_padToTwo).toList().join(); final version = int.parse('${now.year}$timestamp'); final output = schemaGenerator.createMigration(libraryReader, fieldses, version: version); if (output == null) return; - final stopwatch = Stopwatch(); - stopwatch.start(); + final stopwatch = Stopwatch()..start(); // in a perfect world, the schema would not be edited in such a brittle way // however, reruning the schema generator here doesn't pick up the new migration diff --git a/packages/brick_sqlite_generators/lib/src/builders/sqlite_base_builder.dart b/packages/brick_sqlite_generators/lib/src/builders/sqlite_base_builder.dart index 3d8a125a..5b3730c8 100644 --- a/packages/brick_sqlite_generators/lib/src/builders/sqlite_base_builder.dart +++ b/packages/brick_sqlite_generators/lib/src/builders/sqlite_base_builder.dart @@ -9,11 +9,15 @@ export 'package:brick_build/src/annotation_super_generator.dart'; const _schemaGenerator = SqliteSchemaGenerator(); +/// abstract class SqliteBaseBuilder<_ClassAnnotation> extends BaseBuilder<_ClassAnnotation> { + /// SqliteSchemaGenerator get schemaGenerator => _schemaGenerator; + /// SqliteBaseBuilder(); + /// Future> sqliteFieldsFromBuildStep(BuildStep buildStep) async { final annotatedElements = await getAnnotatedElements(buildStep); return annotatedElements.where((e) => e.element is ClassElement).map((e) { diff --git a/packages/brick_sqlite_generators/lib/src/builders/sqlite_schema_builder.dart b/packages/brick_sqlite_generators/lib/src/builders/sqlite_schema_builder.dart index a53f8fa7..707237f9 100644 --- a/packages/brick_sqlite_generators/lib/src/builders/sqlite_schema_builder.dart +++ b/packages/brick_sqlite_generators/lib/src/builders/sqlite_schema_builder.dart @@ -1,3 +1,4 @@ +import 'package:brick_sqlite/db.dart'; import 'package:brick_sqlite_generators/src/builders/sqlite_base_builder.dart'; import 'package:build/build.dart'; import 'package:source_gen/source_gen.dart'; @@ -7,12 +8,12 @@ class SchemaBuilder<_ClassAnnotation> extends SqliteBaseBuilder<_ClassAnnotation @override final outputExtension = '.schema_builder.dart'; + /// Write a [Schema] from existing migrations. Outputs to brick/db/schema.g.dart SchemaBuilder(); @override Future build(BuildStep buildStep) async { - final stopwatch = Stopwatch(); - stopwatch.start(); + final stopwatch = Stopwatch()..start(); final libraryReader = LibraryReader(await buildStep.inputLibrary); final fieldses = await sqliteFieldsFromBuildStep(buildStep); diff --git a/packages/brick_sqlite_generators/lib/src/sqlite_deserialize.dart b/packages/brick_sqlite_generators/lib/src/sqlite_deserialize.dart index 4d310a50..59f4104d 100644 --- a/packages/brick_sqlite_generators/lib/src/sqlite_deserialize.dart +++ b/packages/brick_sqlite_generators/lib/src/sqlite_deserialize.dart @@ -1,12 +1,14 @@ import 'package:analyzer/dart/element/element.dart'; import 'package:brick_build/generators.dart' show SerdesGenerator, SharedChecker; +import 'package:brick_core/src/model.dart'; import 'package:brick_sqlite/brick_sqlite.dart'; -import 'package:brick_sqlite/db.dart' show InsertTable, InsertForeignKey; +import 'package:brick_sqlite/db.dart' show InsertForeignKey, InsertTable; import 'package:brick_sqlite_generators/src/sqlite_serdes_generator.dart'; import 'package:source_gen/source_gen.dart' show InvalidGenerationSourceError; /// Generate a function to produce a [ClassElement] from SQLite data class SqliteDeserialize<_Model extends SqliteModel> extends SqliteSerdesGenerator<_Model> { + /// Generate a function to produce a [ClassElement] from SQLite data SqliteDeserialize( super.element, super.fields, { @@ -21,7 +23,11 @@ class SqliteDeserialize<_Model extends SqliteModel> extends SqliteSerdesGenerato "..${InsertTable.PRIMARY_KEY_FIELD} = data['${InsertTable.PRIMARY_KEY_COLUMN}'] as int;"; @override - String deserializerNullableClause({required field, required fieldAnnotation, required name}) { + String deserializerNullableClause({ + required FieldElement field, + required Sqlite fieldAnnotation, + required String name, + }) { final checker = checkerForType(field.type); if (checker.isIterable && checker.isArgTypeASibling) { return ''; @@ -35,7 +41,12 @@ class SqliteDeserialize<_Model extends SqliteModel> extends SqliteSerdesGenerato } @override - String? coderForField(field, checker, {required wrappedInFuture, required fieldAnnotation}) { + String? coderForField( + FieldElement field, + SharedChecker checker, { + required bool wrappedInFuture, + required Sqlite fieldAnnotation, + }) { final fieldValue = serdesValueForField(field, fieldAnnotation.name!, checker: checker); final defaultValue = SerdesGenerator.defaultValueSuffix(fieldAnnotation); if (field.name == InsertTable.PRIMARY_KEY_FIELD) { @@ -81,7 +92,7 @@ class SqliteDeserialize<_Model extends SqliteModel> extends SqliteSerdesGenerato if (checker.isArgTypeASibling) { final awaited = wrappedInFuture ? 'async => await' : '=>'; - final query = ''' + const query = ''' Query.where('${InsertTable.PRIMARY_KEY_FIELD}', ${InsertTable.PRIMARY_KEY_FIELD}, limit1: true), '''; final argTypeAsString = SharedChecker.withoutNullability(argType); @@ -137,7 +148,7 @@ class SqliteDeserialize<_Model extends SqliteModel> extends SqliteSerdesGenerato final discoveredByIndex = 'jsonDecode($fieldValue).map((d) => d as int > -1 ? ${SharedChecker.withoutNullability(argType)}.values[d] : null)'; final nullableSuffix = checker.isNullable ? '?' : ''; - return '$discoveredByIndex$nullableSuffix.whereType<${argType.getDisplayString(withNullability: true)}>()$castIterable'; + return '$discoveredByIndex$nullableSuffix.whereType<${argType.getDisplayString()}>()$castIterable'; } // Iterable @@ -147,12 +158,12 @@ class SqliteDeserialize<_Model extends SqliteModel> extends SqliteSerdesGenerato // Iterable if (argTypeChecker.fromJsonConstructor != null) { - final klass = argTypeChecker.targetType.element as ClassElement; + final klass = argTypeChecker.targetType.element! as ClassElement; final parameterType = argTypeChecker.fromJsonConstructor!.parameters.first.type; final nullableSuffix = checker.isNullable ? " ?? '[]'" : ''; return '''jsonDecode($fieldValue$nullableSuffix).map( - (d) => ${klass.displayName}.fromJson(d as ${parameterType.getDisplayString(withNullability: true)}) + (d) => ${klass.displayName}.fromJson(d as ${parameterType.getDisplayString()}) )$castIterable$defaultValue'''; } @@ -208,9 +219,9 @@ class SqliteDeserialize<_Model extends SqliteModel> extends SqliteSerdesGenerato } else if (checker.isMap) { return 'jsonDecode($fieldValue)'; } else if (checker.fromJsonConstructor != null) { - final klass = checker.targetType.element as ClassElement; + final klass = checker.targetType.element! as ClassElement; final parameterType = checker.fromJsonConstructor!.parameters.first.type; - return '${klass.displayName}.fromJson(jsonDecode($fieldValue as String) as ${parameterType.getDisplayString(withNullability: true)})'; + return '${klass.displayName}.fromJson(jsonDecode($fieldValue as String) as ${parameterType.getDisplayString()})'; } return null; diff --git a/packages/brick_sqlite_generators/lib/src/sqlite_fields.dart b/packages/brick_sqlite_generators/lib/src/sqlite_fields.dart index eb4b8a86..39be4390 100644 --- a/packages/brick_sqlite_generators/lib/src/sqlite_fields.dart +++ b/packages/brick_sqlite_generators/lib/src/sqlite_fields.dart @@ -2,16 +2,18 @@ import 'package:analyzer/dart/element/element.dart'; import 'package:brick_build/generators.dart'; -import 'package:brick_sqlite/brick_sqlite.dart' show SqliteSerializable, Sqlite, Column; +import 'package:brick_sqlite/brick_sqlite.dart' show Column, Sqlite, SqliteSerializable; /// Find `@Sqlite` given a field class SqliteAnnotationFinder extends AnnotationFinder { + /// final SqliteSerializable? config; + /// Find `@Sqlite` given a field SqliteAnnotationFinder([this.config]); @override - Sqlite from(element) { + Sqlite from(FieldElement element) { final obj = objectForField(element); if (obj == null) { @@ -58,8 +60,11 @@ class SqliteAnnotationFinder extends AnnotationFinder { class SqliteFields extends FieldsForClass { @override final SqliteAnnotationFinder finder; + + /// final SqliteSerializable? config; + /// Converts all fields to [Sqlite]s for later consumption SqliteFields(ClassElement element, [this.config]) : finder = SqliteAnnotationFinder(config), super(element: element); diff --git a/packages/brick_sqlite_generators/lib/src/sqlite_schema/migration_generator.dart b/packages/brick_sqlite_generators/lib/src/sqlite_schema/migration_generator.dart index ba6875c5..7760537e 100644 --- a/packages/brick_sqlite_generators/lib/src/sqlite_schema/migration_generator.dart +++ b/packages/brick_sqlite_generators/lib/src/sqlite_schema/migration_generator.dart @@ -27,8 +27,11 @@ class _MigrationImpl extends Migration { /// Recreate existing migrations as manageable objects. /// Eventually used in [SchemaDifference] to generate new [Migration]s class MigrationGenerator extends Generator { + /// static final emptySchema = Schema(0, tables: {}); + /// Recreate existing migrations as manageable objects. + /// Eventually used in [SchemaDifference] to generate new [Migration]s const MigrationGenerator(); /// Search [library] for all classes that extend [Migration]. Recreate these in Dart Code @@ -129,7 +132,7 @@ class MigrationGenerator extends Generator { /// Creates a new migration from the delta between the existing migration and a new schema @override - String? generate(library, BuildStep? buildStep, {Schema? newSchema, int? version}) { + String? generate(LibraryReader library, BuildStep? buildStep, {Schema? newSchema, int? version}) { final allMigrations = expandAllMigrations(library); final oldSchema = Schema.fromMigrations(allMigrations.toSet()); diff --git a/packages/brick_sqlite_generators/lib/src/sqlite_schema/sqlite_schema_generator.dart b/packages/brick_sqlite_generators/lib/src/sqlite_schema/sqlite_schema_generator.dart index 2718ddf2..04346b3d 100644 --- a/packages/brick_sqlite_generators/lib/src/sqlite_schema/sqlite_schema_generator.dart +++ b/packages/brick_sqlite_generators/lib/src/sqlite_schema/sqlite_schema_generator.dart @@ -11,15 +11,18 @@ import 'package:source_gen/source_gen.dart' show LibraryReader; import 'package:source_gen/source_gen.dart'; final _formatter = dart_style.DartFormatter(); + +/// const migrationGenerator = MigrationGenerator(); -/// Produces a [Schema] from all @[OfflineFirst] annotations +/// Produces a [Schema] from all SQLite-enabled annotations class SqliteSchemaGenerator { + /// Produces a [Schema] from all SQLite-enabled annotations const SqliteSchemaGenerator(); /// Complete schema file output /// - /// [classes] are all classes by their table name with the @[OfflineFirst] annotation + /// [fieldses] are all classes by their table name String generate(LibraryReader library, List fieldses) { final newSchema = _createNewSchema(library, fieldses); final existingMigrations = migrationGenerator.expandAllMigrations(library); @@ -113,7 +116,6 @@ class SqliteSchemaGenerator { foreignTableName: localTableName, nullable: foreignTableColumnDefinition.nullable, onDeleteCascade: true, - onDeleteSetDefault: false, ), SchemaColumn( InsertForeignKey.joinsTableForeignColumnName(foreignTableName), @@ -122,7 +124,6 @@ class SqliteSchemaGenerator { foreignTableName: foreignTableName, nullable: foreignTableColumnDefinition.nullable, onDeleteCascade: true, - onDeleteSetDefault: false, ), }, indices: { @@ -142,17 +143,17 @@ class SqliteSchemaGenerator { } SchemaTable _createTable(String tableName, SqliteFields fields) { - final columns = _createColumns(fields).where((c) => c != null).toList(); - columns.insert( - 0, - SchemaColumn( - InsertTable.PRIMARY_KEY_COLUMN, - Column.integer, - autoincrement: true, - isPrimaryKey: true, - nullable: false, - ), - ); + final columns = _createColumns(fields).where((c) => c != null).toList() + ..insert( + 0, + SchemaColumn( + InsertTable.PRIMARY_KEY_COLUMN, + Column.integer, + autoincrement: true, + isPrimaryKey: true, + nullable: false, + ), + ); final indices = _createIndices(tableName, fields); @@ -163,6 +164,7 @@ class SqliteSchemaGenerator { ); } + /// @visibleForOverriding SharedChecker checkerForField(FieldElement field) { var checker = checkerForType(field.type); @@ -205,9 +207,11 @@ class SqliteSchemaGenerator { }); } + /// @visibleForOverriding SharedChecker checkerForType(DartType type) => SharedChecker(type); + /// @mustCallSuper SchemaColumn? schemaColumn(Sqlite column, {required SharedChecker checker}) { if (column.columnType != null) { @@ -266,6 +270,7 @@ class SqliteSchemaGenerator { return null; } + /// @visibleForOverriding SchemaIndex? schemaIndex(Sqlite column, {required SharedChecker checker}) { final isIterableAssociation = checker.isIterable && checker.isArgTypeASibling; diff --git a/packages/brick_sqlite_generators/lib/src/sqlite_serdes_generator.dart b/packages/brick_sqlite_generators/lib/src/sqlite_serdes_generator.dart index f7ee7f04..bf3ad7fd 100644 --- a/packages/brick_sqlite_generators/lib/src/sqlite_serdes_generator.dart +++ b/packages/brick_sqlite_generators/lib/src/sqlite_serdes_generator.dart @@ -1,10 +1,12 @@ import 'package:analyzer/dart/element/element.dart'; import 'package:brick_build/generators.dart'; +import 'package:brick_core/src/model.dart'; import 'package:brick_sqlite/brick_sqlite.dart'; import 'package:brick_sqlite/db.dart' show InsertForeignKey; import 'package:brick_sqlite_generators/src/sqlite_fields.dart'; import 'package:source_gen/source_gen.dart'; +/// abstract class SqliteSerdesGenerator<_Model extends SqliteModel> extends SerdesGenerator { @override @@ -13,6 +15,7 @@ abstract class SqliteSerdesGenerator<_Model extends SqliteModel> @override final String repositoryName; + /// SqliteSerdesGenerator( super.element, SqliteFields super.fields, { @@ -30,7 +33,7 @@ abstract class SqliteSerdesGenerator<_Model extends SqliteModel> SharedChecker checkerForField(FieldElement field) => checkerForType(field.type); @override - bool ignoreCoderForField(field, annotation, checker) { + bool ignoreCoderForField(FieldElement field, Sqlite annotation, SharedChecker checker) { if (annotation.columnType != null) { if (checker.isSerializable) return false; @@ -57,7 +60,7 @@ abstract class SqliteSerdesGenerator<_Model extends SqliteModel> /// Generate foreign key column if the type is a sibling; /// otherwise, return the field's annotated name; @override - String providerNameForField(annotatedName, {required checker}) { + String providerNameForField(String? annotatedName, {required SharedChecker checker}) { if (checker.isSibling) { return InsertForeignKey.foreignKeyColumnName( SharedChecker.withoutNullability(checker.unFuturedType), diff --git a/packages/brick_sqlite_generators/lib/src/sqlite_serialize.dart b/packages/brick_sqlite_generators/lib/src/sqlite_serialize.dart index 26965cb7..a15fcd7e 100644 --- a/packages/brick_sqlite_generators/lib/src/sqlite_serialize.dart +++ b/packages/brick_sqlite_generators/lib/src/sqlite_serialize.dart @@ -1,14 +1,16 @@ import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/nullability_suffix.dart'; import 'package:brick_build/generators.dart'; +import 'package:brick_core/src/model.dart'; import 'package:brick_sqlite/brick_sqlite.dart'; -import 'package:brick_sqlite/db.dart' show InsertTable, InsertForeignKey; +import 'package:brick_sqlite/db.dart' show InsertForeignKey, InsertTable; import 'package:brick_sqlite_generators/src/sqlite_serdes_generator.dart'; import 'package:meta/meta.dart'; import 'package:source_gen/source_gen.dart' show InvalidGenerationSourceError; /// Generate a function to produce a [ClassElement] to SQLite data class SqliteSerialize<_Model extends SqliteModel> extends SqliteSerdesGenerator<_Model> { + /// Generate a function to produce a [ClassElement] to SQLite data SqliteSerialize( super.element, super.fields, { @@ -18,6 +20,7 @@ class SqliteSerialize<_Model extends SqliteModel> extends SqliteSerdesGenerator< @override final doesDeserialize = false; + /// String get tableName => element.name; @override @@ -69,7 +72,12 @@ class SqliteSerialize<_Model extends SqliteModel> extends SqliteSerdesGenerator< } @override - String? coderForField(field, checker, {required wrappedInFuture, required fieldAnnotation}) { + String? coderForField( + FieldElement field, + SharedChecker checker, { + required bool wrappedInFuture, + required Sqlite fieldAnnotation, + }) { final name = providerNameForField(fieldAnnotation.name, checker: checker); final fieldValue = serdesValueForField(field, fieldAnnotation.name!, checker: checker); if (name == InsertTable.PRIMARY_KEY_COLUMN) { @@ -247,7 +255,7 @@ class SqliteSerialize<_Model extends SqliteModel> extends SqliteSerdesGenerator< } @override - bool ignoreCoderForField(field, annotation, checker) { + bool ignoreCoderForField(FieldElement field, Sqlite annotation, SharedChecker checker) { if (annotation.columnType != null) return false; return super.ignoreCoderForField(field, annotation, checker); } diff --git a/packages/brick_sqlite_generators/pubspec.yaml b/packages/brick_sqlite_generators/pubspec.yaml index cd047fd7..bb9142d0 100644 --- a/packages/brick_sqlite_generators/pubspec.yaml +++ b/packages/brick_sqlite_generators/pubspec.yaml @@ -19,7 +19,7 @@ dependencies: source_gen: ">=1.2.2 <2.0.0" dev_dependencies: - test: ^1.20.1 - lints: ^2.0.1 brick_build_test: path: ../brick_build_test + lints: + test: diff --git a/packages/brick_sqlite_generators/test/migration_generator/test_from_identical_schema.dart b/packages/brick_sqlite_generators/test/migration_generator/test_from_identical_schema.dart index 0fa6c2fb..b020434e 100644 --- a/packages/brick_sqlite_generators/test/migration_generator/test_from_identical_schema.dart +++ b/packages/brick_sqlite_generators/test/migration_generator/test_from_identical_schema.dart @@ -16,7 +16,6 @@ class Migration1 extends Migration { final schema = Schema( 2, - generatorVersion: 1, tables: { SchemaTable( 'User', diff --git a/packages/brick_sqlite_generators/test/migration_generator/test_from_new_schema.dart b/packages/brick_sqlite_generators/test/migration_generator/test_from_new_schema.dart index 2bf416fd..f82c8e22 100644 --- a/packages/brick_sqlite_generators/test/migration_generator/test_from_new_schema.dart +++ b/packages/brick_sqlite_generators/test/migration_generator/test_from_new_schema.dart @@ -18,7 +18,6 @@ class Migration1 extends Migration { final schema = Schema( 2, - generatorVersion: 1, tables: { SchemaTable( 'User', @@ -37,7 +36,7 @@ final schema = Schema( }, ); -final output = ''' +const output = ''' // GENERATED CODE EDIT WITH CAUTION // THIS FILE **WILL NOT** BE REGENERATED // This file should be version controlled and can be manually edited. diff --git a/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_after_save_with_association.dart b/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_after_save_with_association.dart index 3723f36b..73865511 100644 --- a/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_after_save_with_association.dart +++ b/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_after_save_with_association.dart @@ -1,6 +1,6 @@ import 'package:brick_sqlite/brick_sqlite.dart'; -final output = r""" +const output = r""" // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_all_field_types.dart b/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_all_field_types.dart index e705ce4f..a8924c98 100644 --- a/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_all_field_types.dart +++ b/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_all_field_types.dart @@ -2,7 +2,7 @@ import 'package:brick_sqlite/brick_sqlite.dart'; enum Casing { snake, camel } -final output = r''' +const output = r''' // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_boolean_fields.dart b/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_boolean_fields.dart index 23178ee3..808f4c52 100644 --- a/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_boolean_fields.dart +++ b/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_boolean_fields.dart @@ -1,6 +1,6 @@ import 'package:brick_sqlite/brick_sqlite.dart'; -final output = r""" +const output = r""" // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_field_with_type_argument.dart b/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_field_with_type_argument.dart index 1cce7aca..d91faccd 100644 --- a/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_field_with_type_argument.dart +++ b/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_field_with_type_argument.dart @@ -1,6 +1,6 @@ import 'package:brick_sqlite/brick_sqlite.dart'; -final output = r""" +const output = r""" // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_sqlite_column_type.dart b/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_sqlite_column_type.dart index d6eae813..3c766d82 100644 --- a/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_sqlite_column_type.dart +++ b/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_sqlite_column_type.dart @@ -1,6 +1,6 @@ import 'package:brick_sqlite/brick_sqlite.dart'; -final output = r""" +const output = r""" // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_sqlite_enum_as_string.dart b/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_sqlite_enum_as_string.dart index cae7259a..3ba83217 100644 --- a/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_sqlite_enum_as_string.dart +++ b/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_sqlite_enum_as_string.dart @@ -1,6 +1,6 @@ import 'package:brick_sqlite/brick_sqlite.dart'; -final output = r""" +const output = r""" // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_sqlite_unique.dart b/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_sqlite_unique.dart index 1b1edcd9..bae23341 100644 --- a/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_sqlite_unique.dart +++ b/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_sqlite_unique.dart @@ -1,6 +1,6 @@ import 'package:brick_sqlite/brick_sqlite.dart'; -final output = r""" +const output = r""" // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_to_json_from_json.dart b/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_to_json_from_json.dart index 0007f26d..5f3979f8 100644 --- a/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_to_json_from_json.dart +++ b/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator/test_to_json_from_json.dart @@ -1,6 +1,6 @@ import 'package:brick_sqlite/brick_sqlite.dart'; -final output = r''' +const output = r''' // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator_test.dart b/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator_test.dart index 20b5cd56..2d10728d 100644 --- a/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator_test.dart +++ b/packages/brick_sqlite_generators/test/sqlite_model_serdes_generator_test.dart @@ -18,7 +18,7 @@ import 'sqlite_model_serdes_generator/test_sqlite_unique.dart' as sqlite_unique; import 'sqlite_model_serdes_generator/test_to_json_from_json.dart' as to_json_from_json; final _generator = TestGenerator(); -final folder = 'sqlite_model_serdes_generator'; +const folder = 'sqlite_model_serdes_generator'; final generateReader = generateLibraryForFolder(folder); void main() { @@ -28,7 +28,7 @@ void main() { final reader = await generateReader('id_field'); expect( () async => await _generator.generate(reader, MockBuildStep()), - throwsA(TypeMatcher()), + throwsA(const TypeMatcher()), ); }); @@ -36,7 +36,7 @@ void main() { final reader = await generateReader('primary_key_field'); expect( () async => await _generator.generate(reader, MockBuildStep()), - throwsA(TypeMatcher()), + throwsA(const TypeMatcher()), ); }); @@ -44,7 +44,7 @@ void main() { final reader = await generateReader('column_type_without_generator'); expect( () async => await _generator.generate(reader, MockBuildStep()), - throwsA(TypeMatcher()), + throwsA(const TypeMatcher()), ); }); }); diff --git a/packages/brick_sqlite_generators/test/sqlite_schema/test_all_field_types.dart b/packages/brick_sqlite_generators/test/sqlite_schema/test_all_field_types.dart index c2a09144..65b11957 100644 --- a/packages/brick_sqlite_generators/test/sqlite_schema/test_all_field_types.dart +++ b/packages/brick_sqlite_generators/test/sqlite_schema/test_all_field_types.dart @@ -2,7 +2,7 @@ import 'package:brick_sqlite/brick_sqlite.dart'; enum Casing { snake, camel } -final output = ''' +const output = ''' // GENERATED CODE DO NOT EDIT // This file should be version controlled import 'package:brick_sqlite/db.dart'; diff --git a/packages/brick_sqlite_generators/test/sqlite_schema/test_from_to_json.dart b/packages/brick_sqlite_generators/test/sqlite_schema/test_from_to_json.dart index 5b27f7fa..9ffd79de 100644 --- a/packages/brick_sqlite_generators/test/sqlite_schema/test_from_to_json.dart +++ b/packages/brick_sqlite_generators/test/sqlite_schema/test_from_to_json.dart @@ -1,6 +1,6 @@ import 'package:brick_sqlite/brick_sqlite.dart'; -final output = ''' +const output = ''' // GENERATED CODE DO NOT EDIT // This file should be version controlled import 'package:brick_sqlite/db.dart'; diff --git a/packages/brick_sqlite_generators/test/sqlite_schema/test_index_annotation.dart b/packages/brick_sqlite_generators/test/sqlite_schema/test_index_annotation.dart index 03a9217c..8b44d82a 100644 --- a/packages/brick_sqlite_generators/test/sqlite_schema/test_index_annotation.dart +++ b/packages/brick_sqlite_generators/test/sqlite_schema/test_index_annotation.dart @@ -1,6 +1,6 @@ import 'package:brick_sqlite/brick_sqlite.dart'; -final output = ''' +const output = ''' // GENERATED CODE DO NOT EDIT // This file should be version controlled import 'package:brick_sqlite/db.dart'; diff --git a/packages/brick_sqlite_generators/test/sqlite_schema/test_nullable.dart b/packages/brick_sqlite_generators/test/sqlite_schema/test_nullable.dart index e508e1e3..4257b988 100644 --- a/packages/brick_sqlite_generators/test/sqlite_schema/test_nullable.dart +++ b/packages/brick_sqlite_generators/test/sqlite_schema/test_nullable.dart @@ -1,6 +1,6 @@ import 'package:brick_sqlite/brick_sqlite.dart'; -final output = ''' +const output = ''' // GENERATED CODE DO NOT EDIT // This file should be version controlled import 'package:brick_sqlite/db.dart'; diff --git a/packages/brick_sqlite_generators/test/sqlite_schema/test_one_to_many_association.dart b/packages/brick_sqlite_generators/test/sqlite_schema/test_one_to_many_association.dart index e52230d4..c507f27b 100644 --- a/packages/brick_sqlite_generators/test/sqlite_schema/test_one_to_many_association.dart +++ b/packages/brick_sqlite_generators/test/sqlite_schema/test_one_to_many_association.dart @@ -10,7 +10,7 @@ class SqliteAssoc extends SqliteModel { final int key = -1; } -final output = ''' +const output = ''' // GENERATED CODE DO NOT EDIT // This file should be version controlled import 'package:brick_sqlite/db.dart'; diff --git a/packages/brick_sqlite_generators/test/sqlite_schema/test_one_to_one_association.dart b/packages/brick_sqlite_generators/test/sqlite_schema/test_one_to_one_association.dart index cc115064..3bd1807f 100644 --- a/packages/brick_sqlite_generators/test/sqlite_schema/test_one_to_one_association.dart +++ b/packages/brick_sqlite_generators/test/sqlite_schema/test_one_to_one_association.dart @@ -10,7 +10,7 @@ class SqliteAssoc extends SqliteModel { final int key = -1; } -final output = ''' +const output = ''' // GENERATED CODE DO NOT EDIT // This file should be version controlled import 'package:brick_sqlite/db.dart'; diff --git a/packages/brick_sqlite_generators/test/sqlite_schema/test_simple.dart b/packages/brick_sqlite_generators/test/sqlite_schema/test_simple.dart index 08365d0a..d5b36267 100644 --- a/packages/brick_sqlite_generators/test/sqlite_schema/test_simple.dart +++ b/packages/brick_sqlite_generators/test/sqlite_schema/test_simple.dart @@ -1,6 +1,6 @@ import 'package:brick_sqlite/brick_sqlite.dart'; -final migrationOutput = ''' +const migrationOutput = ''' // GENERATED CODE EDIT WITH CAUTION // THIS FILE **WILL NOT** BE REGENERATED // This file should be version controlled and can be manually edited. @@ -41,7 +41,7 @@ class Migration1 extends Migration { } '''; -final output = ''' +const output = ''' // GENERATED CODE DO NOT EDIT // This file should be version controlled import 'package:brick_sqlite/db.dart'; diff --git a/packages/brick_sqlite_generators/test/sqlite_schema/test_sqlite_column_type.dart b/packages/brick_sqlite_generators/test/sqlite_schema/test_sqlite_column_type.dart index 01437d2d..a749012e 100644 --- a/packages/brick_sqlite_generators/test/sqlite_schema/test_sqlite_column_type.dart +++ b/packages/brick_sqlite_generators/test/sqlite_schema/test_sqlite_column_type.dart @@ -2,7 +2,7 @@ import 'dart:typed_data'; import 'package:brick_sqlite/brick_sqlite.dart'; -final output = ''' +const output = ''' // GENERATED CODE DO NOT EDIT // This file should be version controlled import 'package:brick_sqlite/db.dart'; diff --git a/packages/brick_sqlite_generators/test/sqlite_schema_generator_test.dart b/packages/brick_sqlite_generators/test/sqlite_schema_generator_test.dart index 91a7972b..e3596599 100644 --- a/packages/brick_sqlite_generators/test/sqlite_schema_generator_test.dart +++ b/packages/brick_sqlite_generators/test/sqlite_schema_generator_test.dart @@ -73,7 +73,7 @@ void main() { }); } -final annotationChecker = TypeChecker.fromRuntime(SqliteSerializable); +const annotationChecker = TypeChecker.fromRuntime(SqliteSerializable); Future>> generateSchemaMap(String filename) async { final reader = await generateReader(filename); diff --git a/packages/brick_supabase/analysis_options.yaml b/packages/brick_supabase/analysis_options.yaml index 5008bf6c..f04c6cf0 100644 --- a/packages/brick_supabase/analysis_options.yaml +++ b/packages/brick_supabase/analysis_options.yaml @@ -1,326 +1 @@ include: ../../analysis_options.yaml - -linter: - rules: - # This list is derived from the list of all available lints located at - # https://github.com/dart-lang/linter/blob/master/example/all.yaml - - always_declare_return_types - # - always_put_control_body_on_new_line - # - always_put_required_named_parameters_first - # - always_specify_types - - always_use_package_imports - - annotate_overrides - # - avoid_annotating_with_dynamic - - avoid_bool_literals_in_conditional_expressions - # - avoid_catches_without_on_clauses - # - avoid_catching_errors - - avoid_classes_with_only_static_members - - avoid_double_and_int_checks - # - avoid_dynamic_calls - - avoid_empty_else - # - avoid_equals_and_hash_code_on_mutable_classes - - avoid_escaping_inner_quotes - - avoid_field_initializers_in_const_classes - # - avoid_final_parameters - - avoid_function_literals_in_foreach_calls - - avoid_implementing_value_types - - avoid_init_to_null - - avoid_js_rounded_ints - - avoid_multiple_declarations_per_line - - avoid_null_checks_in_equality_operators - # - avoid_positional_boolean_parameters - - avoid_print - - avoid_private_typedef_functions - - avoid_redundant_argument_values - - avoid_relative_lib_imports - - avoid_renaming_method_parameters - - avoid_return_types_on_setters - - avoid_returning_null_for_void - - avoid_returning_this - - avoid_setters_without_getters - - avoid_shadowing_type_parameters - - avoid_single_cascade_in_expression_statements - - avoid_slow_async_io - - avoid_type_to_string - - avoid_types_as_parameter_names - # - avoid_types_on_closure_parameters - - avoid_unnecessary_containers - - avoid_unused_constructor_parameters - - avoid_void_async - - avoid_web_libraries_in_flutter - - await_only_futures - - camel_case_extensions - - camel_case_types - - cancel_subscriptions - - cascade_invocations - - cast_nullable_to_non_nullable - # - close_sinks - - collection_methods_unrelated_type - - combinators_ordering - - comment_references - - conditional_uri_does_not_exist - - constant_identifier_names - - control_flow_in_finally - - curly_braces_in_flow_control_structures - - dangling_library_doc_comments - - depend_on_referenced_packages - - deprecated_consistency - - deprecated_member_use_from_same_package - # - diagnostic_describe_all_properties - - directives_ordering - - discarded_futures - - do_not_use_environment - - empty_catches - - empty_constructor_bodies - - empty_statements - - eol_at_end_of_file - - exhaustive_cases - - file_names - - flutter_style_todos - - hash_and_equals - - implementation_imports - - implicit_call_tearoffs - - implicit_reopen - - invalid_case_patterns - - join_return_with_assignment - # - leading_newlines_in_multiline_strings - - library_annotations - - library_names - - library_prefixes - - library_private_types_in_public_api - # - lines_longer_than_80_chars - - literal_only_boolean_expressions - - matching_super_parameters - - missing_whitespace_between_adjacent_strings - - no_adjacent_strings_in_list - - no_default_cases - - no_duplicate_case_values - - no_leading_underscores_for_library_prefixes - - no_leading_underscores_for_local_identifiers - - no_literal_bool_comparisons - - no_logic_in_create_state - - no_runtimeType_toString - - no_self_assignments - - no_wildcard_variable_uses - - non_constant_identifier_names - - noop_primitive_operations - - null_check_on_nullable_type_parameter - - null_closures - - omit_local_variable_types - - one_member_abstracts - - only_throw_errors - - overridden_fields - - package_api_docs - - package_names - - package_prefixed_library_names - - parameter_assignments - - prefer_adjacent_string_concatenation - - prefer_asserts_in_initializer_lists - - prefer_asserts_with_message - - prefer_collection_literals - - prefer_conditional_assignment - - prefer_const_constructors - - prefer_const_constructors_in_immutables - - prefer_const_declarations - - prefer_const_literals_to_create_immutables - - prefer_constructors_over_static_methods - - prefer_contains - # - prefer_double_quotes - - prefer_expression_function_bodies - - prefer_final_fields - - prefer_final_in_for_each - - prefer_final_locals - # - prefer_final_parameters - - prefer_for_elements_to_map_fromIterable - - prefer_foreach - - prefer_function_declarations_over_variables - - prefer_generic_function_type_aliases - - prefer_if_elements_to_conditional_expressions - - prefer_if_null_operators - - prefer_initializing_formals - - prefer_inlined_adds - - prefer_int_literals - - prefer_interpolation_to_compose_strings - - prefer_is_empty - - prefer_is_not_empty - - prefer_is_not_operator - - prefer_iterable_whereType - - prefer_mixin - - prefer_null_aware_method_calls - - prefer_null_aware_operators - # - prefer_relative_imports - - prefer_single_quotes - - prefer_spread_collections - - prefer_typing_uninitialized_variables - - prefer_void_to_null - - provide_deprecation_message - - public_member_api_docs - - recursive_getters - - require_trailing_commas - - secure_pubspec_urls - - sized_box_for_whitespace - - sized_box_shrink_expand - - slash_for_doc_comments - - sort_child_properties_last - # - sort_constructors_first - - sort_pub_dependencies - - sort_unnamed_constructors_first - - test_types_in_equals - - throw_in_finally - - tighten_type_of_initializing_formals - - type_annotate_public_apis - - type_init_formals - - type_literal_in_constant_pattern - - unawaited_futures - # - unnecessary_await_in_return - - unnecessary_brace_in_string_interps - - unnecessary_breaks - - unnecessary_const - - unnecessary_constructor_name - # - unnecessary_final - - unnecessary_getters_setters - - unnecessary_lambdas - - unnecessary_late - - unnecessary_library_directive - - unnecessary_new - - unnecessary_null_aware_assignments - - unnecessary_null_aware_operator_on_extension_on_nullable - - unnecessary_null_checks - - unnecessary_null_in_if_null_operators - - unnecessary_nullable_for_final_variable_declarations - - unnecessary_overrides - - unnecessary_parenthesis - - unnecessary_raw_strings - - unnecessary_statements - - unnecessary_string_escapes - - unnecessary_string_interpolations - - unnecessary_this - - unnecessary_to_list_in_spreads - # - unreachable_from_main - - unrelated_type_equality_checks - - unsafe_html - - use_build_context_synchronously - - use_colored_box - - use_decorated_box - - use_enums - - use_full_hex_values_for_flutter_colors - - use_function_type_syntax_for_parameters - - use_if_null_to_convert_nulls_to_bools - - use_is_even_rather_than_modulo - - use_key_in_widget_constructors - - use_late_for_private_fields_and_variables - - use_named_constants - - use_raw_strings - - use_rethrow_when_possible - - use_setters_to_change_properties - - use_string_buffers - - use_string_in_part_of_directives - - use_super_parameters - - use_test_throws_matchers - - use_to_and_as_if_applicable - - valid_regexps - - void_checks - -analyzer: - exclude: - - example/ - - "**/example/" - - example_rest - - example_graphql - - "**/*.g.dart" - - errors: - # override custom - always_use_package_imports: error - camel_case_extensions: error - camel_case_types: error - curly_braces_in_flow_control_structures: error - directives_ordering: error - file_names: error - prefer_single_quotes: error - prefer_is_empty: error - prefer_is_not_empty: error - require_trailing_commas: error - sort_pub_dependencies: error - unnecessary_statements: error - - # override flutter_lints - avoid_print: error - avoid_unnecessary_containers: error - avoid_web_libraries_in_flutter: error - no_logic_in_create_state: error - prefer_const_constructors: error - prefer_const_constructors_in_immutables: error - prefer_const_declarations: error - prefer_const_literals_to_create_immutables: error - sized_box_for_whitespace: error - sort_child_properties_last: error - use_build_context_synchronously: error - use_full_hex_values_for_flutter_colors: error - use_key_in_widget_constructors: error - - # override recommended lints - always_require_non_null_named_parameters: error - annotate_overrides: error - avoid_function_literals_in_foreach_calls: error - avoid_init_to_null: error - avoid_null_checks_in_equality_operators: error - avoid_renaming_method_parameters: error - avoid_return_types_on_setters: error - avoid_returning_null_for_void: error - avoid_single_cascade_in_expression_statements: error - await_only_futures: error - constant_identifier_names: error - control_flow_in_finally: error - depend_on_referenced_packages: ignore - empty_constructor_bodies: error - empty_statements: error - exhaustive_cases: error - implementation_imports: ignore - invalid_case_patterns: error - library_names: error - library_prefixes: error - library_private_types_in_public_api: error - matching_super_parameters: error - no_leading_underscores_for_library_prefixes: error - no_leading_underscores_for_local_identifiers: error - no_literal_bool_comparisons: error - null_check_on_nullable_type_parameter: error - null_closures: error - overridden_fields: error - package_names: error - prefer_adjacent_string_concatenation: error - prefer_collection_literals: error - prefer_conditional_assignment: error - prefer_contains: error - prefer_equal_for_default_values: error - prefer_final_fields: error - prefer_for_elements_to_map_fromIterable: error - prefer_function_declarations_over_variables: error - prefer_if_null_operators: error - prefer_initializing_formals: error - prefer_inlined_adds: error - prefer_interpolation_to_compose_strings: error - prefer_is_not_operator: error - prefer_null_aware_operators: error - prefer_spread_collections: error - prefer_void_to_null: error - recursive_getters: error - slash_for_doc_comments: error - type_init_formals: error - type_literal_in_constant_pattern: error - unnecessary_brace_in_string_interps: error - unnecessary_breaks: error - unnecessary_const: error - unnecessary_constructor_name: error - unnecessary_getters_setters: error - unnecessary_late: error - unnecessary_new: error - unnecessary_null_aware_assignments: error - unnecessary_null_in_if_null_operators: error - unnecessary_nullable_for_final_variable_declarations: error - unnecessary_string_escapes: error - unnecessary_string_interpolations: error - unnecessary_this: error - use_function_type_syntax_for_parameters: error - use_rethrow_when_possible: error diff --git a/packages/brick_supabase/lib/src/query_supabase_transformer.dart b/packages/brick_supabase/lib/src/query_supabase_transformer.dart index 4b9c41eb..0c39d348 100644 --- a/packages/brick_supabase/lib/src/query_supabase_transformer.dart +++ b/packages/brick_supabase/lib/src/query_supabase_transformer.dart @@ -44,6 +44,7 @@ class QuerySupabaseTransformer<_Model extends SupabaseModel> { return limit(computedBuilder); } + /// PostgrestFilterBuilder>> select(SupabaseQueryBuilder builder) => (query?.where ?? []).fold(builder.select(selectFields), (acc, condition) { final whereStatement = expandCondition(condition); diff --git a/packages/brick_supabase/test/__mocks_generated__.dart b/packages/brick_supabase/test/__mocks_generated__.dart index 94710f97..67e413b0 100644 --- a/packages/brick_supabase/test/__mocks_generated__.dart +++ b/packages/brick_supabase/test/__mocks_generated__.dart @@ -1,3 +1,5 @@ +// ignore_for_file: type_annotate_public_apis + part of '__mocks__.dart'; Demo _$DemoFromSupabase(Map json) => Demo( diff --git a/packages/brick_supabase_generators/lib/src/supabase_deserialize.dart b/packages/brick_supabase_generators/lib/src/supabase_deserialize.dart index 3ee5568d..8cea15f9 100644 --- a/packages/brick_supabase_generators/lib/src/supabase_deserialize.dart +++ b/packages/brick_supabase_generators/lib/src/supabase_deserialize.dart @@ -4,9 +4,10 @@ import 'package:brick_supabase/brick_supabase.dart'; import 'package:brick_supabase_generators/src/supabase_fields.dart'; import 'package:brick_supabase_generators/src/supabase_serdes_generator.dart'; -/// Generate a function to produce a [ClassElement] from REST data +/// Generate a function to produce a [ClassElement] from Supabase data class SupabaseDeserialize extends SupabaseSerdesGenerator with JsonDeserialize { + /// Generate a function to produce a [ClassElement] from Supabase data SupabaseDeserialize( super.element, super.fields, { diff --git a/packages/brick_supabase_generators/lib/src/supabase_fields.dart b/packages/brick_supabase_generators/lib/src/supabase_fields.dart index d2e7870d..a1e09e88 100644 --- a/packages/brick_supabase_generators/lib/src/supabase_fields.dart +++ b/packages/brick_supabase_generators/lib/src/supabase_fields.dart @@ -10,10 +10,11 @@ class SupabaseAnnotationFinder extends AnnotationFinder /// Model-level settings final SupabaseSerializable? config; + /// Find `@Supabase` given a field SupabaseAnnotationFinder([this.config]); @override - Supabase from(element) { + Supabase from(FieldElement element) { final obj = objectForField(element); if (obj == null) { @@ -57,8 +58,11 @@ class SupabaseAnnotationFinder extends AnnotationFinder class SupabaseFields extends FieldsForClass { @override final SupabaseAnnotationFinder finder; + + /// final SupabaseSerializable? config; + /// Converts all fields to [Supabase]s for later consumption SupabaseFields(ClassElement element, [this.config]) : finder = SupabaseAnnotationFinder(config), super(element: element); diff --git a/packages/brick_supabase_generators/lib/src/supabase_serdes_generator.dart b/packages/brick_supabase_generators/lib/src/supabase_serdes_generator.dart index 4dd796b5..2868f9e4 100644 --- a/packages/brick_supabase_generators/lib/src/supabase_serdes_generator.dart +++ b/packages/brick_supabase_generators/lib/src/supabase_serdes_generator.dart @@ -2,7 +2,9 @@ import 'package:brick_json_generators/json_serdes_generator.dart'; import 'package:brick_supabase/brick_supabase.dart'; import 'package:brick_supabase_generators/src/supabase_fields.dart'; +/// abstract class SupabaseSerdesGenerator extends JsonSerdesGenerator { + /// SupabaseSerdesGenerator( super.element, SupabaseFields super.fields, { diff --git a/packages/brick_supabase_generators/lib/src/supabase_serialize.dart b/packages/brick_supabase_generators/lib/src/supabase_serialize.dart index e1cb308b..d79c55f2 100644 --- a/packages/brick_supabase_generators/lib/src/supabase_serialize.dart +++ b/packages/brick_supabase_generators/lib/src/supabase_serialize.dart @@ -7,6 +7,7 @@ import 'package:brick_supabase_generators/src/supabase_serdes_generator.dart'; /// Generate a function to produce a [ClassElement] to REST data class SupabaseSerialize extends SupabaseSerdesGenerator with JsonSerialize { + /// Generate a function to produce a [ClassElement] to REST data SupabaseSerialize( super.element, super.fields, { diff --git a/packages/brick_supabase_generators/lib/supabase_model_serdes_generator.dart b/packages/brick_supabase_generators/lib/supabase_model_serdes_generator.dart index 9cbdc541..4fc8ac55 100644 --- a/packages/brick_supabase_generators/lib/supabase_model_serdes_generator.dart +++ b/packages/brick_supabase_generators/lib/supabase_model_serdes_generator.dart @@ -13,6 +13,8 @@ class SupabaseModelSerdesGenerator extends ProviderSerializableGenerator=1.2.2 <2.0.0" dev_dependencies: - test: ^1.20.1 - lints: ^2.0.1 brick_build_test: path: ../brick_build_test + lints: + test: diff --git a/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_constructor_member_field_mismatch.dart b/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_constructor_member_field_mismatch.dart index 5b35bea1..1542bf1b 100644 --- a/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_constructor_member_field_mismatch.dart +++ b/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_constructor_member_field_mismatch.dart @@ -1,6 +1,6 @@ import 'package:brick_supabase/brick_supabase.dart'; -final output = r''' +const output = r''' Future _$SupabaseConstructorMemberFieldMismatchFromSupabase( Map data, diff --git a/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_enum_as_string.dart b/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_enum_as_string.dart index 93a020b4..4240fb2c 100644 --- a/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_enum_as_string.dart +++ b/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_enum_as_string.dart @@ -1,6 +1,6 @@ import 'package:brick_supabase/brick_supabase.dart'; -final output = r''' +const output = r''' Future _$EnumAsStringFromSupabase(Map data, {required SupabaseProvider provider, SupabaseFirstRepository? repository}) async { diff --git a/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_ignore_from_to.dart b/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_ignore_from_to.dart index 242207f6..a47ad059 100644 --- a/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_ignore_from_to.dart +++ b/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_ignore_from_to.dart @@ -1,6 +1,6 @@ import 'package:brick_supabase/brick_supabase.dart'; -final output = r''' +const output = r''' Future _$SupabaseIgnoreFromToFromSupabase( Map data, {required SupabaseProvider provider, diff --git a/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_runtime_supabase_column_definition.dart b/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_runtime_supabase_column_definition.dart index 70921a53..fa9d60b8 100644 --- a/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_runtime_supabase_column_definition.dart +++ b/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_runtime_supabase_column_definition.dart @@ -1,6 +1,6 @@ import 'package:brick_supabase/brick_supabase.dart'; -final output = r""" +const output = r""" // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_unique.dart b/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_unique.dart index 49a1e0ad..473dccfd 100644 --- a/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_unique.dart +++ b/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_unique.dart @@ -1,6 +1,6 @@ import 'package:brick_supabase/brick_supabase.dart'; -final output = r""" +const output = r""" // GENERATED CODE DO NOT EDIT part of '../brick.g.dart'; diff --git a/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_unserializable_field_with_generator.dart b/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_unserializable_field_with_generator.dart index 5803a7cd..f9574d1d 100644 --- a/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_unserializable_field_with_generator.dart +++ b/packages/brick_supabase_generators/test/supabase_model_serdes_generator/test_unserializable_field_with_generator.dart @@ -3,7 +3,7 @@ import 'dart:typed_data'; import 'package:brick_supabase/brick_supabase.dart'; -final output = r''' +const output = r''' Future _$SupabaseUnserializableFieldWithGeneratorFromSupabase( Map data,