107 lines
No EOL
2.8 KiB
TypeScript
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' });
|
|
}; |