// Tiny .env reader (the repo hand-parses .env; no dotenv dependency).
const fs = require("fs");
const path = require("path");
// .env lives at the repo root (shared with other scripts) and may sit several
// directories above this module — walk up from __dirname until we find it.
function findEnvFile() {
let dir = __dirname;
for (let i = 0; i < 10; i++) {
const p = path.join(dir, ".env");
if (fs.existsSync(p)) return p;
const parent = path.dirname(dir);
if (parent === dir) break;
dir = parent;
}
return path.join(__dirname, "..", ".env"); // fallback
}
let cache = null;
function loadEnv() {
if (cache) return cache;
cache = {};
let text = "";
try {
text = fs.readFileSync(findEnvFile(), "utf8");
} catch {
return cache;
}
for (const line of text.split(/\r?\n/)) {
// Allow mixed-case keys (e.g. Brightdata_Username).
const m = line.match(/^\s*([A-Za-z0-9_]+)\s*=\s*(.*)\s*$/);
if (m) cache[m[1]] = m[2].replace(/^["']|["']$/g, "").trim();
}
return cache;
}
// Case-insensitive lookup against process.env then the .env file.
function lookup(key) {
if (process.env[key]) return process.env[key];
const file = loadEnv();
if (file[key]) return file[key];
const lc = key.toLowerCase();
for (const k of Object.keys(file)) if (k.toLowerCase() === lc) return file[k];
for (const k of Object.keys(process.env))
if (k.toLowerCase() === lc && process.env[k]) return process.env[k];
return null;
}
function env(key, { required = false } = {}) {
const v = lookup(key);
if (required && !v) {
throw new Error(
`Missing required env var ${key}. Add it to .env (or export it).`,
);
}
return v;
}
// First non-empty value among several candidate key names.
function envAny(names, { required = false } = {}) {
for (const n of names) {
const v = lookup(n);
if (v) return v;
}
if (required) throw new Error(`Missing env var (tried: ${names.join(", ")}).`);
return null;
}
module.exports = { env, envAny, loadEnv };