| const http = require('http'); | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| const PORT = 5050; | |
| const MODELS_DIR = path.join(__dirname, '..', '..', 'models'); | |
| const FILE_MAP = { | |
| 'text': 'text.json', | |
| 'image': 'image.json', | |
| 'video': 'video.json', | |
| 'audio': 'audio.json', | |
| '3d': '3d.json' | |
| }; | |
| function sendJSON(res, data, status = 200) { | |
| res.writeHead(status, { | |
| 'Content-Type': 'application/json', | |
| 'Access-Control-Allow-Origin': '*', | |
| 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', | |
| 'Access-Control-Allow-Headers': 'Content-Type' | |
| }); | |
| res.end(JSON.stringify(data)); | |
| } | |
| function sendError(res, msg, status = 400) { | |
| sendJSON(res, { error: msg }, status); | |
| } | |
| function readBody(req) { | |
| return new Promise((resolve, reject) => { | |
| let body = ''; | |
| req.on('data', chunk => body += chunk); | |
| req.on('end', () => { | |
| try { resolve(JSON.parse(body)); } | |
| catch (e) { reject(new Error('Invalid JSON')); } | |
| }); | |
| }); | |
| } | |
| const server = http.createServer(async (req, res) => { | |
| if (req.method === 'OPTIONS') { | |
| res.writeHead(204, { | |
| 'Access-Control-Allow-Origin': '*', | |
| 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', | |
| 'Access-Control-Allow-Headers': 'Content-Type' | |
| }); | |
| return res.end(); | |
| } | |
| const url = new URL(req.url, `http://localhost:${PORT}`); | |
| if (url.pathname === '/' || url.pathname === '/index.html') { | |
| const html = fs.readFileSync(path.join(__dirname, 'index.html'), 'utf8'); | |
| res.writeHead(200, { 'Content-Type': 'text/html' }); | |
| return res.end(html); | |
| } | |
| if (url.pathname === '/api/files') { | |
| return sendJSON(res, { files: Object.keys(FILE_MAP) }); | |
| } | |
| if (url.pathname === '/api/providers') { | |
| const seen = new Set(); | |
| const presets = []; | |
| for (const filename of Object.values(FILE_MAP)) { | |
| let data; | |
| try { | |
| data = JSON.parse(fs.readFileSync(path.join(MODELS_DIR, filename), 'utf8')); | |
| } catch (e) { | |
| continue; | |
| } | |
| const entries = Array.isArray(data) | |
| ? data | |
| : [].concat(data.lightning || [], data.overrides || []); | |
| for (const model of entries) { | |
| if (!model || typeof model !== 'object') continue; | |
| const urls = Array.isArray(model.api_url) ? model.api_url : (model.api_url ? [model.api_url] : []); | |
| const envs = Array.isArray(model.api_key_env) ? model.api_key_env : (model.api_key_env ? [model.api_key_env] : []); | |
| urls.forEach((u, i) => { | |
| if (!u || seen.has(u)) return; | |
| seen.add(u); | |
| presets.push({ | |
| url: u, | |
| key: envs[i] || '', | |
| file: filename, | |
| model: model.name || model.id || '' | |
| }); | |
| }); | |
| } | |
| } | |
| presets.sort((a, b) => a.url.localeCompare(b.url)); | |
| return sendJSON(res, { presets }); | |
| } | |
| if (url.pathname.startsWith('/api/models/')) { | |
| const key = url.pathname.split('/api/models/')[1]; | |
| const filename = FILE_MAP[key]; | |
| if (!filename) return sendError(res, 'Unknown file key'); | |
| const filePath = path.join(MODELS_DIR, filename); | |
| if (req.method === 'GET') { | |
| try { | |
| const data = fs.readFileSync(filePath, 'utf8'); | |
| return sendJSON(res, JSON.parse(data)); | |
| } catch (e) { | |
| return sendError(res, `Failed to read ${filename}: ${e.message}`, 500); | |
| } | |
| } | |
| if (req.method === 'POST') { | |
| try { | |
| const body = await readBody(req); | |
| fs.writeFileSync(filePath, JSON.stringify(body, null, 4), 'utf8'); | |
| return sendJSON(res, { success: true, file: filename }); | |
| } catch (e) { | |
| return sendError(res, `Failed to write ${filename}: ${e.message}`, 500); | |
| } | |
| } | |
| } | |
| sendError(res, 'Not found', 404); | |
| }); | |
| server.listen(PORT, () => { | |
| console.log(`Model Editor running at http://localhost:${PORT}`); | |
| }); | |
Xet Storage Details
- Size:
- 3.83 kB
- Xet hash:
- 56dff3f7b282f166944da466d0453dd2eaaa5d46ef99d821b42f3801fad2a634
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.