dotenv-diff 2.5.0 → 2.5.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.
Files changed (199) hide show
  1. package/CHANGELOG.md +341 -536
  2. package/dist/bin/dotenv-diff.js +0 -0
  3. package/package.json +5 -1
  4. package/dist/cli.d.ts +0 -9
  5. package/dist/cli.js +0 -294
  6. package/dist/diffEnv.d.ts +0 -5
  7. package/dist/diffEnv.js +0 -7
  8. package/dist/index.d.ts +0 -2
  9. package/dist/index.js +0 -2
  10. package/dist/lib/checkGitignore.d.ts +0 -23
  11. package/dist/lib/checkGitignore.js +0 -73
  12. package/dist/lib/diffEnv.d.ts +0 -18
  13. package/dist/lib/diffEnv.js +0 -29
  14. package/dist/lib/parseEnv.d.ts +0 -10
  15. package/dist/lib/parseEnv.js +0 -25
  16. package/dist/parseEnv.d.ts +0 -1
  17. package/dist/parseEnv.js +0 -16
  18. package/dist/src/core/compareScan.d.ts +0 -10
  19. package/dist/src/core/compareScan.d.ts.map +0 -1
  20. package/dist/src/core/compareScan.js +0 -19
  21. package/dist/src/core/compareScan.js.map +0 -1
  22. package/dist/src/core/computeHealthScore.d.ts +0 -8
  23. package/dist/src/core/computeHealthScore.d.ts.map +0 -1
  24. package/dist/src/core/computeHealthScore.js +0 -35
  25. package/dist/src/core/computeHealthScore.js.map +0 -1
  26. package/dist/src/core/cspDetector.d.ts +0 -7
  27. package/dist/src/core/cspDetector.d.ts.map +0 -1
  28. package/dist/src/core/cspDetector.js +0 -38
  29. package/dist/src/core/cspDetector.js.map +0 -1
  30. package/dist/src/core/defaultExcludeKeys.d.ts +0 -7
  31. package/dist/src/core/defaultExcludeKeys.d.ts.map +0 -1
  32. package/dist/src/core/detectClientExposure.d.ts +0 -12
  33. package/dist/src/core/detectClientExposure.d.ts.map +0 -1
  34. package/dist/src/core/detectClientExposure.js +0 -62
  35. package/dist/src/core/detectClientExposure.js.map +0 -1
  36. package/dist/src/core/detectExpirations.d.ts +0 -14
  37. package/dist/src/core/detectExpirations.d.ts.map +0 -1
  38. package/dist/src/core/detectExpirations.js +0 -44
  39. package/dist/src/core/detectExpirations.js.map +0 -1
  40. package/dist/src/core/detectUppercaseKeys.d.ts +0 -9
  41. package/dist/src/core/detectUppercaseKeys.d.ts.map +0 -1
  42. package/dist/src/core/detectUppercaseKeys.js +0 -28
  43. package/dist/src/core/detectUppercaseKeys.js.map +0 -1
  44. package/dist/src/core/determineComparisonFile.d.ts +0 -13
  45. package/dist/src/core/determineComparisonFile.d.ts.map +0 -1
  46. package/dist/src/core/determineComparisonFile.js +0 -33
  47. package/dist/src/core/determineComparisonFile.js.map +0 -1
  48. package/dist/src/core/entropy.d.ts +0 -8
  49. package/dist/src/core/entropy.d.ts.map +0 -1
  50. package/dist/src/core/entropy.js +0 -23
  51. package/dist/src/core/entropy.js.map +0 -1
  52. package/dist/src/core/envDiscovery.d.ts +0 -19
  53. package/dist/src/core/envDiscovery.d.ts.map +0 -1
  54. package/dist/src/core/envDiscovery.js +0 -81
  55. package/dist/src/core/envDiscovery.js.map +0 -1
  56. package/dist/src/core/envPairing.d.ts +0 -8
  57. package/dist/src/core/envPairing.d.ts.map +0 -1
  58. package/dist/src/core/envPairing.js +0 -36
  59. package/dist/src/core/envPairing.js.map +0 -1
  60. package/dist/src/core/envValidator.d.ts +0 -9
  61. package/dist/src/core/envValidator.d.ts.map +0 -1
  62. package/dist/src/core/envValidator.js +0 -103
  63. package/dist/src/core/envValidator.js.map +0 -1
  64. package/dist/src/core/exampleSecretDetector.d.ts +0 -13
  65. package/dist/src/core/exampleSecretDetector.d.ts.map +0 -1
  66. package/dist/src/core/exampleSecretDetector.js +0 -61
  67. package/dist/src/core/exampleSecretDetector.js.map +0 -1
  68. package/dist/src/core/frameworkDetector.d.ts +0 -14
  69. package/dist/src/core/frameworkDetector.d.ts.map +0 -1
  70. package/dist/src/core/frameworkDetector.js +0 -40
  71. package/dist/src/core/frameworkDetector.js.map +0 -1
  72. package/dist/src/core/frameworkValidator.d.ts +0 -10
  73. package/dist/src/core/frameworkValidator.d.ts.map +0 -1
  74. package/dist/src/core/frameworkValidator.js +0 -21
  75. package/dist/src/core/frameworkValidator.js.map +0 -1
  76. package/dist/src/core/frameworks/angularRules.d.ts +0 -4
  77. package/dist/src/core/frameworks/angularRules.d.ts.map +0 -1
  78. package/dist/src/core/helpers/isAllOk.d.ts +0 -9
  79. package/dist/src/core/helpers/isAllOk.d.ts.map +0 -1
  80. package/dist/src/core/helpers/isAllOk.js +0 -16
  81. package/dist/src/core/helpers/isAllOk.js.map +0 -1
  82. package/dist/src/core/helpers/updateTotals.d.ts +0 -19
  83. package/dist/src/core/helpers/updateTotals.d.ts.map +0 -1
  84. package/dist/src/core/helpers/updateTotals.js +0 -37
  85. package/dist/src/core/helpers/updateTotals.js.map +0 -1
  86. package/dist/src/core/parseAndFilterEnv.d.ts +0 -20
  87. package/dist/src/core/parseAndFilterEnv.d.ts.map +0 -1
  88. package/dist/src/core/parseAndFilterEnv.js +0 -22
  89. package/dist/src/core/parseAndFilterEnv.js.map +0 -1
  90. package/dist/src/core/processComparisonFile.d.ts +0 -43
  91. package/dist/src/core/processComparisonFile.d.ts.map +0 -1
  92. package/dist/src/core/processComparisonFile.js +0 -170
  93. package/dist/src/core/processComparisonFile.js.map +0 -1
  94. package/dist/src/core/scan/scanJsonOutput.d.ts +0 -85
  95. package/dist/src/core/scan/scanJsonOutput.d.ts.map +0 -1
  96. package/dist/src/core/scan/scanJsonOutput.js +0 -97
  97. package/dist/src/core/scan/scanJsonOutput.js.map +0 -1
  98. package/dist/src/core/scan/secretDetectors.d.ts +0 -28
  99. package/dist/src/core/scan/secretDetectors.d.ts.map +0 -1
  100. package/dist/src/core/scan/secretDetectors.js +0 -272
  101. package/dist/src/core/scan/secretDetectors.js.map +0 -1
  102. package/dist/src/core/scanFile.d.ts +0 -10
  103. package/dist/src/core/scanFile.d.ts.map +0 -1
  104. package/dist/src/core/scanFile.js +0 -65
  105. package/dist/src/core/scanFile.js.map +0 -1
  106. package/dist/src/core/scanJsonOutput.d.ts +0 -85
  107. package/dist/src/core/scanJsonOutput.d.ts.map +0 -1
  108. package/dist/src/core/scanJsonOutput.js +0 -97
  109. package/dist/src/core/scanJsonOutput.js.map +0 -1
  110. package/dist/src/core/secretDetectors.d.ts +0 -28
  111. package/dist/src/core/secretDetectors.d.ts.map +0 -1
  112. package/dist/src/core/secretDetectors.js +0 -272
  113. package/dist/src/core/secretDetectors.js.map +0 -1
  114. package/dist/src/core/t3env/detectT3Env.d.ts +0 -12
  115. package/dist/src/core/t3env/detectT3Env.d.ts.map +0 -1
  116. package/dist/src/core/t3env/detectT3Env.js +0 -113
  117. package/dist/src/core/t3env/detectT3Env.js.map +0 -1
  118. package/dist/src/core/t3env/t3EnvRules.d.ts +0 -10
  119. package/dist/src/core/t3env/t3EnvRules.d.ts.map +0 -1
  120. package/dist/src/core/t3env/t3EnvRules.js +0 -61
  121. package/dist/src/core/t3env/t3EnvRules.js.map +0 -1
  122. package/dist/src/core/t3env/t3EnvValidator.d.ts +0 -9
  123. package/dist/src/core/t3env/t3EnvValidator.d.ts.map +0 -1
  124. package/dist/src/core/t3env/t3EnvValidator.js +0 -32
  125. package/dist/src/core/t3env/t3EnvValidator.js.map +0 -1
  126. package/dist/src/lib/diffEnv.d.ts +0 -19
  127. package/dist/src/lib/diffEnv.d.ts.map +0 -1
  128. package/dist/src/lib/diffEnv.js +0 -31
  129. package/dist/src/lib/diffEnv.js.map +0 -1
  130. package/dist/src/lib/parseEnv.d.ts +0 -11
  131. package/dist/src/lib/parseEnv.d.ts.map +0 -1
  132. package/dist/src/lib/parseEnv.js +0 -26
  133. package/dist/src/lib/parseEnv.js.map +0 -1
  134. package/dist/src/services/codeBaseScanner.d.ts +0 -8
  135. package/dist/src/services/codeBaseScanner.d.ts.map +0 -1
  136. package/dist/src/services/codeBaseScanner.js +0 -110
  137. package/dist/src/services/codeBaseScanner.js.map +0 -1
  138. package/dist/src/services/duplicates.d.ts +0 -12
  139. package/dist/src/services/duplicates.d.ts.map +0 -1
  140. package/dist/src/services/duplicates.js +0 -36
  141. package/dist/src/services/duplicates.js.map +0 -1
  142. package/dist/src/services/ensureFilesOrPrompt.d.ts +0 -22
  143. package/dist/src/services/ensureFilesOrPrompt.d.ts.map +0 -1
  144. package/dist/src/services/ensureFilesOrPrompt.js +0 -76
  145. package/dist/src/services/ensureFilesOrPrompt.js.map +0 -1
  146. package/dist/src/services/scanOutputToConsole.d.ts +0 -17
  147. package/dist/src/services/scanOutputToConsole.d.ts.map +0 -1
  148. package/dist/src/services/scanOutputToConsole.js +0 -127
  149. package/dist/src/services/scanOutputToConsole.js.map +0 -1
  150. package/dist/src/ui/compare/printAutoFix.d.ts +0 -16
  151. package/dist/src/ui/compare/printAutoFix.d.ts.map +0 -1
  152. package/dist/src/ui/compare/printAutoFix.js +0 -34
  153. package/dist/src/ui/compare/printAutoFix.js.map +0 -1
  154. package/dist/src/ui/compare/printAutoFixApplied.d.ts +0 -7
  155. package/dist/src/ui/compare/printAutoFixApplied.d.ts.map +0 -1
  156. package/dist/src/ui/compare/printAutoFixApplied.js +0 -22
  157. package/dist/src/ui/compare/printAutoFixApplied.js.map +0 -1
  158. package/dist/src/ui/compare/printDuplicates.d.ts +0 -17
  159. package/dist/src/ui/compare/printDuplicates.d.ts.map +0 -1
  160. package/dist/src/ui/compare/printDuplicates.js +0 -25
  161. package/dist/src/ui/compare/printDuplicates.js.map +0 -1
  162. package/dist/src/ui/compare/printFixTips.d.ts +0 -11
  163. package/dist/src/ui/compare/printFixTips.d.ts.map +0 -1
  164. package/dist/src/ui/compare/printFixTips.js +0 -46
  165. package/dist/src/ui/compare/printFixTips.js.map +0 -1
  166. package/dist/src/ui/compare/printSuccess.d.ts +0 -11
  167. package/dist/src/ui/compare/printSuccess.d.ts.map +0 -1
  168. package/dist/src/ui/compare/printSuccess.js +0 -27
  169. package/dist/src/ui/compare/printSuccess.js.map +0 -1
  170. package/dist/src/ui/scan/printCspWarning.d.ts +0 -9
  171. package/dist/src/ui/scan/printCspWarning.d.ts.map +0 -1
  172. package/dist/src/ui/scan/printCspWarning.js +0 -20
  173. package/dist/src/ui/scan/printCspWarning.js.map +0 -1
  174. package/dist/src/ui/scan/printEnvWarnings.d.ts +0 -8
  175. package/dist/src/ui/scan/printEnvWarnings.d.ts.map +0 -1
  176. package/dist/src/ui/scan/printEnvWarnings.js +0 -20
  177. package/dist/src/ui/scan/printEnvWarnings.js.map +0 -1
  178. package/dist/src/ui/scan/printExposedVars.d.ts +0 -8
  179. package/dist/src/ui/scan/printExposedVars.d.ts.map +0 -1
  180. package/dist/src/ui/scan/printExposedVars.js +0 -24
  181. package/dist/src/ui/scan/printExposedVars.js.map +0 -1
  182. package/dist/src/ui/scan/printT3EnvWarnings.d.ts +0 -8
  183. package/dist/src/ui/scan/printT3EnvWarnings.d.ts.map +0 -1
  184. package/dist/src/ui/scan/printT3EnvWarnings.js +0 -20
  185. package/dist/src/ui/scan/printT3EnvWarnings.js.map +0 -1
  186. package/dist/src/ui/scan/printUniqueVariables.d.ts +0 -7
  187. package/dist/src/ui/scan/printUniqueVariables.d.ts.map +0 -1
  188. package/dist/src/ui/scan/printUniqueVariables.js +0 -14
  189. package/dist/src/ui/scan/printUniqueVariables.js.map +0 -1
  190. package/dist/src/ui/scan/printVariables.d.ts +0 -10
  191. package/dist/src/ui/scan/printVariables.d.ts.map +0 -1
  192. package/dist/src/ui/scan/printVariables.js +0 -37
  193. package/dist/src/ui/scan/printVariables.js.map +0 -1
  194. package/dist/src/ui/shared/printProgress.d.ts +0 -24
  195. package/dist/src/ui/shared/printProgress.d.ts.map +0 -1
  196. package/dist/src/ui/shared/printProgress.js +0 -43
  197. package/dist/src/ui/shared/printProgress.js.map +0 -1
  198. package/dist/types/scanUsage.d.ts +0 -43
  199. package/dist/types/scanUsage.d.ts.map +0 -1
@@ -1,272 +0,0 @@
1
- import { shannonEntropyNormalized } from '../entropy.js';
2
- // Regular expressions for detecting suspicious keys and provider patterns
3
- export const SUSPICIOUS_KEYS = /\b(pass(word)?|secret|token|apikey|api_key|key|auth|bearer|private|client_secret|access[_-]?token)\b/i;
4
- // Regular expressions for detecting provider patterns
5
- export const PROVIDER_PATTERNS = [
6
- /\bAKIA[0-9A-Z]{16}\b/, // AWS access key id
7
- /\bASIA[0-9A-Z]{16}\b/, // AWS temp key
8
- /\bghp_[0-9A-Za-z]{30,}\b/, // GitHub token
9
- /\bsk_live_[0-9a-zA-Z]{24,}\b/, // Stripe live secret
10
- /\bsk_test_[0-9a-zA-Z]{24,}\b/, // Stripe test secret
11
- /\bAIza[0-9A-Za-z\-_]{20,}\b/, // Google API key
12
- /\bya29\.[0-9A-Za-z\-_]+\b/, // Google OAuth access token
13
- /\b[A-Za-z0-9_-]{21}:[A-Za-z0-9_-]{140}\b/, // Firebase token
14
- /\b0x[a-fA-F0-9]{40}\b/, // Ethereum address
15
- /\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/, // JWT token
16
- /\bAC[0-9a-fA-F]{32}\b/, // Twilio Account SID
17
- ];
18
- const LONG_LITERAL = /["'`]{1}([A-Za-z0-9+/_\-]{24,})["'`]{1}/g;
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
- ];
28
- // Known harmless attribute keys commonly used in UI / analytics
29
- const HARMLESS_ATTRIBUTE_KEYS = /\b(trackingId|trackingContext|data-testid|data-test|aria-label)\b/i;
30
- /**
31
- * Determines the severity of a secret finding.
32
- * @param kind 'pattern' | 'entropy'
33
- * @param message The message describing the finding
34
- * @param literalLength The length of the literal string (if applicable)
35
- * @returns The severity level of the secret finding
36
- */
37
- function determineSeverity(kind, message, literalLength) {
38
- // HIGH: Known provider key patterns
39
- if (message.includes('known provider key pattern')) {
40
- return 'high';
41
- }
42
- // HIGH: Very high-entropy long strings
43
- if (kind === 'entropy' && literalLength && literalLength >= 48) {
44
- return 'high';
45
- }
46
- // MEDIUM: Password/secret/token patterns
47
- if (message.includes('password/secret/token-like')) {
48
- return 'medium';
49
- }
50
- // MEDIUM: Medium high-entropy strings
51
- if (kind === 'entropy' && literalLength && literalLength >= 32) {
52
- return 'medium';
53
- }
54
- // MEDIUM: HTTP URLs
55
- if (message.includes('HTTP URL detected')) {
56
- return 'medium';
57
- }
58
- // LOW: HTTPS URLs
59
- if (message.includes('HTTPS URL detected')) {
60
- return 'low';
61
- }
62
- // Default to medium if we can't determine
63
- return 'medium';
64
- }
65
- /**
66
- * Checks if a line has an ignore comment
67
- * fx: // dotenv-diff-ignore or /* dotenv-diff-ignore *\/ or <!-- dotenv-diff-ignore -->
68
- * @param line - The line to check
69
- * @returns True if the line should be ignored
70
- */
71
- export function hasIgnoreComment(line) {
72
- const normalized = line.trim();
73
- // Allow mixed casing, extra spaces, and optional dashes
74
- return (/\/\/.*dotenv[\s-]*diff[\s-]*ignore/i.test(normalized) ||
75
- /\/\*.*dotenv[\s-]*diff[\s-]*ignore.*\*\//i.test(normalized) ||
76
- /<!--.*dotenv[\s-]*diff[\s-]*ignore.*-->/i.test(normalized) ||
77
- /\bdotenv[\s-]*diff[\s-]*ignore\b/i.test(normalized));
78
- }
79
- /**
80
- * Checks if a URL should be ignored based on ignoreUrls from config.
81
- * @param url - The URL that might be a potential secret
82
- * @param ignoreUrls - List of URLs to ignore (from config)
83
- * @returns true if the URL matches any ignore pattern
84
- */
85
- function ignoreUrlsMatch(url, ignoreUrls) {
86
- if (!ignoreUrls?.length)
87
- return false;
88
- // case-insensitive substring match
89
- return ignoreUrls.some((pattern) => url.toLowerCase().includes(pattern.toLowerCase()));
90
- }
91
- /**
92
- * Checks if a string looks like a harmless literal.
93
- * @param s - The string to check.
94
- * @returns True if the string looks harmless, false otherwise.
95
- */
96
- function looksHarmlessLiteral(s) {
97
- return (/\S+@\S+/.test(s) || // emails
98
- /^data:[a-z]+\/[a-z0-9.+-]+;base64,/i.test(s) || // data URIs
99
- /^\.{0,2}\//.test(s) || // relative paths
100
- /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(s) || // UUID
101
- /^[0-9a-f]{32,128}$/i.test(s) || // MD5, SHA1, SHA256, etc.
102
- /^[A-Za-z0-9+/_\-]{16,20}={0,2}$/.test(s) || // short base64
103
- /^[A-Za-z0-9+/_\-]*(_PUBLIC|_PRIVATE|VITE_|NEXT_PUBLIC|VUE_)[A-Za-z0-9+/_\-]*={0,2}$/.test(s) || // env-like keys
104
- /^[MmZzLlHhVvCcSsQqTtAa][0-9eE+.\- ,MmZzLlHhVvCcSsQqTtAa]*$/.test(s) || // SVG path data
105
- /<svg[\s\S]*?>[\s\S]*?<\/svg>/i.test(s) || // SVG markup
106
- HARMLESS_URLS.some((rx) => rx.test(s)) // Allowlisted URLs
107
- );
108
- }
109
- /**
110
- * Checks if a line looks like a URL construction pattern.
111
- * @param line - The line to check.
112
- * @returns True if the line looks like URL construction, false otherwise.
113
- */
114
- function looksLikeUrlConstruction(line) {
115
- // Check for template literals or string concatenation that looks like URLs
116
- return (
117
- // Template literals with URL-like patterns
118
- /=\s*`[^`]*\$\{[^}]+\}[^`]*\/[^`]*`/.test(line) ||
119
- // String concatenation with slashes
120
- /=\s*["'][^"']*\/[^"']*["']\s*\+/.test(line) ||
121
- // Contains common URL patterns
122
- /=\s*["'`][^"'`]*\/[^"'`]*(auth|api|login|redirect|callback|protocol)[^"'`]*\/[^"'`]*["'`]/.test(line) ||
123
- // Keycloak-specific patterns
124
- /realms\/.*\/protocol\/openid-connect/.test(line));
125
- }
126
- /**
127
- * Checks if a file path is probably a test path.
128
- * This is determined by looking for common test folder names and file extensions.
129
- * @param p - The file path to check.
130
- * @returns True if the file path is probably a test path, false otherwise.
131
- */
132
- function isProbablyTestPath(p) {
133
- return (/\b(__tests__|__mocks__|fixtures|sandbox|samples)\b/i.test(p) ||
134
- /\.(spec|test)\.[jt]sx?$/.test(p));
135
- }
136
- /**
137
- * Checks if a string is a pure interpolation template.
138
- * @param s - The string to check.
139
- * @returns True if the string is a pure interpolation template, false otherwise.
140
- */
141
- function isPureInterpolationTemplate(s) {
142
- // Matches templates like `${a}`, `${a}:${b}`, `${a}|${b}|${c}`
143
- // i.e. no meaningful static content
144
- const withoutInterpolations = s.replace(/\$\{[^}]+\}/g, '');
145
- return /^[\s:|,._-]*$/.test(withoutInterpolations);
146
- }
147
- // Threshold is the value between 0 and 1 that determines the sensitivity of the detection.
148
- const DEFAULT_SECRET_THRESHOLD = 0.85;
149
- /**
150
- * Optimized for sveltekit and vite env accessors
151
- * @param line - A line of code to check.
152
- * @returns True if the line is an environment variable accessor, false otherwise.
153
- */
154
- function isEnvAccessor(line) {
155
- return /\b(process\.env|import\.meta\.env|\$env\/(static|dynamic)\/(public|private))\b/.test(line);
156
- }
157
- /**
158
- * Detects secrets in the source code of a file.
159
- * @param file - The file path to check.
160
- * @param source - The source code to scan for secrets.
161
- * @returns An array of secret findings.
162
- */
163
- export function detectSecretsInSource(file, source, opts) {
164
- const threshold = isProbablyTestPath(file) ? 0.95 : DEFAULT_SECRET_THRESHOLD;
165
- const findings = [];
166
- const lines = source.split(/\r?\n/);
167
- let insideIgnoreBlock = false;
168
- for (let i = 0; i < lines.length; i++) {
169
- const lineNo = i + 1;
170
- const line = lines[i] || '';
171
- if (/<!--\s*dotenv[\s-]*diff[\s-]*ignore[\s-]*start\s*-->/i.test(line)) {
172
- insideIgnoreBlock = true;
173
- continue;
174
- }
175
- if (/<!--\s*dotenv[\s-]*diff[\s-]*ignore[\s-]*end\s*-->/i.test(line)) {
176
- insideIgnoreBlock = false;
177
- continue;
178
- }
179
- // Skip if inside ignore block
180
- if (insideIgnoreBlock)
181
- continue;
182
- // Skip comments
183
- if (/^\s*\/\//.test(line))
184
- continue;
185
- // Check if line has ignore comment
186
- if (hasIgnoreComment(line))
187
- continue;
188
- // Check for HTTPS URLs
189
- HTTPS_PATTERN.lastIndex = 0;
190
- let httpsMatch;
191
- while ((httpsMatch = HTTPS_PATTERN.exec(line))) {
192
- const url = httpsMatch[1] || '';
193
- if (url && !looksHarmlessLiteral(url)) {
194
- if (ignoreUrlsMatch(url, opts?.ignoreUrls))
195
- continue;
196
- const protocol = url.startsWith('https') ? 'HTTPS' : 'HTTP';
197
- findings.push({
198
- file,
199
- line: lineNo,
200
- kind: 'pattern',
201
- message: `${protocol} URL detected – consider moving to an environment variable`,
202
- snippet: line.trim().slice(0, 180),
203
- severity: protocol === 'HTTP' ? 'medium' : 'low',
204
- });
205
- }
206
- }
207
- // 1) Suspicious key literal assignments
208
- if (SUSPICIOUS_KEYS.test(line)) {
209
- // Ignore known harmless UI / analytics attributes
210
- if (HARMLESS_ATTRIBUTE_KEYS.test(line))
211
- continue;
212
- const m = line.match(/=\s*["'`](.+?)["'`]/);
213
- if (m &&
214
- m[1] &&
215
- !looksHarmlessLiteral(m[1]) &&
216
- !looksLikeUrlConstruction(line) &&
217
- m[1].length >= 12 &&
218
- !isEnvAccessor(line) &&
219
- !isPureInterpolationTemplate(m[1])) {
220
- findings.push({
221
- file,
222
- line: lineNo,
223
- kind: 'pattern',
224
- message: 'matches password/secret/token-like literal assignment',
225
- snippet: line.trim().slice(0, 180),
226
- severity: 'medium',
227
- });
228
- }
229
- }
230
- // 2) Provider patterns
231
- for (const rx of PROVIDER_PATTERNS) {
232
- if (rx.test(line)) {
233
- findings.push({
234
- file,
235
- line: lineNo,
236
- kind: 'pattern',
237
- message: 'matches known provider key pattern',
238
- snippet: line.trim().slice(0, 180),
239
- severity: 'high',
240
- });
241
- }
242
- }
243
- // 3) High-entropy long literals
244
- LONG_LITERAL.lastIndex = 0;
245
- let lm;
246
- while ((lm = LONG_LITERAL.exec(line))) {
247
- const literal = lm[1] || '';
248
- if (looksHarmlessLiteral(literal))
249
- continue;
250
- if (literal.length < 32)
251
- continue;
252
- const ent = shannonEntropyNormalized(literal);
253
- if (ent >= threshold) {
254
- const message = `found high-entropy string (len ${literal.length}, H≈${ent.toFixed(2)})`;
255
- findings.push({
256
- file,
257
- line: lineNo,
258
- kind: 'entropy',
259
- message,
260
- snippet: line.trim().slice(0, 180),
261
- severity: determineSeverity('entropy', message, literal.length),
262
- });
263
- }
264
- }
265
- }
266
- const uniqueFindings = findings.filter((f, idx, arr) => idx ===
267
- arr.findIndex((other) => other.file === f.file &&
268
- other.line === f.line &&
269
- other.snippet === f.snippet));
270
- return uniqueFindings;
271
- }
272
- //# sourceMappingURL=secretDetectors.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"secretDetectors.js","sourceRoot":"","sources":["../../../../src/core/scan/secretDetectors.ts"],"names":[],"mappings":"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"}
@@ -1,10 +0,0 @@
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): EnvUsage[];
10
- //# sourceMappingURL=scanFile.d.ts.map
@@ -1 +0,0 @@
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;AAKhE;;;;;;GAMG;AACH,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,WAAW,GAChB,QAAQ,EAAE,CAsEZ"}
@@ -1,65 +0,0 @@
1
- import path from 'path';
2
- import { ENV_PATTERNS } from './patterns.js';
3
- import { hasIgnoreComment } from './security/secretDetectors.js';
4
- import { normalizePath } from './helpers/normalizePath.js';
5
- /**
6
- * Scans a file for environment variable usage.
7
- * @param filePath - The path to the file being scanned.
8
- * @param content - The content of the file.
9
- * @param opts - The scan options.
10
- * @returns An array of environment variable usages found in the file.
11
- */
12
- export function scanFile(filePath, content, opts) {
13
- const usages = [];
14
- const lines = content.split('\n');
15
- // Get relative path from cwd corss-platform compatible
16
- const relativePath = normalizePath(path.relative(opts.cwd, filePath));
17
- // Collect all $env imports used in this file
18
- const envImports = [];
19
- const importRegex = /import\s+(?:\{[^}]*\}|\w+)\s+from\s+['"](\$env\/(?:static|dynamic)\/(?:private|public))['"]/g;
20
- let importMatch;
21
- while ((importMatch = importRegex.exec(content)) !== null) {
22
- if (importMatch[1]) {
23
- envImports.push(importMatch[1]);
24
- }
25
- }
26
- for (const pattern of ENV_PATTERNS) {
27
- let match;
28
- const regex = new RegExp(pattern.regex.source, pattern.regex.flags);
29
- while ((match = regex.exec(content)) !== null) {
30
- const variable = match[1];
31
- if (!variable)
32
- continue;
33
- const matchIndex = match.index;
34
- // Find line and column
35
- const beforeMatch = content.substring(0, matchIndex);
36
- const lineNumber = beforeMatch.split('\n').length;
37
- const lastNewlineIndex = beforeMatch.lastIndexOf('\n');
38
- const column = lastNewlineIndex === -1
39
- ? matchIndex + 1
40
- : matchIndex - lastNewlineIndex;
41
- // Get the context (the actual line)
42
- const contextLine = lines[lineNumber - 1] ?? '';
43
- // Determine previous line for ignore detection
44
- const prevLine = lines[lineNumber - 2] ?? '';
45
- const isIgnored = hasIgnoreComment(contextLine) || hasIgnoreComment(prevLine);
46
- // If usage is ignored, skip it entirely
47
- if (isIgnored)
48
- continue;
49
- // Check if console.log
50
- const isLogged = /\bconsole\.(log|error|warn|info|debug)\s*\(/.test(contextLine);
51
- usages.push({
52
- variable,
53
- file: relativePath,
54
- line: lineNumber,
55
- column,
56
- pattern: pattern.name,
57
- imports: envImports,
58
- context: contextLine,
59
- isLogged,
60
- });
61
- }
62
- }
63
- return usages;
64
- }
65
- //# sourceMappingURL=scanFile.js.map
@@ -1 +0,0 @@
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;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CACtB,QAAgB,EAChB,OAAe,EACf,IAAiB;IAEjB,MAAM,MAAM,GAAe,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAElC,uDAAuD;IACvD,MAAM,YAAY,GAAG,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEtE,6CAA6C;IAC7C,MAAM,UAAU,GAAa,EAAE,CAAC;IAEhC,MAAM,WAAW,GACf,8FAA8F,CAAC;IAEjG,IAAI,WAAmC,CAAC;IAExC,OAAO,CAAC,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC1D,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;YACnB,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;QACnC,IAAI,KAA6B,CAAC;QAClC,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,GACV,gBAAgB,KAAK,CAAC,CAAC;gBACrB,CAAC,CAAC,UAAU,GAAG,CAAC;gBAChB,CAAC,CAAC,UAAU,GAAG,gBAAgB,CAAC;YAEpC,oCAAoC;YACpC,MAAM,WAAW,GAAG,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YAEhD,+CAA+C;YAC/C,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YAE7C,MAAM,SAAS,GACb,gBAAgB,CAAC,WAAW,CAAC,IAAI,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAE9D,wCAAwC;YACxC,IAAI,SAAS;gBAAE,SAAS;YAExB,uBAAuB;YACvB,MAAM,QAAQ,GAAG,6CAA6C,CAAC,IAAI,CACjE,WAAW,CACZ,CAAC;YAEF,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,UAAU;gBACnB,OAAO,EAAE,WAAW;gBACpB,QAAQ;aACT,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -1,85 +0,0 @@
1
- import type { ScanResult, Duplicate, SupportedFramework } from '../config/types.js';
2
- /**
3
- * JSON structure for scan results output
4
- */
5
- interface ScanJsonOutput {
6
- stats?: {
7
- filesScanned: number;
8
- totalUsages: number;
9
- uniqueVariables: number;
10
- warningsCount: number;
11
- duration: number;
12
- };
13
- missing?: Array<{
14
- variable: string;
15
- usages: Array<{
16
- file: string;
17
- line: number;
18
- pattern: string;
19
- context: string;
20
- }>;
21
- }>;
22
- unused?: string[];
23
- allUsages?: Array<{
24
- variable: string;
25
- file: string;
26
- line: number;
27
- pattern: string;
28
- context: string;
29
- }>;
30
- comparedAgainst?: string;
31
- totalEnvVariables?: number;
32
- secrets?: Array<{
33
- file: string;
34
- line: number;
35
- message: string;
36
- snippet: string;
37
- }>;
38
- duplicates?: {
39
- env?: Duplicate[];
40
- example?: Duplicate[];
41
- };
42
- logged?: Array<{
43
- variable: string;
44
- file: string;
45
- line: number;
46
- context: string;
47
- }>;
48
- expireWarnings?: Array<{
49
- key: string;
50
- date: string;
51
- daysLeft: number;
52
- }>;
53
- uppercaseWarnings?: Array<{
54
- key: string;
55
- suggestion: string;
56
- }>;
57
- inconsistentNamingWarnings?: Array<{
58
- key1: string;
59
- key2: string;
60
- suggestion: string;
61
- }>;
62
- frameworkWarnings?: Array<{
63
- variable: string;
64
- reason: string;
65
- file: string;
66
- line: number;
67
- framework: SupportedFramework;
68
- }>;
69
- exampleWarnings?: Array<{
70
- key: string;
71
- value: string;
72
- reason: string;
73
- severity: string;
74
- }>;
75
- healthScore?: number;
76
- }
77
- /**
78
- * Creates a JSON output for the scan results.
79
- * @param scanResult - The result of the scan.
80
- * @param comparedAgainst - The file being compared against.
81
- * @returns The JSON output.
82
- */
83
- export declare function createJsonOutput(scanResult: ScanResult, comparedAgainst: string): ScanJsonOutput;
84
- export {};
85
- //# sourceMappingURL=scanJsonOutput.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scanJsonOutput.d.ts","sourceRoot":"","sources":["../../../src/core/scanJsonOutput.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAEV,SAAS,EACT,kBAAkB,EACnB,MAAM,oBAAoB,CAAC;AAI5B;;GAEG;AACH,UAAU,cAAc;IACtB,KAAK,CAAC,EAAE;QACN,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,MAAM,CAAC;QACxB,aAAa,EAAE,MAAM,CAAC;QACtB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,OAAO,CAAC,EAAE,KAAK,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,KAAK,CAAC;YACZ,IAAI,EAAE,MAAM,CAAC;YACb,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,CAAC;YAChB,OAAO,EAAE,MAAM,CAAC;SACjB,CAAC,CAAC;KACJ,CAAC,CAAC;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,KAAK,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,UAAU,CAAC,EAAE;QACX,GAAG,CAAC,EAAE,SAAS,EAAE,CAAC;QAClB,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;KACvB,CAAC;IACF,MAAM,CAAC,EAAE,KAAK,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,cAAc,CAAC,EAAE,KAAK,CAAC;QACrB,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;IACH,iBAAiB,CAAC,EAAE,KAAK,CAAC;QACxB,GAAG,EAAE,MAAM,CAAC;QACZ,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IACH,0BAA0B,CAAC,EAAE,KAAK,CAAC;QACjC,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IACH,iBAAiB,CAAC,EAAE,KAAK,CAAC;QACxB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,kBAAkB,CAAC;KAC/B,CAAC,CAAC;IACH,eAAe,CAAC,EAAE,KAAK,CAAC;QACtB,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,MAAM,GACtB,cAAc,CAwGhB"}
@@ -1,97 +0,0 @@
1
- import { computeHealthScore } from './computeHealthScore.js';
2
- import { normalizePath } from './helpers/normalizePath.js';
3
- /**
4
- * Creates a JSON output for the scan results.
5
- * @param scanResult - The result of the scan.
6
- * @param comparedAgainst - The file being compared against.
7
- * @returns The JSON output.
8
- */
9
- export function createJsonOutput(scanResult, comparedAgainst) {
10
- const output = {};
11
- // Add comparison info if we compared against a file
12
- if (comparedAgainst) {
13
- output.comparedAgainst = comparedAgainst;
14
- }
15
- output.stats = scanResult.stats;
16
- if (scanResult.secrets?.length) {
17
- output.secrets = scanResult.secrets.map((s) => ({
18
- file: normalizePath(s.file),
19
- line: s.line,
20
- message: s.message,
21
- snippet: s.snippet,
22
- }));
23
- }
24
- if (scanResult.missing?.length) {
25
- const missingSet = new Set(scanResult.missing);
26
- const usagesByVariable = new Map();
27
- for (const usage of scanResult.used) {
28
- if (missingSet.has(usage.variable)) {
29
- const existing = usagesByVariable.get(usage.variable) ?? [];
30
- existing.push(usage);
31
- usagesByVariable.set(usage.variable, existing);
32
- }
33
- }
34
- output.missing = scanResult.missing.map((variable) => ({
35
- variable,
36
- usages: (usagesByVariable.get(variable) ?? []).map((u) => ({
37
- file: normalizePath(u.file),
38
- line: u.line,
39
- pattern: u.pattern,
40
- context: u.context,
41
- })),
42
- }));
43
- }
44
- if (scanResult.unused?.length) {
45
- output.unused = scanResult.unused;
46
- }
47
- if (scanResult.uppercaseWarnings?.length) {
48
- output.uppercaseWarnings = scanResult.uppercaseWarnings.map((w) => ({
49
- key: w.key,
50
- suggestion: w.suggestion,
51
- }));
52
- }
53
- if (scanResult.inconsistentNamingWarnings?.length) {
54
- output.inconsistentNamingWarnings =
55
- scanResult.inconsistentNamingWarnings.map((w) => ({
56
- key1: w.key1,
57
- key2: w.key2,
58
- suggestion: w.suggestion,
59
- }));
60
- }
61
- if (scanResult.frameworkWarnings?.length) {
62
- output.frameworkWarnings = scanResult.frameworkWarnings.map((w) => ({
63
- variable: w.variable,
64
- reason: w.reason,
65
- file: normalizePath(w.file),
66
- line: w.line,
67
- framework: w.framework,
68
- }));
69
- }
70
- const hasDuplicates = (scanResult.duplicates.env?.length ?? 0) > 0 ||
71
- (scanResult.duplicates.example?.length ?? 0) > 0;
72
- if (hasDuplicates) {
73
- output.duplicates = scanResult.duplicates;
74
- }
75
- // Add logged variables if any
76
- if (scanResult.logged?.length) {
77
- output.logged = scanResult.logged.map((l) => ({
78
- variable: l.variable,
79
- file: normalizePath(l.file),
80
- line: l.line,
81
- context: l.context,
82
- }));
83
- }
84
- // Example warnings
85
- if (scanResult.exampleWarnings?.length) {
86
- output.exampleWarnings = scanResult.exampleWarnings.map((w) => ({
87
- key: w.key,
88
- value: w.value,
89
- reason: w.reason,
90
- severity: w.severity,
91
- }));
92
- }
93
- const healthScore = computeHealthScore(scanResult);
94
- output.healthScore = healthScore;
95
- return output;
96
- }
97
- //# sourceMappingURL=scanJsonOutput.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scanJsonOutput.js","sourceRoot":"","sources":["../../../src/core/scanJsonOutput.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AA8E3D;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,UAAsB,EACtB,eAAuB;IAEvB,MAAM,MAAM,GAAmB,EAAE,CAAC;IAElC,oDAAoD;IACpD,IAAI,eAAe,EAAE,CAAC;QACpB,MAAM,CAAC,eAAe,GAAG,eAAe,CAAC;IAC3C,CAAC;IAED,MAAM,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC;IAEhC,IAAI,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;QAC/B,MAAM,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC9C,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;YAC3B,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,OAAO,EAAE,CAAC,CAAC,OAAO;SACnB,CAAC,CAAC,CAAC;IACN,CAAC;IAED,IAAI,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;QAC/B,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAsB,CAAC;QAEvD,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;YACpC,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACnC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAC5D,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACrB,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;QAED,MAAM,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YACrD,QAAQ;YACR,MAAM,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACzD,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;gBAC3B,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,OAAO,EAAE,CAAC,CAAC,OAAO;gBAClB,OAAO,EAAE,CAAC,CAAC,OAAO;aACnB,CAAC,CAAC;SACJ,CAAC,CAAC,CAAC;IACN,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QAC9B,MAAM,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IACpC,CAAC;IAED,IAAI,UAAU,CAAC,iBAAiB,EAAE,MAAM,EAAE,CAAC;QACzC,MAAM,CAAC,iBAAiB,GAAG,UAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAClE,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,UAAU,EAAE,CAAC,CAAC,UAAU;SACzB,CAAC,CAAC,CAAC;IACN,CAAC;IAED,IAAI,UAAU,CAAC,0BAA0B,EAAE,MAAM,EAAE,CAAC;QAClD,MAAM,CAAC,0BAA0B;YAC/B,UAAU,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAChD,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,UAAU,EAAE,CAAC,CAAC,UAAU;aACzB,CAAC,CAAC,CAAC;IACR,CAAC;IAED,IAAI,UAAU,CAAC,iBAAiB,EAAE,MAAM,EAAE,CAAC;QACzC,MAAM,CAAC,iBAAiB,GAAG,UAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAClE,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;YAC3B,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,SAAS,EAAE,CAAC,CAAC,SAAS;SACvB,CAAC,CAAC,CAAC;IACN,CAAC;IAED,MAAM,aAAa,GACjB,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC;QAC5C,CAAC,UAAU,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAEnD,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,CAAC,UAAU,GAAG,UAAU,CAAC,UAAU,CAAC;IAC5C,CAAC;IAED,8BAA8B;IAC9B,IAAI,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QAC9B,MAAM,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC5C,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;YAC3B,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,CAAC,CAAC,OAAO;SACnB,CAAC,CAAC,CAAC;IACN,CAAC;IAED,mBAAmB;IACnB,IAAI,UAAU,CAAC,eAAe,EAAE,MAAM,EAAE,CAAC;QACvC,MAAM,CAAC,eAAe,GAAG,UAAU,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC9D,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,QAAQ,EAAE,CAAC,CAAC,QAAQ;SACrB,CAAC,CAAC,CAAC;IACN,CAAC;IAED,MAAM,WAAW,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IACnD,MAAM,CAAC,WAAW,GAAG,WAAW,CAAC;IAEjC,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -1,28 +0,0 @@
1
- export type SecretSeverity = 'high' | 'medium' | 'low';
2
- export type SecretFinding = {
3
- file: string;
4
- line: number;
5
- kind: 'pattern' | 'entropy';
6
- message: string;
7
- snippet: string;
8
- severity: SecretSeverity;
9
- };
10
- export declare const SUSPICIOUS_KEYS: RegExp;
11
- export declare const PROVIDER_PATTERNS: RegExp[];
12
- /**
13
- * Checks if a line has an ignore comment
14
- * fx: // dotenv-diff-ignore or /* dotenv-diff-ignore *\/ or <!-- dotenv-diff-ignore -->
15
- * @param line - The line to check
16
- * @returns True if the line should be ignored
17
- */
18
- export declare function hasIgnoreComment(line: string): boolean;
19
- /**
20
- * Detects secrets in the source code of a file.
21
- * @param file - The file path to check.
22
- * @param source - The source code to scan for secrets.
23
- * @returns An array of secret findings.
24
- */
25
- export declare function detectSecretsInSource(file: string, source: string, opts?: {
26
- ignoreUrls?: string[];
27
- }): SecretFinding[];
28
- //# sourceMappingURL=secretDetectors.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"secretDetectors.d.ts","sourceRoot":"","sources":["../../../src/core/secretDetectors.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAGvD,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;IAChB,QAAQ,EAAE,cAAc,CAAC;CAC1B,CAAC;AAGF,eAAO,MAAM,eAAe,QAC6E,CAAC;AAG1G,eAAO,MAAM,iBAAiB,EAAE,MAAM,EAYrC,CAAC;AAiEF;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAUtD;AAmGD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAC/B,aAAa,EAAE,CA4HjB"}