* Format a value for writing to .env file. * Handles special characters that require quoting. * Uses quoting strategy compatible with dotenv.parse().
(value: string)
| 9 | * Uses quoting strategy compatible with dotenv.parse(). |
| 10 | */ |
| 11 | function formatValue(value: string): string { |
| 12 | const needsQuotes = |
| 13 | value.includes('\n') || |
| 14 | value.includes('"') || |
| 15 | value.includes("'") || |
| 16 | value.includes(' ') || |
| 17 | value.includes('#') || |
| 18 | value.includes('$') || |
| 19 | value.includes('\\') || |
| 20 | value.startsWith(' ') || |
| 21 | value.endsWith(' ') |
| 22 | |
| 23 | if (!needsQuotes) { |
| 24 | return value |
| 25 | } |
| 26 | |
| 27 | // For values with newlines, we must use double quotes with \n escape |
| 28 | // (dotenv.parse handles \n in double-quoted values) |
| 29 | if (value.includes('\n')) { |
| 30 | const escaped = value.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n') |
| 31 | return `"${escaped}"` |
| 32 | } |
| 33 | |
| 34 | // For values with double quotes but no single quotes, use single quotes |
| 35 | // (dotenv.parse treats single-quoted values literally) |
| 36 | if (value.includes('"') && !value.includes("'")) { |
| 37 | return `'${value}'` |
| 38 | } |
| 39 | |
| 40 | // For values with single quotes but no double quotes, use double quotes |
| 41 | if (value.includes("'") && !value.includes('"')) { |
| 42 | const escaped = value.replace(/\\/g, '\\\\').replace(/\$/g, '\\$') |
| 43 | return `"${escaped}"` |
| 44 | } |
| 45 | |
| 46 | // For values with both quote types, leave unquoted if safe. |
| 47 | // dotenv.parse does not unescape \" in double-quoted values, so quoting would break roundtrip. |
| 48 | // Unquoted values work as long as there's no # (inline comment), no leading/trailing whitespace, |
| 49 | // and no newlines (already handled above). |
| 50 | if (value.includes('"') && value.includes("'")) { |
| 51 | if (!value.includes('#') && !value.startsWith(' ') && !value.endsWith(' ')) { |
| 52 | return value |
| 53 | } |
| 54 | // If value has both quote types AND # or leading/trailing spaces, there's a dotenv limitation. |
| 55 | // We do best-effort with double quotes + escaping, knowing backslashes will be preserved. |
| 56 | const escaped = value.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n') |
| 57 | return `"${escaped}"` |
| 58 | } |
| 59 | |
| 60 | // Default: use double quotes for other special chars |
| 61 | const escaped = value.replace(/\\/g, '\\\\').replace(/\$/g, '\\$') |
| 62 | return `"${escaped}"` |
| 63 | } |
| 64 | |
| 65 | /** |
| 66 | * Read and parse a .env file. |