registerApk method
Implementation
Future<RegisterResult> registerApk({
required Dio dio,
required String packageName,
required String version,
required String storagePath,
required int fileSize,
required String projectType,
String? flavor,
}) async {
try {
final regResp = await dio.post(
Endpoints.uploadApk,
data: {
'packageName': packageName,
'version': version,
'storagePath': storagePath,
'size': fileSize,
},
);
final data = regResp.data['data'] as Map<String, dynamic>?;
final downloadUrl = (data?['downloadUrl'] as String?) ?? '';
final rolled = data?['rolledOver'] as List?;
final rolledOver = rolled == null
? const <Map<String, dynamic>>[]
: rolled
.whereType<Map>()
.map((m) => m.map((k, v) => MapEntry(k.toString(), v)))
.toList();
return RegisterResult(downloadUrl: downloadUrl, rolledOver: rolledOver);
} on DioException catch (e) {
final status = e.response?.statusCode;
final code = e.response?.data?['code'] as String?;
final msg = e.response?.data?['message'] as String? ??
e.message ??
'Unknown error';
if (status == 403 && code == 'PLAN_LIMIT') {
CliAnalytics.ins.logPlanLimitHit(projectType: projectType);
AppLogger.error(
'Upload blocked — you\'ve reached your APK limit for this app.',
);
AppLogger.error(
'Free plan: 5 APKs per app. Upgrade in the AppFlight mobile app.',
);
AppLogger.error('Settings → Subscription → Upgrade to First Class');
AppLogger.debug('Raw response: ${e.response?.data}');
exit(ExitCodes.planLimit);
}
CliAnalytics.ins.logUploadFailed(
errorCode: 'metadata_failed',
projectType: projectType,
flavor: flavor,
);
AppLogger.error('Metadata registration failed: $msg');
exit(ExitCodes.storageFailed);
}
}