import { defineConfig } from "vitest/config"; import react from "@vitejs/plugin-react"; import { loadEnv } from "vite"; import { createHash } from "node:crypto"; import { fileURLToPath } from "node:url"; function buildValue(value: string | undefined): string | null { const normalized = value?.trim(); return normalized && !["unknown", "none", "null"].includes(normalized.toLowerCase()) ? normalized : null; } export default defineConfig(({ mode }) => { const env = loadEnv(mode, fileURLToPath(new URL(".", import.meta.url)), "VITE_"); const apiBaseUrl = env.VITE_API_BASE_URL || "http://localhost:8000"; const bindingInput = JSON.stringify({ api_base_url: apiBaseUrl, schema_version: 1, target: "modelforge-web", }); const buildProvenance = Object.freeze({ schema_version: 1 as const, target: "modelforge-web" as const, api_base_url: apiBaseUrl, binding_sha256: createHash("sha256").update(bindingInput).digest("hex"), }); // Keep the served provenance document on its established exact schema: the managed // security gate cryptographically binds that document to the API origin. Build identity is // deliberately a separate compile-time export so it can be shown to operators without // weakening or versioning that security contract. const buildStamp = Object.freeze({ version: buildValue(process.env.MODELFORGE_VERSION), source_commit: buildValue(process.env.MODELFORGE_COMMIT), built_at: buildValue(process.env.MODELFORGE_BUILT_AT), }); const provenanceModuleId = "\0virtual:modelforge-build-provenance"; return { plugins: [ react(), { name: "modelforge-build-provenance", resolveId(id: string) { return id === "virtual:modelforge-build-provenance" ? provenanceModuleId : null; }, load(id: string) { return id === provenanceModuleId ? `export const buildProvenance = Object.freeze(${JSON.stringify(buildProvenance)});\nexport const buildStamp = Object.freeze(${JSON.stringify(buildStamp)});` : null; }, generateBundle() { this.emitFile({ type: "asset", fileName: ".well-known/modelforge-build-provenance.json", source: `${JSON.stringify(buildProvenance)}\n`, }); }, }, ], server: { port: 3000, // Optional same-origin development bridge for browser acceptance against a real remote API. // Production builds never use it and no target is inferred when the variable is absent. proxy: env.VITE_API_PROXY_TARGET ? { "/api": { target: env.VITE_API_PROXY_TARGET, changeOrigin: false }, } : undefined, }, test: { environment: "jsdom", setupFiles: "./src/test/setup.ts", // One reusable worker keeps the release gate deterministic on operator // hosts that also run several long-lived local control-plane processes. pool: "threads", maxWorkers: 1, isolate: false, }, }; });