fix: resolve Tauri full build TypeScript errors from tauri-typegen

- Consolidate ws-state and cert-tofu emit calls in ws_proxy.rs into
  private helper functions (emit_ws_state, emit_cert_tofu). One call
  site per event name prevents tauri-typegen 0.5.0 from generating
  duplicate event listener functions.
- Add CI fixup step that injects 'export type Value = unknown' into
  generated types.ts — tauri-typegen cannot map serde_json::Value to
  a TypeScript type, so the generated file references an undefined type.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
J3vb
2026-04-03 11:10:40 +02:00
co-authored by Claude Sonnet 4.6
parent d4f254b945
commit dc7859d284
2 changed files with 41 additions and 20 deletions
+17
View File
@@ -137,6 +137,23 @@ jobs:
working-directory: Client/tauri-client/
run: cargo tauri-typegen generate
- name: Fix generated TypeScript bindings (tauri-typegen 0.5.0 workaround)
working-directory: Client/tauri-client/
# tauri-typegen 0.5.0 cannot map serde_json::Value to a TS type — patch post-generation.
# Duplicate events are avoided at source by using one emit() call site per event name.
run: |
node -e "
const fs = require('fs');
const tp = fs.readFileSync('src/generated/types.ts', 'utf8');
if (!tp.includes('export type Value')) {
fs.writeFileSync('src/generated/types.ts', tp.replace(
'export interface CredentialData',
'export type Value = unknown;\n\nexport interface CredentialData'
));
}
console.log('Generated bindings patched.');
"
- name: Clippy lint (Rust)
working-directory: Client/tauri-client/src-tauri/
run: cargo clippy -- -D warnings
+24 -20
View File
@@ -179,6 +179,16 @@ fn tofu_check<R: Runtime>(
}
}
/// Single call site for ws-state events — keeps tauri-typegen from generating duplicates.
fn emit_ws_state<R: Runtime>(app: &AppHandle<R>, state: &str) {
let _ = app.emit("ws-state", state);
}
/// Single call site for cert-tofu events — keeps tauri-typegen from generating duplicates.
fn emit_cert_tofu<R: Runtime>(app: &AppHandle<R>, payload: serde_json::Value) {
let _ = app.emit("cert-tofu", payload);
}
/// Connect to a WSS server. Spawns a background task that:
/// - Emits `ws-message` events for incoming server messages
/// - Emits `ws-state` events for connection state changes
@@ -207,7 +217,7 @@ pub async fn ws_connect<R: Runtime>(
return Err("Only wss:// connections are permitted".into());
}
let _ = app.emit("ws-state", "connecting");
emit_ws_state(&app, "connecting");
// Create TOFU verifier that captures the cert fingerprint during handshake.
let (verifier, captured_fp) = TofuVerifier::new();
@@ -255,27 +265,21 @@ pub async fn ws_connect<R: Runtime>(
match tofu_check(&app, &host, &fingerprint) {
Ok(status) => {
info!("[ws_proxy] TOFU check passed for {}: {}", host, status);
let _ = app.emit(
"cert-tofu",
serde_json::json!({
"host": host,
"fingerprint": fingerprint,
"status": status,
}),
);
emit_cert_tofu(&app, serde_json::json!({
"host": host,
"fingerprint": fingerprint,
"status": status,
}));
}
Err(mismatch_msg) => {
warn!("[ws_proxy] TOFU check FAILED for {} — certificate fingerprint mismatch", host);
debug!("[ws_proxy] TOFU detail: {}", mismatch_msg);
let _ = app.emit(
"cert-tofu",
serde_json::json!({
"host": host,
"fingerprint": fingerprint,
"status": "mismatch",
"message": mismatch_msg,
}),
);
emit_cert_tofu(&app, serde_json::json!({
"host": host,
"fingerprint": fingerprint,
"status": "mismatch",
"message": mismatch_msg,
}));
// Reject the connection — do not proceed.
return Err(mismatch_msg);
}
@@ -283,7 +287,7 @@ pub async fn ws_connect<R: Runtime>(
// ── End TOFU check ───────────────────────────────────────────────────
info!("[ws_proxy] connected to {}", host);
let _ = app.emit("ws-state", "open");
emit_ws_state(&app, "open");
let (mut sink, mut stream) = ws_stream.split();
@@ -340,7 +344,7 @@ pub async fn ws_connect<R: Runtime>(
}
}
info!("[ws_proxy] connection closed");
let _ = app_state.emit("ws-state", "closed");
emit_ws_state(&app_state, "closed");
});
Ok(())