50 lines
1.3 KiB
TypeScript

import Constants from 'expo-constants';
import { supabase } from './supabase';
const apiUrl = Constants.expoConfig?.extra?.apiUrl as string;
type FetchOptions = Omit<RequestInit, 'body'> & {
body?: any;
};
/**
* Wrapper für Backend-API-Calls mit automatischem Auth-Token.
* Pendant zum Nuxt-`useSafeFetch` aus apps/rebreak/.
*
* Backend antwortet mit { success, data, status } — wir entpacken `data`.
*/
export async function apiFetch<T = any>(
path: string,
options: FetchOptions = {}
): Promise<T> {
const session = (await supabase.auth.getSession()).data.session;
const headers: Record<string, string> = {
'Content-Type': 'application/json',
...(options.headers as Record<string, string>),
};
if (session?.access_token) {
headers.Authorization = `Bearer ${session.access_token}`;
}
const res = await fetch(`${apiUrl}${path}`, {
...options,
headers,
body: options.body ? JSON.stringify(options.body) : undefined,
});
if (!res.ok) {
const text = await res.text();
throw new Error(`API ${res.status}: ${text}`);
}
const json = await res.json();
// Unwrap { success, data, status } — siehe useSafeFetch-Pattern in der Vue-App
if (json && typeof json === 'object' && 'success' in json && 'data' in json) {
return json.data as T;
}
return json as T;
}