Files
fabric_trade_admin/src/services/http.ts
T

87 lines
2.5 KiB
TypeScript
Raw Normal View History

2026-08-06 17:12:28 +03:30
const TOKEN_KEY = 'fabric-admin-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) ?? sessionStorage.getItem(TOKEN_KEY)
}
export function setAccessToken(token: string | null, remember = true): void {
localStorage.removeItem(TOKEN_KEY)
sessionStorage.removeItem(TOKEN_KEY)
if (!token) return
if (remember) localStorage.setItem(TOKEN_KEY, token)
else sessionStorage.setItem(TOKEN_KEY, token)
}
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
}