Files
venus/venus-html5-app/scripts/serve-local.js
dev 9756538f16 Initial commit: Venus OS boat addons monorepo
Organizes 11 projects for Cerbo GX/Venus OS into a single repository:
- axiom-nmea: Raymarine LightHouse protocol decoder
- dbus-generator-ramp: Generator current ramp controller
- dbus-lightning: Blitzortung lightning monitor
- dbus-meteoblue-forecast: Meteoblue weather forecast
- dbus-no-foreign-land: noforeignland.com tracking
- dbus-tides: Tide prediction from depth + harmonics
- dbus-vrm-history: VRM cloud history proxy
- dbus-windy-station: Windy.com weather upload
- mfd-custom-app: MFD app deployment package
- venus-html5-app: Custom Victron HTML5 app fork
- watermaker: Watermaker PLC control UI

Adds root README, .gitignore, project template, and per-project
.gitignore files. Sensitive config files excluded via .gitignore
with .example templates provided.

Made-with: Cursor
2026-03-16 17:04:16 +00:00

69 lines
1.8 KiB
JavaScript

const http = require("http")
const fs = require("fs")
const path = require("path")
const PORT = parseInt(process.env.SERVE_PORT, 10) || 3001
const DIST_DIR = path.resolve(__dirname, "..", "dist")
const APP_PREFIX = "/app"
const MIME_TYPES = {
".html": "text/html",
".js": "application/javascript",
".css": "text/css",
".json": "application/json",
".png": "image/png",
".jpg": "image/jpeg",
".svg": "image/svg+xml",
".ico": "image/x-icon",
".woff": "font/woff",
".woff2": "font/woff2",
".ttf": "font/ttf",
".map": "application/json",
".txt": "text/plain",
".webmanifest": "application/manifest+json",
}
const server = http.createServer((req, res) => {
let urlPath = req.url.split("?")[0]
if (urlPath === "/") {
res.writeHead(302, { Location: "/app/" })
res.end()
return
}
if (!urlPath.startsWith(APP_PREFIX)) {
res.writeHead(404)
res.end("Not Found")
return
}
let filePath = urlPath.slice(APP_PREFIX.length) || "/index.html"
if (filePath === "/") filePath = "/index.html"
const fullPath = path.join(DIST_DIR, filePath)
if (!fullPath.startsWith(DIST_DIR)) {
res.writeHead(403)
res.end("Forbidden")
return
}
fs.stat(fullPath, (err, stats) => {
if (!err && stats.isFile()) {
const ext = path.extname(fullPath)
const contentType = MIME_TYPES[ext] || "application/octet-stream"
res.writeHead(200, { "Content-Type": contentType })
fs.createReadStream(fullPath).pipe(res)
} else {
const indexPath = path.join(DIST_DIR, "index.html")
res.writeHead(200, { "Content-Type": "text/html" })
fs.createReadStream(indexPath).pipe(res)
}
})
})
server.listen(PORT, "0.0.0.0", () => {
console.log(`Serving venus-html5-app on http://0.0.0.0:${PORT}/app/`)
})