"use client"; const uploadFile = async ( file: File | Blob, allowedFileExtensions: string[] | undefined, environmentId: string | undefined ) => { try { if (!(file instanceof Blob) || !(file instanceof File)) { throw new Error(`Invalid file type. Expected Blob or File, but received ${typeof file}`); } const fileBuffer = await file.arrayBuffer(); // check the file size const bufferBytes = fileBuffer.byteLength; const bufferKB = bufferBytes / 1024; if (bufferKB > 10240) { const err = new Error("File size is greater than 10MB"); err.name = "FileTooLargeError"; throw err; } const payload = { fileName: file.name, fileType: file.type, allowedFileExtensions: allowedFileExtensions, environmentId: environmentId, }; const response = await fetch("/api/v1/management/storage", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(payload), }); if (!response.ok) { throw new Error(`Upload failed with status: ${response.status}`); } const json = await response.json(); const { data } = json; const { signedUrl, fileUrl, signingData, presignedFields } = data; let requestHeaders: Record = {}; if (signingData) { const { signature, timestamp, uuid } = signingData; requestHeaders = { "X-File-Type": file.type, "X-File-Name": encodeURIComponent(file.name), "X-Environment-ID": environmentId ?? "", "X-Signature": signature, "X-Timestamp": String(timestamp), "X-UUID": uuid, }; } const formData = new FormData(); if (presignedFields) { Object.keys(presignedFields).forEach((key) => { formData.append(key, presignedFields[key]); }); } // Add the actual file to be uploaded formData.append("file", file); const uploadResponse = await fetch(signedUrl, { method: "POST", ...(signingData ? { headers: requestHeaders } : {}), body: formData, }); if (!uploadResponse.ok) { throw new Error(`Upload failed with status: ${uploadResponse.status}`); } return { uploaded: true, url: fileUrl, }; } catch (error) { throw error; } }; export { uploadFile };