import { allApps, initApps, TOES_URL } from '$apps' import appsRouter from './api/apps' import syncRouter from './api/sync' import systemRouter from './api/system' import { Hype } from '@because/hype' const app = new Hype({ layout: false, logging: !!process.env.DEBUG }) app.route('/api/apps', appsRouter) app.route('/api/sync', syncRouter) app.route('/api/system', systemRouter) // Tool URLs: /tool/code?app=todo&file=README.md -> redirect to tool port app.get('/tool/:tool', c => { const toolName = c.req.param('tool') const tool = allApps().find(a => a.tool && a.name === toolName) if (!tool || tool.state !== 'running' || !tool.port) { return c.text(`Tool "${toolName}" not found or not running`, 404) } const params = new URLSearchParams(c.req.query()).toString() const base = new URL(TOES_URL) base.port = String(tool.port) const url = params ? `${base.origin}?${params}` : base.origin return c.redirect(url) }) // Tool API proxy: /api/tools/:tool/* -> proxy to tool port app.all('/api/tools/:tool/:path{.+}', async c => { const toolName = c.req.param('tool') const tool = allApps().find(a => a.tool && a.name === toolName) if (!tool || tool.state !== 'running' || !tool.port) { return c.json({ error: `Tool "${toolName}" not found or not running` }, 404) } const subPath = '/' + c.req.param('path') // Build target URL const params = new URLSearchParams(c.req.query()).toString() const targetUrl = params ? `http://localhost:${tool.port}${subPath}?${params}` : `http://localhost:${tool.port}${subPath}` // Proxy the request const response = await fetch(targetUrl, { method: c.req.method, headers: c.req.raw.headers, body: c.req.method !== 'GET' && c.req.method !== 'HEAD' ? c.req.raw.body : undefined, }) return new Response(response.body, { status: response.status, headers: response.headers, }) }) await initApps() export default { ...app.defaults, maxRequestBodySize: 1024 * 1024 * 50, // 50MB }