@_nazmiforreal/flutter-ota 0.1.5 → 0.1.7

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 (147) hide show
  1. package/README.md +13 -13
  2. package/bin/{flutter-patcher-linux-x64 → flutter-ota-linux-x64} +0 -0
  3. package/bin/{flutter-patcher.js → flutter-ota.js} +4 -4
  4. package/dart-src/packages/cli-tools/bin/{flutter_patcher.dart → flutter_ota_kit.dart} +2 -2
  5. package/dart-src/packages/cli-tools/lib/{flutter_patcher_cli.dart → flutter_ota_kit_cli.dart} +5 -3
  6. package/dart-src/packages/cli-tools/lib/src/backend.dart +6 -25
  7. package/dart-src/packages/cli-tools/lib/src/cli_base.dart +10 -4
  8. package/dart-src/packages/cli-tools/lib/src/commands/build.dart +5 -3
  9. package/dart-src/packages/cli-tools/lib/src/commands/bundle.dart +279 -10
  10. package/dart-src/packages/cli-tools/lib/src/commands/channel.dart +7 -7
  11. package/dart-src/packages/cli-tools/lib/src/commands/config_command.dart +5 -5
  12. package/dart-src/packages/cli-tools/lib/src/commands/console.dart +4 -4
  13. package/dart-src/packages/cli-tools/lib/src/commands/deploy.dart +4 -4
  14. package/dart-src/packages/cli-tools/lib/src/commands/doctor.dart +3 -3
  15. package/dart-src/packages/cli-tools/lib/src/commands/fingerprint.dart +1 -1
  16. package/dart-src/packages/cli-tools/lib/src/commands/init.dart +294 -45
  17. package/dart-src/packages/cli-tools/lib/src/commands/keys.dart +1 -1
  18. package/dart-src/packages/cli-tools/lib/src/commands/migrate.dart +218 -69
  19. package/dart-src/packages/cli-tools/lib/src/commands/rollback.dart +5 -5
  20. package/dart-src/packages/cli-tools/lib/src/commands/storage.dart +117 -0
  21. package/dart-src/packages/cli-tools/lib/src/config.dart +29 -78
  22. package/dart-src/packages/cli-tools/lib/src/operations.dart +4 -4
  23. package/dart-src/packages/cli-tools/lib/src/pack.dart +12 -6
  24. package/dart-src/packages/cli-tools/lib/src/runner.dart +25 -6
  25. package/dart-src/packages/cli-tools/lib/src/ui/ui.dart +5 -3
  26. package/dart-src/packages/cli-tools/lib/src/verbose.dart +3 -0
  27. package/dart-src/packages/cli-tools/migrations/aws/README.md +7 -0
  28. package/dart-src/packages/cli-tools/migrations/postgres/bundles.sql +45 -0
  29. package/dart-src/packages/cli-tools/migrations/postgres/get_target_app_version_list.sql +21 -0
  30. package/dart-src/packages/cli-tools/migrations/postgres/get_update_info_by_app_version.sql +126 -0
  31. package/dart-src/packages/cli-tools/migrations/postgres/get_update_info_by_fingerprint_hash.sql +125 -0
  32. package/dart-src/packages/cli-tools/migrations/postgres/hash_user_id.sql +30 -0
  33. package/dart-src/packages/cli-tools/migrations/postgres/is_device_eligible.sql +237 -0
  34. package/dart-src/packages/cli-tools/migrations/supabase/20260520014100_hot-updater_rls.sql +11 -0
  35. package/dart-src/packages/cli-tools/pubspec.yaml +9 -11
  36. package/dart-src/packages/cli-tools/test/backends_test.dart +4 -4
  37. package/dart-src/packages/cli-tools/test/build_pack_test.dart +1 -1
  38. package/dart-src/packages/cli-tools/test/cli_test.dart +3 -3
  39. package/dart-src/packages/cli-tools/test/mocks/mock_aws_s3_client.dart +2 -2
  40. package/dart-src/packages/cli-tools/test/mocks/mock_d1_client.dart +2 -2
  41. package/dart-src/packages/cli-tools/test/mocks/mock_postgres_client.dart +7 -7
  42. package/dart-src/packages/core/lib/{flutter_patcher_core.dart → flutter_ota_kit_core.dart} +1 -1
  43. package/dart-src/packages/core/pubspec.yaml +2 -2
  44. package/dart-src/packages/core/test/rollout_test.dart +1 -1
  45. package/dart-src/packages/core/test/semver_test.dart +1 -1
  46. package/dart-src/packages/core/test/types_test.dart +2 -2
  47. package/dart-src/packages/core/test/uuid_test.dart +1 -1
  48. package/dart-src/packages/core/tool/dbg.dart +1 -1
  49. package/dart-src/plugins/aws/lib/{flutter_patcher_aws.dart → flutter_ota_kit_aws.dart} +0 -2
  50. package/dart-src/plugins/aws/lib/src/aws_cloudfront_client.dart +1 -1
  51. package/dart-src/plugins/aws/lib/src/aws_database.dart +1 -1
  52. package/dart-src/plugins/aws/lib/src/aws_s3_client.dart +1 -1
  53. package/dart-src/plugins/aws/lib/src/aws_storage.dart +1 -1
  54. package/dart-src/plugins/aws/lib/src/aws_storage_profile.dart +25 -3
  55. package/dart-src/plugins/aws/lib/src/with_cloudfront_signed_url.dart +1 -1
  56. package/dart-src/plugins/aws/pubspec.yaml +4 -4
  57. package/dart-src/plugins/aws/test/aws_database_test.dart +3 -3
  58. package/dart-src/plugins/aws/test/aws_storage_test.dart +2 -2
  59. package/dart-src/plugins/aws/test/mock_aws_s3_client.dart +2 -2
  60. package/dart-src/plugins/cloudflare/lib/src/cloudflare_worker_database.dart +1 -1
  61. package/dart-src/plugins/cloudflare/lib/src/d1_build_where.dart +1 -1
  62. package/dart-src/plugins/cloudflare/lib/src/d1_bundle_mapper.dart +1 -1
  63. package/dart-src/plugins/cloudflare/lib/src/d1_database.dart +1 -1
  64. package/dart-src/plugins/cloudflare/lib/src/d1_database_plugin.dart +2 -2
  65. package/dart-src/plugins/cloudflare/lib/src/r2_s3_client.dart +1 -1
  66. package/dart-src/plugins/cloudflare/lib/src/r2_storage.dart +1 -1
  67. package/dart-src/plugins/cloudflare/lib/src/r2_storage_profile.dart +1 -1
  68. package/dart-src/plugins/cloudflare/pubspec.yaml +4 -4
  69. package/dart-src/plugins/cloudflare/test/cloudflare_worker_database_test.dart +2 -2
  70. package/dart-src/plugins/cloudflare/test/d1_bundle_mapper_test.dart +2 -2
  71. package/dart-src/plugins/cloudflare/test/d1_database_test.dart +2 -2
  72. package/dart-src/plugins/cloudflare/test/mock_d1_client.dart +2 -2
  73. package/dart-src/plugins/cloudflare/test/mock_r2_client.dart +2 -2
  74. package/dart-src/plugins/cloudflare/test/r2_storage_test.dart +2 -2
  75. package/dart-src/plugins/plugin-core/lib/{flutter_patcher_plugin_core.dart → flutter_ota_kit_plugin_core.dart} +1 -1
  76. package/dart-src/plugins/plugin-core/lib/src/create_blob_database_plugin.dart +1 -1
  77. package/dart-src/plugins/plugin-core/lib/src/filter_compatible_app_versions.dart +1 -1
  78. package/dart-src/plugins/plugin-core/lib/src/get_update_info.dart +1 -1
  79. package/dart-src/plugins/plugin-core/lib/src/request_update_bundle_state.dart +1 -1
  80. package/dart-src/plugins/plugin-core/lib/src/resolve_update_info_from_bundles.dart +1 -1
  81. package/dart-src/plugins/plugin-core/lib/src/types.dart +2 -2
  82. package/dart-src/plugins/plugin-core/pubspec.yaml +3 -3
  83. package/dart-src/plugins/plugin-core/test/asset_storage_layout_test.dart +3 -3
  84. package/dart-src/plugins/plugin-core/test/bundle_unit_of_work_store_test.dart +2 -2
  85. package/dart-src/plugins/plugin-core/test/bundle_unit_of_work_test.dart +2 -2
  86. package/dart-src/plugins/plugin-core/test/create_blob_database_plugin_test.dart +2 -2
  87. package/dart-src/plugins/plugin-core/test/create_database_plugin_test.dart +5 -5
  88. package/dart-src/plugins/plugin-core/test/create_storage_plugin_test.dart +2 -2
  89. package/dart-src/plugins/plugin-core/test/generate_min_bundle_id_test.dart +2 -2
  90. package/dart-src/plugins/plugin-core/test/get_update_info_test.dart +2 -2
  91. package/dart-src/plugins/plugin-core/test/helpers_test.dart +2 -2
  92. package/dart-src/plugins/plugin-core/test/query_bundles_test.dart +2 -2
  93. package/dart-src/plugins/plugin-core/test/request_update_bundle_state_test.dart +3 -3
  94. package/dart-src/plugins/plugin-core/test/uuidv7_test.dart +1 -1
  95. package/dart-src/plugins/postgres/lib/{flutter_patcher_postgres.dart → flutter_ota_kit_postgres.dart} +1 -1
  96. package/dart-src/plugins/postgres/lib/src/postgres_bundle_mapper.dart +1 -1
  97. package/dart-src/plugins/postgres/lib/src/postgres_database.dart +2 -2
  98. package/dart-src/plugins/postgres/lib/src/postgres_get_update_info.dart +2 -2
  99. package/dart-src/plugins/postgres/lib/src/postgres_storage.dart +9 -9
  100. package/dart-src/plugins/postgres/lib/src/postgres_types.dart +1 -1
  101. package/dart-src/plugins/postgres/pubspec.yaml +4 -4
  102. package/dart-src/plugins/postgres/test/mock_postgres_client.dart +2 -2
  103. package/dart-src/plugins/postgres/test/postgres_bundle_mapper_test.dart +2 -2
  104. package/dart-src/plugins/postgres/test/postgres_database_test.dart +2 -2
  105. package/dart-src/plugins/supabase/lib/edge.dart +1 -1
  106. package/dart-src/plugins/supabase/lib/{flutter_patcher_supabase.dart → flutter_ota_kit_supabase.dart} +1 -1
  107. package/dart-src/plugins/supabase/lib/src/supabase_bundle_mapper.dart +1 -1
  108. package/dart-src/plugins/supabase/lib/src/supabase_client_http.dart +60 -20
  109. package/dart-src/plugins/supabase/lib/src/supabase_database.dart +2 -2
  110. package/dart-src/plugins/supabase/lib/src/supabase_edge_function_database.dart +1 -1
  111. package/dart-src/plugins/supabase/lib/src/supabase_edge_function_storage.dart +1 -1
  112. package/dart-src/plugins/supabase/lib/src/supabase_storage.dart +2 -5
  113. package/dart-src/plugins/supabase/pubspec.yaml +4 -4
  114. package/dart-src/plugins/supabase/test/mock_supabase_client.dart +5 -5
  115. package/dart-src/plugins/supabase/test/supabase_bundle_mapper_test.dart +3 -3
  116. package/dart-src/plugins/supabase/test/supabase_database_test.dart +3 -3
  117. package/dart-src/plugins/supabase/test/supabase_storage_test.dart +2 -2
  118. package/migrations/aws/README.md +7 -0
  119. package/migrations/cloudflare/0001_hot-updater_init.sql +16 -0
  120. package/migrations/cloudflare/0002_hot-updater_0.13.0.sql +8 -0
  121. package/migrations/cloudflare/0003_hot-updater_0.18.0.sql +38 -0
  122. package/migrations/cloudflare/0004_hot-updater_0.29.0.sql +11 -0
  123. package/migrations/cloudflare/0005_hot-updater_0.31.0.sql +24 -0
  124. package/migrations/cloudflare/bundles.sql +42 -0
  125. package/migrations/postgres/bundles.sql +45 -0
  126. package/migrations/postgres/get_target_app_version_list.sql +21 -0
  127. package/migrations/postgres/get_update_info_by_app_version.sql +126 -0
  128. package/migrations/postgres/get_update_info_by_fingerprint_hash.sql +125 -0
  129. package/migrations/postgres/hash_user_id.sql +30 -0
  130. package/migrations/postgres/is_device_eligible.sql +237 -0
  131. package/package.json +4 -4
  132. package/scripts/postinstall.js +15 -15
  133. package/scripts/vendor.sh +1 -1
  134. package/dart-src/packages/cli-tools/.dart_tool/package_config.json +0 -496
  135. package/dart-src/packages/cli-tools/.dart_tool/package_graph.json +0 -743
  136. package/dart-src/packages/cli-tools/pubspec.lock +0 -638
  137. package/dart-src/packages/cli-tools/test/standalone_backend_test.dart +0 -315
  138. package/dart-src/plugins/aws/lib/src/aws_lambda_edge_storage.dart +0 -72
  139. package/dart-src/plugins/aws/test/aws_lambda_edge_storage_test.dart +0 -190
  140. package/dart-src/plugins/standalone/.gitkeep +0 -0
  141. package/dart-src/plugins/standalone/lib/flutter_patcher_standalone.dart +0 -12
  142. package/dart-src/plugins/standalone/lib/src/standalone_config.dart +0 -107
  143. package/dart-src/plugins/standalone/lib/src/standalone_database.dart +0 -233
  144. package/dart-src/plugins/standalone/lib/src/standalone_storage.dart +0 -175
  145. package/dart-src/plugins/standalone/pubspec.yaml +0 -18
  146. package/dart-src/plugins/standalone/test/standalone_test.dart +0 -264
  147. /package/dart-src/plugins/cloudflare/lib/{flutter_patcher_cloudflare.dart → flutter_ota_kit_cloudflare.dart} +0 -0
@@ -1,4 +1,4 @@
1
- import 'package:flutter_patcher_core/flutter_patcher_core.dart'
1
+ import 'package:flutter_ota_kit_core/flutter_ota_kit_core.dart'
2
2
  show Platform;
3
3
 
4
4
  /// Database row for the `bundles` table (snake_case columns).
@@ -1,5 +1,5 @@
1
- name: flutter_patcher_postgres
2
- description: Postgres plugin for flutter_patcher — database backend.
1
+ name: flutter_ota_kit_postgres
2
+ description: Postgres plugin for flutter_ota_kit — database backend.
3
3
  version: 0.1.0
4
4
  publish_to: none
5
5
 
@@ -7,9 +7,9 @@ environment:
7
7
  sdk: ">=3.3.0 <4.0.0"
8
8
 
9
9
  dependencies:
10
- flutter_patcher_core:
10
+ flutter_ota_kit_core:
11
11
  path: ../../packages/core
12
- flutter_patcher_plugin_core:
12
+ flutter_ota_kit_plugin_core:
13
13
  path: ../../plugins/plugin-core
14
14
  postgres: ^3.4.0
15
15
 
@@ -1,6 +1,6 @@
1
- import 'package:flutter_patcher_plugin_core/flutter_patcher_plugin_core.dart';
1
+ import 'package:flutter_ota_kit_plugin_core/flutter_ota_kit_plugin_core.dart';
2
2
 
3
- import 'package:flutter_patcher_postgres/flutter_patcher_postgres.dart';
3
+ import 'package:flutter_ota_kit_postgres/flutter_ota_kit_postgres.dart';
4
4
 
5
5
  /// In-memory store backing [MockPostgresClient]. Mirrors the `bundles` and
6
6
  /// `bundle_patches` tables (snake_case row maps).
@@ -1,6 +1,6 @@
1
- import 'package:flutter_patcher_core/flutter_patcher_core.dart'
1
+ import 'package:flutter_ota_kit_core/flutter_ota_kit_core.dart'
2
2
  show Bundle, BundleMetadata, BundlePatchArtifact, Platform;
3
- import 'package:flutter_patcher_postgres/flutter_patcher_postgres.dart';
3
+ import 'package:flutter_ota_kit_postgres/flutter_ota_kit_postgres.dart';
4
4
  import 'package:test/test.dart';
5
5
 
6
6
  void main() {
@@ -1,4 +1,4 @@
1
- import 'package:flutter_patcher_core/flutter_patcher_core.dart'
1
+ import 'package:flutter_ota_kit_core/flutter_ota_kit_core.dart'
2
2
  show
3
3
  AppVersionGetBundlesArgs,
4
4
  Bundle,
@@ -7,7 +7,7 @@ import 'package:flutter_patcher_core/flutter_patcher_core.dart'
7
7
  UpdateInfo,
8
8
  UpdateStatus,
9
9
  nilUuid;
10
- import 'package:flutter_patcher_plugin_core/flutter_patcher_plugin_core.dart'
10
+ import 'package:flutter_ota_kit_plugin_core/flutter_ota_kit_plugin_core.dart'
11
11
  show
12
12
  DatabaseBundleQueryOptions,
13
13
  DatabaseBundleQueryWhere,
@@ -1,4 +1,4 @@
1
- /// Edge-function entrypoint for flutter_patcher_supabase.
1
+ /// Edge-function entrypoint for flutter_ota_kit_supabase.
2
2
  ///
3
3
  /// Mirrors hot-updater's `plugins/supabase/src/edge.ts`: exposes only the
4
4
  /// edge-runnable variants (runtime-only database + storage plugins).
@@ -1,4 +1,4 @@
1
- /// flutter_patcher_supabase — Supabase backend for flutter_patcher.
1
+ /// flutter_ota_kit_supabase — Supabase backend for flutter_ota_kit.
2
2
  ///
3
3
  /// Faithful Dart translation of hot-updater's `plugins/supabase`:
4
4
  /// database + storage plugins (direct + edge-function variants) over the
@@ -3,7 +3,7 @@ library;
3
3
 
4
4
  import 'dart:convert';
5
5
 
6
- import 'package:flutter_patcher_core/flutter_patcher_core.dart';
6
+ import 'package:flutter_ota_kit_core/flutter_ota_kit_core.dart';
7
7
 
8
8
  import 'types.dart';
9
9
 
@@ -245,17 +245,23 @@ class _StorageBucket implements SupabaseStorageBucketLike {
245
245
  String path,
246
246
  int expiresIn,
247
247
  ) async {
248
- final uri = Uri.parse(
249
- '$_baseUrl/storage/v1/object/sign/$_bucket/$path',
250
- ).replace(queryParameters: {'expiresIn': expiresIn.toString()});
251
- final res = await http.post(uri, headers: _headers);
248
+ final uri = Uri.parse('$_baseUrl/storage/v1/object/sign/$_bucket/$path');
249
+ final res = await http.post(
250
+ uri,
251
+ headers: {..._headers, 'Content-Type': 'application/json'},
252
+ body: jsonEncode({'expiresIn': expiresIn}),
253
+ );
252
254
  if (res.statusCode >= 400) {
253
255
  return _MockSignedUrlResult(null, jsonDecode(res.body));
254
256
  }
255
257
  final body = jsonDecode(res.body) as Map<String, dynamic>;
258
+ final signed = body['signedURL'] as String?;
259
+ // Supabase returns a relative path ("/object/sign/...?token=..."); make it
260
+ // absolute against the project base URL.
256
261
  return _MockSignedUrlResult(
257
- '$_baseUrl/storage/v1/object/sign/$_bucket/$path?...${body['signedURL']}',
258
- null);
262
+ signed == null ? null : '$_baseUrl/storage/v1$signed',
263
+ null,
264
+ );
259
265
  }
260
266
 
261
267
  @override
@@ -279,7 +285,11 @@ class _StorageBucket implements SupabaseStorageBucketLike {
279
285
  return _MockSignedUrlListResult(
280
286
  body
281
287
  .map((e) => _MockSignedUrlResult(
282
- e['signedURL'] as String?,
288
+ // Supabase returns a relative path; make it absolute against
289
+ // the project base URL, matching [createSignedUrl].
290
+ e['signedURL'] == null
291
+ ? null
292
+ : '$_baseUrl/storage/v1${e['signedURL'] as String}',
283
293
  e['error'] as String?,
284
294
  ))
285
295
  .toList(),
@@ -287,6 +297,22 @@ class _StorageBucket implements SupabaseStorageBucketLike {
287
297
  );
288
298
  }
289
299
 
300
+ Future<void> _ensureBucket() async {
301
+ final res = await http.post(
302
+ Uri.parse('$_baseUrl/storage/v1/bucket'),
303
+ headers: {..._headers, 'Content-Type': 'application/json'},
304
+ body: jsonEncode({'name': _bucket, 'public': true}),
305
+ );
306
+ // 400/409 just mean it already exists — that's fine.
307
+ if (res.statusCode >= 400) {
308
+ final body = jsonDecode(res.body) as Map<String, dynamic>;
309
+ final msg = (body['message'] ?? body['error'] ?? '').toString();
310
+ if (!msg.contains('already exists') && res.statusCode != 409) {
311
+ throw StateError('Failed to create bucket "$_bucket": $msg');
312
+ }
313
+ }
314
+ }
315
+
290
316
  @override
291
317
  Future<SupabaseUploadResult> upload(
292
318
  String path,
@@ -294,20 +320,34 @@ class _StorageBucket implements SupabaseStorageBucketLike {
294
320
  String? contentType,
295
321
  String? cacheControl,
296
322
  }) async {
297
- final uri = Uri.parse('$_baseUrl/storage/v1/object/$_bucket/$path');
298
- final res = await http.post(
299
- uri,
300
- headers: {
301
- ..._headers,
302
- 'Content-Type': contentType ?? 'application/octet-stream',
303
- if (cacheControl != null) 'Cache-Control': cacheControl,
304
- },
305
- body: fileBytes,
306
- );
307
- if (res.statusCode >= 400) {
308
- return _MockUploadResult(null, jsonDecode(res.body));
323
+ Future<_MockUploadResult> doUpload() async {
324
+ final uri = Uri.parse('$_baseUrl/storage/v1/object/$_bucket/$path');
325
+ final res = await http.post(
326
+ uri,
327
+ headers: {
328
+ ..._headers,
329
+ 'Content-Type': contentType ?? 'application/octet-stream',
330
+ if (cacheControl != null) 'Cache-Control': cacheControl,
331
+ },
332
+ body: fileBytes,
333
+ );
334
+ if (res.statusCode >= 400) {
335
+ return _MockUploadResult(null, jsonDecode(res.body));
336
+ }
337
+ return _MockUploadResult(jsonDecode(res.body), null);
338
+ }
339
+
340
+ final first = await doUpload();
341
+ if (first.error != null) {
342
+ final msg =
343
+ (first.error is Map ? (first.error as Map)['message'] : first.error)
344
+ .toString();
345
+ if (msg.contains('Bucket not found')) {
346
+ await _ensureBucket();
347
+ return doUpload();
348
+ }
309
349
  }
310
- return _MockUploadResult(jsonDecode(res.body), null);
350
+ return first;
311
351
  }
312
352
 
313
353
  @override
@@ -3,8 +3,8 @@ library;
3
3
 
4
4
  import 'dart:convert';
5
5
 
6
- import 'package:flutter_patcher_core/flutter_patcher_core.dart';
7
- import 'package:flutter_patcher_plugin_core/flutter_patcher_plugin_core.dart';
6
+ import 'package:flutter_ota_kit_core/flutter_ota_kit_core.dart';
7
+ import 'package:flutter_ota_kit_plugin_core/flutter_ota_kit_plugin_core.dart';
8
8
 
9
9
  import 'supabase_bundle_mapper.dart';
10
10
  import 'supabase_client_adapter.dart';
@@ -1,7 +1,7 @@
1
1
  /// Faithful port of hot-updater `plugins/supabase/src/supabaseEdgeFunctionDatabase.ts`.
2
2
  library;
3
3
 
4
- import 'package:flutter_patcher_plugin_core/flutter_patcher_plugin_core.dart';
4
+ import 'package:flutter_ota_kit_plugin_core/flutter_ota_kit_plugin_core.dart';
5
5
 
6
6
  import 'supabase_database.dart';
7
7
 
@@ -1,7 +1,7 @@
1
1
  /// Faithful port of hot-updater `plugins/supabase/src/supabaseEdgeFunctionStorage.ts`.
2
2
  library;
3
3
 
4
- import 'package:flutter_patcher_plugin_core/flutter_patcher_plugin_core.dart';
4
+ import 'package:flutter_ota_kit_plugin_core/flutter_ota_kit_plugin_core.dart';
5
5
 
6
6
  import 'supabase_client_adapter.dart';
7
7
  import 'supabase_client_http.dart';
@@ -3,7 +3,7 @@ library;
3
3
 
4
4
  import 'dart:io' as io;
5
5
 
6
- import 'package:flutter_patcher_plugin_core/flutter_patcher_plugin_core.dart';
6
+ import 'package:flutter_ota_kit_plugin_core/flutter_ota_kit_plugin_core.dart';
7
7
 
8
8
  import 'supabase_client_adapter.dart';
9
9
  import 'supabase_client_http.dart';
@@ -151,11 +151,8 @@ class NodeStorageProfileImpl implements NodeStorageProfile {
151
151
  }
152
152
 
153
153
  await verifySigned(bucket: bucket, key: storageKey);
154
- final fullPath = upload.data is Map
155
- ? (upload.data as Map)['fullPath'] as String?
156
- : null;
157
154
  return {
158
- 'storageUri': 'supabase-storage://${fullPath ?? storageKey}',
155
+ 'storageUri': 'supabase-storage://$bucketName/$storageKey',
159
156
  };
160
157
  }
161
158
 
@@ -1,5 +1,5 @@
1
- name: flutter_patcher_supabase
2
- description: Supabase plugin for flutter_patcher — database + storage backends.
1
+ name: flutter_ota_kit_supabase
2
+ description: Supabase plugin for flutter_ota_kit — database + storage backends.
3
3
  version: 0.1.0
4
4
  publish_to: none
5
5
 
@@ -7,9 +7,9 @@ environment:
7
7
  sdk: ">=3.3.0 <4.0.0"
8
8
 
9
9
  dependencies:
10
- flutter_patcher_core:
10
+ flutter_ota_kit_core:
11
11
  path: ../../packages/core
12
- flutter_patcher_plugin_core:
12
+ flutter_ota_kit_plugin_core:
13
13
  path: ../../plugins/plugin-core
14
14
  http: ^1.2.0
15
15
  supabase: ^2.14.0
@@ -6,12 +6,12 @@
6
6
  /// plugin, plus a configurable storage bucket used by the storage plugin.
7
7
  library;
8
8
 
9
- import 'package:flutter_patcher_core/flutter_patcher_core.dart';
10
- import 'package:flutter_patcher_plugin_core/flutter_patcher_plugin_core.dart';
9
+ import 'package:flutter_ota_kit_core/flutter_ota_kit_core.dart';
10
+ import 'package:flutter_ota_kit_plugin_core/flutter_ota_kit_plugin_core.dart';
11
11
 
12
- import 'package:flutter_patcher_supabase/src/supabase_bundle_mapper.dart';
13
- import 'package:flutter_patcher_supabase/src/supabase_client_adapter.dart';
14
- import 'package:flutter_patcher_supabase/src/types.dart';
12
+ import 'package:flutter_ota_kit_supabase/src/supabase_bundle_mapper.dart';
13
+ import 'package:flutter_ota_kit_supabase/src/supabase_client_adapter.dart';
14
+ import 'package:flutter_ota_kit_supabase/src/types.dart';
15
15
 
16
16
  // ---------------------------------------------------------------------------
17
17
  // In-memory row store
@@ -1,6 +1,6 @@
1
- import 'package:flutter_patcher_core/flutter_patcher_core.dart';
2
- import 'package:flutter_patcher_supabase/src/supabase_bundle_mapper.dart';
3
- import 'package:flutter_patcher_supabase/src/types.dart';
1
+ import 'package:flutter_ota_kit_core/flutter_ota_kit_core.dart';
2
+ import 'package:flutter_ota_kit_supabase/src/supabase_bundle_mapper.dart';
3
+ import 'package:flutter_ota_kit_supabase/src/types.dart';
4
4
  import 'package:test/test.dart';
5
5
 
6
6
  Bundle _makeBundle({List<BundlePatchArtifact> patches = const []}) => Bundle(
@@ -1,6 +1,6 @@
1
- import 'package:flutter_patcher_core/flutter_patcher_core.dart';
2
- import 'package:flutter_patcher_plugin_core/flutter_patcher_plugin_core.dart';
3
- import 'package:flutter_patcher_supabase/flutter_patcher_supabase.dart';
1
+ import 'package:flutter_ota_kit_core/flutter_ota_kit_core.dart';
2
+ import 'package:flutter_ota_kit_plugin_core/flutter_ota_kit_plugin_core.dart';
3
+ import 'package:flutter_ota_kit_supabase/flutter_ota_kit_supabase.dart';
4
4
  import 'package:test/test.dart';
5
5
 
6
6
  import 'mock_supabase_client.dart';
@@ -1,7 +1,7 @@
1
1
  import 'dart:io' as io;
2
2
 
3
- import 'package:flutter_patcher_plugin_core/flutter_patcher_plugin_core.dart';
4
- import 'package:flutter_patcher_supabase/flutter_patcher_supabase.dart';
3
+ import 'package:flutter_ota_kit_plugin_core/flutter_ota_kit_plugin_core.dart';
4
+ import 'package:flutter_ota_kit_supabase/flutter_ota_kit_supabase.dart';
5
5
  import 'package:test/test.dart';
6
6
 
7
7
  import 'mock_supabase_client.dart';
@@ -0,0 +1,7 @@
1
+ # AWS migrations
2
+
3
+ The AWS backend stores bundle metadata as JSON in S3 (blob database), not in a
4
+ relational database. There are **no SQL migrations** to apply — the bucket and
5
+ object prefix are created on first `deploy`.
6
+
7
+ If you front downloads with CloudFront, provision the distribution separately.
@@ -0,0 +1,16 @@
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);
@@ -0,0 +1,8 @@
1
+ -- Migration number: 0002 2025-03-07T16:25:12.486Z
2
+ -- HotUpdater.bundles
3
+
4
+ ALTER TABLE bundles
5
+ ADD COLUMN channel TEXT NOT NULL DEFAULT 'production';
6
+
7
+ ALTER TABLE bundles
8
+ DROP COLUMN file_url;
@@ -0,0 +1,38 @@
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);
@@ -0,0 +1,11 @@
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;
@@ -0,0 +1,24 @@
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);
@@ -0,0 +1,42 @@
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);
@@ -0,0 +1,45 @@
1
+ -- HotUpdater.bundles
2
+
3
+ CREATE TYPE platforms AS ENUM ('ios', 'android');
4
+
5
+ CREATE TABLE bundles (
6
+ id uuid PRIMARY KEY,
7
+ platform platforms NOT NULL,
8
+ should_force_update boolean NOT NULL,
9
+ enabled boolean NOT NULL,
10
+ file_hash text NOT NULL,
11
+ git_commit_hash text,
12
+ message text,
13
+ channel text NOT NULL DEFAULT 'production',
14
+ storage_uri text NOT NULL,
15
+ target_app_version text,
16
+ fingerprint_hash text,
17
+ CONSTRAINT check_version_or_fingerprint CHECK (
18
+ (target_app_version IS NOT NULL) OR (fingerprint_hash IS NOT NULL)
19
+ ),
20
+ metadata jsonb DEFAULT '{}'::jsonb,
21
+ manifest_storage_uri text,
22
+ manifest_file_hash text,
23
+ asset_base_storage_uri text,
24
+ rollout_cohort_count INTEGER DEFAULT 1000
25
+ CHECK (rollout_cohort_count >= 0 AND rollout_cohort_count <= 1000),
26
+ target_cohorts TEXT[]
27
+ );
28
+
29
+ CREATE TABLE bundle_patches (
30
+ id text PRIMARY KEY,
31
+ bundle_id uuid NOT NULL REFERENCES bundles(id) ON DELETE CASCADE,
32
+ base_bundle_id uuid NOT NULL REFERENCES bundles(id) ON DELETE CASCADE,
33
+ base_file_hash text NOT NULL,
34
+ patch_file_hash text NOT NULL,
35
+ patch_storage_uri text NOT NULL,
36
+ order_index integer NOT NULL DEFAULT 0
37
+ );
38
+
39
+ CREATE INDEX bundles_target_app_version_idx ON bundles(target_app_version);
40
+ CREATE INDEX bundles_fingerprint_hash_idx ON bundles(fingerprint_hash);
41
+ CREATE INDEX bundles_channel_idx ON bundles(channel);
42
+ CREATE INDEX bundles_rollout_idx ON bundles(rollout_cohort_count);
43
+ CREATE INDEX bundles_target_cohorts_idx ON bundles USING GIN (target_cohorts);
44
+ CREATE INDEX bundle_patches_bundle_id_idx ON bundle_patches(bundle_id);
45
+ CREATE INDEX bundle_patches_base_bundle_id_idx ON bundle_patches(base_bundle_id);
@@ -0,0 +1,21 @@
1
+ -- HotUpdater.get_target_app_version_list
2
+
3
+ CREATE OR REPLACE FUNCTION get_target_app_version_list (
4
+ app_platform platforms,
5
+ min_bundle_id uuid
6
+ )
7
+ RETURNS TABLE (
8
+ target_app_version text
9
+ )
10
+ LANGUAGE plpgsql
11
+ AS
12
+ $$
13
+ BEGIN
14
+ RETURN QUERY
15
+ SELECT b.target_app_version
16
+ FROM bundles b
17
+ WHERE b.platform = app_platform
18
+ AND b.id >= min_bundle_id
19
+ GROUP BY b.target_app_version;
20
+ END;
21
+ $$;