'use strict'; const http = require('node:http'); const { spawn } = require('node:child_process'); const path = require('node:path'); const { createLogger, createModuleServer, loadManifest } = require('./platform-module-sdk.cjs'); const manifest = loadManifest(path.join(__dirname, 'module.json')); const logger = createLogger({ moduleId: manifest.id }); const basePath = process.env.HUB_BASE_PATH || `/${manifest.slug}`; const nextPort = 3001; let shuttingDown = false; const nextServer = spawn(process.execPath, ['server.js'], { cwd: __dirname, env: { ...process.env, HOSTNAME: '127.0.0.1', PORT: String(nextPort) }, stdio: 'inherit', }); nextServer.once('exit', (code) => { if (shuttingDown) return; logger.error('Next.js-Prozess wurde beendet', { code }); process.exit(code || 1); }); const server = createModuleServer({ manifest, logger, identityRequired: true, routes(request, response, context) { const targetPath = `${basePath}${context.url.pathname}${context.url.search}`; const headers = { ...request.headers, host: `127.0.0.1:${nextPort}` }; for (const name of Object.keys(headers)) { if (name.startsWith('x-kalendartool-mpm-')) delete headers[name]; } headers['x-kalendartool-mpm-user-id'] = context.identity.userId; headers['x-kalendartool-mpm-username'] = context.identity.username; headers['x-kalendartool-mpm-display-name'] = context.identity.displayName || context.identity.username; headers['x-kalendartool-mpm-role'] = context.identity.role; const upstream = http.request({ host: '127.0.0.1', port: nextPort, method: request.method, path: targetPath, headers, }, (upstreamResponse) => { response.writeHead(upstreamResponse.statusCode || 502, upstreamResponse.headers); upstreamResponse.pipe(response); }); upstream.on('error', () => { if (!response.headersSent) { response.writeHead(502, { 'Content-Type': 'application/json' }); response.end(JSON.stringify({ statusCode: 502, message: 'Kalendertool ist noch nicht bereit' })); } else { response.end(); } }); request.pipe(upstream); }, }); function waitForNext(attempt = 0) { const probe = http.get({ host: '127.0.0.1', port: nextPort, path: `${basePath}/api/manifest`, headers: { 'x-kalendartool-mpm-user-id': 'readiness-probe', 'x-kalendartool-mpm-username': 'readiness-probe', 'x-kalendartool-mpm-display-name': 'readiness-probe', 'x-kalendartool-mpm-role': 'USER', }, }, (response) => { response.resume(); if (response.statusCode === 200) { const port = Number(process.env.PORT || manifest.port); server.listen(port, '0.0.0.0', () => logger.info('MPM-Modulserver gestartet', { port })); return; } retry(attempt); }); probe.on('error', () => retry(attempt)); } function retry(attempt) { if (attempt >= 119) { logger.error('Next.js wurde nicht rechtzeitig bereit'); process.exit(1); } setTimeout(() => waitForNext(attempt + 1), 250); } waitForNext(); function shutdown() { shuttingDown = true; if (server.listening) server.close(); nextServer.kill('SIGTERM'); } process.once('SIGTERM', shutdown); process.once('SIGINT', shutdown);