Download apps/web/src/api/client.ts from hunian003/message: direct link, hf CLI and curl.
- Browser
- Download file 3.21 kB
-
https://huggingface.co/spaces/hunian003/message/resolve/main/apps/web/src/api/client.ts
- Command line
-
hf download hf://spaces/hunian003/message/apps/web/src/api/client.ts
-
curl -L -o client.ts https://huggingface.co/spaces/hunian003/message/resolve/main/apps/web/src/api/client.ts
3.21 kB
| import { ApiError } from '@typings/api'; | |
| const BASE_URL = '/api'; | |
| const DEFAULT_TIMEOUT = 30000; | |
| interface RequestOptions { | |
| method?: 'GET' | 'POST' | 'PUT' | 'DELETE'; | |
| body?: unknown; | |
| headers?: Record<string, string>; | |
| timeout?: number; | |
| } | |
| class ApiClient { | |
| private baseUrl: string; | |
| constructor(baseUrl: string = BASE_URL) { | |
| this.baseUrl = baseUrl; | |
| } | |
| private async handleResponse<T>(response: Response): Promise<T> { | |
| if (!response.ok) { | |
| let errorMessage = '请求失败'; | |
| if (response.status === 401) { | |
| errorMessage = '未授权,请重新登录'; | |
| } else if (response.status === 403) { | |
| errorMessage = '没有权限执行此操作'; | |
| } else if (response.status === 404) { | |
| errorMessage = '请求的资源不存在'; | |
| } else if (response.status >= 500) { | |
| errorMessage = '服务器错误,请稍后重试'; | |
| } else { | |
| try { | |
| const errorData = await response.json(); | |
| errorMessage = errorData.detail || errorData.message || errorMessage; | |
| } catch { | |
| // 无法解析错误详情 | |
| } | |
| } | |
| throw new ApiError(response.status, errorMessage); | |
| } | |
| const contentType = response.headers.get('content-type'); | |
| if (contentType?.includes('application/json')) { | |
| return response.json(); | |
| } | |
| return {} as T; | |
| } | |
| async request<T>(path: string, options: RequestOptions = {}): Promise<T> { | |
| const { method = 'GET', body, headers = {}, timeout = DEFAULT_TIMEOUT } = options; | |
| const controller = new AbortController(); | |
| const timeoutId = setTimeout(() => controller.abort(), timeout); | |
| const config: RequestInit = { | |
| method, | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| ...headers, | |
| }, | |
| signal: controller.signal, | |
| }; | |
| if (body && method !== 'GET') { | |
| config.body = JSON.stringify(body); | |
| } | |
| try { | |
| const response = await fetch(`${this.baseUrl}${path}`, config); | |
| clearTimeout(timeoutId); | |
| return this.handleResponse<T>(response); | |
| } catch (error) { | |
| clearTimeout(timeoutId); | |
| if (error && typeof error === 'object' && 'name' in error && error.name === 'AbortError') { | |
| throw new ApiError(0, '请求超时,请检查网络连接'); | |
| } | |
| if (!error || typeof error !== 'object' || !('status' in error) || !error.status) { | |
| throw new ApiError(0, '网络错误,请检查网络连接'); | |
| } | |
| throw error; | |
| } | |
| } | |
| async get<T>(path: string): Promise<T> { | |
| return this.request<T>(path); | |
| } | |
| async post<T>(path: string, body?: unknown): Promise<T> { | |
| return this.request<T>(path, { method: 'POST', body }); | |
| } | |
| async put<T>(path: string, body?: unknown): Promise<T> { | |
| return this.request<T>(path, { method: 'PUT', body }); | |
| } | |
| async delete<T>(path: string): Promise<T> { | |
| return this.request<T>(path, { method: 'DELETE' }); | |
| } | |
| async upload<T>(path: string, formData: FormData): Promise<T> { | |
| const response = await fetch(`${this.baseUrl}${path}`, { | |
| method: 'POST', | |
| body: formData, | |
| }); | |
| return this.handleResponse<T>(response); | |
| } | |
| } | |
| export const apiClient = new ApiClient(); |