From db95ad11c5ccde20714a725c5f9dd8b2159ad96c Mon Sep 17 00:00:00 2001 From: Louis Knight-Webb Date: Sat, 14 Jun 2025 17:49:17 -0400 Subject: [PATCH] Use date types --- AGENT.md | 2 + backend/src/bin/generate_types.rs | 70 +++++++++++++++++++++++-------- backend/src/models/project.rs | 2 + backend/src/models/user.rs | 2 + shared/README.md | 27 ------------ shared/types.ts | 18 ++++---- 6 files changed, 68 insertions(+), 53 deletions(-) delete mode 100644 shared/README.md diff --git a/AGENT.md b/AGENT.md index 7e88151d..c8682f6b 100644 --- a/AGENT.md +++ b/AGENT.md @@ -58,3 +58,5 @@ bloop/ # Managing Shared Types Between Rust and TypeScript ts-rs allows you to derive TypeScript types from Rust structs/enums. By annotating your Rust types with #[derive(TS)] and related macros, ts-rs will generate .ts declaration files for those types. +When making changes to the types, you can regenerate them using `npm run generate-types` +Do not manually edit shared/types.ts diff --git a/backend/src/bin/generate_types.rs b/backend/src/bin/generate_types.rs index 584b60da..8b4dcea9 100644 --- a/backend/src/bin/generate_types.rs +++ b/backend/src/bin/generate_types.rs @@ -4,31 +4,67 @@ use ts_rs::TS; // Import all the types we want to export using the library crate use bloop_backend::models::{ - ApiResponse, Project, CreateProject, UpdateProject, - CreateUser, UpdateUser, LoginRequest, LoginResponse, UserResponse, + ApiResponse, CreateProject, CreateUser, LoginRequest, LoginResponse, Project, UpdateProject, + UpdateUser, UserResponse, }; fn main() { let shared_path = Path::new("../shared"); - + // Create the shared directory if it doesn't exist std::fs::create_dir_all(shared_path).unwrap(); - + println!("Generating TypeScript types..."); - + // Set environment variable to configure ts-rs output directory env::set_var("TS_RS_EXPORT_DIR", shared_path.to_str().unwrap()); - - // Export TypeScript types for each struct using ts-rs export functionality - bloop_backend::models::ApiResponse::<()>::export().unwrap(); - bloop_backend::models::Project::export().unwrap(); - bloop_backend::models::CreateProject::export().unwrap(); - bloop_backend::models::UpdateProject::export().unwrap(); - bloop_backend::models::CreateUser::export().unwrap(); - bloop_backend::models::UpdateUser::export().unwrap(); - bloop_backend::models::LoginRequest::export().unwrap(); - bloop_backend::models::LoginResponse::export().unwrap(); - bloop_backend::models::UserResponse::export().unwrap(); - + + // // Export TypeScript types for each struct using ts-rs export functionality + // bloop_backend::models::ApiResponse::<()>::export().unwrap(); + // bloop_backend::models::Project::export().unwrap(); + // bloop_backend::models::CreateProject::export().unwrap(); + // bloop_backend::models::UpdateProject::export().unwrap(); + // bloop_backend::models::CreateUser::export().unwrap(); + // bloop_backend::models::UpdateUser::export().unwrap(); + // bloop_backend::models::LoginRequest::export().unwrap(); + // bloop_backend::models::LoginResponse::export().unwrap(); + // bloop_backend::models::UserResponse::export().unwrap(); + + // Generate consolidated types.ts file + let consolidated_content = format!( + r#"// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +// Auto-generated from Rust backend types using ts-rs + +{} + +{} + +{} + +{} + +{} + +{} + +{} + +{} + +{} +"#, + bloop_backend::models::ApiResponse::<()>::decl(), + bloop_backend::models::CreateProject::decl(), + bloop_backend::models::CreateUser::decl(), + bloop_backend::models::LoginRequest::decl(), + bloop_backend::models::LoginResponse::decl(), + bloop_backend::models::Project::decl(), + bloop_backend::models::UpdateProject::decl(), + bloop_backend::models::UpdateUser::decl(), + bloop_backend::models::UserResponse::decl(), + ); + + std::fs::write(shared_path.join("types.ts"), consolidated_content).unwrap(); + println!("TypeScript types generated successfully in ../shared/"); } diff --git a/backend/src/models/project.rs b/backend/src/models/project.rs index e6bbf7e0..a6f2e66a 100644 --- a/backend/src/models/project.rs +++ b/backend/src/models/project.rs @@ -10,7 +10,9 @@ pub struct Project { pub id: Uuid, pub name: String, pub owner_id: Uuid, // Foreign key to User + #[ts(type = "Date")] pub created_at: DateTime, + #[ts(type = "Date")] pub updated_at: DateTime, } diff --git a/backend/src/models/user.rs b/backend/src/models/user.rs index d70268fa..f18959a3 100644 --- a/backend/src/models/user.rs +++ b/backend/src/models/user.rs @@ -52,7 +52,9 @@ pub struct UserResponse { pub id: Uuid, pub email: String, pub is_admin: bool, + #[ts(type = "Date")] pub created_at: DateTime, + #[ts(type = "Date")] pub updated_at: DateTime, } diff --git a/shared/README.md b/shared/README.md deleted file mode 100644 index e002d13b..00000000 --- a/shared/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Shared Types - -This directory contains shared types and schemas that are used by both the frontend and backend. - -## Usage - -### Frontend -```typescript -import { ApiResponse } from '../shared/types' -``` - -### Backend -Consider using `ts-rs` to generate TypeScript types from Rust structs: - -```rust -use ts_rs::TS; - -#[derive(Serialize, TS)] -#[ts(export)] -pub struct ApiResponse { - pub success: bool, - pub data: Option, - pub message: Option, -} -``` - -This will generate TypeScript definitions that stay in sync with your Rust types. diff --git a/shared/types.ts b/shared/types.ts index b6c63313..cc50c5a7 100644 --- a/shared/types.ts +++ b/shared/types.ts @@ -1,20 +1,20 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. // Auto-generated from Rust backend types using ts-rs -export type ApiResponse = { success: boolean, data: T | null, message: string | null, }; +type ApiResponse = { success: boolean, data: T | null, message: string | null, }; -export type CreateProject = { name: string, }; +type CreateProject = { name: string, }; -export type CreateUser = { email: string, password: string, is_admin: boolean | null, }; +type CreateUser = { email: string, password: string, is_admin: boolean | null, }; -export type LoginRequest = { email: string, password: string, }; +type LoginRequest = { email: string, password: string, }; -export type LoginResponse = { user: User, token: string, }; +type LoginResponse = { user: User, token: string, }; -export type Project = { id: string, name: string, owner_id: string, created_at: string, updated_at: string, }; +type Project = { id: string, name: string, owner_id: string, created_at: Date, updated_at: Date, }; -export type UpdateProject = { name: string | null, }; +type UpdateProject = { name: string | null, }; -export type UpdateUser = { email: string | null, password: string | null, is_admin: boolean | null, }; +type UpdateUser = { email: string | null, password: string | null, is_admin: boolean | null, }; -export type User = { id: string, email: string, is_admin: boolean, created_at: string, updated_at: string, }; +type User = { id: string, email: string, is_admin: boolean, created_at: Date, updated_at: Date, };