Files

77 lines
3.0 KiB
TypeScript

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,
},
};
});