Support build-time ditto.json config file

Read an optional ditto.json (or CONFIG_FILE env) at build time, validate
it with Zod, and inject the result via Vite's define. At runtime the
build-time values are merged between the hardcoded defaults and user
localStorage, giving precedence: user > build-time > hardcoded.

Extract canonical Zod schemas into config/schema.ts (no path aliases)
so they can be imported from both vite.config.ts and runtime code.
Move AppConfigSchema out of AppProvider into src/lib/schemas.ts to
eliminate duplication.
This commit is contained in:
Alex Gleason
2026-02-26 17:53:54 -06:00
parent d45adf604a
commit 3eb92f472c
8 changed files with 228 additions and 126 deletions
+29
View File
@@ -1,8 +1,34 @@
import fs from "node:fs";
import path from "node:path";
import react from "@vitejs/plugin-react-swc";
import { defineConfig } from "vitest/config";
import { DittoConfigSchema } from "./config/schema";
/**
* Load and validate the build-time ditto.json configuration file.
* Returns the parsed config object, or `undefined` if the file doesn't exist.
* Set the CONFIG_FILE env var to override the default path ("./ditto.json").
*/
function loadDittoConfig(): object | undefined {
const configPath = path.resolve(process.env.CONFIG_FILE ?? "./ditto.json");
let raw: string;
try {
raw = fs.readFileSync(configPath, "utf-8");
} catch {
// File not found — no build-time config
return undefined;
}
const json = JSON.parse(raw);
const result = DittoConfigSchema.parse(json);
return result;
}
const dittoConfig = loadDittoConfig();
// https://vitejs.dev/config/
export default defineConfig(() => ({
server: {
@@ -12,6 +38,9 @@ export default defineConfig(() => ({
plugins: [
react(),
],
define: {
__DITTO_CONFIG__: JSON.stringify(dittoConfig ?? null),
},
test: {
globals: true,
environment: 'jsdom',