import { existsSync, readFileSync } from "node:fs"; import { dirname, resolve } from "node:path"; import { fileURLToPath } from "node:url"; function resolveWorkspaceRoot() { return resolve(dirname(fileURLToPath(import.meta.url)), ".."); } export function resolveWorkspaceEnvPath(options = {}) { const { workspaceRoot = resolveWorkspaceRoot() } = options; return resolve(workspaceRoot, ".env"); } export function resolveWorkspaceEnvPaths(options = {}) { const { workspaceRoot = resolveWorkspaceRoot(), nodeEnv = process.env.NODE_ENV } = options; const candidates = [".env"]; if (nodeEnv) { candidates.push(`.env.${nodeEnv}`); } candidates.push(".env.local"); if (nodeEnv) { candidates.push(`.env.${nodeEnv}.local`); } return [...new Set(candidates.map((candidate) => resolve(workspaceRoot, candidate)))]; } export function loadWorkspaceEnv(options = {}) { const envPaths = resolveWorkspaceEnvPaths(options); const originalKeys = new Set(Object.keys(process.env)); const loadedPaths = []; for (const envPath of envPaths) { if (!existsSync(envPath)) { continue; } const contents = readFileSync(envPath, "utf8"); for (const rawLine of contents.split(/\r?\n/u)) { const line = rawLine.trim(); if (!line || line.startsWith("#")) { continue; } const separatorIndex = line.indexOf("="); if (separatorIndex <= 0) { continue; } const key = line.slice(0, separatorIndex).trim(); const rawValue = line.slice(separatorIndex + 1).trim(); const quoted = (rawValue.startsWith("\"") && rawValue.endsWith("\"")) || (rawValue.startsWith("'") && rawValue.endsWith("'")); const value = quoted ? rawValue.slice(1, -1) : rawValue; if (!originalKeys.has(key)) { process.env[key] = value; } } loadedPaths.push(envPath); } return loadedPaths; }