|
import mime from 'mime' |
|
import { flatten } from 'lodash-es' |
|
import { FileAppearanceTypeEnum } from './types' |
|
import type { FileEntity } from './types' |
|
import { upload } from '@/service/base' |
|
import { FILE_EXTS } from '@/app/components/base/prompt-editor/constants' |
|
import { SupportUploadFileTypes } from '@/app/components/workflow/types' |
|
import type { FileResponse } from '@/types/workflow' |
|
import { TransferMethod } from '@/types/app' |
|
|
|
type FileUploadParams = { |
|
file: File |
|
onProgressCallback: (progress: number) => void |
|
onSuccessCallback: (res: { id: string }) => void |
|
onErrorCallback: () => void |
|
} |
|
type FileUpload = (v: FileUploadParams, isPublic?: boolean, url?: string) => void |
|
export const fileUpload: FileUpload = ({ |
|
file, |
|
onProgressCallback, |
|
onSuccessCallback, |
|
onErrorCallback, |
|
}, isPublic, url) => { |
|
const formData = new FormData() |
|
formData.append('file', file) |
|
const onProgress = (e: ProgressEvent) => { |
|
if (e.lengthComputable) { |
|
const percent = Math.floor(e.loaded / e.total * 100) |
|
onProgressCallback(percent) |
|
} |
|
} |
|
|
|
upload({ |
|
xhr: new XMLHttpRequest(), |
|
data: formData, |
|
onprogress: onProgress, |
|
}, isPublic, url) |
|
.then((res: { id: string }) => { |
|
onSuccessCallback(res) |
|
}) |
|
.catch(() => { |
|
onErrorCallback() |
|
}) |
|
} |
|
|
|
export const getFileExtension = (fileName: string, fileMimetype: string, isRemote?: boolean) => { |
|
if (fileMimetype) |
|
return mime.getExtension(fileMimetype) || '' |
|
|
|
if (isRemote) |
|
return '' |
|
|
|
if (fileName) { |
|
const fileNamePair = fileName.split('.') |
|
const fileNamePairLength = fileNamePair.length |
|
|
|
if (fileNamePairLength > 1) |
|
return fileNamePair[fileNamePairLength - 1] |
|
} |
|
|
|
return '' |
|
} |
|
|
|
export const getFileAppearanceType = (fileName: string, fileMimetype: string) => { |
|
const extension = getFileExtension(fileName, fileMimetype) |
|
|
|
if (extension === 'gif') |
|
return FileAppearanceTypeEnum.gif |
|
|
|
if (FILE_EXTS.image.includes(extension.toUpperCase())) |
|
return FileAppearanceTypeEnum.image |
|
|
|
if (FILE_EXTS.video.includes(extension.toUpperCase())) |
|
return FileAppearanceTypeEnum.video |
|
|
|
if (FILE_EXTS.audio.includes(extension.toUpperCase())) |
|
return FileAppearanceTypeEnum.audio |
|
|
|
if (extension === 'html') |
|
return FileAppearanceTypeEnum.code |
|
|
|
if (extension === 'pdf') |
|
return FileAppearanceTypeEnum.pdf |
|
|
|
if (extension === 'md' || extension === 'markdown') |
|
return FileAppearanceTypeEnum.markdown |
|
|
|
if (extension === 'xlsx' || extension === 'xls') |
|
return FileAppearanceTypeEnum.excel |
|
|
|
if (extension === 'docx' || extension === 'doc') |
|
return FileAppearanceTypeEnum.word |
|
|
|
if (extension === 'pptx' || extension === 'ppt') |
|
return FileAppearanceTypeEnum.ppt |
|
|
|
if (FILE_EXTS.document.includes(extension.toUpperCase())) |
|
return FileAppearanceTypeEnum.document |
|
|
|
return FileAppearanceTypeEnum.custom |
|
} |
|
|
|
export const getSupportFileType = (fileName: string, fileMimetype: string, isCustom?: boolean) => { |
|
if (isCustom) |
|
return SupportUploadFileTypes.custom |
|
|
|
const extension = getFileExtension(fileName, fileMimetype) |
|
for (const key in FILE_EXTS) { |
|
if ((FILE_EXTS[key]).includes(extension.toUpperCase())) |
|
return key |
|
} |
|
|
|
return '' |
|
} |
|
|
|
export const getProcessedFiles = (files: FileEntity[]) => { |
|
return files.filter(file => file.progress !== -1).map(fileItem => ({ |
|
type: fileItem.supportFileType, |
|
transfer_method: fileItem.transferMethod, |
|
url: fileItem.url || '', |
|
upload_file_id: fileItem.uploadedId || '', |
|
})) |
|
} |
|
|
|
export const getProcessedFilesFromResponse = (files: FileResponse[]) => { |
|
return files.map((fileItem) => { |
|
return { |
|
id: fileItem.related_id, |
|
name: fileItem.filename, |
|
size: fileItem.size || 0, |
|
type: fileItem.mime_type, |
|
progress: 100, |
|
transferMethod: fileItem.transfer_method, |
|
supportFileType: fileItem.type, |
|
uploadedId: fileItem.related_id, |
|
url: fileItem.url, |
|
} |
|
}) |
|
} |
|
|
|
export const getFileNameFromUrl = (url: string) => { |
|
const urlParts = url.split('/') |
|
return urlParts[urlParts.length - 1] || '' |
|
} |
|
|
|
export const getSupportFileExtensionList = (allowFileTypes: string[], allowFileExtensions: string[]) => { |
|
if (allowFileTypes.includes(SupportUploadFileTypes.custom)) |
|
return allowFileExtensions.map(item => item.toUpperCase()) |
|
|
|
return allowFileTypes.map(type => FILE_EXTS[type]).flat() |
|
} |
|
|
|
export const isAllowedFileExtension = (fileName: string, fileMimetype: string, allowFileTypes: string[], allowFileExtensions: string[]) => { |
|
return getSupportFileExtensionList(allowFileTypes, allowFileExtensions).includes(getFileExtension(fileName, fileMimetype).toUpperCase()) |
|
} |
|
|
|
export const getFilesInLogs = (rawData: any) => { |
|
const originalFiles = flatten(Object.keys(rawData || {}).map((key) => { |
|
if (typeof rawData[key] === 'object' || Array.isArray(rawData[key])) |
|
return rawData[key] |
|
return undefined |
|
}).filter(Boolean)).filter(item => item?.model_identity === '__dify__file__') |
|
return getProcessedFilesFromResponse(originalFiles) |
|
} |
|
|
|
export const fileIsUploaded = (file: FileEntity) => { |
|
if (file.uploadedId) |
|
return true |
|
|
|
if (file.transferMethod === TransferMethod.remote_url && file.progress === 100) |
|
return true |
|
} |
|
|
|
export const downloadFile = (url: string, filename: string) => { |
|
const anchor = document.createElement('a') |
|
anchor.href = url |
|
anchor.download = filename |
|
anchor.style.display = 'none' |
|
anchor.target = '_blank' |
|
anchor.title = filename |
|
document.body.appendChild(anchor) |
|
anchor.click() |
|
document.body.removeChild(anchor) |
|
} |
|
|