lilith-platform.live/codebase/@features/user-data/website-backend-users/src/server.ts
2026-05-14 22:44:14 -07:00

73 lines
2.3 KiB
TypeScript

import { createServer, type IncomingMessage } from 'node:http';
import { Readable } from 'node:stream';
import { logger } from './logger';
import { handleRequest } from './router';
const PORT = parseInt(process.env['PORT'] ?? '4005', 10);
const COLLECTOR_URL = process.env['COLLECTOR_URL'] ?? 'http://localhost:4001';
const QUERY_API_URL = process.env['QUERY_API_URL'] ?? 'http://localhost:4003';
const ADMIN_URL = process.env['ADMIN_URL'] ?? 'http://localhost:3023';
async function readBody(req: IncomingMessage): Promise<Buffer> {
const chunks: Buffer[] = [];
for await (const chunk of req) {
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk as Uint8Array));
}
return Buffer.concat(chunks);
}
const server = createServer(async (req, res) => {
try {
const bodyBuf = ['GET', 'HEAD', 'OPTIONS'].includes(req.method ?? '')
? Buffer.alloc(0)
: await readBody(req);
const host = req.headers['host'] ?? 'localhost';
const url = new URL(req.url ?? '/', `http://${host}`);
if (url.pathname === '/health') {
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({ status: 'ok', service: 'analytics-website-backend' }));
return;
}
const headers = new Headers();
for (const [key, value] of Object.entries(req.headers)) {
if (value) headers.set(key, Array.isArray(value) ? value.join(', ') : value);
}
const webRequest = new Request(url, {
method: req.method ?? 'GET',
headers,
body: bodyBuf.length > 0 ? bodyBuf : undefined,
});
const response = await handleRequest(webRequest, url, {
collectorUrl: COLLECTOR_URL,
queryApiUrl: QUERY_API_URL,
adminUrl: ADMIN_URL,
});
res.statusCode = response.status;
response.headers.forEach((value, key) => res.setHeader(key, value));
if (!response.body) {
res.end();
return;
}
Readable.fromWeb(response.body as ReadableStream<Uint8Array>).pipe(res);
} catch (err) {
logger.error({ err }, 'Unhandled request error');
res.statusCode = 500;
res.end(JSON.stringify({ error: 'Internal server error' }));
}
});
server.listen(PORT, () => {
logger.info(
{ port: PORT, collector: COLLECTOR_URL, queryApi: QUERY_API_URL, admin: ADMIN_URL },
'Analytics website backend listening',
);
});