@_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.
Files changed (259) hide show
  1. package/README.md +112 -18
  2. package/bin/flutter-ota-linux-x64 +0 -0
  3. package/bin/flutter-ota.js +12 -11
  4. package/dart-src/packages/cli-tools/README.md +146 -2
  5. package/dart-src/packages/cli-tools/lib/flutter_ota_kit_cli.dart +46 -13
  6. package/dart-src/packages/cli-tools/lib/src/backend.dart +6 -6
  7. package/dart-src/packages/cli-tools/lib/src/commands/build.dart +2 -0
  8. package/dart-src/packages/cli-tools/lib/src/commands/bundle.dart +7 -7
  9. package/dart-src/packages/cli-tools/lib/src/commands/deploy.dart +4 -1
  10. package/dart-src/packages/cli-tools/lib/src/commands/init.dart +36 -8
  11. package/dart-src/packages/cli-tools/lib/src/commands/pocketbase.dart +1 -1
  12. package/dart-src/packages/cli-tools/lib/src/commands/rollback.dart +1 -1
  13. package/dart-src/packages/cli-tools/lib/src/config.dart +5 -5
  14. package/dart-src/packages/cli-tools/lib/src/operations.dart +2 -2
  15. package/dart-src/packages/cli-tools/pubspec.yaml +8 -21
  16. package/dart-src/packages/cli-tools/test/backends_test.dart +3 -3
  17. package/dart-src/packages/cli-tools/test/cli_test.dart +1 -1
  18. package/dart-src/packages/cli-tools/test/mocks/mock_aws_s3_client.dart +2 -2
  19. package/dart-src/packages/cli-tools/test/mocks/mock_d1_client.dart +2 -2
  20. package/dart-src/packages/cli-tools/test/mocks/mock_pocketbase_client.dart +4 -1
  21. package/dart-src/packages/cli-tools/test/mocks/mock_postgres_client.dart +2 -2
  22. package/dart-src/packages/cli-tools/test/pocketbase_smoke_test.dart +1 -1
  23. package/dart-src/root/README.md +334 -0
  24. package/dart-src/root/analysis_options.yaml +21 -0
  25. package/dart-src/root/android/build.gradle +116 -0
  26. package/dart-src/root/android/consumer-rules.pro +23 -0
  27. package/dart-src/root/android/settings.gradle +1 -0
  28. package/dart-src/root/android/src/main/AndroidManifest.xml +21 -0
  29. package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/ApplyResult.kt +52 -0
  30. package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/BlacklistStore.kt +154 -0
  31. package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/BootDiagnosticStore.kt +150 -0
  32. package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/CrashGuard.kt +271 -0
  33. package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/FlutterPatcherApplication.kt +201 -0
  34. package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/FlutterPatcherAutoInitProvider.kt +93 -0
  35. package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/FlutterPatcherPlugin.kt +245 -0
  36. package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/LoaderHook.kt +298 -0
  37. package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/PatchManager.kt +1579 -0
  38. package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/PatcherConfig.kt +173 -0
  39. package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/SignatureVerifier.kt +177 -0
  40. package/dart-src/root/android/src/test/kotlin/com/flutter_patcher/flutter_patcher/CrashGuardTest.kt +61 -0
  41. package/dart-src/root/android/src/test/kotlin/com/flutter_patcher/flutter_patcher/LoaderHookTest.kt +25 -0
  42. package/dart-src/root/android/src/test/kotlin/com/flutter_patcher/flutter_patcher/PatchManagerTest.kt +401 -0
  43. package/dart-src/root/android/src/test/kotlin/com/flutter_patcher/flutter_patcher/PatcherConfigTest.kt +30 -0
  44. package/dart-src/root/bin/pack.dart +182 -0
  45. package/dart-src/root/lib/flutter_ota_kit.dart +1170 -0
  46. package/dart-src/root/lib/src/app_version_resolver.dart +36 -0
  47. package/dart-src/root/lib/src/aws_update_source.dart +97 -0
  48. package/dart-src/root/lib/src/blacklist.dart +54 -0
  49. package/dart-src/root/lib/src/boot_diagnostic.dart +138 -0
  50. package/dart-src/root/lib/src/cloudflare_update_source.dart +97 -0
  51. package/dart-src/root/lib/src/flutter_ota_app.dart +69 -0
  52. package/dart-src/root/lib/src/io.dart +48 -0
  53. package/dart-src/root/lib/src/io_stub.dart +19 -0
  54. package/dart-src/root/lib/src/ota_progress_overlay.dart +1186 -0
  55. package/dart-src/root/lib/src/pack/pack.dart +434 -0
  56. package/dart-src/root/lib/src/patch_info.dart +12 -0
  57. package/dart-src/root/lib/src/patcher_channel.dart +160 -0
  58. package/dart-src/{plugins/aws/lib → root/lib/src/pkg/aws}/src/aws_database.dart +1 -1
  59. package/dart-src/{plugins/aws/lib → root/lib/src/pkg/aws}/src/aws_s3_client.dart +1 -1
  60. package/dart-src/{plugins/aws/lib → root/lib/src/pkg/aws}/src/aws_storage.dart +1 -1
  61. package/dart-src/{plugins/aws/lib → root/lib/src/pkg/aws}/src/aws_storage_profile.dart +1 -1
  62. package/dart-src/{plugins/aws/lib → root/lib/src/pkg/aws}/src/with_cloudfront_signed_url.dart +1 -1
  63. package/dart-src/root/lib/src/pkg/client/flutter_ota_kit_client.dart +1 -0
  64. package/dart-src/root/lib/src/pkg/client/src/server_update_source.dart +46 -0
  65. package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/cloudflare_worker_database.dart +1 -1
  66. package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/d1_build_where.dart +1 -1
  67. package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/d1_bundle_mapper.dart +3 -3
  68. package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/d1_database.dart +1 -1
  69. package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/d1_database_plugin.dart +2 -2
  70. package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/r2_s3_client.dart +1 -1
  71. package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/r2_storage.dart +1 -1
  72. package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/r2_storage_profile.dart +1 -1
  73. package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/status.dart +1 -1
  74. package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/flutter_ota_kit_plugin_core.dart +1 -1
  75. package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/create_blob_database_plugin.dart +1 -1
  76. package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/filter_compatible_app_versions.dart +1 -1
  77. package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/get_update_info.dart +1 -1
  78. package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/request_update_bundle_state.dart +1 -1
  79. package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/resolve_update_info_from_bundles.dart +1 -1
  80. package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/types.dart +2 -2
  81. package/dart-src/{plugins/pocketbase/lib → root/lib/src/pkg/pocketbase}/src/pocketbase_bundle_mapper.dart +2 -2
  82. package/dart-src/{plugins/pocketbase/lib → root/lib/src/pkg/pocketbase}/src/pocketbase_database.dart +26 -15
  83. package/dart-src/{plugins/pocketbase/lib → root/lib/src/pkg/pocketbase}/src/pocketbase_storage.dart +1 -1
  84. package/dart-src/{plugins/postgres/lib → root/lib/src/pkg/postgres}/src/postgres_bundle_mapper.dart +2 -2
  85. package/dart-src/{plugins/postgres/lib → root/lib/src/pkg/postgres}/src/postgres_database.dart +2 -2
  86. package/dart-src/{plugins/postgres/lib → root/lib/src/pkg/postgres}/src/postgres_get_update_info.dart +2 -2
  87. package/dart-src/{plugins/postgres/lib → root/lib/src/pkg/postgres}/src/postgres_storage.dart +1 -1
  88. package/dart-src/{plugins/postgres/lib → root/lib/src/pkg/postgres}/src/postgres_types.dart +1 -1
  89. package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/supabase_bundle_mapper.dart +2 -2
  90. package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/supabase_database.dart +2 -2
  91. package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/supabase_edge_function_database.dart +1 -1
  92. package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/supabase_edge_function_storage.dart +1 -1
  93. package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/supabase_storage.dart +1 -1
  94. package/dart-src/root/lib/src/pocketbase_update_source.dart +107 -0
  95. package/dart-src/root/lib/src/postgres_update_source.dart +95 -0
  96. package/dart-src/root/lib/src/shared_update_check.dart +131 -0
  97. package/dart-src/root/lib/src/supabase_update_source.dart +93 -0
  98. package/dart-src/root/pubspec.yaml +54 -0
  99. package/package.json +1 -1
  100. package/scripts/postinstall.js +17 -13
  101. package/scripts/vendor.sh +22 -7
  102. package/dart-src/packages/core/CHANGELOG.md +0 -21
  103. package/dart-src/packages/core/README.md +0 -23
  104. package/dart-src/packages/core/example/lib/main.dart +0 -69
  105. package/dart-src/packages/core/pubspec.yaml +0 -13
  106. package/dart-src/packages/core/test/rollout_test.dart +0 -135
  107. package/dart-src/packages/core/test/semver_test.dart +0 -55
  108. package/dart-src/packages/core/test/semver_vectors.json +0 -1
  109. package/dart-src/packages/core/test/types_test.dart +0 -131
  110. package/dart-src/packages/core/test/uuid_test.dart +0 -40
  111. package/dart-src/packages/core/tool/dbg.dart +0 -7
  112. package/dart-src/plugins/aws/.gitkeep +0 -0
  113. package/dart-src/plugins/aws/CHANGELOG.md +0 -23
  114. package/dart-src/plugins/aws/LICENSE +0 -21
  115. package/dart-src/plugins/aws/README.md +0 -28
  116. package/dart-src/plugins/aws/example/lib/main.dart +0 -60
  117. package/dart-src/plugins/aws/pubspec.yaml +0 -30
  118. package/dart-src/plugins/aws/test/aws_database_test.dart +0 -161
  119. package/dart-src/plugins/aws/test/aws_storage_test.dart +0 -73
  120. package/dart-src/plugins/aws/test/mock_aws_s3_client.dart +0 -78
  121. package/dart-src/plugins/cloudflare/.gitkeep +0 -0
  122. package/dart-src/plugins/cloudflare/CHANGELOG.md +0 -23
  123. package/dart-src/plugins/cloudflare/LICENSE +0 -21
  124. package/dart-src/plugins/cloudflare/README.md +0 -25
  125. package/dart-src/plugins/cloudflare/example/lib/main.dart +0 -62
  126. package/dart-src/plugins/cloudflare/migrations/0001_hot-updater_init.sql +0 -16
  127. package/dart-src/plugins/cloudflare/migrations/0002_hot-updater_0.13.0.sql +0 -8
  128. package/dart-src/plugins/cloudflare/migrations/0003_hot-updater_0.18.0.sql +0 -38
  129. package/dart-src/plugins/cloudflare/migrations/0004_hot-updater_0.29.0.sql +0 -11
  130. package/dart-src/plugins/cloudflare/migrations/0005_hot-updater_0.31.0.sql +0 -24
  131. package/dart-src/plugins/cloudflare/pubspec.yaml +0 -28
  132. package/dart-src/plugins/cloudflare/sql/bundles.sql +0 -42
  133. package/dart-src/plugins/cloudflare/test/cloudflare_worker_database_test.dart +0 -126
  134. package/dart-src/plugins/cloudflare/test/d1_bundle_mapper_test.dart +0 -106
  135. package/dart-src/plugins/cloudflare/test/d1_database_test.dart +0 -200
  136. package/dart-src/plugins/cloudflare/test/mock_d1_client.dart +0 -261
  137. package/dart-src/plugins/cloudflare/test/mock_r2_client.dart +0 -78
  138. package/dart-src/plugins/cloudflare/test/r2_storage_test.dart +0 -74
  139. package/dart-src/plugins/plugin-core/CHANGELOG.md +0 -20
  140. package/dart-src/plugins/plugin-core/LICENSE +0 -21
  141. package/dart-src/plugins/plugin-core/README.md +0 -21
  142. package/dart-src/plugins/plugin-core/example/lib/main.dart +0 -61
  143. package/dart-src/plugins/plugin-core/pubspec.yaml +0 -23
  144. package/dart-src/plugins/plugin-core/test/asset_storage_layout_test.dart +0 -170
  145. package/dart-src/plugins/plugin-core/test/bundle_unit_of_work_store_test.dart +0 -74
  146. package/dart-src/plugins/plugin-core/test/bundle_unit_of_work_test.dart +0 -345
  147. package/dart-src/plugins/plugin-core/test/create_blob_database_plugin_test.dart +0 -843
  148. package/dart-src/plugins/plugin-core/test/create_database_plugin_test.dart +0 -298
  149. package/dart-src/plugins/plugin-core/test/create_storage_plugin_test.dart +0 -195
  150. package/dart-src/plugins/plugin-core/test/generate_min_bundle_id_test.dart +0 -56
  151. package/dart-src/plugins/plugin-core/test/get_update_info_test.dart +0 -1589
  152. package/dart-src/plugins/plugin-core/test/helpers_test.dart +0 -283
  153. package/dart-src/plugins/plugin-core/test/query_bundles_test.dart +0 -202
  154. package/dart-src/plugins/plugin-core/test/request_update_bundle_state_test.dart +0 -86
  155. package/dart-src/plugins/plugin-core/test/uuidv7_test.dart +0 -88
  156. package/dart-src/plugins/pocketbase/CHANGELOG.md +0 -23
  157. package/dart-src/plugins/pocketbase/LICENSE +0 -21
  158. package/dart-src/plugins/pocketbase/README.md +0 -54
  159. package/dart-src/plugins/pocketbase/example/lib/main.dart +0 -62
  160. package/dart-src/plugins/pocketbase/pubspec.yaml +0 -26
  161. package/dart-src/plugins/pocketbase/test/pb_uri_test.dart +0 -12
  162. package/dart-src/plugins/postgres/.gitkeep +0 -0
  163. package/dart-src/plugins/postgres/CHANGELOG.md +0 -23
  164. package/dart-src/plugins/postgres/LICENSE +0 -21
  165. package/dart-src/plugins/postgres/README.md +0 -29
  166. package/dart-src/plugins/postgres/example/lib/main.dart +0 -67
  167. package/dart-src/plugins/postgres/pubspec.yaml +0 -26
  168. package/dart-src/plugins/postgres/sql/bundles.sql +0 -45
  169. package/dart-src/plugins/postgres/sql/get_target_app_version_list.sql +0 -21
  170. package/dart-src/plugins/postgres/sql/get_update_info.spec.ts +0 -171
  171. package/dart-src/plugins/postgres/sql/get_update_info_by_app_version.sql +0 -126
  172. package/dart-src/plugins/postgres/sql/get_update_info_by_fingerprint_hash.sql +0 -125
  173. package/dart-src/plugins/postgres/sql/hash_user_id.sql +0 -30
  174. package/dart-src/plugins/postgres/sql/is_device_eligible.sql +0 -237
  175. package/dart-src/plugins/postgres/sql/prepareSql.ts +0 -11
  176. package/dart-src/plugins/postgres/test/mock_postgres_client.dart +0 -320
  177. package/dart-src/plugins/postgres/test/postgres_bundle_mapper_test.dart +0 -139
  178. package/dart-src/plugins/postgres/test/postgres_database_test.dart +0 -210
  179. package/dart-src/plugins/postgres/test/postgres_storage_runtime_test.dart +0 -60
  180. package/dart-src/plugins/supabase/CHANGELOG.md +0 -24
  181. package/dart-src/plugins/supabase/LICENSE +0 -21
  182. package/dart-src/plugins/supabase/README.md +0 -53
  183. package/dart-src/plugins/supabase/example/lib/main.dart +0 -63
  184. package/dart-src/plugins/supabase/pubspec.yaml +0 -27
  185. package/dart-src/plugins/supabase/supabase/edge-functions/index.ts +0 -44
  186. package/dart-src/plugins/supabase/supabase/edge-functions/runtime.docker.integration.spec.ts +0 -968
  187. package/dart-src/plugins/supabase/supabase/migrations/20250103114225_init.sql +0 -232
  188. package/dart-src/plugins/supabase/supabase/migrations/20250314000000_hot-updater_0.13.0.sql +0 -137
  189. package/dart-src/plugins/supabase/supabase/migrations/20250516000000_hot-updater_0.18.0.sql +0 -206
  190. package/dart-src/plugins/supabase/supabase/migrations/20251014000000_hot-updater_0.21.0.sql +0 -186
  191. package/dart-src/plugins/supabase/supabase/migrations/20260401000000_hot-updater_0.29.0.sql +0 -505
  192. package/dart-src/plugins/supabase/supabase/migrations/20260414000000_hot-updater_0.30.0.sql +0 -50
  193. package/dart-src/plugins/supabase/supabase/migrations/20260422000000_hot-updater_0.31.0.sql +0 -20
  194. package/dart-src/plugins/supabase/supabase/migrations/20260520014100_hot-updater_rls.sql +0 -75
  195. package/dart-src/plugins/supabase/test/mock_supabase_client.dart +0 -654
  196. package/dart-src/plugins/supabase/test/supabase_bundle_mapper_test.dart +0 -115
  197. package/dart-src/plugins/supabase/test/supabase_database_test.dart +0 -198
  198. package/dart-src/plugins/supabase/test/supabase_storage_test.dart +0 -168
  199. /package/dart-src/{packages/core → root}/LICENSE +0 -0
  200. /package/dart-src/{plugins/aws/lib → root/lib/src/pkg/aws}/flutter_ota_kit_aws.dart +0 -0
  201. /package/dart-src/{plugins/aws/lib → root/lib/src/pkg/aws}/src/aws_cloudfront_client.dart +0 -0
  202. /package/dart-src/{plugins/aws/lib → root/lib/src/pkg/aws}/src/aws_cloudfront_signer.dart +0 -0
  203. /package/dart-src/{plugins/aws/lib → root/lib/src/pkg/aws}/src/aws_config.dart +0 -0
  204. /package/dart-src/{plugins/aws/lib → root/lib/src/pkg/aws}/src/aws_ssm_client.dart +0 -0
  205. /package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/flutter_ota_kit_cloudflare.dart +0 -0
  206. /package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/d1_client.dart +0 -0
  207. /package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/d1_config.dart +0 -0
  208. /package/dart-src/{plugins/cloudflare/lib → root/lib/src/pkg/cloudflare}/src/r2_config.dart +0 -0
  209. /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/flutter_ota_kit_core.dart +0 -0
  210. /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/app_update_info.dart +0 -0
  211. /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/bundle.dart +0 -0
  212. /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/bundle_artifacts.dart +0 -0
  213. /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/bundle_patch_artifact.dart +0 -0
  214. /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/changed_asset.dart +0 -0
  215. /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/get_bundles_args.dart +0 -0
  216. /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/metadata.dart +0 -0
  217. /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/patch_info.dart +0 -0
  218. /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/platform.dart +0 -0
  219. /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/rollout.dart +0 -0
  220. /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/semver.dart +0 -0
  221. /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/semver_range.dart +0 -0
  222. /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/semver_version.dart +0 -0
  223. /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/strategy.dart +0 -0
  224. /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/update_bundle_params.dart +0 -0
  225. /package/dart-src/{packages/core/lib → root/lib/src/pkg/core}/src/uuid.dart +0 -0
  226. /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/asset_storage_layout.dart +0 -0
  227. /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/bundle_helpers.dart +0 -0
  228. /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/bundle_storage_layout.dart +0 -0
  229. /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/bundle_unit_of_work.dart +0 -0
  230. /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/bundle_unit_of_work_store.dart +0 -0
  231. /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/calculate_pagination.dart +0 -0
  232. /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/compression_format.dart +0 -0
  233. /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/content_addressed_assets.dart +0 -0
  234. /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/create_database_plugin.dart +0 -0
  235. /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/create_storage_key_builder.dart +0 -0
  236. /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/create_storage_plugin.dart +0 -0
  237. /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/generate_min_bundle_id.dart +0 -0
  238. /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/is_object.dart +0 -0
  239. /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/legacy_asset_storage_layout.dart +0 -0
  240. /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/paginate_bundles.dart +0 -0
  241. /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/parse_storage_uri.dart +0 -0
  242. /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/query_bundles.dart +0 -0
  243. /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/storage_helpers.dart +0 -0
  244. /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/storage_profile.dart +0 -0
  245. /package/dart-src/{plugins/plugin-core/lib → root/lib/src/pkg/plugin_core}/src/uuidv7.dart +0 -0
  246. /package/dart-src/{plugins/pocketbase/lib → root/lib/src/pkg/pocketbase}/flutter_ota_kit_pocketbase.dart +0 -0
  247. /package/dart-src/{plugins/pocketbase/lib → root/lib/src/pkg/pocketbase}/src/pocketbase_client.dart +0 -0
  248. /package/dart-src/{plugins/pocketbase/lib → root/lib/src/pkg/pocketbase}/src/pocketbase_config.dart +0 -0
  249. /package/dart-src/{plugins/postgres/lib → root/lib/src/pkg/postgres}/flutter_ota_kit_postgres.dart +0 -0
  250. /package/dart-src/{plugins/postgres/lib → root/lib/src/pkg/postgres}/src/postgres_client.dart +0 -0
  251. /package/dart-src/{plugins/postgres/lib → root/lib/src/pkg/postgres}/src/postgres_config.dart +0 -0
  252. /package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/edge.dart +0 -0
  253. /package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/flutter_ota_kit_supabase.dart +0 -0
  254. /package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/error_message.dart +0 -0
  255. /package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/supabase_client_adapter.dart +0 -0
  256. /package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/supabase_client_http.dart +0 -0
  257. /package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/supabase_config.dart +0 -0
  258. /package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/supabase_signed_url_batcher.dart +0 -0
  259. /package/dart-src/{plugins/supabase/lib → root/lib/src/pkg/supabase}/src/types.dart +0 -0
@@ -1,320 +0,0 @@
1
- import 'package:flutter_ota_kit_plugin_core/flutter_ota_kit_plugin_core.dart';
2
-
3
- import 'package:flutter_ota_kit_postgres/flutter_ota_kit_postgres.dart';
4
-
5
- /// In-memory store backing [MockPostgresClient]. Mirrors the `bundles` and
6
- /// `bundle_patches` tables (snake_case row maps).
7
- class Store {
8
- Store({List<Bundle>? seed}) {
9
- if (seed != null) {
10
- for (final b in seed) {
11
- bundleRows.add(bundleToRowValues(b));
12
- bundlePatchRows.addAll(bundleToPatchRows(b));
13
- }
14
- }
15
- }
16
-
17
- final List<Map<String, dynamic>> bundleRows = [];
18
- final List<Map<String, dynamic>> bundlePatchRows = [];
19
-
20
- Map<String, dynamic>? bundleRowById(String id) => bundleRows
21
- .where((row) => row['id'] == id)
22
- .cast<Map<String, dynamic>?>()
23
- .firstOrNull;
24
- }
25
-
26
- /// Mock [PostgresClientLike] that emulates the queries the plugin issues
27
- /// against an in-memory [Store]. Faithful enough to exercise the plugin's
28
- /// SQL building, row mapping, transactions, and RPC calls without a live DB.
29
- class MockPostgresClient implements PostgresClientLike {
30
- MockPostgresClient(this.store);
31
-
32
- final Store store;
33
- final List<String> executedSqls = [];
34
- final List<Map<String, dynamic>> executedParams = [];
35
-
36
- @override
37
- Future<List<Map<String, dynamic>>> execute(
38
- String sql,
39
- Map<String, dynamic> parameters,
40
- ) async {
41
- executedSqls.add(sql);
42
- executedParams.add(parameters);
43
- return _handle(sql, parameters);
44
- }
45
-
46
- @override
47
- Future<T> runTx<T>(Future<T> Function(PostgresClientLike tx) fn) async {
48
- return fn(_TxClient(this));
49
- }
50
-
51
- @override
52
- Future<void> close() async {}
53
-
54
- List<Map<String, dynamic>> _handle(String sql, Map<String, dynamic> params) {
55
- if (sql.contains('get_target_app_version_list')) {
56
- return _targetAppVersionList(params);
57
- }
58
- if (sql.contains('get_update_info_by_app_version')) {
59
- return _updateInfoByAppVersion(params);
60
- }
61
- if (sql.contains('get_update_info_by_fingerprint_hash')) {
62
- return _updateInfoByFingerprint(params);
63
- }
64
- if (sql.contains('GROUP BY channel')) return _channels();
65
- if (sql.contains('COUNT(*)')) return _count(sql, params);
66
- if (sql.contains('FROM bundle_patches') && sql.contains('ANY')) {
67
- return _patchesForIds(params);
68
- }
69
- if (sql.contains('INSERT INTO bundle_patches')) {
70
- _upsertPatch(params);
71
- return [];
72
- }
73
- if (sql.contains('INSERT INTO bundles')) {
74
- _upsertBundle(params);
75
- return [];
76
- }
77
- if (sql.contains('DELETE FROM bundle_patches')) {
78
- _deletePatches(sql, params);
79
- return [];
80
- }
81
- if (sql.contains('DELETE FROM bundles')) {
82
- return _deleteBundle(sql, params);
83
- }
84
- if (sql.contains('SELECT * FROM bundles')) {
85
- return _selectBundles(sql, params);
86
- }
87
- return [];
88
- }
89
-
90
- dynamic _paramAfter(String sql, String token, Map<String, dynamic> params) {
91
- final idx = sql.indexOf(token);
92
- if (idx < 0) return null;
93
- final rest = sql.substring(idx + token.length).trim();
94
- final match = RegExp(r'@(\w+)').firstMatch(rest);
95
- if (match == null) return null;
96
- final name = match.group(1)!;
97
- return params['@$name'] ?? params[name];
98
- }
99
-
100
- List<Map<String, dynamic>> _filterBundles(
101
- String sql,
102
- Map<String, dynamic> params,
103
- ) {
104
- return store.bundleRows.where((row) {
105
- final channel = _paramAfter(sql, 'channel =', params);
106
- if (channel != null && row['channel'] != channel) return false;
107
- final platform = _paramAfter(sql, 'platform =', params);
108
- if (platform != null && row['platform'] != platform) return false;
109
- final enabled = _paramAfter(sql, 'enabled =', params);
110
- if (enabled != null && row['enabled'] != enabled) return false;
111
- final target = _paramAfter(sql, 'target_app_version =', params);
112
- if (target != null && row['target_app_version'] != target) return false;
113
- final idEq = _paramAfter(sql, 'id =', params);
114
- if (idEq != null && row['id'] != idEq) return false;
115
- return true;
116
- }).toList();
117
- }
118
-
119
- List<Map<String, dynamic>> _selectBundles(
120
- String sql,
121
- Map<String, dynamic> params,
122
- ) {
123
- var rows = _filterBundles(sql, params);
124
-
125
- if (sql.contains('ORDER BY id asc')) {
126
- rows = rows.toList()
127
- ..sort((a, b) => (a['id'] as String).compareTo(b['id'] as String));
128
- } else {
129
- rows = rows.toList()
130
- ..sort((a, b) => (b['id'] as String).compareTo(a['id'] as String));
131
- }
132
-
133
- final limit = params['@limit'] as int?;
134
- final offset = params['@offset'] as int? ?? 0;
135
- if (limit != null && limit > 0) {
136
- final end = (offset + limit).clamp(0, rows.length);
137
- rows = rows.sublist(offset.clamp(0, rows.length), end);
138
- } else if (offset > 0) {
139
- rows = rows.sublist(offset.clamp(0, rows.length));
140
- }
141
- return rows;
142
- }
143
-
144
- List<Map<String, dynamic>> _count(String sql, Map<String, dynamic> params) {
145
- return [
146
- {'total': _filterBundles(sql, params).length},
147
- ];
148
- }
149
-
150
- List<Map<String, dynamic>> _channels() {
151
- final channels = store.bundleRows
152
- .map((r) => r['channel'] as String)
153
- .toSet()
154
- .toList();
155
- return channels.map((c) => {'channel': c}).toList();
156
- }
157
-
158
- List<Map<String, dynamic>> _patchesForIds(Map<String, dynamic> params) {
159
- final ids = (params['bundle_ids'] as List).cast<String>();
160
- return store.bundlePatchRows
161
- .where((p) => ids.contains(p['bundle_id']))
162
- .toList();
163
- }
164
-
165
- void _upsertBundle(Map<String, dynamic> params) {
166
- final row = <String, dynamic>{};
167
- params.forEach((k, v) => row[k] = v);
168
- final existing = store.bundleRows.indexWhere((r) => r['id'] == row['id']);
169
- if (existing >= 0) {
170
- store.bundleRows[existing] = row;
171
- } else {
172
- store.bundleRows.add(row);
173
- }
174
- }
175
-
176
- void _upsertPatch(Map<String, dynamic> params) {
177
- final row = <String, dynamic>{};
178
- params.forEach((k, v) => row[k] = v);
179
- final existing = store.bundlePatchRows.indexWhere(
180
- (r) => r['id'] == row['id'],
181
- );
182
- if (existing >= 0) {
183
- store.bundlePatchRows[existing] = row;
184
- } else {
185
- store.bundlePatchRows.add(row);
186
- }
187
- }
188
-
189
- void _deletePatches(String sql, Map<String, dynamic> params) {
190
- final id = params['@p0'] ?? params['p0'];
191
- if (sql.contains('base_bundle_id')) {
192
- store.bundlePatchRows.removeWhere((p) => p['base_bundle_id'] == id);
193
- } else {
194
- store.bundlePatchRows.removeWhere((p) => p['bundle_id'] == id);
195
- }
196
- }
197
-
198
- List<Map<String, dynamic>> _deleteBundle(
199
- String sql,
200
- Map<String, dynamic> params,
201
- ) {
202
- final id = params['@p0'] ?? params['p0'];
203
- final existed = store.bundleRows.any((r) => r['id'] == id);
204
- store.bundleRows.removeWhere((r) => r['id'] == id);
205
- store.bundlePatchRows.removeWhere((p) => p['bundle_id'] == id);
206
- return existed
207
- ? [
208
- {'id': id},
209
- ]
210
- : [];
211
- }
212
-
213
- List<Map<String, dynamic>> _targetAppVersionList(
214
- Map<String, dynamic> params,
215
- ) {
216
- final platform = params['app_platform'];
217
- final min = params['min_bundle_id'] as String? ?? '';
218
- final versions = store.bundleRows
219
- .where(
220
- (r) =>
221
- r['platform'] == platform &&
222
- (r['id'] as String).compareTo(min) >= 0,
223
- )
224
- .map((r) => r['target_app_version'])
225
- .where((v) => v != null)
226
- .toSet()
227
- .cast<String>()
228
- .toList();
229
- return versions.map((v) => {'target_app_version': v}).toList();
230
- }
231
-
232
- Map<String, dynamic>? _newestMatch(
233
- bool Function(Map<String, dynamic> row) predicate,
234
- ) {
235
- final matches = store.bundleRows.where(predicate).toList()
236
- ..sort((a, b) => (b['id'] as String).compareTo(a['id'] as String));
237
- return matches.isEmpty ? null : matches.first;
238
- }
239
-
240
- List<Map<String, dynamic>> _updateInfoByAppVersion(
241
- Map<String, dynamic> params,
242
- ) {
243
- final platform = params['app_platform'];
244
- final channel = params['target_channel'];
245
- final min = params['min_bundle_id'] as String? ?? '';
246
- final list =
247
- (params['target_app_version_list'] as List?)?.cast<String>() ?? [];
248
- final row = _newestMatch(
249
- (r) =>
250
- r['platform'] == platform &&
251
- r['enabled'] == true &&
252
- r['channel'] == channel &&
253
- (r['id'] as String).compareTo(min) >= 0 &&
254
- list.contains(r['target_app_version']),
255
- );
256
- if (row == null) return [];
257
- return [_infoRow(row)];
258
- }
259
-
260
- List<Map<String, dynamic>> _updateInfoByFingerprint(
261
- Map<String, dynamic> params,
262
- ) {
263
- final platform = params['app_platform'];
264
- final channel = params['target_channel'];
265
- final min = params['min_bundle_id'] as String? ?? '';
266
- final fp = params['target_fingerprint_hash'];
267
- final row = _newestMatch(
268
- (r) =>
269
- r['platform'] == platform &&
270
- r['enabled'] == true &&
271
- r['channel'] == channel &&
272
- (r['id'] as String).compareTo(min) >= 0 &&
273
- r['fingerprint_hash'] == fp,
274
- );
275
- if (row == null) return [];
276
- return [_infoRow(row)];
277
- }
278
-
279
- Map<String, dynamic> _infoRow(Map<String, dynamic> row) => {
280
- 'id': row['id'],
281
- 'should_force_update': row['should_force_update'],
282
- 'message': row['message'],
283
- 'status': 'UPDATE',
284
- 'storage_uri': row['storage_uri'],
285
- 'file_hash': row['file_hash'],
286
- };
287
- }
288
-
289
- class _TxClient implements PostgresClientLike {
290
- _TxClient(this._parent);
291
-
292
- final MockPostgresClient _parent;
293
-
294
- @override
295
- Future<List<Map<String, dynamic>>> execute(
296
- String sql,
297
- Map<String, dynamic> parameters,
298
- ) => _parent.execute(sql, parameters);
299
-
300
- @override
301
- Future<T> runTx<T>(Future<T> Function(PostgresClientLike tx) fn) =>
302
- throw UnsupportedError('Nested transactions are not supported');
303
-
304
- @override
305
- Future<void> close() async {}
306
- }
307
-
308
- /// Build a [PostgresConfig] wired to [MockPostgresClient].
309
- PostgresConfig mockPostgresConfig(Store store) => PostgresConfig(
310
- host: 'mock',
311
- database: 'mock',
312
- clientFactory: (_) => MockPostgresClient(store),
313
- );
314
-
315
- /// Create a [DatabasePlugin] backed by the mock store.
316
- DatabasePlugin newPlugin({Store? store}) {
317
- final s = store ?? Store();
318
- final plugin = postgresDatabase(mockPostgresConfig(s))();
319
- return plugin;
320
- }
@@ -1,139 +0,0 @@
1
- import 'package:flutter_ota_kit_core/flutter_ota_kit_core.dart'
2
- show Bundle, BundleMetadata, BundlePatchArtifact, Platform;
3
- import 'package:flutter_ota_kit_postgres/flutter_ota_kit_postgres.dart';
4
- import 'package:test/test.dart';
5
-
6
- void main() {
7
- group('postgres bundle mapper', () {
8
- test('bundleToRowValues emits snake_case columns', () {
9
- final bundle = Bundle(
10
- id: '018f0000-0000-7000-8000-000000000001',
11
- platform: Platform.android,
12
- shouldForceUpdate: true,
13
- enabled: true,
14
- fileHash: 'hash-1',
15
- gitCommitHash: 'abc',
16
- message: 'hello',
17
- channel: 'production',
18
- storageUri: 'file:///b1',
19
- targetAppVersion: '1.2.3',
20
- fingerprintHash: null,
21
- metadata: const BundleMetadata(appVersion: '1.2.3'),
22
- manifestStorageUri: 'file:///m1',
23
- manifestFileHash: 'mh1',
24
- assetBaseStorageUri: 'file:///a1',
25
- patches: const [
26
- BundlePatchArtifact(
27
- baseBundleId: '018f0000-0000-7000-8000-000000000000',
28
- baseFileHash: 'base-hash',
29
- patchFileHash: 'patch-hash',
30
- patchStorageUri: 'file:///p1',
31
- ),
32
- ],
33
- patchBaseBundleId: '018f0000-0000-7000-8000-000000000000',
34
- patchBaseFileHash: 'base-hash',
35
- patchFileHash: 'patch-hash',
36
- patchStorageUri: 'file:///p1',
37
- rolloutCohortCount: 1000,
38
- targetCohorts: const ['team-a'],
39
- );
40
-
41
- final row = bundleToRowValues(bundle);
42
- expect(row['id'], bundle.id);
43
- expect(row['should_force_update'], true);
44
- expect(row['file_hash'], 'hash-1');
45
- expect(row['target_app_version'], '1.2.3');
46
- expect(row['platform'], 'android');
47
- expect(row['manifest_storage_uri'], 'file:///m1');
48
- expect(row['rollout_cohort_count'], 1000);
49
- expect(row['target_cohorts'], const ['team-a']);
50
- expect(row['metadata'], isA<Map>());
51
- });
52
-
53
- test('mapRowToBundle rebuilds derived patch fields', () {
54
- final bundle = Bundle(
55
- id: '018f0000-0000-7000-8000-000000000001',
56
- platform: Platform.android,
57
- shouldForceUpdate: false,
58
- enabled: true,
59
- fileHash: 'hash-1',
60
- channel: 'production',
61
- storageUri: 'file:///b1',
62
- targetAppVersion: '1.2.3',
63
- message: null,
64
- fingerprintHash: null,
65
- metadata: const BundleMetadata(appVersion: '1.2.3'),
66
- manifestStorageUri: null,
67
- manifestFileHash: null,
68
- assetBaseStorageUri: null,
69
- patches: const [
70
- BundlePatchArtifact(
71
- baseBundleId: '018f0000-0000-7000-8000-000000000000',
72
- baseFileHash: 'base-hash',
73
- patchFileHash: 'patch-hash',
74
- patchStorageUri: 'file:///p1',
75
- ),
76
- ],
77
- patchBaseBundleId: null,
78
- patchBaseFileHash: null,
79
- patchFileHash: null,
80
- patchStorageUri: null,
81
- rolloutCohortCount: 1000,
82
- targetCohorts: null,
83
- );
84
-
85
- final row = bundleToRowValues(bundle);
86
- final patchRows = bundleToPatchRows(bundle);
87
- final back = mapRowToBundle(PostgresBundleRow.fromJson(row), [
88
- PostgresBundlePatchRow.fromJson(patchRows.first),
89
- ]);
90
-
91
- expect(back.id, bundle.id);
92
- expect(back.fileHash, 'hash-1');
93
- expect(back.patches, hasLength(1));
94
- expect(back.patches!.first.patchFileHash, 'patch-hash');
95
- expect(back.patchStorageUri, 'file:///p1');
96
- expect(back.rolloutCohortCount, 1000);
97
- expect(back.metadata?.appVersion, '1.2.3');
98
- });
99
-
100
- test('bundleToPatchRows builds compound ids', () {
101
- final bundle = Bundle(
102
- id: 'bid',
103
- platform: Platform.android,
104
- shouldForceUpdate: false,
105
- enabled: true,
106
- fileHash: 'h',
107
- channel: 'production',
108
- storageUri: 's',
109
- message: null,
110
- fingerprintHash: null,
111
- metadata: null,
112
- manifestStorageUri: null,
113
- manifestFileHash: null,
114
- assetBaseStorageUri: null,
115
- patches: const [
116
- BundlePatchArtifact(
117
- baseBundleId: 'base',
118
- baseFileHash: 'bh',
119
- patchFileHash: 'ph',
120
- patchStorageUri: 'ps',
121
- ),
122
- ],
123
- patchBaseBundleId: null,
124
- patchBaseFileHash: null,
125
- patchFileHash: null,
126
- patchStorageUri: null,
127
- rolloutCohortCount: 1000,
128
- targetCohorts: null,
129
- );
130
-
131
- final rows = bundleToPatchRows(bundle);
132
- expect(rows, hasLength(1));
133
- expect(rows.first['id'], 'bid:base');
134
- expect(rows.first['bundle_id'], 'bid');
135
- expect(rows.first['base_bundle_id'], 'base');
136
- expect(rows.first['order_index'], 0);
137
- });
138
- });
139
- }
@@ -1,210 +0,0 @@
1
- import 'package:flutter_ota_kit_core/flutter_ota_kit_core.dart'
2
- show
3
- AppVersionGetBundlesArgs,
4
- Bundle,
5
- FingerprintGetBundlesArgs,
6
- Platform,
7
- UpdateInfo,
8
- UpdateStatus,
9
- nilUuid;
10
- import 'package:flutter_ota_kit_plugin_core/flutter_ota_kit_plugin_core.dart'
11
- show DatabaseBundleQueryOptions, DatabaseBundleQueryWhere, Paginated;
12
- import 'package:test/test.dart';
13
-
14
- import 'mock_postgres_client.dart';
15
-
16
- Bundle _bundle(
17
- String id, {
18
- String channel = 'production',
19
- String? fingerprintHash,
20
- }) => Bundle(
21
- id: id,
22
- platform: Platform.android,
23
- shouldForceUpdate: false,
24
- enabled: true,
25
- fileHash: 'file-hash-$id',
26
- channel: channel,
27
- storageUri: 'file:///bundle-$id',
28
- targetAppVersion: '1.0.0',
29
- message: null,
30
- fingerprintHash: fingerprintHash,
31
- metadata: null,
32
- manifestStorageUri: null,
33
- manifestFileHash: null,
34
- assetBaseStorageUri: null,
35
- patches: const [],
36
- patchBaseBundleId: null,
37
- patchBaseFileHash: null,
38
- patchFileHash: null,
39
- patchStorageUri: null,
40
- rolloutCohortCount: 1000,
41
- targetCohorts: null,
42
- );
43
-
44
- void main() {
45
- group('postgresDatabase', () {
46
- test('getChannels returns distinct channels', () async {
47
- final plugin = newPlugin();
48
- await plugin.appendBundle(
49
- _bundle('018f0000-0000-7000-8000-000000000001'),
50
- );
51
- await plugin.appendBundle(
52
- _bundle('018f0000-0000-7000-8000-000000000002', channel: 'staging'),
53
- );
54
- await plugin.commitBundle();
55
-
56
- final channels = await plugin.getChannels();
57
- expect(channels, containsAll(['production', 'staging']));
58
- expect(channels.length, 2);
59
- });
60
-
61
- test('getBundles returns bundles and pagination', () async {
62
- final plugin = newPlugin();
63
- await plugin.appendBundle(
64
- _bundle('018f0000-0000-7000-8000-000000000001'),
65
- );
66
- await plugin.appendBundle(
67
- _bundle('018f0000-0000-7000-8000-000000000002'),
68
- );
69
- await plugin.commitBundle();
70
-
71
- final result = await plugin.getBundles(
72
- const DatabaseBundleQueryOptions(limit: 10),
73
- );
74
- expect(result, isA<Paginated<List<Bundle>>>());
75
- expect(result.data, hasLength(2));
76
- expect(result.pagination.total, 2);
77
- });
78
-
79
- test('getBundles filters by channel', () async {
80
- final plugin = newPlugin();
81
- await plugin.appendBundle(
82
- _bundle('018f0000-0000-7000-8000-000000000001'),
83
- );
84
- await plugin.appendBundle(
85
- _bundle('018f0000-0000-7000-8000-000000000002', channel: 'staging'),
86
- );
87
- await plugin.commitBundle();
88
-
89
- final result = await plugin.getBundles(
90
- DatabaseBundleQueryOptions(
91
- where: const DatabaseBundleQueryWhere(channel: 'staging'),
92
- limit: 10,
93
- ),
94
- );
95
- expect(result.data, hasLength(1));
96
- expect(result.data.first.channel, 'staging');
97
- });
98
-
99
- test(
100
- 'getBundleById returns null for missing, bundle for existing',
101
- () async {
102
- final plugin = newPlugin();
103
- await plugin.appendBundle(
104
- _bundle('018f0000-0000-7000-8000-000000000001'),
105
- );
106
- await plugin.commitBundle();
107
-
108
- expect(await plugin.getBundleById('does-not-exist'), isNull);
109
- final got = await plugin.getBundleById(
110
- '018f0000-0000-7000-8000-000000000001',
111
- );
112
- expect(got, isNotNull);
113
- expect(got!.id, '018f0000-0000-7000-8000-000000000001');
114
- },
115
- );
116
-
117
- test('commitBundle append -> update -> delete reflects in store', () async {
118
- final plugin = newPlugin();
119
- await plugin.appendBundle(
120
- _bundle('018f0000-0000-7000-8000-000000000001'),
121
- );
122
- await plugin.commitBundle();
123
-
124
- var got = await plugin.getBundleById(
125
- '018f0000-0000-7000-8000-000000000001',
126
- );
127
- expect(got!.enabled, true);
128
-
129
- await plugin.updateBundle(got.id, {'enabled': false});
130
- await plugin.commitBundle();
131
- got = await plugin.getBundleById('018f0000-0000-7000-8000-000000000001');
132
- expect(got!.enabled, false);
133
-
134
- await plugin.deleteBundle(got);
135
- await plugin.commitBundle();
136
- expect(
137
- await plugin.getBundleById('018f0000-0000-7000-8000-000000000001'),
138
- isNull,
139
- );
140
- });
141
-
142
- test(
143
- 'getUpdateInfo via RPC returns UpdateInfo for compatible bundle',
144
- () async {
145
- final plugin = newPlugin();
146
- await plugin.appendBundle(
147
- _bundle('018f0000-0000-7000-8000-000000000001'),
148
- );
149
- await plugin.commitBundle();
150
-
151
- final info = await plugin.getUpdateInfo(
152
- AppVersionGetBundlesArgs(
153
- appVersion: '1.0.0',
154
- bundleId: nilUuid,
155
- channel: 'production',
156
- minBundleId: nilUuid,
157
- platform: Platform.android,
158
- ),
159
- );
160
- expect(info, isA<UpdateInfo>());
161
- expect(info!.status, UpdateStatus.update);
162
- expect(
163
- info.storageUri,
164
- 'file:///bundle-018f0000-0000-7000-8000-000000000001',
165
- );
166
- },
167
- );
168
-
169
- test('getUpdateInfo via fingerprint returns matching bundle', () async {
170
- final plugin = newPlugin();
171
- final fpBundle = _bundle(
172
- '018f0000-0000-7000-8000-000000000001',
173
- fingerprintHash: 'fp-abc',
174
- );
175
- await plugin.appendBundle(fpBundle);
176
- await plugin.commitBundle();
177
-
178
- final info = await plugin.getUpdateInfo(
179
- FingerprintGetBundlesArgs(
180
- fingerprintHash: 'fp-abc',
181
- bundleId: nilUuid,
182
- channel: 'production',
183
- minBundleId: nilUuid,
184
- platform: Platform.android,
185
- ),
186
- );
187
- expect(info, isA<UpdateInfo>());
188
- expect(info!.fileHash, 'file-hash-018f0000-0000-7000-8000-000000000001');
189
- });
190
-
191
- test('getUpdateInfo returns null when no compatible bundle', () async {
192
- final plugin = newPlugin();
193
- await plugin.appendBundle(
194
- _bundle('018f0000-0000-7000-8000-000000000001'),
195
- );
196
- await plugin.commitBundle();
197
-
198
- final info = await plugin.getUpdateInfo(
199
- AppVersionGetBundlesArgs(
200
- appVersion: '9.9.9',
201
- bundleId: nilUuid,
202
- channel: 'production',
203
- minBundleId: nilUuid,
204
- platform: Platform.android,
205
- ),
206
- );
207
- expect(info, isNull);
208
- });
209
- });
210
- }