fix some bugs
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
const TOKEN_KEY = 'ft_access_token'
|
||||
|
||||
export function getApiBaseUrl(): string {
|
||||
return (import.meta.env.VITE_API_BASE_URL as string | undefined)?.replace(/\/$/, '')
|
||||
|| 'https://parche.montech.ir/server/api'
|
||||
}
|
||||
|
||||
export function getAccessToken(): string | null {
|
||||
return localStorage.getItem(TOKEN_KEY)
|
||||
}
|
||||
|
||||
export function setAccessToken(token: string | null): void {
|
||||
if (token) localStorage.setItem(TOKEN_KEY, token)
|
||||
else localStorage.removeItem(TOKEN_KEY)
|
||||
}
|
||||
|
||||
export class ApiError extends Error {
|
||||
status: number
|
||||
constructor(status: number, message: string) {
|
||||
super(message)
|
||||
this.status = status
|
||||
}
|
||||
}
|
||||
|
||||
type RequestOptions = {
|
||||
method?: string
|
||||
body?: unknown
|
||||
auth?: boolean
|
||||
query?: Record<string, string | number | boolean | undefined | null>
|
||||
}
|
||||
|
||||
function buildUrl(path: string, query?: RequestOptions['query']): string {
|
||||
const base = getApiBaseUrl()
|
||||
const url = new URL(path.startsWith('http') ? path : `${base}${path.startsWith('/') ? '' : '/'}${path}`)
|
||||
if (query) {
|
||||
for (const [key, value] of Object.entries(query)) {
|
||||
if (value === undefined || value === null || value === '') continue
|
||||
url.searchParams.set(key, String(value))
|
||||
}
|
||||
}
|
||||
return url.toString()
|
||||
}
|
||||
|
||||
export async function apiRequest<T>(path: string, options: RequestOptions = {}): Promise<T> {
|
||||
const headers: Record<string, string> = {
|
||||
Accept: 'application/json',
|
||||
}
|
||||
if (options.body !== undefined) {
|
||||
headers['Content-Type'] = 'application/json'
|
||||
}
|
||||
if (options.auth !== false) {
|
||||
const token = getAccessToken()
|
||||
if (token) headers.Authorization = `Bearer ${token}`
|
||||
}
|
||||
|
||||
const res = await fetch(buildUrl(path, options.query), {
|
||||
method: options.method ?? (options.body !== undefined ? 'POST' : 'GET'),
|
||||
headers,
|
||||
body: options.body !== undefined ? JSON.stringify(options.body) : undefined,
|
||||
})
|
||||
|
||||
const text = await res.text()
|
||||
let data: unknown = null
|
||||
if (text) {
|
||||
try {
|
||||
data = JSON.parse(text)
|
||||
} catch {
|
||||
data = text
|
||||
}
|
||||
}
|
||||
|
||||
if (!res.ok) {
|
||||
const message =
|
||||
typeof data === 'object' && data && 'message' in data
|
||||
? Array.isArray((data as { message: unknown }).message)
|
||||
? ((data as { message: string[] }).message).join('، ')
|
||||
: String((data as { message: unknown }).message)
|
||||
: `خطای سرور (${res.status})`
|
||||
throw new ApiError(res.status, message)
|
||||
}
|
||||
|
||||
return data as T
|
||||
}
|
||||
Reference in New Issue
Block a user