import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import type { CreateProviderRequest, Provider, ProviderListResponse, ProviderOptionsResponse, ProviderResponse, ProviderTestResponse, ProviderTestResultResponse, UpdateProviderRequest, } from "../../shared/api"; import { handleResponse, handleVoidResponse } from "../utils/api"; const PROVIDERS_KEY = ["providers"] as const; const MODELS_KEY = ["models"] as const; export async function createProvider(data: CreateProviderRequest): Promise { const response = await fetch("/api/providers", { body: JSON.stringify(data), headers: { "Content-Type": "application/json" }, method: "POST", }); return handleResponse(response, (data) => (data as ProviderResponse).provider); } export async function deleteProvider(id: string): Promise { const response = await fetch(`/api/providers/${id}`, { method: "DELETE" }); return handleVoidResponse(response); } export async function fetchProvider(id: string): Promise { const response = await fetch(`/api/providers/${id}`); return handleResponse(response, (data) => (data as ProviderResponse).provider); } export async function fetchProviderList(params: { keyword?: string; page?: number; pageSize?: number; }): Promise { const searchParams = new URLSearchParams(); if (params.page) searchParams.set("page", String(params.page)); if (params.pageSize) searchParams.set("pageSize", String(params.pageSize)); if (params.keyword) searchParams.set("keyword", params.keyword); const qs = searchParams.toString(); const url = `/api/providers${qs ? `?${qs}` : ""}`; const response = await fetch(url); if (!response.ok) { const body = (await response.json().catch(() => null)) as null | { error?: string }; throw new Error(body?.error ?? `HTTP ${response.status}`); } return response.json() as Promise; } export async function fetchProviderOptions(): Promise { const response = await fetch("/api/providers/options"); if (!response.ok) { const body = (await response.json().catch(() => null)) as null | { error?: string }; throw new Error(body?.error ?? `HTTP ${response.status}`); } return response.json() as Promise; } export async function testProviderConfig(data: CreateProviderRequest): Promise { const response = await fetch("/api/providers/test", { body: JSON.stringify(data), headers: { "Content-Type": "application/json" }, method: "POST", }); if (!response.ok) { const body = (await response.json().catch(() => null)) as null | { error?: string }; throw new Error(body?.error ?? `HTTP ${response.status}`); } const result = (await response.json()) as ProviderTestResultResponse; return result.providerTestResponse; } export async function updateProvider(id: string, data: UpdateProviderRequest): Promise { const response = await fetch(`/api/providers/${id}`, { body: JSON.stringify(data), headers: { "Content-Type": "application/json" }, method: "PATCH", }); return handleResponse(response, (data) => (data as ProviderResponse).provider); } export function useCreateProvider() { const queryClient = useQueryClient(); return useMutation({ mutationFn: createProvider, onSuccess: () => { void queryClient.invalidateQueries({ queryKey: PROVIDERS_KEY }); }, }); } export function useDeleteProvider() { const queryClient = useQueryClient(); return useMutation({ mutationFn: deleteProvider, onSuccess: () => { void queryClient.invalidateQueries({ queryKey: PROVIDERS_KEY }); void queryClient.invalidateQueries({ queryKey: MODELS_KEY }); }, }); } export function useProvider(id: string) { return useQuery({ enabled: !!id, queryFn: () => fetchProvider(id), queryKey: [...PROVIDERS_KEY, "detail", id], }); } export function useProviderList(params: { keyword?: string; page?: number; pageSize?: number }) { return useQuery({ queryFn: () => fetchProviderList(params), queryKey: [...PROVIDERS_KEY, "list", params], }); } export function useProviderOptions() { return useQuery({ queryFn: fetchProviderOptions, queryKey: [...PROVIDERS_KEY, "options"], }); } export function useTestProviderConfig() { return useMutation({ mutationFn: testProviderConfig, }); } export function useUpdateProvider() { const queryClient = useQueryClient(); return useMutation({ mutationFn: (args: { data: UpdateProviderRequest; id: string }) => updateProvider(args.id, args.data), onSuccess: () => { void queryClient.invalidateQueries({ queryKey: PROVIDERS_KEY }); }, }); }