env-sentinel
Version:
Zero-dependency tool that auto-validates .env files against schema.env, with optional fallback and secure warnings.
38 lines (37 loc) • 1.55 kB
JavaScript
const REFERENCE_REGEX = /(?<!\\)(\$\{(?<key1>[A-Za-z_][A-Za-z0-9_]*)\}|\{\$(?<key2>[A-Za-z_][A-Za-z0-9_]*)\}|\$(?<key3>[A-Za-z_][A-Za-z0-9_]*))/;
export function parseEnvContent(rawEnvContent) {
const env = {};
const lines = rawEnvContent.split(/\r?\n/).filter((line) => line.trim() && !line.trim().startsWith('#'));
const linesWithReferences = [];
for (const line of lines) {
const [key, ...rest] = line.split('=');
const trimmedKey = key.trim();
if (!trimmedKey)
continue;
let value = rest.join('=').trim();
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
value = value.slice(1, -1);
}
if (REFERENCE_REGEX.test(value)) {
linesWithReferences.push({ key: trimmedKey, value });
continue;
}
env[trimmedKey] = value;
}
for (const line of linesWithReferences) {
const { key, value } = line;
env[key] = value.replace(REFERENCE_REGEX, (match) => {
const referencedKey = getReferencedKey(match);
const referencedValue = env[referencedKey];
if (referencedValue === undefined) {
throw new Error(`Referenced key "${referencedKey}" not found in the env.`);
}
return referencedValue;
});
}
return env;
}
function getReferencedKey(key) {
const { groups } = REFERENCE_REGEX.exec(key);
return groups.key1 || groups.key2 || groups.key3 || key;
}