fix(cli): add backup and crash recovery to auth-plugins config write
Creates .bak before writeFileSync; on failure restores from backup and returns a descriptive error instead of corrupting the config.
This commit is contained in:
parent
88e1e3d0fa
commit
fb19e544c9
@ -1,4 +1,4 @@
|
|||||||
import { readFileSync, writeFileSync, copyFileSync } from "node:fs"
|
import { readFileSync, writeFileSync, copyFileSync, existsSync } from "node:fs"
|
||||||
import { modify, applyEdits } from "jsonc-parser"
|
import { modify, applyEdits } from "jsonc-parser"
|
||||||
import type { ConfigMergeResult, InstallConfig } from "../types"
|
import type { ConfigMergeResult, InstallConfig } from "../types"
|
||||||
import { getConfigDir } from "./config-context"
|
import { getConfigDir } from "./config-context"
|
||||||
@ -31,6 +31,7 @@ export async function addAuthPlugins(config: InstallConfig): Promise<ConfigMerge
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { format, path } = detectConfigFormat()
|
const { format, path } = detectConfigFormat()
|
||||||
|
const backupPath = `${path}.bak`
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let existingConfig: OpenCodeConfig | null = null
|
let existingConfig: OpenCodeConfig | null = null
|
||||||
@ -59,11 +60,13 @@ export async function addAuthPlugins(config: InstallConfig): Promise<ConfigMerge
|
|||||||
|
|
||||||
const newConfig = { ...(existingConfig ?? {}), plugin: plugins }
|
const newConfig = { ...(existingConfig ?? {}), plugin: plugins }
|
||||||
|
|
||||||
|
if (format !== "none" && existsSync(path)) {
|
||||||
|
copyFileSync(path, backupPath)
|
||||||
|
}
|
||||||
|
|
||||||
if (format === "jsonc") {
|
if (format === "jsonc") {
|
||||||
const content = readFileSync(path, "utf-8")
|
const content = readFileSync(path, "utf-8")
|
||||||
|
|
||||||
copyFileSync(path, `${path}.bak`)
|
|
||||||
|
|
||||||
const newContent = applyEdits(
|
const newContent = applyEdits(
|
||||||
content,
|
content,
|
||||||
modify(content, ["plugin"], plugins, {
|
modify(content, ["plugin"], plugins, {
|
||||||
@ -74,13 +77,62 @@ export async function addAuthPlugins(config: InstallConfig): Promise<ConfigMerge
|
|||||||
try {
|
try {
|
||||||
parseJsonc(newContent)
|
parseJsonc(newContent)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
copyFileSync(`${path}.bak`, path)
|
if (existsSync(backupPath)) {
|
||||||
|
copyFileSync(backupPath, path)
|
||||||
|
}
|
||||||
throw new Error(`Generated JSONC is invalid: ${error instanceof Error ? error.message : String(error)}`)
|
throw new Error(`Generated JSONC is invalid: ${error instanceof Error ? error.message : String(error)}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
writeFileSync(path, newContent)
|
try {
|
||||||
|
writeFileSync(path, newContent)
|
||||||
|
} catch (error) {
|
||||||
|
const hasBackup = existsSync(backupPath)
|
||||||
|
try {
|
||||||
|
if (hasBackup) {
|
||||||
|
copyFileSync(backupPath, path)
|
||||||
|
}
|
||||||
|
} catch (restoreError) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
configPath: path,
|
||||||
|
error: `Failed to write config file, and restore from backup failed: ${String(error)}; restore error: ${String(restoreError)}`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
configPath: path,
|
||||||
|
error: hasBackup
|
||||||
|
? `Failed to write config file. Restored from backup: ${String(error)}`
|
||||||
|
: `Failed to write config file. No backup was available: ${String(error)}`,
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
writeFileSync(path, JSON.stringify(newConfig, null, 2) + "\n")
|
const nextContent = JSON.stringify(newConfig, null, 2) + "\n"
|
||||||
|
try {
|
||||||
|
writeFileSync(path, nextContent)
|
||||||
|
} catch (error) {
|
||||||
|
const hasBackup = existsSync(backupPath)
|
||||||
|
try {
|
||||||
|
if (hasBackup) {
|
||||||
|
copyFileSync(backupPath, path)
|
||||||
|
}
|
||||||
|
} catch (restoreError) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
configPath: path,
|
||||||
|
error: `Failed to write config file, and restore from backup failed: ${String(error)}; restore error: ${String(restoreError)}`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
configPath: path,
|
||||||
|
error: hasBackup
|
||||||
|
? `Failed to write config file. Restored from backup: ${String(error)}`
|
||||||
|
: `Failed to write config file. No backup was available: ${String(error)}`,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return { success: true, configPath: path }
|
return { success: true, configPath: path }
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user