Files
OpenFlare/atsf_server/web/lib/api/client.ts
T
ryan 4f8970ff5c feat: add user management features including user creation, editing, and role management
- Implemented user API functions for fetching, creating, updating, and managing users.
- Created a UsersPage component for displaying and managing users with search and pagination.
- Added types for user data and mutation payloads.
- Introduced a LegacyRouteRedirect component for handling legacy routes.
- Defined settings-related types for better type safety in settings management.
2026-03-11 15:40:41 +08:00

54 lines
1.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { publicEnv } from '@/lib/env/public-env';
import type { ApiEnvelope } from '@/types/api';
export class ApiError extends Error {
constructor(
message: string,
public readonly status: number,
) {
super(message);
this.name = 'ApiError';
}
}
export function getApiUrl(path: string) {
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
return `${publicEnv.apiBaseUrl}${normalizedPath}`;
}
export async function apiRequest<T>(path: string, init?: RequestInit) {
const headers = new Headers(init?.headers ?? {});
if (!(init?.body instanceof FormData) && !headers.has('Content-Type')) {
headers.set('Content-Type', 'application/json');
}
const response = await fetch(getApiUrl(path), {
credentials: 'include',
headers,
...init,
});
let payload: ApiEnvelope<T> | null = null;
try {
payload = (await response.json()) as ApiEnvelope<T>;
} catch {
payload = null;
}
if (!response.ok) {
throw new ApiError(payload?.message || `请求失败(${response.status})`, response.status);
}
if (!payload) {
throw new ApiError('响应格式无效', response.status);
}
if (!payload.success) {
throw new ApiError(payload.message || '请求失败', response.status);
}
return payload.data;
}