import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { adminFetch } from './admin-api'; // ── Types ────────────────────────────────────────────────────────────── export type OutboundMethod = 'POST' | 'PUT' | 'PATCH'; export type OutboundAuthKind = 'NONE' | 'BEARER' | 'BASIC'; export type TrustMode = 'SYSTEM_DEFAULT' | 'TRUST_ALL' | 'TRUST_PATHS'; // Jackson DEDUCTION mode picks subtype by which fields are present. // None = {}, Bearer = { tokenCiphertext }, Basic = { username, passwordCiphertext }. // Using a flat optional shape for pragmatic TypeScript compatibility. export type OutboundAuth = { tokenCiphertext?: string; username?: string; passwordCiphertext?: string; }; // Server returns this shape (`OutboundConnectionDto` in Java) export interface OutboundConnectionDto { id: string; name: string; description: string | null; url: string; method: OutboundMethod; defaultHeaders: Record; defaultBodyTmpl: string | null; tlsTrustMode: TrustMode; tlsCaPemPaths: string[]; hmacSecretSet: boolean; authKind: OutboundAuthKind; allowedEnvironmentIds: string[]; createdAt: string; createdBy: string; updatedAt: string; updatedBy: string; } // Client sends this shape for create/update (`OutboundConnectionRequest` in Java) export interface OutboundConnectionRequest { name: string; description?: string | null; url: string; method: OutboundMethod; defaultHeaders?: Record; defaultBodyTmpl?: string | null; tlsTrustMode: TrustMode; tlsCaPemPaths?: string[]; hmacSecret?: string | null; auth: OutboundAuth; allowedEnvironmentIds?: string[]; } // Server returns this from POST /{id}/test export interface OutboundConnectionTestResult { status: number; latencyMs: number; responseSnippet: string | null; tlsProtocol: string | null; tlsCipherSuite: string | null; peerCertificateSubject: string | null; peerCertificateExpiresAtEpochMs: number | null; error: string | null; } // ── Query Hooks ──────────────────────────────────────────────────────── export function useOutboundConnections() { return useQuery({ queryKey: ['admin', 'outbound-connections'], queryFn: () => adminFetch('/outbound-connections'), }); } export function useOutboundConnection(id: string | undefined) { return useQuery({ queryKey: ['admin', 'outbound-connections', id], queryFn: () => adminFetch(`/outbound-connections/${id}`), enabled: !!id, }); } // ── Mutation Hooks ───────────────────────────────────────────────────── export function useCreateOutboundConnection() { const qc = useQueryClient(); return useMutation({ mutationFn: (req: OutboundConnectionRequest) => adminFetch('/outbound-connections', { method: 'POST', body: JSON.stringify(req), }), onSuccess: () => qc.invalidateQueries({ queryKey: ['admin', 'outbound-connections'] }), }); } export function useUpdateOutboundConnection(id: string) { const qc = useQueryClient(); return useMutation({ mutationFn: (req: OutboundConnectionRequest) => adminFetch(`/outbound-connections/${id}`, { method: 'PUT', body: JSON.stringify(req), }), onSuccess: () => { qc.invalidateQueries({ queryKey: ['admin', 'outbound-connections'] }); qc.invalidateQueries({ queryKey: ['admin', 'outbound-connections', id] }); }, }); } export function useDeleteOutboundConnection() { const qc = useQueryClient(); return useMutation({ mutationFn: (id: string) => adminFetch(`/outbound-connections/${id}`, { method: 'DELETE' }), onSuccess: () => qc.invalidateQueries({ queryKey: ['admin', 'outbound-connections'] }), }); } export function useTestOutboundConnection() { return useMutation({ mutationFn: (id: string) => adminFetch(`/outbound-connections/${id}/test`, { method: 'POST', }), }); }