the-tip-top-frontend/services/api.ts
soufiane 636780870d fix: change headers type from HeadersInit to Record<string, string>
Replace HeadersInit type with Record<string, string> for headers object to allow index access with bracket notation. This resolves the TypeScript error "Property 'Authorization' does not exist on type 'HeadersInit'".

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 02:01:53 +01:00

150 lines
3.6 KiB
TypeScript

import { API_BASE_URL } from '@/utils/constants';
import { getToken } from '@/utils/helpers';
export interface FetchOptions extends RequestInit {
token?: string;
}
export class ApiError extends Error {
constructor(
public status: number,
message: string,
public data?: any
) {
super(message);
this.name = 'ApiError';
}
}
async function fetchWithAuth(
endpoint: string,
options: FetchOptions = {}
): Promise<Response> {
const token = options.token || getToken();
// Logs de debug
console.log('🔐 [API] Préparation de la requête:', {
endpoint,
hasToken: !!token,
tokenPreview: token ? `${token.substring(0, 20)}...` : 'Aucun',
});
const headers: Record<string, string> = {
'Content-Type': 'application/json',
...options.headers as Record<string, string>,
};
if (token) {
headers['Authorization'] = `Bearer ${token}`;
console.log('✅ [API] Header Authorization ajouté');
} else {
console.warn('⚠️ [API] Aucun token disponible - requête sans authentification');
}
const config: RequestInit = {
...options,
headers,
};
const url = endpoint.startsWith('http') ? endpoint : `${API_BASE_URL}${endpoint}`;
console.log('📡 [API] Envoi de la requête:', {
url,
method: config.method || 'GET',
headers: headers,
body: options.body,
});
try {
const response = await fetch(url, config);
if (!response.ok) {
let errorMessage = 'Une erreur est survenue';
let errorData;
try {
errorData = await response.json();
errorMessage = errorData.message || errorData.error || errorMessage;
console.error('❌ [API] Erreur du serveur:', {
status: response.status,
statusText: response.statusText,
errorData,
errorMessage,
});
} catch {
errorMessage = response.statusText || errorMessage;
console.error('❌ [API] Erreur sans JSON:', {
status: response.status,
statusText: response.statusText,
});
}
throw new ApiError(response.status, errorMessage, errorData);
}
return response;
} catch (error) {
if (error instanceof ApiError) {
throw error;
}
throw new ApiError(0, 'Erreur de connexion au serveur');
}
}
export const api = {
get: async <T>(endpoint: string, options?: FetchOptions): Promise<T> => {
const response = await fetchWithAuth(endpoint, {
...options,
method: 'GET',
});
return response.json();
},
post: async <T>(
endpoint: string,
data?: any,
options?: FetchOptions
): Promise<T> => {
const response = await fetchWithAuth(endpoint, {
...options,
method: 'POST',
body: data ? JSON.stringify(data) : undefined,
});
return response.json();
},
put: async <T>(
endpoint: string,
data?: any,
options?: FetchOptions
): Promise<T> => {
const response = await fetchWithAuth(endpoint, {
...options,
method: 'PUT',
body: data ? JSON.stringify(data) : undefined,
});
return response.json();
},
patch: async <T>(
endpoint: string,
data?: any,
options?: FetchOptions
): Promise<T> => {
const response = await fetchWithAuth(endpoint, {
...options,
method: 'PATCH',
body: data ? JSON.stringify(data) : undefined,
});
return response.json();
},
delete: async <T>(endpoint: string, options?: FetchOptions): Promise<T> => {
const response = await fetchWithAuth(endpoint, {
...options,
method: 'DELETE',
});
return response.json();
},
};