@danielszlaski/envguard 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/.envguardrc.example.json +1 -0
  2. package/.envguardrc.json +16 -0
  3. package/.github/FUNDING.yml +15 -0
  4. package/LICENSE +1 -1
  5. package/README.md +246 -11
  6. package/dist/analyzer/envAnalyzer.d.ts +8 -2
  7. package/dist/analyzer/envAnalyzer.d.ts.map +1 -1
  8. package/dist/analyzer/envAnalyzer.js +22 -8
  9. package/dist/analyzer/envAnalyzer.js.map +1 -1
  10. package/dist/cli.js +25 -3
  11. package/dist/cli.js.map +1 -1
  12. package/dist/commands/fix.d.ts.map +1 -1
  13. package/dist/commands/fix.js +32 -7
  14. package/dist/commands/fix.js.map +1 -1
  15. package/dist/commands/scan.d.ts +1 -0
  16. package/dist/commands/scan.d.ts.map +1 -1
  17. package/dist/commands/scan.js +150 -41
  18. package/dist/commands/scan.js.map +1 -1
  19. package/dist/config/configLoader.d.ts +6 -0
  20. package/dist/config/configLoader.d.ts.map +1 -1
  21. package/dist/config/configLoader.js +1 -0
  22. package/dist/config/configLoader.js.map +1 -1
  23. package/dist/scanner/codeScanner.d.ts +5 -2
  24. package/dist/scanner/codeScanner.d.ts.map +1 -1
  25. package/dist/scanner/codeScanner.js +72 -25
  26. package/dist/scanner/codeScanner.js.map +1 -1
  27. package/dist/types.d.ts +6 -1
  28. package/dist/types.d.ts.map +1 -1
  29. package/package.json +1 -1
  30. package/src/analyzer/envAnalyzer.ts +27 -10
  31. package/src/cli.ts +29 -3
  32. package/src/commands/fix.ts +40 -9
  33. package/src/commands/scan.ts +168 -47
  34. package/src/config/configLoader.ts +8 -0
  35. package/src/scanner/codeScanner.ts +97 -28
  36. package/src/types.ts +3 -1
  37. package/test-project/src/lambda2/handler2.js +1 -1
  38. package/test-project/.envguardrc.json +0 -7
@@ -7,6 +7,7 @@
7
7
  "PLATFORM_PROVIDED_VAR"
8
8
  ],
9
9
  "strict": false,
10
+ "detectFallbacks": true,
10
11
  "exclude": [
11
12
  "**/tmp/**",
12
13
  "**/cache/**",
@@ -0,0 +1,16 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft-07/schema",
3
+ "title": "EnvGuard Configuration",
4
+ "description": "Configuration file for EnvGuard - keep your environment variables in sync",
5
+ "ignoreVars": [
6
+ "VAR_NAME"
7
+ ],
8
+ "strict": false,
9
+ "detectFallbacks": true,
10
+ "exclude": [
11
+ "**/tmp/**",
12
+ "**/cache/**",
13
+ "**/node_modules/**",
14
+ "**/dist/**"
15
+ ]
16
+ }
@@ -0,0 +1,15 @@
1
+ # These are supported funding model platforms
2
+
3
+ github: szlaskidaniel # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4
+ # patreon: # Replace with a single Patreon username
5
+ # open_collective: # Replace with a single Open Collective username
6
+ # ko_fi: # Replace with a single Ko-fi username
7
+ # tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8
+ # community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9
+ # liberapay: # Replace with a single Liberapay username
10
+ # issuehunt: # Replace with a single IssueHunt username
11
+ # lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
12
+ # polar: # Replace with a single Polar username
13
+ # buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
14
+ # thanks_dev: # Replace with a single thanks.dev username
15
+ # custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Daniel
3
+ Copyright (c) 2026 Daniel Szlaski
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,7 +1,9 @@
1
- # EnvGuard
1
+ # EnvGuard CLI
2
+ **Static Analysis for Environment Variables**
2
3
 
3
4
  Keep your environment variables in sync with your codebase.
4
5
 
6
+
5
7
  ## The Problem
6
8
 
7
9
  - `.env.example` is always out of sync with actual `.env`
@@ -21,18 +23,27 @@ EnvGuard automatically:
21
23
 
22
24
  ## Installation
23
25
 
26
+ **Option 1: Install globally**
27
+
28
+ ```bash
29
+ npm install -g @danielszlaski/envguard
30
+ ```
31
+
32
+ After installation, use the short command:
24
33
  ```bash
25
- npm install -g envguard
34
+ envguard scan
26
35
  ```
27
36
 
28
- Or use with npx:
37
+ **Option 2: Use with npx (no installation needed)**
29
38
 
30
39
  ```bash
31
- npx envguard scan
40
+ npx @danielszlaski/envguard scan
32
41
  ```
33
42
 
34
43
  ## Usage
35
44
 
45
+ > **Note:** The examples below use `envguard` (short form), which works after installation. If using npx without installation, use `npx @danielszlaski/envguard` instead.
46
+
36
47
  ### Scan for issues
37
48
 
38
49
  ```bash
@@ -111,19 +122,183 @@ envguard check
111
122
 
112
123
  This is equivalent to `envguard scan --ci` and will exit with code 1 if issues are found.
113
124
 
114
- #### GitHub Actions Example
125
+ ## GitHub Actions Setup
126
+
127
+ EnvGuard integrates seamlessly with GitHub Actions to validate your environment variables on every pull request or push.
128
+
129
+ ### Quick Setup (Recommended)
130
+
131
+ Create `.github/workflows/envguard.yml` in your repository:
132
+
133
+ ```yaml
134
+ name: Environment Variables Check
135
+
136
+ on:
137
+ pull_request:
138
+ branches: [main]
139
+ push:
140
+ branches: [main, develop]
141
+
142
+ jobs:
143
+ envguard:
144
+ runs-on: ubuntu-latest
145
+
146
+ steps:
147
+ - name: Checkout code
148
+ uses: actions/checkout@v4
149
+
150
+ - name: Setup Node.js
151
+ uses: actions/setup-node@v4
152
+ with:
153
+ node-version: '20.x'
154
+
155
+ - name: Run EnvGuard check
156
+ run: npx @danielszlaski/envguard scan --ci
157
+ ```
158
+
159
+ **That's it!** No installation needed - `npx` downloads EnvGuard on demand.
160
+
161
+ ### Advanced Setup - With PR Comments
162
+
163
+ Get automatic comments on pull requests when issues are found:
115
164
 
116
165
  ```yaml
117
- name: Check Env Sync
118
- on: [pull_request]
166
+ name: Environment Variables Check
167
+
168
+ on:
169
+ pull_request:
170
+ branches: [main]
119
171
 
120
172
  jobs:
121
173
  envguard:
122
174
  runs-on: ubuntu-latest
175
+ permissions:
176
+ pull-requests: write
177
+
178
+ steps:
179
+ - name: Checkout code
180
+ uses: actions/checkout@v4
181
+
182
+ - name: Setup Node.js
183
+ uses: actions/setup-node@v4
184
+ with:
185
+ node-version: '20.x'
186
+
187
+ - name: Run EnvGuard scan
188
+ id: envguard
189
+ continue-on-error: true
190
+ run: |
191
+ OUTPUT=$(npx @danielszlaski/envguard scan 2>&1)
192
+ echo "$OUTPUT"
193
+ echo "output<<EOF" >> $GITHUB_OUTPUT
194
+ echo "$OUTPUT" >> $GITHUB_OUTPUT
195
+ echo "EOF" >> $GITHUB_OUTPUT
196
+ npx @danielszlaski/envguard scan --ci
197
+
198
+ - name: Comment on PR if failed
199
+ if: failure()
200
+ uses: actions/github-script@v7
201
+ with:
202
+ script: |
203
+ github.rest.issues.createComment({
204
+ issue_number: context.issue.number,
205
+ owner: context.repo.owner,
206
+ repo: context.repo.repo,
207
+ body: '## ⚠️ EnvGuard Check Failed\n\n```\n${{ steps.envguard.outputs.output }}\n```\n\nPlease run `npx @danielszlaski/envguard fix` locally to generate `.env.example` files, then commit the changes.'
208
+ })
209
+ ```
210
+
211
+ ### Strict Mode in CI
212
+
213
+ Enable strict mode to catch all variables including runtime-provided ones:
214
+
215
+ ```yaml
216
+ - name: Run EnvGuard check (strict)
217
+ run: npx @danielszlaski/envguard scan --ci --strict
218
+ ```
219
+
220
+ ### Weekly Audit
221
+
222
+ Schedule weekly checks to catch configuration drift:
223
+
224
+ ```yaml
225
+ name: Weekly Environment Audit
226
+
227
+ on:
228
+ schedule:
229
+ - cron: '0 9 * * MON' # Every Monday at 9am UTC
230
+
231
+ jobs:
232
+ audit:
233
+ runs-on: ubuntu-latest
234
+
235
+ steps:
236
+ - uses: actions/checkout@v4
237
+ - uses: actions/setup-node@v4
238
+ with:
239
+ node-version: '20.x'
240
+ - run: npx @danielszlaski/envguard scan --ci --strict
241
+
242
+ - name: Create issue if problems found
243
+ if: failure()
244
+ uses: actions/github-script@v7
245
+ with:
246
+ script: |
247
+ github.rest.issues.create({
248
+ owner: context.repo.owner,
249
+ repo: context.repo.repo,
250
+ title: '⚠️ Environment Variables Out of Sync',
251
+ body: 'Weekly EnvGuard audit found issues. Run `npx @danielszlaski/envguard scan` locally for details.',
252
+ labels: ['env-config', 'maintenance']
253
+ })
254
+ ```
255
+
256
+ ### Caching for Faster Runs
257
+
258
+ Speed up CI runs by caching npx downloads:
259
+
260
+ ```yaml
261
+ - name: Setup Node.js
262
+ uses: actions/setup-node@v4
263
+ with:
264
+ node-version: '20.x'
265
+ cache: 'npm' # Caches npx downloads
266
+
267
+ - name: Run EnvGuard
268
+ run: npx @danielszlaski/envguard scan --ci
269
+ ```
270
+
271
+ ### Other CI Platforms
272
+
273
+ **GitLab CI** (`.gitlab-ci.yml`):
274
+ ```yaml
275
+ envguard:
276
+ image: node:20
277
+ script:
278
+ - npx @danielszlaski/envguard scan --ci
279
+ only:
280
+ - merge_requests
281
+ ```
282
+
283
+ **CircleCI** (`.circleci/config.yml`):
284
+ ```yaml
285
+ version: 2.1
286
+ jobs:
287
+ envguard:
288
+ docker:
289
+ - image: cimg/node:20.0
123
290
  steps:
124
- - uses: actions/checkout@v3
125
- - uses: actions/setup-node@v3
126
- - run: npx envguard check
291
+ - checkout
292
+ - run: npx @danielszlaski/envguard scan --ci
293
+ ```
294
+
295
+ **Travis CI** (`.travis.yml`):
296
+ ```yaml
297
+ language: node_js
298
+ node_js:
299
+ - '20'
300
+ script:
301
+ - npx @danielszlaski/envguard scan --ci
127
302
  ```
128
303
 
129
304
  ## Supported Languages & Frameworks
@@ -166,6 +341,7 @@ Create a `.envguardrc.json` file in your project root to customize behavior:
166
341
  "COMPANY_INTERNAL_VAR"
167
342
  ],
168
343
  "strict": false,
344
+ "detectFallbacks": true,
169
345
  "exclude": [
170
346
  "**/build/**",
171
347
  "**/tmp/**"
@@ -177,6 +353,7 @@ Create a `.envguardrc.json` file in your project root to customize behavior:
177
353
 
178
354
  - `ignoreVars` (string[]): Custom environment variables to ignore in non-strict mode. These will be treated like AWS_REGION and won't trigger warnings.
179
355
  - `strict` (boolean): Enable strict mode by default (can be overridden with CLI flag)
356
+ - `detectFallbacks` (boolean): Detect fallback patterns in code and treat them as warnings instead of errors (default: `true`)
180
357
  - `exclude` (string[]): Additional file patterns to exclude from scanning
181
358
 
182
359
  **Alternative: package.json**
@@ -203,6 +380,62 @@ You can also add configuration to your `package.json`:
203
380
  **GitHub Apps & CI/CD:**
204
381
  When using EnvGuard as a GitHub App or in CI/CD pipelines, commit your `.envguardrc.json` to the repository. This ensures consistent behavior across all environments and team members.
205
382
 
383
+ ### Fallback Detection (Smart Severity)
384
+
385
+ EnvGuard automatically detects common defensive patterns in your code and adjusts issue severity accordingly. When a variable is used with a fallback or default value, it's treated as a **WARNING** instead of an **ERROR**.
386
+
387
+ **Detected patterns:**
388
+
389
+ ```javascript
390
+ // Default values with || or ??
391
+ const port = process.env.PORT || 3000; // WARNING
392
+ const url = process.env.API_URL ?? 'localhost'; // WARNING
393
+
394
+ // Ternary operators
395
+ const env = process.env.NODE_ENV ? 'set' : 'dev'; // WARNING
396
+
397
+ // Conditional checks
398
+ if (process.env.FEATURE_FLAG) { } // WARNING
399
+ if (!process.env.DEBUG) { } // WARNING
400
+
401
+ // Destructuring with defaults
402
+ const { LOG_LEVEL = 'info' } = process.env; // WARNING
403
+
404
+ // Optional chaining
405
+ const value = process.env?.OPTIONAL_VAR; // WARNING
406
+
407
+ // No fallback - strict requirement
408
+ const apiKey = process.env.API_KEY; // ERROR
409
+ ```
410
+
411
+ **Severity levels:**
412
+
413
+ - **ERROR** (✖): Variable used without any safety mechanism - likely to cause runtime errors
414
+ - **WARNING** (⚠): Variable used with fallback/default - code handles missing values
415
+ - **INFO** (ℹ): Unused variables or optional documentation issues
416
+
417
+ **Disable fallback detection:**
418
+
419
+ If you prefer all missing variables to be treated as errors regardless of fallbacks:
420
+
421
+ ```bash
422
+ # CLI flag
423
+ envguard scan --no-detect-fallbacks
424
+
425
+ # Config file
426
+ {
427
+ "detectFallbacks": false
428
+ }
429
+ ```
430
+
431
+ **Why this feature exists:**
432
+
433
+ Not all missing environment variables are equal. Variables with defensive fallbacks are less critical than those that will cause `undefined` errors. This feature helps you prioritize what to fix first while still being aware of all env var usage.
434
+
435
+ **Limitations:**
436
+
437
+ Fallback detection uses regex patterns and catches common cases (~80% of real-world usage). Complex patterns like function calls with fallbacks or deeply nested conditionals may not be detected. For strict validation, use `--no-detect-fallbacks` or set `detectFallbacks: false` in your config.
438
+
206
439
  ### Monorepo Support
207
440
 
208
441
  EnvGuard automatically detects all `.env` files in your project, including subdirectories. When you run `envguard fix`, it creates a `.env.example` file next to each `.env` file it finds.
@@ -276,9 +509,11 @@ Checking src/lambda/serverless.yml
276
509
  - `envguard scan` - Scan for issues and display report
277
510
  - `envguard scan --ci` - Scan and exit with error code if issues found
278
511
  - `envguard scan --strict` - Report all variables including known runtime variables
512
+ - `envguard scan --no-detect-fallbacks` - Treat all missing variables as errors (ignore fallback detection)
279
513
  - `envguard fix` - Auto-generate `.env.example`
280
514
  - `envguard check` - Alias for `scan --ci`
281
515
  - `envguard check --strict` - Check with strict mode enabled
516
+ - `envguard check --no-detect-fallbacks` - Check without fallback detection
282
517
 
283
518
  ### Strict Mode
284
519
 
@@ -318,4 +553,4 @@ npm start scan
318
553
 
319
554
  ## License
320
555
 
321
- MIT
556
+ MIT 2026 Daniel Szlaski
@@ -1,8 +1,14 @@
1
1
  import { ScanResult } from '../types';
2
2
  import { EnvEntry } from '../parser/envParser';
3
3
  export declare class EnvAnalyzer {
4
- analyze(usedVars: Map<string, string[]>, definedVars: Map<string, EnvEntry>, exampleVars: Set<string>): ScanResult;
5
- generateExampleContent(usedVars: Map<string, string[]>, existingEntries: Map<string, EnvEntry>): string;
4
+ analyze(usedVars: Map<string, {
5
+ locations: string[];
6
+ hasFallback: boolean;
7
+ }>, definedVars: Map<string, EnvEntry>, exampleVars: Set<string>, detectFallbacks?: boolean): ScanResult;
8
+ generateExampleContent(usedVars: Map<string, {
9
+ locations: string[];
10
+ hasFallback: boolean;
11
+ }>, existingEntries: Map<string, EnvEntry>): string;
6
12
  private getFormatHint;
7
13
  }
8
14
  //# sourceMappingURL=envAnalyzer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"envAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer/envAnalyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,UAAU,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,qBAAa,WAAW;IACtB,OAAO,CACL,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAC/B,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,EAClC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,GACvB,UAAU;IA8Cb,sBAAsB,CACpB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAC/B,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,GACrC,MAAM;IAyCT,OAAO,CAAC,aAAa;CAkCtB"}
1
+ {"version":3,"file":"envAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer/envAnalyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,UAAU,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,qBAAa,WAAW;IACtB,OAAO,CACL,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC,EACpE,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,EAClC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EACxB,eAAe,GAAE,OAAc,GAC9B,UAAU;IA6Db,sBAAsB,CACpB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC,EACpE,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,GACrC,MAAM;IA0CT,OAAO,CAAC,aAAa;CAkCtB"}
@@ -2,16 +2,22 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EnvAnalyzer = void 0;
4
4
  class EnvAnalyzer {
5
- analyze(usedVars, definedVars, exampleVars) {
5
+ analyze(usedVars, definedVars, exampleVars, detectFallbacks = true) {
6
6
  const issues = [];
7
7
  // Issue 1: Variables used in code but missing from .env
8
- for (const [varName, locations] of usedVars.entries()) {
8
+ for (const [varName, usage] of usedVars.entries()) {
9
9
  if (!definedVars.has(varName)) {
10
+ // If detectFallbacks is enabled and variable has a fallback, it's a WARNING, otherwise ERROR
11
+ const severity = (detectFallbacks && usage.hasFallback) ? 'warning' : 'error';
12
+ const details = (detectFallbacks && usage.hasFallback)
13
+ ? `Used in code with fallback/default but not defined in .env`
14
+ : `Used in code but not defined in .env`;
10
15
  issues.push({
11
16
  type: 'missing',
17
+ severity,
12
18
  varName,
13
- details: `Used in code but not defined in .env`,
14
- locations,
19
+ details,
20
+ locations: usage.locations,
15
21
  });
16
22
  }
17
23
  }
@@ -20,19 +26,26 @@ class EnvAnalyzer {
20
26
  if (!usedVars.has(varName)) {
21
27
  issues.push({
22
28
  type: 'unused',
29
+ severity: 'info',
23
30
  varName,
24
31
  details: `Defined in .env but never used in code`,
25
32
  });
26
33
  }
27
34
  }
28
35
  // Issue 3: Variables used in code but not in .env.example
29
- for (const [varName, locations] of usedVars.entries()) {
36
+ for (const [varName, usage] of usedVars.entries()) {
30
37
  if (!exampleVars.has(varName)) {
38
+ // If detectFallbacks is enabled and variable has a fallback, it's less critical for documentation
39
+ const severity = (detectFallbacks && usage.hasFallback) ? 'info' : 'warning';
40
+ const details = (detectFallbacks && usage.hasFallback)
41
+ ? `Used in code with fallback but missing from .env.example`
42
+ : `Used in code but missing from .env.example`;
31
43
  issues.push({
32
44
  type: 'undocumented',
45
+ severity,
33
46
  varName,
34
- details: `Used in code but missing from .env.example`,
35
- locations,
47
+ details,
48
+ locations: usage.locations,
36
49
  });
37
50
  }
38
51
  }
@@ -48,7 +61,8 @@ class EnvAnalyzer {
48
61
  content += '# Do not put actual secrets in this file - use .env instead\n\n';
49
62
  const sortedVars = Array.from(usedVars.keys()).sort();
50
63
  for (const varName of sortedVars) {
51
- const locations = usedVars.get(varName);
64
+ const usage = usedVars.get(varName);
65
+ const locations = usage.locations;
52
66
  const existingEntry = existingEntries.get(varName);
53
67
  // Add location comments
54
68
  content += `# Used in: ${locations.slice(0, 3).join(', ')}`;
@@ -1 +1 @@
1
- {"version":3,"file":"envAnalyzer.js","sourceRoot":"","sources":["../../src/analyzer/envAnalyzer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"envAnalyzer.js","sourceRoot":"","sources":["../../src/analyzer/envAnalyzer.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -15,8 +15,20 @@ program
15
15
  .description('Scan codebase and compare with .env files')
16
16
  .option('--ci', 'Exit with error code if issues found (for CI/CD)')
17
17
  .option('--strict', 'Report all variables including known runtime variables (AWS_REGION, NODE_ENV, etc.)')
18
- .action(async (options) => {
18
+ .option('--no-detect-fallbacks', 'Treat all missing variables as errors, ignoring fallback detection')
19
+ .action(async (cmd, command) => {
19
20
  try {
21
+ // Build options object, only including detectFallbacks if the flag was used
22
+ const options = {
23
+ ci: cmd.ci,
24
+ strict: cmd.strict
25
+ };
26
+ // Check if the --no-detect-fallbacks flag was explicitly provided
27
+ // Commander adds it to the command's options when the flag is used
28
+ const flagProvided = command.parent?.rawArgs.some((arg) => arg.includes('detect-fallback'));
29
+ if (flagProvided) {
30
+ options.detectFallbacks = cmd.detectFallbacks;
31
+ }
20
32
  await (0, scan_1.scanCommand)(options);
21
33
  }
22
34
  catch (error) {
@@ -40,9 +52,19 @@ program
40
52
  .command('check')
41
53
  .description('Check for issues (alias for scan --ci)')
42
54
  .option('--strict', 'Report all variables including known runtime variables (AWS_REGION, NODE_ENV, etc.)')
43
- .action(async (options) => {
55
+ .option('--no-detect-fallbacks', 'Treat all missing variables as errors, ignoring fallback detection')
56
+ .action(async (cmd, command) => {
44
57
  try {
45
- await (0, scan_1.scanCommand)({ ci: true, strict: options.strict });
58
+ const options = {
59
+ ci: true,
60
+ strict: cmd.strict
61
+ };
62
+ // Check if the --no-detect-fallbacks flag was explicitly provided
63
+ const flagProvided = command.parent?.rawArgs.some((arg) => arg.includes('detect-fallback'));
64
+ if (flagProvided) {
65
+ options.detectFallbacks = cmd.detectFallbacks;
66
+ }
67
+ await (0, scan_1.scanCommand)(options);
46
68
  }
47
69
  catch (error) {
48
70
  logger_1.Logger.error(`${error}`);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,0CAA8C;AAC9C,wCAA4C;AAE5C,2CAAwC;AAExC,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,4DAA4D,CAAC;KACzE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,2CAA2C,CAAC;KACxD,MAAM,CAAC,MAAM,EAAE,kDAAkD,CAAC;KAClE,MAAM,CAAC,UAAU,EAAE,qFAAqF,CAAC;KACzG,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,IAAI,CAAC;QACH,MAAM,IAAA,kBAAW,EAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,eAAM,CAAC,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,0CAA0C,CAAC;KACvD,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,IAAI,CAAC;QACH,MAAM,IAAA,gBAAU,GAAE,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,eAAM,CAAC,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,wCAAwC,CAAC;KACrD,MAAM,CAAC,UAAU,EAAE,qFAAqF,CAAC;KACzG,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,IAAI,CAAC;QACH,MAAM,IAAA,kBAAW,EAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,eAAM,CAAC,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"fix.d.ts","sourceRoot":"","sources":["../../src/commands/fix.ts"],"names":[],"mappings":"AAOA,wBAAsB,UAAU;;GAwE/B"}
1
+ {"version":3,"file":"fix.d.ts","sourceRoot":"","sources":["../../src/commands/fix.ts"],"names":[],"mappings":"AAOA,wBAAsB,UAAU;;GAiG/B"}
@@ -43,8 +43,18 @@ const logger_1 = require("../utils/logger");
43
43
  async function fixCommand() {
44
44
  const rootDir = process.cwd();
45
45
  logger_1.Logger.startSpinner('Generating .env.example files...');
46
+ // Load configuration
47
+ const { ConfigLoader } = require('../config/configLoader');
48
+ const config = ConfigLoader.loadConfig(rootDir);
46
49
  // Step 1: Find all .env files
47
- const scanner = new codeScanner_1.CodeScanner(rootDir);
50
+ const excludePatterns = [
51
+ 'node_modules',
52
+ 'dist',
53
+ 'build',
54
+ '.git',
55
+ ...(config.exclude || []),
56
+ ];
57
+ const scanner = new codeScanner_1.CodeScanner(rootDir, excludePatterns);
48
58
  const envFiles = await scanner.findEnvFiles();
49
59
  logger_1.Logger.stopSpinner();
50
60
  if (envFiles.length === 0) {
@@ -64,7 +74,18 @@ async function fixCommand() {
64
74
  const displayPath = relativePath || '.';
65
75
  logger_1.Logger.path(`Processing ${displayPath}/`);
66
76
  // Step 3: Scan code files in this directory and subdirectories
67
- const usedVars = await scanDirectoryForVars(rootDir, envDir, scanner);
77
+ const allUsedVars = await scanDirectoryForVars(rootDir, envDir, scanner, config.exclude);
78
+ // Filter out ignored variables based on config (they shouldn't be in .env.example)
79
+ const { isKnownRuntimeVar } = require('../constants/knownEnvVars');
80
+ const usedVars = new Map();
81
+ for (const [varName, usage] of allUsedVars.entries()) {
82
+ const isCustomIgnored = ConfigLoader.shouldIgnoreVar(varName, config);
83
+ const isRuntimeVar = isKnownRuntimeVar(varName);
84
+ // Skip known runtime variables and custom ignore vars
85
+ if (!isRuntimeVar && !isCustomIgnored) {
86
+ usedVars.set(varName, usage);
87
+ }
88
+ }
68
89
  if (usedVars.size === 0) {
69
90
  logger_1.Logger.info('No environment variables found in code', true);
70
91
  logger_1.Logger.blank();
@@ -93,25 +114,29 @@ async function fixCommand() {
93
114
  logger_1.Logger.summary(`Generated ${envFiles.length} .env.example file(s) with ${totalVars} total variables`);
94
115
  return { success: true };
95
116
  }
96
- async function scanDirectoryForVars(rootDir, targetDir, scanner) {
117
+ async function scanDirectoryForVars(rootDir, targetDir, scanner, excludePatterns = []) {
97
118
  const envVars = new Map();
98
119
  const { glob } = require('glob');
99
120
  // Find all code files in this directory and subdirectories
100
121
  const relativeDir = path.relative(rootDir, targetDir);
101
122
  const pattern = relativeDir ? `${relativeDir}/**/*.{js,ts,jsx,tsx,mjs,cjs}` : '**/*.{js,ts,jsx,tsx,mjs,cjs}';
123
+ const defaultIgnore = ['**/node_modules/**', '**/dist/**', '**/build/**', '**/.git/**'];
124
+ const customIgnore = excludePatterns.map(p => p.includes('*') ? p : `**/${p}/**`);
102
125
  const files = await glob(pattern, {
103
126
  cwd: rootDir,
104
- ignore: ['**/node_modules/**', '**/dist/**', '**/build/**', '**/.git/**'],
127
+ ignore: [...defaultIgnore, ...customIgnore],
105
128
  absolute: true,
106
129
  });
107
130
  for (const file of files) {
108
131
  const vars = await scanner.scanFile(file);
109
- for (const varName of vars) {
132
+ for (const [varName, hasFallback] of vars.entries()) {
110
133
  const relativePath = path.relative(rootDir, file);
111
134
  if (!envVars.has(varName)) {
112
- envVars.set(varName, []);
135
+ envVars.set(varName, { locations: [], hasFallback: false });
113
136
  }
114
- envVars.get(varName).push(relativePath);
137
+ const entry = envVars.get(varName);
138
+ entry.locations.push(relativePath);
139
+ entry.hasFallback = entry.hasFallback || hasFallback;
115
140
  }
116
141
  }
117
142
  return envVars;
@@ -1 +1 @@
1
- {"version":3,"file":"fix.js","sourceRoot":"","sources":["../../src/commands/fix.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fix.js","sourceRoot":"","sources":["../../src/commands/fix.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,gCAiGC;AAxGD,2CAA6B;AAC7B,uCAAyB;AACzB,wDAAqD;AACrD,mDAAgD;AAChD,yDAAsD;AACtD,4CAAyC;AAElC,KAAK,UAAU,UAAU;IAC9B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE9B,eAAM,CAAC,YAAY,CAAC,kCAAkC,CAAC,CAAC;IAExD,qBAAqB;IACrB,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAEhD,8BAA8B;IAC9B,MAAM,eAAe,GAAG;QACtB,cAAc;QACd,MAAM;QACN,OAAO;QACP,MAAM;QACN,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;KAC1B,CAAC;IACF,MAAM,OAAO,GAAG,IAAI,yBAAW,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAC1D,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC;IAE9C,eAAM,CAAC,WAAW,EAAE,CAAC;IAErB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,eAAM,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC;QACrD,eAAM,CAAC,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,CAAC;IAED,eAAM,CAAC,OAAO,CAAC,SAAS,QAAQ,CAAC,MAAM,eAAe,CAAC,CAAC;IACxD,eAAM,CAAC,KAAK,EAAE,CAAC;IAEf,MAAM,MAAM,GAAG,IAAI,qBAAS,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAG,IAAI,yBAAW,EAAE,CAAC;IACnC,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,iCAAiC;IACjC,KAAK,MAAM,WAAW,IAAI,QAAQ,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACzC,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACpD,MAAM,WAAW,GAAG,YAAY,IAAI,GAAG,CAAC;QAExC,eAAM,CAAC,IAAI,CAAC,cAAc,WAAW,GAAG,CAAC,CAAC;QAE1C,+DAA+D;QAC/D,MAAM,WAAW,GAAG,MAAM,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QAEzF,mFAAmF;QACnF,MAAM,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAC;QACnE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAyD,CAAC;QAElF,KAAK,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;YACrD,MAAM,eAAe,GAAG,YAAY,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACtE,MAAM,YAAY,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;YAEhD,sDAAsD;YACtD,IAAI,CAAC,YAAY,IAAI,CAAC,eAAe,EAAE,CAAC;gBACtC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACxB,eAAM,CAAC,IAAI,CAAC,wCAAwC,EAAE,IAAI,CAAC,CAAC;YAC5D,eAAM,CAAC,KAAK,EAAE,CAAC;YACf,SAAS;QACX,CAAC;QAED,eAAM,CAAC,OAAO,CAAC,SAAS,QAAQ,CAAC,IAAI,qCAAqC,EAAE,IAAI,CAAC,CAAC;QAClF,eAAM,CAAC,KAAK,EAAE,CAAC;QAEf,2DAA2D;QAC3D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QACtD,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAElD,4CAA4C;QAC5C,MAAM,UAAU,GAAG,QAAQ,CAAC,sBAAsB,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;QAE9E,gCAAgC;QAChC,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;QAEnD,eAAM,CAAC,OAAO,CAAC,aAAa,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QACzE,eAAM,CAAC,KAAK,EAAE,CAAC;QAEf,SAAS,IAAI,QAAQ,CAAC,IAAI,CAAC;QAE3B,0CAA0C;QAC1C,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC9C,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAEpF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,eAAM,CAAC,OAAO,CAAC,sBAAsB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YACxE,eAAM,CAAC,KAAK,EAAE,CAAC;QACjB,CAAC;IACH,CAAC;IAED,eAAM,CAAC,OAAO,CAAC,aAAa,QAAQ,CAAC,MAAM,8BAA8B,SAAS,kBAAkB,CAAC,CAAC;IAEtG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC;AAED,KAAK,UAAU,oBAAoB,CACjC,OAAe,EACf,SAAiB,EACjB,OAAoB,EACpB,kBAA4B,EAAE;IAE9B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAyD,CAAC;IACjF,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEjC,2DAA2D;IAC3D,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,+BAA+B,CAAC,CAAC,CAAC,8BAA8B,CAAC;IAE7G,MAAM,aAAa,GAAG,CAAC,oBAAoB,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC;IACxF,MAAM,YAAY,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAElF,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE;QAChC,GAAG,EAAE,OAAO;QACZ,MAAM,EAAE,CAAC,GAAG,aAAa,EAAE,GAAG,YAAY,CAAC;QAC3C,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IAEH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,MAAO,OAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACnD,KAAK,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YACpD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAClD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1B,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;YAC9D,CAAC;YACD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC;YACpC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACnC,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,IAAI,WAAW,CAAC;QACvD,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -2,6 +2,7 @@ import { Issue } from '../types';
2
2
  export declare function scanCommand(options: {
3
3
  ci?: boolean;
4
4
  strict?: boolean;
5
+ detectFallbacks?: boolean;
5
6
  }): Promise<{
6
7
  success: boolean;
7
8
  issues: Issue[];
@@ -1 +1 @@
1
- {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAKjC,wBAAsB,WAAW,CAAC,OAAO,EAAE;IAAE,EAAE,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE;;;GAmO5E"}
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAKjC,wBAAsB,WAAW,CAAC,OAAO,EAAE;IAAE,EAAE,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE;;;GAgVvG"}