Some checks failed
Branch Build CE / Build Setup (push) Has been cancelled
Branch Build CE / Build-Push Admin Docker Image (push) Has been cancelled
Branch Build CE / Build-Push Web Docker Image (push) Has been cancelled
Branch Build CE / Build-Push Space Docker Image (push) Has been cancelled
Branch Build CE / Build-Push Live Collaboration Docker Image (push) Has been cancelled
Branch Build CE / Build-Push API Server Docker Image (push) Has been cancelled
Branch Build CE / Build-Push Proxy Docker Image (push) Has been cancelled
Branch Build CE / Build-Push AIO Docker Image (push) Has been cancelled
Branch Build CE / Upload Build Assets (push) Has been cancelled
Branch Build CE / Build Release (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Codespell / Check for spelling errors (push) Has been cancelled
Sync Repositories / sync_changes (push) Has been cancelled
Synced from upstream: 8853637e981ed7d8a6cff32bd98e7afe20f54362
87 lines
2.7 KiB
TypeScript
87 lines
2.7 KiB
TypeScript
// external imports
|
|
import { fileTypeFromBuffer } from "file-type";
|
|
// plane imports
|
|
import { TFileMetaDataLite, TFileSignedURLResponse } from "@plane/types";
|
|
|
|
/**
|
|
* @description from the provided signed URL response, generate a payload to be used to upload the file
|
|
* @param {TFileSignedURLResponse} signedURLResponse
|
|
* @param {File} file
|
|
* @returns {FormData} file upload request payload
|
|
*/
|
|
export const generateFileUploadPayload = (signedURLResponse: TFileSignedURLResponse, file: File): FormData => {
|
|
const formData = new FormData();
|
|
Object.entries(signedURLResponse.upload_data.fields).forEach(([key, value]) => formData.append(key, value));
|
|
formData.append("file", file);
|
|
return formData;
|
|
};
|
|
|
|
/**
|
|
* @description Detect MIME type from file signature using file-type library
|
|
* @param {File} file
|
|
* @returns {Promise<string>} detected MIME type or empty string if unknown
|
|
*/
|
|
const detectMimeTypeFromSignature = async (file: File): Promise<string> => {
|
|
try {
|
|
// Read first 4KB which is usually sufficient for most file type detection
|
|
const chunk = file.slice(0, 4096);
|
|
const buffer = await chunk.arrayBuffer();
|
|
const uint8Array = new Uint8Array(buffer);
|
|
|
|
const fileType = await fileTypeFromBuffer(uint8Array);
|
|
return fileType?.mime || "";
|
|
} catch (_error) {
|
|
return "";
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @description Determine the MIME type of a file using multiple detection methods
|
|
* @param {File} file
|
|
* @returns {Promise<string>} detected MIME type
|
|
*/
|
|
const detectFileType = async (file: File): Promise<string> => {
|
|
// check if the file has a MIME type
|
|
if (file.type && file.type.trim() !== "") {
|
|
return file.type;
|
|
}
|
|
|
|
// detect from file signature using file-type library
|
|
try {
|
|
const signatureType = await detectMimeTypeFromSignature(file);
|
|
if (signatureType) {
|
|
return signatureType;
|
|
}
|
|
} catch (_error) {
|
|
console.error("Error detecting file type from signature:", _error);
|
|
}
|
|
|
|
// fallback for unknown files
|
|
return "application/octet-stream";
|
|
};
|
|
|
|
/**
|
|
* @description returns the necessary file meta data to upload a file
|
|
* @param {File} file
|
|
* @returns {Promise<TFileMetaDataLite>} payload with file info
|
|
*/
|
|
export const getFileMetaDataForUpload = async (file: File): Promise<TFileMetaDataLite> => {
|
|
const fileType = await detectFileType(file);
|
|
return {
|
|
name: file.name,
|
|
size: file.size,
|
|
type: fileType,
|
|
};
|
|
};
|
|
|
|
/**
|
|
* @description this function returns the assetId from the asset source
|
|
* @param {string} src
|
|
* @returns {string} assetId
|
|
*/
|
|
export const getAssetIdFromUrl = (src: string): string => {
|
|
const sourcePaths = src.split("/");
|
|
const assetUrl = sourcePaths[sourcePaths.length - 1];
|
|
return assetUrl ?? "";
|
|
};
|