dotenv-diff 2.7.9 → 2.7.10

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 (393) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/src/commands/compare.js +1 -1
  3. package/dist/src/commands/compare.js.map +1 -1
  4. package/dist/src/commands/prompts/promptEnsureFiles.d.ts.map +1 -1
  5. package/dist/src/commands/prompts/promptEnsureFiles.js +10 -5
  6. package/dist/src/commands/prompts/promptEnsureFiles.js.map +1 -1
  7. package/dist/src/commands/scanUsage.js +9 -9
  8. package/dist/src/commands/scanUsage.js.map +1 -1
  9. package/dist/src/config/types.d.ts +2 -1
  10. package/dist/src/config/types.d.ts.map +1 -1
  11. package/dist/src/core/fixEnv.d.ts.map +1 -1
  12. package/dist/src/core/fixEnv.js +8 -5
  13. package/dist/src/core/fixEnv.js.map +1 -1
  14. package/dist/src/core/helpers/isLikelyMinified.d.ts +2 -0
  15. package/dist/src/core/helpers/isLikelyMinified.d.ts.map +1 -1
  16. package/dist/src/core/helpers/isLikelyMinified.js +2 -0
  17. package/dist/src/core/helpers/isLikelyMinified.js.map +1 -1
  18. package/dist/src/core/scan/patterns.d.ts +9 -1
  19. package/dist/src/core/scan/patterns.d.ts.map +1 -1
  20. package/dist/src/core/scan/patterns.js +32 -0
  21. package/dist/src/core/scan/patterns.js.map +1 -1
  22. package/dist/src/core/scan/scanFile.d.ts.map +1 -1
  23. package/dist/src/core/scan/scanFile.js +9 -2
  24. package/dist/src/core/scan/scanFile.js.map +1 -1
  25. package/dist/src/core/security/secretDetectors.js +1 -1
  26. package/dist/src/core/security/secretDetectors.js.map +1 -1
  27. package/dist/src/services/detectEnvExpirations.js +0 -2
  28. package/dist/src/services/detectEnvExpirations.js.map +1 -1
  29. package/dist/src/services/envDiscovery.js +6 -6
  30. package/dist/src/services/envDiscovery.js.map +1 -1
  31. package/dist/src/services/processComparisonFile.d.ts +1 -2
  32. package/dist/src/services/processComparisonFile.d.ts.map +1 -1
  33. package/dist/test/e2e/cli.autoscan.e2e.test.d.ts +2 -0
  34. package/dist/test/e2e/cli.autoscan.e2e.test.d.ts.map +1 -0
  35. package/dist/test/e2e/cli.autoscan.e2e.test.js +263 -0
  36. package/dist/test/e2e/cli.autoscan.e2e.test.js.map +1 -0
  37. package/dist/test/e2e/cli.compare.e2e.test.d.ts +2 -0
  38. package/dist/test/e2e/cli.compare.e2e.test.d.ts.map +1 -0
  39. package/dist/test/e2e/cli.compare.e2e.test.js +94 -0
  40. package/dist/test/e2e/cli.compare.e2e.test.js.map +1 -0
  41. package/dist/test/e2e/cli.detectExpired.e2e.test.d.ts +2 -0
  42. package/dist/test/e2e/cli.detectExpired.e2e.test.d.ts.map +1 -0
  43. package/dist/test/e2e/cli.detectExpired.e2e.test.js +148 -0
  44. package/dist/test/e2e/cli.detectExpired.e2e.test.js.map +1 -0
  45. package/dist/test/e2e/cli.flags.e2e.test.d.ts +2 -0
  46. package/dist/test/e2e/cli.flags.e2e.test.d.ts.map +1 -0
  47. package/dist/test/e2e/cli.flags.e2e.test.js +424 -0
  48. package/dist/test/e2e/cli.flags.e2e.test.js.map +1 -0
  49. package/dist/test/e2e/cli.healthscore.test.d.ts +2 -0
  50. package/dist/test/e2e/cli.healthscore.test.d.ts.map +1 -0
  51. package/dist/test/e2e/cli.healthscore.test.js +79 -0
  52. package/dist/test/e2e/cli.healthscore.test.js.map +1 -0
  53. package/dist/test/e2e/cli.ignore.e2e.test.d.ts +2 -0
  54. package/dist/test/e2e/cli.ignore.e2e.test.d.ts.map +1 -0
  55. package/dist/test/e2e/cli.ignore.e2e.test.js +88 -0
  56. package/dist/test/e2e/cli.ignore.e2e.test.js.map +1 -0
  57. package/dist/test/e2e/cli.inconsistentNaming.e2e.test.d.ts +2 -0
  58. package/dist/test/e2e/cli.inconsistentNaming.e2e.test.d.ts.map +1 -0
  59. package/dist/test/e2e/cli.inconsistentNaming.e2e.test.js +94 -0
  60. package/dist/test/e2e/cli.inconsistentNaming.e2e.test.js.map +1 -0
  61. package/dist/test/e2e/cli.jsonOutput.e2e.test.d.ts +2 -0
  62. package/dist/test/e2e/cli.jsonOutput.e2e.test.d.ts.map +1 -0
  63. package/dist/test/e2e/cli.jsonOutput.e2e.test.js +39 -0
  64. package/dist/test/e2e/cli.jsonOutput.e2e.test.js.map +1 -0
  65. package/dist/test/e2e/cli.loggedWarnings.e2e.test.d.ts +2 -0
  66. package/dist/test/e2e/cli.loggedWarnings.e2e.test.d.ts.map +1 -0
  67. package/dist/test/e2e/cli.loggedWarnings.e2e.test.js +118 -0
  68. package/dist/test/e2e/cli.loggedWarnings.e2e.test.js.map +1 -0
  69. package/dist/test/e2e/cli.secrets.e2e.test.d.ts +2 -0
  70. package/dist/test/e2e/cli.secrets.e2e.test.d.ts.map +1 -0
  71. package/dist/test/e2e/cli.secrets.e2e.test.js +344 -0
  72. package/dist/test/e2e/cli.secrets.e2e.test.js.map +1 -0
  73. package/dist/test/e2e/cli.strict.e2e.test.d.ts +2 -0
  74. package/dist/test/e2e/cli.strict.e2e.test.d.ts.map +1 -0
  75. package/dist/test/e2e/cli.strict.e2e.test.js +76 -0
  76. package/dist/test/e2e/cli.strict.e2e.test.js.map +1 -0
  77. package/dist/test/e2e/cli.uppercaseWarnings.e2e.test.d.ts +2 -0
  78. package/dist/test/e2e/cli.uppercaseWarnings.e2e.test.d.ts.map +1 -0
  79. package/dist/test/e2e/cli.uppercaseWarnings.e2e.test.js +59 -0
  80. package/dist/test/e2e/cli.uppercaseWarnings.e2e.test.js.map +1 -0
  81. package/dist/test/e2e/cli.warningsCount.e2e.test.d.ts +2 -0
  82. package/dist/test/e2e/cli.warningsCount.e2e.test.d.ts.map +1 -0
  83. package/dist/test/e2e/cli.warningsCount.e2e.test.js +54 -0
  84. package/dist/test/e2e/cli.warningsCount.e2e.test.js.map +1 -0
  85. package/dist/test/e2e/frameworks/cli.nextJs.e2e.test.d.ts +2 -0
  86. package/dist/test/e2e/frameworks/cli.nextJs.e2e.test.d.ts.map +1 -0
  87. package/dist/test/e2e/frameworks/cli.nextJs.e2e.test.js +182 -0
  88. package/dist/test/e2e/frameworks/cli.nextJs.e2e.test.js.map +1 -0
  89. package/dist/test/e2e/frameworks/cli.sveltekit.e2e.test.d.ts +2 -0
  90. package/dist/test/e2e/frameworks/cli.sveltekit.e2e.test.d.ts.map +1 -0
  91. package/dist/test/e2e/frameworks/cli.sveltekit.e2e.test.js +333 -0
  92. package/dist/test/e2e/frameworks/cli.sveltekit.e2e.test.js.map +1 -0
  93. package/dist/test/integration/compare-flow.integration.test.d.ts +2 -0
  94. package/dist/test/integration/compare-flow.integration.test.d.ts.map +1 -0
  95. package/dist/test/integration/compare-flow.integration.test.js +26 -0
  96. package/dist/test/integration/compare-flow.integration.test.js.map +1 -0
  97. package/dist/test/unit/cli/program.test.d.ts +2 -0
  98. package/dist/test/unit/cli/program.test.d.ts.map +1 -0
  99. package/dist/test/unit/cli/program.test.js +49 -0
  100. package/dist/test/unit/cli/program.test.js.map +1 -0
  101. package/dist/test/unit/cli/run.test.d.ts +2 -0
  102. package/dist/test/unit/cli/run.test.d.ts.map +1 -0
  103. package/dist/test/unit/cli/run.test.js +331 -0
  104. package/dist/test/unit/cli/run.test.js.map +1 -0
  105. package/dist/test/unit/commands/compare.test.d.ts +2 -0
  106. package/dist/test/unit/commands/compare.test.d.ts.map +1 -0
  107. package/dist/test/unit/commands/compare.test.js +664 -0
  108. package/dist/test/unit/commands/compare.test.js.map +1 -0
  109. package/dist/test/unit/commands/init.test.d.ts +2 -0
  110. package/dist/test/unit/commands/init.test.d.ts.map +1 -0
  111. package/dist/test/unit/commands/init.test.js +54 -0
  112. package/dist/test/unit/commands/init.test.js.map +1 -0
  113. package/dist/test/unit/commands/prompts/promptEnsureFiles.test.d.ts +2 -0
  114. package/dist/test/unit/commands/prompts/promptEnsureFiles.test.d.ts.map +1 -0
  115. package/dist/test/unit/commands/prompts/promptEnsureFiles.test.js +225 -0
  116. package/dist/test/unit/commands/prompts/promptEnsureFiles.test.js.map +1 -0
  117. package/dist/test/unit/commands/prompts/promptNoEnvScenario.test.d.ts +2 -0
  118. package/dist/test/unit/commands/prompts/promptNoEnvScenario.test.d.ts.map +1 -0
  119. package/dist/test/unit/commands/prompts/promptNoEnvScenario.test.js +109 -0
  120. package/dist/test/unit/commands/prompts/promptNoEnvScenario.test.js.map +1 -0
  121. package/dist/test/unit/commands/prompts/prompts.test.d.ts +2 -0
  122. package/dist/test/unit/commands/prompts/prompts.test.d.ts.map +1 -0
  123. package/dist/test/unit/commands/prompts/prompts.test.js +75 -0
  124. package/dist/test/unit/commands/prompts/prompts.test.js.map +1 -0
  125. package/dist/test/unit/commands/scanUsage.test.d.ts +2 -0
  126. package/dist/test/unit/commands/scanUsage.test.d.ts.map +1 -0
  127. package/dist/test/unit/commands/scanUsage.test.js +639 -0
  128. package/dist/test/unit/commands/scanUsage.test.js.map +1 -0
  129. package/dist/test/unit/config/loadConfig.test.d.ts +2 -0
  130. package/dist/test/unit/config/loadConfig.test.d.ts.map +1 -0
  131. package/dist/test/unit/config/loadConfig.test.js +106 -0
  132. package/dist/test/unit/config/loadConfig.test.js.map +1 -0
  133. package/dist/test/unit/config/options.test.d.ts +2 -0
  134. package/dist/test/unit/config/options.test.d.ts.map +1 -0
  135. package/dist/test/unit/config/options.test.js +69 -0
  136. package/dist/test/unit/config/options.test.js.map +1 -0
  137. package/dist/test/unit/core/compare/calculateStats.test.d.ts +2 -0
  138. package/dist/test/unit/core/compare/calculateStats.test.d.ts.map +1 -0
  139. package/dist/test/unit/core/compare/calculateStats.test.js +33 -0
  140. package/dist/test/unit/core/compare/calculateStats.test.js.map +1 -0
  141. package/dist/test/unit/core/compare/parseAndFilterEnv.test.d.ts +2 -0
  142. package/dist/test/unit/core/compare/parseAndFilterEnv.test.d.ts.map +1 -0
  143. package/dist/test/unit/core/compare/parseAndFilterEnv.test.js +227 -0
  144. package/dist/test/unit/core/compare/parseAndFilterEnv.test.js.map +1 -0
  145. package/dist/test/unit/core/compare/updateTotals.test.d.ts +2 -0
  146. package/dist/test/unit/core/compare/updateTotals.test.d.ts.map +1 -0
  147. package/dist/test/unit/core/compare/updateTotals.test.js +106 -0
  148. package/dist/test/unit/core/compare/updateTotals.test.js.map +1 -0
  149. package/dist/test/unit/core/detectInconsistentNaming.test.d.ts +2 -0
  150. package/dist/test/unit/core/detectInconsistentNaming.test.d.ts.map +1 -0
  151. package/dist/test/unit/core/detectInconsistentNaming.test.js +79 -0
  152. package/dist/test/unit/core/detectInconsistentNaming.test.js.map +1 -0
  153. package/dist/test/unit/core/diffEnv.test.d.ts +2 -0
  154. package/dist/test/unit/core/diffEnv.test.d.ts.map +1 -0
  155. package/dist/test/unit/core/diffEnv.test.js +74 -0
  156. package/dist/test/unit/core/diffEnv.test.js.map +1 -0
  157. package/dist/test/unit/core/duplicates.unit.test.d.ts +2 -0
  158. package/dist/test/unit/core/duplicates.unit.test.d.ts.map +1 -0
  159. package/dist/test/unit/core/duplicates.unit.test.js +91 -0
  160. package/dist/test/unit/core/duplicates.unit.test.js.map +1 -0
  161. package/dist/test/unit/core/filterIgnoredKeys.test.d.ts +2 -0
  162. package/dist/test/unit/core/filterIgnoredKeys.test.d.ts.map +1 -0
  163. package/dist/test/unit/core/filterIgnoredKeys.test.js +61 -0
  164. package/dist/test/unit/core/filterIgnoredKeys.test.js.map +1 -0
  165. package/dist/test/unit/core/fixEnv.test.d.ts +2 -0
  166. package/dist/test/unit/core/fixEnv.test.d.ts.map +1 -0
  167. package/dist/test/unit/core/fixEnv.test.js +323 -0
  168. package/dist/test/unit/core/fixEnv.test.js.map +1 -0
  169. package/dist/test/unit/core/frameworks/frameworkDetector.test.d.ts +2 -0
  170. package/dist/test/unit/core/frameworks/frameworkDetector.test.d.ts.map +1 -0
  171. package/dist/test/unit/core/frameworks/frameworkDetector.test.js +44 -0
  172. package/dist/test/unit/core/frameworks/frameworkDetector.test.js.map +1 -0
  173. package/dist/test/unit/core/frameworks/frameworkValidator.test.d.ts +2 -0
  174. package/dist/test/unit/core/frameworks/frameworkValidator.test.d.ts.map +1 -0
  175. package/dist/test/unit/core/frameworks/frameworkValidator.test.js +51 -0
  176. package/dist/test/unit/core/frameworks/frameworkValidator.test.js.map +1 -0
  177. package/dist/test/unit/core/frameworks/nextJsRules.test.d.ts +2 -0
  178. package/dist/test/unit/core/frameworks/nextJsRules.test.d.ts.map +1 -0
  179. package/dist/test/unit/core/frameworks/nextJsRules.test.js +97 -0
  180. package/dist/test/unit/core/frameworks/nextJsRules.test.js.map +1 -0
  181. package/dist/test/unit/core/frameworks/sveltekitRules.test.d.ts +2 -0
  182. package/dist/test/unit/core/frameworks/sveltekitRules.test.d.ts.map +1 -0
  183. package/dist/test/unit/core/frameworks/sveltekitRules.test.js +177 -0
  184. package/dist/test/unit/core/frameworks/sveltekitRules.test.js.map +1 -0
  185. package/dist/test/unit/core/helpers/resolveFromCwd.test.d.ts +2 -0
  186. package/dist/test/unit/core/helpers/resolveFromCwd.test.d.ts.map +1 -0
  187. package/dist/test/unit/core/helpers/resolveFromCwd.test.js +35 -0
  188. package/dist/test/unit/core/helpers/resolveFromCwd.test.js.map +1 -0
  189. package/dist/test/unit/core/helpers/toUpperSnakeCase.test.d.ts +2 -0
  190. package/dist/test/unit/core/helpers/toUpperSnakeCase.test.d.ts.map +1 -0
  191. package/dist/test/unit/core/helpers/toUpperSnakeCase.test.js +47 -0
  192. package/dist/test/unit/core/helpers/toUpperSnakeCase.test.js.map +1 -0
  193. package/dist/test/unit/core/parseEnv.test.d.ts +2 -0
  194. package/dist/test/unit/core/parseEnv.test.d.ts.map +1 -0
  195. package/dist/test/unit/core/parseEnv.test.js +169 -0
  196. package/dist/test/unit/core/parseEnv.test.js.map +1 -0
  197. package/dist/test/unit/core/scan/compareScan.test.d.ts +2 -0
  198. package/dist/test/unit/core/scan/compareScan.test.d.ts.map +1 -0
  199. package/dist/test/unit/core/scan/compareScan.test.js +40 -0
  200. package/dist/test/unit/core/scan/compareScan.test.js.map +1 -0
  201. package/dist/test/unit/core/scan/computeHealthScore.test.d.ts +2 -0
  202. package/dist/test/unit/core/scan/computeHealthScore.test.d.ts.map +1 -0
  203. package/dist/test/unit/core/scan/computeHealthScore.test.js +41 -0
  204. package/dist/test/unit/core/scan/computeHealthScore.test.js.map +1 -0
  205. package/dist/test/unit/core/scan/determineComparisonFile.test.d.ts +2 -0
  206. package/dist/test/unit/core/scan/determineComparisonFile.test.d.ts.map +1 -0
  207. package/dist/test/unit/core/scan/determineComparisonFile.test.js +162 -0
  208. package/dist/test/unit/core/scan/determineComparisonFile.test.js.map +1 -0
  209. package/dist/test/unit/core/scan/patterns.test.d.ts +2 -0
  210. package/dist/test/unit/core/scan/patterns.test.d.ts.map +1 -0
  211. package/dist/test/unit/core/scan/patterns.test.js +483 -0
  212. package/dist/test/unit/core/scan/patterns.test.js.map +1 -0
  213. package/dist/test/unit/core/scan/scanFile.test.d.ts +2 -0
  214. package/dist/test/unit/core/scan/scanFile.test.d.ts.map +1 -0
  215. package/dist/test/unit/core/scan/scanFile.test.js +258 -0
  216. package/dist/test/unit/core/scan/scanFile.test.js.map +1 -0
  217. package/dist/test/unit/core/security/entropy.test.d.ts +2 -0
  218. package/dist/test/unit/core/security/entropy.test.d.ts.map +1 -0
  219. package/dist/test/unit/core/security/entropy.test.js +34 -0
  220. package/dist/test/unit/core/security/entropy.test.js.map +1 -0
  221. package/dist/test/unit/core/security/exampleSecretDetector.test.d.ts +2 -0
  222. package/dist/test/unit/core/security/exampleSecretDetector.test.d.ts.map +1 -0
  223. package/dist/test/unit/core/security/exampleSecretDetector.test.js +57 -0
  224. package/dist/test/unit/core/security/exampleSecretDetector.test.js.map +1 -0
  225. package/dist/test/unit/core/security/secretDetectors.test.d.ts +2 -0
  226. package/dist/test/unit/core/security/secretDetectors.test.d.ts.map +1 -0
  227. package/dist/test/unit/core/security/secretDetectors.test.js +490 -0
  228. package/dist/test/unit/core/security/secretDetectors.test.js.map +1 -0
  229. package/dist/test/unit/index.test.d.ts +2 -0
  230. package/dist/test/unit/index.test.d.ts.map +1 -0
  231. package/dist/test/unit/index.test.js +17 -0
  232. package/dist/test/unit/index.test.js.map +1 -0
  233. package/dist/test/unit/services/detectEnvExpirations.test.d.ts +2 -0
  234. package/dist/test/unit/services/detectEnvExpirations.test.d.ts.map +1 -0
  235. package/dist/test/unit/services/detectEnvExpirations.test.js +120 -0
  236. package/dist/test/unit/services/detectEnvExpirations.test.js.map +1 -0
  237. package/dist/test/unit/services/envDiscovery.test.d.ts +2 -0
  238. package/dist/test/unit/services/envDiscovery.test.d.ts.map +1 -0
  239. package/dist/test/unit/services/envDiscovery.test.js +177 -0
  240. package/dist/test/unit/services/envDiscovery.test.js.map +1 -0
  241. package/dist/test/unit/services/envPairing.test.d.ts +2 -0
  242. package/dist/test/unit/services/envPairing.test.d.ts.map +1 -0
  243. package/dist/test/unit/services/envPairing.test.js +103 -0
  244. package/dist/test/unit/services/envPairing.test.js.map +1 -0
  245. package/dist/test/unit/services/filewalker.test.d.ts +2 -0
  246. package/dist/test/unit/services/filewalker.test.d.ts.map +1 -0
  247. package/dist/test/unit/services/filewalker.test.js +422 -0
  248. package/dist/test/unit/services/filewalker.test.js.map +1 -0
  249. package/dist/test/unit/services/git.test.d.ts +2 -0
  250. package/dist/test/unit/services/git.test.d.ts.map +1 -0
  251. package/dist/test/unit/services/git.test.js +357 -0
  252. package/dist/test/unit/services/git.test.js.map +1 -0
  253. package/dist/test/unit/services/printScanResult.test.d.ts +2 -0
  254. package/dist/test/unit/services/printScanResult.test.d.ts.map +1 -0
  255. package/dist/test/unit/services/printScanResult.test.js +275 -0
  256. package/dist/test/unit/services/printScanResult.test.js.map +1 -0
  257. package/dist/test/unit/services/processComparisonFile.test.d.ts +2 -0
  258. package/dist/test/unit/services/processComparisonFile.test.d.ts.map +1 -0
  259. package/dist/test/unit/services/processComparisonFile.test.js +261 -0
  260. package/dist/test/unit/services/processComparisonFile.test.js.map +1 -0
  261. package/dist/test/unit/services/scanCodebase.test.d.ts +2 -0
  262. package/dist/test/unit/services/scanCodebase.test.d.ts.map +1 -0
  263. package/dist/test/unit/services/scanCodebase.test.js +433 -0
  264. package/dist/test/unit/services/scanCodebase.test.js.map +1 -0
  265. package/dist/test/unit/ui/compare/compareJsonOutput.test.d.ts +2 -0
  266. package/dist/test/unit/ui/compare/compareJsonOutput.test.d.ts.map +1 -0
  267. package/dist/test/unit/ui/compare/compareJsonOutput.test.js +137 -0
  268. package/dist/test/unit/ui/compare/compareJsonOutput.test.js.map +1 -0
  269. package/dist/test/unit/ui/compare/printErrorNotFound.test.d.ts +2 -0
  270. package/dist/test/unit/ui/compare/printErrorNotFound.test.d.ts.map +1 -0
  271. package/dist/test/unit/ui/compare/printErrorNotFound.test.js +36 -0
  272. package/dist/test/unit/ui/compare/printErrorNotFound.test.js.map +1 -0
  273. package/dist/test/unit/ui/compare/printHeader.test.d.ts +2 -0
  274. package/dist/test/unit/ui/compare/printHeader.test.d.ts.map +1 -0
  275. package/dist/test/unit/ui/compare/printHeader.test.js +23 -0
  276. package/dist/test/unit/ui/compare/printHeader.test.js.map +1 -0
  277. package/dist/test/unit/ui/compare/printIssues.test.d.ts +2 -0
  278. package/dist/test/unit/ui/compare/printIssues.test.d.ts.map +1 -0
  279. package/dist/test/unit/ui/compare/printIssues.test.js +69 -0
  280. package/dist/test/unit/ui/compare/printIssues.test.js.map +1 -0
  281. package/dist/test/unit/ui/compare/printPrompt.test.d.ts +2 -0
  282. package/dist/test/unit/ui/compare/printPrompt.test.d.ts.map +1 -0
  283. package/dist/test/unit/ui/compare/printPrompt.test.js +40 -0
  284. package/dist/test/unit/ui/compare/printPrompt.test.js.map +1 -0
  285. package/dist/test/unit/ui/compare/printStats.test.d.ts +2 -0
  286. package/dist/test/unit/ui/compare/printStats.test.d.ts.map +1 -0
  287. package/dist/test/unit/ui/compare/printStats.test.js +52 -0
  288. package/dist/test/unit/ui/compare/printStats.test.js.map +1 -0
  289. package/dist/test/unit/ui/scan/printComparisonError.test.d.ts +2 -0
  290. package/dist/test/unit/ui/scan/printComparisonError.test.d.ts.map +1 -0
  291. package/dist/test/unit/ui/scan/printComparisonError.test.js +28 -0
  292. package/dist/test/unit/ui/scan/printComparisonError.test.js.map +1 -0
  293. package/dist/test/unit/ui/scan/printConsolelogWarning.test.d.ts +2 -0
  294. package/dist/test/unit/ui/scan/printConsolelogWarning.test.d.ts.map +1 -0
  295. package/dist/test/unit/ui/scan/printConsolelogWarning.test.js +118 -0
  296. package/dist/test/unit/ui/scan/printConsolelogWarning.test.js.map +1 -0
  297. package/dist/test/unit/ui/scan/printExampleWarnings.test.d.ts +2 -0
  298. package/dist/test/unit/ui/scan/printExampleWarnings.test.d.ts.map +1 -0
  299. package/dist/test/unit/ui/scan/printExampleWarnings.test.js +63 -0
  300. package/dist/test/unit/ui/scan/printExampleWarnings.test.js.map +1 -0
  301. package/dist/test/unit/ui/scan/printExpireWarnings.test.d.ts +2 -0
  302. package/dist/test/unit/ui/scan/printExpireWarnings.test.d.ts.map +1 -0
  303. package/dist/test/unit/ui/scan/printExpireWarnings.test.js +100 -0
  304. package/dist/test/unit/ui/scan/printExpireWarnings.test.js.map +1 -0
  305. package/dist/test/unit/ui/scan/printFrameworkWarnings.test.d.ts +2 -0
  306. package/dist/test/unit/ui/scan/printFrameworkWarnings.test.d.ts.map +1 -0
  307. package/dist/test/unit/ui/scan/printFrameworkWarnings.test.js +95 -0
  308. package/dist/test/unit/ui/scan/printFrameworkWarnings.test.js.map +1 -0
  309. package/dist/test/unit/ui/scan/printHeader.test.d.ts +2 -0
  310. package/dist/test/unit/ui/scan/printHeader.test.d.ts.map +1 -0
  311. package/dist/test/unit/ui/scan/printHeader.test.js +23 -0
  312. package/dist/test/unit/ui/scan/printHeader.test.js.map +1 -0
  313. package/dist/test/unit/ui/scan/printHealthScore.test.d.ts +2 -0
  314. package/dist/test/unit/ui/scan/printHealthScore.test.d.ts.map +1 -0
  315. package/dist/test/unit/ui/scan/printHealthScore.test.js +44 -0
  316. package/dist/test/unit/ui/scan/printHealthScore.test.js.map +1 -0
  317. package/dist/test/unit/ui/scan/printInconsistentNamingWarning.test.d.ts +2 -0
  318. package/dist/test/unit/ui/scan/printInconsistentNamingWarning.test.d.ts.map +1 -0
  319. package/dist/test/unit/ui/scan/printInconsistentNamingWarning.test.js +55 -0
  320. package/dist/test/unit/ui/scan/printInconsistentNamingWarning.test.js.map +1 -0
  321. package/dist/test/unit/ui/scan/printMissing.test.d.ts +2 -0
  322. package/dist/test/unit/ui/scan/printMissing.test.d.ts.map +1 -0
  323. package/dist/test/unit/ui/scan/printMissing.test.js +71 -0
  324. package/dist/test/unit/ui/scan/printMissing.test.js.map +1 -0
  325. package/dist/test/unit/ui/scan/printMissingExample.test.d.ts +2 -0
  326. package/dist/test/unit/ui/scan/printMissingExample.test.d.ts.map +1 -0
  327. package/dist/test/unit/ui/scan/printMissingExample.test.js +77 -0
  328. package/dist/test/unit/ui/scan/printMissingExample.test.js.map +1 -0
  329. package/dist/test/unit/ui/scan/printSecrets.test.d.ts +2 -0
  330. package/dist/test/unit/ui/scan/printSecrets.test.d.ts.map +1 -0
  331. package/dist/test/unit/ui/scan/printSecrets.test.js +108 -0
  332. package/dist/test/unit/ui/scan/printSecrets.test.js.map +1 -0
  333. package/dist/test/unit/ui/scan/printStats.test.d.ts +2 -0
  334. package/dist/test/unit/ui/scan/printStats.test.d.ts.map +1 -0
  335. package/dist/test/unit/ui/scan/printStats.test.js +42 -0
  336. package/dist/test/unit/ui/scan/printStats.test.js.map +1 -0
  337. package/dist/test/unit/ui/scan/printUnused.test.d.ts +2 -0
  338. package/dist/test/unit/ui/scan/printUnused.test.d.ts.map +1 -0
  339. package/dist/test/unit/ui/scan/printUnused.test.js +35 -0
  340. package/dist/test/unit/ui/scan/printUnused.test.js.map +1 -0
  341. package/dist/test/unit/ui/scan/printUppercaseWarning.test.d.ts +2 -0
  342. package/dist/test/unit/ui/scan/printUppercaseWarning.test.d.ts.map +1 -0
  343. package/dist/test/unit/ui/scan/printUppercaseWarning.test.js +44 -0
  344. package/dist/test/unit/ui/scan/printUppercaseWarning.test.js.map +1 -0
  345. package/dist/test/unit/ui/scan/scanJsonOutput.test.d.ts +2 -0
  346. package/dist/test/unit/ui/scan/scanJsonOutput.test.d.ts.map +1 -0
  347. package/dist/test/unit/ui/scan/scanJsonOutput.test.js +270 -0
  348. package/dist/test/unit/ui/scan/scanJsonOutput.test.js.map +1 -0
  349. package/dist/test/unit/ui/shared/printAutoFix.test.d.ts +2 -0
  350. package/dist/test/unit/ui/shared/printAutoFix.test.d.ts.map +1 -0
  351. package/dist/test/unit/ui/shared/printAutoFix.test.js +54 -0
  352. package/dist/test/unit/ui/shared/printAutoFix.test.js.map +1 -0
  353. package/dist/test/unit/ui/shared/printConfigStatus.test.d.ts +2 -0
  354. package/dist/test/unit/ui/shared/printConfigStatus.test.d.ts.map +1 -0
  355. package/dist/test/unit/ui/shared/printConfigStatus.test.js +44 -0
  356. package/dist/test/unit/ui/shared/printConfigStatus.test.js.map +1 -0
  357. package/dist/test/unit/ui/shared/printDuplicates.test.d.ts +2 -0
  358. package/dist/test/unit/ui/shared/printDuplicates.test.d.ts.map +1 -0
  359. package/dist/test/unit/ui/shared/printDuplicates.test.js +43 -0
  360. package/dist/test/unit/ui/shared/printDuplicates.test.js.map +1 -0
  361. package/dist/test/unit/ui/shared/printFixTips.test.d.ts +2 -0
  362. package/dist/test/unit/ui/shared/printFixTips.test.d.ts.map +1 -0
  363. package/dist/test/unit/ui/shared/printFixTips.test.js +67 -0
  364. package/dist/test/unit/ui/shared/printFixTips.test.js.map +1 -0
  365. package/dist/test/unit/ui/shared/printGitignore.test.d.ts +2 -0
  366. package/dist/test/unit/ui/shared/printGitignore.test.d.ts.map +1 -0
  367. package/dist/test/unit/ui/shared/printGitignore.test.js +59 -0
  368. package/dist/test/unit/ui/shared/printGitignore.test.js.map +1 -0
  369. package/dist/test/unit/ui/shared/printInitStatus.test.d.ts +2 -0
  370. package/dist/test/unit/ui/shared/printInitStatus.test.d.ts.map +1 -0
  371. package/dist/test/unit/ui/shared/printInitStatus.test.js +43 -0
  372. package/dist/test/unit/ui/shared/printInitStatus.test.js.map +1 -0
  373. package/dist/test/unit/ui/shared/printOptionErrors.test.d.ts +2 -0
  374. package/dist/test/unit/ui/shared/printOptionErrors.test.d.ts.map +1 -0
  375. package/dist/test/unit/ui/shared/printOptionErrors.test.js +57 -0
  376. package/dist/test/unit/ui/shared/printOptionErrors.test.js.map +1 -0
  377. package/dist/test/unit/ui/shared/setupGlobalConfig.test.d.ts +2 -0
  378. package/dist/test/unit/ui/shared/setupGlobalConfig.test.d.ts.map +1 -0
  379. package/dist/test/unit/ui/shared/setupGlobalConfig.test.js +27 -0
  380. package/dist/test/unit/ui/shared/setupGlobalConfig.test.js.map +1 -0
  381. package/dist/test/unit/ui/theme.test.d.ts +2 -0
  382. package/dist/test/unit/ui/theme.test.d.ts.map +1 -0
  383. package/dist/test/unit/ui/theme.test.js +61 -0
  384. package/dist/test/unit/ui/theme.test.js.map +1 -0
  385. package/dist/test/utils/cli-helpers.d.ts +27 -0
  386. package/dist/test/utils/cli-helpers.d.ts.map +1 -0
  387. package/dist/test/utils/cli-helpers.js +46 -0
  388. package/dist/test/utils/cli-helpers.js.map +1 -0
  389. package/dist/test/utils/fs-helpers.d.ts +20 -0
  390. package/dist/test/utils/fs-helpers.d.ts.map +1 -0
  391. package/dist/test/utils/fs-helpers.js +30 -0
  392. package/dist/test/utils/fs-helpers.js.map +1 -0
  393. package/package.json +3 -1
@@ -0,0 +1,639 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import {} from '../../../src/core/security/secretDetectors.js';
3
+ import { promptNoEnvScenario } from '../../../src/commands/prompts/promptNoEnvScenario.js';
4
+ vi.mock('../../../src/services/scanCodebase.js', () => ({
5
+ scanCodebase: vi.fn(),
6
+ }));
7
+ vi.mock('../../../src/core/scan/determineComparisonFile.js', () => ({
8
+ determineComparisonFile: vi.fn(),
9
+ }));
10
+ vi.mock('../../../src/services/printScanResult.js', () => ({
11
+ printScanResult: vi.fn(),
12
+ }));
13
+ vi.mock('../../../src/ui/scan/scanJsonOutput.js', () => ({
14
+ scanJsonOutput: vi.fn(() => ({ ok: true })),
15
+ }));
16
+ vi.mock('../../../src/ui/scan/printMissingExample.js', () => ({
17
+ printMissingExample: vi.fn(() => false),
18
+ }));
19
+ vi.mock('../../../src/services/processComparisonFile.js', () => ({
20
+ processComparisonFile: vi.fn(),
21
+ }));
22
+ vi.mock('../../../src/ui/scan/printComparisonError.js', () => ({
23
+ printComparisonError: vi.fn(() => ({ exit: false })),
24
+ }));
25
+ vi.mock('../../../src/core/security/secretDetectors.js', () => ({
26
+ hasIgnoreComment: vi.fn(() => false),
27
+ }));
28
+ vi.mock('../../../src/core/frameworks/frameworkValidator.js', () => ({
29
+ frameworkValidator: vi.fn(() => []),
30
+ }));
31
+ vi.mock('../../../src/core/security/exampleSecretDetector.js', () => ({
32
+ detectSecretsInExample: vi.fn(() => [
33
+ {
34
+ key: 'SECRET',
35
+ value: '123',
36
+ reason: 'hardcoded',
37
+ severity: 'high',
38
+ },
39
+ ]),
40
+ }));
41
+ vi.mock('../../../src/commands/prompts/promptNoEnvScenario.js', () => ({
42
+ promptNoEnvScenario: vi.fn(),
43
+ }));
44
+ import { scanUsage } from '../../../src/commands/scanUsage.js';
45
+ import { scanCodebase } from '../../../src/services/scanCodebase.js';
46
+ import { determineComparisonFile } from '../../../src/core/scan/determineComparisonFile.js';
47
+ import { printScanResult } from '../../../src/services/printScanResult.js';
48
+ import { processComparisonFile } from '../../../src/services/processComparisonFile.js';
49
+ import { printMissingExample } from '../../../src/ui/scan/printMissingExample.js';
50
+ import { printComparisonError } from '../../../src/ui/scan/printComparisonError.js';
51
+ import { frameworkValidator } from '../../../src/core/frameworks/frameworkValidator.js';
52
+ describe('scanUsage', () => {
53
+ const dummySecret = {
54
+ file: 'file.ts',
55
+ line: 1,
56
+ kind: 'pattern',
57
+ message: 'secret found',
58
+ snippet: 'SECRET=123',
59
+ severity: 'high',
60
+ };
61
+ const baseScanResult = {
62
+ used: [],
63
+ missing: [],
64
+ unused: [],
65
+ stats: {
66
+ filesScanned: 1,
67
+ totalUsages: 0,
68
+ uniqueVariables: 0,
69
+ warningsCount: 0,
70
+ duration: 0,
71
+ },
72
+ secrets: [],
73
+ duplicates: {},
74
+ logged: [],
75
+ fileContentMap: new Map(),
76
+ };
77
+ const baseOpts = {
78
+ cwd: '/root',
79
+ include: [],
80
+ exclude: [],
81
+ ignore: [],
82
+ ignoreRegex: [],
83
+ secrets: false,
84
+ json: false,
85
+ };
86
+ beforeEach(() => {
87
+ vi.clearAllMocks();
88
+ vi.mocked(scanCodebase).mockResolvedValue({ ...baseScanResult });
89
+ vi.mocked(determineComparisonFile).mockResolvedValue({ type: 'none' });
90
+ vi.mocked(printScanResult).mockReturnValue({ exitWithError: false });
91
+ vi.mocked(printMissingExample).mockReturnValue(false);
92
+ vi.mocked(promptNoEnvScenario).mockResolvedValue({
93
+ compareFile: undefined,
94
+ });
95
+ vi.mocked(frameworkValidator).mockReturnValue([]);
96
+ });
97
+ it('returns early when example missing in CI mode', async () => {
98
+ vi.mocked(printMissingExample).mockReturnValue(true);
99
+ const result = await scanUsage(baseOpts);
100
+ expect(result.exitWithError).toBe(true);
101
+ });
102
+ it('exits when comparison error requests exit', async () => {
103
+ vi.mocked(determineComparisonFile).mockResolvedValue({
104
+ type: 'found',
105
+ file: { path: '/env/.env', name: '.env' },
106
+ });
107
+ vi.mocked(processComparisonFile).mockReturnValue({
108
+ error: { message: 'err', shouldExit: true },
109
+ });
110
+ vi.mocked(printComparisonError).mockReturnValue({ exit: true });
111
+ const result = await scanUsage(baseOpts);
112
+ expect(result.exitWithError).toBe(true);
113
+ });
114
+ it('returns error in JSON mode when missing keys exist', async () => {
115
+ vi.mocked(scanCodebase).mockResolvedValue({
116
+ ...baseScanResult,
117
+ missing: ['A'],
118
+ });
119
+ const result = await scanUsage({ ...baseOpts, json: true });
120
+ expect(result.exitWithError).toBe(true);
121
+ });
122
+ it('returns error in JSON mode for high severity secret', async () => {
123
+ vi.mocked(scanCodebase).mockResolvedValue({
124
+ ...baseScanResult,
125
+ secrets: [dummySecret],
126
+ });
127
+ const result = await scanUsage({ ...baseOpts, json: true });
128
+ expect(result.exitWithError).toBe(true);
129
+ });
130
+ it('does not return error in JSON mode for non-high example warnings when strict is false', async () => {
131
+ vi.mocked(scanCodebase).mockResolvedValue({
132
+ ...baseScanResult,
133
+ exampleWarnings: [
134
+ {
135
+ key: 'EXAMPLE_KEY',
136
+ value: 'placeholder-but-flagged',
137
+ reason: 'Entropy',
138
+ severity: 'medium',
139
+ },
140
+ ],
141
+ });
142
+ const result = await scanUsage({ ...baseOpts, json: true, strict: false });
143
+ expect(result.exitWithError).toBe(false);
144
+ });
145
+ it('returns strict error in JSON mode when strict violations exist', async () => {
146
+ vi.mocked(scanCodebase).mockResolvedValue({
147
+ ...baseScanResult,
148
+ unused: ['A'],
149
+ });
150
+ const result = await scanUsage({
151
+ ...baseOpts,
152
+ json: true,
153
+ strict: true,
154
+ });
155
+ expect(result.exitWithError).toBe(true);
156
+ });
157
+ it('returns error in JSON mode when expiration warning is urgent (<=7 days)', async () => {
158
+ vi.mocked(scanCodebase).mockResolvedValue({
159
+ ...baseScanResult,
160
+ expireWarnings: [{ key: 'TOKEN', date: '2026-03-10', daysLeft: 7 }],
161
+ });
162
+ const result = await scanUsage({ ...baseOpts, json: true, strict: false });
163
+ expect(result.exitWithError).toBe(true);
164
+ });
165
+ it('skips prompt when type is none and isCiMode is true', async () => {
166
+ vi.mocked(determineComparisonFile).mockResolvedValue({ type: 'none' });
167
+ const result = await scanUsage({ ...baseOpts, isCiMode: true });
168
+ expect(promptNoEnvScenario).not.toHaveBeenCalled();
169
+ expect(result.exitWithError).toBe(false);
170
+ });
171
+ it('skips prompt when type is none and json is true', async () => {
172
+ vi.mocked(determineComparisonFile).mockResolvedValue({ type: 'none' });
173
+ const result = await scanUsage({ ...baseOpts, json: true });
174
+ expect(promptNoEnvScenario).not.toHaveBeenCalled();
175
+ expect(result.exitWithError).toBe(false);
176
+ });
177
+ it('calls promptNoEnvScenario when type is none and not CI/json', async () => {
178
+ vi.mocked(promptNoEnvScenario).mockResolvedValue({
179
+ compareFile: { path: '/env/.env', name: '.env' },
180
+ });
181
+ vi.mocked(determineComparisonFile).mockResolvedValue({ type: 'none' });
182
+ vi.mocked(processComparisonFile).mockReturnValue({
183
+ scanResult: { ...baseScanResult },
184
+ comparedAgainst: '.env',
185
+ envVariables: {},
186
+ duplicatesFound: false,
187
+ dupsEnv: [],
188
+ dupsEx: [],
189
+ fix: {
190
+ fixApplied: false,
191
+ removedDuplicates: [],
192
+ addedEnv: [],
193
+ gitignoreUpdated: false,
194
+ },
195
+ });
196
+ await scanUsage({ ...baseOpts, isCiMode: false, json: false });
197
+ expect(promptNoEnvScenario).toHaveBeenCalled();
198
+ expect(processComparisonFile).toHaveBeenCalled();
199
+ });
200
+ it('sets frameworkWarnings on scanResult when frameworkValidator returns results', async () => {
201
+ const { frameworkValidator } = await import('../../../src/core/frameworks/frameworkValidator.js');
202
+ vi.mocked(frameworkValidator).mockReturnValue([
203
+ {
204
+ variable: 'API_KEY',
205
+ reason: 'exposed',
206
+ file: 'app.ts',
207
+ line: 1,
208
+ framework: 'nextjs',
209
+ },
210
+ ]);
211
+ vi.mocked(determineComparisonFile).mockResolvedValue({ type: 'none' });
212
+ await scanUsage({ ...baseOpts, isCiMode: true });
213
+ expect(printScanResult).toHaveBeenCalledWith(expect.objectContaining({
214
+ frameworkWarnings: expect.arrayContaining([
215
+ expect.objectContaining({ variable: 'API_KEY' }),
216
+ ]),
217
+ }), expect.anything(), expect.anything(), expect.anything());
218
+ });
219
+ it('continues when comparison error has shouldExit false', async () => {
220
+ vi.mocked(determineComparisonFile).mockResolvedValue({
221
+ type: 'found',
222
+ file: { path: '/env/.env', name: '.env' },
223
+ });
224
+ vi.mocked(processComparisonFile).mockReturnValue({
225
+ error: { message: 'soft error', shouldExit: false },
226
+ });
227
+ vi.mocked(printComparisonError).mockReturnValue({ exit: false });
228
+ const result = await scanUsage(baseOpts);
229
+ expect(result.exitWithError).toBe(false);
230
+ });
231
+ it('transfers uppercaseWarnings, expireWarnings and inconsistentNamingWarnings to scanResult', async () => {
232
+ vi.mocked(determineComparisonFile).mockResolvedValue({
233
+ type: 'found',
234
+ file: { path: '/env/.env', name: '.env' },
235
+ });
236
+ vi.mocked(processComparisonFile).mockReturnValue({
237
+ scanResult: { ...baseScanResult },
238
+ comparedAgainst: '.env',
239
+ envVariables: {},
240
+ duplicatesFound: false,
241
+ dupsEnv: [],
242
+ dupsEx: [],
243
+ fix: {
244
+ fixApplied: false,
245
+ removedDuplicates: [],
246
+ addedEnv: [],
247
+ gitignoreUpdated: false,
248
+ },
249
+ uppercaseWarnings: [{ key: 'myKey', suggestion: 'MY_KEY' }],
250
+ expireWarnings: [{ key: 'OLD_KEY', date: '2024-01-01', daysLeft: -10 }],
251
+ inconsistentNamingWarnings: [{ key1: 'A', key2: 'B', suggestion: 'A_B' }],
252
+ });
253
+ await scanUsage(baseOpts);
254
+ expect(printScanResult).toHaveBeenCalledWith(expect.objectContaining({
255
+ uppercaseWarnings: expect.arrayContaining([
256
+ expect.objectContaining({ key: 'myKey' }),
257
+ ]),
258
+ expireWarnings: expect.arrayContaining([
259
+ expect.objectContaining({ key: 'OLD_KEY' }),
260
+ ]),
261
+ inconsistentNamingWarnings: expect.arrayContaining([
262
+ expect.objectContaining({ key1: 'A' }),
263
+ ]),
264
+ }), expect.anything(), expect.anything(), expect.anything());
265
+ });
266
+ it('sets exampleWarnings when comparedAgainst matches DEFAULT_EXAMPLE_FILE', async () => {
267
+ const { DEFAULT_EXAMPLE_FILE } = await import('../../../src/config/constants.js');
268
+ vi.mocked(determineComparisonFile).mockResolvedValue({
269
+ type: 'found',
270
+ file: { path: '/env/.env.example', name: DEFAULT_EXAMPLE_FILE },
271
+ });
272
+ vi.mocked(processComparisonFile).mockReturnValue({
273
+ scanResult: { ...baseScanResult },
274
+ comparedAgainst: DEFAULT_EXAMPLE_FILE,
275
+ envVariables: {},
276
+ duplicatesFound: false,
277
+ dupsEnv: [],
278
+ dupsEx: [],
279
+ exampleFull: { SECRET: 'abc123' },
280
+ fix: {
281
+ fixApplied: false,
282
+ removedDuplicates: [],
283
+ addedEnv: [],
284
+ gitignoreUpdated: false,
285
+ },
286
+ });
287
+ await scanUsage(baseOpts);
288
+ const { detectSecretsInExample } = await import('../../../src/core/security/exampleSecretDetector.js');
289
+ expect(detectSecretsInExample).toHaveBeenCalledWith({ SECRET: 'abc123' });
290
+ });
291
+ it('does not set exampleWarnings when comparedAgainst is not the default example file', async () => {
292
+ vi.mocked(determineComparisonFile).mockResolvedValue({
293
+ type: 'found',
294
+ file: { path: '/env/.env', name: '.env' },
295
+ });
296
+ vi.mocked(processComparisonFile).mockReturnValue({
297
+ scanResult: { ...baseScanResult },
298
+ comparedAgainst: '.env',
299
+ envVariables: {},
300
+ duplicatesFound: false,
301
+ dupsEnv: [],
302
+ dupsEx: [],
303
+ exampleFull: { SECRET: 'abc123' },
304
+ fix: {
305
+ fixApplied: false,
306
+ removedDuplicates: [],
307
+ addedEnv: [],
308
+ gitignoreUpdated: false,
309
+ },
310
+ });
311
+ await scanUsage(baseOpts);
312
+ const { detectSecretsInExample } = await import('../../../src/core/security/exampleSecretDetector.js');
313
+ expect(detectSecretsInExample).not.toHaveBeenCalled();
314
+ });
315
+ it('filters out commented usages before processing', async () => {
316
+ vi.mocked(scanCodebase).mockResolvedValue({
317
+ ...baseScanResult,
318
+ used: [
319
+ {
320
+ variable: 'A',
321
+ file: 'f.ts',
322
+ line: 1,
323
+ column: 0,
324
+ pattern: 'process.env',
325
+ context: '// process.env.A',
326
+ },
327
+ {
328
+ variable: 'B',
329
+ file: 'f.ts',
330
+ line: 2,
331
+ column: 0,
332
+ pattern: 'process.env',
333
+ context: 'process.env.B',
334
+ },
335
+ ],
336
+ });
337
+ vi.mocked(determineComparisonFile).mockResolvedValue({ type: 'none' });
338
+ await scanUsage({ ...baseOpts, isCiMode: true });
339
+ expect(printScanResult).toHaveBeenCalledWith(expect.objectContaining({
340
+ used: expect.arrayContaining([
341
+ expect.objectContaining({ variable: 'B' }),
342
+ ]),
343
+ }), expect.anything(), expect.anything(), expect.anything());
344
+ expect(printScanResult).toHaveBeenCalledWith(expect.objectContaining({
345
+ used: expect.not.arrayContaining([
346
+ expect.objectContaining({ variable: 'A' }),
347
+ ]),
348
+ }), expect.anything(), expect.anything(), expect.anything());
349
+ });
350
+ it('removes logged warning for block-commented console env usage', async () => {
351
+ vi.mocked(scanCodebase).mockResolvedValue({
352
+ ...baseScanResult,
353
+ used: [
354
+ {
355
+ variable: 'TEST_KEY',
356
+ file: 'src/index.ts',
357
+ line: 4,
358
+ column: 1,
359
+ pattern: 'process.env',
360
+ context: '/* console.log(process.env.TEST_KEY); */',
361
+ isLogged: true,
362
+ },
363
+ ],
364
+ logged: [
365
+ {
366
+ variable: 'TEST_KEY',
367
+ file: 'src/index.ts',
368
+ line: 4,
369
+ column: 1,
370
+ pattern: 'process.env',
371
+ context: '/* console.log(process.env.TEST_KEY); */',
372
+ isLogged: true,
373
+ },
374
+ ],
375
+ });
376
+ vi.mocked(determineComparisonFile).mockResolvedValue({ type: 'none' });
377
+ await scanUsage({ ...baseOpts, isCiMode: true });
378
+ expect(printScanResult).toHaveBeenCalledWith(expect.objectContaining({
379
+ logged: [],
380
+ used: [],
381
+ }), expect.anything(), expect.anything(), expect.anything());
382
+ });
383
+ it('returns exitWithError true in JSON strict mode for each warning type', async () => {
384
+ const cases = [
385
+ { duplicates: { env: [{ key: 'A', count: 2 }] } },
386
+ { duplicates: { example: [{ key: 'B', count: 2 }] } },
387
+ {
388
+ secrets: [
389
+ {
390
+ file: 'f.ts',
391
+ line: 1,
392
+ kind: 'pattern',
393
+ message: 'x',
394
+ snippet: 'y',
395
+ severity: 'low',
396
+ },
397
+ ],
398
+ },
399
+ {
400
+ frameworkWarnings: [
401
+ {
402
+ variable: 'A',
403
+ reason: 'r',
404
+ file: 'f.ts',
405
+ line: 1,
406
+ framework: 'nextjs',
407
+ },
408
+ ],
409
+ },
410
+ {
411
+ used: [
412
+ {
413
+ variable: 'A',
414
+ file: 'f.ts',
415
+ line: 1,
416
+ column: 0,
417
+ pattern: 'process.env',
418
+ context: 'console.log(process.env.A)',
419
+ isLogged: true,
420
+ },
421
+ ],
422
+ },
423
+ { uppercaseWarnings: [{ key: 'a', suggestion: 'A' }] },
424
+ { expireWarnings: [{ key: 'K', date: '2020-01-01', daysLeft: -100 }] },
425
+ {
426
+ inconsistentNamingWarnings: [
427
+ { key1: 'A', key2: 'B', suggestion: 'A_B' },
428
+ ],
429
+ },
430
+ ];
431
+ for (const extra of cases) {
432
+ vi.mocked(scanCodebase).mockResolvedValue({
433
+ ...baseScanResult,
434
+ ...extra,
435
+ });
436
+ const result = await scanUsage({ ...baseOpts, json: true, strict: true });
437
+ expect(result.exitWithError).toBe(true);
438
+ }
439
+ });
440
+ it('filters out usages on HTML comment closing lines (-->)', async () => {
441
+ vi.mocked(scanCodebase).mockResolvedValue({
442
+ ...baseScanResult,
443
+ used: [
444
+ {
445
+ variable: 'A',
446
+ file: 'f.ts',
447
+ line: 1,
448
+ column: 0,
449
+ pattern: 'process.env',
450
+ context: '--> process.env.A',
451
+ },
452
+ ],
453
+ });
454
+ vi.mocked(determineComparisonFile).mockResolvedValue({ type: 'none' });
455
+ await scanUsage({ ...baseOpts, isCiMode: true });
456
+ expect(printScanResult).toHaveBeenCalledWith(expect.objectContaining({ used: [] }), expect.anything(), expect.anything(), expect.anything());
457
+ });
458
+ it('filters out the dotenv-diff-ignore-end line itself', async () => {
459
+ vi.mocked(scanCodebase).mockResolvedValue({
460
+ ...baseScanResult,
461
+ used: [
462
+ {
463
+ variable: 'END_LINE',
464
+ file: 'f.ts',
465
+ line: 1,
466
+ column: 0,
467
+ pattern: 'process.env',
468
+ context: '<!-- dotenv-diff-ignore-end -->',
469
+ },
470
+ ],
471
+ });
472
+ vi.mocked(determineComparisonFile).mockResolvedValue({ type: 'none' });
473
+ await scanUsage({ ...baseOpts, isCiMode: true });
474
+ expect(printScanResult).toHaveBeenCalledWith(expect.objectContaining({ used: [] }), expect.anything(), expect.anything(), expect.anything());
475
+ });
476
+ it('filters out the dotenv-diff-ignore-start line itself and subsequent usages inside block (line 217-218)', async () => {
477
+ vi.mocked(scanCodebase).mockResolvedValue({
478
+ ...baseScanResult,
479
+ used: [
480
+ {
481
+ variable: 'START_LINE',
482
+ file: 'f.ts',
483
+ line: 1,
484
+ column: 0,
485
+ pattern: 'process.env',
486
+ context: '<!-- dotenv-diff-ignore-start -->',
487
+ },
488
+ {
489
+ variable: 'INSIDE_BLOCK',
490
+ file: 'f.ts',
491
+ line: 2,
492
+ column: 0,
493
+ pattern: 'process.env',
494
+ context: 'process.env.INSIDE_BLOCK',
495
+ },
496
+ ],
497
+ });
498
+ vi.mocked(determineComparisonFile).mockResolvedValue({ type: 'none' });
499
+ await scanUsage({ ...baseOpts, isCiMode: true });
500
+ expect(printScanResult).toHaveBeenCalledWith(expect.objectContaining({ used: [] }), expect.anything(), expect.anything(), expect.anything());
501
+ });
502
+ it('passes false to printComparisonError when json is not set (line 105)', async () => {
503
+ vi.mocked(determineComparisonFile).mockResolvedValue({
504
+ type: 'found',
505
+ file: { path: '/env/.env', name: '.env' },
506
+ });
507
+ vi.mocked(processComparisonFile).mockReturnValue({
508
+ error: { message: 'err', shouldExit: false },
509
+ });
510
+ vi.mocked(printComparisonError).mockReturnValue({ exit: false });
511
+ const { json: _omit, ...optsWithoutJson } = baseOpts;
512
+ await scanUsage(optsWithoutJson);
513
+ expect(printComparisonError).toHaveBeenCalledWith(expect.any(String), expect.any(Boolean), false);
514
+ });
515
+ it('handles undefined secrets gracefully in JSON mode (line 143)', async () => {
516
+ vi.mocked(scanCodebase).mockResolvedValue({
517
+ ...baseScanResult,
518
+ secrets: undefined,
519
+ });
520
+ const result = await scanUsage({ ...baseOpts, json: true });
521
+ expect(result.exitWithError).toBe(false);
522
+ });
523
+ it('returns false in strict JSON mode when there are no violations (lines 163-175)', async () => {
524
+ const result = await scanUsage({ ...baseOpts, json: true, strict: true });
525
+ expect(result.exitWithError).toBe(false);
526
+ });
527
+ it('exits in strict JSON mode when exampleWarnings exist (line 175)', async () => {
528
+ vi.mocked(scanCodebase).mockResolvedValue({
529
+ ...baseScanResult,
530
+ exampleWarnings: [
531
+ { key: 'SECRET', value: 'abc', reason: 'Entropy', severity: 'low' },
532
+ ],
533
+ });
534
+ const result = await scanUsage({ ...baseOpts, json: true, strict: true });
535
+ expect(result.exitWithError).toBe(true);
536
+ });
537
+ it('keeps usage with no context (line 207)', async () => {
538
+ vi.mocked(scanCodebase).mockResolvedValue({
539
+ ...baseScanResult,
540
+ used: [
541
+ {
542
+ variable: 'NO_CONTEXT_KEY',
543
+ file: 'f.ts',
544
+ line: 1,
545
+ column: 0,
546
+ pattern: 'process.env',
547
+ context: undefined,
548
+ },
549
+ ],
550
+ });
551
+ vi.mocked(determineComparisonFile).mockResolvedValue({ type: 'none' });
552
+ await scanUsage({ ...baseOpts, isCiMode: true });
553
+ expect(printScanResult).toHaveBeenCalledWith(expect.objectContaining({
554
+ used: [expect.objectContaining({ variable: 'NO_CONTEXT_KEY' })],
555
+ }), expect.anything(), expect.anything(), expect.anything());
556
+ });
557
+ it('filters usage inside unclosed HTML comment block (line 220)', async () => {
558
+ vi.mocked(scanCodebase).mockResolvedValue({
559
+ ...baseScanResult,
560
+ used: [
561
+ {
562
+ variable: 'INSIDE_HTML_COMMENT',
563
+ file: 'f.ts',
564
+ line: 1,
565
+ column: 0,
566
+ pattern: 'process.env',
567
+ context: '<!-- unclosed comment process.env.INSIDE_HTML_COMMENT',
568
+ },
569
+ {
570
+ variable: 'AFTER_OPEN',
571
+ file: 'f.ts',
572
+ line: 2,
573
+ column: 0,
574
+ pattern: 'process.env',
575
+ context: 'process.env.AFTER_OPEN',
576
+ },
577
+ ],
578
+ });
579
+ vi.mocked(determineComparisonFile).mockResolvedValue({ type: 'none' });
580
+ await scanUsage({ ...baseOpts, isCiMode: true });
581
+ expect(printScanResult).toHaveBeenCalledWith(expect.objectContaining({ used: [] }), expect.anything(), expect.anything(), expect.anything());
582
+ });
583
+ it('handles undefined logged and secrets in calculateStats (lines 249, 253)', async () => {
584
+ vi.mocked(scanCodebase).mockResolvedValue({
585
+ ...baseScanResult,
586
+ logged: undefined,
587
+ secrets: undefined,
588
+ });
589
+ vi.mocked(determineComparisonFile).mockResolvedValue({ type: 'none' });
590
+ // Should not throw even when logged/secrets are undefined
591
+ await expect(scanUsage({ ...baseOpts, isCiMode: true })).resolves.not.toThrow();
592
+ expect(printScanResult).toHaveBeenCalled();
593
+ });
594
+ it('resumes keeping usages after dotenv-diff-ignore-end (line 222-223)', async () => {
595
+ vi.mocked(scanCodebase).mockResolvedValue({
596
+ ...baseScanResult,
597
+ used: [
598
+ {
599
+ variable: 'START_LINE',
600
+ file: 'f.ts',
601
+ line: 1,
602
+ column: 0,
603
+ pattern: 'process.env',
604
+ context: '<!-- dotenv-diff-ignore-start -->',
605
+ },
606
+ {
607
+ variable: 'INSIDE_BLOCK',
608
+ file: 'f.ts',
609
+ line: 2,
610
+ column: 0,
611
+ pattern: 'process.env',
612
+ context: 'process.env.INSIDE_BLOCK',
613
+ },
614
+ {
615
+ variable: 'END_MARKER',
616
+ file: 'f.ts',
617
+ line: 3,
618
+ column: 0,
619
+ pattern: 'process.env',
620
+ context: '<!-- dotenv-diff-ignore-end -->',
621
+ },
622
+ {
623
+ variable: 'AFTER_BLOCK',
624
+ file: 'f.ts',
625
+ line: 4,
626
+ column: 0,
627
+ pattern: 'process.env',
628
+ context: 'process.env.AFTER_BLOCK',
629
+ },
630
+ ],
631
+ });
632
+ vi.mocked(determineComparisonFile).mockResolvedValue({ type: 'none' });
633
+ await scanUsage({ ...baseOpts, isCiMode: true });
634
+ expect(printScanResult).toHaveBeenCalledWith(expect.objectContaining({
635
+ used: [expect.objectContaining({ variable: 'AFTER_BLOCK' })],
636
+ }), expect.anything(), expect.anything(), expect.anything());
637
+ });
638
+ });
639
+ //# sourceMappingURL=scanUsage.test.js.map