import type { ZodType } from 'zod'; import { ConversationsResponseSchema, ConversationDetailResponseSchema, ErrorResponseSchema, ProcessedPostsResponseSchema, SendReplyRequestSchema, StartConversationRequestSchema, StartConversationResponseSchema, SuccessResponseSchema, SuggestedReplyResponseSchema, type ActiveChat, type ConversationDetailResponse, type ProcessedPost, type SuccessResponse, } from '../../../../../packages/api-contracts/src/index.js'; import { createDashboardRequest } from '../../api/request.js'; async function parseResponse(response: Response, schema: ZodType): Promise { const payload: unknown = await response.json(); if (!response.ok) { const parsedError = ErrorResponseSchema.safeParse(payload); throw new Error(parsedError.success ? parsedError.data.error : `Request failed (${response.status})`); } return schema.parse(payload); } function conversationPath(id: string): string { return `/api/conversations/${encodeURIComponent(id)}`; } export interface ConversationApi { list(): Promise; detail(id: string): Promise; suggestReply(id: string): Promise; suggestMediaAsk(id: string): Promise; processedPosts(username: string): Promise; sendReply(id: string, message: string): Promise; startConversation(username: string, message: string): Promise; } export function createConversationApi(fetchImplementation?: typeof fetch): ConversationApi { const request = createDashboardRequest(fetchImplementation); return { async list() { return parseResponse(await request('/api/conversations'), ConversationsResponseSchema); }, async detail(id) { return parseResponse(await request(conversationPath(id)), ConversationDetailResponseSchema); }, async suggestReply(id) { const response = await parseResponse( await request(`${conversationPath(id)}/suggest-reply`, { method: 'POST' }), SuggestedReplyResponseSchema, ); return response.suggestedReply; }, async suggestMediaAsk(id) { const response = await parseResponse( await request(`${conversationPath(id)}/suggest-media-ask`, { method: 'POST' }), SuggestedReplyResponseSchema, ); return response.suggestedReply; }, async processedPosts(username) { return parseResponse( await request(`/api/posts/by-author/${encodeURIComponent(username.trim().replace(/^u\//i, ''))}`), ProcessedPostsResponseSchema, ); }, async sendReply(id, message) { const body = SendReplyRequestSchema.parse({ message: message.trim() }); return parseResponse( await request(`${conversationPath(id)}/send-reply`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }), SuccessResponseSchema, ); }, async startConversation(username, message) { const body = StartConversationRequestSchema.parse({ username: username.trim().replace(/^u\//i, ''), message: message.trim(), }); const response = await parseResponse( await request('/api/conversations/start', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }), StartConversationResponseSchema, ); return response.chat; }, }; } export const conversationApi = createConversationApi();