feat: migrate ESLint to v9 flat config

- Replace .eslintrc.json with eslint.config.mjs
- Simplify configuration using @antfu/eslint-config
- Add necessary ESLint plugin dependencies
- Disable overly strict style rules
- Set package.json type to module for ESM support
- Fix ESLint disable comment format

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
lyzno1
2025-09-10 22:21:17 +08:00
parent 2b1882a5e3
commit 05dcfcf0ca
85 changed files with 464 additions and 502 deletions

View File

@ -17,7 +17,7 @@ import {
import Button from '@/app/components/base/button'
import cn from '@/utils/classnames'
type FileFromLinkOrLocalProps = {
interface FileFromLinkOrLocalProps {
showFromLink?: boolean
showFromLocal?: boolean
trigger: (open: boolean) => React.ReactNode
@ -38,8 +38,7 @@ const FileFromLinkOrLocal = ({
const disabled = !!fileConfig.number_limits && files.length >= fileConfig.number_limits
const handleSaveUrl = () => {
if (!url)
return
if (!url) { return }
if (!FILE_URL_REGEX.test(url)) {
setShowError(true)

View File

@ -1,6 +1,6 @@
import cn from '@/utils/classnames'
type FileImageRenderProps = {
interface FileImageRenderProps {
imageUrl: string
className?: string
alt?: string

View File

@ -4,7 +4,7 @@ import type { FileUpload } from './types'
import { FILE_EXTS } from './constants'
import { SupportUploadFileTypes } from './types'
type FileInputProps = {
interface FileInputProps {
fileConfig: FileUpload
}
const FileInput = ({
@ -18,8 +18,7 @@ const FileInput = ({
if (targetFiles) {
if (fileConfig.number_limits) {
for (let i = 0; i < targetFiles.length; i++) {
if (i + 1 + files.length <= fileConfig.number_limits)
handleLocalFileUpload(targetFiles[i])
if (i + 1 + files.length <= fileConfig.number_limits) { handleLocalFileUpload(targetFiles[i]) }
}
}
else {

View File

@ -24,7 +24,7 @@ import cn from '@/utils/classnames'
import ReplayLine from '@/app/components/base/icons/other/ReplayLine'
import ImagePreview from '@/app/components/base/image-uploader/image-preview'
type FileInAttachmentItemProps = {
interface FileInAttachmentItemProps {
file: FileEntity
showDeleteAction?: boolean
showDownloadAction?: boolean

View File

@ -67,7 +67,7 @@ const FILE_TYPE_ICON_MAP = {
color: 'text-[#00B2EA]',
},
}
type FileTypeIconProps = {
interface FileTypeIconProps {
type: FileAppearanceType
size?: 'sm' | 'lg' | 'md'
className?: string

View File

@ -148,8 +148,7 @@ export const useFile = (fileConfig: FileUpload) => {
const newFiles = produce(files, (draft) => {
const index = draft.findIndex(file => file.id === newFile.id)
if (index > -1)
draft[index] = newFile
if (index > -1) { draft[index] = newFile }
})
setFiles(newFiles)
}, [fileStore])
@ -198,10 +197,8 @@ export const useFile = (fileConfig: FileUpload) => {
const files = fileStore.getState().files
const file = files.find(file => file.id === fileId)
if (file && file.progress < 80 && file.progress >= 0)
handleUpdateFile({ ...file, progress: file.progress + 20 })
else
clearTimeout(timer)
if (file && file.progress < 80 && file.progress >= 0) { handleUpdateFile({ ...file, progress: file.progress + 20 }) }
else { clearTimeout(timer) }
}, 200)
}, [fileStore, handleUpdateFile])
const handleLoadFileFromLink = useCallback((url: string) => {
@ -235,10 +232,8 @@ export const useFile = (fileConfig: FileUpload) => {
notify({ type: 'error', message: t('common.fileUploader.fileExtensionNotSupport') })
handleRemoveFile(uploadingFile.id)
}
if (!checkSizeLimit(newFile.supportFileType, newFile.size))
handleRemoveFile(uploadingFile.id)
else
handleUpdateFile(newFile)
if (!checkSizeLimit(newFile.supportFileType, newFile.size)) { handleRemoveFile(uploadingFile.id) }
else { handleUpdateFile(newFile) }
}).catch(() => {
notify({ type: 'error', message: t('common.fileUploader.pasteFileLinkInvalid') })
handleRemoveFile(uploadingFile.id)
@ -263,8 +258,7 @@ export const useFile = (fileConfig: FileUpload) => {
}
const allowedFileTypes = fileConfig.allowed_file_types
const fileType = getSupportFileType(file.name, file.type, allowedFileTypes?.includes(SupportUploadFileTypes.custom))
if (!checkSizeLimit(fileType, file.size))
return
if (!checkSizeLimit(fileType, file.size)) { return }
const reader = new FileReader()
const isImage = file.type.startsWith('image')
@ -344,8 +338,7 @@ export const useFile = (fileConfig: FileUpload) => {
const file = e.dataTransfer.files[0]
if (file)
handleLocalFileUpload(file)
if (file) { handleLocalFileUpload(file) }
}, [handleLocalFileUpload])
return {

View File

@ -19,12 +19,12 @@ import Button from '@/app/components/base/button'
import cn from '@/utils/classnames'
import { TransferMethod } from '@/types/app'
type Option = {
interface Option {
value: string
label: string
icon: JSX.Element
}
type FileUploaderInAttachmentProps = {
interface FileUploaderInAttachmentProps {
fileConfig: FileUpload
}
const FileUploaderInAttachment = ({
@ -71,8 +71,7 @@ const FileUploaderInAttachment = ({
return (open: boolean) => renderButton(option, open)
}, [renderButton])
const renderOption = useCallback((option: Option) => {
if (option.value === TransferMethod.local_file && fileConfig?.allowed_file_upload_methods?.includes(TransferMethod.local_file))
return renderButton(option)
if (option.value === TransferMethod.local_file && fileConfig?.allowed_file_upload_methods?.includes(TransferMethod.local_file)) { return renderButton(option) }
if (option.value === TransferMethod.remote_url && fileConfig?.allowed_file_upload_methods?.includes(TransferMethod.remote_url)) {
return (
@ -109,7 +108,7 @@ const FileUploaderInAttachment = ({
)
}
type FileUploaderInAttachmentWrapperProps = {
interface FileUploaderInAttachmentWrapperProps {
value?: FileEntity[]
onChange: (files: FileEntity[]) => void
fileConfig: FileUpload

View File

@ -11,7 +11,7 @@ import type {
FileEntity,
} from './types'
type Shape = {
interface Shape {
files: FileEntity[]
setFiles: (files: FileEntity[]) => void
}
@ -34,8 +34,7 @@ export const FileContext = createContext<FileStore | null>(null)
export function useStore<T>(selector: (state: Shape) => T): T {
const store = useContext(FileContext)
if (!store)
throw new Error('Missing FileContext.Provider in the tree')
if (!store) { throw new Error('Missing FileContext.Provider in the tree') }
return useZustandStore(store, selector)
}
@ -44,7 +43,7 @@ export const useFileStore = () => {
return useContext(FileContext)!
}
type FileProviderProps = {
interface FileProviderProps {
children: React.ReactNode
value?: FileEntity[]
onChange?: (files: FileEntity[]) => void
@ -56,8 +55,7 @@ export const FileContextProvider = ({
}: FileProviderProps) => {
const storeRef = useRef<FileStore | undefined>(undefined)
if (!storeRef.current)
storeRef.current = createFileStore(value, onChange)
if (!storeRef.current) { storeRef.current = createFileStore(value, onChange) }
return (
<FileContext.Provider value={storeRef.current}>

View File

@ -17,7 +17,7 @@ export enum FileAppearanceTypeEnum {
export type FileAppearanceType = keyof typeof FileAppearanceTypeEnum
export type FileEntity = {
export interface FileEntity {
id: string
name: string
size: number
@ -32,7 +32,7 @@ export type FileEntity = {
isRemote?: boolean
}
export type EnabledOrDisabled = {
export interface EnabledOrDisabled {
enabled?: boolean
}
@ -41,7 +41,7 @@ export enum Resolution {
high = 'high',
}
export type FileUploadConfigResponse = {
export interface FileUploadConfigResponse {
batch_count_limit: number
image_file_size_limit?: number | string // default is 10MB
file_size_limit: number // default is 15MB
@ -71,7 +71,7 @@ export enum SupportUploadFileTypes {
custom = 'custom',
}
export type FileResponse = {
export interface FileResponse {
related_id: string
extension: string
filename: string

View File

@ -5,7 +5,7 @@ import { FILE_EXTS } from './constants'
import { upload } from '@/service/base'
import { TransferMethod } from '@/types/app'
type FileUploadParams = {
interface FileUploadParams {
file: File
onProgressCallback: (progress: number) => void
onSuccessCallback: (res: { id: string }) => void
@ -42,21 +42,17 @@ export const fileUpload: FileUpload = ({
export const getFileExtension = (fileName: string, fileMimetype: string, isRemote?: boolean) => {
let extension = ''
if (fileMimetype)
extension = mime.getExtension(fileMimetype) || ''
if (fileMimetype) { extension = mime.getExtension(fileMimetype) || '' }
if (fileName && !extension) {
const fileNamePair = fileName.split('.')
const fileNamePairLength = fileNamePair.length
if (fileNamePairLength > 1)
extension = fileNamePair[fileNamePairLength - 1]
else
extension = ''
if (fileNamePairLength > 1) { extension = fileNamePair[fileNamePairLength - 1] }
else { extension = '' }
}
if (isRemote)
extension = ''
if (isRemote) { extension = '' }
return extension
}
@ -64,50 +60,37 @@ export const getFileExtension = (fileName: string, fileMimetype: string, isRemot
export const getFileAppearanceType = (fileName: string, fileMimetype: string) => {
const extension = getFileExtension(fileName, fileMimetype)
if (extension === 'gif')
return FileAppearanceTypeEnum.gif
if (extension === 'gif') { return FileAppearanceTypeEnum.gif }
if (FILE_EXTS.image.includes(extension.toUpperCase()))
return FileAppearanceTypeEnum.image
if (FILE_EXTS.image.includes(extension.toUpperCase())) { return FileAppearanceTypeEnum.image }
if (FILE_EXTS.video.includes(extension.toUpperCase()))
return FileAppearanceTypeEnum.video
if (FILE_EXTS.video.includes(extension.toUpperCase())) { return FileAppearanceTypeEnum.video }
if (FILE_EXTS.audio.includes(extension.toUpperCase()))
return FileAppearanceTypeEnum.audio
if (FILE_EXTS.audio.includes(extension.toUpperCase())) { return FileAppearanceTypeEnum.audio }
if (extension === 'html')
return FileAppearanceTypeEnum.code
if (extension === 'html') { return FileAppearanceTypeEnum.code }
if (extension === 'pdf')
return FileAppearanceTypeEnum.pdf
if (extension === 'pdf') { return FileAppearanceTypeEnum.pdf }
if (extension === 'md' || extension === 'markdown' || extension === 'mdx')
return FileAppearanceTypeEnum.markdown
if (extension === 'md' || extension === 'markdown' || extension === 'mdx') { return FileAppearanceTypeEnum.markdown }
if (extension === 'xlsx' || extension === 'xls')
return FileAppearanceTypeEnum.excel
if (extension === 'xlsx' || extension === 'xls') { return FileAppearanceTypeEnum.excel }
if (extension === 'docx' || extension === 'doc')
return FileAppearanceTypeEnum.word
if (extension === 'docx' || extension === 'doc') { return FileAppearanceTypeEnum.word }
if (extension === 'pptx' || extension === 'ppt')
return FileAppearanceTypeEnum.ppt
if (extension === 'pptx' || extension === 'ppt') { return FileAppearanceTypeEnum.ppt }
if (FILE_EXTS.document.includes(extension.toUpperCase()))
return FileAppearanceTypeEnum.document
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
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
if ((FILE_EXTS[key]).includes(extension.toUpperCase())) { return key }
}
return ''
@ -144,8 +127,7 @@ export const getFileNameFromUrl = (url: string) => {
}
export const getSupportFileExtensionList = (allowFileTypes: string[], allowFileExtensions: string[]) => {
if (allowFileTypes.includes(SupportUploadFileTypes.custom))
return allowFileExtensions.map(item => item.slice(1).toUpperCase())
if (allowFileTypes.includes(SupportUploadFileTypes.custom)) { return allowFileExtensions.map(item => item.slice(1).toUpperCase()) }
return allowFileTypes.map(type => FILE_EXTS[type]).flat()
}
@ -174,11 +156,9 @@ export const getFilesInLogs = (rawData: any) => {
}
export const fileIsUploaded = (file: FileEntity) => {
if (file.uploadedId)
return true
if (file.uploadedId) { return true }
if (file.transferMethod === TransferMethod.remote_url && file.progress === 100)
return true
if (file.transferMethod === TransferMethod.remote_url && file.progress === 100) { return true }
}
export const downloadFile = (url: string, filename: string) => {