@_nazmiforreal/flutter-ota 0.1.26 → 0.1.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +112 -18
- package/bin/flutter-ota-linux-x64 +0 -0
- package/bin/flutter-ota.js +12 -11
- package/dart-src/packages/cli-tools/README.md +146 -2
- package/dart-src/packages/cli-tools/lib/flutter_ota_kit_cli.dart +46 -13
- package/dart-src/packages/cli-tools/lib/src/backend.dart +6 -6
- package/dart-src/packages/cli-tools/lib/src/commands/build.dart +2 -0
- package/dart-src/packages/cli-tools/lib/src/commands/bundle.dart +7 -7
- package/dart-src/packages/cli-tools/lib/src/commands/deploy.dart +4 -1
- package/dart-src/packages/cli-tools/lib/src/commands/init.dart +36 -8
- package/dart-src/packages/cli-tools/lib/src/commands/pocketbase.dart +1 -1
- package/dart-src/packages/cli-tools/lib/src/commands/rollback.dart +1 -1
- package/dart-src/packages/cli-tools/lib/src/config.dart +5 -5
- package/dart-src/packages/cli-tools/lib/src/operations.dart +2 -2
- package/dart-src/packages/cli-tools/pubspec.yaml +8 -21
- package/dart-src/packages/cli-tools/test/backends_test.dart +3 -3
- package/dart-src/packages/cli-tools/test/cli_test.dart +1 -1
- package/dart-src/packages/cli-tools/test/mocks/mock_aws_s3_client.dart +2 -2
- package/dart-src/packages/cli-tools/test/mocks/mock_d1_client.dart +2 -2
- package/dart-src/packages/cli-tools/test/mocks/mock_pocketbase_client.dart +4 -1
- package/dart-src/packages/cli-tools/test/mocks/mock_postgres_client.dart +2 -2
- package/dart-src/packages/cli-tools/test/pocketbase_smoke_test.dart +1 -1
- package/dart-src/root/README.md +334 -0
- package/dart-src/root/analysis_options.yaml +21 -0
- package/dart-src/root/android/build.gradle +116 -0
- package/dart-src/root/android/consumer-rules.pro +23 -0
- package/dart-src/root/android/settings.gradle +1 -0
- package/dart-src/root/android/src/main/AndroidManifest.xml +21 -0
- package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/ApplyResult.kt +52 -0
- package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/BlacklistStore.kt +154 -0
- package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/BootDiagnosticStore.kt +150 -0
- package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/CrashGuard.kt +271 -0
- package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/FlutterPatcherApplication.kt +201 -0
- package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/FlutterPatcherAutoInitProvider.kt +93 -0
- package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/FlutterPatcherPlugin.kt +245 -0
- package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/LoaderHook.kt +298 -0
- package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/PatchManager.kt +1579 -0
- package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/PatcherConfig.kt +173 -0
- package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/SignatureVerifier.kt +177 -0
- package/dart-src/root/android/src/test/kotlin/com/flutter_patcher/flutter_patcher/CrashGuardTest.kt +61 -0
- package/dart-src/root/android/src/test/kotlin/com/flutter_patcher/flutter_patcher/LoaderHookTest.kt +25 -0
- package/dart-src/root/android/src/test/kotlin/com/flutter_patcher/flutter_patcher/PatchManagerTest.kt +401 -0
- package/dart-src/root/android/src/test/kotlin/com/flutter_patcher/flutter_patcher/PatcherConfigTest.kt +30 -0
- package/dart-src/root/bin/pack.dart +182 -0
- package/dart-src/root/lib/flutter_ota_kit.dart +1170 -0
- package/dart-src/root/lib/src/app_version_resolver.dart +36 -0
- package/dart-src/root/lib/src/aws_update_source.dart +97 -0
- package/dart-src/root/lib/src/blacklist.dart +54 -0
- package/dart-src/root/lib/src/boot_diagnostic.dart +138 -0
- package/dart-src/root/lib/src/cloudflare_update_source.dart +97 -0
- package/dart-src/root/lib/src/flutter_ota_app.dart +69 -0
- package/dart-src/root/lib/src/io.dart +48 -0
- package/dart-src/root/lib/src/io_stub.dart +19 -0
- package/dart-src/root/lib/src/ota_progress_overlay.dart +1186 -0
- package/dart-src/root/lib/src/pack/pack.dart +434 -0
- package/dart-src/root/lib/src/patch_info.dart +12 -0
- package/dart-src/root/lib/src/patcher_channel.dart +160 -0
- package/dart-src/{plugins/aws/lib → root/lib/src/pkg/aws}/src/aws_database.dart +1 -1
- package/dart-src/{plugins/aws/lib → root/lib/src/pkg/aws}/src/aws_s3_client.dart +1 -1
- package/dart-src/{plugins/aws/lib → root/lib/src/pkg/aws}/src/aws_storage.dart +1 -1
- package/dart-src/{plugins/aws/lib → root/lib/src/pkg/aws}/src/aws_storage_profile.dart +1 -1
- package/dart-src/{plugins/aws/lib → root/lib/src/pkg/aws}/src/with_cloudfront_signed_url.dart +1 -1
- package/dart-src/root/lib/src/pkg/client/flutter_ota_kit_client.dart +1 -0
- package/dart-src/root/lib/src/pkg/client/src/server_update_source.dart +46 -0
- package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/cloudflare_worker_database.dart +1 -1
- package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/d1_build_where.dart +1 -1
- package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/d1_bundle_mapper.dart +3 -3
- package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/d1_database.dart +1 -1
- package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/d1_database_plugin.dart +2 -2
- package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/r2_s3_client.dart +1 -1
- package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/r2_storage.dart +1 -1
- package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/r2_storage_profile.dart +1 -1
- package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/status.dart +1 -1
- package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/flutter_ota_kit_plugin_core.dart +1 -1
- package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/create_blob_database_plugin.dart +1 -1
- package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/filter_compatible_app_versions.dart +1 -1
- package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/get_update_info.dart +1 -1
- package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/request_update_bundle_state.dart +1 -1
- package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/resolve_update_info_from_bundles.dart +1 -1
- package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/types.dart +2 -2
- package/dart-src/{plugins/pocketbase/lib → root/lib/src/pkg/pocketbase}/src/pocketbase_bundle_mapper.dart +2 -2
- package/dart-src/{plugins/pocketbase/lib → root/lib/src/pkg/pocketbase}/src/pocketbase_database.dart +26 -15
- package/dart-src/{plugins/pocketbase/lib → root/lib/src/pkg/pocketbase}/src/pocketbase_storage.dart +1 -1
- package/dart-src/{plugins/postgres/lib → root/lib/src/pkg/postgres}/src/postgres_bundle_mapper.dart +2 -2
- package/dart-src/{plugins/postgres/lib → root/lib/src/pkg/postgres}/src/postgres_database.dart +2 -2
- package/dart-src/{plugins/postgres/lib → root/lib/src/pkg/postgres}/src/postgres_get_update_info.dart +2 -2
- package/dart-src/{plugins/postgres/lib → root/lib/src/pkg/postgres}/src/postgres_storage.dart +1 -1
- package/dart-src/{plugins/postgres/lib → root/lib/src/pkg/postgres}/src/postgres_types.dart +1 -1
- package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/supabase_bundle_mapper.dart +2 -2
- package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/supabase_database.dart +2 -2
- package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/supabase_edge_function_database.dart +1 -1
- package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/supabase_edge_function_storage.dart +1 -1
- package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/supabase_storage.dart +1 -1
- package/dart-src/root/lib/src/pocketbase_update_source.dart +107 -0
- package/dart-src/root/lib/src/postgres_update_source.dart +95 -0
- package/dart-src/root/lib/src/shared_update_check.dart +131 -0
- package/dart-src/root/lib/src/supabase_update_source.dart +93 -0
- package/dart-src/root/pubspec.yaml +54 -0
- package/package.json +1 -1
- package/scripts/postinstall.js +17 -13
- package/scripts/vendor.sh +22 -7
- package/dart-src/packages/core/CHANGELOG.md +0 -21
- package/dart-src/packages/core/README.md +0 -23
- package/dart-src/packages/core/example/lib/main.dart +0 -69
- package/dart-src/packages/core/pubspec.yaml +0 -13
- package/dart-src/packages/core/test/rollout_test.dart +0 -135
- package/dart-src/packages/core/test/semver_test.dart +0 -55
- package/dart-src/packages/core/test/semver_vectors.json +0 -1
- package/dart-src/packages/core/test/types_test.dart +0 -131
- package/dart-src/packages/core/test/uuid_test.dart +0 -40
- package/dart-src/packages/core/tool/dbg.dart +0 -7
- package/dart-src/plugins/aws/.gitkeep +0 -0
- package/dart-src/plugins/aws/CHANGELOG.md +0 -23
- package/dart-src/plugins/aws/LICENSE +0 -21
- package/dart-src/plugins/aws/README.md +0 -28
- package/dart-src/plugins/aws/example/lib/main.dart +0 -60
- package/dart-src/plugins/aws/pubspec.yaml +0 -30
- package/dart-src/plugins/aws/test/aws_database_test.dart +0 -161
- package/dart-src/plugins/aws/test/aws_storage_test.dart +0 -73
- package/dart-src/plugins/aws/test/mock_aws_s3_client.dart +0 -78
- package/dart-src/plugins/cloudflare/.gitkeep +0 -0
- package/dart-src/plugins/cloudflare/CHANGELOG.md +0 -23
- package/dart-src/plugins/cloudflare/LICENSE +0 -21
- package/dart-src/plugins/cloudflare/README.md +0 -25
- package/dart-src/plugins/cloudflare/example/lib/main.dart +0 -62
- package/dart-src/plugins/cloudflare/migrations/0001_hot-updater_init.sql +0 -16
- package/dart-src/plugins/cloudflare/migrations/0002_hot-updater_0.13.0.sql +0 -8
- package/dart-src/plugins/cloudflare/migrations/0003_hot-updater_0.18.0.sql +0 -38
- package/dart-src/plugins/cloudflare/migrations/0004_hot-updater_0.29.0.sql +0 -11
- package/dart-src/plugins/cloudflare/migrations/0005_hot-updater_0.31.0.sql +0 -24
- package/dart-src/plugins/cloudflare/pubspec.yaml +0 -28
- package/dart-src/plugins/cloudflare/sql/bundles.sql +0 -42
- package/dart-src/plugins/cloudflare/test/cloudflare_worker_database_test.dart +0 -126
- package/dart-src/plugins/cloudflare/test/d1_bundle_mapper_test.dart +0 -106
- package/dart-src/plugins/cloudflare/test/d1_database_test.dart +0 -200
- package/dart-src/plugins/cloudflare/test/mock_d1_client.dart +0 -261
- package/dart-src/plugins/cloudflare/test/mock_r2_client.dart +0 -78
- package/dart-src/plugins/cloudflare/test/r2_storage_test.dart +0 -74
- package/dart-src/plugins/plugin-core/CHANGELOG.md +0 -20
- package/dart-src/plugins/plugin-core/LICENSE +0 -21
- package/dart-src/plugins/plugin-core/README.md +0 -21
- package/dart-src/plugins/plugin-core/example/lib/main.dart +0 -61
- package/dart-src/plugins/plugin-core/pubspec.yaml +0 -23
- package/dart-src/plugins/plugin-core/test/asset_storage_layout_test.dart +0 -170
- package/dart-src/plugins/plugin-core/test/bundle_unit_of_work_store_test.dart +0 -74
- package/dart-src/plugins/plugin-core/test/bundle_unit_of_work_test.dart +0 -345
- package/dart-src/plugins/plugin-core/test/create_blob_database_plugin_test.dart +0 -843
- package/dart-src/plugins/plugin-core/test/create_database_plugin_test.dart +0 -298
- package/dart-src/plugins/plugin-core/test/create_storage_plugin_test.dart +0 -195
- package/dart-src/plugins/plugin-core/test/generate_min_bundle_id_test.dart +0 -56
- package/dart-src/plugins/plugin-core/test/get_update_info_test.dart +0 -1589
- package/dart-src/plugins/plugin-core/test/helpers_test.dart +0 -283
- package/dart-src/plugins/plugin-core/test/query_bundles_test.dart +0 -202
- package/dart-src/plugins/plugin-core/test/request_update_bundle_state_test.dart +0 -86
- package/dart-src/plugins/plugin-core/test/uuidv7_test.dart +0 -88
- package/dart-src/plugins/pocketbase/CHANGELOG.md +0 -23
- package/dart-src/plugins/pocketbase/LICENSE +0 -21
- package/dart-src/plugins/pocketbase/README.md +0 -54
- package/dart-src/plugins/pocketbase/example/lib/main.dart +0 -62
- package/dart-src/plugins/pocketbase/pubspec.yaml +0 -26
- package/dart-src/plugins/pocketbase/test/pb_uri_test.dart +0 -12
- package/dart-src/plugins/postgres/.gitkeep +0 -0
- package/dart-src/plugins/postgres/CHANGELOG.md +0 -23
- package/dart-src/plugins/postgres/LICENSE +0 -21
- package/dart-src/plugins/postgres/README.md +0 -29
- package/dart-src/plugins/postgres/example/lib/main.dart +0 -67
- package/dart-src/plugins/postgres/pubspec.yaml +0 -26
- package/dart-src/plugins/postgres/sql/bundles.sql +0 -45
- package/dart-src/plugins/postgres/sql/get_target_app_version_list.sql +0 -21
- package/dart-src/plugins/postgres/sql/get_update_info.spec.ts +0 -171
- package/dart-src/plugins/postgres/sql/get_update_info_by_app_version.sql +0 -126
- package/dart-src/plugins/postgres/sql/get_update_info_by_fingerprint_hash.sql +0 -125
- package/dart-src/plugins/postgres/sql/hash_user_id.sql +0 -30
- package/dart-src/plugins/postgres/sql/is_device_eligible.sql +0 -237
- package/dart-src/plugins/postgres/sql/prepareSql.ts +0 -11
- package/dart-src/plugins/postgres/test/mock_postgres_client.dart +0 -320
- package/dart-src/plugins/postgres/test/postgres_bundle_mapper_test.dart +0 -139
- package/dart-src/plugins/postgres/test/postgres_database_test.dart +0 -210
- package/dart-src/plugins/postgres/test/postgres_storage_runtime_test.dart +0 -60
- package/dart-src/plugins/supabase/CHANGELOG.md +0 -24
- package/dart-src/plugins/supabase/LICENSE +0 -21
- package/dart-src/plugins/supabase/README.md +0 -53
- package/dart-src/plugins/supabase/example/lib/main.dart +0 -63
- package/dart-src/plugins/supabase/pubspec.yaml +0 -27
- package/dart-src/plugins/supabase/supabase/edge-functions/index.ts +0 -44
- package/dart-src/plugins/supabase/supabase/edge-functions/runtime.docker.integration.spec.ts +0 -968
- package/dart-src/plugins/supabase/supabase/migrations/20250103114225_init.sql +0 -232
- package/dart-src/plugins/supabase/supabase/migrations/20250314000000_hot-updater_0.13.0.sql +0 -137
- package/dart-src/plugins/supabase/supabase/migrations/20250516000000_hot-updater_0.18.0.sql +0 -206
- package/dart-src/plugins/supabase/supabase/migrations/20251014000000_hot-updater_0.21.0.sql +0 -186
- package/dart-src/plugins/supabase/supabase/migrations/20260401000000_hot-updater_0.29.0.sql +0 -505
- package/dart-src/plugins/supabase/supabase/migrations/20260414000000_hot-updater_0.30.0.sql +0 -50
- package/dart-src/plugins/supabase/supabase/migrations/20260422000000_hot-updater_0.31.0.sql +0 -20
- package/dart-src/plugins/supabase/supabase/migrations/20260520014100_hot-updater_rls.sql +0 -75
- package/dart-src/plugins/supabase/test/mock_supabase_client.dart +0 -654
- package/dart-src/plugins/supabase/test/supabase_bundle_mapper_test.dart +0 -115
- package/dart-src/plugins/supabase/test/supabase_database_test.dart +0 -198
- package/dart-src/plugins/supabase/test/supabase_storage_test.dart +0 -168
- /package/dart-src/{packages/core → root}/LICENSE +0 -0
- /package/dart-src/{plugins/aws/lib → root/lib/src/pkg/aws}/flutter_ota_kit_aws.dart +0 -0
- /package/dart-src/{plugins/aws/lib → root/lib/src/pkg/aws}/src/aws_cloudfront_client.dart +0 -0
- /package/dart-src/{plugins/aws/lib → root/lib/src/pkg/aws}/src/aws_cloudfront_signer.dart +0 -0
- /package/dart-src/{plugins/aws/lib → root/lib/src/pkg/aws}/src/aws_config.dart +0 -0
- /package/dart-src/{plugins/aws/lib → root/lib/src/pkg/aws}/src/aws_ssm_client.dart +0 -0
- /package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/flutter_ota_kit_cloudflare.dart +0 -0
- /package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/d1_client.dart +0 -0
- /package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/d1_config.dart +0 -0
- /package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/r2_config.dart +0 -0
- /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/flutter_ota_kit_core.dart +0 -0
- /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/app_update_info.dart +0 -0
- /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/bundle.dart +0 -0
- /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/bundle_artifacts.dart +0 -0
- /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/bundle_patch_artifact.dart +0 -0
- /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/changed_asset.dart +0 -0
- /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/get_bundles_args.dart +0 -0
- /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/metadata.dart +0 -0
- /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/patch_info.dart +0 -0
- /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/platform.dart +0 -0
- /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/rollout.dart +0 -0
- /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/semver.dart +0 -0
- /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/semver_range.dart +0 -0
- /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/semver_version.dart +0 -0
- /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/strategy.dart +0 -0
- /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/update_bundle_params.dart +0 -0
- /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/uuid.dart +0 -0
- /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/asset_storage_layout.dart +0 -0
- /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/bundle_helpers.dart +0 -0
- /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/bundle_storage_layout.dart +0 -0
- /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/bundle_unit_of_work.dart +0 -0
- /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/bundle_unit_of_work_store.dart +0 -0
- /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/calculate_pagination.dart +0 -0
- /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/compression_format.dart +0 -0
- /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/content_addressed_assets.dart +0 -0
- /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/create_database_plugin.dart +0 -0
- /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/create_storage_key_builder.dart +0 -0
- /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/create_storage_plugin.dart +0 -0
- /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/generate_min_bundle_id.dart +0 -0
- /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/is_object.dart +0 -0
- /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/legacy_asset_storage_layout.dart +0 -0
- /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/paginate_bundles.dart +0 -0
- /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/parse_storage_uri.dart +0 -0
- /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/query_bundles.dart +0 -0
- /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/storage_helpers.dart +0 -0
- /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/storage_profile.dart +0 -0
- /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/uuidv7.dart +0 -0
- /package/dart-src/{plugins/pocketbase/lib → root/lib/src/pkg/pocketbase}/flutter_ota_kit_pocketbase.dart +0 -0
- /package/dart-src/{plugins/pocketbase/lib → root/lib/src/pkg/pocketbase}/src/pocketbase_client.dart +0 -0
- /package/dart-src/{plugins/pocketbase/lib → root/lib/src/pkg/pocketbase}/src/pocketbase_config.dart +0 -0
- /package/dart-src/{plugins/postgres/lib → root/lib/src/pkg/postgres}/flutter_ota_kit_postgres.dart +0 -0
- /package/dart-src/{plugins/postgres/lib → root/lib/src/pkg/postgres}/src/postgres_client.dart +0 -0
- /package/dart-src/{plugins/postgres/lib → root/lib/src/pkg/postgres}/src/postgres_config.dart +0 -0
- /package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/edge.dart +0 -0
- /package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/flutter_ota_kit_supabase.dart +0 -0
- /package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/error_message.dart +0 -0
- /package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/supabase_client_adapter.dart +0 -0
- /package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/supabase_client_http.dart +0 -0
- /package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/supabase_config.dart +0 -0
- /package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/supabase_signed_url_batcher.dart +0 -0
- /package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/types.dart +0 -0
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import 'dart:io' show Directory, File;
|
|
2
|
-
|
|
3
|
-
import 'package:flutter_ota_kit_aws/flutter_ota_kit_aws.dart' show s3Storage;
|
|
4
|
-
import 'package:flutter_ota_kit_plugin_core/flutter_ota_kit_plugin_core.dart'
|
|
5
|
-
show StoragePlugin;
|
|
6
|
-
import 'package:path/path.dart' show basename;
|
|
7
|
-
import 'package:test/test.dart';
|
|
8
|
-
|
|
9
|
-
import 'mock_aws_s3_client.dart' show Store, mockConfig;
|
|
10
|
-
|
|
11
|
-
void main() {
|
|
12
|
-
group('aws s3Storage', () {
|
|
13
|
-
late Store store;
|
|
14
|
-
late StoragePlugin plugin;
|
|
15
|
-
late String tmpFile;
|
|
16
|
-
late String outFile;
|
|
17
|
-
|
|
18
|
-
setUp(() {
|
|
19
|
-
store = Store();
|
|
20
|
-
plugin = s3Storage(mockConfig(store));
|
|
21
|
-
final dir = Directory.systemTemp.createTempSync('fp_s3_').path;
|
|
22
|
-
tmpFile = '$dir/bundle.zip';
|
|
23
|
-
File(tmpFile).writeAsBytesSync([1, 2, 3, 4]);
|
|
24
|
-
outFile = '$dir/out.zip';
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
test('plugin metadata', () {
|
|
28
|
-
expect(plugin.name, 's3Storage');
|
|
29
|
-
expect(plugin.supportedProtocol, 's3');
|
|
30
|
-
expect(plugin.profiles.hasNode, isTrue);
|
|
31
|
-
expect(plugin.profiles.hasRuntime, isTrue);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
test('node upload + exists + downloadFile + delete', () async {
|
|
35
|
-
final node = plugin.profiles.node!;
|
|
36
|
-
final res = await node.upload('v1', tmpFile);
|
|
37
|
-
expect(res['storageUri'], 's3://test-bucket/v1/${basename(tmpFile)}');
|
|
38
|
-
expect(await node.exists(res['storageUri']!), isTrue);
|
|
39
|
-
|
|
40
|
-
await node.downloadFile(res['storageUri']!, outFile);
|
|
41
|
-
expect(File(outFile).readAsBytesSync(), [1, 2, 3, 4]);
|
|
42
|
-
|
|
43
|
-
await node.delete(res['storageUri']!);
|
|
44
|
-
expect(await node.exists(res['storageUri']!), isFalse);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
test('runtime getDownloadUrl + readText (and missing → null)', () async {
|
|
48
|
-
final node = plugin.profiles.node!;
|
|
49
|
-
final runtime = plugin.profiles.runtime!;
|
|
50
|
-
|
|
51
|
-
final manifest = '${Directory.systemTemp.path}/fp_manifest.json';
|
|
52
|
-
File(manifest).writeAsStringSync('{"hello":1}');
|
|
53
|
-
final uploaded = await node.upload('manifests', manifest);
|
|
54
|
-
|
|
55
|
-
final url = await runtime.getDownloadUrl(uploaded['storageUri']!);
|
|
56
|
-
expect(url['fileUrl'], contains('manifests/'));
|
|
57
|
-
|
|
58
|
-
final text = await runtime.readText(uploaded['storageUri']!);
|
|
59
|
-
expect(text, '{"hello":1}');
|
|
60
|
-
|
|
61
|
-
expect(await runtime.readText('s3://test-bucket/missing'), isNull);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
test('listObjects filters by prefix', () async {
|
|
65
|
-
final node = plugin.profiles.node!;
|
|
66
|
-
await node.upload('a', tmpFile);
|
|
67
|
-
await node.upload('b', tmpFile);
|
|
68
|
-
|
|
69
|
-
expect(await node.listObjects(), hasLength(2));
|
|
70
|
-
expect(await node.listObjects('a/'), hasLength(1));
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import 'dart:convert' show utf8;
|
|
2
|
-
|
|
3
|
-
import 'package:flutter_ota_kit_plugin_core/flutter_ota_kit_plugin_core.dart'
|
|
4
|
-
show StorageObject;
|
|
5
|
-
|
|
6
|
-
import 'package:flutter_ota_kit_aws/flutter_ota_kit_aws.dart'
|
|
7
|
-
show AwsS3ClientLike, AwsS3StorageConfig;
|
|
8
|
-
|
|
9
|
-
/// In-memory store backing [MockAwsS3Client].
|
|
10
|
-
class Store {
|
|
11
|
-
final Map<String, List<int>> objects = {};
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/// Mock AWS S3 client that stores objects in memory.
|
|
15
|
-
class MockAwsS3Client implements AwsS3ClientLike {
|
|
16
|
-
MockAwsS3Client(this.store, {this.bucketName = 'bucket'});
|
|
17
|
-
|
|
18
|
-
final Store store;
|
|
19
|
-
final String bucketName;
|
|
20
|
-
|
|
21
|
-
@override
|
|
22
|
-
Future<void> deleteObject(String key) async => store.objects.remove(key);
|
|
23
|
-
|
|
24
|
-
@override
|
|
25
|
-
Future<void> deleteObjects(List<String> keys) async {
|
|
26
|
-
for (final key in keys) {
|
|
27
|
-
store.objects.remove(key);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
@override
|
|
32
|
-
Future<bool> headObject(String key) async => store.objects.containsKey(key);
|
|
33
|
-
|
|
34
|
-
@override
|
|
35
|
-
Future<List<int>> getObjectAsBytes(String key) async {
|
|
36
|
-
final bytes = store.objects[key];
|
|
37
|
-
if (bytes == null) throw Exception('NoSuchKey: $key');
|
|
38
|
-
return bytes;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
@override
|
|
42
|
-
Future<String> getObjectAsString(String key) async =>
|
|
43
|
-
utf8.decode(await getObjectAsBytes(key));
|
|
44
|
-
|
|
45
|
-
@override
|
|
46
|
-
Future<String> getPresignedUrl(String key, {int expiresIn = 3600}) async =>
|
|
47
|
-
'https://$bucketName.s3.us-east-1.amazonaws.com/$bucketName/$key'
|
|
48
|
-
'?X-Amz-Signature=mock&X-Amz-Expires=$expiresIn';
|
|
49
|
-
|
|
50
|
-
@override
|
|
51
|
-
Future<List<StorageObject>> listObjects([String? prefix]) async {
|
|
52
|
-
final p = prefix ?? '';
|
|
53
|
-
return store.objects.keys
|
|
54
|
-
.where((k) => k.startsWith(p))
|
|
55
|
-
.map(
|
|
56
|
-
(k) => StorageObject(
|
|
57
|
-
key: k,
|
|
58
|
-
storageUri: 's3://$bucketName/$k',
|
|
59
|
-
size: store.objects[k]!.length,
|
|
60
|
-
),
|
|
61
|
-
)
|
|
62
|
-
.toList();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
@override
|
|
66
|
-
Future<void> putObject(String key, List<int> body, String contentType) async {
|
|
67
|
-
store.objects[key] = body;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/// Build an [AwsS3StorageConfig] wired to an in-memory [Store].
|
|
72
|
-
AwsS3StorageConfig mockConfig(Store store) => AwsS3StorageConfig(
|
|
73
|
-
bucketName: 'test-bucket',
|
|
74
|
-
region: 'us-east-1',
|
|
75
|
-
accessKeyId: 'test-access-key',
|
|
76
|
-
secretAccessKey: 'test-secret',
|
|
77
|
-
clientFactory: (_) => MockAwsS3Client(store),
|
|
78
|
-
);
|
|
File without changes
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
## 0.1.10
|
|
2
|
-
|
|
3
|
-
- Release 2026-09-10
|
|
4
|
-
|
|
5
|
-
## 0.1.9
|
|
6
|
-
|
|
7
|
-
- Release 2026-09-10
|
|
8
|
-
|
|
9
|
-
## 0.1.9
|
|
10
|
-
|
|
11
|
-
- Automated release 2026-09-10
|
|
12
|
-
|
|
13
|
-
## 0.1.8
|
|
14
|
-
|
|
15
|
-
- Added comprehensive documentation for all public APIs.
|
|
16
|
-
- Documented D1 database, R2 storage, and worker database plugins.
|
|
17
|
-
- General maintenance.
|
|
18
|
-
|
|
19
|
-
## 0.1.7
|
|
20
|
-
|
|
21
|
-
- General maintenance.
|
|
22
|
-
|
|
23
|
-
## 0.1.6
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 HYPER12755
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# flutter_ota_kit_cloudflare
|
|
2
|
-
|
|
3
|
-
Cloudflare backend for flutter_ota_kit: bundle metadata in **D1** (SQLite-at-edge)
|
|
4
|
-
and artifacts in **R2** (S3-compatible storage). Used by the `flutter-ota` CLI and
|
|
5
|
-
the Flutter SDK's `FlutterPatcher.configureCloudflare(...)`.
|
|
6
|
-
|
|
7
|
-
## What's inside
|
|
8
|
-
|
|
9
|
-
- `d1Database` / `D1DatabaseConfig` — bundle metadata in D1.
|
|
10
|
-
`CloudflareWorkerDatabaseConfig` / `cloudflareWorkerDatabase` for the
|
|
11
|
-
Worker-facing variant.
|
|
12
|
-
- `r2Storage` / `R2S3StorageConfig` — artifact storage in R2 (AWS SigV4).
|
|
13
|
-
- D1 row mappers and `D1ClientFactory` / `R2S3ClientFactory` test seams.
|
|
14
|
-
|
|
15
|
-
## Configuration (environment)
|
|
16
|
-
|
|
17
|
-
| Variable | Purpose |
|
|
18
|
-
| --- | --- |
|
|
19
|
-
| `CLOUDFLARE_ACCOUNT_ID` | Cloudflare account id. |
|
|
20
|
-
| `CLOUDFLARE_API_TOKEN` | API token with D1 read/write + R2 permissions. |
|
|
21
|
-
| R2 access/secret keys + bucket | Supplied via `R2S3StorageConfig` (see the CLI `init` and `doc/backends.md`). |
|
|
22
|
-
|
|
23
|
-
## License
|
|
24
|
-
|
|
25
|
-
MIT.
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
// flutter_ota_kit_cloudflare example
|
|
2
|
-
//
|
|
3
|
-
// `flutter_ota_kit_cloudflare` provides Cloudflare D1 (database) + R2
|
|
4
|
-
// (storage) plugins for `flutter_ota_kit`. D1 is Cloudflare's SQLite-
|
|
5
|
-
// based serverless database; R2 is S3-compatible object storage. The
|
|
6
|
-
// combo is the cheapest self-hostable option for low-traffic apps.
|
|
7
|
-
//
|
|
8
|
-
// Most apps don't import this package directly; they wire it through
|
|
9
|
-
// `flutter_ota_kit.configureCloudflare(...)` in their app boot path.
|
|
10
|
-
// This file shows the low-level config types in case you're writing a
|
|
11
|
-
// custom server or a CLI extension.
|
|
12
|
-
//
|
|
13
|
-
// Run: `dart run example/main.dart`
|
|
14
|
-
|
|
15
|
-
import 'package:flutter_ota_kit_cloudflare/flutter_ota_kit_cloudflare.dart';
|
|
16
|
-
|
|
17
|
-
void main() {
|
|
18
|
-
// ── 1. D1 database config (Cloudflare's SQLite). ─────────────────
|
|
19
|
-
// `databaseId` is the UUID of the D1 database. `accountId` is your
|
|
20
|
-
// Cloudflare account ID. `cloudflareApiToken` needs D1 read/write.
|
|
21
|
-
const d1Config = D1DatabaseConfig(
|
|
22
|
-
databaseId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
|
|
23
|
-
accountId: '0123456789abcdef0123456789abcdef',
|
|
24
|
-
cloudflareApiToken: 'cf-token-...',
|
|
25
|
-
);
|
|
26
|
-
print('D1 database: ${d1Config.databaseId}');
|
|
27
|
-
print('Account: ${d1Config.accountId}');
|
|
28
|
-
|
|
29
|
-
// ── 2. R2 storage config (S3-compatible object storage). ──────────
|
|
30
|
-
// R2 is S3-compatible: same `accessKeyId`/`secretAccessKey` flow,
|
|
31
|
-
// but the endpoint host is `{accountId}.r2.cloudflarestorage.com`.
|
|
32
|
-
const r2Config = R2S3StorageConfig(
|
|
33
|
-
accountId: '0123456789abcdef0123456789abcdef',
|
|
34
|
-
bucketName: 'flutter-ota-bundles',
|
|
35
|
-
accessKeyId: 'r2-access-key',
|
|
36
|
-
secretAccessKey: 'r2-secret-key',
|
|
37
|
-
basePath: 'bundles',
|
|
38
|
-
);
|
|
39
|
-
print('R2 bucket: ${r2Config.bucketName}');
|
|
40
|
-
print('Region: ${r2Config.region}');
|
|
41
|
-
|
|
42
|
-
// ── 3. Resolving a custom client (test seam). ────────────────────
|
|
43
|
-
// The `clientFactory` lets you inject a mock S3 client in tests or
|
|
44
|
-
// use a custom S3-compatible client in production.
|
|
45
|
-
// final client = resolveR2Client(r2Config);
|
|
46
|
-
|
|
47
|
-
// ── 4. Row-to-Bundle mapping (server-side helper). ────────────────
|
|
48
|
-
// Use this when reading bundles from a custom D1 query and passing
|
|
49
|
-
// them to the SDK's `PatchInfo.fromJson`. The mapper handles both
|
|
50
|
-
// camelCase and snake_case column names.
|
|
51
|
-
// const row = {
|
|
52
|
-
// 'id': '01a059a6-7d3c-4f3e-8a2c-9c2e3a4b5d6e',
|
|
53
|
-
// 'channel': 'production',
|
|
54
|
-
// 'enabled': true,
|
|
55
|
-
// 'file_hash': '7c4a8d09ca3762af61e59520943dc26494f8941b',
|
|
56
|
-
// 'storage_uri': 'r2://flutter-ota-bundles/01a059a6/patch.zip',
|
|
57
|
-
// 'target_app_version': '1.0.0',
|
|
58
|
-
// 'rollout_cohort_count': 100,
|
|
59
|
-
// };
|
|
60
|
-
// final bundle = transformRowToBundle(row);
|
|
61
|
-
// print('Mapped bundle: ${bundle.id} (${bundle.storageUri})');
|
|
62
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
-- Migration number: 0001 2025-01-27T08:37:50.374Z
|
|
2
|
-
-- HotUpdater.bundles
|
|
3
|
-
|
|
4
|
-
CREATE TABLE bundles (
|
|
5
|
-
id TEXT PRIMARY KEY,
|
|
6
|
-
platform TEXT NOT NULL CHECK (platform IN ('ios', 'android')),
|
|
7
|
-
target_app_version TEXT NOT NULL,
|
|
8
|
-
should_force_update INTEGER NOT NULL CHECK (should_force_update IN (0, 1)),
|
|
9
|
-
enabled INTEGER NOT NULL CHECK (enabled IN (0, 1)),
|
|
10
|
-
file_url TEXT NOT NULL,
|
|
11
|
-
file_hash TEXT NOT NULL,
|
|
12
|
-
git_commit_hash TEXT,
|
|
13
|
-
message TEXT
|
|
14
|
-
);
|
|
15
|
-
|
|
16
|
-
CREATE INDEX bundles_target_app_version_idx ON bundles(target_app_version);
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
-- Migration number: 0003 2025-05-18T16:25:12.486Z
|
|
2
|
-
-- HotUpdater.bundles
|
|
3
|
-
|
|
4
|
-
ALTER TABLE bundles ADD COLUMN fingerprint_hash TEXT;
|
|
5
|
-
ALTER TABLE bundles ADD COLUMN storage_uri TEXT;
|
|
6
|
-
ALTER TABLE bundles ADD COLUMN metadata JSONB DEFAULT '{}';
|
|
7
|
-
|
|
8
|
-
UPDATE bundles
|
|
9
|
-
SET storage_uri = 'r2://%%BUCKET_NAME%%/' || id || '/bundle.zip'
|
|
10
|
-
WHERE storage_uri IS NULL;
|
|
11
|
-
|
|
12
|
-
CREATE TABLE bundles_temp (
|
|
13
|
-
id TEXT PRIMARY KEY,
|
|
14
|
-
platform TEXT NOT NULL,
|
|
15
|
-
should_force_update INTEGER NOT NULL,
|
|
16
|
-
enabled INTEGER NOT NULL,
|
|
17
|
-
file_hash TEXT NOT NULL,
|
|
18
|
-
git_commit_hash TEXT,
|
|
19
|
-
message TEXT,
|
|
20
|
-
channel TEXT NOT NULL DEFAULT 'production',
|
|
21
|
-
storage_uri TEXT NOT NULL,
|
|
22
|
-
target_app_version TEXT,
|
|
23
|
-
fingerprint_hash TEXT,
|
|
24
|
-
metadata JSONB DEFAULT '{}',
|
|
25
|
-
CHECK ((target_app_version IS NOT NULL) OR (fingerprint_hash IS NOT NULL))
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
INSERT INTO bundles_temp
|
|
29
|
-
SELECT id, platform, should_force_update, enabled, file_hash, git_commit_hash, message, channel, storage_uri, target_app_version, fingerprint_hash, metadata
|
|
30
|
-
FROM bundles;
|
|
31
|
-
|
|
32
|
-
DROP TABLE bundles;
|
|
33
|
-
|
|
34
|
-
ALTER TABLE bundles_temp RENAME TO bundles;
|
|
35
|
-
|
|
36
|
-
CREATE INDEX bundles_target_app_version_idx ON bundles(target_app_version);
|
|
37
|
-
CREATE INDEX bundles_fingerprint_hash_idx ON bundles(fingerprint_hash);
|
|
38
|
-
CREATE INDEX bundles_channel_idx ON bundles(channel);
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
-- Migration number: 0004 2025-12-21T00:00:00.000Z
|
|
2
|
-
|
|
3
|
-
-- HotUpdater.bundles
|
|
4
|
-
|
|
5
|
-
ALTER TABLE bundles ADD COLUMN rollout_cohort_count INTEGER DEFAULT 1000
|
|
6
|
-
CHECK (rollout_cohort_count >= 0 AND rollout_cohort_count <= 1000);
|
|
7
|
-
|
|
8
|
-
CREATE INDEX IF NOT EXISTS bundles_rollout_idx ON bundles(rollout_cohort_count);
|
|
9
|
-
|
|
10
|
-
-- SQLite doesn't have array type, store as JSON text
|
|
11
|
-
ALTER TABLE bundles ADD COLUMN target_cohorts TEXT;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
-- Migration number: 0005 2026-04-22T00:00:00.000Z
|
|
2
|
-
|
|
3
|
-
-- HotUpdater.bundle_artifact_columns
|
|
4
|
-
|
|
5
|
-
ALTER TABLE bundles ADD COLUMN manifest_storage_uri TEXT;
|
|
6
|
-
ALTER TABLE bundles ADD COLUMN manifest_file_hash TEXT;
|
|
7
|
-
ALTER TABLE bundles ADD COLUMN asset_base_storage_uri TEXT;
|
|
8
|
-
|
|
9
|
-
CREATE TABLE bundle_patches (
|
|
10
|
-
id TEXT PRIMARY KEY,
|
|
11
|
-
bundle_id TEXT NOT NULL,
|
|
12
|
-
base_bundle_id TEXT NOT NULL,
|
|
13
|
-
base_file_hash TEXT NOT NULL,
|
|
14
|
-
patch_file_hash TEXT NOT NULL,
|
|
15
|
-
patch_storage_uri TEXT NOT NULL,
|
|
16
|
-
order_index INTEGER NOT NULL DEFAULT 0,
|
|
17
|
-
FOREIGN KEY (bundle_id) REFERENCES bundles(id) ON DELETE CASCADE,
|
|
18
|
-
FOREIGN KEY (base_bundle_id) REFERENCES bundles(id) ON DELETE CASCADE
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
CREATE INDEX IF NOT EXISTS bundle_patches_bundle_id_idx
|
|
22
|
-
ON bundle_patches(bundle_id);
|
|
23
|
-
CREATE INDEX IF NOT EXISTS bundle_patches_base_bundle_id_idx
|
|
24
|
-
ON bundle_patches(base_bundle_id);
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
name: flutter_ota_kit_cloudflare
|
|
2
|
-
description: Cloudflare D1 + R2 storage plugins for flutter_ota_kit (faithful port of hot-updater plugins/cloudflare).
|
|
3
|
-
version: 0.1.10
|
|
4
|
-
homepage: https://github.com/HYPER12755/flutter-ota-kit
|
|
5
|
-
repository: https://github.com/HYPER12755/flutter-ota-kit
|
|
6
|
-
issue_tracker: https://github.com/HYPER12755/flutter-ota-kit/issues
|
|
7
|
-
documentation: https://github.com/HYPER12755/flutter-ota-kit#readme
|
|
8
|
-
license: MIT
|
|
9
|
-
|
|
10
|
-
environment:
|
|
11
|
-
sdk: ">=3.13.2 <4.0.0"
|
|
12
|
-
|
|
13
|
-
dependencies:
|
|
14
|
-
flutter_ota_kit_core: ^0.1.8
|
|
15
|
-
flutter_ota_kit_plugin_core: ^0.0.10
|
|
16
|
-
crypto: ^3.0.0
|
|
17
|
-
http: ^1.2.0
|
|
18
|
-
path: ^1.9.0
|
|
19
|
-
|
|
20
|
-
dev_dependencies:
|
|
21
|
-
test: ^1.25.0
|
|
22
|
-
lints: ^4.0.0
|
|
23
|
-
|
|
24
|
-
dependency_overrides:
|
|
25
|
-
flutter_ota_kit_core:
|
|
26
|
-
path: ../../packages/core
|
|
27
|
-
flutter_ota_kit_plugin_core:
|
|
28
|
-
path: ../plugin-core
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
-- HotUpdater.bundles
|
|
2
|
-
|
|
3
|
-
CREATE TABLE bundles (
|
|
4
|
-
id TEXT PRIMARY KEY,
|
|
5
|
-
platform TEXT NOT NULL CHECK (platform IN ('ios', 'android')),
|
|
6
|
-
target_app_version TEXT,
|
|
7
|
-
should_force_update INTEGER NOT NULL CHECK (should_force_update IN (0, 1)),
|
|
8
|
-
enabled INTEGER NOT NULL CHECK (enabled IN (0, 1)),
|
|
9
|
-
file_hash TEXT NOT NULL,
|
|
10
|
-
git_commit_hash TEXT,
|
|
11
|
-
message TEXT,
|
|
12
|
-
channel TEXT NOT NULL DEFAULT 'production',
|
|
13
|
-
storage_uri TEXT NOT NULL,
|
|
14
|
-
fingerprint_hash TEXT,
|
|
15
|
-
metadata JSONB DEFAULT '{}',
|
|
16
|
-
manifest_storage_uri TEXT,
|
|
17
|
-
manifest_file_hash TEXT,
|
|
18
|
-
asset_base_storage_uri TEXT,
|
|
19
|
-
rollout_cohort_count INTEGER DEFAULT 1000
|
|
20
|
-
CHECK (rollout_cohort_count >= 0 AND rollout_cohort_count <= 1000),
|
|
21
|
-
target_cohorts TEXT,
|
|
22
|
-
CHECK ((target_app_version IS NOT NULL) OR (fingerprint_hash IS NOT NULL))
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
CREATE TABLE bundle_patches (
|
|
26
|
-
id TEXT PRIMARY KEY,
|
|
27
|
-
bundle_id TEXT NOT NULL,
|
|
28
|
-
base_bundle_id TEXT NOT NULL,
|
|
29
|
-
base_file_hash TEXT NOT NULL,
|
|
30
|
-
patch_file_hash TEXT NOT NULL,
|
|
31
|
-
patch_storage_uri TEXT NOT NULL,
|
|
32
|
-
order_index INTEGER NOT NULL DEFAULT 0,
|
|
33
|
-
FOREIGN KEY (bundle_id) REFERENCES bundles(id) ON DELETE CASCADE,
|
|
34
|
-
FOREIGN KEY (base_bundle_id) REFERENCES bundles(id) ON DELETE CASCADE
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
CREATE INDEX bundles_target_app_version_idx ON bundles(target_app_version);
|
|
38
|
-
CREATE INDEX bundles_fingerprint_hash_idx ON bundles(fingerprint_hash);
|
|
39
|
-
CREATE INDEX bundles_channel_idx ON bundles(channel);
|
|
40
|
-
CREATE INDEX bundles_rollout_idx ON bundles(rollout_cohort_count);
|
|
41
|
-
CREATE INDEX bundle_patches_bundle_id_idx ON bundle_patches(bundle_id);
|
|
42
|
-
CREATE INDEX bundle_patches_base_bundle_id_idx ON bundle_patches(base_bundle_id);
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import 'package:flutter_ota_kit_core/flutter_ota_kit_core.dart'
|
|
2
|
-
show
|
|
3
|
-
AppVersionGetBundlesArgs,
|
|
4
|
-
Bundle,
|
|
5
|
-
BundlePatchArtifact,
|
|
6
|
-
FingerprintGetBundlesArgs,
|
|
7
|
-
Platform,
|
|
8
|
-
UpdateStatus,
|
|
9
|
-
nilUuid;
|
|
10
|
-
import 'package:flutter_ota_kit_plugin_core/flutter_ota_kit_plugin_core.dart'
|
|
11
|
-
show DatabasePlugin;
|
|
12
|
-
import 'package:test/test.dart';
|
|
13
|
-
|
|
14
|
-
import 'mock_d1_client.dart' show Store, newWorkerPlugin;
|
|
15
|
-
|
|
16
|
-
Bundle _makeBundle({
|
|
17
|
-
required String id,
|
|
18
|
-
String channel = 'production',
|
|
19
|
-
bool enabled = true,
|
|
20
|
-
String? fingerprintHash,
|
|
21
|
-
String? targetAppVersion,
|
|
22
|
-
String? message,
|
|
23
|
-
List<BundlePatchArtifact>? patches,
|
|
24
|
-
}) => Bundle(
|
|
25
|
-
id: id,
|
|
26
|
-
channel: channel,
|
|
27
|
-
enabled: enabled,
|
|
28
|
-
shouldForceUpdate: false,
|
|
29
|
-
fileHash: 'h-$id',
|
|
30
|
-
platform: Platform.android,
|
|
31
|
-
targetAppVersion: targetAppVersion,
|
|
32
|
-
storageUri: 's3://$id',
|
|
33
|
-
fingerprintHash: fingerprintHash,
|
|
34
|
-
message: message,
|
|
35
|
-
patches: patches,
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
void main() {
|
|
39
|
-
group('cloudflare d1WorkerDatabase', () {
|
|
40
|
-
late Store store;
|
|
41
|
-
late DatabasePlugin plugin;
|
|
42
|
-
|
|
43
|
-
setUp(() {
|
|
44
|
-
store = Store();
|
|
45
|
-
plugin = newWorkerPlugin(store);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
test('getChannels returns distinct channels', () async {
|
|
49
|
-
await plugin.appendBundle(_makeBundle(id: 'a', channel: 'production'));
|
|
50
|
-
await plugin.appendBundle(_makeBundle(id: 'b', channel: 'staging'));
|
|
51
|
-
await plugin.appendBundle(_makeBundle(id: 'c', channel: 'production'));
|
|
52
|
-
await plugin.commitBundle();
|
|
53
|
-
|
|
54
|
-
final channels = await plugin.getChannels();
|
|
55
|
-
expect(channels, hasLength(2));
|
|
56
|
-
expect(channels, containsAll(['production', 'staging']));
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
test(
|
|
60
|
-
'getBundleById returns null for missing, bundle for existing',
|
|
61
|
-
() async {
|
|
62
|
-
await plugin.appendBundle(_makeBundle(id: 'b1'));
|
|
63
|
-
await plugin.commitBundle();
|
|
64
|
-
|
|
65
|
-
expect(await plugin.getBundleById('missing'), isNull);
|
|
66
|
-
final got = await plugin.getBundleById('b1');
|
|
67
|
-
expect(got, isNotNull);
|
|
68
|
-
expect(got!.id, 'b1');
|
|
69
|
-
},
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
test('commitBundle append -> update -> delete reflects in store', () async {
|
|
73
|
-
await plugin.appendBundle(_makeBundle(id: 'b1', message: 'original'));
|
|
74
|
-
await plugin.commitBundle();
|
|
75
|
-
expect((await plugin.getBundleById('b1'))!.message, 'original');
|
|
76
|
-
|
|
77
|
-
var got = await plugin.getBundleById('b1');
|
|
78
|
-
await plugin.updateBundle(got!.id, {'message': 'updated'});
|
|
79
|
-
await plugin.commitBundle();
|
|
80
|
-
expect((await plugin.getBundleById('b1'))!.message, 'updated');
|
|
81
|
-
|
|
82
|
-
got = await plugin.getBundleById('b1');
|
|
83
|
-
await plugin.deleteBundle(got!);
|
|
84
|
-
await plugin.commitBundle();
|
|
85
|
-
expect(await plugin.getBundleById('b1'), isNull);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
test(
|
|
89
|
-
'getUpdateInfo (appVersion) returns UpdateInfo for compatible bundle',
|
|
90
|
-
() async {
|
|
91
|
-
await plugin.appendBundle(
|
|
92
|
-
_makeBundle(id: 'b1', targetAppVersion: '1.0.0'),
|
|
93
|
-
);
|
|
94
|
-
await plugin.commitBundle();
|
|
95
|
-
|
|
96
|
-
final info = await plugin.getUpdateInfo(
|
|
97
|
-
AppVersionGetBundlesArgs(
|
|
98
|
-
platform: Platform.android,
|
|
99
|
-
bundleId: nilUuid,
|
|
100
|
-
appVersion: '1.0.0',
|
|
101
|
-
channel: 'production',
|
|
102
|
-
minBundleId: nilUuid,
|
|
103
|
-
),
|
|
104
|
-
);
|
|
105
|
-
expect(info, isNotNull);
|
|
106
|
-
expect(info!.id, 'b1');
|
|
107
|
-
expect(info.status, UpdateStatus.update);
|
|
108
|
-
},
|
|
109
|
-
);
|
|
110
|
-
|
|
111
|
-
test('getUpdateInfo (fingerprint) returns matching bundle', () async {
|
|
112
|
-
await plugin.appendBundle(_makeBundle(id: 'fp', fingerprintHash: 'fp1'));
|
|
113
|
-
await plugin.commitBundle();
|
|
114
|
-
|
|
115
|
-
final info = await plugin.getUpdateInfo(
|
|
116
|
-
FingerprintGetBundlesArgs(
|
|
117
|
-
platform: Platform.android,
|
|
118
|
-
bundleId: nilUuid,
|
|
119
|
-
fingerprintHash: 'fp1',
|
|
120
|
-
),
|
|
121
|
-
);
|
|
122
|
-
expect(info, isNotNull);
|
|
123
|
-
expect(info!.id, 'fp');
|
|
124
|
-
});
|
|
125
|
-
});
|
|
126
|
-
}
|