Spaces:
Paused
Paused
| /** Version manager tool state persistence. */ | |
| import { getDbInstance } from "./core"; | |
| interface VersionManagerRow { | |
| id?: unknown; | |
| tool?: unknown; | |
| current_version?: unknown; | |
| installed_version?: unknown; | |
| pinned_version?: unknown; | |
| binary_path?: unknown; | |
| status?: unknown; | |
| pid?: unknown; | |
| port?: unknown; | |
| api_key?: unknown; | |
| management_key?: unknown; | |
| auto_update?: unknown; | |
| auto_start?: unknown; | |
| last_health_check?: unknown; | |
| last_update_check?: unknown; | |
| health_status?: unknown; | |
| config_overrides?: unknown; | |
| error_message?: unknown; | |
| created_at?: unknown; | |
| updated_at?: unknown; | |
| } | |
| function toRecord(value: unknown): Record<string, unknown> { | |
| return value && typeof value === "object" ? (value as Record<string, unknown>) : {}; | |
| } | |
| function parseConfigOverrides(value: unknown): Record<string, unknown> | null { | |
| if (!value || typeof value !== "string" || value.trim() === "") return null; | |
| try { | |
| const parsed = JSON.parse(value); | |
| return typeof parsed === "object" && parsed !== null ? parsed : null; | |
| } catch { | |
| return null; | |
| } | |
| } | |
| function stringifyConfigOverrides(value: Record<string, unknown> | null): string | null { | |
| if (value === null) return null; | |
| try { | |
| return JSON.stringify(value); | |
| } catch { | |
| return null; | |
| } | |
| } | |
| interface VersionManagerTool { | |
| id: number; | |
| tool: string; | |
| currentVersion: string | null; | |
| installedVersion: string | null; | |
| pinnedVersion: string | null; | |
| binaryPath: string | null; | |
| status: string; | |
| pid: number | null; | |
| port: number; | |
| apiKey: string | null; | |
| managementKey: string | null; | |
| autoUpdate: boolean; | |
| autoStart: boolean; | |
| lastHealthCheck: string | null; | |
| lastUpdateCheck: string | null; | |
| healthStatus: string; | |
| configOverrides: Record<string, unknown> | null; | |
| errorMessage: string | null; | |
| createdAt: string; | |
| updatedAt: string; | |
| } | |
| function rowToVersionManager(row: VersionManagerRow): VersionManagerTool { | |
| const record = toRecord(row); | |
| return { | |
| id: typeof record.id === "number" ? record.id : 0, | |
| tool: typeof record.tool === "string" ? record.tool : "", | |
| currentVersion: | |
| record.current_version === null | |
| ? null | |
| : typeof record.current_version === "string" | |
| ? record.current_version | |
| : null, | |
| installedVersion: | |
| record.installed_version === null | |
| ? null | |
| : typeof record.installed_version === "string" | |
| ? record.installed_version | |
| : null, | |
| pinnedVersion: | |
| record.pinned_version === null | |
| ? null | |
| : typeof record.pinned_version === "string" | |
| ? record.pinned_version | |
| : null, | |
| binaryPath: | |
| record.binary_path === null | |
| ? null | |
| : typeof record.binary_path === "string" | |
| ? record.binary_path | |
| : null, | |
| status: typeof record.status === "string" ? record.status : "not_installed", | |
| pid: record.pid === null ? null : typeof record.pid === "number" ? record.pid : null, | |
| port: typeof record.port === "number" ? record.port : 8317, | |
| apiKey: | |
| record.api_key === null ? null : typeof record.api_key === "string" ? record.api_key : null, | |
| managementKey: | |
| record.management_key === null | |
| ? null | |
| : typeof record.management_key === "string" | |
| ? record.management_key | |
| : null, | |
| autoUpdate: | |
| record.auto_update === 1 || record.auto_update === true || record.auto_update === "1", | |
| autoStart: record.auto_start === 1 || record.auto_start === true || record.auto_start === "1", | |
| lastHealthCheck: | |
| record.last_health_check === null | |
| ? null | |
| : typeof record.last_health_check === "string" | |
| ? record.last_health_check | |
| : null, | |
| lastUpdateCheck: | |
| record.last_update_check === null | |
| ? null | |
| : typeof record.last_update_check === "string" | |
| ? record.last_update_check | |
| : null, | |
| healthStatus: typeof record.health_status === "string" ? record.health_status : "unknown", | |
| configOverrides: parseConfigOverrides(record.config_overrides), | |
| errorMessage: | |
| record.error_message === null | |
| ? null | |
| : typeof record.error_message === "string" | |
| ? record.error_message | |
| : null, | |
| createdAt: typeof record.created_at === "string" ? record.created_at : "", | |
| updatedAt: typeof record.updated_at === "string" ? record.updated_at : "", | |
| }; | |
| } | |
| export async function getVersionManagerStatus(): Promise<VersionManagerTool[]> { | |
| const db = getDbInstance(); | |
| const rows = db.prepare("SELECT * FROM version_manager").all() as VersionManagerRow[]; | |
| return rows.map(rowToVersionManager); | |
| } | |
| export async function getVersionManagerTool(tool: string): Promise<VersionManagerTool | null> { | |
| const db = getDbInstance(); | |
| const row = db.prepare("SELECT * FROM version_manager WHERE tool = ?").get(tool) as | |
| | VersionManagerRow | |
| | undefined; | |
| if (!row) return null; | |
| return rowToVersionManager(row); | |
| } | |
| export async function upsertVersionManagerTool(data: { | |
| tool: string; | |
| currentVersion?: string | null; | |
| installedVersion?: string | null; | |
| pinnedVersion?: string | null; | |
| binaryPath?: string | null; | |
| status?: string; | |
| pid?: number | null; | |
| port?: number; | |
| apiKey?: string | null; | |
| managementKey?: string | null; | |
| autoUpdate?: boolean; | |
| autoStart?: boolean; | |
| healthStatus?: string; | |
| configOverrides?: Record<string, unknown> | null; | |
| errorMessage?: string | null; | |
| }): Promise<VersionManagerTool> { | |
| const db = getDbInstance(); | |
| db.prepare( | |
| ` | |
| INSERT INTO version_manager ( | |
| tool, current_version, installed_version, pinned_version, binary_path, | |
| status, pid, port, api_key, management_key, auto_update, auto_start, | |
| health_status, config_overrides, error_message, created_at, updated_at | |
| ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now'), datetime('now')) | |
| ON CONFLICT(tool) DO UPDATE SET | |
| current_version = excluded.current_version, | |
| installed_version = excluded.installed_version, | |
| pinned_version = excluded.pinned_version, | |
| binary_path = excluded.binary_path, | |
| status = excluded.status, | |
| pid = excluded.pid, | |
| port = excluded.port, | |
| api_key = excluded.api_key, | |
| management_key = excluded.management_key, | |
| auto_update = excluded.auto_update, | |
| auto_start = excluded.auto_start, | |
| health_status = excluded.health_status, | |
| config_overrides = excluded.config_overrides, | |
| error_message = excluded.error_message, | |
| updated_at = datetime('now') | |
| ` | |
| ).run( | |
| data.tool, | |
| data.currentVersion ?? null, | |
| data.installedVersion ?? null, | |
| data.pinnedVersion ?? null, | |
| data.binaryPath ?? null, | |
| data.status ?? "not_installed", | |
| data.pid ?? null, | |
| data.port ?? 8317, | |
| data.apiKey ?? null, | |
| data.managementKey ?? null, | |
| data.autoUpdate !== undefined ? (data.autoUpdate ? 1 : 0) : 1, | |
| data.autoStart !== undefined ? (data.autoStart ? 1 : 0) : 0, | |
| data.healthStatus ?? "unknown", | |
| stringifyConfigOverrides(data.configOverrides ?? null), | |
| data.errorMessage ?? null | |
| ); | |
| const result = await getVersionManagerTool(data.tool); | |
| if (!result) throw new Error("Failed to retrieve inserted version manager tool"); | |
| return result; | |
| } | |
| export async function updateVersionManagerTool( | |
| tool: string, | |
| updates: Record<string, unknown> | |
| ): Promise<VersionManagerTool | null> { | |
| const db = getDbInstance(); | |
| const existing = await getVersionManagerTool(tool); | |
| if (!existing) return null; | |
| const ALLOWED_COLUMNS = new Set([ | |
| "currentVersion", | |
| "installedVersion", | |
| "pinnedVersion", | |
| "binaryPath", | |
| "status", | |
| "pid", | |
| "port", | |
| "apiKey", | |
| "managementKey", | |
| "autoUpdate", | |
| "autoStart", | |
| "healthStatus", | |
| "configOverrides", | |
| "errorMessage", | |
| ]); | |
| const sets: string[] = ["updated_at = datetime('now')"]; | |
| const params: Record<string, unknown> = { tool }; | |
| for (const [key, value] of Object.entries(updates)) { | |
| if (!ALLOWED_COLUMNS.has(key)) continue; | |
| const dbKey = key.replace(/([A-Z])/g, "_$1").toLowerCase(); | |
| if (key === "configOverrides") { | |
| sets.push("config_overrides = @configOverrides"); | |
| params.configOverrides = stringifyConfigOverrides(value as Record<string, unknown> | null); | |
| } else if (key === "autoUpdate" || key === "autoStart") { | |
| sets.push(`${dbKey} = @${key}`); | |
| params[key] = value === true ? 1 : 0; | |
| } else if (value === null) { | |
| sets.push(`${dbKey} = null`); | |
| } else { | |
| sets.push(`${dbKey} = @${key}`); | |
| params[key] = value; | |
| } | |
| } | |
| db.prepare(`UPDATE version_manager SET ${sets.join(", ")} WHERE tool = @tool`).run(params); | |
| return getVersionManagerTool(tool); | |
| } | |
| export async function deleteVersionManagerTool(tool: string): Promise<boolean> { | |
| const db = getDbInstance(); | |
| const result = db.prepare("DELETE FROM version_manager WHERE tool = ?").run(tool); | |
| return result.changes > 0; | |
| } | |
| export async function updateToolHealth(tool: string, healthStatus: string): Promise<boolean> { | |
| const db = getDbInstance(); | |
| const result = db | |
| .prepare( | |
| "UPDATE version_manager SET health_status = ?, last_health_check = datetime('now') WHERE tool = ?" | |
| ) | |
| .run(healthStatus, tool); | |
| return result.changes > 0; | |
| } | |
| export async function updateToolVersion( | |
| tool: string, | |
| field: "current_version" | "installed_version", | |
| version: string | |
| ): Promise<boolean> { | |
| const db = getDbInstance(); | |
| const result = db | |
| .prepare(`UPDATE version_manager SET ${field} = ?, updated_at = datetime('now') WHERE tool = ?`) | |
| .run(version, tool); | |
| return result.changes > 0; | |
| } | |
| export async function setToolStatus( | |
| tool: string, | |
| status: string, | |
| pid?: number, | |
| errorMessage?: string | |
| ): Promise<boolean> { | |
| const db = getDbInstance(); | |
| const result = db | |
| .prepare( | |
| pid !== undefined | |
| ? "UPDATE version_manager SET status = ?, pid = ?, error_message = ?, updated_at = datetime('now') WHERE tool = ?" | |
| : "UPDATE version_manager SET status = ?, error_message = ?, updated_at = datetime('now') WHERE tool = ?" | |
| ) | |
| .run( | |
| ...(pid !== undefined | |
| ? [status, pid, errorMessage ?? null, tool] | |
| : [status, errorMessage ?? null, tool]) | |
| ); | |
| return result.changes > 0; | |
| } | |