Files
zapstore/lib/services/package_manager/installed_packages_snapshot.dart
T
2026-04-30 21:42:41 -03:00

105 lines
3.2 KiB
Dart

import 'dart:convert';
import 'dart:io';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
import 'package:zapstore/services/log_service.dart';
import 'package:zapstore/services/package_manager/package_manager.dart';
class InstalledPackagesSnapshot {
static const _fileName = 'installed_packages_snapshot.json';
static Future<File> _file() async {
final dir = await getApplicationSupportDirectory();
return File(path.join(dir.path, _fileName));
}
static Future<void> save(Map<String, PackageInfo> installed) async {
try {
final file = await _file();
final tmp = File('${file.path}.tmp');
final list = installed.values
.map(
(p) => <String, dynamic>{
'appId': p.appId,
'name': p.name,
'version': p.version,
'versionCode': p.versionCode,
'signatureHashes': p.signatureHashes,
'canInstallSilently': p.canInstallSilently,
},
)
.toList(growable: false);
final payload = jsonEncode({
'v': 1,
'savedAt': DateTime.now().millisecondsSinceEpoch,
'installed': list,
});
await tmp.writeAsString(payload, flush: true);
if (await file.exists()) {
await file.delete();
}
await tmp.rename(file.path);
} catch (e, st) {
// Best-effort snapshot only.
LogService.I.warn(
'installed packages snapshot save failed',
tag: 'package_manager',
err: e,
stack: st,
);
}
}
static Future<Map<String, PackageInfo>> load() async {
try {
final file = await _file();
if (!await file.exists()) return {};
final raw = await file.readAsString();
final decoded = jsonDecode(raw);
if (decoded is! Map) return {};
final version = decoded['v'];
if (version != null && version is! int) {
LogService.I.warn(
'installed packages snapshot: unknown schema',
tag: 'package_manager',
fields: {'version': version.toString()},
);
}
final installed = decoded['installed'];
if (installed is! List) return {};
final result = <String, PackageInfo>{};
for (final item in installed) {
if (item is! Map) continue;
final map = Map<String, dynamic>.from(item);
final appId = map['appId'] as String?;
if (appId == null || appId.isEmpty) continue;
final rawHashes = map['signatureHashes'];
final signatureHashes = rawHashes is List
? rawHashes.cast<String>().toList()
: <String>[];
result[appId] = PackageInfo(
appId: appId,
name: map['name'] as String?,
version: (map['version'] as String?) ?? '0.0.0',
versionCode: map['versionCode'] as int?,
signatureHashes: signatureHashes,
installTime: null,
canInstallSilently: (map['canInstallSilently'] as bool?) ?? false,
);
}
return result;
} catch (e, st) {
LogService.I.warn(
'installed packages snapshot load failed',
tag: 'package_manager',
err: e,
stack: st,
);
return {};
}
}
}