Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces ts-rs generated TypeScript bindings for Rust IPC types and refactors the frontend to consume those generated types instead of maintaining handwritten duplicates.
Changes:
- Add
ts-rsto the Tauri (Rust) backend and export multiple structs/enums intosrc/lib/bindings/. - Refactor frontend type imports/exports (
AppError,ErrorCode, and many IPC models) to use@/lib/bindings. - Adjust a few call sites/types to match generated nullability/optionality (e.g., patcher config args and workshop thumbnail path).
Reviewed changes
Copilot reviewed 55 out of 56 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/utils/errors.ts | Re-exports AppError/ErrorCode from generated bindings while keeping Zod-based context helpers. |
| src/pages/Library.tsx | Updates startPatcher invocation to pass an empty config object (optional fields). |
| src/modules/workshop/api/useProjectThumbnail.ts | Aligns thumbnail path typing to string | null | undefined and updates hook signature. |
| src/modules/workshop/api/keys.ts | Allows thumbnailPath to be null in query keys. |
| src/lib/tauri.ts | Replaces handwritten IPC model types with imports/re-exports from generated bindings. |
| src/lib/bindings/index.ts | Barrel export for all generated bindings. |
| src/lib/bindings/AccentColor.ts | Generated binding for AccentColor. |
| src/lib/bindings/AppError.ts | Generated binding for AppError. |
| src/lib/bindings/AppInfo.ts | Generated binding for AppInfo. |
| src/lib/bindings/BulkInstallError.ts | Generated binding for BulkInstallError. |
| src/lib/bindings/BulkInstallResult.ts | Generated binding for BulkInstallResult. |
| src/lib/bindings/CreateProjectArgs.ts | Generated binding for CreateProjectArgs. |
| src/lib/bindings/CslolModInfo.ts | Generated binding for CslolModInfo. |
| src/lib/bindings/ErrorCode.ts | Generated binding for ErrorCode. |
| src/lib/bindings/FantomeImportProgress.ts | Generated binding for FantomeImportProgress. |
| src/lib/bindings/FantomePeekResult.ts | Generated binding for FantomePeekResult. |
| src/lib/bindings/GitImportProgress.ts | Generated binding for GitImportProgress. |
| src/lib/bindings/ImportFantomeArgs.ts | Generated binding for ImportFantomeArgs. |
| src/lib/bindings/ImportGitRepoArgs.ts | Generated binding for ImportGitRepoArgs. |
| src/lib/bindings/InstalledMod.ts | Generated binding for InstalledMod. |
| src/lib/bindings/InstallProgress.ts | Generated binding for InstallProgress. |
| src/lib/bindings/LayerInfo.ts | Generated binding for LayerInfo. |
| src/lib/bindings/MigrationPhase.ts | Generated binding for MigrationPhase. |
| src/lib/bindings/MigrationProgress.ts | Generated binding for MigrationProgress. |
| src/lib/bindings/ModLayer.ts | Generated binding for ModLayer. |
| src/lib/bindings/ModpkgInfo.ts | Generated binding for ModpkgInfo. |
| src/lib/bindings/OverlayProgress.ts | Generated binding for OverlayProgress. |
| src/lib/bindings/PackFormat.ts | Generated binding for PackFormat. |
| src/lib/bindings/PackProjectArgs.ts | Generated binding for PackProjectArgs. |
| src/lib/bindings/PackResult.ts | Generated binding for PackResult. |
| src/lib/bindings/PatcherConfig.ts | Generated binding for PatcherConfig. |
| src/lib/bindings/PatcherPhase.ts | Generated binding for PatcherPhase. |
| src/lib/bindings/PatcherStatus.ts | Generated binding for PatcherStatus. |
| src/lib/bindings/Profile.ts | Generated binding for Profile. |
| src/lib/bindings/ProfileSlug.ts | Generated binding for ProfileSlug. |
| src/lib/bindings/SaveProjectConfigArgs.ts | Generated binding for SaveProjectConfigArgs. |
| src/lib/bindings/Settings.ts | Generated binding for Settings. |
| src/lib/bindings/Theme.ts | Generated binding for Theme. |
| src/lib/bindings/ValidationResult.ts | Generated binding for ValidationResult. |
| src/lib/bindings/WorkshopAuthor.ts | Generated binding for WorkshopAuthor. |
| src/lib/bindings/WorkshopLayer.ts | Generated binding for WorkshopLayer. |
| src/lib/bindings/WorkshopProject.ts | Generated binding for WorkshopProject. |
| src-tauri/src/workshop/mod.rs | Adds TS derives + exports for multiple workshop-related IPC types. |
| src-tauri/src/state.rs | Adds TS derives + exports and maps PathBuf to Option<String> for TS output. |
| src-tauri/src/patcher/mod.rs | Exports PatcherPhase via ts-rs. |
| src-tauri/src/overlay/mod.rs | Exports OverlayProgress via ts-rs. |
| src-tauri/src/mods/mod.rs | Exports multiple mod/profile/library-related IPC types via ts-rs. |
| src-tauri/src/mods/migration.rs | Exports CslolModInfo via ts-rs. |
| src-tauri/src/mods/inspect.rs | Exports ModpkgInfo/LayerInfo via ts-rs. |
| src-tauri/src/error.rs | Exports ErrorCode and renames exported error response to AppError. |
| src-tauri/src/commands/patcher.rs | Exports PatcherConfig/PatcherStatus via ts-rs, with optional markers. |
| src-tauri/src/commands/app.rs | Exports AppInfo via ts-rs. |
| src-tauri/Cargo.toml | Adds ts-rs dependency with chrono + serde_json impl features. |
| src-tauri/.cargo/config.toml | Sets TS_RS_EXPORT_DIR to ../src/lib/bindings/. |
| package.json | Adds generate:types script to trigger Rust compilation/export. |
| Cargo.lock | Locks ts-rs and transitive dependencies. |
Comments suppressed due to low confidence (3)
src-tauri/src/mods/inspect.rs:30
- Same issue as above for
LayerInfo.file_count: ts-rs will emitbigintforu64, but the value will be serialized over IPC as a JSON number. Please override the exported TS type or adjust serialization so the TS type matches the runtime value.
pub struct LayerInfo {
pub name: String,
pub priority: i32,
pub description: Option<String>,
pub file_count: u64,
src-tauri/src/overlay/mod.rs:19
OverlayProgress.stageis currently a free-formString, which causes the generated TS binding to widen tostage: string. The frontend relies on a finite set of stage literals for label maps and determinate progress logic; widening removes exhaustiveness checks and can let unknown stages slip through. Consider modelingstageas an enum (or overriding the ts-rs type to a string-literal union) so the TS binding stays in sync with the actual stage set.
pub struct OverlayProgress {
pub stage: String,
pub current_file: Option<String>,
pub current: u32,
pub total: u32,
src-tauri/src/workshop/mod.rs:124
FantomeImportProgress.stageis exported as aString, so the generated TS binding becomesstage: string. The UI branches on specific stages (e.g. "extracting"/"finalizing"/"error"/"complete"), and having this as a literal union (via an enum or ts-rs type override) would prevent typos and keep frontend progress rendering exhaustive.
pub struct FantomeImportProgress {
pub stage: String,
pub current_wad: Option<String>,
pub current: u32,
pub total: u32,
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| pub layers: Vec<LayerInfo>, | ||
| pub file_count: u64, | ||
| pub total_size: u64, | ||
| } |
There was a problem hiding this comment.
u64 fields exported via ts-rs are being generated as bigint in the TypeScript bindings (see src/lib/bindings/ModpkgInfo.ts), but the IPC payload coming from Tauri/serde_json will be a JSON number at runtime. This creates a TS/runtime mismatch and will either break consumers (TS expects bigint) or encourage unsafe conversions. Consider overriding the TS type for these fields (e.g. #[ts(type = "number")]) or switching to a string-based serialization + TS string if values can exceed Number.MAX_SAFE_INTEGER.
| pub struct GitImportProgress { | ||
| pub stage: String, | ||
| pub message: Option<String>, | ||
| } |
There was a problem hiding this comment.
GitImportProgress.stage is exported as a String, so the generated TS binding becomes stage: string. Since the frontend treats the stage as a closed set ("downloading"/"extracting"/"error"/"complete"), consider using an enum or ts-rs type override to generate a string-literal union and keep progress handling type-safe.
No description provided.