import * as plugins from '../plugins.ts'; import type { ObjectStorageContainer } from '../classes/objectstoragecontainer.ts'; import * as handlers from './handlers/index.ts'; import { files as bundledFiles } from '../../ts_bundled/bundle.ts'; export class OpsServer { public objectStorageRef: ObjectStorageContainer; public typedrouter = new plugins.typedrequest.TypedRouter(); public server!: plugins.typedserver.utilityservers.UtilityWebsiteServer; // Handler instances public adminHandler!: handlers.AdminHandler; public statusHandler!: handlers.StatusHandler; public bucketsHandler!: handlers.BucketsHandler; public objectsHandler!: handlers.ObjectsHandler; public configHandler!: handlers.ConfigHandler; public credentialsHandler!: handlers.CredentialsHandler; public policiesHandler!: handlers.PoliciesHandler; public auditHandler!: handlers.AuditHandler; constructor(objectStorageRef: ObjectStorageContainer) { this.objectStorageRef = objectStorageRef; } public async start(port = 3000) { this.server = new plugins.typedserver.utilityservers.UtilityWebsiteServer({ domain: 'localhost', feedMetadata: undefined, bundledContent: bundledFiles, addCustomRoutes: async (typedserver) => { typedserver.addRoute('/livez', 'GET', async () => { return this.jsonResponse({ ok: true, status: 'alive' }); }); typedserver.addRoute('/readyz', 'GET', async () => { const ready = await this.objectStorageRef.isReady(); return this.jsonResponse( { ok: ready, status: ready ? 'ready' : 'starting' }, ready ? 200 : 503, ); }); typedserver.addRoute('/healthz', 'GET', async () => { return this.jsonResponse(await this.objectStorageRef.getOperationalHealth()); }); typedserver.addRoute('/metrics', 'GET', async () => { const metrics = await this.objectStorageRef.getOperationalMetrics(); return new Response(metrics, { headers: { 'content-type': 'text/plain; version=0.0.4' }, }); }); }, }); // Chain typedrouters: server -> opsServer -> individual handlers this.server.typedrouter.addTypedRouter(this.typedrouter); // Set up all handlers await this.setupHandlers(); await this.server.start(port); console.log(`OpsServer started on http://localhost:${port}`); } private async setupHandlers(): Promise { // AdminHandler requires async initialization for JWT key generation this.adminHandler = new handlers.AdminHandler(this); await this.adminHandler.initialize(); // All other handlers self-register in their constructors this.statusHandler = new handlers.StatusHandler(this); this.bucketsHandler = new handlers.BucketsHandler(this); this.objectsHandler = new handlers.ObjectsHandler(this); this.configHandler = new handlers.ConfigHandler(this); this.credentialsHandler = new handlers.CredentialsHandler(this); this.policiesHandler = new handlers.PoliciesHandler(this); this.auditHandler = new handlers.AuditHandler(this); console.log('OpsServer TypedRequest handlers initialized'); } public async stop() { if (this.server) { await this.server.stop(); console.log('OpsServer stopped'); } } private jsonResponse(data: unknown, status = 200): Response { return new Response(JSON.stringify(data), { status, headers: { 'content-type': 'application/json' }, }); } }