dotenv-diff 1.6.3 → 1.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -43,6 +43,18 @@ When using the `--check-values` option, the tool will also compare the actual va
43
43
 
44
44
  `dotenv-diff` warns when a `.env*` file contains the same key multiple times. The last occurrence wins. Suppress these warnings with `--allow-duplicates`.
45
45
 
46
+ ## Ignore specific keys
47
+
48
+ Exclude certain keys from the comparison using `--ignore` for exact names or `--ignore-regex` for patterns:
49
+
50
+ ```bash
51
+ dotenv-diff --ignore API_KEY,SESSION_ID
52
+ dotenv-diff --ignore-regex '^SECRET_'
53
+ dotenv-diff --ignore API_KEY --ignore-regex '^SECRET_'
54
+ ```
55
+
56
+ Ignored keys are removed from all warnings and do not affect the exit code.
57
+
46
58
  ## Output format in JSON
47
59
 
48
60
  You can output the results in JSON format using the `--json` option:
@@ -9,5 +9,7 @@ export function createProgram() {
9
9
  .option('--env <file>', 'Path to a specific .env file')
10
10
  .option('--example <file>', 'Path to a specific .env.example file')
11
11
  .option('--allow-duplicates', 'Do not warn about duplicate keys in .env* files')
12
+ .option('--ignore <keys>', 'Comma-separated list of keys to ignore')
13
+ .option('--ignore-regex <pattern>', 'Regex pattern to ignore matching keys')
12
14
  .option('--json', 'Output results in JSON format');
13
15
  }
@@ -24,11 +24,19 @@ export async function run(program) {
24
24
  process.exit(1);
25
25
  }
26
26
  const report = [];
27
- const { exitWithError } = await compareMany([{ envName: path.basename(opts.envFlag), envPath: opts.envFlag, examplePath: opts.exampleFlag }], {
27
+ const { exitWithError } = await compareMany([
28
+ {
29
+ envName: path.basename(opts.envFlag),
30
+ envPath: opts.envFlag,
31
+ examplePath: opts.exampleFlag,
32
+ },
33
+ ], {
28
34
  checkValues: opts.checkValues,
29
35
  cwd: opts.cwd,
30
36
  allowDuplicates: opts.allowDuplicates,
31
37
  json: opts.json,
38
+ ignore: opts.ignore,
39
+ ignoreRegex: opts.ignoreRegex,
32
40
  collect: (e) => report.push(e),
33
41
  });
34
42
  if (opts.json) {
@@ -65,6 +73,8 @@ export async function run(program) {
65
73
  cwd: opts.cwd,
66
74
  allowDuplicates: opts.allowDuplicates,
67
75
  json: opts.json,
76
+ ignore: opts.ignore,
77
+ ignoreRegex: opts.ignoreRegex,
68
78
  collect: (e) => report.push(e),
69
79
  });
70
80
  if (opts.json) {
@@ -33,6 +33,8 @@ export declare function compareMany(pairs: Array<{
33
33
  cwd: string;
34
34
  allowDuplicates?: boolean;
35
35
  json?: boolean;
36
+ ignore: string[];
37
+ ignoreRegex: RegExp[];
36
38
  collect?: (entry: CompareJsonEntry) => void;
37
39
  }): Promise<{
38
40
  exitWithError: boolean;
@@ -5,6 +5,7 @@ import { parseEnvFile } from '../lib/parseEnv.js';
5
5
  import { diffEnv } from '../lib/diffEnv.js';
6
6
  import { warnIfEnvNotIgnored } from '../services/git.js';
7
7
  import { findDuplicateKeys } from '../services/duplicates.js';
8
+ import { filterIgnoredKeys } from '../core/filterIgnoredKeys.js';
8
9
  export async function compareMany(pairs, opts) {
9
10
  let exitWithError = false;
10
11
  for (const { envName, envPath, examplePath } of pairs) {
@@ -34,8 +35,10 @@ export async function compareMany(pairs, opts) {
34
35
  });
35
36
  // Duplicate detection
36
37
  if (!opts.allowDuplicates) {
37
- const dupsEnv = findDuplicateKeys(envPath);
38
- const dupsEx = findDuplicateKeys(examplePath);
38
+ const dupsEnv = findDuplicateKeys(envPath).filter(({ key }) => !opts.ignore.includes(key) &&
39
+ !opts.ignoreRegex.some((rx) => rx.test(key)));
40
+ const dupsEx = findDuplicateKeys(examplePath).filter(({ key }) => !opts.ignore.includes(key) &&
41
+ !opts.ignoreRegex.some((rx) => rx.test(key)));
39
42
  if (dupsEnv.length || dupsEx.length) {
40
43
  entry.duplicates = {};
41
44
  }
@@ -55,8 +58,12 @@ export async function compareMany(pairs, opts) {
55
58
  }
56
59
  }
57
60
  // Diff + empty
58
- const current = parseEnvFile(envPath);
59
- const example = parseEnvFile(examplePath);
61
+ const currentFull = parseEnvFile(envPath);
62
+ const exampleFull = parseEnvFile(examplePath);
63
+ const currentKeys = filterIgnoredKeys(Object.keys(currentFull), opts.ignore, opts.ignoreRegex);
64
+ const exampleKeys = filterIgnoredKeys(Object.keys(exampleFull), opts.ignore, opts.ignoreRegex);
65
+ const current = Object.fromEntries(currentKeys.map((k) => [k, currentFull[k]]));
66
+ const example = Object.fromEntries(exampleKeys.map((k) => [k, exampleFull[k]]));
60
67
  const diff = diffEnv(current, example, opts.checkValues);
61
68
  const emptyKeys = Object.entries(current)
62
69
  .filter(([, v]) => (v ?? '').trim() === '')
@@ -6,6 +6,8 @@ export type Options = {
6
6
  json: boolean;
7
7
  envFlag: string | null;
8
8
  exampleFlag: string | null;
9
+ ignore: string[];
10
+ ignoreRegex: RegExp[];
9
11
  cwd: string;
10
12
  };
11
13
  type RawOptions = {
@@ -16,6 +18,8 @@ type RawOptions = {
16
18
  json?: boolean;
17
19
  env?: string;
18
20
  example?: string;
21
+ ignore?: string | string[];
22
+ ignoreRegex?: string | string[];
19
23
  };
20
24
  export declare function normalizeOptions(raw: RawOptions): Options;
21
25
  export {};
@@ -6,6 +6,24 @@ export function normalizeOptions(raw) {
6
6
  const isYesMode = Boolean(raw.yes);
7
7
  const allowDuplicates = Boolean(raw.allowDuplicates);
8
8
  const json = Boolean(raw.json);
9
+ const parseList = (val) => {
10
+ const arr = Array.isArray(val) ? val : val ? [val] : [];
11
+ return arr
12
+ .flatMap((s) => s.split(','))
13
+ .map((s) => s.trim())
14
+ .filter(Boolean);
15
+ };
16
+ const ignore = parseList(raw.ignore);
17
+ const ignoreRegex = [];
18
+ for (const pattern of parseList(raw.ignoreRegex)) {
19
+ try {
20
+ ignoreRegex.push(new RegExp(pattern));
21
+ }
22
+ catch {
23
+ console.error(chalk.red(`❌ Error: invalid --ignore-regex pattern: ${pattern}`));
24
+ process.exit(1);
25
+ }
26
+ }
9
27
  if (isCiMode && isYesMode) {
10
28
  console.log(chalk.yellow('⚠️ Both --ci and --yes provided; proceeding with --yes.'));
11
29
  }
@@ -20,6 +38,8 @@ export function normalizeOptions(raw) {
20
38
  json,
21
39
  envFlag,
22
40
  exampleFlag,
41
+ ignore,
42
+ ignoreRegex,
23
43
  cwd,
24
44
  };
25
45
  }
@@ -0,0 +1 @@
1
+ export declare function filterIgnoredKeys(keys: string[], ignore: string[], ignoreRegex: RegExp[]): string[];
@@ -0,0 +1,3 @@
1
+ export function filterIgnoredKeys(keys, ignore, ignoreRegex) {
2
+ return keys.filter((k) => !ignore.includes(k) && !ignoreRegex.some((rx) => rx.test(k)));
3
+ }
package/package.json CHANGED
@@ -1,25 +1,36 @@
1
1
  {
2
2
  "name": "dotenv-diff",
3
- "version": "1.6.3",
3
+ "version": "1.6.4",
4
4
  "type": "module",
5
- "description": "A small CLI and library to find differences between .env and .env.example files.",
5
+ "description": "A CLI tool to find differences between .env and .env.example / .env.* files.",
6
6
  "bin": {
7
7
  "dotenv-diff": "dist/bin/dotenv-diff.js"
8
8
  },
9
9
  "main": "dist/index.js",
10
10
  "types": "dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ },
16
+ "./package.json": "./package.json"
17
+ },
11
18
  "files": [
12
19
  "dist/",
13
20
  "README.md",
14
21
  "LICENSE"
15
22
  ],
23
+ "sideEffects": false,
16
24
  "scripts": {
17
25
  "build": "tsc",
18
26
  "dev": "vitest --watch",
19
- "test": "vitest",
27
+ "test": "vitest run",
28
+ "test:unit": "vitest run test/unit",
29
+ "test:e2e": "vitest run test/e2e",
20
30
  "lint": "eslint ./src --ext .ts",
21
31
  "format": "prettier --write \"src/**/*.ts\" \"src/*.ts\"",
22
- "start": "node dist/bin/dotenv-diff.js"
32
+ "start": "node dist/bin/dotenv-diff.js",
33
+ "prepublishOnly": "npm run lint && npm test && npm run build"
23
34
  },
24
35
  "author": "Chrilleweb",
25
36
  "license": "MIT",
@@ -36,8 +47,12 @@
36
47
  "type": "git",
37
48
  "url": "https://github.com/Chrilleweb/dotenv-diff.git"
38
49
  },
50
+ "homepage": "https://github.com/Chrilleweb/dotenv-diff#readme",
51
+ "bugs": {
52
+ "url": "https://github.com/Chrilleweb/dotenv-diff/issues"
53
+ },
39
54
  "engines": {
40
- "node": ">=14.0.0"
55
+ "node": ">=20.0.0"
41
56
  },
42
57
  "dependencies": {
43
58
  "chalk": "^5.4.1",