@_nazmiforreal/flutter-ota 0.1.11 → 0.1.13

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 (176) hide show
  1. package/README.md +1 -1
  2. package/bin/flutter-ota-linux-x64 +0 -0
  3. package/dart-src/packages/cli-tools/.dart_tool/package_config.json +46 -76
  4. package/dart-src/packages/cli-tools/.dart_tool/package_graph.json +140 -166
  5. package/dart-src/packages/cli-tools/README.md +1 -1
  6. package/dart-src/packages/cli-tools/lib/flutter_ota_kit_cli.dart +30 -17
  7. package/dart-src/packages/cli-tools/lib/src/backend.dart +30 -31
  8. package/dart-src/packages/cli-tools/lib/src/cli_base.dart +3 -1
  9. package/dart-src/packages/cli-tools/lib/src/commands/build.dart +44 -43
  10. package/dart-src/packages/cli-tools/lib/src/commands/bundle.dart +265 -239
  11. package/dart-src/packages/cli-tools/lib/src/commands/channel.dart +75 -66
  12. package/dart-src/packages/cli-tools/lib/src/commands/config_command.dart +39 -35
  13. package/dart-src/packages/cli-tools/lib/src/commands/console.dart +30 -27
  14. package/dart-src/packages/cli-tools/lib/src/commands/deploy.dart +88 -72
  15. package/dart-src/packages/cli-tools/lib/src/commands/doctor.dart +66 -29
  16. package/dart-src/packages/cli-tools/lib/src/commands/fingerprint.dart +10 -6
  17. package/dart-src/packages/cli-tools/lib/src/commands/init.dart +299 -190
  18. package/dart-src/packages/cli-tools/lib/src/commands/keys.dart +24 -23
  19. package/dart-src/packages/cli-tools/lib/src/commands/migrate.dart +111 -97
  20. package/dart-src/packages/cli-tools/lib/src/commands/pocketbase.dart +237 -0
  21. package/dart-src/packages/cli-tools/lib/src/commands/rollback.dart +43 -34
  22. package/dart-src/packages/cli-tools/lib/src/commands/storage.dart +57 -53
  23. package/dart-src/packages/cli-tools/lib/src/config.dart +227 -93
  24. package/dart-src/packages/cli-tools/lib/src/operations.dart +9 -8
  25. package/dart-src/packages/cli-tools/lib/src/pack.dart +26 -25
  26. package/dart-src/packages/cli-tools/lib/src/pocketbase/data_bootstrap.dart +39 -0
  27. package/dart-src/packages/cli-tools/lib/src/pocketbase/hooks/bundles.pb.js +56 -0
  28. package/dart-src/packages/cli-tools/lib/src/pocketbase/installer.dart +189 -0
  29. package/dart-src/packages/cli-tools/lib/src/pocketbase/process_manager.dart +123 -0
  30. package/dart-src/packages/cli-tools/lib/src/pocketbase/schema_installer.dart +237 -0
  31. package/dart-src/packages/cli-tools/lib/src/runner.dart +36 -15
  32. package/dart-src/packages/cli-tools/lib/src/sign.dart +13 -5
  33. package/dart-src/packages/cli-tools/lib/src/ui/ui.dart +10 -13
  34. package/dart-src/packages/cli-tools/lib/src/util.dart +3 -1
  35. package/dart-src/packages/cli-tools/pubspec.lock +69 -116
  36. package/dart-src/packages/cli-tools/pubspec.yaml +25 -7
  37. package/dart-src/packages/cli-tools/test/backends_test.dart +62 -32
  38. package/dart-src/packages/cli-tools/test/build_pack_test.dart +4 -4
  39. package/dart-src/packages/cli-tools/test/cli_test.dart +89 -42
  40. package/dart-src/packages/cli-tools/test/mocks/mock_aws_s3_client.dart +8 -13
  41. package/dart-src/packages/cli-tools/test/mocks/mock_d1_client.dart +23 -18
  42. package/dart-src/packages/cli-tools/test/mocks/mock_pocketbase_client.dart +197 -0
  43. package/dart-src/packages/cli-tools/test/mocks/mock_postgres_client.dart +70 -46
  44. package/dart-src/packages/cli-tools/test/pocketbase_installer_test.dart +72 -0
  45. package/dart-src/packages/cli-tools/test/pocketbase_schema_test.dart +107 -0
  46. package/dart-src/packages/cli-tools/test/pocketbase_smoke_test.dart +59 -0
  47. package/dart-src/packages/core/README.md +2 -2
  48. package/dart-src/packages/core/example/lib/main.dart +69 -0
  49. package/dart-src/packages/core/lib/flutter_ota_kit_core.dart +1 -1
  50. package/dart-src/packages/core/lib/src/app_update_info.dart +17 -15
  51. package/dart-src/packages/core/lib/src/bundle.dart +102 -94
  52. package/dart-src/packages/core/lib/src/bundle_artifacts.dart +1 -2
  53. package/dart-src/packages/core/lib/src/bundle_patch_artifact.dart +15 -16
  54. package/dart-src/packages/core/lib/src/changed_asset.dart +24 -22
  55. package/dart-src/packages/core/lib/src/get_bundles_args.dart +13 -13
  56. package/dart-src/packages/core/lib/src/metadata.dart +9 -7
  57. package/dart-src/packages/core/lib/src/patch_info.dart +8 -7
  58. package/dart-src/packages/core/lib/src/platform.dart +4 -3
  59. package/dart-src/packages/core/lib/src/rollout.dart +14 -11
  60. package/dart-src/packages/core/lib/src/semver_range.dart +49 -39
  61. package/dart-src/packages/core/lib/src/semver_version.dart +8 -7
  62. package/dart-src/packages/core/lib/src/status.dart +4 -3
  63. package/dart-src/packages/core/lib/src/update_bundle_params.dart +7 -7
  64. package/dart-src/packages/core/lib/src/uuid.dart +1 -2
  65. package/dart-src/packages/core/pubspec.yaml +6 -7
  66. package/dart-src/packages/core/test/rollout_test.dart +15 -8
  67. package/dart-src/packages/core/test/semver_test.dart +5 -2
  68. package/dart-src/packages/core/test/types_test.dart +26 -24
  69. package/dart-src/packages/core/test/uuid_test.dart +3 -1
  70. package/dart-src/packages/core/tool/dbg.dart +1 -0
  71. package/dart-src/plugins/aws/CHANGELOG.md +6 -0
  72. package/dart-src/plugins/aws/example/lib/main.dart +60 -0
  73. package/dart-src/plugins/aws/lib/flutter_ota_kit_aws.dart +5 -1
  74. package/dart-src/plugins/aws/lib/src/aws_cloudfront_client.dart +11 -16
  75. package/dart-src/plugins/aws/lib/src/aws_cloudfront_signer.dart +7 -2
  76. package/dart-src/plugins/aws/lib/src/aws_database.dart +14 -18
  77. package/dart-src/plugins/aws/lib/src/aws_s3_client.dart +23 -18
  78. package/dart-src/plugins/aws/lib/src/aws_ssm_client.dart +5 -4
  79. package/dart-src/plugins/aws/lib/src/aws_storage.dart +2 -3
  80. package/dart-src/plugins/aws/lib/src/aws_storage_profile.dart +10 -16
  81. package/dart-src/plugins/aws/lib/src/with_cloudfront_signed_url.dart +6 -9
  82. package/dart-src/plugins/aws/pubspec.yaml +15 -10
  83. package/dart-src/plugins/aws/test/aws_database_test.dart +51 -57
  84. package/dart-src/plugins/aws/test/mock_aws_s3_client.dart +8 -13
  85. package/dart-src/plugins/cloudflare/CHANGELOG.md +7 -0
  86. package/dart-src/plugins/cloudflare/example/lib/main.dart +62 -0
  87. package/dart-src/plugins/cloudflare/lib/flutter_ota_kit_cloudflare.dart +4 -2
  88. package/dart-src/plugins/cloudflare/lib/src/cloudflare_worker_database.dart +3 -3
  89. package/dart-src/plugins/cloudflare/lib/src/d1_build_where.dart +3 -2
  90. package/dart-src/plugins/cloudflare/lib/src/d1_bundle_mapper.dart +24 -27
  91. package/dart-src/plugins/cloudflare/lib/src/d1_database_plugin.dart +22 -30
  92. package/dart-src/plugins/cloudflare/lib/src/r2_config.dart +1 -1
  93. package/dart-src/plugins/cloudflare/lib/src/r2_s3_client.dart +21 -29
  94. package/dart-src/plugins/cloudflare/lib/src/r2_storage.dart +7 -7
  95. package/dart-src/plugins/cloudflare/lib/src/r2_storage_profile.dart +7 -15
  96. package/dart-src/plugins/cloudflare/pubspec.yaml +14 -9
  97. package/dart-src/plugins/cloudflare/test/cloudflare_worker_database_test.dart +46 -42
  98. package/dart-src/plugins/cloudflare/test/d1_database_test.dart +100 -90
  99. package/dart-src/plugins/cloudflare/test/mock_d1_client.dart +23 -18
  100. package/dart-src/plugins/cloudflare/test/mock_r2_client.dart +8 -13
  101. package/dart-src/plugins/cloudflare/test/r2_storage_test.dart +1 -4
  102. package/dart-src/plugins/plugin-core/CHANGELOG.md +16 -0
  103. package/dart-src/plugins/plugin-core/example/lib/main.dart +61 -0
  104. package/dart-src/plugins/plugin-core/lib/flutter_ota_kit_plugin_core.dart +3 -7
  105. package/dart-src/plugins/plugin-core/lib/src/asset_storage_layout.dart +5 -5
  106. package/dart-src/plugins/plugin-core/lib/src/bundle_helpers.dart +23 -0
  107. package/dart-src/plugins/plugin-core/lib/src/bundle_storage_layout.dart +16 -10
  108. package/dart-src/plugins/plugin-core/lib/src/bundle_unit_of_work.dart +31 -26
  109. package/dart-src/plugins/plugin-core/lib/src/calculate_pagination.dart +5 -1
  110. package/dart-src/plugins/plugin-core/lib/src/content_addressed_assets.dart +1 -1
  111. package/dart-src/plugins/plugin-core/lib/src/create_blob_database_plugin.dart +78 -71
  112. package/dart-src/plugins/plugin-core/lib/src/create_database_plugin.dart +56 -35
  113. package/dart-src/plugins/plugin-core/lib/src/create_storage_plugin.dart +10 -13
  114. package/dart-src/plugins/plugin-core/lib/src/paginate_bundles.dart +30 -17
  115. package/dart-src/plugins/plugin-core/lib/src/parse_storage_uri.dart +3 -1
  116. package/dart-src/plugins/plugin-core/lib/src/query_bundles.dart +5 -3
  117. package/dart-src/plugins/plugin-core/lib/src/request_update_bundle_state.dart +2 -4
  118. package/dart-src/plugins/plugin-core/lib/src/storage_helpers.dart +18 -0
  119. package/dart-src/plugins/plugin-core/lib/src/types.dart +7 -6
  120. package/dart-src/plugins/plugin-core/pubspec.yaml +12 -9
  121. package/dart-src/plugins/plugin-core/test/asset_storage_layout_test.dart +13 -9
  122. package/dart-src/plugins/plugin-core/test/bundle_unit_of_work_test.dart +28 -15
  123. package/dart-src/plugins/plugin-core/test/create_blob_database_plugin_test.dart +254 -122
  124. package/dart-src/plugins/plugin-core/test/create_database_plugin_test.dart +36 -32
  125. package/dart-src/plugins/plugin-core/test/create_storage_plugin_test.dart +18 -15
  126. package/dart-src/plugins/plugin-core/test/generate_min_bundle_id_test.dart +8 -3
  127. package/dart-src/plugins/plugin-core/test/get_update_info_test.dart +682 -693
  128. package/dart-src/plugins/plugin-core/test/helpers_test.dart +45 -21
  129. package/dart-src/plugins/plugin-core/test/query_bundles_test.dart +76 -13
  130. package/dart-src/plugins/plugin-core/test/uuidv7_test.dart +20 -9
  131. package/dart-src/plugins/pocketbase/CHANGELOG.md +8 -0
  132. package/dart-src/plugins/pocketbase/LICENSE +21 -0
  133. package/dart-src/plugins/pocketbase/README.md +54 -0
  134. package/dart-src/plugins/pocketbase/example/lib/main.dart +62 -0
  135. package/dart-src/plugins/pocketbase/lib/flutter_ota_kit_pocketbase.dart +28 -0
  136. package/dart-src/plugins/pocketbase/lib/src/pocketbase_bundle_mapper.dart +121 -0
  137. package/dart-src/plugins/pocketbase/lib/src/pocketbase_client.dart +349 -0
  138. package/dart-src/plugins/pocketbase/lib/src/pocketbase_config.dart +61 -0
  139. package/dart-src/plugins/pocketbase/lib/src/pocketbase_database.dart +278 -0
  140. package/dart-src/plugins/pocketbase/lib/src/pocketbase_storage.dart +255 -0
  141. package/dart-src/plugins/pocketbase/pubspec.yaml +26 -0
  142. package/dart-src/plugins/pocketbase/test/pb_uri_test.dart +12 -0
  143. package/dart-src/plugins/postgres/CHANGELOG.md +6 -0
  144. package/dart-src/plugins/postgres/example/lib/main.dart +67 -0
  145. package/dart-src/plugins/postgres/lib/flutter_ota_kit_postgres.dart +3 -6
  146. package/dart-src/plugins/postgres/lib/src/postgres_bundle_mapper.dart +32 -52
  147. package/dart-src/plugins/postgres/lib/src/postgres_config.dart +3 -1
  148. package/dart-src/plugins/postgres/lib/src/postgres_database.dart +28 -38
  149. package/dart-src/plugins/postgres/lib/src/postgres_get_update_info.dart +16 -14
  150. package/dart-src/plugins/postgres/lib/src/postgres_storage.dart +26 -14
  151. package/dart-src/plugins/postgres/lib/src/postgres_types.dart +27 -28
  152. package/dart-src/plugins/postgres/pubspec.yaml +14 -9
  153. package/dart-src/plugins/postgres/test/mock_postgres_client.dart +62 -39
  154. package/dart-src/plugins/postgres/test/postgres_bundle_mapper_test.dart +3 -4
  155. package/dart-src/plugins/postgres/test/postgres_database_test.dart +102 -73
  156. package/dart-src/plugins/postgres/test/postgres_storage_runtime_test.dart +60 -0
  157. package/dart-src/plugins/supabase/CHANGELOG.md +17 -0
  158. package/dart-src/plugins/supabase/README.md +2 -2
  159. package/dart-src/plugins/supabase/example/lib/main.dart +63 -0
  160. package/dart-src/plugins/supabase/lib/flutter_ota_kit_supabase.dart +2 -0
  161. package/dart-src/plugins/supabase/lib/src/error_message.dart +11 -0
  162. package/dart-src/plugins/supabase/lib/src/supabase_bundle_mapper.dart +34 -58
  163. package/dart-src/plugins/supabase/lib/src/supabase_client_adapter.dart +3 -13
  164. package/dart-src/plugins/supabase/lib/src/supabase_client_http.dart +34 -52
  165. package/dart-src/plugins/supabase/lib/src/supabase_database.dart +38 -30
  166. package/dart-src/plugins/supabase/lib/src/supabase_edge_function_storage.dart +21 -29
  167. package/dart-src/plugins/supabase/lib/src/supabase_signed_url_batcher.dart +7 -19
  168. package/dart-src/plugins/supabase/lib/src/supabase_storage.dart +18 -29
  169. package/dart-src/plugins/supabase/lib/src/types.dart +26 -26
  170. package/dart-src/plugins/supabase/pubspec.yaml +14 -9
  171. package/dart-src/plugins/supabase/test/mock_supabase_client.dart +57 -57
  172. package/dart-src/plugins/supabase/test/supabase_bundle_mapper_test.dart +30 -27
  173. package/dart-src/plugins/supabase/test/supabase_database_test.dart +26 -35
  174. package/dart-src/plugins/supabase/test/supabase_storage_test.dart +27 -34
  175. package/package.json +2 -2
  176. package/scripts/vendor.sh +1 -1
@@ -31,13 +31,13 @@ class _UpdateInfoRow {
31
31
  });
32
32
 
33
33
  factory _UpdateInfoRow.fromJson(Map<String, dynamic> row) => _UpdateInfoRow(
34
- id: row['id'] as String,
35
- shouldForceUpdate: row['should_force_update'] as bool,
36
- message: row['message'] as String?,
37
- status: row['status'] as String,
38
- storageUri: row['storage_uri'] as String?,
39
- fileHash: row['file_hash'] as String?,
40
- );
34
+ id: row['id'] as String,
35
+ shouldForceUpdate: row['should_force_update'] as bool,
36
+ message: row['message'] as String?,
37
+ status: row['status'] as String,
38
+ storageUri: row['storage_uri'] as String?,
39
+ fileHash: row['file_hash'] as String?,
40
+ );
41
41
 
42
42
  final String id;
43
43
  final bool shouldForceUpdate;
@@ -48,13 +48,15 @@ class _UpdateInfoRow {
48
48
  }
49
49
 
50
50
  UpdateInfo mapUpdateInfoRow(_UpdateInfoRow row) => UpdateInfo(
51
- id: row.id,
52
- shouldForceUpdate: row.shouldForceUpdate,
53
- message: row.message,
54
- status: row.status == 'ROLLBACK' ? UpdateStatus.rollback : UpdateStatus.update,
55
- storageUri: row.storageUri,
56
- fileHash: row.fileHash,
57
- );
51
+ id: row.id,
52
+ shouldForceUpdate: row.shouldForceUpdate,
53
+ message: row.message,
54
+ status: row.status == 'ROLLBACK'
55
+ ? UpdateStatus.rollback
56
+ : UpdateStatus.update,
57
+ storageUri: row.storageUri,
58
+ fileHash: row.fileHash,
59
+ );
58
60
 
59
61
  /// Resolve update info via the Postgres RPCs.
60
62
  Future<UpdateInfo?> getUpdateInfo(
@@ -29,7 +29,8 @@ class PostgresStorageConfig {
29
29
 
30
30
  /// Resolves the storage client for a config (test seam via [PostgresConfig.clientFactory]).
31
31
  PostgresClientLike resolvePostgresStorageClient(PostgresStorageConfig config) =>
32
- config.db.clientFactory?.call(config.db) ?? PostgresClient.connect(config.db);
32
+ config.db.clientFactory?.call(config.db) ??
33
+ PostgresClient.connect(config.db);
33
34
 
34
35
  String _storageUri(String key, String? servingBaseUrl) {
35
36
  if (servingBaseUrl != null && servingBaseUrl.isNotEmpty) {
@@ -52,8 +53,9 @@ String _strip(String storageUri, String? servingBaseUrl) {
52
53
  return storageUri.substring('postgres://'.length);
53
54
  }
54
55
  if (servingBaseUrl != null && storageUri.startsWith(servingBaseUrl)) {
55
- final base =
56
- servingBaseUrl.endsWith('/') ? servingBaseUrl : '$servingBaseUrl/';
56
+ final base = servingBaseUrl.endsWith('/')
57
+ ? servingBaseUrl
58
+ : '$servingBaseUrl/';
57
59
  return storageUri.startsWith(base)
58
60
  ? storageUri.substring(base.length)
59
61
  : storageUri;
@@ -71,8 +73,7 @@ NodeStorageProfile createPostgresNodeProfile(
71
73
  PostgresClientLike client,
72
74
  String? basePath,
73
75
  String? servingBaseUrl,
74
- ) =>
75
- _PostgresNodeProfile(client, basePath, servingBaseUrl);
76
+ ) => _PostgresNodeProfile(client, basePath, servingBaseUrl);
76
77
 
77
78
  class _PostgresNodeProfile implements NodeStorageProfile {
78
79
  _PostgresNodeProfile(this._client, this._basePath, this._servingBaseUrl);
@@ -92,11 +93,7 @@ class _PostgresNodeProfile implements NodeStorageProfile {
92
93
  'INSERT INTO flutter_ota_kit_storage (key, data, content_type) '
93
94
  'VALUES (@key, @data, @ct) '
94
95
  'ON CONFLICT (key) DO UPDATE SET data = EXCLUDED.data, content_type = EXCLUDED.content_type',
95
- {
96
- '@key': fullKey,
97
- '@data': bytes,
98
- '@ct': _contentType(fullKey),
99
- },
96
+ {'@key': fullKey, '@data': bytes, '@ct': _contentType(fullKey)},
100
97
  );
101
98
  return {'storageUri': _storageUri(fullKey, _servingBaseUrl)};
102
99
  }
@@ -164,8 +161,7 @@ class _PostgresNodeProfile implements NodeStorageProfile {
164
161
  RuntimeStorageProfile createPostgresRuntimeProfile(
165
162
  PostgresClientLike client,
166
163
  String? servingBaseUrl,
167
- ) =>
168
- _PostgresRuntimeProfile(client, servingBaseUrl);
164
+ ) => _PostgresRuntimeProfile(client, servingBaseUrl);
169
165
 
170
166
  class _PostgresRuntimeProfile implements RuntimeStorageProfile {
171
167
  _PostgresRuntimeProfile(this._client, this._servingBaseUrl);
@@ -175,7 +171,19 @@ class _PostgresRuntimeProfile implements RuntimeStorageProfile {
175
171
 
176
172
  @override
177
173
  Future<Map<String, String>> getDownloadUrl(String storageUri) async {
178
- return {'fileUrl': _storageUri(_strip(storageUri, _servingBaseUrl), _servingBaseUrl)};
174
+ if (_servingBaseUrl == null || _servingBaseUrl.isEmpty) {
175
+ throw StateError(
176
+ 'Postgres storage requires a servingBaseUrl to expose bytes over HTTP. '
177
+ 'Set `postgres.servingBaseUrl` in your config to a thin proxy that reads '
178
+ 'from the `flutter_ota_kit_storage` table.',
179
+ );
180
+ }
181
+ return {
182
+ 'fileUrl': _storageUri(
183
+ _strip(storageUri, _servingBaseUrl),
184
+ _servingBaseUrl,
185
+ ),
186
+ };
179
187
  }
180
188
 
181
189
  @override
@@ -198,7 +206,11 @@ StoragePlugin Function(PostgresStorageConfig) postgresStorage =
198
206
  factory: (cfg) {
199
207
  final client = resolvePostgresStorageClient(cfg);
200
208
  return (
201
- node: createPostgresNodeProfile(client, cfg.basePath, cfg.servingBaseUrl),
209
+ node: createPostgresNodeProfile(
210
+ client,
211
+ cfg.basePath,
212
+ cfg.servingBaseUrl,
213
+ ),
202
214
  runtime: createPostgresRuntimeProfile(client, cfg.servingBaseUrl),
203
215
  );
204
216
  },
@@ -1,5 +1,4 @@
1
- import 'package:flutter_ota_kit_core/flutter_ota_kit_core.dart'
2
- show Platform;
1
+ import 'package:flutter_ota_kit_core/flutter_ota_kit_core.dart' show Platform;
3
2
 
4
3
  /// Database row for the `bundles` table (snake_case columns).
5
4
  ///
@@ -66,24 +65,24 @@ class PostgresBundleRow {
66
65
  final List<String>? targetCohorts;
67
66
 
68
67
  Map<String, dynamic> toJson() => {
69
- 'id': id,
70
- 'channel': channel,
71
- 'enabled': enabled,
72
- 'should_force_update': shouldForceUpdate,
73
- 'file_hash': fileHash,
74
- 'git_commit_hash': gitCommitHash,
75
- 'message': message,
76
- 'platform': platform.name,
77
- 'target_app_version': targetAppVersion,
78
- 'storage_uri': storageUri,
79
- 'fingerprint_hash': fingerprintHash,
80
- 'metadata': metadata ?? const {},
81
- 'manifest_storage_uri': manifestStorageUri,
82
- 'manifest_file_hash': manifestFileHash,
83
- 'asset_base_storage_uri': assetBaseStorageUri,
84
- 'rollout_cohort_count': rolloutCohortCount,
85
- 'target_cohorts': targetCohorts,
86
- };
68
+ 'id': id,
69
+ 'channel': channel,
70
+ 'enabled': enabled,
71
+ 'should_force_update': shouldForceUpdate,
72
+ 'file_hash': fileHash,
73
+ 'git_commit_hash': gitCommitHash,
74
+ 'message': message,
75
+ 'platform': platform.name,
76
+ 'target_app_version': targetAppVersion,
77
+ 'storage_uri': storageUri,
78
+ 'fingerprint_hash': fingerprintHash,
79
+ 'metadata': metadata ?? const {},
80
+ 'manifest_storage_uri': manifestStorageUri,
81
+ 'manifest_file_hash': manifestFileHash,
82
+ 'asset_base_storage_uri': assetBaseStorageUri,
83
+ 'rollout_cohort_count': rolloutCohortCount,
84
+ 'target_cohorts': targetCohorts,
85
+ };
87
86
  }
88
87
 
89
88
  /// Database row for the `bundle_patches` table (snake_case columns).
@@ -121,12 +120,12 @@ class PostgresBundlePatchRow {
121
120
  final int orderIndex;
122
121
 
123
122
  Map<String, dynamic> toJson() => {
124
- 'id': id,
125
- 'bundle_id': bundleId,
126
- 'base_bundle_id': baseBundleId,
127
- 'base_file_hash': baseFileHash,
128
- 'patch_file_hash': patchFileHash,
129
- 'patch_storage_uri': patchStorageUri,
130
- 'order_index': orderIndex,
131
- };
123
+ 'id': id,
124
+ 'bundle_id': bundleId,
125
+ 'base_bundle_id': baseBundleId,
126
+ 'base_file_hash': baseFileHash,
127
+ 'patch_file_hash': patchFileHash,
128
+ 'patch_storage_uri': patchStorageUri,
129
+ 'order_index': orderIndex,
130
+ };
132
131
  }
@@ -1,21 +1,26 @@
1
1
  name: flutter_ota_kit_postgres
2
2
  description: Postgres plugin for flutter_ota_kit — database backend.
3
- version: 0.1.0
4
- publish_to: https://pub.dev
5
- homepage: https://github.com/HYPER12755/flutter_ota_kit
6
- repository: https://github.com/HYPER12755/flutter_ota_kit
7
- issue_tracker: https://github.com/HYPER12755/flutter_ota_kit/issues
8
- documentation: https://github.com/HYPER12755/flutter_ota_kit#readme
3
+ version: 0.1.2
4
+ homepage: https://github.com/HYPER12755/flutter-ota-kit
5
+ repository: https://github.com/HYPER12755/flutter-ota-kit
6
+ issue_tracker: https://github.com/HYPER12755/flutter-ota-kit/issues
7
+ documentation: https://github.com/HYPER12755/flutter-ota-kit#readme
9
8
  license: MIT
10
9
 
11
10
  environment:
12
- sdk: ">=3.3.0 <4.0.0"
11
+ sdk: ">=3.13.2 <4.0.0"
13
12
 
14
13
  dependencies:
15
- flutter_ota_kit_core: ^0.1.0
16
- flutter_ota_kit_plugin_core: ^0.0.1
14
+ flutter_ota_kit_core: ^0.1.1
15
+ flutter_ota_kit_plugin_core: ^0.0.3
17
16
  postgres: ^3.4.0
18
17
 
19
18
  dev_dependencies:
20
19
  test: ^1.25.0
21
20
  lints: ^4.0.0
21
+
22
+ dependency_overrides:
23
+ flutter_ota_kit_core:
24
+ path: ../../packages/core
25
+ flutter_ota_kit_plugin_core:
26
+ path: ../plugin-core
@@ -51,10 +51,7 @@ class MockPostgresClient implements PostgresClientLike {
51
51
  @override
52
52
  Future<void> close() async {}
53
53
 
54
- List<Map<String, dynamic>> _handle(
55
- String sql,
56
- Map<String, dynamic> params,
57
- ) {
54
+ List<Map<String, dynamic>> _handle(String sql, Map<String, dynamic> params) {
58
55
  if (sql.contains('get_target_app_version_list')) {
59
56
  return _targetAppVersionList(params);
60
57
  }
@@ -126,7 +123,8 @@ class MockPostgresClient implements PostgresClientLike {
126
123
  var rows = _filterBundles(sql, params);
127
124
 
128
125
  if (sql.contains('ORDER BY id asc')) {
129
- rows = rows.toList()..sort((a, b) => (a['id'] as String).compareTo(b['id'] as String));
126
+ rows = rows.toList()
127
+ ..sort((a, b) => (a['id'] as String).compareTo(b['id'] as String));
130
128
  } else {
131
129
  rows = rows.toList()
132
130
  ..sort((a, b) => (b['id'] as String).compareTo(a['id'] as String));
@@ -150,13 +148,18 @@ class MockPostgresClient implements PostgresClientLike {
150
148
  }
151
149
 
152
150
  List<Map<String, dynamic>> _channels() {
153
- final channels = store.bundleRows.map((r) => r['channel'] as String).toSet().toList();
151
+ final channels = store.bundleRows
152
+ .map((r) => r['channel'] as String)
153
+ .toSet()
154
+ .toList();
154
155
  return channels.map((c) => {'channel': c}).toList();
155
156
  }
156
157
 
157
158
  List<Map<String, dynamic>> _patchesForIds(Map<String, dynamic> params) {
158
159
  final ids = (params['bundle_ids'] as List).cast<String>();
159
- return store.bundlePatchRows.where((p) => ids.contains(p['bundle_id'])).toList();
160
+ return store.bundlePatchRows
161
+ .where((p) => ids.contains(p['bundle_id']))
162
+ .toList();
160
163
  }
161
164
 
162
165
  void _upsertBundle(Map<String, dynamic> params) {
@@ -173,7 +176,9 @@ class MockPostgresClient implements PostgresClientLike {
173
176
  void _upsertPatch(Map<String, dynamic> params) {
174
177
  final row = <String, dynamic>{};
175
178
  params.forEach((k, v) => row[k] = v);
176
- final existing = store.bundlePatchRows.indexWhere((r) => r['id'] == row['id']);
179
+ final existing = store.bundlePatchRows.indexWhere(
180
+ (r) => r['id'] == row['id'],
181
+ );
177
182
  if (existing >= 0) {
178
183
  store.bundlePatchRows[existing] = row;
179
184
  } else {
@@ -198,14 +203,24 @@ class MockPostgresClient implements PostgresClientLike {
198
203
  final existed = store.bundleRows.any((r) => r['id'] == id);
199
204
  store.bundleRows.removeWhere((r) => r['id'] == id);
200
205
  store.bundlePatchRows.removeWhere((p) => p['bundle_id'] == id);
201
- return existed ? [{'id': id}] : [];
206
+ return existed
207
+ ? [
208
+ {'id': id},
209
+ ]
210
+ : [];
202
211
  }
203
212
 
204
- List<Map<String, dynamic>> _targetAppVersionList(Map<String, dynamic> params) {
213
+ List<Map<String, dynamic>> _targetAppVersionList(
214
+ Map<String, dynamic> params,
215
+ ) {
205
216
  final platform = params['app_platform'];
206
217
  final min = params['min_bundle_id'] as String? ?? '';
207
218
  final versions = store.bundleRows
208
- .where((r) => r['platform'] == platform && (r['id'] as String).compareTo(min) >= 0)
219
+ .where(
220
+ (r) =>
221
+ r['platform'] == platform &&
222
+ (r['id'] as String).compareTo(min) >= 0,
223
+ )
209
224
  .map((r) => r['target_app_version'])
210
225
  .where((v) => v != null)
211
226
  .toSet()
@@ -222,44 +237,53 @@ class MockPostgresClient implements PostgresClientLike {
222
237
  return matches.isEmpty ? null : matches.first;
223
238
  }
224
239
 
225
- List<Map<String, dynamic>> _updateInfoByAppVersion(Map<String, dynamic> params) {
240
+ List<Map<String, dynamic>> _updateInfoByAppVersion(
241
+ Map<String, dynamic> params,
242
+ ) {
226
243
  final platform = params['app_platform'];
227
244
  final channel = params['target_channel'];
228
245
  final min = params['min_bundle_id'] as String? ?? '';
229
- final list = (params['target_app_version_list'] as List?)?.cast<String>() ?? [];
230
- final row = _newestMatch((r) =>
231
- r['platform'] == platform &&
232
- r['enabled'] == true &&
233
- r['channel'] == channel &&
234
- (r['id'] as String).compareTo(min) >= 0 &&
235
- list.contains(r['target_app_version']));
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
+ );
236
256
  if (row == null) return [];
237
257
  return [_infoRow(row)];
238
258
  }
239
259
 
240
- List<Map<String, dynamic>> _updateInfoByFingerprint(Map<String, dynamic> params) {
260
+ List<Map<String, dynamic>> _updateInfoByFingerprint(
261
+ Map<String, dynamic> params,
262
+ ) {
241
263
  final platform = params['app_platform'];
242
264
  final channel = params['target_channel'];
243
265
  final min = params['min_bundle_id'] as String? ?? '';
244
266
  final fp = params['target_fingerprint_hash'];
245
- final row = _newestMatch((r) =>
246
- r['platform'] == platform &&
247
- r['enabled'] == true &&
248
- r['channel'] == channel &&
249
- (r['id'] as String).compareTo(min) >= 0 &&
250
- r['fingerprint_hash'] == fp);
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
+ );
251
275
  if (row == null) return [];
252
276
  return [_infoRow(row)];
253
277
  }
254
278
 
255
279
  Map<String, dynamic> _infoRow(Map<String, dynamic> row) => {
256
- 'id': row['id'],
257
- 'should_force_update': row['should_force_update'],
258
- 'message': row['message'],
259
- 'status': 'UPDATE',
260
- 'storage_uri': row['storage_uri'],
261
- 'file_hash': row['file_hash'],
262
- };
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
+ };
263
287
  }
264
288
 
265
289
  class _TxClient implements PostgresClientLike {
@@ -271,8 +295,7 @@ class _TxClient implements PostgresClientLike {
271
295
  Future<List<Map<String, dynamic>>> execute(
272
296
  String sql,
273
297
  Map<String, dynamic> parameters,
274
- ) =>
275
- _parent.execute(sql, parameters);
298
+ ) => _parent.execute(sql, parameters);
276
299
 
277
300
  @override
278
301
  Future<T> runTx<T>(Future<T> Function(PostgresClientLike tx) fn) =>
@@ -284,10 +307,10 @@ class _TxClient implements PostgresClientLike {
284
307
 
285
308
  /// Build a [PostgresConfig] wired to [MockPostgresClient].
286
309
  PostgresConfig mockPostgresConfig(Store store) => PostgresConfig(
287
- host: 'mock',
288
- database: 'mock',
289
- clientFactory: (_) => MockPostgresClient(store),
290
- );
310
+ host: 'mock',
311
+ database: 'mock',
312
+ clientFactory: (_) => MockPostgresClient(store),
313
+ );
291
314
 
292
315
  /// Create a [DatabasePlugin] backed by the mock store.
293
316
  DatabasePlugin newPlugin({Store? store}) {
@@ -84,10 +84,9 @@ void main() {
84
84
 
85
85
  final row = bundleToRowValues(bundle);
86
86
  final patchRows = bundleToPatchRows(bundle);
87
- final back = mapRowToBundle(
88
- PostgresBundleRow.fromJson(row),
89
- [PostgresBundlePatchRow.fromJson(patchRows.first)],
90
- );
87
+ final back = mapRowToBundle(PostgresBundleRow.fromJson(row), [
88
+ PostgresBundlePatchRow.fromJson(patchRows.first),
89
+ ]);
91
90
 
92
91
  expect(back.id, bundle.id);
93
92
  expect(back.fileHash, 'hash-1');