@opsydyn/elysia-spectral 1.3.0 → 1.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.
- package/CHANGELOG.md +14 -0
- package/dist/index.mjs +9 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.4.0](https://github.com/opsydyn/elysia-spectral/compare/v1.3.1...v1.4.0) (2026-04-28)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **dashboard:** redesign with sharp-edge knowledge-store aesthetic ([81c3082](https://github.com/opsydyn/elysia-spectral/commit/81c3082b49a79a660d6d12e035ad57a9e2f24253))
|
|
9
|
+
|
|
10
|
+
## [1.3.1](https://github.com/opsydyn/elysia-spectral/compare/v1.3.0...v1.3.1) (2026-04-28)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* **dashboard:** stop double-encoding inlined CSS and JS assets ([a4457bf](https://github.com/opsydyn/elysia-spectral/commit/a4457bf87fc30e5a0e68a580796085f39aa49dbe))
|
|
16
|
+
|
|
3
17
|
## [1.3.0](https://github.com/opsydyn/elysia-spectral/compare/v1.2.0...v1.3.0) (2026-04-28)
|
|
4
18
|
|
|
5
19
|
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { a as enforceThreshold, c as strict, d as RulesetLoadError, f as defaultRulesetResolvers, g as lintOpenApi, h as recommended, i as OpenApiLintThresholdError, l as server, m as loadRuleset, n as createOpenApiLintRuntime, o as shouldFail, p as loadResolvedRuleset, r as resolveStartupMode, s as presets, t as OpenApiLintArtifactWriteError, u as resolveReporter } from "./core-BLJeXQ15.mjs";
|
|
2
2
|
import { Elysia } from "elysia";
|
|
3
|
-
//#region \
|
|
4
|
-
var
|
|
3
|
+
//#region \0inline-text:3.mjs
|
|
4
|
+
var _inline_text_3_default = "(() => {\n const THEME_KEY = 'elysia-spectral-theme';\n const THEMES = ['astro', 'tron', '808'];\n let stored = null;\n try {\n stored = localStorage.getItem(THEME_KEY);\n } catch {}\n const initial = THEMES.includes(stored) ? stored : 'astro';\n document.documentElement.dataset.theme = initial;\n\n const themeSel = document.querySelector('[data-theme-switcher]');\n if (themeSel) {\n themeSel.value = initial;\n themeSel.addEventListener('change', () => {\n const next = THEMES.includes(themeSel.value) ? themeSel.value : 'astro';\n document.documentElement.dataset.theme = next;\n try {\n localStorage.setItem(THEME_KEY, next);\n } catch {}\n });\n }\n\n const rel = (iso) => {\n const t = Date.parse(iso);\n if (Number.isNaN(t)) return '';\n const s = Math.round((Date.now() - t) / 1000);\n if (s < 60) return s + 's ago';\n if (s < 3600) return Math.round(s / 60) + 'm ago';\n if (s < 86400) return Math.round(s / 3600) + 'h ago';\n return Math.round(s / 86400) + 'd ago';\n };\n for (const el of document.querySelectorAll('[data-relative-time]')) {\n el.textContent = rel(el.getAttribute('data-relative-time'));\n }\n\n const rows = Array.from(document.querySelectorAll('[data-findings] tr'));\n const search = document.querySelector('[data-search]');\n const empty = document.querySelector('[data-empty-findings]');\n const chips = Array.from(document.querySelectorAll('[data-filter]'));\n let activeSeverity = 'all';\n let query = '';\n\n const apply = () => {\n let visible = 0;\n for (const tr of rows) {\n const sev = tr.getAttribute('data-severity');\n const hay = tr.getAttribute('data-haystack') || '';\n const sevOk = activeSeverity === 'all' || sev === activeSeverity;\n const qOk = !query || hay.includes(query);\n const show = sevOk && qOk;\n tr.classList.toggle('is-hidden', !show);\n if (show) visible += 1;\n }\n if (empty)\n empty.classList.toggle('hidden', visible !== 0 || rows.length === 0);\n };\n\n for (const chip of chips) {\n const select = () => {\n activeSeverity = chip.getAttribute('data-filter') || 'all';\n for (const c of chips) c.classList.toggle('is-active', c === chip);\n apply();\n };\n chip.addEventListener('click', select);\n chip.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n select();\n }\n });\n }\n\n if (search) {\n search.addEventListener('input', () => {\n query = search.value.trim().toLowerCase();\n apply();\n });\n }\n\n for (const btn of document.querySelectorAll('[data-copy]')) {\n btn.addEventListener('click', async () => {\n const value = btn.getAttribute('data-copy') || '';\n try {\n await navigator.clipboard.writeText(value);\n btn.classList.add('copied');\n btn.textContent = 'copied';\n setTimeout(() => {\n btn.classList.remove('copied');\n btn.textContent = 'copy';\n }, 1200);\n } catch {}\n });\n }\n\n document.addEventListener('keydown', (e) => {\n if (\n e.target &&\n (e.target.tagName === 'INPUT' ||\n e.target.tagName === 'TEXTAREA' ||\n e.target.tagName === 'SELECT')\n )\n return;\n if (e.key === 'r') {\n const link = document.querySelector('[data-refresh]');\n if (link) link.click();\n }\n if (e.key === '/' && search) {\n e.preventDefault();\n search.focus();\n }\n });\n})();\n";
|
|
5
5
|
//#endregion
|
|
6
|
-
//#region \
|
|
7
|
-
var dashboard_css_default = "export default \":root {\\n color-scheme: dark;\\n --bg: #17191e;\\n --fg: #eef0f9;\\n --muted: #8a93a0;\\n --line: #262a33;\\n --surface: #1d2027;\\n --accent: #ad5dca;\\n --accent-soft: #2b7eca;\\n --pass: #23d18b;\\n --fail: #dc3657;\\n --warn: #ffc368;\\n --info: #54b9ff;\\n --hint: #545864;\\n --mono:\\n ui-monospace, SFMono-Regular, \\\"JetBrains Mono\\\", Menlo, Monaco, Consolas,\\n \\\"Liberation Mono\\\", \\\"Courier New\\\", monospace;\\n}\\n\\n[data-theme=\\\"tron\\\"] {\\n --bg: #06080d;\\n --fg: #e6f7ff;\\n --muted: #5d8aa3;\\n --line: #0e2c3d;\\n --surface: #0a1320;\\n --accent: #38f3ff;\\n --accent-soft: #1ea7ff;\\n --pass: #7de8ff;\\n --fail: #ff3c5f;\\n --warn: #a8f5ff;\\n --info: #73d8ff;\\n --hint: #273746;\\n}\\n\\n[data-theme=\\\"808\\\"] {\\n --bg: #202020;\\n --fg: #ffffff;\\n --muted: #9a958a;\\n --line: #2a2a2a;\\n --surface: #262626;\\n --accent: #f8a125;\\n --accent-soft: #e72e2e;\\n --pass: #f1f827;\\n --fail: #e72e2e;\\n --warn: #f8a125;\\n --info: #f1f827;\\n --hint: #404040;\\n}\\n\\n* {\\n box-sizing: border-box;\\n}\\n\\nbody {\\n margin: 0;\\n font-family: var(--mono);\\n font-feature-settings:\\n \\\"calt\\\" 0,\\n \\\"liga\\\" 0,\\n \\\"ss01\\\";\\n background: var(--bg);\\n color: var(--fg);\\n font-size: 13px;\\n line-height: 1.5;\\n}\\n\\nheader {\\n position: sticky;\\n top: 0;\\n z-index: 10;\\n display: flex;\\n align-items: center;\\n justify-content: space-between;\\n padding: 16px 24px;\\n border-bottom: 1px solid var(--line);\\n background: color-mix(in srgb, var(--bg) 88%, transparent);\\n backdrop-filter: blur(8px);\\n overflow: hidden;\\n}\\n\\nheader::before {\\n content: \\\"\\\";\\n position: absolute;\\n inset: 0;\\n z-index: 0;\\n background:\\n radial-gradient(900px 220px at 12% -30%, var(--accent), transparent 60%),\\n radial-gradient(\\n 700px 200px at 88% -20%,\\n var(--accent-soft),\\n transparent 65%\\n );\\n opacity: 0.45;\\n pointer-events: none;\\n}\\n\\nheader > * {\\n position: relative;\\n z-index: 1;\\n}\\n\\n.brand {\\n display: flex;\\n align-items: center;\\n gap: 10px;\\n}\\n\\n.dot {\\n width: 8px;\\n height: 8px;\\n border-radius: 50%;\\n background: var(--accent);\\n box-shadow:\\n 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent),\\n 0 0 18px color-mix(in srgb, var(--accent) 60%, transparent);\\n}\\n\\nh1 {\\n margin: 0;\\n font-size: 13px;\\n font-weight: 600;\\n letter-spacing: 0.02em;\\n text-transform: uppercase;\\n}\\n\\n.actions {\\n display: flex;\\n align-items: center;\\n gap: 10px;\\n}\\n\\n.visually-hidden {\\n position: absolute;\\n width: 1px;\\n height: 1px;\\n overflow: hidden;\\n clip: rect(0 0 0 0);\\n}\\n\\n.theme-switch {\\n display: inline-flex;\\n align-items: center;\\n gap: 6px;\\n}\\n\\n.theme-label {\\n font-size: 10px;\\n text-transform: uppercase;\\n letter-spacing: 0.08em;\\n color: var(--muted);\\n}\\n\\n.theme-switch select {\\n font-family: var(--mono);\\n font-size: 11px;\\n padding: 5px 24px 5px 10px;\\n border: 1px solid var(--line);\\n border-radius: 6px;\\n background: var(--surface)\\n url(\\\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path fill='none' stroke='%238a93a0' stroke-width='1.4' d='M1 1l4 4 4-4'/></svg>\\\")\\n no-repeat right 8px center;\\n color: var(--fg);\\n -webkit-appearance: none;\\n appearance: none;\\n cursor: pointer;\\n}\\n.theme-switch select:hover {\\n border-color: var(--muted);\\n}\\n.theme-switch select:focus {\\n outline: none;\\n border-color: var(--accent);\\n}\\n\\nkbd {\\n font-family: var(--mono);\\n font-size: 11px;\\n padding: 2px 6px;\\n border: 1px solid var(--line);\\n border-bottom-width: 2px;\\n border-radius: 4px;\\n color: var(--muted);\\n background: var(--surface);\\n}\\n\\n.refresh {\\n color: var(--fg);\\n text-decoration: none;\\n padding: 6px 12px;\\n border: 1px solid var(--line);\\n border-radius: 6px;\\n font-size: 12px;\\n font-family: var(--mono);\\n background: var(--surface);\\n transition:\\n border-color 0.15s,\\n transform 0.05s;\\n}\\n.refresh:hover {\\n border-color: var(--accent);\\n}\\n.refresh:active {\\n transform: translateY(1px);\\n}\\n\\nmain {\\n padding: 24px;\\n max-width: 1100px;\\n margin: 0 auto;\\n}\\n\\n.banner {\\n padding: 12px 16px;\\n border-radius: 8px;\\n margin-bottom: 16px;\\n font-size: 13px;\\n}\\n.banner-pass {\\n background: color-mix(in srgb, var(--pass) 14%, transparent);\\n border: 1px solid color-mix(in srgb, var(--pass) 60%, var(--line));\\n}\\n.banner-fail {\\n background: color-mix(in srgb, var(--fail) 14%, transparent);\\n border: 1px solid color-mix(in srgb, var(--fail) 60%, var(--line));\\n}\\n.tagline {\\n display: block;\\n margin-top: 6px;\\n font-weight: 700;\\n letter-spacing: 0.12em;\\n color: var(--pass);\\n text-transform: uppercase;\\n font-size: 11px;\\n}\\n\\n.meta {\\n display: grid;\\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\\n gap: 8px;\\n margin: 0 0 16px;\\n padding: 0;\\n}\\n.meta div {\\n background: var(--surface);\\n border: 1px solid var(--line);\\n border-radius: 6px;\\n padding: 8px 12px;\\n}\\n.meta dt {\\n color: var(--muted);\\n font-size: 10px;\\n text-transform: uppercase;\\n letter-spacing: 0.06em;\\n margin-bottom: 4px;\\n}\\n.meta dd {\\n margin: 0;\\n font-size: 12px;\\n}\\n.muted-line {\\n display: block;\\n color: var(--muted);\\n font-size: 11px;\\n margin-top: 2px;\\n}\\n\\n.summary {\\n list-style: none;\\n padding: 0;\\n margin: 0 0 24px;\\n display: flex;\\n gap: 6px;\\n flex-wrap: wrap;\\n}\\n.summary li {\\n padding: 6px 12px;\\n border: 1px solid var(--line);\\n border-radius: 999px;\\n font-size: 12px;\\n color: var(--muted);\\n cursor: pointer;\\n user-select: none;\\n transition:\\n border-color 0.12s,\\n background 0.12s;\\n}\\n.summary li:hover {\\n border-color: var(--muted);\\n}\\n.summary li:focus {\\n outline: 2px solid color-mix(in srgb, var(--accent) 60%, transparent);\\n outline-offset: 2px;\\n}\\n.summary li.is-active {\\n background: color-mix(in srgb, var(--accent) 14%, transparent);\\n border-color: var(--accent);\\n color: var(--fg);\\n}\\n.summary li span {\\n color: var(--fg);\\n font-weight: 600;\\n margin-right: 6px;\\n}\\n.summary .sev-error span {\\n color: var(--fail);\\n}\\n.summary .sev-warn span {\\n color: var(--warn);\\n}\\n.summary .sev-info span {\\n color: var(--info);\\n}\\n\\nsection {\\n margin-top: 24px;\\n}\\nh2 {\\n font-size: 11px;\\n text-transform: uppercase;\\n letter-spacing: 0.06em;\\n color: var(--muted);\\n margin: 0 0 12px;\\n font-weight: 600;\\n}\\n\\n.findings-head {\\n display: flex;\\n align-items: center;\\n justify-content: space-between;\\n gap: 12px;\\n margin-bottom: 8px;\\n}\\n.findings-head h2 {\\n margin: 0;\\n}\\n\\n[data-search] {\\n font-family: var(--mono);\\n font-size: 12px;\\n padding: 6px 10px;\\n min-width: 240px;\\n background: var(--surface);\\n color: var(--fg);\\n border: 1px solid var(--line);\\n border-radius: 6px;\\n}\\n[data-search]:focus {\\n outline: none;\\n border-color: var(--accent);\\n}\\n\\n.artifacts {\\n list-style: none;\\n padding: 0;\\n margin: 0;\\n}\\n.artifacts li {\\n display: flex;\\n align-items: center;\\n gap: 12px;\\n padding: 6px 0;\\n border-bottom: 1px solid var(--line);\\n font-size: 12px;\\n}\\n.artifacts code {\\n color: var(--muted);\\n min-width: 160px;\\n}\\n.artifacts .path {\\n flex: 1;\\n word-break: break-all;\\n}\\n\\n.copy {\\n font-family: var(--mono);\\n font-size: 11px;\\n padding: 2px 8px;\\n border: 1px solid var(--line);\\n background: var(--surface);\\n color: var(--muted);\\n border-radius: 4px;\\n cursor: pointer;\\n}\\n.copy:hover {\\n color: var(--fg);\\n border-color: var(--muted);\\n}\\n.copy.copied {\\n color: var(--pass);\\n border-color: var(--pass);\\n}\\n\\ntable {\\n width: 100%;\\n border-collapse: collapse;\\n font-size: 12px;\\n}\\nth,\\ntd {\\n text-align: left;\\n padding: 8px 12px;\\n border-bottom: 1px solid var(--line);\\n vertical-align: top;\\n}\\nth {\\n color: var(--muted);\\n font-weight: 500;\\n font-size: 10px;\\n text-transform: uppercase;\\n letter-spacing: 0.06em;\\n}\\ntbody tr:hover {\\n background: color-mix(in srgb, var(--fg) 4%, transparent);\\n}\\ntr.is-hidden {\\n display: none;\\n}\\n\\n.badge {\\n display: inline-block;\\n padding: 2px 8px;\\n border-radius: 4px;\\n font-size: 10px;\\n text-transform: uppercase;\\n letter-spacing: 0.06em;\\n font-family: var(--mono);\\n}\\n.sev-error .badge {\\n background: color-mix(in srgb, var(--fail) 22%, transparent);\\n color: var(--fail);\\n}\\n.sev-warn .badge {\\n background: color-mix(in srgb, var(--warn) 22%, transparent);\\n color: var(--warn);\\n}\\n.sev-info .badge {\\n background: color-mix(in srgb, var(--info) 22%, transparent);\\n color: var(--info);\\n}\\n.sev-hint .badge {\\n background: color-mix(in srgb, var(--hint) 22%, transparent);\\n color: var(--hint);\\n}\\n\\n.recommendation {\\n margin: 4px 0 0;\\n color: var(--muted);\\n font-size: 11px;\\n}\\n.pointer {\\n display: block;\\n margin-top: 4px;\\n color: var(--muted);\\n font-size: 11px;\\n}\\n.empty {\\n color: var(--muted);\\n font-size: 12px;\\n}\\n.hidden {\\n display: none;\\n}\\n\";";
|
|
6
|
+
//#region \0inline-text:2.mjs
|
|
7
|
+
var _inline_text_2_default = ":root {\n color-scheme: dark;\n --bg: #0e1018;\n --fg: #eef0f9;\n --muted: #8a93a0;\n --line: #262a33;\n --surface: #161922;\n --surface-2: #1d2027;\n --accent: #ad5dca;\n --accent-soft: #2b7eca;\n --accent-2: #2dd4bf;\n --pass: #23d18b;\n --fail: #dc3657;\n --warn: #ffc368;\n --info: #54b9ff;\n --hint: #545864;\n --grid-line: rgba(255, 255, 255, 0.04);\n --grid-size: 2rem;\n --mono:\n \"IBM Plex Mono\", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,\n \"Liberation Mono\", \"Courier New\", monospace;\n --display: \"Bangers\", var(--mono);\n}\n\n[data-theme=\"tron\"] {\n --bg: #06080d;\n --fg: #e6f7ff;\n --muted: #5d8aa3;\n --line: #0e2c3d;\n --surface: #0a1320;\n --surface-2: #0d1a2b;\n --accent: #38f3ff;\n --accent-soft: #1ea7ff;\n --accent-2: #38f3ff;\n --pass: #7de8ff;\n --fail: #ff3c5f;\n --warn: #a8f5ff;\n --info: #73d8ff;\n --hint: #273746;\n --grid-line: rgba(56, 243, 255, 0.06);\n}\n\n[data-theme=\"808\"] {\n --bg: #1a1a1a;\n --fg: #ffffff;\n --muted: #9a958a;\n --line: #2a2a2a;\n --surface: #222222;\n --surface-2: #2a2a2a;\n --accent: #f8a125;\n --accent-soft: #e72e2e;\n --accent-2: #f1f827;\n --pass: #f1f827;\n --fail: #e72e2e;\n --warn: #f8a125;\n --info: #f1f827;\n --hint: #404040;\n --grid-line: rgba(248, 161, 37, 0.06);\n}\n\n* {\n box-sizing: border-box;\n}\n\nhtml {\n background:\n radial-gradient(\n circle at top left,\n color-mix(in srgb, var(--accent) 14%, transparent),\n transparent 32%\n ),\n radial-gradient(\n circle at top right,\n color-mix(in srgb, var(--accent-2) 10%, transparent),\n transparent 30%\n ),\n var(--bg);\n min-height: 100%;\n}\n\nbody {\n margin: 0;\n font-family: var(--mono);\n background:\n linear-gradient(\n 180deg,\n color-mix(in srgb, var(--bg) 92%, transparent),\n transparent 16rem\n ),\n linear-gradient(90deg, var(--grid-line) 1px, transparent 1px),\n linear-gradient(var(--grid-line) 1px, transparent 1px), transparent;\n background-size:\n auto,\n var(--grid-size) var(--grid-size),\n var(--grid-size) var(--grid-size),\n auto;\n background-position:\n 0 0,\n center top,\n center top,\n 0 0;\n color: var(--fg);\n font-size: 13px;\n line-height: 1.55;\n}\n\nheader {\n position: sticky;\n top: 0;\n z-index: 10;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 24px;\n background: color-mix(in srgb, var(--bg) 82%, transparent);\n backdrop-filter: blur(16px);\n box-shadow: 0 1px 0 color-mix(in srgb, var(--fg) 8%, transparent);\n overflow: hidden;\n}\n\nheader::before {\n content: \"\";\n position: absolute;\n inset: 0;\n z-index: 0;\n background:\n radial-gradient(900px 220px at 12% -30%, var(--accent), transparent 60%),\n radial-gradient(\n 700px 200px at 88% -20%,\n var(--accent-soft),\n transparent 65%\n );\n opacity: 0.35;\n pointer-events: none;\n}\n\nheader::after {\n content: \"\";\n position: absolute;\n left: 0;\n right: 0;\n bottom: 0;\n height: 1px;\n background: linear-gradient(\n 90deg,\n transparent,\n color-mix(in srgb, var(--accent) 55%, transparent),\n transparent\n );\n}\n\nheader > * {\n position: relative;\n z-index: 1;\n}\n\n.brand {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.dot {\n width: 10px;\n height: 10px;\n background: linear-gradient(135deg, var(--accent), var(--accent-2));\n box-shadow:\n 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent),\n 0 0 18px color-mix(in srgb, var(--accent) 60%, transparent);\n}\n\nh1 {\n margin: 0;\n font-family: var(--display);\n font-size: 22px;\n font-weight: 400;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n text-shadow: 0.04em 0.04em 0\n color-mix(in srgb, var(--accent) 22%, transparent);\n}\n\n.actions {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0 0 0 0);\n}\n\n.theme-switch {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 4px 10px;\n border: 1px solid var(--line);\n background: color-mix(in srgb, var(--surface) 85%, transparent);\n}\n\n.theme-label {\n font-size: 10px;\n text-transform: uppercase;\n letter-spacing: 0.12em;\n color: var(--muted);\n font-weight: 600;\n}\n\n.theme-switch select {\n font-family: var(--mono);\n font-size: 11px;\n padding: 4px 22px 4px 8px;\n border: 1px solid var(--line);\n border-radius: 0;\n background: var(--surface-2)\n url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path fill='none' stroke='%238a93a0' stroke-width='1.4' d='M1 1l4 4 4-4'/></svg>\")\n no-repeat right 8px center;\n color: var(--fg);\n -webkit-appearance: none;\n appearance: none;\n cursor: pointer;\n}\n.theme-switch select:hover {\n border-color: var(--accent);\n}\n.theme-switch select:focus {\n outline: none;\n border-color: var(--accent);\n}\n\nkbd {\n font-family: var(--mono);\n font-size: 11px;\n padding: 3px 7px;\n border: 1px solid var(--line);\n border-bottom-width: 2px;\n border-radius: 0;\n color: var(--muted);\n background: var(--surface);\n}\n\n.refresh {\n color: var(--fg);\n text-decoration: none;\n padding: 7px 14px;\n border: 1px solid var(--line);\n border-radius: 0;\n font-size: 12px;\n font-family: var(--mono);\n font-weight: 600;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n background: var(--surface);\n box-shadow: 0 6px 18px rgba(0, 0, 0, 0.25);\n transition:\n border-color 0.15s,\n transform 0.05s,\n color 0.15s;\n}\n.refresh:hover {\n border-color: var(--accent);\n color: var(--accent);\n}\n.refresh:active {\n transform: translateY(1px);\n}\n\nmain {\n padding: 28px 24px 64px;\n max-width: 1100px;\n margin: 0 auto;\n}\n\n.banner {\n position: relative;\n padding: 16px 18px;\n border-radius: 0;\n margin-bottom: 20px;\n font-size: 13px;\n border: 1px solid var(--line);\n background: linear-gradient(\n 180deg,\n color-mix(in srgb, var(--surface) 80%, transparent),\n color-mix(in srgb, var(--bg) 92%, transparent)\n );\n box-shadow: 0 18px 44px rgba(0, 0, 0, 0.28);\n}\n.banner::before {\n content: \"\";\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: var(--accent);\n}\n.banner-pass::before {\n background: var(--pass);\n}\n.banner-fail::before {\n background: var(--fail);\n}\n.banner-pass {\n border-color: color-mix(in srgb, var(--pass) 45%, var(--line));\n}\n.banner-fail {\n border-color: color-mix(in srgb, var(--fail) 45%, var(--line));\n}\n.banner strong {\n font-family: var(--display);\n font-weight: 400;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n font-size: 16px;\n margin-right: 6px;\n}\n.tagline {\n display: block;\n margin-top: 8px;\n font-weight: 700;\n letter-spacing: 0.16em;\n color: var(--pass);\n text-transform: uppercase;\n font-size: 11px;\n}\n\n.meta {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 10px;\n margin: 0 0 20px;\n padding: 0;\n}\n.meta div {\n background: linear-gradient(\n 180deg,\n color-mix(in srgb, var(--surface) 90%, var(--accent) 10%),\n color-mix(in srgb, var(--bg) 96%, transparent)\n );\n border: 1px solid var(--line);\n border-radius: 0;\n padding: 10px 14px;\n box-shadow: 0 6px 18px rgba(0, 0, 0, 0.22);\n}\n.meta dt {\n color: var(--muted);\n font-size: 10px;\n text-transform: uppercase;\n letter-spacing: 0.1em;\n margin-bottom: 4px;\n font-weight: 600;\n}\n.meta dd {\n margin: 0;\n font-size: 12px;\n}\n.muted-line {\n display: block;\n color: var(--muted);\n font-size: 11px;\n margin-top: 2px;\n}\n\n.summary {\n list-style: none;\n padding: 0;\n margin: 0 0 28px;\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n.summary li {\n padding: 7px 14px;\n border: 1px solid var(--line);\n border-radius: 0;\n font-size: 12px;\n color: var(--muted);\n cursor: pointer;\n user-select: none;\n background: color-mix(in srgb, var(--surface) 80%, transparent);\n transition:\n border-color 0.12s,\n background 0.12s,\n color 0.12s;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n font-weight: 600;\n}\n.summary li:hover {\n border-color: var(--muted);\n color: var(--fg);\n}\n.summary li:focus {\n outline: 2px solid color-mix(in srgb, var(--accent) 60%, transparent);\n outline-offset: 2px;\n}\n.summary li.is-active {\n background: color-mix(in srgb, var(--accent) 16%, transparent);\n border-color: var(--accent);\n color: var(--fg);\n}\n.summary li span {\n color: var(--fg);\n font-weight: 700;\n margin-right: 8px;\n font-family: var(--display);\n letter-spacing: 0.05em;\n}\n.summary .sev-error span {\n color: var(--fail);\n}\n.summary .sev-warn span {\n color: var(--warn);\n}\n.summary .sev-info span {\n color: var(--info);\n}\n\nsection {\n margin-top: 28px;\n}\nh2 {\n font-family: var(--display);\n font-size: 14px;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n color: var(--fg);\n margin: 0 0 14px;\n font-weight: 400;\n}\n\n.findings-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 12px;\n}\n.findings-head h2 {\n margin: 0;\n}\n\n[data-search] {\n font-family: var(--mono);\n font-size: 12px;\n padding: 8px 12px;\n min-width: 260px;\n background: var(--surface);\n color: var(--fg);\n border: 1px solid var(--line);\n border-radius: 0;\n}\n[data-search]:focus {\n outline: none;\n border-color: var(--accent);\n}\n\n.artifacts {\n list-style: none;\n padding: 0;\n margin: 0;\n border: 1px solid var(--line);\n background: color-mix(in srgb, var(--surface) 70%, transparent);\n}\n.artifacts li {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--line);\n font-size: 12px;\n}\n.artifacts li:last-child {\n border-bottom: 0;\n}\n.artifacts code {\n color: var(--muted);\n min-width: 160px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n font-weight: 600;\n font-size: 11px;\n}\n.artifacts .path {\n flex: 1;\n word-break: break-all;\n}\n\n.copy {\n font-family: var(--mono);\n font-size: 10px;\n padding: 4px 10px;\n border: 1px solid var(--line);\n border-radius: 0;\n background: var(--surface);\n color: var(--muted);\n cursor: pointer;\n text-transform: uppercase;\n letter-spacing: 0.1em;\n font-weight: 600;\n}\n.copy:hover {\n color: var(--fg);\n border-color: var(--accent);\n}\n.copy.copied {\n color: var(--pass);\n border-color: var(--pass);\n}\n\ntable {\n width: 100%;\n border-collapse: collapse;\n font-size: 12px;\n border: 1px solid var(--line);\n background: color-mix(in srgb, var(--surface) 70%, transparent);\n}\nth,\ntd {\n text-align: left;\n padding: 10px 14px;\n border-bottom: 1px solid var(--line);\n vertical-align: top;\n}\ntr:last-child td {\n border-bottom: 0;\n}\nth {\n color: var(--muted);\n font-weight: 600;\n font-size: 10px;\n text-transform: uppercase;\n letter-spacing: 0.1em;\n background: color-mix(in srgb, var(--surface-2) 70%, transparent);\n}\ntbody tr:hover {\n background: color-mix(in srgb, var(--accent) 5%, transparent);\n}\ntr.is-hidden {\n display: none;\n}\n\n.badge {\n display: inline-block;\n padding: 3px 9px;\n border-radius: 0;\n font-size: 10px;\n text-transform: uppercase;\n letter-spacing: 0.1em;\n font-family: var(--mono);\n font-weight: 700;\n border: 1px solid transparent;\n}\n.sev-error .badge {\n background: color-mix(in srgb, var(--fail) 18%, transparent);\n color: var(--fail);\n border-color: color-mix(in srgb, var(--fail) 35%, transparent);\n}\n.sev-warn .badge {\n background: color-mix(in srgb, var(--warn) 18%, transparent);\n color: var(--warn);\n border-color: color-mix(in srgb, var(--warn) 35%, transparent);\n}\n.sev-info .badge {\n background: color-mix(in srgb, var(--info) 18%, transparent);\n color: var(--info);\n border-color: color-mix(in srgb, var(--info) 35%, transparent);\n}\n.sev-hint .badge {\n background: color-mix(in srgb, var(--hint) 22%, transparent);\n color: var(--hint);\n border-color: color-mix(in srgb, var(--hint) 35%, transparent);\n}\n\n.recommendation {\n margin: 6px 0 0;\n color: var(--muted);\n font-size: 11px;\n}\n.pointer {\n display: block;\n margin-top: 6px;\n color: var(--muted);\n font-size: 11px;\n}\n.empty {\n color: var(--muted);\n font-size: 12px;\n}\n.hidden {\n display: none;\n}\n\n:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n}\n";
|
|
8
8
|
//#endregion
|
|
9
9
|
//#region src/output/dashboard.ts
|
|
10
10
|
const renderDashboard = (input) => {
|
|
@@ -16,7 +16,10 @@ const renderDashboard = (input) => {
|
|
|
16
16
|
<meta charset="utf-8" />
|
|
17
17
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
18
18
|
<title>Elysia Spectral Lint Dashboard</title>
|
|
19
|
-
<
|
|
19
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
20
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
21
|
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Bangers&family=IBM+Plex+Mono:wght@400;500;600;700&display=swap" />
|
|
22
|
+
<style>${_inline_text_2_default}</style>
|
|
20
23
|
</head>
|
|
21
24
|
<body>
|
|
22
25
|
<header>
|
|
@@ -38,7 +41,7 @@ const renderDashboard = (input) => {
|
|
|
38
41
|
</div>
|
|
39
42
|
</header>
|
|
40
43
|
<main>${body}</main>
|
|
41
|
-
<script>${
|
|
44
|
+
<script>${_inline_text_3_default}<\/script>
|
|
42
45
|
</body>
|
|
43
46
|
</html>`;
|
|
44
47
|
};
|