dotenv-diff 2.4.5 → 2.4.7

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 (138) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +34 -131
  3. package/dist/src/cli/run.d.ts.map +1 -1
  4. package/dist/src/cli/run.js +53 -41
  5. package/dist/src/cli/run.js.map +1 -1
  6. package/dist/src/commands/compare.d.ts +2 -2
  7. package/dist/src/commands/compare.d.ts.map +1 -1
  8. package/dist/src/commands/compare.js +64 -50
  9. package/dist/src/commands/compare.js.map +1 -1
  10. package/dist/src/commands/scanUsage.d.ts +3 -5
  11. package/dist/src/commands/scanUsage.d.ts.map +1 -1
  12. package/dist/src/commands/scanUsage.js +2 -4
  13. package/dist/src/commands/scanUsage.js.map +1 -1
  14. package/dist/src/config/constants.d.ts +42 -0
  15. package/dist/src/config/constants.d.ts.map +1 -0
  16. package/dist/src/config/constants.js +54 -0
  17. package/dist/src/config/constants.js.map +1 -0
  18. package/dist/src/config/loadConfig.d.ts.map +1 -1
  19. package/dist/src/config/loadConfig.js +6 -2
  20. package/dist/src/config/loadConfig.js.map +1 -1
  21. package/dist/src/config/options.d.ts +21 -4
  22. package/dist/src/config/options.d.ts.map +1 -1
  23. package/dist/src/config/options.js +72 -55
  24. package/dist/src/config/options.js.map +1 -1
  25. package/dist/src/config/types.d.ts +172 -197
  26. package/dist/src/config/types.d.ts.map +1 -1
  27. package/dist/src/config/types.js +1 -10
  28. package/dist/src/config/types.js.map +1 -1
  29. package/dist/src/core/compareScan.d.ts +1 -0
  30. package/dist/src/core/compareScan.d.ts.map +1 -1
  31. package/dist/src/core/compareScan.js +1 -0
  32. package/dist/src/core/compareScan.js.map +1 -1
  33. package/dist/src/core/determineComparisonFile.d.ts +1 -1
  34. package/dist/src/core/determineComparisonFile.d.ts.map +1 -1
  35. package/dist/src/core/determineComparisonFile.js +2 -8
  36. package/dist/src/core/determineComparisonFile.js.map +1 -1
  37. package/dist/src/core/envPairing.d.ts +1 -2
  38. package/dist/src/core/envPairing.d.ts.map +1 -1
  39. package/dist/src/core/envPairing.js +5 -2
  40. package/dist/src/core/envPairing.js.map +1 -1
  41. package/dist/src/core/fixEnv.d.ts.map +1 -1
  42. package/dist/src/core/fixEnv.js +4 -2
  43. package/dist/src/core/fixEnv.js.map +1 -1
  44. package/dist/src/core/frameworkDetector.d.ts +4 -3
  45. package/dist/src/core/frameworkDetector.d.ts.map +1 -1
  46. package/dist/src/core/frameworkDetector.js.map +1 -1
  47. package/dist/src/core/frameworkValidator.d.ts +2 -10
  48. package/dist/src/core/frameworkValidator.d.ts.map +1 -1
  49. package/dist/src/core/frameworkValidator.js.map +1 -1
  50. package/dist/src/core/frameworks/nextJsRules.d.ts +2 -3
  51. package/dist/src/core/frameworks/nextJsRules.d.ts.map +1 -1
  52. package/dist/src/core/frameworks/nextJsRules.js +18 -20
  53. package/dist/src/core/frameworks/nextJsRules.js.map +1 -1
  54. package/dist/src/core/frameworks/sveltekitRules.d.ts +2 -3
  55. package/dist/src/core/frameworks/sveltekitRules.d.ts.map +1 -1
  56. package/dist/src/core/frameworks/sveltekitRules.js +41 -29
  57. package/dist/src/core/frameworks/sveltekitRules.js.map +1 -1
  58. package/dist/src/core/helpers/normalizePath.d.ts +6 -0
  59. package/dist/src/core/helpers/normalizePath.d.ts.map +1 -0
  60. package/dist/src/core/helpers/normalizePath.js +8 -0
  61. package/dist/src/core/helpers/normalizePath.js.map +1 -0
  62. package/dist/src/core/helpers/updateTotals.d.ts +1 -2
  63. package/dist/src/core/helpers/updateTotals.d.ts.map +1 -1
  64. package/dist/src/core/helpers/updateTotals.js.map +1 -1
  65. package/dist/src/core/patterns.d.ts +0 -15
  66. package/dist/src/core/patterns.d.ts.map +1 -1
  67. package/dist/src/core/patterns.js +0 -18
  68. package/dist/src/core/patterns.js.map +1 -1
  69. package/dist/src/core/processComparisonFile.d.ts +6 -14
  70. package/dist/src/core/processComparisonFile.d.ts.map +1 -1
  71. package/dist/src/core/processComparisonFile.js.map +1 -1
  72. package/dist/src/core/scanFile.d.ts +1 -1
  73. package/dist/src/core/scanFile.d.ts.map +1 -1
  74. package/dist/src/core/scanFile.js +7 -5
  75. package/dist/src/core/scanFile.js.map +1 -1
  76. package/dist/src/core/scanJsonOutput.d.ts +78 -4
  77. package/dist/src/core/scanJsonOutput.d.ts.map +1 -1
  78. package/dist/src/core/scanJsonOutput.js +39 -32
  79. package/dist/src/core/scanJsonOutput.js.map +1 -1
  80. package/dist/src/index.js +7 -0
  81. package/dist/src/index.js.map +1 -1
  82. package/dist/src/services/codeBaseScanner.d.ts.map +1 -1
  83. package/dist/src/services/codeBaseScanner.js +59 -22
  84. package/dist/src/services/codeBaseScanner.js.map +1 -1
  85. package/dist/src/services/duplicates.js +2 -2
  86. package/dist/src/services/duplicates.js.map +1 -1
  87. package/dist/src/services/ensureFilesOrPrompt.d.ts.map +1 -1
  88. package/dist/src/services/ensureFilesOrPrompt.js +5 -2
  89. package/dist/src/services/ensureFilesOrPrompt.js.map +1 -1
  90. package/dist/src/services/envDiscovery.d.ts +1 -14
  91. package/dist/src/services/envDiscovery.d.ts.map +1 -1
  92. package/dist/src/services/envDiscovery.js +22 -9
  93. package/dist/src/services/envDiscovery.js.map +1 -1
  94. package/dist/src/services/git.d.ts.map +1 -1
  95. package/dist/src/services/git.js +10 -9
  96. package/dist/src/services/git.js.map +1 -1
  97. package/dist/src/services/scanOutputToConsole.d.ts +2 -4
  98. package/dist/src/services/scanOutputToConsole.d.ts.map +1 -1
  99. package/dist/src/services/scanOutputToConsole.js +5 -4
  100. package/dist/src/services/scanOutputToConsole.js.map +1 -1
  101. package/dist/src/ui/compare/printIssues.d.ts +1 -1
  102. package/dist/src/ui/compare/printIssues.d.ts.map +1 -1
  103. package/dist/src/ui/compare/printIssues.js +0 -1
  104. package/dist/src/ui/compare/printIssues.js.map +1 -1
  105. package/dist/src/ui/compare/printStats.d.ts +1 -1
  106. package/dist/src/ui/compare/printStats.d.ts.map +1 -1
  107. package/dist/src/ui/compare/printStats.js +0 -1
  108. package/dist/src/ui/compare/printStats.js.map +1 -1
  109. package/dist/src/ui/scan/printConsolelogWarning.d.ts.map +1 -1
  110. package/dist/src/ui/scan/printConsolelogWarning.js +3 -1
  111. package/dist/src/ui/scan/printConsolelogWarning.js.map +1 -1
  112. package/dist/src/ui/scan/printFrameworkWarnings.d.ts +2 -2
  113. package/dist/src/ui/scan/printFrameworkWarnings.d.ts.map +1 -1
  114. package/dist/src/ui/scan/printFrameworkWarnings.js.map +1 -1
  115. package/dist/src/ui/scan/printMissing.d.ts.map +1 -1
  116. package/dist/src/ui/scan/printMissing.js +3 -1
  117. package/dist/src/ui/scan/printMissing.js.map +1 -1
  118. package/dist/src/ui/scan/printProgress.d.ts +15 -0
  119. package/dist/src/ui/scan/printProgress.d.ts.map +1 -0
  120. package/dist/src/ui/scan/printProgress.js +35 -0
  121. package/dist/src/ui/scan/printProgress.js.map +1 -0
  122. package/dist/src/ui/scan/printSecrets.d.ts +1 -1
  123. package/dist/src/ui/scan/printSecrets.d.ts.map +1 -1
  124. package/dist/src/ui/scan/printSecrets.js +3 -2
  125. package/dist/src/ui/scan/printSecrets.js.map +1 -1
  126. package/dist/src/ui/shared/printFixTips.d.ts +1 -1
  127. package/dist/src/ui/shared/printFixTips.d.ts.map +1 -1
  128. package/dist/src/ui/shared/printFixTips.js +0 -1
  129. package/dist/src/ui/shared/printFixTips.js.map +1 -1
  130. package/dist/src/ui/shared/printProgress.d.ts +24 -0
  131. package/dist/src/ui/shared/printProgress.d.ts.map +1 -0
  132. package/dist/src/ui/shared/printProgress.js +43 -0
  133. package/dist/src/ui/shared/printProgress.js.map +1 -0
  134. package/dist/src/ui/shared/setupGlobalConfig.d.ts +1 -1
  135. package/dist/src/ui/shared/setupGlobalConfig.d.ts.map +1 -1
  136. package/dist/src/ui/shared/setupGlobalConfig.js +0 -1
  137. package/dist/src/ui/shared/setupGlobalConfig.js.map +1 -1
  138. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -17,6 +17,22 @@ This project follows [Keep a Changelog](https://keepachangelog.com/) and [Semant
17
17
 
18
18
  -
19
19
 
20
+ ## [2.4.7] - 2026-01-11
21
+
22
+ ### Added
23
+
24
+ - Added progress bar to codebase scanner.
25
+
26
+ ### Fixed
27
+
28
+ - Fixed path normalization issue where file paths were not consistently displayed across different operating systems.
29
+
30
+ ## [2.4.6] - 2026-01-06
31
+
32
+ ### Fixed
33
+
34
+ - Modified JSON output for scan usage.
35
+
20
36
  ## [2.4.5] - 2025-12-29
21
37
 
22
38
  ### Changed
package/README.md CHANGED
@@ -1,14 +1,8 @@
1
1
  # dotenv-diff
2
2
 
3
- ![Demo](./public/demo3.gif)
4
-
5
- `dotenv-diff` scans your codebase to detect which environment variables are used
6
- and compares them against your `.env` or `.env.example` files.
3
+ Scan your entire codebase to detect every environment variable reference. It helps you catch missing, unused, duplicated, and misused variables early, before they cause runtime errors.
7
4
 
8
- It helps you catch missing, unused, or misconfigured environment variables **before deployment**.
9
-
10
- Optimized for **SvelteKit** and **Next.js**, but works well with modern
11
- JavaScript and TypeScript projects such as **Node.js, Nuxt, and Vue**.
5
+ Optimized for SvelteKit and Next.js. Also works well in modern JavaScript/TypeScript projects and frameworks like Node.js, Nuxt, and Vue — or any other setup where you want reliable .env file comparison.
12
6
 
13
7
  ![CI](https://github.com/chrilleweb/dotenv-diff/actions/workflows/ci.yml/badge.svg)
14
8
  [![npm version](https://img.shields.io/npm/v/dotenv-diff.svg)](https://www.npmjs.com/package/dotenv-diff)
@@ -16,6 +10,14 @@ JavaScript and TypeScript projects such as **Node.js, Nuxt, and Vue**.
16
10
 
17
11
  ---
18
12
 
13
+ ### Warnings & errors detection
14
+ ![Demo](./public/demo3.gif)
15
+
16
+ ### Clean / successful scan
17
+ ![Successful Scan](./public/successful-scan.png)
18
+
19
+ ---
20
+
19
21
  ## Why dotenv-diff?
20
22
 
21
23
  - Ensure all required environment variables are defined before deploying
@@ -26,50 +28,6 @@ JavaScript and TypeScript projects such as **Node.js, Nuxt, and Vue**.
26
28
 
27
29
  ---
28
30
 
29
- ## GitHub Actions Example
30
-
31
- Run `dotenv-diff` in CI to validate environment variables automatically:
32
-
33
- ```yaml
34
- - name: Check environment variables
35
- run: dotenv-diff --example .env.example
36
- ```
37
-
38
- To compare against a different example file:
39
-
40
- ```bash
41
- dotenv-diff --example .env.example.staging
42
- ```
43
-
44
- If no `.env.example` file exists, run:
45
-
46
- ```bash
47
- dotenv-diff
48
- ```
49
-
50
- This scans the codebase but skips comparison.
51
-
52
- ---
53
-
54
- ## Monorepo (Turborepo) Usage
55
-
56
- In monorepos with multiple apps and packages, you can include shared folders:
57
-
58
- ```json
59
- {
60
- "scripts": {
61
- "dotenv-diff": "dotenv-diff --example .env.example --include-files '../../packages/**/*' --ignore VITE_MODE"
62
- }
63
- }
64
- ```
65
-
66
- This will:
67
- - Scan the current app
68
- - Include shared packages
69
- - Ignore variables used only in specific environments
70
-
71
- ---
72
-
73
31
  ## Automatic Fixes (`--fix`)
74
32
 
75
33
  Automatically add missing variables to your `.env` file:
@@ -82,7 +40,7 @@ dotenv-diff --fix
82
40
 
83
41
  1. Code uses `process.env.NEW_API_KEY`
84
42
  2. Run `dotenv-diff --fix`
85
- 3. Tool adds `NEW_API_KEY=` to `.env`
43
+ 3. Tool adds `NEW_API_KEY=` to `.env` or `.env.example`
86
44
 
87
45
  ---
88
46
 
@@ -98,63 +56,19 @@ dotenv-diff --strict
98
56
 
99
57
  ## Framework-Specific Warnings
100
58
 
101
- When using **SvelteKit** or **Next.js**, `dotenv-diff` warns about incorrect usage.
59
+ In SvelteKit and Next.js projects, dotenv-diff detects framework-specific
60
+ environment variable misuses.
102
61
 
103
62
  Example warning:
104
63
 
105
64
  ```bash
106
- Environment variable usage issues:
65
+ Framework issues (Sveltekit):
107
66
  - PUBLIC_URL (src/routes/+page.ts:1)
108
67
  → Variables accessed through import.meta.env must start with "VITE_"
109
68
  ```
110
69
 
111
70
  ---
112
71
 
113
- ## Detect Secrets in `.env.example`
114
-
115
- `dotenv-diff` scans example files for potential secrets:
116
-
117
- ```bash
118
- Potential real secrets found in .env.example:
119
- - API_KEY = "sk_test_..." → Matches known provider pattern [high]
120
- ```
121
-
122
- ---
123
-
124
- ## Logging Environment Variables
125
-
126
- Detect accidental logging of sensitive values:
127
-
128
- ```js
129
- console.log(process.env.API_KEY);
130
- ```
131
-
132
- This triggers a warning.
133
-
134
- ---
135
-
136
- ## Ignore Specific Warnings
137
-
138
- Ignore specific lines using comments:
139
-
140
- ```js
141
- const secret = "https://example.com"; // dotenv-diff-ignore
142
- ```
143
-
144
- ---
145
-
146
- ## Health Score
147
-
148
- Provides an overall score based on:
149
- - Missing variables
150
- - Potential secrets
151
- - Naming conventions
152
- - Logged variables
153
- - Unused variables
154
- - Framework-specific rules
155
-
156
- ---
157
-
158
72
  ## Expiration Warnings
159
73
 
160
74
  Add expiration metadata to variables:
@@ -166,34 +80,6 @@ API_TOKEN=
166
80
 
167
81
  ---
168
82
 
169
- ## Inconsistent Naming Warnings
170
-
171
- Warns about inconsistent keys like `APIKEY` vs `API_KEY`.
172
-
173
- Disable via config:
174
-
175
- ```json
176
- "inconsistentNamingWarnings": false
177
- ```
178
-
179
- ---
180
-
181
- ## Show / Hide Output Options
182
-
183
- Disable unused variables list:
184
-
185
- ```bash
186
- dotenv-diff --no-show-unused
187
- ```
188
-
189
- Disable statistics:
190
-
191
- ```bash
192
- dotenv-diff --no-show-stats
193
- ```
194
-
195
- ---
196
-
197
83
  ## File Scanning Options
198
84
 
199
85
  Include or exclude files:
@@ -224,12 +110,23 @@ dotenv-diff --compare --env .env.local --example .env.example.local
224
110
 
225
111
  ---
226
112
 
227
- ## Automatically Create Missing Files
113
+ ## Monorepo (Turborepo) Usage
228
114
 
229
- ```bash
230
- dotenv-diff --compare --yes
115
+ In monorepos with multiple apps and packages, you can include shared folders:
116
+
117
+ ```json
118
+ {
119
+ "scripts": {
120
+ "dotenv-diff": "dotenv-diff --example .env.example --include-files '../../packages/**/*' --ignore VITE_MODE"
121
+ }
122
+ }
231
123
  ```
232
124
 
125
+ This will:
126
+ - Scan the current app
127
+ - Include shared packages
128
+ - Ignore variables used only in specific environments
129
+
233
130
  ---
234
131
 
235
132
  ## Exit Codes
@@ -239,6 +136,12 @@ dotenv-diff --compare --yes
239
136
 
240
137
  ---
241
138
 
139
+ ## Documentation
140
+
141
+ Full documentation: https://dotenv-diff-docs.vercel.app
142
+
143
+ ---
144
+
242
145
  ## 🤝 Contributing
243
146
 
244
147
  Issues and pull requests are welcome.
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/cli/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmBzC;;;;GAIG;AACH,wBAAsB,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBzD"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/cli/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4BzC;;;;GAIG;AACH,wBAAsB,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBzD"}
@@ -5,11 +5,11 @@ import { discoverEnvFiles } from '../services/envDiscovery.js';
5
5
  import { pairWithExample } from '../core/envPairing.js';
6
6
  import { ensureFilesOrPrompt } from '../services/ensureFilesOrPrompt.js';
7
7
  import { compareMany } from '../commands/compare.js';
8
- import {} from '../config/types.js';
9
8
  import { scanUsage } from '../commands/scanUsage.js';
10
9
  import { printErrorNotFound } from '../ui/compare/printErrorNotFound.js';
11
10
  import { setupGlobalConfig } from '../ui/shared/setupGlobalConfig.js';
12
11
  import { loadConfig } from '../config/loadConfig.js';
12
+ import { DEFAULT_ENV_FILE } from '../config/constants.js';
13
13
  /**
14
14
  * Run the CLI program
15
15
  * @param program The commander program instance
@@ -27,25 +27,19 @@ export async function run(program) {
27
27
  // Normalize merged options
28
28
  const opts = normalizeOptions(mergedRawOptions);
29
29
  setupGlobalConfig(opts);
30
- // Route to appropriate command
31
- if (opts.compare) {
32
- await runCompareMode(opts);
33
- }
34
- else {
35
- await runScanMode(opts);
36
- }
30
+ // Route to appropriate command and handle exit
31
+ const exitWithError = opts.compare
32
+ ? await runCompareMode(opts)
33
+ : await runScanMode(opts);
34
+ process.exit(exitWithError ? 1 : 0);
37
35
  }
38
36
  /**
39
37
  * Run scan-usage mode (default behavior)
40
38
  * @param opts - Normalized options
41
- * @returns void
39
+ * @returns Whether to exit with an error code
42
40
  */
43
41
  async function runScanMode(opts) {
44
- const envPath = typeof opts.envFlag === 'string'
45
- ? opts.envFlag
46
- : fs.existsSync('.env')
47
- ? '.env'
48
- : undefined;
42
+ const envPath = resolveEnvPath(opts.envFlag);
49
43
  const { exitWithError } = await scanUsage({
50
44
  cwd: opts.cwd,
51
45
  include: opts.includeFiles,
@@ -60,42 +54,47 @@ async function runScanMode(opts) {
60
54
  showStats: opts.showStats,
61
55
  isCiMode: opts.isCiMode,
62
56
  secrets: opts.secrets,
63
- strict: opts.strict ?? false,
64
- ignoreUrls: opts.ignoreUrls ?? [],
65
- uppercaseKeys: opts.uppercaseKeys ?? true,
57
+ strict: opts.strict,
58
+ ignoreUrls: opts.ignoreUrls,
59
+ files: opts.files,
60
+ uppercaseKeys: opts.uppercaseKeys,
66
61
  expireWarnings: opts.expireWarnings,
67
62
  inconsistentNamingWarnings: opts.inconsistentNamingWarnings,
68
- ...(opts.files ? { files: opts.files } : {}),
69
63
  });
70
- process.exit(exitWithError ? 1 : 0);
64
+ return exitWithError;
71
65
  }
72
66
  /**
73
67
  * Run compare mode
74
68
  * @param opts - Normalized options
75
- * @returns void
69
+ * @returns Whether to exit with an error code
76
70
  */
77
71
  async function runCompareMode(opts) {
78
72
  // Handle direct file comparison (both --env and --example specified)
79
73
  if (opts.envFlag && opts.exampleFlag) {
80
- await runDirectFileComparison(opts);
81
- return;
74
+ return await runDirectFileComparison(opts);
82
75
  }
83
76
  // Handle auto-discovery comparison
84
- await runAutoDiscoveryComparison(opts);
77
+ return await runAutoDiscoveryComparison(opts);
85
78
  }
86
79
  /**
87
80
  * Compare two specific files directly
88
81
  * @param opts - Normalized options
89
- * @returns void
82
+ * @returns Whether to exit with an error code
90
83
  */
91
84
  async function runDirectFileComparison(opts) {
85
+ // Type guard ensures both flags are defined
86
+ if (!opts.envFlag || !opts.exampleFlag) {
87
+ throw new Error('Both envFlag and exampleFlag must be defined for direct file comparison');
88
+ }
92
89
  const envExists = fs.existsSync(opts.envFlag);
93
90
  const exExists = fs.existsSync(opts.exampleFlag);
94
91
  // Handle missing files
95
92
  if (!envExists || !exExists) {
96
- const shouldExit = await handleMissingFiles(opts, opts.envFlag, opts.exampleFlag);
97
- if (shouldExit)
98
- return;
93
+ const result = await handleMissingFiles(opts, opts.envFlag, opts.exampleFlag);
94
+ if (result.shouldExit) {
95
+ outputResults([], opts);
96
+ return result.exitWithError;
97
+ }
99
98
  }
100
99
  // Perform comparison
101
100
  const report = [];
@@ -106,12 +105,13 @@ async function runDirectFileComparison(opts) {
106
105
  examplePath: opts.exampleFlag,
107
106
  },
108
107
  ], buildCompareOptions(opts, report));
109
- outputResults(report, opts, exitWithError);
108
+ outputResults(report, opts);
109
+ return exitWithError;
110
110
  }
111
111
  /**
112
112
  * Compare using auto-discovery
113
113
  * @param opts - Normalized options
114
- * @returns void
114
+ * @returns Whether to exit with an error code
115
115
  */
116
116
  async function runAutoDiscoveryComparison(opts) {
117
117
  // Discover available env files
@@ -130,21 +130,22 @@ async function runAutoDiscoveryComparison(opts) {
130
130
  isCiMode: opts.isCiMode,
131
131
  });
132
132
  if (initResult.shouldExit) {
133
- outputResults([], opts, initResult.exitCode !== 0);
134
- return;
133
+ outputResults([], opts);
134
+ return initResult.exitCode !== 0;
135
135
  }
136
136
  // Compare all discovered pairs
137
137
  const pairs = pairWithExample(discovery);
138
138
  const report = [];
139
139
  const { exitWithError } = await compareMany(pairs, buildCompareOptions(opts, report));
140
- outputResults(report, opts, exitWithError);
140
+ outputResults(report, opts);
141
+ return exitWithError;
141
142
  }
142
143
  /**
143
144
  * Handle missing files in CI vs interactive mode
144
145
  * @param opts - Normalized options
145
146
  * @param envFlag - Path to the .env file
146
147
  * @param exampleFlag - Path to the example file
147
- * @returns Whether the process should exit after handling missing files
148
+ * @returns Result indicating if process should exit and with what error code
148
149
  */
149
150
  async function handleMissingFiles(opts, envFlag, exampleFlag) {
150
151
  const envExists = fs.existsSync(envFlag);
@@ -152,7 +153,7 @@ async function handleMissingFiles(opts, envFlag, exampleFlag) {
152
153
  if (opts.isCiMode) {
153
154
  // In CI mode, just show errors and exit
154
155
  printErrorNotFound(envExists, exExists, envFlag, exampleFlag);
155
- process.exit(1);
156
+ return { shouldExit: true, exitWithError: true };
156
157
  }
157
158
  else {
158
159
  // Interactive mode - try to prompt for file creation
@@ -165,11 +166,10 @@ async function handleMissingFiles(opts, envFlag, exampleFlag) {
165
166
  isCiMode: opts.isCiMode,
166
167
  });
167
168
  if (result.shouldExit) {
168
- outputResults([], opts, result.exitCode !== 0);
169
- return true;
169
+ return { shouldExit: true, exitWithError: result.exitCode !== 0 };
170
170
  }
171
171
  }
172
- return false;
172
+ return { shouldExit: false, exitWithError: false };
173
173
  }
174
174
  /**
175
175
  * Build options object for compareMany function
@@ -206,15 +206,27 @@ async function handleInitFlag(cliOptions) {
206
206
  return false;
207
207
  }
208
208
  /**
209
- * Output results and exit with appropriate code
209
+ * Resolve the environment file path based on the flag or default
210
+ * @param envFlag - Optional environment file path from CLI flag
211
+ * @returns The resolved env file path or undefined
212
+ */
213
+ function resolveEnvPath(envFlag) {
214
+ if (typeof envFlag === 'string') {
215
+ return envFlag;
216
+ }
217
+ if (fs.existsSync(DEFAULT_ENV_FILE)) {
218
+ return DEFAULT_ENV_FILE;
219
+ }
220
+ return undefined;
221
+ }
222
+ /**
223
+ * Output results to console if in JSON mode
210
224
  * @param report - The comparison report entries
211
225
  * @param opts - Normalized options
212
- * @param exitWithError - Whether to exit with an error code
213
226
  */
214
- function outputResults(report, opts, exitWithError) {
227
+ function outputResults(report, opts) {
215
228
  if (opts.json) {
216
229
  console.log(JSON.stringify(report, null, 2));
217
230
  }
218
- process.exit(exitWithError ? 1 : 0);
219
231
  }
220
232
  //# sourceMappingURL=run.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/cli/run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/cli/run.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,9 @@
1
- import type { ComparisonOptions, FilePair, ComparisonResult } from '../config/types.js';
1
+ import type { ComparisonOptions, FilePair, ExitResult } from '../config/types.js';
2
2
  /**
3
3
  * Compares multiple pairs of .env and .env.example files.
4
4
  * @param pairs - The pairs of environment files to compare.
5
5
  * @param opts - The comparison options.
6
6
  * @returns An object indicating the overall comparison results.
7
7
  */
8
- export declare function compareMany(pairs: FilePair[], opts: Readonly<ComparisonOptions>): Promise<ComparisonResult>;
8
+ export declare function compareMany(pairs: FilePair[], opts: Readonly<ComparisonOptions>): Promise<ExitResult>;
9
9
  //# sourceMappingURL=compare.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../../src/commands/compare.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAGV,iBAAiB,EACjB,QAAQ,EACR,gBAAgB,EAGjB,MAAM,oBAAoB,CAAC;AA2G5B;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,QAAQ,EAAE,EACjB,IAAI,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAChC,OAAO,CAAC,gBAAgB,CAAC,CAqK3B"}
1
+ {"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../../src/commands/compare.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAGV,iBAAiB,EACjB,QAAQ,EACR,UAAU,EAGX,MAAM,oBAAoB,CAAC;AAY5B;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,QAAQ,EAAE,EACjB,IAAI,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAChC,OAAO,CAAC,UAAU,CAAC,CAqKrB"}
@@ -5,7 +5,6 @@ import { diffEnv } from '../core/diffEnv.js';
5
5
  import { checkGitignoreStatus } from '../services/git.js';
6
6
  import { findDuplicateKeys } from '../services/duplicates.js';
7
7
  import { filterIgnoredKeys } from '../core/filterIgnoredKeys.js';
8
- import { isAllOk } from '../core/helpers/isAllOk.js';
9
8
  import { updateTotals } from '../core/helpers/updateTotals.js';
10
9
  import { applyFixes } from '../core/fixEnv.js';
11
10
  import { printFixTips } from '../ui/shared/printFixTips.js';
@@ -16,55 +15,6 @@ import { printAutoFix } from '../ui/shared/printAutoFix.js';
16
15
  import { printIssues } from '../ui/compare/printIssues.js';
17
16
  import { printSuccess } from '../ui/shared/printSuccess.js';
18
17
  import { printGitignoreWarning } from '../ui/shared/printGitignore.js';
19
- /**
20
- * Creates a category filter function based on options.
21
- * fx: onlyFiltering({ only: ['missing', 'extra'] })
22
- * @param opts Comparison options
23
- * @returns A function that filters categories
24
- */
25
- function createCategoryFilter(opts) {
26
- const onlySet = opts.only?.length
27
- ? new Set(opts.only)
28
- : undefined;
29
- return (category) => !onlySet || onlySet.has(category);
30
- }
31
- /**
32
- * Parses and filters the environment and example files.
33
- * @param envPath The path to the .env file
34
- * @param examplePath The path to the .env.example file
35
- * @param opts Comparison options
36
- * @returns An object containing the parsed and filtered environment variables
37
- */
38
- function parseAndFilter(envPath, examplePath, opts) {
39
- const currentFull = parseEnvFile(envPath);
40
- const exampleFull = parseEnvFile(examplePath);
41
- const currentKeys = filterIgnoredKeys(Object.keys(currentFull), opts.ignore, opts.ignoreRegex);
42
- const exampleKeys = filterIgnoredKeys(Object.keys(exampleFull), opts.ignore, opts.ignoreRegex);
43
- return {
44
- current: Object.fromEntries(currentKeys.map((k) => [k, currentFull[k] ?? ''])),
45
- example: Object.fromEntries(exampleKeys.map((k) => [k, exampleFull[k] ?? ''])),
46
- currentKeys,
47
- exampleKeys,
48
- };
49
- }
50
- /**
51
- * Finds duplicate keys in the environment and example files.
52
- * @param envPath The path to the .env file
53
- * @param examplePath The path to the .env.example file
54
- * @param opts Comparison options
55
- * @param run A function that determines if a category should be included
56
- * @returns An object containing arrays of duplicate keys for both files
57
- */
58
- function findDuplicates(envPath, examplePath, opts, run) {
59
- if (opts.allowDuplicates || !run('duplicate'))
60
- return { dupsEnv: [], dupsEx: [] };
61
- const ignoreSet = new Set(opts.ignore);
62
- const regexList = opts.ignoreRegex;
63
- const filterKey = (key) => !ignoreSet.has(key) && !regexList.some((rx) => rx.test(key));
64
- const dupsEnv = findDuplicateKeys(envPath).filter(({ key }) => filterKey(key));
65
- const dupsEx = findDuplicateKeys(examplePath).filter(({ key }) => filterKey(key));
66
- return { dupsEnv, dupsEx };
67
- }
68
18
  /**
69
19
  * Compares multiple pairs of .env and .env.example files.
70
20
  * @param pairs - The pairs of environment files to compare.
@@ -178,4 +128,68 @@ export async function compareMany(pairs, opts) {
178
128
  }
179
129
  return { exitWithError };
180
130
  }
131
+ /**
132
+ * Creates a category filter function based on options.
133
+ * fx: onlyFiltering({ only: ['missing', 'extra'] })
134
+ * @param opts Comparison options
135
+ * @returns A function that filters categories
136
+ */
137
+ function createCategoryFilter(opts) {
138
+ const onlySet = opts.only?.length
139
+ ? new Set(opts.only)
140
+ : undefined;
141
+ return (category) => !onlySet || onlySet.has(category);
142
+ }
143
+ /**
144
+ * Parses and filters the environment and example files.
145
+ * @param envPath The path to the .env file
146
+ * @param examplePath The path to the .env.example file
147
+ * @param opts Comparison options
148
+ * @returns An object containing the parsed and filtered environment variables
149
+ */
150
+ function parseAndFilter(envPath, examplePath, opts) {
151
+ const currentFull = parseEnvFile(envPath);
152
+ const exampleFull = parseEnvFile(examplePath);
153
+ const currentKeys = filterIgnoredKeys(Object.keys(currentFull), opts.ignore, opts.ignoreRegex);
154
+ const exampleKeys = filterIgnoredKeys(Object.keys(exampleFull), opts.ignore, opts.ignoreRegex);
155
+ return {
156
+ current: Object.fromEntries(currentKeys.map((k) => [k, currentFull[k] ?? ''])),
157
+ example: Object.fromEntries(exampleKeys.map((k) => [k, exampleFull[k] ?? ''])),
158
+ currentKeys,
159
+ exampleKeys,
160
+ };
161
+ }
162
+ /**
163
+ * Finds duplicate keys in the environment and example files.
164
+ * @param envPath The path to the .env file
165
+ * @param examplePath The path to the .env.example file
166
+ * @param opts Comparison options
167
+ * @param run A function that determines if a category should be included
168
+ * @returns An object containing arrays of duplicate keys for both files
169
+ */
170
+ function findDuplicates(envPath, examplePath, opts, run) {
171
+ if (opts.allowDuplicates || !run('duplicate'))
172
+ return { dupsEnv: [], dupsEx: [] };
173
+ const ignoreSet = new Set(opts.ignore);
174
+ const regexList = opts.ignoreRegex;
175
+ const filterKey = (key) => !ignoreSet.has(key) && !regexList.some((rx) => rx.test(key));
176
+ const dupsEnv = findDuplicateKeys(envPath).filter(({ key }) => filterKey(key));
177
+ const dupsEx = findDuplicateKeys(examplePath).filter(({ key }) => filterKey(key));
178
+ return { dupsEnv, dupsEx };
179
+ }
180
+ /**
181
+ * Checks if all filtered comparison results are okay (i.e., no issues found).
182
+ * This is used in compare.ts to determine if the comparison passed all checks.
183
+ * @param filtered - The filtered comparison results.
184
+ * @returns True if all checks pass, false otherwise.
185
+ */
186
+ function isAllOk(filtered) {
187
+ return (filtered.missing.length === 0 &&
188
+ (filtered.extra?.length ?? 0) === 0 &&
189
+ (filtered.empty?.length ?? 0) === 0 &&
190
+ filtered.duplicatesEnv.length === 0 &&
191
+ filtered.duplicatesEx.length === 0 &&
192
+ (filtered.mismatches?.length ?? 0) === 0 &&
193
+ !filtered.gitignoreIssue);
194
+ }
181
195
  //# sourceMappingURL=compare.js.map