app/frontend/app/utils/api/apiRequest.ts

107 lines
No EOL
2.8 KiB
TypeScript

export const apiRequest = async (url: string, options: RequestInit = {}) => {
const token = localStorage.getItem('token');
const allowedRequests = [
'/api/auth/login',
'/api/auth/register',
]
if (allowedRequests.includes(url)) {
return publicRequest(url, options)
}
if (!token) {
throw new Error('No authentication token found.' + url);
}
return privateRequest(url, token, options);
};
export const publicRequest = async (url: string, options: RequestInit = {}) => {
console.log('→ Sending request', url, options.method);
url = 'http://localhost' + url;
const response = await fetch(url, {
headers: {
'Content-Type': 'application/json',
...(options.headers || {}),
},
...options,
});
if (!response.ok) {
throw new Error(`HTTP Error: ${response.status} ${response.statusText}`);
}
return response.json();
}
export const privateRequest = async (fullUrl: string, token: string, options: RequestInit = {}) => {
const headers = {
...(options.headers || {}),
Authorization: `Bearer ${token}`,
};
const url = `${process.env.NEXT_PUBLIC_API_URL}${fullUrl}`;
const response = await fetch(url, { headers, ...options });
// Authentication failure - token invalid - redirect to login
if (response.status === 401) {
localStorage.removeItem('token');
localStorage.removeItem('refreshToken');
window.location.href = '/login';
throw new Error('Unauthorized. Redirecting to login.');
}
if (!response.ok) {
throw new Error(`HTTP Error: ${response.status} ${response.statusText}`);
}
return response.json();
}
// Add shorthand HTTP methods
apiRequest.get = (url: string, options: RequestInit = {}) => {
return apiRequest(url, { ...options, method: 'GET' });
};
apiRequest.post = <TBody extends Record<string, unknown> | undefined>(
url: string,
body: TBody,
options: RequestInit = {},
) => {
return apiRequest(url, {
...options,
method: 'POST',
headers: {
'Content-Type': 'application/json',
...(options.headers || {}),
},
body: body ? JSON.stringify(body) : undefined,
});
};
apiRequest.put = <TBody extends Record<string, unknown> | undefined>(
url: string,
body: TBody,
options: RequestInit = {}
) => {
return apiRequest(url, {
...options,
method: 'PUT',
headers: {
'Content-Type': 'application/json',
...(options.headers || {}),
},
body: body ? JSON.stringify(body) : undefined,
});
};
apiRequest.delete = (url: string, options: RequestInit = {}) => {
return apiRequest(url, { ...options, method: 'DELETE' });
};