77 lines
3.0 KiB
TypeScript
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,
|
|
},
|
|
};
|
|
});
|