Spaces:
Running
Running
| const fs = require('fs'); | |
| const path = require('path'); | |
| const { v4: uuidv4 } = require('uuid'); | |
| // 1. 寻找原项目在 Docker 容器内的 SQLite 数据库路径 | |
| const dbPaths = [ | |
| path.join(__dirname, 'server/prisma/dev.db'), | |
| path.join(__dirname, 'prisma/dev.db'), | |
| '/app/server/prisma/dev.db' | |
| ]; | |
| let dbPath = ''; | |
| for (const p of dbPaths) { | |
| if (fs.existsSync(p)) { | |
| dbPath = p; | |
| break; | |
| } | |
| } | |
| if (!dbPath) { | |
| console.log("⚠️ 未探测到初始数据库文件,正在尝试使用标准路径..."); | |
| dbPath = '/app/server/prisma/dev.db'; | |
| } | |
| // 2. 映射你配置的 HF Secrets 名字与项目数据库里的 Provider 标识 | |
| const secretsMap = { | |
| "GOOGLE_API_KEY": "google", | |
| "GROQ_API_KEY": "groq", | |
| "GITHUB_TOKEN": "github", | |
| "OPENROUTER_API_KEY": "openrouter", | |
| "MISTRAL_API_KEY": "mistral", | |
| "TOGETHER_API_KEY": "together", | |
| "NVIDIA_API_KEY": "nvidia", | |
| "COHERE_API_KEY": "cohere", | |
| "HF_TOKEN": "huggingface", | |
| "CEREBRAS_API_KEY": "cerebras", | |
| "SAMBANOVA_API_KEY": "sambanova", | |
| "CLOUDFLARE_API_TOKEN": "cloudflare", | |
| "ZHIPU_API_KEY": "zhipu" | |
| }; | |
| async function injectSecrets() { | |
| console.log(`📦 正在通过 Node.js 连接核心数据库: ${dbPath}`); | |
| // 动态载入原项目自带的 sqlite3 驱动(Prisma 底层自带或依赖 node-sqlite3) | |
| // 为了防止部分环境缺少原生绑定,我们使用原项目必定存在的更好办法:直接通过 sqlite3 库或执行 prisma 脚本 | |
| // 这里使用最稳妥的纯原生更好理解:由于原项目使用了 Prisma,直接用原生 fs 或通过 sqlite 写入 | |
| try { | |
| const sqlite3 = require('sqlite3').verbose(); | |
| const db = new sqlite3.Database(dbPath); | |
| db.serialize(() => { | |
| // 探测表名 | |
| db.all("SELECT name FROM sqlite_master WHERE type='table';", [], (err, tables) => { | |
| if (err) { | |
| console.error("❌ 读取数据库表失败:", err); | |
| return; | |
| } | |
| const tableNames = tables.map(t => t.name); | |
| console.log(`📊 探测到系统当前表结构: ${tableNames.join(', ')}`); | |
| const targetTable = tableNames.includes('Provider') ? 'Provider' : tableNames.find(t => t.toLowerCase().includes('key') || t.toLowerCase().includes('provider')); | |
| if (!targetTable) { | |
| console.log("❌ 未能识别到存储表,请在前端手动添加任意一个Key完成首次初始化。"); | |
| return; | |
| } | |
| let successCount = 0; | |
| const now = new Date().toISOString(); | |
| Object.entries(secretsMap).forEach(([secretName, providerId]) => { | |
| const actualKey = process.env[secretName]; // Node.js 读取环境变量的标准写法 | |
| if (!actualKey) return; | |
| // 检查是否存在 | |
| db.get(`SELECT id FROM ${targetTable} WHERE name = ? OR provider = ?`, [providerId, providerId], (err, row) => { | |
| if (!row) { | |
| const recordId = uuidv4(); | |
| // 尝试标准 Prisma 插入 | |
| db.run(`INSERT INTO ${targetTable} (id, name, provider, apiKey, status, createdAt, updatedAt) VALUES (?, ?, ?, ?, ?, ?, ?)`, | |
| [recordId, providerId, providerId, actualKey, 'active', now, now], | |
| function(err) { | |
| if (err) { | |
| // 备用极简插入 | |
| db.run(`INSERT INTO ${targetTable} (id, name, apiKey) VALUES (?, ?, ?)`, [recordId, providerId, actualKey]); | |
| } | |
| } | |
| ); | |
| successCount++; | |
| console.log(`✅ 成功自动恢复平台通道: ${providerId}`); | |
| } | |
| }); | |
| }); | |
| }); | |
| }); | |
| } catch (e) { | |
| console.log("⚠️ 正在等待系统原生 Prisma 初始化中,稍后将自动建立映射关系。"); | |
| } | |
| } | |
| injectSecrets(); |