dotenv-diff 2.6.0 → 2.6.2
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 +19 -0
- package/README.md +9 -9
- package/dist/src/cli/run.d.ts.map +1 -1
- package/dist/src/cli/run.js.map +1 -1
- package/dist/src/commands/compare.d.ts.map +1 -1
- package/dist/src/commands/compare.js +5 -1
- package/dist/src/commands/compare.js.map +1 -1
- package/dist/src/commands/prompts/promptEnsureFiles.d.ts +9 -0
- package/dist/src/commands/prompts/promptEnsureFiles.d.ts.map +1 -1
- package/dist/src/commands/prompts/promptEnsureFiles.js +1 -1
- package/dist/src/commands/prompts/promptEnsureFiles.js.map +1 -1
- package/dist/src/commands/prompts/promptNoEnvScenario.js +1 -1
- package/dist/src/commands/prompts/promptNoEnvScenario.js.map +1 -1
- package/dist/src/commands/prompts/prompts.d.ts.map +1 -0
- package/dist/src/commands/prompts/prompts.js.map +1 -0
- package/dist/src/commands/scanUsage.js +4 -4
- package/dist/src/commands/scanUsage.js.map +1 -1
- package/dist/src/config/types.d.ts +94 -29
- package/dist/src/config/types.d.ts.map +1 -1
- package/dist/src/config/types.js +0 -2
- package/dist/src/config/types.js.map +1 -1
- package/dist/src/core/compare/parseAndFilterEnv.d.ts +4 -0
- package/dist/src/core/compare/parseAndFilterEnv.d.ts.map +1 -1
- package/dist/src/core/compare/parseAndFilterEnv.js +2 -2
- package/dist/src/core/compare/parseAndFilterEnv.js.map +1 -1
- package/dist/src/core/compare/updateTotals.d.ts +5 -0
- package/dist/src/core/compare/updateTotals.d.ts.map +1 -1
- package/dist/src/core/compare/updateTotals.js.map +1 -1
- package/dist/src/core/fixEnv.d.ts +5 -8
- package/dist/src/core/fixEnv.d.ts.map +1 -1
- package/dist/src/core/fixEnv.js +1 -3
- package/dist/src/core/fixEnv.js.map +1 -1
- package/dist/src/core/frameworks/frameworkDetector.d.ts +5 -0
- package/dist/src/core/frameworks/frameworkDetector.d.ts.map +1 -1
- package/dist/src/core/frameworks/frameworkDetector.js.map +1 -1
- package/dist/src/core/helpers/normalizePath.d.ts.map +1 -1
- package/dist/src/core/security/exampleSecretDetector.d.ts +1 -6
- package/dist/src/core/security/exampleSecretDetector.d.ts.map +1 -1
- package/dist/src/core/security/exampleSecretDetector.js.map +1 -1
- package/dist/src/core/security/secretDetectors.d.ts +3 -0
- package/dist/src/core/security/secretDetectors.d.ts.map +1 -1
- package/dist/src/core/security/secretDetectors.js.map +1 -1
- package/dist/src/services/envDiscovery.d.ts +3 -0
- package/dist/src/services/envDiscovery.d.ts.map +1 -1
- package/dist/src/services/envDiscovery.js.map +1 -1
- package/dist/src/services/printScanResult.d.ts +1 -15
- package/dist/src/services/printScanResult.d.ts.map +1 -1
- package/dist/src/services/printScanResult.js +23 -18
- package/dist/src/services/printScanResult.js.map +1 -1
- package/dist/src/services/processComparisonFile.d.ts +5 -19
- package/dist/src/services/processComparisonFile.d.ts.map +1 -1
- package/dist/src/services/processComparisonFile.js +16 -19
- package/dist/src/services/processComparisonFile.js.map +1 -1
- package/dist/src/ui/compare/printPrompt.d.ts +11 -1
- package/dist/src/ui/compare/printPrompt.d.ts.map +1 -1
- package/dist/src/ui/compare/printPrompt.js +11 -1
- package/dist/src/ui/compare/printPrompt.js.map +1 -1
- package/dist/src/ui/compare/printStats.d.ts +8 -0
- package/dist/src/ui/compare/printStats.d.ts.map +1 -1
- package/dist/src/ui/compare/printStats.js.map +1 -1
- package/dist/src/ui/scan/printConsolelogWarning.d.ts +1 -2
- package/dist/src/ui/scan/printConsolelogWarning.d.ts.map +1 -1
- package/dist/src/ui/scan/printConsolelogWarning.js +1 -4
- package/dist/src/ui/scan/printConsolelogWarning.js.map +1 -1
- package/dist/src/ui/scan/printExampleWarnings.d.ts +2 -3
- package/dist/src/ui/scan/printExampleWarnings.d.ts.map +1 -1
- package/dist/src/ui/scan/printExampleWarnings.js +1 -6
- package/dist/src/ui/scan/printExampleWarnings.js.map +1 -1
- package/dist/src/ui/scan/printFrameworkWarnings.d.ts +1 -2
- package/dist/src/ui/scan/printFrameworkWarnings.d.ts.map +1 -1
- package/dist/src/ui/scan/printFrameworkWarnings.js +4 -6
- package/dist/src/ui/scan/printFrameworkWarnings.js.map +1 -1
- package/dist/src/ui/scan/printHealthScore.d.ts.map +1 -1
- package/dist/src/ui/scan/printHealthScore.js +8 -4
- package/dist/src/ui/scan/printHealthScore.js.map +1 -1
- package/dist/src/ui/scan/printInconsistentNamingWarning.d.ts +1 -2
- package/dist/src/ui/scan/printInconsistentNamingWarning.d.ts.map +1 -1
- package/dist/src/ui/scan/printInconsistentNamingWarning.js +2 -3
- package/dist/src/ui/scan/printInconsistentNamingWarning.js.map +1 -1
- package/dist/src/ui/scan/printMissing.d.ts +1 -3
- package/dist/src/ui/scan/printMissing.d.ts.map +1 -1
- package/dist/src/ui/scan/printMissing.js +1 -5
- package/dist/src/ui/scan/printMissing.js.map +1 -1
- package/dist/src/ui/scan/printProgress.d.ts +7 -0
- package/dist/src/ui/scan/printProgress.d.ts.map +1 -1
- package/dist/src/ui/scan/printProgress.js +1 -0
- package/dist/src/ui/scan/printProgress.js.map +1 -1
- package/dist/src/ui/scan/printSecrets.d.ts +1 -2
- package/dist/src/ui/scan/printSecrets.d.ts.map +1 -1
- package/dist/src/ui/scan/printSecrets.js +1 -4
- package/dist/src/ui/scan/printSecrets.js.map +1 -1
- package/dist/src/ui/scan/printStats.d.ts +2 -9
- package/dist/src/ui/scan/printStats.d.ts.map +1 -1
- package/dist/src/ui/scan/printStats.js +2 -2
- package/dist/src/ui/scan/printStats.js.map +1 -1
- package/dist/src/ui/scan/printUnused.d.ts +1 -2
- package/dist/src/ui/scan/printUnused.d.ts.map +1 -1
- package/dist/src/ui/scan/printUnused.js +1 -4
- package/dist/src/ui/scan/printUnused.js.map +1 -1
- package/dist/src/ui/scan/printUppercaseWarning.d.ts +1 -2
- package/dist/src/ui/scan/printUppercaseWarning.d.ts.map +1 -1
- package/dist/src/ui/scan/printUppercaseWarning.js +2 -3
- package/dist/src/ui/scan/printUppercaseWarning.js.map +1 -1
- package/dist/src/ui/scan/scanJsonOutput.d.ts +8 -41
- package/dist/src/ui/scan/scanJsonOutput.d.ts.map +1 -1
- package/dist/src/ui/scan/scanJsonOutput.js +10 -0
- package/dist/src/ui/scan/scanJsonOutput.js.map +1 -1
- package/dist/src/ui/shared/printAutoFix.d.ts +2 -8
- package/dist/src/ui/shared/printAutoFix.d.ts.map +1 -1
- package/dist/src/ui/shared/printAutoFix.js +3 -5
- package/dist/src/ui/shared/printAutoFix.js.map +1 -1
- package/dist/src/ui/shared/printGitignore.d.ts +6 -0
- package/dist/src/ui/shared/printGitignore.d.ts.map +1 -1
- package/dist/src/ui/shared/printGitignore.js.map +1 -1
- package/dist/src/ui/shared/printStrictModeError.d.ts +3 -0
- package/dist/src/ui/shared/printStrictModeError.d.ts.map +1 -1
- package/dist/src/ui/shared/printStrictModeError.js.map +1 -1
- package/docs/assets/demo1.gif +0 -0
- package/docs/assets/success1.png +0 -0
- package/docs/configuration_and_flags.md +726 -0
- package/docs/expiration_warnings.md +111 -0
- package/docs/frameworks/index.md +24 -0
- package/docs/frameworks/nextjs_warnings.md +56 -0
- package/docs/frameworks/sveltekit_warnings.md +130 -0
- package/docs/git_hooks_ci.md +51 -0
- package/docs/ignore_comments.md +82 -0
- package/docs/index.md +43 -0
- package/docs/monorepo_support.md +63 -0
- package/package.json +10 -9
- package/dist/src/ui/prompts.d.ts.map +0 -1
- package/dist/src/ui/prompts.js.map +0 -1
- /package/dist/src/{ui → commands/prompts}/prompts.d.ts +0 -0
- /package/dist/src/{ui → commands/prompts}/prompts.js +0 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Expiration Warnings
|
|
2
|
+
|
|
3
|
+
Expiration warnings help you track time-limited environment variables such as temporary API keys, tokens, and credentials.
|
|
4
|
+
|
|
5
|
+
By annotating a key with an expiration date, `dotenv-diff` can:
|
|
6
|
+
|
|
7
|
+
- warn when a key is expired
|
|
8
|
+
- warn when a key is close to expiration
|
|
9
|
+
- fail the process in `--strict` mode
|
|
10
|
+
|
|
11
|
+
## Syntax
|
|
12
|
+
|
|
13
|
+
Add an expiration annotation directly above the variable:
|
|
14
|
+
|
|
15
|
+
```env
|
|
16
|
+
# @expire 2026-12-31
|
|
17
|
+
TEMP_API_TOKEN=abc123
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Supported annotation styles:
|
|
21
|
+
|
|
22
|
+
```env
|
|
23
|
+
# @expire 2026-12-31
|
|
24
|
+
TOKEN_A=...
|
|
25
|
+
|
|
26
|
+
// @expire 2026-12-31
|
|
27
|
+
TOKEN_B=...
|
|
28
|
+
|
|
29
|
+
@expire 2026-12-31
|
|
30
|
+
TOKEN_C=...
|
|
31
|
+
|
|
32
|
+
# expire 2026-12-31
|
|
33
|
+
TOKEN_D=...
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Rules
|
|
37
|
+
|
|
38
|
+
- Date format must be `YYYY-MM-DD`
|
|
39
|
+
- `@` is optional (`expire 2026-12-31` also works)
|
|
40
|
+
- The annotation applies to the **next env key only**
|
|
41
|
+
- If no key follows, no warning is created
|
|
42
|
+
|
|
43
|
+
## Warning output
|
|
44
|
+
|
|
45
|
+
When expiration annotations are found, CLI output includes an `Expiration warnings` section.
|
|
46
|
+
|
|
47
|
+
Severity is shown from `daysLeft`:
|
|
48
|
+
|
|
49
|
+
- `< 0`: expired (`EXPIRED ... days ago`)
|
|
50
|
+
- `0`: `EXPIRES TODAY`
|
|
51
|
+
- `1`: `expires tomorrow`
|
|
52
|
+
- `2-3`: urgent warning
|
|
53
|
+
- `4-7`: warning
|
|
54
|
+
- `> 7`: still shown as informational warning
|
|
55
|
+
|
|
56
|
+
## Strict mode
|
|
57
|
+
|
|
58
|
+
In strict mode, expiration warnings are treated as blocking warnings and return exit code `1`.
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
dotenv-diff --strict
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
If expiration warnings exist, strict mode includes them in the strict error summary.
|
|
65
|
+
|
|
66
|
+
## Enable / disable
|
|
67
|
+
|
|
68
|
+
Expiration warnings are enabled by default.
|
|
69
|
+
|
|
70
|
+
Disable via CLI:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
dotenv-diff --no-expire-warnings
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Or disable in `dotenv-diff.config.json`:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"expireWarnings": false
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
You can also force-enable explicitly:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
dotenv-diff --expire-warnings
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## JSON output
|
|
91
|
+
|
|
92
|
+
With `--json`, expiration warnings are returned in the `expireWarnings` field:
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"expireWarnings": [
|
|
97
|
+
{
|
|
98
|
+
"key": "TEMP_API_TOKEN",
|
|
99
|
+
"date": "2026-12-31",
|
|
100
|
+
"daysLeft": 30
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Best practices
|
|
107
|
+
|
|
108
|
+
- Use `YYYY-MM-DD` consistently
|
|
109
|
+
- Keep expiration comments immediately above the key they belong to
|
|
110
|
+
- Add a short comment describing why the key expires
|
|
111
|
+
- Combine with `--strict` in CI/CD to catch expired credentials early
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Framework-Specific Warnings
|
|
2
|
+
|
|
3
|
+
This section explains which framework-specific environment variable are currently supported and how it works.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Supported frameworks
|
|
8
|
+
|
|
9
|
+
- [SvelteKit warnings](./sveltekit_warnings.md)
|
|
10
|
+
- [Next.js warnings](./nextjs_warnings.md)
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Framework detection
|
|
15
|
+
|
|
16
|
+
dotenv-diff detects framework rules automatically from `package.json` in your current working directory.
|
|
17
|
+
|
|
18
|
+
E.g.
|
|
19
|
+
|
|
20
|
+
- If `@sveltejs/kit` is present, SvelteKit rules are enabled.
|
|
21
|
+
- If `next` is present, Next.js rules are enabled.
|
|
22
|
+
- If neither is detected, framework-specific warnings are skipped.
|
|
23
|
+
|
|
24
|
+
---
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Next.js warnings
|
|
2
|
+
|
|
3
|
+
`dotenv-diff` includes Next.js-specific rules to catch unsafe or invalid environment variable usage.
|
|
4
|
+
|
|
5
|
+
This page reflects the currently implemented rule behavior.
|
|
6
|
+
|
|
7
|
+
## 1 Client code must use `NEXT_PUBLIC_` variables only
|
|
8
|
+
|
|
9
|
+
When a file is treated as client code (`"use client"` or Pages Router client files), non-`NEXT_PUBLIC_` variables trigger a warning.
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
"use client";
|
|
13
|
+
console.log(process.env.SECRET_TOKEN);
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Warning:
|
|
17
|
+
|
|
18
|
+
`Server-only variable accessed from client code`
|
|
19
|
+
|
|
20
|
+
## 2 `import.meta.env` is not supported in Next.js
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
console.log(import.meta.env.PRIVATE_KEY);
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Warning:
|
|
27
|
+
|
|
28
|
+
`Next.js uses process.env, not import.meta.env (Vite syntax)`
|
|
29
|
+
|
|
30
|
+
## 3 Sensitive-looking `NEXT_PUBLIC_` names trigger exposure warnings
|
|
31
|
+
|
|
32
|
+
If a `NEXT_PUBLIC_` variable contains `SECRET`, `PRIVATE`, or `PASSWORD`, a warning is produced.
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
console.log(process.env.NEXT_PUBLIC_SECRET_PASSWORD);
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Warning:
|
|
39
|
+
|
|
40
|
+
`Potential sensitive environment variable exposed to the browser`
|
|
41
|
+
|
|
42
|
+
## What is allowed
|
|
43
|
+
|
|
44
|
+
Server files (for example API routes and other server-only code) can use private environment variables without framework warnings.
|
|
45
|
+
|
|
46
|
+
## Summary of rules
|
|
47
|
+
|
|
48
|
+
- Client code → only `NEXT_PUBLIC_*`
|
|
49
|
+
- `import.meta.env` → not valid in Next.js
|
|
50
|
+
- Sensitive names in `NEXT_PUBLIC_*` → warning
|
|
51
|
+
|
|
52
|
+
## Best practices
|
|
53
|
+
|
|
54
|
+
- Use `NEXT_PUBLIC_*` only for browser-safe values
|
|
55
|
+
- Keep secrets in server-only code paths
|
|
56
|
+
- Do not use `import.meta.env` in Next.js projects
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# SvelteKit warnings
|
|
2
|
+
|
|
3
|
+
`dotenv-diff` includes SvelteKit-specific rules for invalid or unsafe environment variable usage.
|
|
4
|
+
|
|
5
|
+
This page documents the exact warning behavior currently implemented.
|
|
6
|
+
|
|
7
|
+
## 1 `import.meta.env` must use `VITE_` prefix
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import.meta.env.PUBLIC_URL
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Warning:
|
|
14
|
+
|
|
15
|
+
`Variables accessed through import.meta.env must start with "VITE_"`
|
|
16
|
+
|
|
17
|
+
Correct usage:
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import.meta.env.VITE_PUBLIC_URL
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 2 `process.env` should only be used in server files
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
process.env.VITE_SECRET
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Warning:
|
|
30
|
+
|
|
31
|
+
`process.env should only be used in server files`
|
|
32
|
+
|
|
33
|
+
## 3 `$env/dynamic/private` cannot be used in client-side code
|
|
34
|
+
|
|
35
|
+
```svelte
|
|
36
|
+
<script lang="ts">
|
|
37
|
+
import { env } from '$env/dynamic/private';
|
|
38
|
+
console.log(env.SECRET_KEY);
|
|
39
|
+
</script>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Warning:
|
|
43
|
+
|
|
44
|
+
`$env/dynamic/private cannot be used in client-side code`
|
|
45
|
+
|
|
46
|
+
## 4 `$env/dynamic/private` variables must not start with `PUBLIC_`
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { env } from '$env/dynamic/private';
|
|
50
|
+
console.log(env.PUBLIC_API_URL);
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Warning:
|
|
54
|
+
|
|
55
|
+
`$env/dynamic/private variables must not start with "PUBLIC_"`
|
|
56
|
+
|
|
57
|
+
## 5 `$env/dynamic/public` variables must start with `PUBLIC_`
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
import { env } from '$env/dynamic/public';
|
|
61
|
+
console.log(env.API_URL);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Warning:
|
|
65
|
+
|
|
66
|
+
`$env/dynamic/public variables must start with "PUBLIC_"`
|
|
67
|
+
|
|
68
|
+
## 6 `$env/static/private` variables must not start with `PUBLIC_`
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
import { PUBLIC_KEY } from '$env/static/private';
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Warning:
|
|
75
|
+
|
|
76
|
+
`$env/static/private variables must not start with "PUBLIC_"`
|
|
77
|
+
|
|
78
|
+
## 7 `$env/static/private` cannot be used in client-side code
|
|
79
|
+
|
|
80
|
+
```svelte
|
|
81
|
+
<script lang="ts">
|
|
82
|
+
import { SECRET_KEY } from '$env/static/private';
|
|
83
|
+
</script>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Warning:
|
|
87
|
+
|
|
88
|
+
`$env/static/private variables cannot be used in client-side code`
|
|
89
|
+
|
|
90
|
+
## 8 `$env/static/public` variables must start with `PUBLIC_`
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
import { API_URL } from '$env/static/public';
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Warning:
|
|
97
|
+
|
|
98
|
+
`$env/static/public variables must start with "PUBLIC_"`
|
|
99
|
+
|
|
100
|
+
## 9 Sensitive-looking `PUBLIC_` / `VITE_` names trigger exposure warnings
|
|
101
|
+
|
|
102
|
+
If a client-exposed name contains `SECRET`, `PRIVATE`, or `PASSWORD`, a warning is produced.
|
|
103
|
+
|
|
104
|
+
```svelte
|
|
105
|
+
<script lang="ts">
|
|
106
|
+
import { env } from '$env/dynamic/public';
|
|
107
|
+
console.log(env.PUBLIC_SECRET_PASSWORD);
|
|
108
|
+
</script>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Warning:
|
|
112
|
+
|
|
113
|
+
`Potential sensitive environment variable exposed to the browser`
|
|
114
|
+
|
|
115
|
+
## Summary of rules
|
|
116
|
+
|
|
117
|
+
- `import.meta.env` → must use `VITE_*`
|
|
118
|
+
- `process.env` → server files only
|
|
119
|
+
- `$env/dynamic/private` → server-only, never `PUBLIC_*`
|
|
120
|
+
- `$env/dynamic/public` → must use `PUBLIC_*`
|
|
121
|
+
- `$env/static/private` → server-only, never `PUBLIC_*`
|
|
122
|
+
- `$env/static/public` → must use `PUBLIC_*`
|
|
123
|
+
- Sensitive client-exposed names (`PUBLIC_*`/`VITE_*`) → warning
|
|
124
|
+
|
|
125
|
+
## Best practices
|
|
126
|
+
|
|
127
|
+
- Use `PUBLIC_*` only for values intended for the browser
|
|
128
|
+
- Use `VITE_*` only via `import.meta.env`
|
|
129
|
+
- Keep private variables in server-only code
|
|
130
|
+
- Never expose secrets via `PUBLIC_*` or `VITE_*`
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Git Hooks and CI/CD
|
|
2
|
+
|
|
3
|
+
`dotenv-diff` is a CLI-first tool and does not manage git hooks or CI workflows by itself.
|
|
4
|
+
|
|
5
|
+
Instead, it is built to integrate cleanly with your existing tooling, such as Husky pre-commit hooks and GitHub Actions.
|
|
6
|
+
|
|
7
|
+
## Using dotenv-diff as a pre-commit hook
|
|
8
|
+
|
|
9
|
+
Running `dotenv-diff` before each commit helps catch missing, unused, and misused environment variables early.
|
|
10
|
+
|
|
11
|
+
A common setup is Husky + lint-staged, where `dotenv-diff` runs automatically on commit.
|
|
12
|
+
|
|
13
|
+
## Running dotenv-diff in GitHub Actions
|
|
14
|
+
|
|
15
|
+
Use `dotenv-diff` in CI to validate environment variable consistency on pull requests.
|
|
16
|
+
|
|
17
|
+
This is especially useful to keep `.env.example` in sync with real usage in code.
|
|
18
|
+
|
|
19
|
+
### Example GitHub Action
|
|
20
|
+
|
|
21
|
+
`.github/workflows/dotenv-diff.yml`
|
|
22
|
+
|
|
23
|
+
```yaml
|
|
24
|
+
name: dotenv-diff
|
|
25
|
+
|
|
26
|
+
on: [pull_request]
|
|
27
|
+
|
|
28
|
+
jobs:
|
|
29
|
+
env-validation:
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@v6
|
|
33
|
+
- uses: actions/setup-node@v6
|
|
34
|
+
- run: npm ci
|
|
35
|
+
- run: npx dotenv-diff --example .env.example --strict
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Why use this in hooks and CI
|
|
39
|
+
|
|
40
|
+
- Prevent commits that introduce undocumented environment variables
|
|
41
|
+
- Catch framework-specific env usage issues early
|
|
42
|
+
- Keep `.env.example` accurate across contributors and pull requests
|
|
43
|
+
|
|
44
|
+
## Best practices
|
|
45
|
+
|
|
46
|
+
- Use `--example` to validate against your reference file
|
|
47
|
+
- Use `--strict` in CI for fail-fast behavior on warnings
|
|
48
|
+
- Keep hook checks fast and predictable
|
|
49
|
+
- Pair with monorepo patterns (`--include-files`) where relevant
|
|
50
|
+
|
|
51
|
+
---
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Ignore Comments
|
|
2
|
+
|
|
3
|
+
dotenv-diff can skip certain lines or code sections from being flagged during scanning. This is helpful when you know a specific warning is safe in your source code.
|
|
4
|
+
|
|
5
|
+
Ignore comments work for both secret detection and environment variable usage scanning, allowing you to suppress false positives while maintaining security in the rest of your codebase.
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [Single Line Ignore](#single-line-ignore)
|
|
10
|
+
- [Block Ignore](#block-ignore)
|
|
11
|
+
- [When to Use](#when-to-use)
|
|
12
|
+
|
|
13
|
+
## Single Line Ignore
|
|
14
|
+
|
|
15
|
+
You can ignore a single line by adding an inline comment with `dotenv-diff-ignore`.
|
|
16
|
+
|
|
17
|
+
### JavaScript/TypeScript
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
const apiKey = 'safe_secret_123123123'; // dotenv-diff-ignore
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
This will suppress potential secret warnings for this specific line but still allow dotenv-diff to report other issues elsewhere in the file.
|
|
24
|
+
|
|
25
|
+
### JavaScript Block Comments
|
|
26
|
+
|
|
27
|
+
```javascript
|
|
28
|
+
const url = 'https://safe.example.com'; /* dotenv-diff-ignore */
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### HTML
|
|
32
|
+
|
|
33
|
+
```html
|
|
34
|
+
<a href="https://safe.example.com">Link</a> <!-- dotenv-diff-ignore -->
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### JSX/TSX Files
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
<p>Database: {process.env.DATABASE_URL}</p> {/* <!-- dotenv-diff-ignore --> */}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Block Ignore
|
|
44
|
+
|
|
45
|
+
You can ignore entire sections of code using start and end markers. All lines between the markers will be skipped during scanning.
|
|
46
|
+
|
|
47
|
+
### HTML/JSX/TSX
|
|
48
|
+
|
|
49
|
+
```html
|
|
50
|
+
<!-- dotenv-diff-ignore-start -->
|
|
51
|
+
<p>Hardcoded data, images or links that are safe to ignore</p>
|
|
52
|
+
<img src="https://cdn.safe-service.com/image.png" />
|
|
53
|
+
<a href="https://legacy-system.com/api">Legacy API</a>
|
|
54
|
+
<!-- dotenv-diff-ignore-end -->
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
// dotenv-diff-ignore-start
|
|
59
|
+
const legacyApiKey = 'legacy_secret_456456456';
|
|
60
|
+
const safeKey = process.env.SAFE_KEY;
|
|
61
|
+
// dotenv-diff-ignore-end
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
This is particularly useful for:
|
|
65
|
+
|
|
66
|
+
- Legacy code sections that can't be easily refactored
|
|
67
|
+
- Generated HTML or markup with safe hardcoded values
|
|
68
|
+
- Documentation or example code embedded in your source
|
|
69
|
+
- Third-party integrations with known safe URLs
|
|
70
|
+
|
|
71
|
+
Ignore markers are case-insensitive.
|
|
72
|
+
|
|
73
|
+
## Alternative Configuration
|
|
74
|
+
|
|
75
|
+
If you need to ignore entire files, folders, or key patterns globally, consider using configuration options instead:
|
|
76
|
+
|
|
77
|
+
- `--exclude-files <patterns>` - Skip entire files or directories from scanning
|
|
78
|
+
- `--ignore <keys>` - Ignore specific environment variable keys
|
|
79
|
+
- `--ignore-regex <patterns>` - Ignore keys matching regex patterns
|
|
80
|
+
- `--ignore-urls <list>` - Ignore specific URLs during secret detection
|
|
81
|
+
|
|
82
|
+
See the [Configuration and Flags](./configuration_and_flags.md) documentation for more details.
|
package/docs/index.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# dotenv-diff Documentation
|
|
2
|
+
|
|
3
|
+
Welcome to the official documentation for `dotenv-diff`.
|
|
4
|
+
|
|
5
|
+
This section gives you a quick overview of available guides and where to find framework-specific rules.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Quick Start
|
|
10
|
+
|
|
11
|
+
Install:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install dotenv-diff
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Run:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx dotenv-diff --example .env.example
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Table of Contents
|
|
26
|
+
|
|
27
|
+
| Document | Description |
|
|
28
|
+
|---|---|
|
|
29
|
+
| [Configuration and Flags](./configuration_and_flags.md) | Full CLI/config reference for options and behavior |
|
|
30
|
+
| [Expiration Warnings](./expiration_warnings.md) | How `@expire` annotations work and strict mode integration |
|
|
31
|
+
| [Ignore Comments](./ignore_comments.md) | Suppress false positives with inline/block ignore markers |
|
|
32
|
+
| [Monorepo Support](./monorepo_support.md) | Scan shared packages and cross-folder usage in monorepos |
|
|
33
|
+
| [Git Hooks and CI/CD](./git_hooks_ci.md) | Integrate dotenv-diff with Husky, lint-staged, and GitHub Actions |
|
|
34
|
+
| [Framework Warnings (Index)](./frameworks/index.md) | Framework detection and links to supported framework rules |
|
|
35
|
+
| [SvelteKit warnings](./frameworks/sveltekit_warnings.md) | SvelteKit-specific env validation rules |
|
|
36
|
+
| [Next.js warnings](./frameworks/nextjs_warnings.md) | Next.js-specific env validation rules |
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Quick links
|
|
41
|
+
|
|
42
|
+
- [Issue Tracker](https://github.com/Chrilleweb/dotenv-diff/issues)
|
|
43
|
+
- [CHANGELOG](../CHANGELOG.md)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Monorepo Support
|
|
2
|
+
|
|
3
|
+
In monorepos with multiple apps and shared packages, environment variables are often referenced across folder boundaries.
|
|
4
|
+
|
|
5
|
+
`dotenv-diff` supports this by scanning from your current app and letting you extend the scan scope to shared folders.
|
|
6
|
+
|
|
7
|
+
## Scanning shared packages
|
|
8
|
+
|
|
9
|
+
By default, `dotenv-diff` scans from the current working directory.
|
|
10
|
+
|
|
11
|
+
In a monorepo, use `--include-files` to add shared package paths:
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"scripts": {
|
|
16
|
+
"dotenv-diff": "dotenv-diff --example .env.example --include-files '../../packages/**/*'"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### What this does
|
|
22
|
+
|
|
23
|
+
- Scans the current application
|
|
24
|
+
- Compares your environment variables against `.env.example`
|
|
25
|
+
- Includes shared packages from the monorepo (for example `../../packages/**/*`)
|
|
26
|
+
- Detects env usage across app + shared code
|
|
27
|
+
|
|
28
|
+
## Using a configuration file
|
|
29
|
+
|
|
30
|
+
For larger monorepos, move file patterns and ignores to `dotenv-diff.config.json`:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"example": ".env.example",
|
|
35
|
+
"includeFiles": ["../../packages/**/*"],
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Then run:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
dotenv-diff
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## `--include-files` vs `--files`
|
|
46
|
+
|
|
47
|
+
- `--include-files` **extends** default scan patterns
|
|
48
|
+
- `--files` **replaces** default scan patterns completely
|
|
49
|
+
|
|
50
|
+
For monorepos, `--include-files` is usually the best default because you keep built-in scanning and only add shared paths.
|
|
51
|
+
|
|
52
|
+
## Why this matters in monorepos
|
|
53
|
+
|
|
54
|
+
- Undocumented variables are harder to detect when usage is spread across apps/packages
|
|
55
|
+
- Keeping `.env.example` accurate becomes harder as shared code grows
|
|
56
|
+
- One app-local scan can still include cross-folder usage and reduce drift
|
|
57
|
+
|
|
58
|
+
## Best practices
|
|
59
|
+
|
|
60
|
+
- Run `dotenv-diff` from the app folder that owns the `.env` / `.env.example` pair
|
|
61
|
+
- Add shared package globs with `--include-files` (or `includeFiles` in config)
|
|
62
|
+
- Keep `ignore` small and explicit
|
|
63
|
+
- Use `--strict` in CI to fail fast on warnings and missing variables
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dotenv-diff",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Detects environment variable issues, usage, and potential security risks.",
|
|
6
6
|
"bin": {
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
"files": [
|
|
19
19
|
"dist/",
|
|
20
|
+
"docs/",
|
|
20
21
|
"README.md",
|
|
21
22
|
"CHANGELOG.md",
|
|
22
23
|
"LICENSE"
|
|
@@ -68,19 +69,19 @@
|
|
|
68
69
|
},
|
|
69
70
|
"dependencies": {
|
|
70
71
|
"chalk": "5.6.2",
|
|
71
|
-
"commander": "^14.0.
|
|
72
|
+
"commander": "^14.0.3",
|
|
72
73
|
"prompts": "^2.4.2"
|
|
73
74
|
},
|
|
74
75
|
"devDependencies": {
|
|
75
|
-
"@release-it/conventional-changelog": "^10.0.
|
|
76
|
-
"@types/node": "^25.0
|
|
77
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
78
|
-
"@typescript-eslint/parser": "^8.
|
|
76
|
+
"@release-it/conventional-changelog": "^10.0.5",
|
|
77
|
+
"@types/node": "^25.3.0",
|
|
78
|
+
"@typescript-eslint/eslint-plugin": "^8.56.1",
|
|
79
|
+
"@typescript-eslint/parser": "^8.56.1",
|
|
79
80
|
"@vitest/coverage-v8": "4.0.18",
|
|
80
|
-
"eslint": "^9.39.
|
|
81
|
-
"prettier": "^3.8.
|
|
81
|
+
"eslint": "^9.39.3",
|
|
82
|
+
"prettier": "^3.8.1",
|
|
82
83
|
"release-it": "^19.2.4",
|
|
83
84
|
"typescript": "^5.9.3",
|
|
84
|
-
"vitest": "^4.0.
|
|
85
|
+
"vitest": "^4.0.18"
|
|
85
86
|
}
|
|
86
87
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/ui/prompts.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GACjE,OAAO,CAAC,OAAO,CAAC,CAclB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/ui/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAe,EACf,EAAE,QAAQ,EAAE,SAAS,EAA6C;IAElE,IAAI,SAAS;QAAE,OAAO,IAAI,CAAC;IAC3B,IAAI,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC3B,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC;QACxB,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,IAAI;QACV,OAAO;QACP,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE;YAC7B,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE;SAC9B;QACD,OAAO,EAAE,CAAC;KACX,CAAC,CAAC;IACH,OAAO,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACzB,CAAC"}
|
|
File without changes
|
|
File without changes
|