Files
clash-verge-rev/src/services/update.ts
T
❤是纱雾酱哟~ afc32f568a chore(deps): Bump pnpm and cargo dependencies (#8022)
- Bump dependencies via `pnpm update`
- Bump dependencies via `cargo upgrade`
  - Incompatible dependencies already ignored
- Align Tauri-related dependencies version between `pnpm` and `cargo`
- Drop explicit forbidden of application downgrades

Assisted-by: vscode-copilot-chat:copilot:gpt-5.6-luna codegraph

Signed-off-by: ❤是纱雾酱哟~ <49941141+Dragon1573@users.noreply.github.com>
2026-09-23 07:03:15 +00:00

98 lines
2.7 KiB
TypeScript

import {
check,
type CheckOptions,
type Update,
} from '@tauri-apps/plugin-updater'
import { compareVersions as compareSemver } from 'compare-versions'
import { version as appVersion } from '@root/package.json'
const SEMVER_FULL_REGEX =
/^\d+(?:\.\d+){1,2}(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/
const SEMVER_SEARCH_REGEX =
/v?\d+(?:\.\d+){1,2}(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?/i
const normalizeVersion = (input: string | null | undefined): string | null => {
if (typeof input !== 'string') return null
const trimmed = input.trim()
if (!trimmed) return null
return trimmed.replace(/^v/i, '')
}
const ensureSemver = (input: string | null | undefined): string | null => {
const normalized = normalizeVersion(input)
if (!normalized) return null
return SEMVER_FULL_REGEX.test(normalized) ? normalized : null
}
const extractSemver = (input: string | null | undefined): string | null => {
if (typeof input !== 'string') return null
const match = input.match(SEMVER_SEARCH_REGEX)
if (!match) return null
return normalizeVersion(match[0])
}
const compareVersions = (a: string | null, b: string | null): number | null => {
if (!a || !b) return null
try {
return compareSemver(a, b)
} catch {
return null
}
}
const resolveRemoteVersion = (update: Update): string | null => {
const primary = ensureSemver(update.version)
if (primary) return primary
const fallbackPrimary = extractSemver(update.version)
if (fallbackPrimary) return fallbackPrimary
const raw = update.rawJson ?? {}
const rawVersion = ensureSemver(
typeof raw.version === 'string' ? raw.version : null,
)
if (rawVersion) return rawVersion
const tagVersion = extractSemver(
typeof raw.tag_name === 'string' ? raw.tag_name : null,
)
if (tagVersion) return tagVersion
const nameVersion = extractSemver(
typeof raw.name === 'string' ? raw.name : null,
)
if (nameVersion) return nameVersion
return null
}
const localVersionNormalized = normalizeVersion(appVersion)
export const checkUpdateSafe = async (
options?: CheckOptions,
): Promise<Update | null> => {
const result = await check(options ?? {})
if (!result) return null
const remoteVersion = resolveRemoteVersion(result)
const comparison = compareVersions(remoteVersion, localVersionNormalized)
const isBuildToStable =
/^\d+\.\d+\.\d+\+[0-9A-Za-z.-]+$/.test(localVersionNormalized ?? '') &&
remoteVersion === localVersionNormalized?.split('+')[0]
if (comparison !== null && comparison <= 0 && !isBuildToStable) {
try {
await result.close()
} catch (err) {
console.warn('[updater] failed to close stale update resource', err)
}
return null
}
return result
}
export type { CheckOptions }