Build MVP with Pi installer and atomic updates

This commit is contained in:
2026-07-31 18:17:27 +02:00
parent e575ed2b2f
commit c52def7c37
35 changed files with 7762 additions and 1 deletions
+57
View File
@@ -0,0 +1,57 @@
import { resolve } from "node:path";
import { z } from "zod";
const booleanFromString = z
.enum(["true", "false"])
.default("false")
.transform((value) => value === "true");
const schema = z.object({
NODE_ENV: z.enum(["development", "test", "production"]).default("development"),
HOST: z.string().default("127.0.0.1"),
PORT: z.coerce.number().int().min(1).max(65_535).default(8787),
DATABASE_PATH: z.string().default(resolve("data/companion.db")),
SESSION_TTL_HOURS: z.coerce.number().positive().max(24 * 30).default(24),
COOKIE_SECURE: booleanFromString,
ALLOWED_ORIGINS: z.string().default("http://mg4pi.local:8787"),
UPDATE_STATUS_PATH: z.string().default("/var/lib/pi-car-companion/update-status.json"),
VERSION_FILE: z.string().default(resolve("REVISION"))
});
export type AppConfig = {
nodeEnv: "development" | "test" | "production";
host: string;
port: number;
databasePath: string;
sessionTtlMs: number;
cookieSecure: boolean;
allowedOrigins: ReadonlySet<string>;
updateStatusPath: string;
versionFile: string;
};
export function loadConfig(environment: NodeJS.ProcessEnv = process.env): AppConfig {
const parsed = schema.parse(environment);
const allowedOrigins = new Set(
parsed.ALLOWED_ORIGINS.split(",")
.map((origin) => origin.trim())
.filter(Boolean)
);
if (parsed.NODE_ENV === "development") {
allowedOrigins.add("http://localhost:5173");
allowedOrigins.add("http://127.0.0.1:5173");
}
return {
nodeEnv: parsed.NODE_ENV,
host: parsed.HOST,
port: parsed.PORT,
databasePath: parsed.DATABASE_PATH,
sessionTtlMs: parsed.SESSION_TTL_HOURS * 60 * 60 * 1000,
cookieSecure: parsed.COOKIE_SECURE,
allowedOrigins,
updateStatusPath: parsed.UPDATE_STATUS_PATH,
versionFile: parsed.VERSION_FILE
};
}