mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-18 17:30:16 +01:00
⚙️ fix: File Config Handling (revisited) (#5881)
* fix: improve file handling by preventing memoization issues, providing config values at run time
* 🌍 i18n: Update translation.json with latest translations
This commit is contained in:
parent
61f0480b57
commit
e3b5c59949
24 changed files with 348 additions and 180 deletions
|
|
@ -1,6 +1,13 @@
|
|||
import { excelMimeTypes, QueryKeys } from 'librechat-data-provider';
|
||||
import {
|
||||
megabyte,
|
||||
QueryKeys,
|
||||
excelMimeTypes,
|
||||
codeTypeMapping,
|
||||
fileConfig as defaultFileConfig,
|
||||
} from 'librechat-data-provider';
|
||||
import type { TFile, EndpointFileConfig } from 'librechat-data-provider';
|
||||
import type { QueryClient } from '@tanstack/react-query';
|
||||
import type { TFile } from 'librechat-data-provider';
|
||||
import type { ExtendedFile } from '~/common';
|
||||
import SheetPaths from '~/components/svg/Files/SheetPaths';
|
||||
import TextPaths from '~/components/svg/Files/TextPaths';
|
||||
import FilePaths from '~/components/svg/Files/FilePaths';
|
||||
|
|
@ -190,3 +197,92 @@ export function formatBytes(bytes: number, decimals = 2) {
|
|||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm));
|
||||
}
|
||||
|
||||
const { checkType } = defaultFileConfig;
|
||||
|
||||
export const validateFiles = ({
|
||||
files,
|
||||
fileList,
|
||||
setError,
|
||||
endpointFileConfig,
|
||||
}: {
|
||||
fileList: File[];
|
||||
files: Map<string, ExtendedFile>;
|
||||
setError: (error: string) => void;
|
||||
endpointFileConfig: EndpointFileConfig;
|
||||
}) => {
|
||||
const { fileLimit, fileSizeLimit, totalSizeLimit, supportedMimeTypes } = endpointFileConfig;
|
||||
const existingFiles = Array.from(files.values());
|
||||
const incomingTotalSize = fileList.reduce((total, file) => total + file.size, 0);
|
||||
if (incomingTotalSize === 0) {
|
||||
setError('com_error_files_empty');
|
||||
return false;
|
||||
}
|
||||
const currentTotalSize = existingFiles.reduce((total, file) => total + file.size, 0);
|
||||
|
||||
if (fileLimit && fileList.length + files.size > fileLimit) {
|
||||
setError(`You can only upload up to ${fileLimit} files at a time.`);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < fileList.length; i++) {
|
||||
let originalFile = fileList[i];
|
||||
let fileType = originalFile.type;
|
||||
const extension = originalFile.name.split('.').pop() ?? '';
|
||||
const knownCodeType = codeTypeMapping[extension];
|
||||
|
||||
// Infer MIME type for Known Code files when the type is empty or a mismatch
|
||||
if (knownCodeType && (!fileType || fileType !== knownCodeType)) {
|
||||
fileType = knownCodeType;
|
||||
}
|
||||
|
||||
// Check if the file type is still empty after the extension check
|
||||
if (!fileType) {
|
||||
setError('Unable to determine file type for: ' + originalFile.name);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Replace empty type with inferred type
|
||||
if (originalFile.type !== fileType) {
|
||||
const newFile = new File([originalFile], originalFile.name, { type: fileType });
|
||||
originalFile = newFile;
|
||||
fileList[i] = newFile;
|
||||
}
|
||||
|
||||
if (!checkType(originalFile.type, supportedMimeTypes)) {
|
||||
console.log(originalFile);
|
||||
setError('Currently, unsupported file type: ' + originalFile.type);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fileSizeLimit && originalFile.size >= fileSizeLimit) {
|
||||
setError(`File size exceeds ${fileSizeLimit / megabyte} MB.`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (totalSizeLimit && currentTotalSize + incomingTotalSize > totalSizeLimit) {
|
||||
setError(`The total size of the files cannot exceed ${totalSizeLimit / megabyte} MB.`);
|
||||
return false;
|
||||
}
|
||||
|
||||
const combinedFilesInfo = [
|
||||
...existingFiles.map(
|
||||
(file) =>
|
||||
`${file.file?.name ?? file.filename}-${file.size}-${file.type?.split('/')[0] ?? 'file'}`,
|
||||
),
|
||||
...fileList.map(
|
||||
(file: File | undefined) =>
|
||||
`${file?.name}-${file?.size}-${file?.type.split('/')[0] ?? 'file'}`,
|
||||
),
|
||||
];
|
||||
|
||||
const uniqueFilesSet = new Set(combinedFilesInfo);
|
||||
|
||||
if (uniqueFilesSet.size !== combinedFilesInfo.length) {
|
||||
setError('com_error_files_dupe');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue