Files
formbricks/packages/ui/FileInput/lib/utils.ts
Dhruwang Jariwala 7e6fe63f6a feat: Video upload (#2351)
Co-authored-by: pandeymangg <anshuman.pandey9999@gmail.com>
Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
Co-authored-by: Johannes <johannes@formbricks.com>
2024-04-05 04:40:52 +00:00

144 lines
3.8 KiB
TypeScript

"use client";
import { toast } from "react-hot-toast";
import { TAllowedFileExtension } from "@formbricks/types/common";
export 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, updatedFileName } = data;
let requestHeaders: Record<string, string> = {};
if (signingData) {
const { signature, timestamp, uuid } = signingData;
requestHeaders = {
"X-File-Type": file.type,
"X-File-Name": encodeURIComponent(updatedFileName),
"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 const getAllowedFiles = (
files: File[],
allowedFileExtensions: string[],
maxSizeInMB?: number
): File[] => {
const sizeExceedFiles: string[] = [];
const unsupportedExtensionFiles: string[] = [];
const allowedFiles = files.filter((file) => {
if (!file || !file.type) {
return false;
}
const extension = file.name.split(".").pop();
const fileSizeInMB = file.size / 1000000; // Kb -> Mb
if (!allowedFileExtensions.includes(extension as TAllowedFileExtension)) {
unsupportedExtensionFiles.push(file.name);
return false; // Exclude file if extension not allowed
} else if (maxSizeInMB && fileSizeInMB > maxSizeInMB) {
sizeExceedFiles.push(file.name);
return false; // Exclude files larger than the maximum size
}
return true;
});
// Constructing toast messages based on the issues found
let toastMessage = "";
if (sizeExceedFiles.length > 0) {
toastMessage += `Files exceeding size limit (${maxSizeInMB} MB): ${sizeExceedFiles.join(", ")}. `;
}
if (unsupportedExtensionFiles.length > 0) {
toastMessage += `Unsupported file types: ${unsupportedExtensionFiles.join(", ")}.`;
}
if (toastMessage) {
toast.error(toastMessage);
}
return allowedFiles;
};
export const checkForYoutubePrivacyMode = (url: string): boolean => {
return url.includes("youtube-nocookie.com");
};