You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

183 lines
5.1 KiB

  1. import { SessionWithTokens, authOptions } from "@/config/authConfig";
  2. import { getServerSession } from "next-auth";
  3. import { headers } from "next/headers";
  4. import { redirect } from "next/navigation";
  5. export interface searchParamsProps {
  6. searchParams: { [key: string]: string | string[] | undefined };
  7. }
  8. export class ServerFetchError extends Error {
  9. public readonly response: Response | undefined;
  10. constructor(message?: string, response?: Response) {
  11. super(message);
  12. this.response = response;
  13. Object.setPrototypeOf(this, ServerFetchError.prototype);
  14. }
  15. }
  16. export const serverFetch: typeof fetch = async (input, init) => {
  17. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  18. const session = await getServerSession<any, SessionWithTokens>(authOptions);
  19. const accessToken = session?.accessToken;
  20. console.log(accessToken);
  21. return fetch(input, {
  22. ...init,
  23. headers: {
  24. ...init?.headers,
  25. ...(accessToken
  26. ? {
  27. Authorization: `Bearer ${accessToken}`,
  28. Accept:
  29. "application/json, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, multipart/form-data",
  30. }
  31. : {}),
  32. },
  33. });
  34. };
  35. type FetchParams = Parameters<typeof fetch>;
  36. export async function serverFetchJson<T>(...args: FetchParams) {
  37. const response = await serverFetch(...args);
  38. if (response.ok) {
  39. return response.json() as T;
  40. } else {
  41. const errorText = await response.text()
  42. switch (response.status) {
  43. case 401:
  44. signOutUser();
  45. case 422:
  46. throw new ServerFetchError(
  47. JSON.parse(errorText).error,
  48. response
  49. );
  50. default:
  51. console.error(errorText);
  52. throw new ServerFetchError(
  53. "Something went wrong fetching data in server.",
  54. response
  55. );
  56. }
  57. }
  58. }
  59. export async function serverFetchWithNoContent(...args: FetchParams) {
  60. const response = await serverFetch(...args);
  61. if (response.ok) {
  62. return response.status; // 204 No Content, e.g. for delete data
  63. } else {
  64. switch (response.status) {
  65. case 401:
  66. signOutUser();
  67. default:
  68. console.error(await response.text());
  69. throw Error("Something went wrong fetching data in server.");
  70. }
  71. }
  72. }
  73. export async function serverFetchString<T>(...args: FetchParams) {
  74. const response = await serverFetch(...args);
  75. if (response.ok) {
  76. return response.text() as T;
  77. } else {
  78. switch (response.status) {
  79. case 401:
  80. signOutUser();
  81. default:
  82. console.error(await response.text());
  83. throw new ServerFetchError(
  84. "Something went wrong fetching data in server.",
  85. response,
  86. );
  87. }
  88. }
  89. }
  90. export async function serverFetchBlob<T>(...args: FetchParams) {
  91. const response = await serverFetch(...args);
  92. if (response.ok) {
  93. const body = response.body;
  94. // console.log(body)
  95. // console.log(body?.tee()[0].getReader())
  96. const reader = body?.getReader();
  97. let finalUInt8Array = new Uint8Array();
  98. let done = false;
  99. while (!done) {
  100. const read = await reader?.read();
  101. // version 1
  102. if (read?.done) {
  103. done = true;
  104. } else {
  105. const tempUInt8Array = new Uint8Array(
  106. finalUInt8Array.length + read?.value.length!,
  107. );
  108. tempUInt8Array.set(finalUInt8Array);
  109. tempUInt8Array.set(read?.value!, finalUInt8Array.length);
  110. finalUInt8Array = new Uint8Array(tempUInt8Array.length!);
  111. finalUInt8Array.set(tempUInt8Array);
  112. // console.log("1", finalUInt8Array)
  113. }
  114. }
  115. // version 2 & return bodyRead
  116. // const bodyRead = reader?.read().then(function processText({ done, value }): any {
  117. // // Result objects contain two properties:
  118. // // done - true if the stream has already given you all its data.
  119. // // value - some data. Always undefined when done is true.
  120. // if (done) {
  121. // console.log("Stream complete");
  122. // return { filename: response.headers.get("filename"), blobValue: finalUInt8Array } as T;;
  123. // }
  124. // // value for fetch streams is a Uint8Array
  125. // finalUInt8Array = new Uint8Array(value.length)
  126. // finalUInt8Array.set(value)
  127. // console.log(finalUInt8Array)
  128. // // Read some more, and call this function again
  129. // return reader.read().then(processText);
  130. // })
  131. // const bodyValue = bodyRead?.value
  132. // const blob = await response.blob()
  133. // const blobText = await blob.text();
  134. // const blobType = await blob.type;
  135. // console.log(bodyReader)
  136. // console.log("2", finalUInt8Array)
  137. // console.log(bodyValue)
  138. return {
  139. filename: response.headers.get("filename"),
  140. blobValue: finalUInt8Array,
  141. } as T;
  142. } else {
  143. switch (response.status) {
  144. case 401:
  145. signOutUser();
  146. default:
  147. console.error(await response.text());
  148. throw Error("Something went wrong fetching data in server.");
  149. }
  150. }
  151. }
  152. export const signOutUser = () => {
  153. const headersList = headers();
  154. const referer = headersList.get("referer");
  155. redirect(
  156. `/logout${referer ? `?callbackUrl=${encodeURIComponent(referer)}` : ""}`,
  157. );
  158. };