feat: add instance management to dashboard

This commit is contained in:
chick
2026-07-07 23:04:32 +08:00
parent 182bd19c95
commit 2505ee561a
7 changed files with 267 additions and 12 deletions
+57 -1
View File
@@ -1,5 +1,5 @@
import { readFile } from 'node:fs/promises'
import { readFile, writeFile } from 'node:fs/promises'
import { existsSync } from 'node:fs'
import path from 'node:path'
@@ -47,6 +47,7 @@ export async function loadConfig({ configPath, defaultConfigPath }) {
}
return {
configPath: resolvedPath,
raw: { ...raw, instances },
server: {
host: raw.server?.host || process.env.HOST || '0.0.0.0',
port: Number(process.env.PORT || raw.server?.port || 8788),
@@ -55,6 +56,61 @@ export async function loadConfig({ configPath, defaultConfigPath }) {
}
}
function serializableInstance(instance) {
return {
id: instance.id,
name: instance.name,
url: instance.url,
description: instance.description || '',
tags: instance.tags || [],
auth: instance.auth?.password ? { mode: 'password', password: instance.auth.password } : { mode: 'none' },
capabilities: instance.capabilities || [],
}
}
async function persistConfig(config) {
const raw = {
...(config.raw || {}),
server: config.raw?.server || config.server,
instances: config.instances.map(serializableInstance),
}
await writeFile(config.configPath, `${JSON.stringify(raw, null, 2)}\n`)
config.raw = raw
}
export async function addInstanceToConfig(config, payload) {
const next = normalizeInstance(payload, config.instances.length)
if (config.instances.some(item => item.id === next.id)) throw new Error(`duplicate instance id: ${next.id}`)
config.instances.push(next)
await persistConfig(config)
return next
}
export async function updateInstanceInConfig(config, id, payload) {
const index = config.instances.findIndex(item => item.id === id)
if (index < 0) throw new Error(`instance not found: ${id}`)
const current = config.instances[index]
const merged = {
...current,
...payload,
id: payload.id ? String(payload.id).trim() : current.id,
auth: payload.auth !== undefined || payload.password !== undefined ? payload.auth || { password: payload.password || '' } : current.auth,
}
const next = normalizeInstance(merged, index)
if (next.id !== id && config.instances.some(item => item.id === next.id)) throw new Error(`duplicate instance id: ${next.id}`)
config.instances[index] = next
await persistConfig(config)
return next
}
export async function deleteInstanceFromConfig(config, id) {
const index = config.instances.findIndex(item => item.id === id)
if (index < 0) throw new Error(`instance not found: ${id}`)
const [removed] = config.instances.splice(index, 1)
await persistConfig(config)
return removed
}
export function redactInstance(instance) {
return {
id: instance.id,