71 lines
2.0 KiB
TypeScript
71 lines
2.0 KiB
TypeScript
import { Hono } from 'hono';
|
|
import { serveStatic } from 'hono/bun';
|
|
import fs from 'fs';
|
|
// @ts-ignore Bun project may not have dotenv types configured
|
|
import { config } from 'dotenv';
|
|
|
|
config();
|
|
|
|
const app = new Hono();
|
|
|
|
// Minimal log helpers
|
|
const logLine = (path: string, line: string) => {
|
|
try {
|
|
fs.appendFileSync(path, `${new Date().toISOString()} ${line}\n`);
|
|
} catch (err) {
|
|
console.error('Failed to write log:', err);
|
|
}
|
|
};
|
|
|
|
// Version endpoint sourced from package.json
|
|
app.get('/version', (c) => {
|
|
try {
|
|
const pkgRaw = fs.readFileSync('./package.json', 'utf-8');
|
|
const pkg = JSON.parse(pkgRaw);
|
|
return c.json({ version: pkg.version || '0.0.0' });
|
|
} catch (err) {
|
|
logLine('logs/error.log', `version endpoint error: ${(err as Error)?.message || String(err)}`);
|
|
return c.json({ version: '0.0.0' }, 200);
|
|
}
|
|
});
|
|
|
|
// Serve static files from the frontend directory
|
|
app.use('/*', serveStatic({ root: './frontend' }));
|
|
|
|
// Error handler
|
|
app.onError((err, c) => {
|
|
logLine('logs/error.log', `Unhandled error: ${err?.message || err}`);
|
|
return c.text('Internal Server Error', 500);
|
|
});
|
|
|
|
// Mutation logging endpoint
|
|
app.post('/log-change', async (c) => {
|
|
try {
|
|
const body = await c.req.json();
|
|
const { action = 'unknown', user = 'unknown', target = '', detail = '' } = body || {};
|
|
const payload = JSON.stringify({ action, user, target, detail });
|
|
logLine('logs/changes.log', payload);
|
|
return c.json({ status: 'ok' });
|
|
} catch (err) {
|
|
logLine('logs/error.log', `log-change error: ${(err as Error)?.message || String(err)}`);
|
|
return c.text('Bad Request', 400);
|
|
}
|
|
});
|
|
|
|
const PORT = Number(process.env.PORT || 3000);
|
|
|
|
logLine('logs/server.log', `Starting frontend server on port ${PORT}`);
|
|
|
|
// Graceful shutdown logging
|
|
const shutdown = (signal: string) => {
|
|
logLine('logs/server.log', `Shutting down due to ${signal}`);
|
|
process.exit(0);
|
|
};
|
|
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
|
|
export default {
|
|
port: PORT,
|
|
fetch: app.fetch,
|
|
};
|