-
Notifications
You must be signed in to change notification settings - Fork 8
Open
Labels
documentationImprovements or additions to documentationImprovements or additions to documentationenhancementNew feature or requestNew feature or requestgood first issueGood for newcomersGood for newcomershelp wantedExtra attention is neededExtra attention is neededquestionFurther information is requestedFurther information is requested
Description
Summary
Add first-class support for layered env files and variable interpolation so teams can validate realistic setups:
- Multiple files with deterministic precedence (e.g.,
.env→.env.local→.env.production). - Optional [
dotenv-expand]-style interpolation (e.g.,API_URL=${HOST}/api). - Clear reporting of the effective value and the source file for each key.
Why
Real projects rarely use a single .env. Without layering, validation diverges from production behavior and misses override bugs. Interpolation is common and currently unvalidated.
Proposal
New options
validateEnv({
schema,
files: [".env", ".env.local", ".env.production"], // left→right, later wins
precedence: "right-most-wins", // default
expand: true, // enable ${VAR} interpolation
expandErrorOnMissing: true, // fail if referenced var is missing
expandDetectCycles: true // protect against recursive loops
});CLI
env-guard \
--schema schema.json \
--files .env,.env.local,.env.production \
--expand \
--expand-error-on-missing \
--expand-detect-cyclesBehavior
- Load files in order; later files override earlier ones.
- Interpolate
${VAR}after merge, before schema checks. - On report, include
source(which file provided the winning value). - Mask secret values in all output (keep existing masking rules).
Examples
.env
HOST=https://example.com
PORT=3000
.env.local
PORT=3001
.env.production
API_URL=${HOST}/api
Effective:
HOST=https://example.com(source:.env)PORT=3001(source:.env.local)API_URL=https://example.com/api(source:.env.production)
Schema sample
const schema = {
HOST: { required: true, regex: /^https?:\/\// },
PORT: { required: true, type: "int", min: 1, max: 65535 },
API_URL: { requiredIf: { NODE_ENV: ["production"] }, regex: /^https?:\/\/.+\/api/ }
};Errors & Edge Cases
- Missing referenced var (
expandErrorOnMissing: true): throw withVAR_NOT_DEFINEDand show chain. - Interpolation cycle (
A=${B},B=${A}withexpandDetectCycles: true): throw withCYCLE_DETECTED, include trace. - Shadowing warning: if the same key exists in multiple files, log a note indicating overridden sources (non-fatal).
Reporting
Add to JSON/MD output:
{
"key": "API_URL",
"valueMasked": "https://example.com/api",
"source": ".env.production",
"overrides": [".env"]
}Acceptance Criteria
- Loading multiple files with deterministic right-most precedence.
- Interpolation of
${VAR}with optional strict missing detection. - Cycle detection with human-readable traces.
- Reports include
sourceandoverridesmetadata. - CLI flags as specified; docs updated with examples.
- 95%+ test coverage for merge, expand, cycles, error paths.
Nice-to-have (optional in follow-ups)
- Support
${VAR:-default}fallback syntax. - Per-file glob patterns (e.g.,
.env.*.local).
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
documentationImprovements or additions to documentationImprovements or additions to documentationenhancementNew feature or requestNew feature or requestgood first issueGood for newcomersGood for newcomershelp wantedExtra attention is neededExtra attention is neededquestionFurther information is requestedFurther information is requested