import { readFileSync, writeFileSync } from "fs"; import { parse } from "dotenv"; import path from "path"; import { fileURLToPath } from "url"; export function buildConfig(configPath: string, target: string): void { // Read the config file const configContent = readFileSync(configPath, "utf-8"); // Extract variable names from config (e.g., DASHBOARD_URL, API_URL, EXPERIMENTS_URL) // Match both single and double quotes, empty or populated strings const matches = configContent.match(/(\w+):\s*['"][^'"]*['"]/g) ?? []; const variableNames = Object.keys( matches.reduce((acc: Record, match: string) => { const varName = match.split(":")[0]?.trim(); if (varName) acc[varName] = ""; return acc; }, {}), ); // Read root .env file const __dirname = path.dirname(fileURLToPath(import.meta.url)); const envPath = path.resolve(__dirname, "../../.env"); const envContent = readFileSync(envPath, "utf-8"); const envVars = parse(envContent); // Map config variables to .env variables (check PUBLIC_, VITE_, BUN_PUBLIC_, or plain name) const mappedValues: Record = {}; for (const varName of variableNames) { const publicKey = `PUBLIC_${varName}`; const viteKey = `VITE_${varName}`; const bunKey = `BUN_PUBLIC_${varName}`; mappedValues[varName] = envVars[publicKey] || envVars[viteKey] || envVars[bunKey] || envVars[varName] || ""; } // Apply runtime-specific config logic applyRuntimeSpecificConfig(target, mappedValues, envVars); // Generate new config content - replace all values regardless of current state let newConfigContent = configContent; for (const [varName, value] of Object.entries(mappedValues)) { // Match varName: 'anything' or "anything" and replace with new value (preserve single quotes) const regex = new RegExp(`${varName}:\\s*['"][^'"]*['"]`, "g"); newConfigContent = newConfigContent.replace( regex, `${varName}: '${value}'`, ); } // Write back to config file writeFileSync(configPath, newConfigContent, "utf-8"); console.log(`✅ Config file updated with environment values (${target})`); } function applyRuntimeSpecificConfig( target: string, mappedValues: Record, envVars: Record, ): void { switch (target) { case "core": // Core runtime specific config break; case "experiments": // Experiments runtime specific config break; case "tracking": // Tracking runtime specific config break; case "editorSetup": // Editor setup specific config break; } }