@_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
|
@@ -31,7 +31,11 @@ class InitCommand extends FlutterPatcherCommand {
|
|
|
31
31
|
defaultsTo: 'production',
|
|
32
32
|
help: 'Default channel.',
|
|
33
33
|
);
|
|
34
|
-
argParser.addOption(
|
|
34
|
+
argParser.addOption(
|
|
35
|
+
'platform',
|
|
36
|
+
defaultsTo: 'android',
|
|
37
|
+
help: 'Default platform.',
|
|
38
|
+
);
|
|
35
39
|
argParser.addOption(
|
|
36
40
|
'source',
|
|
37
41
|
abbr: 's',
|
|
@@ -42,7 +46,11 @@ class InitCommand extends FlutterPatcherCommand {
|
|
|
42
46
|
'global',
|
|
43
47
|
help: 'Write to the global ~/.flutter_ota_kit config (no scaffolding).',
|
|
44
48
|
);
|
|
45
|
-
argParser.addFlag(
|
|
49
|
+
argParser.addFlag(
|
|
50
|
+
'force',
|
|
51
|
+
abbr: 'f',
|
|
52
|
+
help: 'Overwrite an existing config.',
|
|
53
|
+
);
|
|
46
54
|
}
|
|
47
55
|
|
|
48
56
|
final FlutterPatcherConfig? config;
|
|
@@ -226,10 +234,7 @@ class InitCommand extends FlutterPatcherCommand {
|
|
|
226
234
|
'Supabase service role key',
|
|
227
235
|
env['SUPABASE_SERVICE_ROLE_KEY'],
|
|
228
236
|
),
|
|
229
|
-
anonKey: _p(
|
|
230
|
-
'Supabase anon key',
|
|
231
|
-
env['SUPABASE_ANON_KEY'],
|
|
232
|
-
),
|
|
237
|
+
anonKey: _p('Supabase anon key', env['SUPABASE_ANON_KEY']),
|
|
233
238
|
bucket: _p('Storage bucket', env['SUPABASE_BUCKET'] ?? 'bundles'),
|
|
234
239
|
basePath: _p('Storage base path', env['SUPABASE_BASE_PATH']),
|
|
235
240
|
managementKey: _p(
|
|
@@ -248,8 +253,10 @@ class InitCommand extends FlutterPatcherCommand {
|
|
|
248
253
|
step('Wrote ${file.path}');
|
|
249
254
|
|
|
250
255
|
if (global) {
|
|
251
|
-
warn(
|
|
252
|
-
|
|
256
|
+
warn(
|
|
257
|
+
'Secrets are stored in plaintext under ~/.flutter_ota_kit. '
|
|
258
|
+
'Restrict permissions and use a secrets manager in production.',
|
|
259
|
+
);
|
|
253
260
|
return;
|
|
254
261
|
}
|
|
255
262
|
|
|
@@ -259,23 +266,33 @@ class InitCommand extends FlutterPatcherCommand {
|
|
|
259
266
|
stdout.writeln();
|
|
260
267
|
stdout.writeln(' ${cyan('Next steps:')}');
|
|
261
268
|
step('1. ${dim('flutter pub get')}');
|
|
262
|
-
step(
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
269
|
+
step(
|
|
270
|
+
'2. In lib/main.dart call ${green('await setupFlutterOta();')} '
|
|
271
|
+
'right after WidgetsFlutterBinding.ensureInitialized() (before runApp). '
|
|
272
|
+
'A `.env` scaffold was written — put secrets there, then build with '
|
|
273
|
+
'`--dart-define-from-file=.env` (environment overrides config).',
|
|
274
|
+
);
|
|
266
275
|
if (provider == 'supabase') {
|
|
267
|
-
step(
|
|
276
|
+
step(
|
|
277
|
+
'3. Provision the backend once: ${dim('flutter-ota migrate supabase')}',
|
|
278
|
+
);
|
|
268
279
|
} else if (provider == 'postgres') {
|
|
269
280
|
step('3. Provision the backend: ${dim('flutter-ota migrate postgres')}');
|
|
270
281
|
} else if (provider == 'cloudflare') {
|
|
271
|
-
step(
|
|
282
|
+
step(
|
|
283
|
+
'3. Provision the backend: ${dim('flutter-ota migrate cloudflare')}',
|
|
284
|
+
);
|
|
272
285
|
} else if (provider == 'aws') {
|
|
273
286
|
step('3. Provision the backend: ${dim('flutter-ota migrate aws')}');
|
|
274
287
|
} else if (provider == 'pocketbase') {
|
|
275
|
-
step(
|
|
288
|
+
step(
|
|
289
|
+
'3. Provision the backend: ${dim('flutter-ota migrate pocketbase')}',
|
|
290
|
+
);
|
|
276
291
|
}
|
|
277
|
-
step(
|
|
278
|
-
|
|
292
|
+
step(
|
|
293
|
+
'4. Build a patch: ${dim('flutter-ota build --version 1.0.1')} '
|
|
294
|
+
'then ${dim('flutter-ota deploy')}',
|
|
295
|
+
);
|
|
279
296
|
});
|
|
280
297
|
|
|
281
298
|
/// Generate the integration files (pubspec dep, manifest permission, setup dart
|
|
@@ -306,7 +323,9 @@ class InitCommand extends FlutterPatcherCommand {
|
|
|
306
323
|
final marker = '\ndependencies:';
|
|
307
324
|
final idx = content.indexOf(marker);
|
|
308
325
|
if (idx == -1) {
|
|
309
|
-
warn(
|
|
326
|
+
warn(
|
|
327
|
+
'Could not find a `dependencies:` block; add `flutter_ota_kit` manually.',
|
|
328
|
+
);
|
|
310
329
|
return;
|
|
311
330
|
}
|
|
312
331
|
final insertAt = idx + marker.length;
|
|
@@ -328,7 +347,9 @@ class InitCommand extends FlutterPatcherCommand {
|
|
|
328
347
|
}
|
|
329
348
|
final match = RegExp(r'<manifest[^>]*>').firstMatch(content);
|
|
330
349
|
if (match == null) {
|
|
331
|
-
warn(
|
|
350
|
+
warn(
|
|
351
|
+
'Could not locate <manifest> tag; add INTERNET permission manually.',
|
|
352
|
+
);
|
|
332
353
|
return;
|
|
333
354
|
}
|
|
334
355
|
final insertAt = match.end;
|
|
@@ -9,7 +9,10 @@ import '../ui/ui.dart';
|
|
|
9
9
|
/// `flutter_ota_kit keys` — generate an Ed25519 keypair for bundle signing.
|
|
10
10
|
class KeysCommand extends FlutterPatcherCommand {
|
|
11
11
|
KeysCommand() {
|
|
12
|
-
argParser.addFlag(
|
|
12
|
+
argParser.addFlag(
|
|
13
|
+
'save',
|
|
14
|
+
help: 'Persist the public key into the project config.',
|
|
15
|
+
);
|
|
13
16
|
}
|
|
14
17
|
|
|
15
18
|
@override
|
|
@@ -39,11 +42,10 @@ class KeysCommand extends FlutterPatcherCommand {
|
|
|
39
42
|
final file = configCandidates().first;
|
|
40
43
|
final json =
|
|
41
44
|
file.existsSync() && file.readAsStringSync().trim().isNotEmpty
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
? (jsonDecode(file.readAsStringSync()) as Map<String, dynamic>)
|
|
46
|
+
: <String, dynamic>{};
|
|
44
47
|
writePath(json, 'publicKey', publicB64);
|
|
45
|
-
await steps.run<void>('Saving public key to ${file.path}',
|
|
46
|
-
() async {
|
|
48
|
+
await steps.run<void>('Saving public key to ${file.path}', () async {
|
|
47
49
|
_save(json);
|
|
48
50
|
});
|
|
49
51
|
}
|
|
@@ -12,9 +12,13 @@ import '../ui/ui.dart';
|
|
|
12
12
|
class MigrateCommand extends FlutterPatcherCommand {
|
|
13
13
|
MigrateCommand({this.config, this.backendOverride}) {
|
|
14
14
|
final detected = config?.provider ?? loadConfig()?.provider;
|
|
15
|
-
argParser.addOption(
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
argParser.addOption(
|
|
16
|
+
'backend',
|
|
17
|
+
abbr: 'b',
|
|
18
|
+
help: detected != null
|
|
19
|
+
? 'Backend provider [detected: $detected].'
|
|
20
|
+
: 'Backend provider.',
|
|
21
|
+
);
|
|
18
22
|
argParser.addOption(
|
|
19
23
|
'database-url',
|
|
20
24
|
help: 'Postgres connection string (or DATABASE_URL env).',
|
|
@@ -114,12 +118,17 @@ class MigrateCommand extends FlutterPatcherCommand {
|
|
|
114
118
|
@override
|
|
115
119
|
Future<int> run() => runGuarded(() async {
|
|
116
120
|
final cfg = effectiveConfig(config ?? loadConfig(), argResults!);
|
|
117
|
-
final provider =
|
|
121
|
+
final provider =
|
|
122
|
+
argResults!['backend'] as String? ?? cfg?.provider ?? 'supabase';
|
|
118
123
|
|
|
119
124
|
if (provider == 'aws') {
|
|
120
125
|
banner('migrate · aws');
|
|
121
|
-
step(
|
|
122
|
-
|
|
126
|
+
step(
|
|
127
|
+
'AWS stores bundle metadata as JSON in S3 — no SQL migrations needed.',
|
|
128
|
+
);
|
|
129
|
+
step(
|
|
130
|
+
'The S3 bucket and object prefix are created automatically on first deploy.',
|
|
131
|
+
);
|
|
123
132
|
step('No action required. Run `flutter-ota deploy` to get started.');
|
|
124
133
|
return;
|
|
125
134
|
}
|
|
@@ -176,7 +185,8 @@ class MigrateCommand extends FlutterPatcherCommand {
|
|
|
176
185
|
}
|
|
177
186
|
|
|
178
187
|
if (provider == 'cloudflare') {
|
|
179
|
-
final cfCfg =
|
|
188
|
+
final cfCfg =
|
|
189
|
+
cfg ??
|
|
180
190
|
FlutterPatcherConfig(
|
|
181
191
|
provider: 'cloudflare',
|
|
182
192
|
supabase: const SupabaseConfigJson(),
|
|
@@ -218,7 +228,8 @@ class MigrateCommand extends FlutterPatcherCommand {
|
|
|
218
228
|
}
|
|
219
229
|
|
|
220
230
|
if (provider == 'supabase') {
|
|
221
|
-
final sbCfg =
|
|
231
|
+
final sbCfg =
|
|
232
|
+
cfg ??
|
|
222
233
|
FlutterPatcherConfig(
|
|
223
234
|
provider: 'supabase',
|
|
224
235
|
supabase: const SupabaseConfigJson(),
|
|
@@ -289,9 +300,7 @@ class MigrateCommand extends FlutterPatcherCommand {
|
|
|
289
300
|
);
|
|
290
301
|
sw.stop();
|
|
291
302
|
if (res.statusCode >= 400) {
|
|
292
|
-
steps.fail(
|
|
293
|
-
'${p.basename(file.path)} (${res.statusCode}): ${res.body}',
|
|
294
|
-
);
|
|
303
|
+
steps.fail('${p.basename(file.path)} (${res.statusCode}): ${res.body}');
|
|
295
304
|
} else {
|
|
296
305
|
final ms = sw.elapsedMilliseconds;
|
|
297
306
|
final time = ms >= 1000
|
|
@@ -341,9 +350,7 @@ class MigrateCommand extends FlutterPatcherCommand {
|
|
|
341
350
|
}
|
|
342
351
|
}
|
|
343
352
|
final ms = sw.elapsedMilliseconds;
|
|
344
|
-
final time = ms >= 1000
|
|
345
|
-
? '${(ms / 1000).toStringAsFixed(1)}s'
|
|
346
|
-
: '${ms}ms';
|
|
353
|
+
final time = ms >= 1000 ? '${(ms / 1000).toStringAsFixed(1)}s' : '${ms}ms';
|
|
347
354
|
steps.success('Ensured storage bucket "${storage.bucketName}" in $time');
|
|
348
355
|
}
|
|
349
356
|
|
|
@@ -483,8 +490,9 @@ class MigrateCommand extends FlutterPatcherCommand {
|
|
|
483
490
|
return;
|
|
484
491
|
}
|
|
485
492
|
final ms = sw.elapsedMilliseconds;
|
|
486
|
-
final time =
|
|
487
|
-
|
|
493
|
+
final time = ms >= 1000
|
|
494
|
+
? '${(ms / 1000).toStringAsFixed(1)}s'
|
|
495
|
+
: '${ms}ms';
|
|
488
496
|
steps.success('Created D1 database ($dbId) in $time');
|
|
489
497
|
} else {
|
|
490
498
|
steps.success('Using existing D1 database ($dbId)');
|
|
@@ -507,8 +515,9 @@ class MigrateCommand extends FlutterPatcherCommand {
|
|
|
507
515
|
steps.fail('${p.basename(file.path)} ($res.statusCode): $msg');
|
|
508
516
|
} else {
|
|
509
517
|
final ms = sw.elapsedMilliseconds;
|
|
510
|
-
final time =
|
|
511
|
-
|
|
518
|
+
final time = ms >= 1000
|
|
519
|
+
? '${(ms / 1000).toStringAsFixed(1)}s'
|
|
520
|
+
: '${ms}ms';
|
|
512
521
|
steps.success('Applied ${p.basename(file.path)} in $time');
|
|
513
522
|
}
|
|
514
523
|
}
|
|
@@ -530,14 +539,16 @@ class MigrateCommand extends FlutterPatcherCommand {
|
|
|
530
539
|
steps.fail('Could not create R2 bucket "$r2Bucket": $msg');
|
|
531
540
|
} else {
|
|
532
541
|
final ms = sw.elapsedMilliseconds;
|
|
533
|
-
final time =
|
|
534
|
-
|
|
542
|
+
final time = ms >= 1000
|
|
543
|
+
? '${(ms / 1000).toStringAsFixed(1)}s'
|
|
544
|
+
: '${ms}ms';
|
|
535
545
|
steps.success('Ensured R2 bucket "$r2Bucket" in $time');
|
|
536
546
|
}
|
|
537
547
|
} else {
|
|
538
548
|
final ms = sw.elapsedMilliseconds;
|
|
539
|
-
final time =
|
|
540
|
-
|
|
549
|
+
final time = ms >= 1000
|
|
550
|
+
? '${(ms / 1000).toStringAsFixed(1)}s'
|
|
551
|
+
: '${ms}ms';
|
|
541
552
|
steps.success('Created R2 bucket "$r2Bucket" in $time');
|
|
542
553
|
}
|
|
543
554
|
|