verification-layer 0.4.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 (95) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +345 -0
  3. package/dist/audit/evidence.d.ts +25 -0
  4. package/dist/audit/evidence.d.ts.map +1 -0
  5. package/dist/audit/evidence.js +70 -0
  6. package/dist/audit/evidence.js.map +1 -0
  7. package/dist/audit/index.d.ts +54 -0
  8. package/dist/audit/index.d.ts.map +1 -0
  9. package/dist/audit/index.js +159 -0
  10. package/dist/audit/index.js.map +1 -0
  11. package/dist/cli.d.ts +3 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +199 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/config.d.ts +7 -0
  16. package/dist/config.d.ts.map +1 -0
  17. package/dist/config.js +77 -0
  18. package/dist/config.js.map +1 -0
  19. package/dist/fixer/index.d.ts +11 -0
  20. package/dist/fixer/index.d.ts.map +1 -0
  21. package/dist/fixer/index.js +171 -0
  22. package/dist/fixer/index.js.map +1 -0
  23. package/dist/fixer/strategies.d.ts +3 -0
  24. package/dist/fixer/strategies.d.ts.map +1 -0
  25. package/dist/fixer/strategies.js +199 -0
  26. package/dist/fixer/strategies.js.map +1 -0
  27. package/dist/index.d.ts +4 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +3 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/reporters/audit-report.d.ts +13 -0
  32. package/dist/reporters/audit-report.d.ts.map +1 -0
  33. package/dist/reporters/audit-report.js +526 -0
  34. package/dist/reporters/audit-report.js.map +1 -0
  35. package/dist/reporters/fix-report.d.ts +3 -0
  36. package/dist/reporters/fix-report.d.ts.map +1 -0
  37. package/dist/reporters/fix-report.js +70 -0
  38. package/dist/reporters/fix-report.js.map +1 -0
  39. package/dist/reporters/index.d.ts +3 -0
  40. package/dist/reporters/index.d.ts.map +1 -0
  41. package/dist/reporters/index.js +425 -0
  42. package/dist/reporters/index.js.map +1 -0
  43. package/dist/reporters/remediation-guides.d.ts +25 -0
  44. package/dist/reporters/remediation-guides.d.ts.map +1 -0
  45. package/dist/reporters/remediation-guides.js +636 -0
  46. package/dist/reporters/remediation-guides.js.map +1 -0
  47. package/dist/scan.d.ts +3 -0
  48. package/dist/scan.d.ts.map +1 -0
  49. package/dist/scan.js +96 -0
  50. package/dist/scan.js.map +1 -0
  51. package/dist/scanners/access/index.d.ts +3 -0
  52. package/dist/scanners/access/index.d.ts.map +1 -0
  53. package/dist/scanners/access/index.js +102 -0
  54. package/dist/scanners/access/index.js.map +1 -0
  55. package/dist/scanners/audit/index.d.ts +3 -0
  56. package/dist/scanners/audit/index.d.ts.map +1 -0
  57. package/dist/scanners/audit/index.js +94 -0
  58. package/dist/scanners/audit/index.js.map +1 -0
  59. package/dist/scanners/encryption/index.d.ts +3 -0
  60. package/dist/scanners/encryption/index.d.ts.map +1 -0
  61. package/dist/scanners/encryption/index.js +86 -0
  62. package/dist/scanners/encryption/index.js.map +1 -0
  63. package/dist/scanners/phi/index.d.ts +3 -0
  64. package/dist/scanners/phi/index.d.ts.map +1 -0
  65. package/dist/scanners/phi/index.js +47 -0
  66. package/dist/scanners/phi/index.js.map +1 -0
  67. package/dist/scanners/phi/patterns.d.ts +13 -0
  68. package/dist/scanners/phi/patterns.d.ts.map +1 -0
  69. package/dist/scanners/phi/patterns.js +242 -0
  70. package/dist/scanners/phi/patterns.js.map +1 -0
  71. package/dist/scanners/retention/index.d.ts +3 -0
  72. package/dist/scanners/retention/index.d.ts.map +1 -0
  73. package/dist/scanners/retention/index.js +102 -0
  74. package/dist/scanners/retention/index.js.map +1 -0
  75. package/dist/scanners/security/index.d.ts +3 -0
  76. package/dist/scanners/security/index.d.ts.map +1 -0
  77. package/dist/scanners/security/index.js +280 -0
  78. package/dist/scanners/security/index.js.map +1 -0
  79. package/dist/stack-detector/index.d.ts +26 -0
  80. package/dist/stack-detector/index.d.ts.map +1 -0
  81. package/dist/stack-detector/index.js +317 -0
  82. package/dist/stack-detector/index.js.map +1 -0
  83. package/dist/stack-detector/stack-guides.d.ts +16 -0
  84. package/dist/stack-detector/stack-guides.d.ts.map +1 -0
  85. package/dist/stack-detector/stack-guides.js +772 -0
  86. package/dist/stack-detector/stack-guides.js.map +1 -0
  87. package/dist/types.d.ts +143 -0
  88. package/dist/types.d.ts.map +1 -0
  89. package/dist/types.js +2 -0
  90. package/dist/types.js.map +1 -0
  91. package/dist/utils/context.d.ts +3 -0
  92. package/dist/utils/context.d.ts.map +1 -0
  93. package/dist/utils/context.js +14 -0
  94. package/dist/utils/context.js.map +1 -0
  95. package/package.json +76 -0
@@ -0,0 +1,425 @@
1
+ import { writeFile } from 'fs/promises';
2
+ import chalk from 'chalk';
3
+ import { getRemediationGuide } from './remediation-guides.js';
4
+ import { getStackSpecificGuides } from '../stack-detector/stack-guides.js';
5
+ function buildReport(result, targetPath) {
6
+ const summary = {
7
+ total: result.findings.length,
8
+ critical: result.findings.filter(f => f.severity === 'critical').length,
9
+ high: result.findings.filter(f => f.severity === 'high').length,
10
+ medium: result.findings.filter(f => f.severity === 'medium').length,
11
+ low: result.findings.filter(f => f.severity === 'low').length,
12
+ info: result.findings.filter(f => f.severity === 'info').length,
13
+ };
14
+ return {
15
+ timestamp: new Date().toISOString(),
16
+ targetPath,
17
+ summary,
18
+ findings: result.findings,
19
+ scannedFiles: result.scannedFiles,
20
+ scanDuration: result.scanDuration,
21
+ stack: result.stack,
22
+ };
23
+ }
24
+ function generateJson(report) {
25
+ return JSON.stringify(report, null, 2);
26
+ }
27
+ function renderContextMarkdown(context) {
28
+ if (!context || context.length === 0)
29
+ return '';
30
+ const lines = context.map(c => {
31
+ const prefix = c.isMatch ? '>' : ' ';
32
+ const lineNum = String(c.lineNumber).padStart(4, ' ');
33
+ return `${prefix} ${lineNum} | ${c.content}`;
34
+ });
35
+ return '\n```\n' + lines.join('\n') + '\n```\n';
36
+ }
37
+ function generateMarkdown(report) {
38
+ const lines = [
39
+ '# HIPAA Compliance Report',
40
+ '',
41
+ `**Generated:** ${report.timestamp}`,
42
+ `**Target:** ${report.targetPath}`,
43
+ `**Files Scanned:** ${report.scannedFiles}`,
44
+ `**Duration:** ${report.scanDuration}ms`,
45
+ '',
46
+ '## Summary',
47
+ '',
48
+ `| Severity | Count |`,
49
+ `|----------|-------|`,
50
+ `| Critical | ${report.summary.critical} |`,
51
+ `| High | ${report.summary.high} |`,
52
+ `| Medium | ${report.summary.medium} |`,
53
+ `| Low | ${report.summary.low} |`,
54
+ `| Info | ${report.summary.info} |`,
55
+ `| **Total** | **${report.summary.total}** |`,
56
+ '',
57
+ ];
58
+ if (report.findings.length > 0) {
59
+ lines.push('## Findings', '');
60
+ const groupedByCategory = report.findings.reduce((acc, f) => {
61
+ acc[f.category] = acc[f.category] || [];
62
+ acc[f.category].push(f);
63
+ return acc;
64
+ }, {});
65
+ for (const [category, findings] of Object.entries(groupedByCategory)) {
66
+ lines.push(`### ${formatCategory(category)}`, '');
67
+ for (const finding of findings) {
68
+ lines.push(`#### ${severityBadge(finding.severity)} ${finding.title}`, '', `**File:** \`${finding.file}\`${finding.line ? `:${finding.line}` : ''}`, '', finding.description, '');
69
+ // Add context if available
70
+ if (finding.context && finding.context.length > 0) {
71
+ lines.push(renderContextMarkdown(finding.context));
72
+ }
73
+ lines.push(`**Recommendation:** ${finding.recommendation}`, '');
74
+ if (finding.hipaaReference) {
75
+ lines.push(`**HIPAA Reference:** ${finding.hipaaReference}`, '');
76
+ }
77
+ lines.push('---', '');
78
+ }
79
+ }
80
+ }
81
+ else {
82
+ lines.push('## No Issues Found', '', 'The scan did not detect any HIPAA compliance issues.');
83
+ }
84
+ return lines.join('\n');
85
+ }
86
+ function renderContextHtml(context) {
87
+ if (!context || context.length === 0)
88
+ return '';
89
+ const lines = context.map(c => {
90
+ const lineNum = String(c.lineNumber).padStart(4, ' ');
91
+ const highlightClass = c.isMatch ? 'highlight' : '';
92
+ return `<div class="context-line ${highlightClass}"><span class="line-num">${lineNum}</span><span class="line-content">${escapeHtml(c.content)}</span></div>`;
93
+ });
94
+ return `<div class="context">${lines.join('')}</div>`;
95
+ }
96
+ function renderRemediationGuide(guide) {
97
+ return `
98
+ <div class="remediation-guide">
99
+ <div class="hipaa-impact">
100
+ <h5>HIPAA Impact</h5>
101
+ <p>${escapeHtml(guide.hipaaImpact).replace(/\n/g, '<br>')}</p>
102
+ </div>
103
+
104
+ <div class="fix-options">
105
+ <h5>How to Fix</h5>
106
+ ${guide.options.map((option, index) => `
107
+ <details class="fix-option" ${index === 0 ? 'open' : ''}>
108
+ <summary>${escapeHtml(option.title)}</summary>
109
+ <p class="option-desc">${escapeHtml(option.description)}</p>
110
+ <pre class="code-block"><code class="language-${option.language}">${escapeHtml(option.code)}</code></pre>
111
+ </details>
112
+ `).join('')}
113
+ </div>
114
+
115
+ <div class="documentation-links">
116
+ <h5>Documentation</h5>
117
+ <ul>
118
+ ${guide.documentation.map(doc => `
119
+ <li><a href="${escapeHtml(doc.url)}" target="_blank" rel="noopener">${escapeHtml(doc.title)}</a></li>
120
+ `).join('')}
121
+ </ul>
122
+ </div>
123
+ </div>
124
+ `;
125
+ }
126
+ function renderStackGuide(guide) {
127
+ return `
128
+ <div class="stack-guide">
129
+ <details class="fix-option" open>
130
+ <summary>${escapeHtml(guide.title)}</summary>
131
+ <p class="option-desc">${escapeHtml(guide.description)}</p>
132
+ <pre class="code-block"><code class="language-${guide.language}">${escapeHtml(guide.code)}</code></pre>
133
+ </details>
134
+ </div>
135
+ `;
136
+ }
137
+ function renderStackSection(stack) {
138
+ // Get stack-specific guides
139
+ const detectedStack = {
140
+ framework: stack.framework,
141
+ database: stack.database,
142
+ auth: stack.auth,
143
+ dependencies: [],
144
+ confidence: { framework: 1, database: 1, auth: 1 },
145
+ details: {},
146
+ };
147
+ const guides = getStackSpecificGuides(detectedStack);
148
+ return `
149
+ <div class="stack-section">
150
+ <h2>Stack Detected</h2>
151
+ <div class="stack-cards">
152
+ <div class="stack-card">
153
+ <div class="stack-icon">⚡</div>
154
+ <div class="stack-label">Framework</div>
155
+ <div class="stack-value">${escapeHtml(stack.frameworkDisplay)}</div>
156
+ </div>
157
+ <div class="stack-card">
158
+ <div class="stack-icon">🗄️</div>
159
+ <div class="stack-label">Database</div>
160
+ <div class="stack-value">${escapeHtml(stack.databaseDisplay)}</div>
161
+ </div>
162
+ <div class="stack-card">
163
+ <div class="stack-icon">🔐</div>
164
+ <div class="stack-label">Authentication</div>
165
+ <div class="stack-value">${escapeHtml(stack.authDisplay)}</div>
166
+ </div>
167
+ </div>
168
+
169
+ ${stack.recommendations.length > 0 ? `
170
+ <div class="stack-recommendations">
171
+ <h3>Stack-Specific Recommendations</h3>
172
+ <ul>
173
+ ${stack.recommendations.map(rec => `<li>${escapeHtml(rec)}</li>`).join('')}
174
+ </ul>
175
+ </div>
176
+ ` : ''}
177
+
178
+ ${guides.session.length > 0 || guides.database.length > 0 || guides.auth.length > 0 ? `
179
+ <div class="stack-guides">
180
+ <h3>Code Examples for Your Stack</h3>
181
+
182
+ ${guides.session.length > 0 ? `
183
+ <div class="guide-category">
184
+ <h4>🔒 Session Management (${stack.frameworkDisplay})</h4>
185
+ ${guides.session.map(g => renderStackGuide(g)).join('')}
186
+ </div>
187
+ ` : ''}
188
+
189
+ ${guides.database.length > 0 ? `
190
+ <div class="guide-category">
191
+ <h4>🗄️ Database Security (${stack.databaseDisplay})</h4>
192
+ ${guides.database.map(g => renderStackGuide(g)).join('')}
193
+ </div>
194
+ ` : ''}
195
+
196
+ ${guides.auth.length > 0 ? `
197
+ <div class="guide-category">
198
+ <h4>🔐 Authentication (${stack.authDisplay})</h4>
199
+ ${guides.auth.map(g => renderStackGuide(g)).join('')}
200
+ </div>
201
+ ` : ''}
202
+ </div>
203
+ ` : ''}
204
+ </div>
205
+ `;
206
+ }
207
+ function generateHtml(report) {
208
+ const severityColors = {
209
+ critical: '#dc2626',
210
+ high: '#ea580c',
211
+ medium: '#ca8a04',
212
+ low: '#2563eb',
213
+ info: '#6b7280',
214
+ };
215
+ return `<!DOCTYPE html>
216
+ <html lang="en">
217
+ <head>
218
+ <meta charset="UTF-8">
219
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
220
+ <title>HIPAA Compliance Report - vlayer</title>
221
+ <style>
222
+ * { margin: 0; padding: 0; box-sizing: border-box; }
223
+ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #1f2937; background: #f9fafb; padding: 2rem; }
224
+ .container { max-width: 1400px; margin: 0 auto; }
225
+ h1 { color: #111827; margin-bottom: 0.5rem; }
226
+ h2 { color: #374151; margin: 2rem 0 1rem; }
227
+ .meta { color: #6b7280; margin-bottom: 2rem; }
228
+ .summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1rem; margin-bottom: 2rem; }
229
+ .summary-card { background: white; padding: 1rem; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); text-align: center; }
230
+ .summary-card .count { font-size: 2rem; font-weight: bold; }
231
+ .findings { display: flex; flex-direction: column; gap: 1.5rem; }
232
+ .finding { background: white; padding: 1.5rem; border-radius: 12px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); border-left: 4px solid; }
233
+ .finding h3 { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem; flex-wrap: wrap; }
234
+ .badge { padding: 0.25rem 0.5rem; border-radius: 4px; font-size: 0.75rem; font-weight: 600; color: white; text-transform: uppercase; }
235
+ .badge-fixable { background: #059669; margin-left: 0.5rem; }
236
+ .file { font-family: 'SF Mono', Monaco, 'Courier New', monospace; background: #f3f4f6; padding: 0.25rem 0.5rem; border-radius: 4px; font-size: 0.875rem; word-break: break-all; }
237
+ .context { margin: 1rem 0; background: #1e1e1e; border-radius: 6px; padding: 0.75rem; overflow-x: auto; }
238
+ .context-line { font-family: 'SF Mono', Monaco, 'Courier New', monospace; font-size: 0.8rem; line-height: 1.5; white-space: pre; color: #d4d4d4; }
239
+ .context-line.highlight { background: rgba(234, 88, 12, 0.3); color: #fff; }
240
+ .context-line .line-num { color: #6b7280; margin-right: 1rem; user-select: none; }
241
+ .recommendation { margin-top: 1rem; padding: 1rem; background: #eff6ff; border-radius: 6px; border-left: 3px solid #3b82f6; }
242
+ .hipaa-ref { color: #6b7280; font-size: 0.875rem; margin-top: 0.5rem; }
243
+
244
+ /* Remediation Guide Styles */
245
+ .guide-toggle { margin-top: 1rem; }
246
+ .guide-toggle summary { cursor: pointer; padding: 0.75rem 1rem; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 6px; font-weight: 600; list-style: none; display: flex; align-items: center; gap: 0.5rem; }
247
+ .guide-toggle summary::-webkit-details-marker { display: none; }
248
+ .guide-toggle summary::before { content: '▶'; font-size: 0.75rem; transition: transform 0.2s; }
249
+ .guide-toggle[open] summary::before { transform: rotate(90deg); }
250
+ .guide-toggle summary:hover { opacity: 0.9; }
251
+
252
+ .remediation-guide { padding: 1.5rem; background: #fefefe; border: 1px solid #e5e7eb; border-top: none; border-radius: 0 0 6px 6px; }
253
+ .remediation-guide h5 { color: #374151; margin: 1rem 0 0.5rem; font-size: 0.95rem; border-bottom: 1px solid #e5e7eb; padding-bottom: 0.25rem; }
254
+ .remediation-guide h5:first-child { margin-top: 0; }
255
+
256
+ .hipaa-impact { background: #fef2f2; padding: 1rem; border-radius: 6px; border-left: 3px solid #dc2626; margin-bottom: 1rem; }
257
+ .hipaa-impact p { color: #7f1d1d; font-size: 0.9rem; }
258
+
259
+ .fix-options { margin: 1rem 0; }
260
+ .fix-option { margin: 0.75rem 0; border: 1px solid #e5e7eb; border-radius: 6px; overflow: hidden; }
261
+ .fix-option summary { padding: 0.75rem 1rem; background: #f9fafb; cursor: pointer; font-weight: 500; color: #1f2937; }
262
+ .fix-option summary:hover { background: #f3f4f6; }
263
+ .fix-option[open] summary { border-bottom: 1px solid #e5e7eb; }
264
+ .option-desc { padding: 1rem; color: #4b5563; font-size: 0.9rem; background: #fff; }
265
+
266
+ .code-block { margin: 0; padding: 1rem; background: #1e1e1e; border-radius: 0 0 6px 6px; overflow-x: auto; }
267
+ .code-block code { font-family: 'SF Mono', Monaco, 'Courier New', monospace; font-size: 0.8rem; color: #d4d4d4; white-space: pre; }
268
+
269
+ .documentation-links { margin-top: 1rem; }
270
+ .documentation-links ul { list-style: none; display: flex; flex-wrap: wrap; gap: 0.5rem; }
271
+ .documentation-links li a { display: inline-block; padding: 0.35rem 0.75rem; background: #e0e7ff; color: #3730a3; border-radius: 4px; text-decoration: none; font-size: 0.85rem; transition: background 0.2s; }
272
+ .documentation-links li a:hover { background: #c7d2fe; }
273
+
274
+ /* Syntax highlighting (basic) */
275
+ .code-block .keyword { color: #c586c0; }
276
+ .code-block .string { color: #ce9178; }
277
+ .code-block .comment { color: #6a9955; }
278
+ .code-block .function { color: #dcdcaa; }
279
+
280
+ /* Stack Section Styles */
281
+ .stack-section { margin: 2rem 0; padding: 1.5rem; background: linear-gradient(135deg, #667eea15 0%, #764ba215 100%); border-radius: 12px; border: 1px solid #e5e7eb; }
282
+ .stack-section h2 { color: #374151; margin-bottom: 1rem; }
283
+ .stack-section h3 { color: #4b5563; margin: 1.5rem 0 1rem; font-size: 1.1rem; }
284
+ .stack-section h4 { color: #6b7280; margin: 1rem 0 0.5rem; font-size: 1rem; }
285
+ .stack-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-bottom: 1.5rem; }
286
+ .stack-card { background: white; padding: 1.25rem; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); text-align: center; border: 1px solid #e5e7eb; }
287
+ .stack-icon { font-size: 2rem; margin-bottom: 0.5rem; }
288
+ .stack-label { color: #6b7280; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.05em; }
289
+ .stack-value { color: #1f2937; font-size: 1.25rem; font-weight: 600; margin-top: 0.25rem; }
290
+ .stack-recommendations { background: white; padding: 1rem 1.5rem; border-radius: 8px; border-left: 4px solid #667eea; margin-bottom: 1.5rem; }
291
+ .stack-recommendations ul { margin: 0.5rem 0 0 1.5rem; }
292
+ .stack-recommendations li { margin: 0.5rem 0; color: #374151; }
293
+ .stack-guides { background: white; padding: 1.5rem; border-radius: 8px; }
294
+ .guide-category { margin-bottom: 1.5rem; }
295
+ .guide-category:last-child { margin-bottom: 0; }
296
+ .stack-guide { margin: 0.75rem 0; }
297
+
298
+ @media (max-width: 768px) {
299
+ body { padding: 1rem; }
300
+ .summary { grid-template-columns: repeat(2, 1fr); }
301
+ .stack-cards { grid-template-columns: 1fr; }
302
+ }
303
+ </style>
304
+ </head>
305
+ <body>
306
+ <div class="container">
307
+ <h1>HIPAA Compliance Report</h1>
308
+ <p style="color: #6b7280; margin-bottom: 1rem;">Generated by <strong>vlayer</strong> - HIPAA Compliance Scanner</p>
309
+ <div class="meta">
310
+ <p><strong>Generated:</strong> ${report.timestamp}</p>
311
+ <p><strong>Target:</strong> ${report.targetPath}</p>
312
+ <p><strong>Files Scanned:</strong> ${report.scannedFiles} | <strong>Duration:</strong> ${report.scanDuration}ms</p>
313
+ </div>
314
+
315
+ <div class="summary">
316
+ <div class="summary-card" style="border-top: 4px solid ${severityColors.critical}">
317
+ <div class="count" style="color: ${severityColors.critical}">${report.summary.critical}</div>
318
+ <div>Critical</div>
319
+ </div>
320
+ <div class="summary-card" style="border-top: 4px solid ${severityColors.high}">
321
+ <div class="count" style="color: ${severityColors.high}">${report.summary.high}</div>
322
+ <div>High</div>
323
+ </div>
324
+ <div class="summary-card" style="border-top: 4px solid ${severityColors.medium}">
325
+ <div class="count" style="color: ${severityColors.medium}">${report.summary.medium}</div>
326
+ <div>Medium</div>
327
+ </div>
328
+ <div class="summary-card" style="border-top: 4px solid ${severityColors.low}">
329
+ <div class="count" style="color: ${severityColors.low}">${report.summary.low}</div>
330
+ <div>Low</div>
331
+ </div>
332
+ </div>
333
+
334
+ ${report.stack && report.stack.framework !== 'unknown' ? renderStackSection(report.stack) : ''}
335
+
336
+ <h2>Findings</h2>
337
+ <div class="findings">
338
+ ${report.findings.map(f => {
339
+ const guide = getRemediationGuide(f);
340
+ return `
341
+ <div class="finding" style="border-left-color: ${severityColors[f.severity]}">
342
+ <h3>
343
+ <span class="badge" style="background: ${severityColors[f.severity]}">${f.severity}</span>
344
+ ${escapeHtml(f.title)}
345
+ ${f.fixType ? '<span class="badge badge-fixable">Auto-fixable</span>' : ''}
346
+ </h3>
347
+ <p class="file">${escapeHtml(f.file)}${f.line ? `:${f.line}` : ''}</p>
348
+ <p style="margin-top: 0.5rem;">${escapeHtml(f.description)}</p>
349
+ ${renderContextHtml(f.context)}
350
+ <div class="recommendation">
351
+ <strong>Quick Recommendation:</strong> ${escapeHtml(f.recommendation)}
352
+ </div>
353
+ ${f.hipaaReference ? `<p class="hipaa-ref"><strong>HIPAA Reference:</strong> ${escapeHtml(f.hipaaReference)}</p>` : ''}
354
+
355
+ ${guide ? `
356
+ <details class="guide-toggle">
357
+ <summary>View Detailed Remediation Guide</summary>
358
+ ${renderRemediationGuide(guide)}
359
+ </details>
360
+ ` : ''}
361
+ </div>
362
+ `;
363
+ }).join('')}
364
+ </div>
365
+
366
+ <footer style="margin-top: 3rem; padding-top: 1rem; border-top: 1px solid #e5e7eb; color: #6b7280; font-size: 0.875rem;">
367
+ <p>Generated by <strong>vlayer</strong> v0.2.0 - HIPAA Compliance Scanner for Healthcare Applications</p>
368
+ <p>Run with <code>--fix</code> flag to automatically fix issues marked as "Auto-fixable"</p>
369
+ </footer>
370
+ </div>
371
+ </body>
372
+ </html>`;
373
+ }
374
+ function escapeHtml(text) {
375
+ return text
376
+ .replace(/&/g, '&amp;')
377
+ .replace(/</g, '&lt;')
378
+ .replace(/>/g, '&gt;')
379
+ .replace(/"/g, '&quot;');
380
+ }
381
+ function formatCategory(category) {
382
+ return category
383
+ .split('-')
384
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1))
385
+ .join(' ');
386
+ }
387
+ function severityBadge(severity) {
388
+ const badges = {
389
+ critical: '🔴',
390
+ high: '🟠',
391
+ medium: '🟡',
392
+ low: '🔵',
393
+ info: '⚪',
394
+ };
395
+ return badges[severity] || '⚪';
396
+ }
397
+ export async function generateReport(result, targetPath, options) {
398
+ const report = buildReport(result, targetPath);
399
+ let content;
400
+ let extension;
401
+ switch (options.format) {
402
+ case 'html':
403
+ content = generateHtml(report);
404
+ extension = 'html';
405
+ break;
406
+ case 'markdown':
407
+ content = generateMarkdown(report);
408
+ extension = 'md';
409
+ break;
410
+ case 'json':
411
+ default:
412
+ content = generateJson(report);
413
+ extension = 'json';
414
+ }
415
+ if (options.outputPath) {
416
+ await writeFile(options.outputPath, content);
417
+ console.log(chalk.green(`\nReport saved to: ${options.outputPath}`));
418
+ }
419
+ else {
420
+ const defaultPath = `vlayer-report.${extension}`;
421
+ await writeFile(defaultPath, content);
422
+ console.log(chalk.green(`\nReport saved to: ${defaultPath}`));
423
+ }
424
+ }
425
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/reporters/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export interface RemediationOption {
2
+ title: string;
3
+ description: string;
4
+ code: string;
5
+ language: string;
6
+ }
7
+ export interface RemediationGuide {
8
+ id: string;
9
+ matchPatterns: string[];
10
+ hipaaImpact: string;
11
+ options: RemediationOption[];
12
+ documentation: Array<{
13
+ title: string;
14
+ url: string;
15
+ }>;
16
+ }
17
+ export declare const REMEDIATION_GUIDES: RemediationGuide[];
18
+ /**
19
+ * Find the best matching remediation guide for a finding
20
+ */
21
+ export declare function getRemediationGuide(finding: {
22
+ title: string;
23
+ id: string;
24
+ }): RemediationGuide | null;
25
+ //# sourceMappingURL=remediation-guides.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remediation-guides.d.ts","sourceRoot":"","sources":["../../src/reporters/remediation-guides.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,aAAa,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACtD;AAED,eAAO,MAAM,kBAAkB,EAAE,gBAAgB,EAsnBhD,CAAC;AAEF;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,gBAAgB,GAAG,IAAI,CAUnG"}