37 lines
1.4 KiB
TypeScript
37 lines
1.4 KiB
TypeScript
'use client';
|
|
|
|
interface ApiOptions { method?: string; headers?: Record<string,string>; body?: unknown }
|
|
|
|
export async function apiRequest<T = unknown>(path: string, options: ApiOptions = {}): Promise<T> {
|
|
const token = typeof window === 'undefined' ? null : localStorage.getItem('pk_token');
|
|
const headers: Record<string,string> = { Accept: 'application/json', ...(options.headers || {}) };
|
|
if (options.body !== undefined) headers['Content-Type'] = 'application/json';
|
|
if (token) headers.Authorization = `Bearer ${token}`;
|
|
const response = await fetch(path, {
|
|
method: options.method || 'GET',
|
|
headers,
|
|
body: options.body === undefined ? undefined : JSON.stringify(options.body),
|
|
cache: 'no-store'
|
|
});
|
|
const data = await response.json().catch(() => ({}));
|
|
if (!response.ok) {
|
|
const detail = typeof data.detail === 'string' ? data.detail : '请求失败';
|
|
throw new Error(detail);
|
|
}
|
|
return data as T;
|
|
}
|
|
|
|
export async function ensureLogin(): Promise<void> {
|
|
if (localStorage.getItem('pk_token')) return;
|
|
let previewId = localStorage.getItem('pk_preview_id');
|
|
if (!previewId) {
|
|
previewId = `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`;
|
|
localStorage.setItem('pk_preview_id', previewId);
|
|
}
|
|
const session = await apiRequest<{ token: string }>('/api/v1/auth/xhs', {
|
|
method: 'POST',
|
|
body: { app_key: 'hub', code: `dev:web-${previewId}` }
|
|
});
|
|
localStorage.setItem('pk_token', session.token);
|
|
}
|