86 lines
3.2 KiB
TypeScript
86 lines
3.2 KiB
TypeScript
import express from 'express';
|
|
import { createServer as createHttpServer } from 'node:http';
|
|
import path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
import { createServer as createViteServer } from 'vite';
|
|
|
|
import healthRouter from './routes/health';
|
|
import llmRouter from './routes/llm';
|
|
import previewRouter from './routes/preview';
|
|
import artifactsRouter from './routes/artifacts';
|
|
import tenantRouter from './routes/tenant';
|
|
import bucketsRouter from './routes/buckets';
|
|
import gitRouter from './routes/git';
|
|
import codingSessionsRouter from './routes/codingSessions';
|
|
import codexAccountRouter from './routes/codexAccount';
|
|
import { requireRokcetAuth } from './auth';
|
|
import { developerMcpClientMetadata } from './services/bucketsMcpOAuth';
|
|
import { attachRokcetNodeGateway } from './services/rokcetNodeConnection';
|
|
import { attachWorkspaceHostGateway } from './services/workspaceHostConnection';
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
|
|
export function createApp() {
|
|
const app = express();
|
|
app.set('trust proxy', 1);
|
|
|
|
app.use(express.json({ limit: '25mb' }));
|
|
|
|
// Public OAuth Client ID Metadata Document for Buckets Developer MCP. In
|
|
// production this HTTPS URL is itself Rokcet's public OAuth client_id.
|
|
app.get('/.well-known/buckets-developer-mcp-client', (_req, res) => {
|
|
res.setHeader('Content-Type', 'application/client-metadata+json');
|
|
res.setHeader('Cache-Control', 'public, max-age=300');
|
|
res.json(developerMcpClientMetadata());
|
|
});
|
|
|
|
// Public health and authentication/session establishment. tenantRouter applies
|
|
// authentication internally to its workspace/deployment routes.
|
|
app.use('/api', healthRouter);
|
|
app.use('/api', tenantRouter);
|
|
|
|
// Rokcet workspace capabilities are product-session protected. A Buckets central
|
|
// SSO session is exchanged for a local Rokcet session before reaching these.
|
|
app.use('/api', requireRokcetAuth, llmRouter);
|
|
app.use('/api', requireRokcetAuth, artifactsRouter);
|
|
app.use('/api', requireRokcetAuth, bucketsRouter);
|
|
app.use('/api', requireRokcetAuth, gitRouter);
|
|
app.use('/api', requireRokcetAuth, codingSessionsRouter);
|
|
app.use('/api', requireRokcetAuth, codexAccountRouter);
|
|
|
|
// Preview compilation accepts generated source and therefore stays behind the
|
|
// Rokcet product session. Rendering is request-scoped and serverless-safe.
|
|
app.use('/api/preview', requireRokcetAuth);
|
|
app.use(previewRouter);
|
|
|
|
return app;
|
|
}
|
|
|
|
export async function startServer() {
|
|
const app = createApp();
|
|
const PORT = Number(process.env.PORT || 3000);
|
|
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
const vite = await createViteServer({
|
|
server: { middlewareMode: true },
|
|
appType: 'spa',
|
|
});
|
|
app.use(vite.middlewares);
|
|
} else {
|
|
const distPath = path.join(process.cwd(), 'dist');
|
|
app.use(express.static(distPath));
|
|
app.get('*', (req, res) => {
|
|
res.sendFile(path.join(distPath, 'index.html'));
|
|
});
|
|
}
|
|
|
|
const server = createHttpServer(app);
|
|
attachRokcetNodeGateway(server);
|
|
attachWorkspaceHostGateway(server);
|
|
server.listen(PORT, '0.0.0.0', () => {
|
|
console.log(`[Open WebUI Workspace Monorepo] Server listening at http://0.0.0.0:${PORT}`);
|
|
});
|
|
return server;
|
|
}
|