/ packages / frontend / src / utils / parse-dotenv.ts
parse-dotenv.ts
 1  export interface DotenvParseOutput {
 2    [name: string]: string;
 3  }
 4  
 5  /**
 6   * Parses a string in the .env file format into an object.
 7   *
 8   * See https://dotenvx.com/docs
 9   *
10   * @param lines - contents to be parsed. example: `'DB_HOST=localhost'`
11   * @returns an object with keys and values based on `lines`. example: `{ DB_HOST : 'localhost' }`
12   */
13  // yanked the parse routine from the dotenv lib, and modified it to operate directly on lines
14  const DOTENV_LINE =
15    /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
16  // Parse lines into an Object
17  export default function parseDotenv<
18    T extends DotenvParseOutput = DotenvParseOutput,
19  >(lines: string): T {
20    const obj: Record<string, string> = {};
21  
22    // Convert line breaks to same format
23    lines = lines.replace(/\r\n?/mg, "\n");
24  
25    let match;
26    while ((match = DOTENV_LINE.exec(lines)) != null) {
27      const key = match[1];
28  
29      // Default undefined or null to empty string
30      let value = match[2] || "";
31  
32      // Remove whitespace
33      value = value.trim();
34  
35      // Check if double quoted
36      const maybeQuote = value[0];
37  
38      // Remove surrounding quotes
39      value = value.replace(/^(['"`])([\s\S]*)\1$/mg, "$2");
40  
41      // Expand newlines if double quoted
42      if (maybeQuote === '"') {
43        value = value.replace(/\\n/g, "\n");
44        value = value.replace(/\\r/g, "\r");
45      }
46  
47      // Add to object
48      obj[key] = value;
49    }
50  
51    return obj as T;
52  }