@_nazmiforreal/flutter-ota 0.1.12 → 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.
- package/README.md +1 -1
- package/bin/flutter-ota-linux-x64 +0 -0
- package/dart-src/packages/cli-tools/.dart_tool/package_config.json +46 -76
- package/dart-src/packages/cli-tools/.dart_tool/package_graph.json +140 -166
- package/dart-src/packages/cli-tools/README.md +1 -1
- package/dart-src/packages/cli-tools/lib/flutter_ota_kit_cli.dart +30 -17
- package/dart-src/packages/cli-tools/lib/src/backend.dart +30 -31
- package/dart-src/packages/cli-tools/lib/src/cli_base.dart +3 -1
- package/dart-src/packages/cli-tools/lib/src/commands/build.dart +44 -43
- package/dart-src/packages/cli-tools/lib/src/commands/bundle.dart +265 -239
- package/dart-src/packages/cli-tools/lib/src/commands/channel.dart +75 -66
- package/dart-src/packages/cli-tools/lib/src/commands/config_command.dart +39 -35
- package/dart-src/packages/cli-tools/lib/src/commands/console.dart +30 -27
- package/dart-src/packages/cli-tools/lib/src/commands/deploy.dart +88 -72
- package/dart-src/packages/cli-tools/lib/src/commands/doctor.dart +66 -29
- package/dart-src/packages/cli-tools/lib/src/commands/fingerprint.dart +10 -6
- package/dart-src/packages/cli-tools/lib/src/commands/init.dart +290 -181
- package/dart-src/packages/cli-tools/lib/src/commands/keys.dart +24 -23
- package/dart-src/packages/cli-tools/lib/src/commands/migrate.dart +111 -97
- package/dart-src/packages/cli-tools/lib/src/commands/pocketbase.dart +237 -0
- package/dart-src/packages/cli-tools/lib/src/commands/rollback.dart +43 -34
- package/dart-src/packages/cli-tools/lib/src/commands/storage.dart +57 -53
- package/dart-src/packages/cli-tools/lib/src/config.dart +227 -93
- package/dart-src/packages/cli-tools/lib/src/operations.dart +9 -8
- package/dart-src/packages/cli-tools/lib/src/pack.dart +26 -25
- package/dart-src/packages/cli-tools/lib/src/pocketbase/data_bootstrap.dart +39 -0
- package/dart-src/packages/cli-tools/lib/src/pocketbase/hooks/bundles.pb.js +56 -0
- package/dart-src/packages/cli-tools/lib/src/pocketbase/installer.dart +189 -0
- package/dart-src/packages/cli-tools/lib/src/pocketbase/process_manager.dart +123 -0
- package/dart-src/packages/cli-tools/lib/src/pocketbase/schema_installer.dart +237 -0
- package/dart-src/packages/cli-tools/lib/src/runner.dart +36 -15
- package/dart-src/packages/cli-tools/lib/src/sign.dart +13 -5
- package/dart-src/packages/cli-tools/lib/src/ui/ui.dart +10 -13
- package/dart-src/packages/cli-tools/lib/src/util.dart +3 -1
- package/dart-src/packages/cli-tools/pubspec.lock +69 -116
- package/dart-src/packages/cli-tools/pubspec.yaml +25 -7
- package/dart-src/packages/cli-tools/test/backends_test.dart +62 -32
- package/dart-src/packages/cli-tools/test/build_pack_test.dart +4 -4
- package/dart-src/packages/cli-tools/test/cli_test.dart +89 -42
- package/dart-src/packages/cli-tools/test/mocks/mock_aws_s3_client.dart +8 -13
- package/dart-src/packages/cli-tools/test/mocks/mock_d1_client.dart +23 -18
- package/dart-src/packages/cli-tools/test/mocks/mock_pocketbase_client.dart +197 -0
- package/dart-src/packages/cli-tools/test/mocks/mock_postgres_client.dart +70 -46
- package/dart-src/packages/cli-tools/test/pocketbase_installer_test.dart +72 -0
- package/dart-src/packages/cli-tools/test/pocketbase_schema_test.dart +107 -0
- package/dart-src/packages/cli-tools/test/pocketbase_smoke_test.dart +59 -0
- package/dart-src/packages/core/README.md +2 -2
- package/dart-src/packages/core/example/lib/main.dart +69 -0
- package/dart-src/packages/core/lib/flutter_ota_kit_core.dart +1 -1
- package/dart-src/packages/core/lib/src/app_update_info.dart +17 -15
- package/dart-src/packages/core/lib/src/bundle.dart +102 -94
- package/dart-src/packages/core/lib/src/bundle_artifacts.dart +1 -2
- package/dart-src/packages/core/lib/src/bundle_patch_artifact.dart +15 -16
- package/dart-src/packages/core/lib/src/changed_asset.dart +24 -22
- package/dart-src/packages/core/lib/src/get_bundles_args.dart +13 -13
- package/dart-src/packages/core/lib/src/metadata.dart +9 -7
- package/dart-src/packages/core/lib/src/patch_info.dart +8 -7
- package/dart-src/packages/core/lib/src/platform.dart +4 -3
- package/dart-src/packages/core/lib/src/rollout.dart +14 -11
- package/dart-src/packages/core/lib/src/semver_range.dart +49 -39
- package/dart-src/packages/core/lib/src/semver_version.dart +8 -7
- package/dart-src/packages/core/lib/src/status.dart +4 -3
- package/dart-src/packages/core/lib/src/update_bundle_params.dart +7 -7
- package/dart-src/packages/core/lib/src/uuid.dart +1 -2
- package/dart-src/packages/core/pubspec.yaml +6 -7
- package/dart-src/packages/core/test/rollout_test.dart +15 -8
- package/dart-src/packages/core/test/semver_test.dart +5 -2
- package/dart-src/packages/core/test/types_test.dart +26 -24
- package/dart-src/packages/core/test/uuid_test.dart +3 -1
- package/dart-src/packages/core/tool/dbg.dart +1 -0
- package/dart-src/plugins/aws/CHANGELOG.md +6 -0
- package/dart-src/plugins/aws/example/lib/main.dart +60 -0
- package/dart-src/plugins/aws/lib/flutter_ota_kit_aws.dart +5 -1
- package/dart-src/plugins/aws/lib/src/aws_cloudfront_client.dart +11 -16
- package/dart-src/plugins/aws/lib/src/aws_cloudfront_signer.dart +7 -2
- package/dart-src/plugins/aws/lib/src/aws_database.dart +14 -18
- package/dart-src/plugins/aws/lib/src/aws_s3_client.dart +23 -18
- package/dart-src/plugins/aws/lib/src/aws_ssm_client.dart +5 -4
- package/dart-src/plugins/aws/lib/src/aws_storage.dart +2 -3
- package/dart-src/plugins/aws/lib/src/aws_storage_profile.dart +10 -16
- package/dart-src/plugins/aws/lib/src/with_cloudfront_signed_url.dart +6 -9
- package/dart-src/plugins/aws/pubspec.yaml +15 -10
- package/dart-src/plugins/aws/test/aws_database_test.dart +51 -57
- package/dart-src/plugins/aws/test/mock_aws_s3_client.dart +8 -13
- package/dart-src/plugins/cloudflare/CHANGELOG.md +7 -0
- package/dart-src/plugins/cloudflare/example/lib/main.dart +62 -0
- package/dart-src/plugins/cloudflare/lib/flutter_ota_kit_cloudflare.dart +4 -2
- package/dart-src/plugins/cloudflare/lib/src/cloudflare_worker_database.dart +3 -3
- package/dart-src/plugins/cloudflare/lib/src/d1_build_where.dart +3 -2
- package/dart-src/plugins/cloudflare/lib/src/d1_bundle_mapper.dart +24 -27
- package/dart-src/plugins/cloudflare/lib/src/d1_database_plugin.dart +22 -30
- package/dart-src/plugins/cloudflare/lib/src/r2_config.dart +1 -1
- package/dart-src/plugins/cloudflare/lib/src/r2_s3_client.dart +21 -29
- package/dart-src/plugins/cloudflare/lib/src/r2_storage.dart +7 -7
- package/dart-src/plugins/cloudflare/lib/src/r2_storage_profile.dart +7 -15
- package/dart-src/plugins/cloudflare/pubspec.yaml +14 -9
- package/dart-src/plugins/cloudflare/test/cloudflare_worker_database_test.dart +46 -42
- package/dart-src/plugins/cloudflare/test/d1_database_test.dart +100 -90
- package/dart-src/plugins/cloudflare/test/mock_d1_client.dart +23 -18
- package/dart-src/plugins/cloudflare/test/mock_r2_client.dart +8 -13
- package/dart-src/plugins/cloudflare/test/r2_storage_test.dart +1 -4
- package/dart-src/plugins/plugin-core/CHANGELOG.md +16 -0
- package/dart-src/plugins/plugin-core/example/lib/main.dart +61 -0
- package/dart-src/plugins/plugin-core/lib/flutter_ota_kit_plugin_core.dart +3 -7
- package/dart-src/plugins/plugin-core/lib/src/asset_storage_layout.dart +5 -5
- package/dart-src/plugins/plugin-core/lib/src/bundle_helpers.dart +23 -0
- package/dart-src/plugins/plugin-core/lib/src/bundle_storage_layout.dart +16 -10
- package/dart-src/plugins/plugin-core/lib/src/bundle_unit_of_work.dart +31 -26
- package/dart-src/plugins/plugin-core/lib/src/calculate_pagination.dart +5 -1
- package/dart-src/plugins/plugin-core/lib/src/content_addressed_assets.dart +1 -1
- package/dart-src/plugins/plugin-core/lib/src/create_blob_database_plugin.dart +78 -71
- package/dart-src/plugins/plugin-core/lib/src/create_database_plugin.dart +56 -35
- package/dart-src/plugins/plugin-core/lib/src/create_storage_plugin.dart +10 -13
- package/dart-src/plugins/plugin-core/lib/src/paginate_bundles.dart +30 -17
- package/dart-src/plugins/plugin-core/lib/src/parse_storage_uri.dart +3 -1
- package/dart-src/plugins/plugin-core/lib/src/query_bundles.dart +5 -3
- package/dart-src/plugins/plugin-core/lib/src/request_update_bundle_state.dart +2 -4
- package/dart-src/plugins/plugin-core/lib/src/storage_helpers.dart +18 -0
- package/dart-src/plugins/plugin-core/lib/src/types.dart +7 -6
- package/dart-src/plugins/plugin-core/pubspec.yaml +12 -9
- package/dart-src/plugins/plugin-core/test/asset_storage_layout_test.dart +13 -9
- package/dart-src/plugins/plugin-core/test/bundle_unit_of_work_test.dart +28 -15
- package/dart-src/plugins/plugin-core/test/create_blob_database_plugin_test.dart +254 -122
- package/dart-src/plugins/plugin-core/test/create_database_plugin_test.dart +36 -32
- package/dart-src/plugins/plugin-core/test/create_storage_plugin_test.dart +18 -15
- package/dart-src/plugins/plugin-core/test/generate_min_bundle_id_test.dart +8 -3
- package/dart-src/plugins/plugin-core/test/get_update_info_test.dart +682 -693
- package/dart-src/plugins/plugin-core/test/helpers_test.dart +45 -21
- package/dart-src/plugins/plugin-core/test/query_bundles_test.dart +76 -13
- package/dart-src/plugins/plugin-core/test/uuidv7_test.dart +20 -9
- package/dart-src/plugins/pocketbase/CHANGELOG.md +8 -0
- package/dart-src/plugins/pocketbase/LICENSE +21 -0
- package/dart-src/plugins/pocketbase/README.md +54 -0
- package/dart-src/plugins/pocketbase/example/lib/main.dart +62 -0
- package/dart-src/plugins/pocketbase/lib/flutter_ota_kit_pocketbase.dart +28 -0
- package/dart-src/plugins/pocketbase/lib/src/pocketbase_bundle_mapper.dart +121 -0
- package/dart-src/plugins/pocketbase/lib/src/pocketbase_client.dart +349 -0
- package/dart-src/plugins/pocketbase/lib/src/pocketbase_config.dart +61 -0
- package/dart-src/plugins/pocketbase/lib/src/pocketbase_database.dart +278 -0
- package/dart-src/plugins/pocketbase/lib/src/pocketbase_storage.dart +255 -0
- package/dart-src/plugins/pocketbase/pubspec.yaml +26 -0
- package/dart-src/plugins/pocketbase/test/pb_uri_test.dart +12 -0
- package/dart-src/plugins/postgres/CHANGELOG.md +6 -0
- package/dart-src/plugins/postgres/example/lib/main.dart +67 -0
- package/dart-src/plugins/postgres/lib/flutter_ota_kit_postgres.dart +3 -6
- package/dart-src/plugins/postgres/lib/src/postgres_bundle_mapper.dart +32 -52
- package/dart-src/plugins/postgres/lib/src/postgres_config.dart +3 -1
- package/dart-src/plugins/postgres/lib/src/postgres_database.dart +28 -38
- package/dart-src/plugins/postgres/lib/src/postgres_get_update_info.dart +16 -14
- package/dart-src/plugins/postgres/lib/src/postgres_storage.dart +26 -14
- package/dart-src/plugins/postgres/lib/src/postgres_types.dart +27 -28
- package/dart-src/plugins/postgres/pubspec.yaml +14 -9
- package/dart-src/plugins/postgres/test/mock_postgres_client.dart +62 -39
- package/dart-src/plugins/postgres/test/postgres_bundle_mapper_test.dart +3 -4
- package/dart-src/plugins/postgres/test/postgres_database_test.dart +102 -73
- package/dart-src/plugins/postgres/test/postgres_storage_runtime_test.dart +60 -0
- package/dart-src/plugins/supabase/CHANGELOG.md +17 -0
- package/dart-src/plugins/supabase/README.md +2 -2
- package/dart-src/plugins/supabase/example/lib/main.dart +63 -0
- package/dart-src/plugins/supabase/lib/flutter_ota_kit_supabase.dart +2 -0
- package/dart-src/plugins/supabase/lib/src/error_message.dart +11 -0
- package/dart-src/plugins/supabase/lib/src/supabase_bundle_mapper.dart +34 -58
- package/dart-src/plugins/supabase/lib/src/supabase_client_adapter.dart +3 -13
- package/dart-src/plugins/supabase/lib/src/supabase_client_http.dart +34 -52
- package/dart-src/plugins/supabase/lib/src/supabase_database.dart +38 -30
- package/dart-src/plugins/supabase/lib/src/supabase_edge_function_storage.dart +21 -29
- package/dart-src/plugins/supabase/lib/src/supabase_signed_url_batcher.dart +7 -19
- package/dart-src/plugins/supabase/lib/src/supabase_storage.dart +18 -29
- package/dart-src/plugins/supabase/lib/src/types.dart +26 -26
- package/dart-src/plugins/supabase/pubspec.yaml +14 -9
- package/dart-src/plugins/supabase/test/mock_supabase_client.dart +57 -57
- package/dart-src/plugins/supabase/test/supabase_bundle_mapper_test.dart +30 -27
- package/dart-src/plugins/supabase/test/supabase_database_test.dart +26 -35
- package/dart-src/plugins/supabase/test/supabase_storage_test.dart +27 -34
- package/package.json +3 -3
- package/scripts/vendor.sh +1 -1
|
@@ -38,12 +38,12 @@ class _FilterBuilder implements SupabaseFilterBuilderLike {
|
|
|
38
38
|
Map<String, String>? query,
|
|
39
39
|
String method = 'GET',
|
|
40
40
|
Object? body,
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
}) : _baseUrl = baseUrl,
|
|
42
|
+
_table = table,
|
|
43
|
+
_headers = headers,
|
|
44
|
+
_query = query ?? {},
|
|
45
|
+
_method = method,
|
|
46
|
+
_body = body;
|
|
47
47
|
|
|
48
48
|
@override
|
|
49
49
|
SupabaseFilterBuilderLike eq(String column, Object? value) =>
|
|
@@ -78,11 +78,7 @@ class _FilterBuilder implements SupabaseFilterBuilderLike {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
@override
|
|
81
|
-
SupabaseFilterBuilderLike not(
|
|
82
|
-
String column,
|
|
83
|
-
String operator,
|
|
84
|
-
Object? value,
|
|
85
|
-
) {
|
|
81
|
+
SupabaseFilterBuilderLike not(String column, String operator, Object? value) {
|
|
86
82
|
_query[column] = 'not.$operator.${_enc(value)}';
|
|
87
83
|
return this;
|
|
88
84
|
}
|
|
@@ -129,8 +125,7 @@ class _FilterBuilder implements SupabaseFilterBuilderLike {
|
|
|
129
125
|
.replace(queryParameters: _query.isEmpty ? null : _query);
|
|
130
126
|
final headers = <String, String>{
|
|
131
127
|
..._headers,
|
|
132
|
-
if (_method != 'GET' && _body != null)
|
|
133
|
-
'Content-Type': 'application/json',
|
|
128
|
+
if (_method != 'GET' && _body != null) 'Content-Type': 'application/json',
|
|
134
129
|
};
|
|
135
130
|
|
|
136
131
|
late http.Response res;
|
|
@@ -181,11 +176,7 @@ class _QueryBuilder implements SupabaseQueryBuilderLike {
|
|
|
181
176
|
_QueryBuilder(this._baseUrl, this._table, this._headers);
|
|
182
177
|
|
|
183
178
|
@override
|
|
184
|
-
SupabaseFilterBuilderLike select(
|
|
185
|
-
String columns, {
|
|
186
|
-
bool? count,
|
|
187
|
-
bool? head,
|
|
188
|
-
}) {
|
|
179
|
+
SupabaseFilterBuilderLike select(String columns, {bool? count, bool? head}) {
|
|
189
180
|
final headers = <String, String>{..._headers};
|
|
190
181
|
if (count == true) headers['Prefer'] = 'count=exact';
|
|
191
182
|
if (head == true) headers['Range'] = '0-0';
|
|
@@ -199,18 +190,16 @@ class _QueryBuilder implements SupabaseQueryBuilderLike {
|
|
|
199
190
|
|
|
200
191
|
@override
|
|
201
192
|
SupabaseFilterBuilderLike delete() => _FilterBuilder(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
193
|
+
baseUrl: _baseUrl,
|
|
194
|
+
table: _table,
|
|
195
|
+
headers: _headers,
|
|
196
|
+
method: 'DELETE',
|
|
197
|
+
);
|
|
207
198
|
|
|
208
199
|
@override
|
|
209
200
|
Future<dynamic> upsert(dynamic values, {String? onConflict}) async {
|
|
210
201
|
final uri = Uri.parse('$_baseUrl/rest/v1/$_table').replace(
|
|
211
|
-
queryParameters: onConflict != null
|
|
212
|
-
? {'on_conflict': onConflict}
|
|
213
|
-
: null,
|
|
202
|
+
queryParameters: onConflict != null ? {'on_conflict': onConflict} : null,
|
|
214
203
|
);
|
|
215
204
|
final headers = <String, String>{
|
|
216
205
|
..._headers,
|
|
@@ -273,10 +262,7 @@ class _StorageBucket implements SupabaseStorageBucketLike {
|
|
|
273
262
|
final res = await http.post(
|
|
274
263
|
uri,
|
|
275
264
|
headers: {..._headers, 'Content-Type': 'application/json'},
|
|
276
|
-
body: jsonEncode({
|
|
277
|
-
'expiresIn': expiresIn,
|
|
278
|
-
'paths': paths,
|
|
279
|
-
}),
|
|
265
|
+
body: jsonEncode({'expiresIn': expiresIn, 'paths': paths}),
|
|
280
266
|
);
|
|
281
267
|
if (res.statusCode >= 400) {
|
|
282
268
|
return _MockSignedUrlListResult(null, jsonDecode(res.body));
|
|
@@ -284,14 +270,16 @@ class _StorageBucket implements SupabaseStorageBucketLike {
|
|
|
284
270
|
final body = jsonDecode(res.body) as List<dynamic>;
|
|
285
271
|
return _MockSignedUrlListResult(
|
|
286
272
|
body
|
|
287
|
-
.map(
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
273
|
+
.map(
|
|
274
|
+
(e) => _MockSignedUrlResult(
|
|
275
|
+
// Supabase returns a relative path; make it absolute against
|
|
276
|
+
// the project base URL, matching [createSignedUrl].
|
|
277
|
+
e['signedURL'] == null
|
|
278
|
+
? null
|
|
279
|
+
: '$_baseUrl/storage/v1${e['signedURL'] as String}',
|
|
280
|
+
e['error'] as String?,
|
|
281
|
+
),
|
|
282
|
+
)
|
|
295
283
|
.toList(),
|
|
296
284
|
null,
|
|
297
285
|
);
|
|
@@ -367,9 +355,8 @@ class _StorageBucket implements SupabaseStorageBucketLike {
|
|
|
367
355
|
|
|
368
356
|
@override
|
|
369
357
|
Future<SupabaseExistsResult> exists(String path) async {
|
|
370
|
-
final uri = Uri.parse(
|
|
371
|
-
|
|
372
|
-
).replace(queryParameters: {'_method': 'HEAD'});
|
|
358
|
+
final uri = Uri.parse('$_baseUrl/storage/v1/object/$_bucket/$path')
|
|
359
|
+
.replace(queryParameters: {'_method': 'HEAD'});
|
|
373
360
|
final res = await http.get(uri, headers: _headers);
|
|
374
361
|
if (res.statusCode == 404) {
|
|
375
362
|
return _MockExistsResult(false, null);
|
|
@@ -404,11 +391,10 @@ class _StorageBucket implements SupabaseStorageBucketLike {
|
|
|
404
391
|
final body = jsonDecode(res.body) as Map<String, dynamic>;
|
|
405
392
|
return _MockListResult(null, body['message'] as String?);
|
|
406
393
|
}
|
|
407
|
-
final body =
|
|
394
|
+
final body =
|
|
395
|
+
(res.body.isEmpty ? [] : jsonDecode(res.body)) as List<dynamic>;
|
|
408
396
|
return _MockListResult(
|
|
409
|
-
body
|
|
410
|
-
.map((e) => _MockStorageObject(e as Map<String, dynamic>))
|
|
411
|
-
.toList(),
|
|
397
|
+
body.map((e) => _MockStorageObject(e as Map<String, dynamic>)).toList(),
|
|
412
398
|
null,
|
|
413
399
|
);
|
|
414
400
|
}
|
|
@@ -510,19 +496,15 @@ class SupabaseHttpClient implements SupabaseClientLike {
|
|
|
510
496
|
final Map<String, String> _headers;
|
|
511
497
|
|
|
512
498
|
SupabaseHttpClient(String supabaseUrl, String key)
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
'apikey': key,
|
|
516
|
-
'Authorization': 'Bearer $key',
|
|
517
|
-
};
|
|
499
|
+
: _baseUrl = supabaseUrl,
|
|
500
|
+
_headers = {'apikey': key, 'Authorization': 'Bearer $key'};
|
|
518
501
|
|
|
519
502
|
@override
|
|
520
503
|
SupabaseQueryBuilderLike from(String table) =>
|
|
521
504
|
_QueryBuilder(_baseUrl, table, _headers);
|
|
522
505
|
|
|
523
506
|
@override
|
|
524
|
-
SupabaseStorageClientLike get storage =>
|
|
525
|
-
_StorageClient(_baseUrl, _headers);
|
|
507
|
+
SupabaseStorageClientLike get storage => _StorageClient(_baseUrl, _headers);
|
|
526
508
|
|
|
527
509
|
@override
|
|
528
510
|
Future<SupabaseRpcResponse> rpc(
|
|
@@ -57,13 +57,15 @@ Object createSupabaseError(Object error) {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
UpdateInfo mapUpdateInfoRow(_SupabaseUpdateInfoRow row) => UpdateInfo(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
60
|
+
id: row.id,
|
|
61
|
+
shouldForceUpdate: row.shouldForceUpdate,
|
|
62
|
+
message: row.message,
|
|
63
|
+
status: row.status == 'ROLLBACK'
|
|
64
|
+
? UpdateStatus.rollback
|
|
65
|
+
: UpdateStatus.update,
|
|
66
|
+
storageUri: row.storageUri,
|
|
67
|
+
fileHash: row.fileHash,
|
|
68
|
+
);
|
|
67
69
|
|
|
68
70
|
/// Supabase-backed [DatabasePlugin] factory.
|
|
69
71
|
///
|
|
@@ -73,15 +75,13 @@ UpdateInfo mapUpdateInfoRow(_SupabaseUpdateInfoRow row) => UpdateInfo(
|
|
|
73
75
|
DatabasePlugin Function() Function(
|
|
74
76
|
SupabaseDatabaseConfig config, [
|
|
75
77
|
DatabasePluginHooks? hooks,
|
|
76
|
-
])
|
|
78
|
+
])
|
|
79
|
+
supabaseDatabase = createDatabasePlugin<SupabaseDatabaseConfig>(
|
|
77
80
|
name: 'supabaseDatabase',
|
|
78
81
|
factory: (config) {
|
|
79
82
|
final supabase = (config.clientFactory != null
|
|
80
83
|
? config.clientFactory!(config.supabaseUrl, config.resolveKey())
|
|
81
|
-
: createSupabaseHttpClient(
|
|
82
|
-
config.supabaseUrl,
|
|
83
|
-
config.resolveKey(),
|
|
84
|
-
));
|
|
84
|
+
: createSupabaseHttpClient(config.supabaseUrl, config.resolveKey()));
|
|
85
85
|
|
|
86
86
|
Future<Map<String, List<SupabaseBundlePatchRow>>> fetchPatchMap(
|
|
87
87
|
List<String> bundleIds,
|
|
@@ -123,7 +123,8 @@ class _SupabaseDatabasePlugin implements AbstractDatabasePlugin {
|
|
|
123
123
|
final SupabaseClientLike supabase;
|
|
124
124
|
final Future<Map<String, List<SupabaseBundlePatchRow>>> Function(
|
|
125
125
|
List<String> bundleIds,
|
|
126
|
-
)
|
|
126
|
+
)
|
|
127
|
+
fetchPatchMap;
|
|
127
128
|
|
|
128
129
|
_SupabaseDatabasePlugin({
|
|
129
130
|
required this.supabase,
|
|
@@ -152,8 +153,11 @@ class _SupabaseDatabasePlugin implements AbstractDatabasePlugin {
|
|
|
152
153
|
}
|
|
153
154
|
final targetAppVersionList = filterCompatibleAppVersions(
|
|
154
155
|
((targetRes.data as List?) ?? [])
|
|
155
|
-
.map(
|
|
156
|
-
|
|
156
|
+
.map(
|
|
157
|
+
(row) => _SupabaseTargetAppVersionRow(
|
|
158
|
+
(row as Map)['target_app_version'],
|
|
159
|
+
),
|
|
160
|
+
)
|
|
157
161
|
.where((row) => row.targetAppVersion != null)
|
|
158
162
|
.map((row) => row.targetAppVersion!)
|
|
159
163
|
.toList(),
|
|
@@ -229,9 +233,11 @@ class _SupabaseDatabasePlugin implements AbstractDatabasePlugin {
|
|
|
229
233
|
final row = SupabaseBundleRow.fromJson(
|
|
230
234
|
(res.data as Map).cast<String, dynamic>(),
|
|
231
235
|
);
|
|
232
|
-
final patches =
|
|
236
|
+
final patches =
|
|
237
|
+
(results[1] as Map<String, List<SupabaseBundlePatchRow>>)[bundleId] ??
|
|
238
|
+
[];
|
|
233
239
|
return mapRowToBundle(row, patches);
|
|
234
|
-
|
|
240
|
+
}
|
|
235
241
|
|
|
236
242
|
@override
|
|
237
243
|
Future<Paginated<List<Bundle>>> getBundles(
|
|
@@ -239,9 +245,10 @@ class _SupabaseDatabasePlugin implements AbstractDatabasePlugin {
|
|
|
239
245
|
) async {
|
|
240
246
|
final where = options.where;
|
|
241
247
|
final limit = options.limit;
|
|
242
|
-
final orderBy =
|
|
243
|
-
const DatabaseBundleQueryOrder(direction: 'desc');
|
|
244
|
-
final offset =
|
|
248
|
+
final orderBy =
|
|
249
|
+
options.orderBy ?? const DatabaseBundleQueryOrder(direction: 'desc');
|
|
250
|
+
final offset =
|
|
251
|
+
options.offset ??
|
|
245
252
|
(options.page != null ? (options.page! - 1) * limit : 0);
|
|
246
253
|
|
|
247
254
|
if ((where?.targetAppVersionIn != null &&
|
|
@@ -279,7 +286,9 @@ class _SupabaseDatabasePlugin implements AbstractDatabasePlugin {
|
|
|
279
286
|
data.map((b) => (b as Map)['id'] as String).toList(),
|
|
280
287
|
);
|
|
281
288
|
final bundles = data.map((b) {
|
|
282
|
-
final row = SupabaseBundleRow.fromJson(
|
|
289
|
+
final row = SupabaseBundleRow.fromJson(
|
|
290
|
+
(b as Map).cast<String, dynamic>(),
|
|
291
|
+
);
|
|
283
292
|
return mapRowToBundle(row, patchMap[row.id] ?? []);
|
|
284
293
|
}).toList();
|
|
285
294
|
|
|
@@ -339,15 +348,11 @@ class _SupabaseDatabasePlugin implements AbstractDatabasePlugin {
|
|
|
339
348
|
throw createSupabaseError(res.error!);
|
|
340
349
|
}
|
|
341
350
|
final data = (res.data as List?) ?? [];
|
|
342
|
-
return data
|
|
343
|
-
.map((row) => (row as Map)['channel'] as String)
|
|
344
|
-
.toList();
|
|
351
|
+
return data.map((row) => (row as Map)['channel'] as String).toList();
|
|
345
352
|
}
|
|
346
353
|
|
|
347
354
|
@override
|
|
348
|
-
Future<void> commitBundle({
|
|
349
|
-
required List<BundleChange> changedSets,
|
|
350
|
-
}) async {
|
|
355
|
+
Future<void> commitBundle({required List<BundleChange> changedSets}) async {
|
|
351
356
|
if (changedSets.isEmpty) return;
|
|
352
357
|
|
|
353
358
|
for (final op in changedSets) {
|
|
@@ -405,9 +410,12 @@ class _SupabaseDatabasePlugin implements AbstractDatabasePlugin {
|
|
|
405
410
|
if (patchRows.isNotEmpty) {
|
|
406
411
|
final patchUpsert = await supabase
|
|
407
412
|
.from('bundle_patches')
|
|
408
|
-
.upsert(
|
|
409
|
-
|
|
410
|
-
|
|
413
|
+
.upsert(
|
|
414
|
+
patchRows.map((p) => p.toJson()).toList(),
|
|
415
|
+
onConflict: 'id',
|
|
416
|
+
);
|
|
417
|
+
if (patchUpsert is SupabaseResponseLike &&
|
|
418
|
+
patchUpsert.error != null) {
|
|
411
419
|
throw createSupabaseError(patchUpsert.error!);
|
|
412
420
|
} else if (patchUpsert is Map && patchUpsert['error'] != null) {
|
|
413
421
|
throw createSupabaseError(patchUpsert['error']!);
|
|
@@ -6,6 +6,7 @@ import 'package:flutter_ota_kit_plugin_core/flutter_ota_kit_plugin_core.dart';
|
|
|
6
6
|
import 'supabase_client_adapter.dart';
|
|
7
7
|
import 'supabase_client_http.dart';
|
|
8
8
|
import 'supabase_signed_url_batcher.dart';
|
|
9
|
+
import 'error_message.dart' show errorMessage;
|
|
9
10
|
|
|
10
11
|
/// Config for the Supabase edge-function storage plugin.
|
|
11
12
|
class SupabaseEdgeFunctionStorageConfig {
|
|
@@ -31,26 +32,27 @@ ParsedStorageUri parseSupabaseEdgeStorageUri(String storageUri) =>
|
|
|
31
32
|
/// (no node profile) backed by the Supabase client.
|
|
32
33
|
final supabaseEdgeFunctionStorage =
|
|
33
34
|
createRuntimeStoragePlugin<SupabaseEdgeFunctionStorageConfig>(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
35
|
+
name: 'supabaseEdgeFunctionStorage',
|
|
36
|
+
supportedProtocol: 'supabase-storage',
|
|
37
|
+
factory: (config) {
|
|
38
|
+
final supabase = config.clientFactory(
|
|
39
|
+
config.supabaseUrl,
|
|
40
|
+
config.supabaseServiceRoleKey,
|
|
41
|
+
);
|
|
42
|
+
final resolveSignedUrl = createSupabaseSignedUrlBatcher(
|
|
43
|
+
createSignedUrls: (bucketName, keys, expiresIn) => supabase.storage
|
|
44
|
+
.from(bucketName)
|
|
45
|
+
.createSignedUrls(keys, expiresIn),
|
|
46
|
+
expiresIn: config.signedUrlExpiresIn ?? 3600,
|
|
47
|
+
formatObjectPath: (bucketName, key) => '$bucketName/$key',
|
|
48
|
+
);
|
|
47
49
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
return RuntimeStorageProfileImplEdge(
|
|
51
|
+
supabase: supabase,
|
|
52
|
+
resolveSignedUrl: resolveSignedUrl,
|
|
53
|
+
);
|
|
54
|
+
},
|
|
51
55
|
);
|
|
52
|
-
},
|
|
53
|
-
);
|
|
54
56
|
|
|
55
57
|
class RuntimeStorageProfileImplEdge implements RuntimeStorageProfile {
|
|
56
58
|
RuntimeStorageProfileImplEdge({
|
|
@@ -69,8 +71,7 @@ class RuntimeStorageProfileImplEdge implements RuntimeStorageProfile {
|
|
|
69
71
|
}
|
|
70
72
|
final res = await supabase.storage.from(parsed.bucket).download(parsed.key);
|
|
71
73
|
if (res.error != null) {
|
|
72
|
-
final msg = (res.message ??
|
|
73
|
-
.toString();
|
|
74
|
+
final msg = (res.message ?? errorMessage(res.error)).toString();
|
|
74
75
|
if (msg.contains('not found')) return null;
|
|
75
76
|
throw StateError('Failed to read storage text: $msg');
|
|
76
77
|
}
|
|
@@ -87,13 +88,4 @@ class RuntimeStorageProfileImplEdge implements RuntimeStorageProfile {
|
|
|
87
88
|
final signedUrl = await resolveSignedUrl(parsed.bucket, parsed.key);
|
|
88
89
|
return {'fileUrl': signedUrl};
|
|
89
90
|
}
|
|
90
|
-
|
|
91
|
-
String _errorToString(Object? error) {
|
|
92
|
-
if (error is Error) return error.toString();
|
|
93
|
-
if (error is Exception) return error.toString();
|
|
94
|
-
if (error is Map && error['message'] is String) {
|
|
95
|
-
return error['message'] as String;
|
|
96
|
-
}
|
|
97
|
-
return error.toString();
|
|
98
|
-
}
|
|
99
91
|
}
|
|
@@ -4,6 +4,7 @@ library;
|
|
|
4
4
|
import 'dart:async';
|
|
5
5
|
|
|
6
6
|
import 'supabase_client_adapter.dart';
|
|
7
|
+
import 'error_message.dart' show errorMessage;
|
|
7
8
|
|
|
8
9
|
/// A pending signed URL request waiting for the next flush.
|
|
9
10
|
class _PendingSignedUrl {
|
|
@@ -18,16 +19,6 @@ class _PendingSignedUrl {
|
|
|
18
19
|
});
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
/// Extract a human-readable message from an unknown error value.
|
|
22
|
-
String _getErrorMessage(Object? error) {
|
|
23
|
-
if (error is Error) return error.toString();
|
|
24
|
-
if (error is Exception) return error.toString();
|
|
25
|
-
if (error is Map && error['message'] is String) {
|
|
26
|
-
return error['message'] as String;
|
|
27
|
-
}
|
|
28
|
-
return error.toString();
|
|
29
|
-
}
|
|
30
|
-
|
|
31
22
|
/// Signature of the batch signed URL generator. Returns the same shape as the
|
|
32
23
|
/// Supabase storage `createSignedUrls` call: a list of results aligned to the
|
|
33
24
|
/// input key order.
|
|
@@ -53,14 +44,10 @@ ResolveSignedUrl createSupabaseSignedUrlBatcher({
|
|
|
53
44
|
var pendingByBucket = <String, List<_PendingSignedUrl>>{};
|
|
54
45
|
var flushScheduled = false;
|
|
55
46
|
|
|
56
|
-
Object createSignedUrlError(
|
|
57
|
-
String bucketName,
|
|
58
|
-
String key,
|
|
59
|
-
Object error,
|
|
60
|
-
) =>
|
|
47
|
+
Object createSignedUrlError(String bucketName, String key, Object error) =>
|
|
61
48
|
StateError(
|
|
62
49
|
'Failed to generate download URL for '
|
|
63
|
-
'"${formatObjectPath(bucketName, key)}": ${
|
|
50
|
+
'"${formatObjectPath(bucketName, key)}": ${errorMessage(error)}',
|
|
64
51
|
);
|
|
65
52
|
|
|
66
53
|
Future<void> flush() async {
|
|
@@ -109,7 +96,9 @@ ResolveSignedUrl createSupabaseSignedUrlBatcher({
|
|
|
109
96
|
}
|
|
110
97
|
} catch (error) {
|
|
111
98
|
for (final request in pending) {
|
|
112
|
-
request.reject(
|
|
99
|
+
request.reject(
|
|
100
|
+
createSignedUrlError(bucketName, request.key, error),
|
|
101
|
+
);
|
|
113
102
|
}
|
|
114
103
|
}
|
|
115
104
|
}),
|
|
@@ -118,8 +107,7 @@ ResolveSignedUrl createSupabaseSignedUrlBatcher({
|
|
|
118
107
|
|
|
119
108
|
return (String bucketName, String key) {
|
|
120
109
|
final completer = Completer<String>();
|
|
121
|
-
final pending =
|
|
122
|
-
pendingByBucket[bucketName] ?? <_PendingSignedUrl>[];
|
|
110
|
+
final pending = pendingByBucket[bucketName] ?? <_PendingSignedUrl>[];
|
|
123
111
|
pending.add(
|
|
124
112
|
_PendingSignedUrl(
|
|
125
113
|
key: key,
|
|
@@ -9,6 +9,7 @@ import 'supabase_client_adapter.dart';
|
|
|
9
9
|
import 'supabase_client_http.dart';
|
|
10
10
|
import 'supabase_config.dart';
|
|
11
11
|
import 'supabase_signed_url_batcher.dart';
|
|
12
|
+
import 'error_message.dart' show errorMessage;
|
|
12
13
|
|
|
13
14
|
/// Parse a `supabase-storage://` URI into bucket + key.
|
|
14
15
|
ParsedStorageUri parseSupabaseStorageUri(String storageUri) =>
|
|
@@ -31,15 +32,6 @@ class SupabaseStorageConfig extends SupabaseServiceRoleConfig {
|
|
|
31
32
|
});
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
String _getErrorMessage(Object? error) {
|
|
35
|
-
if (error is Error) return error.toString();
|
|
36
|
-
if (error is Exception) return error.toString();
|
|
37
|
-
if (error is Map && error['message'] is String) {
|
|
38
|
-
return error['message'] as String;
|
|
39
|
-
}
|
|
40
|
-
return error.toString();
|
|
41
|
-
}
|
|
42
|
-
|
|
43
35
|
Future<String> _createSignedUrlOrThrow({
|
|
44
36
|
required SupabaseStorageBucketLike bucket,
|
|
45
37
|
required String key,
|
|
@@ -61,7 +53,7 @@ Future<String> _createSignedUrlOrThrow({
|
|
|
61
53
|
|
|
62
54
|
throw StateError(
|
|
63
55
|
'Failed to generate download URL for "$key": '
|
|
64
|
-
'${
|
|
56
|
+
'${errorMessage(error ?? StateError("missing signed URL"))}',
|
|
65
57
|
);
|
|
66
58
|
}
|
|
67
59
|
|
|
@@ -69,11 +61,7 @@ Future<void> _verifyObjectCanBeSignedForRuntime({
|
|
|
69
61
|
required SupabaseStorageBucketLike bucket,
|
|
70
62
|
required String key,
|
|
71
63
|
}) async {
|
|
72
|
-
await _createSignedUrlOrThrow(
|
|
73
|
-
bucket: bucket,
|
|
74
|
-
key: key,
|
|
75
|
-
expiresIn: 3600,
|
|
76
|
-
);
|
|
64
|
+
await _createSignedUrlOrThrow(bucket: bucket, key: key, expiresIn: 3600);
|
|
77
65
|
}
|
|
78
66
|
|
|
79
67
|
/// Supabase-backed universal (node + runtime) storage plugin.
|
|
@@ -126,12 +114,14 @@ class NodeStorageProfileImpl implements NodeStorageProfile {
|
|
|
126
114
|
final Future<void> Function({
|
|
127
115
|
required SupabaseStorageBucketLike bucket,
|
|
128
116
|
required String key,
|
|
129
|
-
})
|
|
117
|
+
})
|
|
118
|
+
verifySigned;
|
|
130
119
|
final Future<String> Function({
|
|
131
120
|
required SupabaseStorageBucketLike bucket,
|
|
132
121
|
required String key,
|
|
133
122
|
required int expiresIn,
|
|
134
|
-
})
|
|
123
|
+
})
|
|
124
|
+
createSignedUrlOrThrow;
|
|
135
125
|
|
|
136
126
|
@override
|
|
137
127
|
Future<Map<String, String>> upload(String key, String filePath) async {
|
|
@@ -147,13 +137,11 @@ class NodeStorageProfileImpl implements NodeStorageProfile {
|
|
|
147
137
|
cacheControl: 'max-age=31536000',
|
|
148
138
|
);
|
|
149
139
|
if (upload.error != null) {
|
|
150
|
-
throw StateError(
|
|
140
|
+
throw StateError(errorMessage(upload.error));
|
|
151
141
|
}
|
|
152
142
|
|
|
153
143
|
await verifySigned(bucket: bucket, key: storageKey);
|
|
154
|
-
return {
|
|
155
|
-
'storageUri': 'supabase-storage://$bucketName/$storageKey',
|
|
156
|
-
};
|
|
144
|
+
return {'storageUri': 'supabase-storage://$bucketName/$storageKey'};
|
|
157
145
|
}
|
|
158
146
|
|
|
159
147
|
@override
|
|
@@ -168,7 +156,7 @@ class NodeStorageProfileImpl implements NodeStorageProfile {
|
|
|
168
156
|
final res = await bucket.exists(parsed.key);
|
|
169
157
|
if (res.data == false) return false;
|
|
170
158
|
if (res.error != null) {
|
|
171
|
-
throw StateError(
|
|
159
|
+
throw StateError(errorMessage(res.error));
|
|
172
160
|
}
|
|
173
161
|
await verifySigned(bucket: bucket, key: parsed.key);
|
|
174
162
|
return res.data as bool;
|
|
@@ -185,7 +173,7 @@ class NodeStorageProfileImpl implements NodeStorageProfile {
|
|
|
185
173
|
}
|
|
186
174
|
final res = await bucket.remove([parsed.key]);
|
|
187
175
|
if (res.error != null) {
|
|
188
|
-
final msg = res.message ??
|
|
176
|
+
final msg = res.message ?? errorMessage(res.error);
|
|
189
177
|
if (msg.contains('not found')) {
|
|
190
178
|
throw StateError('Bundle not found');
|
|
191
179
|
}
|
|
@@ -209,7 +197,10 @@ class NodeStorageProfileImpl implements NodeStorageProfile {
|
|
|
209
197
|
if (res.data == null) {
|
|
210
198
|
throw StateError('Failed to download bundle');
|
|
211
199
|
}
|
|
212
|
-
final dir = filePath.substring(
|
|
200
|
+
final dir = filePath.substring(
|
|
201
|
+
0,
|
|
202
|
+
filePath.lastIndexOf(io.Platform.pathSeparator),
|
|
203
|
+
);
|
|
213
204
|
await io.Directory(dir).create(recursive: true);
|
|
214
205
|
await io.File(filePath).writeAsBytes(res.data!);
|
|
215
206
|
}
|
|
@@ -218,9 +209,7 @@ class NodeStorageProfileImpl implements NodeStorageProfile {
|
|
|
218
209
|
Future<List<StorageObject>> listObjects([String? prefix]) async {
|
|
219
210
|
final res = await bucket.list(prefix);
|
|
220
211
|
if (res.error != null) {
|
|
221
|
-
throw StateError(
|
|
222
|
-
'Failed to list objects: ${_getErrorMessage(res.error)}',
|
|
223
|
-
);
|
|
212
|
+
throw StateError('Failed to list objects: ${errorMessage(res.error)}');
|
|
224
213
|
}
|
|
225
214
|
final data = res.data ?? const <SupabaseStorageObject>[];
|
|
226
215
|
return data
|
|
@@ -242,7 +231,7 @@ class NodeStorageProfileImpl implements NodeStorageProfile {
|
|
|
242
231
|
if (keys.isEmpty) return;
|
|
243
232
|
final res = await bucket.remove(keys);
|
|
244
233
|
if (res.error != null) {
|
|
245
|
-
final msg = res.message ??
|
|
234
|
+
final msg = res.message ?? errorMessage(res.error);
|
|
246
235
|
if (!msg.contains('not found')) {
|
|
247
236
|
throw StateError('Failed to delete objects: $msg');
|
|
248
237
|
}
|
|
@@ -272,7 +261,7 @@ class RuntimeStorageProfileImpl implements RuntimeStorageProfile {
|
|
|
272
261
|
}
|
|
273
262
|
final res = await bucket.download(parsed.key);
|
|
274
263
|
if (res.error != null) {
|
|
275
|
-
final msg = res.message ??
|
|
264
|
+
final msg = res.message ?? errorMessage(res.error);
|
|
276
265
|
if (msg.contains('not found')) return null;
|
|
277
266
|
throw StateError('Failed to read storage text: $msg');
|
|
278
267
|
}
|
|
@@ -67,24 +67,24 @@ class SupabaseBundleRow {
|
|
|
67
67
|
);
|
|
68
68
|
|
|
69
69
|
Map<String, dynamic> toJson() => {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
70
|
+
'id': id,
|
|
71
|
+
'channel': channel,
|
|
72
|
+
'enabled': enabled,
|
|
73
|
+
'should_force_update': shouldForceUpdate,
|
|
74
|
+
'file_hash': fileHash,
|
|
75
|
+
'git_commit_hash': gitCommitHash,
|
|
76
|
+
'message': message,
|
|
77
|
+
'platform': platform,
|
|
78
|
+
'target_app_version': targetAppVersion,
|
|
79
|
+
'fingerprint_hash': fingerprintHash,
|
|
80
|
+
'storage_uri': storageUri,
|
|
81
|
+
'metadata': metadata,
|
|
82
|
+
'manifest_storage_uri': manifestStorageUri,
|
|
83
|
+
'manifest_file_hash': manifestFileHash,
|
|
84
|
+
'asset_base_storage_uri': assetBaseStorageUri,
|
|
85
|
+
'rollout_cohort_count': rolloutCohortCount,
|
|
86
|
+
'target_cohorts': targetCohorts,
|
|
87
|
+
};
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
/// Row type from Supabase `bundle_patches` table.
|
|
@@ -119,12 +119,12 @@ class SupabaseBundlePatchRow {
|
|
|
119
119
|
);
|
|
120
120
|
|
|
121
121
|
Map<String, dynamic> toJson() => {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
122
|
+
'id': id,
|
|
123
|
+
'bundle_id': bundleId,
|
|
124
|
+
'base_bundle_id': baseBundleId,
|
|
125
|
+
'base_file_hash': baseFileHash,
|
|
126
|
+
'patch_file_hash': patchFileHash,
|
|
127
|
+
'patch_storage_uri': patchStorageUri,
|
|
128
|
+
'order_index': orderIndex,
|
|
129
|
+
};
|
|
130
130
|
}
|
|
@@ -1,22 +1,27 @@
|
|
|
1
1
|
name: flutter_ota_kit_supabase
|
|
2
2
|
description: Supabase plugin for flutter_ota_kit — database + storage backends.
|
|
3
|
-
version: 0.1.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
documentation: https://github.com/HYPER12755/flutter_ota_kit#readme
|
|
3
|
+
version: 0.1.3
|
|
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.
|
|
11
|
+
sdk: ">=3.13.2 <4.0.0"
|
|
13
12
|
|
|
14
13
|
dependencies:
|
|
15
|
-
flutter_ota_kit_core: ^0.1.
|
|
16
|
-
flutter_ota_kit_plugin_core: ^0.0.
|
|
14
|
+
flutter_ota_kit_core: ^0.1.1
|
|
15
|
+
flutter_ota_kit_plugin_core: ^0.0.3
|
|
17
16
|
http: ^1.2.0
|
|
18
17
|
supabase: ^2.14.0
|
|
19
18
|
|
|
20
19
|
dev_dependencies:
|
|
21
20
|
test: ^1.25.0
|
|
22
21
|
lints: ^4.0.0
|
|
22
|
+
|
|
23
|
+
dependency_overrides:
|
|
24
|
+
flutter_ota_kit_core:
|
|
25
|
+
path: ../../packages/core
|
|
26
|
+
flutter_ota_kit_plugin_core:
|
|
27
|
+
path: ../plugin-core
|