@_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,106 +0,0 @@
1
- import 'dart:convert' show jsonEncode;
2
-
3
- import 'package:flutter_ota_kit_core/flutter_ota_kit_core.dart'
4
- show Bundle, BundleMetadata, BundlePatchArtifact, Platform;
5
- import 'package:flutter_ota_kit_cloudflare/flutter_ota_kit_cloudflare.dart'
6
- show
7
- buildBundlePatchId,
8
- bundleToPatchRows,
9
- parseMetadata,
10
- transformRowToBundle;
11
- import 'package:test/test.dart';
12
-
13
- void main() {
14
- group('d1 bundle mapper', () {
15
- test('transformRowToBundle rebuilds derived patch fields', () {
16
- final row = {
17
- 'id': 'b1',
18
- 'channel': 'production',
19
- 'enabled': 1,
20
- 'should_force_update': 0,
21
- 'file_hash': 'h1',
22
- 'git_commit_hash': null,
23
- 'message': 'msg',
24
- 'platform': 'android',
25
- 'target_app_version': '1.0.0',
26
- 'storage_uri': 's3://b1',
27
- 'fingerprint_hash': null,
28
- 'metadata': jsonEncode({'app_version': '1.2.3'}),
29
- 'manifest_storage_uri': null,
30
- 'manifest_file_hash': null,
31
- 'asset_base_storage_uri': null,
32
- 'rollout_cohort_count': 100,
33
- 'target_cohorts': jsonEncode(['c1', 'c2']),
34
- };
35
- final patchRows = [
36
- {
37
- 'id': 'b1:base1',
38
- 'bundle_id': 'b1',
39
- 'base_bundle_id': 'base1',
40
- 'base_file_hash': 'bf1',
41
- 'patch_file_hash': 'pf1',
42
- 'patch_storage_uri': 's3://p1',
43
- 'order_index': 0,
44
- },
45
- ];
46
-
47
- final bundle = transformRowToBundle(row, patchRows);
48
-
49
- expect(bundle.id, 'b1');
50
- expect(bundle.enabled, isTrue);
51
- expect(bundle.shouldForceUpdate, isFalse);
52
- expect(bundle.platform, Platform.android);
53
- expect(bundle.targetAppVersion, '1.0.0');
54
- expect(bundle.targetCohorts, ['c1', 'c2']);
55
- expect(bundle.patches, hasLength(1));
56
- expect(bundle.patches!.first.baseBundleId, 'base1');
57
- expect(bundle.patchFileHashLegacy, 'pf1');
58
- expect(bundle.patchStorageUri, 's3://p1');
59
- expect(bundle.rolloutCohortCount, 100);
60
- expect(bundle.metadata, isA<BundleMetadata>());
61
- expect(bundle.metadata!.appVersion, '1.2.3');
62
- });
63
-
64
- test('bundleToPatchRows builds compound ids in order', () {
65
- final bundle = Bundle(
66
- id: 'b1',
67
- channel: 'production',
68
- enabled: true,
69
- shouldForceUpdate: false,
70
- fileHash: 'h1',
71
- platform: Platform.android,
72
- targetAppVersion: '1.0.0',
73
- storageUri: 's3://b1',
74
- patches: [
75
- BundlePatchArtifact(
76
- baseBundleId: 'base1',
77
- baseFileHash: 'bf1',
78
- patchFileHash: 'pf1',
79
- patchStorageUri: 's3://p1',
80
- ),
81
- BundlePatchArtifact(
82
- baseBundleId: 'base2',
83
- baseFileHash: 'bf2',
84
- patchFileHash: 'pf2',
85
- patchStorageUri: 's3://p2',
86
- ),
87
- ],
88
- );
89
-
90
- final rows = bundleToPatchRows(bundle);
91
-
92
- expect(rows, hasLength(2));
93
- expect(rows[0]['id'], buildBundlePatchId('b1', 'base1'));
94
- expect(rows[0]['order_index'], 0);
95
- expect(rows[1]['id'], buildBundlePatchId('b1', 'base2'));
96
- expect(rows[1]['order_index'], 1);
97
- });
98
-
99
- test('parseMetadata handles string, object and null', () {
100
- expect(parseMetadata(null), isNull);
101
- expect(parseMetadata(jsonEncode({'a': 1})), {'a': 1});
102
- expect(parseMetadata({'a': 1}), {'a': 1});
103
- expect(parseMetadata('not-json'), isNull);
104
- });
105
- });
106
- }
@@ -1,200 +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
12
- DatabaseBundleQueryOptions,
13
- DatabaseBundleQueryOrder,
14
- DatabaseBundleQueryWhere,
15
- DatabasePlugin;
16
- import 'package:test/test.dart';
17
-
18
- import 'mock_d1_client.dart' show Store, newPlugin;
19
-
20
- Bundle _makeBundle({
21
- required String id,
22
- String channel = 'production',
23
- bool enabled = true,
24
- String? fingerprintHash,
25
- String? targetAppVersion,
26
- String? message,
27
- List<BundlePatchArtifact>? patches,
28
- }) => Bundle(
29
- id: id,
30
- channel: channel,
31
- enabled: enabled,
32
- shouldForceUpdate: false,
33
- fileHash: 'h-$id',
34
- platform: Platform.android,
35
- targetAppVersion: targetAppVersion,
36
- storageUri: 's3://$id',
37
- fingerprintHash: fingerprintHash,
38
- message: message,
39
- patches: patches,
40
- );
41
-
42
- void main() {
43
- group('cloudflare d1Database', () {
44
- late Store store;
45
- late DatabasePlugin plugin;
46
-
47
- setUp(() {
48
- store = Store();
49
- plugin = newPlugin(store);
50
- });
51
-
52
- test('getChannels returns distinct channels', () async {
53
- await plugin.appendBundle(_makeBundle(id: 'a', channel: 'production'));
54
- await plugin.appendBundle(_makeBundle(id: 'b', channel: 'staging'));
55
- await plugin.appendBundle(_makeBundle(id: 'c', channel: 'production'));
56
- await plugin.commitBundle();
57
-
58
- final channels = await plugin.getChannels();
59
- expect(channels, hasLength(2));
60
- expect(channels, containsAll(['production', 'staging']));
61
- });
62
-
63
- test(
64
- 'getBundles returns bundles and pagination; filters by channel',
65
- () async {
66
- for (final id in ['b1', 'b2', 'b3']) {
67
- await plugin.appendBundle(_makeBundle(id: id));
68
- }
69
- await plugin.commitBundle();
70
-
71
- final res = await plugin.getBundles(
72
- DatabaseBundleQueryOptions(
73
- where: const DatabaseBundleQueryWhere(),
74
- limit: 2,
75
- offset: 0,
76
- orderBy: const DatabaseBundleQueryOrder(direction: 'desc'),
77
- ),
78
- );
79
- expect(res.data, hasLength(2));
80
- expect(res.pagination.total, 3);
81
- expect(res.pagination.hasNextPage, isTrue);
82
-
83
- final staging = await plugin.getBundles(
84
- DatabaseBundleQueryOptions(
85
- where: const DatabaseBundleQueryWhere(channel: 'staging'),
86
- limit: 10,
87
- offset: 0,
88
- ),
89
- );
90
- expect(staging.data, isEmpty);
91
- },
92
- );
93
-
94
- test(
95
- 'getBundleById returns null for missing, bundle for existing',
96
- () async {
97
- await plugin.appendBundle(_makeBundle(id: 'b1'));
98
- await plugin.commitBundle();
99
-
100
- expect(await plugin.getBundleById('missing'), isNull);
101
- final got = await plugin.getBundleById('b1');
102
- expect(got, isNotNull);
103
- expect(got!.id, 'b1');
104
- },
105
- );
106
-
107
- test('commitBundle append -> update -> delete reflects in store', () async {
108
- await plugin.appendBundle(_makeBundle(id: 'b1', message: 'original'));
109
- await plugin.commitBundle();
110
- expect((await plugin.getBundleById('b1'))!.message, 'original');
111
-
112
- var got = await plugin.getBundleById('b1');
113
- await plugin.updateBundle(got!.id, {'message': 'updated'});
114
- await plugin.commitBundle();
115
- expect((await plugin.getBundleById('b1'))!.message, 'updated');
116
-
117
- got = await plugin.getBundleById('b1');
118
- await plugin.deleteBundle(got!);
119
- await plugin.commitBundle();
120
- expect(await plugin.getBundleById('b1'), isNull);
121
- });
122
-
123
- test(
124
- 'getUpdateInfo (appVersion) returns UpdateInfo for compatible bundle',
125
- () async {
126
- await plugin.appendBundle(
127
- _makeBundle(id: 'b1', targetAppVersion: '1.0.0'),
128
- );
129
- await plugin.commitBundle();
130
-
131
- final info = await plugin.getUpdateInfo(
132
- AppVersionGetBundlesArgs(
133
- platform: Platform.android,
134
- bundleId: nilUuid,
135
- appVersion: '1.0.0',
136
- channel: 'production',
137
- minBundleId: nilUuid,
138
- ),
139
- );
140
-
141
- expect(info, isNotNull);
142
- expect(info!.id, 'b1');
143
- expect(info.status, UpdateStatus.update);
144
- },
145
- );
146
-
147
- test(
148
- 'getUpdateInfo (appVersion) returns null when no compatible bundle',
149
- () async {
150
- await plugin.appendBundle(
151
- _makeBundle(id: 'b1', targetAppVersion: '1.0.0'),
152
- );
153
- await plugin.commitBundle();
154
-
155
- final info = await plugin.getUpdateInfo(
156
- AppVersionGetBundlesArgs(
157
- platform: Platform.android,
158
- bundleId: nilUuid,
159
- appVersion: '9.9.9',
160
- channel: 'production',
161
- minBundleId: nilUuid,
162
- ),
163
- );
164
-
165
- expect(info, isNull);
166
- },
167
- );
168
-
169
- test('getUpdateInfo (fingerprint) returns matching bundle', () async {
170
- await plugin.appendBundle(_makeBundle(id: 'fp', fingerprintHash: 'fp1'));
171
- await plugin.commitBundle();
172
-
173
- final info = await plugin.getUpdateInfo(
174
- FingerprintGetBundlesArgs(
175
- platform: Platform.android,
176
- bundleId: nilUuid,
177
- fingerprintHash: 'fp1',
178
- ),
179
- );
180
-
181
- expect(info, isNotNull);
182
- expect(info!.id, 'fp');
183
- });
184
-
185
- test('getUpdateInfo (fingerprint) returns null on mismatch', () async {
186
- await plugin.appendBundle(_makeBundle(id: 'fp', fingerprintHash: 'fp1'));
187
- await plugin.commitBundle();
188
-
189
- final info = await plugin.getUpdateInfo(
190
- FingerprintGetBundlesArgs(
191
- platform: Platform.android,
192
- bundleId: nilUuid,
193
- fingerprintHash: 'nope',
194
- ),
195
- );
196
-
197
- expect(info, isNull);
198
- });
199
- });
200
- }
@@ -1,261 +0,0 @@
1
- import 'dart:convert' show jsonDecode;
2
-
3
- import 'package:flutter_ota_kit_cloudflare/flutter_ota_kit_cloudflare.dart'
4
- show
5
- CloudflareWorkerDatabaseConfig,
6
- D1ClientLike,
7
- D1DatabaseConfig,
8
- cloudflareWorkerDatabase,
9
- d1Database;
10
- import 'package:flutter_ota_kit_plugin_core/flutter_ota_kit_plugin_core.dart'
11
- show DatabasePlugin;
12
-
13
- /// In-memory store backing [MockD1Client], mirroring the D1 tables.
14
- class Store {
15
- final List<Map<String, dynamic>> bundleRows = [];
16
- final List<Map<String, dynamic>> patchRows = [];
17
- }
18
-
19
- /// Mock D1 client that emulates the SQL issued by `_D1DatabasePlugin`.
20
- class MockD1Client implements D1ClientLike {
21
- MockD1Client(this.store);
22
-
23
- final Store store;
24
-
25
- bool _asBool(dynamic v) => v is bool ? v : (v as num? ?? 0) != 0;
26
-
27
- List<String> _asList(dynamic v) {
28
- final decoded = jsonDecode(v as String) as List;
29
- return decoded.cast<String>();
30
- }
31
-
32
- bool _match(Map<String, dynamic> row, String where, List<dynamic> params) {
33
- var p = 0;
34
- if (where.contains('channel = ?')) {
35
- if (row['channel'] != params[p++]) return false;
36
- }
37
- if (where.contains('platform = ?')) {
38
- if (row['platform'] != params[p++]) return false;
39
- }
40
- if (where.contains('enabled = ?')) {
41
- if ((_asBool(row['enabled']) ? 1 : 0) != params[p++]) return false;
42
- }
43
- if (where.contains('id IN (SELECT value FROM json_each(?))')) {
44
- if (!_asList(params[p++]).contains(row['id'])) return false;
45
- }
46
- if (where.contains('id = ?')) {
47
- if (row['id'] != params[p++]) return false;
48
- }
49
- if (where.contains('id > ?')) {
50
- if ((row['id'] as String).compareTo(params[p++] as String) <= 0) {
51
- return false;
52
- }
53
- }
54
- if (where.contains('id >= ?')) {
55
- if ((row['id'] as String).compareTo(params[p++] as String) < 0) {
56
- return false;
57
- }
58
- }
59
- if (where.contains('id < ?')) {
60
- if ((row['id'] as String).compareTo(params[p++] as String) >= 0) {
61
- return false;
62
- }
63
- }
64
- if (where.contains('id <= ?')) {
65
- if ((row['id'] as String).compareTo(params[p++] as String) > 0) {
66
- return false;
67
- }
68
- }
69
- if (where.contains('target_app_version IS NOT NULL') &&
70
- !where.contains('target_app_version =')) {
71
- if (row['target_app_version'] == null) return false;
72
- }
73
- if (where.contains('target_app_version IS NULL')) {
74
- if (row['target_app_version'] != null) return false;
75
- }
76
- if (where.contains('target_app_version = ?')) {
77
- if (row['target_app_version'] != params[p++]) return false;
78
- }
79
- if (where.contains(
80
- 'target_app_version IN (SELECT value FROM json_each(?))',
81
- )) {
82
- if (!_asList(params[p++]).contains(row['target_app_version'])) {
83
- return false;
84
- }
85
- }
86
- if (where.contains('fingerprint_hash IS NULL')) {
87
- if (row['fingerprint_hash'] != null) return false;
88
- }
89
- if (where.contains('fingerprint_hash = ?')) {
90
- if (row['fingerprint_hash'] != params[p++]) return false;
91
- }
92
- return true;
93
- }
94
-
95
- List<Map<String, dynamic>> _selectBundles(String sql, List<dynamic> params) {
96
- final fromIdx = sql.indexOf('FROM bundles') + 'FROM bundles'.length;
97
- var endIdx = sql.length;
98
- final orderIdx = sql.indexOf('ORDER BY id');
99
- if (orderIdx != -1) endIdx = orderIdx;
100
- final whereClause = sql.substring(fromIdx, endIdx);
101
- final whereParamCount = '?'.allMatches(whereClause).length;
102
- final whereParams = params.sublist(0, whereParamCount);
103
-
104
- final filtered = store.bundleRows
105
- .where((row) => _match(row, whereClause, whereParams))
106
- .toList();
107
-
108
- final descending = !sql.contains('ORDER BY id ASC');
109
- filtered.sort(
110
- (a, b) => descending
111
- ? (b['id'] as String).compareTo(a['id'] as String)
112
- : (a['id'] as String).compareTo(b['id'] as String),
113
- );
114
-
115
- if (sql.contains('LIMIT ?')) {
116
- final limit = params[whereParamCount] as int;
117
- final offset = params[whereParamCount + 1] as int;
118
- final start = offset.clamp(0, filtered.length);
119
- final end = (offset + limit).clamp(0, filtered.length);
120
- return filtered.sublist(start, end);
121
- }
122
- return filtered;
123
- }
124
-
125
- @override
126
- Future<List<Map<String, dynamic>>> query(
127
- String sql, [
128
- List<dynamic> params = const [],
129
- ]) async {
130
- if (sql.contains('SELECT COUNT(*)')) {
131
- final fromIdx = sql.indexOf('FROM bundles') + 'FROM bundles'.length;
132
- final whereClause = sql.substring(fromIdx);
133
- final total = store.bundleRows
134
- .where((row) => _match(row, whereClause, params))
135
- .length;
136
- return [
137
- {'total': total},
138
- ];
139
- }
140
-
141
- if (sql.contains('SELECT channel FROM bundles')) {
142
- final channels = {
143
- for (final row in store.bundleRows) row['channel'] as String,
144
- };
145
- return [
146
- for (final c in channels) {'channel': c},
147
- ];
148
- }
149
-
150
- if (sql.contains('SELECT target_app_version FROM bundles')) {
151
- final channel = params[0] as String;
152
- final platform = params[1] as String;
153
- final minId = params[2] as String;
154
- return [
155
- for (final row in store.bundleRows)
156
- if (row['channel'] == channel &&
157
- row['platform'] == platform &&
158
- _asBool(row['enabled']) &&
159
- (row['id'] as String).compareTo(minId) >= 0 &&
160
- row['target_app_version'] != null)
161
- {'target_app_version': row['target_app_version'] as String},
162
- ];
163
- }
164
-
165
- if (sql.contains('SELECT * FROM bundle_patches')) {
166
- final ids = _asList(params[0]);
167
- final rows = store.patchRows
168
- .where((row) => ids.contains(row['bundle_id']))
169
- .toList();
170
- rows.sort(
171
- (a, b) =>
172
- (a['order_index'] as num).compareTo(b['order_index'] as num) +
173
- (a['base_bundle_id'] as String).compareTo(
174
- b['base_bundle_id'] as String,
175
- ),
176
- );
177
- return rows;
178
- }
179
-
180
- if (sql.contains('SELECT * FROM bundles')) {
181
- return _selectBundles(sql, params);
182
- }
183
-
184
- if (sql.contains('INSERT OR REPLACE INTO bundles')) {
185
- final row = <String, dynamic>{
186
- 'id': params[0],
187
- 'channel': params[1],
188
- 'enabled': params[2],
189
- 'should_force_update': params[3],
190
- 'file_hash': params[4],
191
- 'git_commit_hash': params[5],
192
- 'message': params[6],
193
- 'platform': params[7],
194
- 'target_app_version': params[8],
195
- 'storage_uri': params[9],
196
- 'fingerprint_hash': params[10],
197
- 'metadata': params[11],
198
- 'manifest_storage_uri': params[12],
199
- 'manifest_file_hash': params[13],
200
- 'asset_base_storage_uri': params[14],
201
- 'rollout_cohort_count': params[15],
202
- 'target_cohorts': params[16],
203
- };
204
- store.bundleRows.removeWhere((r) => r['id'] == row['id']);
205
- store.bundleRows.add(row);
206
- return const [];
207
- }
208
-
209
- if (sql.contains('INSERT OR REPLACE INTO bundle_patches')) {
210
- final row = <String, dynamic>{
211
- 'id': params[0],
212
- 'bundle_id': params[1],
213
- 'base_bundle_id': params[2],
214
- 'base_file_hash': params[3],
215
- 'patch_file_hash': params[4],
216
- 'patch_storage_uri': params[5],
217
- 'order_index': params[6],
218
- };
219
- store.patchRows.removeWhere((r) => r['id'] == row['id']);
220
- store.patchRows.add(row);
221
- return const [];
222
- }
223
-
224
- if (sql.contains('DELETE FROM bundles')) {
225
- final id = params[0];
226
- store.bundleRows.removeWhere((r) => r['id'] == id);
227
- store.patchRows.removeWhere(
228
- (r) => r['bundle_id'] == id || r['base_bundle_id'] == id,
229
- );
230
- return const [];
231
- }
232
-
233
- if (sql.contains('DELETE FROM bundle_patches')) {
234
- final id = params[0];
235
- if (sql.contains('base_bundle_id')) {
236
- store.patchRows.removeWhere((r) => r['base_bundle_id'] == id);
237
- } else {
238
- store.patchRows.removeWhere((r) => r['bundle_id'] == id);
239
- }
240
- return const [];
241
- }
242
-
243
- return const [];
244
- }
245
- }
246
-
247
- /// Build a [D1DatabaseConfig] wired to an in-memory [Store].
248
- D1DatabaseConfig mockConfig(Store store) => D1DatabaseConfig(
249
- databaseId: 'test-db',
250
- accountId: 'test-account',
251
- cloudflareApiToken: 'test-token',
252
- clientFactory: (_) => MockD1Client(store),
253
- );
254
-
255
- /// Construct the plugin with an in-memory store.
256
- DatabasePlugin newPlugin(Store store) => d1Database(mockConfig(store))();
257
-
258
- /// Construct the Workers D1 variant with an in-memory store.
259
- DatabasePlugin newWorkerPlugin(Store store) => cloudflareWorkerDatabase(
260
- CloudflareWorkerDatabaseConfig(getDb: () => MockD1Client(store)),
261
- )();
@@ -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_cloudflare/flutter_ota_kit_cloudflare.dart'
7
- show R2S3StorageConfig, R2S3ClientLike;
8
-
9
- /// In-memory store backing [MockR2Client].
10
- class Store {
11
- final Map<String, List<int>> objects = {};
12
- }
13
-
14
- /// Mock R2 S3 client that stores objects in memory.
15
- class MockR2Client implements R2S3ClientLike {
16
- MockR2Client(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> getSignedUrl(String key, {int expiresIn = 3600}) async =>
47
- 'https://$bucketName.r2.cloudflarestorage.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: 'r2://$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 [R2S3StorageConfig] wired to an in-memory [Store].
72
- R2S3StorageConfig mockR2Config(Store store) => R2S3StorageConfig(
73
- accountId: 'test-account',
74
- bucketName: 'test-bucket',
75
- accessKeyId: 'test-access-key',
76
- secretAccessKey: 'test-secret',
77
- clientFactory: (_) => MockR2Client(store),
78
- );