| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- // API_BASE now uses relative path for proxy, or falls back to direct API URL
- export const API_BASE = process.env.NEXT_PUBLIC_WATCH_FINISHED_API || "/api";
- function buildUrl(path: string, params?: any) {
- // If API_BASE starts with http, use it as absolute URL
- // Otherwise, use it as relative path (for proxy)
- const base = API_BASE.startsWith("http") ? API_BASE : "";
- const fullPath = API_BASE.startsWith("http") ? path : `${API_BASE}${path}`;
- const url = base
- ? new URL(fullPath, base)
- : new URL(fullPath, window.location.origin);
- if (params && typeof params === "object") {
- Object.entries(params).forEach(([k, v]) => {
- if (v !== undefined && v !== null) url.searchParams.append(k, String(v));
- });
- }
- return url.toString();
- }
- export async function get<T = any>(path: string, params?: any): Promise<T> {
- const controller = new AbortController();
- const timeoutId = setTimeout(() => controller.abort(), 90000); // 90 second timeout
- try {
- const res = await fetch(buildUrl(path, params), {
- method: "GET",
- credentials: "same-origin",
- headers: { Accept: "application/json" },
- signal: controller.signal
- });
- clearTimeout(timeoutId);
- if (!res.ok) throw new Error(await res.text());
- return res.json();
- } catch (error) {
- clearTimeout(timeoutId);
- if (error instanceof Error && error.name === "AbortError") {
- throw new Error("Request timeout");
- }
- throw error;
- }
- }
- export async function post<T = any>(path: string, data?: any): Promise<T> {
- const controller = new AbortController();
- const timeoutId = setTimeout(() => controller.abort(), 90000); // 90 second timeout
- try {
- const res = await fetch(buildUrl(path), {
- method: "POST",
- credentials: "same-origin",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json"
- },
- body: data ? JSON.stringify(data) : undefined,
- signal: controller.signal
- });
- clearTimeout(timeoutId);
- if (!res.ok) throw new Error(await res.text());
- return res.json();
- } catch (error) {
- clearTimeout(timeoutId);
- if (error instanceof Error && error.name === "AbortError") {
- throw new Error("Request timeout");
- }
- throw error;
- }
- }
- export async function put<T = any>(path: string, data?: any): Promise<T> {
- const controller = new AbortController();
- const timeoutId = setTimeout(() => controller.abort(), 90000); // 90 second timeout
- try {
- const res = await fetch(buildUrl(path), {
- method: "PUT",
- credentials: "same-origin",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json"
- },
- body: data ? JSON.stringify(data) : undefined,
- signal: controller.signal
- });
- clearTimeout(timeoutId);
- if (!res.ok) throw new Error(await res.text());
- return res.json();
- } catch (error) {
- clearTimeout(timeoutId);
- if (error instanceof Error && error.name === "AbortError") {
- throw new Error("Request timeout");
- }
- throw error;
- }
- }
- export async function del<T = any>(path: string, params?: any): Promise<T> {
- const controller = new AbortController();
- const timeoutId = setTimeout(() => controller.abort(), 90000); // 90 second timeout
- try {
- const res = await fetch(buildUrl(path, params), {
- method: "DELETE",
- credentials: "same-origin",
- headers: { Accept: "application/json" },
- signal: controller.signal
- });
- clearTimeout(timeoutId);
- if (!res.ok) throw new Error(await res.text());
- // Handle empty response body (common for DELETE operations)
- const contentLength = res.headers.get("content-length");
- const contentType = res.headers.get("content-type");
- if (
- contentLength === "0" ||
- res.status === 204 ||
- !contentType?.includes("application/json")
- ) {
- return {} as T;
- }
- const text = await res.text();
- if (!text.trim()) {
- return {} as T;
- }
- return JSON.parse(text);
- } catch (error) {
- clearTimeout(timeoutId);
- if (error instanceof Error && error.name === "AbortError") {
- throw new Error("Request timeout");
- }
- throw error;
- }
- }
|