a78174279d
Fix #2289 invalidatePackage() only removed the plugin from USER_CONFIG_DIR/node_modules/, but bun may install it in CACHE_DIR/node_modules/ on some systems. This left a stale copy behind, causing the startup toast to keep showing the old version even after the auto-update completed successfully. Now both candidate locations are checked and removed so the reinstalled version is loaded on the next restart.
99 lines
2.8 KiB
TypeScript
99 lines
2.8 KiB
TypeScript
import * as fs from "node:fs"
|
|
import * as path from "node:path"
|
|
import { CACHE_DIR, PACKAGE_NAME, USER_CONFIG_DIR } from "./constants"
|
|
import { log } from "../../shared/logger"
|
|
|
|
interface BunLockfile {
|
|
workspaces?: {
|
|
""?: {
|
|
dependencies?: Record<string, string>
|
|
}
|
|
}
|
|
packages?: Record<string, unknown>
|
|
}
|
|
|
|
function stripTrailingCommas(json: string): string {
|
|
return json.replace(/,(\s*[}\]])/g, "$1")
|
|
}
|
|
|
|
function removeFromBunLock(packageName: string): boolean {
|
|
const lockPath = path.join(USER_CONFIG_DIR, "bun.lock")
|
|
if (!fs.existsSync(lockPath)) return false
|
|
|
|
try {
|
|
const content = fs.readFileSync(lockPath, "utf-8")
|
|
const lock = JSON.parse(stripTrailingCommas(content)) as BunLockfile
|
|
let modified = false
|
|
|
|
if (lock.workspaces?.[""]?.dependencies?.[packageName]) {
|
|
delete lock.workspaces[""].dependencies[packageName]
|
|
modified = true
|
|
}
|
|
|
|
if (lock.packages?.[packageName]) {
|
|
delete lock.packages[packageName]
|
|
modified = true
|
|
}
|
|
|
|
if (modified) {
|
|
fs.writeFileSync(lockPath, JSON.stringify(lock, null, 2))
|
|
log(`[auto-update-checker] Removed from bun.lock: ${packageName}`)
|
|
}
|
|
|
|
return modified
|
|
} catch {
|
|
return false
|
|
}
|
|
}
|
|
|
|
export function invalidatePackage(packageName: string = PACKAGE_NAME): boolean {
|
|
try {
|
|
const pkgDirs = [
|
|
path.join(USER_CONFIG_DIR, "node_modules", packageName),
|
|
path.join(CACHE_DIR, "node_modules", packageName),
|
|
]
|
|
const pkgJsonPath = path.join(USER_CONFIG_DIR, "package.json")
|
|
|
|
let packageRemoved = false
|
|
let dependencyRemoved = false
|
|
let lockRemoved = false
|
|
|
|
for (const pkgDir of pkgDirs) {
|
|
if (fs.existsSync(pkgDir)) {
|
|
fs.rmSync(pkgDir, { recursive: true, force: true })
|
|
log(`[auto-update-checker] Package removed: ${pkgDir}`)
|
|
packageRemoved = true
|
|
}
|
|
}
|
|
|
|
if (fs.existsSync(pkgJsonPath)) {
|
|
const content = fs.readFileSync(pkgJsonPath, "utf-8")
|
|
const pkgJson = JSON.parse(content)
|
|
if (pkgJson.dependencies?.[packageName]) {
|
|
delete pkgJson.dependencies[packageName]
|
|
fs.writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2))
|
|
log(`[auto-update-checker] Dependency removed from package.json: ${packageName}`)
|
|
dependencyRemoved = true
|
|
}
|
|
}
|
|
|
|
lockRemoved = removeFromBunLock(packageName)
|
|
|
|
if (!packageRemoved && !dependencyRemoved && !lockRemoved) {
|
|
log(`[auto-update-checker] Package not found, nothing to invalidate: ${packageName}`)
|
|
return false
|
|
}
|
|
|
|
return true
|
|
} catch (err) {
|
|
log("[auto-update-checker] Failed to invalidate package:", err)
|
|
return false
|
|
}
|
|
}
|
|
|
|
/** @deprecated Use invalidatePackage instead - this nukes ALL plugins */
|
|
export function invalidateCache(): boolean {
|
|
log("[auto-update-checker] WARNING: invalidateCache is deprecated, use invalidatePackage")
|
|
return invalidatePackage()
|
|
}
|