import type { MigrationProgress, ServerDescription, VerificationChannel, } from "../migration/types.ts"; import type { AtprotoClient } from "../migration/atproto-client.ts"; export function createInitialProgress(): MigrationProgress { return { repoExported: false, repoImported: false, blobsTotal: 0, blobsMigrated: 0, blobsFailed: [], prefsMigrated: false, plcSigned: false, activated: false, deactivated: false, currentOperation: "", }; } export async function checkHandleAvailabilityViaClient( client: AtprotoClient, handle: string, ): Promise { try { await client.resolveHandle(handle); return false; } catch { return true; } } export function resolveVerificationIdentifier( channel: VerificationChannel, email: string, discordUsername: string, telegramUsername: string, signalUsername: string, ): string { switch (channel) { case "email": return email; case "discord": return discordUsername; case "telegram": return telegramUsername; case "signal": return signalUsername; } } export async function loadServerInfo( client: AtprotoClient, cached: ServerDescription | null, ): Promise { if (cached) return cached; return client.describeServer(); } export async function finalizeAccountMigration( sourceClient: Pick, destinationClient: Pick, options: { sourceAlreadyDeactivated?: boolean; onSourceDeactivated?: () => void; onSourceDeactivationFailed?: (error: unknown) => void; sourceDeactivationRetryDelayMs?: number; } = {}, ): Promise { if (!options.sourceAlreadyDeactivated) { const maxAttempts = 3; const retryDelayMs = options.sourceDeactivationRetryDelayMs ?? 500; let lastError: unknown; for (let attempt = 1; attempt <= maxAttempts; attempt += 1) { try { await sourceClient.deactivateAccount(); options.onSourceDeactivated?.(); lastError = undefined; break; } catch (error) { lastError = error; if (attempt < maxAttempts && retryDelayMs > 0) { await new Promise((resolve) => setTimeout(resolve, retryDelayMs * attempt) ); } } } if (lastError !== undefined) { options.onSourceDeactivationFailed?.(lastError); } } await destinationClient.activateAccount(); }