UNPKG

@tezx/devtools

Version:

Developer tools for the TezX framework, including route inspector, cookie manager, and real-time diagnostics. Lightweight and plug-and-play compatible with Node.js, Bun, and Deno.

143 lines (133 loc) โ€ข 4.61 kB
export function StaticFile(ctx, app) { const staticMap = Object.keys(app.staticFile || {}); const rawJSON = JSON.stringify(staticMap.map(r => { const [method, path] = r.split(" "); return { method, path }; }), null, 2); const toCSV = (data) => { const headers = ["Path", "Method"]; const rows = data.map((s) => { const [method, path] = s.split(" "); return [JSON.stringify(path), JSON.stringify(method)]; }); return [headers.join(","), ...rows.map((r) => r.join(","))].join("\n"); }; const csvString = toCSV(staticMap).replace(/"/g, "&quot;"); return ` <style> .download { margin-top: 1rem; display: flex; gap: 1rem; } .download a { padding: 0.5rem 1rem; border: 1px solid var(--accent); color: var(--accent); text-decoration: none; border-radius: 6px; } .download a:hover { background: var(--accent); color: white; } #searchBar { margin: 1rem 0; display: flex; } #searchBar input { flex: 1; } pre { margin: 0; font-size: 0.875rem; line-height: 1.4; } </style> <div class="tabs toolbar"> <a class="tab-btn active" onclick="showTab('static')">๐Ÿ“‚ Static Files (${staticMap?.length})</a> <a class="tab-btn" onclick="showTab('json')">๐Ÿงพ Raw JSON</a> <a class="tab-btn" onclick="showTab('export')">๐Ÿ“ค Export</a> </div> <div id="searchBar"> <input type="text" id="search" placeholder="Filter by path or handler..." /> </div> <div id="staticTab" class="table-container"> <table id="staticTable"> <thead> <tr> <th>#</th> <th>Path</th> <th>Method</th> <th>Copy</th> </tr> </thead> <tbody> ${staticMap .map((s, i) => { const [method, path] = s.split(" "); return ` <tr> <td>${i + 1}</td> <td> <a href="${path}" target="_blank" style="color: var(--accent); text-decoration: underline; font-weight: 500; font-size: 0.95rem;"> ${path} </a> </td> <td>${method}</td> <td> <button class="copy-btn" onclick="copyToClipboard('${path}')"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"> <path d="M10 1.5A1.5 1.5 0 0 1 11.5 3v1h-1V3a.5.5 0 0 0-.5-.5H4A1.5 1.5 0 0 0 2.5 4v8A1.5 1.5 0 0 0 4 13.5H5v1H4A2.5 2.5 0 0 1 1.5 12V4A2.5 2.5 0 0 1 4 1.5h6z"/> <path d="M5.5 5A1.5 1.5 0 0 0 4 6.5v7A1.5 1.5 0 0 0 5.5 15h6A1.5 1.5 0 0 0 13 13.5v-7A1.5 1.5 0 0 0 11.5 5h-6zM5 6.5A.5.5 0 0 1 5.5 6h6a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-.5.5h-6a.5.5 0 0 1-.5-.5v-7z"/> </svg> </button> </td> </tr> `; }) .join("")} </tbody> </table> </div> <div id="jsonTab" style="display:none"> <div class="json-view"><pre><code>${rawJSON}</code></pre></div> </div> <div id="exportTab" style="display:none"> <div class="download"> <a href="data:text/json;charset=utf-8,${encodeURIComponent(rawJSON)}" download="static.json">๐Ÿ“ฅ JSON</a> <a href="data:text/csv;charset=utf-8,${csvString}" download="static.csv">๐Ÿ“ฅ CSV</a> </div> </div> <script> const tabs = ['static', 'json', 'export']; const tabBtns = document.querySelectorAll('.tab-btn'); function showTab(tab) { tabs.forEach(t => { document.getElementById(t + 'Tab').style.display = t === tab ? 'block' : 'none'; }); tabBtns.forEach(btn => { const active = btn.textContent.toLowerCase().includes(tab); btn.classList.toggle('active', active); }); document.getElementById('searchBar').style.display = (tab === 'static') ? 'flex' : 'none'; } document.getElementById('search').addEventListener('input', (e) => { const keyword = e.target.value.toLowerCase(); const rows = document.querySelectorAll('#staticTable tbody tr'); rows.forEach(row => { row.style.display = row.textContent.toLowerCase().includes(keyword) ? '' : 'none'; }); }); function copyToClipboard(text) { navigator.clipboard.writeText(text).then(() => { showToast("Copied: " + text); }).catch(err => { alert("Failed to copy "+ err?.message); }); } </script> `; }