eitri-cli 1.8.0 → 1.9.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +2 -1
- package/bitbucket-pipelines.yml +35 -1
- package/config/dev.js +1 -1
- package/config/k8s-eitri.js +1 -1
- package/config/loc-eitri.js +1 -1
- package/eitri-cli-v2/Cargo.lock +2500 -0
- package/eitri-cli-v2/Cargo.toml +21 -0
- package/eitri-cli-v2/README.md +119 -0
- package/eitri-cli-v2/index.js +2 -0
- package/eitri-cli-v2/index.unix.node +0 -0
- package/eitri-cli-v2/index.win32.node +0 -0
- package/eitri-cli-v2/node_modules/.yarn-integrity +16 -0
- package/eitri-cli-v2/node_modules/cargo-cp-artifact/LICENSE +21 -0
- package/eitri-cli-v2/node_modules/cargo-cp-artifact/README.md +93 -0
- package/eitri-cli-v2/node_modules/cargo-cp-artifact/bin/cargo-cp-artifact.js +6 -0
- package/eitri-cli-v2/node_modules/cargo-cp-artifact/package.json +34 -0
- package/eitri-cli-v2/node_modules/cargo-cp-artifact/src/args.js +131 -0
- package/eitri-cli-v2/node_modules/cargo-cp-artifact/src/index.js +164 -0
- package/eitri-cli-v2/package-lock.json +26 -0
- package/eitri-cli-v2/package.json +21 -0
- package/eitri-cli-v2/src/commands/mod.rs +1 -0
- package/eitri-cli-v2/src/commands/publish.rs +67 -0
- package/eitri-cli-v2/src/config/mod.rs +1 -0
- package/eitri-cli-v2/src/config/user_credentials.rs +38 -0
- package/eitri-cli-v2/src/infra/async_runtime.rs +9 -0
- package/eitri-cli-v2/src/infra/http_client.rs +484 -0
- package/eitri-cli-v2/src/infra/mod.rs +2 -0
- package/eitri-cli-v2/src/lib.rs +41 -0
- package/eitri-cli-v2/src/model/auth_response.rs +8 -0
- package/eitri-cli-v2/src/model/credentials.rs +8 -0
- package/eitri-cli-v2/src/model/eitri_conf.rs +43 -0
- package/eitri-cli-v2/src/model/mod.rs +4 -0
- package/eitri-cli-v2/src/model/revision.rs +14 -0
- package/eitri-cli-v2/src/services/blind_guardian.rs +87 -0
- package/eitri-cli-v2/src/services/eitri_manager.rs +78 -0
- package/eitri-cli-v2/src/services/mod.rs +3 -0
- package/eitri-cli-v2/src/services/workspace.rs +46 -0
- package/eitri-cli-v2/src/utils/convert_eitri_conf.rs +98 -0
- package/eitri-cli-v2/src/utils/mod.rs +1 -0
- package/eitri-cli-v2/yarn.lock +8 -0
- package/index.js +16 -0
- package/install-dev.bat +1 -1
- package/install-dev.sh +1 -1
- package/package.json +1 -1
- package/src/cmd/push-version.js +20 -9
- package/src/cmd/start.js +5 -2
- package/src/cmd/validate.js +1 -1
- package/src/modules/vegvisir/VegvisirService.js +2 -2
- package/src/service/MiniLog.js +1 -1
- package/src/service/QRCodeFactory.js +1 -1
- package/src/service/Workspace.js +9 -8
- package/src/util/LogUtil.js +14 -0
- package/test/e2e/cli.test.js +54 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
use std::process::exit;
|
|
2
|
+
|
|
3
|
+
use neon::{
|
|
4
|
+
context::{Context, FunctionContext},
|
|
5
|
+
result::JsResult,
|
|
6
|
+
types::JsPromise,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
use crate::{
|
|
10
|
+
infra::async_runtime::runtime,
|
|
11
|
+
services::{eitri_manager, workspace},
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const DIVISOR: &str = "========================================================";
|
|
15
|
+
|
|
16
|
+
pub fn execute(
|
|
17
|
+
mut cx: FunctionContext,
|
|
18
|
+
environment: String,
|
|
19
|
+
message: String,
|
|
20
|
+
) -> JsResult<JsPromise> {
|
|
21
|
+
let init_message = format!("Iniciando publicação de Eitri-App",);
|
|
22
|
+
println!("{DIVISOR}");
|
|
23
|
+
println!("\t{init_message}");
|
|
24
|
+
println!("{DIVISOR}");
|
|
25
|
+
|
|
26
|
+
let rt = match runtime(&mut cx) {
|
|
27
|
+
Ok(rt) => rt,
|
|
28
|
+
Err(_err) => {
|
|
29
|
+
eprintln!("Houve um erro ao criar runtime");
|
|
30
|
+
exit(1);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
let channel = cx.channel();
|
|
35
|
+
|
|
36
|
+
let (deferred, promise) = cx.promise();
|
|
37
|
+
|
|
38
|
+
rt.spawn(async move {
|
|
39
|
+
let eitri_conf = workspace::read_eitri_conf().await;
|
|
40
|
+
let version = eitri_conf.version;
|
|
41
|
+
println!("Versão a ser publicada: {}", version);
|
|
42
|
+
println!("Environment: {}", environment);
|
|
43
|
+
println!("Mensagem: {}", message);
|
|
44
|
+
|
|
45
|
+
let revision = match eitri_manager::get_revision(&eitri_conf.id, &version).await {
|
|
46
|
+
Ok(revision) => revision,
|
|
47
|
+
Err(_err) => {
|
|
48
|
+
eprintln!("Houve um erro ao buscar revisão.");
|
|
49
|
+
exit(1)
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
match eitri_manager::publish_revision(&revision.id, &environment, &message).await {
|
|
53
|
+
Ok(_) => {
|
|
54
|
+
println!("Eitri-App publicado com sucesso!")
|
|
55
|
+
}
|
|
56
|
+
Err(err) => {
|
|
57
|
+
eprintln!("Houve um erro. Error: {:?}", err);
|
|
58
|
+
exit(1)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
deferred.settle_with(&channel, move |mut cx| {
|
|
62
|
+
Ok(cx.string("Eitri-App publicado com sucesso!"))
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
Ok(promise)
|
|
67
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pub mod user_credentials;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
use std::{fs, process::exit};
|
|
2
|
+
|
|
3
|
+
use homedir::get_my_home;
|
|
4
|
+
|
|
5
|
+
use crate::model::credentials::Credentials;
|
|
6
|
+
|
|
7
|
+
pub fn get_credentials() -> Result<Credentials, serde_json::Error> {
|
|
8
|
+
let home_dir = match get_my_home() {
|
|
9
|
+
Ok(dir) => dir,
|
|
10
|
+
Err(_) => {
|
|
11
|
+
eprintln!("Houve um erro ao ler a home do usuário");
|
|
12
|
+
exit(1)
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
let home_dir = match home_dir {
|
|
17
|
+
Some(dir) => dir,
|
|
18
|
+
_ => exit(1),
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
let credentials_file_path = home_dir.join(".eitri").join("prod-eitri.conf.js");
|
|
22
|
+
|
|
23
|
+
let content = match fs::read_to_string(credentials_file_path.to_owned()) {
|
|
24
|
+
Ok(c) => c,
|
|
25
|
+
Err(_) => {
|
|
26
|
+
eprintln!(
|
|
27
|
+
"Houve um erro ao ler credenciais do usuário, certifique-se de ter feito login"
|
|
28
|
+
);
|
|
29
|
+
exit(1)
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
let content = content.replace("module.exports = ", "");
|
|
34
|
+
|
|
35
|
+
let credentials: Credentials = serde_json::from_str(&content)?;
|
|
36
|
+
|
|
37
|
+
Ok(credentials)
|
|
38
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
use neon::{context::Context, result::NeonResult};
|
|
2
|
+
use once_cell::sync::OnceCell;
|
|
3
|
+
use tokio::runtime::Runtime;
|
|
4
|
+
|
|
5
|
+
pub fn runtime<'a, C: Context<'a>>(cx: &mut C) -> NeonResult<&'static Runtime> {
|
|
6
|
+
static RUNTIME: OnceCell<Runtime> = OnceCell::new();
|
|
7
|
+
|
|
8
|
+
RUNTIME.get_or_try_init(|| Runtime::new().or_else(|err| cx.throw_error(err.to_string())))
|
|
9
|
+
}
|
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
// use std::sync::Arc;
|
|
2
|
+
|
|
3
|
+
use reqwest::{header::HeaderMap, multipart::Form, Client};
|
|
4
|
+
use serde::de::DeserializeOwned;
|
|
5
|
+
use serde::Serialize;
|
|
6
|
+
use serde_derive::Deserialize;
|
|
7
|
+
|
|
8
|
+
// use crate::services::vegvisir::get_workspace;
|
|
9
|
+
|
|
10
|
+
// use super::cookie::{get_cookie, write_cookie};
|
|
11
|
+
|
|
12
|
+
#[allow(dead_code)]
|
|
13
|
+
#[derive(Debug, Deserialize)]
|
|
14
|
+
pub struct ApiError {
|
|
15
|
+
pub message: String,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
#[allow(dead_code)]
|
|
19
|
+
#[derive(Debug)]
|
|
20
|
+
pub enum HttpError {
|
|
21
|
+
HttpError(reqwest::StatusCode, ApiError),
|
|
22
|
+
Deserialize(reqwest::Error),
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
#[allow(dead_code)]
|
|
26
|
+
pub async fn post<T, U>(url: &str, data: U, headers: HeaderMap) -> Result<T, HttpError>
|
|
27
|
+
where
|
|
28
|
+
T: DeserializeOwned,
|
|
29
|
+
U: Serialize,
|
|
30
|
+
{
|
|
31
|
+
let client = get_client(url);
|
|
32
|
+
|
|
33
|
+
let response = client
|
|
34
|
+
.post(url)
|
|
35
|
+
.headers(headers)
|
|
36
|
+
.json(&data)
|
|
37
|
+
.send()
|
|
38
|
+
.await
|
|
39
|
+
.map_err(HttpError::Deserialize)?;
|
|
40
|
+
|
|
41
|
+
if response.status().is_success() {
|
|
42
|
+
// write_cookie(&response.headers(), &url);
|
|
43
|
+
return response.json().await.map_err(HttpError::Deserialize);
|
|
44
|
+
}
|
|
45
|
+
let status = response.status();
|
|
46
|
+
let mensagem = response
|
|
47
|
+
.text()
|
|
48
|
+
.await
|
|
49
|
+
.unwrap_or_else(|_| String::from("Erro desconhecido"));
|
|
50
|
+
let api_error: ApiError = serde_json::from_str(&mensagem).unwrap_or_else(|_| ApiError {
|
|
51
|
+
message: String::from("Erro ao relizar parse do JSON"),
|
|
52
|
+
});
|
|
53
|
+
Err(HttpError::HttpError(status, api_error))
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
#[allow(dead_code)]
|
|
57
|
+
pub async fn post_form_data<T>(url: &str, data: Form, headers: HeaderMap) -> Result<T, HttpError>
|
|
58
|
+
where
|
|
59
|
+
T: DeserializeOwned,
|
|
60
|
+
{
|
|
61
|
+
let client = get_client(url);
|
|
62
|
+
|
|
63
|
+
let response = client
|
|
64
|
+
.post(url)
|
|
65
|
+
.headers(headers)
|
|
66
|
+
.multipart(data)
|
|
67
|
+
.send()
|
|
68
|
+
.await
|
|
69
|
+
.map_err(HttpError::Deserialize)?;
|
|
70
|
+
|
|
71
|
+
if response.status().is_success() {
|
|
72
|
+
// write_cookie(&response.headers(), &url);
|
|
73
|
+
return response.json().await.map_err(HttpError::Deserialize);
|
|
74
|
+
}
|
|
75
|
+
let status = response.status();
|
|
76
|
+
let mensagem = response
|
|
77
|
+
.text()
|
|
78
|
+
.await
|
|
79
|
+
.unwrap_or_else(|_| String::from("Erro desconhecido"));
|
|
80
|
+
let api_error: ApiError = serde_json::from_str(&mensagem).unwrap_or_else(|_| ApiError {
|
|
81
|
+
message: String::from("Erro ao relizar parse do JSON"),
|
|
82
|
+
});
|
|
83
|
+
Err(HttpError::HttpError(status, api_error))
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
#[allow(dead_code)]
|
|
87
|
+
pub async fn get<T>(url: &str, headers: HeaderMap) -> Result<T, HttpError>
|
|
88
|
+
where
|
|
89
|
+
T: DeserializeOwned,
|
|
90
|
+
{
|
|
91
|
+
let client = get_client(url);
|
|
92
|
+
|
|
93
|
+
let response = client
|
|
94
|
+
.get(url)
|
|
95
|
+
.headers(headers)
|
|
96
|
+
.send()
|
|
97
|
+
.await
|
|
98
|
+
.map_err(HttpError::Deserialize)?;
|
|
99
|
+
|
|
100
|
+
if response.status().is_success() {
|
|
101
|
+
// write_cookie(&response.headers(), &url);
|
|
102
|
+
return response.json().await.map_err(HttpError::Deserialize);
|
|
103
|
+
}
|
|
104
|
+
let status = response.status();
|
|
105
|
+
let mensagem = response
|
|
106
|
+
.text()
|
|
107
|
+
.await
|
|
108
|
+
.unwrap_or_else(|_| String::from("Erro desconhecido"));
|
|
109
|
+
let api_error: ApiError = serde_json::from_str(&mensagem).unwrap_or_else(|_| ApiError {
|
|
110
|
+
message: String::from("Erro ao relizar parse do JSON"),
|
|
111
|
+
});
|
|
112
|
+
Err(HttpError::HttpError(status, api_error))
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
#[allow(dead_code)]
|
|
116
|
+
pub async fn put<U>(url: &str, data: U, headers: HeaderMap) -> Result<String, HttpError>
|
|
117
|
+
where
|
|
118
|
+
U: Serialize,
|
|
119
|
+
{
|
|
120
|
+
let client = get_client(url);
|
|
121
|
+
|
|
122
|
+
let response = client
|
|
123
|
+
.put(url)
|
|
124
|
+
.headers(headers)
|
|
125
|
+
.json(&data)
|
|
126
|
+
.send()
|
|
127
|
+
.await
|
|
128
|
+
.map_err(HttpError::Deserialize)?;
|
|
129
|
+
|
|
130
|
+
if response.status().is_success() {
|
|
131
|
+
// write_cookie(&response.headers(), &url);
|
|
132
|
+
return response.text().await.map_err(HttpError::Deserialize);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
let status = response.status();
|
|
136
|
+
let mensagem = response
|
|
137
|
+
.text()
|
|
138
|
+
.await
|
|
139
|
+
.unwrap_or_else(|_| String::from("Erro desconhecido"));
|
|
140
|
+
let api_error: ApiError = serde_json::from_str(&mensagem).unwrap_or_else(|_| ApiError {
|
|
141
|
+
message: String::from("Erro ao relizar parse do JSON"),
|
|
142
|
+
});
|
|
143
|
+
Err(HttpError::HttpError(status, api_error))
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
#[allow(dead_code)]
|
|
147
|
+
pub async fn delete(url: &str, headers: HeaderMap) -> Result<(), HttpError> {
|
|
148
|
+
let client = get_client(url);
|
|
149
|
+
|
|
150
|
+
let response = client
|
|
151
|
+
.delete(url)
|
|
152
|
+
.headers(headers)
|
|
153
|
+
.send()
|
|
154
|
+
.await
|
|
155
|
+
.map_err(HttpError::Deserialize)?;
|
|
156
|
+
|
|
157
|
+
if response.status().is_success() {
|
|
158
|
+
// write_cookie(&response.headers(), &url);
|
|
159
|
+
return Ok(());
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
let status = response.status();
|
|
163
|
+
let mensagem = response
|
|
164
|
+
.text()
|
|
165
|
+
.await
|
|
166
|
+
.unwrap_or_else(|_| String::from("Erro desconhecido"));
|
|
167
|
+
let api_error: ApiError = serde_json::from_str(&mensagem).unwrap_or_else(|_| ApiError {
|
|
168
|
+
message: String::from("Erro ao relizar parse do JSON"),
|
|
169
|
+
});
|
|
170
|
+
Err(HttpError::HttpError(status, api_error))
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
#[allow(dead_code)]
|
|
174
|
+
pub async fn get_default_headers(token: String) -> HeaderMap {
|
|
175
|
+
let mut headers = HeaderMap::new();
|
|
176
|
+
|
|
177
|
+
// let workspace = get_workspace().await;
|
|
178
|
+
|
|
179
|
+
headers.append("Authorization", token.parse().unwrap());
|
|
180
|
+
// headers.append("Workspace-Id", workspace.id.parse().unwrap());
|
|
181
|
+
|
|
182
|
+
headers
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
#[allow(dead_code, unused_variables)]
|
|
186
|
+
fn get_client(request_url: &str) -> Client {
|
|
187
|
+
// let jar = get_cookie(request_url).unwrap_or_else(|| panic!("Error ao ler cookie"));
|
|
188
|
+
Client::builder()
|
|
189
|
+
.cookie_store(true)
|
|
190
|
+
// .cookie_provider(Arc::from(jar))
|
|
191
|
+
.build()
|
|
192
|
+
.unwrap()
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
#[cfg(test)]
|
|
196
|
+
mod tests {
|
|
197
|
+
use std::env;
|
|
198
|
+
|
|
199
|
+
use super::*;
|
|
200
|
+
use httpmock::prelude::*;
|
|
201
|
+
use reqwest::multipart;
|
|
202
|
+
use serde_derive::{Deserialize, Serialize};
|
|
203
|
+
use serde_json::json;
|
|
204
|
+
|
|
205
|
+
#[derive(Deserialize)]
|
|
206
|
+
struct Response {
|
|
207
|
+
#[serde(rename = "resultCount")]
|
|
208
|
+
result_count: i32,
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
#[derive(Deserialize)]
|
|
212
|
+
#[serde(rename_all = "camelCase")]
|
|
213
|
+
struct AuthResponse {
|
|
214
|
+
status: String,
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
#[derive(Deserialize, Serialize)]
|
|
218
|
+
struct UpdateData {
|
|
219
|
+
status: String,
|
|
220
|
+
email: String,
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
#[derive(Deserialize)]
|
|
224
|
+
struct FileUploadResponse {
|
|
225
|
+
ok: bool,
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
#[derive(Serialize, Deserialize)]
|
|
229
|
+
struct FakeAuth {
|
|
230
|
+
client_id: String,
|
|
231
|
+
client_secret: String,
|
|
232
|
+
grant_type: String,
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
#[derive(Deserialize)]
|
|
236
|
+
struct VoidResult {}
|
|
237
|
+
|
|
238
|
+
#[tokio::test]
|
|
239
|
+
async fn test_http_post_success() {
|
|
240
|
+
let mut headers = HeaderMap::new();
|
|
241
|
+
headers.append("user-agent", "eitri".parse().unwrap());
|
|
242
|
+
|
|
243
|
+
let client_id = env::var("EITRI_CLI_CLIENT_ID").unwrap();
|
|
244
|
+
let client_secret = env::var("EITRI_CLI_CLIENT_SECRET").unwrap();
|
|
245
|
+
|
|
246
|
+
let data = FakeAuth {
|
|
247
|
+
client_id,
|
|
248
|
+
client_secret,
|
|
249
|
+
grant_type: String::from("client_credentials"),
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
match post::<AuthResponse, FakeAuth>(
|
|
253
|
+
"https://api.eitri.tech/blind-guardian-api/v1/o/auth",
|
|
254
|
+
data,
|
|
255
|
+
headers,
|
|
256
|
+
)
|
|
257
|
+
.await
|
|
258
|
+
{
|
|
259
|
+
Ok(result) => {
|
|
260
|
+
assert_eq!(result.status, "ACTIVE");
|
|
261
|
+
}
|
|
262
|
+
Err(error) => match error {
|
|
263
|
+
HttpError::HttpError(_, error) => {
|
|
264
|
+
panic!("{}", error.message)
|
|
265
|
+
}
|
|
266
|
+
HttpError::Deserialize(error) => {
|
|
267
|
+
panic!("{:?}", error)
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
#[tokio::test]
|
|
274
|
+
async fn test_http_post_form_data_success() {
|
|
275
|
+
let mut headers = HeaderMap::new();
|
|
276
|
+
headers.append("user-agent", "eitri".parse().unwrap());
|
|
277
|
+
headers.append(
|
|
278
|
+
"Workspace-Id",
|
|
279
|
+
"3c42595c-3da6-475f-a843-5f65cd1982e6".parse().unwrap(),
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
let form = multipart::Form::new();
|
|
283
|
+
|
|
284
|
+
let form = form.text("filepath", "src/views/Home.jsx");
|
|
285
|
+
|
|
286
|
+
let part = multipart::Part::bytes("export default function Home {}".as_bytes())
|
|
287
|
+
.file_name("Home")
|
|
288
|
+
.mime_str("text/plain");
|
|
289
|
+
|
|
290
|
+
let part_result = match part {
|
|
291
|
+
Ok(result) => result,
|
|
292
|
+
Err(_) => {
|
|
293
|
+
panic!("Erro ao construir part")
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
let form = form.part("file", part_result);
|
|
297
|
+
|
|
298
|
+
let server = MockServer::start();
|
|
299
|
+
|
|
300
|
+
server.mock(|when, then| {
|
|
301
|
+
when.method(POST).path("/runes-foundry/fileupload");
|
|
302
|
+
then.status(200)
|
|
303
|
+
.header("content-type", "application/json; charset=UTF-8")
|
|
304
|
+
.body(
|
|
305
|
+
json!({
|
|
306
|
+
"ok": true
|
|
307
|
+
})
|
|
308
|
+
.to_string()
|
|
309
|
+
.as_bytes(),
|
|
310
|
+
);
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
match post_form_data::<FileUploadResponse>(
|
|
314
|
+
&server.url("/runes-foundry/fileupload"),
|
|
315
|
+
form,
|
|
316
|
+
headers,
|
|
317
|
+
)
|
|
318
|
+
.await
|
|
319
|
+
{
|
|
320
|
+
Ok(result) => {
|
|
321
|
+
assert!(result.ok);
|
|
322
|
+
}
|
|
323
|
+
Err(error) => match error {
|
|
324
|
+
HttpError::HttpError(_, error) => {
|
|
325
|
+
panic!("{}", error.message)
|
|
326
|
+
}
|
|
327
|
+
HttpError::Deserialize(error) => {
|
|
328
|
+
panic!("{:?}", error)
|
|
329
|
+
}
|
|
330
|
+
},
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
#[tokio::test]
|
|
335
|
+
async fn test_http_get_success() {
|
|
336
|
+
let mut headers = HeaderMap::new();
|
|
337
|
+
headers.append("user-agent", "eitri".parse().unwrap());
|
|
338
|
+
let result: Result<Response, HttpError> =
|
|
339
|
+
get("https://calindra.tech/eitri/product_list.json", headers).await;
|
|
340
|
+
assert!(result.is_ok());
|
|
341
|
+
let data = result.unwrap();
|
|
342
|
+
assert_eq!(6, data.result_count);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
#[tokio::test]
|
|
346
|
+
async fn test_http_get_error_unauthorized() {
|
|
347
|
+
let mut headers = HeaderMap::new();
|
|
348
|
+
headers.append("user-agent", "eitri".parse().unwrap());
|
|
349
|
+
|
|
350
|
+
match get::<Response>(
|
|
351
|
+
"https://api.eitri.tech/eitri-manager-api/eitri-apps",
|
|
352
|
+
headers,
|
|
353
|
+
)
|
|
354
|
+
.await
|
|
355
|
+
{
|
|
356
|
+
Ok(_) => {}
|
|
357
|
+
Err(erro) => match erro {
|
|
358
|
+
HttpError::HttpError(status, error) => {
|
|
359
|
+
assert_eq!(status, 401);
|
|
360
|
+
assert_eq!(error.message, "JWT missing.")
|
|
361
|
+
}
|
|
362
|
+
HttpError::Deserialize(error) => {
|
|
363
|
+
panic!("{:?}", error)
|
|
364
|
+
}
|
|
365
|
+
},
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
#[tokio::test]
|
|
370
|
+
async fn test_http_get_error_forbidden_with_xml_response() {
|
|
371
|
+
let mut headers = HeaderMap::new();
|
|
372
|
+
headers.append("user-agent", "eitri".parse().unwrap());
|
|
373
|
+
match get::<Response>("https://calindra.tech/eitri/product_listx.json", headers).await {
|
|
374
|
+
Ok(_) => {}
|
|
375
|
+
Err(erro) => match erro {
|
|
376
|
+
HttpError::HttpError(status, _) => {
|
|
377
|
+
assert_eq!(status, 403)
|
|
378
|
+
}
|
|
379
|
+
HttpError::Deserialize(error) => {
|
|
380
|
+
panic!("{:?}", error)
|
|
381
|
+
}
|
|
382
|
+
},
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
#[tokio::test]
|
|
387
|
+
async fn test_http_put_success() {
|
|
388
|
+
let mut headers = HeaderMap::new();
|
|
389
|
+
headers.append("user-agent", "eitri".parse().unwrap());
|
|
390
|
+
|
|
391
|
+
let email = String::from("foobar@mail.com");
|
|
392
|
+
|
|
393
|
+
let data = UpdateData {
|
|
394
|
+
status: String::from("ACTIVE"),
|
|
395
|
+
email,
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
let server = MockServer::start();
|
|
399
|
+
|
|
400
|
+
server.mock(|when, then| {
|
|
401
|
+
when.method(PUT).path("/blind-guardian-api/v1/p/users/self");
|
|
402
|
+
then.status(200)
|
|
403
|
+
.header("content-type", "application/json; charset=UTF-8")
|
|
404
|
+
.body(
|
|
405
|
+
json!({
|
|
406
|
+
"status": "ACTIVE",
|
|
407
|
+
"email": "foobar@gmail.com"
|
|
408
|
+
})
|
|
409
|
+
.to_string()
|
|
410
|
+
.as_bytes(),
|
|
411
|
+
);
|
|
412
|
+
});
|
|
413
|
+
match put::<UpdateData>(
|
|
414
|
+
&format!("{}/blind-guardian-api/v1/p/users/self", server.url("")),
|
|
415
|
+
data,
|
|
416
|
+
headers,
|
|
417
|
+
)
|
|
418
|
+
.await
|
|
419
|
+
{
|
|
420
|
+
Ok(_) => {}
|
|
421
|
+
Err(error) => match error {
|
|
422
|
+
HttpError::HttpError(_, error) => {
|
|
423
|
+
panic!("{}", error.message)
|
|
424
|
+
}
|
|
425
|
+
HttpError::Deserialize(error) => {
|
|
426
|
+
panic!("{:?}", error)
|
|
427
|
+
}
|
|
428
|
+
},
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
#[tokio::test]
|
|
433
|
+
async fn test_http_delete_success() {
|
|
434
|
+
let mut headers = HeaderMap::new();
|
|
435
|
+
headers.append("user-agent", "eitri".parse().unwrap());
|
|
436
|
+
headers.append(
|
|
437
|
+
"Workspace-Id",
|
|
438
|
+
"3c42595c-3da6-475f-a843-5f65cd1982e6".parse().unwrap(),
|
|
439
|
+
);
|
|
440
|
+
headers.append(
|
|
441
|
+
"Authorization",
|
|
442
|
+
"3c42595c-3da6-475f-a843-5f65cd1982e6".parse().unwrap(),
|
|
443
|
+
);
|
|
444
|
+
|
|
445
|
+
let server = MockServer::start();
|
|
446
|
+
|
|
447
|
+
server.mock(|when, then| {
|
|
448
|
+
when.method(DELETE).path("/runes-foundry/sources");
|
|
449
|
+
then.status(200)
|
|
450
|
+
.header("content-type", "application/json; charset=UTF-8")
|
|
451
|
+
.body(json!({}).to_string().as_bytes());
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
match delete(&server.url("/runes-foundry/sources"), headers).await {
|
|
455
|
+
Ok(_) => {}
|
|
456
|
+
Err(error) => match error {
|
|
457
|
+
HttpError::HttpError(_, error) => {
|
|
458
|
+
panic!("{}", error.message)
|
|
459
|
+
}
|
|
460
|
+
HttpError::Deserialize(error) => {
|
|
461
|
+
panic!("{:?}", error)
|
|
462
|
+
}
|
|
463
|
+
},
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
#[tokio::test]
|
|
468
|
+
async fn test_http_client_should_receive_cookies() {
|
|
469
|
+
let url = "https://api.eitri.tech/runes-foundry/health";
|
|
470
|
+
let client = get_client(url);
|
|
471
|
+
|
|
472
|
+
let response = client
|
|
473
|
+
.get(url)
|
|
474
|
+
.send()
|
|
475
|
+
.await
|
|
476
|
+
.unwrap_or_else(|_| panic!("Erro inesperado"));
|
|
477
|
+
|
|
478
|
+
let mut cookies = response.cookies();
|
|
479
|
+
|
|
480
|
+
let stick_cookie = cookies.find(|c| c.name() == "stick_runes_foundry").unwrap();
|
|
481
|
+
|
|
482
|
+
assert_eq!(stick_cookie.name(), "stick_runes_foundry");
|
|
483
|
+
}
|
|
484
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
use std::process::exit;
|
|
2
|
+
|
|
3
|
+
use neon::prelude::*;
|
|
4
|
+
mod commands;
|
|
5
|
+
mod config;
|
|
6
|
+
mod infra;
|
|
7
|
+
mod model;
|
|
8
|
+
mod services;
|
|
9
|
+
mod utils;
|
|
10
|
+
fn publish(mut cx: FunctionContext) -> JsResult<JsPromise> {
|
|
11
|
+
let environment = match cx.argument::<JsString>(0) {
|
|
12
|
+
Ok(v) => v.value(&mut cx),
|
|
13
|
+
Err(_err) => {
|
|
14
|
+
eprintln!(
|
|
15
|
+
"É necessário passar como parâmetro o ID do environment para publicar a versão.",
|
|
16
|
+
);
|
|
17
|
+
exit(1);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
let message = match cx.argument::<JsString>(1) {
|
|
22
|
+
Ok(v) => v.value(&mut cx),
|
|
23
|
+
Err(_err) => String::from(""),
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
let promise = commands::publish::execute(cx, environment, message);
|
|
27
|
+
|
|
28
|
+
match promise {
|
|
29
|
+
Ok(promise) => Ok(promise),
|
|
30
|
+
Err(_err) => {
|
|
31
|
+
eprintln!("Houve um erro inesperado ao executar o comando publish, por favor, tente novamente.");
|
|
32
|
+
exit(1)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
#[neon::main]
|
|
38
|
+
fn main(mut cx: ModuleContext) -> NeonResult<()> {
|
|
39
|
+
cx.export_function("publish", publish)?;
|
|
40
|
+
Ok(())
|
|
41
|
+
}
|