jjf123 / src /utils /envParser.js
jjf1999's picture
Upload 138 files
ddce7e8 verified
Raw
History Blame Contribute Delete
3.37 kB
import fs from 'fs';
/**
* 解析 .env 文件内容为对象
* 支持多行字符串(用双引号或单引号包裹)
*/
export function parseEnvFile(filePath) {
const envData = {};
const content = fs.readFileSync(filePath, 'utf8');
const lines = content.split('\n');
let currentKey = null;
let currentValue = '';
let inMultiline = false;
let quoteChar = null;
for (let i = 0; i < lines.length; i++) {
let line = lines[i];
if (inMultiline) {
// 继续收集多行值
currentValue += '\n' + line;
// 检查是否结束(以引号结尾)
if (line.trimEnd().endsWith(quoteChar)) {
// 移除结尾引号
currentValue = currentValue.slice(0, -1);
envData[currentKey] = currentValue;
inMultiline = false;
currentKey = null;
currentValue = '';
quoteChar = null;
}
} else {
line = line.trim();
if (!line || line.startsWith('#')) continue;
const eqIndex = line.indexOf('=');
if (eqIndex === -1) continue;
const key = line.slice(0, eqIndex).trim();
let value = line.slice(eqIndex + 1);
// 检查是否是引号开头的多行字符串
const trimmedValue = value.trimStart();
if ((trimmedValue.startsWith('"') || trimmedValue.startsWith("'")) &&
!trimmedValue.endsWith(trimmedValue[0])) {
// 多行字符串开始
quoteChar = trimmedValue[0];
currentKey = key;
currentValue = trimmedValue.slice(1); // 移除开头引号
inMultiline = true;
} else {
// 单行值,移除可能的引号
value = value.trim();
if ((value.startsWith('"') && value.endsWith('"')) ||
(value.startsWith("'") && value.endsWith("'"))) {
value = value.slice(1, -1);
}
envData[key] = value;
}
}
}
// 处理未闭合的多行字符串
if (inMultiline && currentKey) {
envData[currentKey] = currentValue;
}
return envData;
}
/**
* 更新 .env 文件中的键值对
* 支持多行字符串(自动用双引号包裹)
*/
export function updateEnvFile(filePath, updates) {
let content = fs.readFileSync(filePath, 'utf8');
Object.entries(updates).forEach(([key, value]) => {
// 检查值是否包含换行符,如果包含则用双引号包裹
let formattedValue = value;
if (typeof value === 'string' && value.includes('\n')) {
// 多行字符串:用双引号包裹
formattedValue = `"${value}"`;
}
// 匹配整个键值对(包括可能的多行值)
// 1. 先尝试匹配单行格式
const singleLineRegex = new RegExp(`^${key}=.*$`, 'm');
// 2. 再尝试匹配多行格式(以引号开头,可能跨多行,以引号结尾)
const multiLineRegex = new RegExp(`^${key}=["']([\\s\\S]*?)["']$`, 'm');
if (multiLineRegex.test(content)) {
// 替换多行格式
content = content.replace(multiLineRegex, `${key}=${formattedValue}`);
} else if (singleLineRegex.test(content)) {
// 替换单行格式
content = content.replace(singleLineRegex, `${key}=${formattedValue}`);
} else {
// 键不存在,追加到文件末尾
content += `\n${key}=${formattedValue}`;
}
});
fs.writeFileSync(filePath, content, 'utf8');
}