Export Rust core types to TypeScript with ts-rs and update CI#77
Export Rust core types to TypeScript with ts-rs and update CI#77HsiangNianian wants to merge 41 commits intomainfrom
Conversation
…ndency installation
Reviewer's GuideAdds TypeScript type generation for Tauri backend structs/enums using ts-rs, updates CI to build on additional targets (musl & Windows GNU) with cross support, switches the Microsoft auth client ID, and tweaks a few serialization details for TS/serde interoperability. Class diagram for auth and account TypeScript-backed modelsclassDiagram
class Account {
}
<<enumeration>> Account
Account : Offline(OfflineAccount)
Account : Microsoft(MicrosoftAccount)
class OfflineAccount {
String username
String uuid
}
class MicrosoftAccount {
String username
String uuid
String access_token
String refresh_token
u64 expires_at
}
class DeviceCodeResponse {
String user_code
String device_code
String verification_uri
u64 expires_in
u64 interval
Option~String~ message
}
class TokenResponse {
String access_token
Option~String~ refresh_token
Option~u64~ expires_in
String token_type
Option~String~ scope
}
class MinecraftAuthResponse {
String username
String access_token
String token_type
u64 expires_in
}
class MinecraftProfile {
String id
String name
}
Account *-- OfflineAccount
Account *-- MicrosoftAccount
Class diagram for download and Java management models exported to TypeScriptclassDiagram
class DownloadTask {
String url
PathBuf path
u64 total_size
bool resumable
u32 segments
}
class DownloadMetadata {
String url
String file_name
u64 total_size
u64 downloaded
u32 segments
bool resumable
}
class DownloadSegment {
u64 start
u64 end
u64 downloaded
u32 index
}
class JavaDownloadProgress {
String file_name
u64 downloaded_bytes
u64 total_bytes
f32 progress
bool done
}
class PendingJavaDownload {
u32 major_version
String image_type
String jvm_impl
String os
String arch
}
class DownloadQueue {
Vec~PendingJavaDownload~ pending_downloads
}
class ProgressEvent {
String file
u64 downloaded
u64 total
f32 progress
bool done
}
class JavaInstallation {
String path
String version
String vendor
String image_type
}
class ImageType {
}
<<enumeration>> ImageType
ImageType : Jre
ImageType : Jdk
class JavaReleaseInfo {
u32 major_version
String image_type
String jvm_impl
String os
String arch
String version
String release_name
String download_url
String checksum
u64 size
bool lts
}
class JavaCatalog {
Vec~JavaReleaseInfo~ releases
Vec~u32~ available_major_versions
Vec~String~ available_image_types
Vec~String~ available_jvm_impls
}
class JavaDownloadInfo {
String version
String release_name
String download_url
String checksum
u64 size
}
DownloadQueue *-- PendingJavaDownload
JavaCatalog *-- JavaReleaseInfo
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
@SourceryAI title |
Workspace change through: c46d6c52 changesets found Planned changes to release
|
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- The
ts_rsusage is very repetitive, especially the longexport_topaths; consider centralizing the base output directory (e.g., via a macro, helper attribute, or build script) so new types and path changes are less error‑prone. - Several fields containing arbitrary JSON are exported as
Record<string, unknown>(e.g.,natives,features,classifiers,Argumentsfields); if the frontend relies on particular keys or shapes, it may be worth tightening these TypeScript types to catch UI-side misuse earlier.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The `ts_rs` usage is very repetitive, especially the long `export_to` paths; consider centralizing the base output directory (e.g., via a macro, helper attribute, or build script) so new types and path changes are less error‑prone.
- Several fields containing arbitrary JSON are exported as `Record<string, unknown>` (e.g., `natives`, `features`, `classifiers`, `Arguments` fields); if the frontend relies on particular keys or shapes, it may be worth tightening these TypeScript types to catch UI-side misuse earlier.
## Individual Comments
### Comment 1
<location> `src-tauri/src/core/game_version.rs:6-13` </location>
<code_context>
/// Represents a Fabric loader version from the Meta API.
-#[derive(Debug, Deserialize, Serialize, Clone)]
+#[derive(Debug, Deserialize, Serialize, Clone, TS)]
+#[ts(
+ export,
</code_context>
<issue_to_address>
**issue (bug_risk):** Serde-renamed fields (e.g. `majorVersion`) will be mismatched in generated TS without `ts` renames or `serde-compat`.
For types like `JavaVersion`, `serde(rename = "majorVersion")` changes the JSON field, but `ts-rs` will still emit `major_version` unless configured otherwise. This makes the generated TS types disagree with the actual API. Please either:
1) Enable `ts-rs`’s `serde-compat` feature so serde renames are mirrored automatically, or
2) Add `#[ts(rename = "majorVersion")]` (and similar `ts` renames wherever `serde(rename = ...)` is used).
Otherwise the frontend will receive `majorVersion` while the TS types expect `major_version`.
</issue_to_address>
### Comment 2
<location> `src-tauri/src/main.rs:1753-1760` </location>
<code_context>
/// Version metadata for display in the UI
-#[derive(serde::Serialize)]
+#[derive(serde::Serialize, TS)]
+#[ts(
+ export,
+ export_to = "../../packages/ui/src/types/generated/VersionMetadata.ts"
+)]
struct VersionMetadata {
id: String,
#[serde(rename = "javaVersion")]
</code_context>
<issue_to_address>
**issue (bug_risk):** Generated TS for `VersionMetadata`/`InstalledVersion` fields won’t respect serde `rename`, causing type/JSON divergence.
In `VersionMetadata` and `InstalledVersion`, fields using `#[serde(rename = ...)]` (e.g. `javaVersion`, `type`) will still be emitted by `ts-rs` as `java_version`/`r#type` unless configured. That means the generated TS types won’t match the actual JSON shape the frontend receives.
Please either enable `ts-rs`’s `serde-compat` feature globally, or add explicit `#[ts(rename = "...")]` on the renamed fields so the TS definitions align with the serialized JSON.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Pull request overview
This pull request adds TypeScript type generation from Rust backend types using the ts-rs library. The changes enable automatic generation of TypeScript definitions for all data structures used in communication between the Rust backend and the frontend UI, ensuring type safety across the Rust-TypeScript boundary.
Changes:
- Added ts-rs 11.1.0 dependency to Cargo.toml
- Annotated 40+ core Rust structs and enums with
#[derive(TS)]and export metadata - Configured TypeScript output paths to
packages/ui/src/types/generated/ - Added proper type overrides for complex types (PathBuf → string, serde_json::Value → Record<string, unknown>)
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src-tauri/Cargo.toml | Added ts-rs dependency for TypeScript type generation |
| src-tauri/src/main.rs | Added TS import and annotations for UI-facing types (VersionMetadata, InstalledVersion, GithubRelease, PastebinResponse, MigrationResult, FileInfo) |
| src-tauri/src/core/auth.rs | Annotated authentication types with TS exports including tagged Account enum; includes unrelated CLIENT_ID change |
| src-tauri/src/core/config.rs | Exported configuration types (LauncherConfig, AssistantConfig, FeatureFlags) |
| src-tauri/src/core/downloader.rs | Exported download-related types with progress tracking structures |
| src-tauri/src/core/fabric.rs | Exported Fabric loader types including loader versions, libraries, and main class enum |
| src-tauri/src/core/forge.rs | Exported Forge types with proper PathBuf→string type override |
| src-tauri/src/core/game_version.rs | Exported comprehensive game version types with Record<string, unknown> overrides for serde_json::Value fields |
| src-tauri/src/core/instance.rs | Exported instance/profile configuration types |
| src-tauri/src/core/java.rs | Exported Java installation and catalog types with ImageType enum |
| src-tauri/src/core/manifest.rs | Exported Mojang version manifest types |
| src-tauri/src/core/assistant.rs | Exported AI assistant message and model types |
- Centralize strip_unc_prefix into java/mod.rs to eliminate duplication across detection.rs and validation.rs - Remove unused JAVA_CHECK_TIMEOUT constant from validation.rs - Implement actual timeout mechanism in run_which_command_with_timeout() using try_wait() loop - Parallelize Adoptium API requests for better catalog fetch performance Fixes: - Multiple strip_unc_prefix implementations consolidated - Timeout constant now properly enforced in which/where command execution - Catalog fetching now uses concurrent tokio::spawn tasks instead of sequential await Reviewed-by: Claude Sonnet 4.5
- Add #[allow(dead_code)] attributes to utility functions - Improve 64-bit detection with case-insensitive check - Support aarch64 architecture in bitness detection - Add TODO for future vendor expansion Reviewed-by: Claude Sonnet 4.5
Replace potentially panicking unwrap() call with expect() that includes a descriptive error message to aid debugging if the edge case occurs. Reviewed-by: Claude Sonnet 4.5
…r handling - Extract version compatibility check into shared validation function - Remove duplicated version checking code across multiple modules - Simplify Java detection timeout logic in detection.rs - Expand vendor detection to support more JDK distributions (Dragonwell, Kona, Semeru, BiSheng, etc.) - Refactor start_game to use priority-based Java resolution - Improve error handling in Adoptium provider task collection Reviewed-by: Claude Sonnet 4.5
- Added support for detecting Java installations from SDKMAN! in `find_sdkman_java`. - Improved `run_which_command_with_timeout` to handle command timeouts gracefully. - Introduced a unified `JavaError` enum for consistent error handling across Java operations. - Updated functions to return `Result` types instead of `Option` for better error reporting. - Enhanced `load_cached_catalog` and `save_catalog_cache` to use `JavaError`. - Refactored `fetch_java_catalog`, `fetch_java_release`, and `fetch_available_versions` to return `JavaError`. - Improved validation functions to return detailed errors when checking Java installations. - Added tests for version parsing and compatibility checks. - Updated `resolve_java_for_launch` to handle instance-specific and global Java paths.
…eanup - Add CACHE_VERSION constant for cache format compatibility tracking - Add MAX_CACHE_SIZE_BYTES limit (10 MB) to prevent unbounded cache growth - Add cache_version field to JavaCatalog struct with default value - Implement cache version validation in load_cached_catalog() - Implement cache size enforcement in save_catalog_cache() - Add cleanup_expired_caches() for background cache cleanup - Add enforce_cache_size_limit() to validate cache file sizes - Add is_cache_version_compatible() helper function - Automatically clean up expired caches on load and clear operations - Validate cache version before using cached data Fixes: - Cache expiration without automatic cleanup (now cleaned on load) - Missing cache version control (now validates format compatibility) - Unbounded cache size growth (now limited to 10 MB) Reviewed-by: Claude 3.5 Sonnet
- Extract JavaError to dedicated error.rs module - Add serde defaults for JavaInstallation optional fields - Replace unwrap() with proper error propagation - Add detailed logging for Java resolution priority chain - Improve error mapping in validation (NotFound vs VerificationFailed) Reviewed-by: Claude Sonnet 4.5
- Export JavaError from java module - Fix type mismatches in Adoptium provider methods - Add type annotations for reqwest json() calls - Remove non-existent cache_version field from JavaCatalog - Fix resolve_java_for_launch call signature (remove extra window param) - Add error conversion to String for Tauri commands - Fix import for save_catalog_cache in adoptium.rs Reviewed-by: Claude Sonnet 4.5
Integrate Java runtime refactoring changes: - Modular Java detection and management system - Adoptium Java provider with automatic download - Instance-level Java path overrides - Priority-based Java resolution - Enhanced error handling with JavaError type - Cache management with versioning This merge combines the ts-rs TypeScript bindings work from PR HydroRoll-Team#77 with the comprehensive Java runtime improvements from PR HydroRoll-Team#82.
…ogic - Add scan_java_dir() helper to filter symlinks and scan directories - Implement find_mise_java() for ~/.local/share/mise/installs/java/ - Refactor find_sdkman_java() to scan candidates dir instead of 'current' - Fix import paths to use absolute crate::core::java:: paths - Add mise detection to Linux and macOS candidates Reviewed-by: Claude Sonnet 4.5
- Regenerate ts-rs bindings with single-line type definitions - Add new bindings: account_storage.ts, java module types - Update all existing binding files to compact format - Add generated types for old UI package Reviewed-by: Claude Sonnet 4.5
…matting" This reverts commit c075dd8.
) # 描述 此 PR 为 Java 检测模块添加了 mise 版本管理器支持,并重构了 SDKMAN 检测逻辑,使其更加健壮。同时更新了 TypeScript 类型绑定的格式。 ## 更改类型 - [ ] Bug 修复(修复问题的非破坏性更改) - [x] 新功能(添加功能的非破坏性更改) - [ ] 破坏性更改(会导致现有功能无法正常工作的修复或功能) - [ ] 文档更新 - [ ] UI/UX 改进 - [ ] 性能优化 - [x] 代码重构(无功能性更改) - [ ] 配置更改 - [ ] 测试添加或更新 ## LLM 生成代码声明 - [x] 此 PR 包含 LLM 生成的代码,我**提供**质量担保 - [ ] 此 PR 包含 LLM 生成的代码,我**不提供**质量担保 - [ ] 此 PR 不包含 LLM 生成的代码 **模型**: Claude Sonnet 4.5 ## 相关 Issue 相关 #(如有) ## 更改内容 ### 后端 (Rust) #### Java 检测模块重构 1. **新增 mise 版本管理器支持** - 添加 `find_mise_java()` 函数扫描 `~/.local/share/mise/installs/java/` - 在 Linux 和 macOS 平台的候选列表中集成 mise 检测 2. **重构 SDKMAN 检测逻辑** - 将 `find_sdkman_java()` 从检查 `current` 符号链接改为扫描整个 candidates 目录 - 避免符号链接导致的重复检测问题 3. **添加通用扫描辅助函数** - 实现 `scan_java_dir<F>()` 泛型函数,支持自定义过滤条件 - 自动过滤符号链接,只返回真实的目录安装 - 为 mise 和 SDKMAN 提供统一的扫描逻辑 4. **修复模块导入路径** - 将相对导入 `super::` 改为绝对导入 `crate::core::java::` - 提高代码可维护性和清晰度 5. **改进文档注释** - 为新函数添加详细的 Rustdoc 注释 - 说明参数、返回值和功能 ### 前端 (React) - 无前端更改 ### 配置 - 重新生成 TypeScript 类型绑定(ts-rs),采用更紧凑的单行格式 - 新增类型:`account_storage.ts`、`java/*` 模块类型 - 更新所有现有绑定文件的格式 ## 测试 ### 测试环境 - **操作系统**:Windows 11 - **DropOut 版本**:0.1.24 - **测试的 Minecraft 版本**:N/A(Java 检测功能) - **Mod 加载器**:N/A ### 测试用例 - [x] 已在 Windows 上测试(编译通过) - [ ] 已在 macOS 上测试 - [ ] 已在 Linux 上测试 - [ ] 已测试原版 Minecraft - [ ] 已测试 Fabric - [ ] 已测试 Forge - [ ] 已测试游戏启动 - [ ] 已测试登录流程 - [x] 已测试 Java 检测/下载 ### 测试步骤 1. 运行 `cargo tauri dev` 确保编译通过 2. 运行 `cargo check` 和 `cargo clippy` 确保无警告 3. Pre-commit hooks 全部通过(fmt, check, clippy) **注意**:此 PR 主要是代码重构和新增功能,建议在具有 mise/SDKMAN 环境的 Linux/macOS 系统上进行实际功能测试。 ## 检查清单 ### 代码质量 - [x] 我的代码遵循项目的代码风格指南 - [x] 我已对自己的代码进行了自审 - [x] 我已对难以理解的区域添加了注释 - [x] 我的更改没有产生新的警告或错误 ### 测试验证 - [x] 我已在本地测试了我的更改 - [ ] 我已添加测试来证明我的修复有效或功能正常工作 - [ ] 新的和现有的单元测试在本地通过 - [x] 我至少在一个目标平台上进行了测试(Windows 编译测试) ### 文档更新 - [x] 我已相应地更新了文档(代码注释) - [ ] 如有需要,我已更新 README - [x] 我已在必要处添加/更新代码注释 ### 依赖项 - [x] 我已检查没有添加不必要的依赖项 - [x] 所有新依赖项都已正确记录 - [x] `Cargo.lock` 和/或 `pnpm-lock.yaml` 已更新(如果依赖项有变化) ## 截图 / 视频 N/A(后端功能,无 UI 变更) ## 附加说明 ### 技术细节 **为什么添加 mise 支持?** mise (前身 rtx) 是一个现代的版本管理工具,越来越多的开发者使用它来管理 Java 等运行时。添加此支持可以提高启动器的兼容性。 **符号链接过滤的重要性** 版本管理器(mise/SDKMAN)通常会创建符号链接作为版本别名(如 `21`、`lts`、`current`),过滤这些链接可以: - 避免重复检测同一个 Java 安装 - 减少检测开销 - 提供更清晰的检测结果 **代码重构的影响** - 导入路径的更改不影响功能,仅提高代码组织性 - TypeScript 绑定的格式更改由 ts-rs 自动生成,不影响类型定义的正确性 ### 后续工作建议 - 在 CI 中添加 Linux/macOS 环境的 Java 检测集成测试 - 考虑为其他版本管理器(如 jenv、jabba)添加支持 - 优化检测性能(可能需要并行扫描或缓存机制) ## 破坏性更改说明 无破坏性更改。此 PR 完全向后兼容。 --- **维护者专用:** - [ ] 代码审查已完成 - [ ] CI 检查通过 - [ ] 准备合并 --- **提交记录:** - 50de089 feat(java): add mise version manager support and refactor detection logic - c075dd8 chore(types): regenerate typescript bindings with compact formatting **Reviewed-by**: Claude Sonnet 4.5
Summary by Sourcery
Export backend data structures to TypeScript for the new React-based UI and update CI to build additional targets.
New Features:
Enhancements:
Build:
CI: