@_nazmiforreal/flutter-ota 0.1.28 → 0.1.30

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 (27) hide show
  1. package/bin/flutter-ota-linux-x64 +0 -0
  2. package/bin/flutter-ota.js +0 -0
  3. package/dart-src/packages/cli-tools/.dart_tool/package_config.json +496 -0
  4. package/dart-src/packages/cli-tools/.dart_tool/package_graph.json +754 -0
  5. package/dart-src/packages/cli-tools/.dart_tool/version +1 -0
  6. package/dart-src/packages/cli-tools/lib/src/commands/doctor.dart +22 -1
  7. package/dart-src/packages/cli-tools/lib/src/commands/init.dart +17 -8
  8. package/dart-src/packages/cli-tools/pubspec.lock +636 -0
  9. package/dart-src/packages/cli-tools/pubspec.yaml +7 -7
  10. package/dart-src/packages/cli-tools/test/mocks/mock_pocketbase_client.dart +2 -1
  11. package/dart-src/root/analysis_options.yaml +3 -0
  12. package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/FlutterPatcherPlugin.kt +1 -0
  13. package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/PatchManager.kt +24 -5
  14. package/dart-src/root/android/src/main/kotlin/com/flutter_patcher/flutter_patcher/PatcherConfig.kt +20 -0
  15. package/dart-src/root/lib/flutter_ota_kit.dart +31 -11
  16. package/dart-src/root/lib/src/aws_update_source.dart +1 -0
  17. package/dart-src/root/lib/src/cloudflare_update_source.dart +1 -0
  18. package/dart-src/root/lib/src/ota_progress_overlay.dart +243 -296
  19. package/dart-src/root/lib/src/patcher_channel.dart +14 -1
  20. package/dart-src/root/lib/src/pkg/plugin_core/src/request_update_bundle_state.dart +2 -1
  21. package/dart-src/root/lib/src/pkg/postgres/src/postgres_types.dart +2 -1
  22. package/dart-src/root/lib/src/pocketbase_update_source.dart +1 -0
  23. package/dart-src/root/lib/src/postgres_update_source.dart +1 -0
  24. package/dart-src/root/lib/src/shared_update_check.dart +30 -2
  25. package/dart-src/root/lib/src/supabase_update_source.dart +1 -0
  26. package/dart-src/root/pubspec.yaml +14 -14
  27. package/package.json +1 -1
@@ -83,6 +83,16 @@ class PatcherChannel {
83
83
  return channel.invokeMethod<String>('currentVersion');
84
84
  }
85
85
 
86
+ /// Stable per-install device identifier, persisted natively (SharedPreferences).
87
+ ///
88
+ /// Generated once on first call and never changes for the app install (even
89
+ /// across patch updates and base APK upgrades), making it a suitable seed for
90
+ /// rollout cohort hashing. Throws [MissingPluginException] on non-Android
91
+ /// platforms and on Android bases compiled before this method existed.
92
+ static Future<String?> deviceId() async {
93
+ return channel.invokeMethod<String>('deviceId');
94
+ }
95
+
86
96
  /// Diagnostics from the last cold-start patch load.
87
97
  ///
88
98
  /// The native side returns `Map?` (see `BootDiagnosticStore`), deserialized by the
@@ -137,7 +147,10 @@ class PatcherChannel {
137
147
  }
138
148
 
139
149
  /// Checks whether a patch version (optionally with md5) is blacklisted.
140
- static Future<bool> isVersionBlacklisted(String version, {String md5 = ''}) async {
150
+ static Future<bool> isVersionBlacklisted(
151
+ String version, {
152
+ String md5 = '',
153
+ }) async {
141
154
  final found = await channel.invokeMethod<bool>('isVersionBlacklisted', {
142
155
  'version': version,
143
156
  'md5': md5,
@@ -1,4 +1,5 @@
1
- import 'package:flutter_ota_kit/src/pkg/core/flutter_ota_kit_core.dart' show Bundle;
1
+ import 'package:flutter_ota_kit/src/pkg/core/flutter_ota_kit_core.dart'
2
+ show Bundle;
2
3
 
3
4
  import 'bundle_unit_of_work.dart';
4
5
  import 'bundle_unit_of_work_store.dart';
@@ -1,4 +1,5 @@
1
- import 'package:flutter_ota_kit/src/pkg/core/flutter_ota_kit_core.dart' show Platform;
1
+ import 'package:flutter_ota_kit/src/pkg/core/flutter_ota_kit_core.dart'
2
+ show Platform;
2
3
 
3
4
  /// Database row for the `bundles` table (snake_case columns).
4
5
  ///
@@ -101,6 +101,7 @@ class PocketBaseUpdateSource {
101
101
  fingerprintHash: config.fingerprintHash,
102
102
  minBundleId: config.minBundleId,
103
103
  currentBundleId: currentBundleId,
104
+ cohort: config.cohort,
104
105
  timeout: timeout,
105
106
  );
106
107
  }
@@ -89,6 +89,7 @@ class PostgresUpdateSource {
89
89
  fingerprintHash: config.fingerprintHash,
90
90
  minBundleId: config.minBundleId,
91
91
  currentBundleId: currentBundleId,
92
+ cohort: config.cohort,
92
93
  timeout: timeout,
93
94
  );
94
95
  }
@@ -6,9 +6,11 @@ import 'package:flutter_ota_kit/src/pkg/core/flutter_ota_kit_core.dart'
6
6
  AppVersionGetBundlesArgs,
7
7
  FingerprintGetBundlesArgs,
8
8
  GetBundlesArgs,
9
+ getDefaultNumericCohort,
9
10
  nilUuid,
10
11
  Platform,
11
12
  UpdateInfo,
13
+ UpdateStatus,
12
14
  UpdateStrategy;
13
15
  import 'package:flutter_ota_kit/src/pkg/client/flutter_ota_kit_client.dart'
14
16
  show ServerUpdateResult;
@@ -16,8 +18,24 @@ import 'package:flutter_ota_kit/src/pkg/plugin_core/flutter_ota_kit_plugin_core.
16
18
  show DatabasePlugin, StoragePlugin;
17
19
 
18
20
  import 'patch_info.dart' show PatchInfo;
21
+ import 'patcher_channel.dart' show PatcherChannel;
19
22
  import 'app_version_resolver.dart';
20
23
 
24
+ /// Stable rollout cohort derived from the native per-install device id.
25
+ ///
26
+ /// Returns null on non-Android platforms, on Android bases compiled before
27
+ /// `deviceId` existed, and in CLI/dart-VM contexts — callers must treat null
28
+ /// as "no cohort", matching the pre-fix behaviour.
29
+ Future<String?> _deviceCohort() async {
30
+ try {
31
+ final id = await PatcherChannel.deviceId();
32
+ if (id == null || id.isEmpty) return null;
33
+ return getDefaultNumericCohort(id);
34
+ } catch (_) {
35
+ return null;
36
+ }
37
+ }
38
+
21
39
  final _uuidRe = RegExp(
22
40
  r'^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$',
23
41
  );
@@ -46,6 +64,7 @@ Future<ServerUpdateResult> performSharedUpdateCheck({
46
64
  required String? fingerprintHash,
47
65
  required String minBundleId,
48
66
  String? currentBundleId,
67
+ String? cohort,
49
68
  Duration timeout = const Duration(seconds: 10),
50
69
  }) async {
51
70
  final bundleId =
@@ -53,6 +72,10 @@ Future<ServerUpdateResult> performSharedUpdateCheck({
53
72
  ? currentBundleId
54
73
  : nilUuid;
55
74
 
75
+ final effectiveCohort = (cohort != null && cohort.isNotEmpty)
76
+ ? cohort
77
+ : await _deviceCohort();
78
+
56
79
  final GetBundlesArgs args;
57
80
  if (updateStrategy == UpdateStrategy.fingerprint) {
58
81
  args = FingerprintGetBundlesArgs(
@@ -61,6 +84,7 @@ Future<ServerUpdateResult> performSharedUpdateCheck({
61
84
  bundleId: bundleId,
62
85
  minBundleId: minBundleId,
63
86
  fingerprintHash: fingerprintHash ?? '',
87
+ cohort: effectiveCohort,
64
88
  );
65
89
  } else {
66
90
  final resolvedAppVersion = await resolveAppVersion(appVersion);
@@ -70,6 +94,7 @@ Future<ServerUpdateResult> performSharedUpdateCheck({
70
94
  bundleId: bundleId,
71
95
  minBundleId: minBundleId,
72
96
  appVersion: resolvedAppVersion,
97
+ cohort: effectiveCohort,
73
98
  );
74
99
  }
75
100
 
@@ -84,8 +109,11 @@ Future<ServerUpdateResult> performSharedUpdateCheck({
84
109
  if (info == null) return ServerUpdateResult.upToDate();
85
110
 
86
111
  final storageUri = info.storageUri;
87
- // Server signals rollback with ROLLBACK status and null/empty storageUri
88
- if (info.status == 'ROLLBACK') {
112
+ // Server signals rollback with ROLLBACK status and null/empty storageUri.
113
+ // NOTE: `info.status` is the `UpdateStatus` enum, not a String — comparing
114
+ // it to `'ROLLBACK'` is always false and silently swallowed every rollback
115
+ // response (including the nil-UUID "fall back to base" the SQL emits).
116
+ if (info.status == UpdateStatus.rollback) {
89
117
  return ServerUpdateResult(
90
118
  isUpToDate: false,
91
119
  patch: null,
@@ -87,6 +87,7 @@ class SupabaseUpdateSource {
87
87
  fingerprintHash: config.fingerprintHash,
88
88
  minBundleId: config.minBundleId,
89
89
  currentBundleId: currentBundleId,
90
+ cohort: config.cohort,
90
91
  timeout: timeout,
91
92
  );
92
93
  }
@@ -1,6 +1,6 @@
1
1
  name: flutter_ota_kit
2
2
  description: Open-source, self-hosted code push (OTA updates) for Flutter Android. Patches Dart AOT libapp.so and assets on cold start with integrity checks and crash rollback.
3
- version: 0.2.1
3
+ version: 0.2.5
4
4
  homepage: https://github.com/HYPER12755/flutter-ota-kit
5
5
  repository: https://github.com/HYPER12755/flutter-ota-kit
6
6
  issue_tracker: https://github.com/HYPER12755/flutter-ota-kit/issues
@@ -21,30 +21,30 @@ environment:
21
21
  dependencies:
22
22
  flutter:
23
23
  sdk: flutter
24
- plugin_platform_interface: '>=2.0.2 <3.0.0'
25
- package_info_plus: ^10.0.0
26
- restart_app: ^1.9.1
24
+ plugin_platform_interface: '>=2.1.8 <3.0.0'
25
+ package_info_plus: ^10.2.1
26
+ restart_app: ^1.10.1
27
27
  # The npm `flutter-ota` CLI (`flutter_ota_kit_cli`) is intentionally NOT a pub
28
28
  # dependency; `dart run flutter_ota_kit:pack` is implemented in `lib/src/pack`.
29
- archive: ^4.0.0
30
- args: '>=2.4.0 <3.0.0'
31
- crypto: '>=3.0.3 <4.0.0'
29
+ archive: ^4.3.0
30
+ args: '>=2.7.0 <3.0.0'
31
+ crypto: '>=3.0.7 <4.0.0'
32
32
  # Merged from the former sub-packages (core, plugin-core, client, and the
33
33
  # supabase/postgres/cloudflare/aws/pocketbase backends), now bundled directly
34
34
  # under lib/src/pkg/. Their external dependencies are unioned here.
35
- http: ^1.2.0
36
- path: ^1.9.0
37
- mime: ^2.0.0
38
- supabase: ^2.14.0
39
- postgres: ^3.4.0
35
+ http: ^1.6.0
36
+ path: ^1.9.1
37
+ mime: ^2.1.0
38
+ supabase: ^2.16.1
39
+ postgres: ^3.5.17
40
40
  pointycastle: ^4.0.0
41
- asn1lib: ^1.5.4
41
+ asn1lib: ^1.6.5
42
42
 
43
43
  dev_dependencies:
44
44
  flutter_test:
45
45
  sdk: flutter
46
46
  flutter_lints: ^6.0.0
47
- test: ^1.25.0
47
+ test: ^1.31.1
48
48
 
49
49
  flutter:
50
50
  plugin:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@_nazmiforreal/flutter-ota",
3
- "version": "0.1.28",
3
+ "version": "0.1.30",
4
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"