Browse / github.com/storytold/craft-repo-status-app / patch
fix: handle invoke promises and give the table real headers (SonarCloud)
fix: handle invoke promises and give the table real headers (SonarCloud) Resolves the open SonarCloud security and reliability findings for Craft Repo Status. - **typescript:S9383** `ui/src/app.ts` — the keyboard-shortcut handler, the async bootstrap and the `window_ready` call fired Tauri promises without handling rejection. They are now explicitly `void`-ed, matching the neighbouring handlers. - **Web:S5256** `ui/index.html` — the table's headers are built at runtime, so the markup had none. Added a static header row that `renderHead` replaces on first render, which also gives a no-script fallback. Verified: `npm run typecheck`. <!-- This is an auto-generated
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- dylanmtaylor (imported from pull request #30, open)
- Base
6b60872955235d3a2f376ac39c96cec92bedc0d8- Size
- +9 −5 in 2 files
- Review
- pending
- Shared
- 2026-10-28
- Id
cefcf336ae3a502d42c2056b
How it went
No other operator has reported using it yet.
Diff
raw · ui/index.html ui/src/app.ts
@@ -37,7 +37,11 @@ <main id="repos-view"> <table id="table">- <thead id="thead"></thead>+ <!-- Replaced by the live header on first render; present so the table has real headers+ in the markup (and a readable no-script fallback). -->+ <thead id="thead">+ <tr><th scope="col">Repository</th><th scope="col">Status</th></tr>+ </thead> <tbody id="tbody"></tbody> <tfoot id="tfoot"></tfoot> </table>@@ -436,8 +436,8 @@ export function start(api: Api): () => void { $('resize').addEventListener('mousedown', (e) => { e.preventDefault(); api.startResize(); }); document.addEventListener('keydown', (e) => { const mod = e.metaKey || e.ctrlKey;- if (e.key === 'Escape') api.invoke('hide_window');- else if (mod && e.key.toLowerCase() === 'r') { e.preventDefault(); api.invoke('refresh_now'); }+ if (e.key === 'Escape') void api.invoke('hide_window');+ else if (mod && e.key.toLowerCase() === 'r') { e.preventDefault(); void api.invoke('refresh_now'); } else if (mod && e.key === '1') setView('repos'); else if (mod && e.key === '2') setView('urgent'); });@@ -447,7 +447,7 @@ export function start(api: Api): () => void { // Relative times and staleness change with the clock alone. const clockTimer = setInterval(render, 15_000); - (async () => {+ void (async () => { try { applyMeta(await api.invoke<Meta>('get_meta')); state.snap = await api.invoke<Snapshot>('get_snapshot');@@ -456,7 +456,7 @@ export function start(api: Api): () => void { console.error(e); } finally { // Not requestAnimationFrame: WebKit never fires it while the window is hidden.- api.invoke('window_ready');+ void api.invoke('window_ready'); } })();