@js-recon/js-recon 2.0.1-alpha.1 → 2.0.1-alpha.3

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 (97) hide show
  1. package/.github/dependabot.yml +50 -0
  2. package/.github/workflows/publish-js-recon.yml +25 -1
  3. package/AGENTS.md +694 -0
  4. package/CHANGELOG.md +38 -1
  5. package/build/analyze/helpers/initRules.js +19 -17
  6. package/build/analyze/helpers/initRules.js.map +1 -1
  7. package/build/cliProgram.js +27 -4
  8. package/build/cliProgram.js.map +1 -1
  9. package/build/exploit/utility/rawRequest.js +3 -1
  10. package/build/exploit/utility/rawRequest.js.map +1 -1
  11. package/build/globalConfig.js +1 -1
  12. package/build/index.js +2 -0
  13. package/build/index.js.map +1 -1
  14. package/build/lazyLoad/downloadFilesUtil.js +7 -1
  15. package/build/lazyLoad/downloadFilesUtil.js.map +1 -1
  16. package/build/lazyLoad/downloadQueue.js +11 -1
  17. package/build/lazyLoad/downloadQueue.js.map +1 -1
  18. package/build/lazyLoad/downloadResponse.js +9 -1
  19. package/build/lazyLoad/downloadResponse.js.map +1 -1
  20. package/build/lazyLoad/generic/generic_resolveScope.js +6 -1
  21. package/build/lazyLoad/generic/generic_resolveScope.js.map +1 -1
  22. package/build/lazyLoad/index.js +124 -18
  23. package/build/lazyLoad/index.js.map +1 -1
  24. package/build/lazyLoad/methodFilter.js +7 -1
  25. package/build/lazyLoad/methodFilter.js.map +1 -1
  26. package/build/lazyLoad/next_js/NextJsCrawler.js +61 -1
  27. package/build/lazyLoad/next_js/NextJsCrawler.js.map +1 -1
  28. package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js +4 -0
  29. package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js.map +1 -1
  30. package/build/lazyLoad/next_js/next_routerStateForge.js +105 -39
  31. package/build/lazyLoad/next_js/next_routerStateForge.js.map +1 -1
  32. package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js +27 -3
  33. package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js.map +1 -1
  34. package/build/lazyLoad/outputPath.js +9 -1
  35. package/build/lazyLoad/outputPath.js.map +1 -1
  36. package/build/lazyLoad/react/react_followImports.js +20 -3
  37. package/build/lazyLoad/react/react_followImports.js.map +1 -1
  38. package/build/lazyLoad/react/react_sourcemapUrls.js +7 -28
  39. package/build/lazyLoad/react/react_sourcemapUrls.js.map +1 -1
  40. package/build/lazyLoad/shared/webpackChunkParsers.js +115 -0
  41. package/build/lazyLoad/shared/webpackChunkParsers.js.map +1 -1
  42. package/build/lazyLoad/sourcemap.js +120 -0
  43. package/build/lazyLoad/sourcemap.js.map +1 -1
  44. package/build/lazyLoad/svelte/svelte_getFromPageSource.js +59 -5
  45. package/build/lazyLoad/svelte/svelte_getFromPageSource.js.map +1 -1
  46. package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js +13 -4
  47. package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js.map +1 -1
  48. package/build/lazyLoad/techDetect/checkAngularDevServer.js +51 -0
  49. package/build/lazyLoad/techDetect/checkAngularDevServer.js.map +1 -0
  50. package/build/lazyLoad/techDetect/checkNextDevServer.js +25 -0
  51. package/build/lazyLoad/techDetect/checkNextDevServer.js.map +1 -0
  52. package/build/lazyLoad/techDetect/checkReactDevServer.js +93 -0
  53. package/build/lazyLoad/techDetect/checkReactDevServer.js.map +1 -0
  54. package/build/lazyLoad/techDetect/checkSvelteDevServer.js +32 -0
  55. package/build/lazyLoad/techDetect/checkSvelteDevServer.js.map +1 -0
  56. package/build/lazyLoad/techDetect/checkVueDevServer.js +51 -0
  57. package/build/lazyLoad/techDetect/checkVueDevServer.js.map +1 -0
  58. package/build/lazyLoad/techDetect/index.js +48 -18
  59. package/build/lazyLoad/techDetect/index.js.map +1 -1
  60. package/build/lazyLoad/vue/vue_discoverJsFiles.js +2 -2
  61. package/build/lazyLoad/vue/vue_discoverJsFiles.js.map +1 -1
  62. package/build/lazyLoad/vue/vue_jsImports.js +23 -9
  63. package/build/lazyLoad/vue/vue_jsImports.js.map +1 -1
  64. package/build/lazyLoad/vue/vue_reconstructSourceMaps.js +10 -1
  65. package/build/lazyLoad/vue/vue_reconstructSourceMaps.js.map +1 -1
  66. package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js +2 -2
  67. package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js.map +1 -1
  68. package/build/load/index.js +21 -32
  69. package/build/load/index.js.map +1 -1
  70. package/build/mcp/mcpServer.js +1 -1
  71. package/build/mcp/mcpServer.js.map +1 -1
  72. package/build/mcp/tools.js +1 -1
  73. package/build/mcp/tools.js.map +1 -1
  74. package/build/report/utility/dataTables/genDataTablesPage.js +2 -1
  75. package/build/report/utility/dataTables/genDataTablesPage.js.map +1 -1
  76. package/build/report/utility/genHtml.js +309 -18
  77. package/build/report/utility/genHtml.js.map +1 -1
  78. package/build/report/utility/markdownGen/addAnalyze.js +2 -1
  79. package/build/report/utility/markdownGen/addAnalyze.js.map +1 -1
  80. package/build/report/utility/severityColors.js +35 -0
  81. package/build/report/utility/severityColors.js.map +1 -0
  82. package/build/run/index.js +54 -13
  83. package/build/run/index.js.map +1 -1
  84. package/build/utility/cacheDb.js +78 -0
  85. package/build/utility/cacheDb.js.map +1 -0
  86. package/build/utility/customHeaders.js +30 -0
  87. package/build/utility/customHeaders.js.map +1 -0
  88. package/build/utility/fatalHandlers.js +29 -0
  89. package/build/utility/fatalHandlers.js.map +1 -0
  90. package/build/utility/globals.js +18 -1
  91. package/build/utility/globals.js.map +1 -1
  92. package/build/utility/makeReq.js +37 -86
  93. package/build/utility/makeReq.js.map +1 -1
  94. package/config.dist.yaml +3 -3
  95. package/package.json +2 -4
  96. package/scripts/dev-server-benchmark-utils.mjs +24 -0
  97. package/scripts/dev-server-benchmark.mjs +225 -0
@@ -63,57 +63,226 @@ export const getLocalJqueryAsset = () => {
63
63
  return null;
64
64
  }
65
65
  };
66
+ /**
67
+ * Attempts to read the local highlight.js light/dark theme stylesheets from node_modules
68
+ * (avoids depending on a CDN for code-block syntax highlighting colors).
69
+ *
70
+ * @returns An object containing the light and dark theme CSS, or null for either if not found
71
+ */
72
+ export const getLocalHljsThemes = () => {
73
+ try {
74
+ const require = createRequire(import.meta.url);
75
+ const lightPath = require.resolve("highlight.js/styles/github.css");
76
+ const darkPath = require.resolve("highlight.js/styles/github-dark.css");
77
+ const light = fs.readFileSync(lightPath, "utf8");
78
+ const dark = fs.readFileSync(darkPath, "utf8");
79
+ return { light, dark };
80
+ }
81
+ catch (e) {
82
+ printMsg(MSG.Warn, `[Highlight.js] Local theme assets not found; falling back to CDN ${(e === null || e === void 0 ? void 0 : e.message) || e}`);
83
+ return { light: null, dark: null };
84
+ }
85
+ };
66
86
  /**
67
87
  * Generates an HTML report based on the provided markdown and assets.
68
88
  *
69
89
  * @param analyzeMarkdown - The markdown for the analyze section
70
90
  * @param mappedJsonMarkdown - The markdown for the mapped JSON section
71
91
  * @param dataTablesHtml - The HTML for the data tables section
92
+ * @param aboutHtml - The pre-rendered HTML for the about section
72
93
  * @param dtAssets - The DataTables assets (JavaScript and CSS)
73
94
  * @param jqueryJs - The jQuery JavaScript
95
+ * @param hljsThemes - The highlight.js light/dark theme CSS
74
96
  *
75
97
  * @returns The generated HTML report as a string
76
98
  */
77
- const html = (analyzeMarkdown, mappedJsonMarkdown, dataTablesHtml, dtAssets, jqueryJs) => __awaiter(void 0, void 0, void 0, function* () {
99
+ const html = (analyzeMarkdown, mappedJsonMarkdown, dataTablesHtml, aboutHtml, dtAssets, jqueryJs, hljsThemes) => __awaiter(void 0, void 0, void 0, function* () {
78
100
  return `<!DOCTYPE html>
79
101
  <html>
80
102
  <head>
81
103
  <meta charset="UTF-8">
104
+ <script>
105
+ (function () {
106
+ try {
107
+ var stored = localStorage.getItem('jsrTheme');
108
+ var theme = stored === 'light' || stored === 'dark'
109
+ ? stored
110
+ : (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
111
+ document.documentElement.setAttribute('data-theme', theme);
112
+ } catch (e) {}
113
+ })();
114
+ </script>
82
115
  <title>JS Recon Report</title>
83
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@11.9.0/styles/github-dark.css">
116
+ ${hljsThemes.light
117
+ ? `<style id="hljs-light">${hljsThemes.light}</style>`
118
+ : `<link id="hljs-light" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@11.9.0/styles/github.css">`}
119
+ ${hljsThemes.dark
120
+ ? `<style id="hljs-dark" disabled>${hljsThemes.dark}</style>`
121
+ : `<link id="hljs-dark" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@11.9.0/styles/github-dark.css" disabled>`}
84
122
  ${dtAssets.css
85
123
  ? `<style id="dt-inline-css">${dtAssets.css}</style>`
86
124
  : `<link rel="stylesheet" href="https://cdn.datatables.net/2.0.8/css/dataTables.dataTables.min.css">`}
87
125
  <style>
126
+ :root {
127
+ --bg: #f5f6f8;
128
+ --surface: #ffffff;
129
+ --text: #1a1a1a;
130
+ --text-muted: #5a6472;
131
+ --border: #e0e0e0;
132
+ --accent: #2563eb;
133
+ --accent-text: #ffffff;
134
+ --table-hover: #f0f4ff;
135
+ --code-bg: #f6f8fa;
136
+ --shadow: rgba(0, 0, 0, 0.08);
137
+
138
+ --sev-info-bg: #e0f2fe;
139
+ --sev-info-text: #075985;
140
+ --sev-info-border: #7dd3fc;
141
+ --sev-low-bg: #dcfce7;
142
+ --sev-low-text: #166534;
143
+ --sev-low-border: #86efac;
144
+ --sev-medium-bg: #fef9c3;
145
+ --sev-medium-text: #854d0e;
146
+ --sev-medium-border: #fde047;
147
+ --sev-high-bg: #fee2e2;
148
+ --sev-high-text: #991b1b;
149
+ --sev-high-border: #fca5a5;
150
+ }
151
+ @media (prefers-color-scheme: dark) {
152
+ :root {
153
+ --bg: #0f1117;
154
+ --surface: #171923;
155
+ --text: #e5e7eb;
156
+ --text-muted: #9ca3af;
157
+ --border: #2d3340;
158
+ --accent: #60a5fa;
159
+ --accent-text: #0f1117;
160
+ --table-hover: #1f2430;
161
+ --code-bg: #1e222c;
162
+ --shadow: rgba(0, 0, 0, 0.4);
163
+
164
+ --sev-info-bg: #0c4a6e;
165
+ --sev-info-text: #bae6fd;
166
+ --sev-info-border: #0ea5e9;
167
+ --sev-low-bg: #14532d;
168
+ --sev-low-text: #bbf7d0;
169
+ --sev-low-border: #22c55e;
170
+ --sev-medium-bg: #713f12;
171
+ --sev-medium-text: #fef08a;
172
+ --sev-medium-border: #eab308;
173
+ --sev-high-bg: #7f1d1d;
174
+ --sev-high-text: #fecaca;
175
+ --sev-high-border: #ef4444;
176
+ }
177
+ }
178
+ html[data-theme="light"] {
179
+ --bg: #f5f6f8;
180
+ --surface: #ffffff;
181
+ --text: #1a1a1a;
182
+ --text-muted: #5a6472;
183
+ --border: #e0e0e0;
184
+ --accent: #2563eb;
185
+ --accent-text: #ffffff;
186
+ --table-hover: #f0f4ff;
187
+ --code-bg: #f6f8fa;
188
+ --shadow: rgba(0, 0, 0, 0.08);
189
+ --sev-info-bg: #e0f2fe;
190
+ --sev-info-text: #075985;
191
+ --sev-info-border: #7dd3fc;
192
+ --sev-low-bg: #dcfce7;
193
+ --sev-low-text: #166534;
194
+ --sev-low-border: #86efac;
195
+ --sev-medium-bg: #fef9c3;
196
+ --sev-medium-text: #854d0e;
197
+ --sev-medium-border: #fde047;
198
+ --sev-high-bg: #fee2e2;
199
+ --sev-high-text: #991b1b;
200
+ --sev-high-border: #fca5a5;
201
+ }
202
+ html[data-theme="dark"] {
203
+ --bg: #0f1117;
204
+ --surface: #171923;
205
+ --text: #e5e7eb;
206
+ --text-muted: #9ca3af;
207
+ --border: #2d3340;
208
+ --accent: #60a5fa;
209
+ --accent-text: #0f1117;
210
+ --table-hover: #1f2430;
211
+ --code-bg: #1e222c;
212
+ --shadow: rgba(0, 0, 0, 0.4);
213
+ --sev-info-bg: #0c4a6e;
214
+ --sev-info-text: #bae6fd;
215
+ --sev-info-border: #0ea5e9;
216
+ --sev-low-bg: #14532d;
217
+ --sev-low-text: #bbf7d0;
218
+ --sev-low-border: #22c55e;
219
+ --sev-medium-bg: #713f12;
220
+ --sev-medium-text: #fef08a;
221
+ --sev-medium-border: #eab308;
222
+ --sev-high-bg: #7f1d1d;
223
+ --sev-high-text: #fecaca;
224
+ --sev-high-border: #ef4444;
225
+ }
226
+
227
+ * { box-sizing: border-box; }
228
+
229
+ body {
230
+ padding-top: 80px; /* Height of the navbar */
231
+ margin: 0;
232
+ background: var(--bg);
233
+ color: var(--text);
234
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
235
+ transition: background-color 0.15s ease, color 0.15s ease;
236
+ }
237
+
238
+ a { color: var(--accent); }
239
+
240
+ #content {
241
+ max-width: 1150px;
242
+ margin: 0 auto;
243
+ padding: 8px 24px 60px;
244
+ }
245
+
88
246
  h2, h3, h4 {
89
247
  cursor: pointer;
90
248
  position: relative;
91
249
  padding-left: 20px;
250
+ color: var(--text);
92
251
  }
93
252
  h2::before, h3::before, h4::before {
94
253
  content: '▼';
95
254
  position: absolute;
96
255
  left: 0;
97
256
  transition: transform 0.2s;
257
+ font-size: 0.7em;
258
+ top: 0.35em;
98
259
  }
99
260
  .collapsed::before {
100
261
  transform: rotate(-90deg);
101
262
  }
102
- body {
103
- padding-top: 80px; /* Height of the navbar */
263
+
264
+ code:not(.hljs) {
265
+ background: var(--code-bg);
266
+ color: var(--text);
267
+ padding: 2px 6px;
268
+ border-radius: 4px;
269
+ font-size: 0.9em;
104
270
  }
271
+ pre { background: var(--code-bg); border: 1px solid var(--border); border-radius: 8px; padding: 12px; overflow: auto; }
272
+ pre code.hljs { background: transparent !important; padding: 0; }
273
+
105
274
  .navbar {
106
275
  position: fixed;
107
276
  top: 0;
108
277
  left: 0;
109
278
  width: 100%;
110
- background-color: #ffffff;
111
- border-bottom: 1px solid #e0e0e0;
279
+ background-color: var(--surface);
280
+ border-bottom: 1px solid var(--border);
112
281
  display: flex;
113
282
  align-items: center;
114
- padding: 10px 20px;
283
+ padding: 10px 24px;
115
284
  z-index: 1000;
116
- box-shadow: 0 2px 5px rgba(0,0,0,0.1);
285
+ box-shadow: 0 2px 8px var(--shadow);
117
286
  }
118
287
  .navbar-logo img {
119
288
  height: 40px;
@@ -124,17 +293,61 @@ const html = (analyzeMarkdown, mappedJsonMarkdown, dataTablesHtml, dtAssets, jqu
124
293
  padding: 0;
125
294
  display: flex;
126
295
  gap: 15px;
296
+ flex: 1;
297
+ }
298
+ .navbar-links a {
299
+ color: var(--text-muted);
300
+ text-decoration: none;
301
+ font-weight: 500;
302
+ padding: 6px 4px;
303
+ border-bottom: 2px solid transparent;
304
+ }
305
+ .navbar-links a:hover { color: var(--text); }
306
+ .navbar-links a.active {
307
+ color: var(--accent);
308
+ border-bottom-color: var(--accent);
127
309
  }
310
+ .theme-toggle {
311
+ background: transparent;
312
+ border: 1px solid var(--border);
313
+ color: var(--text);
314
+ border-radius: 8px;
315
+ padding: 6px 12px;
316
+ cursor: pointer;
317
+ font-size: 1rem;
318
+ line-height: 1;
319
+ }
320
+ .theme-toggle:hover { background: var(--table-hover); }
321
+
322
+ .badge {
323
+ display: inline-block;
324
+ padding: 2px 10px;
325
+ border-radius: 999px;
326
+ font-size: 0.78rem;
327
+ font-weight: 600;
328
+ border: 1px solid transparent;
329
+ text-transform: uppercase;
330
+ letter-spacing: 0.02em;
331
+ white-space: nowrap;
332
+ }
333
+ .badge-info { background: var(--sev-info-bg); color: var(--sev-info-text); border-color: var(--sev-info-border); }
334
+ .badge-low { background: var(--sev-low-bg); color: var(--sev-low-text); border-color: var(--sev-low-border); }
335
+ .badge-medium { background: var(--sev-medium-bg); color: var(--sev-medium-text); border-color: var(--sev-medium-border); }
336
+ .badge-high { background: var(--sev-high-bg); color: var(--sev-high-text); border-color: var(--sev-high-border); }
337
+ .badge-unknown { background: var(--surface); color: var(--text-muted); border-color: var(--border); }
338
+
128
339
  .data-table { font-size: 0.9rem; }
129
- pre.code-cell { white-space: pre-wrap; word-break: break-word; max-height: 200px; overflow: auto; }
340
+ pre.code-cell { white-space: pre-wrap; word-break: break-word; max-height: 200px; overflow: auto; background: var(--code-bg); border: 1px solid var(--border); border-radius: 6px; padding: 8px; }
130
341
  thead tr.filter-row th { padding: 4px 6px; }
131
342
  thead tr.filter-row th input {
132
343
  width: 100%;
133
344
  padding: 4px 6px;
134
- border: 1px solid #ccc;
345
+ border: 1px solid var(--border);
135
346
  border-radius: 4px;
136
347
  font-size: 0.85rem;
137
348
  box-sizing: border-box;
349
+ background: var(--surface);
350
+ color: var(--text);
138
351
  }
139
352
  /* Column resize styles */
140
353
  table.display.data-table { table-layout: fixed; }
@@ -151,6 +364,49 @@ const html = (analyzeMarkdown, mappedJsonMarkdown, dataTablesHtml, dtAssets, jqu
151
364
  transition: opacity 0.15s ease-in-out;
152
365
  }
153
366
  table.display.data-table thead th:hover .th-resizer { opacity: 1; }
367
+
368
+ /* DataTables dark-mode reskin (overrides the inlined DataTables stylesheet above) */
369
+ html[data-theme="dark"] table.dataTable,
370
+ html[data-theme="dark"] table.dataTable thead th,
371
+ html[data-theme="dark"] table.dataTable tbody td,
372
+ html[data-theme="dark"] table.dataTable tbody tr {
373
+ color: var(--text);
374
+ background-color: transparent;
375
+ border-color: var(--border) !important;
376
+ }
377
+ html[data-theme="dark"] table.dataTable tbody tr:hover {
378
+ background-color: var(--table-hover);
379
+ }
380
+ html[data-theme="dark"] .dataTables_wrapper .dataTables_info,
381
+ html[data-theme="dark"] .dataTables_wrapper .dataTables_length,
382
+ html[data-theme="dark"] .dataTables_wrapper .dataTables_filter,
383
+ html[data-theme="dark"] .dataTables_wrapper .dataTables_filter input,
384
+ html[data-theme="dark"] .dataTables_wrapper .dataTables_length select {
385
+ color: var(--text);
386
+ background-color: var(--surface);
387
+ border-color: var(--border);
388
+ }
389
+ html[data-theme="dark"] .dataTables_wrapper .dataTables_paginate .paginate_button {
390
+ color: var(--text) !important;
391
+ background: transparent;
392
+ border-color: var(--border) !important;
393
+ }
394
+ html[data-theme="dark"] .dataTables_wrapper .dataTables_paginate .paginate_button.current,
395
+ html[data-theme="dark"] .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
396
+ background: var(--accent) !important;
397
+ color: var(--accent-text) !important;
398
+ border-color: var(--accent) !important;
399
+ }
400
+ html[data-theme="dark"] .dataTables_wrapper .dataTables_paginate .paginate_button:hover {
401
+ background: var(--table-hover) !important;
402
+ color: var(--text) !important;
403
+ border-color: var(--border) !important;
404
+ }
405
+ html[data-theme="dark"] .dataTables_wrapper .dataTables_paginate .paginate_button.disabled,
406
+ html[data-theme="dark"] .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover {
407
+ color: var(--text-muted) !important;
408
+ background: transparent !important;
409
+ }
154
410
  </style>
155
411
  </head>
156
412
  <body>
@@ -164,6 +420,7 @@ const html = (analyzeMarkdown, mappedJsonMarkdown, dataTablesHtml, dtAssets, jqu
164
420
  <li><a href="#dataTables">Data Tables</a></li>
165
421
  <li><a href="#about">About</a></li>
166
422
  </ul>
423
+ <button id="theme-toggle" class="theme-toggle" type="button" aria-label="Toggle dark mode" title="Toggle dark mode">🌙</button>
167
424
  </nav>
168
425
  <div id="content"></div>
169
426
  <script id="page-data" type="application/json">
@@ -171,10 +428,9 @@ const html = (analyzeMarkdown, mappedJsonMarkdown, dataTablesHtml, dtAssets, jqu
171
428
  home: yield marked.parse(analyzeMarkdown),
172
429
  mappedJson: yield marked.parse(mappedJsonMarkdown),
173
430
  dataTables: dataTablesHtml,
174
- about: `# About\n\n The documentation for this tool is available at [JS Recon Docs](https://js-recon.io/).\n\n## Version\n\nThis report is generated with JS Recon [v${CONFIG.version}](https://github.com/js-recon/js-recon/releases/tag/v${CONFIG.version}).`,
431
+ about: aboutHtml,
175
432
  }).replace(/</g, "\\u003c")}
176
433
  </script>
177
- <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
178
434
  ${jqueryJs
179
435
  ? `<script id="jquery-inline-js">${jqueryJs}</script>`
180
436
  : `<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>`}
@@ -186,6 +442,33 @@ const html = (analyzeMarkdown, mappedJsonMarkdown, dataTablesHtml, dtAssets, jqu
186
442
  const contentDiv = document.getElementById('content');
187
443
  const navbarLinks = document.getElementById('navbar-links');
188
444
  const pages = JSON.parse(document.getElementById('page-data').textContent);
445
+ const themeToggle = document.getElementById('theme-toggle');
446
+ const hljsLight = document.getElementById('hljs-light');
447
+ const hljsDark = document.getElementById('hljs-dark');
448
+
449
+ const getTheme = () => document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light';
450
+
451
+ const applyHljsTheme = (theme) => {
452
+ if (hljsLight) hljsLight.disabled = theme === 'dark';
453
+ if (hljsDark) hljsDark.disabled = theme !== 'dark';
454
+ };
455
+
456
+ const setTheme = (theme, persist) => {
457
+ document.documentElement.setAttribute('data-theme', theme);
458
+ applyHljsTheme(theme);
459
+ if (themeToggle) themeToggle.textContent = theme === 'dark' ? '☀️' : '🌙';
460
+ if (persist) {
461
+ try { localStorage.setItem('jsrTheme', theme); } catch (e) {}
462
+ }
463
+ };
464
+
465
+ setTheme(getTheme(), false);
466
+
467
+ if (themeToggle) {
468
+ themeToggle.addEventListener('click', () => {
469
+ setTheme(getTheme() === 'dark' ? 'light' : 'dark', true);
470
+ });
471
+ }
189
472
 
190
473
  const isDtAvailable = () => {
191
474
  if (typeof window.DataTable !== 'undefined') return true; // ESM/global
@@ -455,15 +738,20 @@ const html = (analyzeMarkdown, mappedJsonMarkdown, dataTablesHtml, dtAssets, jqu
455
738
  updateVisibility();
456
739
  };
457
740
 
741
+ const updateActiveNavLink = (pageName) => {
742
+ const links = navbarLinks.querySelectorAll('a');
743
+ links.forEach((a) => {
744
+ const linkPage = (a.getAttribute('href') || '').replace(/^#/, '');
745
+ a.classList.toggle('active', linkPage === pageName);
746
+ });
747
+ };
748
+
458
749
  const renderPage = (pageName) => {
459
750
  const content = pages[pageName] || '<h2>Page Not Found: ' + pageName + '</h2>';
460
- if (pageName === 'home' || pageName === 'dataTables' || pageName === 'mappedJson') {
461
- contentDiv.innerHTML = content;
462
- } else {
463
- contentDiv.innerHTML = window.marked.parse(content);
464
- }
751
+ contentDiv.innerHTML = content;
465
752
  initializeCollapsibleHeaders();
466
753
  initializeDataTablesIfPresent();
754
+ updateActiveNavLink(pageName);
467
755
  };
468
756
 
469
757
  const handleHashChange = () => {
@@ -504,6 +792,7 @@ const genHtml = (outputReportFile, db) => __awaiter(void 0, void 0, void 0, func
504
792
  let mappedJsonMarkdown = analyzeMarkdown;
505
793
  analyzeMarkdown = yield addAnalyze(analyzeMarkdown, db);
506
794
  mappedJsonMarkdown = yield addMappedJson(mappedJsonMarkdown, db);
795
+ const aboutMarkdown = `# About\n\n The documentation for this tool is available at [JS Recon Docs](https://js-recon.io/).\n\n## Version\n\nThis report is generated with JS Recon [v${CONFIG.version}](https://github.com/js-recon/js-recon/releases/tag/v${CONFIG.version}).`;
507
796
  const dataTablesHtml = genDataTablesPage(db);
508
797
  const renderer = new marked.Renderer();
509
798
  renderer.code = ({ text, lang }) => {
@@ -517,9 +806,11 @@ const genHtml = (outputReportFile, db) => __awaiter(void 0, void 0, void 0, func
517
806
  pedantic: false,
518
807
  gfm: true,
519
808
  });
809
+ const aboutHtml = yield marked.parse(aboutMarkdown);
520
810
  const dtAssets = getLocalDataTablesAssets();
521
811
  const jqueryJs = getLocalJqueryAsset();
522
- const renderedHtml = yield html(analyzeMarkdown, mappedJsonMarkdown, dataTablesHtml, dtAssets, jqueryJs);
812
+ const hljsThemes = getLocalHljsThemes();
813
+ const renderedHtml = yield html(analyzeMarkdown, mappedJsonMarkdown, dataTablesHtml, aboutHtml, dtAssets, jqueryJs, hljsThemes);
523
814
  fs.writeFileSync(outputReportFile, renderedHtml);
524
815
  printMsg(MSG.Run, "[✓] HTML report generated successfully");
525
816
  });
@@ -1 +1 @@
1
- {"version":3,"file":"genHtml.js","sourceRoot":"","sources":["../../../src/report/utility/genHtml.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"genHtml.js","sourceRoot":"","sources":["../../../src/report/utility/genHtml.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,IAAI,MAAM,cAAc,CAAC;AAEhC,OAAO,UAAU,MAAM,6BAA6B,CAAC;AACrD,OAAO,MAAM,MAAM,uBAAuB,CAAC;AAC3C,OAAO,aAAa,MAAM,gCAAgC,CAAC;AAC3D,OAAO,iBAAiB,MAAM,mCAAmC,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAQ1D;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,EAAE;IACzC,IAAI,CAAC;QACD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAC;QACxE,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,qDAAqD,CAAC,CAAC;QACzF,MAAM,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC7C,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC/C,OAAO,EAAE,EAAE,EAAE,GAAG,EAA+C,CAAC;IACpE,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QACd,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,4DAA4D,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,OAAO,KAAI,CAAC,EAAE,CAAC,CAAC;QAClG,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAA+C,CAAC;IAChF,CAAC;AACL,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,EAAE;IACpC,IAAI,CAAC;QACD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/C,+EAA+E;QAC/E,yDAAyD;QACzD,IAAI,MAAc,CAAC;QACnB,IAAI,CAAC;YACD,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;QAC1D,CAAC;QAAC,WAAM,CAAC;YACL,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAC3C,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,MAAM,CAAC,CAAC;QACpF,MAAM,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC3C,OAAO,EAAmB,CAAC;IAC/B,CAAC;IAAC,WAAM,CAAC;QACL,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,0DAA0D,CAAC,CAAC;QAC/E,OAAO,IAAqB,CAAC;IACjC,CAAC;AACL,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,EAAE;IACnC,IAAI,CAAC;QACD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/C,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC;QACpE,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAC;QACxE,MAAM,KAAK,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC/C,OAAO,EAAE,KAAK,EAAE,IAAI,EAAmD,CAAC;IAC5E,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QACd,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,oEAAoE,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,OAAO,KAAI,CAAC,EAAE,CAAC,CAAC;QAC1G,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAmD,CAAC;IACxF,CAAC;AACL,CAAC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,IAAI,GAAG,CACT,eAAuB,EACvB,kBAA0B,EAC1B,cAAsB,EACtB,SAAiB,EACjB,QAAmD,EACnD,QAAuB,EACvB,UAAyD,EAC3D,EAAE;IACA,OAAO;;;;;;;;;;;;;;;;IAiBL,UAAU,CAAC,KAAK;QACZ,CAAC,CAAC,0BAA0B,UAAU,CAAC,KAAK,UAAU;QACtD,CAAC,CAAC,mHACV;IAEI,UAAU,CAAC,IAAI;QACX,CAAC,CAAC,kCAAkC,UAAU,CAAC,IAAI,UAAU;QAC7D,CAAC,CAAC,gIACV;IAEI,QAAQ,CAAC,GAAG;QACR,CAAC,CAAC,6BAA6B,QAAQ,CAAC,GAAG,UAAU;QACrD,CAAC,CAAC,mGACV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA+SI,IAAI,CAAC,SAAS,CAAC;QACb,IAAI,EAAE,MAAM,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC;QACzC,UAAU,EAAE,MAAM,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC;QAClD,UAAU,EAAE,cAAc;QAC1B,KAAK,EAAE,SAAS;KACnB,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC;;IAGzB,QAAQ;QACJ,CAAC,CAAC,iCAAiC,QAAQ,WAAW;QACtD,CAAC,CAAC,qEACV;IAEI,QAAQ,CAAC,EAAE;QACP,CAAC,CAAC,6BAA6B,QAAQ,CAAC,EAAE,WAAW;QACrD,CAAC,CAAC,+EACV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAoVM,CAAC;AACT,CAAC,CAAA,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,OAAO,GAAG,CAAO,gBAAwB,EAAE,EAAqB,EAAE,EAAE;IACtE,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,+BAA+B,CAAC,CAAC;IAEtD,IAAI,eAAe,GAAG,kCAAkC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC;IACvF,IAAI,kBAAkB,GAAG,eAAe,CAAC;IAEzC,eAAe,GAAG,MAAM,UAAU,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IACxD,kBAAkB,GAAG,MAAM,aAAa,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;IAEjE,MAAM,aAAa,GAAG,gKAAgK,MAAM,CAAC,OAAO,wDAAwD,MAAM,CAAC,OAAO,IAAI,CAAC;IAE/Q,MAAM,cAAc,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC;IAE7C,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;IACvC,QAAQ,CAAC,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,IAAc,CAAC,CAAC,CAAC,CAAE,IAAe,CAAC,CAAC,CAAC,WAAW,CAAC;QACnF,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC;QACvF,OAAO,0BAA0B,QAAQ,KAAK,eAAe,eAAe,CAAC;IACjF,CAAC,CAAC;IAEF,MAAM,CAAC,UAAU,CAAC;QACd,QAAQ;QACR,KAAK,EAAE,IAAI;QACX,QAAQ,EAAE,KAAK;QACf,GAAG,EAAE,IAAI;KACZ,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,wBAAwB,EAAE,CAAC;IAC5C,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAC;IACvC,MAAM,UAAU,GAAG,kBAAkB,EAAE,CAAC;IACxC,MAAM,YAAY,GAAG,MAAM,IAAI,CAC3B,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,UAAU,CACb,CAAC;IACF,EAAE,CAAC,aAAa,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC;IAEjD,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,wCAAwC,CAAC,CAAC;AAChE,CAAC,CAAA,CAAC;AAEF,eAAe,OAAO,CAAC"}
@@ -7,6 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
+ import { severityBadgeHtml } from "../severityColors.js";
10
11
  /**
11
12
  * Adds an analyze section to the markdown.
12
13
  *
@@ -40,7 +41,7 @@ const addAnalyze = (markdown, db) => __awaiter(void 0, void 0, void 0, function*
40
41
  }
41
42
  toReturn += `${findingLocationBlock}\n`;
42
43
  toReturn += `- **Rule ID:** ${finding.ruleId}\n`;
43
- toReturn += `- **Severity:** ${finding.severity}\n`;
44
+ toReturn += `- **Severity:** ${severityBadgeHtml(finding.severity)}\n`;
44
45
  toReturn += `- **Message:** ${finding.message}\n`;
45
46
  toReturn += `- **Author:** ${finding.ruleAuthor}\n`;
46
47
  toReturn += `- **Technology:** ${finding.ruleTech}\n\n`;
@@ -1 +1 @@
1
- {"version":3,"file":"addAnalyze.js","sourceRoot":"","sources":["../../../../src/report/utility/markdownGen/addAnalyze.ts"],"names":[],"mappings":";;;;;;;;;AAcA;;;;;;;GAOG;AACH,MAAM,UAAU,GAAG,CAAO,QAAgB,EAAE,EAAqB,EAAmB,EAAE;IAClF,IAAI,QAAQ,GAAG,QAAQ,CAAC;IACxB,QAAQ,IAAI,wBAAwB,CAAC;IACrC,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC,GAAG,EAAuB,CAAC;IAC1F,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,eAAe,GAAyC,EAAE,CAAC;QACjE,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC7B,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACrC,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;YAC3C,CAAC;YACD,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpD,CAAC;QAED,KAAK,MAAM,QAAQ,IAAI,eAAe,EAAE,CAAC;YACrC,QAAQ,IAAI,OAAO,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC;YAC9C,KAAK,MAAM,OAAO,IAAI,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC9C,QAAQ,IAAI,QAAQ,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,eAAe,IAAI,CAAC;gBACrE,IAAI,oBAAoB,GAAG,EAAE,CAAC;gBAC9B,IAAI,QAAQ,CAAC,WAAW,EAAE,KAAK,KAAK,EAAE,CAAC;oBACnC,oBAAoB,GAAG,SAAS,GAAG,OAAO,CAAC,eAAe,GAAG,OAAO,CAAC;gBACzE,CAAC;qBAAM,CAAC;oBACJ,oBAAoB,GAAG,OAAO,GAAG,OAAO,CAAC,eAAe,GAAG,OAAO,CAAC;gBACvE,CAAC;gBACD,QAAQ,IAAI,GAAG,oBAAoB,IAAI,CAAC;gBACxC,QAAQ,IAAI,kBAAkB,OAAO,CAAC,MAAM,IAAI,CAAC;gBACjD,QAAQ,IAAI,mBAAmB,OAAO,CAAC,QAAQ,IAAI,CAAC;gBACpD,QAAQ,IAAI,kBAAkB,OAAO,CAAC,OAAO,IAAI,CAAC;gBAClD,QAAQ,IAAI,iBAAiB,OAAO,CAAC,UAAU,IAAI,CAAC;gBACpD,QAAQ,IAAI,qBAAqB,OAAO,CAAC,QAAQ,MAAM,CAAC;YAC5D,CAAC;QACL,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC,CAAA,CAAC;AAEF,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"addAnalyze.js","sourceRoot":"","sources":["../../../../src/report/utility/markdownGen/addAnalyze.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAczD;;;;;;;GAOG;AACH,MAAM,UAAU,GAAG,CAAO,QAAgB,EAAE,EAAqB,EAAmB,EAAE;IAClF,IAAI,QAAQ,GAAG,QAAQ,CAAC;IACxB,QAAQ,IAAI,wBAAwB,CAAC;IACrC,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC,GAAG,EAAuB,CAAC;IAC1F,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,eAAe,GAAyC,EAAE,CAAC;QACjE,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC7B,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACrC,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;YAC3C,CAAC;YACD,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpD,CAAC;QAED,KAAK,MAAM,QAAQ,IAAI,eAAe,EAAE,CAAC;YACrC,QAAQ,IAAI,OAAO,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC;YAC9C,KAAK,MAAM,OAAO,IAAI,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC9C,QAAQ,IAAI,QAAQ,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,eAAe,IAAI,CAAC;gBACrE,IAAI,oBAAoB,GAAG,EAAE,CAAC;gBAC9B,IAAI,QAAQ,CAAC,WAAW,EAAE,KAAK,KAAK,EAAE,CAAC;oBACnC,oBAAoB,GAAG,SAAS,GAAG,OAAO,CAAC,eAAe,GAAG,OAAO,CAAC;gBACzE,CAAC;qBAAM,CAAC;oBACJ,oBAAoB,GAAG,OAAO,GAAG,OAAO,CAAC,eAAe,GAAG,OAAO,CAAC;gBACvE,CAAC;gBACD,QAAQ,IAAI,GAAG,oBAAoB,IAAI,CAAC;gBACxC,QAAQ,IAAI,kBAAkB,OAAO,CAAC,MAAM,IAAI,CAAC;gBACjD,QAAQ,IAAI,mBAAmB,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;gBACvE,QAAQ,IAAI,kBAAkB,OAAO,CAAC,OAAO,IAAI,CAAC;gBAClD,QAAQ,IAAI,iBAAiB,OAAO,CAAC,UAAU,IAAI,CAAC;gBACpD,QAAQ,IAAI,qBAAqB,OAAO,CAAC,QAAQ,MAAM,CAAC;YAC5D,CAAC;QACL,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC,CAAA,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Shared severity → color mapping and badge rendering, used by both the
3
+ * DataTables findings table and the markdown finding write-up so the two
4
+ * surfaces stay visually consistent.
5
+ */
6
+ export const SEVERITY_COLORS = {
7
+ info: { bg: "var(--sev-info-bg)", text: "var(--sev-info-text)", border: "var(--sev-info-border)" },
8
+ low: { bg: "var(--sev-low-bg)", text: "var(--sev-low-text)", border: "var(--sev-low-border)" },
9
+ medium: { bg: "var(--sev-medium-bg)", text: "var(--sev-medium-text)", border: "var(--sev-medium-border)" },
10
+ high: { bg: "var(--sev-high-bg)", text: "var(--sev-high-text)", border: "var(--sev-high-border)" },
11
+ };
12
+ const escapeHtml = (value) => {
13
+ const str = value === null || value === undefined ? "" : String(value);
14
+ return str
15
+ .replace(/&/g, "&amp;")
16
+ .replace(/</g, "&lt;")
17
+ .replace(/>/g, "&gt;")
18
+ .replace(/"/g, "&quot;")
19
+ .replace(/'/g, "&#39;");
20
+ };
21
+ /**
22
+ * Renders a severity value as a colored badge span.
23
+ *
24
+ * @param severity - The severity string (e.g. "info", "low", "medium", "high")
25
+ * @returns HTML for a `<span class="badge badge-<severity>">` element. Unknown
26
+ * severities fall back to a neutral "badge-unknown" style.
27
+ */
28
+ export const severityBadgeHtml = (severity) => {
29
+ const key = (severity || "").toString().toLowerCase().trim();
30
+ const known = Object.prototype.hasOwnProperty.call(SEVERITY_COLORS, key);
31
+ const cls = known ? `badge-${key}` : "badge-unknown";
32
+ const label = escapeHtml(severity !== null && severity !== void 0 ? severity : "unknown");
33
+ return `<span class="badge ${cls}">${label}</span>`;
34
+ };
35
+ //# sourceMappingURL=severityColors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"severityColors.js","sourceRoot":"","sources":["../../../src/report/utility/severityColors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,MAAM,CAAC,MAAM,eAAe,GAAkC;IAC1D,IAAI,EAAE,EAAE,EAAE,EAAE,oBAAoB,EAAE,IAAI,EAAE,sBAAsB,EAAE,MAAM,EAAE,wBAAwB,EAAE;IAClG,GAAG,EAAE,EAAE,EAAE,EAAE,mBAAmB,EAAE,IAAI,EAAE,qBAAqB,EAAE,MAAM,EAAE,uBAAuB,EAAE;IAC9F,MAAM,EAAE,EAAE,EAAE,EAAE,sBAAsB,EAAE,IAAI,EAAE,wBAAwB,EAAE,MAAM,EAAE,0BAA0B,EAAE;IAC1G,IAAI,EAAE,EAAE,EAAE,EAAE,oBAAoB,EAAE,IAAI,EAAE,sBAAsB,EAAE,MAAM,EAAE,wBAAwB,EAAE;CACrG,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,KAAc,EAAU,EAAE;IAC1C,MAAM,GAAG,GAAG,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,GAAG;SACL,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAChC,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,QAAmC,EAAU,EAAE;IAC7E,MAAM,GAAG,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IAC7D,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;IACzE,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC;IACrD,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,SAAS,CAAC,CAAC;IAChD,OAAO,sBAAsB,GAAG,KAAK,KAAK,SAAS,CAAC;AACxD,CAAC,CAAC"}