Files
beenvoice-app/lib/instance-url.ts
T
soconnorandCursor 6762a9bff3 Move production to beenvoice.app with migrated accounts, refreshed auth and timer UX, and expanded invoice flows.
Official URL migration preserves sessions, shortcuts prefs, and last clock-in client; auth screens match web with legal links; time clock and invoice editor/send flows are updated for the new domain and UI patterns.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-26 03:40:48 -04:00

45 lines
1.3 KiB
TypeScript

import AsyncStorage from "@react-native-async-storage/async-storage";
import { invalidServerUrlMessage } from "@/lib/config";
const STORAGE_KEY = "beenvoice:instance-url";
export function normalizeInstanceUrl(input: string): string | null {
const trimmed = input.trim().replace(/\/$/, "");
if (!trimmed) return null;
let url = trimmed;
if (!/^https?:\/\//i.test(url)) {
const isLocal =
/^(localhost|127\.|192\.168\.|10\.|172\.(1[6-9]|2\d|3[01])\.)/i.test(url);
url = `${isLocal ? "http" : "https"}://${url}`;
}
try {
const parsed = new URL(url);
if (!parsed.hostname) return null;
return `${parsed.protocol}//${parsed.host}`;
} catch {
return null;
}
}
export async function loadStoredInstanceUrl(): Promise<string | null> {
const stored = await AsyncStorage.getItem(STORAGE_KEY);
if (!stored) return null;
return normalizeInstanceUrl(stored) ?? stored.replace(/\/$/, "");
}
export async function saveStoredInstanceUrl(url: string): Promise<string> {
const normalized = normalizeInstanceUrl(url);
if (!normalized) {
throw new Error(invalidServerUrlMessage());
}
await AsyncStorage.setItem(STORAGE_KEY, normalized);
return normalized;
}
export async function clearStoredInstanceUrl(): Promise<void> {
await AsyncStorage.removeItem(STORAGE_KEY);
}