dotenv-diff 2.2.5 → 2.2.6
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/dist/src/cli/program.d.ts +4 -0
- package/dist/src/cli/program.d.ts.map +1 -1
- package/dist/src/cli/program.js +4 -0
- package/dist/src/cli/program.js.map +1 -1
- package/dist/src/commands/compare.d.ts.map +1 -1
- package/dist/src/commands/compare.js +2 -2
- package/dist/src/commands/compare.js.map +1 -1
- package/dist/src/commands/scanUsage.d.ts +1 -57
- package/dist/src/commands/scanUsage.d.ts.map +1 -1
- package/dist/src/commands/scanUsage.js +7 -216
- package/dist/src/commands/scanUsage.js.map +1 -1
- package/dist/src/config/types.d.ts +100 -0
- package/dist/src/config/types.d.ts.map +1 -1
- package/dist/src/config/types.js +1 -0
- package/dist/src/config/types.js.map +1 -1
- package/dist/src/core/compareScan.d.ts +9 -0
- package/dist/src/core/compareScan.d.ts.map +1 -0
- package/dist/src/core/compareScan.js +18 -0
- package/dist/src/core/compareScan.js.map +1 -0
- package/dist/src/core/determineComparisonFile.d.ts +11 -0
- package/dist/src/core/determineComparisonFile.d.ts.map +1 -0
- package/dist/src/core/determineComparisonFile.js +34 -0
- package/dist/src/core/determineComparisonFile.js.map +1 -0
- package/dist/src/core/diffEnv.d.ts +19 -0
- package/dist/src/core/diffEnv.d.ts.map +1 -0
- package/dist/src/core/diffEnv.js +31 -0
- package/dist/src/core/diffEnv.js.map +1 -0
- package/dist/src/core/helpers/resolveFromCwd.d.ts +8 -0
- package/dist/src/core/helpers/resolveFromCwd.d.ts.map +1 -0
- package/dist/src/core/helpers/resolveFromCwd.js +9 -0
- package/dist/src/core/helpers/resolveFromCwd.js.map +1 -0
- package/dist/src/core/parseEnv.d.ts +11 -0
- package/dist/src/core/parseEnv.d.ts.map +1 -0
- package/dist/src/core/parseEnv.js +26 -0
- package/dist/src/core/parseEnv.js.map +1 -0
- package/dist/src/core/patterns.d.ts +32 -0
- package/dist/src/core/patterns.d.ts.map +1 -0
- package/dist/src/core/patterns.js +69 -0
- package/dist/src/core/patterns.js.map +1 -0
- package/dist/src/core/scanFile.d.ts +10 -0
- package/dist/src/core/scanFile.d.ts.map +1 -0
- package/dist/src/core/scanFile.js +41 -0
- package/dist/src/core/scanFile.js.map +1 -0
- package/dist/src/core/scanJsonOutput.d.ts +11 -0
- package/dist/src/core/scanJsonOutput.d.ts.map +1 -0
- package/dist/src/core/scanJsonOutput.js +56 -0
- package/dist/src/core/scanJsonOutput.js.map +1 -0
- package/dist/src/core/secretDetectors.d.ts.map +1 -1
- package/dist/src/core/secretDetectors.js +21 -15
- package/dist/src/core/secretDetectors.js.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/services/codeBaseScanner.d.ts +1 -40
- package/dist/src/services/codeBaseScanner.d.ts.map +1 -1
- package/dist/src/services/codeBaseScanner.js +4 -315
- package/dist/src/services/codeBaseScanner.js.map +1 -1
- package/dist/src/services/fileWalker.d.ts +62 -0
- package/dist/src/services/fileWalker.d.ts.map +1 -0
- package/dist/src/services/fileWalker.js +238 -0
- package/dist/src/services/fileWalker.js.map +1 -0
- package/dist/src/services/scanOutputToConsole.d.ts +12 -0
- package/dist/src/services/scanOutputToConsole.d.ts.map +1 -0
- package/dist/src/services/scanOutputToConsole.js +134 -0
- package/dist/src/services/scanOutputToConsole.js.map +1 -0
- package/dist/types/scanUsage.d.ts +43 -0
- package/dist/types/scanUsage.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compares the scan result with the environment variables.
|
|
3
|
+
* @param scanResult - The result of the scan.
|
|
4
|
+
* @param envVariables - The environment variables to compare against.
|
|
5
|
+
* @returns The comparison result.
|
|
6
|
+
*/
|
|
7
|
+
export function compareWithEnvFiles(scanResult, envVariables) {
|
|
8
|
+
const usedVariables = new Set(scanResult.used.map((u) => u.variable));
|
|
9
|
+
const envKeys = new Set(Object.keys(envVariables));
|
|
10
|
+
const missing = [...usedVariables].filter((v) => !envKeys.has(v));
|
|
11
|
+
const unused = [...envKeys].filter((v) => !usedVariables.has(v));
|
|
12
|
+
return {
|
|
13
|
+
...scanResult,
|
|
14
|
+
missing,
|
|
15
|
+
unused,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=compareScan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compareScan.js","sourceRoot":"","sources":["../../../src/core/compareScan.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,UAAsB,EACtB,YAAgD;IAEhD,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IACtE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnD,MAAM,OAAO,GAAG,CAAC,GAAG,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAEjE,OAAO;QACL,GAAG,UAAU;QACb,OAAO;QACP,MAAM;KACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ScanUsageOptions } from '../config/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Determines which file to use for comparison based on provided options
|
|
4
|
+
* @param {ScanUsageOptions} opts - Scan configuration options
|
|
5
|
+
* @returns {Object|null} - The comparison file information or undefined if not found
|
|
6
|
+
*/
|
|
7
|
+
export declare function determineComparisonFile(opts: ScanUsageOptions): {
|
|
8
|
+
path: string;
|
|
9
|
+
name: string;
|
|
10
|
+
} | undefined;
|
|
11
|
+
//# sourceMappingURL=determineComparisonFile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"determineComparisonFile.d.ts","sourceRoot":"","sources":["../../../src/core/determineComparisonFile.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG3D;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,gBAAgB,GACrB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CA0B5C"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import {} from '../config/types.js';
|
|
4
|
+
import { resolveFromCwd } from './helpers/resolveFromCwd.js';
|
|
5
|
+
/**
|
|
6
|
+
* Determines which file to use for comparison based on provided options
|
|
7
|
+
* @param {ScanUsageOptions} opts - Scan configuration options
|
|
8
|
+
* @returns {Object|null} - The comparison file information or undefined if not found
|
|
9
|
+
*/
|
|
10
|
+
export function determineComparisonFile(opts) {
|
|
11
|
+
// Priority: explicit flags first, then auto-discovery
|
|
12
|
+
if (opts.examplePath) {
|
|
13
|
+
const p = resolveFromCwd(opts.cwd, opts.examplePath);
|
|
14
|
+
if (fs.existsSync(p)) {
|
|
15
|
+
return { path: p, name: path.basename(opts.examplePath) };
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if (opts.envPath) {
|
|
19
|
+
const p = resolveFromCwd(opts.cwd, opts.envPath);
|
|
20
|
+
if (fs.existsSync(p)) {
|
|
21
|
+
return { path: p, name: path.basename(opts.envPath) };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// Auto-discovery: look for common env files relative to cwd
|
|
25
|
+
const candidates = ['.env', '.env.example', '.env.local', '.env.production'];
|
|
26
|
+
for (const candidate of candidates) {
|
|
27
|
+
const fullPath = path.resolve(opts.cwd, candidate);
|
|
28
|
+
if (fs.existsSync(fullPath)) {
|
|
29
|
+
return { path: fullPath, name: candidate };
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=determineComparisonFile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"determineComparisonFile.js","sourceRoot":"","sources":["../../../src/core/determineComparisonFile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAyB,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CACrC,IAAsB;IAEtB,sDAAsD;IACtD,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,MAAM,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACrD,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YACrB,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACjD,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YACrB,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACxD,CAAC;IACH,CAAC;IAED,4DAA4D;IAC5D,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,CAAC,CAAC;IAC7E,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACnD,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
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;
|
|
19
|
+
//# sourceMappingURL=diffEnv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diffEnv.d.ts","sourceRoot":"","sources":["../../../src/core/diffEnv.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,eAAe,EAAE;QACf,GAAG,EAAE,MAAM,CAAC;QACZ,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;KAChB,EAAE,CAAC;CACL,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,OAAO,CACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,WAAW,UAAQ,GAClB,UAAU,CA2BZ"}
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
typeof example[key] === 'string' &&
|
|
20
|
+
example[key].trim() !== '' &&
|
|
21
|
+
current[key] !== example[key]);
|
|
22
|
+
})
|
|
23
|
+
.map((key) => ({
|
|
24
|
+
key,
|
|
25
|
+
expected: example[key] ?? '',
|
|
26
|
+
actual: current[key] ?? '',
|
|
27
|
+
}));
|
|
28
|
+
}
|
|
29
|
+
return { missing, extra, valueMismatches };
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=diffEnv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diffEnv.js","sourceRoot":"","sources":["../../../src/core/diffEnv.ts"],"names":[],"mappings":"AAUA;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CACrB,OAA+B,EAC/B,OAA+B,EAC/B,WAAW,GAAG,KAAK;IAEnB,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAEzC,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IACxE,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAEtE,IAAI,eAAe,GAAkC,EAAE,CAAC;IAExD,IAAI,WAAW,EAAE,CAAC;QAChB,eAAe,GAAG,WAAW;aAC1B,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;YACd,OAAO,CACL,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC;gBACzB,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,QAAQ;gBAChC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE;gBAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,GAAG,CAAC,CAC9B,CAAC;QACJ,CAAC,CAAC;aACD,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACb,GAAG;YACH,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE;YAC5B,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE;SAC3B,CAAC,CAAC,CAAC;IACR,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves a path relative to the current working directory.
|
|
3
|
+
* @param cwd - Current working directory
|
|
4
|
+
* @param p - Path to resolve
|
|
5
|
+
* @returns Resolved absolute path
|
|
6
|
+
*/
|
|
7
|
+
export declare const resolveFromCwd: (cwd: string, p: string) => string;
|
|
8
|
+
//# sourceMappingURL=resolveFromCwd.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveFromCwd.d.ts","sourceRoot":"","sources":["../../../../src/core/helpers/resolveFromCwd.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,EAAE,GAAG,MAAM,WACN,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves a path relative to the current working directory.
|
|
4
|
+
* @param cwd - Current working directory
|
|
5
|
+
* @param p - Path to resolve
|
|
6
|
+
* @returns Resolved absolute path
|
|
7
|
+
*/
|
|
8
|
+
export const resolveFromCwd = (cwd, p) => path.isAbsolute(p) ? p : path.resolve(cwd, p);
|
|
9
|
+
//# sourceMappingURL=resolveFromCwd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveFromCwd.js","sourceRoot":"","sources":["../../../../src/core/helpers/resolveFromCwd.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,GAAW,EAAE,CAAS,EAAE,EAAE,CACvD,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
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>;
|
|
11
|
+
//# sourceMappingURL=parseEnv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseEnv.d.ts","sourceRoot":"","sources":["../../../src/core/parseEnv.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiBjE"}
|
|
@@ -0,0 +1,26 @@
|
|
|
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
|
+
}
|
|
26
|
+
//# sourceMappingURL=parseEnv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseEnv.js","sourceRoot":"","sources":["../../../src/core/parseEnv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAElC,MAAM,MAAM,GAA2B,EAAE,CAAC;IAE1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAElD,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1C,IAAI,CAAC,GAAG;YAAE,SAAS;QAEnB,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7C,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export declare const ENV_PATTERNS: ({
|
|
2
|
+
name: "process.env";
|
|
3
|
+
regex: RegExp;
|
|
4
|
+
frameworks: string[];
|
|
5
|
+
} | {
|
|
6
|
+
name: "import.meta.env";
|
|
7
|
+
regex: RegExp;
|
|
8
|
+
frameworks: string[];
|
|
9
|
+
} | {
|
|
10
|
+
name: "sveltekit";
|
|
11
|
+
regex: RegExp;
|
|
12
|
+
frameworks: string[];
|
|
13
|
+
} | {
|
|
14
|
+
name: "deno";
|
|
15
|
+
regex: RegExp;
|
|
16
|
+
frameworks: string[];
|
|
17
|
+
} | {
|
|
18
|
+
name: "next";
|
|
19
|
+
regex: RegExp;
|
|
20
|
+
frameworks: string[];
|
|
21
|
+
} | {
|
|
22
|
+
name: "nuxt";
|
|
23
|
+
regex: RegExp;
|
|
24
|
+
frameworks: string[];
|
|
25
|
+
} | {
|
|
26
|
+
name: "php";
|
|
27
|
+
regex: RegExp;
|
|
28
|
+
frameworks: string[];
|
|
29
|
+
})[];
|
|
30
|
+
export declare const DEFAULT_INCLUDE_EXTENSIONS: string[];
|
|
31
|
+
export declare const DEFAULT_EXCLUDE_PATTERNS: string[];
|
|
32
|
+
//# sourceMappingURL=patterns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../../src/core/patterns.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAqCxB,CAAC;AAGF,eAAO,MAAM,0BAA0B,UAStC,CAAC;AAGF,eAAO,MAAM,wBAAwB,UAiBpC,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Framework-specific patterns for finding environment variable usage
|
|
2
|
+
export const ENV_PATTERNS = [
|
|
3
|
+
{
|
|
4
|
+
name: 'process.env',
|
|
5
|
+
regex: /process\.env\.([A-Z_][A-Z0-9_]*)/g,
|
|
6
|
+
frameworks: ['node', 'next', 'general'],
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
name: 'import.meta.env',
|
|
10
|
+
regex: /import\.meta\.env\.([A-Z_][A-Z0-9_]*)/g,
|
|
11
|
+
frameworks: ['vite', 'svelte', 'vue'],
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
name: 'sveltekit',
|
|
15
|
+
regex: /\$env\/(?:static|dynamic)\/(?:private|public)\/([A-Z_][A-Z0-9_]*)/g,
|
|
16
|
+
frameworks: ['sveltekit'],
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'deno',
|
|
20
|
+
regex: /Deno\.env\.get\(['"`]([A-Z_][A-Z0-9_]*)['"`]\)/g,
|
|
21
|
+
frameworks: ['deno'],
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'next',
|
|
25
|
+
regex: /process\.env\.(NEXT_PUBLIC_[A-Z_][A-Z0-9_]*)/g,
|
|
26
|
+
frameworks: ['next'],
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: 'nuxt',
|
|
30
|
+
regex: /(?:\$config|useRuntimeConfig\(\))\.([A-Z_][A-Z0-9_]*)/g,
|
|
31
|
+
frameworks: ['nuxt'],
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: 'php',
|
|
35
|
+
regex: /(getenv\(['"`]([A-Z_][A-Z0-9_]*)['"`]\)|\$_ENV\[['"`]([A-Z_][A-Z0-9_]*)['"`]\])/g,
|
|
36
|
+
frameworks: ['php'],
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
// Default file extensions to include in scans
|
|
40
|
+
export const DEFAULT_INCLUDE_EXTENSIONS = [
|
|
41
|
+
'.js',
|
|
42
|
+
'.ts',
|
|
43
|
+
'.jsx',
|
|
44
|
+
'.tsx',
|
|
45
|
+
'.vue',
|
|
46
|
+
'.svelte',
|
|
47
|
+
'.mjs',
|
|
48
|
+
'.cjs',
|
|
49
|
+
];
|
|
50
|
+
// Default patterns to exclude from scans
|
|
51
|
+
export const DEFAULT_EXCLUDE_PATTERNS = [
|
|
52
|
+
'node_modules',
|
|
53
|
+
'.sveltekit',
|
|
54
|
+
'.svelte-kit',
|
|
55
|
+
'_actions',
|
|
56
|
+
'dist',
|
|
57
|
+
'build',
|
|
58
|
+
'.next',
|
|
59
|
+
'.nuxt',
|
|
60
|
+
'coverage',
|
|
61
|
+
'.git',
|
|
62
|
+
'.vscode',
|
|
63
|
+
'.idea',
|
|
64
|
+
'.test.',
|
|
65
|
+
'.spec.',
|
|
66
|
+
'__tests__',
|
|
67
|
+
'__mocks__',
|
|
68
|
+
];
|
|
69
|
+
//# sourceMappingURL=patterns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../../src/core/patterns.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B;QACE,IAAI,EAAE,aAAsB;QAC5B,KAAK,EAAE,mCAAmC;QAC1C,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC;KACxC;IACD;QACE,IAAI,EAAE,iBAA0B;QAChC,KAAK,EAAE,wCAAwC;QAC/C,UAAU,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC;KACtC;IACD;QACE,IAAI,EAAE,WAAoB;QAC1B,KAAK,EAAE,oEAAoE;QAC3E,UAAU,EAAE,CAAC,WAAW,CAAC;KAC1B;IACD;QACE,IAAI,EAAE,MAAe;QACrB,KAAK,EAAE,iDAAiD;QACxD,UAAU,EAAE,CAAC,MAAM,CAAC;KACrB;IACD;QACE,IAAI,EAAE,MAAe;QACrB,KAAK,EAAE,+CAA+C;QACtD,UAAU,EAAE,CAAC,MAAM,CAAC;KACrB;IACD;QACE,IAAI,EAAE,MAAe;QACrB,KAAK,EAAE,wDAAwD;QAC/D,UAAU,EAAE,CAAC,MAAM,CAAC;KACrB;IACD;QACE,IAAI,EAAE,KAAc;QACpB,KAAK,EACH,kFAAkF;QACpF,UAAU,EAAE,CAAC,KAAK,CAAC;KACpB;CACF,CAAC;AAEF,8CAA8C;AAC9C,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,KAAK;IACL,KAAK;IACL,MAAM;IACN,MAAM;IACN,MAAM;IACN,SAAS;IACT,MAAM;IACN,MAAM;CACP,CAAC;AAEF,yCAAyC;AACzC,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,cAAc;IACd,YAAY;IACZ,aAAa;IACb,UAAU;IACV,MAAM;IACN,OAAO;IACP,OAAO;IACP,OAAO;IACP,UAAU;IACV,MAAM;IACN,SAAS;IACT,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,WAAW;IACX,WAAW;CACZ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { EnvUsage, ScanOptions } from '../config/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Scans a file for environment variable usage.
|
|
4
|
+
* @param filePath - The path to the file being scanned.
|
|
5
|
+
* @param content - The content of the file.
|
|
6
|
+
* @param opts - The scan options.
|
|
7
|
+
* @returns An array of environment variable usages found in the file.
|
|
8
|
+
*/
|
|
9
|
+
export declare function scanFile(filePath: string, content: string, opts: ScanOptions): Promise<EnvUsage[]>;
|
|
10
|
+
//# sourceMappingURL=scanFile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanFile.d.ts","sourceRoot":"","sources":["../../../src/core/scanFile.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGhE;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAmCrB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { ENV_PATTERNS } from './patterns.js';
|
|
3
|
+
/**
|
|
4
|
+
* Scans a file for environment variable usage.
|
|
5
|
+
* @param filePath - The path to the file being scanned.
|
|
6
|
+
* @param content - The content of the file.
|
|
7
|
+
* @param opts - The scan options.
|
|
8
|
+
* @returns An array of environment variable usages found in the file.
|
|
9
|
+
*/
|
|
10
|
+
export async function scanFile(filePath, content, opts) {
|
|
11
|
+
const usages = [];
|
|
12
|
+
const lines = content.split('\n');
|
|
13
|
+
const relativePath = path.relative(opts.cwd, filePath);
|
|
14
|
+
for (const pattern of ENV_PATTERNS) {
|
|
15
|
+
let match;
|
|
16
|
+
const regex = new RegExp(pattern.regex.source, pattern.regex.flags);
|
|
17
|
+
while ((match = regex.exec(content)) !== null) {
|
|
18
|
+
const variable = match[1];
|
|
19
|
+
if (!variable)
|
|
20
|
+
continue;
|
|
21
|
+
const matchIndex = match.index;
|
|
22
|
+
// Find line and column
|
|
23
|
+
const beforeMatch = content.substring(0, matchIndex);
|
|
24
|
+
const lineNumber = beforeMatch.split('\n').length;
|
|
25
|
+
const lastNewlineIndex = beforeMatch.lastIndexOf('\n');
|
|
26
|
+
const column = matchIndex - lastNewlineIndex;
|
|
27
|
+
// Get the context (the actual line)
|
|
28
|
+
const contextLine = lines[lineNumber - 1]?.trim() || '';
|
|
29
|
+
usages.push({
|
|
30
|
+
variable,
|
|
31
|
+
file: relativePath,
|
|
32
|
+
line: lineNumber,
|
|
33
|
+
column,
|
|
34
|
+
pattern: pattern.name,
|
|
35
|
+
context: contextLine,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return usages;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=scanFile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanFile.js","sourceRoot":"","sources":["../../../src/core/scanFile.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,QAAgB,EAChB,OAAe,EACf,IAAiB;IAEjB,MAAM,MAAM,GAAe,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAEvD,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;QACnC,IAAI,KAAK,CAAC;QACV,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAEpE,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC9C,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAC1B,IAAI,CAAC,QAAQ;gBAAE,SAAS;YACxB,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC;YAE/B,uBAAuB;YACvB,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;YACrD,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;YAClD,MAAM,gBAAgB,GAAG,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YACvD,MAAM,MAAM,GAAG,UAAU,GAAG,gBAAgB,CAAC;YAE7C,oCAAoC;YACpC,MAAM,WAAW,GAAG,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YAExD,MAAM,CAAC,IAAI,CAAC;gBACV,QAAQ;gBACR,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,UAAU;gBAChB,MAAM;gBACN,OAAO,EAAE,OAAO,CAAC,IAAI;gBACrB,OAAO,EAAE,WAAW;aACrB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ScanUsageOptions, ScanResult, ScanJsonEntry } from '../config/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a JSON output for the scan results.
|
|
4
|
+
* @param scanResult - The result of the scan.
|
|
5
|
+
* @param opts - The scan options.
|
|
6
|
+
* @param comparedAgainst - The file being compared against.
|
|
7
|
+
* @param totalEnvVariables - The total number of environment variables.
|
|
8
|
+
* @returns The JSON output.
|
|
9
|
+
*/
|
|
10
|
+
export declare function createJsonOutput(scanResult: ScanResult, opts: ScanUsageOptions, comparedAgainst: string, totalEnvVariables: number): ScanJsonEntry;
|
|
11
|
+
//# sourceMappingURL=scanJsonOutput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanJsonOutput.d.ts","sourceRoot":"","sources":["../../../src/core/scanJsonOutput.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,UAAU,EAEV,aAAa,EACd,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,gBAAgB,EACtB,eAAe,EAAE,MAAM,EACvB,iBAAiB,EAAE,MAAM,GACxB,aAAa,CAoDf"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a JSON output for the scan results.
|
|
3
|
+
* @param scanResult - The result of the scan.
|
|
4
|
+
* @param opts - The scan options.
|
|
5
|
+
* @param comparedAgainst - The file being compared against.
|
|
6
|
+
* @param totalEnvVariables - The total number of environment variables.
|
|
7
|
+
* @returns The JSON output.
|
|
8
|
+
*/
|
|
9
|
+
export function createJsonOutput(scanResult, opts, comparedAgainst, totalEnvVariables) {
|
|
10
|
+
// Group usages by variable for missing variables
|
|
11
|
+
const missingGrouped = scanResult.missing.map((variable) => ({
|
|
12
|
+
variable,
|
|
13
|
+
usages: scanResult.used
|
|
14
|
+
.filter((u) => u.variable === variable)
|
|
15
|
+
.map((u) => ({
|
|
16
|
+
file: u.file,
|
|
17
|
+
line: u.line,
|
|
18
|
+
pattern: u.pattern,
|
|
19
|
+
context: u.context,
|
|
20
|
+
})),
|
|
21
|
+
}));
|
|
22
|
+
const output = {
|
|
23
|
+
stats: scanResult.stats,
|
|
24
|
+
missing: missingGrouped,
|
|
25
|
+
unused: scanResult.unused,
|
|
26
|
+
};
|
|
27
|
+
if (scanResult.secrets?.length) {
|
|
28
|
+
output.secrets = scanResult.secrets.map((s) => ({
|
|
29
|
+
file: s.file,
|
|
30
|
+
line: s.line,
|
|
31
|
+
message: s.message,
|
|
32
|
+
snippet: s.snippet,
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
// Add duplicates if found
|
|
36
|
+
if (scanResult.duplicates) {
|
|
37
|
+
output.duplicates = scanResult.duplicates;
|
|
38
|
+
}
|
|
39
|
+
// Add comparison info if we compared against a file
|
|
40
|
+
if (comparedAgainst) {
|
|
41
|
+
output.comparedAgainst = comparedAgainst;
|
|
42
|
+
output.totalEnvVariables = totalEnvVariables;
|
|
43
|
+
}
|
|
44
|
+
// Optionally include all usages
|
|
45
|
+
if (opts.showStats) {
|
|
46
|
+
output.allUsages = scanResult.used.map((u) => ({
|
|
47
|
+
variable: u.variable,
|
|
48
|
+
file: u.file,
|
|
49
|
+
line: u.line,
|
|
50
|
+
pattern: u.pattern,
|
|
51
|
+
context: u.context,
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
return output;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=scanJsonOutput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanJsonOutput.js","sourceRoot":"","sources":["../../../src/core/scanJsonOutput.ts"],"names":[],"mappings":"AAOA;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAC9B,UAAsB,EACtB,IAAsB,EACtB,eAAuB,EACvB,iBAAyB;IAEzB,iDAAiD;IACjD,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAgB,EAAE,EAAE,CAAC,CAAC;QACnE,QAAQ;QACR,MAAM,EAAE,UAAU,CAAC,IAAI;aACpB,MAAM,CAAC,CAAC,CAAW,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC;aAChD,GAAG,CAAC,CAAC,CAAW,EAAE,EAAE,CAAC,CAAC;YACrB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,OAAO,EAAE,CAAC,CAAC,OAAO;SACnB,CAAC,CAAC;KACN,CAAC,CAAC,CAAC;IAEJ,MAAM,MAAM,GAAkB;QAC5B,KAAK,EAAE,UAAU,CAAC,KAAK;QACvB,OAAO,EAAE,cAAc;QACvB,MAAM,EAAE,UAAU,CAAC,MAAM;KAC1B,CAAC;IAEF,IAAI,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;QAC9B,MAAwB,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACjE,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,OAAO,EAAE,CAAC,CAAC,OAAO;SACnB,CAAC,CAAC,CAAC;IACN,CAAC;IAED,0BAA0B;IAC1B,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;QAC1B,MAAM,CAAC,UAAU,GAAG,UAAU,CAAC,UAAU,CAAC;IAC5C,CAAC;IAED,oDAAoD;IACpD,IAAI,eAAe,EAAE,CAAC;QACpB,MAAM,CAAC,eAAe,GAAG,eAAe,CAAC;QACzC,MAAM,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;IAC/C,CAAC;IAED,gCAAgC;IAChC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,MAAM,CAAC,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAW,EAAE,EAAE,CAAC,CAAC;YACvD,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,OAAO,EAAE,CAAC,CAAC,OAAO;SACnB,CAAC,CAAC,CAAC;IACN,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secretDetectors.d.ts","sourceRoot":"","sources":["../../../src/core/secretDetectors.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,GAAG,SAAS,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;
|
|
1
|
+
{"version":3,"file":"secretDetectors.d.ts","sourceRoot":"","sources":["../../../src/core/secretDetectors.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,GAAG,SAAS,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAwGF;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,aAAa,EAAE,CAgGjB"}
|
|
@@ -17,25 +17,30 @@ const PROVIDER_PATTERNS = [
|
|
|
17
17
|
];
|
|
18
18
|
const LONG_LITERAL = /["'`]{1}([A-Za-z0-9+/_\-]{24,})["'`]{1}/g;
|
|
19
19
|
const HTTPS_PATTERN = /["'`](https?:\/\/(?!localhost)[^"'`]*)["'`]/g;
|
|
20
|
+
// List of harmless URL patterns to ignore
|
|
21
|
+
const HARMLESS_URLS = [
|
|
22
|
+
/https?:\/\/(www\.)?placeholder\.com/i,
|
|
23
|
+
/https?:\/\/(www\.)?example\.com/i,
|
|
24
|
+
/https?:\/\/127\.0\.0\.1(:\d+)?/i,
|
|
25
|
+
/http:\/\/www\.w3\.org\/2000\/svg/i,
|
|
26
|
+
/xmlns=["']http:\/\/www\.w3\.org\/2000\/svg["']/i, // SVG namespace
|
|
27
|
+
];
|
|
20
28
|
/**
|
|
21
29
|
* Checks if a string looks like a harmless literal.
|
|
22
30
|
* @param s - The string to check.
|
|
23
31
|
* @returns True if the string looks harmless, false otherwise.
|
|
24
32
|
*/
|
|
25
33
|
function looksHarmlessLiteral(s) {
|
|
26
|
-
return (
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
/^data:[a-z]+\/[a-z0-9.+-]+;base64,/i.test(s) ||
|
|
31
|
-
/^\.{0,2}\//.test(s) ||
|
|
32
|
-
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(s) ||
|
|
34
|
+
return (/\S+@\S+/.test(s) || // emails
|
|
35
|
+
/^data:[a-z]+\/[a-z0-9.+-]+;base64,/i.test(s) || // data URIs
|
|
36
|
+
/^\.{0,2}\//.test(s) || // relative paths
|
|
37
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(s) || // UUID
|
|
33
38
|
/^[0-9a-f]{32,128}$/i.test(s) || // MD5, SHA1, SHA256, etc.
|
|
34
|
-
/^[A-Za-z0-9+/_\-]{16,20}={0,2}$/.test(s) ||
|
|
35
|
-
/^[A-Za-z0-9+/_\-]*(_PUBLIC|_PRIVATE|VITE_|NEXT_PUBLIC|VUE_)[A-Za-z0-9+/_\-]*={0,2}$/.test(s) ||
|
|
36
|
-
/^[MmZzLlHhVvCcSsQqTtAa][0-9eE+.\- ,MmZzLlHhVvCcSsQqTtAa]*$/.test(s) ||
|
|
37
|
-
/<svg[\s\S]*?>[\s\S]*?<\/svg>/i.test(s) || //
|
|
38
|
-
|
|
39
|
+
/^[A-Za-z0-9+/_\-]{16,20}={0,2}$/.test(s) || // short base64
|
|
40
|
+
/^[A-Za-z0-9+/_\-]*(_PUBLIC|_PRIVATE|VITE_|NEXT_PUBLIC|VUE_)[A-Za-z0-9+/_\-]*={0,2}$/.test(s) || // env-like keys
|
|
41
|
+
/^[MmZzLlHhVvCcSsQqTtAa][0-9eE+.\- ,MmZzLlHhVvCcSsQqTtAa]*$/.test(s) || // SVG path data
|
|
42
|
+
/<svg[\s\S]*?>[\s\S]*?<\/svg>/i.test(s) || // SVG markup
|
|
43
|
+
HARMLESS_URLS.some((rx) => rx.test(s)) // Allowlisted URLs
|
|
39
44
|
);
|
|
40
45
|
}
|
|
41
46
|
/**
|
|
@@ -95,13 +100,14 @@ export function detectSecretsInSource(file, source) {
|
|
|
95
100
|
HTTPS_PATTERN.lastIndex = 0;
|
|
96
101
|
let httpsMatch;
|
|
97
102
|
while ((httpsMatch = HTTPS_PATTERN.exec(line))) {
|
|
98
|
-
const url = httpsMatch[1];
|
|
99
|
-
if (
|
|
103
|
+
const url = httpsMatch[1] || '';
|
|
104
|
+
if (url && !looksHarmlessLiteral(url)) {
|
|
105
|
+
const protocol = url.startsWith('https') ? 'HTTPS' : 'HTTP';
|
|
100
106
|
findings.push({
|
|
101
107
|
file,
|
|
102
108
|
line: lineNo,
|
|
103
109
|
kind: 'pattern',
|
|
104
|
-
message:
|
|
110
|
+
message: `${protocol} URL detected – consider moving to an environment variable`,
|
|
105
111
|
snippet: line.trim().slice(0, 180),
|
|
106
112
|
});
|
|
107
113
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secretDetectors.js","sourceRoot":"","sources":["../../../src/core/secretDetectors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAWxD,0EAA0E;AAC1E,MAAM,eAAe,GACnB,uGAAuG,CAAC;AAE1G,sDAAsD;AACtD,MAAM,iBAAiB,GAAa;IAClC,sBAAsB,EAAE,oBAAoB;IAC5C,sBAAsB,EAAE,eAAe;IACvC,0BAA0B,EAAE,eAAe;IAC3C,8BAA8B,EAAE,qBAAqB;IACrD,8BAA8B,EAAE,qBAAqB;IACrD,6BAA6B,EAAE,iBAAiB;IAChD,2BAA2B,EAAE,4BAA4B;IACzD,0CAA0C,EAAE,iBAAiB;IAC7D,uBAAuB,EAAE,mBAAmB;IAC5C,uDAAuD,EAAE,YAAY;IACrE,uBAAuB,EAAE,qBAAqB;CAC/C,CAAC;AAEF,MAAM,YAAY,GAAG,0CAA0C,CAAC;AAEhE,MAAM,aAAa,GAAG,8CAA8C,CAAC;AAErE;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,CAAS;IACrC,OAAO
|
|
1
|
+
{"version":3,"file":"secretDetectors.js","sourceRoot":"","sources":["../../../src/core/secretDetectors.ts"],"names":[],"mappings":"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"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { parseEnvFile } from './
|
|
2
|
-
export { diffEnv, type DiffResult } from './
|
|
1
|
+
export { parseEnvFile } from './core/parseEnv.js';
|
|
2
|
+
export { diffEnv, type DiffResult } from './core/diffEnv.js';
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/src/index.js
CHANGED
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAmB,MAAM,mBAAmB,CAAC"}
|