Skip to content

Commit 8ee6869

Browse files
committed
[upgrade] added specta to generate ts binding from rust
1 parent 61d2570 commit 8ee6869

File tree

14 files changed

+274
-106
lines changed

14 files changed

+274
-106
lines changed

src-tauri/Cargo.lock

Lines changed: 133 additions & 37 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-tauri/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ tauri-plugin-single-instance = { git = "https://github.com/tauri-apps/plugins-wo
2727
dotenv = "0.15.0"
2828
lazy_static = "1.4.0"
2929
strum = { version = "0.25.0", features = ["strum_macros"] }
30+
specta = "1.0.5"
31+
tauri-specta = { version = "1.0.2", features = ["javascript", "typescript"] }
3032

3133
[features]
3234
# this feature is used for production builds or when `devPath` points to the filesystem

src-tauri/src/libs.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pub mod response;
22
pub mod auth;
33
pub mod filehelper;
4-
pub mod tauri_actions;
4+
pub mod tauri_actions;
5+
pub mod argument;

src-tauri/src/libs/argument.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
use specta::Type;
2+
use serde::{Deserialize, Serialize};
3+
4+
5+
#[derive(Deserialize, Type)]
6+
pub struct MyCustomArgumentType {
7+
pub foo: String,
8+
pub bar: i32,
9+
}

src-tauri/src/libs/auth.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use borsh::{BorshDeserialize, to_vec};
1010

1111

1212

13-
#[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Debug, serde::Serialize, serde::Deserialize, Clone)]
13+
#[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Debug, serde::Serialize, serde::Deserialize, Clone, specta::Type)]
1414
pub struct AccessToken {
1515
access_token: String,
1616
expires_in: i32,
@@ -64,7 +64,7 @@ impl AccessToken {
6464
pub struct Auth;
6565

6666
impl Auth {
67-
pub fn save_auth_code(code: String) -> String {
67+
pub fn save_auth_code(code: String) -> SaveTokenResponse {
6868
let encoded = to_vec(&code).unwrap();
6969
let password: String = env::var("DB_PASSWORD").unwrap();
7070
let mut cocoon = Cocoon::new(password.as_bytes());
@@ -79,7 +79,7 @@ impl Auth {
7979
success: true,
8080
token: code,
8181
};
82-
serde_json::to_string(&response).expect("JSON serialization error")
82+
return response;
8383
}
8484

8585
pub fn load_auth_code() -> String {
@@ -95,18 +95,15 @@ impl Auth {
9595
};
9696
}
9797

98-
pub fn save_access_token(token: String) -> String {
98+
pub fn save_access_token(token: String) -> SaveAccessTokenResponse {
9999
let content : AccessToken = serde_json::from_str(&token).unwrap();
100100
let response : SaveAccessTokenResponse = content.save();
101-
// Serialize the response object to JSON and return as a string
102-
serde_json::to_string(&response).expect("JSON serialization error")
101+
return response;
103102
}
104103

105-
pub fn load_access_token() -> String {
104+
pub fn load_access_token() -> AccessToken {
106105
let response : AccessToken = AccessToken::load();
107-
println!("response: {:?}", response);
108-
// Serialize the response object to JSON and return as a string
109-
serde_json::to_string(&response).expect("JSON serialization error")
106+
return response;
110107
}
111108
}
112109

src-tauri/src/libs/response.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
1+
use specta::Type;
2+
use serde::{Deserialize, Serialize};
13
use super::auth::AccessToken;
24
// save token response
3-
#[derive(serde::Serialize)]
5+
#[derive(Serialize, Type)]
46
pub struct SaveTokenResponse {
57
pub message: String,
68
pub token: String,
79
pub success: bool,
810
}
911

1012

11-
#[derive(serde::Serialize, serde::Deserialize)]
13+
#[derive(Serialize, Type)]
1214
pub struct SaveAccessTokenResponse {
1315
pub message: String,
1416
pub success: bool,
1517
pub token: AccessToken,
1618
}
19+
20+
21+
#[derive(Serialize, Type)]
22+
pub struct GreetResponse {
23+
pub message: String,
24+
}

src-tauri/src/libs/tauri_actions.rs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,54 +5,52 @@ use tauri;
55
// super mod imports;
66
use super::auth::{AccessToken, Auth};
77
use super::filehelper::{ENV_FILE, ACCESS_TOKEN_FILE};
8+
use super::response::{SaveAccessTokenResponse, SaveTokenResponse, GreetResponse};
89

910

10-
#[derive(serde::Serialize)] // Add this derive to enable JSON serialization
11-
struct GreetResponse {
12-
message: String,
13-
}
14-
1511

1612
#[tauri::command]
13+
#[specta::specta]
1714
pub fn test_command() -> String {
1815
println!("access token path: {}", &*ACCESS_TOKEN_FILE);
1916
println!("ENV_FILE: {}", ENV_FILE);
2017
return env::var("DB_PASSWORD").unwrap();
2118
}
2219

23-
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
2420
#[tauri::command]
25-
pub fn greet(name: String) -> String {
26-
let response = GreetResponse {
21+
#[specta::specta]
22+
pub fn greet(name: String) -> GreetResponse {
23+
return GreetResponse {
2724
message: format!("Hello, {}! You've been greeted from Rust!", name),
2825
};
29-
30-
// Serialize the response object to JSON and return as a string
31-
serde_json::to_string(&response).expect("JSON serialization error")
3226
}
3327

3428
// remember to call `.manage(MyState::default())`
3529
#[tauri::command]
36-
pub fn save_access_token(token: String) -> String {
30+
#[specta::specta]
31+
pub fn save_access_token(token: String) -> SaveAccessTokenResponse {
3732
dotenv::from_filename(ENV_FILE).ok();
3833
return Auth::save_access_token(token);
3934
}
4035

4136
// a command to load the access token from the file
4237
#[tauri::command]
43-
pub fn load_access_token() -> String {
38+
#[specta::specta]
39+
pub fn load_access_token() -> AccessToken {
4440
dotenv::from_filename(ENV_FILE).ok();
4541
return Auth::load_access_token();
4642
}
4743

4844

4945
#[tauri::command]
50-
pub fn save_code(code: String) -> String {
46+
#[specta::specta]
47+
pub fn save_code(code: String) -> SaveTokenResponse {
5148
dotenv::from_filename(ENV_FILE).ok();
5249
return Auth::save_auth_code(code);
5350
}
5451

5552
#[tauri::command]
53+
#[specta::specta]
5654
pub fn load_code() -> String {
5755
dotenv::from_filename(ENV_FILE).ok();
5856
return Auth::load_auth_code();

src-tauri/src/main.rs

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,55 @@
44
mod libs;
55

66
use tauri_plugin_log::{LogTarget};
7+
use specta::collect_types;
8+
use tauri_specta::{ts, js};
9+
10+
711
use libs::tauri_actions::{save_access_token,load_access_token, greet, test_command, save_code, load_code};
812
use libs::filehelper::{ENV_FILE, initialize_user_files};
913

1014

11-
fn main() {
12-
dotenv::from_filename(ENV_FILE).ok();
13-
initialize_user_files();
14-
tauri::Builder::default()
15-
.plugin(tauri_plugin_single_instance::init(|app, argv, cwd| {
16-
println!("{}, {argv:?}, {cwd}", app.package_info().name);
17-
// app.emit_all("single-instance", Payload { args: argv, cwd }).unwrap();
18-
}))
19-
.plugin(tauri_plugin_context_menu::init())
20-
.plugin(tauri_plugin_oauth::init())
21-
.plugin(tauri_plugin_log::Builder::default().targets([
22-
LogTarget::LogDir,
23-
LogTarget::Stdout,
24-
LogTarget::Webview,
25-
]).build())
26-
.invoke_handler(tauri::generate_handler![
15+
fn run_specta() {
16+
17+
println!("Running specta to generate typescript bindings");
18+
19+
#[cfg(debug_assertions)]
20+
ts::export(collect_types![
2721
save_access_token,
2822
load_access_token,
2923
greet,
3024
test_command,
3125
save_code,
3226
load_code,
33-
])
34-
.run(tauri::generate_context!())
35-
.expect("error while running tauri application");
27+
], "../src/helpers/commands.ts").unwrap();
28+
}
29+
30+
fn main() {
31+
dotenv::from_filename(ENV_FILE).ok();
32+
initialize_user_files();
33+
run_specta();
34+
35+
tauri::Builder::default()
36+
.plugin(tauri_plugin_single_instance::init(|app, argv, cwd| {
37+
println!("{}, {argv:?}, {cwd}", app.package_info().name);
38+
// app.emit_all("single-instance", Payload { args: argv, cwd }).unwrap();
39+
}))
40+
.plugin(tauri_plugin_context_menu::init())
41+
.plugin(tauri_plugin_oauth::init())
42+
.plugin(tauri_plugin_log::Builder::default().targets([
43+
LogTarget::LogDir,
44+
LogTarget::Stdout,
45+
LogTarget::Webview,
46+
])
47+
.build())
48+
.invoke_handler(tauri::generate_handler![
49+
save_access_token,
50+
load_access_token,
51+
greet,
52+
test_command,
53+
save_code,
54+
load_code,
55+
])
56+
.run(tauri::generate_context!())
57+
.expect("error while running tauri application");
3658
}

src/App.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useState , useEffect} from "react";
22
import { Box, Button, Spinner, useToast } from '@chakra-ui/react'
33
import { fetchUserProfile,getUserProfileFromStorage, getAccessToken, openAuthWindow, saveAccessToken, saveAuthCode, saveUserProfile, getAccessTokenFromStorage, deleteAccessToken } from "./helpers/auth";
4-
import { AccessToken, UserProfile } from "./types/googleapis";
4+
import { UserProfile } from "./types/googleapis";
55
import { loadContextmenu , pushNotification } from "./helpers/windowhelper";
66
import TaskPage from "./components/TaskPage";
77
import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil";
@@ -10,6 +10,7 @@ import Header from "./components/ui/Header";
1010
import { task } from "./types/taskapi";
1111
import { listen_for_auth_code } from "./helpers/eventlistner";
1212
import { test_command } from "./helpers/invoker";
13+
import { AccessToken } from "./helpers/commands";
1314

1415
// disable default context menu on build
1516
loadContextmenu();
@@ -114,7 +115,7 @@ function App() {
114115
if (!accessToken) throw new Error("Signin required");
115116
pushNotification("Login Successful")
116117
const profile = navigator.onLine ? await fetchUserProfile(accessToken.access_token) : await getUserProfileFromStorage();
117-
if(!profile) throw new Error("Something went wrong, please try again");
118+
if(!profile || !profile?.email) throw new Error("Something went wrong, please try again");
118119
setProfile(profile);
119120
setAccessToken(accessToken.access_token);
120121
pushNotification(`welcome back ${profile.name}`)

src/helpers/auth.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { shell } from "@tauri-apps/api";
22
import axios from "axios";
3-
import { AccessToken, UserProfile } from "../types/googleapis";
3+
import { UserProfile } from "../types/googleapis";
44
import { readTextFile, removeFile, writeTextFile, exists } from "@tauri-apps/api/fs";
55
import { CLIENT_ID, CLIENT_SECRET } from "../config/credentials";
66
import settings from "../config/settings";
77
import { generate_oauth_port, get_access_token, get_auth_code, save_access_token, save_auth_code } from "./invoker";
8+
import { AccessToken } from "./commands";
89

910

1011
const DEFAULT_DIRECTORY = settings.fs.DEFAULT_DIRECTORY;
@@ -159,13 +160,12 @@ export async function getAccessTokenFromStorage() {
159160
try {
160161
// if file does not exist, return null
161162
if(! await exists(STORAGE_PATHS.access_token, { dir: DEFAULT_DIRECTORY })) throw new Error("File does not exist");
162-
const accessTokenText: string = (await get_access_token()) as string;
163+
let accessToken = await get_access_token();
163164
console.log('new access token found')
164-
let accessToken = JSON.parse(accessTokenText) as AccessToken;
165165
// check if the access token is expired
166166
console.log(accessToken, "accessToken");
167167
const lastLogin = parseInt(localStorage.getItem("lastLogin") || "0");
168-
if ((accessToken.expiry_in < Date.now() || Date.now() - lastLogin > 3620) && navigator.onLine){
168+
if ((accessToken.expires_in < Date.now() || Date.now() - lastLogin > 3620) && navigator.onLine){
169169
console.log("Access token expired");
170170
accessToken = await refreshAndSaveAccessToken(accessToken.refresh_token);
171171
}

0 commit comments

Comments
 (0)