@_nazmiforreal/flutter-ota 0.1.19 → 0.1.21

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 (59) hide show
  1. package/dart-src/packages/cli-tools/lib/flutter_ota_kit_cli.dart +4 -3
  2. package/dart-src/packages/cli-tools/lib/src/cli_base.dart +3 -2
  3. package/dart-src/packages/cli-tools/lib/src/commands/bundle.dart +22 -10
  4. package/dart-src/packages/cli-tools/lib/src/commands/channel.dart +16 -5
  5. package/dart-src/packages/cli-tools/lib/src/commands/config_command.dart +3 -0
  6. package/dart-src/packages/cli-tools/lib/src/commands/console.dart +7 -8
  7. package/dart-src/packages/cli-tools/lib/src/commands/deploy.dart +12 -3
  8. package/dart-src/packages/cli-tools/lib/src/commands/doctor.dart +129 -6
  9. package/dart-src/packages/cli-tools/lib/src/commands/fingerprint.dart +2 -1
  10. package/dart-src/packages/cli-tools/lib/src/commands/init.dart +23 -14
  11. package/dart-src/packages/cli-tools/lib/src/commands/keys.dart +4 -0
  12. package/dart-src/packages/cli-tools/lib/src/commands/migrate.dart +266 -26
  13. package/dart-src/packages/cli-tools/lib/src/commands/pocketbase.dart +1422 -16
  14. package/dart-src/packages/cli-tools/lib/src/commands/rollback.dart +4 -1
  15. package/dart-src/packages/cli-tools/lib/src/commands/storage.dart +10 -9
  16. package/dart-src/packages/cli-tools/lib/src/config.dart +14 -19
  17. package/dart-src/packages/cli-tools/lib/src/operations.dart +1 -1
  18. package/dart-src/packages/cli-tools/lib/src/pocketbase/installer.dart +1 -1
  19. package/dart-src/packages/cli-tools/lib/src/pocketbase/process_manager.dart +113 -10
  20. package/dart-src/packages/cli-tools/lib/src/pocketbase/schema_installer.dart +59 -6
  21. package/dart-src/packages/cli-tools/lib/src/ui/ui.dart +2 -2
  22. package/dart-src/packages/cli-tools/test/mocks/mock_pocketbase_client.dart +149 -0
  23. package/dart-src/packages/cli-tools/test/pocketbase_schema_test.dart +14 -9
  24. package/dart-src/packages/core/CHANGELOG.md +6 -1
  25. package/dart-src/packages/core/lib/flutter_ota_kit_core.dart +2 -0
  26. package/dart-src/packages/core/lib/src/app_update_info.dart +73 -1
  27. package/dart-src/packages/core/lib/src/bundle.dart +62 -17
  28. package/dart-src/packages/core/lib/src/bundle_artifacts.dart +7 -3
  29. package/dart-src/packages/core/lib/src/bundle_patch_artifact.dart +16 -0
  30. package/dart-src/packages/core/lib/src/changed_asset.dart +33 -3
  31. package/dart-src/packages/core/lib/src/get_bundles_args.dart +24 -2
  32. package/dart-src/packages/core/lib/src/platform.dart +8 -0
  33. package/dart-src/packages/core/lib/src/semver.dart +0 -3
  34. package/dart-src/packages/core/lib/src/status.dart +20 -1
  35. package/dart-src/packages/core/lib/src/strategy.dart +10 -0
  36. package/dart-src/packages/core/lib/src/update_bundle_params.dart +15 -0
  37. package/dart-src/packages/core/lib/src/uuid.dart +11 -0
  38. package/dart-src/plugins/aws/CHANGELOG.md +5 -1
  39. package/dart-src/plugins/aws/lib/src/aws_cloudfront_client.dart +2 -2
  40. package/dart-src/plugins/cloudflare/CHANGELOG.md +5 -1
  41. package/dart-src/plugins/plugin-core/CHANGELOG.md +5 -1
  42. package/dart-src/plugins/plugin-core/lib/src/asset_storage_layout.dart +3 -0
  43. package/dart-src/plugins/plugin-core/lib/src/parse_storage_uri.dart +17 -0
  44. package/dart-src/plugins/plugin-core/lib/src/types.dart +94 -3
  45. package/dart-src/plugins/pocketbase/CHANGELOG.md +5 -1
  46. package/dart-src/plugins/pocketbase/lib/flutter_ota_kit_pocketbase.dart +2 -1
  47. package/dart-src/plugins/pocketbase/lib/src/pocketbase_bundle_mapper.dart +10 -2
  48. package/dart-src/plugins/pocketbase/lib/src/pocketbase_client.dart +617 -4
  49. package/dart-src/plugins/pocketbase/lib/src/pocketbase_database.dart +262 -42
  50. package/dart-src/plugins/pocketbase/lib/src/pocketbase_storage.dart +9 -2
  51. package/dart-src/plugins/postgres/CHANGELOG.md +5 -1
  52. package/dart-src/plugins/supabase/CHANGELOG.md +6 -1
  53. package/dart-src/plugins/supabase/lib/src/supabase_database.dart +4 -0
  54. package/package.json +2 -2
  55. package/bin/flutter-ota-linux-x64 +0 -0
  56. package/bin/flutter-ota.js +0 -36
  57. package/dart-src/packages/cli-tools/.dart_tool/package_config.json +0 -458
  58. package/dart-src/packages/cli-tools/.dart_tool/package_graph.json +0 -707
  59. package/dart-src/packages/cli-tools/pubspec.lock +0 -590
@@ -1,4 +1,8 @@
1
1
  /// PocketBase-backed [DatabasePlugin] implementation.
2
+ ///
3
+ /// Implements full parity with the Cloudflare/Supabase backends including
4
+ /// proper `getUpdateInfo` with `UpdateStrategy` branching, `bundle_patches`
5
+ /// support, and comprehensive filter operators.
2
6
  library;
3
7
 
4
8
  import 'package:flutter_ota_kit_core/flutter_ota_kit_core.dart';
@@ -33,20 +37,69 @@ class _PocketBaseDatabase implements AbstractDatabasePlugin {
33
37
  @override
34
38
  bool get supportsCursorPagination => false;
35
39
 
40
+ // ----- Bundle patches -----
41
+
42
+ String get _patchesCollection => '${config.bundlesCollection}_patches';
43
+
44
+ Future<Map<String, List<Map<String, dynamic>>>> _getPatchMap(
45
+ List<String> bundleIds,
46
+ ) async {
47
+ final patchMap = <String, List<Map<String, dynamic>>>{};
48
+ if (bundleIds.isEmpty) return patchMap;
49
+
50
+ final filter = bundleIds
51
+ .map((id) => 'bundle_id = "${_escape(id)}"')
52
+ .join(' || ');
53
+ try {
54
+ final res = await client.listRecords<dynamic>(
55
+ _patchesCollection,
56
+ (j) => j,
57
+ filter: filter.isEmpty ? null : filter,
58
+ sort: 'order_index',
59
+ perPage: 500,
60
+ );
61
+ for (final item in res.items) {
62
+ final row = item as Map<String, dynamic>;
63
+ final bundleId = row['bundle_id'] as String? ?? '';
64
+ if (bundleId.isNotEmpty) {
65
+ (patchMap[bundleId] ??= []).add(row);
66
+ }
67
+ }
68
+ } catch (_) {
69
+ // patches collection may not exist yet; treat as no patches.
70
+ }
71
+ return patchMap;
72
+ }
73
+
36
74
  // ----- Channels -----
37
75
 
38
76
  @override
39
77
  Future<List<String>> getChannels() async {
40
- final res = await client.listRecords<dynamic>(
41
- config.channelsCollection,
42
- (j) => j,
43
- perPage: 200,
44
- sort: 'name',
45
- );
46
- return res.items
47
- .map((j) => (j as Map)['name'] as String? ?? '')
48
- .where((s) => s.isNotEmpty)
49
- .toList();
78
+ try {
79
+ final res = await client.listRecords<dynamic>(
80
+ config.channelsCollection,
81
+ (j) => j,
82
+ perPage: 200,
83
+ sort: 'name',
84
+ );
85
+ return res.items
86
+ .map((j) => (j as Map)['name'] as String? ?? '')
87
+ .where((s) => s.isNotEmpty)
88
+ .toList();
89
+ } catch (_) {
90
+ // Fallback: extract distinct channels from bundles.
91
+ final res = await client.listRecords<PocketBaseBundleRow>(
92
+ config.bundlesCollection,
93
+ PocketBaseBundleRow.fromJson,
94
+ perPage: 500,
95
+ sort: '-created',
96
+ );
97
+ final channels = <String>{};
98
+ for (final b in res.items) {
99
+ if (b.channel.isNotEmpty) channels.add(b.channel);
100
+ }
101
+ return channels.toList()..sort();
102
+ }
50
103
  }
51
104
 
52
105
  // ----- Single bundle -----
@@ -58,32 +111,134 @@ class _PocketBaseDatabase implements AbstractDatabasePlugin {
58
111
  bundleId,
59
112
  PocketBaseBundleRow.fromJson,
60
113
  );
61
- return row == null ? null : mapRowToBundle(row);
114
+ if (row == null) return null;
115
+ final patchMap = await _getPatchMap([bundleId]);
116
+ return mapRowToBundle(row, patches: patchMap[bundleId]);
62
117
  }
63
118
 
119
+ // ----- Update info -----
120
+
64
121
  @override
65
122
  Future<UpdateInfo?> getUpdateInfo(GetBundlesArgs args) async {
123
+ final channel = args.channel;
124
+ final minBundleId = args.minBundleId;
125
+ final platform = args.platform.value;
126
+
127
+ if (args.updateStrategy == UpdateStrategy.appVersion) {
128
+ final appVersion = (args as AppVersionGetBundlesArgs).appVersion;
129
+
130
+ // 1. Collect distinct target_app_versions from enabled bundles.
131
+ final allRes = await client.listRecords<PocketBaseBundleRow>(
132
+ config.bundlesCollection,
133
+ PocketBaseBundleRow.fromJson,
134
+ filter: _buildFilter(
135
+ channel: channel,
136
+ platformValue: platform,
137
+ enabled: true,
138
+ idGte: minBundleId,
139
+ targetAppVersionNotNull: true,
140
+ ),
141
+ sort: '-created',
142
+ perPage: 500,
143
+ );
144
+ final targetVersions = allRes.items
145
+ .map((b) => b.targetAppVersion)
146
+ .whereType<String>()
147
+ .toSet()
148
+ .toList();
149
+
150
+ // 2. Filter to compatible versions.
151
+ final compatible = filterCompatibleAppVersions(
152
+ targetVersions,
153
+ appVersion,
154
+ );
155
+
156
+ if (compatible.isEmpty) {
157
+ // No compatible bundles — check if we should rollback.
158
+ if (args.bundleId == nilUuid ||
159
+ (minBundleId.isNotEmpty &&
160
+ args.bundleId.compareTo(minBundleId) <= 0)) {
161
+ return null;
162
+ }
163
+ return const UpdateInfo(
164
+ id: nilUuid,
165
+ shouldForceUpdate: true,
166
+ message: null,
167
+ status: UpdateStatus.rollback,
168
+ storageUri: null,
169
+ fileHash: null,
170
+ );
171
+ }
172
+
173
+ // 3. Query bundles with compatible target_app_version using ?= operator.
174
+ final filter = _buildFilter(
175
+ channel: channel,
176
+ platformValue: platform,
177
+ enabled: true,
178
+ idGte: minBundleId,
179
+ targetAppVersionIn: compatible,
180
+ );
181
+ final res = await client.listRecords<PocketBaseBundleRow>(
182
+ config.bundlesCollection,
183
+ PocketBaseBundleRow.fromJson,
184
+ filter: filter.isEmpty ? null : filter,
185
+ sort: '-created',
186
+ perPage: 500,
187
+ );
188
+ final bundles = res.items.map(mapRowToBundle).toList();
189
+ final patchMap = await _getPatchMap(bundles.map((b) => b.id).toList());
190
+ final bundlesWithPatches = bundles
191
+ .map(
192
+ (b) => mapRowToBundle(
193
+ res.items.firstWhere((r) => r.id == b.id),
194
+ patches: patchMap[b.id],
195
+ ),
196
+ )
197
+ .toList();
198
+
199
+ return resolveUpdateInfoFromBundles(
200
+ ResolveUpdateInfoFromBundlesOptions(
201
+ args: args,
202
+ bundles: bundlesWithPatches,
203
+ ),
204
+ );
205
+ }
206
+
207
+ // Fingerprint strategy.
208
+ final fingerprintHash = args is FingerprintGetBundlesArgs
209
+ ? args.fingerprintHash
210
+ : null;
211
+
66
212
  final filter = _buildFilter(
67
- channel: args.channel,
68
- platform: args.platform,
213
+ channel: channel,
214
+ platformValue: platform,
69
215
  enabled: true,
216
+ idGte: minBundleId,
217
+ fingerprintHash: fingerprintHash,
70
218
  );
71
- final list = await client.listRecords<PocketBaseBundleRow>(
219
+ final res = await client.listRecords<PocketBaseBundleRow>(
72
220
  config.bundlesCollection,
73
221
  PocketBaseBundleRow.fromJson,
74
222
  filter: filter.isEmpty ? null : filter,
75
223
  sort: '-created',
76
- perPage: 1,
224
+ perPage: 500,
77
225
  );
78
- if (list.items.isEmpty) return null;
79
- final bundle = mapRowToBundle(list.items.first);
80
- return UpdateInfo(
81
- id: bundle.id,
82
- shouldForceUpdate: bundle.shouldForceUpdate,
83
- message: bundle.message,
84
- status: UpdateStatus.update,
85
- storageUri: bundle.storageUri,
86
- fileHash: bundle.fileHash,
226
+ final bundles = res.items.map(mapRowToBundle).toList();
227
+ final patchMap = await _getPatchMap(bundles.map((b) => b.id).toList());
228
+ final bundlesWithPatches = bundles
229
+ .map(
230
+ (b) => mapRowToBundle(
231
+ res.items.firstWhere((r) => r.id == b.id),
232
+ patches: patchMap[b.id],
233
+ ),
234
+ )
235
+ .toList();
236
+
237
+ return resolveUpdateInfoFromBundles(
238
+ ResolveUpdateInfoFromBundlesOptions(
239
+ args: args,
240
+ bundles: bundlesWithPatches,
241
+ ),
87
242
  );
88
243
  }
89
244
 
@@ -96,17 +251,18 @@ class _PocketBaseDatabase implements AbstractDatabasePlugin {
96
251
  final where = options.where;
97
252
  final filter = _buildFilter(
98
253
  channel: where?.channel,
99
- platform: where?.platform,
254
+ platformValue: where?.platform?.value,
100
255
  enabled: where?.enabled,
101
256
  idEq: where?.id?.eq,
102
257
  idGt: where?.id?.gt,
103
258
  idLt: where?.id?.lt,
104
259
  targetAppVersion: where?.targetAppVersion,
260
+ targetAppVersionIn: where?.targetAppVersionIn,
261
+ targetAppVersionNotNull: where?.targetAppVersionNotNull,
105
262
  fingerprintHash: where?.fingerprintHash,
106
263
  );
107
264
  final orderField = options.orderBy?.field ?? 'id';
108
265
  final desc = options.orderBy?.direction != 'asc';
109
- // PB sort syntax: `field` for asc, `-field` for desc.
110
266
  final sort = (desc ? '-' : '') + orderField;
111
267
  final limit = options.limit == 0 ? 50 : options.limit;
112
268
  final page = (options.offset ?? 0) ~/ limit + 1;
@@ -118,13 +274,16 @@ class _PocketBaseDatabase implements AbstractDatabasePlugin {
118
274
  page: page,
119
275
  perPage: limit,
120
276
  );
277
+ final patchMap = await _getPatchMap(list.items.map((b) => b.id).toList());
121
278
  final total = list.totalItems;
122
279
  final totalPages = list.totalPages == 0 ? 1 : list.totalPages;
123
280
  final currentPage = list.page;
124
281
  final hasNextPage = currentPage < totalPages;
125
282
  final hasPreviousPage = currentPage > 1;
126
283
  return Paginated(
127
- data: list.items.map(mapRowToBundle).toList(),
284
+ data: list.items
285
+ .map((row) => mapRowToBundle(row, patches: patchMap[row.id]))
286
+ .toList(),
128
287
  pagination: PaginationInfo(
129
288
  total: total,
130
289
  hasNextPage: hasNextPage,
@@ -154,9 +313,6 @@ class _PocketBaseDatabase implements AbstractDatabasePlugin {
154
313
  change.data.id,
155
314
  );
156
315
  if (exists) {
157
- // The storage plugin may have pre-created the record (to host
158
- // the artifact file). Update the metadata fields rather than
159
- // failing on a duplicate id.
160
316
  await client.updateRecord<dynamic>(
161
317
  config.bundlesCollection,
162
318
  change.data.id,
@@ -170,24 +326,66 @@ class _PocketBaseDatabase implements AbstractDatabasePlugin {
170
326
  (j) => j,
171
327
  );
172
328
  }
173
- break;
329
+ // Upsert patches.
330
+ await _commitPatches(change.data);
331
+
174
332
  case BundleChangeOperation.update:
175
333
  final patch = _buildUpdatePatch(change.data);
176
- if (patch.isEmpty) continue;
177
- await client.updateRecord<dynamic>(
178
- config.bundlesCollection,
179
- change.data.id,
180
- patch,
181
- (j) => j,
182
- );
183
- break;
334
+ if (patch.isNotEmpty) {
335
+ await client.updateRecord<dynamic>(
336
+ config.bundlesCollection,
337
+ change.data.id,
338
+ patch,
339
+ (j) => j,
340
+ );
341
+ }
342
+ await _commitPatches(change.data);
343
+
184
344
  case BundleChangeOperation.delete:
345
+ // Delete associated patches first.
346
+ await _deletePatches(change.data.id);
185
347
  await client.deleteRecord(config.bundlesCollection, change.data.id);
186
- break;
187
348
  }
188
349
  }
189
350
  }
190
351
 
352
+ Future<void> _commitPatches(Bundle bundle) async {
353
+ final patches = bundle.patches;
354
+ if (patches == null || patches.isEmpty) return;
355
+ // Delete existing patches for this bundle, then re-create.
356
+ await _deletePatches(bundle.id);
357
+ for (var i = 0; i < patches.length; i++) {
358
+ final p = patches[i];
359
+ await client.createRecord<dynamic>(_patchesCollection, {
360
+ 'bundle_id': bundle.id,
361
+ 'base_bundle_id': p.baseBundleId,
362
+ 'base_file_hash': p.baseFileHash,
363
+ 'patch_file_hash': p.patchFileHash,
364
+ 'patch_storage_uri': p.patchStorageUri,
365
+ 'order_index': i,
366
+ }, (j) => j);
367
+ }
368
+ }
369
+
370
+ Future<void> _deletePatches(String bundleId) async {
371
+ try {
372
+ final res = await client.listRecords<dynamic>(
373
+ _patchesCollection,
374
+ (j) => j,
375
+ filter: 'bundle_id = "${_escape(bundleId)}"',
376
+ perPage: 500,
377
+ );
378
+ for (final item in res.items) {
379
+ final id = (item as Map)['id'] as String?;
380
+ if (id != null) {
381
+ await client.deleteRecord(_patchesCollection, id);
382
+ }
383
+ }
384
+ } catch (_) {
385
+ // patches collection may not exist; ignore.
386
+ }
387
+ }
388
+
191
389
  @override
192
390
  Future<void> onUnmount() async {
193
391
  client.close();
@@ -217,30 +415,52 @@ class _PocketBaseDatabase implements AbstractDatabasePlugin {
217
415
 
218
416
  String _buildFilter({
219
417
  String? channel,
418
+ String? platformValue,
220
419
  Platform? platform,
221
420
  bool? enabled,
222
421
  String? idEq,
223
422
  String? idGt,
423
+ String? idGte,
224
424
  String? idLt,
425
+ String? idLte,
426
+ List<String>? idIns,
225
427
  String? targetAppVersion,
428
+ List<String>? targetAppVersionIn,
429
+ bool? targetAppVersionNotNull,
226
430
  String? fingerprintHash,
227
431
  }) {
228
432
  final clauses = <String>[];
229
433
  if (channel != null && channel.isNotEmpty) {
230
434
  clauses.add('channel = "${_escape(channel)}"');
231
435
  }
232
- if (platform != null) {
233
- clauses.add('platform = "${_escape(platform.value)}"');
436
+ final pv = platformValue ?? platform?.value;
437
+ if (pv != null) {
438
+ clauses.add('platform = "${_escape(pv)}"');
234
439
  }
235
440
  if (enabled != null) {
236
441
  clauses.add('enabled = ${enabled ? 'true' : 'false'}');
237
442
  }
238
443
  if (idEq != null) clauses.add('id = "${_escape(idEq)}"');
239
444
  if (idGt != null) clauses.add('id > "${_escape(idGt)}"');
445
+ if (idGte != null) clauses.add('id >= "${_escape(idGte)}"');
240
446
  if (idLt != null) clauses.add('id < "${_escape(idLt)}"');
447
+ if (idLte != null) clauses.add('id <= "${_escape(idLte)}"');
448
+ if (idIns != null && idIns.isNotEmpty) {
449
+ final escaped = idIns.map((id) => '"${_escape(id)}"').join(',');
450
+ clauses.add('id ?= [$escaped]');
451
+ }
241
452
  if (targetAppVersion != null) {
242
453
  clauses.add('target_app_version = "${_escape(targetAppVersion)}"');
243
454
  }
455
+ if (targetAppVersionIn != null && targetAppVersionIn.isNotEmpty) {
456
+ final escaped = targetAppVersionIn
457
+ .map((v) => '"${_escape(v)}"')
458
+ .join(',');
459
+ clauses.add('target_app_version ?= [$escaped]');
460
+ }
461
+ if (targetAppVersionNotNull == true) {
462
+ clauses.add('target_app_version != ""');
463
+ }
244
464
  if (fingerprintHash != null) {
245
465
  clauses.add('fingerprint_hash = "${_escape(fingerprintHash)}"');
246
466
  }
@@ -109,8 +109,15 @@ class _PocketBaseRuntimeStorage implements RuntimeStorageProfile {
109
109
 
110
110
  @override
111
111
  Future<String?> readText(String storageUri) async {
112
- // PB serves binary files only; text reads aren't supported.
113
- return null;
112
+ try {
113
+ final urlData = await getDownloadUrl(storageUri);
114
+ final url = urlData['fileUrl'];
115
+ if (url == null || url.isEmpty) return null;
116
+ final bytes = await _client.downloadFile(url);
117
+ return String.fromCharCodes(bytes);
118
+ } catch (_) {
119
+ return null;
120
+ }
114
121
  }
115
122
  }
116
123
 
@@ -1 +1,5 @@
1
- ## 0.1.5
1
+ ## 0.1.7
2
+
3
+ - General maintenance.
4
+
5
+ ## 0.1.6
@@ -1 +1,6 @@
1
- ## 0.1.6
1
+ ## 0.1.8
2
+
3
+ - Updated `mapUpdateInfoRow` to pass `gitCommitHash` from bundle data.
4
+ - General maintenance.
5
+
6
+ ## 0.1.7
@@ -23,6 +23,7 @@ class _SupabaseUpdateInfoRow {
23
23
  final String status;
24
24
  final String? storageUri;
25
25
  final String? fileHash;
26
+ final String? gitCommitHash;
26
27
 
27
28
  const _SupabaseUpdateInfoRow({
28
29
  required this.id,
@@ -31,6 +32,7 @@ class _SupabaseUpdateInfoRow {
31
32
  required this.status,
32
33
  required this.storageUri,
33
34
  required this.fileHash,
35
+ this.gitCommitHash,
34
36
  });
35
37
  }
36
38
 
@@ -65,6 +67,7 @@ UpdateInfo mapUpdateInfoRow(_SupabaseUpdateInfoRow row) => UpdateInfo(
65
67
  : UpdateStatus.update,
66
68
  storageUri: row.storageUri,
67
69
  fileHash: row.fileHash,
70
+ gitCommitHash: row.gitCommitHash,
68
71
  );
69
72
 
70
73
  /// Supabase-backed [DatabasePlugin] factory.
@@ -213,6 +216,7 @@ class _SupabaseDatabasePlugin implements AbstractDatabasePlugin {
213
216
  status: row['status'] as String,
214
217
  storageUri: row['storage_uri'] as String?,
215
218
  fileHash: row['file_hash'] as String?,
219
+ gitCommitHash: row['git_commit_hash'] as String?,
216
220
  );
217
221
  }
218
222
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@_nazmiforreal/flutter-ota",
3
- "version": "0.1.19",
4
- "description": "Command-line interface for flutter_ota_kit \u2014 an OTA code-push tool for Flutter, hot-updater compatible.",
3
+ "version": "0.1.21",
4
+ "description": "Command-line interface for flutter_ota_kit an OTA code-push tool for Flutter, hot-updater compatible.",
5
5
  "bin": {
6
6
  "flutter-ota": "./bin/flutter-ota.js"
7
7
  },
Binary file
@@ -1,36 +0,0 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
-
4
- const { execFileSync } = require('child_process');
5
- const path = require('path');
6
- const os = require('os');
7
-
8
- const platform = os.platform();
9
- const arch = os.arch();
10
-
11
- const binaryNames = {
12
- 'linux-x64': 'flutter-ota-linux-x64',
13
- 'linux-arm64': 'flutter-ota-linux-arm64',
14
- 'darwin-x64': 'flutter-ota-darwin-x64',
15
- 'darwin-arm64': 'flutter-ota-darwin-arm64',
16
- 'win32-x64': 'flutter-ota-win32-x64.exe',
17
- };
18
-
19
- const key = `${platform}-${arch}`;
20
- const binName = binaryNames[key];
21
-
22
- if (!binName) {
23
- console.error(`flutter-ota: unsupported platform ${platform}-${arch}`);
24
- process.exit(1);
25
- }
26
-
27
- const binPath = path.join(__dirname, binName);
28
-
29
- try {
30
- execFileSync(binPath, process.argv.slice(2), { stdio: 'inherit' });
31
- } catch (err) {
32
- if (err.status !== undefined) {
33
- process.exit(err.status);
34
- }
35
- throw err;
36
- }