code-secret-handler 1.0.0

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 (171) hide show
  1. package/LICENSE +79 -0
  2. package/README.md +221 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +121 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/env/envWriter.d.ts +9 -0
  8. package/dist/env/envWriter.d.ts.map +1 -0
  9. package/dist/env/envWriter.js +76 -0
  10. package/dist/env/envWriter.js.map +1 -0
  11. package/dist/env/keyNamer.d.ts +13 -0
  12. package/dist/env/keyNamer.d.ts.map +1 -0
  13. package/dist/env/keyNamer.js +33 -0
  14. package/dist/env/keyNamer.js.map +1 -0
  15. package/dist/interactive/confirm.d.ts +16 -0
  16. package/dist/interactive/confirm.d.ts.map +1 -0
  17. package/dist/interactive/confirm.js +72 -0
  18. package/dist/interactive/confirm.js.map +1 -0
  19. package/dist/license/gitContext.d.ts +16 -0
  20. package/dist/license/gitContext.d.ts.map +1 -0
  21. package/dist/license/gitContext.js +117 -0
  22. package/dist/license/gitContext.js.map +1 -0
  23. package/dist/license/licenseCheck.d.ts +22 -0
  24. package/dist/license/licenseCheck.d.ts.map +1 -0
  25. package/dist/license/licenseCheck.js +119 -0
  26. package/dist/license/licenseCheck.js.map +1 -0
  27. package/dist/license/telemetry.d.ts +17 -0
  28. package/dist/license/telemetry.d.ts.map +1 -0
  29. package/dist/license/telemetry.js +87 -0
  30. package/dist/license/telemetry.js.map +1 -0
  31. package/dist/reporter/console.d.ts +3 -0
  32. package/dist/reporter/console.d.ts.map +1 -0
  33. package/dist/reporter/console.js +96 -0
  34. package/dist/reporter/console.js.map +1 -0
  35. package/dist/reporter/csv.d.ts +6 -0
  36. package/dist/reporter/csv.d.ts.map +1 -0
  37. package/dist/reporter/csv.js +56 -0
  38. package/dist/reporter/csv.js.map +1 -0
  39. package/dist/reporter/index.d.ts +13 -0
  40. package/dist/reporter/index.d.ts.map +1 -0
  41. package/dist/reporter/index.js +52 -0
  42. package/dist/reporter/index.js.map +1 -0
  43. package/dist/reporter/json.d.ts +7 -0
  44. package/dist/reporter/json.d.ts.map +1 -0
  45. package/dist/reporter/json.js +39 -0
  46. package/dist/reporter/json.js.map +1 -0
  47. package/dist/reporter/markdown.d.ts +6 -0
  48. package/dist/reporter/markdown.d.ts.map +1 -0
  49. package/dist/reporter/markdown.js +106 -0
  50. package/dist/reporter/markdown.js.map +1 -0
  51. package/dist/rewriter/index.d.ts +9 -0
  52. package/dist/rewriter/index.d.ts.map +1 -0
  53. package/dist/rewriter/index.js +95 -0
  54. package/dist/rewriter/index.js.map +1 -0
  55. package/dist/rewriter/langDetector.d.ts +7 -0
  56. package/dist/rewriter/langDetector.d.ts.map +1 -0
  57. package/dist/rewriter/langDetector.js +96 -0
  58. package/dist/rewriter/langDetector.js.map +1 -0
  59. package/dist/rewriter/templates/csharp.d.ts +8 -0
  60. package/dist/rewriter/templates/csharp.d.ts.map +1 -0
  61. package/dist/rewriter/templates/csharp.js +36 -0
  62. package/dist/rewriter/templates/csharp.js.map +1 -0
  63. package/dist/rewriter/templates/generic.d.ts +7 -0
  64. package/dist/rewriter/templates/generic.d.ts.map +1 -0
  65. package/dist/rewriter/templates/generic.js +40 -0
  66. package/dist/rewriter/templates/generic.js.map +1 -0
  67. package/dist/rewriter/templates/go.d.ts +8 -0
  68. package/dist/rewriter/templates/go.d.ts.map +1 -0
  69. package/dist/rewriter/templates/go.js +56 -0
  70. package/dist/rewriter/templates/go.js.map +1 -0
  71. package/dist/rewriter/templates/java.d.ts +7 -0
  72. package/dist/rewriter/templates/java.d.ts.map +1 -0
  73. package/dist/rewriter/templates/java.js +31 -0
  74. package/dist/rewriter/templates/java.js.map +1 -0
  75. package/dist/rewriter/templates/javascript.d.ts +10 -0
  76. package/dist/rewriter/templates/javascript.d.ts.map +1 -0
  77. package/dist/rewriter/templates/javascript.js +54 -0
  78. package/dist/rewriter/templates/javascript.js.map +1 -0
  79. package/dist/rewriter/templates/php.d.ts +8 -0
  80. package/dist/rewriter/templates/php.d.ts.map +1 -0
  81. package/dist/rewriter/templates/php.js +41 -0
  82. package/dist/rewriter/templates/php.js.map +1 -0
  83. package/dist/rewriter/templates/properties.d.ts +9 -0
  84. package/dist/rewriter/templates/properties.d.ts.map +1 -0
  85. package/dist/rewriter/templates/properties.js +39 -0
  86. package/dist/rewriter/templates/properties.js.map +1 -0
  87. package/dist/rewriter/templates/python.d.ts +8 -0
  88. package/dist/rewriter/templates/python.d.ts.map +1 -0
  89. package/dist/rewriter/templates/python.js +48 -0
  90. package/dist/rewriter/templates/python.js.map +1 -0
  91. package/dist/rewriter/templates/ruby.d.ts +8 -0
  92. package/dist/rewriter/templates/ruby.d.ts.map +1 -0
  93. package/dist/rewriter/templates/ruby.js +40 -0
  94. package/dist/rewriter/templates/ruby.js.map +1 -0
  95. package/dist/rewriter/templates/rust.d.ts +7 -0
  96. package/dist/rewriter/templates/rust.d.ts.map +1 -0
  97. package/dist/rewriter/templates/rust.js +27 -0
  98. package/dist/rewriter/templates/rust.js.map +1 -0
  99. package/dist/rewriter/templates/shell.d.ts +7 -0
  100. package/dist/rewriter/templates/shell.d.ts.map +1 -0
  101. package/dist/rewriter/templates/shell.js +42 -0
  102. package/dist/rewriter/templates/shell.js.map +1 -0
  103. package/dist/rewriter/templates/toml.d.ts +9 -0
  104. package/dist/rewriter/templates/toml.d.ts.map +1 -0
  105. package/dist/rewriter/templates/toml.js +34 -0
  106. package/dist/rewriter/templates/toml.js.map +1 -0
  107. package/dist/rewriter/templates/yaml.d.ts +8 -0
  108. package/dist/rewriter/templates/yaml.d.ts.map +1 -0
  109. package/dist/rewriter/templates/yaml.js +37 -0
  110. package/dist/rewriter/templates/yaml.js.map +1 -0
  111. package/dist/scanner/detector.d.ts +18 -0
  112. package/dist/scanner/detector.d.ts.map +1 -0
  113. package/dist/scanner/detector.js +156 -0
  114. package/dist/scanner/detector.js.map +1 -0
  115. package/dist/scanner/fileWalker.d.ts +6 -0
  116. package/dist/scanner/fileWalker.d.ts.map +1 -0
  117. package/dist/scanner/fileWalker.js +146 -0
  118. package/dist/scanner/fileWalker.js.map +1 -0
  119. package/dist/scanner/index.d.ts +8 -0
  120. package/dist/scanner/index.d.ts.map +1 -0
  121. package/dist/scanner/index.js +74 -0
  122. package/dist/scanner/index.js.map +1 -0
  123. package/dist/scanner/rules/aws.d.ts +6 -0
  124. package/dist/scanner/rules/aws.d.ts.map +1 -0
  125. package/dist/scanner/rules/aws.js +90 -0
  126. package/dist/scanner/rules/aws.js.map +1 -0
  127. package/dist/scanner/rules/azure.d.ts +6 -0
  128. package/dist/scanner/rules/azure.d.ts.map +1 -0
  129. package/dist/scanner/rules/azure.js +86 -0
  130. package/dist/scanner/rules/azure.js.map +1 -0
  131. package/dist/scanner/rules/cloud.d.ts +11 -0
  132. package/dist/scanner/rules/cloud.d.ts.map +1 -0
  133. package/dist/scanner/rules/cloud.js +1066 -0
  134. package/dist/scanner/rules/cloud.js.map +1 -0
  135. package/dist/scanner/rules/database.d.ts +6 -0
  136. package/dist/scanner/rules/database.d.ts.map +1 -0
  137. package/dist/scanner/rules/database.js +283 -0
  138. package/dist/scanner/rules/database.js.map +1 -0
  139. package/dist/scanner/rules/gcp.d.ts +6 -0
  140. package/dist/scanner/rules/gcp.d.ts.map +1 -0
  141. package/dist/scanner/rules/gcp.js +108 -0
  142. package/dist/scanner/rules/gcp.js.map +1 -0
  143. package/dist/scanner/rules/generic.d.ts +13 -0
  144. package/dist/scanner/rules/generic.d.ts.map +1 -0
  145. package/dist/scanner/rules/generic.js +305 -0
  146. package/dist/scanner/rules/generic.js.map +1 -0
  147. package/dist/scanner/rules/index.d.ts +18 -0
  148. package/dist/scanner/rules/index.d.ts.map +1 -0
  149. package/dist/scanner/rules/index.js +40 -0
  150. package/dist/scanner/rules/index.js.map +1 -0
  151. package/dist/scanner/rules/jwt.d.ts +6 -0
  152. package/dist/scanner/rules/jwt.d.ts.map +1 -0
  153. package/dist/scanner/rules/jwt.js +97 -0
  154. package/dist/scanner/rules/jwt.js.map +1 -0
  155. package/dist/scanner/rules/network.d.ts +7 -0
  156. package/dist/scanner/rules/network.d.ts.map +1 -0
  157. package/dist/scanner/rules/network.js +166 -0
  158. package/dist/scanner/rules/network.js.map +1 -0
  159. package/dist/scanner/rules/privateKey.d.ts +6 -0
  160. package/dist/scanner/rules/privateKey.d.ts.map +1 -0
  161. package/dist/scanner/rules/privateKey.js +60 -0
  162. package/dist/scanner/rules/privateKey.js.map +1 -0
  163. package/dist/scanner/rules/ssh.d.ts +6 -0
  164. package/dist/scanner/rules/ssh.d.ts.map +1 -0
  165. package/dist/scanner/rules/ssh.js +49 -0
  166. package/dist/scanner/rules/ssh.js.map +1 -0
  167. package/dist/types.d.ts +78 -0
  168. package/dist/types.d.ts.map +1 -0
  169. package/dist/types.js +3 -0
  170. package/dist/types.js.map +1 -0
  171. package/package.json +54 -0
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.writeCsvReport = writeCsvReport;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ function escapeCsv(value) {
10
+ // If value contains comma, newline, or double quote, wrap in quotes
11
+ if (/[",\n\r]/.test(value)) {
12
+ return `"${value.replace(/"/g, '""')}"`;
13
+ }
14
+ return value;
15
+ }
16
+ function maskValue(value) {
17
+ if (value.length <= 8)
18
+ return '*'.repeat(value.length);
19
+ return value.slice(0, 4) + '*'.repeat(Math.min(value.length - 8, 20)) + value.slice(-4);
20
+ }
21
+ /**
22
+ * Writes a CSV report of the scan findings.
23
+ */
24
+ function writeCsvReport(summary, outputPath) {
25
+ const headers = [
26
+ 'File',
27
+ 'Line',
28
+ 'Column',
29
+ 'Severity',
30
+ 'Rule ID',
31
+ 'Description',
32
+ 'Env Key',
33
+ 'Masked Value',
34
+ 'Line Content',
35
+ ];
36
+ const rows = summary.findings.map(f => [
37
+ f.file,
38
+ String(f.line),
39
+ String(f.column),
40
+ f.rule.severity,
41
+ f.rule.id,
42
+ f.rule.description,
43
+ f.envKey,
44
+ maskValue(f.rawValue),
45
+ f.lineContent.trim(),
46
+ ]);
47
+ const csvLines = [
48
+ headers.map(escapeCsv).join(','),
49
+ ...rows.map(row => row.map(escapeCsv).join(',')),
50
+ ];
51
+ const dir = path_1.default.dirname(outputPath);
52
+ if (!fs_1.default.existsSync(dir))
53
+ fs_1.default.mkdirSync(dir, { recursive: true });
54
+ fs_1.default.writeFileSync(outputPath, csvLines.join('\n'), 'utf-8');
55
+ }
56
+ //# sourceMappingURL=csv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csv.js","sourceRoot":"","sources":["../../src/reporter/csv.ts"],"names":[],"mappings":";;;;;;AAAA,4CAAoB;AACpB,gDAAwB;AAGxB,SAAS,SAAS,CAAC,KAAa;IAC9B,oEAAoE;IACpE,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;IAC1C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACvD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1F,CAAC;AAED;;GAEG;AACH,wBAA+B,OAAoB,EAAE,UAAkB;IACrE,MAAM,OAAO,GAAG;QACd,MAAM;QACN,MAAM;QACN,QAAQ;QACR,UAAU;QACV,SAAS;QACT,aAAa;QACb,SAAS;QACT,cAAc;QACd,cAAc;KACf,CAAC;IAEF,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACrC,CAAC,CAAC,IAAI;QACN,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;QACd,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;QAChB,CAAC,CAAC,IAAI,CAAC,QAAQ;QACf,CAAC,CAAC,IAAI,CAAC,EAAE;QACT,CAAC,CAAC,IAAI,CAAC,WAAW;QAClB,CAAC,CAAC,MAAM;QACR,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;QACrB,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE;KACrB,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG;QACf,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAChC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;KACjD,CAAC;IAEF,MAAM,GAAG,GAAG,cAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACrC,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,YAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEhE,YAAE,CAAC,aAAa,CAAC,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { ReportFormat, ScanSummary } from '../types';
2
+ /**
3
+ * Derives the default output file path for a given report format.
4
+ */
5
+ export declare function defaultOutputPath(format: ReportFormat, targetDir: string): string;
6
+ /**
7
+ * Runs the appropriate reporter(s) based on the chosen format.
8
+ * Always prints a console summary; file reporters write to outputPath.
9
+ *
10
+ * @returns The output file path (empty string for console-only).
11
+ */
12
+ export declare function runReporter(format: ReportFormat, summary: ScanSummary, outputPath?: string): string;
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/reporter/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAYrD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAIjF;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,WAAW,EACpB,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAqBR"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.defaultOutputPath = defaultOutputPath;
7
+ exports.runReporter = runReporter;
8
+ const path_1 = __importDefault(require("path"));
9
+ const console_1 = require("./console");
10
+ const json_1 = require("./json");
11
+ const csv_1 = require("./csv");
12
+ const markdown_1 = require("./markdown");
13
+ const EXT_MAP = {
14
+ json: 'json',
15
+ csv: 'csv',
16
+ markdown: 'md',
17
+ };
18
+ /**
19
+ * Derives the default output file path for a given report format.
20
+ */
21
+ function defaultOutputPath(format, targetDir) {
22
+ if (format === 'console')
23
+ return '';
24
+ const ext = EXT_MAP[format];
25
+ return path_1.default.join(targetDir, `secret-scan-report.${ext}`);
26
+ }
27
+ /**
28
+ * Runs the appropriate reporter(s) based on the chosen format.
29
+ * Always prints a console summary; file reporters write to outputPath.
30
+ *
31
+ * @returns The output file path (empty string for console-only).
32
+ */
33
+ function runReporter(format, summary, outputPath) {
34
+ // Always print the console report
35
+ (0, console_1.printConsoleReport)(summary);
36
+ if (format === 'console')
37
+ return '';
38
+ const filePath = outputPath || defaultOutputPath(format, summary.targetDir);
39
+ switch (format) {
40
+ case 'json':
41
+ (0, json_1.writeJsonReport)(summary, filePath);
42
+ break;
43
+ case 'csv':
44
+ (0, csv_1.writeCsvReport)(summary, filePath);
45
+ break;
46
+ case 'markdown':
47
+ (0, markdown_1.writeMarkdownReport)(summary, filePath);
48
+ break;
49
+ }
50
+ return filePath;
51
+ }
52
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/reporter/index.ts"],"names":[],"mappings":";;;;;;;AAAA,gDAAwB;AAExB,uCAA+C;AAC/C,iCAAyC;AACzC,+BAAuC;AACvC,yCAAiD;AAEjD,MAAM,OAAO,GAAqD;IAChE,IAAI,EAAE,MAAM;IACZ,GAAG,EAAE,KAAK;IACV,QAAQ,EAAE,IAAI;CACf,CAAC;AAEF;;GAEG;AACH,2BAAkC,MAAoB,EAAE,SAAiB;IACvE,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACpC,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5B,OAAO,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,sBAAsB,GAAG,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;GAKG;AACH,qBACE,MAAoB,EACpB,OAAoB,EACpB,UAAmB;IAEnB,kCAAkC;IAClC,IAAA,4BAAkB,EAAC,OAAO,CAAC,CAAC;IAE5B,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IAEpC,MAAM,QAAQ,GAAG,UAAU,IAAI,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAE5E,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,MAAM;YACT,IAAA,sBAAe,EAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACnC,MAAM;QACR,KAAK,KAAK;YACR,IAAA,oBAAc,EAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAClC,MAAM;QACR,KAAK,UAAU;YACb,IAAA,8BAAmB,EAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACvC,MAAM;IACV,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { ScanSummary } from '../types';
2
+ /**
3
+ * Writes a JSON report of the scan summary to disk.
4
+ * The raw secret values are masked in the report.
5
+ */
6
+ export declare function writeJsonReport(summary: ScanSummary, outputPath: string): void;
7
+ //# sourceMappingURL=json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/reporter/json.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAqB9E"}
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.writeJsonReport = writeJsonReport;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ /**
10
+ * Writes a JSON report of the scan summary to disk.
11
+ * The raw secret values are masked in the report.
12
+ */
13
+ function writeJsonReport(summary, outputPath) {
14
+ const sanitized = {
15
+ ...summary,
16
+ findings: summary.findings.map(f => ({
17
+ file: f.file,
18
+ line: f.line,
19
+ column: f.column,
20
+ envKey: f.envKey,
21
+ ruleId: f.rule.id,
22
+ description: f.rule.description,
23
+ severity: f.rule.severity,
24
+ // Mask the value in the report
25
+ maskedValue: maskValue(f.rawValue),
26
+ lineContent: f.lineContent.trim(),
27
+ })),
28
+ };
29
+ const dir = path_1.default.dirname(outputPath);
30
+ if (!fs_1.default.existsSync(dir))
31
+ fs_1.default.mkdirSync(dir, { recursive: true });
32
+ fs_1.default.writeFileSync(outputPath, JSON.stringify(sanitized, null, 2), 'utf-8');
33
+ }
34
+ function maskValue(value) {
35
+ if (value.length <= 8)
36
+ return '*'.repeat(value.length);
37
+ return value.slice(0, 4) + '*'.repeat(Math.min(value.length - 8, 20)) + value.slice(-4);
38
+ }
39
+ //# sourceMappingURL=json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/reporter/json.ts"],"names":[],"mappings":";;;;;;AAAA,4CAAoB;AACpB,gDAAwB;AAGxB;;;GAGG;AACH,yBAAgC,OAAoB,EAAE,UAAkB;IACtE,MAAM,SAAS,GAAG;QAChB,GAAG,OAAO;QACV,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACnC,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE;YACjB,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW;YAC/B,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ;YACzB,+BAA+B;YAC/B,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;YAClC,WAAW,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE;SAClC,CAAC,CAAC;KACJ,CAAC;IAEF,MAAM,GAAG,GAAG,cAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACrC,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,YAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEhE,YAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AAC5E,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACvD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1F,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { ScanSummary } from '../types';
2
+ /**
3
+ * Writes a Markdown report suitable for GitHub/GitLab issue or PR comments.
4
+ */
5
+ export declare function writeMarkdownReport(summary: ScanSummary, outputPath: string): void;
6
+ //# sourceMappingURL=markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/reporter/markdown.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAqB,MAAM,UAAU,CAAC;AA+B1D;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CA0ElF"}
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.writeMarkdownReport = writeMarkdownReport;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const SEVERITY_BADGE = {
10
+ critical: '![critical](https://img.shields.io/badge/severity-CRITICAL-red)',
11
+ high: '![high](https://img.shields.io/badge/severity-HIGH-orange)',
12
+ medium: '![medium](https://img.shields.io/badge/severity-MEDIUM-yellow)',
13
+ low: '![low](https://img.shields.io/badge/severity-LOW-blue)',
14
+ };
15
+ const SEVERITY_EMOJI = {
16
+ critical: '🚨',
17
+ high: '🔴',
18
+ medium: '🟡',
19
+ low: '🔵',
20
+ };
21
+ function maskValue(value) {
22
+ if (value.length <= 8)
23
+ return '`' + '*'.repeat(value.length) + '`';
24
+ const masked = value.slice(0, 4) + '*'.repeat(Math.min(value.length - 8, 20)) + value.slice(-4);
25
+ return '`' + masked + '`';
26
+ }
27
+ function groupByFile(findings) {
28
+ const map = new Map();
29
+ for (const f of findings) {
30
+ if (!map.has(f.file))
31
+ map.set(f.file, []);
32
+ map.get(f.file).push(f);
33
+ }
34
+ return map;
35
+ }
36
+ /**
37
+ * Writes a Markdown report suitable for GitHub/GitLab issue or PR comments.
38
+ */
39
+ function writeMarkdownReport(summary, outputPath) {
40
+ const { findings, filesScanned, filesWithSecrets, totalFindings, dryRun, envFile, scannedAt, targetDir } = summary;
41
+ const lines = [];
42
+ lines.push('# 🔐 Code Secret Handler — Scan Report\n');
43
+ lines.push(`> Generated: \`${scannedAt}\`\n`);
44
+ lines.push(`- **Target directory:** \`${targetDir}\` `);
45
+ lines.push(`- **Files scanned:** ${filesScanned} `);
46
+ lines.push(`- **Files with secrets:** ${filesWithSecrets} `);
47
+ lines.push(`- **Total secrets found:** **${totalFindings}** `);
48
+ lines.push(`- **Env file:** \`${envFile}\` `);
49
+ if (dryRun)
50
+ lines.push(`- ⚠️ **DRY RUN** — no files were modified`);
51
+ lines.push('');
52
+ if (totalFindings === 0) {
53
+ lines.push('## ✅ No hardcoded secrets detected!\n');
54
+ lines.push('Great job keeping your codebase clean.\n');
55
+ }
56
+ else {
57
+ // Severity summary table
58
+ const bySeverity = { critical: 0, high: 0, medium: 0, low: 0 };
59
+ for (const f of findings)
60
+ bySeverity[f.rule.severity]++;
61
+ lines.push('## Summary\n');
62
+ lines.push('| Severity | Count |');
63
+ lines.push('|----------|-------|');
64
+ for (const [sev, count] of Object.entries(bySeverity)) {
65
+ if (count === 0)
66
+ continue;
67
+ lines.push(`| ${SEVERITY_EMOJI[sev]} ${sev.toUpperCase()} | ${count} |`);
68
+ }
69
+ lines.push('');
70
+ // Findings by file
71
+ lines.push('## Findings\n');
72
+ const byFile = groupByFile(findings);
73
+ for (const [filePath, fileFindings] of byFile) {
74
+ const relPath = path_1.default.relative(targetDir, filePath);
75
+ lines.push(`### 📄 \`${relPath}\`\n`);
76
+ lines.push('| Line | Col | Severity | Rule | Description | Env Key | Masked Value |');
77
+ lines.push('|------|-----|----------|------|-------------|---------|--------------|');
78
+ for (const f of fileFindings) {
79
+ lines.push(`| ${f.line} | ${f.column} | ${SEVERITY_EMOJI[f.rule.severity]} ${f.rule.severity.toUpperCase()} | \`${f.rule.id}\` | ${f.rule.description} | \`${f.envKey}\` | ${maskValue(f.rawValue)} |`);
80
+ }
81
+ lines.push('');
82
+ // Code snippet for each finding
83
+ for (const f of fileFindings) {
84
+ lines.push('<details>');
85
+ lines.push(`<summary>Line ${f.line} — <code>${f.rule.id}</code></summary>\n`);
86
+ lines.push('```');
87
+ lines.push(f.lineContent);
88
+ lines.push('```\n');
89
+ lines.push('</details>\n');
90
+ }
91
+ }
92
+ // Recommendations
93
+ lines.push('## 🛡️ Recommendations\n');
94
+ lines.push('1. Verify the changes made to your source files.');
95
+ lines.push('2. Ensure `.env` is listed in `.gitignore`.');
96
+ lines.push('3. Rotate any secrets that may have been exposed in git history.');
97
+ lines.push('4. Consider using a secrets manager (AWS Secrets Manager, HashiCorp Vault, etc.).');
98
+ lines.push('5. Set up a pre-commit hook to prevent future secret leaks.');
99
+ lines.push('');
100
+ }
101
+ const dir = path_1.default.dirname(outputPath);
102
+ if (!fs_1.default.existsSync(dir))
103
+ fs_1.default.mkdirSync(dir, { recursive: true });
104
+ fs_1.default.writeFileSync(outputPath, lines.join('\n'), 'utf-8');
105
+ }
106
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/reporter/markdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { Finding, RewriteResult } from '../types';
2
+ /**
3
+ * Groups findings by file, applies the correct language rewriter to each file,
4
+ * and writes the updated content back to disk.
5
+ *
6
+ * @returns Array of RewriteResult, one per modified file.
7
+ */
8
+ export declare function rewriteFiles(findings: Finding[], dryRun?: boolean): RewriteResult[];
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rewriter/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAA4B,aAAa,EAAE,MAAM,UAAU,CAAC;AAmC5E;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,MAAM,UAAQ,GAAG,aAAa,EAAE,CAyDjF"}
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.rewriteFiles = rewriteFiles;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const langDetector_1 = require("./langDetector");
9
+ const javascript_1 = require("./templates/javascript");
10
+ const python_1 = require("./templates/python");
11
+ const java_1 = require("./templates/java");
12
+ const go_1 = require("./templates/go");
13
+ const ruby_1 = require("./templates/ruby");
14
+ const php_1 = require("./templates/php");
15
+ const csharp_1 = require("./templates/csharp");
16
+ const rust_1 = require("./templates/rust");
17
+ const shell_1 = require("./templates/shell");
18
+ const yaml_1 = require("./templates/yaml");
19
+ const properties_1 = require("./templates/properties");
20
+ const toml_1 = require("./templates/toml");
21
+ const generic_1 = require("./templates/generic");
22
+ const REWRITERS = {
23
+ javascript: javascript_1.rewriteJavaScript,
24
+ typescript: javascript_1.rewriteJavaScript, // TS uses same accessor as JS
25
+ python: python_1.rewritePython,
26
+ java: java_1.rewriteJava,
27
+ go: go_1.rewriteGo,
28
+ ruby: ruby_1.rewriteRuby,
29
+ php: php_1.rewritePhp,
30
+ csharp: csharp_1.rewriteCSharp,
31
+ rust: rust_1.rewriteRust,
32
+ shell: shell_1.rewriteShell,
33
+ yaml: yaml_1.rewriteYaml,
34
+ toml: toml_1.rewriteToml,
35
+ properties: properties_1.rewriteProperties,
36
+ generic: generic_1.rewriteGeneric,
37
+ };
38
+ /**
39
+ * Groups findings by file, applies the correct language rewriter to each file,
40
+ * and writes the updated content back to disk.
41
+ *
42
+ * @returns Array of RewriteResult, one per modified file.
43
+ */
44
+ function rewriteFiles(findings, dryRun = false) {
45
+ // Group findings by file
46
+ const byFile = new Map();
47
+ for (const finding of findings) {
48
+ if (!byFile.has(finding.file))
49
+ byFile.set(finding.file, []);
50
+ byFile.get(finding.file).push(finding);
51
+ }
52
+ const results = [];
53
+ for (const [filePath, fileFindings] of byFile) {
54
+ let fileContent;
55
+ try {
56
+ fileContent = fs_1.default.readFileSync(filePath, 'utf-8');
57
+ }
58
+ catch {
59
+ continue;
60
+ }
61
+ const language = (0, langDetector_1.detectLanguage)(filePath);
62
+ const rewriterFn = REWRITERS[language];
63
+ // Apply each finding's rewrite sequentially on the evolving content
64
+ let currentContent = fileContent;
65
+ let totalReplacements = 0;
66
+ let dotenvInjected = false;
67
+ for (const finding of fileFindings) {
68
+ const ctx = {
69
+ finding,
70
+ language,
71
+ fileContent: currentContent,
72
+ };
73
+ const result = rewriterFn(ctx);
74
+ if (result.replacements > 0) {
75
+ currentContent = result.rewrittenContent;
76
+ totalReplacements += result.replacements;
77
+ if (result.dotenvInjected)
78
+ dotenvInjected = true;
79
+ }
80
+ }
81
+ const finalResult = {
82
+ filePath,
83
+ originalContent: fileContent,
84
+ rewrittenContent: currentContent,
85
+ replacements: totalReplacements,
86
+ dotenvInjected,
87
+ };
88
+ results.push(finalResult);
89
+ if (!dryRun && totalReplacements > 0) {
90
+ fs_1.default.writeFileSync(filePath, currentContent, 'utf-8');
91
+ }
92
+ }
93
+ return results;
94
+ }
95
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rewriter/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { Language } from '../types';
2
+ /**
3
+ * Detects the programming language of a file by its path.
4
+ * Falls back to 'generic' if unknown.
5
+ */
6
+ export declare function detectLanguage(filePath: string): Language;
7
+ //# sourceMappingURL=langDetector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"langDetector.d.ts","sourceRoot":"","sources":["../../src/rewriter/langDetector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AA6EpC;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAWzD"}
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.detectLanguage = detectLanguage;
7
+ const path_1 = __importDefault(require("path"));
8
+ /**
9
+ * Maps file extensions to language identifiers.
10
+ */
11
+ const EXT_MAP = {
12
+ // JavaScript / TypeScript
13
+ '.js': 'javascript',
14
+ '.jsx': 'javascript',
15
+ '.mjs': 'javascript',
16
+ '.cjs': 'javascript',
17
+ '.ts': 'typescript',
18
+ '.tsx': 'typescript',
19
+ '.vue': 'javascript', // Vue SFCs use JS/TS — use JS accessor
20
+ '.svelte': 'javascript', // Svelte uses JS
21
+ // Python
22
+ '.py': 'python',
23
+ '.pyw': 'python',
24
+ // Java / Kotlin / Scala
25
+ '.java': 'java',
26
+ '.kt': 'java',
27
+ '.kts': 'java',
28
+ '.scala': 'java',
29
+ '.groovy': 'java',
30
+ // Go
31
+ '.go': 'go',
32
+ // Ruby
33
+ '.rb': 'ruby',
34
+ '.rake': 'ruby',
35
+ '.gemspec': 'ruby',
36
+ // PHP
37
+ '.php': 'php',
38
+ '.php3': 'php',
39
+ '.php4': 'php',
40
+ '.php5': 'php',
41
+ '.phtml': 'php',
42
+ // C# / .NET
43
+ '.cs': 'csharp',
44
+ '.vb': 'csharp',
45
+ '.fs': 'csharp',
46
+ '.fsx': 'csharp',
47
+ // Rust
48
+ '.rs': 'rust',
49
+ // Shell
50
+ '.sh': 'shell',
51
+ '.bash': 'shell',
52
+ '.zsh': 'shell',
53
+ '.fish': 'shell',
54
+ '.ps1': 'shell',
55
+ '.psm1': 'shell',
56
+ '.bat': 'shell',
57
+ '.cmd': 'shell',
58
+ // Config formats (YAML, TOML, properties)
59
+ '.yaml': 'yaml',
60
+ '.yml': 'yaml',
61
+ '.toml': 'toml',
62
+ '.ini': 'properties',
63
+ '.properties': 'properties',
64
+ '.conf': 'properties',
65
+ '.env': 'properties',
66
+ };
67
+ /**
68
+ * Exact filename mappings (no extension or special names).
69
+ */
70
+ const FILENAME_MAP = {
71
+ Dockerfile: 'shell',
72
+ Makefile: 'shell',
73
+ '.env': 'properties',
74
+ '.envrc': 'shell',
75
+ '.bashrc': 'shell',
76
+ '.zshrc': 'shell',
77
+ '.profile': 'shell',
78
+ Gemfile: 'ruby',
79
+ Rakefile: 'ruby',
80
+ };
81
+ /**
82
+ * Detects the programming language of a file by its path.
83
+ * Falls back to 'generic' if unknown.
84
+ */
85
+ function detectLanguage(filePath) {
86
+ const basename = path_1.default.basename(filePath);
87
+ const ext = path_1.default.extname(filePath).toLowerCase();
88
+ // Check exact filename first
89
+ if (FILENAME_MAP[basename])
90
+ return FILENAME_MAP[basename];
91
+ // Check extension
92
+ if (ext && EXT_MAP[ext])
93
+ return EXT_MAP[ext];
94
+ return 'generic';
95
+ }
96
+ //# sourceMappingURL=langDetector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"langDetector.js","sourceRoot":"","sources":["../../src/rewriter/langDetector.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AAGxB;;GAEG;AACH,MAAM,OAAO,GAA6B;IACxC,0BAA0B;IAC1B,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY,EAAM,uCAAuC;IACjE,SAAS,EAAE,YAAY,EAAG,iBAAiB;IAC3C,SAAS;IACT,KAAK,EAAE,QAAQ;IACf,MAAM,EAAE,QAAQ;IAChB,wBAAwB;IACxB,OAAO,EAAE,MAAM;IACf,KAAK,EAAE,MAAM;IACb,MAAM,EAAE,MAAM;IACd,QAAQ,EAAE,MAAM;IAChB,SAAS,EAAE,MAAM;IACjB,KAAK;IACL,KAAK,EAAE,IAAI;IACX,OAAO;IACP,KAAK,EAAE,MAAM;IACb,OAAO,EAAE,MAAM;IACf,UAAU,EAAE,MAAM;IAClB,MAAM;IACN,MAAM,EAAE,KAAK;IACb,OAAO,EAAE,KAAK;IACd,OAAO,EAAE,KAAK;IACd,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,KAAK;IACf,YAAY;IACZ,KAAK,EAAE,QAAQ;IACf,KAAK,EAAE,QAAQ;IACf,KAAK,EAAE,QAAQ;IACf,MAAM,EAAE,QAAQ;IAChB,OAAO;IACP,KAAK,EAAE,MAAM;IACb,QAAQ;IACR,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,OAAO;IAChB,MAAM,EAAE,OAAO;IACf,OAAO,EAAE,OAAO;IAChB,MAAM,EAAE,OAAO;IACf,OAAO,EAAE,OAAO;IAChB,MAAM,EAAE,OAAO;IACf,MAAM,EAAE,OAAO;IACf,0CAA0C;IAC1C,OAAO,EAAE,MAAM;IACf,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,MAAM;IACf,MAAM,EAAE,YAAY;IACpB,aAAa,EAAE,YAAY;IAC3B,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,YAAY;CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,YAAY,GAA6B;IAC7C,UAAU,EAAE,OAAO;IACnB,QAAQ,EAAE,OAAO;IACjB,MAAM,EAAE,YAAY;IACpB,QAAQ,EAAE,OAAO;IACjB,SAAS,EAAE,OAAO;IAClB,QAAQ,EAAE,OAAO;IACjB,UAAU,EAAE,OAAO;IACnB,OAAO,EAAE,MAAM;IACf,QAAQ,EAAE,MAAM;CACjB,CAAC;AAEF;;;GAGG;AACH,wBAA+B,QAAgB;IAC7C,MAAM,QAAQ,GAAG,cAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACzC,MAAM,GAAG,GAAG,cAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IAEjD,6BAA6B;IAC7B,IAAI,YAAY,CAAC,QAAQ,CAAC;QAAE,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC;IAE1D,kBAAkB;IAClB,IAAI,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC;IAE7C,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { RewriteContext, RewriteResult } from '../../types';
2
+ /**
3
+ * Rewrites C# / .NET files:
4
+ * - Replaces literal secret with `Environment.GetEnvironmentVariable("KEY")`
5
+ * - Adds `using System;` if not present
6
+ */
7
+ export declare function rewriteCSharp(ctx: RewriteContext): RewriteResult;
8
+ //# sourceMappingURL=csharp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csharp.d.ts","sourceRoot":"","sources":["../../../src/rewriter/templates/csharp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5D;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,cAAc,GAAG,aAAa,CA8BhE"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rewriteCSharp = rewriteCSharp;
4
+ /**
5
+ * Rewrites C# / .NET files:
6
+ * - Replaces literal secret with `Environment.GetEnvironmentVariable("KEY")`
7
+ * - Adds `using System;` if not present
8
+ */
9
+ function rewriteCSharp(ctx) {
10
+ const { finding, fileContent } = ctx;
11
+ const { rawValue, envKey } = finding;
12
+ let rewrittenContent = fileContent;
13
+ let replacements = 0;
14
+ let dotenvInjected = false;
15
+ const escaped = rawValue.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
16
+ const re = new RegExp(`"${escaped}"`, 'g');
17
+ if (re.test(rewrittenContent)) {
18
+ rewrittenContent = rewrittenContent.replace(re, `Environment.GetEnvironmentVariable("${envKey}")`);
19
+ replacements++;
20
+ }
21
+ if (replacements === 0)
22
+ return { filePath: finding.file, originalContent: fileContent, rewrittenContent: fileContent, replacements: 0, dotenvInjected: false };
23
+ const hasSystemUsing = /^using System;/m.test(rewrittenContent);
24
+ if (!hasSystemUsing) {
25
+ rewrittenContent = `using System;\n` + rewrittenContent;
26
+ dotenvInjected = true;
27
+ }
28
+ return {
29
+ filePath: finding.file,
30
+ originalContent: fileContent,
31
+ rewrittenContent,
32
+ replacements,
33
+ dotenvInjected,
34
+ };
35
+ }
36
+ //# sourceMappingURL=csharp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csharp.js","sourceRoot":"","sources":["../../../src/rewriter/templates/csharp.ts"],"names":[],"mappings":";;;AAEA;;;;GAIG;AACH,uBAA8B,GAAmB;IAC/C,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC;IACrC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAErC,IAAI,gBAAgB,GAAG,WAAW,CAAC;IACnC,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,cAAc,GAAG,KAAK,CAAC;IAE3B,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;IAChE,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,IAAI,OAAO,GAAG,EAAE,GAAG,CAAC,CAAC;IAC3C,IAAI,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAC9B,gBAAgB,GAAG,gBAAgB,CAAC,OAAO,CAAC,EAAE,EAAE,uCAAuC,MAAM,IAAI,CAAC,CAAC;QACnG,YAAY,EAAE,CAAC;IACjB,CAAC;IAED,IAAI,YAAY,KAAK,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,EAAE,eAAe,EAAE,WAAW,EAAE,gBAAgB,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC;IAE/J,MAAM,cAAc,GAAG,iBAAiB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAChE,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,gBAAgB,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;QACxD,cAAc,GAAG,IAAI,CAAC;IACxB,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,OAAO,CAAC,IAAI;QACtB,eAAe,EAAE,WAAW;QAC5B,gBAAgB;QAChB,YAAY;QACZ,cAAc;KACf,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { RewriteContext, RewriteResult } from '../../types';
2
+ /**
3
+ * Generic fallback rewriter:
4
+ * - Replaces the literal secret with `${KEY}` wherever it appears as a quoted string.
5
+ */
6
+ export declare function rewriteGeneric(ctx: RewriteContext): RewriteResult;
7
+ //# sourceMappingURL=generic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic.d.ts","sourceRoot":"","sources":["../../../src/rewriter/templates/generic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5D;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,cAAc,GAAG,aAAa,CAmCjE"}