import express from 'express' import { WebSocketServer } from 'ws' import { createContainerPty } from './docker.js' import { getContainerPath, runCommand } from './utils.js' import path from 'path' import fs from 'fs/promises' const app = express() app.use(express.json()) app.get('/api/status', c => c.json(42)) app.get('/api/container/:uuid([a-zA-Z0-9-]+)/exec/ls/*', async (req, res) => { const uuid = req.params.uuid const p = path.normalize(req.params[0]) try { const files = await runCommand('/bin/ls', [path.join(getContainerPath('phc', uuid), p)]) res.json(files.trim().split('\n')) } catch (e) { res.json({ error: e.toString() }) } }) app.get('/api/container/:uuid([a-zA-Z0-9-]+)/fs/*', async (req, res) => { const uuid = req.params.uuid const p = path.normalize(req.params[0]) console.log('Getting', p) try { const content = await fs.readFile(path.join(getContainerPath('phc', uuid), p), 'utf8') res.json(content) } catch (e) { res.json({ error: e.toString() }) } }) app.put('/api/container/:uuid([a-zA-Z0-9-]+)/fs/*', async (req, res) => { const p = path.normalize(req.params[0]) const content = req.body console.log(content) try { await fs.writeFile(path.join(getContainerPath('phc', uuid), p), content) res.json('ok') } catch (e) { res.json({ error: e.toString() }) } }) const server = app.listen(5432, () => { console.log('Starting API server on :5432...') }) const wss = new WebSocketServer({ server }) wss.on('connection', async (ws, req) => { const tag = req.url.split('/').at(-2) console.log(`Client connected to "${tag}"`) const container = await createContainerPty(tag, { onData(data) { ws.send( JSON.stringify({ type: 'pty', data, }) ) }, onExit(e) { ws.send( JSON.stringify({ type: 'destroyed', ...e, }) ) ws.close() }, }) ws.send( JSON.stringify({ type: 'created', id: container.id, }) ) ws.on('message', data => { container.pty.write(data) }) ws.on('close', () => { container.pty.kill() console.log(`Client disconnected`) }) })