113 lines
2.6 KiB
TypeScript
113 lines
2.6 KiB
TypeScript
import type {
|
|
Task,
|
|
CreateTaskRequest,
|
|
UpdateTaskRequest,
|
|
ApiError,
|
|
} from '~/types/task'
|
|
|
|
const API_BASE_URL = '/api'
|
|
|
|
class ApiClient {
|
|
private async fetchWrapper<T>(
|
|
endpoint: string,
|
|
options: RequestInit = {}
|
|
): Promise<T> {
|
|
const url = `${API_BASE_URL}${endpoint}`
|
|
|
|
const config: RequestInit = {
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
...options.headers,
|
|
},
|
|
...options,
|
|
}
|
|
|
|
if (process.env.NODE_ENV === 'development') {
|
|
console.log(`API Request: ${config.method || 'GET'} ${url}`, {
|
|
body: config.body,
|
|
headers: config.headers,
|
|
})
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(url, config)
|
|
|
|
if (process.env.NODE_ENV === 'development') {
|
|
console.log(`API Response: ${response.status} ${response.statusText}`, {
|
|
url,
|
|
status: response.status,
|
|
})
|
|
}
|
|
|
|
if (!response.ok) {
|
|
let errorMessage = `HTTP ${response.status}: ${response.statusText}`
|
|
|
|
try {
|
|
const errorData = await response.json()
|
|
errorMessage = errorData.message || errorMessage
|
|
} catch {
|
|
// If JSON parsing fails, use the default error message
|
|
}
|
|
|
|
throw new Error(errorMessage)
|
|
}
|
|
|
|
if (response.status === 204) {
|
|
return null as T
|
|
}
|
|
|
|
const data = await response.json()
|
|
|
|
if (process.env.NODE_ENV === 'development') {
|
|
console.log('API Response Data:', data)
|
|
}
|
|
|
|
return data
|
|
} catch (error) {
|
|
const apiError: ApiError = {
|
|
message:
|
|
error instanceof Error ? error.message : 'Unknown error occurred',
|
|
status:
|
|
error instanceof Error && 'status' in error
|
|
? (error as { status?: number }).status
|
|
: undefined,
|
|
}
|
|
|
|
if (process.env.NODE_ENV === 'development') {
|
|
console.error('API Error:', apiError)
|
|
}
|
|
|
|
throw apiError
|
|
}
|
|
}
|
|
|
|
async listTasks(): Promise<Task[]> {
|
|
return this.fetchWrapper<Task[]>('/tasks')
|
|
}
|
|
|
|
async getTask(id: string): Promise<Task> {
|
|
return this.fetchWrapper<Task>(`/tasks/${id}`)
|
|
}
|
|
|
|
async createTask(data: CreateTaskRequest): Promise<Task> {
|
|
return this.fetchWrapper<Task>('/tasks', {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
})
|
|
}
|
|
|
|
async updateTask(id: string, data: UpdateTaskRequest): Promise<Task> {
|
|
return this.fetchWrapper<Task>(`/tasks/${id}`, {
|
|
method: 'PUT',
|
|
body: JSON.stringify(data),
|
|
})
|
|
}
|
|
|
|
async deleteTask(id: string): Promise<void> {
|
|
return this.fetchWrapper<void>(`/tasks/${id}`, {
|
|
method: 'DELETE',
|
|
})
|
|
}
|
|
}
|
|
|
|
export const apiClient = new ApiClient()
|