feat: setup HTTP server and bootstrap application
Setup HTTP server with Bun.serve and bootstrap Telegram bot and other services. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
4996d7548a
commit
99b820709d
@@ -0,0 +1,50 @@
|
|||||||
|
import { serve } from 'bun';
|
||||||
|
import logger from './utils/logger.js';
|
||||||
|
import { config } from './env.js';
|
||||||
|
import { startBot } from './bot.js';
|
||||||
|
import { handleUpload } from './routes/upload.js';
|
||||||
|
import { handleFileRedirect, handleFileInfo } from './routes/files.js';
|
||||||
|
import { handleHealth } from './routes/health.js';
|
||||||
|
import { cleanupRateLimitCache } from './utils/rateLimit.js';
|
||||||
|
|
||||||
|
const server = serve({
|
||||||
|
port: config.port,
|
||||||
|
routes: {
|
||||||
|
'/api/upload': {
|
||||||
|
POST: handleUpload
|
||||||
|
},
|
||||||
|
'/f/:public_id': {
|
||||||
|
GET: handleFileRedirect
|
||||||
|
},
|
||||||
|
'/file/:public_id/info': {
|
||||||
|
GET: handleFileInfo
|
||||||
|
},
|
||||||
|
'/health': {
|
||||||
|
GET: handleHealth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const bot = await startBot();
|
||||||
|
|
||||||
|
logger.info('Server started', { port: config.port, url: config.baseUrl });
|
||||||
|
|
||||||
|
const gracefulShutdown = async (signal) => {
|
||||||
|
logger.info('Graceful shutdown signal received', { signal });
|
||||||
|
|
||||||
|
logger.info('Closing HTTP server');
|
||||||
|
server.stop();
|
||||||
|
|
||||||
|
logger.info('Stopping Telegram bot');
|
||||||
|
await bot.stop();
|
||||||
|
|
||||||
|
logger.info('Server shutdown complete');
|
||||||
|
process.exit(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
|
||||||
|
process.on('SIGINT', () => gracefulShutdown('SIGINT'));
|
||||||
|
|
||||||
|
setInterval(cleanupRateLimitCache, 60000);
|
||||||
|
|
||||||
|
logger.info('Application running successfully');
|
||||||
Vendored
+63
@@ -0,0 +1,63 @@
|
|||||||
|
import { describe, it, expect, mock, beforeEach, afterAll } from "bun:test";
|
||||||
|
|
||||||
|
const mockServe = mock((options) => {
|
||||||
|
return {
|
||||||
|
port: options.port,
|
||||||
|
routes: options.routes,
|
||||||
|
stop: mock()
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const originalServe = Bun.serve;
|
||||||
|
Bun.serve = mockServe;
|
||||||
|
|
||||||
|
const mockStartBot = mock(() => Promise.resolve({
|
||||||
|
stop: mock()
|
||||||
|
}));
|
||||||
|
|
||||||
|
mock.module("../src/bot.js", () => ({
|
||||||
|
startBot: mockStartBot
|
||||||
|
}));
|
||||||
|
|
||||||
|
mock.module("../src/routes/upload.js", () => ({
|
||||||
|
handleUpload: mock()
|
||||||
|
}));
|
||||||
|
|
||||||
|
mock.module("../src/routes/files.js", () => ({
|
||||||
|
handleFileRedirect: mock(),
|
||||||
|
handleFileInfo: mock()
|
||||||
|
}));
|
||||||
|
|
||||||
|
mock.module("../src/routes/health.js", () => ({
|
||||||
|
handleHealth: mock()
|
||||||
|
}));
|
||||||
|
|
||||||
|
mock.module("../src/utils/rateLimit.js", () => ({
|
||||||
|
cleanupRateLimitCache: mock()
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("Bootstrap Server", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
mockServe.mockClear();
|
||||||
|
mockStartBot.mockClear();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
Bun.serve = originalServe;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should bootstrap the application successfully", async () => {
|
||||||
|
await import("../src/index.js");
|
||||||
|
|
||||||
|
expect(mockServe).toHaveBeenCalled();
|
||||||
|
expect(mockStartBot).toHaveBeenCalled();
|
||||||
|
|
||||||
|
const serveCallArgs = mockServe.mock.calls[0][0];
|
||||||
|
expect(serveCallArgs).toHaveProperty("port");
|
||||||
|
expect(serveCallArgs).toHaveProperty("routes");
|
||||||
|
expect(serveCallArgs.routes).toHaveProperty("/api/upload");
|
||||||
|
expect(serveCallArgs.routes).toHaveProperty("/f/:public_id");
|
||||||
|
expect(serveCallArgs.routes).toHaveProperty("/file/:public_id/info");
|
||||||
|
expect(serveCallArgs.routes).toHaveProperty("/health");
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user