Refactor account networking and add WASM support
- Move account-related networking to smbcloud-networking-account - Add smbcloud-networking-account-wasm crate for WASM bindings - Update CLI to use new account networking module - Add me endpoint to smbcloud-networking-account - Update dependencies and workspace members - Expose Environment enum to WASM - Bump smbcloud-networking-account to version 0.3.0
Seto Elkahfi committed
Jul 26, 2025 at 20:15 UTC
7e9456b8af45987c753b2c09f9635e5014ea6541
17 files changed
+128
-62
Cargo.lock
+30
@@ -1196,6 +1196,7 @@ dependencies = [
1196
"serde",
1197
"serde_json",
1198
"smbcloud-model",
1199
+ "wasm-bindgen",
1200
]
1201
1202
[[package]]
@@ -1768,6 +1769,17 @@ dependencies = [
1769
"serde_derive",
1770
]
1771
1772
+[[package]]
1773
+name = "serde-wasm-bindgen"
1774
+version = "0.6.5"
1775
+source = "registry+https://github.com/rust-lang/crates.io-index"
1776
+checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b"
1777
+dependencies = [
1778
+ "js-sys",
1779
+ "serde",
1780
+ "wasm-bindgen",
1781
+]
1782
+
1783
[[package]]
1784
name = "serde_derive"
1785
version = "1.0.219"
@@ -1906,6 +1918,7 @@ dependencies = [
1918
"serde_repr",
1919
"smbcloud-model",
1920
"smbcloud-networking",
1921
+ "smbcloud-networking-account",
1922
"smbcloud-networking-project",
1923
"smbcloud-utils",
1924
"spinners",
@@ -1944,12 +1957,29 @@ dependencies = [
1957
1958
[[package]]
1959
name = "smbcloud-networking-account"
1960
+version = "0.3.0"
1961
+dependencies = [
1962
+ "network",
1963
+ "reqwest",
1964
+ "smbcloud-model",
1965
+ "smbcloud-networking",
1966
+]
1967
+
1968
+[[package]]
1969
+name = "smbcloud-networking-account-wasm"
1970
version = "0.1.0"
1971
dependencies = [
1972
"network",
1973
"reqwest",
1974
+ "serde",
1975
+ "serde-wasm-bindgen",
1976
+ "serde_json",
1977
+ "serde_repr",
1978
"smbcloud-model",
1979
"smbcloud-networking",
1980
+ "thiserror 2.0.12",
1981
+ "wasm-bindgen",
1982
+ "wasm-bindgen-futures",
1983
]
1984
1985
[[package]]
Cargo.toml
+3
@@ -7,6 +7,7 @@ members = [
7
"crates/smbcloud-model",
8
"crates/smbcloud-networking",
9
"crates/smbcloud-networking-account",
10
+ "crates/smbcloud-networking-account-wasm",
11
"crates/smbcloud-networking-project",
12
"crates/smbcloud-utils",
13
]
@@ -34,6 +35,7 @@ serde_repr = "0.1"
35
network = { version = "0.1", path = "crates/network" }
36
smbcloud-model = { version = "0.3", path = "crates/smbcloud-model" }
37
smbcloud-networking = { version = "0.3", path = "crates/smbcloud-networking" }
38
+smbcloud-networking-account = { version = "0.3", path = "crates/smbcloud-networking-account" }
39
smbcloud-networking-project = { version = "0.3", path = "crates/smbcloud-networking-project" }
40
smbcloud-utils = { version = "0.3", path = "crates/smbcloud-utils" }
41
spinners = "4.1.0"
@@ -48,3 +50,4 @@ tracing = "0.1.35"
50
tracing-bunyan-formatter = "0.3.3"
51
tracing-subscriber = "0.3.14"
52
url-builder = "0.1.1"
53
+wasm-bindgen = "0.2"
crates/cli/Cargo.toml
+1
@@ -42,6 +42,7 @@ serde_repr = { workspace = true }
42
network = { workspace = true }
43
smbcloud-model = { workspace = true }
44
smbcloud-networking = { workspace = true }
45
+smbcloud-networking-account = { workspace = true }
46
smbcloud-networking-project = { workspace = true }
47
smbcloud-utils = { workspace = true }
48
spinners = { workspace = true }
crates/cli/src/account/me/mod.rs
+10
-33
@@ -4,11 +4,10 @@ use crate::{
4
cli::CommandResult,
5
ui::{fail_message, fail_symbol, succeed_message, succeed_symbol},
6
};
7
-use anyhow::{anyhow, Result};
7
+use anyhow::Result;
8
use network::environment::Environment;
9
-use reqwest::{Client, StatusCode};
9
use smbcloud_model::account::User;
11
-use smbcloud_networking::{constants::PATH_USERS_ME, smb_base_url_builder};
10
+use smbcloud_networking_account::me::me;
11
use spinners::Spinner;
12
use tabled::{Table, Tabled};
13
@@ -50,7 +49,8 @@ pub async fn process_me(env: Environment) -> Result<CommandResult> {
49
spinners::Spinners::SimpleDotsScrolling,
50
succeed_message("Loading"),
51
);
53
- match me(env).await {
52
+ let token = get_smb_token(env).await?;
53
+ match me(env, &token).await {
54
Ok(user) => {
55
spinner.stop_and_persist(&succeed_symbol(), succeed_message("Loaded."));
56
show_user(&user);
@@ -64,35 +64,12 @@ pub async fn process_me(env: Environment) -> Result<CommandResult> {
64
})
65
}
66
Err(e) => {
67
- spinner.stop_and_persist(&fail_symbol(), fail_message(&e.to_string()));
68
- Err(e)
69
- }
70
- }
71
-}
72
-
73
-pub async fn me(env: Environment) -> Result<User> {
74
- let token = get_smb_token(env).await?;
75
-
76
- let response = Client::new()
77
- .get(build_smb_info_url(env))
78
- .header("Authorization", token)
79
- .header("Accept", "application/json")
80
- .header("Content-Type", "application/x-www-form-urlencoded")
81
- .send()
82
- .await?;
83
-
84
- match response.status() {
85
- StatusCode::OK => {
86
- let user: User = response.json().await?;
87
- Ok(user)
67
+ println!("Error: {e:#?}");
68
+ Ok(CommandResult {
69
+ spinner,
70
+ symbol: fail_symbol(),
71
+ msg: fail_message("Failed to get all projects."),
72
+ })
73
}
89
- StatusCode::UNAUTHORIZED => Err(anyhow!("Invalid token. Please logout first.")),
90
- _ => Err(anyhow!("Error while requesting your information.")),
74
}
75
}
93
-
94
-fn build_smb_info_url(env: Environment) -> String {
95
- let mut url_builder = smb_base_url_builder(env);
96
- url_builder.add_route(PATH_USERS_ME);
97
- url_builder.build()
98
-}
crates/cli/src/deploy/mod.rs
+3
-2
@@ -5,7 +5,7 @@ mod setup;
5
6
use crate::token::get_smb_token;
7
use crate::{
8
- account::{lib::is_logged_in, login::process_login, me::me},
8
+ account::{lib::is_logged_in, login::process_login},
9
cli::CommandResult,
10
deploy::config::check_project,
11
project::runner::detect_runner,
@@ -18,6 +18,7 @@ use git2::{PushOptions, RemoteCallbacks, Repository};
18
use network::environment::Environment;
19
use remote_messages::{build_next_app, start_server};
20
use smbcloud_model::project::{DeploymentPayload, DeploymentStatus};
21
+use smbcloud_networking_account::me::me;
22
use smbcloud_networking_project::{
23
crud_project_deployment_create::create_deployment, crud_project_deployment_update::update,
24
};
@@ -98,7 +99,7 @@ pub async fn process_deploy(env: Environment) -> Result<CommandResult> {
99
100
let created_deployment =
101
create_deployment(env, &access_token, config.project.id, payload).await?;
101
- let user = me(env).await?;
102
+ let user = me(env, &access_token).await?;
103
104
let mut push_opts = PushOptions::new();
105
let mut callbacks = RemoteCallbacks::new();
crates/network/Cargo.toml
+1
@@ -13,3 +13,4 @@ reqwest = { workspace = true, features = ["json"] }
13
serde = { workspace = true, features = ["derive"] }
14
serde_json = { workspace = true }
15
smbcloud-model = { workspace = true }
16
+wasm-bindgen = { workspace = true }
crates/network/src/environment.rs
+3
@@ -1,4 +1,7 @@
1
+use wasm_bindgen::prelude::wasm_bindgen;
2
+
3
#[derive(clap::ValueEnum, Clone, Copy)]
4
+#[wasm_bindgen]
5
pub enum Environment {
6
Dev,
7
Production,
crates/smbcloud-networking-account-wasm/Cargo.toml
new
+20
@@ -0,0 +1,20 @@
1
+[package]
2
+name = "smbcloud-networking-account-wasm"
3
+version = "0.1.0"
4
+edition = "2024"
5
+
6
+[lib]
7
+crate-type = ["cdylib", "rlib"]
8
+
9
+[dependencies]
10
+network = { workspace = true }
11
+smbcloud-networking = { workspace = true }
12
+smbcloud-model = { workspace = true }
13
+reqwest = { workspace = true, features = ["json"] }
14
+wasm-bindgen = { workspace = true }
15
+wasm-bindgen-futures = "0.4.50"
16
+serde = { workspace = true, features = ["derive"] }
17
+serde_json = { workspace = true }
18
+serde_repr = { workspace = true }
19
+thiserror = { workspace = true }
20
+serde-wasm-bindgen = "=0.6.5"
crates/smbcloud-networking-account-wasm/src/lib.rs
new
+2
@@ -0,0 +1,2 @@
1
+pub mod login;
2
+pub(crate) mod url_builder;
crates/smbcloud-networking-account-wasm/src/login.rs
new
+32
@@ -0,0 +1,32 @@
1
+use crate::url_builder::build_smb_login_url;
2
+use network::environment::Environment;
3
+use network::network::request;
4
+use reqwest::Client;
5
+use serde::Serialize;
6
+use smbcloud_model::login::LoginResult;
7
+use smbcloud_networking::constants::SMB_USER_AGENT;
8
+use wasm_bindgen::JsValue;
9
+use wasm_bindgen::prelude::wasm_bindgen;
10
+
11
+#[derive(Debug, Serialize)]
12
+pub struct LoginParams {
13
+ pub username: String,
14
+ pub password: String,
15
+}
16
+
17
+#[wasm_bindgen]
18
+pub async fn login(
19
+ env: Environment,
20
+ username: String,
21
+ password: String,
22
+) -> Result<JsValue, JsValue> {
23
+ let login_params = LoginParams { username, password };
24
+ let builder = Client::new()
25
+ .post(build_smb_login_url(env))
26
+ .json(&login_params)
27
+ .header("User-agent", SMB_USER_AGENT);
28
+ match request::<LoginResult>(builder).await {
29
+ Ok(response) => Ok(serde_wasm_bindgen::to_value(&response)?),
30
+ Err(error) => Err(serde_wasm_bindgen::to_value(&error)?),
31
+ }
32
+}
crates/smbcloud-networking-account-wasm/src/url_builder.rs
renamed
crates/smbcloud-networking-account/.gitignore
new
+1
@@ -0,0 +1 @@
1
+/target
crates/smbcloud-networking-account/Cargo.toml
+1
-4
@@ -1,11 +1,8 @@
1
[package]
2
name = "smbcloud-networking-account"
3
-version = "0.1.0"
3
+version = "0.3.0"
4
edition = "2024"
5
6
-[lib]
7
-crate-type = ["cdylib", "rlib"]
8
-
6
[dependencies]
7
network = { workspace = true }
8
smbcloud-networking = { workspace = true }
crates/smbcloud-networking-account/src/lib.rs
+1
-1
@@ -1,2 +1,2 @@
1
pub mod login;
2
-pub(crate) mod url_builder;
2
+pub mod me;
crates/smbcloud-networking-account/src/login.rs
-19
@@ -1,20 +1 @@
1
-use crate::url_builder::build_smb_login_url;
2
-use network::environment::Environment;
3
-use network::network::request;
4
-use reqwest::Client;
5
-use smbcloud_model::{
6
- error_codes::ErrorResponse,
7
- login::{LoginParams, LoginResult},
8
-};
9
-use smbcloud_networking::constants::SMB_USER_AGENT;
1
11
-pub async fn login(
12
- env: Environment,
13
- login_params: LoginParams,
14
-) -> Result<LoginResult, ErrorResponse> {
15
- let builder = Client::new()
16
- .post(build_smb_login_url(env))
17
- .json(&login_params)
18
- .header("User-agent", SMB_USER_AGENT);
19
- request(builder).await
20
-}
crates/smbcloud-networking-account/src/me.rs
new
+20
@@ -0,0 +1,20 @@
1
+use network::{environment::Environment, network::request};
2
+use reqwest::Client;
3
+use smbcloud_model::account::User;
4
+use smbcloud_model::error_codes::ErrorResponse;
5
+use smbcloud_networking::{constants::PATH_USERS_ME, smb_base_url_builder};
6
+
7
+pub async fn me(env: Environment, access_token: &str) -> Result<User, ErrorResponse> {
8
+ let builder = Client::new()
9
+ .get(build_smb_info_url(env))
10
+ .header("Authorization", access_token)
11
+ .header("Accept", "application/json")
12
+ .header("Content-Type", "application/x-www-form-urlencoded");
13
+ request(builder).await
14
+}
15
+
16
+fn build_smb_info_url(env: Environment) -> String {
17
+ let mut url_builder = smb_base_url_builder(env);
18
+ url_builder.add_route(PATH_USERS_ME);
19
+ url_builder.build()
20
+}
crates/smbcloud-networking-project/Cargo.toml
-3
@@ -17,9 +17,6 @@ categories = [
17
]
18
readme = "README.md"
19
20
-[lib]
21
-crate-type = ["cdylib", "rlib"]
22
-
20
[dependencies]
21
anyhow = { workspace = true }
22
async-trait = { workspace = true, optional = true }