20 files changed
+1048
-140
Cargo.lock
+58
-9
@@ -40,19 +40,30 @@ checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800"
40
41
[[package]]
42
name = "app-fun"
43
-version = "0.1.0"
43
+version = "0.3.2"
44
dependencies = [
45
"anyhow",
46
+ "async-trait",
47
"clap",
48
"console",
49
"dialoguer",
50
+ "dirs",
51
+ "home",
52
+ "log",
53
+ "maybe-async",
54
+ "reqwest",
55
+ "serde",
56
+ "serde_json",
57
"smbpndk-model",
58
+ "smbpndk-networking",
59
+ "smbpndk-utils",
60
"spinners",
61
+ "thiserror",
62
]
63
64
[[package]]
65
name = "app-oten"
55
-version = "0.1.0"
66
+version = "0.3.2"
67
dependencies = [
68
"anyhow",
69
"async-trait",
@@ -75,11 +86,49 @@ dependencies = [
86
87
[[package]]
88
name = "app-pkt"
78
-version = "0.1.0"
89
+version = "0.3.2"
90
+dependencies = [
91
+ "anyhow",
92
+ "async-trait",
93
+ "clap",
94
+ "console",
95
+ "dialoguer",
96
+ "dirs",
97
+ "home",
98
+ "log",
99
+ "maybe-async",
100
+ "reqwest",
101
+ "serde",
102
+ "serde_json",
103
+ "smbpndk-model",
104
+ "smbpndk-networking",
105
+ "smbpndk-utils",
106
+ "spinners",
107
+ "thiserror",
108
+]
109
110
[[package]]
111
name = "app-rdb"
82
-version = "0.1.0"
112
+version = "0.3.2"
113
+dependencies = [
114
+ "anyhow",
115
+ "async-trait",
116
+ "clap",
117
+ "console",
118
+ "dialoguer",
119
+ "dirs",
120
+ "home",
121
+ "log",
122
+ "maybe-async",
123
+ "reqwest",
124
+ "serde",
125
+ "serde_json",
126
+ "smbpndk-model",
127
+ "smbpndk-networking",
128
+ "smbpndk-utils",
129
+ "spinners",
130
+ "thiserror",
131
+]
132
133
[[package]]
134
name = "async-trait"
@@ -1265,7 +1314,7 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
1314
1315
[[package]]
1316
name = "smbpndk-cli"
1268
-version = "0.2.2"
1317
+version = "0.3.2"
1318
dependencies = [
1319
"anyhow",
1320
"app-fun",
@@ -1300,7 +1349,7 @@ dependencies = [
1349
1350
[[package]]
1351
name = "smbpndk-model"
1303
-version = "0.1.0"
1352
+version = "0.3.2"
1353
dependencies = [
1354
"chrono",
1355
"serde",
@@ -1310,7 +1359,7 @@ dependencies = [
1359
1360
[[package]]
1361
name = "smbpndk-networking"
1313
-version = "0.1.0"
1362
+version = "0.3.2"
1363
dependencies = [
1364
"anyhow",
1365
"async-trait",
@@ -1327,7 +1376,7 @@ dependencies = [
1376
1377
[[package]]
1378
name = "smbpndk-networking-project"
1330
-version = "0.1.0"
1379
+version = "0.3.2"
1380
dependencies = [
1381
"anyhow",
1382
"async-trait",
@@ -1345,7 +1394,7 @@ dependencies = [
1394
1395
[[package]]
1396
name = "smbpndk-utils"
1348
-version = "0.1.0"
1397
+version = "0.3.2"
1398
dependencies = [
1399
"anyhow",
1400
"dirs",
app-fun/Cargo.toml
+12
-1
@@ -13,8 +13,19 @@ readme = "../README.md"
13
14
[dependencies]
15
anyhow = "1.0.58"
16
+async-trait = { version = "0.1.51", optional = true }
17
clap = { version = "4.1.6", features = ["derive"] }
18
console = "0.15.0"
19
dialoguer = "0.10.4"
19
-smbpndk-model = { path = "../smbpndk-model" }
20
+dirs = "4.0.0"
21
+home = "0.5.4"
22
+log = "0.4.14"
23
+maybe-async = { version = "0.2", features = ["is_sync"] }
24
+reqwest = { version = "0.11", features = ["json"] }
25
+serde = { version = "1", features = ["derive"] }
26
+serde_json = "1.0.82"
27
+smbpndk-model = { version = "0.3", path = "../smbpndk-model" }
28
+smbpndk-networking = { version = "0.3", path = "../smbpndk-networking" }
29
+smbpndk-utils = { version = "0.3", path = "../smbpndk-utils" }
30
spinners = "4.1.0"
31
+thiserror = "1.0.29"
app-fun/src/handler.rs
+143
-41
@@ -1,74 +1,176 @@
1
-use crate::cli::Commands;
2
-use anyhow::Result;
1
+use crate::{cli::Commands, create_fun_app, delete_fun_app, get_fun_app, get_fun_apps};
2
+use anyhow::{anyhow, Result};
3
use console::style;
4
-use smbpndk_model::CommandResult;
4
+use dialoguer::{theme::ColorfulTheme, Confirm, Input};
5
+use smbpndk_model::{AppCreate, CommandResult};
6
+use smbpndk_utils::{get_config, write_config};
7
use spinners::Spinner;
8
9
pub async fn process_fun_app(commands: Commands) -> Result<CommandResult> {
10
match commands {
11
Commands::New {} => {
12
+ let app_name = Input::<String>::with_theme(&ColorfulTheme::default())
13
+ .with_prompt("App name")
14
+ .interact()
15
+ .unwrap();
16
+ let description = Input::<String>::with_theme(&ColorfulTheme::default())
17
+ .with_prompt("Description")
18
+ .interact()
19
+ .unwrap();
20
+
21
let spinner = Spinner::new(
22
spinners::Spinners::SimpleDotsScrolling,
12
- style("Creating a Fun app...").green().bold().to_string(),
23
+ style("Creating an fun app...").green().bold().to_string(),
24
);
14
- Ok(CommandResult {
15
- spinner,
16
- symbol: "".to_owned(),
17
- msg: "".to_owned(),
25
+
26
+ match create_fun_app(AppCreate {
27
+ name: app_name.clone(),
28
+ description: description.clone(),
29
})
30
+ .await
31
+ {
32
+ Ok(_) => Ok(CommandResult {
33
+ spinner,
34
+ symbol: "✅".to_owned(),
35
+ msg: format!("An fun app created: {app_name}."),
36
+ }),
37
+ Err(e) => {
38
+ println!("Error: {e:#?}");
39
+ Ok(CommandResult {
40
+ spinner,
41
+ symbol: "😩".to_owned(),
42
+ msg: format!("Failed to create an fun app: {app_name}."),
43
+ })
44
+ }
45
+ }
46
}
47
Commands::List {} => {
48
let spinner = Spinner::new(
49
spinners::Spinners::SimpleDotsScrolling,
23
- style("Listing Fun apps...").green().bold().to_string(),
50
+ style("Loading...").green().bold().to_string(),
51
);
25
- Ok(CommandResult {
26
- spinner,
27
- symbol: "".to_owned(),
28
- msg: "".to_owned(),
29
- })
52
+ match get_fun_apps().await {
53
+ Ok(fun_apps) => {
54
+ println!("fun_apps: {fun_apps:#?}");
55
+ println!(
56
+ "{0: <10} | {1: <30} | {2: <10} | {3: <10}",
57
+ "ID", "Name", "Created at", "Updated at"
58
+ );
59
+ for project in fun_apps {
60
+ let id = project.id.split('-').collect::<Vec<&str>>()[0].to_owned();
61
+ let created_at = project.created_at.date_naive();
62
+ let updated_at = project.updated_at.date_naive();
63
+ println!(
64
+ "{0: <10} | {1: <30} | {2: <10} | {3: <10}",
65
+ id, project.name, created_at, updated_at
66
+ );
67
+ }
68
+ Ok(CommandResult {
69
+ spinner,
70
+ symbol: "✅".to_owned(),
71
+ msg: "Showing all fun apps.".to_owned(),
72
+ })
73
+ }
74
+ Err(e) => {
75
+ println!("Error: {e:#?}");
76
+ Ok(CommandResult {
77
+ spinner,
78
+ symbol: "😩".to_owned(),
79
+ msg: "Failed to get all fun apps.".to_owned(),
80
+ })
81
+ }
82
+ }
83
}
84
Commands::Show { id } => {
85
let spinner = Spinner::new(
86
spinners::Spinners::SimpleDotsScrolling,
34
- style(format!("Showing Fun app {id}..."))
35
- .green()
36
- .bold()
37
- .to_string(),
87
+ style("Loading...").green().bold().to_string(),
88
);
39
- Ok(CommandResult {
40
- spinner,
41
- symbol: "".to_owned(),
42
- msg: "".to_owned(),
43
- })
89
+ match get_fun_app(&id).await {
90
+ Ok(_) => Ok(CommandResult {
91
+ spinner,
92
+ symbol: "✅".to_owned(),
93
+ msg: "Showing fun app.".to_owned(),
94
+ }),
95
+ Err(e) => {
96
+ println!("Error: {e:#?}");
97
+ Ok(CommandResult {
98
+ spinner,
99
+ symbol: "😩".to_owned(),
100
+ msg: "Failed to get an fun app.".to_owned(),
101
+ })
102
+ }
103
+ }
104
}
105
Commands::Delete { id } => {
106
let spinner = Spinner::new(
107
spinners::Spinners::SimpleDotsScrolling,
48
- style(format!("Deleting Fun app {id}..."))
49
- .green()
50
- .bold()
51
- .to_string(),
108
+ style("Loading...").green().bold().to_string(),
109
);
53
- Ok(CommandResult {
54
- spinner,
55
- symbol: "".to_owned(),
56
- msg: "".to_owned(),
57
- })
110
+ match delete_fun_app(id).await {
111
+ Ok(_) => Ok(CommandResult {
112
+ spinner,
113
+ symbol: "✅".to_owned(),
114
+ msg: "Delete fun app succeed.".to_owned(),
115
+ }),
116
+ Err(e) => {
117
+ println!("Error: {e:#?}");
118
+ Ok(CommandResult {
119
+ spinner,
120
+ symbol: "😩".to_owned(),
121
+ msg: "Failed to delete fun app.".to_owned(),
122
+ })
123
+ }
124
+ }
125
}
126
Commands::Use { id } => {
127
+ let mut spinner = Spinner::new(
128
+ spinners::Spinners::SimpleDotsScrolling,
129
+ style("Checking config file...").green().bold().to_string(),
130
+ );
131
+
132
+ let fun_app = get_fun_app(&id).await?;
133
+ let mut config = get_config().await?;
134
+
135
+ if let Some(fun_app) = config.current_fun_app {
136
+ if fun_app.id != id {
137
+ spinner.stop_with_message("Found a config.".to_string());
138
+ let yes = Confirm::new()
139
+ .with_prompt(format!(
140
+ "Will change active fun_app to {}. Do you want to continue?",
141
+ &id
142
+ ))
143
+ .interact()?;
144
+ if !yes {
145
+ let spinner = Spinner::new(
146
+ spinners::Spinners::SimpleDotsScrolling,
147
+ style("Cancelling operation...").green().bold().to_string(),
148
+ );
149
+ return Ok(CommandResult {
150
+ spinner,
151
+ symbol: "✅".to_owned(),
152
+ msg: "Operation cancelled.".to_string(),
153
+ });
154
+ }
155
+ }
156
+ }
157
+
158
+ config.current_fun_app = Some(fun_app);
159
let spinner = Spinner::new(
160
spinners::Spinners::SimpleDotsScrolling,
62
- style(format!("Using Fun app {id}..."))
63
- .green()
64
- .bold()
65
- .to_string(),
161
+ style("Saving config...").green().bold().to_string(),
162
);
67
- Ok(CommandResult {
68
- spinner,
69
- symbol: "".to_owned(),
70
- msg: "".to_owned(),
71
- })
163
+ match write_config(config) {
164
+ Ok(_) => Ok(CommandResult {
165
+ spinner,
166
+ symbol: "✅".to_owned(),
167
+ msg: format!("Using fun_app: {:?}", &id),
168
+ }),
169
+ Err(_) => {
170
+ let error = anyhow!("Failed while writing config.");
171
+ Err(error)
172
+ }
173
+ }
174
}
175
}
176
}
app-fun/src/lib.rs
+85
@@ -1,2 +1,87 @@
1
pub mod cli;
2
pub mod handler;
3
+
4
+use anyhow::{anyhow, Result};
5
+use log::debug;
6
+use reqwest::Client;
7
+use smbpndk_model::{AppCreate, Fun};
8
+use smbpndk_networking::{constants::BASE_URL, get_token};
9
+
10
+async fn get_fun_apps() -> Result<Vec<Fun>> {
11
+ // Get current token
12
+ let token = get_token().await?;
13
+
14
+ let response = Client::new()
15
+ .get([BASE_URL, "v1/fun_apps"].join(""))
16
+ .header("Authorization", token)
17
+ .send()
18
+ .await?;
19
+
20
+ match response.status() {
21
+ reqwest::StatusCode::OK => {
22
+ let fun_apps: Vec<Fun> = response.json().await?;
23
+ Ok(fun_apps)
24
+ }
25
+ _ => Err(anyhow!("Failed to fetch fun apps.")),
26
+ }
27
+}
28
+
29
+async fn get_fun_app(id: &str) -> Result<Fun> {
30
+ // Get current token
31
+ let token = get_token().await?;
32
+
33
+ let response = Client::new()
34
+ .get([BASE_URL, "v1/fun_apps/", id].join(""))
35
+ .header("Authorization", token)
36
+ .send()
37
+ .await?;
38
+
39
+ match response.status() {
40
+ reqwest::StatusCode::OK => {
41
+ let fun_app: Fun = response.json().await?;
42
+ println!("Auth app requested: {fun_app:#?}");
43
+ Ok(fun_app)
44
+ }
45
+ _ => Err(anyhow!(format!("Failed to find an fun app with id: {id}."))),
46
+ }
47
+}
48
+
49
+async fn delete_fun_app(id: String) -> Result<()> {
50
+ // Get current token
51
+ let token = get_token().await?;
52
+
53
+ let response = Client::new()
54
+ .delete([BASE_URL, "v1/fun_apps/", &id].join(""))
55
+ .header("Authorization", token)
56
+ .send()
57
+ .await?;
58
+
59
+ match response.status() {
60
+ reqwest::StatusCode::OK => {
61
+ debug!("Project deleted.");
62
+ Ok(())
63
+ }
64
+ _ => Err(anyhow!("Failed to delete an fun app.")),
65
+ }
66
+}
67
+
68
+async fn create_fun_app(fun_app: AppCreate) -> Result<Fun> {
69
+ // Get current token
70
+ let token = get_token().await?;
71
+
72
+ let response = Client::new()
73
+ .post([BASE_URL, "v1/fun_apps"].join(""))
74
+ .json(&fun_app)
75
+ .header("Authorization", token)
76
+ .send()
77
+ .await?;
78
+
79
+ match response.status() {
80
+ reqwest::StatusCode::CREATED => {
81
+ let fun_app: Fun = response.json().await?;
82
+ println!("Project created: {fun_app:#?}");
83
+ Ok(fun_app)
84
+ }
85
+ _ => Err(anyhow!("Failed to create an fun app.")),
86
+ }
87
+}
app-oten/src/handler.rs
+26
-26
@@ -1,12 +1,12 @@
1
-use crate::{cli::Commands, create_auth_app, delete_auth_app, get_auth_app, get_auth_apps};
1
+use crate::{cli::Commands, create_oten_app, delete_oten_app, get_oten_app, get_oten_apps};
2
use anyhow::{anyhow, Result};
3
use console::style;
4
use dialoguer::{theme::ColorfulTheme, Confirm, Input};
5
-use smbpndk_model::{AuthAppCreate, CommandResult};
5
+use smbpndk_model::{AppCreate, CommandResult};
6
use smbpndk_utils::{get_config, write_config};
7
use spinners::Spinner;
8
9
-pub async fn process_auth_app(commands: Commands) -> Result<CommandResult> {
9
+pub async fn process_oten_app(commands: Commands) -> Result<CommandResult> {
10
match commands {
11
Commands::New {} => {
12
let app_name = Input::<String>::with_theme(&ColorfulTheme::default())
@@ -20,10 +20,10 @@ pub async fn process_auth_app(commands: Commands) -> Result<CommandResult> {
20
21
let spinner = Spinner::new(
22
spinners::Spinners::SimpleDotsScrolling,
23
- style("Creating an auth app...").green().bold().to_string(),
23
+ style("Creating an Oten app...").green().bold().to_string(),
24
);
25
26
- match create_auth_app(AuthAppCreate {
26
+ match create_oten_app(AppCreate {
27
name: app_name.clone(),
28
description: description.clone(),
29
})
@@ -32,14 +32,14 @@ pub async fn process_auth_app(commands: Commands) -> Result<CommandResult> {
32
Ok(_) => Ok(CommandResult {
33
spinner,
34
symbol: "✅".to_owned(),
35
- msg: format!("An auth app created: {app_name}."),
35
+ msg: format!("An oten app created: {app_name}."),
36
}),
37
Err(e) => {
38
println!("Error: {e:#?}");
39
Ok(CommandResult {
40
spinner,
41
symbol: "😩".to_owned(),
42
- msg: format!("Failed to create an auth app: {app_name}."),
42
+ msg: format!("Failed to create an oten app: {app_name}."),
43
})
44
}
45
}
@@ -49,15 +49,15 @@ pub async fn process_auth_app(commands: Commands) -> Result<CommandResult> {
49
spinners::Spinners::SimpleDotsScrolling,
50
style("Loading...").green().bold().to_string(),
51
);
52
- match get_auth_apps().await {
53
- Ok(auth_apps) => {
54
- println!("auth_apps: {auth_apps:#?}");
52
+ match get_oten_apps().await {
53
+ Ok(oten_apps) => {
54
+ println!("oten_apps: {oten_apps:#?}");
55
println!(
56
"{0: <10} | {1: <30} | {2: <10} | {3: <10}",
57
"ID", "Name", "Created at", "Updated at"
58
);
59
- for project in auth_apps {
60
- let id = project.id.split("-").collect::<Vec<&str>>()[0].to_owned();
59
+ for project in oten_apps {
60
+ let id = project.id.split('-').collect::<Vec<&str>>()[0].to_owned();
61
let created_at = project.created_at.date_naive();
62
let updated_at = project.updated_at.date_naive();
63
println!(
@@ -68,7 +68,7 @@ pub async fn process_auth_app(commands: Commands) -> Result<CommandResult> {
68
Ok(CommandResult {
69
spinner,
70
symbol: "✅".to_owned(),
71
- msg: "Showing all auth apps.".to_owned(),
71
+ msg: "Showing all oten apps.".to_owned(),
72
})
73
}
74
Err(e) => {
@@ -76,7 +76,7 @@ pub async fn process_auth_app(commands: Commands) -> Result<CommandResult> {
76
Ok(CommandResult {
77
spinner,
78
symbol: "😩".to_owned(),
79
- msg: "Failed to get all auth apps.".to_owned(),
79
+ msg: "Failed to get all oten apps.".to_owned(),
80
})
81
}
82
}
@@ -86,18 +86,18 @@ pub async fn process_auth_app(commands: Commands) -> Result<CommandResult> {
86
spinners::Spinners::SimpleDotsScrolling,
87
style("Loading...").green().bold().to_string(),
88
);
89
- match get_auth_app(&id).await {
89
+ match get_oten_app(&id).await {
90
Ok(_) => Ok(CommandResult {
91
spinner,
92
symbol: "✅".to_owned(),
93
- msg: "Showing auth app.".to_owned(),
93
+ msg: "Showing oten app.".to_owned(),
94
}),
95
Err(e) => {
96
println!("Error: {e:#?}");
97
Ok(CommandResult {
98
spinner,
99
symbol: "😩".to_owned(),
100
- msg: "Failed to get an auth app.".to_owned(),
100
+ msg: "Failed to get an oten app.".to_owned(),
101
})
102
}
103
}
@@ -107,18 +107,18 @@ pub async fn process_auth_app(commands: Commands) -> Result<CommandResult> {
107
spinners::Spinners::SimpleDotsScrolling,
108
style("Loading...").green().bold().to_string(),
109
);
110
- match delete_auth_app(id).await {
110
+ match delete_oten_app(id).await {
111
Ok(_) => Ok(CommandResult {
112
spinner,
113
symbol: "✅".to_owned(),
114
- msg: "Delete auth app succeed.".to_owned(),
114
+ msg: "Delete oten app succeed.".to_owned(),
115
}),
116
Err(e) => {
117
println!("Error: {e:#?}");
118
Ok(CommandResult {
119
spinner,
120
symbol: "😩".to_owned(),
121
- msg: "Failed to delete auth app.".to_owned(),
121
+ msg: "Failed to delete oten app.".to_owned(),
122
})
123
}
124
}
@@ -129,15 +129,15 @@ pub async fn process_auth_app(commands: Commands) -> Result<CommandResult> {
129
style("Checking config file...").green().bold().to_string(),
130
);
131
132
- let auth_app = get_auth_app(&id).await?;
132
+ let oten_app = get_oten_app(&id).await?;
133
let mut config = get_config().await?;
134
135
- if let Some(auth_app) = config.current_auth_app {
136
- if auth_app.id != id {
135
+ if let Some(oten_app) = config.current_oten_app {
136
+ if oten_app.id != id {
137
spinner.stop_with_message("Found a config.".to_string());
138
let yes = Confirm::new()
139
.with_prompt(format!(
140
- "Will change active auth_app to {}. Do you want to continue?",
140
+ "Will change active oten_app to {}. Do you want to continue?",
141
&id
142
))
143
.interact()?;
@@ -155,7 +155,7 @@ pub async fn process_auth_app(commands: Commands) -> Result<CommandResult> {
155
}
156
}
157
158
- config.current_auth_app = Some(auth_app);
158
+ config.current_oten_app = Some(oten_app);
159
let spinner = Spinner::new(
160
spinners::Spinners::SimpleDotsScrolling,
161
style("Saving config...").green().bold().to_string(),
@@ -164,7 +164,7 @@ pub async fn process_auth_app(commands: Commands) -> Result<CommandResult> {
164
Ok(_) => Ok(CommandResult {
165
spinner,
166
symbol: "✅".to_owned(),
167
- msg: format!("Using auth_app: {:?}", &id),
167
+ msg: format!("Using oten_app: {:?}", &id),
168
}),
169
Err(_) => {
170
let error = anyhow!("Failed while writing config.");
app-oten/src/lib.rs
+22
-22
@@ -4,56 +4,56 @@ pub mod handler;
4
use anyhow::{anyhow, Result};
5
use log::debug;
6
use reqwest::Client;
7
-use smbpndk_model::{AuthApp, AuthAppCreate};
7
+use smbpndk_model::{AppCreate, Oten};
8
use smbpndk_networking::{constants::BASE_URL, get_token};
9
10
-async fn get_auth_apps() -> Result<Vec<AuthApp>> {
10
+async fn get_oten_apps() -> Result<Vec<Oten>> {
11
// Get current token
12
let token = get_token().await?;
13
14
let response = Client::new()
15
- .get([BASE_URL, "v1/auth_apps"].join(""))
15
+ .get([BASE_URL, "v1/oten_apps"].join(""))
16
.header("Authorization", token)
17
.send()
18
.await?;
19
20
match response.status() {
21
reqwest::StatusCode::OK => {
22
- let auth_apps: Vec<AuthApp> = response.json().await?;
23
- Ok(auth_apps)
22
+ let oten_apps: Vec<Oten> = response.json().await?;
23
+ Ok(oten_apps)
24
}
25
- _ => Err(anyhow!("Failed to fetch auth apps.")),
25
+ _ => Err(anyhow!("Failed to fetch oten apps.")),
26
}
27
}
28
29
-async fn get_auth_app(id: &str) -> Result<AuthApp> {
29
+async fn get_oten_app(id: &str) -> Result<Oten> {
30
// Get current token
31
let token = get_token().await?;
32
33
let response = Client::new()
34
- .get([BASE_URL, "v1/auth_apps/", id].join(""))
34
+ .get([BASE_URL, "v1/oten_apps/", id].join(""))
35
.header("Authorization", token)
36
.send()
37
.await?;
38
39
match response.status() {
40
reqwest::StatusCode::OK => {
41
- let auth_app: AuthApp = response.json().await?;
42
- println!("Auth app requested: {auth_app:#?}");
43
- Ok(auth_app)
41
+ let oten_app: Oten = response.json().await?;
42
+ println!("Auth app requested: {oten_app:#?}");
43
+ Ok(oten_app)
44
}
45
_ => Err(anyhow!(format!(
46
- "Failed to find an auth app with id: {id}."
46
+ "Failed to find an oten app with id: {id}."
47
))),
48
}
49
}
50
51
-async fn delete_auth_app(id: String) -> Result<()> {
51
+async fn delete_oten_app(id: String) -> Result<()> {
52
// Get current token
53
let token = get_token().await?;
54
55
let response = Client::new()
56
- .delete([BASE_URL, "v1/auth_apps/", &id].join(""))
56
+ .delete([BASE_URL, "v1/oten_apps/", &id].join(""))
57
.header("Authorization", token)
58
.send()
59
.await?;
@@ -63,27 +63,27 @@ async fn delete_auth_app(id: String) -> Result<()> {
63
debug!("Project deleted.");
64
Ok(())
65
}
66
- _ => Err(anyhow!("Failed to delete an auth app.")),
66
+ _ => Err(anyhow!("Failed to delete an oten app.")),
67
}
68
}
69
70
-async fn create_auth_app(auth_app: AuthAppCreate) -> Result<AuthApp> {
70
+async fn create_oten_app(oten_app: AppCreate) -> Result<Oten> {
71
// Get current token
72
let token = get_token().await?;
73
74
let response = Client::new()
75
- .post([BASE_URL, "v1/auth_apps"].join(""))
76
- .json(&auth_app)
75
+ .post([BASE_URL, "v1/oten_apps"].join(""))
76
+ .json(&oten_app)
77
.header("Authorization", token)
78
.send()
79
.await?;
80
81
match response.status() {
82
reqwest::StatusCode::CREATED => {
83
- let auth_app: AuthApp = response.json().await?;
84
- println!("Project created: {auth_app:#?}");
85
- Ok(auth_app)
83
+ let oten_app: Oten = response.json().await?;
84
+ println!("Project created: {oten_app:#?}");
85
+ Ok(oten_app)
86
}
87
- _ => Err(anyhow!("Failed to create an auth app.")),
87
+ _ => Err(anyhow!("Failed to create an oten app.")),
88
}
89
}
app-pkt/Cargo.toml
+17
@@ -12,3 +12,20 @@ categories = ["command-line-utilities", "command-line-interface", "cryptography:
12
readme = "../README.md"
13
14
[dependencies]
15
+anyhow = "1.0.58"
16
+async-trait = { version = "0.1.51", optional = true }
17
+clap = { version = "4.1.6", features = ["derive"] }
18
+console = "0.15.0"
19
+dialoguer = "0.10.4"
20
+dirs = "4.0.0"
21
+home = "0.5.4"
22
+log = "0.4.14"
23
+maybe-async = { version = "0.2", features = ["is_sync"] }
24
+reqwest = { version = "0.11", features = ["json"] }
25
+serde = { version = "1", features = ["derive"] }
26
+serde_json = "1.0.82"
27
+smbpndk-model = { version = "0.3", path = "../smbpndk-model" }
28
+smbpndk-networking = { version = "0.3", path = "../smbpndk-networking" }
29
+smbpndk-utils = { version = "0.3", path = "../smbpndk-utils" }
30
+spinners = "4.1.0"
31
+thiserror = "1.0.29"
app-pkt/src/cli.rs
new
+30
@@ -0,0 +1,30 @@
1
+use clap::Subcommand;
2
+
3
+#[derive(Subcommand)]
4
+pub enum Commands {
5
+ #[clap(about = "Add new auth app.")]
6
+ New {},
7
+
8
+ #[clap(about = "List all your auth apps.")]
9
+ List {},
10
+
11
+ #[clap(about = "Show detail of a auth app.")]
12
+ Show {
13
+ /// Project Id
14
+ #[clap(short, long, required = true)]
15
+ id: String,
16
+ },
17
+
18
+ #[clap(about = "Delete a auth app.")]
19
+ Delete {
20
+ /// Project name
21
+ #[clap(short, long, required = true)]
22
+ id: String,
23
+ },
24
+
25
+ #[clap(about = "Use auth app for current CLI session.")]
26
+ Use {
27
+ #[clap(short, long, required = true)]
28
+ id: String,
29
+ },
30
+}
app-pkt/src/handler.rs
new
+176
@@ -0,0 +1,176 @@
1
+use crate::{cli::Commands, create_pkt_app, delete_pkt_app, get_pkt_app, get_pkt_apps};
2
+use anyhow::{anyhow, Result};
3
+use console::style;
4
+use dialoguer::{theme::ColorfulTheme, Confirm, Input};
5
+use smbpndk_model::{AppCreate, CommandResult};
6
+use smbpndk_utils::{get_config, write_config};
7
+use spinners::Spinner;
8
+
9
+pub async fn process_pkt_app(commands: Commands) -> Result<CommandResult> {
10
+ match commands {
11
+ Commands::New {} => {
12
+ let app_name = Input::<String>::with_theme(&ColorfulTheme::default())
13
+ .with_prompt("App name")
14
+ .interact()
15
+ .unwrap();
16
+ let description = Input::<String>::with_theme(&ColorfulTheme::default())
17
+ .with_prompt("Description")
18
+ .interact()
19
+ .unwrap();
20
+
21
+ let spinner = Spinner::new(
22
+ spinners::Spinners::SimpleDotsScrolling,
23
+ style("Creating a Pkt app...").green().bold().to_string(),
24
+ );
25
+
26
+ match create_pkt_app(AppCreate {
27
+ name: app_name.clone(),
28
+ description: description.clone(),
29
+ })
30
+ .await
31
+ {
32
+ Ok(_) => Ok(CommandResult {
33
+ spinner,
34
+ symbol: "✅".to_owned(),
35
+ msg: format!("Pkt app created: {app_name}."),
36
+ }),
37
+ Err(e) => {
38
+ println!("Error: {e:#?}");
39
+ Ok(CommandResult {
40
+ spinner,
41
+ symbol: "😩".to_owned(),
42
+ msg: format!("Failed to create a Pkt app: {app_name}."),
43
+ })
44
+ }
45
+ }
46
+ }
47
+ Commands::List {} => {
48
+ let spinner = Spinner::new(
49
+ spinners::Spinners::SimpleDotsScrolling,
50
+ style("Loading...").green().bold().to_string(),
51
+ );
52
+ match get_pkt_apps().await {
53
+ Ok(apps) => {
54
+ println!("apps: {apps:#?}");
55
+ println!(
56
+ "{0: <10} | {1: <30} | {2: <10} | {3: <10}",
57
+ "ID", "Name", "Created at", "Updated at"
58
+ );
59
+ for project in apps {
60
+ let id = project.id.split('-').collect::<Vec<&str>>()[0].to_owned();
61
+ let created_at = project.created_at.date_naive();
62
+ let updated_at = project.updated_at.date_naive();
63
+ println!(
64
+ "{0: <10} | {1: <30} | {2: <10} | {3: <10}",
65
+ id, project.name, created_at, updated_at
66
+ );
67
+ }
68
+ Ok(CommandResult {
69
+ spinner,
70
+ symbol: "✅".to_owned(),
71
+ msg: "Showing all Pkt apps.".to_owned(),
72
+ })
73
+ }
74
+ Err(e) => {
75
+ println!("Error: {e:#?}");
76
+ Ok(CommandResult {
77
+ spinner,
78
+ symbol: "😩".to_owned(),
79
+ msg: "Failed to get all Pkt apps.".to_owned(),
80
+ })
81
+ }
82
+ }
83
+ }
84
+ Commands::Show { id } => {
85
+ let spinner = Spinner::new(
86
+ spinners::Spinners::SimpleDotsScrolling,
87
+ style("Loading...").green().bold().to_string(),
88
+ );
89
+ match get_pkt_app(&id).await {
90
+ Ok(_) => Ok(CommandResult {
91
+ spinner,
92
+ symbol: "✅".to_owned(),
93
+ msg: "Showing Pkt app.".to_owned(),
94
+ }),
95
+ Err(e) => {
96
+ println!("Error: {e:#?}");
97
+ Ok(CommandResult {
98
+ spinner,
99
+ symbol: "😩".to_owned(),
100
+ msg: "Failed to get an Pkt app.".to_owned(),
101
+ })
102
+ }
103
+ }
104
+ }
105
+ Commands::Delete { id } => {
106
+ let spinner = Spinner::new(
107
+ spinners::Spinners::SimpleDotsScrolling,
108
+ style("Loading...").green().bold().to_string(),
109
+ );
110
+ match delete_pkt_app(id).await {
111
+ Ok(_) => Ok(CommandResult {
112
+ spinner,
113
+ symbol: "✅".to_owned(),
114
+ msg: "Delete Pkt app succeed.".to_owned(),
115
+ }),
116
+ Err(e) => {
117
+ println!("Error: {e:#?}");
118
+ Ok(CommandResult {
119
+ spinner,
120
+ symbol: "😩".to_owned(),
121
+ msg: "Failed to delete Pkt app.".to_owned(),
122
+ })
123
+ }
124
+ }
125
+ }
126
+ Commands::Use { id } => {
127
+ let mut spinner = Spinner::new(
128
+ spinners::Spinners::SimpleDotsScrolling,
129
+ style("Checking config file...").green().bold().to_string(),
130
+ );
131
+
132
+ let pkt_app = get_pkt_app(&id).await?;
133
+ let mut config = get_config().await?;
134
+
135
+ if let Some(pkt) = config.current_pkt_app {
136
+ if pkt.id != id {
137
+ spinner.stop_with_message("Found a config.".to_string());
138
+ let yes = Confirm::new()
139
+ .with_prompt(format!(
140
+ "Will change active Pkt app to {}. Do you want to continue?",
141
+ &id
142
+ ))
143
+ .interact()?;
144
+ if !yes {
145
+ let spinner = Spinner::new(
146
+ spinners::Spinners::SimpleDotsScrolling,
147
+ style("Cancelling operation...").green().bold().to_string(),
148
+ );
149
+ return Ok(CommandResult {
150
+ spinner,
151
+ symbol: "✅".to_owned(),
152
+ msg: "Operation cancelled.".to_string(),
153
+ });
154
+ }
155
+ }
156
+ }
157
+
158
+ config.current_pkt_app = Some(pkt_app);
159
+ let spinner = Spinner::new(
160
+ spinners::Spinners::SimpleDotsScrolling,
161
+ style("Saving config...").green().bold().to_string(),
162
+ );
163
+ match write_config(config) {
164
+ Ok(_) => Ok(CommandResult {
165
+ spinner,
166
+ symbol: "✅".to_owned(),
167
+ msg: format!("Using Pkt app: {:?}", &id),
168
+ }),
169
+ Err(_) => {
170
+ let error = anyhow!("Failed while writing config.");
171
+ Err(error)
172
+ }
173
+ }
174
+ }
175
+ }
176
+}
app-pkt/src/lib.rs
+82
-9
@@ -1,14 +1,87 @@
1
-pub fn add(left: usize, right: usize) -> usize {
2
- left + right
1
+pub mod cli;
2
+pub mod handler;
3
+
4
+use anyhow::{anyhow, Result};
5
+use log::debug;
6
+use reqwest::Client;
7
+use smbpndk_model::{AppCreate, Pkt};
8
+use smbpndk_networking::{constants::BASE_URL, get_token};
9
+
10
+async fn get_pkt_apps() -> Result<Vec<Pkt>> {
11
+ // Get current token
12
+ let token = get_token().await?;
13
+
14
+ let response = Client::new()
15
+ .get([BASE_URL, "v1/pkt_apps"].join(""))
16
+ .header("Authorization", token)
17
+ .send()
18
+ .await?;
19
+
20
+ match response.status() {
21
+ reqwest::StatusCode::OK => {
22
+ let apps: Vec<Pkt> = response.json().await?;
23
+ Ok(apps)
24
+ }
25
+ _ => Err(anyhow!("Failed to fetch Pkt apps.")),
26
+ }
27
+}
28
+
29
+async fn get_pkt_app(id: &str) -> Result<Pkt> {
30
+ // Get current token
31
+ let token = get_token().await?;
32
+
33
+ let response = Client::new()
34
+ .get([BASE_URL, "v1/pkt_apps/", id].join(""))
35
+ .header("Authorization", token)
36
+ .send()
37
+ .await?;
38
+
39
+ match response.status() {
40
+ reqwest::StatusCode::OK => {
41
+ let auth_app: Pkt = response.json().await?;
42
+ println!("Pkt app requested: {auth_app:#?}");
43
+ Ok(auth_app)
44
+ }
45
+ _ => Err(anyhow!(format!("Failed to find an Pkt app with id: {id}."))),
46
+ }
47
+}
48
+
49
+async fn delete_pkt_app(id: String) -> Result<()> {
50
+ // Get current token
51
+ let token = get_token().await?;
52
+
53
+ let response = Client::new()
54
+ .delete([BASE_URL, "v1/pkt_apps/", &id].join(""))
55
+ .header("Authorization", token)
56
+ .send()
57
+ .await?;
58
+
59
+ match response.status() {
60
+ reqwest::StatusCode::OK => {
61
+ debug!("App deleted.");
62
+ Ok(())
63
+ }
64
+ _ => Err(anyhow!("Failed to delete an Pkt app.")),
65
+ }
66
}
67
5
-#[cfg(test)]
6
-mod tests {
7
- use super::*;
68
+async fn create_pkt_app(app: AppCreate) -> Result<Pkt> {
69
+ // Get current token
70
+ let token = get_token().await?;
71
+
72
+ let response = Client::new()
73
+ .post([BASE_URL, "v1/pkt_apps"].join(""))
74
+ .json(&app)
75
+ .header("Authorization", token)
76
+ .send()
77
+ .await?;
78
9
- #[test]
10
- fn it_works() {
11
- let result = add(2, 2);
12
- assert_eq!(result, 4);
79
+ match response.status() {
80
+ reqwest::StatusCode::CREATED => {
81
+ let app: Pkt = response.json().await?;
82
+ println!("App created: {app:#?}");
83
+ Ok(app)
84
+ }
85
+ _ => Err(anyhow!("Failed to create an Pkt app.")),
86
}
87
}
app-rdb/Cargo.toml
+17
@@ -12,3 +12,20 @@ categories = ["command-line-utilities", "command-line-interface", "cryptography:
12
readme = "../README.md"
13
14
[dependencies]
15
+anyhow = "1.0.58"
16
+async-trait = { version = "0.1.51", optional = true }
17
+clap = { version = "4.1.6", features = ["derive"] }
18
+console = "0.15.0"
19
+dialoguer = "0.10.4"
20
+dirs = "4.0.0"
21
+home = "0.5.4"
22
+log = "0.4.14"
23
+maybe-async = { version = "0.2", features = ["is_sync"] }
24
+reqwest = { version = "0.11", features = ["json"] }
25
+serde = { version = "1", features = ["derive"] }
26
+serde_json = "1.0.82"
27
+smbpndk-model = { version = "0.3", path = "../smbpndk-model" }
28
+smbpndk-networking = { version = "0.3", path = "../smbpndk-networking" }
29
+smbpndk-utils = { version = "0.3", path = "../smbpndk-utils" }
30
+spinners = "4.1.0"
31
+thiserror = "1.0.29"
app-rdb/src/cli.rs
new
+30
@@ -0,0 +1,30 @@
1
+use clap::Subcommand;
2
+
3
+#[derive(Subcommand)]
4
+pub enum Commands {
5
+ #[clap(about = "Add new auth app.")]
6
+ New {},
7
+
8
+ #[clap(about = "List all your auth apps.")]
9
+ List {},
10
+
11
+ #[clap(about = "Show detail of a auth app.")]
12
+ Show {
13
+ /// Project Id
14
+ #[clap(short, long, required = true)]
15
+ id: String,
16
+ },
17
+
18
+ #[clap(about = "Delete a auth app.")]
19
+ Delete {
20
+ /// Project name
21
+ #[clap(short, long, required = true)]
22
+ id: String,
23
+ },
24
+
25
+ #[clap(about = "Use auth app for current CLI session.")]
26
+ Use {
27
+ #[clap(short, long, required = true)]
28
+ id: String,
29
+ },
30
+}
app-rdb/src/handler.rs
new
+176
@@ -0,0 +1,176 @@
1
+use crate::{cli::Commands, create_rdb_app, delete_rdb_app, get_rdb_app, get_rdb_apps};
2
+use anyhow::{anyhow, Result};
3
+use console::style;
4
+use dialoguer::{theme::ColorfulTheme, Confirm, Input};
5
+use smbpndk_model::{AppCreate, CommandResult};
6
+use smbpndk_utils::{get_config, write_config};
7
+use spinners::Spinner;
8
+
9
+pub async fn process_rdb_app(commands: Commands) -> Result<CommandResult> {
10
+ match commands {
11
+ Commands::New {} => {
12
+ let app_name = Input::<String>::with_theme(&ColorfulTheme::default())
13
+ .with_prompt("App name")
14
+ .interact()
15
+ .unwrap();
16
+ let description = Input::<String>::with_theme(&ColorfulTheme::default())
17
+ .with_prompt("Description")
18
+ .interact()
19
+ .unwrap();
20
+
21
+ let spinner = Spinner::new(
22
+ spinners::Spinners::SimpleDotsScrolling,
23
+ style("Creating a Pkt app...").green().bold().to_string(),
24
+ );
25
+
26
+ match create_rdb_app(AppCreate {
27
+ name: app_name.clone(),
28
+ description: description.clone(),
29
+ })
30
+ .await
31
+ {
32
+ Ok(_) => Ok(CommandResult {
33
+ spinner,
34
+ symbol: "✅".to_owned(),
35
+ msg: format!("A Pkt app created: {app_name}."),
36
+ }),
37
+ Err(e) => {
38
+ println!("Error: {e:#?}");
39
+ Ok(CommandResult {
40
+ spinner,
41
+ symbol: "😩".to_owned(),
42
+ msg: format!("Failed to create a Pkt app: {app_name}."),
43
+ })
44
+ }
45
+ }
46
+ }
47
+ Commands::List {} => {
48
+ let spinner = Spinner::new(
49
+ spinners::Spinners::SimpleDotsScrolling,
50
+ style("Loading...").green().bold().to_string(),
51
+ );
52
+ match get_rdb_apps().await {
53
+ Ok(apps) => {
54
+ println!("Rdb apps: {apps:#?}");
55
+ println!(
56
+ "{0: <10} | {1: <30} | {2: <10} | {3: <10}",
57
+ "ID", "Name", "Created at", "Updated at"
58
+ );
59
+ for project in apps {
60
+ let id = project.id.split('-').collect::<Vec<&str>>()[0].to_owned();
61
+ let created_at = project.created_at.date_naive();
62
+ let updated_at = project.updated_at.date_naive();
63
+ println!(
64
+ "{0: <10} | {1: <30} | {2: <10} | {3: <10}",
65
+ id, project.name, created_at, updated_at
66
+ );
67
+ }
68
+ Ok(CommandResult {
69
+ spinner,
70
+ symbol: "✅".to_owned(),
71
+ msg: "Showing all auth apps.".to_owned(),
72
+ })
73
+ }
74
+ Err(e) => {
75
+ println!("Error: {e:#?}");
76
+ Ok(CommandResult {
77
+ spinner,
78
+ symbol: "😩".to_owned(),
79
+ msg: "Failed to get all auth apps.".to_owned(),
80
+ })
81
+ }
82
+ }
83
+ }
84
+ Commands::Show { id } => {
85
+ let spinner = Spinner::new(
86
+ spinners::Spinners::SimpleDotsScrolling,
87
+ style("Loading...").green().bold().to_string(),
88
+ );
89
+ match get_rdb_app(&id).await {
90
+ Ok(_) => Ok(CommandResult {
91
+ spinner,
92
+ symbol: "✅".to_owned(),
93
+ msg: "Showing auth app.".to_owned(),
94
+ }),
95
+ Err(e) => {
96
+ println!("Error: {e:#?}");
97
+ Ok(CommandResult {
98
+ spinner,
99
+ symbol: "😩".to_owned(),
100
+ msg: "Failed to get an auth app.".to_owned(),
101
+ })
102
+ }
103
+ }
104
+ }
105
+ Commands::Delete { id } => {
106
+ let spinner = Spinner::new(
107
+ spinners::Spinners::SimpleDotsScrolling,
108
+ style("Loading...").green().bold().to_string(),
109
+ );
110
+ match delete_rdb_app(id).await {
111
+ Ok(_) => Ok(CommandResult {
112
+ spinner,
113
+ symbol: "✅".to_owned(),
114
+ msg: "Delete auth app succeed.".to_owned(),
115
+ }),
116
+ Err(e) => {
117
+ println!("Error: {e:#?}");
118
+ Ok(CommandResult {
119
+ spinner,
120
+ symbol: "😩".to_owned(),
121
+ msg: "Failed to delete auth app.".to_owned(),
122
+ })
123
+ }
124
+ }
125
+ }
126
+ Commands::Use { id } => {
127
+ let mut spinner = Spinner::new(
128
+ spinners::Spinners::SimpleDotsScrolling,
129
+ style("Checking config file...").green().bold().to_string(),
130
+ );
131
+
132
+ let rdb_app = get_rdb_app(&id).await?;
133
+ let mut config = get_config().await?;
134
+
135
+ if let Some(rdb_app) = config.current_rdb_app {
136
+ if rdb_app.id != id {
137
+ spinner.stop_with_message("Found a config.".to_string());
138
+ let yes = Confirm::new()
139
+ .with_prompt(format!(
140
+ "Will change active Pkt app to {}. Do you want to continue?",
141
+ &id
142
+ ))
143
+ .interact()?;
144
+ if !yes {
145
+ let spinner = Spinner::new(
146
+ spinners::Spinners::SimpleDotsScrolling,
147
+ style("Cancelling operation...").green().bold().to_string(),
148
+ );
149
+ return Ok(CommandResult {
150
+ spinner,
151
+ symbol: "✅".to_owned(),
152
+ msg: "Operation cancelled.".to_string(),
153
+ });
154
+ }
155
+ }
156
+ }
157
+
158
+ config.current_rdb_app = Some(rdb_app);
159
+ let spinner = Spinner::new(
160
+ spinners::Spinners::SimpleDotsScrolling,
161
+ style("Saving config...").green().bold().to_string(),
162
+ );
163
+ match write_config(config) {
164
+ Ok(_) => Ok(CommandResult {
165
+ spinner,
166
+ symbol: "✅".to_owned(),
167
+ msg: format!("Using Pkt app: {:?}", &id),
168
+ }),
169
+ Err(_) => {
170
+ let error = anyhow!("Failed while writing config.");
171
+ Err(error)
172
+ }
173
+ }
174
+ }
175
+ }
176
+}
app-rdb/src/lib.rs
+82
-9
@@ -1,14 +1,87 @@
1
-pub fn add(left: usize, right: usize) -> usize {
2
- left + right
1
+pub mod cli;
2
+pub mod handler;
3
+
4
+use anyhow::{anyhow, Result};
5
+use log::debug;
6
+use reqwest::Client;
7
+use smbpndk_model::{AppCreate, Rdb};
8
+use smbpndk_networking::{constants::BASE_URL, get_token};
9
+
10
+async fn get_rdb_apps() -> Result<Vec<Rdb>> {
11
+ // Get current token
12
+ let token = get_token().await?;
13
+
14
+ let response = Client::new()
15
+ .get([BASE_URL, "v1/rdb_apps"].join(""))
16
+ .header("Authorization", token)
17
+ .send()
18
+ .await?;
19
+
20
+ match response.status() {
21
+ reqwest::StatusCode::OK => {
22
+ let apps: Vec<Rdb> = response.json().await?;
23
+ Ok(apps)
24
+ }
25
+ _ => Err(anyhow!("Failed to fetch Rdb apps.")),
26
+ }
27
+}
28
+
29
+async fn get_rdb_app(id: &str) -> Result<Rdb> {
30
+ // Get current token
31
+ let token = get_token().await?;
32
+
33
+ let response = Client::new()
34
+ .get([BASE_URL, "v1/rdb_apps/", id].join(""))
35
+ .header("Authorization", token)
36
+ .send()
37
+ .await?;
38
+
39
+ match response.status() {
40
+ reqwest::StatusCode::OK => {
41
+ let app: Rdb = response.json().await?;
42
+ println!("Rdb app requested: {app:#?}");
43
+ Ok(app)
44
+ }
45
+ _ => Err(anyhow!(format!("Failed to find an Rdb app with id: {id}."))),
46
+ }
47
+}
48
+
49
+async fn delete_rdb_app(id: String) -> Result<()> {
50
+ // Get current token
51
+ let token = get_token().await?;
52
+
53
+ let response = Client::new()
54
+ .delete([BASE_URL, "v1/rdb_apps/", &id].join(""))
55
+ .header("Authorization", token)
56
+ .send()
57
+ .await?;
58
+
59
+ match response.status() {
60
+ reqwest::StatusCode::OK => {
61
+ debug!("Project deleted.");
62
+ Ok(())
63
+ }
64
+ _ => Err(anyhow!("Failed to delete an Rdb app.")),
65
+ }
66
}
67
5
-#[cfg(test)]
6
-mod tests {
7
- use super::*;
68
+async fn create_rdb_app(app: AppCreate) -> Result<Rdb> {
69
+ // Get current token
70
+ let token = get_token().await?;
71
+
72
+ let response = Client::new()
73
+ .post([BASE_URL, "v1/rdb_apps"].join(""))
74
+ .json(&app)
75
+ .header("Authorization", token)
76
+ .send()
77
+ .await?;
78
9
- #[test]
10
- fn it_works() {
11
- let result = add(2, 2);
12
- assert_eq!(result, 4);
79
+ match response.status() {
80
+ reqwest::StatusCode::CREATED => {
81
+ let app: Rdb = response.json().await?;
82
+ println!("Project created: {app:#?}");
83
+ Ok(app)
84
+ }
85
+ _ => Err(anyhow!("Failed to create an Rdb app.")),
86
}
87
}
smbpndk-cli/src/cli/mod.rs
+20
-13
@@ -20,32 +20,39 @@ pub enum Commands {
20
command: account::cli::Commands,
21
},
22
23
- #[clap(about = "Manage your projects. Add, delete, edit. Need authentication.")]
23
+ #[clap(about = "Manage your projects. Add, show, delete, edit. Need authentication.")]
24
Project {
25
#[clap(subcommand)]
26
command: project::cli::Commands,
27
},
28
29
- #[clap(about = "Manage your Oten authentication app. Add, delete, edit. Need authentication.")]
29
+ #[clap(
30
+ about = "Manage your Oten authentication app. Add, show, delete, edit. Need authentication."
31
+ )]
32
Oten {
33
#[clap(subcommand)]
34
command: app_oten::cli::Commands,
35
},
34
- // Function
36
+
37
+ #[clap(
38
+ about = "Manage your Fun serverless app. Add, show, delete, edit. Need authentication."
39
+ )]
40
Fun {
41
#[clap(subcommand)]
42
command: app_fun::cli::Commands,
43
},
39
- // Package
40
- /*
41
- PktApp {
44
+
45
+ #[clap(
46
+ about = "Manage your Pkt package manager app. Add, show, delete, edit. Need authentication."
47
+ )]
48
+ Pkt {
49
#[clap(subcommand)]
43
- command: pkt_app::cli::Commands,
44
- }, */
45
- // Relational database
46
- /*
47
- RdbApp {
50
+ command: app_pkt::cli::Commands,
51
+ },
52
+
53
+ #[clap(about = "Manage your Rdb database app. Add, show, delete, edit. Need authentication.")]
54
+ Rdb {
55
#[clap(subcommand)]
49
- command: rdb_app::cli::Commands,
50
- }, */
56
+ command: app_rdb::cli::Commands,
57
+ },
58
}
smbpndk-cli/src/main.rs
+6
-2
@@ -1,6 +1,8 @@
1
use anyhow::{anyhow, Result};
2
use app_fun::handler::process_fun_app;
3
-use app_oten::{self, handler::process_auth_app};
3
+use app_oten::handler::process_oten_app;
4
+use app_pkt::handler::process_pkt_app;
5
+use app_rdb::handler::process_rdb_app;
6
use clap::Parser;
7
use console::style;
8
use dotenv::dotenv;
@@ -103,7 +105,9 @@ async fn run() -> Result<CommandResult> {
105
match cli.command {
106
Commands::Account { command } => process_account(command).await,
107
Commands::Project { command } => process_project(command).await,
106
- Commands::Oten { command } => process_auth_app(command).await,
108
+ Commands::Oten { command } => process_oten_app(command).await,
109
Commands::Fun { command } => process_fun_app(command).await,
110
+ Commands::Pkt { command } => process_pkt_app(command).await,
111
+ Commands::Rdb { command } => process_rdb_app(command).await,
112
}
113
}
smbpndk-cli/src/project/mod.rs
+5
-2
@@ -131,7 +131,10 @@ pub async fn process_project(commands: Commands) -> Result<CommandResult> {
131
132
let config = Config {
133
current_project: Some(project),
134
- current_auth_app: None,
134
+ current_oten_app: None,
135
+ current_fun_app: None,
136
+ current_pkt_app: None,
137
+ current_rdb_app: None,
138
};
139
140
let spinner = Spinner::new(
@@ -144,7 +147,7 @@ pub async fn process_project(commands: Commands) -> Result<CommandResult> {
147
let mut file = OpenOptions::new()
148
.create(true)
149
.write(true)
147
- .open([path.to_str().unwrap(), "/.smb/config.json"].join(""))?;
150
+ .open([path.to_str().unwrap(), "/.smb/config"].join(""))?;
151
let json = serde_json::to_string(&config)?;
152
file.write_all(json.as_bytes())?;
153
smbpndk-model/src/lib.rs
+40
-4
@@ -6,7 +6,7 @@ mod ar_date_format {
6
use chrono::{DateTime, TimeZone, Utc};
7
use serde::{self, Deserialize, Deserializer, Serializer};
8
9
- const FORMAT: &'static str = "%Y-%m-%dT%H:%M:%S%.f%#z";
9
+ const FORMAT: &str = "%Y-%m-%dT%H:%M:%S%.f%#z";
10
11
// The signature of a serialize_with function must follow the pattern:
12
//
@@ -47,7 +47,7 @@ pub struct CommandResult {
47
}
48
49
#[derive(Serialize, Deserialize, Debug)]
50
-pub struct AuthApp {
50
+pub struct Oten {
51
pub id: String,
52
pub secret: Option<String>,
53
pub name: String,
@@ -58,7 +58,40 @@ pub struct AuthApp {
58
}
59
60
#[derive(Serialize, Deserialize, Debug)]
61
-pub struct AuthAppCreate {
61
+pub struct Fun {
62
+ pub id: String,
63
+ pub secret: Option<String>,
64
+ pub name: String,
65
+ #[serde(with = "ar_date_format")]
66
+ pub created_at: DateTime<Utc>,
67
+ #[serde(with = "ar_date_format")]
68
+ pub updated_at: DateTime<Utc>,
69
+}
70
+
71
+#[derive(Serialize, Deserialize, Debug)]
72
+pub struct Pkt {
73
+ pub id: String,
74
+ pub secret: Option<String>,
75
+ pub name: String,
76
+ #[serde(with = "ar_date_format")]
77
+ pub created_at: DateTime<Utc>,
78
+ #[serde(with = "ar_date_format")]
79
+ pub updated_at: DateTime<Utc>,
80
+}
81
+
82
+#[derive(Serialize, Deserialize, Debug)]
83
+pub struct Rdb {
84
+ pub id: String,
85
+ pub secret: Option<String>,
86
+ pub name: String,
87
+ #[serde(with = "ar_date_format")]
88
+ pub created_at: DateTime<Utc>,
89
+ #[serde(with = "ar_date_format")]
90
+ pub updated_at: DateTime<Utc>,
91
+}
92
+
93
+#[derive(Serialize, Deserialize, Debug)]
94
+pub struct AppCreate {
95
pub name: String,
96
pub description: String,
97
}
@@ -66,7 +99,10 @@ pub struct AuthAppCreate {
99
#[derive(Deserialize, Debug, Serialize)]
100
pub struct Config {
101
pub current_project: Option<Project>,
69
- pub current_auth_app: Option<AuthApp>,
102
+ pub current_oten_app: Option<Oten>,
103
+ pub current_fun_app: Option<Fun>,
104
+ pub current_pkt_app: Option<Pkt>,
105
+ pub current_rdb_app: Option<Rdb>,
106
}
107
108
#[derive(Deserialize, Debug, Serialize)]
smbpndk-networking/src/lib.rs
+13
@@ -2,6 +2,7 @@ pub mod constants;
2
3
use anyhow::{anyhow, Result};
4
use log::debug;
5
+use smbpndk_model::Config;
6
7
pub async fn get_token() -> Result<String> {
8
if let Some(mut path) = dirs::home_dir() {
@@ -14,3 +15,15 @@ pub async fn get_token() -> Result<String> {
15
Err(anyhow!("Failed to get home directory."))
16
}
17
}
18
+
19
+pub async fn get_config() -> Result<Config> {
20
+ match dirs::home_dir() {
21
+ Some(mut path) => {
22
+ path.push(".smb/config");
23
+ let config = std::fs::read_to_string(path)?;
24
+ let config: Config = serde_json::from_str(&config)?;
25
+ Ok(config)
26
+ }
27
+ None => Err(anyhow!("Failed to get home directory.")),
28
+ }
29
+}
smbpndk-utils/src/lib.rs
+8
-2
@@ -25,7 +25,10 @@ pub async fn get_config() -> Result<Config> {
25
if !path.exists() {
26
let config = Config {
27
current_project: None,
28
- current_auth_app: None,
28
+ current_oten_app: None,
29
+ current_fun_app: None,
30
+ current_pkt_app: None,
31
+ current_rdb_app: None,
32
};
33
return Ok(config);
34
}
@@ -43,7 +46,10 @@ pub async fn get_config() -> Result<Config> {
46
None => {
47
let config = Config {
48
current_project: None,
46
- current_auth_app: None,
49
+ current_oten_app: None,
50
+ current_fun_app: None,
51
+ current_pkt_app: None,
52
+ current_rdb_app: None,
53
};
54
Ok(config)
55
}