dotenv-diff 2.5.1 → 2.5.3
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.
- package/CHANGELOG.md +24 -6
- package/README.md +2 -2
- package/dist/bin/dotenv-diff.js +0 -0
- package/dist/src/ui/scan/printExpireWarnings.d.ts.map +1 -1
- package/dist/src/ui/scan/printExpireWarnings.js +13 -9
- package/dist/src/ui/scan/printExpireWarnings.js.map +1 -1
- package/package.json +1 -1
- package/dist/cli.d.ts +0 -9
- package/dist/cli.js +0 -294
- package/dist/diffEnv.d.ts +0 -5
- package/dist/diffEnv.js +0 -7
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -2
- package/dist/lib/checkGitignore.d.ts +0 -23
- package/dist/lib/checkGitignore.js +0 -73
- package/dist/lib/diffEnv.d.ts +0 -18
- package/dist/lib/diffEnv.js +0 -29
- package/dist/lib/parseEnv.d.ts +0 -10
- package/dist/lib/parseEnv.js +0 -25
- package/dist/parseEnv.d.ts +0 -1
- package/dist/parseEnv.js +0 -16
- package/dist/src/core/compareScan.d.ts +0 -10
- package/dist/src/core/compareScan.d.ts.map +0 -1
- package/dist/src/core/compareScan.js +0 -19
- package/dist/src/core/compareScan.js.map +0 -1
- package/dist/src/core/computeHealthScore.d.ts +0 -8
- package/dist/src/core/computeHealthScore.d.ts.map +0 -1
- package/dist/src/core/computeHealthScore.js +0 -35
- package/dist/src/core/computeHealthScore.js.map +0 -1
- package/dist/src/core/cspDetector.d.ts +0 -7
- package/dist/src/core/cspDetector.d.ts.map +0 -1
- package/dist/src/core/cspDetector.js +0 -38
- package/dist/src/core/cspDetector.js.map +0 -1
- package/dist/src/core/defaultExcludeKeys.d.ts +0 -7
- package/dist/src/core/defaultExcludeKeys.d.ts.map +0 -1
- package/dist/src/core/detectClientExposure.d.ts +0 -12
- package/dist/src/core/detectClientExposure.d.ts.map +0 -1
- package/dist/src/core/detectClientExposure.js +0 -62
- package/dist/src/core/detectClientExposure.js.map +0 -1
- package/dist/src/core/detectExpirations.d.ts +0 -14
- package/dist/src/core/detectExpirations.d.ts.map +0 -1
- package/dist/src/core/detectExpirations.js +0 -44
- package/dist/src/core/detectExpirations.js.map +0 -1
- package/dist/src/core/detectUppercaseKeys.d.ts +0 -9
- package/dist/src/core/detectUppercaseKeys.d.ts.map +0 -1
- package/dist/src/core/detectUppercaseKeys.js +0 -28
- package/dist/src/core/detectUppercaseKeys.js.map +0 -1
- package/dist/src/core/determineComparisonFile.d.ts +0 -13
- package/dist/src/core/determineComparisonFile.d.ts.map +0 -1
- package/dist/src/core/determineComparisonFile.js +0 -33
- package/dist/src/core/determineComparisonFile.js.map +0 -1
- package/dist/src/core/entropy.d.ts +0 -8
- package/dist/src/core/entropy.d.ts.map +0 -1
- package/dist/src/core/entropy.js +0 -23
- package/dist/src/core/entropy.js.map +0 -1
- package/dist/src/core/envDiscovery.d.ts +0 -19
- package/dist/src/core/envDiscovery.d.ts.map +0 -1
- package/dist/src/core/envDiscovery.js +0 -81
- package/dist/src/core/envDiscovery.js.map +0 -1
- package/dist/src/core/envPairing.d.ts +0 -8
- package/dist/src/core/envPairing.d.ts.map +0 -1
- package/dist/src/core/envPairing.js +0 -36
- package/dist/src/core/envPairing.js.map +0 -1
- package/dist/src/core/envValidator.d.ts +0 -9
- package/dist/src/core/envValidator.d.ts.map +0 -1
- package/dist/src/core/envValidator.js +0 -103
- package/dist/src/core/envValidator.js.map +0 -1
- package/dist/src/core/exampleSecretDetector.d.ts +0 -13
- package/dist/src/core/exampleSecretDetector.d.ts.map +0 -1
- package/dist/src/core/exampleSecretDetector.js +0 -61
- package/dist/src/core/exampleSecretDetector.js.map +0 -1
- package/dist/src/core/frameworkDetector.d.ts +0 -14
- package/dist/src/core/frameworkDetector.d.ts.map +0 -1
- package/dist/src/core/frameworkDetector.js +0 -40
- package/dist/src/core/frameworkDetector.js.map +0 -1
- package/dist/src/core/frameworkValidator.d.ts +0 -10
- package/dist/src/core/frameworkValidator.d.ts.map +0 -1
- package/dist/src/core/frameworkValidator.js +0 -21
- package/dist/src/core/frameworkValidator.js.map +0 -1
- package/dist/src/core/frameworks/angularRules.d.ts +0 -4
- package/dist/src/core/frameworks/angularRules.d.ts.map +0 -1
- package/dist/src/core/helpers/isAllOk.d.ts +0 -9
- package/dist/src/core/helpers/isAllOk.d.ts.map +0 -1
- package/dist/src/core/helpers/isAllOk.js +0 -16
- package/dist/src/core/helpers/isAllOk.js.map +0 -1
- package/dist/src/core/helpers/updateTotals.d.ts +0 -19
- package/dist/src/core/helpers/updateTotals.d.ts.map +0 -1
- package/dist/src/core/helpers/updateTotals.js +0 -37
- package/dist/src/core/helpers/updateTotals.js.map +0 -1
- package/dist/src/core/parseAndFilterEnv.d.ts +0 -20
- package/dist/src/core/parseAndFilterEnv.d.ts.map +0 -1
- package/dist/src/core/parseAndFilterEnv.js +0 -22
- package/dist/src/core/parseAndFilterEnv.js.map +0 -1
- package/dist/src/core/processComparisonFile.d.ts +0 -43
- package/dist/src/core/processComparisonFile.d.ts.map +0 -1
- package/dist/src/core/processComparisonFile.js +0 -170
- package/dist/src/core/processComparisonFile.js.map +0 -1
- package/dist/src/core/scan/scanJsonOutput.d.ts +0 -85
- package/dist/src/core/scan/scanJsonOutput.d.ts.map +0 -1
- package/dist/src/core/scan/scanJsonOutput.js +0 -97
- package/dist/src/core/scan/scanJsonOutput.js.map +0 -1
- package/dist/src/core/scan/secretDetectors.d.ts +0 -28
- package/dist/src/core/scan/secretDetectors.d.ts.map +0 -1
- package/dist/src/core/scan/secretDetectors.js +0 -272
- package/dist/src/core/scan/secretDetectors.js.map +0 -1
- package/dist/src/core/scanFile.d.ts +0 -10
- package/dist/src/core/scanFile.d.ts.map +0 -1
- package/dist/src/core/scanFile.js +0 -65
- package/dist/src/core/scanFile.js.map +0 -1
- package/dist/src/core/scanJsonOutput.d.ts +0 -85
- package/dist/src/core/scanJsonOutput.d.ts.map +0 -1
- package/dist/src/core/scanJsonOutput.js +0 -97
- package/dist/src/core/scanJsonOutput.js.map +0 -1
- package/dist/src/core/secretDetectors.d.ts +0 -28
- package/dist/src/core/secretDetectors.d.ts.map +0 -1
- package/dist/src/core/secretDetectors.js +0 -272
- package/dist/src/core/secretDetectors.js.map +0 -1
- package/dist/src/core/t3env/detectT3Env.d.ts +0 -12
- package/dist/src/core/t3env/detectT3Env.d.ts.map +0 -1
- package/dist/src/core/t3env/detectT3Env.js +0 -113
- package/dist/src/core/t3env/detectT3Env.js.map +0 -1
- package/dist/src/core/t3env/t3EnvRules.d.ts +0 -10
- package/dist/src/core/t3env/t3EnvRules.d.ts.map +0 -1
- package/dist/src/core/t3env/t3EnvRules.js +0 -61
- package/dist/src/core/t3env/t3EnvRules.js.map +0 -1
- package/dist/src/core/t3env/t3EnvValidator.d.ts +0 -9
- package/dist/src/core/t3env/t3EnvValidator.d.ts.map +0 -1
- package/dist/src/core/t3env/t3EnvValidator.js +0 -32
- package/dist/src/core/t3env/t3EnvValidator.js.map +0 -1
- package/dist/src/lib/diffEnv.d.ts +0 -19
- package/dist/src/lib/diffEnv.d.ts.map +0 -1
- package/dist/src/lib/diffEnv.js +0 -31
- package/dist/src/lib/diffEnv.js.map +0 -1
- package/dist/src/lib/parseEnv.d.ts +0 -11
- package/dist/src/lib/parseEnv.d.ts.map +0 -1
- package/dist/src/lib/parseEnv.js +0 -26
- package/dist/src/lib/parseEnv.js.map +0 -1
- package/dist/src/services/codeBaseScanner.d.ts +0 -8
- package/dist/src/services/codeBaseScanner.d.ts.map +0 -1
- package/dist/src/services/codeBaseScanner.js +0 -110
- package/dist/src/services/codeBaseScanner.js.map +0 -1
- package/dist/src/services/duplicates.d.ts +0 -12
- package/dist/src/services/duplicates.d.ts.map +0 -1
- package/dist/src/services/duplicates.js +0 -36
- package/dist/src/services/duplicates.js.map +0 -1
- package/dist/src/services/ensureFilesOrPrompt.d.ts +0 -22
- package/dist/src/services/ensureFilesOrPrompt.d.ts.map +0 -1
- package/dist/src/services/ensureFilesOrPrompt.js +0 -76
- package/dist/src/services/ensureFilesOrPrompt.js.map +0 -1
- package/dist/src/services/scanOutputToConsole.d.ts +0 -17
- package/dist/src/services/scanOutputToConsole.d.ts.map +0 -1
- package/dist/src/services/scanOutputToConsole.js +0 -127
- package/dist/src/services/scanOutputToConsole.js.map +0 -1
- package/dist/src/ui/compare/printAutoFix.d.ts +0 -16
- package/dist/src/ui/compare/printAutoFix.d.ts.map +0 -1
- package/dist/src/ui/compare/printAutoFix.js +0 -34
- package/dist/src/ui/compare/printAutoFix.js.map +0 -1
- package/dist/src/ui/compare/printAutoFixApplied.d.ts +0 -7
- package/dist/src/ui/compare/printAutoFixApplied.d.ts.map +0 -1
- package/dist/src/ui/compare/printAutoFixApplied.js +0 -22
- package/dist/src/ui/compare/printAutoFixApplied.js.map +0 -1
- package/dist/src/ui/compare/printDuplicates.d.ts +0 -17
- package/dist/src/ui/compare/printDuplicates.d.ts.map +0 -1
- package/dist/src/ui/compare/printDuplicates.js +0 -25
- package/dist/src/ui/compare/printDuplicates.js.map +0 -1
- package/dist/src/ui/compare/printFixTips.d.ts +0 -11
- package/dist/src/ui/compare/printFixTips.d.ts.map +0 -1
- package/dist/src/ui/compare/printFixTips.js +0 -46
- package/dist/src/ui/compare/printFixTips.js.map +0 -1
- package/dist/src/ui/compare/printSuccess.d.ts +0 -11
- package/dist/src/ui/compare/printSuccess.d.ts.map +0 -1
- package/dist/src/ui/compare/printSuccess.js +0 -27
- package/dist/src/ui/compare/printSuccess.js.map +0 -1
- package/dist/src/ui/scan/printCspWarning.d.ts +0 -9
- package/dist/src/ui/scan/printCspWarning.d.ts.map +0 -1
- package/dist/src/ui/scan/printCspWarning.js +0 -20
- package/dist/src/ui/scan/printCspWarning.js.map +0 -1
- package/dist/src/ui/scan/printEnvWarnings.d.ts +0 -8
- package/dist/src/ui/scan/printEnvWarnings.d.ts.map +0 -1
- package/dist/src/ui/scan/printEnvWarnings.js +0 -20
- package/dist/src/ui/scan/printEnvWarnings.js.map +0 -1
- package/dist/src/ui/scan/printExposedVars.d.ts +0 -8
- package/dist/src/ui/scan/printExposedVars.d.ts.map +0 -1
- package/dist/src/ui/scan/printExposedVars.js +0 -24
- package/dist/src/ui/scan/printExposedVars.js.map +0 -1
- package/dist/src/ui/scan/printT3EnvWarnings.d.ts +0 -8
- package/dist/src/ui/scan/printT3EnvWarnings.d.ts.map +0 -1
- package/dist/src/ui/scan/printT3EnvWarnings.js +0 -20
- package/dist/src/ui/scan/printT3EnvWarnings.js.map +0 -1
- package/dist/src/ui/scan/printUniqueVariables.d.ts +0 -7
- package/dist/src/ui/scan/printUniqueVariables.d.ts.map +0 -1
- package/dist/src/ui/scan/printUniqueVariables.js +0 -14
- package/dist/src/ui/scan/printUniqueVariables.js.map +0 -1
- package/dist/src/ui/scan/printVariables.d.ts +0 -10
- package/dist/src/ui/scan/printVariables.d.ts.map +0 -1
- package/dist/src/ui/scan/printVariables.js +0 -37
- package/dist/src/ui/scan/printVariables.js.map +0 -1
- package/dist/src/ui/shared/printProgress.d.ts +0 -24
- package/dist/src/ui/shared/printProgress.d.ts.map +0 -1
- package/dist/src/ui/shared/printProgress.js +0 -43
- package/dist/src/ui/shared/printProgress.js.map +0 -1
- package/dist/types/scanUsage.d.ts +0 -43
- package/dist/types/scanUsage.d.ts.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,13 +6,23 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
## [](https://github.com/Chrilleweb/dotenv-diff/compare/v2.
|
|
9
|
+
## [](https://github.com/Chrilleweb/dotenv-diff/compare/v2.5.2...vnull) (2026-01-27)
|
|
10
10
|
|
|
11
11
|
### Bug Fixes
|
|
12
12
|
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
|
|
13
|
+
* changed color of scanning header to cyan ([ed6cad1](https://github.com/Chrilleweb/dotenv-diff/commit/ed6cad1502a8c340ddcbcb45a63c20d1ba9feb26))
|
|
14
|
+
* Expire warning text ui ([90caa27](https://github.com/Chrilleweb/dotenv-diff/commit/90caa27762cb1e1a7a81ec4fa978e26af8e46a5c))
|
|
15
|
+
|
|
16
|
+
### Documentation
|
|
17
|
+
|
|
18
|
+
* docs folder instead of public ([f88ad42](https://github.com/Chrilleweb/dotenv-diff/commit/f88ad422a5119cf50b6e27e2ddb7ffd7489e28d4))
|
|
19
|
+
* updated readme gif links ([c45c2df](https://github.com/Chrilleweb/dotenv-diff/commit/c45c2df166139ad2c7a83af3df56032d4f81b310))
|
|
20
|
+
|
|
21
|
+
## [](https://github.com/Chrilleweb/dotenv-diff/compare/v2.5.1...vnull) (2026-01-26)
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
* scanning color magenta ([b90107b](https://github.com/Chrilleweb/dotenv-diff/commit/b90107b0163de3e0ce5def6f235bc40510be71b7))
|
|
16
26
|
|
|
17
27
|
### Changelog
|
|
18
28
|
|
|
@@ -20,7 +30,15 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
|
20
30
|
|
|
21
31
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
22
32
|
|
|
23
|
-
#### [
|
|
33
|
+
#### [v2.5.2](https://github.com/Chrilleweb/dotenv-diff/compare/v2.5.1...v2.5.2)
|
|
34
|
+
|
|
35
|
+
- fix: scanning color magenta [`#223`](https://github.com/Chrilleweb/dotenv-diff/pull/223)
|
|
36
|
+
- chore: trying with updated npm [`#222`](https://github.com/Chrilleweb/dotenv-diff/pull/222)
|
|
37
|
+
- chore: 2 workflows for npm publish and tags release [`#221`](https://github.com/Chrilleweb/dotenv-diff/pull/221)
|
|
38
|
+
|
|
39
|
+
#### [v2.5.1](https://github.com/Chrilleweb/dotenv-diff/compare/2.5.0...v2.5.1)
|
|
40
|
+
|
|
41
|
+
> 26 January 2026
|
|
24
42
|
|
|
25
43
|
- chore: removed publish fra package manager [`#220`](https://github.com/Chrilleweb/dotenv-diff/pull/220)
|
|
26
44
|
- chore: npm publish false [`#219`](https://github.com/Chrilleweb/dotenv-diff/pull/219)
|
|
@@ -37,9 +55,9 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
37
55
|
- fix: modifed release.yml [`#207`](https://github.com/Chrilleweb/dotenv-diff/pull/207)
|
|
38
56
|
- fix: standardize scan output colors [`#206`](https://github.com/Chrilleweb/dotenv-diff/pull/206)
|
|
39
57
|
- chore: setup release-it [`#204`](https://github.com/Chrilleweb/dotenv-diff/pull/204)
|
|
58
|
+
- chore: release v2.5.1 [`68723f6`](https://github.com/Chrilleweb/dotenv-diff/commit/68723f61dc7c426341fc13545de9f461aa964b5a)
|
|
40
59
|
- ci: release yml [`a1db55f`](https://github.com/Chrilleweb/dotenv-diff/commit/a1db55f7701f3328396359f90154cc3ecab5cb69)
|
|
41
60
|
- chore: release npm outside og release-it [`b685037`](https://github.com/Chrilleweb/dotenv-diff/commit/b685037b8a8f1e5a5fd59d21e7a877d11dc75196)
|
|
42
|
-
- chore: removed pnpm specified v [`08f331c`](https://github.com/Chrilleweb/dotenv-diff/commit/08f331c6f4e044ec0d64c904767885fbaa123b36)
|
|
43
61
|
|
|
44
62
|
#### [2.5.0](https://github.com/Chrilleweb/dotenv-diff/compare/v2.4.11...2.5.0)
|
|
45
63
|
|
package/README.md
CHANGED
|
@@ -11,10 +11,10 @@ First-class support for SvelteKit and Next.js. Also works well in modern JavaScr
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
13
|
### Warnings & errors detection
|
|
14
|
-

|
|
15
15
|
|
|
16
16
|
### Clean / successful scan
|
|
17
|
-

|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
package/dist/bin/dotenv-diff.js
CHANGED
|
File without changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"printExpireWarnings.d.ts","sourceRoot":"","sources":["../../../../src/ui/scan/printExpireWarnings.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,aAAa,EAAE,EACzB,MAAM,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"printExpireWarnings.d.ts","sourceRoot":"","sources":["../../../../src/ui/scan/printExpireWarnings.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,aAAa,EAAE,EACzB,MAAM,EAAE,OAAO,QA+BhB"}
|
|
@@ -13,15 +13,19 @@ export function printExpireWarnings(warnings, isJson) {
|
|
|
13
13
|
return;
|
|
14
14
|
console.log(chalk.yellow('⚠️ Expiration warnings:'));
|
|
15
15
|
for (const warn of warnings) {
|
|
16
|
-
const severity = warn.daysLeft
|
|
17
|
-
? chalk.red(
|
|
18
|
-
: warn.daysLeft
|
|
19
|
-
? chalk.red(
|
|
20
|
-
: warn.daysLeft
|
|
21
|
-
? chalk.red(
|
|
22
|
-
: warn.daysLeft
|
|
23
|
-
? chalk.
|
|
24
|
-
:
|
|
16
|
+
const severity = warn.daysLeft === -1
|
|
17
|
+
? chalk.red('EXPIRED YESTERDAY')
|
|
18
|
+
: warn.daysLeft < 0
|
|
19
|
+
? chalk.red(`EXPIRED ${Math.abs(warn.daysLeft)} days ago`)
|
|
20
|
+
: warn.daysLeft === 0
|
|
21
|
+
? chalk.red('EXPIRES TODAY')
|
|
22
|
+
: warn.daysLeft === 1
|
|
23
|
+
? chalk.red('expires tomorrow')
|
|
24
|
+
: warn.daysLeft <= 3
|
|
25
|
+
? chalk.red(`expires in ${warn.daysLeft} days`)
|
|
26
|
+
: warn.daysLeft <= 7
|
|
27
|
+
? chalk.yellow(`expires in ${warn.daysLeft} days`)
|
|
28
|
+
: chalk.green(`expires in ${warn.daysLeft} days`);
|
|
25
29
|
const keyLabel = chalk.yellow(`- ${warn.key.padEnd(15)}`);
|
|
26
30
|
console.log(` ${keyLabel} → ${severity} (${warn.date})`);
|
|
27
31
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"printExpireWarnings.js","sourceRoot":"","sources":["../../../../src/ui/scan/printExpireWarnings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAAyB,EACzB,MAAe;IAEf,IAAI,MAAM,EAAE,CAAC;QACX,OAAO;IACT,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAElC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC,CAAC;IAEtD,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,MAAM,QAAQ,GACZ,IAAI,CAAC,QAAQ,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"printExpireWarnings.js","sourceRoot":"","sources":["../../../../src/ui/scan/printExpireWarnings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAAyB,EACzB,MAAe;IAEf,IAAI,MAAM,EAAE,CAAC;QACX,OAAO;IACT,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAElC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC,CAAC;IAEtD,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,MAAM,QAAQ,GACZ,IAAI,CAAC,QAAQ,KAAK,CAAC,CAAC;YAClB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC;YAChC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC;gBACjB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAC1D,CAAC,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC;oBACnB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC;oBAC5B,CAAC,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC;wBACnB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC;wBAC/B,CAAC,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC;4BAClB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,IAAI,CAAC,QAAQ,OAAO,CAAC;4BAC/C,CAAC,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC;gCAClB,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC,QAAQ,OAAO,CAAC;gCAClD,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,QAAQ,OAAO,CAAC,CAAC;QAEhE,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,MAAM,QAAQ,MAAM,QAAQ,KAAK,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC"}
|
package/package.json
CHANGED
package/dist/cli.d.ts
DELETED
package/dist/cli.js
DELETED
|
@@ -1,294 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* CLI entry point for the `dotenv-diff` tool.
|
|
4
|
-
*
|
|
5
|
-
* - Compares `.env` and `.env.example` files.
|
|
6
|
-
* - Optionally checks for value mismatches.
|
|
7
|
-
* - Warns about missing keys, extra keys, empty values, and mismatches.
|
|
8
|
-
*/
|
|
9
|
-
import { Command } from 'commander';
|
|
10
|
-
import path from 'path';
|
|
11
|
-
import fs from 'fs';
|
|
12
|
-
import chalk from 'chalk';
|
|
13
|
-
import prompts from 'prompts';
|
|
14
|
-
import { parseEnvFile } from './lib/parseEnv.js';
|
|
15
|
-
import { diffEnv } from './lib/diffEnv.js';
|
|
16
|
-
import { warnIfEnvNotIgnored } from './lib/checkGitignore.js';
|
|
17
|
-
const program = new Command();
|
|
18
|
-
program
|
|
19
|
-
.name('dotenv-diff')
|
|
20
|
-
.description('Compare .env and .env.example files')
|
|
21
|
-
.option('--check-values', 'Compare actual values if example has values')
|
|
22
|
-
.option('--ci', 'Run non-interactively and never create files')
|
|
23
|
-
.option('-y, --yes', 'Run non-interactively and answer Yes to prompts')
|
|
24
|
-
.option('--env <file>', 'Path to a specific .env file')
|
|
25
|
-
.option('--example <file>', 'Path to a specific .env.example file')
|
|
26
|
-
.parse(process.argv);
|
|
27
|
-
const options = program.opts();
|
|
28
|
-
const checkValues = options.checkValues ?? false;
|
|
29
|
-
const isCiMode = Boolean(options.ci);
|
|
30
|
-
const isYesMode = Boolean(options.yes);
|
|
31
|
-
if (isCiMode && isYesMode) {
|
|
32
|
-
console.log(chalk.yellow('⚠️ Both --ci and --yes provided; proceeding with --yes.'));
|
|
33
|
-
}
|
|
34
|
-
const cwd = process.cwd();
|
|
35
|
-
const envFlag = options.env ? path.resolve(cwd, options.env) : null;
|
|
36
|
-
const exampleFlag = options.example ? path.resolve(cwd, options.example) : null;
|
|
37
|
-
const bothFlags = Boolean(envFlag && exampleFlag);
|
|
38
|
-
let alreadyWarnedMissingEnv = false;
|
|
39
|
-
if (bothFlags) {
|
|
40
|
-
const envExistsFlag = fs.existsSync(envFlag);
|
|
41
|
-
const exampleExistsFlag = fs.existsSync(exampleFlag);
|
|
42
|
-
if (!envExistsFlag || !exampleExistsFlag) {
|
|
43
|
-
if (!envExistsFlag) {
|
|
44
|
-
console.error(chalk.red(`❌ Error: --env file not found: ${path.basename(envFlag)}`));
|
|
45
|
-
}
|
|
46
|
-
if (!exampleExistsFlag) {
|
|
47
|
-
console.error(chalk.red(`❌ Error: --example file not found: ${path.basename(exampleFlag)}`));
|
|
48
|
-
}
|
|
49
|
-
process.exit(1);
|
|
50
|
-
}
|
|
51
|
-
console.log(chalk.bold(`🔍 Comparing ${path.basename(envFlag)} ↔ ${path.basename(exampleFlag)}...`));
|
|
52
|
-
const current = parseEnvFile(envFlag);
|
|
53
|
-
const example = parseEnvFile(exampleFlag);
|
|
54
|
-
const diff = diffEnv(current, example, checkValues);
|
|
55
|
-
const emptyKeys = Object.entries(current)
|
|
56
|
-
.filter(([, value]) => (value ?? '').trim() === '')
|
|
57
|
-
.map(([key]) => key);
|
|
58
|
-
let exitWithError = false;
|
|
59
|
-
if (diff.missing.length === 0 &&
|
|
60
|
-
diff.extra.length === 0 &&
|
|
61
|
-
emptyKeys.length === 0 &&
|
|
62
|
-
diff.valueMismatches.length === 0) {
|
|
63
|
-
console.log(chalk.green(' ✅ All keys match.'));
|
|
64
|
-
console.log();
|
|
65
|
-
process.exit(0);
|
|
66
|
-
}
|
|
67
|
-
if (diff.missing.length > 0) {
|
|
68
|
-
exitWithError = true;
|
|
69
|
-
console.log(chalk.red(' ❌ Missing keys:'));
|
|
70
|
-
diff.missing.forEach((key) => console.log(chalk.red(` - ${key}`)));
|
|
71
|
-
}
|
|
72
|
-
if (diff.extra.length > 0) {
|
|
73
|
-
console.log(chalk.yellow(' ⚠️ Extra keys (not in example):'));
|
|
74
|
-
diff.extra.forEach((key) => console.log(chalk.yellow(` - ${key}`)));
|
|
75
|
-
}
|
|
76
|
-
if (emptyKeys.length > 0) {
|
|
77
|
-
console.log(chalk.yellow(' ⚠️ Empty values:'));
|
|
78
|
-
emptyKeys.forEach((key) => console.log(chalk.yellow(` - ${key}`)));
|
|
79
|
-
}
|
|
80
|
-
if (checkValues && diff.valueMismatches.length > 0) {
|
|
81
|
-
console.log(chalk.yellow(' ⚠️ Value mismatches:'));
|
|
82
|
-
diff.valueMismatches.forEach(({ key, expected, actual }) => {
|
|
83
|
-
console.log(chalk.yellow(` - ${key}: expected '${expected}', but got '${actual}'`));
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
console.log();
|
|
87
|
-
process.exit(exitWithError ? 1 : 0);
|
|
88
|
-
}
|
|
89
|
-
const envFiles = fs
|
|
90
|
-
.readdirSync(cwd)
|
|
91
|
-
.filter((f) => f.startsWith('.env') && !f.startsWith('.env.example'))
|
|
92
|
-
.sort((a, b) => (a === '.env' ? -1 : b === '.env' ? 1 : a.localeCompare(b)));
|
|
93
|
-
// Brug første .env* fil som "main" hvis flere findes
|
|
94
|
-
// (resten håndteres senere i et loop)
|
|
95
|
-
let primaryEnv = envFiles.includes('.env') ? '.env' : envFiles[0] || '.env';
|
|
96
|
-
let primaryExample = '.env.example';
|
|
97
|
-
// Override env-siden hvis --env er sat
|
|
98
|
-
if (envFlag && !exampleFlag) {
|
|
99
|
-
const envNameFromFlag = path.basename(envFlag);
|
|
100
|
-
primaryEnv = envNameFromFlag;
|
|
101
|
-
const exists = fs.existsSync(envFlag);
|
|
102
|
-
if (exists) {
|
|
103
|
-
const set = new Set([envNameFromFlag, ...envFiles]);
|
|
104
|
-
envFiles.length = 0;
|
|
105
|
-
envFiles.push(...[...set]);
|
|
106
|
-
}
|
|
107
|
-
const suffix = envNameFromFlag === '.env' ? '' : envNameFromFlag.replace('.env', '');
|
|
108
|
-
const potentialExample = suffix ? `.env.example${suffix}` : '.env.example';
|
|
109
|
-
if (fs.existsSync(path.resolve(cwd, potentialExample))) {
|
|
110
|
-
primaryExample = potentialExample;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
// Override example-siden hvis --example er sat
|
|
114
|
-
if (exampleFlag && !envFlag) {
|
|
115
|
-
const exampleNameFromFlag = path.basename(exampleFlag);
|
|
116
|
-
primaryExample = exampleNameFromFlag;
|
|
117
|
-
if (exampleNameFromFlag.startsWith('.env.example')) {
|
|
118
|
-
const suffix = exampleNameFromFlag.slice('.env.example'.length); // '' eller '.staging'
|
|
119
|
-
const matchedEnv = suffix ? `.env${suffix}` : '.env';
|
|
120
|
-
if (fs.existsSync(path.resolve(cwd, matchedEnv))) {
|
|
121
|
-
primaryEnv = matchedEnv;
|
|
122
|
-
envFiles.length = 0;
|
|
123
|
-
envFiles.push(matchedEnv);
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
// Ingen tidlig log her; Case 2 håndterer “file not found”-logikken
|
|
127
|
-
alreadyWarnedMissingEnv = true;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
// Ikke et .env.example* navn → betragt det som en arbitrær example-fil.
|
|
132
|
-
// Rør ikke env’ens valg; behold primaryEnv som tidligere (typisk '.env').
|
|
133
|
-
if (envFiles.length === 0)
|
|
134
|
-
envFiles.push(primaryEnv);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
const envPath = path.resolve(cwd, primaryEnv);
|
|
138
|
-
const examplePath = path.resolve(cwd, primaryExample);
|
|
139
|
-
const envExists = fs.existsSync(envPath);
|
|
140
|
-
const exampleExists = fs.existsSync(examplePath);
|
|
141
|
-
// Case 1: No env files and no .env.example → nothing to do
|
|
142
|
-
if (envFiles.length === 0 && !exampleExists) {
|
|
143
|
-
console.log(chalk.yellow('⚠️ No .env* or .env.example file found. Skipping comparison.'));
|
|
144
|
-
process.exit(0);
|
|
145
|
-
}
|
|
146
|
-
// Case 2: .env is missing but .env.example exists
|
|
147
|
-
if (!envExists && exampleExists) {
|
|
148
|
-
if (!alreadyWarnedMissingEnv) {
|
|
149
|
-
console.log(chalk.yellow(`📄 ${path.basename(envPath)} file not found.`));
|
|
150
|
-
}
|
|
151
|
-
let createEnv = false;
|
|
152
|
-
if (isYesMode) {
|
|
153
|
-
createEnv = true;
|
|
154
|
-
}
|
|
155
|
-
else if (isCiMode) {
|
|
156
|
-
console.log(chalk.gray('🚫 Skipping .env creation (CI mode).'));
|
|
157
|
-
process.exit(1);
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
const response = await prompts({
|
|
161
|
-
type: 'select',
|
|
162
|
-
name: 'createEnv',
|
|
163
|
-
message: `❓ Do you want to create a new ${path.basename(envPath)} file from ${path.basename(examplePath)}?`,
|
|
164
|
-
choices: [
|
|
165
|
-
{ title: 'Yes', value: true },
|
|
166
|
-
{ title: 'No', value: false },
|
|
167
|
-
],
|
|
168
|
-
initial: 0,
|
|
169
|
-
});
|
|
170
|
-
createEnv = Boolean(response.createEnv);
|
|
171
|
-
}
|
|
172
|
-
if (!createEnv) {
|
|
173
|
-
console.log(chalk.gray('🚫 Skipping .env creation.'));
|
|
174
|
-
process.exit(0);
|
|
175
|
-
}
|
|
176
|
-
const exampleContent = fs.readFileSync(examplePath, 'utf-8');
|
|
177
|
-
fs.writeFileSync(envPath, exampleContent);
|
|
178
|
-
console.log(chalk.green(`✅ ${path.basename(envPath)} file created successfully from ${path.basename(examplePath)}.\n`));
|
|
179
|
-
warnIfEnvNotIgnored({ envFile: path.basename(envPath) });
|
|
180
|
-
}
|
|
181
|
-
// Case 3: .env exists, but .env.example is missing
|
|
182
|
-
if (envExists && !exampleExists) {
|
|
183
|
-
console.log(chalk.yellow(`📄 ${path.basename(examplePath)} file not found.`));
|
|
184
|
-
let createExample = false;
|
|
185
|
-
if (isYesMode) {
|
|
186
|
-
createExample = true;
|
|
187
|
-
}
|
|
188
|
-
else if (isCiMode) {
|
|
189
|
-
console.log(chalk.gray('🚫 Skipping .env.example creation (CI mode).'));
|
|
190
|
-
process.exit(1);
|
|
191
|
-
}
|
|
192
|
-
else {
|
|
193
|
-
const response = await prompts({
|
|
194
|
-
type: 'select',
|
|
195
|
-
name: 'createExample',
|
|
196
|
-
message: `❓ Do you want to create a new ${path.basename(examplePath)} file from ${path.basename(envPath)}?`,
|
|
197
|
-
choices: [
|
|
198
|
-
{ title: 'Yes', value: true },
|
|
199
|
-
{ title: 'No', value: false },
|
|
200
|
-
],
|
|
201
|
-
initial: 0,
|
|
202
|
-
});
|
|
203
|
-
createExample = Boolean(response.createExample);
|
|
204
|
-
}
|
|
205
|
-
if (!createExample) {
|
|
206
|
-
console.log(chalk.gray('🚫 Skipping .env.example creation.'));
|
|
207
|
-
process.exit(0);
|
|
208
|
-
}
|
|
209
|
-
const envContent = fs
|
|
210
|
-
.readFileSync(envPath, 'utf-8')
|
|
211
|
-
.split('\n')
|
|
212
|
-
.map((line) => {
|
|
213
|
-
const trimmed = line.trim();
|
|
214
|
-
if (!trimmed || trimmed.startsWith('#'))
|
|
215
|
-
return trimmed;
|
|
216
|
-
const [key] = trimmed.split('=');
|
|
217
|
-
return `${key}=`;
|
|
218
|
-
})
|
|
219
|
-
.join('\n');
|
|
220
|
-
fs.writeFileSync(examplePath, envContent);
|
|
221
|
-
console.log(chalk.green(`✅ ${path.basename(examplePath)} file created successfully from ${path.basename(envPath)}.\n`));
|
|
222
|
-
}
|
|
223
|
-
// Case 4: Run comparison
|
|
224
|
-
if (!fs.existsSync(envPath) || !fs.existsSync(examplePath)) {
|
|
225
|
-
console.error(chalk.red('❌ Error: .env or .env.example is missing after setup.'));
|
|
226
|
-
process.exit(1);
|
|
227
|
-
}
|
|
228
|
-
// Case 5: Compare all found .env* files
|
|
229
|
-
let exitWithError = false;
|
|
230
|
-
for (const envName of envFiles.length > 0 ? envFiles : [primaryEnv]) {
|
|
231
|
-
// Skip self-compare når --example er sat (uden --env)
|
|
232
|
-
if (exampleFlag && !envFlag) {
|
|
233
|
-
const envAbs = path.resolve(cwd, envName);
|
|
234
|
-
if (envAbs === examplePath) {
|
|
235
|
-
// (valgfri) console.log(chalk.gray(`Skipping self-compare for ${envName}`));
|
|
236
|
-
continue;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
const suffix = envName === '.env' ? '' : envName.replace('.env', '');
|
|
240
|
-
const exampleName = suffix ? `.env.example${suffix}` : primaryExample;
|
|
241
|
-
const envPathCurrent = path.resolve(cwd, envName);
|
|
242
|
-
const examplePathCurrent = (exampleFlag && !envFlag)
|
|
243
|
-
? examplePath
|
|
244
|
-
: (fs.existsSync(path.resolve(cwd, exampleName))
|
|
245
|
-
? path.resolve(cwd, exampleName)
|
|
246
|
-
: examplePath);
|
|
247
|
-
if (!fs.existsSync(envPathCurrent) || !fs.existsSync(examplePathCurrent)) {
|
|
248
|
-
console.log(chalk.bold(`🔍 Comparing ${envName} ↔ ${path.basename(examplePathCurrent)}...`));
|
|
249
|
-
console.log(chalk.yellow(' ⚠️ Skipping: missing matching example file.'));
|
|
250
|
-
console.log();
|
|
251
|
-
continue;
|
|
252
|
-
}
|
|
253
|
-
console.log(chalk.bold(`🔍 Comparing ${envName} ↔ ${path.basename(examplePathCurrent)}...`));
|
|
254
|
-
warnIfEnvNotIgnored({
|
|
255
|
-
cwd,
|
|
256
|
-
envFile: envName,
|
|
257
|
-
log: (msg) => console.log(msg.replace(/^/gm, ' ')),
|
|
258
|
-
});
|
|
259
|
-
const current = parseEnvFile(envPathCurrent);
|
|
260
|
-
const example = parseEnvFile(examplePathCurrent);
|
|
261
|
-
const diff = diffEnv(current, example, checkValues);
|
|
262
|
-
const emptyKeys = Object.entries(current)
|
|
263
|
-
.filter(([, value]) => (value ?? '').trim() === '')
|
|
264
|
-
.map(([key]) => key);
|
|
265
|
-
if (diff.missing.length === 0 &&
|
|
266
|
-
diff.extra.length === 0 &&
|
|
267
|
-
emptyKeys.length === 0 &&
|
|
268
|
-
diff.valueMismatches.length === 0) {
|
|
269
|
-
console.log(chalk.green(' ✅ All keys match.'));
|
|
270
|
-
console.log();
|
|
271
|
-
continue;
|
|
272
|
-
}
|
|
273
|
-
if (diff.missing.length > 0) {
|
|
274
|
-
exitWithError = true;
|
|
275
|
-
console.log(chalk.red(' ❌ Missing keys:'));
|
|
276
|
-
diff.missing.forEach((key) => console.log(chalk.red(` - ${key}`)));
|
|
277
|
-
}
|
|
278
|
-
if (diff.extra.length > 0) {
|
|
279
|
-
console.log(chalk.yellow(' ⚠️ Extra keys (not in example):'));
|
|
280
|
-
diff.extra.forEach((key) => console.log(chalk.yellow(` - ${key}`)));
|
|
281
|
-
}
|
|
282
|
-
if (emptyKeys.length > 0) {
|
|
283
|
-
console.log(chalk.yellow(' ⚠️ Empty values:'));
|
|
284
|
-
emptyKeys.forEach((key) => console.log(chalk.yellow(` - ${key}`)));
|
|
285
|
-
}
|
|
286
|
-
if (checkValues && diff.valueMismatches.length > 0) {
|
|
287
|
-
console.log(chalk.yellow(' ⚠️ Value mismatches:'));
|
|
288
|
-
diff.valueMismatches.forEach(({ key, expected, actual }) => {
|
|
289
|
-
console.log(chalk.yellow(` - ${key}: expected '${expected}', but got '${actual}'`));
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
console.log(); // blank line efter sektionen med findings
|
|
293
|
-
}
|
|
294
|
-
process.exit(exitWithError ? 1 : 0);
|
package/dist/diffEnv.d.ts
DELETED
package/dist/diffEnv.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export function diffEnv(current, example) {
|
|
2
|
-
const currentKeys = Object.keys(current);
|
|
3
|
-
const exampleKeys = Object.keys(example);
|
|
4
|
-
const missing = exampleKeys.filter((key) => !currentKeys.includes(key));
|
|
5
|
-
const extra = currentKeys.filter((key) => !exampleKeys.includes(key));
|
|
6
|
-
return { missing, extra };
|
|
7
|
-
}
|
package/dist/index.d.ts
DELETED
package/dist/index.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export type GitignoreCheckOptions = {
|
|
2
|
-
/** Project root directory (default: process.cwd()) */
|
|
3
|
-
cwd?: string;
|
|
4
|
-
/** Name of the env file (default: ".env") */
|
|
5
|
-
envFile?: string;
|
|
6
|
-
/** Custom logger (default: console.log) */
|
|
7
|
-
log?: (msg: string) => void;
|
|
8
|
-
};
|
|
9
|
-
/** Are we in a git repo? (checks for .git directory in cwd) */
|
|
10
|
-
export declare function isGitRepo(cwd?: string): boolean;
|
|
11
|
-
/**
|
|
12
|
-
* Returns:
|
|
13
|
-
* - true → .env-matching patterns are found in .gitignore
|
|
14
|
-
* - false → .env-matching patterns are NOT found (or a negation exists)
|
|
15
|
-
* - null → no .gitignore exists
|
|
16
|
-
*/
|
|
17
|
-
export declare function isEnvIgnoredByGit(options?: GitignoreCheckOptions): boolean | null;
|
|
18
|
-
/**
|
|
19
|
-
* Logs a friendly warning if .env is not ignored by Git.
|
|
20
|
-
* - Does not hard fail: non-blocking DX.
|
|
21
|
-
* - Skips if not in a git repo or if .env does not exist.
|
|
22
|
-
*/
|
|
23
|
-
export declare function warnIfEnvNotIgnored(options?: GitignoreCheckOptions): void;
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import chalk from 'chalk';
|
|
4
|
-
/** Are we in a git repo? (checks for .git directory in cwd) */
|
|
5
|
-
export function isGitRepo(cwd = process.cwd()) {
|
|
6
|
-
return fs.existsSync(path.resolve(cwd, '.git'));
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Returns:
|
|
10
|
-
* - true → .env-matching patterns are found in .gitignore
|
|
11
|
-
* - false → .env-matching patterns are NOT found (or a negation exists)
|
|
12
|
-
* - null → no .gitignore exists
|
|
13
|
-
*/
|
|
14
|
-
export function isEnvIgnoredByGit(options = {}) {
|
|
15
|
-
const { cwd = process.cwd(), envFile = '.env' } = options;
|
|
16
|
-
const gitignorePath = path.resolve(cwd, '.gitignore');
|
|
17
|
-
if (!fs.existsSync(gitignorePath))
|
|
18
|
-
return null;
|
|
19
|
-
const raw = fs.readFileSync(gitignorePath, 'utf8');
|
|
20
|
-
const lines = raw
|
|
21
|
-
.split(/\r?\n/)
|
|
22
|
-
.map((l) => l.trim())
|
|
23
|
-
.filter((l) => l && !l.startsWith('#'));
|
|
24
|
-
// If there is a negation (!pattern) that matches our candidates, we consider it as "not ignored"
|
|
25
|
-
if (lines.some((l) => l.startsWith('!') && matchesCandidate(l.slice(1), envFile))) {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
const candidates = getCandidatePatterns(envFile);
|
|
29
|
-
return lines.some((line) => candidates.has(line));
|
|
30
|
-
}
|
|
31
|
-
/** Our simple candidate patterns that typically cover env files in the root and subfolders */
|
|
32
|
-
function getCandidatePatterns(envFile = '.env') {
|
|
33
|
-
const base = envFile; // ".env"
|
|
34
|
-
const star = `${base}*`; // ".env*"
|
|
35
|
-
const dotStar = `${base}.*`; // ".env.*"
|
|
36
|
-
return new Set([
|
|
37
|
-
base,
|
|
38
|
-
`/${base}`,
|
|
39
|
-
`**/${base}`,
|
|
40
|
-
star,
|
|
41
|
-
`/${star}`,
|
|
42
|
-
`**/${star}`,
|
|
43
|
-
dotStar,
|
|
44
|
-
`/${dotStar}`,
|
|
45
|
-
`**/${dotStar}`,
|
|
46
|
-
]);
|
|
47
|
-
}
|
|
48
|
-
// Matches only against our own candidate patterns (intentionally simple)
|
|
49
|
-
function matchesCandidate(pattern, envFile) {
|
|
50
|
-
return getCandidatePatterns(envFile).has(pattern);
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Logs a friendly warning if .env is not ignored by Git.
|
|
54
|
-
* - Does not hard fail: non-blocking DX.
|
|
55
|
-
* - Skips if not in a git repo or if .env does not exist.
|
|
56
|
-
*/
|
|
57
|
-
export function warnIfEnvNotIgnored(options = {}) {
|
|
58
|
-
const { cwd = process.cwd(), envFile = '.env', log = console.log } = options;
|
|
59
|
-
const envPath = path.resolve(cwd, envFile);
|
|
60
|
-
if (!fs.existsSync(envPath))
|
|
61
|
-
return; // No .env file → nothing to warn about
|
|
62
|
-
if (!isGitRepo(cwd))
|
|
63
|
-
return; // Not a git repo → skip
|
|
64
|
-
const gitignorePath = path.resolve(cwd, '.gitignore');
|
|
65
|
-
if (!fs.existsSync(gitignorePath)) {
|
|
66
|
-
log(chalk.yellow(`⚠️ No .gitignore found – your ${envFile} may be committed.\n Add:\n ${envFile}\n ${envFile}.*\n`));
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
const ignored = isEnvIgnoredByGit({ cwd, envFile });
|
|
70
|
-
if (ignored === false || ignored === null) {
|
|
71
|
-
log(chalk.yellow(`⚠️ ${envFile} is not ignored by Git (.gitignore).\n Consider adding:\n ${envFile}\n ${envFile}.*\n`));
|
|
72
|
-
}
|
|
73
|
-
}
|
package/dist/lib/diffEnv.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export type DiffResult = {
|
|
2
|
-
missing: string[];
|
|
3
|
-
extra: string[];
|
|
4
|
-
valueMismatches: {
|
|
5
|
-
key: string;
|
|
6
|
-
expected: string;
|
|
7
|
-
actual: string;
|
|
8
|
-
}[];
|
|
9
|
-
};
|
|
10
|
-
/**
|
|
11
|
-
* Compares two .env files and returns their differences.
|
|
12
|
-
*
|
|
13
|
-
* @param current - An object representing the current `.env` file (key-value pairs).
|
|
14
|
-
* @param example - An object representing the `.env.example` file (key-value pairs).
|
|
15
|
-
* @param checkValues - If true, compare values when the example has a non-empty value.
|
|
16
|
-
* @returns A `DiffResult` object containing missing, extra, and mismatched keys.
|
|
17
|
-
*/
|
|
18
|
-
export declare function diffEnv(current: Record<string, string>, example: Record<string, string>, checkValues?: boolean): DiffResult;
|
package/dist/lib/diffEnv.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compares two .env files and returns their differences.
|
|
3
|
-
*
|
|
4
|
-
* @param current - An object representing the current `.env` file (key-value pairs).
|
|
5
|
-
* @param example - An object representing the `.env.example` file (key-value pairs).
|
|
6
|
-
* @param checkValues - If true, compare values when the example has a non-empty value.
|
|
7
|
-
* @returns A `DiffResult` object containing missing, extra, and mismatched keys.
|
|
8
|
-
*/
|
|
9
|
-
export function diffEnv(current, example, checkValues = false) {
|
|
10
|
-
const currentKeys = Object.keys(current);
|
|
11
|
-
const exampleKeys = Object.keys(example);
|
|
12
|
-
const missing = exampleKeys.filter((key) => !currentKeys.includes(key));
|
|
13
|
-
const extra = currentKeys.filter((key) => !exampleKeys.includes(key));
|
|
14
|
-
let valueMismatches = [];
|
|
15
|
-
if (checkValues) {
|
|
16
|
-
valueMismatches = exampleKeys
|
|
17
|
-
.filter((key) => {
|
|
18
|
-
return (currentKeys.includes(key) &&
|
|
19
|
-
example[key].trim() !== '' &&
|
|
20
|
-
current[key] !== example[key]);
|
|
21
|
-
})
|
|
22
|
-
.map((key) => ({
|
|
23
|
-
key,
|
|
24
|
-
expected: example[key],
|
|
25
|
-
actual: current[key],
|
|
26
|
-
}));
|
|
27
|
-
}
|
|
28
|
-
return { missing, extra, valueMismatches };
|
|
29
|
-
}
|
package/dist/lib/parseEnv.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Parses a `.env` file and returns an object with key-value pairs.
|
|
3
|
-
*
|
|
4
|
-
* @param path - The file path to the `.env` file.
|
|
5
|
-
* @returns A record object representing parsed environment variables.
|
|
6
|
-
*
|
|
7
|
-
* Lines that are empty or start with `#` (comments) are ignored.
|
|
8
|
-
* Multi-line or quoted values are not supported.
|
|
9
|
-
*/
|
|
10
|
-
export declare function parseEnvFile(path: string): Record<string, string>;
|
package/dist/lib/parseEnv.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
/**
|
|
3
|
-
* Parses a `.env` file and returns an object with key-value pairs.
|
|
4
|
-
*
|
|
5
|
-
* @param path - The file path to the `.env` file.
|
|
6
|
-
* @returns A record object representing parsed environment variables.
|
|
7
|
-
*
|
|
8
|
-
* Lines that are empty or start with `#` (comments) are ignored.
|
|
9
|
-
* Multi-line or quoted values are not supported.
|
|
10
|
-
*/
|
|
11
|
-
export function parseEnvFile(path) {
|
|
12
|
-
const content = fs.readFileSync(path, 'utf-8');
|
|
13
|
-
const lines = content.split('\n');
|
|
14
|
-
const result = {};
|
|
15
|
-
for (const line of lines) {
|
|
16
|
-
const trimmed = line.trim();
|
|
17
|
-
if (!trimmed || trimmed.startsWith('#'))
|
|
18
|
-
continue;
|
|
19
|
-
const [key, ...rest] = trimmed.split('=');
|
|
20
|
-
if (!key)
|
|
21
|
-
continue;
|
|
22
|
-
result[key.trim()] = rest.join('=').trim();
|
|
23
|
-
}
|
|
24
|
-
return result;
|
|
25
|
-
}
|
package/dist/parseEnv.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function parseEnvFile(path: string): Record<string, string>;
|
package/dist/parseEnv.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
export function parseEnvFile(path) {
|
|
3
|
-
const content = fs.readFileSync(path, 'utf-8');
|
|
4
|
-
const lines = content.split('\n');
|
|
5
|
-
const result = {};
|
|
6
|
-
for (const line of lines) {
|
|
7
|
-
const trimmed = line.trim();
|
|
8
|
-
if (!trimmed || trimmed.startsWith('#'))
|
|
9
|
-
continue;
|
|
10
|
-
const [key, ...rest] = trimmed.split('=');
|
|
11
|
-
if (!key)
|
|
12
|
-
continue;
|
|
13
|
-
result[key.trim()] = rest.join('=').trim();
|
|
14
|
-
}
|
|
15
|
-
return result;
|
|
16
|
-
}
|