@_nazmiforreal/flutter-ota 0.1.21 → 0.1.23
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/bin/flutter-ota-linux-x64 +0 -0
- package/bin/flutter-ota.js +85 -0
- package/dart-src/packages/cli-tools/lib/flutter_ota_kit_cli.dart +7 -4
- package/dart-src/packages/cli-tools/lib/src/commands/bundle.dart +95 -32
- package/dart-src/packages/cli-tools/lib/src/commands/channel.dart +28 -12
- package/dart-src/packages/cli-tools/lib/src/commands/config_command.dart +9 -4
- package/dart-src/packages/cli-tools/lib/src/commands/deploy.dart +29 -6
- package/dart-src/packages/cli-tools/lib/src/commands/doctor.dart +20 -32
- package/dart-src/packages/cli-tools/lib/src/commands/init.dart +40 -19
- package/dart-src/packages/cli-tools/lib/src/commands/keys.dart +7 -5
- package/dart-src/packages/cli-tools/lib/src/commands/migrate.dart +33 -22
- package/dart-src/packages/cli-tools/lib/src/commands/pocketbase.dart +256 -68
- package/dart-src/packages/cli-tools/lib/src/commands/rollback.dart +17 -11
- package/dart-src/packages/cli-tools/lib/src/commands/storage.dart +28 -12
- package/dart-src/packages/cli-tools/lib/src/config.dart +5 -6
- package/dart-src/packages/cli-tools/lib/src/operations.dart +1 -3
- package/dart-src/packages/cli-tools/lib/src/pocketbase/process_manager.dart +17 -16
- package/dart-src/packages/cli-tools/lib/src/runner.dart +3 -1
- package/dart-src/packages/cli-tools/lib/src/ui/ui.dart +8 -14
- package/dart-src/packages/cli-tools/test/mocks/mock_pocketbase_client.dart +7 -3
- package/dart-src/packages/cli-tools/test/pocketbase_schema_test.dart +13 -16
- package/dart-src/packages/core/CHANGELOG.md +15 -0
- package/dart-src/packages/core/lib/src/bundle.dart +3 -6
- package/dart-src/packages/core/pubspec.yaml +1 -1
- package/dart-src/plugins/aws/CHANGELOG.md +18 -0
- package/dart-src/plugins/aws/lib/src/aws_cloudfront_client.dart +1 -2
- package/dart-src/plugins/aws/pubspec.yaml +3 -3
- package/dart-src/plugins/cloudflare/CHANGELOG.md +18 -0
- package/dart-src/plugins/cloudflare/pubspec.yaml +3 -3
- package/dart-src/plugins/plugin-core/CHANGELOG.md +15 -0
- package/dart-src/plugins/plugin-core/pubspec.yaml +2 -2
- package/dart-src/plugins/pocketbase/CHANGELOG.md +18 -0
- package/dart-src/plugins/pocketbase/pubspec.yaml +3 -3
- package/dart-src/plugins/postgres/CHANGELOG.md +18 -0
- package/dart-src/plugins/postgres/pubspec.yaml +3 -3
- package/dart-src/plugins/supabase/CHANGELOG.md +18 -0
- package/dart-src/plugins/supabase/pubspec.yaml +3 -3
- package/package.json +2 -2
- package/scripts/postinstall.js +54 -2
|
@@ -7,16 +7,24 @@ import '../ui/ui.dart';
|
|
|
7
7
|
class RollbackCommand extends FlutterPatcherCommand {
|
|
8
8
|
RollbackCommand({this.config, this.backendOverride}) {
|
|
9
9
|
final detected = config?.provider ?? loadConfig()?.provider;
|
|
10
|
-
argParser.addOption(
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
argParser.addOption(
|
|
11
|
+
'backend',
|
|
12
|
+
abbr: 'b',
|
|
13
|
+
help: detected != null
|
|
14
|
+
? 'Backend provider [detected: $detected].'
|
|
15
|
+
: 'Backend provider.',
|
|
16
|
+
);
|
|
13
17
|
argParser.addOption('channel', abbr: 'c', help: 'Channel to roll back.');
|
|
14
18
|
argParser.addOption(
|
|
15
19
|
'bundle-id',
|
|
16
20
|
abbr: 'i',
|
|
17
21
|
help: 'Roll back to this specific bundle id.',
|
|
18
22
|
);
|
|
19
|
-
argParser.addOption(
|
|
23
|
+
argParser.addOption(
|
|
24
|
+
'platform',
|
|
25
|
+
abbr: 'p',
|
|
26
|
+
help: 'Platform filter (e.g. android).',
|
|
27
|
+
);
|
|
20
28
|
}
|
|
21
29
|
|
|
22
30
|
final FlutterPatcherConfig? config;
|
|
@@ -49,14 +57,12 @@ class RollbackCommand extends FlutterPatcherCommand {
|
|
|
49
57
|
|
|
50
58
|
banner('rollback');
|
|
51
59
|
final steps = Steps('rollback');
|
|
52
|
-
final (
|
|
60
|
+
final (
|
|
61
|
+
disabled,
|
|
62
|
+
live,
|
|
63
|
+
) = await steps.run('Rolling back channel "$channel"', () async {
|
|
53
64
|
if (bundleId != null && bundleId.isNotEmpty) {
|
|
54
|
-
return rollbackToBundle(
|
|
55
|
-
backend,
|
|
56
|
-
channel,
|
|
57
|
-
bundleId,
|
|
58
|
-
platform: platform,
|
|
59
|
-
);
|
|
65
|
+
return rollbackToBundle(backend, channel, bundleId, platform: platform);
|
|
60
66
|
}
|
|
61
67
|
final id = await rollbackChannel(backend, channel);
|
|
62
68
|
final nowLive = (await getChannel(backend, channel))?.id ?? '';
|
|
@@ -28,9 +28,13 @@ class StorageCommand extends FlutterPatcherCommand {
|
|
|
28
28
|
class StorageListCommand extends FlutterPatcherCommand {
|
|
29
29
|
StorageListCommand({this.config, this.backendOverride}) {
|
|
30
30
|
final detected = config?.provider ?? loadConfig()?.provider;
|
|
31
|
-
argParser.addOption(
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
argParser.addOption(
|
|
32
|
+
'backend',
|
|
33
|
+
abbr: 'b',
|
|
34
|
+
help: detected != null
|
|
35
|
+
? 'Backend provider [detected: $detected].'
|
|
36
|
+
: 'Backend provider.',
|
|
37
|
+
);
|
|
34
38
|
argParser.addOption('prefix', help: 'Key prefix filter (e.g. bundles).');
|
|
35
39
|
}
|
|
36
40
|
|
|
@@ -50,9 +54,12 @@ class StorageListCommand extends FlutterPatcherCommand {
|
|
|
50
54
|
final prefix = argResults!['prefix'] as String?;
|
|
51
55
|
banner('storage · list');
|
|
52
56
|
final steps = Steps('list');
|
|
53
|
-
final objects = await steps.run(
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
final objects = await steps.run(
|
|
58
|
+
'Listing storage objects',
|
|
59
|
+
() => backend.storage.listObjects(
|
|
60
|
+
prefix == null || prefix.isEmpty ? null : prefix,
|
|
61
|
+
),
|
|
62
|
+
);
|
|
56
63
|
if (objects.isEmpty) {
|
|
57
64
|
steps.skip('(no objects)');
|
|
58
65
|
steps.summary();
|
|
@@ -70,10 +77,17 @@ class StorageListCommand extends FlutterPatcherCommand {
|
|
|
70
77
|
class StorageDeleteCommand extends FlutterPatcherCommand {
|
|
71
78
|
StorageDeleteCommand({this.config, this.backendOverride}) {
|
|
72
79
|
final detected = config?.provider ?? loadConfig()?.provider;
|
|
73
|
-
argParser.addOption(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
80
|
+
argParser.addOption(
|
|
81
|
+
'backend',
|
|
82
|
+
abbr: 'b',
|
|
83
|
+
help: detected != null
|
|
84
|
+
? 'Backend provider [detected: $detected].'
|
|
85
|
+
: 'Backend provider.',
|
|
86
|
+
);
|
|
87
|
+
argParser.addMultiOption(
|
|
88
|
+
'key',
|
|
89
|
+
help: 'Storage key to delete (repeatable).',
|
|
90
|
+
);
|
|
77
91
|
argParser.addOption('uri', help: 'Full storage URI to delete.');
|
|
78
92
|
}
|
|
79
93
|
|
|
@@ -102,8 +116,10 @@ class StorageDeleteCommand extends FlutterPatcherCommand {
|
|
|
102
116
|
banner('storage · delete');
|
|
103
117
|
final steps = Steps('delete');
|
|
104
118
|
if (keys.isNotEmpty) {
|
|
105
|
-
await steps.run(
|
|
106
|
-
|
|
119
|
+
await steps.run(
|
|
120
|
+
'Deleting ${keys.length} object(s)',
|
|
121
|
+
() => backend.storage.deleteObjects(keys),
|
|
122
|
+
);
|
|
107
123
|
} else {
|
|
108
124
|
await steps.run('Deleting $uri', () => backend.storage.delete(uri!));
|
|
109
125
|
}
|
|
@@ -170,9 +170,7 @@ FlutterPatcherConfig? loadConfig() {
|
|
|
170
170
|
jsonDecode(raw) as Map<String, dynamic>,
|
|
171
171
|
);
|
|
172
172
|
} on FormatException {
|
|
173
|
-
stderr.writeln(
|
|
174
|
-
'Warning: invalid config at ${file.path} — ignoring.',
|
|
175
|
-
);
|
|
173
|
+
stderr.writeln('Warning: invalid config at ${file.path} — ignoring.');
|
|
176
174
|
return null;
|
|
177
175
|
}
|
|
178
176
|
}
|
|
@@ -246,7 +244,7 @@ SupabaseServiceRoleConfig resolveSupabaseConfig(
|
|
|
246
244
|
if (resolvedUrl == null || resolvedUrl.isEmpty) {
|
|
247
245
|
throw StateError(
|
|
248
246
|
'Supabase URL is required. Set it via SUPABASE_URL env var, '
|
|
249
|
-
|
|
247
|
+
'or `flutter-ota config set supabase.url <url>`.',
|
|
250
248
|
);
|
|
251
249
|
}
|
|
252
250
|
|
|
@@ -280,7 +278,8 @@ SupabaseStorageConfig resolveSupabaseStorageConfig(
|
|
|
280
278
|
supabaseServiceRoleKey: db.supabaseServiceRoleKey,
|
|
281
279
|
supabaseAnonKey: db.supabaseAnonKey,
|
|
282
280
|
clientFactory: db.clientFactory,
|
|
283
|
-
bucketName:
|
|
281
|
+
bucketName:
|
|
282
|
+
bucket ??
|
|
284
283
|
Platform.environment['SUPABASE_BUCKET'] ??
|
|
285
284
|
config.supabase.bucket ??
|
|
286
285
|
'bundles',
|
|
@@ -382,7 +381,7 @@ PostgresConfig resolvePostgresDatabaseConfig(
|
|
|
382
381
|
if (resolvedHost == null || resolvedHost.isEmpty) {
|
|
383
382
|
throw StateError(
|
|
384
383
|
'Postgres host is required. Set POSTGRES_HOST env var, '
|
|
385
|
-
|
|
384
|
+
'or `flutter-ota config set postgres.host <host>`.',
|
|
386
385
|
);
|
|
387
386
|
}
|
|
388
387
|
|
|
@@ -61,9 +61,7 @@ class ListOptions {
|
|
|
61
61
|
/// Build the zip, upload it, and register a [Bundle] via the backend.
|
|
62
62
|
Future<Bundle> deployBundle(Backend backend, DeployOptions opts) async {
|
|
63
63
|
if (opts.targetAppVersion != null && opts.fingerprintHash != null) {
|
|
64
|
-
throw StateError(
|
|
65
|
-
'Use only one of target-app-version / fingerprint-hash.',
|
|
66
|
-
);
|
|
64
|
+
throw StateError('Use only one of target-app-version / fingerprint-hash.');
|
|
67
65
|
}
|
|
68
66
|
if (opts.targetAppVersion == null && opts.fingerprintHash == null) {
|
|
69
67
|
throw StateError(
|
|
@@ -17,7 +17,7 @@ import 'package:path/path.dart' as p;
|
|
|
17
17
|
|
|
18
18
|
class PocketBaseProcess {
|
|
19
19
|
PocketBaseProcess._(this.process, this.dataDir, this.binaryPath)
|
|
20
|
-
|
|
20
|
+
: _exitCodeCompleted = false {
|
|
21
21
|
process.exitCode.then((_) => _exitCodeCompleted = true);
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -92,12 +92,14 @@ class PocketBaseProcessManager {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
void _writeConfigFile(int pid) {
|
|
95
|
-
configFile.writeAsStringSync(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
configFile.writeAsStringSync(
|
|
96
|
+
jsonEncode({
|
|
97
|
+
'pid': pid,
|
|
98
|
+
'host': host,
|
|
99
|
+
'port': port,
|
|
100
|
+
'url': 'http://$host:$port',
|
|
101
|
+
}),
|
|
102
|
+
);
|
|
101
103
|
}
|
|
102
104
|
|
|
103
105
|
Map<String, dynamic>? readConfig() {
|
|
@@ -135,19 +137,18 @@ class PocketBaseProcessManager {
|
|
|
135
137
|
final hooksDir = Directory(p.join(dataDir.path, 'pb_hooks'));
|
|
136
138
|
await hooksDir.create(recursive: true);
|
|
137
139
|
|
|
138
|
-
final mergedEnv = <String, String>{
|
|
139
|
-
...Platform.environment,
|
|
140
|
-
...?env,
|
|
141
|
-
};
|
|
140
|
+
final mergedEnv = <String, String>{...Platform.environment, ...?env};
|
|
142
141
|
|
|
143
142
|
// Create superuser if credentials provided (PB 0.40+ doesn't support
|
|
144
143
|
// PB_ADMIN_EMAIL env var, so we use the CLI directly).
|
|
145
144
|
if (adminEmail != null && adminPassword != null) {
|
|
146
|
-
final result = await Process.run(
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
145
|
+
final result = await Process.run(binaryPath.path, [
|
|
146
|
+
'superuser',
|
|
147
|
+
'upsert',
|
|
148
|
+
'--dir=${dataDir.path}',
|
|
149
|
+
adminEmail,
|
|
150
|
+
adminPassword,
|
|
151
|
+
], environment: mergedEnv);
|
|
151
152
|
if (result.exitCode != 0) {
|
|
152
153
|
// Non-fatal; serve will continue but schema install may fail.
|
|
153
154
|
}
|
|
@@ -24,7 +24,9 @@ class FlutterPatcherRunner extends CommandRunner<int> {
|
|
|
24
24
|
// Intercept missing subcommand for parent commands so we show our
|
|
25
25
|
// colored usage text instead of the args package's plain text.
|
|
26
26
|
if (results.command == null && results.rest.isEmpty) {
|
|
27
|
-
final cmdName = results.arguments.isNotEmpty
|
|
27
|
+
final cmdName = results.arguments.isNotEmpty
|
|
28
|
+
? results.arguments.first
|
|
29
|
+
: null;
|
|
28
30
|
if (cmdName != null) {
|
|
29
31
|
final cmd = commands[cmdName];
|
|
30
32
|
if (cmd != null && cmd.subcommands.isNotEmpty) {
|
|
@@ -127,7 +127,8 @@ Future<T> spinner<T>(
|
|
|
127
127
|
final r = await task();
|
|
128
128
|
// Keep spinner visible for at least 400ms so fast ops are readable.
|
|
129
129
|
final elapsed = sw.elapsedMilliseconds;
|
|
130
|
-
if (elapsed < 400)
|
|
130
|
+
if (elapsed < 400)
|
|
131
|
+
await Future.delayed(Duration(milliseconds: 400 - elapsed));
|
|
131
132
|
timer.cancel();
|
|
132
133
|
sw.stop();
|
|
133
134
|
stdout.write('\r\x1b[K ${green('✓')} ${done ?? label}\n');
|
|
@@ -296,9 +297,7 @@ class Steps {
|
|
|
296
297
|
void summary() {
|
|
297
298
|
_sw.stop();
|
|
298
299
|
final ms = _sw.elapsedMilliseconds;
|
|
299
|
-
final time = ms >= 1000
|
|
300
|
-
? '${(ms / 1000).toStringAsFixed(1)}s'
|
|
301
|
-
: '${ms}ms';
|
|
300
|
+
final time = ms >= 1000 ? '${(ms / 1000).toStringAsFixed(1)}s' : '${ms}ms';
|
|
302
301
|
final parts = <String>[];
|
|
303
302
|
if (_done > 0) parts.add('${_done} completed');
|
|
304
303
|
if (_skipped > 0) parts.add('${_skipped} skipped');
|
|
@@ -401,9 +400,7 @@ class Steps {
|
|
|
401
400
|
_activeTimer = null;
|
|
402
401
|
_activeLabel = null;
|
|
403
402
|
if (_colorOn) {
|
|
404
|
-
stdout.write(
|
|
405
|
-
'\r\x1b[K ${success ? green('✓') : red('✗')} $label\n',
|
|
406
|
-
);
|
|
403
|
+
stdout.write('\r\x1b[K ${success ? green('✓') : red('✗')} $label\n');
|
|
407
404
|
}
|
|
408
405
|
if (success) {
|
|
409
406
|
_done++;
|
|
@@ -455,9 +452,7 @@ class ProgressBar {
|
|
|
455
452
|
_spin = (_spin + 1) % _frames.length;
|
|
456
453
|
final pctStr = '${(pct * 100).round()}%'.padLeft(4);
|
|
457
454
|
|
|
458
|
-
stdout.write(
|
|
459
|
-
'\r\x1b[K ${cyan(_frames[_spin])} $_label $bar $pctStr',
|
|
460
|
-
);
|
|
455
|
+
stdout.write('\r\x1b[K ${cyan(_frames[_spin])} $_label $bar $pctStr');
|
|
461
456
|
}
|
|
462
457
|
|
|
463
458
|
/// Finish: print the final status line. This is intentionally async and
|
|
@@ -470,11 +465,10 @@ class ProgressBar {
|
|
|
470
465
|
_sw.stop();
|
|
471
466
|
// Keep bar visible for at least 500ms so fast ops are readable.
|
|
472
467
|
final elapsed = _sw.elapsedMilliseconds;
|
|
473
|
-
if (elapsed < 500)
|
|
468
|
+
if (elapsed < 500)
|
|
469
|
+
await Future.delayed(Duration(milliseconds: 500 - elapsed));
|
|
474
470
|
final ms = _sw.elapsedMilliseconds;
|
|
475
|
-
final time = ms >= 1000
|
|
476
|
-
? '${(ms / 1000).toStringAsFixed(1)}s'
|
|
477
|
-
: '${ms}ms';
|
|
471
|
+
final time = ms >= 1000 ? '${(ms / 1000).toStringAsFixed(1)}s' : '${ms}ms';
|
|
478
472
|
if (_colorOn) {
|
|
479
473
|
stdout.write('\r\x1b[K ${green('✓')} $_label in $time\n');
|
|
480
474
|
} else {
|
|
@@ -226,8 +226,9 @@ class MockPocketBaseClient implements PocketBaseClient {
|
|
|
226
226
|
Future<void> deleteAdmin(String id) async {}
|
|
227
227
|
|
|
228
228
|
@override
|
|
229
|
-
Future<List<Map<String, dynamic>>> exportCollection(
|
|
230
|
-
|
|
229
|
+
Future<List<Map<String, dynamic>>> exportCollection(
|
|
230
|
+
String collection,
|
|
231
|
+
) async => [];
|
|
231
232
|
|
|
232
233
|
@override
|
|
233
234
|
Future<void> importCollection(
|
|
@@ -247,7 +248,10 @@ class MockPocketBaseClient implements PocketBaseClient {
|
|
|
247
248
|
|
|
248
249
|
@override
|
|
249
250
|
Future<Map<String, dynamic>> listLogs({
|
|
250
|
-
String? filter,
|
|
251
|
+
String? filter,
|
|
252
|
+
String? sort,
|
|
253
|
+
int page = 1,
|
|
254
|
+
int perPage = 30,
|
|
251
255
|
}) async => {'items': [], 'totalItems': 0};
|
|
252
256
|
|
|
253
257
|
@override
|
|
@@ -80,22 +80,19 @@ void main() {
|
|
|
80
80
|
await mock.stop();
|
|
81
81
|
});
|
|
82
82
|
|
|
83
|
-
test(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
expect(mock.createdCollections, containsAll(_allCollections));
|
|
97
|
-
},
|
|
98
|
-
);
|
|
83
|
+
test('schema installer creates all five collections on a fresh PB', () async {
|
|
84
|
+
final installer = PocketBaseSchemaInstaller(
|
|
85
|
+
url: mock.baseUrl,
|
|
86
|
+
adminEmail: 'admin@x.com',
|
|
87
|
+
adminPassword: 'secret',
|
|
88
|
+
);
|
|
89
|
+
final result = await installer.install();
|
|
90
|
+
expect(mock.authCalled, isTrue);
|
|
91
|
+
expect(mock.lastAuthEmail, 'admin@x.com');
|
|
92
|
+
expect(result.created, containsAll(_allCollections));
|
|
93
|
+
expect(result.skipped, isEmpty);
|
|
94
|
+
expect(mock.createdCollections, containsAll(_allCollections));
|
|
95
|
+
});
|
|
99
96
|
|
|
100
97
|
test('schema installer skips collections that already exist', () async {
|
|
101
98
|
mock.existingCollections = _allCollections;
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
## 0.1.8
|
|
2
|
+
|
|
3
|
+
- Release 2026-09-10
|
|
4
|
+
|
|
5
|
+
## 0.1.8
|
|
6
|
+
|
|
7
|
+
- Automated release 2026-09-10
|
|
8
|
+
|
|
9
|
+
## 0.1.7
|
|
10
|
+
|
|
11
|
+
- Added comprehensive documentation for all public APIs.
|
|
12
|
+
- Improved `Bundle` equality and hashCode implementation.
|
|
13
|
+
- Fixed `toSqlJson()` nullable field handling.
|
|
14
|
+
- Added `semver` exports to barrel file.
|
|
15
|
+
|
|
1
16
|
## 0.1.6
|
|
2
17
|
|
|
3
18
|
- Added `gitCommitHash` field to `UpdateInfo` for commit tracking.
|
|
@@ -178,19 +178,16 @@ class Bundle {
|
|
|
178
178
|
if (targetAppVersion != null) 'target_app_version': targetAppVersion,
|
|
179
179
|
if (fingerprintHash != null) 'fingerprint_hash': fingerprintHash,
|
|
180
180
|
if (metadata != null) 'metadata': metadata!.toJson(),
|
|
181
|
-
if (manifestStorageUri != null)
|
|
182
|
-
'manifest_storage_uri': manifestStorageUri,
|
|
181
|
+
if (manifestStorageUri != null) 'manifest_storage_uri': manifestStorageUri,
|
|
183
182
|
if (manifestFileHash != null) 'manifest_file_hash': manifestFileHash,
|
|
184
183
|
if (assetBaseStorageUri != null)
|
|
185
184
|
'asset_base_storage_uri': assetBaseStorageUri,
|
|
186
185
|
if (patches != null) 'patches': patches!.map((p) => p.toJson()).toList(),
|
|
187
186
|
if (patchBaseBundleId != null) 'patch_base_bundle_id': patchBaseBundleId,
|
|
188
|
-
if (patchBaseFileHash != null)
|
|
189
|
-
'patch_base_file_hash': patchBaseFileHash,
|
|
187
|
+
if (patchBaseFileHash != null) 'patch_base_file_hash': patchBaseFileHash,
|
|
190
188
|
if (patchFileHashLegacy != null) 'patch_file_hash': patchFileHashLegacy,
|
|
191
189
|
if (patchStorageUri != null) 'patch_storage_uri': patchStorageUri,
|
|
192
|
-
if (rolloutCohortCount != null)
|
|
193
|
-
'rollout_cohort_count': rolloutCohortCount,
|
|
190
|
+
if (rolloutCohortCount != null) 'rollout_cohort_count': rolloutCohortCount,
|
|
194
191
|
if (targetCohorts != null) 'target_cohorts': targetCohorts,
|
|
195
192
|
};
|
|
196
193
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
name: flutter_ota_kit_core
|
|
2
2
|
description: Core data model, rollout cohorts, and shared utilities for flutter_ota_kit — Dart translation of hot-updater's packages/core.
|
|
3
|
-
version: 0.1.
|
|
3
|
+
version: 0.1.8
|
|
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
|
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
## 0.1.10
|
|
2
|
+
|
|
3
|
+
- Release 2026-09-10
|
|
4
|
+
|
|
5
|
+
## 0.1.9
|
|
6
|
+
|
|
7
|
+
- Release 2026-09-10
|
|
8
|
+
|
|
9
|
+
## 0.1.9
|
|
10
|
+
|
|
11
|
+
- Automated release 2026-09-10
|
|
12
|
+
|
|
13
|
+
## 0.1.8
|
|
14
|
+
|
|
15
|
+
- Added comprehensive documentation for all public APIs.
|
|
16
|
+
- Documented S3 client, CloudFront signer, SSM client, and storage profiles.
|
|
17
|
+
- General maintenance.
|
|
18
|
+
|
|
1
19
|
## 0.1.7
|
|
2
20
|
|
|
3
21
|
- General maintenance.
|
|
@@ -2,7 +2,6 @@ import 'dart:convert' show utf8;
|
|
|
2
2
|
import 'dart:typed_data' show Uint8List;
|
|
3
3
|
|
|
4
4
|
import 'package:crypto/crypto.dart' show Hmac, sha256;
|
|
5
|
-
import 'package:flutter/foundation.dart' show debugPrint;
|
|
6
5
|
import 'package:http/http.dart' show Client, Request, Response;
|
|
7
6
|
|
|
8
7
|
const String _cloudfrontService = 'cloudfront';
|
|
@@ -92,7 +91,7 @@ class AwsCloudFrontClient implements AwsCloudFrontClientLike {
|
|
|
92
91
|
if (shouldWait) rethrow;
|
|
93
92
|
// When not waiting, surface invalidation failures as warnings and
|
|
94
93
|
// continue (mirrors hot-updater's s3Database behaviour).
|
|
95
|
-
|
|
94
|
+
print(
|
|
96
95
|
'[flutter_ota_kit/aws] CloudFront invalidation failed for '
|
|
97
96
|
'$distributionId; continuing without cache invalidation: $error',
|
|
98
97
|
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
name: flutter_ota_kit_aws
|
|
2
2
|
description: AWS S3 storage + S3/DynamoDB database plugins for flutter_ota_kit (faithful port of hot-updater plugins/aws).
|
|
3
|
-
version: 0.1.
|
|
3
|
+
version: 0.1.10
|
|
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
|
|
@@ -11,8 +11,8 @@ environment:
|
|
|
11
11
|
sdk: ">=3.13.2 <4.0.0"
|
|
12
12
|
|
|
13
13
|
dependencies:
|
|
14
|
-
flutter_ota_kit_core: ^0.1.
|
|
15
|
-
flutter_ota_kit_plugin_core: ^0.0.
|
|
14
|
+
flutter_ota_kit_core: ^0.1.8
|
|
15
|
+
flutter_ota_kit_plugin_core: ^0.0.10
|
|
16
16
|
crypto: ^3.0.0
|
|
17
17
|
http: ^1.2.0
|
|
18
18
|
path: ^1.9.0
|
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
## 0.1.10
|
|
2
|
+
|
|
3
|
+
- Release 2026-09-10
|
|
4
|
+
|
|
5
|
+
## 0.1.9
|
|
6
|
+
|
|
7
|
+
- Release 2026-09-10
|
|
8
|
+
|
|
9
|
+
## 0.1.9
|
|
10
|
+
|
|
11
|
+
- Automated release 2026-09-10
|
|
12
|
+
|
|
13
|
+
## 0.1.8
|
|
14
|
+
|
|
15
|
+
- Added comprehensive documentation for all public APIs.
|
|
16
|
+
- Documented D1 database, R2 storage, and worker database plugins.
|
|
17
|
+
- General maintenance.
|
|
18
|
+
|
|
1
19
|
## 0.1.7
|
|
2
20
|
|
|
3
21
|
- General maintenance.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
name: flutter_ota_kit_cloudflare
|
|
2
2
|
description: Cloudflare D1 + R2 storage plugins for flutter_ota_kit (faithful port of hot-updater plugins/cloudflare).
|
|
3
|
-
version: 0.1.
|
|
3
|
+
version: 0.1.10
|
|
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
|
|
@@ -11,8 +11,8 @@ environment:
|
|
|
11
11
|
sdk: ">=3.13.2 <4.0.0"
|
|
12
12
|
|
|
13
13
|
dependencies:
|
|
14
|
-
flutter_ota_kit_core: ^0.1.
|
|
15
|
-
flutter_ota_kit_plugin_core: ^0.0.
|
|
14
|
+
flutter_ota_kit_core: ^0.1.8
|
|
15
|
+
flutter_ota_kit_plugin_core: ^0.0.10
|
|
16
16
|
crypto: ^3.0.0
|
|
17
17
|
http: ^1.2.0
|
|
18
18
|
path: ^1.9.0
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
## 0.0.10
|
|
2
|
+
|
|
3
|
+
- Release 2026-09-10
|
|
4
|
+
|
|
5
|
+
## 0.0.10
|
|
6
|
+
|
|
7
|
+
- Automated release 2026-09-10
|
|
8
|
+
|
|
9
|
+
## 0.0.9
|
|
10
|
+
|
|
11
|
+
- Added comprehensive documentation for all public APIs.
|
|
12
|
+
- Documented `DatabasePlugin`, `StoragePlugin`, `BuildPlugin` interfaces.
|
|
13
|
+
- Documented `HotUpdaterContext` and `StorageResolveContext` schemas.
|
|
14
|
+
- Documented storage URI protocol schemes.
|
|
15
|
+
|
|
1
16
|
## 0.0.8
|
|
2
17
|
|
|
3
18
|
- General maintenance.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
name: flutter_ota_kit_plugin_core
|
|
2
2
|
description: Plugin core abstractions for flutter_ota_kit — database, storage, and build interfaces.
|
|
3
|
-
version: 0.0.
|
|
3
|
+
version: 0.0.10
|
|
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
|
|
@@ -11,7 +11,7 @@ environment:
|
|
|
11
11
|
sdk: ">=3.13.2 <4.0.0"
|
|
12
12
|
|
|
13
13
|
dependencies:
|
|
14
|
-
flutter_ota_kit_core: ^0.1.
|
|
14
|
+
flutter_ota_kit_core: ^0.1.8
|
|
15
15
|
mime: ^2.0.0
|
|
16
16
|
|
|
17
17
|
dev_dependencies:
|
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
## 0.1.7
|
|
2
|
+
|
|
3
|
+
- Release 2026-09-10
|
|
4
|
+
|
|
5
|
+
## 0.1.6
|
|
6
|
+
|
|
7
|
+
- Release 2026-09-10
|
|
8
|
+
|
|
9
|
+
## 0.1.6
|
|
10
|
+
|
|
11
|
+
- Automated release 2026-09-10
|
|
12
|
+
|
|
13
|
+
## 0.1.5
|
|
14
|
+
|
|
15
|
+
- Added comprehensive documentation for all public APIs.
|
|
16
|
+
- Documented PocketBase client, database, storage, and bundle mapper.
|
|
17
|
+
- General maintenance.
|
|
18
|
+
|
|
1
19
|
## 0.1.4
|
|
2
20
|
|
|
3
21
|
- General maintenance.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
name: flutter_ota_kit_pocketbase
|
|
2
2
|
description: PocketBase plugin for flutter_ota_kit — local-first self-hostable backend with admin UI, auth, file storage, and realtime.
|
|
3
|
-
version: 0.1.
|
|
3
|
+
version: 0.1.7
|
|
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
|
|
@@ -11,8 +11,8 @@ environment:
|
|
|
11
11
|
sdk: ">=3.13.2 <4.0.0"
|
|
12
12
|
|
|
13
13
|
dependencies:
|
|
14
|
-
flutter_ota_kit_core: ^0.1.
|
|
15
|
-
flutter_ota_kit_plugin_core: ^0.0.
|
|
14
|
+
flutter_ota_kit_core: ^0.1.8
|
|
15
|
+
flutter_ota_kit_plugin_core: ^0.0.10
|
|
16
16
|
http: ^1.2.0
|
|
17
17
|
|
|
18
18
|
dev_dependencies:
|
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
## 0.1.10
|
|
2
|
+
|
|
3
|
+
- Release 2026-09-10
|
|
4
|
+
|
|
5
|
+
## 0.1.9
|
|
6
|
+
|
|
7
|
+
- Release 2026-09-10
|
|
8
|
+
|
|
9
|
+
## 0.1.9
|
|
10
|
+
|
|
11
|
+
- Automated release 2026-09-10
|
|
12
|
+
|
|
13
|
+
## 0.1.8
|
|
14
|
+
|
|
15
|
+
- Added comprehensive documentation for all public APIs.
|
|
16
|
+
- Improved bundle mapper and database plugin documentation.
|
|
17
|
+
- General maintenance.
|
|
18
|
+
|
|
1
19
|
## 0.1.7
|
|
2
20
|
|
|
3
21
|
- General maintenance.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
name: flutter_ota_kit_postgres
|
|
2
2
|
description: Postgres plugin for flutter_ota_kit — database backend.
|
|
3
|
-
version: 0.1.
|
|
3
|
+
version: 0.1.10
|
|
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
|
|
@@ -11,8 +11,8 @@ environment:
|
|
|
11
11
|
sdk: ">=3.13.2 <4.0.0"
|
|
12
12
|
|
|
13
13
|
dependencies:
|
|
14
|
-
flutter_ota_kit_core: ^0.1.
|
|
15
|
-
flutter_ota_kit_plugin_core: ^0.0.
|
|
14
|
+
flutter_ota_kit_core: ^0.1.8
|
|
15
|
+
flutter_ota_kit_plugin_core: ^0.0.10
|
|
16
16
|
postgres: ^3.4.0
|
|
17
17
|
|
|
18
18
|
dev_dependencies:
|
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
## 0.1.11
|
|
2
|
+
|
|
3
|
+
- Release 2026-09-10
|
|
4
|
+
|
|
5
|
+
## 0.1.10
|
|
6
|
+
|
|
7
|
+
- Release 2026-09-10
|
|
8
|
+
|
|
9
|
+
## 0.1.10
|
|
10
|
+
|
|
11
|
+
- Automated release 2026-09-10
|
|
12
|
+
|
|
13
|
+
## 0.1.9
|
|
14
|
+
|
|
15
|
+
- Added comprehensive documentation for all public APIs.
|
|
16
|
+
- Improved error message handling with `errorMessage` utility.
|
|
17
|
+
- General maintenance.
|
|
18
|
+
|
|
1
19
|
## 0.1.8
|
|
2
20
|
|
|
3
21
|
- Updated `mapUpdateInfoRow` to pass `gitCommitHash` from bundle data.
|