mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-04 21:32:39 +02:00
add podcast api service
This commit is contained in:
parent
5361290315
commit
20cd1951b5
5 changed files with 54 additions and 22 deletions
|
|
@ -1,21 +1,13 @@
|
|||
import { atom } from "jotai";
|
||||
import { atomWithQuery } from "jotai-tanstack-query";
|
||||
import type { ChatDetails } from "@/app/dashboard/[search_space_id]/chats/chats-client";
|
||||
import { activeSearchSpaceIdAtom } from "@/atoms/seach-spaces/seach-space-queries.atom";
|
||||
import type { Podcast } from "@/contracts/types/podcast.types";
|
||||
import { chatsApiService } from "@/lib/apis/chats-api.service";
|
||||
import { podcastsApiService } from "@/lib/apis/podcasts-api.service";
|
||||
import { cacheKeys } from "@/lib/query-client/cache-keys";
|
||||
|
||||
type ActiveChatState = {
|
||||
chatId: string | null;
|
||||
chatDetails: ChatDetails | null;
|
||||
podcast: Podcast | null;
|
||||
};
|
||||
|
||||
export const activeChatIdAtom = atom<string | null>(null);
|
||||
|
||||
export const activeChatAtom = atomWithQuery<ActiveChatState>((get) => {
|
||||
export const activeChatAtom = atomWithQuery((get) => {
|
||||
const activeChatId = get(activeChatIdAtom);
|
||||
const authToken = localStorage.getItem("surfsense_bearer_token");
|
||||
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ export function ChatPanelContainer() {
|
|||
await podcastsApiService.generatePodcast(request);
|
||||
toast.success(`Podcast generation started!`);
|
||||
} catch (error) {
|
||||
toast.error("Error generating podcast. Please log in again.");
|
||||
console.error("Error generating podcast:", error);
|
||||
toast.error("Error generating podcast. Please try again later.");
|
||||
console.error("Error generating podcast:", JSON.stringify(error));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ export const getPodcastByChatIdRequest = z.object({
|
|||
chat_id: z.number(),
|
||||
});
|
||||
|
||||
export const getPodcastByChatResponse = podcast.nullish();
|
||||
|
||||
export type GeneratePodcastRequest = z.infer<typeof generatePodcastRequest>;
|
||||
export type GetPodcastByChatIdRequest = z.infer<typeof getPodcastByChatIdRequest>;
|
||||
export type GetPodcastByChatResponse = z.infer<typeof getPodcastByChatResponse>;
|
||||
export type Podcast = z.infer<typeof podcast>;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { th } from "date-fns/locale";
|
||||
import type z from "zod";
|
||||
import { AppError, AuthenticationError, AuthorizationError, NotFoundError } from "../error";
|
||||
|
||||
|
|
@ -50,6 +51,11 @@ class BaseApiService {
|
|||
: unknown
|
||||
> {
|
||||
try {
|
||||
/**
|
||||
* ----------
|
||||
* REQUEST
|
||||
* ----------
|
||||
*/
|
||||
const defaultOptions: RequestOptions = {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
|
|
@ -68,18 +74,46 @@ class BaseApiService {
|
|||
},
|
||||
};
|
||||
|
||||
// Validate the base URL
|
||||
if (!this.baseUrl) {
|
||||
throw new AppError("Base URL is not set.");
|
||||
}
|
||||
|
||||
// Validate the bearer token
|
||||
if (!this.bearerToken && !this.noAuthEndpoints.includes(url)) {
|
||||
throw new AuthenticationError("You are not authenticated. Please login again.");
|
||||
}
|
||||
|
||||
// Construct the full URL
|
||||
const fullUrl = new URL(url, this.baseUrl).toString();
|
||||
|
||||
const response = await fetch(fullUrl, mergedOptions);
|
||||
// Prepare fetch options
|
||||
const fetchOptions: RequestInit = {
|
||||
method: mergedOptions.method,
|
||||
headers: mergedOptions.headers,
|
||||
signal: mergedOptions.signal,
|
||||
};
|
||||
|
||||
// Automatically stringify body if Content-Type is application/json and body is an object
|
||||
if (mergedOptions.body !== undefined) {
|
||||
const contentType = mergedOptions.headers?.["Content-Type"];
|
||||
if (contentType === "application/json" && typeof mergedOptions.body === "object") {
|
||||
fetchOptions.body = JSON.stringify(mergedOptions.body);
|
||||
} else {
|
||||
// Pass body as-is for other content types (e.g., form data, already stringified)
|
||||
fetchOptions.body = mergedOptions.body;
|
||||
}
|
||||
}
|
||||
|
||||
const response = await fetch(fullUrl, fetchOptions);
|
||||
|
||||
/**
|
||||
* ----------
|
||||
* RESPONSE
|
||||
* ----------
|
||||
*/
|
||||
|
||||
// Handle errors
|
||||
if (!response.ok) {
|
||||
// biome-ignore lint/suspicious: Unknown
|
||||
let data;
|
||||
|
|
@ -87,12 +121,11 @@ class BaseApiService {
|
|||
try {
|
||||
data = await response.json();
|
||||
} catch (error) {
|
||||
console.error("Failed to parse response as JSON:", error);
|
||||
|
||||
throw new AppError("Something went wrong", response.status, response.statusText);
|
||||
console.error("Failed to parse response as JSON: ", JSON.stringify(error));
|
||||
throw new AppError("Failed to parse response", response.status, response.statusText);
|
||||
}
|
||||
|
||||
// for fastapi errors response
|
||||
// For fastapi errors response
|
||||
if (typeof data === "object" && "detail" in data) {
|
||||
throw new AppError(data.detail, response.status, response.statusText);
|
||||
}
|
||||
|
|
@ -138,13 +171,14 @@ class BaseApiService {
|
|||
break;
|
||||
// Add more cases as needed
|
||||
default:
|
||||
data = await response.text();
|
||||
data = await response.json();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to parse response as JSON:", error);
|
||||
throw new AppError("Failed to parse response", response.status, response.statusText);
|
||||
}
|
||||
|
||||
// Validate response
|
||||
if (responseType === ResponseType.JSON) {
|
||||
if (!responseSchema) {
|
||||
return data;
|
||||
|
|
@ -156,7 +190,7 @@ class BaseApiService {
|
|||
* This is a client side error, and should be fixed by updating the responseSchema to keep things typed.
|
||||
* This error should not be shown to the user , it is for dev only.
|
||||
*/
|
||||
console.error("Invalid API response schema:", parsedData.error);
|
||||
console.error(`Invalid API response schema - ${url} :`, JSON.stringify(parsedData.error));
|
||||
}
|
||||
|
||||
return data;
|
||||
|
|
@ -164,7 +198,7 @@ class BaseApiService {
|
|||
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error("Request failed:", error);
|
||||
console.error("Request failed:", JSON.stringify(error));
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ import {
|
|||
type GetPodcastByChatIdRequest,
|
||||
generatePodcastRequest,
|
||||
getPodcastByChatIdRequest,
|
||||
getPodcastByChatResponse,
|
||||
type Podcast,
|
||||
podcast,
|
||||
} from "@/contracts/types/podcast.types";
|
||||
import { ValidationError } from "../error";
|
||||
import { baseApiService } from "./base-api.service";
|
||||
|
|
@ -22,7 +22,10 @@ class PodcastsApiService {
|
|||
throw new ValidationError(`Invalid request: ${errorMessage}`);
|
||||
}
|
||||
|
||||
return baseApiService.get(`/api/v1/podcasts/by-chat/${request.chat_id}`, podcast);
|
||||
return baseApiService.get(
|
||||
`/api/v1/podcasts/by-chat/${request.chat_id}`,
|
||||
getPodcastByChatResponse
|
||||
);
|
||||
};
|
||||
|
||||
generatePodcast = async (request: GeneratePodcastRequest) => {
|
||||
|
|
@ -38,7 +41,7 @@ class PodcastsApiService {
|
|||
}
|
||||
|
||||
return baseApiService.post(`/api/v1/podcasts/generate`, undefined, {
|
||||
body: request,
|
||||
body: parsedRequest.data,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue