import { ARTALK_SERVER, ARTALK_SITE } from "./config"; // Artalk API v2 types export interface ArtalkComment { id: number; content: string; nick: string; email: string; page_key: string; page_title: string; user_id: number; ua: string; ip: string; is_collapsed: boolean; is_pending: boolean; is_pinned: boolean; vote_up: number; vote_down: number; rid: number; date: string; updated_at: string; badge_word?: string; is_allow_reply?: boolean; children?: ArtalkComment[]; } export interface ArtalkPage { id: number; admin_only: boolean; key: string; title: string; url: string; view: number; comment_count: number; date: string; } let authToken: string | null = null; export function setAuthToken(token: string | null) { authToken = token; } export function getAuthToken(): string | null { return authToken; } export async function login( email: string, password: string ): Promise<{ token: string; user: { name: string; email: string } }> { const url = `${ARTALK_SERVER}/api/v2/auth/email/login`; const res = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email, password }), }); const json = await res.json(); if (!json || !json.token) { throw new Error(json.msg || "登录失败"); } authToken = json.token as string; return { token: authToken, user: json.user }; } export async function getPages(options?: { offset?: number; limit?: number; type?: "all" | "admin_only"; }): Promise<{ pages: ArtalkPage[]; total: number }> { const { offset = 0, limit = 50, type = "all" } = options || {}; const params = new URLSearchParams({ site_name: ARTALK_SITE, offset: offset.toString(), limit: limit.toString(), type, }); const url = `${ARTALK_SERVER}/api/v2/pages?${params.toString()}`; const headers: Record = { "Content-Type": "application/json" }; if (authToken) headers["Authorization"] = `Bearer ${authToken}`; const res = await fetch(url, { headers }); const json = await res.json(); if (json.msg && !json.pages && !json.count) { throw new Error(json.msg); } return { pages: json.pages || json.data || [], total: json.count || json.total || 0 }; } export async function getComments( pageKey: string, options?: { offset?: number; limit?: number } ): Promise<{ comments: ArtalkComment[]; total: number }> { const { offset = 0, limit = 100 } = options || {}; const params = new URLSearchParams({ site_name: ARTALK_SITE, page_key: pageKey, offset: offset.toString(), limit: limit.toString(), flat_mode: "true", sort_by: "date_desc", }); const url = `${ARTALK_SERVER}/api/v2/comments?${params.toString()}`; const headers: Record = { "Content-Type": "application/json" }; if (authToken) headers["Authorization"] = `Bearer ${authToken}`; const res = await fetch(url, { headers }); const json = await res.json(); if (json.msg && !json.comments && !json.count) { throw new Error(json.msg); } return { comments: json.comments || json.data || [], total: json.count || json.total || 0 }; } async function artalkMutate(endpoint: string, method: string, body: Record): Promise { const url = `${ARTALK_SERVER}${endpoint}`; const headers: Record = { "Content-Type": "application/json" }; if (authToken) headers["Authorization"] = `Bearer ${authToken}`; const res = await fetch(url, { method, headers, body: JSON.stringify(body) }); const json = await res.json(); if (json.msg) { throw new Error(json.msg); } return (json.data || json) as T; } export async function updateComment( id: number, data: { content?: string; is_collapsed?: boolean; is_pending?: boolean; is_pinned?: boolean; rid?: number; } ): Promise { return artalkMutate(`/api/v2/comments/${id}`, "PUT", { ...data, site_name: ARTALK_SITE }); } export async function createComment(data: { page_key: string; content: string; name: string; email: string; rid?: number; }): Promise { return artalkMutate("/api/v2/comments", "POST", { ...data, site_name: ARTALK_SITE }); } export async function deleteComment(id: number): Promise { await artalkMutate(`/api/v2/comments/${id}`, "DELETE", { site_name: ARTALK_SITE }); } export async function updatePage( id: number, data: { key: string; title: string; admin_only?: boolean } ): Promise { return artalkMutate(`/api/v2/pages/${id}`, "PUT", { key: data.key, title: data.title, admin_only: data.admin_only ?? false, site_name: ARTALK_SITE, }); }