/** * Creator Studio 的 REST 访问层。 * * 所有请求都带 `X-WP-Nonce`;服务端仍以 Jio 能力矩阵与文章归属做最终判定。 * * @package Jio */ export type ApiError = Error & { status?: number; code?: string; data?: unknown }; function toError(payload: any, status: number): ApiError { const message = (payload && (payload.message || payload.error)) || (status === 401 ? '登录状态已失效,请刷新页面重新登录。' : '请求失败,请稍后重试。'); const error = new Error(String(message)) as ApiError; error.status = status; error.code = payload && payload.code ? String(payload.code) : ''; error.data = payload; return error; } async function readJson(response: Response): Promise { try { return await response.json(); } catch (error) { return null; } } export async function apiGet(url: string, nonce: string): Promise { const response = await fetch(url, { credentials: 'same-origin', headers: { 'X-WP-Nonce': nonce }, }); const payload = await readJson(response); if (!response.ok) { throw toError(payload, response.status); } return payload; } export async function apiPost(url: string, body: Record, nonce: string): Promise { const response = await fetch(url, { method: 'POST', credentials: 'same-origin', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': nonce, }, body: JSON.stringify(body), }); const payload = await readJson(response); if (!response.ok) { throw toError(payload, response.status); } return payload; } export async function apiUpload(url: string, file: File, nonce: string, fields: Record = {}): Promise { const body = new FormData(); body.append('file', file); Object.entries(fields).forEach(([key, value]) => body.append(key, value)); const response = await fetch(url, { method: 'POST', credentials: 'same-origin', headers: { 'X-WP-Nonce': nonce }, body, }); const payload = await readJson(response); if (!response.ok) { throw toError(payload, response.status); } return payload; } export const wpJson = (value: unknown): string => JSON.stringify(value);