Form prototype
This commit is contained in:
161
src/Form/utils/fetchClient.ts
Normal file
161
src/Form/utils/fetchClient.ts
Normal file
@@ -0,0 +1,161 @@
|
||||
export interface FetchOptions extends RequestInit {
|
||||
params?: Record<string, any>
|
||||
timeout?: number
|
||||
}
|
||||
|
||||
export interface FetchResponse<T = any> {
|
||||
data: T
|
||||
status: number
|
||||
statusText: string
|
||||
ok: boolean
|
||||
error?: string
|
||||
}
|
||||
|
||||
export class FetchError extends Error {
|
||||
constructor(
|
||||
public message: string,
|
||||
public status?: number,
|
||||
public response?: any
|
||||
) {
|
||||
super(message)
|
||||
this.name = 'FetchError'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch wrapper with timeout support and axios-like interface
|
||||
*/
|
||||
async function fetchWithTimeout(
|
||||
url: string,
|
||||
options: FetchOptions = {}
|
||||
): Promise<Response> {
|
||||
const { timeout = 30000, ...fetchOptions } = options
|
||||
|
||||
const controller = new AbortController()
|
||||
const timeoutId = setTimeout(() => controller.abort(), timeout)
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
...fetchOptions,
|
||||
signal: controller.signal,
|
||||
})
|
||||
clearTimeout(timeoutId)
|
||||
return response
|
||||
} catch (error) {
|
||||
clearTimeout(timeoutId)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GET request
|
||||
*/
|
||||
export async function get<T = any>(
|
||||
url: string,
|
||||
options?: FetchOptions
|
||||
): Promise<FetchResponse<T>> {
|
||||
try {
|
||||
const response = await fetchWithTimeout(url, {
|
||||
...options,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...options?.headers,
|
||||
},
|
||||
})
|
||||
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
data,
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
ok: response.ok,
|
||||
error: response.ok ? undefined : data?.message || data?.error || response.statusText,
|
||||
}
|
||||
} catch (error) {
|
||||
throw new FetchError(
|
||||
error instanceof Error ? error.message : 'Network request failed',
|
||||
undefined,
|
||||
error
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* POST request
|
||||
*/
|
||||
export async function post<T = any>(
|
||||
url: string,
|
||||
data?: any,
|
||||
options?: FetchOptions
|
||||
): Promise<FetchResponse<T>> {
|
||||
try {
|
||||
const response = await fetchWithTimeout(url, {
|
||||
...options,
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...options?.headers,
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
})
|
||||
|
||||
const responseData = await response.json()
|
||||
|
||||
return {
|
||||
data: responseData,
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
ok: response.ok,
|
||||
error: response.ok ? undefined : responseData?.message || responseData?.error || response.statusText,
|
||||
}
|
||||
} catch (error) {
|
||||
throw new FetchError(
|
||||
error instanceof Error ? error.message : 'Network request failed',
|
||||
undefined,
|
||||
error
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE request
|
||||
*/
|
||||
export async function del<T = any>(
|
||||
url: string,
|
||||
options?: FetchOptions
|
||||
): Promise<FetchResponse<T>> {
|
||||
try {
|
||||
const response = await fetchWithTimeout(url, {
|
||||
...options,
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...options?.headers,
|
||||
},
|
||||
})
|
||||
|
||||
const data = await response.json().catch(() => ({}))
|
||||
|
||||
return {
|
||||
data,
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
ok: response.ok,
|
||||
error: response.ok ? undefined : data?.message || data?.error || response.statusText,
|
||||
}
|
||||
} catch (error) {
|
||||
throw new FetchError(
|
||||
error instanceof Error ? error.message : 'Network request failed',
|
||||
undefined,
|
||||
error
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export const fetchClient = {
|
||||
get,
|
||||
post,
|
||||
delete: del,
|
||||
}
|
||||
Reference in New Issue
Block a user