stabilizaiton work - projects rework for maintenanceability and ui livening

This commit is contained in:
master
2026-02-03 23:40:04 +02:00
parent 074ce117ba
commit 557feefdc3
3305 changed files with 186813 additions and 107843 deletions

View File

@@ -0,0 +1,146 @@
#!/usr/bin/env node
// Wrapper around `ng serve` that resolves the best binding:
// 1. https://stella-ops.local (port 443) — if hostname resolves and port is free
// 2. https://localhost:10000 — always available fallback
//
// Additionally binds http://stella-ops.local (port 80) as a redirect to HTTPS
// when the hostname resolves and port 80 is available.
const { spawn } = require('child_process');
const http = require('http');
const dns = require('dns');
const net = require('net');
const path = require('path');
const HOSTNAME = 'stella-ops.local';
const HTTPS_PORT = 443;
const HTTP_PORT = 80;
const DEV_PORT = 10000;
const SETUP_DOC = 'docs/technical/architecture/port-registry.md';
function isWindows() {
return process.platform === 'win32';
}
function hostsFilePath() {
return isWindows()
? 'C:\\Windows\\System32\\drivers\\etc\\hosts'
: '/etc/hosts';
}
function resolveHostnameIp(hostname) {
return new Promise((resolve) => {
dns.lookup(hostname, { family: 4 }, (err, address) => {
if (err) return resolve(null);
resolve(address);
});
});
}
function isPortAvailable(port, ip) {
return new Promise((resolve) => {
const server = net.createServer();
server.once('error', () => resolve(false));
server.once('listening', () => {
server.close(() => resolve(true));
});
server.listen(port, ip);
});
}
function startHttpRedirect(httpsHost, httpsPort, bindIp) {
return new Promise((resolve) => {
const server = http.createServer((req, res) => {
const location = `https://${httpsHost}${httpsPort === 443 ? '' : ':' + httpsPort}${req.url}`;
res.writeHead(301, { Location: location });
res.end();
});
server.on('error', (err) => {
console.warn(` HTTP redirect on port ${HTTP_PORT} failed: ${err.message}`);
resolve(false);
});
server.listen(HTTP_PORT, bindIp, () => {
console.log(` HTTP redirect active: http://${HOSTNAME} -> https://${httpsHost}${httpsPort === 443 ? '' : ':' + httpsPort}`);
console.log(` Bound to ${bindIp}:${HTTP_PORT}`);
resolve(true);
});
});
}
async function main() {
const extraArgs = process.argv.slice(2);
const resolvedIp = await resolveHostnameIp(HOSTNAME);
const hostnameOk = !!resolvedIp;
const port443Free = hostnameOk ? await isPortAvailable(HTTPS_PORT, resolvedIp) : false;
const port80Free = hostnameOk ? await isPortAvailable(HTTP_PORT, resolvedIp) : false;
let host, port;
if (hostnameOk && port443Free) {
host = HOSTNAME;
port = HTTPS_PORT;
console.log('');
console.log(` ${HOSTNAME} resolves to ${resolvedIp}; port ${HTTPS_PORT} is available.`);
console.log(` Dev server binding to https://${HOSTNAME}`);
console.log(` Also accessible at https://localhost:${DEV_PORT}`);
if (port80Free) {
const redirectOk = await startHttpRedirect(HOSTNAME, HTTPS_PORT, resolvedIp);
if (redirectOk) {
console.log(` Also accessible at http://${HOSTNAME} (redirects to HTTPS)`);
} else {
console.warn(` Failed to start HTTP redirect on ${resolvedIp}:${HTTP_PORT}`);
}
} else {
console.warn(` Port ${HTTP_PORT} on ${resolvedIp} is unavailable; skipping http://${HOSTNAME} redirect.`);
}
console.log('');
} else if (hostnameOk) {
host = HOSTNAME;
port = DEV_PORT;
console.warn('');
console.warn(` ${HOSTNAME} resolves to ${resolvedIp} but port ${HTTPS_PORT} is unavailable`);
console.warn(` (requires elevated privileges or is already in use).`);
console.warn(` Dev server binding to https://${HOSTNAME}:${DEV_PORT}`);
console.warn('');
} else {
host = 'localhost';
port = DEV_PORT;
console.warn('');
console.warn(` WARNING: ${HOSTNAME} does not resolve.`);
console.warn(` Dev server binding to https://localhost:${DEV_PORT}`);
console.warn('');
console.warn(` To use https://${HOSTNAME}, add to ${hostsFilePath()}:`);
console.warn('');
console.warn(` 127.1.0.1 ${HOSTNAME}`);
console.warn('');
console.warn(` See ${SETUP_DOC} for the full list of hostnames.`);
console.warn('');
}
runNgServe(host, port, extraArgs);
}
function runNgServe(host, port, extraArgs) {
const cwd = path.resolve(__dirname, '..');
const ngCli = path.resolve(cwd, 'node_modules', '@angular', 'cli', 'bin', 'ng.js');
// Pass the hostname (not IP) so Vite resolves it for both HTTPS and HMR websocket.
// The hostname resolves to a unique loopback IP via the hosts file, so ports
// won't collide with other services.
const args = ['serve', '--host', host, '--port', String(port), '--ssl', ...extraArgs];
console.log(` ng serve binding to ${host}:${port}`);
const child = spawn(process.execPath, [ngCli, ...args], {
stdio: 'inherit',
cwd,
});
child.on('exit', (code) => process.exit(code ?? 1));
}
main();