@devaloop/devalang 0.0.1-alpha.15 → 0.0.1-alpha.16
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/.devalang +2 -0
- package/.github/workflows/ci.yml +92 -0
- package/Cargo.toml +60 -58
- package/README.md +1 -1
- package/docs/CHANGELOG.md +34 -1
- package/docs/CONTRIBUTING.md +101 -1
- package/docs/ROADMAP.md +1 -1
- package/docs/TODO.md +1 -1
- package/examples/automation.deva +1 -3
- package/examples/bank.deva +4 -4
- package/examples/events.deva +12 -0
- package/examples/function.deva +4 -4
- package/examples/index.deva +3 -5
- package/examples/loop.deva +5 -11
- package/examples/pattern.deva +8 -0
- package/examples/plugin.deva +12 -11
- package/examples/variables.deva +1 -1
- package/out-tsc/bin/index.js +51 -7
- package/out-tsc/index.js +3 -1
- package/out-tsc/scripts/postbuild.js +9 -10
- package/out-tsc/scripts/postinstall.js +49 -0
- package/package.json +12 -4
- package/project-version.json +3 -3
- package/rust/cli/bank.rs +462 -455
- package/rust/cli/build.rs +252 -199
- package/rust/cli/check.rs +221 -180
- package/rust/cli/driver.rs +297 -292
- package/rust/cli/generator.rs +1 -0
- package/rust/cli/init.rs +87 -79
- package/rust/cli/install.rs +35 -32
- package/rust/cli/login.rs +127 -134
- package/rust/cli/mod.rs +13 -11
- package/rust/cli/play.rs +1123 -218
- package/rust/cli/telemetry.rs +19 -0
- package/rust/cli/template.rs +69 -57
- package/rust/cli/update.rs +6 -4
- package/rust/common/api.rs +5 -5
- package/rust/common/mod.rs +3 -3
- package/rust/config/driver.rs +118 -94
- package/rust/config/loader.rs +165 -156
- package/rust/config/mod.rs +4 -2
- package/rust/config/settings.rs +91 -0
- package/rust/config/stats.rs +257 -0
- package/rust/core/audio/engine.rs +696 -659
- package/rust/core/audio/evaluator.rs +263 -132
- package/rust/core/audio/interpreter/arrow_call.rs +198 -187
- package/rust/core/audio/interpreter/call.rs +98 -95
- package/rust/core/audio/interpreter/condition.rs +70 -71
- package/rust/core/audio/interpreter/driver.rs +487 -231
- package/rust/core/audio/interpreter/function.rs +26 -21
- package/rust/core/audio/interpreter/let_.rs +38 -26
- package/rust/core/audio/interpreter/load.rs +18 -18
- package/rust/core/audio/interpreter/loop_.rs +113 -106
- package/rust/core/audio/interpreter/mod.rs +14 -14
- package/rust/core/audio/interpreter/sleep.rs +27 -28
- package/rust/core/audio/interpreter/spawn.rs +105 -102
- package/rust/core/audio/interpreter/tempo.rs +19 -16
- package/rust/core/audio/interpreter/trigger.rs +239 -210
- package/rust/core/audio/loader/mod.rs +1 -1
- package/rust/core/audio/loader/trigger.rs +100 -94
- package/rust/core/audio/mod.rs +7 -7
- package/rust/core/audio/player.rs +64 -64
- package/rust/core/audio/renderer.rs +56 -53
- package/rust/core/audio/special/easing.rs +189 -120
- package/rust/core/audio/special/env.rs +43 -41
- package/rust/core/audio/special/math.rs +102 -92
- package/rust/core/audio/special/mod.rs +9 -9
- package/rust/core/audio/special/modulator.rs +143 -120
- package/rust/core/builder/mod.rs +80 -85
- package/rust/core/debugger/lexer.rs +27 -27
- package/rust/core/debugger/mod.rs +24 -23
- package/rust/core/debugger/module.rs +55 -47
- package/rust/core/debugger/preprocessor.rs +27 -27
- package/rust/core/debugger/store.rs +40 -39
- package/rust/core/error/mod.rs +80 -69
- package/rust/core/lexer/handler/arrow.rs +82 -82
- package/rust/core/lexer/handler/at.rs +21 -21
- package/rust/core/lexer/handler/brace.rs +41 -41
- package/rust/core/lexer/handler/colon.rs +21 -21
- package/rust/core/lexer/handler/comment.rs +30 -30
- package/rust/core/lexer/handler/dot.rs +21 -21
- package/rust/core/lexer/handler/driver.rs +337 -292
- package/rust/core/lexer/handler/identifier.rs +46 -43
- package/rust/core/lexer/handler/indent.rs +66 -66
- package/rust/core/lexer/handler/mod.rs +16 -16
- package/rust/core/lexer/handler/newline.rs +23 -23
- package/rust/core/lexer/handler/number.rs +31 -31
- package/rust/core/lexer/handler/operator.rs +46 -46
- package/rust/core/lexer/handler/parenthesis.rs +41 -41
- package/rust/core/lexer/handler/slash.rs +21 -21
- package/rust/core/lexer/handler/string.rs +63 -63
- package/rust/core/lexer/mod.rs +54 -51
- package/rust/core/lexer/token.rs +97 -94
- package/rust/core/mod.rs +11 -11
- package/rust/core/parser/driver.rs +513 -490
- package/rust/core/parser/handler/arrow_call.rs +233 -227
- package/rust/core/parser/handler/at.rs +245 -162
- package/rust/core/parser/handler/bank.rs +94 -69
- package/rust/core/parser/handler/condition.rs +80 -74
- package/rust/core/parser/handler/dot.rs +143 -135
- package/rust/core/parser/handler/identifier/automate.rs +257 -194
- package/rust/core/parser/handler/identifier/call.rs +91 -88
- package/rust/core/parser/handler/identifier/emit.rs +66 -0
- package/rust/core/parser/handler/identifier/function.rs +100 -91
- package/rust/core/parser/handler/identifier/group.rs +85 -75
- package/rust/core/parser/handler/identifier/let_.rs +158 -143
- package/rust/core/parser/handler/identifier/mod.rs +54 -56
- package/rust/core/parser/handler/identifier/on.rs +98 -0
- package/rust/core/parser/handler/identifier/print.rs +52 -29
- package/rust/core/parser/handler/identifier/sleep.rs +36 -33
- package/rust/core/parser/handler/identifier/spawn.rs +91 -88
- package/rust/core/parser/handler/identifier/synth.rs +65 -63
- package/rust/core/parser/handler/loop_.rs +170 -89
- package/rust/core/parser/handler/mod.rs +8 -8
- package/rust/core/parser/handler/tempo.rs +53 -47
- package/rust/core/parser/mod.rs +4 -4
- package/rust/core/parser/statement.rs +142 -113
- package/rust/core/plugin/loader.rs +123 -48
- package/rust/core/plugin/mod.rs +2 -1
- package/rust/core/plugin/runner.rs +296 -0
- package/rust/core/preprocessor/loader.rs +515 -326
- package/rust/core/preprocessor/mod.rs +4 -4
- package/rust/core/preprocessor/module.rs +60 -58
- package/rust/core/preprocessor/processor.rs +99 -101
- package/rust/core/preprocessor/resolver/bank.rs +51 -48
- package/rust/core/preprocessor/resolver/call.rs +100 -101
- package/rust/core/preprocessor/resolver/condition.rs +97 -97
- package/rust/core/preprocessor/resolver/driver.rs +310 -280
- package/rust/core/preprocessor/resolver/function.rs +69 -68
- package/rust/core/preprocessor/resolver/group.rs +96 -91
- package/rust/core/preprocessor/resolver/let_.rs +32 -28
- package/rust/core/preprocessor/resolver/loop_.rs +320 -121
- package/rust/core/preprocessor/resolver/mod.rs +15 -15
- package/rust/core/preprocessor/resolver/spawn.rs +76 -73
- package/rust/core/preprocessor/resolver/synth.rs +56 -50
- package/rust/core/preprocessor/resolver/tempo.rs +50 -49
- package/rust/core/preprocessor/resolver/trigger.rs +113 -115
- package/rust/core/preprocessor/resolver/value.rs +81 -81
- package/rust/core/shared/duration.rs +9 -9
- package/rust/core/shared/mod.rs +3 -3
- package/rust/core/shared/value.rs +35 -32
- package/rust/core/store/function.rs +34 -34
- package/rust/core/store/global.rs +55 -38
- package/rust/core/store/mod.rs +5 -5
- package/rust/core/store/variable.rs +37 -34
- package/rust/core/utils/mod.rs +2 -2
- package/rust/core/utils/path.rs +37 -31
- package/rust/core/utils/validation.rs +35 -36
- package/rust/installer/addon.rs +84 -80
- package/rust/installer/bank.rs +62 -65
- package/rust/installer/mod.rs +5 -5
- package/rust/installer/plugin.rs +54 -55
- package/rust/installer/utils.rs +56 -56
- package/rust/lib.rs +156 -164
- package/rust/main.rs +250 -144
- package/rust/utils/error.rs +200 -51
- package/rust/utils/file.rs +38 -35
- package/rust/utils/first_usage.rs +76 -0
- package/rust/utils/logger.rs +195 -143
- package/rust/utils/mod.rs +9 -7
- package/rust/utils/signature.rs +19 -17
- package/rust/utils/spinner.rs +22 -19
- package/rust/utils/telemetry.rs +292 -0
- package/rust/utils/watcher.rs +34 -33
- package/templates/minimal/README.md +97 -121
- package/templates/welcome/README.md +97 -121
- package/typescript/bin/index.ts +19 -5
- package/typescript/index.ts +3 -1
- package/typescript/scripts/postbuild.ts +10 -6
- package/typescript/scripts/postinstall.ts +56 -0
- package/typescript/scripts/version/bump.ts +0 -1
- package/typescript/scripts/version/index.ts +0 -1
- package/out-tsc/bin/devalang.exe +0 -0
package/rust/cli/init.rs
CHANGED
|
@@ -1,79 +1,87 @@
|
|
|
1
|
-
use
|
|
2
|
-
use include_dir::{ include_dir
|
|
3
|
-
use
|
|
4
|
-
|
|
5
|
-
#[cfg(feature = "cli")]
|
|
6
|
-
use inquire::{ Select
|
|
7
|
-
|
|
8
|
-
static TEMPLATES_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/templates");
|
|
9
|
-
|
|
10
|
-
#[cfg(feature = "cli")]
|
|
11
|
-
pub fn handle_init_command(name: Option<String>, template: Option<String>) {
|
|
12
|
-
let current_dir = std::env::current_dir().unwrap();
|
|
13
|
-
let project_name = name
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
1
|
+
use crate::{cli::template::get_available_templates, utils::file::copy_dir_recursive};
|
|
2
|
+
use include_dir::{Dir, include_dir};
|
|
3
|
+
use std::{fs, path::Path};
|
|
4
|
+
|
|
5
|
+
#[cfg(feature = "cli")]
|
|
6
|
+
use inquire::{Confirm, Select};
|
|
7
|
+
|
|
8
|
+
static TEMPLATES_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/templates");
|
|
9
|
+
|
|
10
|
+
#[cfg(feature = "cli")]
|
|
11
|
+
pub fn handle_init_command(name: Option<String>, template: Option<String>) {
|
|
12
|
+
let current_dir = std::env::current_dir().unwrap();
|
|
13
|
+
let project_name = name.clone().unwrap_or_else(|| {
|
|
14
|
+
current_dir
|
|
15
|
+
.file_name()
|
|
16
|
+
.unwrap_or_default()
|
|
17
|
+
.to_string_lossy()
|
|
18
|
+
.to_string()
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Select a template if not provided
|
|
22
|
+
let selected_template = template.unwrap_or_else(|| {
|
|
23
|
+
Select::new(
|
|
24
|
+
"Select a template for your project:",
|
|
25
|
+
get_available_templates(),
|
|
26
|
+
)
|
|
27
|
+
.prompt()
|
|
28
|
+
.unwrap_or_else(|_| {
|
|
29
|
+
eprintln!("No template selected. Exiting...");
|
|
30
|
+
std::process::exit(1);
|
|
31
|
+
})
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
if selected_template.is_empty() {
|
|
35
|
+
eprintln!("Template cannot be empty.");
|
|
36
|
+
std::process::exit(1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if name.is_none() {
|
|
40
|
+
// Case of initialization in the current directory
|
|
41
|
+
if fs::read_dir(¤t_dir).unwrap().next().is_some() {
|
|
42
|
+
let confirm =
|
|
43
|
+
Confirm::new("The current directory is not empty. Do you want to continue?")
|
|
44
|
+
.with_default(false)
|
|
45
|
+
.prompt()
|
|
46
|
+
.unwrap_or(false);
|
|
47
|
+
|
|
48
|
+
if !confirm {
|
|
49
|
+
eprintln!("Operation cancelled by the user.");
|
|
50
|
+
std::process::exit(0);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
scaffold_project_current_dir(current_dir.as_path(), selected_template);
|
|
55
|
+
println!(
|
|
56
|
+
"✅ Initialized '{}' project in current directory: {}",
|
|
57
|
+
project_name,
|
|
58
|
+
current_dir.display()
|
|
59
|
+
);
|
|
60
|
+
} else {
|
|
61
|
+
// Case of initialization in a new directory
|
|
62
|
+
let target_path = current_dir.join(&project_name);
|
|
63
|
+
|
|
64
|
+
if target_path.exists() {
|
|
65
|
+
eprintln!("❌ A folder named '{}' already exists.", project_name);
|
|
66
|
+
std::process::exit(1);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
fs::create_dir_all(&target_path).expect("Error creating project directory");
|
|
70
|
+
|
|
71
|
+
scaffold_project_current_dir(&target_path, selected_template);
|
|
72
|
+
println!(
|
|
73
|
+
"✅ Initialized '{}' project in: {}",
|
|
74
|
+
project_name,
|
|
75
|
+
target_path.display()
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
fn scaffold_project_current_dir(path: &Path, template: String) {
|
|
81
|
+
let template_dir = TEMPLATES_DIR.get_dir(&template).unwrap_or_else(|| {
|
|
82
|
+
eprintln!("❌ The template '{}' doesn't exist.", template);
|
|
83
|
+
std::process::exit(1);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
copy_dir_recursive(template_dir, path, &template_dir.path());
|
|
87
|
+
}
|
package/rust/cli/install.rs
CHANGED
|
@@ -1,32 +1,35 @@
|
|
|
1
|
-
use crate::installer::addon::{ install_addon
|
|
2
|
-
|
|
3
|
-
/// Handles the installation command for a given addon type and name.
|
|
4
|
-
#[cfg(feature = "cli")]
|
|
5
|
-
pub async fn handle_install_command(name: String, addon_type: AddonType) -> Result<(), String> {
|
|
6
|
-
use crate::utils::{
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
let
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
1
|
+
use crate::installer::addon::{AddonType, install_addon};
|
|
2
|
+
|
|
3
|
+
/// Handles the installation command for a given addon type and name.
|
|
4
|
+
#[cfg(feature = "cli")]
|
|
5
|
+
pub async fn handle_install_command(name: String, addon_type: AddonType) -> Result<(), String> {
|
|
6
|
+
use crate::utils::{
|
|
7
|
+
logger::{LogLevel, Logger},
|
|
8
|
+
spinner::with_spinner,
|
|
9
|
+
};
|
|
10
|
+
use std::{thread, time::Duration};
|
|
11
|
+
|
|
12
|
+
let logger = Logger::new();
|
|
13
|
+
let deva_dir = std::path::Path::new("./.deva/");
|
|
14
|
+
|
|
15
|
+
let spinner = with_spinner("Installing...", || {
|
|
16
|
+
thread::sleep(Duration::from_millis(800));
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
if let Err(e) = install_addon(addon_type.clone(), name.as_str(), deva_dir).await {
|
|
20
|
+
spinner.finish_and_clear();
|
|
21
|
+
logger.log_message_with_trace(
|
|
22
|
+
LogLevel::Error,
|
|
23
|
+
&format!("Error installing {:?} '{}'", addon_type, name),
|
|
24
|
+
vec![&e],
|
|
25
|
+
);
|
|
26
|
+
} else {
|
|
27
|
+
spinner.finish_and_clear();
|
|
28
|
+
logger.log_message(
|
|
29
|
+
LogLevel::Success,
|
|
30
|
+
&format!("{:?} '{}' installed successfully!", addon_type, name),
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
Ok(())
|
|
35
|
+
}
|
package/rust/cli/login.rs
CHANGED
|
@@ -1,134 +1,127 @@
|
|
|
1
|
-
use
|
|
2
|
-
use
|
|
3
|
-
use
|
|
4
|
-
use
|
|
5
|
-
use
|
|
6
|
-
use
|
|
7
|
-
use
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
#[
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
let
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
logger.log_message(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
let mut path = home_dir().unwrap();
|
|
129
|
-
path.push(".devalang");
|
|
130
|
-
fs::create_dir_all(&path).unwrap();
|
|
131
|
-
|
|
132
|
-
path.push("session_token.json");
|
|
133
|
-
fs::write(path, json).unwrap();
|
|
134
|
-
}
|
|
1
|
+
use crate::common::sso::get_sso_url;
|
|
2
|
+
use crate::config::settings::set_user_config_string;
|
|
3
|
+
use std::str::FromStr;
|
|
4
|
+
use std::{thread, time::Duration};
|
|
5
|
+
use tiny_http::Header;
|
|
6
|
+
use tiny_http::{Response, Server};
|
|
7
|
+
use webbrowser;
|
|
8
|
+
|
|
9
|
+
/// Handle the login command
|
|
10
|
+
/// This function initiates the login process by opening the browser and waiting for the callback.
|
|
11
|
+
#[cfg(feature = "cli")]
|
|
12
|
+
pub async fn handle_login_command() -> Result<(), String> {
|
|
13
|
+
use crate::utils::logger::LogLevel;
|
|
14
|
+
use crate::utils::logger::Logger;
|
|
15
|
+
use crate::utils::spinner::with_spinner;
|
|
16
|
+
|
|
17
|
+
let logger = Logger::new();
|
|
18
|
+
|
|
19
|
+
let mut listener_port = 7878;
|
|
20
|
+
|
|
21
|
+
let test_port_already_in_use = format!("127.0.0.1:{}", listener_port);
|
|
22
|
+
while std::net::TcpListener::bind(&test_port_already_in_use).is_err() {
|
|
23
|
+
listener_port += 1;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let redirect_uri = format!("http://127.0.0.1:{}/callback", listener_port);
|
|
27
|
+
let login_url = format!(
|
|
28
|
+
"{}/?response_type=code&referer=cli&redirect_uri={}",
|
|
29
|
+
get_sso_url(),
|
|
30
|
+
redirect_uri
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
if webbrowser::open(&login_url).is_ok() {
|
|
34
|
+
logger.log_message(LogLevel::Info, "Opening browser for login...");
|
|
35
|
+
logger.log_message(
|
|
36
|
+
LogLevel::Info,
|
|
37
|
+
&format!(
|
|
38
|
+
"If the browser does not open, please visit the following URL: {}",
|
|
39
|
+
login_url
|
|
40
|
+
),
|
|
41
|
+
);
|
|
42
|
+
} else {
|
|
43
|
+
logger.log_message(
|
|
44
|
+
LogLevel::Info,
|
|
45
|
+
"Please open the following URL in your browser to login:",
|
|
46
|
+
);
|
|
47
|
+
logger.log_message(LogLevel::Info, &login_url);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let server = Server::http(format!("127.0.0.1:{}", listener_port)).unwrap();
|
|
51
|
+
|
|
52
|
+
let spinner = with_spinner("Waiting for authentication...", || {
|
|
53
|
+
thread::sleep(Duration::from_millis(800));
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
for request in server.incoming_requests() {
|
|
57
|
+
let query = request.url().to_string();
|
|
58
|
+
if request.url().starts_with("/callback") {
|
|
59
|
+
if query.contains("session=") || query.contains("error=") {
|
|
60
|
+
let token = query.split("session=").nth(1).unwrap_or("").to_string();
|
|
61
|
+
|
|
62
|
+
if token.len() > 0 {
|
|
63
|
+
let response_html = r#"
|
|
64
|
+
<html>
|
|
65
|
+
<body>
|
|
66
|
+
<h1>Authentication Successful</h1>
|
|
67
|
+
<h2>You can now close this window.</h2>
|
|
68
|
+
</body>
|
|
69
|
+
</html>
|
|
70
|
+
"#;
|
|
71
|
+
|
|
72
|
+
let response = Response::from_string(response_html)
|
|
73
|
+
.with_status_code(200)
|
|
74
|
+
.with_header(Header::from_str("Content-Type: text/html").unwrap());
|
|
75
|
+
|
|
76
|
+
request.respond(response).unwrap();
|
|
77
|
+
|
|
78
|
+
save_token(&token);
|
|
79
|
+
|
|
80
|
+
spinner.finish_and_clear();
|
|
81
|
+
|
|
82
|
+
logger.log_message(
|
|
83
|
+
LogLevel::Success,
|
|
84
|
+
"Authentication successful. Token saved to ~/.devalang/config.json",
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
break;
|
|
88
|
+
} else {
|
|
89
|
+
spinner.finish_and_clear();
|
|
90
|
+
logger.log_message(LogLevel::Error, "Invalid session token.");
|
|
91
|
+
request
|
|
92
|
+
.respond(Response::from_string("Invalid session token."))
|
|
93
|
+
.unwrap();
|
|
94
|
+
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
println!("Invalid callback: {}", request.url());
|
|
99
|
+
|
|
100
|
+
spinner.finish_and_clear();
|
|
101
|
+
logger.log_message(LogLevel::Error, "Invalid callback.");
|
|
102
|
+
request
|
|
103
|
+
.respond(Response::from_string("Invalid callback."))
|
|
104
|
+
.unwrap();
|
|
105
|
+
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
} else if request.url().starts_with("/favicon.ico") {
|
|
109
|
+
// Ignore favicon requests
|
|
110
|
+
} else {
|
|
111
|
+
spinner.finish_and_clear();
|
|
112
|
+
logger.log_message(LogLevel::Error, "Invalid request.");
|
|
113
|
+
request
|
|
114
|
+
.respond(Response::from_string("Invalid request."))
|
|
115
|
+
.unwrap();
|
|
116
|
+
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
Ok(())
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/// Save the session token to a file in the user's home directory
|
|
125
|
+
fn save_token(token: &str) {
|
|
126
|
+
set_user_config_string("session", token.to_string());
|
|
127
|
+
}
|
package/rust/cli/mod.rs
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
pub mod driver;
|
|
2
|
-
|
|
3
|
-
pub mod
|
|
4
|
-
pub mod build;
|
|
5
|
-
pub mod
|
|
6
|
-
pub mod
|
|
7
|
-
pub mod
|
|
8
|
-
pub mod install;
|
|
9
|
-
pub mod
|
|
10
|
-
pub mod
|
|
11
|
-
pub mod
|
|
1
|
+
pub mod driver;
|
|
2
|
+
|
|
3
|
+
pub mod bank;
|
|
4
|
+
pub mod build;
|
|
5
|
+
pub mod check;
|
|
6
|
+
pub mod generator;
|
|
7
|
+
pub mod init;
|
|
8
|
+
pub mod install;
|
|
9
|
+
pub mod login;
|
|
10
|
+
pub mod play;
|
|
11
|
+
pub mod telemetry;
|
|
12
|
+
pub mod template;
|
|
13
|
+
pub mod update;
|