← Files BranchaARCHIVED FILE
skills/brancha/app/src/server/nodes/node.routes.ts
2.57 KB · Oct 2, 2026 · 00:29 UTC
import { readJsonBody } from '../http/body.js';
import { Router } from '../http/router.js';
import { sendBuffer, sendJson, sendText } from '../http/response.js';
import { NodeService } from './node.service.js';
export function registerNodeRoutes(router: Router, service: NodeService) {
router.post('/api/projects/:projectId/nodes', async ({ req, res, params }) => {
sendJson(res, 200, service.create(params.projectId, await readJsonBody(req)));
});
router.post('/api/projects/:projectId/nodes/batch', async ({ req, res, params }) => {
sendJson(res, 200, service.createBatch(params.projectId, await readJsonBody(req)));
});
router.put('/api/nodes/:nodeId', async ({ req, res, params }) => {
sendJson(res, 200, service.update(params.nodeId, await readJsonBody(req)));
});
router.put('/api/nodes/:nodeId/artifact', async ({ req, res, params }) => {
sendJson(res, 200, service.updateArtifact(params.nodeId, await readJsonBody(req)));
});
router.put('/api/nodes/:nodeId/artifact/error', async ({ req, res, params }) => {
sendJson(res, 200, service.markArtifactError(params.nodeId, await readJsonBody(req)));
});
router.delete('/api/nodes/:nodeId/artifact', ({ res, params }) => {
sendJson(res, 200, service.clearArtifact(params.nodeId));
});
router.delete('/api/nodes/:nodeId', ({ res, params }) => {
sendJson(res, 200, service.delete(params.nodeId));
});
router.get('/api/nodes/:nodeId/html', ({ req, res, params }) => {
const artifact = service.html(params.nodeId);
const revision = new URL(req.url ?? '', 'http://127.0.0.1').searchParams.get('revision');
sendText(res, 200, artifact.document, 'text/html; charset=utf-8', {
'Cache-Control': revision ? 'private, max-age=31536000, immutable' : 'no-store',
'Content-Security-Policy': `${artifact.policy}; sandbox allow-scripts`,
'X-Frame-Options': 'SAMEORIGIN',
});
});
router.get('/api/nodes/:nodeId/content', ({ res, params }) => {
sendJson(res, 200, service.content(params.nodeId));
});
router.get('/api/nodes/:nodeId/artifact/source', ({ res, params }) => {
sendJson(res, 200, service.artifactSource(params.nodeId));
});
router.get('/api/nodes/:nodeId/artifact', ({ res, params }) => {
const artifact = service.artifact(params.nodeId);
sendBuffer(res, artifact.content, artifact.mime, {
'Cache-Control': 'no-store',
'Content-Security-Policy': "default-src 'none'; sandbox",
'Content-Disposition': `inline; filename*=UTF-8''${encodeURIComponent(artifact.filename)}`,
'Cross-Origin-Resource-Policy': 'cross-origin',
});
});
}
SHA-256: 9a5ca175429d5fac2d0d6bc50f59603a80a924989755d1d1865587ce37ed072f