Source: lib/env.js

import fs from 'fs';
import path from 'path';

/**
 * Parses the content of a .env file and returns an object of key-value pairs.
 * Matches dotenv behavior including single/double quotes and inline comments.
 * @param {string|Buffer} src
 * @returns {Object}
 */
export function parseEnv(src) {
  const obj = {};
  // Match standard env entries: KEY = VAL
  const regex = /^\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*|:\s*)\s*(?:("|')((?:\\\2|.)*?)\2|([^#\r\n]+?))?\s*(?:#.*)?$/;
  const lines = src.toString().split(/\r?\n/);
  for (const line of lines) {
    const match = line.match(regex);
    if (match) {
      const key = match[1];
      let val = '';
      if (match[2]) {
        // Quoted value
        val = match[3];
        if (match[2] === '"') {
          val = val.replace(/\\n/g, '\n').replace(/\\r/g, '\r');
        }
        // Unescape escaped quote character
        val = val.replace(new RegExp(`\\\\${match[2]}`, 'g'), match[2]);
      } else if (match[4]) {
        // Unquoted value
        val = match[4].trim();
      }
      obj[key] = val;
    }
  }
  return obj;
}

/**
 * Loads environment variables from the `.env` file in rootDir into process.env.
 * Does not overwrite existing environment variables.
 * @param {string} rootDir
 */
export function loadEnv(rootDir) {
  if (!rootDir) return;
  const envPath = path.join(rootDir, '.env');
  if (!fs.existsSync(envPath)) {
    return;
  }
  try {
    const content = fs.readFileSync(envPath, 'utf-8');
    const parsed = parseEnv(content);
    for (const key of Object.keys(parsed)) {
      if (process.env[key] === undefined) {
        process.env[key] = parsed[key];
      }
    }
  } catch {
    // Fail silently if reading fails
  }
}

/**
 * Replaces process.env.AVX_PUBLIC_... occurrences in the content
 * with their stringified values from process.env.
 * @param {string} content
 * @returns {string}
 */
export function replaceEnvVariables(content) {
  if (!content) return content;
  return content.replace(/process\.env\.AVX_PUBLIC_([a-zA-Z0-9_]+)/g, (match, key) => {
    const fullKey = 'AVX_PUBLIC_' + key;
    const val = process.env[fullKey];
    return val !== undefined ? JSON.stringify(val) : 'undefined';
  });
}