env-sentinel
Version:
Zero-dependency tool that auto-validates .env files against schema.env, with optional fallback and secure warnings.
81 lines (80 loc) • 2.63 kB
JavaScript
import { parseRuleString } from '../index.js';
import { validatorRegistry } from '../validator-registry.js';
export function validate(envValues, schema, fileContent) {
const issues = [];
let errors = 0;
let warnings = 0;
const notices = 0;
const lineMap = new Map();
if (fileContent) {
const lines = fileContent.split(/\r?\n/);
lines.forEach((line, index) => {
const trimmedLine = line.trim();
if (trimmedLine && !trimmedLine.startsWith('#')) {
const equalIndex = trimmedLine.indexOf('=');
if (equalIndex !== -1) {
const key = trimmedLine.substring(0, equalIndex).trim();
lineMap.set(key, index + 1);
}
}
});
}
for (const [key, ruleString] of Object.entries(schema)) {
const rules = parseRuleString(ruleString);
const value = envValues[key];
const isRequired = rules.some((rule) => rule.name === 'required');
if (isRequired && (value === undefined || value === '')) {
issues.push({
key,
message: `Missing required variable: ${key}`,
severity: 'error',
rule: 'required',
line: lineMap.get(key) || undefined,
});
errors++;
continue;
}
if (value === undefined) {
continue;
}
for (const rule of rules) {
if (rule.name === 'required') {
continue;
}
const validator = validatorRegistry.get(rule.name);
if (!validator) {
issues.push({
key,
message: `Unknown rule '${rule.name}' for ${key}`,
severity: 'warning',
rule: rule.name,
line: lineMap.get(key) || undefined,
});
warnings++;
continue;
}
const result = validator(key, value, rule.args);
if (result !== true) {
issues.push({
key,
message: result,
severity: 'error',
rule: rule.name,
value,
line: lineMap.get(key) || undefined,
});
errors++;
}
}
}
return {
isValid: errors === 0,
issues,
summary: {
total: issues.length,
errors,
warnings,
notices,
},
};
}