⬆️ Upgrade(custom): upgrade deps and fix lint error

This commit is contained in:
Kuingsmile
2026-03-20 11:33:09 +08:00
parent a25b3c6179
commit ae2fa03307
31 changed files with 926 additions and 971 deletions

View File

@@ -7,7 +7,7 @@ import simpleImportSort from 'eslint-plugin-simple-import-sort'
import pluginUnicorn from 'eslint-plugin-unicorn'
import pluginVue from 'eslint-plugin-vue'
import globals from 'globals'
import jsoncParser from 'jsonc-eslint-parser'
import * as jsoncParser from 'jsonc-eslint-parser'
import tseslint from 'typescript-eslint'
import vueParser from 'vue-eslint-parser'
@@ -153,7 +153,7 @@ export default defineConfig(
},
},
{
files: ['*.config.js', '.stylelintrc.cjs', 'scripts/*.{js,mjs,cjs}'],
files: ['*.config.js', '.stylelintrc.cjs', 'scripts/*.{js,mjs,cjs}', 'tests/*.{js,mjs,cjs}'],
languageOptions: {
globals: {
...globals.node,

View File

@@ -54,12 +54,13 @@
}
},
"resolutions": {
"baseline-browser-mapping": "^2.9.13"
"baseline-browser-mapping": "^2.9.13",
"semver": "^7.7.4"
},
"dependencies": {
"@aws-sdk/client-s3": "3.1012.0",
"@aws-sdk/lib-storage": "^3.1012.0",
"@aws-sdk/s3-request-presigner": "^3.1012.0",
"@aws-sdk/client-s3": "3.1013.0",
"@aws-sdk/lib-storage": "^3.1013.0",
"@aws-sdk/s3-request-presigner": "^3.1013.0",
"@nodelib/fs.walk": "^3.0.1",
"@octokit/rest": "^22.0.1",
"@piclist/i18n": "^2.0.0",
@@ -108,27 +109,27 @@
"@codemirror/theme-one-dark": "^6.1.3",
"@codemirror/view": "^6.40.0",
"@electron/notarize": "^3.1.1",
"@eslint/js": "^9.39.2",
"@eslint/js": "^10.0.1",
"@headlessui/vue": "^1.7.23",
"@highlightjs/vue-plugin": "^2.1.2",
"@intlify/unplugin-vue-i18n": "^11.1.1",
"@tailwindcss/vite": "^4.1.18",
"@tailwindcss/vite": "^4.2.2",
"@types/adm-zip": "^0.5.8",
"@types/ali-oss": "^6.23.3",
"@types/fs-extra": "^11.0.4",
"@types/js-yaml": "^4.0.9",
"@types/lodash-es": "^4.17.12",
"@types/multer": "^2.1.0",
"@types/node": "^25.0.3",
"@types/node": "^25.5.0",
"@types/semver": "^7.7.1",
"@types/tunnel": "^0.0.7",
"@types/upyun": "^3.4.3",
"@types/video.js": "^7.3.58",
"@types/write-file-atomic": "^4.0.3",
"@videojs-player/vue": "^1.0.0",
"@vitejs/plugin-vue": "^6.0.3",
"@vitejs/plugin-vue": "^6.0.5",
"@vueuse/core": "^14.2.1",
"baseline-browser-mapping": "^2.10.8",
"baseline-browser-mapping": "^2.10.9",
"codemirror": "^6.0.2",
"dexie": "^3.2.4",
"dotenv": "^17.3.1",
@@ -137,14 +138,14 @@
"electron-builder": "^26.0.12",
"electron-devtools-installer": "^4.0.0",
"electron-vite": "^5.0.0",
"eslint": "^9.39.2",
"eslint": "^10.0.3",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-jsonc": "^2.21.0",
"eslint-plugin-prettier": "^5.5.4",
"eslint-plugin-jsonc": "^3.1.2",
"eslint-plugin-prettier": "^5.5.5",
"eslint-plugin-simple-import-sort": "^12.1.1",
"eslint-plugin-unicorn": "^62.0.0",
"eslint-plugin-vue": "^10.6.2",
"globals": "^16.5.0",
"eslint-plugin-unicorn": "^63.0.0",
"eslint-plugin-vue": "^10.8.0",
"globals": "^17.4.0",
"highlight.js": "^11.11.1",
"husky": "^9.1.7",
"js-yaml": "^4.1.1",
@@ -155,22 +156,22 @@
"pinia-plugin-persistedstate": "^4.7.1",
"postcss": "^8.5.8",
"postcss-html": "^1.8.1",
"prettier": "^3.7.4",
"prettier": "^3.8.1",
"prettier-plugin-tailwindcss": "^0.7.2",
"qrcode.vue": "^3.6.0",
"stylelint": "^16.26.1",
"qrcode.vue": "^3.8.0",
"stylelint": "^17.5.0",
"stylelint-config-html": "^1.1.0",
"stylelint-config-standard": "^39.0.1",
"stylelint-config-standard": "^40.0.0",
"stylelint-config-standard-vue": "^1.0.0",
"stylelint-order": "^7.0.1",
"stylelint-order": "^8.1.1",
"stylus": "^0.64.0",
"tailwindcss": "^4.2.2",
"typescript": "5.8.2",
"typescript-eslint": "^8.52.0",
"typescript": "5.9.3",
"typescript-eslint": "^8.57.1",
"video.js": "^8.23.8",
"vite": "^7.3.1",
"vitest": "^4.0.16",
"vue-eslint-parser": "^10.2.0",
"vue-eslint-parser": "^10.4.0",
"vue-i18n": "^11.3.0",
"vue-router": "^5.0.3",
"vue-tsc": "^3.2.6",

View File

@@ -52,24 +52,6 @@ function combineYmlFiles(ymlFiles, outputPath) {
console.log(`Created ${outputPath} with ${combinedData?.files?.length || 0} file entries`)
}
function processSingleYmlFile(ymlFile, outputPath) {
if (!fs.existsSync(ymlFile)) {
console.log(`File not found: ${ymlFile}`)
return
}
const content = fs.readFileSync(ymlFile, 'utf8')
const data = yaml.load(content)
if (data && data.files) {
data.files = removeDuplicates(data.files)
}
const ymlContent = yaml.dump(data, { lineWidth: -1 })
fs.writeFileSync(outputPath, ymlContent, 'utf8')
console.log(`Processed ${outputPath} with ${data?.files?.length || 0} file entries`)
}
function findYmlInFolder(basePath, folderPattern, ymlFileName) {
const folders = fs.existsSync(basePath)
? fs.readdirSync(basePath).filter(f => {

View File

@@ -29,11 +29,9 @@ const handleClipboardUploadingReturnCtx = async (img?: IUploadOption): Promise<I
}
export const uploadClipboardFiles = async (): Promise<IStringKeyMap> => {
let img: ImgInfo[] | false = false
let backImg: ImgInfo[] | false = false
const res = await handleClipboardUploadingReturnCtx()
img = res.ctx?.output ? res.ctx.output : false
backImg = res.backupCtx?.output ? res.backupCtx.output : false
const img = res.ctx?.output ? res.ctx.output : false
const backImg = res.backupCtx?.output ? res.backupCtx.output : false
const allConfig = picgo.getConfig<any>() || {}
if (img !== false) {
if (img.length > 0) {
@@ -97,11 +95,9 @@ export const uploadChoosedFiles = async (
): Promise<IStringKeyMap[]> => {
const input = files.map(item => item.path)
const rawInput = cloneDeep(input)
let imgs: ImgInfo[] | false = false
let backImgs: ImgInfo[] | false = false
const res = await uploader.setWebContents(webContents).uploadReturnCtx(input)
imgs = res.ctx?.output ? res.ctx.output : false
backImgs = res.backupCtx?.output ? res.backupCtx.output : false
const imgs = res.ctx?.output ? res.ctx.output : false
const backImgs = res.backupCtx?.output ? res.backupCtx.output : false
const result = []
const allConfig = picgo.getConfig<any>() || {}
if (imgs !== false) {

View File

@@ -30,7 +30,7 @@ function dbChecker() {
if (!fs.existsSync(configFilePath)) {
return
}
let configFile: string = '{}'
let configFile: string
const optionsTpl = {
title: $t('TIPS_NOTICE'),
body: '',

View File

@@ -30,7 +30,7 @@ export default [
return true
} catch (err: any) {
logger.error(err)
throw new Error('Migrate failed')
throw new Error('Migrate failed', { cause: err })
}
},
type: IRPCType.INVOKE,
@@ -77,7 +77,7 @@ export default [
)
} catch (err: any) {
logger.error(err)
throw new Error('Migrate failed')
throw new Error('Migrate failed', { cause: err })
}
},
type: IRPCType.INVOKE,

View File

@@ -38,7 +38,7 @@ export default [
{
action: IRPCActionType.PICLIST_OPEN_FILE,
handler: async (_: IIPCEvent, args: [fileName: string]) => {
let abFilePath = path.join(STORE_PATH, args[0])
let abFilePath: string
switch (args[0]) {
case 'piclist.log':
abFilePath = appLogPath()

View File

@@ -224,7 +224,7 @@ class AliyunApi {
ipcMain.removeAllListeners(cancelDownloadLoadingFileList)
}
})
let res = {} as any
let res: any
const result = {
fullList: [] as any,
success: false,
@@ -279,7 +279,7 @@ class AliyunApi {
ipcMain.removeAllListeners('cancelLoadingFileList')
}
})
let res = {} as any
let res: any
const result = {
fullList: [] as any,
success: false,

View File

@@ -42,9 +42,8 @@ class GithubApi {
formatFolder(item: any, slicedPrefix: string, branch: string, repo: string, cdnUrl: string | undefined) {
const key = `${slicedPrefix ? `${slicedPrefix}/` : ''}${item.path}/`
let rawUrl = ''
const placeholders = ['{username}', '{repo}', '{branch}', '{path}']
rawUrl = cdnUrl
let rawUrl = cdnUrl
? placeholders.some(item => cdnUrl.includes(item))
? placeholders.reduce((url, ph) => {
const value =
@@ -78,10 +77,9 @@ class GithubApi {
}
formatFile(item: any, slicedPrefix: string, branch: string, repo: string, cdnUrl: string | undefined) {
let rawUrl = ''
const placeholders = ['{username}', '{repo}', '{branch}', '{path}']
const key = slicedPrefix === '' ? item.path : `${slicedPrefix}/${item.path}`
rawUrl = cdnUrl
let rawUrl = cdnUrl
? placeholders.some(item => cdnUrl.includes(item))
? placeholders.reduce((url, ph) => {
const value =
@@ -194,7 +192,6 @@ class GithubApi {
ipcMain.removeAllListeners(cancelDownloadLoadingFileList)
}
})
let res = {} as any
const result = {
fullList: [] as any,
success: false,
@@ -207,7 +204,7 @@ class GithubApi {
return result
}
const currentPrefix = treeQueue[0]
res = (await got(
const res = (await got(
`${this.baseUrl}/repos/${this.username}/${repo}/git/trees/${branch}:${treeQueue.shift()}`,
getOptions('GET', this.commonHeaders, {}, 'json', undefined, undefined, this.proxy),
)) as any
@@ -245,16 +242,15 @@ class GithubApi {
ipcMain.removeAllListeners('cancelLoadingFileList')
}
})
let res = {} as any
const result = {
fullList: [] as any,
success: false,
finished: false,
}
res = await got(
const res = (await got(
`${this.baseUrl}/repos/${this.username}/${repo}/git/trees/${branch}:${slicedPrefix}`,
getOptions('GET', this.commonHeaders, undefined, 'json', undefined, undefined, this.proxy),
)
)) as any
if (res && res.statusCode === 200) {
res.body.tree.forEach((item: any) => {
if (item.type === 'tree') {

View File

@@ -105,7 +105,7 @@ class ImgurApi {
ipcMain.removeAllListeners('cancelLoadingFileList')
}
})
let res = {} as any
let res: any
const result = {
fullList: [] as any,
success: false,

View File

@@ -84,14 +84,13 @@ class LocalApi {
ipcMain.removeAllListeners(cancelDownloadLoadingFileList)
}
})
let res = {} as any
const result = {
fullList: [] as any,
success: false,
finished: false,
}
try {
res = fsWalk.walkSync(this.transBack(prefix), {
const res = fsWalk.walkSync(this.transBack(prefix), {
followSymbolicLinks: true,
fs,
stats: true,

View File

@@ -246,7 +246,7 @@ class QiniuApi {
ipcMain.removeAllListeners(cancelDownloadLoadingFileList)
}
})
let res = {} as any
let res: any
const result = {
fullList: [] as any,
success: false,
@@ -308,7 +308,7 @@ class QiniuApi {
ipcMain.removeAllListeners('cancelLoadingFileList')
}
})
let res = {} as any
let res: any
const result = {
fullList: [] as any,
success: false,
@@ -384,14 +384,13 @@ class QiniuApi {
const slicedPrefix = prefix.slice(1)
const config = new qiniu.conf.Config()
const bucketManager = new qiniu.rs.BucketManager(this.mac, config)
let res = {} as any
const result = {
fullList: [] as any,
isTruncated: false,
nextMarker: '',
success: false,
}
res = await new Promise((resolve, reject) => {
const res = (await new Promise((resolve, reject) => {
bucketManager.listPrefix(
bucket,
{
@@ -411,7 +410,7 @@ class QiniuApi {
}
},
)
})
})) as any
if (res?.respInfo?.statusCode === 200) {
if (res.respBody?.commonPrefixes) {
res.respBody.commonPrefixes.forEach((item: string) => {
@@ -467,7 +466,7 @@ class QiniuApi {
const config = new qiniu.conf.Config()
const bucketManager = new qiniu.rs.BucketManager(this.mac, config)
let marker = ''
let isTruncated = true
let isTruncated: boolean
const allFileList = {
Contents: [] as any[],
}

View File

@@ -322,7 +322,7 @@ class S3plistApi {
ipcMain.removeAllListeners(cancelDownloadLoadingFileList)
}
})
let res = {} as ListObjectsV2CommandOutput
let res: ListObjectsV2CommandOutput
const result = {
fullList: [] as any,
success: false,
@@ -386,7 +386,7 @@ class S3plistApi {
ipcMain.removeAllListeners('cancelLoadingFileList')
}
})
let res = {} as ListObjectsV2CommandOutput
let res: ListObjectsV2CommandOutput
const result = {
fullList: [] as any,
success: false,

View File

@@ -160,7 +160,6 @@ class SftpApi {
ipcMain.removeAllListeners(cancelDownloadLoadingFileList)
}
})
let res = {} as any
const result = {
fullList: [] as any,
success: false,
@@ -168,7 +167,7 @@ class SftpApi {
}
try {
await this.connectClient()
res = await this.ctx.execCommand(`cd "${prefix}" && ls -la --time-style=long-iso`)
const res = await this.ctx.execCommand(`cd "${prefix}" && ls -la --time-style=long-iso`)
this.ctx.close()
if (this.isRequestSuccess(res.code)) {
const formatedLSRes = this.formatLSResult(res.stdout, prefix)
@@ -231,7 +230,6 @@ class SftpApi {
ipcMain.removeAllListeners('cancelLoadingFileList')
}
})
let res = {} as any
const result = {
fullList: [] as any,
success: false,
@@ -239,7 +237,7 @@ class SftpApi {
}
try {
await this.connectClient()
res = await this.ctx.execCommand(`cd "${prefix}" && ls -la --time-style=long-iso`)
const res = await this.ctx.execCommand(`cd "${prefix}" && ls -la --time-style=long-iso`)
this.ctx.close()
if (this.isRequestSuccess(res.code)) {
const formatedLSRes = this.formatLSResult(res.stdout, prefix)

View File

@@ -64,7 +64,7 @@ class SmmsApi {
ipcMain.removeAllListeners('cancelLoadingFileList')
}
})
let res = {} as any
let res: any
const result = {
fullList: [] as any,
success: false,

View File

@@ -120,7 +120,7 @@ class TcyunApi {
success: false,
finished: false,
}
let res = {} as COS.GetBucketResult
let res: COS.GetBucketResult
do {
res = await this.ctx.getBucket({
Bucket: bucket,
@@ -169,7 +169,7 @@ class TcyunApi {
ipcMain.removeAllListeners('cancelLoadingFileList')
}
})
let res = {} as COS.GetBucketResult
let res: COS.GetBucketResult
const result = {
fullList: [] as any,
success: false,

View File

@@ -180,7 +180,7 @@ class UpyunApi {
ipcMain.removeAllListeners('cancelLoadingFileList')
}
})
let res = {} as any
let res: any
const result = {
fullList: [] as any,
success: false,
@@ -230,14 +230,13 @@ class UpyunApi {
const { bucketName: bucket, prefix, marker, itemsPerPage } = configMap
const slicedPrefix = prefix.slice(1)
const urlPrefix = configMap.customUrl || `http://${bucket}.test.upcdn.net`
let res = {} as any
const result = {
fullList: [] as any,
isTruncated: false,
nextMarker: '',
success: false,
}
res = await this.cli.listDir(prefix, {
const res = await this.cli.listDir(prefix, {
limit: itemsPerPage,
iter: marker || '',
})
@@ -339,9 +338,8 @@ class UpyunApi {
}
} while (isTruncated)
if (allFileList.Contents.length > 0) {
let success = false
for (const allFileListItem of allFileList.Contents) {
success = await this.cli.deleteFile(allFileListItem.key)
const success = await this.cli.deleteFile(allFileListItem.key)
if (!success) {
return false
}

View File

@@ -108,17 +108,16 @@ class WebdavplistApi {
ipcMain.removeAllListeners(cancelDownloadLoadingFileList)
}
})
let res = {} as any
const result = {
fullList: [] as any,
success: false,
finished: false,
}
try {
res = await this.ctx.getDirectoryContents(prefix, {
const res = (await this.ctx.getDirectoryContents(prefix, {
deep: true,
details: true,
})
})) as any
if (this.isRequestSuccess(res.status)) {
if (res.data?.length) {
res.data.forEach((item: FileStat) => {
@@ -153,17 +152,16 @@ class WebdavplistApi {
ipcMain.removeAllListeners('cancelLoadingFileList')
}
})
let res = {} as any
const result = {
fullList: [] as any,
success: false,
finished: false,
}
try {
res = await this.ctx.getDirectoryContents(prefix, {
const res = (await this.ctx.getDirectoryContents(prefix, {
deep: false,
details: true,
})
})) as any
if (this.isRequestSuccess(res.status)) {
if (res.data?.length) {
res.data.forEach((item: FileStat) => {

View File

@@ -19,7 +19,7 @@ function manageDbChecker() {
if (!fs.existsSync(manageConfigFilePath)) {
return
}
let configFile: string = '{}'
let configFile: string
const optionsTpl = {
title: $t('TIPS_NOTICE'),
body: '',

View File

@@ -38,8 +38,8 @@ export async function dogecloudApi(
throw new Error('API Error')
}
return res.data.data
} catch (_e: any) {
throw new Error('API Error')
} catch (e: any) {
throw new Error('API Error', { cause: e })
}
}

View File

@@ -41,7 +41,7 @@ StartupNotify=true
}
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error)
throw new Error(`Failed to ${enable ? 'enable' : 'disable'} auto-start: ${errorMessage}`)
throw new Error(`Failed to ${enable ? 'enable' : 'disable'} auto-start: ${errorMessage}`, { cause: error })
}
}
@@ -55,6 +55,6 @@ export const isAutoStartEnabled = async (): Promise<boolean> => {
return fs.pathExists(desktopFile)
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error)
throw new Error(`Failed to check auto-start status: ${errorMessage}`)
throw new Error(`Failed to check auto-start status: ${errorMessage}`, { cause: error })
}
}

View File

@@ -350,8 +350,8 @@ export const extractData = async (zipPath: string): Promise<Record<string, any>>
const buffer = await fs.readFile(zipPath)
const str = strFromU8(gunzipSync(buffer))
return JSON.parse(str)
} catch (_err) {
throw new Error('Extract failed')
} catch (err) {
throw new Error('Extract failed', { cause: err })
}
}
@@ -360,8 +360,8 @@ export const zipData = async (data: Record<string, any>, zipPath: string): Promi
const buffer = Buffer.from(JSON.stringify(data))
const compressed = gzipSync(buffer)
await fs.writeFile(zipPath, Buffer.from(compressed))
} catch (_err) {
throw new Error('Zip failed')
} catch (err) {
throw new Error('Zip failed', { cause: err })
}
}

View File

@@ -63,8 +63,8 @@ async function dogecloudApi(
throw new Error('API Error')
}
return res.data.data
} catch (_err: any) {
throw new Error('API Error')
} catch (err: any) {
throw new Error('API Error', { cause: err })
}
}

View File

@@ -41,7 +41,7 @@ class SSHClient {
this._isConnected = true
return true
} catch (err: any) {
throw new Error(err)
throw new Error(err, { cause: err })
}
}

View File

@@ -72,7 +72,7 @@ const mergeGalleryDB = async (targetFile: string) => {
await fs.copyFile(targetFilePath, path.join(STORE_PATH, targetFile))
} catch (err: any) {
logger.error('merge gallery db failed:', String(err))
throw new Error('merge gallery db failed')
throw new Error('merge gallery db failed', { cause: err })
}
}
@@ -218,7 +218,7 @@ async function uploadFile(fileName: string[]): Promise<number> {
return 0
}
const uploadFunc = async (file: string): Promise<number> => {
let result = false
let result: boolean
try {
result = await updateLocalToRemote(syncConfig, file)
} catch (_e: any) {
@@ -559,7 +559,7 @@ async function checkCloudFileExist(syncConfig: ISyncConfig, fileName: string) {
}
} catch (error: any) {
logger.error(error)
throw new Error('check file exist failed')
throw new Error('check file exist failed', { cause: error })
}
}

View File

@@ -1252,7 +1252,7 @@ async function initData() {
globalAutoRename.value = allConfig.settings?.autoRename ?? false
globalManualRename.value = allConfig.settings?.rename ?? false
if (compressInFile) {
let cleanedObj = {}
let cleanedObj: Record<string, any>
try {
if (typeof compressInFile.formatConvertObj === 'object') {
cleanedObj = cleanFormatConvertObj(compressInFile.formatConvertObj)
@@ -1343,7 +1343,7 @@ async function initData() {
mergedWatermark[key as keyof IBuildInWaterMarkOptions] = mergedWatermark[mapFieldName][currentPicbedName]
}
})
let cleanedFormatConvertObj = {}
let cleanedFormatConvertObj: Record<string, any>
try {
const parsedObj = JSON.parse(singleConfigInFile.compress?.formatConvertObj as any)
cleanedFormatConvertObj = cleanFormatConvertObj(parsedObj)
@@ -1388,9 +1388,8 @@ function safeSetMapValue(form: any, fieldName: string, picbedType: string, value
const mapFieldName = `${fieldName}Map`
if (fieldName === 'formatConvertObj') {
value = value || '{}'
let parsedObj = {}
try {
parsedObj = JSON.parse(value)
const parsedObj = JSON.parse(value)
const cleanedObj = cleanFormatConvertObj(parsedObj)
if (JSON.stringify(cleanedObj) !== JSON.stringify(parsedObj)) {
value = JSON.stringify(cleanedObj)
@@ -1692,9 +1691,8 @@ watch(activeTab, () => {
})
watch(singleFormatConvertObj, () => {
let parsedObj = {}
try {
parsedObj = JSON.parse(singleFormatConvertObj.value)
const parsedObj = JSON.parse(singleFormatConvertObj.value)
const cleanedObj = cleanFormatConvertObj(parsedObj)
singleConfigSettings.value.compress!.formatConvertObj = cleanedObj
if (JSON.stringify(cleanedObj) !== JSON.stringify(parsedObj)) {
@@ -1706,9 +1704,8 @@ watch(singleFormatConvertObj, () => {
})
watch(formatConvertObjStr, () => {
let parsedObj = {}
try {
parsedObj = JSON.parse(formatConvertObjStr.value)
const parsedObj = JSON.parse(formatConvertObjStr.value)
const cleanedObj = cleanFormatConvertObj(parsedObj)
compressForm.value.formatConvertObj = cleanedObj
if (JSON.stringify(cleanedObj) !== JSON.stringify(parsedObj)) {

View File

@@ -47,7 +47,7 @@ const imageSource = computed(() => {
const iconPath = computed(() => `./assets/icons/${getFileIconPath(props.item.fileName ?? '')}`)
async function getWebdavHeader(key: string) {
let headers = {} as any
let headers: Record<string, any>
if (props.config.authType === 'digest') {
const authHeader = await getAuthHeader(
'GET',

View File

@@ -2007,16 +2007,16 @@ async function saveEditorContent() {
}
async function saveFile(file: string, content: string) {
let dataToSave = content
let formattedContent: string
try {
dataToSave = JSON.stringify(JSON.parse(content), null, 2)
formattedContent = JSON.stringify(JSON.parse(content), null, 2)
} catch (error) {
console.error('Invalid JSON content:', error)
message.error(t('pages.settings.advanced.invalidJson'))
return
}
try {
window.electron.sendRPC(IRPCActionType.WRITE_FILE_CONTENT, file, dataToSave)
window.electron.sendRPC(IRPCActionType.WRITE_FILE_CONTENT, file, formattedContent)
message.success(t('pages.settings.advanced.saveFileSuccess'))
setTimeout(() => {
window.electron.sendRPC(IRPCActionType.RELOAD_WINDOW)

View File

@@ -1,26 +1,37 @@
import { RELEASE_URL, RELEASE_URL_BACKUP } from '@/utils/static'
async function fetchData(url: string, options?: RequestInit) {
const response = await fetch(url, options)
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`, {
cause: { url, status: response.status },
})
}
return response
}
export const getLatestVersion = async (): Promise<string> => {
let primaryError: unknown
try {
const response = await fetch(RELEASE_URL)
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
const response = await fetchData(RELEASE_URL)
const normalList = await response.json()
return normalList[0].name
return normalList[0]?.name ?? ''
} catch (err) {
console.error('Error fetching latest version: ', err)
try {
const response = await fetch(`${RELEASE_URL_BACKUP}/latest.yml`)
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
const data = await response.text()
const r = window.node.yaml.parse(data).toJSON() as IStringKeyMap
return r.version
} catch (err) {
console.error('Error fetching backup latest version: ', err)
return ''
}
primaryError = err
console.warn('Primary version fetch failed, trying backup...', err)
}
try {
const response = await fetchData(`${RELEASE_URL_BACKUP}/latest.yml`)
const data = await response.text()
const r = window.node.yaml.parse(data).toJSON() as IStringKeyMap
return r.version || ''
} catch (backupErr) {
const finalError = new Error('Both primary and backup version fetch failed', {
cause: { primaryError, backupErr },
})
console.error(finalError)
return ''
}
}

View File

@@ -11,19 +11,18 @@
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"types": ["node"],
"typeRoots": ["./node_modules/@types", "./src/universal/types/"],
"paths": {
"@/*": ["src/renderer/*"],
"~/*": ["src/main/*"],
"@/*": ["./src/renderer/*"],
"~/*": ["./src/main/*"],
"root/*": ["./*"],
"#/*": ["src/universal/*"],
"apis/*": ["src/main/apis/*"],
"@core/*": ["src/main/apis/core/*"]
"#/*": ["./src/universal/*"],
"apis/*": ["./src/main/apis/*"],
"@core/*": ["./src/main/apis/core/*"]
},
"lib": ["ESNext", "dom", "dom.iterable", "ScriptHost"]
},
"include": ["src/**/*.ts", "src/**/*.vue", "src/**/*.d.ts", "tests/**/*.ts", "electron.vite.config.*"],
"exclude": ["node_modules", "dist", "out"]
"include": ["./src/**/*.ts", "./src/**/*.vue", "./src/**/*.d.ts", "./tests/**/*.ts", "./electron.vite.config.*"],
"exclude": ["./node_modules", "./dist", "./out"]
}

1627
yarn.lock

File diff suppressed because it is too large Load Diff