api.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. export const API_BASE = process.env.NEXT_PUBLIC_WATCH_FINISHED_API || "/api";
  2. function buildUrl(path: string, params?: any) {
  3. const url = new URL(path, API_BASE);
  4. if (params && typeof params === "object") {
  5. Object.entries(params).forEach(([k, v]) => {
  6. if (v !== undefined && v !== null) url.searchParams.append(k, String(v));
  7. });
  8. }
  9. return url.toString();
  10. }
  11. export async function get<T = any>(path: string, params?: any): Promise<T> {
  12. const controller = new AbortController();
  13. const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout
  14. try {
  15. const res = await fetch(buildUrl(path, params), {
  16. method: "GET",
  17. credentials: "same-origin",
  18. headers: { Accept: "application/json" },
  19. signal: controller.signal
  20. });
  21. clearTimeout(timeoutId);
  22. if (!res.ok) throw new Error(await res.text());
  23. return res.json();
  24. } catch (error) {
  25. clearTimeout(timeoutId);
  26. if (error instanceof Error && error.name === "AbortError") {
  27. throw new Error("Request timeout");
  28. }
  29. throw error;
  30. }
  31. }
  32. export async function post<T = any>(path: string, data?: any): Promise<T> {
  33. // const controller = new AbortController();
  34. // const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout
  35. try {
  36. const res = await fetch(buildUrl(path), {
  37. method: "POST",
  38. credentials: "same-origin",
  39. headers: {
  40. "Content-Type": "application/json",
  41. Accept: "application/json"
  42. },
  43. body: data ? JSON.stringify(data) : undefined
  44. // signal: controller.signal
  45. });
  46. // clearTimeout(timeoutId);
  47. if (!res.ok) throw new Error(await res.text());
  48. return res.json();
  49. } catch (error) {
  50. // clearTimeout(timeoutId);
  51. // if (error.name === "AbortError") {
  52. // throw new Error("Request timeout");
  53. // }
  54. throw error;
  55. }
  56. }
  57. export async function put<T = any>(path: string, data?: any): Promise<T> {
  58. const controller = new AbortController();
  59. const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout
  60. try {
  61. const res = await fetch(buildUrl(path), {
  62. method: "PUT",
  63. credentials: "same-origin",
  64. headers: {
  65. "Content-Type": "application/json",
  66. Accept: "application/json"
  67. },
  68. body: data ? JSON.stringify(data) : undefined,
  69. signal: controller.signal
  70. });
  71. clearTimeout(timeoutId);
  72. if (!res.ok) throw new Error(await res.text());
  73. return res.json();
  74. } catch (error) {
  75. clearTimeout(timeoutId);
  76. if (error instanceof Error && error.name === "AbortError") {
  77. throw new Error("Request timeout");
  78. }
  79. throw error;
  80. }
  81. }
  82. export async function del<T = any>(path: string, params?: any): Promise<T> {
  83. const controller = new AbortController();
  84. const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout
  85. try {
  86. const res = await fetch(buildUrl(path, params), {
  87. method: "DELETE",
  88. credentials: "same-origin",
  89. headers: { Accept: "application/json" },
  90. signal: controller.signal
  91. });
  92. clearTimeout(timeoutId);
  93. if (!res.ok) throw new Error(await res.text());
  94. // Handle empty response body (common for DELETE operations)
  95. const contentLength = res.headers.get("content-length");
  96. const contentType = res.headers.get("content-type");
  97. if (
  98. contentLength === "0" ||
  99. res.status === 204 ||
  100. !contentType?.includes("application/json")
  101. ) {
  102. return {} as T;
  103. }
  104. const text = await res.text();
  105. if (!text.trim()) {
  106. return {} as T;
  107. }
  108. return JSON.parse(text);
  109. } catch (error) {
  110. clearTimeout(timeoutId);
  111. if (error instanceof Error && error.name === "AbortError") {
  112. throw new Error("Request timeout");
  113. }
  114. throw error;
  115. }
  116. }