import '../dto/backend.dart'; import '../models/auth.dart'; import '../models/session.dart'; import '../models/two_factor.dart'; import '../models/verification.dart'; abstract final class BackendMapper { static AuthResult signup(BackendDTO dto) { if (dto.userId.isEmpty) throw const FormatException('Missing user'); return AuthResult(userId: dto.userId, isSimulated: false); } static FactorChallenge challenge(BackendDTO dto, String id) { if (dto.challengeId.isEmpty || dto.channel != 'email') { throw const FactorException(FactorError.unavailable); } return FactorChallenge( id: id, purpose: FactorPurpose.login, operation: id, target: dto.target, expiresAt: dto.expiresAt, resendAt: dto.resendAt, ); } static AuthSession session(BackendDTO dto) { if (dto.accessToken.isEmpty || dto.userId.isEmpty) { throw const FormatException('Missing session'); } return AuthSession(dto.userId, dto.accessToken, dto.refreshToken); } static AuthException authFailure(int status, BackendDTO dto) => AuthException(switch (dto.error) { 'email_in_use' => AuthError.emailInUse, 'signup_attention_required' => AuthError.signupNeedsAssistance, 'account_not_verified' => AuthError.accountNotVerified, _ when status == 401 => AuthError.invalidCredentials, _ when status == 429 => AuthError.factorCooldown, _ => AuthError.unavailable, }); static VerificationException verificationFailure(BackendDTO dto) => VerificationException(switch (dto.error) { 'expired' => VerificationError.expired, 'invalid' => VerificationError.invalid, 'signup_attention_required' => VerificationError.needsAssistance, _ => VerificationError.internal, }); static FactorException factorFailure(int status, BackendDTO dto) => FactorException(switch (dto.error) { 'expired' => FactorError.expired, 'locked' => FactorError.locked, 'invalid' => FactorError.invalid, _ when status == 429 => FactorError.cooldown, _ when status == 401 => FactorError.expired, _ => FactorError.unavailable, }); }